From f6bcc8a21690fbc875fb956d4103a92b30a68b07 Mon Sep 17 00:00:00 2001 From: Kurt Date: Sat, 15 Jun 2024 00:57:44 -0500 Subject: [PATCH] Minor clean StringBuilder.Append has some fancy interpolation handling in the latest NET8 so it's more clean than multiple append calls. --- PKHeX.Core/Editing/PKM/QR/QRMessageUtil.cs | 9 +- .../Legality/LearnSource/MoveLearnInfo.cs | 2 +- PKHeX.Core/Legality/RNG/CXD/NPCLock.cs | 5 +- .../RNG/ClassicEra/Gen4/GenerateMethodK.cs | 4 - PKHeX.Core/MysteryGifts/PGT.cs | 1 - PKHeX.Core/MysteryGifts/WB8.cs | 4 +- PKHeX.Core/PKM/Strings/Font/StringFont8b.cs | 4 +- PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs | 13 +- .../Encryption/SwishCrypto/SCBlockUtil.cs | 10 +- PKHeX.Core/Saves/SAV4.cs | 1 - PKHeX.Core/Saves/SAV5B2W2.cs | 2 +- .../Saves/Substructures/Gen3/Decoration3.cs | 2 +- .../Substructures/Gen3/SecretBase3PKM.cs | 2 +- .../Saves/Substructures/Gen4/Record4.cs | 14 +- .../Substructures/Gen8/SWSH/RaidSpawnList8.cs | 2 +- .../Substructures/Gen9/RaidSpawnList9.cs | 2 +- .../Saves/Substructures/Misc/IGeonet.cs | 1 + PKHeX.Core/Util/DateUtil.cs | 2 +- PKHeX.Core/Util/FileUtil.cs | 4 +- .../Subforms/Save Editors/Gen3/SAV_Misc3.cs | 4 +- .../Subforms/Save Editors/Gen4/SAV_Misc4.cs | 4 +- .../Subforms/Save Editors/Gen8/SAV_Raid8.cs | 2 +- .../Gen9/SAV_PokedexSVKitakami.cs | 1 - .../Subforms/Save Editors/Gen9/SAV_Raid9.cs | 2 +- PKHeX.WinForms/Util/DevUtil.cs | 329 +++++++++--------- PKHeX.WinForms/Util/WinFormsUtil.cs | 2 +- .../General/Xoroshiro128Tests.cs | 1 - .../Legality/RNG/ShadowTests.cs | 4 +- Tests/PKHeX.Core.Tests/PKM/StringTests.cs | 4 +- 29 files changed, 216 insertions(+), 221 deletions(-) diff --git a/PKHeX.Core/Editing/PKM/QR/QRMessageUtil.cs b/PKHeX.Core/Editing/PKM/QR/QRMessageUtil.cs index 2c166fb78..37da54fde 100644 --- a/PKHeX.Core/Editing/PKM/QR/QRMessageUtil.cs +++ b/PKHeX.Core/Editing/PKM/QR/QRMessageUtil.cs @@ -1,6 +1,5 @@ using System; using System.Buffers; -using System.Text; namespace PKHeX.Core; @@ -55,10 +54,10 @@ public static class QRMessageUtil /// QR Message public static string GetMessage(ReadOnlySpan payload) { - var sb = new StringBuilder(payload.Length); - foreach (var b in payload) - sb.Append((char)b); - return sb.ToString(); + Span result = stackalloc char[payload.Length]; + for (int i = 0; i < payload.Length; i++) + result[i] = (char)payload[i]; + return new string(result); } /// diff --git a/PKHeX.Core/Legality/LearnSource/MoveLearnInfo.cs b/PKHeX.Core/Legality/LearnSource/MoveLearnInfo.cs index 77c4840e3..16f0f4183 100644 --- a/PKHeX.Core/Legality/LearnSource/MoveLearnInfo.cs +++ b/PKHeX.Core/Legality/LearnSource/MoveLearnInfo.cs @@ -25,7 +25,7 @@ public readonly record struct MoveLearnInfo(LearnMethod Method, LearnEnvironment sb.Append(Environment).Append('-'); sb.Append(localizedMethod); if (Method is LevelUp) - sb.Append(" @ lv").Append(Argument); + sb.Append($" @ lv{Argument}"); } private string GetLocalizedMethod() => Method switch diff --git a/PKHeX.Core/Legality/RNG/CXD/NPCLock.cs b/PKHeX.Core/Legality/RNG/CXD/NPCLock.cs index 68433eabc..6a1c7d505 100644 --- a/PKHeX.Core/Legality/RNG/CXD/NPCLock.cs +++ b/PKHeX.Core/Legality/RNG/CXD/NPCLock.cs @@ -52,10 +52,9 @@ public readonly record struct NPCLock sb.Append(" (Shadow)"); if (Seen) sb.Append(" [Seen]"); - sb.Append(" - "); - sb.Append("Nature: ").Append((Nature)Nature); + sb.Append($" - Nature: {(Nature)Nature}"); if (Gender != 2) - sb.Append(", ").Append("Gender: ").Append(Gender); + sb.Append($", Gender: {Gender}"); return sb.ToString(); } #endif diff --git a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs index f92ac3e3b..4c87a8c4c 100644 --- a/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs +++ b/PKHeX.Core/Legality/RNG/ClassicEra/Gen4/GenerateMethodK.cs @@ -124,10 +124,6 @@ public static class GenerateMethodK public static uint GetPIDRegular(uint a, uint b) => b << 16 | a; - private static void SetPIDIVSequential(PK4 pk, uint pid, uint rand) - { - } - private static (uint iv1, uint iv2) GetCombinedIVs(EncounterCriteria criteria) { uint iv1 = (uint)criteria.IV_HP | (uint)criteria.IV_ATK << 5 | (uint)criteria.IV_DEF << 10; diff --git a/PKHeX.Core/MysteryGifts/PGT.cs b/PKHeX.Core/MysteryGifts/PGT.cs index a0cf2639e..b8e10c210 100644 --- a/PKHeX.Core/MysteryGifts/PGT.cs +++ b/PKHeX.Core/MysteryGifts/PGT.cs @@ -352,4 +352,3 @@ public enum GiftSubType4 : byte Accessory = 2, Backdrop = 3, } - diff --git a/PKHeX.Core/MysteryGifts/WB8.cs b/PKHeX.Core/MysteryGifts/WB8.cs index a75454b36..9871533a4 100644 --- a/PKHeX.Core/MysteryGifts/WB8.cs +++ b/PKHeX.Core/MysteryGifts/WB8.cs @@ -705,7 +705,7 @@ public sealed class WB8(byte[] Data) : DataMysteryGift(Data), return IsMatchLocationExact(pk) || IsMatchLocationRemapped(pk); } - private bool IsMatchLocationExact(PKM pk) => pk.MetLocation == this.Location; + private bool IsMatchLocationExact(PKM pk) => pk.MetLocation == Location; private bool IsMatchLocationRemapped(PKM pk) { @@ -713,7 +713,7 @@ public sealed class WB8(byte[] Data) : DataMysteryGift(Data), var version = pk.Version; if (pk.Context == EntityContext.Gen8) return LocationsHOME.IsValidMetBDSP(met, version); - return LocationsHOME.GetMetSWSH(this.Location, version) == met; + return LocationsHOME.GetMetSWSH(Location, version) == met; } protected override bool IsMatchDeferred(PKM pk) => false; diff --git a/PKHeX.Core/PKM/Strings/Font/StringFont8b.cs b/PKHeX.Core/PKM/Strings/Font/StringFont8b.cs index 931a05770..6fc0cb33c 100644 --- a/PKHeX.Core/PKM/Strings/Font/StringFont8b.cs +++ b/PKHeX.Core/PKM/Strings/Font/StringFont8b.cs @@ -191,13 +191,13 @@ public static class StringFont8b '\uFB30', '\uFB31', '\uFB32', '\uFB33', '\uFB34', '\uFB35', '\uFB36', '\uFB38', '\uFB39', '\uFB3A', '\uFB3B', '\uFB3C', '\uFB3E', '\uFB40', '\uFB41', '\uFB43', '\uFB44', '\uFB46', '\uFB47', '\uFB48', '\uFB49', '\uFB4A', '\uFB4B', '\uFB4C', '\uFB4D', '\uFB4E', '\uFB4F', '\uFE20', '\uFE21', '\uFE22', '\uFE23', - '\uFFFC' + '\uFFFC', ]; public static ReadOnlySpan DefinedCHSExt => [ '\u0020', '\u002D', '\u003F', '\u0067', '\u00AA', '\u00B7', '\u00E9', '\u2013', '\u2018', '\u2019', '\u201C', '\u201D', '\u201E', '\u2026', '\u20BD', '\u21D2', '\u21D4', '\u2200', '\u2282', '\u2283', '\u25A0', '\u25BC', '\u25BD', '\u25CF', '\u2605', '\u2661', '\u2665', '\u266A', '\u266D', - '\u300A', '\u300B', '\u300C', '\u300D', '\u300E', '\u300F', '\u3010', '\u3011', '\u30FB', '\uFF08', '\uFF09', '\uFF65' + '\u300A', '\u300B', '\u300C', '\u300D', '\u300E', '\u300F', '\u3010', '\u3011', '\u30FB', '\uFF08', '\uFF09', '\uFF65', ]; } diff --git a/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs b/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs index 566d84100..ce98856dc 100644 --- a/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs +++ b/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs @@ -105,9 +105,8 @@ public static class TrainerInfoExtensions if (tr.Version != pk.Version) { - // PK9 does not store version for Picnic eggs. - if (pk is PK9 { Version: 0 }) { } - else { return false; } + if (!IsVersionlessState(pk)) + return false; } Span ot = stackalloc char[pk.MaxStringLengthTrainer]; @@ -119,6 +118,14 @@ public static class TrainerInfoExtensions return true; } + private static bool IsVersionlessState(PKM pk) + { + // PK9 does not store version for Picnic eggs. + if (pk is PK9 { Version: 0 }) // IsEgg is already true for all calls + return true; + return false; + } + private static bool IsMatchVersion(ITrainerInfo tr, PKM pk) { if (tr.Version == pk.Version) diff --git a/PKHeX.Core/Saves/Encryption/SwishCrypto/SCBlockUtil.cs b/PKHeX.Core/Saves/Encryption/SwishCrypto/SCBlockUtil.cs index 6c530bcb0..0e3b457af 100644 --- a/PKHeX.Core/Saves/Encryption/SwishCrypto/SCBlockUtil.cs +++ b/PKHeX.Core/Saves/Encryption/SwishCrypto/SCBlockUtil.cs @@ -119,15 +119,15 @@ public static class SCBlockUtil public static string GetBlockSummary(SCBlock b) { var sb = new StringBuilder(64); - sb.Append("Key: ").AppendFormat("{0:X8}", b.Key).AppendLine(); - sb.Append("Type: ").Append(b.Type).AppendLine(); + sb.AppendLine($"Key: {b.Key:X8}"); + sb.AppendLine($"Type: {b.Type}"); if (b.Data.Length != 0) - sb.Append("Length: ").AppendFormat("{0:X8}", b.Data.Length).AppendLine(); + sb.AppendLine($"Length: {b.Data.Length:X8}"); if (b.SubType != 0) - sb.Append("SubType: ").Append(b.SubType).AppendLine(); + sb.AppendLine($"SubType: {b.SubType}"); else if (b.HasValue()) - sb.Append("Value: ").Append(b.GetValue()).AppendLine(); + sb.AppendLine($"Value: {b.GetValue()}"); return sb.ToString(); } diff --git a/PKHeX.Core/Saves/SAV4.cs b/PKHeX.Core/Saves/SAV4.cs index 2e9152015..1c231241e 100644 --- a/PKHeX.Core/Saves/SAV4.cs +++ b/PKHeX.Core/Saves/SAV4.cs @@ -243,7 +243,6 @@ public abstract class SAV4 : SaveFile, IEventFlag37, IDaycareStorage, IDaycareRa protected int OFS_Record = int.MinValue; public Record4 Records => new(this, Data.AsMemory(OFS_Record, Record4.GetSize(this))); - // Storage public override int PartyCount { diff --git a/PKHeX.Core/Saves/SAV5B2W2.cs b/PKHeX.Core/Saves/SAV5B2W2.cs index e4a2585d4..a72e687b4 100644 --- a/PKHeX.Core/Saves/SAV5B2W2.cs +++ b/PKHeX.Core/Saves/SAV5B2W2.cs @@ -16,7 +16,7 @@ public sealed class SAV5B2W2 : SAV5, ISaveBlock5B2W2 public SaveBlockAccessor5B2W2 Blocks { get; } protected override SAV5B2W2 CloneInternal() => new((byte[]) Data.Clone()); public override int MaxItemID => Legal.MaxItemID_5_B2W2; - + public override IReadOnlyList AllBlocks => Blocks.BlockInfo; public override MyItem Items => Blocks.Items; public override Zukan5 Zukan => Blocks.Zukan; diff --git a/PKHeX.Core/Saves/Substructures/Gen3/Decoration3.cs b/PKHeX.Core/Saves/Substructures/Gen3/Decoration3.cs index edb75aed6..bb9d2615e 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/Decoration3.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/Decoration3.cs @@ -136,7 +136,7 @@ public enum DecorationCategory3 : byte Mat, Poster, Doll, - Cushion + Cushion, } public static class DecorationInfo diff --git a/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3PKM.cs b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3PKM.cs index af69e9d80..4bb1fad75 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3PKM.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3PKM.cs @@ -45,7 +45,7 @@ public sealed class SecretBase3PKM : ISpeciesForm { sb.Append($"{Species:000} - {g.Species[Species]}"); if (HeldItem != 0) - sb.Append(" @ ").Append(g.Item[HeldItem]); + sb.Append($" @ {g.Item[HeldItem]}"); sb.AppendLine(); var moveNames = g.Move; diff --git a/PKHeX.Core/Saves/Substructures/Gen4/Record4.cs b/PKHeX.Core/Saves/Substructures/Gen4/Record4.cs index be78467c3..9c48627d2 100644 --- a/PKHeX.Core/Saves/Substructures/Gen4/Record4.cs +++ b/PKHeX.Core/Saves/Substructures/Gen4/Record4.cs @@ -17,9 +17,9 @@ public sealed class Record4(SAV4 SAV, Memory raw) : SaveBlock(SAV, r { public static int GetSize(SAV4 SAV) => SAV switch { - SAV4DP => Record32DP * sizeof(uint) + Record16 * sizeof(ushort), - SAV4Pt => Record32Pt * sizeof(uint) + Record16 * sizeof(ushort) + 3 * sizeof(ushort), - SAV4HGSS => Record32HGSS * sizeof(uint) + Record16 * sizeof(ushort) + 3 * sizeof(ushort), + SAV4DP => (Record32DP * sizeof(uint)) +(Record16 * sizeof(ushort)), + SAV4Pt => (Record32Pt * sizeof(uint)) +(Record16 * sizeof(ushort)) + (3 * sizeof(ushort)), + SAV4HGSS => (Record32HGSS * sizeof(uint)) +(Record16 * sizeof(ushort)) + (3 * sizeof(ushort)), _ => throw new ArgumentOutOfRangeException(nameof(SAV)), }; @@ -70,7 +70,7 @@ public sealed class Record4(SAV4 SAV, Memory raw) : SaveBlock(SAV, r /// public uint CryptoSeed { - get => (SAV is SAV4DP) ? (ushort)0 : ReadUInt32LittleEndian(Data[^4..]); + get => (SAV is SAV4DP) ? 0 : ReadUInt32LittleEndian(Data[^4..]); set { if (SAV is not SAV4DP) WriteUInt32LittleEndian(Data[^4..], value); } } @@ -81,7 +81,7 @@ public sealed class Record4(SAV4 SAV, Memory raw) : SaveBlock(SAV, r { if (SAV is SAV4DP || IsDecrypted == state) // DP does not encrypt records return; - if (IsDecrypted && state == false) + if (IsDecrypted && !state) RefreshChecksum(); // refresh only on encrypt PokeCrypto.CryptArray(CryptoData, CryptoSeed); IsDecrypted = state; @@ -175,14 +175,14 @@ public sealed class Record4(SAV4 SAV, Memory raw) : SaveBlock(SAV, r public uint GetRecord32(int index) { - ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)Record32); + ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)Record32); EnsureDecrypted(); return ReadUInt32LittleEndian(Record32Data[(index * 4)..]); } public void SetRecord32(int index, uint value) { - ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)Record32); + ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)Record32); EnsureDecrypted(); WriteUInt32LittleEndian(Record32Data[(index * 4)..], Math.Min(GetMax32(index), value)); } diff --git a/PKHeX.Core/Saves/Substructures/Gen8/SWSH/RaidSpawnList8.cs b/PKHeX.Core/Saves/Substructures/Gen8/SWSH/RaidSpawnList8.cs index 337324804..8f14e2ca3 100644 --- a/PKHeX.Core/Saves/Substructures/Gen8/SWSH/RaidSpawnList8.cs +++ b/PKHeX.Core/Saves/Substructures/Gen8/SWSH/RaidSpawnList8.cs @@ -221,5 +221,5 @@ public enum MaxRaidOrigin: uint { Galar, IsleOfArmor, - CrownTundra + CrownTundra, } diff --git a/PKHeX.Core/Saves/Substructures/Gen9/RaidSpawnList9.cs b/PKHeX.Core/Saves/Substructures/Gen9/RaidSpawnList9.cs index f20cadacc..167da1e82 100644 --- a/PKHeX.Core/Saves/Substructures/Gen9/RaidSpawnList9.cs +++ b/PKHeX.Core/Saves/Substructures/Gen9/RaidSpawnList9.cs @@ -156,5 +156,5 @@ public enum TeraRaidOrigin : uint { Paldea, Kitakami, - BlueberryAcademy + BlueberryAcademy, } diff --git a/PKHeX.Core/Saves/Substructures/Misc/IGeonet.cs b/PKHeX.Core/Saves/Substructures/Misc/IGeonet.cs index 0e3b1cf4f..1f076d05c 100644 --- a/PKHeX.Core/Saves/Substructures/Misc/IGeonet.cs +++ b/PKHeX.Core/Saves/Substructures/Misc/IGeonet.cs @@ -31,6 +31,7 @@ public interface IGeonet /// /// Country index /// Subregion index + /// Point status void SetCountrySubregion(byte country, byte subregion, GeonetPoint point); /// diff --git a/PKHeX.Core/Util/DateUtil.cs b/PKHeX.Core/Util/DateUtil.cs index 8b77ebe1e..4ede531d1 100644 --- a/PKHeX.Core/Util/DateUtil.cs +++ b/PKHeX.Core/Util/DateUtil.cs @@ -60,7 +60,7 @@ public static class DateUtil value %= SecondsPerDay; sb.Append(new TimeOnly(ticks: value * TimeSpan.TicksPerSecond).ToString("HH:mm:ss")); if (secondsBias >= 0) - sb.Append(Environment.NewLine).Append("Date: ").Append(Epoch2000.AddSeconds(value + secondsBias)); + sb.Append(Environment.NewLine).Append($"Date: {Epoch2000.AddSeconds(value + secondsBias)}"); return sb.ToString(); } diff --git a/PKHeX.Core/Util/FileUtil.cs b/PKHeX.Core/Util/FileUtil.cs index 112d26e45..99b0cd648 100644 --- a/PKHeX.Core/Util/FileUtil.cs +++ b/PKHeX.Core/Util/FileUtil.cs @@ -210,11 +210,11 @@ public static class FileUtil /// Binary data /// Output result /// Format hint - /// Reference savefile used for PC Binary compatibility checks. + /// Reference save file used for PC Binary compatibility checks. /// True if file object reference is valid, false if none found. public static bool TryGetPKM(byte[] data, [NotNullWhen(true)] out PKM? pk, ReadOnlySpan ext, ITrainerInfo? sav = null) { - if (ext == ".pgt") // size collision with pk6 + if (ext.EndsWith("pgt")) // size collision with pk6 { pk = null; return false; diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_Misc3.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_Misc3.cs index f32df56f1..b2329630e 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_Misc3.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_Misc3.cs @@ -1,12 +1,10 @@ using System; -using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using PKHeX.Core; using static System.Buffers.Binary.BinaryPrimitives; -using static PKHeX.Core.DecorationCategory3; namespace PKHeX.WinForms; @@ -118,7 +116,7 @@ public partial class SAV_Misc3 : Form TB_B1.Text = Math.Min((ushort)9999, j.JoyfulBerriesInRow).ToString(); TB_B2.Text = Math.Min(99990, j.JoyfulBerriesScore).ToString(); TB_B3.Text = Math.Min((ushort)9999, j.JoyfulBerries5InRow).ToString(); - TB_BerryPowder.Text = Math.Min((uint)99999, j.BerryPowder).ToString(); + TB_BerryPowder.Text = Math.Min(99999u, j.BerryPowder).ToString(); } private void SaveJoyful(IGen3Joyful j) diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_Misc4.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_Misc4.cs index 1ce00487a..5e1664ca4 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_Misc4.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen4/SAV_Misc4.cs @@ -756,7 +756,7 @@ public partial class SAV_Misc4 : Form DGV_Seals.Columns.Add(dgvSlot); DGV_Seals.Columns.Add(dgvCount); - var count = (int)Seal4.MAX; + const int count = (int)Seal4.MAX; DGV_Seals.Rows.Add(count); for (int i = 0; i < count; i++) DGV_Seals.Rows[i].Cells[0].Value = seals[i]; @@ -825,7 +825,7 @@ public partial class SAV_Misc4 : Form DGV_Accessories.Columns.Add(dgvSlot); DGV_Accessories.Columns.Add(dgvCount); - var count = AccessoryInfo.Count; + const int count = AccessoryInfo.Count; DGV_Accessories.Rows.Add(count); for (int i = 0; i < count; i++) DGV_Accessories.Rows[i].Cells[0].Value = accessories[i]; diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen8/SAV_Raid8.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen8/SAV_Raid8.cs index ee0dd44ed..08e5e60f7 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen8/SAV_Raid8.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen8/SAV_Raid8.cs @@ -21,7 +21,7 @@ public partial class SAV_Raid8 : Form MaxRaidOrigin.Galar => SAV.RaidGalar, MaxRaidOrigin.IsleOfArmor => SAV.RaidArmor, MaxRaidOrigin.CrownTundra => SAV.RaidCrown, - _ => throw new ArgumentOutOfRangeException($"Raid Origin {raidOrigin} is not valid for Sword and Shield") + _ => throw new ArgumentOutOfRangeException($"Raid Origin {raidOrigin} is not valid for Sword and Shield"), }; CB_Den.Items.AddRange(Enumerable.Range(1, Raids.CountUsed).Select(z => (object)$"Den {z:000}").ToArray()); CB_Den.SelectedIndex = 0; diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_PokedexSVKitakami.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_PokedexSVKitakami.cs index 1becf1d1c..2c193ad46 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_PokedexSVKitakami.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_PokedexSVKitakami.cs @@ -156,7 +156,6 @@ public partial class SAV_PokedexSVKitakami : Form if (forms[0].Length == 0) forms[0] = GameInfo.Strings.Types[0]; - this.SuspendLayout(); // Clear all CheckedListBoxes var seen = CLB_FormSeen.Items; var obtained = CLB_FormObtained.Items; diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Raid9.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Raid9.cs index 316f1583d..16273115c 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Raid9.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen9/SAV_Raid9.cs @@ -22,7 +22,7 @@ public partial class SAV_Raid9 : Form TeraRaidOrigin.Paldea => SAV.RaidPaldea, TeraRaidOrigin.Kitakami => SAV.RaidKitakami, TeraRaidOrigin.BlueberryAcademy => SAV.RaidBlueberry, - _ => throw new ArgumentOutOfRangeException($"Raid Origin {raidOrigin} is not valid for Scarlet and Violet") + _ => throw new ArgumentOutOfRangeException($"Raid Origin {raidOrigin} is not valid for Scarlet and Violet"), }; CB_Raid.Items.AddRange(Enumerable.Range(1, Raids.CountUsed).Select(z => (object)$"Raid {z:000}").ToArray()); CB_Raid.SelectedIndex = 0; diff --git a/PKHeX.WinForms/Util/DevUtil.cs b/PKHeX.WinForms/Util/DevUtil.cs index 7e3e95cf9..85663b82f 100644 --- a/PKHeX.WinForms/Util/DevUtil.cs +++ b/PKHeX.WinForms/Util/DevUtil.cs @@ -7,182 +7,181 @@ using System.Windows.Forms; using PKHeX.Core; using PKHeX.WinForms.Controls; -namespace PKHeX.WinForms +namespace PKHeX.WinForms; + +public static class DevUtil { - public static class DevUtil + public static void AddControl(ToolStripDropDownItem t) { - public static void AddControl(ToolStripDropDownItem t) + t.DropDownItems.Add(GetTranslationUpdater()); + } + + private static readonly string[] Languages = ["ja", "fr", "it", "de", "es", "ko", "zh", "zh2"]; + private static string DefaultLanguage => Main.CurrentLanguage; + + public static bool IsUpdatingTranslations { get; private set; } + + /// + /// Call this to update all translatable resources (Program Messages, Legality Text, Program GUI) + /// + private static void UpdateAll() + { + if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Update translation files with current values?")) + return; + IsUpdatingTranslations = true; + DumpStringsLegality(); + DumpStringsMessage(); + UpdateTranslations(); + IsUpdatingTranslations = false; + } + + private static ToolStripMenuItem GetTranslationUpdater() + { + var ti = new ToolStripMenuItem { - t.DropDownItems.Add(GetTranslationUpdater()); + ShortcutKeys = Keys.Control | Keys.Alt | Keys.D, + Visible = false, + }; + ti.Click += (_, _) => UpdateAll(); + return ti; + } + + private static void UpdateTranslations() + { + var assembly = System.Reflection.Assembly.GetExecutingAssembly(); + var types = assembly.GetTypes(); + + // Trigger a translation then dump all. + foreach (var lang in Languages) // get all languages ready to go + _ = WinFormsTranslator.GetDictionary(lang); + WinFormsTranslator.SetUpdateMode(); + WinFormsTranslator.LoadSettings(DefaultLanguage); + WinFormsTranslator.LoadEnums(EnumTypesToTranslate, DefaultLanguage); + WinFormsTranslator.LoadAllForms(types, LoadBanlist); // populate with every possible control + WinFormsTranslator.TranslateControls(GetExtraControls(), DefaultLanguage); + var dir = GetResourcePath("PKHeX.WinForms", "Resources", "text"); + WinFormsTranslator.DumpAll(DefaultLanguage, Banlist, dir); // dump current to file + WinFormsTranslator.SetUpdateMode(false); + + // Move translated files from the debug exe loc to their project location + var files = Directory.GetFiles(Application.StartupPath); + foreach (var f in files) + { + var fn = Path.GetFileName(f); + if (!fn.EndsWith(".txt")) + continue; + if (!fn.StartsWith("lang_")) + continue; + + var loc = Path.Combine(dir, fn); + if (File.Exists(loc)) + File.Delete(loc); + File.Move(f, loc, true); } - private static readonly string[] Languages = ["ja", "fr", "it", "de", "es", "ko", "zh", "zh2"]; - private static string DefaultLanguage => Main.CurrentLanguage; + Application.Exit(); + } - public static bool IsUpdatingTranslations { get; private set; } + private static readonly Type[] EnumTypesToTranslate = + [ + typeof(StatusCondition), + typeof(PokeSize), + typeof(PokeSizeDetailed), - /// - /// Call this to update all translatable resources (Program Messages, Legality Text, Program GUI) - /// - private static void UpdateAll() + typeof(PassPower5), + typeof(Funfest5Mission), + typeof(OPower6Index), + typeof(OPower6FieldType), + typeof(OPower6BattleType), + typeof(PlayerBattleStyle7), + typeof(PlayerSkinColor7), + typeof(Stamp7), + typeof(FestivalPlazaFacilityColor), + ]; + + private static IEnumerable GetExtraControls() + { + foreach (var name in SlotList.GetEnumNames().Distinct()) + yield return new Label { Name = $"{nameof(Main)}.L_{name}", Text = name }; + } + + private static readonly string[] LoadBanlist = + [ + nameof(SplashScreen), + nameof(PokePreview), + ]; + + private static readonly string[] Banlist = + [ + "Gender=", // editor gender labels + "BTN_Shinytize", // ☆ + "Hidden_", // Hidden controls + "CAL_", // calendar controls now expose Text, don't care. + ".Count", // enum count + $"{nameof(Main)}.L_SizeH", // height rating + $"{nameof(Main)}.L_SizeW", // weight rating + $"{nameof(Main)}.L_SizeS", // scale rating + $"{nameof(Main)}.B_Box", // << and >> arrows + $"{nameof(Main)}.L_Characteristic=", // Characterstic (dynamic) + $"{nameof(Main)}.L_Potential", // ★☆☆☆ IV judge evaluation + $"{nameof(SAV_HoneyTree)}.L_Tree0", // dynamic, don't bother + $"{nameof(SAV_Misc3)}.BTN_Symbol", // symbols should stay as their current character + $"{nameof(SAV_GameSelect)}.L_Prompt", // prompt text (dynamic) + $"{nameof(SAV_BlockDump8)}.L_BlockName", // Block name (dynamic) + $"{nameof(SAV_PokedexResearchEditorLA)}.L_", // Dynamic label + $"{nameof(SAV_OPower)}.L_", // Dynamic label + ]; + + private static void DumpStringsMessage() => DumpStrings(typeof(MessageStrings), false, "PKHeX.Core", "Resources", "text", "program"); + private static void DumpStringsLegality() => DumpStrings(typeof(LegalityCheckStrings), true, "PKHeX.Core", "Resources", "legality", "checks"); + + private static void DumpStrings(Type t, bool sorted, params string[] rel) + { + var dir = GetResourcePath(rel); + DumpStrings(t, sorted, DefaultLanguage, dir); + foreach (var lang in Languages) + DumpStrings(t, sorted, lang, dir); + } + + private static void DumpStrings(Type t, bool sorted, string lang, string dir) + { + LocalizationUtil.SetLocalization(t, lang); + var entries = LocalizationUtil.GetLocalization(t); + IEnumerable export = entries.OrderBy(GetName); // sorted lines + + if (!sorted) + export = entries; + + var location = GetFileLocationInText(t.Name, dir, lang); + File.WriteAllLines(location, export); + LocalizationUtil.SetLocalization(t, DefaultLanguage); + + static string GetName(string line) { - if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Update translation files with current values?")) - return; - IsUpdatingTranslations = true; - DumpStringsLegality(); - DumpStringsMessage(); - UpdateTranslations(); - IsUpdatingTranslations = false; + var index = line.IndexOf('='); + if (index == -1) + return line; + return line[..index]; } + } - private static ToolStripMenuItem GetTranslationUpdater() + private static string GetFileLocationInText(string fileType, string dir, string lang) + { + var fn = $"{fileType}_{lang}.txt"; + return Path.Combine(dir, fn); + } + + private static string GetResourcePath(params string[] subdir) + { + // Starting from the executable path, crawl upwards until we get to the repository/sln root + const string repo = "PKHeX"; + var path = Application.StartupPath; + while (true) { - var ti = new ToolStripMenuItem - { - ShortcutKeys = Keys.Control | Keys.Alt | Keys.D, - Visible = false, - }; - ti.Click += (_, _) => UpdateAll(); - return ti; - } - - private static void UpdateTranslations() - { - var assembly = System.Reflection.Assembly.GetExecutingAssembly(); - var types = assembly.GetTypes(); - - // Trigger a translation then dump all. - foreach (var lang in Languages) // get all languages ready to go - _ = WinFormsTranslator.GetDictionary(lang); - WinFormsTranslator.SetUpdateMode(); - WinFormsTranslator.LoadSettings(DefaultLanguage); - WinFormsTranslator.LoadEnums(EnumTypesToTranslate, DefaultLanguage); - WinFormsTranslator.LoadAllForms(types, LoadBanlist); // populate with every possible control - WinFormsTranslator.TranslateControls(GetExtraControls(), DefaultLanguage); - var dir = GetResourcePath("PKHeX.WinForms", "Resources", "text"); - WinFormsTranslator.DumpAll(DefaultLanguage, Banlist, dir); // dump current to file - WinFormsTranslator.SetUpdateMode(false); - - // Move translated files from the debug exe loc to their project location - var files = Directory.GetFiles(Application.StartupPath); - foreach (var f in files) - { - var fn = Path.GetFileName(f); - if (!fn.EndsWith(".txt")) - continue; - if (!fn.StartsWith("lang_")) - continue; - - var loc = Path.Combine(dir, fn); - if (File.Exists(loc)) - File.Delete(loc); - File.Move(f, loc, true); - } - - Application.Exit(); - } - - private static readonly Type[] EnumTypesToTranslate = - [ - typeof(StatusCondition), - typeof(PokeSize), - typeof(PokeSizeDetailed), - - typeof(PassPower5), - typeof(Funfest5Mission), - typeof(OPower6Index), - typeof(OPower6FieldType), - typeof(OPower6BattleType), - typeof(PlayerBattleStyle7), - typeof(PlayerSkinColor7), - typeof(Stamp7), - typeof(FestivalPlazaFacilityColor), - ]; - - private static IEnumerable GetExtraControls() - { - foreach (var name in SlotList.GetEnumNames().Distinct()) - yield return new Label { Name = $"{nameof(Main)}.L_{name}", Text = name }; - } - - private static readonly string[] LoadBanlist = - [ - nameof(SplashScreen), - nameof(PokePreview), - ]; - - private static readonly string[] Banlist = - [ - "Gender=", // editor gender labels - "BTN_Shinytize", // ☆ - "Hidden_", // Hidden controls - "CAL_", // calendar controls now expose Text, don't care. - ".Count", // enum count - $"{nameof(Main)}.L_SizeH", // height rating - $"{nameof(Main)}.L_SizeW", // weight rating - $"{nameof(Main)}.L_SizeS", // scale rating - $"{nameof(Main)}.B_Box", // << and >> arrows - $"{nameof(Main)}.L_Characteristic=", // Characterstic (dynamic) - $"{nameof(Main)}.L_Potential", // ★☆☆☆ IV judge evaluation - $"{nameof(SAV_HoneyTree)}.L_Tree0", // dynamic, don't bother - $"{nameof(SAV_Misc3)}.BTN_Symbol", // symbols should stay as their current character - $"{nameof(SAV_GameSelect)}.L_Prompt", // prompt text (dynamic) - $"{nameof(SAV_BlockDump8)}.L_BlockName", // Block name (dynamic) - $"{nameof(SAV_PokedexResearchEditorLA)}.L_", // Dynamic label - $"{nameof(SAV_OPower)}.L_", // Dynamic label - ]; - - private static void DumpStringsMessage() => DumpStrings(typeof(MessageStrings), false, "PKHeX.Core", "Resources", "text", "program"); - private static void DumpStringsLegality() => DumpStrings(typeof(LegalityCheckStrings), true, "PKHeX.Core", "Resources", "legality", "checks"); - - private static void DumpStrings(Type t, bool sorted, params string[] rel) - { - var dir = GetResourcePath(rel); - DumpStrings(t, sorted, DefaultLanguage, dir); - foreach (var lang in Languages) - DumpStrings(t, sorted, lang, dir); - } - - private static void DumpStrings(Type t, bool sorted, string lang, string dir) - { - LocalizationUtil.SetLocalization(t, lang); - var entries = LocalizationUtil.GetLocalization(t); - IEnumerable export = entries.OrderBy(GetName); // sorted lines - - if (!sorted) - export = entries; - - var location = GetFileLocationInText(t.Name, dir, lang); - File.WriteAllLines(location, export); - LocalizationUtil.SetLocalization(t, DefaultLanguage); - - static string GetName(string line) - { - var index = line.IndexOf('='); - if (index == -1) - return line; - return line[..index]; - } - } - - private static string GetFileLocationInText(string fileType, string dir, string lang) - { - var fn = $"{fileType}_{lang}.txt"; - return Path.Combine(dir, fn); - } - - private static string GetResourcePath(params string[] subdir) - { - // Starting from the executable path, crawl upwards until we get to the repository/sln root - const string repo = "PKHeX"; - var path = Application.StartupPath; - while (true) - { - var parent = Directory.GetParent(path) ?? throw new DirectoryNotFoundException(path); - path = parent.FullName; - if (path.EndsWith(repo)) - return Path.Combine(path, Path.Combine(subdir)); - } + var parent = Directory.GetParent(path) ?? throw new DirectoryNotFoundException(path); + path = parent.FullName; + if (path.EndsWith(repo)) + return Path.Combine(path, Path.Combine(subdir)); } } } diff --git a/PKHeX.WinForms/Util/WinFormsUtil.cs b/PKHeX.WinForms/Util/WinFormsUtil.cs index 6b2ec3a01..18a9a43f1 100644 --- a/PKHeX.WinForms/Util/WinFormsUtil.cs +++ b/PKHeX.WinForms/Util/WinFormsUtil.cs @@ -262,7 +262,7 @@ public static class WinFormsUtil { var sb = new StringBuilder(128); foreach (var type in extensions) - sb.Append("*.").Append(type).Append(';'); + sb.Append($"*.{type};"); sb.Append("*.pk"); string supported = sb.ToString(); diff --git a/Tests/PKHeX.Core.Tests/General/Xoroshiro128Tests.cs b/Tests/PKHeX.Core.Tests/General/Xoroshiro128Tests.cs index 7c1e90f23..3a25dfee8 100644 --- a/Tests/PKHeX.Core.Tests/General/Xoroshiro128Tests.cs +++ b/Tests/PKHeX.Core.Tests/General/Xoroshiro128Tests.cs @@ -1,4 +1,3 @@ -using System; using FluentAssertions; using Xunit; diff --git a/Tests/PKHeX.Core.Tests/Legality/RNG/ShadowTests.cs b/Tests/PKHeX.Core.Tests/Legality/RNG/ShadowTests.cs index 1b34a338b..da2e7b7cd 100644 --- a/Tests/PKHeX.Core.Tests/Legality/RNG/ShadowTests.cs +++ b/Tests/PKHeX.Core.Tests/Legality/RNG/ShadowTests.cs @@ -128,7 +128,7 @@ public static class PIDTests [0xF2AC8419, 0xADA208E3, 0xDB3A0BA6, 0x5EEF1076], [0x9D28899D, 0xA3ECC9F0, 0x606EC6F0, 0x451FAE3C], }, - Delcatty + Delcatty, ]; yield return [ @@ -145,7 +145,7 @@ public static class PIDTests [0xC7315E32, 0x76566AA1, 0xC0CE436E, 0x98C45DA8, 0x9D1BDC4A], [0xB687F0AF, 0xC01DB6C6, 0xAD6DEC75, 0xDB041314, 0x0D949325], }, - Butterfree + Butterfree, ]; } diff --git a/Tests/PKHeX.Core.Tests/PKM/StringTests.cs b/Tests/PKHeX.Core.Tests/PKM/StringTests.cs index 7b6b850be..ca2f1c615 100644 --- a/Tests/PKHeX.Core.Tests/PKM/StringTests.cs +++ b/Tests/PKHeX.Core.Tests/PKM/StringTests.cs @@ -54,9 +54,9 @@ public class StringTests private static string Hex(ReadOnlySpan outdata) { - var sb = new System.Text.StringBuilder(outdata.Length); + var sb = new System.Text.StringBuilder(outdata.Length*3); foreach (var b in outdata) - sb.Append(b.ToString("X2")).Append(' '); + sb.Append($"{b:X2} "); return sb.ToString(); }