diff options
author | Andrew <47818697+Nyeriah@users.noreply.github.com> | 2025-09-19 04:52:22 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-19 04:52:22 -0300 |
commit | b09609e47d0dbe359d028ab59d49377e9e71b255 (patch) | |
tree | 39649f367fbc715698e7f848e5bd4c3a60e15078 /src | |
parent | d58d8692b11dee6d8b98ddf4ddc700355bbb8c28 (diff) |
feat(Core/Spells): Implement OnSpellCastFinished hook (#22941)
Co-authored-by: Ovahlord <dreadkiller@gmx.de>
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/AI/CreatureAI.h | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 7 |
4 files changed, 24 insertions, 0 deletions
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 4672a87918..5374858a4d 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -29,6 +29,7 @@ class Unit; class Creature; class Player; class SpellInfo; +enum SpellFinishReason : uint8; typedef std::vector<AreaBoundary const*> CreatureBoundary; @@ -146,6 +147,9 @@ public: // Called when spell hits a target virtual void SpellHitTarget(Unit* /*target*/, SpellInfo const* /*spell*/) {} + // Called when a spell either finishes, interrupts or cancels a spell cast + virtual void OnSpellCastFinished(SpellInfo const* /*spell*/, SpellFinishReason /*reason*/) {} + // Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc) virtual void AttackedBy(Unit* /*attacker*/) {} virtual bool IsEscorted() { return false; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b5667566e1..fc48264958 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -4138,6 +4138,9 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi if (ai->CanChaseOnInterrupt()) ai->SetCombatMove(true); } + + if (IsCreature() && IsAIEnabled) + ToCreature()->AI()->OnSpellCastFinished(spell->GetSpellInfo(), SPELL_FINISHED_CANCELED); } } diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 9ad08dd7b3..425189d1bf 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -4112,6 +4112,11 @@ void Spell::_cast(bool skipCheck) sScriptMgr->OnSpellCast(this, m_caster, m_spellInfo, skipCheck); SetExecutedCurrently(false); + + // Call CreatureAI hook OnSpellCastFinished + if (Creature* caster = m_originalCaster->ToCreature()) + if (caster->IsAIEnabled) + caster->AI()->OnSpellCastFinished(GetSpellInfo(), SPELL_FINISHED_SUCCESSFUL_CAST); } void Spell::handle_immediate() @@ -4463,6 +4468,11 @@ void Spell::update(uint32 difftime) SendChannelUpdate(0); finish(); + + // We call the hook here instead of in Spell::finish because we only want to call it for completed channeling. Everything else is handled by interrupts + if (Creature* creatureCaster = m_caster->ToCreature()) + if (creatureCaster->IsAIEnabled) + creatureCaster->AI()->OnSpellCastFinished(m_spellInfo, SPELL_FINISHED_CHANNELING_COMPLETE); } // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly // Xinef: Added this strange check because of diffrent update routines for players / creatures diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index d5e9f26c8d..bb8f2cb7bb 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -92,6 +92,13 @@ enum SpellRangeFlag SPELL_RANGE_RANGED = 2, //hunter range and ranged weapon }; +enum SpellFinishReason : uint8 +{ + SPELL_FINISHED_SUCCESSFUL_CAST = 0, // spell has sucessfully launched + SPELL_FINISHED_CANCELED = 1, // spell has been canceled (interrupts) + SPELL_FINISHED_CHANNELING_COMPLETE = 2 // spell channeling has been finished +}; + struct SpellDestination { SpellDestination(); |