Repository navigation
Custom Hooks
When you make a new mechanic, you might want to add a hook for it too, like how the base game has all sorts of useful hooks. This page outlines a general technique for making custom hooks.
The first step is to just define what a listener (sometimes called a subscriber) looks like, usually using an interface.
//The name of this class doesn't matter, but pick something meaningful if you want to understand your code later
public interface ICustomHookListener
{
//This is the function that will get called when the hook is triggered.
//There's no rules about what this function looks like, but a good
//starting point is to return a Task and pass in a PlayerChoiceContext (if you have one)
//and whatever model triggered the hook
public Task AfterCustomHook(PlayerChoiceContext choiceContext, Power power);
}Implement this interface on any model where you want to receive a callback when something occurs, and define what happens the same way you would a base game hook.
Then you need to create a function that notifies the hook listeners stuff has happened.
//You don't have to put all your notifiers in the same static class, but the base game does and it's as good a place as any
public static class YourCustomHooks
{
//You need to pass in a runstate to notify runstate models and a combatstate to notify combat models
//If it doesn't matter which you notify, just pass in both
public static async Task OnCustomHook(IRunState runState, ICombatState? combatState, PlayerChoiceContext choiceContext, Power power)
{
//RunState and CombatState both have a method to iterate hook listeners.
//In order to call our function we defined in the interface, we need to check if the model
//implements the interface and cast to the interface if it does.
//Calling `.OfType<>` is a very easy way to achieve both.
foreach (ICustomHookListener listener in runState.IterateHookListeners(combatState).OfType<ICustomHookListener>())
{
//Inside the foreach loop, we just call each method, awaiting it if you returned a Task in ICustomHookListener
await listener.AfterCustomHook(choiceContext, power);
}
}
}Then you call YourCustomHooks.OnCustomHook whenever the thing occurs in your code.
You can follow a nearly identical process for adding a custom hook for something that occurs in the base game, with the exception that you will need to patch the base game to call your notifier function instead of calling it yourself directly in your code base