public static IEnumerable <ISyncMethod> RegisterSyncMethodsByIndex(Type type, string prefix, params int[] index) { foreach (var method in MethodsByIndex(type, prefix, index)) { yield return(MP.RegisterSyncMethod(method)); } }
public void LatePatch() { // Facepaint changeFacepaintDialogType = AccessTools.TypeByName("VFEV.Facepaint.Dialog_ChangeFacepaint"); //setFacepaintMethod = AccessTools.Method(changeFacepaintDialogType, "SetHairstyle"); orderedFacepaintDefsField = AccessTools.Field(changeFacepaintDialogType, "orderedFacepaintDefs"); newFacepaintComboSync = MP.RegisterSyncField(AccessTools.Field(changeFacepaintDialogType, "newFacepaintCombo")); coloursTiedSync = MP.RegisterSyncField(AccessTools.Field(changeFacepaintDialogType, "coloursTied")); MP.RegisterSyncMethod(changeFacepaintDialogType, "SetHairstyle"); MP.RegisterSyncWorker <Window>(SyncDialog, changeFacepaintDialogType); MP.RegisterSyncMethod(typeof(VanillaFactionsVikings), nameof(SyncedTryRemoveWindow)); MpCompat.harmony.Patch(AccessTools.Method(changeFacepaintDialogType, "DoWindowContents"), prefix: new HarmonyMethod(typeof(VanillaFactionsVikings), nameof(PreDoWindowContents)), postfix: new HarmonyMethod(typeof(VanillaFactionsVikings), nameof(PostDoWindowContents))); var type = AccessTools.Inner(changeFacepaintDialogType, "FacepaintCombination"); MP.RegisterSyncWorker <object>(SyncFacepaintCombination, type); facepaintDefOneField = AccessTools.Field(type, "facepaintDefOne"); facepaintDefTwoField = AccessTools.Field(type, "facepaintDefTwo"); facepaintColourOneField = AccessTools.Field(type, "colourOne"); facepaintColourTwoField = AccessTools.Field(type, "colourTwo"); MpCompat.harmony.Patch(AccessTools.Method(typeof(WindowStack), nameof(WindowStack.TryRemove), new[] { typeof(Window), typeof(bool) }), prefix: new HarmonyMethod(typeof(VanillaFactionsVikings), nameof(PreTryRemoveWindow))); }
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))); }
// Token: 0x060000A5 RID: 165 RVA: 0x00005CCC File Offset: 0x00003ECC static MultiplayerSupport() { if (!MP.enabled) { return; } MP.RegisterSyncMethod(typeof(GhostGearApparel), "GGCaltropsUse"); MP.RegisterSyncMethod(typeof(GhostGearApparel), "GGRepulse"); MP.RegisterSyncMethod(typeof(GhostGearApparel), "UseGrappleHook"); MethodInfo[] array = { AccessTools.Method(typeof(HaywireData), "TrySetHaywireTicks"), AccessTools.Method(typeof(HaywireUtility), "Rnd100"), AccessTools.Method(typeof(HaywireUtility), "RndTicks"), AccessTools.Method(typeof(HaywireUtility), "RndHWWanderRadius"), AccessTools.Method(typeof(HaywireUtility), "GetRandomThing"), AccessTools.Method(typeof(HaywireEffect), "RndDmg"), AccessTools.Method(typeof(HaywireEffect), "GetCandidate"), AccessTools.Method(typeof(GHInjury), "DoGHRelatedInjury"), AccessTools.Method(typeof(GHInjury), "SetUpInjVars") }; foreach (var methodInfo in array) { FixRNG(methodInfo); } }
public PerspectiveBuildings(ModContentPack mod) { var type = AccessTools.TypeByName("Perspective.CompOffsetter"); MP.RegisterSyncMethod(type, "SetCurrentOffset"); MP.RegisterSyncMethod(type, "SetMirroredState"); }
public VanillaStorytellersWinstonWaves(ModContentPack mod) { // RNG { PatchingUtilities.PatchSystemRandCtor("VSEWW.Window_ChooseReward", false); } // Dialogs { var type = chooseRewardDialogType = AccessTools.TypeByName("VSEWW.Window_ChooseReward"); choosenRewardField = AccessTools.FieldRefAccess <Def>(type, "choosenReward"); type = AccessTools.TypeByName("VSEWW.RewardDef"); MpCompat.harmony.Patch(AccessTools.Method(type, "DrawCard"), transpiler: new HarmonyMethod(typeof(VanillaStorytellersWinstonWaves), nameof(ReplaceButton))); MP.RegisterSyncMethod(typeof(VanillaStorytellersWinstonWaves), nameof(SyncedChooseReward)); // The window is always visible and its default position covers MP chat button // This patch will move it under the button (if MP is on), // especially considering that it'll move up on autosave/joinstate creation type = AccessTools.TypeByName("VSEWW.Window_WaveCounter"); MpCompat.harmony.Patch(AccessTools.Method(type, "SetInitialSizeAndPosition"), postfix: new HarmonyMethod(typeof(VanillaStorytellersWinstonWaves), nameof(PostSetInitialSizeAndPosition))); MP.RegisterPauseLock(PauseIfDialogOpen); } LongEventHandler.ExecuteWhenFinished(LatePatch); }
public VanillaIdeologyMemes(ModContentPack mod) { // RNG { var methods = new[] { // Commented out the ones that use seeded random, as they should be fine // If not, then uncommenting those lines should fix it "VanillaMemesExpanded.CompAbilityHarvestBodyParts:Apply", //"VanillaMemesExpanded.VanillaMemesExpanded_GameConditionManager_RegisterCondition_Patch:SendRandomMood", //"VanillaMemesExpanded.VanillaMemesExpanded_GameCondition_Aurora_Init_Patch:SendRandomMood", //"VanillaMemesExpanded.RitualOutcomeEffectWorker_DivineStars:Apply", "VanillaMemesExpanded.RitualOutcomeEffectWorker_SlaveEmancipation:Apply", "VanillaMemesExpanded.RitualOutcomeEffectWorker_ViolentConversion:Apply", }; PatchingUtilities.PatchSystemRand(methods, false); } // Gizmos { var type = AccessTools.TypeByName("VanillaMemesExpanded.CompDeconstructJunk"); MP.RegisterSyncMethod(type, "SetObjectForDeconstruction"); MP.RegisterSyncMethod(type, "CancelObjectForDeconstruction"); } }
public CleaningArea(ModContentPack mod) { Type type = CleaningAreaMapComponentType = AccessTools.TypeByName("CleaningArea.CleaningArea_MapComponent"); MP.RegisterSyncMethod(AccessTools.PropertySetter(type, "cleaningArea")); MP.RegisterSyncWorker <MapComponent>(SyncWorkerForCleaningArea, type); }
// Token: 0x06000074 RID: 116 RVA: 0x0000552C File Offset: 0x0000372C static MultiplayerSupport() { if (!MP.enabled) { return; } MP.RegisterSyncMethod(typeof(JetPackApparel), "UseJetPack", null); MP.RegisterSyncMethod(typeof(JetPackApparel), "ToggleSlowBurn", null); MP.RegisterSyncMethod(typeof(JetPackApparel), "RefuelJP", null); MP.RegisterSyncMethod(typeof(JetPackApparel), "DropFuelJP", null); MP.RegisterSyncMethod(typeof(JetPackApparel), "ChangeFuelJP", null); MP.RegisterSyncMethod(typeof(JetPackApparel), "DebugUseJP", null); MethodInfo[] array = new MethodInfo[] { AccessTools.Method(typeof(JPInjury), "CheckForExplosion", null, null), AccessTools.Method(typeof(JPInjury), "DoJPRelatedInjury", null, null), AccessTools.Method(typeof(JPInjury), "SetUpInjVars", null, null), AccessTools.Method(typeof(JPSkyFaller), "JPImpact", null, null), AccessTools.Method(typeof(JPSkyFaller), "JPIgnite", null, null) }; for (int i = 0; i < array.Length; i++) { MultiplayerSupport.FixRNG(array[i]); } }
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"); }
// Token: 0x06000029 RID: 41 RVA: 0x00002F24 File Offset: 0x00001124 static MultiplayerSupport() { if (MP.enabled) { MP.RegisterSyncMethod(typeof(FireFoamBelt), "DoFFoam"); } }
public VanillaAchievements(ModContentPack mod) { var type = AccessTools.TypeByName("AchievementsExpanded.AchievementReward"); purchaseRewardMethod = AccessTools.Method(type, "PurchaseReward"); refundPointsMethod = AccessTools.Method(type, "RefundPoints"); tryExecuteEventMethod = AccessTools.Method(type, "TryExecuteEvent"); rewardDatabase = AccessTools.PropertyGetter(typeof(DefDatabase <>).MakeGenericType(type), "AllDefsListForReading"); windowType = AccessTools.TypeByName("AchievementsExpanded.MainTabWindow_Achievements"); var methods = new[] { AccessTools.Method(windowType, "DrawSidePanel"), AccessTools.DeclaredMethod(AccessTools.TypeByName("AchievementsExpanded.TraderTracker"), "Trigger"), }; foreach (var method in methods) { MpCompat.harmony.Patch(method, transpiler: new HarmonyMethod(typeof(VanillaAchievements), nameof(Transpiler))); } // Sync our method MP.RegisterSyncMethod(typeof(VanillaAchievements), nameof(SyncedCalls)); }
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 CorruptionCore(ModContentPack mod) { // ITab_Pawn_Soul - checkboxes to allow praying and show prayers var type = AccessTools.TypeByName("Corruption.Core.Soul.ITab_Pawn_Soul"); pawnSoulITabSoulToShowGetter = AccessTools.PropertyGetter(type, "SoulToShow"); MP.RegisterSyncMethod(typeof(CorruptionCore), nameof(SyncFavourValue)); MpCompat.harmony.Patch(AccessTools.Method(type, "FillTab"), prefix: new HarmonyMethod(typeof(CorruptionCore), nameof(PreFillTab)), postfix: new HarmonyMethod(typeof(CorruptionCore), nameof(PostFillTab))); type = AccessTools.TypeByName("Corruption.Core.Soul.CompSoul"); compSoulFavourTrackerField = AccessTools.Field(type, "FavourTracker"); compSoulAllowPrayingSync = MP.RegisterSyncField(type, "PrayerTracker/AllowPraying"); compSoulShowPrayerSync = MP.RegisterSyncField(type, "PrayerTracker/ShowPrayer"); setPawnPantheonDialogType = AccessTools.TypeByName("Corruption.Core.Dialog_SetPawnPantheon"); setPawnPantheonDialogSoulField = AccessTools.Field(setPawnPantheonDialogType, "soul"); MP.RegisterSyncMethod(setPawnPantheonDialogType, "SelectionChanged"); MP.RegisterSyncWorker <object>(SyncDialogSetPawnPantheon, setPawnPantheonDialogType); type = AccessTools.TypeByName("Corruption.Core.Soul.Soul_FavourTracker"); soulFavourTrackerFavoursField = AccessTools.Field(type, "Favours"); type = AccessTools.TypeByName("Corruption.Core.Soul.FavourProgress"); favourProgressFavourValueField = AccessTools.Field(type, "favourValue"); }
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"); } }
static MultiplayerCompatibility() { if (!MP.enabled) { return; } // Sync all gizmo clicks MP.RegisterSyncMethod(typeof(Command_Process), nameof(Command_Process.ChangeProcess)).SetContext(SyncContext.MapSelected); MP.RegisterSyncMethod(typeof(Command_Quality), nameof(Command_Quality.ChangeQuality)).SetContext(SyncContext.MapSelected); var methods = new[] { nameof(UF_Utility.FinishProcess), nameof(UF_Utility.ProgressOneDay), nameof(UF_Utility.ProgressHalfQuadrum), nameof(UF_Utility.EmptyObject), nameof(UF_Utility.FillObject), nameof(UF_Utility.LogSpeedFactors), }; foreach (string methodName in methods) { MP.RegisterSyncMethod(typeof(UF_Utility), methodName); } MP.RegisterSyncWorker <UF_Process>(UF_Process_SyncWorker, shouldConstruct: false); }
public WorkTab(ModContentPack mod) { // Changing priorities var type = AccessTools.TypeByName("WorkTab.PriorityManager"); MP.RegisterSyncMethod(AccessTools.PropertySetter(type, "ShowPriorities")); type = AccessTools.TypeByName("WorkTab.Pawn_Extensions"); MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", new[] { typeof(Pawn), typeof(WorkTypeDef), typeof(int), typeof(List <int>) })); MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", new[] { typeof(Pawn), typeof(WorkTypeDef), typeof(int), typeof(int), typeof(bool) })); MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", new[] { typeof(Pawn), typeof(WorkGiverDef), typeof(int), typeof(List <int>) })); MP.RegisterSyncMethod(AccessTools.Method(type, "SetPriority", new[] { typeof(Pawn), typeof(WorkGiverDef), typeof(int), typeof(int), typeof(bool) })); // This one not needed as it calls SetPriority, but it'll // end up calling it numerous times - let's just do it in one command. MP.RegisterSyncMethod(type, "DisableAll"); // Technically we don't have to do this, as pasting calls SetPriority... // But well, it ends up being called almost 2000 times in vanilla with DLCs alone... // So I felt like it'll be smarter to sync it as a single command instead of potentially // couple thousand with mods. type = AccessTools.TypeByName("WorkTab.PawnColumnWorker_CopyPasteDetailedWorkPriorities"); copyPasteColumnWorkerConstructor = AccessTools.DeclaredConstructor(type); clipboardField = AccessTools.StaticFieldRefAccess <Dictionary <WorkGiverDef, int[]> >(AccessTools.Field(type, "clipboard")); var method = AccessTools.Method(type, "PasteTo"); pasteToMethod = AccessTools.MethodDelegate <PasteTo>(method); MpCompat.harmony.Patch(method, prefix: new HarmonyMethod(typeof(WorkTab), nameof(PrePasteTo))); MP.RegisterSyncMethod(typeof(WorkTab), nameof(SyncedPasteTo)); // We don't really need to sync those, but not doing so will end up with // a bunch of unnecessary synced calls (one per colonists) // Sadly, there isn't a call like that in case of checkbox priorities - only numeric ones var types = new (string typeName, Type parameterType)[]
// Token: 0x06000050 RID: 80 RVA: 0x000038C0 File Offset: 0x00001AC0 static MultiplayerSupport() { if (!MP.enabled) { return; } MP.RegisterSyncMethod(typeof(RPGraphene_Vent), "ToggleUseFixed"); MP.RegisterSyncMethod(typeof(Building_TempRegulator), "ToggleUseBoost"); MP.RegisterSyncMethod(typeof(Building_RPThingMaker), "RPMakerSelectThing"); MP.RegisterSyncMethod(typeof(Building_RPThingMaker), "SetProdControlValues"); MP.RegisterSyncMethod(typeof(Building_RPThingMaker), "ToggleProducing"); MP.RegisterSyncMethod(typeof(Building_RPThingMaker), "RPMakerSelectLimit"); MP.RegisterSyncMethod(typeof(Building_RPThingMaker), "SetStockLimits"); MP.RegisterSyncMethod(typeof(Building_RPThingMaker), "ToggleDebug"); MethodInfo[] array = { AccessTools.Method(typeof(Building_RPGrapheneBatterySmall), "Tick"), AccessTools.Method(typeof(Building_RPGrapheneBatterySmall), "PostApplyDamage"), AccessTools.Method(typeof(Globals), "DoSecSpecialEffects") }; foreach (var methodInfo in array) { FixRNG(methodInfo); } }
static ExtendedOutfitProxy() { if (!MP.enabled) { return; } ProxyFields = new ISyncField[] { MP.RegisterSyncField(typeof(ExtendedOutfitProxy), nameof(targetWeight)) .SetBufferChanges().PostApply(Update) }; ExtendedOutfitFields = new ISyncField[] { MP.RegisterSyncField(typeof(ExtendedOutfit), nameof(ExtendedOutfit.targetTemperaturesOverride)), MP.RegisterSyncField(typeof(ExtendedOutfit), nameof(ExtendedOutfit.targetTemperatures)), MP.RegisterSyncField(typeof(ExtendedOutfit), nameof(ExtendedOutfit.PenaltyWornByCorpse)), MP.RegisterSyncField(typeof(ExtendedOutfit), nameof(ExtendedOutfit.AutoWorkPriorities)), }; MP.RegisterSyncMethod(typeof(ExtendedOutfit), nameof(ExtendedOutfit.AddStatPriority)); MP.RegisterSyncMethod(typeof(ExtendedOutfit), nameof(ExtendedOutfit.RemoveStatPriority)); MP.RegisterSyncMethod(typeof(ExtendedOutfitProxy), nameof(SetStat)); MP.RegisterSyncWorker <ExtendedOutfit>(ExtendedOutfitSyncer); }
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 static void Initialize() { try { if (!MP.enabled) { return; } const string expectedAPIVersion = "0.1"; if (!MP.API.Equals(expectedAPIVersion)) { throw new Exception($"MP API version mismatch. This mod is designed to work with MPAPI version {expectedAPIVersion}"); } // register synchronized methods MP.RegisterSyncMethod(typeof(DefensivePositionsManager), nameof(DefensivePositionsManager.ToggleAdvancedMode)); MP.RegisterSyncMethod(typeof(PawnSavedPositionHandler), nameof(PawnSavedPositionHandler.SetDefensivePosition)); MP.RegisterSyncMethod(typeof(PawnSavedPositionHandler), nameof(PawnSavedPositionHandler.DiscardSavedPosition)); MP.RegisterSyncMethod(typeof(PawnSquadHandler), nameof(PawnSquadHandler.SetSquadMembers)); MP.RegisterSyncMethod(typeof(PawnSquadHandler), nameof(PawnSquadHandler.ClearSquad)); // register instance resolvers MP.RegisterSyncWorker <DefensivePositionsManager>(ManagerSyncer, typeof(DefensivePositionsManager)); MP.RegisterSyncWorker <PawnSavedPositionHandler>(PawnHandlerSyncer, typeof(PawnSavedPositionHandler)); MP.RegisterSyncWorker <PawnSquadHandler>(SquadHandlerSyncer, typeof(PawnSquadHandler)); DefensivePositionsManager.Instance.Logger.Message("Applied Multiplayer API compatibility layer"); } catch (Exception e) { DefensivePositionsManager.Instance.Logger.Error("Failed to apply Multiplayer API compatibility layer: " + e); } }
static void LateLoad() { Type type = AccessTools.TypeByName("PocketSand.PawnExtensions"); MP.RegisterSyncMethod(type, "EquipFromInventory"); MP.RegisterSyncMethod(type, "DropFromInventory"); }
// Token: 0x06000074 RID: 116 RVA: 0x0000552C File Offset: 0x0000372C static MultiplayerSupport() { if (!MP.enabled) { return; } MP.RegisterSyncMethod(typeof(JetPackApparel), "UseJetPack"); MP.RegisterSyncMethod(typeof(JetPackApparel), "ToggleSlowBurn"); MP.RegisterSyncMethod(typeof(JetPackApparel), "RefuelJP"); MP.RegisterSyncMethod(typeof(JetPackApparel), "DropFuelJP"); MP.RegisterSyncMethod(typeof(JetPackApparel), "ChangeFuelJP"); MP.RegisterSyncMethod(typeof(JetPackApparel), "DebugUseJP"); MethodInfo[] array = { AccessTools.Method(typeof(JPInjury), "CheckForExplosion"), AccessTools.Method(typeof(JPInjury), "DoJPRelatedInjury"), AccessTools.Method(typeof(JPInjury), "SetUpInjVars"), AccessTools.Method(typeof(JPSkyFaller), "JPImpact"), AccessTools.Method(typeof(JPSkyFaller), "JPIgnite") }; foreach (var methodInfo in array) { FixRNG(methodInfo); } }
// Token: 0x060000CB RID: 203 RVA: 0x00009830 File Offset: 0x00007A30 static MultiplayerSupport() { if (!MP.enabled) { return; } MP.RegisterSyncMethod(typeof(Building_MSDrugMix), "MSMixerSelectChem", null); MP.RegisterSyncMethod(typeof(Building_MSDrugMix), "SetProdControlValues", null); MP.RegisterSyncMethod(typeof(Building_MSDrugMix), "ToggleProducing", null); MP.RegisterSyncMethod(typeof(Building_MSDrugMix), "MSMixerSelectLimit", null); MP.RegisterSyncMethod(typeof(Building_MSDrugMix), "SetStockLimits", null); MP.RegisterSyncMethod(typeof(Building_MSDrugMix), "ToggleDebug", null); MP.RegisterSyncMethod(typeof(MSStimWorn), "MSDoStimSelect", null); MP.RegisterSyncMethod(typeof(MSStimWorn), "MSUseStim", null); MethodInfo[] array = new MethodInfo[] { AccessTools.Method(typeof(MSBitsUtility), "GetBitsYield", null, null), AccessTools.Method(typeof(MSBitsUtility), "GetIsBitsSource", null, null), AccessTools.Method(typeof(MSExoticUtility), "DoMSTranscendence", null, null), AccessTools.Method(typeof(MSExoticUtility), "DoMSPerpetuity", null, null), AccessTools.Method(typeof(HediffComp_MSRegen), "ResetTicksToHeal", null, null), AccessTools.Method(typeof(HediffComp_MSRegen), "TryHealRandomOldWound", null, null), AccessTools.Method(typeof(MSHediffComp_TendDuration), "CompTended", null, null), AccessTools.Method(typeof(MSHediffComp_TendDuration), "CompPostTick", null, null), AccessTools.Method(typeof(MSCompFoodPoisonable), "PostIngested", null, null), AccessTools.Method(typeof(HediffComp_MSCure), "SetTicksToCure", null, null), AccessTools.Method(typeof(MSHediffComp_GrowthMode), "CompPostPostAdd", null, null), AccessTools.Method(typeof(MSHediffComp_GrowthMode), "CompPostTick", null, null), AccessTools.Method(typeof(MSHediffComp_GrowthMode), "MSAdjustment", null, null) }; for (int i = 0; i < array.Length; i++) { MultiplayerSupport.FixRNG(array[i]); } }
static void LateSyncMethods() { // Artillery fix { var type = AccessTools.TypeByName("VFESecurity.CompLongRangeArtillery"); selectedCompsProperty = AccessTools.Property(type, "SelectedComps"); turretProperty = AccessTools.Property(type, "Turret"); targetedTileField = AccessTools.Field(type, "targetedTile"); resetWarmupTicksMethod = AccessTools.DeclaredMethod(type, "ResetWarmupTicks"); MP.RegisterSyncMethod(type, "ResetForcedTarget"); MP.RegisterSyncMethod(typeof(VFESecurity), nameof(SetTargetedTile)); MpCompat.harmony.Patch(AccessTools.Method(type, "SetTargetedTile"), new HarmonyMethod(typeof(VFESecurity), nameof(Prefix))); } // RNG fix { var methods = new[] { // ArtilleryComp:TryResolveArtilleryCount is called by ArtilleryComp:CompTick "VFESecurity.ArtilleryComp:BombardmentTick", "VFESecurity.ArtilleryComp:TryStartBombardment", "VFESecurity.Building_Shield:Notify_EnergyDepleted", "VFESecurity.Building_Shield:Draw", "VFESecurity.CompLongRangeArtillery:CompTick", }; PatchingUtilities.PatchPushPopRand(AccessTools.Method("VFESecurity.Building_Shield:AbsorbDamage", new Type[] { typeof(float), typeof(DamageDef), typeof(float) })); PatchingUtilities.PatchPushPopRand(methods); } }
private static void LatePatch() { // Window_Psyker psykerWindowType = AccessTools.TypeByName("Corruption.Psykers.Window_Psyker"); psykerWindowCompField = AccessTools.Field(psykerWindowType, "comp"); MP.RegisterSyncMethod(typeof(CorruptionPsykers), nameof(SyncedAddMinorDiscipline)); MpCompat.harmony.Patch(AccessTools.Method(psykerWindowType, nameof(Window.DoWindowContents)), prefix: new HarmonyMethod(typeof(CorruptionPsykers), nameof(PrePsykerDoWindowContents)), postfix: new HarmonyMethod(typeof(CorruptionPsykers), nameof(PostPsykerDoWindowContents))); MP.RegisterSyncMethod(typeof(CorruptionPsykers), nameof(SyncedTryLearnPower)); var psykerLearnablePowerType = AccessTools.TypeByName("Corruption.Psykers.PsykerLearnablePower"); var type = AccessTools.TypeByName("Corruption.Psykers.CompPsyker"); compPsykerTryLearnPowerMethod = AccessTools.Method(type, "TryLearnPower", new Type[] { psykerLearnablePowerType }); compPsykerAddXpMethod = AccessTools.Method(type, "AddXP"); compPsykerMainDisciplineField = AccessTools.Field(type, "MainDiscipline"); compPsykerMinorDisciplinesField = AccessTools.Field(type, "minorDisciplines"); compPsykerXpSyncField = MP.RegisterSyncField(type, "PsykerXP"); type = AccessTools.TypeByName("Corruption.Psykers.PsykerDisciplineDef"); psykerDisciplineDefAbilitiesField = AccessTools.Field(type, "abilities"); var database = typeof(DefDatabase <>).MakeGenericType(new Type[] { type }); getDefByShortHash = AccessTools.Method(database, "GetByShortHash"); MpCompat.harmony.Patch(AccessTools.Method(psykerWindowType, "DrawSelectedPower"), transpiler: new HarmonyMethod(typeof(CorruptionPsykers), nameof(Transpiler))); }
static IEnumerable <ISyncMethod> RegisterLambdaMethod_Impl(Type parentType, string parentMethod, params int[] lambdaOrdinals) { foreach (int ord in lambdaOrdinals) { var method = MpMethodUtil.GetLambda(parentType, parentMethod, MethodType.Normal, null, ord); yield return(MP.RegisterSyncMethod(method)); } }
public LightsOut(ModContentPack mod) { commandType = AccessTools.TypeByName("LightsOut.Gizmos.KeepOnGizmo"); parentCompGetter = AccessTools.PropertyGetter(commandType, "ParentComp"); MP.RegisterSyncMethod(commandType, "ToggleAction"); MP.RegisterSyncWorker <Command_Toggle>(SyncToggleCommand, commandType); }
public RPGStyleInventory(ModContentPack mod) { Type type = AccessTools.TypeByName("Sandy_Detailed_RPG_Inventory.Sandy_Detailed_RPG_GearTab"); MP.RegisterSyncWorker <ITab_Pawn_Gear>(SyncITab, type); MP.RegisterSyncMethod(type, "InterfaceDrop").SetContext(SyncContext.MapSelected); MP.RegisterSyncMethod(type, "InterfaceIngest").SetContext(SyncContext.MapSelected); }
static Multiplayer() { if (!MP.enabled) { return; } MP.RegisterSyncMethod(typeof(Command_StorageSettingsPresets), nameof(Command_StorageSettingsPresets.CopyIntoFilterFromTemplate)); }