diff --git a/PKHeX.Core/Saves/Substructures/Gen6/SuperTrainBlock.cs b/PKHeX.Core/Saves/Substructures/Gen6/SuperTrainBlock.cs
index 491396bcf..2e9530761 100644
--- a/PKHeX.Core/Saves/Substructures/Gen6/SuperTrainBlock.cs
+++ b/PKHeX.Core/Saves/Substructures/Gen6/SuperTrainBlock.cs
@@ -8,29 +8,80 @@ public class SuperTrainBlock : SaveBlock
public SuperTrainBlock(SAV6AO sav, int offset) : base(sav) => Offset = offset;
// Structure:
- // 8 bytes ??? (flags?)
+ // 6 bytes stage unlock flags
+ // 1 byte distribution stage unlock flags
+ // 1 byte counter (max value = 10)
// float[48] recordScore1; // 0x08, 4byte/entry
// float[48] recordScore2; // 0xC8, 4byte/entry
// SS-F-G[48] recordHolder1; // 0x188, 4byte/entry
// SS-F-G[48] recordHolder2; // 0x248, 4byte/entry
- // byte[12] bags? // 0x308
- // u32 ??? // 0x314
+ // byte[12] bags // 0x308
+ // u32 tutorial tracker (max value = 6) // 0x314
// 0x318 total size
// SS-F-G = u16 species, u8 form, u8 gender
private const int MAX = 48;
+ private const int MAX_RELEASED = 32;
+ private const int MAX_DIST = 6;
+ private const int MAX_BAG = 12;
- public byte[] Bytes8
+ ///
+ /// Checks if a Regimen is unlocked.
+ ///
+ /// Index of regimen.
+ /// Is Unlocked
+ public bool GetIsRegimenUnlocked(int index)
{
- get => Data.Slice(Offset + 0, 8);
- set
- {
- if (value.Length != 8)
- throw new ArgumentException(nameof(value));
- value.CopyTo(Data, Offset + 0);
- }
+ if ((uint)index >= MAX)
+ throw new ArgumentException(nameof(index));
+ return SAV.GetFlag(Offset, index);
+ }
+
+ ///
+ /// Sets a Regimen to the desired unlocked state.
+ ///
+ /// Index of regimen.
+ /// Is Unlocked
+ public void SetIsRegimenUnlocked(int index, bool value)
+ {
+ if ((uint)index >= MAX)
+ throw new ArgumentException(nameof(index));
+ SAV.SetFlag(Offset, index, value);
+ }
+
+ ///
+ /// Checks if a Distribution Regimen is unlocked.
+ ///
+ /// Index of regimen.
+ /// Is Unlocked
+ public bool GetIsDistributionUnlocked(int index)
+ {
+ if ((uint)index >= MAX_DIST)
+ throw new ArgumentException(nameof(index));
+ return SAV.GetFlag(Offset + 6, index);
+ }
+
+ ///
+ /// Sets a Distribution Regimen to the desired unlocked state.
+ ///
+ /// Index of regimen.
+ /// Is Unlocked
+ public void SetIsDistributionUnlocked(int index, bool value)
+ {
+ if ((uint)index >= MAX_DIST)
+ throw new ArgumentException(nameof(index));
+ SAV.SetFlag(Offset + 6, index, value);
+ }
+
+ ///
+ /// Counts something up to 10 (overall stages unlocked?)
+ ///
+ public byte Counter
+ {
+ get => Data[Offset + 7];
+ set => Data[Offset + 7] = Math.Min((byte)10, value);
}
///
@@ -109,34 +160,75 @@ public SuperTrainingSpeciesRecord GetHolder2(int index)
return new SuperTrainingSpeciesRecord(Data, Offset + 0x248 + (4 * index));
}
- public byte[] Bags
- {
- get => Data.Slice(Offset + 0x308, 12);
- set
- {
- if (value.Length != 12)
- throw new ArgumentException(nameof(value));
- value.CopyTo(Data, Offset + 0x308);
- }
- }
-
+ ///
+ /// Gets the bag from the desired .
+ ///
+ /// Bag index
public byte GetBag(int index)
{
- if ((uint)index >= 12)
+ if ((uint)index >= MAX_BAG)
throw new ArgumentException(nameof(index));
return Data[Offset + 0x308 + index];
}
+ ///
+ /// Sets a bag to the desired .
+ ///
+ /// Bag index
+ /// Bag ID
public void SetBag(int index, byte value)
{
- if ((uint)index >= 12)
+ if ((uint)index >= MAX_BAG)
throw new ArgumentException(nameof(index));
Data[Offset + 0x308 + index] = value;
}
- public void ClearBag(int index) => SetBag(index, 0);
+ ///
+ /// Gets the next open bag index.
+ ///
+ /// Bag index that is empty
+ public int GetOpenBagIndex()
+ {
+ for (int i = 0; i < MAX_BAG; i++)
+ {
+ if (GetBag(i) != 0)
+ return i;
+ }
- public uint EndValue
+ return -1;
+ }
+
+ ///
+ /// Adds a bag to the list of bags.
+ ///
+ /// Bag type
+ /// Bag was added or not
+ public bool AddBag(byte bag)
+ {
+ int index = GetOpenBagIndex();
+ if (index < 0)
+ return false;
+ SetBag(index, bag);
+ return true;
+ }
+
+ ///
+ /// Removes a bag from the list of bags.
+ ///
+ /// Bag index
+ public void RemoveBag(int index)
+ {
+ if ((uint)index >= MAX_BAG)
+ throw new ArgumentException(nameof(index));
+ for (int i = index; i < MAX_BAG - 1; i++)
+ {
+ var next = GetBag(i + 1);
+ SetBag(i, next);
+ }
+ SetBag(MAX_BAG - 1, 0);
+ }
+
+ public uint TutorialIndex
{
get => BitConverter.ToUInt32(Data, Offset + 0x314);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x314);
@@ -167,6 +259,27 @@ public void ClearRecord2(int index)
SetTime2(index, 0f);
GetHolder2(index).Clear();
}
+
+ ///
+ /// Unlocks all stages.
+ ///
+ /// Unlock all Distribution stages too.
+ public void UnlockAllStages(bool dist)
+ {
+ for (int i = 0; i < MAX_RELEASED; i++)
+ SetIsRegimenUnlocked(i, true);
+
+ if (!dist)
+ return;
+
+ for (int i = 0; i < MAX_DIST; i++)
+ SetIsDistributionUnlocked(i, true);
+ }
+
+ ///
+ /// Clears all data in the block.
+ ///
+ public void ClearBlock() => Array.Clear(Data, Offset, 0x318);
}
public class SuperTrainingSpeciesRecord
@@ -212,5 +325,16 @@ public byte Gender
/// Wipes the record holder's pkm-related data.
///
public void Clear() => Species = AltForm = Gender = 0;
+
+ ///
+ /// Sets the data to match what is in the provided reference.
+ ///
+ /// Reference to load from.
+ public void LoadFrom(PKM pkm)
+ {
+ Species = (ushort)pkm.Species;
+ AltForm = (byte)pkm.AltForm;
+ Gender = (byte)pkm.Gender;
+ }
}
}
\ No newline at end of file