diff --git a/src/common/Utilities/EventProcessor.h b/src/common/Utilities/EventProcessor.h index f114e0f83..a7f35ce86 100644 --- a/src/common/Utilities/EventProcessor.h +++ b/src/common/Utilities/EventProcessor.h @@ -120,7 +120,7 @@ class EventProcessor [[nodiscard]] uint64 CalculateQueueTime(uint64 delay) const; void CancelEventGroup(uint8 group); - bool HaveEventList() const { return !m_events.empty(); } + bool HasEvents() const { return !m_events.empty(); } protected: uint64 m_time{0}; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index f8602bf58..711ec011b 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -54,6 +54,10 @@ Map::~Map() { // UnloadAll must be called before deleting the map + // Kill all scheduled events without executing them, since the map and its objects are being destroyed. + // This prevents events from running on invalid or deleted objects during map destruction. + Events.KillAllEvents(false); + sScriptMgr->OnDestroyMap(this); if (!m_scriptSchedule.empty()) @@ -447,7 +451,7 @@ void Map::Update(const uint32 t_diff, const uint32 s_diff, bool /*thread*/) } } - _creatureRespawnScheduler.Update(t_diff); + Events.Update(t_diff); if (!t_diff) { @@ -2747,13 +2751,13 @@ void Map::RemoveOldCorpses() void Map::ScheduleCreatureRespawn(ObjectGuid creatureGuid, Milliseconds respawnTimer, Position pos) { - _creatureRespawnScheduler.Schedule(respawnTimer, [this, creatureGuid, pos](TaskContext) + Events.AddEventAtOffset([this, creatureGuid, pos]() { if (Creature* creature = GetCreature(creatureGuid)) creature->Respawn(); else SummonCreature(creatureGuid.GetEntry(), pos); - }); + }, respawnTimer); } /// Send a packet to all players (or players selected team) in the zone (except self if mentioned) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 65c40c5e3..432aff51d 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -23,6 +23,7 @@ #include "DataMap.h" #include "Define.h" #include "DynamicTree.h" +#include "EventProcessor.h" #include "GameObjectModel.h" #include "GridDefines.h" #include "GridRefMgr.h" @@ -33,7 +34,6 @@ #include "PathGenerator.h" #include "Position.h" #include "SharedDefines.h" -#include "TaskScheduler.h" #include "Timer.h" #include "GridTerrainData.h" #include @@ -172,7 +172,7 @@ public: // currently unused for normal maps bool CanUnload(uint32 diff) { - if (!m_unloadTimer) + if (!m_unloadTimer || Events.HasEvents()) return false; if (m_unloadTimer <= diff) @@ -430,7 +430,7 @@ public: void UpdatePlayerZoneStats(uint32 oldZone, uint32 newZone); [[nodiscard]] uint32 ApplyDynamicModeRespawnScaling(WorldObject const* obj, uint32 respawnDelay) const; - TaskScheduler _creatureRespawnScheduler; + EventProcessor Events; void ScheduleCreatureRespawn(ObjectGuid /*creatureGuid*/, Milliseconds /*respawnTimer*/, Position pos = Position());