From 5369aec3c9df2e2888d3312f5e087b43e6614abf Mon Sep 17 00:00:00 2001 From: Andrew <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 12 Aug 2025 14:31:08 -0300 Subject: [PATCH] =?UTF-8?q?fix(Core/SAI):=20=20Force=20SMC=20creatures=20t?= =?UTF-8?q?o=20resume=20chasing=20victims=20once=20in=E2=80=A6=20(#22581)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/game/AI/SmartScripts/SmartAI.cpp | 2 ++ src/server/game/AI/SmartScripts/SmartAI.h | 5 +++++ src/server/game/AI/SmartScripts/SmartScript.cpp | 2 ++ src/server/game/Entities/Unit/Unit.cpp | 14 ++++++++++++-- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index d48cf2681..4c2b252e2 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -72,6 +72,8 @@ SmartAI::SmartAI(Creature* c) : CreatureAI(c) mcanSpawn = true; + _chaseOnInterrupt = false; + // Xinef: Vehicle conditions m_ConditionsTimer = 0; if (me->GetVehicleKit()) diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index ede658a47..1cc940df4 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -212,6 +212,9 @@ public: // Xinef void SetWPPauseTimer(uint32 time) { mWPPauseTimer = time; } + void SetChaseOnInterrupt(bool apply) { _chaseOnInterrupt = apply; } + [[nodiscard]] bool CanChaseOnInterrupt() const { return _chaseOnInterrupt; } + private: bool mIsCharmed; uint32 mFollowCreditType; @@ -257,6 +260,8 @@ private: void CheckConditions(const uint32 diff); ConditionList conditions; uint32 m_ConditionsTimer; + + bool _chaseOnInterrupt; }; class SmartGameObjectAI : public GameObjectAI diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 24a3d6901..2cc4a246b 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -742,6 +742,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (e.action.cast.castFlags & SMARTCAST_COMBAT_MOVE) { + CAST_AI(SmartAI, me->AI())->SetChaseOnInterrupt(true); + if (!me->isMoving()) // Don't try to reposition while we are moving { // If cast flag SMARTCAST_COMBAT_MOVE is set combat movement will not be allowed unless target is outside spell range, out of mana, or LOS. diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f65cdbd97..a2a33e89d 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -53,6 +53,7 @@ #include "Player.h" #include "ReputationMgr.h" #include "ScriptMgr.h" +#include "SmartAI.h" #include "Spell.h" #include "SpellAuraEffects.h" #include "SpellAuras.h" @@ -4109,8 +4110,8 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi //LOG_DEBUG("entities.unit", "Interrupt spell for unit {}.", GetEntry()); Spell* spell = m_currentSpells[spellType]; if (spell - && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) - && (withInstant || spell->GetCastTime() > 0 || spell->getState() == SPELL_STATE_CASTING)) // xinef: or spell is in casting state (channeled spells only) + && (withDelayed || spell->getState() != SPELL_STATE_DELAYED) + && (withInstant || spell->GetCastTime() > 0 || spell->getState() == SPELL_STATE_CASTING)) // xinef: or spell is in casting state (channeled spells only) { // for example, do not let self-stun aura interrupt itself if (!spell->IsInterruptable()) @@ -4128,6 +4129,15 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi m_currentSpells[spellType] = nullptr; spell->SetReferencedFromCurrent(false); } + + // SAI creatures only + // Start chasing victim if they are spell casters (at least one SMC spell) if interrupted/silenced. + if (IsCreature()) + { + if (SmartAI* ai = dynamic_cast(ToCreature()->AI())) + if (ai->CanChaseOnInterrupt()) + ai->SetCombatMove(true); + } } }