Unify EvolutionSet deserialization

Reformat all pickles to the same serialization format (latest)
(format ignores all empty evo entries, to skip allocation of dead entries)
346KB -> 60.3KB, -200 lines of code
This commit is contained in:
Kurt 2023-07-12 19:09:23 -07:00
parent 292ea5ba44
commit 3a88190613
15 changed files with 14 additions and 226 deletions

View file

@ -4,9 +4,9 @@ using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
/// <summary>
/// Generation 7 Evolution Branch Entries
/// Evolution Branch Binary Unpacker
/// </summary>
public static class EvolutionSet7
public static class EvolutionSet
{
private const int SIZE = 8;

View file

@ -1,41 +0,0 @@
using System;
namespace PKHeX.Core;
/// <summary>
/// Generation 1 Evolution Branch Entries
/// </summary>
public static class EvolutionSet1
{
private static EvolutionMethod GetMethod(ReadOnlySpan<byte> data)
{
var method = data[0];
var species = data[1];
var arg = data[2];
return method == 1
? new EvolutionMethod(EvolutionType.LevelUp, species, Level: arg, LevelUp: 1)
: new EvolutionMethod((EvolutionType)method, species, Argument: arg);
}
public static EvolutionMethod[][] GetArray(ReadOnlySpan<byte> data, int maxSpecies)
{
var result = new EvolutionMethod[maxSpecies + 1][];
for (int i = 0, offset = 0; i < result.Length; i++)
result[i] = GetEntry(data, ref offset);
return result;
}
private static EvolutionMethod[] GetEntry(ReadOnlySpan<byte> data, ref int offset)
{
var count = data[offset++];
if (count == 0)
return Array.Empty<EvolutionMethod>();
const int bpe = 3;
var result = new EvolutionMethod[count];
for (int i = 0; i < result.Length; i++, offset += bpe)
result[i] = GetMethod(data.Slice(offset, bpe));
return result;
}
}

View file

@ -1,86 +0,0 @@
using System;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
/// <summary>
/// Generation 3 Evolution Branch Entries
/// </summary>
public static class EvolutionSet3
{
private static EvolutionMethod GetMethod(ReadOnlySpan<byte> data)
{
var method = data[0];
var arg = ReadUInt16LittleEndian(data[2..]);
var species = SpeciesConverter.GetNational3(ReadUInt16LittleEndian(data[4..]));
//2 bytes padding
switch (method)
{
case 1: /* Friendship*/
case 2: /* Friendship day*/
case 3: /* Friendship night*/
return new EvolutionMethod((EvolutionType)method, species, Argument: arg, LevelUp: 1);
case 5: /* Trade */
case 6: /* Trade while holding */
return new EvolutionMethod((EvolutionType)method, species, Argument: arg);
case 4: /* Level Up */
return new EvolutionMethod(EvolutionType.LevelUp, species, Argument: arg, Level: (byte)arg, LevelUp: 1);
case 7: /* Use item */
return new EvolutionMethod((EvolutionType)(method + 1), species, Argument: arg);
case 15: /* Beauty evolution*/
return new EvolutionMethod((EvolutionType)(method + 1), species, Argument: arg, LevelUp: 1);
case 8: /* Tyrogue -> Hitmonchan */
case 9: /* Tyrogue -> Hitmonlee */
case 10: /* Tyrogue -> Hitmontop*/
case 11: /* Wurmple -> Silcoon evolution */
case 12: /* Wurmple -> Cascoon evolution */
case 13: /* Nincada -> Ninjask evolution */
case 14: /* Shedinja spawn in Nincada -> Ninjask evolution */
return new EvolutionMethod((EvolutionType)(method + 1), species, Argument: arg, Level: (byte)arg, LevelUp: 1);
default:
throw new ArgumentOutOfRangeException(nameof(method));
}
}
public static EvolutionMethod[][] GetArray(ReadOnlySpan<byte> data)
{
var result = new EvolutionMethod[Legal.MaxSpeciesID_3 + 1][];
result[0] = Array.Empty<EvolutionMethod>();
for (ushort i = 1; i <= Legal.MaxSpeciesIndex_3; i++)
{
int g4species = SpeciesConverter.GetNational3(i);
if (g4species != 0)
result[g4species] = GetEntry(data, i);
}
return result;
}
private const int maxCount = 5;
private const int size = 8;
private static EvolutionMethod[] GetEntry(ReadOnlySpan<byte> data, ushort index)
{
var span = data.Slice(index * (maxCount * size), maxCount * size);
int count = ScanCountEvolutions(span);
if (count == 0)
return Array.Empty<EvolutionMethod>();
var result = new EvolutionMethod[count];
for (int i = 0, offset = 0; i < result.Length; i++, offset += size)
result[i] = GetMethod(span.Slice(offset, size));
return result;
}
private static int ScanCountEvolutions(ReadOnlySpan<byte> span)
{
for (int count = 0; count < maxCount; count++)
{
if (span[count * size] == 0)
return count;
}
return maxCount;
}
}

View file

@ -1,42 +0,0 @@
using System;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
/// <summary>
/// Generation 5 Evolution Branch Entries
/// </summary>
public static class EvolutionSet5
{
private static EvolutionMethod GetMethod(ReadOnlySpan<byte> data)
{
var method = data[0]; // other byte unnecessary
var arg = ReadUInt16LittleEndian(data[2..]);
var species = ReadUInt16LittleEndian(data[4..]);
var lvl = EvolutionSet6.IsMethodWithArg(method) ? 0 : arg;
var type = (EvolutionType)method;
var lvlup = type.IsLevelUpRequired() ? (byte)1 : (byte)0;
return new EvolutionMethod(type, species, Argument: arg, Level: (byte)lvl, LevelUp: lvlup);
}
private const int bpe = 6; // bytes per evolution entry
public static EvolutionMethod[][] GetArray(BinLinkerAccessor data)
{
var result = new EvolutionMethod[data.Length][];
for (int i = 0; i < result.Length; i++)
result[i] = GetEntry(data[i]);
return result;
}
private static EvolutionMethod[] GetEntry(ReadOnlySpan<byte> data)
{
if (data.Length == 0)
return Array.Empty<EvolutionMethod>();
var result = new EvolutionMethod[data.Length / bpe];
for (int i = 0, offset = 0; i < result.Length; i++, offset += bpe)
result[i] = GetMethod(data.Slice(offset, bpe));
return result;
}
}

View file

@ -1,43 +0,0 @@
using System;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
/// <summary>
/// Generation 6 Evolution Branch Entries
/// </summary>
public static class EvolutionSet6
{
// 6, 8, 16, 17, 18, 19, 20, 21, 22, 29
internal static bool IsMethodWithArg(byte method) => (0b100000011111110000000101000000 & (1 << method)) != 0;
private const int SIZE = 6;
public static EvolutionMethod[][] GetArray(BinLinkerAccessor data)
{
var result = new EvolutionMethod[data.Length][];
for (int i = 0; i < result.Length; i++)
result[i] = GetEntry(data[i]);
return result;
}
private static EvolutionMethod[] GetEntry(ReadOnlySpan<byte> data)
{
var result = new EvolutionMethod[data.Length / SIZE];
for (int i = 0, offset = 0; i < result.Length; i++, offset += SIZE)
result[i] = GetMethod(data.Slice(offset, SIZE));
return result;
}
private static EvolutionMethod GetMethod(ReadOnlySpan<byte> entry)
{
var method = entry[0];
var arg = ReadUInt16LittleEndian(entry[2..]);
var species = ReadUInt16LittleEndian(entry[4..]);
// Argument is used by both Level argument and Item/Move/etc. Clear if appropriate.
var lvl = IsMethodWithArg(method) ? 0 : arg;
var type = (EvolutionType)method;
var lvlup = type.IsLevelUpRequired() ? (byte)1 : (byte)0;
return new EvolutionMethod(type, species, Argument: arg, Level: (byte)lvl, LevelUp: lvlup);
}
}

View file

@ -11,18 +11,18 @@ namespace PKHeX.Core;
public sealed class EvolutionTree : EvolutionNetwork
{
public const int MaxEvolutions = 3;
public static readonly EvolutionTree Evolves1 = GetViaSpecies (PersonalTable.Y, EvolutionSet1.GetArray(GetResource("rby"), 151));
public static readonly EvolutionTree Evolves2 = GetViaSpecies (PersonalTable.C, EvolutionSet1.GetArray(GetResource("gsc"), 251));
public static readonly EvolutionTree Evolves3 = GetViaSpecies (PersonalTable.RS, EvolutionSet3.GetArray(GetResource("g3")));
public static readonly EvolutionTree Evolves4 = GetViaSpecies (PersonalTable.DP, EvolutionSet5.GetArray(GetReader("g4")));
public static readonly EvolutionTree Evolves5 = GetViaSpecies (PersonalTable.BW, EvolutionSet5.GetArray(GetReader("g5")));
public static readonly EvolutionTree Evolves6 = GetViaSpecies (PersonalTable.AO, EvolutionSet6.GetArray(GetReader("ao")));
public static readonly EvolutionTree Evolves7 = GetViaPersonal(PersonalTable.USUM, EvolutionSet7.GetArray(GetReader("uu")));
public static readonly EvolutionTree Evolves7b = GetViaPersonal(PersonalTable.GG, EvolutionSet7.GetArray(GetReader("gg")));
public static readonly EvolutionTree Evolves8 = GetViaPersonal(PersonalTable.SWSH, EvolutionSet7.GetArray(GetReader("ss")));
public static readonly EvolutionTree Evolves8a = GetViaPersonal(PersonalTable.LA, EvolutionSet7.GetArray(GetReader("la"), 0));
public static readonly EvolutionTree Evolves8b = GetViaPersonal(PersonalTable.BDSP, EvolutionSet7.GetArray(GetReader("bs")));
public static readonly EvolutionTree Evolves9 = GetViaPersonal(PersonalTable.SV, EvolutionSet7.GetArray(GetReader("sv")));
public static readonly EvolutionTree Evolves1 = GetViaSpecies (PersonalTable.Y, EvolutionSet.GetArray(GetReader("g1")));
public static readonly EvolutionTree Evolves2 = GetViaSpecies (PersonalTable.C, EvolutionSet.GetArray(GetReader("g2")));
public static readonly EvolutionTree Evolves3 = GetViaSpecies (PersonalTable.RS, EvolutionSet.GetArray(GetReader("g3")));
public static readonly EvolutionTree Evolves4 = GetViaSpecies (PersonalTable.DP, EvolutionSet.GetArray(GetReader("g4")));
public static readonly EvolutionTree Evolves5 = GetViaSpecies (PersonalTable.BW, EvolutionSet.GetArray(GetReader("g5")));
public static readonly EvolutionTree Evolves6 = GetViaSpecies (PersonalTable.AO, EvolutionSet.GetArray(GetReader("g6")));
public static readonly EvolutionTree Evolves7 = GetViaPersonal(PersonalTable.USUM, EvolutionSet.GetArray(GetReader("uu")));
public static readonly EvolutionTree Evolves7b = GetViaPersonal(PersonalTable.GG, EvolutionSet.GetArray(GetReader("gg")));
public static readonly EvolutionTree Evolves8 = GetViaPersonal(PersonalTable.SWSH, EvolutionSet.GetArray(GetReader("ss")));
public static readonly EvolutionTree Evolves8a = GetViaPersonal(PersonalTable.LA, EvolutionSet.GetArray(GetReader("la"), 0));
public static readonly EvolutionTree Evolves8b = GetViaPersonal(PersonalTable.BDSP, EvolutionSet.GetArray(GetReader("bs")));
public static readonly EvolutionTree Evolves9 = GetViaPersonal(PersonalTable.SV, EvolutionSet.GetArray(GetReader("sv")));
private static ReadOnlySpan<byte> GetResource(string resource) => Util.GetBinaryResource($"evos_{resource}.pkl");
private static BinLinkerAccessor GetReader(string resource) => BinLinkerAccessor.Get(GetResource(resource), resource);

Binary file not shown.

Binary file not shown.

Binary file not shown.