using System.Collections.Generic; using System.Linq; using UnityEngine; using HarmonyLib; using RimWorld; using Verse; using Verse.AI; using rjw; namespace Privacy_Please { [HarmonyPatch(typeof(JobDriver_Sex), "setup_ticks")] public static class HarmonyPatch_JobDriver_Sex_setup_ticks { public static void Postfix(ref JobDriver_Sex __instance) { Pawn pawn = __instance.pawn; // Invite another for a threesome? if (RJWHookupSettings.QuickHookupsEnabled && __instance is JobDriver_SexBaseInitiator && pawn.GetAllSexParticipants().Count == 2 && (__instance is JobDriver_JoinInSex) == false && Random.value < BasicSettings.chanceForOtherToJoinInSex) { DebugMode.Message("Find another to join in sex"); List candidates = new List(); float radius = 4f; foreach (Thing thing in GenRadial.RadialDistinctThingsAround(pawn.Position, pawn.Map, radius, true)) { Pawn other = thing as Pawn; ThoughtDef thoughtDef = SexInteractionUtility.GetThoughtsAboutSexAct(other, __instance, out Precept precept); // Find candidates to invite if (other != null && thoughtDef?.hediff == null && SexInteractionUtility.CouldInvitePasserbyForSex(other, pawn.GetAllSexParticipants())) { DebugMode.Message(other.NameShortColored + " is a potential candidate"); candidates.Add(other); } } // Invite a random candidate (weighted by attraction) if (candidates.Count > 0) { Pawn invitedPawn = candidates.RandomElementByWeight(x => SexAppraiser.would_fuck(pawn, x, false, false, true) + SexAppraiser.would_fuck(pawn.GetSexPartner(), x, false, false, true)); pawn.GetSexInitiator().IsInBed(out Building bed); DebugMode.Message(invitedPawn.NameShortColored + " was invited to join in sex"); Job job = new Job(DefDatabase.GetNamed("JoinInSex", false), pawn.GetSexPartner(), bed); invitedPawn.jobs.TryTakeOrderedJob(job); } } } } [HarmonyPatch(typeof(JobDriver_Sex), "SexTick")] public static class HarmonyPatch_JobDriver_Sex_SexTick { // If pawns don't have privacy, they'll stop having sex public static void Postfix(ref JobDriver_Sex __instance, Pawn pawn) { if (pawn.IsHashIntervalTick(90)) { if (pawn.IsMasturbating() && pawn.HasPrivacy(8f) == false) { pawn.jobs.EndCurrentJob(JobCondition.InterruptForced, false, false); } else if (pawn.IsHavingSex()) { bool havePrivacy = true; List participants = pawn.GetAllSexParticipants(); foreach (Pawn participant in participants) { if (participant.HasPrivacy(8f) == false) { havePrivacy = false; } } if (__instance.Sexprops != null && (__instance.Sexprops.isRape || __instance.Sexprops.isWhoring)) { return; } if (havePrivacy == false) { foreach (Pawn participant in participants) { participant.jobs.EndCurrentJob(JobCondition.InterruptForced, false, false); } } } } } } }