diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 41a9d79a2..72a60b800 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1254,13 +1254,13 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama // Script Hook For CalculateSpellDamageTaken -- Allow scripts to change the Damage post class mitigation calculations sScriptMgr->ModifySpellDamageTaken(damageInfo->target, damageInfo->attacker, damage); + int32 cleanDamage = 0; if (Unit::IsDamageReducedByArmor(damageSchoolMask, spellInfo)) { - damageInfo->damage = Unit::CalcArmorReducedDamage(this, victim, damage, spellInfo, 0, attackType); - damageInfo->cleanDamage += damage - damageInfo->damage; + int32 oldDamage = damage; + damage = Unit::CalcArmorReducedDamage(this, victim, damage, spellInfo, 0, attackType); + cleanDamage = oldDamage - damage; } - else - damageInfo->damage = damage; bool blocked = false; // Per-school calc @@ -1282,11 +1282,11 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT; // Calculate crit bonus - uint32 crit_bonus = damageInfo->damage; + uint32 crit_bonus = damage; // Apply crit_damage bonus for melee spells if (Player* modOwner = GetSpellModOwner()) modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); - damageInfo->damage += crit_bonus; + damage += crit_bonus; // Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE float critPctDamageMod = 0.0f; @@ -1302,7 +1302,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama critPctDamageMod += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS, crTypeMask); if (critPctDamageMod != 0) - AddPct(damageInfo->damage, critPctDamageMod); + AddPct(damage, critPctDamageMod); } // Spell weapon based damage CAN BE crit & blocked at same time @@ -1315,22 +1315,26 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama if (damage < int32(damageInfo->blocked)) damageInfo->blocked = uint32(damage); - damageInfo->damage -= damageInfo->blocked; - damageInfo->cleanDamage += damageInfo->blocked; + damage -= damageInfo->blocked; + cleanDamage += damageInfo->blocked; } - int32 resilienceReduction = damageInfo->damage; + int32 resilienceReduction = damage; if (CanApplyResilience()) { if (attackType != RANGED_ATTACK) + { Unit::ApplyResilience(victim, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_MELEE); + } else + { Unit::ApplyResilience(victim, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_RANGED); + } } - resilienceReduction = damageInfo->damage - resilienceReduction; - damageInfo->damage -= resilienceReduction; - damageInfo->cleanDamage += resilienceReduction; + resilienceReduction = damage - resilienceReduction; + damage -= resilienceReduction; + cleanDamage += resilienceReduction; break; } // Magical Attacks @@ -1341,24 +1345,29 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama if (crit) { damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT; - damageInfo->damage = Unit::SpellCriticalDamageBonus(this, spellInfo, damageInfo->damage, victim); + damage = Unit::SpellCriticalDamageBonus(this, spellInfo, damage, victim); } - int32 resilienceReduction = damageInfo->damage; + int32 resilienceReduction = damage; if (CanApplyResilience()) + { Unit::ApplyResilience(victim, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_SPELL); + } - resilienceReduction = damageInfo->damage - resilienceReduction; - damageInfo->damage -= resilienceReduction; - damageInfo->cleanDamage += resilienceReduction; + resilienceReduction = damage - resilienceReduction; + damage -= resilienceReduction; + cleanDamage += resilienceReduction; break; } default: break; } + damageInfo->cleanDamage = std::max(0, cleanDamage); + damageInfo->damage = std::max(0, damage); + // Calculate absorb resist - if (int32(damageInfo->damage) > 0) + if (damageInfo->damage > 0) { DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE); Unit::CalcAbsorbResist(dmgInfo); @@ -1366,8 +1375,6 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama damageInfo->resist = dmgInfo.GetResist(); damageInfo->damage = dmgInfo.GetDamage(); } - else - damageInfo->damage = 0; } void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss, Spell const* spell /*= nullptr*/) @@ -1578,18 +1585,24 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam if (!(damageInfo->HitInfo & HITINFO_MISS)) damageInfo->HitInfo |= HITINFO_AFFECTS_VICTIM; - int32 resilienceReduction = damageInfo->damage; - // attackType is checked already for BASE_ATTACK or OFF_ATTACK so it can't be RANGED_ATTACK here + int32 dmg = damageInfo->damage; + int32 cleanDamage = damageInfo->cleanDamage; if (CanApplyResilience()) + { + int32 resilienceReduction = dmg; Unit::ApplyResilience(victim, nullptr, &resilienceReduction, (damageInfo->hitOutCome == MELEE_HIT_CRIT), CR_CRIT_TAKEN_MELEE); - resilienceReduction = damageInfo->damage - resilienceReduction; - damageInfo->damage -= resilienceReduction; - damageInfo->cleanDamage += resilienceReduction; + resilienceReduction = dmg - resilienceReduction; + dmg -= resilienceReduction; + cleanDamage += resilienceReduction; + } + + damageInfo->damage = std::max(0, dmg); + damageInfo->cleanDamage = std::max(0, cleanDamage); // Calculate absorb resist - if (int32(damageInfo->damage) > 0) + if (damageInfo->damage > 0) { damageInfo->procVictim |= PROC_FLAG_TAKEN_DAMAGE; // Calculate absorb & resists @@ -1610,8 +1623,6 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam damageInfo->damage = dmgInfo.GetDamage(); } - else // Impossible get negative result but.... - damageInfo->damage = 0; } void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 3955eca0e..1e5187024 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -6352,16 +6352,21 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const damage = target->CalculateAOEDamageReduction(damage, GetSpellInfo()->SchoolMask, caster); } + int32 dmg = damage; + int32 mitigatedDamage = cleanDamage.mitigated_damage; if (CanApplyResilience()) { - int32 resilienceReduction = damage; + int32 resilienceReduction = dmg; Unit::ApplyResilience(target, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_SPELL); - resilienceReduction = damage - resilienceReduction; - damage -= resilienceReduction; - cleanDamage.mitigated_damage += resilienceReduction; + resilienceReduction = dmg - resilienceReduction; + dmg -= resilienceReduction; + mitigatedDamage += resilienceReduction; } + damage = std::max(0, dmg); + cleanDamage.mitigated_damage = std::max(0, mitigatedDamage); + DamageInfo dmgInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, cleanDamage.mitigated_damage); Unit::CalcAbsorbResist(dmgInfo); @@ -6433,16 +6438,21 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c damage = damageReductedArmor; } + int32 dmg = damage; + int32 cleanDamageAmount = cleanDamage.mitigated_damage; if (CanApplyResilience()) { - int32 resilienceReduction = damage; + int32 resilienceReduction = dmg; Unit::ApplyResilience(target, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_SPELL); - resilienceReduction = damage - resilienceReduction; - damage -= resilienceReduction; - cleanDamage.mitigated_damage += resilienceReduction; + resilienceReduction = dmg - resilienceReduction; + dmg -= resilienceReduction; + cleanDamageAmount += resilienceReduction; } + damage = std::max(0, dmg); + cleanDamage.mitigated_damage = std::max(0, cleanDamageAmount); + DamageInfo dmgInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, cleanDamage.mitigated_damage); Unit::CalcAbsorbResist(dmgInfo);