mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-06-01 16:27:39 +03:00
604 lines
17 KiB
C#
604 lines
17 KiB
C#
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Text;
|
|
using Syroot.BinaryData;
|
|
using Syroot.Worms.Core.IO;
|
|
|
|
namespace Syroot.Worms.WorldParty
|
|
{
|
|
/// <summary>
|
|
/// Represents a team stored in a <see cref="TeamContainer"/> file.
|
|
/// </summary>
|
|
public class Team : ILoadable, ISaveable
|
|
{
|
|
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
|
|
|
|
private const int _missionCount = 45;
|
|
private const int _trainingMissionCount = 35;
|
|
|
|
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="Team"/> class.
|
|
/// </summary>
|
|
public Team()
|
|
{
|
|
WormNames = new string[8];
|
|
MissionStatuses = new TeamMissionStatus[_missionCount];
|
|
TrainingMissionTimes = new int[_trainingMissionCount];
|
|
WeaponPoints = new byte[46];
|
|
Unknown2 = new int[7];
|
|
}
|
|
|
|
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
|
|
|
/// <summary>
|
|
/// Gets or sets the name of the team.
|
|
/// </summary>
|
|
public string Name { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the 8 worm names.
|
|
/// </summary>
|
|
public string[] WormNames { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the AI intelligence difficulty level, from 0-5, where 0 is human-controlled.
|
|
/// </summary>
|
|
public byte CpuLevel { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the name of soundbank for the voice of team worms.
|
|
/// </summary>
|
|
public string SoundBankName { get; set; }
|
|
|
|
public byte SoundBankLocation { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the name of the team fanfare.
|
|
/// </summary>
|
|
public string FanfareName { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether the fanfare with the name stored in <see cref="FanfareName"/>
|
|
/// (<c>true</c>) or the player's countries' fanfare should be played (<c>false</c>).
|
|
/// </summary>
|
|
public byte UseCustomFanfare { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the sprite index of the team grave, -1 being a custom bitmap grave.
|
|
/// </summary>
|
|
public sbyte GraveSprite { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the file name of the team grave bitmap if it uses a custom one.
|
|
/// </summary>
|
|
public string GraveFileName { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the team grave bitmap if it uses a custom one.
|
|
/// </summary>
|
|
public RawBitmap Grave { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the team's special weapon.
|
|
/// </summary>
|
|
public TeamWeapon TeamWeapon { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of games lost.
|
|
/// </summary>
|
|
public int GamesLost { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of deathmatch games lost.
|
|
/// </summary>
|
|
public int DeathmatchesLost { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of games won.
|
|
/// </summary>
|
|
public int GamesWon { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of deathmatch games won.
|
|
/// </summary>
|
|
public int DeathmatchesWon { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of games drawn.
|
|
/// </summary>
|
|
public int GamesDrawn { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of deathmatch games drawn.
|
|
/// </summary>
|
|
public int DeathmatchesDrawn { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of opponent worms killed by this team.
|
|
/// </summary>
|
|
public int Kills { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of opponent worms killed by this team in deathmatches.
|
|
/// </summary>
|
|
public int DeathmatchKills { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of worms which got killed in this team.
|
|
/// </summary>
|
|
public int Deaths { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of worms which got killed in this team in deathmatches.
|
|
/// </summary>
|
|
public int DeathmatchDeaths { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the array of 33 mission statuses.
|
|
/// </summary>
|
|
public TeamMissionStatus[] MissionStatuses { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the file name of the team flag.
|
|
/// </summary>
|
|
public string FlagFileName { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the bitmap of the team flag.
|
|
/// </summary>
|
|
public RawBitmap Flag { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets an unknown value.
|
|
/// </summary>
|
|
public byte Unknown1 { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the deathmatch rank this team reached.
|
|
/// </summary>
|
|
public byte DeathmatchRank { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the seconds the team required to finish all 35 training missions. The last one is unused.
|
|
/// </summary>
|
|
public int[] TrainingMissionTimes { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a possibly unused training mission time for a 35th mission.
|
|
/// </summary>
|
|
public int UnknownTrainingMissionTime { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the 46 weapons which were bought for points. Specific weapons can be accessed with the
|
|
/// <see cref="TeamWeaponPoints"/> enumeration.
|
|
/// </summary>
|
|
public byte[] WeaponPoints { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the fort of the team.
|
|
/// </summary>
|
|
public byte Fort { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets 7 unknown integer values.
|
|
/// </summary>
|
|
public int[] Unknown2 { 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))
|
|
{
|
|
Name = reader.ReadString(17);
|
|
WormNames = reader.ReadStrings(8, 17);
|
|
CpuLevel = reader.Read1Byte();
|
|
SoundBankName = reader.ReadString(0x20);
|
|
SoundBankLocation = reader.Read1Byte();
|
|
FanfareName = reader.ReadString(0x20);
|
|
UseCustomFanfare = reader.Read1Byte();
|
|
|
|
GraveSprite = reader.ReadSByte();
|
|
if (GraveSprite < 0)
|
|
{
|
|
GraveFileName = reader.ReadString(0x20);
|
|
Grave = new RawBitmap()
|
|
{
|
|
BitsPerPixel = 8,
|
|
Size = new Size(24, 32),
|
|
Palette = reader.ReadStructs<Color>(256),
|
|
Data = reader.ReadBytes(24 * 32)
|
|
};
|
|
}
|
|
|
|
TeamWeapon = reader.ReadEnum<TeamWeapon>(true);
|
|
GamesLost = reader.ReadInt32();
|
|
DeathmatchesLost = reader.ReadInt32();
|
|
GamesWon = reader.ReadInt32();
|
|
DeathmatchesWon = reader.ReadInt32();
|
|
GamesDrawn = reader.ReadInt32();
|
|
DeathmatchesDrawn = reader.ReadInt32();
|
|
Kills = reader.ReadInt32();
|
|
DeathmatchKills = reader.ReadInt32();
|
|
Deaths = reader.ReadInt32();
|
|
DeathmatchDeaths = reader.ReadInt32();
|
|
MissionStatuses = reader.ReadStructs<TeamMissionStatus>(_missionCount);
|
|
|
|
FlagFileName = reader.ReadString(0x20);
|
|
Flag = new RawBitmap()
|
|
{
|
|
BitsPerPixel = 8,
|
|
Size = new Size(20, 17),
|
|
Palette = reader.ReadStructs<Color>(256),
|
|
Data = reader.ReadBytes(20 * 17)
|
|
};
|
|
|
|
Unknown1 = reader.Read1Byte();
|
|
DeathmatchRank = reader.Read1Byte();
|
|
TrainingMissionTimes = reader.ReadInt32s(_trainingMissionCount);
|
|
WeaponPoints = reader.ReadBytes(46);
|
|
Fort = reader.Read1Byte();
|
|
Unknown2 = reader.ReadInt32s(7);
|
|
}
|
|
}
|
|
|
|
/// <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))
|
|
{
|
|
writer.WriteString(Name, 17);
|
|
writer.WriteStrings(WormNames, 17);
|
|
writer.Write(CpuLevel);
|
|
writer.WriteString(SoundBankName, 0x20);
|
|
writer.Write(SoundBankLocation);
|
|
writer.WriteString(FanfareName, 0x20);
|
|
writer.Write(UseCustomFanfare);
|
|
|
|
writer.Write(GraveSprite);
|
|
if (GraveSprite < 0)
|
|
{
|
|
writer.WriteString(GraveFileName, 0x20);
|
|
writer.WriteStructs(Grave.Palette);
|
|
writer.WriteStructs(Grave.Data);
|
|
}
|
|
|
|
writer.WriteEnum(TeamWeapon, true);
|
|
writer.Write(GamesLost);
|
|
writer.Write(DeathmatchesLost);
|
|
writer.Write(GamesWon);
|
|
writer.Write(DeathmatchesWon);
|
|
writer.Write(GamesDrawn);
|
|
writer.Write(DeathmatchesDrawn);
|
|
writer.Write(Kills);
|
|
writer.Write(DeathmatchKills);
|
|
writer.Write(Deaths);
|
|
writer.Write(DeathmatchDeaths);
|
|
writer.WriteStructs(MissionStatuses);
|
|
|
|
writer.WriteString(FlagFileName, 0x20);
|
|
writer.WriteStructs(Flag.Palette);
|
|
writer.WriteStructs(Flag.Data);
|
|
|
|
writer.Write(Unknown1);
|
|
writer.Write(DeathmatchRank);
|
|
writer.Write(TrainingMissionTimes);
|
|
writer.Write(UnknownTrainingMissionTime);
|
|
writer.WriteStructs(WeaponPoints);
|
|
writer.Write(Fort);
|
|
writer.Write(Unknown2);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a team's progress in a mission.
|
|
/// </summary>
|
|
[DebuggerDisplay("TeamMissionStatus Attemps={Attempts} Medal={Medal}")]
|
|
public struct TeamMissionStatus
|
|
{
|
|
/// <summary>
|
|
/// The number of attempts the team required to solve the mission.
|
|
/// </summary>
|
|
public int Attempts;
|
|
|
|
/// <summary>
|
|
/// The medal the team got to solve the mission.
|
|
/// </summary>
|
|
public int Medal;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents the special weapon of a team.
|
|
/// </summary>
|
|
public enum TeamWeapon : byte
|
|
{
|
|
/// <summary>
|
|
/// The Flame Thrower weapon.
|
|
/// </summary>
|
|
Flamethrower,
|
|
|
|
/// <summary>
|
|
/// The Mole Bomb weapon.
|
|
/// </summary>
|
|
MoleBomb,
|
|
|
|
/// <summary>
|
|
/// The Old Woman weapon.
|
|
/// </summary>
|
|
OldWoman,
|
|
|
|
/// <summary>
|
|
/// The Homing Pigeon weapon.
|
|
/// </summary>
|
|
HomingPigeon,
|
|
|
|
/// <summary>
|
|
/// The Sheep Launcher weapon.
|
|
/// </summary>
|
|
SheepLauncher,
|
|
|
|
/// <summary>
|
|
/// The Mad Cow weapon.
|
|
/// </summary>
|
|
MadCow,
|
|
|
|
/// <summary>
|
|
/// The Holy Hand Grenade weapon.
|
|
/// </summary>
|
|
HolyHandGrenade,
|
|
|
|
/// <summary>
|
|
/// The Super Sheep or Aqua Sheep weapon.
|
|
/// </summary>
|
|
SuperSheep
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents the weapons and utilities being an index into the <see cref="Team.WeaponPoints"/> array to store the
|
|
/// amount the team bought.
|
|
/// </summary>
|
|
public enum TeamWeaponPoints
|
|
{
|
|
/// <summary>
|
|
/// The Bazooka weapon.
|
|
/// </summary>
|
|
Bazooka,
|
|
|
|
/// <summary>
|
|
/// The Homing Missile weapon.
|
|
/// </summary>
|
|
HomingMissile,
|
|
|
|
/// <summary>
|
|
/// The Mortar weapon.
|
|
/// </summary>
|
|
Mortar,
|
|
|
|
/// <summary>
|
|
/// The Grenade weapon.
|
|
/// </summary>
|
|
Grenade,
|
|
|
|
/// <summary>
|
|
/// The Cluster Bomb weapon.
|
|
/// </summary>
|
|
ClusterBomb,
|
|
|
|
/// <summary>
|
|
/// The Skunk weapon.
|
|
/// </summary>
|
|
Skunk,
|
|
|
|
/// <summary>
|
|
/// The Petrol Bomb weapon.
|
|
/// </summary>
|
|
PetrolBomb,
|
|
|
|
/// <summary>
|
|
/// The Banana Bomb weapon.
|
|
/// </summary>
|
|
BananaBomb,
|
|
|
|
/// <summary>
|
|
/// The Handgun weapon.
|
|
/// </summary>
|
|
Handgun,
|
|
|
|
/// <summary>
|
|
/// The Shotgun weapon.
|
|
/// </summary>
|
|
Shotgun,
|
|
|
|
/// <summary>
|
|
/// The Uzi weapon.
|
|
/// </summary>
|
|
Uzi,
|
|
|
|
/// <summary>
|
|
/// The Minigun weapon.
|
|
/// </summary>
|
|
Minigun,
|
|
|
|
/// <summary>
|
|
/// The Longbow weapon.
|
|
/// </summary>
|
|
Longbow,
|
|
|
|
/// <summary>
|
|
/// The Airstrike weapon.
|
|
/// </summary>
|
|
Airstrike,
|
|
|
|
/// <summary>
|
|
/// The Napalm Strike weapon.
|
|
/// </summary>
|
|
NapalmStrike,
|
|
|
|
/// <summary>
|
|
/// The Mine weapon.
|
|
/// </summary>
|
|
Mine,
|
|
|
|
/// <summary>
|
|
/// The Firepunch weapon.
|
|
/// </summary>
|
|
Firepunch,
|
|
|
|
/// <summary>
|
|
/// The Dragonball weapon.
|
|
/// </summary>
|
|
Dragonball,
|
|
|
|
/// <summary>
|
|
/// The Kamikaze weapon.
|
|
/// </summary>
|
|
Kamikaze,
|
|
|
|
/// <summary>
|
|
/// The Prod weapon.
|
|
/// </summary>
|
|
Prod,
|
|
|
|
/// <summary>
|
|
/// The Battle Axe weapon.
|
|
/// </summary>
|
|
BattleAxe,
|
|
|
|
/// <summary>
|
|
/// The Blowtorch weapon.
|
|
/// </summary>
|
|
Blowtorch,
|
|
|
|
/// <summary>
|
|
/// The Pneumatic Drill weapon.
|
|
/// </summary>
|
|
PneumaticDrill,
|
|
|
|
/// <summary>
|
|
/// The Girder weapon.
|
|
/// </summary>
|
|
Girder,
|
|
|
|
/// <summary>
|
|
/// The Ninja Rope weapon.
|
|
/// </summary>
|
|
NinjaRope,
|
|
|
|
/// <summary>
|
|
/// The Parachute weapon.
|
|
/// </summary>
|
|
Parachute,
|
|
|
|
/// <summary>
|
|
/// The Bungee weapon.
|
|
/// </summary>
|
|
Bungee,
|
|
|
|
/// <summary>
|
|
/// The Teleport weapon.
|
|
/// </summary>
|
|
Teleport,
|
|
|
|
/// <summary>
|
|
/// The Dynamite weapon.
|
|
/// </summary>
|
|
Dynamite,
|
|
|
|
/// <summary>
|
|
/// The Sheep weapon.
|
|
/// </summary>
|
|
Sheep,
|
|
|
|
/// <summary>
|
|
/// The Baseball Bat weapon.
|
|
/// </summary>
|
|
BaseballBat,
|
|
|
|
/// <summary>
|
|
/// The Flame Thrower weapon.
|
|
/// </summary>
|
|
Flamethrower,
|
|
|
|
/// <summary>
|
|
/// The Homing Pigeon weapon.
|
|
/// </summary>
|
|
HomingPigeon,
|
|
|
|
/// <summary>
|
|
/// The Mad Cow weapon.
|
|
/// </summary>
|
|
MadCow,
|
|
|
|
/// <summary>
|
|
/// The Holy Hand Grenade weapon.
|
|
/// </summary>
|
|
HolyHandGrenade,
|
|
|
|
/// <summary>
|
|
/// The Old Woman weapon.
|
|
/// </summary>
|
|
OldWoman,
|
|
|
|
/// <summary>
|
|
/// The Sheep Launcher weapon.
|
|
/// </summary>
|
|
SheepLauncher,
|
|
|
|
/// <summary>
|
|
/// The Super Sheep or Aqua Sheep weapon.
|
|
/// </summary>
|
|
SuperSheep,
|
|
|
|
/// <summary>
|
|
/// The Mole Bomb weapon.
|
|
/// </summary>
|
|
MoleBomb,
|
|
|
|
/// <summary>
|
|
/// The Jetpack utility.
|
|
/// </summary>
|
|
Jetpack,
|
|
|
|
/// <summary>
|
|
/// The Low Gravity utility.
|
|
/// </summary>
|
|
LowGravity,
|
|
|
|
/// <summary>
|
|
/// The Laser Sight utility.
|
|
/// </summary>
|
|
LaserSight,
|
|
|
|
/// <summary>
|
|
/// The Fast Walk utility.
|
|
/// </summary>
|
|
FastWalk,
|
|
|
|
/// <summary>
|
|
/// The Invisibility utility.
|
|
/// </summary>
|
|
Invisibility,
|
|
|
|
/// <summary>
|
|
/// The Suicide Bomber weapon.
|
|
/// </summary>
|
|
SuicideBomber,
|
|
|
|
/// <summary>
|
|
/// The Worm Select utility.
|
|
/// </summary>
|
|
WormSelect
|
|
}
|
|
}
|