Fix saving TeamContainer instances and add local test files for them.

This commit is contained in:
Ray Koopa 2020-06-27 16:58:34 +02:00
parent fabc3e98b2
commit 7e3fcb766c
9 changed files with 100 additions and 121 deletions

View File

@ -211,7 +211,7 @@ namespace Syroot.Worms.Armageddon
{
BitsPerPixel = 8,
Size = new Size(24, 32),
Palette = reader.ReadStructs<Color>(256),
Palette = reader.ReadColors(256),
Data = reader.ReadBytes(24 * 32)
};
}
@ -234,7 +234,7 @@ namespace Syroot.Worms.Armageddon
{
BitsPerPixel = 8,
Size = new Size(20, 17),
Palette = reader.ReadStructs<Color>(256),
Palette = reader.ReadColors(256),
Data = reader.ReadBytes(20 * 17)
};
@ -264,7 +264,7 @@ namespace Syroot.Worms.Armageddon
if (GraveSprite < 0)
{
writer.WriteString(GraveFileName, 0x20);
writer.WriteStructs(Grave.Palette);
writer.WriteColors(Grave.Palette);
writer.Write(Grave.Data);
}
@ -282,7 +282,7 @@ namespace Syroot.Worms.Armageddon
writer.WriteStructs(MissionStatuses);
writer.WriteString(FlagFileName, 0x20);
writer.WriteStructs(Flag.Palette);
writer.WriteColors(Flag.Palette);
writer.Write(Flag.Data);
writer.Write(DeathmatchRank);
@ -301,14 +301,11 @@ namespace Syroot.Worms.Armageddon
[DebuggerDisplay("TeamMissionStatus Attemps={Attempts} Medal={Medal}")]
public struct TeamMissionStatus
{
/// <summary>
/// The number of attempts the team required to solve the mission.
/// </summary>
public int Attempts;
// ---- FIELDS -------------------------------------------------------------------------------------------------
/// <summary>
/// The medal the team got to solve the mission.
/// </summary>
/// <summary>The number of attempts the team required to solve the mission.</summary>
public int Attempts;
/// <summary>The medal the team got to solve the mission.</summary>
public int Medal;
}
@ -317,44 +314,21 @@ namespace Syroot.Worms.Armageddon
/// </summary>
public enum TeamWeapon : byte
{
/// <summary>
/// The Flame Thrower weapon.
/// </summary>
/// <summary>The Flame Thrower weapon.</summary>
Flamethrower,
/// <summary>
/// The Mole Bomb weapon.
/// </summary>
/// <summary>The Mole Bomb weapon.</summary>
MoleBomb,
/// <summary>
/// The Old Woman weapon.
/// </summary>
/// <summary>The Old Woman weapon.</summary>
OldWoman,
/// <summary>
/// The Homing Pigeon weapon.
/// </summary>
/// <summary>The Homing Pigeon weapon.</summary>
HomingPigeon,
/// <summary>
/// The Sheep Launcher weapon.
/// </summary>
/// <summary>The Sheep Launcher weapon.</summary>
SheepLauncher,
/// <summary>
/// The Mad Cow weapon.
/// </summary>
/// <summary>The Mad Cow weapon.</summary>
MadCow,
/// <summary>
/// The Holy Hand Grenade weapon.
/// </summary>
/// <summary>The Holy Hand Grenade weapon.</summary>
HolyHandGrenade,
/// <summary>
/// The Super Sheep or Aqua Sheep weapon.
/// </summary>
/// <summary>The Super Sheep or Aqua Sheep weapon.</summary>
SuperSheep
}
}

View File

