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