public static bool ValidateOverworldEncounter(PKM pk, uint seed, Shiny shiny = Shiny.FixedValue, int flawless = -1) { // is the seed Xoroshiro determined, or just truncated state? if (seed == uint.MaxValue) { return(false); } var xoro = new Xoroshiro128Plus(seed); var ec = (uint)xoro.NextInt(uint.MaxValue); if (ec != pk.EncryptionConstant) { return(false); } var pid = (uint)xoro.NextInt(uint.MaxValue); if (!IsPIDValid(pk, pid, shiny)) { return(false); } var actualCount = flawless == -1 ? GetIsMatchEnd(pk, xoro) : GetIsMatchEnd(pk, xoro, flawless, flawless); return(actualCount != NoMatchIVs); }
public static void GetShinyIVs(Xoroshiro128Plus rng, out uint[,] frameIVs) { frameIVs = new uint[5, 6]; Xoroshiro128Plus origrng = rng; for (int ivcount = 0; ivcount < 5; ivcount++) { int i = 0; int[] ivs = { -1, -1, -1, -1, -1, -1 }; while (i < ivcount + 1) { var stat = (int)rng.NextInt(6); if (ivs[stat] == -1) { ivs[stat] = 31; i++; } } for (int j = 0; j < 6; j++) { if (ivs[j] == -1) { ivs[j] = (int)rng.NextInt(32); } frameIVs[ivcount, j] = (uint)ivs[j]; } rng = origrng; } }
public static void GetNature(Xoroshiro128Plus rng, uint species, uint altform, out uint nature) { nature = species switch { 849 => altform == 0 ? (uint)TradeExtensions.Amped[rng.NextInt(13)] : (uint)TradeExtensions.LowKey[rng.NextInt(12)], _ => (uint)rng.NextInt(25), }; }
public static Xoroshiro128Plus GetAbility(Xoroshiro128Plus rng, uint nestAbility, out uint ability) { ability = nestAbility switch { 4 => (uint)rng.NextInt(3), 3 => (uint)rng.NextInt(2), _ => nestAbility, }; return(rng); }
public static void GetShinyFrames(ulong seed, out int[] frames, out uint[] type, out List <uint[, ]> IVs, SeedCheckResults mode) { int shinyindex = 0; frames = new int[3]; type = new uint[3]; IVs = new List <uint[, ]>(); bool foundStar = false; bool foundSquare = false; var rng = new Xoroshiro128Plus(seed); for (int i = 0; ; i++) { uint _ = (uint)rng.NextInt(0xFFFFFFFF); // EC uint SIDTID = (uint)rng.NextInt(0xFFFFFFFF); uint PID = (uint)rng.NextInt(0xFFFFFFFF); var shinytype = GetShinyType(PID, SIDTID); // If we found a shiny, record it and return if we got everything we wanted. if (shinytype != 0) { if (shinytype == 1) { foundStar = true; } else if (shinytype == 2) { foundSquare = true; } if (shinyindex == 0 || mode == SeedCheckResults.FirstThree || (foundStar && foundSquare)) { frames[shinyindex] = i; type[shinyindex] = shinytype; GetShinyIVs(rng, out uint[,] frameIVs); IVs.Add(frameIVs); shinyindex++; } if (mode == SeedCheckResults.ClosestOnly || (mode == SeedCheckResults.FirstStarAndSquare && foundStar && foundSquare) || shinyindex >= 3) { return; } } // Get the next seed, and reset for the next iteration rng = new Xoroshiro128Plus(seed); seed = rng.Next(); rng = new Xoroshiro128Plus(seed); } }
/// <summary> /// Obtains the original seed for the Generation 8 overworld wild encounter. /// </summary> /// <param name="pk">Entity to check for</param> /// <returns>Seed</returns> public static uint GetOriginalSeed(PKM pk) { var seed = pk.EncryptionConstant - unchecked((uint)Xoroshiro128Plus.XOROSHIRO_CONST); if (seed == 0xD5B9C463) // Collision seed with the 0xFFFFFFFF re-roll. { var xoro = new Xoroshiro128Plus(seed); /* ec */ xoro.NextInt(uint.MaxValue); var pid = xoro.NextInt(uint.MaxValue); if (pid != pk.PID) return 0xDD6295A4; } return seed; }
public static Xoroshiro128Plus GetIVs(Xoroshiro128Plus rng, uint[] ivs, uint guaranteedIVs, out uint[,] allIVs, out bool match) { Xoroshiro128Plus origrng = rng; GetShinyIVs(rng, out allIVs); rng = origrng; uint[] ivRow = new uint[6] { 255, 255, 255, 255, 255, 255 }; List <bool> ivCheck = new(); for (uint fixedIV = 0; fixedIV < guaranteedIVs;) { uint index = (uint)rng.NextInt(6); if (ivRow[index] == 255) { ivRow[index] = 31; fixedIV++; } } for (int rand = 0; rand < 6; rand++) { if (ivRow[rand] == 255) { ivRow[rand] = (uint)rng.NextInt(32); } } for (int i = 0; i < 6; i++) { if (ivs[i] != 255) { ivCheck.Add(ivs[i] == allIVs[guaranteedIVs - 1, i]); } } if (ivCheck.Contains(false)) { match = false; } else { match = true; } return(rng); }
public static int GetNextShinyFrame(ulong seed, out uint type, out int star, out int square) { star = -1; square = -1; var rng = new Xoroshiro128Plus(seed); for (int i = 0; ; i++) { uint _ = (uint)rng.NextInt(0xFFFFFFFF); // EC uint SIDTID = (uint)rng.NextInt(0xFFFFFFFF); uint PID = (uint)rng.NextInt(0xFFFFFFFF); type = GetShinyType(PID, SIDTID); if (star == -1) { if (type == 1) { star = i; } } if (square == -1) { if (type == 2) { square = i; } } // Get the next seed, and reset for the next iteration rng = new Xoroshiro128Plus(seed); seed = rng.Next(); rng = new Xoroshiro128Plus(seed); if (i > 100_000) { return(star & square); } else if (star != -1 && square != -1) { return(star & square); } } }
public static string GetCurrentFrameInfo(DenUtil.RaidData raidInfo, uint flawlessIVs, ulong seed, out uint shinyType, bool raid = true) { var rng = new Xoroshiro128Plus(seed); _ = (uint)rng.NextInt(0xFFFFFFFF); uint SIDTID = (uint)rng.NextInt(0xFFFFFFFF); uint PID = (uint)rng.NextInt(0xFFFFFFFF); shinyType = GetShinyType(PID, SIDTID); var IVs = new uint[] { 255, 255, 255, 255, 255, 255 }; GetIVs(rng, IVs, flawlessIVs, out uint[,] allIVs, out _); uint[] ivs = new uint[6]; for (int i = 0; i < 6; i++) { ivs[i] = allIVs[flawlessIVs - 1, i]; } return(DenUtil.IVSpreadByStar(GetIVSpread(allIVs), raidInfo, ivs, seed, raid)); }
public static int GetNextShinyFrame(ulong seed, out uint type) { var rng = new Xoroshiro128Plus(seed); for (int i = 0; ; i++) { uint _ = (uint)rng.NextInt(0xFFFFFFFF); // EC uint SIDTID = (uint)rng.NextInt(0xFFFFFFFF); uint PID = (uint)rng.NextInt(0xFFFFFFFF); type = GetShinyType(PID, SIDTID); if (type != 0) { return(i); } // Get the next seed, and reset for the next iteration rng = new Xoroshiro128Plus(seed); seed = rng.Next(); rng = new Xoroshiro128Plus(seed); } }
public static Xoroshiro128Plus GetGender(Xoroshiro128Plus rng, GenderRatio ratio, uint genderIn, out uint gender) { gender = genderIn switch { 0 => ratio == GenderRatio.Genderless ? 2 : ratio == GenderRatio.Female ? 1 : ratio == GenderRatio.Male ? 0 : ((rng.NextInt(253) + 1) < (uint)ratio ? (uint)GenderType.Female : (uint)GenderType.Male), 1 => 0, 2 => 1, 3 => 2, _ => (rng.NextInt(253) + 1) < (uint)ratio ? (uint)GenderType.Female : (uint)GenderType.Male, }; return(rng); }
public static bool IsMatch(ulong seed, int[] ivs, int fixed_ivs) { var rng = new Xoroshiro128Plus(seed); rng.NextInt(); // EC rng.NextInt(); // TID rng.NextInt(); // PID int[] check_ivs = { -1, -1, -1, -1, -1, -1 }; for (int i = 0; i < fixed_ivs; i++) { uint slot; do { slot = (uint)rng.NextInt(6); } while (check_ivs[slot] != -1); if (ivs[slot] != 31) { return(false); } check_ivs[slot] = 31; } for (int i = 0; i < 6; i++) { if (check_ivs[i] != -1) { continue; // already verified? } uint iv = (uint)rng.NextInt(32); if (iv != ivs[i]) { return(false); } } return(true); }
private static bool IsValidSequence(PKM pk, int[] template, ref Xoroshiro128Plus rng) { for (int i = 0; i < 6; i++) { var temp = template[i]; var expect = temp == UNSET ? (int)rng.NextInt(32) : temp; var actual = i switch { 0 => pk.IV_HP, 1 => pk.IV_ATK, 2 => pk.IV_DEF, 3 => pk.IV_SPA, 4 => pk.IV_SPD, _ => pk.IV_SPE, }; if (expect != actual) return false; } return true; }
private static bool TryApplyFromSeed(PKM pk, EncounterCriteria criteria, Shiny shiny, int flawless, uint seed) { var xoro = new Xoroshiro128Plus(seed); // Encryption Constant pk.EncryptionConstant = (uint)xoro.NextInt(uint.MaxValue); // PID var pid = (uint)xoro.NextInt(uint.MaxValue); if (shiny == Shiny.Never) { if (GetIsShiny(pk.TID, pk.SID, pid)) { pid ^= 0x1000_0000; } } else if (shiny != Shiny.Random) { if (!GetIsShiny(pk.TID, pk.SID, pid)) { pid = GetShinyPID(pk.TID, pk.SID, pid, 0); } if (shiny == Shiny.AlwaysSquare && pk.ShinyXor != 0) { return(false); } if (shiny == Shiny.AlwaysStar && pk.ShinyXor == 0) { return(false); } } pk.PID = pid; // IVs var ivs = new[] { UNSET, UNSET, UNSET, UNSET, UNSET, UNSET }; const int MAX = 31; for (int i = 0; i < flawless; i++) { int index; do { index = (int)xoro.NextInt(6); }while (ivs[index] != UNSET); ivs[index] = MAX; } for (int i = 0; i < ivs.Length; i++) { if (ivs[i] == UNSET) { ivs[i] = (int)xoro.NextInt(32); } } if (!criteria.IsIVsCompatible(ivs, 8)) { return(false); } pk.IV_HP = ivs[0]; pk.IV_ATK = ivs[1]; pk.IV_DEF = ivs[2]; pk.IV_SPA = ivs[3]; pk.IV_SPD = ivs[4]; pk.IV_SPE = ivs[5]; // Remainder var scale = (IScaledSize)pk; scale.HeightScalar = (int)xoro.NextInt(0x81) + (int)xoro.NextInt(0x80); scale.WeightScalar = (int)xoro.NextInt(0x81) + (int)xoro.NextInt(0x80); return(true); }
public static PK8 CalculateFromSeed(PK8 pk, Shiny shiny, int flawless, uint seed) { var xoro = new Xoroshiro128Plus(seed); // Encryption Constant pk.EncryptionConstant = (uint)xoro.NextInt(uint.MaxValue); // PID var pid = (uint)xoro.NextInt(uint.MaxValue); if (shiny == Shiny.Never) { if (GetIsShiny(pk.TID, pk.SID, pid)) { pid ^= 0x1000_0000; } } else if (shiny != Shiny.Random) { if (!GetIsShiny(pk.TID, pk.SID, pid)) { pid = GetShinyPID(pk.TID, pk.SID, pid, 0); } } pk.PID = pid; // IVs var ivs = new[] { UNSET, UNSET, UNSET, UNSET, UNSET, UNSET }; const int MAX = 31; for (int i = 0; i < flawless; i++) { int index; do { index = (int)xoro.NextInt(6); }while (ivs[index] != UNSET); ivs[index] = MAX; } for (int i = 0; i < ivs.Length; i++) { if (ivs[i] == UNSET) { ivs[i] = (int)xoro.NextInt(32); } } pk.IV_HP = ivs[0]; pk.IV_ATK = ivs[1]; pk.IV_DEF = ivs[2]; pk.IV_SPA = ivs[3]; pk.IV_SPD = ivs[4]; pk.IV_SPE = ivs[5]; // Size var scale = (IScaledSize)pk; scale.HeightScalar = (int)xoro.NextInt(0x81) + (int)xoro.NextInt(0x80); scale.WeightScalar = (int)xoro.NextInt(0x81) + (int)xoro.NextInt(0x80); return(pk); }