@ -57,7 +57,7 @@ namespace Syroot.Worms.Armageddon
/// <summary>
/// Gets or sets the list of <see cref="Team"/> instances stored.
/// </summary>
public List<Team> Teams { get; set; }
public IList<Team> Teams { get; set; }
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
@ -90,7 +90,7 @@ namespace Syroot.Worms.Armageddon
/// <inheritdoc/>
public void Save(Stream stream)
{
using BinaryStream writer = new BinaryStream(stream, encoding: Encoding.ASCII);
using BinaryStream writer = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true);
// Write the header.
writer.Write(_signature, StringCoding.ZeroTerminated);
@ -120,74 +120,35 @@ namespace Syroot.Worms.Armageddon
[Flags]
public enum UnlockedFeatures : int
{
/// <summary>
/// The utility weapon Laser Sight can be configured.
/// </summary>
/// <summary>No features have been unlocked yet.</summary>
None,
/// <summary>The utility weapon Laser Sight can be configured.</summary>
UtilityLaserSight = 1 << 0,
/// <summary>
/// The utility weapon Fast Walk can be configured.
/// </summary>
/// <summary>The utility weapon Fast Walk can be configured.</summary>
UtilityFastWalk = 1 << 1,
/// <summary>
/// The utility weapon Invisibility can be configured.
/// </summary>
/// <summary>The utility weapon Invisibility can be configured.</summary>
UtilityInvisibility = 1 << 2,
/// <summary>
/// The utility weapon Low Gravity can be configured.
/// </summary>
/// <summary>The utility weapon Low Gravity can be configured.</summary>
UtilityLowGravity = 1 << 3,
/// <summary>
/// The utility weapon Jetpack can be configured.
/// </summary>
/// <summary>The utility weapon Jetpack can be configured.</summary>
UtilityJetpack = 1 << 4,
/// <summary>
/// The Grenade upgrade can be enabled.
/// </summary>
/// <summary>The Grenade upgrade can be enabled.</summary>
UpgradedGrenade = 1 << 8,
/// <summary>
/// The Shotgun upgrade can be enabled.
/// </summary>
/// <summary>The Shotgun upgrade can be enabled.</summary>
UpgradedShotgun = 1 << 9,
/// <summary>
/// The cluster upgrade can be enabled.
/// </summary>
/// <summary>The cluster upgrade can be enabled.</summary>
UpgradedClusters = 1 << 10,
/// <summary>
/// The Longbow upgrade can be enabled.
/// </summary>
/// <summary>The Longbow upgrade can be enabled.</summary>
UpgradedLongbow = 1 << 11,
/// <summary>
/// The upgrade of Super Sheeps to become Aqua Sheeps can be enabled.
/// </summary>
/// <summary>The upgrade of Super Sheeps to become Aqua Sheeps can be enabled.</summary>
AquaSheep = 1 << 12,
/// <summary>
/// Worms can have infinite health and are killable only by drowning them.
/// </summary>
/// <summary>Worms can have infinite health and are killable only by drowning them.</summary>
GodWorms = 1 << 16,
/// <summary>
/// Blood effects when hitting worms can be enabled.
/// </summary>
/// <summary>Blood effects when hitting worms can be enabled.</summary>
BloodFx = 1 << 17,
/// <summary>
/// Every crate explodes with a sheep.
/// </summary>
/// <summary>Every crate explodes with a sheep.</summary>
SheepHeaven = 1 << 18,
/// <summary>
/// Map terrain can be indestructible and Full Wormage scheme is accessible.
/// </summary>
/// <summary>Map terrain can be indestructible and Full Wormage scheme is accessible.</summary>
IndestructibleAndFullWormage = 1 << 24
}
}

View File

