mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-09-10 08:25:47 -05:00
Add better handling for specific GO transfers
No formarg or bad EC evolution peek -> search for higher species rather than from the bottom.
This commit is contained in:
@@ -28,6 +28,12 @@ public static WurmpleEvolution GetWurmpleEvoGroup(ushort species)
|
||||
return (WurmpleEvolution)(wIndex >> 1); // Silcoon, Cascoon
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the input species is a Wurmple evolution
|
||||
/// </summary>
|
||||
/// <returns>True if Wurmple evolution, false if not</returns>
|
||||
public static bool IsWurmpleEvo(ushort species) => GetWurmpleEvoGroup(species) != WurmpleEvolution.None;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Wurmple <see cref="PKM.EncryptionConstant"/> for a given Evolution Value
|
||||
/// </summary>
|
||||
|
||||
@@ -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<IEncounterable> 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>(TArea[] areas)
|
||||
private bool SeekForward<TArea>(TArea[] areas)
|
||||
where TArea : ISpeciesForm
|
||||
{
|
||||
for (; Index < areas.Length; Index++, EvoIndex = 0)
|
||||
@@ -77,6 +98,41 @@ private bool SeekNextArea<TArea>(TArea[] areas)
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool SeekReverse<TArea>(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>(TArea area, EvoCriteria evo) where TArea : ISpeciesForm
|
||||
{
|
||||
if (area.Species != evo.Species)
|
||||
@@ -108,7 +164,11 @@ private bool TryGetNext<TSlot>(TSlot[] slots)
|
||||
Rating = rating;
|
||||
}
|
||||
}
|
||||
EvoIndex = 0; SubIndex = 0; Index++;
|
||||
EvoIndex = 0; SubIndex = 0;
|
||||
if (Mode == SeekMode.Forward)
|
||||
Index++;
|
||||
else
|
||||
Index--;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,29 @@ internal static class EvolutionRestrictions
|
||||
_ => NONE,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets the species-form that it will evolve into.
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user