Core/Spells: fixed application order for spell mods when calculating damage and heal values

This commit is contained in:
Ovahlord
2019-05-11 01:42:12 +02:00
parent 6aa51873a3
commit b001670d78
2 changed files with 31 additions and 49 deletions

View File

@@ -6618,6 +6618,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
float ApCoeffMod = 1.0f;
int32 DoneTotal = 0;
float DoneTotalMod = SpellDamagePctDone(victim, spellProto, damagetype);
// done scripted mod (take it from owner)
Unit const* owner = GetOwner() ? GetOwner() : this;
@@ -6645,7 +6646,9 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
}
// Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask());
int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask());
// modify spell power by victim's SPELL_AURA_MOD_DAMAGE_TAKEN auras (eg Amplify/Dampen Magic)
DoneAdvertisedBenefit += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_TAKEN, spellProto->GetSchoolMask());
// Check for table values
float coeff = spellProto->Effects[effIndex].BonusMultiplier;
@@ -6672,7 +6675,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
{
// No bonus damage for SPELL_DAMAGE_CLASS_NONE class spells by default
if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
return pdamage;
return uint32(std::max(pdamage * DoneTotalMod, 0.0f));
}
// Default calculation
@@ -6690,18 +6693,11 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
DoneTotal += int32(DoneAdvertisedBenefit * coeff * stack);
}
float tmpDamage = (int32(pdamage) + DoneTotal);
float tmpDamage = float(int32(pdamage) + DoneTotal) * DoneTotalMod;
// DOTs calculated in AuraEffect::PeriodicDamageAurasTick
// Done Percentage for DOT is already calculated, no need to do it again. The percentage mod is applied in Aura::HandleAuraSpecificMods.
if (damagetype != DOT)
{
tmpDamage *= SpellDamagePctDone(victim, spellProto, damagetype);
// apply spellmod to Done damage (flat and pct)
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage);
}
// apply spellmod to Done damage (flat and pct)
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, tmpDamage);
return uint32(std::max(tmpDamage, 0.0f));
}
@@ -7396,6 +7392,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
return healamount;
int32 DoneTotal = 0;
float DoneTotalMod = SpellHealingPctDone(victim, spellProto);
// done scripted mod (take it from owner)
Unit const* owner = GetOwner() ? GetOwner() : this;
@@ -7443,6 +7440,8 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
// Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask());
// modify spell power by victim's SPELL_AURA_MOD_HEALING auras (eg Amplify/Dampen Magic)
DoneAdvertisedBenefit += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_HEALING, spellProto->GetSchoolMask());
// Check for table values
float coeff = spellProto->Effects[effIndex].BonusMultiplier;
@@ -7467,7 +7466,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
{
// No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default
if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
return healamount;
return uint32(std::max(healamount * DoneTotalMod, 0.0f));
}
// Default calculation
@@ -7500,18 +7499,11 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
DoneTotal = 0;
}
float heal = float(int32(healamount) + DoneTotal);
float heal = float(int32(healamount) + DoneTotal) * DoneTotalMod;
// DOTs calculated in AuraEffect::HandlePeriodicHealAurasTick
// Done Percentage for DOT is already calculated, no need to do it again. The percentage mod is applied in Aura::HandleAuraSpecificMods.
if (damagetype != DOT)
{
heal *= SpellHealingPctDone(victim, spellProto);
// apply spellmod to Done amount
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, heal);
}
// apply spellmod to Done amount
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SPELLMOD_DOT : SPELLMOD_DAMAGE, heal);
return uint32(std::max(heal, 0.0f));
}

View File

@@ -5624,17 +5624,6 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
else
damage = std::max(int32(damage * GetDonePct()), 0);
if (Player* modOwner = caster->GetSpellModOwner())
modOwner->ApplySpellMod(GetSpellInfo()->Id, SPELLMOD_DOT, damage);
// Calculate armor mitigation
if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
{
uint32 damageReductedArmor = caster->CalcArmorReducedDamage(target, damage, GetSpellInfo());
cleanDamage.mitigated_damage += damage - damageReductedArmor;
damage = damageReductedArmor;
}
switch (GetSpellInfo()->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
@@ -5678,6 +5667,20 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT);
bool crit = false;
crit = roll_chance_f(isAreaAura ? caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()) : GetCritChance());
if (crit)
damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
// Calculate armor mitigation
if (Unit::IsDamageReducedByArmor(GetSpellInfo()->GetSchoolMask(), GetSpellInfo(), GetEffIndex()))
{
uint32 damageReductedArmor = caster->CalcArmorReducedDamage(target, damage, GetSpellInfo());
cleanDamage.mitigated_damage += damage - damageReductedArmor;
damage = damageReductedArmor;
}
if (!m_spellInfo->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
{
if (m_spellInfo->Effects[m_effIndex].IsTargetingArea() || isAreaAura)
@@ -5688,13 +5691,6 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const
}
}
bool crit = false;
crit = roll_chance_f(isAreaAura ? caster->GetUnitSpellCriticalChance(target, m_spellInfo, m_spellInfo->GetSchoolMask()) : GetCritChance());
if (crit)
damage = caster->SpellCriticalDamageBonus(m_spellInfo, damage, target);
int32 dmg = damage;
if (!GetSpellInfo()->HasAttribute(SPELL_ATTR4_FIXED_DAMAGE))
caster->ApplyResilience(target, &dmg);
@@ -5762,9 +5758,6 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c
else
damage = std::max(int32(damage * GetDonePct()), 0);
if (Player* modOwner = caster->GetSpellModOwner())
modOwner->ApplySpellMod(GetSpellInfo()->Id, SPELLMOD_DOT, damage);
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
// Calculate armor mitigation
@@ -5936,9 +5929,6 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const
else
damage = std::max(int32(damage * GetDonePct()), 0);
if (Player* modOwner = caster->GetSpellModOwner())
modOwner->ApplySpellMod(GetSpellInfo()->Id, SPELLMOD_DOT, damage);
damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount());
}