Skip to content

HOWTO add a new hook

PoroCYon edited this page Oct 1, 2017 · 2 revisions

How to add a hook to a TBehaviour

This guide assumes that you have read the HOWTO modify vanilla code in the injector guide, as this one takes off where the latter ended.

0. Preface

This is possibly the area where Prism is quite lacking: hooks. Hooks are (virtual) methods marked with the HookAttribute, and the base class of the behaviour must be Prism.Mods.Hooks.HookContainer.

When a TBehaviour is instantiated, its hooks (a MethodInfo array) are collected using HookContainer.GetHooks. This is done in Prism.Mods.Hooks.HookManager.CreateHooks, which sorts them by priority as well. HookManager also manages all IHookManagers, objects that keep track of the behaviours attached to an entity. An IHookManager needs to implement two methods: Create and Clear. Create calls CreateHooks on all the IHookManager's behaviours, and Clear clears those lists. Most (if not all) classes that implement IHookManager are called a FooBHandler (where 'B' stands for behaviour) and they live in Prism.Mods.BHandlers.

The BHandler exposes methods that call the actual hooks in the correct order using HookManager.Call.

You've probably made a method somewhere in Prism.Mods.Hooks, after having followed the injection guide. We'll continue from that now.

1. Adding the hookable method to the TBehaviour

This step is pretty easy: create a virtual method to the class (somewhere in Prism.API.Behaviours, and mark it with the HookAttribute.

2. Adding the hook to the BHandler

As you could've guessed, this consists of these steps:

  • Add the field that will contain the delegate list.
  • Make sure the list is created in Create() and cleared in Clear()
  • Add a method that calls the hook collection using HookManager.Call

3. Call the BHandler's hook method

This is where you ended in the previous guide. Call the method you created in the previous step and add the necessary boilerplate so the game won't break.

As you can see, lots of work has to be done to go from injected MSIL to a mod hook!

4. To add a new TBehaviour and BHandler

First of all, create the classes and make sure the behaviour can be instantiated somewhere, and make sure the BHandler can be stored somewhere as well. (The injector adds fields to these to vanilla types for most things.) Then add the BHandler to HookManager's list of tracked IHookManagers. Finally, go to step 1 of this guide.