using System; using System.Collections.Generic; using System.Linq; namespace PKHeX.Core { /// /// Logic for getting valid movesets. /// public static class MoveSetApplicator { /// /// Gets a moveset for the provided data. /// /// PKM to generate for /// Full movepool & shuffling /// 4 moves public static int[] GetMoveSet(this PKM pk, bool random = false) { var la = new LegalityAnalysis(pk); var moves = la.GetMoveSet(random); if (random) return moves; var clone = pk.Clone(); clone.SetMoves(moves); clone.SetMaximumPPCurrent(moves); var newLa = new LegalityAnalysis(clone); // ReSharper disable once TailRecursiveCall return newLa.Valid ? moves : GetMoveSet(pk, true); } /// /// Gets a moveset for the provided data. /// /// Precomputed optional /// Full movepool & shuffling /// 4 moves public static int[] GetMoveSet(this LegalityAnalysis la, bool random = false) { int[] m = la.GetSuggestedCurrentMoves(random ? MoveSourceType.All : MoveSourceType.Encounter); var learn = la.GetSuggestedMovesAndRelearn(); if (!m.All(z => learn.Contains(z))) m = m.Intersect(learn).ToArray(); if (random && !la.pkm.IsEgg) Util.Shuffle(m.AsSpan()); const int count = 4; if (m.Length > count) return m.SliceEnd(m.Length - count); Array.Resize(ref m, count); return m; } /// /// Fetches based on the provided . /// /// Pokémon to modify. /// Encounter the relearn moves should be suggested for. If not provided, will try to detect it via legality analysis. /// best suited for the current data. public static IReadOnlyList GetSuggestedRelearnMoves(this PKM pk, IEncounterTemplate? enc = null) => GetSuggestedRelearnMoves(new LegalityAnalysis(pk), enc); /// /// Fetches based on the provided . /// /// which contains parsed information pertaining to legality. /// Encounter the relearn moves should be suggested for. If not provided, will try to detect it via legality analysis. /// best suited for the current data. public static IReadOnlyList GetSuggestedRelearnMoves(this LegalityAnalysis legal, IEncounterTemplate? enc = null) { enc ??= legal.EncounterOriginal; var m = legal.GetSuggestedRelearnMovesFromEncounter(enc); if (m.Any(z => z != 0)) return m; if (enc is MysteryGift or EncounterEgg) return m; if (enc is EncounterSlot6AO {CanDexNav: true} dn) { var moves = legal.Info.Moves; for (int i = 0; i < moves.Length; i++) { if (!moves[i].ShouldBeInRelearnMoves()) continue; var move = legal.pkm.GetMove(i); if (dn.CanBeDexNavMove(move)) return new[] { move, 0, 0, 0 }; } } if (enc is EncounterSlot8b { IsUnderground: true } ug) { var moves = legal.Info.Moves; for (int i = 0; i < moves.Length; i++) { if (!moves[i].ShouldBeInRelearnMoves()) continue; var move = legal.pkm.GetMove(i); if (ug.CanBeUndergroundMove(move)) return new[] { move, 0, 0, 0 }; } if (ug.GetBaseEggMove(out int any)) return new[] { any, 0, 0, 0 }; } var encounter = EncounterSuggestion.GetSuggestedMetInfo(legal.pkm); if (encounter is IRelearn {Relearn: {Count: > 0} r}) return r; return m; } } }