Пример #1
0
        internal static IEnumerable <int> GetValidRelearn(PKM pkm, int species, int form, bool inheritlvlmoves, GameVersion version = Any)
        {
            int generation = pkm.Generation;

            if (generation < 6)
            {
                return(Array.Empty <int>());
            }

            var r = new List <int>();

            r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, form, 1, version));

            if (pkm.Format == 6 && pkm.Species != (int)Species.Meowstic)
            {
                form = 0;
            }

            r.AddRange(MoveEgg.GetEggMoves(pkm.PersonalInfo, species, form, version, Math.Max(2, generation)));
            if (inheritlvlmoves)
            {
                r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, form, 100, version));
            }
            return(r.Distinct());
        }
Пример #2
0
        internal static IEnumerable <int> GetValidRelearn(PKM pkm, int species, bool inheritlvlmoves, GameVersion version = GameVersion.Any)
        {
            List <int> r = new List <int> {
                0
            };

            if (pkm.GenNumber < 6 || pkm.VC)
            {
                return(r);
            }

            r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 1, pkm.AltForm, version));

            int form = pkm.AltForm;

            if (pkm.Format == 6 && pkm.Species != 678)
            {
                form = 0;
            }

            r.AddRange(MoveEgg.GetEggMoves(pkm, species, form, version));
            if (inheritlvlmoves)
            {
                r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 100, pkm.AltForm, version));
            }
            return(r.Distinct());
        }
Пример #3
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));
        }
Пример #4
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);
        }
Пример #5
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);
        }
Пример #6
0
        private static IEnumerable <int> GetMovesForGeneration(PKM pk, IReadOnlyList <EvoCriteria> dl, int generation)
        {
            IEnumerable <int> moves = MoveList.GetValidMoves(pk, dl, generation);

            if (pk.Format >= 8)
            {
                // Shared Egg Moves via daycare
                // Any egg move can be obtained
                var evo    = dl[dl.Count - 1];
                var shared = MoveEgg.GetEggMoves(8, evo.Species, evo.Form, GameVersion.SW);
                if (shared.Length != 0)
                {
                    moves = moves.Concat(shared);
                }
            }
            if (pk.Species == (int)Species.Shedinja)
            {
                // Leveling up Nincada in Gen3/4 levels up, evolves to Ninjask, applies moves for Ninjask, then spawns Shedinja with the current moveset.
                // Future games spawn the Shedinja before doing Ninjask moves, so this is a special case.
                // Can't get more than the evolved-at level move; >=2 special moves will get caught by the legality checker later.
                if (generation == 3)
                {
                    return(moves.Concat(Legal.LevelUpE[(int)Species.Ninjask].GetMoves(100, 20)));
                }
                if (generation == 4)
                {
                    return(moves.Concat(Legal.LevelUpPt[(int)Species.Ninjask].GetMoves(100, 20)));
                }
            }
            return(moves);
        }
Пример #7
0
        /// <summary>
        /// Gets possible encounters that allow all moves requested to be learned.
        /// </summary>
        /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param>
        /// <param name="needs">Moves which cannot be taught by the player.</param>
        /// <param name="version">Specific version to iterate for. Necessary for retrieving possible Egg Moves.</param>
        /// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns>
        private static IEnumerable <EncounterEgg> GetEggs(PKM pk, IReadOnlyCollection <int> needs, GameVersion version)
        {
            if (GameVersion.CXD.Contains(version) || GameVersion.GG.Contains(version))
            {
                yield break; // no eggs from these games
            }
            var eggs = EncounterEggGenerator.GenerateEggs(pk, all: true);

            foreach (var egg in eggs)
            {
                if (needs.Count == 0)
                {
                    yield return(egg);

                    continue;
                }

                IEnumerable <int> em = MoveEgg.GetEggMoves(pk, egg.Species, pk.AltForm, version);
                if (Legal.LightBall.Contains(egg.Species) && needs.Contains(344))
                {
                    em = em.Concat(new[] { 344 }); // Volt Tackle
                }
                if (!needs.Except(em).Any())
                {
                    yield return(egg);
                }
            }
        }
