private static void SetValuesFromSeedLCRNG(PKM pk, PIDType type, uint seed) { var rng = RNG.LCRNG; var A = rng.Next(seed); var B = rng.Next(A); pk.PID = B & 0xFFFF0000 | A >> 16; var skipIV1Frame = type == PIDType.Method_2 || type == PIDType.Method_2_Unown; if (skipIV1Frame) { B = rng.Next(B); } var C = rng.Next(B); var D = rng.Next(C); var skipIV2Frame = type == PIDType.Method_4 || type == PIDType.Method_4_Unown; if (skipIV2Frame) { D = rng.Next(D); } pk.IVs = MethodFinder.GetIVsInt32(C >> 16, D >> 16); }
private static bool IsG4ManaphyPIDValid(PIDType val, PKM pkm) { if (pkm.IsEgg) { if (pkm.IsShiny) { return(false); } if (val == PIDType.Method_1) { return(true); } return(val == PIDType.G4MGAntiShiny && IsAntiShinyARNG()); } if (val == PIDType.Method_1) { return(pkm.WasTradedEgg || !pkm.IsShiny); // can't be shiny on received game } return(val == PIDType.G4MGAntiShiny && (pkm.WasTradedEgg || IsAntiShinyARNG())); bool IsAntiShinyARNG() { var shinyPID = RNG.ARNG.Prev(pkm.PID); return((pkm.TID ^ pkm.SID ^ (shinyPID & 0xFFFF) ^ (shinyPID >> 16)) < 8); // shiny proc } }
private static void SetValuesFromSeedBACD(PKM pk, PIDType type, uint seed) { var rng = RNG.LCRNG; bool shiny = type == PIDType.BACD_R_S || type == PIDType.BACD_U_S; uint X = shiny ? rng.Next(seed) : seed; var A = rng.Next(X); var B = rng.Next(A); var C = rng.Next(B); var D = rng.Next(C); if (shiny) { uint PID; PID = X & 0xFFFF0000 | (uint)pk.SID ^ (uint)pk.TID ^ X >> 16; PID &= 0xFFFFFFF8; PID |= B >> 16 & 0x7; // lowest 3 bits pk.PID = PID; } else { pk.PID = A & 0xFFFF0000 | B >> 16; } pk.IVs = MethodFinder.GetIVsInt32(C >> 16, D >> 16); bool antishiny = type == PIDType.BACD_R_A || type == PIDType.BACD_U_A; while (antishiny && pk.IsShiny) { pk.PID = unchecked (pk.PID + 1); } }
private static bool IsBACD_U_AX(uint idxor, uint pid, uint low, uint A, ref PIDType type) { if ((pid & 0xFFFF) != low) { return(false); } // 0-Origin // 1-ushort rnd, do until >8 // 2-PIDL uint rnd = A >> 16; if (rnd < 8) { return(false); } uint PID = ((rnd ^ idxor ^ low) << 16) | low; if (PID != pid) { return(false); } type = PIDType.BACD_U_AX; return(true); }
/// <summary> /// Method to set PID, IV while validating nature. /// </summary> /// <param name="pk">PKM to modify</param> /// <param name="Method">Given Method</param> /// <param name="HPType">HPType INT for preserving Hidden powers</param> /// <param name="originalPKMN"></param> public static void FindPIDIV(PKM pk, PIDType Method, int HPType, PKM originalPKMN) { if (Method == PIDType.None) { Method = FindLikelyPIDType(pk, originalPKMN); if (pk.Version == 15) { Method = PIDType.CXD; } if (Method == PIDType.None) { pk.SetPIDGender(pk.Gender); } } PKM iterPKM = pk; while (Method != PIDType.None) { uint seed = Util.Rand32(); PIDGenerator.SetValuesFromSeed(pk, Method, seed); if (!(pk.Ability == iterPKM.Ability && pk.AbilityNumber == iterPKM.AbilityNumber && pk.Nature == iterPKM.Nature)) { continue; } if (pk.PID % 25 == iterPKM.Nature && pk.HPType == HPType) // Util.Rand32 is the way to go { break; } pk = iterPKM; } }
public static void Gen4Shiny(this PKM pkm, Shiny shinyType) { if (pkm.GenNumber == 3) { if (pkm.Met_Location == 55 && pkm.Ball == 4) { pkm.SetPIDGender(pkm.Gender); CommonEdits.SetShiny(pkm, shinyType); return; } Gen3Shiny(pkm, shinyType); return; } RNG rng = RNG.LCRNG; PIDType type = PIDType.Method_1; if (pkm.Met_Location == 233) { type = PIDType.Pokewalker; } IEnumerable <uint> seeds; do { pkm.SetPIDGender(pkm.Gender); CommonEdits.SetShiny(pkm, shinyType); seeds = GetSeedsFromPID(pkm.PID, rng); } while (!pkm.IsShiny || seeds == null); PIDGenerator.SetValuesFromSeed(pkm, type, seeds.ElementAt(0)); }
public static void Gen5UnShiny(this PKM pkm) { var generation = pkm.GenNumber; if (generation == 3) { if (pkm.Met_Location == Locations.Transfer4 && pkm.Ball == 4) { pkm.SetPIDGender(pkm.Gender); return; } Gen3UnShiny(pkm); return; } RNG rng = RNG.LCRNG; PIDType type = PIDType.Method_1; IEnumerable <uint> seeds = null; do { pkm.SetPIDGender(pkm.Gender); seeds = GetSeedsFromPID(pkm.PID, rng); } while (pkm.IsShiny || seeds == null); PIDGenerator.SetValuesFromSeed(pkm, type, seeds.ElementAt(0)); }
public static void Gen3UnShiny(this PKM pkm) { RNG rng = RNG.LCRNG; PIDType type = PIDType.Method_1; if (pkm.Version == (int)GameVersion.CXD) { rng = RNG.XDRNG; type = PIDType.CXD; } IEnumerable <uint> seeds; do { pkm.SetPIDGender(pkm.Gender); seeds = GetSeedsFromPID(pkm.PID, rng); } while (pkm.IsShiny || seeds == null); if (pkm.Species == 201) { type = PIDType.Method_1_Unown; } PIDGenerator.SetValuesFromSeed(pkm, type, seeds.ElementAt(0)); }
/// <summary> /// Method to set PID, IV while validating nature. /// </summary> /// <param name="pk">PKM to modify</param> /// <param name="Method">Given Method</param> /// <param name="HPType">HPType INT for preserving Hidden powers</param> private static void FindPIDIV(PKM pk, PIDType Method, int HPType) { if (Method == PIDType.None) { Method = FindLikelyPIDType(pk); if (pk.Version == 15) { Method = PIDType.CXD; } if (Method == PIDType.None) { pk.SetPIDGender(pk.Gender); } } var iterPKM = pk.Clone(); while (true) { uint seed = Util.Rand32(); PIDGenerator.SetValuesFromSeed(pk, Method, seed); if (!(pk.Ability == iterPKM.Ability && pk.AbilityNumber == iterPKM.AbilityNumber && pk.Nature == iterPKM.Nature)) { continue; } if (HPType >= 0 && pk.HPType != HPType) { continue; } if (pk.PID % 25 != iterPKM.Nature) // Util.Rand32 is the way to go { continue; } break; } }
public static void SetValuesFromSeed(PKM pk, PIDType type, uint seed) { switch (type) { case PIDType.Channel: SetValuesFromSeedChannel(pk, seed); break; case PIDType.CXD: SetValuesFromSeedXDRNG(pk, seed); break; case PIDType.Method_1: case PIDType.Method_2: case PIDType.Method_4: SetValuesFromSeedLCRNG(pk, type, seed); break; case PIDType.BACD_R: case PIDType.BACD_R_A: case PIDType.BACD_R_S: SetValuesFromSeedBACD(pk, type, seed); break; case PIDType.BACD_U: case PIDType.BACD_U_A: case PIDType.BACD_U_S: SetValuesFromSeedBACD(pk, type, seed); break; // others: unimplemented case PIDType.ChainShiny: break; case PIDType.Method_1_Unown: case PIDType.Method_2_Unown: case PIDType.Method_4_Unown: break; case PIDType.Method_1_Roamer: break; case PIDType.CuteCharm: break; case PIDType.PokeSpot: break; case PIDType.G4MGAntiShiny: break; case PIDType.G5MGShiny: break; case PIDType.Pokewalker: break; } }
/// <summary> /// Method to set PID, IV while validating nature. /// </summary> /// <param name="pk">PKM to modify</param> /// <param name="Method">Given Method</param> /// <param name="HPType">HPType INT for preserving Hidden powers</param> private static void FindPIDIV(PKM pk, PIDType Method, int HPType) { if (Method == PIDType.None) { Method = FindLikelyPIDType(pk); if (pk.Version == (int)GameVersion.CXD && Method != PIDType.PokeSpot) { Method = PIDType.CXD; } if (Method == PIDType.None) { pk.SetPIDGender(pk.Gender); } } if (Method == PIDType.Method_1_Roamer && pk.HPType != (int)MoveType.Fighting - 1) // M1 Roamers can only be HP fighting { return; } if (Method == PIDType.Pokewalker && (pk.Nature >= 24 || pk.AbilityNumber == 4)) // No possible pokewalker matches { return; } var iterPKM = pk.Clone(); while (true) { uint seed = Util.Rand32(); if (PokeWalkerSeedFail(seed, Method, pk, iterPKM)) { continue; } PIDGenerator.SetValuesFromSeed(pk, Method, seed); if (!(pk.Ability == iterPKM.Ability && pk.AbilityNumber == iterPKM.AbilityNumber && pk.Nature == iterPKM.Nature)) { continue; } if (HPType >= 0 && pk.HPType != HPType) { continue; } if (pk.PID % 25 != iterPKM.Nature) // Util.Rand32 is the way to go { continue; } if (pk.Version == (int)GameVersion.CXD && Method == PIDType.CXD) // verify locks { pk.EncryptionConstant = pk.PID; var la = new LegalityAnalysis(pk); if (la.Info.PIDIV.Type != PIDType.CXD || !la.Info.PIDIVMatches) { continue; } } break; } }
private static Action <PKM, uint> GetGeneratorMethod(PIDType t) { switch (t) { case PIDType.Channel: return(SetValuesFromSeedChannel); case PIDType.CXD: return(SetValuesFromSeedXDRNG); case PIDType.Method_1: case PIDType.Method_2: case PIDType.Method_3: case PIDType.Method_4: case PIDType.Method_1_Unown: case PIDType.Method_2_Unown: case PIDType.Method_3_Unown: case PIDType.Method_4_Unown: case PIDType.Method_1_Roamer: return((pk, seed) => SetValuesFromSeedLCRNG(pk, t, seed)); case PIDType.BACD_R: case PIDType.BACD_R_A: case PIDType.BACD_R_S: case PIDType.BACD_R_AX: return((pk, seed) => SetValuesFromSeedBACD(pk, t, seed & 0xFFFF)); case PIDType.BACD_U: case PIDType.BACD_U_A: case PIDType.BACD_U_S: case PIDType.BACD_U_AX: return((pk, seed) => SetValuesFromSeedBACD(pk, t, seed)); case PIDType.PokeSpot: return(SetRandomPIDIV); case PIDType.G5MGShiny: return(SetValuesFromSeedMG5Shiny); case PIDType.Pokewalker: return((pk, seed) => pk.PID = GetPokeWalkerPID(pk.TID, pk.SID, seed % 24, pk.Gender, pk.PersonalInfo.Gender)); // others: unimplemented case PIDType.CuteCharm: break; case PIDType.ChainShiny: return(SetRandomChainShinyPID); case PIDType.G4MGAntiShiny: break; } return((_, __) => { }); }
private static void SetValuesFromSeedLCRNG(PKM pk, PIDType type, uint seed) { var rng = RNG.LCRNG; var A = rng.Next(seed); var B = rng.Next(A); var skipBetweenPID = type is PIDType.Method_3 or PIDType.Method_3_Unown; if (skipBetweenPID) // VBlank skip between PID rand() [RARE] { B = rng.Next(B); } var swappedPIDHalves = type is >= PIDType.Method_1_Unown and <= PIDType.Method_4_Unown; if (swappedPIDHalves) // switched order of PID halves, "BA.." { pk.PID = (A & 0xFFFF0000) | (B >> 16); } else { pk.PID = (B & 0xFFFF0000) | (A >> 16); } var C = rng.Next(B); var skipIV1Frame = type is PIDType.Method_2 or PIDType.Method_2_Unown; if (skipIV1Frame) // VBlank skip after PID { C = rng.Next(C); } var D = rng.Next(C); var skipIV2Frame = type is PIDType.Method_4 or PIDType.Method_4_Unown; if (skipIV2Frame) // VBlank skip between IVs { D = rng.Next(D); } Span <int> IVs = stackalloc int[6]; MethodFinder.GetIVsInt32(IVs, C >> 16, D >> 16); if (type == PIDType.Method_1_Roamer) { // Only store lowest 8 bits of IV data; zero out the other bits. IVs[1] &= 7; for (int i = 2; i < 6; i++) { IVs[i] = 0; } } pk.SetIVs(IVs); }
public static Dictionary <int, int[]> GetRNGList(PIDType method) { if (method == PIDType.Method_2) { return(WC3RNGList_M2); } if (method == PIDType.BACD_R) { return(WC3RNGList_BACD); } throw new ArgumentException(nameof(method)); }
/// <summary> /// Checks if a pokewalker seed failed, and if it did, randomizes TID and SID (to retry in the future) /// </summary> /// <param name="seed">Seed</param> /// <param name="method">RNG method (every method except pokewalker is ignored)</param> /// <param name="pk">PKM object</param> /// <param name="original">original encounter pkm</param> /// <returns></returns> private static bool PokeWalkerSeedFail(uint seed, PIDType method, PKM pk, PKM original) { if (method != PIDType.Pokewalker) { return(false); } if (seed % 24 != original.Nature) { return(true); } pk.TID = Util.Rand.Next(65535); pk.SID = Util.Rand.Next(65535); return(false); }
public static int GetRNGListIndex(PIDType Method) { switch (Method) { case PIDType.Method_2: return(0); case PIDType.BACD_R: return(1); default: return(-1); } }
public static bool IsCompatible4(this PIDType val, IEncounterable encounter, PKM pkm) { switch (encounter) { case EncounterStatic s: if (s == Encounters4.SpikyEaredPichu || (s.Location == Locations.PokeWalker4 && s.Gift)) // Pokewalker { return(val == PIDType.Pokewalker); } if (s.Shiny == Shiny.Always) { return(val == PIDType.ChainShiny); } if (val == PIDType.CuteCharm && IsCuteCharm4Valid(encounter, pkm)) { return(true); } return(val == PIDType.Method_1); case EncounterSlot sl: if (val == PIDType.Method_1) { return(true); } if (val == PIDType.CuteCharm && IsCuteCharm4Valid(encounter, pkm)) { return(true); } if (val != PIDType.ChainShiny) { return(false); } // Chain shiny with poke radar is only possible in DPPt in tall grass, safari zone do not allow pokeradar // TypeEncounter TallGrass discard any cave or city var ver = (GameVersion)pkm.Version; var IsDPPt = ver == GameVersion.D || ver == GameVersion.P || ver == GameVersion.Pt; return(pkm.IsShiny && IsDPPt && sl.TypeEncounter == EncounterType.TallGrass && !Encounters4.SafariZoneLocation_4.Contains(sl.Location)); case PGT _: // manaphy return(IsG4ManaphyPIDValid(val, pkm)); case PCD d when d.Gift.PK.PID != 1: return(true); // already matches PCD's fixed PID requirement default: // eggs return(val == PIDType.None); } }
private static bool IsRoamerPIDIV(this PIDType val, PKM pkm) { // Roamer PIDIV is always Method 1. // M1 is checked before M1R. A M1R PIDIV can also be a M1 PIDIV, so check that collision. if (PIDType.Method_1_Roamer == val) { return(true); } if (PIDType.Method_1 != val) { return(false); } var IVs = pkm.IVs; return(!(IVs.Skip(2).Any(iv => iv != 0) || IVs[1] > 7)); }
private static bool IsRoamerPIDIV(this PIDType val, PKM pkm) { // Roamer PIDIV is always Method 1. // M1 is checked before M1R. A M1R PIDIV can also be a M1 PIDIV, so check that collision. if (PIDType.Method_1_Roamer == val) { return(true); } if (PIDType.Method_1 != val) { return(false); } // only 8 bits are stored instead of 32 -- 5 bits HP, 3 bits for ATK. return(!(pkm.IV_DEF != 0 || pkm.IV_SPE != 0 || pkm.IV_SPA != 0 || pkm.IV_SPD != 0 || pkm.IV_ATK > 7)); }
/// <summary> /// Set IV Values for the pokemon /// </summary> /// <param name="pk"></param> /// <param name="set"></param> /// <param name="method"></param> /// <param name="hpType"></param> /// <param name="original"></param> private static void SetIVsPID(this PKM pk, ShowdownSet set, PIDType method, int hpType, PKM original) { // Useful Values for computation int Species = pk.Species; int Nature = pk.Nature; int Gender = pk.Gender; int AbilityNumber = pk.AbilityNumber; // 1,2,4 (HA) // Find the encounter var li = EncounterFinder.FindVerifiedEncounter(original); // TODO: Something about the gen 5 events. Maybe check for nature and shiny val and not touch the PID in that case? // Also need to figure out hidden power handling in that case.. for PIDType 0 that may isn't even be possible. if (li.EncounterMatch is EncounterStatic8N e) { pk.IVs = set.IVs; if (AbilityNumber == 4 && (e.Ability == 0 || e.Ability == 1 || e.Ability == 2)) { return; } FindNestPIDIV(pk, e, set.Shiny); ValidateGender(pk); } else if (pk.GenNumber > 4 || pk.VC) { pk.IVs = set.IVs; if (Species == 658 && pk.AltForm == 1) { pk.IVs = new[] { 20, 31, 20, 31, 31, 20 } } ; if (method != PIDType.G5MGShiny) { pk.PID = PKX.GetRandomPID(Species, Gender, pk.Version, Nature, pk.Format, pk.PID); } } else { pk.IVs = set.IVs; if (li.EncounterMatch is PCD) { return; } FindPIDIV(pk, method, hpType); ValidateGender(pk); } }
private static PIDType GetPIDType(PKM pk, PIDType specific) { if (specific != PIDType.None) { return(specific); } if (pk.Version == 15) { return(PIDType.CXD); } if (pk.Gen3 && pk.Species == 201) { return(PIDType.Method_1_Unown + Util.Rand.Next(3)); } return(PIDType.Method_1); }
public static bool UsesEventBasedMethod(int Species, int[] Moves, PIDType method) { var index = BruteTables.GetRNGListIndex(method); if (index == -1) { return(false); } var RNGList = BruteTables.WC3RNGList[index]; if (!RNGList.Keys.Contains(Species)) { return(false); } return(Moves.Any(i => RNGList[Species].Contains(i))); }
public static bool IsCompatible4(this PIDType val, IEncounterable encounter, PKM pkm) { switch (encounter) { case EncounterStatic s: if (s == Encounters4.SpikyEaredPichu || s.Location == 233 && s.Gift) // Pokewalker { return(val == PIDType.Pokewalker); } if (s.Shiny == true) { return(val == PIDType.ChainShiny); } if (val == PIDType.CuteCharm && IsCuteCharm4Valid(encounter, pkm)) { return(true); } return(val == PIDType.Method_1); case EncounterSlot sl: if (val == PIDType.Method_1) { return(true); } if (val == PIDType.CuteCharm && IsCuteCharm4Valid(encounter, pkm)) { return(sl.Type != SlotType.Swarm); // Cute Charm does not work with Swarm } if (val != PIDType.ChainShiny) { return(false); } // Chain shiny with poke radar is only possible in DPPt in tall grass, safari zone do not allow pokeradar // TypeEncounter TallGrass discard any cave or city var IsDPPt = GameVersion.DP.Contains((GameVersion)pkm.Version) || (GameVersion)pkm.Version == GameVersion.Pt; return(pkm.IsShiny && IsDPPt && sl.TypeEncounter == EncounterType.TallGrass && !Encounters4.SafariZoneLocation_4.Contains(sl.Location)); case PGT _: // manaphy return(IsG4ManaphyPIDValid(val, pkm)); default: // eggs return(val == PIDType.None); } }
private static void SetValuesFromSeedLCRNG(PKM pk, PIDType type, uint seed) { var rng = RNG.LCRNG; var A = rng.Next(seed); var B = rng.Next(A); var pid = (B & 0xFFFF0000) | A >> 16; if (type == PIDType.Method_1_Unown || type == PIDType.Method_2_Unown || type == PIDType.Method_4_Unown) { pk.PID = (pid >> 16) | (pid << 16); // swap halves } else { pk.PID = pid; } var skipIV1Frame = type == PIDType.Method_2 || type == PIDType.Method_2_Unown; if (skipIV1Frame) { B = rng.Next(B); } var C = rng.Next(B); var D = rng.Next(C); var skipIV2Frame = type == PIDType.Method_4 || type == PIDType.Method_4_Unown; if (skipIV2Frame) { D = rng.Next(D); } var IVs = MethodFinder.GetIVsInt32(C >> 16, D >> 16); if (type == PIDType.Method_1_Roamer) { IVs[1] &= 7; for (int i = 2; i < 6; i++) { IVs[i] = 0; } } pk.IVs = IVs; }
public static uint GetSeed(int random, PIDType type = PIDType.BACD_U) { int restricted = random % Seeds.Length; var seed = (uint)Seeds[restricted]; if (type == PIDType.BACD_R) { return(seed); } int position = (random % (MewPerRestrictedSeed - 1)) + 1; for (int i = 0; i < position; i++) { seed = RNG.LCRNG.Advance(seed, FramesPerMew); } return(seed); }
public static bool IsReversedPID(this PIDType type) { switch (type) { case PIDType.BACD_R: case PIDType.BACD_R_A: case PIDType.BACD_R_S: case PIDType.BACD_U: case PIDType.BACD_U_A: case PIDType.BACD_U_S: case PIDType.CXD: case PIDType.Method_1_Unown: case PIDType.Method_2_Unown: case PIDType.Method_4_Unown: return(true); default: return(false); } }
public static bool IsCompatible3(this PIDType val, IEncounterable encounter, PKM pkm) { switch (encounter) { case WC3 g: if (val == g.Method) { return(true); } // forced shiny eggs, when hatched, can lose their detectable correlation. return(g.IsEgg && !pkm.IsEgg && val == PIDType.None && (g.Method == PIDType.BACD_R_S || g.Method == PIDType.BACD_U_S)); case EncounterStaticShadow d when d.EReader: return(val == PIDType.None); // All IVs are 0 case EncounterStatic s: switch (pkm.Version) { case (int)GameVersion.CXD: return(val == PIDType.CXD || val == PIDType.CXD_ColoStarter); case (int)GameVersion.E: return(val == PIDType.Method_1); // no roamer glitch case (int)GameVersion.FR: case (int)GameVersion.LG: return(s.Roaming ? val.IsRoamerPIDIV(pkm) : val == PIDType.Method_1); // roamer glitch default: // RS, roamer glitch && RSBox s/w emulation => method 4 available return(s.Roaming ? val.IsRoamerPIDIV(pkm) : MethodH14.Any(z => z == val)); } case EncounterSlot w: if (pkm.Version == 15) { return(val == PIDType.PokeSpot); } return((w.Species == 201 ? MethodH_Unown : MethodH).Any(z => z == val)); default: return(val == PIDType.None); } }
public static void Gen3Shiny(this PKM pkm, Shiny shinyType) { RNG rng = RNG.LCRNG; PIDType type = PIDType.Method_1; if (pkm.Species == 201) { type = PIDType.Method_1_Unown; } IEnumerable <uint> seeds; do { pkm.SetPIDGender(pkm.Gender); CommonEdits.SetShiny(pkm, shinyType); seeds = GetSeedsFromPID(pkm.PID, rng); } while (!pkm.IsShiny || seeds == null); PIDGenerator.SetValuesFromSeed(pkm, type, seeds.ElementAt(0)); }
/// <summary> /// Set IV Values for the pokemon /// </summary> /// <param name="pk"></param> /// <param name="SSet"></param> /// <param name="Method"></param> /// <param name="HPType"></param> /// <param name="originalPKMN"></param> public static void SetIVsPID(PKM pk, ShowdownSet SSet, PIDType Method, int HPType, PKM originalPKMN) { // Useful Values for computation int Species = pk.Species; int Nature = pk.Nature; int Gender = pk.Gender; int AbilityNumber = pk.AbilityNumber; // 1,2,4 (HA) int Ability = pk.Ability; // Find the encounter LegalInfo li = EncounterFinder.FindVerifiedEncounter(originalPKMN); var property = li.EncounterMatch.GetType().GetProperty("PIDType"); // TODO: Something about the gen 5 events. Maybe check for nature and shiny val and not touch the PID in that case? // Also need to figure out hidden power handling in that case.. for PIDType 0 that may isn't even be possible. if (pk.GenNumber > 4 || pk.VC) { pk.IVs = SSet.IVs; if (Species == 658 && pk.AltForm == 1) { pk.IVs = new int[] { 20, 31, 20, 31, 31, 20 } } ; if (Method != PIDType.G5MGShiny) { pk.PID = PKX.GetRandomPID(Species, Gender, pk.Version, Nature, pk.Format, (uint)(AbilityNumber * 0x10001)); } } else { pk.IVs = SSet.IVs; if (li.EncounterMatch is PCD) { return; } FindPIDIV(pk, Method, HPType, originalPKMN); ValidateGender(pk); } }
private static bool IsBACD_U_S(uint idxor, uint pid, uint low, ref uint A, ref PIDType type) { // 0-Origin // 1-PIDH // 2-PIDL (ends up unused) // 3-FORCEBITS // PID = PIDH << 16 | (SID ^ TID ^ PIDH) var X = RNG.LCRNG.Prev(A); // unroll once as there's 3 calls instead of 2 uint PID = (X & 0xFFFF0000) | (idxor ^ X >> 16); PID &= 0xFFFFFFF8; PID |= low & 0x7; // lowest 3 bits if (PID != pid) { return(false); } A = X; // keep the unrolled seed type = PIDType.BACD_U_S; return(true); }