diff options
author | ariel- <ariel-@users.noreply.github.com> | 2016-10-26 02:16:11 -0300 |
---|---|---|
committer | joschiwald <joschiwald.trinity@gmail.com> | 2017-10-15 16:59:56 +0200 |
commit | fe2e3b67a86be5a486c5bfd79d09986b9092a872 (patch) | |
tree | 400abfa2e9e8c9fad1ab5d7dedb7c850426051f9 | |
parent | a932e448478c48f1c8f96502b73ed49e2bd4c73d (diff) |
Core/Spells: use DamageInfo struct to calc spell absorbs and resists, and use calculated proc hitMask on aura ticks
Closes #18135
(cherry picked from commit d3a71a83387f757f87c7d27e1054498c8cc49c8f)
# Conflicts:
# src/server/game/Entities/Unit/Unit.cpp
# src/server/game/Entities/Unit/Unit.h
# src/server/game/Spells/Auras/SpellAuraEffects.cpp
# src/server/game/Spells/SpellEffects.cpp
# src/server/scripts/Commands/cs_misc.cpp
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 21 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 133 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 6 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraEffects.cpp | 35 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 21 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_misc.cpp | 19 |
6 files changed, 120 insertions, 115 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 993dfa9caa3..6ba48a7d80f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -775,12 +775,21 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage) // Absorb, resist some environmental damage type uint32 absorb = 0; uint32 resist = 0; - if (type == DAMAGE_LAVA) - CalcAbsorbResist(this, SPELL_SCHOOL_MASK_FIRE, DIRECT_DAMAGE, damage, &absorb, &resist); - else if (type == DAMAGE_SLIME) - CalcAbsorbResist(this, SPELL_SCHOOL_MASK_NATURE, DIRECT_DAMAGE, damage, &absorb, &resist); - - damage -= absorb + resist; + switch (type) + { + case DAMAGE_LAVA: + case DAMAGE_SLIME: + { + DamageInfo dmgInfo(this, this, damage, nullptr, type == DAMAGE_LAVA ? SPELL_SCHOOL_MASK_FIRE : SPELL_SCHOOL_MASK_NATURE, DIRECT_DAMAGE, BASE_ATTACK); + CalcAbsorbResist(dmgInfo); + absorb = dmgInfo.GetAbsorb(); + resist = dmgInfo.GetResist(); + damage = dmgInfo.GetDamage(); + break; + } + default: + break; + } DealDamageMods(this, damage, &absorb); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 5efa81730cf..a2f0ae3cd38 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -679,7 +679,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons || HasBreakableByDamageAuraType(SPELL_AURA_TRANSFORM, excludeAura)); } -void Unit::DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb) +void Unit::DealDamageMods(Unit const* victim, uint32 &damage, uint32* absorb) const { if (!victim || !victim->IsAlive() || victim->HasUnitState(UNIT_STATE_IN_FLIGHT) || (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsEvadingAttacks())) { @@ -1146,15 +1146,13 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama sScriptMgr->ModifySpellDamageTaken(damageInfo->target, damageInfo->attacker, damage); // Calculate absorb resist - if (damage > 0) - { - CalcAbsorbResist(victim, damageSchoolMask, SPELL_DIRECT_DAMAGE, damage, &damageInfo->absorb, &damageInfo->resist, spellInfo); - damage -= damageInfo->absorb + damageInfo->resist; - } - else + if (damage < 0) damage = 0; damageInfo->damage = damage; + DamageInfo dmgInfo(*damageInfo, SPELL_DIRECT_DAMAGE, BASE_ATTACK, PROC_HIT_NONE); + CalcAbsorbResist(dmgInfo); + damageInfo->damage = dmgInfo.GetDamage(); } void Unit::DealSpellDamage(SpellNonMeleeDamage const* damageInfo, bool durabilityLoss) @@ -1341,15 +1339,17 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam { damageInfo->procVictim |= PROC_FLAG_TAKEN_DAMAGE; // Calculate absorb & resists - CalcAbsorbResist(damageInfo->target, SpellSchoolMask(damageInfo->damageSchoolMask), DIRECT_DAMAGE, damageInfo->damage, &damageInfo->absorb, &damageInfo->resist); + DamageInfo dmgInfo(*damageInfo); + CalcAbsorbResist(dmgInfo); + damageInfo->absorb = dmgInfo.GetAbsorb(); + damageInfo->resist = dmgInfo.GetResist(); + damageInfo->damage = dmgInfo.GetDamage(); if (damageInfo->absorb) damageInfo->HitInfo |= (damageInfo->damage - damageInfo->absorb == 0 ? HITINFO_FULL_ABSORB : HITINFO_PARTIAL_ABSORB); if (damageInfo->resist) damageInfo->HitInfo |= (damageInfo->damage - damageInfo->resist == 0 ? HITINFO_FULL_RESIST : HITINFO_PARTIAL_RESIST); - - damageInfo->damage -= damageInfo->absorb + damageInfo->resist; } else // Impossible get negative result but.... damageInfo->damage = 0; @@ -1470,8 +1470,9 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) damage = this->SpellDamageBonusTaken(caster, i_spellProto, damage, SPELL_DIRECT_DAMAGE, (*dmgShieldItr)->GetSpellEffectInfo()); } - uint32 absorb = 0, resist = 0; - victim->CalcAbsorbResist(this, SpellSchoolMask(i_spellProto->SchoolMask), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist, i_spellProto); + DamageInfo damageInfo(this, victim, damage, i_spellProto, i_spellProto->GetSchoolMask(), SPELL_DIRECT_DAMAGE, BASE_ATTACK); + victim->CalcAbsorbResist(damageInfo); + damage = damageInfo.GetDamage(); // No Unit::CalcAbsorbResist here - opcode doesn't send that data - this damage is probably not affected by that victim->DealDamageMods(this, damage, NULL); @@ -1482,7 +1483,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) damageShield.TotalDamage = damage; damageShield.OverKill = std::max(int32(damage) - int32(GetHealth()), 0); damageShield.SchoolMask = i_spellProto->SchoolMask; - damageShield.LogAbsorbed = absorb; + damageShield.LogAbsorbed = damageInfo.GetAbsorb(); victim->DealDamage(this, damage, 0, SPELL_DIRECT_DAMAGE, i_spellProto->GetSchoolMask(), i_spellProto, true); @@ -1658,57 +1659,49 @@ uint32 Unit::CalcSpellResistance(Unit* victim, SpellSchoolMask schoolMask, Spell return resistance * 10; } -void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, uint32 const damage, uint32* absorb, uint32* resist, SpellInfo const* spellInfo /*= NULL*/) +void Unit::CalcAbsorbResist(DamageInfo& damageInfo) { - if (!victim || !victim->IsAlive() || !damage) + if (!damageInfo.GetVictim() || !damageInfo.GetVictim()->IsAlive() || !damageInfo.GetDamage()) return; - DamageInfo dmgInfo = DamageInfo(this, victim, damage, spellInfo, schoolMask, damagetype, BASE_ATTACK); - - uint32 spellResistance = CalcSpellResistance(victim, schoolMask, spellInfo); - dmgInfo.ResistDamage(CalculatePct(damage, spellResistance)); + uint32 spellResistance = CalcSpellResistance(damageInfo.GetVictim(), damageInfo.GetSchoolMask(), damageInfo.GetSpellInfo()); + damageInfo.ResistDamage(CalculatePct(damageInfo.GetDamage(), spellResistance)); // Ignore Absorption Auras - float auraAbsorbMod = 0; - AuraEffectList const& AbsIgnoreAurasA = GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL); - for (AuraEffectList::const_iterator itr = AbsIgnoreAurasA.begin(); itr != AbsIgnoreAurasA.end(); ++itr) + float auraAbsorbMod(GetMaxPositiveAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL, damageInfo.GetSchoolMask())); + + AuraEffectList const& abilityAbsorbAuras = GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL); + for (AuraEffect const* aurEff : abilityAbsorbAuras) { - if (!((*itr)->GetMiscValue() & schoolMask)) + if (!(aurEff->GetMiscValue() & damageInfo.GetSchoolMask())) continue; - if ((*itr)->GetAmount() > auraAbsorbMod) - auraAbsorbMod = float((*itr)->GetAmount()); - } - - AuraEffectList const& AbsIgnoreAurasB = GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL); - for (AuraEffectList::const_iterator itr = AbsIgnoreAurasB.begin(); itr != AbsIgnoreAurasB.end(); ++itr) - { - if (!((*itr)->GetMiscValue() & schoolMask)) + if (!aurEff->IsAffectingSpell(damageInfo.GetSpellInfo())) continue; - if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectingSpell(spellInfo)) - auraAbsorbMod = float((*itr)->GetAmount()); + if ((aurEff->GetAmount() > auraAbsorbMod)) + auraAbsorbMod = float(aurEff->GetAmount()); } RoundToInterval(auraAbsorbMod, 0.0f, 100.0f); - int32 absorbIgnoringDamage = CalculatePct(dmgInfo.GetDamage(), auraAbsorbMod); - dmgInfo.ModifyDamage(-absorbIgnoringDamage); + int32 absorbIgnoringDamage = CalculatePct(damageInfo.GetDamage(), auraAbsorbMod); + damageInfo.ModifyDamage(-absorbIgnoringDamage); // 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 vSchoolAbsorbCopy(victim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB)); + AuraEffectList vSchoolAbsorbCopy(damageInfo.GetVictim()->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB)); vSchoolAbsorbCopy.sort(Trinity::AbsorbAuraOrderPred()); // absorb without mana cost - for (AuraEffectList::iterator itr = vSchoolAbsorbCopy.begin(); (itr != vSchoolAbsorbCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr) + for (AuraEffectList::iterator itr = vSchoolAbsorbCopy.begin(); (itr != vSchoolAbsorbCopy.end()) && (damageInfo.GetDamage() > 0); ++itr) { AuraEffect* absorbAurEff = *itr; // Check if aura was removed during iteration - we don't need to work on such auras - AuraApplication const* aurApp = absorbAurEff->GetBase()->GetApplicationOfTarget(victim->GetGUID()); + AuraApplication const* aurApp = absorbAurEff->GetBase()->GetApplicationOfTarget(damageInfo.GetVictim()->GetGUID()); if (!aurApp) continue; - if (!(absorbAurEff->GetMiscValue() & schoolMask)) + if (!(absorbAurEff->GetMiscValue() & damageInfo.GetSchoolMask())) continue; // get amount which can be still absorbed by the aura @@ -1721,19 +1714,19 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe bool defaultPrevented = false; - absorbAurEff->GetBase()->CallScriptEffectAbsorbHandlers(absorbAurEff, aurApp, dmgInfo, tempAbsorb, defaultPrevented); + absorbAurEff->GetBase()->CallScriptEffectAbsorbHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb, defaultPrevented); currentAbsorb = tempAbsorb; if (defaultPrevented) continue; // absorb must be smaller than the damage itself - currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(dmgInfo.GetDamage())); + currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage())); - dmgInfo.AbsorbDamage(currentAbsorb); + damageInfo.AbsorbDamage(currentAbsorb); tempAbsorb = currentAbsorb; - absorbAurEff->GetBase()->CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, dmgInfo, tempAbsorb); + absorbAurEff->GetBase()->CallScriptEffectAfterAbsorbHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb); // Check if our aura is using amount to count damage if (absorbAurEff->GetAmount() >= 0) @@ -1747,16 +1740,16 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe } // absorb by mana cost - AuraEffectList vManaShieldCopy(victim->GetAuraEffectsByType(SPELL_AURA_MANA_SHIELD)); - for (AuraEffectList::const_iterator itr = vManaShieldCopy.begin(); (itr != vManaShieldCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr) + AuraEffectList vManaShieldCopy(damageInfo.GetVictim()->GetAuraEffectsByType(SPELL_AURA_MANA_SHIELD)); + for (AuraEffectList::const_iterator itr = vManaShieldCopy.begin(); (itr != vManaShieldCopy.end()) && (damageInfo.GetDamage() > 0); ++itr) { AuraEffect* absorbAurEff = *itr; // Check if aura was removed during iteration - we don't need to work on such auras - AuraApplication const* aurApp = absorbAurEff->GetBase()->GetApplicationOfTarget(victim->GetGUID()); + AuraApplication const* aurApp = absorbAurEff->GetBase()->GetApplicationOfTarget(damageInfo.GetVictim()->GetGUID()); if (!aurApp) continue; // check damage school mask - if (!(absorbAurEff->GetMiscValue() & schoolMask)) + if (!(absorbAurEff->GetMiscValue() & damageInfo.GetSchoolMask())) continue; // get amount which can be still absorbed by the aura @@ -1769,14 +1762,14 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe bool defaultPrevented = false; - absorbAurEff->GetBase()->CallScriptEffectManaShieldHandlers(absorbAurEff, aurApp, dmgInfo, tempAbsorb, defaultPrevented); + absorbAurEff->GetBase()->CallScriptEffectManaShieldHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb, defaultPrevented); currentAbsorb = tempAbsorb; if (defaultPrevented) continue; // absorb must be smaller than the damage itself - currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(dmgInfo.GetDamage())); + currentAbsorb = RoundToInterval(currentAbsorb, 0, int32(damageInfo.GetDamage())); int32 manaReduction = currentAbsorb; @@ -1784,15 +1777,15 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe if (float manaMultiplier = absorbAurEff->GetSpellEffectInfo()->CalcValueMultiplier(absorbAurEff->GetCaster())) manaReduction = int32(float(manaReduction) * manaMultiplier); - int32 manaTaken = -victim->ModifyPower(POWER_MANA, -manaReduction); + int32 manaTaken = -damageInfo.GetVictim()->ModifyPower(POWER_MANA, -manaReduction); // take case when mana has ended up into account currentAbsorb = currentAbsorb ? int32(float(currentAbsorb) * (float(manaTaken) / float(manaReduction))) : 0; - dmgInfo.AbsorbDamage(currentAbsorb); + damageInfo.AbsorbDamage(currentAbsorb); tempAbsorb = currentAbsorb; - absorbAurEff->GetBase()->CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, dmgInfo, tempAbsorb); + absorbAurEff->GetBase()->CallScriptEffectAfterManaShieldHandlers(absorbAurEff, aurApp, damageInfo, tempAbsorb); // Check if our aura is using amount to count damage if (absorbAurEff->GetAmount() >= 0) @@ -1803,67 +1796,63 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe } } - dmgInfo.ModifyDamage(absorbIgnoringDamage); + damageInfo.ModifyDamage(absorbIgnoringDamage); // split damage auras - only when not damaging self - if (victim != this) + if (damageInfo.GetVictim() != this) { // 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 vSplitDamagePctCopy(victim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT)); - for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(); itr != vSplitDamagePctCopy.end() && dmgInfo.GetDamage() > 0; ++itr) + AuraEffectList vSplitDamagePctCopy(damageInfo.GetVictim()->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT)); + for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(); itr != vSplitDamagePctCopy.end() && damageInfo.GetDamage() > 0; ++itr) { // Check if aura was removed during iteration - we don't need to work on such auras - AuraApplication const* aurApp = (*itr)->GetBase()->GetApplicationOfTarget(victim->GetGUID()); + AuraApplication const* aurApp = (*itr)->GetBase()->GetApplicationOfTarget(damageInfo.GetVictim()->GetGUID()); if (!aurApp) continue; // check damage school mask - if (!((*itr)->GetMiscValue() & schoolMask)) + if (!((*itr)->GetMiscValue() & damageInfo.GetSchoolMask())) continue; // Damage can be splitted only if aura has an alive caster Unit* caster = (*itr)->GetCaster(); - if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->IsAlive()) + if (!caster || (caster == damageInfo.GetVictim()) || !caster->IsInWorld() || !caster->IsAlive()) continue; - uint32 splitDamage = CalculatePct(dmgInfo.GetDamage(), (*itr)->GetAmount()); + uint32 splitDamage = CalculatePct(damageInfo.GetDamage(), (*itr)->GetAmount()); - (*itr)->GetBase()->CallScriptEffectSplitHandlers((*itr), aurApp, dmgInfo, splitDamage); + (*itr)->GetBase()->CallScriptEffectSplitHandlers((*itr), aurApp, damageInfo, splitDamage); // absorb must be smaller than the damage itself - splitDamage = RoundToInterval(splitDamage, uint32(0), uint32(dmgInfo.GetDamage())); + splitDamage = RoundToInterval(splitDamage, uint32(0), uint32(damageInfo.GetDamage())); - dmgInfo.AbsorbDamage(splitDamage); + damageInfo.AbsorbDamage(splitDamage); // check if caster is immune to damage - if (caster->IsImmunedToDamage(schoolMask)) + if (caster->IsImmunedToDamage(damageInfo.GetSchoolMask())) { - victim->SendSpellMiss(caster, (*itr)->GetSpellInfo()->Id, SPELL_MISS_IMMUNE); + damageInfo.GetVictim()->SendSpellMiss(caster, (*itr)->GetSpellInfo()->Id, SPELL_MISS_IMMUNE); continue; } uint32 split_absorb = 0; DealDamageMods(caster, splitDamage, &split_absorb); - SpellNonMeleeDamage log(this, caster, (*itr)->GetSpellInfo()->Id, (*itr)->GetBase()->GetSpellXSpellVisualId(), schoolMask, (*itr)->GetBase()->GetCastGUID()); + SpellNonMeleeDamage log(this, caster, (*itr)->GetSpellInfo()->Id, (*itr)->GetBase()->GetSpellXSpellVisualId(), damageInfo.GetSchoolMask(), (*itr)->GetBase()->GetCastGUID()); CleanDamage cleanDamage = CleanDamage(splitDamage, 0, BASE_ATTACK, MELEE_HIT_NORMAL); - DealDamage(caster, splitDamage, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellInfo(), false); + DealDamage(caster, splitDamage, &cleanDamage, DIRECT_DAMAGE, damageInfo.GetSchoolMask(), (*itr)->GetSpellInfo(), false); log.damage = splitDamage; log.absorb = split_absorb; SendSpellNonMeleeDamageLog(&log); // break 'Fear' and similar auras - DamageInfo damageInfo(caster, this, splitDamage, (*itr)->GetSpellInfo(), schoolMask, DIRECT_DAMAGE, BASE_ATTACK); ProcSkillsAndAuras(caster, PROC_FLAG_NONE, PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_HIT, PROC_HIT_NONE, nullptr, &damageInfo, nullptr); } } - - *resist = dmgInfo.GetResist(); - *absorb = dmgInfo.GetAbsorb(); } -void Unit::CalcHealAbsorb(HealInfo& healInfo) +void Unit::CalcHealAbsorb(HealInfo& healInfo) const { if (!healInfo.GetHeal()) return; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 72e9a35c626..827107d55fc 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1161,7 +1161,7 @@ class TC_GAME_API Unit : public WorldObject uint16 GetMeleeAnimKitId() const override { return _meleeAnimKitId; } uint16 GetMaxSkillValueForLevel(Unit const* target = NULL) const { return (target ? GetLevelForTarget(target) : getLevel()) * 5; } - void DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb); + void DealDamageMods(Unit const* victim, uint32 &damage, uint32* absorb) const; uint32 DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDamage = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = NULL, bool durabilityLoss = true); void Kill(Unit* victim, bool durabilityLoss = true); void KillSelf(bool durabilityLoss = true) { Kill(this, durabilityLoss); } @@ -1767,8 +1767,8 @@ class TC_GAME_API Unit : public WorldObject bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = nullptr, int8 effIndex = -1); uint32 CalcArmorReducedDamage(Unit* attacker, Unit* victim, const uint32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = MAX_ATTACK); uint32 CalcSpellResistance(Unit* victim, SpellSchoolMask schoolMask, SpellInfo const* spellInfo) const; - void CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffectType damagetype, uint32 const damage, uint32* absorb, uint32* resist, SpellInfo const* spellInfo = NULL); - void CalcHealAbsorb(HealInfo& healInfo); + void CalcAbsorbResist(DamageInfo& damageInfo); + void CalcHealAbsorb(HealInfo& healInfo) const; void UpdateSpeed(UnitMoveType mtype); float GetSpeed(UnitMoveType mtype) const; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 501383c4261..41ecfa03e06 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5752,8 +5752,6 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const } } - uint32 absorb = 0; - uint32 resist = 0; CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL); // AOE spells are not affected by the new periodic system. @@ -5822,13 +5820,16 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target); int32 dmg = damage; - if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE)) caster->ApplyResilience(target, &dmg); damage = dmg; - caster->CalcAbsorbResist(target, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, GetSpellInfo()); + DamageInfo damageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, BASE_ATTACK); + caster->CalcAbsorbResist(damageInfo); + damage = damageInfo.GetDamage(); + uint32 absorb = damageInfo.GetAbsorb(); + uint32 resist = damageInfo.GetResist(); TC_LOG_DEBUG("spells.periodic", "PeriodicTick: %s attacked %s for %u dmg inflicted by %u absorb is %u", GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), damage, GetId(), absorb); @@ -5837,8 +5838,10 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const // Set trigger flag uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; - uint32 hitMask = crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL; - damage = (damage <= absorb+resist) ? 0 : (damage-absorb-resist); + uint32 hitMask = damageInfo.GetHitMask(); + if (!hitMask) + hitMask = crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL; + if (damage) procVictim |= PROC_FLAG_TAKEN_DAMAGE; @@ -5848,7 +5851,6 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const SpellPeriodicAuraLogInfo pInfo(this, damage, overkill, absorb, resist, 0.0f, crit); - DamageInfo damageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, BASE_ATTACK); caster->ProcSkillsAndAuras(target, procAttacker, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_NONE, hitMask, nullptr, &damageInfo, nullptr); caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true); @@ -5882,8 +5884,6 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c caster->SpellHitResult(target, GetSpellInfo(), false) != SPELL_MISS_NONE) return; - uint32 absorb = 0; - uint32 resist = 0; CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL); bool isAreaAura = GetSpellEffectInfo()->IsAreaAuraEffect() || GetSpellEffectInfo()->IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA); @@ -5927,13 +5927,17 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c caster->ApplyResilience(target, &dmg); damage = dmg; - caster->CalcAbsorbResist(target, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, m_spellInfo); + DamageInfo damageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, BASE_ATTACK); + caster->CalcAbsorbResist(damageInfo); + uint32 absorb = damageInfo.GetAbsorb(); + uint32 resist = damageInfo.GetResist(); TC_LOG_DEBUG("spells.periodic", "PeriodicTick: %s health leech of %s for %u dmg inflicted by %u abs is %u", GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), damage, GetId(), absorb); + // SendSpellNonMeleeDamageLog expects non-absorbed/non-resisted damage SpellNonMeleeDamage log(caster, target, GetId(), GetBase()->GetSpellXSpellVisualId(), GetSpellInfo()->GetSchoolMask(), GetBase()->GetCastGUID()); - log.damage = damage - absorb - resist; + log.damage = damage; log.absorb = absorb; log.resist = resist; log.periodicLog = true; @@ -5943,16 +5947,15 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c // Set trigger flag uint32 procAttacker = PROC_FLAG_DONE_PERIODIC; uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC; - uint32 hitMask = crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL; - damage = (damage <= absorb+resist) ? 0 : (damage-absorb-resist); + uint32 hitMask = damageInfo.GetHitMask(); + if (!hitMask) + hitMask = crit ? PROC_HIT_CRITICAL : PROC_HIT_NORMAL; + if (damage) procVictim |= PROC_FLAG_TAKEN_DAMAGE; if (caster->IsAlive()) - { - DamageInfo damageInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, BASE_ATTACK); caster->ProcSkillsAndAuras(target, procAttacker, procVictim, PROC_SPELL_TYPE_DAMAGE, PROC_SPELL_PHASE_NONE, hitMask, nullptr, &damageInfo, nullptr); - } int32 new_damage = caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false); if (caster->IsAlive()) diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index b36bc5ccddc..7ed906c3247 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -400,18 +400,21 @@ void Spell::EffectEnvironmentalDMG(SpellEffIndex /*effIndex*/) if (!unitTarget || !unitTarget->IsAlive()) return; - uint32 absorb = 0; - uint32 resist = 0; - - m_caster->CalcAbsorbResist(unitTarget, m_spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist, m_spellInfo); - SpellNonMeleeDamage log(m_caster, unitTarget, m_spellInfo->Id, m_SpellVisual, m_spellInfo->GetSchoolMask(), m_castId); - log.damage = damage - absorb - resist; - log.absorb = absorb; - log.resist = resist; + // CalcAbsorbResist already in Player::EnvironmentalDamage if (unitTarget->GetTypeId() == TYPEID_PLAYER) unitTarget->ToPlayer()->EnvironmentalDamage(DAMAGE_FIRE, damage); + else + { + DamageInfo damageInfo(m_caster, unitTarget, damage, m_spellInfo, m_spellInfo->GetSchoolMask(), SPELL_DIRECT_DAMAGE, BASE_ATTACK); + m_caster->CalcAbsorbResist(damageInfo); - m_caster->SendSpellNonMeleeDamageLog(&log); + SpellNonMeleeDamage log(m_caster, unitTarget, m_spellInfo->Id, m_SpellVisual, m_spellInfo->GetSchoolMask(), m_castId); + log.damage = damage; + log.absorb = damageInfo.GetAbsorb(); + log.resist = damageInfo.GetResist(); + + m_caster->SendSpellNonMeleeDamageLog(&log); + } } void Spell::EffectSchoolDMG(SpellEffIndex effIndex) diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index eff5e5049f7..6d44db6cd3b 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -2424,19 +2424,20 @@ public: // melee damage by specific school if (!spellStr) { - uint32 absorb = 0; - uint32 resist = 0; + Player* attacker = handler->GetSession()->GetPlayer(); + DamageInfo dmgInfo(attacker, target, damage, nullptr, schoolmask, SPELL_DIRECT_DAMAGE, BASE_ATTACK); + attacker->CalcAbsorbResist(dmgInfo); - handler->GetSession()->GetPlayer()->CalcAbsorbResist(target, schoolmask, SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); - - if (damage <= absorb + resist) + if (!dmgInfo.GetDamage()) return true; - damage -= absorb + resist; + damage = dmgInfo.GetDamage(); - handler->GetSession()->GetPlayer()->DealDamageMods(target, damage, &absorb); - handler->GetSession()->GetPlayer()->DealDamage(target, damage, NULL, DIRECT_DAMAGE, schoolmask, NULL, false); - handler->GetSession()->GetPlayer()->SendAttackStateUpdate(HITINFO_AFFECTS_VICTIM, target, 1, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0); + uint32 absorb = dmgInfo.GetAbsorb(); + uint32 resist = dmgInfo.GetResist(); + attacker->DealDamageMods(target, damage, &absorb); + attacker->DealDamage(target, damage, nullptr, DIRECT_DAMAGE, schoolmask, nullptr, false); + attacker->SendAttackStateUpdate(HITINFO_AFFECTS_VICTIM, target, 0, schoolmask, damage, absorb, resist, VICTIMSTATE_HIT, 0); return true; } |