From daf093879b62ca4a09b98f1b0a866ed4bb2c9a4a Mon Sep 17 00:00:00 2001 From: Kurt Date: Sun, 29 Apr 2018 18:26:36 -0700 Subject: [PATCH] More generator updates all the way up to nidorina extract some reusable methods exclude invalid headbutt encounters use built in randomgender --- PKHeX.Core/Legality/Core.cs | 10 ++- .../Legality/Encounters/Data/Encounters2.cs | 22 ++--- .../Legality/Encounters/Data/Encounters4.cs | 2 + .../Legality/Encounters/EncounterEgg.cs | 5 +- .../Legality/Encounters/EncounterSlot.cs | 12 ++- .../Legality/Encounters/EncounterStatic.cs | 2 +- .../Legality/Encounters/EncounterTrade.cs | 69 ++++++++++++--- .../Generator/EncounterMovesetGenerator.cs | 6 ++ .../Encounters/Verifiers/EncounterVerifier.cs | 11 +-- PKHeX.Core/Legality/RNG/MethodFinder.cs | 85 +++++++------------ PKHeX.Core/Legality/RNG/PIDGenerator.cs | 79 +++++++++++------ PKHeX.Core/PKM/PKM.cs | 2 + 12 files changed, 189 insertions(+), 116 deletions(-) diff --git a/PKHeX.Core/Legality/Core.cs b/PKHeX.Core/Legality/Core.cs index 8f4fc3f76..90fdf0d73 100644 --- a/PKHeX.Core/Legality/Core.cs +++ b/PKHeX.Core/Legality/Core.cs @@ -2191,9 +2191,15 @@ internal static bool IsOutsider(PKM pkm) return Outsider; } - internal static TreesArea GetCrystalTreeArea(EncounterSlot Slot) + internal static TreeEncounterAvailable GetGSCHeadbuttAvailability(EncounterSlot encounter, int TID) { - return HeadbuttTreesC.FirstOrDefault(a => a.Location == Slot.Location); + var Area = HeadbuttTreesC.FirstOrDefault(a => a.Location == encounter.Location); + if (Area == null) // Failsafe, every area with headbutt encounters has a tree area + return TreeEncounterAvailable.Impossible; + + var table = Area.GetTrees(encounter.Type); + var trainerpivot = TID % 10; + return table[trainerpivot]; } public static int[] GetEncounterMoves(PKM pk, int level, GameVersion version) diff --git a/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs b/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs index 0c63179ac..524878fb6 100644 --- a/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs +++ b/PKHeX.Core/Legality/Encounters/Data/Encounters2.cs @@ -250,19 +250,19 @@ private static EncounterArea[] GetSlots_C(EncounterArea[] f) internal static readonly EncounterTrade[] TradeGift_GSC = { - new EncounterTrade { Species = 095, Level = 03, Location = 126, Gender = 0, TID = 48926, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Onix @ Violet City for Bellsprout [wild] - new EncounterTrade { Species = 066, Level = 05, Location = 126, Gender = 1, TID = 37460, IVs = new[] {12, 03, 07, 06, 06, 06} }, // Machop @ Goldenrod City for Drowzee [wild 9, hatched egg 5] - new EncounterTrade { Species = 100, Level = 05, Location = 126, Gender = 2, TID = 29189, IVs = new[] {08, 09, 08, 08, 08, 08} }, // Voltorb @ Olivine City for Krabby [egg] - new EncounterTrade { Species = 112, Level = 10, Location = 126, Gender = 1, TID = 00283, IVs = new[] {12, 07, 07, 06, 06, 06} }, // Rhydon @ Blackthorn City for Dragonair [wild] - new EncounterTrade { Species = 142, Level = 05, Location = 126, Gender = 0, TID = 26491, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Aerodactyl @ Route 14 for Chansey [egg] - new EncounterTrade { Species = 078, Level = 14, Location = 126, Gender = 0, TID = 15616, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Rapidash @ Pewter City for Gloom [wild] + new EncounterTrade { Species = 095, Level = 03, Gender = 0, TID = 48926, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Onix @ Violet City for Bellsprout [wild] + new EncounterTrade { Species = 066, Level = 05, Gender = 1, TID = 37460, IVs = new[] {12, 03, 07, 06, 06, 06} }, // Machop @ Goldenrod City for Drowzee [wild 9, hatched egg 5] + new EncounterTrade { Species = 100, Level = 05, Gender = 2, TID = 29189, IVs = new[] {08, 09, 08, 08, 08, 08} }, // Voltorb @ Olivine City for Krabby [egg] + new EncounterTrade { Species = 112, Level = 10, Gender = 1, TID = 00283, IVs = new[] {12, 07, 07, 06, 06, 06} }, // Rhydon @ Blackthorn City for Dragonair [wild] + new EncounterTrade { Species = 142, Level = 05, Gender = 0, TID = 26491, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Aerodactyl @ Route 14 for Chansey [egg] + new EncounterTrade { Species = 078, Level = 14, Gender = 0, TID = 15616, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Rapidash @ Pewter City for Gloom [wild] - new EncounterTrade { Species = 085, Level = 10, Location = 126, Gender = 1, TID = 00283, IVs = new[] {12, 07, 07, 06, 06, 06} }, // Dodrio @ Blackthorn City for Dragonair [wild] - new EncounterTrade { Species = 178, Level = 15, Location = 126, Gender = 0, TID = 15616, IVs = new[] {08, 09, 06, 08, 06, 06} }, // Xatu @ Pewter City for Haunter [wild] - new EncounterTrade { Species = 082, Level = 05, Location = 126, Gender = 2, TID = 50082, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Magneton @ Power Plant for Dugtrio [traded for Lickitung] + new EncounterTrade { Species = 085, Level = 10, Gender = 1, TID = 00283, IVs = new[] {12, 07, 07, 06, 06, 06} }, // Dodrio @ Blackthorn City for Dragonair [wild] + new EncounterTrade { Species = 178, Level = 15, Gender = 0, TID = 15616, IVs = new[] {08, 09, 06, 08, 06, 06} }, // Xatu @ Pewter City for Haunter [wild] + new EncounterTrade { Species = 082, Level = 05, Gender = 2, TID = 50082, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Magneton @ Power Plant for Dugtrio [traded for Lickitung] - new EncounterTrade { Species = 021, Level = 10, Location = 126, TID = 01001, Moves = new[] {64,45,43} }, // Spearow @ Goldenrod City for free - new EncounterTrade { Species = 213, Level = 15, Location = 126, TID = 00518 }, // Shuckle @ Cianwood City for free + new EncounterTrade { Species = 021, Level = 10, TID = 01001, Moves = new[] {64,45,43} }, // Spearow @ Goldenrod City for free + new EncounterTrade { Species = 213, Level = 15, TID = 00518 }, // Shuckle @ Cianwood City for free }; internal static readonly string[][] TradeGift_GSC_OTs = { diff --git a/PKHeX.Core/Legality/Encounters/Data/Encounters4.cs b/PKHeX.Core/Legality/Encounters/Data/Encounters4.cs index 2192d87ce..b003ea8b6 100644 --- a/PKHeX.Core/Legality/Encounters/Data/Encounters4.cs +++ b/PKHeX.Core/Legality/Encounters/Data/Encounters4.cs @@ -79,6 +79,8 @@ byte[][] get(string resource, string ident) MarkEncounterTradeStrings(TradeGift_DPPt, TradeDPPt); MarkEncounterTradeStrings(TradeGift_HGSS, TradeHGSS); + foreach (var t in RanchGifts) + t.TrainerNames = RanchOTNames; DP_GreatMarshAlt.SetVersion(GameVersion.DP); DPPt_Unown.SetVersion(GameVersion.DPPt); diff --git a/PKHeX.Core/Legality/Encounters/EncounterEgg.cs b/PKHeX.Core/Legality/Encounters/EncounterEgg.cs index ba3f71578..c7b4fb8c1 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterEgg.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterEgg.cs @@ -53,14 +53,15 @@ public PKM ConvertToPKM(ITrainerInfo SAV) pk.Ball = 4; - int gender = Util.Rand.Next(2); + int gender = pk.PersonalInfo.RandomGender; int nature = Util.Rand.Next(25); - gender = pk.GetSaneGender(gender); if (pk.Format <= 5) { pk.SetPIDGender(gender); + pk.Gender = gender; pk.SetPIDNature(nature); + pk.Nature = nature; pk.RefreshAbility(pk.PIDAbility); } else diff --git a/PKHeX.Core/Legality/Encounters/EncounterSlot.cs b/PKHeX.Core/Legality/Encounters/EncounterSlot.cs index c5247f52e..ce5cad3f1 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterSlot.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterSlot.cs @@ -71,19 +71,17 @@ public PKM ConvertToPKM(ITrainerInfo SAV) int lang = (int)Legal.GetSafeLanguage(Generation, (LanguageID)SAV.Language); int level = LevelMin; var pk = PKMConverter.GetBlank(Generation); - int gender = Util.Rand.Next(2); int nature = Util.Rand.Next(25); SAV.ApplyToPKM(pk); - pk.EncryptionConstant = Util.Rand32(); pk.Species = Species; + int gender = pk.PersonalInfo.RandomGender; pk.Language = lang; pk.CurrentLevel = level; pk.Version = (int)version; pk.AltForm = Form; pk.Nickname = PKX.GetSpeciesNameGeneration(Species, lang, Generation); pk.Ball = GetBall(); - gender = pk.GetSaneGender(gender); if (pk.Format > 2 || Version == GameVersion.C) { @@ -97,8 +95,12 @@ public PKM ConvertToPKM(ITrainerInfo SAV) } pk.Language = lang; + var ability = Util.Rand.Next(0, 2); var pidtype = GetPIDType(); - PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, Util.Rand.Next(0, 2), gender, pidtype); + if (pidtype == PIDType.PokeSpot) + PIDGenerator.SetRandomPokeSpotPID(pk, nature, gender, ability, SlotNumber); + else + PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, ability, gender, pidtype); if (Permissions.IsDexNav) { @@ -128,6 +130,8 @@ public PKM ConvertToPKM(ITrainerInfo SAV) var moves = this is EncounterSlotMoves m ? m.Moves : Legal.GetEncounterMoves(pk, level, version); if (pk.Format == 1 && moves.All(z => z == 0)) moves = ((PersonalInfoG1)PersonalTable.RB[Species]).Moves; + else if (Version == GameVersion.XD) + pk.FatefulEncounter = true; pk.Moves = moves; pk.SetMaximumPPCurrent(moves); pk.OT_Friendship = pk.PersonalInfo.BaseFriendship; diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic.cs index 60805a39a..f95c05857 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterStatic.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterStatic.cs @@ -73,13 +73,13 @@ public PKM ConvertToPKM(ITrainerInfo SAV) int lang = (int)Legal.GetSafeLanguage(Generation, (LanguageID)SAV.Language); int level = LevelMin; var pk = PKMConverter.GetBlank(Generation); - int gender = Gender < 0 ? Util.Rand.Next(2) : Gender; int nature = Nature == Nature.Random ? Util.Rand.Next(25) : (int)Nature; var today = DateTime.Today; SAV.ApplyToPKM(pk); pk.EncryptionConstant = Util.Rand32(); pk.Species = Species; + int gender = Gender < 0 ? pk.PersonalInfo.RandomGender : Gender; pk.Language = lang; pk.CurrentLevel = level; pk.Version = (int)version; diff --git a/PKHeX.Core/Legality/Encounters/EncounterTrade.cs b/PKHeX.Core/Legality/Encounters/EncounterTrade.cs index 155958128..352fa0a99 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterTrade.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterTrade.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; namespace PKHeX.Core { @@ -48,8 +49,8 @@ public class EncounterTrade : IEncounterable, IMoveset, IGeneration, ILocation, public string[] Nicknames { get; internal set; } public string[] TrainerNames { get; internal set; } - public string GetNickname(int language) => Nicknames?.Length < language ? Nicknames[language] : null; - public string GetOT(int language) => TrainerNames?.Length < language ? TrainerNames[language] : null; + public string GetNickname(int language) => Nicknames?.Length > language ? Nicknames[language] : null; + public string GetOT(int language) => TrainerNames?.Length > language ? TrainerNames[language] : null; public static readonly int[] DefaultMetLocation = { @@ -61,33 +62,34 @@ public PKM ConvertToPKM(ITrainerInfo SAV) var version = this.GetCompatibleVersion((GameVersion)SAV.Game); int lang = (int)Legal.GetSafeLanguage(Generation, (LanguageID)SAV.Language); int level = CurrentLevel > 0 ? CurrentLevel : LevelMin; + if (level == 0) + level = 25; // avoid some cases var pk = PKMConverter.GetBlank(Generation); pk.EncryptionConstant = Util.Rand32(); pk.Species = Species; - pk.Language = lang; pk.CurrentLevel = level; - pk.Version = (int)version; - pk.PID = Util.Rand32(); + pk.PID = this is EncounterTradePID p ? p.PID : Util.Rand32(); pk.Ball = Ball; if (pk.Format != 2 || version == GameVersion.C) { - pk.Met_Level = LevelMin; - pk.Met_Location = Location; + pk.Met_Level = level; + pk.Met_Location = Location > 0 ? Location : DefaultMetLocation[Generation - 1]; } pk.MetDate = DateTime.Today; + SAV.ApplyToPKM(pk); int nature = Nature == Nature.Random ? Util.Rand.Next(25) : (int)Nature; pk.Nature = nature; - int gender = Gender < 0 ? Util.Rand.Next(2) : Gender; - pk.Gender = pk.GetSaneGender(gender); + pk.Version = (int)version; + pk.Gender = Gender < 0 ? pk.PersonalInfo.RandomGender : Gender; pk.AltForm = Form; - SAV.ApplyToPKM(pk); + pk.Language = lang; pk.TID = TID; pk.SID = SID; pk.OT_Name = GetOT(lang) ?? SAV.OT; - pk.OT_Gender = GetOT(lang) != null ? OTGender : SAV.Gender; + pk.OT_Gender = GetOT(lang) != null ? Math.Max(0, OTGender) : SAV.Gender; pk.SetNickname(GetNickname(lang)); pk.Language = lang; @@ -107,6 +109,8 @@ public PKM ConvertToPKM(ITrainerInfo SAV) this.CopyContestStatsTo(pk); var moves = Moves ?? Legal.GetEncounterMoves(pk, level, version); + if (pk.Format == 1 && moves.All(z => z == 0)) + moves = ((PersonalInfoG1)PersonalTable.RB[Species]).Moves; pk.Moves = moves; pk.SetMaximumPPCurrent(moves); pk.OT_Friendship = pk.PersonalInfo.BaseFriendship; @@ -119,7 +123,50 @@ public PKM ConvertToPKM(ITrainerInfo SAV) SAV.ApplyHandlingTrainerInfo(pk); pk.SetRandomEC(); + if (pk.Format == 7) + SetSMOTMemory(pk); + return pk; } + + private void UpdateEdgeCase(PKM pkm) + { + switch (Generation) + { + case 3 when Species == 124 && pkm.Version == (int) GameVersion.LG && pkm.Language == (int) LanguageID.Italian: + // Italian LG Jynx untranslated from English name + pkm.OT_Name = GetOT(2); + pkm.SetNickname(GetNickname(2)); + break; + + case 4 when Version == GameVersion.DPPt && Species == 129: // Meister Magikarp + // Has German Language ID for all except German origin, which is English + pkm.Language = (int)(pkm.Language == (int)LanguageID.German ? LanguageID.English : LanguageID.German); + break; + + case 4 when Version == GameVersion.DPPt && (pkm.Version == (int)GameVersion.D || pkm.Version == (int)GameVersion.P): + // DP English origin are Japanese lang + pkm.Language = 1; + break; + + case 4 when Version == GameVersion.HGSS && Species == 25: // Pikachu + // Has English Language ID for all except English origin, which is French + pkm.Language = (int)(pkm.Language == (int)LanguageID.English ? LanguageID.French : LanguageID.English); + break; + + case 5 when Version == GameVersion.BW && pkm.Language == 1: + // Trades for JPN games have language ID of 0, not 1. + pkm.Language = 0; + break; + } + } + + private static void SetSMOTMemory(PKM pk) + { + pk.OT_Memory = 1; + pk.OT_Intensity = 3; + pk.OT_TextVar = 40; + pk.OT_Feeling = 5; + } } } diff --git a/PKHeX.Core/Legality/Encounters/Generator/EncounterMovesetGenerator.cs b/PKHeX.Core/Legality/Encounters/Generator/EncounterMovesetGenerator.cs index 61226538a..84494f148 100644 --- a/PKHeX.Core/Legality/Encounters/Generator/EncounterMovesetGenerator.cs +++ b/PKHeX.Core/Legality/Encounters/Generator/EncounterMovesetGenerator.cs @@ -24,6 +24,7 @@ public static class EncounterMovesetGenerator /// A consumable list of possible results. public static IEnumerable 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 : Versions.Where(z => z <= (GameVersion) pk.MaxGameID); foreach (var ver in vers) @@ -254,6 +255,11 @@ private static IEnumerable GetSlots(PKM pk, IReadOnlyCollection> 8 ^ 0xFF) << 24; // the most significant byte of the PID is chosen so the Pokémon can never be shiny. - // Ensure nature is set to required nature without affecting shininess - pid += nature - pid % 25; + uint pid = PIDGenerator.GetPokeWalkerPID(pk.TID, pk.SID, nature, pk.Gender, pk.PersonalInfo.Gender); - // Ensure Gender is set to required gender without affecting other properties - // If Gender is modified, modify the ability if appropriate - int currentGender = pk.Gender; - if (currentGender != 2) // either m/f - { - var gr = pk.PersonalInfo.Gender; - var pidGender = (pid & 0xFF) < gr ? 1 : 0; - if (currentGender != pidGender) - { - if (currentGender == 0) // Male - { - pid += (uint) (((gr - (pid & 0xFF)) / 25 + 1) * 25); - if ((nature & 1) != (pid & 1)) - pid += 25; - } - else - { - pid -= (uint) ((((pid & 0xFF) - gr) / 25 + 1) * 25); - if ((nature & 1) != (pid & 1)) - pid -= 25; - } - } - } if (pid != oldpid) return GetNonMatch(out pidiv); pidiv = new PIDIV {NoSeed = true, RNG = RNG.LCRNG, Type = PIDType.Pokewalker}; @@ -646,36 +621,42 @@ public static IEnumerable GetPokeSpotSeeds(PKM pkm, int slot) foreach (var seed in seeds) { // check for valid encounter slot info - var esv = (seed>>16)%100; - switch (slot) - { - case 0: - if (esv < 50) break; // valid - continue; - case 1: - if (esv >= 50 && esv < 85) break; // valid - continue; - case 2: - if (esv >= 85) break; - continue; - default: - continue; - } - - // check for valid activation - var s = RNG.XDRNG.Prev(seed); - if ((s>>16)%3 != 0) - { - if ((s>>16)%100 < 10) // can't fail a munchlax/bonsly encounter check - continue; - s = RNG.XDRNG.Prev(s); - if ((s>>16)%3 != 0) // can't activate even if generous - continue; - } + if (!IsPokeSpotActivation(slot, seed, out uint s)) + continue; yield return new PIDIV {OriginSeed = s, RNG = RNG.XDRNG, Type = PIDType.PokeSpot}; } } + public static bool IsPokeSpotActivation(int slot, uint seed, out uint s) + { + s = seed; + var esv = (seed >> 16) % 100; + switch (slot) + { + case 0: + if (esv < 50) break; // valid + return false; + case 1: + if (esv >= 50 && esv < 85) break; // valid + return false; + case 2: + if (esv >= 85) break; + return false; + default: + return false; + } + // check for valid activation + s = RNG.XDRNG.Prev(seed); + if ((s >> 16) % 3 != 0) + { + if ((s >> 16) % 100 < 10) // can't fail a munchlax/bonsly encounter check + return false; + s = RNG.XDRNG.Prev(s); + if ((s >> 16) % 3 != 0) // can't activate even if generous + return false; + } + return true; + } public static bool IsCompatible3(this PIDType val, IEncounterable encounter, PKM pkm) { switch (encounter) diff --git a/PKHeX.Core/Legality/RNG/PIDGenerator.cs b/PKHeX.Core/Legality/RNG/PIDGenerator.cs index 2ba354132..aa7f729c8 100644 --- a/PKHeX.Core/Legality/RNG/PIDGenerator.cs +++ b/PKHeX.Core/Legality/RNG/PIDGenerator.cs @@ -153,6 +153,27 @@ public static void SetValuesFromSeed(PKM pk, PIDType type, uint seed) return (pk, seed) => { }; } + public static void SetRandomPokeSpotPID(PKM pk, int nature, int gender, int ability, int slot) + { + while (true) + { + var seed = Util.Rand32(); + if (!MethodFinder.IsPokeSpotActivation(slot, seed, out var _)) + continue; + + var rng = RNG.XDRNG; + var D = rng.Next(seed); // PID + var E = rng.Next(D); // PID + + pk.PID = D & 0xFFFF0000 | E >> 16; + if (!IsValidCriteria4(pk, nature, ability, gender)) + continue; + + pk.SetRandomIVs(); + return; + } + } + public static uint GetMG5ShinyPID(uint gval, uint av, int TID, int SID) { uint PID = (uint)((TID ^ SID ^ gval) << 16 | gval); @@ -172,24 +193,25 @@ public static uint GetPokeWalkerPID(int TID, int SID, uint nature, int gender, i // Ensure Gender is set to required gender without affecting other properties // If Gender is modified, modify the ability if appropriate int currentGender = gender; - if (currentGender != 2) // either m/f + if (currentGender == 2) + return pid; + + // either m/f + var pidGender = (pid & 0xFF) < gr ? 1 : 0; + if (currentGender == pidGender) + return pid; + + if (currentGender == 0) // Male { - var pidGender = (pid & 0xFF) < gr ? 1 : 0; - if (currentGender != pidGender) - { - if (currentGender == 0) // Male - { - pid += (uint)(((gr - (pid & 0xFF)) / 25 + 1) * 25); - if ((nature & 1) != (pid & 1)) - pid += 25; - } - else - { - pid -= (uint)((((pid & 0xFF) - gr) / 25 + 1) * 25); - if ((nature & 1) != (pid & 1)) - pid -= 25; - } - } + pid += (uint)(((gr - (pid & 0xFF)) / 25 + 1) * 25); + if ((nature & 1) != (pid & 1)) + pid += 25; + } + else + { + pid -= (uint)((((pid & 0xFF) - gr) / 25 + 1) * 25); + if ((nature & 1) != (pid & 1)) + pid -= 25; } return pid; } @@ -250,19 +272,26 @@ private static void SetRandomWildPID4(PKM pk, int nature, int ability, int gende while (true) { method(pk, Util.Rand32()); - - if (pk.GetSaneGender(gender) != gender) - continue; - - if (pk.Nature != nature) - continue; - - if ((pk.PID & 1) != ability) + if (!IsValidCriteria4(pk, nature, ability, gender)) continue; return; } } + private static bool IsValidCriteria4(PKM pk, int nature, int ability, int gender) + { + if (pk.GetSaneGender(gender) != gender) + return false; + + if (pk.Nature != nature) + return false; + + if ((pk.PID & 1) != ability) + return false; + + return true; + } + private static PIDType GetPIDType(PKM pk, PIDType specific) { if (specific != PIDType.None) diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs index f61e8d896..aacd0a9ed 100644 --- a/PKHeX.Core/PKM/PKM.cs +++ b/PKHeX.Core/PKM/PKM.cs @@ -957,6 +957,8 @@ public int[] SetRandomIVs(int[] template, int? flawless = null) for (int i = 0; i < 6; i++) ivs[i] = template[i] < 0 ? (int) (Util.Rand32() & MaxIV) : template[i]; } while (ivs.Count(z => z == MaxIV) < count); + + IVs = ivs; return ivs; }