diff --git a/CheatEnabler/CHANGELOG.md b/CheatEnabler/CHANGELOG.md
index 138a541..012fece 100644
--- a/CheatEnabler/CHANGELOG.md
+++ b/CheatEnabler/CHANGELOG.md
@@ -1,5 +1,10 @@
## Changlog
+* 2.3.24
+ + `Complete Dyson Sphere Shells instantly`: Fix a bug that may cause negative power in some cases
+* 2.3.23
+ + New feature: `Complete Dyson Sphere Shells instantly`
+ + Fix a crash when config panel is opened before game is fully loaded
* 2.3.22
+ Fix `Pump Anywhere`
* 2.3.21
@@ -122,6 +127,11 @@
## 更新日志
+* 2.3.24
+ + `立即完成戴森壳建造`:修复了在某些情况下可能导致发电为负的问题
+* 2.3.23
+ + 新功能:`立即完成戴森壳建造`
+ + 修复了在游戏完全加载前打开配置面板可能导致的崩溃问题
* 2.3.22
+ 修复了`平地抽水`
* 2.3.21
diff --git a/CheatEnabler/CheatEnabler.cs b/CheatEnabler/CheatEnabler.cs
index 25c33f2..8061dd3 100644
--- a/CheatEnabler/CheatEnabler.cs
+++ b/CheatEnabler/CheatEnabler.cs
@@ -86,6 +86,7 @@ public class CheatEnabler : BaseUnityPlugin
PlayerFunctions.Init();
PlayerPatch.Init();
DysonSpherePatch.Init();
+ DysonSphereFunctions.Init();
CombatPatch.Init();
}
diff --git a/CheatEnabler/CheatEnabler.csproj b/CheatEnabler/CheatEnabler.csproj
index 976d27f..0f500e7 100644
--- a/CheatEnabler/CheatEnabler.csproj
+++ b/CheatEnabler/CheatEnabler.csproj
@@ -5,7 +5,7 @@
net472
org.soardev.cheatenabler
DSP MOD - CheatEnabler
- 2.3.22
+ 2.3.24
true
latest
CheatEnabler
diff --git a/CheatEnabler/DysonSphereFunctions.cs b/CheatEnabler/DysonSphereFunctions.cs
new file mode 100644
index 0000000..ec7b4f9
--- /dev/null
+++ b/CheatEnabler/DysonSphereFunctions.cs
@@ -0,0 +1,121 @@
+using HarmonyLib;
+using UXAssist.Common;
+
+namespace CheatEnabler;
+
+public static class DysonSphereFunctions
+{
+ public static void Init()
+ {
+ I18N.Add("You are not in any system.", "You are not in any system.", "你不在任何星系中");
+ I18N.Add("There is no Dyson Sphere shell on \"{0}\".", "There is no Dyson Sphere shell on \"{0}\".", "“{0}”上没有可建造的戴森壳");
+ I18N.Add("This will complete all Dyson Sphere shells on \"{0}\" instantly. Are you sure?", "This will complete all Dyson Sphere shells on \"{0}\" instantly. Are you sure?", "这将立即完成“{0}”上的所有戴森壳。你确定吗?");
+ }
+
+ public static void CompleteShellsInstantly()
+ {
+ StarData star = null;
+ var dysonEditor = UIRoot.instance?.uiGame?.dysonEditor;
+ if (dysonEditor != null && dysonEditor.gameObject.activeSelf)
+ {
+ star = dysonEditor.selection.viewStar;
+ }
+ if (star == null)
+ {
+ star = GameMain.data?.localStar;
+ if (star == null)
+ {
+ UIMessageBox.Show("CheatEnabler".Translate(), "You are not in any system.".Translate(), "确定".Translate(), 3, null);
+ return;
+ }
+ }
+ var dysonSphere = GameMain.data?.dysonSpheres[star.index];
+ if (dysonSphere == null || dysonSphere.layerCount == 0)
+ {
+ UIMessageBox.Show("CheatEnabler".Translate(), string.Format("There is no Dyson Sphere shell on \"{0}\".".Translate(), star.displayName), "确定".Translate(), 3, null);
+ return;
+ }
+
+ UIMessageBox.Show("CheatEnabler".Translate(), string.Format("This will complete all Dyson Sphere shells on \"{0}\" instantly. Are you sure?".Translate(), star.displayName), "取消".Translate(), "确定".Translate(), 2, null, () =>
+ {
+ var totalNodeSpInfo = AccessTools.Field(typeof(DysonSphereLayer), "totalNodeSP");
+ var totalFrameSpInfo = AccessTools.Field(typeof(DysonSphereLayer), "totalFrameSP");
+ var totalCpInfo = AccessTools.Field(typeof(DysonSphereLayer), "totalCP");
+
+ var rocketCount = 0;
+ var solarSailCount = 0;
+ foreach (var dysonSphereLayer in dysonSphere.layersIdBased)
+ {
+ if (dysonSphereLayer == null) continue;
+ long totalNodeSp = 0;
+ long totalFrameSp = 0;
+ long totalCp = 0;
+ for (var i = dysonSphereLayer.frameCursor - 1; i >= 0; i--)
+ {
+ var dysonFrame = dysonSphereLayer.framePool[i];
+ if (dysonFrame == null || dysonFrame.id != i) continue;
+ totalFrameSp += dysonFrame.spMax;
+ var spMax = dysonFrame.spMax / 2;
+ if (dysonFrame.spA < spMax)
+ {
+ rocketCount += spMax - dysonFrame.spA;
+ dysonFrame.spA = spMax;
+ dysonSphere.UpdateProgress(dysonFrame);
+ }
+ if (dysonFrame.spB < spMax)
+ {
+ rocketCount += spMax - dysonFrame.spB;
+ dysonFrame.spB = spMax;
+ dysonSphere.UpdateProgress(dysonFrame);
+ }
+ }
+ for (var i = dysonSphereLayer.nodeCursor - 1; i >= 0; i--)
+ {
+ var dysonNode = dysonSphereLayer.nodePool[i];
+ if (dysonNode == null || dysonNode.id != i) continue;
+ dysonNode.spOrdered = 0;
+ dysonNode._spReq = 0;
+ totalNodeSp += dysonNode.spMax;
+ var diff = dysonNode.spMax - dysonNode.sp;
+ if (diff > 0)
+ {
+ rocketCount += diff;
+ dysonNode.sp = dysonNode.spMax;
+ dysonSphere.UpdateProgress(dysonNode);
+ }
+ dysonNode._cpReq = 0;
+ dysonNode.cpOrdered = 0;
+ foreach (var shell in dysonNode.shells)
+ {
+ var nodeIndex = shell.nodeIndexMap[dysonNode.id];
+ var cpMax = (shell.vertsqOffset[nodeIndex + 1] - shell.vertsqOffset[nodeIndex]) * shell.cpPerVertex;
+ totalCp += cpMax;
+ diff = cpMax - shell.nodecps[nodeIndex];
+ shell.nodecps[nodeIndex] = cpMax;
+ shell.nodecps[shell.nodecps.Length - 1] += diff;
+ solarSailCount += diff;
+ if (totalCpInfo != null)
+ {
+ shell.SetMaterialDynamicVars();
+ }
+ }
+ }
+
+ totalNodeSpInfo?.SetValue(dysonSphereLayer, totalNodeSp);
+ totalFrameSpInfo?.SetValue(dysonSphereLayer, totalFrameSp);
+ totalCpInfo?.SetValue(dysonSphereLayer, totalCp);
+ }
+ dysonSphere.CheckAutoNodes();
+
+ var productRegister = dysonSphere.productRegister;
+ if (productRegister != null)
+ {
+ lock (productRegister)
+ {
+ if (rocketCount > 0) productRegister[11902] += rocketCount;
+ if (solarSailCount > 0) productRegister[11903] += solarSailCount;
+ }
+ }
+ });
+ }
+}
diff --git a/CheatEnabler/README.md b/CheatEnabler/README.md
index 7be57e8..ec32512 100644
--- a/CheatEnabler/README.md
+++ b/CheatEnabler/README.md
@@ -43,6 +43,7 @@
+ Skip absorption period
+ Quick absorb
+ Eject anyway
+ + Complete Dyson Sphere Shells instantly
+ Mecha/Combat:
+ Mecha and Drones/Fleets invicible
+ Buildings invicible
@@ -100,6 +101,7 @@
+ 跳过吸收阶段
+ 快速吸收
+ 全球弹射
+ + 立即完成戴森壳建造
+ 战斗:
+ 机甲和战斗无人机无敌
+ 建筑无敌
diff --git a/CheatEnabler/UIConfigWindow.cs b/CheatEnabler/UIConfigWindow.cs
index 1832221..3d36b89 100644
--- a/CheatEnabler/UIConfigWindow.cs
+++ b/CheatEnabler/UIConfigWindow.cs
@@ -61,6 +61,7 @@ public static class UIConfigWindow
I18N.Add("Eject anyway", "Eject anyway", "全球弹射");
I18N.Add("Overclock Ejectors", "Overclock Ejectors (10x)", "高速弹射器(10倍射速)");
I18N.Add("Overclock Silos", "Overclock Silos (10x)", "高速发射井(10倍射速)");
+ I18N.Add("Complete Dyson Sphere shells instantly", "Complete Dyson Sphere shells instantly", "立即完成戴森壳建造");
I18N.Add("Terraform without enough soil piles", "Terraform without enough soil piles", "沙土不够时依然可以整改地形");
I18N.Add("Instant teleport (like that in Sandbox mode)", "Instant teleport (like that in Sandbox mode)", "快速传送(和沙盒模式一样)");
I18N.Add("Mecha and Drones/Fleets invicible", "Mecha and Drones/Fleets invicible", "机甲和战斗无人机无敌");
@@ -204,6 +205,9 @@ public static class UIConfigWindow
wnd.AddCheckBox(x, y, tab4, DysonSpherePatch.OverclockEjectorEnabled, "Overclock Ejectors");
y += 36f;
wnd.AddCheckBox(x, y, tab4, DysonSpherePatch.OverclockSiloEnabled, "Overclock Silos");
+ x = 300f;
+ y = 10f;
+ wnd.AddButton(x, y, 300f, tab4, "Complete Dyson Sphere shells instantly", 16, "button-complete-dyson-sphere-shells-instantly", DysonSphereFunctions.CompleteShellsInstantly);
var tab5 = wnd.AddTab(_windowTrans, "Mecha/Combat");
x = 0f;
diff --git a/CheatEnabler/package/manifest.json b/CheatEnabler/package/manifest.json
index 2ae2b19..657eee7 100644
--- a/CheatEnabler/package/manifest.json
+++ b/CheatEnabler/package/manifest.json
@@ -1,6 +1,6 @@
{
"name": "CheatEnabler",
- "version_number": "2.3.22",
+ "version_number": "2.3.24",
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/CheatEnabler",
"description": "Add various cheat functions while disabling abnormal determinants / 添加一些作弊功能,同时屏蔽异常检测",
"dependencies": [
diff --git a/UXAssist/CHANGELOG.md b/UXAssist/CHANGELOG.md
index 1f2fa00..282adb1 100644
--- a/UXAssist/CHANGELOG.md
+++ b/UXAssist/CHANGELOG.md
@@ -6,11 +6,13 @@
- 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
+ + New feature: `Mod manager profile based save folder`
+ - Save files are stored in `Save\` folder.
+ - Will use original save location if matching default profile name.
+ `Quick build and dismantle stacking labs`: works for storages and tanks now
+ `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.
+ Auto resize panel to fit content, for better support of multilanguages and mods dependent on UX Assist config panel functions.
- + Fix a crash when config panel is opened before game is fully loaded
* 1.1.4
+ Fix `Remove some build conditions`
* 1.1.3
@@ -157,12 +159,14 @@
- 打开面板时自动将鼠标指向物品设为筛选条件
- 在控制面板物流塔列表中右键点击物品图标快速设置为筛选条件
+ 新功能:`戴森球自动快速建造速度倍率`
- - 注意:这仅适用于沙盒模式下的`戴森球自动快速建造`功能
+ - 注意:这仅适用于沙盒模式下的`戴森球自动快速建造`功能
+ + 新功能:`基于mod管理器配置档案名的存档文件夹`
+ - 存档文件会存储在`Save\`文件夹中
+ - 如果匹配默认配置档案名则使用原始存档位置
+ `快速建造和拆除堆叠研究站`:现在也支持储物仓和储液罐
+ `允许调整游戏窗口大小`:在应用游戏选项时保持窗口可调整大小
+ `记住上次退出时的窗口位置和大小`:如果分辨率相关的配置项未改变,则在应用游戏选项时不调整窗口大小
+ 自动调整面板大小适应内容,以更好地支持多语言和依赖于UX助手配置面板功能的mod
- + 修复了在游戏完全加载前打开配置面板可能导致的崩溃问题
* 1.1.4
+ 修复了`移除部分不影响游戏逻辑的建造条件`
* 1.1.3
diff --git a/UXAssist/DysonSpherePatch.cs b/UXAssist/DysonSpherePatch.cs
index 2658b88..898cd84 100644
--- a/UXAssist/DysonSpherePatch.cs
+++ b/UXAssist/DysonSpherePatch.cs
@@ -28,7 +28,7 @@ public static class DysonSpherePatch
_totalFrameSpInfo = AccessTools.Field(typeof(DysonSphereLayer), "totalFrameSP");
_totalCpInfo = AccessTools.Field(typeof(DysonSphereLayer), "totalCP");
}
-
+
public static void Uninit()
{
StopEjectOnNodeComplete.Enable(false);
@@ -62,6 +62,7 @@ public static class DysonSpherePatch
if (pool[id].nodeLayerId != index) continue;
ds.RemoveDysonRocket(id);
}
+
ds.RemoveLayer(index);
}
@@ -69,10 +70,9 @@ public static class DysonSpherePatch
[HarmonyPatch(typeof(DysonSwarm), nameof(DysonSwarm.AutoConstruct))]
private static bool DysonSwarm_AutoConstruct_Prefix(DysonSwarm __instance)
{
- return false;
+ return __instance.dysonSphere.autoNodeCount == 0;
}
-
[HarmonyPrefix]
[HarmonyPatch(typeof(DysonSphere), nameof(DysonSphere.AutoConstruct))]
private static bool DysonSphere_AutoConstruct_Prefix(DysonSphere __instance)
@@ -85,160 +85,160 @@ public static class DysonSpherePatch
{
var dysonNode = dysonSphereLayer.nodePool[j];
if (dysonNode == null || dysonNode.id != j) continue;
- lock (dysonNode)
+ var count = dysonNode._spReq - dysonNode.spOrdered;
+ int todoCount;
+ int[] productRegister;
+ if (count > 0)
{
- var count = dysonNode._spReq - dysonNode.spOrdered;
- int todoCount;
- int[] productRegister;
- if (count > 0)
+ if (count > totalCount)
{
-
- if (count > totalCount)
- {
- count = totalCount;
- }
-
- todoCount = count;
- if (dysonNode.sp < dysonNode.spMax)
- {
- int diff;
- if (dysonNode.sp + count > dysonNode.spMax)
- {
- diff = dysonNode.spMax - dysonNode.sp;
- count -= diff;
- dysonNode._spReq -= diff;
-
- dysonNode.sp = dysonNode.spMax;
- }
- else
- {
- diff = count;
- dysonNode._spReq -= diff;
-
- dysonNode.sp += diff;
- count = 0;
- }
- // Make compatible with DSPOptimizations
- if (_totalNodeSpInfo != null)
- _totalNodeSpInfo.SetValue(dysonSphereLayer, (long)_totalNodeSpInfo.GetValue(dysonSphereLayer) + diff - 1);
- __instance.UpdateProgress(dysonNode);
- }
-
- 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;
- }
- }
+ count = totalCount;
+ }
+
+ todoCount = count;
+ if (dysonNode.sp < dysonNode.spMax)
+ {
+ int diff;
+ if (dysonNode.sp + count > dysonNode.spMax)
+ {
+ diff = dysonNode.spMax - dysonNode.sp;
+ count -= diff;
+ dysonNode._spReq -= diff;
+
+ dysonNode.sp = dysonNode.spMax;
+ }
+ else
+ {
+ diff = count;
+ dysonNode._spReq -= diff;
+
+ dysonNode.sp += diff;
+ count = 0;
+ }
+
+ // Make compatible with DSPOptimizations
+ if (_totalNodeSpInfo != null)
+ _totalNodeSpInfo.SetValue(dysonSphereLayer, (long)_totalNodeSpInfo.GetValue(dysonSphereLayer) + diff - 1);
+ __instance.UpdateProgress(dysonNode);
}
- count = dysonNode._cpReq - dysonNode.cpOrdered;
if (count > 0)
{
- 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--)
+ var frameCount = dysonNode.frames.Count;
+ var frameIndex = dysonNode.frameTurn % frameCount;
+ for (var i = frameCount; i > 0 && count > 0; i--)
{
- var dysonShell = dysonNode.shells[shellIndex];
- lock (dysonShell)
+ var dysonFrame = dysonNode.frames[frameIndex];
+ var spMax = dysonFrame.spMax >> 1;
+ if (dysonFrame.nodeA == dysonNode && dysonFrame.spA < spMax)
{
- 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)
+ int diff;
+ if (dysonFrame.spA + count > spMax)
{
- _totalCpInfo.SetValue(dysonSphereLayer, (long)_totalCpInfo.GetValue(dysonSphereLayer) + diff);
- dysonShell.SetMaterialDynamicVars();
- }
- }
- shellIndex = (shellIndex + 1) % shellCount;
- }
- dysonNode.shellTurn = shellIndex;
+ diff = spMax - dysonFrame.spA;
+ count -= diff;
+ dysonNode._spReq -= diff;
- productRegister = __instance.productRegister;
- if (productRegister != null)
- {
- lock (productRegister)
- {
- productRegister[11903] += todoCount - count;
+ 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;
+ }
+ }
+ }
+
+ count = dysonNode._cpReq - dysonNode.cpOrdered;
+ if (count > 0)
+ {
+ 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--)
+ {
+ 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._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;
+
+ productRegister = __instance.productRegister;
+ if (productRegister != null)
+ {
+ lock (productRegister)
+ {
+ productRegister[11903] += todoCount - count;
}
}
}
@@ -329,6 +329,7 @@ public static class DysonSpherePatch
}
}
}
+
_initialized = true;
}
@@ -464,7 +465,7 @@ public static class DysonSpherePatch
);
return matcher.InstructionEnumeration();
}
-
+
[HarmonyTranspiler]
[HarmonyPatch(typeof(UIEjectorWindow), nameof(UIEjectorWindow._OnUpdate))]
static IEnumerable UIEjectorWindow__OnUpdate_Transpiler(IEnumerable instructions, ILGenerator generator)
@@ -498,7 +499,7 @@ public static class DysonSpherePatch
private static class OnlyConstructNodes
{
private static Harmony _patch;
-
+
public static void Enable(bool on)
{
if (on)
@@ -543,4 +544,4 @@ public static class DysonSpherePatch
return matcher.InstructionEnumeration();
}
}
-}
+}
\ No newline at end of file
diff --git a/UXAssist/GamePatch.cs b/UXAssist/GamePatch.cs
index 076d7a5..5000da3 100644
--- a/UXAssist/GamePatch.cs
+++ b/UXAssist/GamePatch.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Reflection.Emit;
using BepInEx.Configuration;
using HarmonyLib;
@@ -13,11 +14,15 @@ public static class GamePatch
private const string GameWindowClass = "UnityWndClass";
private static string _gameWindowTitle = "Dyson Sphere Program";
+ public static string ProfileName { get; private set; }
+
public static ConfigEntry EnableWindowResizeEnabled;
public static ConfigEntry LoadLastWindowRectEnabled;
// public static ConfigEntry AutoSaveOptEnabled;
public static ConfigEntry ConvertSavesFromPeaceEnabled;
public static ConfigEntry LastWindowRect;
+ public static ConfigEntry ProfileBasedSaveFolderEnabled;
+ public static ConfigEntry DefaultProfileName;
private static Harmony _gamePatch;
public static void Init()
@@ -39,6 +44,7 @@ public static class GamePatch
arg = arg.Substring(index + profileSuffix.Length);
var wnd = WinApi.FindWindow(GameWindowClass, _gameWindowTitle);
if (wnd == IntPtr.Zero) return;
+ ProfileName = arg;
_gameWindowTitle = $"Dyson Sphere Program - {arg}";
WinApi.SetWindowText(wnd, _gameWindowTitle);
break;
@@ -48,6 +54,14 @@ public static class GamePatch
LoadLastWindowRectEnabled.SettingChanged += (_, _) => LoadLastWindowRect.Enable(LoadLastWindowRectEnabled.Value);
// AutoSaveOptEnabled.SettingChanged += (_, _) => AutoSaveOpt.Enable(AutoSaveOptEnabled.Value);
ConvertSavesFromPeaceEnabled.SettingChanged += (_, _) => ConvertSavesFromPeace.Enable(ConvertSavesFromPeaceEnabled.Value);
+ ProfileBasedSaveFolderEnabled.SettingChanged += (_, _) =>
+ {
+ RefreshSavePath();
+ };
+ DefaultProfileName.SettingChanged += (_, _) =>
+ {
+ RefreshSavePath();
+ };
EnableWindowResize.Enable(EnableWindowResizeEnabled.Value);
LoadLastWindowRect.Enable(LoadLastWindowRectEnabled.Value);
// AutoSaveOpt.Enable(AutoSaveOptEnabled.Value);
@@ -65,6 +79,32 @@ public static class GamePatch
_gamePatch = null;
}
+ private static void RefreshSavePath()
+ {
+ if (ProfileName == null) return;
+
+ if (UIRoot.instance.loadGameWindow.gameObject.activeSelf)
+ {
+ UIRoot.instance.loadGameWindow._Close();
+ }
+ if (UIRoot.instance.saveGameWindow.gameObject.activeSelf)
+ {
+ UIRoot.instance.saveGameWindow._Close();
+ }
+
+ string gameSavePath;
+ if (ProfileBasedSaveFolderEnabled.Value && string.Compare(DefaultProfileName.Value, ProfileName, StringComparison.OrdinalIgnoreCase) != 0)
+ gameSavePath = $"{GameConfig.overrideDocumentFolder}{GameConfig.gameName}/Save/{ProfileName}/";
+ else
+ gameSavePath = $"{GameConfig.overrideDocumentFolder}{GameConfig.gameName}/Save/";
+ if (string.Compare(GameConfig.gameSavePath, gameSavePath, StringComparison.OrdinalIgnoreCase) == 0) return;
+ GameConfig.gameSavePath = gameSavePath;
+ if (!Directory.Exists(GameConfig.gameSavePath))
+ {
+ Directory.CreateDirectory(GameConfig.gameSavePath);
+ }
+ }
+
[HarmonyPrefix, HarmonyPatch(typeof(GameMain), nameof(GameMain.HandleApplicationQuit))]
private static void GameMain_HandleApplicationQuit_Prefix()
{
@@ -180,7 +220,7 @@ public static class GamePatch
var wnd = WinApi.FindWindow(GameWindowClass, _gameWindowTitle);
if (wnd == IntPtr.Zero) return;
var rect = LastWindowRect.Value;
- if (rect.z == 0f && rect.w == 0f) return;
+ if (rect is { z: 0f, w: 0f }) return;
var x = Mathf.RoundToInt(rect.x);
var y = Mathf.RoundToInt(rect.y);
WinApi.SetWindowPos(wnd, IntPtr.Zero, x, y, 0, 0, 0x0235);
@@ -192,7 +232,7 @@ public static class GamePatch
{
if (fullscreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow || GameMain.isRunning) return;
var rect = LastWindowRect.Value;
- if (rect.z == 0f && rect.w == 0f) return;
+ if (rect is { z: 0f, w: 0f }) return;
var w = Mathf.RoundToInt(rect.z);
var h = Mathf.RoundToInt(rect.w);
width = w;
@@ -213,7 +253,7 @@ public static class GamePatch
var wnd = WinApi.FindWindow(GameWindowClass, _gameWindowTitle);
if (wnd == IntPtr.Zero) return;
var rect = LastWindowRect.Value;
- if (rect.z == 0f && rect.w == 0f) return;
+ if (rect is { z: 0f, w: 0f }) return;
var x = Mathf.RoundToInt(rect.x);
var y = Mathf.RoundToInt(rect.y);
var w = Mathf.RoundToInt(rect.z);
diff --git a/UXAssist/README.md b/UXAssist/README.md
index 0850956..7f5fdc1 100644
--- a/UXAssist/README.md
+++ b/UXAssist/README.md
@@ -21,6 +21,11 @@
- Enable game window resize
- Remember window position and size on last exit
- Convert Peace-Mode saves to Combat-Mode on loading
+ - Mod manager profile based save folder
+ - Save files are stored in `Save\` folder.
+ - Will use original save location if matching default profile name.
+ - Increase maximum count of Metadata Instantiations to 20000 (from 2000)
+ - Increase capacity of player order queue to 128 (from 16)
+ Planet/Factory
- Sunlight at night
- Remove some build conditions
@@ -117,6 +122,9 @@
- 可调整游戏窗口大小(可最大化和拖动边框)
- 记住上次退出时的窗口位置和大小
- 在加载和平模式存档时将其转换为战斗模式
+ - 基于mod管理器配置档案名的存档文件夹
+ - 存档文件会存储在`Save\`文件夹中
+ - 如果匹配默认配置档案名则使用原始存档位置
- 将元数据提取的最大数量增加到20000(原来为2000)
- 将玩家指令队列的容量增加到128(原来为16)
+ 行星/工厂
diff --git a/UXAssist/UI/MyWindow.cs b/UXAssist/UI/MyWindow.cs
index b231a4e..2d7a410 100644
--- a/UXAssist/UI/MyWindow.cs
+++ b/UXAssist/UI/MyWindow.cs
@@ -14,9 +14,6 @@ namespace UXAssist.UI;
public class MyWindow : ManualBehaviour
{
- private readonly Dictionary, UnityAction>> _inputFields = new();
- private readonly Dictionary _buttons = new();
- protected bool EventRegistered { get; private set; }
private float _maxX;
protected float MaxY;
protected const float TitleHeight = 48f;
@@ -141,15 +138,10 @@ public class MyWindow : ManualBehaviour
}
t.fontSize = fontSize;
- btn.button.onClick.RemoveAllListeners();
btn.tip = null;
btn.tips = new UIButton.TipSettings();
- _buttons[btn] = onClick;
- if (EventRegistered)
- {
- if (onClick != null)
- btn.button.onClick.AddListener(onClick);
- }
+ btn.button.onClick.RemoveAllListeners();
+ if (onClick != null) btn.button.onClick.AddListener(onClick);
_maxX = Math.Max(_maxX, x + rect.sizeDelta.x);
MaxY = Math.Max(MaxY, y + rect.sizeDelta.y);
@@ -184,11 +176,7 @@ public class MyWindow : ManualBehaviour
}
btn.button.onClick.RemoveAllListeners();
- _buttons[btn] = onClick;
- if (EventRegistered && onClick != null)
- {
- btn.button.onClick.AddListener(onClick);
- }
+ if (onClick != null) btn.button.onClick.AddListener(onClick);
_maxX = Math.Max(_maxX, x + rect.sizeDelta.x);
MaxY = Math.Max(MaxY, y + rect.sizeDelta.y);
@@ -305,67 +293,39 @@ public class MyWindow : ManualBehaviour
inputField.GetComponent().color = new Color(1f, 1f, 1f, 0.05f);
var rect = Util.NormalizeRectWithTopLeft(inputField, x, y, parent);
rect.sizeDelta = new Vector2(210, rect.sizeDelta.y);
- inputField.textComponent.text = text;
+ inputField.text = text;
inputField.textComponent.fontSize = fontSize;
+
inputField.onValueChanged.RemoveAllListeners();
+ if (onChanged != null) inputField.onValueChanged.AddListener(onChanged);
inputField.onEndEdit.RemoveAllListeners();
- _inputFields[inputField] = Tuple.Create(onChanged, onEditEnd);
- if (EventRegistered)
- {
- if (onChanged != null)
- inputField.onValueChanged.AddListener(onChanged);
- if (onEditEnd != null)
- inputField.onEndEdit.AddListener(onEditEnd);
- }
+ if (onEditEnd != null) inputField.onEndEdit.AddListener(onEditEnd);
_maxX = Math.Max(_maxX, x + rect.sizeDelta.x);
MaxY = Math.Max(MaxY, y + rect.sizeDelta.y);
return inputField;
}
-
- public override void _OnRegEvent()
+
+ public InputField AddInputField(float x, float y, float width, RectTransform parent, ConfigEntry config, int fontSize = 16, string objName = "input")
{
- base._OnRegEvent();
- if (EventRegistered) return;
- foreach (var t in _inputFields)
- {
- var inputField = t.Key;
- if (t.Value.Item1 != null)
- inputField.onValueChanged.AddListener(t.Value.Item1);
- if (t.Value.Item2 != null)
- inputField.onEndEdit.AddListener(t.Value.Item2);
- }
+ var stationWindow = UIRoot.instance.uiGame.stationWindow;
+ //public InputField nameInput;
+ var inputField = Instantiate(stationWindow.nameInput);
+ inputField.gameObject.name = objName;
+ Destroy(inputField.GetComponent());
+ inputField.GetComponent().color = new Color(1f, 1f, 1f, 0.05f);
+ var rect = Util.NormalizeRectWithTopLeft(inputField, x, y, parent);
+ rect.sizeDelta = new Vector2(width, rect.sizeDelta.y);
+ inputField.text = config.Value;
+ inputField.textComponent.fontSize = fontSize;
- foreach (var t in _buttons)
- {
- var btn = t.Key;
- if (t.Value != null)
- btn.button.onClick.AddListener(t.Value);
- }
+ inputField.onValueChanged.RemoveAllListeners();
+ inputField.onEndEdit.RemoveAllListeners();
+ inputField.onEndEdit.AddListener(value => config.Value = value);
- EventRegistered = true;
- }
-
- public override void _OnUnregEvent()
- {
- base._OnUnregEvent();
- if (!EventRegistered) return;
- EventRegistered = false;
- foreach (var t in _buttons)
- {
- var btn = t.Key;
- if (t.Value != null)
- btn.button.onClick.RemoveListener(t.Value);
- }
-
- foreach (var t in _inputFields)
- {
- var inputField = t.Key;
- if (t.Value.Item1 != null)
- inputField.onValueChanged.RemoveListener(t.Value.Item1);
- if (t.Value.Item2 != null)
- inputField.onEndEdit.RemoveListener(t.Value.Item2);
- }
+ _maxX = Math.Max(_maxX, x + rect.sizeDelta.x);
+ MaxY = Math.Max(MaxY, y + rect.sizeDelta.y);
+ return inputField;
}
}
@@ -411,10 +371,7 @@ public class MyWindowWithTabs : MyWindow
btn.data = index;
_tabs.Add(Tuple.Create(tabRect, btn));
- if (EventRegistered)
- {
- btn.onClick += OnTabButtonClick;
- }
+ btn.onClick += OnTabButtonClick;
MaxY = Math.Max(MaxY, y + TabHeight);
return tabRect;
@@ -443,32 +400,6 @@ public class MyWindowWithTabs : MyWindow
_tabY += 28f;
}
- public override void _OnRegEvent()
- {
- if (!EventRegistered)
- {
- foreach (var t in _tabs)
- {
- t.Item2.onClick += OnTabButtonClick;
- }
- }
-
- base._OnRegEvent();
- }
-
- public override void _OnUnregEvent()
- {
- if (EventRegistered)
- {
- foreach (var t in _tabs)
- {
- t.Item2.onClick -= OnTabButtonClick;
- }
- }
-
- base._OnUnregEvent();
- }
-
protected void SetCurrentTab(int index) => OnTabButtonClick(index);
private void OnTabButtonClick(int index)
@@ -524,7 +455,7 @@ public static class MyWindowManager
{
var btn = child.GetComponentInChildren