Mirror of 1.4.7 from Lovers Lab

This commit is contained in:
Jacob Adamson 2022-11-05 17:21:09 -04:00
parent 161133e4e1
commit 6e95cff0ed
607 changed files with 11263 additions and 1309 deletions

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RimWorld;
using Verse;
namespace SizedApparel
{
class AlienRaceSupport
{
}
public class SizedApparelPawnDef : Def
{
public bool allowForceHumanlike = false;
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SizedApparel
{
public class Graphic_BodyParts : Verse.Graphic_Multi
{
public float serverity;
public string bodyPart; // such as breasts, penis
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SizedApparel
{
public class Graphic_SizedApparel : Verse.Graphic_Multi
{
}
}

View File

@ -0,0 +1,263 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RimWorld;
using Verse;
using HarmonyLib;
//using AlienRace;
using UnityEngine;
using rjw;
using RevealingApparel;
using System.Reflection;
namespace SizedApparel
{
[StaticConstructorOnStartup]
public class SizedApparelPatch
{
public static bool alienRaceActive = false;
public static bool SJWActive = false;
public static bool RJWActive = false;
public static bool DubsApparelTweaksActive = false;
public static bool rimNudeWorldActive = false;
public static bool OTYNudeActive = false;
public static bool LicentiaActive = false;
static SizedApparelPatch()
{
//check SJW
if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "SafeJobWorld"))
{
SJWActive = true;
}
if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId == "safe.job.world"))
{
SJWActive = true;
}
//check RJW
if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "RimJobWorld"))
{
RJWActive = true;
}
if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId == "rim.job.world"))
{
RJWActive = true;
}
//check Dubs Apparel Tweaks
if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "Dubs Apparel Tweaks"))
{
DubsApparelTweaksActive = true;
}
if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId == "Dubwise.DubsApparelTweaks"))
{
DubsApparelTweaksActive = true;
}
//check Alien Race
if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "Humanoid Alien Races 2.0"))
{
alienRaceActive = true;
}
if (LoadedModManager.RunningModsListForReading.Any(x => x.Name.Contains("Humanoid Alien Races")))
{
alienRaceActive = true;
}
if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId == "erdelf.HumanoidAlienRaces"))
{
alienRaceActive = true;
}
//check RimNudeWorld
if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId == "shauaputa.rimnudeworld"))
{
rimNudeWorldActive = true;
}
//check OTYNude
if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId.Contains("OTY")&& x.PackageId.Contains("Nude")))
{
OTYNudeActive = true;
}
//check Licentia Lab
if (LoadedModManager.RunningModsListForReading.Any(x => x.PackageId.ToLower() == "LustLicentia.RJWLabs".ToLower()))
{
LicentiaActive = true;
}
Log.Message("[SizedApparel] start");
var harmony = new Harmony("SizedApparelforRJW");
harmony.PatchAll();
/*
try
{
((Action)(() => {
if (LoadedModManager.RunningModsListForReading.Any(x => x.Name == "OTY_NUDE"))
{
Log.Message("Sized Apparel for RJW : OTY_NUDE founded");
usingOversized = true;
usingBackBreaking = true;
}
}))();
}
catch (TypeLoadException ex)
{
}
*/
//RJW Patch
try
{
((Action)(() =>
{
if (RJWActive)
{
Log.Message("[SizedApparel] RimJobWorld Found");
//harmony.Patch(AccessTools.Method(typeof(rjw.JobDriver_SexBaseInitiator), "Start"),
//postfix: new HarmonyMethod(typeof(SexStartPatch), "Postfix"));
//harmony.Patch(AccessTools.Method(typeof(rjw.JobDriver_SexBaseInitiator), "End"),
//postfix: new HarmonyMethod(typeof(SexEndPatch), "Postfix"));
//harmony.Patch(AccessTools.Method(typeof(rjw.SexUtility), "DrawNude"),
//postfix: new HarmonyMethod(typeof(DrawNudePatch), "Postfix"));
harmony.Patch(AccessTools.Method(typeof(Sexualizer), "sexualize_pawn"),
postfix: new HarmonyMethod(typeof(SexualizePawnPatch), "Postfix"));
Log.Message("[SizedApparel] RimJobWorld Patched");
}
else
{
Log.Message("[SizedApparel] RimJobWorld Paatch canceled");
}
}))();
}
catch (TypeLoadException ex) { }
//Alien Race Patch
//Alien Race No longer supported.
/*
try
{
((Action)(() =>
{
if (alienRaceActive)
{
Log.Message("[SizedApparel] AlienRace Found");
//harmony.Patch(AccessTools.Method(typeof(AlienRace.HarmonyPatches), "DrawAddons"),
//prefix: new HarmonyMethod(typeof(DrawAddonPatch), "Prefix"));
Log.Message("[SizedApparel] AlienRace Patched");
}
else
{
Log.Message("[SizedApparel] AlienRace Patch canceled");
}
}))();
}
catch (TypeLoadException ex) { }
*/
//Rim Nude World Patch
try
{
((Action)(() =>
{
if (alienRaceActive && rimNudeWorldActive)
{
Log.Message("[SizedApparel] RimNudeWorld Found");
/*
harmony.Patch(AccessTools.Method(typeof(AlienRace.AlienPartGenerator.BodyAddon), "CanDrawAddon"),
postfix: new HarmonyMethod(typeof(RimNudeWorldBreastHidePatch), "Postfix"));
*/
//harmony.Patch(AccessTools.Method(typeof(RimNudeWorld.GenitalPatch), "Postfix"),
//prefix: new HarmonyMethod(typeof(SizedApparelRNWPatch), "Prefix"));
//Log.Message("SizedApparelforRJW::AlienRacePatch");
Log.Message("[SizedApparel] RimNudeWorld Patching...: RevealingApparel");
harmony.Patch(AccessTools.Method(typeof(RevealingApparel.RevealingApparel), "CanDrawRevealing"),
postfix: new HarmonyMethod(typeof(RevealingApparelPatch), "Postfix"));
Log.Message("[SizedApparel] RimNudeWorld Patched: RevealingApparel");
}
else
{
Log.Message("[SizedApparel] RimNudeWorld Patch canceled");
}
}))();
}
catch (TypeLoadException ex)
{
Log.Warning("[SizedApparel] Activated RimNudeWorld version not match to patch!\nSome patch for RimNudeWorld may not work!");
}
//Dubs Apparel Tweaks Patch
try
{
((Action)(() =>
{
if (DubsApparelTweaksActive)
{
Log.Message("[SizedApparel] Dubs Apparel Tweaks Found");
//harmony.Patch(AccessTools.Method(typeof(QuickFast.bs), "SwitchIndoors"),
//postfix: new HarmonyMethod(typeof(SizedApparelDubsApparelPatch), "indoorPostFixPatch"));
Log.Message("[SizedApparel] Dubs Apparel Tweaks (not) Patched (just debug message)");
}
else
{
Log.Message("[SizedApparel] Dubs Apparel Tweaks Patch canceled");
}
}))();
}
catch (TypeLoadException ex) { }
//SizedApparelPatch
try
{
((Action)(() =>
{
Log.Message("[SizedApparel] doing PawnRenderer Patch");
//disable for 1.3
/*
var original = typeof(PawnRenderer).GetMethod("RenderPawnInternal", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] {typeof(Vector3),typeof(float), typeof(bool), typeof(Rot4), typeof(Rot4), typeof(RotDrawMode), typeof(bool), typeof(bool), typeof(bool) }, null );
var postfix = typeof(DrawPawnPatch).GetMethod("RenderPawnInternalPostfix");
var prefix = typeof(DrawPawnPatch).GetMethod("RenderPawnInternalPrefix");
harmony.Patch(original, prefix: new HarmonyMethod(prefix), postfix: new HarmonyMethod(postfix));
*/
//1.3
var original0 = typeof(Pawn_ApparelTracker).GetMethod("Notify_ApparelChanged");
var original1 = typeof(Pawn_ApparelTracker).GetMethod("Notify_ApparelAdded");
var original2 = typeof(Pawn_ApparelTracker).GetMethod("Notify_ApparelRemoved");
var postfix = typeof(ApparelTrackerPatch).GetMethod("Changed");
harmony.Patch(original0, postfix: new HarmonyMethod(postfix));
//harmony.Patch(original1, postfix: new HarmonyMethod(postfix));
//harmony.Patch(original2, postfix: new HarmonyMethod(postfix));
Log.Message("[SizedApparel] PawnRenderer Patch complete");
}))();
}
catch (TypeLoadException ex)
{
Log.Error("[SizedApparel] Cannot Patch for \"RenderPawnInternal\" Method! the mod may not work!");
}
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 어셈블리에 대한 일반 정보는 다음 특성 집합을 통해
// 제어됩니다. 어셈블리와 관련된 정보를 수정하려면
// 이러한 특성 값을 변경하세요.
[assembly: AssemblyTitle("SizedApparelforRJW")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SizedApparelforRJW")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// ComVisible을 false로 설정하면 이 어셈블리의 형식이 COM 구성 요소에
// 표시되지 않습니다. COM에서 이 어셈블리의 형식에 액세스하려면
// 해당 형식에 대해 ComVisible 특성을 true로 설정하세요.
[assembly: ComVisible(false)]
// 이 프로젝트가 COM에 노출되는 경우 다음 GUID는 typelib의 ID를 나타냅니다.
[assembly: Guid("b06471b4-4c6c-478b-b94d-71cc53abd24d")]
// 어셈블리의 버전 정보는 다음 네 가지 값으로 구성됩니다.
//
// 주 버전
// 부 버전
// 빌드 번호
// 수정 버전
//
// 모든 값을 지정하거나 아래와 같이 '*'를 사용하여 빌드 번호 및 수정 번호를
// 기본값으로 할 수 있습니다.
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,37 @@
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 rjw;
namespace SizedApparel
{
//IdeoUIUtility.DoAppearanceItems
[HarmonyPatch(typeof(IdeoUIUtility), "DoAppearanceItems")]
static class SizedApparAppearanceUIPatch
{
//Todo: Use Transpiler
static public void oldPostfix(Ideo ideo, IdeoEditMode editMode, ref float curY, float width)
{
//DrawPubicBlox()
Rect rect = new Rect(4f, curY, IdeoUIUtility.PreceptBoxSize.x, IdeoUIUtility.PreceptBoxSize.y);
Widgets.DrawRectFast(rect, IdeoUIUtility.GetBackgroundColor(PreceptImpact.Medium), null);
string text = "PubicHair".Translate();
}
static void DrawPubicBox(float xOffset, float y, StyleItemTab tab, StyleItemDef defToDisplay)
{
}
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SizedApparel
{
//apparel build with apparel parts. but how?
public class SizedApparelApparelBuilder
{
}
}

View File

@ -0,0 +1,670 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RimWorld;
using Verse;
using HarmonyLib;
//using AlienRace;
using UnityEngine;
using rjw;
using System.Reflection;
namespace SizedApparel
{
public struct Depth4Offsets
{
float South;
float North;
float East;
float West;
}
public struct 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)
{
South = vector;
North = vector;
East = vector;
West = vector;
}
public Rot4Offsets(Vector3 south, Vector3 north, Vector3 east, Vector3 west)
{
South = south;
North = north;
East = east;
West = west;
}
public Vector3 GetOffset(Rot4 rotation)
{
if (rotation == Rot4.East)
return East;
if (rotation == Rot4.West)
return West;
if (rotation == Rot4.South)
return South;
if (rotation == Rot4.North)
return North;
else
return Vector3.zero;
}
}
public struct RaceNameAndBodyType
{
public string raceName;
public string bodyType;
}
public class BodyPart
{
public string partName;
public Depth4Offsets depthOffset;
public List<BodyTypeAndOffset> offsets;
}
public class BodyTypeAndOffset
{
//public RaceNameAndBodyType bodyTypeData;
public string bodyType;
public Rot4Offsets offsets = new Rot4Offsets(Vector3.zero);
public BodyTypeAndOffset(bool useCenter)
{
if (useCenter)
{
offsets = new Rot4Offsets(new Vector3(0.5f, 0, 0.5f));
}
}
public BodyTypeAndOffset(Vector3 defaultOffset)
{
offsets = new Rot4Offsets(defaultOffset);
}
}
public enum SizedApparelBodyPartColorOf
{
Skin, Hair, Custom, None
}
public enum SizedApparelBodyPartOf
{
All, Torso, Breasts, Crotch, Penis, Vagina, Anus, Belly, Udder, Hips, Thighs, hands, feet, None
}
public static class SizedApparelBodyPartOfExtension
{
public static bool IsPartOf(this SizedApparelBodyPartOf source, SizedApparelBodyPartOf target)
{
if (source == SizedApparelBodyPartOf.None)
return false;
switch (target)
{
case SizedApparelBodyPartOf.All:
return true;
case SizedApparelBodyPartOf.Torso:
if (source == SizedApparelBodyPartOf.hands || source == SizedApparelBodyPartOf.feet)
return false;
return true;
case SizedApparelBodyPartOf.Breasts:
if (source == SizedApparelBodyPartOf.Breasts)
return true;
return false;
case SizedApparelBodyPartOf.Crotch:
if (source == SizedApparelBodyPartOf.Penis || source == SizedApparelBodyPartOf.Vagina || source == SizedApparelBodyPartOf.Anus)
return true;
return false;
case SizedApparelBodyPartOf.Penis:
if (source == SizedApparelBodyPartOf.Penis)
return true;
return false;
case SizedApparelBodyPartOf.Vagina:
if (source == SizedApparelBodyPartOf.Vagina)
return true;
return false;
case SizedApparelBodyPartOf.Anus:
if (source == SizedApparelBodyPartOf.Anus)
return true;
return false;
case SizedApparelBodyPartOf.Belly:
if (source == SizedApparelBodyPartOf.Belly)
return true;
return false;
case SizedApparelBodyPartOf.Udder:
if (source == SizedApparelBodyPartOf.Udder)
return true;
return false;
case SizedApparelBodyPartOf.Hips:
if (source == SizedApparelBodyPartOf.Hips || source == SizedApparelBodyPartOf.Thighs || source == SizedApparelBodyPartOf.Penis || source == SizedApparelBodyPartOf.Vagina || source == SizedApparelBodyPartOf.Anus)
return true;
return false;
case SizedApparelBodyPartOf.Thighs:
if (source == SizedApparelBodyPartOf.Thighs)
return true;
return false;
case SizedApparelBodyPartOf.hands:
if (source == SizedApparelBodyPartOf.hands)
return true;
return false;
case SizedApparelBodyPartOf.feet:
if (source == SizedApparelBodyPartOf.feet)
return true;
return false;
case SizedApparelBodyPartOf.None:
return false;
return false;
}
Log.Error("[SizedApparel] missing SizedApparelBodyPartOf!");
return false;
}
}
public class GraphicPointsDef : Def
{
public List<TextureWithGraphicPoints> points;
}
public class TextureWithGraphicPoints
{
public string texturePath; // texture is already classified with bodytype
public List<GraphicPoint> points = new List<GraphicPoint>();
}
public class GraphicPoint
{
public string pointName;
public Vector2 point = new Vector2(0.5f, 0.5f);
}
public class GraphicPointsWithBodyType
{
public string pointName;
public List<PointWithBodyType> points = new List<PointWithBodyType>();
}
public class PointWithBodyType
{
public string bodyTypeName; //null can be used too
public Vector2 point = new Vector2(0.5f,0.5f);
}
public struct BodyPartPoint
{
string name;
Vector2 position;//Uv position. not pixel
}
[Obsolete]//todo
public struct BodyPartSpline
{
}
public enum ColorMode
{
Skin, Hair
}
//Def for Hediff Graphic color options or else.
public class SizedApparelHeddifDef : Def
{
public HediffDef hediffDef;
//public string hediffDefName;
}
//Def per graphic(texture)
public class SizedApparelBodyPartGraphicDef : Def
{
public string graphicPath;
public int severityIndex;
public Vector2 pivot = new Vector2(0.5f, 0.5f); // custom pivot of texture. UV. not pixel
//public Dictionary<string, BodyPartPoint> points = new Dictionary<string, BodyPartPoint>();
//public Dictionary<string, BodyPartSpline> splines = new Dictionary<string, BodyPartSpline>();
}
//Def per BodyParts
public class SizedApparelBodyPartDef : Def
{
SizedApparelBodyPartOf bodyPartOf = SizedApparelBodyPartOf.None;
public bool canPose = false;
public bool canAnimate = false;
}
public class SizedApparelBodyPart
{
static MethodInfo overrideMatMethod = AccessTools.Method(typeof(PawnRenderer), "OverrideMaterialIfNeeded");
public SizedApparelBodyPart(Pawn pawn, string bodyPartName, SizedApparelBodyPartOf bodyPartOf, string defaultHediffName, bool isBreast, bool isOverlay , string customPathName = null, SizedApparelBodyPartColorOf colorOf = SizedApparelBodyPartColorOf.Skin)
{
this.pawn = pawn; //owner
this.bodyPartName = bodyPartName;
this.def = DefDatabase<SizedApparelBodyPartDef>.AllDefs.FirstOrDefault(b => b.defName == bodyPartName);
this.bodyPartOf = bodyPartOf;
this.defaultHediffName = defaultHediffName;
this.isBreast = isBreast;
this.isOverlay = isOverlay;
this.customPath = customPathName;
this.colorType = colorOf;
}
public Vector2 OffsetFromUVOffset(Vector2 vector, Mesh mesh , bool isFliped = false)
{
//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(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)
public SizedApparelBodyPartDef def;
public Pawn pawn;
public string bodyPartName; //breast, penis, belly, pubichair... etc. just name. not like architech something
public string customPath = null;
public SizedApparelBodyPartOf bodyPartOf = SizedApparelBodyPartOf.None;
public string defaultHediffName;
public bool isBreast = false;
public bool isOverlay = false; //write z cache?
public string currentHediffName;
public bool isVisible = true;
public SizedApparelBodyPartColorOf colorType = SizedApparelBodyPartColorOf.Skin;
public Color? customColorOne;
public Color? customColorTwo;
//customize
public string customPose = null;
public Vector2? lookAnLocation = null;
public Rot4? rotOverride = null;
//variation
public string variation = null;
public Color? variationColor;
public colorOverrideMode variationColorMode = colorOverrideMode.Default;
//TODO. age setting?
public int minDrawAge = -1;
public int maxDrawAge = -1;
public void SetCustomPose(string newPose, bool autoUpdate = true, bool autoSetPawnGraphicDirty = false)
{
if (customPose == newPose)
return;
customPose = newPose;
if (autoUpdate)
this.UpdateGraphic();
if(autoSetPawnGraphicDirty)
{
if (pawn == null)
return;
PortraitsCache.SetDirty(pawn);
GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(pawn);
}
}
public bool CheckCanPose(string targetPose, bool checkApparels, bool mustMatchSize)
{
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;
*/
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;
}
}
Graphic graphic = GetBodyPartGraphics(false, mustMatchSize, targetPose);
Graphic graphicH = GetBodyPartGraphics(true, mustMatchSize, targetPose);
if (graphic != null || graphicH != null)
return true;
return false;
}
//TODO...
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 position = Vector2.zero;//offset from pivot //UV. not pixel
public Dictionary<string, BodyPartPoint> points;
public Dictionary<string, BodyPartPoint> pointsHorny;
public float rotation = 0; // +: rotate right, -: rotate left
public Vector2 scale = Vector2.one;
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;
public Vector2 positionOffsetEast = Vector2.zero;
public Vector2 positionOffsetWest = Vector2.zero;
public float depthOffset = 0f;
public float depthOffsetEast = 0.008f;
public float depthOffsetWest = 0.008f;
public float depthOffsetSouth = 0.008f;
public float depthOffsetNorth = 0.008f;
//bigger = in front
public void SetDepthOffsets(float south, float north, float east, float west)
{
depthOffsetSouth = south;
depthOffsetNorth = north;
depthOffsetEast = east;
depthOffsetWest = west;
}
public void SetPositionOffsets(Vector2 south, Vector2 north, Vector2 east, Vector2 west)
{
positionOffsetSouth = south;
positionOffsetNorth = north;
positionOffsetEast = east;
positionOffsetWest = west;
}
public Graphic GetBodyPartGraphics(bool isHorny, bool mustMatchSize = false, string poseOverride = null)
{
Dictionary<string, BodyPartPoint> 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)
{
if (pawn == null)
{
outPoints = null;
return null;
}
var comp = pawn.TryGetComp<ApparelRecorderComp>();
if (comp == null)
{
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);
var result = SizedApparelsDatabase.GetSupportedBodyPartPath(key, isBreast, customPath == null ? bodyPartName : customPath, defaultHediffName);
if (mustMatchSize)
if (Math.Min(currentSeverityInt, cappedSeverityInt) != result.size)
{
outPoints = null;
return null;
}
if (result.pathWithSizeIndex == null)
{
outPoints = null;
return null;
}
outPoints = result.points;
return GraphicDatabase.Get<Graphic_Multi>(result.pathWithSizeIndex);
}
public void UpdateGraphic()
{
bodyPartGraphic = GetBodyPartGraphics(false, out points, false);
bodyPartGraphicHorny = GetBodyPartGraphics(true, out pointsHorny, false);
}
public void UpdateGraphic(int index, int indexCapped = 1000)
{
this.currentSeverityInt = index;
this.cappedSeverityInt = indexCapped;
UpdateGraphic();
}
public void ResetTransform()
{
this.position = Vector2.zero;
this.scale = Vector2.one;
this.rotation = 0;
}
public void ClearGraphics()
{
this.bodyPartGraphic = null;
this.bodyPartGraphicHorny = null;
this.points = null;
this.pointsHorny = null;
}
public void Clear()
{
currentHediffName = null;
currentSeverityInt = -1;
cappedSeverityInt = 1000;
customPose = null;
rotOverride = null;
ClearGraphics();
}
/*
public void SetHediffData(string name, int severityIndex , string variation = null)
{
currentHediffName = name;
currentSeverityInt = severityIndex;
}*/
public void SetHediffData(string name, int severityIndex, int cappedSeverityIndex = 1000, string variation = null)
{
currentHediffName = name;
currentSeverityInt = severityIndex;
this.cappedSeverityInt = cappedSeverityIndex;
this.variation = variation;
}
public void DrawBodyPart (Vector3 rootLoc, float angle, Rot4 facing, RotDrawMode bodyDrawType, PawnRenderFlags flags, Mesh bodyMesh)
{
if (!isVisible)
return;
if (scale == Vector2.zero)
return; //Don't draw if scale is zero
if (pawn == null)
return;
PawnRenderer pawnRenderer = pawn.Drawer.renderer;
Shader shader = ShaderDatabase.CutoutComplex;
Color drawColor1 = Color.white;
Color drawColor2 = Color.white;
bool forceWriteZ = true;
if(colorType == SizedApparelBodyPartColorOf.Skin)
{
forceWriteZ = true;
if (bodyDrawType == RotDrawMode.Fresh)
{
shader = pawn.Drawer.renderer.graphics.nakedGraphic.Shader;
if (!ShaderUtility.SupportsMaskTex(shader))
shader = ShaderDatabase.CutoutSkinOverlay;
drawColor1 = pawn.Drawer.renderer.graphics.nakedGraphic.Color;
drawColor2 = pawn.Drawer.renderer.graphics.nakedGraphic.ColorTwo;
}
else if (bodyDrawType == RotDrawMode.Rotting)
{
shader = pawn.Drawer.renderer.graphics.rottingGraphic.Shader;
if (!ShaderUtility.SupportsMaskTex(shader))
shader = ShaderDatabase.CutoutSkinOverlay;
drawColor1 = pawn.Drawer.renderer.graphics.rottingGraphic.Color;
drawColor2 = pawn.Drawer.renderer.graphics.nakedGraphic.ColorTwo;
}
}
else if (colorType == SizedApparelBodyPartColorOf.Hair)
{
forceWriteZ = false;
shader = ShaderDatabase.Transparent;
if(pawn.story != null)
drawColor1 = pawn.story.hairColor;
}
else if (colorType == SizedApparelBodyPartColorOf.Custom)
{
forceWriteZ = true;
shader = ShaderDatabase.Transparent;
if(customColorOne != null)
drawColor1 = customColorOne.Value;
if (customColorTwo != null)
drawColor2 = customColorTwo.Value;
}
else if (colorType == SizedApparelBodyPartColorOf.None)
{
forceWriteZ = false;
shader = ShaderDatabase.Cutout;
}
Quaternion quaternion = Quaternion.AngleAxis(angle + rotation, Vector3.up);
Vector3 vector = rootLoc;
Rot4 targetRot = facing;
if (rotOverride != null)
targetRot = rotOverride.Value;
if (targetRot == Rot4.South)
{
var loc = OffsetFromUVOffset(positionOffsetSouth, bodyMesh);
vector.x += loc.x;
vector.z += loc.y;
vector.y += depthOffsetSouth;
}
else if(targetRot == Rot4.North)
{
var loc = OffsetFromUVOffset(positionOffsetNorth, bodyMesh);
vector.x += loc.x;
vector.z += loc.y;
vector.y += depthOffsetNorth;
}
else if (targetRot == Rot4.East)
{
var loc = OffsetFromUVOffset(positionOffsetEast, bodyMesh);
vector.x += loc.x;
vector.z += loc.y;
vector.y += depthOffsetEast;
}
else if (targetRot == Rot4.West)
{
var loc = OffsetFromUVOffset(positionOffsetWest, bodyMesh);
vector.x += loc.x;
vector.z += loc.y;
vector.y += depthOffsetWest;
}
Graphic graphic = null;
if (SizedApparelUtility.IsHorny(pawn))
graphic = bodyPartGraphicHorny;
if (graphic == null)
graphic = bodyPartGraphic;
if (graphic == null)
return;
Material mat;
if (!flags.FlagSet(PawnRenderFlags.Cache)&&!isOverlay&& forceWriteZ)
{
graphic = graphic.GetColoredVersion(ShaderDatabase.Cutout, drawColor1, drawColor2);
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
}
graphic = graphic.GetColoredVersion(shader, drawColor1, drawColor2);
vector.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));
}
}
//TODO: Torso Pose?
public class SizedApparelBodyDef : Def
{
//public List<SizedApparelBodyPartDef> BodyParts;
//defName = raceName ?? could it work?
public List<BodyPart> bodyParts;
/*
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 class SizedApparelBody
{
public string customPoseOfBody = null;
public bool canCustomPose()
{
//check apparels
return false;
}
}
}

View File

@ -0,0 +1,272 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using rjw;
using HarmonyLib;
using UnityEngine;
using RimWorld;
using Verse;
namespace SizedApparel
{
public enum colorOverrideMode
{
Default, Multiply, Add
}
public class BodyPartVariationWithRace
{
public string hediffName;
public List<string>varName = new List<string>();
}
public class SizedApparelBodyPartVariationDef : Def
{
public string bodyPartName;
public List<BodyPartVariationWithRace>variations = new List<BodyPartVariationWithRace>();
}
public class SizedApparelBodyPartDetail : HediffComp
{
public string variation = null; // null to default
public string bodyPartName;
public SizedApparelBodyPartVariationDef variationDef;
public Color? colorOverride = null;//TODO
public colorOverrideMode colorMode = colorOverrideMode.Default;//TODO
public override string CompTipStringExtra => "Variation: " + (variation == null ? "Default" : variation) + " (sized apparel)";
public override void CompExposeData()
{
Scribe_Values.Look<string>(ref this.variation, "variation", null, false);
//Scribe_Values.Look<Color?>(ref this.colorOverride, "colorOverride",null, false);
//Scribe_Values.Look<colorOverrideMode>(ref this.colorMode, "colorMode", colorOverrideMode.Default, false);
}
public override void CompPostMake()
{
base.CompPostMake();
if (SizedApparelUtility.isBreast(parent.def.defName))
bodyPartName = "Breasts";
else if (Genital_Helper.is_vagina(parent)) // SizedApparelUtility.isVagina(parent.def.defName)
bodyPartName = "Vagina";
else if (SizedApparelUtility.isAnus(parent.def.defName))
bodyPartName = "Anus";
else if (SizedApparelUtility.isUdder(parent.def.defName))
bodyPartName = "Udder";
else if (Genital_Helper.is_penis(parent)) //SizedApparelUtility.isPenis(parent.def.defName)
bodyPartName = "Penis";
else
bodyPartName = parent.def.defName;
if (Pawn == null)
return;
if (DefDatabase<SizedApparelBodyPartVariationDef>.DefCount == 0)
{
Log.Warning("[Sized Apparel] Cannot Find Any BodyPart Variation Def. It can be version issue or other mod's patch issue.");
variation = null;
return;
}
try
{
variationDef = DefDatabase<SizedApparelBodyPartVariationDef>.AllDefs?.FirstOrDefault(b => b.bodyPartName == bodyPartName);
}
catch(ArgumentNullException e)
{
Log.Warning("[Sized Apparel] Cannot Find Any BodyPart Variation Def of ( " + bodyPartName + " )!. It can be version issue or other mod's patch issue.");
variation = null;
return;
}
if (variationDef == null)
return;
if (variationDef.variations == null)
return;
var variations = variationDef.variations?.FirstOrDefault(v => v.hediffName == parent.def.defName);
if (variations == null)
variations = variationDef.variations?.FirstOrDefault(v => v.hediffName == bodyPartName);
if (variations == null)
return;
if (variations.varName.NullOrEmpty())
return;
this.variation = variations.varName.RandomElement();
if (variation.ToLower() == "null" || variation.ToLower() == "default")
{
variation = null;
}
}
}
public class SizedApparelBodyPartDetailProperties : HediffCompProperties
{
public string bodyPartName;
public SizedApparelBodyPartDetailProperties()
{
this.compClass = typeof(SizedApparelBodyPartDetail);
}
}
public class SizedApparelBodyPartDetailGizmo : Command
{
}
public class SizedApparelBodyPartDetailThing : ThingComp
{
public string variation = null; // null to default
public string bodyPartName;
public SizedApparelBodyPartVariationDef variationDef;
public Color? colorOverride = null;//TODO
public colorOverrideMode colorMode = colorOverrideMode.Default;//TODO
public override string GetDescriptionPart()
{
if(SizedApparelSettings.showBodyPartsVariation)
return "Variation: " +( variation == null?"Default":variation) + " (sized apparel)";
return string.Empty;
}
/*
public override string TransformLabel(string label)
{
return label + "Variation: " + variation == null ? "Default" : variation + " (sized apparel)";
}
*/
public override void PostExposeData()
{
Scribe_Values.Look<string>(ref this.variation, "variation", null, false);
//Scribe_Values.Look<Color?>(ref this.colorOverride, "colorOverride",null, false);
//Scribe_Values.Look<colorOverrideMode>(ref this.colorMode, "colorMode", colorOverrideMode.Default, false);
}
public void InitComp(Pawn pawn = null)
{
HediffDef named = DefDatabase<HediffDef>.GetNamed(this.parent.def.defName, true);
List<Pawn> allMaps_FreeColonistsAndPrisonersSpawned = PawnsFinder.AllMaps_FreeColonistsAndPrisonersSpawned;
pawn = ((allMaps_FreeColonistsAndPrisonersSpawned != null) ? allMaps_FreeColonistsAndPrisonersSpawned.RandomElement<Pawn>() : null);
if (pawn == null)
{
List<Pawn> all_AliveOrDead = PawnsFinder.All_AliveOrDead;
pawn = ((all_AliveOrDead != null) ? all_AliveOrDead.RandomElement<Pawn>() : null);
}
SizedApparelBodyPartDetail compHediffBodyPart = HediffMaker.MakeHediff(named, pawn, null).TryGetComp<SizedApparelBodyPartDetail>();
if (compHediffBodyPart != null)
{
//compHediffBodyPart.initComp(pawn, false);
//compHediffBodyPart.updatesize(0f);
this.variation = compHediffBodyPart.variation;
}
}
public override void PostPostMake()
{
base.PostPostMake();
if (SizedApparelUtility.isBreast(parent.def.defName))
bodyPartName = "Breasts";
else if (SizedApparelUtility.isVagina(parent.def.defName))
bodyPartName = "Vagina";
else if (SizedApparelUtility.isAnus(parent.def.defName))
bodyPartName = "Anus";
else if (SizedApparelUtility.isUdder(parent.def.defName))
bodyPartName = "Udder";
else if (SizedApparelUtility.isPenis(parent.def.defName))
bodyPartName = "Penis";
else
bodyPartName = parent.def.defName;
variationDef = DefDatabase<SizedApparelBodyPartVariationDef>.AllDefs?.FirstOrDefault(b => b.bodyPartName == bodyPartName);
if (variationDef == null)
return;
if (variationDef.variations == null)
return;
var variations = variationDef.variations?.FirstOrDefault(v => v.hediffName == parent.def.defName);
if (variations == null)
variations = variationDef.variations?.FirstOrDefault(v => v.hediffName == bodyPartName);
if (variations == null)
return;
if (variations.varName.NullOrEmpty())
return;
this.variation = variations.varName.RandomElement();
if (variation.ToLower() == "null" || variation.ToLower() == "default")
{
variation = null;
}
}
}
public class SizedApparelBodyPartDetailThingProperties : CompProperties
{
public string bodyPartName;
public SizedApparelBodyPartDetailThingProperties()
{
this.compClass = typeof(SizedApparelBodyPartDetailThing);
}
}
[HarmonyPatch(typeof(SexPartAdder), "recipePartAdder")]
public class recipePartAdderPatch
{
public static void Postfix(RecipeDef recipe, Pawn pawn, BodyPartRecord part, List<Thing> ingredients, Hediff __result)
{
if (__result == null)
return;
Thing thing = ingredients.FirstOrDefault(x => x.def.defName == recipe.addsHediff.defName);
if (thing == null)
return;
SizedApparelBodyPartDetailThing CompThing = thing.TryGetComp<SizedApparelBodyPartDetailThing>();
SizedApparelBodyPartDetail CompHediff = __result.TryGetComp<SizedApparelBodyPartDetail>();
CompHediff.variation = CompThing.variation;
}
}
[HarmonyPatch(typeof(SexPartAdder), "recipePartRemover")]
public class recipePartRemoverPatch
{
public static void Postfix(Hediff hd, ref Thing __result)
{
//Thanks! "Stardust" helped
try
{
SizedApparelBodyPartDetailThing CompThing = __result.TryGetComp<SizedApparelBodyPartDetailThing>();
SizedApparelBodyPartDetail CompHediff = hd.TryGetComp<SizedApparelBodyPartDetail>();
CompThing.variation = CompHediff.variation;
}
catch (NullReferenceException e)
{
Log.Error(e.StackTrace);
}
}
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SizedApparel
{
//editing offset for alien race? such as penis, anus offsets, except breast.(breasts position must be matched with apparels.)
class SizedApparelBodyPartEditor
{
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RimWorld;
using Verse;
using HarmonyLib;
namespace SizedApparel
{
public static class SizedApparelDubsApparelPatch
{
public static void indoorPostFixPatch(Pawn pawn)
{
PawnGraphicSet graphicSet = pawn.Drawer?.renderer?.graphics;
if (graphicSet == null)
return;
var comp = pawn.TryGetComp<ApparelRecorderComp>();
if (comp == null)
return;
comp.needToCheckApparelGraphicRecords = true;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,84 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Verse;
using RimWorld;
using HarmonyLib;
using UnityEngine;
namespace SizedApparel
{
/*
[HarmonyPatch(typeof(PawnRenderer), "BaseHeadOffsetAt")]
[HarmonyAfter(new string[]
{
"rimworld.erdelf.alien_race.main"
})]
*/
//TODO
public static class PawnRenderer_BaseHeadOffsetAt_Patch_For_Pose
{
[HarmonyPostfix]
public static void BaseHeadOffsetAtPostfix_Post(PawnRenderer __instance, Rot4 rotation, ref Vector3 __result, ref Pawn ___pawn)
{
return;
/*
var comp = ___pawn.TryGetComp<ApparelRecorderComp>();
if (comp == null)
return;
if (comp.customPose == null)
return;
SizedApparelPoseDef poseDef = DefDatabase<SizedApparelPoseDef>.GetNamed(comp.customPose);
if (poseDef == null)
return;
Rot4Offsets? headOffset = new Rot4Offsets();
string bodyType = ___pawn.story?.bodyType?.defName;
if (bodyType == null)
{
bodyType = "default";
headOffset = poseDef.headOffset.FirstOrDefault(b => b.bodyType.ToLower() == "default" | b.bodyType.ToLower() == "null").offsets;
}
else
{
headOffset = poseDef.headOffset.FirstOrDefault(b => b.bodyType.ToLower() == bodyType.ToLower()).offsets;
}
if (headOffset == null)
return;
*/
//headOffset.
//TODO: Mesh Based Scaled Offset
//__result = __result + headOffset;
return;
}
}
public class SizedApparelPoseSetDef : Def
{
public List<SizedApparelPose> poses;
}
public class SizedApparelPose
{
//public string poseName; use defName as PoseName
public SizedApparelBodyPartOf targetBodyPart = SizedApparelBodyPartOf.Torso;
public List<BodyTypeAndOffset> headOffset;
}
}

View File

@ -0,0 +1,34 @@
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 rjw;
namespace SizedApparel
{
[HarmonyPatch(typeof(PawnGraphicSet), "CalculateHairMats")]
public static class CalculateHairMatsPatch
{
}
public abstract class PubicHairDef : StyleItemDef
{
}
class SizedApparelPubicHair
{
}
public static class IdeoStyleTackerPatch
{
}
}

View File

@ -0,0 +1,240 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RimWorld;
using Verse;
using HarmonyLib;
using UnityEngine;
using rjw;
namespace SizedApparel
{
//sexualize_pawn patch
class SexualizePawnPatch
{
static void Postfix(Pawn pawn)
{
if (!UnityData.IsInMainThread)
return;
ApparelRecorderComp comp = pawn?.TryGetComp<ApparelRecorderComp>();
if (comp == null)
return;
comp.SetDirty();
/*
comp.ClearAll();
var graphicSet = pawn.Drawer?.renderer?.graphics;
if (graphicSet != null)
{
pawn.Drawer.renderer.graphics.ResolveAllGraphics();
//pawn.Drawer.renderer.graphics.ResolveApparelGraphics();
BodyPatch.SetBodyGraphic(pawn);
}*/
/*
float breastSeverity = comp.breastSeverity;
Hediff breastHediff = comp.breastHediff;
SizedApparelUtility.GetBreastSeverity(pawn, out breastSeverity, out breastHediff);
SizedApparelUtility.hasUnSupportedApparelFromWornData(pawn, breastSeverity, breastHediff, true);
comp.hasUpdateBefore = true;*/
}
}
//since Sized Apparel Logic Changed, it doesn't need to do job patch for rjw.
[Obsolete]
[StaticConstructorOnStartup]
//[HarmonyPatch(typeof(SexUtility), "DrawNude")]
class DrawNudePatch
{
static void Prefix(Pawn pawn, bool keep_hat_on)
{
if (!UnityData.IsInMainThread)
return;
//Log.Message("Hello");
if (RJWPreferenceSettings.sex_wear == RJWPreferenceSettings.Clothing.Clothed)
{
}
else
{
//SetBodyGraphic(pawn.Drawer.renderer.graphics, false);
}
}
static void OldPostfix(Pawn pawn)
{
if (pawn == null)
return;
//GetBreastSeverity(__instance.pawn, out breastSeverity, out breastHediff);
//bool flag = hasUnSupportedApparel(__instance.pawn, breastSeverity, breastHediff);
ApparelRecorderComp comp = pawn.TryGetComp<ApparelRecorderComp>();
if (comp != null)
{
/*
LongEventHandler.ExecuteWhenFinished(delegate
{
float breastSeverity;
Hediff breastHediff;
bool flag = false;
GetBreastSeverity(pawn, out breastSeverity, out breastHediff);
flag = hasUnSupportedApparel(pawn, breastSeverity, breastHediff);
if (!comp.hasUpdateBefore)
comp.SetHasUpdateBefore(true);
comp.SetHasUnsupportedApparel(flag);
}
);
*/
//Log.Message("CheckApparel");
if (!comp.hasUpdateBefore)
comp.hasUpdateBefore = true;
if (!comp.hasUpdateForSex)
{
comp.hasUpdateForSex = true;
float breastSeverity;
Hediff breastHediff;
bool flag = false;
SizedApparelUtility.GetBreastSeverity(pawn, out breastSeverity, out breastHediff);
//Log.Message("GetServerity");
//flag = SizedApparelUtility.hasUnSupportedApparel(pawn, breastSeverity, breastHediff);
flag = SizedApparelUtility.hasUnSupportedApparelFromWornData(pawn, breastSeverity, breastHediff);
comp.hasUnsupportedApparel = flag;
}
//Log.Message("SetFlag");
/*
//Log.Message(comp.testbool.ToString());
//Log.Message("ApparelChanged");
//comp.hasUnsupportedApparel = flag;
//comp.hasUpdateBefore = true;
//comp.SetHasUnsupportedApparel(flag);
//comp.SetHasUpdateBefore(true);
//if (__instance.pawn.Drawer.renderer.graphics != null)
LongEventHandler.ExecuteWhenFinished(delegate
{
SetBodyGraphic(__instance.pawn.Drawer.renderer.graphics, flag);
}
);
*/
}
}
public void todoPostfix(Pawn pawn)
{
if (pawn == null)
return;
ApparelRecorderComp comp = pawn.TryGetComp<ApparelRecorderComp>();
if (comp == null)
return;
comp.SetDirty();
}
}
[Obsolete]
[StaticConstructorOnStartup]
//[HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "Start")]
class SexStartPatch
{
static void Postfix(JobDriver_SexBaseInitiator __instance)
{
//Log.Warning("SexStart");
ApparelRecorderComp pawnARC = __instance.pawn.TryGetComp<ApparelRecorderComp>();
if (pawnARC != null)
{
if (__instance.pawn.RaceProps.Humanlike)
{
pawnARC.havingSex = true;
pawnARC.hasUpdateForSex = false;
__instance.pawn.Drawer.renderer.graphics.SetApparelGraphicsDirty();
}
}
if (__instance.Partner == null)
return;
var partner = __instance.Partner as Pawn;
if (partner == null)
return;
ApparelRecorderComp partnerARC = partner.TryGetComp<ApparelRecorderComp>();
if (partnerARC != null)
{
if (partner.RaceProps.Humanlike)
{
partnerARC.havingSex = true;
pawnARC.hasUpdateForSex = false;
partner.Drawer.renderer.graphics.SetApparelGraphicsDirty();
}
}
}
}
[Obsolete]
[StaticConstructorOnStartup]
//[HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "End")]
class SexEndPatch
{
static void Postfix(JobDriver_SexBaseInitiator __instance)
{
ApparelRecorderComp pawnARC = __instance.pawn.TryGetComp<ApparelRecorderComp>();
if (pawnARC != null)
{
pawnARC.havingSex = false;
pawnARC.hasUpdateForSex = false;
pawnARC.hasUpdateBefore = false;
float breastSeverity;
Hediff breastHediff;
bool flag = true;
if (__instance.pawn.RaceProps.Humanlike)
{
SizedApparelUtility.GetBreastSeverity(__instance.pawn, out breastSeverity, out breastHediff);
//Log.Message("GetServerity");
flag = SizedApparelUtility.hasUnSupportedApparelFromWornData(__instance.pawn, breastSeverity, breastHediff);
pawnARC.hasUnsupportedApparel = flag;
PortraitsCache.SetDirty(__instance.pawn);
__instance.pawn.Drawer.renderer.graphics.ResolveApparelGraphics();
}
pawnARC.hasUnsupportedApparel = flag;
}
if (__instance.Partner == null)
return;
var partner = __instance.Partner as Pawn;
if (partner == null)
return;
ApparelRecorderComp partnerARC = partner.TryGetComp<ApparelRecorderComp>();
if (partnerARC != null)
{
partnerARC.havingSex = false;
partnerARC.hasUpdateForSex = false;
partnerARC.hasUpdateBefore = false;
float breastSeverity;
Hediff breastHediff;
bool flag = true;
if (partner.RaceProps.Humanlike)
{
SizedApparelUtility.GetBreastSeverity(partner, out breastSeverity, out breastHediff);
//Log.Message("GetServerity");
flag = SizedApparelUtility.hasUnSupportedApparelFromWornData(partner, breastSeverity, breastHediff);
partnerARC.hasUnsupportedApparel = flag;
partner.Drawer.renderer.graphics.ResolveApparelGraphics();
PortraitsCache.SetDirty(partner);
}
partnerARC.hasUnsupportedApparel = flag;
}
}
}
}

View File

@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RimWorld;
using Verse;
using HarmonyLib;
//using AlienRace;
using UnityEngine;
using rjw;
namespace SizedApparel
{
//[HarmonyPatch(typeof(RimNudeWorld.GenitalPatch), "Postfix")]
[StaticConstructorOnStartup]
public class SizedApparelRNWPatch
{
static bool Prefix(Pawn pawn)
{
if (pawn == null)
return false;
return true;
}
}
public class RevealingApparelPatch
{
static void Postfix( Pawn pawn, ref bool __result)
{
if (__result == false)
return;
var comp = pawn.TryGetComp<ApparelRecorderComp>();
if (comp == null)
return;
if (comp.hasUnsupportedApparel)
return;
if(pawn.apparel.WornApparel != null)
{
if(pawn.apparel.WornApparel.Any((Apparel ap) =>( ap.def.apparel.tags.Any(s => s.ToLower() == "SizedApparel_IgnorBreastSize".ToLower()))))
__result = false;
}
return;
}
}
}

View File

@ -0,0 +1,743 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity;
using UnityEngine;
using Verse;
namespace SizedApparel
{
//include Human, set humanlike's custom setting
//Only few settings are allow in ModSetting. other needs to be set in Def (xml) file
public class AlienRaceSetting : IExposable
{
public string raceName = null;
public bool overrideDef = false;
public bool asHumanlike = true;
public float drawMinAge = -1; //pawn's Biological age. -1 to ignore.
public AlienRaceSetting(string raceName)
{
this.raceName = raceName;
}
public AlienRaceSetting()
{
}
public void ExposeData()
{
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 drawMinAge, "drawMinAge", -1);
}
//public int ageYoung = -1; //use receDefName_young folder. -1 to ignore
//public int ageOld = -1; //use raceDefName_old folder. -1 to ignore.
}
public class SizedApparelSettings : ModSettings
{
public static bool Debug = false;
public static bool DetailLog = false;
public static bool autoClearCacheOnWriteSetting = true;
public static bool useBodyTexture = true;//for user who not use rimnudeworld
public static bool useGenderSpecificTexture = true;
public static bool matchBodyTextureToMinimumApparelSize = true;//for avoiding breasts cliping
public static bool useBreastSizeCapForApparels = true;
public static bool DontReplaceBodyTextureOnNude = true;
//public static bool DontReplaceBodyTextureOnUnsupported = true;
//TODO: Standalone render bodyparts.
public static bool drawBodyParts = true;//for user who not use rimnudeworld
public static bool drawBreasts = true;
public static bool drawPenis = true;
public static bool drawVagina = true;
public static bool drawMuscleOverlay = true;
public static bool drawHips = true;//TODO
public static bool drawAnus = true;
public static bool drawBelly = false;//TODO
public static bool drawUdder = false;//TODO
public static bool hideBallOfFuta = false;
public static bool hidePenisOfMale = false;
public static bool matchBreastToSupportedApparelSize = true;//for avoiding breasts cliping
public static bool useBodyPartsVariation = true;
public static bool showBodyPartsVariation = true;
public static bool autoJiggleBreasts = true;
//RimNudeWorld
public static bool drawSizedApparelBreastsOnlyWorn = false;
public static bool hideRimNudeWorldBreasts = false;//disable rimnudeworld breasts.
[Obsolete]
public static bool useUnsupportedBodyTexture = true;//bodytexture when wearing unsupported apparel.
public static bool useSafeJobBreasts = true;
public static bool changeBodyType;
public static bool fatToFemale;
public static bool hulkToThin;
public static bool onlyForFemale = true;
public static bool useRandomSize = true;//for user who play without rimjobworld
public static float randomSizeMin = 0.01f;
public static float randomSizeMax = 1.01f;
//Lagacy Variable
public static bool useTitanic = true;
public static bool useColossal = true;
public static bool useGargantuan = true;
public static bool useMassive = true;
public static bool useEnormous = true;
public static bool useHuge = true;
public static bool useLarge = true;
public static bool useAverage = true;
public static bool useSmall = true;
public static bool useTiny = true;
public static bool useNipples = true;
//Alien Race Settings
[Obsolete]
public static bool UnsupportedRaceToUseHumanlike = false;
public static List<string> alienRaces = new List<string>();
public static List<string> alienRacesAllowHumanlikTextures = new List<string>(); //This Value Will be Saved and loaded
public static string alienRaceSearch = "";
public static Vector2 alienRacesListScrollPos;
public static List<AlienRaceSetting> alienRaceSettings = new List<AlienRaceSetting>();
//Force All Apparel as supported
public static bool ForcedSupportApparel = false;
public static bool getUseSettingFromIndex(int target)
{
if (target < 0)
return false;
else if (target == 0)
return useNipples;
else if (target == 1)
return useTiny;
else if (target == 2)
return useSmall;
else if (target == 3)
return useAverage;
else if (target == 4)
return useLarge;
else if (target == 5)
return useHuge;
else if (target == 6)
return useEnormous;
else if (target == 7)
return useMassive;
else if (target == 8)
return useGargantuan;
else if (target == 9)
return useColossal;
else if (target == 10)
return useTitanic;
else
return false;
}
public static bool useUnderBreasts = true;
public static float UnderBreastsOffset = -0.0013f;
public override void ExposeData()
{
Scribe_Values.Look(ref Debug, "Debug", false);
Scribe_Values.Look(ref DetailLog, "DetailLog", false);
Scribe_Values.Look(ref autoClearCacheOnWriteSetting, "autoClearCacheOnWriteSetting", true);
//force to use it. this is important thing.
//Scribe_Values.Look(ref useBreastSizeCapForApparels, "useBreastSizeCapForApparels", true);
Scribe_Values.Look(ref useBodyTexture, "useBodyTexture", true);
Scribe_Values.Look(ref useGenderSpecificTexture, "useGenderSpecificTexture", true);
Scribe_Values.Look(ref matchBodyTextureToMinimumApparelSize, "matchBodyTextureToMinimumApparelSize", true);
Scribe_Values.Look(ref matchBreastToSupportedApparelSize, "matchBreastToSupportedApparelSize", true);
//Unsurpported to forced Surpported
//Scribe_Values.Look(ref UnsupportedRaceToUseHumanlike, "UnsupportedRaceToUseHumanlike", false);
Scribe_Values.Look(ref ForcedSupportApparel, "ForcedSupportApparel", false);
Scribe_Collections.Look<AlienRaceSetting>(ref alienRaceSettings, "alienSettings", LookMode.Deep);
if (Scribe.mode == LoadSaveMode.LoadingVars)
{
if (alienRaceSettings == null)
{
alienRaceSettings = new List<AlienRaceSetting>();
}
}
if (Scribe.mode == LoadSaveMode.ResolvingCrossRefs)
{
if(!alienRaceSettings.NullOrEmpty())
alienRaceSettings.RemoveAll((AlienRaceSetting x) => string.IsNullOrEmpty(x.raceName));
}
Scribe_Values.Look(ref useUnsupportedBodyTexture, "useUnsupportedBodyTexture", true);
Scribe_Values.Look(ref DontReplaceBodyTextureOnNude, "DontReplaceBodyTextureOnNude", false);
Scribe_Values.Look(ref hideRimNudeWorldBreasts, "hideRimNudeWorldBreasts", false);
Scribe_Values.Look(ref useSafeJobBreasts, "useSafeJobBreasts", true);
Scribe_Values.Look(ref useRandomSize, "useRandomSize", true);
Scribe_Values.Look(ref randomSizeMin, "randomSizeMin", 0.01f);
Scribe_Values.Look(ref randomSizeMax, "randomSizeMax", 1.01f);
Scribe_Values.Look(ref drawBodyParts, "drawBodyParts", true);
Scribe_Values.Look(ref useBodyPartsVariation, "useBodyPartsVariation", true); // forse true for now. TODO
Scribe_Values.Look(ref showBodyPartsVariation, "showBodyPartsVariation", true);
Scribe_Values.Look(ref drawMuscleOverlay, "drawMuscleOverlay", true);
Scribe_Values.Look(ref drawBreasts, "drawBreasts", true);
Scribe_Values.Look(ref drawSizedApparelBreastsOnlyWorn, "drawSizedApparelBreastsOnlyWorn", false);
Scribe_Values.Look(ref drawPenis, "drawPenis", true);
Scribe_Values.Look(ref drawVagina, "drawVagina", true);
Scribe_Values.Look(ref drawAnus, "drawAnus", true);
Scribe_Values.Look(ref drawUdder, "drawUdder", true);
Scribe_Values.Look(ref drawBelly, "drawBelly", true);
//force to draw all size type
/*
Scribe_Values.Look(ref useTitanic, "useTitanic", true);
Scribe_Values.Look(ref useColossal, "useColossal", true);
Scribe_Values.Look(ref useGargantuan, "useGargantuan", true);
Scribe_Values.Look(ref useMassive, "useMassive", true);
Scribe_Values.Look(ref useEnormous, "useEnormous", true);
Scribe_Values.Look(ref useHuge, "useHuge", true);
Scribe_Values.Look(ref useLarge, "useLarge", true);
Scribe_Values.Look(ref useAverage, "useAverage", true);
Scribe_Values.Look(ref useSmall, "useSmall", true);
Scribe_Values.Look(ref useTiny, "useTiny", true);
Scribe_Values.Look(ref useNipples, "useNipples", true);
*/
Scribe_Values.Look(ref useUnderBreasts, "useUnderBreasts",true);
Scribe_Values.Look(ref UnderBreastsOffset, "UnderBreastsOffset", -0.0013f);
//TODO: Humanlike Setting Per Race
//Scribe_Values.Look(ref alienRacesAllowHumanlikTextures, "alienRacesAllowHumanlikTextures");
base.ExposeData();
}
}
public class SizedApparelMod : Mod
{
SizedApparelSettings settings;
private static Vector2 ScrollPos = Vector2.zero;
private static List<string> alienDefList = new List<string>(); // to load aliens and compare with modsetting
public override void WriteSettings()
{
base.WriteSettings();
if(SizedApparelSettings.autoClearCacheOnWriteSetting)
ClearCache();
}
public static void CheckAndLoadAlienRaces()
{
if(alienDefList == null)
alienDefList = new List<string>();
if (alienDefList.Count == 0)
{
IEnumerable<ThingDef> HumanlikeRaces;
HumanlikeRaces = DefDatabase<ThingDef>.AllDefs.Where(b => b.race?.Humanlike == true);
foreach (ThingDef raceDef in HumanlikeRaces)
{
//Default Value Is True
alienDefList.Add(raceDef.defName);
}
}
}
public static void ClearCache(bool clearPawnGraphicSet = true)
{
SizedApparelsDatabase.ClearAll();
if (Find.CurrentMap != null)
{
foreach (Pawn pawn in Find.CurrentMap.mapPawns.AllPawns)
{
if (pawn == null)
continue;
var comp = pawn.TryGetComp<ApparelRecorderComp>();
if (comp != null)
comp.SetDirty(clearPawnGraphicSet);
}
}
}
public SizedApparelMod(ModContentPack content) : base(content)
{
this.settings = GetSettings<SizedApparelSettings>();
}
public override void DoSettingsWindowContents(Rect inRect)
{
const float alienRaceSettingHeight = 120;
CheckAndLoadAlienRaces();
Listing_Standard listingStandard = new Listing_Standard();
//Rect rect = new Rect(0f, 0f, inRect.width, 950);
//Rect rect = inRect.ExpandedBy(0.9f);
Rect leftRect = new Rect(inRect.position, new Vector2(inRect.width / 2, inRect.height));
Rect rightRect = new Rect(inRect.position + new Vector2(inRect.width / 2,0), new Vector2(inRect.width / 2, inRect.height));
//rect.xMax *= 0.9f;
//leftRect = leftRect.ContractedBy(10f);
rightRect = rightRect.ContractedBy(10f);
Rect scrollRect = new Rect(0, 0, leftRect.width - 30f, Math.Max(leftRect.height + (float)alienDefList.Count* alienRaceSettingHeight, 1f));
Widgets.BeginScrollView(leftRect, ref ScrollPos, scrollRect, true);
leftRect = new Rect(leftRect.x, leftRect.x, leftRect.width - 30f, leftRect.height + Math.Max((float)alienDefList.Count * alienRaceSettingHeight, 1f));
listingStandard.Begin(leftRect);
listingStandard.maxOneColumn = true;
listingStandard.CheckboxLabeled("Debug Log", ref SizedApparelSettings.Debug, "Debug logs.\nDefault: false");
if (SizedApparelSettings.Debug)
{
listingStandard.CheckboxLabeled("Debug Log (Detail)", ref SizedApparelSettings.DetailLog, "Debug logs for checking missing textures.\nDefault: false");
}
listingStandard.GapLine(1f);
listingStandard.CheckboxLabeled("Auto Clear Cache On Close Setting", ref SizedApparelSettings.autoClearCacheOnWriteSetting, "Auto clear cache data to apply Setting.\nDefault: true");
if(SizedApparelSettings.autoClearCacheOnWriteSetting == false)
{
listingStandard.Label("If you changed options, try Clear Cache to apply. Some options may need to restart");
if (listingStandard.ButtonTextLabeled("Clear Cache", "Press If you changed Option."))//\n do not push unless you really need. \n if this button still not work. reload savefile. if still not work, reload rimworld"
{
ClearCache();
}
}
listingStandard.Gap();
listingStandard.Gap(8);
listingStandard.GapLine(5f);
/*
listingStandard.Label("Optimization",-1,"");
//listingStandard.CheckboxLabeled("Debug Log", ref SizedApparelSettings.Debug, "Debug logs.\nDefault: false");
listingStandard.Gap(8);
listingStandard.Label("no more optimization setting yet.\n It's hardly optimized already :)", -1, "");
listingStandard.GapLine(5f);
*/
//listingStandard.CheckboxLabeled("Use Breast Size Cap from Apparels(recommended: true)", ref SizedApparelSettings.useBreastSizeCapForApparels, "unite breast size from apparels. Smallest value will be used.\nIf you change this option, you need to redress Pawn\nDefault: true");
//listingStandard.BeginScrollView(rect, ref ScrollPos, ref rect);
//listingStandard.Label("Body(Torso)Texture Option", -1, "");
//listingStandard.CheckboxLabeled("use Body (Torso) Texture", ref SizedApparelSettings.useBodyTexture, "change body texture if the pawn is wearing supported apparels only.\nIt may override bodytexture you use.\nIf you use rimnudeworld, don't use this option.\nDefault: false");
//if (SizedApparelSettings.useBodyTexture == true)
//{
// listingStandard.CheckboxLabeled(" use unsupportedApparel Body Texture", ref SizedApparelSettings.useUnsupportedBodyTexture, "Use \"_UnsupportedApparel\" Body Texture when pawn is wearing unsupported apparel.\nIf this option is false, the body will be default texture.\nDefault: true");
// listingStandard.CheckboxLabeled(" Match BodyTexture To Minimum ApparelSize", ref SizedApparelSettings.matchBodyTextureToMinimumApparelSize, "Avoid Clipping When breasts bigger than supported sized apparel.\nDefault: true");
//
//}
listingStandard.Gap(8);
listingStandard.Label("Other Mod Compatibility");
listingStandard.Gap(8);
listingStandard.GapLine(5f);
listingStandard.CheckboxLabeled(" Forced compatibility of unsupported apparel", ref SizedApparelSettings.ForcedSupportApparel, "It may have clipping issue.\nDefault: false");
/*
if(SizedApparelPatch.DubsApparelTweaksActive == true)
{
listingStandard.Label(" Dubs Apparel Tweaks Patched! (may not work in 1.3)");
listingStandard.Gap(8);
}*/
//sizeList.EndScrollView(ref rect);
//listingStandard.EndSection(sizeList);
//listingStandard.EndScrollView(ref sizeScrollRect);
listingStandard.Label("Non RimJobWorld Compatibility (wip)", -1, "User Who play without RimJobWorld");
if (!SizedApparelPatch.RJWActive)
{
if (SizedApparelPatch.SJWActive)
{
listingStandard.Label(" SafeJobWorld is Actived ", -1, "");
listingStandard.CheckboxLabeled(" use SafeJobWorld's Breasts(Hidden to player but it exist)", ref SizedApparelSettings.useSafeJobBreasts, "use BreastsSize from SJW.\nDefault: true");
}
if(SizedApparelPatch.SJWActive? SizedApparelSettings.useSafeJobBreasts==false : true)
{
listingStandard.CheckboxLabeled(" use Random Breasts Size(not yet work)", ref SizedApparelSettings.useRandomSize, "use breasts random size for pawn.\nDefault: true");
listingStandard.Label(" random Size Min: " + SizedApparelSettings.UnderBreastsOffset.ToString(), -1, "Defualt: 0.01");
SizedApparelSettings.randomSizeMin = listingStandard.Slider(SizedApparelSettings.randomSizeMin, 0f, 2f);
listingStandard.Label(" random Size Max: " + SizedApparelSettings.UnderBreastsOffset.ToString(), -1, "Defualt: 1.00");
SizedApparelSettings.randomSizeMax = listingStandard.Slider(SizedApparelSettings.randomSizeMax, SizedApparelSettings.randomSizeMin, 2f);
}
if (SizedApparelPatch.SJWActive == false)
{
}
}
else
{
listingStandard.Label(" RimJobWorld is Actived ", -1, "");
}
listingStandard.Gap(12);
listingStandard.Label("AlienRace Compatibility (wip)", -1, "");
//listingStandard.CheckboxLabeled(" Unsupported race render as \"Humanlike\" ", ref SizedApparelSettings.UnsupportedRaceToUseHumanlike, "If unchecked, unsupported humanlike race will not be patched!\nIf you change this option, you need to restart rimworld or clear cache\nDefault: false");
if (SizedApparelPatch.alienRaceActive)
{
listingStandard.Label(" AlienRace is Actived ", -1, "");
//listingStandard.CheckboxLabeled("Force to use Human's BodyParts for unsuported Alien races", null, "");
//TODO: Allow Humanlike Settings Per Races
/*
SizedApparelSettings.alienRaces = SizedApparelsDatabase.GetAlienRacesDefNames();
listingStandard.Label("Alien Race Settings", -1f, null);
SizedApparelSettings.alienRaceSearch = listingStandard.TextEntry(SizedApparelSettings.alienRaceSearch, 1);
RaceSettings(new Rect(0f, 60f, 16f, 300f), SizedApparelSettings.alienRaces, ref SizedApparelSettings.alienRacesAllowHumanlikTextures, null);
listingStandard.Gap(listingStandard.verticalSpacing);
*/
/*
Widgets.BeginScrollView(aliensRect, ref ScrollPos, leftRect);
List<bool> alienSettingListLoc = new List<bool>();
foreach(var item in SizedApparelsDatabase.AlienRaceUseHumanlike)
{
//Widgets.CheckboxLabeled(aliensRect, item.Key, ref);
}
Widgets.EndScrollView();
*/
}
else
{
listingStandard.Label(" AlienRace is not Actived ", -1, "");
}
//Rect outRect = new Rect(0f, 35f, rect.width, rect.height - 35f);
/*
const float alienSettingHeight = 80;
Rect outRect = listingStandard.GetRect(listingStandard.CurHeight);
outRect = new Rect(outRect.x, outRect.y, outRect.width, alienSettingHeight);
Rect viewRect = new Rect(0, 0, outRect.width - 16f, 100 );//alienDefList.Count * 30f
Widgets.BeginScrollView(outRect, ref ScrollPos, viewRect, true);
Widgets.Label(new Rect(0f, 0f, 30f, 10f), "hello");
Widgets.Label(new Rect(0f, 0f, 30f, 10f), "world");
*/
//Log.Message(alienDefList.Count.ToString());
//float h = alienDefList.Count <= 1 ? alienRaceSettingHeight : alienRaceSettingHeight * 1.8f;
//Rect rect = Race_ListingStandard.GetRect(h);
//rect.x = 0;
//rect.y = 0;
//Rect ScrollViewRect = new Rect(0, 0, rect.width - 16f, alienDefList.Count * alienRaceSettingHeight);
//Widgets.BeginScrollView(rect, ref ScrollPos, ScrollViewRect, true);
float h = alienDefList.Count * alienRaceSettingHeight;
Listing_Standard Race_ListingStandard = listingStandard.BeginSection(h);
foreach (var raceName in alienDefList)
{
Race_ListingStandard.Label(raceName);
Race_ListingStandard.GapLine(1f);
AlienRaceSetting raceSetting = null;
foreach (var r in SizedApparelSettings.alienRaceSettings)
{
if (r.raceName == null)
continue;
if (raceName == r.raceName)
{
raceSetting = r;
break;
}
}
if (raceSetting == null)
{
raceSetting = new AlienRaceSetting(raceName);
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.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 = Race_ListingStandard.Slider(raceSetting.drawMinAge, raceSetting.drawMinAge <= 100 ? -1: 100, raceSetting.drawMinAge >= 100 ? 1000 : 100);
Race_ListingStandard.Gap();
}
listingStandard.EndSection(Race_ListingStandard);
Widgets.EndScrollView();
//listingStandard.Gap(alienSettingHeight);
listingStandard.GapLine(4f);
listingStandard.Gap(16);
listingStandard.Label("RimNudeWorld Compatibility (WIP)", -1, "");
//listingStandard.CheckboxLabeled(" Don't Replace Body Texture On Nude", ref SizedApparelSettings.DontReplaceBodyTextureOnNude, "Only Replace BodyTexture On Not Nude. Trigers are Torso And Chests.\nDefault: False");
if (SizedApparelPatch.rimNudeWorldActive)
{
listingStandard.Label(" RimNudeWorld is On!. Please check SizedApparel's Body parts render option", -1, "disable all body parts render except the breasts. and set it to only worn option true");
listingStandard.CheckboxLabeled(" use Sized Apparel Breasts graphic when worn.", ref SizedApparelSettings.drawSizedApparelBreastsOnlyWorn, "use Sized Apparel's breasts render for breasts of apparel. it will be hidden when the pawn is naked and rimnudeworld will handle nude. \ndefault = true;");
//listingStandard.CheckboxLabeled(" Hide RimNudeWorld Breasts Addon", ref SizedApparelSettings.hideRimNudeWorldBreasts, "For User Who Use Body(Torso) Texture option, remove double drawn breasts.\nYou can use this option as only using Rimnudeworld genital and else without breasts.\nDefault: False");
if (listingStandard.ButtonTextLabeled("Easy Setting Button", "Apply Rimnude Setting"))
{
SizedApparelSettings.drawSizedApparelBreastsOnlyWorn = true;
SizedApparelSettings.useBodyTexture = false;
SizedApparelSettings.drawBreasts = true;
SizedApparelSettings.drawPenis = false;
SizedApparelSettings.drawVagina = false;
SizedApparelSettings.drawAnus = false;
SizedApparelSettings.drawBelly = false;
}
if (false)//SizedApparelSettings.hideRimNudeWorldBreasts == false
{
//listingStandard.CheckboxLabeled(" match Breast Texture To Minimum ApparelSize (not work)", ref SizedApparelSettings.matchBreastTextureToMinimumApparelSize, "Avoid Clipping When breasts bigger than supported sized apparel.\nDefault: true");
//listingStandard.CheckboxLabeled(" use Under Breasts addon (RimNudeWorld)(not recomanded)", ref SizedApparelSettings.useUnderBreasts, "draw breasts under apparel.");
listingStandard.Label(" Under Breasts Offset: " + SizedApparelSettings.UnderBreastsOffset.ToString(), -1, "offset from defeault layer offset. Defualt: -0.0013");
SizedApparelSettings.UnderBreastsOffset = listingStandard.Slider(SizedApparelSettings.UnderBreastsOffset, -0.025f, 0.025f);
}
if (SizedApparelSettings.useBodyTexture)
{
}
}
else
{
listingStandard.Label(" RimNudeWorld is not Actived ", -1, "");
if (listingStandard.ButtonTextLabeled("Easy Setting Button", "Apply Non Rimnude Setting"))
{
SizedApparelSettings.drawSizedApparelBreastsOnlyWorn = false;
SizedApparelSettings.useBodyTexture = true;
SizedApparelSettings.drawBreasts = true;
SizedApparelSettings.drawPenis = true;
SizedApparelSettings.drawVagina = true;
SizedApparelSettings.drawAnus = true;
SizedApparelSettings.drawBelly = true;
}
}
listingStandard.End();
listingStandard.Begin(rightRect);
listingStandard.Label("If you changed the option, try change apparels or reload save", -1);
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.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(" 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");
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(" 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.Gap();
//listingStandard.CheckboxLabeled(" Use Body Part Variation", ref SizedApparelSettings.useBodyPartsVariation, "Use graphic variation such as inverted nipple.\nDefault: true");
//listingStandard.CheckboxLabeled(" Show Body Part Variaion Button(WIP)", ref SizedApparelSettings.showBodyPartsVariationIcon, "WIP. Not work for now.\nDefault: true");
listingStandard.Gap();
//listingStandard.CheckboxLabeled(" Use BodyPart Variation", ref SizedApparelSettings.useBodyPartsVariation, ""); //TODO
listingStandard.CheckboxLabeled(" Show BodyPart Variation Description", ref SizedApparelSettings.showBodyPartsVariation, "Show more info in bodyparts that sized apparel added. such as inverted nipple");
}
/*
listingStandard.Gap(4);
listingStandard.Label("Breast Size Toggle Option", -1, "default option is setted for RimnudeWorld. you should not change this unless you have the textures for that size.");
listingStandard.Gap(4);
//Rect sizeScrollRect = new Rect(inRect.position+ new Vector2(0, listingStandard.CurHeight), inRect.size/3);
//Vector2 sizeScrollPosition = new Vector2(0.9f, 0.5f);
//listingStandard.BeginScrollView(sizeScrollRect, ref sizeScrollPosition, ref sizeScrollRect);
//Listing_Standard sizeList = listingStandard.BeginSection_NewTemp(150);
//sizeList.BeginScrollView(rect, ref ScrollPos, ref rect);
listingStandard.CheckboxLabeled(" use Nipples", ref SizedApparelSettings.useNipples, "use Nipples(Flat breasts) Sized Apparel.\nDefault: true");
listingStandard.CheckboxLabeled(" use Tiny", ref SizedApparelSettings.useTiny, "use Tiny breasts Sized Apparel.\nDefault: true");
listingStandard.CheckboxLabeled(" use Small", ref SizedApparelSettings.useSmall, "use Small breasts Sized Apparel.\nDefault: true");
listingStandard.CheckboxLabeled(" use Average", ref SizedApparelSettings.useAverage, "use Average breasts Sized Apparel.\nDefault: true");
listingStandard.CheckboxLabeled(" use Large", ref SizedApparelSettings.useLarge, "use Large breasts Sized Apparel.\nDefault: true");
listingStandard.CheckboxLabeled(" use Huge", ref SizedApparelSettings.useHuge, "use Huge breasts Sized Apparel.\nDefault: true");
listingStandard.CheckboxLabeled(" use Enormous", ref SizedApparelSettings.useEnormous, "use Enormous breasts Sized Apparel.\nDefault: true");
listingStandard.CheckboxLabeled(" use Massive", ref SizedApparelSettings.useMassive, "use Massive breasts Sized Apparel.\nDefault: true");
listingStandard.CheckboxLabeled(" use Gargantuan", ref SizedApparelSettings.useGargantuan, "use Gargantuan breasts Sized Apparel.\nDefault: true");
listingStandard.CheckboxLabeled(" use Colossal", ref SizedApparelSettings.useColossal, "use Colossal breasts Sized Apparel.\nDefault: true");
listingStandard.CheckboxLabeled(" use Titanic", ref SizedApparelSettings.useTitanic, "use Titanic breasts Sized Apparel.\nDefault: true");
*/
listingStandard.End();
//listingStandard.EndScrollView(ref rect);
base.DoSettingsWindowContents(inRect);
}
public override string SettingsCategory()
{
return "Sized Apparel for RJW";
}
//copy from BnC
public static bool Contai(string source, string toCheck, StringComparison comp)
{
return source != null && source.IndexOf(toCheck, comp) >= 0;
}
//copy from BnC
public static void RaceSettings(Rect rect, List<string> label, ref List<string> alienRacesToAllowHumanlikes, string tooltip = null)
{
bool flag = !GenText.NullOrEmpty(tooltip);
if (flag)
{
bool flag2 = Mouse.IsOver(rect);
if (flag2)
{
Widgets.DrawHighlight(rect);
}
TooltipHandler.TipRegion(rect, tooltip);
}
bool flag3 = GenList.NullOrEmpty<string>(alienRacesToAllowHumanlikes);
if (flag3)
{
alienRacesToAllowHumanlikes = new List<string>();
}
Listing_Standard listing_Standard = new Listing_Standard();
Rect rect2 = rect;
Rect rect3 = rect;
rect3.height = (float)label.Count * 30f;
rect3.width -= 16f;
Widgets.BeginScrollView(rect2, ref SizedApparelSettings.alienRacesListScrollPos, rect3, true);
listing_Standard.Begin(rect3);
for (int i = 0; i < SizedApparelSettings.alienRaces.Count; i++)
{
bool flag4 = GenList.NullOrEmpty<string>(alienRacesToAllowHumanlikes) || !alienRacesToAllowHumanlikes.Contains(label[i]);
bool flag5 = SizedApparelSettings.alienRaceSearch == null || Contai(SizedApparelSettings.alienRaces[i], SizedApparelSettings.alienRaceSearch.ToLower(), StringComparison.OrdinalIgnoreCase);
if (flag5)
{
WidgetRow widgetRow = new WidgetRow(rect.x,listing_Standard.CurHeight, UIDirection.RightThenUp, 99999f, 1f);
widgetRow.Label(label[i], rect.width * 0.8f, null, -1f);
bool flag6 = label[i] != "Human";
if (flag6)
{
widgetRow.ToggleableIcon(ref flag4, TexButton.IconBook, "Use Shared Body Parts texture (\"Humanlike\" body plarts).\nIf Unchecked, the race will use race's owned texture. \n If the race not have supported textures, try this option.", null, null);
}
else
{
//TODO: should I let human can use humanlike textures?
widgetRow.Icon(TexButton.IconBook, "Human Race is forced to use \"Human\" Textures. not \"Humanlike\"");
}
/*
bool flag7 = widgetRow.ButtonIcon(TexButton.ToggleTweak, "Allow Humanlike Body parts rendering from Sized Apparel(NOT RIMNUDE!)", null, null, null, true, -1f);
if (flag7)
{
bool flag8 = Current.Game != null;
if (flag8)
{
bool flag9 = !Find.WindowStack.TryRemove(typeof(RaceEditorWindow), true);
if (flag9)
{
RaceSettings sizeSettings = RaceUtility.GetSizeSettings(DefDatabase<ThingDef>.GetNamed(label[i], false));
RaceEditorWindow raceEditorWindow = new RaceEditorWindow();
raceEditorWindow.alienRace = DefDatabase<ThingDef>.GetNamed(label[i], true);
bool flag10 = sizeSettings != null;
if (flag10)
{
raceEditorWindow.raceSettings = sizeSettings;
raceEditorWindow.headOffset = sizeSettings.headOffset;
raceEditorWindow.sizeModifier = sizeSettings.sizeModifier;
raceEditorWindow.hairSizeModifier = sizeSettings.hairSizeModifier;
raceEditorWindow.headSizeModifier = sizeSettings.headSizeModifier;
raceEditorWindow.scaleChild = sizeSettings.scaleChild;
raceEditorWindow.scaleTeen = sizeSettings.scaleTeen;
}
Find.WindowStack.Add(raceEditorWindow);
}
}
else
{
Messages.Message("You need to be in-game to open size editor", MessageTypeDefOf.RejectInput, true);
}
}
*/
bool flag11 = !flag4;
if (flag11)
{
bool flag12 = !alienRacesToAllowHumanlikes.Contains(label[i]);
if (flag12)
{
alienRacesToAllowHumanlikes.Add(label[i]);
}
}
else
{
bool flag13 = alienRacesToAllowHumanlikes.Contains(label[i]);
if (flag13)
{
alienRacesToAllowHumanlikes.Remove(label[i]);
}
}
listing_Standard.Gap(30f);
}
}
listing_Standard.End();
Widgets.EndScrollView();
}
}
}

View File

@ -0,0 +1,102 @@
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 rjw;
using System.Reflection;
using System.Reflection.Emit;
namespace SizedApparel
{
//TODO...?
//[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)
{
switch (___curTab)
{
case (Dialog_StylingStation.StylingTab)24:
//Draw PubicHair Tab Code here!
return;
default:
return;
}
}
static void DrawStylingTypePubicHair(Dialog_StylingStation dialog_StylingStation, Rect rect)
{
}
static void AddPubicHairTab(Dialog_StylingStation stylingStation, List<TabRecord> tabs)
{
var curTabField = AccessTools.Field(typeof(Dialog_StylingStation), "curTab");
tabs.Add(new TabRecord("PubicHair".Translate().CapitalizeFirst(), delegate ()
{
curTabField.SetValue(stylingStation, (Dialog_StylingStation.StylingTab)24);
}, (Dialog_StylingStation.StylingTab)curTabField.GetValue(stylingStation) == (Dialog_StylingStation.StylingTab)24));
}
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
bool isHair = false;
MethodInfo tabAdd = AccessTools.DeclaredMethod(typeof(List<TabRecord>),"Add");
foreach (var instruction in instructions)
{
if(instruction.opcode == OpCodes.Ldstr)
{
if (instruction.OperandIs("Hair"))
isHair = true;
else
isHair = false;
}
if (isHair && instruction.opcode == OpCodes.Callvirt && instruction.OperandIs(tabAdd))
{
yield return instruction;//finish add hairTab
yield return new CodeInstruction(OpCodes.Ldarg_0);
yield return new CodeInstruction(OpCodes.Ldarg_0);
//Log.Message("this");
yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(Dialog_StylingStation),"tabs"));
//Log.Message("tabs");
//yield return new CodeInstruction(OpCodes.Ldarg_0);
//Log.Message("this");
//yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(Dialog_StylingStation), "curTab"));
//Log.Message("curtab");
yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(SizedApparelStyleStationDrawTabsPatch), "AddPubicHairTab"));
//Log.Message("call");
//yield return new CodeInstruction(OpCodes.Ldarg_0);
//yield return new CodeInstruction(OpCodes.Ldarg_0);
//yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(Dialog_StylingStation), "tabs"));
//yield return new CodeInstruction(OpCodes.Ldstr,"PubicHair".Translate().CapitalizeFirst());
//yield return new CodeInstruction(OpCodes.Ldarg_0);
//yield return new CodeInstruction(OpCodes.Ldarg_0);
isHair = false;
}
else
yield return instruction;
}
yield break;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{B06471B4-4C6C-478B-B94D-71CC53ABD24D}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>SizedApparel</RootNamespace>
<AssemblyName>SizedApparelforRJW</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\1.3\Assemblies\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>none</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\1.3\Assemblies\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony">
<HintPath>..\..\..\..\..\..\workshop\content\294100\2009463077\Current\Assemblies\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>..\..\..\..\RimWorldWin64_Data\Managed\Assembly-CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="HugsLib">
<HintPath>..\..\..\..\..\..\workshop\content\294100\818773962\v1.1\Assemblies\HugsLib.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="RimNudeWorld">
<HintPath>..\..\..\rimnude-unofficial\1.3 Assembly\Assemblies\RimNudeWorld.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="RJW">
<HintPath>..\..\..\RJW\1.3\Assemblies\RJW.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="UnityEngine">
<HintPath>..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.IMGUIModule">
<HintPath>..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.IMGUIModule.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="AlienRaceSupport.cs" />
<Compile Include="Graphic_BodyParts.cs" />
<Compile Include="Graphic_SizedApparel.cs" />
<Compile Include="SizedAppareIdeoPatch.cs" />
<Compile Include="SizedApparelApparelBuilder.cs" />
<Compile Include="SizedApparelBodyPart.cs" />
<Compile Include="SizedApparelBodyPartDetail.cs" />
<Compile Include="SizedApparelBodyPartEditor.cs" />
<Compile Include="SizedApparelComp.cs" />
<Compile Include="HarmonyPatches.cs" />
<Compile Include="SizedApparelDubsApparelPatch.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="SizedApparelsDatabase.cs" />
<Compile Include="SizedApparelSettingcs.cs" />
<Compile Include="SizedApparelStyleStationPatch.cs" />
<Compile Include="SizedApparelUtility.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.1000
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SizedApparelforRJW", "SizedApparelforRJW.csproj", "{B06471B4-4C6C-478B-B94D-71CC53ABD24D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B06471B4-4C6C-478B-B94D-71CC53ABD24D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B06471B4-4C6C-478B-B94D-71CC53ABD24D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B06471B4-4C6C-478B-B94D-71CC53ABD24D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B06471B4-4C6C-478B-B94D-71CC53ABD24D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CF3F9836-AE71-4CAE-8FFC-72BEB9FFBA91}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,372 @@
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 rjw;
namespace SizedApparel
{
public static class SizedApparelsDatabase
{
public struct BodyGraphicKey
{
}
public struct SizedApparelDatabaseKey
{
public string pathWithoutSizeIndex; // Do Not Include Size Data to path! bodytype could be included
public string raceName;
public string bodyTypeName;
public Gender gender;
public string hediffName;
public int targetSize;
public bool isHorny;
public string customPose;
public string variation;
public SizedApparelDatabaseKey(string path, string race, string bodyType = null, Gender genderInput = Gender.None , string hediff = null, int size = -1, bool horny = false, string customPose = null, string variation = null)
{
this.pathWithoutSizeIndex = path;
this.raceName = race;
this.bodyTypeName = bodyType;
this.gender = genderInput;
this.hediffName = hediff;
this.targetSize = size;
this.isHorny = horny;
this.customPose = customPose;
this.variation = variation;
}
}
public struct SizedApparelDatabaseKeyComparer : IEqualityComparer<SizedApparelDatabaseKey>
{
public bool Equals(SizedApparelDatabaseKey x, SizedApparelDatabaseKey y)
{
if (x.targetSize != y.targetSize)
return false;
return true && (x.pathWithoutSizeIndex == y.pathWithoutSizeIndex) && (x.bodyTypeName == y.bodyTypeName) && (x.raceName == y.raceName)&& (x.gender == y.gender) && (x.hediffName == y.hediffName) && (x.isHorny == y.isHorny) && (x.customPose == y.customPose) && (x.variation == y.variation);
}
public int GetHashCode(SizedApparelDatabaseKey obj)
{
return obj.GetHashCode();
}
}
public struct BodyPartDatabaseKey
{
public string raceName;
public string bodyTypeName;
public string hediffName;
public string folderPath;
public Gender gender;
public int targetSize;
public bool isHorny;
public string customPose; // null custom pose as default pose
public string variation; // null variation as default graphic
public BodyPartDatabaseKey(string race, string bodyType = null, string hediff = null, string path = null, Gender pawnGender = Gender.None, int size = -1, bool horny = false, string customPose = null, string variation = null)
{
this.raceName = race;
this.bodyTypeName = bodyType;
this.hediffName = hediff;
this.folderPath = path;
this.gender = pawnGender;
this.targetSize = size;
this.isHorny = horny;
this.customPose = customPose;
this.variation = variation;
}
}
public struct BodyPartDatabaseKeyComparer : IEqualityComparer<BodyPartDatabaseKey>
{
public bool Equals(BodyPartDatabaseKey x, BodyPartDatabaseKey y)
{
if (x.targetSize != y.targetSize)
return false;
return true && (x.raceName == y.raceName) && (x.bodyTypeName == y.bodyTypeName) && (x.hediffName == y.hediffName) && ( x.folderPath == y.folderPath)&& (x.gender == y.gender) && (x.isHorny == y.isHorny) && (x.customPose == y.customPose) && (x.variation == y.variation);
}
public int GetHashCode(BodyPartDatabaseKey obj)
{
return obj.GetHashCode();
}
}
public struct PathAndSize
{
public string pathWithSizeIndex;
public int size;
public bool isUnsupportedHumanlikePath;
public bool isCustomPose;
public string hediffName;
public Dictionary<string, BodyPartPoint> points;
public PathAndSize(string path, int index, bool unsupportedHumanlike = false, bool customPose = false, string hediff = null ,Dictionary<string, BodyPartPoint> pointsInput = null)
{
this.pathWithSizeIndex = path;
this.size = index;
this.isUnsupportedHumanlikePath = unsupportedHumanlike;
this.isCustomPose = customPose;
this.hediffName = hediff;
this.points = pointsInput;
}
}
private static Dictionary<BodyGraphicKey, Graphic> SizedApparelBodyGraphic = new Dictionary<BodyGraphicKey, Graphic>(); // TODO
private static Dictionary<SizedApparelDatabaseKey, PathAndSize> SupportedApparelResultPath = new Dictionary<SizedApparelDatabaseKey, PathAndSize>(new SizedApparelDatabaseKeyComparer());
private static Dictionary<BodyPartDatabaseKey, PathAndSize> SupportedBodyPartResultPath = new Dictionary<BodyPartDatabaseKey, PathAndSize>(new BodyPartDatabaseKeyComparer());
private static Dictionary<string, string> SupportedApparelOriginalPath = new Dictionary<string, string>();
//AlienRace AllowHumanlike. Need to Restart or Clear cache to change options
public static Dictionary<string, bool> AlienRaceUseHumanlike = new Dictionary<string, bool>();
private static void ResetAlienRaceUseHumanlike()
{
AlienRaceUseHumanlike.Clear();
IEnumerable<ThingDef> HumanlikeRaces;
HumanlikeRaces = DefDatabase<ThingDef>.AllDefs.Where(b =>b.race?.Humanlike == true);
foreach (ThingDef raceDef in HumanlikeRaces)
{
//Default Value Is True
AlienRaceUseHumanlike.Add(raceDef.defName, true);
}
}
public static bool GetAlienRaceUseHumanlike(string raceDef)
{
if (AlienRaceUseHumanlike.NullOrEmpty())
{
ResetAlienRaceUseHumanlike();
}
if (AlienRaceUseHumanlike.ContainsKey(raceDef))
return AlienRaceUseHumanlike[raceDef];
return false;
}
public static List<string> GetAlienRacesDefNames()
{
if (AlienRaceUseHumanlike.NullOrEmpty())
{
ResetAlienRaceUseHumanlike();
}
//It must have one or more elements: human.
return AlienRaceUseHumanlike.Keys.ToList();
}
public static void ClearAll()
{
SupportedApparelResultPath.Clear();
SupportedBodyPartResultPath.Clear();
SupportedApparelOriginalPath.Clear();
AlienRaceUseHumanlike.Clear();
}
//Apparels, Bodyparts can be used
public static PathAndSize GetSupportedApparelSizedPath(SizedApparelDatabaseKey key)
{
int currentSize = -1;
float currentSeverity = -1;
return GetSupportedApparelSizedPath(key, out currentSize, out currentSeverity);
}
public static string GetSupportedApparelOriginalPath(string path)
{
string outString;
if (SupportedApparelOriginalPath.TryGetValue(path, out outString))
return outString;
return null;
}
public static Dictionary<string, BodyPartPoint> GetGraphicPoints(string textuerPath)
{
//DefDatabase<>
return null;
}
public static PathAndSize GetSupportedApparelSizedPath(SizedApparelDatabaseKey key, out int indexOut, out float currentSeverityOut)
{
if (SupportedApparelResultPath.ContainsKey(key))
{
if (SizedApparelSettings.Debug)
Log.Message("[Sized Apparel] SizedApparelDataBase::ValidKey: "+ key.pathWithoutSizeIndex);
var value = SupportedApparelResultPath.TryGetValue(key);
indexOut = value.size;
currentSeverityOut = SizedApparelUtility.BreastSizeIndexToSeverity(value.size);
if (SizedApparelSettings.Debug)
Log.Message("[Sized Apparel] SizedApparelDataBase::Result Path: " + value.pathWithSizeIndex);
return value;
}
if (SizedApparelSettings.Debug)
Log.Message(" [Sized Apparel] SizedApparelDataBase::Key Not Found: " + key.pathWithoutSizeIndex);
PathAndSize result;
Graphic sourceGraphic = GraphicDatabase.Get<Graphic_Multi>(key.pathWithoutSizeIndex);
bool flag;
bool customPose = true; //default none pose also custom pose
string hediffResult;
string targetRaceName;
//if (GetAlienRaceUseHumanlike(key.raceName))
//TODO. AlienRaceHumanlike
/*
var pawnDef = DefDatabase<SizedApparelPawnDef>.GetNamed(key.raceName);
if (pawnDef != null)
{
if(pawnDef.isHumanlike)
targetRaceName = "Humanlike";
}
else
targetRaceName = key.raceName;*/
targetRaceName = key.raceName;
Graphic graphic = null;
graphic = SizedApparelUtility.GetSizedApparelGraphic(sourceGraphic, SizedApparelUtility.BreastSizeIndexToSeverity(key.targetSize), out indexOut, out currentSeverityOut, out flag, out hediffResult, targetRaceName, key.hediffName, key.customPose, key.gender);//key.customPose
if(graphic == null && key.gender != Gender.None)
{
//try Genderless
graphic = SizedApparelUtility.GetSizedApparelGraphic(sourceGraphic, SizedApparelUtility.BreastSizeIndexToSeverity(key.targetSize), out indexOut, out currentSeverityOut, out flag, out hediffResult, targetRaceName, key.hediffName, key.customPose, Gender.None);//key.customPose
}
if (key.customPose != null && graphic == null)
{
customPose = false;
graphic = SizedApparelUtility.GetSizedApparelGraphic(sourceGraphic, SizedApparelUtility.BreastSizeIndexToSeverity(key.targetSize), out indexOut, out currentSeverityOut, out flag, out hediffResult , targetRaceName, key.hediffName , null ,key.gender);
if (graphic == null && key.gender != Gender.None)
{
//try Genderless
graphic = SizedApparelUtility.GetSizedApparelGraphic(sourceGraphic, SizedApparelUtility.BreastSizeIndexToSeverity(key.targetSize), out indexOut, out currentSeverityOut, out flag, out hediffResult, targetRaceName, key.hediffName, null, Gender.None);//key.customPose
}
}
//Try Find Different Target Size
if (flag == true)
{
result = new PathAndSize(graphic.path, indexOut, false, customPose, hediffResult);
SupportedApparelResultPath.SetOrAdd(key, result);
SupportedApparelOriginalPath.SetOrAdd(result.pathWithSizeIndex, key.pathWithoutSizeIndex);
}
else
{
result = new PathAndSize(null, -1);
SupportedApparelResultPath.SetOrAdd(key, result);
SupportedApparelOriginalPath.SetOrAdd(key.pathWithoutSizeIndex, key.pathWithoutSizeIndex);
}
return result;
}
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;
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);
if (graphic != null)
{
result = new PathAndSize(graphic.path, currentSize, false, 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, null, key.variation, key.gender);
if (graphic != null)
{
result = new PathAndSize(graphic.path, currentSize, false, 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, null, key.variation, key.gender);
if (graphic != null)
{
result = new PathAndSize(graphic.path, currentSize, false, 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, null, key.variation, key.gender);
if (graphic != null)
{
result = new PathAndSize(graphic.path, currentSize, false, key.customPose == null ? true : false, hediffResult);
SupportedBodyPartResultPath.SetOrAdd(key, result);
return result;
}
//SizedApparelMod.CheckAndLoadAlienRaces();
//HumanLike Search
var raceSetting = SizedApparelSettings.alienRaceSettings.FirstOrDefault((AlienRaceSetting s) => s.raceName == key.raceName);
if (raceSetting !=null && !raceSetting.asHumanlike) //old: !SizedApparelSettings.UnsupportedRaceToUseHumanlike
{
//Cannot find Any result
result = new PathAndSize(null, -1);
SupportedBodyPartResultPath.SetOrAdd(key, result);
return result;
}
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);
if (graphic != null)
{
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);
if (graphic != null)
{
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);
if (graphic != null)
{
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);
if (graphic != null)
{
result = new PathAndSize(graphic.path, currentSize, true, key.customPose == null ? true : false, hediffResult);
SupportedBodyPartResultPath.SetOrAdd(key, result);
return result;
}
//Cannot find Any result
result = new PathAndSize(null, -1);
SupportedBodyPartResultPath.SetOrAdd(key, result);
return result;
}
}
}

View File

@ -0,0 +1,4 @@
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]

Binary file not shown.

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- "null" and "default" varName will be no variation. -->
<Defs>
<SizedApparel.SizedApparelBodyPartVariationDef>
<defName>AnusDetail</defName>
<bodyPartName>Anus</bodyPartName>
<variations>
<li>
<!--Default Anus-->
<hediffName>Anus</hediffName>
<varName>
<li>default</li>
<li>Donut</li>
</varName>
</li>
<li>
<!-- <hediffName>SlimeAnus</hediffName> -->
<!-- <varName> -->
<!-- <li>null</li> -->
<!-- <li>InvertedNipple</li> -->
<!-- </varName> -->
</li>
</variations>
</SizedApparel.SizedApparelBodyPartVariationDef>
</Defs>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- "null" and "default" varName will be no variation. -->
<Defs>
<SizedApparel.SizedApparelBodyPartVariationDef>
<defName>BreastDetail</defName>
<bodyPartName>Breasts</bodyPartName>
<variations>
<li>
<!--Default Breasts-->
<hediffName>Breasts</hediffName>
<varName>
<li>default</li>
<li>InvertedNipple</li>
</varName>
</li>
<li>
<!-- <hediffName>SlimeBreasts</hediffName> -->
<!-- <varName> -->
<!-- <li>null</li> -->
<!-- <li>InvertedNipple</li> -->
<!-- </varName> -->
</li>
</variations>
</SizedApparel.SizedApparelBodyPartVariationDef>
</Defs>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- "null" and "default" varName will be no variation. -->
<Defs>
<SizedApparel.SizedApparelBodyPartVariationDef>
<defName>PenisDetail</defName>
<bodyPartName>Penis</bodyPartName>
<variations>
<li>
<!--Default Penis-->
<hediffName>Penis</hediffName>
<varName>
<li>default</li>
<!-- <li>Uncircumcised</li> -->
</varName>
</li>
</variations>
</SizedApparel.SizedApparelBodyPartVariationDef>
</Defs>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- "null" and "default" varName will be no variation. -->
<Defs>
<SizedApparel.SizedApparelBodyPartVariationDef>
<defName>VaginaDetail</defName>
<bodyPartName>Vagina</bodyPartName>
<variations>
<li>
<!--Default Vagina-->
<hediffName>Vagina</hediffName>
<varName>
<li>default</li>
<li>Puffy</li>
</varName>
</li>
</variations>
</SizedApparel.SizedApparelBodyPartVariationDef>
</Defs>

View File

@ -0,0 +1,18 @@
SizedApparel_ShowBelly
-don't hide belly even the apparel covers torso
SizedApparel_ShowPrivateCrotch
-don't hide crotch(genitals and anus) even the apparel covers genitals
SizedApparel_ShowUdder
-don't hide udder even the apparel covers udder
-wip (not work yet)
SizedApparel_IgnorBreastSize
-sized apparel mod will just ignore the apparel during calculate breasts size of apparels
-this tag is useful to skip. good example is ratkin shield (the shield is covering breasts)
SizedApparel_IgnorePose
-when the custom pose is checking posed apparel texture, skip current apparel
-wip

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<Patch>
<Operation Class="PatchOperationFindMod">
<mods>
<li>Biotech</li>
</mods>
<match Class="PatchOperationSequence">
<success>Normal</success>
<operations>
<li Class="PatchOperationConditional">
<xpath>Defs/ThingDef[defName = "Apparel_Sash"]/apparel/tags</xpath>
<nomatch Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "Apparel_Sash"]/apparel</xpath>
<value>
<tags>
<li>SizedApparel_IgnorBreastSize</li>
<li>SizedApparel_ShowPrivateCrotch</li>
</tags>
</value>
</nomatch>
<match Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "Apparel_Sash"]/apparel/tags</xpath>
<value>
<li>SizedApparel_IgnorBreastSize</li>
<li>SizedApparel_ShowPrivateCrotch</li>
</value>
</match>
</li>
</operations>
</match>
</Operation>
</Patch>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<Patch>
<Operation Class="PatchOperationFindMod">
<mods>
<li>Biotech</li>
</mods>
<match Class="PatchOperationSequence">
<success>Normal</success>
<operations>
<li Class="PatchOperationConditional">
<xpath>Defs/ThingDef[defName = "Apparel_Sash"]/apparel/tags</xpath>
<nomatch Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "Apparel_Sash"]/apparel</xpath>
<value>
<tags>
<li>SizedApparel_IgnorBreastSize</li>
</tags>
</value>
</nomatch>
<match Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "Apparel_Sash"]/apparel/tags</xpath>
<value>
<li>SizedApparel_IgnorBreastSize</li>
</value>
</match>
</li>
</operations>
</match>
</Operation>
</Patch>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- <li>ShowPrivateCrotch</li> -->
<!-- <Patch> -->
<!-- <Operation Class="PatchOperationAdd"> -->
<!-- <xpath>Defs/ThingDef[defName = "Apparel_Duster"]/apparel/tags</xpath> -->
<!-- <value> -->
<!-- <li>SizedApparel_ShowPrivateCrotch</li> -->
<!-- </value> -->
<!-- </Operation> -->
<!-- </Patch> -->
<!-- skip core checking. the core must be loaded. -->
<Patch>
<Operation Class="PatchOperationSequence">
<success>Normal</success>
<operations>
<li Class="PatchOperationConditional">
<xpath>Defs/ThingDef[defName = "Apparel_Duster"]/apparel/tags</xpath>
<nomatch Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "Apparel_Duster"]/apparel</xpath>
<value>
<tags>
<li>SizedApparel_ShowPrivateCrotch</li>
</tags>
</value>
</nomatch>
<match Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "Apparel_Duster"]/apparel/tags</xpath>
<value>
<li>SizedApparel_ShowPrivateCrotch</li>
</value>
</match>
</li>
</operations>
</Operation>
</Patch>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<Patch>
<Operation Class="PatchOperationSequence">
<success>Normal</success>
<operations>
<li Class="PatchOperationConditional">
<xpath>Defs/ThingDef[defName = "Apparel_BasicShirt"]/apparel/tags</xpath>
<nomatch Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "Apparel_BasicShirt"]/apparel</xpath>
<value>
<tags>
<li>SizedApparel_ShowPrivateCrotch</li>
</tags>
</value>
</nomatch>
<match Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "Apparel_BasicShirt"]/apparel/tags</xpath>
<value>
<li>SizedApparel_ShowPrivateCrotch</li>
</value>
</match>
</li>
</operations>
</Operation>
</Patch>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8" ?>
<Patch>
<Operation Class="PatchOperationFindMod">
<mods>
<li>Ideology</li>
</mods>
<match Class="PatchOperationSequence">
<success>Normal</success>
<operations>
<li Class="PatchOperationConditional">
<xpath>Defs/ThingDef[defName = "Apparel_BodyStrap"]/apparel/tags</xpath>
<nomatch Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "Apparel_BodyStrap"]/apparel</xpath>
<value>
<tags>
<li>SizedApparel_IgnorBreastSize</li>
</tags>
</value>
</nomatch>
<match Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "Apparel_BodyStrap"]/apparel/tags</xpath>
<value>
<li>SizedApparel_IgnorBreastSize</li>
</value>
</match>
</li>
</operations>
</match>
</Operation>
</Patch>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8" ?>
<Patch>
<!-- <Operation Class="PatchOperationSequence"> -->
<!-- <success>Always</success> -->
<!-- <operations> -->
<!-- <li Class="PatchOperationTest"> -->
<!-- <xpath>Defs/ThingDef[defName="Human"]/comps</xpath> -->
<!-- <success>Invert</success> -->
<!-- </li> -->
<!-- <li Class="PatchOperationAdd"> -->
<!-- <xPath>Defs/ThingDef[defName="Human]"</xPath> -->
<!-- <value> -->
<!-- <comps /> -->
<!-- </value> -->
<!-- </li> -->
<!-- </operations> -->
<!-- </Operation> -->
<Operation Class="PatchOperationAdd">
<xpath>/Defs/ThingDef[@Name="BasePawn"]/comps</xpath>
<value>
<li>
<compClass>SizedApparel.ApparelRecorderComp</compClass>
</li>
</value>
</Operation>
</Patch>

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8" ?>
<Patch>
<Operation Class="PatchOperationSequence">
<operations>
<li Class = "PatchOperationConditional">
<xpath>/Defs/rjw.HediffDef_PartBase[@Name="RJW_PrivatePartBase"]/comps</xpath>
<nomatch Class="PatchOperationAdd">
<xpath>/Defs/rjw.HediffDef_PartBase[@Name="RJW_PrivatePartBase"]</xpath>
<value>
<comps>
<li Class = "SizedApparel.SizedApparelBodyPartDetailProperties" />
</comps>
</value>
</nomatch>
<match Class="PatchOperationAdd">
<xpath>/Defs/rjw.HediffDef_PartBase[@Name="RJW_PrivatePartBase"]/comps</xpath>
<value>
<li Class = "SizedApparel.SizedApparelBodyPartDetailProperties" />
</value>
</match>
</li>
<!-- <li Class = "PatchOperationConditional"> -->
<!-- <xpath>/Defs/ThingDef[@Name="rjw_BodyPartBase"]/comps</xpath> -->
<!-- <nomatch Class="PatchOperationAdd"> -->
<!-- <xpath>/Defs/ThingDef[@Name="rjw_BodyPartBase"]</xpath> -->
<!-- <value> -->
<!-- <comps> -->
<!-- <li Class = "SizedApparel.SizedApparelBodyPartDetailThingProperties" /> -->
<!-- </comps> -->
<!-- </value> -->
<!-- </nomatch> -->
<!-- <match Class="PatchOperationAdd"> -->
<!-- <xpath>/Defs/ThingDef[@Name="RJW_PrivatePartBase"]/comps</xpath> -->
<!-- <value> -->
<!-- <li Class = "SizedApparel.SizedApparelBodyPartDetailThingProperties" /> -->
<!-- </value> -->
<!-- </match> -->
<!-- </li> -->
</operations>
</Operation>
<!-- <Operation Class="PatchOperationAdd"> -->
<!-- <success>Normal</success> -->
<!-- <xpath>/Defs/HediffDef[@Name="RJW_PrivatePartBase"]/comps</xpath> -->
<!-- <value> -->
<!-- <li Class = "SizedApparel.SizedApparelBodyPartDetailProperties" /> -->
<!-- </value> -->
<!-- </Operation> -->
<!-- <Operation Class="PatchOperationAdd"> -->
<!-- <xpath>/Defs/HediffDef[@Name="NaturalPrivatePartBreast"]/comps[@Class ="SizedApparel.SizedApparelBodyPartDetailProperties"]</xpath> -->
<!-- <value> -->
<!-- <bodyPartName>Breasts</bodyPartName> -->
<!-- </value> -->
<!-- </Operation> -->
<!-- <Operation Class="PatchOperationAdd"> -->
<!-- <xpath>/Defs/HediffDef[@Name="NaturalPrivatePartBreast"]/comps</xpath> -->
<!-- <value> -->
<!-- <bodyPartName>Breasts</bodyPartName> -->
<!-- </value> -->
<!-- </Operation> -->
</Patch>

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8" ?>
<Patch>
<Operation Class="PatchOperationSequence">
<operations>
<!-- <li Class = "PatchOperationConditional"> -->
<!-- <xpath>/Defs/rjw.HediffDef_PartBase[@Name="RJW_PrivatePartBase"]/comps</xpath> -->
<!-- <nomatch Class="PatchOperationAdd"> -->
<!-- <xpath>/Defs/rjw.HediffDef_PartBase[@Name="RJW_PrivatePartBase"]</xpath> -->
<!-- <value> -->
<!-- <comps> -->
<!-- <li Class = "SizedApparel.SizedApparelBodyPartDetailProperties" /> -->
<!-- </comps> -->
<!-- </value> -->
<!-- </nomatch> -->
<!-- <match Class="PatchOperationAdd"> -->
<!-- <xpath>/Defs/rjw.HediffDef_PartBase[@Name="RJW_PrivatePartBase"]/comps</xpath> -->
<!-- <value> -->
<!-- <li Class = "SizedApparel.SizedApparelBodyPartDetailProperties" /> -->
<!-- </value> -->
<!-- </match> -->
<!-- </li> -->
<li Class = "PatchOperationConditional">
<xpath>/Defs/ThingDef[@Name="rjw_BodyPartBase"]/comps</xpath>
<nomatch Class="PatchOperationAdd">
<xpath>/Defs/ThingDef[@Name="rjw_BodyPartBase"]</xpath>
<value>
<comps>
<li Class = "SizedApparel.SizedApparelBodyPartDetailThingProperties" />
</comps>
</value>
</nomatch>
<match Class="PatchOperationAdd">
<xpath>/Defs/ThingDef[@Name="rjw_BodyPartBase"]/comps</xpath>
<value>
<li Class = "SizedApparel.SizedApparelBodyPartDetailThingProperties" />
</value>
</match>
</li>
</operations>
</Operation>
<!-- <Operation Class="PatchOperationAdd"> -->
<!-- <success>Normal</success> -->
<!-- <xpath>/Defs/HediffDef[@Name="RJW_PrivatePartBase"]/comps</xpath> -->
<!-- <value> -->
<!-- <li Class = "SizedApparel.SizedApparelBodyPartDetailProperties" /> -->
<!-- </value> -->
<!-- </Operation> -->
<!-- <Operation Class="PatchOperationAdd"> -->
<!-- <xpath>/Defs/HediffDef[@Name="NaturalPrivatePartBreast"]/comps[@Class ="SizedApparel.SizedApparelBodyPartDetailProperties"]</xpath> -->
<!-- <value> -->
<!-- <bodyPartName>Breasts</bodyPartName> -->
<!-- </value> -->
<!-- </Operation> -->
<!-- <Operation Class="PatchOperationAdd"> -->
<!-- <xpath>/Defs/HediffDef[@Name="NaturalPrivatePartBreast"]/comps</xpath> -->
<!-- <value> -->
<!-- <bodyPartName>Breasts</bodyPartName> -->
<!-- </value> -->
<!-- </Operation> -->
</Patch>

View File

@ -5,11 +5,11 @@
<url></url>
<supportedVersions>
<li>1.3</li>
<li>1.4</li>
</supportedVersions>
<packageId>OTYOTY.SizedApparel</packageId>
<description>
[version 0.93.0]
[worked for RJW Version: 4.9.8]
[version 0.93.2]
This mod changes apparel texture for matching pawn's breasts size.
Also, it has include pawn's private body parts rendering system.

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -0,0 +1 @@
For now, those are just copied, avoid error

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Some files were not shown because too many files have changed in this diff Show More