using static PKHeX.Core.EvolutionRestrictions; using static PKHeX.Core.LegalityCheckStrings; namespace PKHeX.Core; /// /// Verify Evolution Information for a matched /// public static class EvolutionVerifier { /// /// Verifies Evolution scenarios of an for an input and relevant . /// /// Source data to verify /// Source supporting information to verify with 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); /// /// Checks if the Evolution from the source is valid. /// /// Source data to verify /// Source supporting information to verify with /// Evolution is valid or not 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; } }