diff options
author | Shauren <shauren.trinity@gmail.com> | 2018-03-03 14:29:53 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2018-03-25 19:28:36 +0300 |
commit | 3743d042017d72435d2ff8135f66808988beaf9e (patch) | |
tree | 2100274d7035a2bb8a616bd971520f457e5d3846 /src | |
parent | 6d5e25ddd45dc78894daa000c0b122a44bbdbaf6 (diff) |
Core/MMaps: Implemented loading phased tiles
Closes #16909
Diffstat (limited to 'src')
-rw-r--r-- | src/common/Collision/Management/MMapManager.cpp | 142 | ||||
-rw-r--r-- | src/common/Collision/Management/MMapManager.h | 14 | ||||
-rw-r--r-- | src/server/game/Maps/Map.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Movement/PathGenerator.cpp | 4 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 4 | ||||
-rw-r--r-- | src/server/scripts/Commands/cs_mmaps.cpp | 25 | ||||
-rw-r--r-- | src/tools/mmaps_generator/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/tools/mmaps_generator/MapBuilder.cpp | 10 | ||||
-rw-r--r-- | src/tools/mmaps_generator/PathCommon.h | 2 | ||||
-rw-r--r-- | src/tools/mmaps_generator/PathGenerator.cpp | 62 | ||||
-rw-r--r-- | src/tools/mmaps_generator/TerrainBuilder.cpp | 27 |
11 files changed, 221 insertions, 74 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; } } diff --git a/src/common/Collision/Management/MMapManager.h b/src/common/Collision/Management/MMapManager.h index 289475427b4..151813f9b2f 100644 --- a/src/common/Collision/Management/MMapManager.h +++ b/src/common/Collision/Management/MMapManager.h @@ -63,8 +63,9 @@ namespace MMAP MMapManager() : loadedTiles(0), thread_safe_environment(true) {} ~MMapManager(); - void InitializeThreadUnsafe(const std::vector<uint32>& mapIds); - bool loadMap(const std::string& basePath, uint32 mapId, int32 x, int32 y); + void InitializeThreadUnsafe(std::unordered_map<uint32, std::vector<uint32>> 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); @@ -76,13 +77,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<uint32, std::vector<uint32>> childMapData; + std::unordered_map<uint32, uint32> parentMapData; }; } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index c3e1aa744d3..0e161abdf98 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -144,7 +144,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); @@ -306,6 +306,8 @@ i_scriptLock(false), _defaultLight(DB2Manager::GetDefaultMapLight(id)) GetGuidSequenceGenerator<HighGuid::Transport>().Set(sObjectMgr->GetGenerator<HighGuid::Transport>().GetNextAfterMaxUsed()); + 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 6c9e1cd01d9..16cfe366f4e 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -39,8 +39,8 @@ PathGenerator::PathGenerator(const Unit* owner) : TC_LOG_DEBUG("maps", "++ PathGenerator::PathGenerator for %s", _sourceUnit->GetGUID().ToString().c_str()); - uint32 mapId = _sourceUnit->GetMapId(); - if (DisableMgr::IsPathfindingEnabled(mapId)) + uint32 mapId = _sourceUnit->GetPhaseShift().GetTerrainMapId(_sourceUnit->GetMapId(), _sourceUnit->GetPositionX(), _sourceUnit->GetPositionY()); + 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 9e73cc8d532..760ec282bd7 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1575,11 +1575,9 @@ void World::SetInitialWorldSettings() //Load weighted graph on taxi nodes path sTaxiPathGraph.Initialize(); - std::vector<uint32> mapIds; std::unordered_map<uint32, std::vector<uint32>> mapData; for (MapEntry const* mapEntry : sMapStore) { - mapIds.push_back(mapEntry->ID); mapData.emplace(std::piecewise_construct, std::forward_as_tuple(mapEntry->ID), std::forward_as_tuple()); if (mapEntry->ParentMapID != -1) mapData[mapEntry->ParentMapID].push_back(mapEntry->ID); @@ -1591,7 +1589,7 @@ void World::SetInitialWorldSettings() vmmgr2->InitializeThreadUnsafe(mapData); MMAP::MMapManager* mmmgr = MMAP::MMapFactory::createOrGetMMapManager(); - mmmgr->InitializeThreadUnsafe(mapIds); + mmmgr->InitializeThreadUnsafe(mapData); TC_LOG_INFO("server.loading", "Loading SpellInfo store..."); sSpellMgr->LoadSpellInfoStore(); diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index a40fb5f65a5..bd11a31515e 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -31,6 +31,7 @@ #include "Map.h" #include "MMapFactory.h" #include "PathGenerator.h" +#include "PhasingHandler.h" #include "Player.h" #include "PointMovementGenerator.h" #include "RBAC.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("%04u%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/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt index 9dfb0cfdede..0f4f42de20b 100644 --- a/src/tools/mmaps_generator/CMakeLists.txt +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -23,6 +23,7 @@ target_link_libraries(mmaps_generator trinity-core-interface PUBLIC common + extractor_common Recast Detour zlib diff --git a/src/tools/mmaps_generator/MapBuilder.cpp b/src/tools/mmaps_generator/MapBuilder.cpp index 251df44dfa3..acc947096de 100644 --- a/src/tools/mmaps_generator/MapBuilder.cpp +++ b/src/tools/mmaps_generator/MapBuilder.cpp @@ -23,6 +23,8 @@ #include "MapTree.h" #include "ModelInstance.h" +#include "VMapFactory.h" +#include "VMapManager2.h" #include "DetourNavMeshBuilder.h" #include "DetourNavMesh.h" @@ -470,7 +472,12 @@ namespace MMAP /**************************************************************************/ void MapBuilder::buildNavMesh(uint32 mapID, dtNavMesh* &navMesh) { - std::set<uint32>* 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<VMapManager2*>(VMapFactory::createOrGetVMapManager())->getParentMapId(mapID); + if (navMeshParamsMapId == -1) + navMeshParamsMapId = mapID; + + std::set<uint32>* tiles = getTileList(navMeshParamsMapId); // old code for non-statically assigned bitmask sizes: ///*** calculate number of bits needed to store tiles & polys ***/ @@ -531,6 +538,7 @@ namespace MMAP if (!file) { dtFreeNavMesh(navMesh); + navMesh = nullptr; char message[1024]; sprintf(message, "[Map %04u] 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 333a55419ba..414407632d6 100644 --- a/src/tools/mmaps_generator/PathCommon.h +++ b/src/tools/mmaps_generator/PathCommon.h @@ -103,7 +103,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 b30e28623ae..035bddd9063 100644 --- a/src/tools/mmaps_generator/PathGenerator.cpp +++ b/src/tools/mmaps_generator/PathGenerator.cpp @@ -16,17 +16,29 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <boost/filesystem.hpp> - -#include "PathCommon.h" +#include "Banner.h" +#include "DB2FileLoader.h" +#include "DB2FileSystemSource.h" +#include "ExtractorDB2LoadInfo.h" #include "MapBuilder.h" +#include "PathCommon.h" #include "Timer.h" -#include "Banner.h" +#include "VMapFactory.h" +#include "VMapManager2.h" +#include <boost/filesystem/operations.hpp> +#include <unordered_map> +#include <vector> using namespace MMAP; -bool checkDirectories(bool debugOutput) +bool checkDirectories(bool debugOutput, std::vector<std::string>& 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<std::string> dirFiles; if (getDirContents(dirFiles, "maps") == LISTFILE_DIRECTORY_NOT_FOUND || dirFiles.empty()) @@ -44,15 +56,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; + } } } @@ -277,9 +298,30 @@ int main(int argc, char** argv) return 0; } - if (!checkDirectories(debugOutput)) + std::vector<std::string> dbcLocales; + if (!checkDirectories(debugOutput, dbcLocales)) return silent ? -3 : finish("Press ENTER to close...", -3); + DB2FileLoader mapDb2; + std::unordered_map<uint32, std::vector<uint32>> mapData; + { + DB2FileSystemSource mapSource((boost::filesystem::path("dbc") / dbcLocales[0] / "Map.db2").string()); + if (!mapDb2.Load(&mapSource, MapLoadInfo::Instance())) + return silent ? -4 : finish("Failed to load Map.db2", -4); + + for (uint32 x = 0; x < mapDb2.GetRecordCount(); ++x) + { + DB2Record record = mapDb2.GetRecord(x); + + mapData.emplace(std::piecewise_construct, std::forward_as_tuple(record.GetId()), std::forward_as_tuple()); + int16 parentMapId = int16(record.GetUInt16("ParentMapID")); + if (parentMapId != -1) + mapData[parentMapId].push_back(record.GetId()); + } + + static_cast<VMAP::VMapManager2*>(VMAP::VMapFactory::createOrGetVMapManager())->InitializeThreadUnsafe(mapData); + } + MapBuilder builder(maxAngle, skipLiquid, skipContinents, skipJunkMaps, skipBattlegrounds, debugOutput, bigBaseUnit, mapnum, offMeshInputPath); @@ -293,6 +335,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 430abe8e21b..ca4ae090423 100644 --- a/src/tools/mmaps_generator/TerrainBuilder.cpp +++ b/src/tools/mmaps_generator/TerrainBuilder.cpp @@ -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 @@ -138,6 +137,16 @@ namespace MMAP FILE* mapFile = fopen(mapFileName, "rb"); if (!mapFile) + { + int32 parentMapId = static_cast<VMapManager2*>(VMapFactory::createOrGetVMapManager())->getParentMapId(mapID); + if (parentMapId != -1) + { + sprintf(mapFileName, "maps/%04d_%02u_%02u.map", parentMapId, tileY, tileX); + mapFile = fopen(mapFileName, "rb"); + } + } + + if (!mapFile) return false; map_fileheader fheader; @@ -389,7 +398,6 @@ namespace MMAP useTerrain = true; useLiquid = true; uint8 liquidType = MAP_LIQUID_TYPE_NO_WATER; - // FIXME: "warning: the address of ‘liquid_type’ will always evaluate as ‘true’" // if there is no liquid, don't use liquid if (!meshData.liquidVerts.size() || !ltriangles.size()) @@ -626,8 +634,8 @@ namespace MMAP /**************************************************************************/ bool TerrainBuilder::loadVMap(uint32 mapID, uint32 tileX, uint32 tileY, MeshData &meshData) { - IVMapManager* vmapManager = new VMapManager2(); - int result = vmapManager->loadMap("vmaps", mapID, tileX, tileY); + VMapManager2* vmapManager = static_cast<VMapManager2*>(VMapFactory::createOrGetVMapManager()); + int result = vmapManager->loadSingleMap(mapID, "vmaps", tileX, tileY); bool retval = false; do @@ -636,7 +644,7 @@ namespace MMAP break; InstanceTreeMap instanceTrees; - ((VMapManager2*)vmapManager)->getInstanceMapTree(instanceTrees); + vmapManager->getInstanceMapTree(instanceTrees); if (!instanceTrees[mapID]) break; @@ -664,7 +672,7 @@ namespace MMAP worldModel->getGroupModels(groupModels); // all M2s need to have triangle indices reversed - bool isM2 = instance.name.find(".m2") != std::string::npos || instance.name.find(".M2") != std::string::npos; + bool isM2 = (instance.flags & MOD_M2) != 0; // transform data float scale = instance.iScale; @@ -779,8 +787,7 @@ namespace MMAP } while (false); - vmapManager->unloadMap(mapID, tileX, tileY); - delete vmapManager; + vmapManager->unloadSingleMap(mapID, tileX, tileY); return retval; } |