From 9c5523fb371d2297050f6d28f6c982247ca81b72 Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Mon, 11 Sep 2023 02:39:18 +0800 Subject: [PATCH] WIP --- CheatEnabler/BirthPlanetPatch.cs | 6 +- CheatEnabler/CheatEnabler.cs | 62 +++++--- CheatEnabler/CheatEnabler.csproj | 3 +- CheatEnabler/DysonSpherePatch.cs | 182 +++++++++++++++++++++- CheatEnabler/UI/MyKeyBinder.cs | 237 +++++++++++++++++++++++++++++ CheatEnabler/UIConfigWindow.cs | 3 + CheatEnabler/package/manifest.json | 2 +- 7 files changed, 466 insertions(+), 29 deletions(-) create mode 100644 CheatEnabler/UI/MyKeyBinder.cs diff --git a/CheatEnabler/BirthPlanetPatch.cs b/CheatEnabler/BirthPlanetPatch.cs index 18ef0a3..2e6a358 100644 --- a/CheatEnabler/BirthPlanetPatch.cs +++ b/CheatEnabler/BirthPlanetPatch.cs @@ -31,6 +31,7 @@ public static class BirthPlanetPatch _rareVeins = theme.RareVeins.Clone() as int[]; _rareSettings = theme.RareSettings.Clone() as float[]; _specifyBirthStarMass = StarGen.specifyBirthStarMass; + _specifyBirthStarAge = StarGen.specifyBirthStarAge; _inited = true; } @@ -44,6 +45,7 @@ public static class BirthPlanetPatch theme.RareVeins = _rareVeins.Clone() as int[]; theme.RareSettings = _rareSettings.Clone() as float[]; StarGen.specifyBirthStarMass = _specifyBirthStarMass; + StarGen.specifyBirthStarAge = _specifyBirthStarAge; } private bool _inited; @@ -54,6 +56,7 @@ public static class BirthPlanetPatch private int[] _rareVeins; private float[] _rareSettings; private float _specifyBirthStarMass; + private float _specifyBirthStarAge; } public static void Init() @@ -164,7 +167,8 @@ public static class BirthPlanetPatch if (HighLuminosityBirthStar.Value) { - StarGen.specifyBirthStarMass = 100f; + StarGen.specifyBirthStarMass = 53.81f; + StarGen.specifyBirthStarAge = 0.01f; } _initialized = true; diff --git a/CheatEnabler/CheatEnabler.cs b/CheatEnabler/CheatEnabler.cs index e1a1d0a..57cac19 100644 --- a/CheatEnabler/CheatEnabler.cs +++ b/CheatEnabler/CheatEnabler.cs @@ -16,8 +16,8 @@ public class CheatEnabler : BaseUnityPlugin public new static readonly BepInEx.Logging.ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME); + public static ConfigEntry Hotkey; private static bool _configWinInitialized = false; - private static KeyboardShortcut _shortcut = KeyboardShortcut.Deserialize("H + LeftControl"); private static UIConfigWindow _configWin; private static string _unlockTechToMaximumLevel = ""; private static readonly List TechToUnlock = new(); @@ -29,7 +29,8 @@ public class CheatEnabler : BaseUnityPlugin private void Awake() { - DevShortcuts.Enabled = Config.Bind("General", "DevShortcuts", true, "enable DevMode shortcuts"); + Hotkey = Config.Bind("General", "Shortcut", KeyboardShortcut.Deserialize("BackQuote + LeftAlt"), "Shortcut to open config window"); + DevShortcuts.Enabled = Config.Bind("General", "DevShortcuts", true, "Enable DevMode shortcuts"); AbnormalDisabler.Enabled = Config.Bind("General", "DisableAbnormalChecks", false, "disable all abnormal checks"); BuildPatch.ImmediateEnabled = Config.Bind("Build", "ImmediateBuild", false, @@ -76,8 +77,8 @@ public class CheatEnabler : BaseUnityPlugin "Birth planet is solid flat (no water at all)"); BirthPlanetPatch.HighLuminosityBirthStar = Config.Bind("Birth", "HighLuminosityBirthStar", false, "Birth star has high luminosity"); - _unlockTechToMaximumLevel = Config.Bind("General", "UnlockTechToMaxLevel", _unlockTechToMaximumLevel, - "Unlock listed tech to MaxLevel").Value; + // _unlockTechToMaximumLevel = Config.Bind("General", "UnlockTechToMaxLevel", _unlockTechToMaximumLevel, + // "Unlock listed tech to MaxLevel").Value; I18N.Init(); I18N.Add("CheatEnabler Config", "CheatEnabler Config", "CheatEnabler设置"); @@ -95,17 +96,17 @@ public class CheatEnabler : BaseUnityPlugin TerraformPatch.Init(); DysonSpherePatch.Init(); BirthPlanetPatch.Init(); - foreach (var idstr in _unlockTechToMaximumLevel.Split(',')) - { - if (int.TryParse(idstr, out var id)) - { - TechToUnlock.Add(id); - } - } - if (TechToUnlock.Count > 0) - { - Harmony.CreateAndPatchAll(typeof(UnlockTechOnGameStart)); - } + // foreach (var idstr in _unlockTechToMaximumLevel.Split(',')) + // { + // if (int.TryParse(idstr, out var id)) + // { + // TechToUnlock.Add(id); + // } + // } + // if (TechToUnlock.Count > 0) + // { + // Harmony.CreateAndPatchAll(typeof(UnlockTechOnGameStart)); + // } } public void OnDestroy() @@ -129,8 +130,8 @@ public class CheatEnabler : BaseUnityPlugin return; } - if (_shortcut.IsDown()) - ShowConfigWindow(); + if (Hotkey.Value.IsDown()) + ToggleConfigWindow(); } [HarmonyPostfix, HarmonyPatch(typeof(UIRoot), nameof(UIRoot.OpenMainMenuUI))] @@ -157,7 +158,7 @@ public class CheatEnabler : BaseUnityPlugin var transform1 = (RectTransform)btn.transform; transform1.anchoredPosition3D = new Vector3(vec.x, vec.y + (vec.y - vec2.y) * 2, vec.z); btn.button.onClick.RemoveAllListeners(); - btn.button.onClick.AddListener(ShowConfigWindow); + btn.button.onClick.AddListener(ToggleConfigWindow); } { var panel = UIRoot.instance.uiGame.planetGlobe; @@ -179,7 +180,7 @@ public class CheatEnabler : BaseUnityPlugin rect.localScale = new Vector3(0.5f, 0.5f, 0.5f); rect.anchoredPosition3D = new Vector3(128f, -105f, 0f); b.onClick.RemoveAllListeners(); - btn.onClick += (_) => { ShowConfigWindow(); }; + btn.onClick += (_) => { ToggleConfigWindow(); }; btn.tips.tipTitle = "CheatEnabler Config"; I18N.OnInitialized += () => { btn.tips.tipTitle = "CheatEnabler Config".Translate(); }; btn.tips.tipText = null; @@ -191,7 +192,26 @@ public class CheatEnabler : BaseUnityPlugin _initialized = true; } - private static void ShowConfigWindow() + [HarmonyTranspiler] + [HarmonyPatch(typeof(UIBuildMenu), nameof(UIBuildMenu._OnUpdate))] + private static IEnumerable UIBuildMenu__OnUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.inScreen))) + ); + matcher.Repeat(codeMatcher => + { + var jumpPos = codeMatcher.Advance(1).Operand; + codeMatcher.Advance(-1).InsertAndAdvance( + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.noModifier))), + new CodeInstruction(OpCodes.Brfalse_S, jumpPos) + ).Advance(2); + }); + return matcher.InstructionEnumeration(); + } + + private static void ToggleConfigWindow() { if (!_configWinInitialized) { @@ -210,6 +230,7 @@ public class CheatEnabler : BaseUnityPlugin } } + /* private class UnlockTechOnGameStart { [HarmonyPostfix] @@ -296,5 +317,6 @@ public class CheatEnabler : BaseUnityPlugin techStates[currentTech] = value; } } + */ } \ No newline at end of file diff --git a/CheatEnabler/CheatEnabler.csproj b/CheatEnabler/CheatEnabler.csproj index 321d489..738ff59 100644 --- a/CheatEnabler/CheatEnabler.csproj +++ b/CheatEnabler/CheatEnabler.csproj @@ -4,7 +4,7 @@ net472 org.soardev.cheatenabler DSP MOD - CheatEnabler - 1.0.0 + 2.0.0 true latest CheatEnabler @@ -22,6 +22,7 @@ + diff --git a/CheatEnabler/DysonSpherePatch.cs b/CheatEnabler/DysonSpherePatch.cs index 0adef9b..2319411 100644 --- a/CheatEnabler/DysonSpherePatch.cs +++ b/CheatEnabler/DysonSpherePatch.cs @@ -1,8 +1,8 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; -using PowerNetworkStructures; namespace CheatEnabler; @@ -62,6 +62,9 @@ public static class DysonSpherePatch _skipBulletPatch.UnpatchSelf(); _skipBulletPatch = null; } + + SkipBulletPatch.UpdateSailLifeTime(); + SkipBulletPatch.UpdateSailsCacheForThisGame(); _skipBulletPatch = Harmony.CreateAndPatchAll(typeof(SkipBulletPatch)); } else if (_skipBulletPatch != null) @@ -127,13 +130,148 @@ public static class DysonSpherePatch private static class SkipBulletPatch { + private static long _sailLifeTime; + private static DysonSailCache[][] _sailsCache; + private static int[] _sailsCacheLen, _sailsCacheCapacity; + + private struct DysonSailCache + { + public DysonSail Sail; + public int OrbitId; + } + + public static void UpdateSailLifeTime() + { + if (GameMain.history == null) return; + _sailLifeTime = (long)(GameMain.history.solarSailLife * 60f + 0.1f); + } + + public static void UpdateSailsCacheForThisGame() + { + var galaxy = GameMain.data?.galaxy; + if (galaxy == null) return; + var starCount = GameMain.data.galaxy.starCount; + _sailsCache = new DysonSailCache[starCount][]; + _sailsCacheLen = new int[starCount]; + _sailsCacheCapacity = new int[starCount]; + Array.Clear(_sailsCacheLen, 0, starCount); + Array.Clear(_sailsCacheCapacity, 0, starCount); + } + + private static void SetSailsCacheCapacity(int index, int capacity) + { + var newCache = new DysonSailCache[capacity]; + var len = _sailsCacheLen[index]; + if (len > 0) + { + Array.Copy(_sailsCache[index], newCache, len); + } + _sailsCache[index] = newCache; + _sailsCacheCapacity[index] = capacity; + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(GameData), nameof(GameData.NewGame))] + [HarmonyPatch(typeof(GameData), nameof(GameData.Import))] + private static void GameData_NewGame_Postfix() + { + UpdateSailsCacheForThisGame(); + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.SetForNewGame))] + [HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.Import))] + private static void GameHistoryData_SetForNewGame_Postfix() + { + UpdateSailLifeTime(); + } + [HarmonyPostfix] + [HarmonyPatch(typeof(GameHistoryData), nameof(GameHistoryData.UnlockTechFunction))] + private static void GameHistoryData_SetForNewGame_Postfix(int func) + { + if (func == 12) + { + UpdateSailLifeTime(); + } + } + [HarmonyTranspiler] [HarmonyPatch(typeof(EjectorComponent), nameof(EjectorComponent.InternalUpdate))] private static IEnumerable EjectorComponent_InternalUpdate_Patch(IEnumerable instructions, ILGenerator generator) { var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldc_R4, 10f) + ).Advance(2); + var start = matcher.Pos; + matcher.MatchForward(false, + new CodeMatch(OpCodes.Pop) + ).Advance(1); + var end = matcher.Pos; + matcher.Start().Advance(start).RemoveInstructions(end - start).Insert( + new CodeInstruction(OpCodes.Ldarg_2), + new CodeInstruction(OpCodes.Ldarg_0), + new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(EjectorComponent), nameof(EjectorComponent.orbitId))), + new CodeInstruction(OpCodes.Ldloc_S, 8), + new CodeInstruction(OpCodes.Ldloc_S, 10), + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(SkipBulletPatch), nameof(SkipBulletPatch.AddDysonSail))) + ); return matcher.InstructionEnumeration(); } + + private static void AddDysonSail(DysonSwarm swarm, int orbitId, VectorLF3 uPos, VectorLF3 endVec) + { + var index = swarm.starData.index; + var delta1 = endVec - swarm.starData.uPosition; + var delta2 = VectorLF3.Cross(endVec - uPos, swarm.orbits[orbitId].up).normalized * Math.Sqrt(swarm.dysonSphere.gravity / swarm.orbits[orbitId].radius) + + RandomTable.SphericNormal(ref swarm.randSeed, 0.5); + lock(swarm) + { + var cache = _sailsCache[index]; + var len = _sailsCacheLen[index]; + if (cache == null) + { + SetSailsCacheCapacity(index, 256); + cache = _sailsCache[index]; + } + else + { + var capacity = _sailsCacheCapacity[index]; + if (len >= capacity) + { + SetSailsCacheCapacity(index, capacity * 2); + cache = _sailsCache[index]; + } + } + _sailsCacheLen[index] = len + 1; + ref var sailCache = ref cache[len]; + ref var ss = ref sailCache.Sail; + ss.px = (float)delta1.x; + ss.py = (float)delta1.y; + ss.pz = (float)delta1.z; + ss.vx = (float)delta2.x; + ss.vy = (float)delta2.y; + ss.vz = (float)delta2.z; + ss.gs = 1f; + sailCache.OrbitId = orbitId; + } + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(DysonSwarm), "GameTick")] + public static void DysonSwarm_GameTick_Prefix(DysonSwarm __instance, long time) + { + var index = __instance.starData.index; + var len = _sailsCacheLen[index]; + if (len == 0) return; + _sailsCacheLen[index] = 0; + var cache = _sailsCache[index]; + var deadline = time + _sailLifeTime; + for (var i = len - 1; i >= 0; i--) + { + __instance.AddSolarSail(cache[i].Sail, cache[i].OrbitId, deadline); + } + } } private static class SkipAbsorbPatch @@ -188,17 +326,49 @@ public static class DysonSpherePatch private static class QuickAbsortPatch { + // [HarmonyPrefix] + // [HarmonyPatch(typeof(DysonSphereLayer), "GameTick")] + // public static void DysonSphereLayerGameTick(ref DysonSphereLayer __instance, long gameTick) + // { + // DysonSwarm swarm = __instance.dysonSphere.swarm; + // for (int i = __instance.nodeCursor - 1; i > 0; i--) + // { + // DysonNode dysonNode = __instance.nodePool[i]; + // if (dysonNode != null && dysonNode.id == i && dysonNode.sp == dysonNode.spMax) + // { + // dysonNode.OrderConstructCp(gameTick, swarm); + // } + // } + // } [HarmonyTranspiler] [HarmonyPatch(typeof(DysonSphereLayer), nameof(DysonSphereLayer.GameTick))] private static IEnumerable DysonSphereLayer_GameTick_Patch(IEnumerable instructions, ILGenerator generator) { var matcher = new CodeMatcher(instructions, generator); - /* Remove `dysonNode.id % 120 == num` */ - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldc_I4_S, 120) - ).Advance(-2).RemoveInstructions(6); + matcher.Start().InsertAndAdvance( + new CodeInstruction(OpCodes.Ldarg_0), + new CodeInstruction(OpCodes.Ldarg_1), + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(QuickAbsortPatch), nameof(QuickAbsortPatch.DoAbsorb))) + ).MatchForward(false, + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(DysonSphereLayer), nameof(DysonSphereLayer.dysonSphere))), + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(DysonSphere), nameof(DysonSphere.swarm))) + ).Insert(new CodeInstruction(OpCodes.Ret)); return matcher.InstructionEnumeration(); } + + private static void DoAbsorb(DysonSphereLayer layer, long gameTick) + { + var swarm = layer.dysonSphere.swarm; + for (var i = layer.nodeCursor - 1; i > 0; i--) + { + var node = layer.nodePool[i]; + if (node != null && node.id == i && node.sp == node.spMax) + { + node.OrderConstructCp(gameTick, swarm); + } + } + } } private static class EjectAnywayPatch diff --git a/CheatEnabler/UI/MyKeyBinder.cs b/CheatEnabler/UI/MyKeyBinder.cs new file mode 100644 index 0000000..f46e29c --- /dev/null +++ b/CheatEnabler/UI/MyKeyBinder.cs @@ -0,0 +1,237 @@ +using System; +using System.Linq; +using BepInEx.Configuration; +using UnityEngine; +using UnityEngine.UI; + +namespace CheatEnabler.UI; + +// MyKeyBinder modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyKeyBinder.cs +public class MyKeyBinder : MonoBehaviour +{ + private ConfigEntry _config; + + [SerializeField] + public Text functionText; + + [SerializeField] + public Text keyText; + + [SerializeField] + public InputField setTheKeyInput; + + [SerializeField] + public Toggle setTheKeyToggle; + + [SerializeField] + public RectTransform rectTrans; + + [SerializeField] + public UIButton inputUIButton; + + [SerializeField] + public Text conflictText; + + [SerializeField] + public Text waitingText; + + [SerializeField] + public UIButton setDefaultUIButton; + + [SerializeField] + public UIButton setNoneKeyUIButton; + + private bool _nextNotOn; + + public static RectTransform CreateKeyBinder(float x, float y, RectTransform parent, ConfigEntry config, string label = "", int fontSize = 17) + { + var optionWindow = UIRoot.instance.optionWindow; + var uikeyEntry = GameObject.Instantiate(optionWindow.entryPrefab); + GameObject go; + (go = uikeyEntry.gameObject).SetActive(true); + go.name = "my-keybinder"; + var kb = go.AddComponent(); + kb._config = config; + + kb.functionText = uikeyEntry.functionText; + kb.keyText = uikeyEntry.keyText; + kb.setTheKeyInput = uikeyEntry.setTheKeyInput; + kb.setTheKeyToggle = uikeyEntry.setTheKeyToggle; + kb.rectTrans = uikeyEntry.rectTrans; + kb.inputUIButton = uikeyEntry.inputUIButton; + kb.conflictText = uikeyEntry.conflictText; + kb.waitingText = uikeyEntry.waitingText; + kb.setDefaultUIButton = uikeyEntry.setDefaultUIButton; + kb.setNoneKeyUIButton = uikeyEntry.setNoneKeyUIButton; + + + kb.functionText.text = label; + kb.functionText.fontSize = 17; + + ((RectTransform)kb.keyText.transform).anchoredPosition = new Vector2(20f, -27f); + //kb.keyText.alignment = TextAnchor.MiddleRight; + kb.keyText.fontSize = 17; + ((RectTransform)kb.inputUIButton.transform.parent.transform).anchoredPosition = new Vector2(0f + 20f, -57f); + ((RectTransform)kb.setDefaultUIButton.transform).anchoredPosition = new Vector2(140f + 20f, -57f); + ((RectTransform)kb.setNoneKeyUIButton.transform).anchoredPosition = new Vector2(240f + 20f, -57f); + + var rect = Util.NormalizeRectWithTopLeft(kb, x, y, parent); + kb.rectTrans = rect; + + //rect.sizeDelta = new Vector2(240f, 64f); + GameObject.Destroy(uikeyEntry); + kb.setNoneKeyUIButton.gameObject.SetActive(false); + + kb.SettingChanged(); + config.SettingChanged += (sender, args) => { + kb.SettingChanged(); + }; + kb.inputUIButton.onClick += kb.OnInputUIButtonClick; + kb.setDefaultUIButton.onClick += kb.OnSetDefaultKeyClick; + //kb.setNoneKeyUIButton.onClick += kb.OnSetNoneKeyClick; + return go.transform as RectTransform; + + void ResetAnchor(RectTransform theRect) + { + theRect.anchorMax = Vector2.zero; + theRect.anchorMin = Vector2.zero; + } + } + + private void Update() + { + if (!setTheKeyToggle.isOn && inputUIButton.highlighted) + { + setTheKeyToggle.isOn = true; + } + + if (!setTheKeyToggle.isOn) return; + if (!inputUIButton._isPointerEnter && Input.GetKeyDown(KeyCode.Mouse0)) + { + inputUIButton.highlighted = false; + setTheKeyToggle.isOn = false; + Reset(); + } + else if (!this.inputUIButton.highlighted) + { + setTheKeyToggle.isOn = false; + Reset(); + } + else + { + waitingText.gameObject.SetActive(true); + if (!TrySetValue()) return; + setTheKeyToggle.isOn = false; + inputUIButton.highlighted = false; + Reset(); + } + } + + + public bool TrySetValue() + { + if (Input.GetKey(KeyCode.Escape)) + { + VFInput.UseEscape(); + return true; + } + if (Input.GetKey(KeyCode.Mouse0) || Input.GetKey(KeyCode.Mouse1)) + { + return true; + } + var anyKey = GetIunptKeys(); + if (anyKey || _lastKey == KeyCode.None) return false; + var k = GetPressedKey(); + if (string.IsNullOrEmpty(k)) + { + return false; + } + _lastKey = KeyCode.None; + + _config.Value = KeyboardShortcut.Deserialize(k); + //keyText.text = k; + return true; + + } + + private KeyCode _lastKey; + private static readonly KeyCode[] ModKeys = { KeyCode.RightShift, KeyCode.LeftShift, + KeyCode.RightControl, KeyCode.LeftControl, + KeyCode.RightAlt, KeyCode.LeftAlt, + KeyCode.LeftCommand, KeyCode.LeftApple, KeyCode.LeftWindows, + KeyCode.RightCommand, KeyCode.RightApple, KeyCode.RightWindows }; + + public string GetPressedKey() + { + var key = _lastKey.ToString(); + if (string.IsNullOrEmpty(key)) + { + return null; + } + var mod = ""; + foreach (var modKey in ModKeys) + { + if (Input.GetKey(modKey)) + { + mod += "+" + modKey.ToString(); + } + } + + if (!string.IsNullOrEmpty(mod)) + { + key += mod; + } + return key; + } + + //通常キーが押されているかチェック _lastKey に保存 + public bool GetIunptKeys() + { + var anyKey = false; + + foreach (KeyCode item in Enum.GetValues(typeof(KeyCode))) + { + if (item == KeyCode.None || ModKeys.Contains(item) || !Input.GetKey(item)) continue; + _lastKey = item; + anyKey = true; + } + return anyKey; + + } + + public void Reset() + { + conflictText.gameObject.SetActive(false); + waitingText.gameObject.SetActive(false); + setDefaultUIButton.button.Select(); // InputFieldのフォーカス外す + _lastKey = KeyCode.None; + } + + public void OnInputUIButtonClick(int data) + { + inputUIButton.highlighted = true; + + if (!_nextNotOn) return; + _nextNotOn = false; + inputUIButton.highlighted = false; + setTheKeyToggle.isOn = false; + waitingText.gameObject.SetActive(false); + } + + public void OnSetDefaultKeyClick(int data) + { + _config.Value = (KeyboardShortcut)_config.DefaultValue; + keyText.text = _config.Value.Serialize(); + } + + public void OnSetNoneKeyClick(int data) + { + _config.Value = (KeyboardShortcut)_config.DefaultValue; + keyText.text = _config.Value.Serialize(); + } + + public void SettingChanged() + { + keyText.text = _config.Value.Serialize(); + } +} diff --git a/CheatEnabler/UIConfigWindow.cs b/CheatEnabler/UIConfigWindow.cs index b59e93e..73d8c05 100644 --- a/CheatEnabler/UIConfigWindow.cs +++ b/CheatEnabler/UIConfigWindow.cs @@ -11,6 +11,7 @@ public class UIConfigWindow : UI.MyWindowWithTabs I18N.Add("General", "General", "常规"); I18N.Add("Enable Dev Shortcuts", "Enable Dev Shortcuts", "启用开发模式快捷键"); I18N.Add("Disable Abnormal Checks", "Disable Abnormal Checks", "关闭数据异常检查"); + I18N.Add("Hotkey", "Hotkey", "快捷键"); I18N.Add("Build", "Build", "建造"); I18N.Add("Finish build immediately", "Finish build immediately", "建造秒完成"); I18N.Add("Infinite buildings", "Infinite buildings", "无限建筑"); @@ -64,6 +65,8 @@ public class UIConfigWindow : UI.MyWindowWithTabs UI.MyCheckBox.CreateCheckBox(x, y, tab1, DevShortcuts.Enabled, "Enable Dev Shortcuts".Translate()); y += 36f; UI.MyCheckBox.CreateCheckBox(x, y, tab1, AbnormalDisabler.Enabled, "Disable Abnormal Checks".Translate()); + y += 86f; + UI.MyKeyBinder.CreateKeyBinder(x, y, tab1, CheatEnabler.Hotkey, "Hotkey".Translate()); var tab2 = AddTab(136f, 1, _windowTrans, "Build".Translate()); x = 0f; diff --git a/CheatEnabler/package/manifest.json b/CheatEnabler/package/manifest.json index d8bc46e..a4d8257 100644 --- a/CheatEnabler/package/manifest.json +++ b/CheatEnabler/package/manifest.json @@ -1,6 +1,6 @@ { "name": "CheatEnabler", - "version_number": "1.0.0", + "version_number": "2.0.0", "website_url": "https://github.com/soarqin/DSP_Mods/tree/master/CheatEnabler", "description": "Add various cheat functions while disabling abnormal determinants / 添加一些作弊功能,同时屏蔽异常检测", "dependencies": [