Release v4.

- Fixes remaining ProjectX issues and failing tests.
- Relaxes dependencies on other libraries.
This commit is contained in:
Ray Koopa 2020-07-01 13:31:02 +02:00
parent 5321dfb49a
commit c62d4a7551
51 changed files with 1341 additions and 1301 deletions

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Metadata --> <!-- Metadata -->
<PropertyGroup> <PropertyGroup>
<Authors>Syroot</Authors> <Authors>Syroot</Authors>
@ -10,6 +11,7 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression> <PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://gitlab.com/Syroot/Worms</PackageProjectUrl> <PackageProjectUrl>https://gitlab.com/Syroot/Worms</PackageProjectUrl>
<PackageTags>team17;worms</PackageTags> <PackageTags>team17;worms</PackageTags>
<RepositoryUrl>https://gitlab.com/Syroot/Worms</RepositoryUrl>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Include="$(MSBuildThisFileDirectory)..\res\icon.png" Pack="true" PackagePath="" /> <None Include="$(MSBuildThisFileDirectory)..\res\icon.png" Pack="true" PackagePath="" />
@ -33,4 +35,5 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

View File

@ -1,37 +1,38 @@
using System; using System;
using System.IO; using System.IO;
using Syroot.BinaryData; using Syroot.BinaryData;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
internal class ActionConverter : IBinaryConverter internal class ActionConverter : IBinaryConverter
{ {
// ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- // ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
public object? Read(Stream stream, object instance, BinaryMemberAttribute memberAttribute, /// <inheritdoc/>
ByteConverter byteConverter) public object? Read(Stream stream, object instance, BinaryMemberAttribute memberAttribute,
{ ByteConverter byteConverter)
ExplosionAction explosionAction = instance switch {
{ ExplosionAction explosionAction = instance switch
LauncherStyle launcherStyle => launcherStyle.ExplosionAction,
ClusterTarget clusterTarget => clusterTarget.ExplosionAction,
_ => throw new NotImplementedException(),
};
return explosionAction switch
{ {
ExplosionAction.None => null, LauncherStyle launcherStyle => launcherStyle.ExplosionAction,
ExplosionAction.Bounce => stream.ReadObject<BounceAction>(), ClusterTarget clusterTarget => clusterTarget.ExplosionAction,
ExplosionAction.Dig => stream.ReadObject<DigAction>(), _ => throw new NotImplementedException()
ExplosionAction.Home => stream.ReadObject<HomeAction>(), };
ExplosionAction.Roam => stream.ReadObject<RoamAction>(), return explosionAction switch
_ => throw new NotImplementedException(), {
}; ExplosionAction.Home => stream.ReadObject<HomeAction>(),
} ExplosionAction.Bounce => stream.ReadObject<BounceAction>(),
ExplosionAction.Roam => stream.ReadObject<RoamAction>(),
public void Write(Stream stream, object instance, BinaryMemberAttribute memberAttribute, object value, ExplosionAction.Dig => stream.ReadObject<DigAction>(),
ByteConverter byteConverter) _ => null
{ };
stream.WriteObject(value); }
}
} /// <inheritdoc/>
} public void Write(Stream stream, object instance, BinaryMemberAttribute memberAttribute, object value,
ByteConverter byteConverter)
{
stream.WriteObject(value);
}
}
}

View File

@ -1,12 +1,11 @@
using System; using System;
using Syroot.BinaryData;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
[Flags] [Flags]
public enum CollisionFlags : int public enum CollisionFlags : int
{ {
None = 0, None,
Unused0 = 1 << 0, Unused0 = 1 << 0,
Terrain = 1 << 1, Terrain = 1 << 1,
WormsOnTerrain = 1 << 2, WormsOnTerrain = 1 << 2,

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
@ -13,13 +14,17 @@ namespace Syroot.Worms.Armageddon.ProjectX
/// Represents a library stored in a PXL file which contains reusable weapons, files and scripts. /// Represents a library stored in a PXL file which contains reusable weapons, files and scripts.
/// Used by WA PX. S. https://worms2d.info/Project_X/Library_file. /// Used by WA PX. S. https://worms2d.info/Project_X/Library_file.
/// </summary> /// </summary>
public class Library : List<LibraryItem>, ILoadableFile, ISaveableFile public class Library : IList<LibraryItem>, ILoadableFile, ISaveableFile
{ {
// ---- CONSTANTS ---------------------------------------------------------------------------------------------- // ---- CONSTANTS ----------------------------------------------------------------------------------------------
private const int _signature = 0x1BCD0102; private const int _signature = 0x1BCD0102;
private const byte _version = 0x00; private const byte _version = 0x00;
// ---- FIELDS -------------------------------------------------------------------------------------------------
private readonly List<LibraryItem> _list = new List<LibraryItem>();
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------ // ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
/// <summary> /// <summary>
@ -42,8 +47,17 @@ namespace Syroot.Worms.Armageddon.ProjectX
// ---- PROPERTIES --------------------------------------------------------------------------------------------- // ---- PROPERTIES ---------------------------------------------------------------------------------------------
/// <inheritdoc/>
public int Count => _list.Count;
/// <summary>
/// Gets or sets the ProjectX library version.
/// </summary>
public byte Version { get; set; } public byte Version { get; set; }
/// <inheritdoc/>
bool ICollection<LibraryItem>.IsReadOnly => false;
// ---- OPERATORS ---------------------------------------------------------------------------------------------- // ---- OPERATORS ----------------------------------------------------------------------------------------------
/// <summary> /// <summary>
@ -53,8 +67,57 @@ namespace Syroot.Worms.Armageddon.ProjectX
/// <returns>All matching entries.</returns> /// <returns>All matching entries.</returns>
public IEnumerable<LibraryItem> this[string key] => this.Where(x => x.Key == key); public IEnumerable<LibraryItem> this[string key] => this.Where(x => x.Key == key);
/// <inheritdoc/>
public LibraryItem this[int index]
{
get => _list[index];
set => _list[index] = value;
}
// ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- // ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
/// <inheritdoc/>
public void Add(LibraryItem item) => _list.Add(item);
/// <inheritdoc/>
public void Clear() => _list.Clear();
/// <inheritdoc/>
public bool Contains(LibraryItem item) => _list.Contains(item);
/// <inheritdoc/>
public void CopyTo(LibraryItem[] array, int arrayIndex) => _list.CopyTo(array, arrayIndex);
/// <inheritdoc/>
public IEnumerator<LibraryItem> GetEnumerator() => _list.GetEnumerator();
/// <summary>
/// Gets all attached files.
/// </summary>
/// <returns>The enumeration of attached files.</returns>
public IEnumerable<byte[]> GetFiles()
=> this.Where(x => x.Type == LibraryItemType.File).Select(x => (byte[])x.Value);
/// <summary>
/// Gets all attached scripts.
/// </summary>
/// <returns>The enumeration of attached scripts.</returns>
public IEnumerable<string> GetScripts()
=> this.Where(x => x.Type == LibraryItemType.Script).Select(x => (string)x.Value);
/// <summary>
/// Gets all attached weapons.
/// </summary>
/// <returns>The enumeration of attached weapons.</returns>
public IEnumerable<Weapon> GetWeapons()
=> this.Where(x => x.Type == LibraryItemType.Weapon).Select(x => (Weapon)x.Value);
/// <inheritdoc/>
public int IndexOf(LibraryItem item) => _list.IndexOf(item);
/// <inheritdoc/>
public void Insert(int index, LibraryItem item) => _list.Insert(index, item);
/// <summary> /// <summary>
/// Loads the data from the given <see cref="Stream"/>. /// Loads the data from the given <see cref="Stream"/>.
/// </summary> /// </summary>
@ -71,7 +134,7 @@ namespace Syroot.Worms.Armageddon.ProjectX
throw new InvalidDataException("Invalid PXL file version."); throw new InvalidDataException("Invalid PXL file version.");
// Read the items. // Read the items.
Clear(); _list.Clear();
int itemCount = reader.ReadInt32(); int itemCount = reader.ReadInt32();
for (int i = 0; i < itemCount; i++) for (int i = 0; i < itemCount; i++)
{ {
@ -80,13 +143,13 @@ namespace Syroot.Worms.Armageddon.ProjectX
switch (type) switch (type)
{ {
case LibraryItemType.File: case LibraryItemType.File:
Add(new LibraryItem(name, reader.ReadBytes(reader.ReadInt32()))); _list.Add(new LibraryItem(name, reader.ReadBytes(reader.ReadInt32())));
break; break;
case LibraryItemType.Script: case LibraryItemType.Script:
Add(new LibraryItem(name, reader.ReadString(StringCoding.Int32CharCount))); _list.Add(new LibraryItem(name, reader.ReadString(StringCoding.Int32CharCount)));
break; break;
case LibraryItemType.Weapon: case LibraryItemType.Weapon:
Add(new LibraryItem(name, reader.Load<Weapon>())); _list.Add(new LibraryItem(name, reader.Load<Weapon>()));
break; break;
} }
} }
@ -102,6 +165,12 @@ namespace Syroot.Worms.Armageddon.ProjectX
Load(stream); Load(stream);
} }
/// <inheritdoc/>
public bool Remove(LibraryItem item) => _list.Remove(item);
/// <inheritdoc/>
public void RemoveAt(int index) => _list.RemoveAt(index);
/// <summary> /// <summary>
/// Saves the data into the given <paramref name="stream"/>. /// Saves the data into the given <paramref name="stream"/>.
/// </summary> /// </summary>
@ -116,7 +185,7 @@ namespace Syroot.Worms.Armageddon.ProjectX
// Write the items. // Write the items.
writer.Write(Count); writer.Write(Count);
foreach (LibraryItem item in this) foreach (LibraryItem item in _list)
{ {
writer.WriteEnum(item.Type, true); writer.WriteEnum(item.Type, true);
writer.Write(item.Key, StringCoding.Int32CharCount); writer.Write(item.Key, StringCoding.Int32CharCount);
@ -147,26 +216,13 @@ namespace Syroot.Worms.Armageddon.ProjectX
Save(stream); Save(stream);
} }
/// <summary> // ---- METHODS ------------------------------------------------------------------------------------------------
/// Gets all attached files.
/// </summary>
/// <returns>The enumeration of attached files.</returns>
public IEnumerable<byte[]> GetFiles()
=> this.Where(x => x.Type == LibraryItemType.File).Select(x => (byte[])x.Value);
/// <summary> /// <inheritdoc/>
/// Gets all attached scripts. IEnumerator IEnumerable.GetEnumerator()
/// </summary> {
/// <returns>The enumeration of attached scripts.</returns> return ((IEnumerable)_list).GetEnumerator();
public IEnumerable<string> GetScripts() }
=> this.Where(x => x.Type == LibraryItemType.Script).Select(x => (string)x.Value);
/// <summary>
/// Gets all attached weapons.
/// </summary>
/// <returns>The enumeration of attached weapons.</returns>
public IEnumerable<Weapon> GetWeapons()
=> this.Where(x => x.Type == LibraryItemType.Weapon).Select(x => (Weapon)x.Value);
} }
/// <summary> /// <summary>
@ -232,19 +288,11 @@ namespace Syroot.Worms.Armageddon.ProjectX
/// </summary> /// </summary>
public enum LibraryItemType : byte public enum LibraryItemType : byte
{ {
/// <summary> /// <summary>The entry is a raw file in form of a byte array.</summary>
/// The entry is a raw file in form of a byte array.
/// </summary>
File = 2, File = 2,
/// <summary>The entry is a script in form of a string.</summary>
/// <summary>
/// The entry is a script in form of a string.
/// </summary>
Script = 4, Script = 4,
/// <summary>The entry is a weapon in form of a <see cref="Weapon"/> instance.</summary>
/// <summary>
/// The entry is a weapon in form of a <see cref="Weapon"/> instance.
/// </summary>
Weapon = 8 Weapon = 8
} }
} }

