using System; using System.Collections.Generic; using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; namespace CheatEnabler; public static class DysonSpherePatch { public static ConfigEntry StopEjectOnNodeCompleteEnabled; public static ConfigEntry SkipBulletEnabled; public static ConfigEntry SkipAbsorbEnabled; public static ConfigEntry QuickAbsorbEnabled; public static ConfigEntry EjectAnywayEnabled; public static ConfigEntry OverclockEjectorEnabled; public static ConfigEntry OverclockSiloEnabled; private static Harmony _skipBulletPatch; private static Harmony _skipAbsorbPatch; private static Harmony _quickAbsorbPatch; private static Harmony _ejectAnywayPatch; private static Harmony _overclockEjector; private static Harmony _overclockSilo; private static Harmony _dysonSpherePatch; private static bool _instantAbsorb; public static void Init() { _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(); EjectAnywayValueChanged(); OverclockEjectorValueChanged(); OverclockSiloValueChanged(); } public static void Uninit() { StopEjectOnNodeComplete.Enable(false); _skipBulletPatch?.UnpatchSelf(); _skipBulletPatch = null; _skipAbsorbPatch?.UnpatchSelf(); _skipAbsorbPatch = null; _quickAbsorbPatch?.UnpatchSelf(); _quickAbsorbPatch = null; _ejectAnywayPatch?.UnpatchSelf(); _ejectAnywayPatch = null; _overclockEjector?.UnpatchSelf(); _overclockEjector = null; _overclockSilo?.UnpatchSelf(); _overclockSilo = null; _dysonSpherePatch?.UnpatchSelf(); _dysonSpherePatch = null; } private static void SkipBulletValueChanged() { if (SkipBulletEnabled.Value) { if (_skipBulletPatch != null) { return; } SkipBulletPatch.UpdateSailLifeTime(); SkipBulletPatch.UpdateSailsCacheForThisGame(); _skipBulletPatch = Harmony.CreateAndPatchAll(typeof(SkipBulletPatch)); } else if (_skipBulletPatch != null) { _skipBulletPatch.UnpatchSelf(); _skipBulletPatch = null; } } private static void SkipAbsorbValueChanged() { _instantAbsorb = SkipAbsorbEnabled.Value && QuickAbsorbEnabled.Value; if (SkipAbsorbEnabled.Value) { if (_skipAbsorbPatch != null) { return; } _skipAbsorbPatch = Harmony.CreateAndPatchAll(typeof(SkipAbsorbPatch)); } else if (_skipAbsorbPatch != null) { _skipAbsorbPatch.UnpatchSelf(); _skipAbsorbPatch = null; } } private static void QuickAbsorbValueChanged() { _instantAbsorb = SkipAbsorbEnabled.Value && QuickAbsorbEnabled.Value; if (QuickAbsorbEnabled.Value) { if (_quickAbsorbPatch != null) { return; } _quickAbsorbPatch = Harmony.CreateAndPatchAll(typeof(QuickAbsorbPatch)); } else if (_quickAbsorbPatch != null) { _quickAbsorbPatch.UnpatchSelf(); _quickAbsorbPatch = null; } } private static void EjectAnywayValueChanged() { if (EjectAnywayEnabled.Value) { if (_ejectAnywayPatch != null) { return; } _ejectAnywayPatch = Harmony.CreateAndPatchAll(typeof(EjectAnywayPatch)); } else if (_ejectAnywayPatch != null) { _ejectAnywayPatch.UnpatchSelf(); _ejectAnywayPatch = null; } } private static void OverclockEjectorValueChanged() { if (OverclockEjectorEnabled.Value) { if (_overclockEjector != null) { return; } _overclockEjector = Harmony.CreateAndPatchAll(typeof(OverclockEjector)); } else if (_overclockEjector != null) { _overclockEjector.UnpatchSelf(); _overclockEjector = null; } } private static void OverclockSiloValueChanged() { if (OverclockSiloEnabled.Value) { if (_overclockSilo != null) { return; } _overclockSilo = Harmony.CreateAndPatchAll(typeof(OverclockSilo)); } else if (_overclockSilo != null) { _overclockSilo.UnpatchSelf(); _overclockSilo = 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] [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