From d5314a00f55aad1dd3cd3939ba41756cc2d0a4cf Mon Sep 17 00:00:00 2001 From: Kurt Date: Wed, 29 Oct 2025 17:40:13 -0500 Subject: [PATCH] Allow game bug for trade evo's & plus moves --- .../Legality/Verifiers/LegendsZAVerifier.cs | 47 +++++++++++++++++-- .../Strings/Trainer/ReplaceTrainerName8a.cs | 2 +- .../Strings/Trainer/ReplaceTrainerName9a.cs | 2 +- PKHeX.Core/PKM/Strings/Trash/TrashBytesGB.cs | 2 +- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/PKHeX.Core/Legality/Verifiers/LegendsZAVerifier.cs b/PKHeX.Core/Legality/Verifiers/LegendsZAVerifier.cs index be093051a..0ee502900 100644 --- a/PKHeX.Core/Legality/Verifiers/LegendsZAVerifier.cs +++ b/PKHeX.Core/Legality/Verifiers/LegendsZAVerifier.cs @@ -148,9 +148,9 @@ private void CheckFlagsPlus(LegalityAnalysis la, PA9 pk) la.AddLine(GetInvalid(PlusMoveCountInvalid)); // Check for all required indexes. - var (_, plus) = LearnSource9ZA.GetLearnsetAndPlus(pk.Species, pk.Form); + var (learn, plus) = LearnSource9ZA.GetLearnsetAndPlus(pk.Species, pk.Form); var currentLevel = pk.CurrentLevel; - CheckPlusMoveFlags(la, pk, plus, currentLevel, permit); + CheckPlusMoveFlags(la, pk, permit, plus, currentLevel); // Check for indexes set that cannot be set via TM or NPC. @@ -167,7 +167,7 @@ private void CheckFlagsPlus(LegalityAnalysis la, PA9 pk) la.AddLine(msg); } - private void CheckPlusMoveFlags(LegalityAnalysis la, T pk, Learnset plus, byte currentLevel, IPermitPlus permit) where T : IPlusRecord + private void CheckPlusMoveFlags(LegalityAnalysis la, T pk, IPermitPlus permit, Learnset plus, byte currentLevel) where T : IPlusRecord { var levels = plus.GetAllLevels(); var moves = plus.GetAllMoves(); @@ -182,11 +182,48 @@ private void CheckFlagsPlus(LegalityAnalysis la, PA9 pk) if (index == -1) throw new IndexOutOfRangeException("Unexpected learn move index, not in Plus moves?"); - if (!pk.GetMovePlusFlag(index)) - la.AddLine(GetInvalid(PlusMoveSufficientLevelMissing_0, move, level)); + if (pk.GetMovePlusFlag(index)) + continue; // All good, flagged. + + // Trade evolutions forget to set the Plus flags, unlike triggered evolutions. + // If the move is not present as a previous-evolution learnset move, and the head species is a Trade evo, skip the error. + // Assume the best case -- evolved at current level, so none would get set. + if (IsTradeEvoSkip(la.Info.EvoChainsAllGens.Gen9a, move)) + continue; + + la.AddLine(GetInvalid(PlusMoveSufficientLevelMissing_0, move, level)); } } + private static bool IsTradeEvoSkip(ReadOnlySpan evos, ushort move) + { + if (evos.Length <= 1) + return false; + + if (!evos[0].Method.IsTrade()) + return false; + + // Check if the pre-evolution could have learned it before evolving. + for (int i = 1; i < evos.Length; i++) + { + var evo = evos[i]; + var (_, plus) = LearnSource9ZA.GetLearnsetAndPlus(evo.Species, evo.Form); + var moves = plus.GetAllMoves(); + + var index = moves.IndexOf(move); + if (index == -1) + continue; // can't learn + + // if the evo must have traversed this level range (and not the head's level range), then it must have been flagged. + var levels = plus.GetAllLevels(); + var plusLevel = levels[index]; + var headLevel = evos[0].LevelMin; + if (plusLevel <= headLevel) + return false; + } + return true; + } + private const ushort MultipleInvalidPlusMoves = ushort.MaxValue; private static ushort GetInvalidPlusMove(T pk, int maxIndex, IPermitPlus permit, ReadOnlySpan evos) diff --git a/PKHeX.Core/PKM/Strings/Trainer/ReplaceTrainerName8a.cs b/PKHeX.Core/PKM/Strings/Trainer/ReplaceTrainerName8a.cs index c88b8802a..aff6657f4 100644 --- a/PKHeX.Core/PKM/Strings/Trainer/ReplaceTrainerName8a.cs +++ b/PKHeX.Core/PKM/Strings/Trainer/ReplaceTrainerName8a.cs @@ -54,7 +54,7 @@ public static bool IsReplace(ReadOnlySpan name, LanguageID language) } /// - /// Gets the replacement name for in the given language. + /// Gets the replacement name for in the given language. /// public static string GetName(LanguageID language) => language switch { diff --git a/PKHeX.Core/PKM/Strings/Trainer/ReplaceTrainerName9a.cs b/PKHeX.Core/PKM/Strings/Trainer/ReplaceTrainerName9a.cs index 487175832..65e8ca2f7 100644 --- a/PKHeX.Core/PKM/Strings/Trainer/ReplaceTrainerName9a.cs +++ b/PKHeX.Core/PKM/Strings/Trainer/ReplaceTrainerName9a.cs @@ -53,7 +53,7 @@ public static bool IsReplace(ReadOnlySpan name, LanguageID language) } /// - /// Gets the replacement name for in the given language. + /// Gets the replacement name for in the given language. /// public static string GetName(LanguageID language) => language switch { diff --git a/PKHeX.Core/PKM/Strings/Trash/TrashBytesGB.cs b/PKHeX.Core/PKM/Strings/Trash/TrashBytesGB.cs index 9964c6332..a21996642 100644 --- a/PKHeX.Core/PKM/Strings/Trash/TrashBytesGB.cs +++ b/PKHeX.Core/PKM/Strings/Trash/TrashBytesGB.cs @@ -16,7 +16,7 @@ public static int GetStringLength(ReadOnlySpan buffer) } /// - /// Returns a 8-bit aligned index of the terminator. + /// Returns an 8-bit aligned index of the terminator. /// /// Backing buffer of the string. /// Index of the terminator, or -1 if not found.