mirror of
https://github.com/kwsch/PKHeX
synced 2025-02-17 05:48:44 +00:00
Add offset table for sav1
calling Japanese ? X : Y on every single access is too excessive, just compute one layout for each type whenever the first sav1 requires it. could probably reduce the amount of properties by reusing others + shift value; offsets are different due to string lengths being different
This commit is contained in:
parent
fc73eee570
commit
0296f98777
2 changed files with 165 additions and 59 deletions
|
@ -11,6 +11,7 @@ namespace PKHeX.Core
|
|||
protected override string BAKText => $"{OT} ({Version}) - {PlayTimeString}";
|
||||
public override string Filter => "SAV File|*.sav|All Files|*.*";
|
||||
public override string Extension => ".sav";
|
||||
|
||||
public override string[] PKMExtensions => PKM.Extensions.Where(f =>
|
||||
{
|
||||
int gen = f.Last() - 0x30;
|
||||
|
@ -33,11 +34,12 @@ namespace PKHeX.Core
|
|||
if (Starter != 0)
|
||||
Version = Yellow ? GameVersion.YW : GameVersion.RB;
|
||||
|
||||
Japanese = SaveUtil.GetIsG1SAVJ(Data);
|
||||
Offsets = Japanese ? SAV1Offsets.JPN : SAV1Offsets.INT;
|
||||
Box = Data.Length;
|
||||
Array.Resize(ref Data, Data.Length + SIZE_RESERVED);
|
||||
Party = GetPartyOffset(0);
|
||||
|
||||
Japanese = SaveUtil.GetIsG1SAVJ(Data);
|
||||
Personal = PersonalTable.Y;
|
||||
|
||||
// Stash boxes after the save file's end.
|
||||
|
@ -60,18 +62,18 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
|
||||
var current = GetData(Japanese ? 0x302D : 0x30C0, SIZE_STOREDBOX);
|
||||
var current = GetData(Offsets.CurrentBox, SIZE_STOREDBOX);
|
||||
var curBoxPL = new PokeList1(current, capacity, Japanese);
|
||||
for (int i = 0; i < curBoxPL.Pokemon.Length; i++)
|
||||
{
|
||||
var dest = Data.Length - SIZE_RESERVED + CurrentBox * SIZE_BOX + i * SIZE_STORED;
|
||||
var dest = Data.Length - SIZE_RESERVED + (CurrentBox * SIZE_BOX) + (i * SIZE_STORED);
|
||||
var pkDat = i < curBoxPL.Count
|
||||
? new PokeList1(curBoxPL[i]).Write()
|
||||
: new byte[PokeList1.GetDataLength(PokeListType.Single, Japanese)];
|
||||
pkDat.CopyTo(Data, dest);
|
||||
}
|
||||
|
||||
var party = GetData(Japanese ? 0x2ED5 : 0x2F2C, SIZE_STOREDPARTY);
|
||||
var party = GetData(Offsets.Party, SIZE_STOREDPARTY);
|
||||
var partyPL = new PokeList1(party, PokeListType.Party, Japanese);
|
||||
for (int i = 0; i < partyPL.Pokemon.Length; i++)
|
||||
{
|
||||
|
@ -83,19 +85,16 @@ namespace PKHeX.Core
|
|||
}
|
||||
|
||||
byte[] rawDC = new byte[0x38];
|
||||
Array.Copy(Data, Japanese ? 0x2CA7 : 0x2CF4, rawDC, 0, rawDC.Length);
|
||||
Array.Copy(Data, Offsets.Daycare, rawDC, 0, rawDC.Length);
|
||||
byte[] TempDaycare = new byte[PokeList1.GetDataLength(PokeListType.Single, Japanese)];
|
||||
TempDaycare[0] = rawDC[0];
|
||||
Array.Copy(rawDC, 1, TempDaycare, 2 + 1 + PKX.SIZE_1PARTY + StringLength, StringLength);
|
||||
Array.Copy(rawDC, 1 + StringLength, TempDaycare, 2 + 1 + PKX.SIZE_1PARTY, StringLength);
|
||||
Array.Copy(rawDC, 1 + 2 * StringLength, TempDaycare, 2 + 1, PKX.SIZE_1STORED);
|
||||
Array.Copy(rawDC, 1 + (2 * StringLength), TempDaycare, 2 + 1, PKX.SIZE_1STORED);
|
||||
PokeList1 daycareList = new PokeList1(TempDaycare, PokeListType.Single, Japanese);
|
||||
daycareList.Write().CopyTo(Data, GetPartyOffset(7));
|
||||
Daycare = GetPartyOffset(7);
|
||||
|
||||
EventFlag = Japanese ? 0x29E9 : 0x29F3;
|
||||
ObjectSpawnFlags = Japanese ? 0x2848 : 0x2852; // 2 bytes after Coin
|
||||
|
||||
// Enable Pokedex editing
|
||||
PokeDex = 0;
|
||||
|
||||
|
@ -103,10 +102,11 @@ namespace PKHeX.Core
|
|||
ClearBoxes();
|
||||
}
|
||||
|
||||
private readonly SAV1Offsets Offsets;
|
||||
|
||||
// Event Flags
|
||||
protected override int EventFlagMax => EventFlag > 0 ? 0xA00 : int.MinValue; // 320 * 8
|
||||
protected override int EventConstMax => 0;
|
||||
private readonly int ObjectSpawnFlags;
|
||||
|
||||
private const int SIZE_RESERVED = 0x8000; // unpacked box data
|
||||
|
||||
|
@ -131,7 +131,7 @@ namespace PKHeX.Core
|
|||
|
||||
// copy to active loc if current box
|
||||
if (i == CurrentBox)
|
||||
SetData(boxdata, Japanese ? 0x302D : 0x30C0);
|
||||
SetData(boxdata, Offsets.CurrentBox);
|
||||
}
|
||||
|
||||
var partyPL = new PokeList1(PokeListType.Party, Japanese);
|
||||
|
@ -142,16 +142,16 @@ namespace PKHeX.Core
|
|||
if (partyPK.Species > 0)
|
||||
partyPL[pSlot++] = partyPK;
|
||||
}
|
||||
partyPL.Write().CopyTo(Data, Japanese ? 0x2ED5 : 0x2F2C);
|
||||
partyPL.Write().CopyTo(Data, Offsets.Party);
|
||||
|
||||
// Daycare is read-only, but in case it ever becomes editable, copy it back in.
|
||||
byte[] rawDC = GetData(GetDaycareSlotOffset(loc: 0, slot: 0), SIZE_STORED);
|
||||
byte[] dc = new byte[1 + 2*StringLength + PKX.SIZE_1STORED];
|
||||
byte[] dc = new byte[1 + (2 * StringLength) + PKX.SIZE_1STORED];
|
||||
dc[0] = rawDC[0];
|
||||
Array.Copy(rawDC, 2 + 1 + PKX.SIZE_1PARTY + StringLength, dc, 1, StringLength);
|
||||
Array.Copy(rawDC, 2 + 1 + PKX.SIZE_1PARTY, dc, 1 + StringLength, StringLength);
|
||||
Array.Copy(rawDC, 2 + 1, dc, 1 + 2*StringLength, PKX.SIZE_1STORED);
|
||||
dc.CopyTo(Data, Japanese ? 0x2CA7 : 0x2CF4);
|
||||
Array.Copy(rawDC, 2 + 1, dc, 1 + (2 * StringLength), PKX.SIZE_1STORED);
|
||||
dc.CopyTo(Data, Offsets.Daycare);
|
||||
|
||||
SetChecksums();
|
||||
byte[] outData = new byte[Data.Length - SIZE_RESERVED];
|
||||
|
@ -202,12 +202,11 @@ namespace PKHeX.Core
|
|||
public override bool IsPKMPresent(int Offset) => PKX.IsPKMPresentGB(Data, Offset);
|
||||
|
||||
// Checksums
|
||||
protected override void SetChecksums() => Data[CHECKSUM_OFS] = GetRBYChecksum(CHECKSUM_OFS);
|
||||
public override bool ChecksumsValid => Data[CHECKSUM_OFS] == GetRBYChecksum(CHECKSUM_OFS);
|
||||
protected override void SetChecksums() => Data[Offsets.ChecksumOfs] = GetRBYChecksum(Offsets.ChecksumOfs);
|
||||
public override bool ChecksumsValid => Data[Offsets.ChecksumOfs] == GetRBYChecksum(Offsets.ChecksumOfs);
|
||||
public override string ChecksumInfo => ChecksumsValid ? "Checksum valid." : "Checksum invalid";
|
||||
|
||||
private const int CHECKSUM_START = 0x2598;
|
||||
private int CHECKSUM_OFS => Japanese ? 0x3594 : 0x3523;
|
||||
|
||||
private byte GetRBYChecksum(int end)
|
||||
{
|
||||
|
@ -226,32 +225,37 @@ namespace PKHeX.Core
|
|||
get => GetString(0x2598, OTLength);
|
||||
set => SetString(value, OTLength).CopyTo(Data, 0x2598);
|
||||
}
|
||||
|
||||
public byte[] OT_Trash { get => GetData(0x2598, StringLength); set { if (value?.Length == StringLength) SetData(value, 0x2598); } }
|
||||
|
||||
public override int Gender
|
||||
{
|
||||
get => 0;
|
||||
set { }
|
||||
}
|
||||
|
||||
public override int TID
|
||||
{
|
||||
get => BigEndian.ToUInt16(Data, Japanese ? 0x25FB : 0x2605);
|
||||
set => BigEndian.GetBytes((ushort)value).CopyTo(Data, Japanese ? 0x25FB : 0x2605);
|
||||
get => BigEndian.ToUInt16(Data, Offsets.TID);
|
||||
set => BigEndian.GetBytes((ushort)value).CopyTo(Data, Offsets.TID);
|
||||
}
|
||||
|
||||
public override int SID { get => 0; set { } }
|
||||
|
||||
public bool Yellow => Starter == 0x54; // Pikachu
|
||||
public int Starter => Data[Japanese ? 0x29B9 : 0x29C3];
|
||||
public int Starter => Data[Offsets.Starter];
|
||||
|
||||
public byte PikaFriendship
|
||||
{
|
||||
get => Data[Japanese ? 0x2712 : 0x271C];
|
||||
set => Data[Japanese ? 0x2712 : 0x271C] = value;
|
||||
get => Data[Offsets.PikaFriendship];
|
||||
set => Data[Offsets.PikaFriendship] = value;
|
||||
}
|
||||
private int PlayedTimeOffset => Japanese ? 0x2CA0 : 0x2CED;
|
||||
|
||||
public override string PlayTimeString => !PlayedMaximum ? base.PlayTimeString : $"{base.PlayTimeString} {SaveUtil.CRC16_CCITT(Data):X4}";
|
||||
|
||||
public override int PlayedHours
|
||||
{
|
||||
get => Data[PlayedTimeOffset + 0];
|
||||
get => Data[Offsets.PlayTime + 0];
|
||||
set
|
||||
{
|
||||
if (value >= byte.MaxValue) // Set 255:00:00.00 and flag
|
||||
|
@ -260,50 +264,58 @@ namespace PKHeX.Core
|
|||
value = byte.MaxValue;
|
||||
PlayedMinutes = PlayedSeconds = PlayedFrames = 0;
|
||||
}
|
||||
Data[PlayedTimeOffset + 0] = (byte) value;
|
||||
Data[Offsets.PlayTime + 0] = (byte) value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool PlayedMaximum
|
||||
{
|
||||
get => Data[PlayedTimeOffset + 1] != 0;
|
||||
set => Data[PlayedTimeOffset + 1] = (byte)(value ? 1 : 0);
|
||||
get => Data[Offsets.PlayTime + 1] != 0;
|
||||
set => Data[Offsets.PlayTime + 1] = (byte)(value ? 1 : 0);
|
||||
}
|
||||
|
||||
public override int PlayedMinutes
|
||||
{
|
||||
get => Data[PlayedTimeOffset + 2];
|
||||
set => Data[PlayedTimeOffset + 2] = (byte)value;
|
||||
get => Data[Offsets.PlayTime + 2];
|
||||
set => Data[Offsets.PlayTime + 2] = (byte)value;
|
||||
}
|
||||
|
||||
public override int PlayedSeconds
|
||||
{
|
||||
get => Data[PlayedTimeOffset + 3];
|
||||
set => Data[PlayedTimeOffset + 3] = (byte)value;
|
||||
get => Data[Offsets.PlayTime + 3];
|
||||
set => Data[Offsets.PlayTime + 3] = (byte)value;
|
||||
}
|
||||
|
||||
public int PlayedFrames
|
||||
{
|
||||
get => Data[PlayedTimeOffset + 4];
|
||||
set => Data[PlayedTimeOffset + 4] = (byte)value;
|
||||
get => Data[Offsets.PlayTime + 4];
|
||||
set => Data[Offsets.PlayTime + 4] = (byte)value;
|
||||
}
|
||||
|
||||
public int Badges
|
||||
{
|
||||
get => Data[Japanese ? 0x25F8 : 0x2602];
|
||||
set { if (value < 0) return; Data[Japanese ? 0x25F8 : 0x2602] = (byte)value; }
|
||||
get => Data[Offsets.Badges];
|
||||
set { if (value < 0) return; Data[Offsets.Badges] = (byte)value; }
|
||||
}
|
||||
|
||||
private byte Options
|
||||
{
|
||||
get => Data[Japanese ? 0x25F7 : 0x2601];
|
||||
set => Data[Japanese ? 0x25F7 : 0x2601] = value;
|
||||
get => Data[Offsets.Options];
|
||||
set => Data[Offsets.Options] = value;
|
||||
}
|
||||
|
||||
public bool BattleEffects
|
||||
{
|
||||
get => (Options & 0x80) == 0;
|
||||
set => Options = (byte)((Options & 0x7F) | (value ? 0 : 0x80));
|
||||
}
|
||||
|
||||
public bool BattleStyleSwitch
|
||||
{
|
||||
get => (Options & 0x40) == 0;
|
||||
set => Options = (byte)((Options & 0xBF) | (value ? 0 : 0x40));
|
||||
}
|
||||
|
||||
public int Sound
|
||||
{
|
||||
get => (Options & 0x30) >> 4;
|
||||
|
@ -317,6 +329,7 @@ namespace PKHeX.Core
|
|||
Options = (byte)((Options & 0xCF) | (new_sound << 4));
|
||||
}
|
||||
}
|
||||
|
||||
public int TextSpeed
|
||||
{
|
||||
get => Options & 0x7;
|
||||
|
@ -330,26 +343,29 @@ namespace PKHeX.Core
|
|||
Options = (byte)((Options & 0xF8) | new_speed);
|
||||
}
|
||||
}
|
||||
|
||||
public override uint Money
|
||||
{
|
||||
get => (uint)BigEndian.BCDToInt32(Data, Japanese ? 0x25EE : 0x25F3, 3);
|
||||
get => (uint)BigEndian.BCDToInt32(Data, Offsets.Money, 3);
|
||||
set
|
||||
{
|
||||
value = (uint)Math.Min(value, MaxMoney);
|
||||
BigEndian.Int32ToBCD((int)value, 3).CopyTo(Data, Japanese ? 0x25EE : 0x25F3);
|
||||
BigEndian.Int32ToBCD((int)value, 3).CopyTo(Data, Offsets.Money);
|
||||
}
|
||||
}
|
||||
|
||||
public uint Coin
|
||||
{
|
||||
get => (uint)BigEndian.BCDToInt32(Data, Japanese ? 0x2846 : 0x2850, 2);
|
||||
get => (uint)BigEndian.BCDToInt32(Data, Offsets.Coin, 2);
|
||||
set
|
||||
{
|
||||
value = (ushort)Math.Min(value, MaxCoins);
|
||||
BigEndian.Int32ToBCD((int)value, 2).CopyTo(Data, Japanese ? 0x2846 : 0x2850);
|
||||
BigEndian.Int32ToBCD((int)value, 2).CopyTo(Data, Offsets.Coin);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly ushort[] LegalItems = Legal.Pouch_Items_RBY;
|
||||
|
||||
public override InventoryPouch[] Inventory
|
||||
{
|
||||
get
|
||||
|
@ -357,8 +373,8 @@ namespace PKHeX.Core
|
|||
ushort[] legalItems = LegalItems;
|
||||
InventoryPouch[] pouch =
|
||||
{
|
||||
new InventoryPouchGB(InventoryType.Items, legalItems, 99, Japanese ? 0x25C4 : 0x25C9, 20),
|
||||
new InventoryPouchGB(InventoryType.PCItems, legalItems, 99, Japanese ? 0x27DC : 0x27E6, 50)
|
||||
new InventoryPouchGB(InventoryType.Items, legalItems, 99, Offsets.Items, 20),
|
||||
new InventoryPouchGB(InventoryType.PCItems, legalItems, 99, Offsets.PCItems, 50)
|
||||
};
|
||||
foreach (var p in pouch)
|
||||
{
|
||||
|
@ -383,25 +399,30 @@ namespace PKHeX.Core
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetDaycareSlotOffset(int loc, int slot)
|
||||
{
|
||||
return Daycare;
|
||||
}
|
||||
|
||||
public override uint? GetDaycareEXP(int loc, int slot)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public override bool? IsDaycareOccupied(int loc, int slot)
|
||||
{
|
||||
if (loc == 0 && slot == 0)
|
||||
return Data[Japanese ? 0x2CA7 : 0x2CF4] == 0x01;
|
||||
return Data[Offsets.Daycare] == 0x01;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public override void SetDaycareEXP(int loc, int slot, uint EXP)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void SetDaycareOccupied(int loc, int slot, bool occupied)
|
||||
{
|
||||
|
||||
|
@ -410,26 +431,31 @@ namespace PKHeX.Core
|
|||
// Storage
|
||||
public override int PartyCount
|
||||
{
|
||||
get => Data[Japanese ? 0x2ED5 : 0x2F2C];
|
||||
protected set => Data[Japanese ? 0x2ED5 : 0x2F2C] = (byte)value;
|
||||
get => Data[Offsets.Party];
|
||||
protected set => Data[Offsets.Party] = (byte)value;
|
||||
}
|
||||
|
||||
public override int GetBoxOffset(int box)
|
||||
{
|
||||
return Data.Length - SIZE_RESERVED + box * SIZE_BOX;
|
||||
return Data.Length - SIZE_RESERVED + (box * SIZE_BOX);
|
||||
}
|
||||
|
||||
public override int GetPartyOffset(int slot)
|
||||
{
|
||||
return Data.Length - SIZE_RESERVED + BoxCount * SIZE_BOX + slot * SIZE_STORED;
|
||||
return Data.Length - SIZE_RESERVED + (BoxCount * SIZE_BOX) + (slot * SIZE_STORED);
|
||||
}
|
||||
|
||||
public override int CurrentBox
|
||||
{
|
||||
get => Data[Japanese ? 0x2842 : 0x284C] & 0x7F;
|
||||
set => Data[Japanese ? 0x2842 : 0x284C] = (byte)((Data[Japanese ? 0x2842 : 0x284C] & 0x80) | (value & 0x7F));
|
||||
get => Data[Offsets.CurrentBoxIndex] & 0x7F;
|
||||
set => Data[Offsets.CurrentBoxIndex] = (byte)((Data[Offsets.CurrentBoxIndex] & 0x80) | (value & 0x7F));
|
||||
}
|
||||
|
||||
public override string GetBoxName(int box)
|
||||
{
|
||||
return $"BOX {box + 1}";
|
||||
}
|
||||
|
||||
public override void SetBoxName(int box, string value)
|
||||
{
|
||||
// Don't allow for custom box names
|
||||
|
@ -441,14 +467,13 @@ namespace PKHeX.Core
|
|||
return new PokeList1(data, PokeListType.Single, Japanese)[0];
|
||||
return new PK1(data);
|
||||
}
|
||||
|
||||
public override byte[] DecryptPKM(byte[] data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
// Pokédex
|
||||
private int PokedexSeenOffset => Japanese ? 0x25B1 : 0x25B6;
|
||||
private int PokedexCaughtOffset => Japanese ? 0x259E : 0x25A3;
|
||||
protected override void SetDex(PKM pkm)
|
||||
{
|
||||
int species = pkm.Species;
|
||||
|
@ -458,6 +483,7 @@ namespace PKHeX.Core
|
|||
SetCaught(pkm.Species, true);
|
||||
SetSeen(pkm.Species, true);
|
||||
}
|
||||
|
||||
private bool CanSetDex(int species)
|
||||
{
|
||||
if (species <= 0)
|
||||
|
@ -468,32 +494,37 @@ namespace PKHeX.Core
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void SetSeen(int species, bool seen)
|
||||
{
|
||||
int bit = species - 1;
|
||||
int ofs = bit >> 3;
|
||||
SetFlag(PokedexSeenOffset + ofs, bit & 7, seen);
|
||||
SetFlag(Offsets.DexSeen + ofs, bit & 7, seen);
|
||||
}
|
||||
|
||||
public override void SetCaught(int species, bool caught)
|
||||
{
|
||||
int bit = species - 1;
|
||||
int ofs = bit >> 3;
|
||||
SetFlag(PokedexCaughtOffset + ofs, bit & 7, caught);
|
||||
SetFlag(Offsets.DexCaught + ofs, bit & 7, caught);
|
||||
}
|
||||
|
||||
public override bool GetSeen(int species)
|
||||
{
|
||||
int bit = species - 1;
|
||||
int ofs = bit >> 3;
|
||||
return GetFlag(PokedexSeenOffset + ofs, bit & 7);
|
||||
return GetFlag(Offsets.DexSeen + ofs, bit & 7);
|
||||
}
|
||||
|
||||
public override bool GetCaught(int species)
|
||||
{
|
||||
int bit = species - 1;
|
||||
int ofs = bit >> 3;
|
||||
return GetFlag(PokedexCaughtOffset + ofs, bit & 7);
|
||||
return GetFlag(Offsets.DexCaught + ofs, bit & 7);
|
||||
}
|
||||
|
||||
private const int SpawnFlagCount = 0xF0;
|
||||
|
||||
public bool[] EventSpawnFlags
|
||||
{
|
||||
get
|
||||
|
@ -501,7 +532,7 @@ namespace PKHeX.Core
|
|||
// RB uses 0xE4 (0xE8) flags, Yellow uses 0xF0 flags. Just grab 0xF0
|
||||
bool[] data = new bool[SpawnFlagCount];
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
data[i] = GetFlag(ObjectSpawnFlags + i >> 3, i & 7);
|
||||
data[i] = GetFlag(Offsets.ObjectSpawnFlags + i >> 3, i & 7);
|
||||
return data;
|
||||
}
|
||||
set
|
||||
|
@ -509,11 +540,12 @@ namespace PKHeX.Core
|
|||
if (value?.Length != SpawnFlagCount)
|
||||
return;
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
SetFlag(ObjectSpawnFlags + i >> 3, i & 7, value[i]);
|
||||
SetFlag(Offsets.ObjectSpawnFlags + i >> 3, i & 7, value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public override string GetString(int Offset, int Length) => StringConverter.GetString1(Data, Offset, Length, Japanese);
|
||||
|
||||
public override byte[] SetString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0)
|
||||
{
|
||||
if (PadToSize == 0)
|
||||
|
|
74
PKHeX.Core/Saves/Substructures/Gen12/SAV1Offsets.cs
Normal file
74
PKHeX.Core/Saves/Substructures/Gen12/SAV1Offsets.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
internal class SAV1Offsets
|
||||
{
|
||||
public static readonly SAV1Offsets INT = GetINT();
|
||||
public static readonly SAV1Offsets JPN = GetJPN();
|
||||
|
||||
private static SAV1Offsets GetINT() => new SAV1Offsets
|
||||
{
|
||||
DexCaught = 0x25A3,
|
||||
DexSeen = 0x25B6,
|
||||
Items = 0x25C9,
|
||||
Money = 0x25F3,
|
||||
Options = 0x2601,
|
||||
Badges = 0x2602,
|
||||
TID = 0x2605,
|
||||
PikaFriendship = 0x271C,
|
||||
PCItems = 0x27E6,
|
||||
CurrentBoxIndex = 0x284C,
|
||||
Coin = 0x2850,
|
||||
ObjectSpawnFlags = 0x2852, // 2 bytes after Coin
|
||||
Starter = 0x29C3,
|
||||
EventFlag = 0x29F3,
|
||||
PlayTime = 0x2CED,
|
||||
Daycare = 0x2CF4,
|
||||
Party = 0x2F2C,
|
||||
CurrentBox = 0x30C0,
|
||||
ChecksumOfs = 0x3523,
|
||||
};
|
||||
|
||||
private static SAV1Offsets GetJPN() => new SAV1Offsets
|
||||
{
|
||||
DexCaught = 0x259E,
|
||||
DexSeen = 0x25B1,
|
||||
Items = 0x25C4,
|
||||
Money = 0x25EE,
|
||||
Options = 0x25F7,
|
||||
Badges = 0x25F8,
|
||||
TID = 0x25FB,
|
||||
PikaFriendship = 0x2712,
|
||||
PCItems = 0x27DC,
|
||||
CurrentBoxIndex = 0x2842,
|
||||
Coin = 0x2846,
|
||||
ObjectSpawnFlags = 0x2848, // 2 bytes after Coin
|
||||
Starter = 0x29B9,
|
||||
EventFlag = 0x29E9,
|
||||
PlayTime = 0x2CA0,
|
||||
Daycare = 0x2CA7,
|
||||
Party = 0x2ED5,
|
||||
CurrentBox = 0x302D,
|
||||
ChecksumOfs = 0x3594,
|
||||
};
|
||||
|
||||
public int DexCaught { get; private set; }
|
||||
public int DexSeen { get; private set; }
|
||||
public int Items { get; private set; }
|
||||
public int Money { get; private set; }
|
||||
public int Options { get; private set; }
|
||||
public int Badges { get; private set; }
|
||||
public int TID { get; private set; }
|
||||
public int PikaFriendship { get; private set; }
|
||||
public int PCItems { get; private set; }
|
||||
public int CurrentBoxIndex { get; private set; }
|
||||
public int Coin { get; private set; }
|
||||
public int ObjectSpawnFlags { get; private set; }
|
||||
public int Starter { get; private set; }
|
||||
public int EventFlag { get; private set; }
|
||||
public int PlayTime { get; private set; }
|
||||
public int Daycare { get; private set; }
|
||||
public int Party { get; private set; }
|
||||
public int CurrentBox { get; private set; }
|
||||
public int ChecksumOfs { get; private set; }
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue