mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-01-13 07:18:00 +03:00
Rewrite logic of parsing Scheme object count and type.
Mirrors frontend logic more closely now without the need for static lookup arrays.
This commit is contained in:
parent
57815e9072
commit
26a9125f0a
@ -19,6 +19,10 @@ namespace Syroot.Worms.Armageddon
|
||||
|
||||
private const string _signature = "SCHM";
|
||||
|
||||
private const int _objectCount5Step = 30;
|
||||
private const int _objectCount10Step = 44;
|
||||
private const int _objectCountLastStep = 59;
|
||||
|
||||
// Lookup tables.
|
||||
private static readonly Dictionary<byte, byte> _mapWaterRiseToRaw = new Dictionary<byte, byte>()
|
||||
{
|
||||
@ -67,12 +71,10 @@ namespace Syroot.Worms.Armageddon
|
||||
[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 };
|
||||
|
||||
// ---- MEMBERS ------------------------------------------------------------------------------------------------
|
||||
|
||||
private byte _objectCount;
|
||||
private byte _mineDelay;
|
||||
private byte _turnTime;
|
||||
private byte _roundTimeMinutes;
|
||||
@ -214,9 +216,24 @@ namespace Syroot.Worms.Armageddon
|
||||
public SchemeObjectType ObjectTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the maximum number of objects (mines or oil drums) on the map.
|
||||
/// Gets or sets the maximum number of objects (mines or oil drums) on the map. Note that setting this value
|
||||
/// rounds it valid count.
|
||||
/// </summary>
|
||||
public SchemeObjectCount ObjectCount { get; set; }
|
||||
public byte ObjectCount
|
||||
{
|
||||
get => _objectCount;
|
||||
set
|
||||
{
|
||||
if (value > 100)
|
||||
_objectCount = (byte)(value - value % 10);
|
||||
else if (value > 30)
|
||||
_objectCount = (byte)(value - value % 5);
|
||||
else if (value == 0)
|
||||
_objectCount = 1;
|
||||
else
|
||||
_objectCount = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the number of seconds a mine requires to explode. Can be 1-3 and 5-127 seconds.
|
||||
@ -685,7 +702,7 @@ namespace Syroot.Worms.Armageddon
|
||||
/// <param name="format">The <see cref="SchemeSaveFormat"/> to respect when storing the settings.</param>
|
||||
public void Save(Stream stream, SchemeSaveFormat format)
|
||||
{
|
||||
using BinaryStream writer = new BinaryStream(stream, encoding: Encoding.ASCII);
|
||||
using BinaryStream writer = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true);
|
||||
|
||||
// Write the header.
|
||||
writer.Write(_signature, StringCoding.Raw);
|
||||
@ -759,45 +776,25 @@ namespace Syroot.Worms.Armageddon
|
||||
|
||||
private void LoadObjectTypesAndCount(BinaryStream reader)
|
||||
{
|
||||
// Invalid values default to 8 mines.
|
||||
ObjectTypes = SchemeObjectType.Mines;
|
||||
ObjectCount = SchemeObjectCount.Count8;
|
||||
|
||||
byte raw = reader.Read1Byte();
|
||||
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];
|
||||
case 3: case 4: raw = 1; break;
|
||||
case 6: case 7: raw = 0; break;
|
||||
}
|
||||
|
||||
// Determine object count.
|
||||
int step = Math.Min(raw < 8 ? 8 : raw / 4 - 2, _objectCountLastStep);
|
||||
if (step >= _objectCount10Step)
|
||||
step = 100 + 10 * (step - _objectCount10Step);
|
||||
else if (step >= _objectCount5Step)
|
||||
step = 30 + 5 * (step - _objectCount5Step);
|
||||
ObjectCount = (byte)step;
|
||||
|
||||
// Determine object types.
|
||||
ObjectTypes = raw == 5 // old "both" value
|
||||
? SchemeObjectType.Both
|
||||
: (SchemeObjectType)(raw & (byte)SchemeObjectType.Both);
|
||||
}
|
||||
|
||||
private void LoadMineDelayConfig(BinaryStream reader)
|
||||
@ -874,17 +871,12 @@ namespace Syroot.Worms.Armageddon
|
||||
|
||||
// 8th and 7th bit control constant / proportional black hole gravity, otherwise normal gravity.
|
||||
byte mailStrikeProb = (byte)Weapons[(int)SchemeWeapon.MailStrike].Probability;
|
||||
if (mailStrikeProb.GetBit(7))
|
||||
{
|
||||
if (mailStrikeProb.GetBit(6))
|
||||
if (!mailStrikeProb.GetBit(7))
|
||||
RwGravity = mailStrikeProb.DecodeSByte(7);
|
||||
else 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;
|
||||
@ -908,41 +900,23 @@ namespace Syroot.Worms.Armageddon
|
||||
|
||||
private void SaveObjectTypesAndCount(BinaryStream writer, SchemeSaveFormat format)
|
||||
{
|
||||
byte raw = 0;
|
||||
if (format == SchemeSaveFormat.ExtendedWithObjectCount)
|
||||
byte raw;
|
||||
if (format == SchemeSaveFormat.ExtendedWithObjectCount && ObjectCount != 8)
|
||||
{
|
||||
// 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);
|
||||
raw = (byte)ObjectTypes;
|
||||
|
||||
int step = ObjectCount;
|
||||
if (ObjectCount >= 100)
|
||||
step = _objectCount10Step + (ObjectCount - 100) / 10;
|
||||
else if (ObjectCount >= 30)
|
||||
step = _objectCount5Step + (ObjectCount - 30) / 5;
|
||||
raw |= (byte)(4 * step + 8);
|
||||
}
|
||||
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;
|
||||
}
|
||||
raw = ObjectTypes == SchemeObjectType.Both ? (byte)5 : (byte)ObjectTypes;
|
||||
}
|
||||
writer.Write(raw);
|
||||
}
|
||||
|
@ -985,315 +985,10 @@ namespace Syroot.Worms.Armageddon
|
||||
[Flags]
|
||||
public enum SchemeObjectType
|
||||
{
|
||||
None = 0,
|
||||
None,
|
||||
Mines = 1 << 0,
|
||||
OilDrums = 1 << 1
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the possible maximum number of objects which can appear on the map.
|
||||
/// </summary>
|
||||
public enum SchemeObjectCount
|
||||
{
|
||||
/// <summary>
|
||||
/// No objects.
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 1 object.
|
||||
/// </summary>
|
||||
Count1 = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 2 objects.
|
||||
/// </summary>
|
||||
Count2 = 2,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 3 objects.
|
||||
/// </summary>
|
||||
Count3 = 3,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 4 objects.
|
||||
/// </summary>
|
||||
Count4 = 4,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 5 objects.
|
||||
/// </summary>
|
||||
Count5 = 5,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 6 objects.
|
||||
/// </summary>
|
||||
Count6 = 6,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 7 objects.
|
||||
/// </summary>
|
||||
Count7 = 7,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 8 objects.
|
||||
/// </summary>
|
||||
Count8 = 8,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 9 objects.
|
||||
/// </summary>
|
||||
Count9 = 9,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 10 objects.
|
||||
/// </summary>
|
||||
Count10 = 10,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 11 objects.
|
||||
/// </summary>
|
||||
Count11 = 11,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 12 objects.
|
||||
/// </summary>
|
||||
Count12 = 12,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 13 objects.
|
||||
/// </summary>
|
||||
Count13 = 13,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 14 objects.
|
||||
/// </summary>
|
||||
Count14 = 14,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 15 objects.
|
||||
/// </summary>
|
||||
Count15 = 15,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 16 objects.
|
||||
/// </summary>
|
||||
Count16 = 16,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 17 objects.
|
||||
/// </summary>
|
||||
Count17 = 17,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 18 objects.
|
||||
/// </summary>
|
||||
Count18 = 18,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 19 objects.
|
||||
/// </summary>
|
||||
Count19 = 19,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 20 objects.
|
||||
/// </summary>
|
||||
Count20 = 20,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 21 objects.
|
||||
/// </summary>
|
||||
Count21 = 21,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 22 objects.
|
||||
/// </summary>
|
||||
Count22 = 22,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 23 objects.
|
||||
/// </summary>
|
||||
Count23 = 23,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 24 objects.
|
||||
/// </summary>
|
||||
Count24 = 24,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 25 objects.
|
||||
/// </summary>
|
||||
Count25 = 25,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 26 objects.
|
||||
/// </summary>
|
||||
Count26 = 26,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 27 objects.
|
||||
/// </summary>
|
||||
Count27 = 27,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 28 objects.
|
||||
/// </summary>
|
||||
Count28 = 28,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 29 objects.
|
||||
/// </summary>
|
||||
Count29 = 29,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 30 objects.
|
||||
/// </summary>
|
||||
Count30 = 30,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 35 objects.
|
||||
/// </summary>
|
||||
Count35 = 35,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 40 objects.
|
||||
/// </summary>
|
||||
Count40 = 40,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 45 objects.
|
||||
/// </summary>
|
||||
Count45 = 45,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 50 objects.
|
||||
/// </summary>
|
||||
Count50 = 50,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 55 objects.
|
||||
/// </summary>
|
||||
Count55 = 55,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 60 objects.
|
||||
/// </summary>
|
||||
Count60 = 60,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 65 objects.
|
||||
/// </summary>
|
||||
Count65 = 65,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 70 objects.
|
||||
/// </summary>
|
||||
Count70 = 70,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 75 objects.
|
||||
/// </summary>
|
||||
Count75 = 75,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 80 objects.
|
||||
/// </summary>
|
||||
Count80 = 80,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 85 objects.
|
||||
/// </summary>
|
||||
Count85 = 85,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 90 objects.
|
||||
/// </summary>
|
||||
Count90 = 90,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 95 objects.
|
||||
/// </summary>
|
||||
Count95 = 95,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 100 objects.
|
||||
/// </summary>
|
||||
Count100 = 100,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 110 objects.
|
||||
/// </summary>
|
||||
Count110 = 110,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 120 objects.
|
||||
/// </summary>
|
||||
Count120 = 120,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 130 objects.
|
||||
/// </summary>
|
||||
Count130 = 130,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 140 objects.
|
||||
/// </summary>
|
||||
Count140 = 140,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 150 objects.
|
||||
/// </summary>
|
||||
Count150 = 150,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 160 objects.
|
||||
/// </summary>
|
||||
Count160 = 160,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 170 objects.
|
||||
/// </summary>
|
||||
Count170 = 170,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 180 objects.
|
||||
/// </summary>
|
||||
Count180 = 180,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 190 objects.
|
||||
/// </summary>
|
||||
Count190 = 190,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 200 objects.
|
||||
/// </summary>
|
||||
Count200 = 200,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 210 objects.
|
||||
/// </summary>
|
||||
Count210 = 210,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 220 objects.
|
||||
/// </summary>
|
||||
Count220 = 220,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 230 objects.
|
||||
/// </summary>
|
||||
Count230 = 230,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 240 objects.
|
||||
/// </summary>
|
||||
Count240 = 240,
|
||||
|
||||
/// <summary>
|
||||
/// Up to 250 objects.
|
||||
/// </summary>
|
||||
Count250 = 250
|
||||
OilDrums = 1 << 1,
|
||||
Both = Mines | OilDrums
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using Syroot.Worms.Armageddon;
|
||||
using Syroot.Worms.Mgame;
|
||||
|
||||
namespace Syroot.Worms.Scratchpad
|
||||
@ -9,8 +11,30 @@ namespace Syroot.Worms.Scratchpad
|
||||
{
|
||||
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
||||
|
||||
private static void Main(string[] args)
|
||||
private static void Main()
|
||||
{
|
||||
IEnumerable<string> fileNames = Directory.EnumerateFiles(
|
||||
@"C:\Games\Worms Armageddon 3.7.2.1\User\Schemes", "*.wsc", SearchOption.AllDirectories);
|
||||
|
||||
foreach (string fileName in fileNames)
|
||||
{
|
||||
string tempFile = Path.GetTempFileName();
|
||||
using (Stream tempStream = new FileStream(tempFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None))
|
||||
{
|
||||
// Load the scheme and save it to temp file.
|
||||
Scheme origScheme = new Scheme(fileName);
|
||||
tempStream.Position = 0;
|
||||
origScheme.Save(tempStream);
|
||||
|
||||
// Load the temp file.
|
||||
tempStream.Position = 0;
|
||||
Scheme newScheme = new Scheme(tempStream);
|
||||
|
||||
if (origScheme.ObjectCount != newScheme.ObjectCount || origScheme.ObjectTypes != newScheme.ObjectTypes)
|
||||
throw new InvalidOperationException("mismatch");
|
||||
}
|
||||
File.Delete(tempFile);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ConvertIgdImages()
|
||||
@ -21,7 +45,6 @@ namespace Syroot.Worms.Scratchpad
|
||||
|
||||
foreach (string igdFilePath in Directory.GetFiles(igdFolder, "*.igd", SearchOption.AllDirectories))
|
||||
{
|
||||
|
||||
// Load the IGD and let it convert the images.
|
||||
Igd igd = new Igd(igdFilePath);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user