From ce199374b4ee156508abb66f706155d981114f5f Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Tue, 23 Jun 2026 03:13:23 +0800 Subject: [PATCH] refactor(UXAssist): split UIFunctions into UI sub-features --- UXAssist/Functions/UI/AutoConstructUI.cs | 107 ++ UXAssist/Functions/UI/AutoCruiseUI.cs | 66 ++ UXAssist/Functions/UI/MenuButtonUI.cs | 158 +++ UXAssist/Functions/UI/MilkyWayUI.cs | 325 ++++++ UXAssist/Functions/UI/StarmapFilterUI.cs | 564 +++++++++++ UXAssist/Functions/UIFunctions.cs | 1168 ++-------------------- UXAssist/Patches/PlayerPatch.cs | 2 +- UXAssist/Patches/UIPatch.cs | 8 +- UXAssist/UXAssist.cs | 4 +- 9 files changed, 1323 insertions(+), 1079 deletions(-) create mode 100644 UXAssist/Functions/UI/AutoConstructUI.cs create mode 100644 UXAssist/Functions/UI/AutoCruiseUI.cs create mode 100644 UXAssist/Functions/UI/MenuButtonUI.cs create mode 100644 UXAssist/Functions/UI/MilkyWayUI.cs create mode 100644 UXAssist/Functions/UI/StarmapFilterUI.cs diff --git a/UXAssist/Functions/UI/AutoConstructUI.cs b/UXAssist/Functions/UI/AutoConstructUI.cs new file mode 100644 index 0000000..2008f7d --- /dev/null +++ b/UXAssist/Functions/UI/AutoConstructUI.cs @@ -0,0 +1,107 @@ +using System; +using UnityEngine; +using UnityEngine.UI; +using UXAssist.Common; +using UXAssist.UI; + +namespace UXAssist.Functions.UI; + +internal static class AutoConstructUI +{ + public static MyCheckButton ToggleAutoConstruct; + public static GameObject ConstructCountPanel; + public static Text ConstructCountText; + + public static void Init() + { + I18N.Add("Enable auto-construct", "Enable auto-construct", "启用自动建造"); + I18N.Add("Disable auto-construct", "Disable auto-construct", "禁用自动建造"); + I18N.Add("Buildings to construct: {0}", "Buildings to construct: {0}", "待建造数量: {0}"); + } + + public static void Start() + { + } + + public static void Uninit() + { + } + + public static void OnInputUpdate() + { + } + + public static void OnUpdate() + { + } + + public static void InitToggleAutoConstructCheckButton() + { + var lowGroup = GameObject.Find("UI Root/Overlay Canvas/In Game/Low Group"); + var parent = lowGroup.GetComponent(); + ToggleAutoConstruct = MyCheckButton.CreateCheckButton(0, 0, parent, Patches.Factory.FactoryPatch.AutoConstructEnabled).WithSize(160f, 40f); + var rectTrans = ToggleAutoConstruct.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(-165f, 185f, 0f); + rectTrans.localScale = new Vector3(1f, 1f, 1f); + + ConstructCountPanel = new GameObject("uxassist-construct-count-panel"); + rectTrans = ConstructCountPanel.AddComponent(); + rectTrans.SetParent(parent); + 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(-165f, 161f, 0f); + rectTrans.localScale = new Vector3(1f, 1f, 1f); + rectTrans.sizeDelta = new Vector2(160f, 24f); + var bg = ConstructCountPanel.AddComponent(); + bg.color = new Color(0.2f, 0.2f, 0.2f, 0.6f); + + ConstructCountText = GameObject.Instantiate(UIRoot.instance.uiGame.assemblerWindow.stateText); + ConstructCountText.gameObject.name = "construct-count-text"; + ConstructCountText.text = String.Format("Buildings to construct: {0}".Translate(), 0); + ConstructCountText.color = new Color(1f, 1f, 1f, 0.4f); + ConstructCountText.alignment = TextAnchor.MiddleLeft; + ConstructCountText.fontSize = 16; + rectTrans = ConstructCountText.rectTransform; + rectTrans.SetParent(ConstructCountPanel.transform); + rectTrans.sizeDelta = new Vector2(150f, 20f); + rectTrans.anchorMax = new Vector2(0.5f, 0.5f); + rectTrans.anchorMin = new Vector2(0.5f, 0.5f); + rectTrans.pivot = new Vector2(0.5f, 0.5f); + rectTrans.anchoredPosition3D = new Vector3(0f, 0f, 0f); + rectTrans.localScale = new Vector3(1f, 1f, 1f); + + UpdateToggleAutoConstructCheckButtonVisiblility(); + ToggleAutoConstructChecked(); + ToggleAutoConstruct.OnChecked += ToggleAutoConstructChecked; + static void ToggleAutoConstructChecked() + { + if (ToggleAutoConstruct.Checked) + { + ToggleAutoConstruct.SetLabelText("Disable auto-construct"); + } + else + { + ToggleAutoConstruct.SetLabelText("Enable auto-construct"); + } + } + } + + public static void UpdateToggleAutoConstructCheckButtonVisiblility() + { + if (ToggleAutoConstruct == null) return; + var localPlanet = GameMain.localPlanet; + var active = localPlanet != null && localPlanet.factoryLoaded && localPlanet.factory.prebuildCount > 0 && Patches.Factory.FactoryPatch.AutoConstructButtonEnabled.Value; + ToggleAutoConstruct.gameObject.SetActive(active); + ConstructCountPanel.gameObject.SetActive(active); + } + + public static void UpdateConstructCountText(int count) + { + if (ConstructCountText == null) return; + ConstructCountText.text = String.Format("Buildings to construct: {0}".Translate(), count); + } +} diff --git a/UXAssist/Functions/UI/AutoCruiseUI.cs b/UXAssist/Functions/UI/AutoCruiseUI.cs new file mode 100644 index 0000000..8355b36 --- /dev/null +++ b/UXAssist/Functions/UI/AutoCruiseUI.cs @@ -0,0 +1,66 @@ +using UnityEngine; +using UXAssist.Common; +using UXAssist.UI; + +namespace UXAssist.Functions.UI; + +internal static class AutoCruiseUI +{ + public static MyCheckButton ToggleAutoCruise; + + public static void Init() + { + I18N.Add("Enable auto-cruise", "Enable auto-cruise", "启用自动巡航"); + I18N.Add("Disable auto-cruise", "Disable auto-cruise", "禁用自动巡航"); + } + + public static void Start() + { + } + + public static void Uninit() + { + } + + public static void OnInputUpdate() + { + } + + public static void OnUpdate() + { + } + + 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(160f, 40f); + 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); + rectTrans.localScale = new Vector3(1f, 1f, 1f); + + UpdateToggleAutoCruiseCheckButtonVisiblility(); + ToggleAutoCruiseChecked(); + ToggleAutoCruise.OnChecked += ToggleAutoCruiseChecked; + 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); + } +} diff --git a/UXAssist/Functions/UI/MenuButtonUI.cs b/UXAssist/Functions/UI/MenuButtonUI.cs new file mode 100644 index 0000000..d5b3c43 --- /dev/null +++ b/UXAssist/Functions/UI/MenuButtonUI.cs @@ -0,0 +1,158 @@ +using UnityEngine; +using UnityEngine.UI; +using CommonAPI.Systems; +using UXAssist.Common; +using UXAssist.UI; +using GameLogicProc = UXAssist.Common.GameLogic; + +namespace UXAssist.Functions.UI; + +internal static class MenuButtonUI +{ + private static bool _initialized; + private static PressKeyBind _toggleKey; + private static bool _configWinInitialized; + private static MyConfigWindow _configWin; + private static GameObject _buttonOnPlanetGlobe; + + public static void Init() + { + _toggleKey = KeyBindings.RegisterKeyBinding(new BuiltinKey + { + key = new CombineKey((int)KeyCode.BackQuote, CombineKey.ALT_COMB, ECombineKeyAction.OnceClick, false), + conflictGroup = KeyBindConflict.MOVEMENT | KeyBindConflict.FLYING | KeyBindConflict.SAILING | KeyBindConflict.BUILD_MODE_1 | KeyBindConflict.KEYBOARD_KEYBIND, + name = "OpenUXAssistConfigWindow", + canOverride = true + }); + I18N.Add("KEYOpenUXAssistConfigWindow", "[UXA] Open UXAssist Config Window", "[UXA] 打开UX助手设置面板"); + I18N.Add("UXAssist Config", "UXAssist Config", "UX助手设置"); + I18N.OnInitialized += RecreateConfigWindow; + } + + public static void Start() + { + } + + public static void Uninit() + { + } + + public static void OnInputUpdate() + { + if (_toggleKey.keyValue) + { + ToggleConfigWindow(); + } + } + + public static void OnUpdate() + { + } + + public static void ToggleConfigWindow() + { + if (!_configWinInitialized) + { + if (!I18N.Initialized()) return; + _configWinInitialized = true; + _configWin = MyConfigWindow.CreateInstance(); + } + + if (_configWin.active) + { + _configWin._Close(); + } + else + { + _configWin.Open(); + } + } + + public static void InitMenuButtons() + { + if (_initialized) return; + var uiRoot = UIRoot.instance; + if (!uiRoot) return; + { + var mainMenu = uiRoot.uiMainMenu; + var src = mainMenu.newGameButton; + var parent = src.transform.parent; + var btn = GameObject.Instantiate(src, parent); + btn.name = "button-uxassist-config"; + var l = btn.text.GetComponent(); + if (l != null) + { + l.stringKey = "UXAssist Config"; + l.translation = "UXAssist Config".Translate(); + } + + btn.text.text = "UXAssist 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.uiGame.planetGlobe; + var src = panel.button2; + var sandboxMenu = uiRoot.uiGame.sandboxMenu; + var icon = sandboxMenu.categoryButtons[6].transform.Find("icon")?.GetComponent()?.sprite; + var b = GameObject.Instantiate(src, src.transform.parent); + _buttonOnPlanetGlobe = b.gameObject; + var rect = (RectTransform)_buttonOnPlanetGlobe.transform; + var btn = _buttonOnPlanetGlobe.GetComponent(); + var img = _buttonOnPlanetGlobe.transform.Find("button-2/icon")?.GetComponent(); + if (img != null) + { + img.sprite = icon; + } + + if (_buttonOnPlanetGlobe != null && btn != null) + { + _buttonOnPlanetGlobe.name = "open-uxassist-config"; + rect.localScale = new Vector3(0.6f, 0.6f, 0.6f); + rect.anchoredPosition3D = new Vector3(64f, -5f, 0f); + b.onClick.RemoveAllListeners(); + btn.onClick += _ => { ToggleConfigWindow(); }; + btn.tips.tipTitle = "UXAssist Config"; + I18N.OnInitialized += () => { btn.tips.tipTitle = "UXAssist Config".Translate(); }; + btn.tips.tipText = null; + btn.tips.corner = 9; + btn.tips.offset = new Vector2(-20f, -20f); + _buttonOnPlanetGlobe.SetActive(true); + } + } + AutoCruiseUI.InitToggleAutoCruiseCheckButton(); + AutoConstructUI.InitToggleAutoConstructCheckButton(); + StarmapFilterUI.InitStarmapButtons(); + _initialized = true; + } + + public static void RecreateConfigWindow() + { + if (!_configWinInitialized) return; + var wasActive = _configWin.active; + if (wasActive) _configWin._Close(); + MyConfigWindow.DestroyInstance(_configWin); + _configWinInitialized = false; + if (wasActive) ToggleConfigWindow(); + } + + public static void UpdateGlobeButtonPosition(UIPlanetGlobe planetGlobe) + { + if (_buttonOnPlanetGlobe == null) return; + var rect = (RectTransform)_buttonOnPlanetGlobe.transform; + if (planetGlobe.dysonSphereSystemUnlocked || planetGlobe.logisticsSystemUnlocked) + { + rect.anchoredPosition3D = new Vector3(64f, -5f, 0f); + } + else + { + rect.anchoredPosition3D = new Vector3(128f, -100f, 0f); + } + } +} diff --git a/UXAssist/Functions/UI/MilkyWayUI.cs b/UXAssist/Functions/UI/MilkyWayUI.cs new file mode 100644 index 0000000..59b97c8 --- /dev/null +++ b/UXAssist/Functions/UI/MilkyWayUI.cs @@ -0,0 +1,325 @@ +using System; +using System.IO; +using System.Text; +using UnityEngine; +using UnityEngine.UI; +using UXAssist.Common; +using UXAssist.UI; + +namespace UXAssist.Functions.UI; + +internal static class MilkyWayUI +{ + const int ClusterUploadResultKeepCount = 100; + private static readonly ClusterUploadResult[] _clusterUploadResults = new ClusterUploadResult[ClusterUploadResultKeepCount]; + private static readonly object _clusterUploadResultsLock = new(); + private static int _clusterUploadResultsHead = 0; + private static int _clusterUploadResultsCount = 0; + + private struct ClusterUploadResult + { + public DateTime UploadTime; + public int Result; + public float RequestTime; + } + + private static ClusterPlayerData[] _topTenPlayerData = null; + private static readonly StringBuilder _sb = new(" ", 12); + + public static MyCheckButton MilkyWayTopTenPlayersToggler; + public static event Action OnMilkyWayTopTenPlayersUpdated; + + public static void Init() + { + I18N.Add("No recent milkyway upload results", "No recent milkyway upload results", "没有最近的银河系发电数据上传结果"); + I18N.Add("Success", "Success", "成功"); + I18N.Add("Failure: ", "Failure: ", "失败: "); + I18N.Add("Show top players", "Show top players", "显示玩家排行榜"); + I18N.Add("Hide top players", "Hide top players", "隐藏玩家排行榜"); + } + + public static void Start() + { + } + + public static void Uninit() + { + } + + public static void OnInputUpdate() + { + } + + public static void OnUpdate() + { + } + + public static void AddClusterUploadResult(int result, float requestTime) + { + lock (_clusterUploadResultsLock) + { + if (_clusterUploadResultsCount >= ClusterUploadResultKeepCount) + { + _clusterUploadResults[_clusterUploadResultsHead] = new ClusterUploadResult { UploadTime = DateTime.Now, Result = result, RequestTime = requestTime }; + _clusterUploadResultsHead = (_clusterUploadResultsHead + 1) % ClusterUploadResultKeepCount; + } + else + { + _clusterUploadResults[(_clusterUploadResultsHead + _clusterUploadResultsCount) % ClusterUploadResultKeepCount] = new ClusterUploadResult { UploadTime = DateTime.Now, Result = result, RequestTime = requestTime }; + _clusterUploadResultsCount++; + } + } + } + + public static void Export(BinaryWriter w) + { + lock (_clusterUploadResultsLock) + { + w.Write(_clusterUploadResultsCount); + w.Write(_clusterUploadResultsHead); + for (var i = 0; i < _clusterUploadResultsCount; i++) + { + ref var result = ref _clusterUploadResults[(i + _clusterUploadResultsHead) % ClusterUploadResultKeepCount]; + w.Write(result.UploadTime.ToBinary()); + w.Write(result.Result); + w.Write(result.RequestTime); + } + } + } + + public static void Import(BinaryReader r) + { + lock (_clusterUploadResultsLock) + { + _clusterUploadResultsCount = r.ReadInt32(); + _clusterUploadResultsHead = r.ReadInt32(); + for (var i = 0; i < _clusterUploadResultsCount; i++) + { + ref var result = ref _clusterUploadResults[(i + _clusterUploadResultsHead) % ClusterUploadResultKeepCount]; + result.UploadTime = DateTime.FromBinary(r.ReadInt64()); + result.Result = r.ReadInt32(); + result.RequestTime = r.ReadSingle(); + } + } + } + + public static void ClearClusterUploadResults() + { + lock (_clusterUploadResultsLock) + { + _clusterUploadResultsCount = 0; + _clusterUploadResultsHead = 0; + } + } + + public static void ShowRecentMilkywayUploadResults() + { + lock (_clusterUploadResultsLock) + { + if (_clusterUploadResultsCount == 0) + { + UIMessageBox.Show("UXAssist".Translate(), "No recent milkyway upload results".Translate(), "确定".Translate(), UIMessageBox.INFO, null); + return; + } + StringBuilder sb = new(); + var start = _clusterUploadResultsCount; + var end = start > 10 ? start - 10 : 0; + for (var i = start - 1; i >= end; i--) + { + var res = _clusterUploadResults[(i + _clusterUploadResultsHead) % ClusterUploadResultKeepCount]; + sb.AppendLine($"{res.UploadTime.ToString("yyyy-MM-dd HH:mm:ss")} - {((res.Result is 0 or 20) ? "Success".Translate() : ("Failure: ".Translate() + res.Result.ToString()))} - {res.RequestTime:F2}s"); + } + UIMessageBox.Show("UXAssist".Translate(), sb.ToString(), "确定".Translate(), UIMessageBox.INFO, null); + } + } + + public static void SetTopPlayerCount(int count) + { + _topTenPlayerData = new ClusterPlayerData[count]; + } + + public static void SetTopPlayerData(int index, ref ClusterPlayerData playerData) + { + if (index < 0 || index >= _topTenPlayerData.Length) return; + _topTenPlayerData[index] = playerData; + } + + public static void UpdateMilkyWayTopTenPlayers() + { + if (_topTenPlayerData == null) return; + OnMilkyWayTopTenPlayersUpdated?.Invoke(); + } + + public static void InitMilkyWayTopTenPlayers() + { + var uiRoot = UIRoot.instance; + if (!uiRoot) return; + + var rect = uiRoot.uiMilkyWay.transform as RectTransform; + var panel = new GameObject("uxassist-milkyway-top-ten-players-panel"); + var rtrans = panel.AddComponent(); + rtrans.SetParent(rect); + rtrans.sizeDelta = new Vector2(0f, 0f); + rtrans.localScale = new Vector3(1f, 1f, 1f); + rtrans.anchorMax = new Vector2(1f, 1f); + rtrans.anchorMin = new Vector2(0f, 0f); + rtrans.pivot = new Vector2(0f, 1f); + rtrans.anchoredPosition3D = new Vector3(0, 0, 0f); + + MyFlatButton[] buttons = []; + Text[] textFields = []; + + MilkyWayTopTenPlayersToggler = MyCheckButton.CreateCheckButton(0, 0, rtrans, false, "Show top players".Translate()).WithSize(120f, 24f); + MilkyWayTopTenPlayersToggler.OnChecked += UpdateButtons; + MilkyWayTopTenPlayersToggler.Checked = false; + UpdateButtons(); + OnMilkyWayTopTenPlayersUpdated += UpdateButtons; + + Text CreateTextField(RectTransform parent) + { + var txt = UnityEngine.Object.Instantiate(UIRoot.instance.uiGame.assemblerWindow.stateText, parent); + txt.gameObject.name = "uxassist-milkyway-top-ten-players-text-field"; + txt.text = ""; + txt.color = new Color(1f, 1f, 1f, 0.4f); + txt.alignment = TextAnchor.MiddleLeft; + txt.fontSize = 15; + txt.rectTransform.sizeDelta = new Vector2(0, 18); + return txt; + } + + void UpdateButtons() + { + var chk = MilkyWayTopTenPlayersToggler.Checked; + if (_topTenPlayerData == null) + { + MilkyWayTopTenPlayersToggler.gameObject.SetActive(false); + return; + } + var count = _topTenPlayerData.Length; + MilkyWayTopTenPlayersToggler.gameObject.SetActive(count > 0); + if (count != buttons.Length) + { + for (var i = count; i < buttons.Length; i++) + { + UnityEngine.Object.Destroy(buttons[i].gameObject); + UnityEngine.Object.Destroy(textFields[i * 4].gameObject); + UnityEngine.Object.Destroy(textFields[i * 4 + 1].gameObject); + UnityEngine.Object.Destroy(textFields[i * 4 + 2].gameObject); + UnityEngine.Object.Destroy(textFields[i * 4 + 3].gameObject); + } + Array.Resize(ref buttons, count); + Array.Resize(ref textFields, count * 4); + } + float maxWidth0 = 0f; + float maxWidth1 = 0f; + float maxWidth2 = 0f; + float maxWidth3 = 0f; + for (var i = 0; i < count; i++) + { + var button = buttons[i]; + if (chk) + { + if (button == null) + { + button = MyFlatButton.CreateFlatButton(0f, 20f * i + 24f, rtrans, "").WithSize(20f, 18f); + buttons[i] = button; + button.uiButton.data = i; + button.uiButton.onClick += data => + { + if (data < 0 || data >= _topTenPlayerData.Length) return; + ref var playerData = ref _topTenPlayerData[data]; + var seed = playerData.seedKey; + int combatValue = (int)(seed % 1000L); + int resourceMultiplier = (int)(seed / 1000L % 100L); + int starCount = (int)(seed / 100000L % 1000L); + int gameSeed = (int)(seed / 100000000L); + var uiMilkyWaySearchPanel = UIRoot.instance.uiMilkyWay.uiSearchPanel; + uiMilkyWaySearchPanel.selectSeed = gameSeed; + uiMilkyWaySearchPanel.selectStarCnt = starCount; + uiMilkyWaySearchPanel.selectResMulti = resourceMultiplier; + if (combatValue / 100 > 0) + { + uiMilkyWaySearchPanel.selectMode = 1; + uiMilkyWaySearchPanel.selectCombatDiff = combatValue % 100; + } + else + { + uiMilkyWaySearchPanel.selectMode = 0; + uiMilkyWaySearchPanel.selectCombatDiff = 0; + } + uiMilkyWaySearchPanel.RefreshInputText(); + uiMilkyWaySearchPanel.OnSearchButtonClick(0); + }; + textFields[i * 4] = CreateTextField(rtrans); + textFields[i * 4].alignment = TextAnchor.MiddleRight; + textFields[i * 4 + 1] = CreateTextField(rtrans); + textFields[i * 4 + 2] = CreateTextField(rtrans); + textFields[i * 4 + 3] = CreateTextField(rtrans); + textFields[i * 4 + 3].alignment = TextAnchor.MiddleRight; + } + button.SetLabelText(">>"); + textFields[i * 4].text = (i + 1).ToString(); + textFields[i * 4 + 1].text = _topTenPlayerData[i].name; + textFields[i * 4 + 2].text = SeedToString(_topTenPlayerData[i].seedKey); + textFields[i * 4 + 3].text = String.Format("{0}W", ToKMG(_topTenPlayerData[i].genCap * 60L)); + maxWidth0 = Math.Max(maxWidth0, textFields[i * 4].preferredWidth); + maxWidth1 = Math.Max(maxWidth1, textFields[i * 4 + 1].preferredWidth); + maxWidth2 = Math.Max(maxWidth2, textFields[i * 4 + 2].preferredWidth); + maxWidth3 = Math.Max(maxWidth3, textFields[i * 4 + 3].preferredWidth); + button.gameObject.SetActive(true); + textFields[i * 4].gameObject.SetActive(true); + textFields[i * 4 + 1].gameObject.SetActive(true); + textFields[i * 4 + 2].gameObject.SetActive(true); + textFields[i * 4 + 3].gameObject.SetActive(true); + } + else + { + if (button != null) + { + button.gameObject.SetActive(false); + textFields[i * 4].gameObject.SetActive(false); + textFields[i * 4 + 1].gameObject.SetActive(false); + textFields[i * 4 + 2].gameObject.SetActive(false); + textFields[i * 4 + 3].gameObject.SetActive(false); + } + } + } + if (chk) + { + for (var i = 0; i < count; i++) + { + var y = 20f * i + 24f; + global::UXAssist.UI.Util.NormalizeRectWithTopLeft(textFields[i * 4].rectTransform, 24f + maxWidth0 + 5f, y); + global::UXAssist.UI.Util.NormalizeRectWithTopLeft(textFields[i * 4 + 1].rectTransform, 24f + maxWidth0 + 10f, y); + global::UXAssist.UI.Util.NormalizeRectWithTopLeft(textFields[i * 4 + 2].rectTransform, 24f + maxWidth0 + 10f + maxWidth1 + 5f, y); + global::UXAssist.UI.Util.NormalizeRectWithTopLeft(textFields[i * 4 + 3].rectTransform, 24f + maxWidth0 + 10f + maxWidth1 + 5f + maxWidth2 + 5f + maxWidth3, y); + } + } + MilkyWayTopTenPlayersToggler.SetLabelText(chk ? "Hide top players".Translate() : "Show top players".Translate()); + + string ToKMG(long value) + { + StringBuilderUtility.WriteKMG(_sb, 8, value, true); + return _sb.ToString(); + } + + string SeedToString(long seed) + { + int combatValue = (int)(seed % 1000L); + int resourceMultiplier = (int)(seed / 1000L % 100L); + int starCount = (int)(seed / 100000L % 1000L); + int gameSeed = (int)(seed / 100000000L); + string text; + if (combatValue / 100 > 0) + { + text = String.Format("{0:D8}-{1}-Z{2}-{3:00}", gameSeed, starCount, resourceMultiplier, combatValue % 100); + } + else + { + text = String.Format("{0:D8}-{1}-A{2}", gameSeed, starCount, resourceMultiplier); + } + return text; + } + } + } +} diff --git a/UXAssist/Functions/UI/StarmapFilterUI.cs b/UXAssist/Functions/UI/StarmapFilterUI.cs new file mode 100644 index 0000000..9d83dfe --- /dev/null +++ b/UXAssist/Functions/UI/StarmapFilterUI.cs @@ -0,0 +1,564 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using UXAssist.Common; +using UXAssist.UI; +using GameLogicProc = UXAssist.Common.GameLogic; + +namespace UXAssist.Functions.UI; + +internal static class StarmapFilterUI +{ + private static int _cornerComboBoxIndex; + private static string[] _starOrderNames; + private static bool _starmapFilterInitialized; + private static ulong[] _starmapStarFilterValues; + private static bool _starFilterEnabled; + public static MyCheckButton StarmapFilterToggler; + public static bool[] ShowStarName; + + private static readonly Sprite[] PlanetIcons = [ + null, + null, + null, + null, + null, + null, + null, + Common.Util.LoadEmbeddedSprite("assets/planet_icon/07.png"), + null, + Common.Util.LoadEmbeddedSprite("assets/planet_icon/09.png"), + Common.Util.LoadEmbeddedSprite("assets/planet_icon/10.png"), + null, + null, + Common.Util.LoadEmbeddedSprite("assets/planet_icon/13.png"), + Common.Util.LoadEmbeddedSprite("assets/planet_icon/14.png"), + Common.Util.LoadEmbeddedSprite("assets/planet_icon/15.png"), + Common.Util.LoadEmbeddedSprite("assets/planet_icon/16.png"), + Common.Util.LoadEmbeddedSprite("assets/planet_icon/17.png"), + null, + Common.Util.LoadEmbeddedSprite("assets/planet_icon/19.png"), + Common.Util.LoadEmbeddedSprite("assets/planet_icon/20.png"), + Common.Util.LoadEmbeddedSprite("assets/planet_icon/21.png"), + Common.Util.LoadEmbeddedSprite("assets/planet_icon/22.png"), + Common.Util.LoadEmbeddedSprite("assets/planet_icon/23.png"), + Common.Util.LoadEmbeddedSprite("assets/planet_icon/24.png"), + Common.Util.LoadEmbeddedSprite("assets/planet_icon/25.png") + ]; + + private static readonly (int, int)[] FilterVeinIds = [(9, 0), (10, 0), (11, 0), (12, 0), (13, 0), (14, 0), (7, 0), (0, 1116), (0, 1000), (8, 1011), (0, 1120), (0, 1121)]; + private static readonly int[] FilterPlanetThemes = [16, 23, 15, 22, 25, 21, 14, 17, 19, 7, 10, 20, 24, 9, 13]; + private static readonly Dictionary ItemToVeinBitFlagMap = new() + { + {1011, 8}, + {1120, 20}, + {1121, 21}, + {1116, 22}, + {1000, 23}, + }; + + public static void Init() + { + I18N.Add("High yield", "High yield", "高产"); + I18N.Add("Perfect", "Perfect", "完美"); + I18N.Add("Union results", "Union results", "结果取并集"); + I18N.Add("All 6 Basic Ores", "All 6 Basic Ores", "六种基础矿物齐全"); + I18N.Add("Show original name", "Show original name", "显示原始名称"); + I18N.Add("Show distance", "Show distance", "显示距离"); + I18N.Add("Show planet count", "Show planet count", "显示行星数"); + I18N.Add("Show all information", "Show all information", "显示全部信息"); + } + + public static void Start() + { + } + + public static void Uninit() + { + } + + public static void OnInputUpdate() + { + } + + public static void OnUpdate() + { + } + + public static void InitStarmapButtons() + { + var uiRoot = UIRoot.instance; + if (!uiRoot) return; + + var rect = uiRoot.uiGame.starmap.transform as RectTransform; + var panel = new GameObject("uxassist-starmap-panel"); + var rtrans = panel.AddComponent(); + panel.transform.SetParent(rect); + rtrans.sizeDelta = new Vector2(0f, 0f); + rtrans.localScale = new Vector3(1f, 1f, 1f); + rtrans.anchorMax = new Vector2(1f, 1f); + rtrans.anchorMin = new Vector2(0f, 0f); + rtrans.pivot = new Vector2(0f, 1f); + rtrans.anchoredPosition3D = new Vector3(0, 0, 0f); + + var cornerComboBox = MyCornerComboBox.CreateComboBox(135, 0, rtrans, true).WithItems("Show original name".Translate(), "Show distance".Translate(), "Show planet count".Translate(), "Show all information".Translate()); + cornerComboBox.SetIndex(CornerComboBoxIndex); + cornerComboBox.OnSelChanged += (index) => + { + CornerComboBoxIndex = index; + }; + StarmapFilterToggler = MyCheckButton.CreateCheckButton(0, 0, rtrans, false, ">>").WithSize(24, 24); + MyCheckButton[] buttons = [ + MyCheckButton.CreateCheckButton(24, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Kimberlite + MyCheckButton.CreateCheckButton(48, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Fractal Silicon + MyCheckButton.CreateCheckButton(72, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Organic Crystal + MyCheckButton.CreateCheckButton(96, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Grating Crystal + MyCheckButton.CreateCheckButton(120, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Stalagmite Crystal + MyCheckButton.CreateCheckButton(144, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Unipolar Magnet + MyCheckButton.CreateCheckButton(168, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Crude Oil + MyCheckButton.CreateCheckButton(192, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Fire Ice + MyCheckButton.CreateCheckButton(216, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Sulfuric Acid + MyCheckButton.CreateCheckButton(240, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Water + MyCheckButton.CreateCheckButton(264, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Hydrogen + MyCheckButton.CreateCheckButton(288, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Deuterium + + MyCheckButton.CreateCheckButton(24, 24, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 48, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 72, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 96, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 120, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 144, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 168, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + + MyCheckButton.CreateCheckButton(24, 210, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 234, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 258, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 282, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 306, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 330, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 354, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + MyCheckButton.CreateCheckButton(24, 378, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), + ]; + var unionCheckBox = MyCheckBox.CreateCheckBox(312, 0, rtrans, false, "Union results".Translate(), 15).WithSmallerBox(24f); + unionCheckBox.gameObject.SetActive(false); + unionCheckBox.OnChecked += () => + { + UpdateStarmapStarFilters(); + }; + var allOresText = MyWindow.AddText(20, 190, rtrans, "All 6 Basic Ores".Translate(), 12); + allOresText.gameObject.SetActive(false); + StarmapFilterToggler.OnChecked += UpdateButtons; + foreach (var button in buttons) + { + button.OnChecked += () => + { + if (button.Checked && !VFInput.shift && !VFInput.control) + { + foreach (var b in buttons) + { + if (b != button) b.Checked = false; + } + } + UpdateStarmapStarFilters(); + }; + } + + I18N.OnInitialized += UpdateI18N; + GameLogicProc.OnDataLoaded += () => + { + VeinProto veinProto; + ItemProto itemProto; + for (int i = 0; i < 12; i++) + { + var (veinProtoId, itemProtoId) = FilterVeinIds[i]; + if (itemProtoId != 0) + { + itemProto = LDB.items.Select(itemProtoId); + buttons[i].SetIcon(itemProto.iconSprite); + } + else if (veinProtoId != 0) + { + veinProto = LDB.veins.Select(veinProtoId); + buttons[i].SetIcon(veinProto.iconSprite); + } + } + + for (int i = 0; i < FilterPlanetThemes.Length; i++) + { + buttons[12 + i].SetIcon(PlanetIcons[FilterPlanetThemes[i]]); + } + UpdateI18N(); + }; + + GameLogicProc.OnGameBegin += () => + { + if (DSPGame.IsMenuDemo) return; + + var galaxy = GameMain.data.galaxy; + ShowStarName = new bool[galaxy.starCount]; + _starOrderNames = new string[galaxy.starCount]; + _starmapStarFilterValues = new ulong[galaxy.starCount]; + StarData[] stars = [.. galaxy.stars.Where(star => star != null)]; + Array.Sort(stars, (a, b) => + { + int res = a.position.sqrMagnitude.CompareTo(b.position.sqrMagnitude); + if (res != 0) return res; + return a.index.CompareTo(b.index); + }); + for (int i = 0; i < stars.Length; i++) + { + var star = stars[i]; + _starOrderNames[star.index] = star.displayName; + } + int[] spectrCount = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + for (int i = 0; i < stars.Length; i++) + { + var star = stars[i]; + var index = star.index; + switch (star.type) + { + case EStarType.MainSeqStar: + switch (star.spectr) + { + case ESpectrType.M: + _starOrderNames[index] = String.Format("M{0}", ++spectrCount[0]); + break; + case ESpectrType.K: + _starOrderNames[index] = String.Format("K{0}", ++spectrCount[1]); + break; + case ESpectrType.G: + _starOrderNames[index] = String.Format("G{0}", ++spectrCount[2]); + break; + case ESpectrType.F: + _starOrderNames[index] = String.Format("F{0}", ++spectrCount[3]); + break; + case ESpectrType.A: + _starOrderNames[index] = String.Format("A{0}", ++spectrCount[4]); + break; + case ESpectrType.B: + _starOrderNames[index] = String.Format("B{0}", ++spectrCount[5]); + break; + case ESpectrType.O: + _starOrderNames[index] = String.Format("O{0}", ++spectrCount[6]); + break; + } + break; + case EStarType.GiantStar: + _starOrderNames[index] = String.Format("GS{0}", ++spectrCount[7]); + break; + case EStarType.WhiteDwarf: + _starOrderNames[index] = String.Format("WD{0}", ++spectrCount[8]); + break; + case EStarType.NeutronStar: + _starOrderNames[index] = String.Format("NS{0}", ++spectrCount[9]); + break; + case EStarType.BlackHole: + _starOrderNames[index] = String.Format("BH{0}", ++spectrCount[10]); + break; + } + } + StarmapFilterToggler.gameObject.SetActive(false); + StarmapFilterToggler.Checked = false; + UpdateButtons(); + SetStarFilterEnabled(false); + foreach (var star in galaxy.stars) + { + if (star != null) PlanetModelingManager.RequestScanStar(star); + } + _starmapFilterInitialized = true; + if (PlanetModelingManager.scnPlanetReqList.Count == 0) + { + OnPlanetScanEnded(); + } + }; + GameLogicProc.OnGameEnd += () => + { + _starOrderNames = null; + ShowStarName = null; + _starmapStarFilterValues = null; + _starmapFilterInitialized = false; + }; + void UpdateI18N() + { + if (cornerComboBox != null) + { + var items = cornerComboBox.Items; + cornerComboBox.UpdateLabelText(); + items[0] = "Show original name".Translate(); + items[1] = "Show distance".Translate(); + items[2] = "Show planet count".Translate(); + items[3] = "Show all information".Translate(); + } + if (buttons != null) + { + VeinProto veinProto; + ItemProto itemProto; + for (int i = 0; i < 12; i++) + { + var (veinProtoId, itemProtoId) = FilterVeinIds[i]; + if (itemProtoId != 0) + { + itemProto = LDB.items.Select(itemProtoId); + buttons[i].WithTip(itemProto.Name); + } + else if (veinProtoId != 0) + { + veinProto = LDB.veins.Select(veinProtoId); + buttons[i].WithTip(veinProto.Name); + } + } + for (int i = 0; i < FilterPlanetThemes.Length; i++) + { + var theme = FilterPlanetThemes[i]; + var themeProto = LDB.themes.Select(theme); + switch (i) + { + case 5: + buttons[12 + i].SetLabelText($"{themeProto.DisplayName.Translate()} ({"High yield".Translate()})"); + break; + case 6: + buttons[12 + i].SetLabelText($"{themeProto.DisplayName.Translate()} ({"Perfect".Translate()})"); + break; + default: + buttons[12 + i].SetLabelText(themeProto.DisplayName.Translate()); + break; + } + } + } + if (allOresText != null) allOresText.text = "All 6 Basic Ores".Translate(); + } + void UpdateButtons() + { + var chk = StarmapFilterToggler.Checked; + foreach (var button in buttons) + { + if (chk) + button.gameObject.SetActive(true); + else + { + button.gameObject.SetActive(false); + button.Checked = false; + } + } + unionCheckBox.gameObject.SetActive(chk); + allOresText.gameObject.SetActive(chk); + StarmapFilterToggler.SetLabelText(chk ? "X" : ">>"); + if (!chk) + { + UpdateStarmapStarFilters(); + } + UIRoot.instance.uiGame.dfMonitor.transform.parent.gameObject.SetActive(!chk); + } + void UpdateStarmapStarFilters() + { + var filterValue = 0UL; + var union = unionCheckBox.Checked; + if (StarmapFilterToggler.Checked) + { + for (int i = 0; i < 12; i++) + { + if (buttons[i].Checked) + { + var (veinProtoId, itemProtoId) = FilterVeinIds[i]; + if (veinProtoId != 0) + { + filterValue |= 1UL << veinProtoId; + } + else if (itemProtoId != 0) + { + filterValue |= 1UL << ItemToVeinBitFlagMap[itemProtoId]; + } + } + } + for (int i = 0; i < FilterPlanetThemes.Length; i++) + { + if (buttons[12 + i].Checked) + { + filterValue |= 1UL << (30 + FilterPlanetThemes[i]); + } + } + } + if (filterValue == 0UL) + { + for (int i = 0; i < ShowStarName.Length; i++) + { + ShowStarName[i] = false; + } + SetStarFilterEnabled(false); + return; + } + for (int i = _starmapStarFilterValues.Length - 1; i >= 0; i--) + { + ShowStarName[i] = union ? (_starmapStarFilterValues[i] & filterValue) != 0 : (_starmapStarFilterValues[i] & filterValue) == filterValue; + } + SetStarFilterEnabled(true); + } + } + + public static void OnPlanetScanEnded() + { + if (!_starmapFilterInitialized || StarmapFilterToggler == null || StarmapFilterToggler.gameObject.activeSelf) return; + StarmapUpdateFilterValues(); + StarmapFilterToggler.gameObject.SetActive(true); + } + + private static void StarmapUpdateFilterValues() + { + var galaxy = GameMain.data.galaxy; + var stars = galaxy.stars; + for (int i = 0; i < galaxy.starCount; i++) + { + var star = stars[i]; + if (star == null) continue; + var value = 0UL; + foreach (var planet in star.planets) + { + if (planet == null) continue; + if (!planet.scanned) + { + PlanetModelingManager.RequestScanPlanet(planet); + continue; + } + var planetValue = 0UL; + if (planet.type == EPlanetType.Gas) + { + foreach (var n in planet.gasItems) + { + if (ItemToVeinBitFlagMap.TryGetValue(n, out var bitFlag)) + { + planetValue |= 1UL << bitFlag; + } + } + } + else + { + if (planet.runtimeVeinGroups != null) + { + foreach (var group in planet.runtimeVeinGroups) + { + if (group.amount > 0) + { + planetValue |= 1UL << (int)group.type; + } + } + } + if (ItemToVeinBitFlagMap.TryGetValue(planet.waterItemId, out var bitFlag)) + { + planetValue |= 1UL << bitFlag; + } + } + if ((value & (1UL << (30 + planet.theme))) == 0) + { + switch (planet.theme) + { + case 7: + case 9: + case 10: + case 13: + case 17: + case 19: + case 20: + case 24: + { + const ulong needed = 0x7EUL; + if ((planetValue & needed) == needed) + { + value |= 1UL << (30 + planet.theme); + } + break; + } + case 14: + { + const ulong needed = 0x2200UL; + if ((planetValue & needed) == needed) + { + value |= 1UL << (30 + planet.theme); + } + break; + } + case 15: + case 16: + case 21: + case 22: + case 23: + case 25: + value |= 1UL << (30 + planet.theme); + break; + } + } + value |= planetValue; + } + _starmapStarFilterValues[i] = value; + } + } + + public static int CornerComboBoxIndex + { + get => _cornerComboBoxIndex; + set + { + _cornerComboBoxIndex = value; + Patches.PlayerPatch.ShortcutKeysForStarsName.ForceShowAllStarsNameExternal = _cornerComboBoxIndex != 0 && !_starFilterEnabled; + UpdateStarmapStarNames(); + } + } + + private static void SetStarFilterEnabled(bool enabled) + { + if (_starFilterEnabled == enabled) return; + _starFilterEnabled = enabled; + if (!enabled) Patches.PlayerPatch.ShortcutKeysForStarsName.ShowAllStarsNameStatus = 0; + Patches.PlayerPatch.ShortcutKeysForStarsName.ForceShowAllStarsNameExternal = _cornerComboBoxIndex != 0 && !_starFilterEnabled; + UpdateStarmapStarNames(); + } + + private static void UpdateStarmapStarNames() + { + foreach (var starUI in UIRoot.instance.uiGame.starmap.starUIs) + { + var star = starUI?.star; + if (star == null) continue; + switch (_cornerComboBoxIndex) + { + case 1: + starUI.nameText.text = String.Format("{0:00}-{1}-{2:0.00}", star.index + 1, _starOrderNames[star.index], GetStarDist(star)); + break; + case 2: + { + var (nongas, total) = GetStarPlanetCount(star); + starUI.nameText.text = String.Format("{0:00}-{1}-{2}-{3}", star.index + 1, _starOrderNames[star.index], nongas, total); + break; + } + case 3: + { + var (nongas, total) = GetStarPlanetCount(star); + starUI.nameText.text = String.Format("{0:00}-{1}-{2:0.00}-{3}-{4}", star.index + 1, _starOrderNames[star.index], GetStarDist(star), nongas, total); + break; + } + default: + starUI.nameText.text = star.displayName; + break; + } + } + return; + + double GetStarDist(StarData star) + { + return star.position.magnitude; + } + + (int, int) GetStarPlanetCount(StarData star) + { + int total = 0; + int nongas = 0; + foreach (var planet in star.planets) + { + if (planet == null) continue; + if (planet.type != EPlanetType.Gas) nongas++; + total++; + } + return (nongas, total); + } + } +} diff --git a/UXAssist/Functions/UIFunctions.cs b/UXAssist/Functions/UIFunctions.cs index cf71839..5d50e85 100644 --- a/UXAssist/Functions/UIFunctions.cs +++ b/UXAssist/Functions/UIFunctions.cs @@ -1,1105 +1,129 @@ -using System; -using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using UnityEngine; -using UnityEngine.UI; -using CommonAPI.Systems; -using UXAssist.Common; -using UXAssist.UI; -using UXAssist.Patches.Factory; -using GameLogicProc = UXAssist.Common.GameLogic; +using UXAssist.Common.ModFeatures; +using UXAssist.Functions.UI; namespace UXAssist.Functions; +[ModFeature("UI", Order = 12)] public static class UIFunctions { - private static bool _initialized; - private static PressKeyBind _toggleKey; - private static bool _configWinInitialized; - private static MyConfigWindow _configWin; - private static GameObject _buttonOnPlanetGlobe; - public static void Init() { - _toggleKey = KeyBindings.RegisterKeyBinding(new BuiltinKey - { - key = new CombineKey((int)KeyCode.BackQuote, CombineKey.ALT_COMB, ECombineKeyAction.OnceClick, false), - conflictGroup = KeyBindConflict.MOVEMENT | KeyBindConflict.FLYING | KeyBindConflict.SAILING | KeyBindConflict.BUILD_MODE_1 | KeyBindConflict.KEYBOARD_KEYBIND, - name = "OpenUXAssistConfigWindow", - canOverride = true - }); - I18N.Add("KEYOpenUXAssistConfigWindow", "[UXA] Open UXAssist Config Window", "[UXA] 打开UX助手设置面板"); + MenuButtonUI.Init(); + AutoCruiseUI.Init(); + AutoConstructUI.Init(); + StarmapFilterUI.Init(); + MilkyWayUI.Init(); + } - I18N.Add("Enable auto-cruise", "Enable auto-cruise", "启用自动巡航"); - I18N.Add("Disable auto-cruise", "Disable auto-cruise", "禁用自动巡航"); - I18N.Add("Enable auto-construct", "Enable auto-construct", "启用自动建造"); - I18N.Add("Disable auto-construct", "Disable auto-construct", "禁用自动建造"); - I18N.Add("Buildings to construct: {0}", "Buildings to construct: {0}", "待建造数量: {0}"); - I18N.Add("High yield", "High yield", "高产"); - I18N.Add("Perfect", "Perfect", "完美"); - I18N.Add("Union results", "Union results", "结果取并集"); - I18N.Add("All 6 Basic Ores", "All 6 Basic Ores", "六种基础矿物齐全"); - I18N.Add("Show original name", "Show original name", "显示原始名称"); - I18N.Add("Show distance", "Show distance", "显示距离"); - I18N.Add("Show planet count", "Show planet count", "显示行星数"); - I18N.Add("Show all information", "Show all information", "显示全部信息"); - I18N.Add("No recent milkyway upload results", "No recent milkyway upload results", "没有最近的银河系发电数据上传结果"); - I18N.Add("Success", "Success", "成功"); - I18N.Add("Failure: ", "Failure: ", "失败: "); - I18N.Add("Show top players", "Show top players", "显示玩家排行榜"); - I18N.Add("Hide top players", "Hide top players", "隐藏玩家排行榜"); - I18N.OnInitialized += RecreateConfigWindow; + public static void Start() + { + MenuButtonUI.Start(); + AutoCruiseUI.Start(); + AutoConstructUI.Start(); + StarmapFilterUI.Start(); + MilkyWayUI.Start(); + } + + public static void Uninit() + { + MenuButtonUI.Uninit(); + AutoCruiseUI.Uninit(); + AutoConstructUI.Uninit(); + StarmapFilterUI.Uninit(); + MilkyWayUI.Uninit(); } public static void OnInputUpdate() { - if (_toggleKey.keyValue) - { - ToggleConfigWindow(); - } + MenuButtonUI.OnInputUpdate(); + AutoCruiseUI.OnInputUpdate(); + AutoConstructUI.OnInputUpdate(); + StarmapFilterUI.OnInputUpdate(); + MilkyWayUI.OnInputUpdate(); } - #region ConfigWindow - public static void ToggleConfigWindow() + public static void OnUpdate() { - if (!_configWinInitialized) - { - if (!I18N.Initialized()) return; - _configWinInitialized = true; - _configWin = MyConfigWindow.CreateInstance(); - } - - if (_configWin.active) - { - _configWin._Close(); - } - else - { - _configWin.Open(); - } + MenuButtonUI.OnUpdate(); + AutoCruiseUI.OnUpdate(); + AutoConstructUI.OnUpdate(); + StarmapFilterUI.OnUpdate(); + MilkyWayUI.OnUpdate(); } public static void InitMenuButtons() { - if (_initialized) return; - var uiRoot = UIRoot.instance; - if (!uiRoot) return; - { - var mainMenu = uiRoot.uiMainMenu; - var src = mainMenu.newGameButton; - var parent = src.transform.parent; - var btn = GameObject.Instantiate(src, parent); - btn.name = "button-uxassist-config"; - var l = btn.text.GetComponent(); - if (l != null) - { - l.stringKey = "UXAssist Config"; - l.translation = "UXAssist Config".Translate(); - } - - btn.text.text = "UXAssist 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(Functions.UIFunctions.ToggleConfigWindow); - } - { - var panel = uiRoot.uiGame.planetGlobe; - var src = panel.button2; - var sandboxMenu = uiRoot.uiGame.sandboxMenu; - var icon = sandboxMenu.categoryButtons[6].transform.Find("icon")?.GetComponent()?.sprite; - var b = GameObject.Instantiate(src, src.transform.parent); - _buttonOnPlanetGlobe = b.gameObject; - var rect = (RectTransform)_buttonOnPlanetGlobe.transform; - var btn = _buttonOnPlanetGlobe.GetComponent(); - var img = _buttonOnPlanetGlobe.transform.Find("button-2/icon")?.GetComponent(); - if (img != null) - { - img.sprite = icon; - } - - if (_buttonOnPlanetGlobe != null && btn != null) - { - _buttonOnPlanetGlobe.name = "open-uxassist-config"; - rect.localScale = new Vector3(0.6f, 0.6f, 0.6f); - rect.anchoredPosition3D = new Vector3(64f, -5f, 0f); - b.onClick.RemoveAllListeners(); - btn.onClick += _ => { Functions.UIFunctions.ToggleConfigWindow(); }; - btn.tips.tipTitle = "UXAssist Config"; - I18N.OnInitialized += () => { btn.tips.tipTitle = "UXAssist Config".Translate(); }; - btn.tips.tipText = null; - btn.tips.corner = 9; - btn.tips.offset = new Vector2(-20f, -20f); - _buttonOnPlanetGlobe.SetActive(true); - } - } - InitToggleAutoCruiseCheckButton(); - InitToggleAutoConstructCheckButton(); - InitStarmapButtons(); - _initialized = true; - } - - public static void RecreateConfigWindow() - { - if (!_configWinInitialized) return; - var wasActive = _configWin.active; - if (wasActive) _configWin._Close(); - MyConfigWindow.DestroyInstance(_configWin); - _configWinInitialized = false; - if (wasActive) ToggleConfigWindow(); - } - - public static void UpdateGlobeButtonPosition(UIPlanetGlobe planetGlobe) - { - if (_buttonOnPlanetGlobe == null) return; - var rect = (RectTransform)_buttonOnPlanetGlobe.transform; - if (planetGlobe.dysonSphereSystemUnlocked || planetGlobe.logisticsSystemUnlocked) - { - rect.anchoredPosition3D = new Vector3(64f, -5f, 0f); - } - else - { - rect.anchoredPosition3D = new Vector3(128f, -100f, 0f); - } - } - #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(160f, 40f); - 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); - rectTrans.localScale = new Vector3(1f, 1f, 1f); - - UpdateToggleAutoCruiseCheckButtonVisiblility(); - ToggleAutoCruiseChecked(); - ToggleAutoCruise.OnChecked += ToggleAutoCruiseChecked; - 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 ToggleAutoConstructCheckButton - public static UI.MyCheckButton ToggleAutoConstruct; - public static GameObject ConstructCountPanel; - public static Text ConstructCountText; - - public static void InitToggleAutoConstructCheckButton() - { - var lowGroup = GameObject.Find("UI Root/Overlay Canvas/In Game/Low Group"); - var parent = lowGroup.GetComponent(); - ToggleAutoConstruct = MyCheckButton.CreateCheckButton(0, 0, parent, FactoryPatch.AutoConstructEnabled).WithSize(160f, 40f); - var rectTrans = ToggleAutoConstruct.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(-165f, 185f, 0f); - rectTrans.localScale = new Vector3(1f, 1f, 1f); - - ConstructCountPanel = new GameObject("uxassist-construct-count-panel"); - rectTrans = ConstructCountPanel.AddComponent(); - rectTrans.SetParent(parent); - 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(-165f, 161f, 0f); - rectTrans.localScale = new Vector3(1f, 1f, 1f); - rectTrans.sizeDelta = new Vector2(160f, 24f); - var bg = ConstructCountPanel.AddComponent(); - bg.color = new Color(0.2f, 0.2f, 0.2f, 0.6f); - - ConstructCountText = GameObject.Instantiate(UIRoot.instance.uiGame.assemblerWindow.stateText); - ConstructCountText.gameObject.name = "construct-count-text"; - ConstructCountText.text = String.Format("Buildings to construct: {0}".Translate(), 0); - ConstructCountText.color = new Color(1f, 1f, 1f, 0.4f); - ConstructCountText.alignment = TextAnchor.MiddleLeft; - ConstructCountText.fontSize = 16; - rectTrans = ConstructCountText.rectTransform; - rectTrans.SetParent(ConstructCountPanel.transform); - rectTrans.sizeDelta = new Vector2(150f, 20f); - rectTrans.anchorMax = new Vector2(0.5f, 0.5f); - rectTrans.anchorMin = new Vector2(0.5f, 0.5f); - rectTrans.pivot = new Vector2(0.5f, 0.5f); - rectTrans.anchoredPosition3D = new Vector3(0f, 0f, 0f); - rectTrans.localScale = new Vector3(1f, 1f, 1f); - - UpdateToggleAutoConstructCheckButtonVisiblility(); - ToggleAutoConstructChecked(); - ToggleAutoConstruct.OnChecked += ToggleAutoConstructChecked; - static void ToggleAutoConstructChecked() - { - if (ToggleAutoConstruct.Checked) - { - ToggleAutoConstruct.SetLabelText("Disable auto-construct"); - } - else - { - ToggleAutoConstruct.SetLabelText("Enable auto-construct"); - } - } - } - - public static void UpdateToggleAutoConstructCheckButtonVisiblility() - { - if (ToggleAutoConstruct == null) return; - var localPlanet = GameMain.localPlanet; - var active = localPlanet != null && localPlanet.factoryLoaded && localPlanet.factory.prebuildCount > 0 && FactoryPatch.AutoConstructButtonEnabled.Value; - ToggleAutoConstruct.gameObject.SetActive(active); - ConstructCountPanel.gameObject.SetActive(active); - } - - public static void UpdateConstructCountText(int count) - { - if (ConstructCountText == null) return; - ConstructCountText.text = String.Format("Buildings to construct: {0}".Translate(), count); - } - #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; - - private static readonly Sprite[] PlanetIcons = [ - null, - null, - null, - null, - null, - null, - null, - Common.Util.LoadEmbeddedSprite("assets/planet_icon/07.png"), - null, - Common.Util.LoadEmbeddedSprite("assets/planet_icon/09.png"), - Common.Util.LoadEmbeddedSprite("assets/planet_icon/10.png"), - null, - null, - Common.Util.LoadEmbeddedSprite("assets/planet_icon/13.png"), - Common.Util.LoadEmbeddedSprite("assets/planet_icon/14.png"), - Common.Util.LoadEmbeddedSprite("assets/planet_icon/15.png"), - Common.Util.LoadEmbeddedSprite("assets/planet_icon/16.png"), - Common.Util.LoadEmbeddedSprite("assets/planet_icon/17.png"), - null, - Common.Util.LoadEmbeddedSprite("assets/planet_icon/19.png"), - Common.Util.LoadEmbeddedSprite("assets/planet_icon/20.png"), - Common.Util.LoadEmbeddedSprite("assets/planet_icon/21.png"), - Common.Util.LoadEmbeddedSprite("assets/planet_icon/22.png"), - Common.Util.LoadEmbeddedSprite("assets/planet_icon/23.png"), - Common.Util.LoadEmbeddedSprite("assets/planet_icon/24.png"), - Common.Util.LoadEmbeddedSprite("assets/planet_icon/25.png") - ]; - - private static readonly (int, int)[] FilterVeinIds = [(9, 0), (10, 0), (11, 0), (12, 0), (13, 0), (14, 0), (7, 0), (0, 1116), (0, 1000), (8, 1011), (0, 1120), (0, 1121)]; - private static readonly int[] FilterPlanetThemes = [16, 23, 15, 22, 25, 21, 14, 17, 19, 7, 10, 20, 24, 9, 13]; - private static readonly Dictionary ItemToVeinBitFlagMap = new() - { - {1011, 8}, - {1120, 20}, - {1121, 21}, - {1116, 22}, - {1000, 23}, - }; - - public static void InitStarmapButtons() - { - var uiRoot = UIRoot.instance; - if (!uiRoot) return; - - var rect = uiRoot.uiGame.starmap.transform as RectTransform; - var panel = new GameObject("uxassist-starmap-panel"); - var rtrans = panel.AddComponent(); - panel.transform.SetParent(rect); - rtrans.sizeDelta = new Vector2(0f, 0f); - rtrans.localScale = new Vector3(1f, 1f, 1f); - rtrans.anchorMax = new Vector2(1f, 1f); - rtrans.anchorMin = new Vector2(0f, 0f); - rtrans.pivot = new Vector2(0f, 1f); - rtrans.anchoredPosition3D = new Vector3(0, 0, 0f); - - var cornerComboBox = UI.MyCornerComboBox.CreateComboBox(135, 0, rtrans, true).WithItems("Show original name".Translate(), "Show distance".Translate(), "Show planet count".Translate(), "Show all information".Translate()); - cornerComboBox.SetIndex(Functions.UIFunctions.CornerComboBoxIndex); - cornerComboBox.OnSelChanged += (index) => - { - Functions.UIFunctions.CornerComboBoxIndex = index; - }; - StarmapFilterToggler = UI.MyCheckButton.CreateCheckButton(0, 0, rtrans, false, ">>").WithSize(24, 24); - MyCheckButton[] buttons = [ - UI.MyCheckButton.CreateCheckButton(24, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Kimberlite - UI.MyCheckButton.CreateCheckButton(48, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Fractal Silicon - UI.MyCheckButton.CreateCheckButton(72, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Organic Crystal - UI.MyCheckButton.CreateCheckButton(96, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Grating Crystal - UI.MyCheckButton.CreateCheckButton(120, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Stalagmite Crystal - UI.MyCheckButton.CreateCheckButton(144, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Unipolar Magnet - UI.MyCheckButton.CreateCheckButton(168, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Crude Oil - UI.MyCheckButton.CreateCheckButton(192, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Fire Ice - UI.MyCheckButton.CreateCheckButton(216, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Sulfuric Acid - UI.MyCheckButton.CreateCheckButton(240, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Water - UI.MyCheckButton.CreateCheckButton(264, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Hydrogen - UI.MyCheckButton.CreateCheckButton(288, 0, rtrans, false).WithIcon().WithSize(24, 24).WithIconWidth(24), // Deuterium - - UI.MyCheckButton.CreateCheckButton(24, 24, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 48, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 72, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 96, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 120, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 144, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 168, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - - UI.MyCheckButton.CreateCheckButton(24, 210, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 234, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 258, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 282, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 306, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 330, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 354, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - UI.MyCheckButton.CreateCheckButton(24, 378, rtrans, false).WithIcon().WithSize(150, 24).WithIconWidth(24), - ]; - var unionCheckBox = UI.MyCheckBox.CreateCheckBox(312, 0, rtrans, false, "Union results".Translate(), 15).WithSmallerBox(24f); - unionCheckBox.gameObject.SetActive(false); - unionCheckBox.OnChecked += () => - { - UpdateStarmapStarFilters(); - }; - var allOresText = MyWindow.AddText(20, 190, rtrans, "All 6 Basic Ores".Translate(), 12); - allOresText.gameObject.SetActive(false); - StarmapFilterToggler.OnChecked += UpdateButtons; - foreach (var button in buttons) - { - button.OnChecked += () => - { - if (button.Checked && !VFInput.shift && !VFInput.control) - { - foreach (var b in buttons) - { - if (b != button) b.Checked = false; - } - } - UpdateStarmapStarFilters(); - }; - } - - I18N.OnInitialized += UpdateI18N; - GameLogicProc.OnDataLoaded += () => - { - VeinProto veinProto; - ItemProto itemProto; - for (int i = 0; i < 12; i++) - { - var (veinProtoId, itemProtoId) = FilterVeinIds[i]; - if (itemProtoId != 0) - { - itemProto = LDB.items.Select(itemProtoId); - buttons[i].SetIcon(itemProto.iconSprite); - } - else if (veinProtoId != 0) - { - veinProto = LDB.veins.Select(veinProtoId); - buttons[i].SetIcon(veinProto.iconSprite); - } - } - - for (int i = 0; i < FilterPlanetThemes.Length; i++) - { - buttons[12 + i].SetIcon(PlanetIcons[FilterPlanetThemes[i]]); - } - UpdateI18N(); - }; - - GameLogicProc.OnGameBegin += () => - { - if (DSPGame.IsMenuDemo) return; - - var galaxy = GameMain.data.galaxy; - ShowStarName = new bool[galaxy.starCount]; - _starOrderNames = new string[galaxy.starCount]; - _starmapStarFilterValues = new ulong[galaxy.starCount]; - StarData[] stars = [.. galaxy.stars.Where(star => star != null)]; - Array.Sort(stars, (a, b) => - { - int res = a.position.sqrMagnitude.CompareTo(b.position.sqrMagnitude); - if (res != 0) return res; - return a.index.CompareTo(b.index); - }); - for (int i = 0; i < stars.Length; i++) - { - var star = stars[i]; - _starOrderNames[star.index] = star.displayName; - } - int[] spectrCount = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - for (int i = 0; i < stars.Length; i++) - { - var star = stars[i]; - var index = star.index; - switch (star.type) - { - case EStarType.MainSeqStar: - switch (star.spectr) - { - case ESpectrType.M: - _starOrderNames[index] = String.Format("M{0}", ++spectrCount[0]); - break; - case ESpectrType.K: - _starOrderNames[index] = String.Format("K{0}", ++spectrCount[1]); - break; - case ESpectrType.G: - _starOrderNames[index] = String.Format("G{0}", ++spectrCount[2]); - break; - case ESpectrType.F: - _starOrderNames[index] = String.Format("F{0}", ++spectrCount[3]); - break; - case ESpectrType.A: - _starOrderNames[index] = String.Format("A{0}", ++spectrCount[4]); - break; - case ESpectrType.B: - _starOrderNames[index] = String.Format("B{0}", ++spectrCount[5]); - break; - case ESpectrType.O: - _starOrderNames[index] = String.Format("O{0}", ++spectrCount[6]); - break; - } - break; - case EStarType.GiantStar: - _starOrderNames[index] = String.Format("GS{0}", ++spectrCount[7]); - break; - case EStarType.WhiteDwarf: - _starOrderNames[index] = String.Format("WD{0}", ++spectrCount[8]); - break; - case EStarType.NeutronStar: - _starOrderNames[index] = String.Format("NS{0}", ++spectrCount[9]); - break; - case EStarType.BlackHole: - _starOrderNames[index] = String.Format("BH{0}", ++spectrCount[10]); - break; - } - } - StarmapFilterToggler.gameObject.SetActive(false); - StarmapFilterToggler.Checked = false; - UpdateButtons(); - SetStarFilterEnabled(false); - foreach (var star in galaxy.stars) - { - if (star != null) PlanetModelingManager.RequestScanStar(star); - } - _starmapFilterInitialized = true; - if (PlanetModelingManager.scnPlanetReqList.Count == 0) - { - OnPlanetScanEnded(); - } - }; - GameLogicProc.OnGameEnd += () => - { - _starOrderNames = null; - ShowStarName = null; - _starmapStarFilterValues = null; - _starmapFilterInitialized = false; - }; - void UpdateI18N() - { - if (cornerComboBox != null) - { - var items = cornerComboBox.Items; - cornerComboBox.UpdateLabelText(); - items[0] = "Show original name".Translate(); - items[1] = "Show distance".Translate(); - items[2] = "Show planet count".Translate(); - items[3] = "Show all information".Translate(); - } - if (buttons != null) - { - VeinProto veinProto; - ItemProto itemProto; - for (int i = 0; i < 12; i++) - { - var (veinProtoId, itemProtoId) = FilterVeinIds[i]; - if (itemProtoId != 0) - { - itemProto = LDB.items.Select(itemProtoId); - buttons[i].WithTip(itemProto.Name); - } - else if (veinProtoId != 0) - { - veinProto = LDB.veins.Select(veinProtoId); - buttons[i].WithTip(veinProto.Name); - } - } - for (int i = 0; i < FilterPlanetThemes.Length; i++) - { - var theme = FilterPlanetThemes[i]; - var themeProto = LDB.themes.Select(theme); - switch (i) - { - case 5: - buttons[12 + i].SetLabelText($"{themeProto.DisplayName.Translate()} ({"High yield".Translate()})"); - break; - case 6: - buttons[12 + i].SetLabelText($"{themeProto.DisplayName.Translate()} ({"Perfect".Translate()})"); - break; - default: - buttons[12 + i].SetLabelText(themeProto.DisplayName.Translate()); - break; - } - } - } - if (allOresText != null) allOresText.text = "All 6 Basic Ores".Translate(); - } - void UpdateButtons() - { - var chk = StarmapFilterToggler.Checked; - foreach (var button in buttons) - { - if (chk) - button.gameObject.SetActive(true); - else - { - button.gameObject.SetActive(false); - button.Checked = false; - } - } - unionCheckBox.gameObject.SetActive(chk); - allOresText.gameObject.SetActive(chk); - StarmapFilterToggler.SetLabelText(chk ? "X" : ">>"); - if (!chk) - { - UpdateStarmapStarFilters(); - } - UIRoot.instance.uiGame.dfMonitor.transform.parent.gameObject.SetActive(!chk); - } - void UpdateStarmapStarFilters() - { - var filterValue = 0UL; - var union = unionCheckBox.Checked; - if (StarmapFilterToggler.Checked) - { - for (int i = 0; i < 12; i++) - { - if (buttons[i].Checked) - { - var (veinProtoId, itemProtoId) = FilterVeinIds[i]; - if (veinProtoId != 0) - { - filterValue |= 1UL << veinProtoId; - } - else if (itemProtoId != 0) - { - filterValue |= 1UL << ItemToVeinBitFlagMap[itemProtoId]; - } - } - } - for (int i = 0; i < FilterPlanetThemes.Length; i++) - { - if (buttons[12 + i].Checked) - { - filterValue |= 1UL << (30 + FilterPlanetThemes[i]); - } - } - } - if (filterValue == 0UL) - { - for (int i = 0; i < ShowStarName.Length; i++) - { - ShowStarName[i] = false; - } - SetStarFilterEnabled(false); - return; - } - for (int i = _starmapStarFilterValues.Length - 1; i >= 0; i--) - { - ShowStarName[i] = union ? (_starmapStarFilterValues[i] & filterValue) != 0 : (_starmapStarFilterValues[i] & filterValue) == filterValue; - } - SetStarFilterEnabled(true); - } - } - - public static void OnPlanetScanEnded() - { - if (!_starmapFilterInitialized || StarmapFilterToggler == null || StarmapFilterToggler.gameObject.activeSelf) return; - StarmapUpdateFilterValues(); - StarmapFilterToggler.gameObject.SetActive(true); - } - - private static void StarmapUpdateFilterValues() - { - var galaxy = GameMain.data.galaxy; - var stars = galaxy.stars; - for (int i = 0; i < galaxy.starCount; i++) - { - var star = stars[i]; - if (star == null) continue; - var value = 0UL; - foreach (var planet in star.planets) - { - if (planet == null) continue; - if (!planet.scanned) - { - PlanetModelingManager.RequestScanPlanet(planet); - continue; - } - var planetValue = 0UL; - if (planet.type == EPlanetType.Gas) - { - foreach (var n in planet.gasItems) - { - if (ItemToVeinBitFlagMap.TryGetValue(n, out var bitFlag)) - { - planetValue |= 1UL << bitFlag; - } - } - } - else - { - if (planet.runtimeVeinGroups != null) - { - foreach (var group in planet.runtimeVeinGroups) - { - if (group.amount > 0) - { - planetValue |= 1UL << (int)group.type; - } - } - } - if (ItemToVeinBitFlagMap.TryGetValue(planet.waterItemId, out var bitFlag)) - { - planetValue |= 1UL << bitFlag; - } - } - if ((value & (1UL << (30 + planet.theme))) == 0) - { - switch (planet.theme) - { - case 7: - case 9: - case 10: - case 13: - case 17: - case 19: - case 20: - case 24: - { - const ulong needed = 0x7EUL; - if ((planetValue & needed) == needed) - { - value |= 1UL << (30 + planet.theme); - } - break; - } - case 14: - { - const ulong needed = 0x2200UL; - if ((planetValue & needed) == needed) - { - value |= 1UL << (30 + planet.theme); - } - break; - } - case 15: - case 16: - case 21: - case 22: - case 23: - case 25: - value |= 1UL << (30 + planet.theme); - break; - } - } - value |= planetValue; - } - _starmapStarFilterValues[i] = value; - } - } - - public static int CornerComboBoxIndex - { - get => _cornerComboBoxIndex; - set - { - _cornerComboBoxIndex = value; - Patches.PlayerPatch.ShortcutKeysForStarsName.ForceShowAllStarsNameExternal = _cornerComboBoxIndex != 0 && !_starFilterEnabled; - UpdateStarmapStarNames(); - } - } - - private static void SetStarFilterEnabled(bool enabled) - { - if (_starFilterEnabled == enabled) return; - _starFilterEnabled = enabled; - if (!enabled) Patches.PlayerPatch.ShortcutKeysForStarsName.ShowAllStarsNameStatus = 0; - Patches.PlayerPatch.ShortcutKeysForStarsName.ForceShowAllStarsNameExternal = _cornerComboBoxIndex != 0 && !_starFilterEnabled; - UpdateStarmapStarNames(); - } - - private static void UpdateStarmapStarNames() - { - foreach (var starUI in UIRoot.instance.uiGame.starmap.starUIs) - { - var star = starUI?.star; - if (star == null) continue; - switch (_cornerComboBoxIndex) - { - case 1: - starUI.nameText.text = String.Format("{0:00}-{1}-{2:0.00}", star.index + 1, _starOrderNames[star.index], GetStarDist(star)); - break; - case 2: - { - var (nongas, total) = GetStarPlanetCount(star); - starUI.nameText.text = String.Format("{0:00}-{1}-{2}-{3}", star.index + 1, _starOrderNames[star.index], nongas, total); - break; - } - case 3: - { - var (nongas, total) = GetStarPlanetCount(star); - starUI.nameText.text = String.Format("{0:00}-{1}-{2:0.00}-{3}-{4}", star.index + 1, _starOrderNames[star.index], GetStarDist(star), nongas, total); - break; - } - default: - starUI.nameText.text = star.displayName; - break; - } - } - return; - - double GetStarDist(StarData star) - { - return star.position.magnitude; - } - - (int, int) GetStarPlanetCount(StarData star) - { - int total = 0; - int nongas = 0; - foreach (var planet in star.planets) - { - if (planet == null) continue; - if (planet.type != EPlanetType.Gas) nongas++; - total++; - } - return (nongas, total); - } - } - #endregion - - #region MilkyWayClusterUploadResult - - const int ClusterUploadResultKeepCount = 100; - private static readonly ClusterUploadResult[] _clusterUploadResults = new ClusterUploadResult[ClusterUploadResultKeepCount]; - private static readonly object _clusterUploadResultsLock = new(); - private static int _clusterUploadResultsHead = 0; - private static int _clusterUploadResultsCount = 0; - - private struct ClusterUploadResult - { - public DateTime UploadTime; - public int Result; - public float RequestTime; - } - - public static void AddClusterUploadResult(int result, float requestTime) - { - lock (_clusterUploadResultsLock) - { - if (_clusterUploadResultsCount >= ClusterUploadResultKeepCount) - { - _clusterUploadResults[_clusterUploadResultsHead] = new ClusterUploadResult { UploadTime = DateTime.Now, Result = result, RequestTime = requestTime }; - _clusterUploadResultsHead = (_clusterUploadResultsHead + 1) % ClusterUploadResultKeepCount; - } - else - { - _clusterUploadResults[(_clusterUploadResultsHead + _clusterUploadResultsCount) % ClusterUploadResultKeepCount] = new ClusterUploadResult { UploadTime = DateTime.Now, Result = result, RequestTime = requestTime }; - _clusterUploadResultsCount++; - } - } - } - - public static void ExportClusterUploadResults(BinaryWriter w) - { - lock (_clusterUploadResultsLock) - { - w.Write(_clusterUploadResultsCount); - w.Write(_clusterUploadResultsHead); - for (var i = 0; i < _clusterUploadResultsCount; i++) - { - ref var result = ref _clusterUploadResults[(i + _clusterUploadResultsHead) % ClusterUploadResultKeepCount]; - w.Write(result.UploadTime.ToBinary()); - w.Write(result.Result); - w.Write(result.RequestTime); - } - } - } - - public static void ImportClusterUploadResults(BinaryReader r) - { - lock (_clusterUploadResultsLock) - { - _clusterUploadResultsCount = r.ReadInt32(); - _clusterUploadResultsHead = r.ReadInt32(); - for (var i = 0; i < _clusterUploadResultsCount; i++) - { - ref var result = ref _clusterUploadResults[(i + _clusterUploadResultsHead) % ClusterUploadResultKeepCount]; - result.UploadTime = DateTime.FromBinary(r.ReadInt64()); - result.Result = r.ReadInt32(); - result.RequestTime = r.ReadSingle(); - } - } - } - - public static void ClearClusterUploadResults() - { - lock (_clusterUploadResultsLock) - { - _clusterUploadResultsCount = 0; - _clusterUploadResultsHead = 0; - } - } - - public static void ShowRecentMilkywayUploadResults() - { - lock (_clusterUploadResultsLock) - { - if (_clusterUploadResultsCount == 0) - { - UIMessageBox.Show("UXAssist".Translate(), "No recent milkyway upload results".Translate(), "确定".Translate(), UIMessageBox.INFO, null); - return; - } - StringBuilder sb = new(); - var start = _clusterUploadResultsCount; - var end = start > 10 ? start - 10 : 0; - for (var i = start - 1; i >= end; i--) - { - var res = _clusterUploadResults[(i + _clusterUploadResultsHead) % ClusterUploadResultKeepCount]; - sb.AppendLine($"{res.UploadTime.ToString("yyyy-MM-dd HH:mm:ss")} - {((res.Result is 0 or 20) ? "Success".Translate() : ("Failure: ".Translate() + res.Result.ToString()))} - {res.RequestTime:F2}s"); - } - UIMessageBox.Show("UXAssist".Translate(), sb.ToString(), "确定".Translate(), UIMessageBox.INFO, null); - } - } - #endregion - - #region MilkyWayTopTenPlayers - private static ClusterPlayerData[] _topTenPlayerData = null; - private static readonly StringBuilder _sb = new(" ", 12); - - public static UI.MyCheckButton MilkyWayTopTenPlayersToggler; - public static event Action OnMilkyWayTopTenPlayersUpdated; - - public static void SetTopPlayerCount(int count) - { - _topTenPlayerData = new ClusterPlayerData[count]; - } - - public static void SetTopPlayerData(int index, ref ClusterPlayerData playerData) - { - if (index < 0 || index >= _topTenPlayerData.Length) return; - _topTenPlayerData[index] = playerData; - } - - public static void UpdateMilkyWayTopTenPlayers() - { - if (_topTenPlayerData == null) return; - OnMilkyWayTopTenPlayersUpdated?.Invoke(); + MenuButtonUI.InitMenuButtons(); } public static void InitMilkyWayTopTenPlayers() { - var uiRoot = UIRoot.instance; - if (!uiRoot) return; + MilkyWayUI.InitMilkyWayTopTenPlayers(); + } - var rect = uiRoot.uiMilkyWay.transform as RectTransform; - var panel = new GameObject("uxassist-milkyway-top-ten-players-panel"); - var rtrans = panel.AddComponent(); - rtrans.SetParent(rect); - rtrans.sizeDelta = new Vector2(0f, 0f); - rtrans.localScale = new Vector3(1f, 1f, 1f); - rtrans.anchorMax = new Vector2(1f, 1f); - rtrans.anchorMin = new Vector2(0f, 0f); - rtrans.pivot = new Vector2(0f, 1f); - rtrans.anchoredPosition3D = new Vector3(0, 0, 0f); + public static void UpdateGlobeButtonPosition(UIPlanetGlobe planetGlobe) + { + MenuButtonUI.UpdateGlobeButtonPosition(planetGlobe); + } - MyFlatButton[] buttons = []; - Text[] textFields = []; + public static void UpdateToggleAutoCruiseCheckButtonVisiblility() + { + AutoCruiseUI.UpdateToggleAutoCruiseCheckButtonVisiblility(); + } - MilkyWayTopTenPlayersToggler = UI.MyCheckButton.CreateCheckButton(0, 0, rtrans, false, "Show top players".Translate()).WithSize(120f, 24f); - MilkyWayTopTenPlayersToggler.OnChecked += UpdateButtons; - MilkyWayTopTenPlayersToggler.Checked = false; - UpdateButtons(); - OnMilkyWayTopTenPlayersUpdated += UpdateButtons; + public static void UpdateToggleAutoConstructCheckButtonVisiblility() + { + AutoConstructUI.UpdateToggleAutoConstructCheckButtonVisiblility(); + } - Text CreateTextField(RectTransform parent) - { - var txt = UnityEngine.Object.Instantiate(UIRoot.instance.uiGame.assemblerWindow.stateText, parent); - txt.gameObject.name = "uxassist-milkyway-top-ten-players-text-field"; - txt.text = ""; - txt.color = new Color(1f, 1f, 1f, 0.4f); - txt.alignment = TextAnchor.MiddleLeft; - txt.fontSize = 15; - txt.rectTransform.sizeDelta = new Vector2(0, 18); - return txt; - } + public static void UpdateConstructCountText(int count) + { + AutoConstructUI.UpdateConstructCountText(count); + } - void UpdateButtons() - { - var chk = MilkyWayTopTenPlayersToggler.Checked; - if (_topTenPlayerData == null) - { - MilkyWayTopTenPlayersToggler.gameObject.SetActive(false); - return; - } - var count = _topTenPlayerData.Length; - MilkyWayTopTenPlayersToggler.gameObject.SetActive(count > 0); - if (count != buttons.Length) - { - for (var i = count; i < buttons.Length; i++) - { - UnityEngine.Object.Destroy(buttons[i].gameObject); - UnityEngine.Object.Destroy(textFields[i * 4].gameObject); - UnityEngine.Object.Destroy(textFields[i * 4 + 1].gameObject); - UnityEngine.Object.Destroy(textFields[i * 4 + 2].gameObject); - UnityEngine.Object.Destroy(textFields[i * 4 + 3].gameObject); - } - Array.Resize(ref buttons, count); - Array.Resize(ref textFields, count * 4); - } - float maxWidth0 = 0f; - float maxWidth1 = 0f; - float maxWidth2 = 0f; - float maxWidth3 = 0f; - for (var i = 0; i < count; i++) - { - var button = buttons[i]; - if (chk) - { - if (button == null) - { - button = MyFlatButton.CreateFlatButton(0f, 20f * i + 24f, rtrans, "").WithSize(20f, 18f); - buttons[i] = button; - button.uiButton.data = i; - button.uiButton.onClick += data => - { - if (data < 0 || data >= _topTenPlayerData.Length) return; - ref var playerData = ref _topTenPlayerData[data]; - var seed = playerData.seedKey; - int combatValue = (int)(seed % 1000L); - int resourceMultiplier = (int)(seed / 1000L % 100L); - int starCount = (int)(seed / 100000L % 1000L); - int gameSeed = (int)(seed / 100000000L); - var uiMilkyWaySearchPanel = UIRoot.instance.uiMilkyWay.uiSearchPanel; - uiMilkyWaySearchPanel.selectSeed = gameSeed; - uiMilkyWaySearchPanel.selectStarCnt = starCount; - uiMilkyWaySearchPanel.selectResMulti = resourceMultiplier; - if (combatValue / 100 > 0) - { - uiMilkyWaySearchPanel.selectMode = 1; - uiMilkyWaySearchPanel.selectCombatDiff = combatValue % 100; - } - else - { - uiMilkyWaySearchPanel.selectMode = 0; - uiMilkyWaySearchPanel.selectCombatDiff = 0; - } - uiMilkyWaySearchPanel.RefreshInputText(); - uiMilkyWaySearchPanel.OnSearchButtonClick(0); - }; - textFields[i * 4] = CreateTextField(rtrans); - textFields[i * 4].alignment = TextAnchor.MiddleRight; - textFields[i * 4 + 1] = CreateTextField(rtrans); - textFields[i * 4 + 2] = CreateTextField(rtrans); - textFields[i * 4 + 3] = CreateTextField(rtrans); - textFields[i * 4 + 3].alignment = TextAnchor.MiddleRight; - } - button.SetLabelText(">>"); - textFields[i * 4].text = (i + 1).ToString(); - textFields[i * 4 + 1].text = _topTenPlayerData[i].name; - textFields[i * 4 + 2].text = SeedToString(_topTenPlayerData[i].seedKey); - textFields[i * 4 + 3].text = String.Format("{0}W", ToKMG(_topTenPlayerData[i].genCap * 60L)); - maxWidth0 = Math.Max(maxWidth0, textFields[i * 4].preferredWidth); - maxWidth1 = Math.Max(maxWidth1, textFields[i * 4 + 1].preferredWidth); - maxWidth2 = Math.Max(maxWidth2, textFields[i * 4 + 2].preferredWidth); - maxWidth3 = Math.Max(maxWidth3, textFields[i * 4 + 3].preferredWidth); - button.gameObject.SetActive(true); - textFields[i * 4].gameObject.SetActive(true); - textFields[i * 4 + 1].gameObject.SetActive(true); - textFields[i * 4 + 2].gameObject.SetActive(true); - textFields[i * 4 + 3].gameObject.SetActive(true); - } - else - { - if (button != null) - { - button.gameObject.SetActive(false); - textFields[i * 4].gameObject.SetActive(false); - textFields[i * 4 + 1].gameObject.SetActive(false); - textFields[i * 4 + 2].gameObject.SetActive(false); - textFields[i * 4 + 3].gameObject.SetActive(false); - } - } - } - if (chk) - { - for (var i = 0; i < count; i++) - { - var y = 20f * i + 24f; - UI.Util.NormalizeRectWithTopLeft(textFields[i * 4].rectTransform, 24f + maxWidth0 + 5f, y); - UI.Util.NormalizeRectWithTopLeft(textFields[i * 4 + 1].rectTransform, 24f + maxWidth0 + 10f, y); - UI.Util.NormalizeRectWithTopLeft(textFields[i * 4 + 2].rectTransform, 24f + maxWidth0 + 10f + maxWidth1 + 5f, y); - UI.Util.NormalizeRectWithTopLeft(textFields[i * 4 + 3].rectTransform, 24f + maxWidth0 + 10f + maxWidth1 + 5f + maxWidth2 + 5f + maxWidth3, y); - } - } - MilkyWayTopTenPlayersToggler.SetLabelText(chk ? "Hide top players".Translate() : "Show top players".Translate()); + public static void OnPlanetScanEnded() + { + StarmapFilterUI.OnPlanetScanEnded(); + } - string ToKMG(long value) - { - StringBuilderUtility.WriteKMG(_sb, 8, value, true); - return _sb.ToString(); - } + public static void AddClusterUploadResult(int result, float requestTime) + { + MilkyWayUI.AddClusterUploadResult(result, requestTime); + } - string SeedToString(long seed) - { - int combatValue = (int)(seed % 1000L); - int resourceMultiplier = (int)(seed / 1000L % 100L); - int starCount = (int)(seed / 100000L % 1000L); - int gameSeed = (int)(seed / 100000000L); - string text; - if (combatValue / 100 > 0) - { - text = String.Format("{0:D8}-{1}-Z{2}-{3:00}", gameSeed, starCount, resourceMultiplier, combatValue % 100); - } - else - { - text = String.Format("{0:D8}-{1}-A{2}", gameSeed, starCount, resourceMultiplier); - } - return text; - } - } + public static void ExportClusterUploadResults(BinaryWriter w) + { + MilkyWayUI.Export(w); + } + + public static void ImportClusterUploadResults(BinaryReader r) + { + MilkyWayUI.Import(r); + } + + public static void ClearClusterUploadResults() + { + MilkyWayUI.ClearClusterUploadResults(); + } + + public static void ShowRecentMilkywayUploadResults() + { + MilkyWayUI.ShowRecentMilkywayUploadResults(); + } + + public static void SetTopPlayerCount(int count) + { + MilkyWayUI.SetTopPlayerCount(count); + } + + public static void SetTopPlayerData(int index, ref ClusterPlayerData playerData) + { + MilkyWayUI.SetTopPlayerData(index, ref playerData); + } + + public static void UpdateMilkyWayTopTenPlayers() + { + MilkyWayUI.UpdateMilkyWayTopTenPlayers(); } - #endregion } diff --git a/UXAssist/Patches/PlayerPatch.cs b/UXAssist/Patches/PlayerPatch.cs index f6b3f1c..4c33ff8 100644 --- a/UXAssist/Patches/PlayerPatch.cs +++ b/UXAssist/Patches/PlayerPatch.cs @@ -114,7 +114,7 @@ public class PlayerPatch : PatchImpl new CodeInstruction(OpCodes.Brtrue, jumpPos.Value), new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(PlayerPatch.ShortcutKeysForStarsName), nameof(ShortcutKeysForStarsName.ForceShowAllStarsName))), new CodeInstruction(OpCodes.Brtrue, jumpPos.Value), - new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(Functions.UIFunctions), nameof(Functions.UIFunctions.ShowStarName))), + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(Functions.UI.StarmapFilterUI), nameof(Functions.UI.StarmapFilterUI.ShowStarName))), new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(UIStarmapStar), nameof(UIStarmapStar.star))), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(StarData), nameof(StarData.index))), diff --git a/UXAssist/Patches/UIPatch.cs b/UXAssist/Patches/UIPatch.cs index 0c9f077..46e3e73 100644 --- a/UXAssist/Patches/UIPatch.cs +++ b/UXAssist/Patches/UIPatch.cs @@ -355,21 +355,21 @@ public class UIPatch : PatchImpl [HarmonyPatch(typeof(UIStarmapStar), nameof(UIStarmapStar.OnStarDisplayNameChange))] private static bool UIStarmapStar_OnStarDisplayNameChange_Prefix() { - return Functions.UIFunctions.CornerComboBoxIndex == 0; + return Functions.UI.StarmapFilterUI.CornerComboBoxIndex == 0; } [HarmonyPostfix] [HarmonyPatch(typeof(UIStarmapStar), nameof(UIStarmapStar._OnClose))] private static void UIStarmapStar__OnClose_Postfix(UIStarmapStar __instance) { - Functions.UIFunctions.StarmapFilterToggler?.SetCheckedWithEvent(false); + Functions.UI.StarmapFilterUI.StarmapFilterToggler?.SetCheckedWithEvent(false); } [HarmonyPrefix] [HarmonyPatch(typeof(UIMechaLab), nameof(UIMechaLab.DetermineVisible))] private static bool UIMechaLab_DetermineVisible_Prefix(UIMechaLab __instance, ref bool __result) { - if (!UIRoot.instance.uiGame.starmap.active || !Functions.UIFunctions.StarmapFilterToggler.Checked) + if (!UIRoot.instance.uiGame.starmap.active || !Functions.UI.StarmapFilterUI.StarmapFilterToggler.Checked) { return true; } @@ -382,7 +382,7 @@ public class UIPatch : PatchImpl [HarmonyPatch(typeof(UIGoalPanel), nameof(UIGoalPanel.DetermineVisiable))] private static bool UIGoalPanel_DetermineVisiable_Prefix(UIGoalPanel __instance) { - if (!UIRoot.instance.uiGame.starmap.active || !Functions.UIFunctions.StarmapFilterToggler.Checked) + if (!UIRoot.instance.uiGame.starmap.active || !Functions.UI.StarmapFilterUI.StarmapFilterToggler.Checked) { return true; } diff --git a/UXAssist/UXAssist.cs b/UXAssist/UXAssist.cs index 2da8ed5..a2976da 100644 --- a/UXAssist/UXAssist.cs +++ b/UXAssist/UXAssist.cs @@ -238,7 +238,6 @@ public class UXAssist : BaseUnityPlugin, IModCanSave "Planet vein utilization"); I18N.Init(); - I18N.Add("UXAssist Config", "UXAssist Config", "UX助手设置"); // UI Patches GameLogicProc.Enable(true); @@ -246,7 +245,8 @@ public class UXAssist : BaseUnityPlugin, IModCanSave UIConfigWindow.Init(); _patches = Util.GetTypesFiltered(Assembly.GetExecutingAssembly(), - t => string.Equals(t.Namespace, "UXAssist.Patches", StringComparison.Ordinal) || string.Equals(t.Namespace, "UXAssist.Functions", StringComparison.Ordinal)); + t => (string.Equals(t.Namespace, "UXAssist.Patches", StringComparison.Ordinal) || string.Equals(t.Namespace, "UXAssist.Functions", StringComparison.Ordinal)) + && !Attribute.IsDefined(t, typeof(ModFeatureAttribute))); _patches?.Do(type => type.GetMethod("Init")?.Invoke(null, null)); _compats = Util.GetTypesInNamespace(Assembly.GetExecutingAssembly(), "UXAssist.ModsCompat"); object[] parameters = [_harmony];