Add ENC_SV_DATA, PLAYER_SAVE_DATA, capsules, UgCountRecord

This commit is contained in:
Kurt 2021-11-26 01:21:38 -08:00
parent b7c9993bac
commit b50791530c
5 changed files with 457 additions and 8 deletions

View file

@ -37,9 +37,9 @@ namespace PKHeX.Core
// 0x7E9F8 - Menu selections (TopMenuItemTypeInt32, bool IsNew)[8], TopMenuItemTypeInt32 LastSelected
// 0x7EA3C - _FIELDOBJ_SAVE Objects[1000] (sizeof (0x44, 17 int fields), total size 0x109A0
Records = new Record8b(this, 0x8F3DC); // size: 0x78 * 12
// 0x8F97C - ENC_SV_DATA; 21 honey trees, 3 sway grass info, 2 mvpoke
// PLAYER_SAVE_DATA
// SaveBallDecoData CapsuleData[99], AffixSealData[20]
Encounter = new EncounterSave8b(this, 0x8F97C); // size: 0x188
Player = new PlayerData8b(this, 0x8FB04); // 0x80
SealDeco = new SealBallDecoData8b(this, 0x8FB84); // size: 0x4288
SealList = new SealList8b(this, 0x93E0C); // size: 0x960 SaveSealData[200]
// _RANDOM_GROUP
// FieldGimmickSaveData; int[3] gearRotate
@ -56,13 +56,13 @@ namespace PKHeX.Core
UgSaveData = new UgSaveData8b(this, 0x9A89C); // size: 0x27A0
// 0x9D03C - GMS_DATA // size: 0x31304, (GMS_POINT_DATA[650], ushort, ushort, byte)?; substructure GMS_POINT_HISTORY_DATA[5]
// 0xCE340 - PLAYER_NETWORK_DATA; bcatFlagArray byte[1300]
// UnionSaveData
// CON_PHOTO_LANG_DATA -- contest photo language data; photo_data[5], photo_fx[5]
// 0xCEA10(?) - UnionSaveData
// 0xCEA1C(?) - CON_PHOTO_LANG_DATA -- contest photo language data; photo_data[5], photo_fx[5]
// ZUKAN_PERSONAL_RND_DATA -- Spinda PID storage; uint[4] see, uint[4] get, uint[17] reserve
// CON_PHOTO_EXT_DATA[5]
// GMS_POINT_HISTORY_EXT_DATA[]
// UgCountRecord
// ReBuffnameData
// GMS_POINT_HISTORY_EXT_DATA[3250]
UgCount = new UgCountRecord8b(this, 0xE8178); // size: 0x20
// 0xE8198 - ReBuffnameData; RE_DENDOU_RECORD[30], RE_DENDOU_POKEMON_DATA_INSIDE[6] (0x20) = 0x1680
// 0xE9818 -- 0x10 byte[] MD5 hash of all savedata;
// v1.1 additions
@ -192,6 +192,9 @@ namespace PKHeX.Core
public Zukan8b Zukan { get; }
public BattleTrainerStatus8b BattleTrainer { get; }
public Record8b Records { get; }
public EncounterSave8b Encounter { get; }
public PlayerData8b Player { get; }
public SealBallDecoData8b SealDeco { get; }
public SealList8b SealList { get; }
public BerryTreeGrowSave8b BerryTrees { get; }
public PoffinSaveData8b Poffins { get; }
@ -200,6 +203,7 @@ namespace PKHeX.Core
public Poketch8b Poketch { get; }
public Daycare8b Daycare { get; }
public UgSaveData8b UgSaveData { get; }
public UgCountRecord8b UgCount { get; }
// First Savedata Expansion!
public RecordAddData8b RecordAdd { get; }

View file

