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