/// <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="ShowdownSet"/>.</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 satisfactory, otherwise use current auto legality functionality</param> public static PKM GetLegalFromTemplate(this ITrainerInfo dest, PKM template, ShowdownSet set, out bool satisfied) { var Form = SanityCheckForm(template, ref set); template.ApplySetDetails(set); var destType = template.GetType(); var destVer = (GameVersion)dest.Game; if (destVer <= 0 && dest is SaveFile s) { destVer = s.Version; } var encounters = EncounterMovesetGenerator.GenerateEncounters(pk: template, moves: set.Moves); foreach (var enc in encounters) { var ver = enc is IVersion v ? v.Version : destVer; var gen = enc is IGeneration g ? g.Generation : dest.Generation; var tr = TrainerSettings.GetSavedTrainerData(ver, gen); var raw = enc.ConvertToPKM(tr); var pk = PKMConverter.ConvertToType(raw, destType, out _); ApplySetDetails(pk, set, Form, raw, dest); var la = new LegalityAnalysis(pk); if (la.Valid) { satisfied = true; return(pk); } Debug.WriteLine(la.Report()); } satisfied = false; return(template); }
/// <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="ShowdownSet"/>.</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 satisfactory, otherwise use deprecated bruteforce auto legality functionality</param> public static PKM GetLegalFromTemplate(this ITrainerInfo dest, PKM template, ShowdownSet set, out bool satisfied) { set = set.PreProcessShowdownSet(); var Form = SanityCheckForm(template, ref set); template.ApplySetDetails(set); template.SetRecordFlags(); // Validate TR moves for the encounter 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(); EncounterMovesetGenerator.PriorityList = new[] { EncounterOrder.Egg, EncounterOrder.Static, EncounterOrder.Trade, EncounterOrder.Slot, EncounterOrder.Mystery }; var encounters = EncounterMovesetGenerator.GenerateEncounters(pk: template, moves: set.Moves, gamelist); if (template.Species <= 721) { encounters = encounters.Concat(GetFriendSafariEncounters(template)); } foreach (var enc in encounters) { var ver = enc is IVersion v ? v.Version : destVer; var gen = enc is IGeneration g ? g.Generation : dest.Generation; var tr = UseTrainerData ? TrainerSettings.GetSavedTrainerData(ver, gen) : TrainerSettings.DefaultFallback(gen); var raw = SanityCheckEncounters(enc).ConvertToPKM(tr); if (raw.IsEgg) // PGF events are sometimes eggs. Force hatch them before proceeding { raw.HandleEggEncounters(enc, tr); } var pk = PKMConverter.ConvertToType(raw, destType, out _); if (pk == null) { continue; } ApplySetDetails(pk, set, Form, raw, dest, enc); if (set.CanGigantamax && pk is IGigantamax gmax) { if (!gmax.CanGigantamax) { continue; } } var la = new LegalityAnalysis(pk); if (la.Valid) { satisfied = true; return(pk); } Debug.WriteLine(la.Report()); } satisfied = false; return(template); }
/// <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 satisfactory, otherwise use deprecated bruteforce auto legality functionality</param> public static PKM GetLegalFromTemplate(this ITrainerInfo dest, PKM template, IBattleTemplate set, out bool satisfied) { if (set is RegenTemplate t) { t.FixGender(template.PersonalInfo); } 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(); var encounters = EncounterMovesetGenerator.GenerateEncounters(pk: template, moves: set.Moves, gamelist); encounters = encounters.Concat(GetFriendSafariEncounters(template)); foreach (var enc in encounters) { if (!IsEncounterValid(set, enc, isHidden, destVer, out var ver)) { continue; } var tr = UseTrainerData ? TrainerSettings.GetSavedTrainerData(ver, enc.Generation) : TrainerSettings.DefaultFallback(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); } var pk = PKMConverter.ConvertToType(raw, destType, out _); if (pk == null) { continue; } ApplySetDetails(pk, set, raw, dest, enc); if (pk is IGigantamax gmax && gmax.CanGigantamax != set.CanGigantamax) { continue; } var la = new LegalityAnalysis(pk); if (la.Valid) { satisfied = true; return(pk); } Debug.WriteLine($"{la.Report()}\n"); } satisfied = false; return(template); }
/// <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="ShowdownSet"/>.</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 satisfactory, otherwise use deprecated bruteforce auto legality functionality</param> public static PKM GetLegalFromTemplate(this ITrainerInfo dest, PKM template, ShowdownSet set, out bool satisfied) { var Form = SanityCheckForm(template, ref set); template.ApplySetDetails(set); template.SetRecordFlags(); // Validate TR moves for the encounter 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(); var encounters = EncounterMovesetGenerator.GenerateEncounters(pk: template, moves: set.Moves, gamelist); foreach (var enc in encounters) { var ver = enc is IVersion v ? v.Version : destVer; var gen = enc is IGeneration g ? g.Generation : dest.Generation; ITrainerInfo tr = new SimpleTrainerInfo(ver); if (UseTrainerData) { tr = TrainerSettings.GetSavedTrainerData(ver, gen, new SimpleTrainerInfo(ver)); } var raw = SanityCheckEncounters(enc).ConvertToPKM(tr); var pk = PKMConverter.ConvertToType(raw, destType, out _); if (pk == null) { continue; } ApplySetDetails(pk, set, Form, raw, dest, enc); if (set.CanGigantamax && pk is IGigantamax gmax) { if (!gmax.CanGigantamax) { continue; } } var la = new LegalityAnalysis(pk); if (la.Valid) { satisfied = true; return(pk); } Debug.WriteLine(la.Report()); } satisfied = false; return(template); }
/// <summary> /// Main function that auto legalizes based on the legality /// </summary> /// <param name="roughPK">rough pkm that has all the SSet values entered</param> /// <param name="SSet">Showdown set object</param> /// <param name="satisfied">If the final result is satisfactory, otherwise use current auto legality functionality</param> /// <returns></returns> public static PKM APILegality(PKM roughPK, ShowdownSet SSet, out bool satisfied) { bool changedForm = false; if (SSet.Form != null) { changedForm = FixFormes(SSet, out SSet); } satisfied = false; // true when all features of the PKM are satisfied int Form = roughPK.AltForm; if (changedForm) { Form = SSet.FormIndex; roughPK.ApplySetDetails(SSet); } int HPType = roughPK.HPType; // List of candidate PKM files int[] moves = SSet.Moves; var f = GeneratePKMs(roughPK, SAV, moves); foreach (PKM pkmn in f) { if (pkmn != null) { PKM pk = PKMConverter.ConvertToType(pkmn, SAV.PKMType, out _); // All Possible PKM files LegalInfo info = new LegalInfo(pk); var pidiv = info.PIDIV ?? MethodFinder.Analyze(pk); PIDType Method = PIDType.None; if (pidiv != null) { Method = pidiv.Type; } SetVersion(pk, pkmn); // PreEmptive Version setting SetSpeciesLevel(pk, SSet, Form); SetMovesEVsItems(pk, SSet); SetTrainerDataAndMemories(pk); SetNatureAbility(pk, SSet); SetIVsPID(pk, SSet, Method, HPType, pkmn); PrintLegality(pk); ColosseumFixes(pk); pk.SetSuggestedHyperTrainingData(pk.IVs); // Hypertrain SetEncryptionConstant(pk); SetShinyBoolean(pk, SSet.Shiny); CheckAndSetFateful(pk); FixGender(pk, SSet); FixRibbons(pk); FixMemoriesPKM(pk); SetSpeciesBall(pk); SetHappiness(pk); LegalityAnalysis la = new LegalityAnalysis(pk); if (la.Valid) { satisfied = true; } if (satisfied) { return(pk); } else { Console.WriteLine(la.Report()); } } } return(roughPK); }
/// <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); }
/// <summary> /// Function that generates legal PKM objects from ShowdownSets and views them/sets them in boxes /// </summary> /// <param name="sets">A list of ShowdownSet(s) that need to be genned</param> /// <param name="replace">A boolean that determines if current pokemon will be replaced or not</param> /// <param name="message">Output message to be displayed for the user</param> /// <param name="allowAPI">Use of generators before bruteforcing</param> private static void ImportSets(List <ShowdownSet> sets, bool replace, out string message, bool allowAPI = true) { message = "[DEBUG] Commencing Import"; List <int> emptySlots = new List <int> { }; IList <PKM> BoxData = C_SAV.SAV.BoxData; int BoxOffset = C_SAV.CurrentBox * C_SAV.SAV.BoxSlotCount; if (replace) { emptySlots = Enumerable.Range(0, sets.Count).ToList(); } else { emptySlots = PopulateEmptySlots(BoxData, C_SAV.CurrentBox); } if (emptySlots.Count < sets.Count && sets.Count != 1) { message = "Not enough space in the box"; return; } int apiCounter = 0; List <ShowdownSet> invalidAPISets = new List <ShowdownSet>(); for (int i = 0; i < sets.Count; i++) { ShowdownSet Set = sets[i]; if (sets.Count == 1 && DialogResult.Yes != PKHeX.WinForms.WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Import this set?", Set.Text)) { return; } if (Set.InvalidLines.Count > 0) { PKHeX.WinForms.WinFormsUtil.Alert("Invalid lines detected:", string.Join(Environment.NewLine, Set.InvalidLines)); } bool resetForm = false; if (Set.Form != null && (Set.Form.Contains("Mega") || Set.Form == "Primal" || Set.Form == "Busted")) { resetForm = true; } PKM roughPKM = C_SAV.SAV.BlankPKM; roughPKM.ApplySetDetails(Set); roughPKM.Version = (int)GameVersion.MN; // Avoid the blank version glitch PKM legal = C_SAV.SAV.BlankPKM; bool satisfied = false; if (allowAPI) { PKM APIGeneratedPKM = C_SAV.SAV.BlankPKM; try { APIGeneratedPKM = AutoLegalityMod.APILegality(roughPKM, Set, out satisfied); } catch { satisfied = false; } if (satisfied) { legal = APIGeneratedPKM; apiCounter++; APILegalized = true; } } if (!allowAPI || !satisfied) { invalidAPISets.Add(Set); Blah b = new Blah { SAV = C_SAV.SAV }; legal = b.LoadShowdownSetModded_PKSM(roughPKM, Set, resetForm, TID_ALM, SID_ALM, OT_ALM, gender_ALM); APILegalized = false; } PKM pk = SetTrainerData(legal, sets.Count == 1); if (sets.Count > 1) { BoxData[BoxOffset + emptySlots[i]] = pk; } } if (sets.Count > 1) { C_SAV.SAV.BoxData = BoxData; C_SAV.ReloadSlots(); message = "[DEBUG] API Genned Sets: " + apiCounter + Environment.NewLine + Environment.NewLine + "Number of sets not genned by the API: " + invalidAPISets.Count; foreach (ShowdownSet i in invalidAPISets) { Debug.WriteLine(i.Text); } } else { message = "[DEBUG] Set Genning Complete"; } }
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 }))
/// <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); }
/// <summary> /// Creates <see cref="PKM"/> from the showdownsets and checks compatibility with the savefile. /// </summary> /// <remarks>REMEMBER: Many moves was removed in the 8th gen, so some showdownsets will eventually be incompatible with your savefile.</remarks> public void CreatePkM() { if (SAV == null) { Console.WriteLine("No savefile loaded yet."); return; } if (showdownSets.Count == 0) { Console.WriteLine("No showdown set loaded."); return; } foreach (ShowdownSet set in showdownSets) { PKM pkm = SAV.BlankPKM; string speciesname = SpeciesName.GetSpeciesName(set.Species, 2); Console.WriteLine("Creating " + speciesname); if (Breeding.CanHatchAsEgg(set.Species)) { EncounterEgg egg = new EncounterEgg(set.Species, set.Form, set.Level, SAV.Generation, game); pkm = egg.ConvertToPKM(SAV); } else { pkm.Species = set.Species; pkm.Form = set.Form; pkm.SetGender(pkm.GetSaneGender()); IEncounterable[] encs = EncounterMovesetGenerator.GenerateEncounter(pkm, SAV.Generation).ToArray(); if (encs.Length == 0) { // use debut generation for Pokemon that available but not catchable in current generation e.g. Meltan encs = EncounterMovesetGenerator.GenerateEncounter(pkm, pkm.DebutGeneration).ToArray(); } foreach (IEncounterable enc in encs) { PKM pk = enc.ConvertToPKM(SAV); // not all Pokemon in database are legal in all games if (new LegalityAnalysis(pk, SAV.Personal).Valid) { pkm = PKMConverter.ConvertToType(pk, SAV.PKMType, out _); if ((pk.Generation != SAV.Generation || pk.GO || pk.GO_HOME || pk.LGPE) && pkm is IBattleVersion b) { b.BattleVersion = (int)game; } break; } } } pkm.Language = SAV.Language; pkm.ApplySetDetails(set); LegalityAnalysis la = new LegalityAnalysis(pkm, SAV.Personal); string report = la.Report(); if (report == "Legal!") { ENTITIES.Add(pkm); IsValid.Add(true); } else { // setting blank pkm if invalid for better indexing ENTITIES.Add(SAV.BlankPKM); IsValid.Add(false); Console.WriteLine("Warning: " + speciesname + " is invalid!"); Console.WriteLine(report); Console.WriteLine("Ignoring " + speciesname); } } }