From f7ae161e3d52facba0e0a7168de077b211a24e46 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Wed, 13 Sep 2023 20:46:16 -0400 Subject: [PATCH] Core/MMaps: Fixed pathing for objects that have terrain swaps active Port From (https://github.com/TrinityCore/TrinityCore/commit/86725ed9267803506d8a5cab04c2c5641a234dd9) --- Source/Game/Chat/Commands/MMapsCommands.cs | 4 +-- Source/Game/Maps/MMapManager.cs | 36 +++++++++---------- Source/Game/Maps/Map.cs | 4 +-- Source/Game/Maps/TerrainManager.cs | 26 ++++++++++++++ .../Game/Movement/Generators/PathGenerator.cs | 4 +-- 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/Source/Game/Chat/Commands/MMapsCommands.cs b/Source/Game/Chat/Commands/MMapsCommands.cs index ce43be301..025bcef74 100644 --- a/Source/Game/Chat/Commands/MMapsCommands.cs +++ b/Source/Game/Chat/Commands/MMapsCommands.cs @@ -96,7 +96,7 @@ namespace Game.Chat // calculate navmesh tile location uint terrainMapId = PhasingHandler.GetTerrainMapId(player.GetPhaseShift(), player.GetMapId(), player.GetMap().GetTerrain(), x, y); Detour.dtNavMesh navmesh = Global.MMapMgr.GetNavMesh(terrainMapId); - Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(terrainMapId, player.GetInstanceId()); + Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(terrainMapId, player.GetMapId(), player.GetInstanceId()); if (navmesh == null || navmeshquery == null) { handler.SendSysMessage("NavMesh not loaded for current map."); @@ -148,7 +148,7 @@ namespace Game.Chat Player player = handler.GetSession().GetPlayer(); uint terrainMapId = PhasingHandler.GetTerrainMapId(player.GetPhaseShift(), player.GetMapId(), player.GetMap().GetTerrain(), player.GetPositionX(), player.GetPositionY()); Detour.dtNavMesh navmesh = Global.MMapMgr.GetNavMesh(terrainMapId); - Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(terrainMapId, handler.GetPlayer().GetInstanceId()); + Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(terrainMapId, player.GetMapId(), player.GetInstanceId()); if (navmesh == null || navmeshquery == null) { handler.SendSysMessage("NavMesh not loaded for current map."); diff --git a/Source/Game/Maps/MMapManager.cs b/Source/Game/Maps/MMapManager.cs index ed85e6e00..7920cec14 100644 --- a/Source/Game/Maps/MMapManager.cs +++ b/Source/Game/Maps/MMapManager.cs @@ -132,25 +132,25 @@ namespace Game return false; } - public bool LoadMapInstance(string basePath, uint mapId, uint instanceId) + public bool LoadMapInstance(string basePath, uint meshMapId, uint instanceMapId, uint instanceId) { - if (!LoadMapData(basePath, mapId)) + if (!LoadMapData(basePath, meshMapId)) return false; - MMapData mmap = loadedMMaps[mapId]; - if (mmap.navMeshQueries.ContainsKey(instanceId)) + MMapData mmap = loadedMMaps[meshMapId]; + if (mmap.navMeshQueries.ContainsKey((instanceMapId, instanceId))) return true; // allocate mesh query Detour.dtNavMeshQuery query = new(); if (Detour.dtStatusFailed(query.init(mmap.navMesh, 1024))) { - Log.outError(LogFilter.Maps, "MMAP.GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId {0:D4} instanceId {1}", mapId, instanceId); + Log.outError(LogFilter.Maps, $"MMAP.GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId {instanceMapId:D4} instanceId {instanceId}"); return false; } - Log.outDebug(LogFilter.Maps, "MMAP.GetNavMeshQuery: created dtNavMeshQuery for mapId {0:D4} instanceId {1}", mapId, instanceId); - mmap.navMeshQueries.Add(instanceId, query); + Log.outDebug(LogFilter.Maps, $"MMAP.GetNavMeshQuery: created dtNavMeshQuery for mapId {instanceMapId:D4} instanceId {instanceId}"); + mmap.navMeshQueries.Add((instanceMapId, instanceId), query); return true; } @@ -226,25 +226,25 @@ namespace Game return true; } - public bool UnloadMapInstance(uint mapId, uint instanceId) + public bool UnloadMapInstance(uint meshMapId, uint instanceMapId, uint instanceId) { // check if we have this map loaded - MMapData mmap = GetMMapData(mapId); + MMapData mmap = GetMMapData(meshMapId); if (mmap == null) { // file may not exist, therefore not loaded - Log.outDebug(LogFilter.Maps, "MMAP:unloadMapInstance: Asked to unload not loaded navmesh map {0}", mapId); + Log.outDebug(LogFilter.Maps, $"MMAP:unloadMapInstance: Asked to unload not loaded navmesh map {meshMapId}"); return false; } - if (!mmap.navMeshQueries.ContainsKey(instanceId)) + if (!mmap.navMeshQueries.ContainsKey((instanceMapId, instanceId))) { - Log.outDebug(LogFilter.Maps, "MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId {0} instanceId {1}", mapId, instanceId); + Log.outDebug(LogFilter.Maps, $"MMAP:unloadMapInstance: Asked to unload not loaded dtNavMeshQuery mapId {instanceMapId} instanceId {instanceId}"); return false; } - mmap.navMeshQueries.Remove(instanceId); - Log.outInfo(LogFilter.Maps, "MMAP:unloadMapInstance: Unloaded mapId {0} instanceId {1}", mapId, instanceId); + mmap.navMeshQueries.Remove((instanceMapId, instanceId)); + Log.outInfo(LogFilter.Maps, $"MMAP:unloadMapInstance: Unloaded mapId {instanceMapId} instanceId {instanceId}"); return true; } @@ -258,13 +258,13 @@ namespace Game return mmap.navMesh; } - public Detour.dtNavMeshQuery GetNavMeshQuery(uint mapId, uint instanceId) + public Detour.dtNavMeshQuery GetNavMeshQuery(uint meshMapId, uint instanceMapId, uint instanceId) { - MMapData mmap = GetMMapData(mapId); + MMapData mmap = GetMMapData(meshMapId); if (mmap == null) return null; - return mmap.navMeshQueries.LookupByKey(instanceId); + return mmap.navMeshQueries.LookupByKey((instanceMapId, instanceId)); } public uint GetLoadedTilesCount() { return loadedTiles; } @@ -283,7 +283,7 @@ namespace Game navMesh = mesh; } - public Dictionary navMeshQueries = new(); // instanceId to query + public Dictionary<(uint, uint), Detour.dtNavMeshQuery> navMeshQueries = new(); // instanceId to query public Detour.dtNavMesh navMesh; public Dictionary loadedTileRefs = new(); // maps [map grid coords] to [dtTile] diff --git a/Source/Game/Maps/Map.cs b/Source/Game/Maps/Map.cs index 04bb745d5..f6d86d6e8 100644 --- a/Source/Game/Maps/Map.cs +++ b/Source/Game/Maps/Map.cs @@ -56,7 +56,7 @@ namespace Game.Maps Global.TransportMgr.CreateTransportsForMap(this); - Global.MMapMgr.LoadMapInstance(Global.WorldMgr.GetDataPath(), GetId(), i_InstanceId); + m_terrain.LoadMMapInstance(GetId(), GetInstanceId()); _worldStateValues = Global.WorldStateMgr.GetInitialWorldStatesForMap(this); @@ -88,7 +88,7 @@ namespace Game.Maps Global.OutdoorPvPMgr.DestroyOutdoorPvPForMap(this); Global.BattleFieldMgr.DestroyBattlefieldsForMap(this); - Global.MMapMgr.UnloadMapInstance(GetId(), i_InstanceId); + m_terrain.UnloadMMapInstance(GetId(), GetInstanceId()); } public void LoadAllCells() diff --git a/Source/Game/Maps/TerrainManager.cs b/Source/Game/Maps/TerrainManager.cs index f9a986f31..d6d3ddc96 100644 --- a/Source/Game/Maps/TerrainManager.cs +++ b/Source/Game/Maps/TerrainManager.cs @@ -270,6 +270,14 @@ namespace Game.Maps LoadMapAndVMapImpl(gx, gy); } + public void LoadMMapInstance(uint mapId, uint instanceId) + { + LoadMMapInstanceImpl(mapId, instanceId); + + foreach (var childTerrain in _childTerrain) + childTerrain.LoadMMapInstanceImpl(mapId, instanceId); + } + public void LoadMapAndVMapImpl(int gx, int gy) { LoadMap(gx, gy); @@ -282,6 +290,11 @@ namespace Game.Maps _loadedGrids[GetBitsetIndex(gx, gy)] = true; } + void LoadMMapInstanceImpl(uint mapId, uint instanceId) + { + Global.MMapMgr.LoadMapInstance(Global.WorldMgr.GetDataPath(), _mapId, mapId, instanceId); + } + public void LoadMap(int gx, int gy) { if (_gridMap[gx][gy] != null) @@ -346,6 +359,14 @@ namespace Game.Maps // unload later } + public void UnloadMMapInstance(uint mapId, uint instanceId) + { + UnloadMMapInstanceImpl(mapId, instanceId); + + foreach (var childTerrain in _childTerrain) + childTerrain.UnloadMMapInstanceImpl(mapId, instanceId); + } + public void UnloadMapImpl(int gx, int gy) { _gridMap[gx][gy] = null; @@ -358,6 +379,11 @@ namespace Game.Maps _loadedGrids[GetBitsetIndex(gx, gy)] = false; } + void UnloadMMapInstanceImpl(uint mapId, uint instanceId) + { + Global.MMapMgr.UnloadMapInstance(_mapId, mapId, instanceId); + } + public GridMap GetGrid(uint mapId, float x, float y, bool loadIfMissing = true) { // half opt method diff --git a/Source/Game/Movement/Generators/PathGenerator.cs b/Source/Game/Movement/Generators/PathGenerator.cs index 71808f27f..ef1c84188 100644 --- a/Source/Game/Movement/Generators/PathGenerator.cs +++ b/Source/Game/Movement/Generators/PathGenerator.cs @@ -27,8 +27,8 @@ namespace Game.Movement uint mapId = PhasingHandler.GetTerrainMapId(_source.GetPhaseShift(), _source.GetMapId(), _source.GetMap().GetTerrain(), _source.GetPositionX(), _source.GetPositionY()); if (Global.DisableMgr.IsPathfindingEnabled(_source.GetMapId())) { - _navMesh = Global.MMapMgr.GetNavMesh(mapId); - _navMeshQuery = Global.MMapMgr.GetNavMeshQuery(mapId, _source.GetInstanceId()); + _navMeshQuery = Global.MMapMgr.GetNavMeshQuery(mapId, _source.GetMapId(), _source.GetInstanceId()); + _navMesh = _navMeshQuery?.getAttachedNavMesh() ?? Global.MMapMgr.GetNavMesh(mapId); } CreateFilter(); }