Update to .NET 9, c# 13 (#4390)

This commit is contained in:
Kurt 2024-11-17 13:13:58 -06:00 committed by GitHub
parent adb67922c5
commit ceb669c112
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
112 changed files with 442 additions and 356 deletions

View file

@ -35,6 +35,23 @@ dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:sug
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggest
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggest
dotnet_style_parentheses_in_other_operators = always_for_clarity:suggest
csharp_indent_labels = one_less_than_current
csharp_using_directive_placement = outside_namespace:silent
csharp_prefer_simple_using_statement = true:suggestion
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent
csharp_style_prefer_primary_constructors = true:suggestion
csharp_prefer_system_threading_lock = true:suggestion
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
dotnet_diagnostic.WFO1000.severity = none
[*.{cs,vb}]
#### Naming styles ####
@ -43,3 +60,67 @@ dotnet_style_parentheses_in_other_operators = always_for_clarity:suggest
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.capitalization = pascal_case
[*.{cs,vb}]
#### Naming styles ####
# Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# Naming styles
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
end_of_line = crlf
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:silent
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_explicit_tuple_names = true:suggestion
# IDE0130: Namespace does not match folder structure
dotnet_diagnostic.IDE0130.severity = none

View file

@ -28,9 +28,9 @@ PKHeX erwartet entschlüsselte Spielstände. Da diese konsolenspezifisch verschl
## Erstellen
PKHeX ist eine Windows Forms Anwendung, welche die [.NET 8.0](https://dotnet.microsoft.com/download/dotnet/8.0) runtime benötigt.
PKHeX ist eine Windows Forms Anwendung, welche die [.NET 9.0](https://dotnet.microsoft.com/download/dotnet/9.0) runtime benötigt.
Die Anwendung kann mit jedem Kompiler erstellt werden, der C# 12 unterstützt.
Die Anwendung kann mit jedem Kompiler erstellt werden, der C# 13 unterstützt.
### Erstell Konfiguration

View file

@ -28,9 +28,9 @@ PKHeX espera archivos de guardado que no estén cifrados con las claves específ
## Building
PKHeX es una aplicación de Windows Forms que requiere [.NET 8.0](https://dotnet.microsoft.com/download/dotnet/8.0).
PKHeX es una aplicación de Windows Forms que requiere [.NET 9.0](https://dotnet.microsoft.com/download/dotnet/9.0).
El archivo ejecutable puede ser construido con cualquier compilador que soporte C# 12.
El archivo ejecutable puede ser construido con cualquier compilador que soporte C# 13.
### Configuraciones del Build

View file

@ -27,9 +27,9 @@ PKHeX attend des fichiers de sauvegarde qui ne sont pas chiffrés avec des clés
## Construction
PKHeX est une application Windows Forms qui nécessite [.NET 8.0.](https://dotnet.microsoft.com/download/dotnet/8.0)
PKHeX est une application Windows Forms qui nécessite [.NET 9.0.](https://dotnet.microsoft.com/download/dotnet/9.0)
L'exécutable peut être construit avec n'importe quel compilateur prenant en charge C# 12.
L'exécutable peut être construit avec n'importe quel compilateur prenant en charge C# 13.
### Construire les configurations

View file

@ -28,9 +28,9 @@ PKHeX si aspetta file di salvataggio non criptati con le chiavi specifiche della
## Building
PKHeX è un applicazione Windows Form che necessita del [.NET Desktop Runtime 8.0](https://dotnet.microsoft.com/download/dotnet/8.0).
PKHeX è un applicazione Windows Form che necessita del [.NET Desktop Runtime 9.0](https://dotnet.microsoft.com/download/dotnet/9.0).
L'eseguibile può essere compilato con qualsiasi compiler che supporti C# 12.
L'eseguibile può essere compilato con qualsiasi compiler che supporti C# 13.
### Configurazioni di Build

View file

@ -28,9 +28,9 @@ PKHeX 所读取存档文件必须是未经主机唯一密钥加密,因此请
## 构建
PKHeX 是 Windows 窗口应用程序,依赖于 [.NET 8.0](https://dotnet.microsoft.com/download/dotnet/8.0)。
PKHeX 是 Windows 窗口应用程序,依赖于 [.NET 9.0](https://dotnet.microsoft.com/download/dotnet/9.0)。
可以使用任何支持 C# 12 的编译器生成可执行文件。
可以使用任何支持 C# 13 的编译器生成可执行文件。
### 构建配置

View file

@ -28,9 +28,9 @@ PKHeX 所讀取檔案須未經主機唯一密鑰加密,因而請使用儲存
## 構建
PKHeX 係 Windows 窗體應用程式,其須依賴於 [.NET 7.0](https://dotnet.microsoft.com/download/dotnet/8.0)。
PKHeX 係 Windows 窗體應用程式,其須依賴於 [.NET 9.0](https://dotnet.microsoft.com/download/dotnet/9.0)。
程式可透過任意支援 C# 12 之編譯器構建。
程式可透過任意支援 C# 13 之編譯器構建。
### 構建配置

View file

@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<Version>24.11.11</Version>
<LangVersion>12</LangVersion>
<LangVersion>13</LangVersion>
<Nullable>enable</Nullable>
<NeutralLanguage>en</NeutralLanguage>
<Product>PKHeX</Product>

View file

@ -12,8 +12,8 @@ public static class BoxManipDefaults
/// <summary>
/// Common sorting actions.
/// </summary>
public static readonly IReadOnlyList<BoxManipBase> SortCommon = new List<BoxManipBase>
{
public static readonly IReadOnlyList<BoxManipBase> SortCommon =
[
new BoxManipSort(SortSpecies, EntitySorting.OrderBySpecies),
new BoxManipSort(SortSpeciesReverse, EntitySorting.OrderByDescendingSpecies),
new BoxManipSort(SortLevel, EntitySorting.OrderByLevel),
@ -24,13 +24,13 @@ public static class BoxManipDefaults
new BoxManipSortComplex(SortParty, (list, sav, start) => list.BubbleUp(sav, i => ((SAV7b)sav).Blocks.Storage.IsParty(i), start), s => s is SAV7b),
new BoxManipSort(SortShiny, list => list.OrderByCustom(pk => !pk.IsShiny)),
new BoxManipSort(SortRandom, list => list.OrderByCustom(_ => Util.Rand.Next())),
};
];
/// <summary>
/// Advanced sorting actions.
/// </summary>
public static readonly IReadOnlyList<BoxManipBase> SortAdvanced = new List<BoxManipBase>
{
public static readonly IReadOnlyList<BoxManipBase> SortAdvanced =
[
new BoxManipSort(SortUsage, EntitySorting.OrderByUsage, s => s.Generation >= 3),
new BoxManipSort(SortPotential, list => list.OrderByCustom(pk => (pk.MaxIV * 6) - pk.IVTotal)),
new BoxManipSort(SortTraining, list => list.OrderByCustom(pk => (pk.MaxEV * 6) - pk.EVTotal)),
@ -45,13 +45,13 @@ public static class BoxManipDefaults
new BoxManipSort(SortMarks, list => list.OrderByCustom(pk => pk is IRibbonSetMarks s ? int.MaxValue - s.MarkCount : 0), s => s.BlankPKM is IRibbonSetMarks),
new BoxManipSort(SortLegal, list => list.OrderByCustom(pk => !new LegalityAnalysis(pk).Valid)),
new BoxManipSort(SortEncounterType, list => list.OrderByCustom(pk => new LegalityAnalysis(pk).Info.EncounterMatch.LongName)),
};
];
/// <summary>
/// Common deletion actions.
/// </summary>
public static readonly IReadOnlyList<BoxManipBase> ClearCommon = new List<BoxManipBase>
{
public static readonly IReadOnlyList<BoxManipBase> ClearCommon =
[
new BoxManipClear(DeleteAll, _ => true),
new BoxManipClear(DeleteEggs, pk => pk.IsEgg, s => s.Generation >= 2 && s is not SAV8LA),
new BoxManipClearComplex(DeletePastGen, (pk, sav) => pk.Generation != sav.Generation, s => s.Generation >= 4),
@ -61,13 +61,13 @@ public static class BoxManipDefaults
new BoxManipClear(DeleteItemless, pk => pk.HeldItem == 0, s => s is not SAV8LA),
new BoxManipClear(DeleteIllegal, pk => !new LegalityAnalysis(pk).Valid),
new BoxManipClearDuplicate<string>(DeleteClones, pk => SearchUtil.GetCloneDetectMethod(CloneDetectionMethod.HashDetails)(pk)),
};
];
/// <summary>
/// Common modifying actions.
/// </summary>
public static readonly IReadOnlyList<BoxManipBase> ModifyCommon = new List<BoxManipBase>
{
public static readonly IReadOnlyList<BoxManipBase> ModifyCommon =
[
new BoxManipModifyComplex(ModifyHatchEggs, (pk, sav) => pk.ForceHatchPKM(sav), s => s.Generation >= 2 && s is not SAV8LA),
new BoxManipModify(ModifyMaxFriendship, pk => pk.MaximizeFriendship()),
new BoxManipModify(ModifyMaxLevel, pk => pk.MaximizeLevel()),
@ -78,5 +78,5 @@ public static class BoxManipDefaults
new BoxManipModify(ModifyRemoveNicknames, pk => pk.SetDefaultNickname()),
new BoxManipModify(ModifyRemoveItem, pk => pk.HeldItem = 0, s => s.Generation >= 2),
new BoxManipModify(ModifyHeal, pk => pk.Heal(), s => s.Generation >= 6), // HP stored in box, or official code has bugged transfer PP the user would like to rectify.
};
];
}

View file

@ -14,7 +14,7 @@ public sealed class EventWork<T> : EventVar where T : struct
/// <summary>
/// Values with known behavior. They are labeled with a humanized string.
/// </summary>
public readonly IList<EventWorkVal> Options = new List<EventWorkVal> { new() };
public readonly List<EventWorkVal> Options = [new()];
public EventWork(int index, EventVarType t, IReadOnlyList<string> pieces) : base(index, t, pieces[1])
{

View file

@ -11,30 +11,30 @@ public sealed class GameDataSource
/// <summary>
/// List of <see cref="Region3DSIndex"/> values to display.
/// </summary>
public static readonly IReadOnlyList<ComboItem> Regions = new List<ComboItem>
{
public static readonly IReadOnlyList<ComboItem> Regions =
[
new ("Japan (日本)", 0),
new ("Americas (NA/SA)", 1),
new ("Europe (EU/AU)", 2),
new ("China (中国大陆)", 4),
new ("Korea (한국)", 5),
new ("Taiwan (香港/台灣)", 6),
};
];
/// <summary>
/// List of <see cref="LanguageID"/> values to display.
/// </summary>
private static readonly ComboItem[] LanguageList =
[
new ComboItem("JPN (日本語)", (int)LanguageID.Japanese),
new ComboItem("ENG (English)", (int)LanguageID.English),
new ComboItem("FRE (Français)", (int)LanguageID.French),
new ComboItem("ITA (Italiano)", (int)LanguageID.Italian),
new ComboItem("GER (Deutsch)", (int)LanguageID.German),
new ComboItem("ESP (Español)", (int)LanguageID.Spanish),
new ComboItem("KOR (한국어)", (int)LanguageID.Korean),
new ComboItem("CHS (简体中文)", (int)LanguageID.ChineseS),
new ComboItem("CHT (繁體中文)", (int)LanguageID.ChineseT),
new ("JPN (日本語)", (int)LanguageID.Japanese),
new ("ENG (English)", (int)LanguageID.English),
new ("FRE (Français)", (int)LanguageID.French),
new ("ITA (Italiano)", (int)LanguageID.Italian),
new ("GER (Deutsch)", (int)LanguageID.German),
new ("ESP (Español)", (int)LanguageID.Spanish),
new ("KOR (한국어)", (int)LanguageID.Korean),
new ("CHS (简体中文)", (int)LanguageID.ChineseS),
new ("CHT (繁體中文)", (int)LanguageID.ChineseT),
];
/// <summary>

View file

@ -101,7 +101,7 @@ public static class EncounterEvent
/// Reloads the locally stored event templates.
/// </summary>
/// <param name="paths">External folder(s) to source individual mystery gift template files from.</param>
public static void RefreshMGDB(params string[] paths)
public static void RefreshMGDB(params ReadOnlySpan<string> paths)
{
// If no paths are provided, clear the arrays. See the bottom of this method.
HashSet<PCD>? g4 = null; List<PCD>? lg4 = null;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible1(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible2(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version, PKM Entity) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible3(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible3GC(EvoCriteria[] Chain, EncounterTypeGroup Flags) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible4(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version, PKM Entity) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible5(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible6(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible7(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible7GG(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible7GO(EvoCriteria[] Chain, EncounterTypeGroup Flags) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible8(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible8GO(EvoCriteria[] Chain, EncounterTypeGroup Flags) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible8a(EvoCriteria[] Chain, EncounterTypeGroup Flags) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible8b(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version, PKM Entity) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public record struct EncounterPossible9(EvoCriteria[] Chain, EncounterTypeGroup Flags, GameVersion Version) : IEnumerator<IEncounterable>
{
public IEncounterable Current { get; private set; }
public IEncounterable Current { get; private set; } = null!;
private int Index;
private int SubIndex;

View file

@ -671,7 +671,7 @@ public static class MethodFinder
pidiv = PIDIV.None;
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static PIDIV AnalyzeGB(PKM _)
{

View file

@ -1,5 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
@ -52,7 +52,8 @@ public static class WordFilter
/// <summary>
/// Due to some messages repeating (Trainer names), keep a list of repeated values for faster lookup.
/// </summary>
private static readonly Dictionary<string, string?> Lookup = new(INIT_COUNT);
private static readonly ConcurrentDictionary<string, string?>.AlternateLookup<ReadOnlySpan<char>> Lookup =
new ConcurrentDictionary<string, string?>().GetAlternateLookup<ReadOnlySpan<char>>();
/// <summary>
/// Checks to see if a phrase contains filtered content.
@ -60,45 +61,35 @@ public static class WordFilter
/// <param name="message">Phrase to check for</param>
/// <param name="regMatch">Matching regex that filters the phrase.</param>
/// <returns>Boolean result if the message is filtered or not.</returns>
public static bool IsFiltered(string message, [NotNullWhen(true)] out string? regMatch)
public static bool IsFiltered(ReadOnlySpan<char> message, [NotNullWhen(true)] out string? regMatch)
{
if (string.IsNullOrWhiteSpace(message) || message.Length <= 1)
if (message.IsWhiteSpace() || message.Length <= 1)
{
regMatch = null;
return false;
}
// Check dictionary
lock (dictLock)
{
if (Lookup.TryGetValue(message, out regMatch))
return regMatch != null;
}
if (Lookup.TryGetValue(message, out regMatch))
return regMatch != null;
// Make the string lowercase invariant
Span<char> lowercase = stackalloc char[message.Length];
for (int i = 0; i < lowercase.Length; i++)
lowercase[i] = char.ToLowerInvariant(message[i]);
message.ToLowerInvariant(lowercase);
// not in dictionary, check patterns
if (TryMatch(lowercase, out regMatch))
{
lock (dictLock)
Lookup[message] = regMatch;
Lookup.TryAdd(message, regMatch);
return true;
}
// didn't match any pattern, cache result
lock (dictLock)
{
if ((Lookup.Count & ~MAX_COUNT) != 0)
Lookup.Clear(); // reset
Lookup[message] = regMatch = null;
}
if ((Lookup.Dictionary.Count & ~MAX_COUNT) != 0)
Lookup.Dictionary.Clear(); // reset
Lookup.TryAdd(message, regMatch = null);
return false;
}
private static readonly object dictLock = new();
private const int MAX_COUNT = (1 << 17) - 1; // arbitrary cap for max dictionary size
private const int INIT_COUNT = 1 << 10; // arbitrary init size to limit future doublings
}

View file

@ -67,7 +67,7 @@ public sealed class NicknameVerifier : Verifier
// Non-nicknamed strings have already been checked.
if (ParseSettings.Settings.WordFilter.IsEnabled(pk.Format) && pk.IsNicknamed)
{
if (WordFilter.IsFiltered(nickname.ToString(), out var badPattern))
if (WordFilter.IsFiltered(nickname, out var badPattern))
data.AddLine(GetInvalid($"Word Filter: {badPattern}"));
if (TrainerNameVerifier.ContainsTooManyNumbers(nickname, data.Info.Generation))
data.AddLine(GetInvalid("Word Filter: Too many numbers."));

View file

@ -54,12 +54,14 @@ public sealed class TrainerNameVerifier : Verifier
if (ParseSettings.Settings.WordFilter.IsEnabled(pk.Format))
{
if (WordFilter.IsFiltered(trainer.ToString(), out var badPattern))
if (WordFilter.IsFiltered(trainer, out var badPattern))
data.AddLine(GetInvalid($"Word Filter: {badPattern}"));
if (ContainsTooManyNumbers(trainer, data.Info.Generation))
data.AddLine(GetInvalid("Word Filter: Too many numbers."));
if (WordFilter.IsFiltered(pk.HandlingTrainerName, out badPattern))
Span<char> ht = stackalloc char[pk.TrashCharCountTrainer];
int nameLen = pk.LoadString(pk.HandlingTrainerTrash, ht);
if (WordFilter.IsFiltered(ht[..nameLen], out badPattern))
data.AddLine(GetInvalid($"Word Filter: {badPattern}"));
}
}

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<Description>Pokémon C# Class Library</Description>
<RootNamespace>PKHeX.Core</RootNamespace>
</PropertyGroup>

View file

@ -157,11 +157,9 @@ public static class SpeciesName
}
Span<char> result = stackalloc char[nick.Length];
nick.CopyTo(result);
// All names are uppercase.
foreach (ref var c in result)
c = char.ToUpperInvariant(c);
nick.AsSpan().ToUpperInvariant(result);
if (language == (int)LanguageID.French)
StringConverter4Util.StripDiacriticsFR4(result); // strips accents on E and I

View file

@ -19,7 +19,7 @@ public sealed class SaveBlockMetadata<T>
public IEnumerable<string> GetSortedBlockList()
{
return BlockList.Select(z => z.Key).OrderBy(z => z);
return BlockList.Select(z => z.Key).Order();
}
public IDataIndirect GetBlock(string name) => BlockList.First(z => z.Key == name).Value;

View file

@ -814,7 +814,7 @@ public sealed class SAV2 : SaveFile, ILangDeviantSave, IEventFlagArray, IEventWo
}
public bool IsGBMobileAvailable => Japanese && Version == GameVersion.C;
public bool IsGBMobileEnabled => Japanese && Enum.IsDefined(typeof(GBMobileCableColor), GBMobileCable);
public bool IsGBMobileEnabled => Japanese && Enum.IsDefined(GBMobileCable);
public GBMobileCableColor GBMobileCable
{

View file

@ -70,7 +70,7 @@ public sealed class SAV2Stadium : SAV_STADIUM, IBoxDetailName
ClearBoxes();
}
protected sealed override void SetChecksums()
protected override void SetChecksums()
{
base.SetChecksums();
SetMailChecksums();

View file

@ -14,7 +14,7 @@ public sealed class Daycare8b(SAV8BS sav, Memory<byte> raw) : SaveBlock<SAV8BS>(
// BLOCK STRUCTURE
// PB8[2] Parents;
// bool32 eggExist;
// ulong eggSeed; -- setter puts only 32 bits!
// ulong eggSeed; -- setter does sign extension from signed 32 bit value!
// int32 eggStepCount;
private const int SlotCount = 2;
@ -62,9 +62,15 @@ public sealed class Daycare8b(SAV8BS sav, Memory<byte> raw) : SaveBlock<SAV8BS>(
set => WriteUInt64LittleEndian(ExtraData[4..], value);
}
/// <summary>
/// Sign extension when setting a 32-bit integer seed to a 64-bit value.
/// </summary>
/// <remarks>If the top bit is set in the 32-bit unsigned representation, bits 32-63 will be set as well.</remarks>
public void SetSeed(int seed) => Seed = (ulong)seed;
public int EggStepCount
{
get => ReadInt32LittleEndian(ExtraData[8..]);
set => WriteInt32LittleEndian(ExtraData[8..], value);
get => ReadInt32LittleEndian(ExtraData[12..]);
set => WriteInt32LittleEndian(ExtraData[12..], value);
}
}

View file

@ -151,9 +151,9 @@ public sealed class FashionUnlock8(SAV8SWSH sav, SCBlock block) : SaveBlock<SAV8
];
private static ReadOnlySpan<ushort> InvalidFashionOffset_M => [
0x969, 0xB00, 0xC48, 0xC49, 0xC4A, 0xD57, 0xE37, 0xE38, 0xE39
0x969, 0xB00, 0xC48, 0xC49, 0xC4A, 0xD57, 0xE37, 0xE38, 0xE39,
];
private static ReadOnlySpan<ushort> InvalidFashionOffset_F => [
0x95D, 0xB00, 0xD76, 0xD77, 0xE41, 0xE47
0x95D, 0xB00, 0xD76, 0xD77, 0xE41, 0xE47,
];
}

View file

@ -55,7 +55,7 @@ public sealed class Mail2 : MailDetail
};
#region Offsets
public static int GetMailboxOffset(int language) => 0x600 + (COUNT_PARTY * 2) * GetMailSize(language);
public static int GetMailboxOffset(int language) => 0x600 + ((COUNT_PARTY * 2) * GetMailSize(language));
private static int GetMailOffset(int index, int size)
{
@ -75,7 +75,7 @@ public sealed class Mail2 : MailDetail
{
if ((uint)index >= COUNT_MAILBOX)
throw new ArgumentOutOfRangeException(nameof(index));
return (index * size) + (0x600 + (COUNT_PARTY * 2) * size + 1);
return (index * size) + (0x600 + ((COUNT_PARTY * 2) * size) + 1);
}
public static int GetMailboxOffsetStadium2(int language) => SAV2Stadium.MailboxBlockOffset(language) + 1;
@ -137,7 +137,7 @@ public sealed class Mail2 : MailDetail
public override void SetMessage(string line1, string line2, bool userEntered)
{
if (IsEmpty == true && line1 == string.Empty && line2 == string.Empty)
if (IsEmpty == true && line1.Length == 0 && line2.Length == 0)
{
Data.AsSpan(0, MESSAGE_LENGTH).Clear();
return;
@ -158,7 +158,7 @@ public sealed class Mail2 : MailDetail
// Japanese/international user-entered mail always has a line break at index 0x10
var span1 = Data.AsSpan(0, LINE_LENGTH);
SetString(span1, line1, LINE_LENGTH);
if (line2 != string.Empty) // Pad the first line with spaces if needed
if (line2.Length != 0) // Pad the first line with spaces if needed
span1.Replace<byte>(0x50, 0x7F);
Data[LINE_LENGTH] = LineBreakCode;
var span2 = Data.AsSpan(LINE_LENGTH + 1, LINE_LENGTH);

View file

@ -36,7 +36,7 @@ public sealed class Mail3 : MailDetail
set
{
var span = Data.AsSpan(0x12, 8);
if (value == string.Empty)
if (value.Length == 0)
{
span.Fill(0xFF);
return;

View file

@ -117,55 +117,23 @@ public static partial class Util
return result;
}
#if NET9_0_OR_GREATER
REPLACE WITH TryFromHexString / TryToHexString
#endif
/// <summary>
/// Parses a variable length hex string (non-spaced, bytes in reverse order).
/// Parses a variable length hex string (non-spaced, bytes in order).
/// </summary>
public static byte[] GetBytesFromHexString(ReadOnlySpan<char> input)
{
byte[] result = new byte[input.Length / 2];
GetBytesFromHexString(input, result);
return result;
}
=> Convert.FromHexString(input);
/// <inheritdoc cref="GetBytesFromHexString(ReadOnlySpan{char})"/>
public static void GetBytesFromHexString(ReadOnlySpan<char> input, Span<byte> result)
{
for (int i = 0; i < result.Length; i++)
{
var slice = input.Slice(i * 2, 2);
result[^(i + 1)] = (byte)GetHexValue(slice);
}
}
private const string HexChars = "0123456789ABCDEF";
=> Convert.FromHexString(input, result, out _, out _);
/// <summary>
/// Converts the byte array into a hex string (non-spaced, bytes in reverse order).
/// Converts the byte array into a hex string (non-spaced, bytes in order).
/// </summary>
public static string GetHexStringFromBytes(ReadOnlySpan<byte> data)
{
System.Diagnostics.Debug.Assert(data.Length is (4 or 8 or 12 or 16));
Span<char> result = stackalloc char[data.Length * 2];
GetHexStringFromBytes(data, result);
return new string(result);
}
/// <inheritdoc cref="GetHexStringFromBytes(ReadOnlySpan{byte})"/>
public static void GetHexStringFromBytes(ReadOnlySpan<byte> data, Span<char> result)
{
if (result.Length != data.Length * 2)
throw new ArgumentException("Result buffer must be twice the size of the input buffer.");
for (int i = 0; i < data.Length; i++)
{
// Write tuples from the opposite side of the result buffer.
var offset = (data.Length - i - 1) * 2;
result[offset + 0] = HexChars[data[i] >> 4];
result[offset + 1] = HexChars[data[i] & 0xF];
}
return Convert.ToHexString(data);
}
/// <summary>

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<TargetFramework>net9.0-windows</TargetFramework>
<RootNamespace>PKHeX.Drawing.Misc</RootNamespace>
</PropertyGroup>

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<TargetFramework>net9.0-windows</TargetFramework>
<RootNamespace>PKHeX.Drawing.PokeSprite</RootNamespace>
</PropertyGroup>

View file

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<TargetFramework>net9.0-windows</TargetFramework>
<RootNamespace>PKHeX.Drawing</RootNamespace>
</PropertyGroup>

View file

@ -84,13 +84,13 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
FlickerInterface();
}
private sealed class ValidationRequiredSet(Control[] Controls, Func<PKM, bool> ShouldCheck, Func<Control, bool> State)
private sealed class ValidationRequiredSet(Control[] controls, Func<PKM, bool> shouldCheck, Func<Control, bool> isState)
{
public Control? IsNotValid(PKM pk)
{
if (!ShouldCheck(pk))
if (!shouldCheck(pk))
return null;
return Array.Find(Controls, z => State(z));
return Array.Find(controls, z => isState(z));
}
}
@ -392,7 +392,7 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
}
// General Use Functions //
private void SetDetailsOT(ITrainerInfo tr)
private void SetDetailsOT<T>(T tr) where T : ITrainerInfo
{
if (string.IsNullOrWhiteSpace(tr.OT))
return;
@ -423,7 +423,7 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
UpdateNickname(this, EventArgs.Empty);
}
private void SetDetailsHT(ITrainerInfo tr)
private void SetDetailsHT<T>(T tr) where T : ITrainerInfo
{
var trainer = tr.OT;
if (trainer.Length == 0)
@ -998,8 +998,8 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
if (FieldsLoaded && sender == CB_Form)
{
Entity.Form = (byte)CB_Form.SelectedIndex;
uint EXP = Experience.GetEXP(Entity.CurrentLevel, Entity.PersonalInfo.EXPGrowth);
TB_EXP.Text = EXP.ToString();
uint exp = Experience.GetEXP(Entity.CurrentLevel, Entity.PersonalInfo.EXPGrowth);
TB_EXP.Text = exp.ToString();
}
UpdateStats();
@ -1182,8 +1182,8 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
return;
// Recalculate EXP for Given Level
uint EXP = Experience.GetEXP(Entity.CurrentLevel, Entity.PersonalInfo.EXPGrowth);
TB_EXP.Text = EXP.ToString();
uint exp = Experience.GetEXP(Entity.CurrentLevel, Entity.PersonalInfo.EXPGrowth);
TB_EXP.Text = exp.ToString();
// Check for Gender Changes
UC_Gender.Gender = Entity.GetSaneGender();
@ -1242,11 +1242,11 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
private void ReloadMetLocations(GameVersion version, EntityContext context)
{
var metList = GameInfo.GetLocationList(version, context, egg: false);
CB_MetLocation.DataSource = new BindingSource(metList, null);
CB_MetLocation.DataSource = new BindingSource(metList, string.Empty);
CB_MetLocation.DropDownWidth = GetWidth(metList, CB_MetLocation.Font);
var eggList = GameInfo.GetLocationList(version, context, egg: true);
CB_EggLocation.DataSource = new BindingSource(eggList, null);
CB_EggLocation.DataSource = new BindingSource(eggList, string.Empty);
CB_EggLocation.DropDownWidth = GetWidth(eggList, CB_EggLocation.Font);
static int GetWidth(IReadOnlyCollection<ComboItem> items, Font f)
@ -1800,7 +1800,7 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
{
FieldsLoaded = false;
var index = WinFormsUtil.GetIndex(c);
c.DataSource = new BindingSource(LegalMoveSource.Display.DataSource, null);
c.DataSource = new BindingSource(LegalMoveSource.Display.DataSource, string.Empty);
c.SelectedValue = index;
FieldsLoaded = true;
}
@ -2008,7 +2008,7 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
{
FieldsLoaded = false;
bool TranslationRequired = false;
bool isTranslationRequired = false;
PopulateFilteredDataSources(sav);
PopulateFields(Entity);
@ -2027,7 +2027,7 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
{
Hidden_TC.TabPages.Insert(1, Hidden_Met);
TC_Editor.TabPages.Insert(1, Tab_Met);
TranslationRequired = true;
isTranslationRequired = true;
}
if (Entity.Format <= 2 && Hidden_TC.TabPages.Contains(Hidden_Cosmetic))
@ -2039,7 +2039,7 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
{
Hidden_TC.TabPages.Insert(4, Hidden_Cosmetic);
TC_Editor.TabPages.Insert(4, Tab_Cosmetic);
TranslationRequired = true;
isTranslationRequired = true;
}
if (!HaX && sav is SAV7b)
@ -2058,7 +2058,7 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
// pk2 save files do not have an Origin Game stored. Prompt the met location list to update.
if (Entity.Format == 2)
CheckMetLocationChange(GameVersion.C, Entity.Context);
return TranslationRequired;
return isTranslationRequired;
}
private void CenterSubEditors()
@ -2082,13 +2082,12 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
}
}
// ReSharper disable once FieldCanBeMadeReadOnly.Global
public Action<IBattleTemplate> LoadShowdownSet;
public Action<IBattleTemplate> LoadShowdownSet { get; set; }
private void LoadShowdownSetDefault(IBattleTemplate Set)
private void LoadShowdownSetDefault(IBattleTemplate set)
{
var pk = PreparePKM();
pk.ApplySetDetails(Set);
pk.ApplySetDetails(set);
PopulateFields(pk);
}
@ -2152,9 +2151,9 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
SetCountrySubRegion(CB_Country, "countries");
CB_3DSReg.DataSource = source.ConsoleRegions;
CB_GroundTile.DataSource = new BindingSource(source.G4GroundTiles, null);
CB_Nature.DataSource = new BindingSource(source.Natures, null);
CB_StatNature.DataSource = new BindingSource(source.Natures, null);
CB_GroundTile.DataSource = new BindingSource(source.G4GroundTiles, string.Empty);
CB_Nature.DataSource = new BindingSource(source.Natures, string.Empty);
CB_StatNature.DataSource = new BindingSource(source.Natures, string.Empty);
// Sub-editors
Stats.InitializeDataSources();
@ -2166,7 +2165,7 @@ public sealed partial class PKMEditor : UserControl, IMainEditor
{
if (!force && exist.DataSource is BindingSource b && b.Count == update.Count)
return;
exist.DataSource = new BindingSource(update, null);
exist.DataSource = new BindingSource(update, string.Empty);
}
private void PopulateFilteredDataSources(ITrainerInfo sav, bool force = false)

View file

@ -739,8 +739,8 @@ public partial class StatEditor : UserControl
var tera = Util.GetCBList(types[..TeraDisplayIndex]);
tera.Insert(0, new(TeraOverrideNone, TeraOverrideNoneValue));
tera.Add(new(types[TeraDisplayIndex], TeraStellarValue));
CB_TeraTypeOriginal.DataSource = new BindingSource(tera, null);
CB_TeraTypeOverride.DataSource = new BindingSource(tera, null);
CB_TeraTypeOriginal.DataSource = new BindingSource(tera, string.Empty);
CB_TeraTypeOverride.DataSource = new BindingSource(tera, string.Empty);
ChangingFields = false;
}
@ -757,7 +757,7 @@ public partial class StatEditor : UserControl
MainEditor.UpdateSprite();
}
private void L_TeraTypeOverride_Click(object sender, EventArgs e) => CB_TeraTypeOverride.SelectedValue = Entity.SV ? (int)TeraOverrideNoneValue : CB_TeraTypeOriginal.SelectedValue;
private void L_TeraTypeOverride_Click(object sender, EventArgs e) => CB_TeraTypeOverride.SelectedValue = Entity.SV ? (int)TeraOverrideNoneValue : CB_TeraTypeOriginal.SelectedValue!;
private void ChangeTeraType(object sender, EventArgs e)
{

View file

@ -1,6 +1,7 @@
using System;
using System.Buffers;
using System.Drawing;
using System.Threading;
using System.Timers;
using System.Windows.Forms;
using PKHeX.Drawing;
@ -20,7 +21,7 @@ public sealed class BitmapAnimator : IDisposable
private Image? ExtraLayer;
private Image?[]? GlowCache;
private Image? OriginalBackground;
private readonly object Lock = new();
private readonly Lock Lock = new();
private PictureBox? pb;
private int GlowInterval;

View file

@ -695,8 +695,10 @@ public partial class SAVEditor : UserControl, ISlotViewer<PictureBox>, ISaveFile
}
else
{
form = new SAV_GroupViewer(sav, M.Env.PKMEditor, g);
form.Owner = ParentForm;
form = new SAV_GroupViewer(sav, M.Env.PKMEditor, g)
{
Owner = ParentForm,
};
}
form.BringToFront();
form.Show();
@ -1263,7 +1265,7 @@ public partial class SAVEditor : UserControl, ISlotViewer<PictureBox>, ISaveFile
var current = br.CurrentSlot;
var list = br.SaveNames.Select((z, i) => new ComboItem(z, i)).ToList();
CB_SaveSlot.InitializeBinding();
CB_SaveSlot.DataSource = new BindingSource(list, null);
CB_SaveSlot.DataSource = new BindingSource(list, string.Empty);
CB_SaveSlot.SelectedValue = current;
}
else
@ -1418,35 +1420,42 @@ public partial class SAVEditor : UserControl, ISlotViewer<PictureBox>, ISaveFile
private async void TabMouseMove(object sender, MouseEventArgs e)
{
if (!IsBoxDragActive)
return;
if (e.Location == DragStartPoint)
return;
// Gather data
var src = SAV.CurrentBox;
var bin = SAV.GetBoxBinary(src);
// Create Temp File to Drag
var newFile = Path.Combine(Path.GetTempPath(), $"box_{src}.bin");
try
{
using var img = new Bitmap(Box.Width, Box.Height);
Box.DrawToBitmap(img, new Rectangle(0, 0, Box.Width, Box.Height));
using var cursor = Cursor = new Cursor(img.GetHicon());
await File.WriteAllBytesAsync(newFile, bin).ConfigureAwait(true);
DoDragDrop(new DataObject(DataFormats.FileDrop, new[] { newFile }), DragDropEffects.Copy);
if (!IsBoxDragActive)
return;
if (e.Location == DragStartPoint)
return;
// Gather data
var src = SAV.CurrentBox;
var bin = SAV.GetBoxBinary(src);
// Create Temp File to Drag
var newFile = Path.Combine(Path.GetTempPath(), $"box_{src}.bin");
try
{
using var img = new Bitmap(Box.Width, Box.Height);
Box.DrawToBitmap(img, new Rectangle(0, 0, Box.Width, Box.Height));
using var cursor = Cursor = new Cursor(img.GetHicon());
await File.WriteAllBytesAsync(newFile, bin).ConfigureAwait(true);
DoDragDrop(new DataObject(DataFormats.FileDrop, new[] { newFile }), DragDropEffects.Copy);
}
// Tons of things can happen with drag & drop; don't try to handle things, just indicate failure.
catch (Exception x)
{ WinFormsUtil.Error("Drag && Drop Error", x); }
finally
{
Cursor = Cursors.Default;
await Task.Delay(100).ConfigureAwait(false);
IsBoxDragActive = false;
await DeleteAsync(newFile, 20_000).ConfigureAwait(false);
}
}
// Tons of things can happen with drag & drop; don't try to handle things, just indicate failure.
catch (Exception x)
{ WinFormsUtil.Error("Drag && Drop Error", x); }
finally
catch
{
Cursor = Cursors.Default;
await Task.Delay(100).ConfigureAwait(false);
IsBoxDragActive = false;
await DeleteAsync(newFile, 20_000).ConfigureAwait(false);
// Ignore.
}
}

View file

@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Media;
using System.Threading.Tasks;
using System.Windows.Forms;
@ -170,12 +169,19 @@ public sealed class SlotChangeManager(SAVEditor se) : IDisposable
private async void DeleteAsync(string path, int delay)
{
await Task.Delay(delay).ConfigureAwait(true);
if (!File.Exists(path) || Drag.Info.CurrentPath == path)
return;
try
{
await Task.Delay(delay).ConfigureAwait(true);
if (!File.Exists(path) || Drag.Info.CurrentPath == path)
return;
try { File.Delete(path); }
catch (Exception ex) { Debug.WriteLine(ex.Message); }
try { File.Delete(path); }
catch (Exception ex) { Debug.WriteLine(ex.Message); }
}
catch
{
// Ignore.
}
}
private string CreateDragDropPKM(PictureBox pb, bool encrypt, out bool external)
@ -201,7 +207,8 @@ public sealed class SlotChangeManager(SAVEditor se) : IDisposable
private bool TryMakeDragDropPKM(PictureBox pb, byte[] data, string newfile)
{
File.WriteAllBytes(newfile, data);
var img = (Bitmap)pb.Image;
if (pb.Image is not Bitmap img)
return false;
Drag.SetCursor(pb.FindForm(), new Cursor(img.GetHicon()));
Hover.Stop();
pb.Image = null;
@ -379,7 +386,7 @@ public sealed class SlotChangeManager(SAVEditor se) : IDisposable
LastSlot.CurrentBackground?.Dispose();
}
private void UpdateBoxViewAtBoxIndexes(params int[] boxIndexes)
private void UpdateBoxViewAtBoxIndexes(params ReadOnlySpan<int> boxIndexes)
{
foreach (var box in Boxes)
{

View file

@ -174,7 +174,7 @@ public partial class PokePreview : Form
}
break;
}
sb.AppendLine(line.ToString());
sb.Append(line).AppendLine();
}
var detail = sb.ToString();
@ -182,7 +182,7 @@ public partial class PokePreview : Form
while (lines.MoveNext())
{
var line = lines.Current;
sb.AppendLine(line.ToString());
sb.Append(line).AppendLine();
}
var enc = sb.ToString();
return (detail.TrimEnd(), enc.TrimEnd());

View file

@ -1100,7 +1100,8 @@ public partial class Main : Form
var qr = QREncode.GenerateQRCode(pk);
var sprite = dragout.Image;
if (dragout.Image is not Bitmap sprite)
return;
var la = new LegalityAnalysis(pk, C_SAV.SAV.Personal);
if (la.Parsed && pk.Species != 0)
{
@ -1214,6 +1215,7 @@ public partial class Main : Form
e.Effect = DragDropEffects.Copy;
}
// ReSharper disable once AsyncVoidMethod
private async void Dragout_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left)
@ -1292,17 +1294,24 @@ public partial class Main : Form
private async void Main_FormClosing(object sender, FormClosingEventArgs e)
{
if (C_SAV.SAV.State.Edited || PKME_Tabs.PKMIsUnsaved)
try
{
var prompt = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgProgramCloseUnsaved, MsgProgramCloseConfirm);
if (prompt != DialogResult.Yes)
if (C_SAV.SAV.State.Edited || PKME_Tabs.PKMIsUnsaved)
{
e.Cancel = true;
return;
var prompt = WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgProgramCloseUnsaved, MsgProgramCloseConfirm);
if (prompt != DialogResult.Yes)
{
e.Cancel = true;
return;
}
}
}
await PKHeXSettings.SaveSettings(ConfigPath, Settings).ConfigureAwait(false);
await PKHeXSettings.SaveSettings(ConfigPath, Settings).ConfigureAwait(false);
}
catch
{
// Ignore; program is shutting down.
}
}
#endregion

View file

@ -49,6 +49,8 @@ public partial class QR : Form
private void ResizeWindow()
{
var img = PB_QR.Image;
if (img == null)
return;
splitContainer1.Height = splitContainer1.Panel1.Height + img.Height;
splitContainer1.Width = img.Width;
}
@ -76,9 +78,11 @@ public partial class QR : Form
private void PB_QR_Click(object sender, EventArgs e)
{
if (PB_QR.Image is not { } img)
return;
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgQRClipboardImage))
return;
try { Clipboard.SetImage(PB_QR.Image); }
try { Clipboard.SetImage(img); }
// Clipboard can be locked periodically, just notify on failure.
catch { WinFormsUtil.Alert(MsgQRClipboardFail); }
}

View file

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<TargetFramework>net9.0-windows</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<UseWindowsForms>true</UseWindowsForms>
<ForceDesignerDpiUnaware>true</ForceDesignerDpiUnaware>

View file

@ -32,6 +32,14 @@ internal static class Program
// Run the application
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
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.
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.
var splash = new SplashScreen();
new Task(() => splash.ShowDialog()).Start();
new Task(() => EncounterEvent.RefreshMGDB(WinForms.Main.MGDatabasePath)).Start();

View file

@ -168,15 +168,12 @@ public sealed class StartupSettings : IStartupSettings
if (!GameLanguage.IsLanguageValid(value))
{
// Migrate old language codes set in earlier versions.
switch (value)
_language = value switch
{
case "zh":
_language = "zh-Hans";
break;
case "zh2":
_language = "zh-Hant";
break;
}
"zh" => "zh-Hans",
"zh2" => "zh-Hant",
_ => _language,
};
return;
}
_language = value;

View file

@ -10,11 +10,7 @@ public partial class BoxExporter : Form
private readonly SaveFile SAV;
private readonly IFileNamer<PKM>[] Namers = [.. EntityFileNamer.AvailableNamers];
private BoxExportSettings Settings
{
get => (BoxExportSettings)PG_Settings.SelectedObject;
init => PG_Settings.SelectedObject = value;
}
private readonly BoxExportSettings Settings;
public BoxExporter(SaveFile sav, ExportOverride eo = ExportOverride.None)
{
@ -26,7 +22,7 @@ public partial class BoxExporter : Form
var settings = obj.BoxExport;
if (eo != 0)
settings = settings with { Scope = eo == ExportOverride.All ? BoxExportScope.All : BoxExportScope.Current };
Settings = settings;
PG_Settings.SelectedObject = Settings = settings;
int index = 0;
for (var i = 0; i < Namers.Length; i++)

View file

@ -224,8 +224,8 @@ public partial class MemoryAmie : Form
var strings = MemStrings;
CB_OTMemory.InitializeBinding();
CB_CTMemory.InitializeBinding();
CB_OTMemory.DataSource = new BindingSource(strings.Memory, null);
CB_CTMemory.DataSource = new BindingSource(strings.Memory, null);
CB_OTMemory.DataSource = new BindingSource(strings.Memory, string.Empty);
CB_CTMemory.DataSource = new BindingSource(strings.Memory, string.Empty);
// Quality Chooser
AddIntensity(this, strings.Species[0].Text); // None
@ -258,7 +258,7 @@ public partial class MemoryAmie : Form
var memIndex = Memories.GetMemoryArgType(memory, memoryGen);
var args = MemStrings.GetArgumentStrings(memIndex, memoryGen);
CB_OTVar.InitializeBinding();
CB_OTVar.DataSource = new BindingSource(args, null);
CB_OTVar.DataSource = new BindingSource(args, string.Empty);
LOTV.Text = TextArgs.GetMemoryCategory(memIndex, memoryGen);
LOTV.Visible = CB_OTVar.Visible = CB_OTVar.Enabled = args.Count > 1;
}
@ -269,7 +269,7 @@ public partial class MemoryAmie : Form
var memIndex = Memories.GetMemoryArgType(memory, memoryGen);
var argvals = MemStrings.GetArgumentStrings(memIndex, memoryGen);
CB_CTVar.InitializeBinding();
CB_CTVar.DataSource = new BindingSource(argvals, null);
CB_CTVar.DataSource = new BindingSource(argvals, string.Empty);
LCTV.Text = TextArgs.GetMemoryCategory(memIndex, memoryGen);
LCTV.Visible = CB_CTVar.Visible = CB_CTVar.Enabled = argvals.Count > 1;
}

View file

@ -177,7 +177,7 @@ public partial class MoveShopEditor : Form
for (int i = 0; i < dgv.Rows.Count; i++)
{
var row = dgv.Rows[i];
var index = int.Parse((string)row.Cells[ColumnIndex].Value) - Bias;
var index = int.Parse((string)row.Cells[ColumnIndex].Value!) - Bias;
var purchased = row.Cells[ColumnPurchased];
var mastered = row.Cells[ColumnMastered];
purchased.Value = Shop.GetPurchasedRecordFlag(index);
@ -190,11 +190,11 @@ public partial class MoveShopEditor : Form
for (int i = 0; i < dgv.Rows.Count; i++)
{
var row = dgv.Rows[i];
var index = int.Parse((string)row.Cells[ColumnIndex].Value) - Bias;
var index = int.Parse((string)row.Cells[ColumnIndex].Value!) - Bias;
var purchased = row.Cells[ColumnPurchased];
var mastered = row.Cells[ColumnMastered];
Shop.SetPurchasedRecordFlag(index, (bool)purchased.Value);
Master.SetMasteredRecordFlag(index, (bool)mastered.Value);
Shop.SetPurchasedRecordFlag(index, (bool)purchased.Value!);
Master.SetMasteredRecordFlag(index, (bool)mastered.Value!);
}
}

View file

@ -93,7 +93,7 @@ public partial class TechRecordEditor : Form
{
var row = dgv.Rows[i];
var index = int.Parse(row.Cells[ColumnIndex].Value?.ToString() ?? "");
Record.SetMoveRecordFlag(index, (bool)row.Cells[ColumnHasFlag].Value);
Record.SetMoveRecordFlag(index, (bool)row.Cells[ColumnHasFlag].Value!);
}
}
@ -137,7 +137,7 @@ public partial class TechRecordEditor : Form
// Toggle the checkbox of cell 0
var cell = row.Cells[ColumnHasFlag];
cell.Value = !(bool)cell.Value;
cell.Value = !(bool)cell.Value!;
}
private void PressKeyCell(object sender, KeyEventArgs e)
@ -151,7 +151,7 @@ public partial class TechRecordEditor : Form
// Toggle the checkbox of cell 0
var cell = row.Cells[ColumnHasFlag];
cell.Value = !(bool)cell.Value;
cell.Value = !(bool)cell.Value!;
}
private void SortColumn(object sender, DataGridViewCellMouseEventArgs e)

View file

@ -127,7 +127,7 @@ public partial class TrashEditor : Form
TB_Text.TextChanged += (_, _) => UpdateString(TB_Text);
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(GameInfo.SpeciesDataSource, null);
CB_Species.DataSource = new BindingSource(GameInfo.SpeciesDataSource, string.Empty);
CB_Language.InitializeBinding();
CB_Language.DataSource = GameInfo.LanguageDataSource(generation);

View file

@ -302,7 +302,7 @@ public partial class SAV_Database : Form
foreach (ComboBox cb in new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4 })
{
cb.InitializeBinding();
cb.DataSource = new BindingSource(moves, null);
cb.DataSource = new BindingSource(moves, string.Empty);
}
}
@ -594,6 +594,7 @@ public partial class SAV_Database : Form
return settings;
}
// ReSharper disable once AsyncVoidMethod
private async void B_Search_Click(object sender, EventArgs e)
{
B_Search.Enabled = false;

View file

@ -126,7 +126,7 @@ public partial class SAV_Encounters : Form
private EncounterTypeGroup[] GetTypes()
{
return TypeFilters.Controls.OfType<CheckBox>().Where(z => z.Checked).Select(z => z.Name)
.Select(z => (EncounterTypeGroup)Enum.Parse(typeof(EncounterTypeGroup), z)).ToArray();
.Select(Enum.Parse<EncounterTypeGroup>).ToArray();
}
private readonly PictureBox[] PKXBOXES;
@ -213,7 +213,7 @@ public partial class SAV_Encounters : Form
foreach (ComboBox cb in new[] { CB_Move1, CB_Move2, CB_Move3, CB_Move4 })
{
cb.InitializeBinding();
cb.DataSource = new BindingSource(DS_Move, null);
cb.DataSource = new BindingSource(DS_Move, string.Empty);
}
}
@ -386,6 +386,7 @@ public partial class SAV_Encounters : Form
return settings;
}
// ReSharper disable once AsyncVoidMethod
private async void B_Search_Click(object sender, EventArgs e)
{
B_Search.Enabled = false;

View file

@ -368,7 +368,7 @@ public partial class SAV_FolderList : Form
{
if (dg.RowCount == 0)
return;
var cm = (CurrencyManager?)BindingContext?[dg.DataSource];
var cm = (CurrencyManager?)BindingContext?[dg.DataSource!];
cm?.SuspendBinding();
int column = CB_FilterColumn.SelectedIndex - 1;
var text = TB_FilterTextContains.Text.AsSpan();

View file

@ -214,7 +214,7 @@ public partial class SAV_MysteryGiftDB : Form
foreach (var cb in arr)
{
cb.InitializeBinding();
cb.DataSource = new BindingSource(moves, null);
cb.DataSource = new BindingSource(moves, string.Empty);
}
}

View file

@ -27,7 +27,7 @@ public partial class SAV_Misc3 : Form
ReadDecorations(h);
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.ToList(), null);
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.ToList(), string.Empty);
LoadPaintings();
}
else
@ -64,7 +64,7 @@ public partial class SAV_Misc3 : Form
{
cba[i].Items.Clear();
cba[i].InitializeBinding();
cba[i].DataSource = new BindingSource(legal, null);
cba[i].DataSource = new BindingSource(legal, string.Empty);
var g3Species = SAV.GetWork(0x43 + i);
var species = SpeciesConverter.GetNational3(g3Species);
cba[i].SelectedValue = (int)species;
@ -604,7 +604,7 @@ public partial class SAV_Misc3 : Form
int ctr = 0;
for (int i = 0; i < data.Length; i++)
{
var deco = (Decoration3)(int)dgv.Rows[i].Cells[0].Value;
var deco = (Decoration3)(int)dgv.Rows[i].Cells[0].Value!;
if (deco == Decoration3.NONE) // Compression of Empty Slots
continue;

View file

@ -17,7 +17,7 @@ public partial class SAV_Roamer3 : Form
SAV = sav;
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species, null);
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species, string.Empty);
LoadData();
}

