mirror of
https://github.com/mangosfour/server.git
synced 2025-12-12 19:37:03 +00:00
[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:
parent
c44438a517
commit
699a22b2de
2 changed files with 46 additions and 54 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue