Prepare support for W:A 3.8 V3 schemes.

- Add all new V3 extended options. These will be moved to their own struct soon.
- Renames several existing properties and enums to be more concise.
- Convert RubberWorm probabilities to V3 values.
- Add test testing against a dump of all schemes uploaded to WSDB as of this commit.
This commit is contained in:
Ray Koopa 2020-06-28 19:06:40 +02:00
parent 10008eaf6e
commit 13583a6971
8 changed files with 1561 additions and 683 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
src/test/Syroot.Worms.Armageddon.Test/Files/Schemes/WA/Wsdb/dump.csv filter=lfs diff=lfs merge=lfs -text

File diff suppressed because it is too large Load Diff

View File

@ -2,28 +2,73 @@ using System;
namespace Syroot.Worms.Armageddon
{
/// <summary>
/// Represents which worms are cured from being poisoned if a worm collects a health crate.
/// </summary>
public enum HealthCure : byte
{
/// <summary>Cures only the worm collecting the health crate.</summary>
Single,
/// <summary>Cures the team of the worm collecting the health crate.</summary>
Team,
/// <summary>Cures all allied teams of the worm collecting the health crate.</summary>
Allies,
/// <summary>Cures nobody.</summary>
Nobody = 255
}
/// <summary>
/// Represents the possible cavern roof extension directions.
/// </summary>
public enum Roofing : byte
{
/// <summary>Does not extend the roof.</summary>
Default,
/// <summary>Extends the roof infinitely upwards.</summary>
Up,
/// <summary>Extends the roof infinitely up- and sidewards.</summary>
UpSide
}
/// <summary>
/// Gets or sets a value determining which kinds of weapons can be dropped while rolling during roping.
/// </summary>
public enum RopeRollDrops : byte
{
/// <summary>No weapons can be dropped while rolling.</summary>
None,
/// <summary>Weapons which are droppable from a rope can be dropped while rolling.</summary>
Rope,
/// <summary>Weapons which are droppable from a rope or while jumping can be dropped while rolling.</summary>
RopeJump
}
/// <summary>
/// Represents the known versions of scheme file formats.
/// </summary>
public enum SchemeVersion : byte
{
/// <summary>Default format used by WA before version 3.6.28.0 and WWP.</summary>
Standard = 1,
/// <summary>Extended format used by WA since version 3.6.28.0, storing super weapon settings.</summary>
Extended = 2
/// <summary>WA 3.0 and WWP, original format.</summary>
Version1 = 1,
/// <summary>WA 3.5 and newer, storing super weapons.</summary>
Version2 = 2,
/// <summary>WA 3.7.3 and newer, storing new options.</summary>
Version3 = 3
}
/// <summary>
/// Represents the possible variations of the options stored in a scheme file.
/// Represents the gravity simulation used in a game (as originating from RubberWorm).
/// </summary>
public enum SchemeSaveFormat
public enum RwGravityType : byte
{
/// <summary>Represents <see cref="SchemeVersion.Standard"/>.</summary>
Standard,
/// <summary>Represents <see cref="SchemeVersion.Extended"/>.</summary>
Extended,
/// <summary>Represents <see cref="SchemeVersion.Extended"/> and stores object counts since WA 3.6.28.0.</summary>
ExtendedWithObjectCount
/// <summary>No RubberWorm gravity logic is used.</summary>
None,
/// <summary>Default gravity, but affecting more objects.</summary>
Default,
/// <summary>Gravity is calculated as a constant force black hole.</summary>
BlackHoleConstant,
/// <summary>Gravity is calculated as a linear force / proportional black hole.</summary>
BlackHoleLinear
}
/// <summary>
@ -31,7 +76,7 @@ namespace Syroot.Worms.Armageddon
/// </summary>
public enum SchemeEditor : byte
{
/// <summary>Default (Worms Armageddon internal editor or those that do not set a recognition byte.</summary>
/// <summary>Default (game editor or those that do not set a recognition byte).</summary>
None,
/// <summary>LeTotalKiller's PHP online editor.</summary>
LeTotalKiller = 0x5F,
@ -39,10 +84,52 @@ namespace Syroot.Worms.Armageddon
SchemeEddy = 0x89
}
/// <summary>
/// Represents the effects an enabled <see cref="Scheme.SheepHeaven"/> has on the game.
/// </summary>
[Flags]
public enum SheepHeavenFlags : byte
{
/// <summary>Crates always eject a sheep when exploding.</summary>
Explode = 1 << 0,
/// <summary>Extended fuse timer on sheep weapons.</summary>
Fuse = 1 << 1,
/// <summary>Crates have higher probability to contain sheep weapons.</summary>
Odds = 1 << 2,
/// <summary>Enabled all of the sheep heaven effects.</summary>
All = Explode | Fuse | Odds
}
/// <summary>
/// Represents the possible loss of control when skimming on water.
/// </summary>
public enum SkimControlLoss : byte
{
/// <summary>Control is lost when skimming.</summary>
Lose,
/// <summary>Control is retained but the rope cannot be shot again until landing.</summary>
Keep,
/// <summary>Control is retained and the rope can be shot even before landing.</summary>
KeepWithRope
}
/// <summary>
/// Represents the possible methods of triggering skip walking to speed up the walking speed.
/// </summary>
public enum SkipWalk : byte
{
/// <summary>Skip walking is possible by right clicking during the turn.</summary>
Default,
/// <summary>Skip walking is possible by using the up and down arrow keys.</summary>
Facilitated,
/// <summary>Skip walking is prevented.</summary>
Disabled = 255
}
/// <summary>
/// Represents the stockpiling mode of weapon armory between rounds.
/// </summary>
public enum SchemeStockpiling : byte
public enum StockpilingMode : byte
{
/// <summary>Each round starts with the exact amount of weapons set in the scheme.</summary>
Off,
@ -55,7 +142,7 @@ namespace Syroot.Worms.Armageddon
/// <summary>
/// Represents the method to determine the next turn's worm.
/// </summary>
public enum SchemeWormSelect : byte
public enum WormSelect : byte
{
/// <summary>Worms are selected in the order in which they appear in the team.</summary>
Sequential,
@ -68,7 +155,7 @@ namespace Syroot.Worms.Armageddon
/// <summary>
/// Represents the event triggered when the round timer runs out.
/// </summary>
public enum SchemeSuddenDeathEvent : byte
public enum SuddenDeathEvent : byte
{
/// <summary>The round ends and is drawn.</summary>
RoundEnd,
@ -84,7 +171,7 @@ namespace Syroot.Worms.Armageddon
/// Represents the types of objects which can appear on the map.
/// </summary>
[Flags]
public enum SchemeObjectType
public enum MapObjectType
{
/// <summary>Neither mines or oil drums are placed on the map.</summary>
None,
@ -97,137 +184,17 @@ namespace Syroot.Worms.Armageddon
}
/// <summary>
/// Represents the weapons in the game.
/// Represents the objects or effects worms phase through.
/// </summary>
public enum SchemeWeaponName
public enum WormPhasing : byte
{
/// <summary>The Bazooka weapon.</summary>
Bazooka,
/// <summary>The Homing Missile weapon.</summary>
HomingMissile,
/// <summary>The Mortar weapon.</summary>
Mortar,
/// <summary>The Grenade weapon.</summary>
Grenade,
/// <summary>The Cluster Bomb weapon.</summary>
ClusterBomb,
/// <summary>The Skunk weapon.</summary>
Skunk,
/// <summary>The Petrol Bomb weapon.</summary>
PetrolBomb,
/// <summary>The Banana Bomb weapon.</summary>
BananaBomb,
/// <summary>The Handgun weapon.</summary>
Handgun,
/// <summary>The Shotgun weapon.</summary>
Shotgun,
/// <summary>The Uzi weapon.</summary>
Uzi,
/// <summary>The Minigun weapon.</summary>
Minigun,
/// <summary>The Longbow weapon.</summary>
Longbow,
/// <summary>The Airstrike weapon.</summary>
Airstrike,
/// <summary>The Napalm Strike weapon.</summary>
NapalmStrike,
/// <summary>The Mine weapon.</summary>
Mine,
/// <summary>The Firepunch weapon.</summary>
Firepunch,
/// <summary>The Dragonball weapon.</summary>
Dragonball,
/// <summary>The Kamikaze weapon.</summary>
Kamikaze,
/// <summary>The Prod weapon.</summary>
Prod,
/// <summary>The Battle Axe weapon.</summary>
BattleAxe,
/// <summary>The Blowtorch weapon.</summary>
Blowtorch,
/// <summary>The Pneumatic Drill weapon.</summary>
PneumaticDrill,
/// <summary>The Girder weapon.</summary>
Girder,
/// <summary>The Ninja Rope weapon.</summary>
NinjaRope,
/// <summary>The Parachute weapon.</summary>
Parachute,
/// <summary>The Bungee weapon.</summary>
Bungee,
/// <summary>The Teleport weapon.</summary>
Teleport,
/// <summary>The Dynamite weapon.</summary>
Dynamite,
/// <summary>The Sheep weapon.</summary>
Sheep,
/// <summary>The Baseball Bat weapon.</summary>
BaseballBat,
/// <summary>The Flame Thrower weapon.</summary>
Flamethrower,
/// <summary>The Homing Pigeon weapon.</summary>
HomingPigeon,
/// <summary>The Mad Cow weapon.</summary>
MadCow,
/// <summary>The Holy Hand Grenade weapon.</summary>
HolyHandGrenade,
/// <summary>The Old Woman weapon.</summary>
OldWoman,
/// <summary>The Sheep Launcher weapon.</summary>
SheepLauncher,
/// <summary>The Super Sheep or Aqua Sheep weapon.</summary>
SuperSheep,
/// <summary>The Mole Bomb weapon.</summary>
MoleBomb,
/// <summary>The Jetpack utility.</summary>
Jetpack,
/// <summary>The Low Gravity utility.</summary>
LowGravity,
/// <summary>The Laser Sight utility.</summary>
LaserSight,
/// <summary>The Fast Walk utility.</summary>
FastWalk,
/// <summary>The Invisibility utility.</summary>
Invisibility,
/// <summary>The Damage x2 utility.</summary>
DamageX2,
/// <summary>The Freeze super weapon.</summary>
Freeze,
/// <summary>The Super Banana Bomb super weapon.</summary>
SuperBananaBomb,
/// <summary>The Mine Strike super weapon.</summary>
MineStrike,
/// <summary>The Girder Starter Pack super weapon.</summary>
GirderStarterPack,
/// <summary>The Earthquake super weapon.</summary>
Earthquake,
/// <summary>The Scales Of Justice super weapon.</summary>
ScalesOfJustice,
/// <summary>The Ming Vase super weapon.</summary>
MingVase,
/// <summary>The Mike's Carpet Bomb super weapon.</summary>
MikesCarpetBomb,
/// <summary>The Patsy's Magic Bullet super weapon.</summary>
MagicBullet,
/// <summary>The Indian Nuclear Test super weapon.</summary>
NuclearTest,
/// <summary>The Select Worm super weapon.</summary>
SelectWorm,
/// <summary>The Salvation Army super weapon.</summary>
SalvationArmy,
/// <summary>The Mole Squadron super weapon.</summary>
MoleSquadron,
/// <summary>The MB Bomb super weapon.</summary>
MBBomb,
/// <summary>The Concrete Donkey super weapon.</summary>
ConcreteDonkey,
/// <summary>The Suicide Bomber super weapon.</summary>
SuicideBomber,
/// <summary>The Sheep Strike super weapon.</summary>
SheepStrike,
/// <summary>The Mail Strike super weapon.</summary>
MailStrike,
/// <summary>The Armageddon super weapon.</summary>
Armageddon
/// <summary>Worms are affected as usual.</summary>
None,
/// <summary>Worms are not affected by other worms.</summary>
Worms,
/// <summary>Worms are not affected by other worms and weapons.</summary>
WormsWeapons,
/// <summary>Worms are not affected by other worms, weapons, and damage.</summary>
WormsWeaponsDamage
}
}

View File

@ -5,23 +5,23 @@ using System.Runtime.InteropServices;
namespace Syroot.Worms.Armageddon
{
/// <summary>
/// Represents the configuration of a weapon.
/// Represents the configuration of a weapon in a <see cref="Scheme"/>.
/// </summary>
[DebuggerDisplay("Ammo={Ammunition} Power={Power} Delay={Delay} Prob={Probability}")]
[DebuggerDisplay("Ammo={Ammo} Power={Power} Delay={Delay} Crates={Crates}")]
[StructLayout(LayoutKind.Sequential)]
public struct SchemeWeapon : IEquatable<SchemeWeapon>
{
// ---- FIELDS -------------------------------------------------------------------------------------------------
/// <summary>Amount with which a team is equipped at game start. 10 and negative values represent infinity.</summary>
public sbyte Ammunition;
/// <summary>Power of this weapon.</summary>
public sbyte Ammo;
/// <summary>Intensity of this weapon.</summary>
public byte Power;
/// <summary>Number of turns required to be taken by each team before this weapon becomes available. Negative
/// values represent infinity.</summary>
public sbyte Delay;
/// <summary>Percentual chance of this weapon to appear in crates. Has no effect for super weapons.</summary>
public sbyte Probability;
/// <summary>Probability of this weapon to appear in crates. Has no effect on super weapons.</summary>
public sbyte Crates;
// ---- OPERATORS ----------------------------------------------------------------------------------------------
@ -36,12 +36,12 @@ namespace Syroot.Worms.Armageddon
/// <inheritdoc/>
public bool Equals(SchemeWeapon other)
=> Ammunition == other.Ammunition
=> Ammo == other.Ammo
&& Power == other.Power
&& Delay == other.Delay
&& Probability == other.Probability;
&& Crates == other.Crates;
/// <inheritdoc/>
public override int GetHashCode() => HashCode.Combine(Ammunition, Power, Delay, Probability);
public override int GetHashCode() => HashCode.Combine(Ammo, Power, Delay, Crates);
}
}

View File

@ -5,7 +5,7 @@
<Description>.NET library for loading and modifying files of Team17's Worms Armageddon.</Description>
<PackageReleaseNotes>Fix issues when loading and saving some formats. Simplify Scheme usage.</PackageReleaseNotes>
<PackageTags>$(PackageTags);worms armageddon</PackageTags>
<Version>3.2.0</Version>
<Version>3.3.0-beta001</Version>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Syroot.Worms\Syroot.Worms.csproj" />

View File

@ -0,0 +1,152 @@
namespace Syroot.Worms.Armageddon
{
/// <summary>
/// Represents the weapons in the game.
/// </summary>
public enum Weapon
{
/// <summary>The Bazooka weapon.</summary>
Bazooka,
/// <summary>The Homing Missile weapon.</summary>
HomingMissile,
/// <summary>The Mortar weapon.</summary>
Mortar,
/// <summary>The Grenade weapon.</summary>
Grenade,
/// <summary>The Cluster Bomb weapon.</summary>
ClusterBomb,
/// <summary>The Skunk weapon.</summary>
Skunk,
/// <summary>The Petrol Bomb weapon.</summary>
PetrolBomb,
/// <summary>The Banana Bomb weapon.</summary>
BananaBomb,
/// <summary>The Handgun weapon.</summary>
Handgun,
/// <summary>The Shotgun weapon.</summary>
Shotgun,
/// <summary>The Uzi weapon.</summary>
Uzi,
/// <summary>The Minigun weapon.</summary>
Minigun,
/// <summary>The Longbow weapon.</summary>
Longbow,
/// <summary>The Airstrike weapon.</summary>
Airstrike,
/// <summary>The Napalm Strike weapon.</summary>
NapalmStrike,
/// <summary>The Mine weapon.</summary>
Mine,
/// <summary>The Firepunch weapon.</summary>
Firepunch,
/// <summary>The Dragonball weapon.</summary>
Dragonball,
/// <summary>The Kamikaze weapon.</summary>
Kamikaze,
/// <summary>The Prod weapon.</summary>
Prod,
/// <summary>The Battle Axe weapon.</summary>
BattleAxe,
/// <summary>The Blowtorch weapon.</summary>
Blowtorch,
/// <summary>The Pneumatic Drill weapon.</summary>
PneumaticDrill,
/// <summary>The Girder weapon.</summary>
Girder,
/// <summary>The Ninja Rope weapon.</summary>
NinjaRope,
/// <summary>The Parachute weapon.</summary>
Parachute,
/// <summary>The Bungee weapon.</summary>
Bungee,
/// <summary>The Teleport weapon.</summary>
Teleport,
/// <summary>The Dynamite weapon.</summary>
Dynamite,
/// <summary>The Sheep weapon.</summary>
Sheep,
/// <summary>The Baseball Bat weapon.</summary>
BaseballBat,
/// <summary>The Flame Thrower weapon.</summary>
Flamethrower,
/// <summary>The Homing Pigeon weapon.</summary>
HomingPigeon,
/// <summary>The Mad Cow weapon.</summary>
MadCow,
/// <summary>The Holy Hand Grenade weapon.</summary>
HolyHandGrenade,
/// <summary>The Old Woman weapon.</summary>
OldWoman,
/// <summary>The Sheep Launcher weapon.</summary>
SheepLauncher,
/// <summary>The Super Sheep or Aqua Sheep weapon.</summary>
SuperSheep,
/// <summary>The Mole Bomb weapon.</summary>
MoleBomb,
/// <summary>The Jetpack utility.</summary>
Jetpack,
/// <summary>The Low Gravity utility.</summary>
LowGravity,
/// <summary>The Laser Sight utility.</summary>
LaserSight,
/// <summary>The Fast Walk utility.</summary>
FastWalk,
/// <summary>The Invisibility utility.</summary>
Invisibility,
/// <summary>The Damage x2 utility.</summary>
DamageX2,
/// <summary>The Freeze super weapon.</summary>
Freeze,
/// <summary>The Super Banana Bomb super weapon.</summary>
SuperBananaBomb,
/// <summary>The Mine Strike super weapon.</summary>
MineStrike,
/// <summary>The Girder Starter Pack super weapon.</summary>
GirderStarterPack,
/// <summary>The Earthquake super weapon.</summary>
Earthquake,
/// <summary>The Scales Of Justice super weapon.</summary>
ScalesOfJustice,
/// <summary>The Ming Vase super weapon.</summary>
MingVase,
/// <summary>The Mike's Carpet Bomb super weapon.</summary>
MikesCarpetBomb,
/// <summary>The Patsy's Magic Bullet super weapon.</summary>
MagicBullet,
/// <summary>The Indian Nuclear Test super weapon.</summary>
NuclearTest,
/// <summary>The Select Worm super weapon.</summary>
SelectWorm,
/// <summary>The Salvation Army super weapon.</summary>
SalvationArmy,
/// <summary>The Mole Squadron super weapon.</summary>
MoleSquadron,
/// <summary>The MB Bomb super weapon.</summary>
MBBomb,
/// <summary>The Concrete Donkey super weapon.</summary>
ConcreteDonkey,
/// <summary>The Suicide Bomber super weapon.</summary>
SuicideBomber,
/// <summary>The Sheep Strike super weapon.</summary>
SheepStrike,
/// <summary>The Mail Strike super weapon.</summary>
MailStrike,
/// <summary>The Armageddon super weapon.</summary>
Armageddon
}
/// <summary>
/// Represents utility methods for <see cref="Weapon"/> instances.
/// </summary>
public static class WeaponTools
{
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
/// <summary>
/// Returns a value indicating whether the <paramref name="weapon"/> is handled as a super weapon.
/// </summary>
/// <param name="weapon">The <see cref="Weapon"/> to check for being a super weapon.</param>
/// <returns>Whether the weapon is a super weapon.</returns>
public static bool IsSuperWeapon(this Weapon weapon) => weapon >= Weapon.Freeze;
}
}

Binary file not shown.
1 version https://git-lfs.github.com/spec/v1
2 oid sha256:b353a827e69dbbc3ccc3eb8ca8bf815894a4546d6d29c66ec28c842b7df43b94
3 size 6663628

View File

@ -1,4 +1,7 @@
using System;
using System.Buffers.Binary;
using System.Globalization;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Syroot.Worms.Armageddon;
using Syroot.Worms.Test.Core;
@ -14,10 +17,37 @@ namespace Syroot.Worms.Test.Armageddon
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
/// <summary>
/// Loads all files found in the test directory.
/// Tests all files found in the test directory.
/// </summary>
[TestMethod]
public void TestFiles() => FileTester.Run<Scheme>(Game.Test, "*.wsc");
public void TestFiles() => Tools.TestFiles<Scheme>(Game.Test, "*.wsc");
/// <summary>
/// Tests all schemes from a Worms Scheme Database CSV dump (ask owner Byte for updated dumps).
/// </summary>
[TestMethod]
public void TestWsdb()
{
// Reuse buffer for all schemes, including the SCHM header stripped in the dump.
byte[] buffer = new byte[407];
BinaryPrimitives.WriteInt32LittleEndian(buffer, 0x4D484353);
using StreamReader csv = new StreamReader(@"Files\Schemes\WA\WSDB\dump.csv");
while (!csv.EndOfStream)
{
string[] cells = csv.ReadLine().Split(',');
int id = Int32.Parse(cells[0]);
DateTime uploadTime = DateTime.Parse(cells[1], CultureInfo.InvariantCulture);
string data = cells[2];
int length = (data.Length - @"\x".Length) / 2;
for (int i = 0; i < length; i++)
buffer[i + 4] = Convert.ToByte(data.Substring(i * 2 + 2, 2), 16);
using MemoryStream stream = new MemoryStream(buffer, 0, length, false);
Tools.TestStream<Scheme>($"WSDB {id} / {uploadTime:yyyy-MM-dd HH:mm}", stream);
}
}
/// <summary>
/// Tests rounding down to the nearest valid fall damage value.