using System; using System.Collections.Generic; using System.Reflection.Emit; using BepInEx.Configuration; using HarmonyLib; namespace CheatEnabler; public static class DysonSpherePatch { public static ConfigEntry SkipBulletEnabled; public static ConfigEntry SkipAbsorbEnabled; public static ConfigEntry QuickAbsortEnabled; public static ConfigEntry EjectAnywayEnabled; public static ConfigEntry OverclockEjectorEnabled; public static ConfigEntry OverclockSiloEnabled; private static Harmony _skipBulletPatch; private static Harmony _skipAbsorbPatch; private static Harmony _quickAbsortPatch; private static Harmony _ejectAnywayPatch; private static Harmony _overclockEjector; private static Harmony _overclockSilo; private static Harmony _patch; public static void Init() { _patch ??= Harmony.CreateAndPatchAll(typeof(DysonSpherePatch)); SkipBulletEnabled.SettingChanged += (_, _) => SkipBulletValueChanged(); SkipAbsorbEnabled.SettingChanged += (_, _) => SkipAbsorbValueChanged(); QuickAbsortEnabled.SettingChanged += (_, _) => QuickAbsortValueChanged(); EjectAnywayEnabled.SettingChanged += (_, _) => EjectAnywayValueChanged(); OverclockEjectorEnabled.SettingChanged += (_, _) => OverclockEjectorValueChanged(); OverclockSiloEnabled.SettingChanged += (_, _) => OverclockSiloValueChanged(); SkipBulletValueChanged(); SkipAbsorbValueChanged(); QuickAbsortValueChanged(); EjectAnywayValueChanged(); OverclockEjectorValueChanged(); OverclockSiloValueChanged(); } public static void Uninit() { _skipBulletPatch?.UnpatchSelf(); _skipBulletPatch = null; _skipAbsorbPatch?.UnpatchSelf(); _skipAbsorbPatch = null; _quickAbsortPatch?.UnpatchSelf(); _quickAbsortPatch = null; _ejectAnywayPatch?.UnpatchSelf(); _ejectAnywayPatch = null; _overclockEjector?.UnpatchSelf(); _overclockEjector = null; _overclockSilo?.UnpatchSelf(); _overclockSilo = null; _patch?.UnpatchSelf(); _patch = 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() { if (SkipAbsorbEnabled.Value) { if (_skipAbsorbPatch != null) { return; } _skipAbsorbPatch = Harmony.CreateAndPatchAll(typeof(SkipAbsorbPatch)); } else if (_skipAbsorbPatch != null) { _skipAbsorbPatch.UnpatchSelf(); _skipAbsorbPatch = null; } } private static void QuickAbsortValueChanged() { if (QuickAbsortEnabled.Value) { if (_quickAbsortPatch != null) { return; } _quickAbsortPatch = Harmony.CreateAndPatchAll(typeof(QuickAbsortPatch)); } else if (_quickAbsortPatch != null) { _quickAbsortPatch.UnpatchSelf(); _quickAbsortPatch = 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 DysonNode_ConstructCp_Patch(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