diff options
author | Meji <alvaro.megias@outlook.com> | 2025-09-22 21:56:04 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-09-22 21:56:04 +0200 |
commit | 1085b3f43321e58f151c1543a70b3558c26ed8e5 (patch) | |
tree | 621f525f17904bd95a0018eca9310c0c63aaf897 /src/server/game | |
parent | df02bec2a1871267548494bc473711a0f9de9b43 (diff) |
Core/AreaTriggers: Implement AreaTriggerActionSetFlag::DontRunOnLeaveWhenExpiring (#31276)
Diffstat (limited to 'src/server/game')
-rw-r--r-- | src/server/game/AI/CoreAI/AreaTriggerAI.h | 3 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.cpp | 2 | ||||
-rw-r--r-- | src/server/game/AI/SmartScripts/SmartAI.h | 3 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.cpp | 23 | ||||
-rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.h | 10 |
6 files changed, 29 insertions, 14 deletions
diff --git a/src/server/game/AI/CoreAI/AreaTriggerAI.h b/src/server/game/AI/CoreAI/AreaTriggerAI.h index d912c92f9c9..238f6cd1618 100644 --- a/src/server/game/AI/CoreAI/AreaTriggerAI.h +++ b/src/server/game/AI/CoreAI/AreaTriggerAI.h @@ -24,6 +24,7 @@ class AreaTrigger; class Spell; class Unit; +enum class AreaTriggerExitReason : uint8; class TC_GAME_API AreaTriggerAI { @@ -58,7 +59,7 @@ class TC_GAME_API AreaTriggerAI virtual void OnUnitEnter([[maybe_unused]] Unit* unit) { } // Called when an unit exit the AreaTrigger, or when the AreaTrigger is removed - virtual void OnUnitExit([[maybe_unused]] Unit* unit) { } + virtual void OnUnitExit([[maybe_unused]] Unit* unit, [[maybe_unused]] AreaTriggerExitReason reason) { } // Called when the AreaTrigger is removed virtual void OnRemove() { } diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index ca10757769b..cdc2530617c 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -1135,7 +1135,7 @@ void SmartAreaTriggerAI::OnUnitEnter(Unit* unit) GetScript()->ProcessEventsFor(SMART_EVENT_AREATRIGGER_ENTER, unit); } -void SmartAreaTriggerAI::OnUnitExit(Unit* unit) +void SmartAreaTriggerAI::OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) { GetScript()->ProcessEventsFor(SMART_EVENT_AREATRIGGER_EXIT, unit); } diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 02e9b73bb76..0d1054796d2 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -25,6 +25,7 @@ #include "SmartScript.h" #include "WaypointDefines.h" +enum class AreaTriggerExitReason : uint8; enum class MovementStopReason : uint8; enum SmartEscortState : uint8 @@ -341,7 +342,7 @@ public: void OnInitialize() override; void OnUpdate(uint32 diff) override; void OnUnitEnter(Unit* unit) override; - void OnUnitExit(Unit* unit) override; + void OnUnitExit(Unit* unit, AreaTriggerExitReason reason) override; SmartScript* GetScript() { return &mScript; } void SetTimedActionList(SmartScriptHolder& e, uint32 entry, Unit* invoker); diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index 7c96b94ffee..6e2c3806d8a 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -189,7 +189,7 @@ enum class AreaTriggerActionSetFlag : uint32 SuppressConditionError = 0x0040, // NYI NotTriggeredbyCaster = 0x0080, CreatorsPartyOnly = 0x0100, - DontRunOnLeaveWhenExpiring = 0x0200, /*NYI*/ + DontRunOnLeaveWhenExpiring = 0x0200, CanAffectUninteractible = 0x0400, DontDespawnWithCreator = 0x0800, CanAffectBeastmaster = 0x1000, // Can affect GMs diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index d3ff2686e05..829aa4d4816 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -96,7 +96,7 @@ void AreaTrigger::RemoveFromWorld() _ai->OnRemove(); // Handle removal of all units, calling OnUnitExit & deleting auras if needed - HandleUnitEnterExit({}); + HandleUnitEnterExit({}, AreaTriggerExitReason::ByExpire); WorldObject::RemoveFromWorld(); @@ -850,7 +850,7 @@ void AreaTrigger::SearchUnitInBoundedPlane(UF::AreaTriggerBoundedPlane const& bo }); } -void AreaTrigger::HandleUnitEnterExit(std::vector<Unit*> const& newTargetList) +void AreaTrigger::HandleUnitEnterExit(std::vector<Unit*> const& newTargetList, AreaTriggerExitReason exitMode) { GuidUnorderedSet exitUnits(std::move(_insideUnits)); @@ -870,7 +870,7 @@ void AreaTrigger::HandleUnitEnterExit(std::vector<Unit*> const& newTargetList) for (ObjectGuid const& exitUnitGuid : exitUnits) if (Unit* leavingUnit = ObjectAccessor::GetUnit(*this, exitUnitGuid)) - HandleUnitExitInternal(leavingUnit); + HandleUnitExitInternal(leavingUnit, exitMode); UpdateHasPlayersFlag(); @@ -897,22 +897,29 @@ void AreaTrigger::HandleUnitEnter(Unit* unit) unit->EnterAreaTrigger(this); } -void AreaTrigger::HandleUnitExitInternal(Unit* unit) +void AreaTrigger::HandleUnitExitInternal(Unit* unit, AreaTriggerExitReason exitMode) { + bool canTriggerOnExit = exitMode != AreaTriggerExitReason::ByExpire || !HasActionSetFlag(AreaTriggerActionSetFlag::DontRunOnLeaveWhenExpiring); + if (Player* player = unit->ToPlayer()) { if (player->isDebugAreaTriggers) ChatHandler(player->GetSession()).PSendSysMessage(LANG_DEBUG_AREATRIGGER_ENTITY_LEFT, GetEntry(), IsCustom(), IsStaticSpawn(), _spawnId); - player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_AREA_TRIGGER_EXIT, GetEntry(), 1); + if (canTriggerOnExit) + { + player->UpdateQuestObjectiveProgress(QUEST_OBJECTIVE_AREA_TRIGGER_EXIT, GetEntry(), 1); - if (GetTemplate()->ActionSetId) - player->UpdateCriteria(CriteriaType::LeaveAreaTriggerWithActionSet, GetTemplate()->ActionSetId); + if (GetTemplate()->ActionSetId) + player->UpdateCriteria(CriteriaType::LeaveAreaTriggerWithActionSet, GetTemplate()->ActionSetId); + } } UndoActions(unit); - _ai->OnUnitExit(unit); + if (canTriggerOnExit) + _ai->OnUnitExit(unit, exitMode); + unit->ExitAreaTrigger(this); } diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.h b/src/server/game/Entities/AreaTrigger/AreaTrigger.h index 4ab68286d1b..b4638b57c10 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.h +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.h @@ -65,6 +65,12 @@ enum class AreaTriggerPathType : int32 MovementScript = 3 }; +enum class AreaTriggerExitReason : uint8 +{ + NotInside = 0, // Unit leave areatrigger + ByExpire = 1 // On areatrigger despawn +}; + class TC_GAME_API AreaTrigger final : public WorldObject, public GridObject<AreaTrigger>, public MapObject { public: @@ -228,9 +234,9 @@ class TC_GAME_API AreaTrigger final : public WorldObject, public GridObject<Area void SearchUnitInCylinder(UF::AreaTriggerCylinder const& cylinder, std::vector<Unit*>& targetList); void SearchUnitInDisk(UF::AreaTriggerDisk const& disk, std::vector<Unit*>& targetList); void SearchUnitInBoundedPlane(UF::AreaTriggerBoundedPlane const& boundedPlane, std::vector<Unit*>& targetList); - void HandleUnitEnterExit(std::vector<Unit*> const& targetList); + void HandleUnitEnterExit(std::vector<Unit*> const& targetList, AreaTriggerExitReason exitMode = AreaTriggerExitReason::NotInside); void HandleUnitEnter(Unit* unit); - void HandleUnitExitInternal(Unit* unit); + void HandleUnitExitInternal(Unit* unit, AreaTriggerExitReason exitMode = AreaTriggerExitReason::NotInside); void DoActions(Unit* unit); void UndoActions(Unit* unit); |