diff --git a/CheatEnabler/CheatEnabler.cs b/CheatEnabler/CheatEnabler.cs index f69c8d0..e2698d5 100644 --- a/CheatEnabler/CheatEnabler.cs +++ b/CheatEnabler/CheatEnabler.cs @@ -5,9 +5,11 @@ using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.UI; +using UXAssist.Common; namespace CheatEnabler; +[BepInDependency("org.soardev.uxassist")] [BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] public class CheatEnabler : BaseUnityPlugin { @@ -15,13 +17,6 @@ public class CheatEnabler : BaseUnityPlugin BepInEx.Logging.Logger.CreateLogSource(PluginInfo.PLUGIN_NAME); public static ConfigEntry Hotkey; - private static bool _configWinInitialized = false; - private static UIConfigWindow _configWin; - - private static Harmony _windowPatch; - private static Harmony _patch; - - private static bool _initialized; private void Awake() { @@ -111,10 +106,8 @@ public class CheatEnabler : BaseUnityPlugin I18N.Init(); I18N.Add("CheatEnabler Config", "CheatEnabler Config", "CheatEnabler设置"); I18N.Apply(); - - // UI Patch - _windowPatch ??= Harmony.CreateAndPatchAll(typeof(UI.MyWindowManager.Patch)); - _patch ??= Harmony.CreateAndPatchAll(typeof(CheatEnabler)); + + UIConfigWindow.Init(); DevShortcuts.Init(); AbnormalDisabler.Init(); @@ -140,138 +133,10 @@ public class CheatEnabler : BaseUnityPlugin TechPatch.Uninit(); AbnormalDisabler.Uninit(); DevShortcuts.Uninit(); - _patch?.UnpatchSelf(); - _patch = null; - _windowPatch?.UnpatchSelf(); - _windowPatch = null; - } - - private void Update() - { - if (VFInput.inputing) return; - if (Hotkey.Value.IsDown()) ToggleConfigWindow(); } private void LateUpdate() { FactoryPatch.NightLight.LateUpdate(); } - - [HarmonyPostfix, HarmonyPatch(typeof(UIRoot), nameof(UIRoot.OpenMainMenuUI))] - public static void UIRoot_OpenMainMenuUI_Postfix() - { - if (_initialized) return; - { - var mainMenu = UIRoot.instance.uiMainMenu; - var src = mainMenu.newGameButton; - var parent = src.transform.parent; - var btn = Instantiate(src, parent); - btn.name = "button-cheatenabler-config"; - var l = btn.text.GetComponent(); - if (l != null) - { - l.stringKey = "CheatEnabler Config"; - l.translation = "CheatEnabler Config".Translate(); - } - btn.text.text = "CheatEnabler Config".Translate(); - btn.text.fontSize = btn.text.fontSize * 7 / 8; - I18N.OnInitialized += () => { btn.text.text = "CheatEnabler Config".Translate(); }; - 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); - btn.button.onClick.RemoveAllListeners(); - btn.button.onClick.AddListener(ToggleConfigWindow); - } - { - var panel = UIRoot.instance.uiGame.planetGlobe; - var src = panel.button2; - var sandboxMenu = UIRoot.instance.uiGame.sandboxMenu; - var icon = sandboxMenu.categoryButtons[6].transform.Find("icon")?.GetComponent()?.sprite; - var b = Instantiate(src, src.transform.parent); - var panelButtonGo = b.gameObject; - var rect = (RectTransform)panelButtonGo.transform; - var btn = panelButtonGo.GetComponent(); - var img = panelButtonGo.transform.Find("button-2/icon")?.GetComponent(); - if (img != null) - { - img.sprite = icon; - } - if (panelButtonGo != null && btn != null) - { - panelButtonGo.name = "open-cheatenabler-config"; - rect.localScale = new Vector3(0.5f, 0.5f, 0.5f); - rect.anchoredPosition3D = new Vector3(128f, -105f, 0f); - b.onClick.RemoveAllListeners(); - btn.onClick += _ => { ToggleConfigWindow(); }; - btn.tips.tipTitle = "CheatEnabler Config"; - I18N.OnInitialized += () => { btn.tips.tipTitle = "CheatEnabler Config".Translate(); }; - btn.tips.tipText = null; - btn.tips.corner = 9; - btn.tips.offset = new Vector2(-20f, -20f); - panelButtonGo.SetActive(true); - } - } - _initialized = true; - } - - [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(); - } - - [HarmonyTranspiler] - [HarmonyPatch(typeof(UIButton), nameof(UIButton.LateUpdate))] - private static IEnumerable UIButton_LateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldloc_2), - new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Component), nameof(Component.gameObject))), - new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(GameObject), nameof(GameObject.activeSelf))) - ); - var labels = matcher.Labels; - matcher.Labels = null; - matcher.Insert( - new CodeInstruction(OpCodes.Ldloc_2).WithLabels(labels), - new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Component), nameof(Component.transform))), - new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.parent))), - new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.parent))), - new CodeInstruction(OpCodes.Callvirt, AccessTools.Method(typeof(Transform), nameof(Transform.SetAsLastSibling))) - ); - return matcher.InstructionEnumeration(); - } - - private static void ToggleConfigWindow() - { - if (!_configWinInitialized) - { - if (!I18N.Initialized()) return; - _configWinInitialized = true; - _configWin = UIConfigWindow.CreateInstance(); - } - - if (_configWin.active) - { - _configWin._Close(); - } - else - { - _configWin.Open(); - } - } } diff --git a/CheatEnabler/CheatEnabler.csproj b/CheatEnabler/CheatEnabler.csproj index e2b1493..a230340 100644 --- a/CheatEnabler/CheatEnabler.csproj +++ b/CheatEnabler/CheatEnabler.csproj @@ -23,6 +23,10 @@ + + + + diff --git a/CheatEnabler/DevShortcuts.cs b/CheatEnabler/DevShortcuts.cs index 4177067..2f7ff0d 100644 --- a/CheatEnabler/DevShortcuts.cs +++ b/CheatEnabler/DevShortcuts.cs @@ -80,7 +80,6 @@ public static class DevShortcuts matcher.RemoveInstructions(2); matcher.Opcode = OpCodes.Br; matcher.Labels = labels; - CheatEnabler.Logger.LogDebug($"{matcher.Pos}"); return matcher.InstructionEnumeration(); } } diff --git a/CheatEnabler/README.md b/CheatEnabler/README.md index a1844f0..7dc8957 100644 --- a/CheatEnabler/README.md +++ b/CheatEnabler/README.md @@ -156,33 +156,33 @@ + 工厂: + 建造秒完成 + 建筑师模式(无限建筑) - + 无限交互距离 + + ** 无限交互距离 + 无条件建造 - + 移除部分不影响游戏逻辑的建造条件 + + ** 移除部分不影响游戏逻辑的建造条件 + 无碰撞 - + 夜间日光灯 + + ** 夜间日光灯 + 传送带信号物品生成 + 统计面板中计算所有原材料和中间产物 + 传送带信号替换格式 + 风力发电机和太阳能板无间距限制 + 提升各种发电设备发电量 + 行星: - + 在行星视图中允许玩家操作 + + ** 在行星视图中允许玩家操作 + 自然资源采集不消耗 + 高速采集 + 平地抽水 + 沙土不够时依然可以整改地形 - + 初始化本行星(不重置矿脉) - + 快速拆除所有建筑(不掉落) + + ** 初始化本行星(不重置矿脉) + + ** 快速拆除所有建筑(不掉落) + 戴森球: - + 可用节点全部造完时停止弹射 - + 只建造节点不建造框架 + + ** 可用节点全部造完时停止弹射 + + ** 只建造节点不建造框架 + 跳过子弹阶段 + 跳过吸收阶段 + 快速吸收 + 全球弹射 - + 初始化戴森球 - + 快速拆除戴森壳 + + ** 初始化戴森球 + + ** 快速拆除戴森壳 + 母星系: + 母星有稀有资源 + 母星是纯平的 diff --git a/CheatEnabler/UIConfigWindow.cs b/CheatEnabler/UIConfigWindow.cs index 4b441bc..dea18a7 100644 --- a/CheatEnabler/UIConfigWindow.cs +++ b/CheatEnabler/UIConfigWindow.cs @@ -1,15 +1,19 @@ using UnityEngine; +using UXAssist.UI; +using UXAssist.Common; namespace CheatEnabler; -public class UIConfigWindow : UI.MyWindowWithTabs +public static class UIConfigWindow { - private RectTransform _windowTrans; + private static RectTransform _windowTrans; + private static MyConfigWindow _configWindow; - private UIButton _resignGameBtn; - private readonly UIButton[] _dysonLayerBtn = new UIButton[10]; + private static RectTransform _tab4; + private static UIButton _resignGameBtn; + private static readonly UIButton[] _dysonLayerBtn = new UIButton[10]; - static UIConfigWindow() + public static void Init() { I18N.Add("General", "General", "常规"); I18N.Add("Enable Dev Shortcuts", "Enable Dev Shortcuts", "开发模式快捷键"); @@ -75,70 +79,61 @@ public class UIConfigWindow : UI.MyWindowWithTabs I18N.Add("Birth planet is solid flat (no water at all)", "Birth planet is solid flat (no water at all)", "母星是纯平的(没有水)"); I18N.Add("Birth star has high luminosity", "Birth star has high luminosity", "母星系恒星高亮"); I18N.Apply(); + MyConfigWindow.OnUICreated += CreateUI; + MyConfigWindow.OnUpdateUI += UpdateUI; } - public static UIConfigWindow CreateInstance() - { - return UI.MyWindowManager.CreateWindow("CEConfigWindow", "CheatEnabler Config"); - } - - public override void _OnCreate() - { - _windowTrans = GetComponent(); - _windowTrans.sizeDelta = new Vector2(580f, 420f); - - CreateUI(); - } - - private void CreateUI() + private static void CreateUI(MyConfigWindow wnd, RectTransform trans) { + _configWindow = wnd; + _windowTrans = trans; // General tab var x = 0f; var y = 10f; - var tab1 = AddTab(36f, 0, _windowTrans, "General"); - UI.MyCheckBox.CreateCheckBox(x, y, tab1, DevShortcuts.Enabled, "Enable Dev Shortcuts"); + var tab1 = wnd.AddTab(_windowTrans, "General"); + MyCheckBox.CreateCheckBox(x, y, tab1, DevShortcuts.Enabled, "Enable Dev Shortcuts"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab1, AbnormalDisabler.Enabled, "Disable Abnormal Checks"); + MyCheckBox.CreateCheckBox(x, y, tab1, AbnormalDisabler.Enabled, "Disable Abnormal Checks"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab1, TechPatch.Enabled, "Unlock Tech with Key-Modifiers"); + MyCheckBox.CreateCheckBox(x, y, tab1, TechPatch.Enabled, "Unlock Tech with Key-Modifiers"); y += 118f; - UI.MyKeyBinder.CreateKeyBinder(x, y, tab1, CheatEnabler.Hotkey, "Hotkey"); + MyKeyBinder.CreateKeyBinder(x, y, tab1, CheatEnabler.Hotkey, "Hotkey"); x = 156f; y = 16f; - AddTipsButton(x, y, tab1, "Dev Shortcuts", "Dev Shortcuts Tips", "dev-shortcuts-tips"); + MyWindow.AddTipsButton(x, y, tab1, "Dev Shortcuts", "Dev Shortcuts Tips", "dev-shortcuts-tips"); x += 52f; y += 72f; - AddTipsButton(x, y, tab1, "Unlock Tech with Key-Modifiers", "Unlock Tech with Key-Modifiers Tips", "unlock-tech-tips"); + MyWindow.AddTipsButton(x, y, tab1, "Unlock Tech with Key-Modifiers", "Unlock Tech with Key-Modifiers Tips", "unlock-tech-tips"); x = 300f; y = 10f; - _resignGameBtn = AddButton(x, y, tab1, "Assign game to current account", 16, "resign-game-btn", () => { GameMain.data.account = AccountData.me; }); + _resignGameBtn = wnd.AddButton(x, y, tab1, "Assign game to current account", 16, "resign-game-btn", () => { GameMain.data.account = AccountData.me; }); var rect = (RectTransform)_resignGameBtn.transform; rect.sizeDelta = new Vector2(200f, rect.sizeDelta.y); - var tab2 = AddTab(136f, 1, _windowTrans, "Factory"); + var tab2 = wnd.AddTab(_windowTrans, "Factory"); x = 0f; y = 10f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.ImmediateEnabled, "Finish build immediately"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.ImmediateEnabled, "Finish build immediately"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.ArchitectModeEnabled, "Architect mode"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.ArchitectModeEnabled, "Architect mode"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.UnlimitInteractiveEnabled, "Unlimited interactive range"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.UnlimitInteractiveEnabled, "Unlimited interactive range"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.NoConditionEnabled, "Build without condition"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.NoConditionEnabled, "Build without condition"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.NoCollisionEnabled, "No collision"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.NoCollisionEnabled, "No collision"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.NightLightEnabled, "Night Light"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.NightLightEnabled, "Night Light"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BeltSignalGeneratorEnabled, "Belt signal generator"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BeltSignalGeneratorEnabled, "Belt signal generator"); y += 26f; x += 26f; - var cb = UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BeltSignalCountRecipeEnabled, "Count all raws and intermediates in statistics", 13); + var cb = MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BeltSignalCountRecipeEnabled, "Count all raws and intermediates in statistics", 13); y += 26f; - var cb2 = UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BeltSignalNumberAltFormat, "Belt signal alt format", 13); + var cb2 = MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BeltSignalNumberAltFormat, "Belt signal alt format", 13); x += 180f; y += 6f; - var tip1 = AddTipsButton(x, y, tab2, "Belt signal alt format", "Belt signal alt format tips", "belt-signal-alt-format-tips"); + var tip1 = MyWindow.AddTipsButton(x, y, tab2, "Belt signal alt format", "Belt signal alt format tips", "belt-signal-alt-format-tips"); FactoryPatch.BeltSignalGeneratorEnabled.SettingChanged += (_, _) => { @@ -147,41 +142,41 @@ public class UIConfigWindow : UI.MyWindowWithTabs OnBeltSignalChanged(); x = 240f; y = 10f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.RemoveSomeConditionEnabled, "Remove some build conditions"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.RemoveSomeConditionEnabled, "Remove some build conditions"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.RemovePowerSpaceLimitEnabled, "Remove power space limit"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.RemovePowerSpaceLimitEnabled, "Remove power space limit"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BoostWindPowerEnabled, "Boost wind power"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BoostWindPowerEnabled, "Boost wind power"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BoostSolarPowerEnabled, "Boost solar power"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BoostSolarPowerEnabled, "Boost solar power"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BoostGeothermalPowerEnabled, "Boost geothermal power"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BoostGeothermalPowerEnabled, "Boost geothermal power"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BoostFuelPowerEnabled, "Boost fuel power"); + MyCheckBox.CreateCheckBox(x, y, tab2, FactoryPatch.BoostFuelPowerEnabled, "Boost fuel power"); x += 32f; y += 26f; - AddText(x, y, tab2, "Boost fuel power 2", 13); + MyWindow.AddText(x, y, tab2, "Boost fuel power 2", 13); // Planet Tab - var tab3 = AddTab(236f, 2, _windowTrans, "Planet"); + var tab3 = wnd.AddTab(_windowTrans, "Planet"); x = 0f; y = 10f; - UI.MyCheckBox.CreateCheckBox(x, y, tab3, PlanetFunctions.PlayerActionsInGlobeViewEnabled, "Enable player actions in globe view"); + MyCheckBox.CreateCheckBox(x, y, tab3, PlanetFunctions.PlayerActionsInGlobeViewEnabled, "Enable player actions in globe view"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab3, ResourcePatch.InfiniteResourceEnabled, "Infinite Natural Resources"); + MyCheckBox.CreateCheckBox(x, y, tab3, ResourcePatch.InfiniteResourceEnabled, "Infinite Natural Resources"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab3, ResourcePatch.FastMiningEnabled, "Fast Mining"); + MyCheckBox.CreateCheckBox(x, y, tab3, ResourcePatch.FastMiningEnabled, "Fast Mining"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab3, WaterPumperPatch.Enabled, "Pump Anywhere"); + MyCheckBox.CreateCheckBox(x, y, tab3, WaterPumperPatch.Enabled, "Pump Anywhere"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab3, TerraformPatch.Enabled, "Terraform without enough sands"); + MyCheckBox.CreateCheckBox(x, y, tab3, TerraformPatch.Enabled, "Terraform without enough sands"); x = 300f; y = 10f; - AddButton(x, y, tab3, "矿物掩埋标题", 16, "button-bury-all", () => { PlanetFunctions.BuryAllVeins(true); }); + wnd.AddButton(x, y, tab3, "矿物掩埋标题", 16, "button-bury-all", () => { PlanetFunctions.BuryAllVeins(true); }); y += 36f; - AddButton(x, y, tab3, "矿物还原标题", 16, "button-bury-restore-all", () => { PlanetFunctions.BuryAllVeins(false); }); + wnd.AddButton(x, y, tab3, "矿物还原标题", 16, "button-bury-restore-all", () => { PlanetFunctions.BuryAllVeins(false); }); y += 36f; - AddButton(x, y, tab3, "铺满地基提示", 16, "button-reform-all", () => + wnd.AddButton(x, y, tab3, "铺满地基提示", 16, "button-reform-all", () => { var player = GameMain.mainPlayer; if (player == null) return; @@ -191,45 +186,45 @@ public class UIConfigWindow : UI.MyWindowWithTabs GameMain.localPlanet.factory.PlanetReformAll(reformTool.brushType, reformTool.brushColor, reformTool.buryVeins); }); y += 36f; - AddButton(x, y, tab3, "还原地形提示", 16, "button-reform-revert-all", () => + wnd.AddButton(x, y, tab3, "还原地形提示", 16, "button-reform-revert-all", () => { var factory = GameMain.localPlanet?.factory; if (factory == null) return; GameMain.localPlanet.factory.PlanetReformRevert(); }); y += 36f; - AddButton(x, y, tab3, "Initialize This Planet", 16, "button-init-planet", () => { PlanetFunctions.RecreatePlanet(true); }); + wnd.AddButton(x, y, tab3, "Initialize This Planet", 16, "button-init-planet", () => { PlanetFunctions.RecreatePlanet(true); }); y += 36f; - AddButton(x, y, tab3, "Dismantle All Buildings", 16, "button-dismantle-all", () => { PlanetFunctions.DismantleAll(false); }); + wnd.AddButton(x, y, tab3, "Dismantle All Buildings", 16, "button-dismantle-all", () => { PlanetFunctions.DismantleAll(false); }); - var tab4 = AddTab(336f, 3, _windowTrans, "Dyson Sphere"); + var tab4 = wnd.AddTab(_windowTrans, "Dyson Sphere"); x = 0f; y = 10f; - UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.StopEjectOnNodeCompleteEnabled, "Stop ejectors when available nodes are all filled up"); + MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.StopEjectOnNodeCompleteEnabled, "Stop ejectors when available nodes are all filled up"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.OnlyConstructNodesEnabled, "Construct only nodes but frames"); + MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.OnlyConstructNodesEnabled, "Construct only nodes but frames"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.SkipBulletEnabled, "Skip bullet period"); + MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.SkipBulletEnabled, "Skip bullet period"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.SkipAbsorbEnabled, "Skip absorption period"); + MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.SkipAbsorbEnabled, "Skip absorption period"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.QuickAbsorbEnabled, "Quick absorb"); + MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.QuickAbsorbEnabled, "Quick absorb"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.EjectAnywayEnabled, "Eject anyway"); + MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.EjectAnywayEnabled, "Eject anyway"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.OverclockEjectorEnabled, "Overclock Ejectors"); + MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.OverclockEjectorEnabled, "Overclock Ejectors"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.OverclockSiloEnabled, "Overclock Silos"); + MyCheckBox.CreateCheckBox(x, y, tab4, DysonSpherePatch.OverclockSiloEnabled, "Overclock Silos"); x = 300f; y = 10f; - AddButton(x, y, tab4, "Initialize Dyson Sphere", 16, "init-dyson-sphere", () => { DysonSpherePatch.InitCurrentDysonSphere(-1); }); + wnd.AddButton(x, y, tab4, "Initialize Dyson Sphere", 16, "init-dyson-sphere", () => { DysonSpherePatch.InitCurrentDysonSphere(-1); }); y += 36f; - AddText(x, y, tab4, "Click to dismantle selected layer", 16, "text-dismantle-layer"); + MyWindow.AddText(x, y, tab4, "Click to dismantle selected layer", 16, "text-dismantle-layer"); y += 26f; for (var i = 0; i < 10; i++) { var id = i + 1; - var btn = AddFlatButton(x, y, tab4, id.ToString(), 12, "dismantle-layer-" + id, () => { DysonSpherePatch.InitCurrentDysonSphere(id); }); + var btn = wnd.AddFlatButton(x, y, tab4, id.ToString(), 12, "dismantle-layer-" + id, () => { DysonSpherePatch.InitCurrentDysonSphere(id); }); ((RectTransform)btn.transform).sizeDelta = new Vector2(40f, 20f); _dysonLayerBtn[i] = btn; if (i == 4) @@ -243,32 +238,31 @@ public class UIConfigWindow : UI.MyWindowWithTabs } } - var tab5 = AddTab(436f, 4, _windowTrans, "Birth"); + var tab5 = wnd.AddTab(_windowTrans, "Birth"); x = 0f; y = 10f; - UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.SitiVeinsOnBirthPlanet, "Silicon/Titanium on birth planet"); + MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.SitiVeinsOnBirthPlanet, "Silicon/Titanium on birth planet"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.FireIceOnBirthPlanet, "Fire ice on birth planet"); + MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.FireIceOnBirthPlanet, "Fire ice on birth planet"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.KimberliteOnBirthPlanet, "Kimberlite on birth planet"); + MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.KimberliteOnBirthPlanet, "Kimberlite on birth planet"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.FractalOnBirthPlanet, "Fractal silicon on birth planet"); + MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.FractalOnBirthPlanet, "Fractal silicon on birth planet"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.OrganicOnBirthPlanet, "Organic crystal on birth planet"); + MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.OrganicOnBirthPlanet, "Organic crystal on birth planet"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.OpticalOnBirthPlanet, "Optical grating crystal on birth planet"); + MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.OpticalOnBirthPlanet, "Optical grating crystal on birth planet"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.SpiniformOnBirthPlanet, "Spiniform stalagmite crystal on birth planet"); + MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.SpiniformOnBirthPlanet, "Spiniform stalagmite crystal on birth planet"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.UnipolarOnBirthPlanet, "Unipolar magnet on birth planet"); + MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.UnipolarOnBirthPlanet, "Unipolar magnet on birth planet"); x = 200f; y = 10f; - UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.FlatBirthPlanet, "Birth planet is solid flat (no water at all)"); + MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.FlatBirthPlanet, "Birth planet is solid flat (no water at all)"); y += 36f; - UI.MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.HighLuminosityBirthStar, "Birth star has high luminosity"); + MyCheckBox.CreateCheckBox(x, y, tab5, BirthPlanetPatch.HighLuminosityBirthStar, "Birth star has high luminosity"); - SetCurrentTab(0); - UpdateUI(); + _tab4 = tab4; return; void OnBeltSignalChanged() @@ -280,22 +274,22 @@ public class UIConfigWindow : UI.MyWindowWithTabs } } - public void UpdateUI() + private static void UpdateUI() { UpdateResignButton(); UpdateDysonShells(); } - private void UpdateResignButton() + private static void UpdateResignButton() { var resignEnabled = GameMain.data.account != AccountData.me; if (_resignGameBtn.gameObject.activeSelf == resignEnabled) return; _resignGameBtn.gameObject.SetActive(resignEnabled); } - private void UpdateDysonShells() + private static void UpdateDysonShells() { - if (!Tabs[3].Item1.gameObject.activeSelf) return; + if (!_tab4.gameObject.activeSelf) return; var star = GameMain.localStar; if (star != null) { @@ -318,39 +312,4 @@ public class UIConfigWindow : UI.MyWindowWithTabs _dysonLayerBtn[i].button.interactable = false; } } - - public override void _OnDestroy() - { - } - - public override bool _OnInit() - { - _windowTrans.anchoredPosition = new Vector2(0, 0); - return true; - } - - public override void _OnFree() - { - } - - public override void _OnOpen() - { - } - - public override void _OnClose() - { - } - - public override void _OnUpdate() - { - base._OnUpdate(); - if (VFInput.escape && !VFInput.inputing) - { - VFInput.UseEscape(); - _Close(); - return; - } - - UpdateUI(); - } } \ No newline at end of file diff --git a/DSP_Mods.sln b/DSP_Mods.sln index f33bb42..7379bb3 100644 --- a/DSP_Mods.sln +++ b/DSP_Mods.sln @@ -29,6 +29,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DustbinPreloader", "Dustbin EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PoolOpt", "PoolOpt\PoolOpt.csproj", "{8BE61246-2C9D-4088-AA33-5AFF22C5046E}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UXAssist", "UXAssist\UXAssist.csproj", "{9C048229-6A50-4642-BC5E-02CD39D3869A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -87,5 +89,9 @@ Global {8BE61246-2C9D-4088-AA33-5AFF22C5046E}.Debug|Any CPU.Build.0 = Debug|Any CPU {8BE61246-2C9D-4088-AA33-5AFF22C5046E}.Release|Any CPU.ActiveCfg = Release|Any CPU {8BE61246-2C9D-4088-AA33-5AFF22C5046E}.Release|Any CPU.Build.0 = Release|Any CPU + {9C048229-6A50-4642-BC5E-02CD39D3869A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9C048229-6A50-4642-BC5E-02CD39D3869A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9C048229-6A50-4642-BC5E-02CD39D3869A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9C048229-6A50-4642-BC5E-02CD39D3869A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/CheatEnabler/I18N.cs b/UXAssist/Common/I18N.cs similarity index 98% rename from CheatEnabler/I18N.cs rename to UXAssist/Common/I18N.cs index bcab0b1..2a7cbb8 100644 --- a/CheatEnabler/I18N.cs +++ b/UXAssist/Common/I18N.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Linq; using HarmonyLib; -namespace CheatEnabler; +namespace UXAssist.Common; public static class I18N { diff --git a/UXAssist/README.md b/UXAssist/README.md new file mode 100644 index 0000000..7dc8957 --- /dev/null +++ b/UXAssist/README.md @@ -0,0 +1,200 @@ +# CheatEnabler + +#### Add various cheat functions while disabling abnormal determinants +#### 添加一些作弊功能,同时屏蔽异常检测 + +## Changlog +* 2.2.7 + + New function: `Construct only nodes but frames` + + Opening config panel does not close inventory panel now + + Remove `Input direction conflict` check while using `Remove some build conditions` + + Fix a bug that prevents `Belt signal alt format` from switching number formats for current belt signals +* 2.2.6 + + New function: `Stop ejectors when available nodes are all filled up` + + Fix a bug that absorb solar sails on unfinised nodes +* 2.2.5 + + Skip all intermediate states and absorb solar sails instantly while enable `Quick absorb`, `Skip bullet period` and `Skip absorption period` at the same time. + + Fix a problem that `Quick absorb` does not absorb all solar sails instantly when most nodes are full. + + Fix crash while using with some mods +* 2.2.4 + + New function: `Enable player actions in globe view` + + Fix UI bug +* 2.2.3 + + New function: `Remove some build conditions` + + Fix compatibility with some mods +* 2.2.2 + + New function: `Assign game to currrnet account` + + New subfunction: `Belt signal alt format` + + Fix a crash on using `Initialize this Planet` + + Fix belt build in `Finish build immediately` +* 2.2.1 + + Check condition for miners even when `Build without condition` is enabled. + + Fix a patch issue that may cause `Build without condition` not working. +* 2.2.0 + + Add some power related functions + + Add a subfunction to belt signal item generation, which simulates production process of raws and intermediates on statistics + + Split some functions from Architect mode +* 2.1.0 + + Belt signal item generation + + Fix window display priority which may cause tips to be covered by main window +* 2.0.0 + + Refactorying codes + + UI implementation + + Add a lot of functions +* 1.0.0 + + Initial release + +## Usage + +* Press `` LAlt+`(BackQuote) `` to call up the config panel. You can change the shortcut on the panel. +* There are also buttons on title screen and planet minimap area to call up the config panel. +* Features: + + Strict hotkey dectection for build menu, thus building hotkeys(0~9, F1~F10, X, U) are not triggered while holding Ctrl/Alt/Shift. + + General: + + Enable Dev Shortcuts (check config panel for usage) + + Disable Abnormal Checks + + Unlock techs with key-modifiers (Ctrl/Alt/Shift) + + Assign game to currrnet account + + Factory: + + Finish build immediately + + Architect mode (Infinite buildings) + + Unlimited interactive range + + Build without condition + + Remove some build conditions + + No collision + + Sunlight at night + + Belt signal item generation + + Count all raws and intermediates in statistics + + Belt signal alt format + + Remove space limit between wind turbines and solar panels + + Boost power generations for kinds of power generators + + Planet: + + Enable player actions in globe view + + Infinite Natural Resources + + Fast Mining + + Pump Anywhere + + Terraform without enought sands + + Re-intialize planet (without reseting veins) + + Quick dismantle all buildings (without drops) + + Dyson Sphere: + + Stop ejectors when available nodes are all filled up + + Construct only nodes but frames + + Skip bullet period + + Skip absorption period + + Quick absorb + + Eject anyway + + Re-initialize Dyson Spheres + + Quick dismantle Dyson Shells + + Birth star: + + Rare resources on birth planet + + Solid flat on birth planet + + High luminosity for birth star + +## Notes +* Please upgrade `BepInEx` 5.4.21 or later if using with [BlueprintTweaks](https://dsp.thunderstore.io/package/kremnev8/BlueprintTweaks/) to avoid possible conflicts. + + You can download `BepInEx` [here](https://github.com/bepinex/bepinex/releases/latest)(choose x64 edition). + + If using with r2modman, you can upgrade `BepInEx` by clicking `Settings` -> `Browse profile folder`, then extract downloaded zip to the folder and overwrite existing files. + +## CREDITS +* [Dyson Sphere Program](https://store.steampowered.com/app/1366540): The great game +* [BepInEx](https://bepinex.dev/): Base modding framework +* [Multifunction_mod](https://github.com/blacksnipebiu/Multifunction_mod): Some cheat functions +* [LSTM](https://github.com/hetima/DSP_LSTM) & [PlanetFinder](https://github.com/hetima/DSP_PlanetFinder): UI implementations + +## 更新日志 +* 2.2.7 + + 新功能:`只建造节点不建造框架` + + 打开设置面板时不再关闭背包面板 + + 在`移除部分不影响游戏逻辑的建造条件`启用时移除`输入方向冲突`的检查条件 + + 修复导致`传送带信号替换格式`不切换传送带信号数字格式的问题 +* 2.2.6 + + 新功能:`可用节点全部造完时停止弹射` + + 修复了在未完成的节点上吸收太阳帆的问题 +* 2.2.5 + + 在同时启用`快速吸收`、`跳过子弹阶段`和`跳过吸收阶段`时,所有弹射的太阳帆会跳过所有中间环节立即吸收 + + 修复了`快速吸收`在大部分节点已满时无法立即吸收所有太阳帆的问题 + + 修复了与一些mod的兼容性问题 +* 2.2.4 + + 新功能:`在行星视图中允许玩家操作` + + 修复了UI显示问题 +* 2.2.3 + + 新功能:`移除部分不影响游戏逻辑的建造条件` + + 修复了与一些mod的兼容性问题 +* 2.2.2 + + 新功能:`将游戏绑定给当前账号` + + 新子功能:`传送带信号替换格式` + + 修复了`初始化本行星`可能导致崩溃的问题 + + 修复了`建造秒完成`中传送带建造的问题 +* 2.2.1 + + 即使在启用`无条件建造`时依然检查矿机的建造条件 + + 修复一个可能导致`无条件建造`不生效的问题 +* 2.2.0 + + 添加了一些发电相关功能 + + 为传送带信号物品生成添加了一个子功能,在统计面板模拟了原材料和中间产物的生产过程 + + 从建筑师模式中分离了一些功能 +* 2.1.0 + + 传送带信号物品生成 + + 修复窗口显示优先级可能导致提示信息被主窗口遮挡的问题 +* 2.0.0 + + 重构代码 + + UI实现 + + 添加了很多功能 +* 1.0.0 + + 初始版本 + +## 使用说明 + +* 按 `` 左Alt+`(反引号) `` 键呼出主面板,可以在面板上修改快捷键。 +* 标题界面和行星小地图旁也有按钮呼出主面板。 +* 功能: + + 更严格的建造菜单热键检测,因此在按住Ctrl/Alt/Shift时不再会触发建造热键(0~9, F1~F10, X, U) + + 常规: + + 启用开发模式快捷键(使用说明见设置面板) + + 屏蔽异常检测 + + 使用组合键解锁科技(Ctrl/Alt/Shift) + + 将游戏绑定给当前账号 + + 工厂: + + 建造秒完成 + + 建筑师模式(无限建筑) + + ** 无限交互距离 + + 无条件建造 + + ** 移除部分不影响游戏逻辑的建造条件 + + 无碰撞 + + ** 夜间日光灯 + + 传送带信号物品生成 + + 统计面板中计算所有原材料和中间产物 + + 传送带信号替换格式 + + 风力发电机和太阳能板无间距限制 + + 提升各种发电设备发电量 + + 行星: + + ** 在行星视图中允许玩家操作 + + 自然资源采集不消耗 + + 高速采集 + + 平地抽水 + + 沙土不够时依然可以整改地形 + + ** 初始化本行星(不重置矿脉) + + ** 快速拆除所有建筑(不掉落) + + 戴森球: + + ** 可用节点全部造完时停止弹射 + + ** 只建造节点不建造框架 + + 跳过子弹阶段 + + 跳过吸收阶段 + + 快速吸收 + + 全球弹射 + + ** 初始化戴森球 + + ** 快速拆除戴森壳 + + 母星系: + + 母星有稀有资源 + + 母星是纯平的 + + 母星系恒星高亮 + +## 注意事项 +* 如果和[BlueprintTweaks](https://dsp.thunderstore.io/package/kremnev8/BlueprintTweaks/)一起使用,请升级`BepInEx`到5.4.21或更高版本,以避免可能的冲突。 + + 你可以在[这里](https://github.com/bepinex/bepinex/releases/latest)(选择x64版本)下载`BepInEx`。 + + 如果使用r2modman,你可以点击`Settings` -> `Browse profile folder`,然后将下载的zip解压到该文件夹并覆盖现有文件。 + +## 鸣谢 +* [戴森球计划](https://store.steampowered.com/app/1366540): 伟大的游戏 +* [BepInEx](https://bepinex.dev/): 基础模组框架 +* [Multifunction_mod](https://github.com/blacksnipebiu/Multifunction_mod): 一些作弊功能 +* [LSTM](https://github.com/hetima/DSP_LSTM) & [PlanetFinder](https://github.com/hetima/DSP_PlanetFinder): UI实现 diff --git a/CheatEnabler/UI/MyCheckbox.cs b/UXAssist/UI/MyCheckbox.cs similarity index 98% rename from CheatEnabler/UI/MyCheckbox.cs rename to UXAssist/UI/MyCheckbox.cs index 708aba1..041f599 100644 --- a/CheatEnabler/UI/MyCheckbox.cs +++ b/UXAssist/UI/MyCheckbox.cs @@ -3,7 +3,7 @@ using BepInEx.Configuration; using UnityEngine; using UnityEngine.UI; -namespace CheatEnabler.UI; +namespace UXAssist.UI; // MyCheckBox modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyCheckBox.cs public class MyCheckBox : MonoBehaviour diff --git a/UXAssist/UI/MyConfigWindow.cs b/UXAssist/UI/MyConfigWindow.cs new file mode 100644 index 0000000..1f00d79 --- /dev/null +++ b/UXAssist/UI/MyConfigWindow.cs @@ -0,0 +1,64 @@ +using System; +using System.Linq; +using UnityEngine; +using UXAssist.Common; + +namespace UXAssist.UI; + +public class MyConfigWindow : MyWindowWithTabs +{ + public static Action OnUICreated; + public static Action OnUpdateUI; + + private RectTransform _windowTrans; + + public static MyConfigWindow CreateInstance() + { + return MyWindowManager.CreateWindow("UXAConfigWindow", "UXAssist Config"); + } + + public override void _OnCreate() + { + _windowTrans = GetComponent(); + _windowTrans.sizeDelta = new Vector2(680f, 420f); + + OnUICreated?.Invoke(this, _windowTrans); + SetCurrentTab(0); + OnUpdateUI?.Invoke(); + } + + public override void _OnDestroy() + { + } + + public override bool _OnInit() + { + _windowTrans.anchoredPosition = new Vector2(0, 0); + return true; + } + + public override void _OnFree() + { + } + + public override void _OnOpen() + { + } + + public override void _OnClose() + { + } + + public override void _OnUpdate() + { + base._OnUpdate(); + if (VFInput.escape && !VFInput.inputing) + { + VFInput.UseEscape(); + _Close(); + return; + } + + OnUpdateUI?.Invoke(); + } +} diff --git a/CheatEnabler/UI/MyKeyBinder.cs b/UXAssist/UI/MyKeyBinder.cs similarity index 99% rename from CheatEnabler/UI/MyKeyBinder.cs rename to UXAssist/UI/MyKeyBinder.cs index 3333580..cfddd1b 100644 --- a/CheatEnabler/UI/MyKeyBinder.cs +++ b/UXAssist/UI/MyKeyBinder.cs @@ -4,7 +4,7 @@ using BepInEx.Configuration; using UnityEngine; using UnityEngine.UI; -namespace CheatEnabler.UI; +namespace UXAssist.UI; // MyKeyBinder modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyKeyBinder.cs public class MyKeyBinder : MonoBehaviour diff --git a/CheatEnabler/UI/MySlider.cs b/UXAssist/UI/MySlider.cs similarity index 99% rename from CheatEnabler/UI/MySlider.cs rename to UXAssist/UI/MySlider.cs index 7978f44..0434506 100644 --- a/CheatEnabler/UI/MySlider.cs +++ b/UXAssist/UI/MySlider.cs @@ -2,7 +2,7 @@ using UnityEngine; using UnityEngine.UI; -namespace CheatEnabler.UI; +namespace UXAssist.UI; // MySlider modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MySlider.cs diff --git a/CheatEnabler/UI/MyWindow.cs b/UXAssist/UI/MyWindow.cs similarity index 91% rename from CheatEnabler/UI/MyWindow.cs rename to UXAssist/UI/MyWindow.cs index 3780a86..a78af1d 100644 --- a/CheatEnabler/UI/MyWindow.cs +++ b/UXAssist/UI/MyWindow.cs @@ -6,7 +6,7 @@ using UnityEngine.Events; using UnityEngine.UI; using Object = UnityEngine.Object; -namespace CheatEnabler.UI; +namespace UXAssist.UI; // MyWindow modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyWindowCtl.cs @@ -51,7 +51,7 @@ public class MyWindow: ManualBehaviour } } - protected static Text AddText(float x, float y, RectTransform parent, string label, int fontSize = 14, string objName = "label") + public static Text AddText(float x, float y, RectTransform parent, string label, int fontSize = 14, string objName = "label") { var src = UIRoot.instance.uiGame.assemblerWindow.stateText; var txt = Instantiate(src); @@ -68,7 +68,7 @@ public class MyWindow: ManualBehaviour return txt; } - protected static UIButton AddTipsButton(float x, float y, RectTransform parent, string label, string tip, string content, string objName = "tips-button") + public static UIButton AddTipsButton(float x, float y, RectTransform parent, string label, string tip, string content, string objName = "tips-button") { var src = UIRoot.instance.galaxySelect.sandboxToggle.gameObject.transform.parent.Find("tip-button"); var dst = Instantiate(src); @@ -82,7 +82,7 @@ public class MyWindow: ManualBehaviour return btn; } - protected UIButton AddButton(float x, float y, RectTransform parent, string text = "", int fontSize = 16, string objName = "button", UnityAction onClick = null) + public UIButton AddButton(float x, float y, RectTransform parent, string text = "", int fontSize = 16, string objName = "button", UnityAction onClick = null) { var panel = UIRoot.instance.uiGame.statWindow.performancePanelUI; var btn = Instantiate(panel.cpuActiveButton); @@ -113,7 +113,7 @@ public class MyWindow: ManualBehaviour return btn; } - protected UIButton AddFlatButton(float x, float y, RectTransform parent, string text = "", int fontSize = 12, string objName = "button", UnityAction onClick = null) + public UIButton AddFlatButton(float x, float y, RectTransform parent, string text = "", int fontSize = 12, string objName = "button", UnityAction onClick = null) { var panel = UIRoot.instance.uiGame.dysonEditor.controlPanel.hierarchy.layerPanel; var btn = Instantiate(panel.layerButtons[0]); @@ -206,7 +206,8 @@ public class MyWindow: ManualBehaviour public class MyWindowWithTabs : MyWindow { - protected readonly List> Tabs = new(); + private readonly List> _tabs = new(); + private float _tabX = 36f; public override void TryClose() { _Close(); @@ -217,7 +218,7 @@ public class MyWindowWithTabs : MyWindow return true; } - protected RectTransform AddTab(float x, int index, RectTransform parent, string label) + public RectTransform AddTab(float x, int index, RectTransform parent, string label) { var tab = new GameObject(); var tabRect = tab.AddComponent(); @@ -243,7 +244,7 @@ public class MyWindowWithTabs : MyWindow btnText.fontSize = 16; btn.data = index; - Tabs.Add(Tuple.Create(tabRect, btn)); + _tabs.Add(Tuple.Create(tabRect, btn)); if (EventRegistered) { btn.onClick += OnTabButtonClick; @@ -251,11 +252,18 @@ public class MyWindowWithTabs : MyWindow return tabRect; } + public RectTransform AddTab(RectTransform parent, string label) + { + var result = AddTab(_tabX, _tabs.Count, parent, label); + _tabX += 100f; + return result; + } + public override void _OnRegEvent() { if (!EventRegistered) { - foreach (var t in Tabs) + foreach (var t in _tabs) { t.Item2.onClick += OnTabButtonClick; } @@ -267,7 +275,7 @@ public class MyWindowWithTabs : MyWindow { if (EventRegistered) { - foreach (var t in Tabs) + foreach (var t in _tabs) { t.Item2.onClick -= OnTabButtonClick; } @@ -279,7 +287,7 @@ public class MyWindowWithTabs : MyWindow private void OnTabButtonClick(int index) { - foreach (var (rectTransform, btn) in Tabs) + foreach (var (rectTransform, btn) in _tabs) { if (btn.data != index) { diff --git a/CheatEnabler/UI/Util.cs b/UXAssist/UI/Util.cs similarity index 98% rename from CheatEnabler/UI/Util.cs rename to UXAssist/UI/Util.cs index 34d5e29..f53eeed 100644 --- a/CheatEnabler/UI/Util.cs +++ b/UXAssist/UI/Util.cs @@ -1,6 +1,6 @@ using UnityEngine; -namespace CheatEnabler.UI; +namespace UXAssist.UI; public static class Util { diff --git a/UXAssist/UIConfigWindow.cs b/UXAssist/UIConfigWindow.cs new file mode 100644 index 0000000..81fd6b7 --- /dev/null +++ b/UXAssist/UIConfigWindow.cs @@ -0,0 +1,26 @@ +using System; +using UnityEngine; +using UXAssist.UI; +using UXAssist.Common; + +namespace UXAssist; + +public static class UIConfigWindow +{ + private static RectTransform _windowTrans; + private static MyConfigWindow _configWindow; + + public static void Init() + { + I18N.Add("UXAssist", "UXAssist", "UX助手"); + I18N.Apply(); + MyConfigWindow.OnUICreated += CreateUI; + } + + private static void CreateUI(MyConfigWindow wnd, RectTransform trans) + { + _configWindow = wnd; + _windowTrans = trans; + var tab1 = wnd.AddTab(_windowTrans, "UXAssist"); + } +} diff --git a/UXAssist/UXAssist.cs b/UXAssist/UXAssist.cs new file mode 100644 index 0000000..4daa13a --- /dev/null +++ b/UXAssist/UXAssist.cs @@ -0,0 +1,285 @@ +using System.Collections.Generic; +using System.Reflection.Emit; +using BepInEx; +using BepInEx.Configuration; +using HarmonyLib; +using UnityEngine; +using UnityEngine.UI; +using UXAssist.Common; +using UXAssist.UI; + +namespace UXAssist; + +[BepInPlugin(PluginInfo.PLUGIN_GUID, PluginInfo.PLUGIN_NAME, PluginInfo.PLUGIN_VERSION)] +public class UXAssist : 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 MyConfigWindow _configWin; + + private static Harmony _windowPatch; + private static Harmony _patch; + + private static bool _initialized; + + private void Awake() + { + Hotkey = Config.Bind("General", "Shortcut", KeyboardShortcut.Deserialize("BackQuote + LeftAlt"), "Shortcut to open config window"); + /* + DevShortcuts.Enabled = Config.Bind("General", "DevShortcuts", false, "Enable DevMode shortcuts"); + AbnormalDisabler.Enabled = Config.Bind("General", "DisableAbnormalChecks", false, + "disable all abnormal checks"); + TechPatch.Enabled = Config.Bind("General", "UnlockTech", false, + "Unlock clicked tech by holding key-modifilers(Shift/Alt/Ctrl)"); + FactoryPatch.ImmediateEnabled = Config.Bind("Build", "ImmediateBuild", false, + "Build immediately"); + FactoryPatch.ArchitectModeEnabled = Config.Bind("Build", "Architect", false, + "Architect Mode"); + FactoryPatch.UnlimitInteractiveEnabled = Config.Bind("Build", "UnlimitInteractive", false, + "Unlimit interactive range"); + FactoryPatch.RemoveSomeConditionEnabled = Config.Bind("Build", "RemoveSomeBuildConditionCheck", false, + "Remove part of build condition checks that does not affect game logic"); + FactoryPatch.NoConditionEnabled = Config.Bind("Build", "BuildWithoutCondition", false, + "Build without condition"); + FactoryPatch.NoCollisionEnabled = Config.Bind("Build", "NoCollision", false, + "No collision"); + FactoryPatch.BeltSignalGeneratorEnabled = Config.Bind("Build", "BeltSignalGenerator", false, + "Belt signal generator"); + FactoryPatch.BeltSignalNumberAltFormat = Config.Bind("Build", "BeltSignalNumberFormat", false, + "Belt signal number format alternative format (AAAA=generation speed in minutes, B=proliferate points, C=stack count):\n AAAABC by default\n BCAAAA as alternative"); + FactoryPatch.BeltSignalCountRecipeEnabled = Config.Bind("Build", "BeltSignalCountRecipe", false, + "Belt signal count all raws and intermediates in statistics"); + FactoryPatch.NightLightEnabled = Config.Bind("Build", "NightLight", false, + "Night light"); + FactoryPatch.RemovePowerSpaceLimitEnabled = Config.Bind("Build", "RemovePowerDistanceLimit", false, + "Remove distance limit for wind turbines and geothermals"); + FactoryPatch.BoostWindPowerEnabled = Config.Bind("Build", "BoostWindPower", false, + "Boost wind power"); + FactoryPatch.BoostSolarPowerEnabled = Config.Bind("Build", "BoostSolarPower", false, + "Boost solar power"); + FactoryPatch.BoostFuelPowerEnabled = Config.Bind("Build", "BoostFuelPower", false, + "Boost fuel power"); + FactoryPatch.BoostGeothermalPowerEnabled = Config.Bind("Build", "BoostGeothermalPower", false, + "Boost geothermal power"); + PlanetFunctions.PlayerActionsInGlobeViewEnabled = Config.Bind("Planet", "PlayerActionsInGlobeView", false, + "Enable player actions in globe view"); + ResourcePatch.InfiniteResourceEnabled = Config.Bind("Planet", "AlwaysInfiniteResource", false, + "always infinite natural resource"); + ResourcePatch.FastMiningEnabled = Config.Bind("Planet", "FastMining", false, + "super-fast mining speed"); + WaterPumperPatch.Enabled = Config.Bind("Planet", "WaterPumpAnywhere", false, + "Can pump water anywhere (while water type is not None)"); + TerraformPatch.Enabled = Config.Bind("Planet", "TerraformAnyway", false, + "Can do terraform without enough sands"); + DysonSpherePatch.StopEjectOnNodeCompleteEnabled = Config.Bind("DysonSphere", "StopEjectOnNodeComplete", false, + "Stop ejectors when available nodes are all filled up"); + DysonSpherePatch.OnlyConstructNodesEnabled = Config.Bind("DysonSphere", "OnlyConstructNodes", false, + "Construct only nodes but frames"); + DysonSpherePatch.SkipBulletEnabled = Config.Bind("DysonSphere", "SkipBullet", false, + "Skip bullet"); + DysonSpherePatch.SkipAbsorbEnabled = Config.Bind("DysonSphere", "SkipAbsorb", false, + "Skip absorption"); + DysonSpherePatch.QuickAbsorbEnabled = Config.Bind("DysonSphere", "QuickAbsorb", false, + "Quick absorb"); + DysonSpherePatch.EjectAnywayEnabled = Config.Bind("DysonSphere", "EjectAnyway", false, + "Eject anyway"); + DysonSpherePatch.OverclockEjectorEnabled = Config.Bind("DysonSphere", "OverclockEjector", false, + "Overclock ejector"); + DysonSpherePatch.OverclockSiloEnabled = Config.Bind("DysonSphere", "OverclockSilo", false, + "Overclock silo"); + BirthPlanetPatch.SitiVeinsOnBirthPlanet = Config.Bind("Birth", "SiTiVeinsOnBirthPlanet", false, + "Silicon/Titanium on birth planet"); + BirthPlanetPatch.FireIceOnBirthPlanet = Config.Bind("Birth", "FireIceOnBirthPlanet", false, + "Fire ice on birth planet"); + BirthPlanetPatch.KimberliteOnBirthPlanet = Config.Bind("Birth", "KimberliteOnBirthPlanet", false, + "Kimberlite on birth planet"); + BirthPlanetPatch.FractalOnBirthPlanet = Config.Bind("Birth", "FractalOnBirthPlanet", false, + "Fractal silicon on birth planet"); + BirthPlanetPatch.OrganicOnBirthPlanet = Config.Bind("Birth", "OrganicOnBirthPlanet", false, + "Organic crystal on birth planet"); + BirthPlanetPatch.OpticalOnBirthPlanet = Config.Bind("Birth", "OpticalOnBirthPlanet", false, + "Optical grating crystal on birth planet"); + BirthPlanetPatch.SpiniformOnBirthPlanet = Config.Bind("Birth", "SpiniformOnBirthPlanet", false, + "Spiniform stalagmite crystal on birth planet"); + BirthPlanetPatch.UnipolarOnBirthPlanet = Config.Bind("Birth", "UnipolarOnBirthPlanet", false, + "Unipolar magnet on birth planet"); + BirthPlanetPatch.FlatBirthPlanet = Config.Bind("Birth", "FlatBirthPlanet", false, + "Birth planet is solid flat (no water at all)"); + BirthPlanetPatch.HighLuminosityBirthStar = Config.Bind("Birth", "HighLuminosityBirthStar", false, + "Birth star has high luminosity"); + */ + I18N.Init(); + I18N.Add("UXAssist Config", "UXAssist Config", "UX助手设置"); + I18N.Apply(); + + // UI Patch + _windowPatch ??= Harmony.CreateAndPatchAll(typeof(UI.MyWindowManager.Patch)); + _patch ??= Harmony.CreateAndPatchAll(typeof(UXAssist)); + + UIConfigWindow.Init(); + /* + DevShortcuts.Init(); + AbnormalDisabler.Init(); + TechPatch.Init(); + FactoryPatch.Init(); + PlanetFunctions.Init(); + ResourcePatch.Init(); + WaterPumperPatch.Init(); + TerraformPatch.Init(); + DysonSpherePatch.Init(); + BirthPlanetPatch.Init(); + */ + } + + private void OnDestroy() + { + /* + BirthPlanetPatch.Uninit(); + DysonSpherePatch.Uninit(); + TerraformPatch.Uninit(); + WaterPumperPatch.Uninit(); + ResourcePatch.Uninit(); + PlanetFunctions.Uninit(); + FactoryPatch.Uninit(); + TechPatch.Uninit(); + AbnormalDisabler.Uninit(); + DevShortcuts.Uninit(); + */ + _patch?.UnpatchSelf(); + _patch = null; + _windowPatch?.UnpatchSelf(); + _windowPatch = null; + } + + private void Update() + { + if (VFInput.inputing) return; + if (Hotkey.Value.IsDown()) ToggleConfigWindow(); + } +/* + private void LateUpdate() + { + FactoryPatch.NightLight.LateUpdate(); + } +*/ + [HarmonyPostfix, HarmonyPatch(typeof(UIRoot), nameof(UIRoot.OpenMainMenuUI))] + public static void UIRoot_OpenMainMenuUI_Postfix() + { + if (_initialized) return; + { + var mainMenu = UIRoot.instance.uiMainMenu; + var src = mainMenu.newGameButton; + var parent = src.transform.parent; + var btn = Instantiate(src, parent); + btn.name = "button-cheatenabler-config"; + var l = btn.text.GetComponent(); + if (l != null) + { + l.stringKey = "CheatEnabler Config"; + l.translation = "CheatEnabler Config".Translate(); + } + btn.text.text = "CheatEnabler Config".Translate(); + btn.text.fontSize = btn.text.fontSize * 7 / 8; + I18N.OnInitialized += () => { btn.text.text = "UXAssist Config".Translate(); }; + 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); + btn.button.onClick.RemoveAllListeners(); + btn.button.onClick.AddListener(ToggleConfigWindow); + } + { + var panel = UIRoot.instance.uiGame.planetGlobe; + var src = panel.button2; + var sandboxMenu = UIRoot.instance.uiGame.sandboxMenu; + var icon = sandboxMenu.categoryButtons[6].transform.Find("icon")?.GetComponent()?.sprite; + var b = Instantiate(src, src.transform.parent); + var panelButtonGo = b.gameObject; + var rect = (RectTransform)panelButtonGo.transform; + var btn = panelButtonGo.GetComponent(); + var img = panelButtonGo.transform.Find("button-2/icon")?.GetComponent(); + if (img != null) + { + img.sprite = icon; + } + if (panelButtonGo != null && btn != null) + { + panelButtonGo.name = "open-uxassist-config"; + rect.localScale = new Vector3(0.5f, 0.5f, 0.5f); + rect.anchoredPosition3D = new Vector3(128f, -105f, 0f); + b.onClick.RemoveAllListeners(); + btn.onClick += _ => { ToggleConfigWindow(); }; + btn.tips.tipTitle = "CheatEnabler Config"; + I18N.OnInitialized += () => { btn.tips.tipTitle = "UXAssist Config".Translate(); }; + btn.tips.tipText = null; + btn.tips.corner = 9; + btn.tips.offset = new Vector2(-20f, -20f); + panelButtonGo.SetActive(true); + } + } + _initialized = true; + } + + [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(); + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(UIButton), nameof(UIButton.LateUpdate))] + private static IEnumerable UIButton_LateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldloc_2), + new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Component), nameof(Component.gameObject))), + new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(GameObject), nameof(GameObject.activeSelf))) + ); + var labels = matcher.Labels; + matcher.Labels = null; + matcher.Insert( + new CodeInstruction(OpCodes.Ldloc_2).WithLabels(labels), + new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Component), nameof(Component.transform))), + new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.parent))), + new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.parent))), + new CodeInstruction(OpCodes.Callvirt, AccessTools.Method(typeof(Transform), nameof(Transform.SetAsLastSibling))) + ); + return matcher.InstructionEnumeration(); + } + + private static void ToggleConfigWindow() + { + if (!_configWinInitialized) + { + if (!I18N.Initialized()) return; + _configWinInitialized = true; + _configWin = MyConfigWindow.CreateInstance(); + } + + if (_configWin.active) + { + _configWin._Close(); + } + else + { + _configWin.Open(); + } + } +} diff --git a/UXAssist/UXAssist.csproj b/UXAssist/UXAssist.csproj new file mode 100644 index 0000000..b6cbe38 --- /dev/null +++ b/UXAssist/UXAssist.csproj @@ -0,0 +1,28 @@ + + + + net472 + org.soardev.uxassist + DSP MOD - UXAssist + 1.0.0 + true + latest + UXAssist + UXAssist + + + + + + + + + + + + + + + + + diff --git a/UXAssist/package/icon.png b/UXAssist/package/icon.png new file mode 100644 index 0000000..1e293d0 Binary files /dev/null and b/UXAssist/package/icon.png differ diff --git a/UXAssist/package/manifest.json b/UXAssist/package/manifest.json new file mode 100644 index 0000000..6dc8af5 --- /dev/null +++ b/UXAssist/package/manifest.json @@ -0,0 +1,9 @@ +{ + "name": "UXAssist", + "version_number": "1.0.0", + "website_url": "https://github.com/soarqin/DSP_Mods/tree/master/UXAssist", + "description": "Some functions and patches for better user experience / 一些提升用户体验的功能和补丁", + "dependencies": [ + "xiaoye97-BepInEx-5.4.17" + ] +}