PKHeX/PKHeX.Core/Legality/Encounters/Verifiers/EvolutionVerifier.cs
Kurt 3c232505e5
Refactoring: Narrow some value types (Species, Move, Form) (#3575)
In this pull request I've changed a ton of method signatures to reflect the more-narrow types of Species, Move# and Form; additionally, I've narrowed other large collections that stored lists of species / permitted values, and reworked them to be more performant with the latest API spaghetti that PKHeX provides. Roamer met locations, usually in a range of [max-min]<64, can be quickly checked using a bitflag operation on a UInt64. Other collections (like "Is this from Colosseum or XD") were eliminated -- shadow state is not transferred COLO<->XD, so having a Shadow ID or matching the met location from a gift/wild encounter is a sufficient check for "originated in XD".
2022-08-26 23:43:36 -07:00

61 lines
2.5 KiB
C#

using static PKHeX.Core.EvolutionRestrictions;
using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core;
/// <summary>
/// Verify Evolution Information for a matched <see cref="IEncounterable"/>
/// </summary>
public static class EvolutionVerifier
{
/// <summary>
/// Verifies Evolution scenarios of an <see cref="IEncounterable"/> for an input <see cref="PKM"/> and relevant <see cref="LegalInfo"/>.
/// </summary>
/// <param name="pk">Source data to verify</param>
/// <param name="info">Source supporting information to verify with</param>
public static CheckResult VerifyEvolution(PKM pk, LegalInfo info)
{
// Check if basic evolution methods are satisfiable with this encounter.
if (!IsValidEvolution(pk, info))
return new CheckResult(Severity.Invalid, LEvoInvalid, CheckIdentifier.Evolution);
// Check if complex evolution methods are satisfiable with this encounter.
if (!IsValidEvolutionWithMove(pk, info))
return new CheckResult(Severity.Invalid, string.Format(LMoveEvoFCombination_0, ParseSettings.SpeciesStrings[pk.Species]), CheckIdentifier.Evolution);
return VALID;
}
private static readonly CheckResult VALID = new(CheckIdentifier.Evolution);
/// <summary>
/// Checks if the Evolution from the source <see cref="IEncounterable"/> is valid.
/// </summary>
/// <param name="pk">Source data to verify</param>
/// <param name="info">Source supporting information to verify with</param>
/// <returns>Evolution is valid or not</returns>
private static bool IsValidEvolution(PKM pk, LegalInfo info)
{
var chains = info.EvoChainsAllGens;
if (chains.Get(pk.Context).Length == 0)
return false; // Can't exist as current species
// OK if un-evolved from original encounter
ushort species = pk.Species;
var enc = info.EncounterMatch;
if (species == enc.Species) // never evolved
return true;
// Bigender->Fixed (non-Genderless) destination species, accounting for PID-Gender relationship
if (species == (int)Species.Vespiquen && enc.Generation < 6 && (pk.EncryptionConstant & 0xFF) >= 0x1F) // Combee->Vespiquen Invalid Evolution
return false;
// Double check that our encounter was able to exist as the encounter species.
foreach (var z in chains.Get(enc.Context))
{
if (z.Species == enc.Species)
return true;
}
return false;
}
}