diff --git a/Source/Game/Chat/Commands/MMapsCommands.cs b/Source/Game/Chat/Commands/MMapsCommands.cs index 1fd1471cb..8ce5e7796 100644 --- a/Source/Game/Chat/Commands/MMapsCommands.cs +++ b/Source/Game/Chat/Commands/MMapsCommands.cs @@ -30,7 +30,7 @@ namespace Game.Chat [Command("path", RBACPermissions.CommandMmapPath)] static bool PathCommand(StringArguments args, CommandHandler handler) { - if (Global.MMapMgr.GetNavMesh(handler.GetPlayer().GetMapId(), handler.GetSession().GetPlayer().GetTerrainSwaps()) == null) + if (Global.MMapMgr.GetNavMesh(handler.GetPlayer().GetMapId()) == null) { handler.SendSysMessage("NavMesh not loaded for current map."); return true; @@ -103,8 +103,8 @@ namespace Game.Chat handler.SendSysMessage("gridloc [{0}, {1}]", gx, gy); // calculate navmesh tile location - Detour.dtNavMesh navmesh = Global.MMapMgr.GetNavMesh(handler.GetPlayer().GetMapId(), handler.GetSession().GetPlayer().GetTerrainSwaps()); - Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(handler.GetPlayer().GetMapId(), player.GetInstanceId(), handler.GetSession().GetPlayer().GetTerrainSwaps()); + Detour.dtNavMesh navmesh = Global.MMapMgr.GetNavMesh(handler.GetPlayer().GetMapId()); + Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(handler.GetPlayer().GetMapId(), player.GetInstanceId()); if (navmesh == null || navmeshquery == null) { handler.SendSysMessage("NavMesh not loaded for current map."); @@ -156,8 +156,8 @@ namespace Game.Chat static bool LoadedTilesCommand(StringArguments args, CommandHandler handler) { uint mapid = handler.GetPlayer().GetMapId(); - Detour.dtNavMesh navmesh = Global.MMapMgr.GetNavMesh(mapid, handler.GetSession().GetPlayer().GetTerrainSwaps()); - Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(mapid, handler.GetPlayer().GetInstanceId(), handler.GetSession().GetPlayer().GetTerrainSwaps()); + Detour.dtNavMesh navmesh = Global.MMapMgr.GetNavMesh(mapid); + Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(mapid, handler.GetPlayer().GetInstanceId()); if (navmesh == null || navmeshquery == null) { handler.SendSysMessage("NavMesh not loaded for current map."); @@ -185,7 +185,7 @@ namespace Game.Chat handler.SendSysMessage(" global mmap pathfinding is {0}abled", Global.DisableMgr.IsPathfindingEnabled(mapId) ? "En" : "Dis"); handler.SendSysMessage(" {0} maps loaded with {1} tiles overall", Global.MMapMgr.getLoadedMapsCount(), Global.MMapMgr.getLoadedTilesCount()); - Detour.dtNavMesh navmesh = Global.MMapMgr.GetNavMesh(handler.GetPlayer().GetMapId(), handler.GetSession().GetPlayer().GetTerrainSwaps()); + Detour.dtNavMesh navmesh = Global.MMapMgr.GetNavMesh(handler.GetPlayer().GetMapId()); if (navmesh == null) { handler.SendSysMessage("NavMesh not loaded for current map."); diff --git a/Source/Game/Chat/Commands/MiscCommands.cs b/Source/Game/Chat/Commands/MiscCommands.cs index b58d31794..8bedacf0c 100644 --- a/Source/Game/Chat/Commands/MiscCommands.cs +++ b/Source/Game/Chat/Commands/MiscCommands.cs @@ -206,7 +206,7 @@ namespace Game.Chat bool haveMap = Map.ExistMap(mapId, gridX, gridY); bool haveVMap = Map.ExistVMap(mapId, gridX, gridY); - bool haveMMap = (Global.DisableMgr.IsPathfindingEnabled(mapId) && Global.MMapMgr.GetNavMesh(handler.GetSession().GetPlayer().GetMapId(), handler.GetSession().GetPlayer().GetTerrainSwaps()) != null); + bool haveMMap = (Global.DisableMgr.IsPathfindingEnabled(mapId) && Global.MMapMgr.GetNavMesh(handler.GetSession().GetPlayer().GetMapId()) != null); if (haveVMap) { diff --git a/Source/Game/Maps/MMapManager.cs b/Source/Game/Maps/MMapManager.cs index 83ccf2266..b1eb9d6bb 100644 --- a/Source/Game/Maps/MMapManager.cs +++ b/Source/Game/Maps/MMapManager.cs @@ -34,15 +34,6 @@ namespace Game const string MAP_FILE_NAME_FORMAT = "{0}/mmaps/{1:D4}.mmap"; const string TILE_FILE_NAME_FORMAT = "{0}/mmaps/{1:D4}{2:D2}{3:D2}.mmtile"; - public void Initialize() - { - foreach (MapRecord mapEntry in CliDB.MapStorage.Values) - { - if (mapEntry.ParentMapID != -1) - phaseMapData.Add((uint)mapEntry.ParentMapID, mapEntry.Id); - } - } - MMapData GetMMapData(uint mapId) { return loadedMMaps.LookupByKey(mapId); @@ -84,7 +75,7 @@ namespace Game Log.outInfo(LogFilter.Maps, "MMAP:loadMapData: Loaded {0:D4}.mmap", mapId); // store inside our map list - loadedMMaps[mapId] = new MMapData(mesh, mapId); + loadedMMaps[mapId] = new MMapData(mesh); return true; } } @@ -145,14 +136,6 @@ namespace Game mmap.loadedTileRefs.Add(packedGridPos, tileRef); ++loadedTiles; Log.outInfo(LogFilter.Maps, "MMAP:loadMap: Loaded mmtile {0:D4}[{1:D2}, {2:D2}]", mapId, x, y); - - var phasedMaps = phaseMapData.LookupByKey(mapId); - if (!phasedMaps.Empty()) - { - mmap.AddBaseTile(packedGridPos, data, fileHeader, fileHeader.size); - LoadPhaseTiles(phasedMaps, x, y); - } - return true; } @@ -161,89 +144,6 @@ namespace Game } } - PhasedTile LoadTile(uint mapId, int x, int y) - { - // load this tile . mmaps/MMMXXYY.mmtile - string filename = string.Format(TILE_FILE_NAME_FORMAT, Global.WorldMgr.GetDataPath(), mapId, x, y); - if (!File.Exists(filename)) - { - // Not all tiles have phased versions, don't flood this msg - return null; - } - PhasedTile pTile = new PhasedTile(); - - using (BinaryReader reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read))) - { - // read header - pTile.fileHeader = reader.ReadStruct(); - Array.Reverse(pTile.fileHeader.mmapMagic); - if (new string(pTile.fileHeader.mmapMagic) != MapConst.mmapMagic) - { - Log.outError(LogFilter.Maps, "MMAP.LoadTile: Bad header in mmap {0:D4}{1:D2}{2:D2}.mmtile", mapId, x, y); - return null; - } - - if (pTile.fileHeader.mmapVersion != MapConst.mmapVersion) - { - Log.outError(LogFilter.Maps, "MMAP:LoadTile: {0:D4}{1:D2}{2:D2}.mmtile was built with generator v{3}, expected v{4}", mapId, x, y, pTile.fileHeader.mmapVersion, MapConst.mmapVersion); - return null; - } - - pTile.data = new Detour.dtRawTileData(); - pTile.data.FromBytes(reader.ReadBytes((int)pTile.fileHeader.size), 0); - - if (pTile.data.ToBytes().Length == 0) - { - Log.outError(LogFilter.Maps, "MMAP.LoadTile: Bad header or data in mmap {0:D4}{1:D2}{2:D2}.mmtile", mapId, x, y); - return null; - } - } - - return pTile; - } - - void LoadPhaseTiles(List phasedMapData, int x, int y) - { - Log.outDebug(LogFilter.Maps, "MMAP.LoadPhaseTiles: Loading phased mmtiles for map {0}, X: {1}, Y: {2}", phasedMapData.FirstOrDefault(), x, y); - - uint packedGridPos = packTileID(x, y); - - foreach (uint phaseMapId in phasedMapData) - { - PhasedTile data = LoadTile(phaseMapId, x, y); - // only a few tiles have terrain swaps, do not write error for them - if (data != null) - { - Log.outDebug(LogFilter.Maps, "MMAP.LoadPhaseTiles: Loaded phased {0:D4}{1:D2}{2:D2}.mmtile for root phase map {3}", phaseMapId, x, y, phasedMapData.FirstOrDefault()); - if (!_phaseTiles.ContainsKey(phaseMapId)) - _phaseTiles[phaseMapId] = new Dictionary(); - - _phaseTiles[phaseMapId][packedGridPos] = data; - } - } - } - - void UnloadPhaseTile(List phasedMapData, int x, int y) - { - Log.outDebug(LogFilter.Maps, "MMAP.UnloadPhaseTile: Unloading phased mmtile for map {0}, X: {1}, Y: {2}", phasedMapData.FirstOrDefault(), x, y); - - uint packedGridPos = packTileID(x, y); - - foreach (uint phaseMapId in phasedMapData.ToList()) - { - var phasedTileDic = _phaseTiles.LookupByKey(phaseMapId); - if (phasedTileDic == null) - continue; - - var phaseTile = phasedTileDic.LookupByKey(packedGridPos); - if (phaseTile != null) - { - Log.outDebug(LogFilter.Maps, "MMAP.UnloadPhaseTile: Unloaded phased {0:D4}{1:D2}{2:D2}.mmtile for root phase map {3}", phaseMapId, x, y, phasedMapData.FirstOrDefault()); - phasedTileDic.Remove(packedGridPos); - } - } - } - public bool unloadMap(uint mapId, uint x, uint y) { // check if we have this map loaded @@ -281,13 +181,6 @@ namespace Game mmap.loadedTileRefs.Remove(packedGridPos); --loadedTiles; Log.outInfo(LogFilter.Maps, "MMAP:unloadMap: Unloaded mmtile {0:D4}[{1:D2}, {2:D2}] from {3:D4}", mapId, x, y, mapId); - - var phasedMaps = phaseMapData.LookupByKey(mapId); - if (!phasedMaps.Empty()) - { - mmap.DeleteBaseTile(packedGridPos); - UnloadPhaseTile(phasedMaps, (int)x, (int)y); - } return true; } @@ -314,12 +207,6 @@ namespace Game Log.outError(LogFilter.Maps, "MMAP:unloadMap: Could not unload {0:D4}{1:D2}{2:D2}.mmtile from navmesh", mapId, x, y); else { - var phasedMaps = phaseMapData.LookupByKey(mapId); - if (!phasedMaps.Empty()) - { - mmap.DeleteBaseTile(i.Key); - UnloadPhaseTile(phasedMaps, (int)x, (int)y); - } --loadedTiles; Log.outInfo(LogFilter.Maps, "MMAP:unloadMap: Unloaded mmtile {0:D4} [{1:D2}, {2:D2}] from {3:D4}", mapId, x, y, mapId); } @@ -354,16 +241,16 @@ namespace Game return true; } - public Detour.dtNavMesh GetNavMesh(uint mapId, List swaps) + public Detour.dtNavMesh GetNavMesh(uint mapId) { MMapData mmap = GetMMapData(mapId); if (mmap == null) return null; - return mmap.GetNavMesh(swaps); + return mmap.navMesh; } - public Detour.dtNavMeshQuery GetNavMeshQuery(uint mapId, uint instanceId, List swaps) + public Detour.dtNavMeshQuery GetNavMeshQuery(uint mapId, uint instanceId) { MMapData mmap = GetMMapData(mapId); if (mmap == null) @@ -373,7 +260,7 @@ namespace Game { // allocate mesh query Detour.dtNavMeshQuery query = new Detour.dtNavMeshQuery(); - if (Detour.dtStatusFailed(query.init(mmap.GetNavMesh(swaps), 1024))) + if (Detour.dtStatusFailed(query.init(mmap.navMesh, 1024))) { Log.outError(LogFilter.Maps, "MMAP:GetNavMeshQuery: Failed to initialize dtNavMeshQuery for mapId {0} instanceId {1}", mapId, instanceId); return null; @@ -389,181 +276,21 @@ namespace Game public uint getLoadedTilesCount() { return loadedTiles; } public int getLoadedMapsCount() { return loadedMMaps.Count; } - public Dictionary GetPhaseTileContainer(uint mapId) { return _phaseTiles.LookupByKey(mapId); } - Dictionary loadedMMaps = new Dictionary(); - MultiMap phaseMapData = new MultiMap(); - Dictionary> _phaseTiles = new Dictionary>(); uint loadedTiles; } public class MMapData { - public MMapData(Detour.dtNavMesh mesh, uint mapId) + public MMapData(Detour.dtNavMesh mesh) { navMesh = mesh; - _mapId = mapId; - } - - void RemoveSwap(PhasedTile ptile, uint swap, uint packedXY) - { - uint x = (packedXY >> 16); - uint y = (packedXY & 0x0000FFFF); - - if (!loadedPhasedTiles[swap].Contains(packedXY)) - { - Log.outDebug(LogFilter.Maps, "MMapData.RemoveSwap: mmtile {0:D4}[{1:D2}, {2:D2}] unload skipped, due to not loaded", swap, x, y); - return; - } - Detour.dtMeshHeader header = ptile.data.header; - - Detour.dtRawTileData data; - // remove old tile - if (Detour.dtStatusFailed(navMesh.removeTile(loadedTileRefs[packedXY], out data))) - Log.outError(LogFilter.Maps, "MMapData.RemoveSwap: Could not unload phased {0:D4}{1:D2}{2:D2}.mmtile from navmesh", swap, x, y); - else - { - Log.outDebug(LogFilter.Maps, "MMapData.RemoveSwap: Unloaded phased {0:D4}{1:D2}{2:D2}.mmtile from navmesh", swap, x, y); - - // restore base tile - ulong loadedRef = 0; - if (Detour.dtStatusSucceed(navMesh.addTile(_baseTiles[packedXY].data, 0, 0, ref loadedRef))) - { - Log.outDebug(LogFilter.Maps, "MMapData.RemoveSwap: Loaded base mmtile {0:D4}[{1:D2}, {2:D2}] into {0:D4}[{1:D2}, {2:D2}]", _mapId, x, y, _mapId, header.x, header.y); - } - else - Log.outError(LogFilter.Maps, "MMapData.RemoveSwap: Could not load base {0:D4}{1:D2}{2:D2}.mmtile to navmesh", _mapId, x, y); - - loadedTileRefs[packedXY] = loadedRef; - } - - loadedPhasedTiles.Remove(swap, packedXY); - - if (loadedPhasedTiles[swap].Empty()) - { - _activeSwaps.Remove(swap); - Log.outDebug(LogFilter.Maps, "MMapData.RemoveSwap: Fully removed swap {0} from map {1}", swap, _mapId); - } - } - - void AddSwap(PhasedTile ptile, uint swap, uint packedXY) - { - uint x = (packedXY >> 16); - uint y = (packedXY & 0x0000FFFF); - - if (!loadedTileRefs.ContainsKey(packedXY)) - { - Log.outDebug(LogFilter.Maps, "MMapData.AddSwap: phased mmtile {0:D4}[{1:D2}, {2:D2}] load skipped, due to not loaded base tile on map {3}", swap, x, y, _mapId); - return; - } - if (loadedPhasedTiles[swap].Contains(packedXY)) - { - Log.outDebug(LogFilter.Maps, "MMapData.AddSwap: WARNING! phased mmtile {0:D4}[{1:D2}, {2:D2}] load skipped, due to already loaded on map {3}", swap, x, y, _mapId); - return; - } - - Detour.dtMeshHeader header = ptile.data.header; - - Detour.dtMeshTile oldTile = navMesh.getTileByRef(loadedTileRefs[packedXY]); - if (oldTile == null) - { - Log.outDebug(LogFilter.Maps, "MMapData.AddSwap: phased mmtile {0:D4}[{1:D2}, {2:D2}] load skipped, due to not loaded base tile ref on map {3}", swap, x, y, _mapId); - return; - } - - // header xy is based on the swap map's tile set, wich doesn't have all the same tiles as root map, so copy the xy from the orignal header - header.x = oldTile.header.x; - header.y = oldTile.header.y; - - Detour.dtRawTileData data; - // remove old tile - if (Detour.dtStatusFailed(navMesh.removeTile(loadedTileRefs[packedXY], out data))) - Log.outError(LogFilter.Maps, "MMapData.AddSwap: Could not unload {0:D4}{1:D2}{2:D2}.mmtile from navmesh", _mapId, x, y); - else - { - Log.outDebug(LogFilter.Maps, "MMapData.AddSwap: Unloaded {0:D4}{1:D2}{2:D2}.mmtile from navmesh", _mapId, x, y); - - _activeSwaps.Add(swap); - loadedPhasedTiles.Add(swap, packedXY); - - // add new swapped tile - ulong loadedRef = 0; - if (Detour.dtStatusSucceed(navMesh.addTile(ptile.data, 0, 0, ref loadedRef))) - Log.outDebug(LogFilter.Maps, "MMapData.AddSwap: Loaded phased mmtile {0:D4}[{1:D2}, {2:D2}] into {0:D4}[{1:D2}, {2:D2}]", swap, x, y, _mapId, header.x, header.y); - else - Log.outError(LogFilter.Maps, "MMapData.AddSwap: Could not load {0:D4}{1:D2}{2:D2}.mmtile to navmesh", swap, x, y); - - loadedTileRefs[packedXY] = loadedRef; - } - } - - public Detour.dtNavMesh GetNavMesh(List swaps) - { - foreach (uint swap in _activeSwaps) - { - if (!swaps.Contains(swap)) // swap not active - { - var ptc = Global.MMapMgr.GetPhaseTileContainer(swap); - foreach (var pair in ptc) - RemoveSwap(pair.Value, swap, pair.Key); // remove swap - } - } - - // for each of the calling unit's terrain swaps - foreach (uint swap in swaps) - { - if (!_activeSwaps.Contains(swap)) // swap not active - { - // for each of the terrain swap's xy tiles - var ptc = Global.MMapMgr.GetPhaseTileContainer(swap); - if (ptc != null) - { - foreach (var pair in ptc) - AddSwap(pair.Value, swap, pair.Key); // add swap - } - } - } - - return navMesh; - } - - public void AddBaseTile(uint packedGridPos, Detour.dtRawTileData data, MmapTileHeader fileHeader, uint dataSize) - { - if (!_baseTiles.ContainsKey(packedGridPos)) - { - PhasedTile phasedTile = new PhasedTile(); - phasedTile.data = data; - phasedTile.fileHeader = fileHeader; - phasedTile.dataSize = (int)dataSize; - _baseTiles[packedGridPos] = phasedTile; - } - } - - public void DeleteBaseTile(uint packedGridPos) - { - var phaseTile = _baseTiles.LookupByKey(packedGridPos); - if (phaseTile != null) - { - _baseTiles.Remove(packedGridPos); - } } public Dictionary navMeshQueries = new Dictionary(); // instanceId to query public Detour.dtNavMesh navMesh; - public Dictionary loadedTileRefs = new Dictionary(); - MultiMap loadedPhasedTiles = new MultiMap(); - - uint _mapId; - Dictionary _baseTiles = new Dictionary(); - List _activeSwaps = new List(); - } - - public class PhasedTile - { - public Detour.dtRawTileData data; - public MmapTileHeader fileHeader; - public int dataSize; + public Dictionary loadedTileRefs = new Dictionary(); // maps [map grid coords] to [dtTile] } [StructLayout(LayoutKind.Sequential)] diff --git a/Source/Game/Movement/Generators/PathGenerator.cs b/Source/Game/Movement/Generators/PathGenerator.cs index 800491a1b..c91fc8a7a 100644 --- a/Source/Game/Movement/Generators/PathGenerator.cs +++ b/Source/Game/Movement/Generators/PathGenerator.cs @@ -42,8 +42,8 @@ namespace Game.Movement uint mapId = _sourceUnit.GetMapId(); if (Global.DisableMgr.IsPathfindingEnabled(mapId)) { - _navMesh = Global.MMapMgr.GetNavMesh(mapId, _sourceUnit.GetTerrainSwaps()); - _navMeshQuery = Global.MMapMgr.GetNavMeshQuery(mapId, _sourceUnit.GetInstanceId(), _sourceUnit.GetTerrainSwaps()); + _navMesh = Global.MMapMgr.GetNavMesh(mapId); + _navMeshQuery = Global.MMapMgr.GetNavMeshQuery(mapId, _sourceUnit.GetInstanceId()); } CreateFilter(); } diff --git a/Source/Game/Server/WorldManager.cs b/Source/Game/Server/WorldManager.cs index ab0900457..9ff52665b 100644 --- a/Source/Game/Server/WorldManager.cs +++ b/Source/Game/Server/WorldManager.cs @@ -357,8 +357,6 @@ namespace Game //Load weighted graph on taxi nodes path Global.TaxiPathGraph.Initialize(); - Global.MMapMgr.Initialize(); - Log.outInfo(LogFilter.ServerLoading, "Loading SpellInfo Storage..."); Global.SpellMgr.LoadSpellInfoStore();