diff --git a/PKHeX.Core/Legality/Analysis.cs b/PKHeX.Core/Legality/Analysis.cs index 9e5867ecd..a7f639bc8 100644 --- a/PKHeX.Core/Legality/Analysis.cs +++ b/PKHeX.Core/Legality/Analysis.cs @@ -154,7 +154,10 @@ public LegalityAnalysis(PKM pk, PersonalInfo pi) Parsed = true; } #if SUPPRESS + // We want to swallow any error from malformed input data from the user. The Valid state is all that we really need. +#pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) +#pragma warning restore CA1031 // Do not catch general exception types { System.Diagnostics.Debug.WriteLine(e.Message); Info = new LegalInfo(pkm); @@ -284,11 +287,10 @@ private void UpdateVCTransferInfo() var enc = (Info.EncounterOriginalGB = EncounterMatch); if (enc is EncounterInvalid) return; - var updated = Info.EncounterMatch = EncounterStaticGenerator.GetVCStaticTransferEncounter(pkm, enc); - if (!(updated is EncounterStatic7 s) || !EncounterStaticGenerator.IsVCStaticTransferEncounterValid(pkm, s)) - { AddLine(Severity.Invalid, LEncInvalid, CheckIdentifier.Encounter); return; } + var vc = EncounterStaticGenerator.GetVCStaticTransferEncounter(pkm, enc); + Info.EncounterMatch = vc; - foreach (var z in Transfer.VerifyVCEncounter(pkm, enc, s, Info.Moves)) + foreach (var z in Transfer.VerifyVCEncounter(pkm, enc, vc, Info.Moves)) AddLine(z); Transfer.VerifyTransferLegalityG12(this); diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic1.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic1.cs index 1197b69b6..2c5516c50 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic1.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic1.cs @@ -26,5 +26,38 @@ protected override bool IsMatchLocation(PKM pkm) { return true; } + + public override bool IsMatchDeferred(PKM pkm) + { + if (pkm is PK1 pk1 && pk1.Gen1_NotTradeback && !IsCatchRateValid(pk1)) + return true; + + return !ParseSettings.AllowGBCartEra && GameVersion.GBCartEraOnly.Contains(Version); + } + + private bool IsCatchRateValid(PK1 pk1) + { + var catch_rate = pk1.Catch_Rate; + if (Species == (int)Core.Species.Pikachu) + { + if (catch_rate == 190) // Red Blue Pikachu is not a static encounter + return false; + if (catch_rate == 163 && Level == 5) // Light Ball (Yellow) starter + return true; + } + + if (Version == GameVersion.Stadium) + { + // Amnesia Psyduck has different catch rates depending on language + if (Species == (int)Core.Species.Psyduck) + return catch_rate == (pk1.Japanese ? 167 : 168); + return catch_rate == 167 || catch_rate == 168; + } + + // Encounters can have different Catch Rates (RBG vs Y) + var table = Version == GameVersion.Y ? PersonalTable.Y : PersonalTable.RB; + var rate = table[Species].CatchRate; + return catch_rate == rate; + } } } diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic2.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic2.cs index 873b0b00b..bd753c9f9 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic2.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic2.cs @@ -72,6 +72,11 @@ protected override bool IsMatchLocation(PKM pkm) return Location == pkm.Met_Location; return true; } + + public override bool IsMatchDeferred(PKM pkm) + { + return !ParseSettings.AllowGBCartEra && GameVersion.GBCartEraOnly.Contains(Version); + } } public sealed class EncounterStatic2Odd : EncounterStatic2 diff --git a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic7.cs b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic7.cs index 4897b00f7..5825d7c55 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic7.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterStatic/EncounterStatic7.cs @@ -28,5 +28,40 @@ protected override bool IsMatchForm(PKM pkm, DexLevel evo) return Form == evo.Form || Legal.IsFormChangeable(Species, Form, pkm.Format); } + + public static EncounterStatic7 GetVC1(int species, int metLevel) + { + bool mew = species == (int)Core.Species.Mew; + return new EncounterStatic7 + { + Species = species, + Gift = true, // Forces Poké Ball + Ability = Legal.TransferSpeciesDefaultAbility_1.Contains(species) ? 1 : 4, // Hidden by default, else first + Shiny = mew ? Shiny.Never : Shiny.Random, + Fateful = mew, + Location = Locations.Transfer1, + Level = metLevel, + Version = GameVersion.RBY, + FlawlessIVCount = mew ? 5 : 3, + }; + } + + public static EncounterStatic7 GetVC2(int species, int metLevel) + { + bool mew = species == (int)Core.Species.Mew; + bool fateful = mew || species == (int)Core.Species.Celebi; + return new EncounterStatic7 + { + Species = species, + Gift = true, // Forces Poké Ball + Ability = Legal.TransferSpeciesDefaultAbility_2.Contains(species) ? 1 : 4, // Hidden by default, else first + Shiny = mew ? Shiny.Never : Shiny.Random, + Fateful = fateful, + Location = Locations.Transfer2, + Level = metLevel, + Version = GameVersion.GSC, + FlawlessIVCount = fateful ? 5 : 3 + }; + } } -} \ No newline at end of file +} diff --git a/PKHeX.Core/Legality/Encounters/Generator/EncounterStaticGenerator.cs b/PKHeX.Core/Legality/Encounters/Generator/EncounterStaticGenerator.cs index e42c87009..0d71c8efa 100644 --- a/PKHeX.Core/Legality/Encounters/Generator/EncounterStaticGenerator.cs +++ b/PKHeX.Core/Legality/Encounters/Generator/EncounterStaticGenerator.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using static PKHeX.Core.Legal; @@ -43,7 +44,7 @@ private static IEnumerable GetMatchingStaticEncounters(PKM pkm, { foreach (var dl in evos) { - if (!GetIsMatchStatic(pkm, e, dl)) + if (!e.IsMatch(pkm, dl)) continue; if (e.IsMatchDeferred(pkm)) @@ -57,20 +58,6 @@ private static IEnumerable GetMatchingStaticEncounters(PKM pkm, yield return e; } - private static bool GetIsMatchStatic(PKM pkm, EncounterStatic e, DexLevel evo) - { - if (!e.IsMatch(pkm, evo)) - return false; - - if (pkm is PK1 pk1 && pk1.Gen1_NotTradeback && !IsValidCatchRatePK1(e, pk1)) - return false; - - if (!ParseSettings.AllowGBCartEra && GameVersion.GBCartEraOnly.Contains(e.Version)) - return false; - - return true; - } - private static IEnumerable GetStaticEncounters(PKM pkm, IReadOnlyList dl, GameVersion gameSource = GameVersion.Any) { if (gameSource == GameVersion.Any) @@ -80,48 +67,17 @@ private static IEnumerable GetStaticEncounters(PKM pkm, IReadOn return table.Where(e => dl.Any(d => d.Species == e.Species)); } - internal static IEncounterable GetVCStaticTransferEncounter(PKM pkm, IEncounterable enc) + internal static EncounterStatic7 GetVCStaticTransferEncounter(PKM pkm, IEncounterable enc) { + var species = pkm.Species; + var met = pkm.Met_Level; if (pkm.VC1) - return GetRBYStaticTransfer(pkm.Species > MaxSpeciesID_1 ? enc.Species : pkm.Species, pkm.Met_Level); + return EncounterStatic7.GetVC1(species > MaxSpeciesID_1 ? enc.Species : species, met); if (pkm.VC2) - return GetGSStaticTransfer(pkm.Species > MaxSpeciesID_2 ? enc.Species : pkm.Species, pkm.Met_Level); - return new EncounterInvalid(pkm); - } + return EncounterStatic7.GetVC2(species > MaxSpeciesID_2 ? enc.Species : species, met); - private static EncounterStatic7 GetRBYStaticTransfer(int species, int pkmMetLevel) - { - bool mew = species == (int)Species.Mew; - return new EncounterStatic7 - { - Species = species, - Gift = true, // Forces Poké Ball - Ability = TransferSpeciesDefaultAbility_1.Contains(species) ? 1 : 4, // Hidden by default, else first - Shiny = mew ? Shiny.Never : Shiny.Random, - Fateful = mew, - Location = Transfer1, - Level = pkmMetLevel, - Version = GameVersion.RBY, - FlawlessIVCount = mew ? 5 : 3, - }; - } - - private static EncounterStatic7 GetGSStaticTransfer(int species, int pkmMetLevel) - { - bool mew = species == (int) Species.Mew; - bool fateful = mew || species == (int) Species.Celebi; - return new EncounterStatic7 - { - Species = species, - Gift = true, // Forces Poké Ball - Ability = TransferSpeciesDefaultAbility_2.Contains(species) ? 1 : 4, // Hidden by default, else first - Shiny = mew ? Shiny.Never : Shiny.Random, - Fateful = fateful, - Location = Transfer2, - Level = pkmMetLevel, - Version = GameVersion.GSC, - FlawlessIVCount = fateful ? 5 : 3 - }; + // Should never reach here. + throw new ArgumentException(nameof(pkm.Version)); } internal static EncounterStatic? GetStaticLocation(PKM pkm, int species = -1) @@ -129,46 +85,15 @@ private static EncounterStatic7 GetGSStaticTransfer(int species, int pkmMetLevel switch (pkm.GenNumber) { case 1: - return GetRBYStaticTransfer(species, pkm.Met_Level); + return EncounterStatic7.GetVC1(species, pkm.Met_Level); case 2: - return GetGSStaticTransfer(species, pkm.Met_Level); + return EncounterStatic7.GetVC2(species, pkm.Met_Level); default: var dl = EvolutionChain.GetValidPreEvolutions(pkm, maxLevel: 100, skipChecks: true); return GetPossible(pkm, dl).FirstOrDefault(); } } - internal static bool IsVCStaticTransferEncounterValid(PKM pkm, EncounterStatic e) - { - return pkm.Met_Location == e.Location && pkm.Egg_Location == e.EggLocation; - } - - private static bool IsValidCatchRatePK1(EncounterStatic e, PK1 pk1) - { - var catch_rate = pk1.Catch_Rate; - // Pure gen 1, trades can be filter by catch rate - if (pk1.Species == (int)Species.Pikachu || pk1.Species == (int)Species.Raichu) - { - if (catch_rate == 190) // Red Blue Pikachu, is not a static encounter - return false; - if (catch_rate == 163 && e.Level == 5) // Light Ball (Yellow) starter - return true; - } - - if (e.Version == GameVersion.Stadium) - { - // Amnesia Psyduck has different catch rates depending on language - if (e.Species == (int)Species.Psyduck) - return catch_rate == (pk1.Japanese ? 167 : 168); - return GBRestrictions.Stadium_CatchRate.Contains(catch_rate); - } - - // Encounters can have different Catch Rates (RBG vs Y) - var table = e.Version == GameVersion.Y ? PersonalTable.Y : PersonalTable.RB; - var rate = table[e.Species].CatchRate; - return catch_rate == rate; - } - // Generation Specific Fetching private static IEnumerable GetEncounterStaticTable(PKM pkm, GameVersion gameSource = GameVersion.Any) { diff --git a/PKHeX.Core/Legality/Encounters/Information/EncounterSuggestion.cs b/PKHeX.Core/Legality/Encounters/Information/EncounterSuggestion.cs index d7d0d84d9..a2897f07a 100644 --- a/PKHeX.Core/Legality/Encounters/Information/EncounterSuggestion.cs +++ b/PKHeX.Core/Legality/Encounters/Information/EncounterSuggestion.cs @@ -132,7 +132,7 @@ public static int GetSuggestedEggMetLocation(PKM pkm) case GameVersion.C: case GameVersion.GSC: case GameVersion.RBY: - return pkm.Format > 2 ? Legal.Transfer2 : pkm.Met_Level == 0 ? 0 : Locations.HatchLocationC; + return pkm.Format > 2 ? Locations.Transfer2 : pkm.Met_Level == 0 ? 0 : Locations.HatchLocationC; } return -1; } @@ -151,9 +151,9 @@ public static int GetSuggestedTransferLocation(PKM pkm) if (pkm.Version == (int) GameVersion.GO) return 30012; if (pkm.VC1) - return Legal.Transfer1; + return Locations.Transfer1; if (pkm.VC2) - return Legal.Transfer2; + return Locations.Transfer2; if (pkm.Format == 4) // Pal Park return Locations.Transfer3; diff --git a/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs b/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs index f93684db3..fdd640a9e 100644 --- a/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs +++ b/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs @@ -243,7 +243,7 @@ private static CheckMoveResult[] ParseMoves(PKM pkm, MoveParseSource source, Leg { var res = new CheckMoveResult[4]; bool AllParsed() => res.All(z => z != null); - var required = pkm.Format != 1 ? 1 : GBRestrictions.GetRequiredMoveCount(pkm, source.CurrentMoves, info, source.Base); + var required = !(pkm is PK1 pk1) ? 1 : GBRestrictions.GetRequiredMoveCount(pk1, source.CurrentMoves, info, source.Base); // Special considerations! int reset = 0; diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs b/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs index b1fc27e82..a02702fac 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs @@ -122,10 +122,6 @@ private static List[] GetChainAll(PKM pkm, IEncounterable enc, IRea int minlvl = GetMinLevelGeneration(pkm, g); GensEvoChains[g].RemoveAll(e => e.Level < minlvl); } - else if (g == 2 && pkm.TradebackStatus == TradebackType.Gen1_NotTradeback) - { - GensEvoChains[2] = NONE; - } else if (g == 1) { // Remove Gen2 post-evolutions (Scizor, Blissey...) diff --git a/PKHeX.Core/Legality/Restrictions/GBRestrictions.cs b/PKHeX.Core/Legality/Restrictions/GBRestrictions.cs index c6183dcc5..555bf3788 100644 --- a/PKHeX.Core/Legality/Restrictions/GBRestrictions.cs +++ b/PKHeX.Core/Legality/Restrictions/GBRestrictions.cs @@ -156,7 +156,7 @@ internal static void GetIncompatibleEvolutionMoves(PKM pkm, IReadOnlyList m previousspecies = 0; } - internal static int GetRequiredMoveCount(PKM pk, IReadOnlyList moves, LegalInfo info, IReadOnlyList initialmoves) + internal static int GetRequiredMoveCount(PK1 pk, IReadOnlyList moves, LegalInfo info, IReadOnlyList initialmoves) { if (!pk.Gen1_NotTradeback) // No Move Deleter in Gen 1 return 1; // Move Deleter exits, slots from 2 onwards can always be empty diff --git a/PKHeX.Core/Legality/Tables/Locations.cs b/PKHeX.Core/Legality/Tables/Locations.cs index 51a306b69..0802b343e 100644 --- a/PKHeX.Core/Legality/Tables/Locations.cs +++ b/PKHeX.Core/Legality/Tables/Locations.cs @@ -53,6 +53,12 @@ public static class Locations /// Route 5 in public const int HatchLocation8 = 40; + /// Generation 1 -> Generation 7 Transfer Location (Kanto) + public const int Transfer1 = 30013; + + /// Generation 2 -> Generation 7 Transfer Location (Johto) + public const int Transfer2 = 30017; + /// Generation 3 -> Generation 4 Transfer Location (Pal Park) public const int Transfer3 = 0x37; diff --git a/PKHeX.Core/Legality/Tables/Tables1.cs b/PKHeX.Core/Legality/Tables/Tables1.cs index 9323ae1ab..c402608ad 100644 --- a/PKHeX.Core/Legality/Tables/Tables1.cs +++ b/PKHeX.Core/Legality/Tables/Tables1.cs @@ -9,11 +9,6 @@ public static partial class Legal internal const int MaxItemID_1 = 255; internal const int MaxAbilityID_1 = 0; - /// - /// Generation 1 -> Generation 7 Transfer Location (Kanto) - /// - public const int Transfer1 = 30013; - internal static readonly ushort[] Pouch_Items_RBY = { 000,001,002,003,004,005,006, 010,011,012,013,014,015, diff --git a/PKHeX.Core/Legality/Tables/Tables2.cs b/PKHeX.Core/Legality/Tables/Tables2.cs index 6b3cdd848..6b092428c 100644 --- a/PKHeX.Core/Legality/Tables/Tables2.cs +++ b/PKHeX.Core/Legality/Tables/Tables2.cs @@ -10,11 +10,6 @@ public static partial class Legal internal const int MaxItemID_2 = 255; internal const int MaxAbilityID_2 = 0; - /// - /// Generation 2 -> Generation 7 Transfer Location (Johto) - /// - public const int Transfer2 = 30017; - internal static readonly ushort[] Pouch_Items_GSC = { 3, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 46, 47, 48, 49, 51, 52, 53, 57, 60, 62, 63, 64, 65, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95, 96, 97, 98, 99, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 117, 118, 119, 121, 122, 123, 124, 125, 126, 131, 132, 138, 139, 140, 143, 144, 146, 150, 151, 152, 156, 158, 163, 167, 168, 169, 170, 172, 173, 174, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189 }; diff --git a/PKHeX.Core/Legality/Tables/Tables4.cs b/PKHeX.Core/Legality/Tables/Tables4.cs index dc5defae6..512c8d093 100644 --- a/PKHeX.Core/Legality/Tables/Tables4.cs +++ b/PKHeX.Core/Legality/Tables/Tables4.cs @@ -267,11 +267,11 @@ public static partial class Legal 2000, 2002, 2009, 2010, 2011, 2013, 2014 }; - internal static int GetTransfer45MetLocation(PKM pk5) + internal static int GetTransfer45MetLocation(PKM pkm) { - if (pk5.Gen4 && pk5.FatefulEncounter) + if (pkm.Gen4 && pkm.FatefulEncounter) { - var spec = pk5.Species; + var spec = pkm.Species; if (spec == 251) // Celebi return Locations.Transfer4_CelebiUnused; if (243 <= spec && spec <= 245) // Beast diff --git a/PKHeX.Core/Legality/Tables/Tables5.cs b/PKHeX.Core/Legality/Tables/Tables5.cs index 3b1a3e52f..e566f070e 100644 --- a/PKHeX.Core/Legality/Tables/Tables5.cs +++ b/PKHeX.Core/Legality/Tables/Tables5.cs @@ -111,7 +111,7 @@ public static partial class Legal // Dream ball not usable in wild }; - internal static readonly HashSet DreamWorldBalls = new HashSet (WildPokeBalls5.Concat(new[] { 25 })); + internal static readonly HashSet DreamWorldBalls = new HashSet(WildPokeBalls5) {(int)Ball.Dream}; internal static readonly int[] FutureEvolutionsGen5 = { diff --git a/PKHeX.Core/Legality/Verifiers/TransferVerifier.cs b/PKHeX.Core/Legality/Verifiers/TransferVerifier.cs index 2de8f3576..a331bae0a 100644 --- a/PKHeX.Core/Legality/Verifiers/TransferVerifier.cs +++ b/PKHeX.Core/Legality/Verifiers/TransferVerifier.cs @@ -143,9 +143,6 @@ public void VerifyTransferLegalityG8(LegalityAnalysis data) public IEnumerable VerifyVCEncounter(PKM pkm, IEncounterable encounter, ILocation transfer, IList Moves) { // Check existing EncounterMatch - if (encounter is EncounterInvalid) - yield break; // Avoid duplicate invalid message - if (encounter is EncounterStatic v && (GameVersion.GBCartEraOnly.Contains(v.Version) || v.Version == GameVersion.VCEvents)) { bool exceptions = false; diff --git a/PKHeX.Core/PKM/PK1.cs b/PKHeX.Core/PKM/PK1.cs index cd5f9987b..0104a7535 100644 --- a/PKHeX.Core/PKM/PK1.cs +++ b/PKHeX.Core/PKM/PK1.cs @@ -146,7 +146,7 @@ public PK7 ConvertToPK7() Move2_PPUps = Move2_PPUps, Move3_PPUps = Move3_PPUps, Move4_PPUps = Move4_PPUps, - Met_Location = Legal.Transfer1, // "Kanto region", hardcoded. + Met_Location = Locations.Transfer1, // "Kanto region", hardcoded. Gender = Gender, OT_Name = StringConverter12.GetG1ConvertedString(otname, Japanese), IsNicknamed = false, @@ -170,7 +170,7 @@ public PK7 ConvertToPK7() int flawless = Species == (int)Core.Species.Mew ? 5 : 3; var rnd = Util.Rand; for (var i = 0; i < new_ivs.Length; i++) - new_ivs[i] = rnd.Next(pk7.MaxIV + 1); + new_ivs[i] = rnd.Next(32); for (var i = 0; i < flawless; i++) new_ivs[i] = 31; Util.Shuffle(new_ivs); diff --git a/PKHeX.Core/PKM/PK2.cs b/PKHeX.Core/PKM/PK2.cs index 8a4fc2ee0..a9f66a14e 100644 --- a/PKHeX.Core/PKM/PK2.cs +++ b/PKHeX.Core/PKM/PK2.cs @@ -145,7 +145,7 @@ public PK7 ConvertToPK7() Move2_PPUps = Move2_PPUps, Move3_PPUps = Move3_PPUps, Move4_PPUps = Move4_PPUps, - Met_Location = Legal.Transfer2, // "Johto region", hardcoded. + Met_Location = Locations.Transfer2, // "Johto region", hardcoded. Gender = Gender, IsNicknamed = false, AltForm = AltForm, @@ -170,7 +170,7 @@ public PK7 ConvertToPK7() int flawless = special ? 5 : 3; var rnd = Util.Rand; for (var i = 0; i < new_ivs.Length; i++) - new_ivs[i] = rnd.Next(pk7.MaxIV + 1); + new_ivs[i] = rnd.Next(32); for (var i = 0; i < flawless; i++) new_ivs[i] = 31; Util.Shuffle(new_ivs); @@ -191,23 +191,19 @@ public PK7 ConvertToPK7() else if (IsNicknamedBank) { pk7.IsNicknamed = true; - pk7.Nickname = Korean ? Nickname - : StringConverter12.GetG1ConvertedString(nick, Japanese); + pk7.Nickname = Korean ? Nickname : StringConverter12.GetG1ConvertedString(nick, Japanese); } - pk7.OT_Name = Korean ? OT_Name - : StringConverter12.GetG1ConvertedString(otname, Japanese); + pk7.OT_Name = Korean ? OT_Name : StringConverter12.GetG1ConvertedString(otname, Japanese); pk7.OT_Gender = OT_Gender; // Crystal pk7.SetTradeMemoryHT(bank: true); // oh no, memories on gen7 pkm // Dizzy Punch cannot be transferred { - var moves = pk7.Moves; - var index = Array.IndexOf(moves, 146); // Dizzy Punch + var index = pk7.GetMoveIndex(146); // Dizzy Punch if (index != -1) { - moves[index] = 0; - pk7.Moves = moves; + pk7.SetMove(index, 0); pk7.FixMoves(); } } diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs index 959c25996..27319d973 100644 --- a/PKHeX.Core/PKM/PKM.cs +++ b/PKHeX.Core/PKM/PKM.cs @@ -1083,6 +1083,42 @@ public void TransferPropertiesWithReflection(PKM Destination) /// public bool HasMove(int move) => Move1 == move || Move2 == move || Move3 == move || Move4 == move; + public int GetMoveIndex(int move) => Move1 == move ? 0 : Move2 == move ? 1 : Move3 == move ? 2 : Move4 == move ? 3 : -1; + + public int GetMove(int index) + { + switch (index) + { + case 0: return Move1; + case 1: return Move2; + case 2: return Move3; + case 3: return Move4; + default: + throw new IndexOutOfRangeException(nameof(index)); + } + } + + public void SetMove(int index, int value) + { + switch (index) + { + case 0: + Move1 = value; + return; + case 1: + Move2 = value; + return; + case 2: + Move3 = value; + return; + case 3: + Move4 = value; + return; + default: + throw new IndexOutOfRangeException(nameof(index)); + } + } + /// /// Clears moves that a may have, possibly from a future generation. ///