2017-08-25 20:10:55 +02:00

369 lines
12 KiB
C#

using System.Diagnostics;
using System.IO;
using System.Text;
using Syroot.BinaryData;
using Syroot.Maths;
using Syroot.Worms.Core;
namespace Syroot.Worms.Gen2.Armageddon
{
/// <summary>
/// Represents a team stored in a <see cref="TeamContainer"/> file.
/// </summary>
public class Team : ILoadable, ISaveable
{
// ---- CONSTANTS ----------------------------------------------------------------------------------------------
private const int _missionCount = 33;
private const int _trainingMissionCount = 6;
// ---- 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];
Unknown1 = new int[10];
TrainingMissionMedals = new byte[_trainingMissionCount];
Unknown2 = new byte[10];
Unknown3 = 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 BitmapData 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 BitmapData Flag { 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 6 training missions.
/// </summary>
public int[] TrainingMissionTimes { get; set; }
/// <summary>
/// Gets or sets 10 unknown integer values.
/// </summary>
public int[] Unknown1 { get; set; }
/// <summary>
/// Gets or sets the medals the team achieved in all 6 training missions.
/// </summary>
public byte[] TrainingMissionMedals { get; set; }
/// <summary>
/// Gets or sets 10 unknown bytes.
/// </summary>
public byte[] Unknown2 { get; set; }
/// <summary>
/// Gets or sets 7 unknown integer values.
/// </summary>
public int[] Unknown3 { get; set; }
/// <summary>
/// Gets or sets an unknown byte.
/// </summary>
public byte Unknown4 { 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))
{
Name = reader.ReadFixedString(17);
WormNames = reader.ReadFixedStrings(8, 17);
CpuLevel = reader.ReadByte();
SoundBankName = reader.ReadFixedString(0x20);
SoundBankLocation = reader.ReadByte();
FanfareName = reader.ReadFixedString(0x20);
UseCustomFanfare = reader.ReadByte();
GraveSprite = reader.ReadSByte();
if (GraveSprite < 0)
{
GraveFileName = reader.ReadFixedString(0x20);
Grave = new BitmapData()
{
BitsPerPixel = 8,
Size = new Vector2(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.ReadFixedString(0x20);
Flag = new BitmapData()
{
BitsPerPixel = 8,
Size = new Vector2(20, 17),
Palette = reader.ReadStructs<Color>(256),
Data = reader.ReadBytes(20 * 17)
};
DeathmatchRank = reader.ReadByte();
TrainingMissionTimes = reader.ReadInt32s(_trainingMissionCount);
Unknown1 = reader.ReadInt32s(10);
TrainingMissionMedals = reader.ReadBytes(_trainingMissionCount);
Unknown2 = reader.ReadBytes(10);
Unknown3 = reader.ReadInt32s(7);
Unknown4 = reader.ReadByte();
}
}
/// <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))
{
writer.Write(Name, 17);
writer.Write(WormNames, 17);
writer.Write(CpuLevel);
writer.Write(SoundBankName, 0x20);
writer.Write(SoundBankLocation);
writer.Write(FanfareName, 0x20);
writer.Write(UseCustomFanfare);
writer.Write(GraveSprite);
if (GraveSprite < 0)
{
writer.Write(GraveFileName, 0x20);
writer.Write(Grave.Palette);
writer.Write(Grave.Data);
}
writer.Write(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.Write(MissionStatuses);
writer.Write(FlagFileName, 0x20);
writer.Write(Flag.Palette);
writer.Write(Flag.Data);
writer.Write(DeathmatchRank);
writer.Write(TrainingMissionTimes);
writer.Write(Unknown1);
writer.Write(TrainingMissionMedals);
writer.Write(Unknown2);
writer.Write(Unknown3);
writer.Write(Unknown4);
}
}
}
/// <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
}
}