diff options
| author | Shauren <shauren.trinity@gmail.com> | 2025-11-06 18:34:58 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2025-11-06 18:34:58 +0100 |
| commit | a9c752af97f3457101059d173a8974764db2a7d5 (patch) | |
| tree | 98bdfe490d70e605f7eb6cb7b7c6bea3d665afaa /src | |
| parent | f439120b1f8c4f5a5c3fc0deb6aa01bf971e4fdf (diff) | |
Core/MMaps: Allow loading mmap meshes per map instance
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/mmaps_common/Management/MMapManager.cpp | 218 | ||||
| -rw-r--r-- | src/common/mmaps_common/Management/MMapManager.h | 13 | ||||
| -rw-r--r-- | src/server/game/Maps/Map.cpp | 1 | ||||
| -rw-r--r-- | src/server/game/Maps/TerrainMgr.cpp | 16 | ||||
| -rw-r--r-- | src/server/game/Maps/TerrainMgr.h | 3 | ||||
| -rw-r--r-- | src/server/game/Movement/PathGenerator.cpp | 2 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_misc.cpp | 2 | ||||
| -rw-r--r-- | src/server/scripts/Commands/cs_mmaps.cpp | 10 |
8 files changed, 161 insertions, 104 deletions
diff --git a/src/common/mmaps_common/Management/MMapManager.cpp b/src/common/mmaps_common/Management/MMapManager.cpp index d0862a49156..d6d181bd9d4 100644 --- a/src/common/mmaps_common/Management/MMapManager.cpp +++ b/src/common/mmaps_common/Management/MMapManager.cpp @@ -20,6 +20,7 @@ #include "Hash.h" #include "Log.h" #include "MMapDefines.h" +#include "MapUtils.h" #include "Memory.h" #include <algorithm> @@ -28,22 +29,44 @@ namespace MMAP constexpr char MAP_FILE_NAME_FORMAT[] = "{}mmaps/{:04}.mmap"; constexpr char TILE_FILE_NAME_FORMAT[] = "{}mmaps/{:04}_{:02}_{:02}.mmtile"; - using NavMeshPtr = std::unique_ptr<dtNavMesh, decltype(Trinity::unique_ptr_deleter<dtNavMesh*, &::dtFreeNavMesh>())>; - using NavMeshQueryPtr = std::unique_ptr<dtNavMeshQuery, decltype(Trinity::unique_ptr_deleter<dtNavMeshQuery*, &::dtFreeNavMeshQuery>())>; + static thread_local bool thread_safe_environment = false; - typedef std::unordered_map<std::pair<uint32, uint32>, NavMeshQueryPtr> NavMeshQuerySet; - typedef std::unordered_map<uint32, dtTileRef> MMapTileSet; + using NavMeshQuerySet = std::unordered_map<std::pair<uint32, uint32>, dtNavMeshQuery>; + using MMapTileSet = std::unordered_map<uint32, dtTileRef>; + + struct MMapMapData + { + dtNavMesh navMesh; + MMapTileSet loadedTileRefs; // maps [map grid coords] to [dtTile] + }; + + using MeshDataMap = std::unordered_map<uint32, MMapMapData>; // dummy struct to hold map's mmap data struct MMapData { - explicit MMapData(NavMeshPtr&& mesh) : navMesh(std::move(mesh)) { } + MeshDataMap meshData; // we have to use single dtNavMeshQuery for every instance, since those are not thread safe NavMeshQuerySet navMeshQueries; // instanceId to query - NavMeshPtr navMesh; - MMapTileSet loadedTileRefs; // maps [map grid coords] to [dtTile] + static uint32 GetInstanceIdForMeshLookup([[maybe_unused]] uint32 mapId, [[maybe_unused]] uint32 instanceId) + { + // for maps that won't have dynamic mesh, return 0 to reuse the same mesh across all instances + return 0; + } + + std::pair<MeshDataMap::iterator, bool> GetMeshData(uint32 mapId, uint32 instanceId) + { + // for maps that won't have dynamic mesh, return 0 to reuse the same mesh across all instances + return meshData.try_emplace(GetInstanceIdForMeshLookup(mapId, instanceId)); + } + + MeshDataMap::iterator FindMeshData(uint32 mapId, uint32 instanceId) + { + // for maps that won't have dynamic mesh, return 0 to reuse the same mesh across all instances + return meshData.find(GetInstanceIdForMeshLookup(mapId, instanceId)); + } }; // ######################## MMapManager ######################## @@ -61,12 +84,13 @@ namespace MMAP // the caller must pass the list of all mapIds that will be used in the MMapManager lifetime for (auto const& [mapId, childMapIds] : mapData) { - loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr)); + loadedMMaps[mapId].reset(new MMapData()); for (uint32 childMapId : childMapIds) parentMapData[childMapId] = mapId; } - thread_safe_environment = false; + // mark the loading main thread as safe + thread_safe_environment = true; } MMapDataSet::const_iterator MMapManager::GetMMapData(uint32 mapId) const @@ -79,40 +103,47 @@ namespace MMAP return itr; } - LoadResult MMapManager::loadMapData(std::string_view basePath, uint32 mapId) + LoadResult MMapManager::loadMapData(std::string_view basePath, uint32 mapId, uint32 instanceId) { // we already have this map loaded? - MMapDataSet::iterator itr = loadedMMaps.find(mapId); - if (itr != loadedMMaps.end()) + MMapDataSet::iterator itr; + if (thread_safe_environment) { - if (itr->second) - return LoadResult::AlreadyLoaded; + bool needsLoading; + std::tie(itr, needsLoading) = loadedMMaps.try_emplace(mapId); + if (needsLoading) + itr->second.reset(new MMapData()); } else { - if (thread_safe_environment) - itr = loadedMMaps.insert(MMapDataSet::value_type(mapId, nullptr)).first; - else + itr = loadedMMaps.find(mapId); + if (itr == loadedMMaps.end()) ABORT_MSG("Invalid mapId %u passed to MMapManager after startup in thread unsafe environment", mapId); } + auto [meshItr, needsLoading] = itr->second->GetMeshData(mapId, instanceId); + if (!needsLoading) + return LoadResult::AlreadyLoaded; + + auto loadGuard = Trinity::make_unique_ptr_with_deleter(&meshItr, [&](MeshDataMap::iterator* m) + { + itr->second->meshData.erase(*m); + }); + // load and init dtNavMesh - read parameters from file dtNavMeshParams params; if (LoadResult paramsResult = parseNavMeshParamsFile(basePath, mapId, ¶ms); paramsResult != LoadResult::Success) return paramsResult; - NavMeshPtr mesh(dtAllocNavMesh()); - ASSERT(mesh); - if (dtStatusFailed(mesh->init(¶ms))) + if (dtStatusFailed(meshItr->second.navMesh.init(¶ms))) { TC_LOG_ERROR("maps", "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap {:04}", mapId); return LoadResult::LibraryError; } TC_LOG_DEBUG("maps", "MMAP:loadMapData: Loaded {:04}.mmap", mapId); + (void)loadGuard.release(); - // store inside our map list - itr->second.reset(new MMapData(std::move(mesh))); return LoadResult::Success; } @@ -168,10 +199,10 @@ namespace MMAP return uint32(x << 16 | y); } - LoadResult MMapManager::loadMap(std::string_view basePath, uint32 mapId, int32 x, int32 y) + LoadResult MMapManager::loadMap(std::string_view basePath, uint32 mapId, uint32 instanceId, int32 x, int32 y) { // make sure the mmap is loaded and ready to load tiles - switch (LoadResult mapResult = loadMapData(basePath, mapId)) + switch (LoadResult mapResult = loadMapData(basePath, mapId, instanceId)) { case LoadResult::Success: case LoadResult::AlreadyLoaded: @@ -182,11 +213,11 @@ namespace MMAP // get this mmap data MMapData* mmap = loadedMMaps[mapId].get(); - ASSERT(mmap->navMesh); + MMapMapData& meshData = mmap->GetMeshData(mapId, instanceId).first->second; // check if we already have this tile loaded uint32 packedGridPos = packTileID(x, y); - if (mmap->loadedTileRefs.contains(packedGridPos)) + if (meshData.loadedTileRefs.contains(packedGridPos)) return LoadResult::AlreadyLoaded; // load this tile :: mmaps/MMMM_XX_YY.mmtile @@ -253,9 +284,9 @@ namespace MMAP dtTileRef tileRef = 0; // memory allocated for data is now managed by detour, and will be deallocated when the tile is removed - if (dtStatusSucceed(mmap->navMesh->addTile(static_cast<unsigned char*>(data.release()), fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef))) + if (dtStatusSucceed(meshData.navMesh.addTile(static_cast<unsigned char*>(data.release()), fileHeader.size, DT_TILE_FREE_DATA, 0, &tileRef))) { - mmap->loadedTileRefs.insert(std::pair<uint32, dtTileRef>(packedGridPos, tileRef)); + meshData.loadedTileRefs[packedGridPos] = tileRef; ++loadedTiles; TC_LOG_DEBUG("maps", "MMAP:loadMap: Loaded mmtile {:04}[{:02}, {:02}] into {:04}[{:02}, {:02}]", mapId, x, y, mapId, header->x, header->y); return LoadResult::Success; @@ -269,7 +300,7 @@ namespace MMAP bool MMapManager::loadMapInstance(std::string_view basePath, uint32 meshMapId, uint32 instanceMapId, uint32 instanceId) { - switch (loadMapData(basePath, meshMapId)) + switch (loadMapData(basePath, meshMapId, instanceId)) { case LoadResult::Success: case LoadResult::AlreadyLoaded: @@ -279,14 +310,17 @@ namespace MMAP } MMapData* mmap = loadedMMaps[meshMapId].get(); - auto [queryItr, inserted] = mmap->navMeshQueries.try_emplace({ instanceMapId, instanceId }, nullptr); + auto [queryItr, inserted] = mmap->navMeshQueries.try_emplace({ instanceMapId, instanceId }); if (!inserted) return true; + auto loadGuard = Trinity::make_unique_ptr_with_deleter(&queryItr, [&](NavMeshQuerySet::iterator* m) + { + mmap->navMeshQueries.erase(*m); + }); + // allocate mesh query - NavMeshQueryPtr query(dtAllocNavMeshQuery()); - ASSERT(query); - if (dtStatusFailed(query->init(mmap->navMesh.get(), 1024))) + if (dtStatusFailed(queryItr->second.init(&mmap->GetMeshData(meshMapId, instanceId).first->second.navMesh, 1024))) { mmap->navMeshQueries.erase(queryItr); TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId {:04} instanceId {}", instanceMapId, instanceId); @@ -294,11 +328,11 @@ namespace MMAP } TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId {:04} instanceId {}", instanceMapId, instanceId); - queryItr->second = std::move(query); + (void)loadGuard.release(); return true; } - bool MMapManager::unloadMap(uint32 mapId, int32 x, int32 y) + void MMapManager::unloadMap(uint32 mapId, int32 x, int32 y) { // check if we have this map loaded MMapDataSet::const_iterator itr = GetMMapData(mapId); @@ -306,72 +340,69 @@ namespace MMAP { // file may not exist, therefore not loaded TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map. {:04}_{:02}_{:02}.mmtile", mapId, x, y); - return false; + return; } MMapData* mmap = itr->second.get(); - - // check if we have this tile loaded uint32 packedGridPos = packTileID(x, y); - auto tileRef = mmap->loadedTileRefs.extract(packedGridPos); - if (!tileRef) + for (auto& [instanceId, meshData] : mmap->meshData) { - // file may not exist, therefore not loaded - TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh tile. {:04}{:02}{:02}.mmtile", mapId, x, y); - return false; - } + // check if we have this tile loaded + auto tileRef = meshData.loadedTileRefs.extract(packedGridPos); + if (!tileRef) + continue; - // unload, and mark as non loaded - if (dtStatusFailed(mmap->navMesh->removeTile(tileRef.mapped(), 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 - // we cannot recover from this error - assert out - TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload {:04}_{:02}_{:02}.mmtile from navmesh", mapId, x, y); - ABORT(); - } - else - { - --loadedTiles; - TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile {:04}[{:02}, {:02}] from {:03}", mapId, x, y, mapId); - return true; + // unload, and mark as non loaded + if (dtStatusFailed(meshData.navMesh.removeTile(tileRef.mapped(), 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 + // we cannot recover from this error - assert out + TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload {:04}_{:02}_{:02}.mmtile from navmesh", mapId, x, y); + ABORT(); + } + else + { + --loadedTiles; + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile {:04}[{:02}, {:02}] from {:03}", mapId, x, y, mapId); + } } - - return false; } - bool MMapManager::unloadMap(uint32 mapId) + void MMapManager::unloadMap(uint32 mapId) { MMapDataSet::iterator itr = loadedMMaps.find(mapId); if (itr == loadedMMaps.end() || !itr->second) { // file may not exist, therefore not loaded TC_LOG_DEBUG("maps", "MMAP:unloadMap: Asked to unload not loaded navmesh map {:04}", mapId); - return false; + return; } - // unload all tiles from given map - MMapData* mmap = itr->second.get(); - for (auto const& [tileId, tileRef] : mmap->loadedTileRefs) + if (MMapData::GetInstanceIdForMeshLookup(mapId, std::numeric_limits<uint32>::max()) == 0) { - uint32 x = (tileId >> 16); - uint32 y = (tileId & 0x0000FFFF); - if (dtStatusFailed(mmap->navMesh->removeTile(tileRef, nullptr, nullptr))) - TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload {:04}_{:02}_{:02}.mmtile from navmesh", mapId, x, y); - else + // unload all tiles from given map + MMapMapData& mesh = itr->second->meshData[0]; + for (auto const& [tileId, tileRef] : mesh.loadedTileRefs) { - --loadedTiles; - TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile {:04}[{:02}, {:02}] from {:04}", mapId, x, y, mapId); + uint32 x = (tileId >> 16); + uint32 y = (tileId & 0x0000FFFF); + if (dtStatusFailed(mesh.navMesh.removeTile(tileRef, nullptr, nullptr))) + TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload {:04}_{:02}_{:02}.mmtile from navmesh", mapId, x, y); + else + { + --loadedTiles; + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile {:04}[{:02}, {:02}] from {:04}", mapId, x, y, mapId); + } } } + else // require all tiles to be already unloaded + ASSERT(std::ranges::all_of(itr->second->meshData, [](MMapMapData const& mesh) { return mesh.loadedTileRefs.empty(); }, Trinity::Containers::MapValue)); - itr->second = nullptr; TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded {:04}.mmap", mapId); - - return true; } - bool MMapManager::unloadMapInstance(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId) + void MMapManager::unloadMapInstance(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId) { // check if we have this map loaded MMapDataSet::const_iterator itr = GetMMapData(meshMapId); @@ -379,29 +410,48 @@ namespace MMAP { // file may not exist, therefore not loaded TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map {:04}", meshMapId); - return false; + return; } MMapData* mmap = itr->second.get(); std::size_t erased = mmap->navMeshQueries.erase({ instanceMapId, instanceId }); if (!erased) - { TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId {:04} instanceId {}", instanceMapId, instanceId); - return false; + + MeshDataMap::iterator meshItr = mmap->FindMeshData(meshMapId, instanceId); + if (meshItr != mmap->meshData.end()) + { + // unload all tiles from given map + for (auto const& [tileId, tileRef] : meshItr->second.loadedTileRefs) + { + uint32 x = (tileId >> 16); + uint32 y = (tileId & 0x0000FFFF); + if (dtStatusFailed(meshItr->second.navMesh.removeTile(tileRef, nullptr, nullptr))) + TC_LOG_ERROR("maps", "MMAP:unloadMap: Could not unload {:04}_{:02}_{:02}.mmtile from navmesh", meshMapId, x, y); + else + { + --loadedTiles; + TC_LOG_DEBUG("maps", "MMAP:unloadMap: Unloaded mmtile {:04}[{:02}, {:02}] from {:04}", meshMapId, x, y, meshMapId); + } + } + + mmap->meshData.erase(meshItr); } TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId {:04} instanceId {}", instanceMapId, instanceId); - - return true; } - dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId) + dtNavMesh const* MMapManager::GetNavMesh(uint32 mapId, uint32 instanceId) { MMapDataSet::const_iterator itr = GetMMapData(mapId); if (itr == loadedMMaps.end()) return nullptr; - return itr->second->navMesh.get(); + MeshDataMap::iterator meshItr = itr->second->FindMeshData(mapId, instanceId); + if (meshItr == itr->second->meshData.end()) + return nullptr; + + return &meshItr->second.navMesh; } dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId) @@ -414,6 +464,6 @@ namespace MMAP if (queryItr == itr->second->navMeshQueries.end()) return nullptr; - return queryItr->second.get(); + return &queryItr->second; } } diff --git a/src/common/mmaps_common/Management/MMapManager.h b/src/common/mmaps_common/Management/MMapManager.h index 87c09d65e6b..b277a3e96da 100644 --- a/src/common/mmaps_common/Management/MMapManager.h +++ b/src/common/mmaps_common/Management/MMapManager.h @@ -59,26 +59,25 @@ namespace MMAP void InitializeThreadUnsafe(std::unordered_map<uint32, std::vector<uint32>> const& mapData); static LoadResult parseNavMeshParamsFile(std::string_view basePath, uint32 mapId, dtNavMeshParams* params, std::vector<OffMeshData>* offmeshConnections = nullptr); - LoadResult loadMap(std::string_view basePath, uint32 mapId, int32 x, int32 y); + LoadResult loadMap(std::string_view basePath, uint32 mapId, uint32 instanceId, int32 x, int32 y); bool loadMapInstance(std::string_view basePath, uint32 meshMapId, uint32 instanceMapId, uint32 instanceId); - bool unloadMap(uint32 mapId, int32 x, int32 y); - bool unloadMap(uint32 mapId); - bool unloadMapInstance(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId); + void unloadMap(uint32 mapId, int32 x, int32 y); + void unloadMap(uint32 mapId); + void unloadMapInstance(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId); // the returned [dtNavMeshQuery const*] is NOT threadsafe dtNavMeshQuery const* GetNavMeshQuery(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId); - dtNavMesh const* GetNavMesh(uint32 mapId); + dtNavMesh const* GetNavMesh(uint32 mapId, uint32 instanceId); uint32 getLoadedTilesCount() const { return loadedTiles; } uint32 getLoadedMapsCount() const { return uint32(loadedMMaps.size()); } private: - LoadResult loadMapData(std::string_view basePath, uint32 mapId); + LoadResult loadMapData(std::string_view basePath, uint32 mapId, uint32 instanceId); uint32 packTileID(int32 x, int32 y); MMapDataSet::const_iterator GetMMapData(uint32 mapId) const; MMapDataSet loadedMMaps; uint32 loadedTiles = 0; - bool thread_safe_environment = true; std::unordered_map<uint32, uint32> parentMapData; }; diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 3a8e3c4cc56..ab5c83ee077 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -290,6 +290,7 @@ void Map::EnsureGridCreated(GridCoord const& p) int gy = (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord; m_terrain->LoadMapAndVMap(gx, gy); + m_terrain->LoadMMap(GetInstanceId(), gx, gy); } } diff --git a/src/server/game/Maps/TerrainMgr.cpp b/src/server/game/Maps/TerrainMgr.cpp index 19dd852baca..4233f08e072 100644 --- a/src/server/game/Maps/TerrainMgr.cpp +++ b/src/server/game/Maps/TerrainMgr.cpp @@ -25,7 +25,6 @@ #include "MMapManager.h" #include "PhasingHandler.h" #include "Random.h" -#include "ScriptMgr.h" #include "Util.h" #include "VMapFactory.h" #include "VMapManager.h" @@ -144,7 +143,7 @@ bool TerrainInfo::ExistVMap(uint32 mapid, int32 gx, int32 gy) bool TerrainInfo::HasChildTerrainGridFile(uint32 mapId, int32 gx, int32 gy) const { - auto childMapItr = std::find_if(_childTerrain.begin(), _childTerrain.end(), [mapId](std::shared_ptr<TerrainInfo> const& childTerrain) { return childTerrain->GetId() == mapId; }); + auto childMapItr = std::ranges::find(_childTerrain, mapId, [](std::shared_ptr<TerrainInfo> const& childTerrain) { return childTerrain->GetId(); }); return childMapItr != _childTerrain.end() && (*childMapItr)->_gridFileExists[GetBitsetIndex(gx, gy)]; } @@ -171,11 +170,18 @@ void TerrainInfo::LoadMMapInstance(uint32 mapId, uint32 instanceId) childTerrain->LoadMMapInstanceImpl(mapId, instanceId); } +void TerrainInfo::LoadMMap(uint32 instanceId, int32 gx, int32 gy) +{ + LoadMMapImpl(instanceId, gx, gy); + + for (std::shared_ptr<TerrainInfo> const& childTerrain : _childTerrain) + childTerrain->LoadMMapImpl(instanceId, gx, gy); +} + void TerrainInfo::LoadMapAndVMapImpl(int32 gx, int32 gy) { LoadMap(gx, gy); LoadVMap(gx, gy); - LoadMMap(gx, gy); for (std::shared_ptr<TerrainInfo> const& childTerrain : _childTerrain) childTerrain->LoadMapAndVMapImpl(gx, gy); @@ -233,12 +239,12 @@ void TerrainInfo::LoadVMap(int32 gx, int32 gy) } } -void TerrainInfo::LoadMMap(int32 gx, int32 gy) +void TerrainInfo::LoadMMapImpl(uint32 instanceId, int32 gx, int32 gy) { if (!DisableMgr::IsPathfindingEnabled(GetId())) return; - switch (MMAP::LoadResult mmapLoadResult = MMAP::MMapManager::instance()->loadMap(sWorld->GetDataPath(), GetId(), gx, gy)) + switch (MMAP::LoadResult mmapLoadResult = MMAP::MMapManager::instance()->loadMap(sWorld->GetDataPath(), GetId(), instanceId, gx, gy)) { case MMAP::LoadResult::Success: TC_LOG_DEBUG("mmaps.tiles", "MMAP loaded name:{}, id:{}, x:{}, y:{} (mmap rep.: x:{}, y:{})", GetMapName(), GetId(), gx, gy, gx, gy); diff --git a/src/server/game/Maps/TerrainMgr.h b/src/server/game/Maps/TerrainMgr.h index b4b5c5e4f89..f0e35556f22 100644 --- a/src/server/game/Maps/TerrainMgr.h +++ b/src/server/game/Maps/TerrainMgr.h @@ -58,13 +58,14 @@ public: void LoadMapAndVMap(int32 gx, int32 gy); void LoadMMapInstance(uint32 mapId, uint32 instanceId); + void LoadMMap(uint32 instanceId, int32 gx, int32 gy); private: void LoadMapAndVMapImpl(int32 gx, int32 gy); void LoadMMapInstanceImpl(uint32 mapId, uint32 instanceId); void LoadMap(int32 gx, int32 gy); void LoadVMap(int32 gx, int32 gy); - void LoadMMap(int32 gx, int32 gy); + void LoadMMapImpl(uint32 instanceId, int32 gx, int32 gy); public: void UnloadMap(int32 gx, int32 gy); diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 49f2f0150fa..8f44c3fcc29 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -43,7 +43,7 @@ PathGenerator::PathGenerator(WorldObject const* owner) : { MMAP::MMapManager* mmap = MMAP::MMapManager::instance(); _navMeshQuery = mmap->GetNavMeshQuery(mapId, _source->GetMapId(), _source->GetInstanceId()); - _navMesh = _navMeshQuery ? _navMeshQuery->getAttachedNavMesh() : mmap->GetNavMesh(mapId); + _navMesh = _navMeshQuery ? _navMeshQuery->getAttachedNavMesh() : mmap->GetNavMesh(mapId, _source->GetInstanceId()); } CreateFilter(); diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 5e87cf376fb..f824e35850c 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -258,7 +258,7 @@ public: uint32 haveMap = TerrainInfo::ExistMap(mapId, gridX, gridY) ? 1 : 0; uint32 haveVMap = TerrainInfo::ExistVMap(mapId, gridX, gridY) ? 1 : 0; - uint32 haveMMap = (DisableMgr::IsPathfindingEnabled(mapId) && MMAP::MMapManager::instance()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) ? 1 : 0; + uint32 haveMMap = (DisableMgr::IsPathfindingEnabled(mapId) && MMAP::MMapManager::instance()->GetNavMesh(object->GetMapId(), object->GetInstanceId())) ? 1 : 0; if (haveVMap) { diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp index b7734a8c505..ec2ada1971d 100644 --- a/src/server/scripts/Commands/cs_mmaps.cpp +++ b/src/server/scripts/Commands/cs_mmaps.cpp @@ -66,7 +66,8 @@ public: static bool HandleMmapPathCommand(ChatHandler* handler, char const* args) { - if (!MMAP::MMapManager::instance()->GetNavMesh(handler->GetSession()->GetPlayer()->GetMapId())) + Player* player = handler->GetSession()->GetPlayer(); + if (!MMAP::MMapManager::instance()->GetNavMesh(player->GetMapId(), player->GetInstanceId())) { handler->PSendSysMessage("NavMesh not loaded for current map."); return true; @@ -75,7 +76,6 @@ public: handler->PSendSysMessage("mmap path:"); // units - Player* player = handler->GetSession()->GetPlayer(); Unit* target = handler->getSelectedUnit(); if (!player || !target) { @@ -144,7 +144,7 @@ public: handler->PSendSysMessage("%04u_%02i_%02i.mmtile", terrainMapId, gx, gy); handler->PSendSysMessage("tileloc [%i, %i]", gy, gx); - dtNavMesh const* navmesh = MMAP::MMapManager::instance()->GetNavMesh(terrainMapId); + dtNavMesh const* navmesh = MMAP::MMapManager::instance()->GetNavMesh(terrainMapId, player->GetInstanceId()); dtNavMeshQuery const* navmeshquery = MMAP::MMapManager::instance()->GetNavMeshQuery(terrainMapId, player->GetMapId(), player->GetInstanceId()); if (!navmesh || !navmeshquery) { @@ -195,7 +195,7 @@ public: { Player* player = handler->GetSession()->GetPlayer(); uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMapId(), player->GetMap()->GetTerrain(), player->GetPositionX(), player->GetPositionY()); - dtNavMesh const* navmesh = MMAP::MMapManager::instance()->GetNavMesh(terrainMapId); + dtNavMesh const* navmesh = MMAP::MMapManager::instance()->GetNavMesh(terrainMapId, player->GetInstanceId()); dtNavMeshQuery const* navmeshquery = MMAP::MMapManager::instance()->GetNavMeshQuery(terrainMapId, player->GetMapId(), player->GetInstanceId()); if (!navmesh || !navmeshquery) { @@ -227,7 +227,7 @@ public: MMAP::MMapManager* manager = MMAP::MMapManager::instance(); handler->PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount()); - dtNavMesh const* navmesh = manager->GetNavMesh(terrainMapId); + dtNavMesh const* navmesh = manager->GetNavMesh(terrainMapId, player->GetInstanceId()); if (!navmesh) { handler->PSendSysMessage("NavMesh not loaded for current map."); |