View file

@ -76,9 +76,9 @@ public partial class SAV_Geonet4 : Form
for (int i = 0; i < DGV_Geonet.Rows.Count; i++)
{
var row = DGV_Geonet.Rows[i];
var country = (int)row.Cells[0].Value;
var subregion = (int)row.Cells[2].Value;
var point = (GeonetPoint)row.Cells[4].Value;
var country = (int)row.Cells[0].Value!;
var subregion = (int)row.Cells[2].Value!;
var point = (GeonetPoint)row.Cells[4].Value!;
if (country > 0)
Geonet.SetCountrySubregion((byte)country, (byte)subregion, point);
}

View file

@ -30,7 +30,7 @@ public partial class SAV_Misc4 : Form
accessories = GameInfo.Strings.accessories;
backdrops = GameInfo.Strings.backdrops;
poketchapps = GameInfo.Strings.poketchapps;
backdropsSorted = [.. backdrops.OrderBy(z => z)]; // sorted copy
backdropsSorted = [.. backdrops.Order()]; // sorted copy
StatNUDA = [NUD_Stat0, NUD_Stat1, NUD_Stat2, NUD_Stat3];
StatLabelA = [L_Stat0, L_Stat1, L_Stat2, L_Stat3]; // Current, Trade, Record, Trade
@ -360,7 +360,7 @@ public partial class SAV_Misc4 : Form
CB_Species.InitializeBinding();
var speciesList = GameInfo.FilteredSources.Species.Skip(1).ToList();
CB_Species.DataSource = new BindingSource(speciesList, null);
CB_Species.DataSource = new BindingSource(speciesList, string.Empty);
editing = false;
CB_Stats1.SelectedIndex = 0;
@ -887,7 +887,7 @@ public partial class SAV_Misc4 : Form
DisplayIndex = 0,
Width = 190,
FlatStyle = FlatStyle.Flat,
DataSource = new BindingSource(backdropsSorted, null),
DataSource = new BindingSource(backdropsSorted, string.Empty),
};
DGV_Backdrops.Columns.Add(dgv);

View file

@ -27,7 +27,7 @@ public partial class SAV_Pokedex4 : Form
// Fill List
CB_Species.InitializeBinding();
var filtered = GameInfo.FilteredSources;
CB_Species.DataSource = new BindingSource(filtered.Species.Skip(1).ToList(), null);
CB_Species.DataSource = new BindingSource(filtered.Species.Skip(1).ToList(), string.Empty);
for (int i = 1; i < SAV.MaxSpeciesID + 1; i++)
LB_Species.Items.Add($"{i:000} - {GameInfo.Strings.specieslist[i]}");

View file

@ -42,28 +42,28 @@ public partial class SAV_Underground : Form
// Goods
DGV_UGGoods.Rows.Add(SAV4Sinnoh.UG_POUCH_SIZE);
Item_Goods.DataSource = new BindingSource(ugGoodsSorted, null);
Item_Goods.DataSource = new BindingSource(ugGoodsSorted, string.Empty);
Item_Goods.DisplayIndex = 0;
DGV_UGGoods.CancelEdit();
// Spheres
DGV_UGSpheres.Rows.Add(MAX_SIZE);
Item_Spheres.DataSource = new BindingSource(ugSpheres, null);
Item_Spheres.DataSource = new BindingSource(ugSpheres, string.Empty);
Item_Spheres.DisplayIndex = 0;
DGV_UGSpheres.CancelEdit();
// Traps
DGV_UGTraps.Rows.Add(MAX_SIZE);
Item_Traps.DataSource = new BindingSource(ugTrapsSorted, null);
Item_Traps.DataSource = new BindingSource(ugTrapsSorted, string.Empty);
Item_Traps.DisplayIndex = 0;
DGV_UGTraps.CancelEdit();
// Treasures
DGV_UGTreasures.Rows.Add(MAX_SIZE);
Item_Treasures.DataSource = new BindingSource(ugTreasuresSorted, null);
Item_Treasures.DataSource = new BindingSource(ugTreasuresSorted, string.Empty);
Item_Treasures.DisplayIndex = 0;
DGV_UGTreasures.CancelEdit();
}
@ -139,7 +139,7 @@ public partial class SAV_Underground : Form
int ctr = 0;
for (int i = 0; i < DGV_UGGoods.Rows.Count; i++)
{
var str = DGV_UGGoods.Rows[i].Cells[0].Value.ToString();
var str = DGV_UGGoods.Rows[i].Cells[0].Value!.ToString();
var itemindex = Array.IndexOf(ugGoods, str);
if (itemindex <= 0)
@ -154,7 +154,7 @@ public partial class SAV_Underground : Form
for (int i = 0; i < DGV_UGSpheres.Rows.Count; i++)
{
var row = DGV_UGSpheres.Rows[i];
var str = row.Cells[0].Value.ToString();
var str = row.Cells[0].Value!.ToString();
var itemindex = Array.IndexOf(ugSpheres, str);
bool success = int.TryParse(row.Cells[1].Value?.ToString(), out var itemcnt);
@ -170,7 +170,7 @@ public partial class SAV_Underground : Form
ctr = 0;
for (int i = 0; i < DGV_UGTraps.Rows.Count; i++)
{
var str = DGV_UGTraps.Rows[i].Cells[0].Value.ToString();
var str = DGV_UGTraps.Rows[i].Cells[0].Value!.ToString();
var itemindex = Array.IndexOf(ugTraps, str);
if (itemindex <= 0)
@ -184,7 +184,7 @@ public partial class SAV_Underground : Form
ctr = 0;
for (int i = 0; i < DGV_UGTreasures.Rows.Count; i++)
{
var str = DGV_UGTreasures.Rows[i].Cells[0].Value.ToString();
var str = DGV_UGTreasures.Rows[i].Cells[0].Value!.ToString();
var itemindex = Array.IndexOf(ugTreasures, str);
if (itemindex <= 0)

View file

@ -248,13 +248,15 @@ public partial class SAV_DLC5 : Form
private void B_ExportPNGCGear_Click(object sender, EventArgs e)
{
if (PB_CGearBackground.Image is not { } img)
return;
using var sfd = new SaveFileDialog();
sfd.Filter = "PNG File|*.png";
sfd.FileName = "Background.png";
if (sfd.ShowDialog() != DialogResult.OK)
return;
PB_CGearBackground.Image.Save(sfd.FileName, ImageFormat.Png);
img.Save(sfd.FileName, ImageFormat.Png);
}
private void B_ImportCGB_Click(object sender, EventArgs e)

View file

@ -144,7 +144,7 @@ public partial class SAV_Misc5 : Form
states.Add(new ComboItem($"Unknown (0x{c:X2})", c));
cbr[i].Items.Clear();
cbr[i].InitializeBinding();
cbr[i].DataSource = new BindingSource(states.Where(v => v.Value >= 2 || v.Value == c).ToList(), null);
cbr[i].DataSource = new BindingSource(states.Where(v => v.Value >= 2 || v.Value == c).ToList(), string.Empty);
cbr[i].SelectedValue = (int)c;
}
@ -160,7 +160,7 @@ public partial class SAV_Misc5 : Form
states.Add(new ComboItem($"Unknown (0x{current:X2})", current));
CB_RoamStatus.Items.Clear();
CB_RoamStatus.InitializeBinding();
CB_RoamStatus.DataSource = new BindingSource(states, null);
CB_RoamStatus.DataSource = new BindingSource(states, string.Empty);
CB_RoamStatus.SelectedValue = (int)current;
}
@ -307,7 +307,7 @@ public partial class SAV_Misc5 : Form
{
cb.Items.Clear();
cb.InitializeBinding();
cb.DataSource = new BindingSource(PassPowerB, null);
cb.DataSource = new BindingSource(PassPowerB, string.Empty);
}
CB_PassPower1.SelectedValue = (int)pass.PassPower1;
@ -512,9 +512,9 @@ public partial class SAV_Misc5 : Form
CB_Gender.InitializeBinding();
var filtered = GameInfo.FilteredSources;
CB_Species.DataSource = new BindingSource(filtered.Species, null);
CB_Move.DataSource = new BindingSource(filtered.Moves, null);
CB_Areas.DataSource = new BindingSource(areas, null);
CB_Species.DataSource = new BindingSource(filtered.Species, string.Empty);
CB_Move.DataSource = new BindingSource(filtered.Moves, string.Empty);
CB_Areas.DataSource = new BindingSource(areas, string.Empty);
CB_Areas.SelectedIndex = 0;
}
@ -608,7 +608,7 @@ public partial class SAV_Misc5 : Form
private void SetGenders(EntreeSlot slot)
{
CB_Gender.DataSource = new BindingSource(GetGenderChoices(slot.Species), null);
CB_Gender.DataSource = new BindingSource(GetGenderChoices(slot.Species), string.Empty);
}
private void B_RandForest_Click(object sender, EventArgs e)
@ -660,7 +660,7 @@ public partial class SAV_Misc5 : Form
L_Form.Visible = CB_Form.Enabled = CB_Form.Visible = hasForms;
var list = FormConverter.GetFormList(slot.Species, GameInfo.Strings.types, GameInfo.Strings.forms, Main.GenderSymbols, SAV.Context);
CB_Form.DataSource = new BindingSource(list, null);
CB_Form.DataSource = new BindingSource(list, string.Empty);
}
private void ReadSubway()

