public static IEnumerable <PKM> GetCompatible(this SaveFile sav, IEnumerable <PKM> pks) { var savtype = sav.PKMType; foreach (var temp in pks) { var pk = EntityConverter.ConvertToType(temp, savtype, out var c); if (pk == null) { Debug.WriteLine(c.GetDisplayString(temp, savtype)); continue; } if (sav is ILangDeviantSave il && EntityConverter.IsIncompatibleGB(temp, il.Japanese, pk.Japanese)) { var str = EntityConverterResult.IncompatibleLanguageGB.GetIncompatibleGBMessage(pk, il.Japanese); Debug.WriteLine(str); continue; } var compat = sav.EvaluateCompatibility(pk); if (compat.Count > 0) { continue; } yield return(pk); } }
/// <summary> /// Gets a blank file for the save file. If the template path exists, a template load will be attempted. /// </summary> /// <param name="sav">Save File to fetch a template for</param> /// <param name="templatePath">Path to look for a template in</param> /// <returns>Template if it exists, or a blank <see cref="PKM"/> from the <see cref="sav"/></returns> public static PKM LoadTemplate(this SaveFile sav, string?templatePath = null) { if (templatePath == null || !Directory.Exists(templatePath)) { return(LoadTemplateInternal(sav)); } var di = new DirectoryInfo(templatePath); string path = Path.Combine(templatePath, $"{di.Name}.{sav.PKMType.Name.ToLowerInvariant()}"); if (!File.Exists(path)) { return(LoadTemplateInternal(sav)); } var fi = new FileInfo(path); if (!EntityDetection.IsSizePlausible(fi.Length)) { return(LoadTemplateInternal(sav)); } var data = File.ReadAllBytes(path); var prefer = EntityFileExtension.GetContextFromExtension(fi.Extension, sav.Context); var pk = EntityFormat.GetFromBytes(data, prefer); if (pk?.Species is not > 0) { return(LoadTemplateInternal(sav)); } return(EntityConverter.ConvertToType(pk, sav.BlankPKM.GetType(), out _) ?? LoadTemplateInternal(sav)); }
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); }
/// <summary> /// Gets a legal <see cref="PKM"/> from a random in-game encounter's data. /// </summary> /// <param name="tr">Trainer Data to use in generating the encounter</param> /// <param name="species">Species ID to generate</param> /// <param name="form">Form to generate; if left null, picks first encounter</param> /// <param name="shiny"></param> /// <param name="alpha"></param> /// <param name="attempt"></param> /// <param name="pk">Result legal pkm</param> /// <returns>True if a valid result was generated, false if the result should be ignored.</returns> public static bool GetRandomEncounter(this ITrainerInfo tr, int species, int?form, bool shiny, bool alpha, ref int attempt, out PKM?pk) { var blank = EntityBlank.GetBlank(tr); pk = GetRandomEncounter(blank, tr, species, form, shiny, alpha, ref attempt); if (pk == null) { return(false); } pk = EntityConverter.ConvertToType(pk, blank.GetType(), out _); return(pk != null); }
/// <summary> /// Gets a compatible <see cref="PKM"/> for editing with a new <see cref="SaveFile"/>. /// </summary> /// <param name="sav">SaveFile to receive the compatible <see cref="pk"/></param> /// <param name="pk">Current Pokémon being edited</param> /// <returns>Current Pokémon, assuming conversion is possible. If conversion is not possible, a blank <see cref="PKM"/> will be obtained from the <see cref="sav"/>.</returns> public static PKM GetCompatiblePKM(this SaveFile sav, PKM pk) { if (pk.Format >= 3 || sav.Generation >= 7) { return(EntityConverter.ConvertToType(pk, sav.PKMType, out _) ?? sav.BlankPKM); } // gen1-2 compatibility check if (pk.Japanese != ((ILangDeviantSave)sav).Japanese) { return(sav.BlankPKM); } if (sav is SAV2 s2 && s2.Korean != pk.Korean) { return(sav.BlankPKM); } return(EntityConverter.ConvertToType(pk, sav.PKMType, out _) ?? sav.BlankPKM); }
public async Task TradeAsync([Summary("Trade Code")] int code, [Summary("Showdown Set")][Remainder] string content) { content = ReusableActions.StripCodeBlock(content); var set = new ShowdownSet(content); var template = AutoLegalityWrapper.GetTemplate(set); if (set.InvalidLines.Count != 0) { var msg = $"Unable to parse Showdown Set:\n{string.Join("\n", set.InvalidLines)}"; await ReplyAsync(msg).ConfigureAwait(false); return; } try { var sav = AutoLegalityWrapper.GetTrainerInfo <T>(); var pkm = sav.GetLegal(template, out var result); var la = new LegalityAnalysis(pkm); var spec = GameInfo.Strings.Species[template.Species]; pkm = EntityConverter.ConvertToType(pkm, typeof(T), out _) ?? pkm; if (pkm is not T pk || !la.Valid) { var reason = result == "Timeout" ? $"That {spec} set took too long to generate." : $"I wasn't able to create a {spec} from that set."; var imsg = $"Oops! {reason}"; if (result == "Failed") { imsg += $"\n{AutoLegalityWrapper.GetLegalizationHint(template, sav, pkm)}"; } await ReplyAsync(imsg).ConfigureAwait(false); return; } pk.ResetPartyStats(); var sig = Context.User.GetFavor(); await AddTradeToQueueAsync(code, Context.User.Username, pk, sig, Context.User).ConfigureAwait(false); } catch (Exception ex) { LogUtil.LogSafe(ex, nameof(TradeModule <T>)); var msg = $"Oops! An unexpected problem happened with this Showdown Set:\n```{string.Join("\n", set.GetSetLines())}```"; await ReplyAsync(msg).ConfigureAwait(false); } }
/// <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> /// <param name="form">Form to generate; if left null, picks first encounter</param> /// <param name="shiny"></param> /// <param name="alpha"></param> /// <param name="attempt"></param> /// <returns>Result legal pkm, null if data should be ignored.</returns> private static PKM?GetRandomEncounter(PKM blank, ITrainerInfo tr, int species, int?form, bool shiny, bool alpha, ref int attempt) { blank.Species = species; blank.Gender = blank.GetSaneGender(); if (species is ((int)Species.Meowstic)or((int)Species.Indeedee)) { if (form == null) { blank.Form = blank.Gender; } else { blank.Gender = (int)form; } } var template = EntityBlank.GetBlank(tr.Generation, (GameVersion)tr.Game); if (form != null) { blank.Form = (int)form; var item = GetFormSpecificItem(tr.Game, blank.Species, (int)form); if (item != null) { blank.HeldItem = (int)item; } if (blank.Species == (int)Species.Keldeo && blank.Form == 1) { blank.Move1 = (int)Move.SecretSword; } } if (form == null) { var f = GetAvailableForm(blank); if (f == -1) { return(null); } blank.Form = f; } if (blank.GetIsFormInvalid(tr, blank.Form)) { return(null); } attempt++; var ssettext = new ShowdownSet(blank).Text.Split('\r')[0]; if (shiny && !SimpleEdits.IsShinyLockedSpeciesForm(blank.Species, blank.Form)) { ssettext += Environment.NewLine + "Shiny: Yes"; } if (template is IAlpha && alpha) { ssettext += Environment.NewLine + "Alpha: Yes"; } var sset = new ShowdownSet(ssettext); var set = new RegenTemplate(sset) { Nickname = string.Empty }; template.ApplySetDetails(set); var success = tr.TryAPIConvert(set, template, out PKM pk); if (success == LegalizationResult.Regenerated) { if (form == null) { return(pk); } if (pk.Form == (int)form) { return(pk); } } // just get a legal pkm and return. Only validate form and not shininess or alpha. var legalencs = EncounterMovesetGenerator.GeneratePKMs(blank, tr).Where(z => new LegalityAnalysis(z).Valid); var firstenc = GetFirstEncounter(legalencs, form); if (firstenc == null) { attempt--; return(null); } var originspecies = firstenc.Species; if (originspecies != blank.Species) { firstenc.Species = blank.Species; firstenc.CurrentLevel = 100; if (!firstenc.IsNicknamed) { firstenc.Nickname = SpeciesName.GetSpeciesNameGeneration(firstenc.Species, firstenc.Language, firstenc.Format); } firstenc.SetMoves(firstenc.GetMoveSet()); firstenc.RefreshAbility(firstenc.AbilityNumber >> 1); } var second = EntityConverter.ConvertToType(firstenc, blank.GetType(), out _); if (second == null) { return(null); } second.HeldItem = blank.HeldItem; if (second is IScaledSizeValue sv) { sv.HeightAbsolute = sv.CalcHeightAbsolute; sv.WeightAbsolute = sv.CalcWeightAbsolute; } if (form == null || second.Form == (int)form) { return(second); } // force form and check legality as a last ditch effort. second.Form = (int)form; second.SetSuggestedFormArgument(originspecies); if (second is IScaledSizeValue sc) { sc.HeightAbsolute = sc.CalcHeightAbsolute; sc.WeightAbsolute = sc.CalcWeightAbsolute; } if (new LegalityAnalysis(second).Valid) { return(second); } return(null); }