diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MBBB.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MBBB.cs
new file mode 100644
index 0000000..2f261ba
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MBBB.cs
@@ -0,0 +1,79 @@
+using System.Collections.Generic;
+using System.IO;
+using Warcraft.NET.Files.ADT.Entries.Legion;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MBBB Chunk - Level of detail
+ ///
+ public class MBBB : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MBBB";
+
+ ///
+ /// Gets or sets s.
+ ///
+ public List MBBBEntries { get; set; } = [];
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MBBB()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MBBB(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var mbbbCount = br.BaseStream.Length / MBBBEntry.GetSize();
+ for (var i = 0; i < mbbbCount; ++i)
+ {
+ MBBBEntries.Add(new MBBBEntry(br.ReadBytes(MBBBEntry.GetSize())));
+ }
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var mbbb in MBBBEntries)
+ {
+ bw.Write(mbbb.Serialize());
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MBMB.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MBMB.cs
new file mode 100644
index 0000000..57e47c6
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MBMB.cs
@@ -0,0 +1,78 @@
+using System.Collections.Generic;
+using System.IO;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MBMB Chunk - Level of detail
+ ///
+ public class MBMB : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MBMB";
+
+ ///
+ /// Unknown array with 20 byte elements.
+ ///
+ public List Entries = [];
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MBMB()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MBMB(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var mbmbCount = br.BaseStream.Length / 20;
+ for (var i = 0; i < mbmbCount; ++i)
+ {
+ Entries.Add(br.ReadBytes(20));
+ }
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var entry in Entries)
+ {
+ bw.Write(entry);
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MBMH.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MBMH.cs
new file mode 100644
index 0000000..566bf1f
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MBMH.cs
@@ -0,0 +1,80 @@
+using System.Collections.Generic;
+using System.IO;
+using Warcraft.NET.Files.ADT.Entries.Legion;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MBMH Chunk - Level of detail
+ ///
+ public class MBMH : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MBMH";
+
+ ///
+ /// Gets or sets s.
+ ///
+ public List MBMHEntries { get; set; } = [];
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MBMH()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MBMH(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var objCount = br.BaseStream.Length / MBMHEntry.GetSize();
+
+ for (var i = 0; i < objCount; ++i)
+ {
+ MBMHEntries.Add(new MBMHEntry(br.ReadBytes(MBMHEntry.GetSize())));
+ }
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var mbmhEntry in MBMHEntries)
+ {
+ bw.Write(mbmhEntry.Serialize());
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MBMI.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MBMI.cs
new file mode 100644
index 0000000..6137117
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MBMI.cs
@@ -0,0 +1,79 @@
+using System.IO;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MBMI Chunk - Level of detail
+ ///
+ public class MBMI : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MBMI";
+
+ ///
+ /// Blend Mesh indices.
+ ///
+ public ushort[] BlendMeshIndices { get; set; }
+
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MBMI()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MBMI(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var count = (int)(ms.Length / 2);
+ BlendMeshIndices = new ushort[count];
+ for (var i = 0; i < count; i++)
+ {
+ BlendMeshIndices[i] = br.ReadUInt16();
+ }
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var index in BlendMeshIndices)
+ {
+ bw.Write(index);
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MBNV.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MBNV.cs
new file mode 100644
index 0000000..6ad6a06
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MBNV.cs
@@ -0,0 +1,80 @@
+using System.Collections.Generic;
+using System.IO;
+using Warcraft.NET.Files.ADT.Entries.Legion;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MBMI Chunk - Level of detail
+ ///
+ public class MBNV : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MBNV";
+
+ ///
+ /// Blend Mesh Vertices.
+ ///
+ public List Entries { get; set; } = [];
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MBNV()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MBNV(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var mbnvCount = br.BaseStream.Length / MBNVEntry.GetSize();
+ for (var i = 0; i < mbnvCount; ++i)
+ {
+ Entries.Add(new MBNVEntry(br.ReadBytes(MBNVEntry.GetSize())));
+ }
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var entry in Entries)
+ {
+ bw.Write(entry.Serialize());
+ }
+
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLDD.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLDD.cs
index eb32810..08319ed 100644
--- a/Warcraft.NET/Files/ADT/Chunks/Legion/MLDD.cs
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLDD.cs
@@ -23,7 +23,7 @@ public MLDD() : base()
/// Initializes a new instance of the class.
///
/// ExtendedData.
- public MLDD(byte[] inData): base(inData)
+ public MLDD(byte[] inData) : base(inData)
{
}
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLDX.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLDX.cs
index 2bc77a0..a98c11b 100644
--- a/Warcraft.NET/Files/ADT/Chunks/Legion/MLDX.cs
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLDX.cs
@@ -1,7 +1,7 @@
-using Warcraft.NET.Files.ADT.Entries.Legion;
-using Warcraft.NET.Files.Interfaces;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.IO;
+using Warcraft.NET.Files.ADT.Entries.Legion;
+using Warcraft.NET.Files.Interfaces;
namespace Warcraft.NET.Files.ADT.Chunks.Legion
{
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLFD.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLFD.cs
index 3b2a651..2162576 100644
--- a/Warcraft.NET/Files/ADT/Chunks/Legion/MLFD.cs
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLFD.cs
@@ -1,5 +1,5 @@
-using Warcraft.NET.Files.Interfaces;
-using System.IO;
+using System.IO;
+using Warcraft.NET.Files.Interfaces;
namespace Warcraft.NET.Files.ADT.Chunks.Legion
{
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLHD.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLHD.cs
new file mode 100644
index 0000000..02b144d
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLHD.cs
@@ -0,0 +1,80 @@
+using System.IO;
+using Warcraft.NET.Extensions;
+using Warcraft.NET.Files.Interfaces;
+using Warcraft.NET.Files.Structures;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MLHD Chunk - Level of detail header
+ ///
+ public class MLHD : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MLHD";
+
+ ///
+ /// Unknown uint
+ ///
+ public uint Unknown0 { get; set; }
+
+ ///
+ /// Unknown bounding box
+ ///
+ public BoundingBox UnkBoundingBox { get; set; }
+
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLHD()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLHD(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ Unknown0 = br.ReadUInt32();
+ UnkBoundingBox = br.ReadBoundingBox();
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return 28;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ bw.Write(Unknown0);
+ bw.WriteBoundingBox(UnkBoundingBox);
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLLD.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLLD.cs
new file mode 100644
index 0000000..20fb1a4
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLLD.cs
@@ -0,0 +1,100 @@
+using System.IO;
+using Warcraft.NET.Files.ADT.Flags;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MLLD Chunk - Level of detail
+ ///
+ public class MLLD : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MLLD";
+
+ ///
+ /// Flags.
+ ///
+ public MLLDFlags Flags { get; set; }
+
+ ///
+ /// Size of the first (possibly compressed) depth chunk.
+ ///
+ public ushort DepthChunkSize { get; set; }
+
+ ///
+ /// Approximate size of the second (possibly compressed) alpha chunk. Possibly off by 4-7 bytes.
+ ///
+ public ushort ApproxAlphaChunkSize { get; set; }
+
+ ///
+ /// Data of the first (possibly compressed) depth chunk.
+ ///
+ public byte[] DepthChunkData { get; set; }
+
+ ///
+ /// Data of the second (possibly compressed) alpha chunk.
+ /// Note: there might be 4-7 extra bytes at the end due to not full understand of this chunk.
+ ///
+ public byte[] AlphaChunkData { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLLD()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLLD(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ Flags = (MLLDFlags)br.ReadUInt32();
+ DepthChunkSize = br.ReadUInt16();
+ ApproxAlphaChunkSize = br.ReadUInt16();
+ DepthChunkData = br.ReadBytes(DepthChunkSize);
+ AlphaChunkData = br.ReadBytes((int)(ms.Length - ms.Position));
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ bw.Write((uint)Flags);
+ bw.Write(DepthChunkSize);
+ bw.Write(ApproxAlphaChunkSize);
+ bw.Write(DepthChunkData);
+ bw.Write(AlphaChunkData);
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLLI.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLLI.cs
new file mode 100644
index 0000000..7a48646
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLLI.cs
@@ -0,0 +1,81 @@
+using System.IO;
+using Warcraft.NET.Extensions;
+using Warcraft.NET.Files.Interfaces;
+using Warcraft.NET.Files.Structures;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MLLI Chunk - Level of detail indices
+ ///
+ public class MLLI : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MLLI";
+
+ ///
+ /// Unknown.
+ ///
+ public ShortVector3[] LiquidIndices { get; set; }
+
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLLI()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLLI(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var vertexCount = inData.Length / 6;
+ LiquidIndices = new ShortVector3[vertexCount];
+ for (var i = 0; i < vertexCount; ++i)
+ {
+ LiquidIndices[i] = br.ReadShortVector3();
+ }
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var vertex in LiquidIndices)
+ {
+ bw.WriteShortVector3(vertex);
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLLL.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLLL.cs
new file mode 100644
index 0000000..20a8d52
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLLL.cs
@@ -0,0 +1,79 @@
+using System.Collections.Generic;
+using System.IO;
+using Warcraft.NET.Files.ADT.Entries.Legion;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MLLL Chunk - Level of detail levels
+ ///
+ public class MLLL : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MLLL";
+
+ ///
+ /// Gets or sets s.
+ ///
+ public List MLLLEntries { get; set; } = [];
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLLL()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLLL(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var mlllCount = br.BaseStream.Length / MLLLEntry.GetSize();
+ for (var i = 0; i < mlllCount; ++i)
+ {
+ MLLLEntries.Add(new MLLLEntry(br.ReadBytes(MLLLEntry.GetSize())));
+ }
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var entry in MLLLEntries)
+ {
+ bw.Write(entry.Serialize());
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLLN.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLLN.cs
new file mode 100644
index 0000000..aa82074
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLLN.cs
@@ -0,0 +1,112 @@
+using System.IO;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MLLN Chunk - Level of detail liquid
+ ///
+ public class MLLN : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MLLN";
+
+ ///
+ /// Unknown.
+ ///
+ public uint Unknown0 { get; set; }
+
+ ///
+ /// MLLI Length.
+ ///
+ public uint MLLILength { get; set; }
+
+ ///
+ /// Unknown.
+ ///
+ public uint Unknown2 { get; set; }
+
+ ///
+ /// Unknown.
+ ///
+ public ushort Unknown3A { get; set; }
+
+ ///
+ /// Unknown.
+ ///
+ public ushort Unknown3B { get; set; }
+
+ ///
+ /// Unknown.
+ ///
+ public uint Unknown4 { get; set; }
+
+ ///
+ /// Unknown.
+ ///
+ public uint Unknown5 { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLLN()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLLN(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ Unknown0 = br.ReadUInt32();
+ MLLILength = br.ReadUInt32();
+ Unknown2 = br.ReadUInt32();
+ Unknown3A = br.ReadUInt16();
+ Unknown3B = br.ReadUInt16();
+ Unknown4 = br.ReadUInt32();
+ Unknown5 = br.ReadUInt32();
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ bw.Write(Unknown0);
+ bw.Write(MLLILength);
+ bw.Write(Unknown2);
+ bw.Write(Unknown3A);
+ bw.Write(Unknown3B);
+ bw.Write(Unknown4);
+ bw.Write(Unknown5);
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLLV.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLLV.cs
new file mode 100644
index 0000000..66c8c08
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLLV.cs
@@ -0,0 +1,81 @@
+using System.IO;
+using System.Numerics;
+using Warcraft.NET.Extensions;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MLLV Chunk - Level of detail vertices
+ ///
+ public class MLLV : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MLLV";
+
+ ///
+ /// Unknown.
+ ///
+ public Vector3[] LiquidVertices { get; set; }
+
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLLV()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLLV(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var vertexCount = inData.Length / 12;
+ LiquidVertices = new Vector3[vertexCount];
+ for (var i = 0; i < vertexCount; ++i)
+ {
+ LiquidVertices[i] = br.ReadVector3();
+ }
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var vertex in LiquidVertices)
+ {
+ bw.WriteVector3(vertex);
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLMD.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLMD.cs
index f5605a5..c753a0b 100644
--- a/Warcraft.NET/Files/ADT/Chunks/Legion/MLMD.cs
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLMD.cs
@@ -1,7 +1,7 @@
-using Warcraft.NET.Files.ADT.Entries.Legion;
-using Warcraft.NET.Files.Interfaces;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.IO;
+using Warcraft.NET.Files.ADT.Entries.Legion;
+using Warcraft.NET.Files.Interfaces;
namespace Warcraft.NET.Files.ADT.Chunks.Legion
{
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLMX.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLMX.cs
index ab02638..ddbecc3 100644
--- a/Warcraft.NET/Files/ADT/Chunks/Legion/MLMX.cs
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLMX.cs
@@ -1,7 +1,7 @@
-using Warcraft.NET.Files.ADT.Entries.Legion;
-using Warcraft.NET.Files.Interfaces;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.IO;
+using Warcraft.NET.Files.ADT.Entries.Legion;
+using Warcraft.NET.Files.Interfaces;
namespace Warcraft.NET.Files.ADT.Chunks.Legion
{
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLND.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLND.cs
new file mode 100644
index 0000000..f62a9dc
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLND.cs
@@ -0,0 +1,79 @@
+using System.Collections.Generic;
+using System.IO;
+using Warcraft.NET.Files.ADT.Entries.Legion;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MLND Chunk - Level of detail
+ ///
+ public class MLND : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MLND";
+
+ ///
+ /// Gets or sets s.
+ ///
+ public List MLNDEntries { get; set; } = [];
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLND()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLND(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var mlndCount = br.BaseStream.Length / MLNDEntry.GetSize();
+ for (var i = 0; i < mlndCount; ++i)
+ {
+ MLNDEntries.Add(new MLNDEntry(br.ReadBytes(MLNDEntry.GetSize())));
+ }
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var entry in MLNDEntries)
+ {
+ bw.Write(entry.Serialize());
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLSI.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLSI.cs
new file mode 100644
index 0000000..b3299e7
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLSI.cs
@@ -0,0 +1,79 @@
+using System.IO;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MLSI Chunk - Level of detail
+ ///
+ public class MLSI : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MLSI";
+
+ ///
+ /// Skirt indices.
+ ///
+ public ushort[] SkirtIndices { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLSI()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLSI(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var mlsiCount = br.BaseStream.Length / sizeof(uint);
+ SkirtIndices = new ushort[mlsiCount];
+ for (var i = 0; i < mlsiCount; i++)
+ {
+ SkirtIndices[i] = br.ReadUInt16();
+ }
+
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var skirtIndex in SkirtIndices)
+ {
+ bw.Write(skirtIndex);
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLVH.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLVH.cs
new file mode 100644
index 0000000..3556de8
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLVH.cs
@@ -0,0 +1,80 @@
+using System.IO;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MLVH Chunk - Level of detail heightmap
+ ///
+ public class MLVH : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MLVH";
+
+ ///
+ /// Height data.
+ ///
+ public float[] HeightData { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLVH()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLVH(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var heightCount = br.BaseStream.Length / sizeof(float);
+
+ HeightData = new float[heightCount];
+
+ for (var i = 0; i < heightCount; i++)
+ {
+ HeightData[i] = br.ReadSingle();
+ }
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)Serialize().Length;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var height in HeightData)
+ {
+ bw.Write(height);
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Chunks/Legion/MLVI.cs b/Warcraft.NET/Files/ADT/Chunks/Legion/MLVI.cs
new file mode 100644
index 0000000..ee230f0
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Chunks/Legion/MLVI.cs
@@ -0,0 +1,78 @@
+using System.IO;
+using Warcraft.NET.Files.Interfaces;
+
+namespace Warcraft.NET.Files.ADT.Chunks.Legion
+{
+ ///
+ /// MLVI Chunk - Level of detail
+ ///
+ public class MLVI : IIFFChunk, IBinarySerializable
+ {
+ ///
+ /// Holds the binary chunk signature.
+ ///
+ public const string Signature = "MLVI";
+
+ ///
+ /// Vertex indices.
+ ///
+ public ushort[] VertexIndices { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLVI()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLVI(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using (var ms = new MemoryStream(inData))
+ using (var br = new BinaryReader(ms))
+ {
+ var mlviCount = br.BaseStream.Length / sizeof(uint);
+ VertexIndices = new ushort[mlviCount];
+ for (var i = 0; i < mlviCount; i++)
+ {
+ VertexIndices[i] = br.ReadUInt16();
+ }
+ }
+ }
+
+ ///
+ public string GetSignature()
+ {
+ return Signature;
+ }
+
+ ///
+ public uint GetSize()
+ {
+ return (uint)VertexIndices.Length * 4;
+ }
+
+ ///
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ foreach (var vertexIndex in VertexIndices)
+ {
+ bw.Write(vertexIndex);
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Entries/Legion/MBBBEntry.cs b/Warcraft.NET/Files/ADT/Entries/Legion/MBBBEntry.cs
new file mode 100644
index 0000000..a739cad
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Entries/Legion/MBBBEntry.cs
@@ -0,0 +1,67 @@
+using System.IO;
+using Warcraft.NET.Extensions;
+using Warcraft.NET.Files.Structures;
+
+namespace Warcraft.NET.Files.ADT.Entries.Legion
+{
+ ///
+ /// Blend mesh bounding box entry.
+ ///
+ public class MBBBEntry
+ {
+ ///
+ /// Unique ID of the map object.
+ ///
+ public uint MapObjectID { get; set; }
+
+ ///
+ /// Bounding box.
+ ///
+ public BoundingBox BoundingBox { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MBBBEntry()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MBBBEntry(byte[] data)
+ {
+ using (var ms = new MemoryStream(data))
+ using (var br = new BinaryReader(ms))
+ {
+ MapObjectID = br.ReadUInt32();
+ BoundingBox = br.ReadBoundingBox();
+ }
+ }
+
+ ///
+ /// Gets the size of an entry.
+ ///
+ /// The size.
+ public static int GetSize()
+ {
+ return 28;
+ }
+
+ ///
+ /// Gets the size of the data contained in this chunk.
+ ///
+ /// The size.
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ bw.Write(MapObjectID);
+ bw.WriteBoundingBox(BoundingBox);
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Entries/Legion/MBMHEntry.cs b/Warcraft.NET/Files/ADT/Entries/Legion/MBMHEntry.cs
new file mode 100644
index 0000000..d033092
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Entries/Legion/MBMHEntry.cs
@@ -0,0 +1,101 @@
+using System.IO;
+
+namespace Warcraft.NET.Files.ADT.Entries.Legion
+{
+ ///
+ /// Blend mesh header entry.
+ ///
+ public class MBMHEntry
+ {
+ ///
+ /// Unique ID of the map object.
+ ///
+ public uint MapObjectID { get; set; }
+
+ ///
+ /// Texture ID of linked WMO.
+ ///
+ public uint TextureID { get; set; }
+
+ ///
+ /// Unknown value (wiki says always 0).
+ ///
+ public uint Unknown0 { get; set; }
+
+ ///
+ /// Number of records in MBMI chunk for this mesh.
+ ///
+ public uint MBMICount { get; set; }
+
+ ///
+ /// Number of records in MBNV chunk for this mesh.
+ ///
+ public uint MBNVCount { get; set; }
+
+ ///
+ /// Offset to start record in MBMI chunk for this mesh.
+ ///
+ public uint MBMIStart { get; set; }
+
+ ///
+ /// Offset to start record in MBNV chunk for this mesh.
+ ///
+ public uint MBNVStart { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MBMHEntry()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MBMHEntry(byte[] data)
+ {
+ using (var ms = new MemoryStream(data))
+ using (var br = new BinaryReader(ms))
+ {
+ MapObjectID = br.ReadUInt32();
+ TextureID = br.ReadUInt32();
+ Unknown0 = br.ReadUInt32();
+ MBMICount = br.ReadUInt32();
+ MBNVCount = br.ReadUInt32();
+ MBMIStart = br.ReadUInt32();
+ MBNVStart = br.ReadUInt32();
+ }
+ }
+
+ ///
+ /// Gets the size of an entry.
+ ///
+ /// The size.
+ public static int GetSize()
+ {
+ return 28;
+ }
+
+ ///
+ /// Gets the size of the data contained in this chunk.
+ ///
+ /// The size.
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ bw.Write(MapObjectID);
+ bw.Write(TextureID);
+ bw.Write(Unknown0);
+ bw.Write(MBMICount);
+ bw.Write(MBNVCount);
+ bw.Write(MBMIStart);
+ bw.Write(MBNVStart);
+
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Entries/Legion/MBNVEntry.cs b/Warcraft.NET/Files/ADT/Entries/Legion/MBNVEntry.cs
new file mode 100644
index 0000000..371a0c7
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Entries/Legion/MBNVEntry.cs
@@ -0,0 +1,92 @@
+using System.IO;
+using System.Numerics;
+using Warcraft.NET.Extensions;
+using Warcraft.NET.Files.Structures;
+
+namespace Warcraft.NET.Files.ADT.Entries.Legion
+{
+ ///
+ /// Blend mesh vertices entry.
+ ///
+ public class MBNVEntry
+ {
+ ///
+ /// Vertex position.
+ ///
+ public Vector3 Position { get; set; }
+
+ ///
+ /// Vertex normal.
+ ///
+ public Vector3 Normal { get; set; }
+
+ ///
+ /// Texture/UV coordinate.
+ ///
+ public Vector2 TextureCoordinates { get; set; }
+
+ ///
+ /// Color.
+ ///
+ public RGBA[] Color { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MBNVEntry()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MBNVEntry(byte[] data)
+ {
+ using (var ms = new MemoryStream(data))
+ using (var br = new BinaryReader(ms))
+ {
+ Position = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
+ Normal = new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle());
+ TextureCoordinates = new Vector2(br.ReadSingle(), br.ReadSingle());
+ Color = new RGBA[3];
+ for (var i = 0; i < 3; i++)
+ {
+ Color[i] = br.ReadRGBA();
+ }
+ }
+ }
+
+ ///
+ /// Gets the size of an entry.
+ ///
+ /// The size.
+ public static int GetSize()
+ {
+ return 44;
+ }
+
+ ///
+ /// Gets the size of the data contained in this chunk.
+ ///
+ /// The size.
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ bw.WriteVector3(Position);
+ bw.WriteVector3(Normal);
+ bw.Write(TextureCoordinates.X);
+ bw.Write(TextureCoordinates.Y);
+
+ for (var i = 0; i < 3; i++)
+ {
+ bw.WriteRGBA(Color[i]);
+ }
+
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Entries/Legion/MLLLEntry.cs b/Warcraft.NET/Files/ADT/Entries/Legion/MLLLEntry.cs
new file mode 100644
index 0000000..8749215
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Entries/Legion/MLLLEntry.cs
@@ -0,0 +1,86 @@
+using System.IO;
+
+namespace Warcraft.NET.Files.ADT.Entries.Legion
+{
+ ///
+ /// LOD level entry.
+ ///
+ public class MLLLEntry
+ {
+ ///
+ /// LOD bands.
+ ///
+ public float LODBands { get; set; }
+
+ ///
+ /// Height length.
+ ///
+ public uint HeightLength { get; set; }
+
+ ///
+ /// Height index.
+ ///
+ public uint HeightIndex { get; set; }
+
+ ///
+ /// MapAreaLow (WDL) length.
+ ///
+ public uint MapAreaLowLength { get; set; }
+
+ ///
+ /// MapAreaLow (WDL) index.
+ ///
+ public uint MapAreaLowIndex { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLLLEntry()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLLLEntry(byte[] data)
+ {
+ using (var ms = new MemoryStream(data))
+ using (var br = new BinaryReader(ms))
+ {
+ LODBands = br.ReadSingle();
+ HeightLength = br.ReadUInt32();
+ HeightIndex = br.ReadUInt32();
+ MapAreaLowLength = br.ReadUInt32();
+ MapAreaLowIndex = br.ReadUInt32();
+ }
+ }
+
+ ///
+ /// Gets the size of an entry.
+ ///
+ /// The size.
+ public static int GetSize()
+ {
+ return 20;
+ }
+
+ ///
+ /// Gets the size of the data contained in this chunk.
+ ///
+ /// The size.
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ bw.Write(LODBands);
+ bw.Write(HeightLength);
+ bw.Write(HeightIndex);
+ bw.Write(MapAreaLowLength);
+ bw.Write(MapAreaLowIndex);
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Entries/Legion/MLNDEntry.cs b/Warcraft.NET/Files/ADT/Entries/Legion/MLNDEntry.cs
new file mode 100644
index 0000000..e46b2e5
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Entries/Legion/MLNDEntry.cs
@@ -0,0 +1,93 @@
+using System.IO;
+
+namespace Warcraft.NET.Files.ADT.Entries.Legion
+{
+ ///
+ /// LOD quad tree entry.
+ ///
+ public class MLNDEntry
+ {
+ ///
+ /// MLVI used element offset
+ ///
+ public uint MLVIOffset { get; set; }
+
+ ///
+ /// MLVI used element length
+ ///
+ public uint MLVILength { get; set; }
+
+ ///
+ /// Unknown 0.
+ ///
+ public uint Unknown0 { get; set; }
+
+ ///
+ /// Unknown 1.
+ ///
+ public uint Unknown1 { get; set; }
+
+ ///
+ /// Indexes into MLND for child leaves.
+ ///
+ public ushort[] Indices { get; set; }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public MLNDEntry()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// ExtendedData.
+ public MLNDEntry(byte[] data)
+ {
+ using (var ms = new MemoryStream(data))
+ using (var br = new BinaryReader(ms))
+ {
+ MLVIOffset = br.ReadUInt32();
+ MLVILength = br.ReadUInt32();
+ Unknown0 = br.ReadUInt32();
+ Unknown1 = br.ReadUInt32();
+ Indices = new ushort[4];
+ for (var i = 0; i < 4; ++i)
+ {
+ Indices[i] = br.ReadUInt16();
+ }
+ }
+ }
+
+ ///
+ /// Gets the size of an entry.
+ ///
+ /// The size.
+ public static int GetSize()
+ {
+ return 24;
+ }
+
+ ///
+ /// Gets the size of the data contained in this chunk.
+ ///
+ /// The size.
+ public byte[] Serialize(long offset = 0)
+ {
+ using (var ms = new MemoryStream())
+ using (var bw = new BinaryWriter(ms))
+ {
+ bw.Write(MLVIOffset);
+ bw.Write(MLVILength);
+ bw.Write(Unknown0);
+ bw.Write(Unknown1);
+ foreach (var index in Indices)
+ {
+ bw.Write(index);
+ }
+ return ms.ToArray();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Warcraft.NET/Files/ADT/Flags/MLLDFlags.cs b/Warcraft.NET/Files/ADT/Flags/MLLDFlags.cs
new file mode 100644
index 0000000..4deeaec
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/Flags/MLLDFlags.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace Warcraft.NET.Files.ADT.Flags
+{
+ ///
+ /// Flags for the .
+ ///
+ [Flags]
+ public enum MLLDFlags : uint
+ {
+ ///
+ /// Has Tile Data
+ ///
+ HasTileData = 0x1,
+
+ ///
+ /// Depth (first) chunk is compressed.
+ ///
+ DepthChunkCompressed = 0x2,
+
+ ///
+ /// Alpha (second) chunk is compressed.
+ ///
+ AlphaChunkCompressed = 0x4,
+ }
+}
diff --git a/Warcraft.NET/Files/ADT/TerrainLOD/Legion/TerrainLOD.cs b/Warcraft.NET/Files/ADT/TerrainLOD/Legion/TerrainLOD.cs
new file mode 100644
index 0000000..a448059
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/TerrainLOD/Legion/TerrainLOD.cs
@@ -0,0 +1,170 @@
+using System.Collections.Generic;
+using System.IO;
+using Warcraft.NET.Attribute;
+using Warcraft.NET.Extensions;
+using Warcraft.NET.Files.ADT.Chunks;
+using Warcraft.NET.Files.ADT.Chunks.Legion;
+using Warcraft.NET.Types;
+
+namespace Warcraft.NET.Files.ADT.TerrainLOD.Legion
+{
+#nullable enable
+ public class TerrainLOD : TerrainLODBase
+ {
+ ///
+ /// LOD header.
+ ///
+ [ChunkOrder(2)]
+ public MLHD Header { get; set; }
+
+ ///
+ /// LOD heightmap.
+ ///
+ [ChunkOrder(3)]
+ public MLVH Heightmap { get; set; }
+
+ ///
+ /// LOD levels.
+ ///
+ [ChunkOrder(4)]
+ public MLLL Levels { get; set; }
+
+ ///
+ /// LOD quad-tree.
+ ///
+ [ChunkOrder(5)]
+ public MLND QuadTree { get; set; }
+
+ ///
+ /// LOD Vertex Indices.
+ ///
+ [ChunkOrder(6)]
+ public MLVI VertexIndices { get; set; }
+
+ ///
+ /// LOD Skirt Indices.
+ ///
+ [ChunkOrder(7)]
+ public MLSI SkirtIndices { get; set; }
+
+ ///
+ /// Blend mesh headers.
+ ///
+ [ChunkOrder(8), ChunkOptional]
+ public MBMH BlendMeshHeaders { get; set; }
+
+ ///
+ /// Blend mesh bounding boxes.
+ ///
+ [ChunkOrder(9), ChunkOptional]
+ public MBBB BlendMeshBoundingBoxes { get; set; }
+
+ ///
+ /// Blend mesh indices.
+ ///
+ [ChunkOrder(10), ChunkOptional]
+ public MBMI BlendMeshIndices { get; set; }
+
+ ///
+ /// Blend mesh vertices.
+ ///
+ [ChunkOrder(11), ChunkOptional]
+ public MBNV BlendMeshVertices { get; set; }
+
+ ///
+ /// Blend mesh batches.
+ ///
+ [ChunkOrder(12), ChunkOptional]
+ public MBMB BlendMeshBatches { get; set; }
+
+ ///
+ /// Liquid data.
+ /// TODO: Requires additional implementation for decompressing as well as properly reading the last chunk.
+ ///
+ [ChunkOrder(13), ChunkOptional]
+ public MLLD LiquidData { get; set; }
+
+ ///
+ /// Unknown name. Wiki says "MLLN introduces a new liquid".
+ ///
+ public SynchronizedList LiquidN { get; set; } = new SynchronizedList(new List(4096));
+
+ ///
+ /// Liquid indices.
+ ///
+ public SynchronizedList LiquidIndices { get; set; } = new SynchronizedList(new List(4096));
+
+ ///
+ /// Liquid veritices.
+ ///
+ public SynchronizedList LiquidVertices { get; set; } = new SynchronizedList(new List(4096));
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TerrainLOD() : base()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The binary data.
+ public TerrainLOD(byte[] inData)
+ {
+ LoadBinaryData(inData);
+ }
+
+ ///
+ public void LoadBinaryData(byte[] inData)
+ {
+ using var ms = new MemoryStream(inData);
+ using var br = new BinaryReader(ms);
+
+ Version = br.ReadIFFChunk(false, false);
+ Header = br.ReadIFFChunk(false, false);
+ Heightmap = br.ReadIFFChunk(false, false);
+ Levels = br.ReadIFFChunk(false, false);
+ QuadTree = br.ReadIFFChunk(false, false);
+ VertexIndices = br.ReadIFFChunk(false, false);
+ SkirtIndices = br.ReadIFFChunk(false, false);
+
+ while (br.BaseStream.Position < br.BaseStream.Length)
+ {
+ var chunk = br.PeekChunkSignature();
+
+ switch (chunk)
+ {
+ case "MBMH":
+ BlendMeshHeaders = br.ReadIFFChunk(false, false);
+ break;
+ case "MBBB":
+ BlendMeshBoundingBoxes = br.ReadIFFChunk(false, false);
+ break;
+ case "MBMI":
+ BlendMeshIndices = br.ReadIFFChunk(false, false);
+ break;
+ case "MBNV":
+ BlendMeshVertices = br.ReadIFFChunk(false, false);
+ break;
+ case "MBMB":
+ BlendMeshBatches = br.ReadIFFChunk(false, false);
+ break;
+ case "MLLD":
+ LiquidData = br.ReadIFFChunk(false, false);
+ break;
+ case "MLLN":
+ LiquidN.Add(br.ReadIFFChunk(false, false));
+ break;
+ case "MLLI":
+ LiquidIndices.Add(br.ReadIFFChunk(false, false));
+ break;
+ case "MLLV":
+ LiquidVertices.Add(br.ReadIFFChunk(false, false));
+ break;
+ }
+ }
+ }
+ }
+#nullable disable
+}
diff --git a/Warcraft.NET/Files/ADT/TerrainLOD/TerrainLODBase.cs b/Warcraft.NET/Files/ADT/TerrainLOD/TerrainLODBase.cs
new file mode 100644
index 0000000..cbc3d8c
--- /dev/null
+++ b/Warcraft.NET/Files/ADT/TerrainLOD/TerrainLODBase.cs
@@ -0,0 +1,27 @@
+using Warcraft.NET.Attribute;
+using Warcraft.NET.Files.ADT.Chunks;
+
+namespace Warcraft.NET.Files.ADT.TerrainLOD
+{
+ public abstract class TerrainLODBase : ChunkedFile
+ {
+ [ChunkOrder(1)]
+ public MVER Version { get; set; }
+
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TerrainLODBase() : base()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The binary data.
+ public TerrainLODBase(byte[] inData) : base(inData)
+ {
+ }
+ }
+}
diff --git a/Warcraft.NET/Files/WDT/Entries/SL/MPL3Entry.cs b/Warcraft.NET/Files/WDT/Entries/SL/MPL3Entry.cs
index 459512c..b5ff613 100644
--- a/Warcraft.NET/Files/WDT/Entries/SL/MPL3Entry.cs
+++ b/Warcraft.NET/Files/WDT/Entries/SL/MPL3Entry.cs
@@ -110,7 +110,7 @@ public MPL3Entry(byte[] data)
/// Gets the size of an entry.
///
/// The size.
- public new static int GetSize()
+ public static int GetSize()
{
return 56;
}
@@ -119,7 +119,7 @@ public MPL3Entry(byte[] data)
/// Gets the size of the data contained in this chunk.
///
/// The size.
- public new byte[] Serialize(long offset = 0)
+ public byte[] Serialize(long offset = 0)
{
using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))