mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-13 01:08:35 +00:00
fix(Core/Unit): Fix thorns/retribution aura only dealing damage on white hits (#23041)
This commit is contained in:
@@ -866,6 +866,9 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage
|
||||
// interrupting auras with AURA_INTERRUPT_FLAG_DAMAGE before checking !damage (absorbed damage breaks that type of auras)
|
||||
if (spellProto)
|
||||
{
|
||||
if (attacker && damagetype != DOT && spellProto->DmgClass == SPELL_DAMAGE_CLASS_MELEE && !(spellProto->GetSchoolMask() & SPELL_SCHOOL_MASK_HOLY))
|
||||
attacker->DealDamageShieldDamage(victim);
|
||||
|
||||
if (!spellProto->HasAttribute(SPELL_ATTR4_REACTIVE_DAMAGE_PROC))
|
||||
victim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TAKE_DAMAGE, spellProto->Id);
|
||||
}
|
||||
@@ -1973,57 +1976,60 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
|
||||
|
||||
// Do effect if any damage done to target
|
||||
if (damageInfo->damages[0].damage + damageInfo->damages[1].damage)
|
||||
DealDamageShieldDamage(victim);
|
||||
}
|
||||
|
||||
void Unit::DealDamageShieldDamage(Unit* victim)
|
||||
{
|
||||
// We're going to call functions which can modify content of the list during iteration over it's elements
|
||||
// Let's copy the list so we can prevent iterator invalidation
|
||||
AuraEffectList vDamageShieldsCopy(victim->GetAuraEffectsByType(SPELL_AURA_DAMAGE_SHIELD));
|
||||
for (AuraEffectList::const_iterator dmgShieldItr = vDamageShieldsCopy.begin(); dmgShieldItr != vDamageShieldsCopy.end(); ++dmgShieldItr)
|
||||
{
|
||||
// We're going to call functions which can modify content of the list during iteration over it's elements
|
||||
// Let's copy the list so we can prevent iterator invalidation
|
||||
AuraEffectList vDamageShieldsCopy(victim->GetAuraEffectsByType(SPELL_AURA_DAMAGE_SHIELD));
|
||||
for (AuraEffectList::const_iterator dmgShieldItr = vDamageShieldsCopy.begin(); dmgShieldItr != vDamageShieldsCopy.end(); ++dmgShieldItr)
|
||||
SpellInfo const* i_spellProto = (*dmgShieldItr)->GetSpellInfo();
|
||||
// Damage shield can be resisted...
|
||||
if (SpellMissInfo missInfo = victim->SpellHitResult(this, i_spellProto, false))
|
||||
{
|
||||
SpellInfo const* i_spellProto = (*dmgShieldItr)->GetSpellInfo();
|
||||
// Damage shield can be resisted...
|
||||
if (SpellMissInfo missInfo = victim->SpellHitResult(this, i_spellProto, false))
|
||||
{
|
||||
victim->SendSpellMiss(this, i_spellProto->Id, missInfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
// ...or immuned
|
||||
if (IsImmunedToDamageOrSchool(i_spellProto))
|
||||
{
|
||||
victim->SendSpellDamageImmune(this, i_spellProto->Id);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 damage = uint32(std::max(0, (*dmgShieldItr)->GetAmount())); // xinef: done calculated at amount calculation
|
||||
|
||||
if (Unit* caster = (*dmgShieldItr)->GetCaster())
|
||||
{
|
||||
damage = caster->SpellDamageBonusDone(this, i_spellProto, damage, SPELL_DIRECT_DAMAGE, (*dmgShieldItr)->GetEffIndex());
|
||||
damage = this->SpellDamageBonusTaken(caster, i_spellProto, damage, SPELL_DIRECT_DAMAGE);
|
||||
}
|
||||
|
||||
uint32 absorb = 0;
|
||||
|
||||
DamageInfo dmgInfo(victim, this, damage, i_spellProto, i_spellProto->GetSchoolMask(), SPELL_DIRECT_DAMAGE);
|
||||
Unit::CalcAbsorbResist(dmgInfo);
|
||||
absorb = dmgInfo.GetAbsorb();
|
||||
damage = dmgInfo.GetDamage();
|
||||
|
||||
Unit::DealDamageMods(this, damage, &absorb);
|
||||
|
||||
/// @todo: Move this to a packet handler
|
||||
WorldPacket data(SMSG_SPELLDAMAGESHIELD, (8 + 8 + 4 + 4 + 4 + 4));
|
||||
data << victim->GetGUID();
|
||||
data << GetGUID();
|
||||
data << uint32(i_spellProto->Id);
|
||||
data << uint32(damage); // Damage
|
||||
int32 overkill = int32(damage) - int32(GetHealth());
|
||||
data << uint32(overkill > 0 ? overkill : 0); // Overkill
|
||||
data << uint32(i_spellProto->GetSchoolMask());
|
||||
victim->SendMessageToSet(&data, true);
|
||||
|
||||
Unit::DealDamage(victim, this, damage, 0, SPELL_DIRECT_DAMAGE, i_spellProto->GetSchoolMask(), i_spellProto, true);
|
||||
victim->SendSpellMiss(this, i_spellProto->Id, missInfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
// ...or immuned
|
||||
if (IsImmunedToDamageOrSchool(i_spellProto))
|
||||
{
|
||||
victim->SendSpellDamageImmune(this, i_spellProto->Id);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32 damage = uint32(std::max(0, (*dmgShieldItr)->GetAmount())); // xinef: done calculated at amount calculation
|
||||
|
||||
if (Unit* caster = (*dmgShieldItr)->GetCaster())
|
||||
{
|
||||
damage = caster->SpellDamageBonusDone(this, i_spellProto, damage, SPELL_DIRECT_DAMAGE, (*dmgShieldItr)->GetEffIndex());
|
||||
damage = this->SpellDamageBonusTaken(caster, i_spellProto, damage, SPELL_DIRECT_DAMAGE);
|
||||
}
|
||||
|
||||
uint32 absorb = 0;
|
||||
|
||||
DamageInfo dmgInfo(victim, this, damage, i_spellProto, i_spellProto->GetSchoolMask(), SPELL_DIRECT_DAMAGE);
|
||||
Unit::CalcAbsorbResist(dmgInfo);
|
||||
absorb = dmgInfo.GetAbsorb();
|
||||
damage = dmgInfo.GetDamage();
|
||||
|
||||
Unit::DealDamageMods(this, damage, &absorb);
|
||||
|
||||
/// @todo: Move this to a packet handler
|
||||
WorldPacket data(SMSG_SPELLDAMAGESHIELD, (8 + 8 + 4 + 4 + 4 + 4));
|
||||
data << victim->GetGUID();
|
||||
data << GetGUID();
|
||||
data << uint32(i_spellProto->Id);
|
||||
data << uint32(damage); // Damage
|
||||
int32 overkill = int32(damage) - int32(GetHealth());
|
||||
data << uint32(overkill > 0 ? overkill : 0); // Overkill
|
||||
data << uint32(i_spellProto->GetSchoolMask());
|
||||
victim->SendMessageToSet(&data, true);
|
||||
|
||||
Unit::DealDamage(victim, this, damage, 0, SPELL_DIRECT_DAMAGE, i_spellProto->GetSchoolMask(), i_spellProto, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1171,6 +1171,7 @@ public:
|
||||
static uint32 DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = nullptr, bool durabilityLoss = true, bool allowGM = false, Spell const* spell = nullptr);
|
||||
void DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss);
|
||||
void DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss, Spell const* spell = nullptr);
|
||||
void DealDamageShieldDamage(Unit* victim);
|
||||
static void DealDamageMods(Unit const* victim, uint32& damage, uint32* absorb);
|
||||
|
||||
static void Kill(Unit* killer, Unit* victim, bool durabilityLoss = true, WeaponAttackType attackType = BASE_ATTACK, SpellInfo const* spellProto = nullptr, Spell const* spell = nullptr);
|
||||
|
||||
Reference in New Issue
Block a user