Decompiled source of PropHunt v1.1.0

PropHunt.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using DooDesch.Transition;
using DooDesch.UI;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.Audio;
using Il2CppScheduleOne.AvatarFramework;
using Il2CppScheduleOne.Building;
using Il2CppScheduleOne.Building.Doors;
using Il2CppScheduleOne.Combat;
using Il2CppScheduleOne.Core.Items.Framework;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Doors;
using Il2CppScheduleOne.Dragging;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.Equipping;
using Il2CppScheduleOne.FX;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.Interaction;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Map;
using Il2CppScheduleOne.Misc;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.PlayerScripts.Health;
using Il2CppScheduleOne.Police;
using Il2CppScheduleOne.Property;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.Tiles;
using Il2CppScheduleOne.Trash;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.Phone;
using Il2CppScheduleOne.Vehicles;
using Il2CppSteamworks;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using PropHunt;
using PropHunt.Catch;
using PropHunt.Config;
using PropHunt.Disguise;
using PropHunt.Game;
using PropHunt.Music;
using PropHunt.Net;
using PropHunt.Patches;
using PropHunt.Phone;
using PropHunt.PlayArea;
using PropHunt.Quests;
using PropHunt.Taunt;
using PropHunt.UI;
using PropHunt.UI.Hud;
using PropHunt.View;
using S1API.AssetBundles;
using S1API.Internal.Abstraction;
using S1API.PhoneApp;
using S1API.Quests;
using S1API.Quests.Constants;
using S1API.UI;
using SideHustle;
using SideHustle.Multiplayer;
using SteamNetworkLib;
using SteamNetworkLib.Exceptions;
using SteamNetworkLib.Models;
using SteamNetworkLib.Sync;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Core), "PropHunt", "1.1.0", "DooDesch", "https://github.com/DooDesch-Mods/ScheduleOne-PropHunt")]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonOptionalDependencies(new string[] { "SideHustle" })]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("PropHunt")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+d3b289cb3c93d4a580f26229dac8c050be859ded")]
[assembly: AssemblyProduct("PropHunt")]
[assembly: AssemblyTitle("PropHunt")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[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 DooDesch.Transition
{
	internal static class Veil
	{
		internal static class Ease
		{
			public static float In(float t)
			{
				t = Mathf.Clamp01(t);
				return t * t * t;
			}

			public static float Out(float t)
			{
				t = Mathf.Clamp01(t);
				float num = 1f - t;
				return 1f - num * num * num;
			}

			public static float InOut(float t)
			{
				t = Mathf.Clamp01(t);
				return t * t * (3f - 2f * t);
			}
		}

		internal static bool EyelidsAvailable
		{
			get
			{
				try
				{
					return Singleton<EyelidOverlay>.InstanceExists;
				}
				catch
				{
					return false;
				}
			}
		}

		internal static bool BlackAvailable
		{
			get
			{
				try
				{
					return Singleton<BlackOverlay>.InstanceExists || Singleton<HUD>.InstanceExists;
				}
				catch
				{
					return false;
				}
			}
		}

		private static EyelidOverlay Eyes()
		{
			try
			{
				return Singleton<EyelidOverlay>.InstanceExists ? Singleton<EyelidOverlay>.Instance : null;
			}
			catch
			{
				return null;
			}
		}

		internal static void SetEyelids(float openness)
		{
			EyelidOverlay val = Eyes();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				val.AutoUpdate = false;
				val.SetOpen(Mathf.Clamp01(openness));
			}
			catch
			{
			}
		}

		internal static float CurrentEyelidOpen(float fallback = 1f)
		{
			EyelidOverlay val = Eyes();
			if ((Object)(object)val == (Object)null)
			{
				return fallback;
			}
			try
			{
				return val.CurrentOpen;
			}
			catch
			{
				return fallback;
			}
		}

		internal static void ReleaseEyelids()
		{
			EyelidOverlay val = Eyes();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				val.AutoUpdate = true;
			}
			catch
			{
			}
		}

		internal static float EyelidTargetOpen()
		{
			try
			{
				Player local = Player.Local;
				if ((Object)(object)local != (Object)null && (Object)(object)local.Energy != (Object)null)
				{
					float currentEnergy = local.Energy.CurrentEnergy;
					return (currentEnergy < 20f) ? Mathf.Lerp(0.625f, 1f, currentEnergy / 20f) : 1f;
				}
			}
			catch
			{
			}
			return 1f;
		}

		internal static IEnumerator CloseEyelids(float dur)
		{
			float start = CurrentEyelidOpen();
			if (dur <= 0f)
			{
				SetEyelids(0f);
				yield break;
			}
			for (float t = 0f; t < dur; t += Time.deltaTime)
			{
				SetEyelids(Mathf.Lerp(start, 0f, Ease.InOut(t / dur)));
				yield return null;
			}
			SetEyelids(0f);
		}

		internal static IEnumerator OpenEyelidsToTarget(float dur)
		{
			float target = EyelidTargetOpen();
			if (dur <= 0f)
			{
				SetEyelids(target);
				ReleaseEyelids();
				yield break;
			}
			for (float t = 0f; t < dur; t += Time.deltaTime)
			{
				SetEyelids(Mathf.Lerp(0f, target, Ease.Out(t / dur)));
				yield return null;
			}
			SetEyelids(target);
			ReleaseEyelids();
		}

		internal static IEnumerator FadeEyelids(float target, float dur, bool releaseToGame)
		{
			if ((Object)(object)Eyes() == (Object)null)
			{
				yield break;
			}
			float start = CurrentEyelidOpen(target);
			if (dur > 0f)
			{
				for (float t = 0f; t < dur; t += Time.deltaTime)
				{
					SetEyelids(Mathf.Lerp(start, target, Ease.InOut(t / dur)));
					yield return null;
				}
			}
			SetEyelids(target);
			if (releaseToGame)
			{
				ReleaseEyelids();
			}
		}

		internal static void BlackOpen(float t)
		{
			Black(toBlack: true, t);
		}

		internal static void BlackClose(float t)
		{
			Black(toBlack: false, t);
		}

		private static void Black(bool toBlack, float t)
		{
			try
			{
				if (Singleton<BlackOverlay>.InstanceExists)
				{
					BlackOverlay instance = Singleton<BlackOverlay>.Instance;
					if (toBlack)
					{
						instance.Open(t);
					}
					else
					{
						instance.Close(t);
					}
				}
				else if (Singleton<HUD>.InstanceExists)
				{
					Singleton<HUD>.Instance.SetBlackOverlayVisible(toBlack, t);
				}
			}
			catch (Exception ex)
			{
				ScreenTransition.Warn?.Invoke("Veil.Black failed: " + ex.Message);
			}
		}

		internal static void SetCanMove(bool canMove)
		{
			try
			{
				PlayerMovement instance = PlayerSingleton<PlayerMovement>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.CanMove = canMove;
				}
			}
			catch
			{
			}
		}

		internal static void SetCanLook(bool canLook)
		{
			try
			{
				PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.SetCanLook(canLook);
				}
			}
			catch
			{
			}
		}
	}
	internal enum VeilMode
	{
		Eyelids,
		Black,
		EyelidsAndBlack
	}
	internal struct TransitionRequest
	{
		public VeilMode Mechanism;

		public float CloseSeconds;

		public float OpenSeconds;

		public float HoldSeconds;

		public bool LockMovement;

		public bool LockCamera;

		public Action DuringBlack;

		public Action OnMidHold;

		public Action OnDone;

		public Func<bool> WaitUntilReady;

		public float WaitDeadlineSeconds;

		public Action WhileWaiting;

		public Func<bool> KeepClosedAfter;

		public string Key;
	}
	internal static class ScreenTransition
	{
		public static Action<string> Warn = delegate(string msg)
		{
			try
			{
				MelonLogger.Warning(msg);
			}
			catch
			{
			}
		};

		private static readonly HashSet<string> Active = new HashSet<string>();

		public static bool IsRunning(string key)
		{
			return Active.Contains(Bucket(key));
		}

		public static bool Play(TransitionRequest req)
		{
			string text = Bucket(req.Key);
			if (Active.Contains(text))
			{
				return false;
			}
			bool flag = req.Mechanism == VeilMode.Eyelids || req.Mechanism == VeilMode.EyelidsAndBlack;
			bool flag2 = req.Mechanism == VeilMode.Black || req.Mechanism == VeilMode.EyelidsAndBlack;
			if ((!flag || !Veil.EyelidsAvailable) && (!flag2 || !Veil.BlackAvailable))
			{
				Safe(req.DuringBlack);
				Safe(req.OnDone);
				return true;
			}
			Active.Add(text);
			try
			{
				MelonCoroutines.Start(Run(req, text, flag, flag2));
			}
			catch (Exception ex)
			{
				Warn?.Invoke("ScreenTransition.Play start failed: " + ex.Message);
				Active.Remove(text);
				Safe(req.DuringBlack);
				Safe(req.OnDone);
			}
			return true;
		}

		public static void ForceReset(string key = null)
		{
			if (key == null)
			{
				Active.Clear();
			}
			else
			{
				Active.Remove(Bucket(key));
			}
			try
			{
				Veil.BlackClose(0f);
				Veil.SetEyelids(1f);
				Veil.ReleaseEyelids();
				Veil.SetCanMove(canMove: true);
				Veil.SetCanLook(canLook: true);
			}
			catch (Exception ex)
			{
				Warn?.Invoke("ScreenTransition.ForceReset failed: " + ex.Message);
			}
		}

		private static IEnumerator Run(TransitionRequest req, string key, bool eye, bool black)
		{
			bool lockedMove = false;
			bool lockedLook = false;
			try
			{
				if (req.LockMovement)
				{
					Veil.SetCanMove(canMove: false);
					lockedMove = true;
				}
				if (req.LockCamera)
				{
					Veil.SetCanLook(canLook: false);
					lockedLook = true;
				}
				if (black)
				{
					Veil.BlackOpen(req.CloseSeconds);
				}
				if (eye)
				{
					yield return Veil.CloseEyelids(req.CloseSeconds);
				}
				else
				{
					yield return Wait(req.CloseSeconds);
				}
				Safe(req.DuringBlack);
				yield return null;
				yield return null;
				if (req.WaitUntilReady != null)
				{
					float deadline = Time.time + Mathf.Max(0f, req.WaitDeadlineSeconds);
					while (Time.time < deadline && !SafeReady(req.WaitUntilReady))
					{
						Safe(req.WhileWaiting);
						yield return null;
					}
					Safe(req.WhileWaiting);
				}
				if (req.HoldSeconds > 0f)
				{
					float deadline = req.HoldSeconds * 0.5f;
					yield return Wait(deadline);
					Safe(req.OnMidHold);
					yield return Wait(req.HoldSeconds - deadline);
				}
				else
				{
					Safe(req.OnMidHold);
				}
				if (req.KeepClosedAfter == null || !SafeReady(req.KeepClosedAfter))
				{
					if (black)
					{
						Veil.BlackClose(req.OpenSeconds);
					}
					if (eye)
					{
						yield return Veil.OpenEyelidsToTarget(req.OpenSeconds);
					}
					else
					{
						yield return Wait(req.OpenSeconds);
					}
				}
				Safe(req.OnDone);
			}
			finally
			{
				bool flag = req.KeepClosedAfter != null && SafeReady(req.KeepClosedAfter);
				if (eye)
				{
					if (flag)
					{
						Veil.SetEyelids(0f);
					}
					else
					{
						Veil.SetEyelids(Veil.EyelidTargetOpen());
						Veil.ReleaseEyelids();
					}
				}
				if (black && !flag)
				{
					Veil.BlackClose(0.25f);
				}
				if (lockedMove)
				{
					Veil.SetCanMove(canMove: true);
				}
				if (lockedLook)
				{
					Veil.SetCanLook(canLook: true);
				}
				Active.Remove(key);
			}
		}

		private static string Bucket(string key)
		{
			if (!string.IsNullOrEmpty(key))
			{
				return key;
			}
			return "default";
		}

		private static IEnumerator Wait(float sec)
		{
			if (!(sec <= 0f))
			{
				for (float t = 0f; t < sec; t += Time.deltaTime)
				{
					yield return null;
				}
			}
		}

		private static bool SafeReady(Func<bool> f)
		{
			try
			{
				return f();
			}
			catch
			{
				return false;
			}
		}

		private static void Safe(Action a)
		{
			if (a == null)
			{
				return;
			}
			try
			{
				a();
			}
			catch (Exception ex)
			{
				Warn?.Invoke("ScreenTransition callback failed: " + ex.Message);
			}
		}
	}
}
namespace PropHunt
{
	public sealed class Core : MelonMod
	{
		private static LaunchContext _session;

