コード例 #1
0
        private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, IReadOnlyList <int> currentMoves, LegalInfo info)
        {
            var res          = new CheckMoveResult[4];
            var G1Encounter  = info.EncounterMatch;
            var InitialMoves = Array.Empty <int>();
            var SpecialMoves = GetSpecialMoves(info.EncounterMatch);
            var games        = info.EncounterMatch.Generation == 1 ? GBRestrictions.GetGen1Versions(info) : GBRestrictions.GetGen2Versions(info, pkm.Korean);

            foreach (var ver in games)
            {
                var VerInitialMoves = MoveLevelUp.GetEncounterMoves(G1Encounter.Species, 0, G1Encounter.LevelMin, ver);
                if (VerInitialMoves.Intersect(InitialMoves).Count() == VerInitialMoves.Length)
                {
                    return(res);
                }

                var source = new MoveParseSource
                {
                    CurrentMoves  = currentMoves,
                    SpecialSource = SpecialMoves,
                    Base          = VerInitialMoves,
                };
                res = ParseMoves(pkm, source, info);
                if (res.All(r => r.Valid))
                {
                    return(res);
                }
                InitialMoves = VerInitialMoves;
            }
            return(res);
        }
コード例 #2
0
        private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, int[] Moves, LegalInfo info)
        {
            GameVersion[]     games = (info.EncounterMatch as IGeneration)?.Generation == 1 ? Legal.GetGen1Versions(info) : Legal.GetGen2Versions(info);
            CheckMoveResult[] res   = new CheckMoveResult[4];
            var G1Encounter         = info.EncounterMatch;

            if (G1Encounter == null)
            {
                return(ParseMovesSpecialMoveset(pkm, Moves, info));
            }
            var InitialMoves = new int[0];

            int[] SpecialMoves = GetSpecialMoves(info.EncounterMatch);
            var   emptyegg     = new int[0];

            foreach (GameVersion ver in games)
            {
                var VerInitialMoves = Legal.GetInitialMovesGBEncounter(G1Encounter.Species, G1Encounter.LevelMin, ver).ToArray();
                if (VerInitialMoves.SequenceEqual(InitialMoves))
                {
                    return(res);
                }
                res = ParseMoves(pkm, Moves, SpecialMoves, emptyegg, emptyegg, emptyegg, new int[0], VerInitialMoves, info);
                if (res.All(r => r.Valid))
                {
                    return(res);
                }
                InitialMoves = VerInitialMoves;
            }
            return(res);
        }
