using System.Collections.Generic; using System.Linq; using Verse; using Verse.AI; using Verse.AI.Group; using RimWorld; using rjw; using UnityEngine; using HarmonyLib; namespace Privacy_Please { public static class SexInteractionUtility { public static bool PawnCaughtLovinByWitness(Pawn pawn, Pawn witness) { return true; if (witness == null || pawn == witness || (pawn.IsMasturbating() == false && pawn.IsHavingSex() == false) || witness.IsUnfazedBySex() == false || witness.CanSee(pawn) == false) { return false; } List sexParticipants = pawn.GetAllSexParticipants(); bool witnessIsApproachingSexParticipant = witness.jobs.curDriver is JobDriver_SexBaseInitiator && sexParticipants.Contains((witness.jobs.curDriver as JobDriver_SexBaseInitiator).Partner); if (sexParticipants.Contains(witness) || witnessIsApproachingSexParticipant) { return false; } return true; } public static bool PawnIsCheatingOnPartner(Pawn pawn, Pawn partner) { List spouses = pawn.GetSpouses(false); if (BasicSettings.worryAboutInfidelity == false || partner.IsLoverOfOther(pawn) == false || pawn.HasTrait("Polygamous") || partner.HasTrait("Polygamous") || partner.IsMasturbating() || partner.IsHavingSex() == false || partner.GetSexPartner()?.Dead == true || partner.GetSexPartner()?.IsAnimal() == true || partner.GetAllSexParticipants().Contains(pawn) || (spouses.NullOrEmpty() == false && partner.GetAllSexParticipants().Any(x => spouses.Contains(x)))) { return false; } return true; } public static bool SexParticipantsIncludesACheatingPartner(Pawn pawn, List participants) { foreach (Pawn participant in participants) { if (PawnIsCheatingOnPartner(pawn, participant)) { return true; } } return false; } public static bool CouldInvitePasserbyForSex(Pawn passerby, List participants) { if (passerby == null || participants.Contains(passerby) || passerby.IsUnfazedBySex() == false || participants.All(x => x.CanSee(passerby) == false)) { return false; } if (participants.Count > 2 || participants.Any(x => x.IsForbidden(passerby) || x.HostileTo(passerby) || PawnIsCheatingOnPartner(x, passerby)) || CasualSex_Helper.CanHaveSex(passerby) == false || xxx.IsTargetPawnOkay(passerby) == false) { return false; } if (passerby.MentalState != null || passerby.jobs.curDriver is JobDriver_Flee || passerby.jobs.curDriver is JobDriver_AttackMelee || passerby.jobs.curDriver is JobDriver_Vomit) { return false; } if (SexUtility.ReadyForHookup(passerby) && (passerby?.jobs?.curJob == null || (passerby.jobs.curJob.playerForced == false && CasualSex_Helper.quickieAllowedJobs.Contains(passerby.jobs.curJob.def))) && participants.Any(x => SexAppraiser.would_fuck(x, passerby) > 0.1f && SexAppraiser.would_fuck(passerby, x) > 0.1f) && participants.All(x => SexAppraiser.would_fuck(x, passerby, false, false, true) > 0.1f && SexAppraiser.would_fuck(passerby, x, false, false, true) > 0.1f)) { return true; } return false; } public static ReactionToSexAct GetReactionToSexAct(Pawn witness, JobDriver_Sex jobDriver, bool applyThoughtDefs = false) { Pawn pawn = jobDriver.pawn; ReactionToSexAct reactionOfWitness = ReactionToSexAct.Acceptance; // Determine if there are any issues with the sex event and the witness' morals foreach (SexActReactionDef sexActReactionDef in DefDatabase.AllDefs) { var methodInfo = AccessTools.Method(typeof(SexInteractionUtility), sexActReactionDef.sexActCheck, null, null); if (methodInfo == null) { DebugMode.Message("Method '" + sexActReactionDef.sexActCheck + "' was not found"); continue; } if ((bool)methodInfo.Invoke(null, new object[] { jobDriver })) { DebugMode.Message(sexActReactionDef.defName); reactionOfWitness = sexActReactionDef.DetermineReactionOfPawns(pawn, witness, applyThoughtDefs); } } return reactionOfWitness; } public static bool SexActIsNecrophilia(JobDriver_Sex jobDriver) { return jobDriver.Partner != null && jobDriver.Partner.Dead; } public static bool SexActIsBestiality(JobDriver_Sex jobDriver) { return jobDriver.Partner != null && jobDriver.Partner.RaceProps.Animal; } public static bool SexActIsRape(JobDriver_Sex jobDriver) { return jobDriver is JobDriver_Rape || jobDriver is JobDriver_RapeEnemy || jobDriver is JobDriver_SexBaseRecieverRaped; } public static bool SexActIsXenophilia(JobDriver_Sex jobDriver) { return jobDriver.Partner != null && jobDriver.Partner.def.defName != jobDriver.pawn.def.defName; } public static bool SexActIsMasturbation(JobDriver_Sex jobDriver) { return jobDriver.pawn.IsMasturbating(); } public static bool SexActIsExhibitionism(JobDriver_Sex jobDriver) { return jobDriver.pawn.IsHavingSex(); } public static bool SexActIsInfidelity(JobDriver_Sex jobDriver) { return jobDriver.pawn.IsHavingSex(); } } }