Code:
//o--------------------------------------------------------------
//| GetHitChance; Yeahlight, Nov 24, 2008
//o--------------------------------------------------------------
//| Returns the chance to hit between attacker and defender
//o--------------------------------------------------------------
int16 Mob::GetHitChance(Mob* attacker, Mob* defender, int skill_num)
{
bool debugFlag = true;
//Yeahlight: If the target is sitting, the chance to hit them is 100%
if(defender->GetAppearance() == SittingAppearance)
return 999;
sint16 ATKadjustment = (attacker->GetLevel() - defender->GetLevel()) * 3;
sint16 hitRateAdjustment = (attacker->GetLevel() - defender->GetLevel());
int16 hitChance = 70;
int16 weaponSkill = 0;
if(ATKadjustment < 0)
ATKadjustment = 0;
if(attacker->IsClient())
weaponSkill = attacker->CastToClient()->GetSkill(skill_num);
else
weaponSkill = attacker->GetSkill(skill_num);
int16 accuracyATK = (int)((float)weaponSkill * 2.70f) + 5 + ATKadjustment;
if(accuracyATK == 0)
accuracyATK = 1;
int16 avoidanceAC = defender->GetAvoidanceAC();
//Yeahlight: 5% bonus evasion for defensive monks
if(defender->GetClass() == MONK || defender->GetClass() == MONKGM)
hitChance = hitChance - 5;
//Yeahlight: 5% bonus accuracy for offensive rogues
if(attacker->GetClass() == ROGUE || attacker->GetClass() == ROGUEGM)
hitChance = hitChance + 5;
//Yeahlight: As the attacker falls further under the level of the defender, it becomes harder to land a hit
// Note: This will become a major tweak for class balancing! We must keep this on par with spell casting level penalties
if(hitRateAdjustment < 0)
{
hitRateAdjustment = abs(hitRateAdjustment);
if(hitRateAdjustment > 15)
hitRateAdjustment = 15;
float tempAdjustment = (float)hitRateAdjustment * 2.00f / 3.00f;
hitRateAdjustment = (int)tempAdjustment;
hitChance = hitChance - hitRateAdjustment;
}
//Yeahlight: Adjust hit rate based on the gap between accuracy and avoidance AC
sint16 gapPercent = (sint16)(((float)(accuracyATK - avoidanceAC) / (float)(accuracyATK)) * 100.00f);
sint16 gapAdjustment = ((float)gapPercent / 5.00f);
if(gapAdjustment > 5)
gapAdjustment = 5;
else if(gapAdjustment < -5)
gapAdjustment = -5;
hitChance = hitChance + gapAdjustment;
//Yeahlight: Debug messages
if(debugFlag && defender->IsClient() && defender->CastToClient()->GetDebugMe())
defender->Message(LIGHTEN_BLUE, "Debug: %s's ATK accuracy: %i; Your AC evasion: %i; Hit rate: %i%s", attacker->GetName(), accuracyATK, avoidanceAC, hitChance, "%");
if(debugFlag && attacker->IsClient() && attacker->CastToClient()->GetDebugMe())
attacker->Message(LIGHTEN_BLUE, "Debug: Your ATK accuracy: %i; %s's AC evasion: %i; Hit rate: %i%s", accuracyATK, defender->GetName(), avoidanceAC, hitChance, "%");
CAST_CLIENT_DEBUG_PTR(attacker)->Log(CP_ATTACK, "Mob::GetHitChance: Your hit chance: %f", hitChance);
CAST_CLIENT_DEBUG_PTR(defender)->Log(CP_ATTACK, "Mob::GetHitChance: %s's hit chance: %f", attacker->GetName(), hitChance);
return hitChance;
}