Devirtualize GetMatchingSlots

This commit is contained in:
Kurt
2023-05-07 13:34:47 -07:00
parent e75da5d3b7
commit 5c70e41b76
18 changed files with 55 additions and 50 deletions

View File

@@ -1,5 +1,3 @@
using System.Collections.Generic;
namespace PKHeX.Core;
/// <summary>
@@ -10,14 +8,6 @@ public abstract record EncounterArea(GameVersion Version) : IVersion
public int Location { get; protected init; }
public SlotType Type { get; protected init; }
/// <summary>
/// Gets the slots contained in the area that match the provided data.
/// </summary>
/// <param name="pk">Pokémon Data</param>
/// <param name="chain">Evolution lineage</param>
/// <returns>Enumerable list of encounters</returns>
public abstract IEnumerable<EncounterSlot> GetMatchingSlots(PKM pk, EvoCriteria[] chain);
/// <summary>
/// Checks if the provided met location ID matches the parameters for the area.
/// </summary>

View File

@@ -43,7 +43,7 @@ private EncounterArea1(ReadOnlySpan<byte> data, GameVersion game) : base(game)
Slots = slots;
}
public override IEnumerable<EncounterSlot1> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot1> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
(bool useCatchRate, byte rate) = pk is PK1 pk1 ? (true, pk1.Catch_Rate) : (false, (byte)0);
foreach (var slot in Slots)

View File

@@ -66,7 +66,7 @@ private EncounterSlot2[] ReadSlots(ReadOnlySpan<byte> data, int count)
return slots;
}
public override IEnumerable<EncounterSlot2> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot2> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
if (pk is not ICaughtData2 {CaughtData: not 0} pk2)
return GetSlotsFuzzy(chain);

View File

@@ -110,7 +110,7 @@ private EncounterSlot3Swarm ReadSwarmSlot(ReadOnlySpan<byte> entry)
return new EncounterSlot3Swarm(this, species, min, max, slotNum, moves);
}
public override IEnumerable<EncounterSlot3> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot3> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
if (pk.Format != 3) // Met Location and Met Level are changed on PK3->PK4
return GetSlotsFuzzy(chain);

View File

@@ -23,7 +23,7 @@ public EncounterArea3XD(int loc, ushort s0, byte l0, ushort s1, byte l1, ushort
};
}
public override IEnumerable<EncounterSlot3PokeSpot> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot3PokeSpot> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
if (pk.Format != 3) // Met Location and Met Level are changed on PK3->PK4
return GetSlotsFuzzy(chain);

View File

@@ -62,7 +62,7 @@ private EncounterSlot4 ReadRegularSlot(ReadOnlySpan<byte> entry)
return new EncounterSlot4(this, species, form, min, max, slotNum, mpi, mpc, sti, stc);
}
public override IEnumerable<EncounterSlot4> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot4> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
if (pk.Format != 4) // Met Location and Met Level are changed on PK4->PK5
return GetSlotsFuzzy(chain);

View File

