diff --git a/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3.cs b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3.cs new file mode 100644 index 000000000..2be1f10b4 --- /dev/null +++ b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3.cs @@ -0,0 +1,71 @@ +using System; +using System.Linq; + +namespace PKHeX.Core +{ + public class SecretBase3 + { + private readonly byte[] Data; + private readonly int Offset; + private bool Japanese => Language == (int) LanguageID.Japanese; + + public SecretBase3(byte[] data, int offset) + { + Data = data; + Offset = offset; + } + + public int SecretBaseLocation { get => Data[Offset + 0]; set => Data[Offset + 0] = (byte) value; } + public int OT_Gender + { + get => (Data[Offset + 1] >> 4) & 1; + set => Data[Offset + 1] = (byte) ((Data[Offset + 1] & 0xEF) | (value & 1) << 4); + } + + public string OT_Name + { + get => StringConverter.GetString3(Data, Offset + 2, 7, Japanese); + set => StringConverter.SetString3(value, 7, Japanese, 7).CopyTo(Data, Offset + 2); + } + public uint OT_ID + { + get => BitConverter.ToUInt32(Data, Offset + 9); + set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 9); + } + public int OT_Class { get => Data[Offset + 9]; set => Data[Offset + 9] = (byte) value; } + public int Language { get => Data[Offset + 0x0D]; set => Data[Offset + 0x0D] = (byte)value; } + public int _E { get => Data[Offset + 0x0E]; set => Data[Offset + 0x0E] = (byte)value; } + public int _F { get => Data[Offset + 0x0F]; set => Data[Offset + 0x0F] = (byte)value; } + public int _10 { get => Data[Offset + 0x10]; set => Data[Offset + 0x10] = (byte)value; } + public int _11 { get => Data[Offset + 0x11]; set => Data[Offset + 0x11] = (byte)value; } + + public byte[] Decorations + { + get => Data.Skip(Offset + 0x12).Take(0x10).ToArray(); + set => value.CopyTo(Data, Offset + 0x12); + } + public byte[] DecorationCoordinates + { + get => Data.Skip(Offset + 0x22).Take(0x10).ToArray(); + set => value.CopyTo(Data, Offset + 0x22); + } + + public SecretBase3Team Team + { + get => new SecretBase3Team(Data.Skip(Offset + 50).Take(72).ToArray()); + set => value.Write().CopyTo(Data, Offset + 50); + } + + public int TID + { + get => (ushort)OT_ID; + set => OT_ID = (ushort)(SID | (ushort)value); + } + + public int SID + { + get => (ushort)OT_ID >> 8; + set => OT_ID = (ushort)(((ushort)value << 16) | TID); + } + } +} diff --git a/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3PKM.cs b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3PKM.cs new file mode 100644 index 000000000..54f44f4d0 --- /dev/null +++ b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3PKM.cs @@ -0,0 +1,32 @@ +using System; +using System.Linq; + +namespace PKHeX.Core +{ + public class SecretBase3PKM + { + public uint PID { get; set; } + public int Move1 { get; set; } + public int Move2 { get; set; } + public int Move3 { get; set; } + public int Move4 { get; set; } + public int Species { get; set; } + public int HeldItem { get; set; } + public int Level { get; set; } + public int EVAll { get; set; } + public int[] Moves => new[] { Move1, Move2, Move3, Move4 }; + + public string Summary + { + get + { + var first = $"{Species:000} - {GameInfo.Strings.Species[Species]}"; + if (HeldItem != 0) + first += $"@ {GameInfo.Strings.Item[HeldItem]}"; + var second = $"Moves: {string.Join(" / ", Moves.Select(z => GameInfo.Strings.Move[z]))}"; + var third = $"Level: {Level}, EVs: {EVAll}, PID: {PID}"; + return first + Environment.NewLine + second + Environment.NewLine + third; + } + } + } +} \ No newline at end of file diff --git a/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3Team.cs b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3Team.cs new file mode 100644 index 000000000..3796a7582 --- /dev/null +++ b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3Team.cs @@ -0,0 +1,68 @@ +using System; + +namespace PKHeX.Core +{ + public class SecretBase3Team + { + private const int O_PID = 0; + private const int O_Moves = 0x18; + private const int O_Species = 0x24; + private const int O_Item = 0x30; + private const int O_Level = 0x3C; + private const int O_EV = 0x42; + + private static int GetOffsetPID(int i) => O_PID + (i * 4); + private static int GetOffsetMove(int i, int move) => O_Moves + (i * 8) + (move * 2); + private static int GetOffsetSpecies(int i) => O_Species + (i * 2); + private static int GetOffsetItem(int i) => O_Item + (i * 2); + + public readonly SecretBase3PKM[] Team; + private readonly byte[] Data; + public SecretBase3Team(byte[] data) + { + Team = new SecretBase3PKM[6]; + for (int i = 0; i < Team.Length; i++) + Team[i] = GetPKM(i); + Data = data; + } + + public byte[] Write() + { + for (int i = 0; i < Team.Length; i++) + SetPKM(i); + return Data; + } + + private SecretBase3PKM GetPKM(int i) + { + return new SecretBase3PKM + { + PID = BitConverter.ToUInt32(Data, GetOffsetPID(i)), + Species = BitConverter.ToUInt16(Data, GetOffsetSpecies(i)), + HeldItem = BitConverter.ToUInt16(Data, GetOffsetItem(i)), + Move1 = BitConverter.ToUInt16(Data, GetOffsetMove(i, 0)), + Move2 = BitConverter.ToUInt16(Data, GetOffsetMove(i, 1)), + Move3 = BitConverter.ToUInt16(Data, GetOffsetMove(i, 2)), + Move4 = BitConverter.ToUInt16(Data, GetOffsetMove(i, 3)), + Level = Data[O_Level + i], + EVAll = Data[O_EV + i], + }; + } + + private void SetPKM(int i) + { + var pk = Team[i]; + BitConverter.GetBytes((uint) pk.PID).CopyTo(Data, GetOffsetPID(i)); + BitConverter.GetBytes((ushort)pk.Species).CopyTo(Data, GetOffsetSpecies(i)); + BitConverter.GetBytes((ushort)pk.HeldItem).CopyTo(Data, GetOffsetItem(i)); + BitConverter.GetBytes((ushort)pk.Move1).CopyTo(Data, GetOffsetMove(i, 0)); + BitConverter.GetBytes((ushort)pk.Move2).CopyTo(Data, GetOffsetMove(i, 1)); + BitConverter.GetBytes((ushort)pk.Move3).CopyTo(Data, GetOffsetMove(i, 2)); + BitConverter.GetBytes((ushort)pk.Move4).CopyTo(Data, GetOffsetMove(i, 3)); + Data[O_Level + i] = (byte) pk.Level; + Data[O_EV + i] = (byte) pk.EVAll; + + BitConverter.GetBytes((uint) pk.PID).CopyTo(Data, GetOffsetPID(i)); + } + } +} \ No newline at end of file