From c7465133f7d01d95fc8423e5978f1182a4ec628a Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Sat, 10 May 2025 00:50:11 +0800 Subject: [PATCH] UXAssist v1.3.3 --- UXAssist/CHANGELOG.md | 17 +- UXAssist/Functions/UIFunctions.cs | 64 +++++-- UXAssist/Patches/GamePatch.cs | 278 ++++++++++++++++-------------- UXAssist/Patches/PlayerPatch.cs | 236 ++++++++++++------------- UXAssist/UI/MyCheckButton.cs | 1 - UXAssist/UI/MyFlatButton.cs | 95 ++++++++++ UXAssist/UI/MyWindow.cs | 34 +--- UXAssist/UIConfigWindow.cs | 13 +- 8 files changed, 438 insertions(+), 300 deletions(-) create mode 100644 UXAssist/UI/MyFlatButton.cs diff --git a/UXAssist/CHANGELOG.md b/UXAssist/CHANGELOG.md index 8b2938b..897a82b 100644 --- a/UXAssist/CHANGELOG.md +++ b/UXAssist/CHANGELOG.md @@ -7,7 +7,9 @@ + Starmap filter: Hide top overlaping windows while the filter UI is shown. + `Auto-config logistic stations`: Can set Max. Charging Power for Battlefield Analysis Base now. + `Re-initialize planet`: Fix a crash. - + `Auto navigation on sailings`: Do not auto-use Warper if required Tech is not researched. + + `Auto navigation on sailings`: + - Add a button to enable/disable `Auto-cruise` quickly. + - Do not auto-use Warper if required Tech is not researched. + `Dismantle blueprint selected buildings`: Fix an issue that belt connected buildings are dismantled unexpectly. + `Mod manager profile based save folder`: Fix compatibility with [SaveTheWindows](https://thunderstore.io/c/dyson-sphere-program/p/starfi5h/SaveTheWindows/). + `Enhanced control for logistic storage capacities` & `Allow overflow for Logistic Stations and Advanced Mining Machines`: @@ -307,6 +309,19 @@ ## 更新日志 +* 1.3.3 + + 星图过滤器:当过滤器UI显示时隐藏顶部重叠窗口 + + `自动配置物流站`:现在可以为战场分析基站设置最大充能功率 + + `重新初始化行星`:修复崩溃问题 + + `航行时自动导航`: + - 添加快速启用/禁用`自动巡航`的按钮 + - 如果所需科技未研究则不自动使用翘曲器 + + `拆除蓝图选中建筑`:修复传送带连接建筑意外被拆除的问题 + + `基于mod管理器配置档案的存档文件夹`:修复与[SaveTheWindows](https://thunderstore.io/c/dyson-sphere-program/p/starfi5h/SaveTheWindows/)的兼容性 + + `物流存储容量控制改进`和`允许物流站和大型采矿机物品溢出`: + - 如果物流存储容量已经超过升级后的最大容量,则在升级`物流运输机容量`时不会按比例提升 + - 粘贴蓝图时物流存储容量将降低至科技容量限制 + + `物流站实时信息面板`:支持修改物流站槽位数的mod * 1.3.2 + 新功能:`在和平模式下隐藏战斗相关科技` + 新按钮:`使用元数据解锁所有科技` diff --git a/UXAssist/Functions/UIFunctions.cs b/UXAssist/Functions/UIFunctions.cs index 70ac389..9b8da23 100644 --- a/UXAssist/Functions/UIFunctions.cs +++ b/UXAssist/Functions/UIFunctions.cs @@ -7,7 +7,6 @@ using UnityEngine; using UnityEngine.UI; using System; using System.Linq; -using System.Threading; using System.Collections.Generic; public static class UIFunctions @@ -17,13 +16,6 @@ public static class UIFunctions private static bool _configWinInitialized; private static MyConfigWindow _configWin; private static GameObject _buttonOnPlanetGlobe; - private static int _cornerComboBoxIndex; - private static string[] _starOrderNames; - private static bool _starmapFilterInitialized; - private static ulong[] _starmapStarFilterValues; - private static bool _starFilterEnabled; - public static UI.MyCheckButton StarmapFilterToggler; - public static bool[] ShowStarName; public static void Init() { @@ -35,6 +27,9 @@ public static class UIFunctions canOverride = true }); I18N.Add("KEYOpenUXAssistConfigWindow", "[UXA] Open UXAssist Config Window", "[UXA] 打开UX助手设置面板"); + + I18N.Add("Enable auto-cruise", "Enable auto-cruise", "启用自动巡航"); + I18N.Add("Disable auto-cruise", "Disable auto-cruise", "禁用自动巡航"); I18N.Add("High yield", "High yield", "高产"); I18N.Add("Perfect", "Perfect", "完美"); I18N.Add("Union results", "Union results", "结果取并集"); @@ -54,7 +49,7 @@ public static class UIFunctions } } -#region ConfigWindow + #region ConfigWindow public static void ToggleConfigWindow() { if (!_configWinInitialized) @@ -132,6 +127,7 @@ public static class UIFunctions _buttonOnPlanetGlobe.SetActive(true); } } + InitToggleAutoCruiseCheckButton(); InitStarmapButtons(); _initialized = true; } @@ -159,9 +155,53 @@ public static class UIFunctions rect.anchoredPosition3D = new Vector3(128f, -100f, 0f); } } -#endregion + #endregion + + #region ToggleAutoCruiseCheckButton + public static UI.MyCheckButton ToggleAutoCruise; + + public static void InitToggleAutoCruiseCheckButton() + { + var lowGroup = GameObject.Find("UI Root/Overlay Canvas/In Game/Low Group"); + ToggleAutoCruise = MyCheckButton.CreateCheckButton(0, 0, lowGroup.GetComponent(), Patches.PlayerPatch.AutoCruiseEnabled).WithSize(120f, 40f); + UpdateToggleAutoCruiseCheckButtonVisiblility(); + ToggleAutoCruiseChecked(); + ToggleAutoCruise.OnChecked += ToggleAutoCruiseChecked; + var rectTrans = ToggleAutoCruise.rectTrans; + rectTrans.anchorMax = new Vector2(0.5f, 0f); + rectTrans.anchorMin = new Vector2(0.5f, 0f); + rectTrans.pivot = new Vector2(0.5f, 0f); + rectTrans.anchoredPosition3D = new Vector3(0f, 185f, 0f); + static void ToggleAutoCruiseChecked() + { + if (ToggleAutoCruise.Checked) + { + ToggleAutoCruise.SetLabelText("Disable auto-cruise"); + } + else + { + ToggleAutoCruise.SetLabelText("Enable auto-cruise"); + } + } + } + + public static void UpdateToggleAutoCruiseCheckButtonVisiblility() + { + if (ToggleAutoCruise == null) return; + var active = Patches.PlayerPatch.AutoNavigationEnabled.Value && Patches.PlayerPatch.AutoNavigation.IndicatorAstroId > 0; + ToggleAutoCruise.gameObject.SetActive(active); + } + #endregion + + #region StarMapButtons + private static int _cornerComboBoxIndex; + private static string[] _starOrderNames; + private static bool _starmapFilterInitialized; + private static ulong[] _starmapStarFilterValues; + private static bool _starFilterEnabled; + public static UI.MyCheckButton StarmapFilterToggler; + public static bool[] ShowStarName; -#region StarMapButtons private static readonly Sprite[] PlanetIcons = [ null, null, @@ -677,5 +717,5 @@ public static class UIFunctions return (nongas, total); } } -#endregion + #endregion } diff --git a/UXAssist/Patches/GamePatch.cs b/UXAssist/Patches/GamePatch.cs index 17ce228..39976a8 100644 --- a/UXAssist/Patches/GamePatch.cs +++ b/UXAssist/Patches/GamePatch.cs @@ -80,7 +80,12 @@ public class GamePatch : PatchImpl I18N.Add("Logical frame rate: {0}x", "[UXA] Logical frame rate: {0}x", "[UXA] 逻辑帧速率: {0}x"); EnableWindowResizeEnabled.SettingChanged += (_, _) => EnableWindowResize.Enable(EnableWindowResizeEnabled.Value); - LoadLastWindowRectEnabled.SettingChanged += (_, _) => LoadLastWindowRect.Enable(LoadLastWindowRectEnabled.Value); + LoadLastWindowRectEnabled.SettingChanged += (_, _) => { + if (LoadLastWindowRectEnabled.Value) + { + FixLastWindowRect(); + } + }; MouseCursorScaleUpMultiplier.SettingChanged += (_, _) => { MouseCursorScaleUp.NeedReloadCursors = true; @@ -108,8 +113,16 @@ public class GamePatch : PatchImpl public static void Start() { RefreshSavePath(); + if (LoadLastWindowRectEnabled.Value) + { + FixLastWindowRect(); + var wnd = WindowFunctions.FindGameWindow(); + if (wnd != IntPtr.Zero) + { + ThreadingHelper.Instance.StartCoroutine(SetWindowPositionCoroutine(wnd, (int)LastWindowRect.Value.x, (int)LastWindowRect.Value.y)); + } + } EnableWindowResize.Enable(EnableWindowResizeEnabled.Value); - LoadLastWindowRect.Enable(LoadLastWindowRectEnabled.Value); MouseCursorScaleUp.NeedReloadCursors = false; MouseCursorScaleUp.Enable(MouseCursorScaleUpMultiplier.Value > 1); // AutoSaveOpt.Enable(AutoSaveOptEnabled.Value); @@ -120,7 +133,6 @@ public class GamePatch : PatchImpl public static void Uninit() { Enable(false); - LoadLastWindowRect.Enable(false); EnableWindowResize.Enable(false); MouseCursorScaleUp.NeedReloadCursors = false; MouseCursorScaleUp.Enable(false); @@ -158,18 +170,145 @@ public class GamePatch : PatchImpl var gameSaveFolder = GameConfig.gameSaveFolder; if (!Directory.Exists(gameSaveFolder)) Directory.CreateDirectory(gameSaveFolder); - if (UIRoot.instance.loadGameWindow.active) UIRoot.instance.loadGameWindow.RefreshList(); - if (UIRoot.instance.saveGameWindow.active) UIRoot.instance.saveGameWindow.RefreshList(); + if (UIRoot.instance?.loadGameWindow?.active == true) UIRoot.instance.loadGameWindow.RefreshList(); + if (UIRoot.instance?.saveGameWindow?.active == true) UIRoot.instance.saveGameWindow.RefreshList(); } [HarmonyPrefix, HarmonyPatch(typeof(GameMain), nameof(GameMain.HandleApplicationQuit))] private static void GameMain_HandleApplicationQuit_Prefix() { + if (!LoadLastWindowRectEnabled.Value) return; var wnd = WindowFunctions.FindGameWindow(); if (wnd == IntPtr.Zero) return; WinApi.GetWindowRect(wnd, out var rect); LastWindowRect.Value = new Vector4(rect.Left, rect.Top, Screen.width, Screen.height); } + private static void FixLastWindowRect() + { + if (Screen.fullScreenMode is not (FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow)) + { + var rect = LastWindowRect.Value; + var x = Mathf.RoundToInt(rect.x); + var y = Mathf.RoundToInt(rect.y); + var w = Mathf.RoundToInt(rect.z); + var h = Mathf.RoundToInt(rect.w); + var needFix = false; + if (w < 100) + { + w = 1280; + needFix = true; + } + + if (h < 100) + { + h = 720; + needFix = true; + } + + var rc = new WinApi.Rect { Left = x, Top = y, Right = x + w, Bottom = y + h }; + if (WinApi.MonitorFromRect(ref rc, 0) == IntPtr.Zero) + { + x = 0; + y = 0; + w = 1280; + h = 720; + needFix = true; + } + if (needFix) + { + LastWindowRect.Value = new Vector4(x, y, w, h); + } + } + } + + public static IEnumerator SetWindowPositionCoroutine(IntPtr wnd, int x, int y) + { + yield return new WaitForEndOfFrame(); + yield return new WaitForEndOfFrame(); + WinApi.SetWindowPos(wnd, IntPtr.Zero, x, y, 0, 0, 0x0235); + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(Screen), nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(FullScreenMode), typeof(int))] + private static void Screen_SetResolution_Prefix(ref int width, ref int height, FullScreenMode fullscreenMode, ref Vector2Int __state) + { + if (fullscreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow) return; + if (GameMain.isRunning) + { + var wnd = WindowFunctions.FindGameWindow(); + if (wnd == IntPtr.Zero) return; + WinApi.GetWindowRect(wnd, out var rc); + __state = new Vector2Int(rc.Left, rc.Top); + return; + } + else if (!LoadLastWindowRectEnabled.Value) return; + int x = 0, y = 0, w = 0, h = 0; + var rect = LastWindowRect.Value; + if (rect is not { z: 0f, w: 0f }) + { + x = Mathf.RoundToInt(rect.x); + y = Mathf.RoundToInt(rect.y); + w = Mathf.RoundToInt(rect.z); + h = Mathf.RoundToInt(rect.w); + } + width = w; + height = h; + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(Screen), nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(FullScreenMode), typeof(int))] + private static void Screen_SetResolution_Postfix(FullScreenMode fullscreenMode, Vector2Int __state) + { + if (fullscreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow) return; + var gameRunning = GameMain.isRunning; + if (!LoadLastWindowRectEnabled.Value && !gameRunning) return; + var wnd = WindowFunctions.FindGameWindow(); + if (wnd == IntPtr.Zero) return; + int x, y; + if (gameRunning) + { + x = __state.x; + y = __state.y; + } + else + { + var rect = LastWindowRect.Value; + if (rect is { z: 0f, w: 0f }) return; + x = Mathf.RoundToInt(rect.x); + y = Mathf.RoundToInt(rect.y); + } + ThreadingHelper.Instance.StartCoroutine(SetWindowPositionCoroutine(wnd, x, y)); + } + + private static GameOption _gameOption; + + [HarmonyPostfix] + [HarmonyPatch(typeof(UIOptionWindow), nameof(UIOptionWindow._OnOpen))] + private static void UIOptionWindow__OnOpen_Postfix() + { + _gameOption = DSPGame.globalOption; + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(GameOption), nameof(GameOption.Apply))] + private static IEnumerable UIOptionWindow_ApplyOptions_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + var label1 = generator.DefineLabel(); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(Screen), nameof(Screen.SetResolution), [typeof(int), typeof(int), typeof(bool), typeof(int)])) + ).Advance(1).Labels.Add(label1); + matcher.Start().Insert( + Transpilers.EmitDelegate(() => + _gameOption.fullscreen == DSPGame.globalOption.fullscreen && + _gameOption.resolution.width == DSPGame.globalOption.resolution.width && + _gameOption.resolution.height == DSPGame.globalOption.resolution.height && + _gameOption.resolution.refreshRate == DSPGame.globalOption.resolution.refreshRate + ), + new CodeInstruction(OpCodes.Brtrue, label1) + ); + return matcher.InstructionEnumeration(); + } private class EnableWindowResize : PatchImpl { @@ -215,135 +354,6 @@ public class GamePatch : PatchImpl } } - public class LoadLastWindowRect : PatchImpl - { - protected override void OnEnable() - { - if (Screen.fullScreenMode is not (FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow)) - { - var rect = LastWindowRect.Value; - var x = Mathf.RoundToInt(rect.x); - var y = Mathf.RoundToInt(rect.y); - var w = Mathf.RoundToInt(rect.z); - var h = Mathf.RoundToInt(rect.w); - var needFix = false; - if (w < 100) - { - w = 1280; - needFix = true; - } - - if (h < 100) - { - h = 720; - needFix = true; - } - - var rc = new WinApi.Rect { Left = x, Top = y, Right = x + w, Bottom = y + h }; - if (WinApi.MonitorFromRect(ref rc, 0) == IntPtr.Zero) - { - x = 0; - y = 0; - w = 1280; - h = 720; - needFix = true; - } - if (needFix) - { - LastWindowRect.Value = new Vector4(x, y, w, h); - } - } - } - - protected override void OnDisable() - { - //GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix; - } - - public static IEnumerator SetWindowPosition(IntPtr wnd, int x, int y) - { - yield return new WaitForEndOfFrame(); - yield return new WaitForEndOfFrame(); - WinApi.SetWindowPos(wnd, IntPtr.Zero, x, y, 0, 0, 0x0235); - } - - [HarmonyPrefix] - [HarmonyPatch(typeof(Screen), nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(FullScreenMode), typeof(int))] - private static void Screen_SetResolution_Prefix(ref int width, ref int height, FullScreenMode fullscreenMode, ref Vector2Int __state) - { - if (fullscreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow) return; - int x = 0, y = 0, w = 0, h = 0; - var rect = LastWindowRect.Value; - if (rect is not { z: 0f, w: 0f }) - { - x = Mathf.RoundToInt(rect.x); - y = Mathf.RoundToInt(rect.y); - w = Mathf.RoundToInt(rect.z); - h = Mathf.RoundToInt(rect.w); - } - if (GameMain.isRunning) - { - __state = new Vector2Int(x, y); - return; - } - width = w; - height = h; - } - - [HarmonyPostfix] - [HarmonyPatch(typeof(Screen), nameof(Screen.SetResolution), typeof(int), typeof(int), typeof(FullScreenMode), typeof(int))] - private static void Screen_SetResolution_Postfix(FullScreenMode fullscreenMode, Vector2Int __state) - { - if (fullscreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow) return; - var wnd = WindowFunctions.FindGameWindow(); - if (wnd == IntPtr.Zero) return; - int x, y; - if (GameMain.isRunning) - { - x = __state.x; - y = __state.y; - } - else - { - var rect = LastWindowRect.Value; - if (rect is { z: 0f, w: 0f }) return; - x = Mathf.RoundToInt(rect.x); - y = Mathf.RoundToInt(rect.y); - } - ThreadingHelper.Instance.StartCoroutine(SetWindowPosition(wnd, x, y)); - } - - private static GameOption _gameOption; - - [HarmonyPostfix] - [HarmonyPatch(typeof(UIOptionWindow), nameof(UIOptionWindow._OnOpen))] - private static void UIOptionWindow__OnOpen_Postfix() - { - _gameOption = DSPGame.globalOption; - } - - [HarmonyTranspiler] - [HarmonyPatch(typeof(GameOption), nameof(GameOption.Apply))] - private static IEnumerable UIOptionWindow_ApplyOptions_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - var label1 = generator.DefineLabel(); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(Screen), nameof(Screen.SetResolution), [typeof(int), typeof(int), typeof(bool), typeof(int)])) - ).Advance(1).Labels.Add(label1); - matcher.Start().Insert( - Transpilers.EmitDelegate(() => - _gameOption.fullscreen == DSPGame.globalOption.fullscreen && - _gameOption.resolution.width == DSPGame.globalOption.resolution.width && - _gameOption.resolution.height == DSPGame.globalOption.resolution.height && - _gameOption.resolution.refreshRate == DSPGame.globalOption.resolution.refreshRate - ), - new CodeInstruction(OpCodes.Brtrue, label1) - ); - return matcher.InstructionEnumeration(); - } - } - /* private class AutoSaveOpt: PatchImpl { diff --git a/UXAssist/Patches/PlayerPatch.cs b/UXAssist/Patches/PlayerPatch.cs index e9b2e06..d68a9d8 100644 --- a/UXAssist/Patches/PlayerPatch.cs +++ b/UXAssist/Patches/PlayerPatch.cs @@ -58,6 +58,8 @@ public class PlayerPatch : PatchImpl HideTipsForSandsChangesEnabled.SettingChanged += (_, _) => HideTipsForSandsChanges.Enable(HideTipsForSandsChangesEnabled.Value); ShortcutKeysForStarsNameEnabled.SettingChanged += (_, _) => ShortcutKeysForStarsName.Enable(ShortcutKeysForStarsNameEnabled.Value); AutoNavigationEnabled.SettingChanged += (_, _) => AutoNavigation.Enable(AutoNavigationEnabled.Value); + AutoNavigationEnabled.SettingChanged += (_, _) => Functions.UIFunctions.UpdateToggleAutoCruiseCheckButtonVisiblility(); + AutoCruiseEnabled.SettingChanged += (_, _) => Functions.UIFunctions.UpdateToggleAutoCruiseCheckButtonVisiblility(); } public static void Start() @@ -128,7 +130,7 @@ public class PlayerPatch : PatchImpl } - private class EnhancedMechaForgeCountControl: PatchImpl + private class EnhancedMechaForgeCountControl : PatchImpl { [HarmonyTranspiler] [HarmonyPatch(typeof(UIReplicatorWindow), nameof(UIReplicatorWindow.OnOkButtonClick))] @@ -179,7 +181,7 @@ public class PlayerPatch : PatchImpl } } - private class HideTipsForSandsChanges: PatchImpl + private class HideTipsForSandsChanges : PatchImpl { [HarmonyTranspiler] [HarmonyPatch(typeof(Player), nameof(Player.SetSandCount))] @@ -193,7 +195,7 @@ public class PlayerPatch : PatchImpl } } - public class ShortcutKeysForStarsName: PatchImpl + public class ShortcutKeysForStarsName : PatchImpl { public static int ShowAllStarsNameStatus; public static bool ForceShowAllStarsName; @@ -226,114 +228,116 @@ public class PlayerPatch : PatchImpl { ShowAllStarsNameStatus = 0; } -/* - [HarmonyTranspiler] - [HarmonyPatch(typeof(UIStarmapPlanet), nameof(UIStarmapPlanet._OnLateUpdate))] - private static IEnumerable UIStarmapPlanet__OnLateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(OpCodes.Ldloc_3), - new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(UIStarmapPlanet), nameof(UIStarmapPlanet.projected))) - ); - matcher.Advance(3); - matcher.CreateLabel(out var jumpPos1); - matcher.InsertAndAdvance( - new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(ShortcutKeysForStarsName), nameof(_showAllStarsNameStatus))), - new CodeInstruction(OpCodes.Ldc_I4_2), - new CodeInstruction(OpCodes.Ceq), - new CodeInstruction(OpCodes.Brfalse, jumpPos1), - new CodeInstruction(OpCodes.Ldc_I4_0), - new CodeInstruction(OpCodes.Stloc_3) - ); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIStarmapPlanet), nameof(UIStarmapPlanet.gameHistory))), - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIStarmapPlanet), nameof(UIStarmapPlanet.planet))), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlanetData), nameof(PlanetData.id))), - new CodeMatch(OpCodes.Callvirt, AccessTools.Field(typeof(GameHistoryData), nameof(GameHistoryData.GetPlanetPin))), - new CodeMatch(OpCodes.Ldc_I4_1), - new CodeMatch(ci => ci.Branches(out _)), - new CodeMatch(OpCodes.Ldc_I4_1), - new CodeMatch(ci => ci.IsStloc()), - new CodeMatch(ci => ci.Branches(out _)) - ); - matcher.CreateLabelAt(matcher.Pos + 8, out var jumpPos); - var labels = matcher.Labels; - matcher.Labels = null; - matcher.InsertAndAdvance( - new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(ShortcutKeysForStarsName), nameof(_showAllStarsNameStatus))).WithLabels(labels), - new CodeInstruction(OpCodes.Ldc_I4_1), - new CodeInstruction(OpCodes.Ceq), - new CodeInstruction(OpCodes.Brtrue, jumpPos), - new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PlayerPatch), nameof(_showAllStarsNameKey))), - new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(KeyBindings), nameof(KeyBindings.IsKeyPressing))), - new CodeInstruction(OpCodes.Brtrue, jumpPos) - ); - return matcher.InstructionEnumeration(); - } + /* + [HarmonyTranspiler] + [HarmonyPatch(typeof(UIStarmapPlanet), nameof(UIStarmapPlanet._OnLateUpdate))] + private static IEnumerable UIStarmapPlanet__OnLateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(OpCodes.Ldloc_3), + new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(UIStarmapPlanet), nameof(UIStarmapPlanet.projected))) + ); + matcher.Advance(3); + matcher.CreateLabel(out var jumpPos1); + matcher.InsertAndAdvance( + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(ShortcutKeysForStarsName), nameof(_showAllStarsNameStatus))), + new CodeInstruction(OpCodes.Ldc_I4_2), + new CodeInstruction(OpCodes.Ceq), + new CodeInstruction(OpCodes.Brfalse, jumpPos1), + new CodeInstruction(OpCodes.Ldc_I4_0), + new CodeInstruction(OpCodes.Stloc_3) + ); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIStarmapPlanet), nameof(UIStarmapPlanet.gameHistory))), + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIStarmapPlanet), nameof(UIStarmapPlanet.planet))), + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(PlanetData), nameof(PlanetData.id))), + new CodeMatch(OpCodes.Callvirt, AccessTools.Field(typeof(GameHistoryData), nameof(GameHistoryData.GetPlanetPin))), + new CodeMatch(OpCodes.Ldc_I4_1), + new CodeMatch(ci => ci.Branches(out _)), + new CodeMatch(OpCodes.Ldc_I4_1), + new CodeMatch(ci => ci.IsStloc()), + new CodeMatch(ci => ci.Branches(out _)) + ); + matcher.CreateLabelAt(matcher.Pos + 8, out var jumpPos); + var labels = matcher.Labels; + matcher.Labels = null; + matcher.InsertAndAdvance( + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(ShortcutKeysForStarsName), nameof(_showAllStarsNameStatus))).WithLabels(labels), + new CodeInstruction(OpCodes.Ldc_I4_1), + new CodeInstruction(OpCodes.Ceq), + new CodeInstruction(OpCodes.Brtrue, jumpPos), + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PlayerPatch), nameof(_showAllStarsNameKey))), + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(KeyBindings), nameof(KeyBindings.IsKeyPressing))), + new CodeInstruction(OpCodes.Brtrue, jumpPos) + ); + return matcher.InstructionEnumeration(); + } - [HarmonyTranspiler] - [HarmonyPatch(typeof(UIStarmapDFHive), nameof(UIStarmapDFHive._OnLateUpdate))] - private static IEnumerable UIStarmapDFHive__OnLateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(ci => ci.IsLdloc()), - new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(UIStarmapDFHive), nameof(UIStarmapDFHive.projected))) - ); - matcher.Advance(3); - matcher.CreateLabel(out var jumpPos1); - matcher.InsertAndAdvance( - new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(ShortcutKeysForStarsName), nameof(_showAllStarsNameStatus))), - new CodeInstruction(OpCodes.Ldc_I4_2), - new CodeInstruction(OpCodes.Ceq), - new CodeInstruction(OpCodes.Brfalse, jumpPos1), - new CodeInstruction(OpCodes.Ldc_I4_0), - new CodeInstruction(OpCodes.Stloc_S, 4) - ); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIStarmapDFHive), nameof(UIStarmapDFHive.gameHistory))), - new CodeMatch(OpCodes.Ldarg_0), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIStarmapDFHive), nameof(UIStarmapDFHive.hive))), - new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(EnemyDFHiveSystem), nameof(EnemyDFHiveSystem.hiveStarId))), - new CodeMatch(OpCodes.Ldc_I4, 1000000), - new CodeMatch(OpCodes.Sub), - new CodeMatch(OpCodes.Callvirt, AccessTools.Field(typeof(GameHistoryData), nameof(GameHistoryData.GetHivePin))), - new CodeMatch(OpCodes.Ldc_I4_1), - new CodeMatch(ci => ci.Branches(out _)), - new CodeMatch(OpCodes.Ldc_I4_1), - new CodeMatch(ci => ci.IsStloc()), - new CodeMatch(ci => ci.Branches(out _)) - ); - matcher.CreateLabelAt(matcher.Pos + 10, out var jumpPos); - var labels = matcher.Labels; - matcher.Labels = null; - matcher.InsertAndAdvance( - new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(ShortcutKeysForStarsName), nameof(_showAllStarsNameStatus))).WithLabels(labels), - new CodeInstruction(OpCodes.Ldc_I4_1), - new CodeInstruction(OpCodes.Ceq), - new CodeInstruction(OpCodes.Brtrue, jumpPos), - new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PlayerPatch), nameof(_showAllStarsNameKey))), - new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(KeyBindings), nameof(KeyBindings.IsKeyPressing))), - new CodeInstruction(OpCodes.Brtrue, jumpPos) - ); - return matcher.InstructionEnumeration(); - } -*/ + [HarmonyTranspiler] + [HarmonyPatch(typeof(UIStarmapDFHive), nameof(UIStarmapDFHive._OnLateUpdate))] + private static IEnumerable UIStarmapDFHive__OnLateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(ci => ci.IsLdloc()), + new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(UIStarmapDFHive), nameof(UIStarmapDFHive.projected))) + ); + matcher.Advance(3); + matcher.CreateLabel(out var jumpPos1); + matcher.InsertAndAdvance( + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(ShortcutKeysForStarsName), nameof(_showAllStarsNameStatus))), + new CodeInstruction(OpCodes.Ldc_I4_2), + new CodeInstruction(OpCodes.Ceq), + new CodeInstruction(OpCodes.Brfalse, jumpPos1), + new CodeInstruction(OpCodes.Ldc_I4_0), + new CodeInstruction(OpCodes.Stloc_S, 4) + ); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIStarmapDFHive), nameof(UIStarmapDFHive.gameHistory))), + new CodeMatch(OpCodes.Ldarg_0), + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(UIStarmapDFHive), nameof(UIStarmapDFHive.hive))), + new CodeMatch(OpCodes.Ldfld, AccessTools.Field(typeof(EnemyDFHiveSystem), nameof(EnemyDFHiveSystem.hiveStarId))), + new CodeMatch(OpCodes.Ldc_I4, 1000000), + new CodeMatch(OpCodes.Sub), + new CodeMatch(OpCodes.Callvirt, AccessTools.Field(typeof(GameHistoryData), nameof(GameHistoryData.GetHivePin))), + new CodeMatch(OpCodes.Ldc_I4_1), + new CodeMatch(ci => ci.Branches(out _)), + new CodeMatch(OpCodes.Ldc_I4_1), + new CodeMatch(ci => ci.IsStloc()), + new CodeMatch(ci => ci.Branches(out _)) + ); + matcher.CreateLabelAt(matcher.Pos + 10, out var jumpPos); + var labels = matcher.Labels; + matcher.Labels = null; + matcher.InsertAndAdvance( + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(ShortcutKeysForStarsName), nameof(_showAllStarsNameStatus))).WithLabels(labels), + new CodeInstruction(OpCodes.Ldc_I4_1), + new CodeInstruction(OpCodes.Ceq), + new CodeInstruction(OpCodes.Brtrue, jumpPos), + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PlayerPatch), nameof(_showAllStarsNameKey))), + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(KeyBindings), nameof(KeyBindings.IsKeyPressing))), + new CodeInstruction(OpCodes.Brtrue, jumpPos) + ); + return matcher.InstructionEnumeration(); + } + */ } - public class AutoNavigation: PatchImpl + public class AutoNavigation : PatchImpl { private static bool _canUseWarper; private static int _indicatorAstroId; private static bool _speedUp; private static Vector3 _direction; + public static int IndicatorAstroId => _indicatorAstroId; + public static void ToggleAutoCruise() { AutoCruiseEnabled.Value = !AutoCruiseEnabled.Value; @@ -361,9 +365,9 @@ public class PlayerPatch : PatchImpl if (navi.indicatorAstroId != _indicatorAstroId) { _indicatorAstroId = navi.indicatorAstroId; - if (_indicatorAstroId == 0) return; + Functions.UIFunctions.UpdateToggleAutoCruiseCheckButtonVisiblility(); } - else if (_indicatorAstroId == 0) return; + if (_indicatorAstroId == 0) return; switch (controller.movementStateInFrame) { case EMovementState.Walk: @@ -390,12 +394,12 @@ public class PlayerPatch : PatchImpl var astroVec = astro.uPos - playerPos; var distance = astroVec.magnitude; if (distance < astro.type switch - { - EAstroType.Planet => 800.0 + astro.uRadius, - EAstroType.Star => 4000.0 + astro.uRadius, - EAstroType.EnemyHive => 800.0, - _ => 2000.0 + astro.uRadius - }) + { + EAstroType.Planet => 800.0 + astro.uRadius, + EAstroType.Star => 4000.0 + astro.uRadius, + EAstroType.EnemyHive => 800.0, + _ => 2000.0 + astro.uRadius + }) { if (isHive) { @@ -478,12 +482,12 @@ public class PlayerPatch : PatchImpl if (distance < GalaxyData.LY * 1.5) { if (distance < actionSail.currentWarpSpeed * distance switch - { - > GalaxyData.LY * 0.6 => 0.33, - > GalaxyData.LY * 0.3 => 0.5, - > GalaxyData.LY * 0.1 => 0.66, - _ => 1.0 - }) + { + > GalaxyData.LY * 0.6 => 0.33, + > GalaxyData.LY * 0.3 => 0.5, + > GalaxyData.LY * 0.1 => 0.66, + _ => 1.0 + }) { controller.input0.y = -1f; } diff --git a/UXAssist/UI/MyCheckButton.cs b/UXAssist/UI/MyCheckButton.cs index 9bc4d4e..42f1f18 100644 --- a/UXAssist/UI/MyCheckButton.cs +++ b/UXAssist/UI/MyCheckButton.cs @@ -5,7 +5,6 @@ using UnityEngine.UI; namespace UXAssist.UI; -// MyCheckButton modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyCheckButton.cs public class MyCheckButton : MonoBehaviour { public RectTransform rectTrans; diff --git a/UXAssist/UI/MyFlatButton.cs b/UXAssist/UI/MyFlatButton.cs new file mode 100644 index 0000000..7fb5ad5 --- /dev/null +++ b/UXAssist/UI/MyFlatButton.cs @@ -0,0 +1,95 @@ +using System; +using BepInEx.Configuration; +using UnityEngine; +using UnityEngine.UI; + +namespace UXAssist.UI; + +public class MyFlatButton : MonoBehaviour +{ + public RectTransform rectTrans; + public UIButton uiButton; + public Text labelText; + + private static GameObject _baseObject; + + public static void InitBaseObject() + { + if (_baseObject) return; + var panel = UIRoot.instance.uiGame.dysonEditor.controlPanel.hierarchy.layerPanel; + var go = Instantiate(panel.layerButtons[0].gameObject); + var btn = go.GetComponent(); + btn.gameObject.name = "my-flatbutton"; + btn.highlighted = false; + var img = btn.GetComponent(); + if (img != null) + { + img.sprite = panel.buttonDefaultSprite; + img.color = new Color(img.color.r, img.color.g, img.color.b, 13f / 255f); + } + + img = btn.gameObject.transform.Find("frame")?.GetComponent(); + if (img != null) + { + img.color = new Color(img.color.r, img.color.g, img.color.b, 0f); + } + + btn.button.onClick.RemoveAllListeners(); + _baseObject = go; + } + + public static MyFlatButton CreateFlatButton(float x, float y, RectTransform parent, string label = "", int fontSize = 15, Action onClick = null) + { + return CreateFlatButton(x, y, parent, fontSize, onClick).WithLabelText(label); + } + + public static MyFlatButton CreateFlatButton(float x, float y, RectTransform parent, int fontSize = 15, Action onClick = null) + { + var go = Instantiate(_baseObject); + go.name = "my-flatbutton"; + go.SetActive(true); + var cb = go.AddComponent(); + var rect = Util.NormalizeRectWithTopLeft(cb, x, y, parent); + + cb.rectTrans = rect; + cb.uiButton = go.GetComponent(); + + cb.labelText = go.transform.Find("Text")?.GetComponent(); + cb.uiButton.onClick += onClick; + return cb; + } + + public void SetLabelText(string val) + { + if (labelText != null) + { + labelText.text = val.Translate(); + } + } + + public MyFlatButton WithLabelText(string val) + { + SetLabelText(val); + return this; + } + + public MyFlatButton WithSize(float width, float height) + { + rectTrans.sizeDelta = new Vector2(width, height); + return this; + } + + public MyFlatButton WithTip(string tip, float delay = 1f) + { + uiButton.tips.type = UIButton.ItemTipType.Other; + uiButton.tips.topLevel = true; + uiButton.tips.tipTitle = tip; + uiButton.tips.tipText = null; + uiButton.tips.delay = delay; + uiButton.tips.corner = 2; + uiButton.UpdateTip(); + return this; + } + public float Width => rectTrans.sizeDelta.x + labelText.rectTransform.sizeDelta.x; + public float Height => Math.Max(rectTrans.sizeDelta.y, labelText.rectTransform.sizeDelta.y); +} diff --git a/UXAssist/UI/MyWindow.cs b/UXAssist/UI/MyWindow.cs index aa3469f..2cf4302 100644 --- a/UXAssist/UI/MyWindow.cs +++ b/UXAssist/UI/MyWindow.cs @@ -194,38 +194,13 @@ public class MyWindow : ManualBehaviour return btn; } - public UIButton AddFlatButton(float x, float y, RectTransform parent, string text = "", int fontSize = 12, string objName = "button", UnityAction onClick = null) + public MyFlatButton 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]); + var btn = MyFlatButton.CreateFlatButton(x, y, parent, text, fontSize, _ => onClick()); btn.gameObject.name = objName; - btn.highlighted = false; - var img = btn.GetComponent(); - if (img != null) - { - img.sprite = panel.buttonDefaultSprite; - img.color = new Color(img.color.r, img.color.g, img.color.b, 13f / 255f); - } - img = btn.gameObject.transform.Find("frame")?.GetComponent(); - if (img != null) - { - img.color = new Color(img.color.r, img.color.g, img.color.b, 0f); - } - - var rect = Util.NormalizeRectWithTopLeft(btn, x, y, parent); - var t = btn.gameObject.transform.Find("Text")?.GetComponent(); - if (t != null) - { - t.text = text.Translate(); - t.fontSize = fontSize; - } - - btn.button.onClick.RemoveAllListeners(); - if (onClick != null) btn.button.onClick.AddListener(onClick); - - _maxX = Math.Max(_maxX, x + rect.sizeDelta.x); - MaxY = Math.Max(MaxY, y + rect.sizeDelta.y); + _maxX = Math.Max(_maxX, x + btn.Width); + MaxY = Math.Max(MaxY, y + btn.Height); return btn; } @@ -568,6 +543,7 @@ public abstract class MyWindowManager MyCheckBox.InitBaseObject(); MyComboBox.InitBaseObject(); MyCornerComboBox.InitBaseObject(); + MyFlatButton.InitBaseObject(); } public static T CreateWindow(string name, string title = "") where T : MyWindow diff --git a/UXAssist/UIConfigWindow.cs b/UXAssist/UIConfigWindow.cs index 1810ee1..622fdd1 100644 --- a/UXAssist/UIConfigWindow.cs +++ b/UXAssist/UIConfigWindow.cs @@ -195,7 +195,7 @@ public static class UIConfigWindow public override string FormatValue(string format, int value) { var sb = new StringBuilder(" "); - StringBuilderUtility.WriteKMG(sb, 8, (long)value * 300000L, false); + StringBuilderUtility.WriteKMG(sb, 8, value * 300000L, false); sb.Append('W'); return sb.ToString().Trim(); } @@ -207,7 +207,7 @@ public static class UIConfigWindow public override string FormatValue(string format, int value) { var sb = new StringBuilder(" "); - StringBuilderUtility.WriteKMG(sb, 8, (long)value * 300000L, false); + StringBuilderUtility.WriteKMG(sb, 8, value * 300000L, false); sb.Append('W'); return sb.ToString().Trim(); } @@ -219,7 +219,7 @@ public static class UIConfigWindow public override string FormatValue(string format, int value) { var sb = new StringBuilder(" "); - StringBuilderUtility.WriteKMG(sb, 8, (long)value * 3000000L, false); + StringBuilderUtility.WriteKMG(sb, 8, value * 3000000L, false); sb.Append('W'); return sb.ToString().Trim(); } @@ -246,7 +246,7 @@ public static class UIConfigWindow public override string FormatValue(string format, int value) { var sb = new StringBuilder(" "); - StringBuilderUtility.WriteKMG(sb, 8, (long)value * 15000000L, false); + StringBuilderUtility.WriteKMG(sb, 8, value * 15000000L, false); sb.Append('W'); return sb.ToString().Trim(); } @@ -717,9 +717,8 @@ public static class UIConfigWindow UIMessageBox.Show("Dismantle selected layer".Translate(), "Dismantle selected layer Confirm".Translate(), "取消".Translate(), "确定".Translate(), 2, null, () => { DysonSphereFunctions.InitCurrentDysonLayer(star, id); }); } - ); - ((RectTransform)btn.transform).sizeDelta = new Vector2(40f, 20f); - DysonLayerBtn[i] = btn; + ).WithSize(40f, 20f); + DysonLayerBtn[i] = btn.uiButton; if (i == 4) { x -= 160f;