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);
}
}
}