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;
}