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 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; } }
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); } }
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 <MmapTileHeader>(); 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 <uint> 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 <uint, PhasedTile>(); } _phaseTiles[phaseMapId][packedGridPos] = data; } } }