コード例 #1
0
        public VEE(ModContentPack mod)
        {
            var methodsForAll = new[]
            {
                "VEE.DummySpaceBattle:Tick",
                "VEE.HeddifComp_MightJoin:CompPostTick",
                "VEE.Shuttle:Tick",

                // These 4 methods initialize System.Random, but don't use them in any way whatsoever.
                //"VEE.PurpleEvents.GlobalWarming:ChangeBiomes",
                //"VEE.PurpleEvents.GlobalWarming:ChangeTileTemp",
                //"VEE.PurpleEvents.IceAge:ChangeBiomes",
                //"VEE.PurpleEvents.IceAge:ChangeTileTemp",
                "VEE.PurpleEvents.PsychicBloom:Init",

                "VEE.RegularEvents.ApparelPod:TryExecuteWorker",
                "VEE.RegularEvents.CaravanAnimalWI:GenerateGroup",
                "VEE.RegularEvents.Drought:HarmPlant",
                "VEE.RegularEvents.HuntingParty:TryExecuteWorker",
                "VEE.RegularEvents.MeteoriteShower:TryExecuteWorker",
                "VEE.RegularEvents.SpaceBattle:GameConditionTick", // This method was having issues with transpiling no matter what I did, skipping it until it can be fixed
                "VEE.RegularEvents.WeaponPod:TryExecuteWorker",
            };

            PatchingUtilities.PatchSystemRand(methodsForAll, false);
            // This method only calls other methods that use RNG calls
            PatchingUtilities.PatchPushPopRand("VEE.RegularEvents.EarthQuake:TryExecuteWorker");
            // Only patch System.Random out, as this methods is only called by other ones
            PatchingUtilities.PatchSystemRand("VEE.RegularEvents.EarthQuake:DamageInRadius", false);
        }
コード例 #2
0
        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");
            }
        }
コード例 #3
0
        public VEE(ModContentPack mod)
        {
            var methodsForAll = new[]
            {
                "VEE.HeddifComp_MightJoin:CompPostTick",

                "VEE.HuntingParty:TryExecuteWorker",

                // These 4 methods initialize System.Random, but don't use them in any way whatsoever.
                //"VEE.PurpleEvents.GlobalWarming:ChangeBiomes",
                //"VEE.PurpleEvents.GlobalWarming:ChangeTileTemp",
                //"VEE.PurpleEvents.IceAge:ChangeBiomes",
                //"VEE.PurpleEvents.IceAge:ChangeTileTemp",
                "VEE.PurpleEvents.PsychicBloom:Init",

                "VEE.RegularEvents.ApparelPod:TryExecuteWorker",
                "VEE.RegularEvents.CaravanAnimalWI:GenerateGroup",
                "VEE.RegularEvents.MeteoriteShower:TryExecuteWorker",
                "VEE.RegularEvents.WeaponPod:TryExecuteWorker",
            };

            PatchingUtilities.PatchSystemRand(methodsForAll, false);
            // This method only calls other methods that use RNG calls
            PatchingUtilities.PatchPushPopRand("VEE.RegularEvents.EarthQuake:TryExecuteWorker");
            // Only patch System.Random out, as this methods is only called by other ones
            PatchingUtilities.PatchSystemRand("VEE.RegularEvents.EarthQuake:DamageInRadius", false);

            // Unity RNG
            PatchingUtilities.PatchUnityRand("VEE.Shuttle:Tick");

            LongEventHandler.ExecuteWhenFinished(LatePatch);
        }
コード例 #4
0
        public AlphaBehavioursAndEvents(ModContentPack mod)
        {
            //RNG Fix
            {
                var rngFixConstructors = new[]
                {
                    "AlphaBehavioursAndEvents.CompAnimalProduct",
                    "AlphaBehavioursAndEvents.CompExploder",
                    "AlphaBehavioursAndEvents.CompGasProducer",
                    "AlphaBehavioursAndEvents.CompInitialHediff",
                    "AlphaBehavioursAndEvents.Gas_Ocular",
                    "AlphaBehavioursAndEvents.Hediff_Crushing",

                    //"NewAlphaAnimalSubproducts.CompAnimalProduct ", // System.Random initialized, but not used
                };

                PatchingUtilities.PatchSystemRandCtor(rngFixConstructors, false);

                var rngFixMethods = new[] //System.Random fixes
                {
                    "AlphaBehavioursAndEvents.CompGasProducer:CompTick",
                    "AlphaBehavioursAndEvents.CompAnimalProduct:InformGathered",
                    "AlphaBehavioursAndEvents.CompInitialHediff:CompTickRare",
                    "AlphaBehavioursAndEvents.Gas_Ocular:Tick",
                    "AlphaBehavioursAndEvents.Hediff_Crushing:RandomFilthGenerator",
                    "AlphaBehavioursAndEvents.CompExploder:wickInitializer",
                };
                PatchingUtilities.PatchPushPopRand(rngFixMethods);

                PatchingUtilities.PatchSystemRand("AlphaBehavioursAndEvents.DamageWorker_ExtraInfecter:ApplySpecialEffectsToPart");
            }
        }
