using System.Drawing; using System.IO; using System.Text; using Syroot.BinaryData; using Syroot.Worms.Core; namespace Syroot.Worms.WorldParty { /// /// Represents map configuration stored by the land generator in LAND.DAT files. /// Used by WWP. 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 Size 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 the height of the water in pixels. /// public int WaterHeight { get; set; } /// /// Gets or sets an array of coordinates at which objects can be placed. /// public Point[] ObjectLocations { 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 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); WaterHeight = reader.ReadInt32(); // Read the possible object coordinate array. ObjectLocations = reader.ReadStructs(reader.ReadInt32()); // Read the image data. Foreground = new Img(stream, true); CollisionMask = new Img(stream, true); Background = new Img(stream, true); // 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); writer.Write(WaterHeight); // Write the possible object coordinate array. writer.Write(ObjectLocations.Length); writer.Write(ObjectLocations); // Write the image data. Foreground.Save(writer.BaseStream, false, true); CollisionMask.Save(writer.BaseStream, false, true); Background.Save(writer.BaseStream, false, true); // 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); } } }