mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-04-12 12:20:05 +03:00
464 lines
18 KiB
C#
464 lines
18 KiB
C#
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Text;
|
|
using Syroot.BinaryData;
|
|
using Syroot.Worms.Core;
|
|
|
|
namespace Syroot.Worms.Gen2.Armageddon.ProjectX
|
|
{
|
|
[DebuggerDisplay("Weapon Name={Name}")]
|
|
public class Weapon : ILoadable, ISaveable
|
|
{
|
|
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
|
|
|
public WeaponVersion Version { get; set; }
|
|
|
|
public long Checksum { get; set; }
|
|
|
|
public int TableRow { get; set; }
|
|
|
|
public bool Remembered { get; set; }
|
|
|
|
public bool UsableInCavern { get; set; }
|
|
|
|
public int Shots { get; set; }
|
|
|
|
public bool ShotEndsTurn { get; set; }
|
|
|
|
public int RetreatTime { get; set; }
|
|
|
|
public int Unknown1 { get; set; }
|
|
|
|
public int CrateChance { get; set; }
|
|
|
|
public int CrateCount { get; set; }
|
|
|
|
public int Unknown2 { get; set; }
|
|
|
|
public WeaponActivation Activation { get; set; }
|
|
|
|
public int NotUsed { get; set; }
|
|
|
|
public int ThrowHerdCount { get; set; }
|
|
|
|
public int AirstrikeSubtype { get; set; }
|
|
|
|
public WeaponSpacebarAction SpacebarAction { get; set; }
|
|
|
|
public WeaponCrosshairAction CrosshairAction { get; set; }
|
|
|
|
public WeaponThrowAction ThrowAction { get; set; }
|
|
|
|
public IStyle Style { get; set; }
|
|
|
|
public bool AmmunitionOverride { get; set; }
|
|
|
|
public int Ammunition { get; set; }
|
|
|
|
public int Unknown3 { get; set; }
|
|
|
|
public int WeaponSprite { get; set; }
|
|
|
|
public string NameLong { get; set; }
|
|
|
|
public string Name { get; set; }
|
|
|
|
public string GridImageFile { get; set; }
|
|
|
|
public string GfxDirectoryFile { get; set; }
|
|
|
|
public string[] SpriteNames { get; set; }
|
|
|
|
public bool DelayOverride { get; set; }
|
|
|
|
public int Delay { get; set; }
|
|
|
|
public bool UseLibrary { get; set; }
|
|
|
|
public string LibraryName { get; set; }
|
|
|
|
public string LibraryWeaponName { get; set; }
|
|
|
|
public string AimSpriteEven { get; set; }
|
|
|
|
public string AimSpriteUphill { get; set; }
|
|
|
|
public string AimSpriteDownhill { get; set; }
|
|
|
|
public string PickSpriteEven { get; set; }
|
|
|
|
public string PickSpriteUphill { get; set; }
|
|
|
|
public string PickSpriteDownhill { get; set; }
|
|
|
|
public string FireSpriteEven { get; set; }
|
|
|
|
public string FireSpriteUphill { get; set; }
|
|
|
|
public string FireSpriteDownhill { get; set; }
|
|
|
|
public bool AimSpriteOverride { get; set; }
|
|
|
|
public bool PickSpriteOverride { get; set; }
|
|
|
|
public bool FireSpriteOverride { get; set; }
|
|
|
|
public bool Utility { get; set; }
|
|
|
|
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Loads the data from the given <see cref="Stream"/>.
|
|
/// </summary>
|
|
/// <param name="stream">The <see cref="Stream"/> to load the data from.</param>
|
|
public void Load(Stream stream)
|
|
{
|
|
using (BinaryStream reader = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true))
|
|
{
|
|
// Read the header.
|
|
long offset = reader.Position;
|
|
Version = reader.ReadEnum<WeaponVersion>(true);
|
|
Checksum = reader.ReadInt64();
|
|
|
|
// Read general settings.
|
|
TableRow = reader.ReadInt32();
|
|
Remembered = reader.ReadBoolean(BooleanCoding.Dword);
|
|
UsableInCavern = reader.ReadBoolean(BooleanCoding.Dword);
|
|
Shots = reader.ReadInt32();
|
|
ShotEndsTurn = reader.ReadBoolean(BooleanCoding.Dword);
|
|
RetreatTime = reader.ReadInt32();
|
|
Unknown1 = reader.ReadInt32();
|
|
CrateChance = reader.ReadInt32();
|
|
CrateCount = reader.ReadInt32();
|
|
Unknown2 = reader.ReadInt32();
|
|
|
|
// Read the activation and the corresponding weapon settings.
|
|
Activation = reader.ReadEnum<WeaponActivation>(false);
|
|
switch (Activation)
|
|
{
|
|
case WeaponActivation.Airstrike:
|
|
AirstrikeSubtype = reader.ReadInt32();
|
|
Style = reader.ReadObject<AirstrikeStyle>();
|
|
break;
|
|
case WeaponActivation.Crosshair:
|
|
NotUsed = reader.ReadInt32();
|
|
CrosshairAction = reader.ReadEnum<WeaponCrosshairAction>(false);
|
|
switch (CrosshairAction)
|
|
{
|
|
case WeaponCrosshairAction.Bow:
|
|
Style = reader.ReadObject<BowStyle>();
|
|
break;
|
|
case WeaponCrosshairAction.Flamethrower:
|
|
Style = reader.ReadObject<FlamethrowerStyle>();
|
|
break;
|
|
case WeaponCrosshairAction.Gun:
|
|
Style = reader.ReadObject<GunStyle>();
|
|
break;
|
|
case WeaponCrosshairAction.Launcher:
|
|
Style = reader.ReadObject<LauncherStyle>();
|
|
break;
|
|
}
|
|
break;
|
|
case WeaponActivation.Spacebar:
|
|
SpacebarAction = reader.ReadEnum<WeaponSpacebarAction>(false);
|
|
switch (SpacebarAction)
|
|
{
|
|
case WeaponSpacebarAction.Armageddon:
|
|
Style = reader.ReadObject<LauncherStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.BaseballBat:
|
|
Style = reader.ReadObject<BaseballBatStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.BattleAxe:
|
|
Style = reader.ReadObject<BattleAxeStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.Blowtorch:
|
|
Style = reader.ReadObject<BlowtorchStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.Dragonball:
|
|
Style = reader.ReadObject<DragonballStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.Firepunch:
|
|
Style = reader.ReadObject<FirepunchStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.Jetpack:
|
|
Style = reader.ReadObject<JetpackStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.Kamikaze:
|
|
Style = reader.ReadObject<KamikazeStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.NinjaRope:
|
|
Style = reader.ReadObject<NinjaRopeStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.NuclearTest:
|
|
Style = reader.ReadObject<NuclearTestStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.Parachute:
|
|
Style = reader.ReadObject<ParachuteStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.PneumaticDrill:
|
|
Style = reader.ReadObject<PneumaticDrillStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.Prod:
|
|
Style = reader.ReadObject<ProdStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.SuicideBomber:
|
|
Style = reader.ReadObject<SuicideBomberStyle>();
|
|
break;
|
|
case WeaponSpacebarAction.Bungee:
|
|
case WeaponSpacebarAction.Earthquake:
|
|
case WeaponSpacebarAction.Freeze:
|
|
case WeaponSpacebarAction.Girder:
|
|
case WeaponSpacebarAction.ScalesOfJustice:
|
|
case WeaponSpacebarAction.SelectWorm:
|
|
case WeaponSpacebarAction.SkipGo:
|
|
case WeaponSpacebarAction.Surrender:
|
|
case WeaponSpacebarAction.Teleport:
|
|
case WeaponSpacebarAction.Utility:
|
|
Style = null;
|
|
break;
|
|
}
|
|
break;
|
|
case WeaponActivation.Throw:
|
|
ThrowHerdCount = reader.ReadInt32();
|
|
ThrowAction = reader.ReadEnum<WeaponThrowAction>(false);
|
|
switch (ThrowAction)
|
|
{
|
|
case WeaponThrowAction.Canister:
|
|
Style = reader.ReadObject<CanisterStyle>();
|
|
break;
|
|
case WeaponThrowAction.Launcher:
|
|
Style = reader.ReadObject<LauncherStyle>();
|
|
break;
|
|
case WeaponThrowAction.Mine:
|
|
Style = reader.ReadObject<MineStyle>();
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Read additional settings.
|
|
reader.Position = offset + 468;
|
|
AmmunitionOverride = reader.ReadBoolean(BooleanCoding.Dword);
|
|
Ammunition = reader.ReadInt32();
|
|
Unknown3 = reader.ReadInt32();
|
|
WeaponSprite = reader.ReadInt32();
|
|
NameLong = reader.ReadString(StringCoding.Int32CharCount);
|
|
Name = reader.ReadString(StringCoding.Int32CharCount);
|
|
GridImageFile = reader.ReadString(StringCoding.Int32CharCount);
|
|
GfxDirectoryFile = reader.ReadString(StringCoding.Int32CharCount);
|
|
SpriteNames = reader.ReadStrings(5, StringCoding.Int32CharCount);
|
|
DelayOverride = reader.ReadBoolean(BooleanCoding.Dword);
|
|
Delay = reader.ReadInt32();
|
|
|
|
UseLibrary = reader.ReadBoolean();
|
|
if (UseLibrary)
|
|
{
|
|
LibraryName = reader.ReadString(StringCoding.Int32CharCount);
|
|
LibraryWeaponName = reader.ReadString(StringCoding.Int32CharCount);
|
|
}
|
|
|
|
AimSpriteEven = reader.ReadString(StringCoding.Int32CharCount);
|
|
AimSpriteUphill = reader.ReadString(StringCoding.Int32CharCount);
|
|
AimSpriteDownhill = reader.ReadString(StringCoding.Int32CharCount);
|
|
PickSpriteEven = reader.ReadString(StringCoding.Int32CharCount);
|
|
PickSpriteUphill = reader.ReadString(StringCoding.Int32CharCount);
|
|
PickSpriteDownhill = reader.ReadString(StringCoding.Int32CharCount);
|
|
FireSpriteEven = reader.ReadString(StringCoding.Int32CharCount);
|
|
FireSpriteUphill = reader.ReadString(StringCoding.Int32CharCount);
|
|
FireSpriteDownhill = reader.ReadString(StringCoding.Int32CharCount);
|
|
AimSpriteOverride = reader.ReadBoolean();
|
|
PickSpriteOverride = reader.ReadBoolean();
|
|
FireSpriteOverride = reader.ReadBoolean();
|
|
if (Version == WeaponVersion.Version_0_8_0)
|
|
{
|
|
Utility = reader.ReadBoolean();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the data into the given <paramref name="stream"/>.
|
|
/// </summary>
|
|
/// <param name="stream">The <see cref="Stream"/> to save the data to.</param>
|
|
public void Save(Stream stream)
|
|
{
|
|
using (BinaryStream writer = new BinaryStream(stream, encoding: Encoding.ASCII, leaveOpen: true))
|
|
{
|
|
// Write the header.
|
|
long offset = writer.Position;
|
|
writer.WriteEnum(Version, true);
|
|
writer.Write(Checksum);
|
|
|
|
// Write the general settings.
|
|
writer.Write(TableRow);
|
|
writer.Write(Remembered, BooleanCoding.Dword);
|
|
writer.Write(UsableInCavern, BooleanCoding.Dword);
|
|
writer.Write(Shots);
|
|
writer.Write(ShotEndsTurn, BooleanCoding.Dword);
|
|
writer.Write(RetreatTime);
|
|
writer.Write(Unknown1);
|
|
writer.Write(CrateChance);
|
|
writer.Write(CrateCount);
|
|
writer.Write(Unknown2);
|
|
|
|
// Write the activation and the corresponding weapon settings.
|
|
writer.WriteEnum(Activation, true);
|
|
switch (Activation)
|
|
{
|
|
case WeaponActivation.Airstrike:
|
|
writer.Write(AirstrikeSubtype);
|
|
writer.WriteObject(Style);
|
|
break;
|
|
case WeaponActivation.Crosshair:
|
|
writer.Write(NotUsed);
|
|
writer.WriteEnum(CrosshairAction, true);
|
|
if (CrosshairAction != WeaponCrosshairAction.None)
|
|
{
|
|
writer.WriteObject(Style);
|
|
}
|
|
break;
|
|
case WeaponActivation.Spacebar:
|
|
writer.WriteEnum(SpacebarAction, true);
|
|
switch (SpacebarAction)
|
|
{
|
|
case WeaponSpacebarAction.Armageddon:
|
|
case WeaponSpacebarAction.BaseballBat:
|
|
case WeaponSpacebarAction.BattleAxe:
|
|
case WeaponSpacebarAction.Blowtorch:
|
|
case WeaponSpacebarAction.Dragonball:
|
|
case WeaponSpacebarAction.Firepunch:
|
|
case WeaponSpacebarAction.Jetpack:
|
|
case WeaponSpacebarAction.Kamikaze:
|
|
case WeaponSpacebarAction.NinjaRope:
|
|
case WeaponSpacebarAction.NuclearTest:
|
|
case WeaponSpacebarAction.Parachute:
|
|
case WeaponSpacebarAction.PneumaticDrill:
|
|
case WeaponSpacebarAction.Prod:
|
|
case WeaponSpacebarAction.SuicideBomber:
|
|
writer.WriteObject(Style);
|
|
break;
|
|
}
|
|
break;
|
|
case WeaponActivation.Throw:
|
|
writer.Write(ThrowHerdCount);
|
|
writer.WriteEnum(ThrowAction, true);
|
|
if (ThrowAction != WeaponThrowAction.None)
|
|
{
|
|
writer.WriteObject(Style);
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Write additional settings.
|
|
writer.Position = offset + 468;
|
|
writer.Write(AmmunitionOverride, BooleanCoding.Dword);
|
|
writer.Write(Ammunition);
|
|
writer.Write(Unknown3);
|
|
writer.Write(WeaponSprite);
|
|
writer.Write(NameLong, StringCoding.Int32CharCount);
|
|
writer.Write(Name, StringCoding.Int32CharCount);
|
|
writer.Write(GridImageFile, StringCoding.Int32CharCount);
|
|
writer.Write(GfxDirectoryFile, StringCoding.Int32CharCount);
|
|
writer.Write(SpriteNames, StringCoding.Int32CharCount);
|
|
writer.Write(DelayOverride, BooleanCoding.Dword);
|
|
writer.Write(Delay);
|
|
|
|
writer.Write(UseLibrary);
|
|
if (UseLibrary)
|
|
{
|
|
writer.Write(LibraryName, StringCoding.Int32CharCount);
|
|
writer.Write(LibraryWeaponName, StringCoding.Int32CharCount);
|
|
}
|
|
|
|
writer.Write(AimSpriteEven, StringCoding.Int32CharCount);
|
|
writer.Write(AimSpriteUphill, StringCoding.Int32CharCount);
|
|
writer.Write(AimSpriteDownhill, StringCoding.Int32CharCount);
|
|
writer.Write(PickSpriteEven, StringCoding.Int32CharCount);
|
|
writer.Write(PickSpriteUphill, StringCoding.Int32CharCount);
|
|
writer.Write(PickSpriteDownhill, StringCoding.Int32CharCount);
|
|
writer.Write(FireSpriteEven, StringCoding.Int32CharCount);
|
|
writer.Write(FireSpriteUphill, StringCoding.Int32CharCount);
|
|
writer.Write(FireSpriteDownhill, StringCoding.Int32CharCount);
|
|
writer.Write(AimSpriteOverride);
|
|
writer.Write(PickSpriteOverride);
|
|
writer.Write(FireSpriteOverride);
|
|
if (Version == WeaponVersion.Version_0_8_0)
|
|
{
|
|
writer.Write(Utility);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public enum WeaponVersion : int
|
|
{
|
|
Version_0_8_0_pre = 0x5ABBDD05,
|
|
Version_0_8_0 = 0x5ABBDD06
|
|
}
|
|
|
|
public enum WeaponActivation : int
|
|
{
|
|
None,
|
|
Crosshair,
|
|
Throw,
|
|
Airstrike,
|
|
Spacebar
|
|
}
|
|
|
|
public enum WeaponSpacebarAction : int
|
|
{
|
|
None,
|
|
Firepunch,
|
|
BaseballBat,
|
|
Dragonball,
|
|
Kamikaze,
|
|
SuicideBomber,
|
|
NinjaRope,
|
|
Bungee,
|
|
PneumaticDrill,
|
|
Prod,
|
|
Teleport,
|
|
Blowtorch,
|
|
Parachute,
|
|
Surrender,
|
|
SkipGo,
|
|
SelectWorm,
|
|
NuclearTest,
|
|
Girder,
|
|
BattleAxe,
|
|
Utility,
|
|
Freeze,
|
|
Earthquake,
|
|
ScalesOfJustice,
|
|
Jetpack,
|
|
Armageddon
|
|
}
|
|
|
|
public enum WeaponCrosshairAction : int
|
|
{
|
|
None,
|
|
Flamethrower,
|
|
Gun,
|
|
Launcher,
|
|
Bow
|
|
}
|
|
|
|
public enum WeaponThrowAction : int
|
|
{
|
|
None,
|
|
Mine,
|
|
Launcher,
|
|
Canister
|
|
}
|
|
|
|
public enum WeaponSpriteNameIndex
|
|
{
|
|
Unknown0,
|
|
Launcher,
|
|
Cluster,
|
|
Home,
|
|
Unknown4
|
|
}
|
|
}
|