Extract iterator flag mask check logic, reuse

This commit is contained in:
Kurt
2023-04-23 16:43:47 -07:00
parent 907ed0b32f
commit de17753733

View File

@@ -296,22 +296,7 @@ private static IEnumerable<IEncounterable> GetEggs(PKM pk, ushort[] needs, EvoCr
var eggs = generator.GetPossible(pk, chain, version, Egg);
foreach (var egg in eggs)
{
if (needs.Length == 0)
{
yield return egg;
continue;
}
var source = GameData.GetLearnSource(egg.Version);
var eggMoves = source.GetEggMoves(egg.Species, egg.Form);
int flags = Moveset.BitOverlap(eggMoves, needs);
var vt = Array.IndexOf(needs, (ushort)Move.VoltTackle);
if (vt != -1 && egg is EncounterEgg { CanHaveVoltTackle: true })
flags |= 1 << vt;
else if (egg.Generation <= 2)
flags |= GetMoveMaskGen2(needs, egg);
if (flags == (1 << needs.Length) - 1)
if (needs.Length == 0 || HasAllNeededMovesEgg(needs, egg))
yield return egg;
}
}
@@ -329,22 +314,12 @@ private static IEnumerable<IEncounterable> GetGifts(PKM pk, ushort[] needs, EvoC
{
var context = pk.Context;
var gifts = generator.GetPossible(pk, chain, version, Mystery);
foreach (var g in gifts)
foreach (var enc in gifts)
{
if (!IsSane(chain, g, context))
if (!IsSane(chain, enc, context))
continue;
if (needs.Length == 0)
{
yield return g;
continue;
}
var flags = 0;
if (g is IMoveset m)
flags = m.Moves.BitOverlap(needs);
if (g is IRelearn r)
flags |= r.Relearn.BitOverlap(needs);
if (flags == (1 << needs.Length) - 1)
yield return g;
if (needs.Length == 0 || GetHasAllNeededMoves(needs, enc))
yield return enc;
}
}
@@ -365,15 +340,7 @@ private static IEnumerable<IEncounterable> GetStatic(PKM pk, ushort[] needs, Evo
{
if (!IsSane(chain, enc, context))
continue;
if (needs.Length == 0)
{
yield return enc;
continue;
}
// Some rare encounters have special moves hidden in the Relearn section (Gen7 Wormhole Ho-Oh). Include relearn moves
var flags = GetMoveMaskConsiderGen2(needs, enc);
if (flags == (1 << needs.Length) - 1)
if (needs.Length == 0 || GetHasAllNeededMovesConsiderGen2(needs, enc))
yield return enc;
}
}
@@ -391,19 +358,12 @@ private static IEnumerable<IEncounterable> GetTrades(PKM pk, ushort[] needs, Evo
{
var context = pk.Context;
var trades = generator.GetPossible(pk, chain, version, Trade);
foreach (var trade in trades)
foreach (var enc in trades)
{
if (!IsSane(chain, trade, context))
if (!IsSane(chain, enc, context))
continue;
if (needs.Length == 0)
{
yield return trade;
continue;
}
var flags = GetMoveMaskConsiderGen2(needs, trade);
if (flags == (1 << needs.Length) - 1)
yield return trade;
if (needs.Length == 0 || GetHasAllNeededMovesConsiderGen2(needs, enc))
yield return enc;
}
}
@@ -449,13 +409,19 @@ private static bool IsSane(ReadOnlySpan<EvoCriteria> chain, IEncounterTemplate e
return false;
}
private static int GetMoveMaskConsiderGen2(ReadOnlySpan<ushort> needs, IEncounterTemplate enc)
private static int GetMoveMask(ReadOnlySpan<ushort> needs, IEncounterTemplate enc)
{
var flags = 0;
if (enc is IMoveset m)
flags = m.Moves.BitOverlap(needs);
if (enc is IMoveset { Moves: { HasMoves: true } m })
flags = m.BitOverlap(needs);
if (enc is IRelearn { Relearn: { HasMoves: true } r })
flags |= r.BitOverlap(needs);
return flags;
}
private static int GetMoveMaskConsiderGen2(ReadOnlySpan<ushort> needs, IEncounterTemplate enc)
{
int flags = GetMoveMask(needs, enc);
if (enc.Generation <= 2)
flags |= GetMoveMaskGen2(needs, enc);
return flags;
@@ -469,6 +435,19 @@ private static int GetMoveMaskGen2(ReadOnlySpan<ushort> needs, IEncounterTemplat
return Moveset.BitOverlap(moves, needs);
}
private static int GetMoveMaskEgg(ReadOnlySpan<ushort> needs, IEncounterTemplate egg)
{
var source = GameData.GetLearnSource(egg.Version);
var eggMoves = source.GetEggMoves(egg.Species, egg.Form);
int flags = Moveset.BitOverlap(eggMoves, needs);
var vt = needs.IndexOf((ushort)Move.VoltTackle);
if (vt != -1 && egg is EncounterEgg { CanHaveVoltTackle: true })
flags |= 1 << vt;
else if (egg.Generation <= 2)
flags |= GetMoveMaskGen2(needs, egg);
return flags;
}
private static bool HasAllNeededMovesSlot(ReadOnlySpan<ushort> needs, IEncounterTemplate slot)
{
if (slot is IMoveset m)
@@ -482,6 +461,25 @@ private static bool HasAllNeededMovesSlot(ReadOnlySpan<ushort> needs, IEncounter
return false;
}
private static bool HasAllNeededMovesEgg(ReadOnlySpan<ushort> needs, IEncounterTemplate egg)
{
int flags = GetMoveMaskEgg(needs, egg);
return flags == (1 << needs.Length) - 1;
}
private static bool GetHasAllNeededMoves(ReadOnlySpan<ushort> needs, IEncounterTemplate enc)
{
int flags = GetMoveMask(needs, enc);
return flags == (1 << needs.Length) - 1;
}
private static bool GetHasAllNeededMovesConsiderGen2(ReadOnlySpan<ushort> needs, IEncounterTemplate enc)
{
// Some rare encounters have special moves hidden in the Relearn section (Gen7 Wormhole Ho-Oh). Include relearn moves
int flags = GetMoveMaskConsiderGen2(needs, enc);
return flags == (1 << needs.Length) - 1;
}
private static bool HasAllNeededMovesEncounter2(ReadOnlySpan<ushort> needs, IEncounterTemplate enc)
{
int flags = GetMoveMaskGen2(needs, enc);