		private static GamemodeDescriptor _descriptor;

		private static GameModeController _controller;

		private static bool _patched;

		public static Core Instance { get; private set; }

		public static Instance Log { get; private set; }

		internal static GameModeController Session => _controller;

		[Conditional("DEBUG")]
		public static void LogDebug(string msg)
		{
			Instance log = Log;
			if (log != null)
			{
				log.Msg(msg);
			}
		}

		public override void OnInitializeMelon()
		{
			Instance = this;
			Log = ((MelonBase)this).LoggerInstance;
			PropHuntPreferences.Initialize();
			RegisterWithSideHustle();
			Log.Msg($"PropHunt initialized. Enabled={PropHuntPreferences.Enabled}");
		}

		private static void RegisterWithSideHustle()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			try
			{
				GamemodeDescriptor val = new GamemodeDescriptor();
				val.Id = "doodesch.prophunt";
				val.DisplayName = "PropHunt";
				val.Description = "Hiders disguise as props; hunters find them before the timer runs out.";
				val.Author = "DooDesch";
				val.Support = (GamemodeSupport)1;
				val.Surface = (GamemodeSurface)1;
				val.OnHostMultiplayer = OnHostMultiplayer;
				val.OnJoinMultiplayer = OnJoinMultiplayer;
				val.OnExitToHub = OnExitToHub;
				val.HostSettings = PropHuntSettingsSpec.Build();
				val.Presets = RoundPresets.Build();
				val.BlockVanillaQuests = true;
				val.AllowedQuestTitles = new string[1] { "PropHunt" };
				val.SkipIntro = true;
				val.ForceNewGame = true;
				val.BlockSaveDuringSession = true;
				val.SuppressNpcCombatReactions = true;
				val.DisableVanillaPlayerDeath = true;
				val.DefaultRequiredModsOnly = true;
				ModPolicy val2 = new ModPolicy();
				val2.AllowedMods = new string[3] { "Snitch", "Inkorporated", "Inkubator" };
				val.Policy = val2;
				_descriptor = val;
				API.Register(_descriptor);
				Log.Msg("[PropHunt] registered with Side Hustle.");
			}
			catch (Exception ex)
			{
				Log.Warning("[PropHunt] Side Hustle not available; cannot register as a gamemode: " + ex.Message);
			}
		}

		private static void OnHostMultiplayer(LaunchContext ctx)
		{
			_session = ctx;
			Log.Msg($"[PropHunt] hosting via Side Hustle (lobby {ctx.LobbyId}, {ctx.PlayerCount} player(s)).");
			try
			{
				MultiplayerInfo multiplayer = ctx.Multiplayer;
				if (multiplayer != null && !string.IsNullOrEmpty(multiplayer.Mode) && multiplayer.Mode.StartsWith("Custom - ") && !string.IsNullOrEmpty(multiplayer.ConfigBlob))
				{
					PropHuntPreferences.SaveCustomPreset(multiplayer.ConfigBlob, multiplayer.Mode.Substring("Custom - ".Length));
					if (_descriptor != null)
					{
						_descriptor.Presets = RoundPresets.Build();
					}
				}
			}
			catch (Exception ex)
			{
				Log.Warning("[PropHunt] save custom preset failed: " + ex.Message);
			}
			PropHuntNet.Initialize();
			_controller?.Dispose();
			_controller = new GameModeController(ctx, isHost: true);
			_controller.StartAsHost();
		}

		private static void OnJoinMultiplayer(LaunchContext ctx)
		{
			_session = ctx;
			Log.Msg($"[PropHunt] joined via Side Hustle (lobby {ctx.LobbyId}, host {ctx.HostName ?? "?"}).");
			PropHuntNet.Initialize();
			_controller?.Dispose();
			_controller = new GameModeController(ctx, isHost: false);
			_controller.StartAsClient();
		}

		private static void OnExitToHub(LaunchContext ctx)
		{
			Log.Msg("[PropHunt] session ended; tearing down.");
			HudController.Teardown();
			_controller?.Dispose();
			_controller = null;
			_session = null;
		}

		public override void OnSceneWasInitialized(int buildIndex, string sceneName)
		{
			if (sceneName == "Main" && !_patched)
			{
				_patched = true;
				bool flag = false;
				try
				{
					using IEnumerator<MethodBase> enumerator = ((MelonBase)this).HarmonyInstance.GetPatchedMethods().GetEnumerator();
					if (enumerator.MoveNext())
					{
						_ = enumerator.Current;
						flag = true;
					}
				}
				catch
				{
				}
				try
				{
					if (flag)
					{
						Log.Msg("[PropHunt] gameplay patches already applied; skipping PatchAll.");
					}
					else
					{
						((MelonBase)this).HarmonyInstance.PatchAll();
						Log.Msg("[PropHunt] PatchAll completed.");
					}
				}
				catch (Exception ex)
				{
					Log.Error("[PropHunt] PatchAll FAILED (later patches skipped): " + ex);
				}
				try
				{
					int num = 0;
					foreach (MethodBase patchedMethod in ((MelonBase)this).HarmonyInstance.GetPatchedMethods())
					{
						_ = patchedMethod;
						num++;
					}
					Log.Msg($"[PropHunt] patched method count: {num}");
				}
				catch
				{
				}
			}
			if (sceneName == "Menu" || sceneName == "Main")
			{
				PropHuntNet.Initialize();
			}
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (sceneName != "Main")
			{
				return;
			}
			try
			{
				if (WeaponCatalog.RefreshFromRegistry() && _descriptor != null)
				{
					_descriptor.HostSettings = PropHuntSettingsSpec.Build();
				}
			}
			catch (Exception ex)
			{
				Log.Warning("[PropHunt] weapon catalog refresh failed: " + ex.Message);
			}
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			if (sceneName != "Main")
			{
				return;
			}
			try
			{
				HudController.Teardown();
			}
			catch
			{
			}
			if (_controller != null)
			{
				Log.Msg("[PropHunt] left the gameplay scene; tearing down the session.");
				try
				{
					_controller.Dispose();
				}
				catch
				{
				}
				_controller = null;
				_session = null;
			}
		}

		public override void OnUpdate()
		{
			PropHuntNet.Tick();
			_controller?.Tick(Time.deltaTime);
			PropHuntPhoneApp.Instance?.Tick();
			HudController.Tick();
		}

		public override void OnLateUpdate()
		{
			_controller?.LateTick();
		}

		public override void OnGUI()
		{
			if (_controller != null)
			{
				_controller.DrawGui();
			}
		}
	}
}
namespace PropHunt.View
{
	internal static class BodyCam
	{
		private static bool _active;

		private const float PullBack = 3.6f;

		private const float Lift = 2.1f;

		private const float StartLerp = 0.5f;

		private const float StopLerp = 0.4f;

		internal static bool Active => _active;

		internal static void Start()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//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_005f: 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_0069: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			if (_active)
			{
				return;
			}
			try
			{
				PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance;
				Player local = Player.Local;
				if (!((Object)(object)instance == (Object)null) && !((Object)(object)local == (Object)null))
				{
					Vector3 val = BodyPoint(local);
					Vector3 val2 = -((Component)local).transform.forward;
					Vector3 val3 = val + val2 * 3.6f + Vector3.up * 2.1f;
					Vector3 val4 = val - val3;
					Quaternion val5 = Quaternion.LookRotation(((Vector3)(ref val4)).normalized, Vector3.up);
					local.SetVisibleToLocalPlayer(true);
					instance.blockNextStopTransformOverride = false;
					instance.OverrideTransform(val3, val5, 0.5f, false);
					_active = true;
				}
			}
			catch (Exception)
			{
			}
		}

