Core/AI: OnSpellCast, OnSpellFailed, OnSpellStart hooks

Port From (https://github.com/TrinityCore/TrinityCore/commit/050f55b62fded4cc73b76e42d56d98ea950cc26a)
This commit is contained in:
hondacrx
2022-05-30 15:44:21 -04:00
parent 5575703997
commit 306b0cb227
8 changed files with 80 additions and 14 deletions
+4 -1
View File
@@ -237,8 +237,11 @@ namespace Framework.Constants
SceneCancel = 80, // none
SceneComplete = 81, // none
SummonedUnitDies = 82, // CreatureId(0 all), CooldownMin, CooldownMax
OnSpellCast = 83, // SpellID, CooldownMin, CooldownMax
OnSpellFailed = 84, // SpellID, CooldownMin, CooldownMax
OnSpellStart = 85, // SpellID, CooldownMin, CooldownMax
End = 83
End = 86
}
public enum SmartActions
@@ -98,13 +98,6 @@ namespace Framework.Constants
Ranged = 2 //hunter range and ranged weapon
}
public enum SpellFinishReason
{
SuccessfulCast = 0, // spell has sucessfully launched
Canceled = 1, // spell has been canceled (interrupts)
ChannelingComplete = 2 // spell channeling has been finished
}
[Flags]
public enum SpellInterruptFlags
{
+11 -2
View File
@@ -491,8 +491,17 @@ namespace Game.AI
// Called when spell hits a target
public virtual void SpellHitTarget(WorldObject target, SpellInfo spellInfo) { }
// Called when a spell either finishes, interrupts or cancels a spell cast
public virtual void OnSpellCastFinished(SpellInfo spell, SpellFinishReason reason) { }
// Called when a spell finishes
public virtual void OnSpellCast(SpellInfo spell) { }
// Called when a spell fails
public virtual void OnSpellFailed(SpellInfo spell) { }
// Called when a spell starts
public virtual void OnSpellStart(SpellInfo spell) { }
// Called when a channeled spell finishes
public virtual void OnChannelFinished(SpellInfo spell) { }
// Should return true if the NPC is currently being escorted
public virtual bool IsEscorted() { return false; }
+15
View File
@@ -670,6 +670,21 @@ namespace Game.AI
{
GetScript().ProcessEventsFor(SmartEvents.SpellHitTarget, target.ToUnit(), 0, 0, false, spellInfo, target.ToGameObject());
}
public override void OnSpellCast(SpellInfo spellInfo)
{
GetScript().ProcessEventsFor(SmartEvents.OnSpellCast, null, 0, 0, false, spellInfo);
}
public override void OnSpellFailed(SpellInfo spellInfo)
{
GetScript().ProcessEventsFor(SmartEvents.OnSpellFailed, null, 0, 0, false, spellInfo);
}
public override void OnSpellStart(SpellInfo spellInfo)
{
GetScript().ProcessEventsFor(SmartEvents.OnSpellStart, null, 0, 0, false, spellInfo);
}
public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null)
{
@@ -629,6 +629,9 @@ namespace Game.AI
SmartEvents.SceneCancel => 0,
SmartEvents.SceneComplete => 0,
SmartEvents.SummonedUnitDies => Marshal.SizeOf(typeof(SmartEvent.Summoned)),
SmartEvents.OnSpellCast => Marshal.SizeOf(typeof(SmartEvent.SpellCast)),
SmartEvents.OnSpellFailed => Marshal.SizeOf(typeof(SmartEvent.SpellCast)),
SmartEvents.OnSpellStart => Marshal.SizeOf(typeof(SmartEvent.SpellCast)),
_ => Marshal.SizeOf(typeof(SmartEvent.Raw)),
};
@@ -987,6 +990,17 @@ namespace Game.AI
if (!IsMinMaxValid(e, e.Event.spellHit.cooldownMin, e.Event.spellHit.cooldownMax))
return false;
break;
case SmartEvents.OnSpellCast:
case SmartEvents.OnSpellFailed:
case SmartEvents.OnSpellStart:
{
if (!IsSpellValid(e, e.Event.spellCast.spell))
return false;
if (!IsMinMaxValid(e, e.Event.spellCast.cooldownMin, e.Event.spellCast.cooldownMax))
return false;
break;
}
case SmartEvents.OocLos:
case SmartEvents.IcLos:
if (!IsMinMaxValid(e, e.Event.los.cooldownMin, e.Event.los.cooldownMax))
@@ -2406,6 +2420,9 @@ namespace Game.AI
SmartEvents.SceneCancel => SmartScriptTypeMaskId.Scene,
SmartEvents.SceneComplete => SmartScriptTypeMaskId.Scene,
SmartEvents.SummonedUnitDies => SmartScriptTypeMaskId.Creature + SmartScriptTypeMaskId.Gameobject,
SmartEvents.OnSpellCast => SmartScriptTypeMaskId.Creature,
SmartEvents.OnSpellFailed => SmartScriptTypeMaskId.Creature,
SmartEvents.OnSpellStart => SmartScriptTypeMaskId.Creature,
_ => 0,
};
@@ -2589,6 +2606,9 @@ namespace Game.AI
[FieldOffset(16)]
public Counter counter;
[FieldOffset(16)]
public SpellCast spellCast;
[FieldOffset(16)]
public Spell spell;
@@ -2782,6 +2802,12 @@ namespace Game.AI
public uint cooldownMin;
public uint cooldownMax;
}
public struct SpellCast
{
public uint spell;
public uint cooldownMin;
public uint cooldownMax;
}
public struct Spell
{
public uint effIndex;
@@ -3226,6 +3226,20 @@ namespace Game.AI
}
break;
}
case SmartEvents.OnSpellCast:
case SmartEvents.OnSpellFailed:
case SmartEvents.OnSpellStart:
{
if (spell == null)
return;
if (spell.Id != e.Event.spellCast.spell)
return;
RecalcTimer(e, e.Event.spellCast.cooldownMin, e.Event.spellCast.cooldownMax);
ProcessAction(e, null, 0, 0, bvar, spell);
break;
}
case SmartEvents.OocLos:
{
if (_me == null || _me.IsEngaged())
+1 -1
View File
@@ -2422,7 +2422,7 @@ namespace Game.Entities
}
if (IsCreature() && IsAIEnabled())
ToCreature().GetAI().OnSpellCastFinished(spell.GetSpellInfo(), SpellFinishReason.Canceled);
ToCreature().GetAI().OnSpellFailed(spell.GetSpellInfo());
}
}
public void UpdateInterruptMask()
+9 -3
View File
@@ -2502,6 +2502,12 @@ namespace Game.Spells
if (!_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.IgnoreGCD))
TriggerGlobalCooldown();
// Call CreatureAI hook OnSpellStart
Creature caster = m_originalCaster.ToCreature();
if (caster != null)
if (caster.IsAIEnabled())
caster.GetAI().OnSpellStart(GetSpellInfo());
if (willCastDirectly)
Cast(true);
}
@@ -2902,11 +2908,11 @@ namespace Game.Spells
Unit.ProcSkillsAndAuras(m_originalCaster, null, procAttacker, new ProcFlagsInit(ProcFlags.None), ProcFlagsSpellType.MaskAll, ProcFlagsSpellPhase.Cast, hitMask, this, null, null);
// Call CreatureAI hook OnSuccessfulSpellCast
// Call CreatureAI hook OnSpellCast
Creature caster = m_originalCaster.ToCreature();
if (caster)
if (caster.IsAIEnabled())
caster.GetAI().OnSpellCastFinished(GetSpellInfo(), SpellFinishReason.SuccessfulCast);
caster.GetAI().OnSpellCast(GetSpellInfo());
}
void DoProcessTargetContainer<T>(List<T> targetContainer) where T : TargetInfoBase
@@ -3268,7 +3274,7 @@ namespace Game.Spells
Creature creatureCaster = m_caster.ToCreature();
if (creatureCaster != null)
if (creatureCaster.IsAIEnabled())
creatureCaster.GetAI().OnSpellCastFinished(m_spellInfo, SpellFinishReason.ChannelingComplete);
creatureCaster.GetAI().OnChannelFinished(m_spellInfo);
}
break;
}