Пример #8
0
        public EggInfoSource(PKM pkm, EncounterEgg e)
        {
            // Eggs with special moves cannot inherit levelup moves as the current moves are predefined.
            AllowInherited = e.Species != 489 && e.Species != 490;

            // Level up moves can only be inherited if ditto is not the mother.
            bool AllowLevelUp = Legal.GetCanInheritMoves(e.Species);

            Base = Legal.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, e.Level);

            Egg     = MoveEgg.GetEggMoves(pkm, e.Species, e.Form, e.Version);
            LevelUp = AllowLevelUp
                ? Legal.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, 100).Except(Base).ToList()
                : (IReadOnlyList <int>)Array.Empty <int>();
            Tutor = e.Version == GameVersion.C
                ? MoveTutor.GetTutorMoves(pkm, e.Species, 0, false, 2).ToList()
                : (IReadOnlyList <int>)Array.Empty <int>();

            // Only TM/HM moves from the source game of the egg, not any other games from the same generation
            TMHM = MoveTechnicalMachine.GetTMHM(pkm, pkm.Species, pkm.AltForm, e.Generation, e.Version).ToList();

            // Non-Base moves that can magically appear in the regular movepool
            bool volt = (e.Generation > 3 || e.Version == GameVersion.E) && Legal.LightBall.Contains(pkm.Species);

            if (volt)
            {
                Egg = Egg.ToList(); // array->list
                Egg.Add(344);       // Volt Tackle
            }
        }
        private static IEnumerable <int> GetMovesForGeneration(PKM pk, IReadOnlyList <EvoCriteria> chain, int generation)
        {
            IEnumerable <int> moves = MoveList.GetValidMoves(pk, chain, generation);

            if (generation <= 2)
            {
                moves = moves.Concat(MoveList.GetValidMoves(pk, chain, generation, MoveSourceType.LevelUp));
            }
            if (pk.Format >= 8)
            {
                // Shared Egg Moves via daycare
                // Any egg move can be obtained
                moves = moves.Concat(MoveEgg.GetSharedEggMoves(pk, generation));

                // TR moves -- default logic checks the TR flags, so we need to add all possible ones here.
                if (!(pk.BDSP || pk.LA))
                {
                    moves = moves.Concat(MoveTechnicalMachine.GetAllPossibleRecords(pk.Species, pk.Form));
                }
            }
            if (pk.Species == (int)Species.Shedinja)
            {
                // Leveling up Nincada in Gen3/4 levels up, evolves to Ninjask, applies moves for Ninjask, then spawns Shedinja with the current moveset.
                // Future games spawn the Shedinja before doing Ninjask moves, so this is a special case.
                // Can't get more than the evolved-at level move; >=2 special moves will get caught by the legality checker later.
                return(generation switch
                {
                    3 => moves.Concat(Legal.LevelUpE [(int)Species.Ninjask].GetMoves(100, 20)),
                    4 => moves.Concat(Legal.LevelUpPt[(int)Species.Ninjask].GetMoves(100, 20)),
                    _ => moves,
                });
Пример #10
0
        private static IEnumerable <int> GetMovesForGeneration(PKM pk, IReadOnlyList <EvoCriteria> dl, int generation)
        {
            IEnumerable <int> moves = Legal.GetValidMoves(pk, dl, generation);

            if (generation >= 8)
            {
                var evo    = dl[dl.Count - 1];
                var shared = MoveEgg.GetEggMoves(pk, evo.Species, evo.Form, GameVersion.SW);
                moves = moves.Concat(shared);
            }
            return(moves);
        }
Пример #11
0
        private static bool GetIsSharedEggMove(PKM pkm, int gen, int move)
        {
            if (gen < 8 || pkm.IsEgg)
            {
                return(false);
            }
            var table       = PersonalTable.SWSH;
            var entry       = (PersonalInfoSWSH)table.GetFormeEntry(pkm.Species, pkm.AltForm);
            var baseSpecies = entry.BaseSpecies;
            var baseForm    = entry.BaseSpeciesForm;
            var egg         = MoveEgg.GetEggMoves(pkm, baseSpecies, baseForm, GameVersion.SW);

            return(egg.Contains(move));
        }
Пример #12
0
        private int[] GetCurrentEggMoves(PKM pk)
        {
            var moves = MoveEgg.GetEggMoves(pk, Species, pk.AltForm, Version);

            if (moves.Length == 0)
            {
                moves = MoveLevelUp.GetEncounterMoves(pk, Level, Version);
            }
            else if (moves.Length < 4 && pk.Format >= 6)
            {
                // Sprinkle in some default level up moves
                var lvl = Legal.GetBaseEggMoves(pk, Species, Version, Level);
                moves = lvl.Concat(moves).ToArray();
            }
            return(moves);
        }
Пример #13
0
        public static EggSource6[] Validate(int generation, int species, int form, GameVersion version, ReadOnlySpan <int> moves, out bool valid)
        {
            var count = moves.IndexOf(0);

            if (count == 0)
            {
                valid = false; // empty moveset
                return(Array.Empty <EggSource6>());
            }
            if (count == -1)
            {
                count = moves.Length;
            }

            var learn    = GameData.GetLearnsets(version);
            var table    = GameData.GetPersonal(version);
            var index    = table.GetFormIndex(species, form);
            var learnset = learn[index];
            var egg      = MoveEgg.GetEggMoves(generation, species, form, version);

            var         actual   = new EggSource6[count];
            Span <byte> possible = stackalloc byte[count];
            var         value    = new BreedInfo <EggSource6>(actual, possible, learnset, moves, level);

            if (species is (int)Species.Pichu && moves[count - 1] is (int)Move.VoltTackle)
            {
                actual[--count] = VoltTackle;
            }

            if (count == 0)
            {
                valid = VerifyBaseMoves(value);
            }
            else
            {
                bool inherit = Breeding.GetCanInheritMoves(species);
                MarkMovesForOrigin(value, egg, count, inherit);
                valid = RecurseMovesForOrigin(value, count - 1);
            }

            if (!valid)
            {
                CleanResult(actual, possible);
            }
            return(value.Actual);
        }
Пример #14
0
        private int[] GetCurrentEggMoves(PKM pk, GameVersion version)
        {
            var moves = MoveEgg.GetEggMoves(pk, Species, Form, version);

            if (moves.Length == 0)
            {
                return(MoveLevelUp.GetEncounterMoves(pk, Level, version));
            }
            if (moves.Length >= 4 || pk.Format < 6)
            {
                return(moves);
            }

            // Sprinkle in some default level up moves
            var lvl = Legal.GetBaseEggMoves(pk, Species, Form, version, Level);

            return(lvl.Concat(moves).ToArray());
        }
Пример #15
0
        private static bool GetIsSharedEggMove(PKM pkm, int gen, int move)
        {
            if (gen < 8 || pkm.IsEgg)
            {
                return(false);
            }
            var table       = PersonalTable.SWSH;
            var entry       = (PersonalInfoSWSH)table.GetFormeEntry(pkm.Species, pkm.AltForm);
            var baseSpecies = entry.BaseSpecies;
            var baseForm    = entry.FormIndex;

            // since we aren't storing entry->seed_poke_index, there's oddballs we can't handle with just personal data (?)
            if (pkm.Species == (int)Species.Indeedee)
            {
                baseForm = pkm.AltForm;
            }

            var egg = MoveEgg.GetEggMoves(pkm, baseSpecies, baseForm, GameVersion.SW);

            return(egg.Contains(move));
        }
Пример #16
0
        public static EggSource6[] Validate(int generation, int species, int form, GameVersion version, int[] moves, out bool valid)
        {
            var count = Array.IndexOf(moves, 0);

            if (count == 0)
            {
                valid = false; // empty moveset
                return(Array.Empty <EggSource6>());
            }
            if (count == -1)
            {
                count = moves.Length;
            }

            var learn    = GameData.GetLearnsets(version);
            var table    = GameData.GetPersonal(version);
            var index    = table.GetFormIndex(species, form);
            var learnset = learn[index];
            var egg      = MoveEgg.GetEggMoves(generation, species, form, version);

            var value = new BreedInfo <EggSource6>(count, learnset, moves, 1);

            if (moves[count - 1] is (int)Move.VoltTackle)
            {
                if (--count == 0)
                {
                    valid = false; // must have base moves; sanity check
                    return(Array.Empty <EggSource6>());
                }
                value.Actual[count] = VoltTackle;
            }

            bool inherit = Breeding.GetCanInheritMoves(species);

            MarkMovesForOrigin(value, egg, count, inherit);

            valid = RecurseMovesForOrigin(value, count - 1);
            return(value.Actual);
        }
Пример #17
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));
        }
