From 4e0f23cdc00ea07e3b8f74bc17399de6f07c9004 Mon Sep 17 00:00:00 2001 From: Kurt Date: Mon, 4 Sep 2023 18:23:10 -0700 Subject: [PATCH] Handle get moveset for Gen1 Red Trade Jynx Need to not devolve into Smoochum as the rules are restrictive: no relearn, but we want to allow Jynx to "permit" moves it learns from levels 0-29. --- .../Moveset/EncounterMovesetGenerator.cs | 4 +-- .../Information/EncounterSuggestion.cs | 4 +-- .../EvolutionGroup/EvolutionGroup1.cs | 2 +- .../EvolutionGroup/EvolutionOrigin.cs | 27 +++++++++++++++++-- PKHeX.Core/Legality/MoveListSuggest.cs | 2 +- .../PKHeX.Core.Tests/General/MarshalTests.cs | 1 + 6 files changed, 32 insertions(+), 8 deletions(-) diff --git a/PKHeX.Core/Legality/Encounters/Generator/Moveset/EncounterMovesetGenerator.cs b/PKHeX.Core/Legality/Encounters/Generator/Moveset/EncounterMovesetGenerator.cs index b3702b78d..9ab1a3e2f 100644 --- a/PKHeX.Core/Legality/Encounters/Generator/Moveset/EncounterMovesetGenerator.cs +++ b/PKHeX.Core/Legality/Encounters/Generator/Moveset/EncounterMovesetGenerator.cs @@ -191,7 +191,7 @@ private static IEnumerable GenerateVersionEncounters(PKM pk, Rea private static IEnumerable GenerateVersionEncounters(PKM pk, ReadOnlyMemory moves, GameVersion version, byte generation, EntityContext context) { - var origin = new EvolutionOrigin(pk.Species, (byte)version, generation, 1, 100, true); + var origin = new EvolutionOrigin(pk.Species, (byte)version, generation, 1, 100, OriginOptions.EncounterTemplate); var chain = EvolutionChain.GetOriginChain(pk, origin); if (chain.Length == 0) yield break; @@ -259,7 +259,7 @@ private static ushort[] GetNeededMoves(PKM pk, ReadOnlySpan moves, GameV var length = pk.MaxMoveID + 1; var rent = ArrayPool.Shared.Rent(length); var permitted = rent.AsSpan(0, length); - var enc = new EvolutionOrigin(pk.Species, (byte)ver, (byte)generation, 1, 100, true); + var enc = new EvolutionOrigin(pk.Species, (byte)ver, (byte)generation, 1, 100, OriginOptions.EncounterTemplate); var history = EvolutionChain.GetEvolutionChainsSearch(pk, enc, context, 0); var e = new NeededEncounter(context, generation, ver); // default empty LearnPossible.Get(pk, e, history, permitted); diff --git a/PKHeX.Core/Legality/Encounters/Information/EncounterSuggestion.cs b/PKHeX.Core/Legality/Encounters/Information/EncounterSuggestion.cs index 8951a44e2..68ab8fb5c 100644 --- a/PKHeX.Core/Legality/Encounters/Information/EncounterSuggestion.cs +++ b/PKHeX.Core/Legality/Encounters/Information/EncounterSuggestion.cs @@ -19,7 +19,7 @@ public static class EncounterSuggestion return GetSuggestedEncounterEgg(pk, loc); Span chain = stackalloc EvoCriteria[EvolutionTree.MaxEvolutions]; - var origin = new EvolutionOrigin(pk.Species, (byte)pk.Version, (byte)pk.Generation, (byte)pk.CurrentLevel, (byte)pk.CurrentLevel, SkipChecks: true); + var origin = new EvolutionOrigin(pk.Species, (byte)pk.Version, (byte)pk.Generation, (byte)pk.CurrentLevel, (byte)pk.CurrentLevel, OriginOptions.SkipChecks); var count = EvolutionChain.GetOriginChain(chain, pk, origin); var ver = (GameVersion)pk.Version; var generator = EncounterGenerator.GetGenerator(ver); @@ -122,7 +122,7 @@ public static int GetLowestLevel(PKM pk, byte startLevel) int most = 1; Span chain = stackalloc EvoCriteria[EvolutionTree.MaxEvolutions]; - var origin = new EvolutionOrigin(pk.Species, (byte)pk.Version, (byte)pk.Generation, startLevel, 100, SkipChecks: true); + var origin = new EvolutionOrigin(pk.Species, (byte)pk.Version, (byte)pk.Generation, startLevel, 100, OriginOptions.SkipChecks); while (true) { var count = EvolutionChain.GetOriginChain(chain, pk, origin); diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionGroup/EvolutionGroup1.cs b/PKHeX.Core/Legality/Evolutions/EvolutionGroup/EvolutionGroup1.cs index 4f15194f3..40117c478 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionGroup/EvolutionGroup1.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionGroup/EvolutionGroup1.cs @@ -8,7 +8,7 @@ public sealed class EvolutionGroup1 : IEvolutionGroup, IEvolutionEnvironment private static readonly EvolutionTree Tree = EvolutionTree.Evolves1; public IEvolutionGroup GetNext(PKM pk, EvolutionOrigin enc) => EvolutionGroup2.Instance; - public IEvolutionGroup? GetPrevious(PKM pk, EvolutionOrigin enc) => pk.Format == 1 && ParseSettings.AllowGen1Tradeback ? EvolutionGroup2.Instance : null; + public IEvolutionGroup? GetPrevious(PKM pk, EvolutionOrigin enc) => !enc.NoDevolveGen1 && pk.Format == 1 && ParseSettings.AllowGen1Tradeback ? EvolutionGroup2.Instance : null; public void DiscardForOrigin(Span result, PKM pk) { diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionGroup/EvolutionOrigin.cs b/PKHeX.Core/Legality/Evolutions/EvolutionGroup/EvolutionOrigin.cs index 521f3f4b3..906b55480 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionGroup/EvolutionOrigin.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionGroup/EvolutionOrigin.cs @@ -1,3 +1,5 @@ +using System; + namespace PKHeX.Core; /// @@ -8,5 +10,26 @@ namespace PKHeX.Core; /// Generation the encounter originated in /// Minimum level the encounter originated at /// Maximum level in final state -/// Skip enforcement of legality for evolution criteria -public readonly record struct EvolutionOrigin(ushort Species, byte Version, byte Generation, byte LevelMin, byte LevelMax, bool SkipChecks = false); +/// Options to toggle logic when using this data +public readonly record struct EvolutionOrigin(ushort Species, byte Version, byte Generation, byte LevelMin, byte LevelMax, OriginOptions Options = 0) +{ + /// + /// Checks if evolution checks against the Entity should be skipped when devolving or devolving. + /// + public bool SkipChecks => Options.HasFlag(OriginOptions.SkipChecks); + + /// + /// Internally used to enforce Gen1 origin encounters NOT jumping to Gen2 to continue devolving. + /// + public bool NoDevolveGen1 => Options.HasFlag(OriginOptions.EncounterTemplate); +} + +[Flags] +public enum OriginOptions : byte +{ + None = 0, + SkipChecks = 1 << 0, + CheckVersionWhenNavigating = 1 << 1, + + EncounterTemplate = SkipChecks | CheckVersionWhenNavigating, +} diff --git a/PKHeX.Core/Legality/MoveListSuggest.cs b/PKHeX.Core/Legality/MoveListSuggest.cs index a3d1f14bc..a10f2ab7c 100644 --- a/PKHeX.Core/Legality/MoveListSuggest.cs +++ b/PKHeX.Core/Legality/MoveListSuggest.cs @@ -186,7 +186,7 @@ private static void GetSuggestedRelearnEgg(this IEncounterTemplate enc, ReadOnly var generator = EncounterGenerator.GetGenerator(enc.Version); Span chain = stackalloc EvoCriteria[EvolutionTree.MaxEvolutions]; - var origin = new EvolutionOrigin(enc.Species, (byte)enc.Version, (byte)enc.Generation, 1, 100, true); + var origin = new EvolutionOrigin(enc.Species, (byte)enc.Version, (byte)enc.Generation, 1, 100, OriginOptions.EncounterTemplate); int count = EvolutionChain.GetOriginChain(chain, pk, origin); for (int i = 0; i < count; i++) { diff --git a/Tests/PKHeX.Core.Tests/General/MarshalTests.cs b/Tests/PKHeX.Core.Tests/General/MarshalTests.cs index 625c7c9af..9fcd6e5c0 100644 --- a/Tests/PKHeX.Core.Tests/General/MarshalTests.cs +++ b/Tests/PKHeX.Core.Tests/General/MarshalTests.cs @@ -21,6 +21,7 @@ public class MarshalTests [Theory] [InlineData( 8, typeof(NPCLock))] [InlineData( 8, typeof(IndividualValueSet))] + [InlineData( 8, typeof(EvolutionOrigin))] [InlineData(16, typeof(DreamWorldEntry))] [InlineData(16, typeof(CheckResult))] [InlineData(16, typeof(EvolutionLink))]