diff --git a/.gitignore b/.gitignore index aa4950f..4c47a94 100644 --- a/.gitignore +++ b/.gitignore @@ -267,3 +267,4 @@ __pycache__/ libs/ libs.fixed/ +*/*.swp diff --git a/README.md b/README.md index 5ce6626..cb6c27c 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,9 @@ - Make all simgame room transitions instant. - RemovedContractsFix - This fix removes invalid contracts allowing saves to load if a user created contract was removed from the mods in use. +- NavigationMapFilterLagFix + - This fix removes some unnecessary code in the navigation map's difficulty filter selection. + - The performance gain is negligible in vanilla, but in modpacks using the entire IS map such as RT or BTA, this saves a few seconds. # Experimental patches - MDDB_TagsetQueryInChunks diff --git a/source/BattletechPerformanceFix.csproj b/source/BattletechPerformanceFix.csproj index 4c46833..dd24718 100644 --- a/source/BattletechPerformanceFix.csproj +++ b/source/BattletechPerformanceFix.csproj @@ -53,6 +53,7 @@ + @@ -67,7 +68,7 @@ - + @@ -120,4 +121,4 @@ yes | cp "$(TargetDir)$(TargetName).dll" "$(SolutionDir)../../Mods/BattletechPerformanceFix/$(TargetName).dll" yes | cp "$(TargetDir)$(TargetName).dll" "$(SolutionDir)../../Mods/BattletechPerformanceFix/$(TargetName).dll" - \ No newline at end of file + diff --git a/source/Main.cs b/source/Main.cs index 0231c9e..8c0785a 100644 --- a/source/Main.cs +++ b/source/Main.cs @@ -91,6 +91,7 @@ public static void Start(string modDirectory, string json) { typeof(DataLoaderGetEntryCheck), true }, { typeof(ShopTabLagFix), true }, { typeof(ContractLagFix), true }, + { typeof(NavigationMapFilterLagFix), true }, { typeof(EnableLoggingDuringLoads), true }, { typeof(ExtraLogging), true }, { typeof(ShaderDependencyOverride), true }, diff --git a/source/NavigationMapFilterLagFix.cs b/source/NavigationMapFilterLagFix.cs new file mode 100644 index 0000000..b3d43ab --- /dev/null +++ b/source/NavigationMapFilterLagFix.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using System.Linq; +using BattleTech.UI; +using Harmony; +using System.Reflection; +using System.Reflection.Emit; +using static BattletechPerformanceFix.Extensions; + +namespace BattletechPerformanceFix +{ + /* Removes a redundant call for creating difficulty callouts, saves a few seconds per filter selection */ + class NavigationMapFilterLagFix : Feature + { + public void Activate() + { + var method = AccessTools.Method(typeof(SGNavigationScreen), "OnDifficultySelectionChanged"); + var transpiler = new HarmonyMethod(typeof(NavigationMapFilterLagFix), nameof(Transpiler)); + Main.harmony.Patch(method, null, null, transpiler); + } + + // cuts out the if/else block in OnDifficultySelectionChanged() because CreateDifficultyCallouts() + // is called later by RefreshSystemIndicators() anyways just after the block + private static IEnumerable Transpiler(IEnumerable instructions) + { + int startIndex = -1; + int endIndex = -1; + + // searches for the if block start & end points, in case some other mod is modifying this function + // (which is why we don't hardcode the indices) + var code = instructions.ToList(); + for (int i = 0; i < code.Count-1; i++) { + if (startIndex == -1) { + if (code[i].opcode == OpCodes.Ldarg_1 && code[i+1].opcode == OpCodes.Brtrue) { + startIndex = i; + } + } else { + if (code[i].opcode == OpCodes.Ldarg_1 && code[i+1].opcode == OpCodes.Call && + (code[i+1].operand as MethodInfo).Name == "CreateDifficultyCallouts") { + endIndex = i+1; + break; + } + } + } + + if (startIndex != -1 && endIndex != -1) { + LogDebug("Overwriting instructions in SGNavigationScreen.OnDifficultySelectionChanged()" + + " at indices " + startIndex + "-" + endIndex + " with nops"); + for (int i = startIndex; i <= endIndex; i++) { + code[i].opcode = OpCodes.Nop; + } + } else { + LogError("Failed to find the code to overwrite in " + + "SGNavigationScreen.OnDifficultySelectionChanged(); no changes were made."); + LogError("NavigationMapFilterLagFix has not been applied, report this as a bug"); + } + + return code.AsEnumerable(); + } + } +}