コード例 #3
0
ファイル: VerifyCurrentMoves.cs プロジェクト: ZeroX1ng/PKHeX
        private static CheckMoveResult[] ParseMoves(PKM pkm, MoveParseSource source, LegalInfo info)
        {
            var res = new CheckMoveResult[4];

            bool AllParsed() => res.All(z => z != null);

            // Special considerations!
            const int NoMinGeneration = 0;
            int       minGeneration   = NoMinGeneration;

            if (pkm is IBattleVersion {
                BattleVersion : not 0
            } v)
            {
                minGeneration = ((GameVersion)v.BattleVersion).GetGeneration();
                source.ResetSources();
            }

            // Check empty moves and relearn moves before generation specific moves
            for (int m = 0; m < 4; m++)
            {
                var move = source.CurrentMoves[m];
                if (move == 0)
                {
                    res[m] = new CheckMoveResult(None, pkm.Format, Valid, LMoveSourceEmpty, CurrentMove);
                }
                else if (minGeneration == NoMinGeneration && info.EncounterMoves.Relearn.Contains(move))
                {
                    res[m] = new CheckMoveResult(Relearn, info.Generation, Valid, LMoveSourceRelearn, CurrentMove);
                }
            }

            if (AllParsed())
            {
                return(res);
            }

            // Encapsulate arguments to simplify method calls
            var moveInfo = new LearnInfo(pkm, source);

            // Check moves going backwards, marking the move valid in the most current generation when it can be learned
            int[] generations = GenerationTraversal.GetVisitedGenerationOrder(pkm, info.EncounterOriginal.Generation);
            if (pkm.Format <= 2)
            {
                generations = Array.FindAll(generations, z => z < info.EncounterMoves.LevelUpMoves.Length);
            }
            if (minGeneration != NoMinGeneration)
            {
                generations = Array.FindAll(generations, z => z >= minGeneration);
            }

            if (generations.Length != 0)
            {
                int lastgen = generations[^ 1];
コード例 #4
0
        private static CheckMoveResult[] ParseMoves(PKM pkm, MoveParseSource source, LegalInfo info)
        {
            var res = new CheckMoveResult[4];

            bool AllParsed() => res.All(z => z != null);

            var required = pkm is not PK1 pk1 ? 1 : GBRestrictions.GetRequiredMoveCount(pk1, source.CurrentMoves, info, source.Base);

            // Special considerations!
            int reset = 0;

            if (pkm is IBattleVersion {
                BattleVersion : not 0
            } v)
            {
                reset = ((GameVersion)v.BattleVersion).GetGeneration();
                source.ResetSources();
            }

            // Check empty moves and relearn moves before generation specific moves
            for (int m = 0; m < 4; m++)
            {
                if (source.CurrentMoves[m] == 0)
                {
                    res[m] = new CheckMoveResult(None, pkm.Format, m < required ? Fishy : Valid, LMoveSourceEmpty, CurrentMove);
                }
                else if (reset == 0 && info.EncounterMoves.Relearn.Contains(source.CurrentMoves[m]))
                {
                    res[m] = new CheckMoveResult(Relearn, info.Generation, Valid, LMoveSourceRelearn, CurrentMove);
                }
            }

            if (AllParsed())
            {
                return(res);
            }

            // Encapsulate arguments to simplify method calls
            var moveInfo = new LearnInfo(pkm, source);

            // Check moves going backwards, marking the move valid in the most current generation when it can be learned
            int[] generations = GenerationTraversal.GetVisitedGenerationOrder(pkm, info.EncounterOriginal.Generation);
            if (pkm.Format <= 2)
            {
                generations = generations.Where(z => z < info.EncounterMoves.LevelUpMoves.Length).ToArray();
            }
            if (reset != 0)
            {
                generations = generations.Where(z => z >= reset).ToArray();
            }

            int lastgen = generations.Length == 0 ? 0 : generations[^ 1];
コード例 #5
0
        private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, IReadOnlyList <int> currentMoves, LegalInfo info)
        {
            var res          = new CheckMoveResult[4];
            var enc          = info.EncounterMatch;
            var level        = pkm.HasOriginalMetLocation ? pkm.Met_Level : enc.LevelMin;
            var InitialMoves = Array.Empty <int>();
            var SpecialMoves = GetSpecialMoves(enc);
            var games        = enc.Generation == 1 ? GBRestrictions.GetGen1Versions(enc) : GBRestrictions.GetGen2Versions(enc, pkm.Korean);

            foreach (var ver in games)
            {
                var VerInitialMoves = MoveLevelUp.GetEncounterMoves(enc.Species, 0, level, ver);
                if (VerInitialMoves.Intersect(InitialMoves).Count() == VerInitialMoves.Length)
                {
                    return(res);
                }

                var source = new MoveParseSource
                {
                    CurrentMoves  = currentMoves,
                    SpecialSource = SpecialMoves,
                    Base          = VerInitialMoves,
                };
                res = ParseMoves(pkm, source, info);

                // Must have a minimum count of moves, depending on the tradeback state.
                if (pkm is PK1 pk1)
                {
                    int count = GBRestrictions.GetRequiredMoveCount(pk1, source.CurrentMoves, info, source.Base);
                    if (count == 1)
                    {
                        return(res);
                    }

                    for (int m = 0; m < count; m++)
                    {
                        var move = source.CurrentMoves[m];
                        if (move == 0)
                        {
                            res[m] = new CheckMoveResult(None, pkm.Format, Invalid, LMoveSourceEmpty, CurrentMove);
                        }
                    }
                }
                if (res.All(r => r.Valid))
                {
                    return(res);
                }
                InitialMoves = VerInitialMoves;
            }
            return(res);
        }
コード例 #6
0
ファイル: VerifyCurrentMoves.cs プロジェクト: kang1806/PKHeX
        private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, int[] Moves, LegalInfo info)
        {
            CheckMoveResult[] res = new CheckMoveResult[4];
            var G1Encounter       = info.EncounterMatch;

            if (G1Encounter == null)
            {
                return(ParseMovesSpecialMoveset(pkm, Moves, info));
            }
            var InitialMoves = Array.Empty <int>();

            int[] SpecialMoves = GetSpecialMoves(info.EncounterMatch);
            var   games        = info.EncounterMatch is IGeneration g && g.Generation == 1 ? Legal.GetGen1Versions(info) : Legal.GetGen2Versions(info);

            foreach (var ver in games)
            {
                var VerInitialMoves = MoveLevelUp.GetEncounterMoves(G1Encounter.Species, 0, G1Encounter.LevelMin, ver);
                if (VerInitialMoves.Intersect(InitialMoves).Count() == VerInitialMoves.Length)
                {
                    return(res);
                }

                var source = new MoveParseSource
                {
                    CurrentMoves  = Moves,
                    SpecialSource = SpecialMoves,
                    Base          = VerInitialMoves,
                };
                res = ParseMoves(pkm, source, info);
                if (res.All(r => r.Valid))
                {
                    return(res);
                }
                InitialMoves = VerInitialMoves;
            }
            return(res);
        }
コード例 #7
0
        private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, int[] Moves, LegalInfo info)
        {
            CheckMoveResult[] res = new CheckMoveResult[4];
            var G1Encounter       = info.EncounterMatch;

            if (G1Encounter == null)
            {
                return(ParseMovesSpecialMoveset(pkm, Moves, info));
            }
            var InitialMoves = new int[0];

            int[] SpecialMoves = GetSpecialMoves(info.EncounterMatch);
            IEnumerable <GameVersion> games = (info.EncounterMatch as IGeneration)?.Generation == 1 ? Legal.GetGen1Versions(info) : Legal.GetGen2Versions(info);

            foreach (GameVersion ver in games)
            {
                var VerInitialMoves = Legal.GetInitialMovesGBEncounter(G1Encounter.Species, G1Encounter.LevelMin, ver).ToArray();
                if (VerInitialMoves.SequenceEqual(InitialMoves))
                {
                    return(res);
                }

                var source = new MoveParseSource
                {
                    CurrentMoves  = Moves,
                    SpecialSource = SpecialMoves,
                    Base          = VerInitialMoves,
                };
                res = ParseMoves(pkm, source, info);
                if (res.All(r => r.Valid))
                {
                    return(res);
                }
                InitialMoves = VerInitialMoves;
            }
            return(res);
        }
