feat(Core/Spells): add helper to get clean and unmitigated damage for pro… (#7244)

This commit is contained in:
UltraNix
2021-10-05 23:59:57 +02:00
committed by GitHub
parent 5af98783c9
commit 3223f90bcb
12 changed files with 283 additions and 169 deletions

View File

@@ -5933,7 +5933,8 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
if (caster)
{
int32 heal = caster->CountPctFromMaxHealth(10);
caster->HealBySpell(target, auraSpellInfo, heal);
HealInfo healInfo(caster, target, heal, auraSpellInfo, auraSpellInfo->GetSchoolMask());
caster->HealBySpell(healInfo);
if (int32 mana = caster->GetMaxPower(POWER_MANA))
{
@@ -6272,8 +6273,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);
// ignore non positive values (can be result apply spellmods to aura damage
@@ -6333,23 +6332,33 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
if ((crit = roll_chance_f(GetCritChance())))
damage = Unit::SpellCriticalDamageBonus(caster, m_spellInfo, damage, target);
int32 dmg = damage;
if (CanApplyResilience())
Unit::ApplyResilience(target, nullptr, &dmg, crit, CR_CRIT_TAKEN_SPELL);
damage = dmg;
Unit::CalcAbsorbResist(caster, target, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, GetSpellInfo());
LOG_DEBUG("spells.aura.effect", "PeriodicTick: %s attacked %s for %u dmg inflicted by %u abs is %u",
GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), damage, GetId(), absorb);
Unit::DealDamageMods(target, damage, &absorb);
// Auras reducing damage from AOE spells
if (GetSpellInfo()->Effects[GetEffIndex()].IsAreaAuraEffect() || GetSpellInfo()->Effects[GetEffIndex()].IsTargetingArea() || GetSpellInfo()->Effects[GetEffIndex()].Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA) // some persistent area auras have targets like A=53 B=28
{
damage = target->CalculateAOEDamageReduction(damage, GetSpellInfo()->SchoolMask, caster);
}
if (CanApplyResilience())
{
int32 resilienceReduction = damage;
Unit::ApplyResilience(target, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_SPELL);
resilienceReduction = damage - resilienceReduction;
damage -= resilienceReduction;
cleanDamage.mitigated_damage += resilienceReduction;
}
DamageInfo dmgInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, cleanDamage.mitigated_damage);
Unit::CalcAbsorbResist(dmgInfo);
uint32 absorb = dmgInfo.GetAbsorb();
uint32 resist = dmgInfo.GetResist();
damage = dmgInfo.GetDamage();
LOG_DEBUG("spells.aura.effect", "PeriodicTick: %s attacked %s for %u dmg inflicted by %u abs is %u",
GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), damage, GetId(), absorb);
Unit::DealDamageMods(target, damage, &absorb);
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC;
@@ -6357,7 +6366,6 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
if (absorb > 0)
procEx |= PROC_EX_ABSORB;
damage = (damage <= absorb + resist) ? 0 : (damage - absorb - resist);
if (damage)
procVictim |= PROC_FLAG_TAKEN_DAMAGE;
@@ -6370,7 +6378,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
// allow null caster to call this function
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex());
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo);
}
void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) const
@@ -6388,8 +6396,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);
uint32 damage = std::max(GetAmount(), 0);
@@ -6413,12 +6419,22 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
damage = damageReductedArmor;
}
int32 dmg = damage;
if (CanApplyResilience())
Unit::ApplyResilience(target, nullptr, &dmg, crit, CR_CRIT_TAKEN_SPELL);
damage = dmg;
{
int32 resilienceReduction = damage;
Unit::ApplyResilience(target, nullptr, &resilienceReduction, crit, CR_CRIT_TAKEN_SPELL);
Unit::CalcAbsorbResist(caster, target, GetSpellInfo()->GetSchoolMask(), DOT, damage, &absorb, &resist, m_spellInfo);
resilienceReduction = damage - resilienceReduction;
damage -= resilienceReduction;
cleanDamage.mitigated_damage += resilienceReduction;
}
DamageInfo dmgInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask(), DOT, cleanDamage.mitigated_damage);
Unit::CalcAbsorbResist(dmgInfo);
uint32 absorb = dmgInfo.GetAbsorb();
uint32 resist = dmgInfo.GetResist();
damage = dmgInfo.GetDamage();
// Set trigger flag
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
@@ -6427,23 +6443,26 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
if (absorb > 0)
procEx |= PROC_EX_ABSORB;
damage = (damage <= absorb + resist) ? 0 : (damage - absorb - resist);
if (damage)
if (dmgInfo.GetDamage())
procVictim |= PROC_FLAG_TAKEN_DAMAGE;
if (target->GetHealth() < damage)
damage = target->GetHealth();
if (target->GetHealth() < dmgInfo.GetDamage())
{
dmgInfo.ModifyDamage(dmgInfo.GetDamage() - target->GetHealth());
}
damage = dmgInfo.GetDamage();
LOG_DEBUG("spells.aura.effect", "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);
if (caster)
caster->SendSpellNonMeleeDamageLog(target, GetId(), damage + absorb + resist, GetSpellInfo()->GetSchoolMask(), absorb, resist, false, 0, crit);
caster->SendSpellNonMeleeDamageLog(target, GetSpellInfo(), damage, GetSpellInfo()->GetSchoolMask(), absorb, resist, false, 0, crit);
int32 new_damage;
new_damage = Unit::DealDamage(caster, target, damage, &cleanDamage, DOT, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), false);
// allow null caster to call this function
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex());
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, &dmgInfo);
if (!caster || !caster->IsAlive())
return;
@@ -6453,7 +6472,8 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
uint32 heal = uint32(caster->SpellHealingBonusDone(caster, GetSpellInfo(), uint32(new_damage * gainMultiplier), DOT, 0.0f, GetBase()->GetStackAmount()));
heal = uint32(caster->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT, GetBase()->GetStackAmount()));
int32 gain = caster->HealBySpell(caster, GetSpellInfo(), heal);
HealInfo healInfo(caster, caster, heal, GetSpellInfo(), GetSpellInfo()->GetSchoolMask());
int32 gain = caster->HealBySpell(healInfo);
caster->getHostileRefMgr().threatAssist(caster, gain * 0.5f, GetSpellInfo());
}
@@ -6482,7 +6502,8 @@ void AuraEffect::HandlePeriodicHealthFunnelAuraTick(Unit* target, Unit* caster)
damage = int32(damage * gainMultiplier);
caster->HealBySpell(target, GetSpellInfo(), damage);
HealInfo healInfo(caster, target, damage, GetSpellInfo(), GetSpellInfo()->GetSchoolMask());
caster->HealBySpell(healInfo);
}
void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
@@ -6579,16 +6600,17 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
LOG_DEBUG("spells.aura.effect", "PeriodicTick: %s heal of %s for %u health inflicted by %u",
GetCasterGUID().ToString().c_str(), target->GetGUID().ToString().c_str(), damage, GetId());
uint32 absorb = 0;
uint32 heal = uint32(damage);
// Script Hook For HandlePeriodicDamageAurasTick -- Allow scripts to change the Damage pre class mitigation calculations
sScriptMgr->ModifyPeriodicDamageAurasTick(target, caster, heal);
Unit::CalcHealAbsorb(target, GetSpellInfo(), heal, absorb);
int32 gain = Unit::DealHeal(caster, target, heal);
HealInfo healInfo(caster, target, heal, GetSpellInfo(), GetSpellInfo()->GetSchoolMask());
Unit::CalcHealAbsorb(healInfo);
int32 gain = Unit::DealHeal(caster, target, healInfo.GetHeal());
SpellPeriodicAuraLogInfo pInfo(this, heal, heal - gain, absorb, 0, 0.0f, crit);
SpellPeriodicAuraLogInfo pInfo(this, healInfo.GetHeal(), healInfo.GetHeal() - gain, healInfo.GetAbsorb(), 0, 0.0f, crit);
target->SendPeriodicAuraLog(&pInfo);
if (caster)
@@ -6610,20 +6632,20 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
uint32 absorb2 = 0;
Unit::DealDamageMods(caster, manaPerSecond, &absorb2);
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL);
Unit::DealDamage(caster, caster, manaPerSecond, &cleanDamage, SELF_DAMAGE, GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), true);
}
uint32 procAttacker = PROC_FLAG_DONE_PERIODIC;
uint32 procVictim = PROC_FLAG_TAKEN_PERIODIC;
uint32 procEx = (crit ? PROC_EX_CRITICAL_HIT : PROC_EX_NORMAL_HIT) | PROC_EX_INTERNAL_HOT;
if (absorb > 0)
if (healInfo.GetAbsorb() > 0)
procEx |= PROC_EX_ABSORB;
// ignore item heals
if (!haveCastItem && GetAuraType() != SPELL_AURA_OBS_MOD_HEALTH) // xinef: dont allow obs_mod_health to proc spells, this is passive regeneration and not hot
// xinef: allow null caster to proc
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, damage, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex());
caster->ProcDamageAndSpell(target, caster ? procAttacker : 0, procVictim, procEx, heal, BASE_ATTACK, GetSpellInfo(), nullptr, GetEffIndex(), nullptr, nullptr, &healInfo);
}
void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) const
@@ -6793,7 +6815,7 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
SpellInfo const* spellProto = GetSpellInfo();
// maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
SpellNonMeleeDamage damageInfo(caster, target, spellProto->Id, spellProto->SchoolMask);
SpellNonMeleeDamage damageInfo(caster, target, spellProto, spellProto->SchoolMask);
// no SpellDamageBonus for burn mana
caster->CalculateSpellDamageTaken(&damageInfo, int32(gain * dmgMultiplier), spellProto);
@@ -6809,7 +6831,9 @@ void AuraEffect::HandlePeriodicPowerBurnAuraTick(Unit* target, Unit* caster) con
procVictim |= PROC_FLAG_TAKEN_DAMAGE;
caster->DealSpellDamage(&damageInfo, true);
caster->ProcDamageAndSpell(damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto, nullptr, GetEffIndex());
DamageInfo dmgInfo(damageInfo, DOT);
caster->ProcDamageAndSpell(damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto, nullptr, GetEffIndex(), nullptr, &dmgInfo);
}
void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEventInfo& eventInfo)
@@ -6854,7 +6878,7 @@ void AuraEffect::HandleProcTriggerDamageAuraProc(AuraApplication* aurApp, ProcEv
{
Unit* target = aurApp->GetTarget();
Unit* triggerTarget = eventInfo.GetProcTarget();
SpellNonMeleeDamage damageInfo(target, triggerTarget, GetId(), GetSpellInfo()->SchoolMask);
SpellNonMeleeDamage damageInfo(target, triggerTarget, GetSpellInfo(), GetSpellInfo()->SchoolMask);
uint32 damage = target->SpellDamageBonusDone(triggerTarget, GetSpellInfo(), GetAmount(), SPELL_DIRECT_DAMAGE);
damage = triggerTarget->SpellDamageBonusTaken(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
target->CalculateSpellDamageTaken(&damageInfo, damage, GetSpellInfo());