Refactor move selection prevention to use interface

This commit is contained in:
Deukhoofd 2025-06-28 10:36:43 +02:00
parent 04cf585f5a
commit 2319160b52
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
12 changed files with 59 additions and 27 deletions

View File

@ -331,7 +331,8 @@ public class BattleImpl : ScriptSource, IBattle
moveChoice.ChosenMove.MoveData.Target, moveChoice.User)) moveChoice.ChosenMove.MoveData.Target, moveChoice.User))
return false; return false;
var preventMove = false; var preventMove = false;
choice.RunScriptHook(script => script.PreventMoveSelection(moveChoice, ref preventMove)); choice.RunScriptHookInterface<IScriptPreventMoveSelection>(script =>
script.PreventMoveSelection(moveChoice, ref preventMove));
if (preventMove) if (preventMove)
return false; return false;
} }

View File

@ -61,13 +61,6 @@ public abstract class Script : IDeepCloneable
{ {
} }
/// <summary>
/// Override to customize whether the move can be selected at all.
/// </summary>
public virtual void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
{
}
/// <summary> /// <summary>
/// Force a certain move choice to be selected. If the choice is set, the Pokemon will be forced /// Force a certain move choice to be selected. If the choice is set, the Pokemon will be forced
/// to use it, and will not be able to select any other choice. /// to use it, and will not be able to select any other choice.
@ -855,3 +848,14 @@ public interface IScriptOnInitialize
/// </summary> /// </summary>
void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters); void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters);
} }
/// <summary>
/// This interface is used to allow scripts to prevent a move from being selected.
/// </summary>
public interface IScriptPreventMoveSelection
{
/// <summary>
/// Override to customize whether the move can be selected at all.
/// </summary>
void PreventMoveSelection(IMoveChoice choice, ref bool prevent);
}

View File

@ -13,7 +13,6 @@ public static class ScriptExecution
/// <summary> /// <summary>
/// Executes a hook on all scripts in a source. /// Executes a hook on all scripts in a source.
/// </summary> /// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RunScriptHook(this IScriptSource source, Action<Script> hook) public static void RunScriptHook(this IScriptSource source, Action<Script> hook)
{ {
var iterator = source.GetScripts(); var iterator = source.GetScripts();
@ -37,6 +36,34 @@ public static class ScriptExecution
} }
} }
/// <summary>
/// Executes a hook on all scripts in a source.
/// </summary>
public static void RunScriptHookInterface<TScriptHook>(this IScriptSource source, Action<TScriptHook> hook)
{
var iterator = source.GetScripts();
List<ScriptCategory>? suppressedCategories = null;
foreach (var container in iterator)
{
if (container.IsEmpty)
continue;
var script = container.Script;
if (script is IScriptOnBeforeAnyHookInvoked onBeforeAnyHookInvoked)
onBeforeAnyHookInvoked.OnBeforeAnyHookInvoked(ref suppressedCategories);
}
foreach (var container in iterator)
{
if (container.IsEmpty)
continue;
var script = container.Script;
if (script is not TScriptHook scriptHook)
continue;
if (suppressedCategories != null && suppressedCategories.Contains(script.Category))
continue;
hook(scriptHook);
}
}
/// <summary> /// <summary>
/// Executes a hook on all scripts in a source. /// Executes a hook on all scripts in a source.
/// </summary> /// </summary>

View File

