From 0f4024952e1dc1f7df70112c7f719a755ca3eb7c Mon Sep 17 00:00:00 2001 From: Kurt Date: Wed, 1 May 2024 00:49:43 -0500 Subject: [PATCH] Minor clean indexof -> contains trailing space some variable reuse pcdata/boxdata less janky handling --- PKHeX.Core/Editing/CommonEdits.cs | 65 ++++++++++--------- PKHeX.Core/Editing/Showdown/ShowdownSet.cs | 14 ++-- .../Templates/Gen8a/EncounterArea8a.cs | 5 +- .../LearnSource/Sources/LearnSource8BDSP.cs | 2 +- .../LearnSource/Sources/LearnSource8SWSH.cs | 2 +- .../LearnSource/Sources/LearnSource9SV.cs | 6 +- PKHeX.Core/Legality/Learnset/Learnset.cs | 4 +- .../Legality/Moves/Breeding/MoveBreed2.cs | 2 +- .../Legality/Moves/Breeding/MoveBreed3.cs | 2 +- .../Legality/Moves/Breeding/MoveBreed4.cs | 2 +- .../Legality/Moves/Breeding/MoveBreed5.cs | 2 +- .../Legality/Moves/Breeding/MoveBreed6.cs | 2 +- PKHeX.Core/Legality/RNG/Algorithms/XDRNG.cs | 10 +-- .../Legality/Verifiers/EffortValueVerifier.cs | 23 +++++-- .../Verifiers/IndividualValueVerifier.cs | 6 +- .../Verifiers/LegendsArceusVerifier.cs | 2 +- PKHeX.Core/MysteryGifts/WA8.cs | 6 +- PKHeX.Core/MysteryGifts/WB7.cs | 6 +- PKHeX.Core/MysteryGifts/WB8.cs | 6 +- PKHeX.Core/MysteryGifts/WC6.cs | 6 +- PKHeX.Core/MysteryGifts/WC7.cs | 6 +- PKHeX.Core/MysteryGifts/WC8.cs | 6 +- PKHeX.Core/MysteryGifts/WC9.cs | 6 +- PKHeX.Core/PKM/Strings/Font/StringFont8b.cs | 2 +- PKHeX.Core/Saves/SaveFile.cs | 19 ++++-- .../Saves/Substructures/Gen6/MyItem6XY.cs | 2 +- .../Substructures/Gen9/RaidSevenStar9.cs | 2 +- .../Substructures/Time/Epoch0000DateTime.cs | 2 +- PKHeX.Core/Saves/Util/DexFormUtil.cs | 36 +++++----- PKHeX.Core/Util/ArrayUtil.cs | 21 ------ PKHeX.Core/Util/FileUtil.cs | 54 +++++++++++---- PKHeX.WinForms/MainWindow/Main.cs | 7 +- .../Save Editors/Gen6/SAV_SecretBase.cs | 2 +- Tests/PKHeX.Core.Tests/Saves/SMTests.cs | 2 +- 34 files changed, 190 insertions(+), 150 deletions(-) diff --git a/PKHeX.Core/Editing/CommonEdits.cs b/PKHeX.Core/Editing/CommonEdits.cs index 27ded6590..5add1f96d 100644 --- a/PKHeX.Core/Editing/CommonEdits.cs +++ b/PKHeX.Core/Editing/CommonEdits.cs @@ -158,61 +158,66 @@ public static class CommonEdits /// Copies details to the . /// /// Pokémon to modify. - /// details to copy from. - public static void ApplySetDetails(this PKM pk, IBattleTemplate Set) + /// details to copy from. + public static void ApplySetDetails(this PKM pk, IBattleTemplate set) { - pk.Species = Math.Min(pk.MaxSpeciesID, Set.Species); - pk.Form = Set.Form; - if (Set.Moves[0] != 0) - pk.SetMoves(Set.Moves, true); - pk.ApplyHeldItem(Set.HeldItem, Set.Context); - pk.CurrentLevel = Set.Level; - pk.CurrentFriendship = Set.Friendship; - pk.SetIVs(Set.IVs); + pk.Species = Math.Min(pk.MaxSpeciesID, set.Species); + pk.Form = set.Form; + + ReadOnlySpan moves = set.Moves; + if (moves[0] != 0) + pk.SetMoves(moves, true); + if (Legal.IsPPUpAvailable(pk)) + pk.SetMaximumPPUps(moves); + + pk.ApplyHeldItem(set.HeldItem, set.Context); + pk.CurrentLevel = set.Level; + pk.CurrentFriendship = set.Friendship; + + ReadOnlySpan ivs = set.IVs; + ReadOnlySpan evs = set.EVs; + pk.SetIVs(ivs); if (pk is GBPKM gb) { // In Generation 1/2 Format sets, when IVs are not specified with a Hidden Power set, we might not have the hidden power type. // Under this scenario, just force the Hidden Power type. - if (Array.IndexOf(Set.Moves, (ushort)Move.HiddenPower) != -1 && gb.HPType != Set.HiddenPowerType) + if (moves.Contains((ushort)Move.HiddenPower) && gb.HPType != set.HiddenPowerType) { - if (Set.IVs.AsSpan().ContainsAny(30, 31)) - gb.SetHiddenPower(Set.HiddenPowerType); + if (ivs.ContainsAny(30, 31)) + gb.SetHiddenPower(set.HiddenPowerType); } // In Generation 1/2 Format sets, when EVs are not specified at all, it implies maximum EVs instead! // Under this scenario, just apply maximum EVs (65535). - if (!Set.EVs.AsSpan().ContainsAnyExcept(0)) + if (!evs.ContainsAnyExcept(0)) gb.MaxEVs(); else - gb.SetEVs(Set.EVs); + gb.SetEVs(evs); } else { - pk.SetEVs(Set.EVs); + pk.SetEVs(evs); } // IVs have no side effects such as hidden power type in gen 8 // therefore all specified IVs are deliberate and should not be Hyper Trained for Pokémon met in gen 8 if (pk.Generation < 8) - pk.SetSuggestedHyperTrainingData(Set.IVs); + pk.SetSuggestedHyperTrainingData(ivs); if (ShowdownSetIVMarkings) pk.SetMarkings(); - pk.SetNickname(Set.Nickname); - pk.SetSaneGender(Set.Gender); - - if (Legal.IsPPUpAvailable(pk)) - pk.SetMaximumPPUps(Set.Moves); + pk.SetNickname(set.Nickname); + pk.SetSaneGender(set.Gender); if (pk.Format >= 3) { - pk.SetAbility(Set.Ability); - pk.SetNature(Set.Nature); + pk.SetAbility(set.Ability); + pk.SetNature(set.Nature); } - pk.SetIsShiny(Set.Shiny); + pk.SetIsShiny(set.Shiny); pk.SetRandomEC(); if (pk is IAwakened a) @@ -229,17 +234,17 @@ public static class CommonEdits g.SetSuggestedGanbaruValues(pk); if (pk is IGigantamax c) - c.CanGigantamax = Set.CanGigantamax; + c.CanGigantamax = set.CanGigantamax; if (pk is IDynamaxLevel d) - d.DynamaxLevel = d.GetSuggestedDynamaxLevel(pk, requested: Set.DynamaxLevel); + d.DynamaxLevel = d.GetSuggestedDynamaxLevel(pk, requested: set.DynamaxLevel); if (pk is ITeraType tera) { - var type = Set.TeraType == MoveType.Any ? (MoveType)pk.PersonalInfo.Type1 : Set.TeraType; + var type = set.TeraType == MoveType.Any ? (MoveType)pk.PersonalInfo.Type1 : set.TeraType; tera.SetTeraType(type); } if (pk is IMoveShop8Mastery s) - s.SetMoveShopFlags(Set.Moves, pk); + s.SetMoveShopFlags(set.Moves, pk); if (ShowdownSetBehaviorNature && pk.Format >= 8) pk.Nature = pk.StatNature; @@ -248,7 +253,7 @@ public static class CommonEdits if (pk is ITechRecord t) { t.ClearRecordFlags(); - t.SetRecordFlags(Set.Moves, legal.Info.EvoChainsAllGens.Get(pk.Context)); + t.SetRecordFlags(set.Moves, legal.Info.EvoChainsAllGens.Get(pk.Context)); } if (legal.Parsed && !MoveResult.AllValid(legal.Info.Relearn)) pk.SetRelearnMoves(legal); diff --git a/PKHeX.Core/Editing/Showdown/ShowdownSet.cs b/PKHeX.Core/Editing/Showdown/ShowdownSet.cs index 4fec1693b..e94ab5a4a 100644 --- a/PKHeX.Core/Editing/Showdown/ShowdownSet.cs +++ b/PKHeX.Core/Editing/Showdown/ShowdownSet.cs @@ -212,16 +212,17 @@ public sealed class ShowdownSet : IBattleTemplate private bool ParseLine(ReadOnlySpan line, ref int movectr) { + var moves = Moves.AsSpan(); if (line[0] is '-' or '–') { var moveString = ParseLineMove(line); int move = StringUtil.FindIndexIgnoreCase(Strings.movelist, moveString); if (move < 0) InvalidLines.Add($"Unknown Move: {moveString}"); - else if (Array.IndexOf(Moves, (ushort)move) != -1) + else if (moves.Contains((ushort)move)) InvalidLines.Add($"Duplicate Move: {moveString}"); else - Moves[movectr++] = (ushort)move; + moves[movectr++] = (ushort)move; return movectr == MaxMoveCount; } @@ -507,7 +508,12 @@ public sealed class ShowdownSet : IBattleTemplate Ability = pk.Ability; pk.GetEVs(EVs); pk.GetIVs(IVs); - pk.GetMoves(Moves); + + var moves = Moves.AsSpan(); + pk.GetMoves(moves); + if (moves.Contains((ushort)Move.HiddenPower)) + HiddenPowerType = HiddenPower.GetType(IVs, Context); + Nature = pk.StatNature; Gender = pk.Gender < 2 ? pk.Gender : (byte)2; Friendship = pk.CurrentFriendship; @@ -520,8 +526,6 @@ public sealed class ShowdownSet : IBattleTemplate DynamaxLevel = g.DynamaxLevel; } - if (Array.IndexOf(Moves, (ushort)Move.HiddenPower) != -1) - HiddenPowerType = HiddenPower.GetType(IVs, Context); if (pk is ITeraType t) TeraType = t.TeraType; if (pk is IHyperTrain h) diff --git a/PKHeX.Core/Legality/Encounters/Templates/Gen8a/EncounterArea8a.cs b/PKHeX.Core/Legality/Encounters/Templates/Gen8a/EncounterArea8a.cs index 974d66bd2..068eec0ce 100644 --- a/PKHeX.Core/Legality/Encounters/Templates/Gen8a/EncounterArea8a.cs +++ b/PKHeX.Core/Legality/Encounters/Templates/Gen8a/EncounterArea8a.cs @@ -25,10 +25,7 @@ public sealed record EncounterArea8a : IEncounterArea, IAreaLoc public ushort Location => Locations[0]; - public bool IsMatchLocation(ushort location) - { - return Array.IndexOf(Locations, (byte)location) != -1; - } + public bool IsMatchLocation(ushort location) => Locations.AsSpan().Contains((byte)location); public static EncounterArea8a[] GetAreas(BinLinkerAccessor input) { diff --git a/PKHeX.Core/Legality/LearnSource/Sources/LearnSource8BDSP.cs b/PKHeX.Core/Legality/LearnSource/Sources/LearnSource8BDSP.cs index 77ec71ed6..efbaa81f2 100644 --- a/PKHeX.Core/Legality/LearnSource/Sources/LearnSource8BDSP.cs +++ b/PKHeX.Core/Legality/LearnSource/Sources/LearnSource8BDSP.cs @@ -86,7 +86,7 @@ public sealed class LearnSource8BDSP : ILearnSource, IEggSour { var baseSpecies = pi.HatchSpecies; var baseForm = pi.HatchFormIndex; - return GetEggMoves(baseSpecies, baseForm).IndexOf(move) != -1; + return GetEggMoves(baseSpecies, baseForm).Contains(move); } public void GetAllMoves(Span result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All) diff --git a/PKHeX.Core/Legality/LearnSource/Sources/LearnSource8SWSH.cs b/PKHeX.Core/Legality/LearnSource/Sources/LearnSource8SWSH.cs index 1790416a5..dc20b852d 100644 --- a/PKHeX.Core/Legality/LearnSource/Sources/LearnSource8SWSH.cs +++ b/PKHeX.Core/Legality/LearnSource/Sources/LearnSource8SWSH.cs @@ -98,7 +98,7 @@ public sealed class LearnSource8SWSH : ILearnSource, IEggSour { var baseSpecies = pi.HatchSpecies; var baseForm = pi.HatchFormIndexEverstone; - return GetEggMoves(baseSpecies, baseForm).IndexOf(move) != -1; + return GetEggMoves(baseSpecies, baseForm).Contains(move); } private static bool GetIsTR(PersonalInfo8SWSH info, PKM pk, EvoCriteria evo, ushort move, LearnOption option) diff --git a/PKHeX.Core/Legality/LearnSource/Sources/LearnSource9SV.cs b/PKHeX.Core/Legality/LearnSource/Sources/LearnSource9SV.cs index 5d8855aa0..45d461f60 100644 --- a/PKHeX.Core/Legality/LearnSource/Sources/LearnSource9SV.cs +++ b/PKHeX.Core/Legality/LearnSource/Sources/LearnSource9SV.cs @@ -35,7 +35,7 @@ public sealed class LearnSource9SV : ILearnSource, IEggSource, if (index >= EggMoves.Length) return false; var moves = EggMoves[index].AsSpan(); - return moves.IndexOf(move) != -1; + return moves.Contains(move); } public ReadOnlySpan GetEggMoves(ushort species, byte form) @@ -52,7 +52,7 @@ public sealed class LearnSource9SV : ILearnSource, IEggSource, if (index >= Reminder.Length) return false; var moves = Reminder[index].AsSpan(); - return moves.IndexOf(move) != -1; + return moves.Contains(move); } public ReadOnlySpan GetReminderMoves(ushort species, byte form) @@ -146,7 +146,7 @@ public sealed class LearnSource9SV : ILearnSource, IEggSource, { var baseSpecies = pi.HatchSpecies; var baseForm = pi.HatchFormIndexEverstone; - return GetEggMoves(baseSpecies, baseForm).IndexOf(move) != -1; + return GetEggMoves(baseSpecies, baseForm).Contains(move); } public void GetAllMoves(Span result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All) diff --git a/PKHeX.Core/Legality/Learnset/Learnset.cs b/PKHeX.Core/Legality/Learnset/Learnset.cs index 30a7fde85..f2917f7cf 100644 --- a/PKHeX.Core/Legality/Learnset/Learnset.cs +++ b/PKHeX.Core/Legality/Learnset/Learnset.cs @@ -187,7 +187,7 @@ public sealed class Learnset(ushort[] Moves, byte[] Levels) for (int i = startIndex; i < endIndex; i++) { var move = Moves[i]; - if (ignore.IndexOf(move) >= 0) + if (ignore.Contains(move)) continue; AddMoveShiftLater(moves, ref ctr, move); @@ -207,7 +207,7 @@ public sealed class Learnset(ushort[] Moves, byte[] Levels) break; var move = Moves[i]; - if (ignore.IndexOf(move) >= 0) + if (ignore.Contains(move)) continue; AddMoveShiftLater(moves, ref ctr, move); diff --git a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed2.cs b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed2.cs index b94abe29f..c4890cb89 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed2.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed2.cs @@ -161,7 +161,7 @@ public static class MoveBreed2 if (move > Legal.MaxMoveID_2) // byte continue; - if (baseEgg.IndexOf(move) != -1) + if (baseEgg.Contains(move)) possible[i] |= 1 << (int)Base; if (inheritLevelUp && learn.GetIsLearn(move)) diff --git a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed3.cs b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed3.cs index 352eecaa2..085b3f6a8 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed3.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed3.cs @@ -162,7 +162,7 @@ public static class MoveBreed3 { var move = moves[i]; - if (baseEgg.IndexOf(move) != -1) + if (baseEgg.Contains(move)) possible[i] |= 1 << (int)Base; if (inheritLevelUp && learn.GetIsLearn(move)) diff --git a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed4.cs b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed4.cs index 24a18a6dc..4489c7420 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed4.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed4.cs @@ -165,7 +165,7 @@ public static class MoveBreed4 { var move = moves[i]; - if (baseEgg.IndexOf(move) != -1) + if (baseEgg.Contains(move)) possible[i] |= 1 << (int)Base; if (inheritLevelUp && learn.GetIsLearn(move)) diff --git a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed5.cs b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed5.cs index 4f12059de..16f93da36 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed5.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed5.cs @@ -157,7 +157,7 @@ public static class MoveBreed5 { var move = moves[i]; - if (baseEgg.IndexOf(move) != -1) + if (baseEgg.Contains(move)) possible[i] |= 1 << (int)Base; if (inheritLevelUp && learn.GetIsLearn(move)) diff --git a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed6.cs b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed6.cs index 37f01d8e3..2cace30d9 100644 --- a/PKHeX.Core/Legality/Moves/Breeding/MoveBreed6.cs +++ b/PKHeX.Core/Legality/Moves/Breeding/MoveBreed6.cs @@ -149,7 +149,7 @@ public static class MoveBreed6 { var move = moves[i]; - if (baseEgg.IndexOf(move) != -1) + if (baseEgg.Contains(move)) possible[i] |= 1 << (int)Base; if (inheritLevelUp && learn.GetIsLearn(move)) diff --git a/PKHeX.Core/Legality/RNG/Algorithms/XDRNG.cs b/PKHeX.Core/Legality/RNG/Algorithms/XDRNG.cs index e15bb7380..d0d26d0a2 100644 --- a/PKHeX.Core/Legality/RNG/Algorithms/XDRNG.cs +++ b/PKHeX.Core/Legality/RNG/Algorithms/XDRNG.cs @@ -295,16 +295,16 @@ public static class XDRNG } return ctr; } - + /// /// Multiplication constants for jumping 2^(index) frames forward. /// private static ReadOnlySpan JumpMult => [ - 0x000343FD, 0xA9FC6809, 0xDDFF5051, 0xF490B9A1, 0x43BA1741, 0xD290BE81, 0x82E3BD01, 0xBF507A01, - 0xF8C4F401, 0x7A19E801, 0x1673D001, 0xB5E7A001, 0x8FCF4001, 0xAF9E8001, 0x9F3D0001, 0x3E7A0001, - 0x7CF40001, 0xF9E80001, 0xF3D00001, 0xE7A00001, 0xCF400001, 0x9E800001, 0x3D000001, 0x7A000001, - 0xF4000001, 0xE8000001, 0xD0000001, 0xA0000001, 0x40000001, 0x80000001, 0x00000001, 0x00000001, + 0x000343FD, 0xA9FC6809, 0xDDFF5051, 0xF490B9A1, 0x43BA1741, 0xD290BE81, 0x82E3BD01, 0xBF507A01, + 0xF8C4F401, 0x7A19E801, 0x1673D001, 0xB5E7A001, 0x8FCF4001, 0xAF9E8001, 0x9F3D0001, 0x3E7A0001, + 0x7CF40001, 0xF9E80001, 0xF3D00001, 0xE7A00001, 0xCF400001, 0x9E800001, 0x3D000001, 0x7A000001, + 0xF4000001, 0xE8000001, 0xD0000001, 0xA0000001, 0x40000001, 0x80000001, 0x00000001, 0x00000001, ]; /// diff --git a/PKHeX.Core/Legality/Verifiers/EffortValueVerifier.cs b/PKHeX.Core/Legality/Verifiers/EffortValueVerifier.cs index 662217f17..ad651a645 100644 --- a/PKHeX.Core/Legality/Verifiers/EffortValueVerifier.cs +++ b/PKHeX.Core/Legality/Verifiers/EffortValueVerifier.cs @@ -9,7 +9,7 @@ namespace PKHeX.Core; public sealed class EffortValueVerifier : Verifier { protected override CheckIdentifier Identifier => CheckIdentifier.EVs; - + public override void Verify(LegalityAnalysis data) { var pk = data.Entity; @@ -32,7 +32,8 @@ public sealed class EffortValueVerifier : Verifier var enc = data.EncounterMatch; Span evs = stackalloc int[6]; pk.GetEVs(evs); - if (format >= 6 && evs.ContainsAny(253, 254, 255)) + + if (format >= 6 && IsAnyAboveHardLimit6(evs)) data.AddLine(GetInvalid(LEffortAbove252)); else if (format < 5) // 3/4 VerifyGainedEVs34(data, enc, evs, pk); @@ -46,9 +47,9 @@ public sealed class EffortValueVerifier : Verifier data.AddLine(Get(LEffortAllEqual, Severity.Fishy)); } - private void VerifyGainedEVs34(LegalityAnalysis data, IEncounterTemplate enc, Span evs, PKM pk) + private void VerifyGainedEVs34(LegalityAnalysis data, IEncounterTemplate enc, ReadOnlySpan evs, PKM pk) { - bool anyAbove100 = evs.Find(static ev => ev > EffortValues.MaxVitamins34) != default; + bool anyAbove100 = IsAnyAboveVitaminLimit(evs); if (!anyAbove100) return; @@ -66,4 +67,18 @@ public sealed class EffortValueVerifier : Verifier data.AddLine(GetInvalid(string.Format(LEffortUntrainedCap, EffortValues.MaxVitamins34))); } } + + // Hard cap at 252 for Gen6+ + private static bool IsAnyAboveHardLimit6(ReadOnlySpan evs) => evs.ContainsAny(253, 254, 255); + + // Vitamins can only raise to 100 in Gen3/4 + private static bool IsAnyAboveVitaminLimit(ReadOnlySpan evs) + { + foreach (var iv in evs) + { + if (iv > EffortValues.MaxVitamins34) + return true; + } + return false; + } } diff --git a/PKHeX.Core/Legality/Verifiers/IndividualValueVerifier.cs b/PKHeX.Core/Legality/Verifiers/IndividualValueVerifier.cs index 281ffa9a7..aa7ce8203 100644 --- a/PKHeX.Core/Legality/Verifiers/IndividualValueVerifier.cs +++ b/PKHeX.Core/Legality/Verifiers/IndividualValueVerifier.cs @@ -46,8 +46,8 @@ public sealed class IndividualValueVerifier : Verifier Span IVs = stackalloc int[6]; g.GetIVs(IVs); - var ivflag = IVs.Find(static iv => (byte)(iv - 0xFC) < 3); - if (ivflag == default) // Random IVs + var ivflag = IVs.IndexOfAny(0xFC, 0xFD, 0xFE); + if (ivflag == -1) // Random IVs { bool valid = Legal.GetIsFixedIVSequenceValidSkipRand(IVs, data.Entity); if (!valid) @@ -55,7 +55,7 @@ public sealed class IndividualValueVerifier : Verifier } else { - int IVCount = ivflag - 0xFB; // IV2/IV3 + int IVCount = IVs[ivflag] - 0xFB; // IV2/IV3 VerifyIVsFlawless(data, IVCount); } } diff --git a/PKHeX.Core/Legality/Verifiers/LegendsArceusVerifier.cs b/PKHeX.Core/Legality/Verifiers/LegendsArceusVerifier.cs index 3f52539cd..15be2de55 100644 --- a/PKHeX.Core/Legality/Verifiers/LegendsArceusVerifier.cs +++ b/PKHeX.Core/Legality/Verifiers/LegendsArceusVerifier.cs @@ -159,7 +159,7 @@ public sealed class LegendsArceusVerifier : Verifier if (!mustKnow && currentLearn.GetLevelLearnMove(move) != level) continue; - if (current.IndexOf(move) == -1) + if (!current.Contains(move)) current[ctr++] = move; if (ctr == 4) return 4; diff --git a/PKHeX.Core/MysteryGifts/WA8.cs b/PKHeX.Core/MysteryGifts/WA8.cs index f79b50a28..7131560d1 100644 --- a/PKHeX.Core/MysteryGifts/WA8.cs +++ b/PKHeX.Core/MysteryGifts/WA8.cs @@ -598,9 +598,9 @@ public sealed class WA8(byte[] Data) : DataMysteryGift(Data), ILangNick, INature { Span finalIVs = stackalloc int[6]; GetIVs(finalIVs); - var ivflag = finalIVs.Find(static iv => (byte)(iv - 0xFC) < 3); + var ivflag = finalIVs.IndexOfAny(0xFC, 0xFD, 0xFE); var rng = Util.Rand; - if (ivflag == default) // Random IVs + if (ivflag == -1) // Random IVs { for (int i = 0; i < finalIVs.Length; i++) { @@ -610,7 +610,7 @@ public sealed class WA8(byte[] Data) : DataMysteryGift(Data), ILangNick, INature } else // 1/2/3 perfect IVs { - int IVCount = ivflag - 0xFB; + int IVCount = finalIVs[ivflag] - 0xFB; do { finalIVs[rng.Next(6)] = 31; } while (finalIVs.Count(31) < IVCount); for (int i = 0; i < finalIVs.Length; i++) diff --git a/PKHeX.Core/MysteryGifts/WB7.cs b/PKHeX.Core/MysteryGifts/WB7.cs index 1786c4fda..401ee1afb 100644 --- a/PKHeX.Core/MysteryGifts/WB7.cs +++ b/PKHeX.Core/MysteryGifts/WB7.cs @@ -498,9 +498,9 @@ public sealed class WB7(byte[] Data) { Span finalIVs = stackalloc int[6]; GetIVs(finalIVs); - var ivflag = finalIVs.Find(static iv => (byte)(iv - 0xFC) < 3); + var ivflag = finalIVs.IndexOfAny(0xFC, 0xFD, 0xFE); var rng = Util.Rand; - if (ivflag == default) // Random IVs + if (ivflag == -1) // Random IVs { for (int i = 0; i < finalIVs.Length; i++) { @@ -510,7 +510,7 @@ public sealed class WB7(byte[] Data) } else // 1/2/3 perfect IVs { - int IVCount = ivflag - 0xFB; + int IVCount = finalIVs[ivflag] - 0xFB; do { finalIVs[rng.Next(6)] = 31; } while (finalIVs.Count(31) < IVCount); for (int i = 0; i < finalIVs.Length; i++) diff --git a/PKHeX.Core/MysteryGifts/WB8.cs b/PKHeX.Core/MysteryGifts/WB8.cs index 6cfa5aafd..639848bc7 100644 --- a/PKHeX.Core/MysteryGifts/WB8.cs +++ b/PKHeX.Core/MysteryGifts/WB8.cs @@ -592,9 +592,9 @@ public sealed class WB8(byte[] Data) : DataMysteryGift(Data), { Span finalIVs = stackalloc int[6]; GetIVs(finalIVs); - var ivflag = finalIVs.Find(static iv => (byte)(iv - 0xFC) < 3); + var ivflag = finalIVs.IndexOfAny(0xFC, 0xFD, 0xFE); var rng = Util.Rand; - if (ivflag == default) // Random IVs + if (ivflag == -1) // Random IVs { for (int i = 0; i < finalIVs.Length; i++) { @@ -604,7 +604,7 @@ public sealed class WB8(byte[] Data) : DataMysteryGift(Data), } else // 1/2/3 perfect IVs { - int IVCount = ivflag - 0xFB; + int IVCount = finalIVs[ivflag] - 0xFB; do { finalIVs[rng.Next(6)] = 31; } while (finalIVs.Count(31) < IVCount); for (int i = 0; i < finalIVs.Length; i++) diff --git a/PKHeX.Core/MysteryGifts/WC6.cs b/PKHeX.Core/MysteryGifts/WC6.cs index 92ad61046..857049db3 100644 --- a/PKHeX.Core/MysteryGifts/WC6.cs +++ b/PKHeX.Core/MysteryGifts/WC6.cs @@ -493,9 +493,9 @@ public sealed class WC6(byte[] Data) : DataMysteryGift(Data), IRibbonSetEvent3, { Span finalIVs = stackalloc int[6]; GetIVs(finalIVs); - var ivflag = finalIVs.Find(static iv => (byte)(iv - 0xFC) < 3); + var ivflag = finalIVs.IndexOfAny(0xFC, 0xFD, 0xFE); var rng = Util.Rand; - if (ivflag == default) // Random IVs + if (ivflag == -1) // Random IVs { for (int i = 0; i < finalIVs.Length; i++) { @@ -505,7 +505,7 @@ public sealed class WC6(byte[] Data) : DataMysteryGift(Data), IRibbonSetEvent3, } else // 1/2/3 perfect IVs { - int IVCount = ivflag - 0xFB; + int IVCount = finalIVs[ivflag] - 0xFB; do { finalIVs[rng.Next(6)] = 31; } while (finalIVs.Count(31) < IVCount); for (int i = 0; i < finalIVs.Length; i++) diff --git a/PKHeX.Core/MysteryGifts/WC7.cs b/PKHeX.Core/MysteryGifts/WC7.cs index e76a2dd78..a4e2a2f39 100644 --- a/PKHeX.Core/MysteryGifts/WC7.cs +++ b/PKHeX.Core/MysteryGifts/WC7.cs @@ -533,9 +533,9 @@ public sealed class WC7(byte[] Data) : DataMysteryGift(Data), IRibbonSetEvent3, { Span finalIVs = stackalloc int[6]; GetIVs(finalIVs); - var ivflag = finalIVs.Find(static iv => (byte)(iv - 0xFC) < 3); + var ivflag = finalIVs.IndexOfAny(0xFC, 0xFD, 0xFE); var rng = Util.Rand; - if (ivflag == default) // Random IVs + if (ivflag == -1) // Random IVs { for (int i = 0; i < finalIVs.Length; i++) { @@ -545,7 +545,7 @@ public sealed class WC7(byte[] Data) : DataMysteryGift(Data), IRibbonSetEvent3, } else // 1/2/3 perfect IVs { - int IVCount = ivflag - 0xFB; + int IVCount = finalIVs[ivflag] - 0xFB; do { finalIVs[rng.Next(6)] = 31; } while (finalIVs.Count(31) < IVCount); for (int i = 0; i < finalIVs.Length; i++) diff --git a/PKHeX.Core/MysteryGifts/WC8.cs b/PKHeX.Core/MysteryGifts/WC8.cs index 773752d18..dc7c8e879 100644 --- a/PKHeX.Core/MysteryGifts/WC8.cs +++ b/PKHeX.Core/MysteryGifts/WC8.cs @@ -616,9 +616,9 @@ public sealed class WC8(byte[] Data) : DataMysteryGift(Data), ILangNick, INature { Span finalIVs = stackalloc int[6]; GetIVs(finalIVs); - var ivflag = finalIVs.Find(static iv => (byte)(iv - 0xFC) < 3); + var ivflag = finalIVs.IndexOfAny(0xFC, 0xFD, 0xFE); var rng = Util.Rand; - if (ivflag == default) // Random IVs + if (ivflag == -1) // Random IVs { for (int i = 0; i < finalIVs.Length; i++) { @@ -628,7 +628,7 @@ public sealed class WC8(byte[] Data) : DataMysteryGift(Data), ILangNick, INature } else // 1/2/3 perfect IVs { - int IVCount = ivflag - 0xFB; + int IVCount = finalIVs[ivflag] - 0xFB; do { finalIVs[rng.Next(6)] = 31; } while (finalIVs.Count(31) < IVCount); for (int i = 0; i < finalIVs.Length; i++) diff --git a/PKHeX.Core/MysteryGifts/WC9.cs b/PKHeX.Core/MysteryGifts/WC9.cs index 62c02fd97..7c9abcefd 100644 --- a/PKHeX.Core/MysteryGifts/WC9.cs +++ b/PKHeX.Core/MysteryGifts/WC9.cs @@ -643,9 +643,9 @@ public sealed class WC9(byte[] Data) : DataMysteryGift(Data), ILangNick, INature { Span finalIVs = stackalloc int[6]; GetIVs(finalIVs); - var ivflag = finalIVs.Find(static iv => (byte)(iv - 0xFC) < 3); + var ivflag = finalIVs.IndexOfAny(0xFC, 0xFD, 0xFE); var rng = Util.Rand; - if (ivflag == default) // Random IVs + if (ivflag == -1) // Random IVs { for (int i = 0; i < finalIVs.Length; i++) { @@ -655,7 +655,7 @@ public sealed class WC9(byte[] Data) : DataMysteryGift(Data), ILangNick, INature } else // 1/2/3 perfect IVs { - int IVCount = ivflag - 0xFB; + int IVCount = finalIVs[ivflag] - 0xFB; do { finalIVs[rng.Next(6)] = 31; } while (finalIVs.Count(31) < IVCount); for (int i = 0; i < finalIVs.Length; i++) diff --git a/PKHeX.Core/PKM/Strings/Font/StringFont8b.cs b/PKHeX.Core/PKM/Strings/Font/StringFont8b.cs index 078f03872..931a05770 100644 --- a/PKHeX.Core/PKM/Strings/Font/StringFont8b.cs +++ b/PKHeX.Core/PKM/Strings/Font/StringFont8b.cs @@ -12,7 +12,7 @@ public static class StringFont8b // BD/SP: StreamingAssets/AssetAssistant/Dpr/font // S/V: arc/appli/font/bin // For KOR/CHS/CHT, BD/SP uses a bundled copy of the Switch system font - + public static ReadOnlySpan DefinedLiberationSans => [ '\u0020', '\u0021', '\u0022', '\u0023', '\u0024', '\u0025', '\u0026', '\u0027', '\u0028', '\u0029', '\u002A', '\u002B', '\u002C', '\u002D', '\u002E', '\u002F', diff --git a/PKHeX.Core/Saves/SaveFile.cs b/PKHeX.Core/Saves/SaveFile.cs index 15aa4b6d4..21ff5b4c5 100644 --- a/PKHeX.Core/Saves/SaveFile.cs +++ b/PKHeX.Core/Saves/SaveFile.cs @@ -498,13 +498,17 @@ public abstract class SaveFile : ITrainerInfo, IGameValueLimit, IGeneration, IVe private bool IsRegionOverwriteProtected(int min, int max) { - foreach (var arrays in SlotPointers) + var ptrs = SlotPointers; + if (ptrs.Length == 0) + return false; + + foreach (var arrays in ptrs) { foreach (int slotIndex in arrays) { if (!GetSlotFlags(slotIndex).IsOverwriteProtected()) continue; - if (ArrayUtil.WithinRange(slotIndex, min, max)) + if (min <= slotIndex && slotIndex < max) return true; } } @@ -514,13 +518,20 @@ public abstract class SaveFile : ITrainerInfo, IGameValueLimit, IGeneration, IVe public bool IsAnySlotLockedInBox(int BoxStart, int BoxEnd) { - foreach (var arrays in SlotPointers) + var ptrs = SlotPointers; + if (ptrs.Length == 0) + return false; + + var min = BoxStart * BoxSlotCount; + var max = (BoxEnd + 1) * BoxSlotCount; + + foreach (var arrays in ptrs) { foreach (int slotIndex in arrays) { if (!GetSlotFlags(slotIndex).HasFlag(StorageSlotSource.Locked)) continue; - if (ArrayUtil.WithinRange(slotIndex, BoxStart * BoxSlotCount, (BoxEnd + 1) * BoxSlotCount)) + if (min <= slotIndex && slotIndex < max) return true; } } diff --git a/PKHeX.Core/Saves/Substructures/Gen6/MyItem6XY.cs b/PKHeX.Core/Saves/Substructures/Gen6/MyItem6XY.cs index 8398fbf4f..3d728244e 100644 --- a/PKHeX.Core/Saves/Substructures/Gen6/MyItem6XY.cs +++ b/PKHeX.Core/Saves/Substructures/Gen6/MyItem6XY.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; namespace PKHeX.Core; -public sealed class MyItem6XY(SAV6XY SAV, Memory raw) : MyItem(SAV, raw) +public sealed class MyItem6XY(SAV6XY SAV, Memory raw) : MyItem(SAV, raw) { private const int HeldItem = 0; // 0 private const int KeyItem = 0x640; // 1 diff --git a/PKHeX.Core/Saves/Substructures/Gen9/RaidSevenStar9.cs b/PKHeX.Core/Saves/Substructures/Gen9/RaidSevenStar9.cs index e396299c7..be654d6c1 100644 --- a/PKHeX.Core/Saves/Substructures/Gen9/RaidSevenStar9.cs +++ b/PKHeX.Core/Saves/Substructures/Gen9/RaidSevenStar9.cs @@ -56,7 +56,7 @@ public sealed class SevenStarRaidDetail(SevenStarRaidCapturedDetail captured, Se defeated.Defeated = value; else captured.Defeated = value; - } + } } } diff --git a/PKHeX.Core/Saves/Substructures/Time/Epoch0000DateTime.cs b/PKHeX.Core/Saves/Substructures/Time/Epoch0000DateTime.cs index cb959fde1..ed7bde9ae 100644 --- a/PKHeX.Core/Saves/Substructures/Time/Epoch0000DateTime.cs +++ b/PKHeX.Core/Saves/Substructures/Time/Epoch0000DateTime.cs @@ -13,7 +13,7 @@ public sealed class Epoch0000DateTime(Memory Data): EpochDateTime(Data) public override int Year { get => RawYear; set => RawYear = value; } public override int Month { get => RawMonth; set => RawMonth = value; } - + public override DateTime Timestamp { get => new(Year, Month, Day, Hour, Minute, 0); diff --git a/PKHeX.Core/Saves/Util/DexFormUtil.cs b/PKHeX.Core/Saves/Util/DexFormUtil.cs index e5a142423..26de0082b 100644 --- a/PKHeX.Core/Saves/Util/DexFormUtil.cs +++ b/PKHeX.Core/Saves/Util/DexFormUtil.cs @@ -40,14 +40,14 @@ public static class DexFormUtil private static ReadOnlySpan DexSpeciesWithForm_SM => [ - 003, 006, 009, 015, 018, 019, 020, 025, 026, 027, 028, 037, 038, 050, 051, 052, - 053, 065, 074, 075, 076, 080, 088, 089, 094, 103, 105, 115, 127, 130, 142, 150, - 181, 201, 208, 212, 214, 229, 248, 254, 257, 260, 282, 302, 303, 306, 308, 310, - 319, 323, 334, 351, 354, 359, 362, 373, 376, 380, 381, 382, 383, 384, 386, 412, - 413, 421, 422, 423, 428, 445, 448, 460, 475, 479, 487, 492, 493, 531, 550, 555, - 585, 586, 641, 642, 645, 646, 647, 648, 649, 658, 666, 669, 670, 671, 676, 678, - 681, 710, 711, 716, 718, 719, 720, 735, 738, 741, 745, 746, 754, 758, 773, 774, - 778, 784, 801, + 003, 006, 009, 015, 018, 019, 020, 025, 026, 027, 028, 037, 038, 050, 051, 052, + 053, 065, 074, 075, 076, 080, 088, 089, 094, 103, 105, 115, 127, 130, 142, 150, + 181, 201, 208, 212, 214, 229, 248, 254, 257, 260, 282, 302, 303, 306, 308, 310, + 319, 323, 334, 351, 354, 359, 362, 373, 376, 380, 381, 382, 383, 384, 386, 412, + 413, 421, 422, 423, 428, 445, 448, 460, 475, 479, 487, 492, 493, 531, 550, 555, + 585, 586, 641, 642, 645, 646, 647, 648, 649, 658, 666, 669, 670, 671, 676, 678, + 681, 710, 711, 716, 718, 719, 720, 735, 738, 741, 745, 746, 754, 758, 773, 774, + 778, 784, 801, ]; private static ReadOnlySpan DexSpeciesCount_SM => @@ -64,14 +64,14 @@ public static class DexFormUtil private static ReadOnlySpan DexSpeciesWithForm_USUM => [ - 003, 006, 009, 015, 018, 019, 020, 025, 026, 027, 028, 037, 038, 050, 051, 052, - 053, 065, 074, 075, 076, 080, 088, 089, 094, 103, 105, 115, 127, 130, 142, 150, - 181, 201, 208, 212, 214, 229, 248, 254, 257, 260, 282, 302, 303, 306, 308, 310, - 319, 323, 334, 351, 354, 359, 362, 373, 376, 380, 381, 382, 383, 384, 386, 412, - 413, 414, 421, 422, 423, 428, 445, 448, 460, 475, 479, 487, 492, 493, 531, 550, - 555, 585, 586, 641, 642, 645, 646, 647, 648, 649, 658, 664, 665, 666, 669, 670, - 671, 676, 678, 681, 710, 711, 716, 718, 719, 720, 735, 738, 741, 743, 744, 745, - 746, 752, 754, 758, 773, 774, 777, 778, 784, 800, 801, + 003, 006, 009, 015, 018, 019, 020, 025, 026, 027, 028, 037, 038, 050, 051, 052, + 053, 065, 074, 075, 076, 080, 088, 089, 094, 103, 105, 115, 127, 130, 142, 150, + 181, 201, 208, 212, 214, 229, 248, 254, 257, 260, 282, 302, 303, 306, 308, 310, + 319, 323, 334, 351, 354, 359, 362, 373, 376, 380, 381, 382, 383, 384, 386, 412, + 413, 414, 421, 422, 423, 428, 445, 448, 460, 475, 479, 487, 492, 493, 531, 550, + 555, 585, 586, 641, 642, 645, 646, 647, 648, 649, 658, 664, 665, 666, 669, 670, + 671, 676, 678, 681, 710, 711, 716, 718, 719, 720, 735, 738, 741, 743, 744, 745, + 746, 752, 754, 758, 773, 774, 777, 778, 784, 800, 801, ]; private static ReadOnlySpan DexSpeciesCount_USUM => @@ -88,8 +88,8 @@ public static class DexFormUtil private static ReadOnlySpan DexSpeciesWithForm_GG => [ - 003, 006, 009, 015, 018, 019, 020, 025, 026, 027, 028, 037, 038, 050, 051, 052, - 053, 065, 074, 075, 076, 080, 088, 089, 094, 103, 105, 115, 127, 130, 142, 150, + 003, 006, 009, 015, 018, 019, 020, 025, 026, 027, 028, 037, 038, 050, 051, 052, + 053, 065, 074, 075, 076, 080, 088, 089, 094, 103, 105, 115, 127, 130, 142, 150, ]; private static ReadOnlySpan DexSpeciesCount_GG => diff --git a/PKHeX.Core/Util/ArrayUtil.cs b/PKHeX.Core/Util/ArrayUtil.cs index b6265d7a8..400acb036 100644 --- a/PKHeX.Core/Util/ArrayUtil.cs +++ b/PKHeX.Core/Util/ArrayUtil.cs @@ -8,27 +8,6 @@ namespace PKHeX.Core; /// public static class ArrayUtil { - public static T Find(this Span data, Func value) where T : unmanaged - { - foreach (var x in data) - { - if (value(x)) - return x; - } - return default; - } - - /// - /// Checks the range (exclusive max) if the is inside. - /// - public static bool WithinRange(int value, int min, int max) => min <= value && value < max; - - public static IEnumerable EnumerateSplit(T[] bin, int size, int start = 0) - { - for (int i = start; i < bin.Length; i += size) - yield return bin.AsSpan(i, size).ToArray(); - } - /// /// Copies a list to the destination list, with an option to copy to a starting point. /// diff --git a/PKHeX.Core/Util/FileUtil.cs b/PKHeX.Core/Util/FileUtil.cs index 6c3e8b641..db387b8ce 100644 --- a/PKHeX.Core/Util/FileUtil.cs +++ b/PKHeX.Core/Util/FileUtil.cs @@ -54,8 +54,8 @@ public static class FileUtil return mc; if (TryGetPKM(data, out var pk, ext)) return pk; - if (TryGetPCBoxBin(data, out IEnumerable pks, reference)) - return pks; + if (TryGetPCBoxBin(data, out var concat, reference)) + return concat; if (TryGetBattleVideo(data, out var bv)) return bv; if (TryGetMysteryGift(data, out var g, ext)) @@ -228,23 +228,34 @@ public static class FileUtil /// Tries to get a object from the input parameters. /// /// Binary data - /// Output result + /// Output result /// Reference SaveFile used for PC Binary compatibility checks. /// True if file object reference is valid, false if none found. - public static bool TryGetPCBoxBin(byte[] data, out IEnumerable pkms, SaveFile? sav) + public static bool TryGetPCBoxBin(byte[] data, [NotNullWhen(true)] out ConcatenatedEntitySet? result, SaveFile? sav) { - if (sav == null || IsNoDataPresent(data)) - { - pkms = []; + result = null; + if (sav is null || IsNoDataPresent(data)) return false; - } - var length = data.Length; - if (EntityDetection.IsSizePlausible(length / sav.SlotCount) || EntityDetection.IsSizePlausible(length / sav.BoxSlotCount)) + + // Only return if the size is one of the save file's data chunk formats. + var expect = sav.SIZE_BOXSLOT; + + // Check if it's the entire PC data. + var countPC = sav.SlotCount; + if (expect * countPC == data.Length) { - pkms = ArrayUtil.EnumerateSplit(data, length); + result = new(data, countPC); return true; } - pkms = []; + + // Check if it's a single box data. + var countBox = sav.BoxSlotCount; + if (expect * countBox == data.Length) + { + result = new(data, countBox); + return true; + } + return false; } @@ -321,3 +332,22 @@ public static class FileUtil return pk; } } + +/// +/// Represents a set of concatenated data. +/// +/// Object data +/// Count of objects +public sealed record ConcatenatedEntitySet(Memory Data, int Count) +{ + public int SlotSize => Data.Length / Count; + + public Span GetSlot(int index) + { + var size = SlotSize; + ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)size); + + var offset = index * size; + return Data.Span.Slice(offset, size); + } +} diff --git a/PKHeX.WinForms/MainWindow/Main.cs b/PKHeX.WinForms/MainWindow/Main.cs index 9cbf9b7aa..6cdf61e95 100644 --- a/PKHeX.WinForms/MainWindow/Main.cs +++ b/PKHeX.WinForms/MainWindow/Main.cs @@ -618,7 +618,7 @@ public partial class Main : Form case SaveFile s: return OpenSAV(s, path); case IPokeGroup b: return OpenGroup(b); case MysteryGift g: return OpenMysteryGift(g, path); - case IEnumerable pkms: return OpenPCBoxBin(pkms); + case ConcatenatedEntitySet pkms: return OpenPCBoxBin(pkms); case IEncounterConvertible enc: return OpenPKM(enc.ConvertToPKM(C_SAV.SAV)); case SAV3GCMemoryCard gc: @@ -678,10 +678,9 @@ public partial class Main : Form return true; } - private bool OpenPCBoxBin(IEnumerable pkms) + private bool OpenPCBoxBin(ConcatenatedEntitySet pkms) { - var data = pkms.SelectMany(z => z).ToArray(); - if (!C_SAV.OpenPCBoxBin(data, out string c)) + if (!C_SAV.OpenPCBoxBin(pkms.Data.Span, out string c)) { WinFormsUtil.Alert(MsgFileLoadIncompatible, c); return true; diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_SecretBase.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_SecretBase.cs index f6e05c7f6..153092c6f 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_SecretBase.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_SecretBase.cs @@ -226,7 +226,7 @@ public partial class SAV_SecretBase : Form CB_Species.SelectedValue = (int)pk.Species; CB_HeldItem.SelectedValue = pk.HeldItem; CB_Form.SelectedIndex = pk.Form; - + CB_Nature.SelectedValue = (int)pk.Nature; CB_Ball.SelectedValue = (int)pk.Ball; diff --git a/Tests/PKHeX.Core.Tests/Saves/SMTests.cs b/Tests/PKHeX.Core.Tests/Saves/SMTests.cs index 8420f64a4..293de2af2 100644 --- a/Tests/PKHeX.Core.Tests/Saves/SMTests.cs +++ b/Tests/PKHeX.Core.Tests/Saves/SMTests.cs @@ -29,6 +29,6 @@ public static class SMTests save.ChecksumInfo.Should().BeEquivalentTo(originalChecksumInfo, "because the checksum should have been modified"); save.ChecksumsValid.Should().BeTrue("because the checksum should be valid after write"); newSave.ChecksumsValid.Should().BeTrue("because the checksums should be valid after reopening the save"); - newSave.ChecksumInfo.Should().BeEquivalentTo(save.ChecksumInfo, "because the checksums should be the same since write and open"); + newSave.ChecksumInfo.Should().BeEquivalentTo(originalChecksumInfo, "because the checksums should be the same since write and open"); } }