Пример #18
0
        internal static IEnumerable <int> GetValidRelearn(PKM pkm, int species, int form, bool inheritlvlmoves, GameVersion version = GameVersion.Any)
        {
            if (pkm.GenNumber < 6)
            {
                return(Array.Empty <int>());
            }

            var r = new List <int>();

            r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 1, form, version));

            if (pkm.Format == 6 && pkm.Species != 678)
            {
                form = 0;
            }

            r.AddRange(MoveEgg.GetEggMoves(pkm, species, form, version));
            if (inheritlvlmoves)
            {
                r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 100, form, version));
            }
            return(r.Distinct());
        }
Пример #19
0
        private static void ParseMovesByGeneration(PKM pkm, IList <CheckMoveResult> res, int gen, LegalInfo info, LearnInfo learnInfo)
        {
            var  moves  = learnInfo.Source.CurrentMoves;
            bool native = gen == pkm.Format;

            for (int m = 0; m < 4; m++)
            {
                if (IsCheckValid(res[m])) // already validated with another generation
                {
                    continue;
                }
                int move = moves[m];
                if (move == 0)
                {
                    continue;
                }

                if (gen <= 2)
                {
                    if (gen == 2 && !native && move > Legal.MaxMoveID_1 && pkm.VC1)
                    {
                        res[m] = new CheckMoveResult(Unknown, gen, Invalid, LMoveSourceInvalid, Move);
                        continue;
                    }
                    if (gen == 2 && learnInfo.Source.EggMoveSource.Contains(move))
                    {
                        res[m] = new CheckMoveResult(EggMove, gen, Valid, LMoveSourceEgg, Move);
                    }
                    else if (learnInfo.Source.Base.Contains(move))
                    {
                        res[m] = new CheckMoveResult(Initial, gen, Valid, native ? LMoveSourceDefault : string.Format(LMoveFDefault_0, gen), Move);
                    }
                }
                if (info.EncounterMoves.LevelUpMoves[gen].Contains(move))
                {
                    res[m] = new CheckMoveResult(LevelUp, gen, Valid, native ? LMoveSourceLevelUp : string.Format(LMoveFLevelUp_0, gen), Move);
                }
                else if (info.EncounterMoves.TMHMMoves[gen].Contains(move))
                {
                    res[m] = new CheckMoveResult(TMHM, gen, Valid, native ? LMoveSourceTMHM : string.Format(LMoveFTMHM_0, gen), Move);
                }
                else if (info.EncounterMoves.TutorMoves[gen].Contains(move))
                {
                    res[m] = new CheckMoveResult(Tutor, gen, Valid, native ? LMoveSourceTutor : string.Format(LMoveFTutor_0, gen), Move);
                }
                else if (gen == info.Generation && learnInfo.Source.SpecialSource.Contains(move))
                {
                    res[m] = new CheckMoveResult(Special, gen, Valid, LMoveSourceSpecial, Move);
                }
                else if (gen >= 8 && MoveEgg.GetIsSharedEggMove(pkm, gen, move))
                {
                    res[m] = new CheckMoveResult(Shared, gen, Valid, native ? LMoveSourceShared : string.Format(LMoveSourceSharedF, gen), Move);
                }

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

                // Gen1/Gen2 only below
                if (gen == 2 && learnInfo.Source.NonTradeBackLevelUpMoves.Contains(m))
                {
                    learnInfo.Gen2PreevoMoves.Add(m);
                }
                else if (gen == 1)
                {
                    learnInfo.Gen1Moves.Add(m);
                    if (learnInfo.Gen2PreevoMoves.Count != 0)
                    {
                        learnInfo.MixedGen12NonTradeback = true;
                    }
                }

                if (pkm.TradebackStatus == TradebackType.Any && info.Generation != gen)
                {
                    pkm.TradebackStatus = TradebackType.WasTradeback;
                }
            }
        }