From 054b8e14b8d46d9031e0b15b3e4138b47ee2ebfb Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Sun, 25 Aug 2024 14:41:17 +0800 Subject: [PATCH] More works --- CheatEnabler/DysonSpherePatch.cs | 5 +- CheatEnabler/FactoryPatch.cs | 8 +- CheatEnabler/package/manifest.json | 2 +- UXAssist/CHANGELOG.md | 4 + UXAssist/Common/GameLogic.cs | 44 +++ UXAssist/DysonSpherePatch.cs | 8 +- UXAssist/FactoryPatch.cs | 20 +- UXAssist/GamePatch.cs | 55 +++- UXAssist/TechPatch.cs | 4 +- UXAssist/UXAssist.cs | 365 ++++++++++++------------ UniverseGenTweaks/BirthPlanetPatch.cs | 4 +- UniverseGenTweaks/package/manifest.json | 2 +- 12 files changed, 310 insertions(+), 211 deletions(-) create mode 100644 UXAssist/Common/GameLogic.cs diff --git a/CheatEnabler/DysonSpherePatch.cs b/CheatEnabler/DysonSpherePatch.cs index 09b2d9c..8dbc8c2 100644 --- a/CheatEnabler/DysonSpherePatch.cs +++ b/CheatEnabler/DysonSpherePatch.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; +using UXAssist.Common; namespace CheatEnabler; @@ -113,9 +114,11 @@ public static class DysonSpherePatch UpdateSailLifeTime(); UpdateSailsCacheForThisGame(); _patch ??= Harmony.CreateAndPatchAll(typeof(SkipBulletPatch)); + GameLogic.OnGameEnd += GameMain_Begin_Postfix; } else { + GameLogic.OnGameEnd -= GameMain_Begin_Postfix; _patch?.UnpatchSelf(); _patch = null; } @@ -151,8 +154,6 @@ public static class DysonSpherePatch _sailsCacheCapacity[index] = capacity; } - [HarmonyPostfix] - [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] private static void GameMain_Begin_Postfix() { UpdateSailsCacheForThisGame(); diff --git a/CheatEnabler/FactoryPatch.cs b/CheatEnabler/FactoryPatch.cs index c09eec4..7266041 100644 --- a/CheatEnabler/FactoryPatch.cs +++ b/CheatEnabler/FactoryPatch.cs @@ -85,10 +85,12 @@ public static class FactoryPatch GreaterPowerUsageInLogistics.Enable(GreaterPowerUsageInLogisticsEnabled.Value); ControlPanelRemoteLogistics.Enable(ControlPanelRemoteLogisticsEnabled.Value); _factoryPatch = Harmony.CreateAndPatchAll(typeof(FactoryPatch)); + GameLogic.OnGameBegin += GameMain_Begin_Postfix_For_ImmBuild; } public static void Uninit() { + GameLogic.OnGameBegin -= GameMain_Begin_Postfix_For_ImmBuild; _factoryPatch?.UnpatchSelf(); _factoryPatch = null; ImmediateBuild.Enable(false); @@ -173,8 +175,6 @@ public static class FactoryPatch } } - [HarmonyPostfix] - [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] private static void GameMain_Begin_Postfix_For_ImmBuild() { var factory = GameMain.mainPlayer?.factory; @@ -492,8 +492,10 @@ public static class FactoryPatch { InitSignalBelts(); _beltSignalPatch ??= Harmony.CreateAndPatchAll(typeof(BeltSignalGenerator)); + GameLogic.OnGameBegin += GameMain_Begin_Postfix; return; } + GameLogic.OnGameBegin -= GameMain_Begin_Postfix; _beltSignalPatch?.UnpatchSelf(); _beltSignalPatch = null; _initialized = false; @@ -726,8 +728,6 @@ public static class FactoryPatch set.Remove(v); } - [HarmonyPostfix] - [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] private static void GameMain_Begin_Postfix() { if (BeltSignalGeneratorEnabled.Value) InitSignalBelts(); diff --git a/CheatEnabler/package/manifest.json b/CheatEnabler/package/manifest.json index b631f26..2ae2b19 100644 --- a/CheatEnabler/package/manifest.json +++ b/CheatEnabler/package/manifest.json @@ -5,6 +5,6 @@ "description": "Add various cheat functions while disabling abnormal determinants / 添加一些作弊功能,同时屏蔽异常检测", "dependencies": [ "xiaoye97-BepInEx-5.4.17", - "soarqin-UXAssist-1.0.24" + "soarqin-UXAssist-1.1.5" ] } diff --git a/UXAssist/CHANGELOG.md b/UXAssist/CHANGELOG.md index 76ae162..5b8cfe0 100644 --- a/UXAssist/CHANGELOG.md +++ b/UXAssist/CHANGELOG.md @@ -1,6 +1,8 @@ ## Changlog * 1.1.5 + `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. + Fix a crash when config panel is opened before game is fully loaded * 1.1.4 + Fix `Remove some build conditions` @@ -145,6 +147,8 @@ ## 更新日志 * 1.1.5 + `快速建造和拆除堆叠研究站`:现在也支持储物仓和储液罐 + + `允许调整游戏窗口大小`:在应用游戏选项时保持窗口可调整大小 + + `记住上次退出时的窗口位置和大小`:如果分辨率相关的配置项未改变,则在应用游戏选项时不调整窗口大小 + 修复了在游戏完全加载前打开配置面板可能导致的崩溃问题 * 1.1.4 + 修复了`移除部分不影响游戏逻辑的建造条件` diff --git a/UXAssist/Common/GameLogic.cs b/UXAssist/Common/GameLogic.cs new file mode 100644 index 0000000..50248ba --- /dev/null +++ b/UXAssist/Common/GameLogic.cs @@ -0,0 +1,44 @@ +using System; +using HarmonyLib; + +namespace UXAssist.Common; + +public static class GameLogic +{ + private static Harmony _harmony; + public static Action OnDataLoaded; + public static Action OnGameBegin; + public static Action OnGameEnd; + + public static void Init() + { + _harmony = Harmony.CreateAndPatchAll(typeof(GameLogic)); + } + + public static void Uninit() + { + _harmony?.UnpatchSelf(); + _harmony = null; + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(VFPreload), nameof(VFPreload.InvokeOnLoadWorkEnded))] + public static void VFPreload_InvokeOnLoadWorkEnded_Postfix() + { + OnDataLoaded?.Invoke(); + } + + [HarmonyPostfix, HarmonyPriority(Priority.First)] + [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] + public static void GameMain_Begin_Postfix() + { + OnGameBegin?.Invoke(); + } + + [HarmonyPostfix, HarmonyPriority(Priority.Last)] + [HarmonyPatch(typeof(GameMain), nameof(GameMain.End))] + public static void GameMain_End_Postfix() + { + OnGameEnd?.Invoke(); + } +} diff --git a/UXAssist/DysonSpherePatch.cs b/UXAssist/DysonSpherePatch.cs index bf479e6..e78de22 100644 --- a/UXAssist/DysonSpherePatch.cs +++ b/UXAssist/DysonSpherePatch.cs @@ -98,9 +98,13 @@ public static class DysonSpherePatch { InitNodeForAbsorb(); _patch ??= Harmony.CreateAndPatchAll(typeof(StopEjectOnNodeComplete)); + GameLogic.OnGameBegin += GameMain_Begin_Postfix; + GameLogic.OnGameEnd += GameMain_End_Postfix; } else { + GameLogic.OnGameEnd -= GameMain_End_Postfix; + GameLogic.OnGameBegin -= GameMain_Begin_Postfix; _patch?.UnpatchSelf(); _patch = null; _initialized = false; @@ -173,15 +177,11 @@ public static class DysonSpherePatch return comp != null && comp.Count > 0; } - [HarmonyPostfix] - [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] private static void GameMain_Begin_Postfix() { InitNodeForAbsorb(); } - [HarmonyPostfix] - [HarmonyPatch(typeof(GameMain), nameof(GameMain.End))] private static void GameMain_End_Postfix() { _initialized = false; diff --git a/UXAssist/FactoryPatch.cs b/UXAssist/FactoryPatch.cs index fa9978b..4d64ccd 100644 --- a/UXAssist/FactoryPatch.cs +++ b/UXAssist/FactoryPatch.cs @@ -1648,11 +1648,15 @@ public static class FactoryPatch if (enable) { _patch ??= Harmony.CreateAndPatchAll(typeof(DragBuildPowerPoles)); + GameLogic.OnGameBegin += GameMain_Begin_Postfix; + GameLogic.OnGameEnd += GameMain_End_Postfix; FixProto(); return; } UnfixProto(); + GameLogic.OnGameEnd -= GameMain_End_Postfix; + GameLogic.OnGameBegin -= GameMain_Begin_Postfix; _patch?.UnpatchSelf(); _patch = null; } @@ -1699,15 +1703,11 @@ public static class FactoryPatch OldDragBuildDist.Clear(); } - [HarmonyPostfix, HarmonyPriority(Priority.Last)] - [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] private static void GameMain_Begin_Postfix() { FixProto(); } - [HarmonyPostfix, HarmonyPriority(Priority.Last)] - [HarmonyPatch(typeof(GameMain), nameof(GameMain.End))] private static void GameMain_End_Postfix() { UnfixProto(); @@ -1891,10 +1891,14 @@ public static class FactoryPatch { AddBeltSignalProtos(); _persistPatch = Harmony.CreateAndPatchAll(typeof(Persist)); + GameLogic.OnDataLoaded += Persist.VFPreload_InvokeOnLoadWorkEnded_Postfix; + GameLogic.OnGameBegin += Persist.GameMain_Begin_Postfix; } public static void UninitPersist() { + GameLogic.OnGameBegin -= Persist.GameMain_Begin_Postfix; + GameLogic.OnDataLoaded -= Persist.VFPreload_InvokeOnLoadWorkEnded_Postfix; _persistPatch?.UnpatchSelf(); _persistPatch = null; } @@ -2083,9 +2087,7 @@ public static class FactoryPatch private static class Persist { - [HarmonyPostfix, HarmonyPriority(Priority.Last)] - [HarmonyPatch(typeof(VFPreload), nameof(VFPreload.InvokeOnLoadWorkEnded))] - private static void VFPreload_InvokeOnLoadWorkEnded_Postfix() + public static void VFPreload_InvokeOnLoadWorkEnded_Postfix() { if (BeltSignalsForBuyOut._initialized) return; BeltSignalsForBuyOut._initialized = true; @@ -2103,9 +2105,7 @@ public static class FactoryPatch RemovePlanetSignalBelts(factory.index); } - [HarmonyPostfix] - [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] - private static void GameMain_Begin_Postfix() + public static void GameMain_Begin_Postfix() { _clusterSeedKey = GameMain.data.GetClusterSeedKey(); InitSignalBelts(); diff --git a/UXAssist/GamePatch.cs b/UXAssist/GamePatch.cs index f31fc54..076d7a5 100644 --- a/UXAssist/GamePatch.cs +++ b/UXAssist/GamePatch.cs @@ -76,11 +76,33 @@ public static class GamePatch private static class EnableWindowResize { + private static bool _enabled; + private static Harmony _patch; public static void Enable(bool on) { var wnd = WinApi.FindWindow(GameWindowClass, _gameWindowTitle); if (wnd == IntPtr.Zero) return; + _enabled = on; if (on) + { + WinApi.SetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE, + WinApi.GetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE) | (int)WindowStyles.WS_THICKFRAME | (int)WindowStyles.WS_MAXIMIZEBOX); + _patch ??= Harmony.CreateAndPatchAll(typeof(EnableWindowResize)); + return; + } + _patch?.UnpatchSelf(); + _patch = null; + WinApi.SetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE, + WinApi.GetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE) & ~((int)WindowStyles.WS_THICKFRAME | (int)WindowStyles.WS_MAXIMIZEBOX)); + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(UIOptionWindow), nameof(UIOptionWindow.ApplyOptions))] + private static void UIOptionWindow_ApplyOptions_Postfix() + { + var wnd = WinApi.FindWindow(GameWindowClass, _gameWindowTitle); + if (wnd == IntPtr.Zero) return; + if (_enabled) WinApi.SetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE, WinApi.GetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE) | (int)WindowStyles.WS_THICKFRAME | (int)WindowStyles.WS_MAXIMIZEBOX); else @@ -98,6 +120,7 @@ public static class GamePatch if (on) { _patch ??= Harmony.CreateAndPatchAll(typeof(LoadLastWindowRect)); + GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix; if (Screen.fullScreenMode is not (FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow)) { var rect = LastWindowRect.Value; @@ -146,6 +169,7 @@ public static class GamePatch MoveWindowPosition(); return; } + GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix; _patch?.UnpatchSelf(); _patch = null; } @@ -182,8 +206,6 @@ public static class GamePatch MoveWindowPosition(); } - [HarmonyPostfix] - [HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")] private static void VFPreload_InvokeOnLoadWorkEnded_Postfix() { if (_loaded || Screen.fullScreenMode is FullScreenMode.ExclusiveFullScreen or FullScreenMode.FullScreenWindow or FullScreenMode.MaximizedWindow) return; @@ -202,6 +224,35 @@ public static class GamePatch WinApi.SetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE, WinApi.GetWindowLong(wnd, (int)WindowLongFlags.GWL_STYLE) | (int)WindowStyles.WS_THICKFRAME | (int)WindowStyles.WS_MAXIMIZEBOX); } + + private static GameOption _gameOption; + [HarmonyPostfix] + [HarmonyPatch(typeof(UIOptionWindow), nameof(UIOptionWindow._OnOpen))] + private static void UIOptionWindow__OnOpen_Postfix() + { + _gameOption = DSPGame.globalOption; + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(GameOption), nameof(GameOption.Apply))] + private static IEnumerable UIOptionWindow_ApplyOptions_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + var label1 = generator.DefineLabel(); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(Screen), nameof(Screen.SetResolution), [typeof(int), typeof(int), typeof(bool), typeof(int)])) + ).Advance(1).Labels.Add(label1); + matcher.Start().Insert( + Transpilers.EmitDelegate(() => + _gameOption.fullscreen == DSPGame.globalOption.fullscreen && + _gameOption.resolution.width == DSPGame.globalOption.resolution.width && + _gameOption.resolution.height == DSPGame.globalOption.resolution.height && + _gameOption.resolution.refreshRate == DSPGame.globalOption.resolution.refreshRate + ), + new CodeInstruction(OpCodes.Brtrue, label1) + ); + return matcher.InstructionEnumeration(); + } } /* diff --git a/UXAssist/TechPatch.cs b/UXAssist/TechPatch.cs index e0d0dae..db2cb69 100644 --- a/UXAssist/TechPatch.cs +++ b/UXAssist/TechPatch.cs @@ -40,8 +40,10 @@ public static class TechPatch if (on) { _patch ??= Harmony.CreateAndPatchAll(typeof(SorterCargoStacking)); + GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix; return; } + GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix; _patch?.UnpatchSelf(); _patch = null; } @@ -106,8 +108,6 @@ public static class TechPatch } } - [HarmonyPostfix, HarmonyPriority(Priority.Last)] - [HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")] private static void VFPreload_InvokeOnLoadWorkEnded_Postfix() { TryPatchProto(true); diff --git a/UXAssist/UXAssist.cs b/UXAssist/UXAssist.cs index f654930..3a304ce 100644 --- a/UXAssist/UXAssist.cs +++ b/UXAssist/UXAssist.cs @@ -27,6 +27,7 @@ public class UXAssist : BaseUnityPlugin, IModCanSave private static bool _configWinInitialized; private static MyConfigWindow _configWin; private static Harmony _patch; + private static Harmony _persistPatch; private static bool _initialized; private static PressKeyBind _toggleKey; @@ -134,6 +135,8 @@ public class UXAssist : BaseUnityPlugin, IModCanSave // UI Patch _patch ??= Harmony.CreateAndPatchAll(typeof(UXAssist)); + _persistPatch ??= Harmony.CreateAndPatchAll(typeof(Persist)); + GameLogic.Init(); MyWindowManager.Init(); UIConfigWindow.Init(); @@ -158,8 +161,11 @@ public class UXAssist : BaseUnityPlugin, IModCanSave GamePatch.Uninit(); MyWindowManager.Uninit(); + GameLogic.Uninit(); _patch?.UnpatchSelf(); _patch = null; + _persistPatch?.UnpatchSelf(); + _persistPatch = null; } private void Update() @@ -270,195 +276,186 @@ public class UXAssist : BaseUnityPlugin, IModCanSave _initialized = true; } - // Check for noModifier while pressing hotkeys on build bar - [HarmonyTranspiler] - [HarmonyPatch(typeof(UIBuildMenu), nameof(UIBuildMenu._OnUpdate))] - private static IEnumerable UIBuildMenu__OnUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) + private static class Persist { - var matcher = new CodeMatcher(instructions, generator); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.inScreen))) - ); - matcher.Repeat(codeMatcher => + // Check for noModifier while pressing hotkeys on build bar + [HarmonyTranspiler] + [HarmonyPatch(typeof(UIBuildMenu), nameof(UIBuildMenu._OnUpdate))] + private static IEnumerable UIBuildMenu__OnUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) { - var jumpPos = codeMatcher.Advance(1).Operand; - codeMatcher.Advance(-1).InsertAndAdvance( - new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.noModifier))), - new CodeInstruction(OpCodes.Brfalse_S, jumpPos) - ).Advance(2); - }); - return matcher.InstructionEnumeration(); - } + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.inScreen))) + ); + matcher.Repeat(codeMatcher => + { + var jumpPos = codeMatcher.Advance(1).Operand; + codeMatcher.Advance(-1).InsertAndAdvance( + new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.noModifier))), + new CodeInstruction(OpCodes.Brfalse_S, jumpPos) + ).Advance(2); + }); + return matcher.InstructionEnumeration(); + } - // Patch to fix the issue that warning popup on VeinUtil upgraded to level 8000+ - [HarmonyTranspiler] - [HarmonyPatch(typeof(ABN_VeinsUtil), nameof(ABN_VeinsUtil.CheckValue))] - private static IEnumerable ABN_VeinsUtil_CheckValue_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldelem_R8), - new CodeMatch(OpCodes.Conv_R4), - new CodeMatch(OpCodes.Add), - new CodeMatch(OpCodes.Stloc_1) - ); - // loc1 = Mathf.Round(n * 1000f) / 1000f; - matcher.Advance(3).Insert( - new CodeInstruction(OpCodes.Ldc_R4, 1000f), - new CodeInstruction(OpCodes.Mul), - new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Mathf), nameof(Mathf.Round))), - new CodeInstruction(OpCodes.Ldc_R4, 1000f), - new CodeInstruction(OpCodes.Div) - ); - return matcher.InstructionEnumeration(); - } - - // Bring popup tip window to top layer - [HarmonyTranspiler] - [HarmonyPatch(typeof(UIButton), nameof(UIButton.LateUpdate))] - private static IEnumerable UIButton_LateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldloc_2), - new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Component), nameof(Component.gameObject))), - new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(GameObject), nameof(GameObject.activeSelf))) - ); - var labels = matcher.Labels; - matcher.Labels = null; - matcher.Insert( - new CodeInstruction(OpCodes.Ldloc_2).WithLabels(labels), - new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Component), nameof(Component.transform))), - new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.parent))), - new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.parent))), - new CodeInstruction(OpCodes.Callvirt, AccessTools.Method(typeof(Transform), nameof(Transform.SetAsLastSibling))) - ); - return matcher.InstructionEnumeration(); - } - - // Sort blueprint structures by item id, model index, recipe id, area index, and position before saving - [HarmonyPostfix] - [HarmonyPatch(typeof(BlueprintUtils), nameof(BlueprintUtils.GenerateBlueprintData))] - private static void BlueprintUtils_GenerateBlueprintData_Postfix(BlueprintData _blueprintData) - { - var buildings = _blueprintData.buildings; - Array.Sort(buildings, (a, b) => + // Patch to fix the issue that warning popup on VeinUtil upgraded to level 8000+ + [HarmonyTranspiler] + [HarmonyPatch(typeof(ABN_VeinsUtil), nameof(ABN_VeinsUtil.CheckValue))] + private static IEnumerable ABN_VeinsUtil_CheckValue_Transpiler(IEnumerable instructions, ILGenerator generator) { - var tmpItemId = a.itemId - b.itemId; - if(tmpItemId != 0) - return tmpItemId; - var tmpModelIndex = a.modelIndex - b.modelIndex; - if(tmpModelIndex != 0) - return tmpModelIndex; - var tmpRecipeId = a.recipeId - b.recipeId; - if(tmpRecipeId != 0) - return tmpRecipeId; - var tmpAreaIndex = a.areaIndex - b.areaIndex; - if(tmpAreaIndex != 0) - return tmpAreaIndex; - const double ky = 256.0; - const double kx = 1024.0; - var scorePosA = (a.localOffset_y * ky + a.localOffset_x) * kx + a.localOffset_z; - var scorePosB = (b.localOffset_y * ky + b.localOffset_x) * kx + b.localOffset_z; - return scorePosA < scorePosB ? 1 : -1; - }); - for (var i = buildings.Length - 1; i >= 0; i--) + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldelem_R8), + new CodeMatch(OpCodes.Conv_R4), + new CodeMatch(OpCodes.Add), + new CodeMatch(OpCodes.Stloc_1) + ); + // loc1 = Mathf.Round(n * 1000f) / 1000f; + matcher.Advance(3).Insert( + new CodeInstruction(OpCodes.Ldc_R4, 1000f), + new CodeInstruction(OpCodes.Mul), + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(Mathf), nameof(Mathf.Round))), + new CodeInstruction(OpCodes.Ldc_R4, 1000f), + new CodeInstruction(OpCodes.Div) + ); + return matcher.InstructionEnumeration(); + } + + // Bring popup tip window to top layer + [HarmonyTranspiler] + [HarmonyPatch(typeof(UIButton), nameof(UIButton.LateUpdate))] + private static IEnumerable UIButton_LateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) { - buildings[i].index = i; + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldloc_2), + new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Component), nameof(Component.gameObject))), + new CodeMatch(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(GameObject), nameof(GameObject.activeSelf))) + ); + var labels = matcher.Labels; + matcher.Labels = null; + matcher.Insert( + new CodeInstruction(OpCodes.Ldloc_2).WithLabels(labels), + new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Component), nameof(Component.transform))), + new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.parent))), + new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Transform), nameof(Transform.parent))), + new CodeInstruction(OpCodes.Callvirt, AccessTools.Method(typeof(Transform), nameof(Transform.SetAsLastSibling))) + ); + return matcher.InstructionEnumeration(); + } + + // Sort blueprint structures by item id, model index, recipe id, area index, and position before saving + [HarmonyPostfix] + [HarmonyPatch(typeof(BlueprintUtils), nameof(BlueprintUtils.GenerateBlueprintData))] + private static void BlueprintUtils_GenerateBlueprintData_Postfix(BlueprintData _blueprintData) + { + var buildings = _blueprintData.buildings; + Array.Sort(buildings, (a, b) => + { + var tmpItemId = a.itemId - b.itemId; + if (tmpItemId != 0) + return tmpItemId; + var tmpModelIndex = a.modelIndex - b.modelIndex; + if (tmpModelIndex != 0) + return tmpModelIndex; + var tmpRecipeId = a.recipeId - b.recipeId; + if (tmpRecipeId != 0) + return tmpRecipeId; + var tmpAreaIndex = a.areaIndex - b.areaIndex; + if (tmpAreaIndex != 0) + return tmpAreaIndex; + const double ky = 256.0; + const double kx = 1024.0; + var scorePosA = (a.localOffset_y * ky + a.localOffset_x) * kx + a.localOffset_z; + var scorePosB = (b.localOffset_y * ky + b.localOffset_x) * kx + b.localOffset_z; + return scorePosA < scorePosB ? 1 : -1; + }); + for (var i = buildings.Length - 1; i >= 0; i--) + { + buildings[i].index = i; + } + } + + // Increase maximum value of property realizing, 2000 -> 20000 + [HarmonyTranspiler] + [HarmonyPatch(typeof(UIPropertyEntry), nameof(UIPropertyEntry.UpdateUIElements))] + [HarmonyPatch(typeof(UIPropertyEntry), nameof(UIPropertyEntry.OnRealizeButtonClick))] + [HarmonyPatch(typeof(UIPropertyEntry), nameof(UIPropertyEntry.OnInputValueEnd))] + private static IEnumerable UIProductEntry_UpdateUIElements_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldc_I4, 2000) + ); + matcher.Repeat(m => { m.SetAndAdvance(OpCodes.Ldc_I4, 20000); }); + return matcher.InstructionEnumeration(); + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(UIPropertyEntry), nameof(UIPropertyEntry.OnInputValueEnd))] + private static IEnumerable UIProductEntry_OnInputValueEnd_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(ci => ci.opcode == OpCodes.Ldc_R4 && ci.OperandIs(2000f)) + ); + matcher.Repeat(m => { m.SetAndAdvance(OpCodes.Ldc_R4, 20000f); }); + return matcher.InstructionEnumeration(); + } + + // Increase capacity of player order queue, 16 -> 128 + [HarmonyTranspiler] + [HarmonyPatch(typeof(PlayerOrder), MethodType.Constructor, typeof(Player))] + private static IEnumerable PlayerOrder_Constructor_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(ci => (ci.opcode == OpCodes.Ldc_I4_S || ci.opcode == OpCodes.Ldc_I4) && ci.OperandIs(16)) + ); + matcher.Repeat(m => { m.SetAndAdvance(OpCodes.Ldc_I4, 128); }); + return matcher.InstructionEnumeration(); + } + + // Increase Player Command Queue from 16 to 128 + [HarmonyTranspiler] + [HarmonyPatch(typeof(PlayerOrder), nameof(PlayerOrder._trimEnd))] + [HarmonyPatch(typeof(PlayerOrder), nameof(PlayerOrder.Enqueue))] + private static IEnumerable PlayerOrder_ExtendCount_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(ci => (ci.opcode == OpCodes.Ldc_I4_S || ci.opcode == OpCodes.Ldc_I4) && ci.OperandIs(16)) + ); + matcher.Repeat(m => { m.SetAndAdvance(OpCodes.Ldc_I4, 128); }); + return matcher.InstructionEnumeration(); + } + + // Allow F11 in star map + [HarmonyTranspiler] + [HarmonyPatch(typeof(UIGame), nameof(UIGame._OnLateUpdate))] + private static IEnumerable UIGame__OnLateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.MatchForward(false, + new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.inFullscreenGUI))), + new CodeMatch(ci => ci.opcode == OpCodes.Brfalse || ci.opcode == OpCodes.Brfalse_S) + ); + var jumpPos = matcher.Advance(1).Operand; + matcher.Advance(-1).Insert( + new CodeInstruction(OpCodes.Ldarg_0), + new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(UIGame), nameof(UIGame.starmap))), + new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(ManualBehaviour), nameof(ManualBehaviour.active))), + new CodeInstruction(OpCodes.Brtrue_S, jumpPos) + ); + return matcher.InstructionEnumeration(); + } + + // Ignore UIDFCommunicatorWindow.Determine() + [HarmonyPrefix] + [HarmonyPatch(typeof(UIDFCommunicatorWindow), nameof(UIDFCommunicatorWindow.Determine))] + private static bool UIDFCommunicatorWindow_Determine_Prefix() + { + return false; } } - - // Increase maximum value of property realizing, 2000 -> 20000 - [HarmonyTranspiler] - [HarmonyPatch(typeof(UIPropertyEntry), nameof(UIPropertyEntry.UpdateUIElements))] - [HarmonyPatch(typeof(UIPropertyEntry), nameof(UIPropertyEntry.OnRealizeButtonClick))] - [HarmonyPatch(typeof(UIPropertyEntry), nameof(UIPropertyEntry.OnInputValueEnd))] - private static IEnumerable UIProductEntry_UpdateUIElements_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldc_I4, 2000) - ); - matcher.Repeat(m => - { - m.SetAndAdvance(OpCodes.Ldc_I4, 20000); - }); - return matcher.InstructionEnumeration(); - } - - [HarmonyTranspiler] - [HarmonyPatch(typeof(UIPropertyEntry), nameof(UIPropertyEntry.OnInputValueEnd))] - private static IEnumerable UIProductEntry_OnInputValueEnd_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - matcher.MatchForward(false, - new CodeMatch(ci => ci.opcode == OpCodes.Ldc_R4 && ci.OperandIs(2000f)) - ); - matcher.Repeat(m => - { - m.SetAndAdvance(OpCodes.Ldc_R4, 20000f); - }); - return matcher.InstructionEnumeration(); - } - - // Increase capacity of player order queue, 16 -> 128 - [HarmonyTranspiler] - [HarmonyPatch(typeof(PlayerOrder), MethodType.Constructor, typeof(Player))] - private static IEnumerable PlayerOrder_Constructor_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - matcher.MatchForward(false, - new CodeMatch(ci => (ci.opcode == OpCodes.Ldc_I4_S || ci.opcode == OpCodes.Ldc_I4) && ci.OperandIs(16)) - ); - matcher.Repeat(m => - { - m.SetAndAdvance(OpCodes.Ldc_I4, 128); - }); - return matcher.InstructionEnumeration(); - } - - // Increase Player Command Queue from 16 to 128 - [HarmonyTranspiler] - [HarmonyPatch(typeof(PlayerOrder), nameof(PlayerOrder._trimEnd))] - [HarmonyPatch(typeof(PlayerOrder), nameof(PlayerOrder.Enqueue))] - private static IEnumerable PlayerOrder_ExtendCount_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - matcher.MatchForward(false, - new CodeMatch(ci => (ci.opcode == OpCodes.Ldc_I4_S || ci.opcode == OpCodes.Ldc_I4) && ci.OperandIs(16)) - ); - matcher.Repeat(m => - { - m.SetAndAdvance(OpCodes.Ldc_I4, 128); - }); - return matcher.InstructionEnumeration(); - } - - // Allow F11 in star map - [HarmonyTranspiler] - [HarmonyPatch(typeof(UIGame), nameof(UIGame._OnLateUpdate))] - private static IEnumerable UIGame__OnLateUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) - { - var matcher = new CodeMatcher(instructions, generator); - matcher.MatchForward(false, - new CodeMatch(OpCodes.Ldsfld, AccessTools.Field(typeof(VFInput), nameof(VFInput.inFullscreenGUI))), - new CodeMatch(ci => ci.opcode == OpCodes.Brfalse || ci.opcode == OpCodes.Brfalse_S) - ); - var jumpPos = matcher.Advance(1).Operand; - matcher.Advance(-1).Insert( - new CodeInstruction(OpCodes.Ldarg_0), - new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(UIGame), nameof(UIGame.starmap))), - new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(ManualBehaviour), nameof(ManualBehaviour.active))), - new CodeInstruction(OpCodes.Brtrue_S, jumpPos) - ); - return matcher.InstructionEnumeration(); - } - - // Ignore UIDFCommunicatorWindow.Determine() - [HarmonyPrefix] - [HarmonyPatch(typeof(UIDFCommunicatorWindow), nameof(UIDFCommunicatorWindow.Determine))] - private static bool UIDFCommunicatorWindow_Determine_Prefix() - { - return false; - } } diff --git a/UniverseGenTweaks/BirthPlanetPatch.cs b/UniverseGenTweaks/BirthPlanetPatch.cs index a9973fc..b102ec8 100644 --- a/UniverseGenTweaks/BirthPlanetPatch.cs +++ b/UniverseGenTweaks/BirthPlanetPatch.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using BepInEx.Configuration; using HarmonyLib; +using UXAssist.Common; namespace UniverseGenTweaks; public static class BirthPlanetPatch @@ -73,15 +74,16 @@ public static class BirthPlanetPatch HighLuminosityBirthStar.SettingChanged += (_, _) => PatchBirthThemeData(); PatchBirthThemeData(); _patch ??= Harmony.CreateAndPatchAll(typeof(BirthPlanetPatch)); + GameLogic.OnDataLoaded += VFPreload_InvokeOnLoadWorkEnded_Postfix; } public static void Uninit() { + GameLogic.OnDataLoaded -= VFPreload_InvokeOnLoadWorkEnded_Postfix; _patch?.UnpatchSelf(); _patch = null; } - [HarmonyPostfix, HarmonyPatch(typeof(VFPreload), "InvokeOnLoadWorkEnded")] private static void VFPreload_InvokeOnLoadWorkEnded_Postfix() { PatchBirthThemeData(); diff --git a/UniverseGenTweaks/package/manifest.json b/UniverseGenTweaks/package/manifest.json index ea061e6..46ecea3 100644 --- a/UniverseGenTweaks/package/manifest.json +++ b/UniverseGenTweaks/package/manifest.json @@ -6,6 +6,6 @@ "dependencies": [ "xiaoye97-BepInEx-5.4.17", "CommonAPI-DSPModSave-1.2.0", - "soarqin-UXAssist-1.0.25" + "soarqin-UXAssist-1.1.5" ] }