mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-01-13 15:27:59 +03:00
Added support for loading Land.dat files.
This commit is contained in:
parent
a2a368baed
commit
5f40d63c03
@ -22,6 +22,7 @@ Formats of the second generation 2D games are mostly focused right now.
|
||||
|-------------------|:---------:|:-----------:|:----:|:----:|
|
||||
| Archive | DIR | W2, WA, WWP | Yes | Yes |
|
||||
| Image | IMG | W2, WA, WWP | Yes | No |
|
||||
| Land Data | LAND.DAT | W2, WA, WWP | Yes | No |
|
||||
| Mission | DAT | W2 | No | No |
|
||||
| Mission | WAM | WA, WWP | No | No |
|
||||
| Monochrome Map | LEV | W2 | No | No |
|
||||
|
@ -18,8 +18,6 @@ namespace Syroot.Worms.Test
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
Palette palette = new Palette("C:\\Games\\Worms World Party\\graphics\\palettes\\wwp.pal");
|
||||
|
||||
Console.WriteLine("Done.");
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
@ -14,12 +14,9 @@ namespace Syroot.Worms.UnitTest.Common
|
||||
{
|
||||
// ---- MEMBERS ------------------------------------------------------------------------------------------------
|
||||
|
||||
private static readonly string[] _gamePaths =
|
||||
{
|
||||
@"C:\Games\Worms2",
|
||||
@"C:\Games\Worms Armageddon 3.7.2.1",
|
||||
@"C:\Games\Worms World Party"
|
||||
};
|
||||
private static readonly string[] _gamePathsWorms2 = { @"C:\Games\Worms2" };
|
||||
private static readonly string[] _gamePathsWormsArmageddon = { @"C:\Games\Worms Armageddon 3.7.2.1" };
|
||||
private static readonly string[] _gamePathsWormsWorldParty = { @"C:\Games\Worms World Party" };
|
||||
|
||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||
|
||||
@ -28,11 +25,13 @@ namespace Syroot.Worms.UnitTest.Common
|
||||
/// optional array <paramref name="excludedFiles"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the files to load.</typeparam>
|
||||
/// <param name="games">The games to test.</param>
|
||||
/// <param name="wildcard">The wildcard to match.</param>
|
||||
/// <param name="excludedFiles">Optionally, the files to exclude.</param>
|
||||
internal static void LoadFiles<T>(string wildcard, string[] excludedFiles = null) where T : ILoadableFile, new()
|
||||
internal static void LoadFiles<T>(Game games, string wildcard, string[] excludedFiles = null)
|
||||
where T : ILoadableFile, new()
|
||||
{
|
||||
foreach (string fileName in FindFiles(wildcard))
|
||||
foreach (string fileName in FindFiles(games, wildcard))
|
||||
{
|
||||
if (excludedFiles?.Contains(Path.GetFileName(fileName), StringComparer.OrdinalIgnoreCase) == true)
|
||||
{
|
||||
@ -47,21 +46,46 @@ namespace Syroot.Worms.UnitTest.Common
|
||||
}
|
||||
|
||||
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of files found in any of the paths provided in the _gamePaths variable which match the
|
||||
/// specified <paramref name="wildcard"/>.
|
||||
/// </summary>
|
||||
/// <param name="wildcard">The wildcard which files have to match.</param>
|
||||
/// <returns>A list of files matching the search.</returns>
|
||||
private static List<string> FindFiles(string wildcard)
|
||||
|
||||
private static List<string> FindFiles(Game games, string wildcard)
|
||||
{
|
||||
List<string> gamePaths = GetGamePaths(games);
|
||||
List<string> files = new List<string>();
|
||||
foreach (string testPath in _gamePaths)
|
||||
foreach (string testPath in gamePaths)
|
||||
{
|
||||
files.AddRange(Directory.GetFiles(testPath, wildcard, SearchOption.AllDirectories));
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
private static List<string> GetGamePaths(Game game)
|
||||
{
|
||||
List<string> gamePaths = new List<string>();
|
||||
if (game.HasFlag(Game.Worms2))
|
||||
{
|
||||
gamePaths.AddRange(_gamePathsWorms2);
|
||||
}
|
||||
if (game.HasFlag(Game.WormsArmageddon))
|
||||
{
|
||||
gamePaths.AddRange(_gamePathsWormsArmageddon);
|
||||
}
|
||||
if (game.HasFlag(Game.WormsWorldParty))
|
||||
{
|
||||
gamePaths.AddRange(_gamePathsWormsWorldParty);
|
||||
}
|
||||
return gamePaths;
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum Game
|
||||
{
|
||||
Worms2 = 1 << 0,
|
||||
WormsArmageddon = 1 << 1,
|
||||
WormsWorldParty = 1 << 2,
|
||||
|
||||
Gen2 = Worms2 | WormsArmageddon | WormsWorldParty,
|
||||
Armageddon = WormsArmageddon | WormsWorldParty,
|
||||
All = -1
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace Syroot.Worms.UnitTest.Gen2
|
||||
[TestMethod]
|
||||
public void LoadArchives()
|
||||
{
|
||||
TestHelpers.LoadFiles<Archive>("*.dir");
|
||||
TestHelpers.LoadFiles<Archive>(Game.Gen2, "*.dir");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
25
src/Syroot.Worms.UnitTest/Gen2/Armageddon/LandDataTests.cs
Normal file
25
src/Syroot.Worms.UnitTest/Gen2/Armageddon/LandDataTests.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Syroot.Worms.Gen2.Armageddon;
|
||||
using Syroot.Worms.UnitTest.Common;
|
||||
|
||||
namespace Syroot.Worms.UnitTest.Gen2.Armageddon
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a collection of tests for the <see cref="LandData"/> class.
|
||||
/// </summary>
|
||||
[TestCategory("LandData (Armageddon)")]
|
||||
[TestClass]
|
||||
public class LandDataTests
|
||||
{
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Loads all files found in any game directories.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void LoadLandData()
|
||||
{
|
||||
TestHelpers.LoadFiles<LandData>(Game.Armageddon, "land.dat");
|
||||
}
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ namespace Syroot.Worms.UnitTest.Gen2.Armageddon
|
||||
[TestMethod]
|
||||
public void LoadSchemes()
|
||||
{
|
||||
TestHelpers.LoadFiles<Scheme>("*.wsc");
|
||||
TestHelpers.LoadFiles<Scheme>(Game.Armageddon, "*.wsc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace Syroot.Worms.UnitTest.Gen2
|
||||
[TestMethod]
|
||||
public void LoadImages()
|
||||
{
|
||||
TestHelpers.LoadFiles<Image>("*.img");
|
||||
TestHelpers.LoadFiles<Image>(Game.All, "*.img");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace Syroot.Worms.UnitTest.Gen2
|
||||
[TestMethod]
|
||||
public void LoadPalettes()
|
||||
{
|
||||
TestHelpers.LoadFiles<Palette>("*.pal", new string[]
|
||||
TestHelpers.LoadFiles<Palette>(Game.Gen2, "*.pal", new string[]
|
||||
{
|
||||
"wwp.pal", // Contains 4 bytes of trash after the data chunk.
|
||||
"wwpmaped.pal" // Contains 4 bytes of trash after the data chunk.
|
||||
|
25
src/Syroot.Worms.UnitTest/Gen2/Worms2/LandDataTests.cs
Normal file
25
src/Syroot.Worms.UnitTest/Gen2/Worms2/LandDataTests.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Syroot.Worms.Gen2.Worms2;
|
||||
using Syroot.Worms.UnitTest.Common;
|
||||
|
||||
namespace Syroot.Worms.UnitTest.Gen2.Worms2
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a collection of tests for the <see cref="LandData"/> class.
|
||||
/// </summary>
|
||||
[TestCategory("LandData (Worms2)")]
|
||||
[TestClass]
|
||||
public class LandDataTests
|
||||
{
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Loads all files found in any game directories.
|
||||
/// </summary>
|
||||
[TestMethod]
|
||||
public void LoadLandData()
|
||||
{
|
||||
TestHelpers.LoadFiles<LandData>(Game.Worms2, "land.dat");
|
||||
}
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ namespace Syroot.Worms.UnitTest.Gen2.Worms2
|
||||
[TestMethod]
|
||||
public void LoadSchemeOptions()
|
||||
{
|
||||
TestHelpers.LoadFiles<SchemeOptions>("*.opt");
|
||||
TestHelpers.LoadFiles<SchemeOptions>(Game.Worms2, "*.opt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace Syroot.Worms.UnitTest.Gen2.Worms2
|
||||
[TestMethod]
|
||||
public void LoadSchemeWeapons()
|
||||
{
|
||||
TestHelpers.LoadFiles<SchemeWeapons>("*.wep");
|
||||
TestHelpers.LoadFiles<SchemeWeapons>(Game.Worms2, "*.wep");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ namespace Syroot.Worms.Core
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the RIFF data from.</param>
|
||||
protected void LoadRiff(Stream stream)
|
||||
{
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII))
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII, true))
|
||||
{
|
||||
// Read the file header.
|
||||
if (reader.ReadString(_signature.Length) != _signature)
|
||||
|
@ -65,7 +65,7 @@ namespace Syroot.Worms.Gen2
|
||||
}
|
||||
|
||||
Clear();
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII))
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII, true))
|
||||
{
|
||||
// Read the header.
|
||||
if (reader.ReadInt32() != _signature)
|
||||
|
@ -7,8 +7,8 @@ using Syroot.Worms.Core;
|
||||
namespace Syroot.Worms.Gen2.Armageddon
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents scheme options stored in an OPT file which contains game settings.
|
||||
/// S. https://worms2d.info/Options_file.
|
||||
/// Represents map configuration stored by the land generator in LAND.DAT files.
|
||||
/// Used by WA and WWP. S. https://worms2d.info/Land_Data_file.
|
||||
/// </summary>
|
||||
public class LandData : ILoadableFile
|
||||
{
|
||||
@ -18,6 +18,13 @@ namespace Syroot.Worms.Gen2.Armageddon
|
||||
|
||||
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class.
|
||||
/// </summary>
|
||||
public LandData()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class, loading the data from the given
|
||||
/// <see cref="Stream"/>.
|
||||
@ -92,7 +99,7 @@ namespace Syroot.Worms.Gen2.Armageddon
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public void Load(Stream stream)
|
||||
{
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII))
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII, true))
|
||||
{
|
||||
// Read the header.
|
||||
if (reader.ReadInt32() != _signature)
|
||||
@ -107,8 +114,8 @@ namespace Syroot.Worms.Gen2.Armageddon
|
||||
WaterHeight = reader.ReadInt32();
|
||||
|
||||
// Read the possible object coordinate array.
|
||||
int badObjectLocations = reader.ReadInt32(); // TODO: Check what this is used for.
|
||||
ObjectLocations = new Vector2[reader.ReadInt32()];
|
||||
int objectLocationCountAgain = reader.ReadInt32(); // TODO: Repetitive or useful?
|
||||
for (int i = 0; i < ObjectLocations.Length; i++)
|
||||
{
|
||||
ObjectLocations[i] = reader.ReadStruct<Vector2>();
|
||||
|
@ -608,7 +608,7 @@ namespace Syroot.Worms.Gen2.Armageddon
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public void Load(Stream stream)
|
||||
{
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII))
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII, true))
|
||||
{
|
||||
// Read the header.
|
||||
if (reader.ReadString(_signature.Length) != _signature)
|
||||
|
@ -80,7 +80,7 @@ namespace Syroot.Worms.Gen2
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public void Load(Stream stream)
|
||||
{
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII))
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII, true))
|
||||
{
|
||||
// Read the header.
|
||||
if (reader.ReadInt32() != _signature)
|
||||
@ -117,10 +117,10 @@ namespace Syroot.Worms.Gen2
|
||||
}
|
||||
}
|
||||
|
||||
Size = reader.ReadStruct<Vector2>();
|
||||
|
||||
// Read the image data, which might be compressed.
|
||||
byte[] data = new byte[Size.X * Size.Y * (BitsPerPixel / 8)];
|
||||
Size = new Vector2(reader.ReadInt16(), reader.ReadInt16());
|
||||
|
||||
// Read the bytes, which might be compressed.
|
||||
byte[] data = new byte[Size.X * Size.Y * BitsPerPixel / 8];
|
||||
if (flags.HasFlag(Flags.Compressed))
|
||||
{
|
||||
Team17Compression.Decompress(reader.BaseStream, ref data);
|
||||
@ -129,6 +129,7 @@ namespace Syroot.Worms.Gen2
|
||||
{
|
||||
data = reader.ReadBytes(data.Length);
|
||||
}
|
||||
|
||||
Data = data;
|
||||
}
|
||||
}
|
||||
|
147
src/Syroot.Worms/Gen2/Worms2/LandData.cs
Normal file
147
src/Syroot.Worms/Gen2/Worms2/LandData.cs
Normal file
@ -0,0 +1,147 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Syroot.IO;
|
||||
using Syroot.Maths;
|
||||
using Syroot.Worms.Core;
|
||||
|
||||
namespace Syroot.Worms.Gen2.Worms2
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents map configuration stored by the land generator in LAND.DAT files.
|
||||
/// Used by W2. S. https://worms2d.info/Land_Data_file.
|
||||
/// </summary>
|
||||
public class LandData : ILoadableFile
|
||||
{
|
||||
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
||||
|
||||
private const int _signature = 0x1A444E4C; // "LND", 0x1A
|
||||
|
||||
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class.
|
||||
/// </summary>
|
||||
public LandData()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class, loading the data from the given
|
||||
/// <see cref="Stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public LandData(Stream stream)
|
||||
{
|
||||
Load(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LandData"/> class, loading the data from the given file.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file to load the data from.</param>
|
||||
public LandData(string fileName)
|
||||
{
|
||||
Load(fileName);
|
||||
}
|
||||
|
||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the landscape in pixels.
|
||||
/// </summary>
|
||||
public Vector2 Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether an indestructible top border will be enabled.
|
||||
/// </summary>
|
||||
public bool TopBorder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an array of coordinates at which objects can be placed.
|
||||
/// </summary>
|
||||
public Vector2[] ObjectLocations { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the visual foreground image.
|
||||
/// </summary>
|
||||
public Image Foreground { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collision mask of the landscape.
|
||||
/// </summary>
|
||||
public Image CollisionMask { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the visual background image.
|
||||
/// </summary>
|
||||
public Image Background { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an image of unknown use.
|
||||
/// </summary>
|
||||
public Image UnknownImage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to the land image file.
|
||||
/// </summary>
|
||||
public string LandTexturePath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to the Water.dir file.
|
||||
/// </summary>
|
||||
public string WaterDirPath { get; set; }
|
||||
|
||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Loads the data from the given <see cref="Stream"/>.
|
||||
/// </summary>
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public void Load(Stream stream)
|
||||
{
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII, true))
|
||||
{
|
||||
// Read the header.
|
||||
if (reader.ReadInt32() != _signature)
|
||||
{
|
||||
throw new InvalidDataException("Invalid LND file signature.");
|
||||
}
|
||||
int fileLength = reader.ReadInt32();
|
||||
|
||||
// Read the data.
|
||||
Size = reader.ReadStruct<Vector2>();
|
||||
TopBorder = reader.ReadBoolean(BinaryBooleanFormat.NonZeroDword);
|
||||
|
||||
// Read the possible object coordinate array.
|
||||
ObjectLocations = new Vector2[reader.ReadInt32()];
|
||||
for (int i = 0; i < ObjectLocations.Length; i++)
|
||||
{
|
||||
ObjectLocations[i] = reader.ReadStruct<Vector2>();
|
||||
}
|
||||
int unknown = reader.ReadInt32(); // Seems 0.
|
||||
|
||||
// Read the image data.
|
||||
Foreground = new Image(stream);
|
||||
CollisionMask = new Image(stream);
|
||||
Background = new Image(stream);
|
||||
UnknownImage = new Image(stream);
|
||||
|
||||
// Read the file paths.
|
||||
LandTexturePath = reader.ReadString(BinaryStringFormat.ByteLengthPrefix);
|
||||
WaterDirPath = reader.ReadString(BinaryStringFormat.ByteLengthPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the data from the given file.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name of the file to load the data from.</param>
|
||||
public void Load(string fileName)
|
||||
{
|
||||
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
Load(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ namespace Syroot.Worms.Gen2.Worms2
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents scheme options stored in an OPT file which contains game settings.
|
||||
/// S. https://worms2d.info/Options_file.
|
||||
/// Used by W2. S. https://worms2d.info/Options_file.
|
||||
/// </summary>
|
||||
public class SchemeOptions : ILoadableFile, ISaveableFile
|
||||
{
|
||||
@ -221,7 +221,7 @@ namespace Syroot.Worms.Gen2.Worms2
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public void Load(Stream stream)
|
||||
{
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII))
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII, true))
|
||||
{
|
||||
// Read the header.
|
||||
if (reader.ReadString(_signature.Length) != _signature)
|
||||
|
@ -7,7 +7,7 @@ namespace Syroot.Worms.Gen2.Worms2
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents scheme weapons stored in an WEP file which contains armory configuration.
|
||||
/// S. https://worms2d.info/Weapons_file.
|
||||
/// Used by W2. S. https://worms2d.info/Weapons_file.
|
||||
/// </summary>
|
||||
public class SchemeWeapons : ILoadableFile, ISaveableFile
|
||||
{
|
||||
@ -62,7 +62,7 @@ namespace Syroot.Worms.Gen2.Worms2
|
||||
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
||||
public void Load(Stream stream)
|
||||
{
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII))
|
||||
using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII, true))
|
||||
{
|
||||
// Read the header.
|
||||
reader.Seek(_trashLength);
|
||||
|
Loading…
x
Reference in New Issue
Block a user