Пример #1
0
        public static ADTChunk ReadChunk(BinaryReader fileReader, uint mcnkOffset, ADT parent)
        {
            var chunk = new ADTChunk();

            fileReader.BaseStream.Position = mcnkOffset;

            // Read the header
            ReadMCNK(fileReader, chunk);

            if (chunk.Header.offsColorValues != 0)
            {
                fileReader.BaseStream.Position = mcnkOffset + chunk.Header.offsColorValues;
                ReadMCCV(fileReader, chunk);
            }
            if (chunk.Header.ofsHeight != 0)
            {
                fileReader.BaseStream.Position = mcnkOffset + chunk.Header.ofsHeight;
                ReadMCVT(fileReader, chunk);
            }
            if (chunk.Header.ofsNormal != 0)
            {
                fileReader.BaseStream.Position = mcnkOffset + chunk.Header.ofsNormal;
                ReadMCNR(fileReader, chunk);
            }
            if (chunk.Header.ofsLayer != 0)
            {
                fileReader.BaseStream.Position = mcnkOffset + chunk.Header.ofsLayer;
                ReadMCLY(fileReader, chunk);
            }
            if (chunk.Header.ofsRefs != 0)
            {
                fileReader.BaseStream.Position = mcnkOffset + chunk.Header.ofsRefs;
                ReadMCRF(fileReader, chunk);
            }
            if (chunk.Header.ofsShadow != 0)
            {
                fileReader.BaseStream.Position = mcnkOffset + chunk.Header.ofsShadow;
                ReadMCSH(fileReader, chunk);
            }
            if (chunk.Header.ofsAlpha != 0)
            {
                fileReader.BaseStream.Position = mcnkOffset + chunk.Header.ofsAlpha;
                ReadMCAL(fileReader, chunk);
            }
            if (chunk.Header.ofsSndEmitters != 0)
            {
                fileReader.BaseStream.Position = mcnkOffset + chunk.Header.ofsSndEmitters;
                ReadMCSE(fileReader, chunk);
            }

            return chunk;
        }
Пример #2
0
		/// <summary>
		/// Writes all height maps to the default MapDir
		/// </summary>
		//public static void WriteADTs(WDT wdt)
		public static void WriteADT(ADT adt)
		{
			// Map data should only be stored per map
			var path = GetMapDirectory(adt.Terrain.MapId);
			if (!Directory.Exists(path))
			{
				Directory.CreateDirectory(path);
			}
			using (var file = File.Create(GetFileName(adt.Terrain.MapId, adt.TileX, adt.TileY)))
			{
				using (var writer = new BinaryWriter(file))
				{
					writer.Write(FileTypeId);
					writer.Write(Version);

					writer.Write(adt.IsWMOOnly);

					writer.Write(adt.TerrainVertices);
					writer.Write(adt.TerrainIndices);


					// Write liquid information
					var hasLiquids = false;
					for (var xc = 0; xc < TerrainConstants.ChunksPerTileSide; xc++)
					{
						for (var yc = 0; yc < TerrainConstants.ChunksPerTileSide; yc++)
						{
							var chunk = adt.Chunks[xc, yc];

							if (chunk.HasLiquid)
							{
								hasLiquids = true;
								break;
							}
						}
					}

					writer.Write(hasLiquids);
					if (hasLiquids)
					{
						for (var xc = 0; xc < TerrainConstants.ChunksPerTileSide; xc++)
						{
							for (var yc = 0; yc < TerrainConstants.ChunksPerTileSide; yc++)
							{
								var chunk = adt.Chunks[xc, yc];

								writer.Write(chunk.HasLiquid ? (int)chunk.LiquidType : (int)LiquidType.None);
								if (chunk.HasLiquid)
								{
									// write boundaries
									var header = chunk.WaterInfo.Header;
									writer.Write(header.XOffset);
									writer.Write(header.YOffset);
									var w = (byte)Math.Min(header.Width, TerrainConstants.UnitsPerChunkSide - header.XOffset);
									var h = (byte)Math.Min(header.Height, TerrainConstants.UnitsPerChunkSide - header.YOffset);
									writer.Write(w);
									writer.Write(h);

									var heights = chunk.LiquidHeights;
									for (var x = header.XOffset; x <= w + header.XOffset; x++)
									{
										for (var y = header.YOffset; y <= h + header.YOffset; y++)
										{
											//var height = chunk.LiquidMap[x, y] ? heights[x, y] : float.MinValue;
											var height = heights[x, y];
											writer.Write(height);
										}
									}
								}
							}
						}
					}
				}
			}

		}
Пример #3
0
        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;
        }
Пример #4
0
        static void ReadMWMO(BinaryReader fileReader, ADT adt)
        {
            var type = fileReader.ReadUInt32();
            var size = fileReader.ReadUInt32();

            long endPos = fileReader.BaseStream.Position + size;
            while (fileReader.BaseStream.Position < endPos)
            {
                if (fileReader.PeekByte() == 0)
                {
                    fileReader.BaseStream.Position++;
                }
                else
                {
                    adt.ObjectFiles.Add(fileReader.ReadCString());
                }
            }
        }
