コード例 #1
0
        public AlphaBehavioursAndEvents(ModContentPack mod)
        {
            //RNG Fix
            {
                var rngFixConstructors = new[]
                {
                    "AlphaBehavioursAndEvents.DeathActionWorker_ExplodeAndSpawnEggs",
                    "AlphaBehavioursAndEvents.Hediff_Crushing",

                    // Ocular plant conversion
                    "AlphaBehavioursAndEvents.CompAbilityOcularConversion",
                    "AlphaBehavioursAndEvents.Gas_Ocular",
                };

                PatchingUtilities.PatchSystemRandCtor(rngFixConstructors, false);

                var rngFixMethods = new[] //System.Random fixes
                {
                    "AlphaBehavioursAndEvents.Hediff_Crushing:RandomFilthGenerator",

                    // Ocular plant conversion
                    "AlphaBehavioursAndEvents.CompAbilityOcularConversion:Apply",
                    "AlphaBehavioursAndEvents.Gas_Ocular:Tick",
                };
                PatchingUtilities.PatchPushPopRand(rngFixMethods);
            }
        }
コード例 #2
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);
        }
        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);
            }
        }
コード例 #4
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);
        }
コード例 #5
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");
            }
        }
        public VFESecurity(ModContentPack mod)
        {
            // RNG fix
            {
                var methodNames = new[]
                {
                    "VFESecurity.ArtilleryStrikeArrivalAction_AIBase:Arrived",
                    "VFESecurity.ArtilleryStrikeArrivalAction_Insectoid:StrikeAction",
                    "VFESecurity.ArtilleryStrikeArrivalAction_Map:Arrived",
                    "VFESecurity.ArtilleryStrikeArrivalAction_Outpost:StrikeAction",
                    "VFESecurity.ArtilleryStrikeArrivalAction_PeaceTalks:Arrived",
                    "VFESecurity.ArtilleryStrikeArrivalAction_Settlement:StrikeAction",
                    "VFESecurity.WorldObjectCompProperties_Artillery:ArtilleryCountFor",
                    // ArtilleryStrikeUtility:GetRandomShellFor and ArtilleryStrikeUtility:PotentialStrikeCells are only called by methods that are patched already
                    "VFESecurity.Building_BarbedWire:SpringSub",
                    "VFESecurity.Building_TrapBear:SpringSub",
                    // This one seems like it should have no random calls at all in its hierarchy, but desync traces show that there are actually some.
                    "VFESecurity.Verb_Dazzle:TryCastShot",
                    "NoCamShakeExplosions.DamageWorker_FlameNoCamShake:Apply",
                    "NoCamShakeExplosions.DamageWorker_FlameNoCamShake:ExplosionAffectCell",
                    // Motes
                    "VFESecurity.ExtendedMoteMaker:SearchlightEffect",
                };

                PatchingUtilities.PatchPushPopRand(AccessTools.Method(AccessTools.Inner(AccessTools.TypeByName("VFESecurity.Patch_Building_Trap"), "Spring"), "ShouldDestroy"));
                PatchingUtilities.PatchPushPopRand(methodNames);
                LongEventHandler.ExecuteWhenFinished(LateSyncMethods);
            }
        }
コード例 #7
0
        public VFEF(ModContentPack mod)
        {
            //RNG Fix
            {
                var methods = new[] {
                    "VFEF.MoteSprinkler:NewMote",
                    "VFEF.MoteSprinkler:ThrowWaterSpray",
                };

                PatchingUtilities.PatchPushPopRand(methods);
            }
        }
コード例 #8
0
        public Desynchronized(ModContentPack mod)
        {
            var rngFixMethods = new[]
            {
                "Desynchronized.TNDBS.Pawn_NewsKnowledgeTracker:ForgetRandom",
                "Desynchronized.TNDBS.Pawn_NewsKnowledgeTracker:ForgetRandomly",
                "Desynchronized.TNDBS.Utilities.NewsSpreadUtility:SelectNewsRandomly",
                "Desynchronized.TNDBS.Utilities.NewsSpreadUtility:SelectNewsDistinctly",
                "Desynchronized.Patches.NewsTransmit.PostFix_InteractionWorker:ExecuteNewsTarnsmission",
                "Desynchronized.TNDBS.TaleNewsPawnDied:CalculateNewsImportanceForPawn",
            };

            PatchingUtilities.PatchPushPopRand(rngFixMethods);
        }
コード例 #9
0
        public ExplosiveTrailsEffect(ModContentPack mod)
        {
            if (isApplied)
            {
                return;
            }

            isApplied = true;

            var methodNames = new[]
            {
                "ExplosiveTrailsEffect.ExhaustFlames:ThrowRocketExhaustFlame",
                "ExplosiveTrailsEffect.SmokeThrowher:ThrowSmokeTrail",
            };

            PatchingUtilities.PatchPushPopRand(methodNames);
        }
コード例 #10
0
        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");
        }
コード例 #11
0
        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);
            }
        }
コード例 #12
0
        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);
            }
        }
コード例 #13
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);
        }
        public VanillaExpandedFramework(ModContentPack mod)
        {
            var type = AccessTools.TypeByName("ItemProcessor.Building_ItemProcessor");

            // _1 and _5 are used to check if gizmo should be enabled, so we don't sync them
            MpCompat.RegisterSyncMethodsByIndex(type, "<GetGizmos>", 0, 2, 3, 4, 6, 7);

            type = AccessTools.TypeByName("ItemProcessor.Command_SetQualityList");
            itemProcessorField = AccessTools.Field(type, "building");
            MP.RegisterSyncWorker <Command>(SyncSetTargetQuality, type, shouldConstruct: true);
            MpCompat.RegisterSyncMethodsByIndex(type, "<ProcessInput>", Enumerable.Range(0, 8).ToArray());

            // 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" })
            {
                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");
        }
コード例 #15
0
 public MiscTraining(ModContentPack mod)
 {
     PatchingUtilities.PatchPushPopRand("TrainingFacility.JobDriver_Archery:ShootArrow");
 }
コード例 #16
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)));
            }
        }