View File

@ -1,21 +1,17 @@
using System.Runtime.InteropServices; using Syroot.BinaryData;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
public struct Mine public struct Mine
{ {
public int Sensitivity; // ---- FIELDS -------------------------------------------------------------------------------------------------
public int TimeBeforeOn; [BinaryMember(Order = 1)] public int Sensitivity;
[BinaryMember(Order = 2)] public int TimeBeforeOn;
public CollisionFlags SensitiveTo; [BinaryMember(Order = 3)] public CollisionFlags SensitiveTo;
[BinaryMember(Order = 4)] public int FuseTime;
public int FuseTime; [BinaryMember(Order = 5)] public int ExplosionBias;
[BinaryMember(Order = 6)] public int ExplosionPower;
public int ExplosionBias; [BinaryMember(Order = 7)] public int MaxDamage;
}
public int ExplosionPower; }
public int MaxDamage;
}
}

View File

@ -1,189 +1,199 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
using Syroot.BinaryData; using Syroot.BinaryData;
using Syroot.Worms.IO; using Syroot.Worms.IO;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
/// <summary> /// <summary>
/// Represents a scheme stored in a PXS file which contains game settings, weapon tables, required libraries and /// Represents a scheme stored in a PXS file which contains game settings, weapon tables, required libraries and
/// attached files and scripts. /// attached files and scripts.
/// Used by WA PX. S. https://worms2d.info/Project_X/Scheme_file. /// Used by WA PX. S. https://worms2d.info/Project_X/Scheme_file.
/// </summary> /// </summary>
public class Scheme : ILoadableFile, ISaveableFile public class Scheme : ILoadableFile, ISaveableFile
{ {
// ---- CONSTANTS ---------------------------------------------------------------------------------------------- // ---- CONSTANTS ----------------------------------------------------------------------------------------------
private const string _signature = "SCHM OF WAPX"; private const string _signature = "SCHM OF WAPX";
private const int _weaponsPerTable = 71; private const int _weaponsPerTable = 71;
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------ // ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Scheme"/> class. /// Initializes a new instance of the <see cref="Scheme"/> class.
/// </summary> /// </summary>
public Scheme() { } public Scheme() { }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Scheme"/> class, loading the data from the given /// Initializes a new instance of the <see cref="Scheme"/> class, loading the data from the given
/// <see cref="Stream"/>. /// <see cref="Stream"/>.
/// </summary> /// </summary>
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param> /// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
public Scheme(Stream stream) => Load(stream); public Scheme(Stream stream) => Load(stream);
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Scheme"/> class, loading the data from the given file. /// Initializes a new instance of the <see cref="Scheme"/> class, loading the data from the given file.
/// </summary> /// </summary>
/// <param name="fileName">The name of the file to load the data from.</param> /// <param name="fileName">The name of the file to load the data from.</param>
public Scheme(string fileName) => Load(fileName); public Scheme(string fileName) => Load(fileName);
// ---- PROPERTIES --------------------------------------------------------------------------------------------- // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int Version { get; set; } public int Version { get; set; }
public SchemeFlags Flags { get; set; } public SchemeFlags Flags { get; set; }
public IList<Weapon[]> WeaponTables { get; set; } = new List<Weapon[]>(); public IList<Weapon[]> WeaponTables { get; set; } = new List<Weapon[]>();
public IDictionary<string, byte[]> Files { get; set; } = new Dictionary<string, byte[]>(); public IDictionary<string, byte[]> Files { get; set; } = new Dictionary<string, byte[]>();
public IDictionary<string, string> Scripts { get; set; } = new Dictionary<string, string>(); public IDictionary<string, string> Scripts { get; set; } = new Dictionary<string, string>();
public IList<string> Libraries { get; set; } = new List<string>(); public IList<string> Libraries { get; set; } = new List<string>();
public string GameSchemeName { get; set; } = String.Empty; public string GameSchemeName { get; set; } = String.Empty;
public Armageddon.Scheme? GameScheme { get; set; } public Armageddon.Scheme? GameScheme { get; set; }
// ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- // ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
/// <inheritdoc/> /// <inheritdoc/>
public void Load(Stream stream) public void Load(Stream stream)
{ {
using BinaryStream reader = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true); using BinaryStream reader = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true);
// Read the header. // Read the header.
if (reader.ReadString(_signature.Length) != _signature) if (reader.ReadString(_signature.Length) != _signature)
throw new InvalidDataException("Invalid PXS file signature."); throw new InvalidDataException("Invalid PXS file signature.");
Version = reader.ReadInt32(); Version = reader.ReadInt32();
// Read the scheme flags. // Read the scheme flags.
Flags = reader.ReadStruct<SchemeFlags>(); Flags = reader.ReadStruct<SchemeFlags>();
// Read the weapon tables. // Read the weapon tables.
int weaponTableCount = reader.ReadInt32(); int weaponTableCount = reader.ReadInt32();
WeaponTables = new List<Weapon[]>(weaponTableCount); WeaponTables = new List<Weapon[]>(weaponTableCount);
for (int i = 0; i < weaponTableCount; i++) for (int i = 0; i < weaponTableCount; i++)
{ {
Weapon[] weaponTable = new Weapon[_weaponsPerTable]; Weapon[] weaponTable = new Weapon[_weaponsPerTable];
for (int j = 0; j < _weaponsPerTable; j++) for (int j = 0; j < _weaponsPerTable; j++)
weaponTable[j] = reader.Load<Weapon>(); weaponTable[j] = reader.Load<Weapon>();
WeaponTables.Add(weaponTable); WeaponTables.Add(weaponTable);
} }
// Read a placeholder array. // Read a placeholder array.
reader.Seek(sizeof(int)); reader.Seek(sizeof(int));
// Read attached files. // Read attached files.
int filesCount = reader.ReadInt32(); int filesCount = reader.ReadInt32();
Files = new Dictionary<string, byte[]>(filesCount); Files = new Dictionary<string, byte[]>(filesCount);
for (int i = 0; i < filesCount; i++) for (int i = 0; i < filesCount; i++)
{ {
string name = reader.ReadString(StringCoding.Int32CharCount); string name = reader.ReadString(StringCoding.Int32CharCount);
int length = reader.ReadInt32(); int length = reader.ReadInt32();
Files.Add(name, reader.ReadBytes(length)); Files.Add(name, reader.ReadBytes(length));
} }
// Read attached scripts. // Read attached scripts.
int scriptsCount = reader.ReadInt32(); int scriptsCount = reader.ReadInt32();
Scripts = new Dictionary<string, string>(scriptsCount); Scripts = new Dictionary<string, string>(scriptsCount);
for (int i = 0; i < scriptsCount; i++) for (int i = 0; i < scriptsCount; i++)
Scripts.Add(reader.ReadString(StringCoding.Int32CharCount), Scripts.Add(reader.ReadString(StringCoding.Int32CharCount),
reader.ReadString(StringCoding.Int32CharCount)); reader.ReadString(StringCoding.Int32CharCount));
// Read required libraries. // Read required libraries.
int librariesCount = reader.ReadInt32(); int librariesCount = reader.ReadInt32();
Libraries = new List<string>(reader.ReadStrings(librariesCount, StringCoding.Int32CharCount)); Libraries = new List<string>(reader.ReadStrings(librariesCount, StringCoding.Int32CharCount));
// Read a possibly attached scheme file. // Read a possibly attached scheme file.
if (reader.ReadBoolean()) if (reader.ReadBoolean())
{ {
reader.Seek(sizeof(int)); // Scheme length not required due to intelligent loading. byte[] schemeData = reader.ReadBytes(reader.ReadInt32());
GameScheme = reader.Load<Armageddon.Scheme>(); using MemoryStream schemeStream = new MemoryStream(schemeData);
GameSchemeName = reader.ReadString(StringCoding.Int32CharCount); GameScheme = schemeStream.Load<Armageddon.Scheme>();
} GameSchemeName = reader.ReadString(StringCoding.Int32CharCount);
} }
else
/// <inheritdoc/> {
public void Load(string fileName) GameScheme = null;
{ GameSchemeName = String.Empty;
using FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); }
Load(stream); }
}
/// <inheritdoc/>
/// <inheritdoc/> public void Load(string fileName)
public void Save(Stream stream) {
{ using FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
using BinaryStream writer = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true); Load(stream);
}
// Write the header.
writer.Write(_signature, StringCoding.Raw); /// <inheritdoc/>
writer.Write(Version); public void Save(Stream stream)
{
// Write the scheme flags. using BinaryStream writer = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true);
writer.WriteStruct(Flags);
// Write the header.
// Write the weapon tables. writer.Write(_signature, StringCoding.Raw);
writer.Write(WeaponTables.Count); writer.Write(Version);
// Write the scheme flags.
writer.WriteStruct(Flags);
// Write the weapon tables.
writer.Write(WeaponTables.Count);
foreach (Weapon[] weaponTable in WeaponTables) foreach (Weapon[] weaponTable in WeaponTables)
for (int i = 0; i < _weaponsPerTable; i++) for (int i = 0; i < _weaponsPerTable; i++)
writer.Save(weaponTable[i]); writer.Save(weaponTable[i]);
// Write a placeholder array. // Write a placeholder array.
writer.Write(0); writer.Write(0);
// Write attached files. // Write attached files.
writer.Write(Files.Count); writer.Write(Files.Count);
foreach (KeyValuePair<string, byte[]> file in Files) foreach (KeyValuePair<string, byte[]> file in Files)
{ {
writer.Write(file.Key, StringCoding.Int32CharCount); writer.Write(file.Key, StringCoding.Int32CharCount);
writer.Write(file.Value.Length); writer.Write(file.Value.Length);
writer.Write(file.Value); writer.Write(file.Value);
} }
// Write attached scripts. // Write attached scripts.
writer.Write(Scripts.Count); writer.Write(Scripts.Count);
foreach (KeyValuePair<string, string> script in Scripts) foreach (KeyValuePair<string, string> script in Scripts)
{ {
writer.Write(script.Key, StringCoding.Int32CharCount); writer.Write(script.Key, StringCoding.Int32CharCount);
writer.Write(script.Value, StringCoding.Int32CharCount); writer.Write(script.Value, StringCoding.Int32CharCount);
} }
// Write required libraries. // Write required libraries.
writer.Write(Libraries.Count); writer.Write(Libraries.Count);
writer.Write(Libraries); writer.Write(Libraries, StringCoding.Int32CharCount);
// Write a possibly attached scheme file. // Write a possibly attached scheme file.
if (GameScheme != null) if (GameScheme != null)
{ {
byte[] schemeBytes; writer.Write(true);
using (MemoryStream schemeStream = new MemoryStream()) using MemoryStream schemeStream = new MemoryStream();
{ GameScheme.Save(schemeStream);
GameScheme.Save(schemeStream);
schemeBytes = schemeStream.ToArray(); writer.Write((int)schemeStream.Position);
} schemeStream.Position = 0;
writer.Write(schemeBytes.Length); schemeStream.CopyTo(writer);
writer.Write(GameSchemeName, StringCoding.Int32CharCount); writer.Write(GameSchemeName, StringCoding.Int32CharCount);
} }
} else
{
/// <inheritdoc/> writer.Write(false);
public void Save(string fileName) }
{ }
using FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None);
Save(stream); /// <inheritdoc/>
} public void Save(string fileName)
} {
} using FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None);
Save(stream);
}
}
}

