public static WDT ReadWDT(MapInfo entry) { var dir = entry.InternalName; var wdtDir = Path.Combine(baseDir, dir); var wdtName = dir; var wdtFilePath = Path.Combine(wdtDir, wdtName + Extension); var finder = WCellTerrainSettings.GetDefaultMPQFinder(); if (!finder.FileExists(wdtFilePath)) return null; var wdt = new WDT(entry.Id) { Entry = entry, Name = wdtName, Filename = wdtDir }; using (var fileReader = new BinaryReader(finder.OpenFile(wdtFilePath))) { ReadMVER(fileReader, wdt); ReadMPHD(fileReader, wdt); ReadMAIN(fileReader, wdt); if (wdt.Header.IsWMOMap) { // No terrain, the map is a "global" wmo // MWMO and MODF chunks follow ReadMWMO(fileReader, wdt); ReadMODF(fileReader, wdt); } } return wdt; }
/// <summary> /// Creates a dummy WDT and loads the given tile into it /// </summary> public static ADT LoadTile(MapId map, int x, int y) { var wdt = new WDT(map); wdt.TileProfile[x, y] = true; return((ADT)wdt.LoadTile(x, y)); }
public static void GetTileSets(WDT wdt) { if (!wdt.IsWMOOnly) { var tileSet = new ZoneTileSet(); Tiles[(int) wdt.MapId] = tileSet; ZoneGrid grid; // Rows are along the x-axis for (var x = 0; x < 64; x++) { // Columns are along the y-axis for (var y = 0; y < 64; y++) { if (!wdt.TileProfile[y, x]) continue; ++count; var adt = ADTReader.ReadADT(wdt, x, y); if (adt == null) continue; tileSet.ZoneGrids[y, x] = grid = new ZoneGrid(new uint[TerrainConstants.ChunksPerTileSide, TerrainConstants.ChunksPerTileSide]); // Rows along the x-axis for (var chunkX = 0; chunkX < 16; chunkX++) { // Columns along the y-axis for (var chunkY = 0; chunkY < 16; chunkY++) { var areaId = adt.GetADTChunk(chunkY, chunkX).Header.AreaId; if (Enum.IsDefined(typeof(ZoneId), areaId)) { grid.ZoneIds[chunkY, chunkX] = (uint)areaId; } else { grid.ZoneIds[chunkY, chunkX] = 0; } } } //return tiles; } } } else { log.Info("Could not read Zones from WMO: " + wdt.MapId); } }
public static void ExtractAllADTs() { foreach (MapId mapId in Enum.GetValues(typeof(MapId))) { var name = TileIdentifier.GetName(mapId); if (string.IsNullOrEmpty(name)) { Console.WriteLine(@"No ADT for map {0}.", mapId); continue; } var wdt = new WDT(mapId); for (var tileX = 0; tileX < 64; tileX++) { for (var tileY = 0; tileY < 64; tileY++) { string filePath; MpqLibrarian mpqFinder; if (!ADTReader.TryGetADTPath(mapId, tileX, tileY, out filePath, out mpqFinder)) continue; try { wdt.TileProfile[tileX, tileY] = true; var adt = ADTReader.ReadADT(wdt, tileX, tileY); if (adt != null) { adt.GenerateMapWithNoSimplification(); Console.WriteLine(@"Tile ({0}, {1}) in Map {2} has been imported...", tileX, tileY, mapId); Console.WriteLine(@"Writing to file..."); // export to file SimpleTileWriter.WriteADT(adt); continue; } } catch (ArgumentException) { } Console.WriteLine(@"Extracting FAILED: Tile ({0}, {1}) in Map {2} could not be loaded", tileX, tileY, mapId); } } } }
static void PrintProfile(WDT wdt) { using (var file = new StreamWriter(wdt.Entry.InternalName + ".wdtprofile.txt")) { for (var x = 0; x < 64; x++) { for (var y = 0; y < 64; y++) { if (wdt.TileProfile[y, x]) { file.Write("X"); } else { file.Write("."); } } file.WriteLine(); } } }
/// <summary> /// Creates a dummy WDT and loads the given tile into it /// </summary> public static ADT LoadTile(MapId map, int x, int y) { var wdt = new WDT(map); wdt.TileProfile[x, y] = true; return (ADT)wdt.LoadTile(x, y); }
public static ADT ReadADT(WDT terrain, int x, int y, bool addWMOsAndM2s = true) { string filePath; MpqLibrarian mpqFinder; if (!TryGetADTPath(terrain.MapId, x, y, out filePath, out mpqFinder)) { log.Error("ADT file does not exist: {0}", filePath); return null; } var adt = new ADT(x, y, terrain); using (var stream = mpqFinder.OpenFile(filePath)) using (var fileReader = new BinaryReader(stream)) { if (stream.Length == 0) { log.Error("ADT file is empty: {0}", filePath); return null; } ReadMVER(fileReader, adt); ReadMHDR(fileReader, adt); if (adt.Header.offsInfo != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsInfo; ReadMCIN(fileReader, adt); } //if (adt.Header.offsTex != 0) //{ // fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsTex; // ReadMTEX(fileReader, adt); //} if (adt.Header.offsModels != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsModels; ReadMMDX(fileReader, adt); } if (adt.Header.offsModelIds != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsModelIds; ReadMMID(fileReader, adt); } if (adt.Header.offsMapObjects != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsMapObjects; ReadMWMO(fileReader, adt); } if (adt.Header.offsMapObjectIds != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsMapObjectIds; ReadMWID(fileReader, adt); } if (adt.Header.offsDoodadDefinitions != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsDoodadDefinitions; ReadMDDF(fileReader, adt); } if (adt.Header.offsObjectDefinitions != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsObjectDefinitions; ReadMODF(fileReader, adt); } //if (adt.Header.offsFlightBoundary != 0) //{ // fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsFlightBoundary; // ReadMFBO(fileReader, adt); //} if (adt.Header.offsMH2O != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsMH2O; ReadMH2O(fileReader, adt); } ReadMCNK(fileReader, adt); } if (addWMOsAndM2s) { // add WMOs & M2s adt.WMOs = new WMORoot[adt.ObjectDefinitions.Count]; var actualWMOCount = 0; for (var i = 0; i < adt.ObjectDefinitions.Count; i++) { var def = adt.ObjectDefinitions[i]; var wmo = terrain.GetOrReadWMO(def); adt.WMOs[i] = wmo; if (wmo != null) { ++actualWMOCount; } } if (actualWMOCount == 0) { adt.WMOs = new WMORoot[0]; // No WMOs available -> unset } adt.M2s = new M2[adt.DoodadDefinitions.Count]; var actualM2Count = 0; for (var i = 0; i < adt.DoodadDefinitions.Count; i++) { var def = adt.DoodadDefinitions[i]; var m2 = terrain.GetOrReadM2(def); adt.M2s[i] = m2; if (m2 != null) { ++actualM2Count; } } if (actualM2Count == 0) { adt.M2s = new M2[0]; // No M2s available -> unset } } return adt; }
static void ReadMWMO(BinaryReader fileReader, WDT wdt) { var type = fileReader.ReadUInt32(); var size = fileReader.ReadUInt32(); var endPos = fileReader.BaseStream.Position + size; while (fileReader.BaseStream.Position < endPos) { if (fileReader.PeekByte() == 0) { fileReader.BaseStream.Position++; } else { wdt.WmoFiles.Add(fileReader.ReadCString()); } } }
static void ReadMVER(BinaryReader fileReader, WDT wdt) { var type = fileReader.ReadUInt32(); var size = fileReader.ReadUInt32(); wdt.Version = fileReader.ReadInt32(); }
static void ReadMPHD(BinaryReader fileReader, WDT wdt) { var type = fileReader.ReadUInt32(); var size = fileReader.ReadUInt32(); wdt.Header.Header1 = (WDTFlags)fileReader.ReadInt32(); wdt.Header.Header2 = fileReader.ReadInt32(); wdt.Header.Header3 = fileReader.ReadInt32(); wdt.Header.Header4 = fileReader.ReadInt32(); wdt.Header.Header5 = fileReader.ReadInt32(); wdt.Header.Header6 = fileReader.ReadInt32(); wdt.Header.Header7 = fileReader.ReadInt32(); wdt.Header.Header8 = fileReader.ReadInt32(); }
static void ReadMODF(BinaryReader fileReader, WDT wdt) { var type = fileReader.ReadUInt32(); var size = fileReader.ReadUInt32(); var endPos = fileReader.BaseStream.Position + size; while (fileReader.BaseStream.Position < endPos) { var objectDef = new MapObjectDefinition(); var nameIndex = fileReader.ReadInt32(); // 4 bytes objectDef.FilePath = wdt.WmoFiles[nameIndex]; objectDef.UniqueId = fileReader.ReadUInt32(); // 4 bytes objectDef.Position = fileReader.ReadVector3(); // 12 bytes objectDef.OrientationA = fileReader.ReadSingle(); // 4 Bytes objectDef.OrientationB = fileReader.ReadSingle(); // 4 Bytes objectDef.OrientationC = fileReader.ReadSingle(); // 4 Bytes objectDef.Extents = fileReader.ReadBoundingBox(); // 12*2 bytes objectDef.Flags = fileReader.ReadUInt16(); // 2 bytes objectDef.DoodadSetId = fileReader.ReadUInt16(); // 2 bytes objectDef.NameSet = fileReader.ReadUInt16(); // 2 bytes fileReader.ReadUInt16(); // padding wdt.WmoDefinitions.Add(objectDef); } }
static void ReadMAIN(BinaryReader fileReader, WDT wdt) { var type = fileReader.ReadUInt32(); var size = fileReader.ReadUInt32(); // Rows are along the x-axis for (var x = 0; x < TerrainConstants.TilesPerMapSide; x++) { // Columns are along the y-axis for (var y = 0; y < TerrainConstants.TilesPerMapSide; y++) { //if (x == 48 && y == 30) //{ // wdt.TileProfile[y, x] = true; //} //else //{ // wdt.TileProfile[y, x] = false; //} // Stored as [col, row], that's weird. wdt.TileProfile[y, x] = (fileReader.ReadInt64() != 0); } } }
/// <summary> /// Extracts all heightfields of the given map /// </summary> public static bool ExtractHeightfield(MapId mapId) { var name = TileIdentifier.GetName(mapId); if (string.IsNullOrEmpty(name)) { Console.WriteLine(@"No ADT for map {0}.", mapId); return false; } // get started var mpqFinder = WCellTerrainSettings.GetDefaultMPQFinder(); // Create WDT var wdt = new WDT(mapId); var startTime = DateTime.Now; // compute total size Console.Write(@"Estimating workload... "); var totalAmount = 0; var archives = new HashSet<string>(); for (var tileX = 0; tileX < TerrainConstants.TilesPerMapSide; tileX++) { for (var tileY = 0; tileY < TerrainConstants.TilesPerMapSide; tileY++) { var fname = ADTReader.GetFilename(mapId, tileX, tileY); var archive = mpqFinder.GetArchive(fname); if (archive != null && archive.GetFileSize(fname) > 0) { //totalSize += archive.GetFileSize(fname); ++totalAmount; archives.Add(archive.Path); } } } Console.WriteLine(@"Done - Found {0} tiles in {1} files.", totalAmount, archives.Count); // Get cooking: Console.WriteLine(); Console.WriteLine("Extracting..."); // Load all ADTs and write them to file var processedTiles = 0; for (var tileX = 0; tileX < TerrainConstants.TilesPerMapSide; tileX++) { for (var tileY = 0; tileY < TerrainConstants.TilesPerMapSide; tileY++) { try { var fname = ADTReader.GetFilename(mapId, tileX, tileY); long fsize; var archive = mpqFinder.GetArchive(fname); if (archive != null && (fsize = archive.GetFileSize(fname)) > 0) { //processedSize += fsize; var adt = ADTReader.ReadADT(wdt, tileX, tileY, false); Console.Write(@"Tile ({0}, {1}) in Map {2} has been read from {3}. Writing... ", tileX, tileY, mapId, Path.GetFileName(archive.Path)); // write to file WriteHeightfield(adt); // stats ++processedTiles; var timePassed = DateTime.Now - startTime; var timePerTile = timePassed.Ticks / processedTiles; var progress = processedTiles / (float)totalAmount; var timeRemaining = new TimeSpan((totalAmount - processedTiles) * timePerTile); Console.WriteLine(@"Done. [{0}/{1} {2:F2}% - {3} (Remaining: {4})]", processedTiles, totalAmount, 100 * progress, timePassed.Format(), timeRemaining.Format()); continue; } } catch (Exception e) { Console.WriteLine(); LogUtil.ErrorException(e, @"Extraction FAILED: Tile ({0}, {1}) in Map {2} could not be loaded", tileX, tileY, mapId); return false; } } } return true; }
public static ADT ReadADT(WDT terrain, int x, int y) { var mpqFinder = WCellTerrainSettings.GetDefaultMPQFinder(); var filePath = GetFilename(terrain.MapId, x, y); if (!mpqFinder.FileExists(filePath)) { log.Error("ADT file does not exist: ", filePath); return null; } var adt = new ADT(x, y, terrain); using (var stream = mpqFinder.OpenFile(filePath)) using (var fileReader = new BinaryReader(stream)) { ReadMVER(fileReader, adt); ReadMHDR(fileReader, adt); if (adt.Header.offsInfo != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsInfo; ReadMCIN(fileReader, adt); } //if (adt.Header.offsTex != 0) //{ // fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsTex; // ReadMTEX(fileReader, adt); //} if (adt.Header.offsModels != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsModels; ReadMMDX(fileReader, adt); } if (adt.Header.offsModelIds != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsModelIds; ReadMMID(fileReader, adt); } if (adt.Header.offsMapObjects != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsMapObjects; ReadMWMO(fileReader, adt); } if (adt.Header.offsMapObjectIds != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsMapObjectIds; ReadMWID(fileReader, adt); } if (adt.Header.offsDoodadDefinitions != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsDoodadDefinitions; ReadMDDF(fileReader, adt); } if (adt.Header.offsObjectDefinitions != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsObjectDefinitions; ReadMODF(fileReader, adt); } //if (adt.Header.offsFlightBoundary != 0) //{ // fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsFlightBoundary; // ReadMFBO(fileReader, adt); //} if (adt.Header.offsMH2O != 0) { fileReader.BaseStream.Position = adt.Header.Base + adt.Header.offsMH2O; ReadMH2O(fileReader, adt); } ReadMCNK(fileReader, adt); } // add WMOs & M2s adt.WMOs = new WMORoot[adt.ObjectDefinitions.Count]; for (var i = 0; i < adt.ObjectDefinitions.Count; i++) { var def = adt.ObjectDefinitions[i]; var wmo = terrain.GetOrReadWMO(def); adt.WMOs[i] = wmo; } adt.M2s = new M2[adt.DoodadDefinitions.Count]; for (var i = 0; i < adt.DoodadDefinitions.Count; i++) { var def = adt.DoodadDefinitions[i]; var m2 = terrain.GetOrReadM2(def); adt.M2s[i] = m2; } return adt; }
private void Init(MapId mapId) { BackupTileSource = new WDT(mapId); BackupTileSource.FillTileProfile(); }