Core/Auras: Implemented OnHeartbeat AuraScript hook and refactored an aurascript to use it as example
Port From (https://github.com/TrinityCore/TrinityCore/commit/55ce5b150f716b6d470af80a9c31adf78e4cc198)
This commit is contained in:
@@ -59,6 +59,7 @@ namespace Framework.Constants
|
|||||||
CheckAreaTarget,
|
CheckAreaTarget,
|
||||||
Dispel,
|
Dispel,
|
||||||
AfterDispel,
|
AfterDispel,
|
||||||
|
OnHeartbeat,
|
||||||
EnterLeaveCombat,
|
EnterLeaveCombat,
|
||||||
// Spell Proc Hooks
|
// Spell Proc Hooks
|
||||||
CheckProc,
|
CheckProc,
|
||||||
|
|||||||
@@ -2562,7 +2562,7 @@ namespace Game.Entities
|
|||||||
// SMSG_FLIGHT_SPLINE_SYNC for cyclic splines
|
// SMSG_FLIGHT_SPLINE_SYNC for cyclic splines
|
||||||
SendFlightSplineSyncUpdate();
|
SendFlightSplineSyncUpdate();
|
||||||
|
|
||||||
// Trigger heartbeat procs and generic aura behavior such as food emotes
|
// Trigger heartbeat procs and generic aura behavior such as food emotes and invoking aura script hooks
|
||||||
TriggerAuraHeartbeat();
|
TriggerAuraHeartbeat();
|
||||||
|
|
||||||
// Update Vignette position and visibility
|
// Update Vignette position and visibility
|
||||||
|
|||||||
@@ -1094,6 +1094,7 @@ namespace Game.Scripting
|
|||||||
// DO NOT OVERRIDE THESE IN SCRIPTS
|
// DO NOT OVERRIDE THESE IN SCRIPTS
|
||||||
public delegate bool AuraCheckAreaTargetDelegate(Unit target);
|
public delegate bool AuraCheckAreaTargetDelegate(Unit target);
|
||||||
public delegate void AuraDispelDelegate(DispelInfo dispelInfo);
|
public delegate void AuraDispelDelegate(DispelInfo dispelInfo);
|
||||||
|
public delegate void AuraHeartbeatDelegate();
|
||||||
public delegate void AuraEffectDamageAndHealingCalcFnType(AuraEffect aurEff, Unit victim, ref int damageOrHealing, ref int flatMod, ref float pctMod);
|
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 AuraEffectApplicationModeDelegate(AuraEffect aura, AuraEffectHandleModes auraMode);
|
||||||
public delegate void AuraEffectPeriodicDelegate(AuraEffect aura);
|
public delegate void AuraEffectPeriodicDelegate(AuraEffect aura);
|
||||||
@@ -1135,6 +1136,18 @@ namespace Game.Scripting
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class AuraHeartbeatHandler
|
||||||
|
{
|
||||||
|
AuraHeartbeatDelegate _callImpl;
|
||||||
|
|
||||||
|
public AuraHeartbeatHandler(AuraHeartbeatDelegate callImpl) { _callImpl = callImpl; }
|
||||||
|
|
||||||
|
public void Call(AuraScript auraScript)
|
||||||
|
{
|
||||||
|
_callImpl();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class EffectBase : EffectHook
|
public class EffectBase : EffectHook
|
||||||
{
|
{
|
||||||
AuraType _effAurName;
|
AuraType _effAurName;
|
||||||
@@ -1264,7 +1277,7 @@ namespace Game.Scripting
|
|||||||
_callImpl(aurEff, victim, ref damageOrHealing, ref flatMod, ref pctMod);
|
_callImpl(aurEff, victim, ref damageOrHealing, ref flatMod, ref pctMod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EffectApplyHandler : EffectBase
|
public class EffectApplyHandler : EffectBase
|
||||||
{
|
{
|
||||||
AuraEffectApplicationModeDelegate _callImpl;
|
AuraEffectApplicationModeDelegate _callImpl;
|
||||||
@@ -1601,6 +1614,11 @@ namespace Game.Scripting
|
|||||||
// where function is: void function (DispelInfo dispelInfo);
|
// where function is: void function (DispelInfo dispelInfo);
|
||||||
public List<AuraDispelHandler> AfterDispel = new();
|
public List<AuraDispelHandler> AfterDispel = new();
|
||||||
|
|
||||||
|
// executed on every heartbeat of a unit
|
||||||
|
// example: OnHeartbeat += AuraHeartbeatFn(class::function);
|
||||||
|
// where function is: void function ();
|
||||||
|
public List<AuraHeartbeatHandler> OnHeartbeat = new();
|
||||||
|
|
||||||
// executed when aura effect is applied with specified mode to target
|
// executed when aura effect is applied with specified mode to target
|
||||||
// should be used when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe
|
// should be used when effect handler preventing/replacing is needed, do not use this hook for triggering spellcasts/removing auras etc - may be unsafe
|
||||||
// example: OnEffectApply += AuraEffectApplyFn(class.function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
|
// example: OnEffectApply += AuraEffectApplyFn(class.function, EffectIndexSpecifier, EffectAuraNameSpecifier, AuraEffectHandleModes);
|
||||||
|
|||||||
@@ -1986,6 +1986,18 @@ namespace Game.Spells
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void CallScriptOnHeartbeat()
|
||||||
|
{
|
||||||
|
foreach (var script in m_loadedScripts)
|
||||||
|
{
|
||||||
|
script._PrepareScriptCall(AuraScriptHookType.OnHeartbeat);
|
||||||
|
foreach (var onHeartbeat in script.OnHeartbeat)
|
||||||
|
onHeartbeat.Call(script);
|
||||||
|
|
||||||
|
script._FinishScriptCall();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public bool CallScriptEffectApplyHandlers(AuraEffect aurEff, AuraApplication aurApp, AuraEffectHandleModes mode)
|
public bool CallScriptEffectApplyHandlers(AuraEffect aurEff, AuraApplication aurApp, AuraEffectHandleModes mode)
|
||||||
{
|
{
|
||||||
bool preventDefault = false;
|
bool preventDefault = false;
|
||||||
@@ -2865,12 +2877,15 @@ namespace Game.Spells
|
|||||||
_staticApplications[target.GetGUID()] |= effMask;
|
_staticApplications[target.GetGUID()] |= effMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Heartbeat()
|
public override void Heartbeat()
|
||||||
{
|
{
|
||||||
base.Heartbeat();
|
base.Heartbeat();
|
||||||
|
|
||||||
// Periodic food and drink emote animation
|
// Periodic food and drink emote animation
|
||||||
HandlePeriodicFoodSpellVisualKit();
|
HandlePeriodicFoodSpellVisualKit();
|
||||||
|
|
||||||
|
// Invoke the OnHeartbeat AuraScript hook
|
||||||
|
CallScriptOnHeartbeat();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandlePeriodicFoodSpellVisualKit()
|
void HandlePeriodicFoodSpellVisualKit()
|
||||||
|
|||||||
@@ -3883,17 +3883,9 @@ namespace Scripts.Spells.Azerite
|
|||||||
return ValidateSpellInfo(SpellFragileEchoesMonk, SpellFragileEchoesShaman, SpellFragileEchoesPriestDiscipline, SpellFragileEchoesPaladin, SpellFragileEchoesDruid, SpellFragileEchoesPriestHoly);
|
return ValidateSpellInfo(SpellFragileEchoesMonk, SpellFragileEchoesShaman, SpellFragileEchoesPriestDiscipline, SpellFragileEchoesPaladin, SpellFragileEchoesDruid, SpellFragileEchoesPriestHoly);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForcePeriodic(AuraEffect aurEff, ref bool isPeriodic, ref int amplitude)
|
void UpdateSpecAura()
|
||||||
{
|
{
|
||||||
// simulate heartbeat timer
|
Player target = GetUnitOwner().ToPlayer();
|
||||||
isPeriodic = true;
|
|
||||||
amplitude = 5000;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateSpecAura(AuraEffect aurEff)
|
|
||||||
{
|
|
||||||
PreventDefaultAction();
|
|
||||||
Player target = GetTarget().ToPlayer();
|
|
||||||
if (target == null)
|
if (target == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -3902,7 +3894,7 @@ namespace Scripts.Spells.Azerite
|
|||||||
if (target.GetPrimarySpecialization() != spec)
|
if (target.GetPrimarySpecialization() != spec)
|
||||||
target.RemoveAurasDueToSpell(aura);
|
target.RemoveAurasDueToSpell(aura);
|
||||||
else if (!target.HasAura(aura))
|
else if (!target.HasAura(aura))
|
||||||
target.CastSpell(target, aura, aurEff);
|
target.CastSpell(target, aura, GetEffect(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (target.GetClass())
|
switch (target.GetClass())
|
||||||
@@ -3930,8 +3922,7 @@ namespace Scripts.Spells.Azerite
|
|||||||
|
|
||||||
public override void Register()
|
public override void Register()
|
||||||
{
|
{
|
||||||
DoEffectCalcPeriodic.Add(new(ForcePeriodic, 0, AuraType.Dummy));
|
OnHeartbeat.Add(new(UpdateSpecAura));
|
||||||
OnEffectPeriodic.Add(new(UpdateSpecAura, 0, AuraType.Dummy));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user