using System; namespace PKHeX.Core; /// /// Logic for getting valid movesets. /// public static class MoveSetApplicator { extension(PKM pk) { /// /// Applies a new legal moveset to the , with option to apply random moves instead. /// /// True to apply a random moveset, false to apply a level-up moveset. public void SetMoveset(bool random = false) { Span moves = stackalloc ushort[4]; pk.GetMoveSet(moves, random); pk.SetMoves(moves); } /// /// Applies the suggested Relearn Moves to the . /// /// Legality Analysis to use. public void SetRelearnMoves(LegalityAnalysis la) { Span moves = stackalloc ushort[4]; la.GetSuggestedRelearnMoves(moves); pk.SetRelearnMoves(moves); } /// /// Gets a moveset for the provided data. /// /// Result storage /// Full movepool & shuffling /// 4 moves public void GetMoveSet(Span moves, bool random = false) { var la = new LegalityAnalysis(pk); la.GetMoveSet(moves, random); if (random) return; var clone = pk.Clone(); clone.SetMoves(moves); var newLa = new LegalityAnalysis(clone); if (!newLa.Valid) newLa.GetMoveSet(moves, true); } } extension(LegalityAnalysis la) { /// /// Gets a moveset for the provided data. /// /// Result storage /// Full movepool & shuffling /// 4 moves public void GetMoveSet(Span moves, bool random = false) { la.GetSuggestedCurrentMoves(moves, random ? MoveSourceType.All : MoveSourceType.Encounter); if (random && !la.Entity.IsEgg) Util.Rand.Shuffle(moves); } /// /// Fetches based on the provided . /// /// Result storage /// Encounter the relearn moves should be suggested for. If not provided, will use the original encounter from the analysis. /// best suited for the current data. public void GetSuggestedRelearnMoves(Span moves, IEncounterTemplate? enc = null) { enc ??= la.EncounterOriginal; la.GetSuggestedRelearnMovesFromEncounter(moves, enc); if (moves[0] != 0) return; if (enc is MysteryGift or IEncounterEgg) return; if (enc is ISingleMoveBonus {IsMoveBonusPossible: true} bonus) { var chk = la.Info.Moves; for (int i = 0; i < chk.Length; i++) { if (!chk[i].ShouldBeInRelearnMoves()) continue; var move = la.Entity.GetMove(i); if (!bonus.IsMoveBonus(move)) continue; moves.Clear(); moves[0] = move; return; } if (bonus.IsMoveBonusRequired && bonus.TryGetRandomMoveBonus(out var bonusMove)) { moves.Clear(); moves[0] = bonusMove; return; } } var encounter = EncounterSuggestion.GetSuggestedMetInfo(la.Entity); if (encounter is IRelearn {Relearn: {HasMoves:true} r}) r.CopyTo(moves); } } }