aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/mmaps_common/Management/MMapManager.cpp218
-rw-r--r--src/common/mmaps_common/Management/MMapManager.h13
-rw-r--r--src/server/game/Maps/Map.cpp1
-rw-r--r--src/server/game/Maps/TerrainMgr.cpp16
-rw-r--r--src/server/game/Maps/TerrainMgr.h3
-rw-r--r--src/server/game/Movement/PathGenerator.cpp2
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp2
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp10
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, &params); paramsResult != LoadResult::Success)
return paramsResult;
- NavMeshPtr mesh(dtAllocNavMesh());
- ASSERT(mesh);
- if (dtStatusFailed(mesh->init(&params)))
+ if (dtStatusFailed(meshItr->second.navMesh.init(&params)))
{
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.");