@ -0,0 +1,186 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace PKHeX.Core
{
/// <summary>
/// Encounter Save Data
/// </summary>
/// <remarks>size 0x188, struct_name ENC_SV_DATA</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class EncounterSave8b : SaveBlock
{
public const int COUNT_HONEYTREE = 21;
private const int SIZE_HillBackData = 0x8;
private const int SIZE_HoneyTree = 8 + 4 + (COUNT_HONEYTREE * HoneyTree8b.SIZE); // 0x108
private const int SIZE_Roamer = 0x20;
private const int SIZE_Closing = 10 + 2; // 2 padding alignment
private const int OFS_HillBackData = 0xC;
private const int OFS_HoneyTree = OFS_HillBackData + SIZE_HillBackData; // 0x14
private const int OFS_SWAY = OFS_HoneyTree + SIZE_HoneyTree; // 0x11C
private const int OFS_ZONEHISTORY = OFS_SWAY + (4 * 6); // 0x134
private const int OFS_ROAM1 = OFS_ZONEHISTORY + 4 + 4; // 0x13C
private const int OFS_ROAM2 = OFS_ROAM1 + SIZE_Roamer; // 0x15C
private const int OFS_CLOSING = OFS_ROAM2 + SIZE_Roamer; // 0x17C
private const int SIZE = OFS_CLOSING + SIZE_Closing; // 0x188
public EncounterSave8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;
public void Clear() => Data.AsSpan(Offset, SIZE).Clear();
public int EncounterWalkCount
{
get => BitConverter.ToInt32(Data, Offset + 0x00);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x00);
}
public int SafariRandSeed
{
get => BitConverter.ToInt32(Data, Offset + 0x04);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x04);
}
public int GenerateRandSeed
{
get => BitConverter.ToInt32(Data, Offset + 0x08);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x08);
}
// HILL_BACK_DATA
public bool HillTalkFlag
{
get => BitConverter.ToUInt32(Data, Offset + OFS_HillBackData + 0x00) == 1;
set => BitConverter.GetBytes(value ? 1u : 0).CopyTo(Data, Offset + OFS_HillBackData + 0x00);
}
public ushort HillEncTblIdx1
{
get => BitConverter.ToUInt16(Data, Offset + OFS_HillBackData + 0x04);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_HillBackData + 0x04);
}
public ushort HillEncTblIdx2
{
get => BitConverter.ToUInt16(Data, Offset + OFS_HillBackData + 0x06);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_HillBackData + 0x06);
}
// HONEY_TREE
public long HoneyLastUpdateMinutes
{
get => BitConverter.ToInt64(Data, Offset + OFS_HoneyTree + 0x00);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_HoneyTree + 0x00);
}
public byte HoneyTreeNo
{
get => Data[Offset + OFS_HoneyTree + 0x08];
set => Data[Offset + OFS_HoneyTree + 0x08] = value;
}
#pragma warning disable CA1819 // Properties should not return arrays
public HoneyTree8b[] HoneyTrees
{
get => GetTrees();
set => SetTrees(value);
}
#pragma warning restore CA1819 // Properties should not return arrays
private HoneyTree8b[] GetTrees()
{
var result = new HoneyTree8b[COUNT_HONEYTREE];
for (int i = 0; i < result.Length; i++)
result[i] = new HoneyTree8b(Data, Offset + OFS_HoneyTree + 0xC + (i * HoneyTree8b.SIZE));
return result;
}
private static void SetTrees(IReadOnlyList<HoneyTree8b> value)
{
if (value.Count != COUNT_HONEYTREE)
throw new ArgumentOutOfRangeException(nameof(value.Count));
// data is already hard-referencing the original byte array. This is mostly a hack for Property Grid displays.
}
public uint Radar1Species { get => BitConverter.ToUInt32(Data, Offset + OFS_SWAY + 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_SWAY + 0x00); }
public uint Radar1Chain { get => BitConverter.ToUInt32(Data, Offset + OFS_SWAY + 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_SWAY + 0x04); }
public uint Radar2Species { get => BitConverter.ToUInt32(Data, Offset + OFS_SWAY + 0x08); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_SWAY + 0x08); }
public uint Radar2Chain { get => BitConverter.ToUInt32(Data, Offset + OFS_SWAY + 0x0C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_SWAY + 0x0C); }
public uint Radar3Species { get => BitConverter.ToUInt32(Data, Offset + OFS_SWAY + 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_SWAY + 0x10); }
public uint Radar3Chain { get => BitConverter.ToUInt32(Data, Offset + OFS_SWAY + 0x14); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_SWAY + 0x14); }
public int BeforeZone { get => BitConverter.ToInt32(Data, Offset + OFS_ZONEHISTORY + 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ZONEHISTORY + 0x00); }
public int OldZone { get => BitConverter.ToInt32(Data, Offset + OFS_ZONEHISTORY + 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ZONEHISTORY + 0x04); }
public int Roamer1ZoneID { get => BitConverter.ToInt32 (Data, Offset + OFS_ROAM1 + 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ROAM1 + 0x00); }
public ulong Roamer1Seed { get => BitConverter.ToUInt64(Data, Offset + OFS_ROAM1 + 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ROAM1 + 0x04); }
public uint Roamer1Species { get => BitConverter.ToUInt32(Data, Offset + OFS_ROAM1 + 0x0C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ROAM1 + 0x0C); }
public uint Roamer1HP { get => BitConverter.ToUInt32(Data, Offset + OFS_ROAM1 + 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ROAM1 + 0x10); }
public byte Roamer1Level { get => Data[Offset + OFS_ROAM1 + 0x14]; set => Data[Offset + OFS_ROAM1 + 0x14] = value; }
public uint Roamer1Status { get => BitConverter.ToUInt32(Data, Offset + OFS_ROAM1 + 0x18); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ROAM1 + 0x18); }
public byte Roamer1Encount { get => Data[Offset + OFS_ROAM1 + 0x1C]; set => Data[Offset + OFS_ROAM1 + 0x1C] = value; }
public int Roamer2ZoneID { get => BitConverter.ToInt32 (Data, Offset + OFS_ROAM2 + 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ROAM2 + 0x00); }
public ulong Roamer2Seed { get => BitConverter.ToUInt64(Data, Offset + OFS_ROAM2 + 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ROAM2 + 0x04); }
public uint Roamer2Species { get => BitConverter.ToUInt32(Data, Offset + OFS_ROAM2 + 0x0C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ROAM2 + 0x0C); }
public uint Roamer2HP { get => BitConverter.ToUInt32(Data, Offset + OFS_ROAM2 + 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ROAM2 + 0x10); }
public byte Roamer2Level { get => Data[Offset + OFS_ROAM2 + 0x14]; set => Data[Offset + OFS_ROAM2 + 0x14] = value; }
public uint Roamer2Status { get => BitConverter.ToUInt32(Data, Offset + OFS_ROAM2 + 0x18); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_ROAM2 + 0x18); }
public byte Roamer2Encount { get => Data[Offset + OFS_ROAM2 + 0x1C]; set => Data[Offset + OFS_ROAM2 + 0x1C] = value; }
public bool GenerateValid
{
get => BitConverter.ToUInt32(Data, Offset + OFS_CLOSING + 0) == 1;
set => BitConverter.GetBytes(value ? 1u : 0).CopyTo(Data, Offset + OFS_CLOSING + 0);
}
public short SprayCount
{
get => BitConverter.ToInt16(Data, Offset + OFS_CLOSING + 4);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_CLOSING + 4);
}
public byte SprayType { get => Data[Offset + OFS_CLOSING + 6]; set => Data[Offset + OFS_CLOSING + 6] = value; }
public byte VsSeekerCharge { get => Data[Offset + OFS_CLOSING + 7]; set => Data[Offset + OFS_CLOSING + 7] = value; } // max 100
public byte PokeRadarCharge { get => Data[Offset + OFS_CLOSING + 8]; set => Data[Offset + OFS_CLOSING + 8] = value; } // max 50
public byte FluteType { get => Data[Offset + OFS_CLOSING + 9]; set => Data[Offset + OFS_CLOSING + 9] = value; } // vidro
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public class HoneyTree8b
{
public const int SIZE = 0xC;
private readonly int Offset;
private readonly byte[] Data;
public HoneyTree8b(byte[] data, int offset)
{
Data = data;
Offset = offset;
}
public bool Spreaded
{
get => BitConverter.ToUInt32(Data, Offset + 0x00) == 1;
set => BitConverter.GetBytes(value ? 1u : 0).CopyTo(Data, Offset + 0x00);
}
public int Minutes
{
get => BitConverter.ToInt32(Data, Offset + 0x04);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x04);
}
public byte TblMonsNo
{
get => Data[Offset + 0x08];
set => Data[Offset + 0x08] = value;
}
public byte RareLv
{
get => Data[Offset + 0x09];
set => Data[Offset + 0x09] = value;
}
public byte SwayLv
{
get => Data[Offset + 0x0A];
set => Data[Offset + 0x0A] = value;
}
// 0xB alignment
}
}

