Compare commits

...

2 commits

Author SHA1 Message Date
c0ffeeeeeeee
1a66bae865 Merge branch '1.5_solo_anims' into '1.5'
Patch to allow solo anims

See merge request c0ffeeeeeeee/rimworld-animations!22
2024-08-01 23:15:22 +00:00
AbstractConcept
03a41e32c0 Patch to allow solo anims 2024-08-01 12:53:40 -05:00
2 changed files with 122 additions and 81 deletions

View file

@ -6,93 +6,134 @@ using RimWorld;
using Verse;
using rjw;
namespace Rimworld_Animations {
namespace Rimworld_Animations
{
[HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "Start")]
static class HarmonyPatch_JobDriver_SexBaseInitiator_Start {
public static void Postfix(ref JobDriver_SexBaseInitiator __instance) {
Pawn pawn = __instance.pawn;
Pawn partner = __instance.Target as Pawn;
if (partner?.jobs?.curDriver is JobDriver_SexBaseReciever partnerSexBaseReceiver) {
Pawn Target = __instance.Target as Pawn;
List<Pawn> participants = partnerSexBaseReceiver.parteners.Append(partner).ToList();
GroupAnimationDef groupAnimation = AnimationUtility.FindGroupAnimation(participants, out int reorder);
if (groupAnimation != null)
{
Thing anchor = (Thing)__instance.Bed ?? partner;
AnimationUtility.StartGroupAnimation(participants, groupAnimation, reorder, anchor);
int animTicks = AnimationUtility.GetAnimationLength(pawn);
foreach(Pawn participant in participants)
{
if (RJWAnimationSettings.debugMode)
{
Log.Message("Participant: " + participant.Name);
Log.Message("JobDriver: " + participant.CurJobDef.defName);
}
//null ref check for pawns that might have lost their jobs or become null for some reason
if (participant?.jobs?.curDriver is JobDriver_Sex participantJobDriver)
{
participantJobDriver.ticks_left = animTicks;
participantJobDriver.sex_ticks = animTicks;
participantJobDriver.orgasmStartTick = animTicks;
participantJobDriver.duration = animTicks;
}
}
}
}
}
static IEnumerable<String> NonSexActRulePackDefNames = new String[]
{
"MutualHandholdingRP",
"MutualMakeoutRP",
};
public static bool NonSexualAct(JobDriver_SexBaseInitiator sexBaseInitiator)
static class HarmonyPatch_JobDriver_SexBaseInitiator_Start
{
public static void Postfix(ref JobDriver_SexBaseInitiator __instance)
{
if(NonSexActRulePackDefNames.Contains(sexBaseInitiator.Sexprops.rulePack))
Pawn pawn = __instance.pawn;
Pawn partner = __instance.Target as Pawn;
if (partner == null)
partner = pawn;
List<Pawn> participants = GetAllSexParticipants(pawn);
GroupAnimationDef groupAnimation = AnimationUtility.FindGroupAnimation(participants, out int reorder);
if (groupAnimation != null)
{
return true;
}
return false;
}
}
Thing anchor = (Thing)__instance.Bed ?? partner;
AnimationUtility.StartGroupAnimation(participants, groupAnimation, reorder, anchor);
int animTicks = AnimationUtility.GetAnimationLength(pawn);
[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
//added null ref checks for instances when pawns get nulled or lose their jobs
if (__instance.Partner?.jobs?.curDriver is JobDriver_SexBaseReciever partnerReceiverJob)
{
foreach(Pawn pawn in partnerReceiverJob.parteners)
foreach (Pawn participant in participants)
{
if (pawn != null) AnimationUtility.StopGroupAnimation(pawn);
}
if (RJWAnimationSettings.debugMode)
{
Log.Message("Participant: " + participant.Name);
Log.Message("JobDriver: " + participant.CurJobDef.defName);
}
//null ref check for pawns that might have lost their jobs or become null for some reason
if (participant?.jobs?.curDriver is JobDriver_Sex participantJobDriver)
{
participantJobDriver.ticks_left = animTicks;
participantJobDriver.sex_ticks = animTicks;
participantJobDriver.orgasmStartTick = animTicks;
participantJobDriver.duration = animTicks;
}
}
}
}
}
}
public static List<Pawn> GetAllSexParticipants(this Pawn pawn)
{
List<Pawn> participants = new List<Pawn>();
if (pawn?.jobs?.curDriver == null ||
(pawn.jobs.curDriver is JobDriver_Sex) == false)
return participants;
var receiver = pawn.GetSexReceiver();
if (receiver != null)
{
participants = (receiver.jobs.curDriver as JobDriver_SexBaseReciever).parteners;
participants.AddDistinct(receiver);
return participants;
}
participants.AddDistinct(pawn);
return participants;
}
public static Pawn GetSexReceiver(this Pawn pawn)
{
if (pawn?.jobs?.curDriver == null)
return null;
if (pawn.jobs.curDriver is JobDriver_SexBaseReciever)
return pawn;
JobDriver_SexBaseInitiator jobDriver = pawn.jobs.curDriver as JobDriver_SexBaseInitiator;
if (jobDriver?.Partner?.jobs?.curDriver == null)
return null;
if (jobDriver.Partner.jobs.curDriver is JobDriver_SexBaseReciever)
return jobDriver.Partner;
return null;
}
static IEnumerable<String> 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
//added null ref checks for instances when pawns get nulled or lose their jobs
if (__instance.Partner?.jobs?.curDriver is JobDriver_SexBaseReciever partnerReceiverJob)
{
foreach (Pawn pawn in partnerReceiverJob.parteners)
{
if (pawn != null) AnimationUtility.StopGroupAnimation(pawn);
}
}
}
}
}