diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 000000000..f640b535c
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,45 @@
+root = true
+
+# All Files
+[*]
+charset = utf-8
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+# Solution Files
+[*.sln]
+indent_style = space
+indent_size = 4
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+# XML Project Files
+[*.csproj]
+indent_style = space
+indent_size = 2
+
+# Code Files
+[*.cs]
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_style = space
+indent_size = 4
+tab_width = 4
+end_of_line = crlf
+csharp_prefer_braces = when_multiline:warning
+dotnet_diagnostic.IDE0047.severity = none
+dotnet_diagnostic.IDE0048.severity = none
+dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggest
+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
+
+[*.{cs,vb}]
+#### Naming styles ####
+
+# Naming styles
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
diff --git a/PKHeX.Core/Editing/Applicators/BallApplicator.cs b/PKHeX.Core/Editing/Applicators/BallApplicator.cs
index 9a7d75f7e..fcedf685b 100644
--- a/PKHeX.Core/Editing/Applicators/BallApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/BallApplicator.cs
@@ -3,160 +3,159 @@
using System.Linq;
using static PKHeX.Core.Ball;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Contains logic to apply a new value to a .
+///
+public static class BallApplicator
{
///
- /// Contains logic to apply a new value to a .
+ /// Gets all balls that are legal for the input .
///
- public static class BallApplicator
+ ///
+ /// Requires checking the for every that is tried.
+ ///
+ /// Pokémon to retrieve a list of valid balls for.
+ /// Enumerable list of values that the is legal with.
+ public static IEnumerable GetLegalBalls(PKM pk)
{
- ///
- /// Gets all balls that are legal for the input .
- ///
- ///
- /// Requires checking the for every that is tried.
- ///
- /// Pokémon to retrieve a list of valid balls for.
- /// Enumerable list of values that the is legal with.
- public static IEnumerable GetLegalBalls(PKM pkm)
+ var clone = pk.Clone();
+ foreach (var b in BallList)
{
- var clone = pkm.Clone();
- foreach (var b in BallList)
- {
- clone.Ball = (int)b;
- if (new LegalityAnalysis(clone).Valid)
- yield return b;
- }
- }
-
- ///
- /// Applies a random legal ball value if any exist.
- ///
- ///
- /// Requires checking the for every that is tried.
- ///
- /// Pokémon to modify.
- public static int ApplyBallLegalRandom(PKM pkm)
- {
- var balls = GetBallListFromColor(pkm).ToArray();
- Util.Shuffle(balls.AsSpan());
- return ApplyFirstLegalBall(pkm, balls);
- }
-
- ///
- /// Applies a legal ball value if any exist, ordered by color.
- ///
- ///
- /// Requires checking the for every that is tried.
- ///
- /// Pokémon to modify.
- public static int ApplyBallLegalByColor(PKM pkm)
- {
- var balls = GetBallListFromColor(pkm);
- return ApplyFirstLegalBall(pkm, balls);
- }
-
- ///
- /// Applies a random ball value in a cyclical manner.
- ///
- /// Pokémon to modify.
- public static int ApplyBallNext(PKM pkm)
- {
- var balls = GetBallList(pkm.Ball);
- var next = balls.First();
- return pkm.Ball = (int)next;
- }
-
- private static int ApplyFirstLegalBall(PKM pkm, IEnumerable balls)
- {
- foreach (var b in balls)
- {
- pkm.Ball = (int)b;
- if (new LegalityAnalysis(pkm).Valid)
- break;
- }
- return pkm.Ball;
- }
-
- private static IEnumerable GetBallList(int ball)
- {
- var balls = BallList;
- var currentBall = (Ball)ball;
- return GetCircularOnce(balls, currentBall);
- }
-
- private static IEnumerable GetBallListFromColor(PKM pkm)
- {
- // Gen1/2 don't store color in personal info
- var pi = pkm.Format >= 3 ? pkm.PersonalInfo : PersonalTable.USUM.GetFormEntry(pkm.Species, 0);
- var color = (PersonalColor)pi.Color;
- var balls = BallColors[color];
- var currentBall = (Ball)pkm.Ball;
- return GetCircularOnce(balls, currentBall);
- }
-
- private static IEnumerable GetCircularOnce(T[] items, T current)
- {
- var currentIndex = Array.IndexOf(items, current);
- if (currentIndex < 0)
- currentIndex = items.Length - 2;
- for (int i = currentIndex + 1; i < items.Length; i++)
- yield return items[i];
- for (int i = 0; i <= currentIndex; i++)
- yield return items[i];
- }
-
- private static readonly Ball[] BallList = (Ball[]) Enum.GetValues(typeof(Ball));
-
- static BallApplicator()
- {
- var exclude = new[] {None, Poke};
- var end = new[] {Poke};
- var allBalls = BallList.Except(exclude).ToArray();
- var colors = (PersonalColor[])Enum.GetValues(typeof(PersonalColor));
- foreach (var c in colors)
- {
- var matchingColors = BallColors[c];
- var extra = allBalls.Except(matchingColors).ToArray();
- Util.Shuffle(extra.AsSpan());
- BallColors[c] = ArrayUtil.ConcatAll(matchingColors, extra, end);
- }
- }
-
- ///
- /// Priority Match ball IDs that match the color ID in descending order
- ///
- private static readonly Dictionary BallColors = new()
- {
- [PersonalColor.Red] = new[] { Cherish, Repeat, Fast, Heal, Great, Dream, Lure },
- [PersonalColor.Blue] = new[] { Dive, Net, Great, Beast, Lure },
- [PersonalColor.Yellow] = new[] { Level, Ultra, Repeat, Quick, Moon },
- [PersonalColor.Green] = new[] { Safari, Friend, Nest, Dusk },
- [PersonalColor.Black] = new[] { Luxury, Heavy, Ultra, Moon, Net, Beast },
-
- [PersonalColor.Brown] = new[] { Level, Heavy },
- [PersonalColor.Purple] = new[] { Master, Love, Dream, Heal },
- [PersonalColor.Gray] = new[] { Heavy, Premier, Luxury },
- [PersonalColor.White] = new[] { Premier, Timer, Luxury, Ultra },
- [PersonalColor.Pink] = new[] { Love, Dream, Heal },
- };
-
- ///
- /// Personal Data color IDs
- ///
- private enum PersonalColor : byte
- {
- Red,
- Blue,
- Yellow,
- Green,
- Black,
-
- Brown,
- Purple,
- Gray,
- White,
- Pink,
+ clone.Ball = (int)b;
+ if (new LegalityAnalysis(clone).Valid)
+ yield return b;
}
}
+
+ ///
+ /// Applies a random legal ball value if any exist.
+ ///
+ ///
+ /// Requires checking the for every that is tried.
+ ///
+ /// Pokémon to modify.
+ public static int ApplyBallLegalRandom(PKM pk)
+ {
+ var balls = GetBallListFromColor(pk).ToArray();
+ Util.Shuffle(balls.AsSpan());
+ return ApplyFirstLegalBall(pk, balls);
+ }
+
+ ///
+ /// Applies a legal ball value if any exist, ordered by color.
+ ///
+ ///
+ /// Requires checking the for every that is tried.
+ ///
+ /// Pokémon to modify.
+ public static int ApplyBallLegalByColor(PKM pk)
+ {
+ var balls = GetBallListFromColor(pk);
+ return ApplyFirstLegalBall(pk, balls);
+ }
+
+ ///
+ /// Applies a random ball value in a cyclical manner.
+ ///
+ /// Pokémon to modify.
+ public static int ApplyBallNext(PKM pk)
+ {
+ var balls = GetBallList(pk.Ball);
+ var next = balls.First();
+ return pk.Ball = (int)next;
+ }
+
+ private static int ApplyFirstLegalBall(PKM pk, IEnumerable balls)
+ {
+ foreach (var b in balls)
+ {
+ pk.Ball = (int)b;
+ if (new LegalityAnalysis(pk).Valid)
+ break;
+ }
+ return pk.Ball;
+ }
+
+ private static IEnumerable GetBallList(int ball)
+ {
+ var balls = BallList;
+ var currentBall = (Ball)ball;
+ return GetCircularOnce(balls, currentBall);
+ }
+
+ private static IEnumerable GetBallListFromColor(PKM pk)
+ {
+ // Gen1/2 don't store color in personal info
+ var pi = pk.Format >= 3 ? pk.PersonalInfo : PersonalTable.USUM.GetFormEntry(pk.Species, 0);
+ var color = (PersonalColor)pi.Color;
+ var balls = BallColors[color];
+ var currentBall = (Ball)pk.Ball;
+ return GetCircularOnce(balls, currentBall);
+ }
+
+ private static IEnumerable GetCircularOnce(T[] items, T current)
+ {
+ var currentIndex = Array.IndexOf(items, current);
+ if (currentIndex < 0)
+ currentIndex = items.Length - 2;
+ for (int i = currentIndex + 1; i < items.Length; i++)
+ yield return items[i];
+ for (int i = 0; i <= currentIndex; i++)
+ yield return items[i];
+ }
+
+ private static readonly Ball[] BallList = (Ball[]) Enum.GetValues(typeof(Ball));
+
+ static BallApplicator()
+ {
+ var exclude = new[] {None, Poke};
+ var end = new[] {Poke};
+ var allBalls = BallList.Except(exclude).ToArray();
+ var colors = (PersonalColor[])Enum.GetValues(typeof(PersonalColor));
+ foreach (var c in colors)
+ {
+ var matchingColors = BallColors[c];
+ var extra = allBalls.Except(matchingColors).ToArray();
+ Util.Shuffle(extra.AsSpan());
+ BallColors[c] = ArrayUtil.ConcatAll(matchingColors, extra, end);
+ }
+ }
+
+ ///
+ /// Priority Match ball IDs that match the color ID in descending order
+ ///
+ private static readonly Dictionary BallColors = new()
+ {
+ [PersonalColor.Red] = new[] { Cherish, Repeat, Fast, Heal, Great, Dream, Lure },
+ [PersonalColor.Blue] = new[] { Dive, Net, Great, Beast, Lure },
+ [PersonalColor.Yellow] = new[] { Level, Ultra, Repeat, Quick, Moon },
+ [PersonalColor.Green] = new[] { Safari, Friend, Nest, Dusk },
+ [PersonalColor.Black] = new[] { Luxury, Heavy, Ultra, Moon, Net, Beast },
+
+ [PersonalColor.Brown] = new[] { Level, Heavy },
+ [PersonalColor.Purple] = new[] { Master, Love, Dream, Heal },
+ [PersonalColor.Gray] = new[] { Heavy, Premier, Luxury },
+ [PersonalColor.White] = new[] { Premier, Timer, Luxury, Ultra },
+ [PersonalColor.Pink] = new[] { Love, Dream, Heal },
+ };
+
+ ///
+ /// Personal Data color IDs
+ ///
+ private enum PersonalColor : byte
+ {
+ Red,
+ Blue,
+ Yellow,
+ Green,
+ Black,
+
+ Brown,
+ Purple,
+ Gray,
+ White,
+ Pink,
+ }
}
diff --git a/PKHeX.Core/Editing/Applicators/CatchRateApplicator.cs b/PKHeX.Core/Editing/Applicators/CatchRateApplicator.cs
index 48b570af9..8a4554355 100644
--- a/PKHeX.Core/Editing/Applicators/CatchRateApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/CatchRateApplicator.cs
@@ -1,39 +1,38 @@
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Logic for applying a value.
+///
+public static class CatchRateApplicator
{
- ///
- /// Logic for applying a value.
- ///
- public static class CatchRateApplicator
+ public static int GetSuggestedCatchRate(PK1 pk1, SaveFile sav)
{
- public static int GetSuggestedCatchRate(PK1 pk1, SaveFile sav)
+ var la = new LegalityAnalysis(pk1);
+ return GetSuggestedCatchRate(pk1, sav, la);
+ }
+
+ public static int GetSuggestedCatchRate(PK1 pk1, SaveFile sav, LegalityAnalysis la)
+ {
+ if (la.Valid)
+ return pk1.Catch_Rate;
+
+ if (la.Info.Generation == 2)
+ return 0;
+
+ var v = la.EncounterMatch;
+ switch (v)
{
- var la = new LegalityAnalysis(pk1);
- return GetSuggestedCatchRate(pk1, sav, la);
- }
-
- public static int GetSuggestedCatchRate(PK1 pk1, SaveFile sav, LegalityAnalysis la)
- {
- if (la.Valid)
- return pk1.Catch_Rate;
-
- if (la.Info.Generation == 2)
- return 0;
-
- var v = la.EncounterMatch;
- switch (v)
+ case EncounterTrade1 c:
+ return c.GetInitialCatchRate();
+ case EncounterStatic1E { Version: GameVersion.Stadium, Species: (int)Species.Psyduck}:
+ return pk1.Japanese ? 167 : 168; // Amnesia Psyduck has different catch rates depending on language
+ default:
{
- case EncounterTrade1 c:
- return c.GetInitialCatchRate();
- case EncounterStatic1E { Version: GameVersion.Stadium, Species: (int)Species.Psyduck}:
- return pk1.Japanese ? 167 : 168; // Amnesia Psyduck has different catch rates depending on language
- default:
- {
- if (sav.Version.Contains(v.Version) || v.Version.Contains(sav.Version))
- return sav.Personal[v.Species].CatchRate;
- if (!GameVersion.RB.Contains(v.Version))
- return PersonalTable.Y[v.Species].CatchRate;
- return PersonalTable.RB[v.Species].CatchRate;
- }
+ if (sav.Version.Contains(v.Version) || v.Version.Contains(sav.Version))
+ return sav.Personal[v.Species].CatchRate;
+ if (!GameVersion.RB.Contains(v.Version))
+ return PersonalTable.Y[v.Species].CatchRate;
+ return PersonalTable.RB[v.Species].CatchRate;
}
}
}
diff --git a/PKHeX.Core/Editing/Applicators/GenderApplicator.cs b/PKHeX.Core/Editing/Applicators/GenderApplicator.cs
index 4ce8920c6..5ed2c0f3a 100644
--- a/PKHeX.Core/Editing/Applicators/GenderApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/GenderApplicator.cs
@@ -1,76 +1,75 @@
using System;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+public static class GenderApplicator
{
- public static class GenderApplicator
+ ///
+ /// Sets the value, with special consideration for the values which derive the value.
+ ///
+ /// Pokémon to modify.
+ /// Desired value to set.
+ /// Has special logic for an unspecified gender.
+ public static void SetSaneGender(this PKM pk, int gender)
{
- ///
- /// Sets the value, with special consideration for the values which derive the value.
- ///
- /// Pokémon to modify.
- /// Desired value to set.
- /// Has special logic for an unspecified gender.
- public static void SetSaneGender(this PKM pk, int gender)
+ int g = gender == -1 ? pk.GetSaneGender() : gender;
+ pk.SetGender(g);
+ }
+
+ ///
+ /// Sets the value, with special consideration for the values which derive the value.
+ ///
+ /// Pokémon to modify.
+ /// Desired value to set.
+ public static void SetGender(this PKM pk, int gender)
+ {
+ gender = Math.Min(2, Math.Max(0, gender));
+ if (pk.Gender == gender)
+ return;
+
+ if (pk.Format <= 2)
{
- int g = gender == -1 ? pk.GetSaneGender() : gender;
- pk.SetGender(g);
+ pk.SetAttackIVFromGender(gender);
}
-
- ///
- /// Sets the value, with special consideration for the values which derive the value.
- ///
- /// Pokémon to modify.
- /// Desired value to set.
- public static void SetGender(this PKM pk, int gender)
+ else if (pk.Format <= 5)
{
- gender = Math.Min(2, Math.Max(0, gender));
- if (pk.Gender == gender)
- return;
-
- if (pk.Format <= 2)
- {
- pk.SetAttackIVFromGender(gender);
- }
- else if (pk.Format <= 5)
- {
- pk.SetPIDGender(gender);
- pk.Gender = gender;
- }
- else
- {
- pk.Gender = gender;
- }
+ pk.SetPIDGender(gender);
+ pk.Gender = gender;
}
-
- ///
- /// Sanity checks the provided value, and returns a sane value.
- ///
- ///
- /// Most-legal value
- public static int GetSaneGender(this PKM pk)
+ else
{
- int gt = pk.PersonalInfo.Gender;
- switch (gt)
- {
- case PersonalInfo.RatioMagicGenderless: return 2;
- case PersonalInfo.RatioMagicFemale: return 1;
- case PersonalInfo.RatioMagicMale: return 0;
- }
- if (!pk.IsGenderValid())
- return EntityGender.GetFromPIDAndRatio(pk.PID, gt);
- return pk.Gender;
- }
-
- ///
- /// Updates the for a Generation 1/2 format .
- ///
- /// Pokémon to modify.
- /// Desired .
- public static void SetAttackIVFromGender(this PKM pk, int gender)
- {
- var rnd = Util.Rand;
- while (pk.Gender != gender)
- pk.IV_ATK = rnd.Next(16);
+ pk.Gender = gender;
}
}
+
+ ///
+ /// Sanity checks the provided value, and returns a sane value.
+ ///
+ ///
+ /// Most-legal value
+ public static int GetSaneGender(this PKM pk)
+ {
+ int gt = pk.PersonalInfo.Gender;
+ switch (gt)
+ {
+ case PersonalInfo.RatioMagicGenderless: return 2;
+ case PersonalInfo.RatioMagicFemale: return 1;
+ case PersonalInfo.RatioMagicMale: return 0;
+ }
+ if (!pk.IsGenderValid())
+ return EntityGender.GetFromPIDAndRatio(pk.PID, gt);
+ return pk.Gender;
+ }
+
+ ///
+ /// Updates the for a Generation 1/2 format .
+ ///
+ /// Pokémon to modify.
+ /// Desired .
+ public static void SetAttackIVFromGender(this PKM pk, int gender)
+ {
+ var rnd = Util.Rand;
+ while (pk.Gender != gender)
+ pk.IV_ATK = rnd.Next(16);
+ }
}
diff --git a/PKHeX.Core/Editing/Applicators/HiddenPowerApplicator.cs b/PKHeX.Core/Editing/Applicators/HiddenPowerApplicator.cs
index a309676a1..f18bada92 100644
--- a/PKHeX.Core/Editing/Applicators/HiddenPowerApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/HiddenPowerApplicator.cs
@@ -1,27 +1,26 @@
using System;
-namespace PKHeX.Core
-{
- public static class HiddenPowerApplicator
- {
- ///
- /// Sets the to match a provided .
- ///
- /// Pokémon to modify.
- /// Desired Hidden Power typing.
- public static void SetHiddenPower(this PKM pk, int hiddenPowerType)
- {
- Span IVs = stackalloc int[6];
- pk.GetIVs(IVs);
- HiddenPower.SetIVsForType(hiddenPowerType, IVs, pk.Format);
- pk.SetIVs(IVs);
- }
+namespace PKHeX.Core;
- ///
- /// Sets the to match a provided .
- ///
- /// Pokémon to modify.
- /// Desired Hidden Power typing.
- public static void SetHiddenPower(this PKM pk, MoveType hiddenPowerType) => pk.SetHiddenPower((int)hiddenPowerType);
+public static class HiddenPowerApplicator
+{
+ ///
+ /// Sets the to match a provided .
+ ///
+ /// Pokémon to modify.
+ /// Desired Hidden Power typing.
+ public static void SetHiddenPower(this PKM pk, int hiddenPowerType)
+ {
+ Span IVs = stackalloc int[6];
+ pk.GetIVs(IVs);
+ HiddenPower.SetIVsForType(hiddenPowerType, IVs, pk.Format);
+ pk.SetIVs(IVs);
}
+
+ ///
+ /// Sets the to match a provided .
+ ///
+ /// Pokémon to modify.
+ /// Desired Hidden Power typing.
+ public static void SetHiddenPower(this PKM pk, MoveType hiddenPowerType) => pk.SetHiddenPower((int)hiddenPowerType);
}
diff --git a/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs b/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs
index 80ca5cf88..cf73b9ffa 100644
--- a/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/MarkingApplicator.cs
@@ -1,69 +1,68 @@
using System;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Logic for modifying the .
+///
+public static class MarkingApplicator
{
///
- /// Logic for modifying the .
+ /// Default when applying markings.
///
- public static class MarkingApplicator
+ // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global
+ public static Func> MarkingMethod { get; set; } = FlagHighLow;
+
+ ///
+ /// Sets the to indicate flawless (or near-flawless) .
+ ///
+ /// Pokémon to modify.
+ public static void SetMarkings(this PKM pk)
{
- ///
- /// Default when applying markings.
- ///
- // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global
- public static Func> MarkingMethod { get; set; } = FlagHighLow;
+ if (pk.MarkingCount < 6)
+ return; // insufficient marking indexes
- ///
- /// Sets the to indicate flawless (or near-flawless) .
- ///
- /// Pokémon to modify.
- public static void SetMarkings(this PKM pk)
+ var method = MarkingMethod(pk);
+ pk.SetMarking(0, method(pk.IV_HP , 0));
+ pk.SetMarking(1, method(pk.IV_ATK, 1));
+ pk.SetMarking(2, method(pk.IV_DEF, 2));
+ pk.SetMarking(3, method(pk.IV_SPA, 3));
+ pk.SetMarking(4, method(pk.IV_SPD, 4));
+ pk.SetMarking(5, method(pk.IV_SPE, 5));
+ }
+
+ ///
+ /// Toggles the marking at a given index.
+ ///
+ /// Pokémon to modify.
+ /// Marking index to toggle
+ /// Current marking value
+ public static int ToggleMarking(this PKM pk, int index)
+ {
+ var marking = pk.GetMarking(index);
+ var revised = NextMarking(pk.Format, marking);
+ pk.SetMarking(index, revised);
+ return revised;
+ }
+
+ private static int NextMarking(int format, int marking) => format switch
+ {
+ <= 6 => marking ^ 1, // toggle : 0 (off) | 1 (on)
+ _ => (marking + 1) % 3, // cycle 0->1->2->0... : 0 (none) | 1 (blue) | 2 (pink)
+ };
+
+ private static Func FlagHighLow(PKM pk)
+ {
+ if (pk.Format < 7)
+ return GetSimpleMarking;
+ return GetComplexMarking;
+
+ static int GetSimpleMarking(int val, int _) => val == 31 ? 1 : 0;
+ static int GetComplexMarking(int val, int _) => val switch
{
- if (pk.MarkingCount < 6)
- return; // insufficient marking indexes
-
- var method = MarkingMethod(pk);
- pk.SetMarking(0, method(pk.IV_HP , 0));
- pk.SetMarking(1, method(pk.IV_ATK, 1));
- pk.SetMarking(2, method(pk.IV_DEF, 2));
- pk.SetMarking(3, method(pk.IV_SPA, 3));
- pk.SetMarking(4, method(pk.IV_SPD, 4));
- pk.SetMarking(5, method(pk.IV_SPE, 5));
- }
-
- ///
- /// Toggles the marking at a given index.
- ///
- /// Pokémon to modify.
- /// Marking index to toggle
- /// Current marking value
- public static int ToggleMarking(this PKM pk, int index)
- {
- var marking = pk.GetMarking(index);
- var revised = NextMarking(pk.Format, marking);
- pk.SetMarking(index, revised);
- return revised;
- }
-
- private static int NextMarking(int format, int marking) => format switch
- {
- <= 6 => marking ^ 1, // toggle : 0 (off) | 1 (on)
- _ => (marking + 1) % 3, // cycle 0->1->2->0... : 0 (none) | 1 (blue) | 2 (pink)
+ 31 or 1 => 1,
+ 30 or 0 => 2,
+ _ => 0,
};
-
- private static Func FlagHighLow(PKM pk)
- {
- if (pk.Format < 7)
- return GetSimpleMarking;
- return GetComplexMarking;
-
- static int GetSimpleMarking(int val, int _) => val == 31 ? 1 : 0;
- static int GetComplexMarking(int val, int _) => val switch
- {
- 31 or 1 => 1,
- 30 or 0 => 2,
- _ => 0,
- };
- }
}
}
diff --git a/PKHeX.Core/Editing/Applicators/MemoryApplicator.cs b/PKHeX.Core/Editing/Applicators/MemoryApplicator.cs
index c4ea24d80..1cfedaecf 100644
--- a/PKHeX.Core/Editing/Applicators/MemoryApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/MemoryApplicator.cs
@@ -1,51 +1,50 @@
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Logic for modifying the Memory parameters of a .
+///
+public static class MemoryApplicator
{
///
- /// Logic for modifying the Memory parameters of a .
+ /// Sets all Memory related data to the default value (zero).
///
- public static class MemoryApplicator
+ /// Pokémon to modify.
+ public static void ClearMemories(this PKM pk)
{
- ///
- /// Sets all Memory related data to the default value (zero).
- ///
- /// Pokémon to modify.
- public static void ClearMemories(this PKM pk)
- {
- if (pk is IAffection a)
- a.OT_Affection = a.HT_Affection = 0;
- if (pk is IMemoryOT o)
- o.ClearMemoriesOT();
- if (pk is IMemoryHT h)
- h.ClearMemoriesHT();
- }
+ if (pk is IAffection a)
+ a.OT_Affection = a.HT_Affection = 0;
+ if (pk is IMemoryOT o)
+ o.ClearMemoriesOT();
+ if (pk is IMemoryHT h)
+ h.ClearMemoriesHT();
+ }
- ///
- /// Sets the Memory details to a Hatched Egg's memories.
- ///
- /// Pokémon to modify.
- public static void SetHatchMemory6(this PKM pk)
+ ///
+ /// Sets the Memory details to a Hatched Egg's memories.
+ ///
+ /// Pokémon to modify.
+ public static void SetHatchMemory6(this PKM pk)
+ {
+ if (pk is IMemoryOT o)
{
- if (pk is IMemoryOT o)
- {
- o.OT_Memory = 2;
- o.OT_Feeling = MemoryContext6.GetRandomFeeling6(2);
- o.OT_Intensity = 1;
- o.OT_TextVar = pk.XY ? (ushort)43 : (ushort)27; // riverside road : battling spot
- }
- if (pk is IAffection a)
- a.OT_Affection = 0;
+ o.OT_Memory = 2;
+ o.OT_Feeling = MemoryContext6.GetRandomFeeling6(2);
+ o.OT_Intensity = 1;
+ o.OT_TextVar = pk.XY ? (ushort)43 : (ushort)27; // riverside road : battling spot
}
+ if (pk is IAffection a)
+ a.OT_Affection = 0;
+ }
- ///
- /// Sets a random memory specific to locality.
- ///
- /// Pokémon to modify.
- public static void SetRandomMemory6(this PK6 pk)
- {
- // for lack of better randomization :)
- pk.OT_Memory = 63;
- pk.OT_Intensity = 6;
- pk.OT_Feeling = MemoryContext6.GetRandomFeeling6(pk.OT_Memory);
- }
+ ///
+ /// Sets a random memory specific to locality.
+ ///
+ /// Pokémon to modify.
+ public static void SetRandomMemory6(this PK6 pk)
+ {
+ // for lack of better randomization :)
+ pk.OT_Memory = 63;
+ pk.OT_Intensity = 6;
+ pk.OT_Feeling = MemoryContext6.GetRandomFeeling6(pk.OT_Memory);
}
}
diff --git a/PKHeX.Core/Editing/Applicators/MoveApplicator.cs b/PKHeX.Core/Editing/Applicators/MoveApplicator.cs
index 2115b21b1..81da670b0 100644
--- a/PKHeX.Core/Editing/Applicators/MoveApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/MoveApplicator.cs
@@ -1,79 +1,78 @@
using System;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Logic for applying a moveset to a .
+///
+public static class MoveApplicator
{
///
- /// Logic for applying a moveset to a .
+ /// Sets the individual PP Up count values depending if a Move is present in the move's slot or not.
///
- public static class MoveApplicator
+ /// Pokémon to modify.
+ /// to use (if already known). Will fetch the current if not provided.
+ public static void SetMaximumPPUps(this PKM pk, int[] moves)
{
- ///
- /// Sets the individual PP Up count values depending if a Move is present in the move's slot or not.
- ///
- /// Pokémon to modify.
- /// to use (if already known). Will fetch the current if not provided.
- public static void SetMaximumPPUps(this PKM pk, int[] moves)
- {
- pk.Move1_PPUps = GetPPUpCount(moves[0]);
- pk.Move2_PPUps = GetPPUpCount(moves[1]);
- pk.Move3_PPUps = GetPPUpCount(moves[2]);
- pk.Move4_PPUps = GetPPUpCount(moves[3]);
+ pk.Move1_PPUps = GetPPUpCount(moves[0]);
+ pk.Move2_PPUps = GetPPUpCount(moves[1]);
+ pk.Move3_PPUps = GetPPUpCount(moves[2]);
+ pk.Move4_PPUps = GetPPUpCount(moves[3]);
- pk.SetMaximumPPCurrent(moves);
- static int GetPPUpCount(int moveID) => moveID > 0 ? 3 : 0;
- }
-
- ///
- /// Sets the individual PP Up count values depending if a Move is present in the move slot or not.
- ///
- /// Pokémon to modify.
- public static void SetMaximumPPUps(this PKM pk) => pk.SetMaximumPPUps(pk.Moves);
-
- ///
- /// Updates the and updates the current PP counts.
- ///
- /// Pokémon to modify.
- /// to set. Will be resized if 4 entries are not present.
- /// Option to maximize PP Ups
- public static void SetMoves(this PKM pk, int[] moves, bool maxPP = false)
- {
- if (Array.FindIndex(moves, z => z > pk.MaxMoveID) != -1)
- moves = Array.FindAll(moves, z => z <= pk.MaxMoveID);
- if (moves.Length != 4)
- Array.Resize(ref moves, 4);
-
- pk.Moves = moves;
- if (maxPP && Legal.IsPPUpAvailable(pk))
- pk.SetMaximumPPUps(moves);
- else
- pk.SetMaximumPPCurrent(moves);
- pk.FixMoves();
- }
-
- ///
- /// Updates the individual PP count values for each move slot based on the maximum possible value.
- ///
- /// Pokémon to modify.
- /// to use (if already known). Will fetch the current if not provided.
- public static void SetMaximumPPCurrent(this PKM pk, ReadOnlySpan moves)
- {
- pk.Move1_PP = moves.Length == 0 ? 0 : pk.GetMovePP(moves[0], pk.Move1_PPUps);
- pk.Move2_PP = moves.Length <= 1 ? 0 : pk.GetMovePP(moves[1], pk.Move2_PPUps);
- pk.Move3_PP = moves.Length <= 2 ? 0 : pk.GetMovePP(moves[2], pk.Move3_PPUps);
- pk.Move4_PP = moves.Length <= 3 ? 0 : pk.GetMovePP(moves[3], pk.Move4_PPUps);
- }
-
- ///
- /// Updates the individual PP count values for each move slot based on the maximum possible value.
- ///
- /// Pokémon to modify.
- public static void SetMaximumPPCurrent(this PKM pk) => pk.SetMaximumPPCurrent(pk.Moves);
-
- ///
- /// Refreshes the Move PP for the desired move.
- ///
- /// Pokémon to modify.
- /// Move PP to refresh.
- public static void SetSuggestedMovePP(this PKM pk, int index) => pk.HealPPIndex(index);
+ pk.SetMaximumPPCurrent(moves);
+ static int GetPPUpCount(int moveID) => moveID > 0 ? 3 : 0;
}
+
+ ///
+ /// Sets the individual PP Up count values depending if a Move is present in the move slot or not.
+ ///
+ /// Pokémon to modify.
+ public static void SetMaximumPPUps(this PKM pk) => pk.SetMaximumPPUps(pk.Moves);
+
+ ///
+ /// Updates the and updates the current PP counts.
+ ///
+ /// Pokémon to modify.
+ /// to set. Will be resized if 4 entries are not present.
+ /// Option to maximize PP Ups
+ public static void SetMoves(this PKM pk, int[] moves, bool maxPP = false)
+ {
+ if (Array.FindIndex(moves, z => z > pk.MaxMoveID) != -1)
+ moves = Array.FindAll(moves, z => z <= pk.MaxMoveID);
+ if (moves.Length != 4)
+ Array.Resize(ref moves, 4);
+
+ pk.Moves = moves;
+ if (maxPP && Legal.IsPPUpAvailable(pk))
+ pk.SetMaximumPPUps(moves);
+ else
+ pk.SetMaximumPPCurrent(moves);
+ pk.FixMoves();
+ }
+
+ ///
+ /// Updates the individual PP count values for each move slot based on the maximum possible value.
+ ///
+ /// Pokémon to modify.
+ /// to use (if already known). Will fetch the current if not provided.
+ public static void SetMaximumPPCurrent(this PKM pk, ReadOnlySpan moves)
+ {
+ pk.Move1_PP = moves.Length == 0 ? 0 : pk.GetMovePP(moves[0], pk.Move1_PPUps);
+ pk.Move2_PP = moves.Length <= 1 ? 0 : pk.GetMovePP(moves[1], pk.Move2_PPUps);
+ pk.Move3_PP = moves.Length <= 2 ? 0 : pk.GetMovePP(moves[2], pk.Move3_PPUps);
+ pk.Move4_PP = moves.Length <= 3 ? 0 : pk.GetMovePP(moves[3], pk.Move4_PPUps);
+ }
+
+ ///
+ /// Updates the individual PP count values for each move slot based on the maximum possible value.
+ ///
+ /// Pokémon to modify.
+ public static void SetMaximumPPCurrent(this PKM pk) => pk.SetMaximumPPCurrent(pk.Moves);
+
+ ///
+ /// Refreshes the Move PP for the desired move.
+ ///
+ /// Pokémon to modify.
+ /// Move PP to refresh.
+ public static void SetSuggestedMovePP(this PKM pk, int index) => pk.HealPPIndex(index);
}
diff --git a/PKHeX.Core/Editing/Applicators/MoveSetApplicator.cs b/PKHeX.Core/Editing/Applicators/MoveSetApplicator.cs
index 0af1f3d98..03fcd674e 100644
--- a/PKHeX.Core/Editing/Applicators/MoveSetApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/MoveSetApplicator.cs
@@ -2,120 +2,119 @@
using System.Collections.Generic;
using System.Linq;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Logic for getting valid movesets.
+///
+public static class MoveSetApplicator
{
///
- /// Logic for getting valid movesets.
+ /// Gets a moveset for the provided data.
///
- public static class MoveSetApplicator
+ /// PKM to generate for
+ /// Full movepool & shuffling
+ /// 4 moves
+ public static int[] GetMoveSet(this PKM pk, bool random = false)
{
- ///
- /// Gets a moveset for the provided data.
- ///
- /// PKM to generate for
- /// Full movepool & shuffling
- /// 4 moves
- public static int[] GetMoveSet(this PKM pk, bool random = false)
- {
- var la = new LegalityAnalysis(pk);
- var moves = la.GetMoveSet(random);
+ var la = new LegalityAnalysis(pk);
+ var moves = la.GetMoveSet(random);
- if (random)
- return moves;
+ if (random)
+ return moves;
- var clone = pk.Clone();
- clone.SetMoves(moves);
- clone.SetMaximumPPCurrent(moves);
- var newLa = new LegalityAnalysis(clone);
+ var clone = pk.Clone();
+ clone.SetMoves(moves);
+ clone.SetMaximumPPCurrent(moves);
+ var newLa = new LegalityAnalysis(clone);
- // ReSharper disable once TailRecursiveCall
- return newLa.Valid ? moves : GetMoveSet(pk, true);
- }
+ // ReSharper disable once TailRecursiveCall
+ return newLa.Valid ? moves : GetMoveSet(pk, true);
+ }
- ///
- /// Gets a moveset for the provided data.
- ///
- /// Precomputed optional
- /// Full movepool & shuffling
- /// 4 moves
- public static int[] GetMoveSet(this LegalityAnalysis la, bool random = false)
- {
- int[] m = la.GetSuggestedCurrentMoves(random ? MoveSourceType.All : MoveSourceType.Encounter);
+ ///
+ /// Gets a moveset for the provided data.
+ ///
+ /// Precomputed optional
+ /// Full movepool & shuffling
+ /// 4 moves
+ public static int[] GetMoveSet(this LegalityAnalysis la, bool random = false)
+ {
+ int[] m = la.GetSuggestedCurrentMoves(random ? MoveSourceType.All : MoveSourceType.Encounter);
- var learn = la.GetSuggestedMovesAndRelearn();
- if (!m.All(z => learn.Contains(z)))
- m = m.Intersect(learn).ToArray();
+ var learn = la.GetSuggestedMovesAndRelearn();
+ if (!m.All(z => learn.Contains(z)))
+ m = m.Intersect(learn).ToArray();
- if (random && !la.pkm.IsEgg)
- Util.Shuffle(m.AsSpan());
+ if (random && !la.Entity.IsEgg)
+ Util.Shuffle(m.AsSpan());
- const int count = 4;
- if (m.Length > count)
- return m.SliceEnd(m.Length - count);
- Array.Resize(ref m, count);
+ const int count = 4;
+ if (m.Length > count)
+ return m.SliceEnd(m.Length - count);
+ Array.Resize(ref m, count);
+ return m;
+ }
+
+ ///
+ /// Fetches based on the provided .
+ ///
+ /// Pokémon to modify.
+ /// Encounter the relearn moves should be suggested for. If not provided, will try to detect it via legality analysis.
+ /// best suited for the current data.
+ public static IReadOnlyList GetSuggestedRelearnMoves(this PKM pk, IEncounterTemplate? enc = null) => GetSuggestedRelearnMoves(new LegalityAnalysis(pk), enc);
+
+ ///
+ /// Fetches based on the provided .
+ ///
+ /// which contains parsed information pertaining to legality.
+ /// Encounter the relearn moves should be suggested for. If not provided, will try to detect it via legality analysis.
+ /// best suited for the current data.
+ public static IReadOnlyList GetSuggestedRelearnMoves(this LegalityAnalysis legal, IEncounterTemplate? enc = null)
+ {
+ enc ??= legal.EncounterOriginal;
+ var m = legal.GetSuggestedRelearnMovesFromEncounter(enc);
+ if (m.Any(z => z != 0))
return m;
+
+ if (enc is MysteryGift or EncounterEgg)
+ return m;
+
+ if (enc is EncounterSlot6AO {CanDexNav: true} dn)
+ {
+ var moves = legal.Info.Moves;
+ for (int i = 0; i < moves.Length; i++)
+ {
+ if (!moves[i].ShouldBeInRelearnMoves())
+ continue;
+
+ var move = legal.Entity.GetMove(i);
+ if (dn.CanBeDexNavMove(move))
+ return new[] { move, 0, 0, 0 };
+ }
}
- ///
- /// Fetches based on the provided .
- ///
- /// Pokémon to modify.
- /// Encounter the relearn moves should be suggested for. If not provided, will try to detect it via legality analysis.
- /// best suited for the current data.
- public static IReadOnlyList GetSuggestedRelearnMoves(this PKM pk, IEncounterTemplate? enc = null) => GetSuggestedRelearnMoves(new LegalityAnalysis(pk), enc);
-
- ///
- /// Fetches based on the provided .
- ///
- /// which contains parsed information pertaining to legality.
- /// Encounter the relearn moves should be suggested for. If not provided, will try to detect it via legality analysis.
- /// best suited for the current data.
- public static IReadOnlyList GetSuggestedRelearnMoves(this LegalityAnalysis legal, IEncounterTemplate? enc = null)
+ if (enc is EncounterSlot8b { IsUnderground: true } ug)
{
- enc ??= legal.EncounterOriginal;
- var m = legal.GetSuggestedRelearnMovesFromEncounter(enc);
- if (m.Any(z => z != 0))
- return m;
-
- if (enc is MysteryGift or EncounterEgg)
- return m;
-
- if (enc is EncounterSlot6AO {CanDexNav: true} dn)
+ var moves = legal.Info.Moves;
+ for (int i = 0; i < moves.Length; i++)
{
- var moves = legal.Info.Moves;
- for (int i = 0; i < moves.Length; i++)
- {
- if (!moves[i].ShouldBeInRelearnMoves())
- continue;
+ if (!moves[i].ShouldBeInRelearnMoves())
+ continue;
- var move = legal.pkm.GetMove(i);
- if (dn.CanBeDexNavMove(move))
- return new[] { move, 0, 0, 0 };
- }
+ var move = legal.Entity.GetMove(i);
+ if (ug.CanBeUndergroundMove(move))
+ return new[] { move, 0, 0, 0 };
}
- if (enc is EncounterSlot8b { IsUnderground: true } ug)
- {
- var moves = legal.Info.Moves;
- for (int i = 0; i < moves.Length; i++)
- {
- if (!moves[i].ShouldBeInRelearnMoves())
- continue;
-
- var move = legal.pkm.GetMove(i);
- if (ug.CanBeUndergroundMove(move))
- return new[] { move, 0, 0, 0 };
- }
-
- if (ug.GetBaseEggMove(out int any))
- return new[] { any, 0, 0, 0 };
- }
-
- var encounter = EncounterSuggestion.GetSuggestedMetInfo(legal.pkm);
- if (encounter is IRelearn {Relearn: {Count: > 0} r})
- return r;
-
- return m;
+ if (ug.GetBaseEggMove(out int any))
+ return new[] { any, 0, 0, 0 };
}
+
+ var encounter = EncounterSuggestion.GetSuggestedMetInfo(legal.Entity);
+ if (encounter is IRelearn {Relearn: {Count: > 0} r})
+ return r;
+
+ return m;
}
}
diff --git a/PKHeX.Core/Editing/Applicators/RibbonApplicator.cs b/PKHeX.Core/Editing/Applicators/RibbonApplicator.cs
index 3bc2fbd0b..2ffaf1258 100644
--- a/PKHeX.Core/Editing/Applicators/RibbonApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/RibbonApplicator.cs
@@ -1,241 +1,241 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Logic for applying ribbons.
+///
+public static class RibbonApplicator
{
+ private static List GetAllRibbonNames(PKM pk) => RibbonInfo.GetRibbonInfo(pk).Select(z => z.Name).ToList();
+
///
- /// Logic for applying ribbons.
+ /// Gets a list of valid ribbons for the .
///
- public static class RibbonApplicator
+ /// Entity to fetch the list for.
+ /// All ribbon names.
+ /// List of all valid ribbon names.
+ public static IReadOnlyList GetValidRibbons(PKM pk, IList allRibbons)
{
- private static List GetAllRibbonNames(PKM pkm) => RibbonInfo.GetRibbonInfo(pkm).Select(z => z.Name).ToList();
+ var clone = pk.Clone();
+ return SetAllValidRibbons(allRibbons, clone);
+ }
- ///
- /// Gets a list of valid ribbons for the .
- ///
- /// Entity to fetch the list for.
- /// All ribbon names.
- /// List of all valid ribbon names.
- public static IReadOnlyList GetValidRibbons(PKM pkm, IList allRibbons)
+ ///
+ /// Gets a list of valid ribbons for the .
+ ///
+ /// Entity to fetch the list for.
+ /// List of all valid ribbon names.
+ public static IReadOnlyList GetValidRibbons(PKM pk)
+ {
+ var names = GetAllRibbonNames(pk);
+ return GetValidRibbons(pk, names);
+ }
+
+ ///
+ /// Gets a list of valid ribbons for the that can be removed.
+ ///
+ /// Entity to fetch the list for.
+ /// All ribbon names.
+ /// List of all removable ribbon names.
+ public static IReadOnlyList GetRemovableRibbons(PKM pk, IList allRibbons)
+ {
+ var clone = pk.Clone();
+ return RemoveAllValidRibbons(allRibbons, clone);
+ }
+
+ ///
+ /// Gets a list of valid ribbons for the that can be removed.
+ ///
+ /// Entity to fetch the list for.
+ /// List of all removable ribbon names.
+ public static IReadOnlyList GetRemovableRibbons(PKM pk)
+ {
+ var names = GetAllRibbonNames(pk);
+ return GetRemovableRibbons(pk, names);
+ }
+
+ ///
+ /// Sets all valid ribbons to the .
+ ///
+ /// Entity to set ribbons for.
+ /// True if any ribbons were applied.
+ public static bool SetAllValidRibbons(PKM pk)
+ {
+ var ribNames = GetAllRibbonNames(pk);
+ ribNames.RemoveAll(z => z.StartsWith("RibbonMark", StringComparison.Ordinal)); // until marking legality is handled
+ return SetAllValidRibbons(pk, ribNames);
+ }
+
+ ///
+ /// Sets all valid ribbons to the .
+ ///
+ /// Entity to set ribbons for.
+ /// Ribbon names to try setting.
+ /// True if any ribbons were applied.
+ public static bool SetAllValidRibbons(PKM pk, List ribNames)
+ {
+ var list = SetAllValidRibbons(ribNames, pk);
+ return list.Count != 0;
+ }
+
+ private static IReadOnlyList SetAllValidRibbons(IList allRibbons, PKM pk)
+ {
+ var la = new LegalityAnalysis(pk);
+ var valid = new List();
+
+ while (TryApplyAllRibbons(pk, la, allRibbons, valid) != 0)
{
- var pk = pkm.Clone();
- return SetAllValidRibbons(allRibbons, pk);
+ // Repeat the operation until no more ribbons are set.
}
- ///
- /// Gets a list of valid ribbons for the .
- ///
- /// Entity to fetch the list for.
- /// List of all valid ribbon names.
- public static IReadOnlyList GetValidRibbons(PKM pkm)
+ // Ribbon Deadlock
+ if (pk is IRibbonSetCommon6 c6)
+ InvertDeadlockContest(c6, la, true);
+
+ return valid;
+ }
+
+ ///
+ /// Sets all valid ribbons to the .
+ ///
+ /// Entity to set ribbons for.
+ /// True if any ribbons were removed.
+ public static bool RemoveAllValidRibbons(PKM pk)
+ {
+ var ribNames = GetAllRibbonNames(pk);
+ return RemoveAllValidRibbons(pk, ribNames);
+ }
+
+ ///
+ /// Sets all valid ribbons to the .
+ ///
+ /// Entity to set ribbons for.
+ /// Ribbon names to try setting.
+ /// True if any ribbons were removed.
+ public static bool RemoveAllValidRibbons(PKM pk, List ribNames)
+ {
+ var list = RemoveAllValidRibbons(ribNames, pk);
+ return list.Count != 0;
+ }
+
+ private static IReadOnlyList RemoveAllValidRibbons(IList allRibbons, PKM pk)
+ {
+ var la = new LegalityAnalysis(pk);
+ var valid = new List();
+
+ // Ribbon Deadlock
+ if (pk is IRibbonSetCommon6 c6)
+ InvertDeadlockContest(c6, la, false);
+
+ while (TryRemoveAllRibbons(pk, la, allRibbons, valid) != 0)
{
- var names = GetAllRibbonNames(pkm);
- return GetValidRibbons(pkm, names);
+ // Repeat the operation until no more ribbons are set.
}
- ///
- /// Gets a list of valid ribbons for the that can be removed.
- ///
- /// Entity to fetch the list for.
- /// All ribbon names.
- /// List of all removable ribbon names.
- public static IReadOnlyList GetRemovableRibbons(PKM pkm, IList allRibbons)
+ return valid;
+ }
+
+ private static int TryApplyAllRibbons(PKM pk, LegalityAnalysis la, IList allRibbons, ICollection valid)
+ {
+ int applied = 0;
+ for (int i = 0; i < allRibbons.Count;)
{
- var pk = pkm.Clone();
- return RemoveAllValidRibbons(allRibbons, pk);
- }
-
- ///
- /// Gets a list of valid ribbons for the that can be removed.
- ///
- /// Entity to fetch the list for.
- /// List of all removable ribbon names.
- public static IReadOnlyList GetRemovableRibbons(PKM pkm)
- {
- var names = GetAllRibbonNames(pkm);
- return GetRemovableRibbons(pkm, names);
- }
-
- ///
- /// Sets all valid ribbons to the .
- ///
- /// Entity to set ribbons for.
- /// True if any ribbons were applied.
- public static bool SetAllValidRibbons(PKM pkm)
- {
- var ribNames = GetAllRibbonNames(pkm);
- ribNames.RemoveAll(z => z.StartsWith("RibbonMark")); // until marking legality is handled
- return SetAllValidRibbons(pkm, ribNames);
- }
-
- ///
- /// Sets all valid ribbons to the .
- ///
- /// Entity to set ribbons for.
- /// Ribbon names to try setting.
- /// True if any ribbons were applied.
- public static bool SetAllValidRibbons(PKM pkm, List ribNames)
- {
- var list = SetAllValidRibbons(ribNames, pkm);
- return list.Count != 0;
- }
-
- private static IReadOnlyList SetAllValidRibbons(IList allRibbons, PKM pk)
- {
- var la = new LegalityAnalysis(pk);
- var valid = new List();
-
- while (TryApplyAllRibbons(pk, la, allRibbons, valid) != 0)
- {
- // Repeat the operation until no more ribbons are set.
- }
-
- // Ribbon Deadlock
- if (pk is IRibbonSetCommon6 c6)
- InvertDeadlockContest(c6, la, true);
-
- return valid;
- }
-
- ///
- /// Sets all valid ribbons to the .
- ///
- /// Entity to set ribbons for.
- /// True if any ribbons were removed.
- public static bool RemoveAllValidRibbons(PKM pkm)
- {
- var ribNames = GetAllRibbonNames(pkm);
- return RemoveAllValidRibbons(pkm, ribNames);
- }
-
- ///
- /// Sets all valid ribbons to the .
- ///
- /// Entity to set ribbons for.
- /// Ribbon names to try setting.
- /// True if any ribbons were removed.
- public static bool RemoveAllValidRibbons(PKM pkm, List ribNames)
- {
- var list = RemoveAllValidRibbons(ribNames, pkm);
- return list.Count != 0;
- }
-
- private static IReadOnlyList RemoveAllValidRibbons(IList allRibbons, PKM pk)
- {
- var la = new LegalityAnalysis(pk);
- var valid = new List();
-
- // Ribbon Deadlock
- if (pk is IRibbonSetCommon6 c6)
- InvertDeadlockContest(c6, la, false);
-
- while (TryRemoveAllRibbons(pk, la, allRibbons, valid) != 0)
- {
- // Repeat the operation until no more ribbons are set.
- }
-
- return valid;
- }
-
- private static int TryApplyAllRibbons(PKM pk, LegalityAnalysis la, IList allRibbons, ICollection valid)
- {
- int applied = 0;
- for (int i = 0; i < allRibbons.Count;)
- {
- la.ResetParse();
- var rib = allRibbons[i];
- var success = TryApplyRibbon(pk, la, rib);
- if (success)
- {
- ++applied;
- allRibbons.RemoveAt(i);
- valid.Add(rib);
- }
- else
- {
- RemoveRibbon(pk, rib);
- ++i;
- }
- }
-
- return applied;
- }
-
- private static int TryRemoveAllRibbons(PKM pk, LegalityAnalysis la, IList allRibbons, ICollection valid)
- {
- int removed = 0;
- for (int i = 0; i < allRibbons.Count;)
- {
- la.ResetParse();
- var rib = allRibbons[i];
- var success = TryRemoveRibbon(pk, la, rib);
- if (success)
- {
- ++removed;
- allRibbons.RemoveAt(i);
- valid.Add(rib);
- }
- else
- {
- SetRibbonValue(pk, rib, 1);
- ++i;
- }
- }
-
- return removed;
- }
-
- private static void RemoveRibbon(PKM pk, string rib) => SetRibbonValue(pk, rib, 0);
-
- private static bool TryRemoveRibbon(PKM pk, LegalityAnalysis la, string rib)
- {
- RemoveRibbon(pk, rib);
- return UpdateIsValid(la);
- }
-
- private static bool TryApplyRibbon(PKM pk, LegalityAnalysis la, string rib)
- {
- SetRibbonValue(pk, rib, 1);
- return UpdateIsValid(la);
- }
-
- private static bool UpdateIsValid(LegalityAnalysis la)
- {
- LegalityAnalyzers.Ribbon.Verify(la);
- return la.Results.All(z => z.Valid);
- }
-
- private static void SetRibbonValue(PKM pk, string rib, int value)
- {
- switch (rib)
- {
- case nameof(PK7.RibbonCountMemoryBattle):
- ReflectUtil.SetValue(pk, rib, value * (pk.Gen4 ? 6 : 8));
- break;
- case nameof(PK7.RibbonCountMemoryContest):
- ReflectUtil.SetValue(pk, rib, value * (pk.Gen4 ? 20 : 40));
- break;
- default:
- if (rib.StartsWith("RibbonCountG3"))
- ReflectUtil.SetValue(pk, rib, value * 4);
- else
- ReflectUtil.SetValue(pk, rib, value != 0);
- break;
- }
- }
-
- private static void InvertDeadlockContest(IRibbonSetCommon6 c6, LegalityAnalysis la, bool desiredState)
- {
- // RibbonContestStar depends on having all contest ribbons, and having RibbonContestStar requires all.
- // Since the above logic sets individual ribbons, we must try setting this deadlock pair manually.
- if (c6.RibbonMasterToughness == desiredState || c6.RibbonContestStar == desiredState)
- return;
-
la.ResetParse();
- c6.RibbonMasterToughness = c6.RibbonContestStar = desiredState;
- bool result = UpdateIsValid(la);
- if (!result)
- c6.RibbonMasterToughness = c6.RibbonContestStar = !desiredState;
+ var rib = allRibbons[i];
+ var success = TryApplyRibbon(pk, la, rib);
+ if (success)
+ {
+ ++applied;
+ allRibbons.RemoveAt(i);
+ valid.Add(rib);
+ }
+ else
+ {
+ RemoveRibbon(pk, rib);
+ ++i;
+ }
+ }
+
+ return applied;
+ }
+
+ private static int TryRemoveAllRibbons(PKM pk, LegalityAnalysis la, IList allRibbons, ICollection valid)
+ {
+ int removed = 0;
+ for (int i = 0; i < allRibbons.Count;)
+ {
+ la.ResetParse();
+ var rib = allRibbons[i];
+ var success = TryRemoveRibbon(pk, la, rib);
+ if (success)
+ {
+ ++removed;
+ allRibbons.RemoveAt(i);
+ valid.Add(rib);
+ }
+ else
+ {
+ SetRibbonValue(pk, rib, 1);
+ ++i;
+ }
+ }
+
+ return removed;
+ }
+
+ private static void RemoveRibbon(PKM pk, string rib) => SetRibbonValue(pk, rib, 0);
+
+ private static bool TryRemoveRibbon(PKM pk, LegalityAnalysis la, string rib)
+ {
+ RemoveRibbon(pk, rib);
+ return UpdateIsValid(la);
+ }
+
+ private static bool TryApplyRibbon(PKM pk, LegalityAnalysis la, string rib)
+ {
+ SetRibbonValue(pk, rib, 1);
+ return UpdateIsValid(la);
+ }
+
+ private static bool UpdateIsValid(LegalityAnalysis la)
+ {
+ LegalityAnalyzers.Ribbon.Verify(la);
+ return la.Results.All(z => z.Valid);
+ }
+
+ private static void SetRibbonValue(PKM pk, string rib, int value)
+ {
+ switch (rib)
+ {
+ case nameof(PK7.RibbonCountMemoryBattle):
+ ReflectUtil.SetValue(pk, rib, value * (pk.Gen4 ? 6 : 8));
+ break;
+ case nameof(PK7.RibbonCountMemoryContest):
+ ReflectUtil.SetValue(pk, rib, value * (pk.Gen4 ? 20 : 40));
+ break;
+ default:
+ if (rib.StartsWith("RibbonCountG3", StringComparison.Ordinal))
+ ReflectUtil.SetValue(pk, rib, value * 4);
+ else
+ ReflectUtil.SetValue(pk, rib, value != 0);
+ break;
}
}
+
+ private static void InvertDeadlockContest(IRibbonSetCommon6 c6, LegalityAnalysis la, bool desiredState)
+ {
+ // RibbonContestStar depends on having all contest ribbons, and having RibbonContestStar requires all.
+ // Since the above logic sets individual ribbons, we must try setting this deadlock pair manually.
+ if (c6.RibbonMasterToughness == desiredState || c6.RibbonContestStar == desiredState)
+ return;
+
+ la.ResetParse();
+ c6.RibbonMasterToughness = c6.RibbonContestStar = desiredState;
+ bool result = UpdateIsValid(la);
+ if (!result)
+ c6.RibbonMasterToughness = c6.RibbonContestStar = !desiredState;
+ }
}
diff --git a/PKHeX.Core/Editing/Applicators/TechnicalRecordApplicator.cs b/PKHeX.Core/Editing/Applicators/TechnicalRecordApplicator.cs
index f37ba557f..44b19bb04 100644
--- a/PKHeX.Core/Editing/Applicators/TechnicalRecordApplicator.cs
+++ b/PKHeX.Core/Editing/Applicators/TechnicalRecordApplicator.cs
@@ -1,65 +1,64 @@
using System;
using System.Collections.Generic;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Logic for modifying the Technical Record flags of a .
+///
+public static class TechnicalRecordApplicator
{
///
- /// Logic for modifying the Technical Record flags of a .
+ /// Sets the Technical Record flags for the .
///
- public static class TechnicalRecordApplicator
+ /// Pokémon to modify.
+ /// Value to set for the record.
+ /// Max record to set.
+ public static void SetRecordFlags(this ITechRecord8 pk, bool value, int max = 100)
{
- ///
- /// Sets the Technical Record flags for the .
- ///
- /// Pokémon to modify.
- /// Value to set for the record.
- /// Max record to set.
- public static void SetRecordFlags(this ITechRecord8 pk, bool value, int max = 100)
+ for (int i = 0; i < max; i++)
+ pk.SetMoveRecordFlag(i, value);
+ }
+
+ ///
+ /// Clears the Technical Record flags for the .
+ ///
+ /// Pokémon to modify.
+ public static void ClearRecordFlags(this ITechRecord8 pk) => pk.SetRecordFlags(false, 112);
+
+ ///
+ /// Sets the Technical Record flags for the based on the current moves.
+ ///
+ /// Pokémon to modify.
+ /// Moves to set flags for. If a move is not a Technical Record, it is skipped.
+ public static void SetRecordFlags(this ITechRecord8 pk, IEnumerable moves)
+ {
+ var permit = pk.TechRecordPermitFlags;
+ var moveIDs = pk.TechRecordPermitIndexes;
+ if (permit.Length != moveIDs.Length)
+ return;
+
+ foreach (var m in moves)
{
- for (int i = 0; i < max; i++)
- pk.SetMoveRecordFlag(i, value);
+ var index = moveIDs.IndexOf(m);
+ if (index == -1)
+ continue;
+ if (permit[index])
+ pk.SetMoveRecordFlag(index, true);
}
+ }
- ///
- /// Clears the Technical Record flags for the .
- ///
- /// Pokémon to modify.
- public static void ClearRecordFlags(this ITechRecord8 pk) => pk.SetRecordFlags(false, 112);
-
- ///
- /// Sets the Technical Record flags for the based on the current moves.
- ///
- /// Pokémon to modify.
- /// Moves to set flags for. If a move is not a Technical Record, it is skipped.
- public static void SetRecordFlags(this ITechRecord8 pk, IEnumerable moves)
+ ///
+ /// Sets all the Technical Record flags for the if they are permitted to be learned in-game.
+ ///
+ /// Pokémon to modify.
+ public static void SetRecordFlags(this ITechRecord8 pk)
+ {
+ var permit = pk.TechRecordPermitFlags;
+ for (int i = 0; i < permit.Length; i++)
{
- var permit = pk.TechRecordPermitFlags;
- var moveIDs = pk.TechRecordPermitIndexes;
- if (permit.Length != moveIDs.Length)
- return;
-
- foreach (var m in moves)
- {
- var index = moveIDs.IndexOf(m);
- if (index == -1)
- continue;
- if (permit[index])
- pk.SetMoveRecordFlag(index, true);
- }
- }
-
- ///
- /// Sets all the Technical Record flags for the if they are permitted to be learned in-game.
- ///
- /// Pokémon to modify.
- public static void SetRecordFlags(this ITechRecord8 pk)
- {
- var permit = pk.TechRecordPermitFlags;
- for (int i = 0; i < permit.Length; i++)
- {
- if (permit[i])
- pk.SetMoveRecordFlag(i, true);
- }
+ if (permit[i])
+ pk.SetMoveRecordFlag(i, true);
}
}
}
diff --git a/PKHeX.Core/Editing/Bulk/BatchEditing.cs b/PKHeX.Core/Editing/Bulk/BatchEditing.cs
index ffa80fea5..5edc6eb6b 100644
--- a/PKHeX.Core/Editing/Bulk/BatchEditing.cs
+++ b/PKHeX.Core/Editing/Bulk/BatchEditing.cs
@@ -1,504 +1,503 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
-using System.Globalization;
using System.Linq;
using System.Reflection;
using static PKHeX.Core.MessageStrings;
using static PKHeX.Core.BatchModifications;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Logic for editing many with user provided list.
+///
+public static class BatchEditing
{
- ///
- /// Logic for editing many with user provided list.
- ///
- public static class BatchEditing
+ public static readonly Type[] Types =
{
- public static readonly Type[] Types =
+ typeof (PK8), typeof (PA8), typeof (PB8),
+ typeof (PB7),
+ typeof (PK7), typeof (PK6), typeof (PK5), typeof (PK4), typeof(BK4),
+ typeof (PK3), typeof (XK3), typeof (CK3),
+ typeof (PK2), typeof (SK2), typeof (PK1),
+ };
+
+ ///
+ /// Extra properties to show in the list of selectable properties (GUI)
+ ///
+ public static readonly List CustomProperties = new()
+ {
+ PROP_LEGAL, PROP_TYPENAME, PROP_RIBBONS, PROP_CONTESTSTATS, PROP_MOVEMASTERY,
+ IdentifierContains, nameof(ISlotInfo.Slot), nameof(SlotInfoBox.Box),
+ };
+
+ ///
+ /// Property names, indexed by .
+ ///
+ public static string[][] Properties => GetProperties.Value;
+
+ private static readonly Lazy GetProperties = new(() => GetPropArray(Types, CustomProperties));
+
+ private static readonly Dictionary[] Props = GetPropertyDictionaries(Types);
+
+ private static Dictionary[] GetPropertyDictionaries(IReadOnlyList types)
+ {
+ var result = new Dictionary[types.Count];
+ for (int i = 0; i < types.Count; i++)
+ result[i] = GetPropertyDictionary(types[i], ReflectUtil.GetAllPropertyInfoPublic);
+ return result;
+ }
+
+ private static Dictionary GetPropertyDictionary(Type type, Func> selector)
+ {
+ var dict = new Dictionary();
+ var props = selector(type);
+ foreach (var p in props)
{
- typeof (PK8), typeof (PA8), typeof (PB8),
- typeof (PB7),
- typeof (PK7), typeof (PK6), typeof (PK5), typeof (PK4), typeof(BK4),
- typeof (PK3), typeof (XK3), typeof (CK3),
- typeof (PK2), typeof (SK2), typeof (PK1),
- };
+ if (!dict.ContainsKey(p.Name))
+ dict.Add(p.Name, p);
+ }
+ return dict;
+ }
- ///
- /// Extra properties to show in the list of selectable properties (GUI)
- ///
- public static readonly List CustomProperties = new()
+ internal const string CONST_RAND = "$rand";
+ internal const string CONST_SHINY = "$shiny";
+ internal const string CONST_SUGGEST = "$suggest";
+ private const string CONST_BYTES = "$[]";
+ private const char CONST_POINTER = '*';
+ internal const char CONST_SPECIAL = '$';
+
+ internal const string PROP_LEGAL = "Legal";
+ internal const string PROP_TYPENAME = "ObjectType";
+ internal const string PROP_RIBBONS = "Ribbons";
+ internal const string PROP_CONTESTSTATS = "ContestStats";
+ internal const string PROP_MOVEMASTERY = "MoveMastery";
+ internal const string IdentifierContains = nameof(IdentifierContains);
+
+ private static string[][] GetPropArray(IReadOnlyList types, IReadOnlyList extra)
+ {
+ var result = new string[types.Count + 2][];
+ var p = result.AsSpan(1, types.Count);
+
+ for (int i = 0; i < p.Length; i++)
{
- PROP_LEGAL, PROP_TYPENAME, PROP_RIBBONS, PROP_CONTESTSTATS, PROP_MOVEMASTERY,
- IdentifierContains, nameof(ISlotInfo.Slot), nameof(SlotInfoBox.Box),
- };
-
- ///
- /// Property names, indexed by .
- ///
- public static string[][] Properties => GetProperties.Value;
-
- private static readonly Lazy GetProperties = new(() => GetPropArray(Types, CustomProperties));
-
- private static readonly Dictionary[] Props = GetPropertyDictionaries(Types);
-
- private static Dictionary[] GetPropertyDictionaries(IReadOnlyList types)
- {
- var result = new Dictionary[types.Count];
- for (int i = 0; i < types.Count; i++)
- result[i] = GetPropertyDictionary(types[i], ReflectUtil.GetAllPropertyInfoPublic);
- return result;
+ var props = ReflectUtil.GetPropertiesPublic(types[i]);
+ p[i] = props.Concat(extra).OrderBy(a => a).ToArray();
}
- private static Dictionary GetPropertyDictionary(Type type, Func> selector)
+ // Properties for any PKM
+ // Properties shared by all PKM
+ var first = p[0];
+ var any = new HashSet(first);
+ var all = new HashSet(first);
+ for (int i = 1; i < p.Length; i++)
{
- var dict = new Dictionary();
- var props = selector(type);
- foreach (var p in props)
- {
- if (!dict.ContainsKey(p.Name))
- dict.Add(p.Name, p);
- }
- return dict;
+ any.UnionWith(p[i]);
+ all.IntersectWith(p[i]);
}
- internal const string CONST_RAND = "$rand";
- internal const string CONST_SHINY = "$shiny";
- internal const string CONST_SUGGEST = "$suggest";
- private const string CONST_BYTES = "$[]";
- private const string CONST_POINTER = "*";
+ result[0] = any.OrderBy(z => z).ToArray();
+ result[^1] = all.OrderBy(z => z).ToArray();
+ return result;
+ }
- internal const string PROP_LEGAL = "Legal";
- internal const string PROP_TYPENAME = "ObjectType";
- internal const string PROP_RIBBONS = "Ribbons";
- internal const string PROP_CONTESTSTATS = "ContestStats";
- internal const string PROP_MOVEMASTERY = "MoveMastery";
- internal const string IdentifierContains = nameof(IdentifierContains);
+ ///
+ /// Tries to fetch the property from the cache of available properties.
+ ///
+ /// Pokémon to check
+ /// Property Name to check
+ /// Property Info retrieved (if any).
+ /// True if has property, false if does not.
+ public static bool TryGetHasProperty(PKM pk, string name, [NotNullWhen(true)] out PropertyInfo? pi)
+ {
+ var type = pk.GetType();
+ return TryGetHasProperty(type, name, out pi);
+ }
- private static string[][] GetPropArray(IReadOnlyList types, IReadOnlyList extra)
+ ///
+ /// Tries to fetch the property from the cache of available properties.
+ ///
+ /// Type to check
+ /// Property Name to check
+ /// Property Info retrieved (if any).
+ /// True if has property, false if does not.
+ public static bool TryGetHasProperty(Type type, string name, [NotNullWhen(true)] out PropertyInfo? pi)
+ {
+ var index = Array.IndexOf(Types, type);
+ if (index < 0)
{
- var result = new string[types.Count + 2][];
- var p = result.AsSpan(1, types.Count);
-
- for (int i = 0; i < p.Length; i++)
- {
- var props = ReflectUtil.GetPropertiesPublic(types[i]);
- p[i] = props.Concat(extra).OrderBy(a => a).ToArray();
- }
-
- // Properties for any PKM
- // Properties shared by all PKM
- var first = p[0];
- var any = new HashSet(first);
- var all = new HashSet(first);
- for (int i = 1; i < p.Length; i++)
- {
- any.UnionWith(p[i]);
- all.IntersectWith(p[i]);
- }
-
- result[0] = any.OrderBy(z => z).ToArray();
- result[^1] = all.OrderBy(z => z).ToArray();
- return result;
+ pi = null;
+ return false;
}
+ var props = Props[index];
+ return props.TryGetValue(name, out pi);
+ }
- ///
- /// Tries to fetch the property from the cache of available properties.
- ///
- /// Pokémon to check
- /// Property Name to check
- /// Property Info retrieved (if any).
- /// True if has property, false if does not.
- public static bool TryGetHasProperty(PKM pk, string name, [NotNullWhen(true)] out PropertyInfo? pi)
+ ///
+ /// Gets a list of types that implement the requested .
+ ///
+ public static IEnumerable GetTypesImplementing(string property)
+ {
+ for (int i = 0; i < Types.Length; i++)
{
- var type = pk.GetType();
- return TryGetHasProperty(type, name, out pi);
- }
-
- ///
- /// Tries to fetch the property from the cache of available properties.
- ///
- /// Type to check
- /// Property Name to check
- /// Property Info retrieved (if any).
- /// True if has property, false if does not.
- public static bool TryGetHasProperty(Type type, string name, [NotNullWhen(true)] out PropertyInfo? pi)
- {
- var index = Array.IndexOf(Types, type);
- if (index < 0)
- {
- pi = null;
- return false;
- }
- var props = Props[index];
- return props.TryGetValue(name, out pi);
- }
-
- ///
- /// Gets a list of types that implement the requested .
- ///
- public static IEnumerable GetTypesImplementing(string property)
- {
- for (int i = 0; i < Types.Length; i++)
- {
- var type = Types[i];
- var props = Props[i];
- if (!props.TryGetValue(property, out var pi))
- continue;
- yield return $"{type.Name}: {pi.PropertyType.Name}";
- }
- }
-
- ///
- /// Gets the type of the property using the saved cache of properties.
- ///
- /// Property Name to fetch the type for
- /// Type index (within . Leave empty (0) for a nonspecific format.
- /// Short name of the property's type.
- public static string? GetPropertyType(string propertyName, int typeIndex = 0)
- {
- if (CustomProperties.Contains(propertyName))
- return "Custom";
-
- if (typeIndex == 0) // Any
- {
- foreach (var p in Props)
- {
- if (p.TryGetValue(propertyName, out var pi))
- return pi.PropertyType.Name;
- }
- return null;
- }
-
- int index = typeIndex - 1 >= Props.Length ? 0 : typeIndex - 1; // All vs Specific
- var pr = Props[index];
- if (!pr.TryGetValue(propertyName, out var info))
- return null;
- return info.PropertyType.Name;
- }
-
- ///
- /// Initializes the list with a context-sensitive value. If the provided value is a string, it will attempt to convert that string to its corresponding index.
- ///
- /// Instructions to initialize.
- public static void ScreenStrings(IEnumerable il)
- {
- foreach (var i in il.Where(i => !i.PropertyValue.All(char.IsDigit)))
- {
- string pv = i.PropertyValue;
- if (pv.StartsWith("$") && !pv.StartsWith(CONST_BYTES) && pv.Contains(','))
- i.SetRandRange(pv);
-
- SetInstructionScreenedValue(i);
- }
- }
-
- ///
- /// Initializes the with a context-sensitive value. If the provided value is a string, it will attempt to convert that string to its corresponding index.
- ///
- /// Instruction to initialize.
- private static void SetInstructionScreenedValue(StringInstruction i)
- {
- switch (i.PropertyName)
- {
- case nameof(PKM.Species): i.SetScreenedValue(GameInfo.Strings.specieslist); return;
- case nameof(PKM.HeldItem): i.SetScreenedValue(GameInfo.Strings.itemlist); return;
- case nameof(PKM.Ability): i.SetScreenedValue(GameInfo.Strings.abilitylist); return;
- case nameof(PKM.Nature): i.SetScreenedValue(GameInfo.Strings.natures); return;
- case nameof(PKM.Ball): i.SetScreenedValue(GameInfo.Strings.balllist); return;
-
- case nameof(PKM.Move1) or nameof(PKM.Move2) or nameof(PKM.Move3) or nameof(PKM.Move4):
- case nameof(PKM.RelearnMove1) or nameof(PKM.RelearnMove2) or nameof(PKM.RelearnMove3) or nameof(PKM.RelearnMove4):
- i.SetScreenedValue(GameInfo.Strings.movelist); return;
- }
- }
-
- ///
- /// Checks if the object is filtered by the provided .
- ///
- /// Filters which must be satisfied.
- /// Object to check.
- /// True if matches all filters.
- public static bool IsFilterMatch(IEnumerable filters, PKM pk) => filters.All(z => IsFilterMatch(z, pk, Props[Array.IndexOf(Types, pk.GetType())]));
-
- ///
- /// Checks if the object is filtered by the provided .
- ///
- /// Filters which must be satisfied.
- /// Object to check.
- /// True if matches all filters.
- public static bool IsFilterMatchMeta(IEnumerable filters, SlotCache pk)
- {
- foreach (var i in filters)
- {
- foreach (var filter in BatchFilters.FilterMeta)
- {
- if (!filter.IsMatch(i.PropertyName))
- continue;
-
- if (!filter.IsFiltered(pk, i))
- return false;
-
- break;
- }
- }
- return true;
- }
-
- ///
- /// Checks if the object is filtered by the provided .
- ///
- /// Filters which must be satisfied.
- /// Object to check.
- /// True if matches all filters.
- public static bool IsFilterMatch(IEnumerable filters, object obj)
- {
- foreach (var cmd in filters)
- {
- if (cmd.PropertyName is PROP_TYPENAME)
- {
- if ((obj.GetType().Name == cmd.PropertyValue) != cmd.Evaluator)
- return false;
- continue;
- }
-
- if (!ReflectUtil.HasProperty(obj, cmd.PropertyName, out var pi))
- return false;
- try
- {
- if (pi.IsValueEqual(obj, cmd.PropertyValue) == cmd.Evaluator)
- continue;
- }
- // User provided inputs can mismatch the type's required value format, and fail to be compared.
- catch (Exception e)
- {
- Debug.WriteLine($"Unable to compare {cmd.PropertyName} to {cmd.PropertyValue}.");
- Debug.WriteLine(e.Message);
- }
- return false;
- }
- return true;
- }
-
- ///
- /// Tries to modify the .
- ///
- /// Object to modify.
- /// Filters which must be satisfied prior to any modifications being made.
- /// Modifications to perform on the .
- /// Result of the attempted modification.
- public static bool TryModify(PKM pk, IEnumerable filters, IEnumerable modifications)
- {
- var result = TryModifyPKM(pk, filters, modifications);
- return result == ModifyResult.Modified;
- }
-
- ///
- /// Tries to modify the .
- ///
- /// Command Filter
- /// Filters which must be satisfied prior to any modifications being made.
- /// Modifications to perform on the .
- /// Result of the attempted modification.
- internal static ModifyResult TryModifyPKM(PKM pk, IEnumerable filters, IEnumerable modifications)
- {
- if (!pk.ChecksumValid || pk.Species == 0)
- return ModifyResult.Invalid;
-
- var info = new BatchInfo(pk);
- var pi = Props[Array.IndexOf(Types, pk.GetType())];
- foreach (var cmd in filters)
- {
- try
- {
- if (!IsFilterMatch(cmd, info, pi))
- return ModifyResult.Filtered;
- }
- // Swallow any error because this can be malformed user input.
- catch (Exception ex)
- {
- Debug.WriteLine(MsgBEModifyFailCompare + " " + ex.Message, cmd.PropertyName, cmd.PropertyValue);
- return ModifyResult.Error;
- }
- }
-
- ModifyResult result = ModifyResult.Modified;
- foreach (var cmd in modifications)
- {
- try
- {
- var tmp = SetPKMProperty(cmd, info, pi);
- if (tmp != ModifyResult.Modified)
- result = tmp;
- }
- // Swallow any error because this can be malformed user input.
- catch (Exception ex)
- {
- Debug.WriteLine(MsgBEModifyFail + " " + ex.Message, cmd.PropertyName, cmd.PropertyValue);
- }
- }
- return result;
- }
-
- ///
- /// Sets the if the should be filtered due to the provided.
- ///
- /// Command Filter
- /// Pokémon to check.
- /// PropertyInfo cache (optional)
- /// True if filtered, else false.
- private static ModifyResult SetPKMProperty(StringInstruction cmd, BatchInfo info, IReadOnlyDictionary props)
- {
- var pk = info.Entity;
- if (cmd.PropertyValue.StartsWith(CONST_BYTES))
- return SetByteArrayProperty(pk, cmd);
-
- if (cmd.PropertyValue.StartsWith(CONST_SUGGEST, true, CultureInfo.CurrentCulture))
- return SetSuggestedPKMProperty(cmd.PropertyName, info, cmd.PropertyValue);
- if (cmd.PropertyValue == CONST_RAND && cmd.PropertyName == nameof(PKM.Moves))
- return SetMoves(pk, info.Legality.GetMoveSet(true));
-
- if (SetComplexProperty(pk, cmd))
- return ModifyResult.Modified;
-
- if (!props.TryGetValue(cmd.PropertyName, out var pi))
- return ModifyResult.Error;
-
- if (!pi.CanWrite)
- return ModifyResult.Error;
-
- object val;
- if (cmd.Random)
- val = cmd.RandomValue;
- else if (cmd.PropertyValue.StartsWith(CONST_POINTER) && props.TryGetValue(cmd.PropertyValue[1..], out var opi))
- val = opi.GetValue(pk);
- else
- val = cmd.PropertyValue;
-
- ReflectUtil.SetValue(pi, pk, val);
- return ModifyResult.Modified;
- }
-
- ///
- /// Checks if the should be filtered due to the provided.
- ///
- /// Command Filter
- /// Pokémon to check.
- /// PropertyInfo cache (optional)
- /// True if filter matches, else false.
- private static bool IsFilterMatch(StringInstruction cmd, BatchInfo info, IReadOnlyDictionary props)
- {
- var match = BatchFilters.FilterMods.Find(z => z.IsMatch(cmd.PropertyName));
- if (match != null)
- return match.IsFiltered(info, cmd);
- return IsPropertyFiltered(cmd, info.Entity, props);
- }
-
- ///
- /// Checks if the should be filtered due to the provided.
- ///
- /// Command Filter
- /// Pokémon to check.
- /// PropertyInfo cache (optional)
- /// True if filter matches, else false.
- private static bool IsFilterMatch(StringInstruction cmd, PKM pk, IReadOnlyDictionary props)
- {
- var match = BatchFilters.FilterMods.Find(z => z.IsMatch(cmd.PropertyName));
- if (match != null)
- return match.IsFiltered(pk, cmd);
- return IsPropertyFiltered(cmd, pk, props);
- }
-
- ///
- /// Checks if the should be filtered due to the provided.
- ///
- /// Command Filter
- /// Pokémon to check.
- /// PropertyInfo cache
- /// True if filtered, else false.
- private static bool IsPropertyFiltered(StringInstruction cmd, PKM pk, IReadOnlyDictionary props)
- {
- if (!props.TryGetValue(cmd.PropertyName, out var pi))
- return false;
- if (!pi.CanRead)
- return false;
- return pi.IsValueEqual(pk, cmd.PropertyValue) == cmd.Evaluator;
- }
-
- ///
- /// Sets the data with a suggested value based on its .
- ///
- /// Property to modify.
- /// Cached info storing Legal data.
- /// Suggestion string which starts with
- private static ModifyResult SetSuggestedPKMProperty(string name, BatchInfo info, string propValue)
- {
- var first = BatchMods.SuggestionMods.Find(z => z.IsMatch(name, propValue, info));
- if (first != null)
- return first.Modify(name, propValue, info);
- return ModifyResult.Error;
- }
-
- ///
- /// Sets the byte array property to a specified value.
- ///
- /// Pokémon to modify.
- /// Modification
- private static ModifyResult SetByteArrayProperty(PKM pk, StringInstruction cmd)
- {
- switch (cmd.PropertyName)
- {
- case nameof(PKM.Nickname_Trash): ConvertToBytes(cmd.PropertyValue).CopyTo(pk.Nickname_Trash); return ModifyResult.Modified;
- case nameof(PKM.OT_Trash): ConvertToBytes(cmd.PropertyValue).CopyTo(pk.OT_Trash); return ModifyResult.Modified;
- case nameof(PKM.HT_Trash): ConvertToBytes(cmd.PropertyValue).CopyTo(pk.HT_Trash); return ModifyResult.Modified;
- default:
- return ModifyResult.Error;
- }
- static byte[] ConvertToBytes(string str)
- {
- var arr = str[CONST_BYTES.Length..].Split(',');
- return Array.ConvertAll(arr, z => Convert.ToByte(z.Trim(), 16));
- }
- }
-
- ///
- /// Sets the property to a non-specific smart value.
- ///
- /// Pokémon to modify.
- /// Modification
- /// True if modified, false if no modifications done.
- private static bool SetComplexProperty(PKM pk, StringInstruction cmd)
- {
- if (cmd.PropertyName.StartsWith("IV") && cmd.PropertyValue == CONST_RAND)
- {
- SetRandomIVs(pk, cmd);
- return true;
- }
-
- var match = BatchMods.ComplexMods.Find(z => z.IsMatch(cmd.PropertyName, cmd.PropertyValue));
- if (match == null)
- return false;
-
- match.Modify(pk, cmd);
- return true;
- }
-
- ///
- /// Sets the IV(s) to a random value.
- ///
- /// Pokémon to modify.
- /// Modification
- private static void SetRandomIVs(PKM pk, StringInstruction cmd)
- {
- if (cmd.PropertyName == nameof(PKM.IVs))
- {
- pk.SetRandomIVs();
- return;
- }
-
- if (TryGetHasProperty(pk, cmd.PropertyName, out var pi))
- ReflectUtil.SetValue(pi, pk, Util.Rand.Next(pk.MaxIV + 1));
+ var type = Types[i];
+ var props = Props[i];
+ if (!props.TryGetValue(property, out var pi))
+ continue;
+ yield return $"{type.Name}: {pi.PropertyType.Name}";
}
}
+
+ ///
+ /// Gets the type of the property using the saved cache of properties.
+ ///
+ /// Property Name to fetch the type for
+ /// Type index (within . Leave empty (0) for a nonspecific format.
+ /// Short name of the property's type.
+ public static string? GetPropertyType(string propertyName, int typeIndex = 0)
+ {
+ if (CustomProperties.Contains(propertyName))
+ return "Custom";
+
+ if (typeIndex == 0) // Any
+ {
+ foreach (var p in Props)
+ {
+ if (p.TryGetValue(propertyName, out var pi))
+ return pi.PropertyType.Name;
+ }
+ return null;
+ }
+
+ int index = typeIndex - 1 >= Props.Length ? 0 : typeIndex - 1; // All vs Specific
+ var pr = Props[index];
+ if (!pr.TryGetValue(propertyName, out var info))
+ return null;
+ return info.PropertyType.Name;
+ }
+
+ ///
+ /// Initializes the list with a context-sensitive value. If the provided value is a string, it will attempt to convert that string to its corresponding index.
+ ///
+ /// Instructions to initialize.
+ public static void ScreenStrings(IEnumerable il)
+ {
+ foreach (var i in il.Where(i => !i.PropertyValue.All(char.IsDigit)))
+ {
+ string pv = i.PropertyValue;
+ if (pv.StartsWith(CONST_SPECIAL) && !pv.StartsWith(CONST_BYTES, StringComparison.Ordinal) && pv.Contains(','))
+ i.SetRandRange(pv);
+
+ SetInstructionScreenedValue(i);
+ }
+ }
+
+ ///
+ /// Initializes the with a context-sensitive value. If the provided value is a string, it will attempt to convert that string to its corresponding index.
+ ///
+ /// Instruction to initialize.
+ private static void SetInstructionScreenedValue(StringInstruction i)
+ {
+ switch (i.PropertyName)
+ {
+ case nameof(PKM.Species): i.SetScreenedValue(GameInfo.Strings.specieslist); return;
+ case nameof(PKM.HeldItem): i.SetScreenedValue(GameInfo.Strings.itemlist); return;
+ case nameof(PKM.Ability): i.SetScreenedValue(GameInfo.Strings.abilitylist); return;
+ case nameof(PKM.Nature): i.SetScreenedValue(GameInfo.Strings.natures); return;
+ case nameof(PKM.Ball): i.SetScreenedValue(GameInfo.Strings.balllist); return;
+
+ case nameof(PKM.Move1) or nameof(PKM.Move2) or nameof(PKM.Move3) or nameof(PKM.Move4):
+ case nameof(PKM.RelearnMove1) or nameof(PKM.RelearnMove2) or nameof(PKM.RelearnMove3) or nameof(PKM.RelearnMove4):
+ i.SetScreenedValue(GameInfo.Strings.movelist); return;
+ }
+ }
+
+ ///
+ /// Checks if the object is filtered by the provided .
+ ///
+ /// Filters which must be satisfied.
+ /// Object to check.
+ /// True if matches all filters.
+ public static bool IsFilterMatch(IEnumerable filters, PKM pk) => filters.All(z => IsFilterMatch(z, pk, Props[Array.IndexOf(Types, pk.GetType())]));
+
+ ///
+ /// Checks if the object is filtered by the provided .
+ ///
+ /// Filters which must be satisfied.
+ /// Object to check.
+ /// True if matches all filters.
+ public static bool IsFilterMatchMeta(IEnumerable filters, SlotCache pk)
+ {
+ foreach (var i in filters)
+ {
+ foreach (var filter in BatchFilters.FilterMeta)
+ {
+ if (!filter.IsMatch(i.PropertyName))
+ continue;
+
+ if (!filter.IsFiltered(pk, i))
+ return false;
+
+ break;
+ }
+ }
+ return true;
+ }
+
+ ///
+ /// Checks if the object is filtered by the provided .
+ ///
+ /// Filters which must be satisfied.
+ /// Object to check.
+ /// True if matches all filters.
+ public static bool IsFilterMatch(IEnumerable filters, object obj)
+ {
+ foreach (var cmd in filters)
+ {
+ if (cmd.PropertyName is PROP_TYPENAME)
+ {
+ if ((obj.GetType().Name == cmd.PropertyValue) != cmd.Evaluator)
+ return false;
+ continue;
+ }
+
+ if (!ReflectUtil.HasProperty(obj, cmd.PropertyName, out var pi))
+ return false;
+ try
+ {
+ if (pi.IsValueEqual(obj, cmd.PropertyValue) == cmd.Evaluator)
+ continue;
+ }
+ // User provided inputs can mismatch the type's required value format, and fail to be compared.
+ catch (Exception e)
+ {
+ Debug.WriteLine($"Unable to compare {cmd.PropertyName} to {cmd.PropertyValue}.");
+ Debug.WriteLine(e.Message);
+ }
+ return false;
+ }
+ return true;
+ }
+
+ ///
+ /// Tries to modify the .
+ ///
+ /// Object to modify.
+ /// Filters which must be satisfied prior to any modifications being made.
+ /// Modifications to perform on the .
+ /// Result of the attempted modification.
+ public static bool TryModify(PKM pk, IEnumerable filters, IEnumerable modifications)
+ {
+ var result = TryModifyPKM(pk, filters, modifications);
+ return result == ModifyResult.Modified;
+ }
+
+ ///
+ /// Tries to modify the .
+ ///
+ /// Command Filter
+ /// Filters which must be satisfied prior to any modifications being made.
+ /// Modifications to perform on the .
+ /// Result of the attempted modification.
+ internal static ModifyResult TryModifyPKM(PKM pk, IEnumerable filters, IEnumerable modifications)
+ {
+ if (!pk.ChecksumValid || pk.Species == 0)
+ return ModifyResult.Invalid;
+
+ var info = new BatchInfo(pk);
+ var pi = Props[Array.IndexOf(Types, pk.GetType())];
+ foreach (var cmd in filters)
+ {
+ try
+ {
+ if (!IsFilterMatch(cmd, info, pi))
+ return ModifyResult.Filtered;
+ }
+ // Swallow any error because this can be malformed user input.
+ catch (Exception ex)
+ {
+ Debug.WriteLine(MsgBEModifyFailCompare + " " + ex.Message, cmd.PropertyName, cmd.PropertyValue);
+ return ModifyResult.Error;
+ }
+ }
+
+ ModifyResult result = ModifyResult.Modified;
+ foreach (var cmd in modifications)
+ {
+ try
+ {
+ var tmp = SetPKMProperty(cmd, info, pi);
+ if (tmp != ModifyResult.Modified)
+ result = tmp;
+ }
+ // Swallow any error because this can be malformed user input.
+ catch (Exception ex)
+ {
+ Debug.WriteLine(MsgBEModifyFail + " " + ex.Message, cmd.PropertyName, cmd.PropertyValue);
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// Sets the if the should be filtered due to the provided.
+ ///
+ /// Command Filter
+ /// Pokémon to check.
+ /// PropertyInfo cache (optional)
+ /// True if filtered, else false.
+ private static ModifyResult SetPKMProperty(StringInstruction cmd, BatchInfo info, IReadOnlyDictionary props)
+ {
+ var pk = info.Entity;
+ if (cmd.PropertyValue.StartsWith(CONST_BYTES, StringComparison.Ordinal))
+ return SetByteArrayProperty(pk, cmd);
+
+ if (cmd.PropertyValue.StartsWith(CONST_SUGGEST, StringComparison.OrdinalIgnoreCase))
+ return SetSuggestedPKMProperty(cmd.PropertyName, info, cmd.PropertyValue);
+ if (cmd.PropertyValue == CONST_RAND && cmd.PropertyName == nameof(PKM.Moves))
+ return SetMoves(pk, info.Legality.GetMoveSet(true));
+
+ if (SetComplexProperty(pk, cmd))
+ return ModifyResult.Modified;
+
+ if (!props.TryGetValue(cmd.PropertyName, out var pi))
+ return ModifyResult.Error;
+
+ if (!pi.CanWrite)
+ return ModifyResult.Error;
+
+ object val;
+ if (cmd.Random)
+ val = cmd.RandomValue;
+ else if (cmd.PropertyValue.StartsWith(CONST_POINTER) && props.TryGetValue(cmd.PropertyValue[1..], out var opi))
+ val = opi.GetValue(pk);
+ else
+ val = cmd.PropertyValue;
+
+ ReflectUtil.SetValue(pi, pk, val);
+ return ModifyResult.Modified;
+ }
+
+ ///
+ /// Checks if the should be filtered due to the provided.
+ ///
+ /// Command Filter
+ /// Pokémon to check.
+ /// PropertyInfo cache (optional)
+ /// True if filter matches, else false.
+ private static bool IsFilterMatch(StringInstruction cmd, BatchInfo info, IReadOnlyDictionary props)
+ {
+ var match = BatchFilters.FilterMods.Find(z => z.IsMatch(cmd.PropertyName));
+ if (match != null)
+ return match.IsFiltered(info, cmd);
+ return IsPropertyFiltered(cmd, info.Entity, props);
+ }
+
+ ///
+ /// Checks if the should be filtered due to the provided.
+ ///
+ /// Command Filter
+ /// Pokémon to check.
+ /// PropertyInfo cache (optional)
+ /// True if filter matches, else false.
+ private static bool IsFilterMatch(StringInstruction cmd, PKM pk, IReadOnlyDictionary props)
+ {
+ var match = BatchFilters.FilterMods.Find(z => z.IsMatch(cmd.PropertyName));
+ if (match != null)
+ return match.IsFiltered(pk, cmd);
+ return IsPropertyFiltered(cmd, pk, props);
+ }
+
+ ///
+ /// Checks if the should be filtered due to the provided.
+ ///
+ /// Command Filter
+ /// Pokémon to check.
+ /// PropertyInfo cache
+ /// True if filtered, else false.
+ private static bool IsPropertyFiltered(StringInstruction cmd, PKM pk, IReadOnlyDictionary props)
+ {
+ if (!props.TryGetValue(cmd.PropertyName, out var pi))
+ return false;
+ if (!pi.CanRead)
+ return false;
+ return pi.IsValueEqual(pk, cmd.PropertyValue) == cmd.Evaluator;
+ }
+
+ ///
+ /// Sets the data with a suggested value based on its .
+ ///
+ /// Property to modify.
+ /// Cached info storing Legal data.
+ /// Suggestion string which starts with
+ private static ModifyResult SetSuggestedPKMProperty(string name, BatchInfo info, string propValue)
+ {
+ var first = BatchMods.SuggestionMods.Find(z => z.IsMatch(name, propValue, info));
+ if (first != null)
+ return first.Modify(name, propValue, info);
+ return ModifyResult.Error;
+ }
+
+ ///
+ /// Sets the byte array property to a specified value.
+ ///
+ /// Pokémon to modify.
+ /// Modification
+ private static ModifyResult SetByteArrayProperty(PKM pk, StringInstruction cmd)
+ {
+ switch (cmd.PropertyName)
+ {
+ case nameof(PKM.Nickname_Trash): ConvertToBytes(cmd.PropertyValue).CopyTo(pk.Nickname_Trash); return ModifyResult.Modified;
+ case nameof(PKM.OT_Trash): ConvertToBytes(cmd.PropertyValue).CopyTo(pk.OT_Trash); return ModifyResult.Modified;
+ case nameof(PKM.HT_Trash): ConvertToBytes(cmd.PropertyValue).CopyTo(pk.HT_Trash); return ModifyResult.Modified;
+ default:
+ return ModifyResult.Error;
+ }
+ static byte[] ConvertToBytes(string str)
+ {
+ var arr = str[CONST_BYTES.Length..].Split(',');
+ return Array.ConvertAll(arr, z => Convert.ToByte(z.Trim(), 16));
+ }
+ }
+
+ ///
+ /// Sets the property to a non-specific smart value.
+ ///
+ /// Pokémon to modify.
+ /// Modification
+ /// True if modified, false if no modifications done.
+ private static bool SetComplexProperty(PKM pk, StringInstruction cmd)
+ {
+ if (cmd.PropertyName.StartsWith("IV", StringComparison.Ordinal) && cmd.PropertyValue == CONST_RAND)
+ {
+ SetRandomIVs(pk, cmd);
+ return true;
+ }
+
+ var match = BatchMods.ComplexMods.Find(z => z.IsMatch(cmd.PropertyName, cmd.PropertyValue));
+ if (match == null)
+ return false;
+
+ match.Modify(pk, cmd);
+ return true;
+ }
+
+ ///
+ /// Sets the IV(s) to a random value.
+ ///
+ /// Pokémon to modify.
+ /// Modification
+ private static void SetRandomIVs(PKM pk, StringInstruction cmd)
+ {
+ if (cmd.PropertyName == nameof(PKM.IVs))
+ {
+ pk.SetRandomIVs();
+ return;
+ }
+
+ if (TryGetHasProperty(pk, cmd.PropertyName, out var pi))
+ ReflectUtil.SetValue(pi, pk, Util.Rand.Next(pk.MaxIV + 1));
+ }
}
diff --git a/PKHeX.Core/Editing/Bulk/BatchEditor.cs b/PKHeX.Core/Editing/Bulk/BatchEditor.cs
index ed6b5ac84..668166541 100644
--- a/PKHeX.Core/Editing/Bulk/BatchEditor.cs
+++ b/PKHeX.Core/Editing/Bulk/BatchEditor.cs
@@ -4,83 +4,82 @@
using System.Linq;
using static PKHeX.Core.MessageStrings;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Carries out a batch edit and contains information summarizing the results.
+///
+public sealed class BatchEditor
{
+ private int Modified { get; set; }
+ private int Iterated { get; set; }
+ private int Failed { get; set; }
+
///
- /// Carries out a batch edit and contains information summarizing the results.
+ /// Tries to modify the .
///
- public sealed class BatchEditor
+ /// Object to modify.
+ /// Filters which must be satisfied prior to any modifications being made.
+ /// Modifications to perform on the .
+ /// Result of the attempted modification.
+ public bool Process(PKM pk, IEnumerable filters, IEnumerable modifications)
{
- private int Modified { get; set; }
- private int Iterated { get; set; }
- private int Failed { get; set; }
-
- ///
- /// Tries to modify the .
- ///
- /// Object to modify.
- /// Filters which must be satisfied prior to any modifications being made.
- /// Modifications to perform on the .
- /// Result of the attempted modification.
- public bool Process(PKM pkm, IEnumerable filters, IEnumerable modifications)
+ if (pk.Species <= 0)
+ return false;
+ if (!pk.Valid)
{
- if (pkm.Species <= 0)
- return false;
- if (!pkm.Valid)
- {
- Iterated++;
- const string reason = "Not Valid.";
- Debug.WriteLine($"{MsgBEModifyFailBlocked} {reason}");
- return false;
- }
-
- var result = BatchEditing.TryModifyPKM(pkm, filters, modifications);
- if (result != ModifyResult.Invalid)
- Iterated++;
- if (result == ModifyResult.Error)
- Failed++;
- if (result != ModifyResult.Modified)
- return false;
-
- pkm.RefreshChecksum();
- Modified++;
- return true;
+ Iterated++;
+ const string reason = "Not Valid.";
+ Debug.WriteLine($"{MsgBEModifyFailBlocked} {reason}");
+ return false;
}
- ///
- /// Gets a message indicating the overall result of all modifications performed across multiple Batch Edit jobs.
- ///
- /// Collection of modifications.
- /// Friendly (multi-line) string indicating the result of the batch edits.
- public string GetEditorResults(ICollection sets)
+ var result = BatchEditing.TryModifyPKM(pk, filters, modifications);
+ if (result != ModifyResult.Invalid)
+ Iterated++;
+ if (result == ModifyResult.Error)
+ Failed++;
+ if (result != ModifyResult.Modified)
+ return false;
+
+ pk.RefreshChecksum();
+ Modified++;
+ return true;
+ }
+
+ ///
+ /// Gets a message indicating the overall result of all modifications performed across multiple Batch Edit jobs.
+ ///
+ /// Collection of modifications.
+ /// Friendly (multi-line) string indicating the result of the batch edits.
+ public string GetEditorResults(ICollection sets)
+ {
+ if (sets.Count == 0)
+ return MsgBEInstructionNone;
+ int ctr = Modified / sets.Count;
+ int len = Iterated / sets.Count;
+ string maybe = sets.Count == 1 ? string.Empty : "~";
+ string result = string.Format(MsgBEModifySuccess, maybe, ctr, len);
+ if (Failed > 0)
+ result += Environment.NewLine + maybe + string.Format(MsgBEModifyFailError, Failed);
+ return result;
+ }
+
+ public static BatchEditor Execute(IList lines, IEnumerable data)
+ {
+ var editor = new BatchEditor();
+ var sets = StringInstructionSet.GetBatchSets(lines).ToArray();
+ foreach (var pk in data)
{
- if (sets.Count == 0)
- return MsgBEInstructionNone;
- int ctr = Modified / sets.Count;
- int len = Iterated / sets.Count;
- string maybe = sets.Count == 1 ? string.Empty : "~";
- string result = string.Format(MsgBEModifySuccess, maybe, ctr, len);
- if (Failed > 0)
- result += Environment.NewLine + maybe + string.Format(MsgBEModifyFailError, Failed);
- return result;
+ foreach (var set in sets)
+ editor.Process(pk, set.Filters, set.Instructions);
}
- public static BatchEditor Execute(IList lines, IEnumerable data)
- {
- var editor = new BatchEditor();
- var sets = StringInstructionSet.GetBatchSets(lines).ToArray();
- foreach (var pk in data)
- {
- foreach (var set in sets)
- editor.Process(pk, set.Filters, set.Instructions);
- }
+ return editor;
+ }
- return editor;
- }
-
- public void AddSkipped()
- {
- ++Iterated;
- }
+ public void AddSkipped()
+ {
+ ++Iterated;
}
}
diff --git a/PKHeX.Core/Editing/Bulk/BatchFilters.cs b/PKHeX.Core/Editing/Bulk/BatchFilters.cs
index b32113aa7..4d244d35e 100644
--- a/PKHeX.Core/Editing/Bulk/BatchFilters.cs
+++ b/PKHeX.Core/Editing/Bulk/BatchFilters.cs
@@ -1,31 +1,30 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
using static PKHeX.Core.BatchEditing;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+public static class BatchFilters
{
- public static class BatchFilters
+ public static readonly List FilterMods = new()
{
- public static readonly List FilterMods = new()
- {
- new ComplexFilter(PROP_LEGAL,
- (pkm, cmd) => bool.TryParse(cmd.PropertyValue, out var b) && (b == new LegalityAnalysis(pkm).Valid) == cmd.Evaluator,
- (info, cmd) => bool.TryParse(cmd.PropertyValue, out var b) && (b == info.Legality.Valid) == cmd.Evaluator),
+ new ComplexFilter(PROP_LEGAL,
+ (pk, cmd) => bool.TryParse(cmd.PropertyValue, out var b) && (b == new LegalityAnalysis(pk).Valid) == cmd.Evaluator,
+ (info, cmd) => bool.TryParse(cmd.PropertyValue, out var b) && (b == info.Legality.Valid) == cmd.Evaluator),
- new ComplexFilter(PROP_TYPENAME,
- (pkm, cmd) => (pkm.GetType().Name == cmd.PropertyValue) == cmd.Evaluator,
- (info, cmd) => (info.Entity.GetType().Name == cmd.PropertyValue) == cmd.Evaluator),
- };
+ new ComplexFilter(PROP_TYPENAME,
+ (pk, cmd) => (pk.GetType().Name == cmd.PropertyValue) == cmd.Evaluator,
+ (info, cmd) => (info.Entity.GetType().Name == cmd.PropertyValue) == cmd.Evaluator),
+ };
- public static readonly List FilterMeta = new()
- {
- new MetaFilter(IdentifierContains,
- (obj, cmd) => obj is SlotCache s && s.Identify().Contains(cmd.PropertyValue) == cmd.Evaluator),
+ public static readonly List FilterMeta = new()
+ {
+ new MetaFilter(IdentifierContains,
+ (obj, cmd) => obj is SlotCache s && s.Identify().Contains(cmd.PropertyValue) == cmd.Evaluator),
- new MetaFilter(nameof(SlotInfoBox.Box),
- (obj, cmd) => obj is SlotCache { Source: SlotInfoBox b } && int.TryParse(cmd.PropertyValue, out var box) && b.Box + 1 == box),
+ new MetaFilter(nameof(SlotInfoBox.Box),
+ (obj, cmd) => obj is SlotCache { Source: SlotInfoBox b } && int.TryParse(cmd.PropertyValue, out var box) && b.Box + 1 == box),
- new MetaFilter(nameof(ISlotInfo.Slot),
- (obj, cmd) => obj is SlotCache s && int.TryParse(cmd.PropertyValue, out var slot) && s.Source.Slot + 1 == slot),
- };
- }
+ new MetaFilter(nameof(ISlotInfo.Slot),
+ (obj, cmd) => obj is SlotCache s && int.TryParse(cmd.PropertyValue, out var slot) && s.Source.Slot + 1 == slot),
+ };
}
diff --git a/PKHeX.Core/Editing/Bulk/BatchInfo.cs b/PKHeX.Core/Editing/Bulk/BatchInfo.cs
index a0a2534d9..54a991fdd 100644
--- a/PKHeX.Core/Editing/Bulk/BatchInfo.cs
+++ b/PKHeX.Core/Editing/Bulk/BatchInfo.cs
@@ -1,19 +1,18 @@
using System.Collections.Generic;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Information wrapper used for Batch Editing to apply suggested values.
+///
+public sealed class BatchInfo
{
- ///
- /// Information wrapper used for Batch Editing to apply suggested values.
- ///
- public sealed class BatchInfo
- {
- internal PKM Entity { get; }
- internal BatchInfo(PKM pk) => Entity = pk;
+ internal PKM Entity { get; }
+ internal BatchInfo(PKM pk) => Entity = pk;
- private LegalityAnalysis? la;
- internal LegalityAnalysis Legality => la ??= new LegalityAnalysis(Entity);
+ private LegalityAnalysis? la;
+ internal LegalityAnalysis Legality => la ??= new LegalityAnalysis(Entity);
- public bool Legal => Legality.Valid;
- internal IReadOnlyList SuggestedRelearn => Legality.GetSuggestedRelearnMoves();
- }
+ public bool Legal => Legality.Valid;
+ internal IReadOnlyList SuggestedRelearn => Legality.GetSuggestedRelearnMoves();
}
diff --git a/PKHeX.Core/Editing/Bulk/BatchMods.cs b/PKHeX.Core/Editing/Bulk/BatchMods.cs
index d4992ba5e..624216e13 100644
--- a/PKHeX.Core/Editing/Bulk/BatchMods.cs
+++ b/PKHeX.Core/Editing/Bulk/BatchMods.cs
@@ -3,95 +3,94 @@
using System.Globalization;
using static PKHeX.Core.BatchEditing;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+public static class BatchMods
{
- public static class BatchMods
+ public static readonly List SuggestionMods = new()
{
- public static readonly List SuggestionMods = new()
- {
- // Interface Specific
- new TypeSuggestion(nameof(ICombatPower.Stat_CP), p => p.ResetCP()),
- new TypeSuggestion(nameof(IScaledSizeValue.HeightAbsolute), p => p.ResetHeight()),
- new TypeSuggestion(nameof(IScaledSizeValue.WeightAbsolute), p => p.ResetWeight()),
- new TypeSuggestion(nameof(Extensions.HyperTrainClear), p => p.HyperTrainClear()),
- new TypeSuggestion(nameof(Extensions.ClearGeoLocationData), p => p.ClearGeoLocationData()),
- new TypeSuggestion(nameof(Extensions.AwakeningClear), p => p.AwakeningClear()),
- new TypeSuggestion(nameof(Extensions.AwakeningMax), p => p.AwakeningMax()),
- new TypeSuggestion(nameof(GanbaruExtensions.ClearGanbaruValues), p => p.ClearGanbaruValues()),
- new TypeSuggestion(nameof(GanbaruExtensions.SetSuggestedGanbaruValues), p => p.SetSuggestedGanbaruValues((PKM)p)),
+ // Interface Specific
+ new TypeSuggestion(nameof(ICombatPower.Stat_CP), p => p.ResetCP()),
+ new TypeSuggestion(nameof(IScaledSizeValue.HeightAbsolute), p => p.ResetHeight()),
+ new TypeSuggestion(nameof(IScaledSizeValue.WeightAbsolute), p => p.ResetWeight()),
+ new TypeSuggestion(nameof(Extensions.HyperTrainClear), p => p.HyperTrainClear()),
+ new TypeSuggestion(nameof(Extensions.ClearGeoLocationData), p => p.ClearGeoLocationData()),
+ new TypeSuggestion(nameof(Extensions.AwakeningClear), p => p.AwakeningClear()),
+ new TypeSuggestion(nameof(Extensions.AwakeningMax), p => p.AwakeningMax()),
+ new TypeSuggestion(nameof(GanbaruExtensions.ClearGanbaruValues), p => p.ClearGanbaruValues()),
+ new TypeSuggestion(nameof(GanbaruExtensions.SetSuggestedGanbaruValues), p => p.SetSuggestedGanbaruValues((PKM)p)),
- // Date Copy
- new TypeSuggestion(nameof(PKM.EggMetDate), p => p.EggMetDate = p.MetDate),
- new TypeSuggestion(nameof(PKM.MetDate), p => p.MetDate = p.EggMetDate),
+ // Date Copy
+ new TypeSuggestion(nameof(PKM.EggMetDate), p => p.EggMetDate = p.MetDate),
+ new TypeSuggestion(nameof(PKM.MetDate), p => p.MetDate = p.EggMetDate),
- new TypeSuggestion(nameof(PKM.Nature), p => p.Format >= 8, p => p.Nature = p.StatNature),
- new TypeSuggestion(nameof(PKM.StatNature), p => p.Format >= 8, p => p.StatNature = p.Nature),
- new TypeSuggestion(nameof(PKM.Stats), p => p.ResetPartyStats()),
- new TypeSuggestion(nameof(PKM.Ball), p => BallApplicator.ApplyBallLegalByColor(p)),
- new TypeSuggestion(nameof(PKM.Heal), p => p.Heal()),
- new TypeSuggestion(nameof(PKM.HealPP), p => p.HealPP()),
- new TypeSuggestion(nameof(IHyperTrain.HyperTrainFlags), p => p.SetSuggestedHyperTrainingData()),
+ new TypeSuggestion(nameof(PKM.Nature), p => p.Format >= 8, p => p.Nature = p.StatNature),
+ new TypeSuggestion(nameof(PKM.StatNature), p => p.Format >= 8, p => p.StatNature = p.Nature),
+ new TypeSuggestion(nameof(PKM.Stats), p => p.ResetPartyStats()),
+ new TypeSuggestion(nameof(PKM.Ball), p => BallApplicator.ApplyBallLegalByColor(p)),
+ new TypeSuggestion(nameof(PKM.Heal), p => p.Heal()),
+ new TypeSuggestion(nameof(PKM.HealPP), p => p.HealPP()),
+ new TypeSuggestion(nameof(IHyperTrain.HyperTrainFlags), p => p.SetSuggestedHyperTrainingData()),
- new TypeSuggestion(nameof(PKM.Move1_PP), p => p.SetSuggestedMovePP(0)),
- new TypeSuggestion(nameof(PKM.Move2_PP), p => p.SetSuggestedMovePP(1)),
- new TypeSuggestion(nameof(PKM.Move3_PP), p => p.SetSuggestedMovePP(2)),
- new TypeSuggestion(nameof(PKM.Move4_PP), p => p.SetSuggestedMovePP(3)),
+ new TypeSuggestion(nameof(PKM.Move1_PP), p => p.SetSuggestedMovePP(0)),
+ new TypeSuggestion(nameof(PKM.Move2_PP), p => p.SetSuggestedMovePP(1)),
+ new TypeSuggestion(nameof(PKM.Move3_PP), p => p.SetSuggestedMovePP(2)),
+ new TypeSuggestion(nameof(PKM.Move4_PP), p => p.SetSuggestedMovePP(3)),
- new ComplexSuggestion(nameof(PKM.Moves), (_, _, info) => BatchModifications.SetMoves(info.Entity, info.Legality.GetMoveSet())),
- new ComplexSuggestion(nameof(PKM.EVs), (_, _, info) => BatchModifications.SetEVs(info.Entity)),
- new ComplexSuggestion(nameof(PKM.RelearnMoves), (_, value, info) => BatchModifications.SetSuggestedRelearnData(info, value)),
- new ComplexSuggestion(PROP_RIBBONS, (_, value, info) => BatchModifications.SetSuggestedRibbons(info, value)),
- new ComplexSuggestion(nameof(PKM.Met_Location), (_, _, info) => BatchModifications.SetSuggestedMetData(info)),
- new ComplexSuggestion(nameof(PKM.CurrentLevel), (_, _, info) => BatchModifications.SetMinimumCurrentLevel(info)),
- new ComplexSuggestion(PROP_CONTESTSTATS, p => p is IContestStatsMutable, (_, value, info) => BatchModifications.SetContestStats(info.Entity, info.Legality, value)),
- new ComplexSuggestion(PROP_MOVEMASTERY, (_, value, info) => BatchModifications.SetSuggestedMasteryData(info, value)),
- };
+ new ComplexSuggestion(nameof(PKM.Moves), (_, _, info) => BatchModifications.SetMoves(info.Entity, info.Legality.GetMoveSet())),
+ new ComplexSuggestion(nameof(PKM.EVs), (_, _, info) => BatchModifications.SetEVs(info.Entity)),
+ new ComplexSuggestion(nameof(PKM.RelearnMoves), (_, value, info) => BatchModifications.SetSuggestedRelearnData(info, value)),
+ new ComplexSuggestion(PROP_RIBBONS, (_, value, info) => BatchModifications.SetSuggestedRibbons(info, value)),
+ new ComplexSuggestion(nameof(PKM.Met_Location), (_, _, info) => BatchModifications.SetSuggestedMetData(info)),
+ new ComplexSuggestion(nameof(PKM.CurrentLevel), (_, _, info) => BatchModifications.SetMinimumCurrentLevel(info)),
+ new ComplexSuggestion(PROP_CONTESTSTATS, p => p is IContestStatsMutable, (_, value, info) => BatchModifications.SetContestStats(info.Entity, info.Legality, value)),
+ new ComplexSuggestion(PROP_MOVEMASTERY, (_, value, info) => BatchModifications.SetSuggestedMasteryData(info, value)),
+ };
- private static DateTime ParseDate(string val) => DateTime.ParseExact(val, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None);
+ private static DateTime ParseDate(string val) => DateTime.ParseExact(val, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.None);
- public static readonly List ComplexMods = new()
- {
- // Date
- new ComplexSet(nameof(PKM.MetDate), (pk, cmd) => pk.MetDate = ParseDate(cmd.PropertyValue)),
- new ComplexSet(nameof(PKM.EggMetDate), (pk, cmd) => pk.EggMetDate = ParseDate(cmd.PropertyValue)),
+ public static readonly List ComplexMods = new()
+ {
+ // Date
+ new ComplexSet(nameof(PKM.MetDate), (pk, cmd) => pk.MetDate = ParseDate(cmd.PropertyValue)),
+ new ComplexSet(nameof(PKM.EggMetDate), (pk, cmd) => pk.EggMetDate = ParseDate(cmd.PropertyValue)),
- // Value Swap
- new ComplexSet(nameof(PKM.EncryptionConstant), value => value == nameof(PKM.PID), (pk, _) => pk.EncryptionConstant = pk.PID),
- new ComplexSet(nameof(PKM.PID), value => value == nameof(PKM.EncryptionConstant), (pk, _) => pk.PID = pk.EncryptionConstant),
+ // Value Swap
+ new ComplexSet(nameof(PKM.EncryptionConstant), value => value == nameof(PKM.PID), (pk, _) => pk.EncryptionConstant = pk.PID),
+ new ComplexSet(nameof(PKM.PID), value => value == nameof(PKM.EncryptionConstant), (pk, _) => pk.PID = pk.EncryptionConstant),
- // Realign to Derived Value
- new ComplexSet(nameof(PKM.Ability), value => value.StartsWith("$"), (pk, cmd) => pk.RefreshAbility(Convert.ToInt16(cmd.PropertyValue[1]) - 0x30)),
- new ComplexSet(nameof(PKM.AbilityNumber), value => value.StartsWith("$"), (pk, cmd) => pk.RefreshAbility(Convert.ToInt16(cmd.PropertyValue[1]) - 0x30)),
+ // Realign to Derived Value
+ new ComplexSet(nameof(PKM.Ability), value => value.StartsWith(CONST_SPECIAL), (pk, cmd) => pk.RefreshAbility(Convert.ToInt16(cmd.PropertyValue[1]) - 0x30)),
+ new ComplexSet(nameof(PKM.AbilityNumber), value => value.StartsWith(CONST_SPECIAL), (pk, cmd) => pk.RefreshAbility(Convert.ToInt16(cmd.PropertyValue[1]) - 0x30)),
- // Random
- new ComplexSet(nameof(PKM.EncryptionConstant), value => value == CONST_RAND, (pk, _) => pk.EncryptionConstant = Util.Rand32()),
- new ComplexSet(nameof(PKM.PID), value => value == CONST_RAND, (pk, _) => pk.PID = Util.Rand32()),
- new ComplexSet(nameof(PKM.Gender), value => value == CONST_RAND, (pk, _) => pk.SetPIDGender(pk.Gender)),
- new ComplexSet(nameof(PKM.EVs), value => value == CONST_RAND, (pk, _) => SetRandomEVs(pk)),
+ // Random
+ new ComplexSet(nameof(PKM.EncryptionConstant), value => value == CONST_RAND, (pk, _) => pk.EncryptionConstant = Util.Rand32()),
+ new ComplexSet(nameof(PKM.PID), value => value == CONST_RAND, (pk, _) => pk.PID = Util.Rand32()),
+ new ComplexSet(nameof(PKM.Gender), value => value == CONST_RAND, (pk, _) => pk.SetPIDGender(pk.Gender)),
+ new ComplexSet(nameof(PKM.EVs), value => value == CONST_RAND, (pk, _) => SetRandomEVs(pk)),
- // Shiny
- new ComplexSet(nameof(PKM.PID),
- value => value.StartsWith(CONST_SHINY, true, CultureInfo.CurrentCulture),
- (pk, cmd) => CommonEdits.SetShiny(pk, GetRequestedShinyState(cmd.PropertyValue))),
+ // Shiny
+ new ComplexSet(nameof(PKM.PID),
+ value => value.StartsWith(CONST_SHINY, true, CultureInfo.CurrentCulture),
+ (pk, cmd) => CommonEdits.SetShiny(pk, GetRequestedShinyState(cmd.PropertyValue))),
- new ComplexSet(nameof(PKM.Species), value => value == "0", (pk, _) => Array.Clear(pk.Data, 0, pk.Data.Length)),
- new ComplexSet(nameof(PKM.IsNicknamed), value => string.Equals(value, "false", StringComparison.OrdinalIgnoreCase), (pk, _) => pk.SetDefaultNickname()),
- };
+ new ComplexSet(nameof(PKM.Species), value => value == "0", (pk, _) => Array.Clear(pk.Data, 0, pk.Data.Length)),
+ new ComplexSet(nameof(PKM.IsNicknamed), value => string.Equals(value, "false", StringComparison.OrdinalIgnoreCase), (pk, _) => pk.SetDefaultNickname()),
+ };
- private static void SetRandomEVs(PKM pk)
- {
- Span evs = stackalloc int[6];
- EffortValues.SetRandom(evs, pk.Format);
- pk.SetEVs(evs);
- }
-
- private static Shiny GetRequestedShinyState(string text)
- {
- if (text.EndsWith("0"))
- return Shiny.AlwaysSquare;
- if (text.EndsWith("1"))
- return Shiny.AlwaysStar;
- return Shiny.Random;
- }
+ private static void SetRandomEVs(PKM pk)
+ {
+ Span evs = stackalloc int[6];
+ EffortValues.SetRandom(evs, pk.Format);
+ pk.SetEVs(evs);
}
+
+ private static Shiny GetRequestedShinyState(string text) => text.Length == 0 ? Shiny.Random : GetRequestedShinyState(text[^1]);
+
+ private static Shiny GetRequestedShinyState(char last) => last switch
+ {
+ '0' => Shiny.AlwaysSquare,
+ '1' => Shiny.AlwaysStar,
+ _ => Shiny.Random,
+ };
}
diff --git a/PKHeX.Core/Editing/Bulk/ComplexSet/ComplexFilter.cs b/PKHeX.Core/Editing/Bulk/ComplexSet/ComplexFilter.cs
index efc98373d..b16f7e445 100644
--- a/PKHeX.Core/Editing/Bulk/ComplexSet/ComplexFilter.cs
+++ b/PKHeX.Core/Editing/Bulk/ComplexSet/ComplexFilter.cs
@@ -1,26 +1,25 @@
using System;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+public sealed class ComplexFilter : IComplexFilter
{
- ///
- public sealed class ComplexFilter : IComplexFilter
+ private readonly string Property;
+ private readonly Func FilterPKM;
+ private readonly Func FilterBulk;
+
+ public ComplexFilter(
+ string property,
+ Func filterPkm,
+ Func filterBulk)
{
- private readonly string Property;
- private readonly Func FilterPKM;
- private readonly Func FilterBulk;
-
- public ComplexFilter(
- string property,
- Func filterPkm,
- Func filterBulk)
- {
- Property = property;
- FilterPKM = filterPkm;
- FilterBulk = filterBulk;
- }
-
- public bool IsMatch(string prop) => prop == Property;
- public bool IsFiltered(PKM pkm, StringInstruction cmd) => FilterPKM(pkm, cmd);
- public bool IsFiltered(BatchInfo info, StringInstruction cmd) => FilterBulk(info, cmd);
+ Property = property;
+ FilterPKM = filterPkm;
+ FilterBulk = filterBulk;
}
+
+ public bool IsMatch(string prop) => prop == Property;
+ public bool IsFiltered(PKM pk, StringInstruction value) => FilterPKM(pk, value);
+ public bool IsFiltered(BatchInfo info, StringInstruction value) => FilterBulk(info, value);
}
diff --git a/PKHeX.Core/Editing/Bulk/ComplexSet/ComplexSet.cs b/PKHeX.Core/Editing/Bulk/ComplexSet/ComplexSet.cs
index 165e7b4b5..a388862d2 100644
--- a/PKHeX.Core/Editing/Bulk/ComplexSet/ComplexSet.cs
+++ b/PKHeX.Core/Editing/Bulk/ComplexSet/ComplexSet.cs
@@ -1,24 +1,23 @@
using System;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+public sealed class ComplexSet : IComplexSet
{
- ///
- public sealed class ComplexSet : IComplexSet
+ public readonly string PropertyName;
+ public readonly Func IsValueCompatible = _ => true;
+ private readonly Action Action;
+
+ public ComplexSet(string propertyName, Action modify)
{
- public readonly string PropertyName;
- public readonly Func IsValueCompatible = _ => true;
- private readonly Action Action;
-
- public ComplexSet(string propertyName, Action modify)
- {
- PropertyName = propertyName;
- Action = modify;
- }
-
- public ComplexSet(string propertyName, Func criteria, Action modify) : this(propertyName, modify) => IsValueCompatible = criteria;
-
- public bool IsMatch(string name, string value) => name == PropertyName && IsValueCompatible(value);
-
- public void Modify(PKM pk, StringInstruction instr) => Action(pk, instr);
+ PropertyName = propertyName;
+ Action = modify;
}
+
+ public ComplexSet(string propertyName, Func criteria, Action modify) : this(propertyName, modify) => IsValueCompatible = criteria;
+
+ public bool IsMatch(string name, string value) => name == PropertyName && IsValueCompatible(value);
+
+ public void Modify(PKM pk, StringInstruction instr) => Action(pk, instr);
}
diff --git a/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexFilter.cs b/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexFilter.cs
index ae43cc5f4..f605a347f 100644
--- a/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexFilter.cs
+++ b/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexFilter.cs
@@ -1,12 +1,11 @@
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Complex filter of data based on a string value.
+///
+public interface IComplexFilter
{
- ///
- /// Complex filter of data based on a string value.
- ///
- public interface IComplexFilter
- {
- bool IsMatch(string prop);
- bool IsFiltered(PKM pkm, StringInstruction value);
- bool IsFiltered(BatchInfo info, StringInstruction value);
- }
+ bool IsMatch(string prop);
+ bool IsFiltered(PKM pk, StringInstruction value);
+ bool IsFiltered(BatchInfo info, StringInstruction value);
}
diff --git a/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexFilterMeta.cs b/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexFilterMeta.cs
index c21e88ad6..aed61f80f 100644
--- a/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexFilterMeta.cs
+++ b/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexFilterMeta.cs
@@ -1,11 +1,10 @@
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Complex filter of data based on a string value.
+///
+public interface IComplexFilterMeta
{
- ///
- /// Complex filter of data based on a string value.
- ///
- public interface IComplexFilterMeta
- {
- bool IsMatch(string prop);
- bool IsFiltered(object cache, StringInstruction value);
- }
+ bool IsMatch(string prop);
+ bool IsFiltered(object cache, StringInstruction value);
}
diff --git a/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexSet.cs b/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexSet.cs
index 1042dee85..a5626f853 100644
--- a/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexSet.cs
+++ b/PKHeX.Core/Editing/Bulk/ComplexSet/IComplexSet.cs
@@ -1,11 +1,10 @@
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+/// Complex modification of data to a string value.
+///
+public interface IComplexSet
{
- ///
- /// Complex modification of data to a string value.
- ///
- public interface IComplexSet
- {
- bool IsMatch(string name, string value);
- void Modify(PKM pk, StringInstruction instr);
- }
+ bool IsMatch(string name, string value);
+ void Modify(PKM pk, StringInstruction instr);
}
diff --git a/PKHeX.Core/Editing/Bulk/ComplexSet/MetaFilter.cs b/PKHeX.Core/Editing/Bulk/ComplexSet/MetaFilter.cs
index 0d8de2ead..c6d0da6a3 100644
--- a/PKHeX.Core/Editing/Bulk/ComplexSet/MetaFilter.cs
+++ b/PKHeX.Core/Editing/Bulk/ComplexSet/MetaFilter.cs
@@ -1,22 +1,21 @@
using System;
-namespace PKHeX.Core
+namespace PKHeX.Core;
+
+///
+public sealed class MetaFilter : IComplexFilterMeta
{
- ///
- public sealed class MetaFilter : IComplexFilterMeta
+ private readonly string Property;
+ private readonly Func