Core/Scripts: Added damage and healing calculation hook to spell and aura scripts allowing to override base damage amount, flat value mod and percent value mod separately
This commit is contained in:
1 parent
5bc189372b
commit
9480f79c2a
10 files changed
+199
-61
No files matched your search
@@ -1214,7 +1214,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, CalcDamageInfo* damageInfo, Weapon
|
||||
uint32 damage = 0;
|
||||
damage += CalculateDamage(damageInfo->AttackType, false, true);
|
||||
// Add melee damage bonus
|
||||
damage = MeleeDamageBonusDone(damageInfo->Target, damage, damageInfo->AttackType, DIRECT_DAMAGE, nullptr, true, SpellSchoolMask(damageInfo->DamageSchoolMask));
|
||||
damage = MeleeDamageBonusDone(damageInfo->Target, damage, damageInfo->AttackType, DIRECT_DAMAGE, nullptr, MECHANIC_NONE, true, SpellSchoolMask(damageInfo->DamageSchoolMask));
|
||||
damage = damageInfo->Target->MeleeDamageBonusTaken(this, damage, damageInfo->AttackType, nullptr, SpellSchoolMask(damageInfo->DamageSchoolMask));
|
||||
|
||||
// Script Hook For CalculateMeleeDamage -- Allow scripts to change the Damage pre class mitigation calculations
|
||||
@@ -6180,22 +6180,35 @@ void Unit::EnergizeBySpell(Unit* victim, SpellInfo const* spellInfo, int32 damag
|
||||
SendEnergizeSpellLog(victim, spellInfo->Id, damage, powerType);
|
||||
}
|
||||
|
||||
uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, uint32 stack) const
|
||||
int32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, int32 pdamage, DamageEffectType damagetype, uint8 effIndex, uint32 stack /*= 1*/, Spell* spell /*= nullptr*/, AuraEffect const* aurEff /*= nullptr*/) const
|
||||
{
|
||||
if (!spellProto || !victim || damagetype == DIRECT_DAMAGE)
|
||||
if (!spellProto || !victim)
|
||||
return pdamage;
|
||||
|
||||
int32 DoneTotal = 0;
|
||||
float DoneTotalMod = 1.0f;
|
||||
|
||||
auto callDamageScript = [&](int32& dmg, int32& flatMod, float& pctMod)
|
||||
{
|
||||
if (spell)
|
||||
spell->CallScriptCalcDamageHandlers(victim, dmg, flatMod, pctMod);
|
||||
else if (aurEff)
|
||||
aurEff->GetBase()->CallScriptCalcDamageAndHealingHandlers(aurEff, aurEff->GetBase()->GetApplicationOfTarget(victim->GetGUID()), victim, dmg, flatMod, pctMod);
|
||||
};
|
||||
|
||||
// Some spells don't benefit from done mods
|
||||
if (spellProto->HasAttribute(SPELL_ATTR3_IGNORE_CASTER_MODIFIERS))
|
||||
return pdamage;
|
||||
if (damagetype == DIRECT_DAMAGE || spellProto->HasAttribute(SPELL_ATTR3_IGNORE_CASTER_MODIFIERS))
|
||||
{
|
||||
callDamageScript(pdamage, DoneTotal, DoneTotalMod);
|
||||
return int32(std::max(float(pdamage + DoneTotal) * DoneTotalMod, 0.0f));
|
||||
}
|
||||
|
||||
// Totems get their bonus damage from their owner
|
||||
if (IsCreature() && IsTotem())
|
||||
if (Unit* creator = ObjectAccessor::GetUnit(*this, GetCreatorGUID()))
|
||||
return creator->SpellDamageBonusDone(victim, spellProto, pdamage, damagetype, effIndex, stack);
|
||||
return creator->SpellDamageBonusDone(victim, spellProto, pdamage, damagetype, effIndex, stack, spell, aurEff);
|
||||
|
||||
int32 DoneTotal = 0;
|
||||
float DoneTotalMod = SpellDamagePctDone(victim, spellProto, damagetype);
|
||||
DoneTotalMod = SpellDamagePctDone(victim, spellProto, damagetype);
|
||||
|
||||
// done scripted mod (take it from owner)
|
||||
Unit const* owner = GetOwner() ? GetOwner() : this;
|
||||
@@ -6328,13 +6341,14 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin
|
||||
DoneTotal += int32(DoneAdvertisedBenefit * spellPowerCoeff * stack);
|
||||
}
|
||||
|
||||
float tmpDamage = float(int32(pdamage) + DoneTotal) * DoneTotalMod;
|
||||
callDamageScript(pdamage, DoneTotal, DoneTotalMod);
|
||||
float tmpDamage = float(pdamage + DoneTotal) * DoneTotalMod;
|
||||
|
||||
// apply spellmod to Done damage (flat and pct)
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SpellModOp::PeriodicHealingAndDamage : SpellModOp::HealingAndDamage, tmpDamage);
|
||||
|
||||
return uint32(std::max(tmpDamage, 0.0f));
|
||||
return int32(std::max(tmpDamage, 0.0f));
|
||||
}
|
||||
|
||||
float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype) const
|
||||
@@ -6518,7 +6532,7 @@ float Unit::SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, Damage
|
||||
return DoneTotalMod;
|
||||
}
|
||||
|
||||
uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype) const
|
||||
int32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, int32 pdamage, DamageEffectType damagetype) const
|
||||
{
|
||||
if (!spellProto || damagetype == DIRECT_DAMAGE)
|
||||
return pdamage;
|
||||
@@ -6601,7 +6615,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
|
||||
}
|
||||
|
||||
float tmpDamage = pdamage * TakenTotalMod;
|
||||
return uint32(std::max(tmpDamage, 0.0f));
|
||||
return int32(std::max(tmpDamage, 0.0f));
|
||||
}
|
||||
|
||||
int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask, bool withSpellPowerPctMod /*= false*/) const
|
||||
@@ -6949,12 +6963,12 @@ float Unit::SpellCritChanceTaken(Unit const* caster, SpellInfo const* spellInfo,
|
||||
return damage;
|
||||
}
|
||||
|
||||
uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, uint32 stack) const
|
||||
int32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, int32 healamount, DamageEffectType damagetype, uint8 effIndex, uint32 stack /*= 1*/, Spell* spell /*= nullptr*/, AuraEffect const* aurEff /*= nullptr*/) const
|
||||
{
|
||||
// For totems get healing bonus from owner (statue isn't totem in fact)
|
||||
if (GetTypeId() == TYPEID_UNIT && IsTotem())
|
||||
if (Unit* creator = ObjectAccessor::GetUnit(*this, GetCreatorGUID()))
|
||||
return creator->SpellHealingBonusDone(victim, spellProto, healamount, damagetype, effIndex, stack);
|
||||
return creator->SpellHealingBonusDone(victim, spellProto, healamount, damagetype, effIndex, stack, spell, aurEff);
|
||||
|
||||
// Some spells don't benefit from done mods
|
||||
if (spellProto->HasAttribute(SPELL_ATTR3_IGNORE_CASTER_MODIFIERS))
|
||||
@@ -7055,13 +7069,19 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui
|
||||
DoneTotal = 0;
|
||||
}
|
||||
|
||||
float heal = float(int32(healamount) + DoneTotal) * DoneTotalMod;
|
||||
if (spell)
|
||||
spell->CallScriptCalcHealingHandlers(victim, healamount, DoneTotal, DoneTotalMod);
|
||||
else if (aurEff)
|
||||
aurEff->GetBase()->CallScriptCalcDamageAndHealingHandlers(aurEff, aurEff->GetBase()->GetApplicationOfTarget(victim->GetGUID()), victim, healamount, DoneTotal, DoneTotalMod);
|
||||
|
||||
float heal = float(healamount + DoneTotal) * DoneTotalMod;
|
||||
|
||||
|
||||
// apply spellmod to Done amount
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SpellModOp::PeriodicHealingAndDamage : SpellModOp::HealingAndDamage, heal);
|
||||
|
||||
return uint32(std::max(heal, 0.0f));
|
||||
return int32(std::max(heal, 0.0f));
|
||||
}
|
||||
|
||||
float Unit::SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const
|
||||
@@ -7143,7 +7163,7 @@ float Unit::SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const
|
||||
return DoneTotalMod;
|
||||
}
|
||||
|
||||
uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype) const
|
||||
int32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, int32 healamount, DamageEffectType damagetype) const
|
||||
{
|
||||
float TakenTotalMod = 1.0f;
|
||||
|
||||
@@ -7190,7 +7210,7 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u
|
||||
|
||||
float heal = healamount * TakenTotalMod;
|
||||
|
||||
return uint32(std::max(heal, 0.0f));
|
||||
return int32(std::max(heal, 0.0f));
|
||||
}
|
||||
|
||||
int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask, bool withSpellPowerPctMod /*= false*/) const
|
||||
@@ -7474,7 +7494,7 @@ bool Unit::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Worl
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto /*= nullptr*/, bool useSpellBonusData /*= true*/, SpellSchoolMask damageSchoolMask /*= SPELL_SCHOOL_MASK_NORMAL*/)
|
||||
int32 Unit::MeleeDamageBonusDone(Unit* victim, int32 damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo const* spellProto /*= nullptr*/, Mechanics mechanic /*= MECHANIC_NONE*/, bool useSpellBonusData /*= true*/, SpellSchoolMask damageSchoolMask /*= SPELL_SCHOOL_MASK_NORMAL*/, Spell* spell /*= nullptr*/, AuraEffect const* aurEff /*= nullptr*/)
|
||||
{
|
||||
if (!victim || damage == 0)
|
||||
return 0;
|
||||
@@ -7562,7 +7582,10 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 damage, WeaponAttackType
|
||||
});
|
||||
|
||||
// Add SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC percent bonus
|
||||
if (spellProto)
|
||||
// Add SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC percent bonus
|
||||
if (mechanic != MECHANIC_NONE)
|
||||
AddPct(DoneTotalMod, GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC, mechanic));
|
||||
else if (spellProto && spellProto->Mechanic)
|
||||
AddPct(DoneTotalMod, GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC, spellProto->Mechanic));
|
||||
|
||||
if (!spellProto)
|
||||
@@ -7578,20 +7601,23 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 damage, WeaponAttackType
|
||||
}));
|
||||
}
|
||||
|
||||
float damageF = damage;
|
||||
if (spell)
|
||||
spell->CallScriptCalcDamageHandlers(victim, damage, DoneFlatBenefit, DoneTotalMod);
|
||||
else if (aurEff)
|
||||
aurEff->GetBase()->CallScriptCalcDamageAndHealingHandlers(aurEff, aurEff->GetBase()->GetApplicationOfTarget(victim->GetGUID()), victim, damage, DoneFlatBenefit, DoneTotalMod);
|
||||
|
||||
float damageF = float(damage + DoneFlatBenefit) * DoneTotalMod;
|
||||
|
||||
// apply spellmod to Done damage
|
||||
if (spellProto)
|
||||
if (Player* modOwner = GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(spellProto->Id, damagetype == DOT ? SpellModOp::PeriodicHealingAndDamage : SpellModOp::HealingAndDamage, damageF);
|
||||
|
||||
damageF = (damageF + DoneFlatBenefit) * DoneTotalMod;
|
||||
|
||||
// bonus result can be negative
|
||||
return uint32(std::max(damageF, 0.0f));
|
||||
return int32(std::max(damageF, 0.0f));
|
||||
}
|
||||
|
||||
uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto /*= nullptr*/, SpellSchoolMask damageSchoolMask /*= SPELL_SCHOOL_MASK_NORMAL*/)
|
||||
int32 Unit::MeleeDamageBonusTaken(Unit* attacker, int32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto /*= nullptr*/, SpellSchoolMask damageSchoolMask /*= SPELL_SCHOOL_MASK_NORMAL*/)
|
||||
{
|
||||
if (pdamage == 0)
|
||||
return 0;
|
||||
@@ -7624,7 +7650,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
|
||||
return true;
|
||||
});
|
||||
|
||||
if ((TakenFlatBenefit < 0) && (pdamage < static_cast<uint32>(-TakenFlatBenefit)))
|
||||
if ((TakenFlatBenefit < 0) && (pdamage < -TakenFlatBenefit))
|
||||
return 0;
|
||||
|
||||
// Taken total percent damage auras
|
||||
@@ -7729,7 +7755,7 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
|
||||
}
|
||||
|
||||
float tmpDamage = float(pdamage + TakenFlatBenefit) * TakenTotalMod;
|
||||
return uint32(std::max(tmpDamage, 0.0f));
|
||||
return int32(std::max(tmpDamage, 0.0f));
|
||||
}
|
||||
|
||||
void Unit::ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply)
|
||||
|
||||
Reference in new issue
Block a user