diff --git a/Source/Game/Chat/Commands/MMapsCommands.cs b/Source/Game/Chat/Commands/MMapsCommands.cs index a08037108..5838e538d 100644 --- a/Source/Game/Chat/Commands/MMapsCommands.cs +++ b/Source/Game/Chat/Commands/MMapsCommands.cs @@ -90,11 +90,12 @@ namespace Game.Chat float x, y, z; player.GetPosition(out x, out y, out z); - handler.SendSysMessage("{0:D4}{1:D2}{2:D2}.mmtile", player.GetMapId(), gy, gx); - handler.SendSysMessage("tileloc [{0}, {1}]", gx, gy); - // calculate navmesh tile location uint terrainMapId = PhasingHandler.GetTerrainMapId(player.GetPhaseShift(), player.GetMapId(), player.GetMap().GetTerrain(), x, y); + + handler.SendSysMessage($"{terrainMapId:D4}{gx:D2}{gy:D2}.mmtile"); + handler.SendSysMessage($"tileloc [{gy}, {gx}]"); + Detour.dtNavMesh navmesh = Global.MMapMgr.GetNavMesh(terrainMapId); Detour.dtNavMeshQuery navmeshquery = Global.MMapMgr.GetNavMeshQuery(terrainMapId, player.GetMapId(), player.GetInstanceId()); if (navmesh == null || navmeshquery == null) diff --git a/Source/Game/Maps/MMapManager.cs b/Source/Game/Maps/MMapManager.cs index 7920cec14..78abf3da9 100644 --- a/Source/Game/Maps/MMapManager.cs +++ b/Source/Game/Maps/MMapManager.cs @@ -27,18 +27,18 @@ namespace Game return loadedMMaps.LookupByKey(mapId); } - bool LoadMapData(string basePath, uint mapId) + LoadResult LoadMapData(string basePath, uint mapId) { // we already have this map loaded? if (loadedMMaps.ContainsKey(mapId) && loadedMMaps[mapId] != null) - return true; + return LoadResult.AlreadyLoaded; // load and init dtNavMesh - read parameters from file string filename = string.Format(MAP_FILE_NAME_FORMAT, basePath, mapId); if (!File.Exists(filename)) { - Log.outError(LogFilter.Maps, "Could not open mmap file {0}", filename); - return false; + Log.outError(LogFilter.Maps, $"Could not open mmap file {filename}"); + return LoadResult.FileNotFound; } using BinaryReader reader = new(new FileStream(filename, FileMode.Open, FileAccess.Read), Encoding.UTF8); @@ -56,14 +56,14 @@ namespace Game if (Detour.dtStatusFailed(mesh.init(Params))) { Log.outError(LogFilter.Maps, "MMAP:loadMapData: Failed to initialize dtNavMesh for mmap {0:D4} from file {1}", mapId, filename); - return false; + return LoadResult.LibraryError; } Log.outInfo(LogFilter.Maps, "MMAP:loadMapData: Loaded {0:D4}.mmap", mapId); // store inside our map list loadedMMaps[mapId] = new MMapData(mesh); - return true; + return LoadResult.Success; } uint PackTileID(int x, int y) @@ -71,11 +71,18 @@ namespace Game return (uint)(x << 16 | y); } - public bool LoadMap(string basePath, uint mapId, int x, int y) + public LoadResult LoadMap(string basePath, uint mapId, int x, int y) { // make sure the mmap is loaded and ready to load tiles - if (!LoadMapData(basePath, mapId)) - return false; + LoadResult mapResult = LoadMapData(basePath, mapId); + switch (mapResult) + { + case LoadResult.Success: + case LoadResult.AlreadyLoaded: + break; + default: + return mapResult; + } // get this mmap data MMapData mmap = loadedMMaps[mapId]; @@ -84,7 +91,7 @@ namespace Game // check if we already have this tile loaded uint packedGridPos = PackTileID(x, y); if (mmap.loadedTileRefs.ContainsKey(packedGridPos)) - return false; + return LoadResult.AlreadyLoaded; // load this tile . mmaps/MMMXXYY.mmtile string fileName = string.Format(TILE_FILE_NAME_FORMAT, basePath, mapId, x, y); @@ -95,9 +102,9 @@ namespace Game } if (!File.Exists(fileName)) - { + { Log.outDebug(LogFilter.Maps, "MMAP:loadMap: Could not open mmtile file '{0}'", fileName); - return false; + return LoadResult.FileNotFound; } using BinaryReader reader = new(new FileStream(fileName, FileMode.Open, FileAccess.Read)); @@ -105,13 +112,13 @@ namespace Game if (fileHeader.mmapMagic != MapConst.mmapMagic) { Log.outError(LogFilter.Maps, "MMAP:loadMap: Bad header in mmap {0:D4}{1:D2}{2:D2}.mmtile", mapId, x, y); - return false; + return LoadResult.VersionMismatch; } if (fileHeader.mmapVersion != MapConst.mmapVersion) { Log.outError(LogFilter.Maps, "MMAP:loadMap: {0:D4}{1:D2}{2:D2}.mmtile was built with generator v{3}, expected v{4}", mapId, x, y, fileHeader.mmapVersion, MapConst.mmapVersion); - return false; + return LoadResult.VersionMismatch; } var bytes = reader.ReadBytes((int)fileHeader.size); @@ -125,17 +132,23 @@ 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); - return true; + return LoadResult.Success; } Log.outError(LogFilter.Maps, "MMAP:loadMap: Could not load {0:D4}{1:D2}{2:D2}.mmtile into navmesh", mapId, x, y); - return false; + return LoadResult.LibraryError; } public bool LoadMapInstance(string basePath, uint meshMapId, uint instanceMapId, uint instanceId) { - if (!LoadMapData(basePath, meshMapId)) - return false; + switch (LoadMapData(basePath, meshMapId)) + { + case LoadResult.Success: + case LoadResult.AlreadyLoaded: + break; + default: + return false; + } MMapData mmap = loadedMMaps[meshMapId]; if (mmap.navMeshQueries.ContainsKey((instanceMapId, instanceId))) @@ -297,4 +310,14 @@ namespace Game public uint size; public byte usesLiquids; } + + enum LoadResult + { + Success, + AlreadyLoaded, + FileNotFound, + VersionMismatch, + ReadFromFileFailed, + LibraryError + } } diff --git a/Source/Game/Maps/TerrainManager.cs b/Source/Game/Maps/TerrainManager.cs index 437fd17b0..a4356f232 100644 --- a/Source/Game/Maps/TerrainManager.cs +++ b/Source/Game/Maps/TerrainManager.cs @@ -346,11 +346,22 @@ namespace Game.Maps if (!Global.DisableMgr.IsPathfindingEnabled(GetId())) return; - bool mmapLoadResult = Global.MMapMgr.LoadMap(Global.WorldMgr.GetDataPath(), GetId(), gx, gy); - if (mmapLoadResult) - Log.outDebug(LogFilter.Maps, $"MMAP loaded name:{GetMapName()}, id:{GetId()}, x:{gx}, y:{gy} (mmap rep.: x:{gx}, y:{gy})"); - else - Log.outWarn(LogFilter.Maps, $"Could not load MMAP name:{GetMapName()}, id:{GetId()}, x:{gx}, y:{gy} (mmap rep.: x:{gx}, y:{gy})"); + LoadResult mmapLoadResult = Global.MMapMgr.LoadMap(Global.WorldMgr.GetDataPath(), GetId(), gx, gy); + switch (mmapLoadResult) + { + case LoadResult.Success: + Log.outDebug(LogFilter.Maps, $"MMAP loaded name:{GetMapName()}, id:{GetId()}, x:{gx}, y:{gy} (mmap rep.: x:{gx}, y:{gy})"); + break; + case LoadResult.AlreadyLoaded: + break; + case LoadResult.FileNotFound: + if (_parentTerrain != null) + break; // don't log tile not found errors for child maps + goto default; + default: + Log.outWarn(LogFilter.Maps, $"Could not load MMAP name:{GetMapName()}, id:{GetId()}, x:{gx}, y:{gy} (mmap rep.: x:{gx}, y:{gy}) result: {mmapLoadResult}"); + break; + } } public void UnloadMap(int gx, int gy) @@ -703,18 +714,18 @@ namespace Game.Maps { if (hasDynamicAreaInfo && ddata.floorZ > vdata.floorZ) { - check_z = ddata.floorZ; - groupId = ddata.areaInfo.GroupId; - adtId = ddata.areaInfo.AdtId; - rootId = ddata.areaInfo.RootId; + check_z = ddata.floorZ; + groupId = ddata.areaInfo.GroupId; + adtId = ddata.areaInfo.AdtId; + rootId = ddata.areaInfo.RootId; mogpflags = ddata.areaInfo.MogpFlags; } else { - check_z = vdata.floorZ; - groupId = vdata.areaInfo.GroupId; - adtId = vdata.areaInfo.AdtId; - rootId = vdata.areaInfo.RootId; + check_z = vdata.floorZ; + groupId = vdata.areaInfo.GroupId; + adtId = vdata.areaInfo.AdtId; + rootId = vdata.areaInfo.RootId; mogpflags = vdata.areaInfo.MogpFlags; } }