diff --git a/PKHeX.Core/Editing/Program/IProgramSettings.cs b/PKHeX.Core/Editing/Program/IProgramSettings.cs new file mode 100644 index 000000000..0cf75bb2a --- /dev/null +++ b/PKHeX.Core/Editing/Program/IProgramSettings.cs @@ -0,0 +1,13 @@ +namespace PKHeX.Core; + +public interface IProgramSettings +{ + IStartupSettings Startup { get; } + BackupSettings Backup { get; } + SaveLanguageSettings SaveLanguage { get; } + SlotWriteSettings SlotWrite { get; } + SetImportSettings Import { get; } + LegalitySettings Legality { get; } + EntityConverterSettings Converter { get; } + LocalResourceSettings LocalResources { get; } +} diff --git a/PKHeX.Core/Editing/Program/IStartupSettings.cs b/PKHeX.Core/Editing/Program/IStartupSettings.cs index b206c0d56..c178b6fda 100644 --- a/PKHeX.Core/Editing/Program/IStartupSettings.cs +++ b/PKHeX.Core/Editing/Program/IStartupSettings.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; namespace PKHeX.Core; @@ -15,10 +15,14 @@ public interface IStartupSettings /// /// Method to load the environment's initial save file. /// - AutoLoadSetting AutoLoadSaveOnStartup { get; } + SaveFileLoadSetting AutoLoadSaveOnStartup { get; } /// /// List of recently loaded save file paths. /// List RecentlyLoaded { get; } + + string Version { get; set; } + bool ShowChangelogOnUpdate { get; set; } + bool ForceHaXOnLaunch { get; set; } } diff --git a/PKHeX.Core/Editing/Program/AutoLoadSetting.cs b/PKHeX.Core/Editing/Program/SaveFileLoadSetting.cs similarity index 94% rename from PKHeX.Core/Editing/Program/AutoLoadSetting.cs rename to PKHeX.Core/Editing/Program/SaveFileLoadSetting.cs index 3c1ccdaa7..39035319e 100644 --- a/PKHeX.Core/Editing/Program/AutoLoadSetting.cs +++ b/PKHeX.Core/Editing/Program/SaveFileLoadSetting.cs @@ -3,7 +3,7 @@ namespace PKHeX.Core; /// /// Option to load a save file automatically to an editing environment. /// -public enum AutoLoadSetting +public enum SaveFileLoadSetting { /// /// Doesn't autoload a save file, and instead uses a fake save file data. diff --git a/PKHeX.Core/Editing/Program/Settings/AdvancedSettings.cs b/PKHeX.Core/Editing/Program/Settings/AdvancedSettings.cs new file mode 100644 index 000000000..e8906200a --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/AdvancedSettings.cs @@ -0,0 +1,19 @@ +using System; +using System.ComponentModel; + +namespace PKHeX.Core; + +public sealed class AdvancedSettings +{ + [LocalizedDescription("Folder path that contains dump(s) of block hash-names. If a specific dump file does not exist, only names defined within the program's code will be loaded.")] + public string PathBlockKeyList { get; set; } = string.Empty; + + [LocalizedDescription("Hide event variables below this event type value. Removes event values from the GUI that the user doesn't care to view.")] + public NamedEventType HideEventTypeBelow { get; set; } + + [LocalizedDescription("Hide event variable names for that contain any of the comma-separated substrings below. Removes event values from the GUI that the user doesn't care to view.")] + public string HideEvent8Contains { get; set; } = string.Empty; + + [Browsable(false)] + public string[] GetExclusionList8() => Array.ConvertAll(HideEvent8Contains.Split(',', StringSplitOptions.RemoveEmptyEntries), z => z.Trim()); +} diff --git a/PKHeX.Core/Editing/Program/Settings/BackupSettings.cs b/PKHeX.Core/Editing/Program/Settings/BackupSettings.cs new file mode 100644 index 000000000..4df9693ff --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/BackupSettings.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace PKHeX.Core; + +public sealed class BackupSettings +{ + [LocalizedDescription("Automatic Backups of Save Files are copied to the backup folder when true.")] + public bool BAKEnabled { get; set; } = true; + + [LocalizedDescription("Tracks if the \"Create Backup\" prompt has been issued to the user.")] + public bool BAKPrompt { get; set; } + + [LocalizedDescription("List of extra locations to look for Save Files.")] + public List OtherBackupPaths { get; set; } = []; + + [LocalizedDescription("Save File file-extensions (no period) that the program should also recognize.")] + public List OtherSaveFileExtensions { get; set; } = []; +} diff --git a/PKHeX.Core/Editing/Program/Settings/EncounterDatabaseSettings.cs b/PKHeX.Core/Editing/Program/Settings/EncounterDatabaseSettings.cs new file mode 100644 index 000000000..b1667a257 --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/EncounterDatabaseSettings.cs @@ -0,0 +1,16 @@ +namespace PKHeX.Core; + +public sealed class EncounterDatabaseSettings +{ + [LocalizedDescription("Skips searching if the user forgot to enter Species / Move(s) into the search criteria.")] + public bool ReturnNoneIfEmptySearch { get; set; } = true; + + [LocalizedDescription("Hides unavailable Species if the currently loaded save file cannot import them.")] + public bool FilterUnavailableSpecies { get; set; } = true; + + [LocalizedDescription("Use properties from the PKM Editor tabs to specify criteria like Gender and Nature when generating an encounter.")] + public bool UseTabsAsCriteria { get; set; } = true; + + [LocalizedDescription("Use properties from the PKM Editor tabs even if the new encounter isn't the same evolution chain.")] + public bool UseTabsAsCriteriaAnySpecies { get; set; } = true; +} diff --git a/PKHeX.Core/Editing/Program/Settings/EntityConverterSettings.cs b/PKHeX.Core/Editing/Program/Settings/EntityConverterSettings.cs new file mode 100644 index 000000000..278d88c6f --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/EntityConverterSettings.cs @@ -0,0 +1,19 @@ +namespace PKHeX.Core; + +public sealed class EntityConverterSettings +{ + [LocalizedDescription("Allow PKM file conversion paths that are not possible via official methods. Individual properties will be copied sequentially.")] + public EntityCompatibilitySetting AllowIncompatibleConversion { get; set; } = EntityCompatibilitySetting.DisallowIncompatible; + + [LocalizedDescription("Allow PKM file conversion paths to guess the legal original encounter data that is not stored in the format that it was converted from.")] + public EntityRejuvenationSetting AllowGuessRejuvenateHOME { get; set; } = EntityRejuvenationSetting.MissingDataHOME; + + [LocalizedDescription("Default version to set when transferring from Generation 1 3DS Virtual Console to Generation 7.")] + public GameVersion VirtualConsoleSourceGen1 { get; set; } = GameVersion.RD; + + [LocalizedDescription("Default version to set when transferring from Generation 2 3DS Virtual Console to Generation 7.")] + public GameVersion VirtualConsoleSourceGen2 { get; set; } = GameVersion.SI; + + [LocalizedDescription("Retain the Met Date when transferring from Generation 4 to Generation 5.")] + public bool RetainMetDateTransfer45 { get; set; } +} diff --git a/PKHeX.Core/Editing/Program/Settings/EntityDatabaseSettings.cs b/PKHeX.Core/Editing/Program/Settings/EntityDatabaseSettings.cs new file mode 100644 index 000000000..86cc09015 --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/EntityDatabaseSettings.cs @@ -0,0 +1,26 @@ +namespace PKHeX.Core; + +public sealed class EntityDatabaseSettings +{ + [LocalizedDescription("When loading content for the PKM Database, search within backup save files.")] + public bool SearchBackups { get; set; } = true; + + [LocalizedDescription("When loading content for the PKM Database, search within OtherBackupPaths.")] + public bool SearchExtraSaves { get; set; } = true; + + [LocalizedDescription("When loading content for the PKM Database, search subfolders within OtherBackupPaths.")] + public bool SearchExtraSavesDeep { get; set; } = true; + + [LocalizedDescription("When loading content for the PKM database, the list will be ordered by this option.")] + public DatabaseSortMode InitialSortMode { get; set; } + + [LocalizedDescription("Hides unavailable Species if the currently loaded save file cannot import them.")] + public bool FilterUnavailableSpecies { get; set; } = true; +} + +public enum DatabaseSortMode +{ + None, + SpeciesForm, + SlotIdentity, +} diff --git a/PKHeX.Core/Editing/Program/Settings/LocalResourceSettings.cs b/PKHeX.Core/Editing/Program/Settings/LocalResourceSettings.cs new file mode 100644 index 000000000..aaa00690a --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/LocalResourceSettings.cs @@ -0,0 +1,47 @@ +using System.IO; +using System.Text.Json.Serialization; + +namespace PKHeX.Core; + +public sealed class LocalResourceSettings +{ + [JsonIgnore] + private string LocalPath = string.Empty; + + public void SetLocalPath(string workingDirectory) => LocalPath = workingDirectory; + + private string Resolve(string path) + { + if (string.IsNullOrWhiteSpace(path)) + return LocalPath; + return Path.IsPathRooted(path) ? path : Path.Combine(LocalPath, path); + } + + [LocalizedDescription("Path to the PKM Database folder.")] + public string DatabasePath { get; set; } = "pkmdb"; + public string GetDatabasePath() => Resolve(DatabasePath); + + [LocalizedDescription("Path to the Mystery Gift Database folder for storing extra mystery gift templates that aren't yet recognized.")] + public string MGDatabasePath { get; set; } = "mgdb"; + public string GetMGDatabasePath() => Resolve(MGDatabasePath); + + [LocalizedDescription("Path to the backup folder for keeping save file backups.")] + public string BackupPath { get; set; } = "bak"; + public string GetBackupPath() => Resolve(BackupPath); + + [LocalizedDescription("Path to the sounds folder for sounds to play when hovering over a slot (species cry).")] + public string SoundPath { get; set; } = "sounds"; + public string GetCryPath() => Resolve(SoundPath); + + [LocalizedDescription("Path to the template folder (with *.pk files) for initializing the PKM editor fields when a save file is loaded.")] + public string TemplatePath { get; set; } = "template"; + public string GetTemplatePath() => Resolve(TemplatePath); + + [LocalizedDescription("Path to the Trainers folder (with *.pk files) used for generating encounters with known Trainer data.")] + public string TrainerPath { get; set; } = "trainers"; + public string GetTrainerPath() => Resolve(TrainerPath); + + [LocalizedDescription("Path to the plugins folder.")] + public string PluginPath { get; set; } = "plugins"; + public string GetPluginPath() => Resolve(PluginPath); +} diff --git a/PKHeX.Core/Editing/Program/Settings/MysteryGiftDatabaseSettings.cs b/PKHeX.Core/Editing/Program/Settings/MysteryGiftDatabaseSettings.cs new file mode 100644 index 000000000..231ab6f76 --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/MysteryGiftDatabaseSettings.cs @@ -0,0 +1,7 @@ +namespace PKHeX.Core; + +public sealed class MysteryGiftDatabaseSettings +{ + [LocalizedDescription("Hides gifts if the currently loaded save file cannot (indirectly) receive them.")] + public bool FilterUnavailableSpecies { get; set; } = true; +} diff --git a/PKHeX.Core/Editing/Program/Settings/PrivacySettings.cs b/PKHeX.Core/Editing/Program/Settings/PrivacySettings.cs new file mode 100644 index 000000000..cd8afd05e --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/PrivacySettings.cs @@ -0,0 +1,10 @@ +namespace PKHeX.Core; + +public sealed class PrivacySettings +{ + [LocalizedDescription("Hide Save File Details in Program Title")] + public bool HideSAVDetails { get; set; } + + [LocalizedDescription("Hide Secret Details in Editors")] + public bool HideSecretDetails { get; set; } +} diff --git a/PKHeX.Core/Editing/Program/Settings/ReportGridSettings.cs b/PKHeX.Core/Editing/Program/Settings/ReportGridSettings.cs new file mode 100644 index 000000000..42960232b --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/ReportGridSettings.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; + +namespace PKHeX.Core; + +public sealed class ReportGridSettings +{ + [LocalizedDescription("Extra entity properties to try and show in addition to the default properties displayed.")] + public List ExtraProperties { get; set; } = []; + + [LocalizedDescription("Properties to hide from the report grid.")] + public List HiddenProperties { get; set; } = []; +} diff --git a/PKHeX.Core/Editing/Program/Settings/SaveLanguageSettings.cs b/PKHeX.Core/Editing/Program/Settings/SaveLanguageSettings.cs new file mode 100644 index 000000000..d4905125f --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/SaveLanguageSettings.cs @@ -0,0 +1,44 @@ +using System.ComponentModel; + +namespace PKHeX.Core; + +public sealed class SaveLanguageSettings +{ + [LocalizedDescription("Gen1: If unable to detect a language or version for a save file, use these instead.")] + public LangVersion OverrideGen1 { get; set; } = new(); + + [LocalizedDescription("Gen2: If unable to detect a language or version for a save file, use these instead.")] + public LangVersion OverrideGen2 { get; set; } = new(); + + [LocalizedDescription("Gen3 R/S: If unable to detect a language or version for a save file, use these instead.")] + public LangVersion OverrideGen3RS { get; set; } = new(); + + [LocalizedDescription("Gen3 FR/LG: If unable to detect a language or version for a save file, use these instead.")] + public LangVersion OverrideGen3FRLG { get; set; } = new(); + + [TypeConverter(typeof(ExpandableObjectConverter))] + public sealed record LangVersion + { + public LanguageID Language { get; set; } = LanguageID.English; + public GameVersion Version { get; set; } + } + + public void Apply() + { + SaveLanguage.OverrideLanguageGen1 = OverrideGen1.Language; + if (OverrideGen1.Version.IsGen1()) + SaveLanguage.OverrideVersionGen1 = OverrideGen1.Version; + + SaveLanguage.OverrideLanguageGen2 = OverrideGen2.Language; + if (OverrideGen2.Version is GameVersion.GD or GameVersion.SI) + SaveLanguage.OverrideVersionGen2 = OverrideGen2.Version; + + SaveLanguage.OverrideLanguageGen3RS = OverrideGen3RS.Language; + if (OverrideGen3RS.Version is GameVersion.R or GameVersion.S) + SaveLanguage.OverrideVersionGen3RS = OverrideGen3RS.Version; + + SaveLanguage.OverrideLanguageGen3FRLG = OverrideGen3FRLG.Language; + if (OverrideGen3FRLG.Version is GameVersion.FR or GameVersion.LG) + SaveLanguage.OverrideVersionGen3FRLG = OverrideGen3FRLG.Version; + } +} diff --git a/PKHeX.Core/Editing/Program/Settings/SetImportSettings.cs b/PKHeX.Core/Editing/Program/Settings/SetImportSettings.cs new file mode 100644 index 000000000..f49e3f793 --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/SetImportSettings.cs @@ -0,0 +1,9 @@ +namespace PKHeX.Core; + +public sealed class SetImportSettings +{ + [LocalizedDescription("Apply StatNature to Nature on Import")] + public bool ApplyNature { get; set; } = true; + [LocalizedDescription("Apply Markings on Import")] + public bool ApplyMarkings { get; set; } = true; +} diff --git a/PKHeX.Core/Editing/Program/Settings/SlotWriteSettings.cs b/PKHeX.Core/Editing/Program/Settings/SlotWriteSettings.cs new file mode 100644 index 000000000..a90aa9d04 --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/SlotWriteSettings.cs @@ -0,0 +1,16 @@ +namespace PKHeX.Core; + +public sealed class SlotWriteSettings +{ + [LocalizedDescription("Automatically modify the Save File's Pokédex when injecting a PKM.")] + public bool SetUpdateDex { get; set; } = true; + + [LocalizedDescription("Automatically adapt the PKM Info to the Save File (Handler, Format)")] + public bool SetUpdatePKM { get; set; } = true; + + [LocalizedDescription("Automatically increment the Save File's counters for obtained Pokémon (eggs/captures) when injecting a PKM.")] + public bool SetUpdateRecords { get; set; } = true; + + [LocalizedDescription("When enabled and closing/loading a save file, the program will alert if the current save file has been modified without saving.")] + public bool ModifyUnset { get; set; } = true; +} diff --git a/PKHeX.Core/Editing/Program/Settings/SoundSettings.cs b/PKHeX.Core/Editing/Program/Settings/SoundSettings.cs new file mode 100644 index 000000000..57cae2813 --- /dev/null +++ b/PKHeX.Core/Editing/Program/Settings/SoundSettings.cs @@ -0,0 +1,9 @@ +namespace PKHeX.Core; + +public sealed class SoundSettings +{ + [LocalizedDescription("Play Sound when loading a new Save File")] + public bool PlaySoundSAVLoad { get; set; } = true; + [LocalizedDescription("Play Sound when popping up Legality Report")] + public bool PlaySoundLegalityCheck { get; set; } = true; +} diff --git a/PKHeX.Core/Editing/Program/StartupArguments.cs b/PKHeX.Core/Editing/Program/StartupArguments.cs index 1f0996341..9a5fa8f24 100644 --- a/PKHeX.Core/Editing/Program/StartupArguments.cs +++ b/PKHeX.Core/Editing/Program/StartupArguments.cs @@ -15,13 +15,13 @@ public sealed class StartupArguments public SaveFile? SAV { get; private set; } // ReSharper disable once UnassignedGetOnlyAutoProperty - public Exception? Error { get; } + public Exception? Error { get; internal set; } public readonly List Extra = []; /// /// Step 1: Reads in command line arguments. /// - public void ReadArguments(IEnumerable args) + public void ReadArguments(ReadOnlySpan args) { foreach (var path in args) { @@ -69,15 +69,15 @@ public void ReadTemplateIfNoEntity(string path) private static SaveFile? ReadSettingsDefinedPKM(IStartupSettings startup, PKM pk) => startup.AutoLoadSaveOnStartup switch { - AutoLoadSetting.RecentBackup => SaveFinder.DetectSaveFiles(new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token).FirstOrDefault(z => z.IsCompatiblePKM(pk)), - AutoLoadSetting.LastLoaded => GetMostRecentlyLoaded(startup.RecentlyLoaded).FirstOrDefault(z => z.IsCompatiblePKM(pk)), + SaveFileLoadSetting.RecentBackup => SaveFinder.DetectSaveFiles(new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token).FirstOrDefault(z => z.IsCompatiblePKM(pk)), + SaveFileLoadSetting.LastLoaded => GetMostRecentlyLoaded(startup.RecentlyLoaded).FirstOrDefault(z => z.IsCompatiblePKM(pk)), _ => null, }; private static SaveFile? ReadSettingsAnyPKM(IStartupSettings startup) => startup.AutoLoadSaveOnStartup switch { - AutoLoadSetting.RecentBackup => SaveFinder.DetectSaveFiles(new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token).FirstOrDefault(), - AutoLoadSetting.LastLoaded => GetMostRecentlyLoaded(startup.RecentlyLoaded).FirstOrDefault(), + SaveFileLoadSetting.RecentBackup => SaveFinder.DetectSaveFiles(new CancellationTokenSource(TimeSpan.FromSeconds(5)).Token).FirstOrDefault(), + SaveFileLoadSetting.LastLoaded => GetMostRecentlyLoaded(startup.RecentlyLoaded).FirstOrDefault(), _ => null, }; diff --git a/PKHeX.Core/Editing/Program/StartupUtil.cs b/PKHeX.Core/Editing/Program/StartupUtil.cs new file mode 100644 index 000000000..8b13edebf --- /dev/null +++ b/PKHeX.Core/Editing/Program/StartupUtil.cs @@ -0,0 +1,99 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; + +namespace PKHeX.Core; + +/// +/// Logic for startup initialization and argument parsing. +/// +public static class StartupUtil +{ + public static void ReloadSettings(IProgramSettings settings) + { + var backup = settings.Backup; + SaveFinder.CustomBackupPaths.Clear(); + SaveFinder.CustomBackupPaths.AddRange(backup.OtherBackupPaths.Where(Directory.Exists)); + + settings.SaveLanguage.Apply(); + + var write = settings.SlotWrite; + SaveFile.SetUpdateDex = write.SetUpdateDex ? EntityImportOption.Enable : EntityImportOption.Disable; + SaveFile.SetUpdatePKM = write.SetUpdatePKM ? EntityImportOption.Enable : EntityImportOption.Disable; + SaveFile.SetUpdateRecords = write.SetUpdateRecords ? EntityImportOption.Enable : EntityImportOption.Disable; + CommonEdits.ShowdownSetIVMarkings = settings.Import.ApplyMarkings; + CommonEdits.ShowdownSetBehaviorNature = settings.Import.ApplyNature; + ParseSettings.Initialize(settings.Legality); + + var converter = settings.Converter; + EntityConverter.AllowIncompatibleConversion = converter.AllowIncompatibleConversion; + EntityConverter.RejuvenateHOME = converter.AllowGuessRejuvenateHOME; + EntityConverter.VirtualConsoleSourceGen1 = converter.VirtualConsoleSourceGen1; + EntityConverter.VirtualConsoleSourceGen2 = converter.VirtualConsoleSourceGen2; + EntityConverter.RetainMetDateTransfer45 = converter.RetainMetDateTransfer45; + + var mgdb = settings.LocalResources.GetMGDatabasePath(); + if (!Directory.Exists(mgdb)) + return; + new Task(() => EncounterEvent.RefreshMGDB(mgdb)).Start(); + } + + public static ProgramInit FormLoadInitialActions(ReadOnlySpan args, IStartupSettings startup, BackupSettings backup, Version currentVersion) + { + // Check if there is an update available + var showChangelog = GetShowChangelog(currentVersion, startup); + // Remember the current version for next run + + // HaX behavior requested + var hax = startup.ForceHaXOnLaunch || GetIsHaX(args); + + // Prompt to create a backup folder + var showAskBackupFolderCreate = !backup.BAKPrompt; + if (showAskBackupFolderCreate) + backup.BAKPrompt = true; // Never prompt after this run, unless changed in settings + + startup.Version = currentVersion.ToString(); + return new ProgramInit(showChangelog, showAskBackupFolderCreate, hax); + } + + private static bool GetShowChangelog(Version currentVersion, IStartupSettings startup) + { + if (!startup.ShowChangelogOnUpdate) + return false; + if (!Version.TryParse(startup.Version, out var lastRun)) + return false; + return lastRun < currentVersion; + } + + public static StartupArguments GetStartup(ReadOnlySpan args, IStartupSettings startup, LocalResourceSettings localResource) + { + var result = new StartupArguments(); + try + { + result.ReadArguments(args); + result.ReadSettings(startup); + result.ReadTemplateIfNoEntity(localResource.GetTemplatePath()); + } catch (Exception ex) + { + // If an error occurs, store it in the result for later handling + result.Error = ex; + } + return result; + } + + private static bool GetIsHaX(ReadOnlySpan args) + { + foreach (var x in args) + { + var arg = x.AsSpan().Trim('-'); + if (arg.Equals("HaX", StringComparison.CurrentCultureIgnoreCase)) + return true; + } + + ReadOnlySpan path = Environment.ProcessPath!; + return Path.GetFileNameWithoutExtension(path).EndsWith("HaX"); + } +} + +public readonly record struct ProgramInit(bool ShowChangelog, bool BackupPrompt, bool HaX); diff --git a/PKHeX.Core/Legality/Settings/ParseSettings.cs b/PKHeX.Core/Legality/Settings/ParseSettings.cs index 476439bf1..303a0f40d 100644 --- a/PKHeX.Core/Legality/Settings/ParseSettings.cs +++ b/PKHeX.Core/Legality/Settings/ParseSettings.cs @@ -38,10 +38,7 @@ public static class ParseSettings /// public static bool AllowGen1Tradeback => Settings.Tradeback.AllowGen1Tradeback; - public static void Initialize(LegalitySettings settings) - { - Settings = settings; - } + public static void Initialize(LegalitySettings settings) => Settings = settings; /// /// Checks to see if Crystal is available to visit/originate from. diff --git a/PKHeX.WinForms/MainWindow/Main.cs b/PKHeX.WinForms/MainWindow/Main.cs index 6809decbc..4ed94edc0 100644 --- a/PKHeX.WinForms/MainWindow/Main.cs +++ b/PKHeX.WinForms/MainWindow/Main.cs @@ -22,11 +22,8 @@ namespace PKHeX.WinForms; public partial class Main : Form { - public Main() + public Main(ProgramInit init, StartupArguments args) { - string[] args = Environment.GetCommandLineArgs(); - FormLoadInitialSettings(args, out bool showChangelog, out bool BAKprompt); - InitializeComponent(); if (Settings.Display.DisableScalingDpi) AutoScaleMode = AutoScaleMode.Font; @@ -42,27 +39,22 @@ public Main() FormInitializeSecond(); FormLoadCheckForUpdates(); - var startup = new StartupArguments(); - startup.ReadArguments(args); - startup.ReadSettings(Settings.Startup); - startup.ReadTemplateIfNoEntity(TemplatePath); - if (Settings.Startup.PluginLoadEnable) FormLoadPlugins(); - FormLoadInitialFiles(startup); + FormLoadInitialFiles(args); if (HaX) { EntityConverter.AllowIncompatibleConversion = EntityCompatibilitySetting.AllowIncompatibleAll; WinFormsUtil.Alert(MsgProgramIllegalModeActive, MsgProgramIllegalModeBehave); } - else if (showChangelog) + else if (init.ShowChangelog) { ShowAboutDialog(AboutPage.Changelog); } - if (BAKprompt && !Directory.Exists(BackupPath)) + if (init.BackupPrompt && !Directory.Exists(BackupPath)) PromptBackup(); BringToFront(); @@ -91,56 +83,26 @@ private set } public static IReadOnlyList GenderSymbols { get; private set; } = GameInfo.GenderSymbolUnicode; - public static bool HaX { get; private set; } - - private readonly string[] main_langlist = Enum.GetNames(); - - private static readonly List Plugins = []; + public static bool HaX => Program.HaX; + private static List Plugins { get; }= []; #endregion #region Path Variables - public static readonly string WorkingDirectory = Path.GetDirectoryName(Environment.ProcessPath)!; - public static readonly string DatabasePath = Path.Combine(WorkingDirectory, "pkmdb"); - public static readonly string MGDatabasePath = Path.Combine(WorkingDirectory, "mgdb"); - public static readonly string ConfigPath = Path.Combine(WorkingDirectory, "cfg.json"); - public static readonly string BackupPath = Path.Combine(WorkingDirectory, "bak"); - public static readonly string CryPath = Path.Combine(WorkingDirectory, "sounds"); - private static readonly string TemplatePath = Path.Combine(WorkingDirectory, "template"); - private static readonly string TrainerPath = Path.Combine(WorkingDirectory, "trainers"); - private static readonly string PluginPath = Path.Combine(WorkingDirectory, "plugins"); + public static string DatabasePath => Settings.LocalResources.GetDatabasePath(); + public static string MGDatabasePath => Settings.LocalResources.GetMGDatabasePath(); + public static string BackupPath => Settings.LocalResources.GetBackupPath(); + public static string CryPath => Settings.LocalResources.GetCryPath(); + private static string TemplatePath => Settings.LocalResources.GetTemplatePath(); + private static string TrainerPath => Settings.LocalResources.GetTrainerPath(); + private static string PluginPath => Settings.LocalResources.GetPluginPath(); private const string ThreadPath = "https://projectpokemon.org/pkhex/"; - public static readonly PKHeXSettings Settings = PKHeXSettings.GetSettings(ConfigPath); + public static PKHeXSettings Settings => Program.Settings; #endregion #region //// MAIN MENU FUNCTIONS //// - private static void FormLoadInitialSettings(IEnumerable args, out bool showChangelog, out bool BAKprompt) - { - showChangelog = false; - BAKprompt = false; - - FormLoadConfig(out BAKprompt, out showChangelog); - HaX = Settings.Startup.ForceHaXOnLaunch || GetIsHaX(args); - - WinFormsUtil.AddSaveFileExtensions(Settings.Backup.OtherSaveFileExtensions); - SaveFinder.CustomBackupPaths.Clear(); - SaveFinder.CustomBackupPaths.AddRange(Settings.Backup.OtherBackupPaths.Where(Directory.Exists)); - } - - private static bool GetIsHaX(IEnumerable args) - { - foreach (var x in args) - { - var arg = x.AsSpan().Trim('-'); - if (arg.Equals(nameof(HaX), StringComparison.CurrentCultureIgnoreCase)) - return true; - } - - ReadOnlySpan path = Environment.ProcessPath!; - return Path.GetFileNameWithoutExtension(path).EndsWith(nameof(HaX)); - } private void FormLoadAddEvents() { @@ -251,8 +213,8 @@ private void FormInitializeSecond() { var settings = Settings; Draw = C_SAV.M.Hover.Draw = PKME_Tabs.Draw = settings.Draw; - ReloadProgramSettings(settings); - CB_MainLanguage.Items.AddRange(main_langlist); + ReloadProgramSettings(settings, true); + CB_MainLanguage.Items.AddRange(Enum.GetNames()); PB_Legal.Visible = !HaX; C_SAV.HaX = PKME_Tabs.HaX = HaX; @@ -428,36 +390,23 @@ private void MainMenuSettings(object sender, EventArgs e) C_SAV.ReloadSlots(); } - private void ReloadProgramSettings(PKHeXSettings settings) + private void ReloadProgramSettings(PKHeXSettings settings, bool skipCore = false) { + if (!skipCore) + StartupUtil.ReloadSettings(settings); + Draw.LoadBrushes(); PKME_Tabs.Unicode = Unicode = settings.Display.Unicode; PKME_Tabs.UpdateUnicode(GenderSymbols); SpriteName.AllowShinySprite = settings.Sprite.ShinySprites; SpriteBuilderUtil.SpriterPreference = settings.Sprite.SpritePreference; - var write = settings.SlotWrite; - SaveFile.SetUpdateDex = write.SetUpdateDex ? EntityImportOption.Enable : EntityImportOption.Disable; - SaveFile.SetUpdatePKM = write.SetUpdatePKM ? EntityImportOption.Enable : EntityImportOption.Disable; - SaveFile.SetUpdateRecords = write.SetUpdateRecords ? EntityImportOption.Enable : EntityImportOption.Disable; - C_SAV.ModifyPKM = PKME_Tabs.ModifyPKM = settings.SlotWrite.SetUpdatePKM; - CommonEdits.ShowdownSetIVMarkings = settings.Import.ApplyMarkings; - CommonEdits.ShowdownSetBehaviorNature = settings.Import.ApplyNature; C_SAV.FlagIllegal = settings.Display.FlagIllegal; C_SAV.M.Hover.GlowHover = settings.Hover.HoverSlotGlowEdges; - ParseSettings.Initialize(settings.Legality); PKME_Tabs.HideSecretValues = C_SAV.HideSecretDetails = settings.Privacy.HideSecretDetails; WinFormsUtil.DetectSaveFileOnFileOpen = settings.Startup.TryDetectRecentSave; SelectablePictureBox.FocusBorderDeflate = GenderToggle.FocusBorderDeflate = settings.Display.FocusBorderDeflate; - settings.SaveLanguage.Apply(); - - var converter = settings.Converter; - EntityConverter.AllowIncompatibleConversion = converter.AllowIncompatibleConversion; - EntityConverter.RejuvenateHOME = converter.AllowGuessRejuvenateHOME; - EntityConverter.VirtualConsoleSourceGen1 = converter.VirtualConsoleSourceGen1; - EntityConverter.VirtualConsoleSourceGen2 = converter.VirtualConsoleSourceGen2; - EntityConverter.RetainMetDateTransfer45 = converter.RetainMetDateTransfer45; SpriteBuilder.LoadSettings(settings.Sprite); } @@ -1326,7 +1275,7 @@ private async void Main_FormClosing(object sender, FormClosingEventArgs e) } } - await PKHeXSettings.SaveSettings(ConfigPath, Settings).ConfigureAwait(false); + await PKHeXSettings.SaveSettings(Program.PathConfig, Settings).ConfigureAwait(false); } catch { diff --git a/PKHeX.WinForms/Program.cs b/PKHeX.WinForms/Program.cs index f997db5eb..15557b4c1 100644 --- a/PKHeX.WinForms/Program.cs +++ b/PKHeX.WinForms/Program.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Threading.Tasks; using System.Windows.Forms; using PKHeX.Core; @@ -6,7 +7,6 @@ #if !DEBUG using System.Diagnostics.CodeAnalysis; using System.Reflection; -using System.IO; using System.Threading; #endif @@ -14,47 +14,59 @@ namespace PKHeX.WinForms; internal static class Program { + // Pipelines build can sometimes tack on text to the version code. Strip it out. + public static readonly Version CurrentVersion = Version.Parse(GetSaneVersionTag(Application.ProductVersion)); + + public static readonly string WorkingDirectory = Path.GetDirectoryName(Environment.ProcessPath)!; + public const string ConfigFileName = "cfg.json"; + public static string PathConfig => Path.Combine(WorkingDirectory, ConfigFileName); + /// - /// The main entry point for the application. + /// Global settings instance, loaded before any forms are created. /// + public static PKHeXSettings Settings { get; private set; } = null!; + + public static bool HaX { get; private set; } + [STAThread] private static void Main() { #if !DEBUG - // Add the event handler for handling UI thread exceptions to the event. Application.ThreadException += UIThreadException; - - // Set the unhandled exception mode to force all Windows Forms errors to go through our handler. Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); - - // Add the event handler for handling non-UI thread exceptions to the event. AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; #endif - // Run the application Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); + // Load settings first + var settings = Settings = PKHeXSettings.GetSettings(PathConfig); + settings.LocalResources.SetLocalPath(WorkingDirectory); + var args = Environment.GetCommandLineArgs(); - // if an arg is "dark", set the color mode to dark - if (args.Length > 1 && args[1] == "dark") -#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + var dark = args.Length > 1 && args[1] == "dark"; + if (dark || settings.Startup.DarkMode) +#pragma warning disable WFO5001 Application.SetColorMode(SystemColorMode.Dark); -#pragma warning restore WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. +#pragma warning restore WFO5001 var splash = new SplashScreen(); new Task(() => splash.ShowDialog()).Start(); - new Task(() => EncounterEvent.RefreshMGDB(WinForms.Main.MGDatabasePath)).Start(); - var main = new Main(); + + // Prepare init values that used to be calculated in Main + WinFormsUtil.AddSaveFileExtensions(settings.Backup.OtherSaveFileExtensions); + var startup = StartupUtil.GetStartup(args, settings.Startup, settings.LocalResources); + var init = StartupUtil.FormLoadInitialActions(args, settings.Startup, settings.Backup, CurrentVersion); + HaX = init.HaX; + var main = new Main(init, startup); + + // Setup complete. splash.BeginInvoke(splash.ForceClose); Application.Run(main); } - // Pipelines build can sometimes tack on text to the version code. Strip it out. - public static readonly Version CurrentVersion = Version.Parse(GetSaneVersionTag(Application.ProductVersion)); - private static ReadOnlySpan GetSaneVersionTag(ReadOnlySpan productVersion) { - // Take only 0-9 and '.', stop on first char not in that set. for (int i = 0; i < productVersion.Length; i++) { char c = productVersion[i]; @@ -70,7 +82,6 @@ private static ReadOnlySpan GetSaneVersionTag(ReadOnlySpan productVe #if !DEBUG private static void Error(string msg) => MessageBox.Show(msg, "PKHeX Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); - // Handle the UI exceptions by showing a dialog box, and asking the user if they wish to abort execution. private static void UIThreadException(object sender, ThreadExceptionEventArgs t) { DialogResult result = DialogResult.Cancel; @@ -85,7 +96,6 @@ private static void UIThreadException(object sender, ThreadExceptionEventArgs t) HandleReportingException(t.Exception, reportingException); } - // Exits the program when the user clicks Abort. if (result == DialogResult.Abort) Application.Exit(); } @@ -101,9 +111,6 @@ private static string GetErrorMessage(Exception e) return "An error occurred in PKHeX. Please report this error to the PKHeX author."; } - // Handle the UI exceptions by showing a dialog box, and asking the user if they wish to abort execution. - // NOTE: This exception cannot be kept from terminating the application - it can only - // log the event, and inform the user about it. private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { var ex = e.ExceptionObject as Exception; @@ -135,7 +142,6 @@ private static void CurrentDomain_UnhandledException(object sender, UnhandledExc private static bool IsPluginError(Exception exception, out string pluginName) { - // Check the stacktrace to see if the namespace is a type that derives from IPlugin pluginName = string.Empty; var stackTrace = new System.Diagnostics.StackTrace(exception); foreach (var frame in stackTrace.GetFrames()) @@ -158,7 +164,6 @@ private static void HandleReportingException(Exception? ex, Exception reportingE } catch { - // We've failed to even save the error details to a file. There's nothing else we can do. } if (reportingException is FileNotFoundException x && x.FileName?.StartsWith("PKHeX.Core") == true) { @@ -175,22 +180,15 @@ private static void HandleReportingException(Exception? ex, Exception reportingE } } - /// - /// Attempt to log exceptions to a file when there's an error displaying exception details. - /// - /// - /// private static bool EmergencyErrorLog(Exception? originalException, Exception errorHandlingException) { try { - // Not using a string builder because something's very wrong, and we don't want to make things worse var message = (originalException?.ToString() ?? "null first exception") + Environment.NewLine + errorHandlingException; File.WriteAllText($"PKHeX_Error_Report {DateTime.Now:yyyyMMddHHmmss}.txt", message); } catch (Exception) { - // We've failed to save the error details twice now. There's nothing else we can do. return false; } return true; diff --git a/PKHeX.WinForms/Properties/PKHeXSettings.cs b/PKHeX.WinForms/Properties/PKHeXSettings.cs deleted file mode 100644 index ee2ca89ad..000000000 --- a/PKHeX.WinForms/Properties/PKHeXSettings.cs +++ /dev/null @@ -1,505 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Drawing; -using System.IO; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Threading.Tasks; -using PKHeX.Core; -using PKHeX.Drawing.PokeSprite; - -namespace PKHeX.WinForms; - -[JsonSerializable(typeof(PKHeXSettings))] -public sealed partial class PKHeXSettingsContext : JsonSerializerContext; - -[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] -public sealed class PKHeXSettings -{ - public StartupSettings Startup { get; set; } = new(); - public BackupSettings Backup { get; set; } = new(); - - // General - public LegalitySettings Legality { get; set; } = new(); - public EntityConverterSettings Converter { get; set; } = new(); - public SetImportSettings Import { get; set; } = new(); - public SlotWriteSettings SlotWrite { get; set; } = new(); - public PrivacySettings Privacy { get; set; } = new(); - public SaveLanguageSettings SaveLanguage { get; set; } = new(); - - // UI Tweaks - public DisplaySettings Display { get; set; } = new(); - public SpriteSettings Sprite { get; set; } = new(); - public SoundSettings Sounds { get; set; } = new(); - public HoverSettings Hover { get; set; } = new(); - public BattleTemplateSettings BattleTemplate { get; set; } = new(); - - // GUI Specific - public DrawConfig Draw { get; set; } = new(); - public AdvancedSettings Advanced { get; set; } = new(); - public EntityEditorSettings EntityEditor { get; set; } = new(); - public EntityDatabaseSettings EntityDb { get; set; } = new(); - public EncounterDatabaseSettings EncounterDb { get; set; } = new(); - public MysteryGiftDatabaseSettings MysteryDb { get; set; } = new(); - public ReportGridSettings Report { get; set; } = new(); - - [Browsable(false)] - public SlotExportSettings SlotExport { get; set; } = new(); - - private static PKHeXSettingsContext GetContext() => new(new() - { - WriteIndented = true, - Converters = { new ColorJsonConverter() }, - }); - - public sealed class ColorJsonConverter : JsonConverter - { - public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => ColorTranslator.FromHtml(reader.GetString() ?? string.Empty); - - public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options) => writer.WriteStringValue($"#{value.R:x2}{value.G:x2}{value.B:x2}"); - } - - public static PKHeXSettings GetSettings(string configPath) - { - if (!File.Exists(configPath)) - return new PKHeXSettings(); - - try - { - var lines = File.ReadAllText(configPath); - return JsonSerializer.Deserialize(lines, GetContext().PKHeXSettings) ?? new PKHeXSettings(); - } - catch (Exception x) - { - DumpConfigError(x); - return new PKHeXSettings(); - } - } - - public static async Task SaveSettings(string configPath, PKHeXSettings cfg) - { - try - { - // Serialize the object asynchronously and write it to the path. - await using var fs = File.Create(configPath); - await JsonSerializer.SerializeAsync(fs, cfg, GetContext().PKHeXSettings).ConfigureAwait(false); - } - catch (Exception x) - { - DumpConfigError(x); - } - } - - private static async void DumpConfigError(Exception x) - { - try - { - await File.WriteAllTextAsync("config error.txt", x.ToString()); - } - catch (Exception) - { - Debug.WriteLine(x); // ??? - } - } -} - -public sealed class BackupSettings -{ - [LocalizedDescription("Automatic Backups of Save Files are copied to the backup folder when true.")] - public bool BAKEnabled { get; set; } = true; - - [LocalizedDescription("Tracks if the \"Create Backup\" prompt has been issued to the user.")] - public bool BAKPrompt { get; set; } - - [LocalizedDescription("List of extra locations to look for Save Files.")] - public List OtherBackupPaths { get; set; } = []; - - [LocalizedDescription("Save File file-extensions (no period) that the program should also recognize.")] - public List OtherSaveFileExtensions { get; set; } = []; -} - -public sealed class StartupSettings : IStartupSettings -{ - [Browsable(false)] - [LocalizedDescription("Last version that the program was run with.")] - public string Version { get; set; } = string.Empty; - - [LocalizedDescription("Force HaX mode on Program Launch")] - public bool ForceHaXOnLaunch { get; set; } - - [LocalizedDescription("Automatically locates the most recently saved Save File when opening a new file.")] - public bool TryDetectRecentSave { get; set; } = true; - - [LocalizedDescription("Automatically Detect Save File on Program Startup")] - public AutoLoadSetting AutoLoadSaveOnStartup { get; set; } = AutoLoadSetting.RecentBackup; - - [LocalizedDescription("Show the changelog when a new version of the program is run for the first time.")] - public bool ShowChangelogOnUpdate { get; set; } = true; - - [LocalizedDescription("Loads plugins from the plugins folder, assuming the folder exists.")] - public bool PluginLoadEnable { get; set; } = true; - - [LocalizedDescription("Loads any plugins that were merged into the main executable file.")] - public bool PluginLoadMerged { get; set; } - - [Browsable(false)] - public List RecentlyLoaded { get; set; } = new(DefaultMaxRecent); - - private const int DefaultMaxRecent = 10; - private uint MaxRecentCount = DefaultMaxRecent; - - [LocalizedDescription("Amount of recently loaded save files to remember.")] - public uint RecentlyLoadedMaxCount - { - get => MaxRecentCount; - // Sanity check to not let the user foot-gun themselves a slow recall time. - set => MaxRecentCount = Math.Clamp(value, 1, 1000); - } - - // Don't let invalid values slip into the startup version. - private GameVersion _defaultSaveVersion = Latest.Version; - private string _language = WinFormsUtil.GetCultureLanguage(); - - [Browsable(false)] - public string Language - { - get => _language; - set - { - if (!GameLanguage.IsLanguageValid(value)) - { - // Migrate old language codes set in earlier versions. - _language = value switch - { - "zh" => "zh-Hans", - "zh2" => "zh-Hant", - _ => _language, - }; - return; - } - _language = value; - } - } - - [Browsable(false)] - public GameVersion DefaultSaveVersion - { - get => _defaultSaveVersion; - set - { - if (!value.IsValidSavedVersion()) - return; - _defaultSaveVersion = value; - } - } - - public void LoadSaveFile(string path) - { - var recent = RecentlyLoaded; - // Remove from list if already present. - if (!recent.Remove(path) && recent.Count >= MaxRecentCount) - recent.RemoveAt(recent.Count - 1); - recent.Insert(0, path); - } -} - -public sealed class EntityConverterSettings -{ - [LocalizedDescription("Allow PKM file conversion paths that are not possible via official methods. Individual properties will be copied sequentially.")] - public EntityCompatibilitySetting AllowIncompatibleConversion { get; set; } = EntityCompatibilitySetting.DisallowIncompatible; - - [LocalizedDescription("Allow PKM file conversion paths to guess the legal original encounter data that is not stored in the format that it was converted from.")] - public EntityRejuvenationSetting AllowGuessRejuvenateHOME { get; set; } = EntityRejuvenationSetting.MissingDataHOME; - - [LocalizedDescription("Default version to set when transferring from Generation 1 3DS Virtual Console to Generation 7.")] - public GameVersion VirtualConsoleSourceGen1 { get; set; } = GameVersion.RD; - - [LocalizedDescription("Default version to set when transferring from Generation 2 3DS Virtual Console to Generation 7.")] - public GameVersion VirtualConsoleSourceGen2 { get; set; } = GameVersion.SI; - - [LocalizedDescription("Retain the Met Date when transferring from Generation 4 to Generation 5.")] - public bool RetainMetDateTransfer45 { get; set; } -} - -public sealed class AdvancedSettings -{ - [LocalizedDescription("Folder path that contains dump(s) of block hash-names. If a specific dump file does not exist, only names defined within the program's code will be loaded.")] - public string PathBlockKeyList { get; set; } = string.Empty; - - [LocalizedDescription("Hide event variables below this event type value. Removes event values from the GUI that the user doesn't care to view.")] - public NamedEventType HideEventTypeBelow { get; set; } - - [LocalizedDescription("Hide event variable names for that contain any of the comma-separated substrings below. Removes event values from the GUI that the user doesn't care to view.")] - public string HideEvent8Contains { get; set; } = string.Empty; - - [Browsable(false)] - public string[] GetExclusionList8() => Array.ConvertAll(HideEvent8Contains.Split(',', StringSplitOptions.RemoveEmptyEntries), z => z.Trim()); -} - -public sealed class EntityDatabaseSettings -{ - [LocalizedDescription("When loading content for the PKM Database, search within backup save files.")] - public bool SearchBackups { get; set; } = true; - - [LocalizedDescription("When loading content for the PKM Database, search within OtherBackupPaths.")] - public bool SearchExtraSaves { get; set; } = true; - - [LocalizedDescription("When loading content for the PKM Database, search subfolders within OtherBackupPaths.")] - public bool SearchExtraSavesDeep { get; set; } = true; - - [LocalizedDescription("When loading content for the PKM database, the list will be ordered by this option.")] - public DatabaseSortMode InitialSortMode { get; set; } - - [LocalizedDescription("Hides unavailable Species if the currently loaded save file cannot import them.")] - public bool FilterUnavailableSpecies { get; set; } = true; -} - -public enum DatabaseSortMode -{ - None, - SpeciesForm, - SlotIdentity, -} - -public sealed class EntityEditorSettings -{ - [LocalizedDescription("When changing the Hidden Power type, automatically maximize the IVs to ensure the highest Base Power result. Otherwise, keep the IVs as close as possible to the original.")] - public bool HiddenPowerOnChangeMaxPower { get; set; } = true; - - [LocalizedDescription("When showing the list of balls to select, show the legal balls before the illegal balls rather than sorting by Ball ID.")] - public bool ShowLegalBallsFirst { get; set; } = true; - - [LocalizedDescription("When showing a Generation 1 format entity, show the gender it would have if transferred to other generations.")] - public bool ShowGenderGen1 { get; set; } - - [LocalizedDescription("When showing an entity, show any stored Status Condition (Sleep/Burn/etc) it may have.")] - public bool ShowStatusCondition { get; set; } = true; -} - -public sealed class EncounterDatabaseSettings -{ - [LocalizedDescription("Skips searching if the user forgot to enter Species / Move(s) into the search criteria.")] - public bool ReturnNoneIfEmptySearch { get; set; } = true; - - [LocalizedDescription("Hides unavailable Species if the currently loaded save file cannot import them.")] - public bool FilterUnavailableSpecies { get; set; } = true; - - [LocalizedDescription("Use properties from the PKM Editor tabs to specify criteria like Gender and Nature when generating an encounter.")] - public bool UseTabsAsCriteria { get; set; } = true; - - [LocalizedDescription("Use properties from the PKM Editor tabs even if the new encounter isn't the same evolution chain.")] - public bool UseTabsAsCriteriaAnySpecies { get; set; } = true; -} - -public sealed class MysteryGiftDatabaseSettings -{ - [LocalizedDescription("Hides gifts if the currently loaded save file cannot (indirectly) receive them.")] - public bool FilterUnavailableSpecies { get; set; } = true; -} - -public sealed class ReportGridSettings -{ - [LocalizedDescription("Extra entity properties to try and show in addition to the default properties displayed.")] - public List ExtraProperties { get; set; } = []; - - [LocalizedDescription("Properties to hide from the report grid.")] - public List HiddenProperties { get; set; } = []; -} - -public sealed class HoverSettings -{ - [LocalizedDescription("Show PKM Slot Preview on Hover")] - public bool HoverSlotShowPreview { get; set; } = true; - - [LocalizedDescription("Show Encounter Info on Hover")] - public bool HoverSlotShowEncounter { get; set; } = true; - - [LocalizedDescription("Show all Encounter Info properties on Hover")] - public bool HoverSlotShowEncounterVerbose { get; set; } - - [LocalizedDescription("Show PKM Slot ToolTip on Hover")] - public bool HoverSlotShowText { get; set; } = true; - - [LocalizedDescription("Play PKM Slot Cry on Hover")] - public bool HoverSlotPlayCry { get; set; } = true; - - [LocalizedDescription("Show a Glow effect around the PKM on Hover")] - public bool HoverSlotGlowEdges { get; set; } = true; - - [LocalizedDescription("Show Showdown Paste in special Preview on Hover")] - public bool PreviewShowPaste { get; set; } = true; - - [LocalizedDescription("Show a Glow effect around the PKM on Hover")] - public Point PreviewCursorShift { get; set; } = new(16, 8); -} - -public sealed class SoundSettings -{ - [LocalizedDescription("Play Sound when loading a new Save File")] - public bool PlaySoundSAVLoad { get; set; } = true; - [LocalizedDescription("Play Sound when popping up Legality Report")] - public bool PlaySoundLegalityCheck { get; set; } = true; -} - -public sealed class SetImportSettings -{ - [LocalizedDescription("Apply StatNature to Nature on Import")] - public bool ApplyNature { get; set; } = true; - [LocalizedDescription("Apply Markings on Import")] - public bool ApplyMarkings { get; set; } = true; -} - -public sealed class SlotWriteSettings -{ - [LocalizedDescription("Automatically modify the Save File's Pokédex when injecting a PKM.")] - public bool SetUpdateDex { get; set; } = true; - - [LocalizedDescription("Automatically adapt the PKM Info to the Save File (Handler, Format)")] - public bool SetUpdatePKM { get; set; } = true; - - [LocalizedDescription("Automatically increment the Save File's counters for obtained Pokémon (eggs/captures) when injecting a PKM.")] - public bool SetUpdateRecords { get; set; } = true; - - [LocalizedDescription("When enabled and closing/loading a save file, the program will alert if the current save file has been modified without saving.")] - public bool ModifyUnset { get; set; } = true; -} - -public sealed class DisplaySettings -{ - [LocalizedDescription("Show Unicode gender symbol characters, or ASCII when disabled.")] - public bool Unicode { get; set; } = true; - - [LocalizedDescription("Don't show the Legality popup if Legal!")] - public bool IgnoreLegalPopup { get; set; } - - [LocalizedDescription("Display all properties of the encounter (auto-generated) when exporting a verbose report.")] - public bool ExportLegalityVerboseProperties { get; set; } - - [LocalizedDescription("Always displays the verbose legality report, and inverts the hotkey behavior to instead disable.")] - public bool ExportLegalityAlwaysVerbose { get; set; } - - [LocalizedDescription("Always skips the prompt option asking if you would like to export a legality report to clipboard.")] - public bool ExportLegalityNeverClipboard { get; set; } - - [LocalizedDescription("Flag Illegal Slots in Save File")] - public bool FlagIllegal { get; set; } = true; - - [LocalizedDescription("Focus border indentation for custom drawn image controls.")] - public int FocusBorderDeflate { get; set; } = 1; - - [LocalizedDescription("Disables the GUI scaling based on Dpi on program startup, falling back to font scaling.")] - public bool DisableScalingDpi { get; set; } - - [LocalizedDescription("Skips the context menu hotkey requirement and instead always presents the option to check legality of a slot.")] - public bool SlotLegalityAlwaysVisible { get; set; } -} - -public sealed class SpriteSettings : ISpriteSettings -{ - [LocalizedDescription("Choice for which sprite building mode to use.")] - public SpriteBuilderPreference SpritePreference { get; set; } = SpriteBuilderPreference.UseSuggested; - - [LocalizedDescription("Show fan-made shiny sprites when the PKM is shiny.")] - public bool ShinySprites { get; set; } = true; - - [LocalizedDescription("Show an Egg Sprite As Held Item rather than hiding the PKM")] - public bool ShowEggSpriteAsHeldItem { get; set; } = true; - - [LocalizedDescription("Show the required ball for an Encounter Template")] - public bool ShowEncounterBall { get; set; } = true; - - [LocalizedDescription("Show a background to differentiate an Encounter Template's type")] - public SpriteBackgroundType ShowEncounterColor { get; set; } = SpriteBackgroundType.FullBackground; - - [LocalizedDescription("Show a background to differentiate the recognized Encounter Template type for PKM slots")] - public SpriteBackgroundType ShowEncounterColorPKM { get; set; } - - [LocalizedDescription("Opacity for the Encounter Type background layer.")] - public byte ShowEncounterOpacityBackground { get; set; } = 0x3F; // kinda low - - [LocalizedDescription("Opacity for the Encounter Type stripe layer.")] - public byte ShowEncounterOpacityStripe { get; set; } = 0x5F; // 0xFF opaque - - [LocalizedDescription("Amount of pixels thick to show when displaying the encounter type color stripe.")] - public int ShowEncounterThicknessStripe { get; set; } = 4; // pixels - - [LocalizedDescription("Show a thin stripe to indicate the percent of level-up progress")] - public bool ShowExperiencePercent { get; set; } - - [LocalizedDescription("Show a background to differentiate the Tera Type for PKM slots")] - public SpriteBackgroundType ShowTeraType { get; set; } = SpriteBackgroundType.BottomStripe; - - [LocalizedDescription("Amount of pixels thick to show when displaying the Tera Type color stripe.")] - public int ShowTeraThicknessStripe { get; set; } = 4; // pixels - - [LocalizedDescription("Opacity for the Tera Type background layer.")] - public byte ShowTeraOpacityBackground { get; set; } = 0xFF; // 0xFF opaque - - [LocalizedDescription("Opacity for the Tera Type stripe layer.")] - public byte ShowTeraOpacityStripe { get; set; } = 0xAF; // 0xFF opaque -} - -public sealed class PrivacySettings -{ - [LocalizedDescription("Hide Save File Details in Program Title")] - public bool HideSAVDetails { get; set; } - - [LocalizedDescription("Hide Secret Details in Editors")] - public bool HideSecretDetails { get; set; } -} - -public sealed class SaveLanguageSettings -{ - [LocalizedDescription("Gen1: If unable to detect a language or version for a save file, use these instead.")] - public LangVersion OverrideGen1 { get; set; } = new(); - - [LocalizedDescription("Gen2: If unable to detect a language or version for a save file, use these instead.")] - public LangVersion OverrideGen2 { get; set; } = new(); - - [LocalizedDescription("Gen3 R/S: If unable to detect a language or version for a save file, use these instead.")] - public LangVersion OverrideGen3RS { get; set; } = new(); - - [LocalizedDescription("Gen3 FR/LG: If unable to detect a language or version for a save file, use these instead.")] - public LangVersion OverrideGen3FRLG { get; set; } = new(); - - [TypeConverter(typeof(ExpandableObjectConverter))] - public sealed record LangVersion - { - public LanguageID Language { get; set; } = LanguageID.English; - public GameVersion Version { get; set; } - } - - public void Apply() - { - SaveLanguage.OverrideLanguageGen1 = OverrideGen1.Language; - if (OverrideGen1.Version.IsGen1()) - SaveLanguage.OverrideVersionGen1 = OverrideGen1.Version; - - SaveLanguage.OverrideLanguageGen2 = OverrideGen2.Language; - if (OverrideGen2.Version is GameVersion.GD or GameVersion.SI) - SaveLanguage.OverrideVersionGen2 = OverrideGen2.Version; - - SaveLanguage.OverrideLanguageGen3RS = OverrideGen3RS.Language; - if (OverrideGen3RS.Version is GameVersion.R or GameVersion.S) - SaveLanguage.OverrideVersionGen3RS = OverrideGen3RS.Version; - - SaveLanguage.OverrideLanguageGen3FRLG = OverrideGen3FRLG.Language; - if (OverrideGen3FRLG.Version is GameVersion.FR or GameVersion.LG) - SaveLanguage.OverrideVersionGen3FRLG = OverrideGen3FRLG.Version; - } -} - -public sealed class SlotExportSettings -{ - [LocalizedDescription("Settings to use for box exports.")] - public BoxExportSettings BoxExport { get; set; } = new(); - - [LocalizedDescription("Selected File namer to use for box exports for the GUI, if multiple are available.")] - public string DefaultBoxExportNamer { get; set; } = ""; - - [LocalizedDescription("Allow drag and drop of boxdata binary files from the GUI via the Box tab.")] - public bool AllowBoxDataDrop { get; set; } // default to false, clunky to use -} diff --git a/PKHeX.WinForms/Resources/text/lang_de.txt b/PKHeX.WinForms/Resources/text/lang_de.txt index e5c980359..2f19557cc 100644 --- a/PKHeX.WinForms/Resources/text/lang_de.txt +++ b/PKHeX.WinForms/Resources/text/lang_de.txt @@ -200,12 +200,15 @@ LocalizedDescription.AutoLoadSaveOnStartup=Spielstand beim Programmstart automat LocalizedDescription.BackColor=Illegal Legal move choice background color. LocalizedDescription.BackHighlighted=Highlighted move choice background color. LocalizedDescription.BackLegal=Legal move choice background color. +LocalizedDescription.BackupPath=Path to the backup folder for keeping save file backups. LocalizedDescription.BAKEnabled=Automatische Spielstand Backups aktiviert LocalizedDescription.BAKPrompt=Wurde das "Backup erstellen" Pop-Up bereits vom Benutzer gesehen? LocalizedDescription.BoxExport=Settings to use for box exports. LocalizedDescription.CheckActiveHandler=Prüft die zuletzt geladenen Spielstands Daten und den aktuellen Besitzer, um zu ermitteln, ob der aktuelle Besitzer des Pokémons sich erwarteten Wert unterscheidet. LocalizedDescription.CheckWordFilter=Überprüft Spitznamen und Trainer Namen nach anstößigen Wörtern. Hierfür wird die interne Liste des Nintendo 3DS verwendet. LocalizedDescription.CurrentHandlerMismatch=Schweregrad mit dem der aktuelle Besitzer eines Pokémons in der Legalitäts Analyse geprüft wird. +LocalizedDescription.DarkMode=Use the Dark color mode for the application on startup. +LocalizedDescription.DatabasePath=Path to the PKM Database folder. LocalizedDescription.DefaultBoxExportNamer=Selected File namer to use for box exports for the GUI, if multiple are available. LocalizedDescription.DisableScalingDpi=Disables the GUI scaling based on Dpi on program startup, falling back to font scaling. LocalizedDescription.DisableWordFilterPastGen=Disables retroactive Word Filter checks for earlier formats. @@ -247,6 +250,7 @@ LocalizedDescription.Male=Male gender color. LocalizedDescription.MarkBlue=Blue colored marking. LocalizedDescription.MarkDefault=Default colored marking. LocalizedDescription.MarkPink=Pink colored marking. +LocalizedDescription.MGDatabasePath=Path to the Mystery Gift Database folder for storing extra mystery gift templates that aren't yet recognized. LocalizedDescription.ModifyUnset=Benachrichtigung über nicht gesetzte Änderungen. LocalizedDescription.Nickname12=Nickname rules for Generation 1 and 2. LocalizedDescription.Nickname3=Nickname rules for Generation 3. @@ -273,6 +277,7 @@ LocalizedDescription.PlaySoundLegalityCheck=Ton beim Pop-Up der Legalitäts Anal LocalizedDescription.PlaySoundSAVLoad=Ton beim Öffnen eines Spielstands abspielen. LocalizedDescription.PluginLoadEnable=Läd Plugins aus dem "plugins" Ordner, falls dieser existiert. LocalizedDescription.PluginLoadMerged=Loads any plugins that were merged into the main executable file. +LocalizedDescription.PluginPath=Path to the plugins folder. LocalizedDescription.PreviewCursorShift=Show a Glow effect around the PKM on Hover LocalizedDescription.PreviewShowPaste=Show Showdown Paste in special Preview on Hover LocalizedDescription.RecentlyLoadedMaxCount=Amount of recently loaded save files to remember. @@ -306,12 +311,15 @@ LocalizedDescription.ShowTeraOpacityStripe=Deckkraft der Tery Typ Streifens. LocalizedDescription.ShowTeraThicknessStripe=Anzahl der Pixel des farbigen Streifens der Tera Typen.. LocalizedDescription.ShowTeraType=Zeige einen Hintergrund um Tera Typen der PKM zu unterscheiden. LocalizedDescription.SlotLegalityAlwaysVisible=Skips the context menu hotkey requirement and instead always presents the option to check legality of a slot. +LocalizedDescription.SoundPath=Path to the sounds folder for sounds to play when hovering over a slot (species cry). LocalizedDescription.SpritePreference=Zu benutzenden Sprite Anzeige Modus. LocalizedDescription.StatsCustom=Custom stat labels and grammar. +LocalizedDescription.TemplatePath=Path to the template folder (with *.pk files) for initializing the PKM editor fields when a save file is loaded. LocalizedDescription.TextColor=Legal move choice text color. LocalizedDescription.TextHighlighted=Highlighted move choice text color. LocalizedDescription.TokenOrder=Display format to use when exporting a battle template from the program. LocalizedDescription.TokenOrderCustom=Custom ordering for exporting a set, if chosen via export display style. +LocalizedDescription.TrainerPath=Path to the Trainers folder (with *.pk files) used for generating encounters with known Trainer data. LocalizedDescription.TryDetectRecentSave=Finde automatisch den zuletzt geöffneten Spielstand beim Öffnen einer neuen Datei. LocalizedDescription.Unicode=Unicode LocalizedDescription.UseTabsAsCriteria=Nutze Eigeschaften aus den PKM Editor Tabs um Kriterien wie Geschlecht und Wesen bei der Generierung einer neuen Begegnung zu bestimmen. diff --git a/PKHeX.WinForms/Resources/text/lang_en.txt b/PKHeX.WinForms/Resources/text/lang_en.txt index 6c362f831..41cfdf6e2 100644 --- a/PKHeX.WinForms/Resources/text/lang_en.txt +++ b/PKHeX.WinForms/Resources/text/lang_en.txt @@ -200,12 +200,15 @@ LocalizedDescription.AutoLoadSaveOnStartup=Automatically Detect Save File on Pro LocalizedDescription.BackColor=Illegal Legal move choice background color. LocalizedDescription.BackHighlighted=Highlighted move choice background color. LocalizedDescription.BackLegal=Legal move choice background color. +LocalizedDescription.BackupPath=Path to the backup folder for keeping save file backups. LocalizedDescription.BAKEnabled=Automatic Save File Backups Enabled LocalizedDescription.BAKPrompt=Tracks if the "Create Backup" prompt has been issued to the user. LocalizedDescription.BoxExport=Settings to use for box exports. LocalizedDescription.CheckActiveHandler=Checks the last loaded player save file data and Current Handler state to determine if the Pokémon's Current Handler does not match the expected value. LocalizedDescription.CheckWordFilter=Checks player given Nicknames and Trainer Names for profanity. Bad words will be flagged using the appropriate console's lists. LocalizedDescription.CurrentHandlerMismatch=Severity to flag a Legality Check if Pokémon's Current Handler does not match the expected value. +LocalizedDescription.DarkMode=Use the Dark color mode for the application on startup. +LocalizedDescription.DatabasePath=Path to the PKM Database folder. LocalizedDescription.DefaultBoxExportNamer=Selected File namer to use for box exports for the GUI, if multiple are available. LocalizedDescription.DisableScalingDpi=Disables the GUI scaling based on Dpi on program startup, falling back to font scaling. LocalizedDescription.DisableWordFilterPastGen=Disables retroactive Word Filter checks for earlier formats. @@ -247,6 +250,7 @@ LocalizedDescription.Male=Male gender color. LocalizedDescription.MarkBlue=Blue colored marking. LocalizedDescription.MarkDefault=Default colored marking. LocalizedDescription.MarkPink=Pink colored marking. +LocalizedDescription.MGDatabasePath=Path to the Mystery Gift Database folder for storing extra mystery gift templates that aren't yet recognized. LocalizedDescription.ModifyUnset=Notify Unset Changes LocalizedDescription.Nickname12=Nickname rules for Generation 1 and 2. LocalizedDescription.Nickname3=Nickname rules for Generation 3. @@ -273,6 +277,7 @@ LocalizedDescription.PlaySoundLegalityCheck=Play Sound when popping up Legality LocalizedDescription.PlaySoundSAVLoad=Play Sound when loading a new Save File LocalizedDescription.PluginLoadEnable=Loads plugins from the plugins folder, assuming the folder exists. LocalizedDescription.PluginLoadMerged=Loads any plugins that were merged into the main executable file. +LocalizedDescription.PluginPath=Path to the plugins folder. LocalizedDescription.PreviewCursorShift=Show a Glow effect around the PKM on Hover LocalizedDescription.PreviewShowPaste=Show Showdown Paste in special Preview on Hover LocalizedDescription.RecentlyLoadedMaxCount=Amount of recently loaded save files to remember. @@ -306,12 +311,15 @@ LocalizedDescription.ShowTeraOpacityStripe=Opacity for the Tera Type stripe laye LocalizedDescription.ShowTeraThicknessStripe=Amount of pixels thick to show when displaying the Tera Type color stripe. LocalizedDescription.ShowTeraType=Show a background to differentiate the Tera Type for PKM slots. LocalizedDescription.SlotLegalityAlwaysVisible=Skips the context menu hotkey requirement and instead always presents the option to check legality of a slot. +LocalizedDescription.SoundPath=Path to the sounds folder for sounds to play when hovering over a slot (species cry). LocalizedDescription.SpritePreference=Choice for which sprite building mode to use. LocalizedDescription.StatsCustom=Custom stat labels and grammar. +LocalizedDescription.TemplatePath=Path to the template folder (with *.pk files) for initializing the PKM editor fields when a save file is loaded. LocalizedDescription.TextColor=Legal move choice text color. LocalizedDescription.TextHighlighted=Highlighted move choice text color. LocalizedDescription.TokenOrder=Display format to use when exporting a battle template from the program. LocalizedDescription.TokenOrderCustom=Custom ordering for exporting a set, if chosen via export display style. +LocalizedDescription.TrainerPath=Path to the Trainers folder (with *.pk files) used for generating encounters with known Trainer data. LocalizedDescription.TryDetectRecentSave=Automatically locates the most recently saved Save File when opening a new file. LocalizedDescription.Unicode=Unicode LocalizedDescription.UseTabsAsCriteria=Use properties from the PKM Editor tabs to specify criteria like Gender and Nature when generating an encounter. diff --git a/PKHeX.WinForms/Resources/text/lang_es.txt b/PKHeX.WinForms/Resources/text/lang_es.txt index 943b9fcfe..f06d19769 100644 --- a/PKHeX.WinForms/Resources/text/lang_es.txt +++ b/PKHeX.WinForms/Resources/text/lang_es.txt @@ -200,12 +200,15 @@ LocalizedDescription.AutoLoadSaveOnStartup=Detectar automáticamente el archivo LocalizedDescription.BackColor=Color de fondo para los movimientos ilegales. LocalizedDescription.BackHighlighted=Color de fondo para los movimientos destacados. LocalizedDescription.BackLegal=Color de fondo para los movimientos legales. +LocalizedDescription.BackupPath=Path to the backup folder for keeping save file backups. LocalizedDescription.BAKEnabled=Respaldo Automático de archivos de guardado habilitado LocalizedDescription.BAKPrompt=Realiza un seguimiento si el usuario recibe el mensaje "Crear copia de seguridad". LocalizedDescription.BoxExport=Ajustes a usar para las exportaciones de cajas. LocalizedDescription.CheckActiveHandler=Comprobar el Entrenador del último archivo de guardado y el Entrenador actual para determinar si el Entrenador actual del Pokémon no corresponde con el valor esperado. LocalizedDescription.CheckWordFilter=Comprobar los motes y los nombres de Entrenador por profanidad. Las palabras prohibidas serán detectadas utilizando la lista de la consola 3DS. LocalizedDescription.CurrentHandlerMismatch=En la validación de Legalidad, marcar Severidad si se detecta que el Entrenador Actual del Pokémon no corresponde con el valor esperado. +LocalizedDescription.DarkMode=Use the Dark color mode for the application on startup. +LocalizedDescription.DatabasePath=Path to the PKM Database folder. LocalizedDescription.DefaultBoxExportNamer=Nombre seleccionado para los archivos referentes a las exportaciones de cajas, si hubiese varios. LocalizedDescription.DisableScalingDpi=Desactiva el escalado de la GUI basado en los DPI al arrancar el programa, se usa el escalado de la fuente. LocalizedDescription.DisableWordFilterPastGen=Desactiva el filtro de palabras en formatos anteriors a la era 3DS. @@ -247,6 +250,7 @@ LocalizedDescription.Male=Color para el sexo masculino. LocalizedDescription.MarkBlue=Marca de color azul. LocalizedDescription.MarkDefault=Marca del color por defecto. LocalizedDescription.MarkPink=Marca de color rosa. +LocalizedDescription.MGDatabasePath=Path to the Mystery Gift Database folder for storing extra mystery gift templates that aren't yet recognized. LocalizedDescription.ModifyUnset=Notificar cambios no hechos LocalizedDescription.Nickname12=Normas de motes en 1 y 2 generación. LocalizedDescription.Nickname3=Normas de motes en 3 generación. @@ -273,6 +277,7 @@ LocalizedDescription.PlaySoundLegalityCheck=Reproducir sonido en la validación LocalizedDescription.PlaySoundSAVLoad=Reproducir sonido al cargar archivo de guardado LocalizedDescription.PluginLoadEnable=Carga plugins desde la carpeta de plugins, asumiendo que esa carpeta existe. LocalizedDescription.PluginLoadMerged=Loads any plugins that were merged into the main executable file. +LocalizedDescription.PluginPath=Path to the plugins folder. LocalizedDescription.PreviewCursorShift=Mostrar efecto brillante alrededor del PKM al pasar el ratón LocalizedDescription.PreviewShowPaste=Mostrar el texto del formato Showdown en la vista previa al pasar el ratón LocalizedDescription.RecentlyLoadedMaxCount=Número de partidas cargadas recientemente a mantener. @@ -306,12 +311,15 @@ LocalizedDescription.ShowTeraOpacityStripe=Nivel de opacidad de la raya correspo LocalizedDescription.ShowTeraThicknessStripe=Nivel de grosor (en píxeles) al mostrar la raya coloreada del Teratipo. LocalizedDescription.ShowTeraType=Mostrar un fondo para diferenciar el Teratipo en las ranuras de PKM. LocalizedDescription.SlotLegalityAlwaysVisible=Skips the context menu hotkey requirement and instead always presents the option to check legality of a slot. +LocalizedDescription.SoundPath=Path to the sounds folder for sounds to play when hovering over a slot (species cry). LocalizedDescription.SpritePreference=Escoger qué tipo de sprites usar. LocalizedDescription.StatsCustom=Custom stat labels and grammar. +LocalizedDescription.TemplatePath=Path to the template folder (with *.pk files) for initializing the PKM editor fields when a save file is loaded. LocalizedDescription.TextColor=Color de texto de los movimientos legales. LocalizedDescription.TextHighlighted=Color de texto de los movimientos destacados. LocalizedDescription.TokenOrder=Display format to use when exporting a battle template from the program. LocalizedDescription.TokenOrderCustom=Custom ordering for exporting a set, if chosen via export display style. +LocalizedDescription.TrainerPath=Path to the Trainers folder (with *.pk files) used for generating encounters with known Trainer data. LocalizedDescription.TryDetectRecentSave=Localiza automáticamente el archivo de guardado más reciente al abrir un nuevo archivo. LocalizedDescription.Unicode=Unicode LocalizedDescription.UseTabsAsCriteria=Usar propiedades del tablero del Editor PKM para especificar criterios como Género y Naturaleza cuando se genera un encuentro. diff --git a/PKHeX.WinForms/Resources/text/lang_fr.txt b/PKHeX.WinForms/Resources/text/lang_fr.txt index 029649771..9372257ae 100644 --- a/PKHeX.WinForms/Resources/text/lang_fr.txt +++ b/PKHeX.WinForms/Resources/text/lang_fr.txt @@ -200,12 +200,15 @@ LocalizedDescription.AutoLoadSaveOnStartup=Détection automatique du fichier de LocalizedDescription.BackColor=Illegal Legal move choice background color. LocalizedDescription.BackHighlighted=Highlighted move choice background color. LocalizedDescription.BackLegal=Legal move choice background color. +LocalizedDescription.BackupPath=Path to the backup folder for keeping save file backups. LocalizedDescription.BAKEnabled=Sauvegarde automatique des fichiers activée LocalizedDescription.BAKPrompt=Tracks if the "Create Backup" prompt has been issued to the user. LocalizedDescription.BoxExport=Settings to use for box exports. LocalizedDescription.CheckActiveHandler=Checks the last loaded player save file data and Current Handler state to determine if the Pokémon's Current Handler does not match the expected value. LocalizedDescription.CheckWordFilter=Checks player given Nicknames and Trainer Names for profanity. Bad words will be flagged using the appropriate console's lists. LocalizedDescription.CurrentHandlerMismatch=Severity to flag a Legality Check if Pokémon's Current Handler does not match the expected value. +LocalizedDescription.DarkMode=Use the Dark color mode for the application on startup. +LocalizedDescription.DatabasePath=Path to the PKM Database folder. LocalizedDescription.DefaultBoxExportNamer=Selected File namer to use for box exports for the GUI, if multiple are available. LocalizedDescription.DisableScalingDpi=Disables the GUI scaling based on Dpi on program startup, falling back to font scaling. LocalizedDescription.DisableWordFilterPastGen=Disables retroactive Word Filter checks for earlier formats. @@ -247,6 +250,7 @@ LocalizedDescription.Male=Male gender color. LocalizedDescription.MarkBlue=Blue colored marking. LocalizedDescription.MarkDefault=Default colored marking. LocalizedDescription.MarkPink=Pink colored marking. +LocalizedDescription.MGDatabasePath=Path to the Mystery Gift Database folder for storing extra mystery gift templates that aren't yet recognized. LocalizedDescription.ModifyUnset=Notifier en cas de changements non sauvegardés LocalizedDescription.Nickname12=Nickname rules for Generation 1 and 2. LocalizedDescription.Nickname3=Nickname rules for Generation 3. @@ -273,6 +277,7 @@ LocalizedDescription.PlaySoundLegalityCheck=PlaySoundLegalityCheck LocalizedDescription.PlaySoundSAVLoad=PlaySoundSAVLoad LocalizedDescription.PluginLoadEnable=Charge les plugins depuis le dossier plugins, en supposant que ce dossier existe. LocalizedDescription.PluginLoadMerged=Loads any plugins that were merged into the main executable file. +LocalizedDescription.PluginPath=Path to the plugins folder. LocalizedDescription.PreviewCursorShift=Show a Glow effect around the PKM on Hover LocalizedDescription.PreviewShowPaste=Show Showdown Paste in special Preview on Hover LocalizedDescription.RecentlyLoadedMaxCount=Amount of recently loaded save files to remember. @@ -306,12 +311,15 @@ LocalizedDescription.ShowTeraOpacityStripe=Opacity for the Tera Type stripe laye LocalizedDescription.ShowTeraThicknessStripe=Amount of pixels thick to show when displaying the Tera Type color stripe. LocalizedDescription.ShowTeraType=Show a background to differentiate the Tera Type for PKM slots. LocalizedDescription.SlotLegalityAlwaysVisible=Skips the context menu hotkey requirement and instead always presents the option to check legality of a slot. +LocalizedDescription.SoundPath=Path to the sounds folder for sounds to play when hovering over a slot (species cry). LocalizedDescription.SpritePreference=Choice for which sprite building mode to use. LocalizedDescription.StatsCustom=Custom stat labels and grammar. +LocalizedDescription.TemplatePath=Path to the template folder (with *.pk files) for initializing the PKM editor fields when a save file is loaded. LocalizedDescription.TextColor=Legal move choice text color. LocalizedDescription.TextHighlighted=Highlighted move choice text color. LocalizedDescription.TokenOrder=Display format to use when exporting a battle template from the program. LocalizedDescription.TokenOrderCustom=Custom ordering for exporting a set, if chosen via export display style. +LocalizedDescription.TrainerPath=Path to the Trainers folder (with *.pk files) used for generating encounters with known Trainer data. LocalizedDescription.TryDetectRecentSave=Automatically locates the most recently saved Save File when opening a new file. LocalizedDescription.Unicode=Unicode LocalizedDescription.UseTabsAsCriteria=Use properties from the PKM Editor tabs to specify criteria like Gender and Nature when generating an encounter. diff --git a/PKHeX.WinForms/Resources/text/lang_it.txt b/PKHeX.WinForms/Resources/text/lang_it.txt index 9320a99bf..567df3cdc 100644 --- a/PKHeX.WinForms/Resources/text/lang_it.txt +++ b/PKHeX.WinForms/Resources/text/lang_it.txt @@ -200,12 +200,15 @@ LocalizedDescription.AutoLoadSaveOnStartup=Rileva automaticamente il tipo del Sa LocalizedDescription.BackColor=Illegal Legal move choice background color. LocalizedDescription.BackHighlighted=Highlighted move choice background color. LocalizedDescription.BackLegal=Legal move choice background color. +LocalizedDescription.BackupPath=Path to the backup folder for keeping save file backups. LocalizedDescription.BAKEnabled=Backup automatico dei File di Salvataggio attivo. LocalizedDescription.BAKPrompt=Controlla se è stato chiesto all'utente di Creare un Backup. LocalizedDescription.BoxExport=Settings to use for box exports. LocalizedDescription.CheckActiveHandler=Controlla i dati allenatore dall'ultimo salvataggio caricato per determinare se l'Ultimo Allenatore non corrisponde al valore aspettato. LocalizedDescription.CheckWordFilter=Controlla la volgarità di Soprannomi e Nomi Allenatore. Parole proibite saranno segnalate utilizzando gli elenchi di espressione del 3DS. LocalizedDescription.CurrentHandlerMismatch=Forza una segnalazione di legalità se l'Ultimo Allenatore non corrisponde al valore aspettato. +LocalizedDescription.DarkMode=Use the Dark color mode for the application on startup. +LocalizedDescription.DatabasePath=Path to the PKM Database folder. LocalizedDescription.DefaultBoxExportNamer=Selected File namer to use for box exports for the GUI, if multiple are available. LocalizedDescription.DisableScalingDpi=Disables the GUI scaling based on Dpi on program startup, falling back to font scaling. LocalizedDescription.DisableWordFilterPastGen=Disables retroactive Word Filter checks for earlier formats. @@ -247,6 +250,7 @@ LocalizedDescription.Male=Male gender color. LocalizedDescription.MarkBlue=Blue colored marking. LocalizedDescription.MarkDefault=Default colored marking. LocalizedDescription.MarkPink=Pink colored marking. +LocalizedDescription.MGDatabasePath=Path to the Mystery Gift Database folder for storing extra mystery gift templates that aren't yet recognized. LocalizedDescription.ModifyUnset=Notifica modifiche non complete LocalizedDescription.Nickname12=Nickname rules for Generation 1 and 2. LocalizedDescription.Nickname3=Nickname rules for Generation 3. @@ -273,6 +277,7 @@ LocalizedDescription.PlaySoundLegalityCheck=AvviaSuoniPerControlliLegalità LocalizedDescription.PlaySoundSAVLoad=AvviaSuoniAlCaricamentoDelSAV LocalizedDescription.PluginLoadEnable=Carica Plugins dlla cartella plugins, se esiste. LocalizedDescription.PluginLoadMerged=Loads any plugins that were merged into the main executable file. +LocalizedDescription.PluginPath=Path to the plugins folder. LocalizedDescription.PreviewCursorShift=Show a Glow effect around the PKM on Hover LocalizedDescription.PreviewShowPaste=Show Showdown Paste in special Preview on Hover LocalizedDescription.RecentlyLoadedMaxCount=Amount of recently loaded save files to remember. @@ -306,12 +311,15 @@ LocalizedDescription.ShowTeraOpacityStripe=Opacità dello stripe layer per il Te LocalizedDescription.ShowTeraThicknessStripe=Spessore dei pixel mostrati nella color stripe per il Teratipo. LocalizedDescription.ShowTeraType=>Mostra un background negli Slot PKM per differenziare il Teratipo. LocalizedDescription.SlotLegalityAlwaysVisible=Skips the context menu hotkey requirement and instead always presents the option to check legality of a slot. +LocalizedDescription.SoundPath=Path to the sounds folder for sounds to play when hovering over a slot (species cry). LocalizedDescription.SpritePreference=Quale modalità di costruzione sprite utilizzare LocalizedDescription.StatsCustom=Custom stat labels and grammar. +LocalizedDescription.TemplatePath=Path to the template folder (with *.pk files) for initializing the PKM editor fields when a save file is loaded. LocalizedDescription.TextColor=Legal move choice text color. LocalizedDescription.TextHighlighted=Highlighted move choice text color. LocalizedDescription.TokenOrder=Display format to use when exporting a battle template from the program. LocalizedDescription.TokenOrderCustom=Custom ordering for exporting a set, if chosen via export display style. +LocalizedDescription.TrainerPath=Path to the Trainers folder (with *.pk files) used for generating encounters with known Trainer data. LocalizedDescription.TryDetectRecentSave=Localizza automaticamente l'ultimo File salvato quando apri un nuovo File. LocalizedDescription.Unicode=Unicode LocalizedDescription.UseTabsAsCriteria=Usa proprietà dell'Editor Pokémon per specificare criteri come il Sesso o la Natura quando si genera un incontro. diff --git a/PKHeX.WinForms/Resources/text/lang_ja.txt b/PKHeX.WinForms/Resources/text/lang_ja.txt index c6efd3205..97fb8c9d1 100644 --- a/PKHeX.WinForms/Resources/text/lang_ja.txt +++ b/PKHeX.WinForms/Resources/text/lang_ja.txt @@ -200,12 +200,15 @@ LocalizedDescription.AutoLoadSaveOnStartup=起動時にセーブファイルを LocalizedDescription.BackColor=タブ選択時の全ての技の背景色。 LocalizedDescription.BackHighlighted=タブ選択時の強調表示された技の背景色。 LocalizedDescription.BackLegal=タブ選択時の正規技の背景色。 +LocalizedDescription.BackupPath=Path to the backup folder for keeping save file backups. LocalizedDescription.BAKEnabled=セーブデータの自動バックアップを有効にします。 LocalizedDescription.BAKPrompt=『バックアップ作成』のプロンプトが実行されたかを確認します。 LocalizedDescription.BoxExport=ボックスのエクスポートに使用する設定。 LocalizedDescription.CheckActiveHandler=Checks the last loaded player save file data and Current Handler state to determine if the Pokémon's Current Handler does not match the expected value. LocalizedDescription.CheckWordFilter=プレイヤーがつけたニックネームとトレーナー名に不適切な表現がないかをチェックします。チェックには3DS本体のNGリストが使用されます。 LocalizedDescription.CurrentHandlerMismatch=Severity to flag a Legality Check if Pokémon's Current Handler does not match the expected value. +LocalizedDescription.DarkMode=Use the Dark color mode for the application on startup. +LocalizedDescription.DatabasePath=Path to the PKM Database folder. LocalizedDescription.DefaultBoxExportNamer=Selected File namer to use for box exports for the GUI, if multiple are available. LocalizedDescription.DisableScalingDpi=Disables the GUI scaling based on Dpi on program startup, falling back to font scaling. LocalizedDescription.DisableWordFilterPastGen=3DS時代より前のワードチェックを無効にします。 @@ -247,6 +250,7 @@ LocalizedDescription.Male=オスのアイコンの色 LocalizedDescription.MarkBlue=青色のマーキング。 LocalizedDescription.MarkDefault=デフォルトのマーキング。 LocalizedDescription.MarkPink=ピンクのマーキング。 +LocalizedDescription.MGDatabasePath=Path to the Mystery Gift Database folder for storing extra mystery gift templates that aren't yet recognized. LocalizedDescription.ModifyUnset=未設定の変更を通知する。 LocalizedDescription.Nickname12=第1世代/第2世代のニックネームルール。 LocalizedDescription.Nickname3=第3世代のニックネームルール。 @@ -273,6 +277,7 @@ LocalizedDescription.PlaySoundLegalityCheck=正規チェック時に音を鳴ら LocalizedDescription.PlaySoundSAVLoad=ロード時に音を鳴らす。 LocalizedDescription.PluginLoadEnable=Loads plugins from the plugins folder, assuming the folder exists. LocalizedDescription.PluginLoadMerged=Loads any plugins that were merged into the main executable file. +LocalizedDescription.PluginPath=Path to the plugins folder. LocalizedDescription.PreviewCursorShift=Show a Glow effect around the PKM on Hover LocalizedDescription.PreviewShowPaste=Show Showdown Paste in special Preview on Hover LocalizedDescription.RecentlyLoadedMaxCount=最近開いたファイルを記録する数。 @@ -306,12 +311,15 @@ LocalizedDescription.ShowTeraOpacityStripe=テラスタルタイプのストラ LocalizedDescription.ShowTeraThicknessStripe=テラスタルタイプを表示するときのピクセルの太さ。 LocalizedDescription.ShowTeraType=Show a background to differentiate the Tera Type for PKM slots. LocalizedDescription.SlotLegalityAlwaysVisible=Skips the context menu hotkey requirement and instead always presents the option to check legality of a slot. +LocalizedDescription.SoundPath=Path to the sounds folder for sounds to play when hovering over a slot (species cry). LocalizedDescription.SpritePreference=使用するスプライトの構築モードの選択。 LocalizedDescription.StatsCustom=Custom stat labels and grammar. +LocalizedDescription.TemplatePath=Path to the template folder (with *.pk files) for initializing the PKM editor fields when a save file is loaded. LocalizedDescription.TextColor=正規技のテキストの色。 LocalizedDescription.TextHighlighted=強調表示された技のテキストの色。 LocalizedDescription.TokenOrder=Display format to use when exporting a battle template from the program. LocalizedDescription.TokenOrderCustom=Custom ordering for exporting a set, if chosen via export display style. +LocalizedDescription.TrainerPath=Path to the Trainers folder (with *.pk files) used for generating encounters with known Trainer data. LocalizedDescription.TryDetectRecentSave=新しいファイルを開く時に、最期に保存されたセーブファイルを自動的に見つける。 LocalizedDescription.Unicode=Unicodeを使用するかどうか。 LocalizedDescription.UseTabsAsCriteria=Use properties from the PKM Editor tabs to specify criteria like Gender and Nature when generating an encounter. diff --git a/PKHeX.WinForms/Resources/text/lang_ko.txt b/PKHeX.WinForms/Resources/text/lang_ko.txt index 38aba111b..2a547178b 100644 --- a/PKHeX.WinForms/Resources/text/lang_ko.txt +++ b/PKHeX.WinForms/Resources/text/lang_ko.txt @@ -200,12 +200,15 @@ LocalizedDescription.AutoLoadSaveOnStartup=Automatically Detect Save File on Pro LocalizedDescription.BackColor=Illegal Legal move choice background color. LocalizedDescription.BackHighlighted=Highlighted move choice background color. LocalizedDescription.BackLegal=Legal move choice background color. +LocalizedDescription.BackupPath=Path to the backup folder for keeping save file backups. LocalizedDescription.BAKEnabled=세이브 파일 자동 백업 사용 LocalizedDescription.BAKPrompt=Tracks if the "Create Backup" prompt has been issued to the user. LocalizedDescription.BoxExport=Settings to use for box exports. LocalizedDescription.CheckActiveHandler=Checks the last loaded player save file data and Current Handler state to determine if the Pokémon's Current Handler does not match the expected value. LocalizedDescription.CheckWordFilter=Checks player given Nicknames and Trainer Names for profanity. Bad words will be flagged using the appropriate console's lists. LocalizedDescription.CurrentHandlerMismatch=Severity to flag a Legality Check if Pokémon's Current Handler does not match the expected value. +LocalizedDescription.DarkMode=Use the Dark color mode for the application on startup. +LocalizedDescription.DatabasePath=Path to the PKM Database folder. LocalizedDescription.DefaultBoxExportNamer=Selected File namer to use for box exports for the GUI, if multiple are available. LocalizedDescription.DisableScalingDpi=Disables the GUI scaling based on Dpi on program startup, falling back to font scaling. LocalizedDescription.DisableWordFilterPastGen=Disables retroactive Word Filter checks for earlier formats. @@ -247,6 +250,7 @@ LocalizedDescription.Male=Male gender color. LocalizedDescription.MarkBlue=Blue colored marking. LocalizedDescription.MarkDefault=Default colored marking. LocalizedDescription.MarkPink=Pink colored marking. +LocalizedDescription.MGDatabasePath=Path to the Mystery Gift Database folder for storing extra mystery gift templates that aren't yet recognized. LocalizedDescription.ModifyUnset=적용하지 않은 변경 사항 알림 LocalizedDescription.Nickname12=Nickname rules for Generation 1 and 2. LocalizedDescription.Nickname3=Nickname rules for Generation 3. @@ -273,6 +277,7 @@ LocalizedDescription.PlaySoundLegalityCheck=적법성 검사 창을 띄울 때 LocalizedDescription.PlaySoundSAVLoad=새 세이브 파일을 불러올 때 소리로 알림 LocalizedDescription.PluginLoadEnable=Loads plugins from the plugins folder, assuming the folder exists. LocalizedDescription.PluginLoadMerged=Loads any plugins that were merged into the main executable file. +LocalizedDescription.PluginPath=Path to the plugins folder. LocalizedDescription.PreviewCursorShift=Show a Glow effect around the PKM on Hover LocalizedDescription.PreviewShowPaste=Show Showdown Paste in special Preview on Hover LocalizedDescription.RecentlyLoadedMaxCount=Amount of recently loaded save files to remember. @@ -306,12 +311,15 @@ LocalizedDescription.ShowTeraOpacityStripe=Opacity for the Tera Type stripe laye LocalizedDescription.ShowTeraThicknessStripe=Amount of pixels thick to show when displaying the Tera Type color stripe. LocalizedDescription.ShowTeraType=Show a background to differentiate the Tera Type for PKM slots. LocalizedDescription.SlotLegalityAlwaysVisible=Skips the context menu hotkey requirement and instead always presents the option to check legality of a slot. +LocalizedDescription.SoundPath=Path to the sounds folder for sounds to play when hovering over a slot (species cry). LocalizedDescription.SpritePreference=Choice for which sprite building mode to use. LocalizedDescription.StatsCustom=Custom stat labels and grammar. +LocalizedDescription.TemplatePath=Path to the template folder (with *.pk files) for initializing the PKM editor fields when a save file is loaded. LocalizedDescription.TextColor=Legal move choice text color. LocalizedDescription.TextHighlighted=Highlighted move choice text color. LocalizedDescription.TokenOrder=Display format to use when exporting a battle template from the program. LocalizedDescription.TokenOrderCustom=Custom ordering for exporting a set, if chosen via export display style. +LocalizedDescription.TrainerPath=Path to the Trainers folder (with *.pk files) used for generating encounters with known Trainer data. LocalizedDescription.TryDetectRecentSave=Automatically locates the most recently saved Save File when opening a new file. LocalizedDescription.Unicode=유니코드 사용 LocalizedDescription.UseTabsAsCriteria=Use properties from the PKM Editor tabs to specify criteria like Gender and Nature when generating an encounter. diff --git a/PKHeX.WinForms/Resources/text/lang_zh-Hans.txt b/PKHeX.WinForms/Resources/text/lang_zh-Hans.txt index 5eaaa9e57..8b612df91 100644 --- a/PKHeX.WinForms/Resources/text/lang_zh-Hans.txt +++ b/PKHeX.WinForms/Resources/text/lang_zh-Hans.txt @@ -200,12 +200,15 @@ LocalizedDescription.AutoLoadSaveOnStartup=在程序启动时自动加载存档 LocalizedDescription.BackColor=非法合法招式区分选择背景颜色。 LocalizedDescription.BackHighlighted=鼠标悬停的招式选择背景颜色。 LocalizedDescription.BackLegal=合法招式背景颜色。 +LocalizedDescription.BackupPath=Path to the backup folder for keeping save file backups. LocalizedDescription.BAKEnabled=自动保存文件备份已启用 LocalizedDescription.BAKPrompt=记录是否向用户发送过“创建备份”提示。 LocalizedDescription.BoxExport=用于框导出的设置。 LocalizedDescription.CheckActiveHandler=检查上次存档数据和当前持有人状态,以确定宝可梦当前持有人是否与预期值一致。 LocalizedDescription.CheckWordFilter=检查昵称和训练家名称是否存在违禁词。违禁词会根据3DS的正则列表规则标记。 LocalizedDescription.CurrentHandlerMismatch=如果当前持有人与预期值不匹配,则开启严格合法性检查。 +LocalizedDescription.DarkMode=Use the Dark color mode for the application on startup. +LocalizedDescription.DatabasePath=Path to the PKM Database folder. LocalizedDescription.DefaultBoxExportNamer=如果有多个可用的文件名,则选择文件名用于GUI的框导出。 LocalizedDescription.DisableScalingDpi=在程序启动时禁用基于 Dpi 的 GUI 缩放,回退到字体缩放。 LocalizedDescription.DisableWordFilterPastGen=禁用3DS时代之前格式的文字过滤检查。 @@ -247,6 +250,7 @@ LocalizedDescription.Male=男性性别颜色。 LocalizedDescription.MarkBlue=蓝色标记。 LocalizedDescription.MarkDefault=默认彩色标记。 LocalizedDescription.MarkPink=粉红色标记。 +LocalizedDescription.MGDatabasePath=Path to the Mystery Gift Database folder for storing extra mystery gift templates that aren't yet recognized. LocalizedDescription.ModifyUnset=未保存修改提醒。 LocalizedDescription.Nickname12=第1代和第2代昵称规则。 LocalizedDescription.Nickname3=第3代昵称规则。 @@ -273,6 +277,7 @@ LocalizedDescription.PlaySoundLegalityCheck=弹窗合法性报告时播放声音 LocalizedDescription.PlaySoundSAVLoad=读取新档时播放声音。 LocalizedDescription.PluginLoadEnable=从plugins文件夹加载插件,假设该文件夹存在。 LocalizedDescription.PluginLoadMerged=加载已合并到主可执行文件中的所有插件。 +LocalizedDescription.PluginPath=Path to the plugins folder. LocalizedDescription.PreviewCursorShift=悬停时在 PKM 周围时显示发光效果。 LocalizedDescription.PreviewShowPaste=在悬停在特殊预览中显示Showdown粘贴。 LocalizedDescription.RecentlyLoadedMaxCount=记住最近加载的存档文件数量。 @@ -306,12 +311,15 @@ LocalizedDescription.ShowTeraOpacityStripe=太晶属性指示条的透明度。 LocalizedDescription.ShowTeraThicknessStripe=太晶属性指示条的画素高度。 LocalizedDescription.ShowTeraType=为每个宝可梦槽位的显示背景区分太晶属性。 LocalizedDescription.SlotLegalityAlwaysVisible=无需快捷键调出菜单,始终显示槽位合法性。 +LocalizedDescription.SoundPath=Path to the sounds folder for sounds to play when hovering over a slot (species cry). LocalizedDescription.SpritePreference=选择使用何种构建模式的宝可梦图示。 LocalizedDescription.StatsCustom=自定义能力值标签及语法。 +LocalizedDescription.TemplatePath=Path to the template folder (with *.pk files) for initializing the PKM editor fields when a save file is loaded. LocalizedDescription.TextColor=合法招式选项的文本颜色。 LocalizedDescription.TextHighlighted=鼠标悬停时招式选项的文本颜色。 LocalizedDescription.TokenOrder=从程序导出对战模板时使用的显示格式。 LocalizedDescription.TokenOrderCustom=若选择自定义导出显示样式,可自定义导出时的排列顺序。 +LocalizedDescription.TrainerPath=Path to the Trainers folder (with *.pk files) used for generating encounters with known Trainer data. LocalizedDescription.TryDetectRecentSave=打开新存档时,自动定位到上次保存的存档地址。 LocalizedDescription.Unicode=使用Unicode显示性别符号,禁用时使用ASCII。 LocalizedDescription.UseTabsAsCriteria=在生成相遇时,使用 PKM 编辑器选项卡中的属性指定性别和特性等标准。 diff --git a/PKHeX.WinForms/Resources/text/lang_zh-Hant.txt b/PKHeX.WinForms/Resources/text/lang_zh-Hant.txt index 9e8d9b6b7..048d47b8c 100644 --- a/PKHeX.WinForms/Resources/text/lang_zh-Hant.txt +++ b/PKHeX.WinForms/Resources/text/lang_zh-Hant.txt @@ -200,12 +200,15 @@ LocalizedDescription.AutoLoadSaveOnStartup=在程式啟動時自動載入儲存 LocalizedDescription.BackColor=Illegal Legal move choice background color. LocalizedDescription.BackHighlighted=Highlighted move choice background color. LocalizedDescription.BackLegal=Legal move choice background color. +LocalizedDescription.BackupPath=Path to the backup folder for keeping save file backups. LocalizedDescription.BAKEnabled=自動保儲存資料案備份已啟用 LocalizedDescription.BAKPrompt=記錄是否向使用者發送過“創建備份”提示。 LocalizedDescription.BoxExport=Settings to use for box exports. LocalizedDescription.CheckActiveHandler=檢測上次已加載儲存資料數據及現時持有人狀態,以確定現時持有人資訊與預期值相符 LocalizedDescription.CheckWordFilter=檢查昵稱和訓練家名稱是否存在違禁詞。違禁詞會根據3DS的正則清單規則標記。 LocalizedDescription.CurrentHandlerMismatch=如果寶可夢現時持有人與預期值不匹配,則使用高等級合法性檢查。 +LocalizedDescription.DarkMode=Use the Dark color mode for the application on startup. +LocalizedDescription.DatabasePath=Path to the PKM Database folder. LocalizedDescription.DefaultBoxExportNamer=Selected File namer to use for box exports for the GUI, if multiple are available. LocalizedDescription.DisableScalingDpi=Disables the GUI scaling based on Dpi on program startup, falling back to font scaling. LocalizedDescription.DisableWordFilterPastGen=Disables retroactive Word Filter checks for earlier formats. @@ -247,6 +250,7 @@ LocalizedDescription.Male=Male gender color. LocalizedDescription.MarkBlue=Blue colored marking. LocalizedDescription.MarkDefault=Default colored marking. LocalizedDescription.MarkPink=Pink colored marking. +LocalizedDescription.MGDatabasePath=Path to the Mystery Gift Database folder for storing extra mystery gift templates that aren't yet recognized. LocalizedDescription.ModifyUnset=未儲存修改提醒 LocalizedDescription.Nickname12=Nickname rules for Generation 1 and 2. LocalizedDescription.Nickname3=Nickname rules for Generation 3. @@ -273,6 +277,7 @@ LocalizedDescription.PlaySoundLegalityCheck=彈窗合法性報告時播放聲音 LocalizedDescription.PlaySoundSAVLoad=讀取新檔時播放聲音 LocalizedDescription.PluginLoadEnable=Loads plugins from the plugins folder, assuming the folder exists. LocalizedDescription.PluginLoadMerged=Loads any plugins that were merged into the main executable file. +LocalizedDescription.PluginPath=Path to the plugins folder. LocalizedDescription.PreviewCursorShift=Show a Glow effect around the PKM on Hover LocalizedDescription.PreviewShowPaste=Show Showdown Paste in special Preview on Hover LocalizedDescription.RecentlyLoadedMaxCount=Amount of recently loaded save files to remember. @@ -306,12 +311,15 @@ LocalizedDescription.ShowTeraOpacityStripe=太晶屬性指示條之透明度。 LocalizedDescription.ShowTeraThicknessStripe=太晶屬性指示條之畫素高度。 LocalizedDescription.ShowTeraType=為每個寶可夢格子顯示背景以區分太晶屬性。 LocalizedDescription.SlotLegalityAlwaysVisible=Skips the context menu hotkey requirement and instead always presents the option to check legality of a slot. +LocalizedDescription.SoundPath=Path to the sounds folder for sounds to play when hovering over a slot (species cry). LocalizedDescription.SpritePreference=選擇使用何種構建模式之精靈圖示。 LocalizedDescription.StatsCustom=Custom stat labels and grammar. +LocalizedDescription.TemplatePath=Path to the template folder (with *.pk files) for initializing the PKM editor fields when a save file is loaded. LocalizedDescription.TextColor=Legal move choice text color. LocalizedDescription.TextHighlighted=Highlighted move choice text color. LocalizedDescription.TokenOrder=Display format to use when exporting a battle template from the program. LocalizedDescription.TokenOrderCustom=Custom ordering for exporting a set, if chosen via export display style. +LocalizedDescription.TrainerPath=Path to the Trainers folder (with *.pk files) used for generating encounters with known Trainer data. LocalizedDescription.TryDetectRecentSave=打開新儲存資料時,自動定位到上次儲存之儲存資料位址。 LocalizedDescription.Unicode=使用Unicode顯示性別符號,禁用時使用ASCII LocalizedDescription.UseTabsAsCriteria=Use properties from the PKM Editor tabs to specify criteria like Gender and Nature when generating an encounter. diff --git a/PKHeX.WinForms/Settings/DisplaySettings.cs b/PKHeX.WinForms/Settings/DisplaySettings.cs new file mode 100644 index 000000000..a1ee22625 --- /dev/null +++ b/PKHeX.WinForms/Settings/DisplaySettings.cs @@ -0,0 +1,33 @@ +using PKHeX.Core; + +namespace PKHeX.WinForms; + +public sealed class DisplaySettings +{ + [LocalizedDescription("Show Unicode gender symbol characters, or ASCII when disabled.")] + public bool Unicode { get; set; } = true; + + [LocalizedDescription("Don't show the Legality popup if Legal!")] + public bool IgnoreLegalPopup { get; set; } + + [LocalizedDescription("Display all properties of the encounter (auto-generated) when exporting a verbose report.")] + public bool ExportLegalityVerboseProperties { get; set; } + + [LocalizedDescription("Always displays the verbose legality report, and inverts the hotkey behavior to instead disable.")] + public bool ExportLegalityAlwaysVerbose { get; set; } + + [LocalizedDescription("Always skips the prompt option asking if you would like to export a legality report to clipboard.")] + public bool ExportLegalityNeverClipboard { get; set; } + + [LocalizedDescription("Flag Illegal Slots in Save File")] + public bool FlagIllegal { get; set; } = true; + + [LocalizedDescription("Focus border indentation for custom drawn image controls.")] + public int FocusBorderDeflate { get; set; } = 1; + + [LocalizedDescription("Disables the GUI scaling based on Dpi on program startup, falling back to font scaling.")] + public bool DisableScalingDpi { get; set; } + + [LocalizedDescription("Skips the context menu hotkey requirement and instead always presents the option to check legality of a slot.")] + public bool SlotLegalityAlwaysVisible { get; set; } +} diff --git a/PKHeX.WinForms/Settings/EntityEditorSettings.cs b/PKHeX.WinForms/Settings/EntityEditorSettings.cs new file mode 100644 index 000000000..b202551cc --- /dev/null +++ b/PKHeX.WinForms/Settings/EntityEditorSettings.cs @@ -0,0 +1,16 @@ +namespace PKHeX.Core; + +public sealed class EntityEditorSettings +{ + [LocalizedDescription("When changing the Hidden Power type, automatically maximize the IVs to ensure the highest Base Power result. Otherwise, keep the IVs as close as possible to the original.")] + public bool HiddenPowerOnChangeMaxPower { get; set; } = true; + + [LocalizedDescription("When showing the list of balls to select, show the legal balls before the illegal balls rather than sorting by Ball ID.")] + public bool ShowLegalBallsFirst { get; set; } = true; + + [LocalizedDescription("When showing a Generation 1 format entity, show the gender it would have if transferred to other generations.")] + public bool ShowGenderGen1 { get; set; } + + [LocalizedDescription("When showing an entity, show any stored Status Condition (Sleep/Burn/etc) it may have.")] + public bool ShowStatusCondition { get; set; } = true; +} diff --git a/PKHeX.WinForms/Settings/HoverSettings.cs b/PKHeX.WinForms/Settings/HoverSettings.cs new file mode 100644 index 000000000..85a510bb3 --- /dev/null +++ b/PKHeX.WinForms/Settings/HoverSettings.cs @@ -0,0 +1,31 @@ +using System.Drawing; +using PKHeX.Core; + +namespace PKHeX.WinForms; + +public sealed class HoverSettings +{ + [LocalizedDescription("Show PKM Slot Preview on Hover")] + public bool HoverSlotShowPreview { get; set; } = true; + + [LocalizedDescription("Show Encounter Info on Hover")] + public bool HoverSlotShowEncounter { get; set; } = true; + + [LocalizedDescription("Show all Encounter Info properties on Hover")] + public bool HoverSlotShowEncounterVerbose { get; set; } + + [LocalizedDescription("Show PKM Slot ToolTip on Hover")] + public bool HoverSlotShowText { get; set; } = true; + + [LocalizedDescription("Play PKM Slot Cry on Hover")] + public bool HoverSlotPlayCry { get; set; } = true; + + [LocalizedDescription("Show a Glow effect around the PKM on Hover")] + public bool HoverSlotGlowEdges { get; set; } = true; + + [LocalizedDescription("Show Showdown Paste in special Preview on Hover")] + public bool PreviewShowPaste { get; set; } = true; + + [LocalizedDescription("Show a Glow effect around the PKM on Hover")] + public Point PreviewCursorShift { get; set; } = new(16, 8); +} diff --git a/PKHeX.WinForms/Settings/PKHeXSettings.cs b/PKHeX.WinForms/Settings/PKHeXSettings.cs new file mode 100644 index 000000000..47d4fb255 --- /dev/null +++ b/PKHeX.WinForms/Settings/PKHeXSettings.cs @@ -0,0 +1,110 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Drawing; +using System.IO; +using System.Text.Json; +using System.Text.Json.Serialization; +using System.Threading.Tasks; +using PKHeX.Core; + +namespace PKHeX.WinForms; + +[JsonSerializable(typeof(PKHeXSettings))] +public sealed partial class PKHeXSettingsContext : JsonSerializerContext; + +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] +public sealed class PKHeXSettings : IProgramSettings +{ + public StartupSettings Startup { get; set; } = new(); + public BackupSettings Backup { get; set; } = new(); + public LocalResourceSettings LocalResources { get; set; } = new(); + + // General + public LegalitySettings Legality { get; set; } = new(); + public EntityConverterSettings Converter { get; set; } = new(); + public SetImportSettings Import { get; set; } = new(); + public SlotWriteSettings SlotWrite { get; set; } = new(); + public PrivacySettings Privacy { get; set; } = new(); + public SaveLanguageSettings SaveLanguage { get; set; } = new(); + + // UI Tweaks + public DisplaySettings Display { get; set; } = new(); + public SpriteSettings Sprite { get; set; } = new(); + public SoundSettings Sounds { get; set; } = new(); + public HoverSettings Hover { get; set; } = new(); + public BattleTemplateSettings BattleTemplate { get; set; } = new(); + + // GUI Specific + public DrawConfig Draw { get; set; } = new(); + public AdvancedSettings Advanced { get; set; } = new(); + public EntityEditorSettings EntityEditor { get; set; } = new(); + public EntityDatabaseSettings EntityDb { get; set; } = new(); + public EncounterDatabaseSettings EncounterDb { get; set; } = new(); + public MysteryGiftDatabaseSettings MysteryDb { get; set; } = new(); + public ReportGridSettings Report { get; set; } = new(); + + [Browsable(false)] + public SlotExportSettings SlotExport { get; set; } = new(); + + + [Browsable(false), JsonIgnore] + IStartupSettings IProgramSettings.Startup => Startup; + + private static PKHeXSettingsContext GetContext() => new(new() + { + WriteIndented = true, + Converters = { new ColorJsonConverter() }, + }); + + public sealed class ColorJsonConverter : JsonConverter + { + public override Color Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => ColorTranslator.FromHtml(reader.GetString() ?? string.Empty); + + public override void Write(Utf8JsonWriter writer, Color value, JsonSerializerOptions options) => writer.WriteStringValue($"#{value.R:x2}{value.G:x2}{value.B:x2}"); + } + + public static PKHeXSettings GetSettings(string configPath) + { + if (!File.Exists(configPath)) + return new PKHeXSettings(); + + try + { + var lines = File.ReadAllText(configPath); + return JsonSerializer.Deserialize(lines, GetContext().PKHeXSettings) ?? new PKHeXSettings(); + } + catch (Exception x) + { + DumpConfigError(x); + return new PKHeXSettings(); + } + } + + public static async Task SaveSettings(string configPath, PKHeXSettings cfg) + { + try + { + // Serialize the object asynchronously and write it to the path. + await using var fs = File.Create(configPath); + await JsonSerializer.SerializeAsync(fs, cfg, GetContext().PKHeXSettings).ConfigureAwait(false); + } + catch (Exception x) + { + DumpConfigError(x); + } + } + + private static async void DumpConfigError(Exception x) + { + try + { + await File.WriteAllTextAsync("config error.txt", x.ToString()); + } + catch (Exception) + { + Debug.WriteLine(x); // ??? + } + } +} diff --git a/PKHeX.WinForms/Settings/SlotExportSettings.cs b/PKHeX.WinForms/Settings/SlotExportSettings.cs new file mode 100644 index 000000000..67328d0eb --- /dev/null +++ b/PKHeX.WinForms/Settings/SlotExportSettings.cs @@ -0,0 +1,15 @@ +using PKHeX.Core; + +namespace PKHeX.WinForms; + +public sealed class SlotExportSettings +{ + [LocalizedDescription("Settings to use for box exports.")] + public BoxExportSettings BoxExport { get; set; } = new(); + + [LocalizedDescription("Selected File namer to use for box exports for the GUI, if multiple are available.")] + public string DefaultBoxExportNamer { get; set; } = ""; + + [LocalizedDescription("Allow drag and drop of boxdata binary files from the GUI via the Box tab.")] + public bool AllowBoxDataDrop { get; set; } // default to false, clunky to use +} diff --git a/PKHeX.WinForms/Settings/SpriteSettings.cs b/PKHeX.WinForms/Settings/SpriteSettings.cs new file mode 100644 index 000000000..0d2342b99 --- /dev/null +++ b/PKHeX.WinForms/Settings/SpriteSettings.cs @@ -0,0 +1,49 @@ +using PKHeX.Core; +using PKHeX.Drawing.PokeSprite; + +namespace PKHeX.WinForms; + +public sealed class SpriteSettings : ISpriteSettings +{ + [LocalizedDescription("Choice for which sprite building mode to use.")] + public SpriteBuilderPreference SpritePreference { get; set; } = SpriteBuilderPreference.UseSuggested; + + [LocalizedDescription("Show fan-made shiny sprites when the PKM is shiny.")] + public bool ShinySprites { get; set; } = true; + + [LocalizedDescription("Show an Egg Sprite As Held Item rather than hiding the PKM")] + public bool ShowEggSpriteAsHeldItem { get; set; } = true; + + [LocalizedDescription("Show the required ball for an Encounter Template")] + public bool ShowEncounterBall { get; set; } = true; + + [LocalizedDescription("Show a background to differentiate an Encounter Template's type")] + public SpriteBackgroundType ShowEncounterColor { get; set; } = SpriteBackgroundType.FullBackground; + + [LocalizedDescription("Show a background to differentiate the recognized Encounter Template type for PKM slots")] + public SpriteBackgroundType ShowEncounterColorPKM { get; set; } + + [LocalizedDescription("Opacity for the Encounter Type background layer.")] + public byte ShowEncounterOpacityBackground { get; set; } = 0x3F; // kinda low + + [LocalizedDescription("Opacity for the Encounter Type stripe layer.")] + public byte ShowEncounterOpacityStripe { get; set; } = 0x5F; // 0xFF opaque + + [LocalizedDescription("Amount of pixels thick to show when displaying the encounter type color stripe.")] + public int ShowEncounterThicknessStripe { get; set; } = 4; // pixels + + [LocalizedDescription("Show a thin stripe to indicate the percent of level-up progress")] + public bool ShowExperiencePercent { get; set; } + + [LocalizedDescription("Show a background to differentiate the Tera Type for PKM slots")] + public SpriteBackgroundType ShowTeraType { get; set; } = SpriteBackgroundType.BottomStripe; + + [LocalizedDescription("Amount of pixels thick to show when displaying the Tera Type color stripe.")] + public int ShowTeraThicknessStripe { get; set; } = 4; // pixels + + [LocalizedDescription("Opacity for the Tera Type background layer.")] + public byte ShowTeraOpacityBackground { get; set; } = 0xFF; // 0xFF opaque + + [LocalizedDescription("Opacity for the Tera Type stripe layer.")] + public byte ShowTeraOpacityStripe { get; set; } = 0xAF; // 0xFF opaque +} diff --git a/PKHeX.WinForms/Settings/StartupSettings.cs b/PKHeX.WinForms/Settings/StartupSettings.cs new file mode 100644 index 000000000..2028701ff --- /dev/null +++ b/PKHeX.WinForms/Settings/StartupSettings.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using PKHeX.Core; + +namespace PKHeX.WinForms; + +public sealed class StartupSettings : IStartupSettings +{ + [Browsable(false)] + [LocalizedDescription("Last version that the program was run with.")] + public string Version { get; set; } = string.Empty; + + [LocalizedDescription("Use the Dark color mode for the application on startup.")] + public bool DarkMode { get; set; } + + [LocalizedDescription("Force HaX mode on Program Launch")] + public bool ForceHaXOnLaunch { get; set; } + + [LocalizedDescription("Automatically locates the most recently saved Save File when opening a new file.")] + public bool TryDetectRecentSave { get; set; } = true; + + [LocalizedDescription("Automatically Detect Save File on Program Startup")] + public SaveFileLoadSetting AutoLoadSaveOnStartup { get; set; } = SaveFileLoadSetting.RecentBackup; + + [LocalizedDescription("Show the changelog when a new version of the program is run for the first time.")] + public bool ShowChangelogOnUpdate { get; set; } = true; + + [LocalizedDescription("Loads plugins from the plugins folder, assuming the folder exists.")] + public bool PluginLoadEnable { get; set; } = true; + + [LocalizedDescription("Loads any plugins that were merged into the main executable file.")] + public bool PluginLoadMerged { get; set; } + + [Browsable(false)] + public List RecentlyLoaded { get; set; } = new(DefaultMaxRecent); + + private const int DefaultMaxRecent = 10; + private uint MaxRecentCount = DefaultMaxRecent; + + [LocalizedDescription("Amount of recently loaded save files to remember.")] + public uint RecentlyLoadedMaxCount + { + get => MaxRecentCount; + // Sanity check to not let the user foot-gun themselves a slow recall time. + set => MaxRecentCount = Math.Clamp(value, 1, 1000); + } + + // Don't let invalid values slip into the startup version. + private GameVersion _defaultSaveVersion = Latest.Version; + private string _language = WinFormsUtil.GetCultureLanguage(); + + [Browsable(false)] + public string Language + { + get => _language; + set + { + if (!GameLanguage.IsLanguageValid(value)) + { + // Migrate old language codes set in earlier versions. + _language = value switch + { + "zh" => "zh-Hans", + "zh2" => "zh-Hant", + _ => _language, + }; + return; + } + _language = value; + } + } + + [Browsable(false)] + public GameVersion DefaultSaveVersion + { + get => _defaultSaveVersion; + set + { + if (!value.IsValidSavedVersion()) + return; + _defaultSaveVersion = value; + } + } + + public void LoadSaveFile(string path) + { + var recent = RecentlyLoaded; + // Remove from list if already present. + if (!recent.Remove(path) && recent.Count >= MaxRecentCount) + recent.RemoveAt(recent.Count - 1); + recent.Insert(0, path); + } +} diff --git a/PKHeX.WinForms/Subforms/SettingsEditor.cs b/PKHeX.WinForms/Subforms/SettingsEditor.cs index 5cb6e672f..002dfeae9 100644 --- a/PKHeX.WinForms/Subforms/SettingsEditor.cs +++ b/PKHeX.WinForms/Subforms/SettingsEditor.cs @@ -82,7 +82,7 @@ private static void DeleteSettings() var dr = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Resetting settings requires the program to exit.", MessageStrings.MsgContinue); if (dr != DialogResult.Yes) return; - var path = Main.ConfigPath; + var path = Program.PathConfig; if (File.Exists(path)) File.Delete(path); System.Diagnostics.Process.Start(Application.ExecutablePath);