Core/AI: OnSpellCast, OnSpellFailed, OnSpellStart hooks
Port From (https://github.com/TrinityCore/TrinityCore/commit/050f55b62fded4cc73b76e42d56d98ea950cc26a)
This commit is contained in:
@@ -237,8 +237,11 @@ namespace Framework.Constants
|
|||||||
SceneCancel = 80, // none
|
SceneCancel = 80, // none
|
||||||
SceneComplete = 81, // none
|
SceneComplete = 81, // none
|
||||||
SummonedUnitDies = 82, // CreatureId(0 all), CooldownMin, CooldownMax
|
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
|
public enum SmartActions
|
||||||
|
|||||||
@@ -98,13 +98,6 @@ namespace Framework.Constants
|
|||||||
Ranged = 2 //hunter range and ranged weapon
|
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]
|
[Flags]
|
||||||
public enum SpellInterruptFlags
|
public enum SpellInterruptFlags
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -491,8 +491,17 @@ namespace Game.AI
|
|||||||
// Called when spell hits a target
|
// Called when spell hits a target
|
||||||
public virtual void SpellHitTarget(WorldObject target, SpellInfo spellInfo) { }
|
public virtual void SpellHitTarget(WorldObject target, SpellInfo spellInfo) { }
|
||||||
|
|
||||||
// Called when a spell either finishes, interrupts or cancels a spell cast
|
// Called when a spell finishes
|
||||||
public virtual void OnSpellCastFinished(SpellInfo spell, SpellFinishReason reason) { }
|
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
|
// Should return true if the NPC is currently being escorted
|
||||||
public virtual bool IsEscorted() { return false; }
|
public virtual bool IsEscorted() { return false; }
|
||||||
|
|||||||
@@ -671,6 +671,21 @@ namespace Game.AI
|
|||||||
GetScript().ProcessEventsFor(SmartEvents.SpellHitTarget, target.ToUnit(), 0, 0, false, spellInfo, target.ToGameObject());
|
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)
|
public override void DamageTaken(Unit attacker, ref uint damage, DamageEffectType damageType, SpellInfo spellInfo = null)
|
||||||
{
|
{
|
||||||
GetScript().ProcessEventsFor(SmartEvents.Damaged, attacker, damage);
|
GetScript().ProcessEventsFor(SmartEvents.Damaged, attacker, damage);
|
||||||
|
|||||||
@@ -629,6 +629,9 @@ namespace Game.AI
|
|||||||
SmartEvents.SceneCancel => 0,
|
SmartEvents.SceneCancel => 0,
|
||||||
SmartEvents.SceneComplete => 0,
|
SmartEvents.SceneComplete => 0,
|
||||||
SmartEvents.SummonedUnitDies => Marshal.SizeOf(typeof(SmartEvent.Summoned)),
|
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)),
|
_ => Marshal.SizeOf(typeof(SmartEvent.Raw)),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -987,6 +990,17 @@ namespace Game.AI
|
|||||||
if (!IsMinMaxValid(e, e.Event.spellHit.cooldownMin, e.Event.spellHit.cooldownMax))
|
if (!IsMinMaxValid(e, e.Event.spellHit.cooldownMin, e.Event.spellHit.cooldownMax))
|
||||||
return false;
|
return false;
|
||||||
break;
|
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.OocLos:
|
||||||
case SmartEvents.IcLos:
|
case SmartEvents.IcLos:
|
||||||
if (!IsMinMaxValid(e, e.Event.los.cooldownMin, e.Event.los.cooldownMax))
|
if (!IsMinMaxValid(e, e.Event.los.cooldownMin, e.Event.los.cooldownMax))
|
||||||
@@ -2406,6 +2420,9 @@ namespace Game.AI
|
|||||||
SmartEvents.SceneCancel => SmartScriptTypeMaskId.Scene,
|
SmartEvents.SceneCancel => SmartScriptTypeMaskId.Scene,
|
||||||
SmartEvents.SceneComplete => SmartScriptTypeMaskId.Scene,
|
SmartEvents.SceneComplete => SmartScriptTypeMaskId.Scene,
|
||||||
SmartEvents.SummonedUnitDies => SmartScriptTypeMaskId.Creature + SmartScriptTypeMaskId.Gameobject,
|
SmartEvents.SummonedUnitDies => SmartScriptTypeMaskId.Creature + SmartScriptTypeMaskId.Gameobject,
|
||||||
|
SmartEvents.OnSpellCast => SmartScriptTypeMaskId.Creature,
|
||||||
|
SmartEvents.OnSpellFailed => SmartScriptTypeMaskId.Creature,
|
||||||
|
SmartEvents.OnSpellStart => SmartScriptTypeMaskId.Creature,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2589,6 +2606,9 @@ namespace Game.AI
|
|||||||
[FieldOffset(16)]
|
[FieldOffset(16)]
|
||||||
public Counter counter;
|
public Counter counter;
|
||||||
|
|
||||||
|
[FieldOffset(16)]
|
||||||
|
public SpellCast spellCast;
|
||||||
|
|
||||||
[FieldOffset(16)]
|
[FieldOffset(16)]
|
||||||
public Spell spell;
|
public Spell spell;
|
||||||
|
|
||||||
@@ -2782,6 +2802,12 @@ namespace Game.AI
|
|||||||
public uint cooldownMin;
|
public uint cooldownMin;
|
||||||
public uint cooldownMax;
|
public uint cooldownMax;
|
||||||
}
|
}
|
||||||
|
public struct SpellCast
|
||||||
|
{
|
||||||
|
public uint spell;
|
||||||
|
public uint cooldownMin;
|
||||||
|
public uint cooldownMax;
|
||||||
|
}
|
||||||
public struct Spell
|
public struct Spell
|
||||||
{
|
{
|
||||||
public uint effIndex;
|
public uint effIndex;
|
||||||
|
|||||||
@@ -3226,6 +3226,20 @@ namespace Game.AI
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
case SmartEvents.OocLos:
|
||||||
{
|
{
|
||||||
if (_me == null || _me.IsEngaged())
|
if (_me == null || _me.IsEngaged())
|
||||||
|
|||||||
@@ -2422,7 +2422,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (IsCreature() && IsAIEnabled())
|
if (IsCreature() && IsAIEnabled())
|
||||||
ToCreature().GetAI().OnSpellCastFinished(spell.GetSpellInfo(), SpellFinishReason.Canceled);
|
ToCreature().GetAI().OnSpellFailed(spell.GetSpellInfo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public void UpdateInterruptMask()
|
public void UpdateInterruptMask()
|
||||||
|
|||||||
@@ -2502,6 +2502,12 @@ namespace Game.Spells
|
|||||||
if (!_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.IgnoreGCD))
|
if (!_triggeredCastFlags.HasAnyFlag(TriggerCastFlags.IgnoreGCD))
|
||||||
TriggerGlobalCooldown();
|
TriggerGlobalCooldown();
|
||||||
|
|
||||||
|
// Call CreatureAI hook OnSpellStart
|
||||||
|
Creature caster = m_originalCaster.ToCreature();
|
||||||
|
if (caster != null)
|
||||||
|
if (caster.IsAIEnabled())
|
||||||
|
caster.GetAI().OnSpellStart(GetSpellInfo());
|
||||||
|
|
||||||
if (willCastDirectly)
|
if (willCastDirectly)
|
||||||
Cast(true);
|
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);
|
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();
|
Creature caster = m_originalCaster.ToCreature();
|
||||||
if (caster)
|
if (caster)
|
||||||
if (caster.IsAIEnabled())
|
if (caster.IsAIEnabled())
|
||||||
caster.GetAI().OnSpellCastFinished(GetSpellInfo(), SpellFinishReason.SuccessfulCast);
|
caster.GetAI().OnSpellCast(GetSpellInfo());
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoProcessTargetContainer<T>(List<T> targetContainer) where T : TargetInfoBase
|
void DoProcessTargetContainer<T>(List<T> targetContainer) where T : TargetInfoBase
|
||||||
@@ -3268,7 +3274,7 @@ namespace Game.Spells
|
|||||||
Creature creatureCaster = m_caster.ToCreature();
|
Creature creatureCaster = m_caster.ToCreature();
|
||||||
if (creatureCaster != null)
|
if (creatureCaster != null)
|
||||||
if (creatureCaster.IsAIEnabled())
|
if (creatureCaster.IsAIEnabled())
|
||||||
creatureCaster.GetAI().OnSpellCastFinished(m_spellInfo, SpellFinishReason.ChannelingComplete);
|
creatureCaster.GetAI().OnChannelFinished(m_spellInfo);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user