		internal static void Track(PlayerCamera cam)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!_active || (Object)(object)cam == (Object)null)
			{
				return;
			}
			try
			{
				Player local = Player.Local;
				if (!((Object)(object)local == (Object)null))
				{
					((Component)cam).transform.LookAt(BodyPoint(local));
					local.SetVisibleToLocalPlayer(true);
				}
			}
			catch
			{
			}
		}

		internal static void Stop()
		{
			if (!_active)
			{
				return;
			}
			_active = false;
			try
			{
				PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.StopTransformOverride(0.4f, true, true);
				}
			}
			catch (Exception)
			{
			}
			try
			{
				Player local = Player.Local;
				if (local != null)
				{
					local.SetVisibleToLocalPlayer(false);
				}
			}
			catch
			{
			}
		}

		private static Vector3 BodyPoint(Player lp)
		{
			//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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)lp.Avatar != (Object)null && (Object)(object)lp.Avatar.CenterPointTransform != (Object)null)
				{
					return lp.Avatar.CenterPointTransform.position;
				}
			}
			catch
			{
			}
			return ((Component)lp).transform.position + Vector3.up;
		}
	}
	internal static class EyeBlink
	{
		private const string BlinkKey = "PropHunt.Blink";

		private static bool _blindHeld;

		private const float CloseSeconds = 0.5f;

		private const float OpenSeconds = 0.65f;

		private const float BlindCloseSeconds = 0.4f;

		private const float BlindOpenSeconds = 0.45f;

		internal static bool Running => ScreenTransition.IsRunning("PropHunt.Blink");

		internal static void Teleport(Action onShut)
		{
			if (onShut != null)
			{
				ScreenTransition.Play(new TransitionRequest
				{
					Mechanism = VeilMode.Eyelids,
					CloseSeconds = 0.5f,
					OpenSeconds = 0.65f,
					DuringBlack = onShut,
					KeepClosedAfter = () => _blindHeld,
					Key = "PropHunt.Blink"
				});
			}
		}

		internal static void Blind()
		{
			if (_blindHeld)
			{
				return;
			}
			_blindHeld = true;
			if (!Veil.EyelidsAvailable)
			{
				return;
			}
			try
			{
				MelonCoroutines.Start(Veil.FadeEyelids(0f, 0.4f, releaseToGame: false));
			}
			catch
			{
			}
		}

		internal static void Unblind()
		{
			if (!_blindHeld)
			{
				return;
			}
			_blindHeld = false;
			if (!Veil.EyelidsAvailable)
			{
				return;
			}
			try
			{
				MelonCoroutines.Start(Veil.FadeEyelids(1f, 0.45f, releaseToGame: true));
			}
			catch
			{
				Veil.SetEyelids(1f);
				Veil.ReleaseEyelids();
			}
		}

		internal static void ResetState()
		{
			_blindHeld = false;
			ScreenTransition.ForceReset("PropHunt.Blink");
		}
	}
	internal static class SpectatorCam
	{
		internal static bool Active;

		internal static Transform Target;

		internal static float Distance = 3.5f;

		internal static float Height = 1f;
	}
	internal sealed class SpectatorController
	{
		private readonly GameModeController _ctl;

		private bool _active;

		private bool _freecam;

		private int _cycle;

		private ulong _targetId;

		private float _nextRefresh;

		internal bool Active => _active;

		internal string HudText { get; private set; }

		internal SpectatorController(GameModeController ctl)
		{
			_ctl = ctl;
		}

		internal void Tick()
		{
			try
			{
				bool flag = ShouldSpectate();
				if (flag && !_active)
				{
					Enter();
				}
				else if (!flag && _active)
				{
					Exit();
					return;
				}
				if (!_active)
				{
					HudText = null;
					return;
				}
				if (Input.GetKeyDown((KeyCode)52))
				{
					ToggleMode();
				}
				if (_freecam)
				{
					HudText = "FREECAM   [4] follow-cam";
					return;
				}
				if (Time.time >= _nextRefresh)
				{
					_nextRefresh = Time.time + 1f;
					PlayerRegistry.Refresh();
				}
				EnsureTarget();
				if (Input.GetKeyDown((KeyCode)323))
				{
					CycleTarget();
				}
				UpdateFollowCam();
			}
			catch (Exception)
			{
			}
		}

		internal void ForceExit()
		{
			if (_active)
			{
				Exit();
			}
		}

		private bool ShouldSpectate()
		{
			RoundPhase phase = _ctl.Phase;
			if (phase != RoundPhase.Hiding && phase != RoundPhase.Hunting)
			{
				return false;
			}
			PlayerState playerState = LocalState();
			if (playerState == null)
			{
				return false;
			}
			if (playerState.Role == PlayerRole.Spectator)
			{
				return true;
			}
			if (playerState.Role == PlayerRole.Hider && playerState.Eliminated)
			{
				return true;
			}
			return false;
		}

		private void Enter()
		{
			_active = true;
			_freecam = false;
			_targetId = 0uL;
			SetCanMove(can: false);
			SetCanLook(can: false);
			PlayerRegistry.Refresh();
			EnsureTarget();
			SpectatorCam.Active = true;
		}

		private void Exit()
		{
			_active = false;
			SpectatorCam.Active = false;
			SpectatorCam.Target = null;
			if (_freecam)
			{
				SetFreeCam(on: false);
				_freecam = false;
			}
			SetCanLook(can: true);
			SetCanMove(can: true);
			HudText = null;
		}

		private void ToggleMode()
		{
			_freecam = !_freecam;
			if (_freecam)
			{
				SpectatorCam.Active = false;
				SetFreeCam(on: true);
				return;
			}
			SetFreeCam(on: false);
			SetCanMove(can: false);
			SetCanLook(can: false);
			SpectatorCam.Active = true;
		}

		private void EnsureTarget()
		{
			if (_targetId == 0L || !IsAliveOther(_targetId))
			{
				List<ulong> list = AliveOthers();
				_targetId = ((list.Count > 0) ? list[0] : 0);
				_cycle = 0;
			}
		}

		private void CycleTarget()
		{
			List<ulong> list = AliveOthers();
			if (list.Count == 0)
			{
				_targetId = 0uL;
				return;
			}
			_cycle = (_cycle + 1) % list.Count;
			_targetId = list[_cycle];
		}

		private List<ulong> AliveOthers()
		{
			List<ulong> list = new List<ulong>();
			List<ulong> list2 = new List<ulong>();
			ulong localId = _ctl.LocalId;
			foreach (KeyValuePair<ulong, PlayerState> player in _ctl.State.Players)
			{
				PlayerState value = player.Value;
				if (value.SteamId != localId && !value.Eliminated)
				{
					if (value.Role == PlayerRole.Hider)
					{
						list.Add(value.SteamId);
					}
					else if (value.Role == PlayerRole.Hunter)
					{
						list2.Add(value.SteamId);
					}
				}
			}
			list.Sort();
			list2.Sort();
			list.AddRange(list2);
			return list;
		}

		private bool IsAliveOther(ulong id)
		{
			if (id != _ctl.LocalId && _ctl.State.Players.TryGetValue(id, out var value) && !value.Eliminated)
			{
				if (value.Role != PlayerRole.Hider)
				{
					return value.Role == PlayerRole.Hunter;
				}
				return true;
			}
			return false;
		}

		private void UpdateFollowCam()
		{
			Player val = ((_targetId != 0L) ? PlayerRegistry.Get(_targetId) : null);
			PlayerState playerState = LocalState();
			string text = ((playerState != null && playerState.Role == PlayerRole.Spectator) ? "You join next round.  " : "Caught!  ");
			if ((Object)(object)val == (Object)null)
			{
				SpectatorCam.Target = null;
				HudText = text + "Spectating - waiting for a player...   [4] freecam";
			}
			else
			{
				SpectatorCam.Target = ((Component)val).transform;
				HudText = text + "Spectating " + SafeName(val) + "   [click] next   [4] freecam";
			}
		}

		private PlayerState LocalState()
		{
			ulong localId = _ctl.LocalId;
			if (localId == 0L || !_ctl.State.Players.TryGetValue(localId, out var value))
			{
				return null;
			}
			return value;
		}

		private static void SetCanMove(bool can)
		{
			try
			{
				PlayerMovement instance = PlayerSingleton<PlayerMovement>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.CanMove = can;
				}
			}
			catch
			{
			}
		}

		private static void SetCanLook(bool can)
		{
			try
			{
				PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.SetCanLook(can);
				}
			}
			catch
			{
			}
		}

		private static void SetFreeCam(bool on)
		{
			try
			{
				PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.SetFreeCam(on, true);
				}
			}
			catch
			{
			}
		}

		private static string SafeName(Player p)
		{
			try
			{
				string playerName = p.PlayerName;
				return string.IsNullOrEmpty(playerName) ? "a player" : playerName;
			}
			catch
			{
				return "a player";
			}
		}
	}
	internal sealed class ThirdPersonController
	{
		private readonly GameModeController _ctl;

		private bool _on;

		private bool? _appliedArmsVisible;

		private ViewmodelAvatar _viewmodel;

		private float _scrollAccum;

		private float _zoomVel;

		private bool Allowed
		{
			get
			{
				if (_ctl.RoundActive && _ctl.LocalRole != PlayerRole.Hunter)
				{
					return !_ctl.LocalSpectating;
				}
				return false;
			}
		}

		internal bool IsOn
		{
			get
			{
				if (_on)
				{
					return Allowed;
				}
				return false;
			}
		}

		internal ThirdPersonController(GameModeController ctl)
		{
			_ctl = ctl;
		}

		internal void ForceOff()
		{
			_on = false;
		}

		internal void ForceOn()
		{
			_on = true;
		}

		internal void Tick()
		{
			try
			{
				if (!BodyCam.Active)
				{
					if (Input.GetKeyDown((KeyCode)118) && Allowed)
					{
						_on = !_on;
					}
					bool flag = (ThirdPersonView.Active = _on && Allowed);
					if (flag)
					{
						UpdateCameraForProp();
					}
					SetArmsVisible(!flag);
					SetOwnBodyVisible(flag && _ctl.LocalPropId < 0);
				}
			}
			catch
			{
			}
		}

		private void UpdateCameraForProp()
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				float num = ((_ctl.LocalPropId >= 0) ? PropCatalog.SizeOf(_ctl.LocalPropId) : 0f);
				if (num > 0f)
				{
					ThirdPersonView.BaseDistance = Mathf.Clamp(num * 1.7f + 1f, 1.6f, 9f);
					ThirdPersonView.Height = Mathf.Clamp(num * 0.4f, 0.2f, 2f);
				}
				else
				{
					ThirdPersonView.BaseDistance = 2.8f;
					ThirdPersonView.Height = 0.4f;
				}
				_scrollAccum += Input.mouseScrollDelta.y;
				int num2 = 0;
				while (Mathf.Abs(_scrollAccum) >= 1f && num2++ < 6)
				{
					float num3 = Mathf.Sign(_scrollAccum);
					ThirdPersonView.ZoomMultiplier = Mathf.Clamp(ThirdPersonView.ZoomMultiplier * Mathf.Pow(1.1f, 0f - num3), 0.55f, 2.5f);
					_scrollAccum -= num3;
				}
				float num4 = Mathf.Clamp(ThirdPersonView.BaseDistance * ThirdPersonView.ZoomMultiplier, 0.5f, 16f);
				ThirdPersonView.Distance = Mathf.SmoothDamp(ThirdPersonView.Distance, num4, ref _zoomVel, 0.12f);
			}
			catch
			{
			}
		}

		private void SetOwnBodyVisible(bool visible)
		{
			try
			{
				Player local = Player.Local;
				if ((Object)(object)local == (Object)null)
				{
					return;
				}
				local.SetVisibleToLocalPlayer(visible);
				if (!visible)
				{
					return;
				}
				try
				{
					local.SetThirdPersonMeshesVisibility(true);
				}
				catch
				{
				}
			}
			catch
			{
			}
		}

		private void SetArmsVisible(bool visible)
		{
			if (_appliedArmsVisible == visible)
			{
				return;
			}
			_appliedArmsVisible = visible;
			try
			{
				if ((Object)(object)_viewmodel == (Object)null)
				{
					_viewmodel = Object.FindObjectOfType<ViewmodelAvatar>();
				}
				if ((Object)(object)_viewmodel != (Object)null)
				{
					_viewmodel.SetVisibility(visible);
				}
			}
			catch
			{
			}
		}

		internal void Dispose()
		{
			_on = false;
			ThirdPersonView.Active = false;
			ThirdPersonView.ZoomMultiplier = 1f;
			_scrollAccum = 0f;
			SetArmsVisible(visible: true);
			SetOwnBodyVisible(visible: false);
		}
	}
	internal static class ThirdPersonView
	{
		internal static bool Active;

		internal static float Distance = 2.8f;

		internal static float Height = 0.4f;

		internal static float BaseDistance = 2.8f;

		internal static float ZoomMultiplier = 1f;

		internal const float ZoomStepPercent = 0.1f;

		internal const float ZoomMultiplierMin = 0.55f;

		internal const float ZoomMultiplierMax = 2.5f;

		internal const float GlobalMinDistance = 0.5f;

		internal const float GlobalMaxDistance = 16f;
	}
}
namespace PropHunt.UI
{
	internal sealed class Onboarding
	{
		private readonly GameModeController _ctl;

		private RoundPhase _lastPhase;

		private bool _cardActive;

		private bool _spawnCaptured;

		private Vector3 _spawnPos;

		private float _cardShownAt;

		private bool _helpOpen;

		private const float CardMaxSeconds = 45f;

		private const float LeaveRadius = 8f;

		internal bool CardActive => _cardActive;

		internal bool HelpOpen => _helpOpen;

		internal bool ShowControlsHint
		{
			get
			{
				if (_ctl.RoundActive)
				{
					return !_helpOpen;
				}
				return false;
			}
		}

		internal bool LocalIsHunter => _ctl.LocalRole == PlayerRole.Hunter;

		internal string CardTitle
		{
			get
			{
				if (!LocalIsHunter)
				{
					return "YOU ARE A HIDER";
				}
				return "YOU ARE A HUNTER";
			}
		}

		internal string CardGoal
		{
			get
			{
				if (!LocalIsHunter)
				{
					return "Disguise as a prop and survive until the hunt timer runs out.";
				}
				return "Find and shoot the disguised props before the hunt timer runs out.";
			}
		}