コード例 #5
0
 public AlphaMemes(ModContentPack mod)
 {
     PatchingUtilities.PatchSystemRand("AlphaMemes.AlphaMemes_DamageWorker_AddInjury_Apply_Patch:SendHistoryIfMelee", false);
     // The following method is seeded, so it should be fine
     // If not, then patching it as well should fix it
     //"AlphaMemes.GameComponent_RandomMood:GameComponentTick",
 }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        public WitcherMonsterHunt(ModContentPack mod)
        {
            var methods = new[]
            {
                "WMHAnimalBehaviours.DamageWorker_ExtraInfecter:ApplySpecialEffectsToPart",
                "WMHAnimalBehaviours.IncidentWorker_MonsterEncounter:TryExecuteWorker",
            };

            PatchingUtilities.PatchSystemRand(methods, false);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        public VanillaFurnitureExpanded(ModContentPack mod)
        {
            var methods = new[]
            {
                "AOMoreFurniture.JobDriver_PlayComputerIndustrial:WatchTickAction",
                "AOMoreFurniture.JobDriver_PlayComputerModern:WatchTickAction",
                "AOMoreFurniture.JobDriver_PlayArcadeSounds:WatchTickAction",
                "AOMoreFurniture.JobDriver_PlayPunchingBag:WatchTickAction",
            };

            PatchingUtilities.PatchSystemRand(methods, false);
        }
コード例 #11
0
        public WhatTheHack(ModContentPack mod)
        {
            var methods = new[]
            {
                AccessTools.Method(AccessTools.TypeByName("WhatTheHack.Harmony.IncidentWorker_Raid_TryExecuteWorker"), "SpawnHackedMechanoids"),
                AccessTools.Method(AccessTools.TypeByName("WhatTheHack.Harmony.Pawn_JobTracker_DetermineNextJob"), "HackedPoorlyEvent"),
                AccessTools.Method(AccessTools.TypeByName("WhatTheHack.Harmony.Thing_ButcherProducts"), "GenerateExtraButcherProducts"),
                AccessTools.Method(AccessTools.TypeByName("WhatTheHack.Needs.Need_Maintenance"), "MaybeUnhackMechanoid"),
                AccessTools.Method(AccessTools.TypeByName("WhatTheHack.Recipes.Recipe_Hacking"), "CheckHackingFail"),
            };

            PatchingUtilities.PatchSystemRand(methods, false);
        }
コード例 #12
0
        public FertileFieldsCompat(ModContentPack mod)
        {
            {
                // RNG
                PatchingUtilities.PatchSystemRand("RFF_Code.Building_CompostBin:PlaceProduct");
            }

            Type type = GrowZoneManagerType = AccessTools.TypeByName("RFF_Code.GrowZoneManager");

            MP.RegisterSyncMethod(type, "ToggleReturnToSoil");
            MP.RegisterSyncMethod(type, "ToggleDesignateReplacements");

            MP.RegisterSyncWorker <MapComponent>(SyncWorkerForGrowZoneManager, type);
        }
コード例 #13
0
 public AlphaBehavioursAndEvents(ModContentPack mod)
 {
     //RNG Fix
     {
         var rngFixMethods = new[] { //System.Random fixes
             "AlphaBehavioursAndEvents.CompGasProducer:CompTick",
             "AlphaBehavioursAndEvents.CompAnimalProduct:InformGathered",
             "AlphaBehavioursAndEvents.CompInitialHediff:CompTickRare",
             "AlphaBehavioursAndEvents.Gas_Ocular:Tick",
             "AlphaBehavioursAndEvents.Hediff_Crushing:RandomFilthGenerator",
         };
         PatchingUtilities.PatchSystemRand(rngFixMethods);
     }
 }
コード例 #14
0
        private static void LatePatch()
        {
            var types = new[]
            {
                "VSEWW.MapComponent_Winston:SetNextNormalRaidInfo",
                "VSEWW.MapComponent_Winston:SetNextBossRaidInfo",
                "VSEWW.NextRaidInfo:WavePawns",
                "VSEWW.NextRaidInfo:ChooseAndApplyModifier",
            };

            PatchingUtilities.PatchSystemRand(types, false);

            var type = AccessTools.TypeByName("VSEWW.MapComponent_Winston");

            MP.RegisterSyncMethod(type, "ExecuteRaid");
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        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);
        }
コード例 #17
0
        public VanillaFishingExpanded(ModContentPack mod)
        {
            // RNG fix
            {
                PatchingUtilities.PatchSystemRand(AccessTools.Method("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");

                MP.RegisterSyncMethod(commandType, "<ProcessInput>b__4_0");
                MP.RegisterSyncMethod(commandType, "<ProcessInput>b__4_1");
                MP.RegisterSyncMethod(commandType, "<ProcessInput>b__4_2");

                MP.RegisterSyncWorker <Command>(SyncFishingZoneChange, commandType, shouldConstruct: false);
            }
        }
コード例 #18
0
        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();
            }
        }
