public static void LatePatch() { // Ancient PD turret - toggle aiming at drop pods, enemies, explosive projectiles MpCompat.RegisterLambdaMethod("VFEAncients.Building_TurretPD", "GetGizmos", 1, 3, 5); var type = AccessTools.TypeByName("VFEAncients.CompGeneTailoringPod"); // Start gene tailoring operation (after danger warning confirmation) MP.RegisterSyncMethod(type, "StartOperation"); // Cancel operation (before starting it) MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 8); // (Dev) instant success/failure MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 9, 10).SetDebugOnly(); // (Dev) instant finish, random result not synced, as it calls CompleteOperation // would cause a tiny conflict, not worth bothering with it // (I think it would need to be done without SetDebugOnly, or it would cause issues) choosePowerDialogType = AccessTools.TypeByName("VFEAncients.Dialog_ChoosePowers"); var powerDefType = AccessTools.TypeByName("VFEAncients.PowerDef"); var tupleType = typeof(Tuple <,>).MakeGenericType(powerDefType, powerDefType); onChosen = CompileCallOnChosen(powerDefType, tupleType); MP.RegisterSyncMethod(typeof(VanillaFactionsAncients), nameof(SyncedChoosePower)); MP.RegisterSyncWorker <Window>(SyncDialogChoosePower, choosePowerDialogType); MpCompat.harmony.Patch(AccessTools.DeclaredConstructor(choosePowerDialogType, new[] { typeof(List <>).MakeGenericType(tupleType), typeof(Pawn), typeof(Action <>).MakeGenericType(tupleType) }), postfix: new HarmonyMethod(typeof(VanillaFactionsAncients), nameof(PostDialogConstructor))); MpCompat.harmony.Patch(AccessTools.Method(choosePowerDialogType, nameof(Window.DoWindowContents)), transpiler: new HarmonyMethod(typeof(VanillaFactionsAncients), nameof(ReplaceButtons))); }
public OneBedToSleepWithAll(ModContentPack mod) { compType = AccessTools.TypeByName("OneBedToSleepWithAll.CompPolygamyMode"); MpCompat.RegisterLambdaMethod(compType, "CompGetGizmosExtra", 1); // Comp has a null props.compClass, most likely it's dynamically created MP.RegisterSyncWorker <ThingComp>(SyncCompPolygamyMode, compType); }
public SmartMedicine(ModContentPack mod) { // Stock up medicine/drugs { var type = AccessTools.TypeByName("SmartMedicine.StockUpUtility"); var pasteMethod = AccessTools.Method(type, "StockUpPasteSettings"); stockUpPasteMethod = AccessTools.MethodDelegate <StockUpPasteSettingsDelegate>(pasteMethod); stockUpSettingsMethod = AccessTools.MethodDelegate <StockUpSettingsDelegate>(AccessTools.Method(type, "StockUpSettings")); MpCompat.harmony.Patch(pasteMethod, prefix: new HarmonyMethod(typeof(SmartMedicine), nameof(PrePasteSettings))); MpCompat.harmony.Patch(AccessTools.Method(type, "SetStockCount", new[] { typeof(Pawn), typeof(ThingDef), typeof(int) }), prefix: new HarmonyMethod(typeof(SmartMedicine), nameof(PreSetStockCount))); // Mod methods to sync MP.RegisterSyncMethod(AccessTools.Method(type, "StockUpStop", new[] { typeof(Pawn), typeof(ThingDef) })); MP.RegisterSyncMethod(AccessTools.Method(type, "StockUpClearSettings")); // Our methods to sync MP.RegisterSyncMethod(typeof(SmartMedicine), nameof(SyncedSetStockCount)); MP.RegisterSyncMethod(typeof(SmartMedicine), nameof(SyncedPasteSettings)); // We'll need the access to copiedPawn field to modify it when pasting smartMedicineCompType = AccessTools.TypeByName("SmartMedicine.SmartMedicineGameComp"); copiedPawnField = AccessTools.FieldRefAccess <Pawn>(smartMedicineCompType, "copiedPawn"); } // Set wound target tend quality { var type = AccessTools.TypeByName("SmartMedicine.HediffRowPriorityCare"); MpCompat.RegisterLambdaDelegate(type, "LabelButton", 0, 1); } }
public AnimalTab(ModContentPack mod) { var type = AccessTools.TypeByName("AnimalTab.Command_HandlerSettings"); commandCtor = AccessTools.Constructor(type, new[] { AccessTools.TypeByName("AnimalTab.CompHandlerSettings") }); compField = AccessTools.FieldRefAccess <ThingComp>(type, "comp"); MP.RegisterSyncMethod(type, "MassSetMode").SetContext(SyncContext.MapSelected); MP.RegisterSyncMethod(type, "MassSetHandler").SetContext(SyncContext.MapSelected); MP.RegisterSyncMethod(type, "MassSetLevel").SetContext(SyncContext.MapSelected); MP.RegisterSyncWorker <Command_Action>(SyncHandlerSettingsCommand, type); type = AccessTools.TypeByName("AnimalTab.PawnColumnWorker_Handler"); MpCompat.RegisterLambdaDelegate(type, "DoHandlerFloatMenu", 0, 1, 2); MpCompat.RegisterLambdaDelegate(type, "DoMassHandlerFloatMenu", 0, 1, 4); MpCompat.harmony.Patch(AccessTools.Method(type, nameof(PawnColumnWorker.DoHeader)), prefix: new HarmonyMethod(typeof(AnimalTab), nameof(PreDoHeader)), postfix: new HarmonyMethod(typeof(AnimalTab), nameof(StopWatch))); MpCompat.harmony.Patch(AccessTools.Method(type, nameof(PawnColumnWorker.DoCell)), prefix: new HarmonyMethod(typeof(AnimalTab), nameof(PreDoCell)), postfix: new HarmonyMethod(typeof(AnimalTab), nameof(StopWatch))); type = compHandlerSettingsType = AccessTools.TypeByName("AnimalTab.CompHandlerSettings"); modeField = MP.RegisterSyncField(type, "_mode"); levelField = MP.RegisterSyncField(type, "_level"); }
public CashRegister(ModContentPack mod) { var type = AccessTools.TypeByName("CashRegister.Shifts.ITab_Register_Shifts"); MpCompat.RegisterLambdaMethod(type, "GetGizmos", 1).SetContext(SyncContext.MapSelected); MP.RegisterSyncWorker <object>(NoSync, type, shouldConstruct: true); MP.RegisterSyncMethod(typeof(CashRegister), nameof(SyncedSetShifts)).ExposeParameter(1).ExposeParameter(2).ExposeParameter(3).ExposeParameter(4).ExposeParameter(5).MinTime(100); MpCompat.harmony.Patch(AccessTools.Method(type, "FillTab"), prefix: new HarmonyMethod(typeof(CashRegister), nameof(PreFillTab)), postfix: new HarmonyMethod(typeof(CashRegister), nameof(PostFillTab))); type = AccessTools.TypeByName("CashRegister.Gizmo_Radius"); gizmoRadiusConstructor = AccessTools.GetDeclaredConstructors(type).First(x => x.GetParameters().Length == 1); gizmoSelectionField = AccessTools.FieldRefAccess <Building[]>(type, "selection"); MP.RegisterSyncMethod(AccessTools.DeclaredMethod(type, "ButtonDown")); MP.RegisterSyncMethod(AccessTools.DeclaredMethod(type, "ButtonUp")); MP.RegisterSyncMethod(AccessTools.DeclaredMethod(type, "ButtonCenter")); MP.RegisterSyncWorker <Gizmo>(SyncGizmoRadius, type); type = AccessTools.TypeByName("CashRegister.Building_CashRegister"); cashRegisterType = type.MakeArrayType(); shiftsListField = AccessTools.FieldRefAccess <IList>(type, "shifts"); type = AccessTools.TypeByName("CashRegister.Shifts.Shift"); shiftConstructor = AccessTools.Constructor(type); timetableField = AccessTools.FieldRefAccess <object>(type, "timetable"); assignedField = AccessTools.FieldRefAccess <List <Pawn> >(type, "assigned"); type = AccessTools.TypeByName("CashRegister.Timetable.TimetableBool"); timesField = AccessTools.FieldRefAccess <List <bool> >(type, "times"); }
public VanillaPlantsMorePlants(ModContentPack mod) { PatchingUtilities.PatchSystemRand("VanillaPlantsExpandedMorePlants.Plant_SowsAdjacent:SpawnSetup", false); PatchingUtilities.PatchSystemRand("VanillaPlantsExpandedMorePlants.Plant_TransformOnMaturity:TickLong", false); MpCompat.RegisterLambdaMethod("VanillaPlantsExpandedMorePlants.Zone_GrowingAquatic", "GetGizmos", 1, 3); MpCompat.RegisterLambdaMethod("VanillaPlantsExpandedMorePlants.Zone_GrowingSandy", "GetGizmos", 1, 3); }
public AnimaObelisk(ModContentPack mod) { var type = AccessTools.TypeByName("PsyObelisk.Things.ThingComp_PsyObelisk"); PatchingUtilities.PatchUnityRand(AccessTools.Method(type, "GlowAround"), false); var syncMethods = MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", Enumerable.Range(0, 8).ToArray()); // 0 to 7 syncMethods.Skip(2).SetDebugOnly(); }
public VanillaIdeologyDryads(ModContentPack mod) { // RNG PatchingUtilities.PatchSystemRandCtor("VanillaIdeologyExpanded_Dryads.HediffComp_PeriodicWounds"); // Gizmos MP.RegisterSyncMethod(AccessTools.TypeByName("VanillaIdeologyExpanded_Dryads.CompPawnMerge"), "SetDryadAwakenPod"); MpCompat.RegisterLambdaMethod("VanillaIdeologyExpanded_Dryads.CompSpawnAwakened", "CompGetGizmosExtra", 0).SetDebugOnly(); }
public static void LatePatch() { var type = AccessTools.TypeByName("EccentricPower.CompFusionCapacitor"); MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 0, 1, 2).SetDebugOnly(); type = AccessTools.TypeByName("EccentricPower.CompFusionStorage"); MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 1, 3, 4, 5, 6).Skip(2).SetDebugOnly(); }
public Windows(ModContentPack mod) { var type = AccessTools.TypeByName("OpenTheWindows.Building_Window"); MpCompat.RegisterLambdaMethod(type, "GetGizmos", 1, 3); type = AccessTools.TypeByName("OpenTheWindows.CompWindow"); MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 1); }
public AvoidFriendlyFire(ModContentPack mod) { { var type = AccessTools.TypeByName("AvoidFriendlyFire.ExtendedPawnData"); MP.RegisterSyncWorker <object>(SyncWorkerFor, type); } { MpCompat.RegisterLambdaDelegate("AvoidFriendlyFire.Pawn_DraftController_GetGizmos_Patch", "Postfix", 1); } }
public ChoiceOfPsycastsCompat(ModContentPack mod) { var type = learnPsycastsType = AccessTools.TypeByName("RimWorld.ChoiceOfPsycasts.LearnPsycasts"); MpCompat.RegisterLambdaDelegate(type, "Choice", 1); MpCompat.RegisterLambdaDelegate(type, "ChoiceCustom", 1); levelField = AccessTools.FieldRefAccess<int>(type, "Level"); parentField = AccessTools.FieldRefAccess<Pawn>(type, "Parent"); MP.RegisterSyncWorker<Command_Action>(SyncLearnPsycasts, type); }
public VanillaGeneticsExpanded(ModContentPack mod) { // Sync worker { var type = AccessTools.TypeByName("GeneticRim.Command_SetGenomeList"); setGenomeListMap = AccessTools.FieldRefAccess <Map>(type, "map"); setGenomeListBuilding = AccessTools.FieldRefAccess <Building>(type, "building"); MP.RegisterSyncWorker <Command>(SyncCommand, type, shouldConstruct: true); } // RNG { var constructors = new[] { "GeneticRim.CompExploder", "GeneticRim.HediffComp_PeriodicWounds", }; PatchingUtilities.PatchSystemRandCtor(constructors, false); } // Gizmos { // Archocentipide former - start and (dev) finish gizmos MpCompat.RegisterLambdaMethod("GeneticRim.Building_ArchocentipedeFormer", "GetGizmos", 0, 1)[1].SetDebugOnly(); // Archowomb - awaken confirmation and (dev) finish gizmo MpCompat.RegisterLambdaMethod("GeneticRim.Building_ArchoWomb", "GetGizmos", 1, 2)[1].SetDebugOnly(); // Mechahybridizer - (dev) finish gizmo MpCompat.RegisterLambdaMethod("GeneticRim.Building_Mechahybridizer", "GetGizmos", 0).SetDebugOnly(); // Age related disease dev gizmo MpCompat.RegisterLambdaMethod("GeneticRim.CompApplyAgeDiseases", "GetGizmos", 0).SetDebugOnly(); // DNA storage bank and mechahybridizer gizmos var type = AccessTools.TypeByName("GeneticRim.ArchotechExtractableAnimals_MapComponent"); MP.RegisterSyncMethod(type, "AddAnimalToCarry"); MP.RegisterSyncMethod(type, "AddParagonToCarry"); // DNA storage bank gizmo MpCompat.RegisterLambdaDelegate("GeneticRim.Command_SetGenomeList", "ProcessInput", 2); } // Float menu { MpCompat.RegisterLambdaDelegate("GeneticRim.CompArchotechGrowthCell", "CompFloatMenuOptions", 0); } LongEventHandler.ExecuteWhenFinished(LatePatch); }
public VanillaFactionsVikings(ModContentPack mod) { LongEventHandler.ExecuteWhenFinished(LatePatch); // Debug stuff var type = AccessTools.TypeByName("VFEV.Apiary"); MpCompat.RegisterSyncMethodsByIndex(type, "<GetGizmos>", 0, 1).Do(m => m.SetDebugOnly()); // This method seems unused... But I guess it's better to be safe than sorry. PatchingUtilities.PatchSystemRand(AccessTools.Method(type, "ResetTend"), false); }
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); }
public RimFridgeCompat(ModContentPack mod) { // Several Gizmos { MpCompat.RegisterLambdaDelegate("RimFridge.CompRefrigerator", "CompGetGizmosExtra", 1, 2, 3, 4, 5); MpCompat.RegisterLambdaMethod("RimFridge.CompToggleGlower", "CompGetGizmosExtra", 0); dialogType = AccessTools.TypeByName("RimFridge.Dialog_RenameFridge"); fridgeField = AccessTools.Field(dialogType, "fridge"); MP.RegisterSyncWorker <Dialog_Rename>(SyncFridgeName, dialogType); MP.RegisterSyncMethod(dialogType, "SetName"); } }
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 RimsentialSpaceports(ModContentPack mod) { // Gizmos { var type = AccessTools.TypeByName("Spaceports.Buildings.Building_Beacon"); MpCompat.RegisterLambdaMethod(type, "GetGizmos", 1, 2, 3); MP.RegisterSyncMethod(type, "ConfirmAction"); type = AccessTools.TypeByName("Spaceports.Buildings.Building_Shuttle"); MpCompat.RegisterLambdaMethod(type, "GetGizmos", 0, 1); type = AccessTools.TypeByName("Spaceports.Buildings.Building_ShuttlePad"); MP.RegisterSyncMethod(type, "SetAccessState"); type = AccessTools.TypeByName("Spaceports.Buildings.Building_ShuttleSpot"); MP.RegisterSyncMethod(type, "SetAccessState"); } // Choice letters { 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("Spaceports.Letters.PrisonerTransferLetter"); var methods = MpMethodUtil.GetLambda(type, "Choices", MethodType.Getter, null, 0, 1, 2).ToArray(); MP.RegisterSyncMethod(methods[0]); MP.RegisterSyncMethod(methods[1]); MP.RegisterSyncMethod(methods[2]); rejectMethods[type] = methods[2]; var typeNames = new[] { "Spaceports.Letters.InterstellarDerelictLetter", "Spaceports.Letters.MedevacLetter", "Spaceports.Letters.MysteryCargoLetter", "Spaceports.Letters.SpicyPawnLendingLetter", }; 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]; } } }
public SmartFarming(ModContentPack mod) { var type = AccessTools.TypeByName("SmartFarming.Mod_SmartFarming"); compCache = AccessTools.StaticFieldRefAccess <IDictionary>(type, "compCache"); type = AccessTools.TypeByName("SmartFarming.MapComponent_SmartFarming"); growZoneRegistryField = AccessTools.FieldRefAccess <IDictionary>(type, "growZoneRegistry"); type = AccessTools.TypeByName("SmartFarming.ZoneData"); MpCompat.RegisterLambdaDelegate(type, "Init", 3, 4).SetContext(SyncContext.CurrentMap); // Toggle no petty jobs, force harvest now MP.RegisterSyncMethod(type, "SwitchSowMode"); // Called from two places MP.RegisterSyncMethod(type, "SwitchPriority"); // Called from two places MP.RegisterSyncWorker <object>(SyncZoneData, type); }
public static void LatePatch() { var type = AccessTools.TypeByName("VFEMech.MissileSilo"); MP.RegisterSyncMethod(type, "StartFire"); MP.RegisterSyncMethod(type, "ConfigureNewTarget"); foreach (var method in MpCompat.RegisterSyncMethodsByIndex(type, "<GetGizmos>", 2, 3)) { method.SetDebugOnly(); } type = AccessTools.TypeByName("VFE.Mechanoids.Buildings.Building_AutoPlant"); // Methods b__8_0, b__8_2, b__8_3. They are the first 3 methods in the file. The b__8_1 is the last one, and thus has index 3. MpCompat.RegisterSyncMethodsByIndex(type, "<GetGizmos>", 0, 1, 2); }
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 static void LatePatch() { // Gizmos { // DNA storage bank - (dev) fill gizmo MpCompat.RegisterLambdaMethod("GeneticRim.Building_DNAStorageBank", "GetGizmos", 1).SetDebugOnly(); // Genomorpher gizmos/windows // Dev finish and reset all gizmos MpCompat.RegisterLambdaMethod("GeneticRim.CompGenomorpher", "CompGetGizmosExtra", 1, 2).SetDebugOnly(); // Accept hybrid options from the window (opened only for one player) MP.RegisterSyncMethod(AccessTools.DeclaredMethod("GeneticRim.CompGenomorpher:Initialize")); // Electrowomb dev mode gizmo MpCompat.RegisterLambdaMethod("GeneticRim.CompElectroWomb", "CompGetGizmosExtra", 0).SetDebugOnly(); } }
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 VanillaFishingExpanded(ModContentPack mod) { // RNG fix { PatchingUtilities.PatchSystemRandCtor("VCE_Fishing.JobDriver_Fish", false); PatchingUtilities.PatchPushPopRand("VCE_Fishing.JobDriver_Fish:SelectFishToCatch"); } // Gizmo (select fish size to catch) { commandType = AccessTools.TypeByName("VCE_Fishing.Command_SetFishList"); mapField = AccessTools.Field(commandType, "map"); fishingZoneField = AccessTools.Field(commandType, "zone"); MpCompat.RegisterSyncMethodsByIndex(commandType, "<ProcessInput>", Enumerable.Range(0, 3).ToArray()); MP.RegisterSyncWorker <Command>(SyncFishingZoneChange, commandType, shouldConstruct: false); } }
public VanillaFactionsVikings(ModContentPack mod) { LongEventHandler.ExecuteWhenFinished(LatePatch); // Debug commands, other stuff var type = AccessTools.TypeByName("VFEV.Building_MeadBarrel"); MpCompat.RegisterSyncMethodByIndex(type, "<GetGizmos>", 0).SetDebugOnly(); type = AccessTools.TypeByName("VFEV.Apiary"); foreach (var gizmo in MpCompat.RegisterSyncMethodsByIndex(type, "<GetGizmos>", 0, 1)) { gizmo.SetDebugOnly(); } // This method seems unused... But I guess it's better to be safe than sorry. PatchingUtilities.PatchSystemRand(AccessTools.Method(type, "ResetTend"), false); }
public VFEF(ModContentPack mod) { //RNG Fix { var methods = new[] { "VFEF.MoteSprinkler:NewMote", "VFEF.MoteSprinkler:ThrowWaterSpray", }; PatchingUtilities.PatchPushPopRand(methods); } // Gizmo fix { // Toggle should scarecrow affect tamed/player animals MpCompat.RegisterLambdaMethod("VFEF.Building_Scarecrow", "GetGizmos", 1); } }
public AlphaBiomes(ModContentPack mod) { var type = AccessTools.TypeByName("AlphaBiomes.Command_SetStoneType"); buildingField = AccessTools.FieldRefAccess <Building>(type, "building"); // SyncWorker needed as the <ProcessInput> methods require syncing of the `building` field MP.RegisterSyncWorker <Command>(SyncSetStoneType, type, shouldConstruct: true); MpCompat.RegisterLambdaMethod(type, "ProcessInput", Enumerable.Range(0, 6).ToArray()); var rngFixMethods = new[] { "AlphaBiomes.CompGasProducer:CompTick", "AlphaBiomes.TarSprayer:SteamSprayerTick", "AlphaBiomes.GameCondition_AcidRain:DoCellSteadyEffects", }; PatchingUtilities.PatchSystemRand(AccessTools.Constructor(AccessTools.TypeByName("AlphaBiomes.CompGasProducer")), false); PatchingUtilities.PatchPushPopRand(rngFixMethods); }
public Pharmacist(ModContentPack mod) { var type = AccessTools.TypeByName("Pharmacist.PharmacistSettings"); var outer = type; setDefaultsMethod = AccessTools.MethodDelegate <SetDefaults>(AccessTools.Method(type, "SetDefaults")); medicalCareField = AccessTools.StaticFieldRefAccess <object>(AccessTools.Field(type, "medicalCare")); type = AccessTools.Inner(outer, "MedicalCare"); diseaseMarginField = MP.RegisterSyncField(type, "_diseaseMargin"); minorWoundsThresholdField = MP.RegisterSyncField(type, "_minorWoundsThreshold"); diseaseThresholdField = MP.RegisterSyncField(type, "_diseaseThreshold"); MP.RegisterSyncWorker <object>(SyncMedicalCare, type); type = AccessTools.TypeByName("Pharmacist.MainTabWindow_Pharmacist"); MpCompat.RegisterLambdaDelegate(type, "DrawCareSelectors", 0, 1, 2); MpCompat.harmony.Patch(AccessTools.Method(type, "DrawOptions"), prefix: new HarmonyMethod(typeof(Pharmacist), nameof(PreDrawOptions)), postfix: new HarmonyMethod(typeof(Pharmacist), nameof(PostDrawOptions))); }
public MoreArchotechGarbage(ModContentPack mod) { // RNG Fix { var rngTypes = new[] { "RimWorld.CompSpawnerH", "RimWorld.CompSpawnerResearch", "RimWorld.CompSpawnerResearchMK2", "RimWorld.JoinOrRaidTameOrManhunter", "RimWorld.MechhSummon", "RimWorld.MechhSummonNoRoyalty", }; foreach (var type in rngTypes) { PatchingUtilities.PatchSystemRand($"{type}:RandomNumber"); } } // Gizmo Fix { // Mech cluster (0), raid (2), ship part (4) var type = AccessTools.TypeByName("RimWorld.MechhSummon"); MpCompat.RegisterLambdaDelegate(type, "GetGizmos", Array.Empty <string>(), 0, 2); MpCompat.RegisterLambdaMethod(type, "GetGizmos", 4); // Raid (0), ship part (2) type = AccessTools.TypeByName("RimWorld.MechhSummonNoRoyalty"); MpCompat.RegisterLambdaDelegate(type, "GetGizmos", Array.Empty <string>(), 0); MpCompat.RegisterLambdaMethod(type, "GetGizmos", 2); // Summon meteorite MpCompat.RegisterLambdaDelegate("RimWorld.PodSummoner", "GetGizmos", Array.Empty <string>(), 0); // Dev mode gizmos MpCompat.RegisterLambdaMethod("RimWorld.CompSpawnerH", "CompGetGizmosExtra", 0).SetDebugOnly(); MpCompat.RegisterLambdaMethod("RimWorld.CompSpawnerResearch", "CompGetGizmosExtra", 0).SetDebugOnly(); MpCompat.RegisterLambdaMethod("RimWorld.CompSpawnerResearchMK2", "CompGetGizmosExtra", 0).SetDebugOnly(); } }
public QualityBuilder(ModContentPack mod) { Type builderCompType = AccessTools.TypeByName("QualityBuilder.CompQualityBuilder"); Type toggleCommandType = AccessTools.TypeByName("QualityBuilder.CompQualityBuilder+ToggleCommand+<>c"); Type designatorType = AccessTools.TypeByName("QualityBuilder._Designator_SkilledBuilder+<>c"); Type[] argTypes = { typeof(QualityCategory) }; MethodInfo toggleCommandMethod = MpCompat.GetFirstMethodBySignature(toggleCommandType, argTypes); MethodInfo designatorMethod = MpCompat.GetFirstMethodBySignature(designatorType, argTypes); //my decompiler shows the method name is <get_RightClickFloatMenuOptions>b__3_0 //while harmony saids it is <get_RightClickFloatMenuOptions>b__2_0, weird..." MP.RegisterSyncWorker <object>(SyncTypes, toggleCommandType); MP.RegisterSyncWorker <object>(SyncTypes, designatorType); MP.RegisterSyncMethod(builderCompType, "ToggleSkilled"); MP.RegisterSyncMethod(toggleCommandMethod).SetContext(SyncContext.MapSelected); MP.RegisterSyncMethod(designatorMethod); }