View file

@ -26,7 +26,7 @@ public partial class SAV_Pokedex5 : Form
// Fill List
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), null);
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), string.Empty);
for (int i = 1; i < SAV.MaxSpeciesID + 1; i++)
LB_Species.Items.Add($"{i:000} - {GameInfo.Strings.Species[i]}");

View file

@ -94,17 +94,17 @@ public partial class SAV_UnityTower : Form
for (int i = 0; i < DGV_Geonet.Rows.Count; i++)
{
var row = DGV_Geonet.Rows[i];
var country = (int)row.Cells[0].Value;
var subregion = (int)row.Cells[2].Value;
var point = (GeonetPoint)row.Cells[4].Value;
var country = (int)row.Cells[0].Value!;
var subregion = (int)row.Cells[2].Value!;
var point = (GeonetPoint)row.Cells[4].Value!;
if (country > 0)
UnityTower.SetCountrySubregion((byte)country, (byte)subregion, point);
}
for (int i = 0; i < DGV_UnityTower.Rows.Count; i++)
{
var row = DGV_UnityTower.Rows[i];
var unlocked = (bool)row.Cells[0].Value;
var country = (int)row.Cells[1].Value;
var unlocked = (bool)row.Cells[0].Value!;
var country = (int)row.Cells[1].Value!;
UnityTower.SetUnityTowerFloor((byte)country, unlocked);
}
UnityTower.SetSAVCountry();

