public static IEnumerable <IEncounterable> GetEncounters(PKM pk)
    {
        var chain = EncounterOrigin.GetOriginChain(pk);

        return(pk.Version switch
        {
            (int)GameVersion.GO => GetEncountersGO(pk, chain),
            > (int)GameVersion.GO => GetEncountersGG(pk, chain),
            _ => GetEncountersMainline(pk, chain),
        });
    public static IEnumerable <IEncounterable> GetEncounters(PKM pk)
    {
        var chain = EncounterOrigin.GetOriginChain(pk);

        return(pk.Version switch
        {
            (int)GameVersion.GO => EncounterGenerator7.GetEncountersGO(pk, chain),
            (int)GameVersion.PLA => EncounterGenerator8a.GetEncounters(pk, chain),
            (int)GameVersion.BD or(int) GameVersion.SP => EncounterGenerator8b.GetEncounters(pk, chain),
            (int)GameVersion.SW when pk.Met_Location == Locations.HOME_SWLA => EncounterGenerator8a.GetEncounters(pk, chain),
            (int)GameVersion.SW when pk.Met_Location == Locations.HOME_SWBD => EncounterGenerator8b.GetEncountersFuzzy(pk, chain, GameVersion.BD),
            (int)GameVersion.SH when pk.Met_Location == Locations.HOME_SHSP => EncounterGenerator8b.GetEncountersFuzzy(pk, chain, GameVersion.SP),
            _ => GetEncountersMainline(pk, chain),
        });
    public static IEnumerable <IEncounterable> GetEncounters(PKM pk)
    {
        int ctr = 0;

        var chain = EncounterOrigin.GetOriginChain(pk);
        var game  = (GameVersion)pk.Version;

        IEncounterable?deferred = null;
        IEncounterable?partial  = null;

        if (pk.FatefulEncounter || pk.Met_Location == Locations.LinkGift6)
        {
            foreach (var z in GetValidGifts(pk, chain, game))
            {
                var match = z.GetMatchRating(pk);
                switch (match)
                {
                case Match: yield return(z); break;

                case Deferred: deferred ??= z; break;

                case PartialMatch: partial ??= z; break;
                }
                ++ctr;
            }

            if (ctr != 0)
            {
                if (deferred != null)
                {
                    yield return(deferred);
                }

                if (partial != null)
                {
                    yield return(partial);
                }

                yield break;
            }
        }

        if (Locations.IsEggLocationBred6(pk.Egg_Location))
        {
            foreach (var z in GenerateEggs(pk, 6))
            {
                yield return(z); ++ctr;
            }
            if (ctr == 0)
            {
                yield break;
            }
        }

        foreach (var z in GetValidStaticEncounter(pk, chain, game))
        {
            var match = z.GetMatchRating(pk);
            switch (match)
            {
            case Match: yield return(z); ++ctr; break;

            case Deferred: deferred ??= z; break;

            case PartialMatch: partial ??= z; break;
            }
        }
        if (ctr != 0)
        {
            yield break;
        }

        foreach (var z in GetValidWildEncounters(pk, chain, game))
        {
            var match = z.GetMatchRating(pk);
            switch (match)
            {
            case Match: yield return(z); ++ctr; break;

            case Deferred: deferred ??= z; break;

            case PartialMatch: partial ??= z; break;
            }
        }
        if (ctr != 0)
        {
            yield break;
        }

        foreach (var z in GetValidEncounterTrades(pk, chain, game))
        {
            var match = z.GetMatchRating(pk);
            switch (match)
            {
            case Match: yield return(z); /*++ctr*/ break;

            case Deferred: deferred ??= z; break;

            case PartialMatch: partial ??= z; break;
            }
        }

        if (deferred != null)
        {
            yield return(deferred);
        }

        if (partial != null)
        {
            yield return(partial);
        }
    }
    private static IEnumerable <IEncounterable> GenerateRawEncounters3CXD(PKM pk)
    {
        var chain = EncounterOrigin.GetOriginChain(pk);

        var game = (GameVersion)pk.Version;

        // Mystery Gifts
        foreach (var z in GetValidGifts(pk, chain, game))
        {
            // Don't bother deferring matches.
            var match = z.GetMatchRating(pk);
            if (match != PartialMatch)
            {
                yield return(z);
            }
        }

        // Trades
        foreach (var z in GetValidEncounterTrades(pk, chain, game))
        {
            // Don't bother deferring matches.
            var match = z.GetMatchRating(pk);
            if (match != PartialMatch)
            {
                yield return(z);
            }
        }

        IEncounterable?partial = null;

        // Static Encounter
        foreach (var z in GetValidStaticEncounter(pk, chain, game))
        {
            var match = z.GetMatchRating(pk);
            if (match == PartialMatch)
            {
                partial ??= z;
            }
            else
            {
                yield return(z);
            }
        }

        // Encounter Slots
        foreach (var z in GetValidWildEncounters(pk, chain, game))
        {
            var match = z.GetMatchRating(pk);
            if (match == PartialMatch)
            {
                partial ??= z;
                continue;
            }
            yield return(z);
        }

        if (partial is not null)
        {
            yield return(partial);
        }
    }
    private static IEnumerable <IEncounterable> GenerateRawEncounters3(PKM pk, LegalInfo info)
    {
        var chain = EncounterOrigin.GetOriginChain(pk);
        var game  = (GameVersion)pk.Version;

        // Mystery Gifts
        foreach (var z in GetValidGifts(pk, chain, game))
        {
            // Don't bother deferring matches.
            var match = z.GetMatchRating(pk);
            if (match != PartialMatch)
            {
                yield return(z);
            }
        }

        // Trades
        foreach (var z in GetValidEncounterTrades(pk, chain, game))
        {
            // Don't bother deferring matches.
            var match = z.GetMatchRating(pk);
            if (match != PartialMatch)
            {
                yield return(z);
            }
        }

        IEncounterable?deferred = null;
        IEncounterable?partial  = null;

        // Static Encounter
        // Defer everything if Safari Ball
        bool safari = pk.Ball == 0x05; // never static encounters

        if (!safari)
        {
            foreach (var z in GetValidStaticEncounter(pk, chain, game))
            {
                var match = z.GetMatchRating(pk);
                if (match == PartialMatch)
                {
                    partial ??= z;
                }
                else
                {
                    yield return(z);
                }
            }
        }

        // Encounter Slots
        var slots = FrameFinder.GetFrames(info.PIDIV, pk).ToList();

        foreach (var z in GetValidWildEncounters(pk, chain, game))
        {
            var match = z.GetMatchRating(pk);
            if (match == PartialMatch)
            {
                partial ??= z;
                continue;
            }

            var frame = slots.Find(s => s.IsSlotCompatibile((EncounterSlot3)z, pk));
            if (frame == null)
            {
                deferred ??= z;
                continue;
            }
            yield return(z);
        }

        info.FrameMatches = false;
        if (deferred is EncounterSlot3 x)
        {
            yield return(x);
        }

        if (pk.Version != (int)GameVersion.CXD) // no eggs in C/XD
        {
            foreach (var z in GenerateEggs(pk, 3))
            {
                yield return(z);
            }
        }

        if (partial is EncounterSlot3 y)
        {
            var frame = slots.Find(s => s.IsSlotCompatibile(y, pk));
            info.FrameMatches = frame != null;
            yield return(y);
        }

        // do static encounters if they were deferred to end, spit out any possible encounters for invalid pk
        if (!safari)
        {
            yield break;
        }

        partial = null;

        foreach (var z in GetValidStaticEncounter(pk, chain, game))
        {
            var match = z.GetMatchRating(pk);
            if (match == PartialMatch)
            {
                partial ??= z;
            }
            else
            {
                yield return(z);
            }
        }

        if (partial is not null)
        {
            yield return(partial);
        }
    }