diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index ced1d1f47..addcf5b2b 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -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); } } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 1e8b5fd2e..77b56d566 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -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);