Core/MMaps: Fixed pathing for objects that have terrain swaps active

This commit is contained in:
Shauren authored and Ovahlord committed 2023-08-08 00:21:48 +02:00
1 parent 96b1933a6c
commit bfd31d59c2
7 files changed
+62 -32

No files matched your search

+21 -20
View File
@@ -211,13 +211,14 @@ namespace MMAP
} }
} }
bool MMapManager::loadMapInstance(std::string const& basePath, uint32 mapId, uint32 instanceId) bool MMapManager::loadMapInstance(std::string const& basePath, uint32 meshMapId, uint32 instanceMapId, uint32 instanceId)
{ {
if (!loadMapData(basePath, mapId)) if (!loadMapData(basePath, meshMapId))
return false; return false;
MMapData* mmap = loadedMMaps[mapId]; MMapData* mmap = loadedMMaps[meshMapId];
if (mmap->navMeshQueries.find(instanceId) != mmap->navMeshQueries.end()) auto [queryItr, inserted] = mmap->navMeshQueries.try_emplace({ instanceMapId, instanceId }, nullptr);
if (!inserted)
return true; return true;
// allocate mesh query // allocate mesh query
@@ -226,12 +227,13 @@ namespace MMAP
if (dtStatusFailed(query->init(mmap->navMesh, 1024))) if (dtStatusFailed(query->init(mmap->navMesh, 1024)))
{ {
dtFreeNavMeshQuery(query); dtFreeNavMeshQuery(query);
TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); mmap->navMeshQueries.erase(queryItr);
TC_LOG_ERROR("maps", "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId %03u instanceId %u", instanceMapId, instanceId);
return false; return false;
} }
TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", mapId, instanceId); TC_LOG_DEBUG("maps", "MMAP:GetNavMeshQuery: created dtNavMeshQuery for mapId %03u instanceId %u", instanceMapId, instanceId);
mmap->navMeshQueries.insert(std::pair<uint32, dtNavMeshQuery*>(instanceId, query)); queryItr->second = query;
return true; return true;
} }
@@ -310,29 +312,28 @@ namespace MMAP
return true; return true;
} }
bool MMapManager::unloadMapInstance(uint32 mapId, uint32 instanceId) bool MMapManager::unloadMapInstance(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId)
{ {
// check if we have this map loaded // check if we have this map loaded
MMapDataSet::const_iterator itr = GetMMapData(mapId); MMapDataSet::const_iterator itr = GetMMapData(meshMapId);
if (itr == loadedMMaps.end()) if (itr == loadedMMaps.end())
{ {
// file may not exist, therefore not loaded // file may not exist, therefore not loaded
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %03u", mapId); TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map %03u", meshMapId);
return false; return false;
} }
MMapData* mmap = itr->second; MMapData* mmap = itr->second;
if (mmap->navMeshQueries.find(instanceId) == mmap->navMeshQueries.end()) auto queryItr = mmap->navMeshQueries.find({ instanceMapId, instanceId });
if (queryItr == mmap->navMeshQueries.end())
{ {
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %03u instanceId %u", mapId, instanceId); TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId %03u instanceId %u", instanceMapId, instanceId);
return false; return false;
} }
dtNavMeshQuery* query = mmap->navMeshQueries[instanceId]; dtFreeNavMeshQuery(queryItr->second);
mmap->navMeshQueries.erase(queryItr);
dtFreeNavMeshQuery(query); TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", instanceMapId, instanceId);
mmap->navMeshQueries.erase(instanceId);
TC_LOG_DEBUG("maps", "MMAP:unloadMapInstance: Unloaded mapId %03u instanceId %u", mapId, instanceId);
return true; return true;
} }
@@ -346,13 +347,13 @@ namespace MMAP
return itr->second->navMesh; return itr->second->navMesh;
} }
dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 mapId, uint32 instanceId) dtNavMeshQuery const* MMapManager::GetNavMeshQuery(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId)
{ {
auto itr = GetMMapData(mapId); auto itr = GetMMapData(meshMapId);
if (itr == loadedMMaps.end()) if (itr == loadedMMaps.end())
return nullptr; return nullptr;
auto queryItr = itr->second->navMeshQueries.find(instanceId); auto queryItr = itr->second->navMeshQueries.find({ instanceMapId, instanceId });
if (queryItr == itr->second->navMeshQueries.end()) if (queryItr == itr->second->navMeshQueries.end())
return nullptr; return nullptr;
@@ -21,6 +21,7 @@
#include "Define.h" #include "Define.h"
#include "DetourNavMesh.h" #include "DetourNavMesh.h"
#include "DetourNavMeshQuery.h" #include "DetourNavMeshQuery.h"
#include "Hash.h"
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
@@ -29,7 +30,7 @@
namespace MMAP namespace MMAP
{ {
typedef std::unordered_map<uint32, dtTileRef> MMapTileSet; typedef std::unordered_map<uint32, dtTileRef> MMapTileSet;
typedef std::unordered_map<uint32, dtNavMeshQuery*> NavMeshQuerySet; typedef std::unordered_map<std::pair<uint32, uint32>, dtNavMeshQuery*> NavMeshQuerySet;
// dummy struct to hold map's mmap data // dummy struct to hold map's mmap data
struct TC_COMMON_API MMapData struct TC_COMMON_API MMapData
@@ -65,13 +66,13 @@ namespace MMAP
void InitializeThreadUnsafe(std::unordered_map<uint32, std::vector<uint32>> const& mapData); void InitializeThreadUnsafe(std::unordered_map<uint32, std::vector<uint32>> const& mapData);
bool loadMap(std::string const& basePath, uint32 mapId, int32 x, int32 y); bool loadMap(std::string const& basePath, uint32 mapId, int32 x, int32 y);
bool loadMapInstance(std::string const& basePath, uint32 mapId, uint32 instanceId); bool loadMapInstance(std::string const& basePath, uint32 meshMapId, uint32 instanceMapId, uint32 instanceId);
bool unloadMap(uint32 mapId, int32 x, int32 y); bool unloadMap(uint32 mapId, int32 x, int32 y);
bool unloadMap(uint32 mapId); bool unloadMap(uint32 mapId);
bool unloadMapInstance(uint32 mapId, uint32 instanceId); bool unloadMapInstance(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId);
// the returned [dtNavMeshQuery const*] is NOT threadsafe // the returned [dtNavMeshQuery const*] is NOT threadsafe
dtNavMeshQuery const* GetNavMeshQuery(uint32 mapId, uint32 instanceId); dtNavMeshQuery const* GetNavMeshQuery(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId);
dtNavMesh const* GetNavMesh(uint32 mapId); dtNavMesh const* GetNavMesh(uint32 mapId);
uint32 getLoadedTilesCount() const { return loadedTiles; } uint32 getLoadedTilesCount() const { return loadedTiles; }
+2 -4
View File
@@ -21,7 +21,6 @@
#include "CellImpl.h" #include "CellImpl.h"
#include "DatabaseEnv.h" #include "DatabaseEnv.h"
#include "DBCStores.h" #include "DBCStores.h"
#include "DisableMgr.h"
#include "DynamicTree.h" #include "DynamicTree.h"
#include "GameObjectModel.h" #include "GameObjectModel.h"
#include "GameTime.h" #include "GameTime.h"
@@ -34,7 +33,6 @@
#include "InstanceSaveMgr.h" #include "InstanceSaveMgr.h"
#include "Log.h" #include "Log.h"
#include "MapManager.h" #include "MapManager.h"
#include "MMapFactory.h"
#include "MiscPackets.h" #include "MiscPackets.h"
#include "MotionMaster.h" #include "MotionMaster.h"
#include "ObjectAccessor.h" #include "ObjectAccessor.h"
@@ -95,7 +93,7 @@ Map::~Map()
sOutdoorPvPMgr->DestroyOutdoorPvPForMap(this); sOutdoorPvPMgr->DestroyOutdoorPvPForMap(this);
sBattlefieldMgr->DestroyBattlefieldsForMap(this); sBattlefieldMgr->DestroyBattlefieldsForMap(this);
MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(GetId(), i_InstanceId); m_terrain->UnloadMMapInstance(GetId(), GetInstanceId());
} }
void Map::LoadAllCells() void Map::LoadAllCells()
@@ -150,7 +148,7 @@ i_scriptLock(false), _respawnCheckTimer(0)
sTransportMgr->CreateTransportsForMap(this); sTransportMgr->CreateTransportsForMap(this);
MMAP::MMapFactory::createOrGetMMapManager()->loadMapInstance(sWorld->GetDataPath(), GetId(), i_InstanceId); m_terrain->LoadMMapInstance(GetId(), GetInstanceId());
_worldStateValues = sWorldStateMgr->GetInitialWorldStatesForMap(this); _worldStateValues = sWorldStateMgr->GetInitialWorldStatesForMap(this);
+26
View File
@@ -163,6 +163,14 @@ void TerrainInfo::LoadMapAndVMap(int32 gx, int32 gy)
LoadMapAndVMapImpl(gx, gy); LoadMapAndVMapImpl(gx, gy);
} }
void TerrainInfo::LoadMMapInstance(uint32 mapId, uint32 instanceId)
{
LoadMMapInstanceImpl(mapId, instanceId);
for (std::shared_ptr<TerrainInfo> const& childTerrain : _childTerrain)
childTerrain->LoadMMapInstanceImpl(mapId, instanceId);
}
void TerrainInfo::LoadMapAndVMapImpl(int32 gx, int32 gy) void TerrainInfo::LoadMapAndVMapImpl(int32 gx, int32 gy)
{ {
LoadMap(gx, gy); LoadMap(gx, gy);
@@ -175,6 +183,11 @@ void TerrainInfo::LoadMapAndVMapImpl(int32 gx, int32 gy)
_loadedGrids[GetBitsetIndex(gx, gy)] = true; _loadedGrids[GetBitsetIndex(gx, gy)] = true;
} }
void TerrainInfo::LoadMMapInstanceImpl(uint32 mapId, uint32 instanceId)
{
MMAP::MMapFactory::createOrGetMMapManager()->loadMapInstance(sWorld->GetDataPath(), _mapId, mapId, instanceId);
}
void TerrainInfo::LoadMap(int32 gx, int32 gy) void TerrainInfo::LoadMap(int32 gx, int32 gy)
{ {
if (_gridMap[gx][gy]) if (_gridMap[gx][gy])
@@ -240,6 +253,14 @@ void TerrainInfo::UnloadMap(int32 gx, int32 gy)
// unload later // unload later
} }
void TerrainInfo::UnloadMMapInstance(uint32 mapId, uint32 instanceId)
{
UnloadMMapInstanceImpl(mapId, instanceId);
for (std::shared_ptr<TerrainInfo> const& childTerrain : _childTerrain)
childTerrain->UnloadMMapInstanceImpl(mapId, instanceId);
}
void TerrainInfo::UnloadMapImpl(int32 gx, int32 gy) void TerrainInfo::UnloadMapImpl(int32 gx, int32 gy)
{ {
_gridMap[gx][gy] = nullptr; _gridMap[gx][gy] = nullptr;
@@ -252,6 +273,11 @@ void TerrainInfo::UnloadMapImpl(int32 gx, int32 gy)
_loadedGrids[GetBitsetIndex(gx, gy)] = false; _loadedGrids[GetBitsetIndex(gx, gy)] = false;
} }
void TerrainInfo::UnloadMMapInstanceImpl(uint32 mapId, uint32 instanceId)
{
MMAP::MMapFactory::createOrGetMMapManager()->unloadMapInstance(_mapId, mapId, instanceId);
}
GridMap* TerrainInfo::GetGrid(uint32 mapId, float x, float y, bool loadIfMissing /*= true*/) GridMap* TerrainInfo::GetGrid(uint32 mapId, float x, float y, bool loadIfMissing /*= true*/)
{ {
// half opt method // half opt method
+4
View File
@@ -57,18 +57,22 @@ public:
void AddChildTerrain(std::shared_ptr<TerrainInfo> childTerrain); void AddChildTerrain(std::shared_ptr<TerrainInfo> childTerrain);
void LoadMapAndVMap(int32 gx, int32 gy); void LoadMapAndVMap(int32 gx, int32 gy);
void LoadMMapInstance(uint32 mapId, uint32 instanceId);
private: private:
void LoadMapAndVMapImpl(int32 gx, int32 gy); void LoadMapAndVMapImpl(int32 gx, int32 gy);
void LoadMMapInstanceImpl(uint32 mapId, uint32 instanceId);
void LoadMap(int32 gx, int32 gy); void LoadMap(int32 gx, int32 gy);
void LoadVMap(int32 gx, int32 gy); void LoadVMap(int32 gx, int32 gy);
void LoadMMap(int32 gx, int32 gy); void LoadMMap(int32 gx, int32 gy);
public: public:
void UnloadMap(int32 gx, int32 gy); void UnloadMap(int32 gx, int32 gy);
void UnloadMMapInstance(uint32 mapId, uint32 instanceId);
private: private:
void UnloadMapImpl(int32 gx, int32 gy); void UnloadMapImpl(int32 gx, int32 gy);
void UnloadMMapInstanceImpl(uint32 mapId, uint32 instanceId);
GridMap* GetGrid(uint32 mapId, float x, float y, bool loadIfMissing = true); GridMap* GetGrid(uint32 mapId, float x, float y, bool loadIfMissing = true);
+2 -2
View File
@@ -44,8 +44,8 @@ PathGenerator::PathGenerator(WorldObject const* owner) :
if (DisableMgr::IsPathfindingEnabled(mapId)) if (DisableMgr::IsPathfindingEnabled(mapId))
{ {
MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager(); MMAP::MMapManager* mmap = MMAP::MMapFactory::createOrGetMMapManager();
_navMesh = mmap->GetNavMesh(mapId); _navMeshQuery = mmap->GetNavMeshQuery(mapId, _source->GetMapId(), _source->GetInstanceId());
_navMeshQuery = mmap->GetNavMeshQuery(mapId, _source->GetInstanceId()); _navMesh = _navMeshQuery ? _navMeshQuery->getAttachedNavMesh() : mmap->GetNavMesh(mapId);
} }
CreateFilter(); CreateFilter();
+2 -2
View File
@@ -141,7 +141,7 @@ public:
// calculate navmesh tile location // calculate navmesh tile location
uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMapId(), player->GetMap()->GetTerrain(), x, y); uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMapId(), player->GetMap()->GetTerrain(), x, y);
dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(terrainMapId); dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(terrainMapId);
dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(terrainMapId, player->GetInstanceId()); dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(terrainMapId, player->GetMapId(), player->GetInstanceId());
if (!navmesh || !navmeshquery) if (!navmesh || !navmeshquery)
{ {
handler->PSendSysMessage("NavMesh not loaded for current map."); handler->PSendSysMessage("NavMesh not loaded for current map.");
@@ -192,7 +192,7 @@ public:
Player* player = handler->GetSession()->GetPlayer(); Player* player = handler->GetSession()->GetPlayer();
uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMapId(), player->GetMap()->GetTerrain(), player->GetPositionX(), player->GetPositionY()); uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMapId(), player->GetMap()->GetTerrain(), player->GetPositionX(), player->GetPositionY());
dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(terrainMapId); dtNavMesh const* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(terrainMapId);
dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(terrainMapId, player->GetInstanceId()); dtNavMeshQuery const* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(terrainMapId, player->GetMapId(), player->GetInstanceId());
if (!navmesh || !navmeshquery) if (!navmesh || !navmeshquery)
{ {
handler->PSendSysMessage("NavMesh not loaded for current map."); handler->PSendSysMessage("NavMesh not loaded for current map.");