/// <summary> /// Gets a legal <see cref="PKM"/> from a random in-game encounter's data. /// </summary> /// <param name="blank">Template data that will have its properties modified</param> /// <param name="tr">Trainer Data to use in generating the encounter</param> /// <param name="species">Species ID to generate</param> /// <returns>Result legal pkm, null if data should be ignored.</returns> private static PKM?GetRandomEncounter(PKM blank, ITrainerInfo tr, int species) { blank.Species = species; blank.Gender = blank.GetSaneGender(); if (species == (int)Species.Meowstic || species == (int)Species.Indeedee) { blank.AltForm = blank.Gender; } var legalencs = EncounterMovesetGenerator.GeneratePKMs(blank, tr).Where(z => new LegalityAnalysis(z).Valid); var f = legalencs.FirstOrDefault(); if (f == null) { return(null); } var an = f.AbilityNumber; f.Species = species; f.Gender = f.GetSaneGender(); if (species == (int)Species.Meowstic || species == (int)Species.Indeedee) { f.AltForm = f.Gender; } f.CurrentLevel = 100; f.Nickname = SpeciesName.GetSpeciesNameGeneration(f.Species, f.Language, f.Format); f.IsNicknamed = false; f.RefreshAbility(an >> 1); return(f); }
/// <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> /// Gets a legal <see cref="PKM"/> from a random in-game encounter's data. /// </summary> /// <param name="blank">Template data that will have its properties modified</param> /// <param name="tr">Trainer Data to use in generating the encounter</param> /// <param name="species">Species ID to generate</param> /// <returns>Result legal pkm, null if data should be ignored.</returns> private static PKM?GetRandomEncounter(PKM blank, ITrainerInfo tr, int species) { blank.Species = species; blank.Gender = blank.GetSaneGender(); if (species == 678) { blank.AltForm = blank.Gender; } var f = EncounterMovesetGenerator.GeneratePKMs(blank, tr).FirstOrDefault(); if (f == null) { return(null); } int abilityretain = f.AbilityNumber >> 1; f.Species = species; f.Gender = f.GetSaneGender(); if (species == 678) { f.AltForm = f.Gender; } f.CurrentLevel = 100; f.Nickname = SpeciesName.GetSpeciesNameGeneration(f.Species, f.Language, f.Format); f.IsNicknamed = false; f.SetSuggestedMoves(); f.AbilityNumber = abilityretain; f.RefreshAbility(abilityretain); return(f); }
/// <summary> /// Temporary Reimplementation of Kaphotics's Generator without the exception being thrown to avoid relying on the bruteforce mechanism /// </summary> /// <param name="pk">PKM to modify</param> /// <param name="info">Trainer Info for TID</param> /// <param name="moves">INT list of moves for the pkm</param> /// <param name="versions">Versions to iterate over (All in our case)</param> /// <returns></returns> public static IEnumerable <PKM> GeneratePKMs(PKM pk, ITrainerInfo info, int[] moves = null, params GameVersion[] versions) { GameVersion[] Versions = ((GameVersion[])Enum.GetValues(typeof(GameVersion))).Where(z => z < GameVersion.RB && z > 0).OrderBy(x => x.GetGeneration()).Reverse().ToArray(); pk.TID = info.TID; var m = moves ?? pk.Moves; var vers = versions?.Length >= 1 ? versions : Versions.Where(z => z <= (GameVersion)pk.MaxGameID); if (pk.Gen3) { vers = vers.Concat(new GameVersion[] { (GameVersion)15 }); } foreach (var ver in vers) { var encs = EncounterMovesetGenerator.GenerateVersionEncounters(pk, m, ver); foreach (var enc in encs) { var result = enc.ConvertToPKM(info); if (result.Version != (int)ver) { continue; } yield return(result); } } }
public void CanGenerateMG5Case() { const Species species = Species.Haxorus; var pk = new PK5 { Species = (int)species }; var ez = EncounterMovesetGenerator.GenerateEncounters(pk, pk.Moves, GameVersion.W2).OfType <EncounterStatic>().First(); ez.Should().NotBeNull("Shiny Haxorus stationary encounter exists for B2/W2"); var criteria = EncounterCriteria.Unrestricted; var tr = new SimpleTrainerInfo(GameVersion.B2) { TID = 57600, SID = 62446, }; for (var nature = Nature.Hardy; nature <= Nature.Quirky; nature++) { criteria = criteria with { Nature = nature }; var pkm = ez.ConvertToPKM(tr, criteria); pkm.Nature.Should().Be((int)nature, "not nature locked"); pkm.IsShiny.Should().BeTrue("encounter is shiny locked"); pkm.TID.Should().Be(tr.TID); pkm.SID.Should().Be(tr.SID); } } }
public void SimulatorGetEncounters() { var set = new ShowdownSet(SetGlaceonUSUMTutor); var pk7 = new PK7 { Species = set.Species, AltForm = set.FormIndex, Moves = set.Moves }; var encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.MN); Assert.IsTrue(!encs.Any()); pk7.HT_Name = "PKHeX"; encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.MN); var first = encs.FirstOrDefault(); Assert.IsTrue(first != null); var egg = (EncounterEgg)first; var info = new SimpleTrainerInfo(); var pk = egg.ConvertToPKM(info); Assert.IsTrue(pk.Species != set.Species); var la = new LegalityAnalysis(pk); Assert.IsTrue(la.Valid); var test = EncounterMovesetGenerator.GeneratePKMs(pk7, info).ToList(); foreach (var t in test) { var la2 = new LegalityAnalysis(t); Assert.IsTrue(la2.Valid); } }
/// <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); }
public static PKM?GetLivingEntry(this ITrainerInfo tr, PKM template, int species, int form, Type destType) { template.Species = species; template.Form = form; template.Gender = template.GetSaneGender(); var f = EncounterMovesetGenerator.GeneratePKMs(template, tr).FirstOrDefault(); if (f == null) { return(null); } var result = EntityConverter.ConvertToType(f, destType, out _); if (result == null) { return(null); } result.Species = species; result.Form = form; result.CurrentLevel = 100; result.Heal(); return(result); }
private IEnumerable <IEncounterable> GetEncounters(int species, int[] moves, PKM pk) { pk.Species = species; var parent = GameUtil.GetMetLocationVersionGroup(SAV.Version); var vers = GameUtil.GameVersions.Where(z => parent.Contains(z)).ToArray(); return(EncounterMovesetGenerator.GenerateEncounters(pk, moves, vers)); }
/// <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> /// Gets a legal <see cref="PKM"/> from a random in-game encounter's data. /// </summary> /// <param name="blank">Template data that will have its properties modified</param> /// <param name="tr">Trainer Data to use in generating the encounter</param> /// <param name="species">Species ID to generate</param> /// <returns>Result legal pkm, null if data should be ignored.</returns> private static PKM?GetRandomEncounter(PKM blank, ITrainerInfo tr, int species) { blank.Species = species; blank.Gender = blank.GetSaneGender(); if (species == (int)Species.Meowstic || species == (int)Species.Indeedee) { blank.AltForm = blank.Gender; } var legalencs = EncounterMovesetGenerator.GeneratePKMs(blank, tr).Where(z => new LegalityAnalysis(z).Valid); var f = legalencs.FirstOrDefault(); if (f == null) { return(null); } var an = f.AbilityNumber; f.Species = species; f.Gender = f.GetSaneGender(); if (species == (int)Species.Meowstic || species == (int)Species.Indeedee) { f.AltForm = f.Gender; } f.CurrentLevel = 100; f.Nickname = SpeciesName.GetSpeciesNameGeneration(f.Species, f.Language, f.Format); f.IsNicknamed = false; f.SetSuggestedMoves(); f.SetSuggestedMovePP(0); f.SetSuggestedMovePP(1); f.SetSuggestedMovePP(2); f.SetSuggestedMovePP(3); f.RefreshAbility(an >> 1); var info = new LegalityAnalysis(f).Info; if (info.Generation > 0 && info.EvoChainsAllGens[info.Generation].All(z => z.Species != info.EncounterMatch.Species)) { f.CurrentHandler = 1; f.HT_Name = f.OT_Name; if (f is IHandlerLanguage h) { h.HT_Language = 1; } } if (f is IFormArgument fa) { fa.FormArgument = ShowdownEdits.GetSuggestedFormArgument(f, info.EncounterMatch.Species); } int wIndex = WurmpleUtil.GetWurmpleEvoGroup(f.Species); if (wIndex != -1) { f.EncryptionConstant = WurmpleUtil.GetWurmpleEC(wIndex); } return(f); }
public static void CanLearnEggMoveBDSP(Species species, Move move) { MoveEgg.GetEggMoves(8, (int)species, 0, GameVersion.BD).Contains((int)move).Should().BeFalse(); var pb8 = new PB8 { Species = (int)species }; var encs = EncounterMovesetGenerator.GenerateEncounters(pb8, new[] { (int)move }, GameVersion.BD); encs.Any().Should().BeFalse("Unavailable until HOME update supports BD/SP."); }
/// <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); }
public void SimulatorParseEncounter(string text) { var set = new ShowdownSet(text); var pk7 = new PK7 { Species = set.Species, AltForm = set.FormIndex, Moves = set.Moves, CurrentLevel = set.Level }; var encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves); var tr3 = encs.First(z => z is EncounterTrade t && t.Generation == 3); var pk3 = tr3.ConvertToPKM(new SAV3()); var la = new LegalityAnalysis(pk3); la.Valid.Should().BeTrue(); }
//[TestMethod] //[TestCategory(SimulatorParse)] public void TestGenerate() { for (int i = 1; i <= 807; i++) { var tr = new SimpleTrainerInfo(); var pk = new PK7 { Species = i }; var ez = EncounterMovesetGenerator.GeneratePKMs(pk, tr); Debug.WriteLine($"Starting {i:000}"); bool v = ez.Select(p => new LegalityAnalysis(p)).All(la => la.Valid); Debug.WriteLine($"Finished {i:000}"); Debug.Assert(v); } }
public void SimulatorGetVCEgg1() { var set = new ShowdownSet(SetSlowpoke12); var pk7 = new PK7 { Species = set.Species, AltForm = set.FormIndex, Moves = set.Moves, HT_Name = "PKHeX" }; var encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.GD).ToList(); Assert.True(encs.Count > 0); var info = new SimpleTrainerInfo(GameVersion.SN); var enc = encs[0]; var pk = enc.ConvertToPKM(info); var la = new LegalityAnalysis(pk); Assert.True(la.Valid); }
private async void B_Search_Click(object sender, EventArgs e) { B_Search.Enabled = false; EncounterMovesetGenerator.PriorityList = GetTypes(); var search = SearchDatabase(); var results = await Task.Run(() => search.ToList()).ConfigureAwait(true); if (results.Count == 0) { WinFormsUtil.Alert(MsgDBSearchNone); } SetResults(results); // updates Count Label as well. System.Media.SystemSounds.Asterisk.Play(); B_Search.Enabled = true; EncounterMovesetGenerator.ResetFilters(); }
public void SimulatorGetSplitBreed() { var set = new ShowdownSet(SetMunchSnorLax); var pk7 = new PK7 { Species = set.Species, AltForm = set.FormIndex, Moves = set.Moves, HT_Name = "PKHeX" }; // !! specify the HT name, we need tutors for this one var encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.SN).ToList(); Assert.True(encs.Count > 0); Assert.True(encs.All(z => z.Species > 150)); var info = new SimpleTrainerInfo(GameVersion.SN); var enc = encs[0]; var pk = enc.ConvertToPKM(info); var la = new LegalityAnalysis(pk); Assert.True(la.Valid); }
/// <summary> /// Gets all encounters where a <see cref="species"/> can learn all input <see cref="moves"/>. /// </summary> public static IEnumerable <IEncounterable> GetLearn(int species, int[] moves, int form = 0) { if (species <= 0) { return(Array.Empty <IEncounterable>()); } if (moves.Any(z => z < 0)) { return(Array.Empty <IEncounterable>()); } var blank = EntityBlank.GetBlank(PKX.Generation); blank.Species = species; blank.Form = form; var vers = GameUtil.GameVersions; return(EncounterMovesetGenerator.GenerateEncounters(blank, moves, vers)); }
public void PokemonGenerationReturnsLegalPokemon(int species) { int count = 0; var tr = new SimpleTrainerInfo(GameVersion.SN); var pk = new PK7 { Species = species }; pk.Gender = pk.GetSaneGender(); var ez = EncounterMovesetGenerator.GeneratePKMs(pk, tr); foreach (var e in ez) { var la = new LegalityAnalysis(e); la.Valid.Should().BeTrue($"Because generated Pokemon {count} for {species:000} should be valid"); Assert.True(la.Valid); count++; } }
public void SimulatorGetCelebi() { var set = new ShowdownSet(SetCelebi); var pk7 = new PK7 { Species = set.Species, AltForm = set.FormIndex, Moves = set.Moves }; var encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.X); Assert.IsTrue(encs.Any()); encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.X); var first = encs.FirstOrDefault(); Assert.IsTrue(first != null); var enc = first; var info = new SimpleTrainerInfo(); var pk = enc.ConvertToPKM(info); var la = new LegalityAnalysis(pk); Assert.IsTrue(la.Valid); }
public void SimulatorGetWC3() { var set = new ShowdownSet(SetROCKSMetang); var pk3 = new PK3 { Species = set.Species, AltForm = set.FormIndex, Moves = set.Moves }; var encs = EncounterMovesetGenerator.GenerateEncounters(pk3, set.Moves, GameVersion.R); Assert.IsTrue(encs.Any()); encs = EncounterMovesetGenerator.GenerateEncounters(pk3, set.Moves, GameVersion.R); var first = encs.FirstOrDefault(); Assert.IsTrue(first != null); var wc3 = (WC3)first; var info = new SimpleTrainerInfo(); var pk = wc3.ConvertToPKM(info); var la = new LegalityAnalysis(pk); Assert.IsTrue(la.Valid); }
public void SimulatorGetSmeargle() { var set = new ShowdownSet(SetSmeargle); var pk7 = new PK7 { Species = set.Species, Form = set.Form, Moves = set.Moves }; var encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.MN); Assert.True(encs.Any()); encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.MN); var first = encs.FirstOrDefault(); Assert.NotNull(first); var enc = first !; var info = new SimpleTrainerInfo(GameVersion.SN); var pk = enc.ConvertToPKM(info); var la = new LegalityAnalysis(pk); Assert.True(la.Valid); }
//[TestMethod] //[TestCategory(SimulatorParse)] public void TestGenerate() { int count = 0; var tr = new SimpleTrainerInfo(); for (int i = 1; i <= 807; i++) { var pk = new PK7 { Species = i }; pk.Gender = pk.GetSaneGender(); var ez = EncounterMovesetGenerator.GeneratePKMs(pk, tr); Debug.WriteLine($"Starting {i:000}"); foreach (var e in ez) { var la = new LegalityAnalysis(e); Assert.IsTrue(la.Valid); count++; } Debug.WriteLine($"Finished {i:000}"); } Debug.WriteLine($"Generated {count} PKMs!"); }
/// <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> /// 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); }
private static bool InnerBruteForce(PKM pk, GameVersion game, bool shiny, int abilitynum, ShowdownSet set) { pk.ClearRelearnMoves(); switch (game) { case GameVersion.RD: case GameVersion.BU: case GameVersion.YW: case GameVersion.GN: pk.Met_Location = 30013; pk.Met_Level = 100; break; case GameVersion.GD: case GameVersion.SV: case GameVersion.C: pk.Met_Location = 30017; pk.Met_Level = 100; break; case GameVersion.CXD: pk.Met_Location = 30001; pk.Met_Level = 100; break; default: pk.SetSuggestedMetLocation(); break; } pk.SetSuggestedRelearnMoves(); pk.CurrentHandler = 1; pk.HT_Name = "Archit"; pk.PID = PKX.GetRandomPID(pk.Species, pk.Gender, pk.Version, pk.Nature, pk.Format, (uint)(pk.AbilityNumber * 0x10001)); if (shiny) { pk.SetShiny(); } if (pk.PID == 0) { pk.PID = PKX.GetRandomPID(pk.Species, pk.Gender, pk.Version, pk.Nature, pk.Format, (uint)(pk.AbilityNumber * 0x10001)); if (shiny) { pk.SetShiny(); } } pk.RefreshAbility(abilitynum); pk.SetSuggestedMemories(); if (pk.GenNumber < 6) { pk.EncryptionConstant = pk.PID; } if (CommonErrorHandling2(pk)) { pk.HyperTrain(); if (shiny) { pk.SetShiny(); } return(true); } pk.HyperTrain(); bool legalized = new LegalityAnalysis(pk).Valid; AlternateAbilityRefresh(pk); if (pk.GenNumber < 6 && !legalized) { pk.EncryptionConstant = pk.PID; } if (new LegalityAnalysis(pk).Valid&& pk.Format >= pk.GenNumber) { pk.SetHappiness(); if (shiny && pk.IsShiny) { return(true); } if (!set.Shiny || pk.IsShiny) { return(true); } pk.SetShinySID(); if (new LegalityAnalysis(pk).Valid) { return(true); } pk.SetShiny(); if (new LegalityAnalysis(pk).Valid) { return(true); } } else { var edge = EncounterMovesetGenerator.GenerateEncounters(pk).OfType <EncounterStatic>(); foreach (EncounterStatic el in edge) { ApplyEncounterAttributes(pk, set, el); var la = new LegalityAnalysis(pk); if (la.Valid) { return(true); } Debug.WriteLine(la.Report()); } } return(false); }
private static IEnumerable <IEncounterable> GetEncounters(int species, int[] moves, PKM pk, IReadOnlyList <GameVersion> vers) { pk.Species = species; return(EncounterMovesetGenerator.GenerateEncounters(pk, moves, vers)); }
/// <summary> /// Gets a legal <see cref="PKM"/> from a random in-game encounter's data. /// </summary> /// <param name="blank">Template data that will have its properties modified</param> /// <param name="tr">Trainer Data to use in generating the encounter</param> /// <param name="species">Species ID to generate</param> /// <returns>Result legal pkm, null if data should be ignored.</returns> private static PKM?GetRandomEncounter(PKM blank, ITrainerInfo tr, int species) { blank.Species = species; blank.Gender = blank.GetSaneGender(); if (species is ((int)Species.Meowstic)or((int)Species.Indeedee)) { blank.Form = blank.Gender; } var legalencs = EncounterMovesetGenerator.GeneratePKMs(blank, tr).Where(z => new LegalityAnalysis(z).Valid); var firstenc = legalencs.FirstOrDefault(); if (firstenc == null) { return(null); } var f = PKMConverter.ConvertToType(firstenc, blank.GetType(), out _); if (f == null) { var template = PKMConverter.GetBlank(tr.Generation, (GameVersion)tr.Game); var set = new ShowdownSet(new ShowdownSet(blank).Text.Split('\r')[0]); template.ApplySetDetails(set); var success = tr.TryAPIConvert(set, template, out PKM pk); return(success == LegalizationResult.Regenerated ? pk : null); } var an = f.AbilityNumber; f.Species = species; f.Gender = f.GetSaneGender(); if (species is ((int)Species.Meowstic)or((int)Species.Indeedee)) { f.Form = f.Gender; } f.CurrentLevel = 100; f.Nickname = SpeciesName.GetSpeciesNameGeneration(f.Species, f.Language, f.Format); f.IsNicknamed = false; f.SetSuggestedMoves(); f.SetSuggestedMovePP(0); f.SetSuggestedMovePP(1); f.SetSuggestedMovePP(2); f.SetSuggestedMovePP(3); f.RefreshAbility(an >> 1); var info = new LegalityAnalysis(f).Info; if (info.Generation > 0 && info.EvoChainsAllGens[info.Generation].All(z => z.Species != info.EncounterMatch.Species)) { f.CurrentHandler = 1; f.HT_Name = f.OT_Name; if (f is IHandlerLanguage h) { h.HT_Language = 1; } } if (f is IFormArgument fa) { fa.FormArgument = ShowdownEdits.GetSuggestedFormArgument(f, info.EncounterMatch.Species); } int wIndex = WurmpleUtil.GetWurmpleEvoGroup(f.Species); if (wIndex != -1) { f.EncryptionConstant = WurmpleUtil.GetWurmpleEncryptionConstant(wIndex); } if (f is IHomeTrack { Tracker : 0 } ht&& APILegality.SetRandomTracker) { ht.Tracker = APILegality.GetRandomULong(); } if (new LegalityAnalysis(f).Valid) { return(f); } // local name clashes! { var template = PKMConverter.GetBlank(tr.Generation, (GameVersion)tr.Game); var set = new ShowdownSet(new ShowdownSet(blank).Text.Split('\r')[0]); template.ApplySetDetails(set); var success = tr.TryAPIConvert(set, template, out PKM pk); return(success == LegalizationResult.Regenerated ? pk : null); } }
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 }))