Core/Unit: corrected calculation for SPELL_AURA_MOD_DAMAGE_TAKEN/SPELL_AURA_MOD_HEALING auras

- Spell bonus calculation and penalty was done twice, but it's simply flat +SP, which should be taken into account before other bonuses
- Fixed missing code from SpellDamageBonusDone/SpellHealingBonusDone and killed multiplication by stack amount twice for default coefficient spells (already multiplied on level penalty)
This commit is contained in:
ariel-
2022-05-09 15:51:50 +02:00
committed by Ovahlord
parent c81f48197d
commit 6024b7b4fb
2 changed files with 26 additions and 88 deletions

View File

@@ -6687,7 +6687,16 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
// Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask(), true);
// modify spell power by victim's SPELL_AURA_MOD_DAMAGE_TAKEN auras (eg Amplify/Dampen Magic)
DoneAdvertisedBenefit += victim->SpellBaseDamageBonusTaken(spellProto);
DoneAdvertisedBenefit += GetTotalAuraModifier(SPELL_AURA_MOD_DAMAGE_TAKEN, [spellProto](AuraEffect const* aurEff)
{
if (spellProto->HasAttribute(SPELL_ATTR10_IGNORE_POSITIVE_DAMAGE_TAKEN_MODS) && aurEff->GetAmount() > 0)
return false;
if ((aurEff->GetMiscValue() & spellProto->GetSchoolMask()) != 0)
return true;
return false;
});
// Custom scripted damage
switch (spellProto->SpellFamilyName)
@@ -7088,24 +7097,6 @@ int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask, bool withSpellP
return DoneAdvertisedBenefit;
}
int32 Unit::SpellBaseDamageBonusTaken(SpellInfo const* spellInfo) const
{
int32 TakenAdvertisedBenefit = 0;
TakenAdvertisedBenefit += GetTotalAuraModifier(SPELL_AURA_MOD_DAMAGE_TAKEN, [spellInfo](AuraEffect const* aurEff)
{
if (spellInfo->HasAttribute(SPELL_ATTR10_IGNORE_POSITIVE_DAMAGE_TAKEN_MODS) && aurEff->GetAmount() > 0)
return false;
if ((aurEff->GetMiscValue() & spellInfo->GetSchoolMask()) != 0)
return true;
return false;
});
return TakenAdvertisedBenefit;
}
float Unit::SpellCritChanceDone(SpellInfo const* spellInfo, SpellSchoolMask schoolMask, WeaponAttackType attackType /*= BASE_ATTACK*/, bool isPeriodic /*= false*/) const
{
//! Mobs can't crit with spells. (Except player controlled)
@@ -7447,24 +7438,35 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
// Done fixed damage bonus auras
int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask(), true);
// modify spell power by victim's SPELL_AURA_MOD_HEALING auras (eg Amplify/Dampen Magic)
DoneAdvertisedBenefit += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_HEALING, spellProto->GetSchoolMask());
// Pets just add their bonus damage to their spell damage
// note that their spell damage is just gain of their own auras
if (HasUnitTypeMask(UNIT_MASK_GUARDIAN))
DoneAdvertisedBenefit += static_cast<Guardian const*>(this)->GetBonusDamage();
// Check for table values
float coeff = spellProto->Effects[effIndex].BonusMultiplier;
if (SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id))
{
WeaponAttackType const attType = (spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK;
float APbonus = float(victim->GetTotalAuraModifier(attType == BASE_ATTACK ? SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS : SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS));
APbonus += GetTotalAttackPowerValue(attType);
if (damagetype == DOT)
{
coeff = bonus->dot_damage;
if (bonus->ap_dot_bonus > 0)
DoneTotal += int32(bonus->ap_dot_bonus * stack * GetTotalAttackPowerValue(
(spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK));
if (bonus->ap_dot_bonus > 0)
DoneTotal += int32(bonus->ap_dot_bonus * stack * APbonus);
}
else
{
coeff = bonus->direct_damage;
if (bonus->ap_bonus > 0)
DoneTotal += int32(bonus->ap_bonus * stack * GetTotalAttackPowerValue(
(spellProto->IsRangedWeaponSpell() && spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE) ? RANGED_ATTACK : BASE_ATTACK));
DoneTotal += int32(bonus->ap_bonus * stack * APbonus);
}
}
else
@@ -7621,12 +7623,6 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
if (AuraEffect const* Tenacity = GetAuraEffect(58549, 0))
AddPct(TakenTotalMod, Tenacity->GetAmount());
// Healing Done
int32 TakenTotal = 0;
// Taken fixed damage bonus auras
int32 TakenAdvertisedBenefit = SpellBaseHealingBonusTaken(spellProto->GetSchoolMask());
// Nourish cast
if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags[1] & 0x2000000)
{
@@ -7636,36 +7632,6 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
TakenTotalMod *= 1.2f;
}
// Check for table values
float coeff = 0;
if (SpellBonusEntry const* bonus = sSpellMgr->GetSpellBonusData(spellProto->Id))
coeff = (damagetype == DOT) ? bonus->dot_damage : bonus->direct_damage;
else
{
// No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default
if (spellProto->DmgClass == SPELL_DAMAGE_CLASS_NONE)
{
healamount = uint32(std::max((float(healamount) * TakenTotalMod), 0.0f));
return healamount;
}
}
// Default calculation
if (TakenAdvertisedBenefit)
{
if (coeff < 0)
coeff = CalculateDefaultCoefficient(spellProto, damagetype) * int32(stack) * 1.88f; // As wowwiki says: C = (Cast Time / 3.5) * 1.88 (for healing spells)
if (Player* modOwner = GetSpellModOwner())
{
coeff *= 100.0f;
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff);
coeff /= 100.0f;
}
TakenTotal += int32(TakenAdvertisedBenefit * coeff * stack);
}
if (caster)
{
TakenTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_RECEIVED, [caster, spellProto](AuraEffect const* aurEff) -> bool
@@ -7676,21 +7642,7 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
});
}
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
switch (spellProto->Effects[i].ApplyAuraName)
{
// Bonus healing does not apply to these spells
case SPELL_AURA_PERIODIC_LEECH:
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
TakenTotal = 0;
break;
}
if (spellProto->Effects[i].Effect == SPELL_EFFECT_HEALTH_LEECH)
TakenTotal = 0;
}
float heal = float(int32(healamount) + TakenTotal) * TakenTotalMod;
float heal = healamount * TakenTotalMod;
return uint32(std::max(heal, 0.0f));
}
@@ -7740,18 +7692,6 @@ int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask, bool withSpell
return advertisedBenefit;
}
int32 Unit::SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const
{
int32 advertisedBenefit = 0;
AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING);
for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
if (((*i)->GetMiscValue() & schoolMask) != 0)
advertisedBenefit += (*i)->GetAmount();
return advertisedBenefit;
}
bool Unit::IsImmunedToDamage(SpellSchoolMask schoolMask) const
{
if (schoolMask == SPELL_SCHOOL_MASK_NONE)

View File

@@ -1634,12 +1634,10 @@ class TC_GAME_API Unit : public WorldObject
Unit* GetMeleeHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo = nullptr);
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask, bool withSpellPowerPctMod = false) const;
int32 SpellBaseDamageBonusTaken(SpellInfo const* spellInfo) const;
uint32 SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, uint32 stack = 1) const;
float SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype) const;
uint32 SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype) const;
int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask, bool withSpellPowerPctMod = false) const;
int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const;
uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, uint32 stack = 1) const;
float SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const;
uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1) const;