コード例 #19
0
        public VanillaAnimalsCaves(ModContentPack mod)
        {
            // RNG
            {
                var methods = new[]
                {
                    "VAECaves.Building_SpiderEggs:Tick",
                    "VAECaves.DamageWorker_TwoArmSlam:Apply",
                    "VAECaves.IncidentWorker_Hulk:CanFireNowSub",
                    "VAECaves.JobDriver_CreateEggs:<MakeNewToils>b__1_0",
                };

                PatchingUtilities.PatchSystemRand(methods, false);
                PatchingUtilities.PatchSystemRandCtor("VAECaves.Hediff_WallBreaker", false);
            }

            // Gizmos
            {
                MpCompat.RegisterLambdaMethod("VAECaves.Building_Cocoon", "GetGizmos", 0);
                MpCompat.RegisterLambdaMethod("VAECaves.CompConditionalSpawner", "CompGetGizmosExtra", 0).SetDebugOnly();
            }
        }
コード例 #20
0
        public EccentricTechFusionPower(ModContentPack mod)
        {
            // RNG
            {
                var type = AccessTools.TypeByName("EccentricPower.CompFusionGenerator");
                PatchingUtilities.PatchSystemRand(AccessTools.Method(type, "generateNewFailurePoints"), false);
                PatchingUtilities.PatchSystemRand(AccessTools.Method(type, "doEmergencyVentFireDamage"), true);
            }

            // Gizmos
            {
                var type = AccessTools.TypeByName("EccentricPower.CompFusionGenerator");
                MP.RegisterSyncMethod(type, "SetDesiredOutputLevel");
                MP.RegisterSyncMethod(type, "setPowerMode");
                MP.RegisterSyncMethod(type, "StartIgnitionCycle");
                MP.RegisterSyncMethod(type, "StartShutdownCycle");
                MP.RegisterSyncMethod(type, "StartEmergencyVent");
                MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", Enumerable.Range(3, 5).ToArray()).SetDebugOnly(); // 3 to 7
            }

            LongEventHandler.ExecuteWhenFinished(LatePatch);
        }
コード例 #21
0
        public VanillaFactionsInsectoid(ModContentPack mod)
        {
            // Gizmos
            {
                // These two methods aren't patched, but supposedly the teleporter isn't included in the mod right now due to being bugged
                // Working on them could be problematic, as it seems that they reimplement (or at least used to reimplement) vanilla caravan forming screen completely from scratch
                // VFEI.Comps.ItemComps.CompArchotechTeleporter
                // VFEI.Comps.ItemComps.CompCustomTransporter

                var type = AccessTools.TypeByName("InsectoidBioengineering.Building_BioengineeringIncubator");
                MpCompat.RegisterSyncMethodsByIndex(type, "<GetGizmos>", 0, 1, 2, 3);

                // Keep an eye on this in the future, seems like something the devs might combine into a single class at some point
                foreach (var geneNumber in new[] { "First", "Second", "Third" })
                {
                    type = AccessTools.TypeByName($"InsectoidBioengineering.Command_Set{geneNumber}GenomeList");
                    MP.RegisterSyncWorker <Command>(SyncSetGenomeCommand, type, shouldConstruct: true);
                    MP.RegisterSyncMethod(AccessTools.Method(type, $"TryInsert{geneNumber}Genome"));
                }
            }

            // RNG
            {
                var constructors = new[]
                {
                    "InsectoidBioengineering.Building_BioengineeringIncubator",
                    //"VFEI.CompFilthProducer",
                };

                PatchingUtilities.PatchSystemRandCtor(constructors, false);

                var methods = new[]
                {
                    "VFEI.CompTargetEffect_Tame:RandomNumber",
                };

                PatchingUtilities.PatchSystemRand(methods);
            }
        }