コード例 #8
0
ファイル: VerifyCurrentMoves.cs プロジェクト: kang1806/PKHeX
        private static CheckMoveResult[] ParseMoves(PKM pkm, MoveParseSource source, LegalInfo info)
        {
            CheckMoveResult[] res = new CheckMoveResult[4];
            bool AllParsed() => res.All(r => r != null);

            var required = Legal.GetRequiredMoveCount(pkm, source.CurrentMoves, info, source.Base);

            // Check empty moves and relearn moves before generation specific moves
            for (int m = 0; m < 4; m++)
            {
                if (source.CurrentMoves[m] == 0)
                {
                    res[m] = new CheckMoveResult(MoveSource.None, pkm.Format, m < required ? Severity.Fishy : Severity.Valid, V167, CheckIdentifier.Move);
                }
                else if (info.EncounterMoves.Relearn.Contains(source.CurrentMoves[m]))
                {
                    res[m] = new CheckMoveResult(MoveSource.Relearn, info.Generation, Severity.Valid, V172, CheckIdentifier.Move)
                    {
                        Flag = true
                    }
                }
                ;
            }

            if (AllParsed())
            {
                return(res);
            }

            // Encapsulate arguments to simplify method calls
            var moveInfo = new LearnInfo(pkm)
            {
                Source = source
            };

            // Check moves going backwards, marking the move valid in the most current generation when it can be learned
            int[] generations = GetGenMovesCheckOrder(pkm);
            if (pkm.Format <= 2)
            {
                generations = generations.Where(z => z < info.EncounterMoves.LevelUpMoves.Length).ToArray();
            }

            int lastgen = generations.LastOrDefault();

            foreach (var gen in generations)
            {
                ParseMovesByGeneration(pkm, res, gen, info, moveInfo, lastgen);
                if (AllParsed())
                {
                    return(res);
                }
            }

            if (pkm.Species == 292 && info.Generation <= 4)
            {
                ParseShedinjaEvolveMoves(pkm, res, source.CurrentMoves);
            }

            for (int m = 0; m < 4; m++)
            {
                if (res[m] == null)
                {
                    res[m] = new CheckMoveResult(MoveSource.Unknown, info.Generation, Severity.Invalid, V176, CheckIdentifier.Move);
                }
            }
            return(res);
        }