		internal string[] CardKeys
		{
			get
			{
				if (LocalIsHunter)
				{
					return new string[2]
					{
						"[" + KeyBinds.Name((KeyCode)323) + "]  shoot / catch   (big props take more hits)",
						"You are blinded until the hunt begins."
					};
				}
				return new string[4]
				{
					$"[{KeyBinds.Name((KeyCode)101)}] become what you look at      [{KeyBinds.Name((KeyCode)50)}] random prop",
					$"[{KeyBinds.Name((KeyCode)102)}]+mouse rotate      [{KeyBinds.Name((KeyCode)306)}] slow-walk",
					$"[{KeyBinds.Name((KeyCode)113)}] decoy      [{KeyBinds.Name((KeyCode)103)}] stun      [{KeyBinds.Name((KeyCode)49)}] taunt (hold = wheel)",
					$"[{KeyBinds.Name((KeyCode)118)}] third-person      [{KeyBinds.Name((KeyCode)98)}] prop markers on/off"
				};
			}
		}

		internal string CardFooter => "[" + KeyBinds.Name((KeyCode)104) + "] controls anytime   -   leave the safehouse when you are ready";

		internal string ControlsHintText => "[" + KeyBinds.Name((KeyCode)104) + "] Controls";

		internal string[] HelpHider => new string[9]
		{
			"[" + KeyBinds.Name((KeyCode)101) + "] become looked-at prop",
			"[" + KeyBinds.Name((KeyCode)50) + "] random prop",
			"[" + KeyBinds.Name((KeyCode)102) + "]+mouse rotate facing",
			"[" + KeyBinds.Name((KeyCode)306) + "] slow-walk",
			"[" + KeyBinds.Name((KeyCode)113) + "] drop decoy",
			"[" + KeyBinds.Name((KeyCode)103) + "] concussion (stun hunters)",
			"[" + KeyBinds.Name((KeyCode)49) + "] taunt (hold = wheel)",
			"[" + KeyBinds.Name((KeyCode)118) + "] third-person view",
			"[" + KeyBinds.Name((KeyCode)98) + "] toggle becomable-prop markers (off = blend in)"
		};

		internal string[] HelpHunter => new string[3]
		{
			"[" + KeyBinds.Name((KeyCode)323) + "] shoot / catch props",
			"Props have HP - big props take more hits.",
			"Blinded during the hide phase."
		};

		internal string[] HelpSpectator => new string[2]
		{
			"[" + KeyBinds.Name((KeyCode)52) + "] follow-cam <-> freecam",
			"[" + KeyBinds.Name((KeyCode)323) + "] next player (follow-cam)"
		};

		internal Onboarding(GameModeController ctl)
		{
			_ctl = ctl;
		}

		internal void Tick()
		{
			try
			{
				RoundPhase phase = _ctl.Phase;
				if (phase == RoundPhase.Hiding && _lastPhase != RoundPhase.Hiding)
				{
					PlayerRole localRole = _ctl.LocalRole;
					if (localRole == PlayerRole.Hider || localRole == PlayerRole.Hunter)
					{
						_cardActive = true;
						_spawnCaptured = false;
						_cardShownAt = Time.time;
					}
				}
				_lastPhase = phase;
				if (Input.GetKeyDown((KeyCode)104))
				{
					_helpOpen = !_helpOpen;
				}
				if (_cardActive)
				{
					UpdateCardDismiss();
				}
			}
			catch
			{
			}
		}

		private void UpdateCardDismiss()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time - _cardShownAt > 45f)
			{
				_cardActive = false;
				return;
			}
			RoundPhase phase = _ctl.Phase;
			if (phase != RoundPhase.Hiding && phase != RoundPhase.Hunting)
			{
				_cardActive = false;
				return;
			}
			if (phase == RoundPhase.Hunting)
			{
				_cardActive = false;
				return;
			}
			Player local = Player.Local;
			if ((Object)(object)local == (Object)null)
			{
				return;
			}
			Vector3 position = ((Component)local).transform.position;
			if (!_spawnCaptured)
			{
				_spawnPos = position;
				_spawnCaptured = true;
				return;
			}
			float num = position.x - _spawnPos.x;
			float num2 = position.z - _spawnPos.z;
			if (num * num + num2 * num2 > 64f)
			{
				_cardActive = false;
			}
		}

		internal void Reset()
		{
			_cardActive = false;
			_spawnCaptured = false;
			_helpOpen = false;
			_lastPhase = RoundPhase.Lobby;
		}
	}
}
namespace PropHunt.UI.Hud
{
	internal static class HudController
	{
		private static HudRoot _root;

		internal static void Tick()
		{
			try
			{
				GameModeController active = GameModeController.Active;
				if (active == null || !InGameplayScene())
				{
					if (_root != null)
					{
						Teardown();
					}
					return;
				}
				if (_root == null)
				{
					_root = new HudRoot();
				}
				_root.Apply(active);
			}
			catch
			{
			}
		}

		private static bool InGameplayScene()
		{
			//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)
			try
			{
				Scene activeScene = SceneManager.GetActiveScene();
				return ((Scene)(ref activeScene)).name == "Main";
			}
			catch
			{
				return true;
			}
		}

		internal static void ShowHitmarker()
		{
			try
			{
				_root?.ShowHitmarker();
			}
			catch
			{
			}
		}

		internal static void Teardown()
		{
			try
			{
				_root?.Destroy();
			}
			catch
			{
			}
			_root = null;
		}
	}
	internal sealed class HudRoot
	{
		private readonly GameObject _go;

		private readonly Transform _host;

		private readonly GameObject _statusPill;

		private readonly Text _status;

		private readonly HpBar _hp;

		private readonly HpBar _hunterHp;

		private readonly Text _hint;

		private readonly Text _transform;

		private readonly GameObject _abilityPill;

		private readonly Text _ability;

		private readonly GameObject _becomePill;

		private readonly Text _become;

		private readonly FlashLabel _flash;

		private readonly Hitmarker _hitmarker;

		private readonly GameObject _specPill;

		private readonly Text _spec;

		private readonly GameObject _oobPill;

		private readonly Text _oob;

		private readonly GameObject _safehousePill;

		private readonly Text _safehouse;

		private readonly GameObject _downedPill;

		private readonly Text _downed;

		private readonly Scoreboard _scoreboard;

		private readonly GameObject _cardPanel;

		private readonly Text _cardTitle;

		private readonly Text _cardBody;

		private readonly GameObject _helpPanel;

		private readonly Text _helpBody;

		private readonly Text _controlsHint;

		private string _cStatus;

		private string _cHint;

		private string _cTransform;

		private string _cAbility;

		private string _cBecome;

		private string _cSpec;

		private string _cOob;

		private string _cDowned;

		private string _cCardTitle;

		private string _cCardBody;

		private string _cHelpBody;

		private string _cControlsHint;

		private bool _cCardHunter;

		private bool _aStatus;

		private bool _aHp;

		private bool _aHunterHp;

		private bool _aHint;

		private bool _aTransform;

		private bool _aAbility;

		private bool _aBecome;

		private bool _aSpec;

		private bool _aOob;

		private bool _aSafehouse;

		private bool _aDowned;

		private bool _aCard;

		private bool _aHelp;

		private bool _aControlsHint;

		internal HudRoot()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Expected O, but got Unknown
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0539: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_0625: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_0681: Unknown result type (might be due to invalid IL or missing references)
			//IL_0696: Unknown result type (might be due to invalid IL or missing references)
			//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0729: Unknown result type (might be due to invalid IL or missing references)
			//IL_077a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0784: Unknown result type (might be due to invalid IL or missing references)
			//IL_0799: Unknown result type (might be due to invalid IL or missing references)
			//IL_07de: Unknown result type (might be due to invalid IL or missing references)
			//IL_082b: Unknown result type (might be due to invalid IL or missing references)
			//IL_088a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0894: Unknown result type (might be due to invalid IL or missing references)
			_go = new GameObject("PropHunt_Hud");
			Object.DontDestroyOnLoad((Object)(object)_go);
			Canvas obj = _go.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 100;
			GameObject val = UIFactory.Panel("hud_root", _go.transform, Theme.Clear, (Vector2?)null, (Vector2?)null, true);
			((Graphic)val.GetComponent<Image>()).raycastTarget = false;
			_host = val.transform;
			_statusPill = HudWidgets.Pill(_host, "hud_status", Theme.WithAlpha(Theme.BgDeep, 0.74f));
			HudWidgets.Outline(_statusPill, Theme.HairlineStrong);
			HudWidgets.Place(_statusPill, 0.5f, 1f, 0f, -12f, 760f, 36f);
			_status = HudWidgets.Label(_statusPill.transform, "txt", 16, Theme.TextPrimary, (TextAnchor)4, (FontStyle)1);
			HudWidgets.Stretch(((Graphic)_status).rectTransform, 12f, 0f, 12f, 0f);
			_hp = new HpBar(_host);
			HudWidgets.Place(_hp.Root, 0.5f, 1f, 0f, -56f, 260f, 18f);
			_hunterHp = new HpBar(_host);
			HudWidgets.Place(_hunterHp.Root, 0.5f, 1f, 0f, -56f, 260f, 18f);
			_hint = HudWidgets.Label(_host, "hud_hint", 13, Theme.InfoText, (TextAnchor)4, (FontStyle)0);
			HudWidgets.Place((Component)(object)_hint, 0.5f, 1f, 0f, -84f, 1100f, 24f);
			_transform = HudWidgets.Label(_host, "hud_transform", 13, Theme.SuccessText, (TextAnchor)4, (FontStyle)1);
			HudWidgets.Place((Component)(object)_transform, 0.5f, 1f, 0f, -112f, 800f, 22f);
			_abilityPill = HudWidgets.Pill(_host, "hud_ability", Theme.WithAlpha(Theme.BgDeep, 0.7f));
			HudWidgets.Outline(_abilityPill, Theme.Hairline);
			HudWidgets.Place(_abilityPill, 0.5f, 1f, 0f, -140f, 440f, 26f);
			_ability = HudWidgets.Label(_abilityPill.transform, "txt", 13, Theme.InfoText, (TextAnchor)4, (FontStyle)1);
			HudWidgets.Stretch(((Graphic)_ability).rectTransform, 12f, 0f, 12f, 0f);
			_becomePill = HudWidgets.Pill(_host, "hud_become", Theme.WithAlpha(Theme.BgDeep, 0.78f));
			HudWidgets.Place(_becomePill, 0.5f, 0.5f, 0f, -52f, 380f, 30f);
			_become = HudWidgets.Label(_becomePill.transform, "txt", 16, Theme.SuccessText, (TextAnchor)4, (FontStyle)1);
			HudWidgets.Stretch(((Graphic)_become).rectTransform, 10f, 0f, 10f, 0f);
			_flash = new FlashLabel(_host, 34);
			HudWidgets.Place(_flash.Root, 0.5f, 0.5f, 0f, 84f, 700f, 48f);
			_hitmarker = new Hitmarker(_host);
			_specPill = HudWidgets.Pill(_host, "hud_spec", Theme.WithAlpha(Theme.BgDeep, 0.74f));
			HudWidgets.Outline(_specPill, Theme.Hairline);
			HudWidgets.Place(_specPill, 0.5f, 0f, 0f, 74f, 540f, 34f);
			_spec = HudWidgets.Label(_specPill.transform, "txt", 13, Theme.InfoText, (TextAnchor)4, (FontStyle)1);
			HudWidgets.Stretch(((Graphic)_spec).rectTransform, 14f, 0f, 14f, 0f);
			_oobPill = HudWidgets.Pill(_host, "hud_oob", Theme.WithAlpha(Theme.DangerSubtle, 0.9f));
			HudWidgets.Outline(_oobPill, Theme.Danger);
			HudWidgets.Place(_oobPill, 0.5f, 1f, 0f, -188f, 600f, 44f);
			_oob = HudWidgets.Label(_oobPill.transform, "txt", 20, Theme.DangerText, (TextAnchor)4, (FontStyle)1);
			HudWidgets.Stretch(((Graphic)_oob).rectTransform, 12f, 0f, 12f, 0f);
			_safehousePill = HudWidgets.Pill(_host, "hud_safehouse", Theme.WithAlpha(Theme.SuccessSubtle, 0.9f));
			HudWidgets.Outline(_safehousePill, Theme.Success);
			HudWidgets.Place(_safehousePill, 0.5f, 0.5f, 0f, -110f, 440f, 36f);
			_safehouse = HudWidgets.Label(_safehousePill.transform, "txt", 16, Theme.SuccessText, (TextAnchor)4, (FontStyle)1);
			HudWidgets.Stretch(((Graphic)_safehouse).rectTransform, 12f, 0f, 12f, 0f);
			_downedPill = HudWidgets.Pill(_host, "hud_downed", Theme.WithAlpha(Theme.WarningSubtle, 0.92f));
			HudWidgets.Outline(_downedPill, Theme.Warning);
			HudWidgets.Place(_downedPill, 0.5f, 0.5f, 0f, -150f, 460f, 40f);
			_downed = HudWidgets.Label(_downedPill.transform, "txt", 16, Theme.WarningText, (TextAnchor)4, (FontStyle)1);
			HudWidgets.Stretch(((Graphic)_downed).rectTransform, 12f, 0f, 12f, 0f);
			_scoreboard = new Scoreboard(_host);
			_cardPanel = HudWidgets.Pill(_host, "hud_card", Theme.WithAlpha(Theme.BgDeep, 0.92f));
			HudWidgets.Outline(_cardPanel, Theme.HairlineStrong);
			HudWidgets.Place(_cardPanel, 0.5f, 0.5f, 0f, 120f, 600f, 220f);
			_cardTitle = HudWidgets.Label(_cardPanel.transform, "title", 20, Theme.SuccessText, (TextAnchor)1, (FontStyle)1);
			HudWidgets.Place((Component)(object)_cardTitle, 0.5f, 1f, 0f, -16f, 560f, 30f);
			_cardBody = HudWidgets.Label(_cardPanel.transform, "body", 13, Theme.TextPrimary, (TextAnchor)1, (FontStyle)0);
			_cardBody.lineSpacing = 1.25f;
			HudWidgets.Stretch(((Graphic)_cardBody).rectTransform, 22f, 56f, 22f, 16f);
			_helpPanel = HudWidgets.Pill(_host, "hud_help", Theme.WithAlpha(Theme.BgDeep, 0.95f));
			HudWidgets.Outline(_helpPanel, Theme.HairlineStrong);
			HudWidgets.Place(_helpPanel, 0.5f, 0.5f, 0f, 0f, 620f, 580f);
			Text obj2 = HudWidgets.Label(_helpPanel.transform, "title", 20, Theme.TextPrimary, (TextAnchor)1, (FontStyle)1);
			HudWidgets.Place((Component)(object)obj2, 0.5f, 1f, 0f, -16f, 580f, 28f);
			obj2.text = "PropHunt - Controls";
			_helpBody = HudWidgets.Label(_helpPanel.transform, "body", 13, Theme.TextPrimary, (TextAnchor)0, (FontStyle)0);
			_helpBody.lineSpacing = 1.3f;
			_helpBody.supportRichText = true;
			HudWidgets.Stretch(((Graphic)_helpBody).rectTransform, 28f, 56f, 28f, 16f);
			_controlsHint = HudWidgets.Label(_host, "hud_controls_hint", 11, Theme.WithAlpha(Theme.TextMuted, 0.9f), (TextAnchor)7, (FontStyle)1);
			HudWidgets.Place((Component)(object)_controlsHint, 0.5f, 0f, 0f, 22f, 360f, 20f);
			HideAll();
			try
			{
				Canvas.ForceUpdateCanvases();
			}
			catch
			{
			}
		}

