Condense some expressions for move fetch

This commit is contained in:
Kurt 2023-04-23 15:51:48 -07:00
parent 599387e7aa
commit b417964193
35 changed files with 184 additions and 337 deletions

View File

@ -106,13 +106,15 @@ private static int GetCircularOnce<T>(T[] items, T current, Span<T> result)
var currentIndex = Array.IndexOf(items, current);
if (currentIndex < 0)
currentIndex = items.Length - 2;
return GetCircularOnce(items, currentIndex, result);
}
int ctr = 0;
for (int i = currentIndex + 1; i < items.Length; i++)
result[ctr++] = items[i];
for (int i = 0; i <= currentIndex; i++)
result[ctr++] = items[i];
return ctr;
private static int GetCircularOnce<T>(ReadOnlySpan<T> items, int startIndex, Span<T> result)
{
var tail = items[(startIndex + 1)..];
tail.CopyTo(result);
items[..startIndex].CopyTo(result[tail.Length..]);
return items.Length;
}
private static readonly Ball[] BallList = (Ball[])Enum.GetValues(typeof(Ball));

View File

@ -87,8 +87,11 @@ private static string[][] GetPropArray(IReadOnlyList<Type> types, IReadOnlyList<
for (int i = 0; i < p.Length; i++)
{
var props = ReflectUtil.GetPropertiesPublic(types[i]);
p[i] = props.Concat(extra).OrderBy(a => a).ToArray();
var type = types[i];
var props = ReflectUtil.GetPropertiesPublic(type);
var combine = props.Concat(extra).ToArray();
Array.Sort(combine);
p[i] = combine;
}
// Properties for any PKM
@ -96,14 +99,20 @@ private static string[][] GetPropArray(IReadOnlyList<Type> types, IReadOnlyList<
var first = p[0];
var any = new HashSet<string>(first);
var all = new HashSet<string>(first);
for (int i = 1; i < p.Length; i++)
foreach (var set in p[1..])
{
any.UnionWith(p[i]);
all.IntersectWith(p[i]);
any.UnionWith(set);
all.IntersectWith(set);
}
result[0] = any.OrderBy(z => z).ToArray();
result[^1] = all.OrderBy(z => z).ToArray();
var arrAny = any.ToArray();
Array.Sort(arrAny);
result[0] = arrAny;
var arrAll = all.ToArray();
Array.Sort(arrAll);
result[^1] = arrAll;
return result;
}
@ -175,7 +184,9 @@ public static IEnumerable<string> GetTypesImplementing(string property)
return null;
}
int index = typeIndex - 1 >= Props.Length ? 0 : typeIndex - 1; // All vs Specific
int index = typeIndex - 1;
if ((uint)index >= Props.Length)
index = 0; // All vs Specific
var pr = Props[index];
if (!pr.TryGetValue(propertyName, out var info))
return null;
@ -188,14 +199,20 @@ public static IEnumerable<string> GetTypesImplementing(string property)
/// <param name="il">Instructions to initialize.</param>
public static void ScreenStrings(IEnumerable<StringInstruction> il)
{
foreach (var i in il.Where(i => !i.PropertyValue.All(char.IsDigit)))
foreach (var i in il)
{
string pv = i.PropertyValue;
var pv = i.PropertyValue;
if (pv.All(char.IsDigit))
continue;
if (pv.StartsWith(CONST_SPECIAL) && !pv.StartsWith(CONST_BYTES, StringComparison.Ordinal))
{
var str = pv.AsSpan(1);
if (StringInstruction.IsRandomRange(str))
{
i.SetRandomRange(str);
continue;
}
}
SetInstructionScreenedValue(i);
@ -222,13 +239,29 @@ private static void SetInstructionScreenedValue(StringInstruction i)
}
}
private static Dictionary<string, PropertyInfo> GetProps(PKM pk)
{
var type = pk.GetType();
var typeIndex = Array.IndexOf(Types, type);
return Props[typeIndex];
}
/// <summary>
/// Checks if the object is filtered by the provided <see cref="filters"/>.
/// </summary>
/// <param name="filters">Filters which must be satisfied.</param>
/// <param name="pk">Object to check.</param>
/// <returns>True if <see cref="pk"/> matches all filters.</returns>
public static bool IsFilterMatch(IEnumerable<StringInstruction> filters, PKM pk) => filters.All(z => IsFilterMatch(z, pk, Props[Array.IndexOf(Types, pk.GetType())]));
public static bool IsFilterMatch(IEnumerable<StringInstruction> filters, PKM pk)
{
var props = GetProps(pk);
foreach (var filter in filters)
{
if (!IsFilterMatch(filter, pk, props))
return false;
}
return true;
}
/// <summary>
/// Checks if the object is filtered by the provided <see cref="filters"/>.
@ -266,7 +299,9 @@ public static bool IsFilterMatch(IEnumerable<StringInstruction> filters, object
{
if (cmd.PropertyName is PROP_TYPENAME)
{
if (!cmd.Comparer.IsCompareEquivalence(cmd.PropertyValue == obj.GetType().Name))
var type = obj.GetType();
var typeName = type.Name;
if (!cmd.Comparer.IsCompareEquivalence(cmd.PropertyValue == typeName))
return false;
continue;
}
@ -315,12 +350,12 @@ internal static ModifyResult TryModifyPKM(PKM pk, IEnumerable<StringInstruction>
return ModifyResult.Invalid;
var info = new BatchInfo(pk);
var pi = Props[Array.IndexOf(Types, pk.GetType())];
var props = GetProps(pk);
foreach (var cmd in filters)
{
try
{
if (!IsFilterMatch(cmd, info, pi))
if (!IsFilterMatch(cmd, info, props))
return ModifyResult.Filtered;
}
// Swallow any error because this can be malformed user input.
@ -336,7 +371,7 @@ internal static ModifyResult TryModifyPKM(PKM pk, IEnumerable<StringInstruction>
{
try
{
var tmp = SetPKMProperty(cmd, info, pi);
var tmp = SetPKMProperty(cmd, info, props);
if (tmp != ModifyResult.Modified)
result = tmp;
}
@ -433,7 +468,7 @@ private static bool IsPropertyFiltered(StringInstruction cmd, PKM pk, IReadOnlyD
return false;
string val = cmd.PropertyValue;
if (cmd.PropertyValue.StartsWith(CONST_POINTER) && props.TryGetValue(val[1..], out var opi))
if (val.StartsWith(CONST_POINTER) && props.TryGetValue(val[1..], out var opi))
{
var result = opi.GetValue(pk) ?? throw new NullReferenceException();
return cmd.Comparer.IsCompareOperator(pi.CompareTo(pk, result));

View File

@ -55,23 +55,9 @@ private static void GetEncounterMoves(IEncounterTemplate enc, Span<ushort> moves
private static void CheckEncounterMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, EncounterEgg egg)
{
ReadOnlySpan<ushort> eggMoves, levelMoves;
if (egg.Version is GameVersion.C)
{
var inst = LearnSource2C.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
else
{
var inst = LearnSource2GS.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
ILearnSource inst = egg.Version == GameVersion.C ? LearnSource2C.Instance : LearnSource2GS.Instance;
var eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
var levelMoves = inst.GetInheritMoves(egg.Species, egg.Form);
for (var i = result.Length - 1; i >= 0; i--)
{

View File

@ -66,39 +66,15 @@ private static void CheckNincadaMoves(Span<MoveResult> result, ReadOnlySpan<usho
private static void CheckEncounterMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, EncounterEgg egg)
{
ReadOnlySpan<ushort> eggMoves, levelMoves;
if (egg.Version is GameVersion.E)
ILearnSource inst = egg.Version switch
{
var inst = LearnSource3E.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
else if (egg.Version is GameVersion.FR)
{
var inst = LearnSource3FR.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
else if (egg.Version is GameVersion.LG)
{
var inst = LearnSource3LG.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
else
{
var inst = LearnSource3RS.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
GameVersion.E => LearnSource3E.Instance,
GameVersion.FR => LearnSource3FR.Instance,
GameVersion.LG => LearnSource3LG.Instance,
_ => LearnSource3RS.Instance,
};
var eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
var levelMoves = inst.GetInheritMoves(egg.Species, egg.Form);
for (var i = result.Length - 1; i >= 0; i--)
{
@ -172,13 +148,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvolutionHistory history, IEn
{
var shedinja = LearnSource3E.Instance;
var moves = shedinja.GetLearnset((int)Species.Ninjask, 0);
(bool HasMoves, int start, int end) = moves.GetMoveRange(evos[0].LevelMax, 20);
if (HasMoves)
{
var all = moves.Moves;
for (int i = start; i < end; i++)
result[all[i]] = true;
}
var span = moves.GetMoveRange(evos[0].LevelMax, 20);
foreach (var move in span)
result[move] = true;
}
}

View File

@ -58,31 +58,15 @@ private static void CheckNincadaMoves(Span<MoveResult> result, ReadOnlySpan<usho
private static void CheckEncounterMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, EncounterEgg egg)
{
ReadOnlySpan<ushort> eggMoves, levelMoves;
if (egg.Version <= GameVersion.SS) // HG/SS
ILearnSource inst = egg.Version switch
{
var inst = LearnSource4HGSS.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
else if (egg.Version is GameVersion.Pt)
{
var inst = LearnSource4Pt.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
else
{
var inst = LearnSource4DP.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
// HG/SS
<= GameVersion.SS => LearnSource4HGSS.Instance,
GameVersion.Pt => LearnSource4Pt.Instance,
_ => LearnSource4DP.Instance,
};
var eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
var levelMoves = inst.GetInheritMoves(egg.Species, egg.Form);
for (var i = result.Length - 1; i >= 0; i--)
{
@ -170,13 +154,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvolutionHistory history, IEn
{
var shedinja = LearnSource4Pt.Instance;
var moves = shedinja.GetLearnset((int)Species.Ninjask, 0);
(bool HasMoves, int start, int end) = moves.GetMoveRange(evos[0].LevelMax, 20);
if (HasMoves)
{
var all = moves.Moves;
for (int i = start; i < end; i++)
result[all[i]] = true;
}
var span = moves.GetMoveRange(evos[0].LevelMax, 20);
foreach (var move in span)
result[move] = true;
}
}

View File

@ -28,23 +28,9 @@ public sealed class LearnGroup5 : ILearnGroup
private static void CheckEncounterMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, EncounterEgg egg)
{
ReadOnlySpan<ushort> eggMoves, levelMoves;
if (egg.Version > GameVersion.B) // B2/W2
{
var inst = LearnSource5B2W2.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
else
{
var inst = LearnSource5BW.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
ILearnSource inst = egg.Version > GameVersion.B ? LearnSource5B2W2.Instance : LearnSource5BW.Instance;
var eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
var levelMoves = inst.GetInheritMoves(egg.Species, egg.Form);
for (var i = result.Length - 1; i >= 0; i--)
{

View File

@ -29,23 +29,9 @@ public sealed class LearnGroup6 : ILearnGroup
private static void CheckEncounterMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, EncounterEgg egg)
{
ReadOnlySpan<ushort> eggMoves, levelMoves;
if (egg.Version > GameVersion.Y) // OR/AS
{
var inst = LearnSource6AO.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
else
{
var inst = LearnSource6XY.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
ILearnSource inst = egg.Version > GameVersion.Y ? LearnSource6AO.Instance : LearnSource6XY.Instance;
var eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
var levelMoves = inst.GetInheritMoves(egg.Species, egg.Form);
for (var i = result.Length - 1; i >= 0; i--)
{

View File

@ -36,23 +36,9 @@ public sealed class LearnGroup7 : ILearnGroup
private static void CheckEncounterMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, EncounterEgg egg)
{
ReadOnlySpan<ushort> eggMoves, levelMoves;
if (egg.Version > GameVersion.Y) // OR/AS
{
var inst = LearnSource7USUM.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
else
{
var inst = LearnSource7SM.Instance;
eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
levelMoves = egg.CanInheritMoves
? inst.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
}
ILearnSource inst = egg.Version > GameVersion.MN ? LearnSource7USUM.Instance : LearnSource7SM.Instance;
var eggMoves = inst.GetEggMoves(egg.Species, egg.Form);
var levelMoves = inst.GetInheritMoves(egg.Species, egg.Form);
for (var i = result.Length - 1; i >= 0; i--)
{

View File

@ -71,11 +71,9 @@ private static void CheckSharedMoves(Span<MoveResult> result, ReadOnlySpan<ushor
private static void CheckEncounterMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, EncounterEgg egg)
{
var game = LearnSource8SWSH.Instance;
ReadOnlySpan<ushort> eggMoves = game.GetEggMoves(egg.Species, egg.Form);
ReadOnlySpan<ushort> levelMoves = egg.CanInheritMoves
? game.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
ILearnSource game = LearnSource8SWSH.Instance;
var eggMoves = game.GetEggMoves(egg.Species, egg.Form);
var levelMoves = game.GetInheritMoves(egg.Species, egg.Form);
for (var i = result.Length - 1; i >= 0; i--)
{

View File

@ -56,11 +56,9 @@ private static void CheckSharedMoves(Span<MoveResult> result, ReadOnlySpan<ushor
private static void CheckEncounterMoves(Span<MoveResult> result, ReadOnlySpan<ushort> current, EncounterEgg egg)
{
var game = LearnSource9SV.Instance;
ReadOnlySpan<ushort> eggMoves = game.GetEggMoves(egg.Species, egg.Form);
ReadOnlySpan<ushort> levelMoves = egg.CanInheritMoves
? game.GetLearnset(egg.Species, egg.Form).Moves
: ReadOnlySpan<ushort>.Empty;
ILearnSource game = LearnSource9SV.Instance;
var eggMoves = game.GetEggMoves(egg.Species, egg.Form);
var levelMoves = game.GetInheritMoves(egg.Species, egg.Form);
for (var i = result.Length - 1; i >= 0; i--)
{

View File

@ -81,13 +81,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
{
var learn = Learnsets[evo.Species];
var min = ParseSettings.AllowGen1Tradeback && ParseSettings.AllowGen2MoveReminder(pk) ? 1 : evo.LevelMin;
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax, min);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax, min);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -81,13 +81,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
{
var learn = GetLearnset(evo.Species, evo.Form);
var min = ParseSettings.AllowGen1Tradeback && ParseSettings.AllowGen2MoveReminder(pk) ? 1 : evo.LevelMin;
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax, min);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax, min);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -97,16 +97,11 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
{
var learn = GetLearnset(evo.Species, evo.Form);
var min = ParseSettings.AllowGen2MoveReminder(pk) ? 1 : evo.LevelMin;
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax, min);
if (hasMoves)
var span = learn.GetMoveRange(evo.LevelMax, min);
foreach (var move in span)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
{
var move = moves[i];
if (!removeVC || move <= Legal.MaxMoveID_1)
result[move] = true;
}
if (!removeVC || move <= Legal.MaxMoveID_1)
result[move] = true;
}
}

View File

@ -83,16 +83,11 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
{
var learn = Learnsets[evo.Species];
var min = ParseSettings.AllowGen2MoveReminder(pk) ? 1 : evo.LevelMin;
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax, min);
if (hasMoves)
var span = learn.GetMoveRange(evo.LevelMax, min);
foreach (var move in span)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
{
var move = moves[i];
if (!removeVC || move <= Legal.MaxMoveID_1)
result[move] = true;
}
if (!removeVC || move <= Legal.MaxMoveID_1)
result[move] = true;
}
}

View File

@ -102,13 +102,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -101,13 +101,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -101,13 +101,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -107,13 +107,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -108,13 +108,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -122,13 +122,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -120,13 +120,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -107,13 +107,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -104,13 +104,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -98,13 +98,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -89,13 +89,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -64,13 +64,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(ReminderBonus);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(ReminderBonus);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -99,13 +99,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(ReminderBonus);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(ReminderBonus);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -102,13 +102,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(ReminderBonus);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(ReminderBonus);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -97,13 +97,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.SharedEggMove))

View File

@ -71,13 +71,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.Machine))

View File

@ -131,13 +131,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.SharedEggMove))

View File

@ -133,13 +133,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
if (types.HasFlag(MoveSourceType.LevelUp))
{
var learn = GetLearnset(evo.Species, evo.Form);
(bool hasMoves, int start, int end) = learn.GetMoveRange(evo.LevelMax);
if (hasMoves)
{
var moves = learn.Moves;
for (int i = end; i >= start; i--)
result[moves[i]] = true;
}
var span = learn.GetMoveRange(evo.LevelMax);
foreach (var move in span)
result[move] = true;
}
if (types.HasFlag(MoveSourceType.SharedEggMove))

View File

@ -32,6 +32,13 @@ public void SetEncounterMoves(ushort species, byte form, int level, Span<ushort>
}
public ReadOnlySpan<ushort> GetEggMoves(ushort species, byte form) => ReadOnlySpan<ushort>.Empty;
public ReadOnlySpan<ushort> GetInheritMoves(ushort species, byte form)
{
if (!Breeding.GetCanInheritMoves(species))
return default;
return GetLearnset(species, form).GetAllMoves();
}
}
/// <summary>

View File

@ -10,7 +10,7 @@ public sealed class Learnset
/// <summary>
/// Moves that can be learned.
/// </summary>
internal readonly ushort[] Moves;
private readonly ushort[] Moves;
/// <summary>
/// Levels at which a move at a given index can be learned.
@ -25,10 +25,12 @@ public Learnset(ushort[] moves, byte[] levels)
Levels = levels;
}
public (bool HasMoves, int Start, int End) GetMoveRange(int maxLevel, int minLevel = 0)
public ReadOnlySpan<ushort> GetAllMoves() => Moves;
public ReadOnlySpan<ushort> GetMoveRange(int maxLevel, int minLevel = 0)
{
if (minLevel <= 1 && maxLevel >= 100)
return (true, 0, Moves.Length - 1);
return Moves;
if (minLevel > maxLevel)
return default;
int start = FindGrq(minLevel);
@ -38,7 +40,8 @@ public Learnset(ushort[] moves, byte[] levels)
if (end < 0)
return default;
return (true, start, end);
var length = end - start + 1;
return Moves.AsSpan(start, length);
}
private int FindGrq(int level, int start = 0)

View File

@ -353,11 +353,9 @@ private static GameVersion GetVersionG3SAV(ReadOnlySpan<byte> data)
case 0: return RS; // save has no battle tower record data
default:
// RS data structure only extends 0x890 bytes; check if any data is present afterwards.
for (int i = 0x890; i < 0xF2C; i += 4)
{
if (ReadUInt64LittleEndian(data[i..]) != 0)
return E;
}
var remainder = data[0x890..0xF2C];
if (remainder.IndexOfAnyExcept<byte>(0) != -1)
return E;
return RS;
}
}