Mirror of 1.4.15 from Lovers Lab

This commit is contained in:
ghostclinic3YTB 2023-04-03 21:47:49 -04:00
parent 9a3d9f4185
commit a5ed05c17b
1180 changed files with 4378 additions and 1905 deletions

View file

@ -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
}
}