示例#1
0
        private static CheckMoveResult[] ParseMovesRelearn(PKM pkm, IReadOnlyList <int> currentMoves, LegalInfo info)
        {
            var source = new MoveParseSource
            {
                CurrentMoves  = currentMoves,
                SpecialSource = GetSpecialMoves(info.EncounterMatch),
            };

            if (info.EncounterMatch is EncounterEgg e)
            {
                source.EggMoveSource = MoveEgg.GetEggMoves(pkm, e.Species, e.Form, e.Version);
            }

            var res     = ParseMoves(pkm, source, info);
            var relearn = pkm.RelearnMoves;

            for (int i = 0; i < 4; i++)
            {
                if ((pkm.IsEgg || res[i].Flag) && !relearn.Contains(currentMoves[i]))
                {
                    res[i] = new CheckMoveResult(res[i], Invalid, string.Format(LMoveRelearnFMiss_0, res[i].Comment), res[i].Identifier);
                }
            }

            return(res);
        }
示例#2
0
        private static CheckMoveResult[] ParseMovesRelearn(PKM pkm, int[] Moves, LegalInfo info)
        {
            var source = new MoveParseSource
            {
                CurrentMoves  = Moves,
                SpecialSource = GetSpecialMoves(info.EncounterMatch),
            };

            if (info.EncounterMatch is EncounterEgg e)
            {
                source.EggMoveSource = Legal.GetEggMoves(pkm, e.Species, pkm.AltForm);
                bool TradebackPreevo = pkm.Format == 2 && info.EncounterMatch.Species > 151 && pkm.InhabitedGeneration(1);
                if (TradebackPreevo)
                {
                    source.NonTradeBackLevelUpMoves = Legal.GetExclusivePreEvolutionMoves(pkm, info.EncounterMatch.Species, info.EvoChainsAllGens[2], 2, e.Game)
                                                      .Where(m => m > Legal.MaxMoveID_1).ToArray();
                }
            }
            CheckMoveResult[] res = ParseMoves(pkm, source, info);

            int[] RelearnMoves = pkm.RelearnMoves;
            for (int i = 0; i < 4; i++)
            {
                if ((pkm.IsEgg || res[i].Flag) && !RelearnMoves.Contains(Moves[i]))
                {
                    res[i] = new CheckMoveResult(res[i], Severity.Invalid, string.Format(V170, res[i].Comment), res[i].Identifier);
                }
            }

            return(res);
        }
示例#3
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);
        }
示例#4
0
        private static CheckMoveResult[] ParseMovesWasEggPreRelearn(PKM pkm, IReadOnlyList <int> currentMoves, LegalInfo info, EncounterEgg e)
        {
            // Level up moves could not be inherited if Ditto is parent,
            // that means genderless species and male only species (except Nidoran-M and Volbeat; they breed with Nidoran-F and Illumise) could not have level up moves as an egg
            var pi           = pkm.PersonalInfo;
            var AllowLevelUp = !pi.Genderless && !(pi.OnlyMale && Breeding.MixedGenderBreeding.Contains(e.Species));
            int BaseLevel    = AllowLevelUp ? 100 : e.LevelMin;
            var LevelUp      = MoveList.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, BaseLevel);

            var TradebackPreevo      = pkm.Format == 2 && e.Species > 151;
            var NonTradebackLvlMoves = TradebackPreevo
                ? MoveList.GetExclusivePreEvolutionMoves(pkm, e.Species, info.EvoChainsAllGens[2], 2, e.Version).Where(m => m > Legal.MaxMoveID_1).ToArray()
                : Array.Empty <int>();

            var Egg = MoveEgg.GetEggMoves(pkm.PersonalInfo, e.Species, e.Form, e.Version, e.Generation);

            if (info.Generation < 3 && pkm.Format >= 7 && pkm.VC1)
            {
                Egg = Array.FindAll(Egg, m => m <= Legal.MaxMoveID_1);
            }

            var specialMoves = e.CanHaveVoltTackle ? new[] { (int)Move.VoltTackle } : Array.Empty <int>(); // Volt Tackle for bred Pichu line

            var source = new MoveParseSource
            {
                CurrentMoves             = currentMoves,
                SpecialSource            = specialMoves,
                NonTradeBackLevelUpMoves = NonTradebackLvlMoves,

                EggLevelUpSource = LevelUp,
                EggMoveSource    = Egg,
            };

            return(ParseMoves(pkm, source, info));
        }
