mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-10-01 15:50:21 -05:00
Add gen3 roamer pidiv detection
add shiny lock for spiky eared pichu fix wurmple ECPID comparison (only continue if ALL are wurmple) slightly speed up comparison of LCRNG spreads, may be worth applying same approach to others.
This commit is contained in:
@@ -166,7 +166,7 @@ private void verifyECPIDWurmple()
|
||||
}
|
||||
|
||||
// Check if Wurmple was the origin (only Egg and Wild Encounter)
|
||||
bool wasWurmple = pkm.WasEgg || (Type == typeof (EncounterSlot[]) && ((EncounterSlot[])EncounterMatch).Any(slot => slot.Species == 265));
|
||||
bool wasWurmple = pkm.WasEgg || (Type == typeof (EncounterSlot[]) && ((EncounterSlot[])EncounterMatch).All(slot => slot.Species == 265));
|
||||
if (!wasWurmple)
|
||||
return;
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ public static PIDIV Analyze(PKM pk)
|
||||
return pidiv;
|
||||
|
||||
// Special cases
|
||||
if (getLCRNGRoamerMatch(top, bot, IVs, out pidiv))
|
||||
return pidiv;
|
||||
if (getChannelMatch(top, bot, IVs, out pidiv))
|
||||
return pidiv;
|
||||
if (getMG4Match(pid, IVs, out pidiv))
|
||||
@@ -61,6 +63,8 @@ public static PIDIV Analyze(PKM pk)
|
||||
private static bool getLCRNGMatch(uint top, uint bot, uint[] IVs, out PIDIV pidiv)
|
||||
{
|
||||
var reg = getSeedsFromPID(RNG.LCRNG, top, bot);
|
||||
var iv1 = getIVChunk(IVs, 0);
|
||||
var iv2 = getIVChunk(IVs, 3);
|
||||
foreach (var seed in reg)
|
||||
{
|
||||
// A and B are already used by PID
|
||||
@@ -68,25 +72,39 @@ private static bool getLCRNGMatch(uint top, uint bot, uint[] IVs, out PIDIV pidi
|
||||
|
||||
// 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)) // ABCD
|
||||
var ivC = C >> 16 & 0x7FFF;
|
||||
if (iv1 == ivC)
|
||||
{
|
||||
pidiv = new PIDIV {OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_1};
|
||||
return true;
|
||||
var D = RNG.LCRNG.Next(C);
|
||||
var ivD = D >> 16 & 0x7FFF;
|
||||
if (iv2 == ivD) // ABCD
|
||||
{
|
||||
pidiv = new PIDIV {OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_1};
|
||||
return true;
|
||||
}
|
||||
|
||||
var E = RNG.LCRNG.Next(D);
|
||||
var ivE = E >> 16 & 0x7FFF;
|
||||
if (iv2 == ivE) // ABCE
|
||||
{
|
||||
pidiv = new PIDIV {OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_4};
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
var E = RNG.LCRNG.Next(D);
|
||||
if (getIVs(D >> 16, E >> 16).SequenceEqual(IVs)) // ABDE
|
||||
else
|
||||
{
|
||||
pidiv = new PIDIV {OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_2};
|
||||
return true;
|
||||
}
|
||||
var D = RNG.LCRNG.Next(C);
|
||||
var ivD = D >> 16 & 0x7FFF;
|
||||
if (iv1 != ivD)
|
||||
continue;
|
||||
|
||||
if (getIVs(C >> 16, E >> 16).SequenceEqual(IVs)) // ABCE
|
||||
{
|
||||
pidiv = new PIDIV {OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_4};
|
||||
return true;
|
||||
var E = RNG.LCRNG.Next(D);
|
||||
var ivE = E >> 16 & 0x7FFF;
|
||||
if (iv2 == ivE) // ABDE
|
||||
{
|
||||
pidiv = new PIDIV {OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_2};
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
pidiv = null;
|
||||
@@ -96,6 +114,8 @@ private static bool getLCRNGUnownMatch(uint top, uint bot, uint[] IVs, out 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!
|
||||
var iv1 = getIVChunk(IVs, 0);
|
||||
var iv2 = getIVChunk(IVs, 3);
|
||||
foreach (var seed in reg)
|
||||
{
|
||||
// A and B are already used by PID
|
||||
@@ -103,30 +123,67 @@ private static bool getLCRNGUnownMatch(uint top, uint bot, uint[] IVs, out PIDIV
|
||||
|
||||
// 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
|
||||
var ivC = C >> 16 & 0x7FFF;
|
||||
if (iv1 == ivC)
|
||||
{
|
||||
pidiv = new PIDIV { OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_1_Unown };
|
||||
return true;
|
||||
}
|
||||
var D = RNG.LCRNG.Next(C);
|
||||
var ivD = D >> 16 & 0x7FFF;
|
||||
if (iv2 == ivD) // 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;
|
||||
var E = RNG.LCRNG.Next(D);
|
||||
var ivE = E >> 16 & 0x7FFF;
|
||||
if (iv2 == ivE) // BACE
|
||||
{
|
||||
pidiv = new PIDIV {OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_4_Unown};
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var D = RNG.LCRNG.Next(C);
|
||||
var ivD = D >> 16 & 0x7FFF;
|
||||
if (iv1 != ivD)
|
||||
continue;
|
||||
|
||||
if (getIVs(C >> 16, E >> 16).SequenceEqual(IVs)) // BACE
|
||||
{
|
||||
pidiv = new PIDIV { OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_4_Unown };
|
||||
return true;
|
||||
var E = RNG.LCRNG.Next(D);
|
||||
var ivE = E >> 16 & 0x7FFF;
|
||||
if (iv2 != ivE) // BADE
|
||||
{
|
||||
pidiv = new PIDIV {OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_2_Unown};
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
pidiv = null;
|
||||
return false;
|
||||
}
|
||||
private static bool getLCRNGRoamerMatch(uint top, uint bot, uint[] IVs, out PIDIV pidiv)
|
||||
{
|
||||
var iv2 = getIVChunk(IVs, 3);
|
||||
if (iv2 != 0 || IVs[2] != 0)
|
||||
{
|
||||
pidiv = null;
|
||||
return false;
|
||||
}
|
||||
var iv1 = getIVChunk(IVs, 0);
|
||||
var reg = getSeedsFromPID(RNG.LCRNG, top, bot);
|
||||
foreach (var seed in reg)
|
||||
{
|
||||
// Only the first two IVs are kept
|
||||
var ivC = RNG.LCRNG.Advance(seed, 3) >> 16 & 0x03FF;
|
||||
if (iv1 != ivC)
|
||||
continue;
|
||||
|
||||
pidiv = new PIDIV {OriginSeed = seed, RNG = RNG.LCRNG, Type = PIDType.Method_1_Roamer};
|
||||
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);
|
||||
@@ -280,8 +337,8 @@ private static bool getBACDMatch(PKM pk, uint pid, uint[] IVs, out PIDIV pidiv)
|
||||
var B = seed;
|
||||
var A = RNG.LCRNG.Prev(B);
|
||||
|
||||
var PID = A & 0xFFFF0000 | (B >> 16);
|
||||
bool isShiny = (pk.TID ^ pk.SID ^ (PID >> 16) ^ (PID & 0xFFFF)) < 8;
|
||||
var PID = A & 0xFFFF0000 | B >> 16;
|
||||
bool isShiny = (pk.TID ^ pk.SID ^ PID >> 16 ^ PID & 0xFFFF) < 8;
|
||||
bool forceShiny = false;
|
||||
if (PID != pid)
|
||||
{
|
||||
@@ -306,12 +363,12 @@ private static bool getBACDMatch(PKM pk, uint pid, uint[] IVs, out PIDIV pidiv)
|
||||
continue;
|
||||
forceShiny = true;
|
||||
}
|
||||
if (!forceShiny && ((PID + 8) & 0xFFFFFFF8) != pid)
|
||||
if (!forceShiny && (PID + 8 & 0xFFFFFFF8) != pid)
|
||||
continue;
|
||||
}
|
||||
var s = RNG.LCRNG.Prev(A);
|
||||
|
||||
// Check for Restricted generation pattern
|
||||
// Check for prior Restricted seed
|
||||
var sn = s;
|
||||
for (int i = 0; i < 3; i++, sn = RNG.LCRNG.Prev(sn))
|
||||
{
|
||||
@@ -321,7 +378,7 @@ private static bool getBACDMatch(PKM pk, uint pid, uint[] IVs, out PIDIV pidiv)
|
||||
pidiv = new PIDIV {OriginSeed = sn, RNG = RNG.LCRNG, Type = type};
|
||||
return true;
|
||||
}
|
||||
|
||||
// no restricted seed found, thus unrestricted
|
||||
var t = forceShiny ? PIDType.BACD_U_S : isShiny ? PIDType.BACD_U_A : PIDType.BACD_U;
|
||||
pidiv = new PIDIV {OriginSeed = s, RNG = RNG.LCRNG, Type = t};
|
||||
return true;
|
||||
|
||||
@@ -17,6 +17,8 @@ public enum PIDType
|
||||
Method_2_Unown,
|
||||
/// <summary> Method H4_Unown (FRLG) </summary>
|
||||
Method_4_Unown,
|
||||
/// <summary> Method 1 Roamer (Gen3) </summary>
|
||||
Method_1_Roamer,
|
||||
|
||||
/// <summary>
|
||||
/// Event Reversed Order PID restricted to 16bit Origin Seed
|
||||
|
||||
@@ -723,7 +723,7 @@ public static partial class Legal
|
||||
new EncounterStatic { Species = 143, Level = 50, Location = 159, }, //Snorlax @ Route 11
|
||||
new EncounterStatic { Species = 143, Level = 50, Location = 160, }, //Snorlax @ Route 12
|
||||
new EncounterStatic { Species = 185, Level = 20, Location = 184, }, //Sudowoodo @ Route 36, Encounter does not have type
|
||||
new EncounterStaticTyped { Species = 172, Level = 30, Location = 214, Gender = 1, Form = 1, Moves = new[]{344,270,207,220}, TypeEncounter = EncounterType.Starter_Fossil_Gift_Pt_DPTrio }, //Spiky-eared Pichu @ Ilex forest
|
||||
new EncounterStaticTyped { Species = 172, Level = 30, Location = 214, Gender = 1, Form = 1, Moves = new[]{344,270,207,220}, TypeEncounter = EncounterType.Starter_Fossil_Gift_Pt_DPTrio, Shiny = false }, //Spiky-eared Pichu @ Ilex forest
|
||||
//Stationary Lengerdary
|
||||
new EncounterStaticTyped { Species = 144, Level = 50, Location = 203, TypeEncounter = EncounterType.Cave_HallOfOrigin }, //Articuno @ Seafoam Islands
|
||||
new EncounterStatic { Species = 145, Level = 50, Location = 158, }, //Zapdos @ Route 10
|
||||
|
||||
Reference in New Issue
Block a user