Refactor move selection prevention to use interface

This commit is contained in:
2025-06-28 10:36:43 +02:00
parent 04cf585f5a
commit 2319160b52
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))
return false;
var preventMove = false;
choice.RunScriptHook(script => script.PreventMoveSelection(moveChoice, ref preventMove));
choice.RunScriptHookInterface<IScriptPreventMoveSelection>(script =>
script.PreventMoveSelection(moveChoice, ref preventMove));
if (preventMove)
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>
/// 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.
@@ -854,4 +847,15 @@ public interface IScriptOnInitialize
/// with parameters that are passed to it.
/// </summary>
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>
/// Executes a hook on all scripts in a source.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RunScriptHook(this IScriptSource source, Action<Script> hook)
{
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>
/// Executes a hook on all scripts in a source.
/// </summary>