aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorariel- <ariel-@users.noreply.github.com>2016-10-26 02:16:11 -0300
committerariel- <ariel-@users.noreply.github.com>2016-10-26 02:16:11 -0300
commitd3a71a83387f757f87c7d27e1054498c8cc49c8f (patch)
treed6a0c72afb84d97eaef8d7155d3aca39017f5076 /src
parentacc6688d36a567015a48efbfd5f0a8f13e0dbc70 (diff)
Core/Spells: use DamageInfo struct to calc spell absorbs and resists, and use calculated proc hitMask on aura ticks
Closes #18135
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Player/Player.cpp21
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp150
-rw-r--r--src/server/game/Entities/Unit/Unit.h6
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp38
-rw-r--r--src/server/game/Spells/SpellEffects.cpp16
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp19
6 files changed, 128 insertions, 122 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 59b109ab754..ba85f57b7a2 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -939,12 +939,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 ca470012c41..637ade0ab90 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -646,7 +646,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()))
{
@@ -1155,7 +1155,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
ApplyResilience(victim, nullptr, &damage, crit, CR_CRIT_TAKEN_RANGED);
break;
}
- // Magical Attacks
+ // Magical Attacks
case SPELL_DAMAGE_CLASS_NONE:
case SPELL_DAMAGE_CLASS_MAGIC:
{
@@ -1178,15 +1178,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* damageInfo, bool durabilityLoss)
@@ -1396,15 +1394,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;
@@ -1731,57 +1731,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->IsAffectedOnSpell(damageInfo.GetSpellInfo()))
continue;
- if (((*itr)->GetAmount() > auraAbsorbMod) && (*itr)->IsAffectedOnSpell(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
@@ -1794,19 +1786,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)
@@ -1820,16 +1812,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
@@ -1842,14 +1834,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;
@@ -1857,15 +1849,15 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
if (float manaMultiplier = absorbAurEff->GetSpellInfo()->Effects[absorbAurEff->GetEffIndex()].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)
@@ -1876,39 +1868,39 @@ 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 vSplitDamageFlatCopy(victim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_FLAT));
- for (AuraEffectList::iterator itr = vSplitDamageFlatCopy.begin(); (itr != vSplitDamageFlatCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr)
+ AuraEffectList vSplitDamageFlatCopy(damageInfo.GetVictim()->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_FLAT));
+ for (AuraEffectList::iterator itr = vSplitDamageFlatCopy.begin(); (itr != vSplitDamageFlatCopy.end()) && (damageInfo.GetDamage() > 0); ++itr)
{
// Check if aura was removed during iteration - we don't need to work on such auras
- if (!((*itr)->GetBase()->IsAppliedOnTarget(victim->GetGUID())))
+ if (!((*itr)->GetBase()->IsAppliedOnTarget(damageInfo.GetVictim()->GetGUID())))
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;
int32 splitDamage = (*itr)->GetAmount();
// absorb must be smaller than the damage itself
- splitDamage = RoundToInterval(splitDamage, 0, int32(dmgInfo.GetDamage()));
+ splitDamage = RoundToInterval(splitDamage, 0, int32(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;
}
@@ -1916,66 +1908,62 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe
uint32 splitted_absorb = 0;
DealDamageMods(caster, splitted, &splitted_absorb);
- SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitted, schoolMask, splitted_absorb, 0, false, 0, false);
+ SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitted, damageInfo.GetSchoolMask(), splitted_absorb, 0, false, 0, false);
CleanDamage cleanDamage = CleanDamage(splitted, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
- DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*itr)->GetSpellInfo(), false);
+ DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, damageInfo.GetSchoolMask(), (*itr)->GetSpellInfo(), false);
}
// 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);
- SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitDamage, schoolMask, split_absorb, 0, false, 0, false);
+ SendSpellNonMeleeDamageLog(caster, (*itr)->GetSpellInfo()->Id, splitDamage, damageInfo.GetSchoolMask(), split_absorb, 0, false, 0, false);
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);
// 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 20cdc75c001..95e447bfb5e 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1433,7 +1433,7 @@ class TC_GAME_API Unit : public WorldObject
void Dismount();
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); }
@@ -2033,8 +2033,8 @@ class TC_GAME_API Unit : public WorldObject
static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = NULL, uint8 effIndex = MAX_SPELL_EFFECTS);
uint32 CalcArmorReducedDamage(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 fabdbe44334..08061ac0b34 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -5846,8 +5846,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.
@@ -5942,13 +5940,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, NULL, &dmg, crit, CR_CRIT_TAKEN_SPELL);
+ caster->ApplyResilience(target, nullptr, &dmg, crit, CR_CRIT_TAKEN_SPELL);
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);
@@ -5957,8 +5958,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;
@@ -5969,7 +5972,6 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
SpellPeriodicAuraLogInfo pInfo(this, damage, overkill, absorb, resist, 0.0f, crit);
target->SendPeriodicAuraLog(&pInfo);
- 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);
@@ -5990,8 +5992,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 = m_spellInfo->Effects[m_effIndex].IsAreaAuraEffect() || m_spellInfo->Effects[m_effIndex].IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA);
@@ -6034,29 +6034,33 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
int32 dmg = damage;
if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
- caster->ApplyResilience(target, NULL, &dmg, crit, CR_CRIT_TAKEN_SPELL);
+ caster->ApplyResilience(target, nullptr, &dmg, crit, CR_CRIT_TAKEN_SPELL);
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
caster->SendSpellNonMeleeDamageLog(target, GetId(), damage, GetSpellInfo()->GetSchoolMask(), absorb, resist, false, 0, crit);
+ damage = damageInfo.GetDamage();
// 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 f321925aa8c..8f25b3f7a5a 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -292,14 +292,18 @@ 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);
-
- m_caster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_spellInfo->GetSchoolMask(), absorb, resist, false, 0, false);
+ // 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);
+
+ uint32 absorb = damageInfo.GetAbsorb();
+ uint32 resist = damageInfo.GetResist();
+ m_caster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo->Id, damage, m_spellInfo->GetSchoolMask(), absorb, resist, false, 0, false);
+ }
}
void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 16217fbaea6..1e4daaea2d2 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -2268,19 +2268,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;
}