Skip to content

Instantly share code, notes, and snippets.

@imerr
Created September 28, 2013 10:46
Show Gist options
  • Save imerr/6740831 to your computer and use it in GitHub Desktop.
Save imerr/6740831 to your computer and use it in GitHub Desktop.
int __cdecl CalcMeleeDamage(CHARACTER *pAttacker, CHARACTER *pkVictim, bool bIgnoreDefense, bool bIgnoreTargetRating)
{
int weapon_subtype; // ecx@1
CItem *weapon; // ebx@1
char isPolymorphed; // si@1
int attack_base; // esi@8
int party_att_bonus; // ST5C_4@10
int att_bonus; // ebx@10
int att_meele_magic_bonus; // eax@10
int result; // eax@13
const TItemTable *weapon_proto; // eax@14
CMob *polymorphed_mob; // esi@27
int polymorph_power; // ST50_4@28
int def_grade; // ebx@29
int weapon_damage; // [sp+5Ch] [bp-16Ch]@8
float att_rating; // [sp+60h] [bp-168h]@4
int total_def; // [sp+68h] [bp-160h]@10
int damage_final; // [sp+7Ch] [bp-14Ch]@12
int attack_dmg; // [sp+80h] [bp-148h]@10
int weapon_damage_max; // [sp+90h] [bp-138h]@4
int weapon_damage_min; // [sp+94h] [bp-134h]@4
v88 = *(_DWORD *)_stack_chk_guard;
weapon = CHARACTER__GetWear(pAttacker, WEAR_WEAPON);
isPolymorphed = pAttacker->m_dwPolymorphRace != 0;
if ( weapon )
{
if ( pAttacker->m_dwPolymorphRace != 0 && !pAttacker->m_bPolyMaintainStat )
{
weapon_damage_min = 0;
weapon_damage_max = 0;
att_rating = CalcAttackRating(pAttacker, pkVictim, bIgnoreTargetRating);
goto LABEL_5;
}
weapon_proto = weapon->m_pProto;
if ( !weapon_proto || weapon_proto->bType != 1 || weapon_proto->bSubType > 7u )
{
res0:
result = 0;
goto return;
}
weapon_subtype = weapon_proto->bSubType;
v14 = 1 << weapon_subtype;
if ( !((1 << weapon_subtype) & 0xBB) )
{
if ( v14 & 4 )
{
charname = CHARACTER__GetName(pAttacker);
sys_err("CalcMeleeDamage", 381, "CalcMeleeDamage should not handle bows (name: %s)", charname);
result = 0;
goto return;
}
goto res0;
}
}
weapon_damage_min = 0;
weapon_damage_max = 0;
att_rating = CalcAttackRating(pAttacker, pkVictim, bIgnoreTargetRating);
if ( isPolymorphed )
{
LABEL_5:
if ( !pAttacker->m_bPolyMaintainStat )
{
Item_GetDamage(weapon, &weapon_damage_min, &weapon_damage_max);
polymorphed_mob = CMobManager__Get(singleton_CMobManager___ms_singleton, pAttacker->m_dwPolymorphRace);
if ( polymorphed_mob )
{
polymorph_power = CHARACTER__GetPolymorphPower(pAttacker);
weapon_damage_min += polymorphed_mob->m_table.dwDamageRange[0] * polymorph_power / 0x64u;
weapon_damage_max += polymorphed_mob->m_table.dwDamageRange[1] * polymorph_power / 0x64u;
}
goto calcfinaldmg;
}
if ( weapon )
goto item_damage;
mob_damage:
if ( pAttacker->m_bCharType != 6 )
{
weapon_damage_min = CHARACTER__GetMobDamageMin(pAttacker);
weapon_damage_max = CHARACTER__GetMobDamageMax(pAttacker);
}
goto calcfinaldmg;
}
if ( !weapon )
goto mob_damage;
item_damage:
Item_GetDamage(weapon, &weapon_damage_min, &weapon_damage_max);
calcfinaldmg:
weapon_damage = 2 * number_ex(weapon_damage_min, weapon_damage_max, "battle.cpp", 426);
v27 = 0;
attack_base = (signed int)((long double)(weapon_damage
+ CHARACTER__GetPoint(pAttacker, POINT_ATT_GRADE)
- 2 * pAttacker->m_points.level)
* att_rating)
+ 2 * pAttacker->m_points.level;
if ( weapon )
{
attack_base += 2 * CItem__GetValue(weapon, 5u);
}
party_att_bonus = CHARACTER__GetPoint(pAttacker, POINT_PARTY_ATTACKER_BONUS);
att_bonus = CHARACTER__GetPoint(pAttacker, POINT_ATT_BONUS);
att_meele_magic_bonus = CHARACTER__GetPoint(pAttacker, POINT_MELEE_MAGIC_ATT_BONUS_PER);
total_def = 0;
attack_dmg = CalcAttBonus(
pAttacker,
pkVictim,
(attack_base + party_att_bonus) * (att_meele_magic_bonus + att_bonus + 100) / 100);
if ( !bIgnoreDefense )
{
def_grade = CHARACTER__GetPoint(pkVictim, POINT_DEF_GRADE);
total_def = def_grade * (CHARACTER__GetPoint(pkVictim, POINT_DEF_BONUS) + 100) / 100;
if ( !pAttacker->CEntity.m_lpDesc )
total_def += CHARACTER__GetMarriageBonus(pkVictim, UNIQUE_ITEM_MARRIAGE_DEFENSE_BONUS, 1);
}
if ( pAttacker->m_bCharType != 6 )
attack_dmg = (signed int)(CHARACTER__GetMobDamageMultiply(pAttacker) * (long double)attack_dmg);
damage_final = MAX(0, attack_dmg - total_def);
result = CalcBattleDamage(damage_final, pAttacker->m_points.level, pkVictim->m_points.level);// this is pointless, only thing it does do random 1-5 damage if there's less than 2
return:
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment