[8661] Fixes and improvments in absorb/reduction damage ignore auras work.

* Use stored in aura amount percent damage ignore for auras SPELL_AURA_MOD_IGNORE_ABSORB_FOR_SPELL
* Implement apply percent damage ignore for absorb (SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL (194))
  and redunction (SPELL_AURA_MOD_IGNORE_DAMAGE_REDUCTION_SCHOOL (269)).
  Later need recheck what from this 2 auras applied to armor reduction
  (currently 269 used only in single spell and this spell is single affecting armor
  and single normal school damage applied with 194 aura)
  Also unclear is this must applied to DoTs, expected that not need.
* Implement talent 53375 boots for spell 31884.
This commit is contained in:
VladimirMangos 2009-10-18 04:51:10 +04:00
parent 2412777007
commit 2e884f4228
5 changed files with 105 additions and 35 deletions

View file

@ -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,

View file

@ -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()))

View file

@ -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;

View file

@ -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;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8660"
#define REVISION_NR "8661"
#endif // __REVISION_NR_H__