-
Notifications
You must be signed in to change notification settings - Fork 1
Modder guide : working with thingfilters
Thingfilters are special. And the reason for that is the cheap way they were implemented. You can't distinguish thingfilters one from another without enumerating their content and they don't hold a reference to object, that uses them. And this is a big issue. In order to not duplicate thingfilters, that might contain a hell lot of stuff, over the network just to find proper instance, we're forced to do it in a bit dirty way : we need tell the system that the object, that uses the thingfilter, is going to, well, modify the thingfilter! This is done via adding object into a special stack BEFORE thingfilter modification. For instance, ITab_Storage
modifies the thingfilter. And here's the patch that let's us track the changes :
[HarmonyPatch(typeof(ITab_Storage))]
[HarmonyPatch("FillTab")]
class ITab_StoragePatch
{
[HarmonyPrefix]
public static void Prefix(ITab_Storage __instance)
{
ThingFilterPatch.thingFilterCallerStack.Push(__instance.GetType().GetMethod("get_SelStoreSettingsParent", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(__instance, null));
}
[HarmonyPostfix]
public static void Postfix(ITab_Storage __instance)
{
ThingFilterPatch.thingFilterCallerStack.Pop();
}
}
ThingFilterPatch.thingFilterCallerStack
is used inside patches done to a thingfitler itself. In that way, RimAlong would be able to find exact same object at remote machine and perform modification of it's thingfilter. Right now typeset that can be handled inside that routine is pretty limited. Also, this entire routine might be changed in the nearest future. All of that mean, that you can't simply transfer thingfilters in ParrotPatch
ed method :
//this is NOT gonna work!
ParrotWrapper.ParrotPatchExpressiontarget<Action<ThingFilter, ThingDef>>((ThingFilter __instance, ThingDef thing) => __instance.SetAllow(thing, true));
Refer to ITab_Storage
patch!