From 62d08d7c302ff46b3f05179becff76d877c6d57e Mon Sep 17 00:00:00 2001 From: Kurt Date: Tue, 10 Sep 2019 00:21:51 -0700 Subject: [PATCH] Misc clean split some methods with optional parameters=null add more xmldoc replace some magic numbers -> enum/const references consolidate common array operations (span soon maybe?) --- PKHeX.Core/Editing/Bulk/BatchEditing.cs | 2 +- PKHeX.Core/Editing/Bulk/PKMInfo.cs | 4 +- PKHeX.Core/Editing/CommonEdits.cs | 79 ++++++++++++------- PKHeX.Core/Legality/Analysis.cs | 2 +- .../Encounters/Data/EncounterEvent.cs | 24 ++---- .../Legality/Encounters/EncounterEgg.cs | 8 +- .../Legality/Encounters/EncounterSlot.cs | 14 ++-- .../Encounters/EncounterStaticShadow.cs | 27 +++++-- .../Encounters/EncounterStaticTyped.cs | 3 + .../Encounters/EncounterTradeCatchRate.cs | 3 + .../Legality/Encounters/EncounterTradePID.cs | 4 + PKHeX.Core/Legality/Encounters/LegalInfo.cs | 2 +- .../Encounters/Verifiers/EncounterVerifier.cs | 3 +- .../Encounters/Verifiers/EvolutionVerifier.cs | 4 +- .../Verifiers/MysteryGiftRestriction.cs | 8 ++ .../Verifiers/VerifyCurrentMoves.cs | 13 ++- .../Legality/Evolutions/EvolutionChain.cs | 8 +- PKHeX.Core/Legality/GBRestrictions.cs | 2 +- PKHeX.Core/Legality/Memories.cs | 3 + PKHeX.Core/Legality/Verifiers/PIDVerifier.cs | 2 + .../Legality/Verifiers/TransferVerifier.cs | 2 +- PKHeX.Core/MysteryGifts/MysteryUtil.cs | 3 + PKHeX.Core/MysteryGifts/WB7.cs | 2 +- PKHeX.Core/MysteryGifts/WC3.cs | 2 - PKHeX.Core/PKM/PKM.cs | 23 +++--- PKHeX.Core/PKM/Shared/PokeListGB.cs | 11 ++- PKHeX.Core/PKM/Shared/_K6.cs | 2 +- PKHeX.Core/PKM/Util/PKX.cs | 21 ----- PKHeX.Core/PersonalInfo/PersonalTable.cs | 19 ++--- PKHeX.Core/Saves/SaveFile.cs | 43 +--------- .../Substructures/Gen6/SangoInfoBlock.cs | 2 +- PKHeX.Core/Util/ArrayUtil.cs | 55 +++++++++++++ PKHeX.Core/Util/FileUtil.cs | 2 +- PKHeX.Core/Util/FlagUtil.cs | 21 +++++ 34 files changed, 249 insertions(+), 174 deletions(-) create mode 100644 PKHeX.Core/Util/ArrayUtil.cs create mode 100644 PKHeX.Core/Util/FlagUtil.cs diff --git a/PKHeX.Core/Editing/Bulk/BatchEditing.cs b/PKHeX.Core/Editing/Bulk/BatchEditing.cs index b9a6925f8..97823e9dd 100644 --- a/PKHeX.Core/Editing/Bulk/BatchEditing.cs +++ b/PKHeX.Core/Editing/Bulk/BatchEditing.cs @@ -368,7 +368,7 @@ namespace PKHeX.Core pk.SetSuggestedHyperTrainingData(); return ModifyResult.Modified; case nameof(PKM.RelearnMoves): - pk.RelearnMoves = info.SuggestedRelearn; + pk.SetRelearnMoves(info.SuggestedRelearn); return ModifyResult.Modified; case nameof(PKM.Met_Location): var encounter = info.SuggestedEncounter; diff --git a/PKHeX.Core/Editing/Bulk/PKMInfo.cs b/PKHeX.Core/Editing/Bulk/PKMInfo.cs index 22b6250e2..5852ba6a5 100644 --- a/PKHeX.Core/Editing/Bulk/PKMInfo.cs +++ b/PKHeX.Core/Editing/Bulk/PKMInfo.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; + namespace PKHeX.Core { /// @@ -12,7 +14,7 @@ namespace PKHeX.Core internal LegalityAnalysis Legality => la ?? (la = new LegalityAnalysis(pkm)); public bool Legal => Legality.Valid; - internal int[] SuggestedRelearn => Legality.GetSuggestedRelearn(); + internal IReadOnlyList SuggestedRelearn => Legality.GetSuggestedRelearn(); internal EncounterStatic SuggestedEncounter => Legality.GetSuggestedMetInfo(); } } \ No newline at end of file diff --git a/PKHeX.Core/Editing/CommonEdits.cs b/PKHeX.Core/Editing/CommonEdits.cs index 27874c8a2..24e3d4bfc 100644 --- a/PKHeX.Core/Editing/CommonEdits.cs +++ b/PKHeX.Core/Editing/CommonEdits.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; namespace PKHeX.Core @@ -13,6 +14,11 @@ namespace PKHeX.Core /// public static bool ShowdownSetIVMarkings { get; set; } = true; + /// + /// Default when applying markings. + /// + public static Func> MarkingMethod { get; set; } = FlagHighLow; + /// /// Sets the to the provided value. /// @@ -179,11 +185,8 @@ namespace PKHeX.Core /// /// Pokémon to modify. /// to use (if already known). Will fetch the current if not provided. - public static void SetMaximumPPUps(this PKM pk, int[] Moves = null) + public static void SetMaximumPPUps(this PKM pk, int[] Moves) { - if (Moves == null) - Moves = pk.Moves; - pk.Move1_PPUps = GetPPUpCount(Moves[0]); pk.Move2_PPUps = GetPPUpCount(Moves[1]); pk.Move3_PPUps = GetPPUpCount(Moves[2]); @@ -193,6 +196,12 @@ namespace PKHeX.Core int GetPPUpCount(int moveID) => moveID > 0 ? 3 : 0; } + /// + /// Sets the individual PP Up count values depending if a Move is present in the moveslot or not. + /// + /// Pokémon to modify. + public static void SetMaximumPPUps(this PKM pk) => pk.SetMaximumPPUps(pk.Moves); + /// /// Updates the and updates the current PP counts. /// @@ -219,17 +228,20 @@ namespace PKHeX.Core /// /// Pokémon to modify. /// to use (if already known). Will fetch the current if not provided. - public static void SetMaximumPPCurrent(this PKM pk, int[] Moves = null) + public static void SetMaximumPPCurrent(this PKM pk, int[] Moves) { - if (Moves == null) - Moves = pk.Moves; - - pk.Move1_PP = Moves.Length <= 0 ? 0 : pk.GetMovePP(Moves[0], pk.Move1_PPUps); + pk.Move1_PP = Moves.Length == 0 ? 0 : pk.GetMovePP(Moves[0], pk.Move1_PPUps); pk.Move2_PP = Moves.Length <= 1 ? 0 : pk.GetMovePP(Moves[1], pk.Move2_PPUps); pk.Move3_PP = Moves.Length <= 2 ? 0 : pk.GetMovePP(Moves[2], pk.Move3_PPUps); pk.Move4_PP = Moves.Length <= 3 ? 0 : pk.GetMovePP(Moves[3], pk.Move4_PPUps); } + /// + /// Updates the individual PP count values for each moveslot based on the maximum possible value. + /// + /// Pokémon to modify. + public static void SetMaximumPPCurrent(this PKM pk) => pk.SetMaximumPPCurrent(pk.Moves); + /// /// Sets the value, with special consideration for the values which derive the value. /// @@ -272,9 +284,9 @@ namespace PKHeX.Core /// Pokémon to modify. /// which contains parsed information pertaining to legality. /// best suited for the current data. - public static int[] GetSuggestedRelearnMoves(this PKM pk, LegalityAnalysis legal) + public static IReadOnlyList GetSuggestedRelearnMoves(this PKM pk, LegalityAnalysis legal) { - int[] m = legal.GetSuggestedRelearn(); + var m = legal.GetSuggestedRelearn(); if (m.Any(z => z != 0)) return m; @@ -349,7 +361,7 @@ namespace PKHeX.Core var legal = new LegalityAnalysis(pk); if (legal.Parsed && legal.Info.Relearn.Any(z => !z.Valid)) - pk.RelearnMoves = pk.GetSuggestedRelearnMoves(legal); + pk.SetRelearnMoves(pk.GetSuggestedRelearnMoves(legal)); pk.RefreshChecksum(); } @@ -380,25 +392,26 @@ namespace PKHeX.Core /// /// Pokémon to modify. /// to use (if already known). Will fetch the current if not provided. - public static void SetMarkings(this PKM pk, int[] IVs = null) + public static void SetMarkings(this PKM pk, int[] IVs) { if (pk.Format <= 3) return; // no markings (gen3 only has 4; can't mark stats intelligently - if (IVs == null) - IVs = pk.IVs; - - if (MarkingMethod == null) // shouldn't ever happen - throw new ArgumentNullException(nameof(MarkingMethod)); - var markings = IVs.Select(MarkingMethod(pk)).ToArray(); pk.Markings = PKX.ReorderSpeedLast(markings); } /// - /// Default when applying . + /// Sets the to indicate flawless (or near-flawless) . /// - public static Func> MarkingMethod { get; set; } = FlagHighLow; + /// Pokémon to modify. + public static void SetMarkings(this PKM pk) + { + if (pk.Format <= 3) + return; // no markings (gen3 only has 4; can't mark stats intelligently + + pk.SetMarkings(pk.IVs); + } private static Func FlagHighLow(PKM pk) { @@ -619,10 +632,8 @@ namespace PKHeX.Core /// Marking index to toggle /// Current marking values (optional) /// Current marking values - public static int[] ToggleMarking(this PKM pk, int index, int[] markings = null) + public static int[] ToggleMarking(this PKM pk, int index, int[] markings) { - if (markings == null) - markings = pk.Markings; switch (pk.Format) { case 3: @@ -633,13 +644,21 @@ namespace PKHeX.Core pk.Markings = markings; break; case 7: // 0 (none) | 1 (blue) | 2 (pink) - markings[index] = (markings[index] + 1) % 3; // cycle + markings[index] = (markings[index] + 1) % 3; // cycle 0->1->2->0... pk.Markings = markings; break; } return markings; } + /// + /// Toggles the marking at a given index. + /// + /// Pokémon to modify. + /// Marking index to toggle + /// Current marking values + public static int[] ToggleMarking(this PKM pk, int index) => pk.ToggleMarking(index, pk.Markings); + /// /// Sets the Memory details to a Hatched Egg's memories. /// @@ -670,16 +689,20 @@ namespace PKHeX.Core /// /// Pokémon to modify. /// Precomputed optional - public static void SetDefaultNickname(this PKM pk, LegalityAnalysis la = null) + public static void SetDefaultNickname(this PKM pk, LegalityAnalysis la) { - if (la == null) - la = new LegalityAnalysis(pk); if (la.Parsed && la.EncounterOriginal is EncounterTrade t && t.HasNickname) pk.SetNickname(t.GetNickname(pk.Language)); else pk.ClearNickname(); } + /// + /// Sets the to its default value. + /// + /// Pokémon to modify. + public static void SetDefaultNickname(this PKM pk) => pk.SetDefaultNickname(new LegalityAnalysis(pk)); + private static readonly string[] PotentialUnicode = { "★☆☆☆", "★★☆☆", "★★★☆", "★★★★" }; private static readonly string[] PotentialNoUnicode = { "+", "++", "+++", "++++" }; diff --git a/PKHeX.Core/Legality/Analysis.cs b/PKHeX.Core/Legality/Analysis.cs index b0653f0e2..911197bbc 100644 --- a/PKHeX.Core/Legality/Analysis.cs +++ b/PKHeX.Core/Legality/Analysis.cs @@ -392,7 +392,7 @@ namespace PKHeX.Core /// /// Gets the current array of four moves that might be legal. /// - public int[] GetSuggestedRelearn() + public IReadOnlyList GetSuggestedRelearn() { if (Info?.RelearnBase == null || Info.Generation < 6) return new int[4]; diff --git a/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs b/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs index 140ce9bc8..136cbbb4d 100644 --- a/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs +++ b/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs @@ -30,29 +30,19 @@ namespace PKHeX.Core /// Indicates if the databases are initialized. public static bool Initialized => MGDB_G3.Length != 0; - private static IEnumerable GetData(byte[] bin, int size) - { - for (int i = 0; i < bin.Length; i += size) - { - byte[] data = new byte[size]; - Buffer.BlockCopy(bin, i, data, 0, size); - yield return data; - } - } + private static HashSet GetPCDDB(byte[] bin) => new HashSet(ArrayUtil.EnumerateSplit(bin, PCD.Size).Select(d => new PCD(d))); - private static HashSet GetPCDDB(byte[] bin) => new HashSet(GetData(bin, PCD.Size).Select(d => new PCD(d))); - - private static HashSet GetPGFDB(byte[] bin) => new HashSet(GetData(bin, PGF.Size).Select(d => new PGF(d))); + private static HashSet GetPGFDB(byte[] bin) => new HashSet(ArrayUtil.EnumerateSplit(bin, PGF.Size).Select(d => new PGF(d))); private static HashSet GetWC6DB(byte[] wc6bin, byte[] wc6full) => new HashSet( - GetData(wc6full, WC6.SizeFull).Select(d => new WC6(d)) - .Concat(GetData(wc6bin, WC6.Size).Select(d => new WC6(d)))); + ArrayUtil.EnumerateSplit(wc6full, WC6.SizeFull).Select(d => new WC6(d)) + .Concat(ArrayUtil.EnumerateSplit(wc6bin, WC6.Size).Select(d => new WC6(d)))); private static HashSet GetWC7DB(byte[] wc7bin, byte[] wc7full) => new HashSet( - GetData(wc7full, WC7.SizeFull).Select(d => new WC7(d)) - .Concat(GetData(wc7bin, WC7.Size).Select(d => new WC7(d)))); + ArrayUtil.EnumerateSplit(wc7full, WC7.SizeFull).Select(d => new WC7(d)) + .Concat(ArrayUtil.EnumerateSplit(wc7bin, WC7.Size).Select(d => new WC7(d)))); - private static HashSet GetWB7DB(byte[] wc7full) => new HashSet(GetData(wc7full, WB7.SizeFull).Select(d => new WB7(d))); + private static HashSet GetWB7DB(byte[] wc7full) => new HashSet(ArrayUtil.EnumerateSplit(wc7full, WB7.SizeFull).Select(d => new WB7(d))); public static void RefreshMGDB(params string[] paths) { diff --git a/PKHeX.Core/Legality/Encounters/EncounterEgg.cs b/PKHeX.Core/Legality/Encounters/EncounterEgg.cs index eb896ac66..99cf5913c 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterEgg.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterEgg.cs @@ -71,12 +71,12 @@ namespace PKHeX.Core { switch (Species) { - case 774: // Minior + case (int)Core.Species.Minior: pk.AltForm = Util.Rand.Next(7, 14); break; - case 664: // Scatterbug - case 665: - case 666: + case (int)Core.Species.Scatterbug: + case (int)Core.Species.Spewpa: + case (int)Core.Species.Vivillon: pk.AltForm = Legal.GetVivillonPattern(SAV.Country, SAV.SubRegion); break; } diff --git a/PKHeX.Core/Legality/Encounters/EncounterSlot.cs b/PKHeX.Core/Legality/Encounters/EncounterSlot.cs index c1a3574f6..641769eec 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterSlot.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterSlot.cs @@ -159,17 +159,21 @@ namespace PKHeX.Core private static int GetWildAltForm(PKM pk, int form, ITrainerInfo SAV) { - if (form < 30) + if (form < 30) // specified form { switch (pk.Species) { - case 774: return Util.Rand.Next(7, 14); // Minior - default: return form; + case (int)Core.Species.Minior: + return Util.Rand.Next(7, 14); + default: + return form; } } - if (form == 31) + if (form == 31) // flagged as totally random return Util.Rand.Next(pk.PersonalInfo.FormeCount); - if (pk.Species == 664 || pk.Species == 665 || pk.Species == 666) + + int spec = pk.Species; + if (spec == (int)Core.Species.Scatterbug || spec == (int)Core.Species.Spewpa || spec == (int)Core.Species.Vivillon) return Legal.GetVivillonPattern(SAV.Country, SAV.SubRegion); return 0; } diff --git a/PKHeX.Core/Legality/Encounters/EncounterStaticShadow.cs b/PKHeX.Core/Legality/Encounters/EncounterStaticShadow.cs index dee6de8c0..3cc343d73 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterStaticShadow.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterStaticShadow.cs @@ -2,21 +2,36 @@ namespace PKHeX.Core { + /// + /// Shadow Pokémon Encounter found in + /// public sealed class EncounterStaticShadow : EncounterStatic { + /// + /// Team Specification with required , and Gender. + /// public TeamLock[] Locks { get; internal set; } = Array.Empty(); + + /// + /// Initial Shadow Gauge value. + /// public int Gauge { get; internal set; } + + /// + /// Originates from the EReader scans (Japanese Only) + /// public bool EReader { get; set; } internal override EncounterStatic Clone() { var result = (EncounterStaticShadow)base.Clone(); - if (Locks.Length > 0) - { - result.Locks = new TeamLock[Locks.Length]; - for (int i = 0; i < Locks.Length; i++) - result.Locks[i] = Locks[i].Clone(); - } + + if (Locks.Length == 0) + return result; + + result.Locks = new TeamLock[Locks.Length]; + for (int i = 0; i < Locks.Length; i++) + result.Locks[i] = Locks[i].Clone(); return result; } } diff --git a/PKHeX.Core/Legality/Encounters/EncounterStaticTyped.cs b/PKHeX.Core/Legality/Encounters/EncounterStaticTyped.cs index e4403928a..5d8ff7058 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterStaticTyped.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterStaticTyped.cs @@ -2,6 +2,9 @@ { public sealed class EncounterStaticTyped : EncounterStatic { + /// + /// values permitted for the encounter. + /// public EncounterType TypeEncounter { get; internal set; } = EncounterType.None; } } \ No newline at end of file diff --git a/PKHeX.Core/Legality/Encounters/EncounterTradeCatchRate.cs b/PKHeX.Core/Legality/Encounters/EncounterTradeCatchRate.cs index 0af0dc180..52b530cab 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterTradeCatchRate.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterTradeCatchRate.cs @@ -8,6 +8,9 @@ /// public sealed class EncounterTradeCatchRate : EncounterTrade { + /// + /// value the encounter is found with. + /// public uint Catch_Rate; } } \ No newline at end of file diff --git a/PKHeX.Core/Legality/Encounters/EncounterTradePID.cs b/PKHeX.Core/Legality/Encounters/EncounterTradePID.cs index fc4c3c041..375263485 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterTradePID.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterTradePID.cs @@ -5,7 +5,11 @@ /// public sealed class EncounterTradePID : EncounterTrade { + /// + /// Fixed value the encounter must have. + /// public uint PID; + public override Shiny Shiny { get; set; } = Shiny.FixedValue; protected override void SetPINGA(PKM pk, EncounterCriteria criteria) diff --git a/PKHeX.Core/Legality/Encounters/LegalInfo.cs b/PKHeX.Core/Legality/Encounters/LegalInfo.cs index ed713321b..115c0e8e3 100644 --- a/PKHeX.Core/Legality/Encounters/LegalInfo.cs +++ b/PKHeX.Core/Legality/Encounters/LegalInfo.cs @@ -35,7 +35,7 @@ namespace PKHeX.Core public bool WasXD => pkm?.Version == 15 && EncounterMatch is IVersion v && v.Version == GameVersion.XD; /// Base Relearn Moves for the . - public int[] RelearnBase { get; internal set; } + public IReadOnlyList RelearnBase { get; internal set; } /// Top level Legality Check result list for the . public readonly List Parse = new List(); diff --git a/PKHeX.Core/Legality/Encounters/Verifiers/EncounterVerifier.cs b/PKHeX.Core/Legality/Encounters/Verifiers/EncounterVerifier.cs index 35badec24..e7e49ede8 100644 --- a/PKHeX.Core/Legality/Encounters/Verifiers/EncounterVerifier.cs +++ b/PKHeX.Core/Legality/Encounters/Verifiers/EncounterVerifier.cs @@ -121,10 +121,11 @@ namespace PKHeX.Core // Check Species if (Legal.NoHatchFromEgg.Contains(pkm.Species)) return new CheckResult(Severity.Invalid, LEggSpecies, CheckIdentifier.Encounter); + switch (pkm.GenNumber) { case 1: - case 2: return new CheckResult(CheckIdentifier.Encounter); // no met location info + case 2: return new CheckResult(CheckIdentifier.Encounter); // valid -- no met location info case 3: return pkm.Format != 3 ? VerifyEncounterEgg3Transfer(pkm) : VerifyEncounterEgg3(pkm); case 4: return pkm.IsEgg ? VerifyUnhatchedEgg(pkm, Locations.LinkTrade4) : VerifyEncounterEgg4(pkm); case 5: return pkm.IsEgg ? VerifyUnhatchedEgg(pkm, Locations.LinkTrade5) : VerifyEncounterEgg5(pkm); diff --git a/PKHeX.Core/Legality/Encounters/Verifiers/EvolutionVerifier.cs b/PKHeX.Core/Legality/Encounters/Verifiers/EvolutionVerifier.cs index f9590fb09..285347b67 100644 --- a/PKHeX.Core/Legality/Encounters/Verifiers/EvolutionVerifier.cs +++ b/PKHeX.Core/Legality/Encounters/Verifiers/EvolutionVerifier.cs @@ -31,6 +31,7 @@ namespace PKHeX.Core { if (info.EvoChainsAllGens[pkm.Format].Count == 0) return false; // Can't exist as current species + int species = pkm.Species; if (info.EncounterMatch.Species == species) return true; @@ -42,8 +43,9 @@ namespace PKHeX.Core // If current species evolved with a move evolution and encounter species is not current species check if the evolution by move is valid // Only the evolution by move is checked, if there is another evolution before the evolution by move is covered in IsEvolutionValid - if (Legal.SpeciesEvolutionWithMove.Contains(pkm.Species)) + if (Legal.SpeciesEvolutionWithMove.Contains(species)) return Legal.IsEvolutionValidWithMove(pkm, info); + return true; } } diff --git a/PKHeX.Core/Legality/Encounters/Verifiers/MysteryGiftRestriction.cs b/PKHeX.Core/Legality/Encounters/Verifiers/MysteryGiftRestriction.cs index 9497bb989..bef36374e 100644 --- a/PKHeX.Core/Legality/Encounters/Verifiers/MysteryGiftRestriction.cs +++ b/PKHeX.Core/Legality/Encounters/Verifiers/MysteryGiftRestriction.cs @@ -2,6 +2,9 @@ using System; namespace PKHeX.Core { + /// + /// Restriction Flags for receiving 3DS/NDS era events. + /// [Flags] public enum MysteryGiftRestriction { @@ -36,6 +39,11 @@ namespace PKHeX.Core return (value & flag) != 0; } + /// + /// Checks the flags to pick out a language that can receive the gift. + /// + /// Flag value + /// Language ID; -1 if none public static int GetSuggestedLanguage(this MysteryGiftRestriction value) { for (int i = (int)LanguageID.Japanese; i <= (int)LanguageID.Korean; i++) diff --git a/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs b/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs index 857d925ae..8b7ebfb18 100644 --- a/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs +++ b/PKHeX.Core/Legality/Encounters/Verifiers/VerifyCurrentMoves.cs @@ -15,6 +15,12 @@ namespace PKHeX.Core /// public static class VerifyCurrentMoves { + /// + /// Verifies the current moves of the data based on the provided . + /// + /// Data to check + /// Encounter conditions and legality info + /// Validity of the public static CheckMoveResult[] VerifyMoves(PKM pkm, LegalInfo info) { int[] Moves = pkm.Moves; @@ -339,12 +345,14 @@ namespace PKHeX.Core else if (gen == info.Generation && learnInfo.Source.SpecialSource.Contains(move)) res[m] = new CheckMoveResult(Special, gen, Valid, LMoveSourceSpecial, Move); - if (gen >= 3 || res[m] == null || !res[m].Valid) + if (gen >= 3 || !IsCheckValid(res[m])) continue; // Gen1/Gen2 only below if (gen == 2 && learnInfo.Source.NonTradeBackLevelUpMoves.Contains(m)) + { learnInfo.Gen2PreevoMoves.Add(m); + } else if (gen == 1) { learnInfo.Gen1Moves.Add(m); @@ -837,6 +845,9 @@ namespace PKHeX.Core EncounterMoves.LevelUpMoves[2] = Legal.GetValidMoves(pkm, info.EvoChainsAllGens[2], generation: 2, minLvLG2: defaultLvlG2, LVL: true, Tutor: false, Machine: false, MoveReminder: false).ToList(); } + /// + /// Gets the generation numbers in descending order for iterating over. + /// public static int[] GetGenMovesCheckOrder(PKM pkm) { if (pkm.Format < 3) diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs b/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs index 3e2a0a6f2..a981e5c71 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs @@ -243,12 +243,13 @@ namespace PKHeX.Core }; } - if (pkm.Species == 292 && lvl >= 20 && (!pkm.HasOriginalMetLocation || pkm.Met_Level + 1 <= lvl)) + // Shedinja's evolution case can be a little tricky; hard-code handling. + if (pkm.Species == (int)Species.Shedinja && lvl >= 20 && (!pkm.HasOriginalMetLocation || pkm.Met_Level + 1 <= lvl)) { return new List(2) { - new EvoCriteria { Species = 292, Level = lvl, MinLevel = 20 }, - new EvoCriteria { Species = 290, Level = lvl, MinLevel = 1 } + new EvoCriteria { Species = (int)Species.Shedinja, Level = lvl, MinLevel = 20 }, + new EvoCriteria { Species = (int)Species.Nincada, Level = lvl, MinLevel = 1 } }; } @@ -272,6 +273,7 @@ namespace PKHeX.Core if (!pkm.HasOriginalMetLocation && generation != origin) return pkm.Met_Level; + // gen 3 and prior can't obtain anything at level 1 if (origin <= 3) return 2; diff --git a/PKHeX.Core/Legality/GBRestrictions.cs b/PKHeX.Core/Legality/GBRestrictions.cs index ad124e0e4..84425a040 100644 --- a/PKHeX.Core/Legality/GBRestrictions.cs +++ b/PKHeX.Core/Legality/GBRestrictions.cs @@ -14,7 +14,7 @@ namespace PKHeX { private static readonly int[] G1CaterpieMoves = { 33, 81 }; private static readonly int[] G1WeedleMoves = { 40, 81 }; - private static readonly int[] G1MetapodMoves = { 33, 81, 106 }; + //private static readonly int[] G1MetapodMoves = { 33, 81, 106 }; private static readonly int[] G1KakunaMoves = { 40, 81, 106 }; private static readonly int[] G1Exeggcute_IncompatibleMoves = { 78, 77, 79 }; diff --git a/PKHeX.Core/Legality/Memories.cs b/PKHeX.Core/Legality/Memories.cs index 35ade57e5..83e46c13b 100644 --- a/PKHeX.Core/Legality/Memories.cs +++ b/PKHeX.Core/Legality/Memories.cs @@ -2,6 +2,9 @@ namespace PKHeX.Core { + /// + /// Generation 6 Memory parameters & validation + /// public static class Memories { #region Tables diff --git a/PKHeX.Core/Legality/Verifiers/PIDVerifier.cs b/PKHeX.Core/Legality/Verifiers/PIDVerifier.cs index 0b1f39ca1..7b6b574a3 100644 --- a/PKHeX.Core/Legality/Verifiers/PIDVerifier.cs +++ b/PKHeX.Core/Legality/Verifiers/PIDVerifier.cs @@ -65,6 +65,7 @@ namespace PKHeX.Core if (d.Gift.PK.PID != 1 && pkm.EncryptionConstant != d.Gift.PK.PID) data.AddLine(GetInvalid(LEncGiftPIDMismatch, CheckIdentifier.Shiny)); break; + case WC7 wc7 when wc7.IsAshGreninjaWC7(pkm) && pkm.IsShiny: data.AddLine(GetInvalid(LEncGiftShinyMismatch, CheckIdentifier.Shiny)); break; @@ -105,6 +106,7 @@ namespace PKHeX.Core if (pkm.EncryptionConstant == 0) data.AddLine(Get(LPIDEncryptZero, Severity.Fishy, CheckIdentifier.EC)); + if (3 <= Info.Generation && Info.Generation <= 5) { VerifyTransferEC(data); diff --git a/PKHeX.Core/Legality/Verifiers/TransferVerifier.cs b/PKHeX.Core/Legality/Verifiers/TransferVerifier.cs index 5d4270d89..3f4230df6 100644 --- a/PKHeX.Core/Legality/Verifiers/TransferVerifier.cs +++ b/PKHeX.Core/Legality/Verifiers/TransferVerifier.cs @@ -105,7 +105,7 @@ namespace PKHeX.Core { // Check existing EncounterMatch if (encounter is EncounterInvalid || transfer == null) - yield break; // Avoid duplicate invaild message + yield break; // Avoid duplicate invalid message if (encounter is EncounterStatic v && (GameVersion.GBCartEraOnly.Contains(v.Version) || v.Version == GameVersion.VCEvents)) { diff --git a/PKHeX.Core/MysteryGifts/MysteryUtil.cs b/PKHeX.Core/MysteryGifts/MysteryUtil.cs index 128214613..d7475d305 100644 --- a/PKHeX.Core/MysteryGifts/MysteryUtil.cs +++ b/PKHeX.Core/MysteryGifts/MysteryUtil.cs @@ -5,6 +5,9 @@ using static PKHeX.Core.MessageStrings; namespace PKHeX.Core { + /// + /// Utility logic for dealing with objects. + /// public static class MysteryUtil { /// diff --git a/PKHeX.Core/MysteryGifts/WB7.cs b/PKHeX.Core/MysteryGifts/WB7.cs index 101708238..547f06dd9 100644 --- a/PKHeX.Core/MysteryGifts/WB7.cs +++ b/PKHeX.Core/MysteryGifts/WB7.cs @@ -70,7 +70,7 @@ namespace PKHeX.Core set => RawDate = SetDate(Year, Month, value); } - private static uint SetDate(uint year, uint month, uint day) => Math.Max(0, year - 2000) * 10000 + (month * 100) + day; + private static uint SetDate(uint year, uint month, uint day) => (Math.Max(0, year - 2000) * 10000) + (month * 100) + day; /// /// Gets or sets the date of the card. diff --git a/PKHeX.Core/MysteryGifts/WC3.cs b/PKHeX.Core/MysteryGifts/WC3.cs index 9ba9537c3..5f55e37a2 100644 --- a/PKHeX.Core/MysteryGifts/WC3.cs +++ b/PKHeX.Core/MysteryGifts/WC3.cs @@ -12,8 +12,6 @@ namespace PKHeX.Core /// public class WC3 : MysteryGift, IRibbonSetEvent3, IVersion { - // Template Properties - /// /// Matched Type /// diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs index 2f491646b..433210982 100644 --- a/PKHeX.Core/PKM/PKM.cs +++ b/PKHeX.Core/PKM/PKM.cs @@ -41,12 +41,7 @@ namespace PKHeX.Core public abstract byte[] OT_Trash { get; set; } public virtual byte[] HT_Trash { get; set; } - protected byte[] GetData(int Offset, int Length) - { - byte[] data = new byte[Length]; - Array.Copy(Data, Offset, data, 0, Length); - return data; - } + protected byte[] GetData(int Offset, int Length) => Data.Slice(Offset, Length); protected virtual ushort CalculateChecksum() { @@ -452,13 +447,15 @@ namespace PKHeX.Core public int[] RelearnMoves { get => new[] { RelearnMove1, RelearnMove2, RelearnMove3, RelearnMove4 }; - set - { - RelearnMove1 = value.Length > 0 ? value[0] : 0; - RelearnMove2 = value.Length > 1 ? value[1] : 0; - RelearnMove3 = value.Length > 2 ? value[2] : 0; - RelearnMove4 = value.Length > 3 ? value[3] : 0; - } + set => SetRelearnMoves(value); + } + + public void SetRelearnMoves(IReadOnlyList value) + { + RelearnMove1 = value.Count > 0 ? value[0] : 0; + RelearnMove2 = value.Count > 1 ? value[1] : 0; + RelearnMove3 = value.Count > 2 ? value[2] : 0; + RelearnMove4 = value.Count > 3 ? value[3] : 0; } public int PIDAbility diff --git a/PKHeX.Core/PKM/Shared/PokeListGB.cs b/PKHeX.Core/PKM/Shared/PokeListGB.cs index 370e4f172..add0649a5 100644 --- a/PKHeX.Core/PKM/Shared/PokeListGB.cs +++ b/PKHeX.Core/PKM/Shared/PokeListGB.cs @@ -104,15 +104,14 @@ namespace PKHeX.Core private T GetEntry(int base_ofs, int i) { - byte[] dat = new byte[Entry_Size]; - byte[] otname = new byte[StringLength]; - byte[] nick = new byte[StringLength]; int pkOfs = GetOffsetPKMData(base_ofs, i); int otOfs = GetOffsetPKMOT(base_ofs, i); int nkOfs = GetOffsetPKMNickname(base_ofs, i); - Buffer.BlockCopy(Data, pkOfs, dat, 0, Entry_Size); - Buffer.BlockCopy(Data, otOfs, otname, 0, StringLength); - Buffer.BlockCopy(Data, nkOfs, nick, 0, StringLength); + + var dat = Data.Slice(pkOfs, Entry_Size); + var otname = Data.Slice(otOfs, StringLength); + var nick = Data.Slice(nkOfs, StringLength); + return GetEntry(dat, otname, nick, Data[1 + i] == 0xFD); } diff --git a/PKHeX.Core/PKM/Shared/_K6.cs b/PKHeX.Core/PKM/Shared/_K6.cs index ace733c46..959165579 100644 --- a/PKHeX.Core/PKM/Shared/_K6.cs +++ b/PKHeX.Core/PKM/Shared/_K6.cs @@ -24,7 +24,7 @@ namespace PKHeX.Core protected override ushort CalculateChecksum() { ushort chk = 0; - for (int i = 8; i < 0xE8; i += 2) // fixed value; pb7 overrides stored size + for (int i = 8; i < PKX.SIZE_6STORED; i += 2) // don't use SIZE_STORED property; pb7 overrides stored size chk += BitConverter.ToUInt16(Data, i); return chk; } diff --git a/PKHeX.Core/PKM/Util/PKX.cs b/PKHeX.Core/PKM/Util/PKX.cs index fa17dcbcd..b732ccc9e 100644 --- a/PKHeX.Core/PKM/Util/PKX.cs +++ b/PKHeX.Core/PKM/Util/PKX.cs @@ -853,27 +853,6 @@ namespace PKHeX.Core return ctr - start; } - /// - /// Gets an list of PKM data from a concatenated byte array binary. - /// - /// - /// Length of each PKM byte[] - /// Starting offset to rip from. If omitted, will iterate from the start of the . - /// Ending offset to rip to. If omitted, will iterate to the end of the . - /// Enumerable list of PKM byte arrays - public static IEnumerable GetPKMDataFromConcatenatedBinary(byte[] data, int len, int start = 0, int end = -1) - { - if (end < 0) - end = data.Length; - // split up data to individual pkm - for (int i = start; i < end; i += len) - { - var pk = new byte[len]; - Buffer.BlockCopy(data, i, pk, 0, len); - yield return pk; - } - } - /// /// Detects the language of a or by checking the current Species name against possible names. /// diff --git a/PKHeX.Core/PersonalInfo/PersonalTable.cs b/PKHeX.Core/PersonalInfo/PersonalTable.cs index 62e98865f..883198b98 100644 --- a/PKHeX.Core/PersonalInfo/PersonalTable.cs +++ b/PKHeX.Core/PersonalInfo/PersonalTable.cs @@ -107,17 +107,6 @@ namespace PKHeX.Core return new PersonalTable(Util.GetBinaryResource($"personal_{game}"), format); } - private static byte[][] SplitBytes(byte[] data, int size) - { - byte[][] result = new byte[data.Length / size][]; - for (int i = 0; i < data.Length; i += size) - { - result[i / size] = new byte[size]; - Array.Copy(data, i, result[i / size], 0, size); - } - return result; - } - private static Func GetConstructor(GameVersion format) { switch (format) @@ -214,8 +203,8 @@ namespace PKHeX.Core { var get = GetConstructor(format); int size = GetEntrySize(format); - byte[][] entries = SplitBytes(data, size); - Table = new PersonalInfo[data.Length / size]; + byte[][] entries = ArrayUtil.Split(data, size); + Table = new PersonalInfo[entries.Length]; for (int i = 0; i < Table.Length; i++) Table[i] = get(entries[i]); @@ -310,7 +299,9 @@ namespace PKHeX.Core { int FormCount = this[i].FormeCount; FormList[i] = new string[FormCount]; - if (FormCount <= 0) continue; + if (FormCount <= 0) + continue; + FormList[i][0] = species[i]; for (int j = 1; j < FormCount; j++) FormList[i][j] = $"{species[i]} {j}"; diff --git a/PKHeX.Core/Saves/SaveFile.cs b/PKHeX.Core/Saves/SaveFile.cs index 035ec80de..0540af5c7 100644 --- a/PKHeX.Core/Saves/SaveFile.cs +++ b/PKHeX.Core/Saves/SaveFile.cs @@ -918,7 +918,7 @@ namespace PKHeX.Core var BD = BoxData; var entryLength = BlankPKM.EncryptedBoxData.Length; - var pkdata = PKX.GetPKMDataFromConcatenatedBinary(data, entryLength); + var pkdata = ArrayUtil.EnumerateSplit(data, entryLength); pkdata.Select(GetPKM).CopyTo(BD, IsSlotOverwriteProtected); BoxData = BD; return true; @@ -926,31 +926,6 @@ namespace PKHeX.Core #endregion } - public static class ArrayUtil - { - public static bool IsRangeAll(this byte[] data, int value, int offset, int length) - { - int start = offset + length - 1; - int end = offset; - for (int i = start; i >= end; i--) - { - if (data[i] != value) - return false; - } - - return true; - } - - public static byte[] Slice(this byte[] src, int offset, int length) - { - byte[] data = new byte[length]; - Buffer.BlockCopy(src, offset, data, 0, length); - return data; - } - - public static bool WithinRange(int value, int min, int max) => min <= value && value < max; - } - public static class StorageUtil { public static bool CompressStorage(this SaveFile sav, byte[] storage, out int storedCount, IList[] slotPointers) @@ -1000,20 +975,4 @@ namespace PKHeX.Core return true; } } - - public static class FlagUtil - { - public static bool GetFlag(byte[] arr, int offset, int bitIndex) - { - bitIndex &= 7; // ensure bit access is 0-7 - return (arr[offset] >> bitIndex & 1) != 0; - } - - public static void SetFlag(byte[] arr, int offset, int bitIndex, bool value) - { - bitIndex &= 7; // ensure bit access is 0-7 - arr[offset] &= (byte)~(1 << bitIndex); - arr[offset] |= (byte)((value ? 1 : 0) << bitIndex); - } - } } diff --git a/PKHeX.Core/Saves/Substructures/Gen6/SangoInfoBlock.cs b/PKHeX.Core/Saves/Substructures/Gen6/SangoInfoBlock.cs index f00b7080e..50663d20b 100644 --- a/PKHeX.Core/Saves/Substructures/Gen6/SangoInfoBlock.cs +++ b/PKHeX.Core/Saves/Substructures/Gen6/SangoInfoBlock.cs @@ -6,7 +6,7 @@ namespace PKHeX.Core { public SangoInfoBlock(SaveFile SAV, int offset) : base(SAV) => Offset = offset; - private const uint EON_MAGIC = 0x225D73C2; + private const uint EON_MAGIC = WC6.EonTicketConst; public uint EonTicketReceivedMagic // 0x319B8 { diff --git a/PKHeX.Core/Util/ArrayUtil.cs b/PKHeX.Core/Util/ArrayUtil.cs new file mode 100644 index 000000000..06b7d2a95 --- /dev/null +++ b/PKHeX.Core/Util/ArrayUtil.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; + +namespace PKHeX.Core +{ + /// + /// Byte array reusable logic + /// + public static class ArrayUtil + { + public static bool IsRangeAll(this byte[] data, int value, int offset, int length) + { + int start = offset + length - 1; + int end = offset; + for (int i = start; i >= end; i--) + { + if (data[i] != value) + return false; + } + + return true; + } + + public static byte[] Slice(this byte[] src, int offset, int length) + { + byte[] data = new byte[length]; + Buffer.BlockCopy(src, offset, data, 0, data.Length); + return data; + } + + public static bool WithinRange(int value, int min, int max) => min <= value && value < max; + + public static byte[][] Split(this byte[] data, int size) + { + byte[][] result = new byte[data.Length / size][]; + for (int i = 0; i < data.Length; i += size) + result[i / size] = data.Slice(i, size); + return result; + } + + public static IEnumerable EnumerateSplit(byte[] bin, int size, int start = 0) + { + for (int i = start; i < bin.Length; i += size) + yield return bin.Slice(i, size); + } + + public static IEnumerable EnumerateSplit(byte[] bin, int size, int start, int end) + { + if (end < 0) + end = bin.Length; + for (int i = start; i < end; i += size) + yield return bin.Slice(i, size); + } + } +} \ No newline at end of file diff --git a/PKHeX.Core/Util/FileUtil.cs b/PKHeX.Core/Util/FileUtil.cs index 302d07259..3149c096a 100644 --- a/PKHeX.Core/Util/FileUtil.cs +++ b/PKHeX.Core/Util/FileUtil.cs @@ -159,7 +159,7 @@ namespace PKHeX.Core var length = data.Length; if (PKX.IsPKM(length / SAV.SlotCount) || PKX.IsPKM(length / SAV.BoxSlotCount)) { - pkms = PKX.GetPKMDataFromConcatenatedBinary(data, length); + pkms = ArrayUtil.EnumerateSplit(data, length); return true; } pkms = Enumerable.Empty(); diff --git a/PKHeX.Core/Util/FlagUtil.cs b/PKHeX.Core/Util/FlagUtil.cs new file mode 100644 index 000000000..17713c850 --- /dev/null +++ b/PKHeX.Core/Util/FlagUtil.cs @@ -0,0 +1,21 @@ +namespace PKHeX.Core +{ + /// + /// Utility logic for dealing with bitflags in a byte array. + /// + public static class FlagUtil + { + public static bool GetFlag(byte[] arr, int offset, int bitIndex) + { + bitIndex &= 7; // ensure bit access is 0-7 + return (arr[offset] >> bitIndex & 1) != 0; + } + + public static void SetFlag(byte[] arr, int offset, int bitIndex, bool value) + { + bitIndex &= 7; // ensure bit access is 0-7 + arr[offset] &= (byte)~(1 << bitIndex); + arr[offset] |= (byte)((value ? 1 : 0) << bitIndex); + } + } +} \ No newline at end of file