Exemple #1
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));
        }
Exemple #2
0
        public override void Verify(LegalityAnalysis data)
        {
            var pkm = data.pkm;
            int originalGeneration = data.Info.Generation;
            int currentLanguage    = pkm.Language;
            int maxLanguageID      = Legal.GetMaxLanguageID(originalGeneration);

            if (!IsValidLanguageID(currentLanguage, maxLanguageID, pkm))
            {
                data.AddLine(GetInvalid(string.Format(LOTLanguage, $"<={(LanguageID)maxLanguageID}", (LanguageID)currentLanguage)));
                return;
            }

            // Korean Gen4 games can not trade with other Gen4 languages, but can use Pal Park with any Gen3 game/language.
            if (pkm.Format == 4 && pkm.Gen4 && !IsValidG4Korean(currentLanguage) &&
                !(data.EncounterMatch is EncounterTrade4 {
                Species : (int)Species.Pikachu or(int) Species.Magikarp
            })                                                                                                        // ger magikarp / eng pikachu
Exemple #3
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());
        }
Exemple #4
0
 private void ParsePK1()
 {
     pkm.TradebackStatus = Legal.GetTradebackStatusInitial(pkm);
     UpdateInfo();
     if (pkm.TradebackStatus == TradebackType.Any && Info.Generation != pkm.Format)
     {
         pkm.TradebackStatus = TradebackType.WasTradeback; // Example: GSC Pokemon with only possible encounters in RBY, like the legendary birds
     }
     Nickname.Verify(this);
     Level.Verify(this);
     Level.VerifyG1(this);
     Trainer.VerifyOTG1(this);
     Misc.VerifyMiscG1(this);
     if (pkm.Format == 2)
     {
         Item.Verify(this);
     }
 }
Exemple #5
0
        /// <summary>
        /// Checks if the <see cref="PKM"/> could inhabit a set of games.
        /// </summary>
        /// <param name="Generation">Set of games.</param>
        /// <param name="species"></param>
        /// <returns>True if could inhabit, False if not.</returns>
        public bool InhabitedGeneration(int Generation, int species = -1)
        {
            if (species < 0)
            {
                species = Species;
            }

            if (Format < Generation)
            {
                return(false); // Future
            }
            if (!IsOriginValid)
            {
                return(false);
            }

            // Sanity Check Species ID
            if (Legal.getMaxSpeciesOrigin(GenNumber) < species)
            {
                return(false);
            }

            int gen = GenNumber;

            switch (Generation)
            {
            case 1: return(VC);

            case 2: return(VC);

            case 3: return(Gen3);

            case 4: return(3 <= gen && gen <= 4);

            case 5: return(3 <= gen && gen <= 5);

            case 6: return(3 <= gen && gen <= 6);

            case 7: return(VC || 3 <= gen && gen <= 7);

            default:
                return(false);
            }
        }
        internal static List <EvoCriteria> GetOriginChain(PKM pkm, int maxspeciesorigin = -1, int lvl = -1, int minLevel = 1, bool skipChecks = false)
        {
            var chain = GetValidPreEvolutions(pkm, maxspeciesorigin, lvl, minLevel, skipChecks);

            if (!pkm.HasOriginalMetLocation)
            {
                var maxLevel = Legal.GetMaxLevelEncounter(pkm);
                if (maxLevel < 0)
                {
                    chain.Clear();
                    return(chain);
                }
                foreach (var c in chain)
                {
                    c.Level = Math.Min(maxLevel, c.Level);
                }
            }
            return(chain);
        }
Exemple #7
0
        private static EncounterStatic GetSuggestedEncounterEgg(PKM pkm, int loc = -1)
        {
            int lvl = 1; // gen5+

            if (!pkm.IsNative)
            {
                lvl = pkm.CurrentLevel; // be generous with transfer conditions
            }
            else if (pkm.Format < 5)    // and native
            {
                lvl = 0;
            }
            return(new EncounterStatic
            {
                Species = Legal.GetBaseSpecies(pkm),
                Location = loc != -1 ? loc : GetSuggestedEggMetLocation(pkm),
                Level = lvl,
            });
        }
