diff options
Diffstat (limited to 'src/server/collision/Management/MMapManager.cpp')
-rw-r--r-- | src/server/collision/Management/MMapManager.cpp | 145 |
1 files changed, 60 insertions, 85 deletions
diff --git a/src/server/collision/Management/MMapManager.cpp b/src/server/collision/Management/MMapManager.cpp index bb752fd9b49..8b86bcb053f 100644 --- a/src/server/collision/Management/MMapManager.cpp +++ b/src/server/collision/Management/MMapManager.cpp @@ -24,6 +24,9 @@ namespace MMAP { + static char const* const MAP_FILE_NAME_FORMAT = "mmaps/%04i.mmap"; + static char const* const TILE_FILE_NAME_FORMAT = "mmaps/%04i%02i%02i.mmtile"; + // ######################## MMapManager ######################## MMapManager::~MMapManager() { @@ -41,15 +44,11 @@ namespace MMAP return true; // load and init dtNavMesh - read parameters from file - uint32 pathLen = uint32(sWorld->GetDataPath().length() + strlen("mmaps/%03i.mmap") + 1); - char *fileName = new char[pathLen]; - snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i.mmap").c_str(), mapId); - - FILE* file = fopen(fileName, "rb"); + std::string fileName = Trinity::StringFormat(MAP_FILE_NAME_FORMAT, mapId); + FILE* file = fopen(fileName.c_str(), "rb"); if (!file) { - TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not open mmap file '%s'", fileName); - delete [] fileName; + TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not open mmap file '%s'", fileName.c_str()); return false; } @@ -58,8 +57,7 @@ namespace MMAP fclose(file); if (count != 1) { - TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName); - delete [] fileName; + TC_LOG_DEBUG("maps", "MMAP:loadMapData: Error: Could not read params from file '%s'", fileName.c_str()); return false; } @@ -68,14 +66,11 @@ namespace MMAP if (dtStatusFailed(mesh->init(¶ms))) { dtFreeNavMesh(mesh); - TC_LOG_ERROR("maps", "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %03u from file %s", mapId, fileName); - delete [] fileName; + TC_LOG_ERROR("maps", "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap %04u from file %s", mapId, fileName.c_str()); return false; } - delete [] fileName; - - TC_LOG_DEBUG("maps", "MMAP:loadMapData: Loaded %03i.mmap", mapId); + TC_LOG_DEBUG("maps", "MMAP:loadMapData: Loaded %04i.mmap", mapId); // store inside our map list MMapData* mmap_data = new MMapData(mesh, mapId); @@ -104,33 +99,27 @@ namespace MMAP if (mmap->loadedTileRefs.find(packedGridPos) != mmap->loadedTileRefs.end()) return false; - // load this tile :: mmaps/MMMXXYY.mmtile - uint32 pathLen = uint32(sWorld->GetDataPath().length() + strlen("mmaps/%03i%02i%02i.mmtile") + 1); - char *fileName = new char[pathLen]; - - snprintf(fileName, pathLen, (sWorld->GetDataPath()+"mmaps/%03i%02i%02i.mmtile").c_str(), mapId, x, y); - - FILE* file = fopen(fileName, "rb"); + // load this tile :: mmaps/MMMMXXYY.mmtile + std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, mapId, x, y); + FILE* file = fopen(fileName.c_str(), "rb"); if (!file) { - TC_LOG_DEBUG("maps", "MMAP:loadMap: Could not open mmtile file '%s'", fileName); - delete [] fileName; + TC_LOG_DEBUG("maps", "MMAP:loadMap: Could not open mmtile file '%s'", fileName.c_str()); return false; } - delete [] fileName; // read header MmapTileHeader fileHeader; if (fread(&fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || fileHeader.mmapMagic != MMAP_MAGIC) { - TC_LOG_ERROR("maps", "MMAP:loadMap: Bad header in mmap %03u%02i%02i.mmtile", mapId, x, y); + TC_LOG_ERROR("maps", "MMAP:loadMap: Bad header in mmap %04u%02i%02i.mmtile", mapId, x, y); fclose(file); return false; } if (fileHeader.mmapVersion != MMAP_VERSION) { - TC_LOG_ERROR("maps", "MMAP:loadMap: %03u%02i%02i.mmtile was built with generator v%i, expected v%i", + TC_LOG_ERROR("maps", "MMAP:loadMap: %04u%02i%02i.mmtile was built with generator v%i, expected v%i", mapId, x, y, fileHeader.mmapVersion, MMAP_VERSION); fclose(file); return false; @@ -142,7 +131,7 @@ namespace MMAP size_t result = fread(data, fileHeader.size, 1, file); if (!result) { - TC_LOG_ERROR("maps", "MMAP:loadMap: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, x, y); + TC_LOG_ERROR("maps", "MMAP:loadMap: Bad header or data in mmap %04u%02i%02i.mmtile", mapId, x, y); fclose(file); return false; } @@ -157,14 +146,14 @@ namespace MMAP { mmap->loadedTileRefs.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef)); ++loadedTiles; - TC_LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile %03i[%02i, %02i] into %03i[%02i, %02i]", mapId, x, y, mapId, header->x, header->y); + TC_LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile %04i[%02i, %02i] into %04i[%02i, %02i]", mapId, x, y, mapId, header->x, header->y); LoadPhaseTiles(mapId, x, y); return true; } - TC_LOG_ERROR("maps", "MMAP:loadMap: Could not load %03u%02i%02i.mmtile into navmesh", mapId, x, y); + TC_LOG_ERROR("maps", "MMAP:loadMap: Could not load %04u%02i%02i.mmtile into navmesh", mapId, x, y); dtFree(data); return false; } @@ -172,34 +161,28 @@ namespace MMAP PhasedTile* MMapManager::LoadTile(uint32 mapId, int32 x, int32 y) { // load this tile :: mmaps/MMMXXYY.mmtile - uint32 pathLen = sWorld->GetDataPath().length() + strlen("mmaps/%03i%02i%02i.mmtile") + 1; - char *fileName = new char[pathLen]; - - snprintf(fileName, pathLen, (sWorld->GetDataPath() + "mmaps/%03i%02i%02i.mmtile").c_str(), mapId, x, y); - - FILE* file = fopen(fileName, "rb"); + std::string fileName = Trinity::StringFormat(TILE_FILE_NAME_FORMAT, mapId, x, y); + FILE* file = fopen(fileName.c_str(), "rb"); if (!file) { // Not all tiles have phased versions, don't flood this msg //TC_LOG_DEBUG("phase", "MMAP:LoadTile: Could not open mmtile file '%s'", fileName); - delete[] fileName; return NULL; } - delete[] fileName; PhasedTile* pTile = new PhasedTile(); // read header if (fread(&pTile->fileHeader, sizeof(MmapTileHeader), 1, file) != 1 || pTile->fileHeader.mmapMagic != MMAP_MAGIC) { - TC_LOG_ERROR("phase", "MMAP:LoadTile: Bad header in mmap %03u%02i%02i.mmtile", mapId, x, y); + TC_LOG_ERROR("phase", "MMAP:LoadTile: Bad header in mmap %04u%02i%02i.mmtile", mapId, x, y); fclose(file); return NULL; } if (pTile->fileHeader.mmapVersion != MMAP_VERSION) { - TC_LOG_ERROR("phase", "MMAP:LoadTile: %03u%02i%02i.mmtile was built with generator v%i, expected v%i", + TC_LOG_ERROR("phase", "MMAP:LoadTile: %04u%02i%02i.mmtile was built with generator v%i, expected v%i", mapId, x, y, pTile->fileHeader.mmapVersion, MMAP_VERSION); fclose(file); return NULL; @@ -211,7 +194,7 @@ namespace MMAP size_t result = fread(pTile->data, pTile->fileHeader.size, 1, file); if (!result) { - TC_LOG_ERROR("phase", "MMAP:LoadTile: Bad header or data in mmap %03u%02i%02i.mmtile", mapId, x, y); + TC_LOG_ERROR("phase", "MMAP:LoadTile: Bad header or data in mmap %04u%02i%02i.mmtile", mapId, x, y); fclose(file); return NULL; } @@ -237,7 +220,7 @@ namespace MMAP // only a few tiles have terrain swaps, do not write error for them if (data) { - TC_LOG_DEBUG("phase", "MMAP:LoadPhaseTiles: Loaded phased %03u%02i%02i.mmtile for root phase map %u", map->ID, x, y, mapId); + TC_LOG_DEBUG("phase", "MMAP:LoadPhaseTiles: Loaded phased %04u%02i%02i.mmtile for root phase map %u", map->ID, x, y, mapId); _phaseTiles[map->ID][packedGridPos] = data; } } @@ -256,7 +239,7 @@ namespace MMAP if (_phaseTiles[mapId][packedGridPos]) { - TC_LOG_DEBUG("phase", "MMAP:UnloadPhaseTile: Unloaded phased %03u%02i%02i.mmtile for root phase map %u", mapId, x, y, rootMapId); + TC_LOG_DEBUG("phase", "MMAP:UnloadPhaseTile: Unloaded phased %04u%02i%02i.mmtile for root phase map %u", mapId, x, y, rootMapId); delete _phaseTiles[mapId][packedGridPos]->data; delete _phaseTiles[mapId][packedGridPos]; _phaseTiles[mapId].erase(packedGridPos); @@ -269,7 +252,7 @@ namespace MMAP if (loadedMMaps.find(mapId) == loadedMMaps.end()) { // file may not exist, therefore not loaded - TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map. %03u%02i%02i.mmtile", mapId, x, y); + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map. %04u%02i%02i.mmtile", mapId, x, y); return false; } @@ -280,7 +263,7 @@ namespace MMAP if (mmap->loadedTileRefs.find(packedGridPos) == mmap->loadedTileRefs.end()) { // file may not exist, therefore not loaded - TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %03u%02i%02i.mmtile", mapId, x, y); + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh tile. %04u%02i%02i.mmtile", mapId, x, y); return false; } @@ -292,14 +275,14 @@ namespace MMAP // this is technically a memory leak // if the grid is later reloaded, dtNavMesh::addTile will return error but no extra memory is used // we cannot recover from this error - assert out - TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y); + TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %04u%02i%02i.mmtile from navmesh", mapId, x, y); ASSERT(false); } else { mmap->loadedTileRefs.erase(packedGridPos); --loadedTiles; - TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId); + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %04i", mapId, x, y, mapId); UnloadPhaseTile(mapId, x, y); return true; @@ -313,7 +296,7 @@ namespace MMAP if (loadedMMaps.find(mapId) == loadedMMaps.end()) { // file may not exist, therefore not loaded - TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map %03u", mapId); + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map %04u", mapId); return false; } @@ -324,18 +307,18 @@ namespace MMAP uint32 x = (i->first >> 16); uint32 y = (i->first & 0x0000FFFF); if (dtStatusFailed(mmap->navMesh->removeTile(i->second, NULL, NULL))) - TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %03u%02i%02i.mmtile from navmesh", mapId, x, y); + TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload %04u%02i%02i.mmtile from navmesh", mapId, x, y); else { UnloadPhaseTile(mapId, x, y); --loadedTiles; - TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %03i[%02i, %02i] from %03i", mapId, x, y, mapId); + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile %04i[%02i, %02i] from %04i", mapId, x, y, mapId); } } delete mmap; loadedMMaps.erase(mapId); - TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded %03i.mmap", mapId); + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded %04i.mmap", mapId); return true; } @@ -346,14 +329,14 @@ namespace MMAP if (loadedMMaps.find(mapId) == loadedMMaps.end()) { // file may not exist, therefore not loaded - TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %03u", mapId); + TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %04u", mapId); return false; } MMapData* mmap = loadedMMaps[mapId]; if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) { - TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %03u instanceId %u", mapId, instanceId); + TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %04u instanceId %u", mapId, instanceId); return false; } @@ -361,7 +344,7 @@ namespace MMAP dtFreeNavMeshQuery(query); mmap->navMeshQueries.erase(instanceId); - TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId); + TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId %04u instanceId %u", mapId, instanceId); return true; } @@ -388,11 +371,11 @@ namespace MMAP if (dtStatusFailed(query->init(mmap->GetNavMesh(swaps), 1024))) { dtFreeNavMeshQuery(query); - TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); + TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId); return NULL; } - TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); + TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %04u instanceId %u", mapId, instanceId); mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query)); } @@ -426,25 +409,25 @@ namespace MMAP if (loadedPhasedTiles[swap].find(packedXY) == loadedPhasedTiles[swap].end()) { - TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: mmtile %03u[%02i, %02i] unload skipped, due to not loaded", swap, x, y); + TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: mmtile %04u[%02i, %02i] unload skipped, due to not loaded", swap, x, y); return; } dtMeshHeader* header = (dtMeshHeader*)ptile->data; // remove old tile if (dtStatusFailed(navMesh->removeTile(loadedTileRefs[packedXY], NULL, NULL))) - TC_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not unload phased %03u%02i%02i.mmtile from navmesh", swap, x, y); + TC_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not unload phased %04u%02i%02i.mmtile from navmesh", swap, x, y); else { - TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: Unloaded phased %03u%02i%02i.mmtile from navmesh", swap, x, y); + TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: Unloaded phased %04u%02i%02i.mmtile from navmesh", swap, x, y); // restore base tile if (dtStatusSucceed(navMesh->addTile(_baseTiles[packedXY]->data, _baseTiles[packedXY]->dataSize, 0, 0, &loadedTileRefs[packedXY]))) { - TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: Loaded base mmtile %03u[%02i, %02i] into %03i[%02i, %02i]", _mapId, x, y, _mapId, header->x, header->y); + TC_LOG_DEBUG("phase", "MMapData::RemoveSwap: Loaded base mmtile %04u[%02i, %02i] into %04i[%02i, %02i]", _mapId, x, y, _mapId, header->x, header->y); } else - TC_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not load base %03u%02i%02i.mmtile to navmesh", _mapId, x, y); + TC_LOG_ERROR("phase", "MMapData::RemoveSwap: Could not load base %04u%02i%02i.mmtile to navmesh", _mapId, x, y); } loadedPhasedTiles[swap].erase(packedXY); @@ -464,12 +447,12 @@ namespace MMAP if (loadedTileRefs.find(packedXY) == loadedTileRefs.end()) { - TC_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %03u[%02i, %02i] load skipped, due to not loaded base tile on map %u", swap, x, y, _mapId); + TC_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %04u[%02i, %02i] load skipped, due to not loaded base tile on map %u", swap, x, y, _mapId); return; } if (loadedPhasedTiles[swap].find(packedXY) != loadedPhasedTiles[swap].end()) { - TC_LOG_DEBUG("phase", "MMapData::AddSwap: WARNING! phased mmtile %03u[%02i, %02i] load skipped, due to already loaded on map %u", swap, x, y, _mapId); + TC_LOG_DEBUG("phase", "MMapData::AddSwap: WARNING! phased mmtile %04u[%02i, %02i] load skipped, due to already loaded on map %u", swap, x, y, _mapId); return; } @@ -480,25 +463,22 @@ namespace MMAP if (!oldTile) { - TC_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %03u[%02i, %02i] load skipped, due to not loaded base tile ref on map %u", swap, x, y, _mapId); + TC_LOG_DEBUG("phase", "MMapData::AddSwap: phased mmtile %04u[%02i, %02i] load skipped, due to not loaded base tile ref on map %u", swap, x, y, _mapId); return; } - uint32 old_x = oldTile->header->x; - uint32 old_y = oldTile->header->y; - // header xy is based on the swap map's tile set, wich doesn't have all the same tiles as root map, so copy the xy from the orignal header - memcpy(ptile->data + 8, (char*)&old_x, 4); - memcpy(ptile->data + 12, (char*)&old_y, 4); + header->x = oldTile->header->x; + header->y = oldTile->header->y; // the removed tile's data PhasedTile* pt = new PhasedTile(); // remove old tile if (dtStatusFailed(navMesh->removeTile(loadedTileRefs[packedXY], &pt->data, &pt->dataSize))) - TC_LOG_ERROR("phase", "MMapData::AddSwap: Could not unload %03u%02i%02i.mmtile from navmesh", _mapId, x, y); + TC_LOG_ERROR("phase", "MMapData::AddSwap: Could not unload %04u%02i%02i.mmtile from navmesh", _mapId, x, y); else { - TC_LOG_DEBUG("phase", "MMapData::AddSwap: Unloaded %03u%02i%02i.mmtile from navmesh", _mapId, x, y); + TC_LOG_DEBUG("phase", "MMapData::AddSwap: Unloaded %04u%02i%02i.mmtile from navmesh", _mapId, x, y); // store the removed data first time, this is the origonal, non-phased tile if (_baseTiles.find(packedXY) == _baseTiles.end()) @@ -510,43 +490,38 @@ namespace MMAP // add new swapped tile if (dtStatusSucceed(navMesh->addTile(ptile->data, ptile->fileHeader.size, 0, 0, &loadedTileRefs[packedXY]))) { - TC_LOG_DEBUG("phase", "MMapData::AddSwap: Loaded phased mmtile %03u[%02i, %02i] into %03i[%02i, %02i]", swap, x, y, _mapId, header->x, header->y); + TC_LOG_DEBUG("phase", "MMapData::AddSwap: Loaded phased mmtile %04u[%02i, %02i] into %04i[%02i, %02i]", swap, x, y, _mapId, header->x, header->y); } else - TC_LOG_ERROR("phase", "MMapData::AddSwap: Could not load %03u%02i%02i.mmtile to navmesh", swap, x, y); + TC_LOG_ERROR("phase", "MMapData::AddSwap: Could not load %04u%02i%02i.mmtile to navmesh", swap, x, y); } } dtNavMesh* MMapData::GetNavMesh(TerrainSet swaps) { - for (uint32 swap : _activeSwaps) + std::set<uint32> activeSwaps = _activeSwaps; // _activeSwaps is modified inside RemoveSwap + for (uint32 swap : activeSwaps) { - if (swaps.find(swap) == swaps.end()) // swap not active + if (!swaps.count(swap)) // swap not active { PhaseTileContainer ptc = MMAP::MMapFactory::createOrGetMMapManager()->GetPhaseTileContainer(swap); for (PhaseTileContainer::const_iterator itr = ptc.begin(); itr != ptc.end(); ++itr) - { RemoveSwap(itr->second, swap, itr->first); // remove swap - } } } - if (!swaps.empty()) + // for each of the calling unit's terrain swaps + for (uint32 swap : swaps) { - // for each of the calling unit's terrain swaps - for (uint32 swap : swaps) + if (!_activeSwaps.count(swap)) // swap not active { // for each of the terrain swap's xy tiles PhaseTileContainer ptc = MMAP::MMapFactory::createOrGetMMapManager()->GetPhaseTileContainer(swap); for (PhaseTileContainer::const_iterator itr = ptc.begin(); itr != ptc.end(); ++itr) - { - if (_activeSwaps.find(swap) == _activeSwaps.end()) // swap not active - { - AddSwap(itr->second, swap, itr->first); // add swap - } - } + AddSwap(itr->second, swap, itr->first); // add swap } } + return navMesh; } } |