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 RimWorld ;
using UnityEngine ;
using Verse ;
using Verse.AI ;
namespace Rimworld_Animations {
public static class AnimationUtility {
/ *
Note : always make the list in this order :
Female pawns , animal female pawns , male pawns , animal male pawns
* /
2020-07-14 19:12:09 +00:00
public static AnimationDef tryFindAnimation ( ref List < Pawn > participants , rjw . xxx . rjwSextype sexType = 0 , rjw . SexProps sexProps = null ) {
2020-04-09 00:43:01 +00:00
2020-04-26 15:03:57 +00:00
//aggressors last
2020-04-22 19:48:49 +00:00
participants = participants . OrderBy ( p = > p . jobs . curDriver is rjw . JobDriver_SexBaseInitiator ) . ToList ( ) ;
2020-04-09 00:43:01 +00:00
2020-07-14 19:12:09 +00:00
participants = participants . OrderBy ( p = > p = = sexProps . Giver ) . ToList ( ) ;
2020-07-11 21:20:12 +00:00
participants = participants . OrderByDescending ( p = > rjw . GenderHelper . GetSex ( p ) = = rjw . GenderHelper . Sex . futa ) . ToList ( ) ;
2020-07-09 22:20:17 +00:00
//pawns that can fuck last
2020-06-04 21:31:41 +00:00
participants = participants . OrderBy ( p = > rjw . xxx . can_fuck ( p ) ) . ToList ( ) ;
2020-04-09 00:43:01 +00:00
List < Pawn > localParticipants = new List < Pawn > ( participants ) ;
IEnumerable < AnimationDef > options = DefDatabase < AnimationDef > . AllDefs . Where ( ( AnimationDef x ) = > {
2020-06-02 20:20:38 +00:00
2020-04-09 00:43:01 +00:00
if ( x . actors . Count ! = localParticipants . Count ) {
return false ;
}
for ( int i = 0 ; i < x . actors . Count ; i + + ) {
2020-06-02 20:20:38 +00:00
if ( rjw . RJWPreferenceSettings . Malesex = = rjw . RJWPreferenceSettings . AllowedSex . Nohomo ) {
if ( rjw . xxx . is_male ( localParticipants [ i ] ) & & x . actors [ i ] . isFucked ) {
return false ;
}
}
if ( ( x . actors [ i ] . blacklistedRaces ! = null ) & & x . actors [ i ] . blacklistedRaces . Contains ( localParticipants [ i ] . def . defName ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
2020-04-23 00:09:24 +00:00
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " is blacklisted" ) ;
return false ;
}
2020-04-09 00:43:01 +00:00
if ( x . actors [ i ] . defNames . Contains ( "Human" ) ) {
if ( ! rjw . xxx . is_human ( localParticipants [ i ] ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
2020-04-09 00:43:01 +00:00
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " is not human" ) ;
2020-08-28 07:24:55 +00:00
2020-04-09 00:43:01 +00:00
return false ;
}
2020-07-07 21:54:59 +00:00
}
else if ( ! x . actors [ i ] . bodyDefTypes . Contains ( localParticipants [ i ] . RaceProps . body ) ) {
2020-04-09 00:43:01 +00:00
if ( ! x . actors [ i ] . defNames . Contains ( localParticipants [ i ] . def . defName ) ) {
if ( rjw . RJWSettings . DevMode ) {
2020-04-20 19:01:31 +00:00
string animInfo = x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " is not " ;
2020-04-09 00:43:01 +00:00
foreach ( String defname in x . actors [ i ] . defNames ) {
2020-04-20 19:01:31 +00:00
animInfo + = defname + ", " ;
2020-04-09 00:43:01 +00:00
}
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( animInfo ) ;
2020-04-09 00:43:01 +00:00
}
return false ;
}
}
2020-07-09 22:20:17 +00:00
//genitals checking
if ( x . actors [ i ] . requiredGenitals ! = null ) {
if ( x . actors [ i ] . requiredGenitals . Contains ( "Vagina" ) ) {
2020-04-09 00:43:01 +00:00
2020-07-09 22:20:17 +00:00
if ( ! rjw . Genital_Helper . has_vagina ( localParticipants [ i ] ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " doesn't have vagina" ) ;
2020-07-09 22:20:17 +00:00
return false ;
}
2020-04-09 00:43:01 +00:00
2020-07-09 22:20:17 +00:00
}
if ( x . actors [ i ] . requiredGenitals . Contains ( "Penis" ) ) {
if ( ! ( rjw . Genital_Helper . has_multipenis ( localParticipants [ i ] ) | | rjw . Genital_Helper . has_penis_infertile ( localParticipants [ i ] ) | | rjw . Genital_Helper . has_penis_fertile ( localParticipants [ i ] ) ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " doesn't have penis" ) ;
2020-07-09 22:20:17 +00:00
return false ;
}
}
if ( x . actors [ i ] . requiredGenitals . Contains ( "Mouth" ) ) {
if ( ! rjw . Genital_Helper . has_mouth ( localParticipants [ i ] ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " doesn't have mouth" ) ;
2020-07-09 22:20:17 +00:00
return false ;
}
2020-04-09 00:43:01 +00:00
2020-07-09 22:20:17 +00:00
}
if ( x . actors [ i ] . requiredGenitals . Contains ( "Anus" ) ) {
if ( ! rjw . Genital_Helper . has_anus ( localParticipants [ i ] ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " doesn't have anus" ) ;
2020-07-09 22:20:17 +00:00
return false ;
}
}
if ( x . actors [ i ] . requiredGenitals . Contains ( "Breasts" ) ) {
if ( ! rjw . Genital_Helper . can_do_breastjob ( localParticipants [ i ] ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " doesn't have breasts" ) ;
2020-07-09 22:20:17 +00:00
return false ;
}
}
2020-07-10 00:07:17 +00:00
if ( x . actors [ i ] . requiredGenitals . Contains ( "NoVagina" ) ) {
if ( rjw . Genital_Helper . has_vagina ( localParticipants [ i ] ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " has vagina" ) ;
2020-07-10 00:07:17 +00:00
return false ;
}
}
if ( x . actors [ i ] . requiredGenitals . Contains ( "NoPenis" ) ) {
if ( ( rjw . Genital_Helper . has_multipenis ( localParticipants [ i ] ) | | rjw . Genital_Helper . has_penis_infertile ( localParticipants [ i ] ) | | rjw . Genital_Helper . has_penis_fertile ( localParticipants [ i ] ) ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " has penis" ) ;
2020-07-10 00:07:17 +00:00
return false ;
}
}
if ( x . actors [ i ] . requiredGenitals . Contains ( "NoMouth" ) ) {
if ( rjw . Genital_Helper . has_mouth ( localParticipants [ i ] ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " has mouth" ) ;
2020-07-10 00:07:17 +00:00
return false ;
}
}
if ( x . actors [ i ] . requiredGenitals . Contains ( "NoAnus" ) ) {
if ( rjw . Genital_Helper . has_anus ( localParticipants [ i ] ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " has anus" ) ;
2020-07-10 00:07:17 +00:00
return false ;
}
}
if ( x . actors [ i ] . requiredGenitals . Contains ( "NoBreasts" ) ) {
if ( rjw . Genital_Helper . can_do_breastjob ( localParticipants [ i ] ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " has breasts" ) ;
2020-07-10 00:07:17 +00:00
return false ;
}
}
2020-04-09 00:43:01 +00:00
}
2020-07-09 22:20:17 +00:00
2020-04-09 00:43:01 +00:00
//TESTING ANIMATIONS ONLY REMEMBER TO COMMENT OUT BEFORE PUSH
2020-06-17 02:37:30 +00:00
/ *
2020-07-15 02:20:41 +00:00
if ( x . defName ! = "Cunnilingus" )
2020-04-09 00:43:01 +00:00
return false ;
2020-06-17 02:37:30 +00:00
* /
2020-07-09 22:20:17 +00:00
2020-04-09 00:43:01 +00:00
if ( x . actors [ i ] . isFucking & & ! rjw . xxx . can_fuck ( localParticipants [ i ] ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " can't fuck" ) ;
2020-04-09 00:43:01 +00:00
return false ;
}
if ( x . actors [ i ] . isFucked & & ! rjw . xxx . can_be_fucked ( localParticipants [ i ] ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( x . defName . ToStringSafe ( ) + " not selected -- " + localParticipants [ i ] . def . defName . ToStringSafe ( ) + " " + localParticipants [ i ] . Name . ToStringSafe ( ) + " can't be fucked" ) ;
2020-04-09 00:43:01 +00:00
return false ;
}
}
return true ;
} ) ;
2020-04-18 15:24:09 +00:00
List < AnimationDef > optionsWithSexType = options . ToList ( ) . FindAll ( x = > x . sexTypes . Contains ( sexType ) ) ;
2020-04-20 19:01:31 +00:00
List < AnimationDef > optionsWithSexTypeAndInitiator = optionsWithSexType . FindAll ( x = > {
bool initiatorsAlignWithSexType = true ;
for ( int i = 0 ; i < x . actors . Count ; i + + ) {
//if the animation not for initiators, but an initiator is playing it
2020-07-14 19:12:09 +00:00
if ( sexProps ! = null ) {
2020-08-26 23:19:08 +00:00
if ( ( x . actors [ i ] . initiator & & localParticipants [ i ] = = sexProps . Reciever ) | | ( ! x . actors [ i ] . initiator & & localParticipants [ i ] = = sexProps . Giver ) ) {
2020-07-14 19:12:09 +00:00
initiatorsAlignWithSexType = false ;
}
}
else if ( x . actors [ i ] . initiator & & ! ( localParticipants [ i ] . jobs . curDriver is rjw . JobDriver_SexBaseInitiator ) ) {
2020-04-20 19:01:31 +00:00
initiatorsAlignWithSexType = false ;
}
}
return initiatorsAlignWithSexType ;
} ) ;
List < AnimationDef > optionsWithInitiator = options . ToList ( ) . FindAll ( x = > {
bool initiatorsAlignWithSexType = true ;
for ( int i = 0 ; i < x . actors . Count ; i + + ) {
//if the animation not for initiators, but an initiator is playing it
2020-07-14 19:12:09 +00:00
if ( sexProps ! = null ) {
if ( x . actors [ i ] . initiator & & localParticipants [ i ] = = sexProps . Giver ) {
initiatorsAlignWithSexType = false ;
}
}
else if ( x . actors [ i ] . initiator & & ! ( localParticipants [ i ] . jobs . curDriver is rjw . JobDriver_SexBaseInitiator ) ) {
2020-04-20 19:01:31 +00:00
initiatorsAlignWithSexType = false ;
}
}
return initiatorsAlignWithSexType ;
} ) ;
if ( optionsWithSexTypeAndInitiator . Any ( ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( "Selecting animation for rjwSexType " + sexType . ToStringSafe ( ) + " and initiators..." ) ;
2020-04-20 19:01:31 +00:00
return optionsWithSexType . RandomElement ( ) ;
}
2020-04-18 15:24:09 +00:00
if ( optionsWithSexType . Any ( ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( "Selecting animation for rjwSexType " + sexType . ToStringSafe ( ) + "..." ) ;
2020-04-18 15:24:09 +00:00
return optionsWithSexType . RandomElement ( ) ;
}
2020-04-20 19:01:31 +00:00
if ( optionsWithInitiator . Any ( ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( "Selecting animation for initiators..." ) ;
2020-04-20 19:01:31 +00:00
}
2020-04-09 00:43:01 +00:00
if ( options ! = null & & options . Any ( ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
Log . Message ( "Randomly selecting animation..." ) ;
2020-04-09 00:43:01 +00:00
return options . RandomElement ( ) ;
}
else
return null ;
}
public static void RenderPawnHeadMeshInAnimation ( Mesh mesh , Vector3 loc , Quaternion quaternion , Material material , bool portrait , Pawn pawn ) {
2020-05-30 06:10:31 +00:00
if ( pawn = = null | | pawn . Map ! = Find . CurrentMap ) {
2020-04-09 00:43:01 +00:00
GenDraw . DrawMeshNowOrLater ( mesh , loc , quaternion , material , portrait ) ;
return ;
}
CompBodyAnimator pawnAnimator = pawn . TryGetComp < CompBodyAnimator > ( ) ;
if ( pawnAnimator = = null | | ! pawnAnimator . isAnimating | | portrait ) {
GenDraw . DrawMeshNowOrLater ( mesh , loc , quaternion , material , portrait ) ;
} else {
Vector3 pawnHeadPosition = pawnAnimator . getPawnHeadPosition ( ) ;
pawnHeadPosition . y = loc . y ;
GenDraw . DrawMeshNowOrLater ( mesh , pawnHeadPosition , Quaternion . AngleAxis ( pawnAnimator . headAngle , Vector3 . up ) , material , portrait ) ;
}
}
2020-04-30 04:34:15 +00:00
public static void RenderPawnHeadMeshInAnimation ( Mesh mesh , Vector3 loc , Quaternion quaternion , Material material , bool portrait , Pawn pawn , float bodySizeFactor = 1 ) {
if ( pawn = = null ) {
GenDraw . DrawMeshNowOrLater ( mesh , loc , quaternion , material , portrait ) ;
return ;
}
CompBodyAnimator pawnAnimator = pawn . TryGetComp < CompBodyAnimator > ( ) ;
if ( pawnAnimator = = null | | ! pawnAnimator . isAnimating | | portrait ) {
GenDraw . DrawMeshNowOrLater ( mesh , loc , quaternion , material , portrait ) ;
}
else {
Vector3 pawnHeadPosition = pawnAnimator . getPawnHeadPosition ( ) ;
pawnHeadPosition . x * = bodySizeFactor ;
pawnHeadPosition . x * = bodySizeFactor ;
pawnHeadPosition . y = loc . y ;
GenDraw . DrawMeshNowOrLater ( mesh , pawnHeadPosition , Quaternion . AngleAxis ( pawnAnimator . headAngle , Vector3 . up ) , material , portrait ) ;
}
}
2020-04-09 00:43:01 +00:00
}
}