public static EggSource2[] Validate(int species, GameVersion version, int[] moves, out bool valid) { var count = Array.IndexOf(moves, 0); if (count == 0) { valid = false; // empty moveset return(Array.Empty <EggSource2>()); } if (count == -1) { count = moves.Length; } var learn = GameData.GetLearnsets(version); var table = GameData.GetPersonal(version); var learnset = learn[species]; var pi = table[species]; var egg = (version == GameVersion.C ? Legal.EggMovesC : Legal.EggMovesGS)[species].Moves; var value = new BreedInfo <EggSource2>(count, learnset, moves, level); { bool inherit = Breeding.GetCanInheritMoves(species); MarkMovesForOrigin(value, egg, count, inherit, pi, version); valid = RecurseMovesForOrigin(value, count - 1); } if (!valid) { CleanResult(value.Actual, value.Possible); } return(value.Actual); }
private static void MarkMovesForOrigin(BreedInfo <EggSource6> value, ICollection <int> eggMoves, int count, bool inheritLevelUp) { var possible = value.Possible; var learn = value.Learnset; var baseEgg = value.Learnset.GetBaseEggMoves(value.Level); var moves = value.Moves; for (int i = 0; i < count; i++) { var move = moves[i]; if (baseEgg.IndexOf(move) != -1) { possible[i] |= 1 << (int)Base; } if (inheritLevelUp && learn.GetLevelLearnMove(move) != -1) { possible[i] |= 1 << (int)ParentLevelUp; } if (eggMoves.Contains(move)) { possible[i] |= 1 << (int)ParentEgg; } } }
private static bool RecurseMovesForOrigin(BreedInfo <EggSource2> info, int start, EggSource2 type = Max) { int i = start; do { if (type != Base) { if (RecurseMovesForOrigin(info, i, Base)) { return(true); } } var flag = 1 << (int)Base; if (type != Base) { flag = ~flag; } var permit = info.Possible[i]; if ((permit & flag) == 0) { return(false); } info.Actual[i] = type == Base ? Base : GetFirstType(permit); } while (--i >= 0); return(VerifyBaseMoves(info)); }
public static EggSource6[] Validate(int generation, int species, int form, GameVersion version, ReadOnlySpan <int> moves, out bool valid) { var count = moves.IndexOf(0); if (count == 0) { valid = false; // empty moveset return(Array.Empty <EggSource6>()); } if (count == -1) { count = moves.Length; } var learn = GameData.GetLearnsets(version); var table = GameData.GetPersonal(version); var index = table.GetFormIndex(species, form); var learnset = learn[index]; var egg = MoveEgg.GetEggMoves(generation, species, form, version); var actual = new EggSource6[count]; Span <byte> possible = stackalloc byte[count]; var value = new BreedInfo <EggSource6>(actual, possible, learnset, moves, level); if (species is (int)Species.Pichu && moves[count - 1] is (int)Move.VoltTackle) { actual[--count] = VoltTackle; } if (count == 0) { valid = VerifyBaseMoves(value); } else { bool inherit = Breeding.GetCanInheritMoves(species); MarkMovesForOrigin(value, egg, count, inherit); valid = RecurseMovesForOrigin(value, count - 1); } if (!valid) { CleanResult(actual, possible); } return(value.Actual); }
public static EggSource34[] Validate(int species, GameVersion version, int[] moves, out bool valid) { var count = Array.IndexOf(moves, 0); if (count == 0) { valid = false; // empty moveset return(Array.Empty <EggSource34>()); } if (count == -1) { count = moves.Length; } var learn = GameData.GetLearnsets(version); var table = GameData.GetPersonal(version); var learnset = learn[species]; var pi = table[species]; var egg = Legal.EggMovesRS[species].Moves; var value = new BreedInfo <EggSource34>(count, learnset, moves, level); if (species is (int)Species.Pichu && moves[count - 1] is (int)Move.VoltTackle && version == GameVersion.E) { value.Actual[--count] = VoltTackle; } if (count == 0) { valid = VerifyBaseMoves(value); } else { bool inherit = Breeding.GetCanInheritMoves(species); MarkMovesForOrigin(value, egg, count, inherit, pi); valid = RecurseMovesForOrigin(value, count - 1); } if (!valid) { CleanResult(value.Actual, value.Possible); } return(value.Actual); }
private static void MarkMovesForOrigin(BreedInfo <EggSource2> value, ICollection <int> eggMoves, int count, bool inheritLevelUp, PersonalInfo info, GameVersion version) { var possible = value.Possible; var learn = value.Learnset; var baseEgg = value.Learnset.GetBaseEggMoves(value.Level); var tm = info.TMHM; var moves = value.Moves; for (int i = 0; i < count; i++) { var move = moves[i]; if (baseEgg.IndexOf(move) != -1) { possible[i] |= 1 << (int)Base; } if (inheritLevelUp && learn.GetLevelLearnMove(move) != -1) { possible[i] |= 1 << (int)ParentLevelUp; } if (eggMoves.Contains(move)) { possible[i] |= 1 << (int)FatherEgg; } var tmIndex = Array.IndexOf(Legal.TMHM_GSC, move, 0, 50); if (tmIndex != -1 && tm[tmIndex]) { possible[i] |= 1 << (int)FatherTM; } if (version is GameVersion.C) { var tutorIndex = Array.IndexOf(Legal.Tutors_GSC, move); if (tutorIndex != -1 && tm[57 + tutorIndex]) { possible[i] |= 1 << (int)Tutor; } } } }
public static EggSource6[] Validate(int generation, int species, int form, GameVersion version, int[] moves, out bool valid) { var count = Array.IndexOf(moves, 0); if (count == 0) { valid = false; // empty moveset return(Array.Empty <EggSource6>()); } if (count == -1) { count = moves.Length; } var learn = GameData.GetLearnsets(version); var table = GameData.GetPersonal(version); var index = table.GetFormIndex(species, form); var learnset = learn[index]; var egg = MoveEgg.GetEggMoves(generation, species, form, version); var value = new BreedInfo <EggSource6>(count, learnset, moves, 1); if (moves[count - 1] is (int)Move.VoltTackle) { if (--count == 0) { valid = false; // must have base moves; sanity check return(Array.Empty <EggSource6>()); } value.Actual[count] = VoltTackle; } bool inherit = Breeding.GetCanInheritMoves(species); MarkMovesForOrigin(value, egg, count, inherit); valid = RecurseMovesForOrigin(value, count - 1); return(value.Actual); }
public static EggSource5[] Validate(int species, GameVersion version, int[] moves, out bool valid) { var count = Array.IndexOf(moves, 0); if (count == 0) { valid = false; // empty moveset return(Array.Empty <EggSource5>()); } if (count == -1) { count = moves.Length; } var learn = GameData.GetLearnsets(version); var table = GameData.GetPersonal(version); var learnset = learn[species]; var pi = table[species]; var egg = Legal.EggMovesBW[species].Moves; var value = new BreedInfo <EggSource5>(count, learnset, moves, level); if (moves[count - 1] is (int)Move.VoltTackle) { if (--count == 0) { valid = false; // must have base moves; sanity check return(Array.Empty <EggSource5>()); } value.Actual[count] = VoltTackle; } bool inherit = Breeding.GetCanInheritMoves(species); MarkMovesForOrigin(value, egg, count, inherit, pi); valid = RecurseMovesForOrigin(value, count - 1); return(value.Actual); }
private static bool RecurseMovesForOrigin(BreedInfo <EggSource6> info, int start, EggSource6 type = Max - 1) { int i = start; do { var unpeel = type - 1; if (unpeel != 0 && RecurseMovesForOrigin(info, i, unpeel)) { return(true); } var permit = info.Possible[i]; if ((permit & (1 << (int)type)) == 0) { return(false); } info.Actual[i] = type; } while (--i >= 0); return(VerifyBaseMoves(info)); }
private static void MarkMovesForOrigin(BreedInfo <EggSource34> value, ICollection <int> eggMoves, int count, bool inheritLevelUp, PersonalInfo info) { var possible = value.Possible; var learn = value.Learnset; var baseEgg = value.Learnset.GetBaseEggMoves(value.Level); var tm = info.TMHM; var tmlist = Legal.TM_3.AsSpan(0, 50); var moves = value.Moves; for (int i = 0; i < count; i++) { var move = moves[i]; if (baseEgg.IndexOf(move) != -1) { possible[i] |= 1 << (int)Base; } if (inheritLevelUp && learn.GetLevelLearnMove(move) != -1) { possible[i] |= 1 << (int)ParentLevelUp; } if (eggMoves.Contains(move)) { possible[i] |= 1 << (int)FatherEgg; } var tmIndex = tmlist.IndexOf(move); if (tmIndex != -1 && tm[tmIndex]) { possible[i] |= 1 << (int)FatherTM; } } }
private static bool VerifyBaseMoves(BreedInfo <EggSource6> info) { var count = 0; foreach (var x in info.Actual) { if (x == Base) { count++; } else { break; } } var moves = info.Moves; if (count == -1) { return(moves[moves.Length - 1] != 0); } var baseMoves = info.Learnset.GetBaseEggMoves(info.Level); if (baseMoves.Length < count) { return(false); } if (moves[moves.Length - 1] == 0 && count != baseMoves.Length) { return(false); } for (int i = count - 1, b = baseMoves.Length - 1; i >= 0; i--, b--) { var move = moves[i]; var expect = baseMoves[b]; if (expect != move) { return(false); } } // A low-index base egg move may be nudged out, but can only reappear if sufficient non-base moves are before it. if (baseMoves.Length == count) { return(true); } for (int i = count; i < info.Actual.Length; i++) { var isBase = (info.Possible[i] & (1 << (int)Base)) != 0; if (!isBase) { continue; } var baseIndex = baseMoves.IndexOf(info.Moves[i]); var min = info.Moves.Length - baseMoves.Length + baseIndex; if (i <= min + count) { return(false); } } return(true); }