View file

@ -42,7 +42,7 @@ public partial class SAV_HallOfFame : Form
var filtered = GameInfo.FilteredSources;
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(filtered.Species, null);
CB_Species.DataSource = new BindingSource(filtered.Species, string.Empty);
CB_Move1.InitializeBinding();
CB_Move2.InitializeBinding();
@ -50,13 +50,13 @@ public partial class SAV_HallOfFame : Form
CB_Move4.InitializeBinding();
var MoveList = filtered.Moves;
CB_Move1.DataSource = new BindingSource(MoveList, null);
CB_Move2.DataSource = new BindingSource(MoveList, null);
CB_Move3.DataSource = new BindingSource(MoveList, null);
CB_Move4.DataSource = new BindingSource(MoveList, null);
CB_Move1.DataSource = new BindingSource(MoveList, string.Empty);
CB_Move2.DataSource = new BindingSource(MoveList, string.Empty);
CB_Move3.DataSource = new BindingSource(MoveList, string.Empty);
CB_Move4.DataSource = new BindingSource(MoveList, string.Empty);
CB_HeldItem.InitializeBinding();
CB_HeldItem.DataSource = new BindingSource(filtered.Items, null);
CB_HeldItem.DataSource = new BindingSource(filtered.Items, string.Empty);
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();

