mirror of
https://gitgud.io/Ed86/rjw-whoring.git
synced 2024-08-15 00:03:25 +00:00
322 lines
No EOL
11 KiB
C#
322 lines
No EOL
11 KiB
C#
using HarmonyLib;
|
|
using Verse;
|
|
using System;
|
|
using RimWorld;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using rjw;
|
|
|
|
/// <summary>
|
|
/// patches Building_Bed to add stuff for WhoreBeds
|
|
///
|
|
/// Also contains smaller patches for RoomRoleWorker_Barracks (don't count whore beds) (disabled), Toils_LayDown.ApplyBedThoughts (slept in brothel thought) and RestUtility (don't automatically claim brothel beds)
|
|
/// </summary>
|
|
|
|
namespace rjwwhoring
|
|
{
|
|
public static class harmony_Building_BedPatches
|
|
{
|
|
|
|
private static readonly Color sheetColorForWhores = new Color(181 / 255f, 55 / 255f, 109 / 255f);
|
|
|
|
// Set color for whore beds
|
|
[HarmonyPatch(typeof(Building_Bed))]
|
|
[HarmonyPatch(nameof(Building_Bed.DrawColorTwo), MethodType.Getter)]
|
|
public static class Building_Bed_DrawColor_Patch
|
|
{
|
|
[HarmonyPostfix]
|
|
public static void Postfix(Building_Bed __instance, ref Color __result)
|
|
{
|
|
if (__instance.IsAllowedForWhoringAll())
|
|
{
|
|
__result = sheetColorForWhores;
|
|
}
|
|
}
|
|
}
|
|
|
|
// add whoring toggles to beds
|
|
[HarmonyPatch(typeof(Building_Bed), nameof(Building_Bed.GetGizmos))]
|
|
public static class Building_Bed_GetGizmos_Patch
|
|
{
|
|
[HarmonyPostfix]
|
|
public static void Postfix(Building_Bed __instance, ref IEnumerable<Gizmo> __result)
|
|
{
|
|
if (!WhoringBase.show_whore_widgets_on_bed)
|
|
{
|
|
return;
|
|
}
|
|
__result = Process(__instance, __result);
|
|
}
|
|
|
|
private static IEnumerable<Gizmo> Process(Building_Bed __instance, IEnumerable<Gizmo> __result)
|
|
{
|
|
var isPrisonCell = __instance.GetRoom()?.IsPrisonCell == true;
|
|
if (!__instance.ForPrisoners &&
|
|
!__instance.Medical &&
|
|
__instance.def.building.bed_humanlike &&
|
|
__instance.Faction == Faction.OfPlayerSilentFail &&
|
|
!__instance.def.defName.Contains("Guest") &&
|
|
!__instance.def.defName.Contains("Android") &&
|
|
!isPrisonCell)
|
|
{
|
|
|
|
yield return
|
|
new Command_Toggle
|
|
{
|
|
defaultLabel = "CommandBedAllowWhoringLabel".Translate(),
|
|
defaultDesc = "CommandBedAllowWhoringDesc".Translate(),
|
|
icon = ContentFinder<Texture2D>.Get("UI/Commands/AsWhore"),
|
|
isActive = __instance.IsAllowedForWhoringOwner,
|
|
toggleAction = __instance.ToggleAllowedForWhoringOwner,
|
|
hotKey = KeyBindingDefOf.Misc5, // Guest Beds uses Misc4
|
|
Disabled = !__instance.def.HasAssignableCompFrom(typeof(CompAssignableToPawn_Bed)),
|
|
disabledReason = "This bed type is not assignable to pawns."
|
|
};
|
|
|
|
yield return
|
|
new Command_Toggle
|
|
{
|
|
defaultLabel = "CommandBedSetAsWhoreBedLabel".Translate(),
|
|
defaultDesc = "CommandBedSetAsWhoreBedDesc".Translate(),
|
|
icon = ContentFinder<Texture2D>.Get("UI/Commands/AsWhoreMany"),
|
|
isActive = __instance.IsAllowedForWhoringAll,
|
|
toggleAction = __instance.ToggleAllowedForWhoringAll,
|
|
hotKey = KeyBindingDefOf.Misc6, // Guest Beds uses Misc4
|
|
Disabled = !__instance.def.HasAssignableCompFrom(typeof(CompAssignableToPawn_Bed)),
|
|
disabledReason = "This bed type is not assignable to pawns."
|
|
};
|
|
}
|
|
|
|
foreach (var gizmo in __result)
|
|
{
|
|
if (__instance.IsAllowedForWhoringAll())
|
|
{
|
|
if (gizmo is Command_Toggle && ((Command_Toggle)gizmo).defaultLabel == "CommandBedSetAsGuestLabel".Translate())
|
|
{
|
|
// hide set as guest bed
|
|
continue;
|
|
};
|
|
// old: instead of hiding, just disable
|
|
/*switch (gizmo)
|
|
{
|
|
case Command_Toggle toggle:
|
|
{
|
|
// Disable prisoner and medical, and guest buttons
|
|
if (//toggle.defaultLabel == "CommandBedSetForPrisonersLabel".Translate() ||
|
|
//toggle.defaultLabel == "CommandBedSetAsMedicalLabel".Translate() ||
|
|
toggle.defaultLabel == "CommandBedSetAsGuestLabel".Translate()) gizmo.Disable();
|
|
break;
|
|
}
|
|
}//*/
|
|
}
|
|
yield return gizmo;
|
|
}
|
|
}
|
|
}
|
|
|
|
// add description of whore price factor to inspect string (bottom left corner if item selected)
|
|
[HarmonyPatch(typeof(Building_Bed), nameof(Building_Bed.GetInspectString))]
|
|
public static class Building_Bed_GetInspectString_Patch
|
|
{
|
|
[HarmonyPostfix]
|
|
public static void Postfix(Building_Bed __instance, ref string __result)
|
|
{
|
|
if (__instance.def.building.bed_humanlike && __instance.Faction == Faction.OfPlayerSilentFail && (__instance.IsAllowedForWhoringAll() || __instance.IsAllowedForWhoringOwner()))
|
|
{
|
|
__result = __result + "\n" + "WhorePriceCalcDesc".Translate(WhoreBed_Utility.CalculatePriceFactor(__instance).ToString("F2"));
|
|
if (WhoringBase.DebugWhoring)
|
|
{
|
|
__result = __result + "\nbed.thingIDNumber: " + __instance.thingIDNumber.ToString();
|
|
|
|
__result = __result + "\nscoreUpdateTickDelay: " + WhoringBase.DataStore.GetBedData(__instance).scoreUpdateTickDelay.ToString();
|
|
|
|
if (WhoringBase.DataStore.GetBedData(__instance).reservedUntilGameTick > GenTicks.TicksGame)
|
|
{
|
|
__result = __result + "\nreserved by pawn id: " + WhoringBase.DataStore.GetBedData(__instance).reservedForPawnID.ToString();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// add whore price factor as overlay
|
|
[HarmonyPatch(typeof(Building_Bed), nameof(Building_Bed.DrawGUIOverlay))]
|
|
public static class Building_Bed_DrawGUIOverlay_Patch
|
|
{
|
|
[HarmonyPrefix]
|
|
public static bool Prefix(Building_Bed __instance)
|
|
{
|
|
if (WhoringBase.show_whore_price_factor_on_bed && __instance.def.building.bed_humanlike && __instance.Faction == Faction.OfPlayerSilentFail) {
|
|
// if whore bed, print price factor on it
|
|
if (Find.CameraDriver.CurrentZoom == CameraZoomRange.Closest
|
|
&& ((__instance.IsAllowedForWhoringOwner() && __instance.OwnersForReading.Any<Pawn>())
|
|
|| __instance.IsAllowedForWhoringAll()))
|
|
{
|
|
Color defaultThingLabelColor = GenMapUI.DefaultThingLabelColor;
|
|
|
|
// make string
|
|
float whore_price_factor = WhoreBed_Utility.CalculatePriceFactor(__instance);
|
|
string wpf;
|
|
if (Math.Abs(whore_price_factor) >= 100)
|
|
{
|
|
wpf = ((int)whore_price_factor).ToString("D");
|
|
}
|
|
else if (Math.Abs(whore_price_factor) >= 10)
|
|
{
|
|
wpf = whore_price_factor.ToString("F1");
|
|
}
|
|
else
|
|
{
|
|
wpf = whore_price_factor.ToString("F2");
|
|
}
|
|
|
|
// get dimensions of text and make it appear above names
|
|
Vector2 textsize = Text.CalcSize(wpf);
|
|
Vector2 baseLabelPos = GenMapUI.LabelDrawPosFor(__instance, -0.4f); // -0.4f is copied from vanilla code
|
|
baseLabelPos.y -= textsize.y * 0.75f;
|
|
|
|
GenMapUI.DrawThingLabel(baseLabelPos, wpf, defaultThingLabelColor);
|
|
|
|
if (__instance.IsAllowedForWhoringAll() && !__instance.OwnersForReading.Any<Pawn>())
|
|
{
|
|
// hide "Unowned" if whore bed with no owner
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
// after drawing whore price factor, draw the actual names
|
|
// could have been done as a postfix, but I started with a prefix, hoping I could get by with only one draw call
|
|
return true;
|
|
}
|
|
|
|
}
|
|
|
|
// barracks don't count whore beds, so room type switches to brothel sooner
|
|
// disabled - barracks have their own slept in ~ debuff; doesn't really matter; put some effort in your brothels!
|
|
/*[HarmonyPatch(typeof(RoomRoleWorker_Barracks), nameof(RoomRoleWorker_Barracks.GetScore))]
|
|
public static class RoomRoleWorker_Barracks_GetScore_Patch
|
|
{
|
|
public static bool Prefix(Room room, ref float __result)
|
|
{
|
|
int num = 0;
|
|
int num2 = 0;
|
|
List<Thing> containedAndAdjacentThings = room.ContainedAndAdjacentThings;
|
|
for (int i = 0; i < containedAndAdjacentThings.Count; i++)
|
|
{
|
|
Building_Bed building_Bed = containedAndAdjacentThings[i] as Building_Bed;
|
|
if (building_Bed != null && building_Bed.def.building.bed_humanlike)
|
|
{
|
|
if (building_Bed.ForPrisoners)
|
|
{
|
|
__result = 0f;
|
|
return false;
|
|
}
|
|
num++;
|
|
if (!building_Bed.Medical && !building_Bed.IsAllowedForWhoringAll())
|
|
{
|
|
num2++;
|
|
}
|
|
}
|
|
}
|
|
if (num <= 1)
|
|
{
|
|
__result = 0f;
|
|
return false;
|
|
}
|
|
__result = (float)num2 * 100100f;
|
|
return false;
|
|
}
|
|
}*/
|
|
|
|
// if pawns sleep in a brothel or a whoring bed, they get a thought
|
|
[HarmonyPatch(typeof(Toils_LayDown), "ApplyBedThoughts")]
|
|
public class Toils_LayDown_ApplyBedThoughts_Patch
|
|
{
|
|
[HarmonyPostfix]
|
|
public static void Postfix(Pawn actor)
|
|
{
|
|
if (actor?.needs?.mood == null) return;
|
|
|
|
Building_Bed building_Bed = actor.CurrentBed();
|
|
|
|
actor?.needs?.mood?.thoughts?.memories?.RemoveMemoriesOfDef(ThoughtDefOf.SleptInBrothel);
|
|
|
|
if (building_Bed == null) return;
|
|
|
|
if (building_Bed?.GetRoom()?.Role == WhoreBed_Utility.roleDefBrothel || building_Bed.IsAllowedForWhoringAll())
|
|
{
|
|
var memoryHandler = actor.needs.mood.thoughts.memories;
|
|
int thoughtStage = 0;
|
|
|
|
foreach (var thoughtDef in DefDatabase<ThoughtDef_Whore>.AllDefsListForReading)
|
|
{
|
|
var memory = memoryHandler.GetFirstMemoryOfDef(thoughtDef);
|
|
if (memory?.CurStageIndex >= thoughtDef.stages.Count - 1)
|
|
{
|
|
thoughtStage = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
memoryHandler.TryGainMemory(ThoughtMaker.MakeThought(ThoughtDefOf.SleptInBrothel, thoughtStage));
|
|
}
|
|
}
|
|
}
|
|
|
|
// if room stats are updated, update beds within
|
|
// "necessary" if beds are toggled during pause
|
|
[HarmonyPatch(typeof(Room), "UpdateRoomStatsAndRole")]
|
|
public class Room_UpdateRoomStatsAndRole_Patch
|
|
{
|
|
[HarmonyPostfix]
|
|
public static void Postfix(Room __instance)
|
|
{
|
|
// note: with room stat display enabled, this get's called quite often for whatever room the mouse hovers over
|
|
// even large outdoor areas
|
|
// where iterating over all things to find all beds (even if there are none) is expensive
|
|
// for now, skip doing anything if even the game decides it's not worth it
|
|
// (game sets role to None if region count >36 or something)
|
|
// - the beds will update eventually
|
|
|
|
if (/*Find.PlaySettings.showRoomStats && */__instance.Role == RoomRoleDefOf.None)
|
|
return;
|
|
|
|
if (Find.TickManager.Paused)
|
|
{
|
|
// if paused, update immediately
|
|
WhoreBed_Utility.CalculateBedFactorsForRoom(__instance);
|
|
}
|
|
else
|
|
{
|
|
// else, just make beds update as soon as needed
|
|
WhoreBed_Utility.ResetTicksUntilUpdate(__instance);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///Prevents automatic claiming of brothel beds (beds that allow anyone to use for whoring)
|
|
///Note, that intent is not verified here, and this works because bed usage for actual whoring does not rely on IsValidBedFor call.
|
|
///Should above change in future, this patch needs to be removed or adjusted
|
|
///If the bed is already claimed (for example - assigned manually to pawn), it will still be used.
|
|
///<returns>Modifies __result to false, if bed is set to allow anyone for whroing AND is not already claimed.</returns>
|
|
/// </summary>
|
|
[HarmonyPatch(typeof(RestUtility), nameof(RestUtility.IsValidBedFor))]
|
|
public class RestUtility_IsValidBedFor_Patch
|
|
{
|
|
[HarmonyPostfix]
|
|
public static void Postfix(Pawn sleeper, Thing bedThing, ref bool __result)
|
|
{
|
|
if (!__result) return;
|
|
Building_Bed building_Bed = bedThing as Building_Bed;
|
|
bool isOwner = sleeper.ownership != null && sleeper.ownership.OwnedBed == bedThing;
|
|
if (building_Bed.IsAllowedForWhoringAll() && !isOwner ) __result = false;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
} |