using System; using System.Diagnostics; namespace PKHeX.Core { public sealed class HallFame3Entry { private readonly byte[] Parent; private readonly bool Japanese; private readonly int Offset; private const int Count = 6; public const int SIZE = Count * HallFame3PKM.SIZE; public HallFame3Entry(byte[] data, int offset, bool japanese) { Parent = data; Japanese = japanese; Offset = offset; } private int GetMemberOffset(int i) => Offset + (i * HallFame3PKM.SIZE); private HallFame3PKM GetMember(int i) => new HallFame3PKM(Parent, GetMemberOffset(i), Japanese); public HallFame3PKM[] Team { get { var team = new HallFame3PKM[6]; for (int i = 0; i < Count; i++) team[i] = GetMember(i); return team; } } private const int MaxEntries = 50; private const int MaxLength = MaxEntries * SIZE; public static HallFame3Entry[] GetEntries(SAV3 sav) { byte[] data = new byte[SAV3.SIZE_BLOCK_USED * 2]; Debug.Assert(data.Length > MaxLength); // HoF Data is split across two sav blocks Array.Copy(sav.Data, 0x1C000, data, 0, SAV3.SIZE_BLOCK_USED); Array.Copy(sav.Data, 0x1D000, data, SAV3.SIZE_BLOCK_USED, SAV3.SIZE_BLOCK_USED); bool Japanese = sav.Japanese; var entries = new HallFame3Entry[MaxEntries]; for (int i = 0; i < entries.Length; i++) entries[i] = new HallFame3Entry(data, SIZE, Japanese); return entries; } public static void SetEntries(SAV3 sav, HallFame3Entry[] entries) { byte[] data = entries[0].Team[0].Data; if (data.Length != MaxLength) throw new ArgumentException(nameof(data)); // HoF Data is split across two sav blocks Array.Copy(data, 0, sav.Data, 0x1C000, SAV3.SIZE_BLOCK_USED); Array.Copy(data, SAV3.SIZE_BLOCK_USED, sav.Data, 0x1D000, SAV3.SIZE_BLOCK_USED); } } public sealed class HallFame3PKM { public const int SIZE = 20; public HallFame3PKM(byte[] data, int offset, bool jp) { Data = data; Offset = offset; Japanese = jp; } public readonly byte[] Data; private readonly int Offset; private readonly bool Japanese; public int TID { get => BitConverter.ToUInt16(Data, 0 + Offset); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0 + Offset); } public int SID { get => BitConverter.ToUInt16(Data, 2 + Offset); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 2 + Offset); } public uint PID { get => BitConverter.ToUInt32(Data, 4 + Offset); set => BitConverter.GetBytes(value).CopyTo(Data, 4 + Offset); } private int SpecLevel { get => BitConverter.ToUInt16(Data, 8 + Offset); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 8 + Offset); } public string Nickname { get => GetString(Data, 10 + Offset, 10); set => SetString(value, 10).CopyTo(Data, 10 + Offset); } public int Species { get => SpecLevel & 0x1FF; set => SpecLevel = (SpecLevel & 0xFE00) | value; } public int Level { get => SpecLevel >> 9; set => SpecLevel = (SpecLevel & 0x1FF) | (value << 9); } private string GetString(byte[] data, int offset, int length) => StringConverter3.GetString3(data, offset, length, Japanese); private byte[] SetString(string value, int maxLength) => StringConverter3.SetString3(value, maxLength, Japanese, 10); } }