View file

@ -22,7 +22,7 @@ public partial class SAV_Link6 : Form
foreach (var cb in (ComboBox[])[CB_Item1, CB_Item2, CB_Item3, CB_Item4, CB_Item5, CB_Item6])
{
cb.InitializeBinding();
cb.DataSource = new BindingSource(filtered.Items, null);
cb.DataSource = new BindingSource(filtered.Items, string.Empty);
}
Gifts = SAV.Link.Gifts;
LoadLinkData();

View file

@ -27,7 +27,7 @@ public partial class SAV_PokedexORAS : Form
// Fill List
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), null);
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), string.Empty);
for (int i = 1; i < SAV.MaxSpeciesID + 1; i++)
LB_Species.Items.Add($"{i:000} - {GameInfo.Strings.specieslist[i]}");

View file

@ -27,7 +27,7 @@ public partial class SAV_PokedexXY : Form
// Fill List
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), null);
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), string.Empty);
for (int i = 1; i < SAV.MaxSpeciesID + 1; i++)
LB_Species.Items.Add($"{i:000} - {GameInfo.Strings.specieslist[i]}");

View file

@ -73,7 +73,9 @@ public partial class SAV_Pokepuff : Form
{
if (e.ColumnIndex != 1)
return;
((ComboBox)((DataGridView)sender).EditingControl).DroppedDown = true;
if (sender is not DataGridView { EditingControl: ComboBox cb })
return;
cb.DroppedDown = true;
}
private void B_Cancel_Click(object sender, EventArgs e)

