namespace PKHeX.Core; /// /// Generation 3 & 4 RNG logic. /// public static class ClassicEraRNG { /// /// Generate a chain shiny PID for the provided trainer ID. /// /// Seed to use for the RNG. /// Trainer ID to use for the PID generation. /// Shiny PID. /// Consumes 15 RNG calls public static uint GetChainShinyPID(ref uint seed, in uint id32) { // 1 3-bit for lower // 1 3-bit for upper // 13 rand bits uint lower = LCRNG.Next16(ref seed) & 7; uint upper = LCRNG.Next16(ref seed) & 7; for (int i = 3; i < 16; i++) lower |= (LCRNG.Next16(ref seed) & 1) << i; var tid16 = (ushort)(id32 & 0xFFFFu); var sid16 = (ushort)(id32 >> 16); upper = ((lower ^ tid16 ^ sid16) & 0xFFF8) | (upper & 0x7); return (upper << 16) | lower; } /// /// Rolls the RNG forward twice to get the usual Method 1 call-ordered PID. /// /// Seed right before the first PID call. /// 32-bit value containing the PID (high | low). public static uint GetSequentialPID(ref uint seed) { var rand1 = LCRNG.Next16(ref seed); var rand2 = LCRNG.Next16(ref seed); return (rand2 << 16) | rand1; } /// /// Rolls the RNG forward twice to get the usual Method 1 call-ordered PID. /// /// Seed right before the first PID call. /// 32-bit value containing the PID (high | low). public static uint GetSequentialPID(uint seed) { var rand1 = LCRNG.Next16(ref seed); var rand2 = LCRNG.Next16(ref seed); return (rand2 << 16) | rand1; } /// /// Rolls the RNG forward twice to get the reverse Method 1 call-ordered PID. /// /// Seed right before the first PID call. /// Generation 3 Unown /// 32-bit value containing the PID (high | low). public static uint GetReversePID(ref uint seed) { var rand1 = LCRNG.Next16(ref seed); var rand2 = LCRNG.Next16(ref seed); return (rand2 << 16) | rand1; } /// /// Rolls the RNG forward twice to get the reverse Method 1 call-ordered PID. /// /// Seed right before the first PID call. /// Generation 3 Unown /// 32-bit value containing the PID (high | low). public static uint GetReversePID(uint seed) { var rand1 = LCRNG.Next16(ref seed); var rand2 = LCRNG.Next16(ref seed); return (rand1 << 16) | rand2; } /// /// Generates IVs for a given seed. /// /// Seed to use for the RNG. /// 32-bit value containing the IVs (HABSCD, low->high). public static uint GetSequentialIVs(ref uint seed) { var rand1 = LCRNG.Next16(ref seed); var rand2 = LCRNG.Next16(ref seed); return (rand2 << 15) | rand1; } }