View file

@ -0,0 +1,95 @@
using System;
using System.ComponentModel;
namespace PKHeX.Core
{
/// <summary>
/// Player Map Location Save Data
/// </summary>
/// <remarks>size 0x80, struct_name PLAYER_SAVE_DATA</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class PlayerData8b : SaveBlock
{
private const int SIZE_LOCATION = 4 + (4 * 3) + 4; // 20 (0x14)
private const int OFS_LOC1 = 0x10;
private const int OFS_LOC2 = OFS_LOC1 + SIZE_LOCATION;
private const int OFS_LOC3 = OFS_LOC2 + SIZE_LOCATION;
private const int OFS_PART2 = OFS_LOC3 + SIZE_LOCATION;
private const int OFS_MAP = OFS_PART2 + 4 + 4;
private const int OFS_TOKUSHU_BOOL = OFS_MAP + SIZE_LOCATION;
private const int OFS_TOKUSHU = OFS_TOKUSHU_BOOL + 4;
private const int SIZE = OFS_TOKUSHU + SIZE_LOCATION; // 0x80
public PlayerData8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;
public void Clear() => Data.AsSpan(Offset, SIZE).Clear();
public bool GearType
{
get => BitConverter.ToUInt32(Data, Offset + 0x00) == 1;
set => BitConverter.GetBytes(value ? 1u : 0).CopyTo(Data, Offset + 0x00);
}
public bool ShoesFlag
{
get => BitConverter.ToUInt32(Data, Offset + 0x04) == 1;
set => BitConverter.GetBytes(value ? 1u : 0).CopyTo(Data, Offset + 0x04);
}
public uint Form
{
get => BitConverter.ToUInt32(Data, Offset + 0x08);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x08);
}
public byte BikeColor { get => Data[Offset + 0x0C]; set => Data[Offset + 0x0C] = value; }
// 0x10: WorpPoint - Teleport
// 0x10: WorpPoint - Zenmetu
// 0x10: WorpPoint - Ananuke
public int WarpTeleportZone { get => BitConverter.ToInt32 (Data, Offset + OFS_LOC1 + 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC1 + 0x00); }
public float WarpTeleportX { get => BitConverter.ToSingle(Data, Offset + OFS_LOC1 + 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC1 + 0x04); }
public float WarpTeleportY { get => BitConverter.ToSingle(Data, Offset + OFS_LOC1 + 0x08); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC1 + 0x08); }
public float WarpTeleportZ { get => BitConverter.ToSingle(Data, Offset + OFS_LOC1 + 0x0C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC1 + 0x0C); }
public int WarpTeleportDir { get => BitConverter.ToInt32 (Data, Offset + OFS_LOC1 + 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC1 + 0x10); }
public int WarpZenmetuZone { get => BitConverter.ToInt32 (Data, Offset + OFS_LOC2 + 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC2 + 0x00); }
public float WarpZenmetuX { get => BitConverter.ToSingle(Data, Offset + OFS_LOC2 + 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC2 + 0x04); }
public float WarpZenmetuY { get => BitConverter.ToSingle(Data, Offset + OFS_LOC2 + 0x08); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC2 + 0x08); }
public float WarpZenmetuZ { get => BitConverter.ToSingle(Data, Offset + OFS_LOC2 + 0x0C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC2 + 0x0C); }
public int WarpZenmetuDir { get => BitConverter.ToInt32 (Data, Offset + OFS_LOC2 + 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC2 + 0x10); }
public int WarpAnanukeZone { get => BitConverter.ToInt32 (Data, Offset + OFS_LOC3 + 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC3 + 0x00); }
public float WarpAnanukeX { get => BitConverter.ToSingle(Data, Offset + OFS_LOC3 + 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC3 + 0x04); }
public float WarpAnanukeY { get => BitConverter.ToSingle(Data, Offset + OFS_LOC3 + 0x08); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC3 + 0x08); }
public float WarpAnanukeZ { get => BitConverter.ToSingle(Data, Offset + OFS_LOC3 + 0x0C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC3 + 0x0C); }
public int WarpAnanukeDir { get => BitConverter.ToInt32 (Data, Offset + OFS_LOC3 + 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_LOC3 + 0x10); }
public float WalkCount
{
get => BitConverter.ToSingle(Data, Offset + OFS_PART2 + 0x00);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_PART2 + 0x04);
}
public int NatukiWalkCount
{
get => BitConverter.ToInt32(Data, Offset + OFS_PART2 + 0x04);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_PART2 + 0x04);
}
public int TownMapZone { get => BitConverter.ToInt32 (Data, Offset + OFS_MAP + 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_MAP + 0x00); }
public float TownMapX { get => BitConverter.ToSingle(Data, Offset + OFS_MAP + 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_MAP + 0x04); }
public float TownMapY { get => BitConverter.ToSingle(Data, Offset + OFS_MAP + 0x08); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_MAP + 0x08); }
public float TownMapZ { get => BitConverter.ToSingle(Data, Offset + OFS_MAP + 0x0C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_MAP + 0x0C); }
public int TownMapDir { get => BitConverter.ToInt32 (Data, Offset + OFS_MAP + 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_MAP + 0x10); }
public bool IsTokushuLocation
{
get => BitConverter.ToUInt32(Data, Offset + OFS_TOKUSHU_BOOL + 0x00) == 1;
set => BitConverter.GetBytes(value ? 1u : 0).CopyTo(Data, Offset + OFS_TOKUSHU_BOOL + 0x00);
}
public int TokushuZone { get => BitConverter.ToInt32 (Data, Offset + OFS_TOKUSHU + 0x00); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_TOKUSHU + 0x00); }
public float TokushuX { get => BitConverter.ToSingle(Data, Offset + OFS_TOKUSHU + 0x04); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_TOKUSHU + 0x04); }
public float TokushuY { get => BitConverter.ToSingle(Data, Offset + OFS_TOKUSHU + 0x08); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_TOKUSHU + 0x08); }
public float TokushuZ { get => BitConverter.ToSingle(Data, Offset + OFS_TOKUSHU + 0x0C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_TOKUSHU + 0x0C); }
public int TokushuDir { get => BitConverter.ToInt32 (Data, Offset + OFS_TOKUSHU + 0x10); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + OFS_TOKUSHU + 0x10); }
}
}

