diff --git a/Defs/Ammo/Shell/81mmMortar.xml b/Defs/Ammo/Shell/81mmMortar.xml index 49b31aebfb..d4918a97f5 100644 --- a/Defs/Ammo/Shell/81mmMortar.xml +++ b/Defs/Ammo/Shell/81mmMortar.xml @@ -129,6 +129,7 @@ FoamFuel Bullet_81mmMortarShell_Firefoam + false @@ -145,6 +146,7 @@ Smoke Bullet_81mmMortarShell_Smoke + false diff --git a/ModPatches/BiologicalWarfare/Patches/Patches.xml b/ModPatches/BiologicalWarfare/Patches/Patches.xml index eb1f4d4ec8..8f9e2e5e0f 100644 --- a/ModPatches/BiologicalWarfare/Patches/Patches.xml +++ b/ModPatches/BiologicalWarfare/Patches/Patches.xml @@ -289,4 +289,5 @@ defName="USH_SleepingSicknessGrenadeLauncher" or defName="USH_SleepingSicknessGrenadeBullet"] + \ No newline at end of file diff --git a/Source/CombatExtended/CombatExtended/Defs/AmmoDef.cs b/Source/CombatExtended/CombatExtended/Defs/AmmoDef.cs index 961404e3ac..351f7c187f 100644 --- a/Source/CombatExtended/CombatExtended/Defs/AmmoDef.cs +++ b/Source/CombatExtended/CombatExtended/Defs/AmmoDef.cs @@ -23,6 +23,7 @@ public class AmmoDef : ThingDef // mortar ammo should still availabe when the ammo system is off public bool isMortarAmmo = false; + public bool spawnAsSiegeAmmo = true; public int ammoCount = 1; public ThingDef partialUnloadAmmoDef = null; diff --git a/Source/CombatExtended/Harmony/Harmony_LordToil_Siege.cs b/Source/CombatExtended/Harmony/Harmony_LordToil_Siege.cs index ebd984e9dd..7200056022 100644 --- a/Source/CombatExtended/Harmony/Harmony_LordToil_Siege.cs +++ b/Source/CombatExtended/Harmony/Harmony_LordToil_Siege.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; +using System.Linq; using System.Reflection; +using System.Reflection.Emit; using HarmonyLib; using RimWorld; using Verse; @@ -11,8 +13,61 @@ internal static class Harmony_LordToil_Siege { internal static IEnumerable Transpiler(IEnumerable instructions) { - return instructions.MethodReplacer(typeof(ThingDef).GetMethod("get_IsShell"), - typeof(AmmoUtility).GetMethod(nameof(AmmoUtility.IsShell), BindingFlags.Public | BindingFlags.Static)); + var codes = new List(instructions); + var methodCustomCondition = typeof(Harmony_LordToil_Siege).GetMethod(nameof(CustomCondition), BindingFlags.Static | BindingFlags.Public); + var startIndex = -1; + var endIndex = -1; + MethodInfo targetMethod = AccessTools.Method(typeof(ThingDef), "get_IsShell"); // Start of the if condition + FieldInfo targetField = AccessTools.Field(typeof(DamageDef), "harmsHealth"); // End of the if condition + for (int i = 0; i < codes.Count; i++) + { + if (startIndex == -1) + { + // Find the start of the if statement + if (codes[i].opcode == OpCodes.Callvirt && codes[i].Calls(targetMethod)) + { + startIndex = i - 1; // We want to edit -1 instruction from the call of IsShell + } + } + else if (codes[i].opcode == OpCodes.Ldfld && codes[i].LoadsField(targetField)) + { + endIndex = i; + } + } + if (startIndex == -1 || endIndex == -1) + { + Log.Error("CombatExtended :: Harmony_LordToil_Siege couldn't find code block for patching"); + return codes; // Don't modify as we couldn't find the original code block + } + else + { + codes[startIndex] = new CodeInstruction(OpCodes.Call, methodCustomCondition); // Call the new method for evaluation + codes.RemoveRange(startIndex + 1, endIndex - startIndex); // Remove the default code + return codes; + } + } + + public static bool CustomCondition(Thing thing) + { + // Ensure check is the same here as from CombatExtended.HarmonyCE.Harmony_TurretGunUtility + var ammoDef = thing.def as AmmoDef; + if (ammoDef == null) + { + return false; + } + + // Ignore all non-shell defs. + if (ammoDef == null || !AmmoUtility.IsShell(ammoDef)) + { + return false; + } + + // Check if shell is blacklisted + if (!ammoDef.spawnAsSiegeAmmo) + { + return false; + } + return true; } } } diff --git a/Source/CombatExtended/Harmony/Harmony_TurretGunUtility.cs b/Source/CombatExtended/Harmony/Harmony_TurretGunUtility.cs index b48496d9cf..627366c629 100644 --- a/Source/CombatExtended/Harmony/Harmony_TurretGunUtility.cs +++ b/Source/CombatExtended/Harmony/Harmony_TurretGunUtility.cs @@ -18,7 +18,8 @@ public static class Harmony_TurretGunUtility const string className = "DisplayClass"; const string methodName = ""; - public static void Postfix(object __instance, ThingDef x, ref bool __result, bool ___allowEMP, float ___maxMarketValue, bool ___mustHarmHealth) + // This should be kept up to date with the check in CombatExtended.HarmonyCE.Harmony_LordToil_Siege + public static void Postfix(object __instance, ThingDef x, ref bool __result, bool ___allowEMP, float ___maxMarketValue) { // Ignore already true results. if (__result) @@ -60,8 +61,8 @@ public static void Postfix(object __instance, ThingDef x, ref bool __result, boo return; } - // Check if shell harms health. - if (___mustHarmHealth && explosiveDamageDef != null && !explosiveDamageDef.harmsHealth && projectileDamageDef != null && !projectileDamageDef.harmsHealth) + // Check if blacklisted + if (!ammoDef.spawnAsSiegeAmmo) { return; }