diff --git a/PKHeX.Core/Saves/Substructures/Gen8/BS/BattleTowerWork8b.cs b/PKHeX.Core/Saves/Substructures/Gen8/BS/BattleTowerWork8b.cs
index 8e28430f2..3088b824a 100644
--- a/PKHeX.Core/Saves/Substructures/Gen8/BS/BattleTowerWork8b.cs
+++ b/PKHeX.Core/Saves/Substructures/Gen8/BS/BattleTowerWork8b.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using System.ComponentModel;
namespace PKHeX.Core
@@ -6,10 +7,13 @@ namespace PKHeX.Core
///
/// Stores progress within the Battle Tower for the four battle modes.
///
- /// size: ???
+ /// size: 0x1B8
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class BattleTowerWork8b : SaveBlock
{
+ private const int OFS_ClassData = 20;
+ private const int COUNT_CLASSDATA = 4;
+
public BattleTowerWork8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;
// Structure:
@@ -18,13 +22,80 @@ public sealed class BattleTowerWork8b : SaveBlock
// int old_playmode;
// uint btl_point;
// uint day_challeng_cnt;
- // BTLTOWER_CLASSDATA[] class_data; // 0x18
+ // BTLTOWER_CLASSDATA[4] class_data;
// uint challenge_cnt;
public int MasterRankMax { get => BitConverter.ToInt32(Data, Offset + 0x0); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x0); } // max_master_rank
public int PlayMode { get => BitConverter.ToInt32(Data, Offset + 0x4); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x4); }// play_mode
public int PlayModeOld { get => BitConverter.ToInt32(Data, Offset + 0x8); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x8); } // old_playmode
public uint BP { get => BitConverter.ToUInt32(Data, Offset + 0xC); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0xC); } // btl_point
- // class_data appears to be an array of 4, sized 0x68 each. There's 2 fields at the end instead of 2, dunno.
+ public uint ChallengeCount { get => BitConverter.ToUInt32(Data, Offset + 0x1B4); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x1B4); } // challenge_cnt
+
+ public BattleTowerClassData8b[] Records
+ {
+ get => GetRecords();
+ set => SetRecords(value);
+ }
+
+ private BattleTowerClassData8b[] GetRecords()
+ {
+ var result = new BattleTowerClassData8b[COUNT_CLASSDATA];
+ for (int i = 0; i < result.Length; i++)
+ result[i] = new BattleTowerClassData8b(Data, Offset + OFS_ClassData + (i * BattleTowerClassData8b.SIZE));
+ return result;
+ }
+
+ private static void SetRecords(IReadOnlyList value)
+ {
+ if (value.Count != COUNT_CLASSDATA)
+ throw new ArgumentOutOfRangeException(nameof(value.Count));
+ // data is already hard-referencing the original byte array. This is mostly a hack for Property Grid displays.
+ }
+ }
+
+
+ [TypeConverter(typeof(ExpandableObjectConverter))]
+ public sealed class BattleTowerClassData8b
+ {
+ public const int SIZE = 0x68;
+
+ private readonly int Offset;
+ private readonly byte[] Data;
+
+ public BattleTowerClassData8b(byte[] data, int offset)
+ {
+ Data = data;
+ Offset = offset;
+ }
+
+ public override string ToString() => $"Rank: {Rank}, Streak: {RenshouCount} (Max {RenshouCountOld}), Wins: {TotalWins}|{TotalWinsLoop}|{TotalWinsLose}";
+
+ public byte Cleared
+ {
+ get => Data[Offset + 0x00];
+ set => Data[Offset]= value;
+ }
+ public bool Suspended
+ {
+ get => BitConverter.ToInt32(Data, Offset + 0x04) == 1;
+ set => BitConverter.GetBytes(value ? 1u : 0u).CopyTo(Data, Offset + 0x04);
+ }
+ public ulong BattlePlaySeed { get => BitConverter.ToUInt64(Data, Offset + 0x08); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x08); }
+ public uint Rank { get => BitConverter.ToUInt32(Data, Offset + 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x10); }
+ public uint RankDownLose { get => BitConverter.ToUInt32(Data, Offset + 0x14); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x14); }
+
+ public ulong TrainerSeed1 { get => BitConverter.ToUInt64(Data, Offset + 0x1C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x1C); }
+ public ulong TrainerSeed2 { get => BitConverter.ToUInt64(Data, Offset + 0x24); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x24); }
+ public ulong TrainerSeed3 { get => BitConverter.ToUInt64(Data, Offset + 0x2C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x2C); }
+ public ulong TrainerSeed4 { get => BitConverter.ToUInt64(Data, Offset + 0x34); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x34); }
+ public ulong TrainerSeed5 { get => BitConverter.ToUInt64(Data, Offset + 0x3C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x3C); }
+ public ulong TrainerSeed6 { get => BitConverter.ToUInt64(Data, Offset + 0x44); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x44); }
+ public ulong TrainerSeed7 { get => BitConverter.ToUInt64(Data, Offset + 0x4C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x4C); }
+
+ public uint TotalWins { get => BitConverter.ToUInt32(Data, Offset + 0x54); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x54); }
+ public uint TotalWinsLoop { get => BitConverter.ToUInt32(Data, Offset + 0x58); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x58); }
+ public uint TotalWinsLose { get => BitConverter.ToUInt32(Data, Offset + 0x5C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x5C); }
+ public uint RenshouCountOld { get => BitConverter.ToUInt32(Data, Offset + 0x60); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x60); }
+ public uint RenshouCount { get => BitConverter.ToUInt32(Data, Offset + 0x64); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x64); }
}
}