From a437fecab890ce9226f392256b057aba0237d68a Mon Sep 17 00:00:00 2001 From: Kurt Date: Mon, 24 Nov 2025 17:21:49 -0800 Subject: [PATCH] Reuse EntityGender magic ratio values --- .../Generator/ByGeneration/EncounterGenerator3.cs | 2 +- .../Templates/Gen4/EncounterStatic4Pokewalker.cs | 2 +- PKHeX.Core/Legality/RNG/CXD/MethodCXD.cs | 8 +++----- PKHeX.Core/Legality/RNG/MethodFinder.cs | 2 +- PKHeX.Core/PKM/PKM.cs | 9 +++++---- PKHeX.Core/PKM/Util/EntityGender.cs | 10 +++++++++- Tests/PKHeX.Core.Tests/Legality/RNG/Wild8aRNGTests.cs | 4 ++-- 7 files changed, 22 insertions(+), 15 deletions(-) diff --git a/PKHeX.Core/Legality/Encounters/Generator/ByGeneration/EncounterGenerator3.cs b/PKHeX.Core/Legality/Encounters/Generator/ByGeneration/EncounterGenerator3.cs index cac250ba9..d380c5e56 100644 --- a/PKHeX.Core/Legality/Encounters/Generator/ByGeneration/EncounterGenerator3.cs +++ b/PKHeX.Core/Legality/Encounters/Generator/ByGeneration/EncounterGenerator3.cs @@ -63,7 +63,7 @@ public IEnumerable GetEncounters(PKM pk, EvoCriteria[] chain, Le bool emerald = pk.E; byte gender = pk.Gender; if (pk.Species is (int)Species.Marill or (int)Species.Azumarill) - gender = EntityGender.GetFromPIDAndRatio(pk.EncryptionConstant, 0x3F); + gender = EntityGender.GetFromPID(pk.EncryptionConstant, EntityGender.MM); foreach (var enc in iterator) { diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen4/EncounterStatic4Pokewalker.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen4/EncounterStatic4Pokewalker.cs index 9c8f9c9b9..ed5abab5d 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen4/EncounterStatic4Pokewalker.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen4/EncounterStatic4Pokewalker.cs @@ -158,7 +158,7 @@ private bool IsMatchGender(PKM pk) // Azurill-F can change to M when evolving in Gen4 (but not in Gen5+) due to Gender Ratio differences. if (pk.Species != Species && Species == (ushort)Core.Species.Azurill && Gender == 1) - return EntityGender.GetFromPIDAndRatio(pk.PID, 0xBF) == Gender; + return EntityGender.GetFromPID(pk.PID, EntityGender.MF) == Gender; return true; } diff --git a/PKHeX.Core/Legality/RNG/CXD/MethodCXD.cs b/PKHeX.Core/Legality/RNG/CXD/MethodCXD.cs index 104b5fcc9..c19892944 100644 --- a/PKHeX.Core/Legality/RNG/CXD/MethodCXD.cs +++ b/PKHeX.Core/Legality/RNG/CXD/MethodCXD.cs @@ -282,7 +282,7 @@ public static bool SetStarterFromTrainerID(XK3 pk, in EncounterCriteria criteria uint pid = GetPID(s); if (criteria.IsSpecifiedNature() && !criteria.IsSatisfiedNature((Nature)(pid % 25))) continue; - if (criteria.IsSpecifiedGender() && !criteria.IsSatisfiedGender(EntityGender.GetFromPIDAndRatio(pid, 0x1F))) + if (criteria.IsSpecifiedGender() && !criteria.IsSatisfiedGender(EntityGender.GetFromPID(pid, EntityGender.VM))) continue; var ivSeed = XDRNG.Next4(seed); @@ -359,7 +359,7 @@ public static void SetStarterRandom(XK3 pk, in EncounterCriteria criteria, uint var pid = GetPIDRegular(ref seed); if (criteria.IsSpecifiedNature() && !criteria.IsSatisfiedNature((Nature)(pid % 25))) continue; - if (criteria.IsSpecifiedGender() && !criteria.IsSatisfiedGender(EntityGender.GetFromPIDAndRatio(pid, GenderRatioMale87_5))) + if (criteria.IsSpecifiedGender() && !criteria.IsSatisfiedGender(EntityGender.GetFromPID(pid, EntityGender.VM))) continue; var tid = XDRNG.Next16(ref start); @@ -515,9 +515,7 @@ private static uint GetColoStarterPID(ref uint seed, uint id32) } } - private const byte GenderRatioMale87_5 = 0x1F; // 87.5% - - private static bool IsMaleEevee(uint pid) => (pid & 0xFF) >= GenderRatioMale87_5; + private static bool IsMaleEevee(uint pid) => (pid & 0xFF) >= EntityGender.VM; private static bool IsValidStarterColo(uint id32, uint pid) => IsMaleEevee(pid) && !ShinyUtil.GetIsShiny3(id32, pid); diff --git a/PKHeX.Core/Legality/RNG/MethodFinder.cs b/PKHeX.Core/Legality/RNG/MethodFinder.cs index e4ef068cd..1f50c6be1 100644 --- a/PKHeX.Core/Legality/RNG/MethodFinder.cs +++ b/PKHeX.Core/Legality/RNG/MethodFinder.cs @@ -543,7 +543,7 @@ private static bool IsAzurillEdgeCaseM(PKM pk, uint nature, uint actualPID) if (species is not ((int)Species.Marill or (int)Species.Azumarill)) return false; - const byte AzurillGenderRatio = 0xBF; + const byte AzurillGenderRatio = EntityGender.MF; var gender = EntityGender.GetFromPIDAndRatio(actualPID, AzurillGenderRatio); if (gender != 1) return false; diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs index 03c2a5ff7..27ae2cd09 100644 --- a/PKHeX.Core/PKM/PKM.cs +++ b/PKHeX.Core/PKM/PKM.cs @@ -612,11 +612,12 @@ public virtual bool IsGenderValid() if (gv == PersonalInfo.RatioMagicMale) return gender == 0; - var gen = Generation; - if (gen is not (3 or 4 or 5)) - return gender == (gender & 1); + if (gender >= 2) + return false; // genderless would have returned above + if (!(Gen3 || Gen4 || Gen5)) + return true; // not tied to PID - return gender == EntityGender.GetFromPIDAndRatio(PID, gv); + return gender == EntityGender.GetFromPID(PID, gv); } /// diff --git a/PKHeX.Core/PKM/Util/EntityGender.cs b/PKHeX.Core/PKM/Util/EntityGender.cs index e0aa71b84..7f78e458a 100644 --- a/PKHeX.Core/PKM/Util/EntityGender.cs +++ b/PKHeX.Core/PKM/Util/EntityGender.cs @@ -58,9 +58,17 @@ public static byte GetFromPID(ushort species, uint pid) PersonalInfo.RatioMagicGenderless => Genderless, PersonalInfo.RatioMagicFemale => Female, PersonalInfo.RatioMagicMale => Male, - _ => (pid & 0xFF) < gr ? Female : Male, + _ => GetFromPID(pid, gr), }; + /// + /// Gets the gender for bi-gender species based on the and values. + /// + /// Personality ID. + /// Gender Ratio. + /// Assumes single-gender species are not relevant when called. + public static byte GetFromPID(uint pid, byte gr) => (pid & 0xFF) < gr ? Female : Male; + /// /// Checks if the species (base form) can be female. /// diff --git a/Tests/PKHeX.Core.Tests/Legality/RNG/Wild8aRNGTests.cs b/Tests/PKHeX.Core.Tests/Legality/RNG/Wild8aRNGTests.cs index 6fe491247..8c2aed90f 100644 --- a/Tests/PKHeX.Core.Tests/Legality/RNG/Wild8aRNGTests.cs +++ b/Tests/PKHeX.Core.Tests/Legality/RNG/Wild8aRNGTests.cs @@ -15,7 +15,7 @@ public static void TryGenerateShinyOutbreakZorua() { FlawlessIVs = 0, IsAlpha = false, Shiny = Shiny.Random, RollCount = 30, - GenderRatio = 0x7F, + GenderRatio = EntityGender.HH, }; var result = Overworld8aRNG.TryApplyFromSeed(test, EncounterCriteria.Unrestricted, param, s0); @@ -46,7 +46,7 @@ public static void TestMagby() IsAlpha = true, Shiny = Shiny.Random, RollCount = 17, - GenderRatio = 0x7F, + GenderRatio = EntityGender.HH, }; var xoro = new Xoroshiro128Plus(s0);