mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2025-12-09 03:33:29 +08:00
UXAssist v1.0.9
This commit is contained in:
@@ -714,6 +714,7 @@ public static class FactoryPatch
|
||||
{
|
||||
_lastKey = KeyCode.None;
|
||||
}
|
||||
if (!VFInput.noModifier) return;
|
||||
int delta;
|
||||
if (UpdateKeyPressed(KeyCode.LeftArrow))
|
||||
{
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection.Emit;
|
||||
using BepInEx.Configuration;
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
using UXAssist.Common;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace UXAssist;
|
||||
|
||||
@@ -15,6 +18,7 @@ public static class GamePatch
|
||||
|
||||
public static ConfigEntry<bool> EnableWindowResizeEnabled;
|
||||
public static ConfigEntry<bool> LoadLastWindowRectEnabled;
|
||||
public static ConfigEntry<bool> AutoSaveOptEnabled;
|
||||
public static ConfigEntry<bool> ConvertSavesFromPeaceEnabled;
|
||||
public static ConfigEntry<Vector4> LastWindowRect;
|
||||
private static Harmony _gamePatch;
|
||||
@@ -23,9 +27,11 @@ public static class GamePatch
|
||||
{
|
||||
EnableWindowResizeEnabled.SettingChanged += (_, _) => EnableWindowResize.Enable(EnableWindowResizeEnabled.Value);
|
||||
LoadLastWindowRectEnabled.SettingChanged += (_, _) => LoadLastWindowRect.Enable(LoadLastWindowRectEnabled.Value);
|
||||
AutoSaveOptEnabled.SettingChanged += (_, _) => AutoSaveOpt.Enable(AutoSaveOptEnabled.Value);
|
||||
ConvertSavesFromPeaceEnabled.SettingChanged += (_, _) => ConvertSavesFromPeace.Enable(ConvertSavesFromPeaceEnabled.Value);
|
||||
EnableWindowResize.Enable(EnableWindowResizeEnabled.Value);
|
||||
LoadLastWindowRect.Enable(LoadLastWindowRectEnabled.Value);
|
||||
AutoSaveOpt.Enable(AutoSaveOptEnabled.Value);
|
||||
ConvertSavesFromPeace.Enable(ConvertSavesFromPeaceEnabled.Value);
|
||||
_gamePatch ??= Harmony.CreateAndPatchAll(typeof(GamePatch));
|
||||
}
|
||||
@@ -34,6 +40,7 @@ public static class GamePatch
|
||||
{
|
||||
LoadLastWindowRect.Enable(false);
|
||||
EnableWindowResize.Enable(false);
|
||||
AutoSaveOpt.Enable(false);
|
||||
ConvertSavesFromPeace.Enable(false);
|
||||
_gamePatch?.UnpatchSelf();
|
||||
_gamePatch = null;
|
||||
@@ -178,6 +185,148 @@ public static class GamePatch
|
||||
}
|
||||
}
|
||||
|
||||
private static class AutoSaveOpt
|
||||
{
|
||||
private static Harmony _patch;
|
||||
|
||||
public static void Enable(bool on)
|
||||
{
|
||||
if (on)
|
||||
{
|
||||
Directory.CreateDirectory(GameConfig.gameSaveFolder + "AutoSaves/");
|
||||
_patch ??= Harmony.CreateAndPatchAll(typeof(AutoSaveOpt));
|
||||
return;
|
||||
}
|
||||
|
||||
_patch?.UnpatchSelf();
|
||||
_patch = null;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(GameSave), nameof(GameSave.AutoSave))]
|
||||
private static bool GameSave_AutoSave_Prefix(ref bool __result)
|
||||
{
|
||||
if (!GameSave.SaveCurrentGame(GameSave.AutoSaveTmp))
|
||||
{
|
||||
GlobalObject.SaveOpCounter();
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
var tmpFilename = GameConfig.gameSaveFolder + GameSave.AutoSaveTmp + GameSave.saveExt;
|
||||
var targetFilename = $"{GameConfig.gameSaveFolder}AutoSaves/[{GameMain.data.gameDesc.clusterString}] {DateTime.Now:yyyy-MM-dd_hh-mm-ss}{GameSave.saveExt}";
|
||||
File.Move(tmpFilename, targetFilename);
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(UILoadGameWindow), nameof(UILoadGameWindow.RefreshList))]
|
||||
public static void UILoadGameWindow_RefreshList_Postfix(UILoadGameWindow __instance)
|
||||
{
|
||||
var baseDir = GameConfig.gameSaveFolder + "AutoSaves/";
|
||||
var files = Directory.GetFiles(baseDir, "*" + GameSave.saveExt, SearchOption.TopDirectoryOnly);
|
||||
var entries = __instance.entries;
|
||||
var entries2 = new List<UIGameSaveEntry>();
|
||||
var entryPrefab = __instance.entryPrefab;
|
||||
var entryPrefabParent = entryPrefab.transform.parent;
|
||||
foreach (var f in files)
|
||||
{
|
||||
var fileInfo = new FileInfo(f);
|
||||
var entry = Object.Instantiate(entryPrefab, entryPrefabParent);
|
||||
entry.fileInfo = fileInfo;
|
||||
entries2.Add(entry);
|
||||
}
|
||||
entries2.Sort((x, y) => -x.fileDate.CompareTo(y.fileDate));
|
||||
if (entries2.Count > 10)
|
||||
entries2.RemoveRange(10, entries2.Count - 10);
|
||||
var autoSaveText = ">> " + "自动存档条目".Translate();
|
||||
foreach (var entry in entries2)
|
||||
{
|
||||
entry.indexText.text = "";
|
||||
var saveName = entry.saveName;
|
||||
entry._saveName = $"AutoSaves/{saveName}";
|
||||
var quoteIndex = saveName.IndexOf('[');
|
||||
if (quoteIndex >= 0)
|
||||
{
|
||||
var quoteIndex2 = saveName.IndexOf(']', quoteIndex + 1);
|
||||
if (quoteIndex2 > 0) saveName = saveName.Substring(quoteIndex, quoteIndex2 + 1 - quoteIndex);
|
||||
}
|
||||
entry.nameText.text = $"{autoSaveText} {saveName}";
|
||||
entry.nameText.fontStyle = FontStyle.Italic;
|
||||
entry.nameText.color = new Color(1f, 1f, 1f, 0.7f);
|
||||
entry.timeText.text = $"{entry.fileDate:yyyy-MM-dd HH:mm:ss}";
|
||||
GameSave.ReadModes(entry.fileInfo.FullName, out var isSandbox, out var isPeace);
|
||||
if (entry.sandboxIcon != null)
|
||||
{
|
||||
entry.sandboxIcon.gameObject.SetActive(isSandbox);
|
||||
}
|
||||
if (entry.combatIcon != null)
|
||||
{
|
||||
entry.combatIcon.gameObject.SetActive(!isPeace);
|
||||
}
|
||||
entry.selected = false;
|
||||
entry.gameObject.SetActive(true);
|
||||
}
|
||||
entries.AddRange(entries2);
|
||||
entries.Sort((x, y) => -x.fileDate.CompareTo(y.fileDate));
|
||||
var displayIndex = 1;
|
||||
for (var i = 0; i < entries.Count; i++)
|
||||
{
|
||||
var entry = entries[i];
|
||||
entry.index = i + 1;
|
||||
entry.rectTrans.anchoredPosition = new Vector2(entry.rectTrans.anchoredPosition.x, -40 * i);
|
||||
if (string.IsNullOrEmpty(entry.indexText.text)) continue;
|
||||
entry.indexText.text = displayIndex.ToString();
|
||||
displayIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(UISaveGameWindow), nameof(UISaveGameWindow.RefreshList))]
|
||||
public static void UISaveGameWindow_RefreshList_Postfix(UISaveGameWindow __instance)
|
||||
{
|
||||
var entries = __instance.entries;
|
||||
entries.Sort((x, y) => -x.fileDate.CompareTo(y.fileDate));
|
||||
for (var i = 0; i < entries.Count; i++)
|
||||
{
|
||||
var entry = entries[i];
|
||||
entry.index = i + 1;
|
||||
entry.rectTrans.anchoredPosition = new Vector2(entry.rectTrans.anchoredPosition.x, -40 * i);
|
||||
entry.indexText.text = (i + 1).ToString();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(UILoadGameWindow), nameof(UILoadGameWindow.DoLoadSelectedGame))]
|
||||
[HarmonyPatch(typeof(UILoadGameWindow), nameof(UILoadGameWindow.OnSelectedChange))]
|
||||
private static IEnumerable<CodeInstruction> UILoadGameWindow_ReplaceSaveName_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.Start().MatchForward(false,
|
||||
new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(UIGameSaveEntry), nameof(UIGameSaveEntry.saveName)))
|
||||
);
|
||||
matcher.Repeat(m => m.SetAndAdvance(OpCodes.Ldfld, AccessTools.Field(typeof(UIGameSaveEntry), nameof(UIGameSaveEntry._saveName))));
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(GameSave), nameof(GameSave.LoadCurrentGame))]
|
||||
[HarmonyPatch(typeof(GameSave), nameof(GameSave.LoadGameDesc))]
|
||||
[HarmonyPatch(typeof(GameSave), nameof(GameSave.ReadHeader))]
|
||||
[HarmonyPatch(typeof(GameSave), nameof(GameSave.ReadHeaderAndDescAndProperty))]
|
||||
[HarmonyPatch(typeof(GameSave), nameof(GameSave.SaveExist))]
|
||||
[HarmonyPatch(typeof(GameSave), nameof(GameSave.SavePath))]
|
||||
private static IEnumerable<CodeInstruction> GameSave_RemoveValidateOnLoad_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
|
||||
{
|
||||
var matcher = new CodeMatcher(instructions, generator);
|
||||
matcher.Start().MatchForward(false,
|
||||
new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(CommonUtils), nameof(CommonUtils.ValidFileName)))
|
||||
);
|
||||
matcher.RemoveInstruction();
|
||||
return matcher.InstructionEnumeration();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConvertSavesFromPeace
|
||||
{
|
||||
private static Harmony _patch;
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
#### 一些提升用户体验的功能和补丁
|
||||
|
||||
## Changlog
|
||||
* 1.0.9
|
||||
+ New function: `Better auto-save mechanism`
|
||||
- Auto saves are stored in 'Save\AutoSaves' folder, filenames are combined with cluster address and date-time
|
||||
- Note: this will sort gamesaves by modified time on save/load window, so you don't have to use [DSP_Save_Game_Sorter] anymore
|
||||
* 1.0.8
|
||||
+ New function: `Enhanced control for logistic storage limits`
|
||||
* 1.0.7
|
||||
@@ -47,6 +51,9 @@
|
||||
+ General
|
||||
- Enable game window resize
|
||||
- Remember window position and size on last exit
|
||||
- Better auto-save mechanism
|
||||
- Auto saves are stored in 'Save\AutoSaves' folder, filenames are combined with cluster address and date-time
|
||||
- Note: this will sort gamesaves by modified time on save/load window, so you don't have to use [DSP_Save_Game_Sorter] anymore
|
||||
- Convert Peace-Mode saves to Combat-Mode on loading
|
||||
+ Planet/Factory
|
||||
- Unlimited interactive range
|
||||
@@ -81,6 +88,10 @@
|
||||
* [OffGridConstruction](https://github.com/Velociraptor115-DSPModding/OffGridConstruction): Off-grid building & stepped rotation implementations
|
||||
|
||||
## 更新日志
|
||||
* 1.0.9
|
||||
+ 新功能:`更好的自动保存机制`
|
||||
- 自动存档会以星区地址和日期时间组合为文件名存储在'Save\AutoSaves'文件夹中
|
||||
- 注意:此功能会在保存/读取菜单按最后修改时间对存档进行排序,因此你不再需要[DSP_Save_Game_Sorter]了
|
||||
* 1.0.8
|
||||
+ 新功能:`物流塔存储数量限制控制改进`
|
||||
* 1.0.7
|
||||
@@ -124,6 +135,9 @@
|
||||
+ 通用
|
||||
- 可调整游戏窗口大小(可最大化和拖动边框)
|
||||
- 记住上次退出时的窗口位置和大小
|
||||
- 更好的自动保存机制
|
||||
- 自动存档会以星区地址和日期时间组合为文件名存储在'Save\AutoSaves'文件夹中
|
||||
- 注意:此功能会在保存/读取菜单按最后修改时间对存档进行排序,因此你不再需要[DSP_Save_Game_Sorter]了
|
||||
- 在加载和平模式存档时将其转换为战斗模式
|
||||
+ 行星/工厂
|
||||
- 无限交互距离
|
||||
|
||||
@@ -18,6 +18,8 @@ public static class UIConfigWindow
|
||||
I18N.Add("Dyson Sphere", "Dyson Sphere", "戴森球");
|
||||
I18N.Add("Enable game window resize", "Enable game window resize (maximum box and thick frame)", "可调整游戏窗口大小(可最大化和拖动边框)");
|
||||
I18N.Add("Remeber window position and size on last exit", "Remeber window position and size on last exit", "记住上次退出时的窗口位置和大小");
|
||||
I18N.Add("Better auto-save mechanism", "Better auto-save mechanism", "更好的自动存档机制");
|
||||
I18N.Add("Better auto-save mechanism tips", "Auto saves are stored in 'Save\\AutoSaves' folder, filenames are combined with cluster address and date-time", "自动存档会以星区地址和日期时间组合为文件名存储在'Save\\AutoSaves'文件夹中");
|
||||
I18N.Add("Convert old saves to Combat Mode on loading", "Convert old saves to Combat Mode on loading (Use settings in new game panel)", "读取旧档时转为战斗模式(使用新游戏面板的战斗难度设置)");
|
||||
I18N.Add("Unlimited interactive range", "Unlimited interactive range", "无限交互距离");
|
||||
I18N.Add("Night Light", "Sunlight at night", "夜间日光灯");
|
||||
@@ -61,6 +63,12 @@ public static class UIConfigWindow
|
||||
y += 36f;
|
||||
MyCheckBox.CreateCheckBox(x, y, tab1, GamePatch.LoadLastWindowRectEnabled, "Remeber window position and size on last exit");
|
||||
y += 36f;
|
||||
MyCheckBox.CreateCheckBox(x, y, tab1, GamePatch.AutoSaveOptEnabled, "Better auto-save mechanism");
|
||||
x = 200f;
|
||||
y += 6f;
|
||||
MyWindow.AddTipsButton(x, y, tab1, "Better auto-save mechanism", "Better auto-save mechanism tips", "auto-save-opt-tips");
|
||||
x = 0f;
|
||||
y += 30f;
|
||||
MyCheckBox.CreateCheckBox(x, y, tab1, GamePatch.ConvertSavesFromPeaceEnabled, "Convert old saves to Combat Mode on loading");
|
||||
x += 10f;
|
||||
y = 278f;
|
||||
|
||||
@@ -32,6 +32,8 @@ public class UXAssist : BaseUnityPlugin
|
||||
"Load last window position and size when game starts");
|
||||
GamePatch.LastWindowRect = Config.Bind("Game", "LastWindowRect", new Vector4(0f, 0f, 0f, 0f),
|
||||
"Last window position and size");
|
||||
GamePatch.AutoSaveOptEnabled = Config.Bind("Game", "AutoSaveOpt", false,
|
||||
"Better auto-save mechanism");
|
||||
GamePatch.ConvertSavesFromPeaceEnabled = Config.Bind("Game", "ConvertSavesFromPeace", false,
|
||||
"Convert saves from Peace mode to Combat mode on save loading");
|
||||
FactoryPatch.UnlimitInteractiveEnabled = Config.Bind("Factory", "UnlimitInteractive", false,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<BepInExPluginGuid>org.soardev.uxassist</BepInExPluginGuid>
|
||||
<Description>DSP MOD - UXAssist</Description>
|
||||
<Version>1.0.8</Version>
|
||||
<Version>1.0.9</Version>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<PackageId>UXAssist</PackageId>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "UXAssist",
|
||||
"version_number": "1.0.8",
|
||||
"version_number": "1.0.9",
|
||||
"website_url": "https://github.com/soarqin/DSP_Mods/tree/master/UXAssist",
|
||||
"description": "Some functions and patches for better user experience / 一些提升用户体验的功能和补丁",
|
||||
"dependencies": [
|
||||
|
||||
Reference in New Issue
Block a user