using System; using System.Collections.Generic; using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; namespace CheatEnabler; public static class FactoryPatch { public static ConfigEntry ImmediateEnabled; public static ConfigEntry ArchitectModeEnabled; public static ConfigEntry NoConditionEnabled; public static ConfigEntry NoCollisionEnabled; public static ConfigEntry BeltSignalGeneratorEnabled; public static ConfigEntry BeltSignalNumberAltFormat; public static ConfigEntry BeltSignalCountRecipeEnabled; public static ConfigEntry RemovePowerSpaceLimitEnabled; public static ConfigEntry BoostWindPowerEnabled; public static ConfigEntry BoostSolarPowerEnabled; public static ConfigEntry BoostFuelPowerEnabled; public static ConfigEntry BoostGeothermalPowerEnabled; private static Harmony _factoryPatch; public static void Init() { if (_factoryPatch != null) return; ImmediateEnabled.SettingChanged += (_, _) => ImmediateBuild.Enable(ImmediateEnabled.Value); ArchitectModeEnabled.SettingChanged += (_, _) => ArchitectMode.Enable(ArchitectModeEnabled.Value); NoConditionEnabled.SettingChanged += (_, _) => NoConditionBuild.Enable(NoConditionEnabled.Value); NoCollisionEnabled.SettingChanged += (_, _) => NoCollisionValueChanged(); BeltSignalGeneratorEnabled.SettingChanged += (_, _) => BeltSignalGenerator.Enable(BeltSignalGeneratorEnabled.Value); BeltSignalNumberAltFormat.SettingChanged += (_, _) => BeltSignalGenerator.OnAltFormatChanged(); RemovePowerSpaceLimitEnabled.SettingChanged += (_, _) => RemovePowerSpaceLimit.Enable(RemovePowerSpaceLimitEnabled.Value); BoostWindPowerEnabled.SettingChanged += (_, _) => BoostWindPower.Enable(BoostWindPowerEnabled.Value); BoostSolarPowerEnabled.SettingChanged += (_, _) => BoostSolarPower.Enable(BoostSolarPowerEnabled.Value); BoostFuelPowerEnabled.SettingChanged += (_, _) => BoostFuelPower.Enable(BoostFuelPowerEnabled.Value); BoostGeothermalPowerEnabled.SettingChanged += (_, _) => BoostGeothermalPower.Enable(BoostGeothermalPowerEnabled.Value); ImmediateBuild.Enable(ImmediateEnabled.Value); ArchitectMode.Enable(ArchitectModeEnabled.Value); NoConditionBuild.Enable(NoConditionEnabled.Value); NoCollisionValueChanged(); BeltSignalGenerator.Enable(BeltSignalGeneratorEnabled.Value); RemovePowerSpaceLimit.Enable(RemovePowerSpaceLimitEnabled.Value); BoostWindPower.Enable(BoostWindPowerEnabled.Value); BoostSolarPower.Enable(BoostSolarPowerEnabled.Value); BoostFuelPower.Enable(BoostFuelPowerEnabled.Value); BoostGeothermalPower.Enable(BoostGeothermalPowerEnabled.Value); _factoryPatch = Harmony.CreateAndPatchAll(typeof(FactoryPatch)); } public static void Uninit() { _factoryPatch?.UnpatchSelf(); _factoryPatch = null; ImmediateBuild.Enable(false); ArchitectMode.Enable(false); NoConditionBuild.Enable(false); BeltSignalGenerator.Enable(false); RemovePowerSpaceLimit.Enable(false); BoostWindPower.Enable(false); BoostSolarPower.Enable(false); BoostFuelPower.Enable(false); BoostGeothermalPower.Enable(false); } private static void NoCollisionValueChanged() { var coll = ColliderPool.instance; if (coll == null) return; var obj = coll.gameObject; if (obj == null) return; obj.gameObject.SetActive(!NoCollisionEnabled.Value); } public static void ArrivePlanet(PlanetFactory factory) { var imm = ImmediateEnabled.Value; var architect = ArchitectModeEnabled.Value; if (!imm && !architect) return; var prebuilds = factory.prebuildPool; if (imm) factory.BeginFlattenTerrain(); for (var i = factory.prebuildCursor - 1; i > 0; i--) { if (prebuilds[i].id != i) continue; if (prebuilds[i].itemRequired > 0) { if (!architect) continue; prebuilds[i].itemRequired = 0; if (imm) factory.BuildFinally(GameMain.mainPlayer, i, false); else factory.AlterPrebuildModelState(i); } else { if (imm) factory.BuildFinally(GameMain.mainPlayer, i, false); } } if (imm) factory.EndFlattenTerrain(); } [HarmonyPostfix] [HarmonyPatch(typeof(PlanetData), nameof(PlanetData.NotifyFactoryLoaded))] private static void PlanetData_NotifyFactoryLoaded_Postfix(PlanetData __instance) { ArrivePlanet(__instance.factory); } private static class ImmediateBuild { private static Harmony _immediatePatch; public static void Enable(bool enable) { if (enable) { if (_immediatePatch != null) return; var factory = GameMain.mainPlayer?.factory; if (factory != null) { ArrivePlanet(factory); } _immediatePatch = Harmony.CreateAndPatchAll(typeof(ImmediateBuild)); return; } _immediatePatch?.UnpatchSelf(); _immediatePatch = null; } [HarmonyTranspiler] [HarmonyPatch(typeof(BuildTool_Addon), nameof(BuildTool_Addon.CreatePrebuilds))] [HarmonyPatch(typeof(BuildTool_BlueprintPaste), nameof(BuildTool_BlueprintPaste.CreatePrebuilds))] [HarmonyPatch(typeof(BuildTool_Click), nameof(BuildTool_Click.CreatePrebuilds))] [HarmonyPatch(typeof(BuildTool_Inserter), nameof(BuildTool_Inserter.CreatePrebuilds))] [HarmonyPatch(typeof(BuildTool_Path), nameof(BuildTool_Path.CreatePrebuilds))] private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) { var matcher = new CodeMatcher(instructions, generator); matcher.MatchForward(false, new CodeMatch(OpCodes.Ret) ); if (matcher.IsInvalid) { CheatEnabler.Logger.LogWarning($"Failed to patch CreatePrebuilds"); return matcher.InstructionEnumeration(); } matcher.Advance(-1); if (matcher.Opcode != OpCodes.Nop && (matcher.Opcode != OpCodes.Call || !matcher.Instruction.OperandIs(AccessTools.Method(typeof(GC), nameof(GC.Collect))))) return matcher.InstructionEnumeration(); var labels = matcher.Labels; matcher.Labels = new List