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