public RimFridgeCompat(ModContentPack mod) { // Several Gizmos { Type type = AccessTools.TypeByName("RimFridge.CompRefrigerator"); string[] methods = { "<CompGetGizmosExtra>b__1", "<CompGetGizmosExtra>b__2", "<CompGetGizmosExtra>b__3", "<CompGetGizmosExtra>b__4", "<CompGetGizmosExtra>b__5" }; foreach (string method in methods) { MP.RegisterSyncDelegate(type, "<>c__DisplayClass10_0", method); } dialogType = AccessTools.TypeByName("RimFridge.Dialog_RenameFridge"); fridgeField = AccessTools.Field(dialogType, "fridge"); MP.RegisterSyncWorker <Dialog_Rename>(SyncFridgeName, dialogType); MP.RegisterSyncMethod(dialogType, "SetName"); } }
public RunandGun(ModContentPack mod) { Type type = AccessTools.TypeByName("RunAndGun.Harmony.Pawn_DraftController_GetGizmos_Patch"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass0_0", "<Postfix>b__1"); PatchingUtilities.PatchSystemRand("RunAndGun.Harmony.MentalStateHandler_TryStartMentalState:shouldRunAndGun", false); }
static IEnumerable <ISyncDelegate> RegisterLambdaDelegate_Impl(Type parentType, string parentMethod, string[] fields, params int[] lambdaOrdinals) { foreach (int ord in lambdaOrdinals) { var method = MpMethodUtil.GetLambda(parentType, parentMethod, MethodType.Normal, null, ord); yield return(MP.RegisterSyncDelegate(parentType, method.DeclaringType.Name, method.Name, fields)); } }
public ToggleRefuelable(ModContentPack mod) { MP.RegisterSyncDelegate( AccessTools.TypeByName("ToggleRefuelable.CompRefuelable_CompGetGizmosExtra_Patch"), "<>c__DisplayClass0_0", "<Postfix>b__1" ); }
public MoreFactionInteraction(ModContentPack mod) { var type = AccessTools.TypeByName("Multiplayer.Client.Patches.CloseDialogsForExpiredLetters"); // We should probably add this to the API the next time we update it var rejectMethods = (Dictionary <Type, MethodInfo>)AccessTools.Field(type, "rejectMethods").GetValue(null); type = AccessTools.TypeByName("MoreFactionInteraction.ChoiceLetter_ReverseTradeRequest"); var methods = MpMethodUtil.GetLambda(type, "Choices", MethodType.Getter, null, 0, 3).ToArray(); MP.RegisterSyncDelegate(type, methods[0].DeclaringType.Name, methods[0].Name); MP.RegisterSyncMethod(methods[1]); rejectMethods[type] = methods[1]; var typeNames = new[] { "MoreFactionInteraction.ChoiceLetter_DiplomaticMarriage", "MoreFactionInteraction.ChoiceLetter_ExtortionDemand", "MoreFactionInteraction.ChoiceLetter_MysticalShaman", }; foreach (var typeName in typeNames) { type = AccessTools.TypeByName(typeName); methods = MpMethodUtil.GetLambda(type, "Choices", MethodType.Getter, null, 0, 1).ToArray(); MP.RegisterSyncMethod(methods[0]); MP.RegisterSyncMethod(methods[1]); rejectMethods[type] = methods[1]; } typeNames = new[] { "MoreFactionInteraction.FactionWarPeaceTalks", "MoreFactionInteraction.More_Flavour.AnnualExpo", }; foreach (var typeName in typeNames) { type = AccessTools.TypeByName(typeName); MP.RegisterSyncDialogNodeTree(type, "Notify_CaravanArrived"); } type = AccessTools.TypeByName("MoreFactionInteraction.IncidentWorker_MysticalShaman"); MP.RegisterSyncDialogNodeTree(type, "TryExecuteWorker"); typeNames = new[] { "MoreFactionInteraction.IncidentWorker_MysticalShaman", "MoreFactionInteraction.IncidentWorker_ReverseTradeRequest", "MoreFactionInteraction.IncidentWorker_RoadWorks", }; foreach (var typeName in typeNames) { type = AccessTools.TypeByName(typeName); MP.RegisterSyncDialogNodeTree(type, "TryExecuteWorker"); } }
public ChoiceOfPsycastsCompat(ModContentPack mod) { var type = learnPsycastsType = AccessTools.TypeByName("RimWorld.ChoiceOfPsycasts.LearnPsycasts"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass3_0", "<Choice>b__0"); levelField = AccessTools.Field(type, "Level"); parentField = AccessTools.Field(type, "Parent"); MP.RegisterSyncWorker <Command_Action>(SyncLearnPsycasts, type); }
public GiddyUpCoreCompat(ModContentPack mod) { Type type; // Gizmos { // Release Animals MP.RegisterSyncDelegate( AccessTools.TypeByName("GiddyUpCore.Harmony.Pawn_PlayerSettings_GetGizmos"), "<>c__DisplayClass1_0", "<helpIterator>b__2" ); // Mount MP.RegisterSyncDelegate( AccessTools.TypeByName("GiddyUpCore.Utilities.GUC_FloatMenuUtility"), "<>c__DisplayClass0_0", "<AddMountingOptions>b__0" ); // Dismount MP.RegisterSyncDelegate( AccessTools.TypeByName("GiddyUpCore.Utilities.GUC_FloatMenuUtility"), "<>c__DisplayClass0_0", "<AddMountingOptions>b__1" ); } // Sync ExtendedPawnData { type = AccessTools.TypeByName("GiddyUpCore.Storage.ExtendedDataStorage"); MpCompat.harmony.Patch(AccessTools.Constructor(type), postfix: new HarmonyMethod(typeof(GiddyUpCoreCompat), nameof(ExtendedDataStoragePostfix))); MpCompat.harmony.Patch(AccessTools.Method(type, "GetExtendedDataFor", new Type[] { typeof(Pawn) }), postfix: new HarmonyMethod(typeof(GiddyUpCoreCompat), nameof(GetExtendedDataForPostfix))); MpCompat.harmony.Patch(AccessTools.Method(type, "DeleteExtendedDataFor", new Type[] { typeof(Pawn) }), postfix: new HarmonyMethod(typeof(GiddyUpCoreCompat), nameof(DeleteExtendedDataForPostfix))); } { type = AccessTools.TypeByName("GiddyUpCore.Storage.ExtendedPawnData"); MP.RegisterSyncWorker <object>(ExtendedPawnData, type); } // Remove Random { MpCompat.harmony.Patch(AccessTools.Method("GiddyUpCore.Utilities.NPCMountUtility:generateMounts"), prefix: new HarmonyMethod(typeof(GiddyUpCoreCompat), nameof(GenerateMountsPrefix)), postfix: new HarmonyMethod(typeof(GiddyUpCoreCompat), nameof(GenerateMountsPostfix)), transpiler: new HarmonyMethod(typeof(GiddyUpCoreCompat), nameof(GenerateMountsTranspiler))); } }
// PowerLogic requires late loading as some of the Types have statics that are not ready early. void LateLoad() { Type type; type = AccessTools.TypeByName("PowerLogic.Building_BaseLogicGate"); MP.RegisterSyncMethod(type, "<GetGizmos>b__14_0"); MP.RegisterSyncMethod(type, "<GetGizmos>b__14_2"); MP.RegisterSyncMethod(type, "<GetGizmos>b__14_4"); type = AccessTools.TypeByName("PowerLogic.Building_CurrentSensor"); MP.RegisterSyncMethod(type, "<GetGizmos>b__15_1"); type = AccessTools.TypeByName("PowerLogic.Building_HeatSensor"); MP.RegisterSyncMethod(type, "<GetGizmos>b__30_0"); MP.RegisterSyncMethod(type, "<GetGizmos>b__30_1"); MP.RegisterSyncMethod(type, "<GetGizmos>b__30_2"); MP.RegisterSyncMethod(type, "<GetGizmos>b__30_3"); MP.RegisterSyncMethod(type, "<GetGizmos>b__30_4"); MP.RegisterSyncMethod(type, "<GetGizmos>b__30_6"); type = AccessTools.TypeByName("PowerLogic.Building_LightSensor"); MP.RegisterSyncMethod(type, "<GetGizmos>b__30_0"); MP.RegisterSyncMethod(type, "<GetGizmos>b__30_1"); MP.RegisterSyncMethod(type, "<GetGizmos>b__30_3"); type = AccessTools.TypeByName("PowerLogic.Building_StackSensor"); MP.RegisterSyncMethod(type, "<GetGizmos>b__19_0"); MP.RegisterSyncMethod(type, "<GetGizmos>b__19_1"); MP.RegisterSyncMethod(type, "<GetGizmos>b__19_2"); MP.RegisterSyncMethod(type, "<GetGizmos>b__19_3"); MP.RegisterSyncMethod(type, "<GetGizmos>b__19_4"); MP.RegisterSyncMethod(type, "<GetGizmos>b__19_5"); type = AccessTools.TypeByName("PowerLogic.CompIFF"); MP.RegisterSyncMethod(type, "<CompGetGizmosExtra>b__5_1"); MP.RegisterSyncMethod(type, "<CompGetGizmosExtra>b__5_3"); type = AccessTools.TypeByName("PowerLogic.CompProxSensor"); MP.RegisterSyncMethod(type, "<CompGetGizmosExtra>b__19_0"); MP.RegisterSyncMethod(type, "<CompGetGizmosExtra>b__19_1"); type = AccessTools.TypeByName("PowerLogic.CompTransceiver"); MP.RegisterSyncMethod(type, "<CompGetGizmosExtra>b__46_0"); MP.RegisterSyncMethod(type, "<CompGetGizmosExtra>b__46_1"); MP.RegisterSyncMethod(type, "<CompGetGizmosExtra>b__46_2"); MP.RegisterSyncMethod(type, "<CompGetGizmosExtra>b__46_3"); type = AccessTools.TypeByName("PowerLogic.ITab_Entanglement"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass3_1", "<FillTab>b__2"); // TODO: Need to transpile or pester modder to move his click actions into methods: // ITab_DoorMacro // ITab_ThingDirections // ITab_WifiPulser }
public VanillaFactionsSettlers(ModContentPack mod) { var type = AccessTools.TypeByName("VFE_Settlers.Utilities.UtilityEvent"); // Protection fee event MP.RegisterSyncDialogNodeTree(type, "ProtectionFee"); // Caravan gizmo - turn in wanted criminal to settlement MP.RegisterSyncDelegate(type, "<>c__DisplayClass8_0", "<CommandTurnInWanted>b__0"); // Toggle mode MpCompat.RegisterSyncMethodByIndex(AccessTools.TypeByName("Warmup.CompWarmUpReduction"), "<CompGetGizmosExtra>", 1); // Five fingers fillet table PatchingUtilities.PatchUnityRand("VFE_Settlers.JobGivers.JobDriver_PlayFiveFingerFillet:WatchTickAction", false); }
private static void LatePatch() { // BuildingAltar continuation { // TempleCardUtility is used for UI drawing, called from BuildingAltar var type = AccessTools.TypeByName("Corruption.Worship.TempleCardUtility"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass4_1", "<OpenDedicationSelectMenu>b__1"); // We patch the modded method to intercept some of their calls that will need syncing and call them through our methods, // as syncing the actual methods themselves will sync way too much (methods might/will be called often) MpCompat.harmony.Patch(AccessTools.Method(type, "DrawSermonTemplate"), prefix: new HarmonyMethod(typeof(CorruptionWorship), nameof(DrawSermonTemplatePrefix)), postfix: new HarmonyMethod(typeof(CorruptionWorship), nameof(DrawSermonTemplatePostfix)), transpiler: new HarmonyMethod(typeof(CorruptionWorship), nameof(PatchDrawSermonTemplate))); // The previous inner class (<>c__DisplayClass4_1) needs the following one to be synced too, but this one uses sermon // which requires a bit more data to sync, so we make SyncWorker manually instead of using RegisterSyncDelegate var inner = AccessTools.Inner(type, "<>c__DisplayClass4_0"); templeCardUtilityInnerAltarField = AccessTools.FieldRefAccess <Building>(inner, "altar"); templeCardUtilityInnerSermonField = AccessTools.FieldRefAccess <object>(inner, "template"); MP.RegisterSyncMethod(typeof(CorruptionWorship), nameof(SyncedInterceptedReceiveMemo)); MP.RegisterSyncMethod(typeof(CorruptionWorship), nameof(SyncedInterceptedEndSermon)); MP.RegisterSyncMethod(typeof(CorruptionWorship), nameof(SyncedTryStartSermon)).SetDebugOnly(); MP.RegisterSyncMethod(typeof(CorruptionWorship), nameof(SyncSimpleSermonData)); } // Dialog_ReligiousRiot, opened when there's enough pawns of different religion // Should open for all players, so we assume we can get it/sync it using Find.WindowStack { religiousRiotType = AccessTools.TypeByName("Corruption.Worship.Dialog_ReligiousRiot"); MP.RegisterSyncMethod(religiousRiotType, "ChooseNewReligion"); MP.RegisterSyncMethod(religiousRiotType, "PreserveReligion"); MP.RegisterSyncWorker <Window>(SyncReligiousRiotDialog, religiousRiotType); } // Other stuff { // Rotating worship statue var type = AccessTools.TypeByName("Corruption.Worship.Building_WorshipStatue"); MpCompat.RegisterLambdaMethod(type, "GetGizmos", 0); // Debug ring the bell type = AccessTools.TypeByName("Corruption.Worship.CompBellTower"); MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 0).SetDebugOnly(); // Drop effigy type = AccessTools.TypeByName("Corruption.Worship.CompShrine"); MP.RegisterSyncMethod(type, "DropEffigy"); } }
public AvoidFriendlyFire(ModContentPack mod) { Type type; { type = extendedPawnDataType = AccessTools.TypeByName("AvoidFriendlyFire.ExtendedPawnData"); MP.RegisterSyncWorker <object>(SyncWorkerFor, type); avoidFriendlyFireField = type.GetField("AvoidFriendlyFire"); } { type = AccessTools.TypeByName("AvoidFriendlyFire.Pawn_DraftController_GetGizmos_Patch"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass0_0", "<Postfix>b__1"); } }
public SimpleSidearmsCompat(ModContentPack mod) { Type type; { type = AccessTools.TypeByName("SimpleSidearms.intercepts.FloatMenuMakerMap_AddHumanLikeOrders_Postfix"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass0_0", "<AddHumanlikeOrders>b__0"); } { type = AccessTools.TypeByName("SimpleSidearms.utilities.WeaponAssingment"); MP.RegisterSyncMethod(type, "SetPrimary"); MP.RegisterSyncMethod(type, "weaponSwapSpecific"); MP.RegisterSyncMethod(type, "dropSidearm"); MP.RegisterSyncMethod(type, "forgetSidearmMemory"); } { type = AccessTools.TypeByName("SimpleSidearms.rimworld.GoldfishModule"); MP.RegisterSyncMethod(type, "SetPrimaryEmpty"); MP.RegisterSyncMethod(type, "AddSidearm"); MP.RegisterSyncMethod(type, "DropPrimary"); MP.RegisterSyncMethod(type, "DropSidearm"); MP.RegisterSyncWorker <object>(SyncWorkerForGoldfishModule, type); GoldfishModule_PawnProperty = AccessTools.Property(type, "Owner"); GoldfishModule_GetGoldfishForPawnMethod = AccessTools.Method(type, "GetGoldfishForPawn"); } // All the following for that tiny lock?! // This is an exercise of futility testing the limits of the API // TODO: Pester modder to encapsulate autoLockOnManualSwap in a method LongEventHandler.ExecuteWhenFinished(delegate { type = AccessTools.TypeByName("SimpleSidearms.rimworld.SwapControlsHandler"); MP.RegisterSyncWorker <object>(SyncWorkerForSwapControlsHandler, type); autoLockOnManualSwapSyncField = MP.RegisterSyncField(type, "autoLockOnManualSwap"); SwapControlsHandler_PawnProperty = AccessTools.Property(type, "Owner"); SwapControlsHandler_GetHandlerForPawnMethod = AccessTools.Method(type, "GetHandlerForPawn"); type = AccessTools.TypeByName("SimpleSidearms.rimworld.Gizmo_SidearmsList"); MpCompat.harmony.Patch(AccessTools.Method(type, "DrawLocklock"), prefix: new HarmonyMethod(typeof(SimpleSidearmsCompat), nameof(DrawLockPrefix)), postfix: new HarmonyMethod(typeof(SimpleSidearmsCompat), nameof(DrawLockPostfix))); }); }
public GiddyUpRideAndRollCompat(ModContentPack mod) { // Stop waiting MP.RegisterSyncDelegate( AccessTools.TypeByName("GiddyUpRideAndRoll.Harmony.Pawn_GetGizmos"), "<>c__DisplayClass1_0", "<CreateGizmo_LeaveRider>b__0" ); // Unsure... May not be needed. Harmless to have it. MP.RegisterSyncMethod( AccessTools.Method("GiddyUpRideAndRoll.Harmony.CaravanEnterMapUtility_Enter:MountCaravanMounts") ); // Pawn Column Workers { MP.RegisterSyncMethod(AccessTools.Method("GiddyUpRideAndRoll.PawnColumns.PawnColumnWorker_RR_Mountable_Anyone:SetValue")); MP.RegisterSyncMethod(AccessTools.Method("GiddyUpRideAndRoll.PawnColumns.PawnColumnWorker_RR_Mountable_Master:SetValue")); } // AreaGU Randomness { AreaGUType = AccessTools.TypeByName("GiddyUpCore.Zones.Area_GU"); MpCompat.harmony.Patch(AccessTools.Method("Verse.AreaManager:AddStartingAreas"), postfix: new HarmonyMethod(typeof(GiddyUpRideAndRollCompat), nameof(AddStartingAreasPostfix)) ); MpCompat.harmony.Patch(AccessTools.Method(AreaGUType, "GetUniqueLoadID"), postfix: new HarmonyMethod(typeof(GiddyUpRideAndRollCompat), nameof(GetUniqueLoadIDPostfix)) ); } // Designators { Type type = AccessTools.TypeByName("GiddyUpCore.Zones.Designator_GU"); AreaLabelField = AccessTools.Field(type, "areaLabel"); SetSelectedAreaMethod = AccessTools.Method(type, "setSelectedArea"); MP.RegisterSyncWorker <Designator>(DesignatorGU, type, true); DesignatorDropAnimalExpandType = AccessTools.TypeByName("GiddyUpRideAndRoll.Zones.Designator_GU_DropAnimal_Expand"); DesignatorDropAnimalClearType = AccessTools.TypeByName("GiddyUpRideAndRoll.Zones.Designator_GU_DropAnimal_Clear"); DesignatorNoMountExpandType = AccessTools.TypeByName("GiddyUpRideAndRoll.Zones.Designator_GU_NoMount_Expand"); DesignatorNoMountClearType = AccessTools.TypeByName("GiddyUpRideAndRoll.Zones.Designator_GU_NoMount_Clear"); } }
public VanillaFactionsSettlers(ModContentPack mod) { var type = AccessTools.TypeByName("VFE_Settlers.Utilities.UtilityEvent"); // Protection fee event NodeTreeDialogSync.EnableNodeTreeDialogSync(); MpCompat.harmony.Patch(AccessTools.Method(type, "ProtectionFee"), prefix: NodeTreeDialogSync.HarmonyMethodMarkDialogAsOpen); // Caravan gizmo - turn in wanted criminal to settlement MP.RegisterSyncDelegate(type, "<>c__DisplayClass8_0", "<CommandTurnInWanted>b__0"); // Dev mode set progress to 1 MpCompat.RegisterSyncMethodByIndex(AccessTools.TypeByName("VFE_Settlers.Buildings.Building_ChemshineBarrel"), "<GetGizmos>", 0); // Toggle mode MpCompat.RegisterSyncMethodByIndex(AccessTools.TypeByName("VanillaFactionsExpandedSettlers.CompWarmUpReduction"), "<CompGetGizmosExtra>", 1); // Five fingers fillet table PatchingUtilities.PatchUnityRand("VFE_Settlers.JobGivers.JobDriver_PlayFiveFingerFillet:WatchTickAction", false); }
public VanillaExpandedFramework(ModContentPack mod) { var type = AccessTools.TypeByName("ItemProcessor.Building_ItemProcessor"); // _1, _5 and _7 are used to check if gizmo should be enabled, so we don't sync them MpCompat.RegisterSyncMethodsByIndex(type, "<GetGizmos>", 0, 2, 3, 4, 6, 8, 9, 10); type = AccessTools.TypeByName("ItemProcessor.Command_SetQualityList"); MP.RegisterSyncWorker <Command>(SyncCommandWithBuilding, type, shouldConstruct: true); MpCompat.RegisterSyncMethodsByIndex(type, "<ProcessInput>", Enumerable.Range(0, 8).ToArray()); type = AccessTools.TypeByName("ItemProcessor.Command_SetOutputList"); MP.RegisterSyncWorker <Command>(SyncCommandWithBuilding, type, shouldConstruct: true); MP.RegisterSyncMethod(type, "TryConfigureIngredientsByOutput"); // Keep an eye on this in the future, seems like something the devs could combine into a single class at some point foreach (var ingredientNumber in new[] { "First", "Second", "Third", "Fourth" }) { type = AccessTools.TypeByName($"ItemProcessor.Command_Set{ingredientNumber}ItemList"); MP.RegisterSyncWorker <Command>(SyncSetIngredientCommand, type, shouldConstruct: true); MP.RegisterSyncMethod(type, $"TryInsert{ingredientNumber}Thing"); MpCompat.RegisterSyncMethodsByIndex(type, "<ProcessInput>", 0); } // AddHediff desyncs with Arbiter, but seems fine without it PatchingUtilities.PatchPushPopRand("VanillaCookingExpanded.Thought_Hediff:MoodOffset"); type = AccessTools.TypeByName("VFECore.CompPawnDependsOn"); MpCompat.RegisterSyncMethodByIndex(type, "<CompGetGizmosExtra>", 0).SetDebugOnly(); type = AccessTools.TypeByName("VanillaFurnitureExpanded.CompConfigurableSpawner"); MpCompat.RegisterSyncMethodByIndex(type, "<CompGetGizmosExtra>", 0).SetDebugOnly(); type = AccessTools.TypeByName("VanillaFurnitureExpanded.Command_SetItemsToSpawn"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass2_0", "<ProcessInput>b__1"); type = AccessTools.TypeByName("VanillaFurnitureExpanded.CompRockSpawner"); MpCompat.RegisterSyncMethodByIndex(type, "<CompGetGizmosExtra>", 0); type = AccessTools.TypeByName("VanillaFurnitureExpanded.Command_SetStoneType"); setStoneBuildingField = AccessTools.Field(type, "building"); MpCompat.RegisterSyncMethodByIndex(type, "<ProcessInput>", 0); MP.RegisterSyncWorker <Command>(SyncSetStoneTypeCommand, type, shouldConstruct: true); MP.RegisterSyncDelegate(type, "<>c__DisplayClass2_0", "<ProcessInput>b__1"); }
public SRTSExpanded(ModContentPack mod) { LongEventHandler.ExecuteWhenFinished(DelayedPatch); // Refuel shuttle MP.RegisterSyncDelegate(AccessTools.TypeByName("SRTS.StartUp"), "<>c__DisplayClass24_1", "<LaunchAndBombGizmosPassthrough>b__3"); // Bombing MP.RegisterSyncWorker <Pair <IntVec3, IntVec3> >(SyncIntVec3Pair, typeof(Pair <IntVec3, IntVec3>)); var type = AccessTools.TypeByName("SRTS.CompBombFlyer"); MP.RegisterSyncMethod(type, "TryLaunchBombRun"); bombTypeSync = MP.RegisterSyncField(type, "bombType"); foreach (MethodInfo method in MpCompat.MethodsByIndex(type, "<CompGetGizmosExtra>", 1, 2)) { MpCompat.harmony.Patch(method, prefix: new HarmonyMethod(typeof(SRTSExpanded), nameof(PreSyncBombType)), postfix: new HarmonyMethod(typeof(SRTSExpanded), nameof(PostSyncBombType))); } }
public VanillaAnimalsEndangered(ModContentPack mod) { var type = AccessTools.TypeByName("VanillaAnimalsExpandedEndangered.Pawn_GetGizmos_Patch"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass3_0", "<Postfix>b__1"); }
public RunandGun(ModContentPack mod) { Type type = AccessTools.TypeByName("RunAndGun.Harmony.Pawn_DraftController_GetGizmos_Patch"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass0_0", "<Postfix>b__1"); }
public DragonsDescent(ModContentPack mod) { // Incubator { var type = AccessTools.TypeByName("DD.CompEggIncubator"); var methods = MpCompat.RegisterSyncMethodsByIndex(type, "<CompGetGizmosExtra>", 1, 2, 3, 4); foreach (var method in methods.Skip(1)) // All but the first one are debug-only gizmos { method.SetDebugOnly(); } type = AccessTools.TypeByName("DD.CompProperties_EggIncubator"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass7_0", "<CreateGizmo>b__0"); } // Abilities { var type = AccessTools.TypeByName("DD.AbilityComp_AbilityControl"); var gizmoActionMethod = MpCompat.MethodByIndex(type, "<get_Gizmo>", 1); MP.RegisterSyncMethod(gizmoActionMethod); // Toggle active MpCompat.harmony.Patch(gizmoActionMethod, prefix: new HarmonyMethod(typeof(DragonsDescent), nameof(PreGizmoActionCalled))); abilityCompGizmoGetter = AccessTools.PropertyGetter(type, "Gizmo"); } // Hostility response type changing { var type = AccessTools.TypeByName("DD.CompHostileResponse"); hostilityResponseTypeField = AccessTools.Field(type, "type"); var inner = AccessTools.Inner(type, "<>c__DisplayClass15_0"); MP.RegisterSyncMethod(typeof(DragonsDescent), nameof(SyncSetHostilityResponseType)); compHostileResponseField = AccessTools.Field(inner, "<>4__this"); MpCompat.harmony.Patch(AccessTools.Method(inner, "<get_Gizmo>b__1"), prefix: new HarmonyMethod(typeof(DragonsDescent), nameof(PreSetHostilityResponseType))); } // Altar { compRitualAltarType = AccessTools.TypeByName("DD.CompRitualAltar"); MP.RegisterSyncDelegate(compRitualAltarType, "<>c__DisplayClass11_0", "<CompGetGizmosExtra>b__0").SetDebugOnly(); MP.RegisterSyncDelegate(compRitualAltarType, "<>c__DisplayClass11_0", "<CompGetGizmosExtra>b__1").SetDebugOnly(); MP.RegisterSyncDelegate(compRitualAltarType, "<>c__DisplayClass11_0", "<CompGetGizmosExtra>b__2").SetDebugOnly(); MP.RegisterSyncDelegate(compRitualAltarType, "<>c__DisplayClass11_0", "<CompGetGizmosExtra>b__3").SetDebugOnly(); var type = AccessTools.TypeByName("DD.RitualTracker"); MP.RegisterSyncWorker <object>(SyncRitualTracker, type); ritualTrackerGetRitualMethod = AccessTools.Method(type, "GetRitual"); ritualTrackerMapField = AccessTools.Field(type, "map"); trackerMapComponentType = AccessTools.TypeByName("DD.MapComponent_Tracker"); trackerMapComponentRitualsField = AccessTools.Field(trackerMapComponentType, "rituals"); ritualReferenceType = AccessTools.TypeByName("DD.RitualReference"); ritualReferenceDefField = AccessTools.Field(ritualReferenceType, "def"); var inner = AccessTools.Inner(ritualReferenceType, "<>c__DisplayClass12_0"); MpCompat.RegisterSyncMethodsByIndex(inner, "<SetupAction>", 0, 1); MP.RegisterSyncWorker <object>(SyncRitualReferenceInnerClass, inner, shouldConstruct: true); ritualReferenceInnerRitualField = AccessTools.Field(inner, "ritual"); ritualReferenceInnerSelfField = AccessTools.Field(inner, "<>4__this"); ritualReferenceInnerParentField = AccessTools.Field(inner, "parent"); ritualReferenceInnerRitualsField = AccessTools.Field(inner, "rituals"); type = AccessTools.TypeByName("DD.CompProperties_Ritual"); ritualCompPropertiesRitualsField = AccessTools.Field(type, "rituals"); } }
static void LateLoad() { Type type; // Float Menus { type = AccessTools.TypeByName("CombatExtended.Harmony.FloatMenuMakerMap_Modify_AddHumanlikeOrders"); // CE_Stabilizing MP.RegisterSyncDelegate(type, "<>c__DisplayClass1_1", "<AddMenuItems>b__1"); // PickUp MP.RegisterSyncDelegate(type, "<>c__DisplayClass1_2", "<AddMenuItems>b__4"); // PickUpAll MP.RegisterSyncDelegate(type, "<>c__DisplayClass1_2", "<AddMenuItems>b__5"); // PickUpSome MP.RegisterSyncDelegate(type, "<>c__DisplayClass1_2", "<AddMenuItems>b__7"); // Dialog_Slider MP.RegisterSyncDelegate(type, "<>c__DisplayClass1_3", "<AddMenuItems>b__6"); } // Pawn Gizmos { // Reload type = AccessTools.TypeByName("CombatExtended.CompAmmoUser"); MP.RegisterSyncMethod(type, "TryStartReload"); } { // Toggles type = AccessTools.TypeByName("CombatExtended.CompFireModes"); MP.RegisterSyncMethod(type, "ResetModes"); MP.RegisterSyncMethod(type, "ToggleAimMode"); MP.RegisterSyncMethod(type, "ToggleFireMode"); } // Turret Gizmos { type = AccessTools.TypeByName("CombatExtended.Building_TurretGunCE"); MP.RegisterSyncMethod(type, "<GetGizmos>b__64_0"); MP.RegisterSyncMethod(type, "<GetGizmos>b__64_1"); MP.RegisterSyncMethod(type, "TryOrderReload"); } // Loadouts { type = AccessTools.TypeByName("CombatExtended.Utility_Loadouts"); MP.RegisterSyncMethod(type, "SetLoadout"); MP.RegisterSyncMethod(type, "SetLoadoutById"); MP.RegisterSyncMethod(type, "GenerateLoadoutFromPawn"); } { type = AccessTools.TypeByName("CombatExtended.Loadout"); MP.RegisterSyncMethod(type, "Copy", new SyncType[] { type }); MP.RegisterSyncMethod(type, "Copy"); MP.RegisterSyncMethod(type, "AddSlot"); MP.RegisterSyncMethod(type, "MoveSlot"); MP.RegisterSyncMethod(type, "RemoveSlot", new SyncType[] { typeof(int) }); MP.RegisterSyncMethod(type, "RemoveSlot", new SyncType[] { AccessTools.TypeByName("CombatExtended.LoadoutSlot") }); } // iTab Inventory? { // TODO } // RNG prevention { var methods = new[] { AccessTools.Method("CombatExtended.CompSuppressable:AddSuppression"), AccessTools.Method("CombatExtended.CompSuppressable:CompTick"), // oh boy shooting doesn't work... // TODO }; foreach (var method in methods) { MpCompat.harmony.Patch(method, prefix: new HarmonyMethod(typeof(CombatExtendedCompat), nameof(FixRNGPre)), postfix: new HarmonyMethod(typeof(CombatExtendedCompat), nameof(FixRNGPos)) ); } } }
public GeneticRimCompat(ModContentPack mod) { Type type; // Several Gizmos { type = AccessTools.TypeByName("GeneticRim.GeneticRim_Pawn_GetGizmos_Patch"); string[] methods = { "<AddGizmo>b__0", "<AddGizmo>b__1", "<AddGizmo>b__10", "<AddGizmo>b__11", "<AddGizmo>b__12", "<AddGizmo>b__13", "<AddGizmo>b__14", "<AddGizmo>b__15", "<AddGizmo>b__16", "<AddGizmo>b__17", "<AddGizmo>b__3", "<AddGizmo>b__5", "<AddGizmo>b__7", "<AddGizmo>b__8", "<AddGizmo>b__9", }; foreach (string method in methods) { MP.RegisterSyncDelegate(type, "<>c__DisplayClass0_0", method); } } // ArchotechShip startup { MP.RegisterSyncMethod(AccessTools.Method("GeneticRim.ArchotechUtility:StartupHibernatingParts")); MP.RegisterSyncMethod(AccessTools.Method("GeneticRim.ArchotechCountdown:InitiateCountdown")); } { type = AccessTools.TypeByName("GeneticRim.ArchotechCountdown"); string[] methods = { "InitiateCountdown", "CancelCountdown", "CountdownEnded" }; foreach (string method in methods) { MP.RegisterSyncMethod(AccessTools.Method(type, method)); } } // RNG patching { string[] constructorsToPatch = { "GeneticRim.CompHatcherRandomizer", "GeneticRim.CompIncubator", "GeneticRim.CompRecombinator", "GeneticRim.CompRecombinatorSerum", "GeneticRim.DeathActionWorker_Eggxplosion", "GeneticRim.CompExploder", }; PatchingUtilities.PatchSystemRandCtor(constructorsToPatch, false); string[] methodsWithRand = { "GeneticRim.CompHatcherRandomizer:Hatch", "GeneticRim.CompIncubator:Hatch", "GeneticRim.CompRecombinator:Hatch", "GeneticRim.CompRecombinator:RecombinateAgain", "GeneticRim.CompRecombinatorSerum:Hatch", "GeneticRim.DeathActionWorker_Eggxplosion:PawnDied", "GeneticRim.CompExploder:wickInitializer", }; PatchingUtilities.PatchPushPopRand(methodsWithRand); } }
public VanillaExpandedFramework(ModContentPack mod) { // ItemProcessor { var type = AccessTools.TypeByName("ItemProcessor.Building_ItemProcessor"); // _1, _5 and _7 are used to check if gizmo should be enabled, so we don't sync them MpCompat.RegisterSyncMethodsByIndex(type, "<GetGizmos>", 0, 2, 3, 4, 6, 8, 9, 10); type = AccessTools.TypeByName("ItemProcessor.Command_SetQualityList"); MP.RegisterSyncWorker <Command>(SyncCommandWithBuilding, type, shouldConstruct: true); MpCompat.RegisterSyncMethodsByIndex(type, "<ProcessInput>", Enumerable.Range(0, 8).ToArray()); type = AccessTools.TypeByName("ItemProcessor.Command_SetOutputList"); MP.RegisterSyncWorker <Command>(SyncCommandWithBuilding, type, shouldConstruct: true); MP.RegisterSyncMethod(type, "TryConfigureIngredientsByOutput"); // Keep an eye on this in the future, seems like something the devs could combine into a single class at some point foreach (var ingredientNumber in new[] { "First", "Second", "Third", "Fourth" }) { type = AccessTools.TypeByName($"ItemProcessor.Command_Set{ingredientNumber}ItemList"); MP.RegisterSyncWorker <Command>(SyncSetIngredientCommand, type, shouldConstruct: true); MP.RegisterSyncMethod(type, $"TryInsert{ingredientNumber}Thing"); MpCompat.RegisterSyncMethodsByIndex(type, "<ProcessInput>", 0); } } // Vanilla Cooking Expanded { // AddHediff desyncs with Arbiter, but seems fine without it PatchingUtilities.PatchPushPopRand("VanillaCookingExpanded.Thought_Hediff:MoodOffset"); } // VFE Core { var type = AccessTools.TypeByName("VFECore.CompPawnDependsOn"); MpCompat.RegisterSyncMethodByIndex(type, "<CompGetGizmosExtra>", 0).SetDebugOnly(); } // Vanilla Furniture Expanded { var type = AccessTools.TypeByName("VanillaFurnitureExpanded.CompConfigurableSpawner"); MpCompat.RegisterSyncMethodByIndex(type, "<CompGetGizmosExtra>", 0).SetDebugOnly(); type = AccessTools.TypeByName("VanillaFurnitureExpanded.Command_SetItemsToSpawn"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass2_0", "<ProcessInput>b__1"); type = AccessTools.TypeByName("VanillaFurnitureExpanded.CompRockSpawner"); MpCompat.RegisterSyncMethodByIndex(type, "<CompGetGizmosExtra>", 0); type = AccessTools.TypeByName("VanillaFurnitureExpanded.Command_SetStoneType"); setStoneBuildingField = AccessTools.Field(type, "building"); MpCompat.RegisterSyncMethodByIndex(type, "<ProcessInput>", 0); MP.RegisterSyncWorker <Command>(SyncSetStoneTypeCommand, type, shouldConstruct: true); MP.RegisterSyncDelegate(type, "<>c__DisplayClass2_0", "<ProcessInput>b__1"); } // Vanilla Faction Mechanoids { var type = AccessTools.TypeByName("VFE.Mechanoids.CompMachineChargingStation"); MP.RegisterSyncDelegate(type, "<>c", "<CompGetGizmosExtra>b__21_1", Array.Empty <string>()).SetContext(SyncContext.MapSelected); MP.RegisterSyncDelegate(type, "<>c", "<CompGetGizmosExtra>b__21_6", Array.Empty <string>()).SetContext(SyncContext.MapSelected); MP.RegisterSyncDelegate(type, "<>c__DisplayClass21_0", "<CompGetGizmosExtra>b__4"); } // AnimalBehaviours { // RNG PatchingUtilities.PatchSystemRand("AnimalBehaviours.DamageWorker_ExtraInfecter:ApplySpecialEffectsToPart", false); PatchingUtilities.PatchSystemRandCtor(new[] { "AnimalBehaviours.CompAnimalProduct", "AnimalBehaviours.CompGasProducer" }, false); // Gizmos // Might not work, as I could not find a mod that uses this to test this var type = AccessTools.TypeByName("AnimalBehaviours.CompDestroyThisItem"); MP.RegisterSyncMethod(type, "SetObjectForDestruction"); MP.RegisterSyncMethod(type, "CancelObjectForDestruction"); } // MVCF (Multi Verb Combat Framework) { var type = AccessTools.TypeByName("MVCF.WorldComponent_MVCF"); mvcfGetWorldCompMethod = AccessTools.Method(type, "GetComp"); mvcfAllManagersListField = AccessTools.Field(type, "allManagers"); mvcfManagersTableField = AccessTools.Field(type, "managers"); MP.RegisterSyncMethod(typeof(VanillaExpandedFramework), nameof(SyncedInitVerbManager)); MpCompat.harmony.Patch(AccessTools.Method(type, "GetManagerFor"), prefix: new HarmonyMethod(typeof(VanillaExpandedFramework), nameof(GetManagerForPrefix))); type = AccessTools.TypeByName("MVCF.VerbManager"); MP.RegisterSyncWorker <object>(SyncVerbManager, type, isImplicit: true); mvcfVerbManagerCtor = AccessTools.Constructor(type); mvcfInitializeManagerMethod = AccessTools.Method(type, "Initialize"); mvcfPawnGetter = AccessTools.PropertyGetter(type, "Pawn"); mvcfVerbsField = AccessTools.Field(type, "verbs"); var weakReferenceType = typeof(System.WeakReference <>).MakeGenericType(new[] { type }); weakReferenceCtor = AccessTools.FirstConstructor(weakReferenceType, ctor => ctor.GetParameters().Count() == 1); var conditionalWeakTableType = typeof(System.Runtime.CompilerServices.ConditionalWeakTable <,>).MakeGenericType(new[] { typeof(Pawn), type }); conditionalWeakTableAddMethod = AccessTools.Method(conditionalWeakTableType, "Add"); conditionalWeakTableTryGetValueMethod = AccessTools.Method(conditionalWeakTableType, "TryGetValue"); type = AccessTools.TypeByName("MVCF.ManagedVerb"); mvcfManagerVerbManagerField = AccessTools.Field(type, "man"); MP.RegisterSyncWorker <object>(SyncManagedVerb, type, isImplicit: true); // Seems like selecting the Thing that holds the verb inits some stuff, so we need to set the context MP.RegisterSyncMethod(type, "Toggle"); type = AccessTools.TypeByName("MVCF.Harmony.Gizmos"); MP.RegisterSyncDelegate(type, "<>c__DisplayClass5_0", "<GetGizmos_Postfix>b__1"); // Fire at will MP.RegisterSyncDelegate(type, "<>c__DisplayClass6_0", "<GetAttackGizmos_Postfix>b__4"); // Interrupt Attack MP.RegisterSyncDelegate(type, "<>c__DisplayClass7_0", "<Pawn_GetGizmos_Postfix>b__0"); // Also interrupt Attack } }
private static void LatePatch() { // Tables { var type = AccessTools.TypeByName("Gastronomy.Dining.CompCanDineAt"); MP.RegisterSyncMethod(type, "ChangeDeco"); MP.RegisterSyncMethod(type, "ToggleDining"); } // Register menu { // ITab_Register var type = AccessTools.TypeByName("Gastronomy.TableTops.ITab_Register"); hiddenSpecialThingFiltersMethod = AccessTools.Method(type, "HiddenSpecialThingFilters"); MpCompat.harmony.Patch( AccessTools.Method(type, "FillTab"), prefix: new HarmonyMethod(typeof(Gastronomy), nameof(FillTabPrefix)), postfix: new HarmonyMethod(typeof(Gastronomy), nameof(FillTabPostfix))); // Clear debt on cliking it MP.RegisterSyncDelegate(type, "<>c__DisplayClass18_0", "<DrawDebts>b__1").CancelIfAnyFieldNull().CancelIfNoSelectedObjects().SetContext(SyncContext.CurrentMap); // Sync worker for debt itself, requires SyncContext.CurrentMap type = AccessTools.TypeByName("Gastronomy.Restaurant.Debt"); MP.RegisterSyncWorker <object>(SyncDebt, type); // RestaurantDebt, used for finding the debt type = AccessTools.TypeByName("Gastronomy.Restaurant.RestaurantDebt"); restaurantDebtAllDebtsField = AccessTools.Field(type, "debts"); // Building_CashRegister type = AccessTools.TypeByName("Gastronomy.TableTops.Building_CashRegister"); restaurantControllerField = AccessTools.Field(type, "restaurant"); // TimetableBool type = AccessTools.TypeByName("Gastronomy.Restaurant.Timetable.TimetableBool"); timetableTimesField = AccessTools.Field(type, "times"); // RestaurantMenu type = AccessTools.TypeByName("Gastronomy.Restaurant.RestaurantMenu"); menuFilterField = AccessTools.Field(type, "menuFilter"); menuGlobalFilterField = AccessTools.Field(type, "menuGlobalFilter"); initMenuFilterMethod = AccessTools.Method(type, "InitMenuFilter"); initMenuGlobalFilterMethod = AccessTools.Method(type, "InitMenuGlobalFilter"); MpCompat.harmony.Patch( AccessTools.Constructor(type), prefix: new HarmonyMethod(typeof(Gastronomy), nameof(RestaurantMenuConstructorPrefix))); // RestaurantController restaurantControllerType = AccessTools.TypeByName("Gastronomy.RestaurantController"); controllerFieldsToSync = (new[] { "openForBusiness", "allowGuests", "allowColonists", "allowPrisoners", "guestPricePercentage" }).Select(x => MP.RegisterSyncField(restaurantControllerType, x)).ToArray(); controllerTimetableField = AccessTools.Field(restaurantControllerType, "timetableOpen"); controllerMenuField = AccessTools.Field(restaurantControllerType, "menu"); controllerTimesSync = MP.RegisterSyncField(restaurantControllerType, "timetableOpen/times").SetBufferChanges(); controllerDebtField = AccessTools.Field(restaurantControllerType, "debts"); } // MP overrides { // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Multiplayer.cs#L58 shouldSyncGetter = AccessTools.PropertyGetter(AccessTools.TypeByName("Multiplayer.Client.Multiplayer"), "ShouldSync"); // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Sync/SyncHandlers.cs#L771 allowCategoryHelperMethod = AccessTools.Method(AccessTools.TypeByName("Multiplayer.Client.SyncThingFilters"), "ThingFilter_AllowCategory_Helper"); // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Sync/SyncSerialization.cs#L33 // We get the thingFilterTarget, and add our own filter to it var thingFilterTarget = AccessTools.Field(AccessTools.TypeByName("Multiplayer.Client.Sync"), "thingFilterTarget"); var target = thingFilterTarget.GetValue(null); // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Sync/Sync.cs#L1243 // Get and call the method to add our filter AccessTools.Method(AccessTools.TypeByName("Multiplayer.Client.MultiTarget"), "Add", new Type[] { typeof(Type), typeof(string) }) .Invoke(target, new object[] { restaurantControllerType, "menu/menuFilter" }); // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Sync/SyncHandlers.cs#L960 MpCompat.harmony.Patch(AccessTools.PropertyGetter(AccessTools.TypeByName("Multiplayer.Client.SyncMarkers"), "ThingFilterOwner"), prefix: new HarmonyMethod(typeof(Gastronomy), nameof(ThingFilterOwnerPrefix))); // Set prefixes to the 3 methods that need some additional work that isn't universal to all filters // (See the methods for github links) MpCompat.harmony.Patch(AccessTools.Method(typeof(ThingFilter), nameof(ThingFilter.SetAllow), new[] { typeof(ThingCategoryDef), typeof(bool), typeof(IEnumerable <ThingDef>), typeof(IEnumerable <SpecialThingFilterDef>) }), prefix: new HarmonyMethod(typeof(Gastronomy), nameof(ThingFilter_SetAllowPrefix))); MpCompat.harmony.Patch(AccessTools.Method(typeof(ThingFilter), nameof(ThingFilter.SetDisallowAll)), prefix: new HarmonyMethod(typeof(Gastronomy), nameof(ThingFilter_SetDisallowAllPrefix))); MpCompat.harmony.Patch(AccessTools.Method(typeof(ThingFilter), nameof(ThingFilter.SetAllowAll)), prefix: new HarmonyMethod(typeof(Gastronomy), nameof(ThingFilter_SetAllowAllPrefix))); // Methods that we'll need to setup SyncFields/SyncMethods for MultiTarget var type = AccessTools.TypeByName("Multiplayer.Client.Sync"); // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Sync/Sync.cs#L801 var methodMultiTarget = AccessTools.Method(type, "MethodMultiTarget"); // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Sync/Sync.cs#L818 var fieldMultiTarget = AccessTools.Method(type, "FieldMultiTarget"); // Create fields for SyncFields that will include our filter type = AccessTools.TypeByName("Multiplayer.Client.SyncFieldsPatches"); // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Sync/SyncHandlers.cs#L66 var values = (Array)fieldMultiTarget.Invoke(null, new[] { target, nameof(ThingFilter.AllowedHitPointsPercents) }); foreach (var value in values) { ((ISyncField)value).SetBufferChanges(); } AccessTools.Field(type, "SyncThingFilterHitPoints").SetValue(null, values); // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Sync/SyncHandlers.cs#L69 values = (Array)fieldMultiTarget.Invoke(null, new[] { target, nameof(ThingFilter.AllowedQualityLevels) }); foreach (var value in values) { ((ISyncField)value).SetBufferChanges(); } AccessTools.Field(type, "SyncThingFilterQuality").SetValue(null, values); // Create fields for SyncMethods that will include our filter type = AccessTools.TypeByName("Multiplayer.Client.SyncThingFilters"); // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Sync/SyncHandlers.cs#L658 AccessTools.Field(type, "SyncThingFilterAllowThing").SetValue(null, methodMultiTarget.Invoke(null, new[] { target, nameof(ThingFilter.SetAllow), new SyncType[] { typeof(ThingDef), typeof(bool) } })); // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Sync/SyncHandlers.cs#L659 AccessTools.Field(type, "SyncThingFilterAllowSpecial").SetValue(null, methodMultiTarget.Invoke(null, new[] { target, nameof(ThingFilter.SetAllow), new SyncType[] { typeof(SpecialThingFilterDef), typeof(bool) } })); // https://github.com/rwmt/Multiplayer/blob/7aac8b54727d8626ec39429b97225fc88c807ab8/Source/Client/Sync/SyncHandlers.cs#L660 AccessTools.Field(type, "SyncThingFilterAllowStuffCategory").SetValue(null, methodMultiTarget.Invoke(null, new[] { target, nameof(ThingFilter.SetAllow), new SyncType[] { typeof(StuffCategoryDef), typeof(bool) } })); // Sync our helper methods // (See the methods for github links) MP.RegisterSyncMethod(typeof(Gastronomy), nameof(ThingFilter_DisallowAll_HelperRestaurant)); MP.RegisterSyncMethod(typeof(Gastronomy), nameof(ThingFilter_AllowAll_HelperRestaurant)); MP.RegisterSyncMethod(typeof(Gastronomy), nameof(ThingFilter_AllowCategory_HelperRestaurant)); } }
public GeneticRimCompat(ModContentPack mod) { Type type; // Several Gizmos { type = AccessTools.TypeByName("DraftingPatcher.Pawn_GetGizmos_Patch"); string[] methods = { "<AddGizmo>b__0", "<AddGizmo>b__1", "<AddGizmo>b__10", "<AddGizmo>b__11", "<AddGizmo>b__12", "<AddGizmo>b__13", "<AddGizmo>b__14", "<AddGizmo>b__15", "<AddGizmo>b__16", "<AddGizmo>b__17", "<AddGizmo>b__3", "<AddGizmo>b__5", "<AddGizmo>b__7", "<AddGizmo>b__8", "<AddGizmo>b__9", }; foreach (string method in methods) { MP.RegisterSyncDelegate(type, "<>c__DisplayClass0_0", method); } } // ArchotechShip startup { MP.RegisterSyncMethod(AccessTools.Method("NewMachinery.ArchotechUtility:StartupHibernatingParts")); MP.RegisterSyncMethod(AccessTools.Method("NewMachinery.ArchotechCountdown:InitiateCountdown")); } { type = AccessTools.TypeByName("NewMachinery.ArchotechCountdown"); string[] methods = { "InitiateCountdown", "CancelCountdown", "CountdownEnded" }; foreach (string method in methods) { MP.RegisterSyncMethod(AccessTools.Method(type, method)); } } // Genepod { type = AccessTools.TypeByName("NewMachinery.Building_NewGenePod"); MP.RegisterSyncMethod(type, "<GetGizmos>b__20_0"); MP.RegisterSyncMethod(type, "<GetGizmos>b__20_1"); } // Commands { MP.RegisterSyncMethod(AccessTools.Method("NewMachinery.Command_SetGene2List:ProcessInput")); MP.RegisterSyncMethod(AccessTools.Method("NewMachinery.Command_SetGeneList:ProcessInput")); } // RNG patching { string[] constructorsToPatch = { "NewHatcher.CompHatcherRandomizer", "NewHatcher.CompIncubator", "NewHatcher.CompRecombinator", "NewHatcher.CompRecombinatorSerum", }; PatchingUtilities.PatchSystemRandCtor(constructorsToPatch, false); string[] methodsWithRand = { "NewHatcher.CompHatcherRandomizer:Hatch", "NewHatcher.CompIncubator:Hatch", "NewHatcher.CompRecombinator:Hatch", "NewHatcher.CompRecombinator:RecombinateAgain", "NewHatcher.CompRecombinatorSerum:Hatch", }; PatchingUtilities.PatchPushPopRand(methodsWithRand); } }
public GeneticRimCompat(ModContentPack mod) { Type type; // Several Gizmos { type = AccessTools.TypeByName("DraftingPatcher.Pawn_GetGizmos_Patch"); string[] methods = { "<AddGizmo>b__0", "<AddGizmo>b__1", "<AddGizmo>b__10", "<AddGizmo>b__11", "<AddGizmo>b__12", "<AddGizmo>b__13", "<AddGizmo>b__14", "<AddGizmo>b__15", "<AddGizmo>b__16", "<AddGizmo>b__17", "<AddGizmo>b__3", "<AddGizmo>b__5", "<AddGizmo>b__7", "<AddGizmo>b__8", "<AddGizmo>b__9", }; foreach (string method in methods) { MP.RegisterSyncDelegate(type, "<>c__DisplayClass0_0", method); } } // ArchotechShip startup { MP.RegisterSyncMethod(AccessTools.Method("NewMachinery.ArchotechUtility:StartupHibernatingParts")); MP.RegisterSyncMethod(AccessTools.Method("NewMachinery.ArchotechCountdown:InitiateCountdown")); } { type = AccessTools.TypeByName("NewMachinery.ArchotechCountdown"); string[] methods = { "InitiateCountdown", "CancelCountdown", "CountdownEnded" }; foreach (string method in methods) { MP.RegisterSyncMethod(AccessTools.Method(type, method)); } } // Genepod { type = AccessTools.TypeByName("NewMachinery.Building_NewGenePod"); MP.RegisterSyncMethod(type, "<GetGizmos>b__20_0"); MP.RegisterSyncMethod(type, "<GetGizmos>b__20_1"); } // Commands { MP.RegisterSyncMethod(AccessTools.Method("NewMachinery.Command_SetGene2List:ProcessInput")); MP.RegisterSyncMethod(AccessTools.Method("NewMachinery.Command_SetGeneList:ProcessInput")); } // RNG mitigation { string[] typesWithRand = { "NewHatcher.CompHatcherRandomizer", "NewHatcher.CompIncubator", "NewHatcher.CompRecombinator", "NewHatcher.CompRecombinatorSerum", }; foreach (string typeName in typesWithRand) { type = AccessTools.TypeByName(typeName); MpCompat.harmony.Patch(AccessTools.Constructor(type), postfix: new HarmonyMethod(typeof(GeneticRimCompat), nameof(MitigateRNG)) ); } } }