using System; namespace PKHeX.Core; /// /// Contains logic that calculates the evolution chain of a , only considering the generation it originated in. /// public static class EncounterOrigin { /// /// Gets possible evolution details for the input /// /// Current state of the Pokémon /// Original Generation /// Possible origin species-form-levels to match against encounter data. /// Use if the originated from Generation 1 or 2. public static EvoCriteria[] GetOriginChain(PKM pk, byte generation) { var (minLevel, maxLevel) = GetMinMax(pk, generation); var origin = new EvolutionOrigin(pk.Species, (byte)pk.Version, generation, minLevel, maxLevel); return EvolutionChain.GetOriginChain(pk, origin); } /// /// Gets possible evolution details for the input originating from Generation 1 or 2. /// /// Current state of the Pokémon /// Game/group the originated from. If , it assumes Gen 1, otherwise Gen 2. /// Possible origin species-form-levels to match against encounter data. public static EvoCriteria[] GetOriginChain12(PKM pk, GameVersion gameSource) { var (minLevel, maxLevel) = GetMinMaxGB(pk); bool rby = gameSource == GameVersion.RBY; byte ver = rby ? (byte)GameVersion.RBY : (byte)GameVersion.GSC; byte gen = rby ? (byte)1 : (byte)2; var origin = new EvolutionOrigin(pk.Species, ver, gen, minLevel, maxLevel); return EvolutionChain.GetOriginChain(pk, origin); } private static (byte minLevel, byte maxLevel) GetMinMax(PKM pk, byte generation) { byte maxLevel = (byte)pk.CurrentLevel; byte minLevel = GetLevelOriginMin(pk, generation); return (minLevel, maxLevel); } private static (byte minLevel, byte maxLevel) GetMinMaxGB(PKM pk) { byte maxLevel = (byte)pk.CurrentLevel; byte minLevel = GetLevelOriginMinGB(pk); return (minLevel, maxLevel); } private static byte GetLevelOriginMin(PKM pk, byte generation) => generation switch { 3 => GetLevelOriginMin3(pk), 4 => GetLevelOriginMin4(pk), _ => Math.Max((byte)1, (byte)pk.Met_Level), }; private static bool IsEggLocationNonZero(PKM pk) => pk.Egg_Location != LocationEdits.GetNoneLocation(pk.Context); private static byte GetLevelOriginMinGB(PKM pk) { const byte EggLevel = 5; const byte MinWildLevel = 2; if (pk.IsEgg) return EggLevel; if (pk is not ICaughtData2 { CaughtData: not 0 } pk2) return MinWildLevel; return (byte)pk2.Met_Level; } private static byte GetLevelOriginMin3(PKM pk) { const byte EggLevel = 5; const byte MinWildLevel = 2; if (pk.Format != 3) return MinWildLevel; if (pk.IsEgg) return EggLevel; return (byte)pk.Met_Level; } private static byte GetLevelOriginMin4(PKM pk) { const byte EggLevel = 1; const byte MinWildLevel = 2; if (pk.Format != 4) return IsEggLocationNonZero(pk) ? EggLevel : MinWildLevel; if (pk.IsEgg || IsEggLocationNonZero(pk)) return EggLevel; return (byte)pk.Met_Level; } }