From 045e289c0aca0150dc24fb2360fedf506beb2de2 Mon Sep 17 00:00:00 2001 From: Kurt Date: Mon, 11 May 2020 16:52:09 -0700 Subject: [PATCH] Account for antishiny skip on the NPC mon right before shadow pretty much a copy from the other method with simplifications --- .../Legality/RNG/Locks/TeamLockResult.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/PKHeX.Core/Legality/RNG/Locks/TeamLockResult.cs b/PKHeX.Core/Legality/RNG/Locks/TeamLockResult.cs index 86aa0a7ce..761d4611c 100644 --- a/PKHeX.Core/Legality/RNG/Locks/TeamLockResult.cs +++ b/PKHeX.Core/Legality/RNG/Locks/TeamLockResult.cs @@ -121,6 +121,45 @@ private IEnumerable GetSingleLock(int ctr, NPCLock current) uint pid = Cache[ctr + 1] << 16 | Cache[ctr]; if (current.MatchesLock(pid)) yield return new SeedFrame(pid, ctr + (current.Seen ? 5 : 7)); + else + yield break; + + // Reaching here means the single lock didn't cut it. Maybe the frame before it was an anti-shiny reroll? + + // Track if we ever require the CPU Trainer Shiny Value to be a value for a shiny skip. + // We need to un-set this flag if future frames don't pan out. + bool forcedOT = false; + + int start = 2; + while (true) + { + var upper = Cache[start + 1]; + var lower = Cache[start]; + // uint cid = upper << 16 | lower; + var sv = (upper ^ lower) >> 3; + if (sv == TSV) // XD shiny checks all opponent PKM, even non-shadow. + { + // Anti-shiny rerolled! This is a possible frame. + } + else if (RCSV != NOT_FORCED) // CPU shiny value is required for a previous lock + { + if (sv != RCSV) + { + if (forcedOT) // current call to this method had forced the OT; clear the forced OT before breaking. + RCSV = NOT_FORCED; + yield break; // Since we can't skip this interrupt, we're done. + } + else // No CPU shiny value forced yet. Lets try to skip this lock by requiring the eventual OT to get this shiny. + { + RCSV = (int)sv; + forcedOT = true; + // don't break + } + } + // Yield the final rerolled pid instead of the bad anti-shiny (metadata/validation). + yield return new SeedFrame(pid, start + (current.Seen ? 5 : 7)); + start += 2; + } } ///