Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
It should follow the format major.minor.patch (semantic versioning). If you publish your mod
as a library to NuGet, this version will also be used as the package version.
-->
<Version>0.3.7</Version>
<Version>0.3.8</Version>
</PropertyGroup>
</Project>
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ This is a library for mods to make FSM edits easier.

To add Silksong.FsmUtil to your mod, add the following line to your .csproj:
```
<PackageReference Include="Silksong.FsmUtil" Version="0.3.7" />
<PackageReference Include="Silksong.FsmUtil" Version="0.3.8" />
```
The most up to date version number can be retrieved from [Nuget](https://www.nuget.org/packages/Silksong.FsmUtil).

You will also need to add a dependency to your thunderstore.toml:
```
silksong_modding-FsmUtil = "0.3.7"
silksong_modding-FsmUtil = "0.3.8"
```
The version number does not matter hugely, but the most up to date number can be retrieved from
[Thunderstore](https://thunderstore.io/c/hollow-knight-silksong/p/silksong_modding/FsmUtil/).
Expand Down
4 changes: 2 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ With this, it's easy to:

To add Silksong.FsmUtil to your mod, add the following line to your .csproj:
```
<PackageReference Include="Silksong.FsmUtil" Version="0.3.7" />
<PackageReference Include="Silksong.FsmUtil" Version="0.3.8" />
```
The most up to date version number can be retrieved from [Nuget](https://www.nuget.org/packages/Silksong.FsmUtil).

You will also need to add a dependency to your thunderstore.toml:
```
silksong_modding-FsmUtil = "0.3.7"
silksong_modding-FsmUtil = "0.3.8"
```
The version number does not matter hugely, but the most up to date number can be retrieved from
[Thunderstore](https://thunderstore.io/c/hollow-knight-silksong/p/silksong_modding/FsmUtil/).
Expand Down
51 changes: 43 additions & 8 deletions src/Actions/LambdaAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,56 @@ namespace Silksong.FsmUtil.Actions
/// <summary>
/// An action that executes a single zero-argument function, then exits.
/// </summary>
/// <param name="action">The function to invoke.</param>
/// <param name="everyFrame">If true, execute the function repeatedly on every update frame.</param>
public class LambdaAction(Action action, bool everyFrame = false) : FsmStateAction
public class LambdaAction : FsmStateAction
{
/// <inheritdoc/>
/// <summary>
/// The method to invoke.
/// </summary>
public Action? Method;

/// <summary>
/// If true, execute the function repeatedly on every update frame.
/// </summary>
public bool EveryFrame = false;

/// <summary>
/// Resets the action.
/// </summary>
public override void Reset()
{
Method = null;
EveryFrame = false;
base.Reset();
}

/// <summary>
/// Called when the action is being processed.
/// </summary>
public override void OnEnter()
{
action?.Invoke();
if (!everyFrame) Finish();
if (Method != null)
{
Method.Invoke();
}

if (!EveryFrame)
{
Finish();
}
}

/// <inheritdoc/>
/// <summary>
/// Called every update frame.
/// </summary>
public override void OnUpdate()
{
if (everyFrame) action?.Invoke();
if (EveryFrame)
{
if (Method != null)
{
Method.Invoke();
}
}
}
}
}
144 changes: 140 additions & 4 deletions src/FsmUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -453,23 +453,54 @@ public static void AddActions(this FsmState state, params FsmStateAction[] actio
/// <param name="stateName">The name of the state in which the method is added</param>
/// <param name="method">The method that will be invoked with the action as the parameter</param>
[PublicAPI]
[Obsolete("In a future update, the method here will no longer take a parameter. Please use the `AddLambdaMethod` extension method instead! (Though that one's parameter is the `Finish` method.)")]
public static void AddMethod(this PlayMakerFSM fsm, string stateName, Action<FsmStateAction> method) => fsm.GetState(stateName)!.AddMethod(method);

/// <inheritdoc cref="AddMethod(PlayMakerFSM, string, Action{FsmStateAction})"/>
[PublicAPI]
[Obsolete("In a future update, the method here will no longer take a parameter. Please use the `AddLambdaMethod` extension method instead! (Though that one's parameter is the `Finish` method.)")]
public static void AddMethod(this Fsm fsm, string stateName, Action<FsmStateAction> method) => fsm.GetState(stateName)!.AddMethod(method);

/// <inheritdoc cref="AddMethod(PlayMakerFSM, string, Action{FsmStateAction})"/>
/// <param name="state">The fsm state</param>
/// <param name="method">The method that will be invoked with the action as the parameter</param>
[PublicAPI]
[Obsolete("In a future update, the method here will no longer take a parameter. Please use the `AddLambdaMethod` extension method instead! (Though that one's parameter is the `Finish` method.)")]
public static void AddMethod(this FsmState state, Action<FsmStateAction> method)
{
DelegateAction<FsmStateAction> action = new DelegateAction<FsmStateAction> { Method = method };
action.Arg = action;
state.AddAction(action);
}

/// <summary>
/// Adds a method in a PlayMakerFSM.
/// </summary>
/// <param name="fsm">The fsm</param>
/// <param name="stateName">The name of the state in which the method is added</param>
/// <param name="method">The method that will be invoked</param>
/// <param name="everyFrame">If true, execute the function repeatedly on every update frame</param>
[PublicAPI]
[Obsolete("In a future update, this method will be `AddMethod`.")]
public static void AddMethod2(this PlayMakerFSM fsm, string stateName, Action method, bool everyFrame = false) => fsm.GetState(stateName)!.AddMethod2(method, everyFrame);

/// <inheritdoc cref="AddMethod2(PlayMakerFSM, string, Action, bool)"/>
[PublicAPI]
[Obsolete("In a future update, this method will be `AddMethod`.")]
public static void AddMethod2(this Fsm fsm, string stateName, Action method, bool everyFrame = false) => fsm.GetState(stateName)!.AddMethod2(method, everyFrame);

/// <inheritdoc cref="AddMethod2(PlayMakerFSM, string, Action, bool)"/>
/// <param name="state">The fsm state</param>
/// <param name="method">The method that will be invoked</param>
/// <param name="everyFrame">If true, execute the function repeatedly on every update frame</param>
[PublicAPI]
[Obsolete("In a future update, this method will be `AddMethod`.")]
public static void AddMethod2(this FsmState state, Action method, bool everyFrame = false)
{
LambdaAction action = new LambdaAction { Method = method };
state.AddAction(action);
}

/// <summary>
/// Adds a method with a parameter in a PlayMakerFSM.
/// </summary>
Expand Down Expand Up @@ -599,36 +630,87 @@ public static void InsertActions(this FsmState state, int index, params FsmState
/// <param name="index">The index to place the action in</param>
/// <returns>bool that indicates whether the insertion was successful</returns>
[PublicAPI]
[Obsolete("In a future update, the method here will no longer take a parameter. Please use the `InsertLambdaMethod` extension method instead! (Though that one's parameter is the `Finish` method.)")]
public static void InsertMethod(this PlayMakerFSM fsm, string stateName, Action<FsmStateAction> method, int index) => fsm.GetState(stateName)!.InsertMethod(index, method);

/// <inheritdoc cref="InsertMethod(PlayMakerFSM, string, Action{FsmStateAction}, int)"/>
[PublicAPI]
[Obsolete("In a future update, the method here will no longer take a parameter. Please use the `InsertLambdaMethod` extension method instead! (Though that one's parameter is the `Finish` method.)")]
public static void InsertMethod(this PlayMakerFSM fsm, string stateName, int index, Action<FsmStateAction> method) => fsm.GetState(stateName)!.InsertMethod(index, method);

/// <inheritdoc cref="InsertMethod(PlayMakerFSM, string, Action{FsmStateAction}, int)"/>
[PublicAPI]
[Obsolete("In a future update, the method here will no longer take a parameter. Please use the `InsertLambdaMethod` extension method instead! (Though that one's parameter is the `Finish` method.)")]
public static void InsertMethod(this Fsm fsm, string stateName, Action<FsmStateAction> method, int index) => fsm.GetState(stateName)!.InsertMethod(index, method);

/// <inheritdoc cref="InsertMethod(PlayMakerFSM, string, Action{FsmStateAction}, int)"/>
[PublicAPI]
[Obsolete("In a future update, the method here will no longer take a parameter. Please use the `InsertLambdaMethod` extension method instead! (Though that one's parameter is the `Finish` method.)")]
public static void InsertMethod(this Fsm fsm, string stateName, int index, Action<FsmStateAction> method) => fsm.GetState(stateName)!.InsertMethod(index, method);

/// <inheritdoc cref="InsertMethod(PlayMakerFSM, string, Action{FsmStateAction}, int)"/>
/// <param name="state">The fsm state</param>
/// <param name="method">The method that will be invoked</param>
/// <param name="index">The index to place the action in</param>
[PublicAPI]
[Obsolete("In a future update, the method here will no longer take a parameter. Please use the `InsertLambdaMethod` extension method instead! (Though that one's parameter is the `Finish` method.)")]
public static void InsertMethod(this FsmState state, Action<FsmStateAction> method, int index) => state.InsertMethod(index, method);

/// <inheritdoc cref="InsertMethod(FsmState, Action{FsmStateAction}, int)"/>
[PublicAPI]
[Obsolete("In a future update, the method here will no longer take a parameter. Please use the `InsertLambdaMethod` extension method instead! (Though that one's parameter is the `Finish` method.)")]
public static void InsertMethod(this FsmState state, int index, Action<FsmStateAction> method)
{
DelegateAction<FsmStateAction> action = new DelegateAction<FsmStateAction> { Method = method };
action.Arg = action;
state.InsertAction(action, index);
}

/// <summary>
/// Inserts a method in a PlayMakerFSM.
/// Trying to insert a method out of bounds will cause a `ArgumentOutOfRangeException`.
/// </summary>
/// <param name="fsm">The fsm</param>
/// <param name="stateName">The name of the state in which the method is added</param>
/// <param name="method">The method that will be invoked</param>
/// <param name="index">The index to place the action in</param>
/// <returns>bool that indicates whether the insertion was successful</returns>
[PublicAPI]
[Obsolete("In a future update, this method will be `InsertMethod`.")]
public static void InsertMethod2(this PlayMakerFSM fsm, string stateName, Action method, int index, bool everyFrame = false) => fsm.GetState(stateName)!.InsertMethod2(index, method, everyFrame);

/// <inheritdoc cref="InsertMethod2(PlayMakerFSM, string, Action, int, bool)"/>
[PublicAPI]
[Obsolete("In a future update, this method will be `InsertMethod`.")]
public static void InsertMethod2(this PlayMakerFSM fsm, string stateName, int index, Action method, bool everyFrame = false) => fsm.GetState(stateName)!.InsertMethod2(index, method, everyFrame);

/// <inheritdoc cref="InsertMethod2(PlayMakerFSM, string, Action, int, bool)"/>
[PublicAPI]
[Obsolete("In a future update, this method will be `InsertMethod`.")]
public static void InsertMethod2(this Fsm fsm, string stateName, Action method, int index, bool everyFrame = false) => fsm.GetState(stateName)!.InsertMethod2(index, method, everyFrame);

/// <inheritdoc cref="InsertMethod2(PlayMakerFSM, string, Action, int, bool)"/>
[PublicAPI]
[Obsolete("In a future update, this method will be `InsertMethod`.")]
public static void InsertMethod2(this Fsm fsm, string stateName, int index, Action method, bool everyFrame = false) => fsm.GetState(stateName)!.InsertMethod2(index, method, everyFrame);

/// <inheritdoc cref="InsertMethod2(PlayMakerFSM, string, Action, int, bool)"/>
/// <param name="state">The fsm state</param>
/// <param name="method">The method that will be invoked</param>
/// <param name="index">The index to place the action in</param>
[PublicAPI]
[Obsolete("In a future update, this method will be `InsertMethod`.")]
public static void InsertMethod2(this FsmState state, Action method, int index, bool everyFrame = false) => state.InsertMethod2(index, method, everyFrame);

/// <inheritdoc cref="InsertMethod2(FsmState, Action, int, bool)"/>
[PublicAPI]
[Obsolete("In a future update, this method will be `InsertMethod`.")]
public static void InsertMethod2(this FsmState state, int index, Action method, bool everyFrame = false)
{
LambdaAction action = new LambdaAction { Method = method };
state.InsertAction(action, index);
}

/// <summary>
/// Inserts a method with a parameter in a PlayMakerFSM.
/// Trying to insert a method out of bounds will cause a `ArgumentOutOfRangeException`.
Expand Down Expand Up @@ -673,9 +755,9 @@ public static void InsertLambdaMethod(this FsmState state, int index, Action<Act
/// Insert a method to run before the specified FsmStateAction.
/// </summary>
/// <param name="action">The action to insert before.</param>
/// <param name="method">The method to execute.
/// The argument will be the FsmStateAction which is being added.</param>
/// <param name="method">The method to execute. The argument will be the FsmStateAction which is being added.</param>
[PublicAPI]
[Obsolete("In a future update, the method here will no longer take a parameter. Please use the `InsertLambdaMethodBefore` extension method instead! (Though that one's parameter is the `Finish` method.)")]
public static void InsertMethodBefore(this FsmStateAction action, Action<FsmStateAction> method)
{
FsmState state = action.State;
Expand All @@ -687,16 +769,70 @@ public static void InsertMethodBefore(this FsmStateAction action, Action<FsmStat
/// Insert a method to run after the specified FsmStateAction.
/// </summary>
/// <param name="action">The action to insert after.</param>
/// <param name="method">The method to execute.
/// The argument will be the FsmStateAction which is being added.</param>
/// <param name="method">The method to execute. The argument will be the FsmStateAction which is being added.</param>
[PublicAPI]
[Obsolete("In a future update, the method here will no longer take a parameter. Please use the `InserLambdatMethodAfter` extension method instead! (Though that one's parameter is the `Finish` method.)")]
public static void InsertMethodAfter(this FsmStateAction action, Action<FsmStateAction> method)
{
FsmState state = action.State;
int idx = Array.IndexOf(state.Actions, action);
state.InsertMethod(idx + 1, method);
}

/// <summary>
/// Insert a method to run before the specified FsmStateAction.
/// </summary>
/// <param name="action">The action to insert before.</param>
/// <param name="method">The method to execute.</param>
[PublicAPI]
[Obsolete("In a future update, this method will be `InsertMethodBefore`.")]
public static void InsertMethod2Before(this FsmStateAction action, Action method)
{
FsmState state = action.State;
int idx = Array.IndexOf(state.Actions, action);
state.InsertMethod2(idx, method);
}

/// <summary>
/// Insert a method to run after the specified FsmStateAction.
/// </summary>
/// <param name="action">The action to insert after.</param>
/// <param name="method">The method to execute.</param>
[PublicAPI]
[Obsolete("In a future update, this method will be `InsertMethodAfter`.")]
public static void InsertMethod2After(this FsmStateAction action, Action method)
{
FsmState state = action.State;
int idx = Array.IndexOf(state.Actions, action);
state.InsertMethod2(idx + 1, method);
}

/// <summary>
/// Insert a method to run before the specified FsmStateAction.
/// </summary>
/// <param name="action">The action to insert before.</param>
/// <param name="method">The method to execute. The argument will be the `Finish` method.</param>
[PublicAPI]
public static void InsertLambdaMethodBefore(this FsmStateAction action, Action<Action> method)
{
FsmState state = action.State;
int idx = Array.IndexOf(state.Actions, action);
state.InsertLambdaMethod(idx, method);
}

/// <summary>
/// Insert a method to run after the specified FsmStateAction.
/// </summary>
/// <param name="action">The action to insert after.</param>
/// <param name="method">The method to execute. The argument will be the `Finish` method.</param>
[PublicAPI]
public static void InsertLambdaMethodAfter(this FsmStateAction action, Action<Action> method)
{
FsmState state = action.State;
int idx = Array.IndexOf(state.Actions, action);
state.InsertLambdaMethod(idx + 1, method);
}

/// <summary>
/// Insert an action to run before the specified FsmStateAction.
/// </summary>
Expand Down
2 changes: 1 addition & 1 deletion thunderstore/thunderstore.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[config]
schemaVersion = "0.3.7"
schemaVersion = "0.3.8"

[package]
# The name of the team you are publishing as
Expand Down