From 0640f7e8a0b623cb84661eccf7f0d8a5dacbf6d2 Mon Sep 17 00:00:00 2001 From: gotmachine <24925209+gotmachine@users.noreply.github.com> Date: Wed, 6 Dec 2023 17:05:11 +0100 Subject: [PATCH] New KSP bugfix : [**ModuleAnimateGenericCrewModSpawnIVA**](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/169) [KSP 1.8.0 - 1.12.5], fix IVA & crew portrait not spawning/despawning when ModuleAnimateGeneric is used to change the part crew capacity. Notably affect the stock inflatable airlock. --- .../KSPCommunityFixes.version | 2 +- GameData/KSPCommunityFixes/Settings.cfg | 4 ++ .../ModuleAnimateGenericCrewModSpawnIVA.cs | 57 +++++++++++++++++++ KSPCommunityFixes/KSPCommunityFixes.csproj | 1 + KSPCommunityFixes/Properties/AssemblyInfo.cs | 4 +- README.md | 5 ++ 6 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 KSPCommunityFixes/BugFixes/ModuleAnimateGenericCrewModSpawnIVA.cs diff --git a/GameData/KSPCommunityFixes/KSPCommunityFixes.version b/GameData/KSPCommunityFixes/KSPCommunityFixes.version index 5b77f5c..669d88a 100644 --- a/GameData/KSPCommunityFixes/KSPCommunityFixes.version +++ b/GameData/KSPCommunityFixes/KSPCommunityFixes.version @@ -2,7 +2,7 @@ "NAME": "KSPCommunityFixes", "URL": "https://raw.githubusercontent.com/KSPModdingLibs/KSPCommunityFixes/master/GameData/KSPCommunityFixes/KSPCommunityFixes.version", "DOWNLOAD": "https://github.com/KSPModdingLibs/KSPCommunityFixes/releases", - "VERSION": {"MAJOR": 1, "MINOR": 31, "PATCH": 1, "BUILD": 0}, + "VERSION": {"MAJOR": 1, "MINOR": 32, "PATCH": 0, "BUILD": 0}, "KSP_VERSION": {"MAJOR": 1, "MINOR": 12, "PATCH": 5}, "KSP_VERSION_MIN": {"MAJOR": 1, "MINOR": 8, "PATCH": 0}, "KSP_VERSION_MAX": {"MAJOR": 1, "MINOR": 12, "PATCH": 5} diff --git a/GameData/KSPCommunityFixes/Settings.cfg b/GameData/KSPCommunityFixes/Settings.cfg index 1679d44..72ac53a 100644 --- a/GameData/KSPCommunityFixes/Settings.cfg +++ b/GameData/KSPCommunityFixes/Settings.cfg @@ -183,6 +183,10 @@ KSP_COMMUNITY_FIXES // Notably, docking port Kraken drives will no longer work. DockingPortConserveMomentum = true + // Fix IVA & crew portrait not spawning/despawning when ModuleAnimateGeneric is used to + // change the part crew capacity. Notably affect the stock inflatable airlock. + ModuleAnimateGenericCrewModSpawnIVA = true + // ########################## // Obsolete bugfixes // ########################## diff --git a/KSPCommunityFixes/BugFixes/ModuleAnimateGenericCrewModSpawnIVA.cs b/KSPCommunityFixes/BugFixes/ModuleAnimateGenericCrewModSpawnIVA.cs new file mode 100644 index 0000000..e9705b1 --- /dev/null +++ b/KSPCommunityFixes/BugFixes/ModuleAnimateGenericCrewModSpawnIVA.cs @@ -0,0 +1,57 @@ +using HarmonyLib; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Reflection.Emit; + +// fix issue #169 : IVA doesn’t work properly for parts with ModuleAnimateGeneric that modify crew capacity +namespace KSPCommunityFixes.BugFixes +{ + internal class ModuleAnimateGenericCrewModSpawnIVA : BasePatch + { + protected override Version VersionMin => new Version(1, 8, 0); + + protected override void ApplyPatches(List patches) + { + patches.Add(new PatchInfo( + PatchMethodType.Transpiler, + AccessTools.Method(typeof(ModuleAnimateGeneric), nameof(ModuleAnimateGeneric.CheckCrewState)), + this)); + } + + // Insert a call to our static OnCrewCapacityChanged() method in the "if (crewCapacity != base.part.CrewCapacity)" condition + static IEnumerable ModuleAnimateGeneric_CheckCrewState_Transpiler(IEnumerable instructions) + { + MethodInfo m_RefreshPartContextWindow = AccessTools.Method(typeof(MonoUtilities), nameof(MonoUtilities.RefreshPartContextWindow)); + MethodInfo m_PartModule_GetPart = AccessTools.PropertyGetter(typeof(PartModule), nameof(PartModule.part)); + FieldInfo f_Part_CrewCapacity = AccessTools.Field(typeof(Part), nameof(Part.CrewCapacity)); + MethodInfo m_OnCrewCapacityChanged = AccessTools.Method(typeof(ModuleAnimateGenericCrewModSpawnIVA), nameof(OnCrewCapacityChanged)); + + foreach (CodeInstruction code in instructions) + { + if (code.opcode == OpCodes.Call && ReferenceEquals(code.operand, m_RefreshPartContextWindow)) + { + yield return code; + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Call, m_PartModule_GetPart); + yield return new CodeInstruction(OpCodes.Ldarg_0); + yield return new CodeInstruction(OpCodes.Call, m_PartModule_GetPart); + yield return new CodeInstruction(OpCodes.Ldfld, f_Part_CrewCapacity); + yield return new CodeInstruction(OpCodes.Call, m_OnCrewCapacityChanged); + } + else + { + yield return code; + } + } + } + + static void OnCrewCapacityChanged(Part part, int newCrewCapacity) + { + if (newCrewCapacity > 0) + part.SpawnIVA(); + else + part.DespawnIVA(); + } + } +} diff --git a/KSPCommunityFixes/KSPCommunityFixes.csproj b/KSPCommunityFixes/KSPCommunityFixes.csproj index bcd5053..112a7ed 100644 --- a/KSPCommunityFixes/KSPCommunityFixes.csproj +++ b/KSPCommunityFixes/KSPCommunityFixes.csproj @@ -106,6 +106,7 @@ + diff --git a/KSPCommunityFixes/Properties/AssemblyInfo.cs b/KSPCommunityFixes/Properties/AssemblyInfo.cs index feac64c..cbbb25e 100644 --- a/KSPCommunityFixes/Properties/AssemblyInfo.cs +++ b/KSPCommunityFixes/Properties/AssemblyInfo.cs @@ -30,7 +30,7 @@ // Revision // [assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.31.1.0")] +[assembly: AssemblyFileVersion("1.32.0.0")] -[assembly: KSPAssembly("KSPCommunityFixes", 1, 31, 1)] +[assembly: KSPAssembly("KSPCommunityFixes", 1, 32, 0)] [assembly: KSPAssemblyDependency("MultipleModulePartAPI", 1, 0, 0)] diff --git a/README.md b/README.md index c5d5518..11bcca6 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ User options are available from the "ESC" in-game settings menu :