diff --git a/README.md b/README.md
index 4a4145e..870540f 100644
--- a/README.md
+++ b/README.md
@@ -21,7 +21,6 @@ Formats of the second generation 2D games are mostly focused right now.
| Description | Extension | Games | Load | Save |
|-------------------|:---------:|:-----------:|:----:|:----:|
| Archive | DIR | W2, WA, WWP | Yes | Yes |
-| Game Scheme | WSC | WA, WWP | No | No |
| Image | IMG | W2, WA, WWP | Yes | No |
| Mission | DAT | W2 | No | No |
| Mission | WAM | WA, WWP | No | No |
@@ -32,6 +31,7 @@ Formats of the second generation 2D games are mostly focused right now.
| Project X Library | PXL | WA+PX | No | No |
| Project X Scheme | PXS | WA+PX | No | No |
| Replay | WAGAME | WA | No | No |
+| Scheme | WSC | WA, WWP | Yes | Yes |
| Team Container | ST1 | W2 | No | No |
| Team Container | WGT | WA, WWP | No | No |
| Weapon Scheme | WEP | W2 | No | No |
diff --git a/src/Syroot.Worms.Test/Program.cs b/src/Syroot.Worms.Test/Program.cs
index 2e7f6d7..742710e 100644
--- a/src/Syroot.Worms.Test/Program.cs
+++ b/src/Syroot.Worms.Test/Program.cs
@@ -1,7 +1,8 @@
using System;
using System.IO;
-using Syroot.Worms.Gen2;
using System.Collections.Generic;
+using Syroot.Worms.Gen2.Armageddon;
+using Syroot.Worms.Core;
namespace Syroot.Worms.Test
{
@@ -33,16 +34,8 @@ namespace Syroot.Worms.Test
// Console.WriteLine("Loading {imgFile}...");
// Image image = new Image(imgFile);
//}
-
- Palette pal = new Palette(@"C:\Games\Worms Armageddon 3.7.2.1\graphics\ServerLobby\flagsandwormnet.pal");
- pal.Save(@"D:\Pictures\test.pal");
-
- foreach (string palFile in GetFiles(" *.pal"))
- {
- Console.WriteLine($"Loading {palFile}...");
- Palette palette = new Palette(palFile);
- palette.Save(@"D:\Pictures\test.pal");
- }
+ Scheme scheme = new Scheme(@"D:\Pictures\Test.wsc");
+ scheme.Save(@"D:\Pictures\Test2.wsc");
Console.ReadLine();
}
diff --git a/src/Syroot.Worms/Core/ByteArrayExtensions.cs b/src/Syroot.Worms/Core/ByteArrayExtensions.cs
index 7e5b142..a78348f 100644
--- a/src/Syroot.Worms/Core/ByteArrayExtensions.cs
+++ b/src/Syroot.Worms/Core/ByteArrayExtensions.cs
@@ -1,7 +1,7 @@
namespace Syroot.Worms.Core
{
///
- /// Represents extension methods for byte array instances.
+ /// Represents extension methods for array instances.
///
internal static class ByteArrayExtensions
{
diff --git a/src/Syroot.Worms/Core/ByteExtensions.cs b/src/Syroot.Worms/Core/ByteExtensions.cs
new file mode 100644
index 0000000..b57ef7c
--- /dev/null
+++ b/src/Syroot.Worms/Core/ByteExtensions.cs
@@ -0,0 +1,226 @@
+namespace Syroot.Worms.Core
+{
+ ///
+ /// Represents extension methods for instances.
+ ///
+ internal static class ByteExtensions
+ {
+ // ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
+
+ ///
+ /// Returns the current byte with the bit at the set (being 1).
+ ///
+ /// The extended instance.
+ /// The 0-based index of the bit to enable.
+ /// The current byte with the bit enabled.
+ internal static byte EnableBit(this byte self, int index)
+ {
+ return (byte)(self | (1 << index));
+ }
+
+ ///
+ /// Returns the current byte with the bit at the cleared (being 0).
+ ///
+ /// The extended instance.
+ /// The 0-based index of the bit to disable.
+ /// The current byte with the bit disabled.
+ internal static byte DisableBit(this byte self, int index)
+ {
+ return (byte)(self & ~(1 << index));
+ }
+
+ ///
+ /// Returns a value indicating whether the bit at the in the current byte is enabled
+ /// or disabled.
+ ///
+ /// The extended instance.
+ /// The 0-based index of the bit to check.
+ /// true when the bit is set; otherwise false.
+ internal static bool GetBit(this byte self, int index)
+ {
+ return (self & (1 << index)) != 0;
+ }
+
+ ///
+ /// Returns the current byte with all bits rotated in the given , where positive
+ /// directions rotate left and negative directions rotate right.
+ ///
+ /// The extended instance.
+ /// The direction in which to rotate, where positive directions rotate left.
+ /// The current byte with the bits rotated.
+ internal static byte RotateBits(this byte self, int direction)
+ {
+ int bits = sizeof(byte) * 8;
+ if (direction > 0)
+ {
+ return (byte)((self << direction) | (self >> (bits - direction)));
+ }
+ else if (direction < 0)
+ {
+ direction = -direction;
+ return (byte)((self >> direction) | (self << (bits - direction)));
+ }
+ return self;
+ }
+
+ ///
+ /// Returns the current byte with the bit at the enabled or disabled, according to
+ /// .
+ ///
+ /// The extended instance.
+ /// The 0-based index of the bit to enable or disable.
+ /// true to enable the bit; otherwise false.
+ /// The current byte with the bit enabled or disabled.
+ internal static byte SetBit(this byte self, int index, bool enable)
+ {
+ if (enable)
+ {
+ return EnableBit(self, index);
+ }
+ else
+ {
+ return DisableBit(self, index);
+ }
+ }
+
+ ///
+ /// Returns the current byte with the bit at the enabled when it is disabled or
+ /// disabled when it is enabled.
+ ///
+ /// The extended instance.
+ /// The 0-based index of the bit to toggle.
+ /// The current byte with the bit toggled.
+ internal static byte ToggleBit(this byte self, int index)
+ {
+ if (GetBit(self, index))
+ {
+ return DisableBit(self, index);
+ }
+ else
+ {
+ return EnableBit(self, index);
+ }
+ }
+
+ ///
+ /// Returns an instance represented by the given number of .
+ ///
+ /// The extended instance.
+ /// The number of least significant bits which are used to store the
+ /// value.
+ /// The decoded .
+ internal static byte DecodeByte(this byte self, int bits)
+ {
+ return DecodeByte(self, bits, 0);
+ }
+
+ ///
+ /// Returns an instance represented by the given number of , starting
+ /// at the .
+ ///
+ /// The extended instance.
+ /// The number of least significant bits which are used to store the
+ /// value.
+ /// The first bit of the encoded value.
+ /// The decoded .
+ internal static byte DecodeByte(this byte self, int bits, int firstBit)
+ {
+ // Shift to the first bit and keep only the required bits.
+ return (byte)((self >> firstBit) & ((1 << bits) - 1));
+ }
+
+ ///
+ /// Returns an instance represented by the given number of .
+ ///
+ /// The extended instance.
+ /// The number of least significant bits which are used to store the
+ /// value.
+ /// The decoded .
+ internal static sbyte DecodeSByte(this byte self, int bits)
+ {
+ return DecodeSByte(self, bits, 0);
+ }
+
+ ///
+ /// Returns an instance represented by the given number of , starting
+ /// at the .
+ ///
+ /// The extended instance.
+ /// The number of least significant bits which are used to store the
+ /// value.
+ /// The first bit of the encoded value.
+ /// The decoded .
+ internal static sbyte DecodeSByte(this byte self, int bits, int firstBit)
+ {
+ self >>= firstBit;
+ int absMask = 1 << bits;
+ byte abs = (byte)(self & (absMask - 1));
+ if (abs.GetBit(bits - 1))
+ {
+ return (sbyte)(abs - absMask);
+ }
+ else
+ {
+ return (sbyte)abs;
+ }
+ }
+
+ ///
+ /// Returns the current byte with the given set into the given number of
+ /// .
+ ///
+ /// The extended instance.
+ /// The number of bits which are used to store the value.
+ /// The current byte with the value encoded into it.
+ internal static byte Encode(this byte self, byte value, int bits)
+ {
+ return Encode(self, value, bits, 0);
+ }
+
+ ///
+ /// Returns the current byte with the given set into the given number of
+ /// starting at .
+ ///
+ /// The extended instance.
+ /// The number of bits which are used to store the value.
+ /// The first bit used for the encoded value.
+ /// The current byte with the value encoded into it.
+ internal static byte Encode(this byte self, byte value, int bits, int firstBit)
+ {
+ // Clear the bits required for the value and fit it into them by truncating.
+ int mask = ((1 << bits) - 1) << firstBit;
+ self &= (byte)~mask;
+ value = (byte)((value << firstBit) & mask);
+
+ // Set the value.
+ return (byte)(self | value);
+ }
+
+ ///
+ /// Returns the current byte with the given set into the given number of
+ /// .
+ ///
+ /// The extended instance.
+ /// The number of bits which are used to store the value.
+ /// The current byte with the value encoded into it.
+ internal static byte Encode(this byte self, sbyte value, int bits)
+ {
+ return Encode(self, value, bits, 0);
+ }
+
+ ///
+ /// Returns the current byte with the given set into the given number of
+ /// starting at .
+ ///
+ /// The extended instance.
+ /// The number of bits which are used to store the value.
+ /// The first bit used for the encoded value.
+ /// The current byte with the value encoded into it.
+ internal static byte Encode(this byte self, sbyte value, int bits, int firstBit)
+ {
+ // Set the value as a normal byte, but then fix the sign.
+ self = Encode(self, (byte)value, bits, firstBit);
+ return self.SetBit(bits + firstBit - 1, value < 0);
+ }
+ }
+}
diff --git a/src/Syroot.Worms/Gen2/Armageddon/GameScheme.cs b/src/Syroot.Worms/Gen2/Armageddon/GameScheme.cs
deleted file mode 100644
index f71d920..0000000
--- a/src/Syroot.Worms/Gen2/Armageddon/GameScheme.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Syroot.Worms.Gen2.Armageddon
-{
- class GameScheme
- {
- }
-}
diff --git a/src/Syroot.Worms/Gen2/Armageddon/Scheme.cs b/src/Syroot.Worms/Gen2/Armageddon/Scheme.cs
new file mode 100644
index 0000000..4b39f44
--- /dev/null
+++ b/src/Syroot.Worms/Gen2/Armageddon/Scheme.cs
@@ -0,0 +1,2772 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using Syroot.IO;
+using Syroot.Maths;
+using Syroot.Worms.Core;
+
+namespace Syroot.Worms.Gen2.Armageddon
+{
+ ///
+ /// Represents a high level view on a scheme stored in a WSC file which contains game settings and armory
+ /// configuration.
+ /// Used by WA and WWP. S. https://worms2d.info/Game_scheme_file.
+ ///
+ public class Scheme : ILoadableFile, ISaveableFile
+ {
+ // ---- CONSTANTS ----------------------------------------------------------------------------------------------
+
+ private const int _signature = 0x4D484353; // "SCHM"
+
+ #region Lookup Tables
+
+ private static readonly Dictionary _mapWaterRiseToRaw = new Dictionary()
+ {
+ [0] = 0,
+ [5] = 1,
+ [13] = 19,
+ [20] = 2,
+ [21] = 55,
+ [29] = 43,
+ [37] = 47,
+ [45] = 3,
+ [52] = 26,
+ [53] = 25,
+ [61] = 27,
+ [64] = 8,
+ [69] = 33,
+ [77] = 13,
+ [80] = 4,
+ [84] = 18,
+ [85] = 23,
+ [93] = 11,
+ [101] = 15,
+ [109] = 29,
+ [116] = 22,
+ [117] = 57,
+ [125] = 5,
+ [133] = 63,
+ [141] = 45,
+ [148] = 30,
+ [149] = 9,
+ [157] = 21,
+ [165] = 17,
+ [173] = 61,
+ [180] = 6,
+ [181] = 39,
+ [189] = 37,
+ [197] = 31,
+ [205] = 51,
+ [208] = 12,
+ [212] = 14,
+ [213] = 41,
+ [221] = 53,
+ [229] = 49,
+ [237] = 35,
+ [244] = 10,
+ [245] = 7,
+ [253] = 59
+ };
+ private static readonly byte[] _objectCounts = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85,
+ 90, 95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250 };
+
+ #endregion
+
+ // ---- MEMBERS ------------------------------------------------------------------------------------------------
+
+ private byte _mineDelay;
+ private byte _turnTime;
+ private byte _roundTimeMinutes;
+ private byte _roundTimeSeconds;
+ private byte _numberOfWins;
+ private sbyte _rwGravity;
+ private sbyte _rwGravityConstBlackHole;
+ private sbyte _rwGravityPropBlackHole;
+ private byte _rwKaosMod;
+
+ // ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
+
+ ///
+ /// Initializes a new instance of the class, loading the data from the given
+ /// .
+ ///
+ /// The to load the data from.
+ public Scheme(Stream stream)
+ {
+ Load(stream);
+ }
+
+ ///
+ /// Initializes a new instance of the class, loading the data from the given file.
+ ///
+ /// The name of the file to load the data from.
+ public Scheme(string fileName)
+ {
+ Load(fileName);
+ }
+
+ // ---- PROPERTIES ---------------------------------------------------------------------------------------------
+
+ ///
+ /// Gets or sets the of this scheme, controlling whether super weapon settings
+ /// are stored or not.
+ ///
+ public SchemeVersion Version { get; set; }
+
+ ///
+ /// Gets or sets the delay in seconds between each team's turn to allow relaxed switching of seats.
+ ///
+ public byte HotSeatDelay { get; set; }
+
+ ///
+ /// Gets or sets the time in seconds available for a worm to retreat after using a weapon which ends the turn
+ /// while standing on land.
+ ///
+ public byte RetreatTime { get; set; }
+
+ ///
+ /// Gets or sets the time in seconds available for a worm to retreat after using a weapon which ends the turn
+ /// while on a rope.
+ ///
+ public byte RetreatTimeRope { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the total round time until sudden death will be displayed in the
+ /// turn timer.
+ ///
+ public bool ShowRoundTime { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether significant turns will be replayed in offline games.
+ ///
+ public bool AutomaticReplays { get; set; }
+
+ ///
+ /// Gets or sets the percentual amount of fall damage applied, relative to normal fall damage being 100%.
+ ///
+ public SchemeFallDamage FallDamage { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether worms cannot walk and are mostly stuck at their current position
+ /// without using any utilities.
+ ///
+ public bool ArtilleryMode { get; set; }
+
+ ///
+ /// Gets or sets a value indicating the scheme editor used to modify this scheme. Originally used to indicate
+ /// the unimplemented Bounty Mode.
+ ///
+ public SchemeEditor SchemeEditor { get; set; }
+
+ ///
+ /// Gets or sets a value indicating the stockpiling of armory between game rounds.
+ ///
+ public SchemeStockpiling StockpilingMode { get; set; }
+
+ ///
+ /// Gets or sets a value indicating the worm selection order determining the next worm to be played.
+ ///
+ public SchemeWormSelect WormSelectMode { get; set; }
+
+ ///
+ /// Gets or sets a value indicating the action triggered when Sudden Death starts.
+ ///
+ public SchemeSuddenDeathEvent SuddenDeathEvent { get; set; }
+
+ ///
+ /// Gets or sets the amount in pixels which the water will rise between turns after Sudden Death was triggered.
+ ///
+ public SchemeWaterRise WaterRiseRate { get; set; }
+
+ ///
+ /// Gets or sets the percentual probability of a weapon crate to drop between turns. Negative values might crash
+ /// the game.
+ ///
+ public sbyte WeaponCrateProbability { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether donor cards can spawn upon a worm's death.
+ ///
+ public bool DonorCards { get; set; }
+
+ ///
+ /// Gets or sets the percentual probability of a health crate to drop between turns. Negative values might crash
+ /// the game.
+ ///
+ public sbyte HealthCrateProbability { get; set; }
+
+ ///
+ /// Gets or sets the amount of health included in a health crate added to the collecting worm's energy.
+ ///
+ public byte HealthCrateEnergy { get; set; }
+
+ ///
+ /// Gets or sets the percentual probability of a utility crate to drop between turns. Negative values might
+ /// crash the game.
+ ///
+ public sbyte UtilityCrateProbability { get; set; }
+
+ ///
+ /// Gets or sets the type of objects which can be placed on the map.
+ ///
+ public SchemeObjectType ObjectTypes { get; set; }
+
+ ///
+ /// Gets or sets the maximum number of objects (mines or oil drums) on the map.
+ ///
+ public SchemeObjectCount ObjectCount { get; set; }
+
+ ///
+ /// Gets or sets the number of seconds a mine requires to explode. Can be 1-3 and 5-127 seconds.
+ ///
+ public byte MineDelay
+ {
+ get
+ {
+ return _mineDelay;
+ }
+ set
+ {
+ if (value == 4 || value > 0x7F)
+ {
+ throw new ArgumentException("Mine delay must be between 0-127 and not be 4.", nameof(value));
+ }
+ _mineDelay = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the mine fuse will be randomly chosen between fractions of 1 to 3
+ /// seconds. If true, the setting will be ignored.
+ ///
+ public bool MineDelayRandom { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether mines can refuse to explode after their count down.
+ ///
+ public bool DudMines { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether worms are placed manually by the players for their initial position
+ /// at round start.
+ ///
+ public bool ManualWormPlacement { get; set; }
+
+ ///
+ /// Gets or sets the initial worm energy at round start.
+ ///
+ public byte WormEnergy { get; set; }
+
+ ///
+ /// Gets or sets the turn time in seconds available for the player to move. Must be in the range of 0-127.
+ ///
+ public byte TurnTime
+ {
+ get
+ {
+ return _turnTime;
+ }
+ set
+ {
+ if (value > 0x7F)
+ {
+ throw new ArgumentException("Turn time must be between 0-127.", nameof(value));
+ }
+ _turnTime = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether the turn time is unlimited. If true, the
+ /// setting will be ignored.
+ ///
+ public bool TurnTimeInfinite { get; set; }
+
+ ///
+ /// Gets or sets the round time before sudden death is triggered between 0-127 minutes.
+ ///
+ public byte RoundTimeMinutes
+ {
+ get
+ {
+ return _roundTimeMinutes;
+ }
+ set
+ {
+ if (value > 0x7F)
+ {
+ throw new ArgumentException("Round time must be between 0-127 minutes.", nameof(value));
+ }
+ _roundTimeMinutes = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the round time before sudden death is triggered in between 0-128 seconds. When 0,
+ /// is used instead.
+ ///
+ public byte RoundTimeSeconds
+ {
+ get
+ {
+ return _roundTimeSeconds;
+ }
+ set
+ {
+ if (value > 0x80)
+ {
+ throw new ArgumentException("Round time must be between 0-128 seconds.", nameof(value));
+ }
+ _roundTimeSeconds = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the number of round wins required to win the game. Must not be 0.
+ ///
+ public byte NumberOfWins
+ {
+ get
+ {
+ return _numberOfWins;
+ }
+ set
+ {
+ if (value == 0)
+ {
+ throw new ArgumentException("Number of wins must not be 0.", nameof(value));
+ }
+ _numberOfWins = value;
+ }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether blood effects are enabled.
+ ///
+ public bool Blood { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the Super Sheep weapon gets upgraded to the Aqua Sheep, which can
+ /// fly underwater.
+ ///
+ public bool AquaSheep { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether sheeps will jump out of exploding crates.
+ ///
+ public bool SheepHeaven { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether worms have infinity energy, killable only by drowning them.
+ ///
+ public bool GodWorms { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether terrain cannot be destroyed by explosions.
+ ///
+ public bool IndestructibleLand { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the Grenade weapon is more powerful.
+ ///
+ public bool UpgradedGrenade { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the Shotgun weapon shoots twice for each of the two shots.
+ ///
+ public bool UpgradedShotgun { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether cluster weapon explode into more clusters.
+ ///
+ public bool UpgradedCluster { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the Longbow weapon is more powerful.
+ ///
+ public bool UpgradedLongbow { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether team weapons will be given to the teams, overriding the default
+ /// weapon settings for them.
+ ///
+ public bool EnableTeamWeapons { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether super weapons can be collected from crates.
+ ///
+ public bool EnableSuperWeapons { get; set; }
+
+ ///
+ /// Gets the array of instances, each mapping to one weapon at the index of the
+ /// enumeration. Depending on the scheme , super weapons might not
+ /// be stored in this array.
+ ///
+ public SchemeWeaponSetting[] Weapons { get; set; }
+
+ // ---- RubberWorm Settings ----
+
+ ///
+ /// Gets or sets a value whether power is unlocked like in TestStuff. Configurable with the /alp command.
+ ///
+ public bool RwAntiLockPower { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether worms falling into water will be reset to the last solid location
+ /// they stood on. Configurable with the /antisink command.
+ ///
+ public bool RwAntiSink { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the aim direction of a weapon will be reset at turn start.
+ /// Configurable with the /reaim command.
+ ///
+ public bool RwAutoReaim { get; set; }
+
+ ///
+ /// Gets or sets a value whether the aim of a weapon loops in full rather than half circles. Configurable with
+ /// the /cira command.
+ ///
+ public bool RwCircularAim { get; set; }
+
+ ///
+ /// Gets or sets the maximum number of crates existing on the map at the same time. 0 disables this feature,
+ /// default limit is 5. Configurable with the /cratelimit command.
+ ///
+ public byte RwCrateLimit { get; set; }
+
+ ///
+ /// Gets or sets the maximum number of crates spawning per turn and enables the crate counter. Configurable with
+ /// the /craterate command.
+ ///
+ public byte RwCrateRate { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether crate shower is enabled throughout a turn. Configurable with the
+ /// /crateshower command.
+ ///
+ public bool RwCrateShower { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether weapon fuses can be selected between 0-9 seconds and herd counts
+ /// between 1-10 animals. Configurable with the /fuseex command.
+ ///
+ public bool RwExtendedFuse { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the turn timer is paused while launching a weapon. Configurable with
+ /// the /fdpt or /nopause commands.
+ ///
+ public bool RwFireDoesntPauseTimer { get; set; }
+
+ ///
+ /// Gets or sets the maximum number of flame particles active at the same time in the scale of 100x.
+ /// Configurable with the /flames command.
+ ///
+ public byte RwFlameLimit { get; set; }
+
+ ///
+ /// Gets or sets the friction deaccelerating objects touching solid ground. 96 is default, 100 is no friction,
+ /// higher values accelerate objects. Configurable with the /friction command.
+ ///
+ public byte RwFriction { get; set; }
+
+ ///
+ /// Gets or sets the amount of gravity. Ranges from -64-63 where 0 and 12 are default gravity and negative
+ /// values pull objects upwards. Configurable with the /gravity command. When set,
+ /// and are reset.
+ ///
+ public sbyte RwGravity
+ {
+ get
+ {
+ return _rwGravity;
+ }
+ set
+ {
+ if (value != 0)
+ {
+ RwGravityConstBlackHole = 0;
+ RwGravityPropBlackHole = 0;
+ }
+ _rwGravity = value;
+ }
+ }
+
+ ///
+ /// gets or sets the amount of gravity acting as a constant black hole. Ranges from -32 to 31. Configurable with
+ /// the /cbh command. When set, and are reset.
+ ///
+ public sbyte RwGravityConstBlackHole
+ {
+ get
+ {
+ return _rwGravityConstBlackHole;
+ }
+ set
+ {
+ if (value != 0)
+ {
+ RwGravity = 0;
+ RwGravityPropBlackHole = 0;
+ }
+ _rwGravityConstBlackHole = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the amount of gravity acting as a proportional black hole. Ranges from -32 to 31. Configurable
+ /// with the /pbh command. When set, and are
+ /// reset.
+ ///
+ public sbyte RwGravityPropBlackHole
+ {
+ get
+ {
+ return _rwGravityPropBlackHole;
+ }
+ set
+ {
+ if (value != 0)
+ {
+ RwGravity = 0;
+ RwGravityConstBlackHole = 0;
+ }
+ _rwGravityPropBlackHole = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the Kaos game scheme mod. 0 for none, 1-5 for the corresponding mod. Configurable with the
+ /// /kaosmod command.
+ ///
+ public byte RwKaosMod
+ {
+ get
+ {
+ return _rwKaosMod;
+ }
+ set
+ {
+ if (value > 0xF)
+ {
+ throw new ArgumentException("Kaos mod must not be greater than 15.");
+ }
+ _rwKaosMod = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the rope knocking power in percent, where 100 is the default power. Configurable with the
+ /// /knock command.
+ ///
+ public byte RwKnockForce { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the loss of control while moving a worm ends does no longer end the
+ /// turn and allows the player to continue moving. Configurable with the /ldet or /stoicworm commands.
+ ///
+ public bool RwLoseControlDoesntEndTurn { get; set; }
+
+ ///
+ /// Gets or sets the maximum speed a player can reach while roping. 16 is default, 32 is like in TestStuff, 255
+ /// is unlimited. Configurable with the /speed command.
+ ///
+ public byte RwMaxRopeSpeed { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether using a weapon does no longer end the turn and allows to shoot
+ /// multiple weapons in one turn. Configurable with the /sdet or /multishot commands.
+ ///
+ public bool RwShotDoesntEndTurn { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the weapons Armageddon, Earthquake and Indian Nuke Test are affected
+ /// by aswell. Configurable with the /usw command.
+ ///
+ public bool RwShotDoesntEndTurnAll { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether all objects are pushed by explosions near them. Configurable with
+ /// the /ope command.
+ ///
+ public bool RwObjectPushByExplosion { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether worms can be selected at any time during the turn, as long as worm
+ /// selection is activated. Configurable with the /swat command.
+ ///
+ public bool RwSelectWormAnytime { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the Ninja Rope is more powerful. Configurable with the /ir or /rope+
+ /// commands.
+ ///
+ public bool RwUpgradedRope { get; set; }
+
+ ///
+ /// Gets or sets the (special) game version to be forced. Configurable with the /version command.
+ /// S. http://worms2d.info/List_of_Worms_Armageddon_logic_versions.
+ ///
+ public ushort RwVersionOverride { get; set; }
+
+ ///
+ /// Gets or sets the amount of air viscosity affecting objects. Odd numbers affect worms too. Configurable with
+ /// the /visc command.
+ ///
+ public byte RwViscosity { get; set; }
+
+ ///
+ /// Gets or sets a value indicating whether the selected weapon no longer resets to a remembered one upon
+ /// shooting it. Configurable with the /wdca command.
+ ///
+ public bool RwWeaponsDontChange { get; set; }
+
+ ///
+ /// Gets or sets the influence power of the wind affecting all weapons. 255 is the same influence as the
+ /// Bazooka. Odd numbers affect worms too. Configurable with the /wind command.
+ ///
+ public byte RwWindPower { get; set; }
+
+ ///
+ /// Gets or sets the power with which worms bounce off terrain, where 0 disables this feature and 255 fully
+ /// bounces worms back without speed loss. Configurable with the /rubber command.
+ ///
+ public byte RwWormBouncyness { get; set; }
+
+ // ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
+
+ ///
+ /// Loads the data from the given .
+ ///
+ /// The to load the data from.
+ public void Load(Stream stream)
+ {
+ using (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII))
+ {
+ // Read the header.
+ int signature = reader.ReadInt32();
+ if (signature != _signature)
+ {
+ throw new InvalidDataException("Invalid WSC file signature.");
+ }
+ Version = reader.ReadEnum(true);
+
+ // Read the options.
+ HotSeatDelay = reader.ReadByte();
+ RetreatTime = reader.ReadByte();
+ RetreatTimeRope = reader.ReadByte();
+ ShowRoundTime = reader.ReadBoolean();
+ AutomaticReplays = reader.ReadBoolean();
+ FallDamage = (SchemeFallDamage)(reader.ReadByte() * 50 % 0x100 * 2);
+ ArtilleryMode = reader.ReadBoolean();
+ SchemeEditor = reader.ReadEnum(false);
+ StockpilingMode = reader.ReadEnum(true);
+ WormSelectMode = reader.ReadEnum(true);
+ SuddenDeathEvent = reader.ReadEnum(true);
+ WaterRiseRate = (SchemeWaterRise)(Math.Pow(reader.ReadByte(), 2) * 5 % 0x100);
+ WeaponCrateProbability = reader.ReadSByte();
+ DonorCards = reader.ReadBoolean();
+ HealthCrateProbability = reader.ReadSByte();
+ HealthCrateEnergy = reader.ReadByte();
+ UtilityCrateProbability = reader.ReadSByte();
+ LoadObjectTypesAndCount(reader);
+ LoadMineDelayConfig(reader);
+ DudMines = reader.ReadBoolean();
+ ManualWormPlacement = reader.ReadBoolean();
+ WormEnergy = reader.ReadByte();
+ LoadTurnTimeConfig(reader);
+ LoadRoundTimeConfig(reader);
+ NumberOfWins = (byte)Math.Max(1, (int)reader.ReadByte());
+ Blood = reader.ReadBoolean();
+ AquaSheep = reader.ReadBoolean();
+ SheepHeaven = reader.ReadBoolean();
+ GodWorms = reader.ReadBoolean();
+ IndestructibleLand = reader.ReadBoolean();
+ UpgradedGrenade = reader.ReadBoolean();
+ UpgradedShotgun = reader.ReadBoolean();
+ UpgradedCluster = reader.ReadBoolean();
+ UpgradedLongbow = reader.ReadBoolean();
+ EnableTeamWeapons = reader.ReadBoolean();
+ EnableSuperWeapons = reader.ReadBoolean();
+
+ // Read the weapon settings. Old versions do not store super weapon settings.
+ Weapons = new SchemeWeaponSetting[64];
+ int weaponCount = GetWeaponCount();
+ for (int i = 0; i < weaponCount; i++)
+ {
+ Weapons[i].Ammunition = reader.ReadSByte();
+ Weapons[i].Power = reader.ReadByte();
+ Weapons[i].Delay = reader.ReadSByte();
+ Weapons[i].Probability = reader.ReadSByte();
+ }
+
+ // Ignore possible unknown WWP trash at the end of the file.
+
+ // Parse the RubberWorm settings.
+ LoadRubberWormSettings();
+ }
+ }
+
+ ///
+ /// Loads the data from the given file.
+ ///
+ /// The name of the file to load the data from.
+ public void Load(string fileName)
+ {
+ using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
+ {
+ Load(stream);
+ }
+ }
+
+ ///
+ /// Saves the data into the given .
+ ///
+ /// The to save the data to.
+ public void Save(Stream stream)
+ {
+ Save(stream, SchemeSaveFormat.ExtendedWithObjectCount);
+ }
+
+ ///
+ /// Saves the data into the given with the specified .
+ ///
+ /// The to save the data to.
+ /// The to respect when storing the settings.
+ public void Save(Stream stream, SchemeSaveFormat format)
+ {
+ using (BinaryDataWriter writer = new BinaryDataWriter(stream, Encoding.ASCII))
+ {
+ // Write the header.
+ writer.Write(_signature);
+ writer.Write((byte)Version);
+
+ // Write the options.
+ writer.Write(HotSeatDelay);
+ writer.Write(RetreatTime);
+ writer.Write(RetreatTimeRope);
+ writer.Write(ShowRoundTime);
+ writer.Write(AutomaticReplays);
+ writer.Write((byte)((int)FallDamage / 4 * 41 % 0x80));
+ writer.Write(ArtilleryMode);
+ writer.Write(SchemeEditor, false);
+ writer.Write(StockpilingMode, true);
+ writer.Write(WormSelectMode, true);
+ writer.Write(SuddenDeathEvent, true);
+ writer.Write(_mapWaterRiseToRaw[(byte)WaterRiseRate]);
+ writer.Write(WeaponCrateProbability);
+ writer.Write(DonorCards);
+ writer.Write(HealthCrateProbability);
+ writer.Write(HealthCrateEnergy);
+ writer.Write(UtilityCrateProbability);
+ SaveObjectTypesAndCount(writer, format);
+ SaveMineDelayConfig(writer);
+ writer.Write(DudMines);
+ writer.Write(ManualWormPlacement);
+ writer.Write(WormEnergy);
+ SaveTurnTimeConfig(writer);
+ SaveRoundTimeConfig(writer);
+ writer.Write(NumberOfWins);
+ writer.Write(Blood);
+ writer.Write(AquaSheep);
+ writer.Write(SheepHeaven);
+ writer.Write(GodWorms);
+ writer.Write(IndestructibleLand);
+ writer.Write(UpgradedGrenade);
+ writer.Write(UpgradedShotgun);
+ writer.Write(UpgradedCluster);
+ writer.Write(UpgradedLongbow);
+ writer.Write(EnableTeamWeapons);
+ writer.Write(EnableSuperWeapons);
+
+ // Transfer the RubberWorm settings to unused weapon configuration.
+ SaveRubberWormSettings();
+
+ // Write the weapon settings. Old versions do not store super weapon settings.
+ int weaponCount = GetWeaponCount();
+ for (int i = 0; i < weaponCount; i++)
+ {
+ writer.Write(Weapons[i].Ammunition);
+ writer.Write(Weapons[i].Power);
+ writer.Write(Weapons[i].Delay);
+ writer.Write(Weapons[i].Probability);
+ }
+
+ // Ignore possible unknown WWP trash at the end of the file.
+ }
+ }
+
+ ///
+ /// Saves the data in the given file.
+ ///
+ /// The name of the file to save the data in.
+ public void Save(string fileName)
+ {
+ Save(fileName, SchemeSaveFormat.ExtendedWithObjectCount);
+ }
+
+ ///
+ /// Saves the data in the given file with the specified .
+ ///
+ /// The name of the file to save the data in.
+ /// The to respect when storing the settings.
+ public void Save(string fileName, SchemeSaveFormat format)
+ {
+ using (FileStream stream = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
+ {
+ Save(stream, format);
+ }
+ }
+
+ // ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
+
+ private void LoadObjectTypesAndCount(BinaryDataReader reader)
+ {
+ // Invalid values default to 8 mines.
+ ObjectTypes = SchemeObjectType.Mines;
+ ObjectCount = SchemeObjectCount.Count8;
+
+ byte raw = reader.ReadByte();
+ if (raw < 12)
+ {
+ // WA before 3.6.28.0 and WWP only store object type.
+ switch (raw)
+ {
+ case 0x00:
+ ObjectTypes = SchemeObjectType.None;
+ break;
+ case 0x02:
+ ObjectTypes = SchemeObjectType.OilDrums;
+ break;
+ case 0x05:
+ ObjectTypes = SchemeObjectType.Mines | SchemeObjectType.OilDrums;
+ break;
+ }
+ }
+ else
+ {
+ // WA since 3.6.28.0 encodes object type and count in one byte.
+ int modulo = raw % 4;
+ switch (modulo)
+ {
+ case 0x00:
+ ObjectTypes = SchemeObjectType.None;
+ break;
+ case 0x02:
+ ObjectTypes = SchemeObjectType.OilDrums;
+ break;
+ case 0x03:
+ ObjectTypes = SchemeObjectType.Mines | SchemeObjectType.OilDrums;
+ break;
+ }
+ ObjectCount = (SchemeObjectCount)_objectCounts[(raw - (8 + modulo)) / 4];
+ }
+ }
+
+ private void LoadMineDelayConfig(BinaryDataReader reader)
+ {
+ byte raw = reader.ReadByte();
+ if (raw == 4 || raw > 0x7F)
+ {
+ MineDelay = 0;
+ MineDelayRandom = true;
+ }
+ else
+ {
+ MineDelay = raw;
+ MineDelayRandom = false;
+ }
+ }
+
+ private void LoadTurnTimeConfig(BinaryDataReader reader)
+ {
+ byte raw = reader.ReadByte();
+ if (raw > 0x7F)
+ {
+ TurnTime = 0;
+ TurnTimeInfinite = true;
+ }
+ else
+ {
+ TurnTime = raw;
+ TurnTimeInfinite = false;
+ }
+ }
+
+ private void LoadRoundTimeConfig(BinaryDataReader reader)
+ {
+ byte raw = reader.ReadByte();
+ if (raw > 0x7F)
+ {
+ RoundTimeMinutes = 0;
+ RoundTimeSeconds = (byte)(raw - 0x7F);
+ }
+ else
+ {
+ RoundTimeMinutes = raw;
+ RoundTimeSeconds = 0;
+ }
+ }
+
+ private void LoadRubberWormSettings()
+ {
+ var earthquakeProb = (RwEarthquakeProb)Weapons[(int)SchemeWeapon.Earthquake].Probability;
+ RwAntiLockPower = earthquakeProb.HasFlag(RwEarthquakeProb.AntiLockPower);
+ RwAutoReaim = earthquakeProb.HasFlag(RwEarthquakeProb.AutoReaim);
+ RwCircularAim = earthquakeProb.HasFlag(RwEarthquakeProb.CircularAim);
+ RwShotDoesntEndTurnAll = earthquakeProb.HasFlag(RwEarthquakeProb.ShotDoesntEndTurnAll);
+ RwKaosMod = ((byte)earthquakeProb).DecodeByte(4, 4);
+
+ RwAntiSink = Weapons[(int)SchemeWeapon.SheepStrike].Probability != 0;
+ RwCrateLimit = (byte)Weapons[(int)SchemeWeapon.MagicBullet].Probability;
+ RwCrateRate = (byte)Weapons[(int)SchemeWeapon.NuclearTest].Probability;
+
+ var moleSquadronProb = (RwMoleSquadronProb)Weapons[(int)SchemeWeapon.MoleSquadron].Probability;
+ RwCrateShower = moleSquadronProb.HasFlag(RwMoleSquadronProb.CrateShower);
+ RwExtendedFuse = moleSquadronProb.HasFlag(RwMoleSquadronProb.ExtendedFuse);
+ RwFireDoesntPauseTimer = moleSquadronProb.HasFlag(RwMoleSquadronProb.FireDoesntPauseTimer);
+ RwLoseControlDoesntEndTurn = moleSquadronProb.HasFlag(RwMoleSquadronProb.LoseControlDoesntEndTurn);
+ RwObjectPushByExplosion = moleSquadronProb.HasFlag(RwMoleSquadronProb.ObjectPushByExplosion);
+ RwShotDoesntEndTurn = moleSquadronProb.HasFlag(RwMoleSquadronProb.ShotDoesntEndTurn);
+ RwUpgradedRope = moleSquadronProb.HasFlag(RwMoleSquadronProb.UpgradedRope);
+ RwWeaponsDontChange = moleSquadronProb.HasFlag(RwMoleSquadronProb.WeaponsDontChange);
+
+ RwFlameLimit = (byte)Weapons[(int)SchemeWeapon.ScalesOfJustice].Probability;
+ RwFriction = (byte)Weapons[(int)SchemeWeapon.SalvationArmy].Probability;
+
+ // 8th and 7th bit control constant / proportional black hole gravity, otherwise normal gravity.
+ var mailStrikeProb = (byte)Weapons[(int)SchemeWeapon.MailStrike].Probability;
+ if (mailStrikeProb.GetBit(7))
+ {
+ if (mailStrikeProb.GetBit(6))
+ {
+ RwGravityPropBlackHole = mailStrikeProb.DecodeSByte(6);
+ }
+ else
+ {
+ RwGravityConstBlackHole = mailStrikeProb.DecodeSByte(6);
+ }
+ }
+ else
+ {
+ RwGravity = mailStrikeProb.DecodeSByte(7);
+ }
+
+ RwKnockForce = (byte)Weapons[(int)SchemeWeapon.SuperBananaBomb].Probability;
+ RwMaxRopeSpeed = (byte)Weapons[(int)SchemeWeapon.MineStrike].Probability;
+ RwSelectWormAnytime = ((byte)Weapons[(int)SchemeWeapon.MBBomb].Probability).GetBit(1);
+
+ byte[] versionBytes = new byte[2];
+ versionBytes[0] = (byte)Weapons[(int)SchemeWeapon.SelectWorm].Probability;
+ versionBytes[1] = (byte)Weapons[(int)SchemeWeapon.Freeze].Probability;
+ RwVersionOverride = BitConverter.ToUInt16(versionBytes, 0);
+
+ RwViscosity = (byte)Weapons[(int)SchemeWeapon.ConcreteDonkey].Probability;
+ RwWindPower = (byte)Weapons[(int)SchemeWeapon.SuicideBomber].Probability;
+ RwWormBouncyness = (byte)Weapons[(int)SchemeWeapon.Armageddon].Probability;
+ }
+
+ private int GetWeaponCount()
+ {
+ // Old versions do not store super weapon settings.
+ return Version == SchemeVersion.Extended ? 64 : 45;
+ }
+
+ private void SaveObjectTypesAndCount(BinaryDataWriter writer, SchemeSaveFormat format)
+ {
+ byte raw = 0;
+ if (format == SchemeSaveFormat.ExtendedWithObjectCount)
+ {
+ // WA since 3.6.28.0 encodes object type and count in one byte.
+ switch (ObjectTypes)
+ {
+ case SchemeObjectType.Mines:
+ raw = 0x01;
+ break;
+ case SchemeObjectType.OilDrums:
+ raw = 0x02;
+ break;
+ case SchemeObjectType.Mines | SchemeObjectType.OilDrums:
+ raw = 0x03;
+ break;
+ }
+ // Get the index of the object count and compute the raw value from that.
+ int index = Array.IndexOf(_objectCounts, (byte)ObjectCount);
+ raw = (byte)(index * 4 + (8 + raw));
+ }
+ else
+ {
+ // WA before 3.6.28.0 and WWP only store object type.
+ switch (ObjectTypes)
+ {
+ case SchemeObjectType.Mines:
+ raw = 0x01;
+ break;
+ case SchemeObjectType.OilDrums:
+ raw = 0x02;
+ break;
+ case SchemeObjectType.Mines | SchemeObjectType.OilDrums:
+ raw = 0x05;
+ break;
+ }
+ }
+ writer.Write(raw);
+ }
+
+ private void SaveMineDelayConfig(BinaryDataWriter writer)
+ {
+ if (MineDelayRandom)
+ {
+ writer.Write((byte)4);
+ }
+ else
+ {
+ writer.Write(MineDelay);
+ }
+ }
+
+ private void SaveTurnTimeConfig(BinaryDataWriter writer)
+ {
+ if (TurnTimeInfinite)
+ {
+ writer.Write((byte)0xFF);
+ }
+ else
+ {
+ writer.Write(TurnTime);
+ }
+ }
+
+ private void SaveRoundTimeConfig(BinaryDataWriter writer)
+ {
+ if (RoundTimeSeconds > 0)
+ {
+ writer.Write((byte)(0xFF - (RoundTimeSeconds - 1)));
+ }
+ else
+ {
+ writer.Write(RoundTimeMinutes);
+ }
+ }
+
+ private void SaveRubberWormSettings()
+ {
+ byte earthquakeProb = 0;
+ if (RwAntiLockPower) earthquakeProb |= (byte)RwEarthquakeProb.AntiLockPower;
+ if (RwAutoReaim) earthquakeProb |= (byte)RwEarthquakeProb.AutoReaim;
+ if (RwCircularAim) earthquakeProb |= (byte)RwEarthquakeProb.CircularAim;
+ if (RwShotDoesntEndTurnAll) earthquakeProb |= (byte)RwEarthquakeProb.ShotDoesntEndTurnAll;
+ earthquakeProb = earthquakeProb.Encode(RwKaosMod, 4);
+ Weapons[(int)SchemeWeapon.Earthquake].Probability = (sbyte)earthquakeProb;
+
+ Weapons[(int)SchemeWeapon.SheepStrike].Probability = (sbyte)(RwAntiSink ? 1 : 0);
+ Weapons[(int)SchemeWeapon.MagicBullet].Probability = (sbyte)RwCrateLimit;
+ Weapons[(int)SchemeWeapon.NuclearTest].Probability = (sbyte)RwCrateRate;
+
+ RwMoleSquadronProb moleSquadronProb = RwMoleSquadronProb.None;
+ if (RwCrateShower) moleSquadronProb |= RwMoleSquadronProb.CrateShower;
+ if (RwExtendedFuse) moleSquadronProb |= RwMoleSquadronProb.ExtendedFuse;
+ if (RwFireDoesntPauseTimer) moleSquadronProb |= RwMoleSquadronProb.FireDoesntPauseTimer;
+ if (RwLoseControlDoesntEndTurn) moleSquadronProb |= RwMoleSquadronProb.LoseControlDoesntEndTurn;
+ if (RwObjectPushByExplosion) moleSquadronProb |= RwMoleSquadronProb.ObjectPushByExplosion;
+ if (RwShotDoesntEndTurn) moleSquadronProb |= RwMoleSquadronProb.ShotDoesntEndTurn;
+ if (RwUpgradedRope) moleSquadronProb |= RwMoleSquadronProb.UpgradedRope;
+ if (RwWeaponsDontChange) moleSquadronProb |= RwMoleSquadronProb.WeaponsDontChange;
+ Weapons[(int)SchemeWeapon.MoleSquadron].Probability = (sbyte)moleSquadronProb;
+
+ Weapons[(int)SchemeWeapon.ScalesOfJustice].Probability = (sbyte)RwFlameLimit;
+ Weapons[(int)SchemeWeapon.SalvationArmy].Probability = (sbyte)RwFriction;
+
+ // 8th and 7th bit control constant / proportional black hole gravity, otherwise normal gravity.
+ byte mailStrikeProb = 0;
+ if (RwGravity != 0)
+ {
+ mailStrikeProb = mailStrikeProb.Encode(RwGravity, 7);
+ }
+ else if (RwGravityConstBlackHole != 0)
+ {
+ mailStrikeProb = mailStrikeProb.EnableBit(7);
+ mailStrikeProb = mailStrikeProb.Encode(RwGravityConstBlackHole, 6);
+ }
+ else if (RwGravityPropBlackHole != 0)
+ {
+ mailStrikeProb = mailStrikeProb.EnableBit(7);
+ mailStrikeProb = mailStrikeProb.EnableBit(6);
+ mailStrikeProb = mailStrikeProb.Encode(RwGravityPropBlackHole, 6);
+ }
+ Weapons[(int)SchemeWeapon.MailStrike].Probability = (sbyte)mailStrikeProb;
+
+ Weapons[(int)SchemeWeapon.SuperBananaBomb].Probability = (sbyte)RwKnockForce;
+ Weapons[(int)SchemeWeapon.MineStrike].Probability = (sbyte)RwMaxRopeSpeed;
+ byte mbBombProb = ((byte)Weapons[(int)SchemeWeapon.MBBomb].Probability).SetBit(0, RwSelectWormAnytime);
+ Weapons[(int)SchemeWeapon.MBBomb].Probability = (sbyte)mbBombProb;
+
+ byte[] versionBytes = BitConverter.GetBytes(RwVersionOverride);
+ Weapons[(int)SchemeWeapon.SelectWorm].Probability = (sbyte)versionBytes[0];
+ Weapons[(int)SchemeWeapon.Freeze].Probability = (sbyte)versionBytes[1];
+
+ Weapons[(int)SchemeWeapon.ConcreteDonkey].Probability = (sbyte)RwViscosity;
+ Weapons[(int)SchemeWeapon.SuicideBomber].Probability = (sbyte)RwWindPower;
+ Weapons[(int)SchemeWeapon.Armageddon].Probability = (sbyte)RwWormBouncyness;
+ }
+
+ // ---- ENUMERATIONS -------------------------------------------------------------------------------------------
+
+ [Flags]
+ private enum RwEarthquakeProb : byte
+ {
+ None = 0,
+ AutoReaim = 1 << 0,
+ CircularAim = 1 << 1,
+ AntiLockPower = 1 << 2,
+ ShotDoesntEndTurnAll = 1 << 3
+ // Remaining bits represent kaosmod version.
+ }
+
+ [Flags]
+ private enum RwMoleSquadronProb : byte
+ {
+ None = 0,
+ ShotDoesntEndTurn = 1 << 0,
+ LoseControlDoesntEndTurn = 1 << 1,
+ FireDoesntPauseTimer = 1 << 2,
+ UpgradedRope = 1 << 3,
+ CrateShower = 1 << 4,
+ ObjectPushByExplosion = 1 << 5,
+ WeaponsDontChange = 1 << 6,
+ ExtendedFuse = 1 << 7
+ }
+ }
+
+ ///
+ /// Represents the configuration of a weapon.
+ ///
+ [DebuggerDisplay("Ammo={Ammunition} Power={Power} Delay={Delay} Prob={Probability}")]
+ public struct SchemeWeaponSetting
+ {
+ ///
+ /// The amount of this weapon with which a team is equipped at game start. 10 and negative values represent
+ /// infinity.
+ ///
+ public sbyte Ammunition;
+
+ ///
+ /// The power of this weapon.
+ ///
+ public byte Power;
+
+ ///
+ /// The number of turns required to be taken by each team before this weapon becomes available. Negative values
+ /// represenet infinity.
+ ///
+ public sbyte Delay;
+
+ ///
+ /// The percentual chance of this weapon to appear in crates. Has no effect for super weapons.
+ ///
+ public sbyte Probability;
+ }
+
+ #region Enumerations
+
+ ///
+ /// Represents the known versions of scheme file formats.
+ ///
+ public enum SchemeVersion : byte
+ {
+ ///
+ /// The standard format used by WA before version 3.6.28.0 and WWP. It does not store super weapon settings.
+ ///
+ Standard = 1,
+
+ ///
+ /// The extended format used by WA since version 3.6.28.0.
+ ///
+ Extended = 2
+ }
+
+ ///
+ /// Represents the possible variations of the options stored in a scheme file.
+ ///
+ public enum SchemeSaveFormat
+ {
+ ///
+ /// Represents the format.
+ ///
+ Standard,
+
+ ///
+ /// Represents the format, and does not store object counts.
+ ///
+ Extended,
+
+ ///
+ /// Represents the format, and stores object counts (supported since WA
+ /// 3.6.28.0).
+ ///
+ ExtendedWithObjectCount
+ }
+
+ ///
+ /// Represents the fall damage in percent, relative to the normal fall damage being 100%.
+ ///
+ public enum SchemeFallDamage
+ {
+ ///
+ /// No fall damage.
+ ///
+ None = 0,
+
+ ///
+ /// 4% fall damage.
+ ///
+ Percent4 = 4,
+
+ ///
+ /// 8% fall damage.
+ ///
+ Percent8 = 8,
+
+ ///
+ /// 12% fall damage.
+ ///
+ Percent12 = 12,
+
+ ///
+ /// 16% fall damage.
+ ///
+ Percent16 = 16,
+
+ ///
+ /// 20% fall damage.
+ ///
+ Percent20 = 20,
+
+ ///
+ /// 24% fall damage.
+ ///
+ Percent24 = 24,
+
+ ///
+ /// 28% fall damage.
+ ///
+ Percent28 = 28,
+
+ ///
+ /// 32% fall damage.
+ ///
+ Percent32 = 32,
+
+ ///
+ /// 36% fall damage.
+ ///
+ Percent36 = 36,
+
+ ///
+ /// 40% fall damage.
+ ///
+ Percent40 = 40,
+
+ ///
+ /// 44% fall damage.
+ ///
+ Percent44 = 44,
+
+ ///
+ /// 48% fall damage.
+ ///
+ Percent48 = 48,
+
+ ///
+ /// 52% fall damage.
+ ///
+ Percent52 = 52,
+
+ ///
+ /// 56% fall damage.
+ ///
+ Percent56 = 56,
+
+ ///
+ /// 60% fall damage.
+ ///
+ Percent60 = 60,
+
+ ///
+ /// 64% fall damage.
+ ///
+ Percent64 = 64,
+
+ ///
+ /// 68% fall damage.
+ ///
+ Percent68 = 68,
+
+ ///
+ /// 72% fall damage.
+ ///
+ Percent72 = 72,
+
+ ///
+ /// 76% fall damage.
+ ///
+ Percent76 = 76,
+
+ ///
+ /// 80% fall damage.
+ ///
+ Percent80 = 80,
+
+ ///
+ /// 84% fall damage.
+ ///
+ Percent84 = 84,
+
+ ///
+ /// 88% fall damage.
+ ///
+ Percent88 = 88,
+
+ ///
+ /// 92% fall damage.
+ ///
+ Percent92 = 92,
+
+ ///
+ /// 96% fall damage.
+ ///
+ Percent96 = 96,
+
+ ///
+ /// 100% fall damage.
+ ///
+ Percent100 = 100,
+
+ ///
+ /// 104% fall damage.
+ ///
+ Percent104 = 104,
+
+ ///
+ /// 108% fall damage.
+ ///
+ Percent108 = 108,
+
+ ///
+ /// 112% fall damage.
+ ///
+ Percent112 = 112,
+
+ ///
+ /// 116% fall damage.
+ ///
+ Percent116 = 116,
+
+ ///
+ /// 120% fall damage.
+ ///
+ Percent120 = 120,
+
+ ///
+ /// 124% fall damage.
+ ///
+ Percent124 = 124,
+
+ ///
+ /// 128% fall damage.
+ ///
+ Percent128 = 128,
+
+ ///
+ /// 132% fall damage.
+ ///
+ Percent132 = 132,
+
+ ///
+ /// 136% fall damage.
+ ///
+ Percent136 = 136,
+
+ ///
+ /// 140% fall damage.
+ ///
+ Percent140 = 140,
+
+ ///
+ /// 144% fall damage.
+ ///
+ Percent144 = 144,
+
+ ///
+ /// 148% fall damage.
+ ///
+ Percent148 = 148,
+
+ ///
+ /// 152% fall damage.
+ ///
+ Percent152 = 152,
+
+ ///
+ /// 156% fall damage.
+ ///
+ Percent156 = 156,
+
+ ///
+ /// 160% fall damage.
+ ///
+ Percent160 = 160,
+
+ ///
+ /// 164% fall damage.
+ ///
+ Percent164 = 164,
+
+ ///
+ /// 168% fall damage.
+ ///
+ Percent168 = 168,
+
+ ///
+ /// 172% fall damage.
+ ///
+ Percent172 = 172,
+
+ ///
+ /// 176% fall damage.
+ ///
+ Percent176 = 176,
+
+ ///
+ /// 180% fall damage.
+ ///
+ Percent180 = 180,
+
+ ///
+ /// 184% fall damage.
+ ///
+ Percent184 = 184,
+
+ ///
+ /// 188% fall damage.
+ ///
+ Percent188 = 188,
+
+ ///
+ /// 192% fall damage.
+ ///
+ Percent192 = 192,
+
+ ///
+ /// 196% fall damage.
+ ///
+ Percent196 = 196,
+
+ ///
+ /// 200% fall damage.
+ ///
+ Percent200 = 200,
+
+ ///
+ /// 204% fall damage.
+ ///
+ Percent204 = 204,
+
+ ///
+ /// 208% fall damage.
+ ///
+ Percent208 = 208,
+
+ ///
+ /// 212% fall damage.
+ ///
+ Percent212 = 212,
+
+ ///
+ /// 216% fall damage.
+ ///
+ Percent216 = 216,
+
+ ///
+ /// 220% fall damage.
+ ///
+ Percent220 = 220,
+
+ ///
+ /// 224% fall damage.
+ ///
+ Percent224 = 224,
+
+ ///
+ /// 228% fall damage.
+ ///
+ Percent228 = 228,
+
+ ///
+ /// 232% fall damage.
+ ///
+ Percent232 = 232,
+
+ ///
+ /// 236% fall damage.
+ ///
+ Percent236 = 236,
+
+ ///
+ /// 240% fall damage.
+ ///
+ Percent240 = 240,
+
+ ///
+ /// 244% fall damage.
+ ///
+ Percent244 = 244,
+
+ ///
+ /// 248% fall damage.
+ ///
+ Percent248 = 248,
+
+ ///
+ /// 252% fall damage.
+ ///
+ Percent252 = 252,
+
+ ///
+ /// 256% fall damage.
+ ///
+ Percent256 = 256,
+
+ ///
+ /// 260% fall damage.
+ ///
+ Percent260 = 260,
+
+ ///
+ /// 264% fall damage.
+ ///
+ Percent264 = 264,
+
+ ///
+ /// 268% fall damage.
+ ///
+ Percent268 = 268,
+
+ ///
+ /// 272% fall damage.
+ ///
+ Percent272 = 272,
+
+ ///
+ /// 276% fall damage.
+ ///
+ Percent276 = 276,
+
+ ///
+ /// 280% fall damage.
+ ///
+ Percent280 = 280,
+
+ ///
+ /// 284% fall damage.
+ ///
+ Percent284 = 284,
+
+ ///
+ /// 288% fall damage.
+ ///
+ Percent288 = 288,
+
+ ///
+ /// 292% fall damage.
+ ///
+ Percent292 = 292,
+
+ ///
+ /// 296% fall damage.
+ ///
+ Percent296 = 296,
+
+ ///
+ /// 300% fall damage.
+ ///
+ Percent300 = 300,
+
+ ///
+ /// 304% fall damage.
+ ///
+ Percent304 = 304,
+
+ ///
+ /// 308% fall damage.
+ ///
+ Percent308 = 308,
+
+ ///
+ /// 312% fall damage.
+ ///
+ Percent312 = 312,
+
+ ///
+ /// 316% fall damage.
+ ///
+ Percent316 = 316,
+
+ ///
+ /// 320% fall damage.
+ ///
+ Percent320 = 320,
+
+ ///
+ /// 324% fall damage.
+ ///
+ Percent324 = 324,
+
+ ///
+ /// 328% fall damage.
+ ///
+ Percent328 = 328,
+
+ ///
+ /// 332% fall damage.
+ ///
+ Percent332 = 332,
+
+ ///
+ /// 336% fall damage.
+ ///
+ Percent336 = 336,
+
+ ///
+ /// 340% fall damage.
+ ///
+ Percent340 = 340,
+
+ ///
+ /// 344% fall damage.
+ ///
+ Percent344 = 344,
+
+ ///
+ /// 348% fall damage.
+ ///
+ Percent348 = 348,
+
+ ///
+ /// 352% fall damage.
+ ///
+ Percent352 = 352,
+
+ ///
+ /// 356% fall damage.
+ ///
+ Percent356 = 356,
+
+ ///
+ /// 360% fall damage.
+ ///
+ Percent360 = 360,
+
+ ///
+ /// 364% fall damage.
+ ///
+ Percent364 = 364,
+
+ ///
+ /// 368% fall damage.
+ ///
+ Percent368 = 368,
+
+ ///
+ /// 372% fall damage.
+ ///
+ Percent372 = 372,
+
+ ///
+ /// 376% fall damage.
+ ///
+ Percent376 = 376,
+
+ ///
+ /// 380% fall damage.
+ ///
+ Percent380 = 380,
+
+ ///
+ /// 384% fall damage.
+ ///
+ Percent384 = 384,
+
+ ///
+ /// 388% fall damage.
+ ///
+ Percent388 = 388,
+
+ ///
+ /// 392% fall damage.
+ ///
+ Percent392 = 392,
+
+ ///
+ /// 396% fall damage.
+ ///
+ Percent396 = 396,
+
+ ///
+ /// 400% fall damage.
+ ///
+ Percent400 = 400,
+
+ ///
+ /// 404% fall damage.
+ ///
+ Percent404 = 404,
+
+ ///
+ /// 408% fall damage.
+ ///
+ Percent408 = 408,
+
+ ///
+ /// 412% fall damage.
+ ///
+ Percent412 = 412,
+
+ ///
+ /// 416% fall damage.
+ ///
+ Percent416 = 416,
+
+ ///
+ /// 420% fall damage.
+ ///
+ Percent420 = 420,
+
+ ///
+ /// 424% fall damage.
+ ///
+ Percent424 = 424,
+
+ ///
+ /// 428% fall damage.
+ ///
+ Percent428 = 428,
+
+ ///
+ /// 432% fall damage.
+ ///
+ Percent432 = 432,
+
+ ///
+ /// 436% fall damage.
+ ///
+ Percent436 = 436,
+
+ ///
+ /// 440% fall damage.
+ ///
+ Percent440 = 440,
+
+ ///
+ /// 444% fall damage.
+ ///
+ Percent444 = 444,
+
+ ///
+ /// 448% fall damage.
+ ///
+ Percent448 = 448,
+
+ ///
+ /// 452% fall damage.
+ ///
+ Percent452 = 452,
+
+ ///
+ /// 456% fall damage.
+ ///
+ Percent456 = 456,
+
+ ///
+ /// 460% fall damage.
+ ///
+ Percent460 = 460,
+
+ ///
+ /// 464% fall damage.
+ ///
+ Percent464 = 464,
+
+ ///
+ /// 468% fall damage.
+ ///
+ Percent468 = 468,
+
+ ///
+ /// 472% fall damage.
+ ///
+ Percent472 = 472,
+
+ ///
+ /// 476% fall damage.
+ ///
+ Percent476 = 476,
+
+ ///
+ /// 480% fall damage.
+ ///
+ Percent480 = 480,
+
+ ///
+ /// 484% fall damage.
+ ///
+ Percent484 = 484,
+
+ ///
+ /// 488% fall damage.
+ ///
+ Percent488 = 488,
+
+ ///
+ /// 492% fall damage.
+ ///
+ Percent492 = 492,
+
+ ///
+ /// 496% fall damage.
+ ///
+ Percent496 = 496,
+
+ ///
+ /// 500% fall damage.
+ ///
+ Percent500 = 500,
+
+ ///
+ /// 504% fall damage.
+ ///
+ Percent504 = 504,
+
+ ///
+ /// 508% fall damage.
+ ///
+ Percent508 = 508
+ }
+
+ ///
+ /// Represents the known identifiers of scheme editors stored in schemes modified by them.
+ ///
+ public enum SchemeEditor : byte
+ {
+ None = 0,
+ LeTotalKiller = 0x5F,
+ SchemeEddy = 0x89
+ }
+
+ ///
+ /// Represents the stockpiling mode of weapon armory between rounds.
+ ///
+ public enum SchemeStockpiling : byte
+ {
+ Off = 0,
+ On = 1,
+ Anti = 2
+ }
+
+ ///
+ /// Represents the method to determine the next turn's worm.
+ ///
+ public enum SchemeWormSelect : byte
+ {
+ Ordered = 0,
+ Manual = 1,
+ Random = 2
+ }
+
+ ///
+ /// Represents the event triggered when the round timer runs out.
+ ///
+ public enum SchemeSuddenDeathEvent : byte
+ {
+ RoundEnd = 0,
+ NuclearStrike = 1,
+ HealthDrop = 2
+ }
+
+ ///
+ /// Represents the water rise in pixels after sudden death was triggered.
+ ///
+ public enum SchemeWaterRise : byte
+ {
+ ///
+ /// No water rise.
+ ///
+ None = 0,
+
+ ///
+ /// 5 pixels water rise.
+ ///
+ Pixels5 = 5,
+
+ ///
+ /// 13 pixels water rise.
+ ///
+ Pixels13 = 13,
+
+ ///
+ /// 20 pixels water rise.
+ ///
+ Pixels20 = 20,
+
+ ///
+ /// 21 pixels water rise.
+ ///
+ Pixels21 = 21,
+
+ ///
+ /// 29 pixels water rise.
+ ///
+ Pixels29 = 29,
+
+ ///
+ /// 37 pixels water rise.
+ ///
+ Pixels37 = 37,
+
+ ///
+ /// 45 pixels water rise.
+ ///
+ Pixels45 = 45,
+
+ ///
+ /// 52 pixels water rise.
+ ///
+ Pixels52 = 52,
+
+ ///
+ /// 53 pixels water rise.
+ ///
+ Pixels53 = 53,
+
+ ///
+ /// 61 pixels water rise.
+ ///
+ Pixels61 = 61,
+
+ ///
+ /// 64 pixels water rise.
+ ///
+ Pixels64 = 64,
+
+ ///
+ /// 69 pixels water rise.
+ ///
+ Pixels69 = 69,
+
+ ///
+ /// 77 pixels water rise.
+ ///
+ Pixels77 = 77,
+
+ ///
+ /// 80 pixels water rise.
+ ///
+ Pixels80 = 80,
+
+ ///
+ /// 84 pixels water rise.
+ ///
+ Pixels84 = 84,
+
+ ///
+ /// 85 pixels water rise.
+ ///
+ Pixels85 = 85,
+
+ ///
+ /// 93 pixels water rise.
+ ///
+ Pixels93 = 93,
+
+ ///
+ /// 101 pixels water rise.
+ ///
+ Pixels101 = 101,
+
+ ///
+ /// 109 pixels water rise.
+ ///
+ Pixels109 = 109,
+
+ ///
+ /// 116 pixels water rise.
+ ///
+ Pixels116 = 116,
+
+ ///
+ /// 117 pixels water rise.
+ ///
+ Pixels117 = 117,
+
+ ///
+ /// 125 pixels water rise.
+ ///
+ Pixels125 = 125,
+
+ ///
+ /// 133 pixels water rise.
+ ///
+ Pixels133 = 133,
+
+ ///
+ /// 141 pixels water rise.
+ ///
+ Pixels141 = 141,
+
+ ///
+ /// 148 pixels water rise.
+ ///
+ Pixels148 = 148,
+
+ ///
+ /// 149 pixels water rise.
+ ///
+ Pixels149 = 149,
+
+ ///
+ /// 157 pixels water rise.
+ ///
+ Pixels157 = 157,
+
+ ///
+ /// 165 pixels water rise.
+ ///
+ Pixels165 = 165,
+
+ ///
+ /// 173 pixels water rise.
+ ///
+ Pixels173 = 173,
+
+ ///
+ /// 180 pixels water rise.
+ ///
+ Pixels180 = 180,
+
+ ///
+ /// 181 pixels water rise.
+ ///
+ Pixels181 = 181,
+
+ ///
+ /// 189 pixels water rise.
+ ///
+ Pixels189 = 189,
+
+ ///
+ /// 197 pixels water rise.
+ ///
+ Pixels197 = 197,
+
+ ///
+ /// 205 pixels water rise.
+ ///
+ Pixels205 = 205,
+
+ ///
+ /// 208 pixels water rise.
+ ///
+ Pixels208 = 208,
+
+ ///
+ /// 212 pixels water rise.
+ ///
+ Pixels212 = 212,
+
+ ///
+ /// 213 pixels water rise.
+ ///
+ Pixels213 = 213,
+
+ ///
+ /// 221 pixels water rise.
+ ///
+ Pixels221 = 221,
+
+ ///
+ /// 229 pixels water rise.
+ ///
+ Pixels229 = 229,
+
+ ///
+ /// 237 pixels water rise.
+ ///
+ Pixels237 = 237,
+
+ ///
+ /// 244 pixels water rise.
+ ///
+ Pixels244 = 244,
+
+ ///
+ /// 245 pixels water rise.
+ ///
+ Pixels245 = 245,
+
+ ///
+ /// 253 pixels water rise.
+ ///
+ Pixels253 = 253
+ }
+
+ ///
+ /// Represents the types of objects which can appear on the map.
+ ///
+ [Flags]
+ public enum SchemeObjectType
+ {
+ None = 0,
+ Mines = 1 << 0,
+ OilDrums = 1 << 1
+ }
+
+ ///
+ /// Represents the possible maximum number of objects which can appear on the map.
+ ///
+ public enum SchemeObjectCount
+ {
+ ///
+ /// No objects.
+ ///
+ None = 0,
+
+ ///
+ /// Up to 1 object.
+ ///
+ Count1 = 1,
+
+ ///
+ /// Up to 2 objects.
+ ///
+ Count2 = 2,
+
+ ///
+ /// Up to 3 objects.
+ ///
+ Count3 = 3,
+
+ ///
+ /// Up to 4 objects.
+ ///
+ Count4 = 4,
+
+ ///
+ /// Up to 5 objects.
+ ///
+ Count5 = 5,
+
+ ///
+ /// Up to 6 objects.
+ ///
+ Count6 = 6,
+
+ ///
+ /// Up to 7 objects.
+ ///
+ Count7 = 7,
+
+ ///
+ /// Up to 8 objects.
+ ///
+ Count8 = 8,
+
+ ///
+ /// Up to 9 objects.
+ ///
+ Count9 = 9,
+
+ ///
+ /// Up to 10 objects.
+ ///
+ Count10 = 10,
+
+ ///
+ /// Up to 11 objects.
+ ///
+ Count11 = 11,
+
+ ///
+ /// Up to 12 objects.
+ ///
+ Count12 = 12,
+
+ ///
+ /// Up to 13 objects.
+ ///
+ Count13 = 13,
+
+ ///
+ /// Up to 14 objects.
+ ///
+ Count14 = 14,
+
+ ///
+ /// Up to 15 objects.
+ ///
+ Count15 = 15,
+
+ ///
+ /// Up to 16 objects.
+ ///
+ Count16 = 16,
+
+ ///
+ /// Up to 17 objects.
+ ///
+ Count17 = 17,
+
+ ///
+ /// Up to 18 objects.
+ ///
+ Count18 = 18,
+
+ ///
+ /// Up to 19 objects.
+ ///
+ Count19 = 19,
+
+ ///
+ /// Up to 20 objects.
+ ///
+ Count20 = 20,
+
+ ///
+ /// Up to 21 objects.
+ ///
+ Count21 = 21,
+
+ ///
+ /// Up to 22 objects.
+ ///
+ Count22 = 22,
+
+ ///
+ /// Up to 23 objects.
+ ///
+ Count23 = 23,
+
+ ///
+ /// Up to 24 objects.
+ ///
+ Count24 = 24,
+
+ ///
+ /// Up to 25 objects.
+ ///
+ Count25 = 25,
+
+ ///
+ /// Up to 26 objects.
+ ///
+ Count26 = 26,
+
+ ///
+ /// Up to 27 objects.
+ ///
+ Count27 = 27,
+
+ ///
+ /// Up to 28 objects.
+ ///
+ Count28 = 28,
+
+ ///
+ /// Up to 29 objects.
+ ///
+ Count29 = 29,
+
+ ///
+ /// Up to 30 objects.
+ ///
+ Count30 = 30,
+
+ ///
+ /// Up to 35 objects.
+ ///
+ Count35 = 35,
+
+ ///
+ /// Up to 40 objects.
+ ///
+ Count40 = 40,
+
+ ///
+ /// Up to 45 objects.
+ ///
+ Count45 = 45,
+
+ ///
+ /// Up to 50 objects.
+ ///
+ Count50 = 50,
+
+ ///
+ /// Up to 55 objects.
+ ///
+ Count55 = 55,
+
+ ///
+ /// Up to 60 objects.
+ ///
+ Count60 = 60,
+
+ ///
+ /// Up to 65 objects.
+ ///
+ Count65 = 65,
+
+ ///
+ /// Up to 70 objects.
+ ///
+ Count70 = 70,
+
+ ///
+ /// Up to 75 objects.
+ ///
+ Count75 = 75,
+
+ ///
+ /// Up to 80 objects.
+ ///
+ Count80 = 80,
+
+ ///
+ /// Up to 85 objects.
+ ///
+ Count85 = 85,
+
+ ///
+ /// Up to 90 objects.
+ ///
+ Count90 = 90,
+
+ ///
+ /// Up to 95 objects.
+ ///
+ Count95 = 95,
+
+ ///
+ /// Up to 100 objects.
+ ///
+ Count100 = 100,
+
+ ///
+ /// Up to 110 objects.
+ ///
+ Count110 = 110,
+
+ ///
+ /// Up to 120 objects.
+ ///
+ Count120 = 120,
+
+ ///
+ /// Up to 130 objects.
+ ///
+ Count130 = 130,
+
+ ///
+ /// Up to 140 objects.
+ ///
+ Count140 = 140,
+
+ ///
+ /// Up to 150 objects.
+ ///
+ Count150 = 150,
+
+ ///
+ /// Up to 160 objects.
+ ///
+ Count160 = 160,
+
+ ///
+ /// Up to 170 objects.
+ ///
+ Count170 = 170,
+
+ ///
+ /// Up to 180 objects.
+ ///
+ Count180 = 180,
+
+ ///
+ /// Up to 190 objects.
+ ///
+ Count190 = 190,
+
+ ///
+ /// Up to 200 objects.
+ ///
+ Count200 = 200,
+
+ ///
+ /// Up to 210 objects.
+ ///
+ Count210 = 210,
+
+ ///
+ /// Up to 220 objects.
+ ///
+ Count220 = 220,
+
+ ///
+ /// Up to 230 objects.
+ ///
+ Count230 = 230,
+
+ ///
+ /// Up to 240 objects.
+ ///
+ Count240 = 240,
+
+ ///
+ /// Up to 250 objects.
+ ///
+ Count250 = 250
+ }
+
+ ///
+ /// Represents the weapons in the game.
+ ///
+ public enum SchemeWeapon
+ {
+ ///
+ /// The Bazooka weapon.
+ ///
+ Bazooka,
+
+ ///
+ /// The Homing Missile weapon.
+ ///
+ HomingMissile,
+
+ ///
+ /// The Mortar weapon.
+ ///
+ Mortar,
+
+ ///
+ /// The Grenade weapon.
+ ///
+ Grenade,
+
+ ///
+ /// The Cluster Bomb weapon.
+ ///
+ ClusterBomb,
+
+ ///
+ /// The Skunk weapon.
+ ///
+ Skunk,
+
+ ///
+ /// The Petrol Bomb weapon.
+ ///
+ PetrolBomb,
+
+ ///
+ /// The Banana Bomb weapon.
+ ///
+ BananaBomb,
+
+ ///
+ /// The Handgun weapon.
+ ///
+ Handgun,
+
+ ///
+ /// The Shotgun weapon.
+ ///
+ Shotgun,
+
+ ///
+ /// The Uzi weapon.
+ ///
+ Uzi,
+
+ ///
+ /// The Minigun weapon.
+ ///
+ Minigun,
+
+ ///
+ /// The Longbow weapon.
+ ///
+ Longbow,
+
+ ///
+ /// The Airstrike weapon.
+ ///
+ Airstrike,
+
+ ///
+ /// The Napalm Strike weapon.
+ ///
+ NapalmStrike,
+
+ ///
+ /// The Mine weapon.
+ ///
+ Mine,
+
+ ///
+ /// The Fire Punch weapon.
+ ///
+ FirePunch,
+
+ ///
+ /// The Dragon Ball weapon.
+ ///
+ DragonBall,
+
+ ///
+ /// The Kamikaze weapon.
+ ///
+ Kamikaze,
+
+ ///
+ /// The Prod weapon.
+ ///
+ Prod,
+
+ ///
+ /// The Battle Axe weapon.
+ ///
+ BattleAxe,
+
+ ///
+ /// The Blowtorch weapon.
+ ///
+ Blowtorch,
+
+ ///
+ /// The Pneumatic Drill weapon.
+ ///
+ PneumaticDrill,
+
+ ///
+ /// The Girder weapon.
+ ///
+ Girder,
+
+ ///
+ /// The Ninja Rope weapon.
+ ///
+ NinjaRope,
+
+ ///
+ /// The Parachute weapon.
+ ///
+ Parachute,
+
+ ///
+ /// The Bungee weapon.
+ ///
+ Bungee,
+
+ ///
+ /// The Teleport weapon.
+ ///
+ Teleport,
+
+ ///
+ /// The Dynamite weapon.
+ ///
+ Dynamite,
+
+ ///
+ /// The Sheep weapon.
+ ///
+ Sheep,
+
+ ///
+ /// The Baseball Bat weapon.
+ ///
+ BaseballBat,
+
+ ///
+ /// The Flame Thrower weapon.
+ ///
+ FlameThrower,
+
+ ///
+ /// The Homing Pigeon weapon.
+ ///
+ HomingPigeon,
+
+ ///
+ /// The Mad Cow weapon.
+ ///
+ MadCow,
+
+ ///
+ /// The Holy Hand Grenade weapon.
+ ///
+ HolyHandGrenade,
+
+ ///
+ /// The Old Woman weapon.
+ ///
+ OldWoman,
+
+ ///
+ /// The Sheep Launcher weapon.
+ ///
+ SheepLauncher,
+
+ ///
+ /// The Super Sheep or Aqua Sheep weapon.
+ ///
+ SuperSheep,
+
+ ///
+ /// The Mole Bomb weapon.
+ ///
+ MoleBomb,
+
+ ///
+ /// The Jet Pack utility.
+ ///
+ JetPack,
+
+ ///
+ /// The Low Gravity utility.
+ ///
+ LowGravity,
+
+ ///
+ /// The Laser Sight utility.
+ ///
+ LaserSight,
+
+ ///
+ /// The Fast Walk utility.
+ ///
+ FastWalk,
+
+ ///
+ /// The Invisibility utility.
+ ///
+ Invisibility,
+
+ ///
+ /// The Damage x2 utility.
+ ///
+ DamageX2,
+
+ ///
+ /// The Freeze super weapon.
+ ///
+ Freeze,
+
+ ///
+ /// The Super Banana Bomb super weapon.
+ ///
+ SuperBananaBomb,
+
+ ///
+ /// The Mine Strike super weapon.
+ ///
+ MineStrike,
+
+ ///
+ /// The Girder Starter Pack super weapon.
+ ///
+ GirderStarterPack,
+
+ ///
+ /// The Earthquake super weapon.
+ ///
+ Earthquake,
+
+ ///
+ /// The Scales Of Justice super weapon.
+ ///
+ ScalesOfJustice,
+
+ ///
+ /// The Ming Vase super weapon.
+ ///
+ MingVase,
+
+ ///
+ /// The Mike's Carpet Bomb super weapon.
+ ///
+ MikesCarpetBomb,
+
+ ///
+ /// The Patsy's Magic Bullet super weapon.
+ ///
+ MagicBullet,
+
+ ///
+ /// The Indian Nuclear Test super weapon.
+ ///
+ NuclearTest,
+
+ ///
+ /// The Select Worm super weapon.
+ ///
+ SelectWorm,
+
+ ///
+ /// The Salvation Army super weapon.
+ ///
+ SalvationArmy,
+
+ ///
+ /// The Mole Squadron super weapon.
+ ///
+ MoleSquadron,
+
+ ///
+ /// The MB Bomb super weapon.
+ ///
+ MBBomb,
+
+ ///
+ /// The Concrete Donkey super weapon.
+ ///
+ ConcreteDonkey,
+
+ ///
+ /// The Suicide Bomber super weapon.
+ ///
+ SuicideBomber,
+
+ ///
+ /// The Sheep Strike super weapon.
+ ///
+ SheepStrike,
+
+ ///
+ /// The Mail Strike super weapon.
+ ///
+ MailStrike,
+
+ ///
+ /// The Armageddon super weapon.
+ ///
+ Armageddon
+ }
+
+ #endregion
+}
diff --git a/src/Syroot.Worms/Syroot.Worms.csproj b/src/Syroot.Worms/Syroot.Worms.csproj
index 8d2376b..90a2080 100644
--- a/src/Syroot.Worms/Syroot.Worms.csproj
+++ b/src/Syroot.Worms/Syroot.Worms.csproj
@@ -2,7 +2,7 @@
.NET library to load and modify file formats of Team17 Worms games.
- MIT
+ (c) Syroot, licensed under MIT
Syroot.Worms
Worms
Syroot
@@ -17,19 +17,25 @@
git
https://github.com/Syroot/Worms
- netstandard1.6
- true
+ net45;netstandard1.6
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ portable
+
+
+
+ none
+ true
+
+
\ No newline at end of file