public static void ApplyHandlingTrainerInfo(this ITrainerInfo SAV, PKM pk, bool force = false) { if (pk.Format == SAV.Generation && !force) { return; } pk.HT_Name = SAV.OT; pk.HT_Gender = SAV.Gender; pk.HT_Friendship = pk.OT_Friendship; pk.CurrentHandler = 1; if (pk.Format == 6) { var g = (IGeoTrack)pk; g.Geo1_Country = SAV.Country; g.Geo1_Region = SAV.SubRegion; ((PK6)pk).TradeMemory(true); } }
/// <summary> /// Gets if the current handler is the original trainer. /// </summary> /// <param name="trainer">The <see cref="ITrainerInfo"/> requesting the check.</param> /// <param name="pk">Pokémon data</param> /// <param name="checkGame">Toggle to check the game's version or not</param> /// <returns>True if OT, false if not OT.</returns> public static bool IsOriginalHandler(this ITrainerInfo trainer, PKM pk, bool checkGame) { if (pk.Format >= 6) { return(pk.CurrentHandler != 1); } if (checkGame && trainer.Game != pk.Version) { return(false); } if (trainer.TID != pk.TID || trainer.SID != pk.SID) { return(false); } if (trainer.Gender != pk.OT_Gender) { return(false); } return(trainer.OT == pk.OT_Name); }
/// <summary> /// Imports <see cref="sets"/> to a provided <see cref="arr"/>, with a context of <see cref="tr"/>. /// </summary> /// <param name="tr">Source/Destination trainer</param> /// <param name="sets">Set data to import</param> /// <param name="arr">Current list of data to write to</param> /// <param name="start">Starting offset to place converted details</param> /// <param name="overwrite">Overwrite</param> /// <returns>Result code indicating success or failure</returns> public static AutoModErrorCode ImportToExisting(this ITrainerInfo tr, IReadOnlyList <ShowdownSet> sets, IList <PKM> arr, int start = 0, bool overwrite = true) { var emptySlots = overwrite ? Enumerable.Range(start, sets.Count).ToList() : FindAllEmptySlots(arr, start); if (emptySlots.Count < sets.Count) { return(AutoModErrorCode.NotEnoughSpace); } var generated = 0; var invalidAPISets = new List <ShowdownSet>(); for (int i = 0; i < sets.Count; i++) { var set = sets[i]; if (set.InvalidLines.Count > 0) { return(AutoModErrorCode.InvalidLines); } Debug.WriteLine($"Generating Set: {GameInfo.Strings.Species[set.Species]}"); var pk = tr.GetLegalFromSet(set, out var msg); pk.ResetPartyStats(); if (msg == LegalizationResult.BruteForce) { invalidAPISets.Add(set); } arr[emptySlots[i]] = pk; generated++; } Debug.WriteLine($"API Genned Sets: {generated - invalidAPISets.Count}/{generated}, {invalidAPISets.Count} were not."); foreach (var set in invalidAPISets) { Debug.WriteLine(set.Text); } return(AutoModErrorCode.None); }
public static List <PKM> GetLivingDex(ITrainerInfo tr, IEnumerable <int> speciesToGenerate, PKM blank) { var result = new List <PKM>(); var destType = blank.GetType(); foreach (var s in speciesToGenerate) { var pk = blank.Clone(); pk.Species = s; pk.Gender = pk.GetSaneGender(); var pi = pk.PersonalInfo; for (int i = 0; i < pi.FormeCount; i++) { pk.AltForm = i; if (s == (int)Species.Indeedee || s == (int)Species.Meowstic) { pk.Gender = i; } var f = EncounterMovesetGenerator.GeneratePKMs(pk, tr).FirstOrDefault(); if (f == null) { continue; } var converted = PKMConverter.ConvertToType(f, destType, out _); if (converted == null) { continue; } converted.CurrentLevel = 100; converted.Species = s; converted.AltForm = i; result.Add(converted); } } return(result); }
/// <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); yield return(result); } } }
public void Trade(ITrainerInfo tr, int Day = 1, int Month = 1, int Year = 2015) { if (IsEgg) { // Apply link trade data, only if it left the OT (ignore if dumped & imported, or cloned, etc) if ((tr.OT != OT_Name) || (tr.TID != TID) || (tr.SID != SID) || (tr.Gender != OT_Gender)) { SetLinkTradeEgg(Day, Month, Year, Locations.LinkTrade6NPC); } // Unfortunately, BDSP doesn't return if it's an egg, and can update the HT details & handler. // Continue to the rest of the method. // return; } // Process to the HT if the OT of the Pokémon does not match the SAV's OT info. if (!TradeOT(tr)) { TradeHT(tr); } }
/// <summary> /// Tries to regenerate the <see cref="pk"/> into a valid pkm. /// </summary> /// <param name="tr">Source/Destination trainer</param> /// <param name="pk">Currently invalid pkm data</param> /// <returns>Legalized PKM (hopefully legal)</returns> public static PKM Legalize(this ITrainerInfo tr, PKM pk) { var set = new RegenTemplate(pk) { Ball = (Ball)pk.Ball, ShinyType = pk.ShinyXor == 0 ? Shiny.AlwaysSquare : pk.IsShiny ? Shiny.AlwaysStar : Shiny.Never }; var legal = tr.GetLegalFromTemplate(pk, set, out var satisfied); if (satisfied) { return(legal); } var dest = new PokeTrainerDetails(pk.Clone()); var resetForm = ShowdownUtil.IsInvalidForm(set.Form); legal = BruteForce.ApplyDetails(pk, set, resetForm, dest); legal.SetTrainerData(dest); return(legal); }
protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteria, PKM pk) { base.ApplyDetails(sav, criteria, pk); var pk1 = (PK1)pk; if (Version == GameVersion.YW) { // Since we don't keep track of Yellow's Personal Data, just handle any differences here. pk1.Catch_Rate = Species switch { (int)Core.Species.Kadabra => 96, (int)Core.Species.Dragonair => 27, _ => PersonalTable.RB[Species].CatchRate }; } else { pk1.Catch_Rate = PersonalTable.RB[Species].CatchRate; // RB } }
public static bool IsFromTrainer(this ITrainerInfo tr, PKM pk) { if (tr.Game == (int)GameVersion.Any) { return(true); } if (tr.TID != pk.TID) { return(false); } if (tr.OT != pk.OT_Name) { return(false); } if (pk.Format <= 2) { return(false); } if (tr.SID != pk.SID) { return(false); } if (pk.Format == 3) { return(false); } if (tr.Gender != pk.OT_Gender) { return(false); } if (tr.Game != pk.Version) { return(false); } return(true); }
public static void ApplyTo(this ITrainerInfo info, PKM pk) { pk.OT_Name = info.OT; pk.TID = info.TID; pk.SID = pk.Format < 3 || pk.VC ? 0 : info.SID; pk.OT_Gender = info.Gender; pk.Language = info.Language; pk.Version = info.Game; if (pk is not IRegionOrigin tr) { return; } if (info is not IRegionOrigin o) { return; } tr.Country = o.Country; tr.Region = o.Region; tr.ConsoleRegion = o.ConsoleRegion; }
protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteria, PKM pk) { base.ApplyDetails(sav, criteria, pk); if (CurrentLevel != -1) // Restore met level { pk.Met_Level = LevelMin; } if (TID != -1) { pk.TID = TID; } if (OT_Name.Length != 0) { pk.OT_Name = OT_Name; } else if (OT_Names.Count != 0) { pk.OT_Name = OT_Names[Util.Rand.Next(OT_Names.Count)]; } }
public static void AddFromLocalFile(string file, ICollection <SlotCache> db, ITrainerInfo dest, ICollection <string> validExtensions) { var fi = new FileInfo(file); if (!validExtensions.Contains(fi.Extension) || !PKX.IsPKM(fi.Length)) { return; } var data = File.ReadAllBytes(file); _ = FileUtil.TryGetPKM(data, out var pk, fi.Extension, dest); if (pk?.Species is not > 0) { return; } var info = new SlotInfoFile(file); var entry = new SlotCache(info, pk); db.Add(entry); }
/// <summary> /// Adds the <see cref="trainer"/> to the <see cref="Database"/>. /// </summary> /// <param name="trainer">Trainer details to add.</param> public void Register(ITrainerInfo trainer) { var ver = (GameVersion)trainer.Game; if (ver <= 0 && trainer is SaveFile s) { ver = s.Version; } if (!Database.TryGetValue(ver, out var list)) { Database.Add(ver, new List <ITrainerInfo> { trainer }); return; } if (list.Contains(trainer)) { return; } list.Add(trainer); }
/// <summary> /// Gets possible <see cref="PKM"/> objects that allow all moves requested to be learned. /// </summary> /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param> /// <param name="info">Trainer information of the receiver.</param> /// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param> /// <param name="versions">Any specific version(s) to iterate for. If left blank, all will be checked.</param> /// <returns>A consumable <see cref="PKM"/> list of possible results.</returns> public static IEnumerable <PKM> GeneratePKMs(PKM pk, ITrainerInfo info, int[] moves = null, params GameVersion[] versions) { var m = moves ?? pk.Moves; var vers = versions?.Length >= 1 ? versions : Versions.Where(z => z <= (GameVersion)pk.MaxGameID); foreach (var ver in vers) { var encs = GenerateVersionEncounters(pk, m, ver); foreach (var enc in encs) { var result = enc.ConvertToPKM(info); #if DEBUG var la = new LegalityAnalysis(result); if (!la.Valid) { throw new Exception(); } #endif yield return(result); } } }
public static string GetSummary(ITrainerInfo trainer) { var tid = trainer.TID; var sid = trainer.SID; if (trainer.Generation >= 7) { const int mil = 1_000_000; uint repack = ((uint)sid << 16) + (uint)tid; tid = (int)(repack % mil); sid = (int)(repack / mil); } var result = new[] { $"OT: {trainer.OT}", $"OTGender: {(trainer.Gender == 1 ? "Female" : "Male")}", $"TID: {tid}", $"SID: {sid}" }; return(string.Join(Environment.NewLine, result)); }
/// <summary> /// Gets possible <see cref="PKM"/> objects that allow all moves requested to be learned. /// </summary> /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param> /// <param name="info">Trainer information of the receiver.</param> /// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param> /// <param name="versions">Any specific version(s) to iterate for. If left blank, all will be checked.</param> /// <returns>A consumable <see cref="PKM"/> list of possible results.</returns> public static IEnumerable <PKM> GeneratePKMs(PKM pk, ITrainerInfo info, int[] moves = null, params GameVersion[] versions) { pk.TID = info.TID; var m = moves ?? pk.Moves; var vers = versions?.Length >= 1 ? versions : GameUtil.GetVersionsWithinRange(pk, pk.Format); foreach (var ver in vers) { var encs = GenerateVersionEncounters(pk, m, ver); foreach (var enc in encs) { var result = enc.ConvertToPKM(info); #if DEBUG var la = new LegalityAnalysis(result); if (!la.Valid) { throw new Exception(); } #endif yield return(result); } } }
public static void AddFromLocalFile(string file, ICollection <SlotCache> db, ITrainerInfo dest, ICollection <string> validExtensions) { var fi = new FileInfo(file); if (!validExtensions.Contains(fi.Extension) || !PKX.IsPKM(fi.Length)) { return; } var data = File.ReadAllBytes(file); var prefer = PKX.GetPKMFormatFromExtension(fi.Extension, dest.Generation); var pk = PKMConverter.GetPKMfromBytes(data, prefer); if (pk?.Species is not > 0) { return; } var info = new SlotInfoFile(file); var entry = new SlotCache(info, pk); db.Add(entry); }
/// <summary> /// Main method that calls both API legality and Bruteforce /// </summary> /// <param name="tr">Trainer Data that was passed in</param> /// <param name="set">Showdown set being used</param> /// <param name="template">template PKM to legalize</param> /// <param name="msg">Legalization result (API, Bruteforce, Failure)</param> /// <returns>Legalized pkm</returns> private static PKM GetLegalFromSet(this ITrainerInfo tr, IBattleTemplate set, PKM template, out LegalizationResult msg) { if (set is ShowdownSet s) { set = new RegenTemplate(s); } if (AllowAPI) { bool success = tr.TryAPIConvert(set, template, out PKM pk); if (success) { msg = LegalizationResult.Regenerated; return(pk); } } if (AllowBruteForce) { msg = LegalizationResult.BruteForce; return(tr.GetBruteForcedLegalMon(set, template)); } msg = LegalizationResult.Failed; if (EnableEasterEggs) { var gen = EasterEggs.GetGeneration(template.Species); template.Species = (int)EasterEggs.IllegalPKMMemeSpecies(gen); var legalencs = ModLogic.GetRandomEncounter(tr, (int)EasterEggs.IllegalPKMMemeSpecies(gen), out var legal); if (legalencs && legal != null) { template = legal; } template.SetNickname(EasterEggs.IllegalPKMMemeNickname(gen)); } return(template); }
private static bool IgnoreForm(this PKM pk, ITrainerInfo tr, int form) { var generation = tr.Generation; var species = pk.Species; switch ((Species)species) { case Species.Unown when generation == 2 && form >= 26: return(true); case Species.Scatterbug or Species.Spewpa when form > Vivillon3DS.MaxWildFormID: return(true); case Species.Floette when form == 5: return(true); case Species.Shaymin or Species.Furfrou or Species.Hoopa when form != 0 && generation <= 6: return(true); case Species.Arceus when generation == 4 && form == 9: // ??? form return(true); } if (FormInfo.IsBattleOnlyForm(pk.Species, form, generation)) { return(true); } if (form == 0) { return(false); } if (generation >= 7 && pk.Generation < 7 && pk.Generation != -1 && (species == 25 || SimpleEdits.AlolanOriginForms.Contains(species))) { return(true); } return(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> /// <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 PKM ConvertToPKM(ITrainerInfo sav) => ConvertToPKM(sav, EncounterCriteria.Unrestricted);
private static void TryAddPKMsFromFolder(ConcurrentBag <PKM> dbTemp, string file, ITrainerInfo dest, ICollection <string> validExtensions) { var fi = new FileInfo(file); if (!validExtensions.Contains(fi.Extension) || !PKX.IsPKM(fi.Length)) { return; } var data = File.ReadAllBytes(file); var prefer = PKX.GetPKMFormatFromExtension(fi.Extension, dest.Generation); var pk = PKMConverter.GetPKMfromBytes(data, prefer); if (!(pk?.Species > 0)) { return; } pk.Identifier = file; dbTemp.Add(pk); }
/// <summary> /// Gets possible <see cref="PKM"/> objects that allow all moves requested to be learned within a specific generation. /// </summary> /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param> /// <param name="info">Trainer information of the receiver.</param> /// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param> /// <param name="generation">Specific generation to iterate versions for.</param> public static IEnumerable <PKM> GeneratePKMs(PKM pk, ITrainerInfo info, int generation, int[] moves = null) { var vers = GameUtil.GetVersionsInGeneration(generation); return(GeneratePKMs(pk, info, moves, vers)); }
public abstract PKM ConvertToPKM(ITrainerInfo SAV);
/// <summary> /// Set TID, SID and OT /// </summary> /// <param name="pk">PKM to set trainer data to</param> /// <param name="trainer">Trainer data</param> public static void SetTrainerData(this PKM pk, ITrainerInfo trainer) { pk.TID = trainer.TID; pk.SID = pk.GenNumber >= 3 ? trainer.SID : 0; pk.OT_Name = trainer.OT; }
public abstract PKM ConvertToPKM(ITrainerInfo sav, EncounterCriteria criteria);
public PKM ConvertToPKM(ITrainerInfo SAV, EncounterCriteria criteria) => throw new ArgumentException($"Cannot convert an {nameof(EncounterInvalid)} to PKM.");
public PKM ConvertToPKM(ITrainerInfo SAV) => ConvertToPKM(SAV, EncounterCriteria.Unrestricted);
public PKM ConvertToPKM(ITrainerInfo SAV) { int gen = Math.Max(2, Version.GetGeneration()); var pk = PKMConverter.GetBlank(gen); SAV.ApplyToPKM(pk); pk.Species = Species; pk.Nickname = PKX.GetSpeciesNameGeneration(Species, SAV.Language, gen); pk.CurrentLevel = Level; pk.Version = (int)Version; var moves = Legal.GetEggMoves(pk, Species, pk.AltForm, Version); if (moves.Length == 0) { moves = Legal.GetEncounterMoves(pk, Level, Version); } pk.Moves = moves; pk.SetMaximumPPCurrent(moves); pk.OT_Friendship = pk.PersonalInfo.BaseFriendship; pk.SetRandomIVs(flawless: 3); if (pk.Format <= 2 && Version != GameVersion.C) { return(pk); } pk.Met_Level = EncounterSuggestion.GetSuggestedEncounterEggMetLevel(pk); pk.Met_Location = Math.Max(0, EncounterSuggestion.GetSuggestedEggMetLocation(pk)); if (pk.Format < 3) { return(pk); } pk.Ball = 4; int gender = Util.Rand.Next(2); int nature = Util.Rand.Next(25); gender = pk.GetSaneGender(gender); if (pk.Format <= 5) { pk.SetPIDGender(gender); pk.SetPIDNature(nature); pk.RefreshAbility(pk.PIDAbility); } else { pk.PID = Util.Rand32(); pk.Nature = nature; pk.Gender = gender; pk.RefreshAbility(Util.Rand.Next(2)); } bool traded = (int)Version == SAV.Game; var today = pk.MetDate = DateTime.Today; if (pk.GenNumber >= 4) { pk.Egg_Location = EncounterSuggestion.GetSuggestedEncounterEggLocationEgg(pk, traded); pk.EggMetDate = today; } if (pk.Format < 6) { return(pk); } if (pk.Gen6) { pk.SetHatchMemory6(); } pk.SetRandomEC(); pk.RelearnMoves = moves; return(pk); }
/// <summary> /// Sorts an <see cref="Enumerable"/> list of <see cref="PKM"/> objects to display those originally obtained by the current <see cref="ITrainerInfo"/>. /// </summary> /// <param name="list">Source list to sort</param> /// <param name="trainer">The <see cref="ITrainerInfo"/> requesting the sorted data.</param> /// <returns>Enumerable list that is sorted</returns> public static IEnumerable <PKM> OrderByOwnership(this IEnumerable <PKM> list, ITrainerInfo trainer) { return(list.InitialSortBy() .ThenByDescending(p => trainer.IsOriginalHandler(p, ((GameVersion)trainer.Game).IsValidSavedVersion())) // true first .ThenByDescending(p => string.Equals(p.OT_Name, trainer.OT, StringComparison.CurrentCultureIgnoreCase)) .OrderByTrainer() .ThenBy(p => p.Species) .FinalSortBy()); }