コード例 #22
0
        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.RegisterLambdaMethod(type, "GetGizmos", 0, 2, 3, 4, 6, 8, 9, 10);

                type = AccessTools.TypeByName("ItemProcessor.Command_SetQualityList");
                MP.RegisterSyncWorker <Command>(SyncCommandWithBuilding, type, shouldConstruct: true);
                MpCompat.RegisterLambdaMethod(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.RegisterLambdaMethod(type, "ProcessInput", 0);
                }
            }

            // Vanilla Cooking Expanded
            {
                // AddHediff desyncs with Arbiter, but seems fine without it
                PatchingUtilities.PatchPushPopRand("VanillaCookingExpanded.Thought_Hediff:MoodOffset");
            }

            // VFE Core
            {
                MpCompat.RegisterLambdaMethod("VFECore.CompPawnDependsOn", "CompGetGizmosExtra", 0).SetDebugOnly();

                learnedAbilitiesField = AccessTools.Field(AccessTools.TypeByName("VFECore.Abilities.CompAbilities"), "learnedAbilities");
                MP.RegisterSyncWorker <ITargetingSource>(SyncVEFAbility, AccessTools.TypeByName("VFECore.Abilities.Ability"));
            }

            // Vanilla Furniture Expanded
            {
                MpCompat.RegisterLambdaMethod("VanillaFurnitureExpanded.CompConfigurableSpawner", "CompGetGizmosExtra", 0).SetDebugOnly();

                var type = AccessTools.TypeByName("VanillaFurnitureExpanded.Command_SetItemsToSpawn");
                MpCompat.RegisterLambdaDelegate(type, "ProcessInput", 1);
                MP.RegisterSyncWorker <Command>(SyncCommandWithBuilding, type, shouldConstruct: true);

                MpCompat.RegisterLambdaMethod("VanillaFurnitureExpanded.CompRockSpawner", "CompGetGizmosExtra", 0);

                type = AccessTools.TypeByName("VanillaFurnitureExpanded.Command_SetStoneType");
                setStoneBuildingField = AccessTools.Field(type, "building");
                MpCompat.RegisterLambdaMethod(type, "ProcessInput", 0);
                MP.RegisterSyncWorker <Command>(SyncSetStoneTypeCommand, type, shouldConstruct: true);
                MpCompat.RegisterLambdaDelegate(type, "ProcessInput", 1);

                type = AccessTools.TypeByName("VanillaFurnitureExpanded.CompRandomBuildingGraphic");
                MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 0);
            }

            // Vanilla Faction Mechanoids
            {
                var type = AccessTools.TypeByName("VFE.Mechanoids.CompMachineChargingStation");
                MpCompat.RegisterLambdaDelegate(type, "CompGetGizmosExtra", 1, 6).SetContext(SyncContext.MapSelected);
                MpCompat.RegisterLambdaDelegate(type, "CompGetGizmosExtra", 4);
            }

            // AnimalBehaviours
            {
                // RNG
                PatchingUtilities.PatchSystemRand("AnimalBehaviours.DamageWorker_ExtraInfecter:ApplySpecialEffectsToPart", false);
                var rngFixConstructors = new[]
                {
                    "AnimalBehaviours.CompAnimalProduct",
                    "AnimalBehaviours.CompFilthProducer",
                    "AnimalBehaviours.CompGasProducer",
                    "AnimalBehaviours.CompInitialHediff",
                    "AnimalBehaviours.DeathActionWorker_DropOnDeath",
                };
                PatchingUtilities.PatchSystemRandCtor(rngFixConstructors, false);

                // Gizmos
                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");
                MpCompat.RegisterLambdaDelegate(type, "GetGizmos_Postfix", 1);       // Fire at will
                MpCompat.RegisterLambdaDelegate(type, "GetAttackGizmos_Postfix", 4); // Interrupt Attack
                MpCompat.RegisterLambdaDelegate(type, "Pawn_GetGizmos_Postfix", 0);  // Also interrupt Attack
            }

            // Explosive Trails Effect
            {
                // RNG
                PatchingUtilities.PatchPushPopRand("ExplosiveTrailsEffect.SmokeThrowher:ThrowSmokeTrail");
            }

            // KCSG (Custom Structure Generation)
            {
                // RNG
                var methods = new[]
                {
                    "KCSG.SymbolResolver_AddFields:Resolve",
                    "KCSG.SymbolResolver_Settlement:GenerateRooms",
                };

                PatchingUtilities.PatchSystemRand(methods, false);
            }
        }
コード例 #23
0
 public static void LatePatch() => PatchingUtilities.PatchSystemRand("VEE.RegularEvents.SpaceBattle:GameConditionTick", false);
コード例 #24
0
 public VanillaBrewingExpanded(ModContentPack mod)
 {
     PatchingUtilities.PatchSystemRand("VanillaBrewingExpanded.Plant_AutoProduce:TickLong");
     PatchingUtilities.PatchSystemRandCtor("VanillaBrewingExpanded.Hediff_ConsumedCocktail");
 }
