using System; using System.Collections.Generic; using System.Linq; using System.Text; using RimWorld; using Verse; using HarmonyLib; using UnityEngine; using rjw; using System.Reflection; //since I test system alot, source cord is very dirty and not optimized. namespace SizedApparel { public struct supportedIndex { } [StaticConstructorOnStartup] [HarmonyPatch(typeof(Pawn_HealthTracker), "Notify_HediffChanged")] public class PawnHealthTrackerPatch { public static void Postfix(Hediff hediff, Pawn_HealthTracker __instance, ref Pawn ___pawn) { if (___pawn == null) return; var comp = ___pawn.TryGetComp(); if (comp == null) return; if (hediff == null) return; if (SizedApparelUtility.isRJWParts(hediff))/// { //comp.ClearAll(); //comp.Update(); comp.SetDirty(); //already doing set dirty in hediffchange method. //___pawn.Drawer.renderer.graphics.SetApparelGraphicsDirty(); //PortraitsCache.SetDirty(___pawn); //GlobalTextureAtlasManager.TryMarkPawnFrameSetDirty(___pawn); return; } if (SizedApparelUtility.isBellyBulgeHediff(hediff)) { comp.SetDirty(); return; } } } [StaticConstructorOnStartup] public class HeddifPatchForRimNudeWorld { //hediff.get_Severity() public static void GetSeverityPostFix(Hediff __instance) { if (__instance.Part != null) { if (__instance.Part.def.defName.Equals(SizedApparelUtility.chestString)) { if (__instance.def.defName.EndsWith(SizedApparelUtility.breastsString)) { //Log.Message("Found Breast Hediff"); //_breastSeverity = __instance.Severity; //_breastHediff = __instance; //result = true; //Log.Message(_breastSeverity.ToString()); } } } } //...get_severity() /* public static void BodyAddonHediffSeverityGraphicPatch(AlienRace.AlienPartGenerator.BodyAddonHediffSeverityGraphic __instance, ref float __result) { if (!SizedApparelPatch.rimNudeWorldActive) { return; } if (!SizedApparelSettings.matchBreastToSupportedApparelSize) { return; } if (__instance.path.Contains(SizedApparelUtility.breastsString)) { } }*/ } [StaticConstructorOnStartup] public class BodyPatch { public static void SetBodyGraphic(Pawn pawn,bool drawClothFlag = true, bool fromGraphicRecord = true, bool revert = false) { //Pawn_ApparelTracker __instance; //GetBreastSeverity(__instance.pawn, out breastSeverity, out breastHediff); //bool flag = hasUnSupportedApparel(__instance.pawn, breastSeverity, breastHediff); ApparelRecorderComp comp = pawn.TryGetComp(); if (comp == null) return; if (revert) { var pawnRenderer = pawn.Drawer?.renderer?.graphics; //Log.Message("useBodyTexture"); /* if (!pawnRenderer.AllResolved) { pawnRenderer.ResolveAllGraphics(); }*/ if (pawnRenderer == null) return; if (comp.graphicSourceNaked != null) pawnRenderer.nakedGraphic = comp.graphicSourceNaked.GetColoredVersion(pawnRenderer.nakedGraphic.Shader, pawnRenderer.nakedGraphic.color, pawnRenderer.nakedGraphic.colorTwo); if (comp.graphicSourceRotten != null) pawnRenderer.rottingGraphic = comp.graphicSourceRotten.GetColoredVersion(pawnRenderer.rottingGraphic.Shader, pawnRenderer.rottingGraphic.color, pawnRenderer.rottingGraphic.colorTwo); } if (!comp.hasUpdateBefore) { //comp.Update(true, fromGraphicRecord); } float breastSeverity = comp.breastSeverity; Hediff breastHediff = comp.breastHediff; if (SizedApparelSettings.drawBodyParts == true && SizedApparelSettings.useBodyTexture)//old:SizedApparelSettings.useBodyTexture { //if (SizedApparelSettings.Debug) // Log.Message("[Sized Apparel] Trying to change" + pawn.Name + "'s body texture."); var pawnRenderer = pawn.Drawer?.renderer?.graphics; //Log.Message("useBodyTexture"); /* if (!pawnRenderer.AllResolved) { pawnRenderer.ResolveAllGraphics(); }*/ if (pawnRenderer == null) return; string nakedGraphicPath = pawnRenderer.nakedGraphic?.path; //Log.Message("nakedGraphicPath"); string rottingGraphicPath = pawnRenderer.rottingGraphic?.path; //Log.Message("rottingGraphicPath"); int currentBreastSizeIndex = 0; float currentBreastSeverity = 0; Graphic nakedGraphic; Graphic rottingGraphic; bool validNakedTexture = false; bool validRottingTexture = false; int offset = 0; /* * Obsolete if (SizedApparelSettings.DontReplaceBodyTextureOnNude == true && SizedApparelUtility.isPawnNaked(pawn)) { if (SizedApparelSettings.Debug) Log.Message("[Sized Apparel] " + pawn.Name + "is Naked. And DontReplaceBodyTextureOnNude Option is active. Changing Body Texture is cancled."); return; }*/ if (!comp.hasUnsupportedApparel || SizedApparelUtility.isPawnNaked(pawn) || !drawClothFlag) { if (comp.graphicbaseBodyNaked != null) { pawnRenderer.nakedGraphic = comp.graphicbaseBodyNaked.GetColoredVersion(pawnRenderer.nakedGraphic.Shader, pawnRenderer.nakedGraphic.color, pawnRenderer.nakedGraphic.colorTwo); } if (comp.graphicbaseBodyRotten != null) { pawnRenderer.rottingGraphic = comp.graphicbaseBodyRotten.GetColoredVersion(pawnRenderer.rottingGraphic.Shader, pawnRenderer.rottingGraphic.color, pawnRenderer.rottingGraphic.colorTwo); } } else { if (comp.graphicSourceNaked != null) pawnRenderer.nakedGraphic = comp.graphicSourceNaked.GetColoredVersion(pawnRenderer.nakedGraphic.Shader, pawnRenderer.nakedGraphic.color, pawnRenderer.nakedGraphic.colorTwo); if (comp.graphicSourceRotten != null) pawnRenderer.rottingGraphic = comp.graphicSourceRotten.GetColoredVersion(pawnRenderer.rottingGraphic.Shader, pawnRenderer.rottingGraphic.color, pawnRenderer.rottingGraphic.colorTwo); } return;//no need to replace full body texture anymore. if (false && comp.hasUnsupportedApparel && SizedApparelSettings.useUnsupportedBodyTexture)//old method. no need to do. { //Log.Message("hasUnsupportedApparel"); // SetBodyGraphic(__instance, true); if (true) { if ((ContentFinder.Get((nakedGraphicPath + "_UnsupportedApparel" + "_south"), false) != null)) { nakedGraphic = GraphicDatabase.Get(nakedGraphicPath + "_Unsupported", pawnRenderer.nakedGraphic.Shader, pawnRenderer.nakedGraphic.drawSize, pawnRenderer.nakedGraphic.color, pawnRenderer.nakedGraphic.colorTwo, pawnRenderer.nakedGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); pawnRenderer.nakedGraphic = nakedGraphic; } if ((ContentFinder.Get((rottingGraphicPath + "_UnsupportedApparel" + "_south"), false) != null)) { rottingGraphic = GraphicDatabase.Get(rottingGraphicPath + "_UnsupportedApparel", pawnRenderer.rottingGraphic.Shader, pawnRenderer.rottingGraphic.drawSize, pawnRenderer.rottingGraphic.color, pawnRenderer.rottingGraphic.colorTwo, pawnRenderer.rottingGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); pawnRenderer.rottingGraphic = rottingGraphic; } } } else { if(!comp.hasUnsupportedApparel || SizedApparelUtility.isPawnNaked(pawn)) { } if (comp.graphicbaseBodyNaked!=null) pawnRenderer.nakedGraphic = comp.graphicbaseBodyNaked.GetColoredVersion(pawnRenderer.nakedGraphic.Shader, pawnRenderer.nakedGraphic.color, pawnRenderer.nakedGraphic.colorTwo); if (comp.graphicbaseBodyRotten != null) pawnRenderer.rottingGraphic = comp.graphicbaseBodyRotten.GetColoredVersion(pawnRenderer.rottingGraphic.Shader, pawnRenderer.rottingGraphic.color, pawnRenderer.rottingGraphic.colorTwo); return;//no need to replace full body texture anymore. while (offset < SizedApparelUtility.size.Length) { string breastSeverityStringCache = SizedApparelUtility.BreastSeverityString(breastSeverity, offset, true, ref currentBreastSizeIndex, ref currentBreastSeverity); //search bigger //SizedApparelSettings.matchBodyTextureToMinimumApparelSize? currentBreastSizeIndex <= minSupportedBreasSizeIndex:true if (validNakedTexture == false) { if ((ContentFinder.Get((nakedGraphicPath + breastSeverityStringCache + "_south"), false) != null)) { if (SizedApparelSettings.matchBodyTextureToMinimumApparelSize ? SizedApparelUtility.BreastSizeIndexToSeverity(currentBreastSizeIndex) <= comp.breastSeverityCapToDraw : true) { nakedGraphic = GraphicDatabase.Get(nakedGraphicPath + breastSeverityStringCache, pawnRenderer.nakedGraphic.Shader, pawnRenderer.nakedGraphic.drawSize, pawnRenderer.nakedGraphic.color, pawnRenderer.nakedGraphic.colorTwo, pawnRenderer.nakedGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); pawnRenderer.nakedGraphic = nakedGraphic; validNakedTexture = true; } } } if (validRottingTexture == false) { if ((ContentFinder.Get((rottingGraphicPath + breastSeverityStringCache + "_south"), false) != null)) { if (SizedApparelSettings.matchBodyTextureToMinimumApparelSize ? SizedApparelUtility.BreastSizeIndexToSeverity(currentBreastSizeIndex) <= comp.breastSeverityCapToDraw : true) { rottingGraphic = GraphicDatabase.Get(rottingGraphicPath + breastSeverityStringCache, pawnRenderer.rottingGraphic.Shader, pawnRenderer.rottingGraphic.drawSize, pawnRenderer.rottingGraphic.color, pawnRenderer.rottingGraphic.colorTwo, pawnRenderer.rottingGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); pawnRenderer.rottingGraphic = rottingGraphic; validRottingTexture = true; } } } //search smaller breastSeverityStringCache = SizedApparelUtility.BreastSeverityString(breastSeverity, offset, false, ref currentBreastSizeIndex, ref currentBreastSeverity); if (validNakedTexture == false) { if ((ContentFinder.Get((nakedGraphicPath + breastSeverityStringCache + "_south"), false) != null)) { if (SizedApparelSettings.matchBodyTextureToMinimumApparelSize ? SizedApparelUtility.BreastSizeIndexToSeverity(currentBreastSizeIndex) <= comp.breastSeverityCapToDraw : true) { nakedGraphic = GraphicDatabase.Get(nakedGraphicPath + breastSeverityStringCache, pawnRenderer.nakedGraphic.Shader, pawnRenderer.nakedGraphic.drawSize, pawnRenderer.nakedGraphic.color, pawnRenderer.nakedGraphic.colorTwo, pawnRenderer.nakedGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); pawnRenderer.nakedGraphic = nakedGraphic; validNakedTexture = true; } } } if (validRottingTexture == false) { if ((ContentFinder.Get((rottingGraphicPath + breastSeverityStringCache + "_south"), false) != null)) { if (SizedApparelSettings.matchBodyTextureToMinimumApparelSize ? SizedApparelUtility.BreastSizeIndexToSeverity(currentBreastSizeIndex) <= comp.breastSeverityCapToDraw : true) { rottingGraphic = GraphicDatabase.Get(rottingGraphicPath + breastSeverityStringCache, pawnRenderer.rottingGraphic.Shader, pawnRenderer.rottingGraphic.drawSize, pawnRenderer.rottingGraphic.color, pawnRenderer.rottingGraphic.colorTwo, pawnRenderer.rottingGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); pawnRenderer.rottingGraphic = rottingGraphic; validRottingTexture = true; } } } if (validNakedTexture == true && validRottingTexture == true) { if (SizedApparelSettings.Debug) Log.Message("[Sized Apparel] " + pawn.Name + "'s body texture has changed."); break; } offset++; } } } return; /* if (SizedApparelSettings.useBodyTexture == false) return; //Log.Message("Hello"); if (pawnGraphicSet == null) return; if (pawnGraphicSet.pawn.RaceProps.Humanlike == false) return; return; //Log.Message("SetBodyGraphic"); //pawnGraphicSet.ClearCache(); string path = pawnGraphicSet.pawn.story.bodyType.bodyNakedGraphicPath; string path_bodyDessicated = pawnGraphicSet.pawn.story.bodyType.bodyDessicatedGraphicPath; string filename; string pathname; string filename_bodyDessicated; string pathname_bodyDessicated; pathname = System.IO.Path.GetDirectoryName(path); filename = System.IO.Path.GetFileName(path); filename_bodyDessicated = System.IO.Path.GetFileName(path_bodyDessicated); pathname_bodyDessicated = System.IO.Path.GetDirectoryName(path_bodyDessicated); //Log.Message("SetPath"); bool validBody = false; bool validDessicatedBody = false; //pawnGraphicSet.pawn.Drawer.renderer.graphics.nakedGraphic //pawnGraphicSet.pawn.Drawer.renderer.graphics.dessicatedGraphic if (hasUnsupportApparel) { //Log.Message("IfhasUnsupportApparel"); //Graphic newBodyGraphic = null; //Graphic newRottingGraphic = null; //string path; //Log.Message("tryUnsupportedApparelBodyTexture"); //OLD::pawnGraphicSet.pawn.Drawer.renderer.graphics if (pawnGraphicSet.nakedGraphic != null) if (ContentFinder.Get((pawnGraphicSet.pawn.Drawer.renderer.graphics.nakedGraphic.path + "_UnsupportedApparel" + "_south"), false) != null) { pawnGraphicSet.pawn.Drawer.renderer.graphics.nakedGraphic = GraphicDatabase.Get(pawnGraphicSet.nakedGraphic.path + "_UnsupportedApparel", pawnGraphicSet.nakedGraphic.Shader, pawnGraphicSet.nakedGraphic.drawSize, pawnGraphicSet.nakedGraphic.color, pawnGraphicSet.nakedGraphic.colorTwo); validBody = true; } if (pawnGraphicSet.dessicatedGraphic != null) if (ContentFinder.Get((pawnGraphicSet.dessicatedGraphic.path + "_UnsupportedApparel" + "_south"), false) != null) { pawnGraphicSet.dessicatedGraphic = GraphicDatabase.Get(pawnGraphicSet.dessicatedGraphic.path + "_UnsupportedApparel", pawnGraphicSet.rottingGraphic.Shader, pawnGraphicSet.rottingGraphic.drawSize, pawnGraphicSet.rottingGraphic.color, pawnGraphicSet.rottingGraphic.colorTwo); validDessicatedBody = true; } } else { //Log.Message("undo"); string currentPath = pawnGraphicSet.nakedGraphic.path; string currentDessicatedPath = pawnGraphicSet.dessicatedGraphic.path; //Log.Message(currentPath.Substring(0,currentPath.Length - "_UnsupportedApparel".Length)); if (pawnGraphicSet.nakedGraphic != null) if (ContentFinder.Get(currentPath.Substring(0, currentPath.Length - "_UnsupportedApparel".Length) + "_south", false) != null) { pawnGraphicSet.nakedGraphic = GraphicDatabase.Get((currentPath.Substring(0, currentPath.Length - "_UnsupportedApparel".Length)), pawnGraphicSet.nakedGraphic.Shader, pawnGraphicSet.nakedGraphic.drawSize, pawnGraphicSet.nakedGraphic.color, pawnGraphicSet.nakedGraphic.colorTwo); } if (pawnGraphicSet.dessicatedGraphic != null) if (ContentFinder.Get(currentDessicatedPath.Substring(0, currentDessicatedPath.Length - "_UnsupportedApparel".Length) + "_south", false) != null) { pawnGraphicSet.dessicatedGraphic = GraphicDatabase.Get((currentDessicatedPath.Substring(0, currentDessicatedPath.Length - "_UnsupportedApparel".Length)), pawnGraphicSet.nakedGraphic.Shader, pawnGraphicSet.nakedGraphic.drawSize, pawnGraphicSet.nakedGraphic.color, pawnGraphicSet.nakedGraphic.colorTwo); } }*/ //pawnGraphicSet.ClearCache(); } private static void GetBreastSeverity(Pawn pawn, out float breastSeverity, out Hediff breastHediff) { throw new NotImplementedException(); } } //for worn apparel //[HarmonyPatch(typeof(ApparelGraphicRecordGetter), "TryGetGraphicApparel")] /* [StaticConstructorOnStartup] [HarmonyPatch(typeof(PawnGraphicSet), "ResolveAllGraphics")] class BodyfixForUnsupported { static void Prefix(PawnGraphicSet __instance) { if (!UnityData.IsInMainThread) return; if (__instance.pawn == null) return; var comp = __instance.pawn.TryGetComp(); if (comp == null) return; comp.ClearAll(); //comp.Update(); } }*/ /* [StaticConstructorOnStartup] [HarmonyPatch(typeof(PawnGenerator), "GeneratePawn", typeof(PawnGenerationRequest) )] class GeneratePawnPatch { Type[] types = { typeof(PawnGenerationRequest) }; static void Postfix(PawnGenerationRequest request, Pawn __result) { if (!UnityData.IsInMainThread) return; if (__result != null) { //__result.Drawer.renderer.graphics.ResolveAllGraphics(); __result.Drawer.renderer.graphics.ResolveApparelGraphics(); } } }*/ [StaticConstructorOnStartup] //[HarmonyPatch(typeof(Pawn_ApparelTracker), "ExposeData")] class ApparelTrackerExposePatch { static void Postfix(Pawn_ApparelTracker __instance) { if (!UnityData.IsInMainThread) { return; } if (__instance.pawn == null) return; if (Scribe.mode == LoadSaveMode.PostLoadInit) { ApparelRecorderComp comp = __instance.pawn.TryGetComp(); if (comp == null) return; if (!comp.hasUpdateBefore) comp.Update(true, false); } } } //[StaticConstructorOnStartup] //[HarmonyPatch(typeof(Pawn_ApparelTracker), "Notify_ApparelChanged")] //rimworld 1.2 => apparelChanged, rimworld 1.3 => apparelAdded, apparelRemoved public class ApparelTrackerPatch { //Prefix public static void Changed(Pawn_ApparelTracker __instance) { /* if (Current.Game.World == null) return; */ if (!UnityData.IsInMainThread) { return; } if (__instance.pawn == null) return; if (SizedApparelSettings.Debug) Log.Message("[Sized Apparel] " + __instance.pawn.Name + "'s apparels are changed. updating sizedApparels for it."); //GetBreastSeverity(__instance.pawn, out breastSeverity, out breastHediff); //bool flag = hasUnSupportedApparel(__instance.pawn, breastSeverity, breastHediff); ApparelRecorderComp comp = __instance.pawn.TryGetComp(); if (comp != null) { //comp.ClearBreastCacheValue(); //comp.ClearAll(); //bool flag = false; //SizedApparelUtility.GetBreastSeverity(__instance.pawn, out breastSeverity, out breastHediff); //flag = SizedApparelUtility.hasUnSupportedApparel(__instance.pawn, breastSeverity, breastHediff); //flag = SizedApparelUtility.hasUnSupportedApparelFromWornData(__instance.pawn, breastSeverity, breastHediff); //comp.hasUpdateBefore = true; //comp.hasUnsupportedApparel = flag; //comp.breastHediff = breastHediff; ; //comp.breastSeverity = breastSeverity; //comp.Update(true, false);//TODO: Coverd But No Graphic may cause Big Issue!!! //comp.Update(true, true); comp.SetDirty(); /* if (SizedApparelSettings.drawBodyParts)//old:SizedApparelSettings.useBodyTexture BodyPatch.SetBodyGraphic(__instance.pawn); */ /* //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); } ); */ } } } [StaticConstructorOnStartup] //[HarmonyPatch(typeof(PawnGraphicSet), "SetApparelGraphicsDirty")] class SetApparelGraphicsDirtyPatch { public static bool Prefix(PawnGraphicSet __instance) { if (SizedApparelSettings.useBodyTexture) { //__instance.SetAllGraphicsDirty(); //return false; } return true; } } //TODO [StaticConstructorOnStartup] //[HarmonyPatch(typeof(PawnGraphicSet), "get_apparelGraphics")] class PrivatePartsPatch { public static void Postfix(PawnGraphicSet __instance, ref List __result) { var resualtCach = __result; if (SizedApparelSettings.drawBodyParts) { var privateParts = new List(); if (SizedApparelSettings.drawPenis) { } if (SizedApparelSettings.drawVagina) { } if (SizedApparelSettings.drawHips) { } if (SizedApparelSettings.drawHips) { } if (SizedApparelSettings.drawAnus) { } } } } //[HarmonyPatch(typeof(PawnGraphicSet), "MatsBodyBaseAt")] public class MatBodyBaseAtPatch { public static void Postfix(PawnGraphicSet __instance, Rot4 facing, RotDrawMode bodyCondition, bool drawClothes, List __result) { if (__result == null) return; int num = facing.AsInt + 1000 * (int)bodyCondition; List copy; copy = __result.ListFullCopy(); for (int i = 0; i<__result.Count; i++) { //SizedApparelsDatabase.GetSupportedApparelOriginalPath(__result[i].g) } } } [StaticConstructorOnStartup] [HarmonyPatch(typeof(ApparelGraphicRecordGetter), "TryGetGraphicApparel")] [HarmonyBefore(new string[]{"QualityOfBuilding"})] public class GetApparelGraphicFix { public static void Postfix(Apparel apparel, BodyTypeDef bodyType, ref ApparelGraphicRecord rec, ref bool __result) { if (__result == false) return; if (apparel == null) return; if (bodyType == null) return; if (apparel.Wearer != null) { //rec = new ApparelGraphicRecord(null, null); var comp = apparel.Wearer.TryGetComp(); //if (SizedApparelSettings.matchBodyTextureToMinimumApparelSize) // BreastSeverity = comp.BreastSeverityCache; int currentBreastSizeIndex = 0; float currentBreastSeverity = -1; //int minSupportedBreastSizeIndex = 1000; //float minSupportedBreastSeverity = 1000; //SizedApparelUtility.GetBreastSeverity(apparel.Wearer, out BreastSeverity, out breastHediff); if (comp != null) { if (comp.hasUpdateBefore == false) { //SizedApparelUtility.GetBreastSeverity(apparel.Wearer, out BreastSeverity, out breastHediff); //comp.hasUnsupportedApparel = SizedApparelUtility.hasUnSupportedApparelFromWornData(apparel.Wearer, BreastSeverity, breastHediff); //comp.breastSeverity = BreastSeverity; //comp.breastHediff = breastHediff; //comp.hasUpdateBefore = true; //comp.Update(true,false); } if (comp.isDirty == true) { //return; //comp.ClearAll(); //comp.Update(true, false); } /* if (comp.needToCheckApparelGraphicRecords) { TODO; if (comp.isApparelGraphicRecordChanged()) comp.Update(true, false); }*/ if (comp.needToCheckApparelGraphicRecords) { /* if (comp.isApparelGraphicRecordChanged()) { //return; //comp.Update(true, true); //1.3 //SizedApparelUtility.UpdateAllApparel(___pawn, true); }*/ } var breastHediff = comp.breastHediff; float BreastSeverity = comp.breastSeverity; if (SizedApparelSettings.useBreastSizeCapForApparels) //SizedApparelSettings.useBreastSizeCapForApparels //wip BreastSeverity = Math.Min(comp.BreastSeverityCache, BreastSeverity); if (comp.hasUnsupportedApparel == false && (comp.bodyPartBreasts.bodyPartGraphic !=null || comp.bodyPartBreasts.bodyPartGraphicHorny != null))//(comp.graphicBreasts!=null|| comp.graphicBreasts_horny != null) { Graphic sizedGraphic = null; string resultPath = SizedApparelsDatabase.GetSupportedApparelSizedPath(new SizedApparelsDatabase.SizedApparelDatabaseKey(rec.graphic.path, apparel?.Wearer?.def.defName, breastHediff.def.defName, apparel.Wearer.gender, apparel?.Wearer?.story?.bodyType?.defName, SizedApparelUtility.BreastSeverityInt(BreastSeverity))).pathWithSizeIndex; if(resultPath != null) { //sizedGraphic = SizedApparelUtility.GetSizedApparelGraphic(rec.graphic, BreastSeverity, apparel?.Wearer?.def.defName, breastHediff.def.defName); sizedGraphic = GraphicDatabase.Get(resultPath, rec.graphic.Shader, rec.graphic.drawSize, rec.graphic.color, rec.graphic.colorTwo); } if(sizedGraphic != null) rec = new ApparelGraphicRecord(sizedGraphic, rec.sourceApparel); //minSupportedBreastSizeIndex = Math.Min(currentBreastSizeIndex, minSupportedBreastSizeIndex); //comp.breastSeverityCapToDraw = Math.Min(comp.breastSeverityCapToDraw, minSupportedBreastSeverity); } } else { if (SizedApparelSettings.Debug) Log.Warning("[Sized Apparel] " + apparel.Wearer.Name + " doesn't have SizedApparel Compoenet!!"); } } } } [StaticConstructorOnStartup] [HarmonyPatch(typeof(PawnGraphicSet), "ClearCache")] class GraphicSetClearFix { public static void Postfix(PawnGraphicSet __instance) { if (__instance.pawn == null) { return; } var comp = __instance.pawn.TryGetComp(); if (comp == null) return; //comp.ClearAll(false); //comp.needToCheckApparelGraphicRecords = true; comp.SetDirty(); } } //[HarmonyPatch(typeof(PawnGraphicSet))] //[HarmonyPatch("ResolveApparelGraphics")] //[HarmonyBefore(new string[] { "rimworld.erdelf.alien_race.main" })] [StaticConstructorOnStartup] //[HarmonyPatch(typeof(PawnGraphicSet), "ResolveApparelGraphics")] class ApparelFix { [Obsolete] public static bool old_old_Prefix(Apparel apparel, BodyTypeDef bodyType, ApparelGraphicRecord rec, ref bool __result) { bool result = true; bool flag = apparel.def.apparel.wornGraphicPath.NullOrEmpty(); if (flag) { string text = apparel.def.apparel.wornGraphicPath + "_" + bodyType.defName + "_3"; bool flag2 = false; flag2 = ContentFinder.Get(text + "_north", true) == null || ContentFinder.Get(text + "_east", true) == null || ContentFinder.Get(text + "_south", true) == null; if (flag2) { bool flag3 = apparel.def.apparel.LastLayer != ApparelLayerDefOf.Overhead; if (flag3) { //text = apparel.def.apparel.wornGraphicPath + "_Female"; Graphic graphic = GraphicDatabase.Get(text, ShaderDatabase.Cutout, apparel.def.graphicData.drawSize, apparel.DrawColor); rec = new ApparelGraphicRecord(graphic, apparel); result = false; __result = true; } } else { bool flag4 = apparel.def.apparel.LastLayer == ApparelLayerDefOf.Overhead; if (flag4) { Graphic graphic2 = GraphicDatabase.Get(text, ShaderDatabase.Cutout, apparel.def.graphicData.drawSize, apparel.DrawColor); rec = new ApparelGraphicRecord(graphic2, apparel); result = false; __result = true; } } } return result; } [Obsolete] static void old_Postfix(ref PawnGraphicSet __instance) { if (Current.Game.World == null) return; // Log.Message("ResolveGraphic"); if (__instance.pawn.RaceProps.Humanlike) { //Log.Message("ResolveApparelGraphics"); //__instance.pawn.health.hediffSet.HasHediff(Hediff ,BodyPartRecord ,false); //__instance.pawn.health.hediffSet.GetNotMissingParts(BodyPartHeight.Undefined, BodyPartDepth.Undefined, null, null).Any((BodyPartRecord bpr) => bpr.untranslatedCustomLabel == label || bpr.def.defName == label); var comp = __instance.pawn.TryGetComp(); if (comp != null) { bool flag = false; float BreastSeverity = -1; Hediff breastHediff = null; SizedApparelUtility.GetBreastSeverity(__instance.pawn, out BreastSeverity, out breastHediff); //Log.Message("hasUnsupported? : "+comp.hasUnsupportedApparel.ToString()); if (true) //(!comp.hasUpdateBefore) { //Log.Message("UpdateFirst"); /* if (comp.havingSex) comp.hasUnsupportedApparel = SizedApparelUtility.hasUnSupportedApparel(__instance.pawn, BreastSeverity, breastHediff); else comp.hasUnsupportedApparel = SizedApparelUtility.hasUnSupportedApparelFromWornData(__instance.pawn, BreastSeverity, breastHediff); */ comp.hasUnsupportedApparel = SizedApparelUtility.hasUnSupportedApparelFromWornData(__instance.pawn, BreastSeverity, breastHediff); comp.hasUpdateBefore = true; } if (comp.hasUnsupportedApparel == false) { int currentBreastSizeIndex = 0; int minSupportedBreastSizeIndex = 1000; float currentBreastSeverity = 0; float minSupportedBreastSeverity = 1000; List newAgr = new List(); foreach (ApparelGraphicRecord agr in __instance.apparelGraphics)//ApparelGraphicRecord agr in curAgr { /* if(apparel != null) { ApparelGraphicRecord rec; if (apparel.def.apparel.wornGraphicPath.NullOrEmpty()) { rec = new ApparelGraphicRecord(null, null); newAgr.Add(rec); continue; } string path; if (apparel.def.apparel.LastLayer == ApparelLayerDefOf.Overhead || apparel.def.apparel.wornGraphicPath == BaseContent.PlaceholderImagePath) { path = apparel.def.apparel.wornGraphicPath; } else { path = apparel.def.apparel.wornGraphicPath + "_" + __instance.pawn.story.bodyType.defName; } Shader shader = ShaderDatabase.Cutout; if (apparel.def.apparel.useWornGraphicMask) { shader = ShaderDatabase.CutoutComplex; } Graphic graphic = GraphicDatabase.Get(path, shader, apparel.def.graphicData.drawSize, apparel.DrawColor); rec = new ApparelGraphicRecord(graphic, apparel); //string endstring = (gender == Gender.Female && (ContentFinder.Get(apparel.def.apparel.wornGraphicPath + "_" + bodyType.defName + "_fem_south", false) != null)) ? "_fem" : null; //string path = (apparel.def.apparel.LastLayer != ApparelLayerDefOf.Overhead) ? (apparel.def.apparel.wornGraphicPath + "_" + bodyType.defName + endstring) : apparel.def.apparel.wornGraphicPath; //path = agr.sourceApparel.def.graphic.path; //var path = agr.graphic.path; var ExtraPath = path; string targetPath; } */ string path; string extraPath; //path = agr.sourceApparel.def.apparel.wornGraphicPath + "_" + __instance.pawn.story.bodyType.defName; path = agr.graphic.path; if (breastHediff != null) { extraPath = path + "_" + breastHediff.def.defName; } else extraPath = path; int offset = 0; bool validTexture = false; Graphic graphic = null; bool findBigger = true; // if false : search smaller first while (offset < SizedApparelUtility.size.Length) { if (breastHediff != null) { if (ContentFinder.Get((extraPath + SizedApparelUtility.BreastSeverityString(BreastSeverity, offset, findBigger, ref currentBreastSizeIndex, ref currentBreastSeverity) + "_south"), false) != null) // checking special texture like udder { minSupportedBreastSizeIndex = Math.Min(currentBreastSizeIndex, minSupportedBreastSizeIndex); minSupportedBreastSeverity = Math.Min(currentBreastSeverity, minSupportedBreastSeverity); graphic = new Graphic(); graphic = GraphicDatabase.Get(extraPath + SizedApparelUtility.BreastSeverityString(BreastSeverity, offset, findBigger, ref currentBreastSizeIndex, ref currentBreastSeverity), agr.graphic.Shader, agr.graphic.drawSize, agr.graphic.color, agr.graphic.colorTwo, agr.graphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); validTexture = true; //Log.Message(extraPath + BreastSeverityString(BreastSeverity, offset, findBigger) + ":Extra Texture Found"); break; } //Log.Warning(extraPath + BreastSeverityString(BreastSeverity, offset, findBigger) + ":Extra Texture Not Found."); } if ((ContentFinder.Get((path + SizedApparelUtility.BreastSeverityString(BreastSeverity, offset, findBigger, ref currentBreastSizeIndex, ref currentBreastSeverity) + "_south"), false) != null)) { minSupportedBreastSizeIndex = Math.Min(currentBreastSizeIndex, minSupportedBreastSizeIndex); minSupportedBreastSeverity = Math.Min(currentBreastSeverity, minSupportedBreastSeverity); graphic = GraphicDatabase.Get(path + SizedApparelUtility.BreastSeverityString(BreastSeverity, offset, findBigger, ref currentBreastSizeIndex, ref currentBreastSeverity), agr.graphic.Shader, agr.graphic.drawSize, agr.graphic.color, agr.graphic.colorTwo, agr.graphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, findBigger) + ":Texture Found"); break; } //Log.Warning(path + BreastSeverityString(BreastSeverity, offset, findBigger) + ":Texture Not Found. Try bigger Texture."); offset++; } if (validTexture == false) { //Log.Warning(path + BreastSeverityString(BreastSeverity, offset, findBigger) + ":Texture Not Found. try smaller instead of bigger ."); } if (validTexture == false) { offset = 0; while (offset < SizedApparelUtility.size.Length) { if (breastHediff != null) { if (ContentFinder.Get((extraPath + SizedApparelUtility.BreastSeverityString(BreastSeverity, offset, !findBigger, ref currentBreastSizeIndex, ref currentBreastSeverity) + "_south"), false) != null) // checking special texture like udder { minSupportedBreastSizeIndex = Math.Min(currentBreastSizeIndex, minSupportedBreastSizeIndex); minSupportedBreastSeverity = Math.Min(currentBreastSeverity, minSupportedBreastSeverity); graphic = new Graphic(); graphic = GraphicDatabase.Get(extraPath + SizedApparelUtility.BreastSeverityString(BreastSeverity, offset, !findBigger, ref currentBreastSizeIndex, ref currentBreastSeverity), agr.graphic.Shader, agr.graphic.drawSize, agr.graphic.color, agr.graphic.colorTwo, agr.graphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); validTexture = true; //Log.Message(extraPath + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Extra Texture Found"); break; } //Log.Warning(extraPath + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Extra Texture Not Found."); } if ((ContentFinder.Get((path + SizedApparelUtility.BreastSeverityString(BreastSeverity, offset, !findBigger, ref currentBreastSizeIndex, ref currentBreastSeverity) + "_south"), false) != null)) { minSupportedBreastSizeIndex = Math.Min(currentBreastSizeIndex, minSupportedBreastSizeIndex); minSupportedBreastSeverity = Math.Min(currentBreastSeverity, minSupportedBreastSeverity); graphic = GraphicDatabase.Get(path + SizedApparelUtility.BreastSeverityString(BreastSeverity, offset, !findBigger, ref currentBreastSizeIndex, ref currentBreastSeverity), agr.graphic.Shader, agr.graphic.drawSize, agr.graphic.color, agr.graphic.colorTwo, agr.graphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); break; } //Log.Warning(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Not Found. Try smaller Texture."); offset++; } } if (validTexture == false) { //Log.Warning(path + BreastSeverityString(BreastSeverity, offset, findBigger) + ":Texture Not Found. try smaller instead of bigger ."); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //graphic = GraphicDatabase.Get(path, ShaderDatabase.Cutout, agr.graphic.drawSize, agr.graphic.color); graphic = agr.graphic; } ApparelGraphicRecord _Agr = new ApparelGraphicRecord(graphic, agr.sourceApparel); //_Agr.sourceApparel. newAgr.Add(_Agr); } __instance.apparelGraphics = newAgr; comp.breastSeverityCapToDraw = minSupportedBreastSeverity; if (SizedApparelSettings.useBodyTexture == true) { //Log.Message("useBodyTexture"); if (__instance.nakedGraphic == null || __instance.rottingGraphic == null) { __instance.ResolveAllGraphics(); return; } string nakedGraphicPath = __instance.nakedGraphic.path; //Log.Message("nakedGraphicPath"); string rottingGraphicPath = __instance.rottingGraphic.path; //Log.Message("rottingGraphicPath"); Graphic nakedGraphic; Graphic rottingGraphic; bool validNakedTexture = false; bool validRottingTexture = false; int offset = 0; if (SizedApparelSettings.DontReplaceBodyTextureOnNude == true && SizedApparelUtility.isPawnNaked(__instance.pawn)) return; if (comp.hasUnsupportedApparel && SizedApparelSettings.useUnsupportedBodyTexture) { //Log.Message("hasUnsupportedApparel"); // SetBodyGraphic(__instance, true); if (true) { if ((ContentFinder.Get((nakedGraphicPath + "_UnsupportedApparel" + "_south"), false) != null)) { nakedGraphic = GraphicDatabase.Get(nakedGraphicPath + "_Unsupported", __instance.nakedGraphic.Shader, __instance.nakedGraphic.drawSize, __instance.nakedGraphic.color, __instance.nakedGraphic.colorTwo, __instance.nakedGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); __instance.nakedGraphic = nakedGraphic; } if ((ContentFinder.Get((rottingGraphicPath + "_UnsupportedApparel" + "_south"), false) != null)) { rottingGraphic = GraphicDatabase.Get(rottingGraphicPath + "_UnsupportedApparel", __instance.rottingGraphic.Shader, __instance.rottingGraphic.drawSize, __instance.rottingGraphic.color, __instance.rottingGraphic.colorTwo, __instance.rottingGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); __instance.rottingGraphic = rottingGraphic; } } } else { while (offset < SizedApparelUtility.size.Length) { string breastSeverityStringCache = SizedApparelUtility.BreastSeverityString(BreastSeverity, offset, true, ref currentBreastSizeIndex, ref currentBreastSeverity); //search bigger //SizedApparelSettings.matchBodyTextureToMinimumApparelSize? currentBreastSizeIndex <= minSupportedBreasSizeIndex:true if (validNakedTexture == false) { if ((ContentFinder.Get((nakedGraphicPath + breastSeverityStringCache + "_south"), false) != null)) { if (SizedApparelSettings.matchBodyTextureToMinimumApparelSize ? currentBreastSizeIndex <= minSupportedBreastSizeIndex : true) { nakedGraphic = GraphicDatabase.Get(nakedGraphicPath + breastSeverityStringCache, __instance.nakedGraphic.Shader, __instance.nakedGraphic.drawSize, __instance.nakedGraphic.color, __instance.nakedGraphic.colorTwo, __instance.nakedGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); __instance.nakedGraphic = nakedGraphic; validNakedTexture = true; } } } if (validRottingTexture == false) { if ((ContentFinder.Get((rottingGraphicPath + breastSeverityStringCache + "_south"), false) != null)) { if (SizedApparelSettings.matchBodyTextureToMinimumApparelSize ? currentBreastSizeIndex <= minSupportedBreastSizeIndex : true) { rottingGraphic = GraphicDatabase.Get(rottingGraphicPath + breastSeverityStringCache, __instance.rottingGraphic.Shader, __instance.rottingGraphic.drawSize, __instance.rottingGraphic.color, __instance.rottingGraphic.colorTwo, __instance.rottingGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); __instance.rottingGraphic = rottingGraphic; validRottingTexture = true; } } } //search smaller breastSeverityStringCache = SizedApparelUtility.BreastSeverityString(BreastSeverity, offset, false, ref currentBreastSizeIndex, ref currentBreastSeverity); if (validNakedTexture == false) { if ((ContentFinder.Get((nakedGraphicPath + breastSeverityStringCache + "_south"), false) != null)) { if (SizedApparelSettings.matchBodyTextureToMinimumApparelSize ? currentBreastSizeIndex <= minSupportedBreastSizeIndex : true) { nakedGraphic = GraphicDatabase.Get(nakedGraphicPath + breastSeverityStringCache, __instance.nakedGraphic.Shader, __instance.nakedGraphic.drawSize, __instance.nakedGraphic.color, __instance.nakedGraphic.colorTwo, __instance.nakedGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); __instance.nakedGraphic = nakedGraphic; validNakedTexture = true; } } } if (validRottingTexture == false) { if ((ContentFinder.Get((rottingGraphicPath + breastSeverityStringCache + "_south"), false) != null)) { if (SizedApparelSettings.matchBodyTextureToMinimumApparelSize ? currentBreastSizeIndex <= minSupportedBreastSizeIndex : true) { rottingGraphic = GraphicDatabase.Get(rottingGraphicPath + breastSeverityStringCache, __instance.rottingGraphic.Shader, __instance.rottingGraphic.drawSize, __instance.rottingGraphic.color, __instance.rottingGraphic.colorTwo, __instance.rottingGraphic.data); //newAgr.Add(new ApparelGraphicRecord(graphic, agr.sourceApparel)); //validTexture = true; //Log.Message(path + BreastSeverityString(BreastSeverity, offset, !findBigger) + ":Texture Found"); __instance.rottingGraphic = rottingGraphic; validRottingTexture = true; } } } if (validNakedTexture == true && validRottingTexture == true) break; offset++; } } } } //SetBodyGraphic(__instance, comp.hasUnsupportedApparel); } } return; } /* static void Prefix(ref PawnGraphicSet __instance) { if (!UnityData.IsInMainThread) return; if (__instance.pawn == null) return; var comp = __instance.pawn.TryGetComp(); if (comp == null) return; comp.ClearAll(); comp.Update(); }*/ static void oldPostfix(ref PawnGraphicSet __instance) { if (!UnityData.IsInMainThread) return; if (false&&SizedApparelSettings.useBodyTexture)//TODO { BodyPatch.SetBodyGraphic(__instance.pawn); } } } //[HarmonyPatch(typeof(PawnGraphicSet), "MatsBodyBaseAt")] public class PawnGraphicSetPatch { public static void Postfix(ref List __result, ref PawnGraphicSet __instance, Rot4 facing, RotDrawMode bodyCondition) { } } //TODO: Patch After RJW (Sexualize_GenerateNewPawnInternal) or just postfix to Sexualize [HarmonyPatch(typeof(PawnGenerator), "GenerateNewPawnInternal")] public class PawnGeneratorPatch { } [HarmonyPatch(typeof(Corpse), "RotStageChanged")] public class RotStagePatch { public static void Prefix(CompRottable __instance) { var comp = __instance.parent.TryGetComp(); if (comp == null) return; comp.SetDirty(); } } //Should I Patch this? //[HarmonyPatch(typeof(Pawn_AgeTracker), "RecalculateLifeStageIndex")] public class AgePatch { public static void Postfix(Pawn_AgeTracker __instance, Pawn ___pawn) { var comp = ___pawn.TryGetComp(); if (comp == null) return; comp.CheckAgeChanged(); } } //Styling Station patch..? wip //[HarmonyPatch(typeof(PawnGraphicSet), "MatsBodyBaseAt")] public class BodyMatPatch { public static void Postfix(PawnGraphicSet __instance, RotDrawMode bodyCondition, Rot4 facing, ref List __result, bool drawClothes) { List loc = new List(); if (bodyCondition == RotDrawMode.Dessicated) { return; } for (int i = 0; i< __result.Count; i++) { if (bodyCondition == RotDrawMode.Fresh) { if (__result[i] == __instance.nakedGraphic.MatAt(facing, null)) { continue; } } else if (bodyCondition == RotDrawMode.Rotting || __instance.dessicatedGraphic == null) { if (__result[i] == __instance.rottingGraphic.MatAt(facing, null)) { continue; } } if (drawClothes) { } loc.Add(__result[i]); } } } //RimWorld 1.3 [HarmonyPatch(typeof(PawnRenderer), "BaseHeadOffsetAt")] public class BaseHeadOffsetAtPatch { public static void Postfix(ref PawnRenderer __instance, Pawn ___pawn, Rot4 rotation, ref Vector3 __result) { ApparelRecorderComp apparelRecorder = ___pawn.TryGetComp(); if (apparelRecorder == null) return; if (apparelRecorder.customPose != null) { var item = apparelRecorder.currentCustomPose.headOffset.FirstOrDefault(b => b.bodyType == ___pawn.story.bodyType.label); __result += item.offsets.GetOffset(rotation); } } } //RimWorld 1.3 [HarmonyPatch(typeof(PawnRenderer), "DrawPawnBody")] public class DrawPawnBodyPatch { static MethodInfo overrideMatMethod = AccessTools.Method(typeof(PawnRenderer), "OverrideMaterialIfNeeded"); public static void Prefix(ref PawnRenderer __instance, Pawn ___pawn, PawnRenderFlags flags) { if (!SizedApparelSettings.drawBodyParts) return; if (___pawn == null) return; ApparelRecorderComp apparelRecorder = ___pawn.TryGetComp(); if (apparelRecorder == null) return; //!flags.FlagSet(PawnRenderFlags.StylingStation)&& bool flag = false; //if (apparelRecorder.needToCheckApparelGraphicRecords && apparelRecorder.isApparelGraphicRecordChanged()) /* if (apparelRecorder.isApparelGraphicRecordChanged()) { flag = true; } */ if (false && flags.FlagSet(PawnRenderFlags.StylingStation))//TODO...? { //apparelRecorder.isDirty is allways true if (false)//StylingStation Doesn't work with cache! patch in postfix { apparelRecorder.Update(true, true, true, flags.FlagSet(PawnRenderFlags.Clothes)); //Log.Message(" [Sized Apparel]StylingStation:: isDirty? : " + apparelRecorder.isDirty); if(flags.FlagSet(PawnRenderFlags.Clothes)) SizedApparelUtility.UpdateAllApparel(___pawn, true); } } else { if ((!apparelRecorder.hasUpdateBefore || apparelRecorder.isDirty)) { if (SizedApparelSettings.Debug) Log.Message("[SizedApparel] trying to draw " + ___pawn.Name + " with unupdated component or SetDirty! Updating it."); //apparelRecorder.ClearAll(); //Todo. Async Update? apparelRecorder.Update(true, true, true, flags.FlagSet(PawnRenderFlags.Clothes)); SizedApparelUtility.UpdateAllApparel(___pawn,true); } if (flag) { //apparelRecorder.Update(true, true, true, flags.FlagSet(PawnRenderFlags.Clothes)); //apparelRecorder.Update(true, true); 1.3 //SizedApparelUtility.UpdateAllApparel(___pawn, true); } } if (SizedApparelSettings.drawBodyParts) BodyPatch.SetBodyGraphic(___pawn, flags.FlagSet(PawnRenderFlags.Clothes), false); else BodyPatch.SetBodyGraphic(___pawn, flags.FlagSet(PawnRenderFlags.Clothes), false, false); } public static void Postfix(ref PawnRenderer __instance, Vector3 rootLoc, float angle, Rot4 facing, RotDrawMode bodyDrawType, PawnRenderFlags flags, Pawn ___pawn, Mesh bodyMesh) { if (___pawn == null) return; ApparelRecorderComp apparelRecorder = ___pawn.TryGetComp(); if (apparelRecorder == null) return; Quaternion quaternion = Quaternion.AngleAxis(angle, Vector3.up); if (bodyMesh == null) return; Quaternion quat = Quaternion.AngleAxis(angle, Vector3.up); string defName = __instance.graphics.pawn.def.defName; Shader shader = ___pawn.Drawer.renderer.graphics.nakedGraphic.Shader; Color skinColor = Color.white; Color skinColor2 = Color.white; if (bodyDrawType == RotDrawMode.Fresh) { shader = ___pawn.Drawer.renderer.graphics.nakedGraphic.Shader; if (!ShaderUtility.SupportsMaskTex(shader)) shader = ShaderDatabase.CutoutSkinOverlay; skinColor = ___pawn.Drawer.renderer.graphics.nakedGraphic.Color; skinColor2 = ___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; skinColor = ___pawn.Drawer.renderer.graphics.rottingGraphic.Color; skinColor2 = ___pawn.Drawer.renderer.graphics.nakedGraphic.ColorTwo; } if (flags.FlagSet(PawnRenderFlags.StylingStation))//Styling station doesn't affect to real pawn data. so cannot cache to component. { } //breasts are only rendered when all of worn apparels are supported or nude. if (apparelRecorder.isDrawAge && (!flags.FlagSet(PawnRenderFlags.Clothes) || !apparelRecorder.hasUnsupportedApparel || SizedApparelUtility.isPawnNaked(___pawn))) //TODO : Move it to CanDraw { if (bodyDrawType != RotDrawMode.Dessicated && SizedApparelSettings.drawVagina && SizedApparelUtility.CanDrawVagina(___pawn, flags)) { if(apparelRecorder.bodyPartVagina != null) apparelRecorder.bodyPartVagina.DrawBodyPart(rootLoc, angle, facing, bodyDrawType, flags, bodyMesh); /* //Draw Vagina. AllwaysDraw Vector3 vector = rootLoc; if (facing == Rot4.North) vector.y += 0.0100f;//not sure what to do else vector.y += 0.0088f; Graphic graphic = null; if (SizedApparelUtility.IsHorny(___pawn)) graphic = apparelRecorder.graphicVagina_horny; if (graphic == null) graphic = apparelRecorder.graphicVagina; if (graphic != null) { Material mat; if (!flags.FlagSet(PawnRenderFlags.Cache)) { graphic = graphic.GetColoredVersion(graphic.Shader, skinColor, skinColor2); mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, 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, skinColor, skinColor2); vector.y += 0.00001f; mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, new object[] { graphic.MatAt(facing), ___pawn, flags.FlagSet(PawnRenderFlags.Portrait) }); GenDraw.DrawMeshNowOrLater(bodyMesh, vector, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow)); }*/ } if (bodyDrawType != RotDrawMode.Dessicated && SizedApparelSettings.drawAnus && SizedApparelUtility.CanDrawAnus(___pawn, flags)) { if (apparelRecorder.bodyPartAnus != null) apparelRecorder.bodyPartAnus.DrawBodyPart(rootLoc, angle, facing, bodyDrawType, flags, bodyMesh); /* //Draw Anus. //Allways draw Vector3 vector = rootLoc; if (facing == Rot4.North) vector.y += 0.0105f;//not sure what to do else vector.y += 0.0093f; Graphic graphic = null; if (SizedApparelUtility.IsHorny(___pawn)) graphic = apparelRecorder.graphicAnus_horny; if (graphic == null) graphic = apparelRecorder.graphicAnus; if (graphic != null) { Material mat; if (!flags.FlagSet(PawnRenderFlags.Cache)) { graphic = graphic.GetColoredVersion(graphic.Shader, skinColor, skinColor2); mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, 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, skinColor, skinColor2); vector.y += 0.00001f; mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, new object[] { graphic.MatAt(facing), ___pawn, flags.FlagSet(PawnRenderFlags.Portrait) }); GenDraw.DrawMeshNowOrLater(bodyMesh, vector, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow)); }*/ } if (bodyDrawType != RotDrawMode.Dessicated && SizedApparelSettings.drawBelly && SizedApparelUtility.CanDrawBelly(___pawn, flags)) { if (apparelRecorder.bodyPartBelly != null) apparelRecorder.bodyPartBelly.DrawBodyPart(rootLoc, angle, facing, bodyDrawType, flags, bodyMesh); /* //Draw Belly. Need Complex Hiding Calculation Vector3 vector = rootLoc; if (facing == Rot4.North) vector.y += 0.0002f;//not sure what to do else vector.y += 0.0098f; Graphic graphic = apparelRecorder.graphicBelly; if (graphic != null) { Material mat; if (!flags.FlagSet(PawnRenderFlags.Cache)) { graphic = graphic.GetColoredVersion(graphic.Shader, skinColor, skinColor2); mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, 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, skinColor, skinColor2); vector.y += 0.00001f; mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, new object[] { graphic.MatAt(facing), ___pawn, flags.FlagSet(PawnRenderFlags.Portrait) }); GenDraw.DrawMeshNowOrLater(bodyMesh, vector, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow)); }*/ } if (bodyDrawType != RotDrawMode.Dessicated && SizedApparelSettings.drawUdder && SizedApparelUtility.CanDrawUdder(___pawn, flags)) { if (apparelRecorder.bodyPartUdder != null) apparelRecorder.bodyPartUdder.DrawBodyPart(rootLoc, angle, facing, bodyDrawType, flags, bodyMesh); //Draw Udder. Need Complex Hiding Calculation -> /* Vector3 vector = rootLoc; if (facing == Rot4.North) vector.y += 0.0015f;//not sure what to do else vector.y += 0.0088f; Graphic graphic = null; if (SizedApparelUtility.IsHorny(___pawn)) graphic = apparelRecorder.graphicUdder_horny; if (graphic == null) graphic = apparelRecorder.graphicUdder; if (graphic != null) { Material mat; if (!flags.FlagSet(PawnRenderFlags.Cache)) { graphic = graphic.GetColoredVersion(graphic.Shader, skinColor, skinColor2); mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, 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, skinColor, skinColor2); vector.y += 0.00001f; mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, new object[] { graphic.MatAt(facing), ___pawn, flags.FlagSet(PawnRenderFlags.Portrait) }); GenDraw.DrawMeshNowOrLater(bodyMesh, vector, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow)); }*/ } if (bodyDrawType != RotDrawMode.Dessicated && SizedApparelSettings.drawBreasts && SizedApparelUtility.CanDrawBreasts(___pawn, flags) && (SizedApparelSettings.drawSizedApparelBreastsOnlyWorn ? !SizedApparelUtility.isPawnNaked(___pawn, flags) : true)) { if (apparelRecorder.bodyPartBreasts != null) apparelRecorder.bodyPartBreasts.DrawBodyPart(rootLoc, angle, facing, bodyDrawType, flags, bodyMesh); //Log.Message("DrawBreasts for " + ___pawn.Name); //if (SizedApparelSettings.Debug) // Log.Message("trying to draw breasts"); //Draw Breasts. Allways draw /* Vector3 vector = rootLoc; if (facing == Rot4.North) vector.y += 0.001f;//not sure what to do else vector.y += 0.0113f; Graphic graphic = null; if (SizedApparelUtility.IsHorny(___pawn)) graphic = apparelRecorder.graphicBreasts_horny; if (graphic == null) graphic = apparelRecorder.graphicBreasts; if (graphic != null) { Material mat; if (!flags.FlagSet(PawnRenderFlags.Cache)) { graphic = graphic.GetColoredVersion(graphic.Shader, skinColor, skinColor2); mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, 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, skinColor, skinColor2); vector.y += 0.00001f; mat = flags.FlagSet(PawnRenderFlags.Cache) ? graphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, new object[] { graphic.MatAt(facing), ___pawn, flags.FlagSet(PawnRenderFlags.Portrait) }); GenDraw.DrawMeshNowOrLater(bodyMesh, vector, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow)); } else { //Log.Warning("[SizedApparel] Missing Breasts Graphic for: " + ___pawn.Name); } */ } if (bodyDrawType != RotDrawMode.Dessicated && SizedApparelSettings.drawPenis && SizedApparelUtility.CanDrawPenis(___pawn, flags, true)) { foreach(SizedApparelBodyPart b in apparelRecorder.bodyPartBalls) { b.DrawBodyPart(rootLoc, angle, facing, bodyDrawType, flags, bodyMesh); } foreach (SizedApparelBodyPart b in apparelRecorder.bodyPartPenises) { b.DrawBodyPart(rootLoc, angle, facing, bodyDrawType, flags, bodyMesh); } /* //Render Penis And Balls Vector3 vector = rootLoc; if (facing == Rot4.North) vector.y += 0.0025f; else vector.y += 0.0108f; float offsetX = 0; // right and left float offsetZ = 0; // up and down if(apparelRecorder.graphicPenises != null && apparelRecorder.graphicBallsOfPenises != null) { for (int i = 0; i < apparelRecorder.graphicPenises.Count; i++) { float t = (i + 1f) / (apparelRecorder.graphicPenises.Count + 1); offsetX = Mathf.Lerp(-0.1f, 0.1f, t); offsetZ = Mathf.Lerp(-0.05f, 0.05f, t); Graphic penisGraphic = null; Graphic ballGraphic = null; if (SizedApparelUtility.IsHorny(___pawn)) { penisGraphic = apparelRecorder.graphicPenises_horny[i]; } if (penisGraphic == null) penisGraphic = apparelRecorder.graphicPenises[i]; ballGraphic = apparelRecorder.graphicBallsOfPenises[i];//Balls Doesn't support HornyVariation if (ballGraphic != null && (SizedApparelSettings.hideBallOfFuta ? Genital_Helper.is_futa(___pawn) : true)) { Material mat; //TODO: vector2.y Vector3 vector2 = vector; if (facing == Rot4.North) vector2.y += 0.0060f; else vector2.y -= 0.0012f; if (facing == Rot4.North || facing == Rot4.South) vector2.x += offsetX; else vector2.x += offsetX * 0.5f; if (facing == Rot4.East) vector2.z += offsetZ; if (facing == Rot4.West) vector2.z -= offsetZ; if (!flags.FlagSet(PawnRenderFlags.Cache)) { ballGraphic = ballGraphic.GetColoredVersion(ballGraphic.Shader, skinColor, skinColor2); mat = flags.FlagSet(PawnRenderFlags.Cache) ? ballGraphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, new object[] { ballGraphic.MatAt(facing), ___pawn, flags.FlagSet(PawnRenderFlags.Portrait) }); GenDraw.DrawMeshNowOrLater(bodyMesh, vector2, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow)); // draw for writeZ data to solve shadow issue } ballGraphic = ballGraphic.GetColoredVersion(shader, skinColor, skinColor2); vector2.y += 0.00001f; mat = flags.FlagSet(PawnRenderFlags.Cache) ? ballGraphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, new object[] { ballGraphic.MatAt(facing), ___pawn, flags.FlagSet(PawnRenderFlags.Portrait) }); GenDraw.DrawMeshNowOrLater(bodyMesh, vector2, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow)); } if (penisGraphic != null) { Material mat; Vector3 vector2 = vector; if (facing == Rot4.North || facing == Rot4.South) vector2.x += offsetX; else vector2.x += offsetX * 0.5f; if (facing == Rot4.East) vector2.z += offsetZ; if (facing == Rot4.West) vector2.z -= offsetZ; if (!flags.FlagSet(PawnRenderFlags.Cache)) { penisGraphic = penisGraphic.GetColoredVersion(penisGraphic.Shader, skinColor, skinColor2); mat = flags.FlagSet(PawnRenderFlags.Cache) ? penisGraphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, new object[] { penisGraphic.MatAt(facing), ___pawn, flags.FlagSet(PawnRenderFlags.Portrait) }); GenDraw.DrawMeshNowOrLater(bodyMesh, vector2, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow)); // draw for writeZ data to solve shadow issue } penisGraphic = penisGraphic.GetColoredVersion(shader, skinColor, skinColor2); //TODO: vector2.y vector2.y += 0.00001f; mat = flags.FlagSet(PawnRenderFlags.Cache) ? penisGraphic.MatAt(facing) : (Material)overrideMatMethod.Invoke(__instance, new object[] { penisGraphic.MatAt(facing), ___pawn, flags.FlagSet(PawnRenderFlags.Portrait) }); GenDraw.DrawMeshNowOrLater(bodyMesh, vector2, quaternion, mat, flags.FlagSet(PawnRenderFlags.DrawNow)); } } }*/ }//Draw BodyParts //Draw Modular Apparel Parts if (flags.FlagSet(PawnRenderFlags.Clothes)) { } } } } //TODO [HarmonyPatch(typeof(PawnRenderer), "BaseHeadOffsetAt")] public class HeadOffsetPatch { public static void Postfix(PawnRenderer __instance, Pawn ___pawn, Rot4 rotation, ref Vector3 __result) { var comp = ___pawn.TryGetComp(); if (comp == null) return; } } [Obsolete] public class DrawPawnPatch { public static void TryDrawBodyPart(ref PawnRenderer __instance,Graphic graphic,Graphic hornyGraphic, Vector3 rootLoc, Vector3 drawOffset, float angle, bool renderBody, Rot4 bodyFacing, Rot4 headFacing, RotDrawMode bodyDrawType, bool portrait, bool headStump, bool invisible) { } public static void RenderPawnInternalPrefix(ref PawnRenderer __instance, Vector3 rootLoc, float angle, bool renderBody, Rot4 bodyFacing, Rot4 headFacing, RotDrawMode bodyDrawType, bool portrait, bool headStump, bool invisible, Pawn ___pawn) { if (!__instance.graphics.AllResolved) { __instance.graphics.ResolveAllGraphics(); } if (!SizedApparelSettings.drawBodyParts) return; if (___pawn == null) return; ApparelRecorderComp apparelRecorder = ___pawn.TryGetComp(); if (apparelRecorder == null) return; if (!apparelRecorder.hasUpdateBefore || apparelRecorder.isDirty) { if (SizedApparelSettings.Debug) Log.Message("[SizedApparel] trying to draw " + ___pawn.Name + " with unupdated component! Updating it."); apparelRecorder.Update(true,false); SizedApparelUtility.UpdateAllApparel(___pawn); } if (apparelRecorder.needToCheckApparelGraphicRecords) { if(apparelRecorder.isApparelGraphicRecordChanged()) { //apparelRecorder.Update(true, true); //1.3 //SizedApparelUtility.UpdateAllApparel(___pawn, true); } } if (renderBody) { BodyPatch.SetBodyGraphic(___pawn,true, false); } } //Draw Private parts public static void RenderPawnInternalPostfix(ref PawnRenderer __instance, Vector3 rootLoc, float angle, bool renderBody, Rot4 bodyFacing, Rot4 headFacing, RotDrawMode bodyDrawType, bool portrait, bool headStump, bool invisible, Pawn ___pawn) { if (___pawn == null) return; ApparelRecorderComp apparelRecorder = ___pawn.TryGetComp(); if (apparelRecorder == null) return; Quaternion quaternion = Quaternion.AngleAxis(angle, Vector3.up); Mesh mesh = null; if (!SizedApparelSettings.drawBodyParts) { /* if (SizedApparelPatch.rimNudeWorldActive && SizedApparelSettings.drawSizedApparelBreastsOnlyWorn && !SizedApparelUtility.isPawnNaked(___pawn)) { //TODO if (__instance.graphics == null) return; if (bodyDrawType == RotDrawMode.Dessicated) //don't draw on skeletone return; if (___pawn.RaceProps.Humanlike)//this.pawn.RaceProps.Humanlike { mesh = MeshPool.humanlikeBodySet.MeshAt(bodyFacing); } else { mesh = __instance.graphics.nakedGraphic.MeshAt(bodyFacing); } string defName = __instance.graphics.pawn.def.defName; Vector3 loc = rootLoc; loc.y += 0.009183673f; Vector3 vector = rootLoc; if (bodyFacing == Rot4.North) vector.y += 0.001f;//not sure what to do else vector.y += 0.012f; Graphic graphic = null; if (SizedApparelUtility.IsHorny(___pawn)) graphic = apparelRecorder.graphicBreasts_horny; if (graphic == null) graphic = apparelRecorder.graphicBreasts; if (graphic != null) { Material breastMat = graphic.MatAt(bodyFacing, null); Material baseMat = (!portrait && ___pawn.IsInvisible()) ? InvisibilityMatPool.GetInvisibleMat(breastMat) : breastMat; breastMat = __instance.graphics.flasher.GetDamagedMat(baseMat); GenDraw.DrawMeshNowOrLater(mesh, vector, quaternion, breastMat, portrait); } } */ return; } if (renderBody) { if (__instance.graphics == null) return; if (bodyDrawType == RotDrawMode.Dessicated) //don't draw on skeletone return; if (___pawn.RaceProps.Humanlike)//this.pawn.RaceProps.Humanlike { mesh = MeshPool.humanlikeBodySet.MeshAt(bodyFacing); } else { mesh = __instance.graphics.nakedGraphic.MeshAt(bodyFacing); } string defName = __instance.graphics.pawn.def.defName; Vector3 loc = rootLoc; loc.y += 0.009183673f; //breasts are only rendered when all of worn apparels are supported or nude. if (!apparelRecorder.hasUnsupportedApparel || SizedApparelUtility.isPawnNaked(___pawn)) //TODO : Move it to CanDraw { //string bodyPartPath = "SizedApparel/BodyParts"; //string breastsPath; //Hediff breastHediff = apparelRecorder.breastHediff; //float breastHediffSeverityCap = apparelRecorder.breastSeverityCapToDraw; //string breastName = breastHediff.def.defName;//Todo //breastsPath = "SizedApparel/BodyParts/Breasts/Human/testBodyPart_Female"; /* if ((ContentFinder.Get((breastsPath + "_south"), false) != null)) { Vector3 vector = rootLoc; if (bodyFacing == Rot4.North) vector = vector; else vector.y += 0.0092f; Graphic bodyPartGraphic = GraphicDatabase.Get(breastsPath, ShaderDatabase.Cutout); Material bodyPartMat = bodyPartGraphic.MatAt(bodyFacing, null); //bodyPartMat = __instance.OverrideMaterialIfNeeded_NewTemp(bodyPartMat, __instance.pawn, portrait);//private function and values //for damage mat or somthing more Material baseMat = (!portrait && pawn.IsInvisible()) ? InvisibilityMatPool.GetInvisibleMat(bodyPartMat) : bodyPartMat; bodyPartMat = __instance.graphics.flasher.GetDamagedMat(baseMat); GenDraw.DrawMeshNowOrLater(mesh, vector, quaternion, bodyPartMat, portrait); } else { if (SizedApparelSettings.Debug) Log.Warning("[Sized Apparel] Missing Breast Tesxture: " + breastsPath); //breastName = "Breasts"; } */ if(SizedApparelSettings.drawBreasts && (SizedApparelSettings.drawSizedApparelBreastsOnlyWorn ? !SizedApparelUtility.isPawnNaked(___pawn): true)) { //Log.Message("DrawBreasts for " + ___pawn.Name); //if (SizedApparelSettings.Debug) // Log.Message("trying to draw breasts"); //Draw Breasts. Allways draw Vector3 vector = rootLoc; if (bodyFacing == Rot4.North) vector.y += 0.001f;//not sure what to do else vector.y += 0.012f; Graphic graphic = null; if (SizedApparelUtility.IsHorny(___pawn)) graphic = apparelRecorder.graphicBreasts_horny; if(graphic == null) graphic = apparelRecorder.graphicBreasts; /* if(graphic == null) { apparelRecorder.Update(); if (SizedApparelUtility.IsHorny(___pawn)) graphic = apparelRecorder.graphicBreasts_horny; if (graphic == null) graphic = apparelRecorder.graphicBreasts; }*/ if (graphic != null) { Material mat = graphic.MatAt(bodyFacing, null); Material baseMat = (!portrait && ___pawn.IsInvisible()) ? InvisibilityMatPool.GetInvisibleMat(mat) : mat; mat = __instance.graphics.flasher.GetDamagedMat(baseMat); GenDraw.DrawMeshNowOrLater(mesh, vector, quaternion, mat, portrait); } else { //Log.Warning("[SizedApparel] Missing Breasts Graphic for: " + ___pawn.Name); } } if(SizedApparelSettings.drawVagina && SizedApparelUtility.CanDrawVagina(___pawn)) { //Draw Vagina. AllwaysDraw Vector3 vector = rootLoc; if (bodyFacing == Rot4.North) vector.y += 0.0100f;//not sure what to do else vector.y += 0.0100f; Graphic graphic = null; if (SizedApparelUtility.IsHorny(___pawn)) graphic = apparelRecorder.graphicVagina_horny; if (graphic == null) graphic = apparelRecorder.graphicVagina; if (graphic != null) { Material mat = graphic.MatAt(bodyFacing, null); Material baseMat = (!portrait && ___pawn.IsInvisible()) ? InvisibilityMatPool.GetInvisibleMat(mat) : mat; mat = __instance.graphics.flasher.GetDamagedMat(baseMat); GenDraw.DrawMeshNowOrLater(mesh, vector, quaternion, mat, portrait); } } if(SizedApparelSettings.drawAnus && SizedApparelUtility.CanDrawAnus(___pawn)) { //Draw Anus. //Allways draw Vector3 vector = rootLoc; if (bodyFacing == Rot4.North) vector.y += 0.0105f;//not sure what to do else vector.y += 0.010f; Graphic graphic = null; if (SizedApparelUtility.IsHorny(___pawn)) graphic = apparelRecorder.graphicAnus_horny; if (graphic == null) graphic = apparelRecorder.graphicAnus; if (graphic != null) { Material mat = graphic.MatAt(bodyFacing, null); Material baseMat = (!portrait && ___pawn.IsInvisible()) ? InvisibilityMatPool.GetInvisibleMat(mat) : mat; mat = __instance.graphics.flasher.GetDamagedMat(baseMat); GenDraw.DrawMeshNowOrLater(mesh, vector, quaternion, mat, portrait); } } if (SizedApparelSettings.drawUdder && SizedApparelUtility.CanDrawUdder(___pawn)) { //Draw Udder. Need Complex Hiding Calculation -> Vector3 vector = rootLoc; if (bodyFacing == Rot4.North) vector.y += 0.0015f;//not sure what to do else vector.y += 0.0095f; Graphic graphic = null; if (SizedApparelUtility.IsHorny(___pawn)) graphic = apparelRecorder.graphicUdder_horny; if (graphic == null) graphic = apparelRecorder.graphicUdder; if (graphic != null) { Material mat = graphic.MatAt(bodyFacing, null); Material baseMat = (!portrait && ___pawn.IsInvisible()) ? InvisibilityMatPool.GetInvisibleMat(mat) : mat; mat = __instance.graphics.flasher.GetDamagedMat(baseMat); GenDraw.DrawMeshNowOrLater(mesh, vector, quaternion, mat, portrait); } } if(SizedApparelSettings.drawBelly && SizedApparelUtility.CanDrawBelly(___pawn)) { //Draw Belly. Need Complex Hiding Calculation Vector3 vector = rootLoc; if (bodyFacing == Rot4.North) vector.y += 0.0002f;//not sure what to do else vector.y += 0.0105f; Graphic graphic = apparelRecorder.graphicBelly; if (graphic != null) { Material mat = graphic.MatAt(bodyFacing, null); Material baseMat = (!portrait && ___pawn.IsInvisible()) ? InvisibilityMatPool.GetInvisibleMat(mat) : mat; mat = __instance.graphics.flasher.GetDamagedMat(baseMat); GenDraw.DrawMeshNowOrLater(mesh, vector, quaternion, mat, portrait); } } //Rimworld 1.2 doesn't have PawnRenderFlags! if (SizedApparelSettings.drawPenis && SizedApparelUtility.CanDrawPenis(___pawn,PawnRenderFlags.None, false)) { //Render Penis And Balls Vector3 vector = rootLoc; if (bodyFacing == Rot4.North) vector.y += 0.0025f; else vector.y += 0.015f; float offsetX = 0; for (int i = 0; i < apparelRecorder.graphicPenises.Count; i++) { float t = (i + 1f) / (apparelRecorder.graphicPenises.Count + 1); offsetX = Mathf.Lerp(-0.1f, 0.1f, t); Graphic penisGraphic = null; Graphic ballGraphic = null; if (SizedApparelUtility.IsHorny(___pawn)) { penisGraphic = apparelRecorder.graphicPenises_horny[i]; } if (penisGraphic == null) penisGraphic = apparelRecorder.graphicPenises[i]; ballGraphic = apparelRecorder.graphicBallsOfPenises[i];//Balls Doesn't support HornyVariation if (penisGraphic != null) { //TODO: vector2.y Vector3 vector2 = vector; vector2.x += offsetX; Material mat = penisGraphic.MatAt(bodyFacing, null); Material baseMat = (!portrait && ___pawn.IsInvisible()) ? InvisibilityMatPool.GetInvisibleMat(mat) : mat; mat = __instance.graphics.flasher.GetDamagedMat(baseMat); GenDraw.DrawMeshNowOrLater(mesh, vector2, quaternion, mat, portrait); } if (SizedApparelSettings.hideBallOfFuta) if (Genital_Helper.is_futa(___pawn)) continue;//skip rendering ball if (ballGraphic != null) { //TODO: vector2.y Vector3 vector2 = vector; if (bodyFacing == Rot4.North) vector2.y += 0.0080f; else vector2.y -= 0.002f; vector2.x += offsetX; Material mat = ballGraphic.MatAt(bodyFacing, null); Material baseMat = (!portrait && ___pawn.IsInvisible()) ? InvisibilityMatPool.GetInvisibleMat(mat) : mat; mat = __instance.graphics.flasher.GetDamagedMat(baseMat); GenDraw.DrawMeshNowOrLater(mesh, vector2, quaternion, mat, portrait); } } } } } } } }