From 8d7d7a5f2dc4ad916aa9abe99b1aaa9a2bc055ad Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 29 Oct 2009 04:32:16 +0300 Subject: [PATCH] [8747] Implement player's pet resilience, also fix DoT case. --- src/game/Player.cpp | 50 ----------------------------- src/game/Player.h | 6 ---- src/game/SpellAuras.cpp | 14 ++++---- src/game/SpellEffects.cpp | 8 ++--- src/game/Unit.cpp | 82 +++++++++++++++++++++++++++++------------------ src/game/Unit.h | 19 +++++++++++ src/shared/revision_nr.h | 2 +- 7 files changed, 82 insertions(+), 99 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 09d61f4f2..b63a7848c 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -4816,56 +4816,6 @@ float Player::GetRatingBonusValue(CombatRating cr) const return float(GetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr)) / GetRatingCoefficient(cr); } -uint32 Player::GetMeleeCritDamageReduction(uint32 damage) const -{ - float melee = GetRatingBonusValue(CR_CRIT_TAKEN_MELEE)*2.2f; - if (melee>33.0f) melee = 33.0f; - return uint32 (melee * damage /100.0f); -} - -uint32 Player::GetMeleeDamageReduction(uint32 damage) const -{ - float rate = GetRatingBonusValue(CR_CRIT_TAKEN_MELEE); - // Resilience not limited (limit it by 100%) - if (rate > 100.0f) - rate = 100.0f; - return uint32 (rate * damage / 100.0f); -} - -uint32 Player::GetRangedCritDamageReduction(uint32 damage) const -{ - float ranged = GetRatingBonusValue(CR_CRIT_TAKEN_RANGED)*2.2f; - if (ranged>33.0f) ranged=33.0f; - return uint32 (ranged * damage /100.0f); -} - -uint32 Player::GetRangedDamageReduction(uint32 damage) const -{ - float rate = GetRatingBonusValue(CR_CRIT_TAKEN_RANGED); - // Resilience not limited (limit it by 100%) - if (rate > 100.0f) - rate = 100.0f; - return uint32 (rate * damage / 100.0f); -} - -uint32 Player::GetSpellCritDamageReduction(uint32 damage) const -{ - float spell = GetRatingBonusValue(CR_CRIT_TAKEN_SPELL)*2.2f; - // In wow script resilience limited to 33% - if (spell>33.0f) - spell = 33.0f; - return uint32 (spell * damage / 100.0f); -} - -uint32 Player::GetSpellDamageReduction(uint32 damage) const -{ - float rate = GetRatingBonusValue(CR_CRIT_TAKEN_SPELL); - // Resilience not limited (limit it by 100%) - if (rate > 100.0f) - rate = 100.0f; - return uint32 (rate * damage / 100.0f); -} - float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const { switch (attType) diff --git a/src/game/Player.h b/src/game/Player.h index 4c9325d09..a637fe5c8 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1724,12 +1724,6 @@ class MANGOS_DLL_SPEC Player : public Unit float OCTRegenMPPerSpirit(); float GetRatingCoefficient(CombatRating cr) const; float GetRatingBonusValue(CombatRating cr) const; - uint32 GetMeleeCritDamageReduction(uint32 damage) const; - uint32 GetMeleeDamageReduction(uint32 damage) const; - uint32 GetRangedCritDamageReduction(uint32 damage) const; - uint32 GetRangedDamageReduction(uint32 damage) const; - uint32 GetSpellCritDamageReduction(uint32 damage) const; - uint32 GetSpellDamageReduction(uint32 damage) const; uint32 GetBaseSpellPowerBonus() { return m_baseSpellPower; } float GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 7126a1ad9..e69539f1b 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -6382,10 +6382,10 @@ void Aura::PeriodicTick() if (isCrit) cleanDamage.hitOutCome = MELEE_HIT_CRIT; - // Reduce dot damage from resilience for players. + // only from players // FIXME: need use SpellDamageBonus instead? - if (m_target->GetTypeId() == TYPEID_PLAYER) - pdamage-=((Player*)m_target)->GetSpellDamageReduction(pdamage); + if (IS_PLAYER_GUID(m_caster_guid)) + pdamage -= m_target->GetSpellDamageReduction(pdamage); pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist); @@ -6609,8 +6609,8 @@ void Aura::PeriodicTick() int32 drain_amount = m_target->GetPower(power) > pdamage ? pdamage : m_target->GetPower(power); // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4) - if (power == POWER_MANA && m_target->GetTypeId() == TYPEID_PLAYER) - drain_amount -= ((Player*)m_target)->GetSpellCritDamageReduction(drain_amount); + if (power == POWER_MANA) + drain_amount -= m_target->GetSpellCritDamageReduction(drain_amount); m_target->ModifyPower(power, -drain_amount); @@ -6701,8 +6701,8 @@ void Aura::PeriodicTick() return; // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4) - if (powerType == POWER_MANA && m_target->GetTypeId() == TYPEID_PLAYER) - pdamage -= ((Player*)m_target)->GetSpellCritDamageReduction(pdamage); + if (powerType == POWER_MANA) + pdamage -= m_target->GetSpellCritDamageReduction(pdamage); uint32 gain = uint32(-m_target->ModifyPower(powerType, -pdamage)); diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index bfe3eca10..c25d3946e 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -2486,8 +2486,8 @@ void Spell::EffectPowerDrain(uint32 i) // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4) uint32 power = damage; - if ( drain_power == POWER_MANA && unitTarget->GetTypeId() == TYPEID_PLAYER ) - power -= ((Player*)unitTarget)->GetSpellCritDamageReduction(power); + if (drain_power == POWER_MANA) + power -= unitTarget->GetSpellCritDamageReduction(power); int32 new_damage; if(curPower < power) @@ -2550,8 +2550,8 @@ void Spell::EffectPowerBurn(uint32 i) // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4) uint32 power = damage; - if (powertype == POWER_MANA && unitTarget->GetTypeId() == TYPEID_PLAYER) - power -= ((Player*)unitTarget)->GetSpellCritDamageReduction(power); + if (powertype == POWER_MANA) + power -= unitTarget->GetSpellCritDamageReduction(power); int32 new_damage = (curPower < power) ? curPower : power; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index a7d6a56f9..d8964a093 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1060,11 +1060,11 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S damageInfo->HitInfo|= SPELL_HIT_TYPE_CRIT; damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim); // Resilience - reduce crit damage - if (pVictim->GetTypeId()==TYPEID_PLAYER) - { - uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask); - damage -= ((Player*)pVictim)->GetMeleeCritDamageReduction(redunction_affected_damage); - } + uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask); + if (attackType != RANGED_ATTACK) + damage -= pVictim->GetMeleeCritDamageReduction(redunction_affected_damage); + else + damage -= pVictim->GetRangedCritDamageReduction(redunction_affected_damage); } } break; @@ -1080,20 +1080,18 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S damageInfo->HitInfo|= SPELL_HIT_TYPE_CRIT; damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim); // Resilience - reduce crit damage - if (pVictim->GetTypeId()==TYPEID_PLAYER) - { - uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask); - damage -= ((Player*)pVictim)->GetSpellCritDamageReduction(redunction_affected_damage); - } + uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask); + damage -= pVictim->GetSpellCritDamageReduction(redunction_affected_damage); } } break; } - if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER) + // only from players + if (GetTypeId() == TYPEID_PLAYER) { uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask); - damage -= ((Player*)pVictim)->GetSpellDamageReduction(redunction_affected_damage); + damage -= pVictim->GetSpellDamageReduction(redunction_affected_damage); } // damage mitigation @@ -1286,13 +1284,15 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da damageInfo->damage = int32((damageInfo->damage) * float((100.0f + mod)/100.0f)); // Resilience - reduce crit damage - if (pVictim->GetTypeId()==TYPEID_PLAYER) - { - uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damageInfo->damage,damageInfo->damageSchoolMask); - uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(redunction_affected_damage); - damageInfo->damage -= resilienceReduction; - damageInfo->cleanDamage += resilienceReduction; - } + uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damageInfo->damage,damageInfo->damageSchoolMask); + uint32 resilienceReduction; + if (attackType != RANGED_ATTACK) + resilienceReduction = pVictim->GetMeleeCritDamageReduction(redunction_affected_damage); + else + resilienceReduction = pVictim->GetRangedCritDamageReduction(redunction_affected_damage); + + damageInfo->damage -= resilienceReduction; + damageInfo->cleanDamage += resilienceReduction; break; } case MELEE_HIT_PARRY: @@ -1391,13 +1391,14 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da break; } - if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER) + // only from players + if (GetTypeId() == TYPEID_PLAYER) { uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageInfo->damageSchoolMask); if (attackType != RANGED_ATTACK) - damage-=((Player*)pVictim)->GetMeleeDamageReduction(redunction_affected_damage); + damage -= pVictim->GetMeleeDamageReduction(redunction_affected_damage); else - damage-=((Player*)pVictim)->GetRangedDamageReduction(redunction_affected_damage); + damage -= pVictim->GetRangedDamageReduction(redunction_affected_damage); } // Calculate absorb resist @@ -2941,13 +2942,10 @@ float Unit::GetUnitCriticalChance(WeaponAttackType attackType, const Unit *pVict crit += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE); // reduce crit chance from Rating for players - if (pVictim->GetTypeId()==TYPEID_PLAYER) - { - if (attackType==RANGED_ATTACK) - crit -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_RANGED); - else - crit -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_MELEE); - } + if (attackType != RANGED_ATTACK) + crit -= pVictim->GetMeleeCritChanceReduction(); + else + crit -= pVictim->GetRangedCritChanceReduction(); // Apply crit chance from defence skill crit += (int32(GetMaxSkillValueForLevel(pVictim)) - int32(pVictim->GetDefenseSkillValue(this))) * 0.04f; @@ -8622,8 +8620,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM // Modify critical chance by victim SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE crit_chance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE); // Modify by player victim resilience - if (pVictim->GetTypeId() == TYPEID_PLAYER) - crit_chance -= ((Player*)pVictim)->GetRatingBonusValue(CR_CRIT_TAKEN_SPELL); + crit_chance -= pVictim->GetSpellCritChanceReduction(); } // scripted (increase crit chance ... against ... target by x%) @@ -12631,3 +12628,26 @@ void Unit::KnockBackFrom(Unit* target, float horizintalSpeed, float verticalSpee NearTeleportTo(fx, fy, fz, GetOrientation(), this == target); } } + +float Unit::GetCombatRatingReduction(CombatRating cr) const +{ + if (GetTypeId() == TYPEID_PLAYER) + return ((Player const*)this)->GetRatingBonusValue(cr); + else if (((Creature const*)this)->isPet()) + { + // Player's pet have 0.4 resilience from owner + if (Unit* owner = GetOwner()) + if(owner->GetTypeId() == TYPEID_PLAYER) + return ((Player*)owner)->GetRatingBonusValue(cr) * 0.4f; + } + + return 0.0f; +} + +uint32 Unit::GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const +{ + float percent = GetCombatRatingReduction(cr) * rate; + if (percent > cap) + percent = cap; + return uint32 (percent * damage / 100.0f); +} diff --git a/src/game/Unit.h b/src/game/Unit.h index 9dcb55c7a..18d3989a6 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -1034,6 +1034,21 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType = BASE_ATTACK); void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss); + // player or player's pet resilience (-1%) + float GetMeleeCritChanceReduction() const { return GetCombatRatingReduction(CR_CRIT_TAKEN_MELEE); } + float GetRangedCritChanceReduction() const { return GetCombatRatingReduction(CR_CRIT_TAKEN_RANGED); } + float GetSpellCritChanceReduction() const { return GetCombatRatingReduction(CR_CRIT_TAKEN_SPELL); } + + // player or player's pet resilience (-1%) + uint32 GetMeleeCritDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 2.2f, 33.0f, damage); } + uint32 GetRangedCritDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_RANGED, 2.2f, 33.0f, damage); } + uint32 GetSpellCritDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_SPELL, 2.2f, 33.0f, damage); } + + // player or player's pet resilience (-1%), cap 100% + uint32 GetMeleeDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 1.0f, 100.0f, damage); } + uint32 GetRangedDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 1.0f, 100.0f, damage); } + uint32 GetSpellDamageReduction(uint32 damage) const { return GetCombatRatingDamageReduction(CR_CRIT_TAKEN_MELEE, 1.0f, 100.0f, damage); } + float MeleeSpellMissChance(Unit *pVictim, WeaponAttackType attType, int32 skillDiff, SpellEntry const *spell); SpellMissInfo MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell); SpellMissInfo MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell); @@ -1583,6 +1598,10 @@ class MANGOS_DLL_SPEC Unit : public WorldObject bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown); bool HandleMendingAuraProc(Aura* triggeredByAura); + // player or player's pet + float GetCombatRatingReduction(CombatRating cr) const; + uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const; + uint32 m_state; // Even derived shouldn't modify uint32 m_CombatTimer; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9e5d95f22..5598fe075 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8746" + #define REVISION_NR "8747" #endif // __REVISION_NR_H__ -- 2.11.4.GIT