コード例 #25
0
        public AndroidTiers(ModContentPack mod)
        {
            // RNG
            {
                var methods = new[]
                {
                    "MOARANDROIDS.CompHeatSensitive:PostSpawnSetup",
                    "MOARANDROIDS.CompHeatSensitive:CheckTemperature",
                    "MOARANDROIDS.StartingPawnUtility_Patch+NewGeneratedStartingPawn_Patch:Listener",
                    "MOARANDROIDS.AndroidFactionDialogOverride:Postfix",
                    "MOARANDROIDS.MultiplePawnRacesAtStart:Postfix",
                    "MOARANDROIDS.Recipe_MemoryCorruptionChance:RandomCorruption",
                    "MOARANDROIDS.Recipe_AndroidRewireSurgery:RandomCorruption",
                    "MOARANDROIDS.Recipe_RemoveSentience:RandomCorruption",
                    "MOARANDROIDS.Recipe_RerollTraits:RandomCorruption",
                    "MOARANDROIDS.StockGenerator_SlaveAndroids+<GenerateThings>d__0:MoveNext",
                };

                PatchingUtilities.PatchSystemRand(methods, false);
            }

            // Gizmos
            {
                var type = AccessTools.TypeByName("MOARANDROIDS.CompAndroidState");
                MpCompat.RegisterLambdaDelegate(type, "CompGetGizmosExtra", 0, 2, 4, 5, 7, 10, 11, 12, 14);

                type = AccessTools.TypeByName("MOARANDROIDS.CompAutoDoor");
                MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 0, 1);

                type = AccessTools.TypeByName("MOARANDROIDS.CompRemotelyControlledTurret");
                MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 0);

                // Really ugly... We can't sync the pawns directly here, as they're inaccessible - the ThingComp is holding them inside
                // however, it does not implement IThingHolder or whatever it's supposed to in cases like those
                // so we do a lot of workarounds to not rely on the pawn sync worker
                type = compSkyCloudCoreType = AccessTools.TypeByName("MOARANDROIDS.CompSkyCloudCore");
                skyCloudCoreStoredMindsField = AccessTools.FieldRefAccess <List <Pawn> >(type, "storedMinds");
                MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 6, 10, 11, 12, 13, 26, 27);
                var methods = MpMethodUtil.GetLambda(type, "CompGetGizmosExtra", MethodType.Normal, null, 4, 16, 24);
                foreach (var method in methods)
                {
                    MP.RegisterSyncMethod(method);
                    MP.RegisterSyncWorker <object>(SyncInnerClassWithPawn, method.DeclaringType, shouldConstruct: true);
                }
                var methodsArray = MpMethodUtil.GetLambda(type, "CompGetGizmosExtra", MethodType.Normal, null, 6, 11, 27).ToArray();
                skyCloudCoreGetGizmos6  = MethodInvoker.GetHandler(methodsArray[0]);
                skyCloudCoreGetGizmos11 = MethodInvoker.GetHandler(methodsArray[1]);
                skyCloudCoreGetGizmos27 = MethodInvoker.GetHandler(methodsArray[2]);
                MP.RegisterSyncMethod(typeof(AndroidTiers), nameof(SyncedGetGizmos6));
                MP.RegisterSyncMethod(typeof(AndroidTiers), nameof(SyncedGetGizmos11));
                MP.RegisterSyncMethod(typeof(AndroidTiers), nameof(SyncedGetGizmos27));
                MpCompat.harmony.Patch(methodsArray[0], prefix: new HarmonyMethod(typeof(AndroidTiers), nameof(PreCompGetGizmos6)));
                MpCompat.harmony.Patch(methodsArray[1], prefix: new HarmonyMethod(typeof(AndroidTiers), nameof(PreCompGetGizmos11)));
                MpCompat.harmony.Patch(methodsArray[2], prefix: new HarmonyMethod(typeof(AndroidTiers), nameof(PreCompGetGizmos27)));

                type = AccessTools.TypeByName("MOARANDROIDS.CompSkyMind");
                MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 1, 3);

                type = compSurrogateOwnerType = AccessTools.TypeByName("MOARANDROIDS.CompSurrogateOwner");
                surrogateOwnerSkyCloudHostField = AccessTools.FieldRefAccess <Thing>(type, "skyCloudHost");
                MpCompat.RegisterLambdaDelegate(type, "CompGetGizmosExtra", 1, 3, 5, 9, 10, 13, 16, 19, 23);

                type = AccessTools.TypeByName("MOARANDROIDS.CPaths");
                MpCompat.RegisterLambdaDelegate(type, "QEE_BuildingPawnVatGrower_GetGizmosPostfix", 2, 5, 8);

                // CompComputer - all gizmos end up using a designator to pick a target, so we sync the designator
            }

            // Designators
            {
                var type = AccessTools.TypeByName("MOARANDROIDS.Designator_SurrogateToHack");
                surrogateToHackConstructor   = AccessTools.Constructor(type, new[] { typeof(int) });
                surrogateToHackPosField      = AccessTools.FieldRefAccess <IntVec3>(type, "pos");
                surrogateToHackTargetField   = AccessTools.FieldRefAccess <Pawn>(type, "target");
                surrogateToHackMapField      = AccessTools.FieldRefAccess <Map>(type, "cmap");
                surrogateToHackHackTypeField = AccessTools.FieldRefAccess <int>(type, "hackType");
                MP.RegisterSyncWorker <Designator>(SyncSurrogateToHackDesignator, type);

                type = AccessTools.TypeByName("MOARANDROIDS.Designator_AndroidToControl");
                androidToControlConstructor       = AccessTools.Constructor(type, new[] { typeof(Pawn), typeof(bool) });
                androidToControlPawnField         = AccessTools.FieldRefAccess <Pawn>(type, "controller");
                androidToControlFromSkyCloudField = AccessTools.FieldRefAccess <bool>(type, "fromSkyCloud");
                androidToControlKindOfTargetField = AccessTools.FieldRefAccess <int>(type, "kindOfTarget");
                androidToControlPosField          = AccessTools.FieldRefAccess <IntVec3>(type, "pos");
                androidToControlTargetField       = AccessTools.FieldRefAccess <Thing>(type, "target");
                androidToControlMapField          = AccessTools.FieldRefAccess <Map>(type, "cmap");
                MP.RegisterSyncWorker <Designator>(SyncAndroidToControlDesignator, type);
                MP.RegisterSyncMethod(typeof(AndroidTiers), nameof(SyncedConnectToSkyMind));
                MpCompat.harmony.Patch(AccessTools.Method(type, "CanDesignateThing"),
                                       transpiler: new HarmonyMethod(typeof(AndroidTiers), nameof(ReplaceConnectToSkyMind)));
            }

            // Dialogs
            {
                var type = AccessTools.TypeByName("MOARANDROIDS.Dialog_SkillUp");
                skillUpDialogConstructor            = AccessTools.Constructor(type, new[] { typeof(Pawn), typeof(bool) });
                skillUpGetNbPointsWantedToBuyMethod = MethodInvoker.GetHandler(AccessTools.Method(type, "getNbPointsWantedToBuy"));
                skillUpAndroidField                       = AccessTools.FieldRefAccess <Pawn>(type, "android");
                skillUpSkillDefListField                  = AccessTools.FieldRefAccess <List <SkillDef> >(type, "sd");
                skillUpPointsField                        = AccessTools.FieldRefAccess <List <int> >(type, "points");
                skillUpPassionsStateField                 = AccessTools.FieldRefAccess <List <int> >(type, "points");
                skillUpPointsNeededPerSkillField          = AccessTools.FieldRefAccess <int>(type, "pointsNeededPerSkill");
                skillUppointsNeededToIncreasePassionField = AccessTools.FieldRefAccess <int>(type, "pointsNeededToIncreasePassion");
                MP.RegisterSyncMethod(typeof(AndroidTiers), nameof(SyncedSkillUpDialogAccept));
                MP.RegisterSyncWorker <Window>(SyncSkillUpDialog, type);
                MpCompat.harmony.Patch(AccessTools.Method(type, "DoWindowContents"),
                                       transpiler: new HarmonyMethod(typeof(AndroidTiers), nameof(ReplaceButton)));

                type            = AccessTools.TypeByName("MOARANDROIDS.Utils");
                gcAttpCompField = AccessTools.StaticFieldRefAccess <GameComponent>(AccessTools.Field(type, "GCATPP"));

                type = AccessTools.TypeByName("MOARANDROIDS.GC_ATPP");
                gameComponentDecSkillPointsMethod = MethodInvoker.GetHandler(AccessTools.Method(type, "decSkillPoints"));
                gameComponentConnectUserMethod    = MethodInvoker.GetHandler(AccessTools.Method(type, "connectUser"));
                gameComponentConnectedThingField  = AccessTools.FieldRefAccess <HashSet <Thing> >(type, "connectedThing");
                gameComponentNbSlotField          = AccessTools.FieldRefAccess <int>(type, "nbSlot");
            }

            // 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);

                var typeNames = new[]
                {
                    "MOARANDROIDS.ChoiceLetter_RansomDemand",
                    "MOARANDROIDS.ChoiceLetter_RansomwareDemand",
                };

                foreach (var typeName in typeNames)
                {
                    type = AccessTools.TypeByName(typeName);
                    rejectMethods.Add(type, AccessTools.Method(typeof(ChoiceLetter), nameof(ChoiceLetter.Option_Reject))); // Generic reject option
                    var method = MpMethodUtil.GetLambda(type, "Choices", MethodType.Getter, lambdaOrdinal: 0);
                    MP.RegisterSyncMethod(method);
                }
            }
        }