Exemple #8
0
 private bool VerifyUnNicknamedEncounter(LegalityAnalysis data, PKM pkm, string nickname)
 {
     if (pkm.IsNicknamed)
     {
         for (int i = 0; i < SpeciesName.SpeciesLang.Count; i++)
         {
             if (!SpeciesName.SpeciesDict[i].TryGetValue(nickname, out int index))
             {
                 continue;
             }
             var msg = index == pkm.Species && i != pkm.Language ? LNickMatchNoOthersFail : LNickMatchLanguageFlag;
             data.AddLine(Get(msg, Severity.Fishy));
             return(true);
         }
         if (StringConverter.HasEastAsianScriptCharacters(nickname) && !(pkm is PB7)) // East Asian Scripts
         {
             data.AddLine(GetInvalid(LNickInvalidChar));
             return(true);
         }
         if (nickname.Length > Legal.GetMaxLengthNickname(data.Info.Generation, (LanguageID)pkm.Language))
         {
             var severe = data.EncounterOriginal.EggEncounter && pkm.WasTradedEgg && nickname.Length <= Legal.GetMaxLengthNickname(data.Info.Generation, LanguageID.English)
                     ? Severity.Fishy
                     : Severity.Invalid;
             data.AddLine(Get(LNickLengthLong, severe));
             return(true);
         }
         data.AddLine(GetValid(LNickMatchNoOthers));
     }
     else if (pkm.Format < 3)
     {
         // pk1/pk2 IsNicknamed getter checks for match, logic should only reach here if matches.
         data.AddLine(GetValid(LNickMatchLanguage));
     }
     else
     {
         var  EncounterMatch = data.EncounterOriginal;
         bool valid          = IsNicknameValid(pkm, EncounterMatch, nickname);
         var  result         = valid ? GetValid(LNickMatchLanguage) : GetInvalid(LNickMatchLanguageFail);
         data.AddLine(result);
     }
     return(false);
 }
        private void SetAltForm(PKM pk, ITrainerInfo sav)
        {
            switch (Species)
            {
            case (int)Core.Species.Minior:
                pk.AltForm = Util.Rand.Next(7, 14);
                break;

            case (int)Core.Species.Scatterbug:
            case (int)Core.Species.Spewpa:
            case (int)Core.Species.Vivillon:
                if (sav is IRegionOrigin o)
                {
                    pk.AltForm = Legal.GetVivillonPattern((byte)o.Country, (byte)o.Region);
                }
                // else 0
                break;
            }
        }
        public override void Verify(LegalityAnalysis data)
        {
            var pkm = data.pkm;

            if (!Legal.IsHeldItemAllowed(pkm))
            {
                data.AddLine(GetInvalid(LItemUnreleased));
            }

            if (pkm.Format == 3 && pkm.HeldItem == 175) // Enigma Berry
            {
                VerifyEReaderBerry(data);
            }

            if (pkm.IsEgg && pkm.HeldItem != 0)
            {
                data.AddLine(GetInvalid(LItemEgg));
            }
        }
Exemple #11
0
        public EncounterStatic getSuggestedMetInfo()
        {
            if (pkm == null)
            {
                return(null);
            }

            int loc = getSuggestedTransferLocation(pkm);

            if (pkm.WasEgg)
            {
                return new EncounterStatic
                       {
                           Species  = Legal.getBaseSpecies(pkm),
                           Location = loc != -1 ? loc : getSuggestedEggMetLocation(pkm),
                           Level    = 1,
                       }
            }
            ;

            var area = Legal.getCaptureLocation(pkm);

            if (area != null)
            {
                var slots = area.Slots.OrderBy(s => s.LevelMin);

                return(new EncounterStatic
                {
                    Species = slots.First().Species,
                    Location = loc != -1 ? loc : area.Location,
                    Level = slots.First().LevelMin,
                });
            }

            var encounter = Legal.getStaticLocation(pkm);

            if (loc != -1 && encounter != null)
            {
                encounter.Location = loc;
            }
            return(encounter);
        }
