Decompiled source of Date Everything v2.0.1

BepInEx\plugins\Empress_AI-Date_Everything\EmpressDateEverything.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Networking;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Empress")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+5f1b735e473ca4ccf3b383128fbebd889cb564da")]
[assembly: AssemblyProduct("EmpressDateEverything")]
[assembly: AssemblyTitle("EmpressDateEverything")]
[assembly: AssemblyVersion("1.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EmpressDateEverything
{
	[BepInPlugin("Empress.DateEverything", "Empress DateEverything", "1.1.0")]
	public sealed class EmpressDateEverythingPlugin : BaseUnityPlugin
	{
		internal ConfigEntry<bool> Enabled;

		internal ConfigEntry<bool> DebugLogging;

		internal ConfigEntry<KeyCode> InteractKey;

		internal ConfigEntry<KeyCode> RelationshipsKey;

		internal ConfigEntry<float> MaxDateDistance;

		internal ConfigEntry<int> LoveGainPerDate;

		internal ConfigEntry<int> LoveDecayPerRejection;

		internal ConfigEntry<float> UiScale;

		internal ConfigEntry<float> ChatAutoCloseSeconds;

		internal ConfigEntry<bool> ShowLookPrompt;

		internal ConfigEntry<float> LookPromptDistance;

		internal ConfigEntry<string> PortraitFolder;

		internal ConfigEntry<int> MaxRelationshipsShown;

		internal ConfigEntry<int> RewardCooldownSeconds;

		internal ConfigEntry<int> BetrayalSensitivity;

		internal ConfigEntry<int> MaxActiveFollowers;

		internal ConfigEntry<bool> TextSoundsEnabled;

		internal ConfigEntry<float> TypingCharactersPerSecond;

		internal ConfigEntry<float> TypingSoundVolume;

		internal ConfigEntry<float> CharacterMusicVolume;

		internal static EmpressDateEverythingPlugin Instance;

		private void Awake()
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Expected O, but got Unknown
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Expected O, but got Unknown
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Expected O, but got Unknown
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Expected O, but got Unknown
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Expected O, but got Unknown
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Expected O, but got Unknown
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Expected O, but got Unknown
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Invalid comparison between Unknown and I4
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Expected O, but got Unknown
			Instance = this;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Empress DateEverything", "Enabled", true, "Turns DateEverything on or off.");
			DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Empress DateEverything", "DebugLogging", false, "Adds tiny Empress debug logs.");
			InteractKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "InteractKey", (KeyCode)120, "Key used to ask the thing you are looking at on a date.");
			RelationshipsKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "RelationshipsKey", (KeyCode)287, "Key used to open the relationship board.");
			MaxDateDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Dating", "MaxDateDistance", 6f, new ConfigDescription("How far Empress lets your desperate little date radar reach.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>()));
			LoveGainPerDate = ((BaseUnityPlugin)this).Config.Bind<int>("Dating", "LoveGainPerDate", 7, new ConfigDescription("Base love gained from a successful date.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			LoveDecayPerRejection = ((BaseUnityPlugin)this).Config.Bind<int>("Dating", "LoveDecayPerRejection", 2, new ConfigDescription("Love lost when you back out like a coward.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			UiScale = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "UiScale", 1f, new ConfigDescription("Scales the Empress dating UI.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2f), Array.Empty<object>()));
			ChatAutoCloseSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "ChatAutoCloseSeconds", 0f, new ConfigDescription("Legacy setting. Date chat now stays open until you continue or close it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>()));
			ShowLookPrompt = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowLookPrompt", true, "Shows the small Press X dating prompt when looking at something dateable.");
			LookPromptDistance = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "LookPromptDistance", 4.75f, new ConfigDescription("Maximum distance for the small look prompt and date targeting.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 12f), Array.Empty<object>()));
			PortraitFolder = ((BaseUnityPlugin)this).Config.Bind<string>("Portraits", "PortraitFolder", Path.Combine(Paths.ConfigPath, "EmpressDateEverything", "Portraits"), "Folder for optional PNG portraits. Names can match the target, category, or default.png.");
			MaxRelationshipsShown = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "MaxRelationshipsShown", 30, new ConfigDescription("How many relationships the F6 board shows.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 100), Array.Empty<object>()));
			RewardCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("Dating", "RewardCooldownSeconds", 35, new ConfigDescription("Minimum seconds before the same relationship can gift or punish again.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 240), Array.Empty<object>()));
			BetrayalSensitivity = ((BaseUnityPlugin)this).Config.Bind<int>("Dating", "BetrayalSensitivity", 62, new ConfigDescription("How quickly jealous relationships find out you are seeing someone else.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			MaxActiveFollowers = ((BaseUnityPlugin)this).Config.Bind<int>("Followers", "MaxActiveFollowers", 3, new ConfigDescription("Maximum maxed-out dates that can physically follow you at once.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>()));
			TextSoundsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Audio", "TextSoundsEnabled", true, "Uses the Empress typing blips while date dialogue types.");
			TypingCharactersPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "TypingCharactersPerSecond", 34f, new ConfigDescription("How fast date dialogue types.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 120f), Array.Empty<object>()));
			TypingSoundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "TypingSoundVolume", 30f, new ConfigDescription("Typing blip volume from 0 to 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			CharacterMusicVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "CharacterMusicVolume", 50f, new ConfigDescription("Character music volume from 0 to 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			if ((int)InteractKey.Value == 101)
			{
				InteractKey.Value = (KeyCode)120;
			}
			if (Mathf.Approximately(CharacterMusicVolume.Value, 60f))
			{
				CharacterMusicVolume.Value = 50f;
			}
			GameObject val = new GameObject("EmpressDateEverything.Runtime")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<EmpressDateEverythingRuntime>().EmpressBoot(this);
			EmpressLog("DateEverything is ready. The relationship sim has teeth now.");
		}

		internal static void EmpressLog(string message)
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)("Empress DateEverything: " + message));
		}

		internal static void EmpressDebug(string message)
		{
			if ((Object)(object)Instance != (Object)null && Instance.DebugLogging.Value)
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)("Empress DateEverything debug: " + message));
			}
		}

		internal static void EmpressWarning(string message)
		{
			((BaseUnityPlugin)Instance).Logger.LogWarning((object)("Empress DateEverything: " + message));
		}
	}
	internal sealed class EmpressDateEverythingRuntime : MonoBehaviour
	{
		private EmpressDateEverythingPlugin _plugin;

		private readonly Dictionary<string, EmpressRelationship> _relationships = new Dictionary<string, EmpressRelationship>();

		private readonly Dictionary<string, Texture2D> _portraitCache = new Dictionary<string, Texture2D>();

		private readonly Dictionary<string, EmpressDateFollower> _followers = new Dictionary<string, EmpressDateFollower>();

		private readonly List<EmpressDateChoice> _activeChoices = new List<EmpressDateChoice>();

		private readonly List<EmpressDateAnswerChoice> _activeAnswerChoices = new List<EmpressDateAnswerChoice>();

		private readonly Random _random = new Random();

		private Canvas _canvas;

		private Text _promptText;

		private GameObject _promptPanel;

		private GameObject _datePanel;

		private RawImage _portrait;

		private Text _dateTitle;

		private Text _dateSubtitle;

		private Text _dateBody;

		private Text _dateOptions;

		private GameObject _relationshipsPanel;

		private Text _relationshipsStatsText;

		private ScrollRect _relationshipsScroll;

		private RectTransform _relationshipsListRoot;

		private bool _cursorCaptured;

		private bool _previousCursorVisible;

		private CursorLockMode _previousCursorLockState;

		private Texture2D _empressCursorTexture;

		private EmpressDateTarget? _lookTarget;

		private EmpressDateTarget? _activeTarget;

		private bool _dateWaitingForChoice;

		private bool _dateWaitingForAnswer;

		private bool _dateWaitingAfterChoice;

		private float _scanTimer;

		private string _saveFile = "";

		private Font _font;

		private EmpressDateAudio _audio;

		private Sprite _uiPanelSprite;

		private Sprite _uiGlassSprite;

		private Sprite _uiAccentSprite;

		private Sprite _uiFrameSprite;

		private string _fullDateBody = "";

		private int _fullDateVisibleLength;

		private float _visibleDateCharacters;

		private int _lastVisibleDateCharacters;

		private string _lastCommittedKey = "";

		private string _lastCommittedName = "";

		private string _activeQuestion = "";

		private string _activeFollowUpQuestion = "";

		private bool _singleplayerLockWarned;

		private float _nextFollowerCleanupAt;

		private const int EmpressMinimumShopPriceK = 1;

		private static readonly string[] EmpressOpeners = new string[30]
		{
			"You lock eyes with {0}. It has no eyes, which makes this worse.", "{0} looks emotionally available. Or physically unavoidable. Same thing.", "Empress detects romantic tension between you and {0}. The lab refuses to comment.", "{0} is giving mysterious energy. Probably because it cannot legally speak.", "You approach {0} with the confidence of someone who has dated worse.", "{0} waits for you. Menacingly. Romantically. Economically.", "The air gets weird around {0}. This is either chemistry or bad ventilation.", "You ask {0} if it comes here often. It does. It lives here.", "{0} has entered the dating pool. The pool is haunted.", "Empress has created a private romantic disaster chamber for you and {0}.",
			"{0} seems ready for a date. Or a forklift. Hard to tell.", "You and {0} share a silence so deep HR would call it a meeting.", "{0} is not running away. Huge green flag.", "You feel a spark with {0}. Please do not lick the spark.", "{0} accepts your presence with concerning patience.", "The date begins. {0} has already seen too much.", "{0} is here, you are here, and the universe has stopped trying to be normal.", "You compliment {0}. It remains structurally committed.", "{0} has a vibe. The vibe may be asbestos.", "Empress says this counts as courtship. Empress will not elaborate.",
			"{0} seems flattered. Or rendered.", "You ask {0} about its dreams. It says nothing, which is brave.", "A relationship with {0} begins where good decisions go to die.", "{0} radiates the confidence of something with no browser history.", "You prepare to date {0}. The walls are gossiping.", "{0} is ready. Somehow this is your life now.", "You feel seen by {0}. This is impressive because it may be a wall.", "Empress opens a little dating UI and quietly loses respect for physics.", "{0} has been promoted from object to emotional problem.", "You begin the date. {0} refuses to split the bill."
		};

		private static readonly string[] EmpressSweet = new string[10] { "You tell {0} it has beautiful collision. Love rises by {4}.", "{0} appreciates your gentle tone. It is still processing the concept of tone. Love rises by {4}.", "You say {0} makes this cursed job feel less cursed. Love rises by {4}.", "{0} lets the compliment sit there like a warm soup. Love rises by {4}.", "You admire {0}'s shape, purpose, and emotional load-bearing qualities. Love rises by {4}.", "{0} blushes internally. Probably. Love rises by {4}.", "You offer {0} a respectful nod. The date becomes dangerously wholesome. Love rises by {4}.", "{0} enjoys being perceived without being thrown. Love rises by {4}.", "You tell {0} it matters. Empress pretends not to tear up. Love rises by {4}.", "{0} accepts your tenderness like a tiny haunted receipt. Love rises by {4}." };

		private static readonly string[] EmpressWeird = new string[10] { "You ask {0} if it has ever tasted sunlight. The answer changes you both. Love rises by {4}.", "{0} respects your commitment to being this strange in public. Love rises by {4}.", "You explain your dream where {0} was mayor. It does not object. Love rises by {4}.", "{0} hears your weird little confession and somehow stays. Love rises by {4}.", "You whisper, 'same time next apocalypse?' {0} understands. Love rises by {4}.", "{0} and you invent a secret language made mostly of panic. Love rises by {4}.", "You show {0} a dance move that should be illegal. It survives. Love rises by {4}.", "{0} finds your oddness marketable. Love rises by {4}.", "You tell {0} it would make a gorgeous witness in court. Love rises by {4}.", "The date gets so weird Empress starts taking notes. Love rises by {4}." };

		private static readonly string[] EmpressDramatic = new string[10] { "You declare that {0} is the only thing in this facility that understands you. Love rises by {4}.", "{0} receives your dramatic speech with terrifying stillness. Love rises by {4}.", "You promise {0} a future neither of you can afford. Love rises by {4}.", "Thunder would strike if this building respected timing. Love rises by {4}.", "You stare at {0} like the credits are about to roll. Love rises by {4}.", "{0} becomes your tragic co-star for eleven seconds. Love rises by {4}.", "You say, 'if we survive this, dinner.' {0} cannot legally sign consent forms. Love rises by {4}.", "The date swells with impossible music only Empress can hear. Love rises by {4}.", "{0} accepts your monologue because interrupting would require animation. Love rises by {4}.", "You make this relationship everyone else's problem. Love rises by {4}." };

		private static readonly string[] EmpressStatuses = new string[6] { "Stranger", "Awkward Crush", "Suspicious Situationship", "Beloved Nuisance", "Soulbound Problem", "Empress Approved Disaster" };

		internal void EmpressBoot(EmpressDateEverythingPlugin plugin)
		{
			_plugin = plugin;
			_font = Resources.GetBuiltinResource<Font>("Arial.ttf");
			_saveFile = Path.Combine(Paths.ConfigPath, "EmpressDateEverything", "relationships.empress");
			Directory.CreateDirectory(Path.GetDirectoryName(_saveFile));
			Directory.CreateDirectory(_plugin.PortraitFolder.Value);
			EmpressDateCast.EmpressInitialize(_plugin);
			_audio = new EmpressDateAudio();
			_audio.EmpressInitialize((MonoBehaviour)(object)this, _plugin);
			EmpressLoad();
			EmpressCreateUiSkins();
			EmpressCreateUi();
		}

		private void Update()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if (!_plugin.Enabled.Value)
			{
				EmpressSetVisible(_promptPanel, visible: false);
				EmpressSetVisible(_datePanel, visible: false);
				EmpressSetVisible(_relationshipsPanel, visible: false);
				EmpressRestoreCursorState();
				_audio.EmpressStopCharacterMusic();
				EmpressDismissAllFollowers();
				return;
			}
			if (!EmpressDateEverythingAccess.IsOfflineSingleplayer())
			{
				EmpressApplySingleplayerLock();
				return;
			}
			_singleplayerLockWarned = false;
			EmpressCleanupFollowers();
			if (Input.GetKeyDown(_plugin.RelationshipsKey.Value))
			{
				EmpressToggleRelationships();
			}
			bool flag = _datePanel.activeSelf || _relationshipsPanel.activeSelf;
			EmpressMaintainUiCursor(flag);
			if (flag)
			{
				EmpressApplyUiControlLock();
			}
			if (_relationshipsPanel.activeSelf)
			{
				EmpressSetVisible(_promptPanel, visible: false);
				if (Input.GetKeyDown((KeyCode)27))
				{
					EmpressToggleRelationships();
				}
				return;
			}
			if (_datePanel.activeSelf)
			{
				EmpressTickTyping();
				EmpressDateInput();
				return;
			}
			_scanTimer -= Time.unscaledDeltaTime;
			if (_scanTimer <= 0f)
			{
				_scanTimer = 0.08f;
				_lookTarget = EmpressFindTarget();
				EmpressRefreshPrompt();
			}
			if (_lookTarget != null && EmpressDateKeyDown())
			{
				EmpressStartDate(_lookTarget);
			}
		}

		private bool EmpressDateKeyDown()
		{
			return Input.GetKeyDown((KeyCode)120);
		}

		private void EmpressApplySingleplayerLock()
		{
			_lookTarget = null;
			_activeTarget = null;
			_dateWaitingForChoice = false;
			_dateWaitingForAnswer = false;
			_dateWaitingAfterChoice = false;
			EmpressSetVisible(_datePanel, visible: false);
			EmpressSetVisible(_relationshipsPanel, visible: false);
			EmpressRestoreCursorState();
			_audio.EmpressStopCharacterMusic();
			EmpressDismissAllFollowers();
			_promptText.text = "EMPRESS DATE EVERYTHING LOCKED  ::  singleplayer offline only";
			EmpressSetVisible(_promptPanel, visible: true);
			if (!_singleplayerLockWarned)
			{
				_singleplayerLockWarned = true;
				EmpressDateEverythingPlugin.EmpressWarning("DateEverything is locked because this session is not offline singleplayer.");
			}
		}

		private void EmpressCleanupFollowers()
		{
			if (Time.unscaledTime < _nextFollowerCleanupAt)
			{
				return;
			}
			_nextFollowerCleanupAt = Time.unscaledTime + 2.5f;
			List<string> list = null;
			foreach (KeyValuePair<string, EmpressDateFollower> follower in _followers)
			{
				if ((Object)(object)follower.Value == (Object)null)
				{
					if (list == null)
					{
						list = new List<string>();
					}
					list.Add(follower.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			for (int i = 0; i < list.Count; i++)
			{
				_followers.Remove(list[i]);
				if (_relationships.TryGetValue(list[i], out EmpressRelationship value))
				{
					value.Following = false;
				}
			}
		}

		private void EmpressDismissAllFollowers()
		{
			foreach (EmpressDateFollower value in _followers.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
			}
			_followers.Clear();
			foreach (EmpressRelationship value2 in _relationships.Values)
			{
				value2.Following = false;
			}
		}

		private void EmpressDateInput()
		{
			if (EmpressDateKeyDown())
			{
				EmpressRejectDate();
			}
			else if (Input.GetKeyDown((KeyCode)27))
			{
				EmpressRejectDate();
			}
			else if (_visibleDateCharacters < (float)_fullDateVisibleLength && (Input.GetKeyDown((KeyCode)101) || Input.GetKeyDown((KeyCode)49) || Input.GetKeyDown((KeyCode)50) || Input.GetKeyDown((KeyCode)51) || Input.GetKeyDown((KeyCode)52) || Input.GetKeyDown((KeyCode)53)))
			{
				_visibleDateCharacters = _fullDateVisibleLength;
				_lastVisibleDateCharacters = _fullDateVisibleLength;
				_dateBody.text = _fullDateBody;
				_audio.EmpressStopTypingSound();
			}
			else if (_dateWaitingForChoice)
			{
				if (Input.GetKeyDown((KeyCode)49) || Input.GetKeyDown((KeyCode)257))
				{
					EmpressChoose(0);
				}
				else if (Input.GetKeyDown((KeyCode)50) || Input.GetKeyDown((KeyCode)258))
				{
					EmpressChoose(1);
				}
				else if (Input.GetKeyDown((KeyCode)51) || Input.GetKeyDown((KeyCode)259))
				{
					EmpressChoose(2);
				}
				else if (Input.GetKeyDown((KeyCode)52) || Input.GetKeyDown((KeyCode)260))
				{
					EmpressChoose(3);
				}
				else if ((Input.GetKeyDown((KeyCode)53) || Input.GetKeyDown((KeyCode)261)) && _activeTarget != null)
				{
					EmpressToggleFollower(_activeTarget);
				}
			}
			else if (_dateWaitingForAnswer)
			{
				if (Input.GetKeyDown((KeyCode)49) || Input.GetKeyDown((KeyCode)257))
				{
					EmpressAnswerQuestion(0);
				}
				else if (Input.GetKeyDown((KeyCode)50) || Input.GetKeyDown((KeyCode)258))
				{
					EmpressAnswerQuestion(1);
				}
				else if (Input.GetKeyDown((KeyCode)51) || Input.GetKeyDown((KeyCode)259))
				{
					EmpressAnswerQuestion(2);
				}
				else if (Input.GetKeyDown((KeyCode)52) || Input.GetKeyDown((KeyCode)260))
				{
					EmpressAnswerQuestion(3);
				}
			}
			else if (_dateWaitingAfterChoice && Input.GetKeyDown((KeyCode)101) && _activeTarget != null && EmpressCanContinueDate(_activeTarget.Relationship))
			{
				EmpressContinueDate(_activeTarget);
			}
			else if (_dateWaitingAfterChoice && (Input.GetKeyDown((KeyCode)53) || Input.GetKeyDown((KeyCode)261)) && _activeTarget != null)
			{
				EmpressToggleFollower(_activeTarget);
			}
		}

		private void EmpressTickTyping()
		{
			if (_fullDateBody.Length <= 0 || _visibleDateCharacters >= (float)_fullDateVisibleLength)
			{
				return;
			}
			if (_plugin.TypingCharactersPerSecond.Value <= 0.01f)
			{
				_visibleDateCharacters = _fullDateVisibleLength;
				_lastVisibleDateCharacters = _fullDateVisibleLength;
				_dateBody.text = _fullDateBody;
				_audio.EmpressStopTypingSound();
				return;
			}
			int num = Mathf.Clamp(Mathf.FloorToInt(_visibleDateCharacters), 0, _fullDateVisibleLength);
			_visibleDateCharacters += _plugin.TypingCharactersPerSecond.Value * Time.unscaledDeltaTime;
			int num2 = Mathf.Clamp(Mathf.FloorToInt(_visibleDateCharacters), 0, _fullDateVisibleLength);
			if (num2 > num)
			{
				_dateBody.text = EmpressRichTextSlice(_fullDateBody, num2);
				if (EmpressSliceHasNonWhitespace(_fullDateBody, Mathf.Max(_lastVisibleDateCharacters, num), num2))
				{
					_audio.EmpressPlayCharacter(num2);
				}
				_lastVisibleDateCharacters = num2;
				if (num2 >= _fullDateVisibleLength)
				{
					_audio.EmpressStopTypingSound();
				}
			}
		}

		private void EmpressApplyUiControlLock()
		{
			PlayerController instance = PlayerController.instance;
			if ((Object)(object)instance != (Object)null)
			{
				instance.InputDisable(0.15f);
			}
			if ((Object)(object)CameraAim.Instance != (Object)null)
			{
				CameraAim.Instance.OverrideAimStop();
			}
		}

		private void EmpressMaintainUiCursor(bool visible)
		{
			if (visible)
			{
				EmpressApplyUiCursor();
			}
			else
			{
				EmpressRestoreCursorState();
			}
		}

		private void EmpressCaptureCursorState()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (!_cursorCaptured)
			{
				_previousCursorVisible = Cursor.visible;
				_previousCursorLockState = Cursor.lockState;
				_cursorCaptured = true;
			}
		}

		private void EmpressRestoreCursorState()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (_cursorCaptured)
			{
				Cursor.SetCursor((Texture2D)null, Vector2.zero, (CursorMode)0);
				Cursor.visible = _previousCursorVisible;
				Cursor.lockState = _previousCursorLockState;
				if ((_previousCursorVisible || (int)_previousCursorLockState == 0) && (Object)(object)MenuCursor.instance != (Object)null)
				{
					MenuCursor.instance.Show();
				}
				_cursorCaptured = false;
			}
		}

		private void EmpressApplyUiCursor()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			EmpressCaptureCursorState();
			EmpressEnsureCursorTexture();
			EmpressSuppressGameCursorSystems();
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			Cursor.SetCursor(_empressCursorTexture, new Vector2((float)((Texture)_empressCursorTexture).width * 0.5f, (float)((Texture)_empressCursorTexture).height * 0.5f), (CursorMode)0);
		}

		private void EmpressSuppressGameCursorSystems()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			EmpressDateEverythingAccess.SetCursorUnlockTimer(CursorManager.instance, -1234f);
			if (!((Object)(object)MenuCursor.instance == (Object)null))
			{
				EmpressDateEverythingAccess.SetMenuCursorShowTimer(MenuCursor.instance, 0f);
				EmpressDateEverythingAccess.SetMenuCursorOverridePosTimer(MenuCursor.instance, 0f);
				GameObject menuCursorMesh = EmpressDateEverythingAccess.GetMenuCursorMesh(MenuCursor.instance);
				if ((Object)(object)menuCursorMesh != (Object)null && menuCursorMesh.activeSelf)
				{
					menuCursorMesh.SetActive(false);
				}
				((Component)MenuCursor.instance).transform.localScale = Vector3.zero;
			}
		}

		private void EmpressEnsureCursorTexture()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_empressCursorTexture != (Object)null)
			{
				return;
			}
			_empressCursorTexture = new Texture2D(32, 32, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)0,
				hideFlags = (HideFlags)61,
				name = "EmpressDateEverything.Cursor"
			};
			for (int i = 0; i < ((Texture)_empressCursorTexture).height; i++)
			{
				for (int j = 0; j < ((Texture)_empressCursorTexture).width; j++)
				{
					float num = (float)j - 15.5f;
					float num2 = (float)i - 15.5f;
					float num3 = Mathf.Sqrt(num * num + num2 * num2);
					Color clear = Color.clear;
					if (num3 <= 2.15f)
					{
						((Color)(ref clear))..ctor(1f, 0.95f, 0.93f, 1f);
					}
					else if (num3 <= 5.15f)
					{
						((Color)(ref clear))..ctor(0.96f, 0.55f, 0.28f, 1f);
					}
					else if (num3 <= 7.4f)
					{
						((Color)(ref clear))..ctor(1f, 0.45f, 0.32f, 0.36f);
					}
					_empressCursorTexture.SetPixel(j, i, clear);
				}
			}
			_empressCursorTexture.Apply();
		}

		private void EmpressSetDateDialog(string title, string body, string options)
		{
			_dateTitle.text = title;
			if ((Object)(object)_dateSubtitle != (Object)null)
			{
				_dateSubtitle.text = ((_activeTarget != null) ? EmpressBuildDateSubtitle(_activeTarget) : "");
			}
			_fullDateBody = body;
			_fullDateVisibleLength = EmpressCountVisibleCharacters(body);
			_visibleDateCharacters = 0f;
			_lastVisibleDateCharacters = 0;
			_dateBody.text = "";
			_dateOptions.text = options;
			_audio.EmpressStopTypingSound();
		}

		private static bool EmpressSliceHasNonWhitespace(string text, int startVisible, int endVisible)
		{
			if (string.IsNullOrEmpty(text) || endVisible <= startVisible)
			{
				return false;
			}
			int num = 0;
			bool flag = false;
			foreach (char c in text)
			{
				if (c == '<')
				{
					flag = true;
					continue;
				}
				if (flag)
				{
					if (c == '>')
					{
						flag = false;
					}
					continue;
				}
				if (num >= startVisible && num < endVisible && !char.IsWhiteSpace(c))
				{
					return true;
				}
				num++;
				if (num >= endVisible)
				{
					return false;
				}
			}
			return false;
		}

		private static int EmpressCountVisibleCharacters(string text)
		{
			if (string.IsNullOrEmpty(text))
			{
				return 0;
			}
			int num = 0;
			bool flag = false;
			foreach (char c in text)
			{
				if (c == '<')
				{
					flag = true;
				}
				else if (flag)
				{
					if (c == '>')
					{
						flag = false;
					}
				}
				else
				{
					num++;
				}
			}
			return num;
		}

		private static string EmpressRichTextSlice(string text, int visibleCharacters)
		{
			if (string.IsNullOrEmpty(text) || visibleCharacters <= 0)
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder(text.Length + 32);
			List<string> list = new List<string>();
			StringBuilder stringBuilder2 = new StringBuilder(32);
			bool flag = false;
			int num = 0;
			foreach (char c in text)
			{
				if (flag)
				{
					stringBuilder2.Append(c);
					if (c == '>')
					{
						flag = false;
						string text2 = stringBuilder2.ToString();
						stringBuilder.Append(text2);
						EmpressTrackRichTag(list, text2);
						stringBuilder2.Length = 0;
					}
				}
				else if (c == '<')
				{
					flag = true;
					stringBuilder2.Length = 0;
					stringBuilder2.Append(c);
				}
				else
				{
					if (num >= visibleCharacters)
					{
						break;
					}
					stringBuilder.Append(c);
					num++;
				}
			}
			for (int num2 = list.Count - 1; num2 >= 0; num2--)
			{
				stringBuilder.Append("</");
				stringBuilder.Append(list[num2]);
				stringBuilder.Append('>');
			}
			return stringBuilder.ToString();
		}

		private static void EmpressTrackRichTag(List<string> openTags, string tag)
		{
			if (string.IsNullOrWhiteSpace(tag) || tag.Length < 3)
			{
				return;
			}
			string text = tag.Trim().Trim('<', '>');
			if (text.Length == 0 || text[0] == '!' || text[0] == '?')
			{
				return;
			}
			if (text[0] == '/')
			{
				string text2 = EmpressRichTagName(text.Substring(1));
				for (int num = openTags.Count - 1; num >= 0; num--)
				{
					if (openTags[num] == text2)
					{
						openTags.RemoveAt(num);
						break;
					}
				}
			}
			else if (!text.EndsWith("/"))
			{
				string text3 = EmpressRichTagName(text);
				if (!(text3 == "br") && text3.Length != 0)
				{
					openTags.Add(text3);
				}
			}
		}

		private static string EmpressRichTagName(string tagContent)
		{
			if (string.IsNullOrWhiteSpace(tagContent))
			{
				return "";
			}
			string[] array = tagContent.Split(new char[2] { ' ', '=' }, 2, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length == 0)
			{
				return "";
			}
			return array[0].Trim().ToLowerInvariant();
		}

		private EmpressDateTarget? EmpressFindTarget()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			Camera val = EmpressFindCamera();
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Ray val2 = new Ray(((Component)val).transform.position, ((Component)val).transform.forward);
			float num = Mathf.Min(_plugin.MaxDateDistance.Value, _plugin.LookPromptDistance.Value);
			RaycastHit val3 = default(RaycastHit);
			if (!Physics.Raycast(val2, ref val3, num, -1, (QueryTriggerInteraction)2))
			{
				return null;
			}
			Collider collider = ((RaycastHit)(ref val3)).collider;
			if ((Object)(object)collider == (Object)null)
			{
				return null;
			}
			Transform transform = ((Component)collider).transform;
			PlayerAvatar componentInParent = ((Component)transform).GetComponentInParent<PlayerAvatar>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				string text = EmpressCleanName(EmpressDateEverythingAccess.PlayerName(componentInParent));
				if (string.IsNullOrWhiteSpace(text))
				{
					text = "Player";
				}
				return EmpressMakeTarget("Player", text, ((Component)componentInParent).gameObject, ((RaycastHit)(ref val3)).point);
			}
			Enemy val4 = EmpressFindEnemyFromHit(transform, ((RaycastHit)(ref val3)).point);
			if ((Object)(object)val4 != (Object)null)
			{
				string name = EmpressEnemyDisplayName(val4);
				return EmpressMakeTarget("Enemy", name, ((Component)val4).gameObject, ((RaycastHit)(ref val3)).point);
			}
			TruckDoor val5 = EmpressFindComponentFromHit<TruckDoor>(transform);
			if ((Object)(object)val5 != (Object)null)
			{
				return EmpressMakeTarget("Door", "Truck Door", ((Component)val5).gameObject, ((RaycastHit)(ref val3)).point);
			}
			TutorialDoor val6 = EmpressFindComponentFromHit<TutorialDoor>(transform);
			if ((Object)(object)val6 != (Object)null)
			{
				return EmpressMakeTarget("Door", "Tutorial Door", ((Component)val6).gameObject, ((RaycastHit)(ref val3)).point);
			}
			Transform val7 = EmpressFindDoorFromHit(transform);
			if ((Object)(object)val7 != (Object)null)
			{
				return EmpressMakeTarget("Door", EmpressDoorDisplayName(val7), ((Component)val7).gameObject, ((RaycastHit)(ref val3)).point);
			}
			Transform val8 = EmpressFindTruckFromHit(transform);
			if ((Object)(object)val8 != (Object)null)
			{
				return EmpressMakeTarget("Truck", EmpressTruckDisplayName(val8), ((Component)val8).gameObject, ((RaycastHit)(ref val3)).point);
			}
			PhysGrabCart val9 = EmpressFindComponentFromHit<PhysGrabCart>(transform);
			if ((Object)(object)val9 != (Object)null)
			{
				return EmpressMakeTarget("Cart", EmpressCartDisplayName(val9), ((Component)val9).gameObject, ((RaycastHit)(ref val3)).point);
			}
			ExtractionPoint val10 = EmpressFindComponentFromHit<ExtractionPoint>(transform);
			if ((Object)(object)val10 != (Object)null)
			{
				return EmpressMakeTarget("Extractor", EmpressExtractorDisplayName(val10), ((Component)val10).gameObject, ((RaycastHit)(ref val3)).point);
			}
			ValuableObject val11 = EmpressFindComponentFromHit<ValuableObject>(transform);
			if ((Object)(object)val11 != (Object)null)
			{
				return EmpressMakeTarget("Valuable", EmpressValuableDisplayName(val11), ((Component)val11).gameObject, ((RaycastHit)(ref val3)).point);
			}
			ItemAttributes val12 = EmpressFindComponentFromHit<ItemAttributes>(transform);
			if ((Object)(object)val12 != (Object)null)
			{
				return EmpressMakeTarget("Item", EmpressItemDisplayName(val12), ((Component)val12).gameObject, ((RaycastHit)(ref val3)).point);
			}
			PhysGrabObject val13 = EmpressFindComponentFromHit<PhysGrabObject>(transform);
			if ((Object)(object)val13 != (Object)null)
			{
				return EmpressMakeTarget("Object", EmpressObjectDisplayName(((Component)val13).gameObject), ((Component)val13).gameObject, ((RaycastHit)(ref val3)).point);
			}
			Transform val14 = EmpressFindStaticObjectFromHit(transform);
			if ((Object)(object)val14 != (Object)null)
			{
				return EmpressMakeTarget("Object", EmpressObjectDisplayName(((Component)val14).gameObject), ((Component)val14).gameObject, ((RaycastHit)(ref val3)).point);
			}
			string text2 = ((!(Mathf.Abs(((RaycastHit)(ref val3)).normal.y) > 0.75f)) ? "Wall" : ((((RaycastHit)(ref val3)).normal.y > 0f) ? "Floor" : "Ceiling"));
			string text3 = EmpressCleanName(((Object)((Component)collider).gameObject).name);
			if (string.IsNullOrWhiteSpace(text3) || text3.Equals("Cube", StringComparison.OrdinalIgnoreCase) || text3.Equals("Collider", StringComparison.OrdinalIgnoreCase))
			{
				text3 = text2;
			}
			return EmpressMakeTarget(text2, text3, ((Component)collider).gameObject, ((RaycastHit)(ref val3)).point);
		}

		private static Enemy EmpressFindEnemyFromHit(Transform hitTransform, Vector3 hitPoint)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hitTransform == (Object)null)
			{
				return null;
			}
			Enemy componentInParent = ((Component)hitTransform).GetComponentInParent<Enemy>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return componentInParent;
			}
			EnemyParent componentInParent2 = ((Component)hitTransform).GetComponentInParent<EnemyParent>();
			if ((Object)(object)componentInParent2 != (Object)null)
			{
				componentInParent = ((Component)componentInParent2).GetComponentInChildren<Enemy>(true);
				if ((Object)(object)componentInParent != (Object)null)
				{
					return componentInParent;
				}
			}
			if (EmpressLooksEnemyRelated(hitTransform))
			{
				componentInParent = ((Component)hitTransform).GetComponentInChildren<Enemy>(true);
				if ((Object)(object)componentInParent != (Object)null)
				{
					return componentInParent;
				}
			}
			Collider[] array = Physics.OverlapSphere(hitPoint, 1.15f, -1, (QueryTriggerInteraction)2);
			float num = float.MaxValue;
			Enemy result = null;
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Enemy val2 = ((Component)val).GetComponentInParent<Enemy>();
				if ((Object)(object)val2 == (Object)null)
				{
					EnemyParent componentInParent3 = ((Component)val).GetComponentInParent<EnemyParent>();
					val2 = (((Object)(object)componentInParent3 != (Object)null) ? ((Component)componentInParent3).GetComponentInChildren<Enemy>(true) : null);
				}
				if (!((Object)(object)val2 == (Object)null))
				{
					float num2 = Vector3.Distance(hitPoint, ((Component)val2).transform.position);
					if (num2 < num)
					{
						num = num2;
						result = val2;
					}
				}
			}
			return result;
		}

		private static bool EmpressLooksEnemyRelated(Transform transform)
		{
			Transform val = transform;
			int num = 0;
			while ((Object)(object)val != (Object)null && num < 8)
			{
				string text = ((Object)val).name.ToLowerInvariant();
				if (text.Contains("enemy") || text.Contains("hunter") || text.Contains("runner") || text.Contains("duck") || text.Contains("gnome") || text.Contains("head") || text.Contains("shadow") || text.Contains("bang") || text.Contains("floater"))
				{
					return true;
				}
				Component[] components = ((Component)val).GetComponents<Component>();
				foreach (Component val2 in components)
				{
					if ((Object)(object)val2 != (Object)null && ((object)val2).GetType().Name.StartsWith("Enemy", StringComparison.Ordinal))
					{
						return true;
					}
				}
				num++;
				val = val.parent;
			}
			return false;
		}

		private static string EmpressEnemyDisplayName(Enemy enemy)
		{
			if ((Object)(object)enemy == (Object)null)
			{
				return "Enemy";
			}
			EnemyParent componentInParent = ((Component)enemy).GetComponentInParent<EnemyParent>();
			string text = (((Object)(object)componentInParent != (Object)null) ? EmpressCleanName(componentInParent.enemyName) : "");
			if (string.IsNullOrWhiteSpace(text) || text == "Dinosaur")
			{
				text = EmpressCleanName(((Object)((Component)enemy).gameObject).name);
			}
			if (string.IsNullOrWhiteSpace(text) || text == "Enemy" || text.Length <= 2)
			{
				text = ((object)enemy).GetType().Name;
			}
			return text;
		}

		private static T EmpressFindComponentFromHit<T>(Transform hitTransform) where T : Component
		{
			if ((Object)(object)hitTransform == (Object)null)
			{
				return default(T);
			}
			T component = ((Component)hitTransform).GetComponent<T>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			component = ((Component)hitTransform).GetComponentInParent<T>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			return EmpressFindComponentInChildCluster<T>(hitTransform);
		}

		private static T EmpressFindComponentInChildCluster<T>(Transform root) where T : Component
		{
			if ((Object)(object)root == (Object)null)
			{
				return default(T);
			}
			int num = Mathf.Min(root.childCount, 12);
			for (int i = 0; i < num; i++)
			{
				Transform child = root.GetChild(i);
				if ((Object)(object)child == (Object)null)
				{
					continue;
				}
				T component = ((Component)child).GetComponent<T>();
				if ((Object)(object)component != (Object)null)
				{
					return component;
				}
				int num2 = Mathf.Min(child.childCount, 8);
				for (int j = 0; j < num2; j++)
				{
					Transform child2 = child.GetChild(j);
					if (!((Object)(object)child2 == (Object)null))
					{
						component = ((Component)child2).GetComponent<T>();
						if ((Object)(object)component != (Object)null)
						{
							return component;
						}
					}
				}
			}
			return default(T);
		}

		private static string EmpressCartDisplayName(PhysGrabCart cart)
		{
			string text = (((Object)(object)cart != (Object)null) ? EmpressObjectDisplayName(((Component)cart).gameObject) : "");
			if (string.IsNullOrWhiteSpace(text) || EmpressIsGenericColliderName(text))
			{
				text = "Cart";
			}
			return text;
		}

		private static string EmpressExtractorDisplayName(ExtractionPoint extractor)
		{
			string text = (((Object)(object)extractor != (Object)null) ? EmpressObjectDisplayName(((Component)extractor).gameObject) : "");
			if (string.IsNullOrWhiteSpace(text) || EmpressIsGenericColliderName(text))
			{
				text = "Extractor";
			}
			return text;
		}

		private static string EmpressValuableDisplayName(ValuableObject valuable)
		{
			string text = (((Object)(object)valuable != (Object)null) ? EmpressObjectDisplayName(((Component)valuable).gameObject) : "");
			if (string.IsNullOrWhiteSpace(text) || EmpressIsGenericColliderName(text))
			{
				text = "Valuable";
			}
			return text;
		}

		private static string EmpressItemDisplayName(ItemAttributes item)
		{
			string text = (((Object)(object)item != (Object)null) ? EmpressDateEverythingAccess.ItemName(item) : "");
			if (string.IsNullOrWhiteSpace(text) && (Object)(object)item != (Object)null)
			{
				text = EmpressDateEverythingAccess.ItemAssetName(item);
			}
			if (string.IsNullOrWhiteSpace(text) && (Object)(object)item != (Object)null)
			{
				text = EmpressObjectDisplayName(((Component)item).gameObject);
			}
			if (string.IsNullOrWhiteSpace(text) || EmpressIsGenericColliderName(text))
			{
				text = "Item";
			}
			return text;
		}

		private static string EmpressObjectDisplayName(GameObject gameObject)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				return "";
			}
			Transform val = gameObject.transform;
			string text = "";
			int num = 0;
			while ((Object)(object)val != (Object)null && num < 8)
			{
				string text2 = EmpressCleanName(((Object)((Component)val).gameObject).name);
				if (!string.IsNullOrWhiteSpace(text2))
				{
					if (string.IsNullOrWhiteSpace(text))
					{
						text = text2;
					}
					if (!EmpressIsGenericColliderName(text2))
					{
						return text2;
					}
				}
				num++;
				val = val.parent;
			}
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			return "Object";
		}

		private static Transform EmpressFindStaticObjectFromHit(Transform hitTransform)
		{
			if ((Object)(object)hitTransform == (Object)null)
			{
				return null;
			}
			Transform best = null;
			int bestScore = int.MinValue;
			Transform val = hitTransform;
			int num = 0;
			while ((Object)(object)val != (Object)null && num < 3)
			{
				EmpressScoreStaticCandidate(val, num, ref best, ref bestScore);
				int num2 = Mathf.Min(val.childCount, 10);
				for (int i = 0; i < num2; i++)
				{
					Transform child = val.GetChild(i);
					EmpressScoreStaticCandidate(child, num + 1, ref best, ref bestScore);
					if (!((Object)(object)child == (Object)null))
					{
						int num3 = Mathf.Min(child.childCount, 6);
						for (int j = 0; j < num3; j++)
						{
							EmpressScoreStaticCandidate(child.GetChild(j), num + 2, ref best, ref bestScore);
						}
					}
				}
				num++;
				val = val.parent;
			}
			if (bestScore < 260)
			{
				return null;
			}
			return best;
		}

		private static void EmpressScoreStaticCandidate(Transform candidate, int depth, ref Transform best, ref int bestScore)
		{
			if (!((Object)(object)candidate == (Object)null) && EmpressDateCast.EmpressTryResolveStaticObjectLocal(((Component)candidate).gameObject, out EmpressDateCastSlot slot))
			{
				int num = EmpressDateCast.EmpressStaticObjectPriority(slot.Key) * 100 - depth * 18;
				if (!EmpressIsGenericColliderName(((Object)candidate).name))
				{
					num += 18;
				}
				if ((Object)(object)((Component)candidate).GetComponent<Renderer>() != (Object)null)
				{
					num += 10;
				}
				if (num > bestScore)
				{
					best = candidate;
					bestScore = num;
				}
			}
		}

		private static bool EmpressIsGenericColliderName(string name)
		{
			if (string.IsNullOrWhiteSpace(name))
			{
				return true;
			}
			string text = name.Trim();
			string text2 = text.Replace(" ", "").Replace("_", "").Replace("-", "");
			if (text.Equals("Box", StringComparison.OrdinalIgnoreCase) || text.Equals("Cube", StringComparison.OrdinalIgnoreCase) || text.Equals("Collider", StringComparison.OrdinalIgnoreCase) || text.Equals("Trigger", StringComparison.OrdinalIgnoreCase) || text.Equals("Model", StringComparison.OrdinalIgnoreCase) || text.Equals("Mesh", StringComparison.OrdinalIgnoreCase) || text.Equals("Root", StringComparison.OrdinalIgnoreCase) || text.Equals("Pivot", StringComparison.OrdinalIgnoreCase) || text.Equals("Hitbox", StringComparison.OrdinalIgnoreCase) || text.Equals("Phys Grab Object", StringComparison.OrdinalIgnoreCase) || text.Equals("Physgrabobject", StringComparison.OrdinalIgnoreCase) || text.Equals("Object", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if (text2.Equals("SemiBoxCollider", StringComparison.OrdinalIgnoreCase) || text2.Equals("BoxCollider", StringComparison.OrdinalIgnoreCase) || text2.Equals("MeshCollider", StringComparison.OrdinalIgnoreCase) || text2.Equals("CapsuleCollider", StringComparison.OrdinalIgnoreCase) || text2.Equals("SphereCollider", StringComparison.OrdinalIgnoreCase) || text2.Equals("ColliderMesh", StringComparison.OrdinalIgnoreCase) || text2.Equals("Collision", StringComparison.OrdinalIgnoreCase) || text2.Equals("CollisionMesh", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if ((text.EndsWith(" Collider", StringComparison.OrdinalIgnoreCase) || text.EndsWith(" Trigger", StringComparison.OrdinalIgnoreCase)) && text.IndexOf("door", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("gate", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("hatch", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("cart", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return text.IndexOf("truck", StringComparison.OrdinalIgnoreCase) < 0;
			}
			return false;
		}

		private static Transform EmpressFindDoorFromHit(Transform hitTransform)
		{
			if ((Object)(object)hitTransform == (Object)null)
			{
				return null;
			}
			Transform val = hitTransform;
			int num = 0;
			while ((Object)(object)val != (Object)null && num < 8)
			{
				if (EmpressLooksDoorRelated(val))
				{
					return val;
				}
				num++;
				val = val.parent;
			}
			return EmpressFindDoorInChildren(hitTransform);
		}

		private static Transform EmpressFindDoorInChildren(Transform root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			int num = Mathf.Min(componentsInChildren.Length, 64);
			for (int i = 0; i < num; i++)
			{
				Transform val = componentsInChildren[i];
				if ((Object)(object)val != (Object)null && EmpressLooksDoorRelated(val))
				{
					return val;
				}
			}
			return null;
		}

		private static bool EmpressLooksDoorRelated(Transform transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return false;
			}
			string text = ((Object)transform).name.ToLowerInvariant();
			if (text.Contains("door") || text.Contains("gate") || text.Contains("hatch") || text.Contains("shutter"))
			{
				return true;
			}
			Component[] components = ((Component)transform).GetComponents<Component>();
			foreach (Component val in components)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string name = ((object)val).GetType().Name;
					if (name.IndexOf("Door", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Gate", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static string EmpressDoorDisplayName(Transform doorTransform)
		{
			string text = (((Object)(object)doorTransform != (Object)null) ? EmpressObjectDisplayName(((Component)doorTransform).gameObject) : "");
			if (!string.IsNullOrWhiteSpace(text))
			{
				if (text.IndexOf("truck", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return "Truck Door";
				}
				if (text.IndexOf("hatch", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return "Hatch";
				}
				if (text.IndexOf("gate", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return "Gate";
				}
				if (text.EndsWith(" Collider", StringComparison.OrdinalIgnoreCase) || text.EndsWith(" Trigger", StringComparison.OrdinalIgnoreCase))
				{
					return "Door";
				}
			}
			if (string.IsNullOrWhiteSpace(text) || EmpressIsGenericColliderName(text))
			{
				text = "Doorway";
			}
			return text;
		}

		private static Transform EmpressFindTruckFromHit(Transform hitTransform)
		{
			if ((Object)(object)hitTransform == (Object)null)
			{
				return null;
			}
			Transform val = hitTransform;
			int num = 0;
			while ((Object)(object)val != (Object)null && num < 10)
			{
				if (EmpressLooksTruckRelated(val))
				{
					return val;
				}
				num++;
				val = val.parent;
			}
			return EmpressFindTruckInChildren(hitTransform);
		}

		private static Transform EmpressFindTruckInChildren(Transform root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			int num = Mathf.Min(componentsInChildren.Length, 96);
			for (int i = 0; i < num; i++)
			{
				Transform val = componentsInChildren[i];
				if ((Object)(object)val != (Object)null && EmpressLooksTruckRelated(val))
				{
					return val;
				}
			}
			return null;
		}

		private static bool EmpressLooksTruckRelated(Transform transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return false;
			}
			string text = ((Object)transform).name.ToLowerInvariant();
			if (text.Contains("truck") || text.Contains("haul truck"))
			{
				return true;
			}
			Component[] components = ((Component)transform).GetComponents<Component>();
			foreach (Component val in components)
			{
				if (!((Object)(object)val == (Object)null) && ((object)val).GetType().Name.IndexOf("Truck", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			return false;
		}

		private static string EmpressTruckDisplayName(Transform truckTransform)
		{
			string text = (((Object)(object)truckTransform != (Object)null) ? EmpressObjectDisplayName(((Component)truckTransform).gameObject) : "");
			if (string.IsNullOrWhiteSpace(text) || EmpressIsGenericColliderName(text))
			{
				return "Truck";
			}
			if (text.IndexOf("truck", StringComparison.OrdinalIgnoreCase) < 0)
			{
				return "Truck";
			}
			if (text.IndexOf("door", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return "Truck Door";
			}
			return text;
		}

		private Camera EmpressFindCamera()
		{
			PlayerAvatar val = EmpressDateEverythingAccess.LocalPlayer();
			if ((Object)(object)val != (Object)null && (Object)(object)val.localCamera != (Object)null)
			{
				Camera componentInChildren = ((Component)val.localCamera).GetComponentInChildren<Camera>(true);
				if ((Object)(object)componentInChildren != (Object)null && ((Behaviour)componentInChildren).enabled)
				{
					return componentInChildren;
				}
			}
			if ((Object)(object)Camera.main != (Object)null && ((Behaviour)Camera.main).enabled)
			{
				return Camera.main;
			}
			Camera[] allCameras = Camera.allCameras;
			for (int i = 0; i < allCameras.Length; i++)
			{
				if ((Object)(object)allCameras[i] != (Object)null && ((Behaviour)allCameras[i]).enabled)
				{
					return allCameras[i];
				}
			}
			return null;
		}

		private EmpressDateTarget EmpressMakeTarget(string category, string name, GameObject gameObject, Vector3 point)
		{
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			name = EmpressCleanName(name);
			if (string.IsNullOrWhiteSpace(name))
			{
				name = category;
			}
			EmpressDateCastSlot empressDateCastSlot = EmpressDateCast.EmpressResolve(category, name, gameObject);
			string name2 = EmpressResolveDisplayName(category, name, empressDateCastSlot);
			string key = empressDateCastSlot.Key;
			if (!_relationships.TryGetValue(key, out EmpressRelationship value))
			{
				value = EmpressTryRestoreCollapsedRelationship(empressDateCastSlot);
			}
			if (value == null)
			{
				value = new EmpressRelationship
				{
					Key = key,
					Name = name2,
					Category = empressDateCastSlot.Category,
					CastId = empressDateCastSlot.Key,
					PortraitFile = empressDateCastSlot.PortraitFile,
					Love = 0,
					StoryStage = 0,
					StoryMomentum = 0,
					Dates = 0,
					LastMetTicks = 0L
				};
				_relationships[key] = value;
			}
			value.Name = name2;
			value.Category = empressDateCastSlot.Category;
			value.CastId = empressDateCastSlot.Key;
			value.PortraitFile = empressDateCastSlot.PortraitFile;
			value.LastSeenObject = name;
			return new EmpressDateTarget(key, name2, empressDateCastSlot.Category, gameObject, point, value, empressDateCastSlot, name);
		}

		private static string EmpressResolveDisplayName(string category, string observedName, EmpressDateCastSlot slot)
		{
			string text = ((slot != null) ? EmpressCleanName(slot.Name) : "");
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			string text2 = EmpressCleanName(observedName);
			if (!string.IsNullOrWhiteSpace(text2))
			{
				return text2;
			}
			return EmpressCleanName(category);
		}

		private EmpressRelationship EmpressTryRestoreCollapsedRelationship(EmpressDateCastSlot slot)
		{
			if (slot == null || string.IsNullOrWhiteSpace(slot.Key) || _relationships.ContainsKey(slot.Key))
			{
				return null;
			}
			EmpressRelationship empressRelationship = null;
			foreach (KeyValuePair<string, EmpressRelationship> relationship in _relationships)
			{
				if (relationship.Key.StartsWith(slot.Key + "::", StringComparison.OrdinalIgnoreCase))
				{
					EmpressRelationship value = relationship.Value;
					if (value != null && (empressRelationship == null || EmpressRelationshipScore(value) > EmpressRelationshipScore(empressRelationship)))
					{
						empressRelationship = value;
					}
				}
			}
			if (empressRelationship == null)
			{
				return null;
			}
			_relationships.Remove(empressRelationship.Key);
			empressRelationship.Key = slot.Key;
			empressRelationship.Name = EmpressResolveDisplayName(slot.Category, empressRelationship.LastSeenObject, slot);
			empressRelationship.Category = slot.Category;
			empressRelationship.CastId = slot.Key;
			empressRelationship.PortraitFile = slot.PortraitFile;
			_relationships[slot.Key] = empressRelationship;
			return empressRelationship;
		}

		private static int EmpressRelationshipScore(EmpressRelationship relationship)
		{
			if (relationship == null)
			{
				return int.MinValue;
			}
			return relationship.Love * 100000 + relationship.Dates * 1000 + relationship.MemoryScore * 10 + relationship.StoryStage;
		}

		private void EmpressStartDate(EmpressDateTarget target)
		{
			_activeTarget = target;
			_dateWaitingForChoice = true;
			_dateWaitingForAnswer = false;
			_dateWaitingAfterChoice = false;
			_activeChoices.Clear();
			_activeAnswerChoices.Clear();
			_activeChoices.AddRange(EmpressBuildChoices(target));
			_activeQuestion = EmpressBuildRelationshipQuestion(target, target.Relationship);
			_activeFollowUpQuestion = "";
			string text = EmpressBuildOpening(target);
			text = text + "\n\n" + ((_activeChoices.Count > 0) ? EmpressBuildQuestionPrompt(target) : EmpressBuildFinalPrompt(target));
			EmpressSetDateDialog(EmpressBuildDateTitle(target), text, EmpressChoiceOptions(target));
			EmpressSetPortrait(target);
			_audio.EmpressPlayCharacterMusic(target.Slot);
			EmpressSetVisible(_promptPanel, visible: false);
			EmpressSetVisible(_datePanel, visible: true);
			EmpressDateEverythingPlugin.EmpressDebug("dating " + target.Category + " " + target.Name);
		}

		private void EmpressContinueDate(EmpressDateTarget target)
		{
			_activeTarget = target;
			_dateWaitingForChoice = true;
			_dateWaitingForAnswer = false;
			_dateWaitingAfterChoice = false;
			_activeChoices.Clear();
			_activeAnswerChoices.Clear();
			_activeChoices.AddRange(EmpressBuildChoices(target));
			_activeQuestion = EmpressBuildRelationshipQuestion(target, target.Relationship);
			_activeFollowUpQuestion = "";
			string body = EmpressBuildContinuation(target) + "\n\n" + ((_activeChoices.Count > 0) ? EmpressBuildQuestionPrompt(target) : EmpressBuildFinalPrompt(target));
			EmpressSetDateDialog(EmpressBuildDateTitle(target), body, EmpressChoiceOptions(target));
			EmpressSetPortrait(target);
			_audio.EmpressPlayCharacterMusic(target.Slot);
		}

		private string EmpressChoiceOptions(EmpressDateTarget target)
		{
			List<string> list = new List<string>();
			for (int i = 0; i < _activeChoices.Count && i < 4; i++)
			{
				list.Add("<color=#ffe6bf><b>" + (i + 1) + ".</b></color> " + _activeChoices[i].Label);
			}
			if (target.Relationship.Love >= 100)
			{
				list.Add("<color=#f7cd8a><b>5.</b></color> " + (target.Relationship.Following ? "Ask them to stay put" : "Ask them to follow"));
			}
			list.Add("<color=#d8cab1><b>X.</b></color> Close");
			return string.Join("\n", list);
		}

		private string EmpressAfterChoiceOptions(EmpressDateTarget target)
		{
			List<string> list = new List<string> { "<color=#d6c5aa><b>F6.</b></color> Relationship board" };
			if (EmpressCanContinueDate(target.Relationship))
			{
				list.Insert(0, "<color=#ffe6bf><b>E.</b></color> Continue date");
			}
			if (target.Relationship.Love >= 100)
			{
				list.Add("<color=#f7cd8a><b>5.</b></color> " + (target.Relationship.Following ? "Dismiss follower" : "Let them follow"));
			}
			list.Add("<color=#d8cab1><b>X.</b></color> Close");
			return string.Join("    ", list);
		}

		private static bool EmpressCanContinueDate(EmpressRelationship relationship)
		{
			if (relationship == null)
			{
				return false;
			}
			if (relationship.Love >= 100 && !relationship.Following)
			{
				return false;
			}
			if (relationship.Following && relationship.Anger < 20 && relationship.Jealousy < 20 && relationship.Love >= 90)
			{
				return false;
			}
			return true;
		}

		private string EmpressAnswerOptions()
		{
			List<string> list = new List<string>();
			for (int i = 0; i < _activeAnswerChoices.Count && i < 4; i++)
			{
				list.Add("<color=#ffe6bf><b>" + (i + 1) + ".</b></color> " + _activeAnswerChoices[i].Label);
			}
			list.Add("<color=#d8cab1><b>X.</b></color> Close");
			return string.Join("\n", list);
		}

		private string EmpressCurrentOptions(EmpressDateTarget target)
		{
			if (_dateWaitingForChoice)
			{
				return EmpressChoiceOptions(target);
			}
			if (!_dateWaitingForAnswer)
			{
				return EmpressAfterChoiceOptions(target);
			}
			return EmpressAnswerOptions();
		}

		private string EmpressBuildDateTitle(EmpressDateTarget target)
		{
			return "<b>" + EmpressRichEscape(target.Name) + "</b>";
		}

		private string EmpressBuildDateSubtitle(EmpressDateTarget target)
		{
			EmpressRelationship relationship = target.Relationship;
			return "<color=#ffe4b2>" + EmpressRichEscape(target.Category + " :: " + EmpressStatus(relationship.Love) + " :: chapter " + (relationship.StoryStage + 1) + " :: love " + relationship.Love + "% :: trust " + relationship.Trust + "%") + "</color>";
		}

		private string EmpressBuildQuestionPrompt(EmpressDateTarget target)
		{
			return "<color=#f0d29a><b>" + EmpressRichEscape(target.Name) + " asks:</b></color> \"" + EmpressRichEscape(_activeQuestion) + "\"";
		}

		private static string EmpressBuildFinalPrompt(EmpressDateTarget target)
		{
			if (target.Relationship.Following)
			{
				return "<color=#f0d29a><b>" + EmpressRichEscape(target.Name) + " is already following.</b></color> The story is stable for now. If cheating, anger, or jealousy hits, the relationship can open back up.";
			}
			return "<color=#f0d29a><b>" + EmpressRichEscape(target.Name) + " is ready.</b></color> Talking is no longer the proof. Press 5 if you want them to follow you.";
		}

		private string EmpressBuildRelationshipQuestion(EmpressDateTarget target, EmpressRelationship relationship)
		{
			if (relationship.Anger >= 45)
			{
				return "Are you here to repair this, or are you about to make me angrier on purpose?";
			}
			if (relationship.Jealousy >= 25 && !string.IsNullOrWhiteSpace(relationship.LastOtherName))
			{
				return "When you leave here, are you going to look for " + relationship.LastOtherName + " next?";
			}
			if (relationship.Children > 0)
			{
				return "Do you realize our " + relationship.Children + " hypothetical children would inherit your terrible timing?";
			}
			return EmpressStoryQuestion(target, relationship);
		}

		private static string EmpressStoryQuestion(EmpressDateTarget target, EmpressRelationship relationship)
		{
			switch (Mathf.Clamp(relationship.StoryStage, 0, 8))
			{
			case 0:
				return "Is this a joke, a dare, or the beginning of something embarrassing?";
			case 1:
				return "Are you curious about me, or are you only curious about what I can do for you?";
			case 2:
				return "If I remember one thing from tonight, what are you hoping it is?";
			case 3:
				return "What truth are you brave enough to give me today?";
			case 4:
				return "What are we calling this now that it has consequences?";
			case 5:
				return "If I asked for a future, would you mean yes or just enjoy sounding romantic?";
			case 6:
				return "When this gets difficult, what part of us are you protecting first?";
			case 7:
				return "Are you ready to be chosen back, loudly and inconveniently?";
			default:
				if (!relationship.Following)
				{
					return "If I step off the map for you, are you going to treat that like a promise?";
				}
				return "Now that I am actually with you, what are we surviving next?";
			}
		}

		private List<EmpressDateChoice> EmpressBuildChoices(EmpressDateTarget target)
		{
			EmpressRelationship relationship = target.Relationship;
			List<EmpressDateChoice> list = new List<EmpressDateChoice>();
			if (relationship.Love >= 100 && relationship.Anger < 20 && relationship.Jealousy < 20)
			{
				return list;
			}
			if (relationship.Anger >= 24 || relationship.Jealousy >= 18)
			{
				EmpressTryAddChoice(list, EmpressMakeChoice("apologize", "Apologize", "You drop the bit and offer a real apology instead of hiding behind flirtation.", 0, 1, 4, 4, -2, -8, 2, 1, -1, 0, "apologetic"));
				EmpressTryAddChoice(list, EmpressMakeChoice("repair", "Repair trust", "You name the damage, the pattern, and the specific way you are going to stop making them carry it alone.", 0, 1, 6, 3, -3, -10, 5, 3, -3, 0, "repairing"));
				EmpressTryAddChoice(list, EmpressMakeChoice("reassure", "Reassure", "You reassure them that this conversation matters more than whatever panic brought you in.", 0, 2, 5, 3, -3, -5, 3, 1, -2, 0, "reassuring"));
			}
			EmpressAddStoryChoices(target, relationship, list);
			if (target.Category == "Enemy")
			{
				EmpressTryAddChoice(list, EmpressMakeChoice("truce", "Call truce", "You offer a truce and treat the monster in front of you like it gets to choose what happens next.", 0, 2, 5, 3, -2, -5, 3, 2, -1, 0, "peace-making"));
			}
			if (relationship.SecretDepth < 20 || relationship.Dates <= 1 || target.Category == "Valuable" || target.Category == "Extractor")
			{
				EmpressTryAddChoice(list, EmpressMakeChoice("memory", "Ask what they remember", "You ask what they remember when nobody is looking and do not blink when the answer takes its time.", 1, 1, 4, 2, 0, -1, 1, 5, 0, 0, "curious"));
			}
			EmpressTryAddChoice(list, EmpressMakeChoice("admire", "Admire", "You take a second to admire the details that make them feel singular instead of replaceable.", 0, 2, 3, 3, -1, -2, 2, 1, 0, 0, "admiring"));
			EmpressTryAddChoice(list, EmpressMakeChoice("need", "Ask what they need", "You ask them what they need from you instead of performing confidence.", 1, 1, 5, 2, -1, -2, 2, 4, -1, 0, "attentive"));
			return EmpressFinalizeChoices(relationship, list);
		}

		private void EmpressAddStoryChoices(EmpressDateTarget target, EmpressRelationship relationship, List<EmpressDateChoice> choices)
		{
			switch (Mathf.Clamp(relationship.StoryStage, 0, 8))
			{
			case 0:
				EmpressTryAddChoice(choices, EmpressMakeChoice("date", "Ask on date", "You ask for a real date, not just another stolen hallway moment between disasters.", 2, 3, 2, 4, 1, 0, 4, 1, 1, 0, "romantic"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("admire", "Admire", "You take a second to admire the details that make them feel singular instead of replaceable.", 0, 2, 3, 3, -1, -2, 2, 1, 0, 0, "admiring"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("listen", "Listen closely", "You stop trying to be impressive and listen for what they are not saying yet.", 1, 1, 5, 2, -1, -2, 2, 5, -1, 0, "listening"));
				break;
			case 1:
				EmpressTryAddChoice(choices, EmpressMakeChoice("memory", "Ask what they remember", "You ask what they remember when nobody is looking and do not blink when the answer takes its time.", 1, 1, 4, 2, 0, -1, 1, 5, 0, 0, "curious"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("date", "Ask on date", "You ask for a real date, not just another stolen hallway moment between disasters.", 2, 3, 2, 4, 1, 0, 4, 1, 1, 0, "romantic"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("boundary", "Respect boundary", "You ask where the line is and make it clear you are not here to shove past it.", 0, 1, 6, 2, -2, -3, 3, 2, -2, 0, "boundary-respecting"));
				break;
			case 2:
				EmpressTryAddChoice(choices, EmpressMakeChoice("promise", "Make a promise", "You make one promise small enough to keep and serious enough to matter.", 0, 2, 5, 2, -1, -2, 6, 2, -1, 0, "promising"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("secret", "Share secret", "You lean in and trade them a secret you have not given anyone else in this building.", 1, 2, 5, 2, 0, -1, 2, 6, 0, 0, "confessional"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("flirt", "Flirt", "You flirt with enough conviction to make the room feel warmer and slightly less OSHA-compliant.", 2, 4, 1, 5, 2, 0, 2, 0, 1, 0, "flirtatious"));
				break;
			case 3:
				EmpressTryAddChoice(choices, EmpressMakeChoice("vulnerability", "Be vulnerable", "You say the part that would be easier to bury under jokes, and you let it sit there breathing.", 1, 3, 5, 2, -1, -3, 5, 5, -2, 0, "vulnerable"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("define", "Define relationship", "You ask what this is instead of letting it stay a haunted blur with benefits.", 1, 2, 4, 2, -1, -1, 6, 2, 0, 0, "serious"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("date", "Ask on date", "You ask for a real date, not just another stolen hallway moment between disasters.", 2, 3, 2, 4, 1, 0, 4, 1, 1, 0, "romantic"));
				break;
			case 4:
				EmpressTryAddChoice(choices, EmpressMakeChoice("define", "Define relationship", "You ask what this is instead of letting it stay a haunted blur with benefits.", 1, 2, 4, 2, -1, -1, 6, 2, 0, 0, "serious"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("future", "Talk future", "You stop pretending this is casual and talk about what a future together would actually look like.", 2, 3, 3, 4, 0, 0, 7, 1, 1, 0, "future-facing"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("ritual", "Make a ritual", "You suggest a tiny ritual just for the two of you, something that can survive bad runs and worse timing.", 1, 2, 4, 3, -1, -1, 6, 3, -1, 0, "ritual-making"));
				break;
			case 5:
				EmpressTryAddChoice(choices, EmpressMakeChoice("future", "Talk future", "You stop pretending this is casual and talk about what a future together would actually look like.", 2, 3, 3, 4, 0, 0, 7, 1, 1, 0, "future-facing"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("choose_them", "Choose them", "You make the choice explicit: not convenient, not accidental, not because they were closest. Them.", 2, 4, 4, 4, -2, -2, 8, 2, -2, 0, "chosen"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("vulnerability", "Be vulnerable", "You say the part that would be easier to bury under jokes, and you let it sit there breathing.", 1, 3, 5, 2, -1, -3, 5, 5, -2, 0, "vulnerable"));
				break;
			case 6:
				EmpressTryAddChoice(choices, EmpressMakeChoice("devotion", "Show devotion", "You prove the relationship is not just words by choosing the inconvenient, loyal thing.", 2, 5, 4, 4, -2, -3, 9, 2, -2, 0, "devoted"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("future", "Talk future", "You stop pretending this is casual and talk about what a future together would actually look like.", 2, 3, 3, 4, 0, 0, 7, 1, 1, 0, "future-facing"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("children", "Talk children", "You ask what kind of tiny disastrous family the two of you would build if you stopped joking and started planning.", 2, 4, 4, 5, 0, 0, 8, 2, 0, 1, "family-minded"));
				break;
			default:
				EmpressTryAddChoice(choices, EmpressMakeChoice("devotion", "Show devotion", "You prove the relationship is not just words by choosing the inconvenient, loyal thing.", 2, 5, 4, 4, -2, -3, 9, 2, -2, 0, "devoted"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("children", "Talk children", "You ask what kind of tiny disastrous family the two of you would build if you stopped joking and started planning.", 2, 4, 4, 5, 0, 0, 8, 2, 0, 1, "family-minded"));
				EmpressTryAddChoice(choices, EmpressMakeChoice("choose_them", "Choose them", "You make the choice explicit: not convenient, not accidental, not because they were closest. Them.", 2, 4, 4, 4, -2, -2, 8, 2, -2, 0, "chosen"));
				break;
			}
		}

		private static List<EmpressDateChoice> EmpressFinalizeChoices(EmpressRelationship relationship, List<EmpressDateChoice> choices)
		{
			EmpressRelationship relationship2 = relationship;
			List<EmpressDateChoice> list = choices.Where((EmpressDateChoice choice) => choice != null && !string.Equals(choice.Id, relationship2.LastChoiceId, StringComparison.OrdinalIgnoreCase)).Take(4).ToList();
			if (list.Count < 4)
			{
				foreach (EmpressDateChoice choice2 in choices)
				{
					if (choice2 != null && !list.Any((EmpressDateChoice existing) => existing.Id == choice2.Id))
					{
						list.Add(choice2);
						if (list.Count >= 4)
						{
							break;
						}
					}
				}
			}
			return list;
		}

		private static EmpressDateChoice EmpressMakeChoice(string id, string label, string playerAction, int style, int love, int trust, int mood, int jealousy, int anger, int commitment, int secret, int suspicion, int children, string memoryTag)
		{
			return new EmpressDateChoice
			{
				Id = id,
				Label = label,
				PlayerAction = playerAction,
				Style = style,
				LoveBonus = love,
				TrustBonus = trust,
				MoodBonus = mood,
				JealousyBonus = jealousy,
				AngerBonus = anger,
				CommitmentBonus = commitment,
				SecretBonus = secret,
				SuspicionBonus = suspicion,
				ChildrenBonus = children,
				MemoryTag = memoryTag
			};
		}

		private static void EmpressTryAddChoice(List<EmpressDateChoice> choices, EmpressDateChoice choice)
		{
			EmpressDateChoice choice2 = choice;
			if (!choices.Any((EmpressDateChoice existing) => existing.Id == choice2.Id))
			{
				choices.Add(choice2);
			}
		}

		private void EmpressChoose(int choiceIndex)
		{
			if (_activeTarget != null && choiceIndex >= 0 && choiceIndex < _activeChoices.Count)
			{
				EmpressDateTarget activeTarget = _activeTarget;
				EmpressRelationship relationship = activeTarget.Relationship;
				EmpressDateChoice empressDateChoice = _activeChoices[choiceIndex];
				int num = Mathf.Clamp(_plugin.LoveGainPerDate.Value + empressDateChoice.LoveBonus + _random.Next(0, 4), 0, 100);
				int love = relationship.Love;
				relationship.Love = Mathf.Clamp(relationship.Love + num, 0, 100);
				relationship.Trust = Mathf.Clamp(relationship.Trust + empressDateChoice.TrustBonus + ((empressDateChoice.Style == 0) ? 1 : 0), 0, 100);
				relationship.Mood = Mathf.Clamp(relationship.Mood + empressDateChoice.MoodBonus - Mathf.RoundToInt((float)relationship.Anger * 0.04f), -100, 100);
				relationship.Jealousy = Mathf.Clamp(relationship.Jealousy + empressDateChoice.JealousyBonus + ((empressDateChoice.Style == 2 && !string.IsNullOrWhiteSpace(relationship.LastOtherName)) ? 1 : 0), 0, 100);
				relationship.Anger = Mathf.Clamp(relationship.Anger + empressDateChoice.AngerBonus, 0, 100);
				relationship.Commitment = Mathf.Clamp(relationship.Commitment + empressDateChoice.CommitmentBonus + ((relationship.Love >= 60) ? 1 : 0), 0, 100);
				relationship.SecretDepth = Mathf.Clamp(relationship.SecretDepth + empressDateChoice.SecretBonus, 0, 100);
				relationship.Suspicion = Mathf.Clamp(relationship.Suspicion + empressDateChoice.SuspicionBonus, 0, 100);
				relationship.MemoryScore = Mathf.Clamp(relationship.MemoryScore + 3 + Mathf.Max(0, num / 4) + empressDateChoice.TrustBonus + empressDateChoice.SecretBonus, 0, 9999);
				relationship.Children = Mathf.Clamp(relationship.Children + empressDateChoice.ChildrenBonus, 0, 99);
				relationship.LastStyle = empressDateChoice.MemoryTag;
				relationship.LastChoiceId = empressDateChoice.Id;
				relationship.Dates++;
				relationship.LastMetTicks = DateTime.UtcNow.Ticks;
				relationship.LastOtherName = ((_lastCommittedKey != activeTarget.Key) ? _lastCommittedName : relationship.LastOtherName);
				EmpressRecalculateStoryProgress(relationship, empressDateChoice, num);
				_activeFollowUpQuestion = ((relationship.Love >= 100 && love < 100) ? "" : EmpressFollowUpQuestion(activeTarget, relationship, empressDateChoice));
				_activeAnswerChoices.Clear();
				if (!string.IsNullOrWhiteSpace(_activeFollowUpQuestion))
				{
					_activeAnswerChoices.AddRange(EmpressBuildAnswerChoices(activeTarget, relationship, empressDateChoice, _activeFollowUpQuestion));
				}
				List<string> list = EmpressResolveAftermath(activeTarget, relationship, empressDateChoice, num, love);
				relationship.LastLine = EmpressRelationshipLine(activeTarget, relationship, empressDateChoice, num, _activeFollowUpQuestion);
				if (list.Count > 0)
				{
					relationship.LastLine = relationship.LastLine + "\n\n" + string.Join("\n\n", list);
				}
				_lastCommittedKey = activeTarget.Key;
				_lastCommittedName = activeTarget.Name;
				_dateWaitingForChoice = false;
				_dateWaitingForAnswer = _activeAnswerChoices.Count > 0;
				_dateWaitingAfterChoice = !_dateWaitingForAnswer;
				EmpressSetDateDialog(EmpressBuildDateTitle(activeTarget), relationship.LastLine, _dateWaitingForAnswer ? EmpressAnswerOptions() : EmpressAfterChoiceOptions(activeTarget));
				EmpressSave();
				EmpressRefreshRelationships();
			}
		}

		private List<string> EmpressResolveAftermath(EmpressDateTarget target, EmpressRelationship relationship, EmpressDateChoice choice, int gain, int previousLove)
		{
			List<string> list = new List<string>();
			string text = EmpressSpreadGossip(target, relationship, choice.Style);
			if (!string.IsNullOrWhiteSpace(text))
			{
				list.Add(text);
			}
			string text2 = EmpressMaybeRelationshipConsequence(target, relationship, choice.Style);
			if (!string.IsNullOrWhiteSpace(text2))
			{
				list.Add(text2);
			}
			if (choice.ChildrenBonus > 0)
			{
				list.Add("<color=#ffe5aa><b><u>FAMILY</u></b></color> The two of you leave the conversation with " + relationship.Children + " chaotic future child" + ((relationship.Children == 1) ? "" : "ren") + " on the mental ledger.");
			}
			if (previousLove < 100 && relationship.Love >= 100)
			{
				relationship.Commitment = 100;
				relationship.MemorySummary = "Maxed out on date " + relationship.Dates + "; ready to physically follow you into worse decisions.";
				list.Add(target.Name + " hits maximum affection. The relationship has stopped being theoretical. Press 5 to let them follow you.");
			}
			else
			{
				relationship.MemorySummary = EmpressBuildMemorySummary(target, relationship);
			}
			return list;
		}

		private static void EmpressRecalculateStoryProgress(EmpressRelationship relationship, EmpressDateChoice choice, int gain)
		{
			if (relationship != null && choice != null)
			{
				int num = gain + choice.TrustBonus + choice.CommitmentBonus * 2 + choice.SecretBonus + Mathf.Max(0, choice.MoodBonus) + ((choice.Id == "apologize" || choice.Id == "repair") ? 8 : 0);
				int num2 = relationship.Anger * 2 + relationship.Jealousy + relationship.Betrayals * 18 + Mathf.Max(0, choice.AngerBonus) * 3 + Mathf.Max(0, choice.JealousyBonus);
				int num3 = relationship.Dates * 11 + relationship.Love + relationship.Trust + relationship.Commitment * 2 + relationship.SecretDepth + relationship.Children * 10 + Mathf.RoundToInt((float)relationship.Mood * 0.25f) + num - num2;
				int num4 = Mathf.Clamp(num3 / 32, 0, 8);
				int num5 = Mathf.Clamp(relationship.StoryStage, 0, 8);
				if (num4 > num5 + 1)
				{
					num4 = num5 + 1;
				}
				else if (num4 < num5 - 1)
				{
					num4 = num5 - 1;
				}
				relationship.StoryStage = num4;
				relationship.StoryMomentum = Mathf.Clamp(num3, -999, 9999);
			}
		}

		private static void EmpressRecalculateStoryProgressFromAnswer(EmpressRelationship relationship, EmpressDateAnswerChoice answer)
		{
			if (relationship != null && answer != null)
			{
				int num = relationship.StoryMomentum + answer.LoveBonus + answer.TrustBonus + answer.CommitmentBonus * 2 + answer.SecretBonus + Mathf.Max(0, answer.MoodBonus) - relationship.Anger - relationship.Jealousy / 2 - Mathf.Max(0, answer.AngerBonus) * 3;
				int num2 = Mathf.Clamp(num / 34, 0, 8);
				int num3 = Mathf.Clamp(relationship.StoryStage, 0, 8);
				if (num2 > num3 + 1)
				{
					num2 = num3 + 1;
				}
				else if (num2 < num3 - 1)
				{
					num2 = num3 - 1;
				}
				relationship.StoryStage = num2;
				relationship.StoryMomentum = Mathf.Clamp(num, -999, 9999);
			}
		}

		private static void EmpressBackfillStoryProgress(EmpressRelationship relationship)
		{
			if (relationship != null)
			{
				int num = relationship.Dates * 11 + relationship.Love + relationship.Trust + relationship.Commitment * 2 + relationship.SecretDepth + relationship.Children * 10 + Mathf.RoundToInt((float)relationship.Mood * 0.25f) - relationship.Anger * 2 - relationship.Jealousy - relationship.Betrayals * 18;
				relationship.StoryStage = Mathf.Clamp(num / 32, 0, 8);
				relationship.StoryMomentum = Mathf.Clamp(num, -999, 9999);
			}
		}

		private string EmpressSpreadGossip(EmpressDateTarget target, EmpressRelationship current, int style)
		{
			string text = "";
			if (!string.IsNullOrWhiteSpace(_lastCommittedKey) && _lastCommittedKey != target.Key && _relationships.TryGetValue(_lastCommittedKey, out EmpressRelationship value))
			{
				value.Jealousy = Mathf.Clamp(value.Jealousy + ((style == 2) ? 7 : 4), 0, 100);
				value.Suspicion = Mathf.Clamp(value.Suspicion + Mathf.Max(3, current.Love / 12), 0, 100);
				value.LastOtherName = target.Name;
				if (EmpressRollDiscovery(value, current, style))
				{
					value.Anger = Mathf.Clamp(value.Anger + 12 + ((style == 2) ? 8 : 3), 0, 100);
					value.Betrayals++;
					value.LastBadThing = "Found out you were seeing " + target.Name + ".";
					value.MemorySummary = "They remember " + target.Name + " and are deciding how dramatic to be about it.";
					text = value.Name + " finds out about this date. Somewhere in the building, jealousy learned your route.";
				}
			}
			foreach (EmpressRelationship value2 in _relationships.Values)
			{
				if (value2 != current && !(value2.Key == target.Key) && value2.Dates > 0 && (value2.Love >= 45 || value2.Commitment >= 35))
				{
					int num = Mathf.Clamp(2 + current.Love / 18 + value2.Commitment / 18 + ((style == 2) ? 4 : 0), 2, 14);
					value2.Suspicion = Mathf.Clamp(value2.Suspicion + num, 0, 100);
					value2.Jealousy = Mathf.Clamp(value2.Jealousy + Mathf.Max(1, num / 2), 0, 100);
					if (string.IsNullOrWhiteSpace(value2.LastOtherName))
					{
						value2.LastOtherName = target.Name;
					}
					if (string.IsNullOrWhiteSpace(text) && EmpressRollDiscovery(value2, current, style))
					{
						value2.Anger = Mathf.Clamp(value2.Anger + 8 + num, 0, 100);
						value2.Betrayals++;
						value2.LastOtherName = target.Name;
						value2.LastBadThing = "Caught feelings leaking toward " + target.Name + ".";
						value2.MemorySummary = "They caught the pattern: you, " + target.Name + ", and a suspicious amount of eye contact.";
						text = value2.Name + " notices the pattern. They do not interrupt. That is somehow worse.";
					}
				}
			}
			current.Suspicion = Mathf.Clamp(current.Suspicion + ((style == 2 && !string.IsNullOrWhiteSpace(current.LastOtherName)) ? 4 : (-1)), 0, 100);
			return text;
		}

		private bool EmpressRollDiscovery(EmpressRelationship watcher, EmpressRelationship current, int style)
		{
			if (watcher == null || current == null || watcher.Key == current.Key)
			{
				return false;
			}
			int num = Mathf.Clamp(_plugin.BetrayalSensitivity.Value / 3 + watcher.Suspicion + watcher.Jealousy / 2 + watcher.Commitment / 4 + ((style == 2) ? 10 : 0) - watcher.Trust / 3, 0, 92);
			return _random.Next(0, 100) < num;
		}

		private string EmpressBuildMemorySummary(EmpressDateTarget target, EmpressRelationship relationship)
		{
			if (relationship.Betrayals > 0 && relationship.Anger >= 45)
			{
				return "They remember the betrayal count: " + relationship.Betrayals + ". " + relationship.LastOtherName + " is still a problem.";
			}
			if (relationship.Children > 0)
			{
				return "They keep talking like your " + relationship.Children + " hypothetical child" + ((relationship.Children == 1) ? "" : "ren") + " already need school supplies.";
			}
			if (relationship.GiftsGiven > 0 && relationship.LastGiftName.Length > 0)
			{
				return "They last gave you " + relationship.LastGiftName + " and are absolutely keeping score.";
			}
			if (relationship.SecretDepth >= 30)
			{
				return "They trust you with lore now. That is basically second base for haunted furniture.";
			}
			if (relationship.Following)
			{
				return "They are following you in physical space because maximum affection ignores architecture.";
			}
			return "They remember date " + relationship.Dates + ", your " + relationship.LastStyle + " tone, and the way you looked at " + target.ObservedName + ".";
		}

		private string EmpressBuildOpening(EmpressDateTarget target)
		{
			EmpressRelationship relationship = target.Relationship;
			List<string> list = new List<string>
			{
				EmpressStoryBeatLine(target, relationship, opening: true),
				(relationship.Dates <= 0 || relationship.StoryStage <= 1) ? EmpressCastLore(target) : EmpressStageLoreLine(target, relationship)
			};
			if (relationship.Dates > 0 && relationship.StoryStage > 0)
			{
				list.Add(target.Name + " treats this like chapter " + (relationship.StoryStage + 1) + ", not a reset. Date " + (relationship.Dates + 1) + " has to answer for everything date " + relationship.Dates + " changed.");
			}
			if (!string.IsNullOrWhiteSpace(relationship.LastStyle))
			{
				list.Add("\"Last time you were " + relationship.LastStyle + ",\" " + target.Name + " says. \"So pick carefully. I am building a pattern out of you.\"");
			}
			if (!string.IsNullOrWhiteSpace(relationship.MemorySummary))
			{
				list.Add("Memory: " + relationship.MemorySummary);
			}
			if (relationship.Anger >= 55)
			{
				list.Add(target.Name + " is angry enough to make the UI feel watched. Gifts may become consequences if you keep playing messy.");
			}
			else if (relationship.GiftsGiven > 0 && !string.IsNullOrWhiteSpace(relationship.LastGiftName))
			{
				list.Add(target.Name + " remembers gifting you " + relationship.LastGiftName + ". This generosity has a receipt.");
			}
			if (relationship.Love >= 100)
			{
				list.Add(relationship.Following ? (target.Name + " is already following you. Press 5 if you need them to stay put.") : (target.Name + " is maxed out and ready to follow. Press 5 to invite them off the map and into your bad decisions."));
			}
			if (relationship.Children > 0)
			{
				list.Add(target.Name + " keeps mentioning your " + relationship.Children + " hypothetical child" + ((relationship.Children == 1) ? "" : "ren") + " like the nursery paperwork is already spiritually filed.");
			}
			if (!string.IsNullOrWhiteSpace(_lastCommittedKey) && _lastCommittedKey != target.Key && _relationships.TryGetValue(_lastCommittedKey, out EmpressRelationship value) && value.Love >= 25)
			{
				list.Add(target.Name + " glances toward " + value.Name + ". \"So that is who you have been entertaining.\"");
				relationship.Jealousy = Mathf.Clamp(relationship.Jealousy + 1, 0, 100);
				relationship.LastOtherName = value.Name;
			}
			if (relationship.Jealousy >= 12 && !string.IsNullOrWhiteSpace(relationship.LastOtherName))
			{
				list.Add("\"Tell " + relationship.LastOtherName + " I said hi,\" " + target.Name + " says. Then softer: \"No. Do not. I want to be petty without witnesses.\"");
			}
			string text = EmpressConnectionLine(target);
			if (!string.IsNullOrWhiteSpace(text))
			{
				list.Add(text);
			}
			return string.Join("\n\n", list);
		}

		private string EmpressBuildContinuation(EmpressDateTarget target)
		{
			EmpressRelationship relationship = target.Relationship;
			List<string> list = new List<string> { EmpressStoryBeatLine(target, relationship, opening: false) };
			if (!string.IsNullOrWhiteSpace(relationship.MemorySummary))
			{
				list.Add("Memory: " + relationship.MemorySummary);
			}
			if (relationship.StoryMomentum < 0)
			{
				list.Add(target.Name + " is not resetting the mood for you. The score is below zero, which means the next choice has to repair something.");
			}
			else if (relationship.StoryStage >= 5)
			{
				list.Add(target.Name + " is close enough now that casual answers start sounding like lies.");
			}
			if (relationship.Love >= 100 && !relationship.Following)
			{
				list.Add(target.Name + " has reached the point where talking is no longer the final proof. Press 5 if you want them to follow.");
			}
			return string.Join("\n\n", list);
		}

		private static string EmpressStoryBeatLine(EmpressDateTarget target, EmpressRelationship relationship, bool opening)
		{
			if (relationship.Anger >= 55)
			{
				return target.Name + " keeps distance in the conversation. This is not a fresh scene; it is repair math, and anger is currently winning.";
			}
			if (relationship.Jealousy >= 30 && !string.IsNullOrWhiteSpace(relationship.LastOtherName))
			{
				return target.Name + " remembers " + relationship.LastOtherName + " before they look at you. The story has a triangle now, and triangles cut.";
			}
			switch (Mathf.Clamp(relationship.StoryStage, 0, 8))
			{
			case 0:
				if (!opening)
				{
					return target.Name + " waits instead of filling the silence. First contact is over; now the story wants evidence.";
				}
				return target.Name + " studies you like the first page of a terrible idea.\n\n\"If this is a joke, make it a good one. If it is not, prove it.\"";
			case 1:
				return target.Name + " recognizes you now. Not fully, not safely, but enough that your next move will not vanish into the noise.";
			case 2:
				return target.Name + " keeps one detail from last time and offers one back. The relationship has started trading receipts.";
			case 3:
				return target.Name + " lets the conversation get personal enough to become risky. This is where jokes start needing courage.";
			case 4:
				return target.Name + " is done pretending this is random. The bond has a shape now, and both of you can see the edges.";
			case 5:
				return target.Name + " talks like there is a future and then watches your face to see if you flinch.";
			case 6:
				return target.Name + " moves from wanting attention to wanting loyalty. That is a heavier currency.";
			case 7:
				return target.Name + " has reached the almost-impossible part: they believe you might choose them on purpose.";
			default:
				if (!relationship.Following)
				{
					return target.Name + " stands at the edge of the map like a promise waiting for permission to move.";
				}
				return target.Name + " is already part of your route now. The story continues only if you damage it or defend it.";
			}
		}

		private static string EmpressStageLoreLine(EmpressDateTarget target, EmpressRelationship relationship)
		{
			switch (Mathf.Clamp(relationship.StoryStage, 0, 8))
			{
			case 2:
				return target.Name + " has moved from novelty to memory. They remember what you chose, not just that you showed up.";
			case 3:
				return target.Name + " starts giving you the parts of the story that do not fit on a price tag, health bar, or tooltip.";
			case 4:
				return target.Name + " is measuring whether this relationship is a habit, a promise, or a very stylish mistake.";
			case 5:
				return target.Name + " lets the future into the room and watches what it does to your posture.";
			case 6:
				return target.Name + " has stopped asking if you care and started asking what your care can survive.";
			case 7:
				return target.Name + " is close enough to follow, but they still need the final proof to be an action.";
			default:
				if (!relationship.Following)
				{
					return target.Name + " is at the edge of follower territory. The story is waiting for the body to move.";
				}
				return target.Name + " has already crossed from story into companion. The next chapter only opens if you protect it or break it.";
			}
		}

		private string EmpressRelationshipLine(EmpressDateTarget target, EmpressRelationship relationship, EmpressDateChoice choice, int gain, string followUpQuestion)
		{
			List<string> list = new List<string> { EmpressIntimateResponse(target, relationship, choice, gain) };
			if (relationship.Love >= 60 && relationship.Trust >= 25)
			{
				list.Add(target.Name + " lets the mask slip a little. There is history here now, not just a joke with a progress bar.");
			}
			else if (relationship.Love >= 30)
			{
				list.Add(target.Name + " is starting to expect you. That is sweet. That is also how curses get paperwork.");
			}
			if (relationship.Jealousy >= 18)
			{
				list.Add("\"You collect hearts like scrap,\" " + target.Name + " says. \"Cute. Dangerous. Mostly dangerous.\"");
			}
			if (relationship.Category == "Enemy" && choice.Style == 0)
			{
				list.Add("The violence in the room lowers by one emotional notch. Not enough to be safe, but enough to be interesting.");
			}
			if (relationship.Category == "Valuable" && choice.Style == 1)
			{
				list.Add(target.Name + " explains value is not price. Empress immediately writes that down and pretends she knew.");
			}
			if (relationship.Category == "Extractor" && relationship.Love >= 40)
			{
				list.Add("The extractor hums softer around you. It still wants your loot, but now it feels guilty about it.");
			}
			if (!string.IsNullOrWhiteSpace(followUpQuestion))
			{
				list.Add("<color=#ebd3a1><b>" + EmpressRichEscape(target.Name) + " asks:</b></color> \"" + EmpressRichEscape(followUpQuestion) + "\"");
			}
			return string.Join("\n\n", list);
		}

		private string EmpressOpeningLine(EmpressDateTarget target, EmpressRelationship relationship)
		{
			if (relationship.Dates <= 0)
			{
				return target.Name + " studies you for a long second.\n\n\"So you are the one who keeps looking at things like they might answer back. Careful. Some of us do.\"";
			}
			if (relationship.Love >= 70)
			{
				return target.Name + " brightens in a way it would deny if anyone asked.\n\n\"There you are. I was trying not to miss you. I failed in a very undignified way.\"";
			}
			if (relationship.Jealousy >= 20)
			{
				return target.Name + " does not smile.\n\n\"I know you have been talking to others. I am not angry. I am collecting evidence.\"";
			}
			if (relationship.Trust >= 35)
			{
				return target.Name + " lowers its guard like something unlocking from the inside.\n\n\"You make this place quieter. Not safe. Just quieter. I think that matters.\"";
			}
			return EmpressFormat(EmpressPick(EmpressOpeners), target, relationship, 0);
		}

		private string EmpressIntimateResponse(EmpressDateTarget target, EmpressRelationship relationship, EmpressDateChoice choice, int gain)
		{
			return choice.PlayerAction + "\n\n" + target.Name + " answers, \"" + EmpressChoiceAnswer(target, relationship, choice) + "\"\n\n" + EmpressChoiceStatsLine(relationship, gain, choice);
		}

		private string EmpressChoiceAnswer(EmpressDateTarget target, EmpressRelationship relationship, EmpressDateChoice choice)
		{
			switch (choice.Id)
			{
			case "admire":
				if (relationship.Love < 65)
				{
					return "That landed. I am trying to act normal about it and failing with some style.";
				}
				return "You make me feel seen in a way that should honestly void a warranty.";
			case "memory":
				return EmpressLoreAnswer(target, relationship);
			case "date":
				if (relationship.Love < 55)
				{
					return "You asking that plainly is somehow more dangerous than flirting.";
				}
				return "Yes. A real date. Pick somewhere dramatic enough to make this feel deserved.";
			case "flirt":
				return EmpressDesireAnswer(target, relationship);
			case "reassure":
				return "Good. Because I did not want another pretty answer. I wanted something I could actually lean on.";
			case "apologize":
				if (relationship.Betrayals <= 0)
				{
					return "I was ready to stay sharp. You made that harder.";
				}
				return "That apology cost you something. I can tell. Keep doing that.";
			case "secret":
				return "That is not small. I am keeping it anyway. Do not make me regret learning your soft parts.";
			case "define":
				if (relationship.Commitment < 55)
				{
					return "I wanted you to ask that before the building did it for us.";
				}
				return "Call it a relationship. Call it mutual ruin. Either way, stop pretending it is casual.";
			case "future":
				return "A future with you sounds unstable, expensive, and weirdly comforting. I hate how much I want details.";
			case "children":
				return "Our children would be impossible and probably brilliant. I am alarmed by how quickly I started naming them.";
			case "truce":
				return "I could choose peace with you for a little while. Do not waste how rare that is.";
			case "need":
				if (relationship.Trust < 35)
				{
					return "Patience. And maybe proof you are not here for the novelty alone.";
				}
				return "Consistency. Curiosity. Fewer disappearing acts. You know, luxury items.";
			case "listen":
				return "You actually listened. That is rarer than a good hiding spot and twice as suspicious.";
			case "boundary":
				return "You respected the line without making me thank you for it. That was... annoyingly attractive.";
			case "promise":
				return "A small promise is harder to fake than a grand one. I am going to remember whether you keep it.";
			case "vulnerability":
				return "There you are. Less polished, more real. I like that version better than the charming one.";
			case "ritual":
				return "A ritual means you expect there to be a next time. I am trying not to look pleased.";
			case "repair":
				return "Repair is not romantic until someone means it. This time, I think you might.";
			case "choose_them":
				return "Chosen on purpose. Fine. That hit somewhere inconvenient.";
			case "devotion":
				return "Do not perform devotion unless you can survive being believed. I am dangerously close to believing you.";
			default:
				if (choice.Style != 0)
				{
					if (choice.Style != 1)
					{
						return EmpressDesireAnswer(target, relationship);
					}
					return EmpressLoreAnswer(target, relationship);
				}
				return EmpressTenderAnswer(target, relationship);
			}
		}

		private string EmpressChoiceStatsLine(EmpressRelationship relationship, int gain, EmpressDateChoice choice)
		{
			List<string> list = new List<string>
			{
				"<color=#ffbfd3><b>Love +" + gain + "</b></color>",
				"<color=#abe6c0><b>Trust " + relationship.Trust + "%</b></color>",
				"<color=#f3c18c><b>Commitment " + relationship.Commitment + "%</b></color>",
				"<color=#f1a6c2><b>Jealousy " + relationship.Jealousy + "%</b></color>",
				"<color=#ff9e8d><b>Anger " + relationship.Anger + "%</b></color>",
				"<color=#d7cbb1><b>Memory " + relationship.MemoryScore + "</b></color>"
			};
			if (choice.ChildrenBonus > 0)
			{
				list.Add("<color=#ffe3a9><b>Children " + relationship.Children + "</b></color>");
			}
			return string.Join("   ", list);
		}

		private string EmpressFollowUpQuestion(EmpressDateTarget target, Empre