Exemplo n.º 1
0
        private static void CheckLastEncounterRemoval(IEncounterable enc, IReadOnlyList <EvoCriteria> chain)
        {
            // Last entry from chain is removed, turn next entry into the encountered Pokémon
            var last = chain[chain.Count - 1];

            last.MinLevel      = enc.LevelMin;
            last.RequiresLvlUp = false;

            var first = chain[0];

            if (first.RequiresLvlUp)
            {
                return;
            }

            if (first.MinLevel == 2)
            {
                // Example: Raichu in Gen2 or later
                // Because Pichu requires a level up, the minimum level of the resulting Raichu must be be >2
                // But after removing Pichu (because the origin species is Pikachu), the Raichu minimum level should be 1.
                first.MinLevel      = 1;
                first.RequiresLvlUp = false;
            }
            else // in-game trade or evolution stone can evolve immediately
            {
                first.MinLevel = last.MinLevel;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets an object containing met data properties that might be legal.
        /// </summary>
        public static EncounterSuggestionData?GetSuggestedMetInfo(PKM pkm)
        {
            int loc = GetSuggestedTransferLocation(pkm);

            if (pkm.WasEgg)
            {
                return(GetSuggestedEncounterEgg(pkm, loc));
            }

            var chain = EvolutionChain.GetValidPreEvolutions(pkm, maxLevel: 100, skipChecks: true);
            var w     = EncounterSlotGenerator.GetCaptureLocation(pkm, chain);
            var s     = EncounterStaticGenerator.GetStaticLocation(pkm, chain);

            if (w is null)
            {
                return(s is null ? null : GetSuggestedEncounter(pkm, s, loc));
            }
            if (s is null)
            {
                return(GetSuggestedEncounter(pkm, w, loc));
            }

            bool           isDefinitelySlot   = chain.Any(z => z.Species == w.Species && z.Form == w.Form);
            bool           isDefinitelyStatic = chain.Any(z => z.Species == s.Species && z.Form == s.Form);
            IEncounterable obj = (isDefinitelySlot || !isDefinitelyStatic) ? w : s;

            return(GetSuggestedEncounter(pkm, obj, loc));
        }
Exemplo n.º 3
0
        // Eggs
        private static CheckResult VerifyEncounterEgg(PKM pkm, IEncounterable egg)
        {
            pkm.WasEgg = true;
            // Check Species
            if (Legal.NoHatchFromEgg.Contains(pkm.Species))
            {
                return(new CheckResult(Severity.Invalid, V50, CheckIdentifier.Encounter));
            }
            switch (pkm.GenNumber)
            {
            case 1:
            case 2: return(new CheckResult(CheckIdentifier.Encounter));    // no met location info

            case 3: return(pkm.Format != 3 ? VerifyEncounterEgg3Transfer(pkm) : VerifyEncounterEgg3(pkm));

            case 4: return(pkm.IsEgg ? VerifyUnhatchedEgg(pkm, 02002) : VerifyEncounterEgg4(pkm));

            case 5: return(pkm.IsEgg ? VerifyUnhatchedEgg(pkm, 30003) : VerifyEncounterEgg5(pkm));

            case 6: return(pkm.IsEgg ? VerifyUnhatchedEgg(pkm, 30002) : VerifyEncounterEgg6(pkm));

            case 7: return(pkm.IsEgg ? VerifyUnhatchedEgg(pkm, 30002) : VerifyEncounterEgg7(pkm));

            default:     // none of the above
                return(new CheckResult(Severity.Invalid, V51, CheckIdentifier.Encounter));
            }
        }
 private static void SetFormArgument(this PKM pk, IEncounterable enc)
 {
     if (pk is IFormArgument f)
     {
         f.FormArgument = GetSuggestedFormArgument(pk, enc.Species);
     }
 }
Exemplo n.º 5
0
 public GBEncounterData(PKM pkm, int gen, IEncounterable enc, GameVersion game)
 {
     Game       = game;
     Generation = gen;
     Encounter  = enc;
     if (Encounter is EncounterTrade trade)
     {
         if (pkm.HasOriginalMetLocation && trade.Level < pkm.Met_Level)
         {
             Level = pkm.Met_Level; // Crystal
         }
         else
         {
             Level = trade.Level;
         }
         Type = Generation == 2
             ? GBEncounterType.TradeEncounterG2
             : GBEncounterType.TradeEncounterG1;
     }
     else if (Encounter is EncounterStatic statc)
     {
         Level = statc.Level;
         Type  = statc.Moves != null && statc.Moves[0] != 0 && pkm.Moves.Contains(statc.Moves[0])
             ? GBEncounterType.SpecialEncounter
             : GBEncounterType.StaticEncounter;
     }
     else if (Encounter is EncounterSlot1 slot)
     {
         Level = pkm.HasOriginalMetLocation && slot.LevelMin >= pkm.Met_Level && pkm.Met_Level <= slot.LevelMax
             ? pkm.Met_Level // Crystal
             : slot.LevelMin;
         Type = GBEncounterType.WildEncounter;
     }
 }
Exemplo n.º 6
0
        /// <summary>
        /// Sets all ribbon flags according to a legality report.
        /// </summary>
        /// <param name="pk">Pokémon to modify</param>
        /// <param name="allValid">Set all valid ribbons only</param>
        public static void SetSuggestedRibbons(this PKM pk, IEncounterable enc, bool allValid = true)
        {
            if (allValid)
            {
                RibbonApplicator.SetAllValidRibbons(pk);
                if (pk is PK8 pk8 && pk8.Species != (int)Species.Shedinja && pk8.GetRandomValidMark(enc, out var mark))
                {
                    pk8.SetRibbonIndex(mark);
                }
            }
            string report = new LegalityAnalysis(pk).Report();

            if (report.Contains(string.Format(LegalityCheckStrings.LRibbonFMissing_0, "")))
            {
                var val            = string.Format(LegalityCheckStrings.LRibbonFMissing_0, "");
                var ribbonList     = GetRequiredRibbons(report, val);
                var missingRibbons = GetRibbonsRequired(pk, ribbonList);
                SetRibbonValues(pk, missingRibbons, 0, true);
            }
            if (report.Contains(string.Format(LegalityCheckStrings.LRibbonFInvalid_0, "")))
            {
                var      val            = string.Format(LegalityCheckStrings.LRibbonFInvalid_0, "");
                string[] ribbonList     = GetRequiredRibbons(report, val);
                var      invalidRibbons = GetRibbonsRequired(pk, ribbonList);
                SetRibbonValues(pk, invalidRibbons, 0, false);
            }
        }
Exemplo n.º 7
0
        private static IEnumerable <EncounterSummary> GetSummaries(IEncounterable item)
        {
            switch (item)
            {
            case EncounterSlot s:
                var type = s.Type;
                if (type == 0)
                {
                    yield return(new EncounterSummary(item));

                    break;
                }
                for (int i = 0; i < sizeof(SlotType) * 8; i++)
                {
                    var flag = (SlotType)(1 << i);
                    if ((type & flag) != 0)
                    {
                        yield return(new EncounterSummary(item, flag.ToString()));
                    }
                }

                break;

            default:
                yield return(new EncounterSummary(item));

                break;
            }
        }
Exemplo n.º 8
0
 public static bool IsMarkAllowedSpecific(RibbonIndex mark, PKM pk, IEncounterable _)
 {
     return(mark switch
     {
         RibbonIndex.MarkCurry when !IsMarkAllowedCurry(pk) => false,
         RibbonIndex.MarkDestiny => false,
         _ => true
     });
Exemplo n.º 9
0
 private static int[] GetSpecialMoves(IEncounterable EncounterMatch)
 {
     if (EncounterMatch is IMoveset mg)
     {
         return(mg.Moves ?? new int[0]);
     }
     return(new int[0]);
 }
Exemplo n.º 10
0
 // Egg encounter
 public GBEncounterData(int species, GameVersion game)
 {
     Generation = 2;
     Game       = game;
     Encounter  = new EncounterEgg {
         Species = species, Game = game, Level = Level
     };
 }
Exemplo n.º 11
0
 private static IReadOnlyList <int> GetSpecialMoves(IEncounterable EncounterMatch)
 {
     if (EncounterMatch is IMoveset mg)
     {
         return(mg.Moves);
     }
     return(Array.Empty <int>());
 }
Exemplo n.º 12
0
 public void PrepareEncounter(IEncounterable npc)
 {
     lastEncounter = npc;
     state         = State.Talking;
     SetLookingTarget(npc.GetTransform());
     Utility.instance.ScaleGameObject(transform, new Vector3(2, 2, 2), .3f, encounterAnimationCurve);
     AudioManager.instance.PlaySound("EncounterTrigger");
 }
Exemplo n.º 13
0
 // Utility
 private static bool IsEncounterTypeMatch(IEncounterable e, int type)
 {
     return(e switch
     {
         EncounterStaticTyped t => t.TypeEncounter.Contains(type),
         EncounterSlot4 w => w.TypeEncounter.Contains(type),
         _ => (type == 0)
     });
Exemplo n.º 14
0
 private static int[] GetSpecialMoves(IEncounterable EncounterMatch)
 {
     if (EncounterMatch is IMoveset mg)
     {
         return(mg.Moves ?? Array.Empty <int>());
     }
     return(Array.Empty <int>());
 }
Exemplo n.º 15
0
 private static bool IsCuteCharm4Valid(IEncounterable encounter, PKM pkm)
 {
     if (pkm.Species == 183 || pkm.Species == 184)
     {
         return(!IsCuteCharmAzurillMale(pkm.PID) || // recognized as not Azurill
                encounter.Species == 298);   // encounter must be male Azurill
     }
     return(true);
 }
Exemplo n.º 16
0
        /// <summary>
        /// Gets the current <see cref="PKM.RelearnMoves"/> array of four moves that might be legal.
        /// </summary>
        /// <remarks>Use <see cref="GetSuggestedRelearnMovesFromEncounter"/> instead of calling directly; this method just puts default values in without considering the final moveset.</remarks>
        public static IReadOnlyList <int> GetSuggestedRelearn(this IEncounterable enc, PKM pkm)
        {
            if (ShouldNotHaveRelearnMoves(enc, pkm))
            {
                return(Empty);
            }

            return(GetSuggestedRelearnInternal(enc, pkm));
        }
Exemplo n.º 17
0
        private static List <EvoCriteria> GetEvolutionChain(PKM pkm, IEncounterable Encounter, int maxspec, int maxlevel)
        {
            var vs = GetValidPreEvolutions(pkm, minLevel: Encounter.LevelMin);

            if (Encounter.Species == maxspec)
            {
                if (vs.Count != 1)
                {
                    vs.RemoveAll(z => z.Species != Encounter.Species);
                    vs[0].MinLevel = Encounter.LevelMin;
                }
                return(vs);
            }

            // Evolution chain is in reverse order (devolution)
            // Find the index of the minimum species to determine the end of the chain
            int  minindex = GetEvoChainSpeciesIndex(vs, Encounter.Species);
            bool last     = minindex < 0 || minindex == vs.Count - 1;

            // If we remove a pre-evolution, update the chain if appropriate.
            if (!last)
            {
                // Remove chain species after the encounter
                int count = vs.Count;
                for (int i = minindex + 1; i < count; i++)
                {
                    vs.RemoveAt(i);
                }

                if (vs.Count == 0)
                {
                    return(vs); // no species left in chain
                }
                CheckLastEncounterRemoval(Encounter, vs);
            }

            // maxspec is used to remove future geneneration evolutions, to gather evolution chain of a pokemon in previous generations
            int skip = Math.Max(0, GetEvoChainSpeciesIndex(vs, maxspec));

            for (int i = 0; i < skip; i++)
            {
                vs.RemoveAt(0);
            }

            // Gen3->4 and Gen4->5 transfer sets the Met Level property to the Pokémon's current level.
            // Removes evolutions impossible before the transfer level.
            // For example a FireRed Charizard with a current level (in XY) is 50 but Met Level is 20; it couldn't be a Charizard in Gen3 and Gen4 games
            vs.RemoveAll(e => e.MinLevel > maxlevel);

            // Reduce the evolution chain levels to max level to limit any later analysis/results.
            foreach (var d in vs)
            {
                d.Level = Math.Min(d.Level, maxlevel);
            }

            return(vs);
        }
Exemplo n.º 18
0
 // Egg encounter
 public GBEncounterData(int species, GameVersion game)
 {
     Generation = 2;
     Game       = game;
     Encounter  = new EncounterEgg {
         Species = species, Game = game, Level = 5
     };
     Type = GBEncounterType.EggEncounter;
 }
Exemplo n.º 19
0
 private static void AddEdgeCaseMoves(List <int> moves, IEncounterable encounter, PKM pkm)
 {
     switch (encounter)
     {
     case EncounterStatic8N r when !EncounterStatic8N.IsHighestLevelTier(pkm.Met_Level) && r.IsDownLeveled(pkm):     // Downleveled Raid can happen for shared raids and self-hosted raids.
         moves.AddRange(MoveLevelUp.GetMovesLevelUp(pkm, r.Species, -1, -1, r.LevelMax, r.Form, GameVersion.SW, false, 8));
         break;
     }
 }
Exemplo n.º 20
0
 private static void AddEdgeCaseMoves(List <int> moves, IEncounterable encounter, PKM pkm)
 {
     switch (encounter)
     {
     case EncounterStatic8N r when pkm.Met_Location == Encounters8Nest.SharedNest && !EncounterStatic8N.IsHighestLevelTier(pkm.Met_Level):
         moves.AddRange(MoveLevelUp.GetMovesLevelUp(pkm, r.Species, -1, -1, 60, r.Form, GameVersion.SW, false, 8));
         break;
     }
 }
Exemplo n.º 21
0
 private static bool DisallowSurpriseTrade(PKM pk, IEncounterable enc)
 {
     // Anti-spam
     if (pk.IsNicknamed && !(enc is EncounterTrade t && t.IsNicknamed) && pk.Nickname.Length > 6)
     {
         return(true);
     }
     return(DisallowSurpriseTrade(pk));
 }
Exemplo n.º 22
0
 private void UpdateVCTransferInfo()
 {
     EncounterOriginalGB = EncounterMatch;
     if (pkm.VC1)
         Info.EncounterMatch = EncounterGenerator.GetRBYStaticTransfer(pkm.Species, pkm.Met_Level);
     else if (pkm.VC2)
         Info.EncounterMatch = EncounterGenerator.GetGSStaticTransfer(pkm.Species, pkm.Met_Level);
     foreach (var z in VerifyVCEncounter(pkm, EncounterOriginalGB.Species, EncounterOriginalGB as GBEncounterData, Info.EncounterMatch as EncounterStatic))
         AddLine(z);
 }
Exemplo n.º 23
0
 private static int GetForm(IEncounterable enc)
 {
     return(enc switch
     {
         EncounterSlot s => s.Form,
         EncounterStatic s => s.Form,
         MysteryGift m => m.Form,
         EncounterTrade t => t.Form,
         _ => 0
     });
        private static int GetEncounterFixedAbilityNumber(IEncounterable enc)
        {
            switch (enc)
            {
            case EncounterStatic s: return(s.Ability);

            case EncounterTrade t: return(t.Ability);

            default: return(-1);
            }
        }
Exemplo n.º 25
0
 private static GBEncounterPriority GetGBEncounterPriority(PKM pkm, IEncounterable Encounter)
 {
     return(Encounter switch
     {
         EncounterTrade1 t1 when t1.IsMatchDeferred(pkm) => GBEncounterPriority.Least,
         EncounterTrade1 _ => GBEncounterPriority.TradeEncounterG1,
         EncounterTrade2 _ => GBEncounterPriority.TradeEncounterG2,
         EncounterStatic _ => GBEncounterPriority.StaticEncounter,
         EncounterSlot _ => GBEncounterPriority.WildEncounter,
         _ => GBEncounterPriority.EggEncounter
     });
Exemplo n.º 26
0
        internal static EvoCriteria[][] GetEvolutionChainsAllGens(PKM pkm, IEncounterable Encounter)
        {
            var CompleteEvoChain = GetEvolutionChain(pkm, Encounter, pkm.Species, pkm.CurrentLevel);

            if (Encounter is EncounterInvalid || pkm.IsEgg)
            {
                return(GetChainSingle(pkm, CompleteEvoChain));
            }

            return(GetChainAll(pkm, Encounter, CompleteEvoChain));
        }
Exemplo n.º 27
0
        private static int[] GetSpecialMoves(IEncounterable EncounterMatch)
        {
            switch (EncounterMatch)
            {
            case IMoveset mg:
                return(mg.Moves ?? new int[0]);

            case EncounterSlot s when s.Type == SlotType.Swarm && (s.Species == 273 || s.Species == 274):
                return(new[] { 73 });  // Leech Seed for RSE Swarm (Seedot || Nuzleaf); only matches for RSE origin encounters.
            }
            return(new int[0]);
        }
Exemplo n.º 28
0
        public IEnumerable <CheckResult> VerifyVCEncounter(PKM pkm, IEncounterable encounter, ILocation transfer, IList <CheckMoveResult> Moves)
        {
            // Check existing EncounterMatch
            if (encounter is EncounterInvalid || transfer == null)
            {
                yield break; // Avoid duplicate invaild message
            }
            if (encounter is EncounterStatic v && (GameVersion.GBCartEraOnly.Contains(v.Version) || v.Version == GameVersion.VCEvents))
            {
                bool exceptions = false;
                exceptions |= v.Version == GameVersion.VCEvents && encounter.Species == 151 && pkm.TID == 22796;
                if (!exceptions)
                {
                    yield return(GetInvalid(LG1GBEncounter));
                }
            }

            if (pkm.Met_Location != transfer.Location)
            {
                yield return(GetInvalid(LTransferMetLocation));
            }
            if (pkm.Egg_Location != transfer.EggLocation)
            {
                yield return(GetInvalid(LEggLocationNone));
            }

            // Flag Moves that cannot be transferred
            if (encounter is EncounterStatic s && s.Version == GameVersion.C && s.EggLocation == 256) // Dizzy Punch Gifts
            {
                FlagIncompatibleTransferMove(pkm, Moves, 146, 2);                                     // can't have Dizzy Punch at all
            }
            bool checkShiny = pkm.VC2 || (pkm.TradebackStatus == TradebackType.WasTradeback && pkm.VC1);

            if (!checkShiny)
            {
                yield break;
            }

            if (pkm.Gender == 1)                                  // female
            {
                if (pkm.PersonalInfo.Gender == 31 && pkm.IsShiny) // impossible gender-shiny
                {
                    yield return(GetInvalid(LEncStaticPIDShiny, CheckIdentifier.PID));
                }
            }
            else if (pkm.Species == 201)                                  // unown
            {
                if (pkm.AltForm != 8 && pkm.AltForm != 21 && pkm.IsShiny) // impossibly form-shiny (not I or V)
                {
                    yield return(GetInvalid(LEncStaticPIDShiny, CheckIdentifier.PID));
                }
            }
        }
Exemplo n.º 29
0
        public ValidEncounterMoves(PKM pkm, LevelUpRestriction restrict, IEncounterable encounter)
        {
            var level = MoveList.GetValidMovesAllGens(pkm, restrict.EvolutionChains, minLvLG1: restrict.MinimumLevelGen1, minLvLG2: restrict.MinimumLevelGen2, Tutor: false, Machine: false, RemoveTransferHM: false);

            if (level[encounter.Generation] is List <int> x)
            {
                AddEdgeCaseMoves(x, encounter, pkm);
            }

            LevelUpMoves = level;
            TMHMMoves    = MoveList.GetValidMovesAllGens(pkm, restrict.EvolutionChains, LVL: false, Tutor: false, MoveReminder: false, RemoveTransferHM: false);
            TutorMoves   = MoveList.GetValidMovesAllGens(pkm, restrict.EvolutionChains, LVL: false, Machine: false, MoveReminder: false, RemoveTransferHM: false);
        }
Exemplo n.º 30
0
        /// <summary>
        /// Checks if the encounter is even valid before processing it
        /// </summary>
        /// <param name="set">showdown set</param>
        /// <param name="enc">encounter object</param>
        /// <param name="isHidden">is HA requested</param>
        /// <param name="destVer">version to generate in</param>
        /// <param name="ver">version of enc/destVer</param>
        /// <returns>if the encounter is valid or not</returns>
        private static bool IsEncounterValid(IBattleTemplate set, IEncounterable enc, bool isHidden, GameVersion destVer, out GameVersion ver)
        {
            // Pokemon who are in games of generation >= 8 can change non HA to HA via a capsule and vice versa
            isHidden = isHidden && destVer.GetGeneration() < 8;

            // initialize out vars (not calculating here to save time)
            ver = GameVersion.Any;

            // Don't process if encounter min level is higher than requested level
            if (enc.LevelMin > set.Level)
            {
                var isRaid = enc is EncounterStatic8N || enc is EncounterStatic8NC || enc is EncounterStatic8ND || enc is EncounterStatic8U;
                if (!isRaid)
                {
                    return(false);
                }
            }

            // Don't process if Hidden Ability is requested and the PKM is from Gen 3 or Gen 4
            var gen = enc.Generation;

            if (isHidden && (uint)(gen - 3) < 2)  // Gen 3 and Gen 4
            {
                return(false);
            }

            // Don't process if requested PKM is Gigantamax but the Game is not SW/SH
            ver = enc is IVersion v ? v.Version : destVer;
            if (set.CanGigantamax && !GameVersion.SWSH.Contains(ver))
            {
                return(false);
            }

            // Don't process if Game is LGPE and requested PKM is not Kanto / Meltan / Melmetal
            // Don't process if Game is SWSH and requested PKM is not from the Galar Dex (Zukan8.DexLookup)
            if (GameVersion.GG.Contains(destVer))
            {
                return(set.Species <= 151 || set.Species == 808 || set.Species == 809);
            }
            if (GameVersion.SWSH.Contains(destVer))
            {
                return(((PersonalInfoSWSH)PersonalTable.SWSH.GetFormeEntry(set.Species, set.FormIndex)).IsPresentInGame || SimpleEdits.Zukan8Additions.Contains(set.Species));
            }
            if (set.Species > destVer.GetMaxSpeciesID())
            {
                return(false);
            }

            // Encounter should hopefully be possible
            return(true);
        }