		private void HideAll()
		{
			Hide(_statusPill, ref _aStatus);
			Hide(_hp.Root, ref _aHp);
			Hide(_hunterHp.Root, ref _aHunterHp);
			Hide(_downedPill, ref _aDowned);
			Hide(((Component)_hint).gameObject, ref _aHint);
			Hide(((Component)_transform).gameObject, ref _aTransform);
			Hide(_abilityPill, ref _aAbility);
			Hide(_becomePill, ref _aBecome);
			Hide(_specPill, ref _aSpec);
			Hide(_oobPill, ref _aOob);
			Hide(_safehousePill, ref _aSafehouse);
			Hide(_cardPanel, ref _aCard);
			Hide(_helpPanel, ref _aHelp);
			Hide(((Component)_controlsHint).gameObject, ref _aControlsHint);
		}

		private static void Hide(GameObject go, ref bool cache)
		{
			go.SetActive(false);
			cache = false;
		}

		internal void Apply(GameModeController ctl)
		{
			//IL_0743: Unknown result type (might be due to invalid IL or missing references)
			RoundPhase phase = ctl.Phase;
			bool flag = phase == RoundPhase.Hiding || phase == RoundPhase.Hunting;
			bool flag2 = ctl.LocalRole == PlayerRole.Hider && !ctl.LocalSpectating;
			bool num = flag2 && ctl.LocalPropId >= 0;
			string text = "PropHunt  -  " + phase;
			if (flag)
			{
				text += $"      {ctl.SecondsLeft}s      Hiders left: {ctl.AliveHiderCount}      You: {ctl.LocalRole}";
				int secondsToWhistle = ctl.SecondsToWhistle;
				if (secondsToWhistle >= 0)
				{
					text += $"      whistle in {secondsToWhistle}s";
				}
			}
			else if (phase == RoundPhase.RoundEnd || phase == RoundPhase.Safehouse)
			{
				int secondsUntilNextRound = ctl.SecondsUntilNextRound;
				text = ((phase == RoundPhase.Safehouse && ctl.State.SafehouseReady) ? (text + ((secondsUntilNextRound > 0) ? $"      starting in {secondsUntilNextRound}s" : "      starting...")) : ((secondsUntilNextRound > 0) ? (text + $"      next round in {secondsUntilNextRound}s") : ((phase != RoundPhase.Safehouse) ? (text + "      round over") : (text + "      waiting for the host..."))));
			}
			SetText(_status, ref _cStatus, text);
			SetActive(_statusPill, ref _aStatus, val: true);
			bool flag3 = num && phase == RoundPhase.Hunting;
			if (flag3)
			{
				_hp.Set(Mathf.Max(0, ctl.LocalMaxHits - ctl.LocalHits), Mathf.Max(1, ctl.LocalMaxHits));
			}
			SetActive(_hp.Root, ref _aHp, flag3);
			bool num2 = ctl.LocalRole == PlayerRole.Hunter && !ctl.LocalSpectating;
			bool flag4 = ctl.Settings != null && ctl.Settings.FriendlyFire;
			bool flag5 = num2 && phase == RoundPhase.Hunting && flag4 && !ctl.LocalDowned;
			if (flag5)
			{
				_hunterHp.Set(Mathf.Max(0, ctl.LocalHunterMaxHits - ctl.LocalHunterHits), Mathf.Max(1, ctl.LocalHunterMaxHits));
			}
			SetActive(_hunterHp.Root, ref _aHunterHp, flag5);
			bool localDowned = ctl.LocalDowned;
			if (localDowned)
			{
				SetText(_downed, ref _cDowned, $"KNOCKED DOWN - {ctl.LocalDownedSecondsLeft}s");
			}
			SetActive(_downedPill, ref _aDowned, localDowned);
			string value = (ctl.ThirdPersonOn ? ("[" + KeyBinds.Name((KeyCode)118) + "] 1st-person") : ("[" + KeyBinds.Name((KeyCode)118) + "] 3rd-person"));
			string text2 = null;
			if (flag2 && flag)
			{
				string lookTargetName = ctl.LookTargetName;
				string value2 = ((lookTargetName != null) ? ("[" + KeyBinds.Name((KeyCode)101) + "] become " + lookTargetName) : "Look at a highlighted object to become it");
				string value3 = ((phase == RoundPhase.Hunting) ? "Stay hidden!   " : "");
				string value4 = ((ctl.LocalPropId >= 0) ? ("   [" + KeyBinds.Name((KeyCode)102) + "]+mouse rotate") : "");
				string value5 = ((ctl.Settings == null || ctl.Settings.AllowRandomChange) ? ("   [" + KeyBinds.Name((KeyCode)50) + "] random") : "");
				text2 = $"{value3}{value2}{value5}{value4}      {value}";
			}
			else if (phase == RoundPhase.Hiding && ctl.LocalRole == PlayerRole.Hunter)
			{
				text2 = "Get ready... (blinded until the hunt begins)";
			}
			else if (phase == RoundPhase.Hunting && ctl.LocalRole == PlayerRole.Hunter)
			{
				text2 = "Find the props  -  [" + KeyBinds.Name((KeyCode)323) + "] to catch (big props take more hits)";
			}
			SetText(_hint, ref _cHint, text2 ?? "");
			SetActive(((Component)_hint).gameObject, ref _aHint, text2 != null);
			if (num && flag && ctl.Settings != null)
			{
				RoundSettings settings = ctl.Settings;
				string text3 = ctl.LocalPropName ?? "a prop";
				string text4 = ((settings.MaxPropChanges > 0) ? $"{Mathf.Max(0, settings.MaxPropChanges - ctl.LocalChanges)} CHANGES LEFT" : "UNLIMITED CHANGES");
				SetText(_transform, ref _cTransform, "You are now: " + text3 + "   -   " + text4);
				SetActive(((Component)_transform).gameObject, ref _aTransform, val: true);
				string obj = ((settings.MaxDecoys > 0) ? $"[{KeyBinds.Name((KeyCode)113)}] Decoy ({Mathf.Max(0, settings.MaxDecoys - ctl.LocalDecoysUsed)})" : "");
				string text5 = ((settings.ConcussCharges > 0) ? $"[{KeyBinds.Name((KeyCode)103)}] Stun ({Mathf.Max(0, settings.ConcussCharges - ctl.LocalConcussUsed)})" : "");
				string text6 = (obj + "      " + text5).Trim();
				SetText(_ability, ref _cAbility, text6);
				SetActive(_abilityPill, ref _aAbility, text6.Length > 0);
			}
			else
			{
				SetActive(((Component)_transform).gameObject, ref _aTransform, val: false);
				SetActive(_abilityPill, ref _aAbility, val: false);
			}
			string text7 = ((flag2 && flag) ? ctl.LookTargetName : null);
			if (text7 != null)
			{
				SetText(_become, ref _cBecome, "[" + KeyBinds.Name((KeyCode)101) + "] become " + text7);
			}
			SetActive(_becomePill, ref _aBecome, text7 != null);
			if (ctl.FxActive)
			{
				_flash.Trigger(ctl.FxText, ctl.FxColor, Time.unscaledTime);
			}
			_flash.Tick(Time.unscaledTime);
			_hitmarker.Tick(Time.unscaledTime);
			string spectatorHudText = ctl.SpectatorHudText;
			bool flag6 = !string.IsNullOrEmpty(spectatorHudText);
			if (flag6)
			{
				SetText(_spec, ref _cSpec, spectatorHudText);
			}
			SetActive(_specPill, ref _aSpec, flag6);
			bool localOutside = ctl.LocalOutside;
			if (localOutside)
			{
				SetText(_oob, ref _cOob, $"RETURN TO THE PLAY AREA!   {Mathf.CeilToInt(ctl.OobGrace)}s");
			}
			SetActive(_oobPill, ref _aOob, localOutside);
			SetActive(_safehousePill, ref _aSafehouse, phase == RoundPhase.Safehouse && ctl.State.SafehouseReady);
			if (_aSafehouse && _safehouse.text != "Doors opening - get ready!")
			{
				_safehouse.text = "Doors opening - get ready!";
			}
			ApplyControls(ctl);
			_scoreboard.Apply(ctl);
		}

