From d7c2fa52f4a2dfabcd5bb7b75e47c20131a5aa73 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Wed, 13 Sep 2023 18:18:29 -0400 Subject: [PATCH] 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) --- Source/Framework/Constants/ScriptsConst.cs | 3 + Source/Game/Entities/Unit/Unit.Combat.cs | 4 +- Source/Game/Entities/Unit/Unit.Spells.cs | 67 ++++++++----- Source/Game/Entities/Unit/Unit.cs | 25 ++--- Source/Game/Scripting/SpellScript.cs | 107 ++++++++++++++++++--- Source/Game/Spells/Auras/Aura.cs | 17 +++- Source/Game/Spells/Auras/AuraEffect.cs | 44 ++++----- Source/Game/Spells/Spell.cs | 24 +++++ Source/Game/Spells/SpellEffects.cs | 52 +++++----- Source/Scripts/Spells/Priest.cs | 12 +-- 10 files changed, 248 insertions(+), 107 deletions(-) diff --git a/Source/Framework/Constants/ScriptsConst.cs b/Source/Framework/Constants/ScriptsConst.cs index 4562d9599..12d7faf84 100644 --- a/Source/Framework/Constants/ScriptsConst.cs +++ b/Source/Framework/Constants/ScriptsConst.cs @@ -31,6 +31,8 @@ namespace Framework.Constants OnResistAbsorbCalculation, AfterCast, CalcCritChance, + CalcDamage, + CalcHealing, OnPrecast, CalcCastTime } @@ -48,6 +50,7 @@ namespace Framework.Constants EffectCalcPeriodic, EffectCalcSpellmod, EffectCalcCritChance, + EffectCalcDamageAndHealing, EffectAbsorb, EffectAfterAbsorb, EffectManaShield, diff --git a/Source/Game/Entities/Unit/Unit.Combat.cs b/Source/Game/Entities/Unit/Unit.Combat.cs index 09a88b235..22f604311 100644 --- a/Source/Game/Entities/Unit/Unit.Combat.cs +++ b/Source/Game/Entities/Unit/Unit.Combat.cs @@ -1103,8 +1103,8 @@ namespace Game.Entities uint damage = 0; damage += CalculateDamage(damageInfo.AttackType, false, true); // Add melee damage bonus - damage = MeleeDamageBonusDone(damageInfo.Target, damage, damageInfo.AttackType, DamageEffectType.Direct, null, null, (SpellSchoolMask)damageInfo.DamageSchoolMask); - damage = damageInfo.Target.MeleeDamageBonusTaken(this, damage, damageInfo.AttackType, DamageEffectType.Direct, null, (SpellSchoolMask)damageInfo.DamageSchoolMask); + damage = (uint)MeleeDamageBonusDone(damageInfo.Target, (int)damage, damageInfo.AttackType, DamageEffectType.Direct, null, default, (SpellSchoolMask)damageInfo.DamageSchoolMask); + damage = (uint)damageInfo.Target.MeleeDamageBonusTaken(this, (int)damage, damageInfo.AttackType, DamageEffectType.Direct, null, (SpellSchoolMask)damageInfo.DamageSchoolMask); // Script Hook For CalculateMeleeDamage -- Allow scripts to change the Damage pre class mitigation calculations Global.ScriptMgr.ModifyMeleeDamage(damageInfo.Target, damageInfo.Attacker, ref damage); diff --git a/Source/Game/Entities/Unit/Unit.Spells.cs b/Source/Game/Entities/Unit/Unit.Spells.cs index d45fada80..a13f50068 100644 --- a/Source/Game/Entities/Unit/Unit.Spells.cs +++ b/Source/Game/Entities/Unit/Unit.Spells.cs @@ -57,25 +57,38 @@ namespace Game.Entities return DoneAdvertisedBenefit; } - public uint SpellDamageBonusDone(Unit victim, SpellInfo spellProto, uint pdamage, DamageEffectType damagetype, SpellEffectInfo spellEffectInfo, uint stack = 1) + public int SpellDamageBonusDone(Unit victim, SpellInfo spellProto, int pdamage, DamageEffectType damagetype, SpellEffectInfo spellEffectInfo, uint stack = 1, Spell spell = null, AuraEffect aurEff = null) { - if (spellProto == null || victim == null || damagetype == DamageEffectType.Direct) + if (spellProto == null || victim == null) return pdamage; + int DoneTotal = 0; + float DoneTotalMod = 1.0f; + + void callDamageScript(ref int dmg, ref int flatMod, ref float pctMod) + { + if (spell != null) + spell.CallScriptCalcDamageHandlers(victim, ref dmg, ref flatMod, ref pctMod); + else if (aurEff != null) + aurEff.GetBase().CallScriptCalcDamageAndHealingHandlers(aurEff, aurEff.GetBase().GetApplicationOfTarget(victim.GetGUID()), victim, ref dmg, ref flatMod, ref pctMod); + } + // Some spells don't benefit from done mods - if (spellProto.HasAttribute(SpellAttr3.IgnoreCasterModifiers)) - return pdamage; + if (damagetype == DamageEffectType.Direct || spellProto.HasAttribute(SpellAttr3.IgnoreCasterModifiers)) + { + callDamageScript(ref pdamage, ref DoneTotal, ref DoneTotalMod); + return (int)Math.Max((float)(pdamage + DoneTotal) * DoneTotalMod, 0.0f); + } // For totems get damage bonus from owner if (IsTypeId(TypeId.Unit) && IsTotem()) { Unit owner = GetOwner(); if (owner != null) - return owner.SpellDamageBonusDone(victim, spellProto, pdamage, damagetype, spellEffectInfo, stack); + return owner.SpellDamageBonusDone(victim, spellProto, pdamage, damagetype, spellEffectInfo, stack, spell, aurEff); } - int DoneTotal = 0; - float DoneTotalMod = SpellDamagePctDone(victim, spellProto, damagetype, spellEffectInfo); + DoneTotalMod = SpellDamagePctDone(victim, spellProto, damagetype, spellEffectInfo); // Done fixed damage bonus auras int DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto.GetSchoolMask()); @@ -114,7 +127,7 @@ namespace Game.Entities { // No bonus damage for SPELL_DAMAGE_CLASS_NONE class spells by default if (spellProto.DmgClass == SpellDmgClass.None) - return (uint)Math.Max(pdamage * DoneTotalMod, 0.0f); + return (int)Math.Max(pdamage * DoneTotalMod, 0.0f); } // Default calculation @@ -131,13 +144,16 @@ namespace Game.Entities DoneTotal += (int)(DoneAdvertisedBenefit * coeff * stack); } - float tmpDamage = (float)((int)pdamage + DoneTotal) * DoneTotalMod; + callDamageScript(ref pdamage, ref DoneTotal, ref DoneTotalMod); + + float tmpDamage = (float)(pdamage + DoneTotal) * DoneTotalMod; + // apply spellmod to Done damage (flat and pct) Player _modOwner = GetSpellModOwner(); if (_modOwner != null) _modOwner.ApplySpellMod(spellProto, damagetype == DamageEffectType.DOT ? SpellModOp.PeriodicHealingAndDamage : SpellModOp.HealingAndDamage, ref tmpDamage); - return (uint)Math.Max(tmpDamage, 0.0f); + return (int)Math.Max(tmpDamage, 0.0f); } public float SpellDamagePctDone(Unit victim, SpellInfo spellProto, DamageEffectType damagetype, SpellEffectInfo spellEffectInfo) @@ -243,7 +259,7 @@ namespace Game.Entities return DoneTotalMod; } - public uint SpellDamageBonusTaken(Unit caster, SpellInfo spellProto, uint pdamage, DamageEffectType damagetype) + public int SpellDamageBonusTaken(Unit caster, SpellInfo spellProto, int pdamage, DamageEffectType damagetype) { if (spellProto == null || damagetype == DamageEffectType.Direct) return pdamage; @@ -323,7 +339,7 @@ namespace Game.Entities } float tmpDamage = pdamage * TakenTotalMod; - return (uint)Math.Max(tmpDamage, 0.0f); + return (int)Math.Max(tmpDamage, 0.0f); } public uint SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) @@ -386,14 +402,14 @@ namespace Game.Entities return damage; } - public uint SpellHealingBonusDone(Unit victim, SpellInfo spellProto, uint healamount, DamageEffectType damagetype, SpellEffectInfo spellEffectInfo, uint stack = 1) + public int SpellHealingBonusDone(Unit victim, SpellInfo spellProto, int healamount, DamageEffectType damagetype, SpellEffectInfo spellEffectInfo, uint stack = 1, Spell spell = null, AuraEffect aurEff = null) { // For totems get healing bonus from owner (statue isn't totem in fact) if (IsTypeId(TypeId.Unit) && IsTotem()) { Unit owner = GetOwner(); if (owner) - return owner.SpellHealingBonusDone(victim, spellProto, healamount, damagetype, spellEffectInfo, stack); + return owner.SpellHealingBonusDone(victim, spellProto, healamount, damagetype, spellEffectInfo, stack, spell, aurEff); } // No bonus healing for potion spells @@ -406,15 +422,15 @@ namespace Game.Entities // done scripted mod (take it from owner) Unit owner1 = GetOwner() ?? this; var mOverrideClassScript = owner1.GetAuraEffectsByType(AuraType.OverrideClassScripts); - foreach (var aurEff in mOverrideClassScript) + foreach (var effect in mOverrideClassScript) { - if (!aurEff.IsAffectingSpell(spellProto)) + if (!effect.IsAffectingSpell(spellProto)) continue; - switch (aurEff.GetMiscValue()) + switch (effect.GetMiscValue()) { case 3736: // Hateful Totem of the Third Wind / Increased Lesser Healing Wave / LK Arena (4/5/6) Totem of the Third Wind / Savage Totem of the Third Wind - DoneTotal += aurEff.GetAmount(); + DoneTotal += effect.GetAmount(); break; default: break; @@ -445,7 +461,7 @@ namespace Game.Entities { // No bonus healing for SPELL_DAMAGE_CLASS_NONE class spells by default if (spellProto.DmgClass == SpellDmgClass.None) - return (uint)Math.Max(healamount * DoneTotalMod, 0.0f); + return (int)Math.Max(healamount * DoneTotalMod, 0.0f); } // Default calculation @@ -476,14 +492,19 @@ namespace Game.Entities DoneTotal = 0; } - float heal = (float)((int)healamount + DoneTotal) * DoneTotalMod; + if (spell != null) + spell.CallScriptCalcHealingHandlers(victim, ref healamount, ref DoneTotal, ref DoneTotalMod); + else if (aurEff != null) + aurEff.GetBase().CallScriptCalcDamageAndHealingHandlers(aurEff, aurEff.GetBase().GetApplicationOfTarget(victim.GetGUID()), victim, ref healamount, ref DoneTotal, ref DoneTotalMod); + + float heal = (float)(healamount + DoneTotal) * DoneTotalMod; // apply spellmod to Done amount Player _modOwner = GetSpellModOwner(); if (_modOwner) _modOwner.ApplySpellMod(spellProto, damagetype == DamageEffectType.DOT ? SpellModOp.PeriodicHealingAndDamage : SpellModOp.HealingAndDamage, ref heal); - return (uint)Math.Max(heal, 0.0f); + return (int)Math.Max(heal, 0.0f); } public float SpellHealingPctDone(Unit victim, SpellInfo spellProto) @@ -539,7 +560,7 @@ namespace Game.Entities return DoneTotalMod; } - public uint SpellHealingBonusTaken(Unit caster, SpellInfo spellProto, uint healamount, DamageEffectType damagetype) + public int SpellHealingBonusTaken(Unit caster, SpellInfo spellProto, int healamount, DamageEffectType damagetype) { float TakenTotalMod = 1.0f; @@ -589,7 +610,7 @@ namespace Game.Entities } float heal = healamount * TakenTotalMod; - return (uint)Math.Max(heal, 0.0f); + return (int)Math.Max(heal, 0.0f); } public float SpellCritChanceDone(Spell spell, AuraEffect aurEff, SpellSchoolMask schoolMask, WeaponAttackType attackType = WeaponAttackType.BaseAttack) diff --git a/Source/Game/Entities/Unit/Unit.cs b/Source/Game/Entities/Unit/Unit.cs index c44a3f4e1..48a73764d 100644 --- a/Source/Game/Entities/Unit/Unit.cs +++ b/Source/Game/Entities/Unit/Unit.cs @@ -3023,8 +3023,8 @@ namespace Game.Entities Unit caster = dmgShield.GetCaster(); if (caster) { - damage = caster.SpellDamageBonusDone(this, spellInfo, damage, DamageEffectType.SpellDirect, dmgShield.GetSpellEffectInfo()); - damage = SpellDamageBonusTaken(caster, spellInfo, damage, DamageEffectType.SpellDirect); + damage = (uint)caster.SpellDamageBonusDone(this, spellInfo, (int)damage, DamageEffectType.SpellDirect, dmgShield.GetSpellEffectInfo()); + damage = (uint)SpellDamageBonusTaken(caster, spellInfo, (int)damage, DamageEffectType.SpellDirect); } DamageInfo damageInfo1 = new(this, victim, damage, spellInfo, spellInfo.GetSchoolMask(), DamageEffectType.SpellDirect, WeaponAttackType.BaseAttack); @@ -3850,7 +3850,7 @@ namespace Game.Entities return (uint)Math.Max(damage * (1.0f - mitigation), 0.0f); } - public uint MeleeDamageBonusDone(Unit victim, uint damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo spellProto = null, SpellEffectInfo spellEffectInfo = null, SpellSchoolMask damageSchoolMask = SpellSchoolMask.Normal) + public int MeleeDamageBonusDone(Unit victim, int damage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo spellProto = null, Mechanics mechanic = default, SpellSchoolMask damageSchoolMask = SpellSchoolMask.Normal, Spell spell = null, AuraEffect aurEff = null) { if (victim == null || damage == 0) return 0; @@ -3944,12 +3944,17 @@ namespace Game.Entities }); // Add SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC percent bonus - if (spellEffectInfo != null && spellEffectInfo.Mechanic != 0) - MathFunctions.AddPct(ref DoneTotalMod, GetTotalAuraModifierByMiscValue(AuraType.ModDamageDoneForMechanic, (int)spellEffectInfo.Mechanic)); + if (mechanic != Mechanics.None) + MathFunctions.AddPct(ref DoneTotalMod, GetTotalAuraModifierByMiscValue(AuraType.ModDamageDoneForMechanic, (int)mechanic)); else if (spellProto != null && spellProto.Mechanic != 0) MathFunctions.AddPct(ref DoneTotalMod, GetTotalAuraModifierByMiscValue(AuraType.ModDamageDoneForMechanic, (int)spellProto.Mechanic)); - float damageF = damage; + if (spell != null) + spell.CallScriptCalcDamageHandlers(victim, ref damage, ref DoneFlatBenefit, ref DoneTotalMod); + else if (aurEff != null) + aurEff.GetBase().CallScriptCalcDamageAndHealingHandlers(aurEff, aurEff.GetBase().GetApplicationOfTarget(victim.GetGUID()), victim, ref damage, ref DoneFlatBenefit, ref DoneTotalMod); + + float damageF = (float)(damage + DoneFlatBenefit) * DoneTotalMod; // apply spellmod to Done damage if (spellProto != null) @@ -3959,13 +3964,11 @@ namespace Game.Entities modOwner.ApplySpellMod(spellProto, damagetype == DamageEffectType.DOT ? SpellModOp.PeriodicHealingAndDamage : SpellModOp.HealingAndDamage, ref damageF); } - damageF = (damageF + DoneFlatBenefit) * DoneTotalMod; - // bonus result can be negative - return (uint)Math.Max(damageF, 0.0f); + return (int)Math.Max(damageF, 0.0f); } - public uint MeleeDamageBonusTaken(Unit attacker, uint pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo spellProto = null, SpellSchoolMask damageSchoolMask = SpellSchoolMask.Normal) + public int MeleeDamageBonusTaken(Unit attacker, int pdamage, WeaponAttackType attType, DamageEffectType damagetype, SpellInfo spellProto = null, SpellSchoolMask damageSchoolMask = SpellSchoolMask.Normal) { if (pdamage == 0) return 0; @@ -4068,7 +4071,7 @@ namespace Game.Entities } float tmpDamage = (float)(pdamage + TakenFlatBenefit) * TakenTotalMod; - return (uint)Math.Max(tmpDamage, 0.0f); + return (int)Math.Max(tmpDamage, 0.0f); } bool IsBlockCritical() diff --git a/Source/Game/Scripting/SpellScript.cs b/Source/Game/Scripting/SpellScript.cs index a1b9b5649..3efe8cb7f 100644 --- a/Source/Game/Scripting/SpellScript.cs +++ b/Source/Game/Scripting/SpellScript.cs @@ -164,6 +164,7 @@ namespace Game.Scripting // internal use classes & functions // DO NOT OVERRIDE THESE IN SCRIPTS public delegate SpellCastResult SpellCheckCastFnType(); + public delegate void DamageAndHealingCalcFnType(Unit victim, ref int damageOrHealing, ref int flatMod, ref float pctMod); public delegate void SpellOnResistAbsorbCalculateFnType(DamageInfo damageInfo, ref uint resistAmount, ref int absorbAmount); public delegate void SpellEffectFnType(uint index); public delegate void SpellBeforeHitFnType(SpellMissInfo missInfo); @@ -201,6 +202,21 @@ namespace Game.Scripting } } + public class DamageAndHealingCalcHandler + { + DamageAndHealingCalcFnType _callImpl; + + public DamageAndHealingCalcHandler(DamageAndHealingCalcFnType handler) + { + _callImpl = handler; + } + + public void Call(Unit victim, ref int damageOrHealing, ref int flatMod, ref float pctMod) + { + _callImpl(victim, ref damageOrHealing, ref flatMod, ref pctMod); + } + } + public class OnCalculateResistAbsorbHandler { SpellOnResistAbsorbCalculateFnType _callImpl; @@ -435,6 +451,27 @@ namespace Game.Scripting if (eff.GetAffectedEffectsMask(entry) == 0) Log.outError(LogFilter.Scripts, "Spell `{0}` Effect `{1}` of script `{2}` did not match dbc effect data - handler bound to hook `OnObjectTargetSelect` of SpellScript won't be executed", entry.Id, eff.ToString(), m_scriptName); + if (!CalcDamage.Empty()) + { + if (!entry.HasEffect(SpellEffectName.SchoolDamage) + && !entry.HasEffect(SpellEffectName.PowerDrain) + && !entry.HasEffect(SpellEffectName.HealthLeech) + && !entry.HasEffect(SpellEffectName.WeaponDamage) + && !entry.HasEffect(SpellEffectName.WeaponDamageNoSchool) + && !entry.HasEffect(SpellEffectName.NormalizedWeaponDmg) + && !entry.HasEffect(SpellEffectName.WeaponPercentDamage)) + Log.outError(LogFilter.Scripts, $"Spell `{entry.Id}` script `{m_scriptName}` does not have a damage effect - handler bound to hook `CalcDamage` of SpellScript won't be executed"); + } + + if (!CalcHealing.Empty()) + { + if (!entry.HasEffect(SpellEffectName.Heal) + && !entry.HasEffect(SpellEffectName.HealPct) + && !entry.HasEffect(SpellEffectName.HealMechanical) + && !entry.HasEffect(SpellEffectName.HealthLeech)) + Log.outError(LogFilter.Scripts, $"Spell `{entry.Id}` script `{m_scriptName}` does not have a damage effect - handler bound to hook `CalcHealing` of SpellScript won't be executed"); + } + return base._Validate(entry); } @@ -478,7 +515,9 @@ namespace Game.Scripting || IsInEffectHook() || m_currentScriptState == (byte)SpellScriptHookType.OnCast || m_currentScriptState == (byte)SpellScriptHookType.AfterCast - || m_currentScriptState == (byte)SpellScriptHookType.CalcCritChance; + || m_currentScriptState == (byte)SpellScriptHookType.CalcCritChance + || m_currentScriptState == (byte)SpellScriptHookType.CalcDamage + || m_currentScriptState == (byte)SpellScriptHookType.CalcHealing; } public bool IsInTargetHook() @@ -556,20 +595,32 @@ namespace Game.Scripting // where function is void function(SpellDestination target) public List OnDestinationTargetSelect = new(); + // where function is void function(Unit victim, ref int damage, ref int flatMod, ref float pctMod) + public List CalcDamage = new(); + + // where function is void function(Unit victim, ref int healing, ref int flatMod, ref float pctMod) + public List CalcHealing = new(); + // hooks are executed in following order, at specified event of spell: - // 1. BeforeCast - executed when spell preparation is finished (when cast bar becomes full) before cast is handled - // 2. OnCheckCast - allows to override result of CheckCast function - // 3a. OnObjectAreaTargetSelect - executed just before adding selected targets to final target list (for area targets) - // 3b. OnObjectTargetSelect - executed just before adding selected target to final target list (for single unit targets) - // 4. OnCast - executed just before spell is launched (creates missile) or executed - // 5. AfterCast - executed after spell missile is launched and immediate spell actions are done - // 6. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched - // 7. OnEffectLaunchTarget - executed just before specified effect handler call - when spell missile is launched - called for each target from spell target map - // 8. OnEffectHit - executed just before specified effect handler call - when spell missile hits dest - // 9. BeforeHit - executed just before spell hits a target - called for each target from spell target map - // 10. OnEffectHitTarget - executed just before specified effect handler call - called for each target from spell target map - // 11. OnHit - executed just before spell deals damage and procs auras - when spell hits target - called for each target from spell target map - // 12. AfterHit - executed just after spell finishes all it's jobs for target - called for each target from spell target map + // 1. OnPrecast - executed during spell preparation (before cast bar starts) + // 2. BeforeCast - executed when spell preparation is finished (when cast bar becomes full) before cast is handled + // 3. OnCheckCast - allows to override result of CheckCast function + // 4a. OnObjectAreaTargetSelect - executed just before adding selected targets to final target list (for area targets) + // 4b. OnObjectTargetSelect - executed just before adding selected target to final target list (for single unit targets) + // 4c. OnDestinationTargetSelect - executed just before adding selected target to final target list (for destination targets) + // 5. OnCast - executed just before spell is launched (creates missile) or executed + // 6. AfterCast - executed after spell missile is launched and immediate spell actions are done + // 7. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched + // 8. OnCalcCritChance - executed just after specified effect handler call - when spell missile is launched - called for each target from spell target map + // 9. OnEffectLaunchTarget - executed just before specified effect handler call - when spell missile is launched - called for each target from spell target map + // 10a. CalcDamage - executed during specified effect handler call - when spell missile is launched - called for each target from spell target map + // 10b. CalcHealing - executed during specified effect handler call - when spell missile is launched - called for each target from spell target map + // 11. OnCalculateResistAbsorb - executed when damage resist/absorbs is calculated - before spell hit target + // 12. OnEffectHit - executed just before specified effect handler call - when spell missile hits dest + // 13. BeforeHit - executed just before spell hits a target - called for each target from spell target map + // 14. OnEffectHitTarget - executed just before specified effect handler call - called for each target from spell target map + // 15. OnHit - executed just before spell deals damage and procs auras - when spell hits target - called for each target from spell target map + // 16. AfterHit - executed just after spell finishes all it's jobs for target - called for each target from spell target map // // methods allowing interaction with Spell object @@ -1041,6 +1092,7 @@ namespace Game.Scripting // DO NOT OVERRIDE THESE IN SCRIPTS public delegate bool AuraCheckAreaTargetDelegate(Unit target); public delegate void AuraDispelDelegate(DispelInfo dispelInfo); + public delegate void AuraEffectDamageAndHealingCalcFnType(AuraEffect aurEff, Unit victim, ref int damageOrHealing, ref int flatMod, ref float pctMod); public delegate void AuraEffectApplicationModeDelegate(AuraEffect aura, AuraEffectHandleModes auraMode); public delegate void AuraEffectPeriodicDelegate(AuraEffect aura); public delegate void AuraEffectUpdatePeriodicDelegate(AuraEffect aura); @@ -1196,6 +1248,21 @@ namespace Game.Scripting } } + public class EffectCalcDamageAndHealingHandler : EffectBase + { + AuraEffectDamageAndHealingCalcFnType _callImpl; + + public EffectCalcDamageAndHealingHandler(AuraEffectDamageAndHealingCalcFnType handler, byte effIndex, AuraType auraType) : base(effIndex, auraType) + { + _callImpl = handler; + } + + public void Call(AuraEffect aurEff, Unit victim, ref int damageOrHealing, ref int flatMod, ref float pctMod) + { + _callImpl(aurEff, victim, ref damageOrHealing, ref flatMod, ref pctMod); + } + } + public class EffectApplyHandler : EffectBase { AuraEffectApplicationModeDelegate _callImpl; @@ -1410,6 +1477,10 @@ namespace Game.Scripting if (eff.GetAffectedEffectsMask(entry) == 0) Log.outError(LogFilter.Scripts, $"Spell `{entry.Id}` Effect `{eff}` of script `{m_scriptName}` did not match dbc effect data - handler bound to hook `DoEffectCalcCritChance` of AuraScript won't be executed"); + foreach (var hook in DoEffectCalcDamageAndHealing) + if (hook.GetAffectedEffectsMask(entry) == 0) + Log.outError(LogFilter.Scripts, $"Spell `{entry.Id}` Effect `{hook}` of script `{m_scriptName}` did not match dbc effect data - handler bound to hook `DoEffectCalcDamageAndHealing` of AuraScript won't be executed"); + foreach (var eff in OnEffectAbsorb) if (eff.GetAffectedEffectsMask(entry) == 0) Log.outError(LogFilter.Scripts, "Spell `{0}` Effect `{1}` of script `{2}` did not match dbc effect data - handler bound to hook `OnEffectAbsorb` of AuraScript won't be executed", entry.Id, eff.ToString(), m_scriptName); @@ -1580,6 +1651,12 @@ namespace Game.Scripting // where function is: void function (AuraEffect const* aurEff, Unit* victim, float& critChance); public List DoEffectCalcCritChance = new(); + // executed when aura effect calculates damage or healing for dots and hots + // example: DoEffectCalcDamageAndHealing += AuraEffectCalcDamageFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier); + // example: DoEffectCalcDamageAndHealing += AuraEffectCalcHealingFn(class::function, EffectIndexSpecifier, EffectAuraNameSpecifier); + // where function is: void(AuraEffect aurEff, Unit victim, ref int damageOrHealing, ref int flatMod, ref float pctMod); + public List DoEffectCalcDamageAndHealing = new(); + // executed when absorb aura effect is going to reduce damage // example: OnEffectAbsorb += AuraEffectAbsorbFn(class.function, EffectIndexSpecifier); // where function is: void function (AuraEffect aurEff, DamageInfo& dmgInfo, uint& absorbAmount); @@ -1783,6 +1860,8 @@ namespace Game.Scripting case AuraScriptHookType.EffectAfterApply: case AuraScriptHookType.EffectAfterRemove: case AuraScriptHookType.EffectPeriodic: + case AuraScriptHookType.EffectCalcCritChance: + case AuraScriptHookType.EffectCalcDamageAndHealing: case AuraScriptHookType.EffectAbsorb: case AuraScriptHookType.EffectAfterAbsorb: case AuraScriptHookType.EffectManaShield: diff --git a/Source/Game/Spells/Auras/Aura.cs b/Source/Game/Spells/Auras/Aura.cs index 5b5d5a540..e01d0e415 100644 --- a/Source/Game/Spells/Auras/Aura.cs +++ b/Source/Game/Spells/Auras/Aura.cs @@ -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) { diff --git a/Source/Game/Spells/Auras/AuraEffect.cs b/Source/Game/Spells/Auras/AuraEffect.cs index da97fc48d..8d191aec2 100644 --- a/Source/Game/Spells/Auras/AuraEffect.cs +++ b/Source/Game/Spells/Auras/AuraEffect.cs @@ -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); diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index d9ab14d86..a511bdbe0 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -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 targets, uint effIndex, SpellImplicitTargetInfo targetType) { foreach (var script in m_loadedScripts) diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index 75d2e01d1..8911f93a0 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -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)] diff --git a/Source/Scripts/Spells/Priest.cs b/Source/Scripts/Spells/Priest.cs index 9943ccac4..5c2009a2f 100644 --- a/Source/Scripts/Spells/Priest.cs +++ b/Source/Scripts/Spells/Priest.cs @@ -942,10 +942,10 @@ namespace Scripts.Spells.Priest { PreventHitDefaultEffect(effIndex); - float damageBonus = GetCaster().SpellDamageBonusDone(GetHitUnit(), GetSpellInfo(), (uint)GetEffectValue(), DamageEffectType.SpellDirect, GetEffectInfo()); + float damageBonus = GetCaster().SpellDamageBonusDone(GetHitUnit(), GetSpellInfo(), GetEffectValue(), DamageEffectType.SpellDirect, GetEffectInfo()); float value = damageBonus + damageBonus * GetEffectVariance(); value *= 1.0f + (powerOfTheDarkSide.GetAmount() / 100.0f); - value = GetHitUnit().SpellDamageBonusTaken(GetCaster(), GetSpellInfo(), (uint)value, DamageEffectType.SpellDirect); + value = GetHitUnit().SpellDamageBonusTaken(GetCaster(), GetSpellInfo(), (int)value, DamageEffectType.SpellDirect); SetHitDamage((int)value); } } @@ -972,10 +972,10 @@ namespace Scripts.Spells.Priest { PreventHitDefaultEffect(effIndex); - float healingBonus = GetCaster().SpellHealingBonusDone(GetHitUnit(), GetSpellInfo(), (uint)GetEffectValue(), DamageEffectType.Heal, GetEffectInfo()); + float healingBonus = GetCaster().SpellHealingBonusDone(GetHitUnit(), GetSpellInfo(), GetEffectValue(), DamageEffectType.Heal, GetEffectInfo()); float value = healingBonus + healingBonus * GetEffectVariance(); value *= 1.0f + (powerOfTheDarkSide.GetAmount() / 100.0f); - value = GetHitUnit().SpellHealingBonusTaken(GetCaster(), GetSpellInfo(), (uint)value, DamageEffectType.Heal); + value = GetHitUnit().SpellHealingBonusTaken(GetCaster(), GetSpellInfo(), (int)value, DamageEffectType.Heal); SetHitHeal((int)value); } } @@ -1212,7 +1212,7 @@ namespace Scripts.Spells.Priest void HandleEffectDummy(uint effIndex) { // Note: we need to increase BasePoints by 1 since it's 4 as default. - uint basePoints = GetCaster().SpellHealingBonusDone(GetHitUnit(), _spellInfoHeal, (uint)_healEffectDummy.CalcValue(GetCaster()), DamageEffectType.Heal, _healEffectDummy); + uint basePoints = (uint)GetCaster().SpellHealingBonusDone(GetHitUnit(), _spellInfoHeal, _healEffectDummy.CalcValue(GetCaster()), DamageEffectType.Heal, _healEffectDummy); CastSpellExtraArgs args = new(TriggerCastFlags.FullMask); args.AddSpellMod(SpellValueMod.AuraStack, GetEffectValue()); args.AddSpellMod(SpellValueMod.BasePoint0, (int)basePoints); @@ -1338,7 +1338,7 @@ namespace Scripts.Spells.Priest if (origCaster != null) { - uint basePoints = origCaster.SpellHealingBonusDone(target, _spellInfoHeal, (uint)_healEffectDummy.CalcValue(origCaster), DamageEffectType.Heal, _healEffectDummy); + uint basePoints = (uint)origCaster.SpellHealingBonusDone(target, _spellInfoHeal, _healEffectDummy.CalcValue(origCaster), DamageEffectType.Heal, _healEffectDummy); CastSpellExtraArgs args = new(TriggerCastFlags.FullMask); args.AddSpellMod(SpellValueMod.AuraStack, GetEffectValue()); args.AddSpellMod(SpellValueMod.BasePoint0, (int)basePoints);