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 @@ private static T[] Get<T>(ReadOnlySpan<byte> bin, int size, Func<byte[], T> ctor
/// 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 @@ private static bool GetNonMatch(out PIDIV pidiv)
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 bool TryMatch(ReadOnlySpan<char> message, [NotNullWhen(true)] out
/// <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 bool TryMatch(ReadOnlySpan<char> message, [NotNullWhen(true)] out
/// <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 override void Verify(LegalityAnalysis data)
// 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 override void Verify(LegalityAnalysis data)
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 @@ private static string GetSpeciesName1234(ushort species, int language, byte gene
}
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 SaveBlockMetadata(ISaveBlockAccessor<T> accessor)
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 override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, i
}
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 SAV2Stadium(bool japanese = false) : base(japanese, SaveUtil.SIZE_G2STAD)
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 ulong Seed
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 void Reset()
];
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 Mail2(SAV2Stadium sav, int index) : base(sav.Data.AsSpan(GetMailOffsetSta
};
#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 @@ private static int GetMailboxMailOffset(int index, int size)
{
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 override string GetMessage(bool isLastLine)
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 override void SetMessage(string line1, string line2, bool userEntered)
// 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 override string AuthorName
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 ulong GetHexValue64(ReadOnlySpan<char> value)
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 PKMEditor()
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 @@ internal void UpdateSprite()
}
// 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 @@ private void SetDetailsOT(ITrainerInfo tr)
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 @@ private void UpdateForm(object sender, EventArgs e)
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 @@ private void UpdateSpecies(object sender, EventArgs e)
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 @@ private void CheckMetLocationChange(GameVersion version, EntityContext context)
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 @@ private void SetMoveDataSource(ComboBox c)
{
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 @@ private bool FinalizeInterface(SaveFile sav)
{
FieldsLoaded = false;
bool TranslationRequired = false;
bool isTranslationRequired = false;
PopulateFilteredDataSources(sav);
PopulateFields(Entity);
@ -2027,7 +2027,7 @@ private bool FinalizeInterface(SaveFile sav)
{
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 @@ private bool FinalizeInterface(SaveFile sav)
{
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 @@ private bool FinalizeInterface(SaveFile sav)
// 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 void EnableDragDrop(DragEventHandler enter, DragEventHandler drop)
}
}
// 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 @@ private void InitializeLanguage(ITrainerInfo sav)
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 @@ private static void SetIfDifferentCount(IReadOnlyCollection<ComboItem> update, C
{
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 void InitializeDataSources()
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 @@ private void CHK_IsAlpha_CheckedChanged(object sender, EventArgs e)
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 @@ void TryOpen(SaveFile sav, IReadOnlyList<SlotGroup> g)
}
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 @@ private void ToggleViewMisc(SaveFile sav)
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 void TabMouseUp(object sender, MouseEventArgs e)
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.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 @@ private void HandleMovePKM(PictureBox pb, bool encrypt)
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 @@ private string CreateDragDropPKM(PictureBox pb, bool encrypt, out bool external)
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 void Dispose()
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 @@ private static (string Detail, string Encounter) GetStatsString(PKM pk, Legality
}
break;
}
sb.AppendLine(line.ToString());
sb.Append(line).AppendLine();
}
var detail = sb.ToString();
@ -182,7 +182,7 @@ private static (string Detail, string Encounter) GetStatsString(PKM pk, Legality
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 @@ private void ExportQRFromTabs()
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 @@ private void Main_DragDrop(object? sender, DragEventArgs? e)
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 @@ private void DragoutDrop(object? sender, DragEventArgs? e)
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 QR(Image qr, Image icon, PKM pk, params string[] lines)
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 @@ private void RefreshImage()
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 @@ private static void Main()
// 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 string Language
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 BoxExporter(SaveFile sav, ExportOverride eo = ExportOverride.None)
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 @@ private void GetLangStrings()
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 @@ private void UpdateMemoryDisplay(object sender)
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 @@ private void UpdateMemoryDisplay(object sender)
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 @@ private void LoadRecords()
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 @@ private void Save()
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 @@ private void Save()
{
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 @@ private void ClickCell(object sender, DataGridViewCellEventArgs e)
// 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 @@ private void PressKeyCell(object sender, KeyEventArgs e)
// 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 @@ private void AddTrashEditing(int count, byte generation)
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 @@ private void PopulateComboBoxes()
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 @@ static ushort GetU16(ListControl cb)
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 @@ private void GetTypeFilters()
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 @@ private void PopulateComboBoxes()
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 @@ static ushort GetU16(ListControl cb)
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 @@ private void GetFilterText(DataGridView dg)
{
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 @@ private void PopulateComboBoxes()
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 SAV_Misc3(SAV3 sav)
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 SAV_Misc3(SAV3 sav)
{
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 @@ private static void SaveDecorationCategory(Span<Decoration3> data, DataGridView
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 SAV_Roamer3(SAV3 sav)
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 @@ private void B_Save_Click(object sender, EventArgs e)
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 SAV_Misc4(SAV4 sav)
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 @@ private void ReadBattleFrontier()
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 @@ private void ReadBackdrops()
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 SAV_Pokedex4(SAV4 sav)
// 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 @@ private void InitializeDGV()
// 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 @@ private void SaveUGData()
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 @@ private void SaveUGData()
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 @@ private void SaveUGData()
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 @@ private void SaveUGData()
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 @@ private static bool CheckResult<T>(TiledImageStat result, [NotNullWhen(false)] o
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 @@ private void ReadMain()
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 @@ private void ReadMain()
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 @@ private void ReadEntralink()
{
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 @@ private void LoadForest()
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 @@ private void SetSprite(EntreeSlot slot)
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 @@ private void SetForms(EntreeSlot slot)
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 SAV_Pokedex5(SAV5 sav)
// 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 @@ private void B_Save_Click(object sender, EventArgs e)
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 @@ private void Setup()
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 @@ private void Setup()
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 SAV_Link6(SaveFile sav)
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 SAV_PokedexORAS(SAV6AO sav)
// 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 SAV_PokedexXY(SaveFile sav)
// 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 @@ private void DropClick(object sender, DataGridViewCellEventArgs e)
{
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 @@ private void SetupComboBoxes()
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 @@ private void SetupComboBoxes()
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 @@ private void SetAbilityList(ushort species, byte form, int abilityIndex)
{
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 @@ private void SetForms()
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 @@ private void Setup()
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 @@ private void DropClick(object sender, DataGridViewCellEventArgs e)
{
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 @@ private void B_Save_Click(object sender, EventArgs e)
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 @@ private void Save()
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 SAV_Capture7GG(SAV7b sav)
// 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 SAV_HallOfFame7(SAV7 sav)
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 SAV_PokedexGG(SAV7b sav)
// 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 SAV_PokedexSM(SAV7 sav)
// 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 @@ private void GetComboBoxes()
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 @@ private void B_Save_Click(object sender, EventArgs e)
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 @@ private void B_GiveAll_Click(object sender, EventArgs e)
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 @@ private void SaveItems(IReadOnlyList<Poffin8b> items)
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 SAV_PokedexBDSP(SAV8BS sav)
// 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 SAV_PokedexLA(SAV8LA sav)
// 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 @@ private bool FillLBForms(int index)
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 @@ private bool FillLBForms(int index)
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 SAV_PokedexSWSH(SAV8SWSH sav)
// 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 @@ private void SaveItems(IReadOnlyList<SealSticker8b> items)
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 @@ private void SaveItems(IReadOnlyList<UndergroundItem8b> items)
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 SAV_PokedexSV(SAV9SV sav)
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 SAV_PokedexSVKitakami(SAV9SV sav)
// 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 @@ private static void IMG_Save(Image image, string name)
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 @@ private void AddFlagList(EventLabelCollection list, bool[] values)
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 @@ private void AddFlagList(EventLabelCollection list, bool[] values)
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 @@ private void AddFlagList(EventLabelCollection list, bool[] values)
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 @@ private void AddFlagList(EventLabelCollection list, bool[] values)
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 @@ private void LoadWork(IEnumerable<EventVarGroup> editorWork)
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