コード例 #9
0
ファイル: VerifyCurrentMoves.cs プロジェクト: rv2900/PKHeX
        private static CheckMoveResult[] ParseMoves(PKM pkm, MoveParseSource source, LegalInfo info)
        {
            var res = new CheckMoveResult[4];

            bool AllParsed() => res.All(z => z != null);

            var required = pkm.Format != 1 ? 1 : GBRestrictions.GetRequiredMoveCount(pkm, source.CurrentMoves, info, source.Base);

            // Special considerations!
            int reset = 0;

            if (pkm is IBattleVersion v && v.BattleVersion != 0)
            {
                reset = ((GameVersion)v.BattleVersion).GetGeneration();
                source.EggEventSource           = Array.Empty <int>();
                source.Base                     = Array.Empty <int>();
                source.EggLevelUpSource         = Array.Empty <int>();
                source.EggMoveSource            = Array.Empty <int>();
                source.NonTradeBackLevelUpMoves = Array.Empty <int>();
                source.SpecialSource            = Array.Empty <int>();
            }

            // Check empty moves and relearn moves before generation specific moves
            for (int m = 0; m < 4; m++)
            {
                if (source.CurrentMoves[m] == 0)
                {
                    res[m] = new CheckMoveResult(None, pkm.Format, m < required ? Fishy : Valid, LMoveSourceEmpty, Move);
                }
                else if (reset == 0 && info.EncounterMoves.Relearn.Contains(source.CurrentMoves[m]))
                {
                    res[m] = new CheckMoveResult(Relearn, info.Generation, Valid, LMoveSourceRelearn, Move)
                    {
                        Flag = true
                    }
                }
                ;
            }

            if (AllParsed())
            {
                return(res);
            }

            // Encapsulate arguments to simplify method calls
            var moveInfo = new LearnInfo(pkm, source);

            // Check moves going backwards, marking the move valid in the most current generation when it can be learned
            int[] generations = GetGenMovesCheckOrder(pkm);
            if (pkm.Format <= 2)
            {
                generations = generations.Where(z => z < info.EncounterMoves.LevelUpMoves.Length).ToArray();
            }
            if (reset != 0)
            {
                generations = generations.Where(z => z >= reset).ToArray();
            }

            int lastgen = generations.LastOrDefault();

            foreach (var gen in generations)
            {
                ParseMovesByGeneration(pkm, res, gen, info, moveInfo, lastgen);
                if (AllParsed())
                {
                    return(res);
                }
            }

            if (pkm.Species == (int)Species.Shedinja && info.Generation <= 4)
            {
                ParseShedinjaEvolveMoves(pkm, res, source.CurrentMoves, info.EvoChainsAllGens);
            }

            for (int m = 0; m < 4; m++)
            {
                if (res[m] == null)
                {
                    res[m] = new CheckMoveResult(Unknown, info.Generation, Invalid, LMoveSourceInvalid, Move);
                }
            }
            return(res);
        }
