using HarmonyLib; using rjw; using rjwquirks.Modules.Quirks; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; using UnityEngine; using Verse; namespace rjwquirks.HarmonyPatches { [HarmonyPatch(typeof(Dialog_Sexcard), "SexualityCard")] public static class Patch_Dialog_Sexcard { static IEnumerable Transpiler(IEnumerable instructions) { MethodInfo InsertQuirks = AccessTools.Method(typeof(Patch_Dialog_Sexcard), nameof(DrawQuirks)); MethodInfo DrawSexuality = AccessTools.Method(typeof(Dialog_Sexcard), "DrawSexuality"); bool found = false; // When RJW calls draw sexuality we inject our quirk drawing. foreach (CodeInstruction i in instructions) { if (i.opcode == OpCodes.Call && i.operand as MethodInfo == DrawSexuality) found = true; if (found) { yield return new CodeInstruction(OpCodes.Ldarg_2); yield return new CodeInstruction(OpCodes.Ldloc_3); yield return new CodeInstruction(OpCodes.Call, InsertQuirks); found = false; } yield return i; } } public static void DrawQuirks(Pawn pawn, Rect rect) { QuirkSet quirks = pawn.GetQuirks(); rect.y += 24; if (quirks == null) return; var quirkString = quirks.AllQuirks .Select(quirk => quirk.Label) .OrderBy(Label => Label) .ToCommaList(); if ((Current.ProgramState == ProgramState.Playing && pawn.IsDesignatedHero() && pawn.IsHeroOwner() || Prefs.DevMode) || Current.ProgramState == ProgramState.Entry) { if (Widgets.ButtonText(rect, "Quirks".Translate() + quirkString, false)) DrawQuirkEditMenu(pawn, quirks); } else Widgets.Label(rect, "Quirks".Translate() + quirkString); if (!Mouse.IsOver(rect)) return; Widgets.DrawHighlight(rect); TooltipHandler.TipRegion(rect, quirks.TipString()); } static void DrawQuirkEditMenu(Pawn pawn, QuirkSet quirks) { var quirkDefsAll = DefDatabase.AllDefs.OrderBy(def => def.GetLabelFor(pawn)); var menuOptions = new List(); if (RJWSettings.DevMode) menuOptions.Add(new FloatMenuOption("[DEV] Forced Reset", () => quirks.Clear(true))); menuOptions.Add(new FloatMenuOption("Reset", () => quirks.Clear())); foreach (QuirkDef quirkDef in quirkDefsAll) { if (quirkDef.hidden && !RJWSettings.DevMode && !quirks.Contains(quirkDef)) continue; Quirk quirk = quirks.GetQuirk(quirkDef); FloatMenuOption option; if (quirk == null) { AcceptanceReport report = quirks.CanBeAdded(quirkDef); if (report.Accepted) { option = new FloatMenuOption( quirkDef.GetLabelFor(pawn), () => quirks.AddQuirk(quirkDef), mouseoverGuiAction: (Rect rect) => TooltipHandler.TipRegion(rect, quirkDef.GetDescriptionFor(pawn)) ); } else if (RJWSettings.DevMode) option = new FloatMenuOption($"[DEV]{quirkDef.GetLabelFor(pawn)}: {report.Reason}", () => quirks.AddQuirk(quirkDef, true)); else // Game does not call mouseoverGuiAction for the disabled entries option = new FloatMenuOption($"{quirkDef.GetLabelFor(pawn)}: {report.Reason}", null); } else { AcceptanceReport report = quirks.CanBeRemoved(quirkDef); if (report.Accepted) { option = new FloatMenuOption( "- " + quirk.Label, () => quirks.RemoveQuirk(quirk), mouseoverGuiAction: (Rect rect) => TooltipHandler.TipRegion(rect, quirk.Description) ); } else if (RJWSettings.DevMode) option = new FloatMenuOption($"- {quirk.Label}: {report.Reason}", () => quirks.RemoveQuirk(quirk, true)); else option = new FloatMenuOption($"- {quirk.Label}: {report.Reason}", null); } menuOptions.Add(option); } Find.WindowStack.Add(new FloatMenu(menuOptions)); } } }