From 71df71a0eb1c62728796a4c5404131f84ce98074 Mon Sep 17 00:00:00 2001
From: amevarashi <ameko.hekisui@gmail.com>
Date: Mon, 6 Nov 2023 16:28:08 +0500
Subject: [PATCH] Fixed: Pawns raping despite Rape-Abhorrent precept

---
 .../HistoryEventDefExtensionMethods.cs        |  2 +
 .../IdeologyAddon/Patches/RJW_Patch_Ideo.cs   | 45 +++++++++++++++++++
 2 files changed, 47 insertions(+)

diff --git a/Source/IdeologyAddon/HistoryEvents/HistoryEventDefExtensionMethods.cs b/Source/IdeologyAddon/HistoryEvents/HistoryEventDefExtensionMethods.cs
index 8f1a4ab..808170c 100644
--- a/Source/IdeologyAddon/HistoryEvents/HistoryEventDefExtensionMethods.cs
+++ b/Source/IdeologyAddon/HistoryEvents/HistoryEventDefExtensionMethods.cs
@@ -2,6 +2,7 @@
 using Verse;
 using System.Linq;
 using System.Collections.Generic;
+using System.Runtime.CompilerServices;
 
 namespace RJWSexperience.Ideology.HistoryEvents
 {
@@ -27,6 +28,7 @@ namespace RJWSexperience.Ideology.HistoryEvents
 			//Log.Message($"[RSI] Recorded event {historyEvent.def.ToStringWithPartner(pawn, partner)}");
 		}
 
+		[MethodImpl(MethodImplOptions.AggressiveInlining)]
 		public static HistoryEvent CreateEvent(this HistoryEventDef def, Pawn pawn)
 		{
 			return new HistoryEvent(def, pawn.Named(HistoryEventArgsNames.Doer));
diff --git a/Source/IdeologyAddon/Patches/RJW_Patch_Ideo.cs b/Source/IdeologyAddon/Patches/RJW_Patch_Ideo.cs
index 4a06922..9e9a808 100644
--- a/Source/IdeologyAddon/Patches/RJW_Patch_Ideo.cs
+++ b/Source/IdeologyAddon/Patches/RJW_Patch_Ideo.cs
@@ -7,10 +7,55 @@ using RJWSexperience.Ideology.HistoryEvents;
 using RJWSexperience.Ideology.Precepts;
 using System;
 using System.Collections.Generic;
+using System.Reflection.Emit;
 using Verse;
 
 namespace RJWSexperience.Ideology.Patches
 {
+	[HarmonyPatch(typeof(xxx), nameof(xxx.can_rape))]
+	public static class RJW_Patch_CannotRapeBecauseIdeo
+	{
+		/// <summary>
+		/// Injects IdeoCanRape call into is_human block of xxx.can_rape
+		/// </summary>
+		/// <param name="instructions">Original method instructions</param>
+		/// <returns>Modified method instructions</returns>
+		[HarmonyTranspiler]
+		public static IEnumerable<CodeInstruction> AddIdeoCheck(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
+		{
+			using IEnumerator<CodeInstruction> enumerator = instructions.GetEnumerator();
+
+			System.Reflection.FieldInfo wildMode = AccessTools.Field(typeof(RJWSettings), nameof(RJWSettings.WildMode));
+			Label labelWildMode = generator.DefineLabel();
+			bool done = false;
+
+			while (enumerator.MoveNext())
+			{
+				if (!done && enumerator.Current.LoadsField(wildMode))
+				{
+					// Found RJWSettings.WildMode check, insert before
+					// Need to move labels to our instruction because previous check jumps to one of them, skipping our call
+					var existingLabels = enumerator.Current.labels;
+					enumerator.Current.labels = new List<Label>() { labelWildMode };
+					// Load the first argument - Pawn
+					yield return new CodeInstruction(OpCodes.Ldarg_0) { labels = existingLabels };
+					// Call the check. Consumes pawn and pushes bool
+					yield return CodeInstruction.Call(typeof(RJW_Patch_CannotRapeBecauseIdeo), nameof(IdeoCanRape));;
+					// If bool is true, jump to the next check
+					yield return new CodeInstruction(OpCodes.Brtrue_S, labelWildMode);
+					// The bool was false, push false and exit the method
+					yield return new CodeInstruction(OpCodes.Ldc_I4_0);
+					yield return new CodeInstruction(OpCodes.Ret);
+					done = true;
+				}
+
+				yield return enumerator.Current;
+			}
+		}
+
+		public static bool IdeoCanRape(Pawn pawn) => RsiDefOf.HistoryEvent.RSI_Raped.CreateEvent(pawn).DoerWillingToDo();
+	}
+
 	[HarmonyPatch(typeof(xxx), nameof(xxx.is_rapist))]
 	public static class RJW_Patch_is_rapist
 	{
-- 
GitLab