@@ -53,7 +53,7 @@ private EncounterSlot5 ReadSlot(ReadOnlySpan<byte> entry)
return new EncounterSlot5(this, species, form, min, max);
}
public override IEnumerable<EncounterSlot5> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot5> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
foreach (var slot in Slots)
{

View File

@@ -57,7 +57,7 @@ private EncounterSlot6AO ReadSlot(ReadOnlySpan<byte> entry)
private const int FluteBoostMax = 4; // Black Flute increases levels.
private const int DexNavBoost = 30; // Maximum DexNav chain
public override IEnumerable<EncounterSlot6AO> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot6AO> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
foreach (var slot in Slots)
{

View File

@@ -105,7 +105,7 @@ private EncounterSlot6XY[] ReadSlots(ReadOnlySpan<byte> data)
return slots;
}
public override IEnumerable<EncounterSlot6XY> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot6XY> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
foreach (var slot in Slots)
{

View File

@@ -53,7 +53,7 @@ private EncounterSlot7 ReadSlot(ReadOnlySpan<byte> entry)
return new EncounterSlot7(this, species, form, min, max);
}
public override IEnumerable<EncounterSlot7> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot7> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
foreach (var slot in Slots)
{

View File

@@ -52,7 +52,7 @@ private EncounterSlot7b ReadSlot(ReadOnlySpan<byte> entry)
private const int CatchComboBonus = 1;
public override IEnumerable<EncounterSlot7b> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot7b> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
foreach (var slot in Slots)
{

View File

@@ -66,11 +66,8 @@ private static EncounterSlot7GO ReadSlot(ReadOnlySpan<byte> entry, EncounterArea
return new EncounterSlot7GO(area, species, form, start, end, shiny, gender, type);
}
public override IEnumerable<EncounterSlot7GO> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot7GO> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
// Find the first chain that has slots defined.
// Since it is possible to evolve before transferring, we only need the highest evolution species possible.
// PoGoEncTool has already extrapolated the evolutions to separate encounters!
var sf = Array.Find(chain, z => z.Species == Species && z.Form == Form);
if (sf == default)
return Array.Empty<EncounterSlot7GO>();
@@ -80,6 +77,9 @@ public override IEnumerable<EncounterSlot7GO> GetMatchingSlots(PKM pk, EvoCriter
public IEnumerable<EncounterSlot7GO> GetMatchingSlots(PKM pk, EvoCriteria evo)
{
// Find the first chain that has slots defined.
// Since it is possible to evolve before transferring, we only need the highest evolution species possible.
// PoGoEncTool has already extrapolated the evolutions to separate encounters!
var stamp = EncounterSlotGO.GetTimeStamp(pk.Met_Year + 2000, pk.Met_Month, pk.Met_Day);
var met = Math.Max(evo.LevelMin, pk.Met_Level);
EncounterSlot7GO? deferredIV = null;

View File

@@ -38,7 +38,7 @@ public override bool IsMatchLocation(int location)
return Array.IndexOf(others, (byte)location) != -1;
}
public override IEnumerable<EncounterSlot8> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot8> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
var metLocation = pk.Met_Location;
// wild area gets boosted up to level 60 post-game

View File

@@ -18,7 +18,7 @@ public override bool IsMatchLocation(int location)
return Array.IndexOf(Locations, (byte)location) != -1;
}
public override IEnumerable<EncounterSlot8a> GetMatchingSlots(PKM pk, EvoCriteria[] chain) => GetMatches(chain, pk.Met_Level);
public IEnumerable<EncounterSlot8a> GetMatchingSlots(PKM pk, EvoCriteria[] chain) => GetMatches(chain, pk.Met_Level);
private IEnumerable<EncounterSlot8a> GetMatches(EvoCriteria[] chain, int metLevel)
{

View File

@@ -79,7 +79,7 @@ private bool CanCrossoverTo(int location)
return false;
}
public override IEnumerable<EncounterSlot8b> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot8b> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
foreach (var slot in Slots)
{

View File

@@ -66,7 +66,7 @@ private static EncounterSlot8GO ReadSlot(ReadOnlySpan<byte> entry, EncounterArea
return new EncounterSlot8GO(area, species, form, start, end, shiny, gender, type, format);
}
public override IEnumerable<EncounterSlot8GO> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot8GO> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
// Find the first chain that has slots defined.
// Since it is possible to evolve before transferring, we only need the highest evolution species possible.

View File

@@ -49,7 +49,7 @@ private EncounterSlot9[] ReadSlots(ReadOnlySpan<byte> areaData)
return result;
}
public override IEnumerable<EncounterSlot9> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
public IEnumerable<EncounterSlot9> GetMatchingSlots(PKM pk, EvoCriteria[] chain)
{
var lvl = pk.Met_Level;
foreach (var slot in Slots)

View File

@@ -222,21 +222,45 @@ public IEnumerable<IEncounterable> GetEncounters(PKM pk, EvoCriteria[] chain, Le
if (CanBeWildEncounter(pk))
{
var location = pk.Met_Location;
var areas = GetAreas(game);
foreach (var area in areas)
if (game is GameVersion.X or GameVersion.Y)
{
if (!area.IsMatchLocation(location))
continue;
var slots = area.GetMatchingSlots(pk, chain);
foreach (var slot in slots)
var areas = game == GameVersion.X ? Encounters6XY.SlotsX : Encounters6XY.SlotsY;
foreach (var area in areas)
{
var match = slot.GetMatchRating(pk);
switch (match)
if (!area.IsMatchLocation(location))
continue;
var slots = area.GetMatchingSlots(pk, chain);
foreach (var slot in slots)
{
case Match: yield return slot; yielded = true; break;
case Deferred: deferred ??= slot; break;
case PartialMatch: partial ??= slot; break;
var match = slot.GetMatchRating(pk);
switch (match)
{
case Match: yield return slot; yielded = true; break;
case Deferred: deferred ??= slot; break;
case PartialMatch: partial ??= slot; break;
}
}
}
}
else if (game is GameVersion.AS or GameVersion.OR)
{
var areas = game == GameVersion.AS ? Encounters6AO.SlotsA : Encounters6AO.SlotsO;
foreach (var area in areas)
{
if (!area.IsMatchLocation(location))
continue;
var slots = area.GetMatchingSlots(pk, chain);
foreach (var slot in slots)
{
var match = slot.GetMatchRating(pk);
switch (match)
{
case Match: yield return slot; yielded = true; break;
case Deferred: deferred ??= slot; break;
case PartialMatch: partial ??= slot; break;
}
}
}
}
@@ -282,15 +306,6 @@ public IEnumerable<IEncounterable> GetEncounters(PKM pk, EvoCriteria[] chain, Le
_ => throw new ArgumentOutOfRangeException(nameof(gameSource), gameSource, null),
};
private static EncounterArea[] GetAreas(GameVersion gameSource) => gameSource switch
{
GameVersion.X => Encounters6XY.SlotsX,
GameVersion.Y => Encounters6XY.SlotsY,
GameVersion.AS => Encounters6AO.SlotsA,
GameVersion.OR => Encounters6AO.SlotsO,
_ => throw new ArgumentOutOfRangeException(nameof(gameSource), gameSource, null),
};
private static EncounterTrade6[] GetTrades(GameVersion gameSource) => gameSource switch
{
GameVersion.X => Encounters6XY.TradeGift_XY,