From 60afe858e8a3392ac4be180468588b6379d7645b Mon Sep 17 00:00:00 2001 From: Ovah Date: Mon, 12 Mar 2018 18:19:19 +0000 Subject: [PATCH] MMaps phasing --- .../Collision/Management/MMapManager.cpp | 142 +++++++++++++----- src/common/Collision/Management/MMapManager.h | 14 +- .../DataStores/DBCFileLoader.cpp | 0 .../DataStores/DBCFileLoader.h | 7 + src/server/game/Maps/Map.cpp | 4 +- src/server/game/Movement/PathGenerator.cpp | 2 +- src/server/game/World/World.cpp | 4 +- src/server/scripts/Commands/cs_mmaps.cpp | 25 +-- src/tools/mmaps_generator/MapBuilder.cpp | 12 +- src/tools/mmaps_generator/PathCommon.h | 2 +- src/tools/mmaps_generator/PathGenerator.cpp | 59 +++++++- src/tools/mmaps_generator/TerrainBuilder.cpp | 17 ++- src/tools/vmap4_extractor/vmapexport.cpp | 2 +- 13 files changed, 222 insertions(+), 68 deletions(-) rename src/{server/shared => common}/DataStores/DBCFileLoader.cpp (100%) rename src/{server/shared => common}/DataStores/DBCFileLoader.h (92%) diff --git a/src/common/Collision/Management/MMapManager.cpp b/src/common/Collision/Management/MMapManager.cpp index 2cabac6309..df4793a901 100644 --- a/src/common/Collision/Management/MMapManager.cpp +++ b/src/common/Collision/Management/MMapManager.cpp @@ -19,13 +19,12 @@ #include "MMapManager.h" #include "Log.h" #include "MMapFactory.h" -#include "Config.h" #include "MapDefines.h" namespace MMAP { - static char const* const MAP_FILE_NAME_FORMAT = "%s/mmaps/%03i.mmap"; - static char const* const TILE_FILE_NAME_FORMAT = "%s/mmaps/%03i%02i%02i.mmtile"; + static char const* const MAP_FILE_NAME_FORMAT = "%smmaps/%03i.mmap"; + static char const* const TILE_FILE_NAME_FORMAT = "%smmaps/%03i%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& mapIds) + void MMapManager::InitializeThreadUnsafe(std::unordered_map> 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> 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,8 +149,18 @@ namespace MMAP return false; // load this tile :: mmaps/MMMXXYY.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()); @@ -198,7 +227,56 @@ 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(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); @@ -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. %03u%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; @@ -243,6 +320,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 %03u instanceId %u", mapId, instanceId); - return nullptr; - } + auto queryItr = itr->second->navMeshQueries.find(instanceId); + if (queryItr == itr->second->navMeshQueries.end()) + return nullptr; - TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); - mmap->navMeshQueries.insert(std::pair(instanceId, query)); - } - - return mmap->navMeshQueries[instanceId]; + return queryItr->second; } } diff --git a/src/common/Collision/Management/MMapManager.h b/src/common/Collision/Management/MMapManager.h index dbabeb07d2..a4859ecee4 100644 --- a/src/common/Collision/Management/MMapManager.h +++ b/src/common/Collision/Management/MMapManager.h @@ -64,8 +64,9 @@ namespace MMAP MMapManager() : loadedTiles(0), thread_safe_environment(true) {} ~MMapManager(); - void InitializeThreadUnsafe(const std::vector& mapIds); - bool loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y); + void InitializeThreadUnsafe(std::unordered_map> const& mapData); + bool loadMap(std::string const& basePath, uint32 mapId, int32 x, int32 y); + bool loadMapInstance(std::string const& basePath, uint32 mapId, uint32 instanceId); bool unloadMap(uint32 mapId, int32 x, int32 y); bool unloadMap(uint32 mapId); bool unloadMapInstance(uint32 mapId, uint32 instanceId); @@ -77,13 +78,20 @@ namespace MMAP uint32 getLoadedTilesCount() const { return loadedTiles; } uint32 getLoadedMapsCount() const { return uint32(loadedMMaps.size()); } private: - bool loadMapData(uint32 mapId); + bool loadMapData(std::string const& basePath, uint32 mapId); + bool loadMapImpl(std::string const& basePath, uint32 mapId, int32 x, int32 y); + bool loadMapInstanceImpl(std::string const& basePath, uint32 mapId, uint32 instanceId); + bool unloadMapImpl(uint32 mapId, int32 x, int32 y); + bool unloadMapImpl(uint32 mapId); uint32 packTileID(int32 x, int32 y); MMapDataSet::const_iterator GetMMapData(uint32 mapId) const; MMapDataSet loadedMMaps; uint32 loadedTiles; bool thread_safe_environment; + + std::unordered_map> childMapData; + std::unordered_map parentMapData; }; } diff --git a/src/server/shared/DataStores/DBCFileLoader.cpp b/src/common/DataStores/DBCFileLoader.cpp similarity index 100% rename from src/server/shared/DataStores/DBCFileLoader.cpp rename to src/common/DataStores/DBCFileLoader.cpp diff --git a/src/server/shared/DataStores/DBCFileLoader.h b/src/common/DataStores/DBCFileLoader.h similarity index 92% rename from src/server/shared/DataStores/DBCFileLoader.h rename to src/common/DataStores/DBCFileLoader.h index 708a34156b..377ef8cafc 100644 --- a/src/server/shared/DataStores/DBCFileLoader.h +++ b/src/common/DataStores/DBCFileLoader.h @@ -47,6 +47,13 @@ class TC_SHARED_API DBCFileLoader EndianConvert(val); return val; } + int32 getInt(size_t field) const + { + assert(field < file.fieldCount); + int32 val = *reinterpret_cast(offset + file.GetOffset(field)); + EndianConvert(val); + return val; + } uint8 getUInt8(size_t field) const { assert(field < file.fieldCount); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 463e49adde..08c3d399c4 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -133,7 +133,7 @@ void Map::LoadMMap(int gx, int gy) if (!DisableMgr::IsPathfindingEnabled(GetId())) return; - bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap((sWorld->GetDataPath() + "mmaps").c_str(), GetId(), gx, gy); + bool mmapLoadResult = MMAP::MMapFactory::createOrGetMMapManager()->loadMap(sWorld->GetDataPath(), GetId(), gx, gy); if (mmapLoadResult) TC_LOG_DEBUG("mmaps", "MMAP loaded name:%s, id:%d, x:%d, y:%d (mmap rep.: x:%d, y:%d)", GetMapName(), GetId(), gx, gy, gx, gy); @@ -291,6 +291,8 @@ i_scriptLock(false), _defaultLight(GetDefaultMapLight(id)) //lets initialize visibility distance for map Map::InitVisibilityDistance(); + MMAP::MMapFactory::createOrGetMMapManager()->loadMapInstance(sWorld->GetDataPath(), GetId(), i_InstanceId); + sScriptMgr->OnCreateMap(this); } diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 28f6db3910..f8b1291398 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -41,7 +41,7 @@ PathGenerator::PathGenerator(const Unit* owner) : TC_LOG_DEBUG("maps", "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUID().GetCounter()); uint32 mapId = PhasingHandler::GetTerrainMapId(_sourceUnit->GetPhaseShift(), _sourceUnit->GetMap(), _sourceUnit->GetPositionX(), _sourceUnit->GetPositionY()); - if (DisableMgr::IsPathfindingEnabled(mapId)) + if (DisableMgr::IsPathfindingEnabled(_sourceUnit->GetMapId())) { MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager(); _navMesh = mmap->GetNavMesh(mapId); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index e2cc1bdbb7..9da562d7e4 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1502,11 +1502,9 @@ void World::SetInitialWorldSettings() // Load M2 fly by cameras LoadM2Cameras(m_dataPath); - std::vector mapIds; std::unordered_map> mapData; for (MapEntry const* mapEntry : sMapStore) { - mapIds.push_back(mapEntry->MapID); mapData.emplace(std::piecewise_construct, std::forward_as_tuple(mapEntry->MapID), std::forward_as_tuple()); if (mapEntry->rootPhaseMap != -1) mapData[mapEntry->rootPhaseMap].push_back(mapEntry->MapID); @@ -1518,7 +1516,7 @@ void World::SetInitialWorldSettings() vmmgr2->InitializeThreadUnsafe(mapData); MMAP::MMapManager* mmmgr = MMAP::MMapFactory::createOrGetMMapManager(); - mmmgr->InitializeThreadUnsafe(mapIds); + mmmgr->InitializeThreadUnsafe(mapData); TC_LOG_INFO("server.loading", "Initializing PlayerDump tables..."); PlayerDump::InitializeTables(); diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index 1a3259bb23..1877041e13 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -30,6 +30,7 @@ #include "Player.h" #include "PointMovementGenerator.h" #include "PathGenerator.h" +#include "PhasingHandler.h" #include "MMapFactory.h" #include "Map.h" #include "TargetedMovementGenerator.h" @@ -130,12 +131,16 @@ public: int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS; int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS; + float x, y, z; + player->GetPosition(x, y, z); + handler->PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gx, gy); handler->PSendSysMessage("gridloc [%i, %i]", gy, gx); // calculate navmesh tile location - dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()); - dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(handler->GetSession()->GetPlayer()->GetMapId(), player->GetInstanceId()); + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMap(), x, y); + dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(terrainMapId); + dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(terrainMapId, player->GetInstanceId()); if (!navmesh || !navmeshquery) { handler->PSendSysMessage("NavMesh not loaded for current map."); @@ -143,8 +148,6 @@ public: } float const* min = navmesh->getParams()->orig; - float x, y, z; - player->GetPosition(x, y, z); float location[VERTEX_SIZE] = { y, z, x }; float extents[VERTEX_SIZE] = { 3.0f, 5.0f, 3.0f }; @@ -185,9 +188,10 @@ public: static bool HandleMmapLoadedTilesCommand(ChatHandler* handler, char const* /*args*/) { - uint32 mapid = handler->GetSession()->GetPlayer()->GetMapId(); - dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(mapid); - dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(mapid, handler->GetSession()->GetPlayer()->GetInstanceId()); + Player* player = handler->GetSession()->GetPlayer(); + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMap(), player->GetPositionX(), player->GetPositionY()); + dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(terrainMapId); + dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(terrainMapId, player->GetInstanceId()); if (!navmesh || !navmeshquery) { handler->PSendSysMessage("NavMesh not loaded for current map."); @@ -210,14 +214,15 @@ public: static bool HandleMmapStatsCommand(ChatHandler* handler, char const* /*args*/) { - uint32 mapId = handler->GetSession()->GetPlayer()->GetMapId(); + Player* player = handler->GetSession()->GetPlayer(); + uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMap(), player->GetPositionX(), player->GetPositionY()); handler->PSendSysMessage("mmap stats:"); - handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(mapId) ? "en" : "dis"); + handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(player->GetMapId()) ? "en" : "dis"); MMAP::MMapManager* manager = MMAP::MMapFactory::createOrGetMMapManager(); handler->PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount()); - dtNavMesh const* navmesh = manager->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId()); + dtNavMesh const* navmesh = manager->GetNavMesh(terrainMapId); if (!navmesh) { handler->PSendSysMessage("NavMesh not loaded for current map."); diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 56e8ba318f..80e0dcff5c 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -23,11 +23,13 @@ #include "DetourNavMesh.h" #include "IntermediateValues.h" #include "StringFormat.h" +#include "VMapFactory.h" +#include "VMapManager2.h" #include #define MMAP_MAGIC 0x4d4d4150 // 'MMAP' -#define MMAP_VERSION 7 +#define MMAP_VERSION 8 struct MmapTileHeader { @@ -471,7 +473,12 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) { - std::set* tiles = getTileList(mapID); + // if map has a parent we use that to generate dtNavMeshParams - worldserver will load all missing tiles from that map + int32 navMeshParamsMapId = static_cast(VMapFactory::createOrGetVMapManager())->getParentMapId(mapID); + if (navMeshParamsMapId == -1) + navMeshParamsMapId = mapID; + + std::set* tiles = getTileList(navMeshParamsMapId); // old code for non-statically assigned bitmask sizes: ///*** calculate number of bits needed to store tiles & polys ***/ @@ -532,6 +539,7 @@ namespace MMAP if (!file) { dtFreeNavMesh(navMesh); + navMesh = nullptr; char message[1024]; sprintf(message, "[Map %03i] Failed to open %s for writing!\n", mapID, fileName); perror(message); diff --git a/src/tools/mmaps_generator/PathCommon.h b/src/tools/mmaps_generator/PathCommon.h index 4f553302c0..b14e290685 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -101,7 +101,7 @@ namespace MMAP return LISTFILE_DIRECTORY_NOT_FOUND; do { - if ((findFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) + if (strcmp(findFileInfo.cFileName, ".") != 0 && strcmp(findFileInfo.cFileName, "..") != 0) fileList.push_back(std::string(findFileInfo.cFileName)); } while (FindNextFile(hFind, &findFileInfo)); diff --git a/src/tools/mmaps_generator/PathGenerator.cpp b/src/tools/mmaps_generator/PathGenerator.cpp index 0013b5e13f..83182a7f07 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -16,16 +16,26 @@ * with this program. If not, see . */ -#include - -#include "PathCommon.h" #include "MapBuilder.h" +#include "PathCommon.h" #include "Timer.h" +#include "VMapFactory.h" +#include "VMapManager2.h" +#include "DBCFileLoader.h" +#include +#include +#include using namespace MMAP; -bool checkDirectories(bool debugOutput) +bool checkDirectories(bool debugOutput, std::vector& dbcLocales) { + if (getDirContents(dbcLocales, "dbc") == LISTFILE_DIRECTORY_NOT_FOUND || dbcLocales.empty()) + { + printf("'dbc' directory is empty or does not exist\n"); + return false; + } + std::vector dirFiles; if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) @@ -43,15 +53,24 @@ bool checkDirectories(bool debugOutput) dirFiles.clear(); if (getDirContents(dirFiles, "mmaps") == LISTFILE_DIRECTORY_NOT_FOUND) - return boost::filesystem::create_directory("mmaps"); + { + if (!boost::filesystem::create_directory("mmaps")) + { + printf("'mmaps' directory does not exist and failed to create it\n"); + return false; + } + } dirFiles.clear(); if (debugOutput) { if (getDirContents(dirFiles, "meshes") == LISTFILE_DIRECTORY_NOT_FOUND) { - printf("'meshes' directory does not exist (no place to put debugOutput files)\n"); - return false; + if (!boost::filesystem::create_directory("meshes")) + { + printf("'meshes' directory does not exist and failed to create it (no place to put debugOutput files)\n"); + return false; + } } } @@ -274,9 +293,31 @@ int main(int argc, char** argv) return 0; } - if (!checkDirectories(debugOutput)) + std::vector dbcLocales; + if (!checkDirectories(debugOutput, dbcLocales)) return silent ? -3 : finish("Press ENTER to close...", -3); + std::string mapPath = (boost::filesystem::path("dbc") / "Map.dbc").string(); + DBCFileLoader* loader = new DBCFileLoader(); + + std::unordered_map> mapData; + { + if (!loader->Load(mapPath.c_str(), "x")) + { + delete loader; + return silent ? -4 : finish("Failed to load Map.dbc", -4); + } + for (uint32 x = 0; x < loader->GetRowSize(); ++x) + { + mapData.emplace(std::piecewise_construct, std::forward_as_tuple(loader->getRecord(x).getUInt(0)), std::forward_as_tuple()); + int16 parentMapId = int16(loader->getRecord(x).getInt(19)); + if (parentMapId != -1) + mapData[parentMapId].push_back(loader->getRecord(x).getUInt(0)); + } + + static_cast(VMAP::VMapFactory::createOrGetVMapManager())->InitializeThreadUnsafe(mapData); + } + MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath); @@ -290,6 +331,8 @@ int main(int argc, char** argv) else builder.buildAllMaps(threads); + VMAP::VMapFactory::clear(); + if (!silent) printf("Finished. MMAPS were built in %u ms!\n", GetMSTimeDiffToNow(start)); return 0; diff --git a/src/tools/mmaps_generator/TerrainBuilder.cpp b/src/tools/mmaps_generator/TerrainBuilder.cpp index a703382c8a..e3b550042e 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2008-2018 TrinityCore * Copyright (C) 2005-2011 MaNGOS * @@ -17,12 +17,11 @@ */ #include "TerrainBuilder.h" - #include "MapBuilder.h" - -#include "VMapManager2.h" #include "MapTree.h" #include "ModelInstance.h" +#include "VMapFactory.h" +#include "VMapManager2.h" // ****************************************** // Map file format defines @@ -137,6 +136,16 @@ namespace MMAP sprintf(mapFileName, "maps/%03u%02u%02u.map", mapID, tileY, tileX); FILE* mapFile = fopen(mapFileName, "rb"); + if (!mapFile) + { + int32 parentMapId = static_cast(VMapFactory::createOrGetVMapManager())->getParentMapId(mapID); + if (parentMapId != -1) + { + sprintf(mapFileName, "maps/%03u%02u%02u.map", parentMapId, tileY, tileX); + mapFile = fopen(mapFileName, "rb"); + } + } + if (!mapFile) return false; diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp index 72c83a1d58..e3153100a5 100644 --- a/src/tools/vmap4_extractor/vmapexport.cpp +++ b/src/tools/vmap4_extractor/vmapexport.cpp @@ -613,7 +613,7 @@ int main(int argc, char ** argv) strncpy(m.name, map_name, max_map_name_length); m.name[max_map_name_length - 1] = '\0'; - m.parent_id = int16(dbc->getRecord(x).getUInt(19)); + m.parent_id = int16(dbc->getRecord(x).getInt(19)); if (m.parent_id >= 0) maps_that_are_parents.insert(m.parent_id);