View File

@ -1,56 +1,29 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
/// <summary> /// <summary>
/// Represents global Project X scheme flags affecting general game behavior. /// Represents global Project X scheme flags affecting general game behavior.
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct SchemeFlags public struct SchemeFlags
{ {
[MarshalAs(UnmanagedType.I1)] // ---- FIELDS -------------------------------------------------------------------------------------------------
public bool CyclicMaps;
public bool CyclicMaps;
[MarshalAs(UnmanagedType.I1)] public bool UnderwaterJetpack;
public bool UnderwaterJetpack; public bool UnderwaterRope;
public bool Unused1;
[MarshalAs(UnmanagedType.I1)] public bool Unused2;
public bool UnderwaterRope; public bool Unused3;
public bool Unused4;
[MarshalAs(UnmanagedType.I1)] public bool Unused5;
public bool Unused1; public bool Unused6;
public bool Unused7;
[MarshalAs(UnmanagedType.I1)] public bool Unused8;
public bool Unused2; public bool ShotDoesntEndTurn;
public bool LoseControlDoesntEndTurn;
[MarshalAs(UnmanagedType.I1)] public bool FiringPausesTimer;
public bool Unused3; public bool EnableSchemePowers;
}
[MarshalAs(UnmanagedType.I1)] }
public bool Unused4;
[MarshalAs(UnmanagedType.I1)]
public bool Unused5;
[MarshalAs(UnmanagedType.I1)]
public bool Unused6;
[MarshalAs(UnmanagedType.I1)]
public bool Unused7;
[MarshalAs(UnmanagedType.I1)]
public bool Unused8;
[MarshalAs(UnmanagedType.I1)]
public bool ShotDoesntEndTurn;
[MarshalAs(UnmanagedType.I1)]
public bool LoseControlDoesntEndTurn;
[MarshalAs(UnmanagedType.I1)]
public bool FiringPausesTimer;
[MarshalAs(UnmanagedType.I1)]
public bool EnableSchemePowers;
}
}

View File

@ -1,19 +1,15 @@
using Syroot.BinaryData; using Syroot.BinaryData;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
public struct Sound public struct Sound
{ {
public short SoundIndex; // ---- FIELDS -------------------------------------------------------------------------------------------------
[BinaryMember(BooleanCoding = BooleanCoding.Word)] [BinaryMember(Order = 1)] public ushort SoundIndex;
public bool RepeatSound; [BinaryMember(Order = 2, BooleanCoding = BooleanCoding.Word)] public bool RepeatSound;
[BinaryMember(Order = 3, BooleanCoding = BooleanCoding.Dword)] public bool UseExplosionSound;
[BinaryMember(BooleanCoding = BooleanCoding.Dword)] [BinaryMember(Order = 4)] public int SoundBeforeExplosion;
public bool UseExplosionSound; [BinaryMember(Order = 5)] public int DelayBeforeExplosion;
}
public int SoundBeforeExplosion; }
public int DelayBeforeExplosion;
}
}

View File

@ -1,30 +1,27 @@
using System.Runtime.InteropServices; using Syroot.BinaryData;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
public struct Sprite public struct Sprite
{ {
public int SpriteNumber; // ---- FIELDS -------------------------------------------------------------------------------------------------
public SpriteAnimationType AnimationType; [BinaryMember(Order = 1)] public int SpriteNumber;
[BinaryMember(Order = 2)] public SpriteAnimationType AnimationType;
public int TrailSprite; [BinaryMember(Order = 3)] public int TrailSprite;
[BinaryMember(Order = 4)] public int TrailAmount;
public int TrailAmount; [BinaryMember(Order = 5)] public int TrailVanishSpeed;
[BinaryMember(Order = 6)] public int Unknown;
public int TrailVanishSpeed; }
public int Unknown; public enum SpriteAnimationType : int
} {
HorizontalVelocity,
public enum SpriteAnimationType : int Cycle,
{ TrackMovement,
HorizontalVelocity, TrackSpeed,
Cycle, SlowCycle,
TrackMovement, FasterCycle,
TrackSpeed, FastCycle
SlowCycle, }
FasterCycle, }
FastCycle
}
}

View File

@ -6,20 +6,19 @@ namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int PlaneSprite; [BinaryMember(Order = 1)] public int PlaneSprite;
public int BombsCount; [BinaryMember(Order = 2)] public int BombsCount;
public int DropDistance; [BinaryMember(Order = 3)] public int DropDistance;
public int HorizontalSpeed; [BinaryMember(Order = 4)] public int HorizontalSpeed;
public int Sound; [BinaryMember(Order = 5)] public int Sound;
public WeaponAirstrikeSubstyle AirstrikeSubstyle; [BinaryMember(Order = 6)] public WeaponAirstrikeSubstyle AirstrikeSubstyle;
[BinaryMember(Converter = typeof(AirstrikeSubstyleConverter))] [BinaryMember(Order = 7, Converter = typeof(AirstrikeSubstyleConverter))] public IStyle? Style;
public IStyle? Style;
} }
public enum WeaponAirstrikeSubstyle : int public enum WeaponAirstrikeSubstyle : int

View File

@ -1,33 +1,35 @@
using System; using System;
using System.IO; using System.IO;
using Syroot.BinaryData; using Syroot.BinaryData;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
public class AirstrikeSubstyleConverter : IBinaryConverter public class AirstrikeSubstyleConverter : IBinaryConverter
{ {
// ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- // ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
public object Read(Stream stream, object instance, BinaryMemberAttribute memberAttribute, /// <inheritdoc/>
ByteConverter byteConverter) public object? Read(Stream stream, object instance, BinaryMemberAttribute memberAttribute,
{ ByteConverter byteConverter)
WeaponAirstrikeSubstyle airstrikeSubstyle = instance switch {
{ WeaponAirstrikeSubstyle airstrikeSubstyle = instance switch
AirstrikeStyle airstrikeStyle => airstrikeStyle.AirstrikeSubstyle, {
_ => throw new NotImplementedException(), AirstrikeStyle airstrikeStyle => airstrikeStyle.AirstrikeSubstyle,
}; _ => throw new NotImplementedException(),
return airstrikeSubstyle switch };
{ return airstrikeSubstyle switch
WeaponAirstrikeSubstyle.Launcher => stream.ReadObject<LauncherStyle>(), {
WeaponAirstrikeSubstyle.Mines => stream.ReadObject<MineStyle>(), WeaponAirstrikeSubstyle.Mines => stream.ReadObject<MineStyle>(),
_ => throw new NotImplementedException(), WeaponAirstrikeSubstyle.Launcher => stream.ReadObject<LauncherStyle>(),
}; _ => null
} };
}
public void Write(Stream stream, object instance, BinaryMemberAttribute memberAttribute, object value,
ByteConverter byteConverter) /// <inheritdoc/>
{ public void Write(Stream stream, object instance, BinaryMemberAttribute memberAttribute, object value,
stream.WriteObject(value); ByteConverter byteConverter)
} {
} stream.WriteObject(value);
}
}
} }

View File

@ -1,11 +1,13 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class BaseballBatStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class BaseballBatStyle : IStyle
{
public int Damage { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int PushPower { get; set; } [BinaryMember(Order = 1)] public int Damage { get; set; }
}
[BinaryMember(Order = 2)] public int PushPower { get; set; }
}
} }

View File

@ -1,9 +1,11 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class BattleAxeStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class BattleAxeStyle : IStyle
{
public int PercentualDamage { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
}
[BinaryMember(Order = 1)] public int PercentualDamage { get; set; }
}
} }

View File

@ -1,15 +1,17 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class BlowtorchStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class BlowtorchStyle : IStyle
{
public int Damage { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int PushPower { get; set; } [BinaryMember(Order = 1)] public int Damage { get; set; }
public int ImpactAngle { get; set; } [BinaryMember(Order = 2)] public int PushPower { get; set; }
public int TunellingTime { get; set; } [BinaryMember(Order = 3)] public int ImpactAngle { get; set; }
}
[BinaryMember(Order = 4)] public int TunellingTime { get; set; }
}
} }

View File

@ -1,9 +1,11 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class BowStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class BowStyle : IStyle
{
public int Damage { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
}
[BinaryMember(Order = 1)] public int Damage { get; set; }
}
} }

View File

@ -1,15 +1,17 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class CanisterStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class CanisterStyle : IStyle
{
public int SpriteInactive { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int SpriteActive { get; set; } [BinaryMember(Order = 1)] public int SpriteInactive { get; set; }
public int DiseasePoints { get; set; } [BinaryMember(Order = 2)] public int SpriteActive { get; set; }
public int MaxDamage { get; set; } [BinaryMember(Order = 3)] public int DiseasePoints { get; set; }
}
[BinaryMember(Order = 4)] public int MaxDamage { get; set; }
}
} }

View File

@ -1,21 +1,23 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class DragonballStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class DragonballStyle : IStyle
{
public int FiringSound { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int ImpactSound { get; set; } [BinaryMember(Order = 1)] public int FiringSound { get; set; }
public int BallSprite { get; set; } [BinaryMember(Order = 2)] public int ImpactSound { get; set; }
public int Damage { get; set; } [BinaryMember(Order = 3)] public int BallSprite { get; set; }
public int Angle { get; set; } [BinaryMember(Order = 4)] public int Damage { get; set; }
public int Force { get; set; } [BinaryMember(Order = 5)] public int Angle { get; set; }
public int BallTime { get; set; } [BinaryMember(Order = 6)] public int Force { get; set; }
}
[BinaryMember(Order = 7)] public int BallTime { get; set; }
}
} }

View File

@ -1,15 +1,17 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class FirepunchStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class FirepunchStyle : IStyle
{
public int Damage { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int Angle { get; set; } [BinaryMember(Order = 1)] public int Damage { get; set; }
public int PushPower { get; set; } [BinaryMember(Order = 2)] public int Angle { get; set; }
public int JumpHeight { get; set; } [BinaryMember(Order = 3)] public int PushPower { get; set; }
}
[BinaryMember(Order = 4)] public int JumpHeight { get; set; }
}
} }

View File

