Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for siege mortar ammo #3169

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Defs/Ammo/Shell/81mmMortar.xml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
</statBases>
<ammoClass>FoamFuel</ammoClass>
<detonateProjectile>Bullet_81mmMortarShell_Firefoam</detonateProjectile>
<spawnAsSiegeAmmo>false</spawnAsSiegeAmmo>
</ThingDef>

<ThingDef Class="CombatExtended.AmmoDef" ParentName="81mmMortarShellBaseCraftableBase">
Expand All @@ -145,6 +146,7 @@
</statBases>
<ammoClass>Smoke</ammoClass>
<detonateProjectile>Bullet_81mmMortarShell_Smoke</detonateProjectile>
<spawnAsSiegeAmmo>false</spawnAsSiegeAmmo>
</ThingDef>

<ThingDef Class="CombatExtended.AmmoDef" ParentName="81mmMortarShellBase">
Expand Down
1 change: 1 addition & 0 deletions ModPatches/BiologicalWarfare/Patches/Patches.xml
Original file line number Diff line number Diff line change
Expand Up @@ -289,4 +289,5 @@
defName="USH_SleepingSicknessGrenadeLauncher" or
defName="USH_SleepingSicknessGrenadeBullet"]</xpath>
</Operation>

</Patch>
1 change: 1 addition & 0 deletions Source/CombatExtended/CombatExtended/Defs/AmmoDef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
59 changes: 57 additions & 2 deletions Source/CombatExtended/Harmony/Harmony_LordToil_Siege.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using HarmonyLib;
using RimWorld;
using Verse;
Expand All @@ -11,8 +13,61 @@ internal static class Harmony_LordToil_Siege
{
internal static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
return instructions.MethodReplacer(typeof(ThingDef).GetMethod("get_IsShell"),
typeof(AmmoUtility).GetMethod(nameof(AmmoUtility.IsShell), BindingFlags.Public | BindingFlags.Static));
var codes = new List<CodeInstruction>(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;
}
}
}
7 changes: 4 additions & 3 deletions Source/CombatExtended/Harmony/Harmony_TurretGunUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ public static class Harmony_TurretGunUtility
const string className = "DisplayClass";
const string methodName = "<TryFindRandomShellDef>";

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)
Expand Down Expand Up @@ -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;
}
Expand Down
Loading