Fixed: Pawns raping despite Rape-Abhorrent precept

This commit is contained in:
amevarashi 2023-11-06 16:28:08 +05:00
parent 472933e192
commit 71df71a0eb
2 changed files with 47 additions and 0 deletions

View File

@ -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));

View File

@ -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
{