2018-10-16 00:57:08 +02:00

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
}
}