rimworld-animations-patch/Source/Scripts/Utilities/ApparelAnimationUtility.cs

183 lines
6.8 KiB
C#
Raw Permalink Normal View History

2022-09-10 01:22:08 +00:00
using System.Collections.Generic;
using System.Linq;
using Verse;
using RimWorld;
using Rimworld_Animations;
using UnityEngine;
using AlienRace;
using rjw;
namespace Rimworld_Animations_Patch
{
public static class ApparelAnimationUtility
{
public static float apparelScale = 0.75f;
public static void TryToDrawApparelOnFloor(Pawn pawn)
{
2022-09-11 06:05:16 +00:00
if (pawn?.apparel?.WornApparel != null)
2022-09-10 01:22:08 +00:00
{
2022-09-11 06:05:16 +00:00
CompBodyAnimator compBodyAnimator = pawn.TryGetComp<CompBodyAnimator>();
2022-09-10 01:22:08 +00:00
2022-09-11 06:05:16 +00:00
if (ApparelSettings.clothesThrownOnGround == false || Find.CurrentMap != pawn.Map || compBodyAnimator == null || compBodyAnimator.isAnimating == false)
2022-09-10 01:22:08 +00:00
{ return; }
2022-09-11 06:05:16 +00:00
foreach (Apparel apparel in pawn.apparel.WornApparel)
2022-09-10 01:22:08 +00:00
{
CompApparelVisibility compApparelVisibility = apparel.TryGetComp<CompApparelVisibility>();
if (compApparelVisibility != null && compApparelVisibility.position != default && compApparelVisibility.isBeingWorn == false)
{
Graphic apparelGraphic = apparel.Graphic;
apparelGraphic.drawSize.x *= apparelScale;
apparelGraphic.drawSize.y *= apparelScale;
GenDraw.DrawMeshNowOrLater(mesh: apparelGraphic.MeshAt(rot: apparel.Rotation),
loc: compApparelVisibility.position,
quat: Quaternion.AngleAxis(angle: compApparelVisibility.rotation, axis: Vector3.up),
mat: apparelGraphic.MatAt(rot: apparel.Rotation),
false);
apparelGraphic.drawSize.x *= 1f / apparelScale;
apparelGraphic.drawSize.y *= 1f / apparelScale;
2022-09-11 06:05:16 +00:00
2022-09-10 01:22:08 +00:00
//DebugMode.Message("Drawing " + apparel.def.defName + " on ground");
}
}
}
}
2022-09-11 06:05:16 +00:00
public static bool PrivatePartCoveredByApparel(Apparel apparel, string bodyPart)
2022-09-10 01:22:08 +00:00
{
CompApparelVisibility comp = apparel.TryGetComp<CompApparelVisibility>();
2022-09-11 06:05:16 +00:00
if (comp == null || comp.rimNudeDataStatus == RimNudeDataStatus.Unavailable)
2022-09-10 01:22:08 +00:00
{ return false; }
2022-09-11 06:05:16 +00:00
if (comp.rimNudeDataStatus == RimNudeDataStatus.NotLoaded)
2022-09-10 01:22:08 +00:00
{
2022-09-11 06:05:16 +00:00
RimNudeData rimNudeData = ApparelSettings.GetRimNudeData(apparel);
2022-09-10 01:22:08 +00:00
2022-09-11 06:05:16 +00:00
if (rimNudeData == null)
{
comp.rimNudeDataStatus = RimNudeDataStatus.Unavailable;
return false;
}
2022-09-10 01:22:08 +00:00
2022-09-11 06:05:16 +00:00
comp.coversBelly = rimNudeData.coversBelly;
comp.coversChest = rimNudeData.coversChest;
comp.coversGroin = rimNudeData.coversGroin;
comp.rimNudeDataStatus = RimNudeDataStatus.Loaded;
2022-09-10 01:22:08 +00:00
}
2022-09-11 06:05:16 +00:00
if (comp.isBeingWorn == false)
2022-09-10 01:22:08 +00:00
{ return false; }
2022-09-11 06:05:16 +00:00
if (bodyPart == "Genitals")
{ return comp.coversGroin; }
2022-09-10 01:22:08 +00:00
2022-09-11 06:05:16 +00:00
if (bodyPart == "Chest")
{ return comp.coversChest; }
2022-09-10 01:22:08 +00:00
2022-09-11 06:05:16 +00:00
if (bodyPart == "Torso")
{ return comp.coversBelly; }
2022-09-10 01:22:08 +00:00
return false;
}
public static void DetermineApparelToKeepOn(Pawn pawn)
{
JobDriver_Sex jobdriver = pawn.jobs.curDriver as JobDriver_Sex;
if (pawn.RaceProps.Humanlike == false || pawn?.apparel?.WornApparel == null || jobdriver == null)
{ return; }
2022-09-11 06:05:16 +00:00
foreach (Apparel apparel in pawn.apparel.WornApparel)
2022-09-10 01:22:08 +00:00
{
CompApparelVisibility comp = apparel.TryGetComp<CompApparelVisibility>();
2022-09-11 06:05:16 +00:00
2022-09-10 01:22:08 +00:00
if (comp != null)
{ comp.isBeingWorn = true; }
}
ActorAnimationData animData = pawn.GetAnimationData();
if (animData == null)
{ return; }
AnimationDef anim = animData.animationDef;
int actorID = animData.actorID;
var clothingPreference = pawn.IsInBed(out Building bed) ? RJWPreferenceSettings.sex_wear : ApparelSettings.apparelWornForQuickies;
if (xxx.has_quirk(pawn, "Endytophile"))
{ clothingPreference = RJWPreferenceSettings.Clothing.Clothed; }
// Determine any obstructing apparel that must be removed
foreach (Apparel apparel in pawn.apparel.WornApparel)
{
CompApparelVisibility comp = apparel.TryGetComp<CompApparelVisibility>();
if (comp == null)
{ continue; }
if (apparel.def is bondage_gear_def)
{ continue; }
if (ApparelSettings.GetRimNudeData(apparel) != null && ApparelSettings.GetRimNudeData(apparel).sexWear)
{ continue; }
if (clothingPreference == RJWPreferenceSettings.Clothing.Nude)
{
comp.isBeingWorn = false;
continue;
}
bool isHat = apparel.def.apparel.bodyPartGroups.NullOrEmpty() == false && (apparel.def.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.FullHead) || apparel.def.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.UpperHead));
if (clothingPreference == RJWPreferenceSettings.Clothing.Headgear && isHat == false)
{
comp.isBeingWorn = false;
continue;
}
if (ApparelCoversPawnRequiredBodyParts(pawn, apparel, anim, actorID))
{
comp.isBeingWorn = false;
continue;
}
}
}
public static bool ApparelCoversPawnRequiredBodyParts(Pawn pawn, Apparel apparel, AnimationDef anim, int actorID)
{
bool bodyPartCovered = false;
IEnumerable<BodyPartRecord> bodyParts = pawn.RaceProps.body.AllParts;
var requiredGenitals = anim.actors[actorID].requiredGenitals;
if (requiredGenitals.NullOrEmpty())
{ requiredGenitals = new List<string>(); }
if (anim.actors[actorID].isFucking || requiredGenitals.Contains("Penis"))
2022-09-11 06:05:16 +00:00
{ bodyPartCovered = bodyPartCovered || PrivatePartCoveredByApparel(apparel, "Genitals"); }
2022-09-10 01:22:08 +00:00
if (anim.actors[actorID].isFucked || requiredGenitals.Contains("Vagina"))
2022-09-11 06:05:16 +00:00
{ bodyPartCovered = bodyPartCovered || PrivatePartCoveredByApparel(apparel, "Genitals"); }
2022-09-10 01:22:08 +00:00
if (anim.actors[actorID].isFucked || requiredGenitals.Contains("Anus"))
2022-09-11 06:05:16 +00:00
{ bodyPartCovered = bodyPartCovered || PrivatePartCoveredByApparel(apparel, "Genitals"); }
2022-09-10 01:22:08 +00:00
if (requiredGenitals.Contains("Breasts"))
2022-09-11 06:05:16 +00:00
{ bodyPartCovered = bodyPartCovered || PrivatePartCoveredByApparel(apparel, "Chest"); }
2022-09-10 01:22:08 +00:00
if (requiredGenitals.Contains("Mouth"))
2022-09-11 06:05:16 +00:00
{ bodyPartCovered = bodyPartCovered || apparel.def.apparel.CoversBodyPart(bodyParts.FirstOrDefault(x => x.def.defName.ToLower().ContainsAny("mouth", "teeth", "jaw", "beak"))); }
2022-09-10 01:22:08 +00:00
return bodyPartCovered;
}
}
}