2022-09-10 01:22:08 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using Verse;
|
|
|
|
|
using RimWorld;
|
|
|
|
|
using HarmonyLib;
|
|
|
|
|
using Rimworld_Animations;
|
|
|
|
|
|
|
|
|
|
namespace Rimworld_Animations_Patch
|
|
|
|
|
{
|
|
|
|
|
public static class HandAnimationUtility
|
|
|
|
|
{
|
|
|
|
|
public static BodyPartDef handDef;
|
|
|
|
|
|
2023-02-04 07:13:57 +00:00
|
|
|
|
public static bool BodyPartIsBeingTouched(Pawn pawn, ActorAnimationData actorAnimationData, string bodypartFilePath, out List<HandAnimationData> handAnimationData)
|
2022-09-10 01:22:08 +00:00
|
|
|
|
{
|
|
|
|
|
handAnimationData = new List<HandAnimationData>();
|
2022-09-30 23:34:08 +00:00
|
|
|
|
HandAnimationDef handAnimationDef = pawn?.TryGetComp<CompPawnSexData>()?.handAnimationDef;
|
2022-09-11 06:05:16 +00:00
|
|
|
|
|
2022-09-30 23:34:08 +00:00
|
|
|
|
if (handAnimationDef == null || actorAnimationData == null || bodypartFilePath.NullOrEmpty())
|
2022-09-10 01:22:08 +00:00
|
|
|
|
{ return false; }
|
|
|
|
|
|
|
|
|
|
foreach (HandAnimationData datum in handAnimationDef.handAnimationData)
|
|
|
|
|
{
|
2023-02-04 07:13:57 +00:00
|
|
|
|
if (datum.stageID != actorAnimationData.currentStage || datum.actorID != actorAnimationData.actorID) continue;
|
|
|
|
|
if (datum.bodySide.NullOrEmpty() == false && bodypartFilePath.Contains(datum.bodySide, StringComparison.OrdinalIgnoreCase) == false) continue;
|
2022-09-10 01:22:08 +00:00
|
|
|
|
|
2023-02-04 07:13:57 +00:00
|
|
|
|
if ((datum.targetBodyPart.NullOrEmpty() == false && bodypartFilePath.Contains(datum.targetBodyPart, StringComparison.OrdinalIgnoreCase)) ||
|
|
|
|
|
datum.targetBodyParts.Any(x => bodypartFilePath.Contains(x, StringComparison.OrdinalIgnoreCase)))
|
2022-09-10 01:22:08 +00:00
|
|
|
|
{ handAnimationData.Add(datum); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return handAnimationData.NullOrEmpty() == false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Vector3 GetHandPosition(Pawn pawn, HandAnimationData handAnimationData, Vector3 basePosition, float baseAngle)
|
|
|
|
|
{
|
2023-02-04 07:13:57 +00:00
|
|
|
|
Vector3 handPosition = handAnimationData.Motion.GetHandPosition(pawn, handAnimationData, baseAngle);
|
2022-09-11 06:05:16 +00:00
|
|
|
|
return handPosition * pawn.RaceProps.baseBodySize + basePosition + new Vector3(0f, 0.3f, 0f);
|
2022-09-10 01:22:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static float GetGenitalSize(Pawn pawn, string genitalName)
|
|
|
|
|
{
|
2023-02-04 07:13:57 +00:00
|
|
|
|
CompPawnSexData data = pawn?.TryGetComp<CompPawnSexData>();
|
|
|
|
|
if (data == null) return 0f;
|
|
|
|
|
|
|
|
|
|
switch (genitalName)
|
2022-09-10 01:22:08 +00:00
|
|
|
|
{
|
2023-02-04 07:13:57 +00:00
|
|
|
|
case "penis": return data.sizeOfPenis;
|
|
|
|
|
case "breasts": return data.sizeOfBreasts;
|
|
|
|
|
case "Penis": return data.sizeOfPenis;
|
|
|
|
|
case "Breasts": return data.sizeOfBreasts;
|
2022-09-10 01:22:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0.1f;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-30 23:34:08 +00:00
|
|
|
|
public static Graphic GetHandGraphic(Pawn touchingPawn)
|
2022-09-10 01:22:08 +00:00
|
|
|
|
{
|
2022-09-30 23:34:08 +00:00
|
|
|
|
CompPawnSexData comp = touchingPawn?.TryGetComp<CompPawnSexData>();
|
|
|
|
|
if (comp == null) return null;
|
|
|
|
|
|
|
|
|
|
if (comp.handGraphic == null)
|
|
|
|
|
{
|
|
|
|
|
string handGraphicPath = "Hands/HandClean";
|
|
|
|
|
comp.handGraphic = GraphicDatabase.Get<Graphic_Single>(handGraphicPath, ShaderDatabase.Cutout,
|
|
|
|
|
new Vector2(0.6667f * touchingPawn.RaceProps.baseBodySize, 0.6667f * touchingPawn.RaceProps.baseBodySize), touchingPawn.story.SkinColor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return comp.handGraphic;
|
2022-09-10 01:22:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-04 07:13:57 +00:00
|
|
|
|
public static bool TryToDrawHand(Pawn pawn, ActorAnimationData pawnAnimationData, string bodyAddonName, Vector3 bodyAddonPosition, float bodyAddonAngle, Rot4 bodyAddonRotation, PawnRenderFlags renderFlags)
|
2022-09-30 23:34:08 +00:00
|
|
|
|
{
|
2023-02-04 07:13:57 +00:00
|
|
|
|
if (BodyPartIsBeingTouched(pawn, pawnAnimationData, bodyAddonName, out List<HandAnimationData> handAnimationData))
|
2022-09-30 23:34:08 +00:00
|
|
|
|
{
|
2022-09-10 01:22:08 +00:00
|
|
|
|
foreach (HandAnimationData datum in handAnimationData)
|
2022-09-30 23:34:08 +00:00
|
|
|
|
{
|
2022-09-10 01:22:08 +00:00
|
|
|
|
Pawn touchingPawn = datum.touchingActorID >= 0 && pawn.GetAllSexParticipants().Count > datum.touchingActorID ? pawn.GetAllSexParticipants()[datum.touchingActorID] : pawn;
|
|
|
|
|
|
2022-09-30 23:34:08 +00:00
|
|
|
|
Graphic handGraphic = GetHandGraphic(touchingPawn);
|
|
|
|
|
if (handGraphic == null) return false;
|
|
|
|
|
|
2022-09-10 01:22:08 +00:00
|
|
|
|
Vector3 handPosition = GetHandPosition(pawn, datum, bodyAddonPosition, bodyAddonAngle);
|
2022-09-30 23:34:08 +00:00
|
|
|
|
|
|
|
|
|
GenDraw.DrawMeshNowOrLater(mesh: handGraphic.MeshAt(rot: bodyAddonRotation),
|
2022-09-10 01:22:08 +00:00
|
|
|
|
loc: handPosition + new Vector3(0f, 0.022f, 0f),
|
|
|
|
|
quat: Quaternion.identity,
|
2022-09-30 23:34:08 +00:00
|
|
|
|
mat: handGraphic.MatAt(rot: bodyAddonRotation), renderFlags.FlagSet(PawnRenderFlags.DrawNow));
|
|
|
|
|
|
2022-09-10 01:22:08 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|