mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-15 00:01:28 +00:00
Refactor CheckHitChance
Pulled the accuracy/avoidance spell bonuses into their own functions so we can show the total values in #showstats
This commit is contained in:
parent
c030e1ce8d
commit
e03a90b05d
157
zone/attack.cpp
157
zone/attack.cpp
@ -157,6 +157,62 @@ int Mob::compute_tohit(EQEmu::skills::SkillType skillinuse)
|
|||||||
return std::max(tohit, 1);
|
return std::max(tohit, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return -1 in cases that always hit
|
||||||
|
int Mob::GetTotalToHit(EQEmu::skills::SkillType skill, int chance_mod)
|
||||||
|
{
|
||||||
|
if (chance_mod >= 10000) // override for stuff like SE_SkillAttack
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// calculate attacker's accuracy
|
||||||
|
auto accuracy = compute_tohit(skill) + 10; // add 10 in case the NPC's stats are fucked
|
||||||
|
if (chance_mod > 0) // multiplier
|
||||||
|
accuracy *= chance_mod;
|
||||||
|
|
||||||
|
// Torven parsed an apparent constant of 1.2 somewhere in here * 6 / 5 looks eqmathy to me!
|
||||||
|
accuracy = accuracy * 6 / 5;
|
||||||
|
|
||||||
|
// unsure on the stacking order of these effects, rather hard to parse
|
||||||
|
// item mod2 accuracy isn't applied to range? Theory crafting and parses back it up I guess
|
||||||
|
// mod2 accuracy -- flat bonus
|
||||||
|
if (skill != EQEmu::skills::SkillArchery && skill != EQEmu::skills::SkillThrowing)
|
||||||
|
accuracy += itembonuses.HitChance;
|
||||||
|
|
||||||
|
// 216 Melee Accuracy Amt aka SE_Accuracy -- flat bonus
|
||||||
|
accuracy += itembonuses.Accuracy[EQEmu::skills::HIGHEST_SKILL + 1] +
|
||||||
|
aabonuses.Accuracy[EQEmu::skills::HIGHEST_SKILL + 1] +
|
||||||
|
spellbonuses.Accuracy[EQEmu::skills::HIGHEST_SKILL + 1] +
|
||||||
|
itembonuses.Accuracy[skill] +
|
||||||
|
aabonuses.Accuracy[skill] +
|
||||||
|
spellbonuses.Accuracy[skill];
|
||||||
|
|
||||||
|
// auto hit discs (and looks like there are some autohit AAs)
|
||||||
|
if (spellbonuses.HitChanceEffect[skill] >= 10000 || aabonuses.HitChanceEffect[skill] >= 10000)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (spellbonuses.HitChanceEffect[EQEmu::skills::HIGHEST_SKILL + 1] >= 10000)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// 184 Accuracy % aka SE_HitChance -- percentage increase
|
||||||
|
auto hit_bonus = itembonuses.HitChanceEffect[EQEmu::skills::HIGHEST_SKILL + 1] +
|
||||||
|
aabonuses.HitChanceEffect[EQEmu::skills::HIGHEST_SKILL + 1] +
|
||||||
|
spellbonuses.HitChanceEffect[EQEmu::skills::HIGHEST_SKILL + 1] +
|
||||||
|
itembonuses.HitChanceEffect[skill] +
|
||||||
|
aabonuses.HitChanceEffect[skill] +
|
||||||
|
spellbonuses.HitChanceEffect[skill];
|
||||||
|
|
||||||
|
accuracy = (accuracy * (100 + hit_bonus)) / 100;
|
||||||
|
|
||||||
|
// TODO: April 2003 added an archery/throwing PVP accuracy penalty while moving, should be in here some where,
|
||||||
|
// but PVP is less important so I haven't tried parsing it at all
|
||||||
|
|
||||||
|
// There is also 110 Ranger Archery Accuracy % which should probably be in here some where, but it's not in any spells/aas
|
||||||
|
// Name implies it's a percentage increase, if one wishes to implement, do it like the hit_bonus above but limited to ranger archery
|
||||||
|
|
||||||
|
// There is also 183 UNUSED - Skill Increase Chance which devs say isn't used at all in code, but some spells reference it
|
||||||
|
// I do not recommend implementing this once since there are spells that use it which would make this not live-like with default spell files
|
||||||
|
return accuracy;
|
||||||
|
}
|
||||||
|
|
||||||
// based on dev quotes
|
// based on dev quotes
|
||||||
// the AGI bonus has actually drastically changed from classic
|
// the AGI bonus has actually drastically changed from classic
|
||||||
int Mob::compute_defense()
|
int Mob::compute_defense()
|
||||||
@ -181,6 +237,33 @@ int Mob::compute_defense()
|
|||||||
return std::max(1, defense);
|
return std::max(1, defense);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return -1 in cases that always miss
|
||||||
|
int Mob::GetTotalDefense()
|
||||||
|
{
|
||||||
|
auto avoidance = compute_defense() + 10; // add 10 in case the NPC's stats are fucked
|
||||||
|
auto evasion_bonus = spellbonuses.AvoidMeleeChanceEffect; // we check this first since it has a special case
|
||||||
|
if (evasion_bonus >= 10000)
|
||||||
|
return -1;
|
||||||
|
//
|
||||||
|
// 172 Evasion aka SE_AvoidMeleeChance
|
||||||
|
evasion_bonus += itembonuses.AvoidMeleeChanceEffect + aabonuses.AvoidMeleeChanceEffect; // item bonus here isn't mod2 avoidance
|
||||||
|
|
||||||
|
Mob *owner = nullptr;
|
||||||
|
if (IsPet())
|
||||||
|
owner = GetOwner();
|
||||||
|
else if (IsNPC() && CastToNPC()->GetSwarmOwner())
|
||||||
|
owner = entity_list.GetMobID(CastToNPC()->GetSwarmOwner());
|
||||||
|
|
||||||
|
if (owner) // 215 Pet Avoidance % aka SE_PetAvoidance
|
||||||
|
evasion_bonus += owner->aabonuses.PetAvoidance + owner->spellbonuses.PetAvoidance + owner->itembonuses.PetAvoidance;
|
||||||
|
|
||||||
|
// Evasion is a percentage bonus according to AA descriptions
|
||||||
|
if (evasion_bonus)
|
||||||
|
avoidance = (avoidance * (100 + evasion_bonus)) / 100;
|
||||||
|
|
||||||
|
return avoidance;
|
||||||
|
}
|
||||||
|
|
||||||
// called when a mob is attacked, does the checks to see if it's a hit
|
// called when a mob is attacked, does the checks to see if it's a hit
|
||||||
// and does other mitigation checks. 'this' is the mob being attacked.
|
// and does other mitigation checks. 'this' is the mob being attacked.
|
||||||
bool Mob::CheckHitChance(Mob* other, EQEmu::skills::SkillType skillinuse, int chance_mod)
|
bool Mob::CheckHitChance(Mob* other, EQEmu::skills::SkillType skillinuse, int chance_mod)
|
||||||
@ -192,80 +275,14 @@ bool Mob::CheckHitChance(Mob* other, EQEmu::skills::SkillType skillinuse, int ch
|
|||||||
if (defender->IsClient() && defender->CastToClient()->IsSitting())
|
if (defender->IsClient() && defender->CastToClient()->IsSitting())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// calculate defender's avoidance
|
auto avoidance = defender->GetTotalDefense();
|
||||||
auto avoidance = defender->compute_defense() + 10; // add 10 in case the NPC's stats are fucked
|
if (avoidance == -1) // some sort of auto avoid disc
|
||||||
auto evasion_bonus = defender->spellbonuses.AvoidMeleeChanceEffect; // we check this first since it has a special case
|
|
||||||
if (evasion_bonus <= -100)
|
|
||||||
return true;
|
|
||||||
if (evasion_bonus >= 10000) // some sort of auto avoid disc
|
|
||||||
return false;
|
return false;
|
||||||
// 172 Evasion aka SE_AvoidMeleeChance
|
|
||||||
evasion_bonus += defender->itembonuses.AvoidMeleeChanceEffect + defender->aabonuses.AvoidMeleeChanceEffect; // item bonus here isn't mod2 avoidance
|
|
||||||
|
|
||||||
Mob *owner = nullptr;
|
auto accuracy = attacker->GetTotalToHit(skillinuse, chance_mod);
|
||||||
if (defender->IsPet())
|
if (accuracy == -1)
|
||||||
owner = defender->GetOwner();
|
|
||||||
else if (defender->IsNPC() && defender->CastToNPC()->GetSwarmOwner())
|
|
||||||
owner = entity_list.GetMobID(defender->CastToNPC()->GetSwarmOwner());
|
|
||||||
|
|
||||||
if (owner) // 215 Pet Avoidance % aka SE_PetAvoidance
|
|
||||||
evasion_bonus += owner->aabonuses.PetAvoidance + owner->spellbonuses.PetAvoidance + owner->itembonuses.PetAvoidance;
|
|
||||||
|
|
||||||
// Evasion is a percentage bonus according to AA descriptions
|
|
||||||
if (evasion_bonus)
|
|
||||||
avoidance = (avoidance * (100 + evasion_bonus)) / 100;
|
|
||||||
|
|
||||||
if (chance_mod >= 10000) // override for stuff like SE_SkillAttack
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// calculate attacker's accuracy
|
|
||||||
auto accuracy = attacker->compute_tohit(skillinuse) + 10; // add 10 in case the NPC's stats are fucked
|
|
||||||
if (chance_mod > 0) // multiplier
|
|
||||||
accuracy *= chance_mod;
|
|
||||||
|
|
||||||
// Torven parsed an apparent constant of 1.2 somewhere in here * 6 / 5 looks eqmathy to me!
|
|
||||||
accuracy = accuracy * 6 / 5;
|
|
||||||
|
|
||||||
// unsure on the stacking order of these effects, rather hard to parse
|
|
||||||
// item mod2 accuracy isn't applied to range? Theory crafting and parses back it up I guess
|
|
||||||
// mod2 accuracy -- flat bonus
|
|
||||||
if (skillinuse != EQEmu::skills::SkillArchery && skillinuse != EQEmu::skills::SkillThrowing)
|
|
||||||
accuracy += attacker->itembonuses.HitChance;
|
|
||||||
|
|
||||||
// 216 Melee Accuracy Amt aka SE_Accuracy -- flat bonus
|
|
||||||
accuracy += attacker->itembonuses.Accuracy[EQEmu::skills::HIGHEST_SKILL + 1] +
|
|
||||||
attacker->aabonuses.Accuracy[EQEmu::skills::HIGHEST_SKILL + 1] +
|
|
||||||
attacker->spellbonuses.Accuracy[EQEmu::skills::HIGHEST_SKILL + 1] +
|
|
||||||
attacker->itembonuses.Accuracy[skillinuse] +
|
|
||||||
attacker->aabonuses.Accuracy[skillinuse] +
|
|
||||||
attacker->spellbonuses.Accuracy[skillinuse];
|
|
||||||
|
|
||||||
// auto hit discs (and looks like there are some autohit AAs)
|
|
||||||
if (attacker->spellbonuses.HitChanceEffect[skillinuse] >= 10000 || attacker->aabonuses.HitChanceEffect[skillinuse] >= 10000)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (attacker->spellbonuses.HitChanceEffect[EQEmu::skills::HIGHEST_SKILL + 1] >= 10000)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// 184 Accuracy % aka SE_HitChance -- percentage increase
|
|
||||||
auto hit_bonus = attacker->itembonuses.HitChanceEffect[EQEmu::skills::HIGHEST_SKILL + 1] +
|
|
||||||
attacker->aabonuses.HitChanceEffect[EQEmu::skills::HIGHEST_SKILL + 1] +
|
|
||||||
attacker->spellbonuses.HitChanceEffect[EQEmu::skills::HIGHEST_SKILL + 1] +
|
|
||||||
attacker->itembonuses.HitChanceEffect[skillinuse] +
|
|
||||||
attacker->aabonuses.HitChanceEffect[skillinuse] +
|
|
||||||
attacker->spellbonuses.HitChanceEffect[skillinuse];
|
|
||||||
|
|
||||||
accuracy = (accuracy * (100 + hit_bonus)) / 100;
|
|
||||||
|
|
||||||
// TODO: April 2003 added an archery/throwing PVP accuracy penalty while moving, should be in here some where,
|
|
||||||
// but PVP is less important so I haven't tried parsing it at all
|
|
||||||
|
|
||||||
// There is also 110 Ranger Archery Accuracy % which should probably be in here some where, but it's not in any spells/aas
|
|
||||||
// Name implies it's a percentage increase, if one wishes to implement, do it like the hit_bonus above but limited to ranger archery
|
|
||||||
|
|
||||||
// There is also 183 UNUSED - Skill Increase Chance which devs say isn't used at all in code, but some spells reference it
|
|
||||||
// I do not recommend implementing this once since there are spells that use it which would make this not live-like with default spell files
|
|
||||||
|
|
||||||
// so now we roll!
|
// so now we roll!
|
||||||
// relevant dev quote:
|
// relevant dev quote:
|
||||||
// Then your chance to simply avoid the attack is checked (defender's avoidance roll beat the attacker's accuracy roll.)
|
// Then your chance to simply avoid the attack is checked (defender's avoidance roll beat the attacker's accuracy roll.)
|
||||||
|
|||||||
@ -166,7 +166,9 @@ public:
|
|||||||
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
||||||
bool AvoidDamage(Mob* attacker, int &damage, int hand);
|
bool AvoidDamage(Mob* attacker, int &damage, int hand);
|
||||||
int compute_tohit(EQEmu::skills::SkillType skillinuse);
|
int compute_tohit(EQEmu::skills::SkillType skillinuse);
|
||||||
|
int GetTotalToHit(EQEmu::skills::SkillType skill, int chance_mod); // compute_tohit + spell bonuses
|
||||||
int compute_defense();
|
int compute_defense();
|
||||||
|
int GetTotalDefense(); // compute_defense + spell bonuses
|
||||||
bool CheckHitChance(Mob* attacker, EQEmu::skills::SkillType skillinuse, int chance_mod = 0);
|
bool CheckHitChance(Mob* attacker, EQEmu::skills::SkillType skillinuse, int chance_mod = 0);
|
||||||
virtual void TryCriticalHit(Mob *defender, uint16 skill, int &damage, int min_damage, ExtraAttackOptions *opts = nullptr);
|
virtual void TryCriticalHit(Mob *defender, uint16 skill, int &damage, int min_damage, ExtraAttackOptions *opts = nullptr);
|
||||||
void TryPetCriticalHit(Mob *defender, uint16 skill, int &damage);
|
void TryPetCriticalHit(Mob *defender, uint16 skill, int &damage);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user