Extract interface for SaveBlock, allow strict

External users shouldn't be using SaveBlock
This commit is contained in:
Kurt 2022-04-15 11:45:04 -07:00
parent ac7947fd66
commit a681783f1a
122 changed files with 184 additions and 197 deletions

View File

@ -9,12 +9,12 @@ namespace PKHeX.Core
/// <typeparam name="T">Type of accessor</typeparam>
public sealed class SaveBlockMetadata<T>
{
private readonly Dictionary<SaveBlock, string> BlockList;
private readonly Dictionary<IDataIndirect, string> BlockList;
public SaveBlockMetadata(ISaveBlockAccessor<T> accessor)
{
var aType = accessor.GetType();
BlockList = aType.GetAllPropertiesOfType<SaveBlock>(accessor);
BlockList = aType.GetAllPropertiesOfType<IDataIndirect>(accessor);
}
public IEnumerable<string> GetSortedBlockList()
@ -22,6 +22,6 @@ public IEnumerable<string> GetSortedBlockList()
return BlockList.Select(z => z.Value).OrderBy(z => z);
}
public SaveBlock GetBlock(string name) => BlockList.First(z => z.Value == name).Key;
public IDataIndirect GetBlock(string name) => BlockList.First(z => z.Value == name).Key;
}
}

View File

