aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
authorMeji <alvaro.megias@outlook.com>2025-09-22 21:56:04 +0200
committerGitHub <noreply@github.com>2025-09-22 21:56:04 +0200
commit1085b3f43321e58f151c1543a70b3558c26ed8e5 (patch)
tree621f525f17904bd95a0018eca9310c0c63aaf897 /src/server/game
parentdf02bec2a1871267548494bc473711a0f9de9b43 (diff)
Core/AreaTriggers: Implement AreaTriggerActionSetFlag::DontRunOnLeaveWhenExpiring (#31276)
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/AI/CoreAI/AreaTriggerAI.h3
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp2
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h3
-rw-r--r--src/server/game/DataStores/DBCEnums.h2
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.cpp23
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.h10
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);