@ -210,7 +210,7 @@ namespace Syroot.Worms.WorldParty
{
BitsPerPixel = 8,
Size = new Size(24, 32),
Palette = reader.ReadStructs<Color>(256),
Palette = reader.ReadColors(256),
Data = reader.ReadBytes(24 * 32)
};
}
@ -233,7 +233,7 @@ namespace Syroot.Worms.WorldParty
{
BitsPerPixel = 8,
Size = new Size(20, 17),
Palette = reader.ReadStructs<Color>(256),
Palette = reader.ReadColors(256),
Data = reader.ReadBytes(20 * 17)
};
@ -262,7 +262,7 @@ namespace Syroot.Worms.WorldParty
if (GraveSprite < 0)
{
writer.WriteString(GraveFileName, 0x20);
writer.WriteStructs(Grave.Palette);
writer.WriteColors(Grave.Palette);
writer.Write(Grave.Data);
}
@ -280,7 +280,7 @@ namespace Syroot.Worms.WorldParty
writer.WriteStructs(MissionStatuses);
writer.WriteString(FlagFileName, 0x20);
writer.WriteStructs(Flag.Palette);
writer.WriteColors(Flag.Palette);
writer.Write(Flag.Data);
writer.Write(Unknown1);

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@ -22,7 +23,7 @@ namespace Syroot.Worms.Core.IO
/// Reads an <see cref="ILoadable"/> instance from the current stream.
/// </summary>
/// <typeparam name="T">The type of the <see cref="ILoadable"/> class to instantiate.</typeparam>
/// <param name="self">The extended <see cref="BinaryStream"/>.</param>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <returns>The <see cref="ILoadable"/> instance.</returns>
public static T Load<T>(this BinaryStream self) where T : ILoadable, new()
{
@ -35,7 +36,7 @@ namespace Syroot.Worms.Core.IO
/// Reads <see cref="ILoadable"/> instances from the current stream.
/// </summary>
/// <typeparam name="T">The type of the <see cref="ILoadable"/> class to instantiate.</typeparam>
/// <param name="self">The extended <see cref="BinaryStream"/>.</param>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="count">The number of instances to read.</param>
/// <returns>The <see cref="ILoadable"/> instances.</returns>
public static T[] Load<T>(this BinaryStream self, int count) where T : ILoadable, new()
@ -46,10 +47,31 @@ namespace Syroot.Worms.Core.IO
return instances;
}
/// <summary>
/// Reads an RGBA 32-bit color.
/// </summary>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <returns>The read color.</returns>
public static Color ReadColor(this BinaryStream self) => Color.FromArgb(self.ReadInt32());
/// <summary>
/// Reads <paramref name="count"/> RGBA 32-bit colors.
/// </summary>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="count">The number of values to read.</param>
/// <returns>The read colors.</returns>
public static Color[] ReadColors(this BinaryStream self, int count)
{
Color[] values = new Color[count];
for (int i = 0; i < count; i++)
values[i] = Color.FromArgb(self.ReadInt32());
return values;
}
/// <summary>
/// Reads a 0-terminated string which is stored in a fixed-size block of <paramref name="length"/> bytes.
/// </summary>
/// <param name="self">The extended <see cref="BinaryStream"/>.</param>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="length">The number of bytes the fixed-size blocks takes.</param>
/// <returns>The read string.</returns>
public static string ReadString(this BinaryStream self, int length)
@ -65,10 +87,10 @@ namespace Syroot.Worms.Core.IO
/// Reads <paramref name="count"/> 0-terminated strings which are stored in a fixed-size block of
/// <paramref name="length"/> bytes.
/// </summary>
/// <param name="self">The extended <see cref="BinaryStream"/>.</param>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="count">The number of values to read.</param>
/// <param name="length">The number of bytes the fixed-size blocks takes.</param>
/// <returns>The read string.</returns>
/// <returns>The read strings.</returns>
public static string[] ReadStrings(this BinaryStream self, int count, int length)
{
string[] strings = new string[count];
@ -83,7 +105,7 @@ namespace Syroot.Worms.Core.IO
/// <typeparam name="T">The type of the structure to read.</typeparam>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <returns>The structure of type <typeparamref name="T"/>.</returns>
public static T ReadStruct<T>(this BinaryStream self) where T : struct
public static T ReadStruct<T>(this BinaryStream self) where T : unmanaged
{
// Read the raw bytes of the structure.
#if NETSTANDARD2_0
@ -106,7 +128,7 @@ namespace Syroot.Worms.Core.IO
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="count">The number of values to read.</param>
/// <returns>The structures of type <typeparamref name="T"/>.</returns>
public static T[] ReadStructs<T>(this BinaryStream self, int count) where T : struct
public static T[] ReadStructs<T>(this BinaryStream self, int count) where T : unmanaged
{
// Read the raw bytes of the structures.
#if NETSTANDARD2_0
@ -141,7 +163,7 @@ namespace Syroot.Worms.Core.IO
/// Writes the given <see cref="ISaveable"/> instance into the current stream.
/// </summary>
/// <typeparam name="T">The type of the <see cref="ISaveable"/> class to write.</typeparam>
/// <param name="self">The extended <see cref="BinaryStream"/>.</param>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="value">The instance to write into the current stream.</param>
public static void Save<T>(this BinaryStream self, T value) where T : ISaveable
{
@ -152,7 +174,7 @@ namespace Syroot.Worms.Core.IO
/// Writes the given <see cref="ISaveable"/> instances into the current stream.
/// </summary>
/// <typeparam name="T">The type of the <see cref="ISaveable"/> class to write.</typeparam>
/// <param name="self">The extended <see cref="BinaryStream"/>.</param>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="values">The instances to write into the current stream.</param>
public static void Save<T>(this BinaryStream self, IList<T> values) where T : ISaveable
{
@ -166,6 +188,25 @@ namespace Syroot.Worms.Core.IO
self.WriteInt32(value);
}
/// <summary>
/// Writes the given color.
/// </summary>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="value">The color to write.</param>
public static void WriteColor(this BinaryStream self, Color color)
=> self.Write(color.R << 24 | color.G << 16 | color.B << 8 | color.A);
/// <summary>
/// Writes the given colors.
/// </summary>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="value">The colors to write.</param>
public static void WriteColors(this BinaryStream self, IEnumerable<Color> colors)
{
foreach (Color color in colors)
WriteColor(self, color);
}
/// <summary>
/// Writes the given string into a fixed-size block of <paramref name="length"/> bytes and 0-terminates it.
/// </summary>
@ -187,7 +228,7 @@ namespace Syroot.Worms.Core.IO
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="values">The strings to write.</param>
/// <param name="length">The number of bytes a fixed-size block takes.</param>
public static void WriteStrings(this BinaryStream self, IList<string> values, int length)
public static void WriteStrings(this BinaryStream self, IEnumerable<string> values, int length)
{
foreach (string value in values)
WriteString(self, value, length);
@ -199,7 +240,7 @@ namespace Syroot.Worms.Core.IO
/// <typeparam name="T">The type of the structure to read.</typeparam>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="value">The structure to write.</param>
public static void WriteStruct<T>(this BinaryStream self, T value) where T : struct
public static void WriteStruct<T>(this BinaryStream self, T value) where T : unmanaged
{
ReadOnlySpan<byte> bytes;
unsafe { bytes = new ReadOnlySpan<byte>(Unsafe.AsPointer(ref value), Unsafe.SizeOf<T>()); }
@ -216,10 +257,10 @@ namespace Syroot.Worms.Core.IO
/// <typeparam name="T">The type of the structure to read.</typeparam>
/// <param name="self">The extended <see cref="BinaryStream"/> instance.</param>
/// <param name="values">The structures to write.</param>
public static void WriteStructs<T>(this BinaryStream self, IEnumerable<T> values) where T : struct
public static void WriteStructs<T>(this BinaryStream self, IEnumerable<T> values) where T : unmanaged
{
foreach (T value in values)
self.WriteStruct(value);
WriteStruct(self, value);
}
}
}

View File

@ -13,9 +13,9 @@ namespace Syroot.Worms.Test.Armageddon
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
/// <summary>
/// Loads all files found in any game directories.
/// Tests all files found in the test directory.
/// </summary>
[TestMethod]
public void LoadTeamContainers() => FileTester.Run<TeamContainer>(Game.Armageddon, "*.wgt");
public void LoadTeamContainers() => FileTester.Run<TeamContainer>(Game.Test, "*.wgt");
}
}

View File

@ -62,8 +62,11 @@ namespace Syroot.Worms.Test.Core
T newInstance = new T();
newInstance.Load(stream);
Debug.Write($" compare");
Assert.IsTrue(newInstance.Equals(instance));
if (instance is IEquatable<T> equatable)
{
Debug.Write($" compare");
Assert.IsTrue(((IEquatable<T>)newInstance).Equals(equatable));
}
}
Debug.WriteLine($" OK");
}