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