コード例 #10
0
        private static CheckMoveResult[] ParseMoves(PKM pkm, int[] moves, int[] special, int[] lvlupegg, int[] egg, int[] NonTradebackLvlMoves, int[] eventegg, int[] initialmoves, LegalInfo info)
        {
            CheckMoveResult[] res = new CheckMoveResult[4];
            var required          = Legal.GetRequiredMoveCount(pkm, moves, info, initialmoves);

            // Check none moves and relearn moves before generation moves
            for (int m = 0; m < 4; m++)
            {
                if (moves[m] == 0)
                {
                    res[m] = new CheckMoveResult(MoveSource.None, pkm.Format, m < required ? Severity.Fishy : Severity.Valid, V167, CheckIdentifier.Move);
                }
                else if (info.EncounterMoves.Relearn.Contains(moves[m]))
                {
                    res[m] = new CheckMoveResult(MoveSource.Relearn, pkm.GenNumber, Severity.Valid, V172, CheckIdentifier.Move)
                    {
                        Flag = true
                    }
                }
                ;
            }

            if (res.All(r => r != null))
            {
                return(res);
            }

            bool MixedGen1NonTradebackGen2 = false;
            var  Gen1MovesLearned          = new List <int>();
            var  Gen2PreevoMovesLearned    = new List <int>();
            var  EggMovesLearned           = new List <int>();
            var  LvlupEggMovesLearned      = new List <int>();
            var  EventEggMovesLearned      = new List <int>();
            var  IsGen2Pkm           = pkm.Format == 2 || pkm.VC2;
            var  IncenseMovesLearned = new List <int>();

            // Check moves going backwards, marking the move valid in the most current generation when it can be learned
            int[] generations = GetGenMovesCheckOrder(pkm);
            if (pkm.Format <= 2)
            {
                generations = generations.Where(z => z < info.EncounterMoves.LevelUpMoves.Length).ToArray();
            }
            foreach (var gen in generations)
            {
                var HMLearned = new int[0];
                // Check if pokemon knows HM moves from generation 3 and 4 but are not valid yet, that means it cant learn the HMs in future generations
                bool KnowDefogWhirlpool = false;
                if (gen == 4 && pkm.Format > 4)
                {
                    // Copy to array the hm found or else the list will be emptied when the legal status of moves changes in the current generation
                    HMLearned = moves.Where((m, i) => !(res[i]?.Valid ?? false) && Legal.HM_4_RemovePokeTransfer.Any(l => l == m)).Select((m, i) => i).ToArray();
                    // Defog and Whirlpool at the same time, also both can't be learned in future generations or else they will be valid
                    KnowDefogWhirlpool = moves.Where((m, i) => (m == 250 || m == 432) && !(res[i]?.Valid ?? false)).Count() == 2;
                }
                else if (gen == 3 && pkm.Format > 3)
                {
                    HMLearned = moves.Select((m, i) => i).Where(i => !(res[i]?.Valid ?? false) && Legal.HM_3.Any(l => l == moves[i])).ToArray();
                }

                bool native = gen == pkm.Format;
                for (int m = 0; m < 4; m++)
                {
                    if (res[m]?.Valid ?? false) // already validated with another generation
                    {
                        continue;
                    }
                    if (moves[m] == 0)
                    {
                        continue;
                    }

                    if (gen == 1 && initialmoves.Contains(moves[m]))
                    {
                        res[m] = new CheckMoveResult(MoveSource.Initial, gen, Severity.Valid, native ? V361 : string.Format(V362, gen), CheckIdentifier.Move);
                    }
                    else if (info.EncounterMoves.LevelUpMoves[gen].Contains(moves[m]))
                    {
                        res[m] = new CheckMoveResult(MoveSource.LevelUp, gen, Severity.Valid, native ? V177 : string.Format(V330, gen), CheckIdentifier.Move);
                    }
                    else if (info.EncounterMoves.TMHMMoves[gen].Contains(moves[m]))
                    {
                        res[m] = new CheckMoveResult(MoveSource.TMHM, gen, Severity.Valid, native ? V173 : string.Format(V331, gen), CheckIdentifier.Move);
                    }
                    else if (info.EncounterMoves.TutorMoves[gen].Contains(moves[m]))
                    {
                        res[m] = new CheckMoveResult(MoveSource.Tutor, gen, Severity.Valid, native ? V174 : string.Format(V332, gen), CheckIdentifier.Move);
                    }
                    else if (gen == pkm.GenNumber && special.Contains(moves[m]))
                    {
                        res[m] = new CheckMoveResult(MoveSource.Special, gen, Severity.Valid, V175, CheckIdentifier.Move);
                    }

                    if (res[m] == null || gen >= 3)
                    {
                        continue;
                    }

                    if (res[m].Valid && gen == 2 && NonTradebackLvlMoves.Contains(m))
                    {
                        Gen2PreevoMovesLearned.Add(m);
                    }
                    if (res[m].Valid && gen == 1)
                    {
                        Gen1MovesLearned.Add(m);
                        if (Gen2PreevoMovesLearned.Any())
                        {
                            MixedGen1NonTradebackGen2 = true;
                        }
                    }

                    if (res[m].Valid && gen <= 2 && pkm.TradebackStatus == TradebackType.Any && pkm.GenNumber != gen)
                    {
                        pkm.TradebackStatus = TradebackType.WasTradeback;
                    }
                }

                if (gen == generations.Last())
                {
                    // Check higher-level moves after all the moves but just before egg moves to differentiate it from normal level up moves
                    // Also check if the base egg moves is a non tradeback move
                    for (int m = 0; m < 4; m++)
                    {
                        if (res[m]?.Valid ?? false) // Skip valid move
                        {
                            continue;
                        }
                        if (moves[m] == 0)
                        {
                            continue;
                        }
                        if (!lvlupegg.Contains(moves[m])) // Check if contains level-up egg moves from parents
                        {
                            continue;
                        }

                        if (IsGen2Pkm && Gen1MovesLearned.Any() && moves[m] > Legal.MaxMoveID_1)
                        {
                            res[m] = new CheckMoveResult(MoveSource.InheritLevelUp, gen, Severity.Invalid, V334, CheckIdentifier.Move);
                            MixedGen1NonTradebackGen2 = true;
                        }
                        else
                        {
                            res[m] = new CheckMoveResult(MoveSource.InheritLevelUp, gen, Severity.Valid, V345, CheckIdentifier.Move);
                        }
                        LvlupEggMovesLearned.Add(m);
                        if (pkm.TradebackStatus == TradebackType.Any && pkm.GenNumber == 1)
                        {
                            pkm.TradebackStatus = TradebackType.WasTradeback;
                        }
                    }

                    // Check egg moves after all the generations and all the moves, every move that can't be learned in another source should have preference
                    // the moves that can only be learned from egg moves should in the future check if the move combinations can be breed in gens 2 to 5
                    for (int m = 0; m < 4; m++)
                    {
                        if (res[m]?.Valid ?? false)
                        {
                            continue;
                        }
                        if (moves[m] == 0)
                        {
                            continue;
                        }

                        if (egg.Contains(moves[m]))
                        {
                            if (IsGen2Pkm && Gen1MovesLearned.Any() && moves[m] > Legal.MaxMoveID_1)
                            {
                                // To learn exclusive generation 1 moves the pokemon was tradeback, but it can't be trade to generation 1
                                // without removing moves above MaxMoveID_1, egg moves above MaxMoveID_1 and gen 1 moves are incompatible
                                res[m] = new CheckMoveResult(MoveSource.EggMove, gen, Severity.Invalid, V334, CheckIdentifier.Move)
                                {
                                    Flag = true
                                };
                                MixedGen1NonTradebackGen2 = true;
                            }
                            else
                            {
                                res[m] = new CheckMoveResult(MoveSource.EggMove, gen, Severity.Valid, V171, CheckIdentifier.Move)
                                {
                                    Flag = true
                                }
                            };

                            EggMovesLearned.Add(m);
                            if (pkm.TradebackStatus == TradebackType.Any && pkm.GenNumber == 1)
                            {
                                pkm.TradebackStatus = TradebackType.WasTradeback;
                            }
                        }
                        if (!eventegg.Contains(moves[m]))
                        {
                            continue;
                        }

                        if (!egg.Contains(moves[m]))
                        {
                            if (IsGen2Pkm && Gen1MovesLearned.Any() && moves[m] > Legal.MaxMoveID_1)
                            {
                                res[m] = new CheckMoveResult(MoveSource.SpecialEgg, gen, Severity.Invalid, V334, CheckIdentifier.Move)
                                {
                                    Flag = true
                                };
                                MixedGen1NonTradebackGen2 = true;
                            }
                            else
                            {
                                res[m] = new CheckMoveResult(MoveSource.SpecialEgg, gen, Severity.Valid, V333, CheckIdentifier.Move)
                                {
                                    Flag = true
                                }
                            };
                        }
                        if (pkm.TradebackStatus == TradebackType.Any && pkm.GenNumber == 1)
                        {
                            pkm.TradebackStatus = TradebackType.WasTradeback;
                        }
                        EventEggMovesLearned.Add(m);
                    }

                    // A pokemon could have normal egg moves and regular egg moves
                    // Only if all regular egg moves are event egg moves or all event egg moves are regular egg moves
                    var RegularEggMovesLearned = EggMovesLearned.Union(LvlupEggMovesLearned).ToList();
                    if (RegularEggMovesLearned.Any() && EventEggMovesLearned.Any())
                    {
                        // Moves that are egg moves or event egg moves but not both
                        var IncompatibleEggMoves = RegularEggMovesLearned.Except(EventEggMovesLearned).Union(EventEggMovesLearned.Except(RegularEggMovesLearned)).ToList();
                        if (IncompatibleEggMoves.Any())
                        {
                            foreach (int m in IncompatibleEggMoves)
                            {
                                if (EventEggMovesLearned.Contains(m) && !EggMovesLearned.Contains(m))
                                {
                                    res[m] = new CheckMoveResult(res[m], Severity.Invalid, V337, CheckIdentifier.Move);
                                }
                                else if (!EventEggMovesLearned.Contains(m) && EggMovesLearned.Contains(m))
                                {
                                    res[m] = new CheckMoveResult(res[m], Severity.Invalid, V336, CheckIdentifier.Move);
                                }
                                else if (!EventEggMovesLearned.Contains(m) && LvlupEggMovesLearned.Contains(m))
                                {
                                    res[m] = new CheckMoveResult(res[m], Severity.Invalid, V358, CheckIdentifier.Move);
                                }
                            }
                        }
                    }
                    // If there is no incompatibility with event egg check that there is no inherited move in gift eggs and event eggs
                    else if (RegularEggMovesLearned.Any() && (pkm.WasGiftEgg || pkm.WasEventEgg))
                    {
                        foreach (int m in RegularEggMovesLearned)
                        {
                            if (EggMovesLearned.Contains(m))
                            {
                                res[m] = new CheckMoveResult(res[m], Severity.Invalid, pkm.WasGiftEgg ? V377 : V341, CheckIdentifier.Move);
                            }
                            else if (LvlupEggMovesLearned.Contains(m))
                            {
                                res[m] = new CheckMoveResult(res[m], Severity.Invalid, pkm.WasGiftEgg ? V378 : V347, CheckIdentifier.Move);
                            }
                        }
                    }
                }

                if (3 <= gen && gen <= 4 && pkm.Format > gen)
                {
                    // After all the moves from the generations 3 and 4,
                    // including egg moves if is the origin generation because some hidden moves are also special egg moves in gen 3
                    // Check if the marked hidden moves that were invalid at the start are now marked as valid, that means
                    // the hidden move was learned in gen 3 or 4 but was not removed when transfer to 4 or 5
                    if (KnowDefogWhirlpool)
                    {
                        int invalidCount = moves.Where((m, i) => (m == 250 || m == 432) && (res[i]?.Valid ?? false)).Count();
                        if (invalidCount == 2)          // can't know both at the same time
                        {
                            for (int i = 0; i < 4; i++) // flag both moves
                            {
                                if (moves[i] == 250 || moves[i] == 432)
                                {
                                    res[i] = new CheckMoveResult(res[i], Severity.Invalid, V338, CheckIdentifier.Move);
                                }
                            }
                        }
                    }

                    for (int i = 0; i < HMLearned.Length; i++)
                    {
                        if (res[i]?.Valid ?? false)
                        {
                            res[i] = new CheckMoveResult(res[i], Severity.Invalid, string.Format(V339, gen, gen + 1), CheckIdentifier.Move);
                        }
                    }
                }

                // Mark the gen 1 exclusive moves as illegal because the pokemon also have Non tradeback egg moves.
                if (MixedGen1NonTradebackGen2)
                {
                    foreach (int m in Gen1MovesLearned)
                    {
                        res[m] = new CheckMoveResult(res[m], Severity.Invalid, V335, CheckIdentifier.Move);
                    }

                    foreach (int m in Gen2PreevoMovesLearned)
                    {
                        res[m] = new CheckMoveResult(res[m], Severity.Invalid, V412, CheckIdentifier.Move);
                    }
                }

                if (gen == 1 && pkm.Format == 1 && pkm.Gen1_NotTradeback)
                {
                    // Check moves learned at the same level in red/blue and yellow, illegal because there is no move reminder
                    // Only two incompatibilites and only there are no illegal combination if generation 2 or 7 are included in the analysis
                    ParseRedYellowIncompatibleMoves(pkm, res, moves);

                    ParseEvolutionsIncompatibleMoves(pkm, res, moves, info.EncounterMoves.TMHMMoves[1]);
                }

                if (Legal.SpeciesEvolutionWithMove.Contains(pkm.Species))
                {
                    // Pokemon that evolved by leveling up while learning a specific move
                    // This pokemon could only have 3 moves from preevolutions that are not the move used to evolved
                    // including special and eggs moves before realearn generations
                    ParseEvolutionLevelupMove(pkm, res, moves, IncenseMovesLearned, info);
                }

                if (res.All(r => r != null))
                {
                    return(res);
                }
            }

            if (pkm.Species == 292 && info.EncounterMatch.Species != 292)
            {
                // Ignore Shedinja if the Encounter was also a Shedinja, assume null Encounter as a Nincada egg
                // Check Shedinja evolved moves from Ninjask after egg moves
                // Those moves could also be inherited egg moves
                ParseShedinjaEvolveMoves(pkm, res, moves);
            }

            for (int m = 0; m < 4; m++)
            {
                if (res[m] == null)
                {
                    res[m] = new CheckMoveResult(MoveSource.Unknown, pkm.GenNumber, Severity.Invalid, V176, CheckIdentifier.Move);
                }
            }
            return(res);
        }
