diff --git a/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8.cs b/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8.cs index ed091462b..2eed4275c 100644 --- a/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8.cs +++ b/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8.cs @@ -13,6 +13,13 @@ public sealed class LearnGroup8 : ILearnGroup public ushort MaxMoveID => Legal.MaxMoveID_8; public ILearnGroup? GetPrevious(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) + { + if (option is LearnOption.AtAnyTimeChain) + return LearnGroupHOME.Instance; + return GoBackwards(pk, history, enc, option); + } + + internal static ILearnGroup? GoBackwards(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) { if (enc.Generation >= Generation) return null; diff --git a/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8a.cs b/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8a.cs index 7af432530..aae1b745e 100644 --- a/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8a.cs +++ b/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8a.cs @@ -12,7 +12,7 @@ public sealed class LearnGroup8a : ILearnGroup private const EntityContext Context = EntityContext.Gen8a; public ushort MaxMoveID => Legal.MaxMoveID_8a; - public ILearnGroup? GetPrevious(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) => null; + public ILearnGroup? GetPrevious(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) => option == LearnOption.AtAnyTimeChain ? LearnGroupHOME.Instance : null; public bool HasVisited(PKM pk, EvolutionHistory history) => history.HasVisitedPLA; public bool Check(Span result, ReadOnlySpan current, PKM pk, EvolutionHistory history, diff --git a/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8b.cs b/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8b.cs index 5225e0c90..55ee16b40 100644 --- a/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8b.cs +++ b/PKHeX.Core/Legality/LearnSource/Group/LearnGroup8b.cs @@ -12,7 +12,7 @@ public sealed class LearnGroup8b : ILearnGroup private const EntityContext Context = EntityContext.Gen8b; public ushort MaxMoveID => Legal.MaxMoveID_8b; - public ILearnGroup? GetPrevious(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) => null; + public ILearnGroup? GetPrevious(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) => option == LearnOption.AtAnyTimeChain ? LearnGroupHOME.Instance : null; public bool HasVisited(PKM pk, EvolutionHistory history) => history.HasVisitedBDSP; public bool Check(Span result, ReadOnlySpan current, PKM pk, EvolutionHistory history, diff --git a/PKHeX.Core/Legality/LearnSource/Group/LearnGroup9.cs b/PKHeX.Core/Legality/LearnSource/Group/LearnGroup9.cs index f88ebd1d5..8f5bc6c68 100644 --- a/PKHeX.Core/Legality/LearnSource/Group/LearnGroup9.cs +++ b/PKHeX.Core/Legality/LearnSource/Group/LearnGroup9.cs @@ -12,7 +12,7 @@ public sealed class LearnGroup9 : ILearnGroup private const EntityContext Context = EntityContext.Gen9; public ushort MaxMoveID => Legal.MaxMoveID_9; - public ILearnGroup? GetPrevious(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) => null; + public ILearnGroup? GetPrevious(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) => option == LearnOption.AtAnyTimeChain ? LearnGroupHOME.Instance : null; public bool HasVisited(PKM pk, EvolutionHistory history) => history.HasVisitedGen9; public bool Check(Span result, ReadOnlySpan current, PKM pk, EvolutionHistory history, diff --git a/PKHeX.Core/Legality/LearnSource/Group/LearnGroup9a.cs b/PKHeX.Core/Legality/LearnSource/Group/LearnGroup9a.cs index d9fcd5cc0..576ed1002 100644 --- a/PKHeX.Core/Legality/LearnSource/Group/LearnGroup9a.cs +++ b/PKHeX.Core/Legality/LearnSource/Group/LearnGroup9a.cs @@ -12,7 +12,7 @@ public sealed class LearnGroup9a : ILearnGroup private const EntityContext Context = EntityContext.Gen9a; public ushort MaxMoveID => Legal.MaxMoveID_9a; - public ILearnGroup? GetPrevious(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) => null; + public ILearnGroup? GetPrevious(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) => option == LearnOption.AtAnyTimeChain ? LearnGroupHOME.Instance : null; public bool HasVisited(PKM pk, EvolutionHistory history) => history.HasVisitedZA; public bool Check(Span result, ReadOnlySpan current, PKM pk, EvolutionHistory history, diff --git a/PKHeX.Core/Legality/LearnSource/Group/LearnGroupHOME.cs b/PKHeX.Core/Legality/LearnSource/Group/LearnGroupHOME.cs index f3e40c78b..d2c35072d 100644 --- a/PKHeX.Core/Legality/LearnSource/Group/LearnGroupHOME.cs +++ b/PKHeX.Core/Legality/LearnSource/Group/LearnGroupHOME.cs @@ -15,7 +15,8 @@ public sealed class LearnGroupHOME : ILearnGroup private const LearnOption Option = LearnOption.HOME; public ushort MaxMoveID => 0; - public ILearnGroup? GetPrevious(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) => null; + public ILearnGroup? GetPrevious(PKM pk, EvolutionHistory history, IEncounterTemplate enc, LearnOption option) => + option is LearnOption.AtAnyTimeChain ? LearnGroup8.GoBackwards(pk, history, enc, option) : null; public bool HasVisited(PKM pk, EvolutionHistory history) => pk is IHomeTrack { HasTracker: true } || !ParseSettings.IgnoreTransferIfNoTracker; public bool Check(Span result, ReadOnlySpan current, PKM pk, EvolutionHistory history, diff --git a/PKHeX.Core/Legality/LearnSource/Sources/Shared/LearnOption.cs b/PKHeX.Core/Legality/LearnSource/Sources/Shared/LearnOption.cs index 14c281516..9e860f760 100644 --- a/PKHeX.Core/Legality/LearnSource/Sources/Shared/LearnOption.cs +++ b/PKHeX.Core/Legality/LearnSource/Sources/Shared/LearnOption.cs @@ -28,6 +28,14 @@ public enum LearnOption /// Required to be distinct in that the rules are different from the other two options. TR/TM flags aren't required if the move was learned via HOME. /// HOME, + + /// + /// Check backwards of knowing moves within any game in the visitation chain. + /// + /// + /// Relevant for Evolution move sanity checks, where the move could have been picked up at any point in the game visitation chain. + /// + AtAnyTimeChain, } public static class LearnOptionExtensions @@ -35,7 +43,7 @@ public static class LearnOptionExtensions extension(LearnOption option) { public bool IsCurrent() => option == LearnOption.Current; - public bool IsPast() => option is LearnOption.AtAnyTime or LearnOption.HOME; + public bool IsPast() => option is LearnOption.AtAnyTime or LearnOption.HOME or LearnOption.AtAnyTimeChain; public bool IsFlagCheckRequired() => option != LearnOption.HOME; } } diff --git a/PKHeX.Core/Legality/Restrictions/EvolutionRestrictions.cs b/PKHeX.Core/Legality/Restrictions/EvolutionRestrictions.cs index ec54e71ca..9584c80c0 100644 --- a/PKHeX.Core/Legality/Restrictions/EvolutionRestrictions.cs +++ b/PKHeX.Core/Legality/Restrictions/EvolutionRestrictions.cs @@ -130,7 +130,7 @@ public static bool IsValidEvolutionWithMove(PKM pk, LegalInfo info) if (move is EEVEE) return IsValidEvolutionWithMoveAny(enc, EeveeFairyMoves, pruned, pk, head); - return MemoryPermissions.GetCanKnowMove(enc, move, pruned, pk, head); + return MemoryPermissions.GetCanKnowMove(enc, move, pruned, pk, head, LearnOption.AtAnyTimeChain); } private static bool IsMoveInRelearnSource(PKM pk, LegalInfo info, ushort move) @@ -182,7 +182,7 @@ private static bool IsValidEvolutionWithMoveAny(IEncounterTemplate enc, ReadOnly { foreach (var move in any) { - if (MemoryPermissions.GetCanKnowMove(enc, move, history, pk, head)) + if (MemoryPermissions.GetCanKnowMove(enc, move, history, pk, head, LearnOption.AtAnyTimeChain)) return true; } return false; diff --git a/PKHeX.Core/Legality/Restrictions/Memories/MemoryPermissions.cs b/PKHeX.Core/Legality/Restrictions/Memories/MemoryPermissions.cs index b7512c472..845474b0c 100644 --- a/PKHeX.Core/Legality/Restrictions/Memories/MemoryPermissions.cs +++ b/PKHeX.Core/Legality/Restrictions/Memories/MemoryPermissions.cs @@ -161,11 +161,11 @@ private static bool GetCanKnowMove(PKM pk, ushort move, EntityContext context, E return GetCanKnowMove(enc, move, history, pk, game); } - public static bool GetCanKnowMove(IEncounterTemplate enc, ushort move, EvolutionHistory history, PKM pk, ILearnGroup game) + public static bool GetCanKnowMove(IEncounterTemplate enc, ushort move, EvolutionHistory history, PKM pk, ILearnGroup game, LearnOption option = LearnOption.AtAnyTime) { Span result = stackalloc MoveResult[1]; Span moves = [move]; - LearnVerifierHistory.MarkAndIterate(result, moves, enc, pk, history, game, MoveSourceType.All, LearnOption.AtAnyTime); + LearnVerifierHistory.MarkAndIterate(result, moves, enc, pk, history, game, MoveSourceType.All, option); return result[0].Valid; }