@ -2,7 +2,7 @@
namespace PKHeX.Core
{
public abstract class RecordBlock : SaveBlock, IRecordStatStorage
public abstract class RecordBlock<T> : SaveBlock<T>, IRecordStatStorage where T : SaveFile
{
protected abstract IReadOnlyList<byte> RecordMax { get; }
public abstract int GetRecord(int recordID);
@ -12,11 +12,11 @@ public abstract class RecordBlock : SaveBlock, IRecordStatStorage
public int GetRecordOffset(int recordID) => Records.GetOffset(Offset, recordID);
public void AddRecord(int recordID, int count = 1) => SetRecord(recordID, GetRecord(recordID) + count);
protected RecordBlock(SaveFile sav) : base(sav)
protected RecordBlock(T sav) : base(sav)
{
}
protected RecordBlock(SaveFile sav, byte[] data) : base(sav, data)
protected RecordBlock(T sav, byte[] data) : base(sav, data)
{
}
}

View File

@ -90,12 +90,12 @@ private void LoadChanged(SCBlockAccessor s1, SCBlockAccessor s2, IEnumerable<uin
private static Dictionary<uint, string> GetKeyNames(SCBlockAccessor s1, IEnumerable<SCBlock> b1, IEnumerable<SCBlock> b2)
{
var aType = s1.GetType();
var b1n = aType.GetAllPropertiesOfType<SaveBlock>(s1);
var b1n = aType.GetAllPropertiesOfType<IDataIndirect>(s1);
var names = aType.GetAllConstantsOfType<uint>();
Add(b1n, b1);
Add(b1n, b2);
void Add(Dictionary<SaveBlock, string> list, IEnumerable<SCBlock> blocks)
void Add(Dictionary<IDataIndirect, string> list, IEnumerable<SCBlock> blocks)
{
foreach (var b in blocks)
{

View File

@ -11,7 +11,7 @@ namespace PKHeX.Core
/// </summary>
public sealed class SCBlockMetadata
{
private readonly Dictionary<SaveBlock, string> BlockList;
private readonly Dictionary<IDataIndirect, string> BlockList;
private readonly Dictionary<uint, string> ValueList;
private readonly SCBlockAccessor Accessor;
@ -22,7 +22,7 @@ public SCBlockMetadata(SCBlockAccessor accessor, IEnumerable<string> extraKeyNam
{
var aType = accessor.GetType();
BlockList = aType.GetAllPropertiesOfType<SaveBlock>(accessor);
BlockList = aType.GetAllPropertiesOfType<IDataIndirect>(accessor);
ValueList = aType.GetAllConstantsOfType<uint>();
AddExtraKeyNames(ValueList, extraKeyNames);
if (exclusions.Length > 0)
@ -95,7 +95,7 @@ private string GetBlockHint(SCBlock z, int index)
/// <param name="block">Block requesting the name of</param>
/// <param name="saveBlock">Block that shares the same backing byte array; null if none.</param>
/// <returns>Name of the block indicating the purpose that it serves in-game.</returns>
public string? GetBlockName(SCBlock block, out SaveBlock? saveBlock)
public string? GetBlockName(SCBlock block, out IDataIndirect? saveBlock)
{
// See if we have a Block object for this block
if (block.Data.Length != 0)

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core;
public sealed class BattleSubway5 : SaveBlock
public sealed class BattleSubway5 : SaveBlock<SAV5>
{
public BattleSubway5(SAV5BW sav, int offset) : base(sav) => Offset = offset;
public BattleSubway5(SAV5B2W2 sav, int offset) : base(sav) => Offset = offset;

View File

@ -2,7 +2,7 @@
namespace PKHeX.Core
{
public sealed class BoxLayout5 : SaveBlock
public sealed class BoxLayout5 : SaveBlock<SAV5>
{
public BoxLayout5(SAV5BW sav, int offset) : base(sav) => Offset = offset;
public BoxLayout5(SAV5B2W2 sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class Daycare5 : SaveBlock
public sealed class Daycare5 : SaveBlock<SAV5>
{
// struct daycareSlot
// bool32 occupied
@ -17,7 +17,7 @@ public sealed class Daycare5 : SaveBlock
public const int DaycareSeedSize = 16; // 8 bytes, b2w2 only
public Daycare5(SaveFile sav, int offset) : base(sav) => Offset = offset;
public Daycare5(SAV5 sav, int offset) : base(sav) => Offset = offset;
public ulong? GetSeed()
{

View File

@ -1,6 +1,6 @@
namespace PKHeX.Core
{
public abstract class Encount5 : SaveBlock
public abstract class Encount5 : SaveBlock<SAV5>
{
protected Encount5(SAV5 SAV, int offset) : base(SAV) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public abstract class Entralink5 : SaveBlock
public abstract class Entralink5 : SaveBlock<SAV5>
{
protected Entralink5(SAV5 SAV, int offset) : base(SAV) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public abstract class Misc5 : SaveBlock, IGymTeamInfo
public abstract class Misc5 : SaveBlock<SAV5>, IGymTeamInfo
{
protected Misc5(SAV5 sav, int offset) : base(sav) => Offset = offset;

View File

@ -1,6 +1,6 @@
namespace PKHeX.Core
{
public sealed class Musical5 : SaveBlock
public sealed class Musical5 : SaveBlock<SAV5>
{
public Musical5(SAV5BW SAV, int offset) : base(SAV) => Offset = offset;
public Musical5(SAV5B2W2 SAV, int offset) : base(SAV) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class MysteryBlock5 : SaveBlock
public sealed class MysteryBlock5 : SaveBlock<SAV5>
{
private const int FlagStart = 0;
private const int MaxReceivedFlag = 2048;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class PWTBlock5 : SaveBlock
public sealed class PWTBlock5 : SaveBlock<SAV5B2W2>
{
public PWTBlock5(SAV5B2W2 sav, int offset) : base(sav) => Offset = offset;

View File

@ -6,7 +6,7 @@ namespace PKHeX.Core
/// <summary>
/// Combined save block; 0x100 for first, 0x100 for second.
/// </summary>
public sealed class PlayerData5 : SaveBlock
public sealed class PlayerData5 : SaveBlock<SAV5>
{
public PlayerData5(SAV5BW sav, int offset) : base(sav) => Offset = offset;
public PlayerData5(SAV5B2W2 sav, int offset) : base(sav) => Offset = offset;

View File

@ -1,8 +1,9 @@
namespace PKHeX.Core
{
public sealed class BattleBox6 : SaveBlock
public sealed class BattleBox6 : SaveBlock<SAV6>
{
public BattleBox6(SaveFile SAV, int offset) : base(SAV) => Offset = offset;
public BattleBox6(SAV6XY SAV, int offset) : base(SAV) => Offset = offset;
public BattleBox6(SAV6AO SAV, int offset) : base(SAV) => Offset = offset;
private int LockedFlagOffset => Offset + (6 * PokeCrypto.SIZE_6STORED);

View File

@ -2,7 +2,7 @@
namespace PKHeX.Core
{
public sealed class BoxLayout6 : SaveBlock, IBoxDetailName, IBoxDetailWallpaper
public sealed class BoxLayout6 : SaveBlock<SAV6>, IBoxDetailName, IBoxDetailWallpaper
{
// gfstr5[31] boxNames;
// byte[31] wallpapers;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class ConfigSave6 : SaveBlock
public sealed class ConfigSave6 : SaveBlock<SAV6>
{
/* ===32 bits===
* talkSpeed:2 0,1

View File

@ -7,9 +7,10 @@ namespace PKHeX.Core
/// <summary>
/// Swarm and other overworld info
/// </summary>
public sealed class Encount6 : SaveBlock
public sealed class Encount6 : SaveBlock<SAV6>
{
public Encount6(SaveFile SAV, int offset) : base(SAV) => Offset = offset;
public Encount6(SAV6XY SAV, int offset) : base(SAV) => Offset = offset;
public Encount6(SAV6AO SAV, int offset) : base(SAV) => Offset = offset;
public ushort RepelItemUsed { get => ReadUInt16LittleEndian(Data.AsSpan(Offset + 0x00)); set => WriteUInt16LittleEndian(Data.AsSpan(Offset + 0x00), value); }
public byte RepelSteps { get => Data[Offset + 0x02]; set => Data[Offset + 0x02] = value; }

View File

@ -1,6 +1,6 @@
namespace PKHeX.Core
{
public sealed class Fashion6XY : SaveBlock
public sealed class Fashion6XY : SaveBlock<SAV6XY>
{
public Fashion6XY(SAV6XY sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,9 +3,10 @@
namespace PKHeX.Core
{
public sealed class GameTime6 : SaveBlock
public sealed class GameTime6 : SaveBlock<SAV6>
{
public GameTime6(SaveFile sav, int offset) : base(sav) => Offset = offset;
public GameTime6(SAV6 sav, int offset) : base(sav) => Offset = offset;
public int ResumeYear { get => ReadInt32LittleEndian(Data.AsSpan(Offset + 0x4)); set => WriteInt32LittleEndian(Data.AsSpan(Offset + 0x4), value); }
public int ResumeMonth { get => Data[Offset + 0x8]; set => Data[Offset + 0x8] = (byte)value; }
public int ResumeDay { get => Data[Offset + 0x9]; set => Data[Offset + 0x9] = (byte)value; }

View File

@ -3,9 +3,9 @@
namespace PKHeX.Core
{
public sealed class ItemInfo6 : SaveBlock
public sealed class ItemInfo6 : SaveBlock<SAV6>
{
public ItemInfo6(SaveFile sav, int offset) : base(sav) => Offset = offset;
public ItemInfo6(SAV6 sav, int offset) : base(sav) => Offset = offset;
private const int BoundItemCount = 4;
private const int RecentItemCount = 12;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class LinkBlock6 : SaveBlock
public sealed class LinkBlock6 : SaveBlock<SAV6>
{
public LinkBlock6(SAV6XY sav, int offset) : base(sav) => Offset = offset;
public LinkBlock6(SAV6AO sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class MaisonBlock : SaveBlock
public sealed class MaisonBlock : SaveBlock<SAV6>
{
public MaisonBlock(SAV6XY sav, int offset) : base(sav) => Offset = offset;
public MaisonBlock(SAV6AO sav, int offset) : base(sav) => Offset = offset;

View File

@ -8,7 +8,7 @@ public interface IMisc6
uint Money { get; set; }
}
public sealed class Misc6AO : SaveBlock, IMisc6
public sealed class Misc6AO : SaveBlock<SAV6>, IMisc6
{
public Misc6AO(SAV6AO sav, int offset) : base(sav) => Offset = offset;
public Misc6AO(SAV6AODemo sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class Misc6XY : SaveBlock, IMisc6
public sealed class Misc6XY : SaveBlock<SAV6XY>, IMisc6
{
public Misc6XY(SAV6XY sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,9 +3,9 @@
namespace PKHeX.Core
{
public class MyStatus6 : SaveBlock, IRegionOrigin
public class MyStatus6 : SaveBlock<SAV6>, IRegionOrigin
{
public MyStatus6(SaveFile sav, int offset) : base(sav) => Offset = offset;
public MyStatus6(SAV6 sav, int offset) : base(sav) => Offset = offset;
public int TID
{

View File

@ -9,7 +9,7 @@ namespace PKHeX.Core
/// <remarks>These properties are technically included in OR/AS but they are unused; assumed backwards compatibility for communications with XY</remarks>
public sealed class MyStatus6XY : MyStatus6
{
public MyStatus6XY(SaveFile sav, int offset) : base(sav, offset) { }
public MyStatus6XY(SAV6XY sav, int offset) : base(sav, offset) { }
public TrainerFashion6 Fashion
{

View File

@ -2,7 +2,7 @@
namespace PKHeX.Core
{
public sealed class MysteryBlock6 : SaveBlock
public sealed class MysteryBlock6 : SaveBlock<SAV6>
{
private const int FlagStart = 0;
private const int MaxReceivedFlag = 2048;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class OPower6 : SaveBlock
public sealed class OPower6 : SaveBlock<SAV6>
{
private static readonly OPowerFlagSet[] Mapping =
{
@ -32,7 +32,8 @@ public sealed class OPower6 : SaveBlock
new(3, Accuracy) {Offset = 62},
};
public OPower6(SaveFile sav, int offset) : base(sav) => Offset = offset;
public OPower6(SAV6XY sav, int offset) : base(sav) => Offset = offset;
public OPower6(SAV6AO sav, int offset) : base(sav) => Offset = offset;
private static OPowerFlagSet Get(OPower6Type type) => Array.Find(Mapping, t => t.Identifier == type);
public static int GetOPowerCount(OPower6Type type) => Get(type).BaseCount;

View File

@ -3,9 +3,10 @@
namespace PKHeX.Core
{
public sealed class PlayTime6 : SaveBlock
public sealed class PlayTime6 : SaveBlock<SaveFile>
{
public PlayTime6(SaveFile sav, int offset) : base(sav) => Offset = offset;
public PlayTime6(SAV6 sav, int offset) : base(sav) => Offset = offset;
public PlayTime6(SAV7 sav, int offset) : base(sav) => Offset = offset;
public int PlayedHours
{

View File

@ -3,12 +3,12 @@
namespace PKHeX.Core
{
public sealed class Puff6 : SaveBlock
public sealed class Puff6 : SaveBlock<SAV6>
{
private const int MaxPuffID = 26; // Supreme Winter Poké Puff
private const int PuffSlots = 100;
public Puff6(SaveFile SAV, int offset) : base(SAV) => Offset = offset;
public Puff6(SAV6 SAV, int offset) : base(SAV) => Offset = offset;
public byte[] GetPuffs() => SAV.GetData(Offset, PuffSlots);
public void SetPuffs(byte[] value) => SAV.SetData(value, Offset);

View File

@ -5,7 +5,7 @@
namespace PKHeX.Core
{
public sealed class RecordBlock6 : RecordBlock
public sealed class RecordBlock6 : RecordBlock<SaveFile> // 6 or 7
{
public const int RecordCount = 200;
protected override IReadOnlyList<byte> RecordMax { get; }

View File

@ -3,9 +3,9 @@
namespace PKHeX.Core
{
public sealed class SangoInfoBlock : SaveBlock
public sealed class SangoInfoBlock : SaveBlock<SAV6AO>
{
public SangoInfoBlock(SaveFile SAV, int offset) : base(SAV) => Offset = offset;
public SangoInfoBlock(SAV6AO SAV, int offset) : base(SAV) => Offset = offset;
private const uint EON_MAGIC = WC6.EonTicketConst;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class SecretBase6Block : SaveBlock
public sealed class SecretBase6Block : SaveBlock<SAV6AO>
{
public SecretBase6Block(SAV6AO sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,9 +3,9 @@
namespace PKHeX.Core
{
public sealed class Situation6 : SaveBlock
public sealed class Situation6 : SaveBlock<SAV6>
{
public Situation6(SaveFile SAV, int offset) : base(SAV) => Offset = offset;
public Situation6(SAV6 SAV, int offset) : base(SAV) => Offset = offset;
public int M
{

View File

@ -6,7 +6,7 @@ namespace PKHeX.Core
/// <summary>
/// SUBE block that stores in-game event results.
/// </summary>
public abstract class SubEventLog6 : SaveBlock, IGymTeamInfo
public abstract class SubEventLog6 : SaveBlock<SAV6>, IGymTeamInfo
{
protected SubEventLog6(SAV6 sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class SuperTrainBlock : SaveBlock
public sealed class SuperTrainBlock : SaveBlock<SAV6>
{
public SuperTrainBlock(SAV6XY sav, int offset) : base(sav) => Offset = offset;
public SuperTrainBlock(SAV6AO sav, int offset) : base(sav) => Offset = offset;

View File

@ -2,7 +2,7 @@
namespace PKHeX.Core
{
public sealed class BattleAgency7 : SaveBlock
public sealed class BattleAgency7 : SaveBlock<SAV7USUM>
{
public BattleAgency7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;

View File

@ -4,7 +4,7 @@
namespace PKHeX.Core
{
public sealed class BattleTree7 : SaveBlock
public sealed class BattleTree7 : SaveBlock<SAV7>
{
public BattleTree7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public BattleTree7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class BoxLayout7 : SaveBlock, IBoxDetailName, IBoxDetailWallpaper, ITeamIndexSet
public sealed class BoxLayout7 : SaveBlock<SAV7>, IBoxDetailName, IBoxDetailWallpaper, ITeamIndexSet
{
private const int BoxCount = 32;
@ -38,7 +38,6 @@ public void SetBoxWallpaper(int box, int value)
Data[GetBoxWallpaperOffset(box)] = (byte)value;
}
private Span<byte> GetBoxNameSpan(int box) => Data.AsSpan(GetBoxNameOffset(box), SAV6.LongStringLength);
private int GetBoxNameOffset(int box) => Offset + (SAV6.LongStringLength * box);
public string GetBoxName(int box) => SAV.GetString(GetBoxNameSpan(box));

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class ConfigSave7 : SaveBlock
public sealed class ConfigSave7 : SaveBlock<SAV7>
{
/* ===32 bits===
* talkSpeed:2 0,1

View File

@ -1,6 +1,6 @@
namespace PKHeX.Core
{
public sealed class Daycare7 : SaveBlock
public sealed class Daycare7 : SaveBlock<SAV7>
{
public const int DaycareSeedSize = 32; // 128 bits

View File

@ -2,7 +2,7 @@
namespace PKHeX.Core
{
public sealed class FashionBlock7 : SaveBlock
public sealed class FashionBlock7 : SaveBlock<SAV7>
{
public FashionBlock7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public FashionBlock7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class FieldMenu7 : SaveBlock
public sealed class FieldMenu7 : SaveBlock<SAV7>
{
public FieldMenu7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public FieldMenu7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class FieldMoveModelSave7 : SaveBlock
public sealed class FieldMoveModelSave7 : SaveBlock<SAV7>
{
public FieldMoveModelSave7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public FieldMoveModelSave7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,9 +3,9 @@
namespace PKHeX.Core
{
public sealed class GameTime7 : SaveBlock
public sealed class GameTime7 : SaveBlock<SAV7>
{
public GameTime7(SaveFile sav, int offset) : base(sav) => Offset = offset;
public GameTime7(SAV7 sav, int offset) : base(sav) => Offset = offset;
public int ResumeYear { get => ReadInt32LittleEndian(Data.AsSpan(Offset + 0x4)); set => WriteInt32LittleEndian(Data.AsSpan(Offset + 0x4), value); }
public int ResumeMonth { get => Data[Offset + 0x8]; set => Data[Offset + 0x8] = (byte)value; }
public int ResumeDay { get => Data[Offset + 0x9]; set => Data[Offset + 0x9] = (byte)value; }

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class HallOfFame7 : SaveBlock
public sealed class HallOfFame7 : SaveBlock<SAV7>
{
public HallOfFame7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public HallOfFame7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class JoinFesta7 : SaveBlock
public sealed class JoinFesta7 : SaveBlock<SAV7>
{
public JoinFesta7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public JoinFesta7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;
@ -17,7 +17,7 @@ public int FestaCoins
value = 9999999;
WriteInt32LittleEndian(Data.AsSpan(Offset + 0x508), value);
TotalFestaCoins = ((SAV7)SAV).GetRecord(038) + value; // UsedFestaCoins
TotalFestaCoins = SAV.GetRecord(038) + value; // UsedFestaCoins
}
}

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class CaptureRecords : SaveBlock
public sealed class CaptureRecords : SaveBlock<SAV7b>
{
public CaptureRecords(SAV7b sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class ConfigSave7b : SaveBlock
public sealed class ConfigSave7b : SaveBlock<SAV7b>
{
/* ===First 8 bits===
* talkSpeed:2

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class EventWork7b : SaveBlock, IEventVar<int>
public sealed class EventWork7b : SaveBlock<SAV7b>, IEventVar<int>
{
public EventWork7b(SAV7b sav, int offset) : base(sav)
{

View File

@ -5,11 +5,11 @@
namespace PKHeX.Core
{
public sealed class GoParkStorage : SaveBlock, IEnumerable<GP1>
public sealed class GoParkStorage : SaveBlock<SAV7b>, IEnumerable<GP1>
{
public GoParkStorage(SaveFile sav) : base(sav)
public GoParkStorage(SAV7b sav) : base(sav)
{
Offset = ((SAV7b)sav).Blocks.GetBlockOffset(BelugaBlockIndex.GoParkEntities);
Offset = sav.Blocks.GetBlockOffset(BelugaBlockIndex.GoParkEntities);
}
public const int SlotsPerArea = 50;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class Misc7b : SaveBlock
public sealed class Misc7b : SaveBlock<SAV7b>
{
public Misc7b(SAV7b sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class MyStatus7b : SaveBlock
public sealed class MyStatus7b : SaveBlock<SAV7b>
{
public MyStatus7b(SAV7b sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class PlayTime7b : SaveBlock
public sealed class PlayTime7b : SaveBlock<SAV7b>
{
public PlayTime7b(SAV7b sav, int offset) : base(sav) => Offset = offset;

View File

@ -15,7 +15,7 @@ namespace PKHeX.Core
/// u16 Starter Pointer: Indicates which index is the starter. <see cref="SLOT_EMPTY"/> if no starter yet.
/// u16 List Count: Points to the next empty slot, and indicates how many slots are stored in the list.
/// </remarks>
public sealed class PokeListHeader : SaveBlock
public sealed class PokeListHeader : SaveBlock<SAV7b>
{
/// <summary>
/// Raw representation of data, casted to ushort[].

View File

@ -2,7 +2,7 @@
namespace PKHeX.Core
{
public sealed class WB7Records : SaveBlock
public sealed class WB7Records : SaveBlock<SAV7b>
{
public WB7Records(SAV7b sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,10 +3,9 @@
namespace PKHeX.Core
{
public sealed class Misc7 : SaveBlock
public sealed class Misc7 : SaveBlock<SAV7>
{
public Misc7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public Misc7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;
public Misc7(SAV7 sav, int offset) : base(sav) => Offset = offset;
public uint Money
{

View File

@ -3,13 +3,12 @@
namespace PKHeX.Core
{
public sealed class MyStatus7 : SaveBlock, IRegionOrigin
public sealed class MyStatus7 : SaveBlock<SAV7>, IRegionOrigin
{
public const int GameSyncIDSize = 16; // 64 bits
public const int NexUniqueIDSize = 32; // 128 bits
public MyStatus7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public MyStatus7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;
public MyStatus7(SAV7 sav, int offset) : base(sav) => Offset = offset;
public int TID
{

View File

@ -2,7 +2,7 @@
namespace PKHeX.Core
{
public sealed class MysteryBlock7 : SaveBlock
public sealed class MysteryBlock7 : SaveBlock<SAV7>
{
private const int FlagStart = 0;
private const int MaxReceivedFlag = 2048;
@ -10,8 +10,7 @@ public sealed class MysteryBlock7 : SaveBlock
// private const int FlagRegionSize = (MaxReceivedFlag / 8); // 0x100
private const int CardStart = FlagStart + (MaxReceivedFlag / 8);
public MysteryBlock7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public MysteryBlock7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;
public MysteryBlock7(SAV7 sav, int offset) : base(sav) => Offset = offset;
// Mystery Gift
public bool[] MysteryGiftReceivedFlags

View File

@ -3,10 +3,9 @@
namespace PKHeX.Core
{
public sealed class PokeFinder7 : SaveBlock
public sealed class PokeFinder7 : SaveBlock<SAV7>
{
public PokeFinder7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public PokeFinder7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;
public PokeFinder7(SAV7 sav, int offset) : base(sav) => Offset = offset;
public ushort CameraVersion
{

View File

@ -2,10 +2,9 @@
namespace PKHeX.Core
{
public sealed class ResortSave7 : SaveBlock
public sealed class ResortSave7 : SaveBlock<SAV7>
{
public ResortSave7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public ResortSave7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;
public ResortSave7(SAV7 sav, int offset) : base(sav) => Offset = offset;
public const int ResortCount = 93;
public int GetResortSlotOffset(int slot) => Offset + 0x16 + (slot * PokeCrypto.SIZE_6STORED);

View File

@ -5,30 +5,14 @@ namespace PKHeX.Core;
/// <summary>
/// Base class for a savegame data reader.
/// </summary>
public abstract class SaveBlock
public abstract class SaveBlock<T> : IDataIndirect where T : SaveFile
{
[Browsable(false)]
public int Offset { get; protected init; }
public readonly byte[] Data;
protected readonly SaveFile SAV;
protected SaveBlock(SaveFile sav) => Data = (SAV = sav).Data;
protected SaveBlock(SaveFile sav, byte[] data)
{
SAV = sav;
Data = data;
}
}
public abstract class SaveBlock<T> where T : SaveFile
{
[Browsable(false)]
public int Offset { get; protected init; }
public readonly byte[] Data;
protected readonly T SAV;
protected SaveBlock(T sav) => Data = (SAV = sav).Data;
[Browsable(false)] public byte[] Data { get; }
[Browsable(false)] public int Offset { get; protected init; }
protected SaveBlock(T sav) : this(sav, sav.Data) { }
protected SaveBlock(T sav, byte[] data)
{
@ -36,3 +20,9 @@ protected SaveBlock(T sav, byte[] data)
Data = data;
}
}
public interface IDataIndirect
{
int Offset { get; }
byte[] Data { get; }
}

View File

@ -3,10 +3,9 @@
namespace PKHeX.Core
{
public sealed class Situation7 : SaveBlock
public sealed class Situation7 : SaveBlock<SAV7>
{
public Situation7(SAV7SM sav, int offset) : base(sav) => Offset = offset;
public Situation7(SAV7USUM sav, int offset) : base(sav) => Offset = offset;
public Situation7(SAV7 sav, int offset) : base(sav) => Offset = offset;
// "StartLocation"
public int M { get => ReadUInt16LittleEndian(Data.AsSpan(Offset + 0x00)); set => WriteUInt16LittleEndian(Data.AsSpan(Offset + 0x00), (ushort)value); }
@ -17,7 +16,7 @@ public sealed class Situation7 : SaveBlock
public void UpdateOverworldCoordinates()
{
var o = ((SAV7)SAV).Overworld;
var o = SAV.Overworld;
o.M = M;
o.X = X;
o.Z = Z;

View File

@ -10,7 +10,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size: 0x1B8</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class BattleTowerWork8b : SaveBlock
public sealed class BattleTowerWork8b : SaveBlock<SAV8BS>
{
private const int OFS_ClassData = 20;
private const int COUNT_CLASSDATA = 4;
@ -54,7 +54,6 @@ private static void SetRecords(IReadOnlyList<BattleTowerClassData8b> value)
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class BattleTowerClassData8b
{

View File

@ -8,7 +8,7 @@ namespace PKHeX.Core
/// Defeated Status for all trainers (Dpr.Trainer.TrainerID)
/// </summary>
/// <remarks>size: 0x1618</remarks>
public sealed class BattleTrainerStatus8b : SaveBlock
public sealed class BattleTrainerStatus8b : SaveBlock<SAV8BS>
{
public BattleTrainerStatus8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -9,7 +9,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size: 0x808</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class BerryTreeGrowSave8b : SaveBlock
public sealed class BerryTreeGrowSave8b : SaveBlock<SAV8BS>
{
public BerryTreeGrowSave8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -7,7 +7,7 @@ namespace PKHeX.Core
/// Information about the storage boxes.
/// </summary>
/// <remarks>Structure name: SaveBoxData, size: 0x64A</remarks>
public sealed class BoxLayout8b : SaveBlock, IBoxDetailName
public sealed class BoxLayout8b : SaveBlock<SAV8BS>, IBoxDetailName
{
public const int BoxCount = 40;

View File

@ -9,7 +9,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size 0x40, struct_name CONFIG</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class ConfigSave8b : SaveBlock
public sealed class ConfigSave8b : SaveBlock<SAV8BS>
{
public ConfigSave8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -9,7 +9,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size 0x720, struct_name CONTEST_DATA</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class Contest8b : SaveBlock
public sealed class Contest8b : SaveBlock<SAV8BS>
{
public const int SIZE_CONTEST_PHOTO = 0x16C;
public const int PHOTO_MAX = 5;

View File

@ -6,7 +6,7 @@ namespace PKHeX.Core;
/// Contest photo language data
/// </summary>
/// <remarks>CON_PHOTO_LANG_DATA size: 0x18</remarks>
public sealed class ContestPhotoLanguage8b : SaveBlock
public sealed class ContestPhotoLanguage8b : SaveBlock<SAV8BS>
{
// structure:
// 5 (Style, Beautiful, Cute, Clever, Strong) bytes of language IDs

View File

@ -9,7 +9,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size: 0x2C0</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class Daycare8b : SaveBlock
public sealed class Daycare8b : SaveBlock<SAV8BS>
{
public Daycare8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -10,7 +10,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size 0x188, struct_name ENC_SV_DATA</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class EncounterSave8b : SaveBlock
public sealed class EncounterSave8b : SaveBlock<SAV8BS>
{
public const int COUNT_HONEYTREE = 21;
private const int SIZE_HillBackData = 0x8;

View File

@ -8,7 +8,7 @@ namespace PKHeX.Core
/// size: 0xC
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class FieldGimmickSave8b : SaveBlock
public sealed class FieldGimmickSave8b : SaveBlock<SAV8BS>
{
public FieldGimmickSave8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -10,7 +10,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size: 0x109A0 (1000 * 4*17)</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class FieldObjectSave8b : SaveBlock
public sealed class FieldObjectSave8b : SaveBlock<SAV8BS>
{
private const int COUNT_OBJECTS = 1_000;

View File

@ -7,7 +7,7 @@ namespace PKHeX.Core
/// Structure that manages the 3 event variable storage arrays.
/// </summary>
/// <remarks>Comprised of 3 fixed-sized arrays, we do our read/write in-place. Each element in an array is 4 bytes. Total size: 0x55F0 </remarks>
public sealed class FlagWork8b : SaveBlock, IEventFlag, ISystemFlag, IEventWork<int>
public sealed class FlagWork8b : SaveBlock<SAV8BS>, IEventFlag, ISystemFlag, IEventWork<int>
{
public const int COUNT_WORK = 500;
public const int COUNT_FLAG = 4000;

View File

@ -8,7 +8,7 @@ namespace PKHeX.Core
/// Tracks the main menu items. Size: 0x44
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class MenuSelect8b : SaveBlock
public sealed class MenuSelect8b : SaveBlock<SAV8BS>
{
// (TopMenuItemTypeInt32, bool IsNew)[8], TopMenuItemTypeInt32 LastSelected
private const int COUNT_ITEMS = 8;

View File

@ -8,7 +8,7 @@ namespace PKHeX.Core
/// Player status and info about the trainer
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class MyStatus8b : SaveBlock
public sealed class MyStatus8b : SaveBlock<SAV8BS>
{
public const int MAX_MONEY = 999_999;
public const byte MAX_BADGE = 8;

View File

@ -10,7 +10,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size ???, struct_name CONTEST_DATA</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class MysteryBlock8b : SaveBlock
public sealed class MysteryBlock8b : SaveBlock<SAV8BS>
{
public MysteryBlock8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -3,7 +3,7 @@
/// <summary>
/// Party data storage and metadata
/// </summary>
public sealed class Party8b : SaveBlock
public sealed class Party8b : SaveBlock<SAV8BS>
{
public Party8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -8,7 +8,7 @@ namespace PKHeX.Core
/// Playtime storage
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class PlayTime8b : SaveBlock
public sealed class PlayTime8b : SaveBlock<SAV8BS>
{
public PlayTime8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -9,7 +9,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size 0x80, struct_name PLAYER_SAVE_DATA</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class PlayerData8b : SaveBlock
public sealed class PlayerData8b : SaveBlock<SAV8BS>
{
private const int SIZE_LOCATION = 4 + (4 * 3) + 4; // 20 (0x14)

View File

@ -11,7 +11,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size: 0x644</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class PoffinSaveData8b : SaveBlock
public sealed class PoffinSaveData8b : SaveBlock<SAV8BS>
{
public PoffinSaveData8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -7,7 +7,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size: 0x19C</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class Poketch8b : SaveBlock
public sealed class Poketch8b : SaveBlock<SAV8BS>
{
public const int APP_REGIST_MAX = 20; // bool array unlock flags
public const int POKETCH_MAP_MARK_MAX = 6; // mark_map_pos[6]

View File

@ -10,7 +10,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size: 0x630</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class RandomGroup8b : SaveBlock
public sealed class RandomGroup8b : SaveBlock<SAV8BS>
{
public const int COUNT_GROUP = 12;

View File

@ -7,7 +7,7 @@ namespace PKHeX.Core
/// Stores 12 different sets of record data, with the earliest entry being called the "head" record index.
/// </summary>
/// <remarks>size: 0x5A0 (12 * 4*30)</remarks>
public sealed class Record8b : SaveBlock, IRecordStatStorage
public sealed class Record8b : SaveBlock<SAV8BS>, IRecordStatStorage
{
public const int RecordIndexCount = 12; // There's a total of 12 uint[30] record entries. The head one is used, not sure about the others.
public const int RecordCount = 30;

View File

@ -7,7 +7,7 @@ namespace PKHeX.Core
/// Stores additional record data.
/// </summary>
/// <remarks>size: 0x3C0</remarks>
public sealed class RecordAddData8b : SaveBlock
public sealed class RecordAddData8b : SaveBlock<SAV8BS>
{
// RECORD_ADD_DATA: 0x30-sized[12] (0x240 bytes), and 12*byte[32] (0x180), total 0x3C0
public RecordAddData8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -8,7 +8,7 @@ namespace PKHeX.Core
/// Tracks the 4 select bound item slots. Size: 0x8 (4 * u16)
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class SaveItemShortcut8b : SaveBlock
public sealed class SaveItemShortcut8b : SaveBlock<SAV8BS>
{
public SaveItemShortcut8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -10,7 +10,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size 0x4288</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class SealBallDecoData8b : SaveBlock
public sealed class SealBallDecoData8b : SaveBlock<SAV8BS>
{
public const int COUNT_CAPSULE = 99; // CapsuleData[99]

View File

@ -7,7 +7,7 @@ namespace PKHeX.Core
/// Array storing all the seal sticker counts the player has collected.
/// </summary>
/// <remarks>size: 0x960</remarks>
public sealed class SealList8b : SaveBlock
public sealed class SealList8b : SaveBlock<SAV8BS>
{
public const int SealSaveSize = 200;
public const int SealMaxCount = 99;

View File

@ -9,7 +9,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size: 0x138</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class SystemData8b : SaveBlock
public sealed class SystemData8b : SaveBlock<SAV8BS>
{
// Structure:
// (u32 count, u64 FILETIME) Start Time

View File

@ -9,7 +9,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size 0x20, struct_name UgCountRecord</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class UgCountRecord8b : SaveBlock
public sealed class UgCountRecord8b : SaveBlock<SAV8BS>
{
public UgCountRecord8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -9,7 +9,7 @@ namespace PKHeX.Core
/// </summary>
/// <remarks>size: 0x27A0</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class UgSaveData8b : SaveBlock
public sealed class UgSaveData8b : SaveBlock<SAV8BS>
{
public const int COUNT_DIGPOINTS = 10;
public const int COUNT_ENCOUNTERS = 15;

View File

@ -3,7 +3,7 @@
namespace PKHeX.Core
{
public sealed class UndergroundItemList8b : SaveBlock
public sealed class UndergroundItemList8b : SaveBlock<SAV8BS>
{
public const int ItemSaveSize = 999;
public const int ItemMaxCount = 999;

View File

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
/// <remarks>UnionSaveData size: 0xC</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class UnionSaveData8b : SaveBlock
public sealed class UnionSaveData8b : SaveBlock<SAV8BS>
{
public UnionSaveData8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -7,7 +7,7 @@ namespace PKHeX.Core;
/// Tracks <see cref="Species.Spinda"/> data for the game.
/// </summary>
/// <remarks>ZUKAN_PERSONAL_RND_DATA size: 0x64 (100)</remarks>
public sealed class ZukanSpinda8b : SaveBlock
public sealed class ZukanSpinda8b : SaveBlock<SAV8BS>
{
public ZukanSpinda8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;

View File

@ -8,9 +8,9 @@ namespace PKHeX.Core;
/// Stores the <see cref="Timestamp"/> when the player created their save data.
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class AdventureStart8a : SaveBlock
public sealed class AdventureStart8a : SaveBlock<SAV8LA>
{
public AdventureStart8a(SaveFile sav, SCBlock block) : base(sav, block.Data) { }
public AdventureStart8a(SAV8LA sav, SCBlock block) : base(sav, block.Data) { }
/// <summary>
/// time_t (seconds since 1970 Epoch)

View File

@ -7,7 +7,7 @@ namespace PKHeX.Core;
/// Exposes information about Box Names and which box is the first box to show when the UI is opened.
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class BoxLayout8a : SaveBlock, IBoxDetailName
public sealed class BoxLayout8a : SaveBlock<SAV8LA>, IBoxDetailName
{
public const int BoxCount = 32;
@ -28,7 +28,7 @@ public sealed class BoxLayout8a : SaveBlock, IBoxDetailName
public int CurrentBox
{
get => ((SAV8LA)SAV).GetValue<byte>(SaveBlockAccessor8LA.KCurrentBox);
set => ((SAV8LA)SAV).SetValue(SaveBlockAccessor8LA.KCurrentBox, (byte)value);
get => SAV.GetValue<byte>(SaveBlockAccessor8LA.KCurrentBox);
set => SAV.SetValue(SaveBlockAccessor8LA.KCurrentBox, (byte)value);
}
}

View File

@ -7,9 +7,9 @@ namespace PKHeX.Core;
/// Stores the position of the player.
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class Coordinates8a : SaveBlock
public sealed class Coordinates8a : SaveBlock<SAV8LA>
{
public Coordinates8a(SaveFile sav, SCBlock block) : base(sav, block.Data) { }
public Coordinates8a(SAV8LA sav, SCBlock block) : base(sav, block.Data) { }
public float X { get => ReadSingleLittleEndian(Data.AsSpan(Offset + 0x50)); set => WriteSingleLittleEndian(Data.AsSpan(Offset + 0x50), value); }
public float Z { get => ReadSingleLittleEndian(Data.AsSpan(Offset + 0x54)); set => WriteSingleLittleEndian(Data.AsSpan(Offset + 0x54), value); }
public float Y { get => ReadSingleLittleEndian(Data.AsSpan(Offset + 0x58)); set => WriteSingleLittleEndian(Data.AsSpan(Offset + 0x58), value); }

View File

@ -12,9 +12,9 @@ namespace PKHeX.Core;
/// Month value is offset by -1.
/// </remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class LastSaved8a : SaveBlock
public sealed class LastSaved8a : SaveBlock<SAV8LA>
{
public LastSaved8a(SaveFile sav, SCBlock block) : base(sav, block.Data) { }
public LastSaved8a(SAV8LA sav, SCBlock block) : base(sav, block.Data) { }
private uint LastSaved { get => ReadUInt32LittleEndian(Data.AsSpan(Offset + 0x0)); set => WriteUInt32LittleEndian(Data.AsSpan(Offset + 0x0), value); }
private int LastSavedYear { get => (int)(LastSaved & 0xFFF); set => LastSaved = (LastSaved & 0xFFFFF000) | (uint)value; }
private int LastSavedMonth { get => (int)(LastSaved >> 12 & 0xF); set => LastSaved = (LastSaved & 0xFFFF0FFF) | ((uint)value & 0xF) << 12; }

Some files were not shown because too many files have changed in this diff Show More