コード例 #11
0
ファイル: VerifyCurrentMoves.cs プロジェクト: ZeroX1ng/PKHeX
        private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, IReadOnlyList <int> currentMoves, LegalInfo info)
        {
            var res          = new CheckMoveResult[4];
            var enc          = info.EncounterMatch;
            var level        = pkm.HasOriginalMetLocation ? pkm.Met_Level : enc.LevelMin;
            var InitialMoves = Array.Empty <int>();
            var SpecialMoves = GetSpecialMoves(enc);
            var games        = enc.Generation == 1 ? GBRestrictions.GetGen1Versions(enc) : GBRestrictions.GetGen2Versions(enc, pkm.Korean);

            foreach (var ver in games)
            {
                var VerInitialMoves = enc is IMoveset {
                    Moves.Count : not 0
                } x ? (int[])x.Moves : MoveLevelUp.GetEncounterMoves(enc.Species, 0, level, ver);
                if (VerInitialMoves.Intersect(InitialMoves).Count() == VerInitialMoves.Length)
                {
                    return(res);
                }

                var source = new MoveParseSource
                {
                    CurrentMoves  = currentMoves,
                    SpecialSource = SpecialMoves,
                    Base          = VerInitialMoves,
                };
                res = ParseMoves(pkm, source, info);

                // Must have a minimum count of moves, depending on the tradeback state.
                if (pkm is PK1 pk1)
                {
                    int count = GBRestrictions.GetRequiredMoveCount(pk1, source.CurrentMoves, info, source.Base);
                    if (count == 1)
                    {
                        return(res);
                    }

                    // Reverse for loop and break instead of 0..count continue -- early-breaks for the vast majority of cases.
                    // We already flag for empty interstitial moveslots.
                    for (int m = count - 1; m >= 0; m--)
                    {
                        var move = source.CurrentMoves[m];
                        if (move != 0)
                        {
                            break;
                        }

                        // There are ways to skip level up moves by leveling up more than once.
                        // https://bulbapedia.bulbagarden.net/wiki/List_of_glitches_(Generation_I)#Level-up_learnset_skipping
                        // Evolution canceling also leads to incorrect assumptions in the above used method, so just indicate them as fishy in that case.
                        // Not leveled up? Not possible to be missing the move slot.
                        var severity = enc.LevelMin == pkm.CurrentLevel ? Invalid : Fishy;
                        res[m] = new CheckMoveResult(None, pkm.Format, severity, LMoveSourceEmpty, CurrentMove);
                    }
                }
                if (res.All(r => r.Valid))
                {
                    return(res);
                }
                InitialMoves = VerInitialMoves;
            }
            return(res);
        }