public static WDT Process(MapInfo entry) { var dir = entry.InternalName; var wdtDir = Path.Combine(baseDir, dir); var wdtName = dir; var wdtFilePath = Path.Combine(wdtDir, wdtName + Extension); if (!MpqManager.FileExists(wdtFilePath)) return null; var wdt = new WDT { Manager = MpqManager, Entry = entry, Name = wdtName, Path = wdtDir }; using (var fileReader = new BinaryReader(MpqManager.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 wdt.IsWMOOnly = true; ReadMWMO(fileReader, wdt); ReadMODF(fileReader, wdt); } } return wdt; }
public MpqTerrainManager(TileIdentifier tileId) { var wowRootDir = DBCTool.FindWowDir(); MpqManager = new MpqManager(wowRootDir); TileId = tileId; var entries = GetMapEntries(); MapInfo entry = null; foreach (var item in entries) { if (item.Id != tileId.MapId) { continue; } entry = item; break; } WDTParser.MpqManager = MpqManager; _wdt = WDTParser.Process(entry); _adtManager = new ADTManager(this); _wmoManager = new WMOManager(); _m2Manager = new M2Manager(); _meshManager = new NavMeshManager(); _selectedTriangleManager = new SelectedTriangleManager(_adtManager); }
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 ReadMVER(BinaryReader fileReader, WDT wdt) { var type = fileReader.ReadUInt32(); var size = fileReader.ReadUInt32(); wdt.Version = fileReader.ReadInt32(); }
public MpqTerrainManager(TileIdentifier tileId) { var wowRootDir = DBCTool.FindWowDir(); MpqManager = new MpqManager(wowRootDir); TileId = tileId; var entries = GetMapEntries(); MapInfo entry = null; foreach (var item in entries) { if (item.Id != tileId.MapId) continue; entry = item; break; } WDTParser.MpqManager = MpqManager; _wdt = WDTParser.Process(entry); _adtManager = new ADTManager(this); _wmoManager = new WMOManager(); _m2Manager = new M2Manager(); _meshManager = new NavMeshManager(); _selectedTriangleManager = new SelectedTriangleManager(_adtManager); }
/// <summary> /// Writes all height maps to the default MapDir /// </summary> public static void ExportMapTiles(WDT wdt) { // Map data should only be stored per map ClearObjectData(); var path = Path.Combine(TerrainDisplayConfig.MapDir, wdt.Entry.Id.ToString()); if (wdt.IsWMOOnly) { // This Map has no Tiles, but the MODF still needs to be written // These maps will be considered to have one tile at {0, 0} with only one MODF written therein var adt = ExtractWMOOnly(wdt); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } using (var file = File.Create(Path.Combine(path, TerrainConstants.GetMapFilename(0, 0)))) { WriteTileInfo(file, adt); } return; } // Read in the ADT data - this includes height and liquid maps, WMO information and M2 information TerrainInfo = ExtractMapTiles(wdt); // Write the processed data to files var count = 0; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } for (var tileX = 0; tileX < TerrainConstants.TilesPerMapSide; tileX++) { for (var tileY = 0; tileY < TerrainConstants.TilesPerMapSide; tileY++) { var adt = TerrainInfo[tileY, tileX]; if (adt == null) continue; var filePath = Path.Combine(path, TerrainConstants.GetMapFilename(tileX, tileY)); using (var file = File.Create(filePath)) { WriteTileInfo(file, adt); file.Close(); } count++; } } log.Info("Extracted {0} tiles for {1}.", count, wdt.Entry.Id); }
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 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 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(); } } }
public static WDT Process(MapInfo entry) { var dir = entry.InternalName; var wdtDir = Path.Combine(baseDir, dir); var wdtName = dir; var wdtFilePath = Path.Combine(wdtDir, wdtName + Extension); if (!MpqManager.FileExists(wdtFilePath)) { return(null); } var wdt = new WDT { Manager = MpqManager, Entry = entry, Name = wdtName, Path = wdtDir }; using (var fileReader = new BinaryReader(MpqManager.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 wdt.IsWMOOnly = true; ReadMWMO(fileReader, wdt); ReadMODF(fileReader, wdt); } } return(wdt); }
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.MapTileCount; x++) { // Columns are along the y-axis for (var y = 0; y < TerrainConstants.MapTileCount; 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); } } }
public static ADT ExtractWMOOnly(WDT wdt) { var tileId = new TileIdentifier { MapId = wdt.Entry.Id, MapName = wdt.Name, TileX = 0, TileY = 0 }; var adt = new ADT(tileId); adt.ObjectDefinitions.Capacity = wdt.WmoDefinitions.Count; foreach (var wmoDefinition in wdt.WmoDefinitions) { adt.ObjectDefinitions.Add(wmoDefinition); } adt.ObjectFiles.Capacity = wdt.WmoFiles.Count; foreach (var wmoFile in wdt.WmoFiles) { adt.ObjectFiles.Add(wmoFile); } foreach (var def in adt.ObjectDefinitions) { LoadWMO(wdt.Manager, def); } adt.IsWMOOnly = true; return adt; }
private static void WriteWdt(Stream file, WDT wdt) { var writer = new BinaryWriter(file); writer.Write(FileTypeId); writer.Write(wdt.IsWMOOnly); if (wdt.IsWMOOnly) return; for (var x = 0; x < TerrainConstants.MapTileCount; x++) { // Columns are along the y-axis for (var y = 0; y < TerrainConstants.MapTileCount; y++) { // Stored as [col, row], that's weird. writer.Write(wdt.TileProfile[y, x]); } } }
public static ADT[,] ExtractMapTiles(WDT wdt) { var mapTiles = new ADT[TerrainConstants.TilesPerMapSide, TerrainConstants.TilesPerMapSide]; for (var x = 0; x < TerrainConstants.TilesPerMapSide; x++) { for (var y = 0; y < TerrainConstants.TilesPerMapSide; y++) { if (!wdt.TileProfile[y, x]) continue; if (x != 49 || y != 36) continue; var tileId = new TileIdentifier { MapId = wdt.Entry.Id, MapName = wdt.Name, TileX = x, TileY = y }; var adt = ADTParser.Process(WDTExtractor.MpqManager, tileId); if (adt == null) continue; adt.IsWMOOnly = false; // Load in the WMORoots and their DoodadDefinitions // Load in the ADTs referenced M2Models PrepareChunkInfo(wdt.Manager, adt); ReduceTerrainTris(adt); LoadQuadTree(adt); mapTiles[y, x] = adt; } } return mapTiles; }
private static void ExtractMapObjects(WDT wdt) { if (wdt == null) return; if (wdt.Header.Header1.HasFlag(WDTFlags.GlobalWMO)) { // No terrain, load the global WMO if (wdt.WmoDefinitions == null) return; ExtractWMOs(wdt.WmoDefinitions); } else { for (var tileX = 0; tileX < TerrainConstants.TilesPerMapSide; tileX++) { for (var tileY = 0; tileY < TerrainConstants.TilesPerMapSide; tileY++) { if (!wdt.TileProfile[tileY, tileX]) continue; if (tileX != 49 || tileY != 36) continue; ADT adt = null; if (TileExtractor.TerrainInfo != null) { adt = TileExtractor.TerrainInfo[tileY, tileX]; } if (adt == null) { var tileId = new TileIdentifier { MapId = wdt.Entry.Id, MapName = wdt.Entry.InternalName, TileX = tileX, TileY = tileY }; adt = ADTParser.Process(wdt.Manager, tileId); } if (adt == null) continue; ExtractTileWMOs(adt); ExtractTileM2s(adt); } } } PrepareMapWMOs(); PrepareMapM2s(); WriteMapM2s(wdt.Entry); WriteMapWMOs(wdt.Entry); }