From 63e7c092f15fbb2e37e151c199ba8922d5a03bae Mon Sep 17 00:00:00 2001 From: sixsixnine Date: Fri, 4 Sep 2009 02:14:37 +0400 Subject: [PATCH] [8458] Re-implement SPELL_AURA_MOD_TARGET_ARMOR_PCT in more porper way for weapon dependent cases. (cherry picked from commit 7efab7fd38c3a753e967648ca8ef1f2cdfbac76c) Signed-off-by: VladimirMangos With some fixes and rewrites. --- src/game/Player.cpp | 21 ++++++++++++++++++++- src/game/Player.h | 3 +++ src/game/SpellAuras.cpp | 10 +++++++++- src/game/SpellAuras.h | 1 + src/game/StatSystem.cpp | 25 +++++++++++++++++++++++++ src/game/Unit.cpp | 7 ++----- src/shared/revision_nr.h | 2 +- 7 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 65247bce1..3131fd95f 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -439,6 +439,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa m_baseSpellPower = 0; m_baseFeralAP = 0; m_baseManaRegen = 0; + m_armorPenetrationPct = 0.0f; // Honor System m_lastHonorUpdateTime = time(NULL); @@ -4972,6 +4973,8 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply) } break; case CR_ARMOR_PENETRATION: + if(affectStats) + UpdateArmorPenetration(); break; } } @@ -10441,9 +10444,15 @@ Item* Player::EquipItem( uint16 pos, Item *pItem, bool update ) ApplyEquipCooldown(pItem); if( slot == EQUIPMENT_SLOT_MAINHAND ) + { UpdateExpertise(BASE_ATTACK); + UpdateArmorPenetration(); + } else if( slot == EQUIPMENT_SLOT_OFFHAND ) + { UpdateExpertise(OFF_ATTACK); + UpdateArmorPenetration(); + } } else { @@ -10583,9 +10592,13 @@ void Player::RemoveItem( uint8 bag, uint8 slot, bool update ) } UpdateExpertise(BASE_ATTACK); + UpdateArmorPenetration(); } else if( slot == EQUIPMENT_SLOT_OFFHAND ) + { UpdateExpertise(OFF_ATTACK); + UpdateArmorPenetration(); + } } } // need update known currency @@ -10694,10 +10707,16 @@ void Player::DestroyItem( uint8 bag, uint8 slot, bool update ) RemoveItemDependentAurasAndCasts(pItem); // update expertise - if ( slot == EQUIPMENT_SLOT_MAINHAND ) + if( slot == EQUIPMENT_SLOT_MAINHAND ) + { UpdateExpertise(BASE_ATTACK); + UpdateArmorPenetration(); + } else if( slot == EQUIPMENT_SLOT_OFFHAND ) + { UpdateExpertise(OFF_ATTACK); + UpdateArmorPenetration(); + } // equipment visual show SetVisibleItemSlot(slot, NULL); diff --git a/src/game/Player.h b/src/game/Player.h index 9766119d8..fee045180 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1719,6 +1719,7 @@ class MANGOS_DLL_SPEC Player : public Unit void UpdateAllSpellCritChances(); void UpdateSpellCritChance(uint32 school); void UpdateExpertise(WeaponAttackType attType); + void UpdateArmorPenetration(); void ApplyManaRegenBonus(int32 amount, bool apply); void UpdateManaRegen(); @@ -1882,6 +1883,7 @@ class MANGOS_DLL_SPEC Player : public Unit float GetTotalPercentageModValue(BaseModGroup modGroup) const { return m_auraBaseMod[modGroup][FLAT_MOD] + m_auraBaseMod[modGroup][PCT_MOD]; } void _ApplyAllStatBonuses(); void _RemoveAllStatBonuses(); + float GetArmorPenetrationPct() const { return m_armorPenetrationPct; } void _ApplyWeaponDependentAuraMods(Item *item, WeaponAttackType attackType, bool apply); void _ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, Aura* aura, bool apply); @@ -2349,6 +2351,7 @@ class MANGOS_DLL_SPEC Player : public Unit uint16 m_baseSpellPower; uint16 m_baseFeralAP; uint16 m_baseManaRegen; + float m_armorPenetrationPct; SpellModList m_spellMods[MAX_SPELLMOD]; int32 m_SpellModRemoveCount; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 8242e6fc3..52cc53caf 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -330,7 +330,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_MAX_AFFECTED_TARGETS Use SpellClassMask for spell select &Aura::HandleNULL, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon &Aura::HandleNULL, //279 visual effects? 58836 and 57507 - &Aura::HandleNoImmediateEffect, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT implemented in Unit::CalcArmorReducedDamage + &Aura::HandleModTargetArmorPct, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT &Aura::HandleNULL, //281 SPELL_AURA_MOD_HONOR_GAIN &Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT &Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus @@ -7275,3 +7275,11 @@ bool Aura::IsCritFromAbilityAura(Unit* caster, uint32& damage) } return false; } + +void Aura::HandleModTargetArmorPct(bool apply, bool Real) +{ + if(m_target->GetTypeId() != TYPEID_PLAYER) + return; + + ((Player*)m_target)->UpdateArmorPenetration(); +} diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index fd230cebf..c6965ca53 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -211,6 +211,7 @@ class MANGOS_DLL_SPEC Aura void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real); void HandleNoReagentUseAura(bool Apply, bool Real); void HandlePhase(bool Apply, bool Real); + void HandleModTargetArmorPct(bool Apply, bool Real); virtual ~Aura(); diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index 9ec67fc9e..de578182f 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -132,6 +132,7 @@ bool Player::UpdateAllStats() UpdateAllSpellCritChances(); UpdateDefenseBonusesMod(); UpdateShieldBlockValue(); + UpdateArmorPenetration(); UpdateSpellDamageAndHealingBonus(); UpdateManaRegen(); UpdateExpertise(BASE_ATTACK); @@ -648,6 +649,30 @@ void Player::UpdateExpertise(WeaponAttackType attack) } } +void Player::UpdateArmorPenetration() +{ + m_armorPenetrationPct = GetRatingBonusValue(CR_ARMOR_PENETRATION); + + AuraList const& armorAuras = GetAurasByType(SPELL_AURA_MOD_TARGET_ARMOR_PCT); + for(AuraList::const_iterator itr = armorAuras.begin(); itr != armorAuras.end(); ++itr) + { + // affects all weapons + if((*itr)->GetSpellProto()->EquippedItemClass == -1) + { + m_armorPenetrationPct += (*itr)->GetModifier()->m_amount; + continue; + } + + // dependent on weapon class + for(uint8 i = 0; i < MAX_ATTACK; ++i) + { + Item *weapon = GetWeaponForAttack(WeaponAttackType(i)); + if(weapon && weapon->IsFitToSpellRequirements((*itr)->GetSpellProto())) + m_armorPenetrationPct += (*itr)->GetModifier()->m_amount; + } + } +} + void Player::ApplyManaRegenBonus(int32 amount, bool apply) { m_baseManaRegen+= apply ? amount : -amount; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 9b3cac73b..a69fb3582 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1569,12 +1569,9 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage) // Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura armor += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_NORMAL); - // Apply Player CR_ARMOR_PENETRATION rating + // Apply Player CR_ARMOR_PENETRATION rating and percent talents if (GetTypeId()==TYPEID_PLAYER) - armor *= 1.0f - ((Player*)this)->GetRatingBonusValue(CR_ARMOR_PENETRATION) / 100.0f; - - // Ignore enemy armor by SPELL_AURA_MOD_TARGET_ARMOR_PCT - armor *= 1.0f - GetTotalAuraModifier(SPELL_AURA_MOD_TARGET_ARMOR_PCT) / 100.0f; + armor *= 1.0f - ((Player*)this)->GetArmorPenetrationPct() / 100.0f; if (armor < 0.0f) armor = 0.0f; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a3d1f2ab5..e842472e2 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 "8457" + #define REVISION_NR "8458" #endif // __REVISION_NR_H__