@ -6,15 +6,14 @@ namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int FuelAmount { get; set; } [BinaryMember(Order = 1)] public int FuelAmount { get; set; }
public int FireIntensity { get; set; } [BinaryMember(Order = 2)] public int FireIntensity { get; set; }
public int FireAmount { get; set; } [BinaryMember(Order = 3)] public int FireAmount { get; set; }
public int FireBurnTime { get; set; } [BinaryMember(Order = 4)] public int FireBurnTime { get; set; }
[BinaryMember(BooleanCoding = BooleanCoding.Dword)] [BinaryMember(Order = 5, BooleanCoding = BooleanCoding.Dword)] public bool RemainOnTerrain { get; set; }
public bool RemainOnTerrain { get; set; }
} }
} }

View File

@ -1,35 +1,37 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class GunStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class GunStyle : IStyle
{
public int BulletCount { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int ReloadTime { get; set; } [BinaryMember(Order = 1)] public int BulletCount { get; set; }
public int BulletSpread { get; set; } [BinaryMember(Order = 2)] public int ReloadTime { get; set; }
public int Burst { get; set; } [BinaryMember(Order = 3)] public int BulletSpread { get; set; }
public int BurstSpread { get; set; } [BinaryMember(Order = 4)] public int Burst { get; set; }
public CollisionFlags Collisions { get; set; } [BinaryMember(Order = 5)] public int BurstSpread { get; set; }
public int ExplosionBias { get; set; } [BinaryMember(Order = 6)] public CollisionFlags Collisions { get; set; }
public int ExplosionPower { get; set; } [BinaryMember(Order = 7)] public int ExplosionBias { get; set; }
public int MaxDamage { get; set; } [BinaryMember(Order = 8)] public int ExplosionPower { get; set; }
public int DamageSpread { get; set; } [BinaryMember(Order = 9)] public int MaxDamage { get; set; }
public int ExpEffect { get; set; } [BinaryMember(Order = 10)] public int DamageSpread { get; set; }
public int Range1 { get; set; } [BinaryMember(Order = 11)] public int ExpEffect { get; set; }
public int Range2 { get; set; } [BinaryMember(Order = 12)] public int Range1 { get; set; }
public int Range3 { get; set; } [BinaryMember(Order = 13)] public int Range2 { get; set; }
}
[BinaryMember(Order = 14)] public int Range3 { get; set; }
}
} }

View File

@ -1,9 +1,11 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class JetpackStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class JetpackStyle : IStyle
{
public int Fuel { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
}
[BinaryMember(Order = 1)] public int Fuel { get; set; }
}
} }

View File

@ -1,19 +1,21 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class KamikazeStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class KamikazeStyle : IStyle
{
public int FlyingTime { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int ExplosionDamage { get; set; } [BinaryMember(Order = 1)] public int FlyingTime { get; set; }
public int FireSound { get; set; } [BinaryMember(Order = 2)] public int ExplosionDamage { get; set; }
public int Damage { get; set; } [BinaryMember(Order = 3)] public int FireSound { get; set; }
public int ImpactForce { get; set; } [BinaryMember(Order = 4)] public int Damage { get; set; }
public int ImpactAngle { get; set; } [BinaryMember(Order = 5)] public int ImpactForce { get; set; }
}
[BinaryMember(Order = 6)] public int ImpactAngle { get; set; }
}
} }

View File

@ -1,74 +1,71 @@
using Syroot.BinaryData; using Syroot.BinaryData;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
public class LauncherStyle : IStyle public class LauncherStyle : IStyle
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int SpriteSize { get; set; } [BinaryMember(Order = 1)] public int SpriteSize { get; set; }
public int FixedSpeed { get; set; } [BinaryMember(Order = 2)] public int FixedSpeed { get; set; }
[BinaryMember(BooleanCoding = BooleanCoding.Dword)] [BinaryMember(Order = 3, BooleanCoding = BooleanCoding.Dword)] public bool RunAway { get; set; }
public bool RunAway { get; set; }
[BinaryMember(Order = 4)] public CollisionFlags Collisions { get; set; }
public CollisionFlags Collisions { get; set; }
[BinaryMember(Order = 5)] public int ExplosionBias { get; set; }
public int ExplosionBias { get; set; }
[BinaryMember(Order = 6)] public int ExplosionPushPower { get; set; }
public int ExplosionPushPower { get; set; }
[BinaryMember(Order = 7)] public int ExplosionDamage { get; set; }
public int ExplosionDamage { get; set; }
[BinaryMember(Order = 8)] public int ExplosionDamageVariation { get; set; }
public int ExplosionDamageVariation { get; set; }
[BinaryMember(Order = 9)] public int ExplosionUnknown { get; set; }
public int ExplosionUnknown { get; set; }
[BinaryMember(Order = 10)] public Sprite Sprite { get; set; }
public Sprite Sprite { get; set; }
[BinaryMember(Order = 11)] public int VariableSpeed { get; set; }
public int VariableSpeed { get; set; }
[BinaryMember(Order = 12)] public int WindFactor { get; set; }
public int WindFactor { get; set; }
[BinaryMember(Order = 13)] public int MotionRandomness { get; set; }
public int MotionRandomness { get; set; }
[BinaryMember(Order = 14)] public int GravityFactor { get; set; }
public int GravityFactor { get; set; }
[BinaryMember(Order = 15)] public int ExplosionCountdown { get; set; }
public int ExplosionCountdown { get; set; }
[BinaryMember(Order = 16)] public int ExplosionTimer { get; set; }
public int ExplosionTimer { get; set; }
[BinaryMember(Order = 17)] public Sound Sound { get; set; }
public Sound Sound { get; set; }
[BinaryMember(Order = 18, BooleanCoding = BooleanCoding.Dword)] public bool ExplodeOnSpace { get; set; }
[BinaryMember(BooleanCoding = BooleanCoding.Dword)]
public bool ExplodeOnSpace { get; set; } [BinaryMember(Order = 19)] public ExplosionAction ExplosionAction { get; set; }
public ExplosionAction ExplosionAction { get; set; } [BinaryMember(Order = 20, Converter = typeof(ActionConverter))] public IAction? Action { get; set; }
[BinaryMember(Converter = typeof(ActionConverter))] [BinaryMember(Order = 21, OffsetOrigin = OffsetOrigin.Begin, Offset = 180)]
public IAction? Action { get; set; }
[BinaryMember(OffsetOrigin = OffsetOrigin.Begin, Offset = 180)]
public ExplosionTarget ExplosionTarget { get; set; } public ExplosionTarget ExplosionTarget { get; set; }
[BinaryMember(Offset = sizeof(int), Converter = typeof(TargetConverter))] [BinaryMember(Order = 22, Offset = sizeof(int), Converter = typeof(TargetConverter))]
public ITarget? Target { get; set; } public ITarget? Target { get; set; }
} }
public enum ExplosionAction : int public enum ExplosionAction : int
{ {
None, None,
Home, Home,
Bounce, Bounce,
Roam, Roam,
Dig Dig
} }
public enum ExplosionTarget : int public enum ExplosionTarget : int
{ {
None, None,
Clusters, Clusters,
Fire Fire
} }
} }

View File

@ -1,9 +1,11 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class MineStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class MineStyle : IStyle
{
public Mine Mine; // ---- PROPERTIES ---------------------------------------------------------------------------------------------
}
[BinaryMember(Order = 1)] public Mine Mine;
}
} }

View File

@ -1,13 +1,15 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class NinjaRopeStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class NinjaRopeStyle : IStyle
{
public int ShotCount { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int Length { get; set; } [BinaryMember(Order = 1)] public int ShotCount { get; set; }
public int AngleRestriction { get; set; } [BinaryMember(Order = 2)] public int Length { get; set; }
}
[BinaryMember(Order = 3)] public int AngleRestriction { get; set; }
}
} }

View File

@ -1,11 +1,13 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class NuclearTestStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class NuclearTestStyle : IStyle
{
public int WaterRise { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int DiseasePoints { get; set; } [BinaryMember(Order = 1)] public int WaterRise { get; set; }
}
[BinaryMember(Order = 2)] public int DiseasePoints { get; set; }
}
} }

View File

@ -1,9 +1,11 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class ParachuteStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class ParachuteStyle : IStyle
{
public int WindResponse { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
}
[BinaryMember(Order = 1)] public int WindResponse { get; set; }
}
} }

View File

@ -1,15 +1,17 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class PneumaticDrillStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class PneumaticDrillStyle : IStyle
{
public int Damage { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int PushPower { get; set; } [BinaryMember(Order = 1)] public int Damage { get; set; }
public int ImpactAngle { get; set; } [BinaryMember(Order = 2)] public int PushPower { get; set; }
public int TunellingTime { get; set; } [BinaryMember(Order = 3)] public int ImpactAngle { get; set; }
}
[BinaryMember(Order = 4)] public int TunellingTime { get; set; }
}
} }

View File

@ -1,13 +1,15 @@
using Syroot.BinaryData;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
public class ProdStyle : IStyle public class ProdStyle : IStyle
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int Damage { get; set; } [BinaryMember(Order = 1)] public int Damage { get; set; }
public int Force { get; set; } [BinaryMember(Order = 2)] public int Force { get; set; }
public int Angle { get; set; } [BinaryMember(Order = 3)] public int Angle { get; set; }
} }
} }

View File

@ -1,11 +1,13 @@
namespace Syroot.Worms.Armageddon.ProjectX using Syroot.BinaryData;
{
public class SuicideBomberStyle : IStyle namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- public class SuicideBomberStyle : IStyle
{
public int DiseasePoints { get; set; } // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int Damage { get; set; } [BinaryMember(Order = 1)] public int DiseasePoints { get; set; }
}
[BinaryMember(Order = 2)] public int Damage { get; set; }
}
} }

View File