コード例 #17
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);
            }
        }
コード例 #18
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[] constructorsToPatch =
                {
                    "NewHatcher.CompHatcherRandomizer",
                    "NewHatcher.CompIncubator",
                    "NewHatcher.CompRecombinator",
                    "NewHatcher.CompRecombinatorSerum",
                };

                PatchingUtilities.PatchSystemRandCtor(constructorsToPatch, false);

                string[] methodsWithRand =
                {
                    "NewHatcher.CompHatcherRandomizer:Hatch",
                    "NewHatcher.CompIncubator:Hatch",
                    "NewHatcher.CompRecombinator:Hatch",
                    "NewHatcher.CompRecombinator:RecombinateAgain",
                    "NewHatcher.CompRecombinatorSerum:Hatch",
                };

                PatchingUtilities.PatchPushPopRand(methodsWithRand);
            }
        }
コード例 #19
0
        public GeneticRimCompat(ModContentPack mod)
        {
            Type type;

            // Several Gizmos
            {
                type = AccessTools.TypeByName("GeneticRim.GeneticRim_Pawn_GetGizmos_Patch");

                string[] methods =
                {
                    "<AddGizmo>b__0",
                    "<AddGizmo>b__1",
                    "<AddGizmo>b__10",
                    "<AddGizmo>b__11",
                    "<AddGizmo>b__12",
                    "<AddGizmo>b__13",
                    "<AddGizmo>b__14",
                    "<AddGizmo>b__15",
                    "<AddGizmo>b__16",
                    "<AddGizmo>b__17",
                    "<AddGizmo>b__3",
                    "<AddGizmo>b__5",
                    "<AddGizmo>b__7",
                    "<AddGizmo>b__8",
                    "<AddGizmo>b__9",
                };

                foreach (string method in methods)
                {
                    MP.RegisterSyncDelegate(type, "<>c__DisplayClass0_0", method);
                }
            }

            // ArchotechShip startup
            {
                MP.RegisterSyncMethod(AccessTools.Method("GeneticRim.ArchotechUtility:StartupHibernatingParts"));
                MP.RegisterSyncMethod(AccessTools.Method("GeneticRim.ArchotechCountdown:InitiateCountdown"));
            }
            {
                type = AccessTools.TypeByName("GeneticRim.ArchotechCountdown");

                string[] methods =
                {
                    "InitiateCountdown",
                    "CancelCountdown",
                    "CountdownEnded"
                };

                foreach (string method in methods)
                {
                    MP.RegisterSyncMethod(AccessTools.Method(type, method));
                }
            }

            // RNG patching
            {
                string[] constructorsToPatch =
                {
                    "GeneticRim.CompHatcherRandomizer",
                    "GeneticRim.CompIncubator",
                    "GeneticRim.CompRecombinator",
                    "GeneticRim.CompRecombinatorSerum",
                    "GeneticRim.DeathActionWorker_Eggxplosion",
                    "GeneticRim.CompExploder",
                };

                PatchingUtilities.PatchSystemRandCtor(constructorsToPatch, false);

                string[] methodsWithRand =
                {
                    "GeneticRim.CompHatcherRandomizer:Hatch",
                    "GeneticRim.CompIncubator:Hatch",
                    "GeneticRim.CompRecombinator:Hatch",
                    "GeneticRim.CompRecombinator:RecombinateAgain",
                    "GeneticRim.CompRecombinatorSerum:Hatch",
                    "GeneticRim.DeathActionWorker_Eggxplosion:PawnDied",
                    "GeneticRim.CompExploder:wickInitializer",
                };

                PatchingUtilities.PatchPushPopRand(methodsWithRand);
            }
        }
コード例 #20
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
            }
        }
        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.RegisterSyncMethodsByIndex(type, "<CompGetGizmosExtra>", 0, 1);

                type = AccessTools.TypeByName("VanillaPowerExpanded.CompPipeTank");
                // This method is only called by 2 gizmos and nothing else (as far as I can tell)
                MP.RegisterSyncMethod(type, "SetStoredEnergyPct");
            }
            // 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");
                }
            }

            // RNG Fix
            {
                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
                    "VanillaPowerExpanded.CompPowerPlantNuclear:AffectCell",
                    "VanillaPowerExpanded.Building_GasGeyser:StartSpray",
                    "VanillaPowerExpanded.GasExplosionUtility:TryStartFireNear",
                    "VanillaPowerExpanded.IncidentWorker_GasExplosion:TryExecuteWorker",
                    "VanillaPowerExpanded.IntermittentGasSprayer:SteamSprayerTick",
                    "VanillaPowerExpanded.IntermittentGasSprayer:ThrowAirPuffUp",
                    // NewBaseAirPuff is only called by IntermittentGasSprayer:ThrowAirPuffUp, no need for patching
                    "VanillaPowerExpanded.GasPipeNet:PowerNetTick",
                    "GasNetwork.GasNet:GasNetTick",
                    // 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.Building_Tank:Tick",
                    //"VanillaPowerExpanded.Building_Tank:PostApplyDamage",
                    "VanillaPowerExpanded.CompPowerAdvancedWater:PostSpawnSetup",
                    "VanillaPowerExpanded.CompPowerAdvancedWind:PostSpawnSetup",
                };

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