Exemple #12
0
        /// <summary>
        /// Sets the <see cref="PKM"/> data with a suggested value based on its <see cref="LegalityAnalysis"/>.
        /// </summary>
        /// <param name="name">Property to modify.</param>
        /// <param name="info">Cached info storing Legal data.</param>
        private static ModifyResult SetSuggestedPKMProperty(string name, PKMInfo info)
        {
            var PKM = info.pkm;

            switch (name)
            {
            case nameof(PKM.Stats):
                PKM.SetStats(PKM.GetStats(PKM.PersonalInfo));
                return(ModifyResult.Modified);

            case nameof(IHyperTrain.HyperTrainFlags):
                PKM.SetSuggestedHyperTrainingData();
                return(ModifyResult.Modified);

            case nameof(PKM.RelearnMoves):
                PKM.RelearnMoves = info.SuggestedRelearn;
                return(ModifyResult.Modified);

            case nameof(PKM.Met_Location):
                var encounter = info.SuggestedEncounter;
                if (encounter == null)
                {
                    return(ModifyResult.Error);
                }

                int level    = encounter.Level;
                int location = encounter.Location;
                int minlvl   = Legal.GetLowestLevel(PKM, encounter.LevelMin);

                PKM.Met_Level    = level;
                PKM.Met_Location = location;
                PKM.CurrentLevel = Math.Max(minlvl, level);

                return(ModifyResult.Modified);

            case nameof(PKM.Moves):
                return(SetMoves(PKM, PKM.GetMoveSet(la: info.Legality)));

            default:
                return(ModifyResult.Error);
            }
        }
Exemple #13
0
        /// <summary>
        /// Gets four moves which can be learned depending on the input arguments.
        /// </summary>
        /// <param name="tm">Allow TM moves</param>
        /// <param name="tutor">Allow Tutor moves</param>
        /// <param name="reminder">Allow Move Reminder</param>
        public int[] GetSuggestedMoves(bool tm, bool tutor, bool reminder)
        {
            if (!Parsed)
            {
                return(new int[4]);
            }
            if (pkm.IsEgg && pkm.Format <= 5) // pre relearn
            {
                return(Legal.GetBaseEggMoves(pkm, pkm.Species, (GameVersion)pkm.Version, pkm.CurrentLevel));
            }
            if (!(tm || tutor || reminder) && (Info.Generation <= 2 || pkm.Species == EncounterOriginal.Species))
            {
                var lvl = Info.Generation <= 2 && pkm.Format >= 7 ? pkm.Met_Level : pkm.CurrentLevel;
                var ver = Info.Generation <= 2 && EncounterOriginal is IVersion v ? v.Version : (GameVersion)pkm.Version;
                return(MoveLevelUp.GetEncounterMoves(pkm, lvl, ver));
            }
            var evos = Info.EvoChainsAllGens;

            return(Legal.GetValidMoves(pkm, evos, Tutor: tutor, Machine: tm, MoveReminder: reminder).Skip(1).ToArray()); // skip move 0
        }
Exemple #14
0
 private static void ParseMovesSketch(PKM pkm, CheckMoveResult[] parse, ReadOnlySpan <int> currentMoves)
 {
     for (int i = parse.Length - 1; i >= 0; i--)
     {
         var r    = parse[i];
         var move = currentMoves[i];
         if (move == 0)
         {
             r.Set(None, pkm.Format, Valid, LMoveSourceEmpty, CurrentMove);
         }
         else if (Legal.IsValidSketch(move, pkm.Format))
         {
             r.Set(Sketch, pkm.Format, Valid, L_AValid, CurrentMove);
         }
         else
         {
             r.Set(Unknown, pkm.Format, Invalid, LMoveSourceInvalidSketch, CurrentMove);
         }
     }
 }
Exemple #15
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)
        {
            var eggs = EncounterEggGenerator.GenerateEggs(pk, all: true);

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

                    continue;
                }

                var em = Legal.GetEggMoves(pk, egg.Species, pk.AltForm, version);
                if (!needs.Except(em).Any())
                {
                    yield return(egg);
                }
            }
        }
Exemple #16
0
        private int GetEdgeCaseLanguage(PKM pk, int lang)
        {
            switch (pk.Format)
            {
            case 1 when Species == (int)Core.Species.Mew && Version == GameVersion.VCEvents:     // VC Mew
                pk.TID     = 22796;
                pk.OT_Name = Legal.GetG1OT_GFMew(lang);
                return(lang);

            case 1 when Version == GameVersion.EventsGBGen1:
            case 2 when Version == GameVersion.EventsGBGen2:
            case 3 when this is EncounterStaticShadow s && s.EReader:
            case 3 when Species == (int)Core.Species.Mew:
                pk.OT_Name = "ゲーフリ";
                return((int)LanguageID.Japanese);    // Old Sea Map was only distributed to Japanese games.

            default:
                return(lang);
            }
        }
