1
0
mirror of https://github.com/soarqin/DSP_Mods.git synced 2025-12-08 23:33:33 +08:00

UXAssist 1.1.5

This commit is contained in:
2024-08-30 02:45:46 +08:00
parent d11817d4c3
commit 287cfbbed4
7 changed files with 308 additions and 170 deletions

View File

@@ -237,23 +237,18 @@ public static class UIConfigWindow
private static void UpdateButtons() private static void UpdateButtons()
{ {
var data = GameMain.data; var data = GameMain.data;
if (data != null) if (data == null) return;
var resignEnabled = data.account != AccountData.me;
if (_resignGameBtn.gameObject.activeSelf != resignEnabled)
{ {
var resignEnabled = data.account != AccountData.me; _resignGameBtn.gameObject.SetActive(resignEnabled);
if (_resignGameBtn.gameObject.activeSelf != resignEnabled)
{
_resignGameBtn.gameObject.SetActive(resignEnabled);
}
} }
var history = data.history;
var history = GameMain.history; if (history == null) return;
if (history != null) var banEnabled = history.hasUsedPropertyBanAchievement;
if (_clearBanBtn.gameObject.activeSelf != banEnabled)
{ {
var banEnabled = history.hasUsedPropertyBanAchievement; _clearBanBtn.gameObject.SetActive(banEnabled);
if (_clearBanBtn.gameObject.activeSelf != banEnabled)
{
_clearBanBtn.gameObject.SetActive(banEnabled);
}
} }
} }
} }

View File