コード例 #26
0
        public VanillaPowerExpanded(ModContentPack mod)
        {
            Type type;

            // Gizmos
            // Debug fill/empty
            {
                type = AccessTools.TypeByName("GasNetwork.CompGasStorage");
                // Both these methods are calling (basically) the same method,
                // but that method also has other callers that don't need syncing
                MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 0, 1).SetDebugOnly();
            }

            // Order to or cancel plugging the hole (method names shared by both types)
            {
                var types = new[]
                {
                    "VanillaPowerExpanded.Building_ChemfuelPond",
                    "VanillaPowerExpanded.Building_GasGeyser",
                };
                foreach (var typeName in types)
                {
                    type = AccessTools.TypeByName(typeName);
                    MP.RegisterSyncMethod(type, "SetHoleForPlugging");
                    MP.RegisterSyncMethod(type, "CancelHoleForPlugging");
                }
            }

            // Violence generator
            {
                type = AccessTools.TypeByName("VanillaPowerExpanded.CompSoulsPowerPlant");
                MpCompat.RegisterLambdaMethod(type, "CompGetGizmosExtra", 1); // Toggle on/off
            }

            // RNG Fix
            {
                // Patch GasNetwork.MapComponent_WindDirection ctor
                PatchingUtilities.PatchSystemRand(AccessTools.Constructor(AccessTools.TypeByName("GasNetwork.MapComponent_WindDirection"), new Type[] { typeof(Map) }), false);

                var methods = new[]
                {
                    "VanillaPowerExpanded.Building_SmallBattery:Tick",
                    "VanillaPowerExpanded.Building_SmallBattery:PostApplyDamage",
                    "VanillaPowerExpanded.WeatherEvent_CustomLightningStrike:FireEvent",
                    "VanillaPowerExpanded.MapComponentExtender:doMapSpawns",
                    "VanillaPowerExpanded.CompPlantHarmRadiusIfBroken:CompTick",
                    // HarmRandomPlantInRadius is only called by CompPlantHarmRadiusIfBroken:CompTick, no need for patching
                    // CompPowerPlantNuclear:AffectCell is only calling a seeded random
                    "VanillaPowerExpanded.IntermittentGasSprayer:SteamSprayerTick",
                    // IntermittentGasSprayer - NewBaseAirPuff is only called by ThrowAirPuffUp which is called by SteamSprayerTick, no need for patching
                    // Building_GasGeyser:StartSpray is assigned to IntermittentGasSprayer:startSprayCallback, which is called from SteamSprayerTick
                    "GasNetwork.GasNet:GasNetTick",
                    "GasNetwork.MapComponent_WindDirection:MapGenerated",
                    // PipeNetGrid pushes and pops all Rand calls, no need to patch
                    // CompPowerAdvancedWater:RebuildCache is only calling a seeded random
                };

                // These methods are loading resources in their .ctor, must be patched later
                var methodsForLater = new[]
                {
                    "VanillaPowerExpanded.CompPowerAdvancedWater:PostSpawnSetup",
                    "VanillaPowerExpanded.CompPowerAdvancedWind:PostSpawnSetup",
                };

                PatchingUtilities.PatchPushPopRand(methods);
                LongEventHandler.ExecuteWhenFinished(() => PatchingUtilities.PatchPushPopRand(methodsForLater));

                // Wind map comp
                windDirectionField = AccessTools.FieldRefAccess <float>(AccessTools.TypeByName("GasNetwork.MapComponent_WindDirection"), "windDirection");
                MpCompat.harmony.Patch(AccessTools.Method("GasNetwork.MapComponent_WindDirection:MapComponentTick"),
                                       prefix: new HarmonyMethod(typeof(VanillaPowerExpanded), nameof(ReplaceWindMapComponentTick)));

                // GasNet utilities
                MpCompat.harmony.Patch(AccessTools.Method("GasNetwork.Utilities:HashOffsetTicks"),
                                       prefix: new HarmonyMethod(typeof(VanillaPowerExpanded), nameof(ReplaceHashOffsetTicks)));
            }
        }