		private void ApplyControls(GameModeController ctl)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			Onboarding onboarding = ctl.Onboarding;
			if (onboarding == null)
			{
				SetActive(_cardPanel, ref _aCard, val: false);
				SetActive(_helpPanel, ref _aHelp, val: false);
				SetActive(((Component)_controlsHint).gameObject, ref _aControlsHint, val: false);
				return;
			}
			bool flag = onboarding.CardActive && !ctl.TauntWheelOpen && !onboarding.HelpOpen;
			if (flag)
			{
				SetText(_cardTitle, ref _cCardTitle, onboarding.CardTitle);
				if (_cCardHunter != onboarding.LocalIsHunter)
				{
					_cCardHunter = onboarding.LocalIsHunter;
					((Graphic)_cardTitle).color = (onboarding.LocalIsHunter ? Theme.DangerText : Theme.SuccessText);
				}
				string val = onboarding.CardGoal + "\n\n" + string.Join("\n", onboarding.CardKeys) + "\n\n" + onboarding.CardFooter;
				SetText(_cardBody, ref _cCardBody, val);
			}
			SetActive(_cardPanel, ref _aCard, flag);
			if (onboarding.HelpOpen)
			{
				string val2 = "<b>HIDER</b>\n   " + string.Join("\n   ", onboarding.HelpHider) + "\n\n<b>HUNTER</b>\n   " + string.Join("\n   ", onboarding.HelpHunter) + "\n\n<b>SPECTATOR (when caught)</b>\n   " + string.Join("\n   ", onboarding.HelpSpectator) + "\n\n" + onboarding.ControlsHintText.Replace("Controls", "close");
				SetText(_helpBody, ref _cHelpBody, val2);
			}
			SetActive(_helpPanel, ref _aHelp, onboarding.HelpOpen);
			bool showControlsHint = onboarding.ShowControlsHint;
			if (showControlsHint)
			{
				SetText(_controlsHint, ref _cControlsHint, onboarding.ControlsHintText);
			}
			SetActive(((Component)_controlsHint).gameObject, ref _aControlsHint, showControlsHint);
		}

		private static void SetText(Text t, ref string cache, string val)
		{
			if (!(cache == val))
			{
				cache = val;
				t.text = val;
			}
		}

		private static void SetActive(GameObject go, ref bool cache, bool val)
		{
			if (cache != val)
			{
				cache = val;
				go.SetActive(val);
			}
		}

		internal void ShowHitmarker()
		{
			try
			{
				_hitmarker.Trigger(Time.unscaledTime);
			}
			catch
			{
			}
		}

		internal void Destroy()
		{
			if ((Object)(object)_go != (Object)null)
			{
				Object.Destroy((Object)(object)_go);
			}
		}
	}
	internal static class HudWidgets
	{
		internal static Text Label(Transform parent, string name, int size, Color color, TextAnchor anchor = (TextAnchor)4, FontStyle style = (FontStyle)0)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return HudPrimitives.Label(parent, name, size, color, anchor, style);
		}

		internal static GameObject Pill(Transform parent, string name, Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return HudPrimitives.Pill(parent, name, color);
		}

		internal static void Outline(GameObject go, Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			HudPrimitives.Outline(go, color);
		}

		internal static void Place(Component c, float ax, float ay, float x, float y, float w, float h)
		{
			HudPrimitives.Place(c, ax, ay, x, y, w, h);
		}

		internal static void Place(GameObject go, float ax, float ay, float x, float y, float w, float h)
		{
			HudPrimitives.Place(go, ax, ay, x, y, w, h);
		}

		internal static void Stretch(RectTransform rt, float l, float t, float r, float b)
		{
			HudPrimitives.Stretch(rt, l, t, r, b);
		}
	}
	internal sealed class HpBar
	{
		private readonly GameObject _root;

		private readonly Image _fill;

		private readonly Text _label;

		private float _lastFill = -1f;

		private string _lastText;

		private Color _lastColor;

		internal GameObject Root => _root;

		internal HpBar(Transform parent)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			_root = HudWidgets.Pill(parent, "hud_hp_track", Theme.WithAlpha(Theme.BgDeep, 0.8f));
			HudWidgets.Outline(_root, Theme.HairlineStrong);
			GameObject val = HudWidgets.Pill(_root.transform, "hud_hp_fill", Theme.Success);
			_fill = val.GetComponent<Image>();
			_fill.type = (Type)3;
			_fill.fillMethod = (FillMethod)0;
			_fill.fillOrigin = 0;
			_fill.fillAmount = 1f;
			HudWidgets.Stretch(((Graphic)_fill).rectTransform, 2f, 2f, 2f, 2f);
			_label = HudWidgets.Label(_root.transform, "hud_hp_txt", 11, Theme.TextPrimary, (TextAnchor)4, (FontStyle)1);
			HudWidgets.Stretch(((Graphic)_label).rectTransform, 0f, 0f, 0f, 0f);
		}

		internal void Set(int remaining, int max)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_005d: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			float num = ((max > 0) ? Mathf.Clamp01((float)remaining / (float)max) : 0f);
			if (!Mathf.Approximately(num, _lastFill))
			{
				_lastFill = num;
				_fill.fillAmount = num;
			}
			Color val = ((num > 0.5f) ? Theme.Success : ((num > 0.25f) ? Theme.Warning : Theme.Danger));
			if (val != _lastColor)
			{
				_lastColor = val;
				((Graphic)_fill).color = val;
			}
			string text = $"{remaining} / {max} HP";
			if (text != _lastText)
			{
				_lastText = text;
				_label.text = text;
			}
		}
	}
	internal sealed class Hitmarker
	{
		private const float Dur = 0.22f;

		private readonly GameObject _root;

		private readonly CanvasGroup _cg;

		private float _start;

		internal GameObject Root => _root;

		internal Hitmarker(Transform parent)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			_root = HudWidgets.Pill(parent, "hud_hitmarker", Theme.Clear);
			_cg = _root.AddComponent<CanvasGroup>();
			_cg.blocksRaycasts = false;
			_cg.interactable = false;
			HudWidgets.Place(_root, 0.5f, 0.5f, 0f, 0f, 40f, 40f);
			MakeTick(-11f, 11f, -45f);
			MakeTick(11f, 11f, 45f);
			MakeTick(-11f, -11f, 45f);
			MakeTick(11f, -11f, -45f);
			_root.SetActive(false);
		}

		private void MakeTick(float x, float y, float rot)
		{
			//IL_0010: 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)
			GameObject obj = HudWidgets.Pill(_root.transform, "tick", Color.white);
			HudWidgets.Place(obj, 0.5f, 0.5f, x, y, 11f, 3f);
			((Transform)obj.GetComponent<RectTransform>()).localEulerAngles = new Vector3(0f, 0f, rot);
		}

		internal void Trigger(float now)
		{
			_start = now;
			if (!_root.activeSelf)
			{
				_root.SetActive(true);
			}
		}

		internal void Tick(float now)
		{
			if (_root.activeSelf)
			{
				float num = now - _start;
				if (num >= 0.22f)
				{
					_root.SetActive(false);
				}
				else
				{
					_cg.alpha = Mathf.Clamp01(1f - num / 0.22f);
				}
			}
		}
	}
	internal sealed class Scoreboard
	{
		private struct Award
		{
			public string Title;

			public string Name;

			public string Metric;
		}

		private const float CardWidth = 720f;

		private const float Inset = 30f;

		private const float ContentW = 660f;

		private const float RowH = 30f;

		private const float CRank = 0f;

		private const float WRank = 36f;

		private const float CName = 44f;

		private const float WName = 220f;

		private const float CRole = 270f;

		private const float WRole = 96f;

		private const float CCatch = 374f;

		private const float WCatch = 86f;

		private const float CSurv = 466f;

		private const float WSurv = 92f;

		private const float CScore = 564f;

		private const float WScore = 76f;

		private readonly GameObject _card;

		private readonly GameObject _content;

		private bool _active;

		private string _sig;

		internal Scoreboard(Transform parent)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			_card = HudWidgets.Pill(parent, "hud_scoreboard", Theme.WithAlpha(Theme.BgDeep, 0.94f));
			HudWidgets.Outline(_card, Theme.HairlineStrong);
			HudWidgets.Place(_card, 0.5f, 0.5f, 0f, 0f, 720f, 480f);
			_content = UIFactory.Panel("content", _card.transform, Theme.Clear, (Vector2?)null, (Vector2?)null, false);
			((Graphic)_content.GetComponent<Image>()).raycastTarget = false;
			HudWidgets.Stretch(_content.GetComponent<RectTransform>(), 30f, 26f, 30f, 26f);
			_card.SetActive(false);
		}

		internal void Apply(GameModeController ctl)
		{
			if (ctl.Phase != RoundPhase.RoundEnd)
			{
				if (_active)
				{
					_active = false;
					_card.SetActive(false);
				}
				return;
			}
			GameState state = ctl.State;
			string text = $"{state.Winner}|{state.RoundNumber}|{state.Players.Count}";
			if (!_active)
			{
				_active = true;
				_card.SetActive(true);
			}
			if (text != _sig)
			{
				_sig = text;
				Rebuild(state, ctl.LocalId);
			}
		}

		private void Rebuild(GameState st, ulong localId)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: 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_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0403: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_053a: Unknown result type (might be due to invalid IL or missing references)
			UIFactory.ClearChildren(_content.transform);
			try
			{
				PlayerRegistry.Refresh();
			}
			catch
			{
			}
			List<PlayerState> list = new List<PlayerState>(st.Players.Values);
			list.Sort((PlayerState a, PlayerState b) => b.SessScore.CompareTo(a.SessScore));
			List<Award> list2 = BuildAwards(list);
			float num = 0f;
			if (st.Winner != 0)
			{
				_ = st.Winner;
				_ = 1;
			}
			Color color = ((st.Winner == 0) ? Theme.DangerText : ((st.Winner == 1) ? Theme.SuccessText : Theme.TextPrimary));
			Text t = HudWidgets.Label(_content.transform, "headline", 28, color, (TextAnchor)1, (FontStyle)1);
			FullRow(t, num, 38f);
			num += 42f;
			Text val = HudWidgets.Label(_content.transform, "sub", 11, Theme.TextMuted, (TextAnchor)1, (FontStyle)1);
			val.text = $"ROUND {st.RoundNumber}   -   {list.Count} PLAYERS";
			FullRow(val, num, 16f);
			num += 26f;
			if (list2.Count > 0)
			{
				float num2 = (660f - 10f * (float)(list2.Count - 1)) / (float)list2.Count;
				for (int num3 = 0; num3 < list2.Count; num3++)
				{
					Award award = list2[num3];
					GameObject val2 = HudWidgets.Pill(_content.transform, "award", Theme.WithAlpha(Theme.WarningSubtle, 0.55f));
					HudWidgets.Outline(val2, Theme.WithAlpha(Theme.Warning, 0.4f));
					TopLeft(val2, (float)num3 * (num2 + 10f), num, num2, 58f);
					Cell(val2.transform, "t", award.Title.ToUpperInvariant(), Theme.WarningText, 11, (TextAnchor)1, (FontStyle)1, 8f, 6f, num2 - 16f, 14f);
					Cell(val2.transform, "n", award.Name, Theme.TextPrimary, 14, (TextAnchor)1, (FontStyle)1, 8f, 22f, num2 - 16f, 20f);
					Cell(val2.transform, "m", award.Metric, Theme.TextMuted, 11, (TextAnchor)1, (FontStyle)0, 8f, 40f, num2 - 16f, 14f);
				}
				num += 72f;
			}
			TopLeft(HudWidgets.Pill(_content.transform, "lb_head", Theme.WithAlpha(Theme.BgElevated, 0.6f)), 0f, num, 660f, 30f);
			HeaderCell("Player", 44f, 220f, (TextAnchor)3, num);
			HeaderCell("Role", 270f, 96f, (TextAnchor)3, num);
			HeaderCell("Catches", 374f, 86f, (TextAnchor)5, num);
			HeaderCell("Survived", 466f, 92f, (TextAnchor)5, num);
			HeaderCell("Score", 564f, 76f, (TextAnchor)5, num);
			num += 34f;
			int num4 = 1;
			foreach (PlayerState item in list)
			{
				bool flag = item.SteamId == localId;
				GameObject go = HudWidgets.Pill(_content.transform, "row", flag ? Theme.AccentSubtle : Theme.WithAlpha(Theme.BgElevated, (num4 % 2 == 0) ? 0.32f : 0.16f));
				if (flag)
				{
					HudWidgets.Outline(go, Theme.WithAlpha(Theme.AccentBorder, 0.7f));
				}
				TopLeft(go, 0f, num, 660f, 28f);
				Color color2 = (flag ? Theme.TextPrimary : Theme.TextPrimary);
				Cell(_content.transform, "rank", num4.ToString(), Theme.TextMuted, 13, (TextAnchor)4, (FontStyle)1, 0f, num, 36f, 30f);
				Cell(_content.transform, "name", NameOf(item) + (flag ? "  (you)" : ""), color2, 13, (TextAnchor)3, (FontStyle)(flag ? 1 : 0), 44f, num, 220f, 30f);
				RoleChip(item, 270f, num);
				Cell(_content.transform, "catch", item.CatchesMade.ToString(), Theme.TextMuted, 13, (TextAnchor)5, (FontStyle)0, 374f, num, 86f, 30f);
				Cell(_content.transform, "surv", item.SurvivedSeconds + "s", Theme.TextMuted, 13, (TextAnchor)5, (FontStyle)0, 466f, num, 92f, 30f);
				Cell(_content.transform, "score", item.SessScore.ToString(), Theme.TextPrimary, 13, (TextAnchor)5, (FontStyle)1, 564f, num, 76f, 30f);
				num += 30f;
				num4++;
			}
			float num5 = num + 26f + 26f;
			_card.GetComponent<RectTransform>().sizeDelta = new Vector2(720f, Mathf.Min(num5, (float)Screen.height - 40f));
		}

		private void Cell(Transform parent, string name, string text, Color color, int size, TextAnchor anchor, FontStyle style, float x, float y, float w, float h)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			Text obj = HudWidgets.Label(parent, name, size, color, anchor, style);
			obj.text = text;
			RectTransform rectTransform = ((Graphic)obj).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(0f, 1f);
			rectTransform.pivot = new Vector2(0f, 1f);
			rectTransform.anchoredPosition = new Vector2(x, 0f - y);
			rectTransform.sizeDelta = new Vector2(w, h);
		}

		private void HeaderCell(string text, float x, float w, TextAnchor anchor, float y)
		{
			//IL_0012: 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)
			Cell(_content.transform, "h", text, Theme.InfoText, 11, anchor, (FontStyle)1, x, y, w, 30f);
		}

		private void RoleChip(PlayerState p, float x, float y)
		{
			//IL_0008: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			string text = RoleShort(p);
			Color val = RoleColor(p);
			GameObject obj = HudWidgets.Pill(_content.transform, "rolechip", Theme.WithAlpha(val, 0.18f));
			RectTransform component = obj.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = new Vector2(x, 0f - (y + 4f));
			component.sizeDelta = new Vector2(88f, 20f);
			Text obj2 = HudWidgets.Label(obj.transform, "txt", 11, val, (TextAnchor)4, (FontStyle)1);
			obj2.text = text;
			HudWidgets.Stretch(((Graphic)obj2).rectTransform, 4f, 0f, 4f, 0f);
		}

		private static void TopLeft(GameObject go, float x, float y, float w, float h)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = go.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.anchoredPosition = new Vector2(x, 0f - y);
			component.sizeDelta = new Vector2(w, h);
		}

		private void FullRow(Text t, float y, float h)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			RectTransform rectTransform = ((Graphic)t).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.pivot = new Vector2(0.5f, 1f);
			rectTransform.offsetMin = new Vector2(0f, 0f);
			rectTransform.offsetMax = new Vector2(0f, 0f);
			rectTransform.anchoredPosition = new Vector2(0f, 0f - y);
			rectTransform.sizeDelta = new Vector2(0f, h);
		}

		private static List<Award> BuildAwards(List<PlayerState> players)
		{
			List<Award> list = new List<Award>();
			AddAward(list, players, "Top Hunter", (PlayerState p) => p.CatchesMade, (int v) => $"{v} catches");
			AddAward(list, players, "Survivor", (PlayerState p) => (p.Role == PlayerRole.Hider) ? p.SurvivedSeconds : 0, (int v) => $"{v}s alive");
			AddAward(list, players, "Trickster", (PlayerState p) => p.DecoyBaits, (int v) => $"{v} decoy baits");
			AddAward(list, players, "Shocker", (PlayerState p) => p.StunsLanded, (int v) => $"{v} stuns");
			return list;
		}

		private static void AddAward(List<Award> list, List<PlayerState> players, string title, Func<PlayerState, int> sel, Func<int, string> fmt)
		{
			PlayerState playerState = null;
			int num = 0;
			foreach (PlayerState player in players)
			{
				int num2 = sel(player);
				if (num2 > num)
				{
					num = num2;
					playerState = player;
				}
			}
			if (playerState != null && num > 0)
			{
				list.Add(new Award
				{
					Title = title,
					Name = NameOf(playerState),
					Metric = fmt(num)
				});
			}
		}

		private static string NameOf(PlayerState p)
		{
			try
			{
				Player val = PlayerRegistry.Get(p.SteamId);
				if ((Object)(object)val != (Object)null)
				{
					string playerName = val.PlayerName;
					if (!string.IsNullOrEmpty(playerName))
					{
						return playerName;
					}
				}
			}
			catch
			{
			}
			return "Player " + p.SteamId % 10000;
		}

		private static string RoleShort(PlayerState p)
		{
			if (p.Role == PlayerRole.Hunter)
			{
				return "Hunter";
			}
			if (p.Role == PlayerRole.Hider)
			{
				if (!p.Eliminated)
				{
					return "Hider";
				}
				return "Caught";
			}
			return "Spectator";
		}

		private static Color RoleColor(PlayerState p)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (p.Role == PlayerRole.Hunter)
			{
				return Theme.DangerText;
			}
			if (p.Role == PlayerRole.Hider)
			{
				if (!p.Eliminated)
				{
					return Theme.SuccessText;
				}
				return Theme.TextMuted;
			}
			return Theme.InfoText;
		}
	}
}
namespace PropHunt.Taunt
{
	internal sealed class TauntController
	{
		private struct StaggerEntry
		{
			public float At;

			public ulong Id;

			public string Sound;
		}

		private readonly GameModeController _ctl;

		private long _nextWhistleUnix;

		private readonly List<StaggerEntry> _staggerQueue = new List<StaggerEntry>();

		internal TauntController(GameModeController ctl)
		{
			_ctl = ctl;
		}

		internal void Tick()
		{
			if (!_ctl.IsHost)
			{
				return;
			}
			float time = Time.time;
			for (int num = _staggerQueue.Count - 1; num >= 0; num--)
			{
				if (!(time < _staggerQueue[num].At))
				{
					StaggerEntry staggerEntry = _staggerQueue[num];
					_staggerQueue.RemoveAt(num);
					if (IsLiveHider(staggerEntry.Id))
					{
						try
						{
							SteamNetworkClient client = PropHuntNet.Client;
							if (client != null)
							{
								client.BroadcastMessage((P2PMessage)(object)new TauntMessage
								{
									SteamId = staggerEntry.Id,
									Sound = staggerEntry.Sound,
									IsWhistle = true
								});
							}
						}
						catch
						{
						}
						_ctl.NotifyTaunt(staggerEntry.Id, staggerEntry.Sound, isWhistle: true);
					}
				}
			}
			if (_ctl.Phase != RoundPhase.Hunting)
			{
				_nextWhistleUnix = 0L;
				_staggerQueue.Clear();
				return;
			}
			int tauntIntervalSeconds = _ctl.Settings.TauntIntervalSeconds;
			if (tauntIntervalSeconds <= 0)
			{
				return;
			}
			long num2 = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
			if (_nextWhistleUnix <= 0)
			{
				_nextWhistleUnix = num2 + tauntIntervalSeconds;
			}
			else
			{
				if (num2 < _nextWhistleUnix)
				{
					return;
				}
				_nextWhistleUnix = num2 + tauntIntervalSeconds;
				float num3 = Mathf.Max(0f, _ctl.Settings.WhistleStaggerSeconds);
				float num4 = 0f;
				int num5 = 0;
				foreach (PlayerState value in _ctl.State.Players.Values)
				{
					if (value.Role == PlayerRole.Hider && !value.Eliminated)
					{
						_staggerQueue.Add(new StaggerEntry
						{
							At = time + num4,
							Id = value.SteamId,
							Sound = TauntSounds.PickDefault()
						});
						num4 += num3;
						num5++;
					}
				}
			}
		}

		private bool IsLiveHider(ulong id)
		{
			if (_ctl.State.Players.TryGetValue(id, out var value) && value.Role == PlayerRole.Hider)
			{
				return !value.Eliminated;
			}
			return false;
		}
	}
	internal static class TauntSounds
	{
		private static Dictionary<string, AudioClip> _cache;

		private static float _cacheBuiltAt = -999f;

		private static List<string> _defaultPool;

		private static string _flushName;

		private const string FlushClip = "foley-toilet-flush-without-tank-refill-238004";

		private const float FlushChance = 0.001f;

		private const float ManualVolumeScale = 0.6f;

		private const float WhistleVolumeScale = 0.45f;

		private static string FavPath => Path.Combine(MelonEnvironment.UserDataDirectory, "PropHunt", "taunt_favorites.txt");

		private static void BuildCache()
		{
			if (_cache != null && Time.time - _cacheBuiltAt < 5f)
			{
				return;
			}
			_cache = new Dictionary<string, AudioClip>(StringComparer.OrdinalIgnoreCase);
			try
			{
				Il2CppArrayBase<AudioClip> val = Resources.FindObjectsOfTypeAll<AudioClip>();
				if (val != null)
				{
					for (int i = 0; i < val.Length; i++)
					{
						AudioClip val2 = val[i];
						if ((Object)(object)val2 != (Object)null && !string.IsNullOrEmpty(((Object)val2).name) && !_cache.ContainsKey(((Object)val2).name))
						{
							_cache[((Object)val2).name] = val2;
						}
					}
				}
			}
			catch (Exception)
			{
			}
			_cacheBuiltAt = Time.time;
		}

		private static AudioClip GetClip(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return null;
			}
			if (_cache == null || !_cache.ContainsKey(name))
			{
				BuildCache();
			}
			if (_cache == null || !_cache.TryGetValue(name, out var value))
			{
				return null;
			}
			return value;
		}

