PKHeX/PKHeX.Core/Editing/Applicators/MoveSetApplicator.cs

120 lines
4.2 KiB
C#

using System;
namespace PKHeX.Core;
/// <summary>
/// Logic for getting valid movesets.
/// </summary>
public static class MoveSetApplicator
{
/// <summary>
/// Applies a new legal moveset to the <see cref="pk"/>, with option to apply random moves instead.
/// </summary>
/// <param name="pk">Pokémon to modify.</param>
/// <param name="random">True to apply a random moveset, false to apply a level-up moveset.</param>
public static void SetMoveset(this PKM pk, bool random = false)
{
Span<ushort> moves = stackalloc ushort[4];
pk.GetMoveSet(moves, random);
pk.SetMoves(moves);
}
/// <summary>
/// Applies the suggested Relearn Moves to the <see cref="pk"/>.
/// </summary>
/// <param name="pk">Pokémon to modify.</param>
/// <param name="la">Legality Analysis to use.</param>
public static void SetRelearnMoves(this PKM pk, LegalityAnalysis la)
{
Span<ushort> moves = stackalloc ushort[4];
la.GetSuggestedRelearnMoves(moves);
pk.SetRelearnMoves(moves);
}
/// <summary>
/// Gets a moveset for the provided <see cref="PKM"/> data.
/// </summary>
/// <param name="pk">PKM to generate for</param>
/// <param name="moves">Result storage</param>
/// <param name="random">Full movepool &amp; shuffling</param>
/// <returns>4 moves</returns>
public static void GetMoveSet(this PKM pk, Span<ushort> 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)
return;
// ReSharper disable once TailRecursiveCall
GetMoveSet(pk, moves, true);
}
/// <summary>
/// Gets a moveset for the provided <see cref="PKM"/> data.
/// </summary>
/// <param name="la">Precomputed optional</param>
/// <param name="moves">Result storage</param>
/// <param name="random">Full movepool &amp; shuffling</param>
/// <returns>4 moves</returns>
public static void GetMoveSet(this LegalityAnalysis la, Span<ushort> moves, bool random = false)
{
la.GetSuggestedCurrentMoves(moves, random ? MoveSourceType.All : MoveSourceType.Encounter);
if (random && !la.Entity.IsEgg)
Util.Rand.Shuffle(moves);
}
/// <summary>
/// Fetches <see cref="PKM.RelearnMoves"/> based on the provided <see cref="LegalityAnalysis"/>.
/// </summary>
/// <param name="legal"><see cref="LegalityAnalysis"/> which contains parsed information pertaining to legality.</param>
/// <param name="moves">Result storage</param>
/// <param name="enc">Encounter the relearn moves should be suggested for. If not provided, will use the original encounter from the analysis. </param>
/// <returns><see cref="PKM.RelearnMoves"/> best suited for the current <see cref="PKM"/> data.</returns>
public static void GetSuggestedRelearnMoves(this LegalityAnalysis legal, Span<ushort> moves, IEncounterTemplate? enc = null)
{
enc ??= legal.EncounterOriginal;
legal.GetSuggestedRelearnMovesFromEncounter(moves, enc);
if (moves[0] != 0)
return;
if (enc is MysteryGift or IEncounterEgg)
return;
if (enc is ISingleMoveBonus {IsMoveBonusPossible: true} bonus)
{
var chk = legal.Info.Moves;
for (int i = 0; i < chk.Length; i++)
{
if (!chk[i].ShouldBeInRelearnMoves())
continue;
var move = legal.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(legal.Entity);
if (encounter is IRelearn {Relearn: {HasMoves:true} r})
r.CopyTo(moves);
}
}