Пример #5
0
        static void ReadMWID(BinaryReader fileReader, ADT adt)
        {
            var type = fileReader.ReadUInt32();
            var size = fileReader.ReadUInt32();

            uint count = size / 4;
            for (int i = 0; i < count; i++)
            {
                adt.ObjectFileOffsets.Add(fileReader.ReadInt32());
            }
        }
Пример #6
0
        static void ReadMVER(BinaryReader fileReader, ADT adt)
        {
            var type = fileReader.ReadUInt32();
            var size = fileReader.ReadUInt32();

            adt.Version = fileReader.ReadInt32();
        }
Пример #7
0
 static void ReadMTEX(BinaryReader br, ADT adt)
 {
 }
Пример #8
0
        static void ReadMODF(BinaryReader fileReader, ADT adt)
        {
            var type = fileReader.ReadUInt32();
            var size = fileReader.ReadUInt32();

            long endPos = fileReader.BaseStream.Position + size;
            while (fileReader.BaseStream.Position < endPos)
            {
                var objectDef = new MapObjectDefinition();
                int nameIndex = fileReader.ReadInt32(); // 4 bytes
                objectDef.FilePath = adt.ObjectFiles[nameIndex];
                objectDef.UniqueId = fileReader.ReadUInt32(); // 4 bytes
                // This Position appears to be in the wrong order.
                // To get WoW coords, read it as: {Y, Z, X}
                var Y = fileReader.ReadSingle();
                var Z = fileReader.ReadSingle();
                var X = fileReader.ReadSingle();
                objectDef.Position = new Vector3(X, Y, Z); // 12 bytes
                objectDef.OrientationA = fileReader.ReadSingle(); // 4 Bytes
                objectDef.OrientationB = fileReader.ReadSingle(); // 4 Bytes
                objectDef.OrientationC = fileReader.ReadSingle(); // 4 Bytes

                var min = new Vector3();
                min.Y = fileReader.ReadSingle();
                min.Z = fileReader.ReadSingle();
                min.X = fileReader.ReadSingle();

                var max = new Vector3();
                max.Y = fileReader.ReadSingle();
                max.Z = fileReader.ReadSingle();
                max.X = fileReader.ReadSingle();
                objectDef.Extents = new BoundingBox(min, max); // 12*2 bytes
                objectDef.Flags = fileReader.ReadUInt16(); // 2 bytes
                objectDef.DoodadSetId = fileReader.ReadUInt16(); // 2 bytes
                objectDef.NameSet = fileReader.ReadUInt16(); // 2 bytes
                fileReader.ReadUInt16(); // padding

                adt.ObjectDefinitions.Add(objectDef);
            }
        }
Пример #9
0
        static void ReadMHDR(BinaryReader fileReader, ADT adt)
        {
            var type = fileReader.ReadUInt32();
            var size = fileReader.ReadUInt32();

            adt.Header.Base = (uint)fileReader.BaseStream.Position;

            var pad = fileReader.ReadUInt32();

            adt.Header.offsInfo = fileReader.ReadUInt32();
            adt.Header.offsTex = fileReader.ReadUInt32();
            adt.Header.offsModels = fileReader.ReadUInt32();
            adt.Header.offsModelIds = fileReader.ReadUInt32();
            adt.Header.offsMapObjects = fileReader.ReadUInt32();
            adt.Header.offsMapObjectIds = fileReader.ReadUInt32();
            adt.Header.offsDoodadDefinitions = fileReader.ReadUInt32();
            adt.Header.offsObjectDefinitions = fileReader.ReadUInt32();
            adt.Header.offsFlightBoundary = fileReader.ReadUInt32();
            adt.Header.offsMH2O = fileReader.ReadUInt32();

            var pad3 = fileReader.ReadUInt32();
            var pad4 = fileReader.ReadUInt32();
            var pad5 = fileReader.ReadUInt32();
            var pad6 = fileReader.ReadUInt32();
            var pad7 = fileReader.ReadUInt32();
        }
Пример #10
0
        static void ReadMH2O(BinaryReader fileReader, ADT adt)
        {
            var sig = fileReader.ReadUInt32();
            var size = fileReader.ReadUInt32();

            long ofsMH2O = fileReader.BaseStream.Position;
            MH20Header[] mh20Header = new MH20Header[256];

            for (int i = 0; i < 256; i++)
            {
                mh20Header[i].ofsData1 = fileReader.ReadUInt32();
                mh20Header[i].LayerCount = fileReader.ReadUInt32();
                mh20Header[i].ofsData2 = fileReader.ReadUInt32();
            }

            // Rows
            for (int x = 0; x < 16; x++)
            {
                // Columns
                for (int y = 0; y < 16; y++)
                {
                    // Indexing is [col, row]
                    adt.LiquidInfo[x, y] = ProcessMH2O(fileReader, mh20Header[x * 16 + y], ofsMH2O);
                }
            }
        }
