using System.IO; using System.Text; using Syroot.BinaryData; using Syroot.Maths; using Syroot.Worms.Core; namespace Syroot.Worms.Worms2 { /// /// Represents map configuration stored by the land generator in LAND.DAT files. /// Used by W2. S. https://worms2d.info/Land_Data_file. /// public class LandData : ILoadableFile, ISaveableFile { // ---- CONSTANTS ---------------------------------------------------------------------------------------------- private const int _signature = 0x1A444E4C; // "LND", 0x1A // ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------ /// /// Initializes a new instance of the class. /// public LandData() { } /// /// Initializes a new instance of the class, loading the data from the given /// . /// /// The to load the data from. public LandData(Stream stream) { Load(stream); } /// /// Initializes a new instance of the class, loading the data from the given file. /// /// The name of the file to load the data from. public LandData(string fileName) { Load(fileName); } // ---- PROPERTIES --------------------------------------------------------------------------------------------- /// /// Gets or sets the size of the landscape in pixels. /// public Vector2 Size { get; set; } /// /// Gets or sets a value indicating whether an indestructible top border will be enabled. /// public bool TopBorder { get; set; } /// /// Gets or sets an array of coordinates at which objects can be placed. /// public Vector2[] ObjectLocations { get; set; } /// /// Gets or sets an unknown value, seeming to be 0 most of the time. /// public int Unknown { get; set; } /// /// Gets or sets the visual foreground image. /// public Img Foreground { get; set; } /// /// Gets or sets the collision mask of the landscape. /// public Img CollisionMask { get; set; } /// /// Gets or sets the visual background image. /// public Img Background { get; set; } /// /// Gets or sets an image of unknown use. /// public Img UnknownImage { get; set; } /// /// Gets or sets the path to the land image file. /// public string LandTexturePath { get; set; } /// /// Gets or sets the path to the Water.dir file. /// public string WaterDirPath { get; set; } // ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- /// /// Loads the data from the given . /// /// The to load the data from. public void Load(Stream stream) { using (BinaryStream reader = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true)) { // Read the header. if (reader.ReadInt32() != _signature) { throw new InvalidDataException("Invalid LND file signature."); } int fileSize = reader.ReadInt32(); // Read the data. Size = reader.ReadStruct(); TopBorder = reader.ReadBoolean(BooleanCoding.Dword); // Read the possible object coordinate array. ObjectLocations = reader.ReadStructs(reader.ReadInt32()); Unknown = reader.ReadInt32(); // Read the image data. Foreground = reader.Load(); CollisionMask = reader.Load(); Background = reader.Load(); UnknownImage = reader.Load(); // Read the file paths. LandTexturePath = reader.ReadString(StringCoding.ByteCharCount); WaterDirPath = reader.ReadString(StringCoding.ByteCharCount); } } /// /// Loads the data from the given file. /// /// The name of the file to load the data from. public void Load(string fileName) { using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { Load(stream); } } /// /// Saves the data into the given . /// /// The to save the data to. public void Save(Stream stream) { using (BinaryStream writer = new BinaryStream(stream, encoding: Encoding.ASCII)) { // Write the header. writer.Write(_signature); uint fileSizeOffset = writer.ReserveOffset(); // Write the data. writer.Write(Size); writer.Write(TopBorder, BooleanCoding.Dword); // Write the possible object coordinate array. writer.Write(ObjectLocations.Length); writer.Write(ObjectLocations); writer.Write(Unknown); // Write the image data. Foreground.Save(writer.BaseStream); CollisionMask.Save(writer.BaseStream); Background.Save(writer.BaseStream); UnknownImage.Save(writer.BaseStream); // Write the file paths. writer.Write(LandTexturePath, StringCoding.ByteCharCount); writer.Write(WaterDirPath, StringCoding.ByteCharCount); writer.SatisfyOffset(fileSizeOffset, (int)writer.Position); } } /// /// Saves the data in the given file. /// /// The name of the file to save the data in. public void Save(string fileName) { using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) { Save(stream); } } } }