		internal static void Play(string clipName, Vector3 pos)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			PlayInternal(clipName, pos, WhistleVolume: false);
		}

		internal static void PlayWhistle(string clipName, Vector3 pos)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			PlayInternal(clipName, pos, WhistleVolume: true);
		}

		private static void PlayInternal(string clipName, Vector3 pos, bool WhistleVolume)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			AudioClip clip = GetClip(clipName);
			if (!((Object)(object)clip == (Object)null))
			{
				PlayClip(clip, pos, WhistleVolume ? 0.45f : 0.6f);
			}
		}

		internal static void PlayFx(string[] candidates, Vector3 pos, float volumeScale = 0.7f)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			AudioClip val = ResolveAny(candidates);
			if (!((Object)(object)val == (Object)null))
			{
				PlayClip(val, pos, volumeScale);
			}
		}

		private static AudioClip ResolveAny(string[] names)
		{
			if (names == null)
			{
				return null;
			}
			BuildCache();
			if (_cache == null)
			{
				return null;
			}
			string[] array = names;
			foreach (string text in array)
			{
				if (!string.IsNullOrEmpty(text) && _cache.TryGetValue(text, out var value) && (Object)(object)value != (Object)null)
				{
					return value;
				}
			}
			array = names;
			foreach (string value2 in array)
			{
				if (string.IsNullOrEmpty(value2))
				{
					continue;
				}
				foreach (KeyValuePair<string, AudioClip> item in _cache)
				{
					if ((Object)(object)item.Value != (Object)null && item.Key.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return item.Value;
					}
				}
			}
			return null;
		}

		private static void PlayClip(AudioClip clip, Vector3 pos, float volumeScale)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)clip == (Object)null)
			{
				return;
			}
			try
			{
				GameObject val = new GameObject("ph_taunt");
				val.transform.position = pos;
				AudioSource val2 = val.AddComponent<AudioSource>();
				val2.clip = clip;
				val2.spatialBlend = 1f;
				val2.rolloffMode = (AudioRolloffMode)0;
				val2.minDistance = 6f;
				val2.maxDistance = 140f;
				val2.dopplerLevel = 0f;
				float num = 0.7f;
				try
				{
					AudioManager instance = Singleton<AudioManager>.Instance;
					if ((Object)(object)instance != (Object)null)
					{
						val2.outputAudioMixerGroup = instance.MainGameMixer;
						num = instance.GetVolume((EAudioType)2, true);
					}
				}
				catch
				{
				}
				val2.volume = num * volumeScale;
				val2.Play();
				Object.Destroy((Object)(object)val, clip.length + 0.2f);
			}
			catch (Exception)
			{
			}
		}

		private static void BuildDefaults()
		{
			BuildCache();
			_defaultPool = new List<string>();
			_flushName = null;
			if (_cache == null)
			{
				return;
			}
			foreach (KeyValuePair<string, AudioClip> item in _cache)
			{
				string key = item.Key;
				if (key.IndexOf("cork pop", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					_defaultPool.Add(key);
				}
				else if (Regex.IsMatch(key, "^fart\\s*\\d+$", RegexOptions.IgnoreCase))
				{
					_defaultPool.Add(key);
				}
				else if (string.Equals(key, "foley-toilet-flush-without-tank-refill-238004", StringComparison.OrdinalIgnoreCase))
				{
					_flushName = key;
				}
			}
		}

		internal static List<string> DefaultNames()
		{
			if (_defaultPool == null)
			{
				BuildDefaults();
			}
			return new List<string>(_defaultPool ?? new List<string>());
		}

		internal static List<string> WheelOptions()
		{
			List<string> list = ManualFavorites();
			if (list.Count <= 0)
			{
				return DefaultNames();
			}
			return list;
		}

		internal static string PickDefault()
		{
			if (_defaultPool == null || _defaultPool.Count == 0)
			{
				BuildDefaults();
			}
			if (_flushName != null && Random.value < 0.001f)
			{
				return _flushName;
			}
			if (_defaultPool != null && _defaultPool.Count > 0)
			{
				return _defaultPool[Random.Range(0, _defaultPool.Count)];
			}
			return null;
		}

		internal static List<string> ManualFavorites()
		{
			List<string> list = new List<string>();
			try
			{
				if (File.Exists(FavPath))
				{
					string[] array = File.ReadAllLines(FavPath);
					for (int i = 0; i < array.Length; i++)
					{
						string text = array[i].Trim();
						if (text.Length > 0 && !text.StartsWith("#") && !list.Contains(text))
						{
							list.Add(text);
						}
					}
				}
			}
			catch (Exception)
			{
			}
			return list;
		}

		internal static void AddFavorite(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return;
			}
			try
			{
				if (!ManualFavorites().Contains(name))
				{
					Directory.CreateDirectory(Path.GetDirectoryName(FavPath));
					File.AppendAllText(FavPath, name + "\n");
				}
			}
			catch (Exception)
			{
			}
		}
	}
	internal sealed class TauntWheel
	{
		private readonly GameModeController _ctl;

		private List<string> _labels = new List<string>();

		private List<string> _sounds = new List<string>();

		private string _selectedSound;

		private string _selectedLabel = "Default";

		private int _highlight;

		private bool _open;

		private float _downAt = -1f;

		private Vector2 _aim;

		private const float HoldThreshold = 0.22f;

		private const float AimSpeed = 9f;

		private const float MaxAim = 100f;

		private const float DeadZone = 22f;

		internal bool MenuOpen => _open;

		internal TauntWheel(GameModeController ctl)
		{
			_ctl = ctl;
		}

		internal void Tick()
		{
			if ((_ctl.Phase != RoundPhase.Hiding && _ctl.Phase != RoundPhase.Hunting) || _ctl.LocalRole != PlayerRole.Hider)
			{
				if (_open)
				{
					Close(commit: false);
				}
				_downAt = -1f;
				return;
			}
			try
			{
				if (Input.GetKeyDown((KeyCode)49))
				{
					_downAt = Time.time;
				}
				if (!_open && _downAt >= 0f && Input.GetKey((KeyCode)49) && Time.time - _downAt >= 0.22f)
				{
					Open();
				}
				if (_open)
				{
					UpdateAim();
				}
				if (Input.GetKeyUp((KeyCode)49))
				{
					if (_open)
					{
						Close(commit: true);
					}
					else if (_downAt >= 0f)
					{
						_ctl.RequestManualTaunt(_selectedSound);
					}
					_downAt = -1f;
				}
			}
			catch (Exception)
			{
			}
		}

		private void Open()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			_labels = new List<string> { "Default" };
			_sounds = new List<string> { null };
			foreach (string item in TauntSounds.WheelOptions())
			{
				_labels.Add(item);
				_sounds.Add(item);
			}
			_aim = Vector2.zero;
			_highlight = Mathf.Max(0, _sounds.IndexOf(_selectedSound));
			_open = true;
			SetCanLook(can: false);
		}

		private void Close(bool commit)
		{
			if (commit && _highlight >= 0 && _highlight < _sounds.Count)
			{
				_selectedSound = _sounds[_highlight];
				_selectedLabel = _labels[_highlight];
			}
			_open = false;
			SetCanLook(can: true);
		}

		private void UpdateAim()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//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)
			int count = _labels.Count;
			if (count == 0)
			{
				return;
			}
			_aim += new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y")) * 9f;
			_aim = Vector2.ClampMagnitude(_aim, 100f);
			if (!(((Vector2)(ref _aim)).magnitude < 22f))
			{
				float num = Mathf.Atan2(_aim.x, _aim.y) * 57.29578f;
				if (num < 0f)
				{
					num += 360f;
				}
				_highlight = Mathf.Clamp(Mathf.RoundToInt(num / 360f * (float)count) % count, 0, count - 1);
			}
		}

		private static void SetCanLook(bool can)
		{
			try
			{
				PlayerCamera instance = PlayerSingleton<PlayerCamera>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.SetCanLook(can);
				}
			}
			catch
			{
			}
		}

		internal void DrawGui()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0075: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			//IL_020a: 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_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Expected O, but got Unknown
			//IL_0275: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			if (_open && _labels.Count != 0)
			{
				int count = _labels.Count;
				float num = (float)Screen.width * 0.5f;
				float num2 = (float)Screen.height * 0.5f;
				float num3 = Mathf.Max(180f, (float)count * 24f);
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontStyle = (FontStyle)1,
					wordWrap = false
				};
				for (int i = 0; i < count; i++)
				{
					float num4 = (float)i / (float)count * (float)Math.PI * 2f;
					float num5 = num + Mathf.Sin(num4) * num3;
					float num6 = num2 - Mathf.Cos(num4) * num3;
					bool flag = i == _highlight;
					float num7 = (flag ? 140f : 116f);
					float num8 = (flag ? 32f : 26f);
					Color color = GUI.color;
					GUI.color = (flag ? new Color(0.2f, 0.85f, 0.4f, 0.96f) : new Color(0.05f, 0.06f, 0.09f, 0.78f));
					GUI.Box(new Rect(num5 - num7 / 2f, num6 - num8 / 2f, num7, num8), GUIContent.none);
					GUI.color = color;
					val.fontSize = (flag ? 14 : 12);
					val.normal.textColor = (Color)(flag ? Color.black : new Color(0.82f, 0.88f, 1f));
					GUI.Label(new Rect(num5 - num7 / 2f, num6 - num8 / 2f, num7, num8), Short(_labels[i]), val);
				}
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontStyle = (FontStyle)1,
					fontSize = 18
				};
				val2.normal.textColor = new Color(0.3f, 1f, 0.5f);
				GUI.Label(new Rect(num - 220f, num2 - 14f, 440f, 24f), Short(_labels[_highlight]), val2);
				GUIStyle val3 = new GUIStyle(val2)
				{
					fontSize = 12
				};
				val3.normal.textColor = new Color(0.6f, 0.85f, 1f);
				GUI.Label(new Rect(num - 220f, num2 + 12f, 440f, 18f), "move mouse - release [1] to set", val3);
			}
		}

		private static string Short(string s)
		{
			if (!string.IsNullOrEmpty(s))
			{
				if (s.Length <= 22)
				{
					return s;
				}
				return s.Substring(0, 22);
			}
			return "?";
		}

		internal void Dispose()
		{
			if (_open)
			{
				Close(commit: false);
			}
		}
	}
}
namespace PropHunt.Quests
{
	internal static class GuideQuest
	{
		internal const string Title = "PropHunt";

		private static PropHuntGuideQuest _quest;

		private static readonly Dictionary<string, QuestEntry> _active = new Dictionary<string, QuestEntry>();

		private static readonly Dictionary<string, string> _titles = new Dictionary<string, string>();

		private static readonly List<string> _toRemove = new List<string>();

		private static bool _appOpened;

		internal static void Tick()
		{
			GameModeController active = GameModeController.Active;
			if (active == null || !QuestUiReady())
			{
				return;
			}
			Dictionary<string, string> dictionary = Desired(active);
			if (_quest == null)
			{
				if (dictionary.Count == 0)
				{
					return;
				}
				try
				{
					_quest = QuestManager.CreateQuest<PropHuntGuideQuest>((string)null) as PropHuntGuideQuest;
				}
				catch (Exception ex)
				{
					Core.Log.Warning("[PropHunt] guide quest create failed: " + ex.Message);
					return;
				}
				if (_quest == null)
				{
					return;
				}
			}
			_toRemove.Clear();
			foreach (KeyValuePair<string, QuestEntry> item in _active)
			{
				if (!dictionary.ContainsKey(item.Key))
				{
					_toRemove.Add(item.Key);
				}
			}
			foreach (string item2 in _toRemove)
			{
				QuestEntry val = _active[item2];
				bool flag = Resolve(item2, active);
				try
				{
					string text = ResolveTitle(item2, flag);
					if (text != null)
					{
						val.Title = text;
					}
					if (flag)
					{
						val.Complete();
					}
					else
					{
						val.SetState((QuestState)3);
					}
				}
				catch
				{
				}
				_active.Remove(item2);
				_titles.Remove(item2);
			}
			foreach (KeyValuePair<string, string> item3 in dictionary)
			{
				string value;
				if (!_active.ContainsKey(item3.Key))
				{
					try
					{
						_active[item3.Key] = _quest.AddObjective(item3.Value);
						_titles[item3.Key] = item3.Value;
					}
					catch (Exception ex2)
					{
						Core.Log.Warning("[PropHunt] guide quest add failed: " + ex2.Message);
					}
				}
				else if (_titles.TryGetValue(item3.Key, out value) &&