rimworld-animations-patch_m.../Source/Scripts/Utilities/HandAnimationUtility.cs

100 lines
4.4 KiB
C#
Raw Normal View History

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;
}
}
}