示例#5
0
        private static CheckMoveResult[] ParseMovesWasEggPreRelearn(PKM pkm, int[] Moves, LegalInfo info, EncounterEgg e)
        {
            var EventEggMoves = GetSpecialMoves(info.EncounterMatch);
            // Level up moves could not be inherited if Ditto is parent,
            // that means genderless species and male only species except Nidoran and Volbeat (they breed with female nidoran and illumise) could not have level up moves as an egg
            var AllowLevelUp         = pkm.PersonalInfo.Gender > 0 && pkm.PersonalInfo.Gender < 255 || Legal.MixedGenderBreeding.Contains(e.Species);
            int BaseLevel            = AllowLevelUp ? 100 : e.LevelMin;
            var LevelUp              = Legal.GetBaseEggMoves(pkm, e.Species, e.Game, BaseLevel);
            var TradebackPreevo      = pkm.Format == 2 && info.EncounterMatch.Species > 151;
            var NonTradebackLvlMoves = new int[0];

            if (TradebackPreevo)
            {
                NonTradebackLvlMoves = Legal.GetExclusivePreEvolutionMoves(pkm, info.EncounterMatch.Species, info.EvoChainsAllGens[2], 2, e.Game).Where(m => m > Legal.MaxMoveID_1).ToArray();
            }
            var Egg = Legal.GetEggMoves(pkm, e.Species, pkm.AltForm);

            bool volt    = (info.Generation > 3 || e.Game == GameVersion.E) && Legal.LightBall.Contains(pkm.Species);
            var  Special = volt && EventEggMoves.Length == 0 ? new[] { 344 } : new int[0]; // Volt Tackle for bred Pichu line

            var source = new MoveParseSource
            {
                CurrentMoves             = Moves,
                SpecialSource            = Special,
                NonTradeBackLevelUpMoves = NonTradebackLvlMoves,

                EggLevelUpSource = LevelUp,
                EggMoveSource    = Egg,
                EggEventSource   = EventEggMoves,
            };

            return(ParseMoves(pkm, source, info));
        }
示例#6
0
        private static CheckMoveResult[] ParseMovesRelearn(PKM pkm, int[] Moves, LegalInfo info)
        {
            var source = new MoveParseSource
            {
                CurrentMoves  = Moves,
                SpecialSource = GetSpecialMoves(info.EncounterMatch),
            };

            if (info.EncounterMatch is EncounterEgg e)
            {
                source.EggMoveSource = MoveEgg.GetEggMoves(pkm, e.Species, pkm.AltForm, e.Version);
            }

            CheckMoveResult[] res = ParseMoves(pkm, source, info);

            int[] RelearnMoves = pkm.RelearnMoves;
            for (int i = 0; i < 4; i++)
            {
                if ((pkm.IsEgg || res[i].Flag) && !RelearnMoves.Contains(Moves[i]))
                {
                    res[i] = new CheckMoveResult(res[i], Severity.Invalid, string.Format(V170, res[i].Comment), res[i].Identifier);
                }
            }

            return(res);
        }
示例#7
0
        private static CheckMoveResult[] ParseMovesSpecialMoveset(PKM pkm, int[] Moves, LegalInfo info)
        {
            var source = new MoveParseSource
            {
                CurrentMoves  = Moves,
                SpecialSource = GetSpecialMoves(info.EncounterMatch),
            };

            return(ParseMoves(pkm, source, info));
        }
示例#8
0
        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];
示例#9
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];
示例#10
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);
        }
示例#11
0
        private static CheckMoveResult[] ParseMovesForSmeargle(PKM pkm, int[] Moves, LegalInfo info)
        {
            if (!pkm.IsEgg)
            {
                return(ParseMovesSketch(pkm, Moves));
            }

            // can only know sketch as egg
            var levelup = Legal.GetValidMovesAllGens(pkm, info.EvoChainsAllGens, minLvLG1: 1, Tutor: false, Machine: false, RemoveTransferHM: false);

            info.EncounterMoves = new ValidEncounterMoves(levelup);
            var source = new MoveParseSource {
                CurrentMoves = pkm.Moves,
            };

            return(ParseMoves(pkm, source, info));
        }