Exemple #17
0
        private static CheckResult[] VerifyRelearnEggBase(PKM pkm, LegalInfo info, EncounterEgg e)
        {
            int[]         RelearnMoves = pkm.RelearnMoves;
            CheckResult[] res          = new CheckResult[4];
            // Level up moves cannot be inherited if Ditto is the 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
            bool inheritLvlMoves = Legal.GetCanInheritMoves(e.Species);

            // Obtain level1 moves
            var baseMoves = Legal.GetBaseEggMoves(pkm, e.Species, e.Version, 1);
            int baseCt    = Math.Min(4, baseMoves.Length);

            // Obtain Inherited moves
            var inheritMoves = Legal.GetValidRelearn(pkm, e.Species, inheritLvlMoves, e.Version).ToList();
            int reqBase      = GetRequiredBaseMoves(RelearnMoves, baseMoves, baseCt, inheritMoves);

            // Check if the required amount of Base Egg Moves are present.
            FlagBaseEggMoves(res, reqBase, baseMoves, RelearnMoves);

            // Non-Base moves that can magically appear in the regular movepool
            if (Legal.LightBall.Contains(pkm.Species))
            {
                inheritMoves.Add(344); // Volt Tackle
            }
            // If any splitbreed moves are invalid, flag accordingly
            var splitMoves = e is EncounterEggSplit s
                ? Legal.GetValidRelearn(pkm, s.OtherSpecies, inheritLvlMoves, e.Version).ToList()
                : (IReadOnlyList <int>)Array.Empty <int>();

            // Inherited moves appear after the required base moves.
            // If the pkm is capable of split-species breeding and any inherited move is from the other split scenario, flag accordingly.
            bool splitInvalid = FlagInvalidInheritedMoves(res, reqBase, RelearnMoves, inheritMoves, splitMoves);

            if (splitInvalid)
            {
                FlagSplitbreedMoves(res, reqBase, e, pkm);
            }

            info.RelearnBase = baseMoves;
            return(res);
        }
Exemple #18
0
        private void updateTypeInfo()
        {
            if (pkm.VC && pkm.Format == 7)
            {
                EncounterMatch = Legal.getRBYStaticTransfer(pkm.Species);
            }

            if (pkm.GenNumber <= 2 && pkm.TradebackStatus == TradebackType.Any && EncountersGBMatch?.All(e => e.Generation != pkm.GenNumber) == true)
            {
                // Example: GSC Pokemon with only possible encounters in RBY, like the legendary birds
                pkm.TradebackStatus = TradebackType.WasTradeback;
            }

            MatchedType = Type = (EncounterOriginalGB ?? EncounterMatch ?? pkm.Species)?.GetType();
            var bt = Type.GetTypeInfo().BaseType;

            if (bt != null && !(bt == typeof(Array) || bt == typeof(object) || bt.GetTypeInfo().IsPrimitive)) // a parent exists
            {
                Type = bt;                                                                                    // use base type
            }
        }
        private CheckResult VerifyBallWild(LegalityAnalysis data, EncounterSlot w)
        {
            if (w.Location == 30016 && w.Generation == 7)  // Poké Pelago
            {
                return(VerifyBallEquals(data, (int)Poke)); // Pokeball
            }
            var Info = data.Info;

            // For gen3/4 Safari Zones and BCC getValidWildEncounters already filter to not return
            // mixed possible encounters between safari, BCC and other encounters
            // That means is the first encounter is not safari then there is no safari encounter in the array
            if (3 <= Info.Generation && Info.Generation <= 4 && w.Type.IsSafariType())
            {
                return(VerifyBallEquals(data, (int)Safari)); // Safari Ball
            }
            if (Info.Generation == 4 && w.Type == SlotType.BugContest)
            {
                return(VerifyBallEquals(data, (int)Sport)); // Sport Ball
            }
            return(VerifyBallEquals(data, Legal.GetWildBalls(data.pkm)));
        }
Exemple #20
0
        private void SetTradebackStatusInitial()
        {
            if (pkm is PK1 pk1)
            {
                Legal.SetTradebackStatusRBY(pk1);
                return;
            }

            if (pkm.Format == 2 || pkm.VC2)
            {
                // Check for impossible tradeback scenarios
                bool g2only = !pkm.CanInhabitGen1();
                pkm.TradebackStatus = g2only ? TradebackType.Gen2_NotTradeback : TradebackType.Any;
                return;
            }

            // VC2 is released, we can assume it will be TradebackType.Any.
            // Is impossible to differentiate a VC1 pokemon traded to Gen7 after VC2 is available.
            // Met Date cannot be used definitively as the player can change their system clock.
            pkm.TradebackStatus = TradebackType.Any;
        }
Exemple #21
0
        private CheckResult VerifyG1OTStadium(PKM pkm, string tr, IVersion s)
        {
            if (pkm.OT_Gender != 0)
            {
                return(GetInvalid(LG1OTGender));
            }

            int tid = pkm.TID;

            if (pkm.Japanese)
            {
                if (tid == Legal.GetGBStadiumOTID_JPN(s.Version) && Legal.Stadium1JP == tr)
                {
                    return(GetValid(LG1StadiumJapanese));
                }
            }
            else
            {
                if (s.Version == GameVersion.Stadium && tid == 2000)
                {
                    if (tr == "STADIUM" || tr == "STADE" || tr == "STADIO" || tr == "ESTADIO")
                    {
                        return(GetValid(LG1StadiumInternational));
                    }
                }
                else // Stadium2
                {
                    if (tid == 2000 && tr == "Stadium")
                    {
                        return(GetValid(LG1StadiumInternational));
                    }

                    if (tid == 2001 && (tr == "Stade" || tr == "Stadion" || tr == "Stadio" || tr == "Estadio"))
                    {
                        return(GetValid(LG1StadiumInternational));
                    }
                }
            }
            return(GetInvalid(LG1Stadium));
        }
Exemple #22
0
        public override void Verify(LegalityAnalysis data)
        {
            var pkm = data.pkm;
            int originalGeneration = data.Info.Generation;
            int currentLanguage    = pkm.Language;
            int maxLanguageID      = Legal.GetMaxLanguageID(originalGeneration);

            if (!IsValidLanguageID(currentLanguage, maxLanguageID, pkm))
            {
                data.AddLine(GetInvalid(string.Format(LOTLanguage, $"<={(LanguageID)maxLanguageID}", (LanguageID)currentLanguage)));
                return;
            }

            // Korean Gen4 games can not trade with other Gen4 languages, but can use Pal Park with any Gen3 game/language.
            if (pkm.Format == 4 && pkm.Gen4 && !IsValidG4Korean(currentLanguage) &&
                !(data.EncounterMatch is EncounterTrade x && (x.Species == (int)Species.Pikachu || x.Species == (int)Species.Magikarp))    // ger magikarp / eng pikachu
                )
            {
                bool kor    = currentLanguage == (int)LanguageID.Korean;
                var  msgpkm = kor ? L_XKorean : L_XKoreanNon;
                var  msgsav = kor ? L_XKoreanNon : L_XKorean;
                data.AddLine(GetInvalid(string.Format(LTransferOriginFInvalid0_1, msgpkm, msgsav)));
                return;
            }

            if (originalGeneration <= 2)
            {
                // Korean Crystal does not exist, neither do Korean VC1
                if (pkm.Korean && !GameVersion.GS.Contains((GameVersion)pkm.Version))
                {
                    data.AddLine(GetInvalid(string.Format(LOTLanguage, $"!={(LanguageID)currentLanguage}", (LanguageID)currentLanguage)));
                }

                // Japanese VC is language locked; cannot obtain Japanese-Blue version as other languages.
                if (pkm.Version == (int)GameVersion.BU && !pkm.Japanese)
                {
                    data.AddLine(GetInvalid(string.Format(LOTLanguage, nameof(LanguageID.Japanese), (LanguageID)currentLanguage)));
                }
            }
        }
        private static CheckMoveResult[] ParseMovesIsEggPreRelearn(PKM pkm, int[] Moves, int[] SpecialMoves, bool allowinherited, EncounterEgg e)
        {
            CheckMoveResult[] res = new CheckMoveResult[4];

            var baseEggMoves = Legal.GetBaseEggMoves(pkm, e.Species, e.Game, pkm.GenNumber < 4 ? 5 : 1)?.ToList() ?? new List <int>();
            // Level up moves cannot be inherited if Ditto is parent, thus genderless/single gender species cannot have level up moves as an egg
            bool AllowLvlMoves     = pkm.PersonalInfo.Gender > 0 && pkm.PersonalInfo.Gender < 255 || Legal.MixedGenderBreeding.Contains(e.Species);
            var  InheritedLvlMoves = !AllowLvlMoves? new List <int>() : Legal.GetBaseEggMoves(pkm, e.Species, e.Game, 100)?.ToList() ?? new List <int>();

            InheritedLvlMoves.RemoveAll(x => baseEggMoves.Contains(x));

            var infoset = new MoveInfoSet
            {
                EggMoves       = Legal.GetEggMoves(pkm, e.Species, pkm.AltForm)?.ToList() ?? new List <int>(),
                TutorMoves     = e.Game == GameVersion.C ? Legal.GetTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2)?.ToList() : new List <int>(),
                TMHMMoves      = Legal.GetTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, e.Game, false)?.ToList(),
                LvlMoves       = InheritedLvlMoves,
                BaseMoves      = baseEggMoves,
                SpecialMoves   = SpecialMoves.Where(m => m != 0).ToList(),
                AllowInherited = allowinherited
            };

            // Only TM Hm moves from the source game of the egg, not any other games from the same generation

            if (pkm.Format > 2 || SpecialMoves.Any())
            {
                // For gen 2 is not possible to difference normal eggs from event eggs
                // If there is no special moves assume normal egg
                res = VerifyPreRelearnEggBase(pkm, Moves, infoset, e.Game);
            }
            else if (pkm.Format == 2)
            {
                infoset.SpecialMoves.Clear();
                infoset.AllowInherited = true;
                res = VerifyPreRelearnEggBase(pkm, Moves, infoset, e.Game);
            }

            return(res);
        }