View file

@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace PKHeX.Core
{
/// <summary>
/// Stores customized ball seal configurations.
/// </summary>
/// <remarks>size 0x4288</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class SealBallDecoData8b : SaveBlock
{
public const int COUNT_CAPSULE = 99; // CapsuleData[99]
private const int SIZE = 4 + (COUNT_CAPSULE * SealCapsule8b.SIZE); // 0x4288
public SealBallDecoData8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;
public void Clear() => Data.AsSpan(Offset, SIZE).Clear();
public byte CapsuleCount { get => Data[Offset]; set => Data[Offset] = value; }
#pragma warning disable CA1819 // Properties should not return arrays
public SealCapsule8b[] Capsules
{
get => GetCapsules();
set => SetCapsules(value);
}
#pragma warning restore CA1819 // Properties should not return arrays
private SealCapsule8b[] GetCapsules()
{
var result = new SealCapsule8b[COUNT_CAPSULE];
for (int i = 0; i < result.Length; i++)
result[i] = new SealCapsule8b(Data, Offset + 4 + (i * SealCapsule8b.SIZE));
return result;
}
private static void SetCapsules(IReadOnlyList<SealCapsule8b> value)
{
if (value.Count != COUNT_CAPSULE)
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 SealCapsule8b
{
public const int COUNT_SEAL = 20; // AffixSealData[20]
public const int SIZE = 12 + (COUNT_SEAL * AffixSealData8b.SIZE); // 0xAC
private readonly int Offset;
private readonly byte[] Data;
public override string ToString() => $"{(Species)Species}-{EncryptionConstant:X8}-{Unknown}";
public SealCapsule8b(byte[] data, int offset)
{
Data = data;
Offset = offset;
}
public uint Species { get => BitConverter.ToUInt32(Data, Offset + 0); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0); }
public uint EncryptionConstant { get => BitConverter.ToUInt32(Data, Offset + 4); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 4); }
public uint Unknown { get => BitConverter.ToUInt32(Data, Offset + 8); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 8); }
#pragma warning disable CA1819 // Properties should not return arrays
public AffixSealData8b[] Seals
{
get => GetSeals();
set => SetSeals(value);
}
#pragma warning restore CA1819 // Properties should not return arrays
private AffixSealData8b[] GetSeals()
{
var result = new AffixSealData8b[COUNT_SEAL];
for (int i = 0; i < result.Length; i++)
result[i] = new AffixSealData8b(Data, Offset + 0xC + (i * AffixSealData8b.SIZE));
return result;
}
private static void SetSeals(IReadOnlyList<AffixSealData8b> value)
{
if (value.Count != COUNT_SEAL)
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 class AffixSealData8b
{
public const int SIZE = 8; // u16 id, s16 x,y,z
private readonly int Offset;
private readonly byte[] Data;
public override string ToString() => $"{SealID}-({X},{Y},{Z})";
public AffixSealData8b(byte[] data, int offset)
{
Data = data;
Offset = offset;
}
public ushort SealID { get => BitConverter.ToUInt16(Data, Offset + 0); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0); }
public short X { get => BitConverter.ToInt16(Data, Offset + 2); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 2); }
public short Y { get => BitConverter.ToInt16(Data, Offset + 4); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 4); }
public short Z { get => BitConverter.ToInt16(Data, Offset + 6); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 6); }
}
}

