From 205e9b433de7d6ac3352d21bceb7e92c5ab77ee5 Mon Sep 17 00:00:00 2001 From: Kurt Date: Thu, 21 Mar 2024 00:18:16 -0500 Subject: [PATCH] Set ability bit, precheck for encounter activation --- .../RNG/ClassicEra/Gen3/GenerateMethodH.cs | 10 ++++++++++ .../Legality/RNG/ClassicEra/Gen3/MethodH.cs | 4 +++- .../RNG/ClassicEra/Gen4/GenerateMethodJ.cs | 20 ++++++++++--------- .../RNG/ClassicEra/Gen4/GenerateMethodK.cs | 7 +++++++ .../Legality/RNG/ClassicEra/Gen4/MethodJ.cs | 6 ++++-- .../Legality/RNG/ClassicEra/Gen4/MethodK.cs | 4 +++- 6 files changed, 38 insertions(+), 13 deletions(-) diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/GenerateMethodH.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/GenerateMethodH.cs index d0a479102..b39b717f0 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/GenerateMethodH.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/GenerateMethodH.cs @@ -13,10 +13,17 @@ public static class GenerateMethodH var gr = pi.Gender; var ability = criteria.GetAbilityFromNumber(AbilityPermission.Any12); var (min, max) = SlotMethodH.GetRange(enc.Type, enc.SlotNumber); + bool checkProc = MethodH.IsEncounterCheckApplicable(enc.Type); // Generate Method H correlated PID and IVs, no lead (keep things simple). while (true) { + if (checkProc) + { + var check = new LeadSeed(seed, LeadRequired.None); + if (!MethodH.CheckEncounterActivation(enc, ref check)) + continue; + } var esv = LCRNG.Next16(ref seed) % 100; if (esv < min || esv > max) continue; @@ -116,6 +123,7 @@ public static class GenerateMethodH pk.PID = pid; pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF); + pk.RefreshAbility((int)(pid & 1)); return true; } @@ -142,6 +150,7 @@ public static class GenerateMethodH pk.PID = pid; pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF); + pk.RefreshAbility((int)(pid & 1)); return true; } @@ -221,6 +230,7 @@ public static class GenerateMethodH var iv1 = LCRNG.Next16(ref rand); var iv2 = LCRNG.Next16(ref rand); pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF); + pk.RefreshAbility((int)(pid & 1)); } private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria) diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/MethodH.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/MethodH.cs index 6d3aaeb43..6f53cbd49 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/MethodH.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen3/MethodH.cs @@ -202,7 +202,9 @@ public static class MethodH return default; } - private static bool CheckEncounterActivation(T enc, ref LeadSeed result) + public static bool IsEncounterCheckApplicable(SlotType3 type) => type is Rock_Smash; // Fishing can use Sticky/Suction along with Friendship boost. + + public static bool CheckEncounterActivation(T enc, ref LeadSeed result) where T : IEncounterSlot3 { if (enc.Type is Rock_Smash) diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodJ.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodJ.cs index c05786826..a9f3d874a 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodJ.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodJ.cs @@ -23,10 +23,17 @@ public static class GenerateMethodJ var ability = criteria.GetAbilityFromNumber(AbilityPermission.Any12); var (min, max) = SlotMethodJ.GetRange(enc.Type, enc.SlotNumber); bool randLevel = MethodJ.IsLevelRand(enc); + bool checkProc = MethodJ.IsEncounterCheckApplicable(enc.Type); // Generate Method J correlated PID and IVs, no lead (keep things simple). while (true) { + if (checkProc) + { + var check = new LeadSeed(seed, LeadRequired.None); + if (!MethodJ.CheckEncounterActivation(enc, ref check)) + continue; + } var esv = LCRNG.Next16(ref seed) / 656; if (esv < min || esv > max) continue; @@ -55,7 +62,10 @@ public static class GenerateMethodJ : ((lv % (enc.LevelMax - enc.LevelMin + 1)) + enc.LevelMin); pk.MetLevel = pk.CurrentLevel = (byte)lvl; } - SetPIDIVSequential(pk, pid, seed); + pk.PID = pid; + var iv1 = LCRNG.Next16(ref seed); + var iv2 = LCRNG.Next16(ref seed); + pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF); pk.Gender = gender; pk.Ability = (pid & 1) == 0 ? pi.Ability1 : pi.Ability2; return LCRNG.Prev4(seed); @@ -112,14 +122,6 @@ public static class GenerateMethodJ public static uint GetPIDRegular(uint a, uint b) => b << 16 | a; - private static void SetPIDIVSequential(PK4 pk, uint pid, uint rand) - { - pk.PID = pid; - var iv1 = LCRNG.Next16(ref rand); - var iv2 = LCRNG.Next16(ref rand); - pk.IV32 = ((iv2 & 0x7FFF) << 15) | (iv1 & 0x7FFF); - } - private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria) { uint iv1 = (uint)criteria.IV_HP | (uint)criteria.IV_ATK << 5 | (uint)criteria.IV_DEF << 10; diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs index 705f98aee..6e25215a5 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs @@ -24,10 +24,17 @@ public static class GenerateMethodK var (min, max) = SlotMethodK.GetRange(enc.Type, enc.SlotNumber); bool randLevel = MethodK.IsLevelRand(enc); var modulo = enc.Type.IsSafari() ? 10 : 100; + bool checkProc = MethodK.IsEncounterCheckApplicable(enc.Type); // Generate Method K correlated PID and IVs, no lead (keep things simple). while (true) { + if (checkProc) + { + var check = new LeadSeed(seed, LeadRequired.None); + if (!MethodK.CheckEncounterActivation(enc, ref check)) + continue; + } var esv = LCRNG.Next16(ref seed) % modulo; if (esv < min || esv > max) continue; diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodJ.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodJ.cs index 2b345ee6b..2644e30f2 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodJ.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodJ.cs @@ -93,7 +93,9 @@ public static class MethodJ } } - private static bool CheckEncounterActivation(T enc, ref LeadSeed result) + public static bool IsEncounterCheckApplicable(SlotType4 type) => type is HoneyTree || type.IsFishingRodType(); + + public static bool CheckEncounterActivation(T enc, ref LeadSeed result) where T : IEncounterSlot4 { if (enc.Type.IsFishingRodType()) @@ -146,7 +148,7 @@ public static class MethodJ // This occurs in Mt. Coronet B1F; if passed, check if the player is on a Feebas tile before replacing. // 0 - Hook // 1 - CheckTiles -- current seed - // 2- ESV + // 2 - ESV if (s4.Species is (int)Species.Feebas && !IsFeebasChance(result >> 16)) return false; diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodK.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodK.cs index 66e3bd597..a85c7a2c4 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodK.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/MethodK.cs @@ -90,7 +90,9 @@ public static class MethodK } } - private static bool CheckEncounterActivation(T enc, ref LeadSeed result) + public static bool IsEncounterCheckApplicable(SlotType4 type) => type is Rock_Smash or BugContest || type.IsFishingRodType(); + + public static bool CheckEncounterActivation(T enc, ref LeadSeed result) where T : IEncounterSlot4 { if (enc.Type.IsFishingRodType())