diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 3d6284bf8..8aec468ab 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1302,6 +1302,13 @@ template void Map::Remove(Creature *,bool); template void Map::Remove(GameObject *, bool); template void Map::Remove(DynamicObject *, bool); +/* ******* World Maps ******* */ + +WorldPersistentState* WorldMap::GetPersistanceState() const +{ + return (WorldPersistentState*)Map::GetPersistentState(); +} + /* ******* Dungeon Instance Maps ******* */ DungeonMap::DungeonMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode) diff --git a/src/game/Map.h b/src/game/Map.h index 5ee9c87e7..5a5eb26e1 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -46,6 +46,7 @@ class WorldPacket; class InstanceData; class Group; class MapPersistentState; +class WorldPersistentState; class DungeonPersistentState; class BattleGroundPersistentState; struct ScriptInfo; @@ -93,8 +94,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager friend class MapReference; friend class ObjectGridLoader; friend class ObjectWorldLoader; - public: + protected: Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode); + + public: virtual ~Map(); // currently unused for normal maps @@ -339,6 +342,18 @@ class MANGOS_DLL_SPEC Map : public GridRefManager void RemoveFromGrid(T*, NGridType *, Cell const&); }; +class MANGOS_DLL_SPEC WorldMap : public Map +{ + private: + using Map::GetPersistentState; // hide in subclass for overwrite + public: + WorldMap(uint32 id, time_t expiry) : Map(id, expiry, 0, REGULAR_DIFFICULTY) {} + ~WorldMap() {} + + // can't be NULL for loaded map + WorldPersistentState* GetPersistanceState() const; +}; + class MANGOS_DLL_SPEC DungeonMap : public Map { private: diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 0c730a620..fe9cee38e 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -108,11 +108,11 @@ Map* MapManager::CreateMap(uint32 id, const WorldObject* obj) } else { - //create regular Continent map + //create regular non-instanceable map m = FindMap(id); if( m == NULL ) { - m = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY); + m = new WorldMap(id, i_gridCleanUpDelay); //add map into container i_maps[MapID(id)] = m; diff --git a/src/game/MapPersistentStateMgr.cpp b/src/game/MapPersistentStateMgr.cpp index e17a6500e..3224d35f0 100644 --- a/src/game/MapPersistentStateMgr.cpp +++ b/src/game/MapPersistentStateMgr.cpp @@ -56,13 +56,6 @@ MapEntry const* MapPersistentState::GetMapEntry() const return sMapStore.LookupEntry(m_mapid); } -bool MapPersistentState::CanBeUnload() const -{ - // prevent unload if used for loaded map - // prevent unload if respawn data still exist (will not prevent reset by scheduler) - return !m_usedByMap && m_creatureRespawnTimes.empty() && m_goRespawnTimes.empty(); -} - /* true if the instance state is still valid */ bool MapPersistentState::UnloadIfEmpty() { @@ -135,7 +128,14 @@ void MapPersistentState::ClearRespawnTimes() UnloadIfEmpty(); } +//== WorldPersistentState functions ======================== +bool WorldPersistentState::CanBeUnload() const +{ + // prevent unload if used for loaded map + // prevent unload if respawn data still exist (will not prevent reset by scheduler) + return MapPersistentState::CanBeUnload() && HasRespawnTimes(); +} //== DungeonPersistentState functions ===================== @@ -161,7 +161,7 @@ DungeonPersistentState::~DungeonPersistentState() bool DungeonPersistentState::CanBeUnload() const { // prevent unload if any bounded groups or online bounded player still exists - return MapPersistentState::CanBeUnload() && m_playerList.empty() && m_groupList.empty(); + return MapPersistentState::CanBeUnload() && HasBounds() && HasRespawnTimes(); } /* @@ -222,7 +222,7 @@ bool BattleGroundPersistentState::CanBeUnload() const { // prevent unload if used for loaded map // BGs/Arenas not locked by respawn data/etc - return !IsUsedByMap(); + return MapPersistentState::CanBeUnload(); } //== DungeonResetScheduler functions ====================== @@ -521,7 +521,7 @@ MapPersistentState* MapPersistentStateManager::AddPersistentState(MapEntry const else if (mapEntry->IsBattleGroundOrArena()) state = new BattleGroundPersistentState(mapEntry->MapID, instanceId, difficulty); else - state = new MapPersistentState(mapEntry->MapID, instanceId, difficulty); + state = new WorldPersistentState(mapEntry->MapID); if (instanceId) diff --git a/src/game/MapPersistentStateMgr.h b/src/game/MapPersistentStateMgr.h index 6e73c1d4e..76da29116 100644 --- a/src/game/MapPersistentStateMgr.h +++ b/src/game/MapPersistentStateMgr.h @@ -38,21 +38,14 @@ class Group; class MapPersistentStateManager; -/* - Holds the information necessary for creating a new map for non-instanceable maps - - As object Used for non-instanceable Map only -*/ class MapPersistentState { friend class MapPersistentStateManager; - public: - /* Created either when: - - any new instance is being generated - - the first time a player bound to InstanceId logs in - - when a group bound to the instance is loaded */ + protected: MapPersistentState(uint16 MapId, uint32 InstanceId, Difficulty difficulty); + public: + /* Unloaded when m_playerList and m_groupList become empty or when the instance is reset */ virtual ~MapPersistentState(); @@ -92,9 +85,15 @@ class MapPersistentState void SaveGORespawnTime(uint32 loguid, time_t t); protected: - virtual bool CanBeUnload() const; + virtual bool CanBeUnload() const =0 + { + // prevent unload if used for loaded map + return !m_usedByMap; + } + bool UnloadIfEmpty(); void ClearRespawnTimes(); + bool HasRespawnTimes() const { return m_creatureRespawnTimes.empty() && m_goRespawnTimes.empty(); } private: void SetCreatureRespawnTime(uint32 loguid, time_t t); @@ -113,6 +112,21 @@ class MapPersistentState RespawnTimes m_goRespawnTimes; // lock MapPersistentState from unload, for example for temporary bound dungeon unload delay }; +class WorldPersistentState : public MapPersistentState +{ + public: + /* Created either when: + - any new non-instanceable map created + - respawn data loading for non-instanceable map + */ + explicit WorldPersistentState(uint16 MapId) : MapPersistentState(MapId, 0, REGULAR_DIFFICULTY) {} + + ~WorldPersistentState() {} + + protected: + bool CanBeUnload() const; // overwrite MapPersistentState::CanBeUnload +}; + /* Holds the information necessary for creating a new map for an existing instance Is referenced in three cases: @@ -167,6 +181,7 @@ class DungeonPersistentState : public MapPersistentState protected: bool CanBeUnload() const; // overwrite MapPersistentState::CanBeUnload + bool HasBounds() const { return m_playerList.empty() && m_groupList.empty(); } private: typedef std::list PlayerListType; @@ -197,7 +212,6 @@ class BattleGroundPersistentState : public MapPersistentState bool CanBeUnload() const; // overwrite MapPersistentState::CanBeUnload }; - enum ResetEventType { RESET_EVENT_NORMAL_DUNGEON = 0, // no fixed reset time diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d8eca2a7d..90d4e8f32 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11128" + #define REVISION_NR "11129" #endif // __REVISION_NR_H__