diff --git a/PKHeX.Core/Editing/WurmpleUtil.cs b/PKHeX.Core/Editing/WurmpleUtil.cs
index 17d5cc95c..06564ae2e 100644
--- a/PKHeX.Core/Editing/WurmpleUtil.cs
+++ b/PKHeX.Core/Editing/WurmpleUtil.cs
@@ -28,6 +28,12 @@ public static WurmpleEvolution GetWurmpleEvoGroup(ushort species)
return (WurmpleEvolution)(wIndex >> 1); // Silcoon, Cascoon
}
+ ///
+ /// Checks to see if the input species is a Wurmple evolution
+ ///
+ /// True if Wurmple evolution, false if not
+ public static bool IsWurmpleEvo(ushort species) => GetWurmpleEvoGroup(species) != WurmpleEvolution.None;
+
///
/// Gets the Wurmple for a given Evolution Value
///
diff --git a/PKHeX.Core/Legality/Encounters/Generator/Search/EncounterEnumerator8GO.cs b/PKHeX.Core/Legality/Encounters/Generator/Search/EncounterEnumerator8GO.cs
index ab7ea3ad6..1952a7781 100644
--- a/PKHeX.Core/Legality/Encounters/Generator/Search/EncounterEnumerator8GO.cs
+++ b/PKHeX.Core/Legality/Encounters/Generator/Search/EncounterEnumerator8GO.cs
@@ -13,6 +13,7 @@ public record struct EncounterEnumerator8GO(PKM Entity, EvoCriteria[] Chain) : I
private int Index;
private int EvoIndex;
private int SubIndex;
+ private SeekMode Mode;
private EncounterMatchRating Rating = EncounterMatchRating.MaxNotMatch;
public MatchedEncounter Current { get; private set; }
private YieldState State;
@@ -26,11 +27,19 @@ private enum YieldState : byte
{
Start,
Seek,
+ SeekForward,
+ SeekReverse,
Slot,
Fallback,
End,
}
+ public enum SeekMode : byte
+ {
+ Forward,
+ Reverse,
+ }
+
public bool MoveNext()
{
switch (State)
@@ -40,12 +49,24 @@ public bool MoveNext()
break;
if (!EncounterStateUtil.CanBeWildEncounter(Entity))
break;
+ Mode = GetSeekMode();
+ if (Mode == SeekMode.Reverse)
+ Index = EncountersGO.SlotsGO.Length - 1;
State = YieldState.Seek; goto case YieldState.Seek;
case YieldState.Seek:
- if (!SeekNextArea(EncountersGO.SlotsGO))
+ if (Mode == SeekMode.Forward)
+ { State = YieldState.SeekForward; goto case YieldState.SeekForward; }
+ State = YieldState.SeekReverse; goto case YieldState.SeekReverse;
+ case YieldState.SeekForward:
+ if (!SeekForward(EncountersGO.SlotsGO))
goto case YieldState.Fallback;
State = YieldState.Slot; goto case YieldState.Slot;
+ case YieldState.SeekReverse:
+ if (!SeekReverse(EncountersGO.SlotsGO))
+ goto case YieldState.Fallback;
+ State = YieldState.Slot; goto case YieldState.Slot;
+
case YieldState.Slot:
var group = EncountersGO.SlotsGO[Index];
if (TryGetNext(group.Slots))
@@ -61,7 +82,7 @@ public bool MoveNext()
return false;
}
- private bool SeekNextArea(TArea[] areas)
+ private bool SeekForward(TArea[] areas)
where TArea : ISpeciesForm
{
for (; Index < areas.Length; Index++, EvoIndex = 0)
@@ -77,6 +98,41 @@ private bool SeekNextArea(TArea[] areas)
return false;
}
+ private bool SeekReverse(TArea[] areas) where TArea : ISpeciesForm
+ {
+ for (; Index > 0; Index--, EvoIndex = 0) // Only difference -- search in reverse!
+ {
+ var area = areas[Index];
+ do
+ {
+ if (IsCompatible(area, Chain[EvoIndex]))
+ return true;
+ }
+ while (++EvoIndex < Chain.Length);
+ }
+ return false;
+ }
+
+ private readonly SeekMode GetSeekMode()
+ {
+ var species = Entity.Species;
+ if (species is (int)Species.Dudunsparce or (int)Species.Maushold)
+ {
+ if (!EvolutionRestrictions.GetIsExpectedEvolveFormEC100(species, Entity.Form, Entity.EncryptionConstant % 100 == 0))
+ return SeekMode.Reverse;
+ }
+ else if (EvolutionRestrictions.IsFormArgEvolution(species))
+ {
+ if (Entity is IFormArgument { FormArgument: 0 })
+ return SeekMode.Reverse;
+ }
+ else if (WurmpleUtil.IsWurmpleEvo(species) && !WurmpleUtil.IsWurmpleEvoValid(Entity))
+ {
+ return SeekMode.Reverse;
+ }
+ return SeekMode.Forward;
+ }
+
private readonly bool IsCompatible(TArea area, EvoCriteria evo) where TArea : ISpeciesForm
{
if (area.Species != evo.Species)
@@ -108,7 +164,11 @@ private bool TryGetNext(TSlot[] slots)
Rating = rating;
}
}
- EvoIndex = 0; SubIndex = 0; Index++;
+ EvoIndex = 0; SubIndex = 0;
+ if (Mode == SeekMode.Forward)
+ Index++;
+ else
+ Index--;
return false;
}
diff --git a/PKHeX.Core/Legality/Restrictions/EvolutionRestrictions.cs b/PKHeX.Core/Legality/Restrictions/EvolutionRestrictions.cs
index a46279e13..f69170edd 100644
--- a/PKHeX.Core/Legality/Restrictions/EvolutionRestrictions.cs
+++ b/PKHeX.Core/Legality/Restrictions/EvolutionRestrictions.cs
@@ -36,6 +36,29 @@ internal static class EvolutionRestrictions
_ => NONE,
};
+ ///
+ /// Gets the species-form that it will evolve into.
+ ///
+ ///
+ public static (ushort Species, byte Form) GetEvolvedSpeciesFormEC100(ushort species, bool rare) => species switch
+ {
+ (ushort)Tandemaus => ((ushort)Maushold, (byte)(rare ? 0 : 1)),
+ (ushort)Dunsparce => ((ushort)Dudunsparce, (byte)(rare ? 1 : 0)),
+ _ => throw new ArgumentOutOfRangeException(nameof(species), species, "Incorrect EC%100 species."),
+ };
+
+ public static bool GetIsExpectedEvolveFormEC100(ushort species, byte form, bool rare) => species switch
+ {
+ (ushort)Maushold => form == (byte)(rare ? 0 : 1),
+ (ushort)Dudunsparce => form == (byte)(rare ? 1 : 0),
+ _ => throw new ArgumentOutOfRangeException(nameof(species), species, "Incorrect EC%100 species."),
+ };
+
+ public static bool IsFormArgEvolution(ushort species)
+ {
+ return species is (int)Runerigus or (int)Wyrdeer or (int)Annihilape or (int)Basculegion or (int)Kingambit or (int)Overqwil;
+ }
+
private const ushort NONE = 0;
private const ushort EEVEE = ushort.MaxValue;
diff --git a/PKHeX.Core/Legality/Verifiers/PIDVerifier.cs b/PKHeX.Core/Legality/Verifiers/PIDVerifier.cs
index 18c3c52d9..7da5e2734 100644
--- a/PKHeX.Core/Legality/Verifiers/PIDVerifier.cs
+++ b/PKHeX.Core/Legality/Verifiers/PIDVerifier.cs
@@ -1,4 +1,3 @@
-using System;
using static PKHeX.Core.LegalityCheckStrings;
namespace PKHeX.Core;
@@ -105,20 +104,13 @@ private static void VerifyEC100(LegalityAnalysis data, ushort encSpecies)
// Indicate the evolution for the user.
uint evoVal = pk.EncryptionConstant % 100;
bool rare = evoVal == 0;
- var (species, form) = GetEvolvedSpeciesForm(encSpecies, rare);
+ var (species, form) = EvolutionRestrictions.GetEvolvedSpeciesFormEC100(encSpecies, rare);
var str = GameInfo.Strings;
var forms = FormConverter.GetFormList(species, str.Types, str.forms, GameInfo.GenderSymbolASCII, EntityContext.Gen9);
var msg = string.Format(L_XRareFormEvo_0_1, forms[form], rare);
data.AddLine(GetValid(msg, CheckIdentifier.EC));
}
- private static (ushort, int) GetEvolvedSpeciesForm(ushort species, bool rare) => species switch
- {
- (int)Species.Tandemaus => ((ushort)Species.Maushold, rare ? 0 : 1),
- (int)Species.Dunsparce => ((ushort)Species.Dudunsparce, rare ? 1 : 0),
- _ => throw new ArgumentOutOfRangeException(nameof(species), species, "Incorrect EC%100 species."),
- };
-
private static void VerifyEC(LegalityAnalysis data)
{
var pk = data.Entity;
diff --git a/PKHeX.Core/Resources/legality/wild/encounter_go_home.pkl b/PKHeX.Core/Resources/legality/wild/encounter_go_home.pkl
index 23196e548..d6c7e8653 100644
Binary files a/PKHeX.Core/Resources/legality/wild/encounter_go_home.pkl and b/PKHeX.Core/Resources/legality/wild/encounter_go_home.pkl differ
diff --git a/PKHeX.Core/Resources/legality/wild/encounter_go_lgpe.pkl b/PKHeX.Core/Resources/legality/wild/encounter_go_lgpe.pkl
index d989ce6a4..7747d1f07 100644
Binary files a/PKHeX.Core/Resources/legality/wild/encounter_go_lgpe.pkl and b/PKHeX.Core/Resources/legality/wild/encounter_go_lgpe.pkl differ