internal static IEnumerable <int> GetValidRelearn(PKM pkm, int species, int form, bool inheritlvlmoves, GameVersion version = Any) { int generation = pkm.Generation; if (generation < 6) { return(Array.Empty <int>()); } var r = new List <int>(); r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, form, 1, version)); if (pkm.Format == 6 && pkm.Species != (int)Species.Meowstic) { form = 0; } r.AddRange(MoveEgg.GetEggMoves(pkm.PersonalInfo, species, form, version, Math.Max(2, generation))); if (inheritlvlmoves) { r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, form, 100, version)); } return(r.Distinct()); }
internal static IEnumerable <int> GetValidRelearn(PKM pkm, int species, bool inheritlvlmoves, GameVersion version = GameVersion.Any) { List <int> r = new List <int> { 0 }; if (pkm.GenNumber < 6 || pkm.VC) { return(r); } r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 1, pkm.AltForm, version)); int form = pkm.AltForm; if (pkm.Format == 6 && pkm.Species != 678) { form = 0; } r.AddRange(MoveEgg.GetEggMoves(pkm, species, form, version)); if (inheritlvlmoves) { r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 100, pkm.AltForm, version)); } return(r.Distinct()); }
private static CheckMoveResult[] ParseMovesWasEggPreRelearn(PKM pkm, IReadOnlyList <int> currentMoves, LegalInfo info, EncounterEgg e) { // Level up moves could not be inherited if Ditto is parent, // that means genderless species and male only species (except Nidoran-M and Volbeat; they breed with Nidoran-F and Illumise) could not have level up moves as an egg var pi = pkm.PersonalInfo; var AllowLevelUp = !pi.Genderless && !(pi.OnlyMale && Breeding.MixedGenderBreeding.Contains(e.Species)); int BaseLevel = AllowLevelUp ? 100 : e.LevelMin; var LevelUp = MoveList.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, BaseLevel); var TradebackPreevo = pkm.Format == 2 && e.Species > 151; var NonTradebackLvlMoves = TradebackPreevo ? MoveList.GetExclusivePreEvolutionMoves(pkm, e.Species, info.EvoChainsAllGens[2], 2, e.Version).Where(m => m > Legal.MaxMoveID_1).ToArray() : Array.Empty <int>(); var Egg = MoveEgg.GetEggMoves(pkm.PersonalInfo, e.Species, e.Form, e.Version, e.Generation); if (info.Generation < 3 && pkm.Format >= 7 && pkm.VC1) { Egg = Array.FindAll(Egg, m => m <= Legal.MaxMoveID_1); } var specialMoves = e.CanHaveVoltTackle ? new[] { (int)Move.VoltTackle } : Array.Empty <int>(); // Volt Tackle for bred Pichu line var source = new MoveParseSource { CurrentMoves = currentMoves, SpecialSource = specialMoves, NonTradeBackLevelUpMoves = NonTradebackLvlMoves, EggLevelUpSource = LevelUp, EggMoveSource = Egg, }; return(ParseMoves(pkm, source, info)); }
private static CheckMoveResult[] ParseMovesRelearn(PKM pkm, int[] Moves, LegalInfo info) { var source = new MoveParseSource { CurrentMoves = Moves, SpecialSource = GetSpecialMoves(info.EncounterMatch), }; if (info.EncounterMatch is EncounterEgg e) { source.EggMoveSource = MoveEgg.GetEggMoves(pkm, e.Species, pkm.AltForm, e.Version); } CheckMoveResult[] res = ParseMoves(pkm, source, info); int[] RelearnMoves = pkm.RelearnMoves; for (int i = 0; i < 4; i++) { if ((pkm.IsEgg || res[i].Flag) && !RelearnMoves.Contains(Moves[i])) { res[i] = new CheckMoveResult(res[i], Severity.Invalid, string.Format(V170, res[i].Comment), res[i].Identifier); } } return(res); }
private static CheckMoveResult[] ParseMovesRelearn(PKM pkm, IReadOnlyList <int> currentMoves, LegalInfo info) { var source = new MoveParseSource { CurrentMoves = currentMoves, SpecialSource = GetSpecialMoves(info.EncounterMatch), }; if (info.EncounterMatch is EncounterEgg e) { source.EggMoveSource = MoveEgg.GetEggMoves(pkm, e.Species, e.Form, e.Version); } var res = ParseMoves(pkm, source, info); var relearn = pkm.RelearnMoves; for (int i = 0; i < 4; i++) { if ((pkm.IsEgg || res[i].Flag) && !relearn.Contains(currentMoves[i])) { res[i] = new CheckMoveResult(res[i], Invalid, string.Format(LMoveRelearnFMiss_0, res[i].Comment), res[i].Identifier); } } return(res); }
private static IEnumerable <int> GetMovesForGeneration(PKM pk, IReadOnlyList <EvoCriteria> dl, int generation) { IEnumerable <int> moves = MoveList.GetValidMoves(pk, dl, generation); if (pk.Format >= 8) { // Shared Egg Moves via daycare // Any egg move can be obtained var evo = dl[dl.Count - 1]; var shared = MoveEgg.GetEggMoves(8, evo.Species, evo.Form, GameVersion.SW); if (shared.Length != 0) { moves = moves.Concat(shared); } } if (pk.Species == (int)Species.Shedinja) { // Leveling up Nincada in Gen3/4 levels up, evolves to Ninjask, applies moves for Ninjask, then spawns Shedinja with the current moveset. // Future games spawn the Shedinja before doing Ninjask moves, so this is a special case. // Can't get more than the evolved-at level move; >=2 special moves will get caught by the legality checker later. if (generation == 3) { return(moves.Concat(Legal.LevelUpE[(int)Species.Ninjask].GetMoves(100, 20))); } if (generation == 4) { return(moves.Concat(Legal.LevelUpPt[(int)Species.Ninjask].GetMoves(100, 20))); } } return(moves); }
/// <summary> /// Gets possible encounters that allow all moves requested to be learned. /// </summary> /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param> /// <param name="needs">Moves which cannot be taught by the player.</param> /// <param name="version">Specific version to iterate for. Necessary for retrieving possible Egg Moves.</param> /// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns> private static IEnumerable <EncounterEgg> GetEggs(PKM pk, IReadOnlyCollection <int> needs, GameVersion version) { if (GameVersion.CXD.Contains(version) || GameVersion.GG.Contains(version)) { yield break; // no eggs from these games } var eggs = EncounterEggGenerator.GenerateEggs(pk, all: true); foreach (var egg in eggs) { if (needs.Count == 0) { yield return(egg); continue; } IEnumerable <int> em = MoveEgg.GetEggMoves(pk, egg.Species, pk.AltForm, version); if (Legal.LightBall.Contains(egg.Species) && needs.Contains(344)) { em = em.Concat(new[] { 344 }); // Volt Tackle } if (!needs.Except(em).Any()) { yield return(egg); } } }
public EggInfoSource(PKM pkm, EncounterEgg e) { // Eggs with special moves cannot inherit levelup moves as the current moves are predefined. AllowInherited = e.Species != 489 && e.Species != 490; // Level up moves can only be inherited if ditto is not the mother. bool AllowLevelUp = Legal.GetCanInheritMoves(e.Species); Base = Legal.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, e.Level); Egg = MoveEgg.GetEggMoves(pkm, e.Species, e.Form, e.Version); LevelUp = AllowLevelUp ? Legal.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, 100).Except(Base).ToList() : (IReadOnlyList <int>)Array.Empty <int>(); Tutor = e.Version == GameVersion.C ? MoveTutor.GetTutorMoves(pkm, e.Species, 0, false, 2).ToList() : (IReadOnlyList <int>)Array.Empty <int>(); // Only TM/HM moves from the source game of the egg, not any other games from the same generation TMHM = MoveTechnicalMachine.GetTMHM(pkm, pkm.Species, pkm.AltForm, e.Generation, e.Version).ToList(); // Non-Base moves that can magically appear in the regular movepool bool volt = (e.Generation > 3 || e.Version == GameVersion.E) && Legal.LightBall.Contains(pkm.Species); if (volt) { Egg = Egg.ToList(); // array->list Egg.Add(344); // Volt Tackle } }
private static IEnumerable <int> GetMovesForGeneration(PKM pk, IReadOnlyList <EvoCriteria> chain, int generation) { IEnumerable <int> moves = MoveList.GetValidMoves(pk, chain, generation); if (generation <= 2) { moves = moves.Concat(MoveList.GetValidMoves(pk, chain, generation, MoveSourceType.LevelUp)); } if (pk.Format >= 8) { // Shared Egg Moves via daycare // Any egg move can be obtained moves = moves.Concat(MoveEgg.GetSharedEggMoves(pk, generation)); // TR moves -- default logic checks the TR flags, so we need to add all possible ones here. if (!(pk.BDSP || pk.LA)) { moves = moves.Concat(MoveTechnicalMachine.GetAllPossibleRecords(pk.Species, pk.Form)); } } if (pk.Species == (int)Species.Shedinja) { // Leveling up Nincada in Gen3/4 levels up, evolves to Ninjask, applies moves for Ninjask, then spawns Shedinja with the current moveset. // Future games spawn the Shedinja before doing Ninjask moves, so this is a special case. // Can't get more than the evolved-at level move; >=2 special moves will get caught by the legality checker later. return(generation switch { 3 => moves.Concat(Legal.LevelUpE [(int)Species.Ninjask].GetMoves(100, 20)), 4 => moves.Concat(Legal.LevelUpPt[(int)Species.Ninjask].GetMoves(100, 20)), _ => moves, });
private static IEnumerable <int> GetMovesForGeneration(PKM pk, IReadOnlyList <EvoCriteria> dl, int generation) { IEnumerable <int> moves = Legal.GetValidMoves(pk, dl, generation); if (generation >= 8) { var evo = dl[dl.Count - 1]; var shared = MoveEgg.GetEggMoves(pk, evo.Species, evo.Form, GameVersion.SW); moves = moves.Concat(shared); } return(moves); }
private static bool GetIsSharedEggMove(PKM pkm, int gen, int move) { if (gen < 8 || pkm.IsEgg) { return(false); } var table = PersonalTable.SWSH; var entry = (PersonalInfoSWSH)table.GetFormeEntry(pkm.Species, pkm.AltForm); var baseSpecies = entry.BaseSpecies; var baseForm = entry.BaseSpeciesForm; var egg = MoveEgg.GetEggMoves(pkm, baseSpecies, baseForm, GameVersion.SW); return(egg.Contains(move)); }
private int[] GetCurrentEggMoves(PKM pk) { var moves = MoveEgg.GetEggMoves(pk, Species, pk.AltForm, Version); if (moves.Length == 0) { moves = MoveLevelUp.GetEncounterMoves(pk, Level, Version); } else if (moves.Length < 4 && pk.Format >= 6) { // Sprinkle in some default level up moves var lvl = Legal.GetBaseEggMoves(pk, Species, Version, Level); moves = lvl.Concat(moves).ToArray(); } return(moves); }
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); }
private int[] GetCurrentEggMoves(PKM pk, GameVersion version) { var moves = MoveEgg.GetEggMoves(pk, Species, Form, version); if (moves.Length == 0) { return(MoveLevelUp.GetEncounterMoves(pk, Level, version)); } if (moves.Length >= 4 || pk.Format < 6) { return(moves); } // Sprinkle in some default level up moves var lvl = Legal.GetBaseEggMoves(pk, Species, Form, version, Level); return(lvl.Concat(moves).ToArray()); }
private static bool GetIsSharedEggMove(PKM pkm, int gen, int move) { if (gen < 8 || pkm.IsEgg) { return(false); } var table = PersonalTable.SWSH; var entry = (PersonalInfoSWSH)table.GetFormeEntry(pkm.Species, pkm.AltForm); var baseSpecies = entry.BaseSpecies; var baseForm = entry.FormIndex; // since we aren't storing entry->seed_poke_index, there's oddballs we can't handle with just personal data (?) if (pkm.Species == (int)Species.Indeedee) { baseForm = pkm.AltForm; } var egg = MoveEgg.GetEggMoves(pkm, baseSpecies, baseForm, GameVersion.SW); return(egg.Contains(move)); }
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); }
private static CheckMoveResult[] ParseMovesWasEggPreRelearn(PKM pkm, int[] Moves, LegalInfo info, EncounterEgg e) { var EventEggMoves = GetSpecialMoves(info.EncounterMatch); bool notEvent = EventEggMoves.Length == 0; // Level up moves could not be inherited if Ditto is parent, // that means genderless species and male only species (except Nidoran-M and Volbeat; they breed with Nidoran-F and Illumise) could not have level up moves as an egg var pi = pkm.PersonalInfo; var AllowLevelUp = notEvent && !pi.Genderless && !(pi.OnlyMale && Legal.MixedGenderBreeding.Contains(e.Species)); int BaseLevel = AllowLevelUp ? 100 : e.LevelMin; var LevelUp = Legal.GetBaseEggMoves(pkm, e.Species, e.Version, BaseLevel); var TradebackPreevo = pkm.Format == 2 && info.EncounterMatch.Species > 151; var NonTradebackLvlMoves = TradebackPreevo ? Legal.GetExclusivePreEvolutionMoves(pkm, info.EncounterMatch.Species, info.EvoChainsAllGens[2], 2, e.Version).Where(m => m > Legal.MaxMoveID_1).ToArray() : Array.Empty <int>(); var Egg = MoveEgg.GetEggMoves(pkm, e.Species, pkm.AltForm, e.Version); if (info.Generation < 3 && pkm.Format >= 7 && pkm.VC1) { Egg = Egg.Where(m => m <= Legal.MaxMoveID_1).ToArray(); } bool volt = (info.Generation > 3 || e.Version == GameVersion.E) && Legal.LightBall.Contains(pkm.Species); var Special = volt && notEvent ? new[] { 344 } : Array.Empty <int>(); // Volt Tackle for bred Pichu line var source = new MoveParseSource { CurrentMoves = Moves, SpecialSource = Special, NonTradeBackLevelUpMoves = NonTradebackLvlMoves, EggLevelUpSource = LevelUp, EggMoveSource = Egg, EggEventSource = EventEggMoves, }; return(ParseMoves(pkm, source, info)); }
internal static IEnumerable <int> GetValidRelearn(PKM pkm, int species, int form, bool inheritlvlmoves, GameVersion version = GameVersion.Any) { if (pkm.GenNumber < 6) { return(Array.Empty <int>()); } var r = new List <int>(); r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 1, form, version)); if (pkm.Format == 6 && pkm.Species != 678) { form = 0; } r.AddRange(MoveEgg.GetEggMoves(pkm, species, form, version)); if (inheritlvlmoves) { r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 100, form, version)); } return(r.Distinct()); }
private static void ParseMovesByGeneration(PKM pkm, IList <CheckMoveResult> res, int gen, LegalInfo info, LearnInfo learnInfo) { var moves = learnInfo.Source.CurrentMoves; bool native = gen == pkm.Format; for (int m = 0; m < 4; m++) { if (IsCheckValid(res[m])) // already validated with another generation { continue; } int move = moves[m]; if (move == 0) { continue; } if (gen <= 2) { if (gen == 2 && !native && move > Legal.MaxMoveID_1 && pkm.VC1) { res[m] = new CheckMoveResult(Unknown, gen, Invalid, LMoveSourceInvalid, Move); continue; } if (gen == 2 && learnInfo.Source.EggMoveSource.Contains(move)) { res[m] = new CheckMoveResult(EggMove, gen, Valid, LMoveSourceEgg, Move); } else if (learnInfo.Source.Base.Contains(move)) { res[m] = new CheckMoveResult(Initial, gen, Valid, native ? LMoveSourceDefault : string.Format(LMoveFDefault_0, gen), Move); } } if (info.EncounterMoves.LevelUpMoves[gen].Contains(move)) { res[m] = new CheckMoveResult(LevelUp, gen, Valid, native ? LMoveSourceLevelUp : string.Format(LMoveFLevelUp_0, gen), Move); } else if (info.EncounterMoves.TMHMMoves[gen].Contains(move)) { res[m] = new CheckMoveResult(TMHM, gen, Valid, native ? LMoveSourceTMHM : string.Format(LMoveFTMHM_0, gen), Move); } else if (info.EncounterMoves.TutorMoves[gen].Contains(move)) { res[m] = new CheckMoveResult(Tutor, gen, Valid, native ? LMoveSourceTutor : string.Format(LMoveFTutor_0, gen), Move); } else if (gen == info.Generation && learnInfo.Source.SpecialSource.Contains(move)) { res[m] = new CheckMoveResult(Special, gen, Valid, LMoveSourceSpecial, Move); } else if (gen >= 8 && MoveEgg.GetIsSharedEggMove(pkm, gen, move)) { res[m] = new CheckMoveResult(Shared, gen, Valid, native ? LMoveSourceShared : string.Format(LMoveSourceSharedF, gen), Move); } if (gen >= 3 || !IsCheckValid(res[m])) { continue; } // Gen1/Gen2 only below if (gen == 2 && learnInfo.Source.NonTradeBackLevelUpMoves.Contains(m)) { learnInfo.Gen2PreevoMoves.Add(m); } else if (gen == 1) { learnInfo.Gen1Moves.Add(m); if (learnInfo.Gen2PreevoMoves.Count != 0) { learnInfo.MixedGen12NonTradeback = true; } } if (pkm.TradebackStatus == TradebackType.Any && info.Generation != gen) { pkm.TradebackStatus = TradebackType.WasTradeback; } } }