diff --git a/CheatEnabler/AbnormalDiabler.cs b/CheatEnabler/AbnormalDiabler.cs index 2ed428f..586c631 100644 --- a/CheatEnabler/AbnormalDiabler.cs +++ b/CheatEnabler/AbnormalDiabler.cs @@ -7,6 +7,19 @@ public static class AbnormalDisabler { public static ConfigEntry Enabled; private static Dictionary _savedDeterminators; + private static Harmony _patch; + + public static void Init() + { + _patch = Harmony.CreateAndPatchAll(typeof(AbnormalDisabler)); + } + + public static void Uninit() + { + if (_patch == null) return; + _patch.UnpatchSelf(); + _patch = null; + } [HarmonyPrefix] [HarmonyPatch(typeof(AbnormalityLogic), "NotifyBeforeGameSave")] diff --git a/CheatEnabler/CheatEnabler.cs b/CheatEnabler/CheatEnabler.cs index 0e2fc3e..11cc50b 100644 --- a/CheatEnabler/CheatEnabler.cs +++ b/CheatEnabler/CheatEnabler.cs @@ -5,6 +5,8 @@ using System.Reflection.Emit; using BepInEx; using BepInEx.Configuration; using HarmonyLib; +using UnityEngine; +using UnityEngine.UI; namespace CheatEnabler; @@ -14,11 +16,9 @@ public class CheatEnabler : BaseUnityPlugin public new static readonly BepInEx.Logging.ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME); - private static bool _initialized = false; + private static bool _configWinInitialized = false; private static KeyboardShortcut _shortcut = KeyboardShortcut.Deserialize("H + LeftControl"); private static UIConfigWindow _configWin; - private bool _alwaysInfiniteResource = true; - private bool _waterPumpAnywhere = true; private static bool _sitiVeinsOnBirthPlanet = true; private static bool _fireIceOnBirthPlanet = false; private static bool _kimberliteOnBirthPlanet = false; @@ -32,18 +32,25 @@ public class CheatEnabler : BaseUnityPlugin private static bool _terraformAnyway = false; private static string _unlockTechToMaximumLevel = ""; private static readonly List TechToUnlock = new(); + + private static Harmony _windowPatch; + private static Harmony _patch; + + private static bool _initialized; private void Awake() { DevShortcuts.Enabled = Config.Bind("General", "DevShortcuts", true, "enable DevMode shortcuts"); AbnormalDisabler.Enabled = Config.Bind("General", "DisableAbnormalChecks", false, "disable all abnormal checks"); - _alwaysInfiniteResource = Config.Bind("General", "AlwaysInfiniteResource", _alwaysInfiniteResource, - "always infinite resource").Value; + ResourcePatch.InfiniteEnabled = Config.Bind("Planet", "AlwaysInfiniteResource", false, + "always infinite natural resource"); + ResourcePatch.FastEnabled = Config.Bind("Planet", "FastMining", false, + "super-fast mining speed"); _unlockTechToMaximumLevel = Config.Bind("General", "UnlockTechToMaxLevel", _unlockTechToMaximumLevel, "Unlock listed tech to MaxLevel").Value; - _waterPumpAnywhere = Config.Bind("General", "WaterPumpAnywhere", _waterPumpAnywhere, - "Can pump water anywhere (while water type is not None)").Value; + WaterPumperPatch.Enabled = Config.Bind("Planet", "WaterPumpAnywhere", false, + "Can pump water anywhere (while water type is not None)"); _sitiVeinsOnBirthPlanet = Config.Bind("Birth", "SiTiVeinsOnBirthPlanet", _sitiVeinsOnBirthPlanet, "Has Silicon/Titanium veins on birth planet").Value; _fireIceOnBirthPlanet = Config.Bind("Birth", "FireIceOnBirthPlanet", _fireIceOnBirthPlanet, @@ -68,18 +75,22 @@ public class CheatEnabler : BaseUnityPlugin "Can do terraform without enough sands").Value; I18N.Init(); + I18N.Add("CheatEnabler Config", "CheatEnabler Config", "CheatEnabler设置"); + I18N.Add("General", "General", "常规"); + I18N.Add("Enable Dev Shortcuts", "Enable Dev Shortcuts", "启用开发模式快捷键"); + I18N.Add("Disable Abnormal Checks", "Disable Abnormal Checks", "关闭数据异常检查"); + I18N.Add("Planet", "Planet", "行星"); + I18N.Add("Infinite Natural Resources", "Infinite Natural Resources", "自然资源采集不消耗"); + I18N.Add("Fast Mining", "Fast Mining", "高速采集"); + I18N.Add("Pump Anywhere", "Pump Anywhere", "平地抽水"); // UI Patch - Harmony.CreateAndPatchAll(typeof(UI.MyWindowManager.Patch)); - Harmony.CreateAndPatchAll(typeof(CheatEnabler)); + _windowPatch = Harmony.CreateAndPatchAll(typeof(UI.MyWindowManager.Patch)); + _patch = Harmony.CreateAndPatchAll(typeof(CheatEnabler)); - Harmony.CreateAndPatchAll(typeof(DevShortcuts)); - Harmony.CreateAndPatchAll(typeof(AbnormalDisabler)); - - if (_alwaysInfiniteResource) - { - Harmony.CreateAndPatchAll(typeof(AlwaysInfiniteResource)); - } + DevShortcuts.Init(); + AbnormalDisabler.Init(); + ResourcePatch.Init(); foreach (var idstr in _unlockTechToMaximumLevel.Split(',')) { @@ -94,10 +105,7 @@ public class CheatEnabler : BaseUnityPlugin Harmony.CreateAndPatchAll(typeof(UnlockTechOnGameStart)); } - if (_waterPumpAnywhere) - { - Harmony.CreateAndPatchAll(typeof(WaterPumperCheat)); - } + WaterPumperPatch.Init(); if (_sitiVeinsOnBirthPlanet || _fireIceOnBirthPlanet || _kimberliteOnBirthPlanet || _fractalOnBirthPlanet || _organicOnBirthPlanet || _opticalOnBirthPlanet || _spiniformOnBirthPlanet || _unipolarOnBirthPlanet || @@ -111,83 +119,69 @@ public class CheatEnabler : BaseUnityPlugin Harmony.CreateAndPatchAll(typeof(TerraformAnyway)); } } - + + public void OnDestroy() + { + WaterPumperPatch.Uninit(); + ResourcePatch.Uninit(); + AbnormalDisabler.Uninit(); + DevShortcuts.Uninit(); + _patch?.UnpatchSelf(); + _windowPatch?.UnpatchSelf(); + } + private void Update() { - if (!GameMain.isRunning) - { - return; - } - if (VFInput.inputing) { return; } if (_shortcut.IsDown()) - { - if (_configWin.active) - { - _configWin._Close(); - } - else - { - UIRoot.instance.uiGame.ShutPlayerInventory(); - _configWin.Open(); - } - } + ShowConfigWindow(); } - [HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnCreate")] - public static void UIGame__OnCreate_Postfix() + [HarmonyPostfix, HarmonyPatch(typeof(UIRoot), "_OnOpen")] + public static void UIRoot__OnOpen_Postfix() { if (_initialized) return; + var mainMenu = UIRoot.instance.uiMainMenu; + var src = mainMenu.newGameButton.gameObject; + var parent = src.transform.parent; + var btn = Instantiate(src, parent); + btn.name = "btn-cheatenabler-config"; + var btnConfig = btn.GetComponent(); + btnConfig.text.text = "CheatEnabler Config"; + btnConfig.text.fontSize = btnConfig.text.fontSize * 7 / 8; + I18N.OnInitialized += () => + { + btnConfig.text.text = "CheatEnabler Config".Translate(); + }; + btnConfig.transform.SetParent(parent); + var vec = ((RectTransform)mainMenu.exitButton.transform).anchoredPosition3D; + var vec2 = ((RectTransform)mainMenu.creditsButton.transform).anchoredPosition3D; + var transform1 = (RectTransform)btn.transform; + transform1.anchoredPosition3D = new Vector3(vec.x, vec.y + (vec.y - vec2.y) * 2, vec.z); + btnConfig.button.onClick.AddListener(ShowConfigWindow); _initialized = true; - _configWin = UIConfigWindow.CreateInstance(); } - private class AlwaysInfiniteResource + private static void ShowConfigWindow() { - [HarmonyTranspiler] - [HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool))] - [HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool), typeof(int), typeof(int), - typeof(int))] - [HarmonyPatch(typeof(ItemProto), "GetPropValue")] - [HarmonyPatch(typeof(PlanetTransport), "GameTick")] - [HarmonyPatch(typeof(UIMinerWindow), "_OnUpdate")] - [HarmonyPatch(typeof(UIMiningUpgradeLabel), "Update")] - [HarmonyPatch(typeof(UIPlanetDetail), "OnPlanetDataSet")] - [HarmonyPatch(typeof(UIPlanetDetail), "RefreshDynamicProperties")] - [HarmonyPatch(typeof(UIStarDetail), "OnStarDataSet")] - [HarmonyPatch(typeof(UIStarDetail), "RefreshDynamicProperties")] - [HarmonyPatch(typeof(UIStationStorage), "RefreshValues")] - [HarmonyPatch(typeof(UIVeinCollectorPanel), "_OnUpdate")] - private static IEnumerable Transpiler(IEnumerable instructions) + if (!_configWinInitialized) { - foreach (var instruction in instructions) - { - if (instruction.opcode == OpCodes.Ldfld && instruction.OperandIs(AccessTools.Field(typeof(GameHistoryData), "miningCostRate"))) - { - yield return new CodeInstruction(OpCodes.Pop); - yield return new CodeInstruction(OpCodes.Ldc_R4, 0f); - } - else if (instruction.opcode == OpCodes.Ldfld && instruction.OperandIs(AccessTools.Field(typeof(GameHistoryData), "miningSpeedScale"))) - { - yield return new CodeInstruction(OpCodes.Pop); - yield return new CodeInstruction(OpCodes.Ldc_R4, 720f); - } - else - { - yield return instruction; - } - } + _configWinInitialized = true; + _configWin = UIConfigWindow.CreateInstance(); } - [HarmonyPrefix, HarmonyPatch(typeof(BuildTool_BlueprintPaste), "get_bMeetTech")] - private static bool BuildTool_BlueprintPaste_get_bMeetTech_Prefix(ref bool __result) + if (_configWin.active) { - __result = true; - return false; + _configWin._Close(); + } + else + { + UIRoot.instance.uiGame.ShutPlayerInventory(); + _configWin.Open(); } } @@ -352,35 +346,6 @@ public class CheatEnabler : BaseUnityPlugin } } - private class WaterPumperCheat - { - [HarmonyTranspiler] - [HarmonyPatch(typeof(BuildTool_BlueprintPaste), "CheckBuildConditions")] - [HarmonyPatch(typeof(BuildTool_Click), "CheckBuildConditions")] - private static IEnumerable BuildTool_CheckBuildConditions_Transpiler( - IEnumerable instructions) - { - var isFirst = true; - foreach (var instr in instructions) - { - if (instr.opcode == OpCodes.Ldc_I4_S && instr.OperandIs(22)) - { - if (isFirst) - { - isFirst = false; - } - else - { - yield return new CodeInstruction(OpCodes.Ldc_I4_S, 0); - continue; - } - } - - yield return instr; - } - } - } - private class TerraformAnyway { [HarmonyTranspiler] diff --git a/CheatEnabler/DevShortcuts.cs b/CheatEnabler/DevShortcuts.cs index caed4ba..bdedf1d 100644 --- a/CheatEnabler/DevShortcuts.cs +++ b/CheatEnabler/DevShortcuts.cs @@ -2,9 +2,22 @@ using HarmonyLib; namespace CheatEnabler; -public class DevShortcuts +public static class DevShortcuts { public static ConfigEntry Enabled; + private static Harmony _patch; + + public static void Init() + { + _patch = Harmony.CreateAndPatchAll(typeof(DevShortcuts)); + } + + public static void Uninit() + { + if (_patch == null) return; + _patch.UnpatchSelf(); + _patch = null; + } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerController), "Init")] diff --git a/CheatEnabler/I18N.cs b/CheatEnabler/I18N.cs index 1b7cd03..fc3db83 100644 --- a/CheatEnabler/I18N.cs +++ b/CheatEnabler/I18N.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using HarmonyLib; @@ -6,13 +7,67 @@ namespace CheatEnabler; public class I18N { + private static bool _initialized; + + public static Action OnInitialized; + public static void Init() { Harmony.CreateAndPatchAll(typeof(I18N)); } - private static int _nextID = 0; + private static int _nextID = 1; private static readonly List StringsToAdd = new(); public static void Add(string key, string enus, string zhcn = null, string frfr = null) + { + var strings = LDB._strings; + var strProto = new StringProto + { + Name = key, + SID = "", + ENUS = enus, + ZHCN = string.IsNullOrEmpty(zhcn) ? enus : zhcn, + FRFR = string.IsNullOrEmpty(frfr) ? enus : frfr + }; + if (_initialized) + { + var index = strings.dataArray.Length; + strProto.ID = GetNextID(); + strings.dataArray = strings.dataArray.Append(strProto).ToArray(); + strings.dataIndices[strProto.ID] = index; + strings.nameIndices[strProto.Name] = index; + } + else + { + StringsToAdd.Add(strProto); + } + } + + [HarmonyPostfix, HarmonyPriority(Priority.Last), HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")] + private static void VFPreload_InvokeOnLoadWorkEnded_Postfix() + { + if (_initialized) return; + _initialized = true; + if (StringsToAdd.Count == 0) + { + OnInitialized?.Invoke(); + return; + } + var strings = LDB._strings; + var index = strings.dataArray.Length; + strings.dataArray = strings.dataArray.Concat(StringsToAdd).ToArray(); + StringsToAdd.Clear(); + var newIndex = strings.dataArray.Length; + for (; index < newIndex; index++) + { + var strProto = strings.dataArray[index]; + strProto.ID = GetNextID(); + strings.dataIndices[strProto.ID] = index; + strings.nameIndices[strings.dataArray[index].Name] = index; + } + OnInitialized?.Invoke(); + } + + private static int GetNextID() { var strings = LDB._strings; while (_nextID <= 12000) @@ -24,38 +79,9 @@ public class I18N _nextID++; } - var strProto = new StringProto - { - Name = key, - ID = _nextID, - SID = "", - ENUS = enus, - ZHCN = string.IsNullOrEmpty(zhcn) ? enus : zhcn, - FRFR = string.IsNullOrEmpty(frfr) ? enus : frfr - }; - StringsToAdd.Add(strProto); - _nextID++; - } - private static bool _initialized = false; - [HarmonyPostfix, HarmonyPriority(Priority.Last), HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")] - private static void VFPreload_InvokeOnLoadWorkEnded_Postfix() - { - if (_initialized) return; - _initialized = true; - if (StringsToAdd.Count == 0) - { - return; - } - var strings = LDB._strings; - var index = strings.dataArray.Length; - strings.dataArray = strings.dataArray.Concat(StringsToAdd).ToArray(); - StringsToAdd.Clear(); - var newIndex = strings.dataArray.Length; - for (; index < newIndex; index++) - { - strings.dataIndices[strings.dataArray[index].ID] = index; - strings.nameIndices[strings.dataArray[index].Name] = index; - } + var result = _nextID; + _nextID++; + return result; } } \ No newline at end of file diff --git a/CheatEnabler/ResourcePatch.cs b/CheatEnabler/ResourcePatch.cs new file mode 100644 index 0000000..e48b8c2 --- /dev/null +++ b/CheatEnabler/ResourcePatch.cs @@ -0,0 +1,136 @@ +using System.Collections.Generic; +using System.Reflection.Emit; +using BepInEx.Configuration; +using HarmonyLib; + +namespace CheatEnabler; + +public static class ResourcePatch +{ + public static ConfigEntry InfiniteEnabled; + public static ConfigEntry FastEnabled; + private static Harmony _infinitePatch; + private static Harmony _fastPatch; + + public static void Init() + { + InfiniteEnabled.SettingChanged += (_, _) => InfiniteValueChanged(); + FastEnabled.SettingChanged += (_, _) => FastValueChanged(); + InfiniteValueChanged(); + FastValueChanged(); + } + + public static void Uninit() + { + if (_infinitePatch != null) + { + _infinitePatch.UnpatchSelf(); + _infinitePatch = null; + } + + if (_fastPatch != null) + { + _fastPatch.UnpatchSelf(); + _fastPatch = null; + } + } + + private static void InfiniteValueChanged() + { + if (InfiniteEnabled.Value) + { + if (_infinitePatch != null) + { + _infinitePatch.UnpatchSelf(); + _infinitePatch = null; + } + + _infinitePatch = Harmony.CreateAndPatchAll(typeof(InfiniteResource)); + } + else if (_infinitePatch != null) + { + _infinitePatch.UnpatchSelf(); + _infinitePatch = null; + } + } + private static void FastValueChanged() + { + if (FastEnabled.Value) + { + if (_fastPatch != null) + { + _fastPatch.UnpatchSelf(); + _fastPatch = null; + } + + _fastPatch = Harmony.CreateAndPatchAll(typeof(FastMining)); + } + else if (_fastPatch != null) + { + _fastPatch.UnpatchSelf(); + _fastPatch = null; + } + } + + private static class InfiniteResource + { + [HarmonyTranspiler] + [HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool))] + [HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool), typeof(int), typeof(int), + typeof(int))] + [HarmonyPatch(typeof(ItemProto), "GetPropValue")] + [HarmonyPatch(typeof(PlanetTransport), "GameTick")] + [HarmonyPatch(typeof(UIMinerWindow), "_OnUpdate")] + [HarmonyPatch(typeof(UIMiningUpgradeLabel), "Update")] + [HarmonyPatch(typeof(UIPlanetDetail), "OnPlanetDataSet")] + [HarmonyPatch(typeof(UIPlanetDetail), "RefreshDynamicProperties")] + [HarmonyPatch(typeof(UIStarDetail), "OnStarDataSet")] + [HarmonyPatch(typeof(UIStarDetail), "RefreshDynamicProperties")] + [HarmonyPatch(typeof(UIStationStorage), "RefreshValues")] + [HarmonyPatch(typeof(UIVeinCollectorPanel), "_OnUpdate")] + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(GameHistoryData), nameof(GameHistoryData.miningCostRate))) + ).Repeat(codeMatcher => + codeMatcher.RemoveInstruction().InsertAndAdvance( + new CodeInstruction(OpCodes.Pop), + new CodeInstruction(OpCodes.Ldc_R4, 0f) + ) + ); + return matcher.InstructionEnumeration(); + } + } + + private static class FastMining + { + [HarmonyTranspiler] + [HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool))] + [HarmonyPatch(typeof(FactorySystem), "GameTick", typeof(long), typeof(bool), typeof(int), typeof(int), + typeof(int))] + [HarmonyPatch(typeof(ItemProto), "GetPropValue")] + [HarmonyPatch(typeof(PlanetTransport), "GameTick")] + [HarmonyPatch(typeof(UIMinerWindow), "_OnUpdate")] + [HarmonyPatch(typeof(UIMiningUpgradeLabel), "Update")] + [HarmonyPatch(typeof(UIPlanetDetail), "OnPlanetDataSet")] + [HarmonyPatch(typeof(UIPlanetDetail), "RefreshDynamicProperties")] + [HarmonyPatch(typeof(UIStarDetail), "OnStarDataSet")] + [HarmonyPatch(typeof(UIStarDetail), "RefreshDynamicProperties")] + [HarmonyPatch(typeof(UIStationStorage), "RefreshValues")] + [HarmonyPatch(typeof(UIVeinCollectorPanel), "_OnUpdate")] + private static IEnumerable Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(GameHistoryData), nameof(GameHistoryData.miningSpeedScale))) + ).Repeat(codeMatcher => + codeMatcher.RemoveInstruction().InsertAndAdvance( + new CodeInstruction(OpCodes.Pop), + new CodeInstruction(OpCodes.Ldc_R4, 720f) + ) + ); + return matcher.InstructionEnumeration(); + } + } +} \ No newline at end of file diff --git a/CheatEnabler/UI/MyWindow.cs b/CheatEnabler/UI/MyWindow.cs index f3a2e0f..99492b8 100644 --- a/CheatEnabler/UI/MyWindow.cs +++ b/CheatEnabler/UI/MyWindow.cs @@ -213,13 +213,13 @@ public class MyWindowWithTabs : MyWindow public static class MyWindowManager { private static readonly List Windows = new(4); - private static bool _initialized = false; + private static bool _initialized; public static T CreateWindow(string name, string title = "") where T : MyWindow { var srcWin = UIRoot.instance.uiGame.tankWindow; var src = srcWin.gameObject; - var go = Object.Instantiate(src, srcWin.transform.parent); + var go = Object.Instantiate(src, UIRoot.instance.uiGame.transform.parent); go.name = name; go.SetActive(false); Object.Destroy(go.GetComponent()); @@ -275,19 +275,21 @@ public static class MyWindowManager } */ - [HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnDestroy")] - public static void UIGame__OnDestroy_Postfix() + [HarmonyPostfix, HarmonyPatch(typeof(UIRoot), "_OnDestroy")] + public static void UIRoot__OnDestroy_Postfix() { foreach (var win in Windows) { + win._Free(); win._Destroy(); } Windows.Clear(); } - [HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnInit")] - public static void UIGame__OnInit_Postfix(UIGame __instance) + [HarmonyPostfix, HarmonyPatch(typeof(UIRoot), "_OnOpen")] + public static void UIRoot__OnOpen_Postfix() { + if (_initialized) return; foreach (var win in Windows) { win._Init(win.data); @@ -295,6 +297,7 @@ public static class MyWindowManager _initialized = true; } + /* [HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnFree")] public static void UIGame__OnFree_Postfix() { @@ -303,9 +306,10 @@ public static class MyWindowManager win._Free(); } } + */ - [HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnUpdate")] - public static void UIGame__OnUpdate_Postfix() + [HarmonyPostfix, HarmonyPatch(typeof(UIRoot), "_OnUpdate")] + public static void UIRoot__OnUpdate_Postfix() { if (GameMain.isPaused || !GameMain.isRunning) { diff --git a/CheatEnabler/UIConfigWindow.cs b/CheatEnabler/UIConfigWindow.cs index 25744b5..84ef9a5 100644 --- a/CheatEnabler/UIConfigWindow.cs +++ b/CheatEnabler/UIConfigWindow.cs @@ -8,7 +8,7 @@ public class UIConfigWindow : UI.MyWindowWithTabs public static UIConfigWindow CreateInstance() { - return UI.MyWindowManager.CreateWindow("CEConfigWindow", "CheatEnabler Config"); + return UI.MyWindowManager.CreateWindow("CEConfigWindow", "CheatEnabler Config".Translate()); } public override void _OnCreate() @@ -21,13 +21,23 @@ public class UIConfigWindow : UI.MyWindowWithTabs private void CreateUI() { - //General tab - var tab1 = AddTab(36f, 0, _windowTrans, "General"); + // General tab var x = 0f; var y = 0f; - UI.MyCheckBox.CreateCheckBox(x, y, tab1, DevShortcuts.Enabled, "Enable Dev Shortcuts"); + var tab1 = AddTab(36f, 0, _windowTrans, "General".Translate()); + UI.MyCheckBox.CreateCheckBox(x, y, tab1, DevShortcuts.Enabled, "Enable Dev Shortcuts".Translate()); y += 26f; - UI.MyCheckBox.CreateCheckBox(x, y, tab1, AbnormalDisabler.Enabled, "Disable Abnormal Checks"); + UI.MyCheckBox.CreateCheckBox(x, y, tab1, AbnormalDisabler.Enabled, "Disable Abnormal Checks".Translate()); + + // Planet Tab + var tab2 = AddTab(136f, 1, _windowTrans, "Planet".Translate()); + x = 0f; + y = 0f; + UI.MyCheckBox.CreateCheckBox(x, y, tab2, ResourcePatch.InfiniteEnabled, "Infinite Natural Resources".Translate()); + y += 26f; + UI.MyCheckBox.CreateCheckBox(x, y, tab2, ResourcePatch.FastEnabled, "Fast Mining".Translate()); + y += 26f; + UI.MyCheckBox.CreateCheckBox(x, y, tab2, WaterPumperPatch.Enabled, "Pump Anywhere".Translate()); SetCurrentTab(0); } diff --git a/CheatEnabler/WaterPumpPatch.cs b/CheatEnabler/WaterPumpPatch.cs new file mode 100644 index 0000000..1876472 --- /dev/null +++ b/CheatEnabler/WaterPumpPatch.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; +using System.Reflection.Emit; +using BepInEx.Configuration; +using HarmonyLib; + +namespace CheatEnabler; +public static class WaterPumperPatch +{ + public static ConfigEntry Enabled; + private static Harmony _patch; + + public static void Init() + { + Enabled.SettingChanged += (_, _) => ValueChanged(); + ValueChanged(); + } + + public static void Uninit() + { + if (_patch == null) return; + _patch.UnpatchSelf(); + _patch = null; + } + + private static void ValueChanged() + { + if (Enabled.Value) + { + if (_patch != null) + { + _patch.UnpatchSelf(); + _patch = null; + } + + _patch = Harmony.CreateAndPatchAll(typeof(WaterPumperPatch)); + } + else if (_patch != null) + { + _patch.UnpatchSelf(); + _patch = null; + } + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(BuildTool_BlueprintPaste), "CheckBuildConditions")] + [HarmonyPatch(typeof(BuildTool_Click), "CheckBuildConditions")] + private static IEnumerable BuildTool_CheckBuildConditions_Transpiler( + IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(instr => instr.opcode == OpCodes.Ldc_I4_S && instr.OperandIs(22)) + ).Advance(1).MatchForward(false, + new CodeMatch(instr => instr.opcode == OpCodes.Ldc_I4_S && instr.OperandIs(22)) + ); + matcher.Repeat(codeMatcher => + { + codeMatcher.SetAndAdvance(OpCodes.Ldc_I4_S, 0); + }); + return matcher.InstructionEnumeration(); + } +} \ No newline at end of file diff --git a/UniverseGenTweaks/I18N.cs b/UniverseGenTweaks/I18N.cs index 33e1ba7..bfe6b2a 100644 --- a/UniverseGenTweaks/I18N.cs +++ b/UniverseGenTweaks/I18N.cs @@ -6,38 +6,39 @@ namespace UniverseGenTweaks; public class I18N { + private static bool _initialized; + public static void Init() { Harmony.CreateAndPatchAll(typeof(I18N)); } - private static int _nextID = 0; + private static int _nextID = 1; private static readonly List StringsToAdd = new(); public static void Add(string key, string enus, string zhcn = null, string frfr = null) { var strings = LDB._strings; - while (_nextID <= 12000) - { - if (!strings.dataIndices.ContainsKey(_nextID)) - { - break; - } - - _nextID++; - } var strProto = new StringProto { Name = key, - ID = _nextID, SID = "", ENUS = enus, ZHCN = string.IsNullOrEmpty(zhcn) ? enus : zhcn, FRFR = string.IsNullOrEmpty(frfr) ? enus : frfr }; - StringsToAdd.Add(strProto); - _nextID++; + if (_initialized) + { + var index = strings.dataArray.Length; + strProto.ID = GetNextID(); + strings.dataArray = strings.dataArray.Append(strProto).ToArray(); + strings.dataIndices[strProto.ID] = index; + strings.nameIndices[strProto.Name] = index; + } + else + { + StringsToAdd.Add(strProto); + } } - private static bool _initialized = false; [HarmonyPostfix, HarmonyPriority(Priority.Last), HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")] private static void VFPreload_InvokeOnLoadWorkEnded_Postfix() { @@ -54,8 +55,28 @@ public class I18N var newIndex = strings.dataArray.Length; for (; index < newIndex; index++) { - strings.dataIndices[strings.dataArray[index].ID] = index; + var strProto = strings.dataArray[index]; + strProto.ID = GetNextID(); + strings.dataIndices[strProto.ID] = index; strings.nameIndices[strings.dataArray[index].Name] = index; } } + + private static int GetNextID() + { + var strings = LDB._strings; + while (_nextID <= 12000) + { + if (!strings.dataIndices.ContainsKey(_nextID)) + { + break; + } + + _nextID++; + } + + var result = _nextID; + _nextID++; + return result; + } } \ No newline at end of file