View file

@ -48,10 +48,10 @@ public partial class SAV_SecretBase : Form
CB_Form.InitializeBinding();
var filtered = GameInfo.FilteredSources;
CB_Ball.DataSource = new BindingSource(filtered.Balls, null);
CB_HeldItem.DataSource = new BindingSource(filtered.Items, null);
CB_Species.DataSource = new BindingSource(filtered.Species, null);
CB_Nature.DataSource = new BindingSource(filtered.Natures, null);
CB_Ball.DataSource = new BindingSource(filtered.Balls, string.Empty);
CB_HeldItem.DataSource = new BindingSource(filtered.Items, string.Empty);
CB_Species.DataSource = new BindingSource(filtered.Species, string.Empty);
CB_Nature.DataSource = new BindingSource(filtered.Natures, string.Empty);
CB_Move1.InitializeBinding();
CB_Move2.InitializeBinding();
@ -59,10 +59,10 @@ public partial class SAV_SecretBase : Form
CB_Move4.InitializeBinding();
var moves = filtered.Moves;
CB_Move1.DataSource = new BindingSource(moves, null);
CB_Move2.DataSource = new BindingSource(moves, null);
CB_Move3.DataSource = new BindingSource(moves, null);
CB_Move4.DataSource = new BindingSource(moves, null);
CB_Move1.DataSource = new BindingSource(moves, string.Empty);
CB_Move2.DataSource = new BindingSource(moves, string.Empty);
CB_Move3.DataSource = new BindingSource(moves, string.Empty);
CB_Move4.DataSource = new BindingSource(moves, string.Empty);
}
private void ReloadSecretBaseList()
@ -321,7 +321,7 @@ public partial class SAV_SecretBase : Form
{
var abilities = PersonalTable.AO.GetFormEntry(species, form);
var list = GameInfo.FilteredSources.GetAbilityList(abilities);
CB_Ability.DataSource = new BindingSource(list, null);
CB_Ability.DataSource = new BindingSource(list, string.Empty);
CB_Ability.SelectedIndex = abilityIndex < 3 ? abilityIndex : 0;
}
@ -332,7 +332,7 @@ public partial class SAV_SecretBase : Form
CB_Form.Enabled = CB_Form.Visible = hasForms;
var list = FormConverter.GetFormList(species, GameInfo.Strings.types, GameInfo.Strings.forms, Main.GenderSymbols, SAV.Context);
CB_Form.DataSource = new BindingSource(list, null);
CB_Form.DataSource = new BindingSource(list, string.Empty);
}
private void UpdateSpecies(object sender, EventArgs e)

View file

@ -35,10 +35,10 @@ public partial class SAV_SuperTrain : Form
dataGridView1.Columns.Clear();
{
CB_Species1.InitializeBinding();
CB_Species1.DataSource = new BindingSource(GameInfo.FilteredSources.Species, null);
CB_Species1.DataSource = new BindingSource(GameInfo.FilteredSources.Species, string.Empty);
CB_Species2.InitializeBinding();
CB_Species2.DataSource = new BindingSource(GameInfo.FilteredSources.Species, null);
CB_Species2.DataSource = new BindingSource(GameInfo.FilteredSources.Species, string.Empty);
}
listBox1.SelectedIndex = 0;
FillTrainingBags();
@ -86,8 +86,9 @@ public partial class SAV_SuperTrain : Form
{
if (e.ColumnIndex != 1)
return;
ComboBox comboBox = (ComboBox)dataGridView1.EditingControl;
comboBox.DroppedDown = true;
if (sender is not DataGridView { EditingControl: ComboBox cb })
return;
cb.DroppedDown = true;
}
catch { System.Diagnostics.Debug.WriteLine("Failed to modify item."); }
}
@ -120,7 +121,7 @@ public partial class SAV_SuperTrain : Form
int emptyslots = 0;
for (int i = 0; i < 12; i++)
{
var bag = dataGridView1.Rows[i].Cells[1].Value.ToString();
var bag = dataGridView1.Rows[i].Cells[1].Value!.ToString();
if (Array.IndexOf(trba, bag) == 0)
{
emptyslots++;

View file

@ -255,7 +255,7 @@ public partial class SAV_Trainer : Form
if (SAV is SAV6XY xy)
{
var xystat = (MyStatus6XY)xy.Status;
xystat.Fashion = (TrainerFashion6)PG_CurrentAppearance.SelectedObject;
xystat.Fashion = (TrainerFashion6)PG_CurrentAppearance.SelectedObject!;
xystat.Nickname = TB_TRNick.Text;
}

View file

@ -31,7 +31,7 @@ public partial class SAV_Capture7GG : Form
// Fill List
var species = GameInfo.FilteredSources.Species.Where(z => IsLegalSpecies(z.Value)).ToList();
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(species, null);
CB_Species.DataSource = new BindingSource(species, string.Empty);
foreach (var (text, value) in species.OrderBy(z => z.Value))
LB_Species.Items.Add($"{value:000}: {text}");

View file

@ -27,7 +27,7 @@ public partial class SAV_HallOfFame7 : Form
var cb = entries[i];
cb.Items.Clear();
cb.InitializeBinding();
cb.DataSource = new BindingSource(specList, null);
cb.DataSource = new BindingSource(specList, string.Empty);
cb.SelectedValue = (int)block.GetEntry(i);
}

View file

@ -27,7 +27,7 @@ public partial class SAV_PokedexGG : Form
// Fill List
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), null);
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), string.Empty);
Dex = SAV.Blocks.Zukan;

View file

@ -28,7 +28,7 @@ public partial class SAV_PokedexSM : Form
// Fill List
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), null);
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), string.Empty);
var Species = GameInfo.Strings.Species;
var names = Dex.GetEntryNames(Species);

View file

@ -60,7 +60,7 @@ public partial class SAV_Trainer7GG : Form
CB_Language.InitializeBinding();
CB_Language.DataSource = GameInfo.LanguageDataSource(SAV.Generation);
CB_Game.InitializeBinding();
CB_Game.DataSource = new BindingSource(GameInfo.VersionDataSource.Where(z => GameVersion.Gen7b.Contains(z.Value)).ToList(), null);
CB_Game.DataSource = new BindingSource(GameInfo.VersionDataSource.Where(z => GameVersion.Gen7b.Contains(z.Value)).ToList(), string.Empty);
}
private void LoadTrainerInfo()