@ -1,10 +1,10 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Moves; namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
[Script(ScriptCategory.Move, "belch")] [Script(ScriptCategory.Move, "belch")]
public class Belch : Script public class Belch : Script, IScriptPreventMoveSelection
{ {
/// <inheritdoc /> /// <inheritdoc />
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent) public void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
{ {
var battleData = choice.User.BattleData; var battleData = choice.User.BattleData;
if (battleData == null) if (battleData == null)

View File

@ -1,10 +1,10 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Moves; namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
[Script(ScriptCategory.Move, "celebrate")] [Script(ScriptCategory.Move, "celebrate")]
public class Celebrate : Script public class Celebrate : Script, IScriptPreventMoveSelection
{ {
/// <inheritdoc /> /// <inheritdoc />
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent) public void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
{ {
// This move is mostly useless, and it's not worth the effort to implement it. // This move is mostly useless, and it's not worth the effort to implement it.
// Prevent it from being selected. // Prevent it from being selected.

View File

@ -1,10 +1,10 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Moves; namespace PkmnLib.Plugin.Gen7.Scripts.Moves;
[Script(ScriptCategory.Move, "last_resort")] [Script(ScriptCategory.Move, "last_resort")]
public class LastResort : Script public class LastResort : Script, IScriptPreventMoveSelection
{ {
/// <inheritdoc /> /// <inheritdoc />
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent) public void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
{ {
var battleData = choice.User.BattleData; var battleData = choice.User.BattleData;
if (battleData == null) if (battleData == null)

View File

@ -1,7 +1,7 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon; namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
[Script(ScriptCategory.Pokemon, "disable")] [Script(ScriptCategory.Pokemon, "disable")]
public class DisableEffect : Script public class DisableEffect : Script, IScriptPreventMoveSelection
{ {
private int _turnsLeft = 4; private int _turnsLeft = 4;
private readonly StringKey _move; private readonly StringKey _move;
@ -12,7 +12,7 @@ public class DisableEffect : Script
} }
/// <inheritdoc /> /// <inheritdoc />
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent) public void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
{ {
if (choice.ChosenMove.MoveData.Name == _move) if (choice.ChosenMove.MoveData.Name == _move)
prevent = true; prevent = true;

View File

@ -1,7 +1,7 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon; namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
[Script(ScriptCategory.Pokemon, "heal_block")] [Script(ScriptCategory.Pokemon, "heal_block")]
public class HealBlockEffect : Script public class HealBlockEffect : Script, IScriptPreventMoveSelection
{ {
private int _duration; private int _duration;
@ -19,7 +19,7 @@ public class HealBlockEffect : Script
} }
/// <inheritdoc /> /// <inheritdoc />
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent) public void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
{ {
if (choice.ChosenMove.MoveData.HasFlag("heal")) if (choice.ChosenMove.MoveData.HasFlag("heal"))
prevent = true; prevent = true;

View File

@ -1,7 +1,7 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon; namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
[Script(ScriptCategory.Pokemon, "imprison")] [Script(ScriptCategory.Pokemon, "imprison")]
public class ImprisonEffect : Script public class ImprisonEffect : Script, IScriptPreventMoveSelection
{ {
private readonly IPokemon _user; private readonly IPokemon _user;
@ -11,7 +11,7 @@ public class ImprisonEffect : Script
} }
/// <inheritdoc /> /// <inheritdoc />
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent) public void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
{ {
if (_user.Moves.WhereNotNull().Any(x => x.MoveData.Name == choice.ChosenMove.MoveData.Name)) if (_user.Moves.WhereNotNull().Any(x => x.MoveData.Name == choice.ChosenMove.MoveData.Name))
prevent = true; prevent = true;

View File

@ -3,12 +3,12 @@ using PkmnLib.Static.Moves;
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon; namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
[Script(ScriptCategory.Pokemon, "taunt")] [Script(ScriptCategory.Pokemon, "taunt")]
public class TauntEffect(int turns) : Script public class TauntEffect(int turns) : Script, IScriptPreventMoveSelection
{ {
private int _turns = turns; private int _turns = turns;
/// <inheritdoc /> /// <inheritdoc />
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent) public void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
{ {
if (choice.ChosenMove.MoveData.Category == MoveCategory.Status) if (choice.ChosenMove.MoveData.Category == MoveCategory.Status)
{ {

View File

@ -1,12 +1,12 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon; namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
[Script(ScriptCategory.Pokemon, "throat_chop")] [Script(ScriptCategory.Pokemon, "throat_chop")]
public class ThroatChopEffect : Script public class ThroatChopEffect : Script, IScriptPreventMoveSelection
{ {
private int _turns = 3; private int _turns = 3;
/// <inheritdoc /> /// <inheritdoc />
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent) public void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
{ {
if (choice.ChosenMove.MoveData.HasFlag("sound")) if (choice.ChosenMove.MoveData.HasFlag("sound"))
prevent = true; prevent = true;

View File

@ -1,12 +1,12 @@
namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon; namespace PkmnLib.Plugin.Gen7.Scripts.Pokemon;
[Script(ScriptCategory.Pokemon, "torment")] [Script(ScriptCategory.Pokemon, "torment")]
public class TormentEffect(IMoveChoice? moveChoice) : Script public class TormentEffect(IMoveChoice? moveChoice) : Script, IScriptPreventMoveSelection
{ {
private IMoveChoice? _moveChoice = moveChoice; private IMoveChoice? _moveChoice = moveChoice;
/// <inheritdoc /> /// <inheritdoc />
public override void PreventMoveSelection(IMoveChoice choice, ref bool prevent) public void PreventMoveSelection(IMoveChoice choice, ref bool prevent)
{ {
if (_moveChoice == null) if (_moveChoice == null)
return; return;