[10608] Update melee miss chance calculations...finally.

Also thanks to Revils for correcting effective skill for spells that don't use weapon despite being melee/ranged ability.

Signed-off-by: Lynx3d <lynx3d@some-imaginary-isp.org>
This commit is contained in:
MrLama 2010-10-14 11:20:32 +02:00 committed by Lynx3d
parent c44438a517
commit 699a22b2de
2 changed files with 46 additions and 54 deletions

View file

@ -2847,44 +2847,43 @@ bool Unit::IsSpellBlocked(Unit *pCaster, SpellEntry const * /*spellProto*/, Weap
float Unit::MeleeSpellMissChance(Unit *pVictim, WeaponAttackType attType, int32 skillDiff, SpellEntry const *spell) float Unit::MeleeSpellMissChance(Unit *pVictim, WeaponAttackType attType, int32 skillDiff, SpellEntry const *spell)
{ {
// Calculate hit chance (more correct for chance mod) // Calculate hit chance (more correct for chance mod)
int32 HitChance; float hitChance = 0.0f;
// PvP - PvE melee chances // PvP - PvE melee chances
int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7; // TODO: implement diminishing returns for defense from player's defense rating
int32 leveldif = pVictim->getLevelForTarget(this) - getLevelForTarget(pVictim); // pure skill diff is not sufficient since 3.x anymore, but exact formulas hard to research
if(leveldif < 3) if (pVictim->GetTypeId() == TYPEID_PLAYER)
HitChance = 95 - leveldif; hitChance = 95.0f + skillDiff * 0.04f;
else if (skillDiff < -10)
hitChance = 94.0f + (skillDiff + 10) * 0.4f;
else else
HitChance = 93 - (leveldif - 2) * lchance; hitChance = 95.0f + skillDiff * 0.1f;
// Hit chance depends from victim auras // Hit chance depends from victim auras
if(attType == RANGED_ATTACK) if (attType == RANGED_ATTACK)
HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE); hitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE);
else else
HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE); hitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE);
// Spellmod from SPELLMOD_RESIST_MISS_CHANCE // Spellmod from SPELLMOD_RESIST_MISS_CHANCE
if(Player *modOwner = GetSpellModOwner()) if (Player *modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spell->Id, SPELLMOD_RESIST_MISS_CHANCE, HitChance); modOwner->ApplySpellMod(spell->Id, SPELLMOD_RESIST_MISS_CHANCE, hitChance);
// Miss = 100 - hit // Miss = 100 - hit
float miss_chance= 100.0f - HitChance; float missChance = 100.0f - hitChance;
// Bonuses from attacker aura and ratings // Bonuses from attacker aura and ratings
if (attType == RANGED_ATTACK) if (attType == RANGED_ATTACK)
miss_chance -= m_modRangedHitChance; missChance -= m_modRangedHitChance;
else else
miss_chance -= m_modMeleeHitChance; missChance -= m_modMeleeHitChance;
// bonus from skills is 0.04%
miss_chance -= skillDiff * 0.04f;
// Limit miss chance from 0 to 60% // Limit miss chance from 0 to 60%
if (miss_chance < 0.0f) if (missChance < 0.0f)
return 0.0f; return 0.0f;
if (miss_chance > 60.0f) if (missChance > 60.0f)
return 60.0f; return 60.0f;
return miss_chance; return missChance;
} }
// Melee based spells hit result calculations // Melee based spells hit result calculations
@ -2896,7 +2895,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)
attType = RANGED_ATTACK; attType = RANGED_ATTACK;
// bonus from skills is 0.04% per skill Diff // bonus from skills is 0.04% per skill Diff
int32 attackerWeaponSkill = int32(GetWeaponSkillValue(attType,pVictim)); int32 attackerWeaponSkill = (spell->EquippedItemClass == ITEM_CLASS_WEAPON) ? int32(GetWeaponSkillValue(attType,pVictim)) : GetMaxSkillValueForLevel();
int32 skillDiff = attackerWeaponSkill - int32(pVictim->GetMaxSkillValueForLevel(this)); int32 skillDiff = attackerWeaponSkill - int32(pVictim->GetMaxSkillValueForLevel(this));
int32 fullSkillDiff = attackerWeaponSkill - int32(pVictim->GetDefenseSkillValue(this)); int32 fullSkillDiff = attackerWeaponSkill - int32(pVictim->GetDefenseSkillValue(this));
@ -3162,71 +3161,64 @@ float Unit::MeleeMissChanceCalc(const Unit *pVictim, WeaponAttackType attType) c
return 0.0f; return 0.0f;
// Base misschance 5% // Base misschance 5%
float misschance = 5.0f; float missChance = 5.0f;
// DualWield - Melee spells and physical dmg spells - 5% , white damage 24% // DualWield - white damage has additional 19% miss penalty
if (haveOffhandWeapon() && attType != RANGED_ATTACK) if (haveOffhandWeapon() && attType != RANGED_ATTACK)
{ {
bool isNormal = false; bool isNormal = false;
for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i) for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i)
{ {
if( m_currentSpells[i] && (GetSpellSchoolMask(m_currentSpells[i]->m_spellInfo) & SPELL_SCHOOL_MASK_NORMAL) ) if (m_currentSpells[i] && (GetSpellSchoolMask(m_currentSpells[i]->m_spellInfo) & SPELL_SCHOOL_MASK_NORMAL))
{ {
isNormal = true; isNormal = true;
break; break;
} }
} }
if (isNormal || m_currentSpells[CURRENT_MELEE_SPELL]) if (!isNormal && !m_currentSpells[CURRENT_MELEE_SPELL])
misschance = 5.0f; missChance += 19.0f;
else
misschance = 24.0f;
} }
// PvP : PvE melee misschances per leveldif > 2 int32 skillDiff = int32(GetWeaponSkillValue(attType, pVictim)) - int32(pVictim->GetDefenseSkillValue(this));
int32 chance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7;
int32 leveldif = int32(pVictim->getLevelForTarget(this)) - int32(getLevelForTarget(pVictim)); // PvP - PvE melee chances
if(leveldif < 0) // TODO: implement diminishing returns for defense from player's defense rating
leveldif = 0; // pure skill diff is not sufficient since 3.x anymore, but exact formulas hard to research
if ( pVictim->GetTypeId() == TYPEID_PLAYER )
missChance -= skillDiff * 0.04f;
else if ( skillDiff < -10 )
missChance -= (skillDiff + 10) * 0.4f - 1.0f;
else
missChance -= skillDiff * 0.1f;
// Hit chance from attacker based on ratings and auras // Hit chance bonus from attacker based on ratings and auras
float m_modHitChance;
if (attType == RANGED_ATTACK) if (attType == RANGED_ATTACK)
m_modHitChance = m_modRangedHitChance; missChance -= m_modRangedHitChance;
else else
m_modHitChance = m_modMeleeHitChance; missChance -= m_modMeleeHitChance;
if(leveldif < 3)
misschance += (leveldif - m_modHitChance);
else
misschance += ((leveldif - 2) * chance - m_modHitChance);
// Hit chance for victim based on ratings // Hit chance for victim based on ratings
if (pVictim->GetTypeId()==TYPEID_PLAYER) if (pVictim->GetTypeId()==TYPEID_PLAYER)
{ {
if (attType == RANGED_ATTACK) if (attType == RANGED_ATTACK)
misschance += ((Player*)pVictim)->GetRatingBonusValue(CR_HIT_TAKEN_RANGED); missChance += ((Player*)pVictim)->GetRatingBonusValue(CR_HIT_TAKEN_RANGED);
else else
misschance += ((Player*)pVictim)->GetRatingBonusValue(CR_HIT_TAKEN_MELEE); missChance += ((Player*)pVictim)->GetRatingBonusValue(CR_HIT_TAKEN_MELEE);
} }
// Modify miss chance by victim auras // Modify miss chance by victim auras
if(attType == RANGED_ATTACK) if(attType == RANGED_ATTACK)
misschance -= pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE); missChance -= pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE);
else else
misschance -= pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE); missChance -= pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE);
// Modify miss chance from skill difference ( bonus from skills is 0.04% )
int32 skillBonus = int32(GetWeaponSkillValue(attType,pVictim)) - int32(pVictim->GetDefenseSkillValue(this));
misschance -= skillBonus * 0.04f;
// Limit miss chance from 0 to 60% // Limit miss chance from 0 to 60%
if ( misschance < 0.0f) if (missChance < 0.0f)
return 0.0f; return 0.0f;
if ( misschance > 60.0f) if (missChance > 60.0f)
return 60.0f; return 60.0f;
return misschance; return missChance;
} }
uint32 Unit::GetDefenseSkillValue(Unit const* target) const uint32 Unit::GetDefenseSkillValue(Unit const* target) const

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "10607" #define REVISION_NR "10608"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__