mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-22 03:53:08 +00:00
Fix HGSS box saving (empty->not)
HGSS tracks each box if it is changed, to skip writing it on in-game save. PKHeX (and other editors) weren't updating these bitflags, so when empty boxes had Pokémon added and saved once in-game, the save file would corrupt as it was copying the checksum but not the box's data. Saving twice in-game will cause the checksums to get updated even without the flags being set. I don't think we understand it fully, but this hacky workaround of noting all boxes as "changed" will cause the first-save to properly copy all contents of the boxes to the new primary save section. Rather than tracking which boxes we are reading/writing slots for, or fixing/comparing against a backup -- we need to account for API usage where people might write directly into the save (pcdata.bin/boxdata.bin too). Best to play it safe and let the game fix it. Most wouldn't have noticed this issue as the box they're modifying is usually their most-recently-changed in-game box. Closes #4368
This commit is contained in:
parent
6153d6c851
commit
fced599119
1 changed files with 14 additions and 1 deletions
|
@ -53,6 +53,14 @@ public sealed class SAV4HGSS : SAV4, IBoxDetailName, IBoxDetailWallpaper
|
||||||
GetSAVOffsets();
|
GetSAVOffsets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override byte[] GetFinalData()
|
||||||
|
{
|
||||||
|
// Make sure all boxes are copied when saved only once in-game.
|
||||||
|
// This results in the game "saving a lot of data", but ensures the boxdata struct does not corrupt in-game on single save.
|
||||||
|
FlagsBoxContentChanged = FlagsBoxContentChangedAll;
|
||||||
|
return base.GetFinalData();
|
||||||
|
}
|
||||||
|
|
||||||
private const int OffsetMystery = 0x9D3C; // Flags and Gifts
|
private const int OffsetMystery = 0x9D3C; // Flags and Gifts
|
||||||
protected override int EventWork => 0xDE4;
|
protected override int EventWork => 0xDE4;
|
||||||
protected override int EventFlag => 0x10C4;
|
protected override int EventFlag => 0x10C4;
|
||||||
|
@ -125,12 +133,17 @@ public sealed class SAV4HGSS : SAV4, IBoxDetailName, IBoxDetailWallpaper
|
||||||
set => Storage[BOX_FLAGS] = value[0];
|
set => Storage[BOX_FLAGS] = value[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Counter
|
/// <summary>
|
||||||
|
/// The box structure stores bitflags to indicate which boxes have changed; used when saving to skip unchanged boxes.
|
||||||
|
/// </summary>
|
||||||
|
public int FlagsBoxContentChanged
|
||||||
{
|
{
|
||||||
get => ReadInt32LittleEndian(Storage[(BOX_END + 4)..]);
|
get => ReadInt32LittleEndian(Storage[(BOX_END + 4)..]);
|
||||||
set => WriteInt32LittleEndian(Storage[(BOX_END + 4)..], value);
|
set => WriteInt32LittleEndian(Storage[(BOX_END + 4)..], value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const int FlagsBoxContentChangedAll = 0x3_FFFF; // 18 boxes.
|
||||||
|
|
||||||
private Span<byte> GetBoxNameSpan(int box) => Storage.Slice(GetBoxNameOffset(box), BOX_NAME_LEN);
|
private Span<byte> GetBoxNameSpan(int box) => Storage.Slice(GetBoxNameOffset(box), BOX_NAME_LEN);
|
||||||
public string GetBoxName(int box) => GetString(GetBoxNameSpan(box));
|
public string GetBoxName(int box) => GetString(GetBoxNameSpan(box));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue