Ejemplo n.º 1
0
    /// <summary>
    /// Tries to modify the <see cref="PKM"/>.
    /// </summary>
    /// <param name="pk">Object to modify.</param>
    /// <param name="filters">Filters which must be satisfied prior to any modifications being made.</param>
    /// <param name="modifications">Modifications to perform on the <see cref="pk"/>.</param>
    /// <returns>Result of the attempted modification.</returns>
    public bool Process(PKM pk, IEnumerable <StringInstruction> filters, IEnumerable <StringInstruction> modifications)
    {
        if (pk.Species <= 0)
        {
            return(false);
        }
        if (!pk.Valid)
        {
            Iterated++;
            const string reason = "Not Valid.";
            Debug.WriteLine($"{MsgBEModifyFailBlocked} {reason}");
            return(false);
        }

        var result = BatchEditing.TryModifyPKM(pk, filters, modifications);

        if (result != ModifyResult.Invalid)
        {
            Iterated++;
        }
        if (result == ModifyResult.Error)
        {
            Failed++;
        }
        if (result != ModifyResult.Modified)
        {
            return(false);
        }

        pk.RefreshChecksum();
        Modified++;
        return(true);
    }
Ejemplo n.º 2
0
        private void RunBackgroundWorker()
        {
            if (RTB_Instructions.Lines.Any(line => line.Length == 0))
            {
                WinFormsUtil.Error(MsgBEInstructionInvalid); return;
            }

            var sets = StringInstructionSet.GetBatchSets(RTB_Instructions.Lines).ToArray();

            if (sets.Any(s => s.Filters.Any(z => string.IsNullOrWhiteSpace(z.PropertyValue))))
            {
                WinFormsUtil.Error(MsgBEFilterEmpty); return;
            }

            if (sets.Any(z => z.Instructions.Count == 0))
            {
                WinFormsUtil.Error(MsgBEInstructionNone); return;
            }

            var emptyVal = sets.SelectMany(s => s.Instructions.Where(z => string.IsNullOrWhiteSpace(z.PropertyValue))).ToArray();

            if (emptyVal.Length > 0)
            {
                string props   = string.Join(", ", emptyVal.Select(z => z.PropertyName));
                string invalid = MsgBEPropertyEmpty + Environment.NewLine + props;
                if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, invalid, MsgContinue))
                {
                    return;
                }
            }

            string?destPath = null;

            if (RB_Path.Checked)
            {
                WinFormsUtil.Alert(MsgExportFolder, MsgExportFolderAdvice);
                using var fbd = new FolderBrowserDialog();
                var dr = fbd.ShowDialog();
                if (dr != DialogResult.OK)
                {
                    return;
                }

                destPath = fbd.SelectedPath;
            }

            FLP_RB.Enabled = RTB_Instructions.Enabled = B_Go.Enabled = false;

            foreach (var set in sets)
            {
                BatchEditing.ScreenStrings(set.Filters);
                BatchEditing.ScreenStrings(set.Instructions);
            }
            RunBatchEdit(sets, TB_Folder.Text, destPath);
        }
Ejemplo n.º 3
0
        public static IEnumerable <PKM> FilterByBatchInstruction(IEnumerable <PKM> res, IList <string> BatchInstructions)
        {
            if (BatchInstructions?.All(string.IsNullOrWhiteSpace) != false)
            {
                return(res); // none specified;
            }
            var lines   = BatchInstructions.Where(z => !string.IsNullOrWhiteSpace(z));
            var filters = StringInstruction.GetFilters(lines).ToArray();

            BatchEditing.ScreenStrings(filters);
            return(res.Where(pkm => BatchEditing.IsFilterMatch(filters, pkm))); // Compare across all filters
        }
Ejemplo n.º 4
0
        public async Task GetBatchInfo(string propertyName)
        {
            var result = BatchEditing.GetPropertyType(propertyName);

            if (string.IsNullOrWhiteSpace(result))
            {
                await ReplyAsync($"Unable to find info for {propertyName}.").ConfigureAwait(false);
            }
            else
            {
                await ReplyAsync($"{propertyName}: {result}").ConfigureAwait(false);
            }
        }
Ejemplo n.º 5
0
 private void CB_Property_SelectedIndexChanged(object sender, EventArgs e)
 {
     L_PropType.Text = BatchEditing.GetPropertyType(CB_Property.Text, CB_Format.SelectedIndex);
     if (BatchEditing.TryGetHasProperty(pkm, CB_Property.Text, out var pi))
     {
         L_PropValue.Text     = pi.GetValue(pkm)?.ToString();
         L_PropType.ForeColor = L_PropValue.ForeColor; // reset color
     }
     else // no property, flag
     {
         L_PropValue.Text     = string.Empty;
         L_PropType.ForeColor = Color.Red;
     }
 }
Ejemplo n.º 6
0
        public static IEnumerable <StringInstruction>?GetEncounterFilters(IEnumerable <string> lines)
        {
            var valid = lines.Where(z => z.StartsWith(EncounterFilterPrefix.ToString())).ToList();

            if (valid.Count == 0)
            {
                return(null);
            }
            var cleaned = valid.Select(z => z.TrimStart(EncounterFilterPrefix));
            var filters = StringInstruction.GetFilters(cleaned).ToArray();

            BatchEditing.ScreenStrings(filters);
            return(filters);
        }
Ejemplo n.º 7
0
        private static bool IsValidInstructionSet(List <string> split, out List <StringInstruction> invalid)
        {
            invalid = new List <StringInstruction>();
            var set = new StringInstructionSet(split);

            foreach (var s in set.Filters.Concat(set.Instructions))
            {
                var type = BatchEditing.GetPropertyType(s.PropertyName);
                if (type == null)
                {
                    invalid.Add(s);
                }
            }

            return(invalid.Count == 0);
        }
Ejemplo n.º 8
0
        // View Updates
        private IEnumerable <PKM> SearchDatabase()
        {
            // Populate Search Query Result
            IEnumerable <PKM> res = RawDB;

            // Filter for Selected Source
            if (!Menu_SearchBoxes.Checked)
            {
                res = res.Where(pk => pk.Identifier.StartsWith(DatabasePath + Path.DirectorySeparatorChar, StringComparison.Ordinal));
            }
            if (!Menu_SearchDatabase.Checked)
            {
                res = res.Where(pk => !pk.Identifier.StartsWith(DatabasePath + Path.DirectorySeparatorChar, StringComparison.Ordinal));
#if LOADALL
                res = res.Where(pk => !pk.Identifier.StartsWith(EXTERNAL_SAV, StringComparison.Ordinal));
#endif
            }

            int format = MAXFORMAT + 1 - CB_Format.SelectedIndex;
            switch (CB_FormatComparator.SelectedIndex)
            {
            case 0: /* Do nothing */ break;

            case 1: res = res.Where(pk => pk.Format >= format); break;

            case 2: res = res.Where(pk => pk.Format == format); break;

            case 3: res = res.Where(pk => pk.Format <= format); break;
            }
            if (CB_FormatComparator.SelectedIndex != 0)
            {
                if (format <= 2) // 1-2
                {
                    res = res.Where(pk => pk.Format <= 2);
                }
                if (format >= 3 && format <= 6) // 3-6
                {
                    res = res.Where(pk => pk.Format >= 3);
                }
            }

            switch (CB_Generation.SelectedIndex)
            {
            case 0: /* Do nothing */ break;

            case 1: res = res.Where(pk => pk.Gen7); break;

            case 2: res = res.Where(pk => pk.Gen6); break;

            case 3: res = res.Where(pk => pk.Gen5); break;

            case 4: res = res.Where(pk => pk.Gen4); break;

            case 5: res = res.Where(pk => pk.Gen3); break;
            }

            // Primary Searchables
            int species = WinFormsUtil.GetIndex(CB_Species);
            int ability = WinFormsUtil.GetIndex(CB_Ability);
            int nature  = WinFormsUtil.GetIndex(CB_Nature);
            int item    = WinFormsUtil.GetIndex(CB_HeldItem);
            if (species != -1)
            {
                res = res.Where(pk => pk.Species == species);
            }
            if (ability != -1)
            {
                res = res.Where(pk => pk.Ability == ability);
            }
            if (nature != -1)
            {
                res = res.Where(pk => pk.Nature == nature);
            }
            if (item != -1)
            {
                res = res.Where(pk => pk.HeldItem == item);
            }

            // Secondary Searchables
            int move1 = WinFormsUtil.GetIndex(CB_Move1);
            int move2 = WinFormsUtil.GetIndex(CB_Move2);
            int move3 = WinFormsUtil.GetIndex(CB_Move3);
            int move4 = WinFormsUtil.GetIndex(CB_Move4);
            var moves = new[] { move1, move2, move3, move4 }.Where(z => z > 0).ToList();
            int count = moves.Count;
            if (count > 0)
            {
                res = res.Where(pk => pk.Moves.Intersect(moves).Count() == count);
            }
            int vers = WinFormsUtil.GetIndex(CB_GameOrigin);
            if (vers != -1)
            {
                res = res.Where(pk => pk.Version == vers);
            }
            int hptype = WinFormsUtil.GetIndex(CB_HPType);
            if (hptype != -1)
            {
                res = res.Where(pk => pk.HPType == hptype);
            }
            if (CHK_Shiny.CheckState == CheckState.Checked)
            {
                res = res.Where(pk => pk.IsShiny);
            }
            if (CHK_Shiny.CheckState == CheckState.Unchecked)
            {
                res = res.Where(pk => !pk.IsShiny);
            }
            if (CHK_IsEgg.CheckState == CheckState.Checked)
            {
                res = res.Where(pk => pk.IsEgg);
            }
            if (CHK_IsEgg.CheckState == CheckState.Unchecked)
            {
                res = res.Where(pk => !pk.IsEgg);
            }
            if (CHK_IsEgg.CheckState == CheckState.Checked && int.TryParse(MT_ESV.Text, out int esv))
            {
                res = res.Where(pk => pk.PSV == esv);
            }

            // Tertiary Searchables
            res = FilterByLVL(res, CB_Level.SelectedIndex, TB_Level.Text);
            res = FilterByIVs(res, CB_IV.SelectedIndex);
            res = FilterByEVs(res, CB_EVTrain.SelectedIndex);

            slotSelected = -1; // reset the slot last viewed

            if (Menu_SearchLegal.Checked && !Menu_SearchIllegal.Checked)
            {
                res = res.Where(pk => new LegalityAnalysis(pk).Valid);
            }
            if (!Menu_SearchLegal.Checked && Menu_SearchIllegal.Checked)
            {
                res = res.Where(pk => !new LegalityAnalysis(pk).Valid);
            }

            if (RTB_Instructions.Lines.Any(line => line.Length > 0))
            {
                var filters = StringInstruction.GetFilters(RTB_Instructions.Lines).ToArray();
                BatchEditing.ScreenStrings(filters);
                res = res.Where(pkm => BatchEditing.IsFiltered(filters, pkm)); // Compare across all filters
            }

            if (Menu_SearchClones.Checked)
            {
                res = res.GroupBy(Hash).Where(group => group.Count() > 1).SelectMany(z => z);
            }

            return(res);
        }
Ejemplo n.º 9
0
        // View Updates
        private void B_Search_Click(object sender, EventArgs e)
        {
            // Populate Search Query Result
            IEnumerable <MysteryGift> res = RawDB;

            int format = MAXFORMAT + 1 - CB_Format.SelectedIndex;

            switch (CB_FormatComparator.SelectedIndex)
            {
            case 0: /* Do nothing */ break;

            case 1: res = res.Where(mg => mg.Format >= format); break;

            case 2: res = res.Where(mg => mg.Format == format); break;

            case 3: res = res.Where(mg => mg.Format <= format); break;
            }

            // Primary Searchables
            int species = WinFormsUtil.GetIndex(CB_Species);
            int item    = WinFormsUtil.GetIndex(CB_HeldItem);

            if (species != -1)
            {
                res = res.Where(pk => pk.Species == species);
            }
            if (item != -1)
            {
                res = res.Where(pk => pk.HeldItem == item);
            }

            // Secondary Searchables
            int move1 = WinFormsUtil.GetIndex(CB_Move1);
            int move2 = WinFormsUtil.GetIndex(CB_Move2);
            int move3 = WinFormsUtil.GetIndex(CB_Move3);
            int move4 = WinFormsUtil.GetIndex(CB_Move4);

            if (move1 != -1)
            {
                res = res.Where(mg => mg.HasMove(move1));
            }
            if (move2 != -1)
            {
                res = res.Where(mg => mg.HasMove(move2));
            }
            if (move3 != -1)
            {
                res = res.Where(mg => mg.HasMove(move3));
            }
            if (move4 != -1)
            {
                res = res.Where(mg => mg.HasMove(move4));
            }
            if (CHK_Shiny.CheckState == CheckState.Checked)
            {
                res = res.Where(pk => pk.IsShiny);
            }
            if (CHK_Shiny.CheckState == CheckState.Unchecked)
            {
                res = res.Where(pk => !pk.IsShiny);
            }
            if (CHK_IsEgg.CheckState == CheckState.Checked)
            {
                res = res.Where(pk => pk.IsEgg);
            }
            if (CHK_IsEgg.CheckState == CheckState.Unchecked)
            {
                res = res.Where(pk => !pk.IsEgg);
            }

            slotSelected = -1; // reset the slot last viewed

            if (RTB_Instructions.Lines.Any(line => line.Length > 0))
            {
                var filters = StringInstruction.GetFilters(RTB_Instructions.Lines).ToArray();
                BatchEditing.ScreenStrings(filters);
                res = res.Where(pkm => BatchEditing.IsFilterMatch(filters, pkm)); // Compare across all filters
            }

            var results = res.ToArray();

            if (results.Length == 0)
            {
                WinFormsUtil.Alert(MsgDBSearchNone);
            }

            SetResults(new List <MysteryGift>(results)); // updates Count Label as well.
            System.Media.SystemSounds.Asterisk.Play();
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Main function that auto legalizes based on the legality
        /// </summary>
        /// <remarks>Leverages <see cref="Core"/>'s <see cref="EncounterMovesetGenerator"/> to create a <see cref="PKM"/> from a <see cref="IBattleTemplate"/>.</remarks>
        /// <param name="dest">Destination for the generated pkm</param>
        /// <param name="template">rough pkm that has all the <see cref="set"/> values entered</param>
        /// <param name="set">Showdown set object</param>
        /// <param name="satisfied">If the final result is legal or not</param>
        public static PKM GetLegalFromTemplate(this ITrainerInfo dest, PKM template, IBattleTemplate set, out bool satisfied)
        {
            RegenSet regen;

            if (set is RegenTemplate t)
            {
                t.FixGender(template.PersonalInfo);
                regen = t.Regen;
            }
            else
            {
                regen = RegenSet.Default;
            }

            template.ApplySetDetails(set);
            template.SetRecordFlags(); // Validate TR moves for the encounter
            var isHidden = template.AbilityNumber == 4;
            var destType = template.GetType();
            var destVer  = (GameVersion)dest.Game;

            if (destVer <= 0 && dest is SaveFile s)
            {
                destVer = s.Version;
            }

            var gamelist = GameUtil.GetVersionsWithinRange(template, template.Format).OrderByDescending(c => c.GetGeneration()).ToArray();

            if (PrioritizeGame)
            {
                gamelist = PrioritizeGameVersion == GameVersion.Any ? PrioritizeVersion(gamelist, destVer) : PrioritizeVersion(gamelist, PrioritizeGameVersion);
            }

            var encounters = EncounterMovesetGenerator.GenerateEncounters(pk: template, moves: set.Moves, gamelist);

            foreach (var enc in encounters)
            {
                // Look before we leap -- don't waste time generating invalid / incompatible junk.
                if (!IsEncounterValid(set, enc, isHidden, destVer, out var ver))
                {
                    continue;
                }

                // Create the PKM from the template.
                var tr  = GetTrainer(regen, ver, enc.Generation);
                var raw = SanityCheckEncounters(enc).ConvertToPKM(tr);
                if (raw.IsEgg) // PGF events are sometimes eggs. Force hatch them before proceeding
                {
                    raw.HandleEggEncounters(enc, tr);
                }

                // Bring to the target generation, then apply final details.
                var pk = PKMConverter.ConvertToType(raw, destType, out _);
                if (pk == null)
                {
                    continue;
                }
                ApplySetDetails(pk, set, raw, dest, enc, regen);

                // Apply final tweaks to the data.
                if (pk is IGigantamax gmax && gmax.CanGigantamax != set.CanGigantamax)
                {
                    if (!gmax.CanToggleGigantamax(pk.Species, enc.Species))
                    {
                        continue;
                    }
                    gmax.CanGigantamax = set.CanGigantamax; // soup hax
                }

                // Try applying batch editor values.
                if (AllowBatchCommands && regen.HasBatchSettings)
                {
                    pk.RefreshChecksum();
                    var b = regen.Batch;
                    if (!BatchEditing.TryModify(pk, b.Filters, b.Instructions))
                    {
                        continue;
                    }
                }

                if (pk is PK1 pk1 && ParseSettings.AllowGen1Tradeback)
                {
                    pk1.Catch_Rate = pk1.Gen2Item; // Simulate a gen 2 trade/tradeback to allow tradeback moves
                }
                // Verify the Legality of what we generated, and exit if it is valid.
                var la = new LegalityAnalysis(pk);
                if (la.Valid)
                {
                    satisfied = true;
                    return(pk);
                }
                Debug.WriteLine($"{la.Report()}\n");
            }
            satisfied = false;
            return(template);
        }
        public static string SetAnalysis(this IBattleTemplate set, ITrainerInfo sav, PKM blank)
        {
            if (blank.Version == 0)
            {
                blank.Version = sav.Game;
            }
            var species_name = SpeciesName.GetSpeciesNameGeneration(set.Species, (int)LanguageID.English, sav.Generation);
            var analysis     = set.Form == 0 ? string.Format(SPECIES_UNAVAILABLE, species_name)
                                     : string.Format(SPECIES_UNAVAILABLE_FORM, species_name, set.FormName);

            // Species checks
            var gv = (GameVersion)sav.Game;

            if (!gv.ExistsInGame(set.Species, set.Form))
            {
                return(analysis); // Species does not exist in the game
            }
            // Species exists -- check if it has at least one move.
            // If it has no moves and it didn't generate, that makes the mon still illegal in game (moves are set to legal ones)
            var moves = set.Moves.Where(z => z != 0).ToArray();
            var count = set.Moves.Count(z => z != 0);

            // Reusable data
            var batchedit = false;
            IReadOnlyList <StringInstruction>?filters = null;

            if (set is RegenTemplate r)
            {
                filters   = r.Regen.Batch.Filters;
                batchedit = APILegality.AllowBatchCommands && r.Regen.HasBatchSettings;
            }
            var destVer = (GameVersion)sav.Game;

            if (destVer <= 0 && sav is SaveFile s)
            {
                destVer = s.Version;
            }
            var gamelist = APILegality.FilteredGameList(blank, destVer, batchedit ? filters : null);

            // Move checks
            List <IEnumerable <int> > move_combinations = new();

            for (int i = count; i >= 1; i--)
            {
                move_combinations.AddRange(GetKCombs(moves, i));
            }

            int[] original_moves = new int[4];
            set.Moves.CopyTo(original_moves, 0);
            int[] successful_combination = GetValidMoves(set, sav, move_combinations, blank, gamelist);
            if (!new HashSet <int>(original_moves.Where(z => z != 0)).SetEquals(successful_combination))
            {
                var invalid_moves = string.Join(", ", original_moves.Where(z => !successful_combination.Contains(z) && z != 0).Select(z => $"{(Move)z}"));
                return(successful_combination.Length > 0 ? string.Format(INVALID_MOVES, species_name, invalid_moves) : ALL_MOVES_INVALID);
            }

            // All moves possible, get encounters
            blank.ApplySetDetails(set);
            blank.SetMoves(original_moves);
            blank.SetRecordFlags(Array.Empty <int>());

            var encounters   = EncounterMovesetGenerator.GenerateEncounters(pk: blank, moves: original_moves, gamelist).ToList();
            var initialcount = encounters.Count;

            if (set is RegenTemplate rt && rt.Regen.EncounterFilters is { } x)
            {
                encounters.RemoveAll(enc => !BatchEditing.IsFilterMatch(x, enc));
            }

            // No available encounters
            if (encounters.Count == 0)
            {
                return(string.Format(EXHAUSTED_ENCOUNTERS, initialcount, initialcount));
            }

            // Level checks, check if level is impossible to achieve
            if (encounters.All(z => !APILegality.IsRequestedLevelValid(set, z)))
            {
                return(string.Format(LEVEL_INVALID, species_name, encounters.Min(z => z.LevelMin)));
            }
            encounters.RemoveAll(enc => !APILegality.IsRequestedLevelValid(set, enc));

            // Shiny checks, check if shiny is impossible to achieve
            Shiny shinytype = set.Shiny ? Shiny.Always : Shiny.Never;

            if (set is RegenTemplate ret && ret.Regen.HasExtraSettings)
            {
                shinytype = ret.Regen.Extra.ShinyType;
            }
            if (encounters.All(z => !APILegality.IsRequestedShinyValid(set, z)))
            {
                return(string.Format(SHINY_INVALID, shinytype));
            }
            encounters.RemoveAll(enc => !APILegality.IsRequestedShinyValid(set, enc));

            // Alpha checks
            if (encounters.All(z => !APILegality.IsRequestedAlphaValid(set, z)))
            {
                return(ALPHA_INVALID);
            }
            encounters.RemoveAll(enc => !APILegality.IsRequestedAlphaValid(set, enc));

            // Ability checks
            var abilityreq = APILegality.GetRequestedAbility(blank, set);

            if (abilityreq == AbilityRequest.NotHidden && encounters.All(z => z is EncounterStatic {
                Ability: AbilityPermission.OnlyHidden
            }))
Ejemplo n.º 12
0
        /// <summary>
        /// Main function that auto legalizes based on the legality
        /// </summary>
        /// <remarks>Leverages <see cref="Core"/>'s <see cref="EncounterMovesetGenerator"/> to create a <see cref="PKM"/> from a <see cref="IBattleTemplate"/>.</remarks>
        /// <param name="dest">Destination for the generated pkm</param>
        /// <param name="template">rough pkm that has all the <see cref="set"/> values entered</param>
        /// <param name="set">Showdown set object</param>
        /// <param name="satisfied">If the final result is legal or not</param>
        public static PKM GetLegalFromTemplate(this ITrainerInfo dest, PKM template, IBattleTemplate set, out LegalizationResult satisfied)
        {
            RegenSet regen;

            if (set is RegenTemplate t)
            {
                t.FixGender(template.PersonalInfo);
                regen = t.Regen;
            }
            else
            {
                regen = RegenSet.Default;
            }

            template.ApplySetDetails(set);
            template.SetRecordFlags(); // Validate TR moves for the encounter
            var isHidden = template.AbilityNumber == 4;

            if (template.PersonalInfo.Abilities.Count > 2) // Hidden ability exists for the template
            {
                isHidden = isHidden || template.PersonalInfo.Abilities[2] == template.Ability;
            }
            var destType = template.GetType();
            var destVer  = (GameVersion)dest.Game;

            if (destVer <= 0 && dest is SaveFile s)
            {
                destVer = s.Version;
            }

            var timer    = Stopwatch.StartNew();
            var gamelist = FilteredGameList(template, destVer);

            var encounters = EncounterMovesetGenerator.GenerateEncounters(pk: template, moves: set.Moves, gamelist);
            var criteria   = EncounterCriteria.GetCriteria(set);

            foreach (var enc in encounters)
            {
                // Return out if set times out
                if (timer.Elapsed.TotalSeconds >= Timeout)
                {
                    timer.Stop();
                    satisfied = LegalizationResult.Timeout;
                    return(template);
                }

                // Look before we leap -- don't waste time generating invalid / incompatible junk.
                if (!IsEncounterValid(set, enc, isHidden, destVer))
                {
                    continue;
                }

                // Create the PKM from the template.
                var tr  = GetTrainer(regen, enc.Version, enc.Generation);
                var raw = enc.ConvertToPKM(tr, criteria);
                raw = raw.SanityCheckLocation(enc);
                if (raw.IsEgg) // PGF events are sometimes eggs. Force hatch them before proceeding
                {
                    raw.HandleEggEncounters(enc, tr);
                }

                raw.PreSetPIDIV(enc, set);

                // Transfer any VC1 via VC2, as there may be GSC exclusive moves requested.
                if (dest.Generation >= 7 && raw is PK1 basepk1)
                {
                    raw = basepk1.ConvertToPK2();
                }

                // Bring to the target generation, then apply final details.
                var pk = PKMConverter.ConvertToType(raw, destType, out _);
                if (pk == null)
                {
                    continue;
                }
                ApplySetDetails(pk, set, raw, dest, enc, regen);

                // Apply final tweaks to the data.
                if (pk is IGigantamax gmax && gmax.CanGigantamax != set.CanGigantamax)
                {
                    if (!gmax.CanToggleGigantamax(pk.Species, pk.Form, enc.Species, enc.Form))
                    {
                        continue;
                    }
                    gmax.CanGigantamax = set.CanGigantamax; // soup hax
                }

                // Try applying batch editor values.
                if (AllowBatchCommands && regen.HasBatchSettings)
                {
                    pk.RefreshChecksum();
                    var b = regen.Batch;
                    if (!BatchEditing.TryModify(pk, b.Filters, b.Instructions))
                    {
                        continue;
                    }
                }

                if (pk is PK1 pk1 && ParseSettings.AllowGen1Tradeback)
                {
                    pk1.Catch_Rate = pk1.Gen2Item; // Simulate a gen 2 trade/tradeback to allow tradeback moves
                }
                // Verify the Legality of what we generated, and exit if it is valid.
                var la = new LegalityAnalysis(pk);
                if (la.Valid)
                {
                    satisfied = LegalizationResult.Regenerated;
                    return(pk);
                }
                Debug.WriteLine($"{la.Report()}\n");
            }
            satisfied = LegalizationResult.Failed;
            return(template);
        }
Ejemplo n.º 13
0
        public static string SetAnalysis(this RegenTemplate set, SaveFile sav)
        {
            var species_name = SpeciesName.GetSpeciesNameGeneration(set.Species, (int)LanguageID.English, sav.Generation);
            var analysis     = set.Form == 0 ? string.Format(SPECIES_UNAVAILABLE, species_name)
                                     : string.Format(SPECIES_UNAVAILABLE_FORM, species_name, set.FormName);

            // Species checks
            var gv = (GameVersion)sav.Game;

            if (!gv.ExistsInGame(set.Species, set.Form))
            {
                return(analysis); // Species does not exist in the game
            }
            // Species exists -- check if it has atleast one move. If it has no moves and it didn't generate, that makes the mon still illegal in game (moves are set to legal ones)
            var moves = set.Moves.Where(z => z != 0);
            var count = moves.Count();

            // Reusable data
            var blank     = sav.BlankPKM;
            var batchedit = APILegality.AllowBatchCommands && set.Regen.HasBatchSettings;
            var destVer   = (GameVersion)sav.Game;

            if (destVer <= 0)
            {
                destVer = sav.Version;
            }
            var gamelist = APILegality.FilteredGameList(blank, destVer, batchedit ? set.Regen.Batch.Filters : null);

            // Move checks
            List <IEnumerable <int> > move_combinations = new();

            for (int i = count; i >= 1; i--)
            {
                move_combinations.AddRange(GetKCombs(moves, i));
            }

            int[] original_moves = new int[4];
            set.Moves.CopyTo(original_moves, 0);
            int[] successful_combination = GetValidMoves(set, sav, move_combinations, blank, gamelist);
            if (!new HashSet <int>(original_moves.Where(z => z != 0)).SetEquals(successful_combination))
            {
                var invalid_moves = string.Join(", ", original_moves.Where(z => !successful_combination.Contains(z) && z != 0).Select(z => $"{(Move)z}"));
                return(successful_combination.Length > 0 ? string.Format(INVALID_MOVES, species_name, invalid_moves) : ALL_MOVES_INVALID);
            }
            set.Moves = original_moves;

            // All moves possible, get encounters
            blank.ApplySetDetails(set);
            blank.SetRecordFlags();
            var encounters = EncounterMovesetGenerator.GenerateEncounters(pk: blank, moves: original_moves, gamelist);

            if (set.Regen.EncounterFilters != null)
            {
                encounters = encounters.Where(enc => BatchEditing.IsFilterMatch(set.Regen.EncounterFilters, enc));
            }

            // Level checks, check if level is impossible to achieve
            if (encounters.All(z => !APILegality.IsRequestedLevelValid(set, z)))
            {
                return(string.Format(LEVEL_INVALID, species_name, encounters.Min(z => z.LevelMin)));
            }
            encounters = encounters.Where(enc => APILegality.IsRequestedLevelValid(set, enc));

            // Ability checks
            var abilityreq = APILegality.GetRequestedAbility(blank, set);

            if (abilityreq == AbilityRequest.NotHidden && encounters.All(z => z is EncounterStatic {
                Ability: 4
            }))