コード例 #27
0
        public WhatTheHack(ModContentPack mod)
        {
            thingsById = (Dictionary <int, Thing>)AccessTools.Field(AccessTools.TypeByName("Multiplayer.Client.ThingsById"), "thingsById").GetValue(null);

            // Setup
            {
                // Base mod class
                var type = AccessTools.TypeByName("WhatTheHack.Base");
                MpCompat.harmony.Patch(AccessTools.Method(type, "WorldLoaded"),
                                       postfix: new HarmonyMethod(typeof(WhatTheHack), nameof(PostWorldLoaded)));
                // ExtendedDataStorage class
                type = AccessTools.TypeByName("WhatTheHack.Storage.ExtendedDataStorage");
                pawnStorageDictionary        = AccessTools.FieldRefAccess <IDictionary>(type, "_store");
                getExtendedDataForPawnMethod = MethodInvoker.GetHandler(AccessTools.Method(type, "GetExtendedDataFor", new[] { typeof(Pawn) }));
                // ExtendedPawnData class, needs to be synced for some sync methods
                type = AccessTools.TypeByName("WhatTheHack.Storage.ExtendedPawnData");
                MP.RegisterSyncWorker <object>(SyncExtendedPawnData, type);
            }

            // RNG
            {
                var methods = new[]
                {
                    AccessTools.Method(AccessTools.TypeByName("WhatTheHack.Harmony.IncidentWorker_Raid_TryExecuteWorker"), "SpawnHackedMechanoids"),
                    AccessTools.Method(AccessTools.TypeByName("WhatTheHack.Harmony.Pawn_JobTracker_DetermineNextJob"), "HackedPoorlyEvent"),
                    AccessTools.Method(AccessTools.TypeByName("WhatTheHack.Harmony.Thing_ButcherProducts+<GenerateExtraButcherProducts>d__1"), "MoveNext"),
                    AccessTools.Method(AccessTools.TypeByName("WhatTheHack.Needs.Need_Maintenance"), "MaybeUnhackMechanoid"),
                    AccessTools.Method(AccessTools.TypeByName("WhatTheHack.Recipes.Recipe_Hacking"), "CheckHackingFail"),
                };

                PatchingUtilities.PatchSystemRand(methods, false);
            }

            // Gizmos
            {
                // Activate the beacon to boost rogue AI
                MP.RegisterSyncMethod(AccessTools.Method("WhatTheHack.Buildings.Building_MechanoidBeacon:StartupHibernatingParts"));

                // Mechanoid platform (bed)
                // Toggle regenerate missing parts (1), toggle repair (3)
                MpCompat.RegisterLambdaMethod("WhatTheHack.Buildings.Building_MechanoidPlatform", "GetGizmos", 1, 3);

                // Rogue AI, it's got a bit of functions
                var type = AccessTools.TypeByName("WhatTheHack.Buildings.Building_RogueAI");
                // Methods
                MpCompat.RegisterLambdaMethod(type, "GetTalkGibberishGizmo", 0);
                MpCompat.RegisterLambdaMethod(type, "GetManagePowerNetworkGizmo", 1);
                MpCompat.RegisterLambdaMethod(type, "GetControlTurretAvtivateGizmo", 0);
                MpCompat.RegisterLambdaMethod(type, "GetControlMechanoidActivateGizmo", 0);
                MpCompat.RegisterLambdaMethod(type, "GetHackingAvtivateGizmo", 0);
                // Delegates
                MpCompat.RegisterLambdaDelegate(type, "GetControlMechanoidCancelGizmo", 0);
                MpCompat.RegisterLambdaDelegate(type, "GetControlTurretCancelGizmo", 0);
                MpCompat.RegisterLambdaDelegate(type, "GetHackingCancelGizmo", 0);

                // Gizmo for hacked mechanoids, setting min value for maintenance
                type = AccessTools.TypeByName("WhatTheHack.Command_SetMaintenanceThreshold");
                maintenanceNeedField = AccessTools.FieldRefAccess <Need>(type, "maintenanceNeed");
                MpCompat.RegisterLambdaMethod(type, "ProcessInput", 1);
                MP.RegisterSyncWorker <Command>(SyncCommand_SetMaintenanceThreshold, type, shouldConstruct: true);

                // Gizmo for hacked mechanoids, setting min value for power
                type           = AccessTools.TypeByName("WhatTheHack.Command_SetWorkThreshold");
                powerNeedField = AccessTools.FieldRefAccess <Need>(type, "powerNeed");
                MpCompat.RegisterLambdaMethod(type, "ProcessInput", 1);
                MP.RegisterSyncWorker <Command>(SyncCommand_SetWorkThreshold, type, shouldConstruct: true);

                //
                type = AccessTools.TypeByName("WhatTheHack.Harmony.Pawn_GetGizmos");
                MpCompat.RegisterLambdaDelegate(type, "CreateGizmo_SearchAndDestroy", 1);
                MpCompat.RegisterLambdaDelegate(type, "CreateGizmo_AutoRecharge", 1);
                MpCompat.RegisterLambdaDelegate(type, "CreateGizmo_Work", 1);
                MpCompat.RegisterLambdaDelegate(type, "CreateGizmo_SelfDestruct", 0);
                MpCompat.RegisterLambdaDelegate(type, "CreateGizmo_SelfRepair", 0);
                MpCompat.RegisterLambdaDelegate(type, "CreateGizmo_Repair", 0);
                MpCompat.RegisterLambdaDelegate(type, "CreateGizmo_EquipBelt", 0);
                MpCompat.RegisterLambdaDelegate(type, "CreateGizmo_Overdrive", 0);

                type = AccessTools.TypeByName("WhatTheHack.RemoteController");
                MpCompat.RegisterLambdaDelegate(type, "GetRemoteControlDeActivateGizmo", 0);
                MpCompat.RegisterLambdaDelegate(type, "GetRemoteControlActivateGizmo", 0);

                type = AccessTools.TypeByName("WhatTheHack.Harmony.CompLongRangeMineralScanner_CompGetGizmosExtra");
                MpCompat.RegisterLambdaDelegate(type, "AddMechPartsOption", 1).SetContext(SyncContext.MapSelected);
            }
        }
コード例 #28
0
        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[] methodsWithRand =
                {
                    "NewHatcher.CompHatcherRandomizer:Hatch",
                    "NewHatcher.CompIncubator:Hatch",
                    "NewHatcher.CompRecombinator:Hatch",
                    "NewHatcher.CompRecombinator:RecombinateAgain",
                    "NewHatcher.CompRecombinatorSerum:Hatch",
                };

                PatchingUtilities.PatchSystemRand(methodsWithRand);
            }
        }
コード例 #29
0
        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
            }
        }