using System; using System.Collections.Generic; using System.Linq; using HarmonyLib; using RimWorld; using Verse; using rjw; namespace Rimworld_Animations { [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "Start")] static class HarmonyPatch_JobDriver_SexBaseInitiator_Start { public static void Postfix(ref JobDriver_SexBaseInitiator __instance) { /* These particular jobs need special code don't play anim for now */ if(__instance is JobDriver_Masturbate || __instance is JobDriver_ViolateCorpse) { return; } if(!RJWAnimationSettings.PlayAnimForNonsexualActs && NonSexualAct(__instance)) { return; } Pawn pawn = __instance.pawn; Pawn partner = __instance.Target as Pawn; Building_Bed bed = __instance.Bed; if (partner?.jobs?.curDriver is JobDriver_SexBaseReciever partnerSexBaseReceiver) { Pawn Target = __instance.Target as Pawn; int preAnimDuration = __instance.duration; List participants = partnerSexBaseReceiver.parteners.Append(partner).ToList(); GroupAnimationDef groupAnimation = AnimationUtility.FindGroupAnimation(participants, out int reorder); if (groupAnimation != null) { Thing anchor; if (bed != null) anchor = bed; else anchor = partner; AnimationUtility.StartGroupAnimation(participants, groupAnimation, reorder, anchor); int animTicks = AnimationUtility.GetAnimationLength(pawn); foreach(Pawn participant in participants) { (participant.jobs.curDriver as JobDriver_Sex).ticks_left = animTicks; (participant.jobs.curDriver as JobDriver_Sex).sex_ticks = animTicks; (participant.jobs.curDriver as JobDriver_Sex).orgasmStartTick = animTicks; (participant.jobs.curDriver as JobDriver_Sex).duration = animTicks; } } } } static IEnumerable NonSexActRulePackDefNames = new String[] { "MutualHandholdingRP", "MutualMakeoutRP", }; public static bool NonSexualAct(JobDriver_SexBaseInitiator sexBaseInitiator) { if(NonSexActRulePackDefNames.Contains(sexBaseInitiator.Sexprops.rulePack)) { return true; } return false; } } [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "End")] static class HarmonyPatch_JobDriver_SexBaseInitiator_End { public static void Prefix(ref JobDriver_SexBaseInitiator __instance) { //stop pawn animating AnimationUtility.StopGroupAnimation(__instance.pawn); //stop partner animating if (__instance.Partner is Pawn partner) { AnimationUtility.StopGroupAnimation(partner); } //stop partner's other partners (threesome pawns) animating if (__instance.Partner.jobs.curDriver is JobDriver_SexBaseReciever partnerReceiverJob) { foreach(Pawn pawn in partnerReceiverJob.parteners) { if (pawn != null) AnimationUtility.StopGroupAnimation(pawn); } } } } }