diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index 2700d1d2f..31ee1dcf1 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -311,7 +311,7 @@ enum AuraType SPELL_AURA_266 = 266, SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL = 267, SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268, - SPELL_AURA_269 = 269, + SPELL_AURA_MOD_IGNORE_DAMAGE_REDUCTION_SCHOOL = 269, SPELL_AURA_MOD_IGNORE_TARGET_RESIST = 270, // Possibly need swap vs 195 aura used only in 1 spell Chaos Bolt Passive SPELL_AURA_MOD_DAMAGE_FROM_CASTER = 271, SPELL_AURA_272 = 272, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 738d4d6de..674ae44e1 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -244,8 +244,8 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED &Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE &Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct) - &Aura::HandleNULL, //194 SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL - &Aura::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL implement in Unit::CalculateSpellDamage + &Aura::HandleNoImmediateEffect, //194 SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL implement in Unit::CalcNotIgnoreAbsorbDamage + &Aura::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL implement in Unit::CalcNotIgnoreAbsorbDamage &Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN &Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance &Aura::HandleUnused, //198 unused (3.0.8a) old SPELL_AURA_MOD_ALL_WEAPON_SKILLS @@ -319,7 +319,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]= &Aura::HandleUnused, //266 unused (3.0.8a) &Aura::HandleNoImmediateEffect, //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL implemented in Unit::IsImmunedToSpellEffect &Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT - &Aura::HandleNULL, //269 ignore DR effects? + &Aura::HandleNoImmediateEffect, //269 SPELL_AURA_MOD_IGNORE_DAMAGE_REDUCTION_SCHOOL &Aura::HandleNULL, //270 SPELL_AURA_MOD_IGNORE_TARGET_RESIST &Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus &Aura::HandleNULL, //272 reduce spell cast time? @@ -5764,6 +5764,37 @@ void Aura::HandleSpellSpecificBoosts(bool apply) } case SPELLFAMILY_PALADIN: { + if (m_spellProto->Id == 31884) // Avenging Wrath + { + if(!apply) + spellId1 = 57318; // Sanctified Wrath (triggered) + else + { + int32 percent = 0; + Unit::AuraList const& dummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY); + for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) + { + if ((*itr)->GetSpellProto()->SpellIconID == 3029) + { + percent = (*itr)->GetModifier()->m_amount; + break; + } + } + + // apply in special way + if(percent) + { + spellId1 = 57318; // Sanctified Wrath (triggered) + // prevent aura deletion, specially in multi-boost case + SetInUse(true); + m_target->CastCustomSpell(m_target, spellId1, &percent, &percent, NULL, true, NULL, this); + SetInUse(false); + } + return; + } + break; + } + // Only process on player casting paladin aura // all aura bonuses applied also in aura area effect way to caster if (GetCasterGUID() != m_target->GetGUID() || !IS_PLAYER_GUID(GetCasterGUID())) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index be1bc79b6..b4de81677 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1060,7 +1060,10 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim); // Resilience - reduce crit damage if (pVictim->GetTypeId()==TYPEID_PLAYER) - damage -= ((Player*)pVictim)->GetMeleeCritDamageReduction(damage); + { + uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask); + damage -= ((Player*)pVictim)->GetMeleeCritDamageReduction(redunction_affected_damage); + } } } break; @@ -1077,21 +1080,30 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S damage = SpellCriticalDamageBonus(spellInfo, damage, pVictim); // Resilience - reduce crit damage if (pVictim->GetTypeId()==TYPEID_PLAYER) - damage -= ((Player*)pVictim)->GetSpellCritDamageReduction(damage); + { + uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask); + damage -= ((Player*)pVictim)->GetSpellCritDamageReduction(redunction_affected_damage); + } } } break; } if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER) - damage -= ((Player*)pVictim)->GetSpellDamageReduction(damage); + { + uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask); + damage -= ((Player*)pVictim)->GetSpellDamageReduction(redunction_affected_damage); + } // damage mitigation - if(damage > 0) + if (damage > 0) { // physical damage => armor - if ( damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL ) - damage = CalcArmorReducedDamage(pVictim, damage); + if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL) + { + uint32 armor_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageSchoolMask); + damage = damage - armor_affected_damage + CalcArmorReducedDamage(pVictim, armor_affected_damage); + } // block (only for damage class ranged and -melee, also non-physical damage possible) if (blocked) @@ -1102,21 +1114,9 @@ void Unit::CalculateSpellDamage(SpellNonMeleeDamage *damageInfo, int32 damage, S damage-=damageInfo->blocked; } - // absorb/resist: lookup ignore auras on caster for spell - bool ignore = false; - Unit::AuraList const& ignoreAbsorb = GetAurasByType(SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL); - for(Unit::AuraList::const_iterator i = ignoreAbsorb.begin(); i != ignoreAbsorb.end(); ++i) - if ((*i)->isAffectedOnSpell(spellInfo)) - { - ignore = true; - break; - } - - if (!ignore) - { - CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist); - damage-= damageInfo->absorb + damageInfo->resist; - } + uint32 absorb_affected_damage = CalcNotIgnoreAbsorbDamage(damage,damageSchoolMask,spellInfo); + CalcAbsorbResist(pVictim, damageSchoolMask, SPELL_DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist); + damage-= damageInfo->absorb + damageInfo->resist; } else damage = 0; @@ -1205,7 +1205,7 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da } // Physical Immune check - if(damageInfo->target->IsImmunedToDamage(SpellSchoolMask(damageInfo->damageSchoolMask))) + if (damageInfo->target->IsImmunedToDamage(damageInfo->damageSchoolMask)) { damageInfo->HitInfo |= HITINFO_NORMALSWING; damageInfo->TargetState = VICTIMSTATE_IS_IMMUNE; @@ -1219,13 +1219,15 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da // Add melee damage bonus damage = MeleeDamageBonus(damageInfo->target, damage, damageInfo->attackType); // Calculate armor reduction - damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage); + + uint32 armor_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageInfo->damageSchoolMask); + damageInfo->damage = damage - armor_affected_damage + CalcArmorReducedDamage(damageInfo->target, armor_affected_damage); damageInfo->cleanDamage += damage - damageInfo->damage; damageInfo->hitOutCome = RollMeleeOutcomeAgainst(damageInfo->target, damageInfo->attackType); // Disable parry or dodge for ranged attack - if(damageInfo->attackType == RANGED_ATTACK) + if (damageInfo->attackType == RANGED_ATTACK) { if (damageInfo->hitOutCome == MELEE_HIT_PARRY) damageInfo->hitOutCome = MELEE_HIT_NORMAL; if (damageInfo->hitOutCome == MELEE_HIT_DODGE) damageInfo->hitOutCome = MELEE_HIT_MISS; @@ -1285,7 +1287,8 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da // Resilience - reduce crit damage if (pVictim->GetTypeId()==TYPEID_PLAYER) { - uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(damageInfo->damage); + uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damageInfo->damage,damageInfo->damageSchoolMask); + uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(redunction_affected_damage); damageInfo->damage -= resilienceReduction; damageInfo->cleanDamage += resilienceReduction; } @@ -1389,18 +1392,21 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER) { + uint32 redunction_affected_damage = CalcNotIgnoreDamageRedunction(damage,damageInfo->damageSchoolMask); if (attackType != RANGED_ATTACK) - damage-=((Player*)pVictim)->GetMeleeDamageReduction(damage); + damage-=((Player*)pVictim)->GetMeleeDamageReduction(redunction_affected_damage); else - damage-=((Player*)pVictim)->GetRangedDamageReduction(damage); + damage-=((Player*)pVictim)->GetRangedDamageReduction(redunction_affected_damage); } // Calculate absorb resist if(int32(damageInfo->damage) > 0) { damageInfo->procVictim |= PROC_FLAG_TAKEN_ANY_DAMAGE; + // Calculate absorb & resists - CalcAbsorbResist(damageInfo->target, SpellSchoolMask(damageInfo->damageSchoolMask), DIRECT_DAMAGE, damageInfo->damage, &damageInfo->absorb, &damageInfo->resist); + uint32 absorb_affected_damage = CalcNotIgnoreAbsorbDamage(damageInfo->damage,damageInfo->damageSchoolMask); + CalcAbsorbResist(damageInfo->target, damageInfo->damageSchoolMask, DIRECT_DAMAGE, absorb_affected_damage, &damageInfo->absorb, &damageInfo->resist); damageInfo->damage-=damageInfo->absorb + damageInfo->resist; if (damageInfo->absorb) { @@ -1479,7 +1485,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss) // Call default DealDamage CleanDamage cleanDamage(damageInfo->cleanDamage,damageInfo->attackType,damageInfo->hitOutCome); - DealDamage(pVictim, damageInfo->damage, &cleanDamage, DIRECT_DAMAGE, SpellSchoolMask(damageInfo->damageSchoolMask), NULL, durabilityLoss); + DealDamage(pVictim, damageInfo->damage, &cleanDamage, DIRECT_DAMAGE, damageInfo->damageSchoolMask, NULL, durabilityLoss); // If this is a creature and it attacks from behind it has a probability to daze it's victim if( (damageInfo->hitOutCome==MELEE_HIT_CRIT || damageInfo->hitOutCome==MELEE_HIT_CRUSHING || damageInfo->hitOutCome==MELEE_HIT_NORMAL || damageInfo->hitOutCome==MELEE_HIT_GLANCING) && @@ -1558,6 +1564,36 @@ void Unit::HandleEmoteCommand(uint32 anim_id) SendMessageToSet(&data, true); } +uint32 Unit::CalcNotIgnoreAbsorbDamage( uint32 damage, SpellSchoolMask damageSchoolMask, SpellEntry const* spellInfo /*= NULL*/) +{ + float absorb_affected_rate = 1.0f; + Unit::AuraList const& ignoreAbsorb = GetAurasByType(SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL); + for(Unit::AuraList::const_iterator i = ignoreAbsorb.begin(); i != ignoreAbsorb.end(); ++i) + if ((*i)->GetMiscValue() & damageSchoolMask) + absorb_affected_rate *= (100.0f - (*i)->GetModifier()->m_amount)/100.0f; + + if(spellInfo) + { + Unit::AuraList const& ignoreAbsorb = GetAurasByType(SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL); + for(Unit::AuraList::const_iterator i = ignoreAbsorb.begin(); i != ignoreAbsorb.end(); ++i) + if ((*i)->isAffectedOnSpell(spellInfo)) + absorb_affected_rate *= (100.0f - (*i)->GetModifier()->m_amount)/100.0f; + } + + return absorb_affected_rate <= 0.0f ? 0 : (absorb_affected_rate < 1.0f ? uint32(damage * absorb_affected_rate) : damage); +} + +uint32 Unit::CalcNotIgnoreDamageRedunction( uint32 damage, SpellSchoolMask damageSchoolMask) +{ + float absorb_affected_rate = 1.0f; + Unit::AuraList const& ignoreAbsorb = GetAurasByType(SPELL_AURA_MOD_IGNORE_DAMAGE_REDUCTION_SCHOOL); + for(Unit::AuraList::const_iterator i = ignoreAbsorb.begin(); i != ignoreAbsorb.end(); ++i) + if ((*i)->GetMiscValue() & damageSchoolMask) + absorb_affected_rate *= (100.0f - (*i)->GetModifier()->m_amount)/100.0f; + + return absorb_affected_rate <= 0.0f ? 0 : (absorb_affected_rate < 1.0f ? uint32(damage * absorb_affected_rate) : damage); +} + uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage) { uint32 newdamage = 0; diff --git a/src/game/Unit.h b/src/game/Unit.h index 4725b4a84..48d53db0b 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -637,7 +637,7 @@ struct CalcDamageInfo { Unit *attacker; // Attacker Unit *target; // Target for damage - uint32 damageSchoolMask; + SpellSchoolMask damageSchoolMask; uint32 damage; uint32 absorb; uint32 resist; @@ -1468,6 +1468,9 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void _ApplyAllAuraMods(); int32 CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_index, int32 basePoints, Unit const* target); + + uint32 CalcNotIgnoreAbsorbDamage( uint32 damage, SpellSchoolMask damageSchoolMask, SpellEntry const* spellInfo = NULL); + uint32 CalcNotIgnoreDamageRedunction( uint32 damage, SpellSchoolMask damageSchoolMask); int32 CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_index, Unit const* target); float CalculateLevelPenalty(SpellEntry const* spellProto) const; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 5894aa664..34c7ed8af 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 "8660" + #define REVISION_NR "8661" #endif // __REVISION_NR_H__