From 96bcaeb8297db897f6133e57b5e1573e38b3cd30 Mon Sep 17 00:00:00 2001 From: nugerumon <18164-nuganee@users.noreply.gitgud.io> Date: Sat, 15 Jan 2022 23:09:36 +0000 Subject: [PATCH] Styling Station, mostly --- 1.3 Assembly/Assemblies/RimNudeWorld.dll | Bin 22016 -> 33280 bytes .../RimNudeWorld/RimNudeWorld.csproj | 11 +- .../patches/HarmonyPatch_GetErect.cs | 6 +- .../patches/Ideology/StylingStation.cs | 397 ++++++++++++++++++ 4 files changed, 407 insertions(+), 7 deletions(-) create mode 100644 Source/RimNudeWorld/RimNudeWorld/patches/Ideology/StylingStation.cs diff --git a/1.3 Assembly/Assemblies/RimNudeWorld.dll b/1.3 Assembly/Assemblies/RimNudeWorld.dll index 9f60a2b3d8b3f19657bf01d3619bc085432888ab..d1544c675f5d0d0ccf781f2d627a33dc23b6a024 100644 GIT binary patch literal 33280 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 literal 22016 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 HXMz6&&>VZB diff --git a/Source/RimNudeWorld/RimNudeWorld/RimNudeWorld.csproj b/Source/RimNudeWorld/RimNudeWorld/RimNudeWorld.csproj index 59d7d3f..e7906a1 100644 --- a/Source/RimNudeWorld/RimNudeWorld/RimNudeWorld.csproj +++ b/Source/RimNudeWorld/RimNudeWorld/RimNudeWorld.csproj @@ -47,7 +47,7 @@ False - ..\..\..\..\RJW-4.8.2\1.3\Assemblies\RJW.dll + ..\..\..\..\rjw\1.3\Assemblies\RJW.dll False @@ -56,20 +56,21 @@ - - ..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.dll - False - ..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.CoreModule.dll False + + ..\..\..\..\..\RimWorldWin64_Data\Managed\UnityEngine.IMGUIModule.dll + False + + diff --git a/Source/RimNudeWorld/RimNudeWorld/patches/HarmonyPatch_GetErect.cs b/Source/RimNudeWorld/RimNudeWorld/patches/HarmonyPatch_GetErect.cs index 6c1204f..c8e839e 100644 --- a/Source/RimNudeWorld/RimNudeWorld/patches/HarmonyPatch_GetErect.cs +++ b/Source/RimNudeWorld/RimNudeWorld/patches/HarmonyPatch_GetErect.cs @@ -21,6 +21,7 @@ namespace RimNudeWorld Harmony har = new Harmony("RimNudeWorld"); har.PatchAll(Assembly.GetExecutingAssembly()); + PubesManager.PatchStylingStation(har); } } @@ -71,9 +72,10 @@ namespace RimNudeWorld return; } - else if (NudeSettings.pubicHair && originalPath.Length >= 5 && originalPath.Contains("Pubes")) + // if pawn can not do lovin, or pubicHair is supposed to be hidden, use shaved texture + else if ((NudeSettings.pubicHair || (rjw.xxx.is_human(pawn) && !rjw.xxx.can_do_loving(pawn))) && originalPath.Length >= 5 && originalPath.Contains("Pubes")) { - + __result = GraphicDatabase.Get("Genitals/Pubes/Shaved", __result.Shader, __result.drawSize, __result.color, __result.colorTwo); return; diff --git a/Source/RimNudeWorld/RimNudeWorld/patches/Ideology/StylingStation.cs b/Source/RimNudeWorld/RimNudeWorld/patches/Ideology/StylingStation.cs new file mode 100644 index 0000000..cf24942 --- /dev/null +++ b/Source/RimNudeWorld/RimNudeWorld/patches/Ideology/StylingStation.cs @@ -0,0 +1,397 @@ +using System; +using System.Collections.Generic; +using HarmonyLib; +using RimWorld; +using Verse; +using System.Reflection; +using System.Reflection.Emit; +using UnityEngine; +using AlienRace; +using System.Linq; +using Verse.Sound; + +namespace RimNudeWorld +{ + [StaticConstructorOnStartup] + static class PubesManager + { + public static Dictionary> all_pubes; + + public static int curpawnid; + public static string curgraphicspath; + public static int curvariant; + public static int curcompindex; + + static PubesManager() + { + // find all pubes that exist, sorted by race name + all_pubes = new Dictionary>(); + + foreach (ThingDef_AlienRace race in DefDatabase.AllDefsListForReading) + { + if (!all_pubes.ContainsKey(race.defName)) + { + all_pubes.Add(race.defName, new List()); + } + + List ba_pubes = race?.alienRace?.generalSettings?.alienPartGenerator?.bodyAddons.Where(x => x.bodyPart == "Genitals" && x.path.ToLower().Contains("pubes")).ToList(); + if (ba_pubes == null || ba_pubes.Count() <= 0) + continue; + + foreach (AlienPartGenerator.BodyAddon ba in ba_pubes) + { + all_pubes[race.defName].Add(ba); + } + } + + if (NudeSettings.debugMode) + { + foreach (string k in all_pubes.Keys) + { + foreach (AlienPartGenerator.BodyAddon b in all_pubes[k]) + { + Log.Message("> " + k + " : " + b.path + " (" + b.variantCount.ToString() + " Variants)"); + } + } + } + } + + public static void PatchStylingStation(Harmony h) + { + // when opening styling station window (i.e. on constructor), save current pubes of pawn + // figuring out how to postfix constructor was a pita + MethodBase StylingStationConstructor = (MethodBase)(typeof(Dialog_StylingStation).GetMember(".ctor", AccessTools.all)[0]); + MethodInfo savePubes = typeof(PubesManager).GetMethod("saveCurPubes"); + h.Patch(StylingStationConstructor, null, new HarmonyMethod(savePubes)); + + // prefix to restoring pubes, as end of reset() function has some mark-as-dirty stuff + MethodInfo StylingStationReset = typeof(Dialog_StylingStation).GetMethod("Reset", AccessTools.all); + MethodInfo ResetPubes = typeof(PubesManager).GetMethod("restorePubes"); + h.Patch(StylingStationReset, new HarmonyMethod(ResetPubes)); + } + + public static void saveCurPubes(Pawn pawn, Thing stylingStation) + { + // invalidate potentially saved variables in case of error, so resetting doesn't try to set pubes from previous styling station user + curpawnid = -1; + + // get AlienComp + AlienPartGenerator.AlienComp comp = pawn.GetComp(); + if (comp == null) + { + if (NudeSettings.debugMode) + Log.Message("Pawn has no AlienComp"); + return; + } + + // determine pawn's "equipped" pubes + List addonGraphics = new List(comp.addonGraphics); + List addonVariants = new List(comp.addonVariants); + if (addonGraphics.Count() != addonVariants.Count()) + { + if (NudeSettings.debugMode) + Log.Message("addonGraphics and addonVariants not same length"); + return; + } + string mygraphicspath = ""; + int myvariant = -1; + int compindex = -1; + for (int i = 0; i < addonGraphics.Count(); i++) + { + if (addonGraphics[i].path.ToLower().Contains("pubes")) + { + mygraphicspath = addonGraphics[i].path; + myvariant = addonVariants[i]; + compindex = i; + break; + } + } + + // save + curpawnid = pawn.thingIDNumber; + curgraphicspath = mygraphicspath; + curvariant = myvariant; + curcompindex = compindex; + } + public static bool restorePubes(bool resetColors, Dialog_StylingStation __instance) + { + // Reset() is called with parameter resetColors==true when either "Cancel" or "Reset" buttons are clicked + // Reset() might be called with parameter resetColors==false when "Accept" is clicked + // -> if resetColors==true, reset pubes to original style + if (NudeSettings.debugMode) + Log.Message("Restoring Pubes: " + resetColors.ToString()); + if (resetColors) + { + Pawn p = AccessTools.FieldRefAccess(__instance, "pawn"); + if (p.thingIDNumber == curpawnid) + { + // get AlienComp + AlienPartGenerator.AlienComp comp = p.GetComp(); + if (comp == null) + { + if (NudeSettings.debugMode) + Log.Message("Pawn has no AlienComp"); + return true; + } + comp.addonVariants[curcompindex] = curvariant; + } + } + + return true; + } + + } + + [HarmonyPatch(typeof(Dialog_StylingStation), "DrawTabs")] + class StylingStation + { + + public static void Postfix(Rect rect, ref Vector2 ___hairScrollPosition, Dialog_StylingStation __instance, List ___tabs, Dialog_StylingStation.StylingTab ___curTab, float ___viewRectHeight, List ___tmpStyleItems, bool ___devEditMode, Pawn ___pawn) + { + switch (___curTab) + { + case (Dialog_StylingStation.StylingTab)48: // was 24 + + //Draw PubicHair Tab Code here! + DrawStylingTypePubicHair(__instance, rect, ref ___hairScrollPosition); + + return; + default: + return; + } + } + + public static float[] zoomOffsets() + { + // have these offsets be returned by a public function so mods adding larger pubes (or pubes that are offset) can change them easily + return new float[4]{.5f, .17f, 2f, 2f }; + } + + static void DrawStylingTypePubicHair(Dialog_StylingStation dialog_StylingStation, Rect rect, ref Vector2 scrollPosition) + { + // access all the variables needed... + //float viewRectHeight = AccessTools.FieldRefAccess(dialog_StylingStation, "viewRectHeight"); + //bool devEditMode = AccessTools.FieldRefAccess(dialog_StylingStation, "devEditMode"); + Color desiredHairColor = AccessTools.FieldRefAccess(dialog_StylingStation, "desiredHairColor"); + //MethodInfo DrawHairColors = AccessTools.Method(typeof(Dialog_StylingStation), "DrawHairColors"); + + Pawn pawn = AccessTools.FieldRefAccess(dialog_StylingStation, "pawn"); + + // get available pubes + ThingDef_AlienRace race = pawn.def as ThingDef_AlienRace; + + // determine number of available pubes + int total_pubes_count = 0; + foreach (AlienPartGenerator.BodyAddon pube in PubesManager.all_pubes[race.defName]) + { + total_pubes_count += pube.variantCount; + } + + if (total_pubes_count <= 0) + { + Widgets.NoneLabelCenteredVertically(rect, "(" + "NoneUsableForPawn".Translate(pawn.Named("PAWN")) + ")"); + return; + } + + // get AlienComp + AlienPartGenerator.AlienComp comp = pawn.GetComp(); + if (comp == null) + { + if (NudeSettings.debugMode) + Log.Message("Pawn has no AlienComp"); + return; + } + + // determine pawn's "equipped" pubes + List addonGraphics = new List(comp.addonGraphics); + List addonVariants = new List(comp.addonVariants); + if (addonGraphics.Count() != addonVariants.Count()) + { + if(NudeSettings.debugMode) + Log.Message("addonGraphics and addonVariants not same length"); + return; + } + string mygraphicspath = ""; + int myvariant = -1; + int compindex = -1; + for (int i = 0; i < addonGraphics.Count(); i++) + { + if (addonGraphics[i].path.ToLower().Contains("pubes")) + { + mygraphicspath = addonGraphics[i].path; + myvariant = addonVariants[i]; + compindex = i; + break; + } + } + //Log.Message("current pubes: " + mygraphicspath + " / " + myvariant.ToString()); + + const float btn_size = 70f; // how much space is reserverd for on icon, including border / distance to next // to mimic vanilla, use 70 + int items_per_row = Mathf.FloorToInt((rect.width - 16) / btn_size); + int total_rows = Mathf.CeilToInt(total_pubes_count / items_per_row); + + Rect viewRect = new Rect(rect.x, rect.y, rect.width - 16f, total_rows * btn_size); + float border_space = ((rect.width - 16f) - (items_per_row * btn_size)) / 2; + + Vector2 currentDrawPos = new Vector2(rect.x + border_space, rect.y); + + Widgets.BeginScrollView(rect, ref scrollPosition, viewRect, true); + + foreach (AlienPartGenerator.BodyAddon pube in PubesManager.all_pubes[race.defName]) + { + for (int i = 0; i < pube.variantCount; i++) + { + // if larger than initial position and next would go too far right, go to new line + if (currentDrawPos.x > rect.x+border_space && currentDrawPos.x+btn_size > rect.x + rect.width - 16) + { + currentDrawPos.x = rect.x + border_space; + currentDrawPos.y += btn_size; + } + + Rect rect_outer = new Rect(currentDrawPos.x, currentDrawPos.y, btn_size-10, btn_size-10); + + string _path = pube.path + ((i == 0) ? "" : i.ToString()); + + Texture2D pubes_texture = ContentFinder.Get(_path+"_south"); + + Widgets.DrawHighlight(rect_outer); + if (mygraphicspath == _path || mygraphicspath==(_path+"_Female")) + { + // draw box around currently "equipped" pubes + Widgets.DrawBox(rect_outer, 2); + } + if (Mouse.IsOver(rect_outer)) + { + Widgets.DrawHighlight(rect_outer); + //TooltipHandler.TipRegion(rect2, styleItemDef.LabelCap); + } + + if (Widgets.ButtonInvisible(rect_outer, true)) + { + // this button applies the pubes + comp.addonVariants[compindex] = i; + + SoundDefOf.Tick_High.PlayOneShotOnCamera(); + pawn.Drawer.renderer.graphics.SetAllGraphicsDirty(); + PortraitsCache.SetDirty(pawn); + } + + // actually paint pubes + GUI.color = desiredHairColor; + Rect zoomRect = new Rect(rect_outer.x - zoomOffsets()[0] * rect_outer.width, + rect_outer.y - zoomOffsets()[1] * rect_outer.height, + zoomOffsets()[2] * rect_outer.width, + zoomOffsets()[3] * rect_outer.height); + GUI.DrawTexture(zoomRect, pubes_texture); + GUI.color = Color.white; + + currentDrawPos.x += btn_size; + } + } + + Widgets.EndScrollView(); + + // draw hair colors with inlined dye requirements + // just copypasted from vanilla + Rect newrect = new Rect(rect.x, rect.yMax - 100f, rect.width, 110f); + + Color _desiredHairColor = desiredHairColor; + + float num = newrect.y; + Widgets.ColorSelector(new Rect(newrect.x, num, newrect.width, 92f), ref _desiredHairColor, AllHairColors, null, 22, 2); + if (_desiredHairColor != desiredHairColor) + { + var desiredHairColor_ = dialog_StylingStation.GetType().GetField("desiredHairColor", System.Reflection.BindingFlags.NonPublic + | System.Reflection.BindingFlags.Instance); + desiredHairColor_.SetValue(dialog_StylingStation, _desiredHairColor); + } + num += 60f; + if (desiredHairColor != pawn.story.hairColor && desiredHairColor != pawn.style.nextHairColor) + { + Widgets.ThingIcon(new Rect(newrect.x, num, Text.LineHeight, Text.LineHeight), ThingDefOf.Dye, null, null, 1.1f, null); + string text = "Required".Translate() + ": 1 " + ThingDefOf.Dye.label; + float x = Text.CalcSize(text).x; + Widgets.Label(new Rect(newrect.x + Text.LineHeight + 4f, num, x, Text.LineHeight), text); + Rect rect2 = new Rect(newrect.x, num, x + Text.LineHeight + 8f, Text.LineHeight); + if (Mouse.IsOver(rect2)) + { + Widgets.DrawHighlight(rect2); + TooltipHandler.TipRegionByKey(rect2, "TooltipDyeExplanation"); + } + num += Text.LineHeight; + + if (pawn.Map.resourceCounter.GetCount(ThingDefOf.Dye) < 1) + { + rect2 = new Rect(newrect.x, num, newrect.width, Text.LineHeight); + Color color = GUI.color; + GUI.color = ColorLibrary.RedReadable; + Widgets.Label(rect2, "NotEnoughDye".Translate() + " " + "NotEnoughDyeWillRecolorHair".Translate()); + GUI.color = color; + num += rect2.height; + } + } + + } + + // copypasted from vanilla + private static List allHairColors; + private static List AllHairColors + { + get + { + if (allHairColors == null) + { + allHairColors = (from ic in DefDatabase.AllDefsListForReading + select ic.color).ToList(); + allHairColors.SortByColor((Color x) => x); + } + return allHairColors; + } + } + + static void AddPubicHairTab(Dialog_StylingStation stylingStation, List tabs) + { + var curTabField = AccessTools.Field(typeof(Dialog_StylingStation), "curTab"); + //tabs.Add(new TabRecord("PubicHair".Translate().CapitalizeFirst(), delegate () + tabs.Add(new TabRecord("Pubic Hair", delegate () + { + curTabField.SetValue(stylingStation, (Dialog_StylingStation.StylingTab)48);// was 24 + }, (Dialog_StylingStation.StylingTab)curTabField.GetValue(stylingStation) == (Dialog_StylingStation.StylingTab)48)); // was 24 + } + + // code copied from OTYOTY's Sized Apparel mod + static IEnumerable Transpiler(IEnumerable instructions) + { + bool isHair = false; + MethodInfo tabAdd = AccessTools.DeclaredMethod(typeof(List), "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); + yield return new CodeInstruction(OpCodes.Ldfld, AccessTools.DeclaredField(typeof(Dialog_StylingStation), "tabs")); + + yield return new CodeInstruction(OpCodes.Call, AccessTools.Method(typeof(StylingStation), "AddPubicHairTab")); + + isHair = false; + } + else + yield return instruction; + + } + yield break; + } + } +}