Пример #11
0
 static void ReadMFBO(BinaryReader fileReader, ADT adt)
 {
     var type = fileReader.ReadUInt32();
     var size = fileReader.ReadUInt32();
 }
Пример #12
0
        static void ReadMDDF(BinaryReader fileReader, ADT adt)
        {
            var type = fileReader.ReadUInt32();
            var size = fileReader.ReadUInt32();

            var endPos = fileReader.BaseStream.Position + size;
            while (fileReader.BaseStream.Position < endPos)
            {
                var doodadDefinition = new MapDoodadDefinition();
                var nameIndex = fileReader.ReadInt32();
                doodadDefinition.FilePath = adt.ModelFiles[nameIndex]; // 4 bytes
                doodadDefinition.UniqueId = fileReader.ReadUInt32(); // 4 bytes
                var Y = fileReader.ReadSingle();
                var Z = fileReader.ReadSingle();
                var X = fileReader.ReadSingle();
                doodadDefinition.Position = new Vector3(X, Y, Z); // 12 bytes
                doodadDefinition.OrientationA = fileReader.ReadSingle(); // 4 Bytes
                doodadDefinition.OrientationB = fileReader.ReadSingle(); // 4 Bytes
                doodadDefinition.OrientationC = fileReader.ReadSingle(); // 4 Bytes
                doodadDefinition.Scale = fileReader.ReadUInt16() / 1024f; // 2 bytes
                doodadDefinition.Flags = fileReader.ReadUInt16(); // 2 bytes
                adt.DoodadDefinitions.Add(doodadDefinition);
            }
        }
Пример #13
0
 static void ReadMCNK(BinaryReader br, ADT adt)
 {
     for (var i = 0; i < TerrainConstants.ChunksPerTile; i++)
     {
         var chunk = ADTChunkReader.ReadChunk(br, adt.MapChunkInfo[i].Offset, adt);
         adt.Chunks[chunk.Header.IndexX, chunk.Header.IndexY] = chunk;
         chunk.WaterInfo = adt.LiquidInfo[chunk.Header.IndexX, chunk.Header.IndexY];
     }
 }
Пример #14
0
        static void ReadMCIN(BinaryReader fileReader, ADT adt)
        {
            var type = fileReader.ReadUInt32();
            var size = fileReader.ReadUInt32();

            adt.MapChunkInfo = new MapChunkInfo[256];
            for (var i = 0; i < 256; i++)
            {
                var mcin = new MapChunkInfo
                               {
                                   Offset = fileReader.ReadUInt32(),
                                   Size = fileReader.ReadUInt32(),
                                   Flags = fileReader.ReadUInt32(),
                                   AsyncId = fileReader.ReadUInt32()
                               };

                adt.MapChunkInfo[i] = mcin;
            }
        }
Пример #15
0
        /// <summary>
        /// Write the given ADT's heightfield to disk
        /// </summary>
        public static void WriteHeightfield(ADT adt)
        {
            var path = Path.Combine(WCellTerrainSettings.SimpleMapDir, ((int)adt.Terrain.MapId).ToString());
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            using (var file = File.Create(GetFileName(adt.Terrain.MapId, adt.TileX, adt.TileY)))
            {
                using (var writer = new BinaryWriter(file))
                {
                    for (var y = 0; y < TerrainConstants.ChunksPerTileSide; ++y)
                    {
                        for (var unitY = 0; unitY <= TerrainConstants.UnitsPerChunkSide; ++unitY)
                        {
                            for (var x = 0; x < TerrainConstants.ChunksPerTileSide; ++x)
                            {
                                var chunk = adt.Chunks[x, y];
                                var heights = chunk.Heights.GetLowResMapMatrix();
                                //var holes = (chunk.HolesMask > 0) ? chunk.HolesMap : ADT.EmptyHolesArray;

                                // Add the height map values, inserting them into their correct positions
                                for (var unitX = 0; unitX <= TerrainConstants.UnitsPerChunkSide; ++unitX)
                                {
                                    //var tileX = (x * TerrainConstants.UnitsPerChunkSide) + unitX;
                                    //var tileY = (y * TerrainConstants.UnitsPerChunkSide) + unitY;
                                    //var xPos = TerrainConstants.CenterPoint
                                    //           - (TileX * TerrainConstants.TileSize)
                                    //           - (tileX * TerrainConstants.UnitSize);
                                    //var yPos = TerrainConstants.CenterPoint
                                    //           - (TileY * TerrainConstants.TileSize)
                                    //           - (tileY * TerrainConstants.UnitSize);

                                    var h = (heights[unitX, unitY] + chunk.MedianHeight);

                                    // Write height
                                    writer.Write(h);

                                    //tileHolesMap[tileX, tileY] = holes[unitX / 2, unitY / 2];
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #16
0
		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;
		}