Core/MMaps: Improve mmap debugging experience for terrain swap maps

* Output terrain map id in `.mmap loc` command
* Suppress file not found errors for terrain swap maps
* Fix generating single tiles for terrain swap maps (--tile argument)
Port From (https://github.com/TrinityCore/TrinityCore/commit/6b41c3d3274653605b42f1144f554fe43eee344e)
This commit is contained in:
Hondacrx
2025-12-08 14:48:05 -05:00
parent 34e6130754
commit cef7237f8a
3 changed files with 69 additions and 34 deletions
+4 -3
View File
@@ -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)
+40 -17
View File
@@ -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);
@@ -97,7 +104,7 @@ 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
}
}
+16 -5
View File
@@ -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)