mirror of
				https://gitgud.io/AbstractConcept/rimworld-animations-patch.git
				synced 2024-08-15 00:43:27 +00:00 
			
		
		
		
	v2.0.0
This commit is contained in:
		
							parent
							
								
									38ec4f86c1
								
							
						
					
					
						commit
						ae95e34137
					
				
					 35 changed files with 242 additions and 612 deletions
				
			
		| 
						 | 
				
			
			@ -22,13 +22,20 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
        public Dictionary<AlienPartGenerator.BodyAddon, BodyAddonData> bodyAddonData = new Dictionary<AlienPartGenerator.BodyAddon, BodyAddonData>();
 | 
			
		||||
        public Dictionary<AlienPartGenerator.BodyAddon, BodyAddonData> bodyAddonDataPortraits = new Dictionary<AlienPartGenerator.BodyAddon, BodyAddonData>();
 | 
			
		||||
 | 
			
		||||
        private Pawn pawn;
 | 
			
		||||
        private Pawn pawn { get { return parent as Pawn; } }
 | 
			
		||||
        private bool initialized;
 | 
			
		||||
 | 
			
		||||
        public override void CompTick()
 | 
			
		||||
        {
 | 
			
		||||
            if (initialized == false)
 | 
			
		||||
            {
 | 
			
		||||
                pawn?.Drawer?.renderer?.graphics?.ResolveAllGraphics();
 | 
			
		||||
                initialized = true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public BodyAddonData GetBodyAddonData(AlienPartGenerator.BodyAddon bodyAddon, bool isPortrait)
 | 
			
		||||
        {
 | 
			
		||||
            if (pawn == null)
 | 
			
		||||
            { pawn = parent as Pawn; }
 | 
			
		||||
 | 
			
		||||
            if (pawn == null || (pawn.Map != Find.CurrentMap && pawn.holdingOwner == null) || bodyAddon == null) return null;
 | 
			
		||||
            
 | 
			
		||||
            if (isPortrait)
 | 
			
		||||
| 
						 | 
				
			
			@ -67,16 +74,16 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
        {
 | 
			
		||||
            hands = pawn?.health?.hediffSet?.GetNotMissingParts()?.Where(x => x.def.tags.Contains(BodyPartTagDefOf.ManipulationLimbCore))?.ToList();
 | 
			
		||||
 | 
			
		||||
            Hediff hediffPenis = pawn?.health?.hediffSet?.hediffs?.FirstOrDefault(x => x.def.defName.Contains("penis") == true || x.def.defName.Contains("Penis"));
 | 
			
		||||
            Hediff hediffPenis = pawn?.health?.hediffSet?.hediffs?.FirstOrDefault(x => x.def.defName.Contains("penis", StringComparison.OrdinalIgnoreCase) == true);
 | 
			
		||||
            sizeOfPenis = hediffPenis != null ? hediffPenis.Severity : 0f;
 | 
			
		||||
 | 
			
		||||
            Hediff hediffBreasts = pawn?.health?.hediffSet?.hediffs?.FirstOrDefault(x => x.def.defName.Contains("breasts") == true || x.def.defName.Contains("Breasts") == true);
 | 
			
		||||
            Hediff hediffBreasts = pawn?.health?.hediffSet?.hediffs?.FirstOrDefault(x => x.def.defName.Contains("breasts", StringComparison.OrdinalIgnoreCase) == true);
 | 
			
		||||
            sizeOfBreasts = hediffBreasts != null ? hediffBreasts.Severity : 0f;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int GetNumberOfHands()
 | 
			
		||||
        {
 | 
			
		||||
            if (hands.Any() == false) return 0;
 | 
			
		||||
            if (hands.NullOrEmpty()) return 0;
 | 
			
		||||
 | 
			
		||||
            return hands.Count;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,70 +0,0 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace Rimworld_Animations_Patch
 | 
			
		||||
{
 | 
			
		||||
    public class ActorAddon
 | 
			
		||||
    {
 | 
			
		||||
        // Data to/from animationDef
 | 
			
		||||
        public string addonName;
 | 
			
		||||
        public int? anchoringActor;
 | 
			
		||||
        public string anchorName;
 | 
			
		||||
        public string layer = "Pawn";
 | 
			
		||||
        public GraphicData graphicData;
 | 
			
		||||
        public bool? render;
 | 
			
		||||
 | 
			
		||||
        // Data helper functions
 | 
			
		||||
        public string AddonName
 | 
			
		||||
        {
 | 
			
		||||
            get { return addonName; }
 | 
			
		||||
            set { addonName = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int AnchoringActor
 | 
			
		||||
        {
 | 
			
		||||
            get { return anchoringActor.HasValue ? anchoringActor.Value : 0; }
 | 
			
		||||
            set { anchoringActor = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string AnchorName
 | 
			
		||||
        {
 | 
			
		||||
            get { return anchorName; }
 | 
			
		||||
            set { anchorName = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string Layer
 | 
			
		||||
        {
 | 
			
		||||
            get { return layer; }
 | 
			
		||||
            set { layer = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public GraphicData GraphicData
 | 
			
		||||
        {
 | 
			
		||||
            get { return graphicData; }
 | 
			
		||||
            set { graphicData = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Render
 | 
			
		||||
        {
 | 
			
		||||
            get { return render == true; }
 | 
			
		||||
            set { render = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Simple curves
 | 
			
		||||
        public SimpleCurve PosX = new SimpleCurve();
 | 
			
		||||
        public SimpleCurve PosZ = new SimpleCurve();
 | 
			
		||||
        public SimpleCurve Rotation = new SimpleCurve();
 | 
			
		||||
 | 
			
		||||
        // Constructors
 | 
			
		||||
        public ActorAddon() { }
 | 
			
		||||
 | 
			
		||||
        public ActorAddon(ActorAddonDef actorAddonDef)
 | 
			
		||||
        {
 | 
			
		||||
            this.GraphicData = actorAddonDef.graphicData;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,15 +0,0 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
 | 
			
		||||
namespace Rimworld_Animations_Patch
 | 
			
		||||
{
 | 
			
		||||
    public class ActorAddonDef : Def
 | 
			
		||||
    {
 | 
			
		||||
        public float scale = 1f;
 | 
			
		||||
        public GraphicData graphicData;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,56 +0,0 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Rimworld_Animations_Patch
 | 
			
		||||
{
 | 
			
		||||
    public class AddonKeyframe
 | 
			
		||||
    {
 | 
			
		||||
        // Data to/from animationDef
 | 
			
		||||
        public string addonName;
 | 
			
		||||
        public float? posX;
 | 
			
		||||
        public float? posZ;
 | 
			
		||||
        public float? rotation;
 | 
			
		||||
 | 
			
		||||
        // Data serialization control
 | 
			
		||||
        public bool ShouldSerializeposX() { return posX.HasValue; }
 | 
			
		||||
        public bool ShouldSerializeposZ() { return posZ.HasValue; }
 | 
			
		||||
        public bool ShouldSerializerotation() { return rotation.HasValue; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // Data helper functions
 | 
			
		||||
        public string AddonName
 | 
			
		||||
        {
 | 
			
		||||
            get { return addonName; }
 | 
			
		||||
            set { addonName = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public float PosX
 | 
			
		||||
        {
 | 
			
		||||
            get { return posX.HasValue ? posX.Value : 0f; }
 | 
			
		||||
            set { posX = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public float PosZ
 | 
			
		||||
        {
 | 
			
		||||
            get { return posZ.HasValue ? posZ.Value : 0f; }
 | 
			
		||||
            set { posZ = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public float Rotation
 | 
			
		||||
        {
 | 
			
		||||
            get { return rotation.HasValue ? rotation.Value : 0f; }
 | 
			
		||||
            set { rotation = value; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Constructors
 | 
			
		||||
        public AddonKeyframe() { }
 | 
			
		||||
 | 
			
		||||
        public AddonKeyframe(string addonName)
 | 
			
		||||
        {
 | 
			
		||||
            this.AddonName = addonName;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -22,12 +22,12 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
        private PawnRenderFlags renderFlags;
 | 
			
		||||
        private bool canDraw = false;
 | 
			
		||||
        private bool bodyPartMissing = false;
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
        public BodyAddonData(Pawn pawn, AlienPartGenerator.BodyAddon bodyAddon, bool isPortrait = false)
 | 
			
		||||
        {
 | 
			
		||||
            this.pawn = pawn;
 | 
			
		||||
            this.bodyAddon = bodyAddon;
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            if (isPortrait)
 | 
			
		||||
            { renderFlags |= PawnRenderFlags.Portrait; }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -42,11 +42,11 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
        {
 | 
			
		||||
            bodyType = pawn.story.bodyType.defName;
 | 
			
		||||
            bodyAddonOffsets.Clear();
 | 
			
		||||
         
 | 
			
		||||
 | 
			
		||||
            int bodyAddonIndex = (pawn.def as ThingDef_AlienRace).alienRace.generalSettings.alienPartGenerator.bodyAddons.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);
 | 
			
		||||
| 
						 | 
				
			
			@ -54,8 +54,8 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
                // 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, pawn.story.headType) : Vector3.zero;
 | 
			
		||||
                
 | 
			
		||||
                AlienPartGenerator.RotationOffset rotationOffsets = bodyAddon.offsets.GetOffset(apparentRotation);        
 | 
			
		||||
 | 
			
		||||
                AlienPartGenerator.RotationOffset rotationOffsets = bodyAddon.offsets.GetOffset(apparentRotation);
 | 
			
		||||
                Vector3 bodyAddonOffset = bodyTypeOffset + ((rotationOffsets != null) ? rotationOffsets.GetOffset(renderFlags.FlagSet(PawnRenderFlags.Portrait), pawn.story.bodyType, pawn.story.headType) : Vector3.zero);
 | 
			
		||||
 | 
			
		||||
                // Offset private parts so that they render over tattoos but under apparel (rendering under tatoos looks weird)
 | 
			
		||||
| 
						 | 
				
			
			@ -65,8 +65,8 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
 | 
			
		||||
                    // Erected penises should be drawn over apparel
 | 
			
		||||
                    if (pawn.RaceProps.Humanlike &&
 | 
			
		||||
                        (addonGraphic.path.Contains("penis") || addonGraphic.path.Contains("Penis")) &&
 | 
			
		||||
                        (addonGraphic.path.Contains("flaccid") == false && addonGraphic.path.Contains("Flaccid") == false) &&
 | 
			
		||||
                        addonGraphic.path.Contains("penis", StringComparison.OrdinalIgnoreCase) &&
 | 
			
		||||
                        (addonGraphic.path.Contains("flaccid", StringComparison.OrdinalIgnoreCase) == false) &&
 | 
			
		||||
                        apparentRotation == Rot4.South)
 | 
			
		||||
                    { bodyAddonOffset.y += 0.010f; }
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -74,21 +74,21 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
                // 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); }
 | 
			
		||||
| 
						 | 
				
			
			@ -102,9 +102,9 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
        {
 | 
			
		||||
            if (pawn.story.bodyType.defName != bodyType)
 | 
			
		||||
            { GenerateOffsets(); }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            return bodyAddonOffsets[facing.AsInt];
 | 
			
		||||
        }   
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool CanDraw()
 | 
			
		||||
        {
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +146,7 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
 | 
			
		||||
            if (pawn?.apparel?.WornApparel == null || pawn.apparel.WornApparel.NullOrEmpty())
 | 
			
		||||
            { return; }
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
            foreach (Apparel apparel in pawn.apparel.WornApparel)
 | 
			
		||||
            {
 | 
			
		||||
                CompApparelVisibility comp = apparel?.TryGetComp<CompApparelVisibility>();
 | 
			
		||||
| 
						 | 
				
			
			@ -155,9 +155,9 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
 | 
			
		||||
                if (comp.isBeingWorn == false) continue;
 | 
			
		||||
 | 
			
		||||
                if (bodyAddon.bodyPart == PatchBodyPartDefOf.Genitals || 
 | 
			
		||||
                    bodyAddon.bodyPart == PatchBodyPartDefOf.Anus || 
 | 
			
		||||
                    bodyAddon.bodyPart == PatchBodyPartDefOf.Chest || 
 | 
			
		||||
                if (bodyAddon.bodyPart == PatchBodyPartDefOf.Genitals ||
 | 
			
		||||
                    bodyAddon.bodyPart == PatchBodyPartDefOf.Anus ||
 | 
			
		||||
                    bodyAddon.bodyPart == PatchBodyPartDefOf.Chest ||
 | 
			
		||||
                    bodyAddon.hediffGraphics?.Any(x => x.path.NullOrEmpty() == false && (x.path.Contains("belly") || x.path.Contains("Belly"))) == true)
 | 
			
		||||
                {
 | 
			
		||||
                    if ((bodyAddon.bodyPart == PatchBodyPartDefOf.Genitals || bodyAddon.bodyPart == PatchBodyPartDefOf.Anus) && comp.coversGroin)
 | 
			
		||||
| 
						 | 
				
			
			@ -204,4 +204,4 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,54 +0,0 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Rimworld_Animations;
 | 
			
		||||
 | 
			
		||||
namespace Rimworld_Animations_Patch
 | 
			
		||||
{
 | 
			
		||||
    public class PawnAnimationClipExt : PawnAnimationClip
 | 
			
		||||
    {
 | 
			
		||||
        public List<ActorAddon> addons = new List<ActorAddon>();
 | 
			
		||||
 | 
			
		||||
        public override void buildSimpleCurves()
 | 
			
		||||
        {
 | 
			
		||||
            base.buildSimpleCurves();
 | 
			
		||||
            int keyframePosition = 0;
 | 
			
		||||
 | 
			
		||||
            for (int i = 0; i < keyframes.Count; i++)
 | 
			
		||||
            {
 | 
			
		||||
                PawnKeyframeExt keyframe = keyframes[i] as PawnKeyframeExt;
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
                if (keyframe.atTick.HasValue)
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (ActorAddon addon in addons)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (keyframe.addonKeyframes.Any(x => x.AddonName == addon.AddonName) == false)
 | 
			
		||||
                        { keyframe.addonKeyframes.Add(new AddonKeyframe(addon.AddonName)); }
 | 
			
		||||
 | 
			
		||||
                        addon.PosX.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosX, true);
 | 
			
		||||
                        addon.PosZ.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosZ, true);
 | 
			
		||||
                        addon.Rotation.Add((float)keyframe.atTick / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).Rotation, true);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                else
 | 
			
		||||
                {                  
 | 
			
		||||
                    foreach (ActorAddon addon in addons)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (keyframe.addonKeyframes.Any(x => x.AddonName == addon.AddonName) == false)
 | 
			
		||||
                        { keyframe.addonKeyframes.Add(new AddonKeyframe(addon.AddonName)); }
 | 
			
		||||
 | 
			
		||||
                        addon.PosX.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosX, true);
 | 
			
		||||
                        addon.PosZ.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).PosZ, true);
 | 
			
		||||
                        addon.Rotation.Add((float)keyframePosition / (float)duration, keyframe.GetAddonKeyframe(addon.AddonName).Rotation, true);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    keyframePosition += keyframe.tickDuration;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,19 +0,0 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Rimworld_Animations;
 | 
			
		||||
 | 
			
		||||
namespace Rimworld_Animations_Patch
 | 
			
		||||
{
 | 
			
		||||
    public class PawnKeyframeExt : PawnKeyframe
 | 
			
		||||
    {
 | 
			
		||||
        public List<AddonKeyframe> addonKeyframes;
 | 
			
		||||
 | 
			
		||||
        public AddonKeyframe GetAddonKeyframe(string addonName)
 | 
			
		||||
        {
 | 
			
		||||
            return addonKeyframes.FirstOrDefault(x => x.AddonName == addonName);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,79 +0,0 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using UnityEngine;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using rjw;
 | 
			
		||||
using Rimworld_Animations;
 | 
			
		||||
 | 
			
		||||
namespace Rimworld_Animations_Patch
 | 
			
		||||
{
 | 
			
		||||
	public class JobDriver_JoinInSex : JobDriver_SexBaseInitiator
 | 
			
		||||
	{
 | 
			
		||||
		public override bool TryMakePreToilReservations(bool errorOnFailed)
 | 
			
		||||
		{
 | 
			
		||||
			return true; // pawn.Reserve(Target, job, 3, 0, null, errorOnFailed);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		protected override IEnumerable<Toil> MakeNewToils()
 | 
			
		||||
		{
 | 
			
		||||
			setup_ticks();
 | 
			
		||||
 | 
			
		||||
			this.FailOnDespawnedNullOrForbidden(iTarget);
 | 
			
		||||
			this.FailOn(() => !Partner.health.capacities.CanBeAwake);
 | 
			
		||||
			this.FailOn(() => pawn.Drafted);
 | 
			
		||||
			this.FailOn(() => Partner.Drafted);
 | 
			
		||||
 | 
			
		||||
			Toil FollowToil = new Toil();
 | 
			
		||||
			FollowToil.defaultCompleteMode = ToilCompleteMode.Delay;
 | 
			
		||||
			FollowToil.socialMode = RandomSocialMode.Off;
 | 
			
		||||
			FollowToil.defaultDuration = 1200;
 | 
			
		||||
			FollowToil.tickAction = delegate
 | 
			
		||||
			{
 | 
			
		||||
				pawn.pather.StartPath(Partner, PathEndMode.Touch);
 | 
			
		||||
				
 | 
			
		||||
				if (pawn.pather.Moving == false && Partner.pather.Moving == false && Partner.jobs.curDriver is JobDriver_SexBaseReciever)
 | 
			
		||||
				{ ReadyForNextToil(); }
 | 
			
		||||
			};
 | 
			
		||||
			yield return FollowToil;
 | 
			
		||||
 | 
			
		||||
			Toil SexToil = new Toil();
 | 
			
		||||
			SexToil.defaultCompleteMode = ToilCompleteMode.Never;
 | 
			
		||||
			SexToil.socialMode = RandomSocialMode.Off;
 | 
			
		||||
			SexToil.defaultDuration = duration;
 | 
			
		||||
			SexToil.handlingFacing = true;
 | 
			
		||||
			SexToil.FailOn(() => (Partner.jobs.curDriver is JobDriver_SexBaseReciever) == false);
 | 
			
		||||
			SexToil.initAction = delegate
 | 
			
		||||
			{
 | 
			
		||||
				Start();
 | 
			
		||||
				Sexprops.usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(Partner);
 | 
			
		||||
			};
 | 
			
		||||
			SexToil.AddPreTickAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				if (pawn.IsHashIntervalTick(ticks_between_hearts))
 | 
			
		||||
					ThrowMetaIconF(pawn.Position, pawn.Map, FleckDefOf.Heart);
 | 
			
		||||
				SexTick(pawn, Partner);
 | 
			
		||||
				SexUtility.reduce_rest(pawn, 1);
 | 
			
		||||
				if (ticks_left <= 0)
 | 
			
		||||
					ReadyForNextToil();
 | 
			
		||||
			});
 | 
			
		||||
			SexToil.AddFinishAction(delegate
 | 
			
		||||
			{
 | 
			
		||||
				End();
 | 
			
		||||
			});
 | 
			
		||||
			yield return SexToil;
 | 
			
		||||
 | 
			
		||||
			yield return new Toil
 | 
			
		||||
			{
 | 
			
		||||
				initAction = delegate
 | 
			
		||||
				{
 | 
			
		||||
					//// Trying to add some interactions and social logs
 | 
			
		||||
					SexUtility.ProcessSex(Sexprops);
 | 
			
		||||
				},
 | 
			
		||||
				defaultCompleteMode = ToilCompleteMode.Instant
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -8,13 +8,31 @@ using Verse;
 | 
			
		|||
namespace Rimworld_Animations_Patch
 | 
			
		||||
{
 | 
			
		||||
	[StaticConstructorOnStartup]
 | 
			
		||||
 | 
			
		||||
	[HarmonyPatch(typeof(ApparelGraphicRecordGetter), "TryGetGraphicApparel")]
 | 
			
		||||
	public static class HarmonyPatch_ApparelGraphicRecordGetter_TryGetGraphicApparel
 | 
			
		||||
	{
 | 
			
		||||
		static bool _checkedForSizedApparel;
 | 
			
		||||
		static bool _isRunningSizedApparel;
 | 
			
		||||
 | 
			
		||||
		// Not compatible with SizedApparel - running Graphic.Blit on the resized apparel will cause the pawn to turn invisible for one facing
 | 
			
		||||
		public static bool IsRunningSizedApparel 
 | 
			
		||||
		{ 
 | 
			
		||||
			get 
 | 
			
		||||
			{
 | 
			
		||||
				if (_checkedForSizedApparel == false)
 | 
			
		||||
				{
 | 
			
		||||
					_isRunningSizedApparel = LoadedModManager.RunningModsListForReading.Any(x => x.PackageIdPlayerFacing == "OTYOTY.SizedApparel");
 | 
			
		||||
					_checkedForSizedApparel = true;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				return _isRunningSizedApparel;
 | 
			
		||||
			} 
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void Postfix(ref bool __result, ref Apparel apparel, ref BodyTypeDef bodyType, ref ApparelGraphicRecord rec)
 | 
			
		||||
		{
 | 
			
		||||
			if (__result == false || apparel == null || bodyType == null || rec.graphic == null || ApparelSettings.cropApparel == false)
 | 
			
		||||
			{ return; }
 | 
			
		||||
			if (__result == false || apparel == null || bodyType == null || rec.graphic == null || ApparelSettings.cropApparel == false || IsRunningSizedApparel) return;
 | 
			
		||||
 | 
			
		||||
			// Get graphic
 | 
			
		||||
			Graphic graphic = rec.graphic;
 | 
			
		||||
| 
						 | 
				
			
			@ -23,17 +41,14 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
			if (apparel.def.apparel.LastLayer == ApparelLayerDefOf.OnSkin && apparel.def.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Torso) && !apparel.def.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Legs))
 | 
			
		||||
			{
 | 
			
		||||
				Dictionary<GraphicRequest, Graphic> allGraphics = Traverse.Create(typeof(GraphicDatabase)).Field("allGraphics").GetValue() as Dictionary<GraphicRequest, Graphic>;
 | 
			
		||||
				GraphicRequest graphicRequest = new GraphicRequest(typeof(Graphic_Multi), graphic.path, ShaderDatabase.CutoutComplex, apparel.def.graphicData.drawSize, apparel.DrawColor, apparel.DrawColor, null, 0, null, "Masks/apparel_shirt_mask_" + bodyType.defName);
 | 
			
		||||
				GraphicRequest graphicRequest = new GraphicRequest(typeof(Graphic_Multi), graphic.path, ShaderDatabase.CutoutComplex, graphic.drawSize, apparel.DrawColor, apparel.DrawColor, null, 0, null, "Masks/apparel_shirt_mask_" + bodyType.defName);
 | 
			
		||||
 | 
			
		||||
				if (allGraphics.TryGetValue(graphicRequest) == null)
 | 
			
		||||
				{
 | 
			
		||||
					Graphic graphicWithApparelMask = GraphicDatabase.Get<Graphic_Multi>(graphic.path, ShaderDatabase.CutoutComplex, apparel.def.graphicData.drawSize, apparel.DrawColor, apparel.DrawColor, null, "Masks/apparel_shirt_mask_" + bodyType.defName);
 | 
			
		||||
					graphic = GraphicMaskingUtility.ApplyGraphicWithMasks(graphic, graphicWithApparelMask, true);
 | 
			
		||||
					
 | 
			
		||||
					//DebugMode.Message("Applying apparel mask: Masks/apparel_shirt_mask_" + bodyType.defName + " to " + apparel.def.defName + " (" + graphic.path + ")");
 | 
			
		||||
					Graphic graphicWithApparelMasks = GraphicDatabase.Get<Graphic_Multi>(graphic.path, ShaderDatabase.CutoutComplex, graphic.drawSize, apparel.DrawColor, apparel.DrawColor, null, "Masks/apparel_shirt_mask_" + bodyType.defName);
 | 
			
		||||
					graphic = GraphicMaskingUtility.ApplyGraphicMasks(graphic, graphicWithApparelMasks, true);
 | 
			
		||||
 | 
			
		||||
					if (apparel.Wearer != null)
 | 
			
		||||
					{ PortraitsCache.SetDirty(apparel.Wearer); }
 | 
			
		||||
					//DebugMode.Message("Applying apparel mask: Masks/apparel_shirt_mask_" + bodyType.defName + " to " + apparel.def.defName + " (" + graphic.path + ")");	
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,8 @@ using BabiesAndChildren.api;
 | 
			
		|||
 | 
			
		||||
namespace Rimworld_Animations_Patch
 | 
			
		||||
{
 | 
			
		||||
	[StaticConstructorOnStartup]
 | 
			
		||||
	// To be revisited if BabiesAndChildren is updated
 | 
			
		||||
	/*[StaticConstructorOnStartup]
 | 
			
		||||
	public static class HarmonyPatch_BabiesAndChildren
 | 
			
		||||
	{
 | 
			
		||||
		static HarmonyPatch_BabiesAndChildren()
 | 
			
		||||
| 
						 | 
				
			
			@ -45,5 +46,5 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	}*/
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,12 +21,14 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
			if (__instance?.pawn == null)
 | 
			
		||||
			{ return; }
 | 
			
		||||
 | 
			
		||||
			// Scale delta by body size 
 | 
			
		||||
			if (BasicSettings.autoscaleDeltaPos)
 | 
			
		||||
			{
 | 
			
		||||
				__instance.deltaPos.x *= __instance.pawn.RaceProps.baseBodySize;
 | 
			
		||||
				__instance.deltaPos.z *= __instance.pawn.RaceProps.baseBodySize;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// In-bed specific animations cause the actors to turn to match its facing
 | 
			
		||||
			if (__instance.pawn.IsInBed(out Building bed) &&
 | 
			
		||||
				__instance.pawn.GetAnimationData().animationDef.actors[__instance.pawn.GetAnimationData().actorID].requiredGenitals.NullOrEmpty() == false &&
 | 
			
		||||
				__instance.pawn.GetAnimationData().animationDef.actors[__instance.pawn.GetAnimationData().actorID].requiredGenitals.Contains("Bed"))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,34 +0,0 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using HarmonyLib;
 | 
			
		||||
using RimWorld;
 | 
			
		||||
using Verse;
 | 
			
		||||
using Verse.AI;
 | 
			
		||||
using Rimworld_Animations;
 | 
			
		||||
using rjw;
 | 
			
		||||
 | 
			
		||||
namespace Rimworld_Animations_Patch
 | 
			
		||||
{
 | 
			
		||||
	[HarmonyPatch(typeof(JobDriver), "GetReport")]
 | 
			
		||||
	public static class HarmonyPatch_JobDriver
 | 
			
		||||
	{
 | 
			
		||||
		public static bool Prefix(JobDriver __instance, ref string __result)
 | 
			
		||||
		{
 | 
			
		||||
			JobDriver_Sex jobdriver = __instance as JobDriver_Sex;
 | 
			
		||||
 | 
			
		||||
			if (jobdriver != null && jobdriver.pawn != null && jobdriver.pawn.GetAnimationData() != null && jobdriver.Sexprops.isRape == false && jobdriver.Sexprops.isWhoring == false)
 | 
			
		||||
			{
 | 
			
		||||
				LocalTargetInfo a = jobdriver.job.targetA.IsValid ? jobdriver.job.targetA : jobdriver.job.targetQueueA.FirstValid();
 | 
			
		||||
				LocalTargetInfo b = jobdriver.job.targetB.IsValid ? jobdriver.job.targetB : jobdriver.job.targetQueueB.FirstValid();
 | 
			
		||||
				LocalTargetInfo targetC = jobdriver.job.targetC;
 | 
			
		||||
 | 
			
		||||
				//__result = JobUtility.GetResolvedJobReport(jobdriver.pawn.GetAnimationData().animationDef.label, a, b, targetC);
 | 
			
		||||
 | 
			
		||||
				//return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,37 +0,0 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Verse;
 | 
			
		||||
using HarmonyLib;
 | 
			
		||||
using RimNudeWorld;
 | 
			
		||||
 | 
			
		||||
namespace Rimworld_Animations_Patch
 | 
			
		||||
{
 | 
			
		||||
	/*[StaticConstructorOnStartup]
 | 
			
		||||
	public static class HarmonyPatch_RimNudeWorld
 | 
			
		||||
	{
 | 
			
		||||
		static HarmonyPatch_RimNudeWorld()
 | 
			
		||||
		{
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				((Action)(() =>
 | 
			
		||||
				{
 | 
			
		||||
					if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageIdPlayerFacing == "shauaputa.rimnudeworld"))
 | 
			
		||||
					{
 | 
			
		||||
						(new Harmony("Rimworld_Animations_Patch")).Patch(AccessTools.Method(AccessTools.TypeByName("RevealingApparel.HarmonyPatch_DrawAddons"), "Postfix"),
 | 
			
		||||
							prefix: new HarmonyMethod(AccessTools.Method(typeof(HarmonyPatch_RimNudeWorld), "Prefix_HarmonyPatch_DrawAddons")));
 | 
			
		||||
					}
 | 
			
		||||
				}))();
 | 
			
		||||
			}
 | 
			
		||||
			catch (TypeLoadException) { }
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Patch RimNudeWorld to override the revealing apparel feature; this task is handled by the new apparel settings system
 | 
			
		||||
		public static bool Prefix_HarmonyPatch_DrawAddons()
 | 
			
		||||
		{
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}*/
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +163,7 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
					if (bodyAddonDatum.alignsWithHead)
 | 
			
		||||
					{ bodyAngle = MathUtility.ClampAngle(animatorComp.headAngle); }
 | 
			
		||||
 | 
			
		||||
					if (animatorComp.controlGenitalAngle && (addonGraphic.path.Contains("penis") || addonGraphic.path.Contains("Penis")))
 | 
			
		||||
					if (animatorComp.controlGenitalAngle && addonGraphic.path.Contains("penis", StringComparison.OrdinalIgnoreCase))
 | 
			
		||||
					{ bodyAddonAngle = MathUtility.ClampAngle(bodyAddonAngle + (AnimationSettings.controlGenitalRotation ? MathUtility.ClampAngle(animatorComp.genitalAngle) : 0f)); }
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -205,30 +205,6 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Add-ons
 | 
			
		||||
			if (animatorComp?.isAnimating == true)
 | 
			
		||||
			{
 | 
			
		||||
				//ActorAnimationData actorData = pawn.GetAnimationData();
 | 
			
		||||
				//PawnAnimationClipExt clip = actorData.animationDef.animationStages[actorData.currentStage].animationClips[actorData.actorID] as PawnAnimationClipExt;
 | 
			
		||||
 | 
			
		||||
				/*foreach (ActorAddon addon in clip.Addons)
 | 
			
		||||
				{
 | 
			
		||||
					actorBodypart = actorBody.GetActorBodyPart(addon.AddonName);
 | 
			
		||||
					if (actorBodypart == null) continue;
 | 
			
		||||
 | 
			
		||||
					ActorBody anchoringActorBody = actorBodies.GetComponentsInChildren<ActorBody>()?.FirstOrDefault(x => x.actorID == addon.AnchoringActor);
 | 
			
		||||
					Vector3 anchor = PawnUtility.GetBodyPartAnchor(anchoringActorBody, addon.anchorName);
 | 
			
		||||
 | 
			
		||||
					actorBodypart.transform.position = anchor + new Vector3(addon.PosX.Evaluate(clipPercent), addon.PosZ.Evaluate(clipPercent), 0);
 | 
			
		||||
					actorBodypart.transform.eulerAngles = new Vector3(0, 0, -addon.Rotation.Evaluate(clipPercent));
 | 
			
		||||
 | 
			
		||||
					actorBodypart.bodyPartRenderer.sortingLayerName = addon.Layer;
 | 
			
		||||
					//actorBodypart.bodyPartRenderer.sprite
 | 
			
		||||
 | 
			
		||||
					actorBodypart.gameObject.SetActive(addon.Render);
 | 
			
		||||
				}*/
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Body addons are sometimes are not appropriately concealed by long hair in portraits, so re-draw the pawn's hair here
 | 
			
		||||
			if (pawn.Drawer.renderer.graphics.headGraphic != null && renderFlags.FlagSet(PawnRenderFlags.Portrait) && BasicSettings.redrawHair)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,8 +42,8 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
 | 
			
		||||
	public class ApparelSettingsDisplay : Mod
 | 
			
		||||
	{
 | 
			
		||||
		private const float windowY = 290f;
 | 
			
		||||
		private const float windowHeight = 320f;
 | 
			
		||||
		private const float windowY = 240f;
 | 
			
		||||
		private const float windowHeight = 360f;
 | 
			
		||||
 | 
			
		||||
		private Vector2 scrollPosition;
 | 
			
		||||
		private const float scrollBarWidthMargin = 18f;
 | 
			
		||||
| 
						 | 
				
			
			@ -62,10 +62,10 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
		private const float singleColumnWidth = 100f;
 | 
			
		||||
		private const float doubleColumnWidth = 180f;
 | 
			
		||||
 | 
			
		||||
		private IEnumerable<ThingDef> shortListedApparelDefs = new List<ThingDef>();
 | 
			
		||||
		private IEnumerable<ThingDef> allApparelDefs = new List<ThingDef>();
 | 
			
		||||
		private List<ThingDef> shortListedApparelDefs = new List<ThingDef>();
 | 
			
		||||
		private List<ThingDef> allApparelDefs = new List<ThingDef>();
 | 
			
		||||
 | 
			
		||||
		private IEnumerable<ModContentPack> relevantModContentPacks = new List<ModContentPack>();
 | 
			
		||||
		private List<ModContentPack> relevantModContentPacks = new List<ModContentPack>();
 | 
			
		||||
		private ModContentPack currentModContentPack;
 | 
			
		||||
		
 | 
			
		||||
		public ApparelSettingsDisplay(ModContentPack content) : base(content)
 | 
			
		||||
| 
						 | 
				
			
			@ -161,18 +161,19 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
			bool isEnabled = false;
 | 
			
		||||
 | 
			
		||||
			// Get a list of apparel and mods of interest
 | 
			
		||||
			if (allApparelDefs.Any() == false)
 | 
			
		||||
			if (allApparelDefs.NullOrEmpty())
 | 
			
		||||
			{
 | 
			
		||||
				allApparelDefs = ApparelSettingsUtility.GetApparelOfInterest();
 | 
			
		||||
 | 
			
		||||
				foreach (ThingDef thingDef in allApparelDefs)
 | 
			
		||||
				{
 | 
			
		||||
					if (relevantModContentPacks.Contains(thingDef.modContentPack) == false)
 | 
			
		||||
					{ relevantModContentPacks.Append(thingDef.modContentPack); }
 | 
			
		||||
				}
 | 
			
		||||
				{ relevantModContentPacks.AddDistinct(thingDef.modContentPack); }
 | 
			
		||||
 | 
			
		||||
				currentModContentPack = relevantModContentPacks.First();
 | 
			
		||||
				shortListedApparelDefs = allApparelDefs.Where(x => x.modContentPack == currentModContentPack);
 | 
			
		||||
				currentModContentPack = relevantModContentPacks.FirstOrDefault();
 | 
			
		||||
				
 | 
			
		||||
				if (currentModContentPack == null)
 | 
			
		||||
				{ DebugMode.Message("ERROR: No mod content has been loaded?"); return; }
 | 
			
		||||
 | 
			
		||||
				shortListedApparelDefs = allApparelDefs.Where(x => x.modContentPack == currentModContentPack)?.ToList();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Ensure that all apparel has associated RimNudeData
 | 
			
		||||
| 
						 | 
				
			
			@ -182,44 +183,29 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
			// Add buttons to the top of the main window
 | 
			
		||||
			innerX = halfColumnWidth;
 | 
			
		||||
 | 
			
		||||
			// Mod selection button
 | 
			
		||||
			if (Widgets.ButtonText(new Rect(innerX + SettingsUtility.Align(labelWidth, doubleColumnWidth), windowY - 2 * headerHeight - 5, 2 * doubleColumnWidth + 10, headerHeight), currentModContentPack.Name))
 | 
			
		||||
			{
 | 
			
		||||
			if (shortListedApparelDefs.NullOrEmpty()) return;
 | 
			
		||||
 | 
			
		||||
			// Apparel
 | 
			
		||||
			tempRect = new Rect(innerX + SettingsUtility.Align(labelWidth, doubleColumnWidth), windowY - headerHeight - 5, labelWidth, headerHeight);
 | 
			
		||||
			Widgets.DrawHighlightIfMouseover(tempRect);
 | 
			
		||||
			TooltipHandler.TipRegion(tempRect, "List of apparel that covers the legs and/or torso. Use the provided drop down menu to load apparel settings for different mods.");
 | 
			
		||||
 | 
			
		||||
			if (Widgets.ButtonText(tempRect, "Apparel - " + currentModContentPack.ModMetaData.Name)) {
 | 
			
		||||
				List<FloatMenuOption> options = new List<FloatMenuOption> { };
 | 
			
		||||
 | 
			
		||||
				foreach (ModContentPack modContentPack in relevantModContentPacks)
 | 
			
		||||
				{
 | 
			
		||||
					FloatMenuOption option = new FloatMenuOption(modContentPack.Name, delegate ()
 | 
			
		||||
						{ 
 | 
			
		||||
							currentModContentPack = modContentPack;
 | 
			
		||||
							shortListedApparelDefs = allApparelDefs.Where(x => x.modContentPack == currentModContentPack);
 | 
			
		||||
						},
 | 
			
		||||
					FloatMenuOption option = new FloatMenuOption(modContentPack.ModMetaData.Name, delegate ()
 | 
			
		||||
					{
 | 
			
		||||
						currentModContentPack = modContentPack;
 | 
			
		||||
						shortListedApparelDefs = allApparelDefs.Where(x => x.modContentPack == currentModContentPack)?.ToList();
 | 
			
		||||
					},
 | 
			
		||||
						MenuOptionPriority.Default, null, null, 0f, null, null, true, 0);
 | 
			
		||||
 | 
			
		||||
					options.Add(option);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Find.WindowStack.Add(new FloatMenu(options));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (shortListedApparelDefs.Any() == false) return;
 | 
			
		||||
 | 
			
		||||
			// Apparel
 | 
			
		||||
			tempRect = new Rect(innerX + SettingsUtility.Align(labelWidth, doubleColumnWidth), windowY - headerHeight - 5, labelWidth, headerHeight);
 | 
			
		||||
			Widgets.DrawHighlightIfMouseover(tempRect);
 | 
			
		||||
			TooltipHandler.TipRegion(tempRect, "List of apparel that covers the legs and/or torso. This list can be sorted alphabetically or by the mod that added them.");
 | 
			
		||||
 | 
			
		||||
			if (Widgets.ButtonText(tempRect, "Apparel"))
 | 
			
		||||
			{
 | 
			
		||||
				List<FloatMenuOption> options = new List<FloatMenuOption>
 | 
			
		||||
			{
 | 
			
		||||
				new FloatMenuOption("Sort by name", delegate()
 | 
			
		||||
				{ shortListedApparelDefs = shortListedApparelDefs.OrderBy(x => x.label);
 | 
			
		||||
				}, MenuOptionPriority.Default, null, null, 0f, null, null, true, 0),
 | 
			
		||||
				new FloatMenuOption("Sort by mod", delegate()
 | 
			
		||||
				{ shortListedApparelDefs = ApparelSettingsUtility.GetApparelOfInterest();
 | 
			
		||||
				}, MenuOptionPriority.Default, null, null, 0f, null, null, true, 0),
 | 
			
		||||
			}; Find.WindowStack.Add(new FloatMenu(options));
 | 
			
		||||
			}; innerX += doubleColumnWidth;
 | 
			
		||||
 | 
			
		||||
			// Covers groin
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,6 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
			RenderTexture.active = rt;
 | 
			
		||||
			if (mat != null)
 | 
			
		||||
			{ Graphics.Blit(source, rt, mat); }
 | 
			
		||||
			
 | 
			
		||||
			else
 | 
			
		||||
			{ Graphics.Blit(source, rt); }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -49,7 +48,7 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
				DebugMode.Message("mainTex or maskTex is missing!");
 | 
			
		||||
				return mainTex;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		
 | 
			
		||||
			Color[] mainArray = GetReadableTexture2D(mainTex).GetPixels();
 | 
			
		||||
			Color[] maskArray = GetReadableTexture2D(maskTex, mainTex.width, mainTex.height).GetPixels();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +63,7 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
				else if (mainArray[j].a > 0 && maskArray[j].a > 0 && writeOverMainTex)
 | 
			
		||||
				{ mainArray[j] = new Color(Mathf.Min(mainArray[j].r, maskArray[j].r), Mathf.Min(mainArray[j].g, maskArray[j].g), Mathf.Min(mainArray[j].b, maskArray[j].b), Mathf.Min(mainArray[j].a, maskArray[j].a)); }
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			Texture2D newTex = new Texture2D(mainTex.width, mainTex.height, TextureFormat.RGBA32, mipChain: true);
 | 
			
		||||
			newTex.SetPixels(mainArray);
 | 
			
		||||
			newTex.filterMode = FilterMode.Trilinear;
 | 
			
		||||
| 
						 | 
				
			
			@ -74,71 +73,23 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
			return newTex;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Graphic ApplyGraphicWithMasks(Graphic graphic, Graphic graphicWithMask, bool writeOverMainTex)
 | 
			
		||||
		public static Graphic ApplyGraphicMasks(Graphic graphic, Graphic graphicWithMask, bool writeOverMainTex)
 | 
			
		||||
		{
 | 
			
		||||
			for (int i = 0; i < 4; i++)
 | 
			
		||||
			{
 | 
			
		||||
				Texture2D mainTex = (Texture2D)graphic.MatAt(new Rot4(i)).mainTexture;
 | 
			
		||||
				Texture2D maskTex = graphicWithMask.MatAt(new Rot4(i)).GetMaskTexture();
 | 
			
		||||
				graphic.MatAt(new Rot4(i)).mainTexture = ApplyMaskToTexture2D(mainTex, maskTex, writeOverMainTex);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return graphic;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static Graphic ApplyGraphicWithMasks(Graphic graphic, string mask, bool writeOverMainTex)
 | 
			
		||||
		{
 | 
			
		||||
			for (int i = 0; i < 4; i++)
 | 
			
		||||
			{
 | 
			
		||||
				Texture2D mainTex = (Texture2D)graphic.MatAt(new Rot4(i)).mainTexture;
 | 
			
		||||
 | 
			
		||||
				if (mainTex == null)
 | 
			
		||||
				{ DebugMode.Message("Main Texture2D not found for " + graphic.path + ". Rotation: " + i.ToString()); continue; }
 | 
			
		||||
 | 
			
		||||
				string suffix = string.Empty;
 | 
			
		||||
				switch (i)
 | 
			
		||||
				{
 | 
			
		||||
					case 0: suffix = "_north"; break;
 | 
			
		||||
					case 1: suffix = "_east"; break;
 | 
			
		||||
					case 2: suffix = "_south"; break;
 | 
			
		||||
					case 3: suffix = "_west"; break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Texture2D maskTex = ContentFinder<Texture2D>.Get(mask + suffix, false);
 | 
			
		||||
 | 
			
		||||
				if (maskTex == null)
 | 
			
		||||
				{ DebugMode.Message("Mask Texture2D not found for " + mask + ". Rotation: " + i.ToString()); continue; }
 | 
			
		||||
				{ DebugMode.Message("Mask Texture2D not found for " + graphic.path + ". Rotation: " + i.ToString()); continue; }
 | 
			
		||||
 | 
			
		||||
				graphic.MatAt(new Rot4(i)).mainTexture = ApplyMaskToTexture2D(mainTex, maskTex, writeOverMainTex);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return graphic;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		public static void ResetGraphic(Graphic graphic)
 | 
			
		||||
		{
 | 
			
		||||
			for (int i = 0; i < 4; i++)
 | 
			
		||||
			{
 | 
			
		||||
				string suffix = string.Empty;
 | 
			
		||||
				switch (i)
 | 
			
		||||
				{
 | 
			
		||||
					case 0: suffix = "_north"; break;
 | 
			
		||||
					case 1: suffix = "_east"; break;
 | 
			
		||||
					case 2: suffix = "_south"; break;
 | 
			
		||||
					case 3: suffix = "_west"; break;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				Texture2D texture2D = ContentFinder<Texture2D>.Get(graphic.path + suffix, false);
 | 
			
		||||
 | 
			
		||||
				if (texture2D == null && i == 3)
 | 
			
		||||
				{ texture2D = ContentFinder<Texture2D>.Get(graphic.path + "_east", false); }
 | 
			
		||||
		
 | 
			
		||||
				if (texture2D == null)
 | 
			
		||||
				{ texture2D = ContentFinder<Texture2D>.Get(graphic.path + "_north", false); }
 | 
			
		||||
 | 
			
		||||
				if (texture2D != null)
 | 
			
		||||
				{ graphic.MatAt(new Rot4(i)).mainTexture = texture2D; }
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ namespace Rimworld_Animations_Patch
 | 
			
		|||
                {
 | 
			
		||||
                    IEnumerable<IntVec3> cells = GenRadial.RadialCellsAround(pawn.Position, radius + 0.75f, false).Where(x => x.Standable(pawn.Map) && x.GetRoom(pawn.Map) == pawn.GetRoom());
 | 
			
		||||
 | 
			
		||||
                    if (cells.Any() == true && cells.Count() > 0)
 | 
			
		||||
                    if (cells?.Any() == true && cells.Count() > 0)
 | 
			
		||||
                    { return cells.RandomElement(); }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue