diff options
Diffstat (limited to 'src/common/Collision/Management/MMapManager.cpp')
-rw-r--r-- | src/common/Collision/Management/MMapManager.cpp | 142 |
1 files changed, 108 insertions, 34 deletions
diff --git a/src/common/Collision/Management/MMapManager.cpp b/src/common/Collision/Management/MMapManager.cpp index 11fe943bfc9..f581db5f093 100644 --- a/src/common/Collision/Management/MMapManager.cpp +++ b/src/common/Collision/Management/MMapManager.cpp @@ -19,13 +19,12 @@ #include "MMapManager.h" #include "Errors.h" #include "Log.h" -#include "Config.h" #include "MapDefines.h" namespace MMAP { - static char const* const MAP_FILE_NAME_FORMAT = "%s/mmaps/%04i.mmap"; - static char const* const TILE_FILE_NAME_FORMAT = "%s/mmaps/%04i%02i%02i.mmtile"; + static char const* const MAP_FILE_NAME_FORMAT = "%smmaps/%04i.mmap"; + static char const* const TILE_FILE_NAME_FORMAT = "%smmaps/%04i%02i%02i.mmtile"; // ######################## MMapManager ######################## MMapManager::~MMapManager() @@ -37,11 +36,16 @@ namespace MMAP // if we had, tiles in MMapData->mmapLoadedTiles, their actual data is lost! } - void MMapManager::InitializeThreadUnsafe(const std::vector<uint32>& mapIds) + void MMapManager::InitializeThreadUnsafe(std::unordered_map<uint32, std::vector<uint32>> const& mapData) { + childMapData = mapData; // the caller must pass the list of all mapIds that will be used in the VMapManager2 lifetime - for (uint32 const& mapId : mapIds) - loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr)); + for (std::pair<uint32 const, std::vector<uint32>> const& mapId : mapData) + { + loadedMMaps.insert(MMapDataSet::value_type(mapId.first, nullptr)); + for (uint32 childMapId : mapId.second) + parentMapData[childMapId] = mapId.first; + } thread_safe_environment = false; } @@ -56,7 +60,7 @@ namespace MMAP return itr; } - bool MMapManager::loadMapData(uint32 mapId) + bool MMapManager::loadMapData(std::string const& basePath, uint32 mapId) { // we already have this map loaded? MMapDataSet::iterator itr = loadedMMaps.find(mapId); @@ -74,7 +78,7 @@ namespace MMAP } // load and init dtNavMesh - read parameters from file - std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, sConfigMgr->GetStringDefault("DataDir", ".").c_str(), mapId); + std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, basePath.c_str(), mapId); FILE* file = fopen(fileName.c_str(), "rb"); if (!file) { @@ -114,10 +118,25 @@ namespace MMAP return uint32(x << 16 | y); } - bool MMapManager::loadMap(const std::string& /*basePath*/, uint32 mapId, int32 x, int32 y) + bool MMapManager::loadMap(std::string const& basePath, uint32 mapId, int32 x, int32 y) + { + if (!loadMapImpl(basePath, mapId, x, y)) + return false; + + bool success = true; + auto childMaps = childMapData.find(mapId); + if (childMaps != childMapData.end()) + for (uint32 childMapId : childMaps->second) + if (!loadMapImpl(basePath, childMapId, x, y)) + success = false; + + return success; + } + + bool MMapManager::loadMapImpl(std::string const& basePath, uint32 mapId, int32 x, int32 y) { // make sure the mmap is loaded and ready to load tiles - if (!loadMapData(mapId)) + if (!loadMapData(basePath, mapId)) return false; // get this mmap data @@ -130,10 +149,20 @@ namespace MMAP return false; // load this tile :: mmaps/MMMMXXYY.mmtile - std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, sConfigMgr->GetStringDefault("DataDir", ".").c_str(), mapId, x, y); + std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, basePath.c_str(), mapId, x, y); FILE* file = fopen(fileName.c_str(), "rb"); if (!file) { + auto parentMapItr = parentMapData.find(mapId); + if (parentMapItr != parentMapData.end()) + { + fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, basePath.c_str(), parentMapItr->second, x, y); + file = fopen(fileName.c_str(), "rb"); + } + } + + if (!file) + { TC_LOG_DEBUG("maps", "MMAP:loadMap: Could not open mmtile file '%s'", fileName.c_str()); return false; } @@ -198,8 +227,57 @@ namespace MMAP } } + bool MMapManager::loadMapInstance(std::string const& basePath, uint32 mapId, uint32 instanceId) + { + if (!loadMapInstanceImpl(basePath, mapId, instanceId)) + return false; + + bool success = true; + auto childMaps = childMapData.find(mapId); + if (childMaps != childMapData.end()) + for (uint32 childMapId : childMaps->second) + if (!loadMapInstanceImpl(basePath, childMapId, instanceId)) + success = false; + + return success; + } + + bool MMapManager::loadMapInstanceImpl(std::string const& basePath, uint32 mapId, uint32 instanceId) + { + if (!loadMapData(basePath, mapId)) + return false; + + MMapData* mmap = loadedMMaps[mapId]; + if (mmap->navMeshQueries.find(instanceId) != mmap->navMeshQueries.end()) + return true; + + // allocate mesh query + dtNavMeshQuery* query = dtAllocNavMeshQuery(); + ASSERT(query); + if (dtStatusFailed(query->init(mmap->navMesh, 1024))) + { + dtFreeNavMeshQuery(query); + TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId); + return false; + } + + TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId); + mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query)); + return true; + } + bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y) { + auto childMaps = childMapData.find(mapId); + if (childMaps != childMapData.end()) + for (uint32 childMapId : childMaps->second) + unloadMapImpl(childMapId, x, y); + + return unloadMapImpl(mapId, x, y); + } + + bool MMapManager::unloadMapImpl(uint32 mapId, int32 x, int32 y) + { // check if we have this map loaded MMapDataSet::const_iterator itr = GetMMapData(mapId); if (itr == loadedMMaps.end()) @@ -213,17 +291,16 @@ namespace MMAP // check if we have this tile loaded uint32 packedGridPos = packTileID(x, y); - if (mmap->loadedTileRefs.find(packedGridPos) == mmap->loadedTileRefs.end()) + auto tileRefItr = mmap->loadedTileRefs.find(packedGridPos); + if (tileRefItr == mmap->loadedTileRefs.end()) { // file may not exist, therefore not loaded TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %04u%02i%02i.mmtile", mapId, x, y); return false; } - dtTileRef tileRef = mmap->loadedTileRefs[packedGridPos]; - // unload, and mark as non loaded - if (dtStatusFailed(mmap->navMesh->removeTile(tileRef, nullptr, nullptr))) + if (dtStatusFailed(mmap->navMesh->removeTile(tileRefItr->second, nullptr, nullptr))) { // this is technically a memory leak // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used @@ -233,7 +310,7 @@ namespace MMAP } else { - mmap->loadedTileRefs.erase(packedGridPos); + mmap->loadedTileRefs.erase(tileRefItr); --loadedTiles; TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %04i[%02i, %02i] from %03i", mapId, x, y, mapId); return true; @@ -244,6 +321,16 @@ namespace MMAP bool MMapManager::unloadMap(uint32 mapId) { + auto childMaps = childMapData.find(mapId); + if (childMaps != childMapData.end()) + for (uint32 childMapId : childMaps->second) + unloadMapImpl(childMapId); + + return unloadMapImpl(mapId); + } + + bool MMapManager::unloadMapImpl(uint32 mapId) + { MMapDataSet::iterator itr = loadedMMaps.find(mapId); if (itr == loadedMMaps.end() || !itr->second) { @@ -312,27 +399,14 @@ namespace MMAP dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId) { - MMapDataSet::const_iterator itr = GetMMapData(mapId); + auto itr = GetMMapData(mapId); if (itr == loadedMMaps.end()) return nullptr; - MMapData* mmap = itr->second; - if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) - { - // allocate mesh query - dtNavMeshQuery* query = dtAllocNavMeshQuery(); - ASSERT(query); - if (dtStatusFailed(query->init(mmap->navMesh, 1024))) - { - dtFreeNavMeshQuery(query); - TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId); - return nullptr; - } - - TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId); - mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query)); - } + auto queryItr = itr->second->navMeshQueries.find(instanceId); + if (queryItr == itr->second->navMeshQueries.end()) + return nullptr; - return mmap->navMeshQueries[instanceId]; + return queryItr->second; } } |