View file

@ -0,0 +1,51 @@
using System;
using System.ComponentModel;
namespace PKHeX.Core
{
/// <summary>
/// Underground player metadata counts.
/// </summary>
/// <remarks>size 0x20, struct_name UgCountRecord</remarks>
[TypeConverter(typeof(ExpandableObjectConverter))]
public sealed class UgCountRecord8b : SaveBlock
{
public UgCountRecord8b(SAV8BS sav, int offset) : base(sav) => Offset = offset;
public short DigFossilPlayCount
{
get => BitConverter.ToInt16(Data, Offset + 0x00);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x00);
}
public short NumStatueBroadcastOnTV
{
get => BitConverter.ToInt16(Data, Offset + 0x02);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x02);
}
public int NumTimesSecretBaseBroadcastOnTVWereLiked
{
get => BitConverter.ToInt32(Data, Offset + 0x04);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x04);
}
public int SomeoneSecretBaseLikeCount
{
get => BitConverter.ToInt32(Data, Offset + 0x08);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x08);
}
public int NumSuccessfulLightStoneSearches
{
get => BitConverter.ToInt32(Data, Offset + 0x0C);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x0C);
}
public long Reserved1
{
get => BitConverter.ToInt64(Data, Offset + 0x10);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x10);
}
public long Reserved2
{
get => BitConverter.ToInt64(Data, Offset + 0x18);
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x18);
}
}
}