From f1db88026bc47d11f91e7c2dd5cd7fcaf3fdb5b1 Mon Sep 17 00:00:00 2001 From: Kurt Date: Mon, 1 May 2017 08:37:23 -0700 Subject: [PATCH] Add frlg unown PIDIV type The modified form-finding routine generates the PID gen halves in the reverse order like events. Due to possible collisions with event PIDIVs, only run it for unown (since that's all it applies to); the analyzing of PIDIVs to find incorrect usages isn't really feasible (collision) for this one. #1103 --- PKHeX/Legality/RNG/MethodFinder.cs | 37 ++++++++++++++++++++++++++++++ PKHeX/Legality/RNG/PIDType.cs | 6 +++++ Tests/PKHeX.Tests/PKM/PKMTests.cs | 22 ++++++++++++++++++ 3 files changed, 65 insertions(+) diff --git a/PKHeX/Legality/RNG/MethodFinder.cs b/PKHeX/Legality/RNG/MethodFinder.cs index b2812da13..8ed37005f 100644 --- a/PKHeX/Legality/RNG/MethodFinder.cs +++ b/PKHeX/Legality/RNG/MethodFinder.cs @@ -32,6 +32,8 @@ public static PIDIV Analyze(PKM pk) PIDIV pidiv; if (getLCRNGMatch(top, bot, IVs, out pidiv)) return pidiv; + if (pk.Species == 201 && getLCRNGUnownMatch(top, bot, IVs, out pidiv)) // frlg only + return pidiv; if (getXDRNGMatch(top, bot, IVs, out pidiv)) return pidiv; @@ -90,6 +92,41 @@ private static bool getLCRNGMatch(uint top, uint bot, uint[] IVs, out PIDIV pidi pidiv = null; return false; } + private static bool getLCRNGUnownMatch(uint top, uint bot, uint[] IVs, out PIDIV pidiv) + { + // this is an exact copy of LCRNG 1,2,4 matching, except the PID has its halves switched (BACD, BADE, BACE) + var reg = getSeedsFromPID(RNG.LCRNG, bot, top); // reversed! + foreach (var seed in reg) + { + // A and B are already used by PID + var B = RNG.LCRNG.Advance(seed, 2); + + // Method 1/2/4 can use 3 different RNG frames + var C = RNG.LCRNG.Next(B); + var D = RNG.LCRNG.Next(C); + + if (getIVs(C >> 16, D >> 16).SequenceEqual(IVs)) // BACD + { + pidiv = new PIDIV { OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_1_Unown }; + return true; + } + + var E = RNG.LCRNG.Next(D); + if (getIVs(D >> 16, E >> 16).SequenceEqual(IVs)) // BADE + { + pidiv = new PIDIV { OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_2_Unown }; + return true; + } + + if (getIVs(C >> 16, E >> 16).SequenceEqual(IVs)) // BACE + { + pidiv = new PIDIV { OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_4_Unown }; + return true; + } + } + pidiv = null; + return false; + } private static bool getXDRNGMatch(uint top, uint bot, uint[] IVs, out PIDIV pidiv) { var xdc = getSeedsFromPID(RNG.XDRNG, bot, top); diff --git a/PKHeX/Legality/RNG/PIDType.cs b/PKHeX/Legality/RNG/PIDType.cs index b8c25ada7..d7e199d05 100644 --- a/PKHeX/Legality/RNG/PIDType.cs +++ b/PKHeX/Legality/RNG/PIDType.cs @@ -11,6 +11,12 @@ public enum PIDType Method_2, /// Method H4 Method_4, + /// Method H1_Unown (FRLG) + Method_1_Unown, + /// Method H2_Unown (FRLG) + Method_2_Unown, + /// Method H4_Unown (FRLG) + Method_4_Unown, /// /// Event Reversed Order PID restricted to 16bit Origin Seed diff --git a/Tests/PKHeX.Tests/PKM/PKMTests.cs b/Tests/PKHeX.Tests/PKM/PKMTests.cs index aeaefdc4c..01d0b81b5 100644 --- a/Tests/PKHeX.Tests/PKM/PKMTests.cs +++ b/Tests/PKHeX.Tests/PKM/PKMTests.cs @@ -254,6 +254,28 @@ public void PIDIVMatchingTest() Assert.AreEqual(true, MethodFinder.getPokeSpotSeeds(pkPS1, 1).Any(), "PokeSpot encounter info mismatch (Uncommon)"); var pkPS2 = new PK3 {PID = 0x9B667F3C}; // Surskit (Oasis) Assert.AreEqual(true, MethodFinder.getPokeSpotSeeds(pkPS2, 2).Any(), "PokeSpot encounter info mismatch (Rare)"); + + var pk1U = new PK3 + { + Species = 201, // Unown-C + PID = 0x815549A2, + IVs = new[] {02, 26, 30, 30, 11, 26} + }; + Assert.AreEqual(PIDType.Method_1_Unown, MethodFinder.Analyze(pk1U)?.Type, "Unable to match PID to Method 1 Unown spread"); + var pk2U = new PK3 + { + Species = 201, // Unown-M + PID = 0x8A7B5190, + IVs = new[] {14, 02, 21, 30, 29, 15} + }; + Assert.AreEqual(PIDType.Method_2_Unown, MethodFinder.Analyze(pk2U)?.Type, "Unable to match PID to Method 2 Unown spread"); + var pk4U = new PK3 + { + Species = 201, // Unown-C + PID = 0x5FA80D70, + IVs = new[] {02, 06, 03, 26, 04, 19} + }; + Assert.AreEqual(PIDType.Method_4_Unown, MethodFinder.Analyze(pk4U)?.Type, "Unable to match PID to Method 4 Unown spread"); } } }