@ -1,14 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)build.xml" /> <Import Project="$(SolutionDir)build.xml" />
<PropertyGroup>
<AssemblyName>Syroot.Worms.Armageddon.ProjectX</AssemblyName> <!-- Metadata -->
<Description>.NET library for loading and modifying files of Worms Armageddon ProjectX.</Description> <PropertyGroup>
<PackageReleaseNotes>Overhaul implementation and documentation.</PackageReleaseNotes> <AssemblyName>Syroot.Worms.Armageddon.ProjectX</AssemblyName>
<PackageTags>$(PackageTags);project x;worms armageddon</PackageTags> <Description>.NET library for loading and modifying files of Worms Armageddon ProjectX.</Description>
<Version>4.0.0</Version> <PackageReleaseNotes>Overhaul implementation and documentation.</PackageReleaseNotes>
</PropertyGroup> <PackageTags>$(PackageTags);project x;worms armageddon</PackageTags>
<ItemGroup> <Version>4.0.0</Version>
<ProjectReference Include="..\Syroot.Worms.Armageddon\Syroot.Worms.Armageddon.csproj" /> </PropertyGroup>
<ProjectReference Include="..\Syroot.Worms\Syroot.Worms.csproj" />
</ItemGroup> <!-- References -->
<ItemGroup>
<PackageReference Include="Syroot.BinaryData.Serialization" Version="5.2.1" />
<ProjectReference Include="..\Syroot.Worms\Syroot.Worms.csproj" />
<ProjectReference Include="..\Syroot.Worms.Armageddon\Syroot.Worms.Armageddon.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -1,55 +1,53 @@
using Syroot.BinaryData; using Syroot.BinaryData;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
public class ClusterTarget : ITarget public class ClusterTarget : ITarget
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int ClusterCount { get; set; } [BinaryMember(Order = 1)] public int ClusterCount { get; set; }
public int DispersionPower { get; set; } [BinaryMember(Order = 2)] public int DispersionPower { get; set; }
public int Speed { get; set; } [BinaryMember(Order = 3)] public int Speed { get; set; }
public int EjectionAngle { get; set; } [BinaryMember(Order = 4)] public int EjectionAngle { get; set; }
public int DispersionAngle { get; set; } [BinaryMember(Order = 5)] public int DispersionAngle { get; set; }
public CollisionFlags Collisions { get; set; } [BinaryMember(Order = 6)] public CollisionFlags Collisions { get; set; }
public int ExplosionBias { get; set; } [BinaryMember(Order = 7)] public int ExplosionBias { get; set; }
public int ExplosionPushPower { get; set; } [BinaryMember(Order = 8)] public int ExplosionPushPower { get; set; }
public int ExplosionDamage { get; set; } [BinaryMember(Order = 9)] public int ExplosionDamage { get; set; }
public int ExplosionDamageVariation { get; set; } [BinaryMember(Order = 10)] public int ExplosionDamageVariation { get; set; }
public int SpriteCount { get; set; } [BinaryMember(Order = 11)] public int SpriteCount { get; set; }
public Sprite Sprite { get; set; } [BinaryMember(Order = 12)] public Sprite Sprite { get; set; }
public int Acceleration { get; set; } [BinaryMember(Order = 13)] public int Acceleration { get; set; }
public int WindResponse { get; set; } [BinaryMember(Order = 14)] public int WindResponse { get; set; }
public int MotionRandomness { get; set; } [BinaryMember(Order = 15)] public int MotionRandomness { get; set; }
public int GravityFactor { get; set; } [BinaryMember(Order = 16)] public int GravityFactor { get; set; }
public int Unused1 { get; set; } [BinaryMember(Order = 17)] public int Unused1 { get; set; }
public int Unused2 { get; set; } [BinaryMember(Order = 18)] public int Unused2 { get; set; }
public Sound Sound { get; set; } [BinaryMember(Order = 19)] public Sound Sound { get; set; }
[BinaryMember(BooleanCoding = BooleanCoding.Dword)] [BinaryMember(Order = 20, BooleanCoding = BooleanCoding.Dword)] public bool ExplodeOnSpace { get; set; }
public bool ExplodeOnSpace { get; set; }
[BinaryMember(Order = 21)] public ExplosionAction ExplosionAction { get; set; }
public ExplosionAction ExplosionAction { get; set; }
[BinaryMember(Order = 22, Converter = typeof(ActionConverter))] public IAction? Action { get; set; }
[BinaryMember(Converter = typeof(ActionConverter))] }
public IAction? Action { get; set; } }
}
}

View File

@ -6,13 +6,12 @@ namespace Syroot.Worms.Armageddon.ProjectX
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int Power { get; set; } [BinaryMember(Order = 1)] public int Power { get; set; }
public int Spread { get; set; } [BinaryMember(Order = 2)] public int Spread { get; set; }
public int Time { get; set; } [BinaryMember(Order = 3)] public int Time { get; set; }
[BinaryMember(BooleanCoding = BooleanCoding.Dword)] [BinaryMember(Order = 4, BooleanCoding = BooleanCoding.Dword)] public bool StayBetweenTurns { get; set; }
public bool StayBetweenTurns { get; set; }
} }
} }

View File

@ -1,34 +1,35 @@
using System; using System;
using System.IO; using System.IO;
using Syroot.BinaryData; using Syroot.BinaryData;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
internal class TargetConverter : IBinaryConverter internal class TargetConverter : IBinaryConverter
{ {
// ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- // ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
public object? Read(Stream stream, object instance, BinaryMemberAttribute memberAttribute, /// <inheritdoc/>
ByteConverter byteConverter) public object? Read(Stream stream, object instance, BinaryMemberAttribute memberAttribute,
{ ByteConverter byteConverter)
ExplosionTarget explosionTarget = instance switch {
{ ExplosionTarget explosionTarget = instance switch
LauncherStyle launcherStyle => launcherStyle.ExplosionTarget,
_ => throw new NotImplementedException(),
};
return explosionTarget switch
{ {
ExplosionTarget.None => null, LauncherStyle launcherStyle => launcherStyle.ExplosionTarget,
ExplosionTarget.Clusters => stream.ReadObject<ClusterTarget>(), _ => throw new NotImplementedException(),
ExplosionTarget.Fire => stream.ReadObject<FireTarget>(), };
_ => throw new NotImplementedException(), return explosionTarget switch
}; {
} ExplosionTarget.Clusters => stream.ReadObject<ClusterTarget>(),
ExplosionTarget.Fire => stream.ReadObject<FireTarget>(),
public void Write(Stream stream, object instance, BinaryMemberAttribute memberAttribute, object value, _ => null,
ByteConverter byteConverter) };
{ }
stream.WriteObject(value);
} /// <inheritdoc/>
} public void Write(Stream stream, object instance, BinaryMemberAttribute memberAttribute, object value,
} ByteConverter byteConverter)
{
stream.WriteObject(value);
}
}
}

View File

