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
2021-03-07 01:02:45 +00:00
participants =
participants . OrderBy ( p = > p . jobs . curDriver is rjw . JobDriver_SexBaseInitiator )
. OrderBy ( p = > p = = sexProps . Giver )
. OrderByDescending ( p = > rjw . GenderHelper . GetSex ( p ) = = rjw . GenderHelper . Sex . futa )
. OrderBy ( p = > rjw . xxx . can_fuck ( p ) )
. ToList ( ) ;
2020-06-04 21:31:41 +00:00
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 ;
}
}
2021-06-23 23:39:26 +00:00
if ( x . actors [ i ] . requiredGender ! = null & & ! x . actors [ i ] . requiredGender . Contains ( localParticipants [ i ] . gender . ToStringSafe < Gender > ( ) ) )
{
if ( AnimationSettings . debugMode )
{
Log . Message ( string . Concat ( new string [ ]
{
x . defName . ToStringSafe < string > ( ) ,
" not selected -- " ,
localParticipants [ i ] . def . defName . ToStringSafe < string > ( ) ,
" " ,
localParticipants [ i ] . Name . ToStringSafe < Name > ( ) ,
" does not match required gender"
2021-07-21 19:24:23 +00:00
} ) ) ;
2021-06-23 23:39:26 +00:00
}
return false ;
}
2020-06-02 20:20:38 +00:00
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
2020-04-09 00:43:01 +00:00
2021-01-30 18:25:46 +00:00
if ( ! GenitalCheckForPawn ( x . actors [ i ] . requiredGenitals , localParticipants [ i ] , out string failReason ) ) {
Debug . Log ( "Didn't select " + x . defName + ", " + localParticipants [ i ] . Name + " " + failReason ) ;
return false ;
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 ;
} ) ;
2021-01-30 18:25:46 +00:00
List < AnimationDef > optionsWithInteractionType = options . ToList ( ) . FindAll ( x = > x . interactionDefTypes ! = null & & x . interactionDefTypes . Contains ( sexProps . DictionaryKey ) ) ;
if ( optionsWithInteractionType . Any ( ) ) {
2020-08-28 07:24:55 +00:00
if ( AnimationSettings . debugMode )
2021-01-30 18:25:46 +00:00
Log . Message ( "Selecting animation for interaction type " + sexProps . DictionaryKey . defName + "..." ) ;
return optionsWithInteractionType . RandomElement ( ) ;
2020-04-20 19:01:31 +00:00
}
2021-02-19 20:52:15 +00:00
List < AnimationDef > optionsWithSexType = options . ToList ( ) . FindAll ( x = > x . sexTypes ! = null & & x . sexTypes . Contains ( sexType ) ) ;
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-10-15 23:43:33 +00:00
/ *
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-10-15 23:43:33 +00:00
* /
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 ;
}
2021-07-22 05:59:18 +00:00
public static void RenderPawnHeadMeshInAnimation1 ( Mesh mesh , Vector3 loc , Quaternion quaternion , Material material , bool drawNow , Pawn pawn ) {
2020-04-09 00:43:01 +00:00
2021-07-22 05:59:18 +00:00
if ( pawn = = null | | pawn . Map ! = Find . CurrentMap ) {
GenDraw . DrawMeshNowOrLater ( mesh , loc , quaternion , material , drawNow ) ;
2020-04-09 00:43:01 +00:00
return ;
}
CompBodyAnimator pawnAnimator = pawn . TryGetComp < CompBodyAnimator > ( ) ;
2021-07-22 05:59:18 +00:00
if ( pawnAnimator = = null | | ! pawnAnimator . isAnimating ) {
GenDraw . DrawMeshNowOrLater ( mesh , loc , quaternion , material , drawNow ) ;
2020-04-09 00:43:01 +00:00
} else {
Vector3 pawnHeadPosition = pawnAnimator . getPawnHeadPosition ( ) ;
pawnHeadPosition . y = loc . y ;
2021-07-22 05:59:18 +00:00
GenDraw . DrawMeshNowOrLater ( MeshPool . humanlikeHeadSet . MeshAt ( pawnAnimator . headFacing ) , pawnHeadPosition , Quaternion . AngleAxis ( pawnAnimator . headAngle , Vector3 . up ) , material , true ) ;
}
}
2021-07-22 23:04:21 +00:00
public static void AdjustHead ( ref Quaternion quat , ref Rot4 bodyFacing , ref Vector3 pos , ref float angle , Pawn pawn , PawnRenderFlags flags )
2021-07-22 05:59:18 +00:00
{
2021-07-22 23:04:21 +00:00
if ( flags . FlagSet ( PawnRenderFlags . Portrait ) ) return ;
2021-07-22 05:59:18 +00:00
CompBodyAnimator anim = pawn . TryGetComp < CompBodyAnimator > ( ) ;
if ( anim . isAnimating )
{
bodyFacing = anim . headFacing ;
2021-07-22 23:04:21 +00:00
angle = anim . headAngle ;
2021-07-22 05:59:18 +00:00
quat = Quaternion . AngleAxis ( anim . headAngle , Vector3 . up ) ;
pos = anim . getPawnHeadOffset ( ) ;
2020-04-09 00:43:01 +00:00
}
}
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 ) ;
}
}
2021-01-30 18:25:46 +00:00
public static bool GenitalCheckForPawn ( List < string > requiredGenitals , Pawn pawn , out string failReason ) {
failReason = null ;
if ( requiredGenitals ! = null ) {
if ( requiredGenitals . Contains ( "Vagina" ) ) {
if ( ! rjw . Genital_Helper . has_vagina ( pawn ) ) {
failReason = "missing vagina" ;
return false ;
}
}
if ( requiredGenitals . Contains ( "Penis" ) ) {
if ( ! ( rjw . Genital_Helper . has_multipenis ( pawn ) | | rjw . Genital_Helper . has_penis_infertile ( pawn ) | | rjw . Genital_Helper . has_penis_fertile ( pawn ) | | rjw . Genital_Helper . has_ovipositorM ( pawn ) | | rjw . Genital_Helper . has_ovipositorF ( pawn ) ) ) {
failReason = "missing penis" ;
return false ;
}
}
if ( requiredGenitals . Contains ( "Mouth" ) ) {
if ( ! rjw . Genital_Helper . has_mouth ( pawn ) ) {
failReason = "missing mouth" ;
return false ;
}
}
if ( requiredGenitals . Contains ( "Anus" ) ) {
if ( ! rjw . Genital_Helper . has_anus ( pawn ) ) {
failReason = "missing anus" ;
return false ;
}
}
if ( requiredGenitals . Contains ( "Breasts" ) ) {
if ( ! rjw . Genital_Helper . can_do_breastjob ( pawn ) ) {
failReason = "missing breasts" ;
return false ;
}
}
if ( requiredGenitals . Contains ( "NoVagina" ) ) {
if ( rjw . Genital_Helper . has_vagina ( pawn ) ) {
2021-03-07 01:02:45 +00:00
failReason = "has vagina" ;
2021-01-30 18:25:46 +00:00
return false ;
}
}
if ( requiredGenitals . Contains ( "NoPenis" ) ) {
if ( ( rjw . Genital_Helper . has_multipenis ( pawn ) | | rjw . Genital_Helper . has_penis_infertile ( pawn ) | | rjw . Genital_Helper . has_penis_fertile ( pawn ) ) ) {
2021-03-07 01:02:45 +00:00
failReason = "has penis" ;
2021-01-30 18:25:46 +00:00
return false ;
}
}
if ( requiredGenitals . Contains ( "NoMouth" ) ) {
if ( rjw . Genital_Helper . has_mouth ( pawn ) ) {
failReason = "has mouth" ;
return false ;
}
}
if ( requiredGenitals . Contains ( "NoAnus" ) ) {
if ( rjw . Genital_Helper . has_anus ( pawn ) ) {
failReason = "has anus" ;
return false ;
}
}
if ( requiredGenitals . Contains ( "NoBreasts" ) ) {
if ( rjw . Genital_Helper . can_do_breastjob ( pawn ) ) {
failReason = "has breasts" ;
return false ;
}
}
}
return true ;
}
2021-07-21 19:24:23 +00:00
public static Rot4 PawnHeadRotInAnimation ( Pawn pawn , Rot4 regularPos )
{
2021-07-21 20:25:06 +00:00
Debug . Log ( "Test" ) ;
2021-07-21 19:24:23 +00:00
if ( pawn ? . TryGetComp < CompBodyAnimator > ( ) ! = null & & pawn . TryGetComp < CompBodyAnimator > ( ) . isAnimating )
{
return pawn . TryGetComp < CompBodyAnimator > ( ) . headFacing ;
}
return regularPos ;
}
2020-04-09 00:43:01 +00:00
}
}