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

Port From (https://github.com/TrinityCore/TrinityCore/commit/9cdf3530f41e18fc815e7b164e40c01a18c3d757)
This commit is contained in:
hondacrx
2023-09-13 18:18:29 -04:00
parent 44e79ec8ea
commit d7c2fa52f4
10 changed files with 248 additions and 107 deletions
+15 -2
View File
@@ -577,7 +577,7 @@ namespace Game.Spells
}
}
}
}
if (!addUnit)
@@ -994,7 +994,7 @@ namespace Game.Spells
&& !m_spellInfo.HasAttribute(SpellAttr2.AllowWhileNotShapeshiftedCasterForm)
&& !m_spellInfo.HasAttribute(SpellAttr0.NotShapeshifted);
}
public bool CanBeSaved()
{
if (IsPassive())
@@ -2115,6 +2115,19 @@ namespace Game.Spells
loadedScript._FinishScriptCall();
}
}
public void CallScriptCalcDamageAndHealingHandlers(AuraEffect aurEff, AuraApplication aurApp, Unit victim, ref int damageOrHealing, ref int flatMod, ref float pctMod)
{
foreach (AuraScript script in m_loadedScripts)
{
script._PrepareScriptCall(AuraScriptHookType.EffectCalcDamageAndHealing, aurApp);
foreach (var effectCalcDamageAndHealing in script.DoEffectCalcDamageAndHealing)
if (effectCalcDamageAndHealing.IsEffectAffected(m_spellInfo, aurEff.GetEffIndex()))
effectCalcDamageAndHealing.Call(aurEff, victim, ref damageOrHealing, ref flatMod, ref pctMod);
script._FinishScriptCall();
}
}
public void CallScriptEffectAbsorbHandlers(AuraEffect aurEff, AuraApplication aurApp, DamageInfo dmgInfo, ref uint absorbAmount, ref bool defaultPrevented)
{
+19 -25
View File
@@ -124,7 +124,7 @@ namespace Game.Spells
return amount;
}
public static float? CalculateEstimatedAmount(Unit caster, Unit target, SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, int amount, byte stack)
public static float? CalculateEstimatedAmount(Unit caster, Unit target, SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, int amount, byte stack, AuraEffect aurEff)
{
uint stackAmountForBonuses = !spellEffectInfo.EffectAttributes.HasFlag(SpellEffectAttributes.NoScaleWithStack) ? stack : 1u;
@@ -132,9 +132,9 @@ namespace Game.Spells
{
case AuraType.PeriodicDamage:
case AuraType.PeriodicLeech:
return caster.SpellDamageBonusDone(target, spellInfo, (uint)amount, DamageEffectType.DOT, spellEffectInfo, stackAmountForBonuses);
return caster.SpellDamageBonusDone(target, spellInfo, amount, DamageEffectType.DOT, spellEffectInfo, stackAmountForBonuses, null, aurEff);
case AuraType.PeriodicHeal:
return caster.SpellHealingBonusDone(target, spellInfo, (uint)amount, DamageEffectType.DOT, spellEffectInfo, stackAmountForBonuses);
return caster.SpellHealingBonusDone(target, spellInfo, amount, DamageEffectType.DOT, spellEffectInfo, stackAmountForBonuses, null, aurEff);
default:
break;
}
@@ -147,7 +147,7 @@ namespace Game.Spells
if (!caster || GetBase().GetAuraType() != AuraObjectType.Unit)
return null;
return CalculateEstimatedAmount(caster, GetBase().GetUnitOwner(), GetSpellInfo(), GetSpellEffectInfo(), amount, GetBase().GetStackAmount());
return CalculateEstimatedAmount(caster, GetBase().GetUnitOwner(), GetSpellInfo(), GetSpellEffectInfo(), amount, GetBase().GetStackAmount(), this);
}
public static float CalculateEstimatedfTotalPeriodicAmount(Unit caster, Unit target, SpellInfo spellInfo, SpellEffectInfo spellEffectInfo, float amount, byte stack)
@@ -177,7 +177,7 @@ namespace Game.Spells
if (spellInfo.HasAttribute(SpellAttr5.ExtraInitialPeriod))
totalTicks += 1.0f;
return totalTicks * CalculateEstimatedAmount(caster, target, spellInfo, spellEffectInfo, (int)amount, stack).GetValueOrDefault(amount);
return totalTicks * CalculateEstimatedAmount(caster, target, spellInfo, spellEffectInfo, (int)amount, stack, null).GetValueOrDefault(amount);
}
public uint GetTotalTicks()
@@ -5070,17 +5070,11 @@ namespace Game.Spells
case AuraType.PeriodicDamage:
{
if (caster != null)
damage = caster.SpellDamageBonusDone(target, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
damage = (uint)caster.SpellDamageBonusDone(target, GetSpellInfo(), (int)damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses, null, this);
damage = target.SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT);
damage = (uint)target.SpellDamageBonusTaken(caster, GetSpellInfo(), (int)damage, DamageEffectType.DOT);
// There is a Chance to make a Soul Shard when Drain soul does damage
if (caster != null && GetSpellInfo().SpellFamilyName == SpellFamilyNames.Warlock && GetSpellInfo().SpellFamilyFlags[0].HasAnyFlag(0x00004000u))
{
if (caster.IsTypeId(TypeId.Player) && caster.ToPlayer().IsHonorOrXPTarget(target))
caster.CastSpell(caster, 95810, new CastSpellExtraArgs(this));
}
else if (GetSpellInfo().SpellFamilyName == SpellFamilyNames.Generic)
if (GetSpellInfo().SpellFamilyName == SpellFamilyNames.Generic)
{
switch (GetId())
{
@@ -5104,15 +5098,15 @@ namespace Game.Spells
// Add melee damage bonuses (also check for negative)
if (caster != null)
damage = caster.MeleeDamageBonusDone(target, damage, attackType, DamageEffectType.DOT, GetSpellInfo());
damage = (uint)caster.MeleeDamageBonusDone(target, (int)damage, attackType, DamageEffectType.DOT, GetSpellInfo(), GetSpellEffectInfo().Mechanic, GetSpellInfo().GetSchoolMask(), null, this);
damage = target.MeleeDamageBonusTaken(caster, damage, attackType, DamageEffectType.DOT, GetSpellInfo());
damage = (uint)target.MeleeDamageBonusTaken(caster, (int)damage, attackType, DamageEffectType.DOT, GetSpellInfo());
break;
}
case AuraType.PeriodicDamagePercent:
// ceil obtained value, it may happen that 10 ticks for 10% damage may not kill owner
damage = (uint)Math.Ceiling(MathFunctions.CalculatePct((float)target.GetMaxHealth(), (float)damage));
damage = target.SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT);
damage = (uint)target.SpellDamageBonusTaken(caster, GetSpellInfo(), (int)damage, DamageEffectType.DOT);
break;
default:
break;
@@ -5196,9 +5190,9 @@ namespace Game.Spells
uint damage = (uint)Math.Max(GetAmount(), 0);
if (caster)
damage = caster.SpellDamageBonusDone(target, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
damage = (uint)caster.SpellDamageBonusDone(target, GetSpellInfo(), (int)damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses, null, this);
damage = target.SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT);
damage = (uint)target.SpellDamageBonusTaken(caster, GetSpellInfo(), (int)damage, DamageEffectType.DOT);
bool crit = RandomHelper.randChance(GetCritChanceFor(caster, target));
if (crit)
@@ -5260,8 +5254,8 @@ namespace Game.Spells
float gainMultiplier = GetSpellEffectInfo().CalcValueMultiplier(caster);
uint heal = caster.SpellHealingBonusDone(caster, GetSpellInfo(), (uint)(new_damage * gainMultiplier), DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
heal = caster.SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DamageEffectType.DOT);
uint heal = (uint)caster.SpellHealingBonusDone(caster, GetSpellInfo(), (int)(new_damage * gainMultiplier), DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses, null, this);
heal = (uint)caster.SpellHealingBonusTaken(caster, GetSpellInfo(), (int)heal, DamageEffectType.DOT);
HealInfo healInfo = new(caster, caster, heal, GetSpellInfo(), GetSpellInfo().GetSchoolMask());
caster.HealBySpell(healInfo);
@@ -5325,9 +5319,9 @@ namespace Game.Spells
if (GetAuraType() == AuraType.ObsModHealth)
damage = (uint)target.CountPctFromMaxHealth((int)damage);
else if (caster != null)
damage = caster.SpellHealingBonusDone(target, GetSpellInfo(), damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses);
damage = (uint)caster.SpellHealingBonusDone(target, GetSpellInfo(), (int)damage, DamageEffectType.DOT, GetSpellEffectInfo(), stackAmountForBonuses, null, this);
damage = target.SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DamageEffectType.DOT);
damage = (uint)target.SpellHealingBonusTaken(caster, GetSpellInfo(), (int)damage, DamageEffectType.DOT);
bool crit = RandomHelper.randChance(GetCritChanceFor(caster, target));
if (crit)
@@ -5615,8 +5609,8 @@ namespace Game.Spells
}
SpellNonMeleeDamage damageInfo = new(target, triggerTarget, GetSpellInfo(), GetBase().GetSpellVisual(), GetSpellInfo().SchoolMask, GetBase().GetCastId());
int damage = (int)target.SpellDamageBonusDone(triggerTarget, GetSpellInfo(), (uint)GetAmount(), DamageEffectType.SpellDirect, GetSpellEffectInfo());
damage = (int)triggerTarget.SpellDamageBonusTaken(target, GetSpellInfo(), (uint)damage, DamageEffectType.SpellDirect);
int damage = target.SpellDamageBonusDone(triggerTarget, GetSpellInfo(), GetAmount(), DamageEffectType.SpellDirect, GetSpellEffectInfo(), 1, null, this);
damage = triggerTarget.SpellDamageBonusTaken(target, GetSpellInfo(), damage, DamageEffectType.SpellDirect);
target.CalculateSpellDamageTaken(damageInfo, damage, GetSpellInfo());
Unit.DealDamageMods(damageInfo.attacker, damageInfo.target, ref damageInfo.damage, ref damageInfo.absorb);
target.DealSpellDamage(damageInfo, true);
+24
View File
@@ -7623,6 +7623,30 @@ namespace Game.Spells
}
}
public void CallScriptCalcDamageHandlers(Unit victim, ref int damage, ref int flatMod, ref float pctMod)
{
foreach (SpellScript script in m_loadedScripts)
{
script._PrepareScriptCall(SpellScriptHookType.CalcDamage);
foreach (var calcDamage in script.CalcDamage)
calcDamage.Call(victim, ref damage, ref flatMod, ref pctMod);
script._FinishScriptCall();
}
}
public void CallScriptCalcHealingHandlers(Unit victim, ref int healing, ref int flatMod, ref float pctMod)
{
foreach (SpellScript script in m_loadedScripts)
{
script._PrepareScriptCall(SpellScriptHookType.CalcHealing);
foreach (var calcHealing in script.CalcHealing)
calcHealing.Call(victim, ref healing, ref flatMod, ref pctMod);
script._FinishScriptCall();
}
}
void CallScriptObjectAreaTargetSelectHandlers(List<WorldObject> targets, uint effIndex, SpellImplicitTargetInfo targetType)
{
foreach (var script in m_loadedScripts)
+28 -24
View File
@@ -152,9 +152,9 @@ namespace Game.Spells
Unit unitCaster = GetUnitCasterForEffectHandlers();
if (unitCaster != null && apply_direct_bonus)
{
uint bonus = unitCaster.SpellDamageBonusDone(unitTarget, m_spellInfo, (uint)damage, DamageEffectType.SpellDirect, effectInfo);
damage = (int)(bonus + (uint)(bonus * variance));
damage = (int)unitTarget.SpellDamageBonusTaken(unitCaster, m_spellInfo, (uint)damage, DamageEffectType.SpellDirect);
int bonus = unitCaster.SpellDamageBonusDone(unitTarget, m_spellInfo, damage, DamageEffectType.SpellDirect, effectInfo, 1, this);
damage = (int)(bonus + (bonus * variance));
damage = unitTarget.SpellDamageBonusTaken(unitCaster, m_spellInfo, damage, DamageEffectType.SpellDirect);
}
m_damage += damage;
@@ -684,9 +684,9 @@ namespace Game.Spells
// add spell damage bonus
if (unitCaster != null)
{
uint bonus = unitCaster.SpellDamageBonusDone(unitTarget, m_spellInfo, (uint)damage, DamageEffectType.SpellDirect, effectInfo);
damage = (int)(bonus + (uint)(bonus * variance));
damage = (int)unitTarget.SpellDamageBonusTaken(unitCaster, m_spellInfo, (uint)damage, DamageEffectType.SpellDirect);
int bonus = unitCaster.SpellDamageBonusDone(unitTarget, m_spellInfo, damage, DamageEffectType.SpellDirect, effectInfo, 1, this);
damage = (int)(bonus + (bonus * variance));
damage = unitTarget.SpellDamageBonusTaken(unitCaster, m_spellInfo, damage, DamageEffectType.SpellDirect);
}
int newDamage = -(unitTarget.ModifyPower(powerType, -damage));
@@ -803,14 +803,14 @@ namespace Game.Spells
}
// Death Pact - return pct of max health to caster
else if (m_spellInfo.SpellFamilyName == SpellFamilyNames.Deathknight && m_spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x00080000u))
addhealth = (int)unitCaster.SpellHealingBonusDone(unitTarget, m_spellInfo, (uint)unitCaster.CountPctFromMaxHealth(damage), DamageEffectType.Heal, effectInfo);
addhealth = unitCaster.SpellHealingBonusDone(unitTarget, m_spellInfo, (int)unitCaster.CountPctFromMaxHealth(damage), DamageEffectType.Heal, effectInfo, 1, this);
else
{
uint bonus = unitCaster.SpellHealingBonusDone(unitTarget, m_spellInfo, (uint)addhealth, DamageEffectType.Heal, effectInfo);
addhealth = (int)(bonus + (uint)(bonus * variance));
int bonus = unitCaster.SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, DamageEffectType.Heal, effectInfo, 1, this);
addhealth = (int)(bonus + (bonus * variance));
}
addhealth = (int)unitTarget.SpellHealingBonusTaken(unitCaster, m_spellInfo, (uint)addhealth, DamageEffectType.Heal);
addhealth = unitTarget.SpellHealingBonusTaken(unitCaster, m_spellInfo, addhealth, DamageEffectType.Heal);
// Remove Grievious bite if fully healed
if (unitTarget.HasAura(48920) && ((uint)(unitTarget.GetHealth() + (ulong)addhealth) >= unitTarget.GetMaxHealth()))
@@ -828,15 +828,15 @@ namespace Game.Spells
if (unitTarget == null || !unitTarget.IsAlive() || damage < 0)
return;
uint heal = (uint)unitTarget.CountPctFromMaxHealth(damage);
int heal = (int)unitTarget.CountPctFromMaxHealth(damage);
Unit unitCaster = GetUnitCasterForEffectHandlers();
if (unitCaster)
{
heal = unitCaster.SpellHealingBonusDone(unitTarget, m_spellInfo, heal, DamageEffectType.Heal, effectInfo);
heal = unitCaster.SpellHealingBonusDone(unitTarget, m_spellInfo, heal, DamageEffectType.Heal, effectInfo, 1, this);
heal = unitTarget.SpellHealingBonusTaken(unitCaster, m_spellInfo, heal, DamageEffectType.Heal);
}
m_healing += (int)heal;
m_healing += heal;
}
[SpellEffectHandler(SpellEffectName.HealMechanical)]
@@ -849,15 +849,15 @@ namespace Game.Spells
return;
Unit unitCaster = GetUnitCasterForEffectHandlers();
uint heal = (uint)damage;
int heal = damage;
if (unitCaster)
heal = unitCaster.SpellHealingBonusDone(unitTarget, m_spellInfo, heal, DamageEffectType.Heal, effectInfo);
heal = unitCaster.SpellHealingBonusDone(unitTarget, m_spellInfo, heal, DamageEffectType.Heal, effectInfo, 1, this);
heal += (uint)(heal * variance);
heal += (int)(heal * variance);
if (unitCaster)
heal = unitTarget.SpellHealingBonusTaken(unitCaster, m_spellInfo, heal, DamageEffectType.Heal);
m_healing += (int)heal;
m_healing += heal;
}
[SpellEffectHandler(SpellEffectName.HealthLeech)]
@@ -872,12 +872,12 @@ namespace Game.Spells
Unit unitCaster = GetUnitCasterForEffectHandlers();
uint bonus = 0;
if (unitCaster != null)
unitCaster.SpellDamageBonusDone(unitTarget, m_spellInfo, (uint)damage, DamageEffectType.SpellDirect, effectInfo);
bonus = (uint)unitCaster.SpellDamageBonusDone(unitTarget, m_spellInfo, damage, DamageEffectType.SpellDirect, effectInfo, 1, this);
damage = (int)(bonus + (uint)(bonus * variance));
if (unitCaster != null)
damage = (int)unitTarget.SpellDamageBonusTaken(unitCaster, m_spellInfo, (uint)damage, DamageEffectType.SpellDirect);
damage = unitTarget.SpellDamageBonusTaken(unitCaster, m_spellInfo, damage, DamageEffectType.SpellDirect);
Log.outDebug(LogFilter.Spells, "HealthLeech :{0}", damage);
@@ -895,8 +895,8 @@ namespace Game.Spells
if (unitCaster != null && unitCaster.IsAlive())
{
healthGain = unitCaster.SpellHealingBonusDone(unitCaster, m_spellInfo, healthGain, DamageEffectType.Heal, effectInfo);
healthGain = unitCaster.SpellHealingBonusTaken(unitCaster, m_spellInfo, healthGain, DamageEffectType.Heal);
healthGain = (uint)unitCaster.SpellHealingBonusDone(unitCaster, m_spellInfo, (int)healthGain, DamageEffectType.Heal, effectInfo, 1, this);
healthGain = (uint)unitCaster.SpellHealingBonusTaken(unitCaster, m_spellInfo, (int)healthGain, DamageEffectType.Heal);
HealInfo healInfo = new(unitCaster, unitCaster, healthGain, m_spellInfo, m_spellSchoolMask);
unitCaster.HealBySpell(healInfo);
@@ -2448,6 +2448,7 @@ namespace Game.Spells
}
uint weaponDamage = unitCaster.CalculateDamage(m_attackType, normalized, addPctMods);
Mechanics mechanic = Mechanics.None;
// Sequence is important
foreach (var spellEffectInfo in m_spellInfo.GetEffects())
@@ -2465,8 +2466,11 @@ namespace Game.Spells
weaponDamage = (uint)(weaponDamage * weaponDamagePercentMod);
break;
default:
break; // not weapon damage effect, just skip
continue; // not weapon damage effect, just skip
}
if (spellEffectInfo.Mechanic != Mechanics.None && mechanic == Mechanics.None)
mechanic = spellEffectInfo.Mechanic;
}
weaponDamage += (uint)spell_bonus;
@@ -2476,8 +2480,8 @@ namespace Game.Spells
weaponDamage = Math.Max(weaponDamage, 0);
// Add melee damage bonuses (also check for negative)
weaponDamage = unitCaster.MeleeDamageBonusDone(unitTarget, weaponDamage, m_attackType, DamageEffectType.SpellDirect, m_spellInfo, effectInfo);
m_damage += (int)unitTarget.MeleeDamageBonusTaken(unitCaster, weaponDamage, m_attackType, DamageEffectType.SpellDirect, m_spellInfo);
weaponDamage = (uint)unitCaster.MeleeDamageBonusDone(unitTarget, (int)weaponDamage, m_attackType, DamageEffectType.SpellDirect, m_spellInfo, mechanic, m_spellSchoolMask, this);
m_damage += unitTarget.MeleeDamageBonusTaken(unitCaster, (int)weaponDamage, m_attackType, DamageEffectType.SpellDirect, m_spellInfo);
}
[SpellEffectHandler(SpellEffectName.Threat)]