Exemple #24
0
        private static bool CanKnowMove(PKM pkm, MemoryVariableSet memory, int gen, LegalInfo info, bool battleOnly = false)
        {
            var move = memory.Variable;

            if (move == 0)
            {
                return(false);
            }

            if (pkm.HasMove(move))
            {
                return(true);
            }

            if (Legal.GetCanKnowMove(pkm, memory.Variable, gen, info.EvoChainsAllGens))
            {
                return(true);
            }

            var enc = info.EncounterMatch;

            if (enc is IMoveset ms && ms.Moves.Contains(move))
            {
                return(true);
            }

            if (battleOnly)
            {
                // Some moves can only be known in battle; outside of battle they aren't obtainable as a memory parameter.
                switch (move)
                {
                case 781 when pkm.Species == (int)Species.Zacian:     // Behemoth Blade
                case 782 when pkm.Species == (int)Species.Zamazenta:  // Behemoth Blade
                    return(true);
                }
            }

            return(false);
        }
        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 Volbet (they breed with female nidoran and illumise) could not have level up moves as an egg
            var inheritLvlMoves      = pkm.PersonalInfo.Gender > 0 && pkm.PersonalInfo.Gender < 255 || Legal.MixedGenderBreeding.Contains(e.Species);
            int BaseLvlMoves         = inheritLvlMoves ? 100 : pkm.GenNumber <= 3 ? 5 : 1;
            var LvlupEggMoves        = Legal.GetBaseEggMoves(pkm, e.Species, e.Game, BaseLvlMoves);
            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 EggMoves = Legal.GetEggMoves(pkm, e.Species, pkm.AltForm);

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

            return(ParseMoves(pkm, Moves, SpecialMoves, LvlupEggMoves, EggMoves, NonTradebackLvlMoves, EventEggMoves, new int[0], info));
        }
