Example #1
0
        private static IEnumerable <IEncounterable> GenerateFilteredEncounters12(PKM pkm)
        {
            bool crystal = (pkm.Format == 2 && pkm.Met_Location != 0) || (pkm.Format >= 7 && pkm.OT_Gender == 1);
            bool kadabra = pkm.Species == 64 && pkm is PK1 pk1 &&
                           (pk1.Catch_Rate == PersonalTable.RB[64].CatchRate ||
                            pk1.Catch_Rate == PersonalTable.Y[64].CatchRate);    // catch rate outsider, return gen1 first always

            // iterate over both games, consuming from one list at a time until the other list has higher priority encounters
            var get1 = GenerateRawEncounters1(pkm, crystal);
            var get2 = GenerateRawEncounters2(pkm, crystal);
            var g1i  = new PeekEnumerator <IEncounterable>(get1);
            var g2i  = new PeekEnumerator <IEncounterable>(get2);

            var deferred = new List <IEncounterable>();

            while (g2i.PeekIsNext() || g1i.PeekIsNext())
            {
                var move = GetPreferredGBIterator(pkm, g1i, g2i);
                var obj  = move.Peek();
                int gen  = obj is IGeneration g ? g.Generation : 2; // only eggs don't implement interface

                if (gen == 1 && (pkm.Korean || (obj is EncounterTrade t && !IsEncounterTrade1Valid(pkm, t))))
                {
                    deferred.Add(obj);
                }
Example #2
0
        /// <summary>
        /// Checks supplementary info to see if the encounter is still valid.
        /// </summary>
        /// <remarks>
        /// When an encounter is initially validated, only encounter-related checks are performed.
        /// By checking Moves, Evolution, and <see cref="PIDIV"/> data, a best match encounter can be found.
        /// If the encounter is not valid, the method will not reject it unless another encounter is available to check.
        /// </remarks>
        /// <param name="pkm">Source data to check the match for</param>
        /// <param name="info">Information containing the matched encounter</param>
        /// <param name="iterator">Peekable iterator </param>
        /// <returns>Indication whether or not the encounter passes secondary checks</returns>
        private static bool VerifySecondaryChecks(PKM pkm, LegalInfo info, PeekEnumerator <IEncounterable> iterator)
        {
            if (pkm.Format >= 6)
            {
                info.Relearn = VerifyRelearnMoves.VerifyRelearn(pkm, info);
                if (info.Relearn.Any(z => !z.Valid) && iterator.PeekIsNext())
                {
                    return(false);
                }
            }
            else
            {
                for (int i = 0; i < 4; i++)
                {
                    info.Relearn[i] = new CheckResult(CheckIdentifier.RelearnMove);
                }
            }

            info.Moves = VerifyCurrentMoves.VerifyMoves(pkm, info);
            if (info.Moves.Any(z => !z.Valid) && iterator.PeekIsNext())
            {
                return(false);
            }

            var evo = EvolutionVerifier.VerifyEvolution(pkm, info);

            if (!evo.Valid && iterator.PeekIsNext())
            {
                return(false);
            }
            info.Parse.Add(evo);

            return(true);
        }
Example #3
0
        /// <summary>
        /// Iterates through all possible encounters until a sufficient match is found
        /// </summary>
        /// <remarks>
        /// The iterator lazily finds matching encounters, then verifies secondary checks to weed out any nonexact matches.
        /// </remarks>
        /// <param name="pkm">Source data to find a match for</param>
        /// <param name="info">Object to store matched encounter info</param>
        /// <returns>
        /// Information containing the matched encounter and any parsed checks.
        /// If no clean match is found, the last checked match is returned.
        /// If no match is found, an invalid encounter object is returned.
        /// </returns>
        public static void FindVerifiedEncounter(PKM pkm, LegalInfo info)
        {
            var encounters = EncounterGenerator.GetEncounters(pkm, info);

            using var encounter = new PeekEnumerator <IEncounterable>(encounters);
            if (!encounter.PeekIsNext())
            {
                VerifyWithoutEncounter(pkm, info);
                return;
            }

            var first = encounter.Current;
            var EncounterValidator = EncounterVerifier.GetEncounterVerifierMethod(first.Generation);

            while (encounter.MoveNext())
            {
                var enc = encounter.Current;

                // Check for basic compatibility.
                var e = EncounterValidator(pkm, enc);
                if (!e.Valid && encounter.PeekIsNext())
                {
                    info.Reject(e);
                    continue;
                }

                // Looks like we might have a good enough match. Check if this is really a good match.
                info.EncounterMatch = enc;
                info.Parse.Add(e);
                if (!VerifySecondaryChecks(pkm, info, encounter))
                {
                    continue;
                }

                // Sanity Check -- Some secondary checks might not be as thorough as the partial-match leak-through checks done by the encounter.
                if (enc is not IEncounterMatch mx)
                {
                    break;
                }

                var match = mx.GetMatchRating(pkm);
                if (match != EncounterMatchRating.PartialMatch)
                {
                    break;
                }

                // Reaching here implies the encounter wasn't valid. Try stepping to the next encounter.
                if (encounter.PeekIsNext())
                {
                    continue;
                }

                // We ran out of possible encounters without finding a suitable match; add a message indicating that the encounter is not a complete match.
                info.Parse.Add(new CheckResult(Severity.Invalid, LEncInvalid, CheckIdentifier.Encounter));
                break;
            }

            if (!info.FrameMatches && info.EncounterMatch is EncounterSlot {
                Version : not GameVersion.CXD
            })                                                                                                                  // if false, all valid RNG frame matches have already been consumed
Example #4
0
        /// <summary>
        /// Iterates through all possible encounters until a sufficient match is found
        /// </summary>
        /// <remarks>
        /// The iterator lazily finds matching encounters, then verifies secondary checks to weed out any nonexact matches.
        /// </remarks>
        /// <param name="pkm">Source data to find a match for</param>
        /// <returns>
        /// Information containing the matched encounter and any parsed checks.
        /// If no clean match is found, the last checked match is returned.
        /// If no match is found, an invalid encounter object is returned.
        /// </returns>
        public static LegalInfo FindVerifiedEncounter(PKM pkm)
        {
            LegalInfo info       = new LegalInfo(pkm);
            var       encounters = EncounterGenerator.GetEncounters(pkm, info);

            using (var encounter = new PeekEnumerator <IEncounterable>(encounters.GetEnumerator()))
            {
                if (!encounter.PeekIsNext())
                {
                    return(VerifyWithoutEncounter(pkm, info));
                }

                var EncounterValidator = EncounterVerifier.GetEncounterVerifierMethod(pkm);
                while (encounter.MoveNext())
                {
                    info.EncounterMatch = encounter.Current;
                    var e = EncounterValidator(pkm, info);
                    if (!e.Valid && encounter.PeekIsNext())
                    {
                        info.Reject(e);
                        continue;
                    }
                    info.Parse.Add(e);

                    if (VerifySecondaryChecks(pkm, info, encounter))
                    {
                        break; // passes
                    }
                }
                return(info);
            }
        }
Example #5
0
        /// <summary>
        /// Iterates through all possible encounters until a sufficient match is found
        /// </summary>
        /// <remarks>
        /// The iterator lazily finds matching encounters, then verifies secondary checks to weed out any nonexact matches.
        /// </remarks>
        /// <param name="pkm">Source data to find a match for</param>
        /// <returns>
        /// Information containing the matched encounter and any parsed checks.
        /// If no clean match is found, the last checked match is returned.
        /// If no match is found, an invalid encounter object is returned.
        /// </returns>
        public static LegalInfo FindVerifiedEncounter(PKM pkm)
        {
            var info       = new LegalInfo(pkm);
            var encounters = EncounterGenerator.GetEncounters(pkm, info);

            using var encounter = new PeekEnumerator <IEncounterable>(encounters);
            if (!encounter.PeekIsNext())
            {
                return(VerifyWithoutEncounter(pkm, info));
            }

            var EncounterValidator = EncounterVerifier.GetEncounterVerifierMethod(pkm);

            while (encounter.MoveNext())
            {
                info.EncounterMatch = encounter.Current;
                var e = EncounterValidator(pkm, info);
                if (!e.Valid && encounter.PeekIsNext())
                {
                    info.Reject(e);
                    continue;
                }
                info.Parse.Add(e);

                if (VerifySecondaryChecks(pkm, info, encounter))
                    break; // passes
            }

            if (!info.FrameMatches && info.EncounterMatch is EncounterSlot {
                Version : not GameVersion.CXD
            })                                                                                                                  // if false, all valid RNG frame matches have already been consumed
Example #6
0
        /// <summary>
        /// Iterates through all possible encounters until a sufficient match is found
        /// </summary>
        /// <remarks>
        /// The iterator lazily finds matching encounters, then verifies secondary checks to weed out any nonexact matches.
        /// </remarks>
        /// <param name="pkm">Source data to find a match for</param>
        /// <param name="info">Object to store matched encounter info</param>
        /// <returns>
        /// Information containing the matched encounter and any parsed checks.
        /// If no clean match is found, the last checked match is returned.
        /// If no match is found, an invalid encounter object is returned.
        /// </returns>
        public static void FindVerifiedEncounter(PKM pkm, LegalInfo info)
        {
            var encounters = EncounterGenerator.GetEncounters(pkm, info);

            using var encounter = new PeekEnumerator <IEncounterable>(encounters);
            if (!encounter.PeekIsNext())
            {
                VerifyWithoutEncounter(pkm, info);
                return;
            }

            var EncounterValidator = EncounterVerifier.GetEncounterVerifierMethod(pkm);

            while (encounter.MoveNext())
            {
                info.EncounterMatch = encounter.Current;
                var e = EncounterValidator(pkm, info);
                if (!e.Valid && encounter.PeekIsNext())
                {
                    info.Reject(e);
                    continue;
                }
                info.Parse.Add(e);

                if (!VerifySecondaryChecks(pkm, info, encounter))
                {
                    continue;
                }

                // Sanity Check -- Some secondary checks might not be as thorough as the partial-match leak-through checks done by the encounter.
                if (info.EncounterMatch is not IEncounterMatch mx)
                {
                    break;
                }

                var match = mx.GetMatchRating(pkm);
                if (match != EncounterMatchRating.PartialMatch)
                {
                    break;
                }

                if (encounter.PeekIsNext())
                {
                    continue;
                }

                info.Parse.Add(new CheckResult(Severity.Invalid, LEncInvalid, CheckIdentifier.Encounter));
                break;
            }

            if (!info.FrameMatches && info.EncounterMatch is EncounterSlot {
                Version : not GameVersion.CXD
            })                                                                                                                  // if false, all valid RNG frame matches have already been consumed
Example #7
0
 /// <summary>
 /// Gets the preferred iterator from a pair of <see cref="GBEncounterData"/> iterators based on the highest value <see cref="GBEncounterData.Type"/>.
 /// </summary>
 /// <param name="g1i">Generation 1 Iterator</param>
 /// <param name="g2i">Generation 2 Iterator</param>
 /// <returns>Preferred iterator </returns>
 private static PeekEnumerator <GBEncounterData> GetPreferredGBIterator(PeekEnumerator <GBEncounterData> g1i, PeekEnumerator <GBEncounterData> g2i)
 {
     if (!g1i.PeekIsNext())
     {
         return(g2i);
     }
     if (!g2i.PeekIsNext())
     {
         return(g1i);
     }
     return(g1i.Peek().Type > g2i.Peek().Type ? g1i : g2i);
 }
Example #8
0
        private static IEnumerable <GBEncounterData> GenerateFilteredEncounters(PKM pkm)
        {
            bool crystal  = pkm.Format == 2 && pkm.Met_Location != 0 || pkm.Format >= 7 && pkm.OT_Gender == 1;
            var  g1i      = new PeekEnumerator <GBEncounterData>(get1());
            var  g2i      = new PeekEnumerator <GBEncounterData>(get2());
            var  deferred = new List <GBEncounterData>();

            while (g2i.PeekIsNext() || g1i.PeekIsNext())
            {
                var move = GetPreferredGBIterator(g1i, g2i);
                var obj  = move.Peek();

                if (obj.Generation == 1 && obj.Encounter is EncounterTrade && !IsEncounterTrade1Valid(pkm))
                {
                    deferred.Add(obj);
                }
                else
                {
                    yield return(obj);
                }
                pkm.WasEgg = false;
                move.MoveNext();
            }
            foreach (var z in deferred)
            {
                yield return(z);
            }

            IEnumerable <GBEncounterData> get1()
            {
                if (!pkm.Gen2_NotTradeback && !crystal)
                {
                    foreach (var z in GenerateRawEncounters12(pkm, GameVersion.RBY))
                    {
                        yield return(z);
                    }
                }
            }

            IEnumerable <GBEncounterData> get2()
            {
                if (!pkm.Gen1_NotTradeback)
                {
                    foreach (var z in GenerateRawEncounters12(pkm, crystal ? GameVersion.C : GameVersion.GSC))
                    {
                        yield return(z);
                    }
                }
            }
        }
Example #9
0
        private static IEnumerable <GBEncounterData> GenerateFilteredEncounters(PKM pkm)
        {
            bool crystal  = pkm.Format == 2 && pkm.Met_Location != 0 || pkm.Format >= 7 && pkm.OT_Gender == 1;
            var  g1i      = new PeekEnumerator <GBEncounterData>(get1());
            var  g2i      = new PeekEnumerator <GBEncounterData>(get2());
            var  deferred = new List <GBEncounterData>();

            while (g2i.PeekIsNext() || g1i.PeekIsNext())
            {
                var move = GetPreferredGBIterator(g1i, g2i);
                var obj  = move.Peek();

                if ((obj.Generation == 1 && (pkm.Korean || (obj.Encounter is EncounterTrade && !IsEncounterTrade1Valid(pkm)))) ||
                    (obj.Generation == 2 && (pkm.Korean && (obj.Encounter is IVersion v && v.Version == GameVersion.C))))
                {
                    deferred.Add(obj);
                }
Example #10
0
        private static IEnumerable <IEncounterable> GenerateFilteredEncounters12Both(PKM pkm)
        {
            // Iterate over both games, consuming from one list at a time until the other list has higher priority encounters
            // Buffer the encounters so that we can consume each iterator separately
            var get1 = GenerateRawEncounters12(pkm, GameVersion.RBY);
            var get2 = GenerateRawEncounters12(pkm, GameVersion.GSC);

            using var g1i = new PeekEnumerator <IEncounterable>(get1);
            using var g2i = new PeekEnumerator <IEncounterable>(get2);
            while (g2i.PeekIsNext() || g1i.PeekIsNext())
            {
                var iter = PickPreferredIterator(pkm, g1i, g2i);
                yield return(iter.Current);

                iter.MoveNext();
            }
        }
Example #11
0
        /// <summary>
        /// Iterates through all possible encounters until a sufficient match is found
        /// </summary>
        /// <remarks>
        /// The iterator lazily finds matching encounters, then verifies secondary checks to weed out any nonexact matches.
        /// </remarks>
        /// <param name="pkm">Source data to find a match for</param>
        /// <returns>
        /// Information containing the matched encounter and any parsed checks.
        /// If no clean match is found, the last checked match is returned.
        /// If no match is found, an invalid encounter object is returned.
        /// </returns>
        public static LegalInfo FindVerifiedEncounter(PKM pkm)
        {
            LegalInfo info       = new LegalInfo(pkm);
            var       encounters = EncounterGenerator.GetEncounters(pkm, info);

            using (var encounter = new PeekEnumerator <IEncounterable>(encounters))
            {
                if (!encounter.PeekIsNext())
                {
                    return(VerifyWithoutEncounter(pkm, info));
                }

                var EncounterValidator = EncounterVerifier.GetEncounterVerifierMethod(pkm);
                while (encounter.MoveNext())
                {
                    info.EncounterMatch = encounter.Current;
                    var e = EncounterValidator(pkm, info);
                    if (!e.Valid && encounter.PeekIsNext())
                    {
                        info.Reject(e);
                        continue;
                    }
                    info.Parse.Add(e);

                    if (VerifySecondaryChecks(pkm, info, encounter))
                    {
                        break; // passes
                    }
                }

                if (!info.FrameMatches && info.EncounterMatch is EncounterSlot && pkm.Version != (int)GameVersion.CXD) // if false, all valid RNG frame matches have already been consumed
                {
                    info.Parse.Add(new CheckResult(Severity.Fishy, LEncConditionBadRNGFrame, CheckIdentifier.PID));    // todo for further confirmation
                }
                if (!info.PIDIVMatches)                                                                                // if false, all valid PIDIV matches have already been consumed
                {
                    info.Parse.Add(new CheckResult(Severity.Invalid, LPIDTypeMismatch, CheckIdentifier.PID));
                }

                return(info);
            }
        }
        /// <summary>
        /// Iterates through all possible encounters until a sufficient match is found
        /// </summary>
        /// <remarks>
        /// The iterator lazily finds matching encounters, then verifies secondary checks to weed out any nonexact matches.
        /// </remarks>
        /// <param name="pkm">Source data to find a match for</param>
        /// <returns>
        /// Information containing the matched encounter and any parsed checks.
        /// If no clean match is found, the last checked match is returned.
        /// If no match is found, an invalid encounter object is returned.
        /// </returns>
        public static LegalInfo FindVerifiedEncounter(PKM pkm)
        {
            LegalInfo info       = new LegalInfo(pkm);
            var       encounters = EncounterGenerator.GetEncounters(pkm, info);

            using (var encounter = new PeekEnumerator <IEncounterable>(encounters.GetEnumerator()))
            {
                if (!encounter.PeekIsNext())
                {
                    return(VerifyWithoutEncounter(pkm, info));
                }

                var EncounterValidator = EncounterVerifier.GetEncounterVerifierMethod(pkm);
                while (encounter.MoveNext())
                {
                    info.EncounterMatch = encounter.Current;
                    var e = EncounterValidator(pkm, info);
                    if (!e.Valid && encounter.PeekIsNext())
                    {
                        info.Reject(e);
                        continue;
                    }
                    info.Parse.Add(e);

                    if (VerifySecondaryChecks(pkm, info, encounter))
                    {
                        break; // passes
                    }
                }

                if (!info.PIDIVMatches) // if false, all valid PIDIV matches have already been consumed
                {
                    info.Parse.Add(new CheckResult(Severity.Invalid, V411, CheckIdentifier.PID));
                }

                return(info);
            }
        }
Example #13
0
        private static PeekEnumerator <IEncounterable> PickPreferredIterator(PKM pkm, PeekEnumerator <IEncounterable> g1i, PeekEnumerator <IEncounterable> g2i)
        {
            if (!g1i.PeekIsNext())
            {
                return(g2i);
            }
            if (!g2i.PeekIsNext())
            {
                return(g1i);
            }
            var p1 = GetGBEncounterPriority(pkm, g1i.Current);
            var p2 = GetGBEncounterPriority(pkm, g2i.Current);

            return(p1 > p2 ? g1i : g2i);
        }