From 64ba98598318ccd8b31099c1917fcfee453e57dd Mon Sep 17 00:00:00 2001 From: NathanKell Date: Sun, 7 Aug 2022 17:25:36 -0700 Subject: [PATCH] Support eliminating some extraneous saving by KSP: On despawn of AC/Admin/MC/RnD, and on delete vessel in TS. Written by siimav, KSPCF'd by me. --- GameData/KSPCommunityFixes/Settings.cfg | 5 + KSPCommunityFixes/KSPCommunityFixes.csproj | 1 + KSPCommunityFixes/Performance/FewerSaves.cs | 108 ++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 KSPCommunityFixes/Performance/FewerSaves.cs diff --git a/GameData/KSPCommunityFixes/Settings.cfg b/GameData/KSPCommunityFixes/Settings.cfg index 0894c38..4ce796a 100644 --- a/GameData/KSPCommunityFixes/Settings.cfg +++ b/GameData/KSPCommunityFixes/Settings.cfg @@ -274,6 +274,11 @@ KSP_COMMUNITY_FIXES packedInterval = 0.5 // interval when the active vessel is timewarping } + // This tweak eliminates KSP's stock behavior of saving every time + // you exit a UI-only space center building (AC, MC, etc) + // and every time you delete a vessel in the Tracking Station + FewerSaves = false + // ########################## // Modding // ########################## diff --git a/KSPCommunityFixes/KSPCommunityFixes.csproj b/KSPCommunityFixes/KSPCommunityFixes.csproj index 97109ed..222ebd9 100644 --- a/KSPCommunityFixes/KSPCommunityFixes.csproj +++ b/KSPCommunityFixes/KSPCommunityFixes.csproj @@ -127,6 +127,7 @@ + diff --git a/KSPCommunityFixes/Performance/FewerSaves.cs b/KSPCommunityFixes/Performance/FewerSaves.cs new file mode 100644 index 0000000..ecf0db4 --- /dev/null +++ b/KSPCommunityFixes/Performance/FewerSaves.cs @@ -0,0 +1,108 @@ +using System; +using HarmonyLib; +using System.Collections.Generic; +using UnityEngine; +using KSP.UI.Screens; +using KSP.UI; +using System.Reflection.Emit; + +namespace KSPCommunityFixes +{ + public class FewerSaves : BasePatch + { + protected override Version VersionMin => new Version(1, 8, 0); + + protected override void ApplyPatches(List patches) + { + patches.Add(new PatchInfo( + PatchMethodType.Prefix, + AccessTools.Method(typeof(ACSceneSpawner), nameof(ACSceneSpawner.onACDespawn)), + this)); + + patches.Add(new PatchInfo( + PatchMethodType.Prefix, + AccessTools.Method(typeof(AdministrationSceneSpawner), nameof(AdministrationSceneSpawner.onAdminDespawn)), + this)); + + patches.Add(new PatchInfo( + PatchMethodType.Prefix, + AccessTools.Method(typeof(MCSceneSpawner), nameof(MCSceneSpawner.OnMCDespawn)), + this)); + + patches.Add(new PatchInfo( + PatchMethodType.Prefix, + AccessTools.Method(typeof(RDSceneSpawner), nameof(RDSceneSpawner.onRDDespawn)), + this)); + + patches.Add(new PatchInfo( + PatchMethodType.Transpiler, + AccessTools.Method(typeof(SpaceTracking), "OnVesselDeleteConfirm"), + this)); + } + + static bool ACSceneSpawner_onACDespawn_Prefix(ACSceneSpawner __instance) + { + UIMasterController.Instance.RemoveCanvas(__instance.ACScreenPrefab); + MusicLogic.fetch.UnpauseWithCrossfade(); + return false; + } + + static bool AdministrationSceneSpawner_onAdminDespawn_Prefix(AdministrationSceneSpawner __instance) + { + UIMasterController.Instance.RemoveCanvas(__instance.AdministrationScreenPrefab); + MusicLogic.fetch.UnpauseWithCrossfade(); + return false; + } + + static bool MCSceneSpawner_OnMCDespawn_Prefix(MCSceneSpawner __instance) + { + UIMasterController.Instance.RemoveCanvas(__instance.missionControlPrefab); + MusicLogic.fetch.UnpauseWithCrossfade(); + return false; + } + + static bool RDSceneSpawner_onRDDespawn_Prefix(RDSceneSpawner __instance) + { + UIMasterController.Instance.RemoveCanvas(__instance.RDScreenPrefab); + RenderSettings.defaultReflectionMode = __instance.oldReflectionMode; + RenderSettings.customReflection = __instance.oldReflection; + MusicLogic.fetch.UnpauseWithCrossfade(); + return false; + } + + static IEnumerable SpaceTracking_OnVesselDeleteConfirm_Transpiler(IEnumerable instructions) + { + int startIndex = -1; + int endIndex = -1; + + var codes = new List(instructions); + + for (int i = 0; i < codes.Count; i++) + { + if (codes[i].opcode == OpCodes.Ldstr && + codes[i].operand as string == "persistent") + { + startIndex = i; + + for (int j = startIndex; j < codes.Count; j++) + { + if (codes[j].opcode == OpCodes.Ldarg_0) + { + endIndex = j; + break; + } + } + break; + } + } + + if (startIndex > -1 && endIndex > -1) + { + // Cuts out the section about GamePersistence.SaveGame() + codes.RemoveRange(startIndex, endIndex - startIndex); + } + + return codes; + } + } +}