示例#12
0
        private static CheckMoveResult[] ParseMovesForSmeargle(PKM pkm, IReadOnlyList <int> currentMoves, LegalInfo info)
        {
            if (!pkm.IsEgg)
            {
                return(ParseMovesSketch(pkm, currentMoves));
            }

            // can only know sketch as egg
            var levelup = new int[info.EvoChainsAllGens.Length][];

            levelup[pkm.Format] = new[] { 166 };
            info.EncounterMoves = new ValidEncounterMoves(levelup);
            var source = new MoveParseSource {
                CurrentMoves = currentMoves,
            };

            return(ParseMoves(pkm, source, info));
        }
示例#13
0
        private static void ParseMovesForSmeargle(PKM pkm, CheckMoveResult[] parse, int[] currentMoves, LegalInfo info)
        {
            if (!pkm.IsEgg)
            {
                ParseMovesSketch(pkm, parse, currentMoves);
                return;
            }

            // can only know sketch as egg
            var levelup = new int[info.EvoChainsAllGens.Length][];

            levelup[pkm.Format] = new[] { (int)Move.Sketch };
            info.EncounterMoves = new ValidEncounterMoves(levelup);
            var source = new MoveParseSource {
                CurrentMoves = currentMoves
            };

            ParseMoves(pkm, source, info, parse);
        }
示例#14
0
        private static CheckMoveResult[] ParseMovesWasEggPreRelearn(PKM pkm, int[] Moves, LegalInfo info, EncounterEgg e)
        {
            var  EventEggMoves = GetSpecialMoves(info.EncounterMatch);
            bool notEvent      = EventEggMoves.Length == 0;
            // Level up moves could not be inherited if Ditto is parent,
            // that means genderless species and male only species (except Nidoran-M and Volbeat; they breed with Nidoran-F and Illumise) could not have level up moves as an egg
            var pi           = pkm.PersonalInfo;
            var AllowLevelUp = notEvent && !pi.Genderless && !(pi.OnlyMale && Legal.MixedGenderBreeding.Contains(e.Species));
            int BaseLevel    = AllowLevelUp ? 100 : e.LevelMin;
            var LevelUp      = Legal.GetBaseEggMoves(pkm, e.Species, e.Version, BaseLevel);

            var TradebackPreevo      = pkm.Format == 2 && info.EncounterMatch.Species > 151;
            var NonTradebackLvlMoves = TradebackPreevo
                ? Legal.GetExclusivePreEvolutionMoves(pkm, info.EncounterMatch.Species, info.EvoChainsAllGens[2], 2, e.Version).Where(m => m > Legal.MaxMoveID_1).ToArray()
                : Array.Empty <int>();

            var Egg = MoveEgg.GetEggMoves(pkm, e.Species, pkm.AltForm, e.Version);

            if (info.Generation < 3 && pkm.Format >= 7 && pkm.VC1)
            {
                Egg = Egg.Where(m => m <= Legal.MaxMoveID_1).ToArray();
            }

            bool volt    = (info.Generation > 3 || e.Version == GameVersion.E) && Legal.LightBall.Contains(pkm.Species);
            var  Special = volt && notEvent ? new[] { 344 } : Array.Empty <int>(); // Volt Tackle for bred Pichu line

            var source = new MoveParseSource
            {
                CurrentMoves             = Moves,
                SpecialSource            = Special,
                NonTradeBackLevelUpMoves = NonTradebackLvlMoves,

                EggLevelUpSource = LevelUp,
                EggMoveSource    = Egg,
                EggEventSource   = EventEggMoves,
            };

            return(ParseMoves(pkm, source, info));
        }
示例#15
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);
        }
示例#16
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 = 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);
        }
示例#17
0
        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);
        }
示例#18
0
 public LearnInfo(PKM pkm, MoveParseSource source)
 {
     IsGen2Pkm = pkm.Format == 2 || pkm.VC2;
     Source    = source;
 }
示例#19
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 = 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);
        }
示例#20
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.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);
        }