[리버싱 일기/리메이크] 랑그릿사 2의 마법 데미지 공식은 어떻게 설계되었는가?
필자는 최근 고전 명작 랑그릿사 2 PC판을 기드라로 분석하며, 마법 데미지가 계산되는 내부 로직을 추적했습니다. 각종 구조체와 변수명을 정리하고 나니, 90년대 게임 특유의 실용적이면서도 명쾌한 공식이 모습을 드러냈습니다.
1. 특정 마법의 개별 로직: 토네이도(Tornado)
가장 먼저 분석한 것은 범위 마법인 토네이도입니다. 코드상에서는 대상 유닛의 타입에 따른 보너스 판정이 가장 먼저 눈에 띕니다.
void Tornado(void)
{
// 대상 유닛이 비병일 경우, 보너스 데미지 플래그 활성화
if (ARMY2_UNITTYPE == FLYING_UNIT) {
BonusSpellDamage = 1;
}
/* 계산 공식: ((레벨 / 2) + 시전자의 SP) * 2 */
int damageValue = (((int)FORCE1_LV >> 1) + (int)FORCE1_SP) * 2;
// 최종 데미지 적용 함수 호출 (마법 방어력 계산 포함)
ApplySpellDamage_MDF(damageValue);
}
토네이도는 비병에게 치명적이라는 설정답게, BonusSpellDamage를 통해 추가 타격을 줍니다. 흥미로운 점은 기본 데미지가 (레벨 >> 1 + SP) * 2로 계산된다는 것인데, 여기서 SP는 유닛의 티어값(파이터=1, 로드=2 등)을 의미합니다.
2. 마법 방어력을 고려한 최종 데미지 산출
입력된 기초 데미지는 ApplySpellDamage_MDF 함수를 거치며 타겟의 마법 방어력(MDF)에 의해 가공됩니다.
void ApplySpellDamage_MDF(int damage)
{
// 1. 마법 면역 상태 및 마법 방어력 체크
if (is_magic_immune(FORCE2) || (100 - FORCE1_2_MDF == 0)) return;
// 2. 최종 데미지 계산식
// 보너스 데미지 + 아이템 보너스 + (기초 데미지 * 마방 관통률)
int real_damage = BonusSpellDamage + SpellDamage_Item +
(damage * (100 - (uint)FORCE1_2_MDF)) / 100;
// 3. 데미지 보정 (데미지 하한선 및 HP 초과 방지)
if (real_damage <= 0) real_damage = 1;
int targetHP = (int)FORCE2->Army[ARMY2_NUMBER].HP;
if (targetHP < real_damage) real_damage = targetHP;
// 4. 누적 결과 기록 (범위 마법 계산용)
AccumSpellEffect += real_damage;
AccumSpellTarget += 1;
// 5. 실행 플래그 확인 후 실제 데이터 반영
if (_run_flag_apply == 1) {
FORCE2->Army[ARMY2_NUMBER].HP -= (char)real_damage;
if (FORCE2->Army[ARMY2_NUMBER].HP == 0) {
killed_target_logic(); // 유닛 전사 처리
}
}
}
3. 분석을 통해 알 수 있는 사실들
분석 결과, 랑그릿사 2의 마법 데미지는 크게 세 단계를 거쳐 적용됩니다.
최소 데미지의 보장: 마법 방어력이 아무리 높더라도, 공식에 의해 산출된 데미지가 0이라면 강제로 1의 데미지를 가합니다.
누적 데이터의 활용:
AccumSpellEffect와AccumSpellTarget변수를 통해 마법 한 번으로 총 얼마의 데미지를 몇 명에게 입혔는지 기록합니다. 이는 주로 범위 마법의 효율을 계산할 때 사용됩니다.AI 시뮬레이션의 분리:
_run_flag_apply라는 플래그가 매우 중요합니다. AI가 마법을 쓸지 말지 결정하기 위해 데미지를 미리 계산해 볼 때는 이 플래그를 끄고 함수를 호출하여, 실제 HP는 깎지 않은 채 예상 결과물만 얻어가는 구조입니다.
맺으며
기드라에서 이 로직을 타고 올라가면, 적군 AI가 마법을 선택하는 판단 근거를 찾을 수 있을 것으로 보입니다. 비병에게 토네이도를 날리는 AI의 영리함은 결국 이런 간결한 if문과 시뮬레이션 플래그에서 시작된 것이었습니다. 리버싱은 단순한 코드 해독을 넘어, 30년 전 개발자의 설계 철학을 엿보는 즐거운 과정입니다.
댓글
댓글 쓰기