From 9a0fdcdcf4811f28f60d84a55bcdbe53682a91a3 Mon Sep 17 00:00:00 2001 From: Kurt Date: Mon, 13 Jul 2026 22:36:00 -0500 Subject: [PATCH] Misc tweaks No functional change --- .editorconfig | 2 +- .../Encounters/Data/EncounterEvent.cs | 1 + .../Legality/Learnset/LearnsetStadium.cs | 6 +- PKHeX.Core/Legality/LegalityAnalysis.cs | 140 +++++++++--------- PKHeX.Core/MysteryGifts/MysteryUtil.cs | 25 +++- PKHeX.Core/PKM/Searching/SearchSettings.cs | 2 +- .../Saves/Encryption/MemeCrypto/MemeKey.cs | 2 +- PKHeX.WinForms/MainWindow/Main.cs | 10 +- PKHeX.WinForms/Misc/QR.cs | 4 +- 9 files changed, 104 insertions(+), 88 deletions(-) diff --git a/.editorconfig b/.editorconfig index d92a4b202..3fd23ff31 100644 --- a/.editorconfig +++ b/.editorconfig @@ -29,7 +29,7 @@ dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggest dotnet_style_parentheses_in_other_operators = always_for_clarity:suggest csharp_indent_labels = one_less_than_current -csharp_prefer_braces = when_multiline:warning +csharp_prefer_braces = when_multiline:suggestion csharp_prefer_simple_using_statement = true:suggestion csharp_prefer_system_threading_lock = true:suggestion csharp_style_namespace_declarations = block_scoped:silent diff --git a/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs b/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs index f5522d880..330e3671a 100644 --- a/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs +++ b/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs @@ -148,6 +148,7 @@ public static void RefreshMGDB(params ReadOnlySpan paths) }; if (!added) Trace.WriteLine($"Failed to add gift in {Path.GetDirectoryName(path)}: {gift.FileName}"); + continue; static bool AddOrExpand([NotNullWhen(true)] ref HashSet? arr, ref List? extra, T obj) { diff --git a/PKHeX.Core/Legality/Learnset/LearnsetStadium.cs b/PKHeX.Core/Legality/Learnset/LearnsetStadium.cs index e6d03ba3a..640de3203 100644 --- a/PKHeX.Core/Legality/Learnset/LearnsetStadium.cs +++ b/PKHeX.Core/Legality/Learnset/LearnsetStadium.cs @@ -12,11 +12,9 @@ namespace PKHeX.Core; /// Moves may appear multiple times in the learnset, but only the first needs to be satisfied to be "valid" for Stadium 2's checks. /// https://bluemoonfalls.com/pages/general/move-reminder /// -public sealed class LearnsetStadium +public sealed class LearnsetStadium(ReadOnlySpan input) { - private readonly StadiumTuple[] Learn; - public LearnsetStadium(ReadOnlySpan input) - => Learn = MemoryMarshal.Cast(input).ToArray(); + private readonly StadiumTuple[] Learn = [.. MemoryMarshal.Cast(input)]; /// Gets all entries. public ReadOnlySpan GetMoves() => Learn; diff --git a/PKHeX.Core/Legality/LegalityAnalysis.cs b/PKHeX.Core/Legality/LegalityAnalysis.cs index b7f5ca853..af7c3bf4c 100644 --- a/PKHeX.Core/Legality/LegalityAnalysis.cs +++ b/PKHeX.Core/Legality/LegalityAnalysis.cs @@ -121,23 +121,11 @@ public LegalityAnalysis(PKM pk, IPersonalInfo pi, StorageSlotType source = Ignor EncounterFinder.FindVerifiedEncounter(pk, Info); if (!pk.IsOriginValid) AddLine(Severity.Invalid, EncConditionBadSpecies, CheckIdentifier.GameOrigin); - GetParseMethod()(); - - foreach (var ext in ExternalLegalityCheck.ExternalCheckers.Values) - ext.Verify(this); - - Valid = Parse.TrueForAll(chk => chk.Valid) - && MoveResult.AllValid(Info.Moves) - && MoveResult.AllValid(Info.Relearn); - + GetParseMethod(pk)(); + RunExternalVerifiers(); + Valid = AssertValid(); if (!Valid) - { - if (Info.EncounterMatch is EncounterInvalid && pk.IsUntraded && EvolutionTree.GetEvolutionTree(pk.Context).Reverse.GetReverse(pk.Species, pk.Form).First.Method.Method.IsTrade) - AddLine(Severity.Invalid, EvoInvalid, CheckIdentifier.Evolution); - if (IsPotentiallyMysteryGift(Info, pk)) - AddLine(Severity.Invalid, FatefulGiftMissing, CheckIdentifier.Fateful); - } - + GenerateHints(pk); Parsed = true; } #if SUPPRESS @@ -146,72 +134,90 @@ public LegalityAnalysis(PKM pk, IPersonalInfo pi, StorageSlotType source = Ignor { System.Diagnostics.Debug.WriteLine(e.Message); Valid = false; - - // Moves and Relearn arrays can potentially be empty on error. - foreach (ref var p in Info.Moves.AsSpan()) - { - if (!p.IsParsed) - p = MoveResult.Unobtainable(); - } - - foreach (ref var p in Info.Relearn.AsSpan()) - { - if (!p.IsParsed) - p = MoveResult.Unobtainable(); - } - + EnsureMovesPopulated(); // Moves and Relearn arrays can potentially be empty on error. AddLine(Severity.Invalid, Error, CheckIdentifier.Misc); } #endif } - private static bool IsPotentiallyMysteryGift(LegalInfo info, PKM pk) + private void GenerateHints(PKM pk) { - if (info.EncounterOriginal is not EncounterInvalid enc) - return false; - if (enc.Generation <= 3) - return pk.Format <= 3; - if (!pk.FatefulEncounter) - return false; - if (enc.Generation < 6) - return true; - if (!MoveResult.AllValid(info.Relearn)) - return true; - return false; + if (Info.EncounterMatch is not EncounterInvalid) + return; + if (pk.IsUntraded && EvolutionTree.GetEvolutionTree(pk.Context).Reverse.GetReverse(pk.Species, pk.Form).First.Method.Method.IsTrade) + AddLine(Severity.Invalid, EvoInvalid, CheckIdentifier.Evolution); } - private Action GetParseMethod() + private void RunExternalVerifiers() { - if (Entity.Format <= 2) // prior to storing GameVersion - return ParsePK1; + foreach (var ext in ExternalLegalityCheck.ExternalCheckers.Values) + ext.Verify(this); + } - var gen = GetParseFormat(); - return gen switch + private bool AssertValid() => Parse.TrueForAll(chk => chk.Valid) + && MoveResult.AllValid(Info.Moves) + && MoveResult.AllValid(Info.Relearn); + + private void EnsureMovesPopulated() + { + foreach (ref var p in Info.Moves.AsSpan()) { - 3 => ParsePK3, - 4 => ParsePK4, - 5 => ParsePK5, - 6 => ParsePK6, + if (!p.IsParsed) + p = MoveResult.Unobtainable(); + } - 1 => ParsePK7, - 2 => ParsePK7, - 7 => ParsePK7, - - 8 => ParsePK8, - 9 => ParsePK9, - - _ => throw new ArgumentOutOfRangeException(nameof(gen)), - }; + foreach (ref var p in Info.Relearn.AsSpan()) + { + if (!p.IsParsed) + p = MoveResult.Unobtainable(); + } } - private int GetParseFormat() + private Action GetParseMethod(PKM pk) => GetParseMethod(GetParseFormat(pk)); + + private Action GetParseMethod(LegalityParseFormat method) => method switch { - var gen = Entity.Generation; - if (gen != 0) - return gen; - if (Entity is PK9 { IsUnhatchedEgg: true }) - return 9; - return Entity.Format; + LegalityParseFormat.GameBoy => ParsePK1, + LegalityParseFormat.Gen3 => ParsePK3, + LegalityParseFormat.Gen4 => ParsePK4, + LegalityParseFormat.Gen5 => ParsePK5, + LegalityParseFormat.Gen6 => ParsePK6, + LegalityParseFormat.Gen7 => ParsePK7, + LegalityParseFormat.Gen8 => ParsePK8, + LegalityParseFormat.Gen9 => ParsePK9, + _ => throw new ArgumentOutOfRangeException(nameof(method)), + }; + + private enum LegalityParseFormat + { + GameBoy = 1, + Gen3 = 3, + Gen4 = 4, + Gen5 = 5, + Gen6 = 6, + Gen7 = 7, + Gen8 = 8, + Gen9 = 9, + } + + private static LegalityParseFormat GetParseFormat(PKM pk) + { + // prior to storing GameVersion + var format = pk.Format; + if (format < 3) + return LegalityParseFormat.GameBoy; + + var gen = pk.Generation; + if (gen > 0) + { + if (gen is 1 or 2) + gen = 7; // VC=>Gen7, treat as Gen7 + return (LegalityParseFormat)gen; + } + + if (pk is PK9 { IsUnhatchedEgg: true }) + return LegalityParseFormat.Gen9; + return (LegalityParseFormat)format; } private void ParsePK1() diff --git a/PKHeX.Core/MysteryGifts/MysteryUtil.cs b/PKHeX.Core/MysteryGifts/MysteryUtil.cs index 556b82b25..e68818636 100644 --- a/PKHeX.Core/MysteryGifts/MysteryUtil.cs +++ b/PKHeX.Core/MysteryGifts/MysteryUtil.cs @@ -46,16 +46,27 @@ public static IEnumerable GetGiftsFromFolder(string folder) /// List of lines public string GetTitleFromIndex(GameStrings strings) { - var titles = gift.Generation switch + var titles = gift.Context switch { - 7 => GameInfo.Strings.wondercard7, - 8 => GameInfo.Strings.wondercard8, - 9 => GameInfo.Strings.wondercard9, - _ => throw new ArgumentOutOfRangeException(nameof(gift), gift, null), + EntityContext.Gen7 => GameInfo.Strings.wondercard7, + EntityContext.Gen7b => GameInfo.Strings.wondercard7, + EntityContext.Gen8 => GameInfo.Strings.wondercard8, + EntityContext.Gen8a => GameInfo.Strings.wondercard8, + EntityContext.Gen8b => GameInfo.Strings.wondercard8, + EntityContext.Gen9 => GameInfo.Strings.wondercard9, + EntityContext.Gen9a => GameInfo.Strings.wondercard9, + _ => throw new ArgumentOutOfRangeException(nameof(gift.Context), gift.Context, null), }; if (gift.CardTitleIndex < 0 || gift.CardTitleIndex >= titles.Length || titles[gift.CardTitleIndex].Length == 0) return "Mystery Gift"; + // Need to format the string with the appropriate args, otherwise it will just show {0} and {1} in the title. + var args = gift.GetArgs(strings); + return string.Format(titles[gift.CardTitleIndex], args); + } + + private string[] GetArgs(GameStrings strings) + { var args = new string[15]; if (gift.IsEntity) { @@ -78,9 +89,9 @@ public string GetTitleFromIndex(GameStrings strings) // 10: G8 Ranked Battle season // 11: G8/9 title from affixed Ribbon/mark // 12: G8/9 cash back money amount - // 13: BDSP underground item + // 13: BD/SP underground item // 14: Z-A extra side mission - return string.Format(titles[gift.CardTitleIndex], args); + return args; } /// diff --git a/PKHeX.Core/PKM/Searching/SearchSettings.cs b/PKHeX.Core/PKM/Searching/SearchSettings.cs index 89373dba5..92c84b9e8 100644 --- a/PKHeX.Core/PKM/Searching/SearchSettings.cs +++ b/PKHeX.Core/PKM/Searching/SearchSettings.cs @@ -238,7 +238,7 @@ public ReadOnlyMemory GetVersions(SaveFile sav, GameVersion fallbac }; } - private static GameVersion GetFallbackVersion(ITrainerInfo sav) + private static GameVersion GetFallbackVersion(T sav) where T : IGeneration, IVersion { var parent = GameUtil.GetMetLocationVersionGroup(sav.Version); if (parent == Invalid) diff --git a/PKHeX.Core/Saves/Encryption/MemeCrypto/MemeKey.cs b/PKHeX.Core/Saves/Encryption/MemeCrypto/MemeKey.cs index 4bb508169..5fc7e21e4 100644 --- a/PKHeX.Core/Saves/Encryption/MemeCrypto/MemeKey.cs +++ b/PKHeX.Core/Saves/Encryption/MemeCrypto/MemeKey.cs @@ -33,7 +33,7 @@ public MemeKey(MemeKeyIndex key) if (key.CanSign()) D = new BigInteger(GetMemeDataSign(key), isUnsigned: true, isBigEndian: true); else - D = default; + D = BigInteger.Zero; } /// diff --git a/PKHeX.WinForms/MainWindow/Main.cs b/PKHeX.WinForms/MainWindow/Main.cs index 37d91955a..540d1a6d0 100644 --- a/PKHeX.WinForms/MainWindow/Main.cs +++ b/PKHeX.WinForms/MainWindow/Main.cs @@ -1181,7 +1181,7 @@ private void ClickClone(object sender, EventArgs e) { if (!PKME_Tabs.EditsComplete) return; // don't copy garbage to the box - PKM pk = PKME_Tabs.PreparePKM(); + var pk = PKME_Tabs.PreparePKM(); C_SAV.SetClonesToBox(pk); } @@ -1276,17 +1276,17 @@ private async void Dragout_MouseDown(object sender, MouseEventArgs e) pk.WriteEncryptedDataParty(data); // Create Temp File to Drag - var newfile = FileUtil.GetPKMTempFileName(pk, encrypt); + var newFile = FileUtil.GetPKMTempFileName(pk, encrypt); try { - await File.WriteAllBytesAsync(newfile, data).ConfigureAwait(true); + await File.WriteAllBytesAsync(newFile, data).ConfigureAwait(true); mainDragOutActive = true; var pb = (PictureBox)sender; if (pb.Image is Bitmap img) C_SAV.M.Drag.SetOwnedCursor(pb, img); - DoDragDrop(new DataObject(DataFormats.FileDrop, new[] { newfile }), DragDropEffects.Copy); + DoDragDrop(new DataObject(DataFormats.FileDrop, new[] { newFile }), DragDropEffects.Copy); } // Tons of things can happen with drag & drop; don't try to handle things, just indicate failure. catch (Exception x) @@ -1295,7 +1295,7 @@ private async void Dragout_MouseDown(object sender, MouseEventArgs e) { mainDragOutActive = false; C_SAV.M.Drag.ResetCursor(this); - await DeleteAsync(newfile, 20_000).ConfigureAwait(false); + await DeleteAsync(newFile, 20_000).ConfigureAwait(false); } PKME_Tabs.NotifyWasExported(preModify); // restore pre-modify state, in case the user drags into the same program window } diff --git a/PKHeX.WinForms/Misc/QR.cs b/PKHeX.WinForms/Misc/QR.cs index 138e33bc4..f39d5f79f 100644 --- a/PKHeX.WinForms/Misc/QR.cs +++ b/PKHeX.WinForms/Misc/QR.cs @@ -13,7 +13,7 @@ public partial class QR : Form private readonly Image icon; private Bitmap qr; - private readonly string[] Lines; + private readonly ReadOnlyMemory Lines; private string extraText = string.Empty; public QR(Bitmap qr, Image icon, params string[] lines) @@ -75,7 +75,7 @@ private void RefreshImage() var width = Math.Max(qr.Width, 370); var height = qr.Height + 50; - var img = QRImageUtil.GetQRImageExtended(font, qr, icon, width, height, Lines, extraText); + var img = QRImageUtil.GetQRImageExtended(font, qr, icon, width, height, Lines.Span, extraText); PB_QR.Image = img; }