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> /// 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 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 }))