mirror of
https://gitgud.io/AbstractConcept/rimworld-animations-patch.git
synced 2024-08-15 00:43:27 +00:00
v 1.2.2
This commit is contained in:
parent
dab724fb50
commit
f089b94044
46 changed files with 2631 additions and 393 deletions
191
Source/Scripts/Defs/BodyAddonData.cs
Normal file
191
Source/Scripts/Defs/BodyAddonData.cs
Normal file
|
@ -0,0 +1,191 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Verse;
|
||||
using RimWorld;
|
||||
using AlienRace;
|
||||
using Rimworld_Animations;
|
||||
using UnityEngine;
|
||||
using HarmonyLib;
|
||||
|
||||
namespace Rimworld_Animations_Patch
|
||||
{
|
||||
public class BodyAddonData
|
||||
{
|
||||
public AlienPartGenerator.BodyAddon bodyAddon;
|
||||
public BodyPartRecord bodyPartRecord;
|
||||
public List<Vector3> bodyAddonOffsets = new List<Vector3>();
|
||||
public bool alignsWithHead = false;
|
||||
|
||||
private Pawn pawn;
|
||||
private string bodyType;
|
||||
private PawnRenderFlags renderFlags;
|
||||
private bool canDraw = false;
|
||||
|
||||
public BodyAddonData(Pawn pawn, AlienPartGenerator.BodyAddon bodyAddon, bool isPortrait = false)
|
||||
{
|
||||
this.pawn = pawn;
|
||||
this.bodyAddon = bodyAddon;
|
||||
|
||||
if (isPortrait)
|
||||
{ renderFlags |= PawnRenderFlags.Portrait; }
|
||||
|
||||
bodyPartRecord = pawn?.def?.race?.body?.AllParts?.FirstOrDefault(x => x.def.defName == bodyAddon?.bodyPart || x.customLabel == bodyAddon?.bodyPart);
|
||||
alignsWithHead = bodyAddon.alignWithHead || (bodyPartRecord != null && bodyPartRecord.IsInGroup(BodyPartGroupDefOf.FullHead));
|
||||
|
||||
GenerateOffsets();
|
||||
UpdateVisibility();
|
||||
}
|
||||
|
||||
public void GenerateOffsets()
|
||||
{
|
||||
bodyType = pawn.story.bodyType.defName;
|
||||
bodyAddonOffsets.Clear();
|
||||
|
||||
int bodyAddonIndex = (pawn.def as ThingDef_AlienRace).alienRace.generalSettings.alienPartGenerator.bodyAddons.ToList().IndexOf(bodyAddon);
|
||||
AlienPartGenerator.AlienComp alienComp = pawn.GetComp<AlienPartGenerator.AlienComp>();
|
||||
Graphic addonGraphic = alienComp.addonGraphics[bodyAddonIndex];
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Rot4 apparentRotation = new Rot4(i);
|
||||
|
||||
// Get basic offset for body addon
|
||||
AlienPartGenerator.RotationOffset defaultOffsets = bodyAddon.defaultOffsets.GetOffset(apparentRotation);
|
||||
Vector3 bodyTypeOffset = (defaultOffsets != null) ? defaultOffsets.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, alienComp.crownType) : Vector3.zero;
|
||||
|
||||
AlienPartGenerator.RotationOffset rotationOffsets = bodyAddon.offsets.GetOffset(apparentRotation);
|
||||
Vector3 bodyAddonOffset = bodyTypeOffset + ((rotationOffsets != null) ? rotationOffsets.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, alienComp.crownType) : Vector3.zero);
|
||||
|
||||
// Offset private parts so that they render over tattoos but under apparel (rendering under tatoos looks weird)
|
||||
if (bodyAddon.bodyPart == "Genitals" || bodyAddon.bodyPart == "Chest" || bodyAddon.bodyPart == "Anus" || addonGraphic.path.ToLower().Contains("belly"))
|
||||
{
|
||||
bodyAddonOffset.y = (bodyAddonOffset.y + 0.40f) / 1000f + 0.012f;
|
||||
|
||||
// Erected penises should be drawn over apparel
|
||||
if (pawn.RaceProps.Humanlike &&
|
||||
addonGraphic.path.ToLower().Contains("penis") &&
|
||||
addonGraphic.path.ToLower().Contains("flaccid") == false &&
|
||||
apparentRotation == Rot4.South)
|
||||
{ bodyAddonOffset.y += 0.010f; }
|
||||
}
|
||||
|
||||
// Otherwise use the standard offsets
|
||||
else
|
||||
{ bodyAddonOffset.y = 0.3f + bodyAddonOffset.y; }
|
||||
|
||||
// Draw addons infront of body
|
||||
if (!bodyAddon.inFrontOfBody)
|
||||
{ bodyAddonOffset.y *= -1f; }
|
||||
|
||||
// Adjust for facing
|
||||
if (apparentRotation == Rot4.North)
|
||||
{
|
||||
if (bodyAddon.layerInvert)
|
||||
{ bodyAddonOffset.y = -bodyAddonOffset.y; }
|
||||
}
|
||||
|
||||
if (apparentRotation == Rot4.East)
|
||||
{ bodyAddonOffset.x = -bodyAddonOffset.x; }
|
||||
|
||||
// Adjustment for body addons attached to the head that are not marked as such
|
||||
if (alignsWithHead && bodyAddon.alignWithHead == false)
|
||||
{ bodyAddonOffset -= pawn.Drawer.renderer.BaseHeadOffsetAt(apparentRotation); }
|
||||
|
||||
// Done
|
||||
bodyAddonOffsets.Add(bodyAddonOffset);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3 GetOffset(Rot4 facing)
|
||||
{
|
||||
if (pawn.story.bodyType.defName != bodyType)
|
||||
{ GenerateOffsets(); }
|
||||
|
||||
return bodyAddonOffsets[facing.AsInt];
|
||||
}
|
||||
|
||||
public bool CanDraw()
|
||||
{
|
||||
return pawn.Drawer.renderer.graphics.apparelGraphics.Any() == false || canDraw;
|
||||
}
|
||||
|
||||
public void UpdateVisibility()
|
||||
{
|
||||
canDraw = true;
|
||||
|
||||
if (pawn.CurrentBed()?.def.building.bed_showSleeperBody == false && bodyAddon.drawnInBed == false)
|
||||
{canDraw = false; return; }
|
||||
|
||||
if (bodyAddon.backstoryRequirement.NullOrEmpty() == false && pawn.story.AllBackstories.Any((Backstory x) => x.identifier == bodyAddon.backstoryRequirement) == false)
|
||||
{ canDraw = false; return; }
|
||||
|
||||
if (bodyAddon.drawnDesiccated == false && pawn?.Corpse?.GetRotStage() == RotStage.Dessicated)
|
||||
{ canDraw = false; return; }
|
||||
|
||||
if (pawn.health.hediffSet.GetNotMissingParts().Contains(bodyPartRecord) == false)
|
||||
{ canDraw = false; return; }
|
||||
|
||||
if (pawn.gender == Gender.Female && bodyAddon.drawForFemale == false || pawn.gender == Gender.Male && bodyAddon.drawForMale == false)
|
||||
{ canDraw = false; return; }
|
||||
|
||||
if (bodyAddon.bodyTypeRequirement.NullOrEmpty() == false && pawn.story.bodyType.ToString() != bodyAddon.bodyTypeRequirement)
|
||||
{ canDraw = false; return; }
|
||||
|
||||
if ((pawn.GetPosture() == PawnPosture.LayingOnGroundNormal || pawn.GetPosture() == PawnPosture.LayingOnGroundFaceUp) && bodyAddon.drawnOnGround == false)
|
||||
{ canDraw = false; return; }
|
||||
|
||||
foreach (Apparel apparel in pawn.apparel.WornApparel)
|
||||
{
|
||||
CompApparelVisibility comp = apparel.TryGetComp<CompApparelVisibility>();
|
||||
LoadRimNudeData(comp);
|
||||
|
||||
if (comp.isBeingWorn == false) continue;
|
||||
|
||||
if (bodyAddon.bodyPart == "Genitals" || bodyAddon.bodyPart == "Anus" || bodyAddon.bodyPart == "Chest" || bodyAddon.hediffGraphics?.Any(x => x.path.ToLower().Contains("belly")) == true)
|
||||
{
|
||||
if ((bodyAddon.bodyPart == "Genitals" || bodyAddon.bodyPart == "Anus") && comp.coversGroin)
|
||||
{ canDraw = false; return; };
|
||||
|
||||
if (bodyAddon.bodyPart == "Chest" && comp.coversChest)
|
||||
{ canDraw = false; return; };
|
||||
|
||||
if (bodyAddon.hediffGraphics?.Any(x => x.path.ToLower().Contains("belly")) == true && comp.coversBelly)
|
||||
{ canDraw = false; return; }
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (bodyAddon.hiddenUnderApparelFor?.Any(x => apparel.def.apparel.hatRenderedFrontOfFace == false && apparel.def.apparel.bodyPartGroups.Contains(x)) == true)
|
||||
{ canDraw = false; return; };
|
||||
|
||||
if (bodyAddon.hiddenUnderApparelTag?.Any(x => apparel.def.apparel.hatRenderedFrontOfFace == false && apparel.def.apparel.tags.Contains(x)) == true)
|
||||
{ canDraw = false; return; };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadRimNudeData(CompApparelVisibility comp)
|
||||
{
|
||||
if (comp == null || comp.rimNudeDataStatus == RimNudeDataStatus.Unavailable)
|
||||
{ return; }
|
||||
|
||||
if (comp.rimNudeDataStatus == RimNudeDataStatus.NotLoaded)
|
||||
{
|
||||
RimNudeData rimNudeData = ApparelSettings.GetRimNudeData(comp.apparel);
|
||||
|
||||
if (rimNudeData == null)
|
||||
{
|
||||
comp.rimNudeDataStatus = RimNudeDataStatus.Unavailable;
|
||||
return;
|
||||
}
|
||||
|
||||
comp.coversBelly = rimNudeData.coversBelly;
|
||||
comp.coversChest = rimNudeData.coversChest;
|
||||
comp.coversGroin = rimNudeData.coversGroin;
|
||||
|
||||
comp.rimNudeDataStatus = RimNudeDataStatus.Loaded;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue