mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-02-11 04:28:41 +01:00
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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user