using System.Diagnostics; using System.IO; using System.Text; using Syroot.BinaryData; using Syroot.Worms.Core; using Syroot.Worms.Core.IO; namespace Syroot.Worms.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) --------------------------------------------------------------------------------------- /// /// Loads the data from the given . /// /// The to load the data from. 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(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(false); switch (Activation) { case WeaponActivation.Airstrike: AirstrikeSubtype = reader.ReadInt32(); Style = reader.ReadObject(); break; case WeaponActivation.Crosshair: NotUsed = reader.ReadInt32(); CrosshairAction = reader.ReadEnum(false); switch (CrosshairAction) { case WeaponCrosshairAction.Bow: Style = reader.ReadObject(); break; case WeaponCrosshairAction.Flamethrower: Style = reader.ReadObject(); break; case WeaponCrosshairAction.Gun: Style = reader.ReadObject(); break; case WeaponCrosshairAction.Launcher: Style = reader.ReadObject(); break; } break; case WeaponActivation.Spacebar: SpacebarAction = reader.ReadEnum(false); switch (SpacebarAction) { case WeaponSpacebarAction.Armageddon: Style = reader.ReadObject(); break; case WeaponSpacebarAction.BaseballBat: Style = reader.ReadObject(); break; case WeaponSpacebarAction.BattleAxe: Style = reader.ReadObject(); break; case WeaponSpacebarAction.Blowtorch: Style = reader.ReadObject(); break; case WeaponSpacebarAction.Dragonball: Style = reader.ReadObject(); break; case WeaponSpacebarAction.Firepunch: Style = reader.ReadObject(); break; case WeaponSpacebarAction.Jetpack: Style = reader.ReadObject(); break; case WeaponSpacebarAction.Kamikaze: Style = reader.ReadObject(); break; case WeaponSpacebarAction.NinjaRope: Style = reader.ReadObject(); break; case WeaponSpacebarAction.NuclearTest: Style = reader.ReadObject(); break; case WeaponSpacebarAction.Parachute: Style = reader.ReadObject(); break; case WeaponSpacebarAction.PneumaticDrill: Style = reader.ReadObject(); break; case WeaponSpacebarAction.Prod: Style = reader.ReadObject(); break; case WeaponSpacebarAction.SuicideBomber: Style = reader.ReadObject(); 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(false); switch (ThrowAction) { case WeaponThrowAction.Canister: Style = reader.ReadObject(); break; case WeaponThrowAction.Launcher: Style = reader.ReadObject(); break; case WeaponThrowAction.Mine: Style = reader.ReadObject(); 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(); } } } /// /// Saves the data into the given . /// /// The to save the data to. 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 } }