XD: Purification is stored differently for jp games

A more condensed data structure, 72->60 bytes for each entry instead.
Closes #3255

Related? #2956
This commit is contained in:
Kurt 2021-09-03 18:16:09 -07:00
parent 5f0dcfe6af
commit f9d9bcfb80
3 changed files with 39 additions and 13 deletions

View file

@ -33,7 +33,7 @@ namespace PKHeX.Core
{
// create fake objects
StrategyMemo = new StrategyMemo();
ShadowInfo = new ShadowInfoTableXD();
ShadowInfo = new ShadowInfoTableXD(false);
Initialize();
ClearBoxes();
}
@ -92,8 +92,9 @@ namespace PKHeX.Core
Shadow = subOffsets[7] + 0xA8;
// Purifier = subOffsets[14] + 0xA8;
bool jp = subLength[7] == 0x1E00;
memo = new StrategyMemo(Data, Memo, xd: true);
info = new ShadowInfoTableXD(Data.Slice(Shadow, subLength[7]));
info = new ShadowInfoTableXD(Data.Slice(Shadow, subLength[7]), jp);
}
private void Initialize()

View file

@ -1,12 +1,10 @@
namespace PKHeX.Core
{
public sealed class ShadowInfoEntryXD
public abstract class ShadowInfoEntryXD
{
public readonly byte[] Data;
internal const int SIZE_ENTRY = 72;
public ShadowInfoEntryXD() => Data = new byte[SIZE_ENTRY];
public ShadowInfoEntryXD(byte[] data) => Data = data;
protected ShadowInfoEntryXD(byte[] data) => Data = data;
public bool IsSnagged => Data[0] >> 6 != 0;
public bool IsPurified { get => Data[0] >> 7 == 1; set { Data[0] &= 0x7F; if (value) Data[0] |= 0x80; } }
@ -25,8 +23,32 @@
public uint EXP { get => BigEndian.ToUInt32(Data, 0x04) >> 12; set => BigEndian.GetBytes((BigEndian.ToUInt32(Data, 0x04) & 0xFFF) | (value << 12)).CopyTo(Data, 0x04); }
public bool IsEmpty => Species == 0;
public int Index { get => Data[0x3F]; set => Data[0x3F] = (byte)value; }
public abstract byte Index { get; set; }
public override string ToString() => $"{(Species) Species} 0x{PID:X8} {Purification}";
}
public sealed class ShadowInfoEntry3J : ShadowInfoEntryXD
{
internal const int SIZE_ENTRY = 60; // -12 from U
public ShadowInfoEntry3J() : base(new byte[SIZE_ENTRY]) { }
public ShadowInfoEntry3J(byte[] data) : base(data) { }
public override byte Index { get => Data[0x35]; set => Data[0x35] = value; }
public override string ToString() => $"{(Species)Species} 0x{PID:X8} {Purification}";
}
public sealed class ShadowInfoEntry3U : ShadowInfoEntryXD
{
internal const int SIZE_ENTRY = 72; // -12 from U
public ShadowInfoEntry3U() : base(new byte[SIZE_ENTRY]) { }
public ShadowInfoEntry3U(byte[] data) : base(data) { }
public override byte Index { get => Data[0x3F]; set => Data[0x3F] = value; }
public override string ToString() => $"{(Species)Species} 0x{PID:X8} {Purification}";
}
}

View file

@ -6,24 +6,27 @@ namespace PKHeX.Core
{
private readonly ShadowInfoEntryXD[] Entries;
private readonly int MaxLength;
private const int SIZE_ENTRY = ShadowInfoEntryXD.SIZE_ENTRY;
private readonly int SIZE_ENTRY;
private const int MaxCount = 128;
public ShadowInfoTableXD(byte[] data)
public ShadowInfoTableXD(byte[] data, bool jp)
{
SIZE_ENTRY = GetEntrySize(jp);
MaxLength = data.Length;
int eCount = data.Length/SIZE_ENTRY;
Entries = new ShadowInfoEntryXD[eCount];
for (int i = 0; i < eCount; i++)
Entries[i] = GetEntry(data, i);
Entries[i] = GetEntry(data, i, jp);
}
public ShadowInfoTableXD() : this(new byte[SIZE_ENTRY * MaxCount]) { }
private static int GetEntrySize(bool jp) => jp ? ShadowInfoEntry3J.SIZE_ENTRY : ShadowInfoEntry3U.SIZE_ENTRY;
private static ShadowInfoEntryXD GetEntry(byte[] data, int index)
public ShadowInfoTableXD(bool jp) : this(new byte[GetEntrySize(jp) * MaxCount], jp) { }
private ShadowInfoEntryXD GetEntry(byte[] data, int index, bool jp)
{
var slice = data.Slice(index * SIZE_ENTRY, SIZE_ENTRY);
return new ShadowInfoEntryXD(slice);
return jp ? new ShadowInfoEntry3J(slice) : new ShadowInfoEntry3U(slice);
}
public byte[] Write() => Entries.SelectMany(entry => entry.Data).Take(MaxLength).ToArray();