@ -1,449 +1,398 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Text; using System.Text;
using Syroot.BinaryData; using Syroot.BinaryData;
using Syroot.Worms.IO; using Syroot.Worms.IO;
namespace Syroot.Worms.Armageddon.ProjectX namespace Syroot.Worms.Armageddon.ProjectX
{ {
[DebuggerDisplay("Weapon Name={Name}")] [DebuggerDisplay("Weapon Name={Name}")]
public class Weapon : ILoadable, ISaveable public class Weapon : ILoadable, ISaveable
{ {
// ---- PROPERTIES --------------------------------------------------------------------------------------------- // ---- PROPERTIES ---------------------------------------------------------------------------------------------
public WeaponVersion Version { get; set; } [BinaryMember(Order = 1)] public WeaponVersion Version { get; set; }
public long Checksum { get; set; } [BinaryMember(Order = 2)] public long Checksum { get; set; }
public int TableRow { get; set; } [BinaryMember(Order = 3)] public int TableRow { get; set; }
public bool Remembered { get; set; } [BinaryMember(Order = 4)] public bool Remembered { get; set; }
public bool UsableInCavern { get; set; } [BinaryMember(Order = 5)] public bool UsableInCavern { get; set; }
public int Shots { get; set; } [BinaryMember(Order = 6)] public int Shots { get; set; }
public bool ShotEndsTurn { get; set; } [BinaryMember(Order = 7)] public bool ShotEndsTurn { get; set; }
public int RetreatTime { get; set; } [BinaryMember(Order = 8)] public int RetreatTime { get; set; }
public int Unknown1 { get; set; } [BinaryMember(Order = 9)] public int Unknown1 { get; set; }
public int CrateChance { get; set; } [BinaryMember(Order = 10)] public int CrateChance { get; set; }
public int CrateCount { get; set; } [BinaryMember(Order = 11)] public int CrateCount { get; set; }
public int Unknown2 { get; set; } [BinaryMember(Order = 12)] public int Unknown2 { get; set; }
public WeaponActivation Activation { get; set; } [BinaryMember(Order = 13)] public WeaponActivation Activation { get; set; }
public int NotUsed { get; set; } [BinaryMember(Order = 14)] public int NotUsed { get; set; }
public int ThrowHerdCount { get; set; } [BinaryMember(Order = 15)] public int ThrowHerdCount { get; set; }
public int AirstrikeSubtype { get; set; } [BinaryMember(Order = 16)] public int AirstrikeSubtype { get; set; }
public WeaponSpacebarAction SpacebarAction { get; set; } [BinaryMember(Order = 17)] public WeaponSpacebarAction SpacebarAction { get; set; }
public WeaponCrosshairAction CrosshairAction { get; set; } [BinaryMember(Order = 18)] public WeaponCrosshairAction CrosshairAction { get; set; }
public WeaponThrowAction ThrowAction { get; set; } [BinaryMember(Order = 19)] public WeaponThrowAction ThrowAction { get; set; }
public IStyle? Style { get; set; } [BinaryMember(Order = 20)] public IStyle? Style { get; set; }
public bool AmmunitionOverride { get; set; } [BinaryMember(Order = 21)] public bool AmmunitionOverride { get; set; }
public int Ammunition { get; set; } [BinaryMember(Order = 22)] public int Ammunition { get; set; }
public int Unknown3 { get; set; } [BinaryMember(Order = 23)] public int Unknown3 { get; set; }
public int WeaponSprite { get; set; } [BinaryMember(Order = 24)] public int WeaponSprite { get; set; }
public string NameLong { get; set; } = String.Empty; [BinaryMember(Order = 25)] public string NameLong { get; set; } = String.Empty;
public string Name { get; set; } = String.Empty; [BinaryMember(Order = 26)] public string Name { get; set; } = String.Empty;
public string GridImageFile { get; set; } = String.Empty; [BinaryMember(Order = 27)] public string GridImageFile { get; set; } = String.Empty;
public string GfxDirectoryFile { get; set; } = String.Empty; [BinaryMember(Order = 28)] public string GfxDirectoryFile { get; set; } = String.Empty;
public string[] SpriteNames { get; } = new string[5]; [BinaryMember(Order = 29)] public string[] SpriteNames { get; } = new string[5];
public bool DelayOverride { get; set; } [BinaryMember(Order = 30)] public bool DelayOverride { get; set; }
public int Delay { get; set; } [BinaryMember(Order = 31)] public int Delay { get; set; }
public bool UseLibrary { get; set; } [BinaryMember(Order = 32)] public bool UseLibrary { get; set; }
public string LibraryName { get; set; } = String.Empty; [BinaryMember(Order = 33)] public string LibraryName { get; set; } = String.Empty;
public string LibraryWeaponName { get; set; } = String.Empty; [BinaryMember(Order = 34)] public string LibraryWeaponName { get; set; } = String.Empty;
public string AimSpriteEven { get; set; } = String.Empty; [BinaryMember(Order = 35)] public string AimSpriteEven { get; set; } = String.Empty;
public string AimSpriteUphill { get; set; } = String.Empty; [BinaryMember(Order = 36)] public string AimSpriteUphill { get; set; } = String.Empty;
public string AimSpriteDownhill { get; set; } = String.Empty; [BinaryMember(Order = 37)] public string AimSpriteDownhill { get; set; } = String.Empty;
public string PickSpriteEven { get; set; } = String.Empty; [BinaryMember(Order = 38)] public string PickSpriteEven { get; set; } = String.Empty;
public string PickSpriteUphill { get; set; } = String.Empty; [BinaryMember(Order = 39)] public string PickSpriteUphill { get; set; } = String.Empty;
public string PickSpriteDownhill { get; set; } = String.Empty; [BinaryMember(Order = 40)] public string PickSpriteDownhill { get; set; } = String.Empty;
public string FireSpriteEven { get; set; } = String.Empty; [BinaryMember(Order = 41)] public string FireSpriteEven { get; set; } = String.Empty;
public string FireSpriteUphill { get; set; } = String.Empty; [BinaryMember(Order = 42)] public string FireSpriteUphill { get; set; } = String.Empty;
public string FireSpriteDownhill { get; set; } = String.Empty; [BinaryMember(Order = 43)] public string FireSpriteDownhill { get; set; } = String.Empty;
public bool AimSpriteOverride { get; set; } [BinaryMember(Order = 44)] public bool AimSpriteOverride { get; set; }
public bool PickSpriteOverride { get; set; } [BinaryMember(Order = 45)] public bool PickSpriteOverride { get; set; }
public bool FireSpriteOverride { get; set; } [BinaryMember(Order = 46)] public bool FireSpriteOverride { get; set; }
public bool Utility { get; set; } [BinaryMember(Order = 47)] public bool Utility { get; set; }
// ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- // ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
/// <inheritdoc/> /// <inheritdoc/>
public void Load(Stream stream) public void Load(Stream stream)
{ {
using BinaryStream reader = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true); using BinaryStream reader = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true);
// Read the header. // Read the header.
long offset = reader.Position; long offset = reader.Position;
Version = reader.ReadEnum<WeaponVersion>(true); Version = reader.ReadEnum<WeaponVersion>(true);
Checksum = reader.ReadInt64(); Checksum = reader.ReadInt64();
// Read general settings. // Read general settings.
TableRow = reader.ReadInt32(); TableRow = reader.ReadInt32();
Remembered = reader.ReadBoolean(BooleanCoding.Dword); Remembered = reader.ReadBoolean(BooleanCoding.Dword);
UsableInCavern = reader.ReadBoolean(BooleanCoding.Dword); UsableInCavern = reader.ReadBoolean(BooleanCoding.Dword);
Shots = reader.ReadInt32(); Shots = reader.ReadInt32();
ShotEndsTurn = reader.ReadBoolean(BooleanCoding.Dword); ShotEndsTurn = reader.ReadBoolean(BooleanCoding.Dword);
RetreatTime = reader.ReadInt32(); RetreatTime = reader.ReadInt32();
Unknown1 = reader.ReadInt32(); Unknown1 = reader.ReadInt32();
CrateChance = reader.ReadInt32(); CrateChance = reader.ReadInt32();
CrateCount = reader.ReadInt32(); CrateCount = reader.ReadInt32();
Unknown2 = reader.ReadInt32(); Unknown2 = reader.ReadInt32();
// Read the activation and the corresponding weapon settings. // Read the activation and the corresponding weapon settings.
Activation = reader.ReadEnum<WeaponActivation>(false); Activation = reader.ReadEnum<WeaponActivation>(false);
switch (Activation) switch (Activation)
{ {
case WeaponActivation.Airstrike: case WeaponActivation.Airstrike:
AirstrikeSubtype = reader.ReadInt32(); AirstrikeSubtype = reader.ReadInt32();
Style = reader.ReadObject<AirstrikeStyle>(); Style = reader.ReadObject<AirstrikeStyle>();
break; break;
case WeaponActivation.Crosshair: case WeaponActivation.Crosshair:
NotUsed = reader.ReadInt32(); NotUsed = reader.ReadInt32();
CrosshairAction = reader.ReadEnum<WeaponCrosshairAction>(false); CrosshairAction = reader.ReadEnum<WeaponCrosshairAction>(false);
switch (CrosshairAction) Style = CrosshairAction switch
{ {
case WeaponCrosshairAction.Bow: WeaponCrosshairAction.Bow => reader.ReadObject<BowStyle>(),
Style = reader.ReadObject<BowStyle>(); WeaponCrosshairAction.Flamethrower => reader.ReadObject<FlamethrowerStyle>(),
break; WeaponCrosshairAction.Gun => reader.ReadObject<GunStyle>(),
case WeaponCrosshairAction.Flamethrower: WeaponCrosshairAction.Launcher => reader.ReadObject<LauncherStyle>(),
Style = reader.ReadObject<FlamethrowerStyle>(); _ => null
break; };
case WeaponCrosshairAction.Gun: break;
Style = reader.ReadObject<GunStyle>(); case WeaponActivation.Spacebar:
break; SpacebarAction = reader.ReadEnum<WeaponSpacebarAction>(false);
case WeaponCrosshairAction.Launcher: Style = SpacebarAction switch
Style = reader.ReadObject<LauncherStyle>(); {
break; WeaponSpacebarAction.Armageddon => reader.ReadObject<LauncherStyle>(),
} WeaponSpacebarAction.BaseballBat => reader.ReadObject<BaseballBatStyle>(),
break; WeaponSpacebarAction.BattleAxe => reader.ReadObject<BattleAxeStyle>(),
case WeaponActivation.Spacebar: WeaponSpacebarAction.Blowtorch => reader.ReadObject<BlowtorchStyle>(),
SpacebarAction = reader.ReadEnum<WeaponSpacebarAction>(false); WeaponSpacebarAction.Dragonball => reader.ReadObject<DragonballStyle>(),
switch (SpacebarAction) WeaponSpacebarAction.Firepunch => reader.ReadObject<FirepunchStyle>(),
{ WeaponSpacebarAction.Jetpack => reader.ReadObject<JetpackStyle>(),
case WeaponSpacebarAction.Armageddon: WeaponSpacebarAction.Kamikaze => reader.ReadObject<KamikazeStyle>(),
Style = reader.ReadObject<LauncherStyle>(); WeaponSpacebarAction.NinjaRope => reader.ReadObject<NinjaRopeStyle>(),
break; WeaponSpacebarAction.NuclearTest => reader.ReadObject<NuclearTestStyle>(),
case WeaponSpacebarAction.BaseballBat: WeaponSpacebarAction.Parachute => reader.ReadObject<ParachuteStyle>(),
Style = reader.ReadObject<BaseballBatStyle>(); WeaponSpacebarAction.PneumaticDrill => reader.ReadObject<PneumaticDrillStyle>(),
break; WeaponSpacebarAction.Prod => reader.ReadObject<ProdStyle>(),
case WeaponSpacebarAction.BattleAxe: WeaponSpacebarAction.SuicideBomber => reader.ReadObject<SuicideBomberStyle>(),
Style = reader.ReadObject<BattleAxeStyle>(); _ => null
break; };
case WeaponSpacebarAction.Blowtorch: break;
Style = reader.ReadObject<BlowtorchStyle>(); case WeaponActivation.Throw:
break; ThrowHerdCount = reader.ReadInt32();
case WeaponSpacebarAction.Dragonball: ThrowAction = reader.ReadEnum<WeaponThrowAction>(false);
Style = reader.ReadObject<DragonballStyle>(); Style = ThrowAction switch
break; {
case WeaponSpacebarAction.Firepunch: WeaponThrowAction.Canister => reader.ReadObject<CanisterStyle>(),
Style = reader.ReadObject<FirepunchStyle>(); WeaponThrowAction.Launcher => reader.ReadObject<LauncherStyle>(),
break; WeaponThrowAction.Mine => reader.ReadObject<MineStyle>(),
case WeaponSpacebarAction.Jetpack: _ => null
Style = reader.ReadObject<JetpackStyle>(); };
break; break;
case WeaponSpacebarAction.Kamikaze: }
Style = reader.ReadObject<KamikazeStyle>();
break; // Read additional settings.
case WeaponSpacebarAction.NinjaRope: reader.Position = offset + 468;
Style = reader.ReadObject<NinjaRopeStyle>(); AmmunitionOverride = reader.ReadBoolean(BooleanCoding.Dword);
break; Ammunition = reader.ReadInt32();
case WeaponSpacebarAction.NuclearTest: Unknown3 = reader.ReadInt32();
Style = reader.ReadObject<NuclearTestStyle>(); WeaponSprite = reader.ReadInt32();
break; NameLong = reader.ReadString(StringCoding.Int32CharCount);
case WeaponSpacebarAction.Parachute: Name = reader.ReadString(StringCoding.Int32CharCount);
Style = reader.ReadObject<ParachuteStyle>(); GridImageFile = reader.ReadString(StringCoding.Int32CharCount);
break;
case WeaponSpacebarAction.PneumaticDrill:
Style = reader.ReadObject<PneumaticDrillStyle>();
break;
case WeaponSpacebarAction.Prod:
Style = reader.ReadObject<ProdStyle>();
break;
case WeaponSpacebarAction.SuicideBomber:
Style = reader.ReadObject<SuicideBomberStyle>();
break;
case WeaponSpacebarAction.Bungee:
case WeaponSpacebarAction.Earthquake:
case WeaponSpacebarAction.Freeze:
case WeaponSpacebarAction.Girder:
case WeaponSpacebarAction.ScalesOfJustice:
case WeaponSpacebarAction.SelectWorm:
case WeaponSpacebarAction.SkipGo:
case WeaponSpacebarAction.Surrender:
case WeaponSpacebarAction.Teleport:
case WeaponSpacebarAction.Utility:
Style = null;
break;
}
break;
case WeaponActivation.Throw:
ThrowHerdCount = reader.ReadInt32();
ThrowAction = reader.ReadEnum<WeaponThrowAction>(false);
switch (ThrowAction)
{
case WeaponThrowAction.Canister:
Style = reader.ReadObject<CanisterStyle>();
break;
case WeaponThrowAction.Launcher:
Style = reader.ReadObject<LauncherStyle>();
break;
case WeaponThrowAction.Mine:
Style = reader.ReadObject<MineStyle>();
break;
}
break;
}
// Read additional settings.
reader.Position = offset + 468;
AmmunitionOverride = reader.ReadBoolean(BooleanCoding.Dword);
Ammunition = reader.ReadInt32();
Unknown3 = reader.ReadInt32();
WeaponSprite = reader.ReadInt32();
NameLong = reader.ReadString(StringCoding.Int32CharCount);
Name = reader.ReadString(StringCoding.Int32CharCount);
GridImageFile = reader.ReadString(StringCoding.Int32CharCount);
GfxDirectoryFile = reader.ReadString(StringCoding.Int32CharCount); GfxDirectoryFile = reader.ReadString(StringCoding.Int32CharCount);
for (int i = 0; i < SpriteNames.Length; i++) for (int i = 0; i < SpriteNames.Length; i++)
SpriteNames[i] = reader.ReadString(StringCoding.Int32CharCount); SpriteNames[i] = reader.ReadString(StringCoding.Int32CharCount);
DelayOverride = reader.ReadBoolean(BooleanCoding.Dword); DelayOverride = reader.ReadBoolean(BooleanCoding.Dword);
Delay = reader.ReadInt32(); Delay = reader.ReadInt32();
UseLibrary = reader.ReadBoolean(); UseLibrary = reader.ReadBoolean();
if (UseLibrary) if (UseLibrary)
{ {
LibraryName = reader.ReadString(StringCoding.Int32CharCount); LibraryName = reader.ReadString(StringCoding.Int32CharCount);
LibraryWeaponName = reader.ReadString(StringCoding.Int32CharCount); LibraryWeaponName = reader.ReadString(StringCoding.Int32CharCount);
} }
AimSpriteEven = reader.ReadString(StringCoding.Int32CharCount); AimSpriteEven = reader.ReadString(StringCoding.Int32CharCount);
AimSpriteUphill = reader.ReadString(StringCoding.Int32CharCount); AimSpriteUphill = reader.ReadString(StringCoding.Int32CharCount);
AimSpriteDownhill = reader.ReadString(StringCoding.Int32CharCount); AimSpriteDownhill = reader.ReadString(StringCoding.Int32CharCount);
PickSpriteEven = reader.ReadString(StringCoding.Int32CharCount); PickSpriteEven = reader.ReadString(StringCoding.Int32CharCount);
PickSpriteUphill = reader.ReadString(StringCoding.Int32CharCount); PickSpriteUphill = reader.ReadString(StringCoding.Int32CharCount);
PickSpriteDownhill = reader.ReadString(StringCoding.Int32CharCount); PickSpriteDownhill = reader.ReadString(StringCoding.Int32CharCount);
FireSpriteEven = reader.ReadString(StringCoding.Int32CharCount); FireSpriteEven = reader.ReadString(StringCoding.Int32CharCount);
FireSpriteUphill = reader.ReadString(StringCoding.Int32CharCount); FireSpriteUphill = reader.ReadString(StringCoding.Int32CharCount);
FireSpriteDownhill = reader.ReadString(StringCoding.Int32CharCount); FireSpriteDownhill = reader.ReadString(StringCoding.Int32CharCount);
AimSpriteOverride = reader.ReadBoolean(); AimSpriteOverride = reader.ReadBoolean();
PickSpriteOverride = reader.ReadBoolean(); PickSpriteOverride = reader.ReadBoolean();
FireSpriteOverride = reader.ReadBoolean(); FireSpriteOverride = reader.ReadBoolean();
if (Version == WeaponVersion.Version_0_8_0) if (Version == WeaponVersion.Version_0_8_0)
Utility = reader.ReadBoolean(); Utility = reader.ReadBoolean();
} }
/// <inheritdoc/> /// <inheritdoc/>
public void Save(Stream stream) public void Save(Stream stream)
{ {
using BinaryStream writer = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true); using BinaryStream writer = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true);
// Write the header. // Write the header.
long offset = writer.Position; long offset = writer.Position;
writer.WriteEnum(Version, true); writer.WriteEnum(Version, true);
writer.Write(Checksum); writer.Write(Checksum);
// Write the general settings. // Write the general settings.
writer.Write(TableRow); writer.Write(TableRow);
writer.Write(Remembered, BooleanCoding.Dword); writer.Write(Remembered, BooleanCoding.Dword);
writer.Write(UsableInCavern, BooleanCoding.Dword); writer.Write(UsableInCavern, BooleanCoding.Dword);
writer.Write(Shots); writer.Write(Shots);
writer.Write(ShotEndsTurn, BooleanCoding.Dword); writer.Write(ShotEndsTurn, BooleanCoding.Dword);
writer.Write(RetreatTime); writer.Write(RetreatTime);
writer.Write(Unknown1); writer.Write(Unknown1);
writer.Write(CrateChance); writer.Write(CrateChance);
writer.Write(CrateCount); writer.Write(CrateCount);
writer.Write(Unknown2); writer.Write(Unknown2);
// Write the activation and the corresponding weapon settings. // Write the activation and the corresponding weapon settings.
writer.WriteEnum(Activation, true); writer.WriteEnum(Activation, true);
switch (Activation) switch (Activation)
{ {
case WeaponActivation.Airstrike: case WeaponActivation.Airstrike:
writer.Write(AirstrikeSubtype); writer.Write(AirstrikeSubtype);
writer.WriteObject(Style); writer.WriteObject(Style);
break; break;
case WeaponActivation.Crosshair: case WeaponActivation.Crosshair:
writer.Write(NotUsed); writer.Write(NotUsed);
writer.WriteEnum(CrosshairAction, true); writer.WriteEnum(CrosshairAction, true);
if (CrosshairAction != WeaponCrosshairAction.None) if (CrosshairAction != WeaponCrosshairAction.None)
writer.WriteObject(Style); writer.WriteObject(Style);
break; break;
case WeaponActivation.Spacebar: case WeaponActivation.Spacebar:
writer.WriteEnum(SpacebarAction, true); writer.WriteEnum(SpacebarAction, true);
switch (SpacebarAction) switch (SpacebarAction)
{ {
case WeaponSpacebarAction.Armageddon: case WeaponSpacebarAction.Armageddon:
case WeaponSpacebarAction.BaseballBat: case WeaponSpacebarAction.BaseballBat:
case WeaponSpacebarAction.BattleAxe: case WeaponSpacebarAction.BattleAxe:
case WeaponSpacebarAction.Blowtorch: case WeaponSpacebarAction.Blowtorch:
case WeaponSpacebarAction.Dragonball: case WeaponSpacebarAction.Dragonball:
case WeaponSpacebarAction.Firepunch: case WeaponSpacebarAction.Firepunch:
case WeaponSpacebarAction.Jetpack: case WeaponSpacebarAction.Jetpack:
case WeaponSpacebarAction.Kamikaze: case WeaponSpacebarAction.Kamikaze:
case WeaponSpacebarAction.NinjaRope: case WeaponSpacebarAction.NinjaRope:
case WeaponSpacebarAction.NuclearTest: case WeaponSpacebarAction.NuclearTest:
case WeaponSpacebarAction.Parachute: case WeaponSpacebarAction.Parachute:
case WeaponSpacebarAction.PneumaticDrill: case WeaponSpacebarAction.PneumaticDrill:
case WeaponSpacebarAction.Prod: case WeaponSpacebarAction.Prod:
case WeaponSpacebarAction.SuicideBomber: case WeaponSpacebarAction.SuicideBomber:
writer.WriteObject(Style); writer.WriteObject(Style);
break; break;
} }
break; break;
case WeaponActivation.Throw: case WeaponActivation.Throw:
writer.Write(ThrowHerdCount); writer.Write(ThrowHerdCount);
writer.WriteEnum(ThrowAction, true); writer.WriteEnum(ThrowAction, true);
if (ThrowAction != WeaponThrowAction.None) if (ThrowAction != WeaponThrowAction.None)
writer.WriteObject(Style); writer.WriteObject(Style);
break; break;
} }
// Write additional settings. // Write additional settings.
writer.Position = offset + 468; writer.Position = offset + 468;
writer.Write(AmmunitionOverride, BooleanCoding.Dword); writer.Write(AmmunitionOverride, BooleanCoding.Dword);
writer.Write(Ammunition); writer.Write(Ammunition);
writer.Write(Unknown3); writer.Write(Unknown3);
writer.Write(WeaponSprite); writer.Write(WeaponSprite);
writer.Write(NameLong, StringCoding.Int32CharCount); writer.Write(NameLong, StringCoding.Int32CharCount);
writer.Write(Name, StringCoding.Int32CharCount); writer.Write(Name, StringCoding.Int32CharCount);
writer.Write(GridImageFile, StringCoding.Int32CharCount); writer.Write(GridImageFile, StringCoding.Int32CharCount);
writer.Write(GfxDirectoryFile, StringCoding.Int32CharCount); writer.Write(GfxDirectoryFile, StringCoding.Int32CharCount);
writer.Write(SpriteNames, StringCoding.Int32CharCount); writer.Write(SpriteNames, StringCoding.Int32CharCount);
writer.Write(DelayOverride, BooleanCoding.Dword); writer.Write(DelayOverride, BooleanCoding.Dword);
writer.Write(Delay); writer.Write(Delay);
writer.Write(UseLibrary); writer.Write(UseLibrary);
if (UseLibrary) if (UseLibrary)
{ {
writer.Write(LibraryName, StringCoding.Int32CharCount); writer.Write(LibraryName, StringCoding.Int32CharCount);
writer.Write(LibraryWeaponName, StringCoding.Int32CharCount); writer.Write(LibraryWeaponName, StringCoding.Int32CharCount);
} }
writer.Write(AimSpriteEven, StringCoding.Int32CharCount); writer.Write(AimSpriteEven, StringCoding.Int32CharCount);
writer.Write(AimSpriteUphill, StringCoding.Int32CharCount); writer.Write(AimSpriteUphill, StringCoding.Int32CharCount);
writer.Write(AimSpriteDownhill, StringCoding.Int32CharCount); writer.Write(AimSpriteDownhill, StringCoding.Int32CharCount);
writer.Write(PickSpriteEven, StringCoding.Int32CharCount); writer.Write(PickSpriteEven, StringCoding.Int32CharCount);
writer.Write(PickSpriteUphill, StringCoding.Int32CharCount); writer.Write(PickSpriteUphill, StringCoding.Int32CharCount);
writer.Write(PickSpriteDownhill, StringCoding.Int32CharCount); writer.Write(PickSpriteDownhill, StringCoding.Int32CharCount);
writer.Write(FireSpriteEven, StringCoding.Int32CharCount); writer.Write(FireSpriteEven, StringCoding.Int32CharCount);
writer.Write(FireSpriteUphill, StringCoding.Int32CharCount); writer.Write(FireSpriteUphill, StringCoding.Int32CharCount);
writer.Write(FireSpriteDownhill, StringCoding.Int32CharCount); writer.Write(FireSpriteDownhill, StringCoding.Int32CharCount);
writer.Write(AimSpriteOverride); writer.Write(AimSpriteOverride);
writer.Write(PickSpriteOverride); writer.Write(PickSpriteOverride);
writer.Write(FireSpriteOverride); writer.Write(FireSpriteOverride);
if (Version == WeaponVersion.Version_0_8_0) if (Version == WeaponVersion.Version_0_8_0)
writer.Write(Utility); writer.Write(Utility);
} }
} }
public enum WeaponVersion : int public enum WeaponVersion : int
{ {
Version_0_8_0_pre = 0x5ABBDD05, Version_0_8_0_pre = 0x5ABBDD05,
Version_0_8_0 = 0x5ABBDD06 Version_0_8_0 = 0x5ABBDD06
} }
public enum WeaponActivation : int public enum WeaponActivation : int
{ {
None, None,
Crosshair, Crosshair,
Throw, Throw,
Airstrike, Airstrike,
Spacebar Spacebar
} }
public enum WeaponSpacebarAction : int public enum WeaponSpacebarAction : int
{ {
None, None,
Firepunch, Firepunch,
BaseballBat, BaseballBat,
Dragonball, Dragonball,
Kamikaze, Kamikaze,
SuicideBomber, SuicideBomber,
NinjaRope, NinjaRope,
Bungee, Bungee,
PneumaticDrill, PneumaticDrill,
Prod, Prod,
Teleport, Teleport,
Blowtorch, Blowtorch,
Parachute, Parachute,
Surrender, Surrender,
SkipGo, SkipGo,
SelectWorm, SelectWorm,
NuclearTest, NuclearTest,
Girder, Girder,
BattleAxe, BattleAxe,
Utility, Utility,
Freeze, Freeze,
Earthquake, Earthquake,
ScalesOfJustice, ScalesOfJustice,
Jetpack, Jetpack,
Armageddon Armageddon
} }
public enum WeaponCrosshairAction : int public enum WeaponCrosshairAction : int
{ {
None, None,
Flamethrower, Flamethrower,
Gun, Gun,
Launcher, Launcher,
Bow Bow
} }
public enum WeaponThrowAction : int public enum WeaponThrowAction : int
{ {
None, None,
Mine, Mine,
Launcher, Launcher,
Canister Canister
} }
public enum WeaponSpriteNameIndex public enum WeaponSpriteNameIndex
{ {
Unknown0, Unknown0,
Launcher, Launcher,
Cluster, Cluster,
Home, Home,
Unknown4 Unknown4
} }
} }

View File

@ -1,14 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)build.xml" /> <Import Project="$(SolutionDir)build.xml" />
<!-- Metadata -->
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AssemblyName>Syroot.Worms.Armageddon</AssemblyName>
<Description>.NET library for loading and modifying files of Team17's Worms Armageddon.</Description> <Description>.NET library for loading and modifying files of Team17's Worms Armageddon.</Description>
<PackageReleaseNotes>Overhaul implementation and documentation. Implement W:A V3 scheme format.</PackageReleaseNotes> <PackageReleaseNotes>Overhaul implementation and documentation. Implement W:A V3 scheme format.</PackageReleaseNotes>
<PackageTags>$(PackageTags);worms armageddon</PackageTags> <PackageTags>$(PackageTags);worms armageddon</PackageTags>
<Version>4.0.0</Version> <Version>4.0.0</Version>
</PropertyGroup> </PropertyGroup>
<!-- References -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Syroot.Worms\Syroot.Worms.csproj" /> <ProjectReference Include="..\Syroot.Worms\Syroot.Worms.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,13 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)build.xml" /> <Import Project="$(SolutionDir)build.xml" />
<!-- Metadata -->
<PropertyGroup> <PropertyGroup>
<AssemblyName>Syroot.Worms.Mgame</AssemblyName>
<Description>.NET library for loading and modifying files of Mgame Worms clients.</Description> <Description>.NET library for loading and modifying files of Mgame Worms clients.</Description>
<PackageReleaseNotes>Overhaul implementation and documentation.</PackageReleaseNotes> <PackageReleaseNotes>Overhaul implementation and documentation.</PackageReleaseNotes>
<PackageTags>$(PackageTags);online worms;worms world party aqua</PackageTags> <PackageTags>$(PackageTags);online worms;worms world party aqua</PackageTags>
<Version>4.0.0</Version> <Version>4.0.0</Version>
</PropertyGroup> </PropertyGroup>
<!-- References -->
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
<ProjectReference Include="..\Syroot.Worms\Syroot.Worms.csproj" /> <ProjectReference Include="..\Syroot.Worms\Syroot.Worms.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,5 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)build.xml" /> <Import Project="$(SolutionDir)build.xml" />
<!-- Metadata -->
<PropertyGroup> <PropertyGroup>
<AssemblyName>Syroot.Worms.WorldParty</AssemblyName> <AssemblyName>Syroot.Worms.WorldParty</AssemblyName>
<Description>.NET library for loading and modifying files of Team17's Worms World Party.</Description> <Description>.NET library for loading and modifying files of Team17's Worms World Party.</Description>
@ -7,7 +9,10 @@
<PackageTags>$(PackageTags);worms world party</PackageTags> <PackageTags>$(PackageTags);worms world party</PackageTags>
<Version>4.0.0</Version> <Version>4.0.0</Version>
</PropertyGroup> </PropertyGroup>
<!-- References -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Syroot.Worms\Syroot.Worms.csproj" /> <ProjectReference Include="..\Syroot.Worms\Syroot.Worms.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,13 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)build.xml" /> <Import Project="$(SolutionDir)build.xml" />
<!-- Metadata -->
<PropertyGroup> <PropertyGroup>
<AssemblyName>Syroot.Worms.Worms2</AssemblyName>
<Description>.NET library for loading and modifying files of Team17's Worms 2.</Description> <Description>.NET library for loading and modifying files of Team17's Worms 2.</Description>
<PackageReleaseNotes>Overhaul implementation and documentation.</PackageReleaseNotes> <PackageReleaseNotes>Overhaul implementation and documentation.</PackageReleaseNotes>
<PackageTags>$(PackageTags);worms 2</PackageTags> <PackageTags>$(PackageTags);worms 2</PackageTags>
<Version>4.0.0</Version> <Version>4.0.0</Version>
</PropertyGroup> </PropertyGroup>
<!-- References -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Syroot.Worms\Syroot.Worms.csproj" /> <ProjectReference Include="..\Syroot.Worms\Syroot.Worms.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -14,19 +14,6 @@ namespace Syroot.Worms.IO
// ---- Reading ---- // ---- Reading ----
/// <summary>
/// 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"/> instance.</param>
/// <returns>The <see cref="ILoadable"/> instance.</returns>
public static T Load<T>(this BinaryStream self) where T : ILoadable, new()
{
T instance = new T();
instance.Load(self.BaseStream);
return instance;
}
/// <summary> /// <summary>
/// Reads an RGBA 32-bit color. /// Reads an RGBA 32-bit color.
/// </summary> /// </summary>
@ -78,17 +65,6 @@ namespace Syroot.Worms.IO
// ---- Writing ---- // ---- Writing ----
/// <summary>
/// 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"/> 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
{
value.Save(self.BaseStream);
}
/// <summary> /// <summary>
/// Writes the given <paramref name="value"/> to the given <paramref name="offset"/>. This is meant to be used /// Writes the given <paramref name="value"/> to the given <paramref name="offset"/>. This is meant to be used
/// in combination with <see cref="ReserveOffset"/>. /// in combination with <see cref="ReserveOffset"/>.

View File

@ -61,6 +61,29 @@ namespace Syroot.Worms.IO
public static unsafe void WriteStructs<T>(this Stream stream, ReadOnlySpan<T> span) where T : unmanaged public static unsafe void WriteStructs<T>(this Stream stream, ReadOnlySpan<T> span) where T : unmanaged
=> stream.Write(MemoryMarshal.Cast<T, byte>(span)); => stream.Write(MemoryMarshal.Cast<T, byte>(span));
// ---- ILoadable / ISaveable ----
/// <summary>
/// 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"/> instance.</param>
/// <returns>The <see cref="ILoadable"/> instance.</returns>
public static T Load<T>(this Stream self) where T : ILoadable, new()
{
T instance = new T();
instance.Load(self);
return instance;
}
/// <summary>
/// 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"/> instance.</param>
/// <param name="value">The instance to write into the current stream.</param>
public static void Save<T>(this Stream self, T value) where T : ISaveable => value.Save(self);
// ---- Backports ---- // ---- Backports ----
#if NETSTANDARD2_0 #if NETSTANDARD2_0

View File

@ -1,19 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)build.xml" /> <Import Project="$(SolutionDir)build.xml" />
<!-- Metadata -->
<PropertyGroup> <PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AssemblyName>Syroot.Worms</AssemblyName>
<Description>.NET library for loading and modifying files of Team17 Worms games.</Description> <Description>.NET library for loading and modifying files of Team17 Worms games.</Description>
<PackageReleaseNotes>Overhaul implementation and documentation.</PackageReleaseNotes> <PackageReleaseNotes>Overhaul implementation and documentation.</PackageReleaseNotes>
<Version>4.0.0</Version> <Version>4.0.0</Version>
</PropertyGroup> </PropertyGroup>
<!-- References -->
<ItemGroup> <ItemGroup>
<PackageReference Include="Syroot.BinaryData.Serialization" Version="5.2.0" /> <PackageReference Include="Syroot.BinaryData" Version="5.2.1" />
<PackageReference Include="Syroot.BinaryData" Version="5.2.0" />
<PackageReference Include="System.Drawing.Common" Version="4.5.0" /> <PackageReference Include="System.Drawing.Common" Version="4.5.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'"> <ItemGroup Condition="'$(TargetFramework)'=='netstandard2.0'">
<PackageReference Include="Microsoft.Bcl.HashCode" Version="1.0.0" /> <PackageReference Include="Microsoft.Bcl.HashCode" Version="1.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Compilation --> <!-- Compilation -->
<PropertyGroup> <PropertyGroup>
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
@ -23,4 +24,5 @@
<Message Text="Linking Files" Importance="high" /> <Message Text="Linking Files" Importance="high" />
<Exec Command="MKLINK /D &quot;$(OutputPath)Files&quot; &quot;$(ProjectDir)Files&quot;" /> <Exec Command="MKLINK /D &quot;$(OutputPath)Files&quot; &quot;$(ProjectDir)Files&quot;" />
</Target> </Target>
</Project> </Project>

View File

@ -1,7 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)test.xml" /> <Import Project="$(SolutionDir)test.xml" />
<!-- References -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\library\Syroot.Worms.Armageddon.ProjectX\Syroot.Worms.Armageddon.ProjectX.csproj" /> <ProjectReference Include="..\..\library\Syroot.Worms.Armageddon.ProjectX\Syroot.Worms.Armageddon.ProjectX.csproj" />
<ProjectReference Include="..\Syroot.Worms.Test\Syroot.Worms.Test.csproj" /> <ProjectReference Include="..\Syroot.Worms.Test\Syroot.Worms.Test.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,7 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)test.xml" /> <Import Project="$(SolutionDir)test.xml" />
<!-- References -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\library\Syroot.Worms.Armageddon\Syroot.Worms.Armageddon.csproj" /> <ProjectReference Include="..\..\library\Syroot.Worms.Armageddon\Syroot.Worms.Armageddon.csproj" />
<ProjectReference Include="..\Syroot.Worms.Test\Syroot.Worms.Test.csproj" /> <ProjectReference Include="..\Syroot.Worms.Test\Syroot.Worms.Test.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,7 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)test.xml" /> <Import Project="$(SolutionDir)test.xml" />
<!-- References -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\library\Syroot.Worms.Mgame\Syroot.Worms.Mgame.csproj" /> <ProjectReference Include="..\..\library\Syroot.Worms.Mgame\Syroot.Worms.Mgame.csproj" />
<ProjectReference Include="..\Syroot.Worms.Test\Syroot.Worms.Test.csproj" /> <ProjectReference Include="..\Syroot.Worms.Test\Syroot.Worms.Test.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,6 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)test.xml" /> <Import Project="$(SolutionDir)test.xml" />
<!-- References -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\library\Syroot.Worms\Syroot.Worms.csproj" /> <ProjectReference Include="..\..\library\Syroot.Worms\Syroot.Worms.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,7 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)test.xml" /> <Import Project="$(SolutionDir)test.xml" />
<!-- References -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\library\Syroot.Worms.WorldParty\Syroot.Worms.WorldParty.csproj" /> <ProjectReference Include="..\..\library\Syroot.Worms.WorldParty\Syroot.Worms.WorldParty.csproj" />
<ProjectReference Include="..\Syroot.Worms.Test\Syroot.Worms.Test.csproj" /> <ProjectReference Include="..\Syroot.Worms.Test\Syroot.Worms.Test.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,7 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)test.xml" /> <Import Project="$(SolutionDir)test.xml" />
<!-- References -->
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\library\Syroot.Worms.Worms2\Syroot.Worms.Worms2.csproj" /> <ProjectReference Include="..\..\library\Syroot.Worms.Worms2\Syroot.Worms.Worms2.csproj" />
<ProjectReference Include="..\Syroot.Worms.Test\Syroot.Worms.Test.csproj" /> <ProjectReference Include="..\Syroot.Worms.Test\Syroot.Worms.Test.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>