/// <summary> /// Secondary fallback if PIDType.None to slot the PKM into its most likely type /// </summary> /// <param name="pk">PKM to modify</param> /// <returns>PIDType that is likely used</returns> private static PIDType FindLikelyPIDType(PKM pk) { if (BruteForce.UsesEventBasedMethod(pk.Species, pk.Moves, PIDType.BACD_R)) { return(PIDType.BACD_R); } if (BruteForce.UsesEventBasedMethod(pk.Species, pk.Moves, PIDType.Method_2)) { return(PIDType.Method_2); } if (pk.Species == (int)Species.Manaphy && pk.Gen4) { pk.Egg_Location = Locations.LinkTrade4; // todo: really shouldn't be doing this, don't modify pkm return(PIDType.Method_1); } switch (pk.GenNumber) { case 3: switch (EncounterFinder.FindVerifiedEncounter(pk).EncounterMatch) { case WC3 g: return(g.Method); case EncounterStatic _: switch (pk.Version) { case (int)GameVersion.CXD: return(PIDType.CXD); case (int)GameVersion.E: return(PIDType.Method_1); case (int)GameVersion.FR: case (int)GameVersion.LG: return(PIDType.Method_1); // roamer glitch default: return(PIDType.Method_1); } case EncounterSlot _ when pk.Version == (int)GameVersion.CXD: return(PIDType.PokeSpot); case EncounterSlot _: return(pk.Species == (int)Species.Unown ? PIDType.Method_1_Unown : PIDType.Method_1); default: return(PIDType.None); } case 4: return(EncounterFinder.FindVerifiedEncounter(pk).EncounterMatch switch { EncounterStatic s when s.Location == Locations.PokeWalker4 && s.Gift => PIDType.Pokewalker, EncounterStatic s => (s.Shiny == Shiny.Always ? PIDType.ChainShiny : PIDType.Method_1), PGT _ => PIDType.Method_1, _ => PIDType.None });
/// <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); } }
/// <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); } }
/// <summary> /// Secondary fallback if PIDType.None to slot the PKM into its most likely type /// </summary> /// <param name="pk">PKM to modify</param> /// <returns>PIDType that is likely used</returns> private static PIDType FindLikelyPIDType(PKM pk) { if (BruteForce.UsesEventBasedMethod(pk.Species, pk.Moves, PIDType.BACD_R)) { return(PIDType.BACD_R); } if (BruteForce.UsesEventBasedMethod(pk.Species, pk.Moves, PIDType.Method_2)) { return(PIDType.Method_2); } if (pk.Species == 490 && pk.Gen4) { pk.Egg_Location = 2002; // todo: really shouldn't be doing this, don't modify pkm return(PIDType.Method_1); } switch (pk.GenNumber) { case 3: switch (EncounterFinder.FindVerifiedEncounter(pk).EncounterMatch) { case WC3 g: return(g.Method); case EncounterStatic _: switch (pk.Version) { case (int)GameVersion.CXD: return(PIDType.CXD); case (int)GameVersion.E: return(PIDType.Method_1); case (int)GameVersion.FR: case (int)GameVersion.LG: return(PIDType.Method_1); // roamer glitch default: return(PIDType.Method_1); } case EncounterSlot _: if (pk.Version == 15) { return(PIDType.PokeSpot); } return(pk.Species == 201 ? PIDType.Method_1_Unown : PIDType.Method_1); default: return(PIDType.None); } case 4: switch (EncounterFinder.FindVerifiedEncounter(pk).EncounterMatch) { case EncounterStatic s: if (s.Location == 233 && s.Gift) // Pokewalker { return(PIDType.Pokewalker); } if (s.Shiny == Shiny.Always) { return(PIDType.ChainShiny); } return(PIDType.Method_1); case PGT _: return(PIDType.Method_1); default: return(PIDType.None); } default: return(PIDType.None); } }
/// <summary> /// Secondary fallback if PIDType.None to slot the PKM into its most likely type /// </summary> /// <param name="pk">PKM to modify</param> /// <param name="pkmn">Original PKM</param> /// <returns>PIDType that is likely used</returns> public static PIDType FindLikelyPIDType(PKM pk, PKM pkmn) { BruteForce b = new BruteForce(); if (b.UsesEventBasedMethod(pk.Species, pk.Moves, "BACD_R")) { return(PIDType.BACD_R); } if (b.UsesEventBasedMethod(pk.Species, pk.Moves, "M2")) { return(PIDType.Method_2); } if (pk.Species == 490 && pk.Gen4) { pk.Egg_Location = 2002; return(PIDType.Method_1); } switch (pk.GenNumber) { case 3: switch (EncounterFinder.FindVerifiedEncounter(pk).EncounterMatch) { case WC3 g: return(g.Method); case EncounterStatic s: switch (pk.Version) { case (int)GameVersion.CXD: return(PIDType.CXD); case (int)GameVersion.E: return(PIDType.Method_1); case (int)GameVersion.FR: case (int)GameVersion.LG: return(PIDType.Method_1); // roamer glitch default: return(PIDType.Method_1); } case EncounterSlot w: if (pk.Version == 15) { return(PIDType.PokeSpot); } return(pk.Species == 201 ? PIDType.Method_1_Unown : PIDType.Method_1); default: return(PIDType.None); } case 4: switch (EncounterFinder.FindVerifiedEncounter(pk).EncounterMatch) { case EncounterStatic s: if (s.Location == 233 && s.Gift) // Pokewalker { return(PIDType.Pokewalker); } if (s.Shiny == Shiny.Always) { return(PIDType.ChainShiny); } return(PIDType.Method_1); case PGT _: return(PIDType.Method_1); default: return(PIDType.None); } default: return(PIDType.None); } }
/// <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, IBattleTemplate 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); if (li.EncounterMatch is MysteryGift mg) { var ivs = pk.IVs; for (int i = 0; i < mg.IVs.Length; i++) { ivs[i] = mg.IVs[i] > 31 ? set.IVs[i] : mg.IVs[i]; } pk.IVs = ivs; } else { pk.IVs = set.IVs; } // 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 || li.EncounterMatch is EncounterStatic8NC || li.EncounterMatch is EncounterStatic8ND) { var e = (EncounterStatic)li.EncounterMatch; if (AbilityNumber == 4 && (e.Ability == 0 || e.Ability == 1 || e.Ability == 2)) { return; } var pk8 = (PK8)pk; switch (e) { case EncounterStatic8NC c: FindNestPIDIV(pk8, c, set.Shiny); break; case EncounterStatic8ND c: FindNestPIDIV(pk8, c, set.Shiny); break; case EncounterStatic8N c: FindNestPIDIV(pk8, c, set.Shiny); break; } } else if (pk.GenNumber > 4 || pk.VC) { if (Species == 658 && pk.AltForm == 1) { pk.IVs = new[] { 20, 31, 20, 31, 31, 20 } } ; if (li.EncounterMatch is WC6 w6 && w6.PIDType == Shiny.FixedValue) { return; } if (li.EncounterMatch is WC7 w7 && w7.PIDType == Shiny.FixedValue) { return; } if (li.EncounterMatch is WC8 w8 && w8.PIDType == Shiny.FixedValue) { return; } if (pk.Version >= 24) { return; // Don't even bother changing IVs for Gen 6+ because why bother } if (method != PIDType.G5MGShiny) { var origpid = pk.PID; pk.PID = PKX.GetRandomPID(Util.Rand, Species, Gender, pk.Version, Nature, pk.Format, pk.PID); if (!li.EncounterMatch.Equals(EncounterFinder.FindVerifiedEncounter(pk).EncounterMatch)) { pk.PID = origpid; // Bad things happen when you change the PID! } if (li.Generation != 5) { return; } if (pk is PK5 p && p.NPokémon) { return; } if (li.EncounterMatch is EncounterStatic5 s && (s.Gift || s.Roaming || s.Ability != 4 || s.Location == 75)) { return; } while (true) { var result = (pk.PID & 1) ^ (pk.PID >> 31) ^ (pk.TID & 1) ^ (pk.SID & 1); if (result == 0) { break; } pk.PID = PKX.GetRandomPID(Util.Rand, Species, Gender, pk.Version, Nature, pk.Format, pk.PID); } } } else // Generation 3 and 4 { var encounter = li.EncounterMatch; if (encounter is PCD d) { if (d.Gift.PK.PID != 1) { pk.PID = d.Gift.PK.PID; } else if (pk.Nature != pk.PID % 25) { pk.SetPIDNature(Nature); } return; } if (encounter is EncounterEgg) { pk.SetPIDNature(Nature); return; } if (encounter is EncounterTrade t) { // EncounterTrade4 doesn't have fixed PIDs, so don't early return if (encounter is EncounterTrade3 || encounter is EncounterTrade4PID) { t.SetEncounterTradeIVs(pk); return; // Fixed PID, no need to mutate } } FindPIDIV(pk, method, hpType, set.Shiny, encounter); ValidateGender(pk); } }
/// <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, IBattleTemplate 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); pk.IVs = set.IVs; // 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 || li.EncounterMatch is EncounterStatic8NC || li.EncounterMatch is EncounterStatic8ND) { var e = (EncounterStatic)li.EncounterMatch; if (AbilityNumber == 4 && (e.Ability == 0 || e.Ability == 1 || e.Ability == 2)) { return; } var pk8 = (PK8)pk; switch (e) { case EncounterStatic8NC c: FindNestPIDIV(pk8, c, set.Shiny); break; case EncounterStatic8ND c: FindNestPIDIV(pk8, c, set.Shiny); break; case EncounterStatic8N c: FindNestPIDIV(pk8, c, set.Shiny); break; } } else if (pk.GenNumber > 4 || pk.VC) { if (Species == 658 && pk.AltForm == 1) { pk.IVs = new[] { 20, 31, 20, 31, 31, 20 } } ; if (method != PIDType.G5MGShiny) { pk.PID = PKX.GetRandomPID(Util.Rand, Species, Gender, pk.Version, Nature, pk.Format, pk.PID); if (li.Generation != 5) { return; } if (pk is PK5 p && p.NPokémon) { return; } if (li.EncounterMatch is EncounterStatic s && (s.Gift || s.Roaming || s.Ability != 4 || s.Location == 75)) { return; } while (true) { var result = (pk.PID & 1) ^ (pk.PID >> 31) ^ (pk.TID & 1) ^ (pk.SID & 1); if (result == 0) { break; } pk.PID = PKX.GetRandomPID(Util.Rand, Species, Gender, pk.Version, Nature, pk.Format, pk.PID); } } } else { if (li.EncounterMatch is PCD d) { if (d.Gift.PK.PID != 1) { pk.PID = d.Gift.PK.PID; } else if (pk.Nature != pk.PID % 25) { pk.SetPIDNature(Nature); } return; } if (li.EncounterMatch is EncounterEgg) { pk.SetPIDNature(Nature); return; } if (li.EncounterMatch is EncounterTradePID t) { t.SetEncounterTradeIVs(pk); return; // Fixed PID, no need to mutate } FindPIDIV(pk, method, hpType, set.Shiny); ValidateGender(pk); } }
private static PKM SetToEgg(PKM pkm, int origin, GameVersion gameVersion) { int dayCare = origin <= 4 ? Locations.Daycare4 : Locations.Daycare5; int metLevel = origin <= 4 ? 0 : 1; int currentLevel = origin <= 4 ? 5 : 1; // 非初级形态 PKM tmp = pkm.Clone(); tmp.IsEgg = true; tmp.Egg_Location = dayCare; tmp.Data[0xA8] = tmp.Data[0xA8 + 1] = 0; //Milotic List <CheckResult> checkResult = EncounterFinder.FindVerifiedEncounter(tmp).Parse; if (checkResult.IsPropStrInEleList("Comment", LegalityCheckStrings.LEvoInvalid)) { return(null); } int language = pkm.Language; pkm.Nickname = SpeciesName.GetSpeciesNameGeneration((int)Species.None, language, pkm.Format); pkm.IsNicknamed = true; pkm.IsEgg = true; pkm.HeldItem = 0; pkm.CurrentLevel = currentLevel; pkm.StatNature = pkm.Nature; pkm.RefreshAbility(new Random().Next(0, 3)); pkm.SetIVs(); pkm.EVs = new int[6]; pkm.Ball = (int)Ball.Poke; pkm.Met_Location = 0; pkm.Met_Level = metLevel; pkm.Egg_Location = dayCare; ReflectUtils.methods.TryGetValue("GetEggMoves", out MethodInfo method); int[] result = (int[])method.Invoke(null, new object[] { pkm, pkm.Species, pkm.AltForm, gameVersion }); pkm.SetMoves(new List <int>()); if (result.Length == 0) { pkm.SetRelearnMoves(pkm.GetSuggestedRelearnMoves()); } else { pkm.SetRelearnMoves(GetEggMovesRandom(pkm, result)); } pkm.SetMoves(pkm.RelearnMoves); pkm.SetMovesPPUpsToZero(); pkm.SetMaximumPPCurrent(); pkm.FixMoves(); // 8代独有数据 if (pkm.Format == 8) { PK8 pk8 = (PK8)pkm; pk8.DynamaxLevel = 0; pk8.CanGigantamax = false; } pkm.ClearAllRibbon(); pkm.ClearCurrentHandler(); pkm.ClearMemories(); pkm.ClearRecordFlags(); pkm.CurrentFriendship = 4; return(pkm); }
public IEncounter GetEncounter(Log log) { return(EncounterFinder.GetEncounter(log)); }