364 lines
14 KiB
C#

using System.Diagnostics;
using System.IO;
using System.Text;
using Syroot.IO;
using Syroot.Worms.Core;
namespace Syroot.Worms.Gen2.Armageddon.ProjectX
{
[DebuggerDisplay("Weapon Name={Name}")]
public class Weapon : ILoadable, ISaveable
{
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
private const int _version_0_8_0_pre = 0x5ABBDD05;
private const int _version_0_8_0 = 0x5ABBDD06;
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
public int 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 bool Unknown2 { get; set; }
public WeaponActivation Activation { 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 StyleBase 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 (BinaryDataReader reader = new BinaryDataReader(stream, Encoding.ASCII, true))
{
// Read the header.
long offset = reader.Position;
Version = reader.ReadInt32();
if (Version != _version_0_8_0_pre && Version != _version_0_8_0)
{
throw new InvalidDataException($"Unknown Project X weapon version 0x{Version:X8}.");
}
Checksum = reader.ReadInt64();
// Read general settings.
TableRow = reader.ReadInt32();
Remembered = reader.ReadBoolean(BinaryBooleanFormat.NonZeroDword);
UsableInCavern = reader.ReadBoolean(BinaryBooleanFormat.NonZeroDword);
Shots = reader.ReadInt32();
ShotEndsTurn = reader.ReadBoolean(BinaryBooleanFormat.NonZeroDword);
RetreatTime = reader.ReadInt32();
Unknown1 = reader.ReadInt32();
CrateChance = reader.ReadInt32();
CrateCount = reader.ReadInt32();
Unknown2 = reader.ReadBoolean(BinaryBooleanFormat.NonZeroDword);
// Read the activation and the corresponding weapon settings.
Activation = reader.ReadEnum<WeaponActivation>(true);
switch (Activation)
{
case WeaponActivation.Airstrike:
AirstrikeSubtype = reader.ReadInt32();
Style = reader.Load<AirstrikeStyle>();
break;
case WeaponActivation.Crosshair:
reader.Seek(sizeof(int));
CrosshairAction = reader.ReadEnum<WeaponCrosshairAction>(true);
switch (CrosshairAction)
{
case WeaponCrosshairAction.Bow:
Style = reader.Load<BowStyle>();
break;
case WeaponCrosshairAction.Flamethrower:
Style = reader.Load<FlamethrowerStyle>();
break;
case WeaponCrosshairAction.Gun:
Style = reader.Load<GunStyle>();
break;
case WeaponCrosshairAction.Launcher:
Style = reader.Load<LauncherStyle>();
break;
}
break;
case WeaponActivation.Spacebar:
SpacebarAction = reader.ReadEnum<WeaponSpacebarAction>(true);
switch (SpacebarAction)
{
case WeaponSpacebarAction.Armageddon:
Style = reader.Load<LauncherStyle>();
break;
case WeaponSpacebarAction.BaseballBat:
Style = reader.Load<BaseballBatStyle>();
break;
case WeaponSpacebarAction.BattleAxe:
Style = reader.Load<BattleAxeStyle>();
break;
case WeaponSpacebarAction.Blowtorch:
Style = reader.Load<BlowtorchStyle>();
break;
case WeaponSpacebarAction.Dragonball:
Style = reader.Load<DragonballStyle>();
break;
case WeaponSpacebarAction.Firepunch:
Style = reader.Load<FirepunchStyle>();
break;
case WeaponSpacebarAction.Jetpack:
Style = reader.Load<JetpackStyle>();
break;
case WeaponSpacebarAction.Kamikaze:
Style = reader.Load<KamikazeStyle>();
break;
case WeaponSpacebarAction.NinjaRope:
Style = reader.Load<NinjaRopeStyle>();
break;
case WeaponSpacebarAction.NuclearTest:
Style = reader.Load<NuclearTestStyle>();
break;
case WeaponSpacebarAction.Parachute:
Style = reader.Load<ParachuteStyle>();
break;
case WeaponSpacebarAction.PneumaticDrill:
Style = reader.Load<PneumaticDrillStyle>();
break;
case WeaponSpacebarAction.Prod:
Style = reader.Load<ProdStyle>();
break;
case WeaponSpacebarAction.SuicideBomber:
Style = reader.Load<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>(true);
switch (ThrowAction)
{
case WeaponThrowAction.Canister:
Style = reader.Load<CanisterStyle>();
break;
case WeaponThrowAction.Launcher:
Style = reader.Load<LauncherStyle>();
break;
case WeaponThrowAction.Mine:
Style = reader.Load<MineStyle>();
break;
}
break;
}
// Read additional settings.
reader.Position = offset + 468;
AmmunitionOverride = reader.ReadBoolean(BinaryBooleanFormat.NonZeroDword);
Ammunition = reader.ReadInt32();
Unknown3 = reader.ReadInt32();
WeaponSprite = reader.ReadInt32();
NameLong = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
Name = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
GridImageFile = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
GfxDirectoryFile = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
SpriteNames = reader.ReadStrings(5, BinaryStringFormat.DwordLengthPrefix);
DelayOverride = reader.ReadBoolean(BinaryBooleanFormat.NonZeroDword);
Delay = reader.ReadInt32();
UseLibrary = reader.ReadBoolean();
if (UseLibrary)
{
LibraryName = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
LibraryWeaponName = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
}
AimSpriteEven = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
AimSpriteUphill = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
AimSpriteDownhill = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
PickSpriteEven = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
PickSpriteUphill = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
PickSpriteDownhill = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
FireSpriteEven = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
FireSpriteUphill = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
FireSpriteDownhill = reader.ReadString(BinaryStringFormat.DwordLengthPrefix);
AimSpriteOverride = reader.ReadBoolean();
PickSpriteOverride = reader.ReadBoolean();
FireSpriteOverride = reader.ReadBoolean();
if (Version == _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 (BinaryDataWriter writer = new BinaryDataWriter(stream, Encoding.ASCII, true))
{
}
}
}
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
}
}