@@ -4,6 +4,8 @@
+ New feature: `Logistics Control Panel Improvement` + New feature: `Logistics Control Panel Improvement`
- Auto apply filter with item under mouse cursor while opening the panel - Auto apply filter with item under mouse cursor while opening the panel
- Quick-set item filter while right-clicking item icons in storage list on the panel - Quick-set item filter while right-clicking item icons in storage list on the panel
+ New feature: `Dyson Sphere "Auto Fast Build" speed multiplier`
- Note: this only applies to `Dyson Sphere "Auto Fast Build"` in sandbox mode
+ `Quick build and dismantle stacking labs`: works for storages and tanks now + `Quick build and dismantle stacking labs`: works for storages and tanks now
+ `Enable game window resize`: Keep window resizable on applying game options. + `Enable game window resize`: Keep window resizable on applying game options.
+ `Remember window position and size on last exit`: Do not resize window on applying game options if resolution related config entries are not changed. + `Remember window position and size on last exit`: Do not resize window on applying game options if resolution related config entries are not changed.
@@ -154,6 +156,8 @@
+ 新功能:`物流控制面板改进` + 新功能:`物流控制面板改进`
- 打开面板时自动将鼠标指向物品设为筛选条件 - 打开面板时自动将鼠标指向物品设为筛选条件
- 在控制面板物流塔列表中右键点击物品图标快速设置为筛选条件 - 在控制面板物流塔列表中右键点击物品图标快速设置为筛选条件
+ 新功能:`戴森球自动快速建造速度倍率`
- 注意:这仅适用于沙盒模式下的`戴森球自动快速建造`功能
+ `快速建造和拆除堆叠研究站`:现在也支持储物仓和储液罐 + `快速建造和拆除堆叠研究站`:现在也支持储物仓和储液罐
+ `允许调整游戏窗口大小`:在应用游戏选项时保持窗口可调整大小 + `允许调整游戏窗口大小`:在应用游戏选项时保持窗口可调整大小
+ `记住上次退出时的窗口位置和大小`:如果分辨率相关的配置项未改变,则在应用游戏选项时不调整窗口大小 + `记住上次退出时的窗口位置和大小`:如果分辨率相关的配置项未改变,则在应用游戏选项时不调整窗口大小

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
using BepInEx.Configuration; using BepInEx.Configuration;
using HarmonyLib; using HarmonyLib;
@@ -12,7 +13,9 @@ public static class DysonSpherePatch
public static ConfigEntry<bool> OnlyConstructNodesEnabled; public static ConfigEntry<bool> OnlyConstructNodesEnabled;
public static ConfigEntry<int> AutoConstructMultiplier; public static ConfigEntry<int> AutoConstructMultiplier;
private static Harmony _dysonSpherePatch; private static Harmony _dysonSpherePatch;
private static FieldInfo _totalNodeSpInfo, _totalFrameSpInfo, _totalCpInfo;
public static void Init() public static void Init()
{ {
I18N.Add("[UXAssist] No node to fill", "[UXAssist] No node to fill", "[UXAssist] 无可建造节点"); I18N.Add("[UXAssist] No node to fill", "[UXAssist] No node to fill", "[UXAssist] 无可建造节点");
@@ -21,6 +24,9 @@ public static class DysonSpherePatch
OnlyConstructNodesEnabled.SettingChanged += (_, _) => OnlyConstructNodes.Enable(OnlyConstructNodesEnabled.Value); OnlyConstructNodesEnabled.SettingChanged += (_, _) => OnlyConstructNodes.Enable(OnlyConstructNodesEnabled.Value);
StopEjectOnNodeComplete.Enable(StopEjectOnNodeCompleteEnabled.Value); StopEjectOnNodeComplete.Enable(StopEjectOnNodeCompleteEnabled.Value);
OnlyConstructNodes.Enable(OnlyConstructNodesEnabled.Value); OnlyConstructNodes.Enable(OnlyConstructNodesEnabled.Value);
_totalNodeSpInfo = AccessTools.Field(typeof(DysonSphereLayer), "totalNodeSP");
_totalFrameSpInfo = AccessTools.Field(typeof(DysonSphereLayer), "totalFrameSP");
_totalCpInfo = AccessTools.Field(typeof(DysonSphereLayer), "totalCP");
} }
public static void Uninit() public static void Uninit()
@@ -58,158 +64,182 @@ public static class DysonSpherePatch
} }
ds.RemoveLayer(index); ds.RemoveLayer(index);
} }
[HarmonyPrefix]
[HarmonyPatch(typeof(DysonSwarm), nameof(DysonSwarm.AutoConstruct))]
private static bool DysonSwarm_AutoConstruct_Prefix(DysonSwarm __instance)
{
return false;
}
[HarmonyPrefix] [HarmonyPrefix]
[HarmonyPatch(typeof(DysonSphere), nameof(DysonSphere.AutoConstruct))] [HarmonyPatch(typeof(DysonSphere), nameof(DysonSphere.AutoConstruct))]
private static bool DysonSphere_AutoConstruct_Prefix(DysonSphere __instance) private static bool DysonSphere_AutoConstruct_Prefix(DysonSphere __instance)
{ {
var totalCount = AutoConstructMultiplier.Value * 6; var totalCount = AutoConstructMultiplier.Value * 6;
var totalCount2 = AutoConstructMultiplier.Value * 6;
foreach (var dysonSphereLayer in __instance.layersIdBased) foreach (var dysonSphereLayer in __instance.layersIdBased)
{ {
if (dysonSphereLayer == null) continue; if (dysonSphereLayer == null) continue;
int todoCount;
int[] productRegister;
for (var j = dysonSphereLayer.nodePool.Length - 1; j >= 0; j--) for (var j = dysonSphereLayer.nodePool.Length - 1; j >= 0; j--)
{ {
var dysonNode = dysonSphereLayer.nodePool[j]; var dysonNode = dysonSphereLayer.nodePool[j];
if (dysonNode == null || dysonNode.id != j) continue; if (dysonNode == null || dysonNode.id != j) continue;
var count = dysonNode._spReq - dysonNode.spOrdered; lock (dysonNode)
if (count > 0)
{ {
var count = dysonNode._spReq - dysonNode.spOrdered;
if (count > totalCount) int todoCount;
{ int[] productRegister;
count = totalCount;
dysonNode.spOrdered += count;
}
else
{
dysonNode.spOrdered = dysonNode._spReq;
__instance.RemoveAutoNode(dysonNode);
__instance.PickAutoNode();
}
todoCount = count;
if (dysonNode.sp < dysonNode.spMax)
{
if (dysonNode.sp + count > dysonNode.spMax)
{
var diff = dysonNode.spMax - dysonNode.sp;
count -= diff;
dysonNode.spOrdered -= diff;
dysonNode._spReq -= diff;
dysonNode.sp = dysonNode.spMax;
}
else
{
dysonNode.spOrdered -= count;
dysonNode._spReq -= count;
dysonNode.sp += count;
count = 0;
}
__instance.UpdateProgress(dysonNode);
}
if (count > 0) if (count > 0)
{ {
var frameCount = dysonNode.frames.Count;
var frameIndex = dysonNode.frameTurn % frameCount; if (count > totalCount)
for (var i = frameCount; i > 0; i--)
{ {
var dysonFrame = dysonNode.frames[frameIndex]; count = totalCount;
var spMax = dysonFrame.spMax >> 1; }
if (dysonFrame.nodeA == dysonNode && dysonFrame.spA < spMax)
todoCount = count;
if (dysonNode.sp < dysonNode.spMax)
{
int diff;
if (dysonNode.sp + count > dysonNode.spMax)
{ {
if (dysonFrame.spA + count > spMax) diff = dysonNode.spMax - dysonNode.sp;
{ count -= diff;
var diff = spMax - dysonFrame.spA; dysonNode._spReq -= diff;
count -= diff;
dysonNode.spOrdered -= diff;
dysonNode._spReq -= diff;
dysonFrame.spA = spMax; dysonNode.sp = dysonNode.spMax;
__instance.UpdateProgress(dysonFrame);
}
else
{
dysonNode.spOrdered -= count;
dysonNode._spReq -= count;
dysonFrame.spA += count;
count = 0;
__instance.UpdateProgress(dysonFrame);
break;
}
} }
else
if (dysonFrame.nodeB == dysonNode && dysonFrame.spB < spMax)
{ {
if (dysonFrame.spB + count > spMax) diff = count;
{ dysonNode._spReq -= diff;
var diff = spMax - dysonFrame.spB;
count -= diff;
dysonNode.spOrdered -= diff;
dysonNode._spReq -= diff;
dysonFrame.spB = spMax; dysonNode.sp += diff;
__instance.UpdateProgress(dysonFrame); count = 0;
}
else
{
dysonNode.spOrdered -= count;
dysonNode._spReq -= count;
dysonFrame.spB += count;
count = 0;
__instance.UpdateProgress(dysonFrame);
break;
}
} }
// Make compatible with DSPOptimizations
if (_totalNodeSpInfo != null)
_totalNodeSpInfo.SetValue(dysonSphereLayer, (long)_totalNodeSpInfo.GetValue(dysonSphereLayer) + diff - 1);
__instance.UpdateProgress(dysonNode);
}
frameIndex = (frameIndex + 1) % frameCount; if (count > 0)
{
var frameCount = dysonNode.frames.Count;
var frameIndex = dysonNode.frameTurn % frameCount;
for (var i = frameCount; i > 0 && count > 0; i--)
{
var dysonFrame = dysonNode.frames[frameIndex];
var spMax = dysonFrame.spMax >> 1;
if (dysonFrame.nodeA == dysonNode && dysonFrame.spA < spMax)
{
int diff;
if (dysonFrame.spA + count > spMax)
{
diff = spMax - dysonFrame.spA;
count -= diff;
dysonNode._spReq -= diff;
dysonFrame.spA = spMax;
}
else
{
diff = count;
dysonNode._spReq -= diff;
dysonFrame.spA += diff;
count = 0;
}
// Make compatible with DSPOptimizations
if (_totalFrameSpInfo != null)
_totalFrameSpInfo.SetValue(dysonSphereLayer, (long)_totalFrameSpInfo.GetValue(dysonSphereLayer) + diff - 1);
__instance.UpdateProgress(dysonFrame);
}
if (count > 0 && dysonFrame.nodeB == dysonNode && dysonFrame.spB < spMax)
{
int diff;
if (dysonFrame.spB + count > spMax)
{
diff = spMax - dysonFrame.spB;
count -= diff;
dysonNode._spReq -= diff;
dysonFrame.spB = spMax;
}
else
{
diff = count;
dysonNode._spReq -= diff;
dysonFrame.spB += diff;
count = 0;
}
// Make compatible with DSPOptimizations
if (_totalFrameSpInfo != null)
_totalFrameSpInfo.SetValue(dysonSphereLayer, (long)_totalFrameSpInfo.GetValue(dysonSphereLayer) + diff - 1);
__instance.UpdateProgress(dysonFrame);
}
frameIndex = (frameIndex + 1) % frameCount;
}
dysonNode.frameTurn = frameIndex;
}
if (dysonNode.spOrdered >= dysonNode._spReq)
{
__instance.RemoveAutoNode(dysonNode);
__instance.PickAutoNode();
}
productRegister = __instance.productRegister;
if (productRegister != null)
{
lock (productRegister)
{
productRegister[11902] += todoCount - count;
}
} }
} }
productRegister = __instance.productRegister; count = dysonNode._cpReq - dysonNode.cpOrdered;
if (productRegister != null) if (count > 0)
{ {
lock (productRegister) if (count > totalCount) count = totalCount;
todoCount = count;
var shellCount = dysonNode.shells.Count;
var shellIndex = dysonNode.shellTurn % shellCount;
for (var i = shellCount; i > 0 && count > 0; i--)
{ {
productRegister[11902] += todoCount - count; var dysonShell = dysonNode.shells[shellIndex];
lock (dysonShell)
{
var nodeIndex = dysonShell.nodeIndexMap[dysonNode.id];
var diff = (dysonShell.vertsqOffset[nodeIndex + 1] - dysonShell.vertsqOffset[nodeIndex]) * dysonShell.cpPerVertex - dysonShell.nodecps[nodeIndex];
if (diff > count)
diff = count;
count -= diff;
dysonNode._cpReq -= diff;
dysonShell.nodecps[nodeIndex] += diff;
dysonShell.nodecps[dysonShell.nodecps.Length - 1] += diff;
// Make compatible with DSPOptimizations
if (_totalCpInfo != null)
{
_totalCpInfo.SetValue(dysonSphereLayer, (long)_totalCpInfo.GetValue(dysonSphereLayer) + diff);
dysonShell.SetMaterialDynamicVars();
}
}
shellIndex = (shellIndex + 1) % shellCount;
} }
} dysonNode.shellTurn = shellIndex;
}
count = dysonNode._cpReq - dysonNode.cpOrdered; productRegister = __instance.productRegister;
if (count > totalCount2) count = totalCount2; if (productRegister != null)
todoCount = count; {
dysonNode.cpOrdered += count; lock (productRegister)
var shellCount = dysonNode.shells.Count; {
var shellIndex = dysonNode.shellTurn % shellCount; productRegister[11903] += todoCount - count;
for (var i = shellCount; i > 0 && count > 0; i--) }
{ }
var dysonShell = dysonNode.shells[shellIndex];
var nodeIndex = dysonShell.nodeIndexMap[dysonNode.id];
var diff = (dysonShell.vertsqOffset[nodeIndex + 1] - dysonShell.vertsqOffset[nodeIndex]) * dysonShell.cpPerVertex - dysonShell.nodecps[nodeIndex];
if (diff > count)
diff = count;
count -= diff;
dysonNode.cpOrdered -= diff;
dysonNode._cpReq -= diff;
dysonShell.nodecps[nodeIndex] += diff;
dysonShell.nodecps[dysonShell.nodecps.Length - 1] += diff;
shellIndex = (shellIndex + 1) % shellCount;
}
productRegister = __instance.productRegister;
if (productRegister != null)
{
lock (productRegister)
{
productRegister[11903] += todoCount - count;
} }
} }
} }

View File

@@ -76,6 +76,8 @@
- Construct only structure points but frames - Construct only structure points but frames
- Re-initialize Dyson Spheres - Re-initialize Dyson Spheres
- Quick dismantle Dyson Shells - Quick dismantle Dyson Shells
- Dyson Sphere "Auto Fast Build" speed multiplier
- Note: this only applies to `Dyson Sphere "Auto Fast Build"` in sandbox mode
+ Tech + Tech
- Restore upgrades of `Sorter Cargo Stacking` on panel - Restore upgrades of `Sorter Cargo Stacking` on panel
- Set `Sorter Cargo Stacking` to unresearched state - Set `Sorter Cargo Stacking` to unresearched state
@@ -172,6 +174,8 @@
- 只建造节点不建造框架 - 只建造节点不建造框架
- 初始化戴森球 - 初始化戴森球
- 快速拆除戴森壳 - 快速拆除戴森壳
- 戴森球自动快速建造速度倍率
- 注意:这仅适用于沙盒模式下的`戴森球自动快速建造`功能
+ 科研 + 科研
- 在升级面板上恢复`分拣器货物堆叠`的升级 - 在升级面板上恢复`分拣器货物堆叠`的升级
-`分拣器货物堆叠`设为未研究状态 -`分拣器货物堆叠`设为未研究状态

View File

@@ -1,6 +1,7 @@
using System; using System;
using HarmonyLib; using HarmonyLib;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using BepInEx.Configuration; using BepInEx.Configuration;
using UnityEngine; using UnityEngine;
using UnityEngine.Events; using UnityEngine.Events;
@@ -11,7 +12,7 @@ namespace UXAssist.UI;
// MyWindow modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyWindowCtl.cs // MyWindow modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyWindowCtl.cs
public class MyWindow: ManualBehaviour public class MyWindow : ManualBehaviour
{ {
private readonly Dictionary<InputField, Tuple<UnityAction<string>, UnityAction<string>>> _inputFields = new(); private readonly Dictionary<InputField, Tuple<UnityAction<string>, UnityAction<string>>> _inputFields = new();
private readonly Dictionary<UIButton, UnityAction> _buttons = new(); private readonly Dictionary<UIButton, UnityAction> _buttons = new();
@@ -41,7 +42,7 @@ public class MyWindow: ManualBehaviour
} }
public void Close() => _Close(); public void Close() => _Close();
public void SetTitle(string title) public void SetTitle(string title)
{ {
var txt = gameObject.transform.Find("panel-bg/title-text")?.gameObject.GetComponent<Text>(); var txt = gameObject.transform.Find("panel-bg/title-text")?.gameObject.GetComponent<Text>();
@@ -110,6 +111,7 @@ public class MyWindow: ManualBehaviour
_maxX = Math.Max(_maxX, x + rect.sizeDelta.x); _maxX = Math.Max(_maxX, x + rect.sizeDelta.x);
MaxY = Math.Max(MaxY, y + rect.sizeDelta.y); MaxY = Math.Max(MaxY, y + rect.sizeDelta.y);
} }
return tipsButton; return tipsButton;
} }
@@ -132,10 +134,12 @@ public class MyWindow: ManualBehaviour
l.stringKey = text; l.stringKey = text;
l.translation = text.Translate(); l.translation = text.Translate();
} }
if (t != null) if (t != null)
{ {
t.text = text.Translate(); t.text = text.Translate();
} }
t.fontSize = fontSize; t.fontSize = fontSize;
btn.button.onClick.RemoveAllListeners(); btn.button.onClick.RemoveAllListeners();
btn.tip = null; btn.tip = null;
@@ -146,6 +150,7 @@ public class MyWindow: ManualBehaviour
if (onClick != null) if (onClick != null)
btn.button.onClick.AddListener(onClick); btn.button.onClick.AddListener(onClick);
} }
_maxX = Math.Max(_maxX, x + rect.sizeDelta.x); _maxX = Math.Max(_maxX, x + rect.sizeDelta.x);
MaxY = Math.Max(MaxY, y + rect.sizeDelta.y); MaxY = Math.Max(MaxY, y + rect.sizeDelta.y);
return btn; return btn;
@@ -163,11 +168,13 @@ public class MyWindow: ManualBehaviour
img.sprite = panel.buttonDefaultSprite; img.sprite = panel.buttonDefaultSprite;
img.color = new Color(img.color.r, img.color.g, img.color.b, 13f / 255f); img.color = new Color(img.color.r, img.color.g, img.color.b, 13f / 255f);
} }
img = btn.gameObject.transform.Find("frame")?.GetComponent<Image>(); img = btn.gameObject.transform.Find("frame")?.GetComponent<Image>();
if (img != null) if (img != null)
{ {
img.color = new Color(img.color.r, img.color.g, img.color.b, 0f); img.color = new Color(img.color.r, img.color.g, img.color.b, 0f);
} }
var rect = Util.NormalizeRectWithTopLeft(btn, x, y, parent); var rect = Util.NormalizeRectWithTopLeft(btn, x, y, parent);
var t = btn.gameObject.transform.Find("Text")?.GetComponent<Text>(); var t = btn.gameObject.transform.Find("Text")?.GetComponent<Text>();
if (t != null) if (t != null)
@@ -175,12 +182,14 @@ public class MyWindow: ManualBehaviour
t.text = text.Translate(); t.text = text.Translate();
t.fontSize = fontSize; t.fontSize = fontSize;
} }
btn.button.onClick.RemoveAllListeners(); btn.button.onClick.RemoveAllListeners();
_buttons[btn] = onClick; _buttons[btn] = onClick;
if (EventRegistered && onClick != null) if (EventRegistered && onClick != null)
{ {
btn.button.onClick.AddListener(onClick); btn.button.onClick.AddListener(onClick);
} }
_maxX = Math.Max(_maxX, x + rect.sizeDelta.x); _maxX = Math.Max(_maxX, x + rect.sizeDelta.x);
MaxY = Math.Max(MaxY, y + rect.sizeDelta.y); MaxY = Math.Max(MaxY, y + rect.sizeDelta.y);
return btn; return btn;
@@ -203,10 +212,90 @@ public class MyWindow: ManualBehaviour
_maxX = Math.Max(_maxX, x + rect.sizeDelta.x); _maxX = Math.Max(_maxX, x + rect.sizeDelta.x);
MaxY = Math.Max(MaxY, y + rect.sizeDelta.y); MaxY = Math.Max(MaxY, y + rect.sizeDelta.y);
} }
return slider; return slider;
} }
public InputField AddInputField(float x, float y, RectTransform parent, string text = "", int fontSize = 16, string objName = "input", UnityAction<string> onChanged = null, UnityAction<string> onEditEnd = null) public class ValueMapper<T>
{
public virtual int Min => 1;
public virtual int Max => 100;
public virtual int ValueToIndex(T value) => (int)Convert.ChangeType(value, typeof(int), CultureInfo.InvariantCulture);
public virtual T IndexToValue(int index) => (T)Convert.ChangeType(index, typeof(T), CultureInfo.InvariantCulture);
public virtual string FormatValue(string format, T value)
{
return string.Format($"{{0:{format}}}", value);
}
}
public MySlider AddSlider<T>(float x, float y, RectTransform parent, ConfigEntry<T> config, ValueMapper<T> valueMapper, string format = "G", float width = 0f)
{
var slider = MySlider.CreateSlider(x, y, parent, OnConfigValueChanged(config), valueMapper.Min, valueMapper.Max, format, width);
slider.SetLabelText(valueMapper.FormatValue(format, config.Value));
config.SettingChanged += (sender, args) =>
{
var index = OnConfigValueChanged(config);
slider.Value = index;
};
slider.OnValueChanged += () =>
{
var index = Mathf.RoundToInt(slider.Value);
config.Value = valueMapper.IndexToValue(index);
slider.SetLabelText(valueMapper.FormatValue(format, config.Value));
};
var rect = slider.rectTrans;
if (rect != null)
{
_maxX = Math.Max(_maxX, x + rect.sizeDelta.x);
MaxY = Math.Max(MaxY, y + rect.sizeDelta.y);
}
return slider;
int OnConfigValueChanged(ConfigEntry<T> conf)
{
var index = valueMapper.ValueToIndex(conf.Value);
if (index >= 0) return index;
index = ~index;
index = Math.Max(0, Math.Min(valueMapper.Max, index));
conf.Value = valueMapper.IndexToValue(index);
return index;
}
}
private class ArrayMapper<T> : ValueMapper<T>
{
private readonly T[] _values;
public ArrayMapper(T[] values)
{
Array.Sort(values);
_values = values;
}
public override int Min => 0;
public override int Max => _values.Length - 1;
public override int ValueToIndex(T value)
{
return Array.BinarySearch(_values, value);
}
public override T IndexToValue(int index)
{
return _values[index >= 0 && index < _values.Length ? index : 0];
}
}
public MySlider AddSlider<T>(float x, float y, RectTransform parent, ConfigEntry<T> config, T[] valueList, string format = "G", float width = 0f)
{
return AddSlider(x, y, parent, config, new ArrayMapper<T>(valueList), format, width);
}
public InputField AddInputField(float x, float y, RectTransform parent, string text = "", int fontSize = 16, string objName = "input", UnityAction<string> onChanged = null,
UnityAction<string> onEditEnd = null)
{ {
var stationWindow = UIRoot.instance.uiGame.stationWindow; var stationWindow = UIRoot.instance.uiGame.stationWindow;
//public InputField nameInput; //public InputField nameInput;
@@ -228,6 +317,7 @@ public class MyWindow: ManualBehaviour
if (onEditEnd != null) if (onEditEnd != null)
inputField.onEndEdit.AddListener(onEditEnd); inputField.onEndEdit.AddListener(onEditEnd);
} }
_maxX = Math.Max(_maxX, x + rect.sizeDelta.x); _maxX = Math.Max(_maxX, x + rect.sizeDelta.x);
MaxY = Math.Max(MaxY, y + rect.sizeDelta.y); MaxY = Math.Max(MaxY, y + rect.sizeDelta.y);
return inputField; return inputField;
@@ -245,12 +335,14 @@ public class MyWindow: ManualBehaviour
if (t.Value.Item2 != null) if (t.Value.Item2 != null)
inputField.onEndEdit.AddListener(t.Value.Item2); inputField.onEndEdit.AddListener(t.Value.Item2);
} }
foreach (var t in _buttons) foreach (var t in _buttons)
{ {
var btn = t.Key; var btn = t.Key;
if (t.Value != null) if (t.Value != null)
btn.button.onClick.AddListener(t.Value); btn.button.onClick.AddListener(t.Value);
} }
EventRegistered = true; EventRegistered = true;
} }
@@ -265,6 +357,7 @@ public class MyWindow: ManualBehaviour
if (t.Value != null) if (t.Value != null)
btn.button.onClick.RemoveListener(t.Value); btn.button.onClick.RemoveListener(t.Value);
} }
foreach (var t in _inputFields) foreach (var t in _inputFields)
{ {
var inputField = t.Key; var inputField = t.Key;
@@ -290,7 +383,7 @@ public class MyWindowWithTabs : MyWindow
{ {
return true; return true;
} }
private RectTransform AddTabInternal(float y, int index, RectTransform parent, string label) private RectTransform AddTabInternal(float y, int index, RectTransform parent, string label)
{ {
var tab = new GameObject(); var tab = new GameObject();
@@ -322,6 +415,7 @@ public class MyWindowWithTabs : MyWindow
{ {
btn.onClick += OnTabButtonClick; btn.onClick += OnTabButtonClick;
} }
MaxY = Math.Max(MaxY, y + TabHeight); MaxY = Math.Max(MaxY, y + TabHeight);
return tabRect; return tabRect;
} }
@@ -358,6 +452,7 @@ public class MyWindowWithTabs : MyWindow
t.Item2.onClick += OnTabButtonClick; t.Item2.onClick += OnTabButtonClick;
} }
} }
base._OnRegEvent(); base._OnRegEvent();
} }
@@ -370,6 +465,7 @@ public class MyWindowWithTabs : MyWindow
t.Item2.onClick -= OnTabButtonClick; t.Item2.onClick -= OnTabButtonClick;
} }
} }
base._OnUnregEvent(); base._OnUnregEvent();
} }
@@ -385,6 +481,7 @@ public class MyWindowWithTabs : MyWindow
rectTransform.gameObject.SetActive(false); rectTransform.gameObject.SetActive(false);
continue; continue;
} }
btn.highlighted = true; btn.highlighted = true;
rectTransform.gameObject.SetActive(true); rectTransform.gameObject.SetActive(true);
} }
@@ -401,13 +498,13 @@ public static class MyWindowManager
{ {
_patch ??= Harmony.CreateAndPatchAll(typeof(Patch)); _patch ??= Harmony.CreateAndPatchAll(typeof(Patch));
} }
public static void Uninit() public static void Uninit()
{ {
_patch?.UnpatchSelf(); _patch?.UnpatchSelf();
_patch = null; _patch = null;
} }
public static T CreateWindow<T>(string name, string title = "") where T : MyWindow public static T CreateWindow<T>(string name, string title = "") where T : MyWindow
{ {
var srcWin = UIRoot.instance.uiGame.tankWindow; var srcWin = UIRoot.instance.uiGame.tankWindow;
@@ -438,16 +535,17 @@ public static class MyWindowManager
} }
} }
win.SetTitle(title); win.SetTitle(title);
win._Create(); win._Create();
if (_initialized) if (_initialized)
{ {
win._Init(win.data); win._Init(win.data);
} }
Windows.Add(win); Windows.Add(win);
return (T)win; return (T)win;
} }
public static void DestroyWindow(ManualBehaviour win) public static void DestroyWindow(ManualBehaviour win)
{ {
if (win == null) return; if (win == null) return;
@@ -467,7 +565,6 @@ public static class MyWindowManager
public static class Patch public static class Patch
{ {
/* /*
//_Create -> _Init //_Create -> _Init
[HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnCreate")] [HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnCreate")]
@@ -484,6 +581,7 @@ public static class MyWindowManager
win._Free(); win._Free();
win._Destroy(); win._Destroy();
} }
Windows.Clear(); Windows.Clear();
} }
@@ -495,6 +593,7 @@ public static class MyWindowManager
{ {
win._Init(win.data); win._Init(win.data);
} }
_initialized = true; _initialized = true;
} }
@@ -516,6 +615,7 @@ public static class MyWindowManager
{ {
return; return;
} }
foreach (var win in Windows) foreach (var win in Windows)
{ {
win._Update(); win._Update();

View File

@@ -67,6 +67,7 @@ public static class UIConfigWindow
I18N.Add("Click to dismantle selected layer", "Click to dismantle selected layer", "点击拆除对应的戴森壳"); I18N.Add("Click to dismantle selected layer", "Click to dismantle selected layer", "点击拆除对应的戴森壳");
I18N.Add("Dismantle selected layer", "Dismantle selected layer", "拆除选中的戴森壳"); I18N.Add("Dismantle selected layer", "Dismantle selected layer", "拆除选中的戴森壳");
I18N.Add("Dismantle selected layer Confirm", "This operation will dismantle selected layer, are you sure?", "此操作将会拆除选中的戴森壳,确定吗?"); I18N.Add("Dismantle selected layer Confirm", "This operation will dismantle selected layer, are you sure?", "此操作将会拆除选中的戴森壳,确定吗?");
I18N.Add("Auto Fast Build Speed Multiplier", "Auto Fast Build Speed Multiplier", "自动快速建造速度倍率");
I18N.Add("Restore upgrades of \"Sorter Cargo Stacking\" on panel", "Restore upgrades of \"Sorter Cargo Stacking\" on panel", "在升级面板上恢复\"分拣器货物叠加\"的升级"); I18N.Add("Restore upgrades of \"Sorter Cargo Stacking\" on panel", "Restore upgrades of \"Sorter Cargo Stacking\" on panel", "在升级面板上恢复\"分拣器货物叠加\"的升级");
I18N.Add("Buy out techs with their prerequisites", "Buy out techs with their prerequisites", "购买科技也同时购买所有前置科技"); I18N.Add("Buy out techs with their prerequisites", "Buy out techs with their prerequisites", "购买科技也同时购买所有前置科技");
I18N.Add("Set \"Sorter Cargo Stacking\" to unresearched state", "Set \"Sorter Cargo Stacking\" to unresearched state", "将\"分拣器货物叠加\"设为未研究状态"); I18N.Add("Set \"Sorter Cargo Stacking\" to unresearched state", "Set \"Sorter Cargo Stacking\" to unresearched state", "将\"分拣器货物叠加\"设为未研究状态");
@@ -76,6 +77,24 @@ public static class UIConfigWindow
MyConfigWindow.OnUpdateUI += UpdateUI; MyConfigWindow.OnUpdateUI += UpdateUI;
} }
private class OcMapper : MyWindow.ValueMapper<int>
{
public override int Min => 0;
public override int Max => 40;
public override string FormatValue(string format, int value)
{
return value == 0 ? "max".Translate() : base.FormatValue(format, value);
}
}
private class DistanceMapper : MyWindow.ValueMapper<double>
{
public override int Min => 1;
public override int Max => 40;
public override double IndexToValue(int index) => index * 0.5;
public override int ValueToIndex(double value) => Mathf.RoundToInt((float)(value * 2.0));
}
private static void CreateUI(MyConfigWindow wnd, RectTransform trans) private static void CreateUI(MyConfigWindow wnd, RectTransform trans)
{ {
_windowTrans = trans; _windowTrans = trans;
@@ -151,19 +170,7 @@ public static class UIConfigWindow
y += 30f; y += 30f;
wnd.AddText2(x, y, tab2, "Maximum count to build", 15, "text-oc-build-count"); wnd.AddText2(x, y, tab2, "Maximum count to build", 15, "text-oc-build-count");
y += 24f; y += 24f;
var ocBuildSlider = wnd.AddSlider(x, y, tab2, PlanetFunctions.OrbitalCollectorMaxBuildCount.Value, 0f, 40f, "G", 200f); wnd.AddSlider(x, y, tab2, PlanetFunctions.OrbitalCollectorMaxBuildCount, new OcMapper(), "G", 200f);
if (PlanetFunctions.OrbitalCollectorMaxBuildCount.Value == 0)
{
ocBuildSlider.SetLabelText("max".Translate());
}
ocBuildSlider.OnValueChanged += () =>
{
PlanetFunctions.OrbitalCollectorMaxBuildCount.Value = Mathf.RoundToInt(ocBuildSlider.Value);
if (PlanetFunctions.OrbitalCollectorMaxBuildCount.Value == 0)
{
ocBuildSlider.SetLabelText("max".Translate());
}
};
x = 400f; x = 400f;
y += 54f; y += 54f;
wnd.AddCheckBox(x, y, tab2, LogisticsPatch.LogisticsCapacityTweaksEnabled, "Enhance control for logistic storage limits"); wnd.AddCheckBox(x, y, tab2, LogisticsPatch.LogisticsCapacityTweaksEnabled, "Enhance control for logistic storage limits");
@@ -201,16 +208,8 @@ public static class UIConfigWindow
y += 32f; y += 32f;
wnd.AddText2(x, y, tab3, "Distance to use warp", 15, "text-distance-to-warp"); wnd.AddText2(x, y, tab3, "Distance to use warp", 15, "text-distance-to-warp");
y += 24f; y += 24f;
var distanceToWarp = wnd.AddSlider(x, y, tab3, (float)Math.Round(PlayerPatch.DistanceToWarp.Value * 2.0), 1f, 40f, "0.0", 200f);
if (PlanetFunctions.OrbitalCollectorMaxBuildCount.Value == 0) wnd.AddSlider(x, y, tab3, PlayerPatch.DistanceToWarp, new DistanceMapper(), "0.0", 200f);
{
distanceToWarp.SetLabelText(PlayerPatch.DistanceToWarp.Value.ToString("0.0"));
}
distanceToWarp.OnValueChanged += () =>
{
PlayerPatch.DistanceToWarp.Value = Math.Round(distanceToWarp.Value) * 0.5;
distanceToWarp.SetLabelText(PlayerPatch.DistanceToWarp.Value.ToString("0.0"));
};
var tab4 = wnd.AddTab(trans, "Dyson Sphere"); var tab4 = wnd.AddTab(trans, "Dyson Sphere");
x = 0f; x = 0f;
@@ -250,6 +249,12 @@ public static class UIConfigWindow
x += 40f; x += 40f;
} }
} }
x = 400f;
y += 36f;
wnd.AddText2(x, y, tab4, "Auto Fast Build Speed Multiplier", 15, "text-auto-fast-build-multiplier");
y += 24f;
wnd.AddSlider(x, y, tab4, DysonSpherePatch.AutoConstructMultiplier, [1, 2, 5, 10, 20, 50, 100], "0", 200f);
_dysonTab = tab4; _dysonTab = tab4;
var tab5 = wnd.AddTab(_windowTrans, "Tech/Combat"); var tab5 = wnd.AddTab(_windowTrans, "Tech/Combat");

View File

@@ -129,7 +129,7 @@ public class UXAssist : BaseUnityPlugin, IModCanSave
"Stop ejectors when available nodes are all filled up"); "Stop ejectors when available nodes are all filled up");
DysonSpherePatch.OnlyConstructNodesEnabled = Config.Bind("DysonSphere", "OnlyConstructNodes", false, DysonSpherePatch.OnlyConstructNodesEnabled = Config.Bind("DysonSphere", "OnlyConstructNodes", false,
"Construct only nodes but frames"); "Construct only nodes but frames");
DysonSpherePatch.AutoConstructMultiplier = Config.Bind("DysonSphere", "AutoConstructMultiplier", 10, "Dyson Sphere auto-construct speed multiplier"); DysonSpherePatch.AutoConstructMultiplier = Config.Bind("DysonSphere", "AutoConstructMultiplier", 1, "Dyson Sphere auto-construct speed multiplier");
I18N.Init(); I18N.Init();
I18N.Add("UXAssist Config", "UXAssist Config", "UX助手设置"); I18N.Add("UXAssist Config", "UXAssist Config", "UX助手设置");