View file

@ -45,7 +45,7 @@ public partial class SAV_ZygardeCell : Form
var ew = SAV.EventWork;
for (int i = 0; i < dgv.RowCount; i++)
{
string str = (string)dgv.Rows[i].Cells[2].Value;
string str = (string)dgv.Rows[i].Cells[2].Value!;
int val = Array.IndexOf(states, str);
if (val < 0)
throw new IndexOutOfRangeException("Unable to find cell index.");
@ -73,7 +73,7 @@ public partial class SAV_ZygardeCell : Form
for (int i = 0; i < dgv.RowCount; i++)
{
var state = dgv.Rows[i].Cells[2];
if (Array.IndexOf(states, (string)state.Value) != 2) // Not Collected
if (Array.IndexOf(states, (string)state.Value!) != 2) // Not Collected
added++;
state.Value = states[2];
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using PKHeX.Core;
@ -186,14 +186,14 @@ public partial class SAV_Poffin8b : Form
item.MstID = SetPoffinName(cells[1].Value?.ToString() ?? "");
item.Level = Parse(cells[2]);
item.Taste = Parse(cells[3]);
item.IsNew = (bool)cells[4].Value;
item.IsNew = (bool)cells[4].Value!;
item.FlavorSpicy = Parse(cells[5]);
item.FlavorDry = Parse(cells[6]);
item.FlavorSweet = Parse(cells[7]);
item.FlavorBitter = Parse(cells[8]);
item.FlavorSour = Parse(cells[9]);
static byte Parse(DataGridViewCell c) => (byte)(byte.TryParse(c.Value.ToString(), out var p) ? p : 0);
static byte Parse(DataGridViewCell c) => (byte)(byte.TryParse(c.Value!.ToString(), out var p) ? p : 0);
}
}

View file

@ -26,7 +26,7 @@ public partial class SAV_PokedexBDSP : Form
// Fill List
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), null);
CB_Species.DataSource = new BindingSource(GameInfo.FilteredSources.Species.Skip(1).ToList(), string.Empty);
for (int i = 1; i < SAV.MaxSpeciesID + 1; i++)
LB_Species.Items.Add($"{i:000} - {GameInfo.Strings.specieslist[i]}");

View file

@ -92,11 +92,11 @@ public partial class SAV_PokedexLA : Form
// Fill List
CB_Species.InitializeBinding();
var species = GameInfo.FilteredSources.Species.Where(z => PokedexSave8a.GetDexIndex(PokedexType8a.Hisui, (ushort)z.Value) != 0).ToArray();
CB_Species.DataSource = new BindingSource(species, null);
CB_Species.DataSource = new BindingSource(species, string.Empty);
CB_DisplayForm.InitializeBinding();
DisplayedForms = [new(GameInfo.Strings.types[0], 0)];
CB_DisplayForm.DataSource = new BindingSource(DisplayedForms, null);
CB_DisplayForm.DataSource = new BindingSource(DisplayedForms, string.Empty);
for (var d = 1; d < DexToSpecies.Length; d++)
LB_Species.Items.Add($"{d:000} - {speciesNames[DexToSpecies[d]]}");
@ -157,7 +157,7 @@ public partial class SAV_PokedexLA : Form
DisplayedForms.Clear();
DisplayedForms.Add(new ComboItem(GameInfo.Strings.types[0], 0));
CB_DisplayForm.DataSource = new BindingSource(DisplayedForms, null);
CB_DisplayForm.DataSource = new BindingSource(DisplayedForms, string.Empty);
lastForm = 0;
@ -188,7 +188,7 @@ public partial class SAV_PokedexLA : Form
DisplayedForms.Add(new ComboItem(ds[form], form));
}
CB_DisplayForm.DataSource = new BindingSource(DisplayedForms, null);
CB_DisplayForm.DataSource = new BindingSource(DisplayedForms, string.Empty);
LB_Forms.DataSource = sanitized;
LB_Forms.SelectedIndex = 0;

View file

@ -47,7 +47,7 @@ public partial class SAV_PokedexSWSH : Form
// Fill List
CB_Species.InitializeBinding();
var species = GameInfo.FilteredSources.Species.Where(z => Dex.DexLookup.ContainsKey((ushort)z.Value)).ToArray();
CB_Species.DataSource = new BindingSource(species, null);
CB_Species.DataSource = new BindingSource(species, string.Empty);
var names = Indexes.Select(z => z.GetEntryName(speciesNames) + (Dex.DexLookup[z.Species].DexType == z.Entry.DexType ? string.Empty : "***"));
foreach (var n in names)

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Linq;
@ -109,9 +109,9 @@ public partial class SAV_SealStickers8b : Form
var index = int.Parse(cells[0].Value?.ToString() ?? "0");
var item = items[index];
item.Count = int.TryParse(cells[2].Value.ToString(), out var count) ? count : 0;
item.TotalCount = int.TryParse(cells[3].Value.ToString(), out var total) ? total : 0;
item.IsGet = (bool)cells[4].Value;
item.Count = int.TryParse(cells[2].Value!.ToString(), out var count) ? count : 0;
item.TotalCount = int.TryParse(cells[3].Value!.ToString(), out var total) ? total : 0;
item.IsGet = (bool)cells[4].Value!;
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Linq;
@ -120,9 +120,9 @@ public partial class SAV_Underground8b : Form
var index = int.Parse(cells[0].Value?.ToString() ?? "0");
var item = items[index];
item.Count = int.TryParse(cells[3].Value.ToString(), out var count) ? count : 0;
item.HideNewFlag = !(bool)cells[4].Value;
item.IsFavoriteFlag = (bool)cells[5].Value;
item.Count = int.TryParse(cells[3].Value!.ToString(), out var count) ? count : 0;
item.HideNewFlag = !(bool)cells[4].Value!;
item.IsFavoriteFlag = (bool)cells[5].Value!;
}
}

View file

@ -32,7 +32,7 @@ public partial class SAV_PokedexSV : Form
const int maxSpecies = (int)Species.IronLeaves; // 1010 -- no DLC species
CB_Species.InitializeBinding();
var species = GameInfo.SpeciesDataSource.Where(z => SAV.Personal.IsSpeciesInGame((ushort)z.Value) && z.Value <= maxSpecies).ToArray();
CB_Species.DataSource = new BindingSource(species, null);
CB_Species.DataSource = new BindingSource(species, string.Empty);
var list = species
.Select(z => new DexMap(z))

View file

@ -38,7 +38,7 @@ public partial class SAV_PokedexSVKitakami : Form
// Fill List
CB_Species.InitializeBinding();
var species = GameInfo.SpeciesDataSource.Where(z => SAV.Personal.IsSpeciesInGame((ushort)z.Value)).ToArray();
CB_Species.DataSource = new BindingSource(species, null);
CB_Species.DataSource = new BindingSource(species, string.Empty);
var list = species
.Select(z => new DexMap(z))

View file

@ -409,9 +409,9 @@ public partial class SAV_Trainer9 : Form
System.Media.SystemSounds.Asterisk.Play();
}
private void P_CurrPhoto_Click(object sender, EventArgs e) => IMG_Save(P_CurrPhoto.Image, "current_photo");
private void P_CurrIcon_Click(object sender, EventArgs e) => IMG_Save(P_CurrIcon.Image, "current_icon");
private void P_InitialIcon_Click(object sender, EventArgs e) => IMG_Save(P_InitialIcon.Image, "initial_icon");
private void P_CurrPhoto_Click(object sender, EventArgs e) => IMG_Save(P_CurrPhoto.Image!, "current_photo");
private void P_CurrIcon_Click(object sender, EventArgs e) => IMG_Save(P_CurrIcon.Image!, "current_icon");
private void P_InitialIcon_Click(object sender, EventArgs e) => IMG_Save(P_InitialIcon.Image!, "initial_icon");
private void B_UnlockClothing_Click(object sender, EventArgs e)
{

View file

@ -119,7 +119,7 @@ public sealed partial class SAV_EventFlags : Form
if (e.ColumnIndex != 0 || e.RowIndex == -1)
return;
bool chk = (bool)dgv.Rows[e.RowIndex].Cells[0].Value;
bool chk = (bool)dgv.Rows[e.RowIndex].Cells[0].Value!;
var index = labels[e.RowIndex].Index;
values[index] = chk;
if (NUD_Flag.Value == index)
@ -139,7 +139,7 @@ public sealed partial class SAV_EventFlags : Form
if (e.ColumnIndex != 1)
return;
bool chk = (bool)dgv.Rows[e.RowIndex].Cells[0].Value;
bool chk = (bool)dgv.Rows[e.RowIndex].Cells[0].Value!;
dgv.Rows[e.RowIndex].Cells[0].Value = !chk;
var index = labels[e.RowIndex].Index;
values[index] = !chk;

View file

@ -119,7 +119,7 @@ public sealed partial class SAV_EventFlags2 : Form
if (e.ColumnIndex != 0 || e.RowIndex == -1)
return;
bool chk = (bool)dgv.Rows[e.RowIndex].Cells[0].Value;
bool chk = (bool)dgv.Rows[e.RowIndex].Cells[0].Value!;
var index = labels[e.RowIndex].Index;
values[index] = chk;
if (NUD_Flag.Value == index)
@ -139,7 +139,7 @@ public sealed partial class SAV_EventFlags2 : Form
if (e.ColumnIndex != 1)
return;
bool chk = (bool)dgv.Rows[e.RowIndex].Cells[0].Value;
bool chk = (bool)dgv.Rows[e.RowIndex].Cells[0].Value!;
dgv.Rows[e.RowIndex].Cells[0].Value = !chk;
var index = labels[e.RowIndex].Index;
values[index] = !chk;

View file

@ -134,7 +134,7 @@ public sealed partial class SAV_EventWork : Form
DropDownWidth = Width + 100,
};
cb.InitializeBinding();
cb.DataSource = new BindingSource(f.Options.Select(z => new ComboItem(z.Text, z.Value)).ToList(), null);
cb.DataSource = new BindingSource(f.Options.Select(z => new ComboItem(z.Text, z.Value)).ToList(), string.Empty);
cb.SelectedValue = f.Value;
if (cb.SelectedIndex < 0)
cb.SelectedIndex = 0;

Some files were not shown because too many files have changed in this diff Show more