Startup: load config before Main ctor

Allows specifying Dark mode in settings now.
Extracts reusable settings objects to PKHeX.Core (drawing/GUI stuff kept in WinForms).
Updating settings now refreshes backup paths/mgdb
This commit is contained in:
Kurt 2025-08-13 20:59:46 -05:00
parent 80487a514d
commit 93a381bfde
39 changed files with 850 additions and 623 deletions

View File

@ -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; }
}

View File

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace PKHeX.Core;
@ -15,10 +15,14 @@ public interface IStartupSettings
/// <summary>
/// Method to load the environment's initial save file.
/// </summary>
AutoLoadSetting AutoLoadSaveOnStartup { get; }
SaveFileLoadSetting AutoLoadSaveOnStartup { get; }
/// <summary>
/// List of recently loaded save file paths.
/// </summary>
List<string> RecentlyLoaded { get; }
string Version { get; set; }
bool ShowChangelogOnUpdate { get; set; }
bool ForceHaXOnLaunch { get; set; }
}

View File

@ -3,7 +3,7 @@ namespace PKHeX.Core;
/// <summary>
/// Option to load a save file automatically to an editing environment.
/// </summary>
public enum AutoLoadSetting
public enum SaveFileLoadSetting
{
/// <summary>
/// Doesn't autoload a save file, and instead uses a fake save file data.

View File

@ -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());
}

View File

@ -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<string> OtherBackupPaths { get; set; } = [];
[LocalizedDescription("Save File file-extensions (no period) that the program should also recognize.")]
public List<string> OtherSaveFileExtensions { get; set; } = [];
}

View File

@ -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;
}

View File

@ -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; }
}

View File

@ -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,
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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; }
}

View File

@ -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<string> ExtraProperties { get; set; } = [];
[LocalizedDescription("Properties to hide from the report grid.")]
public List<string> HiddenProperties { get; set; } = [];
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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<object> Extra = [];
/// <summary>
/// Step 1: Reads in command line arguments.
/// </summary>
public void ReadArguments(IEnumerable<string> args)
public void ReadArguments(ReadOnlySpan<string> 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,
};

View File

@ -0,0 +1,99 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace PKHeX.Core;
/// <summary>
/// Logic for startup initialization and argument parsing.
/// </summary>
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<string> 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<string> 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<string> args)
{
foreach (var x in args)
{
var arg = x.AsSpan().Trim('-');
if (arg.Equals("HaX", StringComparison.CurrentCultureIgnoreCase))
return true;
}
ReadOnlySpan<char> path = Environment.ProcessPath!;
return Path.GetFileNameWithoutExtension(path).EndsWith("HaX");
}
}
public readonly record struct ProgramInit(bool ShowChangelog, bool BackupPrompt, bool HaX);

View File

@ -38,10 +38,7 @@ public static class ParseSettings
/// </summary>
public static bool AllowGen1Tradeback => Settings.Tradeback.AllowGen1Tradeback;
public static void Initialize(LegalitySettings settings)
{
Settings = settings;
}
public static void Initialize(LegalitySettings settings) => Settings = settings;
/// <summary>
/// Checks to see if Crystal is available to visit/originate from.

View File

@ -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<string> GenderSymbols { get; private set; } = GameInfo.GenderSymbolUnicode;
public static bool HaX { get; private set; }
private readonly string[] main_langlist = Enum.GetNames<ProgramLanguage>();
private static readonly List<IPlugin> Plugins = [];
public static bool HaX => Program.HaX;
private static List<IPlugin> 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<string> 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<string> args)
{
foreach (var x in args)
{
var arg = x.AsSpan().Trim('-');
if (arg.Equals(nameof(HaX), StringComparison.CurrentCultureIgnoreCase))
return true;
}
ReadOnlySpan<char> 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<ProgramLanguage>());
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
{

View File

@ -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);
/// <summary>
/// The main entry point for the application.
/// Global settings instance, loaded before any forms are created.
/// </summary>
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<char> GetSaneVersionTag(ReadOnlySpan<char> 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<char> GetSaneVersionTag(ReadOnlySpan<char> 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<T>(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
}
}
/// <summary>
/// Attempt to log exceptions to a file when there's an error displaying exception details.
/// </summary>
/// <param name="originalException"></param>
/// <param name="errorHandlingException"></param>
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;

View File

@ -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<Color>
{
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<string> OtherBackupPaths { get; set; } = [];
[LocalizedDescription("Save File file-extensions (no period) that the program should also recognize.")]
public List<string> 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<string> 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<string> ExtraProperties { get; set; } = [];
[LocalizedDescription("Properties to hide from the report grid.")]
public List<string> 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
}

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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=プレイヤーがつけたニックネームとトレーナー名に不適切な表現がないかをチェックします。チェックにはDS本体の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.

View File

@ -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.

View File

@ -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 编辑器选项卡中的属性指定性别和特性等标准。

View File

@ -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.

View File

@ -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; }
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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<Color>
{
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); // ???
}
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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<string> 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);
}
}

View File

@ -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);