Exemple #26
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));
        }
        private static ValidEncounterMoves GetEncounterValidMoves(PKM pkm, LegalInfo info)
        {
            var minLvLG1         = pkm.GenNumber <= 2 ? info.EncounterMatch.LevelMin + 1 : 0;
            var minLvlG2         = Legal.AllowGen2MoveReminder ? 1 : info.EncounterMatch.LevelMin + 1;
            var encounterspecies = info.EncounterMatch.Species;
            var EvoChainsAllGens = info.EvoChainsAllGens;
            // If encounter species is the same species from the first match, the one in variable EncounterMatch, its evolution chains is already in EvoChainsAllGens
            var LevelMoves = Legal.GetValidMovesAllGens(pkm, EvoChainsAllGens, minLvLG1: minLvLG1, minLvLG2: minLvlG2, Tutor: false, Machine: false, RemoveTransferHM: false);
            var TMHMMoves  = Legal.GetValidMovesAllGens(pkm, EvoChainsAllGens, LVL: false, Tutor: false, MoveReminder: false, RemoveTransferHM: false);
            var TutorMoves = Legal.GetValidMovesAllGens(pkm, EvoChainsAllGens, LVL: false, Machine: false, MoveReminder: false, RemoveTransferHM: false);

            return(new ValidEncounterMoves
            {
                EncounterSpecies = encounterspecies,
                LevelUpMoves = LevelMoves,
                TMHMMoves = TMHMMoves,
                TutorMoves = TutorMoves,
                EvolutionChains = EvoChainsAllGens,
                MinimumLevelGen1 = minLvLG1,
                MinimumLevelGen2 = minLvlG2
            });
        }
        public static bool IsEdgeCaseLength(PKM pkm, IEncounterable e, string ot)
        {
            if (e.EggEncounter)
            {
                if (e is WC3 wc3 && pkm.IsEgg && wc3.OT_Name == ot)
                {
                    return(true); // Fixed OT Mystery Gift Egg
                }
                bool eggEdge = pkm.IsEgg ? pkm.IsTradedEgg || pkm.Format == 3 : pkm.WasTradedEgg;
                if (!eggEdge)
                {
                    return(false);
                }
                var len = Legal.GetMaxLengthOT(pkm.GenNumber, LanguageID.English); // max case
                return(ot.Length <= len);
            }

            if (e is MysteryGift mg && mg.OT_Name.Length == ot.Length)
            {
                return(true); // Mattle Ho-Oh
            }
            return(false);
        }
        private static CheckResult VerifyWildEncounterCrystalHeadbutt(PKM pkm, EncounterSlot1 encounter)
        {
            var Area = Legal.GetCrystalTreeArea(encounter);

            if (Area == null)  // Failsafe, every area with headbutt encounters have a tree area
            {
                return(new CheckResult(Severity.Invalid, V605, CheckIdentifier.Encounter));
            }
            var trainerpivot  = pkm.TID % 10;
            var availabletree = encounter.Type == SlotType.Headbutt ? Area.TrainerModerateEncounterTree[trainerpivot] : Area.TrainerLowEncounterTree[trainerpivot];

            switch (availabletree)
            {
            case TreeEncounterAvailable.ValidTree:
                return(new CheckResult(Severity.Valid, V604, CheckIdentifier.Encounter));

            case TreeEncounterAvailable.InvalidTree:
                return(new CheckResult(Severity.Invalid, V604, CheckIdentifier.Encounter));

            default:     //reeEncounterAvailable.Impossible
                return(new CheckResult(Severity.Invalid, V605, CheckIdentifier.Encounter));
            }
        }
Exemple #30
0
        private void UpdateTradebackG12()
        {
            if (pkm.Format == 1)
            {
                Legal.SetTradebackStatusRBY(pkm);
                return;
            }

            if (pkm.Format == 2 || pkm.VC2)
            {
                // Check for impossible tradeback scenarios
                // Korean Gen2 games can't tradeback because there are no Gen1 Korean games released
                bool g2only = pkm.Korean || pkm.IsEgg || pkm.HasOriginalMetLocation ||
                              pkm.Species > Legal.MaxSpeciesID_1 && !Legal.FutureEvolutionsGen1.Contains(pkm.Species);
                pkm.TradebackStatus = g2only ? TradebackType.Gen2_NotTradeback : TradebackType.Any;
                return;
            }

            // VC2 is released, we can assume it will be TradebackType.Any.
            // Is impossible to differentiate a VC1 pokemon traded to Gen7 after VC2 is available.
            // Met Date cannot be used definitively as the player can change their system clock.
            pkm.TradebackStatus = TradebackType.Any;
        }