2020-04-09 00:43:01 +00:00
using System ;
using System.Collections.Generic ;
using System.Linq ;
using System.Text ;
using System.Threading.Tasks ;
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 ) {
if ( __instance is JobDriver_JoinInBed ) {
Log . Warning ( "Tried to start wrong JobDriver with Rimworld-Animations installed. If you see this warning soon after installing this mod, it's fine and animated sex will start soon. If you see this a long time after installing, that's a problem." ) ;
return ;
}
Pawn Target = __instance . Target ;
Pawn pawn = __instance . pawn ;
Building_Bed bed = __instance . Bed ;
if ( __instance is JobDriver_BestialityForFemale )
bed = ( __instance as JobDriver_BestialityForFemale ) . Bed ;
else if ( __instance is JobDriver_WhoreIsServingVisitors ) {
bed = ( __instance as JobDriver_WhoreIsServingVisitors ) . Bed ;
}
else if ( __instance is JobDriver_SexCasualForAnimation ) {
bed = ( __instance as JobDriver_SexCasualForAnimation ) . Bed ;
}
if ( __instance . Target . jobs ? . curDriver is JobDriver_SexBaseReciever ) {
if ( ! ( Target . jobs . curDriver as JobDriver_SexBaseReciever ) . parteners . Contains ( pawn ) ) {
( Target . jobs . curDriver as JobDriver_SexBaseReciever ) . parteners . Add ( pawn ) ;
}
if ( bed ! = null ) {
RerollAnimations ( Target , __instance . duration , bed as Thing ) ;
}
else {
RerollAnimations ( Target , __instance . duration ) ;
}
}
}
public static void RerollAnimations ( Pawn pawn , int duration , Thing bed = null ) {
if ( pawn = = null | | ! ( pawn . jobs ? . curDriver is JobDriver_SexBaseReciever ) ) {
Log . Message ( "Error: Tried to reroll animations when pawn isn't sexing" ) ;
return ;
}
List < Pawn > pawnsToAnimate = ( pawn . jobs . curDriver as JobDriver_SexBaseReciever ) . parteners . ToList ( ) ;
if ( ! pawnsToAnimate . Contains ( pawn ) ) {
pawnsToAnimate = pawnsToAnimate . Append ( pawn ) . ToList ( ) ;
}
AnimationDef anim = AnimationUtility . tryFindAnimation ( ref pawnsToAnimate ) ;
if ( anim ! = null ) {
Log . Message ( "Now playing " + anim . defName ) ;
bool mirror = GenTicks . TicksGame % 2 = = 0 ;
2020-04-10 00:03:56 +00:00
IntVec3 pos = pawn . Position ;
2020-04-09 00:43:01 +00:00
for ( int i = 0 ; i < pawnsToAnimate . Count ; i + + ) {
if ( bed ! = null )
pawnsToAnimate [ i ] . TryGetComp < CompBodyAnimator > ( ) . setAnchor ( bed ) ;
2020-04-10 00:03:56 +00:00
else {
pawnsToAnimate [ i ] . TryGetComp < CompBodyAnimator > ( ) . setAnchor ( pos ) ;
}
2020-04-09 00:43:01 +00:00
pawnsToAnimate [ i ] . TryGetComp < CompBodyAnimator > ( ) . StartAnimation ( anim , i , mirror ) ;
( pawnsToAnimate [ i ] . jobs . curDriver as JobDriver_Sex ) . ticks_left = anim . animationTimeTicks ;
( pawnsToAnimate [ i ] . jobs . curDriver as JobDriver_Sex ) . ticksLeftThisToil = anim . animationTimeTicks ;
( pawnsToAnimate [ i ] . jobs . curDriver as JobDriver_Sex ) . duration = anim . animationTimeTicks ;
( pawnsToAnimate [ i ] . jobs . curDriver as JobDriver_Sex ) . ticks_remaining = anim . animationTimeTicks ;
}
}
else {
Log . Message ( "Anim not found" ) ;
//if pawn isn't already animating,
if ( ! pawn . TryGetComp < CompBodyAnimator > ( ) . isAnimating ) {
( pawn . jobs . curDriver as JobDriver_SexBaseReciever ) . increase_time ( duration ) ;
//they'll just do the thrusting anim
}
}
}
}
[HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "End")]
static class HarmonyPatch_JobDriver_SexBaseInitiator_End {
public static void Postfix ( ref JobDriver_SexBaseInitiator __instance ) {
2020-04-11 05:03:25 +00:00
//Stolen from vanilla lovin
//to make sure vanilla lovin variables are set
if ( __instance . pawn ? . mindState ? . canLovinTick ! = null ) {
SimpleCurve LovinIntervalHoursFromAgeCurve = new SimpleCurve
{
new CurvePoint ( 16f , 1.5f ) ,
new CurvePoint ( 22f , 1.5f ) ,
new CurvePoint ( 30f , 4f ) ,
new CurvePoint ( 50f , 12f ) ,
new CurvePoint ( 75f , 36f )
} ;
int ticksToNextLovin ;
if ( DebugSettings . alwaysDoLovin ) {
ticksToNextLovin = 100 ;
} else {
float centerX = LovinIntervalHoursFromAgeCurve . Evaluate ( __instance . pawn . ageTracker . AgeBiologicalYearsFloat ) ;
centerX = Rand . Gaussian ( centerX , 0.3f ) ;
if ( centerX < 0.5f ) {
centerX = 0.5f ;
}
ticksToNextLovin = ( int ) ( centerX * 2500f ) ;
}
__instance . pawn . mindState . canLovinTick = Find . TickManager . TicksGame + ticksToNextLovin ;
}
2020-04-09 00:43:01 +00:00
if ( __instance . Target . jobs ? . curDriver is JobDriver_SexBaseReciever ) {
if ( __instance . pawn . TryGetComp < CompBodyAnimator > ( ) . isAnimating ) {
List < Pawn > parteners = ( __instance . Target . jobs . curDriver as JobDriver_SexBaseReciever ) . parteners ;
for ( int i = 0 ; i < parteners . Count ; i + + ) {
//prevents pawns who started a new anim from stopping their new anim
if ( ! ( ( parteners [ i ] . jobs . curDriver as JobDriver_SexBaseInitiator ) ! = null & & ( parteners [ i ] . jobs . curDriver as JobDriver_SexBaseInitiator ) . Target ! = __instance . pawn ) )
parteners [ i ] . TryGetComp < CompBodyAnimator > ( ) . isAnimating = false ;
}
__instance . Target . TryGetComp < CompBodyAnimator > ( ) . isAnimating = false ;
if ( xxx . is_human ( __instance . Target ) ) {
__instance . Target . Drawer . renderer . graphics . ResolveApparelGraphics ( ) ;
PortraitsCache . SetDirty ( __instance . Target ) ;
}
}
( __instance . Target . jobs . curDriver as JobDriver_SexBaseReciever ) . parteners . Remove ( __instance . pawn ) ;
}
if ( xxx . is_human ( __instance . pawn ) ) {
__instance . pawn . Drawer . renderer . graphics . ResolveApparelGraphics ( ) ;
PortraitsCache . SetDirty ( __instance . pawn ) ;
}
}
}
}