Decompiled source of GamblePvP v0.6.0

GambleWithYourFriendsPvP.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Extensions;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
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("GambleWithYourFriendsPvP")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GambleWithYourFriendsPvP")]
[assembly: AssemblyTitle("GambleWithYourFriendsPvP")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 GambleWithYourFriendsPvP
{
	public static class BetClampPatches
	{
		[HarmonyPatch(typeof(MoneyManager), "TryChangeBalance")]
		[HarmonyPrefix]
		public static void HappyHourMultiplier(ref long amount, PlayerProfile changer, ChangeType changeType)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			if (NetworkServer.active && !((Object)(object)changer == (Object)null) && (int)changeType == 1 && amount > 0 && HappyHourSystem.IsActive)
			{
				long num = (long)((float)amount * 1.5f);
				if (num > amount)
				{
					Plugin.Log.LogInfo((object)$"[HappyHour] Boosting {changer.playerName}'s payout {amount} -> {num}");
					amount = num;
				}
			}
		}

		[HarmonyPatch(typeof(MoneyManager), "TryChangeBalance")]
		[HarmonyPrefix]
		public static void HauntCurse(ref long amount, PlayerProfile changer, ChangeType changeType)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			if (NetworkServer.active && !((Object)(object)changer == (Object)null) && (int)changeType == 1 && amount > 0 && HauntSystem.IsHaunted(changer.steamId))
			{
				long num = (long)((float)amount * 0.5f);
				Plugin.Log.LogInfo((object)$"[Haunt] Curse on {changer.playerName}: payout {amount} -> {num}");
				amount = num;
			}
		}

		[HarmonyPatch(typeof(MoneyManager), "TryChangeBalance")]
		[HarmonyPrefix]
		public static void HotStreakMultiplier(ref long amount, PlayerProfile changer, ChangeType changeType)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			if ((Object)(object)changer == (Object)null || (int)changeType != 1 || amount <= 0)
			{
				return;
			}
			ModState instance = ModState.Instance;
			if (!((Object)(object)instance == (Object)null) && instance.Ledgers.TryGetValue(changer.steamId, out var value) && value.BuffHotStreak)
			{
				long num = (long)((float)amount * 1.25f);
				if (num != amount)
				{
					Plugin.Log.LogInfo((object)$"[HotStreak] {changer.playerName}: payout {amount} -> {num}");
					amount = num;
				}
			}
		}
	}
	public class BlackMarketBooth : MonoBehaviour
	{
		private TextMeshPro _signLabel;

		private TextMeshPro _itemLabel;

		public int SelectedItem { get; private set; }

		public void SetUI(TextMeshPro sign, TextMeshPro item)
		{
			_signLabel = sign;
			_itemLabel = item;
			RefreshLabels();
		}

		public void RefreshLabels()
		{
			if ((Object)(object)_signLabel != (Object)null)
			{
				((TMP_Text)_signLabel).text = "BLACK MARKET\nNO REFUNDS";
			}
			if ((Object)(object)_itemLabel != (Object)null)
			{
				int num = SelectedItem % BlackMarketSystem.Names.Length;
				string arg = BlackMarketSystem.Names[num];
				int num2 = BlackMarketSystem.Prices[num];
				string arg2 = BlackMarketSystem.Effects[num];
				((TMP_Text)_itemLabel).text = $"{arg}  -  {num2}♦\n{arg2}";
			}
		}

		public void Cycle()
		{
			SoundManager.Play(SoundManager.Cue.Click);
			SelectedItem = (SelectedItem + 1) % BlackMarketSystem.Names.Length;
			RefreshLabels();
		}

		public void Buy()
		{
			ulong num = ResolveLocalSteamId();
			if (num == 0L)
			{
				Plugin.Log.LogWarning((object)"[BlackMarket] No local steam id.");
				return;
			}
			SoundManager.Play(SoundManager.Cue.TakeLoan);
			int num2 = SelectedItem % BlackMarketSystem.Names.Length;
			Plugin.Log.LogInfo((object)$"[BlackMarket] Local player requesting purchase: item={num2}");
			NetSync.ClientRequestBlackMarketPurchase(num, num2);
		}

		private void Update()
		{
			RefreshLabels();
		}

		private static ulong ResolveLocalSteamId()
		{
			NetworkConnectionToServer connection = NetworkClient.connection;
			NetworkIdentity val = ((connection != null) ? ((NetworkConnection)connection).identity : null);
			if ((Object)(object)val != (Object)null)
			{
				PlayerProfile component = ((Component)val).GetComponent<PlayerProfile>();
				if ((Object)(object)component != (Object)null)
				{
					return component.steamId;
				}
			}
			if ((Object)(object)MonoSingleton<LocalManager>.Instance != (Object)null)
			{
				foreach (PlayerReferences player in MonoSingleton<LocalManager>.Instance.players)
				{
					if ((Object)(object)player?.identity != (Object)null && player.identity.isLocalPlayer)
					{
						return player.profile?.steamId ?? 0;
					}
				}
			}
			return 0uL;
		}
	}
	public static class BlackMarketSpawner
	{
		public static IEnumerator SpawnRoutine()
		{
			yield return (object)new WaitForSeconds(3f);
			NetSync.RegisterAll();
			LoanSharkSpawner.EnsureMaterialExternal();
			if ((Object)(object)GameObject.Find("[PvP] BlackMarketKiosk") != (Object)null)
			{
				Plugin.Log.LogInfo((object)"[BlackMarketSpawner] Booth already exists, skipping.");
				yield break;
			}
			Vector3 playerPos = Vector3.zero;
			float deadline = Time.time + 8f;
			while (Time.time < deadline)
			{
				playerPos = FindLocalPlayerPos();
				if (playerPos != Vector3.zero)
				{
					break;
				}
				yield return (object)new WaitForSeconds(0.5f);
			}
			Vector3 val = (Vector3)((playerPos != Vector3.zero) ? new Vector3(playerPos.x, playerPos.y - 1f, playerPos.z + 4f) : Vector3.zero);
			string arg = "player+4z (locked, no nudge)";
			Plugin.Log.LogInfo((object)$"[BlackMarketSpawner] Anchor: {arg} at {val} (player at {playerPos})");
			GameObject val2 = new GameObject("[PvP] BlackMarketKiosk");
			val2.transform.position = val;
			val2.transform.rotation = Quaternion.identity;
			BuildVisuals(val2);
			BlackMarketBooth booth = val2.AddComponent<BlackMarketBooth>();
			Transform obj = val2.transform.Find("Sign/SignText");
			TextMeshPro sign = ((obj != null) ? ((Component)obj).GetComponent<TextMeshPro>() : null);
			Transform obj2 = val2.transform.Find("Desk/ItemText");
			TextMeshPro item = ((obj2 != null) ? ((Component)obj2).GetComponent<TextMeshPro>() : null);
			booth.SetUI(sign, item);
			LoanSharkSpawner.AddInteractableExternal(val2.transform, new Vector3(-0.6f, 1.1f, -0.6f), "CycleItem", "Cycle Item", new Color(0.3f, 0.7f, 0.95f), delegate
			{
				booth.Cycle();
			});
			LoanSharkSpawner.AddInteractableExternal(val2.transform, new Vector3(0.6f, 1.1f, -0.6f), "Buy", "Buy", new Color(0.95f, 0.25f, 0.25f), delegate
			{
				booth.Buy();
			});
			Plugin.Log.LogInfo((object)$"[BlackMarketSpawner] Booth placed at {val2.transform.position}.");
		}

		private static void BuildVisuals(GameObject root)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)val).name = "Desk";
			val.transform.SetParent(root.transform, false);
			val.transform.localPosition = new Vector3(0f, 0.5f, 0f);
			val.transform.localScale = new Vector3(2.5f, 1f, 1f);
			LoanSharkSpawner.ApplyMaterialExternal(val, new Color(0.25f, 0.18f, 0.08f, 1f), glow: false);
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)val2).name = "Sign";
			val2.transform.SetParent(root.transform, false);
			val2.transform.localPosition = new Vector3(0f, 2.2f, 0f);
			val2.transform.localScale = new Vector3(2.8f, 1.5f, 0.05f);
			LoanSharkSpawner.ApplyMaterialExternal(val2, new Color(0.75f, 0.55f, 0.15f, 1f), glow: true);
			GameObject val3 = new GameObject("SignText");
			val3.transform.SetParent(val2.transform, false);
			val3.transform.localPosition = new Vector3(0f, 0f, -0.6f);
			val3.transform.localScale = new Vector3(0.4f, 2f / 3f, 20f);
			TextMeshPro obj = val3.AddComponent<TextMeshPro>();
			((TMP_Text)obj).text = "BLACK MARKET\nNO REFUNDS";
			((TMP_Text)obj).fontSize = 4f;
			((Graphic)obj).color = new Color(0.15f, 0.05f, 0f);
			((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
			GameObject val4 = new GameObject("ItemText");
			val4.transform.SetParent(val.transform, false);
			val4.transform.localPosition = new Vector3(0f, 0.51f, 0f);
			val4.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
			val4.transform.localScale = new Vector3(0.4f, 1f, 1f);
			TextMeshPro obj2 = val4.AddComponent<TextMeshPro>();
			((TMP_Text)obj2).fontSize = 2f;
			((Graphic)obj2).color = Color.white;
			((TMP_Text)obj2).alignment = (TextAlignmentOptions)514;
		}

		private static Vector3 FindLocalPlayerPos()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)MonoSingleton<LocalManager>.Instance != (Object)null && MonoSingleton<LocalManager>.Instance.players != null)
			{
				foreach (PlayerReferences player in MonoSingleton<LocalManager>.Instance.players)
				{
					if ((Object)(object)player?.identity != (Object)null && player.identity.isLocalPlayer && (Object)(object)player.transform != (Object)null)
					{
						return player.transform.position;
					}
				}
			}
			return Vector3.zero;
		}
	}
	public static class BlackMarketSystem
	{
		public enum Item : byte
		{
			SnitchInsurance,
			MobBribe,
			SweetTalk,
			BandageKit,
			GhostRepellent,
			HotStreak,
			LiquidCourage,
			LoanSharkPatience
		}

		public static readonly int[] Prices = new int[8] { 12, 15, 20, 18, 10, 22, 25, 18 };

		public static readonly string[] Names = new string[8] { "Snitch Insurance", "Mob Bribe", "Sweet Talk", "Bandage Kit", "Ghost Repellent", "Hot Streak", "Liquid Courage", "Loan Shark Patience" };

		public static readonly string[] Effects = new string[8] { "Next snitch against you auto-fails.", "Immune to one Hire Goons attack.", "Your next loan today is 1.0x interest.", "Instantly clears wounded penalty + refund.", "Next haunt against you fizzles.", "+25% casino payouts for the rest of the day.", "Wagers you win pay 2x today.", "Loans don't default today (no wounding)." };

		public static void TryPurchase(ulong steamId, int itemId)
		{
			if (!NetworkServer.active || itemId >= Prices.Length)
			{
				return;
			}
			ModState instance = ModState.Instance;
			if ((Object)(object)instance == (Object)null || instance.GameEnded)
			{
				return;
			}
			PlayerLedger orCreate = instance.GetOrCreate(steamId);
			if (orCreate.IsDead)
			{
				return;
			}
			int num = Prices[itemId];
			string text = Names[itemId];
			if (orCreate.PvpTickets < num)
			{
				NetSync.BroadcastToast($"{orCreate.DisplayName} couldn't afford {text} ({orCreate.PvpTickets}/{num} tickets).");
				return;
			}
			orCreate.PvpTickets -= num;
			switch ((Item)(byte)itemId)
			{
			case Item.SnitchInsurance:
				if (orCreate.BuffSnitchInsurance)
				{
					orCreate.PvpTickets += num;
					NetSync.BroadcastToast(orCreate.DisplayName + " already has Snitch Insurance.", ToastSeverity.Average);
					return;
				}
				orCreate.BuffSnitchInsurance = true;
				NetSync.BroadcastToast($"{orCreate.DisplayName} bought Snitch Insurance (-{num}t). Next snitch auto-fails.", ToastSeverity.Mid);
				break;
			case Item.MobBribe:
				if (orCreate.BuffMobBribe)
				{
					orCreate.PvpTickets += num;
					NetSync.BroadcastToast(orCreate.DisplayName + " already has a Mob Bribe.", ToastSeverity.Average);
					return;
				}
				orCreate.BuffMobBribe = true;
				NetSync.BroadcastToast($"{orCreate.DisplayName} bought a Mob Bribe (-{num}t). Immune to one goons hit.", ToastSeverity.Mid);
				break;
			case Item.SweetTalk:
				if (orCreate.BuffSweetTalk)
				{
					orCreate.PvpTickets += num;
					NetSync.BroadcastToast(orCreate.DisplayName + " already has Sweet Talk queued.", ToastSeverity.Average);
					return;
				}
				orCreate.BuffSweetTalk = true;
				NetSync.BroadcastToast($"{orCreate.DisplayName} bought Sweet Talk (-{num}t). Next loan at 1.0x.", ToastSeverity.Mid);
				break;
			case Item.BandageKit:
			{
				long woundedPenaltyRefund = orCreate.WoundedPenaltyRefund;
				if (woundedPenaltyRefund > 0)
				{
					orCreate.WoundedPenaltyRefund = 0L;
					MoneyManager instance2 = NetworkSingleton<MoneyManager>.Instance;
					if (instance2 != null)
					{
						instance2.TryChangeBalance(woundedPenaltyRefund, (PlayerProfile)null, (ChangeType)4);
					}
					orCreate.Ledger += woundedPenaltyRefund;
					NetSync.BroadcastToast($"{orCreate.DisplayName} patched up with a Bandage Kit (-{num}t). Clawed back ${woundedPenaltyRefund}.", ToastSeverity.Mid);
					break;
				}
				orCreate.PvpTickets += num;
				NetSync.BroadcastToast(orCreate.DisplayName + " bought a Bandage Kit but had nothing to heal. Refunded.", ToastSeverity.Average);
				return;
			}
			case Item.GhostRepellent:
				if (orCreate.BuffGhostRepellent)
				{
					orCreate.PvpTickets += num;
					NetSync.BroadcastToast(orCreate.DisplayName + " already has Ghost Repellent.", ToastSeverity.Average);
					return;
				}
				orCreate.BuffGhostRepellent = true;
				NetSync.BroadcastToast($"{orCreate.DisplayName} bought Ghost Repellent (-{num}t). Next haunt fizzles.", ToastSeverity.Mid);
				break;
			case Item.HotStreak:
				if (orCreate.BuffHotStreak)
				{
					orCreate.PvpTickets += num;
					NetSync.BroadcastToast(orCreate.DisplayName + " is already on a Hot Streak.", ToastSeverity.Average);
					return;
				}
				orCreate.BuffHotStreak = true;
				NetSync.BroadcastToast($"{orCreate.DisplayName} bought Hot Streak (-{num}t). +25% payouts today.", ToastSeverity.Mid);
				break;
			case Item.LiquidCourage:
				if (orCreate.BuffLiquidCourage)
				{
					orCreate.PvpTickets += num;
					NetSync.BroadcastToast(orCreate.DisplayName + " is already loaded with Liquid Courage.", ToastSeverity.Average);
					return;
				}
				orCreate.BuffLiquidCourage = true;
				NetSync.BroadcastToast($"{orCreate.DisplayName} bought Liquid Courage (-{num}t). Wagers win double today.", ToastSeverity.Mid);
				break;
			case Item.LoanSharkPatience:
				if (orCreate.BuffLoanShark)
				{
					orCreate.PvpTickets += num;
					NetSync.BroadcastToast(orCreate.DisplayName + " already paid for Patience today.", ToastSeverity.Average);
					return;
				}
				orCreate.BuffLoanShark = true;
				NetSync.BroadcastToast($"{orCreate.DisplayName} bought Loan Shark Patience (-{num}t). No defaults today.", ToastSeverity.Mid);
				break;
			}
			Plugin.Log.LogInfo((object)$"[BlackMarket] {orCreate.DisplayName} bought {text} for {num} tickets. Remaining tickets: {orCreate.PvpTickets}.");
			NetSync.BroadcastLedgerUpdate(orCreate);
		}
	}
	public static class BodyPartPayoutPatches
	{
		[HarmonyPatch(typeof(MoneyManager), "TryChangeBalance")]
		[HarmonyPrefix]
		public static void Reduce(ref long amount, PlayerProfile changer, ChangeType changeType)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Invalid comparison between Unknown and I4
			if ((Object)(object)changer == (Object)null || (int)changeType != 1 || amount <= 0)
			{
				return;
			}
			ModState instance = ModState.Instance;
			if (!((Object)(object)instance == (Object)null) && instance.Ledgers.TryGetValue(changer.steamId, out var value) && value.BodyPartsSold > 0)
			{
				float num = Math.Max(0f, 1f - 0.1f * (float)value.BodyPartsSold);
				long num2 = (long)((float)amount * num);
				if (num2 != amount)
				{
					Plugin.Log.LogInfo((object)$"[BodyParts] {changer.playerName} (-{10 * value.BodyPartsSold}% debuff): payout {amount} -> {num2}");
					amount = num2;
				}
			}
		}
	}
	public static class BotHudPatches
	{
		[HarmonyPatch(typeof(MoneyDisplayAndFeedbacks), "GetCurrentPlayerIds")]
		[HarmonyPostfix]
		public static void GetCurrentPlayerIds_Postfix(ref HashSet<ulong> __result)
		{
			if (!Plugin.BotsEnabled.Value)
			{
				return;
			}
			if (__result == null)
			{
				__result = new HashSet<ulong>();
			}
			int num = BotSystem.BotCountInUse();
			for (int i = 0; i < num; i++)
			{
				ulong botSteamId = BotSystem.GetBotSteamId(i);
				if (botSteamId != 0L)
				{
					__result.Add(botSteamId);
				}
			}
		}

		[HarmonyPatch(typeof(MoneyDisplayAndFeedbacks), "GetPlayerDisplayName")]
		[HarmonyPrefix]
		public static bool GetPlayerDisplayName_Prefix(ulong steamId, ref string __result)
		{
			string botName = BotSystem.GetBotName(steamId);
			if (botName != null)
			{
				__result = botName;
				return false;
			}
			return true;
		}
	}
	public static class BotSystem
	{
		private static readonly ulong[] BotSteamIds = new ulong[3] { 7700000000000001uL, 7700000000000002uL, 7700000000000003uL };

		private static readonly string[] DefaultBotNames = new string[3] { "Vinny", "Tony", "Sal" };

		private static float _nextTick = 0f;

		private static bool _initialized = false;

		public static void Init()
		{
			if (!NetworkServer.active || !Plugin.BotsEnabled.Value || _initialized)
			{
				return;
			}
			NetSync.RegisterAll();
			_initialized = true;
			int num = Mathf.Clamp(Plugin.BotCount.Value, 1, BotSteamIds.Length);
			ModState instance = ModState.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				for (int i = 0; i < num; i++)
				{
					string text = DefaultBotNames[i];
					PlayerLedger orCreate = instance.GetOrCreate(BotSteamIds[i], text);
					Plugin.Log.LogInfo((object)$"[BotSystem] Spawned bot: {text} (steamId {BotSteamIds[i]})");
					NetSync.BroadcastLedgerUpdate(orCreate);
				}
				NetSync.BroadcastToast($"Test bots active: {num} rival" + ((num == 1) ? "" : "s") + " — gambling, loaning, and pestering you.");
			}
		}

		public static void PreviewInLobby()
		{
			if (NetworkServer.active && Plugin.BotsEnabled.Value)
			{
				NetSync.RegisterAll();
				int num = Mathf.Clamp(Plugin.BotCount.Value, 1, BotSteamIds.Length);
				string text = string.Join(", ", DefaultBotNames, 0, num);
				NetSync.BroadcastToast($"[Bots enabled] {num} rival" + ((num == 1) ? "" : "s") + " will join at the casino: " + text);
				Plugin.Log.LogInfo((object)$"[BotSystem] Lobby preview: {num} bots will spawn at casino entry.");
			}
		}

		public static int BotCountInUse()
		{
			return Mathf.Clamp(Plugin.BotCount.Value, 1, BotSteamIds.Length);
		}

		public static ulong GetBotSteamId(int index)
		{
			if (index < 0 || index >= BotSteamIds.Length)
			{
				return 0uL;
			}
			return BotSteamIds[index];
		}

		public static string GetBotName(ulong steamId)
		{
			for (int i = 0; i < BotSteamIds.Length; i++)
			{
				if (BotSteamIds[i] == steamId)
				{
					return DefaultBotNames[i];
				}
			}
			return null;
		}

		public static void Reset()
		{
			_initialized = false;
			_nextTick = 0f;
		}

		public static void Tick()
		{
			if (!NetworkServer.active || !Plugin.BotsEnabled.Value || Time.time < _nextTick)
			{
				return;
			}
			_nextTick = Time.time + Random.Range(8f, 15f);
			ModState instance = ModState.Instance;
			if ((Object)(object)instance == (Object)null || instance.GameEnded)
			{
				return;
			}
			int num = Mathf.Clamp(Plugin.BotCount.Value, 1, BotSteamIds.Length);
			for (int i = 0; i < num; i++)
			{
				if (!instance.Ledgers.TryGetValue(BotSteamIds[i], out var value) || value.IsDead)
				{
					continue;
				}
				float value2 = Random.value;
				if (value2 < 0.55f)
				{
					long num2 = Random.Range(-200, 300);
					value.Ledger += num2;
					NetSync.BroadcastLedgerUpdate(value);
					if (num2 >= 150)
					{
						NetSync.BroadcastToast($"{value.DisplayName} hit a winner (+${num2}).");
					}
					else if (num2 <= -150)
					{
						NetSync.BroadcastToast($"{value.DisplayName} ate a bad beat (${num2}).");
					}
				}
				else if (value2 < 0.7f)
				{
					if (value.ActiveLoanPrincipals.Count == 0)
					{
						long num3 = LoanSystem.GetMaxLoanForCurrentDay() / 4;
						if (num3 >= 25)
						{
							LoanSystem.TryGrantLoan(value.SteamId, num3);
						}
					}
				}
				else if (value2 < 0.85f)
				{
					List<PlayerLedger> list = new List<PlayerLedger>();
					foreach (PlayerLedger value3 in instance.Ledgers.Values)
					{
						if (!value3.IsDead && value3.SteamId != value.SteamId && !IsBot(value3.SteamId))
						{
							list.Add(value3);
						}
					}
					if (list.Count > 0)
					{
						PlayerLedger playerLedger = list[Random.Range(0, list.Count)];
						int[] stakeChoices = WagerSystem.StakeChoices;
						long num4 = stakeChoices[Random.Range(0, stakeChoices.Length)];
						if (value.Wealth >= num4 && playerLedger.Wealth >= num4)
						{
							WagerSystem.TryWager(value.SteamId, playerLedger.SteamId, num4);
						}
					}
				}
				else
				{
					if (!(value2 < 0.95f))
					{
						continue;
					}
					List<PlayerLedger> list2 = new List<PlayerLedger>();
					foreach (PlayerLedger value4 in instance.Ledgers.Values)
					{
						if (!value4.IsDead && value4.SteamId != value.SteamId && !IsBot(value4.SteamId))
						{
							list2.Add(value4);
						}
					}
					if (list2.Count > 0)
					{
						PlayerLedger playerLedger2 = list2[Random.Range(0, list2.Count)];
						SnitchingSystem.TrySnitch(value.SteamId, playerLedger2.SteamId);
					}
				}
			}
		}

		public static bool IsBot(ulong steamId)
		{
			for (int i = 0; i < BotSteamIds.Length; i++)
			{
				if (BotSteamIds[i] == steamId)
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class CosmeticUnlockPatches
	{
		[HarmonyPatch(typeof(CosmeticsUnlockManager), "IsCosmeticUnlocked")]
		[HarmonyPrefix]
		public static bool IsCosmeticUnlocked_Prefix(ref bool __result)
		{
			__result = true;
			return false;
		}
	}
	public static class DaySummaryPatches
	{
		private static FieldInfo _fTicketSourcesRoot;

		private static FieldInfo _fEntryPrefab;

		private static FieldInfo _fEntrySourceText;

		private static FieldInfo _fEntryTicketsText;

		private static FieldInfo _fTitleText;

		private static FieldInfo _fTotalTicketsText;

		private static FieldInfo _fQuotaText;

		private static FieldInfo _fBalanceText;

		private static FieldInfo _fProfitText;

		private static bool _reflectionReady;

		private static void EnsureReflection()
		{
			if (!_reflectionReady)
			{
				Type? typeFromHandle = typeof(DaySummaryUI);
				_fTicketSourcesRoot = typeFromHandle.GetField("ticketSourcesRoot", BindingFlags.Instance | BindingFlags.NonPublic);
				_fEntryPrefab = typeFromHandle.GetField("ticketSourceEntryPrefab", BindingFlags.Instance | BindingFlags.NonPublic);
				_fTitleText = typeFromHandle.GetField("titleText", BindingFlags.Instance | BindingFlags.NonPublic);
				_fTotalTicketsText = typeFromHandle.GetField("totalTicketsText", BindingFlags.Instance | BindingFlags.NonPublic);
				_fQuotaText = typeFromHandle.GetField("quotaText", BindingFlags.Instance | BindingFlags.NonPublic);
				_fBalanceText = typeFromHandle.GetField("balanceText", BindingFlags.Instance | BindingFlags.NonPublic);
				_fProfitText = typeFromHandle.GetField("profitText", BindingFlags.Instance | BindingFlags.NonPublic);
				Type? typeFromHandle2 = typeof(DaySummaryTicketEntry);
				_fEntrySourceText = typeFromHandle2.GetField("sourceText", BindingFlags.Instance | BindingFlags.NonPublic);
				_fEntryTicketsText = typeFromHandle2.GetField("ticketsText", BindingFlags.Instance | BindingFlags.NonPublic);
				_reflectionReady = true;
			}
		}

		[HarmonyPatch(typeof(DaySummaryUI), "Show")]
		[HarmonyPostfix]
		public static void Show_Postfix(DaySummaryUI __instance)
		{
			try
			{
				EnsureReflection();
				((MonoBehaviour)__instance).StartCoroutine(InjectPvPStandings(__instance));
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"[DaySummaryPatches] Show postfix error: {arg}");
			}
		}

		[HarmonyPatch(typeof(DaySummaryUI), "AddTicketEntry")]
		[HarmonyPrefix]
		public static bool AddTicketEntry_Prefix()
		{
			return false;
		}

		private static IEnumerator InjectPvPStandings(DaySummaryUI ui)
		{
			yield return (object)new WaitForSeconds(6.5f);
			ModState state = ModState.Instance;
			if ((Object)(object)state == (Object)null || _fTicketSourcesRoot == null || _fEntryPrefab == null)
			{
				yield break;
			}
			object? value = _fTicketSourcesRoot.GetValue(ui);
			Transform ticketSourcesRoot = (Transform)((value is Transform) ? value : null);
			object? value2 = _fEntryPrefab.GetValue(ui);
			DaySummaryTicketEntry prefab = (DaySummaryTicketEntry)((value2 is DaySummaryTicketEntry) ? value2 : null);
			if ((Object)(object)ticketSourcesRoot == (Object)null || (Object)(object)prefab == (Object)null)
			{
				yield break;
			}
			for (int num = ticketSourcesRoot.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)ticketSourcesRoot.GetChild(num)).gameObject);
			}
			try
			{
				object? obj = _fTitleText?.GetValue(ui);
				TextMeshProUGUI val = (TextMeshProUGUI)((obj is TextMeshProUGUI) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					GameManager instance = NetworkSingleton<GameManager>.Instance;
					int num2 = (((Object)(object)instance != (Object)null) ? (instance.daysPassed + 1) : 0);
					((TMP_Text)val).text = ((num2 > 0) ? $"PvP Standings  ·  End of Day {num2}" : "PvP Standings");
				}
			}
			catch
			{
			}
			ApplyPvPStatBar(ui, state, alsoSwapLabels: true);
			List<PlayerLedger> ranked = new List<PlayerLedger>();
			foreach (PlayerLedger value3 in state.Ledgers.Values)
			{
				if (value3.SteamId != 0L && !string.IsNullOrEmpty(value3.DisplayName) && !(value3.DisplayName == "(unknown)"))
				{
					ranked.Add(value3);
				}
			}
			ranked.Sort((PlayerLedger a, PlayerLedger b) => b.Wealth.CompareTo(a.Wealth));
			int rank = 1;
			foreach (PlayerLedger item in ranked)
			{
				DaySummaryTicketEntry val2 = Object.Instantiate<DaySummaryTicketEntry>(prefab, ticketSourcesRoot);
				val2.Setup(item.DisplayName, 0);
				string text = (item.IsDead ? "x" : (rank switch
				{
					1 => "1st", 
					2 => "2nd", 
					3 => "3rd", 
					_ => $"#{rank}", 
				}));
				string text2 = (item.IsDead ? (text + "  " + item.DisplayName + "  DEAD") : ((!item.IsWounded) ? $"{text}  {item.DisplayName}  ♦{item.PvpTickets}" : $"{text}  {item.DisplayName}  wnd  ♦{item.PvpTickets}"));
				long num3 = item.Wealth - item.LoanPaybackOwed;
				string text3 = CompactDollars(num3);
				try
				{
					object? obj3 = _fEntrySourceText?.GetValue(val2);
					TextMeshProUGUI val3 = (TextMeshProUGUI)((obj3 is TextMeshProUGUI) ? obj3 : null);
					object? obj4 = _fEntryTicketsText?.GetValue(val2);
					TextMeshProUGUI val4 = (TextMeshProUGUI)((obj4 is TextMeshProUGUI) ? obj4 : null);
					if ((Object)(object)val3 != (Object)null)
					{
						((TMP_Text)val3).text = text2;
						if (item.IsDead)
						{
							((Graphic)val3).color = new Color(0.6f, 0.2f, 0.2f);
						}
						else
						{
							switch (rank)
							{
							case 1:
								((Graphic)val3).color = new Color(1f, 0.84f, 0f);
								break;
							case 2:
								((Graphic)val3).color = new Color(0.85f, 0.85f, 0.9f);
								break;
							case 3:
								((Graphic)val3).color = new Color(0.8f, 0.5f, 0.2f);
								break;
							}
						}
					}
					if ((Object)(object)val4 != (Object)null)
					{
						((TMP_Text)val4).text = text3;
						long num4 = Plugin.StartingMoney.Value;
						if (item.IsDead)
						{
							((Graphic)val4).color = new Color(0.6f, 0.2f, 0.2f);
						}
						else if (num3 > num4)
						{
							((Graphic)val4).color = new Color(0.35f, 1f, 0.45f);
						}
						else if (num3 < num4)
						{
							((Graphic)val4).color = new Color(1f, 0.45f, 0.45f);
						}
						else
						{
							((Graphic)val4).color = Color.white;
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[DaySummaryPatches] entry text override failed: " + ex.Message));
				}
				rank++;
				yield return (object)new WaitForSeconds(0.15f);
			}
			int num5 = 0;
			ulong winnerSteamId = 0uL;
			foreach (PlayerLedger item2 in ranked)
			{
				if (!item2.IsDead)
				{
					if (num5 == 0)
					{
						winnerSteamId = item2.SteamId;
					}
					num5++;
				}
			}
			int survivalAward = num5 * 2;
			int topEarnerAward = ((winnerSteamId != 0L) ? 3 : 0);
			int totalAward = survivalAward + topEarnerAward;
			if (survivalAward > 0)
			{
				DaySummaryTicketEntry obj5 = Object.Instantiate<DaySummaryTicketEntry>(prefab, ticketSourcesRoot);
				obj5.Setup($"Survived Day {(((Object)(object)ModState.Instance != (Object)null) ? ModState.Instance.CurrentDayIndex : 0)}  ({num5} survivor" + ((num5 == 1) ? "" : "s") + ")", survivalAward);
				obj5.SetImmediate();
				TintTicketEntry(obj5, ticketYellow: true);
				yield return (object)new WaitForSeconds(0.2f);
			}
			if (topEarnerAward > 0)
			{
				PlayerLedger playerLedger = ranked.Find((PlayerLedger x) => x.SteamId == winnerSteamId);
				string text4 = ((playerLedger != null) ? playerLedger.DisplayName : "?");
				DaySummaryTicketEntry obj6 = Object.Instantiate<DaySummaryTicketEntry>(prefab, ticketSourcesRoot);
				obj6.Setup("Top Earner (" + text4 + ")", topEarnerAward);
				obj6.SetImmediate();
				TintTicketEntry(obj6, ticketYellow: true);
				yield return (object)new WaitForSeconds(0.2f);
			}
			if (NetworkServer.active && totalAward > 0)
			{
				MoneyManager instance2 = NetworkSingleton<MoneyManager>.Instance;
				if ((Object)(object)instance2 != (Object)null)
				{
					try
					{
						instance2.TryChangeTicketBalance((long)totalAward);
						Plugin.Log.LogInfo((object)$"[DaySummaryPatches] PvP tickets granted: {totalAward} (survival {survivalAward} + top earner {topEarnerAward})");
					}
					catch (Exception ex2)
					{
						Plugin.Log.LogWarning((object)("[DaySummaryPatches] TryChangeTicketBalance failed: " + ex2.Message));
					}
				}
			}
			try
			{
				object? obj7 = _fTotalTicketsText?.GetValue(ui);
				TextMeshProUGUI val5 = (TextMeshProUGUI)((obj7 is TextMeshProUGUI) ? obj7 : null);
				if ((Object)(object)val5 != (Object)null)
				{
					MoneyManager instance3 = NetworkSingleton<MoneyManager>.Instance;
					((TMP_Text)val5).text = (((Object)(object)instance3 != (Object)null) ? instance3.ticketBalance : totalAward).ToString();
				}
			}
			catch
			{
			}
			float pollUntil = Time.time + 8f;
			while (Time.time < pollUntil)
			{
				ApplyPvPStatBar(ui, state, alsoSwapLabels: false);
				yield return (object)new WaitForSeconds(0.25f);
			}
		}

		private static void ApplyPvPStatBar(DaySummaryUI ui, ModState state, bool alsoSwapLabels)
		{
			try
			{
				ulong num = ResolveLocalSteamIdStatic();
				PlayerLedger value = null;
				if (num != 0L)
				{
					state.Ledgers.TryGetValue(num, out value);
				}
				int num2 = value?.TotalLoansTaken ?? 0;
				int num3 = value?.TotalSabotagesUsed ?? 0;
				int num4 = value?.TotalWagersWon ?? 0;
				if (alsoSwapLabels)
				{
					TextMeshProUGUI[] componentsInChildren = ((Component)ui).GetComponentsInChildren<TextMeshProUGUI>(true);
					foreach (TextMeshProUGUI val in componentsInChildren)
					{
						if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(((TMP_Text)val).text))
						{
							switch (((TMP_Text)val).text.Trim().ToUpperInvariant())
							{
							case "QUOTA":
								((TMP_Text)val).text = "LOANS";
								break;
							case "BALANCE":
								((TMP_Text)val).text = "SABOTAGES";
								break;
							case "PROFIT":
								((TMP_Text)val).text = "WAGERS WON";
								break;
							}
						}
					}
				}
				if (_fQuotaText?.GetValue(ui) is TextMeshProUGUI[] array)
				{
					TextMeshProUGUI[] componentsInChildren = array;
					foreach (TextMeshProUGUI val2 in componentsInChildren)
					{
						if ((Object)(object)val2 != (Object)null)
						{
							((TMP_Text)val2).text = num2.ToString();
						}
					}
				}
				object? obj = _fBalanceText?.GetValue(ui);
				TextMeshProUGUI val3 = (TextMeshProUGUI)((obj is TextMeshProUGUI) ? obj : null);
				if ((Object)(object)val3 != (Object)null)
				{
					((TMP_Text)val3).text = num3.ToString();
				}
				object? obj2 = _fProfitText?.GetValue(ui);
				TextMeshProUGUI val4 = (TextMeshProUGUI)((obj2 is TextMeshProUGUI) ? obj2 : null);
				if ((Object)(object)val4 != (Object)null)
				{
					((TMP_Text)val4).text = num4.ToString();
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[DaySummaryPatches] ApplyPvPStatBar failed: " + ex.Message));
			}
		}

		private static void TintTicketEntry(DaySummaryTicketEntry entry, bool ticketYellow)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				object? obj = _fEntrySourceText?.GetValue(entry);
				TextMeshProUGUI val = (TextMeshProUGUI)((obj is TextMeshProUGUI) ? obj : null);
				object? obj2 = _fEntryTicketsText?.GetValue(entry);
				TextMeshProUGUI val2 = (TextMeshProUGUI)((obj2 is TextMeshProUGUI) ? obj2 : null);
				if ((Object)(object)val != (Object)null)
				{
					((Graphic)val).color = new Color(0.95f, 0.85f, 0.4f);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					((Graphic)val2).color = new Color(1f, 0.84f, 0f);
				}
			}
			catch
			{
			}
		}

		private static ulong ResolveLocalSteamIdStatic()
		{
			if ((Object)(object)MonoSingleton<LocalManager>.Instance != (Object)null && MonoSingleton<LocalManager>.Instance.players != null)
			{
				foreach (PlayerReferences player in MonoSingleton<LocalManager>.Instance.players)
				{
					if ((Object)(object)player?.identity != (Object)null && player.identity.isLocalPlayer)
					{
						return player.profile?.steamId ?? 0;
					}
				}
			}
			return 0uL;
		}

		private static string CompactDollars(long v)
		{
			string arg = ((v < 0) ? "-" : "");
			long num = Math.Abs(v);
			if (num >= 1000000)
			{
				return $"{arg}${num / 1000000}M";
			}
			if (num >= 1000)
			{
				return $"{arg}${num / 1000}K";
			}
			return $"{arg}${num}";
		}
	}
	public static class EndGame
	{
		public static void TriggerEndGame()
		{
			if (!NetworkServer.active)
			{
				return;
			}
			ModState instance = ModState.Instance;
			if ((Object)(object)instance == (Object)null || instance.GameEnded)
			{
				return;
			}
			instance.MarkGameEnded();
			Plugin.Log.LogInfo((object)"[EndGame] Triggering end-game pipeline.");
			foreach (PlayerLedger value2 in instance.Ledgers.Values)
			{
				if (!value2.IsDead && value2.ActiveLoanPrincipal > 0)
				{
					long loanPaybackOwed = value2.LoanPaybackOwed;
					long num = Math.Min(Math.Max(0L, value2.Wealth), loanPaybackOwed);
					value2.Ledger -= num;
					value2.ActiveLoanPrincipal = 0L;
					Plugin.Log.LogInfo((object)$"[EndGame Clawback] {value2.DisplayName}: house took ${num}.");
				}
			}
			List<PlayerLedger> list = new List<PlayerLedger>();
			foreach (PlayerLedger value3 in instance.Ledgers.Values)
			{
				if (!value3.IsDead)
				{
					list.Add(value3);
				}
			}
			list.Sort((PlayerLedger a, PlayerLedger b) => b.Wealth.CompareTo(a.Wealth));
			long num2 = 0L;
			foreach (PlayerLedger item in list)
			{
				num2 += Math.Max(0L, item.Wealth);
			}
			int[] array = list.Count switch
			{
				0 => new int[0], 
				1 => new int[1] { 100 }, 
				2 => new int[2] { 60, 40 }, 
				_ => new int[3] { 50, 30, 20 }, 
			};
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("RESULTS|");
			for (int num3 = 0; num3 < list.Count; num3++)
			{
				PlayerLedger playerLedger = list[num3];
				long value = 0L;
				if (num3 < array.Length)
				{
					value = (long)Math.Round((double)num2 * ((double)array[num3] / 100.0));
				}
				stringBuilder.Append(EscapeCsv(playerLedger.DisplayName)).Append(',');
				stringBuilder.Append(playerLedger.Wealth).Append(',');
				stringBuilder.Append(value).Append(',');
				stringBuilder.Append((num3 + 1 == 1) ? "WIN" : "PLACED");
				if (num3 < list.Count - 1)
				{
					stringBuilder.Append('|');
				}
			}
			foreach (PlayerLedger value4 in instance.Ledgers.Values)
			{
				if (value4.IsDead)
				{
					stringBuilder.Append('|').Append(EscapeCsv(value4.DisplayName)).Append(",0,0,DEAD");
				}
			}
			string text = stringBuilder.ToString();
			Plugin.Log.LogInfo((object)("[EndGame] " + text));
			NetSync.BroadcastEndGame(text);
			EndGameUI.ShowFinalStandings(text);
			ModState instance2 = ModState.Instance;
			if ((Object)(object)instance2 != (Object)null)
			{
				((MonoBehaviour)instance2).StartCoroutine(DelayedSceneTransition());
			}
		}

		private static IEnumerator DelayedSceneTransition()
		{
			yield return (object)new WaitForSeconds(6f);
			try
			{
				GameManager instance = NetworkSingleton<GameManager>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					Plugin.Log.LogInfo((object)"[EndGame] Transitioning everyone to LoseStateScene for the death cutscene.");
					instance.ServerSetScene((GameState)2);
				}
				else
				{
					Plugin.Log.LogWarning((object)"[EndGame] GameManager not found for scene transition.");
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"[EndGame] Scene transition failed: {arg}");
			}
		}

		private static string EscapeCsv(string s)
		{
			return (s ?? "?").Replace(',', '_').Replace('|', '/');
		}
	}
	public enum ToastSeverity : byte
	{
		Average,
		Mid,
		Big
	}
	public class EndGameUI : MonoBehaviour
	{
		private class Toast
		{
			public string Text;

			public float Until;

			public ToastSeverity Severity;
		}

		private static readonly Queue<Toast> _toasts = new Queue<Toast>();

		private string _standingsPayload;

		private bool _showStandings;

		private bool _showStats;

		private string _currentSceneName = "";

		private GUIStyle _hudStyle;

		private GUIStyle _toastStyle;

		private GUIStyle _toastBigStyle;

		private GUIStyle _toastMidStyle;

		private GUIStyle _toastAvgStyle;

		private GUIStyle _standingStyle;

		private Texture2D _solidBlack;

		private Texture2D _solidRedish;

		private bool _forceLobbyControls;

		private int _hauntTargetIdx;

		private Vector2 _statsScroll;

		private Texture2D _zebraTex;

		private Texture2D _headerBarTex;

		private Texture2D _colHeaderTex;

		private GUIStyle _statsHeaderStyle;

		private GUIStyle _statsColHeaderStyle;

		private GUIStyle _statsCellStyle;

		private GUIStyle _statsCurrentStyle;

		private GUIStyle _statsRankStyle;

		private Vector2 _scroll;

		private GUIStyle _winnerStyle;

		private GUIStyle _placeStyle;

		private GUIStyle _deadStyle;

		private GUIStyle _bannerStyle;

		private Color _gold = new Color(1f, 0.84f, 0f);

		private Color _silver = new Color(0.85f, 0.85f, 0.9f);

		private Color _bronze = new Color(0.8f, 0.5f, 0.2f);

		private Color _deadCol = new Color(0.6f, 0.2f, 0.2f);

		private Texture2D _solidDark;

		public static EndGameUI Instance { get; private set; }

		private void Update()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			string name = ((Scene)(ref activeScene)).name;
			if (name != _currentSceneName)
			{
				_currentSceneName = name;
			}
		}

		private void Awake()
		{
			Instance = this;
		}

		public static void PushToast(string text)
		{
			PushToast(text, ToastSeverity.Average);
		}

		public static void PushToast(string text, ToastSeverity severity)
		{
			_toasts.Enqueue(new Toast
			{
				Text = text,
				Until = Time.unscaledTime + 6f,
				Severity = severity
			});
			Plugin.Log.LogInfo((object)$"[Toast {severity}] {text}");
		}

		public static ulong GetLocalSteamId()
		{
			if ((Object)(object)MonoSingleton<LocalManager>.Instance != (Object)null && MonoSingleton<LocalManager>.Instance.players != null)
			{
				foreach (PlayerReferences player in MonoSingleton<LocalManager>.Instance.players)
				{
					if ((Object)(object)player?.identity != (Object)null && player.identity.isLocalPlayer)
					{
						return player.profile?.steamId ?? 0;
					}
				}
			}
			return 0uL;
		}

		public static void TriggerShake(float intensity, float duration)
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				((MonoBehaviour)Instance).StartCoroutine(Instance.ShakeRoutine(intensity, duration));
			}
		}

		private IEnumerator ShakeRoutine(float intensity, float duration)
		{
			Camera cam = Camera.main;
			if (!((Object)(object)cam == (Object)null))
			{
				Vector3 origLocal = ((Component)cam).transform.localPosition;
				float elapsed = 0f;
				while (elapsed < duration)
				{
					float num = 1f - elapsed / duration;
					((Component)cam).transform.localPosition = origLocal + Random.insideUnitSphere * intensity * num;
					elapsed += Time.deltaTime;
					yield return null;
				}
				((Component)cam).transform.localPosition = origLocal;
			}
		}

		public static void ShowFinalStandings(string payload)
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				Instance._standingsPayload = payload;
				Instance._showStandings = true;
			}
		}

		public static void DismissStandings()
		{
			if (!((Object)(object)Instance == (Object)null))
			{
				Instance._showStandings = false;
			}
		}

		private void EnsureStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			if (_hudStyle == null)
			{
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					fontSize = 16
				};
				val.normal.textColor = Color.white;
				_hudStyle = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 19,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				val2.normal.textColor = Color.white;
				val2.richText = true;
				_toastStyle = val2;
				_toastBigStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 38,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4,
					richText = true
				};
				_toastBigStyle.normal.textColor = new Color(1f, 0.25f, 0.25f);
				_toastMidStyle = new GUIStyle(_toastBigStyle)
				{
					fontSize = 28
				};
				_toastMidStyle.normal.textColor = new Color(1f, 0.6f, 0.15f);
				_toastAvgStyle = new GUIStyle(_toastBigStyle)
				{
					fontSize = 20
				};
				_toastAvgStyle.normal.textColor = new Color(1f, 0.9f, 0.3f);
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 22,
					alignment = (TextAnchor)4
				};
				val3.normal.textColor = Color.white;
				_standingStyle = val3;
				_solidBlack = MakeTex(new Color(0f, 0f, 0f, 0.65f));
				_solidRedish = MakeTex(new Color(0.7f, 0.05f, 0.05f, 0.25f));
			}
		}

		private void OnGUI()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Invalid comparison between Unknown and I4
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Invalid comparison between Unknown and I4
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Invalid comparison between Unknown and I4
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Invalid comparison between Unknown and I4
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Invalid comparison between Unknown and I4
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Invalid comparison between Unknown and I4
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Invalid comparison between Unknown and I4
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Invalid comparison between Unknown and I4
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Invalid comparison between Unknown and I4
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Invalid comparison between Unknown and I4
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Invalid comparison between Unknown and I4
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Invalid comparison between Unknown and I4
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Invalid comparison between Unknown and I4
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Invalid comparison between Unknown and I4
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Invalid comparison between Unknown and I4
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Invalid comparison between Unknown and I4
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Invalid comparison between Unknown and I4
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Invalid comparison between Unknown and I4
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Invalid comparison between Unknown and I4
			EnsureStyles();
			if ((int)Event.current.type == 4 && (int)Event.current.keyCode == 9)
			{
				_showStats = !_showStats;
				Event.current.Use();
			}
			if ((int)Event.current.type == 4 && (int)Event.current.keyCode == 283)
			{
				_forceLobbyControls = !_forceLobbyControls;
				Event.current.Use();
			}
			if ((int)Event.current.type == 4 && (int)Event.current.keyCode == 285)
			{
				ulong num = ResolveLocalSteamId();
				if (num != 0L)
				{
					NetSync.ClientRequestDebugGrantTickets(num, 100);
					Plugin.Log.LogInfo((object)"[Debug] F4 pressed — requesting +100 PvP tickets.");
				}
				Event.current.Use();
			}
			if ((int)Event.current.type == 4 && ShouldShowLobbyControls())
			{
				KeyCode keyCode = Event.current.keyCode;
				if ((int)keyCode == 61 || (int)keyCode == 43 || (int)keyCode == 270)
				{
					NetSync.ClientRequestSettingsChange(Math.Min(10, Plugin.DaysPerGame.Value + 1));
					Event.current.Use();
				}
				else if ((int)keyCode == 45 || (int)keyCode == 95 || (int)keyCode == 269)
				{
					NetSync.ClientRequestSettingsChange(Math.Max(1, Plugin.DaysPerGame.Value - 1));
					Event.current.Use();
				}
				else if ((int)keyCode == 48 || (int)keyCode == 256)
				{
					NetSync.ClientRequestSettingsChange(3);
					Event.current.Use();
				}
			}
			if ((int)Event.current.type == 4)
			{
				ModState instance = ModState.Instance;
				ulong num2 = ResolveLocalSteamId();
				if ((Object)(object)instance != (Object)null && num2 != 0L && instance.Ledgers.TryGetValue(num2, out var value) && value.IsDead)
				{
					List<PlayerLedger> list = new List<PlayerLedger>();
					foreach (PlayerLedger value2 in instance.Ledgers.Values)
					{
						if (!value2.IsDead && value2.SteamId != num2)
						{
							list.Add(value2);
						}
					}
					if (list.Count > 0)
					{
						if ((int)Event.current.keyCode == 116)
						{
							_hauntTargetIdx = (_hauntTargetIdx + 1) % list.Count;
							Event.current.Use();
						}
						else if ((int)Event.current.keyCode == 104)
						{
							PlayerLedger playerLedger = list[_hauntTargetIdx % list.Count];
							NetSync.ClientRequestHaunt(num2, playerLedger.SteamId);
							Event.current.Use();
						}
					}
				}
			}
			if (_showStandings && (int)Event.current.type == 4 && (int)Event.current.keyCode == 27)
			{
				_showStandings = false;
				Event.current.Use();
			}
			DrawWoundedVignette();
			DrawLocalHud();
			DrawOtherPlayersHud();
			DrawToasts();
			if (_showStats)
			{
				DrawStatsPanel();
			}
			if (ShouldShowLobbyControls())
			{
				DrawLobbyControls();
			}
			DrawGhostHauntPanel();
			if (_showStandings)
			{
				DrawStandings();
			}
		}

		private bool ShouldShowLobbyControls()
		{
			if (_forceLobbyControls)
			{
				return true;
			}
			string text = _currentSceneName ?? "";
			if (text == "CasinoScene" || text == "LoseStateScene")
			{
				return false;
			}
			if (text.StartsWith("Splash"))
			{
				return false;
			}
			ModState instance = ModState.Instance;
			if ((Object)(object)instance != (Object)null && (instance.CurrentDayIndex > 0 || instance.GameEnded))
			{
				return false;
			}
			return true;
		}

		private void DrawGhostHauntPanel()
		{
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			ModState instance = ModState.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			ulong num = ResolveLocalSteamId();
			if (num == 0L || !instance.Ledgers.TryGetValue(num, out var value) || !value.IsDead)
			{
				return;
			}
			List<PlayerLedger> list = new List<PlayerLedger>();
			foreach (PlayerLedger value2 in instance.Ledgers.Values)
			{
				if (!value2.IsDead && value2.SteamId != num)
				{
					list.Add(value2);
				}
			}
			if (list.Count != 0)
			{
				int num2 = 320;
				int num3 = 110;
				Rect val = default(Rect);
				((Rect)(ref val))..ctor((float)(Screen.width - num2 - 20), (float)(Screen.height - num3 - 20), (float)num2, (float)num3);
				GUI.DrawTexture(val, (Texture)(object)_solidBlack);
				GUI.Label(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 6f, (float)(num2 - 24), 24f), "☠ GHOST MODE ☠", _hudStyle);
				PlayerLedger playerLedger = list[_hauntTargetIdx % list.Count];
				GUI.Label(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 30f, (float)(num2 - 24), 22f), "Curse target: " + playerLedger.DisplayName, _hudStyle);
				if (GUI.Button(new Rect(((Rect)(ref val)).x + 12f, ((Rect)(ref val)).y + 60f, 130f, 36f), "Cycle [T]"))
				{
					_hauntTargetIdx = (_hauntTargetIdx + 1) % list.Count;
				}
				if (GUI.Button(new Rect(((Rect)(ref val)).x + 160f, ((Rect)(ref val)).y + 60f, 130f, 36f), "HAUNT [H]"))
				{
					NetSync.ClientRequestHaunt(num, playerLedger.SteamId);
				}
			}
		}

		private void EnsureStatsStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00dc: 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)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_010c: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Expected O, but got Unknown
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			if (_statsHeaderStyle == null)
			{
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					fontSize = 22,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				val.normal.textColor = new Color(1f, 0.85f, 0.4f);
				_statsHeaderStyle = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				val2.normal.textColor = new Color(0.75f, 0.75f, 0.85f);
				_statsColHeaderStyle = val2;
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					alignment = (TextAnchor)4
				};
				val3.normal.textColor = Color.white;
				_statsCellStyle = val3;
				GUIStyle val4 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 16,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				val4.normal.textColor = Color.white;
				_statsCurrentStyle = val4;
				GUIStyle val5 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				val5.normal.textColor = Color.white;
				_statsRankStyle = val5;
				_zebraTex = MakeTex(new Color(1f, 1f, 1f, 0.04f));
				_headerBarTex = MakeTex(new Color(0.18f, 0.08f, 0.22f, 0.95f));
				_colHeaderTex = MakeTex(new Color(0.05f, 0.05f, 0.1f, 0.7f));
			}
		}

		private void DrawStatsPanel()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0622: 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_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: 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_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0509: Unknown result type (might be due to invalid IL or missing references)
			//IL_0520: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
			ModState instance = ModState.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			EnsureStatsStyles();
			int value = Plugin.DaysPerGame.Value;
			int num = 200;
			int num2 = 100;
			int num3 = 130;
			int num4 = 30;
			int num5 = num + value * num2 + num3;
			int num6 = Math.Min(Screen.width - 60, num5 + num4 * 2);
			int num7 = 480;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((float)(Screen.width / 2 - num6 / 2), (float)(Screen.height / 2 - num7 / 2), (float)num6, (float)num7);
			GUI.DrawTexture(val, (Texture)(object)_solidBlack);
			GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, (float)num6, 48f), (Texture)(object)_headerBarTex);
			string text = $"♦ DAILY STATS ♦     Day {instance.CurrentDayIndex + 1} of {value}     (Tab to close)";
			GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + 12f, (float)num6, 26f), text, _statsHeaderStyle);
			List<PlayerLedger> list = new List<PlayerLedger>(instance.Ledgers.Values);
			list.Sort((PlayerLedger a, PlayerLedger b) => b.Wealth.CompareTo(a.Wealth));
			float num8 = ((Rect)(ref val)).y + 56f;
			GUI.DrawTexture(new Rect(((Rect)(ref val)).x + 10f, num8, (float)(num6 - 20), 26f), (Texture)(object)_colHeaderTex);
			GUI.Label(new Rect(((Rect)(ref val)).x + (float)num4, num8 + 2f, (float)num, 22f), "PLAYER", _statsColHeaderStyle);
			for (int num9 = 0; num9 < value; num9++)
			{
				GUI.Label(new Rect(((Rect)(ref val)).x + (float)num4 + (float)num + (float)(num9 * num2), num8 + 2f, (float)num2, 22f), $"END DAY {num9 + 1}", _statsColHeaderStyle);
			}
			GUI.Label(new Rect(((Rect)(ref val)).x + (float)num4 + (float)num + (float)(value * num2), num8 + 2f, (float)num3, 22f), "CURRENT", _statsColHeaderStyle);
			float num10 = num8 + 30f;
			float num11 = (float)num7 - (num10 - ((Rect)(ref val)).y) - 14f;
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 10f, num10, (float)(num6 - 20), num11);
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(0f, 0f, (float)(num5 + num4), (float)(list.Count * 32 + 4));
			_statsScroll = GUI.BeginScrollView(val2, _statsScroll, val3);
			float num12 = 0f;
			int num13 = 1;
			Color contentColor = GUI.contentColor;
			Color contentColor2 = default(Color);
			Color contentColor3 = default(Color);
			Color contentColor4 = default(Color);
			foreach (PlayerLedger item in list)
			{
				if (num13 % 2 == 0)
				{
					GUI.DrawTexture(new Rect(0f, num12, (float)(num5 + num4 - 5), 30f), (Texture)(object)_zebraTex);
				}
				string text2;
				if (item.IsDead)
				{
					text2 = "☠";
					contentColor2 = _deadCol;
				}
				else
				{
					switch (num13)
					{
					case 1:
						text2 = "1st";
						contentColor2 = _gold;
						break;
					case 2:
						text2 = "2nd";
						contentColor2 = _silver;
						break;
					case 3:
						text2 = "3rd";
						contentColor2 = _bronze;
						break;
					default:
						text2 = $"#{num13}";
						((Color)(ref contentColor2))..ctor(0.7f, 0.7f, 0.75f);
						break;
					}
				}
				string text3 = "";
				if (item.IsDead)
				{
					text3 = "  [DEAD]";
				}
				else if (item.IsWounded)
				{
					text3 = "  [WND]";
				}
				GUI.contentColor = contentColor2;
				GUI.Label(new Rect((float)(num4 - 10), num12 + 4f, 40f, 22f), text2, _statsRankStyle);
				GUI.contentColor = (item.IsDead ? _deadCol : Color.white);
				GUI.Label(new Rect((float)(num4 + 34), num12 + 4f, (float)(num - 30), 22f), item.DisplayName + text3, _statsCellStyle);
				long num14 = Plugin.StartingMoney.Value;
				for (int num15 = 0; num15 < value; num15++)
				{
					int num16 = num4 + num + num15 * num2 - 10;
					string text4;
					if (num15 < item.PerDaySnapshots.Count)
					{
						long num17 = Plugin.StartingMoney.Value + item.PerDaySnapshots[num15];
						long num18 = num17 - num14;
						text4 = $"${num17}";
						if (num18 > 0)
						{
							((Color)(ref contentColor3))..ctor(0.35f, 1f, 0.45f);
						}
						else if (num18 < 0)
						{
							((Color)(ref contentColor3))..ctor(1f, 0.45f, 0.45f);
						}
						else
						{
							((Color)(ref contentColor3))..ctor(0.75f, 0.75f, 0.75f);
						}
						num14 = num17;
					}
					else
					{
						text4 = "—";
						((Color)(ref contentColor3))..ctor(0.4f, 0.4f, 0.4f);
					}
					GUI.contentColor = contentColor3;
					GUI.Label(new Rect((float)num16, num12 + 4f, (float)num2, 22f), text4, _statsCellStyle);
				}
				long num19 = Plugin.StartingMoney.Value;
				if (item.IsDead)
				{
					contentColor4 = _deadCol;
				}
				else if (item.Wealth > num19)
				{
					((Color)(ref contentColor4))..ctor(0.4f, 1f, 0.5f);
				}
				else if (item.Wealth < num19)
				{
					((Color)(ref contentColor4))..ctor(1f, 0.5f, 0.5f);
				}
				else
				{
					contentColor4 = Color.white;
				}
				GUI.contentColor = contentColor4;
				GUI.Label(new Rect((float)(num4 + num + value * num2 - 10), num12 + 2f, (float)num3, 24f), $"${item.Wealth}", _statsCurrentStyle);
				num12 += 30f;
				num13++;
			}
			GUI.contentColor = contentColor;
			GUI.EndScrollView();
		}

		private void DrawLobbyControls()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			int num = 320;
			int num2 = 96;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((float)(Screen.width - num - 20), 220f, (float)num, (float)num2);
			GUI.DrawTexture(val, (Texture)(object)_solidBlack);
			GUI.Label(new Rect(((Rect)(ref val)).x + 10f, ((Rect)(ref val)).y + 6f, (float)(num - 20), 24f), "GAME SETUP (Host) — F2 hide/show", _hudStyle);
			GUI.Label(new Rect(((Rect)(ref val)).x + 10f, ((Rect)(ref val)).y + 30f, (float)(num - 20), 24f), $"Days per game: {Plugin.DaysPerGame.Value}    keys: + / − / 0", _hudStyle);
			if (GUI.Button(new Rect(((Rect)(ref val)).x + 10f, ((Rect)(ref val)).y + 58f, 70f, 30f), "−  [-]"))
			{
				NetSync.ClientRequestSettingsChange(Math.Max(1, Plugin.DaysPerGame.Value - 1));
			}
			if (GUI.Button(new Rect(((Rect)(ref val)).x + 90f, ((Rect)(ref val)).y + 58f, 70f, 30f), "+  [=]"))
			{
				NetSync.ClientRequestSettingsChange(Math.Min(10, Plugin.DaysPerGame.Value + 1));
			}
			if (GUI.Button(new Rect(((Rect)(ref val)).x + 180f, ((Rect)(ref val)).y + 58f, 120f, 30f), "Reset 3  [0]"))
			{
				NetSync.ClientRequestSettingsChange(3);
			}
		}

		private void DrawLocalHud()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			ModState instance = ModState.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			ulong num = ResolveLocalSteamId();
			if (num != 0L && instance.Ledgers.TryGetValue(num, out var value))
			{
				GUI.DrawTexture(new Rect(20f, 20f, 360f, 100f), (Texture)(object)_solidBlack);
				GUI.Label(new Rect(30f, 25f, 350f, 24f), $"DAY {instance.CurrentDayIndex + 1} / {Plugin.DaysPerGame.Value}", _hudStyle);
				GUI.Label(new Rect(30f, 47f, 350f, 24f), string.Format("Wealth: ${0}    Ledger: {1}{2}", value.Wealth, (value.Ledger >= 0) ? "+" : "", value.Ledger), _hudStyle);
				string text = ((value.ActiveLoanPrincipal > 0) ? $"Loan: owe ${value.LoanPaybackOwed} (took ${value.ActiveLoanPrincipal} day {value.ActiveLoanDayIndex + 1})" : "No active loan");
				if (value.IsWounded)
				{
					text += "   [WOUNDED]";
				}
				if (value.IsDead)
				{
					text = "[YOU ARE DEAD]";
				}
				GUI.Label(new Rect(30f, 69f, 350f, 24f), text, _hudStyle);
				GUIStyle val = new GUIStyle(_hudStyle);
				val.normal.textColor = new Color(0.4f, 0.9f, 1f);
				val.fontStyle = (FontStyle)1;
				GUI.Label(new Rect(30f, 91f, 350f, 24f), $"♦ PvP Tickets: {value.PvpTickets}", val);
			}
		}

		private void DrawOtherPlayersHud()
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			ModState instance = ModState.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			ulong num = ResolveLocalSteamId();
			List<PlayerLedger> list = new List<PlayerLedger>();
			foreach (PlayerLedger value in instance.Ledgers.Values)
			{
				if (value.SteamId != num)
				{
					list.Add(value);
				}
			}
			list.Sort((PlayerLedger a, PlayerLedger b) => b.Wealth.CompareTo(a.Wealth));
			float num2 = 110f;
			int num3 = 0;
			foreach (PlayerLedger item in list)
			{
				float num4 = 48f;
				GUI.DrawTexture(new Rect(20f, num2, 360f, num4), (Texture)(object)_solidBlack);
				string text = $"#{num3 + 2} {item.DisplayName}";
				if (item.IsDead)
				{
					text += "  [DEAD]";
				}
				else if (item.IsWounded)
				{
					text += "  [WOUNDED]";
				}
				GUI.Label(new Rect(30f, num2 + 4f, 350f, 22f), text, _hudStyle);
				string text2 = $"Wealth: ${item.Wealth}";
				if (item.ActiveLoanPrincipal > 0)
				{
					text2 += $"   Loan: -${item.LoanPaybackOwed}";
				}
				GUI.Label(new Rect(30f, num2 + 24f, 350f, 22f), text2, _hudStyle);
				num2 += num4 + 4f;
				num3++;
				if (num3 >= 6)
				{
					break;
				}
			}
		}

		private void DrawToasts()
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			float unscaledTime = Time.unscaledTime;
			while (_toasts.Count > 0 && _toasts.Peek().Until < unscaledTime)
			{
				_toasts.Dequeue();
			}
			int num = 110;
			int num2 = 0;
			foreach (Toast toast in _toasts)
			{
				GUIStyle val = ((toast.Severity == ToastSeverity.Big) ? _toastBigStyle : ((toast.Severity == ToastSeverity.Mid) ? _toastMidStyle : _toastAvgStyle));
				float num3 = Mathf.Clamp01(toast.Until - unscaledTime);
				int num4 = val.fontSize + 12;
				int width = Screen.width;
				Color color = GUI.color;
				GUI.color = new Color(0f, 0f, 0f, num3 * 0.85f);
				GUI.Label(new Rect(3f, (float)(num + 3), (float)width, (float)num4), toast.Text, val);
				GUI.color = new Color(1f, 1f, 1f, num3);
				GUI.Label(new Rect(0f, (float)num, (float)width, (float)num4), toast.Text, val);
				GUI.color = color;
				num += num4 + 4;
				num2++;
				if (num2 > 5)
				{
					break;
				}
			}
		}

		private void DrawWoundedVignette()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			ModState instance = ModState.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			ulong num = ResolveLocalSteamId();
			if (num != 0L && instance.Ledgers.TryGetValue(num, out var value) && (value.IsWounded || value.IsDead))
			{
				GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_solidRedish);
				if (value.IsDead)
				{
					GUI.Label(new Rect(0f, (float)(Screen.height / 2 - 30), (float)Screen.width, 60f), "<color=red>YOU ARE DEAD</color>", _standingStyle);
				}
			}
		}

		private void EnsureStandingsStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if (_winnerStyle == null)
			{
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					fontSize = 28,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)3
				};
				val.normal.textColor = _gold;
				_winnerStyle = val;
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 22,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)3
				};
				val2.normal.textColor = Color.white;
				_placeStyle = val2;
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 18,
					alignment = (TextAnchor)3
				};
				val3.normal.textColor = _deadCol;
				_deadStyle = val3;
				GUIStyle val4 = new GUIStyle(GUI.skin.label)
				{
					fontSize = 44,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				val4.normal.textColor = _gold;
				_bannerStyle = val4;
				_solidDark = MakeTex(new Color(0.05f, 0.05f, 0.08f, 0.92f));
			}
		}

		private void DrawStandings()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			EnsureStandingsStyles();
			int num = 760;
			int num2 = 560;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((float)(Screen.width / 2 - num / 2), (float)(Screen.height / 2 - num2 / 2), (float)num, (float)num2);
			GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)_solidBlack);
			GUI.DrawTexture(val, (Texture)(object)_solidDark);
			GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + 18f, (float)num, 60f), "FINAL STANDINGS", _bannerStyle);
			GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + 72f, (float)num, 26f), "the mob has collected. the survivor is decided.", _hudStyle);
			if (string.IsNullOrEmpty(_standingsPayload))
			{
				GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + 110f, (float)num, 30f), "(awaiting results...)", _placeStyle);
				return;
			}
			string[] array = _standingsPayload.Split('|');
			List<(string, string, string, string)> list = new List<(string, string, string, string)>();
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (!(text == "RESULTS") && !string.IsNullOrEmpty(text))
				{
					string[] array3 = text.Split(',');
					if (array3.Length >= 4)
					{
						list.Add((array3[0], array3[1], array3[2], array3[3]));
					}
				}
			}
			float num3 = ((Rect)(ref val)).y + 120f;
			int num4 = 1;
			Rect val4 = default(Rect);
			foreach (var item in list)
			{
				if (item.Item4 == "DEAD")
				{
					GUI.Label(new Rect(((Rect)(ref val)).x + 40f, num3, (float)(num - 60), 36f), "  ☠  " + item.Item1 + "  —  KILLED BY THE MOB", _deadStyle);
					num3 += 38f;
					continue;
				}
				GUIStyle val2;
				string text2;
				Color val3;
				switch (num4)
				{
				case 1:
					val2 = _winnerStyle;
					text2 = "WINNER";
					val3 = _gold;
					break;
				case 2:
					val2 = _placeStyle;
					text2 = "2nd";
					val3 = _silver;
					break;
				case 3:
					val2 = _placeStyle;
					text2 = "3rd";
					val3 = _bronze;
					break;
				default:
					val2 = _placeStyle;
					text2 = $"{num4}th";
					val3 = Color.gray;
					break;
				}
				((Rect)(ref val4))..ctor(((Rect)(ref val)).x + 30f, num3, (float)(num - 60), (float)((num4 == 1) ? 56 : 42));
				GUI.DrawTexture(val4, (Texture)(object)MakeTex(new Color(val3.r * 0.35f, val3.g * 0.35f, val3.b * 0.35f, 0.5f)));
				string text3 = ((num4 == 1) ? ("  " + text2 + "    " + item.Item1 + "    ·    $" + item.Item2 + "    ·    payout $" + item.Item3) : ("  " + text2 + "     " + item.Item1 + "      $" + item.Item2 + "     payout $" + item.Item3));
				GUI.Label(new Rect(((Rect)(ref val4)).x + 8f, ((Rect)(ref val4)).y + 4f, ((Rect)(ref val4)).width - 16f, ((Rect)(ref val4)).height - 8f), text3, val2);
				num3 += (float)((num4 == 1) ? 64 : 50);
				num4++;
			}
			GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + (float)num2 - 36f, (float)num, 26f), "press [Esc] to dismiss", _hudStyle);
		}

		private static Texture2D MakeTex(Color c)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, c);
			val.Apply();
			return val;
		}

		private static ulong ResolveLocalSteamId()
		{
			if ((Object)(object)MonoSingleton<LocalManager>.Instance != (Object)null && MonoSingleton<LocalManager>.Instance.players != null)
			{
				foreach (PlayerReferences player in MonoSingleton<LocalManager>.Instance.players)
				{
					if ((Object)(object)player?.identity != (Object)null && player.identity.isLocalPlayer)
					{
						return player.profile?.steamId ?? 0;
					}
				}
			}
			return 0uL;
		}
	}
	public static class GameFlowPatches
	{
		private static bool _endGameSent;

		[HarmonyPatch(typeof(GameManager), "ProgressGameRoutine")]
		[HarmonyPrefix]
		public static void StripQuotaBeforeProgress()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			if (NetworkServer.active && Plugin.StripQuota.Value)
			{
				GameManager instance = NetworkSingleton<GameManager>.Instance;
				if (!((Object)(object)instance == (Object)null) && (int)instance.state == 1 && instance.currentQuota != 0L)
				{
					Plugin.Log.LogInfo((object)$"[Quota Strip] Zeroing quota (was {instance.currentQuota}) before progress.");
					instance.NetworkcurrentQuota = 0L;
				}
			}
		}

		[HarmonyPatch(typeof(GameManager), "ProgressNextQuota")]
		[HarmonyPrefix]
		public static bool InterceptQuotaProgress(GameManager __instance)
		{
			if (!NetworkServer.active)
			{
				return true;
			}
			int daysPassed = __instance.daysPassed;
			int value = Plugin.DaysPerGame.Value;
			if (daysPassed >= value && !_endGameSent)
			{
				_endGameSent = true;
				Plugin.Log.LogInfo((object)$"[Hard Stop] {daysPassed} days played, target was {value}. Triggering end-game.");
				EndGame.TriggerEndGame();
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(GameManager), "LobbyInitializeRoutine")]
		[HarmonyPostfix]
		public static void ResetOnLobby()
		{
			_endGameSent = false;
			Plugin.Log.LogInfo((object)"[Game Flow] Lobby init — resetting end-game guard.");
		}
	}
	public static class HauntSystem
	{
		public const float DurationSeconds = 30f;

		public const float CooldownSeconds = 60f;

		public const float Multiplier = 0.5f;

		private static readonly Dictionary<ulong, float> _hauntExpiry = new Dictionary<ulong, float>();

		private static readonly Dictionary<ulong, float> _ghostCooldown = new Dictionary<ulong, float>();

		public static void TryHaunt(ulong ghostId, ulong targetId)
		{
			if (!NetworkServer.active)
			{
				return;
			}
			ModState instance = ModState.Instance;
			if ((Object)(object)instance == (Object)null || instance.GameEnded || ghostId == targetId)
			{
				return;
			}
			PlayerLedger orCreate = instance.GetOrCreate(ghostId);
			PlayerLedger orCreate2 = instance.GetOrCreate(targetId);
			if (!orCreate.IsDead)
			{
				NetSync.BroadcastToast(orCreate.DisplayName + " isn't dead — can't haunt.");
				return;
			}
			if (orCreate2.IsDead)
			{
				NetSync.BroadcastToast(orCreate2.DisplayName + " is already dead.");
				return;
			}
			if (_ghostCooldown.TryGetValue(ghostId, out var value))
			{
				float num = Time.time - value;
				if (num < 60f)
				{
					NetSync.BroadcastToast($"{orCreate.DisplayName}'s ectoplasm needs {60f - num:F0}s to recharge.");
					return;
				}
			}
			if (orCreate2.BuffGhostRepellent)
			{
				orCreate2.BuffGhostRepellent = false;
				NetSync.BroadcastToast(orCreate2.DisplayName + "'s Ghost Repellent dispersed " + orCreate.DisplayName + "'s spirit.", ToastSeverity.Mid);
				NetSync.BroadcastLedgerUpdate(orCreate2);
				return;
			}
			_ghostCooldown[ghostId] = Time.time;
			_hauntExpiry[targetId] = Time.time + 30f;
			orCreate.PvpTickets++;
			Plugin.Log.LogInfo((object)$"[Haunt] {orCreate.DisplayName} (ghost) haunts {orCreate2.DisplayName} for {30f}s.");
			NetSync.BroadcastLedgerUpdate(orCreate);
			NetSync.BroadcastToast("☠\ufe0e " + orCreate.DisplayName + "'s spirit haunts " + orCreate2.DisplayName + " — their luck just curdled.");
		}

		public static bool IsHaunted(ulong steamId)
		{
			if (!_hauntExpiry.TryGetValue(steamId, out var value))
			{
				return false;
			}
			if (Time.time >= value)
			{
				_hauntExpiry.Remove(steamId);
				return false;
			}
			return true;
		}
	}
	public static class LedgerTrackerPatches
	{
		[HarmonyPatch(typeof(MoneyManager), "AddBalance")]
		[HarmonyPostfix]
		public static void OnAdd(long amount, PlayerProfile changer, ChangeType changeType)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				AttributeDelta(Math.Abs(amount), changer, changeType);
			}
		}

		[HarmonyPatch(typeof(MoneyManager), "RemoveBalance")]
		[HarmonyPostfix]
		public static void OnRemove(long amount, PlayerProfile changer, ChangeType changeType)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active)
			{
				AttributeDelta(-Math.Abs(amount), changer, changeType);
			}
		}

		private static void AttributeDelta(long signedDelta, PlayerProfile changer, ChangeType changeType)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)changer == (Object)null) && ((int)changeType == 0 || (int)changeType == 1))
			{
				PlayerLedger playerLedger = ModState.Instance?.GetOrCreate(changer.steamId, changer.playerName);
				if (playerLedger != null && !playerLedger.IsDead)
				{
					playerLedger.Ledger += signedDelta;
					Plugin.Log.LogInfo((object)string.Format("[Ledger] {0}: {1}{2} ({3}) => total {4}", playerLedger.DisplayName, (signedDelta >= 0) ? "+" : "", signedDelta, changeType, playerLedger.Ledger));
					NetSync.BroadcastLedgerUpdate(playerLedger);
				}
			}
		}
	}
	public class LoanShark : MonoBehaviour
	{
		private TextMeshPro _amountLabel;

		private TextMeshPro _signLabel;

		public long SelectedAmount { get; private set; }

		public void SetUI(TextMeshPro signLabel, TextMeshPro amountLabel)
		{
			_signLabel = signLabel;
			_amountLabel = amountLabel;
			RefreshLabels();
		}

		public void RefreshLabels()
		{
			if (SelectedAmount <= 0)
			{
				int maxLoanForCurrentDay = LoanSystem.GetMaxLoanForCurrentDay();
				SelectedAmount = maxLoanForCurrentDay / 4;
			}
			int maxLoanForCurrentDay2 = LoanSystem.GetMaxLoanForCurrentDay();
			if (SelectedAmount > maxLoanForCurrentDay2)
			{
				SelectedAmount = maxLoanForCurrentDay2;
			}
			if ((Object)(object)_signLabel != (Object)null)
			{
				((TMP_Text)_signLabel).text = "LOAN SHARK\nFAST CASH\nFAIR TERMS*";
			}
			if (!((Object)(object)_amountLabel != (Object)null))
			{
				return;
			}
			float num = Plugin.LoanInterest.Value;
			ModState instance = ModState.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				ulong num2 = 0uL;
				NetworkConnectionToServer connection = NetworkClient.connection;
				NetworkIdentity val = ((connection != null) ? ((NetworkConnection)connection).identity : null);
				if ((Object)(object)val != (Object)null)
				{
					PlayerProfile component = ((Component)val).GetComponent<PlayerProfile>();
					if ((Object)(object)component != (Object)null)
					{
						num2 = component.steamId;
					}
				}
				if (num2 != 0L && instance.Ledgers.TryGetValue(num2, out var value))
				{
					num = value.NextLoanInterestRate;
				}
			}
			((TMP_Text)_amountLabel).text = $"${SelectedAmount}  ->  Owe ${Math.Round((float)SelectedAmount * num)} ({num}x)";
		}

		public void Cycle()
		{
			SoundManager.Play(SoundManager.Cue.Click);
			int maxLoanForCurrentDay = LoanSystem.GetMaxLoanForCurrentDay();
			int[] array = new int[4]
			{
				maxLoanForCurrentDay / 10,
				maxLoanForCurrentDay / 4,
				maxLoanForCurrentDay / 2,
				maxLoanForCurrentDay
			};
			int num = 0;
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i] == SelectedAmount)
				{
					num = i;
					break;
				}
			}
			num = (num + 1) % array.Length;
			SelectedAmount = array[num];
			RefreshLabels();
		}

		private void Update()
		{
			RefreshLabels();
		}

		public void SellPart()
		{
			ulong num = ResolveLocalSteamId();
			if (num == 0L)
			{
				Plugin.Log.LogWarning((object)"[LoanShark] No local steam id for SellPart.");
				return;
			}
			Plugin.Log.LogInfo((object)"[LoanShark] Local player requesting body part sale for loan relief.");
			SoundManager.Play(SoundManager.Cue.PayBack);
			NetSync.ClientRequestBodyPartSale(num);
		}

		public void PayBack()
		{
			ulong num = ResolveLocalSteamId();
			if (num == 0L)
			{
				Plugin.Log.LogWarning((object)"[LoanShark] No local steam id.");
				return;
			}
			Plugin.Log.LogInfo((object)"[LoanShark] Local player requesting loan payback.");
			SoundManager.Play(SoundManager.Cue.PayBack);
			NetSync.ClientRequestLoanPayback(num);
		}

		public void Take()
		{
			ulong num = ResolveLocalSteamId();
			if (num == 0L)
			{
				Plugin.Log.LogWarning((object)"[LoanShark] Could not resolve local steam id; cannot request loan.");
				return;
			}
			Plugin.Log.LogInfo((object)$"[LoanShark] Local player requesting ${SelectedAmount} loan.");
			SoundManager.Play(SoundManager.Cue.TakeLoan);
			NetSync.ClientRequestLoan(num, SelectedAmount);
		}

		private static ulong ResolveLocalSteamId()
		{
			NetworkConnectionToServer connection = NetworkClient.connection;
			NetworkIdentity val = ((connection != null) ? ((NetworkConnection)connection).identity : null);
			if ((Object)(object)val != (Object)null)
			{
				PlayerProfile component = ((Component)val).GetComponent<PlayerProfile>();
				if ((Object)(object)component != (Object)null)
				{
					return component.steamId;
				}
			}
			if ((Object)(object)MonoSingleton<LocalManager>.Instance != (Object)null)
			{
				foreach (PlayerReferences player in MonoSingleton<LocalManager>.Instance.players)
				{
					if ((Object)(object)player?.identity != (Object)null && player.identity.isLocalPlayer)
					{
						return player.profile?.steamId ?? 0;
					}
				}
			}
			return 0uL;
		}
	}
	public static class LoanSharkSpawner
	{
		private static Material _urpMat;

		public static IEnumerator SpawnRoutine()
		{
			yield return (object)new WaitForSeconds(3f);
			NetSync.RegisterAll();
			if ((Object)(object)GameObject.Find("[PvP] LoanSharkKiosk") != (Object)null)
			{
				Plugin.Log.LogInfo((object)"[LoanSharkSpawner] Kiosk already exists in scene, skipping.");
				yield break;
			}
			Plugin.Log.LogInfo((object)"[LoanSharkSpawner] v0.2.1 spawn routine starting. Looking for nearest casino landmark...");
			Vector3 playerPos = Vector3.zero;
			float deadline = Time.time + 8f;
			while (Time.time < deadline)
			{
				playerPos = FindLocalPlayerPos();
				if (playerPos != Vector3.zero)
				{
					break;
				}
				yield return (object)new WaitForSeconds(0.5f);
			}
			Vector3 val = playerPos;
			string text = "player";
			GameBase val2 = null;
			float num = float.MaxValue;
			GameBase[] array = Object.FindObjectsOfType<GameBase>();
			foreach (GameBase val3 in array)
			{
				Vector3 val4 = ((Component)val3).transform.position - playerPos;
				float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
				if (sqrMagnitude < num)
				{
					num = sqrMagnitude;
					val2 = val3;
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				Vector3 position = ((Component)val2).transform.position;
				Vector3 val5 = playerPos - position;
				val5.y = 0f;
				if (((Vector3)(ref val5)).sqrMagnitude > 0.01f)
				{
					((Vector3)(ref val5)).Normalize();
					val = position + val5 * 4f;
					text = ((object)val2).GetType().Name;
				}
			}
			if (playerPos != Vector3.zero)
			{
				val.y = playerPos.y - 1f;
			}
			Plugin.Log.LogInfo((object)$"[LoanSharkSpawner] Anchor: {text} at {val} (player at {playerPos}, dist^2 {num:F1})");
			NetSync.BroadcastToast("Booths anchored to nearest game: " + text, ToastSeverity.Average);
			Vector3 candidate = val + new Vector3(0f, 0f, 7f);
			candidate = NudgeClearOfColliders(candidate);
			GameObject val6 = new GameObject("[PvP] LoanSharkKiosk");
			val6.transform.position = candidate;
			val6.transform.rotation = Quaternion.Euler(0f, 180f, 0f);
			EnsureMaterial();
			BuildKioskVisuals(val6);
			LoanShark shark = val6.AddComponent<LoanShark>();
			Transform obj = val6.transform.Find("Desk/AmountText");
			TextMeshPro amountLabel = ((obj != null) ? ((Component)obj).GetComponent<TextMeshPro>() : null);
			shark.SetUI(null, amountLabel);
			AddInteractable(val6.transform, new Vector3(-0.85f, 1.1f, -0.6f), "CycleAmount", "Change Amount", new Color(1f, 0.85f, 0.2f), delegate
			{
				shark.Cycle();
			});
			AddInteractable(val6.transform, new Vector3(0f, 1.1f, -0.6f), "PayBack", "Pay Back Loan", new Color(0.4f, 0.7f, 1f), delegate
			{
				shark.PayBack();
			});
			AddInteractable(val6.transform, new Vector3(0.85f, 1.1f, -0.6f), "TakeLoan", "Take Loan", new Color(0.2f, 0.9f, 0.2f), delegate
			{
				shark.Take();
			});
			AddInteractable(val6.transform, new Vector3(1.3f, 1.1f, -0.6f), "SellPart", "Sell Body Part", new Color(0.7f, 0f, 0.3f), delegate
			{
				shark.SellPart();
			});
			Plugin.Log.LogInfo((object)$"[LoanSharkSpawner] Kiosk placed at {val6.transform.position}.");
			SpawnWagerBooth(val);
			SpawnMobFavorsBooth(val);
		}

		private static void SpawnMobFavorsBooth(Vector3 anchor)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)GameObject.Find("[PvP] MobFavorsBooth") != (Object)null))
			{
				GameObject val = new GameObject("[PvP] MobFavorsBooth");
				val.transform.position = NudgeClearOfColliders(anchor + new Vector3(3f, 0f, 7f));
				val.transform.rotation = Quaternion.Euler(0f, 180f, 0f);
				GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)3);
				((Object)val2).name = "Desk";
				val2.transform.SetParent(val.transform, false);
				val2.transform.localPosition = new Vector3(0f, 0.5f, 0f);
				val2.transform.localScale = new Vector3(2.5f, 1f, 1f);
				ApplyMaterial(val2, new Color(0.15f, 0.15f, 0.15f, 1f));
				GameObject val3 = GameObject.CreatePrimitive((PrimitiveType)3);
				((Object)val3).name = "Sign";
				val3.transform.SetParent(val.transform, false);
				val3.transform.localPosition = new Vector3(0