Cleanup, move OnBeforeAnyHookInvoked function to an interface

This commit is contained in:
2025-06-28 10:28:23 +02:00
parent 43813c1c1c
commit d719ce03ea
10 changed files with 49 additions and 95 deletions

View File

@@ -1,36 +0,0 @@
using PkmnLib.Dynamic.Models;
using PkmnLib.Static;
namespace PkmnLib.Dynamic.ScriptHandling;
public class ProxyScript : Script
{
public delegate void ChangeOffensiveStatValueEventHandler(IExecutingMove move, IPokemon target, byte hit,
uint defensiveStat, ImmutableStatisticSet<uint> targetStats, ref uint value);
private readonly List<(Script, ChangeOffensiveStatValueEventHandler)> _changeOffensiveStatValueEvents = new();
public void AddChangeOffensiveStatValueEvent(Script script, ChangeOffensiveStatValueEventHandler handler)
{
_changeOffensiveStatValueEvents.Add((script, handler));
script.OnRemoveEvent += OnRemoveScriptEvent;
}
private void OnRemoveScriptEvent(Script script)
{
_changeOffensiveStatValueEvents.RemoveAll(x => x.Item1 == script);
}
/// <inheritdoc />
public override void ChangeOffensiveStatValue(IExecutingMove move, IPokemon target, byte hit, uint defensiveStat,
ImmutableStatisticSet<uint> targetStats, Statistic stat, ref uint value)
{
foreach (var (script, handler) in _changeOffensiveStatValueEvents)
{
if (!script.IsSuppressed)
{
handler(move, target, hit, defensiveStat, targetStats, ref value);
}
}
}
}

View File

@@ -18,8 +18,6 @@ public abstract class Script : IDeepCloneable
{
internal event Action<Script>? OnRemoveEvent;
private int _suppressCount;
/// <summary>
/// Remove the script from its owner.
/// </summary>
@@ -41,40 +39,6 @@ public abstract class Script : IDeepCloneable
/// </summary>
public virtual ScriptCategory Category => this.ResolveCategory();
/// <summary>
/// A script can be suppressed by other scripts. If a script is suppressed by at least one script
/// we will not execute its methods. This should return the number of suppressions on the script.
/// </summary>
public int SuppressCount => _suppressCount;
/// <summary>
/// Helper function to check if there is at least one suppression on the script
/// </summary>
public bool IsSuppressed => _suppressCount > 0;
/// <summary>
/// Adds a suppression. This makes the script not run anymore. Note that adding this should also
/// remove the suppression later.
///
/// A common pattern for this is to run this in the <see cref="OnInitialize"/> and remove it in the
/// <see cref="OnRemove"/> function.
/// </summary>
public void Suppress() => _suppressCount++;
/// <summary>
/// Removes a suppression. This allows the script to run again (provided other scripts are not
/// suppressing it). Note that running this should only occur if <see cref="Suppress"/> was called earlier
/// </summary>
public void Unsuppress() => _suppressCount--;
/// <summary>
/// This function is ran before any hook is invoked. This allows for suppressing certain categories
/// of scripts. This is useful for example to prevent certain effects from running.
/// </summary>
public virtual void OnBeforeAnyHookInvoked(ref List<ScriptCategory>? suppressedCategories)
{
}
/// <summary>
/// This function is ran when a volatile effect is added while that volatile effect already is
/// in place. Instead of adding the volatile effect twice, it will execute this function instead.
@@ -767,6 +731,9 @@ public abstract class Script : IDeepCloneable
{
}
/// <summary>
/// This function triggers after a status condition has been applied to a Pokemon.
/// </summary>
public virtual void OnAfterStatusChange(IPokemon pokemon, StringKey status, IPokemon? originPokemon)
{
}
@@ -796,6 +763,9 @@ public abstract class Script : IDeepCloneable
{
}
/// <summary>
/// This function triggers when the weather changes.
/// </summary>
public virtual void OnWeatherChange(IBattle battle, StringKey? weatherName, StringKey? oldWeatherName)
{
}
@@ -844,15 +814,38 @@ public abstract class Script : IDeepCloneable
{
}
/// <summary>
/// This function triggers just before a move choice is executed.
/// </summary>
public virtual void OnBeforeMoveChoice(IMoveChoice moveChoice)
{
}
/// <summary>
/// This function triggers after a move choice has been executed in its entirety.
/// </summary>
public virtual void OnAfterMoveChoice(IMoveChoice moveChoice)
{
}
/// <summary>
/// This function allows a script to change the turn choice that is made by a Pokemon.
/// </summary>
public virtual void ChangeTurnChoice(ref ITurnChoice choice)
{
}
}
/// <summary>
/// This interface is used to allow scripts to run before any hook is invoked. This allows for
/// suppressing certain categories of scripts, which can be useful for preventing certain effects
/// from running.
/// </summary>
public interface IScriptOnBeforeAnyHookInvoked
{
/// <summary>
/// This function is ran before any hook is invoked. This allows for suppressing certain categories
/// of scripts. This is useful for example to prevent certain effects from running.
/// </summary>
void OnBeforeAnyHookInvoked(ref List<ScriptCategory>? suppressedCategories);
}

View File

@@ -23,15 +23,14 @@ public static class ScriptExecution
if (container.IsEmpty)
continue;
var script = container.Script;
script.OnBeforeAnyHookInvoked(ref suppressedCategories);
if (script is IScriptOnBeforeAnyHookInvoked onBeforeAnyHookInvoked)
onBeforeAnyHookInvoked.OnBeforeAnyHookInvoked(ref suppressedCategories);
}
foreach (var container in iterator)
{
if (container.IsEmpty)
continue;
var script = container.Script;
if (script.IsSuppressed)
continue;
if (suppressedCategories != null && suppressedCategories.Contains(script.Category))
continue;
hook(script);
@@ -51,15 +50,14 @@ public static class ScriptExecution
if (container.IsEmpty)
continue;
var script = container.Script;
script.OnBeforeAnyHookInvoked(ref suppressedCategories);
if (script is IScriptOnBeforeAnyHookInvoked onBeforeAnyHookInvoked)
onBeforeAnyHookInvoked.OnBeforeAnyHookInvoked(ref suppressedCategories);
}
foreach (var container in iterator)
{
if (container.IsEmpty)
continue;
var script = container.Script;
if (script.IsSuppressed)
continue;
if (suppressedCategories != null && suppressedCategories.Contains(script.Category))
continue;
hook(script);
@@ -78,15 +76,14 @@ public static class ScriptExecution
if (container.IsEmpty)
continue;
var script = container.Script;
script.OnBeforeAnyHookInvoked(ref suppressedCategories);
if (script is IScriptOnBeforeAnyHookInvoked onBeforeAnyHookInvoked)
onBeforeAnyHookInvoked.OnBeforeAnyHookInvoked(ref suppressedCategories);
}
foreach (var container in source.SelectMany(x => x))
{
if (container.IsEmpty)
continue;
var script = container.Script;
if (script.IsSuppressed)
continue;
if (suppressedCategories != null && suppressedCategories.Contains(script.Category))
continue;
hook(script);