From b3e216bc6aa68f72190911d038a58f284e0b2b66 Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Thu, 28 Sep 2023 03:21:46 +0800 Subject: [PATCH] Work in progress --- CheatEnabler/AbnormalDiabler.cs | 6 +- CheatEnabler/BirthPlanetPatch.cs | 5 +- CheatEnabler/CheatEnabler.cs | 9 +- CheatEnabler/DevShortcuts.cs | 5 +- CheatEnabler/DysonSpherePatch.cs | 166 ++++++++++++++++++++++++++++--- CheatEnabler/FactoryPatch.cs | 108 +++++--------------- CheatEnabler/PlanetFunctions.cs | 15 +-- CheatEnabler/ResourcePatch.cs | 92 +++++++---------- CheatEnabler/TechPatch.cs | 14 +-- CheatEnabler/TerraformPatch.cs | 14 +-- CheatEnabler/UIConfigWindow.cs | 4 +- CheatEnabler/WaterPumpPatch.cs | 14 +-- 12 files changed, 241 insertions(+), 211 deletions(-) diff --git a/CheatEnabler/AbnormalDiabler.cs b/CheatEnabler/AbnormalDiabler.cs index 1f38cb7..3553288 100644 --- a/CheatEnabler/AbnormalDiabler.cs +++ b/CheatEnabler/AbnormalDiabler.cs @@ -11,14 +11,12 @@ public static class AbnormalDisabler public static void Init() { - if (_patch != null) return; - _patch = Harmony.CreateAndPatchAll(typeof(AbnormalDisabler)); + _patch ??= Harmony.CreateAndPatchAll(typeof(AbnormalDisabler)); } public static void Uninit() { - if (_patch == null) return; - _patch.UnpatchSelf(); + _patch?.UnpatchSelf(); _patch = null; } diff --git a/CheatEnabler/BirthPlanetPatch.cs b/CheatEnabler/BirthPlanetPatch.cs index e7485ec..59604d1 100644 --- a/CheatEnabler/BirthPlanetPatch.cs +++ b/CheatEnabler/BirthPlanetPatch.cs @@ -72,13 +72,12 @@ public static class BirthPlanetPatch FlatBirthPlanet.SettingChanged += (_, _) => PatchBirthThemeData(); HighLuminosityBirthStar.SettingChanged += (_, _) => PatchBirthThemeData(); PatchBirthThemeData(); - _patch = Harmony.CreateAndPatchAll(typeof(BirthPlanetPatch)); + _patch ??= Harmony.CreateAndPatchAll(typeof(BirthPlanetPatch)); } public static void Uninit() { - if (_patch == null) return; - _patch.UnpatchSelf(); + _patch?.UnpatchSelf(); _patch = null; } diff --git a/CheatEnabler/CheatEnabler.cs b/CheatEnabler/CheatEnabler.cs index 983aae8..671b24d 100644 --- a/CheatEnabler/CheatEnabler.cs +++ b/CheatEnabler/CheatEnabler.cs @@ -63,9 +63,9 @@ public class CheatEnabler : BaseUnityPlugin "Boost geothermal power"); PlanetFunctions.PlayerActionsInGlobeViewEnabled = Config.Bind("Planet", "PlayerActionsInGlobeView", false, "Enable player actions in globe view"); - ResourcePatch.InfiniteEnabled = Config.Bind("Planet", "AlwaysInfiniteResource", false, + ResourcePatch.InfiniteResourceEnabled = Config.Bind("Planet", "AlwaysInfiniteResource", false, "always infinite natural resource"); - ResourcePatch.FastEnabled = Config.Bind("Planet", "FastMining", false, + ResourcePatch.FastMiningEnabled = Config.Bind("Planet", "FastMining", false, "super-fast mining speed"); WaterPumperPatch.Enabled = Config.Bind("Planet", "WaterPumpAnywhere", false, "Can pump water anywhere (while water type is not None)"); @@ -109,8 +109,8 @@ public class CheatEnabler : BaseUnityPlugin I18N.Apply(); // UI Patch - _windowPatch = Harmony.CreateAndPatchAll(typeof(UI.MyWindowManager.Patch)); - _patch = Harmony.CreateAndPatchAll(typeof(CheatEnabler)); + _windowPatch ??= Harmony.CreateAndPatchAll(typeof(UI.MyWindowManager.Patch)); + _patch ??= Harmony.CreateAndPatchAll(typeof(CheatEnabler)); DevShortcuts.Init(); AbnormalDisabler.Init(); @@ -272,7 +272,6 @@ public class CheatEnabler : BaseUnityPlugin } else { - UIRoot.instance.uiGame.ShutPlayerInventory(); _configWin.Open(); } } diff --git a/CheatEnabler/DevShortcuts.cs b/CheatEnabler/DevShortcuts.cs index 2c1c3eb..b1927cc 100644 --- a/CheatEnabler/DevShortcuts.cs +++ b/CheatEnabler/DevShortcuts.cs @@ -12,7 +12,7 @@ public static class DevShortcuts public static void Init() { - _patch = Harmony.CreateAndPatchAll(typeof(DevShortcuts)); + _patch ??= Harmony.CreateAndPatchAll(typeof(DevShortcuts)); Enabled.SettingChanged += (_, _) => { if (_test != null) _test.active = Enabled.Value; @@ -21,8 +21,7 @@ public static class DevShortcuts public static void Uninit() { - if (_patch == null) return; - _patch.UnpatchSelf(); + _patch?.UnpatchSelf(); _patch = null; } diff --git a/CheatEnabler/DysonSpherePatch.cs b/CheatEnabler/DysonSpherePatch.cs index 3f04591..0494ade 100644 --- a/CheatEnabler/DysonSpherePatch.cs +++ b/CheatEnabler/DysonSpherePatch.cs @@ -8,6 +8,7 @@ namespace CheatEnabler; public static class DysonSpherePatch { + public static ConfigEntry StopEjectOnNodeCompleteEnabled; public static ConfigEntry SkipBulletEnabled; public static ConfigEntry SkipAbsorbEnabled; public static ConfigEntry QuickAbsorbEnabled; @@ -20,18 +21,20 @@ public static class DysonSpherePatch private static Harmony _ejectAnywayPatch; private static Harmony _overclockEjector; private static Harmony _overclockSilo; - private static Harmony _patch; + private static Harmony _dysonSpherePatch; private static bool _instantAbsorb; public static void Init() { - _patch ??= Harmony.CreateAndPatchAll(typeof(DysonSpherePatch)); + _dysonSpherePatch ??= Harmony.CreateAndPatchAll(typeof(DysonSpherePatch)); + StopEjectOnNodeCompleteEnabled.SettingChanged += (_, _) => StopEjectOnNodeComplete.Enable(StopEjectOnNodeCompleteEnabled.Value); SkipBulletEnabled.SettingChanged += (_, _) => SkipBulletValueChanged(); SkipAbsorbEnabled.SettingChanged += (_, _) => SkipAbsorbValueChanged(); QuickAbsorbEnabled.SettingChanged += (_, _) => QuickAbsorbValueChanged(); EjectAnywayEnabled.SettingChanged += (_, _) => EjectAnywayValueChanged(); OverclockEjectorEnabled.SettingChanged += (_, _) => OverclockEjectorValueChanged(); OverclockSiloEnabled.SettingChanged += (_, _) => OverclockSiloValueChanged(); + StopEjectOnNodeComplete.Enable(StopEjectOnNodeCompleteEnabled.Value); SkipBulletValueChanged(); SkipAbsorbValueChanged(); QuickAbsorbValueChanged(); @@ -42,6 +45,7 @@ public static class DysonSpherePatch public static void Uninit() { + StopEjectOnNodeComplete.Enable(false); _skipBulletPatch?.UnpatchSelf(); _skipBulletPatch = null; _skipAbsorbPatch?.UnpatchSelf(); @@ -54,8 +58,8 @@ public static class DysonSpherePatch _overclockEjector = null; _overclockSilo?.UnpatchSelf(); _overclockSilo = null; - _patch?.UnpatchSelf(); - _patch = null; + _dysonSpherePatch?.UnpatchSelf(); + _dysonSpherePatch = null; } private static void SkipBulletValueChanged() @@ -191,10 +195,10 @@ public static class DysonSpherePatch } ds.RemoveLayer(index); } - + [HarmonyTranspiler] [HarmonyPatch(typeof(DysonNode), nameof(DysonNode.ConstructCp))] - private static IEnumerable DysonNode_ConstructCp_Patch(IEnumerable instructions, ILGenerator generator) + private static IEnumerable DysonSpherePatch_DysonNode_ConstructCp_Transpiler(IEnumerable instructions, ILGenerator generator) { var matcher = new CodeMatcher(instructions, generator); matcher.MatchBack(false, @@ -220,6 +224,136 @@ public static class DysonSpherePatch return matcher.InstructionEnumeration(); } + private static class StopEjectOnNodeComplete + { + private static Harmony _patch; + private static HashSet[] _nodeForAbsorb; + + public static void Enable(bool on) + { + if (on) + { + InitNodeForAbsorb(); + _patch ??= Harmony.CreateAndPatchAll(typeof(StopEjectOnNodeComplete)); + } + else + { + _patch?.UnpatchSelf(); + _patch = null; + _nodeForAbsorb = null; + } + } + + private static void InitNodeForAbsorb() + { + _nodeForAbsorb = new HashSet[GameMain.data.galaxy.starCount]; + foreach (var sphere in GameMain.data.dysonSpheres) + { + if (sphere?.layersSorted == null) continue; + var starIndex = sphere.starData.index; + foreach (var layer in sphere.layersSorted) + { + if (layer == null) continue; + for (var i = layer.nodeCursor - 1; i > 0; i--) + { + var node = layer.nodePool[i]; + if (node == null || node.id != i) continue; + SetNodeForAbsorb(starIndex, layer.id, node.id, node.sp == node.spMax && node.cpReqOrder > 0); + } + } + } + } + + private static void SetNodeForAbsorb(int index, int layerId, int nodeId, bool canAbsorb) + { + ref var comp = ref _nodeForAbsorb[index]; + comp ??= new HashSet(); + var idx = nodeId * 10 + layerId; + if (canAbsorb) + comp.Add(idx); + else + comp.Remove(idx); + } + + private static void UpdateNodeForAbsorb(DysonNode node) + { + var shells = node.shells; + if (shells.Count == 0) return; + SetNodeForAbsorb(shells[0].dysonSphere.starData.index, node.layerId, node.id, node.sp == node.spMax && node.cpReqOrder > 0); + } + + private static bool AnyNodeForAbsorb(int starIndex) + { + var comp = _nodeForAbsorb[starIndex]; + return comp != null && comp.Count > 0; + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] + private static void GameMain_Begin_Postfix() + { + InitNodeForAbsorb(); + } + + [HarmonyPostfix] + [HarmonyPatch(typeof(DysonNode), nameof(DysonNode.RecalcCpReq))] + private static void DysonNode_RecalcCpReq_Postfix(DysonNode __instance) + { + UpdateNodeForAbsorb(__instance); + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(DysonSphereLayer), nameof(DysonSphereLayer.RemoveDysonNode))] + private static void DysonSphereLayer_RemoveDysonNode_Prefix(DysonSphereLayer __instance, int nodeId) + { + SetNodeForAbsorb(__instance.starData.index, __instance.id, nodeId, false); + } + + [HarmonyPrefix] + [HarmonyPatch(typeof(DysonSphere), nameof(DysonSphere.ResetNew))] + private static void DysonSphere_ResetNew_Prefix(DysonSphere __instance) + { + var starIndex = __instance.starData.index; + if (_nodeForAbsorb[starIndex] == null) return; + _nodeForAbsorb[starIndex].Clear(); + _nodeForAbsorb[starIndex] = null; + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(EjectorComponent), nameof(EjectorComponent.InternalUpdate))] + private static IEnumerable EjectorComponent_InternalUpdate_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + var label1 = generator.DefineLabel(); + matcher.Start().InsertAndAdvance( + new CodeInstruction(OpCodes.Ldarg_2), + new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(DysonSwarm), nameof(DysonSwarm.starData))), + new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(StarData), nameof(StarData.index))), + new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(StopEjectOnNodeComplete), nameof(StopEjectOnNodeComplete.AnyNodeForAbsorb))), + new CodeInstruction(OpCodes.Brtrue, label1) + ); + matcher.Labels.Add(label1); + return matcher.InstructionEnumeration(); + } + + [HarmonyTranspiler] + [HarmonyPatch(typeof(DysonNode), nameof(DysonNode.ConstructCp))] + private static IEnumerable DysonNode_ConstructCp_Transpiler(IEnumerable instructions, ILGenerator generator) + { + var matcher = new CodeMatcher(instructions, generator); + matcher.Start().MatchForward(false, + new CodeMatch(OpCodes.Stfld, AccessTools.Field(typeof(DysonNode), nameof(DysonNode.sp))) + ).Advance(1); + var labels = matcher.Labels; + matcher.Labels = new List