using System.Collections.Generic; using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; namespace UXAssist; public static class DysonSpherePatch { public static ConfigEntry StopEjectOnNodeCompleteEnabled; public static ConfigEntry OnlyConstructNodesEnabled; private static Harmony _dysonSpherePatch; public static void Init() { _dysonSpherePatch ??= Harmony.CreateAndPatchAll(typeof(DysonSpherePatch)); StopEjectOnNodeCompleteEnabled.SettingChanged += (_, _) => StopEjectOnNodeComplete.Enable(StopEjectOnNodeCompleteEnabled.Value); OnlyConstructNodesEnabled.SettingChanged += (_, _) => OnlyConstructNodes.Enable(OnlyConstructNodesEnabled.Value); StopEjectOnNodeComplete.Enable(StopEjectOnNodeCompleteEnabled.Value); OnlyConstructNodes.Enable(OnlyConstructNodesEnabled.Value); } public static void Uninit() { StopEjectOnNodeComplete.Enable(false); OnlyConstructNodes.Enable(false); _dysonSpherePatch?.UnpatchSelf(); _dysonSpherePatch = null; } public static void InitCurrentDysonSphere(int index) { var star = GameMain.localStar; if (star == null) return; var dysonSpheres = GameMain.data?.dysonSpheres; if (dysonSpheres == null) return; if (index < 0) { if (dysonSpheres[star.index] == null) return; var dysonSphere = new DysonSphere(); dysonSpheres[star.index] = dysonSphere; dysonSphere.Init(GameMain.data, star); dysonSphere.ResetNew(); return; } var ds = dysonSpheres[star.index]; if (ds?.layersIdBased[index] == null) return; var pool = ds.rocketPool; for (var id = ds.rocketCursor - 1; id > 0; id--) { if (pool[id].id != id) continue; if (pool[id].nodeLayerId != index) continue; ds.RemoveDysonRocket(id); } ds.RemoveLayer(index); } [HarmonyTranspiler] [HarmonyPriority(Priority.First)] [HarmonyPatch(typeof(DysonNode), nameof(DysonNode.ConstructCp))] private static IEnumerable DysonSpherePatch_DysonNode_ConstructCp_Transpiler(IEnumerable instructions, ILGenerator generator) { var matcher = new CodeMatcher(instructions, generator); matcher.MatchBack(false, new CodeMatch(OpCodes.Ldc_I4_0), new CodeMatch(OpCodes.Callvirt, AccessTools.Method(typeof(DysonShell), nameof(DysonShell.Construct))) ).Advance(3).InsertAndAdvance( // node._cpReq = node._cpReq - 1; new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldarg_0), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(DysonNode), nameof(DysonNode._cpReq))), new CodeInstruction(OpCodes.Ldc_I4_1), new CodeInstruction(OpCodes.Sub), new CodeInstruction(OpCodes.Stfld, AccessTools.Field(typeof(DysonNode), nameof(DysonNode._cpReq))) ); // Remove use of RecalcCpReq() matcher.MatchForward(false, new CodeMatch(OpCodes.Ldarg_0), new CodeMatch(OpCodes.Call, AccessTools.Method(typeof(DysonNode), nameof(DysonNode.RecalcCpReq))) ); var labels = matcher.Labels; matcher.Labels = new List