Hook factories are responsible for the creation of hooks. Custom content classes use hook factories internally, so there's basically no need for you to create your own. But, if you want to semi-automate the creation of a lot of different items/traits with slightly differing functionality, you can create a class, that will handle everything, and turn its parts on/off conditionally after initializing the hook.
IHookFactory
interfaceYou can create hook factories by deriving either from IHookFactory
or from HookFactoryBase<T>
. The hook factory in the example below will attach a new MyCustomHook
hook to all items that have a "Food" category:
public class MyAwesomeHookFactory : HookFactoryBase<InvItem>{ public override bool TryCreate(InvItem instance, out IHook<InvItem> hook) { if (instance.Categories.Contains("Food")) { hook = new MyAwesomeHook(); return true; } hook = null; return false; }}
You only need to create a hook object. DO NOT attach it to the instance! That's the external code's responsibility.
foreach (IHookFactory factory in RogueFramework.ItemFactories){ IHook? hook = factory.TryCreateHook(__instance); if (hook is not null) controller.AddHook(hook);}
You can either implement your own way of using factories or add it to the RogueLibs' RogueFramework
class:
[RLSetup]public static void Setup(){ RogueFramework.ItemFactories.Add(new MyAwesomeHookFactory());}
RogueLibs uses CustomItemFactory
and other similar classes to initialize custom items and other hooks:
public sealed class CustomItemFactory : HookFactoryBase<InvItem>{ private readonly Dictionary<string, ItemEntry> itemsDict = new Dictionary<string, ItemEntry>(); public override bool TryCreate(InvItem? instance, [NotNullWhen(true)] out IHook<InvItem>? hook) { if (instance?.invItemName != null && itemsDict.TryGetValue(instance.invItemName, out ItemEntry entry)) { hook = entry.Initializer(); if (hook is CustomItem custom) custom.Metadata = entry.Metadata; return true; } hook = null; return false; } public CustomItemMetadata AddItem<TItem>() where TItem : CustomItem, new() { CustomItemMetadata metadata = CustomItemMetadata.Get<TItem>(); itemsDict.Add(metadata.Name, new ItemEntry { Initializer = static () => new TItem(), Metadata = metadata }); return metadata; } private struct ItemEntry { public Func<IHook<InvItem>> Initializer; public CustomItemMetadata Metadata; }}
public static void InvItem_SetupDetails(InvItem __instance){ foreach (IHookFactory factory in RogueFramework.ItemFactories) { IHook? hook = factory.TryCreateHook(__instance); if (hook is not null) controller.AddHook(hook); }}