206 lines
7.4 KiB
C#
206 lines
7.4 KiB
C#
using System.Runtime.CompilerServices;
|
|
using PkmnLib.Dynamic.Events;
|
|
using PkmnLib.Dynamic.Models;
|
|
using PkmnLib.Static;
|
|
|
|
namespace PkmnLib.Dynamic.ScriptHandling;
|
|
|
|
/// <summary>
|
|
/// Helper functions for script execution.
|
|
/// </summary>
|
|
public static class ScriptExecution
|
|
{
|
|
/// <summary>
|
|
/// Executes a hook on all scripts in a source.
|
|
/// </summary>
|
|
public static void RunScriptHook(this IScriptSource source, Action<Script> 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 (suppressedCategories != null && suppressedCategories.Contains(script.Category))
|
|
continue;
|
|
hook(script);
|
|
}
|
|
}
|
|
|
|
/// <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>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static void RunScriptHook(this IEnumerable<IScriptSource> sources, Action<Script> hook)
|
|
{
|
|
var iterator = sources.Distinct().SelectMany(x => x.GetScripts()).ToArray();
|
|
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 (suppressedCategories != null && suppressedCategories.Contains(script.Category))
|
|
continue;
|
|
hook(script);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes a hook on all scripts in a source.
|
|
/// </summary>
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public static void RunScriptHookInterface<TScriptHook>(this IEnumerable<IScriptSource> sources,
|
|
Action<TScriptHook> hook)
|
|
{
|
|
var iterator = sources.Distinct().SelectMany(x => x.GetScripts()).ToArray();
|
|
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 list of sources. Note that this does not walk through the parents of the
|
|
/// sources, but only the sources themselves.
|
|
/// </summary>
|
|
public static void RunScriptHook(this IReadOnlyList<IEnumerable<ScriptContainer>> source, Action<Script> hook)
|
|
{
|
|
List<ScriptCategory>? suppressedCategories = null;
|
|
foreach (var container in source.SelectMany(x => x))
|
|
{
|
|
if (container.IsEmpty)
|
|
continue;
|
|
var script = container.Script;
|
|
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 (suppressedCategories != null && suppressedCategories.Contains(script.Category))
|
|
continue;
|
|
hook(script);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Executes a hook on all scripts in a list of sources. Note that this does not walk through the parents of the
|
|
/// sources, but only the sources themselves.
|
|
/// </summary>
|
|
public static void RunScriptHookInterface<TScriptHook>(this IReadOnlyList<IEnumerable<ScriptContainer>> source,
|
|
Action<TScriptHook> hook)
|
|
{
|
|
List<ScriptCategory>? suppressedCategories = null;
|
|
var iterator = new ScriptIterator(source);
|
|
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 script on an item.
|
|
/// </summary>
|
|
public static void RunItemScript(this IItem item, ScriptResolver scriptResolver, IPokemon? target,
|
|
EventHook eventHook)
|
|
{
|
|
if (!scriptResolver.TryResolveBattleItemScript(item, out var itemScript))
|
|
{
|
|
return;
|
|
}
|
|
if (!itemScript.IsItemUsable)
|
|
return;
|
|
|
|
itemScript.OnInitialize(item.BattleEffect!.Parameters);
|
|
var requiresTarget = itemScript.RequiresTarget;
|
|
if (requiresTarget)
|
|
{
|
|
if (target == null)
|
|
throw new ArgumentNullException(nameof(target), "Item script requires a target.");
|
|
itemScript.OnUseWithTarget(target, eventHook);
|
|
}
|
|
else
|
|
{
|
|
itemScript.OnUse(eventHook);
|
|
}
|
|
}
|
|
} |