mirror of
https://gitgud.io/ll.mirrors/sizedapparel.git
synced 2024-08-15 00:43:40 +00:00
Mirror of 1.4.15 from Lovers Lab
This commit is contained in:
parent
9a3d9f4185
commit
a5ed05c17b
1180 changed files with 4378 additions and 1905 deletions
|
@ -11,10 +11,4 @@ namespace SizedApparel
|
|||
class AlienRaceSupport
|
||||
{
|
||||
}
|
||||
|
||||
public class SizedApparelPawnDef : Def
|
||||
{
|
||||
public bool allowForceHumanlike = false;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||
|
||||
namespace SizedApparel
|
||||
{
|
||||
//Does it better to optimize?
|
||||
public class Graphic_BodyParts : Verse.Graphic_Multi
|
||||
{
|
||||
public float serverity;
|
||||
|
|
|
@ -3,11 +3,17 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
|
||||
namespace SizedApparel
|
||||
{
|
||||
public class Graphic_SizedApparel : Verse.Graphic_Multi
|
||||
//Does it better to optimize?
|
||||
public class Graphic_SizedApparel : Graphic_Multi
|
||||
{
|
||||
|
||||
public string TargetBodyParts = "Breats";
|
||||
//Sized Graphics.
|
||||
public List<Graphic_Multi> graphics;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using HarmonyLib;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using HarmonyLib;
|
||||
//using Rimworld_Animations;
|
||||
//using AlienRace;
|
||||
using UnityEngine;
|
||||
using rjw;
|
||||
using Rimworld_Animations;
|
||||
using RevealingApparel;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Verse;
|
||||
|
||||
namespace SizedApparel
|
||||
{
|
||||
|
@ -87,6 +82,22 @@ namespace SizedApparel
|
|||
{
|
||||
LicentiaActive = true;
|
||||
}
|
||||
if (!LicentiaActive)
|
||||
{
|
||||
if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId.ToLower() == "Euclidean.LustLicentia.RJWLabs".ToLower()))
|
||||
{
|
||||
LicentiaActive = true;
|
||||
}
|
||||
}
|
||||
if (!LicentiaActive)
|
||||
{
|
||||
if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId.ToLower().Contains("LustLicentia.RJWLabs".ToLower())))
|
||||
{
|
||||
LicentiaActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//check rjw animation
|
||||
if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId.ToLower() == "c0ffee.rimworld.animations".ToLower()))
|
||||
|
@ -186,7 +197,7 @@ namespace SizedApparel
|
|||
{
|
||||
Log.Message("[SizedApparel] RimworldAnimaion(rjw animation) Found");
|
||||
|
||||
harmony.Patch(AccessTools.Method(typeof(CompBodyAnimator), "tickClip"),
|
||||
harmony.Patch(AccessTools.Method(typeof(Rimworld_Animations.CompBodyAnimator), "tickClip"),
|
||||
postfix: new HarmonyMethod(typeof(RimworldAnimationPatch), "TickClipPostfix"));
|
||||
|
||||
harmony.Patch(AccessTools.Method(typeof(JobDriver_SexBaseInitiator), "End"),
|
||||
|
|
105
source/SizedApparel/Patch-Animation.cs
Normal file
105
source/SizedApparel/Patch-Animation.cs
Normal file
|
@ -0,0 +1,105 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
//using Rimworld_Animations;
|
||||
|
||||
namespace SizedApparel
|
||||
{
|
||||
|
||||
public class RimworldAnimationPatch
|
||||
{
|
||||
//since instance (CompBodyAnimator class) must be soft dependency, Get as System.Object.
|
||||
public static void TickClipPostfix(System.Object __instance) //CompBodyAnimator __instance, AnimationDef ___anim, int ___curStage, int ___actor, int ___clipTicks, float ___clipPercent
|
||||
{
|
||||
Rimworld_Animations.CompBodyAnimator instance = __instance as Rimworld_Animations.CompBodyAnimator;
|
||||
|
||||
if (instance == null)
|
||||
return;
|
||||
|
||||
if (!instance.controlGenitalAngle)
|
||||
return;
|
||||
|
||||
var comp = instance.parent.GetComp<ApparelRecorderComp>();
|
||||
if (comp == null)
|
||||
return;
|
||||
|
||||
|
||||
comp.SetPenisAngle(instance.genitalAngle - instance.bodyAngle); //genitalAngle is global Angle value in rjwanimation... fix with body Angle;
|
||||
|
||||
|
||||
if (!SizedApparelSettings.AnimationPatch)//Rotating Penis Setting(avobe) is set from RimworldAnimation Setting, not in SizedApparel.
|
||||
return;
|
||||
|
||||
foreach (var actor in instance.actorsInCurrentAnimation)
|
||||
{
|
||||
//comp.ForceUpdateTickAnimation = true;
|
||||
var actorcomp = actor.GetComp<ApparelRecorderComp>();
|
||||
//actorcomp.SetBreastJiggle(true);
|
||||
actorcomp.ForceUpdateTickAnimation = true;
|
||||
|
||||
}
|
||||
return;
|
||||
bool isFuckTick = false;
|
||||
/*
|
||||
var soundEffects = ((PawnAnimationClip)___anim.animationStages[___curStage].animationClips[___actor]).SoundEffects;
|
||||
if (soundEffects.ContainsKey(___clipTicks) && (soundEffects[___clipTicks].Contains("Fuck") || soundEffects[___clipTicks].Contains("Suck")))
|
||||
{
|
||||
isFuckTick = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int jiggleTime = 3;
|
||||
for(int i = 0; i < jiggleTime; i++)
|
||||
{
|
||||
if (soundEffects.ContainsKey(___clipTicks - i) && soundEffects[___clipTicks - i].Contains("Fuck"))
|
||||
{
|
||||
isFuckTick = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
//need to find partner's breasts.
|
||||
/*
|
||||
if (isFuckTick)
|
||||
{
|
||||
foreach (var actor in __instance.actorsInCurrentAnimation)
|
||||
{
|
||||
actor.GetComp<ApparelRecorderComp>().SetBreastJiggle(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var actor in __instance.actorsInCurrentAnimation)
|
||||
{
|
||||
actor.GetComp<ApparelRecorderComp>().SetBreastJiggle(false);
|
||||
}
|
||||
}*/
|
||||
//may have some tick issue? too fast jiggle?
|
||||
}
|
||||
|
||||
//rjw's JobDriver_SexBaseInitiator end patch
|
||||
public static void EndClipPostfix(System.Object __instance)//CompBodyAnimator __instance
|
||||
{
|
||||
Rimworld_Animations.CompBodyAnimator instance = __instance as Rimworld_Animations.CompBodyAnimator;
|
||||
if (instance == null)
|
||||
return;
|
||||
|
||||
if (!instance.controlGenitalAngle)
|
||||
return;
|
||||
var comp = instance.parent.GetComp<ApparelRecorderComp>();
|
||||
if (comp == null)
|
||||
return;
|
||||
comp.SetBreastJiggle(false, -1);
|
||||
comp.ForceUpdateTickAnimation = false;
|
||||
comp.SetPenisAngle(0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -21,7 +21,7 @@ namespace SizedApparel
|
|||
ApparelRecorderComp comp = pawn?.GetComp<ApparelRecorderComp>();
|
||||
if (comp == null)
|
||||
return;
|
||||
comp.SetDirty();
|
||||
comp.SetDirty(true,true,true);
|
||||
/*
|
||||
comp.ClearAll();
|
||||
var graphicSet = pawn.Drawer?.renderer?.graphics;
|
|
@ -10,22 +10,42 @@ using Verse;
|
|||
|
||||
namespace SizedApparel
|
||||
{
|
||||
public struct Depth4Offsets
|
||||
public class Depth4Offsets
|
||||
{
|
||||
float South;
|
||||
float North;
|
||||
float East;
|
||||
float West;
|
||||
public float south=0;
|
||||
public float north=0;
|
||||
public float east=0;
|
||||
public float west=0;
|
||||
|
||||
public Depth4Offsets() { }
|
||||
|
||||
public Depth4Offsets(Vector4 arg)
|
||||
{
|
||||
south = arg.x;
|
||||
north = arg.y;
|
||||
east = arg.z;
|
||||
west = arg.w;
|
||||
}
|
||||
public Depth4Offsets(float s, float n, float e, float w)
|
||||
{
|
||||
south = s;
|
||||
north = n;
|
||||
east = e;
|
||||
west = w;
|
||||
}
|
||||
}
|
||||
|
||||
public struct Rot4Offsets
|
||||
public class Rot4Offsets
|
||||
{
|
||||
//X: right and left
|
||||
//Y: Frong or Back
|
||||
//Z: Up and Down
|
||||
Vector3 South;
|
||||
|
||||
Vector3 North;
|
||||
|
||||
Vector3 East;
|
||||
|
||||
Vector3 West;
|
||||
|
||||
public Rot4Offsets(Vector3 vector)
|
||||
|
@ -66,11 +86,25 @@ namespace SizedApparel
|
|||
public string bodyType;
|
||||
}
|
||||
|
||||
public class BodyWithBodyType
|
||||
{
|
||||
public string bodyType;
|
||||
public List<BodyPart> Addons = new List<BodyPart>();
|
||||
}
|
||||
|
||||
public class BodyPart
|
||||
{
|
||||
public string partName;
|
||||
public Depth4Offsets depthOffset;
|
||||
public List<BodyTypeAndOffset> offsets;
|
||||
public string partName = null;
|
||||
public string customPath = null;
|
||||
public string defaultHediffName = null; // for missing Hediff
|
||||
public bool isBreasts = false;
|
||||
public bool centeredTexture = false;
|
||||
public string boneName = null;
|
||||
public Bone bone = null; // For Graphic Positioning System
|
||||
public SizedApparelBodyPartOf bodyPartOf = SizedApparelBodyPartOf.None;
|
||||
public ColorType colorType = ColorType.Skin;
|
||||
public Depth4Offsets depthOffset = new Depth4Offsets();
|
||||
public BodyTypeAndOffset offsets = new BodyTypeAndOffset();
|
||||
}
|
||||
|
||||
public class BodyTypeAndOffset
|
||||
|
@ -79,11 +113,16 @@ namespace SizedApparel
|
|||
public string bodyType;
|
||||
public Rot4Offsets offsets = new Rot4Offsets(Vector3.zero);
|
||||
|
||||
public BodyTypeAndOffset()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public BodyTypeAndOffset(bool useCenter)
|
||||
{
|
||||
if (useCenter)
|
||||
{
|
||||
offsets = new Rot4Offsets(new Vector3(0.5f, 0, 0.5f));
|
||||
offsets = new Rot4Offsets(Vector3.zero);
|
||||
}
|
||||
}
|
||||
public BodyTypeAndOffset(Vector3 defaultOffset)
|
||||
|
@ -92,7 +131,7 @@ namespace SizedApparel
|
|||
}
|
||||
}
|
||||
|
||||
public enum SizedApparelBodyPartColorOf
|
||||
public enum ColorType
|
||||
{
|
||||
Skin, Hair, Custom, None
|
||||
}
|
||||
|
@ -100,7 +139,7 @@ namespace SizedApparel
|
|||
|
||||
public enum SizedApparelBodyPartOf
|
||||
{
|
||||
All, Torso, Breasts, Crotch, Penis, Vagina, Anus, Belly, Udder, Hips, Thighs, hands, feet, None
|
||||
All, Torso, Breasts, Crotch, Penis, Balls, Vagina, Anus, Belly, PubicHair, Udder, Hips, Thighs, hands, feet, None
|
||||
}
|
||||
public static class SizedApparelBodyPartOfExtension
|
||||
{
|
||||
|
@ -122,13 +161,17 @@ namespace SizedApparel
|
|||
return true;
|
||||
return false;
|
||||
case SizedApparelBodyPartOf.Crotch:
|
||||
if (source == SizedApparelBodyPartOf.Penis || source == SizedApparelBodyPartOf.Vagina || source == SizedApparelBodyPartOf.Anus)
|
||||
if (source == SizedApparelBodyPartOf.Crotch || source == SizedApparelBodyPartOf.Penis || source == SizedApparelBodyPartOf.Vagina || source == SizedApparelBodyPartOf.Anus || source == SizedApparelBodyPartOf.PubicHair || source == SizedApparelBodyPartOf.Balls)
|
||||
return true;
|
||||
return false;
|
||||
case SizedApparelBodyPartOf.Penis:
|
||||
if (source == SizedApparelBodyPartOf.Penis)
|
||||
return true;
|
||||
return false;
|
||||
case SizedApparelBodyPartOf.Balls:
|
||||
if (source == SizedApparelBodyPartOf.Balls)
|
||||
return true;
|
||||
return false;
|
||||
case SizedApparelBodyPartOf.Vagina:
|
||||
if (source == SizedApparelBodyPartOf.Vagina)
|
||||
return true;
|
||||
|
@ -161,10 +204,13 @@ namespace SizedApparel
|
|||
if (source == SizedApparelBodyPartOf.feet)
|
||||
return true;
|
||||
return false;
|
||||
case SizedApparelBodyPartOf.PubicHair:
|
||||
if (source == SizedApparelBodyPartOf.PubicHair)
|
||||
return true;
|
||||
return false;
|
||||
case SizedApparelBodyPartOf.None:
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
Log.Error("[SizedApparel] missing SizedApparelBodyPartOf!");
|
||||
return false;
|
||||
|
@ -186,7 +232,7 @@ namespace SizedApparel
|
|||
public class GraphicPoint
|
||||
{
|
||||
public string pointName;
|
||||
public Vector2 point = new Vector2(0.5f, 0.5f);
|
||||
public Vector2 point = Vector2.zero;
|
||||
}
|
||||
public class GraphicPointsWithBodyType
|
||||
{
|
||||
|
@ -197,13 +243,13 @@ namespace SizedApparel
|
|||
public class PointWithBodyType
|
||||
{
|
||||
public string bodyTypeName; //null can be used too
|
||||
public Vector2 point = new Vector2(0.5f,0.5f);
|
||||
public Vector2 point = Vector2.zero;
|
||||
}
|
||||
|
||||
public struct BodyPartPoint
|
||||
public class BodyPartPoint
|
||||
{
|
||||
string name;
|
||||
Vector2 position;//Uv position. not pixel
|
||||
Vector2 position = Vector2.zero;//Uv position. not pixel
|
||||
}
|
||||
|
||||
[Obsolete]//todo
|
||||
|
@ -211,11 +257,7 @@ namespace SizedApparel
|
|||
{
|
||||
|
||||
}
|
||||
|
||||
public enum ColorMode
|
||||
{
|
||||
Skin, Hair
|
||||
}
|
||||
|
||||
|
||||
//Def for Hediff Graphic color options or else.
|
||||
public class SizedApparelHeddifDef : Def
|
||||
|
@ -226,6 +268,7 @@ namespace SizedApparel
|
|||
}
|
||||
|
||||
//Def per graphic(texture)
|
||||
[Obsolete]
|
||||
public class SizedApparelBodyPartGraphicDef : Def
|
||||
{
|
||||
public string graphicPath;
|
||||
|
@ -239,8 +282,9 @@ namespace SizedApparel
|
|||
public class SizedApparelBodyPartDef : Def
|
||||
{
|
||||
SizedApparelBodyPartOf bodyPartOf = SizedApparelBodyPartOf.None;
|
||||
public bool canPose = false;
|
||||
public bool canAnimate = false;
|
||||
public bool canPose = true;
|
||||
public List<string> TexturePaths;
|
||||
|
||||
}
|
||||
|
||||
public class SizedApparelBodyPart
|
||||
|
@ -249,7 +293,7 @@ namespace SizedApparel
|
|||
|
||||
public bool AutoOffsetForFurCoveredBody = true;
|
||||
|
||||
public SizedApparelBodyPart(Pawn pawn, ApparelRecorderComp apparelRecorderComp, string bodyPartName, SizedApparelBodyPartOf bodyPartOf, string defaultHediffName, bool isBreast, bool isOverlay , string customPathName = null, SizedApparelBodyPartColorOf colorOf = SizedApparelBodyPartColorOf.Skin)
|
||||
public SizedApparelBodyPart(Pawn pawn, ApparelRecorderComp apparelRecorderComp, string bodyPartName, SizedApparelBodyPartOf bodyPartOf, string defaultHediffName, bool isBreast, bool isOverlay, string customPathName = null, ColorType colorOf = ColorType.Skin, Bone parentBone = null, bool isCenteredTexture = false)
|
||||
{
|
||||
this.pawn = pawn; //owner
|
||||
|
||||
|
@ -265,6 +309,14 @@ namespace SizedApparel
|
|||
this.isOverlay = isOverlay;
|
||||
this.customPath = customPathName;
|
||||
this.colorType = colorOf;
|
||||
|
||||
this.bone = parentBone;
|
||||
this.centeredTexture = isCenteredTexture;
|
||||
}
|
||||
|
||||
public void SetCenteredTexture(bool isCentered)
|
||||
{
|
||||
this.centeredTexture = isCentered;
|
||||
}
|
||||
|
||||
public Vector2 OffsetFromUVOffset(Vector2 vector, Mesh mesh , bool isFliped = false)
|
||||
|
@ -272,10 +324,21 @@ namespace SizedApparel
|
|||
//treat mesh as plane
|
||||
//Vector3 width = mesh.vertices[2] - mesh.vertices[1];
|
||||
//Vector3 height = mesh.vertices[1] - mesh.vertices[2];
|
||||
Vector2 loc = new Vector2(0.5f, 0.5f) - vector;
|
||||
|
||||
|
||||
if(!isFliped)
|
||||
return new Vector2((mesh.vertices[2].x - mesh.vertices[0].x)*vector.x,(mesh.vertices[0].z - mesh.vertices[2].z)*vector.y);
|
||||
return new Vector2((mesh.vertices[2].x - mesh.vertices[0].x)*vector.x, (mesh.vertices[2].z - mesh.vertices[0].z)*vector.y);
|
||||
/*
|
||||
* Vector2 loc = new Vector2(0.5f, 0.5f) - vector;
|
||||
if(!isFliped)
|
||||
return new Vector2(Mathf.Lerp(mesh.vertices[0].x, mesh.vertices[2].x, loc.x), Mathf.Lerp(mesh.vertices[0].z, mesh.vertices[2].z, loc.y));
|
||||
return new Vector2(Mathf.Lerp(mesh.vertices[3].x, mesh.vertices[1].x, loc.x), Mathf.Lerp(mesh.vertices[3].z, mesh.vertices[1].z, loc.y));
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
//public Vector2 OffestFromUVOffset(Vector2 vector, Vector2 drawSize, bool isFliped = false)
|
||||
|
@ -284,6 +347,9 @@ namespace SizedApparel
|
|||
|
||||
public Pawn pawn;
|
||||
public ApparelRecorderComp apparelRecorderCompCache; // for reduce getComp call;
|
||||
public Bone bone;
|
||||
|
||||
public bool centeredTexture = false; // false to keep original position from mesh. and consider this graphics pivot as bone position
|
||||
|
||||
public string bodyPartName; //breast, penis, belly, pubichair... etc. just name. not like architech something
|
||||
public string customPath = null;
|
||||
|
@ -291,6 +357,7 @@ namespace SizedApparel
|
|||
public string defaultHediffName;
|
||||
|
||||
public bool isBreast = false;
|
||||
|
||||
public bool isOverlay = false; //write z cache?
|
||||
|
||||
public string currentHediffName;
|
||||
|
@ -299,7 +366,7 @@ namespace SizedApparel
|
|||
|
||||
public int lastPoseTick = -1;
|
||||
|
||||
public SizedApparelBodyPartColorOf colorType = SizedApparelBodyPartColorOf.Skin;
|
||||
public ColorType colorType = ColorType.Skin;
|
||||
public Color? customColorOne;
|
||||
public Color? customColorTwo;
|
||||
|
||||
|
@ -320,6 +387,10 @@ namespace SizedApparel
|
|||
public int maxDrawAge = -1;
|
||||
|
||||
|
||||
public void SetBone(Bone bone)
|
||||
{
|
||||
this.bone = bone;
|
||||
}
|
||||
|
||||
public void SetCustomPose(string newPose, bool autoUpdate = true, bool autoSetPawnGraphicDirty = false)
|
||||
{
|
||||
|
@ -347,32 +418,8 @@ namespace SizedApparel
|
|||
{
|
||||
if (checkApparels)
|
||||
{
|
||||
foreach(ApparelGraphicRecord agr in pawn.Drawer.renderer.graphics.apparelGraphics)
|
||||
{
|
||||
/*
|
||||
if (!agr.sourceApparel.def.apparel.bodyPartGroups.Any(bpgd => bpgd.defName == "Torso" || bpgd.defName == "Chest"))
|
||||
continue;
|
||||
|
||||
if (agr.sourceApparel.def.apparel.tags.Any(s => s.ToLower() == "SizedApparel_IgnorePose".ToLower()))
|
||||
continue;
|
||||
*/
|
||||
//Only Check Torso Apparel Only
|
||||
if (!agr.sourceApparel.def.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Torso))
|
||||
continue;
|
||||
|
||||
string originalPath = SizedApparelsDatabase.GetSupportedApparelOriginalPath(agr.graphic.path);
|
||||
if (originalPath == null)
|
||||
return false;
|
||||
|
||||
int outInt = -1;
|
||||
float outFloat = -1;
|
||||
SizedApparelsDatabase.SizedApparelDatabaseKey key = new SizedApparelsDatabase.SizedApparelDatabaseKey(originalPath,pawn.def.defName,pawn.story?.bodyType?.defName, pawn.gender, currentHediffName, Math.Min(currentSeverityInt, cappedSeverityInt), false, targetPose);
|
||||
if (SizedApparelSettings.useGenderSpecificTexture)
|
||||
key.gender = Gender.None;
|
||||
var result = SizedApparelsDatabase.GetSupportedApparelSizedPath(key, out outInt, out outFloat);
|
||||
if (!result.isCustomPose)
|
||||
return false;
|
||||
}
|
||||
if (!SizedApparelUtility.CanPoseApparels(pawn, targetPose, currentHediffName, currentSeverityInt, cappedSeverityInt))
|
||||
return false;
|
||||
}
|
||||
if (checkBodyParts)
|
||||
{
|
||||
|
@ -390,20 +437,22 @@ namespace SizedApparel
|
|||
public int currentSeverityInt = -1;
|
||||
public int cappedSeverityInt = 1000; // supported severity from worn apparel graphics
|
||||
|
||||
public Vector2 pivot = new Vector2(0.5f, 0.5f);
|
||||
public Vector2 pivot = Vector2.zero;
|
||||
|
||||
public Vector2 position = Vector2.zero;//offset from pivot //UV. not pixel
|
||||
|
||||
public Dictionary<string, BodyPartPoint> points;
|
||||
public Dictionary<string, BodyPartPoint> pointsHorny;
|
||||
public SizedApparelTexturePointDef points;
|
||||
public SizedApparelTexturePointDef pointsHorny;
|
||||
|
||||
|
||||
public float rotation = 0; // +: rotate right, -: rotate left
|
||||
public Vector2 scale = Vector2.one;
|
||||
public float scale = 1f;
|
||||
|
||||
public Graphic bodyPartGraphic;
|
||||
public Graphic bodyPartGraphicHorny;
|
||||
|
||||
|
||||
|
||||
public Vector2 positionOffset = Vector2.zero; //offset from position //UV. not pixel
|
||||
public Vector2 positionOffsetSouth = Vector2.zero;
|
||||
public Vector2 positionOffsetNorth = Vector2.zero;
|
||||
|
@ -426,6 +475,13 @@ namespace SizedApparel
|
|||
depthOffsetEast = east;
|
||||
depthOffsetWest = west;
|
||||
}
|
||||
public void SetDepthOffsets(Depth4Offsets oppsets)
|
||||
{
|
||||
depthOffsetSouth = oppsets.south;
|
||||
depthOffsetNorth = oppsets.north;
|
||||
depthOffsetEast = oppsets.east;
|
||||
depthOffsetWest = oppsets.west;
|
||||
}
|
||||
public void SetPositionOffsets(Vector2 south, Vector2 north, Vector2 east, Vector2 west)
|
||||
{
|
||||
positionOffsetSouth = south;
|
||||
|
@ -435,11 +491,11 @@ namespace SizedApparel
|
|||
}
|
||||
public Graphic GetBodyPartGraphics(bool isHorny, bool mustMatchSize = false, string poseOverride = null)
|
||||
{
|
||||
Dictionary<string, BodyPartPoint> var;
|
||||
SizedApparelTexturePointDef var;
|
||||
return GetBodyPartGraphics(isHorny, out var, mustMatchSize, poseOverride);
|
||||
}
|
||||
|
||||
public Graphic GetBodyPartGraphics(bool isHorny, out Dictionary<string, BodyPartPoint> outPoints, bool mustMatchSize = false ,string poseOverride = null, string variationOverride = null)
|
||||
public Graphic GetBodyPartGraphics(bool isHorny, out SizedApparelTexturePointDef outPoints, bool mustMatchSize = false ,string poseOverride = null, string variationOverride = null)
|
||||
{
|
||||
if (pawn == null)
|
||||
{
|
||||
|
@ -454,11 +510,15 @@ namespace SizedApparel
|
|||
outPoints = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
var key = new SizedApparelsDatabase.BodyPartDatabaseKey(pawn.def.defName, pawn.story?.bodyType?.defName, currentHediffName, customPath==null?bodyPartName: customPath, pawn.gender, Math.Min(currentSeverityInt, cappedSeverityInt), isHorny, poseOverride==null?customPose:poseOverride, variationOverride==null?variation: variationOverride);
|
||||
string bodyTypeString = pawn.story?.bodyType?.defName;
|
||||
|
||||
var key = new SizedApparelsDatabase.BodyPartDatabaseKey(pawn.def.defName, bodyTypeString, currentHediffName, customPath==null?bodyPartName: customPath, pawn.gender, Math.Min(currentSeverityInt, cappedSeverityInt), isHorny, poseOverride==null?customPose:poseOverride, variationOverride==null?variation: variationOverride);
|
||||
var result = SizedApparelsDatabase.GetSupportedBodyPartPath(key, isBreast, customPath == null ? bodyPartName : customPath, defaultHediffName);
|
||||
|
||||
|
||||
|
||||
|
||||
if (mustMatchSize)
|
||||
if (Math.Min(currentSeverityInt, cappedSeverityInt) != result.size)
|
||||
{
|
||||
|
@ -492,7 +552,7 @@ namespace SizedApparel
|
|||
public void ResetTransform()
|
||||
{
|
||||
this.position = Vector2.zero;
|
||||
this.scale = Vector2.one;
|
||||
this.scale = 1f;
|
||||
this.rotation = 0;
|
||||
}
|
||||
|
||||
|
@ -533,7 +593,7 @@ namespace SizedApparel
|
|||
{
|
||||
if (!isVisible)
|
||||
return;
|
||||
if (scale == Vector2.zero)
|
||||
if (scale == 0f)
|
||||
return; //Don't draw if scale is zero
|
||||
if (pawn == null)
|
||||
return;
|
||||
|
@ -561,7 +621,7 @@ namespace SizedApparel
|
|||
HasFurSkin = true;
|
||||
}
|
||||
|
||||
if (colorType == SizedApparelBodyPartColorOf.Skin)
|
||||
if (colorType == ColorType.Skin)
|
||||
{
|
||||
forceWriteZ = true;
|
||||
if (bodyDrawType == RotDrawMode.Fresh)
|
||||
|
@ -597,14 +657,14 @@ namespace SizedApparel
|
|||
|
||||
|
||||
}
|
||||
else if (colorType == SizedApparelBodyPartColorOf.Hair)
|
||||
else if (colorType == ColorType.Hair)
|
||||
{
|
||||
forceWriteZ = false;
|
||||
shader = ShaderDatabase.Transparent;
|
||||
if(pawn.story != null)
|
||||
drawColor1 = pawn.story.HairColor;
|
||||
}
|
||||
else if (colorType == SizedApparelBodyPartColorOf.Custom)
|
||||
else if (colorType == ColorType.Custom)
|
||||
{
|
||||
forceWriteZ = true;
|
||||
shader = ShaderDatabase.Transparent;
|
||||
|
@ -613,7 +673,7 @@ namespace SizedApparel
|
|||
if (customColorTwo != null)
|
||||
drawColor2 = customColorTwo.Value;
|
||||
}
|
||||
else if (colorType == SizedApparelBodyPartColorOf.None)
|
||||
else if (colorType == ColorType.None)
|
||||
{
|
||||
forceWriteZ = false;
|
||||
shader = ShaderDatabase.Cutout;
|
||||
|
@ -621,13 +681,120 @@ namespace SizedApparel
|
|||
|
||||
|
||||
|
||||
Mesh scaledBodyMesh;
|
||||
|
||||
BoneTransform boneTransform = null;
|
||||
if(bone != null)
|
||||
{
|
||||
if (facing == Rot4.South)
|
||||
{
|
||||
boneTransform = bone.south;
|
||||
}
|
||||
else if (facing == Rot4.North)
|
||||
{
|
||||
boneTransform = bone.north;
|
||||
}
|
||||
else if (facing == Rot4.East)
|
||||
{
|
||||
boneTransform = bone.east;
|
||||
|
||||
}
|
||||
else if (facing == Rot4.West)
|
||||
{
|
||||
boneTransform = bone.west;
|
||||
if (boneTransform == null)
|
||||
boneTransform = bone.east;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
float drawScale = scale;
|
||||
float drawRotation = angle;
|
||||
Vector3 drawPosition = rootLoc;
|
||||
|
||||
if (boneTransform != null)
|
||||
{
|
||||
//TODO fixed angle for IK?
|
||||
|
||||
|
||||
if (centeredTexture)
|
||||
{
|
||||
bool westUsingEast = false;
|
||||
if (facing == Rot4.West && bone.west == null)
|
||||
westUsingEast = true;
|
||||
float width = (bodyMesh.vertices[2].x - bodyMesh.vertices[0].x);
|
||||
drawRotation = boneTransform.InitialAngle + boneTransform.angleOffset;
|
||||
//not sure it work correct
|
||||
Vector3 v = (boneTransform.InitialPosition + boneTransform.positionOffset) * width;
|
||||
var q = Quaternion.AngleAxis (westUsingEast? -angle : angle, Vector3.up);
|
||||
v = q * v;
|
||||
drawPosition = (v) ; // calculate rotated point
|
||||
|
||||
//Log.Message(boneTransform.angleOffset.ToString());
|
||||
if (westUsingEast)
|
||||
{
|
||||
//already scaled with "width"?
|
||||
//its using east as west. so flip position
|
||||
drawPosition.Scale(new Vector3(-1f,0f,1f));
|
||||
//drawRotation = boneTransform.InitialAngle - boneTransform.angleOffset;
|
||||
}
|
||||
drawPosition += rootLoc;
|
||||
drawRotation += angle ;
|
||||
}
|
||||
else
|
||||
{
|
||||
//wip
|
||||
bool westUsingEast = false;
|
||||
if (facing == Rot4.West && bone.west == null)
|
||||
westUsingEast = true;
|
||||
float width = (bodyMesh.vertices[2].x - bodyMesh.vertices[0].x);
|
||||
drawRotation = boneTransform.InitialAngle + boneTransform.angleOffset;
|
||||
//not sure it work correct
|
||||
Vector3 v = (-boneTransform.InitialPosition); //initialpos as custom pivot
|
||||
var q = Quaternion.AngleAxis(westUsingEast ? -drawRotation : drawRotation, Vector3.up);
|
||||
var q2 = Quaternion.AngleAxis(westUsingEast ? -angle : angle, Vector3.up);
|
||||
v = q * v; // calculate final draw position with torso angle
|
||||
v = v + boneTransform.InitialPosition + boneTransform.positionOffset;
|
||||
v = q2 * v;
|
||||
drawPosition = (v) * width;
|
||||
if (westUsingEast)
|
||||
{
|
||||
//already scaled with "width"?
|
||||
//its using east as west. so flip position
|
||||
drawPosition.Scale(new Vector3(-1f, 0f, 1f));
|
||||
//drawRotation = boneTransform.InitialAngle - boneTransform.angleOffset;
|
||||
}
|
||||
drawPosition += rootLoc ; // adjust with result
|
||||
//Log.Message(boneTransform.angleOffset.ToString());
|
||||
drawRotation += angle;
|
||||
}
|
||||
}
|
||||
|
||||
if (drawScale != 1f)
|
||||
{
|
||||
// scale Only Rimworld Plane Mesh
|
||||
if(bodyMesh.vertexCount == 4)
|
||||
{
|
||||
float width = (bodyMesh.vertices[2].x - bodyMesh.vertices[0].x);
|
||||
|
||||
var meshSet = MeshPool.GetMeshSetForWidth(scale * width);
|
||||
scaledBodyMesh = meshSet.MeshAt(facing);
|
||||
}
|
||||
else
|
||||
scaledBodyMesh = bodyMesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
scaledBodyMesh = bodyMesh;
|
||||
}
|
||||
|
||||
|
||||
Quaternion quaternion = Quaternion.AngleAxis(drawRotation, Vector3.up);
|
||||
|
||||
Quaternion quaternion = Quaternion.AngleAxis(angle + rotation, Vector3.up);
|
||||
Vector3 vector = rootLoc;
|
||||
|
||||
if (this.pawn.ageTracker.CurLifeStage.bodyDrawOffset != null)
|
||||
{
|
||||
vector += this.pawn.ageTracker.CurLifeStage.bodyDrawOffset.Value;
|
||||
drawPosition += this.pawn.ageTracker.CurLifeStage.bodyDrawOffset.Value;
|
||||
}
|
||||
|
||||
Rot4 targetRot = facing;
|
||||
|
@ -636,31 +803,31 @@ namespace SizedApparel
|
|||
|
||||
if (targetRot == Rot4.South)
|
||||
{
|
||||
var loc = OffsetFromUVOffset(positionOffsetSouth, bodyMesh);
|
||||
vector.x += loc.x;
|
||||
vector.z += loc.y;
|
||||
vector.y += depthOffsetSouth;
|
||||
var loc = OffsetFromUVOffset(positionOffsetSouth, scaledBodyMesh);
|
||||
drawPosition.x += loc.x;
|
||||
drawPosition.z += loc.y;
|
||||
drawPosition.y += depthOffsetSouth;
|
||||
}
|
||||
else if(targetRot == Rot4.North)
|
||||
{
|
||||
var loc = OffsetFromUVOffset(positionOffsetNorth, bodyMesh);
|
||||
vector.x += loc.x;
|
||||
vector.z += loc.y;
|
||||
vector.y += depthOffsetNorth;
|
||||
var loc = OffsetFromUVOffset(positionOffsetNorth, scaledBodyMesh);
|
||||
drawPosition.x += loc.x;
|
||||
drawPosition.z += loc.y;
|
||||
drawPosition.y += depthOffsetNorth;
|
||||
}
|
||||
else if (targetRot == Rot4.East)
|
||||
{
|
||||
var loc = OffsetFromUVOffset(positionOffsetEast, bodyMesh);
|
||||
vector.x += loc.x;
|
||||
vector.z += loc.y;
|
||||
vector.y += depthOffsetEast;
|
||||
var loc = OffsetFromUVOffset(positionOffsetEast, scaledBodyMesh);
|
||||
drawPosition.x += loc.x;
|
||||
drawPosition.z += loc.y;
|
||||
drawPosition.y += depthOffsetEast;
|
||||
}
|
||||
else if (targetRot == Rot4.West)
|
||||
{
|
||||
var loc = OffsetFromUVOffset(positionOffsetWest, bodyMesh);
|
||||
vector.x += loc.x;
|
||||
vector.z += loc.y;
|
||||
vector.y += depthOffsetWest;
|
||||
var loc = OffsetFromUVOffset(positionOffsetWest, scaledBodyMesh);
|
||||
drawPosition.x += loc.x;
|
||||
drawPosition.z += loc.y;
|
||||
drawPosition.y += depthOffsetWest;
|
||||
}
|
||||
|
||||
|
||||
|
@ -694,13 +861,13 @@ namespace SizedApparel
|
|||
{
|
||||
graphic = graphic.GetColoredVersion(ShaderDatabase.Cutout, drawColor1, drawColor2); // ShaderDatabase.Cutout
|
||||
mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(targetRot) : (Material)overrideMatMethod.Invoke(pawnRenderer, new object[] { graphic.MatAt(facing), pawn, flags.FlagSet(PawnRenderFlags.Portrait) });
|
||||
GenDraw.DrawMeshNowOrLater(bodyMesh, vector, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow)); // draw for writeZ data to solve shadow issue
|
||||
GenDraw.DrawMeshNowOrLater(scaledBodyMesh, drawPosition, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow)); // draw for writeZ data to solve shadow issue
|
||||
}
|
||||
|
||||
graphic = graphic.GetColoredVersion(shader, drawColor1, drawColor2);
|
||||
vector.y += 0.00001f;
|
||||
drawPosition.y += 0.00001f;
|
||||
mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(targetRot) : (Material)overrideMatMethod.Invoke(pawnRenderer, new object[] { graphic.MatAt(facing), pawn, flags.FlagSet(PawnRenderFlags.Portrait) });
|
||||
GenDraw.DrawMeshNowOrLater(bodyMesh, vector, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow));
|
||||
GenDraw.DrawMeshNowOrLater(scaledBodyMesh, drawPosition, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow));
|
||||
|
||||
|
||||
}
|
||||
|
@ -710,23 +877,24 @@ namespace SizedApparel
|
|||
//TODO: Torso Pose?
|
||||
|
||||
|
||||
public class SizedApparelBodyDef : Def
|
||||
public class BodyDef : Def
|
||||
{
|
||||
//public List<SizedApparelBodyPartDef> BodyParts;
|
||||
|
||||
|
||||
//defName = raceName ?? could it work?
|
||||
|
||||
public List<BodyPart> bodyParts;
|
||||
public List<BodyWithBodyType> bodies = new List<BodyWithBodyType>();
|
||||
|
||||
/*
|
||||
public List<BodyTypeAndOffset> penisOffset;
|
||||
public List<BodyTypeAndOffset> vaginaOffset; //TODO
|
||||
public List<BodyTypeAndOffset> udderOffset; //TODO
|
||||
public List<BodyTypeAndOffset> bellyOffset; //TODO
|
||||
public List<BodyTypeAndOffset> breastsOffset; //TODO
|
||||
public List<BodyTypeAndOffset> anusOffset; //TODO
|
||||
*/
|
||||
|
||||
//public List<BodyTypeAndOffset> penisOffset;
|
||||
//public List<BodyTypeAndOffset> vaginaOffset;
|
||||
//public List<BodyTypeAndOffset> pubicHairOffset;
|
||||
//public List<BodyTypeAndOffset> udderOffset;
|
||||
//public List<BodyTypeAndOffset> bellyOffset;
|
||||
//public List<BodyTypeAndOffset> breastsOffset;
|
||||
//public List<BodyTypeAndOffset> anusOffset;
|
||||
|
||||
}
|
||||
|
||||
public class SizedApparelBody
|
||||
|
@ -740,4 +908,10 @@ namespace SizedApparel
|
|||
}
|
||||
}
|
||||
|
||||
public class SizedApparelBodyPartOfssetDef : Def
|
||||
{
|
||||
//defName IsRaceName
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
163
source/SizedApparel/SizedApparelBodyPartDef.cs
Normal file
163
source/SizedApparel/SizedApparelBodyPartDef.cs
Normal file
|
@ -0,0 +1,163 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using Verse;
|
||||
|
||||
namespace SizedApparel
|
||||
{
|
||||
|
||||
//This Class is Use for Def BodyParts' Custom Pivot, or Some Special Common Vector Points Per Serverity.
|
||||
//Not Consider Acture Graphic Textures.
|
||||
public class SkeletonDef : Def
|
||||
{
|
||||
//defName = Pawn's race name (such as "Human")
|
||||
//public List<BodyPartGraphicBone> graphicBones = new List<BodyPartGraphicBone>();
|
||||
|
||||
//Do Not Directly Use it
|
||||
public List<Skeleton> skeletons = new List<Skeleton>();
|
||||
|
||||
|
||||
public Skeleton CreateSkeleton(string bodyType)
|
||||
{
|
||||
for(int i = 0; i< skeletons.Count; i++)
|
||||
{
|
||||
if(skeletons[i].bodyType == bodyType)
|
||||
{
|
||||
return new Skeleton(skeletons[i]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class Skeleton
|
||||
{
|
||||
public string bodyType = null; // can be null for animal or etc
|
||||
public List<Bone> Bones;
|
||||
|
||||
//only runtime. Do not Set in Def
|
||||
public Rot4 BodyFacing; // for flip east-west bones
|
||||
public Rot4 HeadFacing; //TODO
|
||||
|
||||
public Skeleton()
|
||||
{
|
||||
|
||||
}
|
||||
public Skeleton(Skeleton skeletonToCopy)
|
||||
{
|
||||
this.Bones = new List<Bone>();
|
||||
|
||||
|
||||
foreach (var s in skeletonToCopy.Bones)
|
||||
{
|
||||
this.Bones.Add(new Bone(s, this));
|
||||
}
|
||||
|
||||
}
|
||||
public Bone FindBone(string boneName)
|
||||
{
|
||||
foreach (var b in this.Bones)
|
||||
{
|
||||
if (b.name == boneName)
|
||||
return b;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//for deafault bone support?
|
||||
public class BodyPartBoneDef : Def
|
||||
{
|
||||
//DefName is Bone Name To Use.
|
||||
public Vector3 customPivot = new Vector3(0.5f, 0, 0.5f);
|
||||
public Vector3 Position = new Vector3(0.5f, 0, 0.5f); // Local Position(UV) from Body
|
||||
public float Length = 1;
|
||||
public float Rotation = 0;
|
||||
public float Scale = 1f; // Default Render Scale.
|
||||
}
|
||||
|
||||
//Body Parts Graphic can be attached to bone position and rotation
|
||||
public class Bone
|
||||
{
|
||||
|
||||
public string name = null;
|
||||
public Skeleton parentSkeleton = null;
|
||||
//public string parentBoneName = null; // ToDo
|
||||
public bool isHeadBone = false; // TODO
|
||||
public BoneTransform south;
|
||||
public BoneTransform north;
|
||||
public BoneTransform east;
|
||||
public BoneTransform west; // can be null. then use east
|
||||
//hiding Graphic parameter will be in that bodygraphic class
|
||||
|
||||
public Bone()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Bone(Bone boneToCopy, Skeleton parent)
|
||||
{
|
||||
this.name = boneToCopy.name;
|
||||
this.parentSkeleton = parent;
|
||||
this.isHeadBone = boneToCopy.isHeadBone;
|
||||
if(boneToCopy.south != null)
|
||||
this.south = new BoneTransform(boneToCopy.south);
|
||||
if (boneToCopy.north != null)
|
||||
this.north = new BoneTransform(boneToCopy.north);
|
||||
if (boneToCopy.east != null)
|
||||
this.east = new BoneTransform(boneToCopy.east);
|
||||
if (boneToCopy.west != null)
|
||||
this.west = new BoneTransform(boneToCopy.west); // null for use east
|
||||
|
||||
}
|
||||
|
||||
public void SetAngle(float angle)
|
||||
{
|
||||
if(south != null)
|
||||
south.angleOffset = angle;
|
||||
if (north != null)
|
||||
north.angleOffset = angle;
|
||||
if (east != null)
|
||||
east.angleOffset = angle;
|
||||
if (west != null)
|
||||
west.angleOffset = angle;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class BoneTransform
|
||||
{
|
||||
//public Vector3 customPivot = new Vector3(0.5f, 0, 0.5f); // used to calculation rotation. the rotating center will be customPivot.
|
||||
//Custom Pivot Doesn't affect to Draw Position on zero Rotated.
|
||||
public Vector3 InitialPosition = Vector3.zero; // Local Position(UV) from Body
|
||||
public float InitialLength = 1;
|
||||
public float InitialAngle = 0;
|
||||
public float InitialScale = 1f;
|
||||
public bool isHeadBone = false; // TODO
|
||||
|
||||
//public BodyPartGraphicBone parentBone; //TODO
|
||||
public Vector3 positionOffset = Vector3.zero;
|
||||
public float lengthOffset = 0;
|
||||
public float angleOffset = 0;
|
||||
public float scaleOffset = 0;
|
||||
|
||||
public BoneTransform() { }
|
||||
|
||||
public BoneTransform(BoneTransform boneToCopy)
|
||||
{
|
||||
|
||||
//this.parentBoneName = boneToCopy.parentBoneName;
|
||||
//this.customPivot = boneToCopy.customPivot;
|
||||
this.InitialPosition = boneToCopy.InitialPosition;
|
||||
this.InitialLength = boneToCopy.InitialLength;
|
||||
this.InitialAngle = boneToCopy.InitialAngle;
|
||||
this.InitialScale = boneToCopy.InitialScale;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -14,10 +14,13 @@ namespace SizedApparel
|
|||
[HarmonyPatch(typeof(PawnGraphicSet), "CalculateHairMats")]
|
||||
public static class CalculateHairMatsPatch
|
||||
{
|
||||
public static void Postfix()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class PubicHairDef : StyleItemDef
|
||||
public class PubicHairDef : StyleItemDef
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace SizedApparel
|
|||
{
|
||||
public string raceName = null;
|
||||
public bool overrideDef = false;
|
||||
public bool asHumanlike = true;
|
||||
public bool asHuman = true;
|
||||
public float drawMinAge = -1; //pawn's Biological age. -1 to ignore.
|
||||
|
||||
public AlienRaceSetting(string raceName)
|
||||
|
@ -32,7 +32,7 @@ namespace SizedApparel
|
|||
{
|
||||
Scribe_Values.Look(ref raceName, "raceName", null);
|
||||
Scribe_Values.Look(ref overrideDef, "overrideDef", false);
|
||||
Scribe_Values.Look(ref asHumanlike, "asHumanlike", true);
|
||||
Scribe_Values.Look(ref asHuman, "asHuman", true);
|
||||
Scribe_Values.Look(ref drawMinAge, "drawMinAge", -1);
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ namespace SizedApparel
|
|||
|
||||
public class SizedApparelSettings : ModSettings
|
||||
{
|
||||
|
||||
public static bool Debug = false;
|
||||
public static bool DetailLog = false;
|
||||
public static bool autoClearCacheOnWriteSetting = true;
|
||||
|
@ -65,9 +66,9 @@ namespace SizedApparel
|
|||
|
||||
//Apply Target Pawn Category
|
||||
public static bool ApplyHumanlikes = true; //Always true.
|
||||
public static bool ApplyAnimals = false;
|
||||
public static bool ApplyAnimals = true;
|
||||
public static bool ApplyAnimalsPlayerFactionOnly = true; //TODO
|
||||
public static bool ApplyMechanoid = false;
|
||||
public static bool ApplyMechanoid = true;
|
||||
|
||||
public static bool ApplyApparelPatchForMale = false; //only ApparelServerityWork.
|
||||
|
||||
|
@ -90,6 +91,7 @@ namespace SizedApparel
|
|||
public static bool drawAnus = true;
|
||||
public static bool drawBelly = false;//TODO
|
||||
public static bool drawUdder = false;//TODO
|
||||
public static bool drawPubicHair = true;
|
||||
public static bool hideBallOfFuta = false;
|
||||
public static bool hidePenisOfMale = false;
|
||||
public static bool matchBreastToSupportedApparelSize = true;//for avoiding breasts cliping
|
||||
|
@ -192,9 +194,9 @@ namespace SizedApparel
|
|||
//Scribe_Values.Look(ref useBreastSizeCapForApparels, "useBreastSizeCapForApparels", true);
|
||||
|
||||
//Apply Categories.
|
||||
Scribe_Values.Look(ref ApplyAnimals, "ApplyAnimals", false);
|
||||
Scribe_Values.Look(ref ApplyAnimals, "ApplyAnimals", true);
|
||||
Scribe_Values.Look(ref ApplyHumanlikes, "ApplyHumanlikes", true);
|
||||
Scribe_Values.Look(ref ApplyMechanoid, "ApplyMechanoid", false);
|
||||
Scribe_Values.Look(ref ApplyMechanoid, "ApplyMechanoid", true);
|
||||
|
||||
Scribe_Values.Look(ref AnimationPatch, "AnimationPatch", true);
|
||||
|
||||
|
@ -245,6 +247,7 @@ namespace SizedApparel
|
|||
Scribe_Values.Look(ref drawAnus, "drawAnus", true);
|
||||
Scribe_Values.Look(ref drawUdder, "drawUdder", true);
|
||||
Scribe_Values.Look(ref drawBelly, "drawBelly", true);
|
||||
Scribe_Values.Look(ref drawPubicHair, "drawPubicHair", true);
|
||||
|
||||
|
||||
//force to draw all size type
|
||||
|
@ -269,7 +272,7 @@ namespace SizedApparel
|
|||
//Scribe_Values.Look(ref alienRacesAllowHumanlikTextures, "alienRacesAllowHumanlikTextures");
|
||||
|
||||
//BreastsPhysics
|
||||
//Scribe_Values.Look(ref breastsPhysics, "breastsPhysics", false);
|
||||
Scribe_Values.Look(ref breastsPhysics, "breastsPhysics", false);
|
||||
|
||||
|
||||
base.ExposeData();
|
||||
|
@ -311,6 +314,7 @@ namespace SizedApparel
|
|||
public static void ClearCache(bool clearPawnGraphicSet = true)
|
||||
{
|
||||
SizedApparelsDatabase.ClearAll();
|
||||
|
||||
if (Find.CurrentMap != null)
|
||||
{
|
||||
foreach (Pawn pawn in Find.CurrentMap.mapPawns.AllPawns)
|
||||
|
@ -319,11 +323,18 @@ namespace SizedApparel
|
|||
continue;
|
||||
var comp = pawn.GetComp<ApparelRecorderComp>();
|
||||
if (comp != null)
|
||||
comp.SetDirty(clearPawnGraphicSet);
|
||||
{
|
||||
comp.UpdateRaceSettingData();
|
||||
comp.SetDirty(clearPawnGraphicSet,true,true,true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public SizedApparelMod(ModContentPack content) : base(content)
|
||||
{
|
||||
this.settings = GetSettings<SizedApparelSettings>();
|
||||
|
@ -506,7 +517,7 @@ namespace SizedApparel
|
|||
|
||||
SizedApparelSettings.alienRaceSettings.Add(raceSetting);
|
||||
}
|
||||
Race_ListingStandard.CheckboxLabeled("If Unsupported, Use Humanlike", ref raceSetting.asHumanlike, "This Race will use Humanlike if it doesn't have own textures. useful for race that Unsupported but simillar to human");
|
||||
Race_ListingStandard.CheckboxLabeled("If Unsupported, As Human race", ref raceSetting.asHuman, "This Race will use Human race if it doesn't have own textures. useful for race that Unsupported but simillar to human");
|
||||
Race_ListingStandard.Label((raceSetting.drawMinAge <= 100 ? "" : "[overdrive]") + "SA BodyPart Draw Min Age: " + raceSetting.drawMinAge.ToString(), -1, "Lower than this age will not use Sized Apparel. Useful for BnC. -1 for disable");
|
||||
raceSetting.drawMinAge = Mathf.Round(Race_ListingStandard.Slider(raceSetting.drawMinAge, raceSetting.drawMinAge <= 100 ? -1: 100, raceSetting.drawMinAge >= 100 ? 1000 : 100));
|
||||
Race_ListingStandard.Gap();
|
||||
|
@ -537,6 +548,7 @@ namespace SizedApparel
|
|||
SizedApparelSettings.drawVagina = false;
|
||||
SizedApparelSettings.drawAnus = false;
|
||||
SizedApparelSettings.drawBelly = false;
|
||||
SizedApparelSettings.drawPubicHair = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -565,6 +577,7 @@ namespace SizedApparel
|
|||
SizedApparelSettings.drawVagina = true;
|
||||
SizedApparelSettings.drawAnus = true;
|
||||
SizedApparelSettings.drawBelly = true;
|
||||
SizedApparelSettings.drawPubicHair = true;
|
||||
}
|
||||
}
|
||||
listingStandard.Gap(8);
|
||||
|
@ -604,30 +617,30 @@ namespace SizedApparel
|
|||
listingStandard.Label("Body Part Render Option (wip)",-1,"standalone BodyPart Render System from this mod. It's for user who don't use RimNudeWorld\nIf you use RimNudeWorld, you should turn off this.");
|
||||
|
||||
listingStandard.CheckboxLabeled("Use Gender Specific Textures.", ref SizedApparelSettings.useGenderSpecificTexture,"Use Gender Specific texture for body and apparel if it's valid. \nDefault: true");
|
||||
listingStandard.GapLine(1);
|
||||
listingStandard.GapLine(5);
|
||||
listingStandard.CheckboxLabeled("Draw Body Parts", ref SizedApparelSettings.drawBodyParts, "Draw Breasts..etc. when the pawn is wearing supported apparels. \nDefault: true");
|
||||
if (SizedApparelSettings.drawBodyParts)
|
||||
{
|
||||
listingStandard.CheckboxLabeled(" Use (Sized Apparel) Body Texture", ref SizedApparelSettings.useBodyTexture, "change pawn's body texture when the pawn is wearing supported apparels. Recommanded\nDefault: true");
|
||||
listingStandard.CheckboxLabeled(" Use (Sized Apparel) Base Body Texture", ref SizedApparelSettings.useBodyTexture, "change pawn's body texture when the pawn is wearing supported apparels. Recommanded\nDefault: true");
|
||||
|
||||
//listingStandard.CheckboxLabeled(" Draw Muscle Overlay (wip)", ref SizedApparelSettings.drawMuscleOverlay, "\nDisable this option when you use RimNudeWorld");
|
||||
|
||||
|
||||
listingStandard.CheckboxLabeled(" Draw Muscle Overlay (wip)", ref SizedApparelSettings.drawMuscleOverlay, "\nDisable this option when you use RimNudeWorld");
|
||||
|
||||
listingStandard.CheckboxLabeled(" Draw Breasts", ref SizedApparelSettings.drawBreasts, "this option is why this mod exist.\nDefault: true");
|
||||
listingStandard.CheckboxLabeled(" Draw Breasts", ref SizedApparelSettings.drawBreasts, "this option is why this mod exist.\nDefault: true");
|
||||
if (SizedApparelSettings.drawBreasts)
|
||||
{
|
||||
listingStandard.CheckboxLabeled(" Match Breasts size to supported apparels",ref SizedApparelSettings.matchBreastToSupportedApparelSize, "to avoid breasts clipping(when breasts are bigger), you need this option.\nDefault: true");
|
||||
listingStandard.CheckboxLabeled(" draw Breasts on worn pawn only (RimNudeWorld)", ref SizedApparelSettings.drawSizedApparelBreastsOnlyWorn, "when the pawn is nude, the breasts graphic for sized apparel will be hidden. \nDefault: false" );
|
||||
//listingStandard.CheckboxLabeled(" (Wip) Breasts Physics", ref SizedApparelSettings.breastsPhysics, "Breasts can be jiggled from animations. It may be heavy for performance. \ndefault = false");
|
||||
listingStandard.CheckboxLabeled(" Match Breasts size to supported apparels",ref SizedApparelSettings.matchBreastToSupportedApparelSize, "to avoid breasts clipping(when breasts are bigger), you need this option.\nDefault: true");
|
||||
listingStandard.CheckboxLabeled(" draw Breasts on worn pawn only (RimNudeWorld)", ref SizedApparelSettings.drawSizedApparelBreastsOnlyWorn, "when the pawn is nude, the breasts graphic for sized apparel will be hidden. \nDefault: false" );
|
||||
listingStandard.CheckboxLabeled(" (Wip) Breasts Physics", ref SizedApparelSettings.breastsPhysics, "Breasts can be jiggled (for now. it works when nude only). It may be heavy for performance. \n Won't work with RimNudeWorld Breasts Rendering. \ndefault = false");
|
||||
}
|
||||
listingStandard.CheckboxLabeled(" Draw Penis", ref SizedApparelSettings.drawPenis,"Disable this option when you use RimNudeWorld");
|
||||
listingStandard.CheckboxLabeled(" Draw Vagina", ref SizedApparelSettings.drawVagina, "Disable this option when you use RimNudeWorld");
|
||||
listingStandard.CheckboxLabeled(" Draw Anus", ref SizedApparelSettings.drawAnus, "Disable this option when you use RimNudeWorld");
|
||||
listingStandard.CheckboxLabeled(" Draw Belly Buldge", ref SizedApparelSettings.drawBelly, "Disable this option when you use RimNudeWorld");
|
||||
listingStandard.CheckboxLabeled(" Draw Penis", ref SizedApparelSettings.drawPenis,"Disable this option when you use RimNudeWorld");
|
||||
listingStandard.CheckboxLabeled(" Draw Vagina", ref SizedApparelSettings.drawVagina, "Disable this option when you use RimNudeWorld");
|
||||
listingStandard.CheckboxLabeled(" Draw Anus", ref SizedApparelSettings.drawAnus, "Disable this option when you use RimNudeWorld");
|
||||
listingStandard.CheckboxLabeled(" Draw Belly Buldge", ref SizedApparelSettings.drawBelly, "Disable this option when you use RimNudeWorld");
|
||||
|
||||
listingStandard.CheckboxLabeled(" Hide Balls of Futa", ref SizedApparelSettings.hideBallOfFuta, "Hide Balls from penis of Futa.\nDefault: false");
|
||||
listingStandard.CheckboxLabeled(" Hide Penis of Man(Not Work yet)", ref SizedApparelSettings.hidePenisOfMale, "this option is for someone who really hate to see male's dick around.\nDefault: false");
|
||||
listingStandard.CheckboxLabeled(" Draw Pubic Hair", ref SizedApparelSettings.drawPubicHair, "Disable this option when you use RimNudeWorld");
|
||||
|
||||
listingStandard.CheckboxLabeled(" Hide Balls of Futa", ref SizedApparelSettings.hideBallOfFuta, "Hide Balls from penis of Futa.\nDefault: false");
|
||||
listingStandard.CheckboxLabeled(" Hide Penis of Man(Not Work yet)", ref SizedApparelSettings.hidePenisOfMale, "this option is for someone who really hate to see male's dick around.\nDefault: false");
|
||||
|
||||
//listingStandard.Gap();
|
||||
//listingStandard.CheckboxLabeled(" Use Body Part Variation", ref SizedApparelSettings.useBodyPartsVariation, "Use graphic variation such as inverted nipple.\nDefault: true");
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using RimWorld;
|
||||
using Verse;
|
||||
using Verse.Sound;
|
||||
using HarmonyLib;
|
||||
using UnityEngine;
|
||||
using rjw;
|
||||
|
@ -13,18 +14,37 @@ using System.Reflection.Emit;
|
|||
|
||||
namespace SizedApparel
|
||||
{
|
||||
//TODO...?
|
||||
//[HarmonyPatch(typeof(Dialog_StylingStation), "DrawTabs")]
|
||||
|
||||
[HarmonyPatch(typeof(Dialog_StylingStation), "DrawTabs")]
|
||||
public class SizedApparelStyleStationDrawTabsPatch
|
||||
{
|
||||
public static void Postfix(Rect rect, ref Vector2 ___hairScrollPosition, Dialog_StylingStation __instance, List<TabRecord> ___tabs, Dialog_StylingStation.StylingTab ___curTab, float ___viewRectHeight, List<StyleItemDef> ___tmpStyleItems, bool ___devEditMode, Pawn ___pawn)
|
||||
public static void Postfix(Rect rect, ref Vector2 ___hairScrollPosition, Dialog_StylingStation __instance, List<TabRecord> ___tabs, Dialog_StylingStation.StylingTab ___curTab, float ___viewRectHeight, ref List<StyleItemDef> ___tmpStyleItems, bool ___devEditMode, Pawn ___pawn, float ___colorsHeight, Color ___desiredHairColor)
|
||||
{
|
||||
|
||||
if (!SizedApparelSettings.drawPubicHair)
|
||||
return;
|
||||
|
||||
|
||||
//Widgets.DrawMenuSection(rect);
|
||||
//TabDrawer.DrawTabs<TabRecord>(rect, ___tabs, 200f);
|
||||
//rect = rect.ContractedBy(18f);
|
||||
switch (___curTab)
|
||||
{
|
||||
case (Dialog_StylingStation.StylingTab)24:
|
||||
|
||||
//Draw PubicHair Tab Code here!
|
||||
//rect.yMax -= ___colorsHeight;
|
||||
DrawStylingTypePubicHair(ref __instance, ref ___viewRectHeight, ref ___tmpStyleItems, ___devEditMode, ___pawn, ___colorsHeight, ___desiredHairColor, rect, ref ___hairScrollPosition, delegate (Rect r, PubicHairDef h)
|
||||
{
|
||||
GUI.color = ___desiredHairColor;
|
||||
Widgets.DefIcon(r, h, null, 1.25f, null, false, null, null, null);
|
||||
//Widgets.DrawTextureFitted(r, h.Icon, 1.25f, null);
|
||||
GUI.color = Color.white;
|
||||
}, delegate (PubicHairDef h)
|
||||
{
|
||||
___pawn.GetComp<ApparelRecorderComp>().pubicHairDef = h;
|
||||
//___pawn.story.hairDef = h;
|
||||
}, (StyleItemDef h) => ___pawn.GetComp<ApparelRecorderComp>().pubicHairDef == h, (StyleItemDef h) => ___pawn.GetComp<ApparelRecorderComp>().initialPubicHairDef == h, null, false);
|
||||
|
||||
return;
|
||||
default:
|
||||
|
@ -32,13 +52,159 @@ namespace SizedApparel
|
|||
}
|
||||
}
|
||||
|
||||
static void DrawStylingTypePubicHair(Dialog_StylingStation dialog_StylingStation, Rect rect)
|
||||
//Some Copy Code from Rimnudeworld
|
||||
//maybe Some Var has to be ref
|
||||
static void DrawStylingTypePubicHair(ref Dialog_StylingStation dialog_StylingStation, ref float viewRectHeight, ref List<StyleItemDef> tmpStyleItems, bool devEditMode, Pawn pawn, float colorsHeight, Color desiredHairColor, Rect rect, ref Vector2 scrollPosition, Action<Rect, PubicHairDef> drawAction, Action<PubicHairDef> selectAction, Func<StyleItemDef, bool> hasStyleItem, Func<StyleItemDef, bool> hadStyleItem, Func<StyleItemDef, bool> extraValidator = null, bool doColors = false)
|
||||
{
|
||||
|
||||
//Color desiredHairColor = AccessTools.FieldRefAccess<Dialog_StylingStation, Color>(dialog_StylingStation, "desiredHairColor");
|
||||
|
||||
int total_pubes_count = 0;
|
||||
total_pubes_count = DefDatabase<PubicHairDef>.AllDefs.Count();
|
||||
|
||||
//need child patch?
|
||||
if (total_pubes_count <= 0)
|
||||
{
|
||||
Widgets.NoneLabelCenteredVertically(rect, "(" + "NoneUsableForPawn".Translate(pawn.Named("PAWN")) + ")");
|
||||
return;
|
||||
}
|
||||
|
||||
ApparelRecorderComp comp = pawn.GetComp<ApparelRecorderComp>();
|
||||
|
||||
|
||||
|
||||
Rect viewRect = new Rect(rect.x, rect.y, rect.width - 16f, viewRectHeight);
|
||||
int num = Mathf.FloorToInt(viewRect.width / 60f) - 1;
|
||||
float num2 = (viewRect.width - (float)num * 60f - (float)(num - 1) * 10f) / 2f;
|
||||
int num3 = 0;
|
||||
int num4 = 0;
|
||||
int num5 = 0;
|
||||
tmpStyleItems.Clear();
|
||||
/*
|
||||
tmpStyleItems.AddRange(from x in DefDatabase<PubicHairDef>.AllDefs
|
||||
where (devEditMode || PawnStyleItemChooser.WantsToUseStyle(pawn, x, null) || hadStyleItem(x)) && (extraValidator == null || extraValidator(x))
|
||||
select x);*/
|
||||
tmpStyleItems.AddRange(DefDatabase<PubicHairDef>.AllDefs);// just add All Pubic Hair def.
|
||||
|
||||
tmpStyleItems.SortBy((StyleItemDef x) => -PawnStyleItemChooser.StyleItemChoiceLikelihoodFor(x, pawn));
|
||||
if (tmpStyleItems.NullOrEmpty<StyleItemDef>())
|
||||
{
|
||||
Widgets.NoneLabelCenteredVertically(rect, "(" + "NoneUsableForPawn".Translate(pawn.Named("PAWN")) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
Widgets.BeginScrollView(rect, ref scrollPosition, viewRect, true);
|
||||
foreach (StyleItemDef styleItemDef in tmpStyleItems)
|
||||
{
|
||||
if (num5 >= num - 1)
|
||||
{
|
||||
num5 = 0;
|
||||
num4++;
|
||||
}
|
||||
else if (num3 > 0)
|
||||
{
|
||||
num5++;
|
||||
}
|
||||
Rect rect2 = new Rect(rect.x + num2 + (float)num5 * 60f + (float)num5 * 10f, rect.y + (float)num4 * 60f + (float)num4 * 10f, 60f, 60f);
|
||||
Widgets.DrawHighlight(rect2);
|
||||
if (Mouse.IsOver(rect2))
|
||||
{
|
||||
Widgets.DrawHighlight(rect2);
|
||||
TooltipHandler.TipRegion(rect2, styleItemDef.LabelCap);
|
||||
}
|
||||
if (drawAction != null)
|
||||
{
|
||||
drawAction(rect2, styleItemDef as PubicHairDef);
|
||||
}
|
||||
if (hasStyleItem(styleItemDef))
|
||||
{
|
||||
Widgets.DrawBox(rect2, 2, null);
|
||||
}
|
||||
if (Widgets.ButtonInvisible(rect2, true))
|
||||
{
|
||||
if (selectAction != null)
|
||||
{
|
||||
selectAction(styleItemDef as PubicHairDef);
|
||||
}
|
||||
SoundDefOf.Tick_High.PlayOneShotOnCamera(null);
|
||||
pawn.Drawer.renderer.graphics.SetAllGraphicsDirty();
|
||||
PortraitsCache.SetDirty(pawn);
|
||||
}
|
||||
num3++;
|
||||
}
|
||||
if (Event.current.type == EventType.Layout)
|
||||
{
|
||||
viewRectHeight = (float)(num4 + 1) * 60f + (float)num4 * 10f + 10f;
|
||||
}
|
||||
Widgets.EndScrollView();
|
||||
}
|
||||
if (doColors)
|
||||
{
|
||||
//dialog_StylingStation.DrawHairColors(new Rect(rect.x, rect.yMax + 10f, rect.width, dialog_StylingStation.colorsHeight));
|
||||
|
||||
//Copy From RimnudeWorld
|
||||
Rect newrect = new Rect(rect.x, rect.yMax - 10f, rect.width, colorsHeight);
|
||||
|
||||
Color _desiredHairColor = desiredHairColor;
|
||||
|
||||
float numC = newrect.y;
|
||||
float height;
|
||||
Widgets.ColorSelector(new Rect(newrect.x, numC, newrect.width, 92f), ref _desiredHairColor, AllHairColors, out height, null, 22, 2);
|
||||
if (_desiredHairColor != desiredHairColor)
|
||||
{
|
||||
var desiredHairColor_ = dialog_StylingStation.GetType().GetField("desiredHairColor", System.Reflection.BindingFlags.NonPublic
|
||||
| System.Reflection.BindingFlags.Instance);
|
||||
desiredHairColor_.SetValue(dialog_StylingStation, _desiredHairColor);
|
||||
}
|
||||
numC += 60f;
|
||||
if (desiredHairColor != pawn.story.HairColor && desiredHairColor != pawn.style.nextHairColor)
|
||||
{
|
||||
Widgets.ThingIcon(new Rect(newrect.x, numC, Text.LineHeight, Text.LineHeight), ThingDefOf.Dye, null, null, 1.1f, null);
|
||||
string text = "Required".Translate() + ": 1 " + ThingDefOf.Dye.label;
|
||||
float x = Text.CalcSize(text).x;
|
||||
Widgets.Label(new Rect(newrect.x + Text.LineHeight + 4f, numC, x, Text.LineHeight), text);
|
||||
Rect rect2 = new Rect(newrect.x, numC, x + Text.LineHeight + 8f, Text.LineHeight);
|
||||
if (Mouse.IsOver(rect2))
|
||||
{
|
||||
Widgets.DrawHighlight(rect2);
|
||||
TooltipHandler.TipRegionByKey(rect2, "TooltipDyeExplanation");
|
||||
}
|
||||
numC += Text.LineHeight;
|
||||
|
||||
if (pawn.Map.resourceCounter.GetCount(ThingDefOf.Dye) < 1)
|
||||
{
|
||||
rect2 = new Rect(newrect.x, numC, newrect.width, Text.LineHeight);
|
||||
Color color = GUI.color;
|
||||
GUI.color = ColorLibrary.RedReadable;
|
||||
Widgets.Label(rect2, "NotEnoughDye".Translate() + " " + "NotEnoughDyeWillRecolorHair".Translate());
|
||||
GUI.color = color;
|
||||
numC += rect2.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private static List<Color> allHairColors;
|
||||
private static List<Color> AllHairColors
|
||||
{
|
||||
get
|
||||
{
|
||||
if (allHairColors == null)
|
||||
{
|
||||
allHairColors = (from ic in DefDatabase<ColorDef>.AllDefsListForReading
|
||||
select ic.color).ToList<Color>();
|
||||
allHairColors.SortByColor((Color x) => x);
|
||||
}
|
||||
return allHairColors;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void AddPubicHairTab(Dialog_StylingStation stylingStation, List<TabRecord> tabs)
|
||||
{
|
||||
if (!SizedApparelSettings.drawPubicHair)
|
||||
return;
|
||||
|
||||
var curTabField = AccessTools.Field(typeof(Dialog_StylingStation), "curTab");
|
||||
tabs.Add(new TabRecord("PubicHair".Translate().CapitalizeFirst(), delegate ()
|
||||
{
|
||||
|
@ -98,5 +264,30 @@ namespace SizedApparel
|
|||
yield break;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Dialog_StylingStation), "Reset")]
|
||||
public class SizedApparelStyleStationResetPatch
|
||||
{
|
||||
public static void Prefix(Pawn ___pawn)
|
||||
{
|
||||
ApparelRecorderComp comp = ___pawn.GetComp<ApparelRecorderComp>();
|
||||
|
||||
//this.pawn.story.hairDef = this.initialHairDef;
|
||||
comp.pubicHairDef = comp.initialPubicHairDef;
|
||||
comp.initialPubicHairDef = null;
|
||||
}
|
||||
}
|
||||
|
||||
//Patching Constructors
|
||||
[HarmonyPatch(typeof(Dialog_StylingStation), MethodType.Constructor, new Type[] { typeof(Pawn), typeof(Thing) })]
|
||||
public class SizedApparelDialogStylingStationPatch
|
||||
{
|
||||
public static void Postfix(Pawn pawn)
|
||||
{
|
||||
var comp = pawn.GetComp<ApparelRecorderComp>();
|
||||
comp.initialPubicHairDef = comp.pubicHairDef;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
30
source/SizedApparel/SizedApparelTexturePointDef.cs
Normal file
30
source/SizedApparel/SizedApparelTexturePointDef.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Verse;
|
||||
|
||||
namespace SizedApparel
|
||||
{
|
||||
//Consider Graphic and Graphic_Multi(Graphic with Facing such as south)
|
||||
public class SizedApparelTexturePointDef : Def
|
||||
{
|
||||
//Path must be texture file name with path
|
||||
//Path example: "Things/Pawn/Humanlike/Bodies/Naked_Female_BaseBody"
|
||||
//Facing Text such as "_south" must not be included.
|
||||
//Use "/" instead of "\"
|
||||
|
||||
public string Path;
|
||||
|
||||
public List<BodyPartPoint> SouthBodyPartPoints = new List<BodyPartPoint>();
|
||||
public List<BodyPartPoint> NorthBodyPartPoints = new List<BodyPartPoint>();
|
||||
public List<BodyPartPoint> EastBodyPartPoints = new List<BodyPartPoint>();
|
||||
|
||||
//can be null. then use EastBodyPartPoints
|
||||
public List<BodyPartPoint> WestBodyPartPoints = new List<BodyPartPoint>();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -32,13 +32,15 @@ namespace SizedApparel
|
|||
static string Tiny = "_1";
|
||||
static string Nipples = "_0";
|
||||
//static String[] size = new string[10] { "_0", "_1", "_2", "_3", "_4", "_5" , "_6", "_7", "_8", "_9"};
|
||||
public static string[] size = new string[11] { Nipples, Tiny, Small, Average, Large, Huge, Enormous, Massive, Gargantuan, Colossal, Titanic };
|
||||
public static string[] breastsSizeStrings = new string[11] { Nipples, Tiny, Small, Average, Large, Huge, Enormous, Massive, Gargantuan, Colossal, Titanic };
|
||||
public static string[] commonSizeStrings = new string[6] { Nipples, Tiny, Small, Average, Large, Huge};
|
||||
|
||||
[Obsolete]
|
||||
public static int findAvailableSmallerSizeFromSetting(int current)
|
||||
{
|
||||
|
||||
int target = current;
|
||||
target = Math.Min(target, size.Length - 1);
|
||||
target = Math.Min(target, breastsSizeStrings.Length - 1);
|
||||
while (target > 0)
|
||||
{
|
||||
if (SizedApparelSettings.getUseSettingFromIndex(target) == false)
|
||||
|
@ -48,21 +50,23 @@ namespace SizedApparel
|
|||
}
|
||||
return target;
|
||||
}
|
||||
[Obsolete]
|
||||
public static int findAvailableBiggerSizeFromSetting(int current)
|
||||
{
|
||||
|
||||
int target = current;
|
||||
|
||||
while (target < size.Length)
|
||||
while (target < breastsSizeStrings.Length)
|
||||
{
|
||||
if (SizedApparelSettings.getUseSettingFromIndex(target) == false)
|
||||
target++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
target = Math.Min(target, size.Length - 1);
|
||||
target = Math.Min(target, breastsSizeStrings.Length - 1);
|
||||
return target;
|
||||
}
|
||||
[Obsolete]
|
||||
public static int findAvailableSizeFromSetting(int current, bool findBigger)
|
||||
{
|
||||
if (findBigger)
|
||||
|
@ -195,14 +199,14 @@ namespace SizedApparel
|
|||
|
||||
|
||||
int offset = 0;
|
||||
|
||||
//int offsetLimit = 10;
|
||||
|
||||
|
||||
bool validTexture = false;
|
||||
Graphic graphic = null;
|
||||
bool findBigger = true; // if false : search smaller first
|
||||
string pathString = "";
|
||||
while (offset < SizedApparelUtility.size.Length)
|
||||
while (offset < SizedApparelUtility.breastsSizeStrings.Length)
|
||||
{
|
||||
if (breastHediffName != null)
|
||||
{
|
||||
|
@ -281,7 +285,7 @@ namespace SizedApparel
|
|||
if (validTexture == false)
|
||||
{
|
||||
offset = 0;
|
||||
while (offset < SizedApparelUtility.size.Length)
|
||||
while (offset < SizedApparelUtility.breastsSizeStrings.Length)
|
||||
{
|
||||
if (breastHediffName != null)
|
||||
{
|
||||
|
@ -393,13 +397,6 @@ namespace SizedApparel
|
|||
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public static SizedApparelBodyPartDef TryGetSizedApparelBodyPart(string bodyPartName)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static bool isPragnencyHediff(Hediff h)
|
||||
{
|
||||
return h.def.defName.ToLower().Contains("pregnancy");
|
||||
|
@ -486,7 +483,7 @@ namespace SizedApparel
|
|||
else
|
||||
defName = customDefName;
|
||||
|
||||
string bodyPartsFolderPath = "SizedApparel/BodyParts/";
|
||||
const string bodyPartsFolderPath = "SizedApparel/BodyParts/";
|
||||
string defaultHediffName = "Breasts";
|
||||
string graphicFolderPath = bodyPartsFolderPath + defName + "/" + "Breasts" + "/";
|
||||
string fileName;
|
||||
|
@ -519,7 +516,7 @@ namespace SizedApparel
|
|||
string pathString = "";
|
||||
int currentSizeIndex = -1;
|
||||
float currentSeverity = -1;
|
||||
while (offset < SizedApparelUtility.size.Length)
|
||||
while (offset < SizedApparelUtility.breastsSizeStrings.Length)
|
||||
{
|
||||
if (hediff != null)
|
||||
{
|
||||
|
@ -557,7 +554,7 @@ namespace SizedApparel
|
|||
if (validTexture == false)
|
||||
{
|
||||
offset = 0;
|
||||
while (offset < SizedApparelUtility.size.Length)
|
||||
while (offset < SizedApparelUtility.breastsSizeStrings.Length)
|
||||
{
|
||||
if (hediff != null)
|
||||
{
|
||||
|
@ -617,7 +614,7 @@ namespace SizedApparel
|
|||
defName = customRaceDefName;
|
||||
|
||||
string bodyType = bodyTypeName;
|
||||
string bodyPartsFolderPath = "SizedApparel/BodyParts/";
|
||||
const string bodyPartsFolderPath = "SizedApparel/BodyParts/";
|
||||
string graphicFolderPath;
|
||||
string targetFolderName = folderName;
|
||||
if (hornyGraphic)
|
||||
|
@ -667,20 +664,29 @@ namespace SizedApparel
|
|||
|
||||
|
||||
int offset = 0;
|
||||
int offsetLimit = 10 ; // = SizedApparelUtility.breastsSizeStrings.Length;
|
||||
|
||||
|
||||
|
||||
float SeverityCapped;
|
||||
|
||||
if (isBreast)
|
||||
{
|
||||
SeverityCapped = SizedApparelUtility.BreastSizeIndexToSeverity(sizeIndex);
|
||||
offsetLimit = SizedApparelUtility.breastsSizeStrings.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
SeverityCapped = SizedApparelUtility.PrivatePartSizeIndexToSeverity(sizeIndex);
|
||||
offsetLimit = SizedApparelUtility.commonSizeStrings.Length;
|
||||
}
|
||||
|
||||
bool validTexture = false;
|
||||
|
||||
bool findBigger = true; // if false : search smaller first
|
||||
string pathString = "";
|
||||
string pathStringWithVariatione = "";
|
||||
while (offset < SizedApparelUtility.size.Length)
|
||||
while (offset < offsetLimit)
|
||||
{
|
||||
if (hediffDefName != null)
|
||||
{
|
||||
|
@ -777,7 +783,7 @@ namespace SizedApparel
|
|||
if (validTexture == false)
|
||||
{
|
||||
offset = 0;
|
||||
while (offset < SizedApparelUtility.size.Length)
|
||||
while (offset < offsetLimit)
|
||||
{
|
||||
if (hediffDefName != null)
|
||||
{
|
||||
|
@ -903,134 +909,17 @@ namespace SizedApparel
|
|||
return graphic;
|
||||
|
||||
}
|
||||
/*
|
||||
public static Graphic GetBodyPartGraphic(Pawn pawn, Hediff hediff, bool isBreast, string folderName, string defaultHediffName, bool hornyGraphic = false, bool updateComp = false, string customRaceDefName = null)
|
||||
|
||||
|
||||
public static PubicHairDef GetRandomPubicHair()
|
||||
{
|
||||
int i = -1;
|
||||
string s = null;
|
||||
return GetBodyPartGraphic(pawn, hediff, isBreast, folderName, defaultHediffName, out i,out s, hornyGraphic, updateComp, customRaceDefName);
|
||||
return DefDatabase<PubicHairDef>.GetRandom();
|
||||
}
|
||||
public static PubicHairDef GetPubicHairEmpty()
|
||||
{
|
||||
return DefDatabase<PubicHairDef>.GetNamed("None");
|
||||
}
|
||||
|
||||
public static Graphic GetBodyPartGraphic(Pawn pawn, Hediff hediff, bool isBreast, string folderName, string defaultHediffName, out int indexOut,out string hediffResult, bool hornyGraphic = false, bool updateComp = false, string customRaceDefName = null)
|
||||
{
|
||||
Graphic graphic = null; //for return
|
||||
indexOut = -1;
|
||||
hediffResult = null;
|
||||
if (pawn == null)
|
||||
return null;
|
||||
if (hediff == null)
|
||||
return null;
|
||||
//rec = new ApparelGraphicRecord(null, null);
|
||||
Graphic nakedGraphic = pawn.Drawer?.renderer?.graphics?.nakedGraphic;
|
||||
if (nakedGraphic == null)
|
||||
return null;
|
||||
var rotComp = pawn.GetComp<CompRottable>();
|
||||
if (rotComp!=null)
|
||||
{
|
||||
if (rotComp.Stage == RotStage.Rotting)
|
||||
nakedGraphic = pawn.Drawer.renderer.graphics.rottingGraphic;
|
||||
}
|
||||
|
||||
ApparelRecorderComp comp = pawn.GetComp<ApparelRecorderComp>();
|
||||
string defName = pawn.def.defName;
|
||||
if (customRaceDefName != null)
|
||||
defName = customRaceDefName;
|
||||
string bodyType = null;
|
||||
if (pawn.story != null)
|
||||
bodyType = pawn.story.bodyType?.defName;
|
||||
string bodyPartsFolderPath = "SizedApparel/BodyParts/";
|
||||
string graphicFolderPath;
|
||||
if (hornyGraphic)
|
||||
graphicFolderPath = bodyPartsFolderPath + defName + "/" + folderName + "/Horny/";
|
||||
else
|
||||
graphicFolderPath = bodyPartsFolderPath + defName + "/" + folderName + "/";
|
||||
string fileName;
|
||||
string extraFileName;
|
||||
if(bodyType != null)
|
||||
{
|
||||
fileName = defaultHediffName + ("_" + bodyType);
|
||||
extraFileName = hediff.def.defName + ("_" + bodyType);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileName = defaultHediffName;
|
||||
extraFileName = hediff.def.defName;
|
||||
}
|
||||
|
||||
//if (SizedApparelSettings.matchBodyTextureToMinimumApparelSize)
|
||||
// BreastSeverity = comp.BreastSeverityCache;
|
||||
//int currentSizeIndex = 0;
|
||||
//float currentSeverity = -1;
|
||||
//int minSupportedBreastSizeIndex = 1000;
|
||||
//float minSupportedBreastSeverity = 1000;
|
||||
|
||||
//SizedApparelUtility.GetBreastSeverity(apparel.Wearer, out BreastSeverity, out breastHediff);
|
||||
if (comp != null)
|
||||
{
|
||||
|
||||
if (comp.hasUpdateBefore == false)
|
||||
{
|
||||
if (updateComp)
|
||||
{
|
||||
//SizedApparelUtility.GetBreastSeverity(apparel.Wearer, out BreastSeverity, out breastHediff);
|
||||
//comp.hasUnsupportedApparel = SizedApparelUtility.hasUnSupportedApparelFromWornData(apparel.Wearer, BreastSeverity, breastHediff);
|
||||
//comp.breastSeverity = BreastSeverity;
|
||||
//comp.breastHediff = breastHediff;
|
||||
//comp.hasUpdateBefore = true;
|
||||
//comp.Update(true,true,false);
|
||||
}
|
||||
|
||||
}
|
||||
float SeverityCapped = hediff.Severity; ;
|
||||
if (isBreast)
|
||||
{
|
||||
if (SizedApparelSettings.useBreastSizeCapForApparels) //SizedApparelSettings.useBreastSizeCapForApparels //wip
|
||||
SeverityCapped = Math.Min(comp.BreastSeverityCache, SeverityCapped);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (comp.hasUnsupportedApparel == false)
|
||||
{
|
||||
int index;
|
||||
if (isBreast)
|
||||
index = SizedApparelUtility.BreastSeverityInt(hediff.Severity);
|
||||
else
|
||||
index = SizedApparelUtility.PrivatePartSeverityInt(hediff.Severity);
|
||||
|
||||
Graphic partGraphic = GetBodyPartGraphic(pawn.def.defName, pawn.story?.bodyType?.defName, hediff.def.defName, hornyGraphic, index, folderName, defaultHediffName,out indexOut, out hediffResult, hornyGraphic, customRaceDefName);
|
||||
if(partGraphic != null)
|
||||
{
|
||||
graphic = GraphicDatabase.Get<Graphic_Multi>(partGraphic.path, nakedGraphic.Shader, nakedGraphic.drawSize, nakedGraphic.color, nakedGraphic.colorTwo);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//minSupportedBreastSizeIndex = Math.Min(currentBreastSizeIndex, minSupportedBreastSizeIndex);
|
||||
//comp.breastSeverityCapToDraw = Math.Min(comp.breastSeverityCapToDraw, minSupportedBreastSeverity);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (SizedApparelSettings.Debug)
|
||||
Log.Warning("[Sized Apparel] " + pawn.Name + " doesn't have SizedApparel Compoenet!!");
|
||||
|
||||
}
|
||||
return graphic;
|
||||
|
||||
}*/
|
||||
|
||||
//TODO
|
||||
public static Graphic GetBodyGraphic()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool IsHorny(Pawn pawn)
|
||||
{
|
||||
|
@ -1280,7 +1169,7 @@ namespace SizedApparel
|
|||
|
||||
if (findBigger)
|
||||
{
|
||||
if (size.Length - (targetIndex + offset) > 0)
|
||||
if (breastsSizeStrings.Length - (targetIndex + offset) > 0)
|
||||
{
|
||||
|
||||
//size.Length< targetIndex + offset
|
||||
|
@ -1294,14 +1183,14 @@ namespace SizedApparel
|
|||
//targetSeverity = BreastSizeIndexToSeverity(result);
|
||||
targetSeverity = PrivatePartSizeIndexToSeverity(result);
|
||||
outTargetSeverity = targetSeverity;
|
||||
return size[result];
|
||||
return breastsSizeStrings[result];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targetIndex - offset < 0)
|
||||
return "_-1";
|
||||
if (size.Length - (targetIndex - offset) > 0)
|
||||
if (breastsSizeStrings.Length - (targetIndex - offset) > 0)
|
||||
{
|
||||
/*
|
||||
if (size[targetIndex - offset] != null)
|
||||
|
@ -1313,7 +1202,7 @@ namespace SizedApparel
|
|||
//targetSeverity = BreastSizeIndexToSeverity(result);
|
||||
targetSeverity = PrivatePartSizeIndexToSeverity(result);
|
||||
outTargetSeverity = targetSeverity;
|
||||
return size[result];
|
||||
return breastsSizeStrings[result];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1345,57 +1234,68 @@ namespace SizedApparel
|
|||
}
|
||||
else if (BreastSeverity < 0.02f)
|
||||
{
|
||||
targetIndex = findAvailableSmallerSizeFromSetting(0);
|
||||
targetIndex = 0;
|
||||
//targetIndex = findAvailableSmallerSizeFromSetting(0);
|
||||
targetSeverity = 0.01f;
|
||||
}
|
||||
else if (BreastSeverity < 0.2f)
|
||||
{
|
||||
targetIndex = findAvailableSmallerSizeFromSetting(1);
|
||||
targetIndex = 1;
|
||||
//targetIndex = findAvailableSmallerSizeFromSetting(1);
|
||||
targetSeverity = 0.02f;
|
||||
}
|
||||
else if (BreastSeverity < 0.40f)
|
||||
{
|
||||
targetIndex = findAvailableSmallerSizeFromSetting(2);
|
||||
targetIndex = 2;
|
||||
//targetIndex = findAvailableSmallerSizeFromSetting(2);
|
||||
targetSeverity = 0.2f;
|
||||
}
|
||||
else if (BreastSeverity < 0.60f)
|
||||
{
|
||||
targetIndex = findAvailableSmallerSizeFromSetting(3);
|
||||
targetIndex = 3;
|
||||
//targetIndex = findAvailableSmallerSizeFromSetting(3);
|
||||
targetSeverity = 0.40f;
|
||||
}
|
||||
else if (BreastSeverity < 0.80f)
|
||||
{
|
||||
targetIndex = findAvailableSmallerSizeFromSetting(4);
|
||||
targetIndex = 4;
|
||||
//targetIndex = findAvailableSmallerSizeFromSetting(4);
|
||||
targetSeverity = 0.60f;
|
||||
}
|
||||
else if (BreastSeverity < 1.0f)
|
||||
{
|
||||
targetIndex = findAvailableSmallerSizeFromSetting(5);
|
||||
targetIndex = 5;
|
||||
//targetIndex = findAvailableSmallerSizeFromSetting(5);
|
||||
targetSeverity = 0.80f;
|
||||
}
|
||||
else if (BreastSeverity < 1.2f)
|
||||
{
|
||||
targetIndex = findAvailableSmallerSizeFromSetting(6);
|
||||
targetIndex = 6;
|
||||
//targetIndex = findAvailableSmallerSizeFromSetting(6);
|
||||
targetSeverity = 1.0f;
|
||||
}
|
||||
else if (BreastSeverity < 1.4f)
|
||||
{
|
||||
targetIndex = findAvailableSmallerSizeFromSetting(7);
|
||||
targetIndex = 7;
|
||||
//targetIndex = findAvailableSmallerSizeFromSetting(7);
|
||||
targetSeverity = 1.2f;
|
||||
}
|
||||
else if (BreastSeverity < 1.6f)
|
||||
{
|
||||
targetIndex = findAvailableSmallerSizeFromSetting(8);
|
||||
targetIndex = 8;
|
||||
//targetIndex = findAvailableSmallerSizeFromSetting(8);
|
||||
targetSeverity = 1.4f;
|
||||
}
|
||||
else if (BreastSeverity < 1.8f)
|
||||
{
|
||||
targetIndex = findAvailableSmallerSizeFromSetting(9);
|
||||
targetIndex = 9;
|
||||
//targetIndex = findAvailableSmallerSizeFromSetting(9);
|
||||
targetSeverity = 1.6f;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetIndex = findAvailableSmallerSizeFromSetting(10);
|
||||
targetIndex = 10;
|
||||
//targetIndex = findAvailableSmallerSizeFromSetting(10);
|
||||
targetSeverity = 1.8f;
|
||||
}
|
||||
//if (targetIndex - offset < 0)
|
||||
|
@ -1404,7 +1304,7 @@ namespace SizedApparel
|
|||
|
||||
if (findBigger)
|
||||
{
|
||||
if (size.Length - (targetIndex + offset) > 0)
|
||||
if (breastsSizeStrings.Length - (targetIndex + offset) > 0)
|
||||
{
|
||||
|
||||
//size.Length< targetIndex + offset
|
||||
|
@ -1416,14 +1316,14 @@ namespace SizedApparel
|
|||
outTargetIndex = result;
|
||||
targetSeverity = BreastSizeIndexToSeverity(result);
|
||||
outTargetSeverity = targetSeverity;
|
||||
return size[result];
|
||||
return breastsSizeStrings[result];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (targetIndex - offset < 0)
|
||||
return "_-1";
|
||||
if (size.Length - (targetIndex - offset) > 0)
|
||||
if (breastsSizeStrings.Length - (targetIndex - offset) > 0)
|
||||
{
|
||||
/*
|
||||
if (size[targetIndex - offset] != null)
|
||||
|
@ -1433,7 +1333,7 @@ namespace SizedApparel
|
|||
outTargetIndex = result;
|
||||
targetSeverity = BreastSizeIndexToSeverity(result);
|
||||
outTargetSeverity = targetSeverity;
|
||||
return size[result];
|
||||
return breastsSizeStrings[result];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1540,7 +1440,7 @@ namespace SizedApparel
|
|||
bool validTexture = false;
|
||||
|
||||
bool findBigger = true; // if false : search smaller first
|
||||
while (offset < size.Length)
|
||||
while (offset < breastsSizeStrings.Length)
|
||||
{
|
||||
if (breastHediff != null)
|
||||
{
|
||||
|
@ -1579,7 +1479,7 @@ namespace SizedApparel
|
|||
if (validTexture == false)
|
||||
{
|
||||
offset = 0;
|
||||
while (offset < size.Length)
|
||||
while (offset < breastsSizeStrings.Length)
|
||||
{
|
||||
if (breastHediff != null)
|
||||
{
|
||||
|
@ -1769,7 +1669,7 @@ namespace SizedApparel
|
|||
bool validTexture = false;
|
||||
|
||||
bool findBigger = true; // if false : search smaller first
|
||||
while (offset < size.Length)
|
||||
while (offset < breastsSizeStrings.Length)
|
||||
{
|
||||
if (breastHediff != null)
|
||||
{
|
||||
|
@ -1825,7 +1725,7 @@ namespace SizedApparel
|
|||
if (validTexture == false)
|
||||
{
|
||||
offset = 0;
|
||||
while (offset < size.Length)
|
||||
while (offset < breastsSizeStrings.Length)
|
||||
{
|
||||
if (breastHediff != null)
|
||||
{
|
||||
|
@ -1948,7 +1848,7 @@ namespace SizedApparel
|
|||
return;
|
||||
}
|
||||
|
||||
pawnGraphicSet.ResolveApparelGraphics();
|
||||
//pawnGraphicSet.ResolveApparelGraphics();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2034,6 +1934,19 @@ namespace SizedApparel
|
|||
return true;
|
||||
}
|
||||
|
||||
public static bool CanDrawPubicHair(Pawn pawn, PawnRenderFlags flags = PawnRenderFlags.None)
|
||||
{
|
||||
if (pawn == null)
|
||||
return false;
|
||||
var comp = pawn.GetComp<ApparelRecorderComp>();
|
||||
if (comp == null)
|
||||
return false;
|
||||
|
||||
if (!flags.FlagSet(PawnRenderFlags.Clothes))
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool CanDrawAnus(Pawn pawn, PawnRenderFlags flags = PawnRenderFlags.None)
|
||||
{
|
||||
if (pawn == null)
|
||||
|
@ -2148,8 +2061,48 @@ namespace SizedApparel
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static bool CanPoseApparels(Pawn pawn, string targetPose, string currentHediffName = null, int currentSeverityInt = 0, int cappedSeverityInt = 1000)
|
||||
{
|
||||
if (pawn == null)
|
||||
return false;
|
||||
foreach (ApparelGraphicRecord agr in pawn.Drawer.renderer.graphics.apparelGraphics)
|
||||
{
|
||||
if (agr.graphic == null)
|
||||
continue;
|
||||
/*
|
||||
if (!agr.sourceApparel.def.apparel.bodyPartGroups.Any(bpgd => bpgd.defName == "Torso" || bpgd.defName == "Chest"))
|
||||
continue;
|
||||
|
||||
if (agr.sourceApparel.def.apparel.tags.Any(s => s.ToLower() == "SizedApparel_IgnorePose".ToLower()))
|
||||
continue;
|
||||
*/
|
||||
//Only Check Torso Apparel Only
|
||||
if (!agr.sourceApparel.def.apparel.bodyPartGroups.Contains(BodyPartGroupDefOf.Torso))
|
||||
continue;
|
||||
|
||||
string originalPath = SizedApparelsDatabase.GetSupportedApparelOriginalPath(agr.graphic.path);
|
||||
if (originalPath == null)
|
||||
return false;
|
||||
|
||||
int outInt = -1;
|
||||
float outFloat = -1;
|
||||
SizedApparelsDatabase.SizedApparelDatabaseKey key = new SizedApparelsDatabase.SizedApparelDatabaseKey(originalPath, pawn.def.defName, pawn.story?.bodyType?.defName, pawn.gender, currentHediffName, Math.Min(currentSeverityInt, cappedSeverityInt), false, targetPose);
|
||||
if (SizedApparelSettings.useGenderSpecificTexture)
|
||||
key.gender = Gender.None;
|
||||
var result = SizedApparelsDatabase.GetSupportedApparelSizedPath(key, out outInt, out outFloat);
|
||||
if (!result.isCustomPose)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -52,9 +52,11 @@
|
|||
<HintPath>..\..\..\rimnude-unofficial\Assembly Folders\1.4 Assembly\Assemblies\RimNudeWorld.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Rimworld-Animations">
|
||||
<Reference Include="Rimworld-Animations, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\rimworld-animations\1.4\Assemblies\Rimworld-Animations.dll</HintPath>
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<Private>False</Private>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="RJW">
|
||||
<HintPath>..\..\..\rjw\1.4\Assemblies\RJW.dll</HintPath>
|
||||
|
@ -87,24 +89,27 @@
|
|||
<Compile Include="AlienRaceSupport.cs" />
|
||||
<Compile Include="Graphic_BodyParts.cs" />
|
||||
<Compile Include="Graphic_SizedApparel.cs" />
|
||||
<Compile Include="Patch-Animation.cs" />
|
||||
<Compile Include="SizedAppareIdeoPatch.cs" />
|
||||
<Compile Include="SizedApparelApparelBuilder.cs" />
|
||||
<Compile Include="SizedApparelBodyPart.cs" />
|
||||
<Compile Include="SizedApparelBodyPartDef.cs" />
|
||||
<Compile Include="SizedApparelBodyPartDetail.cs" />
|
||||
<Compile Include="SizedApparelBodyPartEditor.cs" />
|
||||
<Compile Include="SizedApparelComp.cs" />
|
||||
<Compile Include="HarmonyPatches.cs" />
|
||||
<Compile Include="SizedApparelDef.cs" />
|
||||
<Compile Include="SizedApparelDubsApparelPatch.cs" />
|
||||
<Compile Include="Patch-DubsApparelPatch.cs" />
|
||||
<Compile Include="SizedApparelMain.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SizedApparelPoseSet.cs" />
|
||||
<Compile Include="SizedApparelPubicHair.cs" />
|
||||
<Compile Include="SizedApparelRJWPatch.cs" />
|
||||
<Compile Include="SizedApparelRNWPatch.cs" />
|
||||
<Compile Include="Patch-RimJobWorld.cs" />
|
||||
<Compile Include="Patch-RimNudeWorld.cs" />
|
||||
<Compile Include="SizedApparelsDatabase.cs" />
|
||||
<Compile Include="SizedApparelSettingcs.cs" />
|
||||
<Compile Include="SizedApparelStyleStationPatch.cs" />
|
||||
<Compile Include="SizedApparelTexturePointDef.cs" />
|
||||
<Compile Include="SizedApparelUtility.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
|
|
|
@ -11,6 +11,27 @@ using rjw;
|
|||
|
||||
namespace SizedApparel
|
||||
{
|
||||
public class BodyTypeAndPath
|
||||
{
|
||||
public string BodyType;
|
||||
public string Path;
|
||||
}
|
||||
|
||||
public class ApparelData
|
||||
{
|
||||
public string WornPath;
|
||||
public List<BodyTypeAndPath> Data;
|
||||
}
|
||||
public class PreDefinedApparelDate : Def
|
||||
{
|
||||
public string HediffName;
|
||||
public bool IsBreasts = false;
|
||||
public List<BodyTypeAndPath> Data;
|
||||
}
|
||||
public class PreDefinedBodyPartGraphicDate : Def
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static class SizedApparelsDatabase
|
||||
{
|
||||
|
@ -20,6 +41,12 @@ namespace SizedApparel
|
|||
|
||||
}
|
||||
|
||||
public static void LoadPreDefinedData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public struct SizedApparelDatabaseKey
|
||||
{
|
||||
|
@ -107,9 +134,9 @@ namespace SizedApparel
|
|||
public bool isUnsupportedHumanlikePath;
|
||||
public bool isCustomPose;
|
||||
public string hediffName;
|
||||
public Dictionary<string, BodyPartPoint> points;
|
||||
public SizedApparelTexturePointDef points;
|
||||
|
||||
public PathAndSize(string path, int index, bool unsupportedHumanlike = false, bool customPose = false, string hediff = null ,Dictionary<string, BodyPartPoint> pointsInput = null)
|
||||
public PathAndSize(string path, int index, bool unsupportedHumanlike = false, bool customPose = false, string hediff = null , SizedApparelTexturePointDef pointsInput = null)
|
||||
{
|
||||
this.pathWithSizeIndex = path;
|
||||
this.size = index;
|
||||
|
@ -151,7 +178,8 @@ namespace SizedApparel
|
|||
AlienRaceUseHumanlike.Add(raceDef.defName, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Obsolete]
|
||||
public static bool GetAlienRaceUseHumanlike(string raceDef)
|
||||
{
|
||||
if (AlienRaceUseHumanlike.NullOrEmpty())
|
||||
|
@ -279,12 +307,18 @@ namespace SizedApparel
|
|||
|
||||
public static PathAndSize GetSupportedBodyPartPath(BodyPartDatabaseKey key, bool isBreast, string folderName, string defaultHediffName)
|
||||
{
|
||||
|
||||
PathAndSize result;
|
||||
if (SupportedBodyPartResultPath.ContainsKey(key))
|
||||
return SupportedBodyPartResultPath.TryGetValue(key);
|
||||
int currentSize = -1;
|
||||
string hediffResult;
|
||||
Graphic graphic = null;
|
||||
|
||||
//Find Points from result's path
|
||||
//TODO: Build SizedApparel DataBase separate?
|
||||
|
||||
|
||||
if (key.customPose != null)
|
||||
{
|
||||
graphic = SizedApparelUtility.GetBodyPartGraphic(key.raceName, key.bodyTypeName, key.hediffName, isBreast, key.targetSize, folderName+"/CustomPose/"+key.customPose, defaultHediffName, out currentSize, out hediffResult, key.isHorny, null, key.variation, key.gender);
|
||||
|
@ -292,6 +326,11 @@ namespace SizedApparel
|
|||
{
|
||||
result = new PathAndSize(graphic.path, currentSize, false, true, hediffResult);
|
||||
SupportedBodyPartResultPath.SetOrAdd(key, result);
|
||||
//SizedApparelTexturePointDef PointsDef = DefDatabase<SizedApparelTexturePointDef>.AllDefs.FirstOrDefault((SizedApparelTexturePointDef s) => s.Path == graphic.path);
|
||||
//if (SizedApparelSettings.Debug && PointsDef != null)
|
||||
//{
|
||||
// Log.Message("[SizedApparel] : Points Def Found : " + PointsDef.defName);
|
||||
//}
|
||||
return result;
|
||||
}
|
||||
if (key.bodyTypeName != null)
|
||||
|
@ -300,6 +339,11 @@ namespace SizedApparel
|
|||
{
|
||||
result = new PathAndSize(graphic.path, currentSize, false, true, hediffResult);
|
||||
SupportedBodyPartResultPath.SetOrAdd(key, result);
|
||||
//SizedApparelTexturePointDef PointsDef = DefDatabase<SizedApparelTexturePointDef>.AllDefs.FirstOrDefault((SizedApparelTexturePointDef s) => s.Path == graphic.path);
|
||||
//if (SizedApparelSettings.Debug && PointsDef != null)
|
||||
//{
|
||||
// Log.Message("[SizedApparel] : Points Def Found : " + PointsDef.defName);
|
||||
//}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -307,8 +351,14 @@ namespace SizedApparel
|
|||
graphic = SizedApparelUtility.GetBodyPartGraphic(key.raceName, key.bodyTypeName, key.hediffName, isBreast, key.targetSize, folderName, defaultHediffName, out currentSize, out hediffResult, key.isHorny, null, key.variation, key.gender);
|
||||
if (graphic != null)
|
||||
{
|
||||
//SizedApparelTexturePointDef PointsDef = DefDatabase<SizedApparelTexturePointDef>.AllDefs.FirstOrDefault((SizedApparelTexturePointDef s) => s.Path == graphic.path);
|
||||
//if (SizedApparelSettings.Debug && PointsDef != null)
|
||||
//{
|
||||
// Log.Message("[SizedApparel] : Points Def Found : " + PointsDef.defName);
|
||||
//}
|
||||
result = new PathAndSize(graphic.path, currentSize, false, key.customPose == null ? true : false, hediffResult);
|
||||
SupportedBodyPartResultPath.SetOrAdd(key, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -316,6 +366,11 @@ namespace SizedApparel
|
|||
graphic = SizedApparelUtility.GetBodyPartGraphic(key.raceName, null, key.hediffName, isBreast, key.targetSize, folderName, defaultHediffName, out currentSize, out hediffResult, key.isHorny, null, key.variation, key.gender);
|
||||
if (graphic != null)
|
||||
{
|
||||
//SizedApparelTexturePointDef PointsDef = DefDatabase<SizedApparelTexturePointDef>.AllDefs.FirstOrDefault((SizedApparelTexturePointDef s) => s.Path == graphic.path);
|
||||
//if (SizedApparelSettings.Debug && PointsDef != null)
|
||||
//{
|
||||
// Log.Message("[SizedApparel] : Points Def Found : " + PointsDef.defName);
|
||||
//}
|
||||
result = new PathAndSize(graphic.path, currentSize, false, key.customPose == null ? true : false, hediffResult);
|
||||
SupportedBodyPartResultPath.SetOrAdd(key, result);
|
||||
return result;
|
||||
|
@ -325,7 +380,7 @@ namespace SizedApparel
|
|||
//SizedApparelMod.CheckAndLoadAlienRaces();
|
||||
//HumanLike Search
|
||||
var raceSetting = SizedApparelSettings.alienRaceSettings.FirstOrDefault((AlienRaceSetting s) => s.raceName == key.raceName);
|
||||
if (raceSetting !=null && !raceSetting.asHumanlike) //old: !SizedApparelSettings.UnsupportedRaceToUseHumanlike
|
||||
if (raceSetting !=null && key.raceName == "Human" || !raceSetting.asHuman) //old: !SizedApparelSettings.UnsupportedRaceToUseHumanlike
|
||||
{
|
||||
//Cannot find Any result
|
||||
result = new PathAndSize(null, -1);
|
||||
|
@ -335,35 +390,55 @@ namespace SizedApparel
|
|||
|
||||
if (key.customPose != null)
|
||||
{
|
||||
graphic = SizedApparelUtility.GetBodyPartGraphic(key.raceName, key.bodyTypeName, key.hediffName, isBreast, key.targetSize, folderName + "/CustomPose/" + key.customPose, defaultHediffName, out currentSize, out hediffResult, key.isHorny, "Humanlike", key.variation, key.gender);
|
||||
graphic = SizedApparelUtility.GetBodyPartGraphic(key.raceName, key.bodyTypeName, key.hediffName, isBreast, key.targetSize, folderName + "/CustomPose/" + key.customPose, defaultHediffName, out currentSize, out hediffResult, key.isHorny, "Human", key.variation, key.gender);
|
||||
if (graphic != null)
|
||||
{
|
||||
//SizedApparelTexturePointDef PointsDef = DefDatabase<SizedApparelTexturePointDef>.AllDefs.FirstOrDefault((SizedApparelTexturePointDef s) => s.Path == graphic.path);
|
||||
//if (SizedApparelSettings.Debug && PointsDef != null)
|
||||
//{
|
||||
// Log.Message("[SizedApparel] : Points Def Found : " + PointsDef.defName);
|
||||
//}
|
||||
result = new PathAndSize(graphic.path, currentSize, true, true, hediffResult);
|
||||
SupportedBodyPartResultPath.SetOrAdd(key, result);
|
||||
return result;
|
||||
}
|
||||
if (key.bodyTypeName != null)
|
||||
graphic = SizedApparelUtility.GetBodyPartGraphic(key.raceName, null, key.hediffName, isBreast, key.targetSize, folderName + "/CustomPose/" + key.customPose, defaultHediffName, out currentSize, out hediffResult, key.isHorny, "Humanlike", key.variation, key.gender);
|
||||
graphic = SizedApparelUtility.GetBodyPartGraphic(key.raceName, null, key.hediffName, isBreast, key.targetSize, folderName + "/CustomPose/" + key.customPose, defaultHediffName, out currentSize, out hediffResult, key.isHorny, "Human", key.variation, key.gender);
|
||||
if (graphic != null)
|
||||
{
|
||||
//SizedApparelTexturePointDef PointsDef = DefDatabase<SizedApparelTexturePointDef>.AllDefs.FirstOrDefault((SizedApparelTexturePointDef s) => s.Path == graphic.path);
|
||||
//if (SizedApparelSettings.Debug && PointsDef != null)
|
||||
//{
|
||||
// Log.Message("[SizedApparel] : Points Def Found : " + PointsDef.defName);
|
||||
//}
|
||||
result = new PathAndSize(graphic.path, currentSize, true, true, hediffResult);
|
||||
SupportedBodyPartResultPath.SetOrAdd(key, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
graphic = SizedApparelUtility.GetBodyPartGraphic(key.raceName, key.bodyTypeName, key.hediffName, isBreast, key.targetSize, folderName, defaultHediffName, out currentSize, out hediffResult, key.isHorny, "Humanlike", key.variation, key.gender);
|
||||
graphic = SizedApparelUtility.GetBodyPartGraphic(key.raceName, key.bodyTypeName, key.hediffName, isBreast, key.targetSize, folderName, defaultHediffName, out currentSize, out hediffResult, key.isHorny, "Human", key.variation, key.gender);
|
||||
if (graphic != null)
|
||||
{
|
||||
//SizedApparelTexturePointDef PointsDef = DefDatabase<SizedApparelTexturePointDef>.AllDefs.FirstOrDefault((SizedApparelTexturePointDef s) => s.Path == graphic.path);
|
||||
//if (SizedApparelSettings.Debug && PointsDef != null)
|
||||
//{
|
||||
// Log.Message("[SizedApparel] : Points Def Found : " + PointsDef.defName);
|
||||
//}
|
||||
result = new PathAndSize(graphic.path, currentSize, true, key.customPose == null ? true : false, hediffResult);
|
||||
SupportedBodyPartResultPath.SetOrAdd(key, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (key.bodyTypeName != null)
|
||||
graphic = SizedApparelUtility.GetBodyPartGraphic(key.raceName, null, key.hediffName, isBreast, key.targetSize, folderName, defaultHediffName, out currentSize, out hediffResult, key.isHorny, "Humanlike", key.variation, key.gender);
|
||||
graphic = SizedApparelUtility.GetBodyPartGraphic(key.raceName, null, key.hediffName, isBreast, key.targetSize, folderName, defaultHediffName, out currentSize, out hediffResult, key.isHorny, "Human", key.variation, key.gender);
|
||||
if (graphic != null)
|
||||
{
|
||||
//SizedApparelTexturePointDef PointsDef = DefDatabase<SizedApparelTexturePointDef>.AllDefs.FirstOrDefault((SizedApparelTexturePointDef s) => s.Path == graphic.path);
|
||||
//if (SizedApparelSettings.Debug && PointsDef != null)
|
||||
//{
|
||||
// Log.Message("[SizedApparel] : Points Def Found : " + PointsDef.defName);
|
||||
//}
|
||||
result = new PathAndSize(graphic.path, currentSize, true, key.customPose == null ? true : false, hediffResult);
|
||||
SupportedBodyPartResultPath.SetOrAdd(key, result);
|
||||
return result;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue