Decompiled source of PropHunt v2.0.1

PropHunt.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Empress")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.9.0.0")]
[assembly: AssemblyInformationalVersion("1.9.0")]
[assembly: AssemblyProduct("PropHunt")]
[assembly: AssemblyTitle("PropHunt")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.9.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Empress.REPO.PropHunt
{
	internal static class GameAccess
	{
		private static readonly FieldInfo GameDirectorPlayerList = AccessTools.Field(typeof(GameDirector), "PlayerList");

		private static readonly FieldInfo GameDirectorCurrentState = AccessTools.Field(typeof(GameDirector), "currentState");

		private static readonly FieldInfo PlayerAvatarHealth = AccessTools.Field(typeof(PlayerAvatar), "playerHealth");

		private static readonly FieldInfo PlayerHealthValue = AccessTools.Field(typeof(PlayerHealth), "health");

		private static readonly FieldInfo PlayerAvatarPhysGrabber = AccessTools.Field(typeof(PlayerAvatar), "physGrabber");

		private static readonly FieldInfo PlayerAvatarIsCrouching = AccessTools.Field(typeof(PlayerAvatar), "isCrouching");

		private static readonly FieldInfo PhysGrabObjectLastPlayerGrabbing = AccessTools.Field(typeof(PhysGrabObject), "lastPlayerGrabbing");

		private static readonly FieldInfo PhysGrabberPlayerAvatar = AccessTools.Field(typeof(PhysGrabber), "playerAvatar");

		private static readonly FieldInfo ItemGunPhysGrabObject = AccessTools.Field(typeof(ItemGun), "physGrabObject");

		private static readonly FieldInfo ItemGunItemBattery = AccessTools.Field(typeof(ItemGun), "itemBattery");

		private static readonly FieldInfo ItemGunGunMuzzle = AccessTools.Field(typeof(ItemGun), "gunMuzzle");

		private static readonly FieldInfo ItemGunGunRange = AccessTools.Field(typeof(ItemGun), "gunRange");

		private static readonly FieldInfo ItemBatteryLife = AccessTools.Field(typeof(ItemBattery), "batteryLife");

		private static readonly FieldInfo ItemBatteryLifePrev = AccessTools.Field(typeof(ItemBattery), "batteryLifePrev");

		private static readonly FieldInfo ItemBatteryLifeInt = AccessTools.Field(typeof(ItemBattery), "batteryLifeInt");

		private static readonly FieldInfo ItemBatteryBars = AccessTools.Field(typeof(ItemBattery), "batteryBars");

		private static readonly FieldInfo ItemEquippableOwnerPlayerId = AccessTools.Field(typeof(ItemEquippable), "ownerPlayerId");

		private static readonly MethodInfo ItemEquippableGetOwnerPlayerAvatar = AccessTools.Method(typeof(ItemEquippable), "GetOwnerPlayerAvatar", (Type[])null, (Type[])null);

		private static readonly FieldInfo StatsItemDictionary = AccessTools.Field(typeof(StatsManager), "itemDictionary");

		private static readonly FieldInfo ItemPrefab = AccessTools.Field(typeof(Item), "prefab");

		private static readonly FieldInfo ItemDisabled = AccessTools.Field(typeof(Item), "disabled");

		private static readonly FieldInfo ItemName = AccessTools.Field(typeof(Item), "itemName");

		private static readonly MethodInfo InventoryGetFirstFreeSpot = AccessTools.Method(typeof(Inventory), "GetFirstFreeInventorySpotIndex", (Type[])null, (Type[])null);

		private static readonly MethodInfo ItemEquippableRequestEquip = AccessTools.Method(typeof(ItemEquippable), "RequestEquip", new Type[2]
		{
			typeof(int),
			typeof(int)
		}, (Type[])null);

		private static readonly MethodInfo BatteryFullPercentChange = AccessTools.Method(typeof(ItemBattery), "BatteryFullPercentChange", new Type[2]
		{
			typeof(int),
			typeof(bool)
		}, (Type[])null);

		private static readonly PropertyInfo PrefabRefPrefab = AccessTools.Property(typeof(PrefabRef), "Prefab");

		private static readonly PropertyInfo PrefabRefResourcePath = AccessTools.Property(typeof(PrefabRef), "ResourcePath");

		private static readonly FieldInfo ValuableDirectorValuableDebug = AccessTools.Field(typeof(ValuableDirector), "valuableDebug");

		private static readonly FieldInfo LevelGeneratorEnemiesSpawnTarget = AccessTools.Field(typeof(LevelGenerator), "EnemiesSpawnTarget");

		private static readonly FieldInfo LevelGeneratorEnemiesSpawned = AccessTools.Field(typeof(LevelGenerator), "EnemiesSpawned");

		private static readonly FieldInfo LevelGeneratorEnemyReady = AccessTools.Field(typeof(LevelGenerator), "EnemyReady");

		private static readonly FieldInfo RunManagerPreviousRunLevel = AccessTools.Field(typeof(RunManager), "previousRunLevel");

		private static readonly MethodInfo RunManagerChangeLevel = AccessTools.Method(typeof(RunManager), "ChangeLevel", new Type[3]
		{
			typeof(bool),
			typeof(bool),
			typeof(ChangeLevelType)
		}, (Type[])null);

		private static readonly FieldInfo PlayerControllerRigidbody = AccessTools.Field(typeof(PlayerController), "rb");

		private static readonly FieldInfo PlayerAvatarRigidbody = AccessTools.Field(typeof(PlayerAvatar), "rb");

		private static readonly FieldInfo PlayerAvatarClientPosition = AccessTools.Field(typeof(PlayerAvatar), "clientPosition");

		private static readonly FieldInfo PlayerAvatarClientPositionCurrent = AccessTools.Field(typeof(PlayerAvatar), "clientPositionCurrent");

		private static readonly FieldInfo PlayerAvatarRbVelocity = AccessTools.Field(typeof(PlayerAvatar), "rbVelocity");

		private static readonly FieldInfo PlayerAvatarRbVelocityRaw = AccessTools.Field(typeof(PlayerAvatar), "rbVelocityRaw");

		private static readonly Type ValuableDebugType = AccessTools.Inner(typeof(ValuableDirector), "ValuableDebug");

		internal static List<PlayerAvatar> PlayerList()
		{
			if (!((Object)(object)GameDirector.instance == (Object)null))
			{
				return GameDirectorPlayerList?.GetValue(GameDirector.instance) as List<PlayerAvatar>;
			}
			return null;
		}

		internal static bool IsMainState()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			if ((Object)(object)GameDirector.instance == (Object)null || GameDirectorCurrentState == null)
			{
				return false;
			}
			return (int)(gameState)GameDirectorCurrentState.GetValue(GameDirector.instance) == 2;
		}

		internal static PlayerHealth Health(PlayerAvatar avatar)
		{
			if (!((Object)(object)avatar == (Object)null))
			{
				object? obj = PlayerAvatarHealth?.GetValue(avatar);
				return (PlayerHealth)((obj is PlayerHealth) ? obj : null);
			}
			return null;
		}

		internal static int HealthValue(PlayerHealth health)
		{
			if ((Object)(object)health == (Object)null || PlayerHealthValue == null)
			{
				return 0;
			}
			try
			{
				return (int)PlayerHealthValue.GetValue(health);
			}
			catch
			{
				return 0;
			}
		}

		internal static PhysGrabber AvatarGrabber(PlayerAvatar avatar)
		{
			if (!((Object)(object)avatar == (Object)null))
			{
				object? obj = PlayerAvatarPhysGrabber?.GetValue(avatar);
				return (PhysGrabber)((obj is PhysGrabber) ? obj : null);
			}
			return null;
		}

		internal static bool GetIsCrouching(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar == (Object)null || PlayerAvatarIsCrouching == null)
			{
				return false;
			}
			return (bool)PlayerAvatarIsCrouching.GetValue(avatar);
		}

		internal static void SetIsCrouching(PlayerAvatar avatar, bool value)
		{
			if ((Object)(object)avatar != (Object)null)
			{
				PlayerAvatarIsCrouching?.SetValue(avatar, value);
			}
		}

		internal static PhysGrabObject GunPhysGrabObject(ItemGun gun)
		{
			if (!((Object)(object)gun == (Object)null))
			{
				object? obj = ItemGunPhysGrabObject?.GetValue(gun);
				return (PhysGrabObject)((obj is PhysGrabObject) ? obj : null);
			}
			return null;
		}

		internal static ItemBattery GunBattery(ItemGun gun)
		{
			object obj2;
			if (!((Object)(object)gun == (Object)null))
			{
				object? obj = ItemGunItemBattery?.GetValue(gun);
				obj2 = ((obj is ItemBattery) ? obj : null);
				if (obj2 == null)
				{
					if (gun == null)
					{
						return null;
					}
					return ((Component)gun).GetComponent<ItemBattery>();
				}
			}
			else
			{
				obj2 = null;
			}
			return (ItemBattery)obj2;
		}

		internal static Transform GunMuzzle(ItemGun gun)
		{
			if (!((Object)(object)gun == (Object)null))
			{
				object? obj = ItemGunGunMuzzle?.GetValue(gun);
				return (Transform)((obj is Transform) ? obj : null);
			}
			return null;
		}

		internal static float GunRange(ItemGun gun, float fallback)
		{
			if ((Object)(object)gun == (Object)null || ItemGunGunRange == null)
			{
				return fallback;
			}
			return Mathf.Max(1f, Convert.ToSingle(ItemGunGunRange.GetValue(gun)));
		}

		internal static PlayerAvatar GunOwner(ItemGun gun)
		{
			if ((Object)(object)gun == (Object)null)
			{
				return null;
			}
			ItemEquippable component = ((Component)gun).GetComponent<ItemEquippable>();
			if ((Object)(object)component != (Object)null)
			{
				try
				{
					object? obj = ItemEquippableGetOwnerPlayerAvatar?.Invoke(component, null);
					PlayerAvatar val = (PlayerAvatar)((obj is PlayerAvatar) ? obj : null);
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
				catch
				{
				}
				try
				{
					int num = ((ItemEquippableOwnerPlayerId == null) ? (-1) : ((int)ItemEquippableOwnerPlayerId.GetValue(component)));
					if (num != -1)
					{
						PhotonView val2 = PhotonView.Find(num);
						PlayerAvatar val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<PlayerAvatar>() : null);
						if ((Object)(object)val3 != (Object)null)
						{
							return val3;
						}
					}
				}
				catch
				{
				}
			}
			PhysGrabObject val4 = GunPhysGrabObject(gun);
			PhysGrabber val5 = (PhysGrabber)(((Object)(object)val4 == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/);
			if (!((Object)(object)val5 == (Object)null))
			{
				object? obj4 = PhysGrabberPlayerAvatar?.GetValue(val5);
				return (PlayerAvatar)((obj4 is PlayerAvatar) ? obj4 : null);
			}
			return null;
		}

		internal static void RefillBattery(ItemGun gun)
		{
			ItemBattery val = GunBattery(gun);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			int num = 6;
			if (ItemBatteryBars != null)
			{
				try
				{
					num = Mathf.Max(1, (int)ItemBatteryBars.GetValue(val));
				}
				catch
				{
				}
			}
			ItemBatteryLife?.SetValue(val, 100f);
			ItemBatteryLifePrev?.SetValue(val, 100f);
			ItemBatteryLifeInt?.SetValue(val, num);
			try
			{
				BatteryFullPercentChange?.Invoke(val, new object[2] { num, false });
			}
			catch
			{
			}
		}

		internal static bool IsItemDisabled(Item item)
		{
			if ((Object)(object)item == (Object)null || ItemDisabled == null)
			{
				return true;
			}
			return (bool)ItemDisabled.GetValue(item);
		}

		internal static string ItemDisplayName(Item item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return "";
			}
			return (ItemName?.GetValue(item) as string) ?? ((Object)item).name ?? "";
		}

		internal static Dictionary<string, Item> ItemDictionary()
		{
			if (!((Object)(object)StatsManager.instance == (Object)null))
			{
				return StatsItemDictionary?.GetValue(StatsManager.instance) as Dictionary<string, Item>;
			}
			return null;
		}

		internal static PrefabRef ItemPrefabRef(Item item)
		{
			if (!((Object)(object)item == (Object)null))
			{
				object? obj = ItemPrefab?.GetValue(item);
				return (PrefabRef)((obj is PrefabRef) ? obj : null);
			}
			return null;
		}

		internal static GameObject LoadPrefab(PrefabRef prefabRef)
		{
			if (prefabRef == null || PrefabRefPrefab == null)
			{
				return null;
			}
			try
			{
				object? value = PrefabRefPrefab.GetValue(prefabRef, null);
				return (GameObject)((value is GameObject) ? value : null);
			}
			catch
			{
				return null;
			}
		}

		internal static string ResourcePath(PrefabRef prefabRef)
		{
			if (prefabRef == null || PrefabRefResourcePath == null)
			{
				return "";
			}
			try
			{
				return (PrefabRefResourcePath.GetValue(prefabRef, null) as string) ?? "";
			}
			catch
			{
				return "";
			}
		}

		internal static int FirstFreeInventorySpot()
		{
			if ((Object)(object)Inventory.instance == (Object)null || InventoryGetFirstFreeSpot == null)
			{
				return -1;
			}
			try
			{
				return (int)InventoryGetFirstFreeSpot.Invoke(Inventory.instance, null);
			}
			catch
			{
				return -1;
			}
		}

		internal static void RequestEquip(ItemEquippable equippable, int spot, int physGrabberViewId)
		{
			if ((Object)(object)equippable == (Object)null || ItemEquippableRequestEquip == null)
			{
				return;
			}
			try
			{
				ItemEquippableRequestEquip.Invoke(equippable, new object[2] { spot, physGrabberViewId });
			}
			catch
			{
			}
		}

		internal static void SetValuableDebugAll(ValuableDirector director)
		{
			if ((Object)(object)director == (Object)null || ValuableDirectorValuableDebug == null || ValuableDebugType == null)
			{
				return;
			}
			try
			{
				ValuableDirectorValuableDebug.SetValue(director, Enum.ToObject(ValuableDebugType, 1));
			}
			catch
			{
			}
		}

		internal static void SetEnemyGenerationSkipped(LevelGenerator levelGenerator)
		{
			if ((Object)(object)levelGenerator == (Object)null)
			{
				return;
			}
			try
			{
				LevelGeneratorEnemiesSpawnTarget?.SetValue(levelGenerator, 0);
			}
			catch
			{
			}
			try
			{
				LevelGeneratorEnemiesSpawned?.SetValue(levelGenerator, 0);
			}
			catch
			{
			}
			try
			{
				LevelGeneratorEnemyReady?.SetValue(levelGenerator, true);
			}
			catch
			{
			}
		}

		internal static void ChangeToRandomRunLevel()
		{
			RunManager instance = RunManager.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			try
			{
				RunManagerPreviousRunLevel?.SetValue(instance, instance.levelCurrent);
			}
			catch
			{
			}
			try
			{
				RunManagerChangeLevel?.Invoke(instance, new object[3]
				{
					false,
					false,
					(object)(ChangeLevelType)1
				});
			}
			catch
			{
				try
				{
					instance.ChangeLevel(false, false, (ChangeLevelType)1);
				}
				catch
				{
				}
			}
		}

		internal static void FreezeLocalPlayerPosition(PlayerAvatar avatar, Vector3 avatarPosition, Vector3 controllerPosition)
		{
			//IL_0015: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			PlayerController instance = PlayerController.instance;
			if ((Object)(object)instance != (Object)null)
			{
				((Component)instance).transform.position = controllerPosition;
				object? obj = PlayerControllerRigidbody?.GetValue(instance);
				Rigidbody val = (Rigidbody)((obj is Rigidbody) ? obj : null);
				if ((Object)(object)val != (Object)null)
				{
					val.position = controllerPosition;
					val.velocity = Vector3.zero;
					val.angularVelocity = Vector3.zero;
				}
			}
			if ((Object)(object)avatar != (Object)null)
			{
				((Component)avatar).transform.position = avatarPosition;
				PlayerAvatarClientPosition?.SetValue(avatar, avatarPosition);
				PlayerAvatarClientPositionCurrent?.SetValue(avatar, avatarPosition);
				PlayerAvatarRbVelocity?.SetValue(avatar, Vector3.zero);
				PlayerAvatarRbVelocityRaw?.SetValue(avatar, Vector3.zero);
				object? obj2 = PlayerAvatarRigidbody?.GetValue(avatar);
				Rigidbody val2 = (Rigidbody)((obj2 is Rigidbody) ? obj2 : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.position = avatarPosition;
					val2.velocity = Vector3.zero;
					val2.angularVelocity = Vector3.zero;
				}
			}
		}
	}
	[HarmonyPatch(typeof(WorldSpaceUIPlayerName), "Update")]
	internal static class EmpressPropHuntHidePlayerNamesPatch
	{
		private static bool Prefix(WorldSpaceUIPlayerName __instance)
		{
			//IL_001d: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)null && (Object)(object)__instance.text != (Object)null)
			{
				Color color = ((Graphic)__instance.text).color;
				((Graphic)__instance.text).color = new Color(color.r, color.g, color.b, 0f);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemGun), "Shoot")]
	internal static class EmpressPropHuntItemGunShootPatch
	{
		private static void Prefix(ItemGun __instance)
		{
			if (IsHunterGun(__instance))
			{
				GameAccess.RefillBattery(__instance);
			}
		}

		private static void Postfix(ItemGun __instance)
		{
			if (IsHunterGun(__instance))
			{
				GameAccess.RefillBattery(__instance);
			}
		}

		internal static bool IsHunterGun(ItemGun gun)
		{
			PropHuntManager instance = PropHuntManager.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)gun == (Object)null)
			{
				return false;
			}
			PlayerAvatar avatar = GameAccess.GunOwner(gun);
			return instance.IsActorHunter(instance.ActorNumber(avatar));
		}
	}
	[HarmonyPatch(typeof(ItemGun), "ShootRPC")]
	internal static class EmpressPropHuntItemGunShootRpcPatch
	{
		private static void Postfix(ItemGun __instance)
		{
			PropHuntManager instance = PropHuntManager.Instance;
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)__instance == (Object)null))
			{
				if (EmpressPropHuntItemGunShootPatch.IsHunterGun(__instance))
				{
					GameAccess.RefillBattery(__instance);
				}
				if (instance.TryApplyHunterShotCost(__instance))
				{
					instance.TryResolveHunterGunHit(__instance);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemBattery), "RemoveFullBar")]
	internal static class EmpressPropHuntBatteryRemoveFullBarPatch
	{
		private static bool Prefix(ItemBattery __instance)
		{
			ItemGun gun = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponent<ItemGun>() : null);
			if (!EmpressPropHuntItemGunShootPatch.IsHunterGun(gun))
			{
				return true;
			}
			GameAccess.RefillBattery(gun);
			return false;
		}
	}
	public sealed class HunterWeaponController : MonoBehaviour
	{
		public PropHuntManager Manager;

		private float _nextTick;

		public void Tick(PlayerAvatar avatar)
		{
			if (!((Object)(object)Manager == (Object)null) && !((Object)(object)avatar == (Object)null) && PhotonNetwork.InRoom && Manager.IsMainState && !(Time.time < _nextTick))
			{
				_nextTick = Time.time + 0.75f;
				Manager.EnsureHunterWeaponForLocalHunter(avatar);
			}
		}
	}
	public class PropHuntManager : MonoBehaviourPunCallbacks, IOnEventCallback
	{
		private int _hunterWeaponViewId = -1;

		private float _nextHunterWeaponSpawnAttempt;

		private float _nextHunterWeaponRequest;

		private float _nextHunterWeaponEquip;

		private Item _cachedGunItem;

		private const string ROOM_KEY_ACTIVE = "PH_Active";

		private const string ROOM_KEY_HUNTER = "PH_Hunter";

		private const string PLAYER_KEY_PROP = "PH_PropVID";

		private const string PLAYER_KEY_LOCKED = "PH_Locked";

		private const byte EVT_KILL = 101;

		private const byte EVT_PLAYERDOWN = 102;

		private const byte EVT_MATCHEND = 103;

		private const byte EVT_HUNTER_GUN_REQUEST = 105;

		private const byte EVT_HUNTER_GUN_SYNC = 106;

		private const string EVT_TAG = "PH1";

		public KeyCode KeyHiderToggle = (KeyCode)118;

		public KeyCode KeyDisguiseViewToggle = (KeyCode)99;

		public KeyCode KeyPositionLock = (KeyCode)120;

		public float HunterLockSeconds = 30f;

		public float PreHideSeconds = 30f;

		public float RoundSeconds = 300f;

		public float GunRangeMeters = 60f;

		private double _roundEndRealtime;

		private bool _roundArmed;

		private bool _hudShown;

		private PHRole _localRole;

		private int _hunterActor = -1;

		private HunterWeaponController _gun;

		private readonly HashSet<int> _deadActors = new HashSet<int>();

		private bool _ending;

		private float _endUntil;

		private string _endMsg = "";

		private PHWinner _whoWon;

		private float _hunterLockUntil;

		internal const float TINY_FACTOR = 0.0001f;

		private int _cachedPropPhotonViewId;

		private float _preHideUntil;

		private bool _preHideArmed;

		private bool _positionLocked;

		private Vector3 _positionLockAvatar;

		private Vector3 _positionLockController;

		private string _flashMsg = "";

		private float _flashMsgUntil;

		public static PropHuntManager Instance { get; private set; }

		public bool IsHunterLocked
		{
			get
			{
				if (_localRole == PHRole.Hunter)
				{
					return Time.time < _hunterLockUntil;
				}
				return false;
			}
		}

		private bool PreHideActive
		{
			get
			{
				if (_preHideArmed)
				{
					return Time.time < _preHideUntil;
				}
				return false;
			}
		}

		public bool IsMainState => GameAccess.IsMainState();

		public bool PreHidePhaseActive => PreHideActive;

		public bool RoundIsLive
		{
			get
			{
				if (_roundArmed)
				{
					return (double)Time.time < _roundEndRealtime;
				}
				return false;
			}
		}

		internal bool IsActorHunter(int actorNumber)
		{
			if (actorNumber > 0)
			{
				return actorNumber == _hunterActor;
			}
			return false;
		}

		internal bool IsActorDisguised(int actorNumber)
		{
			if (actorNumber <= 0 || _deadActors.Contains(actorNumber))
			{
				return false;
			}
			Room currentRoom = PhotonNetwork.CurrentRoom;
			Player val = ((currentRoom != null) ? currentRoom.GetPlayer(actorNumber, false) : null);
			if (val == null || !((Dictionary<object, object>)(object)val.CustomProperties).ContainsKey((object)"PH_PropVID"))
			{
				return false;
			}
			if (TryToInt(val.CustomProperties[(object)"PH_PropVID"], out var val2))
			{
				return val2 > 0;
			}
			return false;
		}

		internal int ActorNumber(PlayerAvatar avatar)
		{
			int? obj;
			if (avatar == null)
			{
				obj = null;
			}
			else
			{
				PhotonView photonView = avatar.photonView;
				if (photonView == null)
				{
					obj = null;
				}
				else
				{
					Player owner = photonView.Owner;
					obj = ((owner != null) ? new int?(owner.ActorNumber) : null);
				}
			}
			int? num = obj;
			return num.GetValueOrDefault(-1);
		}

		internal void EnsureHunterWeaponForLocalHunter(PlayerAvatar avatar)
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			if (_localRole != PHRole.Hunter || (Object)(object)avatar == (Object)null || (!PreHidePhaseActive && !RoundIsLive))
			{
				return;
			}
			if (TryFindOwnedHunterGun(avatar, out var gun))
			{
				GameAccess.RefillBattery(gun);
				return;
			}
			TryEquipSyncedHunterWeapon(avatar);
			if (TryFindOwnedHunterGun(avatar, out gun))
			{
				GameAccess.RefillBattery(gun);
			}
			else if (PhotonNetwork.IsMasterClient)
			{
				TrySpawnHunterWeapon(avatar);
			}
			else if (Time.time >= _nextHunterWeaponRequest)
			{
				_nextHunterWeaponRequest = Time.time + 2f;
				object[] array = new object[2]
				{
					"PH1",
					PhotonNetwork.LocalPlayer.ActorNumber
				};
				PhotonNetwork.RaiseEvent((byte)105, (object)array, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)2
				}, SendOptions.SendReliable);
			}
		}

		internal bool HandleHunterWeaponEvent(EventData e)
		{
			if (e.Code != 105 && e.Code != 106)
			{
				return false;
			}
			if (!(e.CustomData is object[] array) || array.Length < 2)
			{
				return true;
			}
			if (!(array[0] is string text) || text != "PH1")
			{
				return true;
			}
			if (e.Code == 105)
			{
				if (!PhotonNetwork.IsMasterClient)
				{
					return true;
				}
				if (!TryToInt(array[1], out var val) || val != _hunterActor)
				{
					return true;
				}
				PlayerAvatar val2 = FindAvatarByActor(val);
				if ((Object)(object)val2 != (Object)null)
				{
					TrySpawnHunterWeapon(val2);
				}
				return true;
			}
			if (TryToInt(array[1], out var val3))
			{
				_hunterWeaponViewId = val3;
			}
			return true;
		}

		internal bool TryResolveHunterGunHit(ItemGun gun)
		{
			//IL_0064: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)gun == (Object)null || !PhotonNetwork.InRoom)
			{
				return false;
			}
			if (!RoundIsLive || IsHunterLocked)
			{
				return false;
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			PlayerAvatar avatar = GameAccess.GunOwner(gun);
			int num = ActorNumber(avatar);
			if (!IsActorHunter(num))
			{
				return false;
			}
			Transform val = GameAccess.GunMuzzle(gun);
			Transform val2 = (((Object)(object)val != (Object)null) ? val : ((Component)gun).transform);
			Ray ray = default(Ray);
			((Ray)(ref ray))..ctor(val2.position, val2.forward);
			float num2 = Mathf.Max(GunRangeMeters, GameAccess.GunRange(gun, GunRangeMeters));
			int num3 = -1;
			float maxDistance = num2;
			List<PlayerAvatar> list = GameAccess.PlayerList();
			if (list == null)
			{
				return false;
			}
			foreach (PlayerAvatar item in list)
			{
				int num4 = ActorNumber(item);
				if (num4 > 0 && num4 != num && IsActorDisguised(num4))
				{
					PropDisguiseController component = ((Component)item).GetComponent<PropDisguiseController>();
					if (!((Object)(object)component == (Object)null) && component.TryRaycastDisguise(ray, maxDistance, out var distance) && !ShotBlocked(ray, distance, item))
					{
						maxDistance = distance;
						num3 = num4;
					}
				}
			}
			if (num3 <= 0)
			{
				return false;
			}
			RequestEliminateFromActor(num, num3);
			return true;
		}

		internal bool TryApplyHunterShotCost(ItemGun gun)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)gun == (Object)null || !PhotonNetwork.InRoom)
			{
				return false;
			}
			if (!RoundIsLive || IsHunterLocked)
			{
				return false;
			}
			if (!PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			PlayerAvatar val = GameAccess.GunOwner(gun);
			int actorNumber = ActorNumber(val);
			if (!IsActorHunter(actorNumber))
			{
				return false;
			}
			PlayerHealth val2 = GameAccess.Health(val);
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			try
			{
				int num = GameAccess.HealthValue(val2);
				val2.HurtOther(5, ((Component)val).transform.position, false, -1, false);
				return num > 5;
			}
			catch
			{
				return false;
			}
		}

		private void RequestEliminateFromActor(int shooterActor, int targetActor)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			object[] array = new object[3] { "PH1", shooterActor, targetActor };
			PhotonNetwork.RaiseEvent((byte)101, (object)array, new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)1
			}, SendOptions.SendReliable);
		}

		private bool ShotBlocked(Ray ray, float targetDistance, PlayerAvatar targetAvatar)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				int num = LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct());
				RaycastHit val = default(RaycastHit);
				if (!Physics.Raycast(ray, ref val, Mathf.Max(0.01f, targetDistance - 0.04f), num, (QueryTriggerInteraction)1))
				{
					return false;
				}
				PlayerAvatar val2 = (((Object)(object)((RaycastHit)(ref val)).collider != (Object)null) ? ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<PlayerAvatar>() : null);
				return (Object)(object)val2 == (Object)null || (Object)(object)val2 != (Object)(object)targetAvatar;
			}
			catch
			{
				return false;
			}
		}

		private bool TryFindOwnedHunterGun(PlayerAvatar avatar, out ItemGun gun)
		{
			gun = null;
			ItemGun[] array = Object.FindObjectsOfType<ItemGun>();
			foreach (ItemGun val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)GameAccess.GunOwner(val) != (Object)(object)avatar))
				{
					gun = val;
					return true;
				}
			}
			return false;
		}

		private void TryEquipSyncedHunterWeapon(PlayerAvatar avatar)
		{
			if (Time.time < _nextHunterWeaponEquip || _hunterWeaponViewId <= 0)
			{
				return;
			}
			_nextHunterWeaponEquip = Time.time + 1f;
			PhotonView val = PhotonView.Find(_hunterWeaponViewId);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ItemGun component = ((Component)val).GetComponent<ItemGun>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			GameAccess.RefillBattery(component);
			PhysGrabObject val2 = GameAccess.GunPhysGrabObject(component);
			PhysGrabber val3 = GameAccess.AvatarGrabber(avatar) ?? PhysGrabber.instance;
			if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null)
			{
				try
				{
					val3.OverrideGrab(val2, 0.2f, false);
					val3.OverrideGrabDistance(0.8f);
				}
				catch
				{
				}
			}
			ItemEquippable component2 = ((Component)component).GetComponent<ItemEquippable>();
			if (!((Object)(object)component2 == (Object)null) && !((Object)(object)val3 == (Object)null) && !((Object)(object)val3.photonView == (Object)null))
			{
				int num = GameAccess.FirstFreeInventorySpot();
				if (num >= 0)
				{
					GameAccess.RequestEquip(component2, num, val3.photonView.ViewID);
				}
			}
		}

		private bool TrySpawnHunterWeapon(PlayerAvatar avatar)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			if ((Object)(object)avatar == (Object)null || Time.time < _nextHunterWeaponSpawnAttempt)
			{
				return false;
			}
			_nextHunterWeaponSpawnAttempt = Time.time + 1.5f;
			if (_hunterWeaponViewId > 0 && (Object)(object)PhotonView.Find(_hunterWeaponViewId) != (Object)null)
			{
				return true;
			}
			if (!TryFindHunterGunItem(out var _, out var resourcePath))
			{
				return false;
			}
			Vector3 val = ((Component)avatar).transform.position + ((Component)avatar).transform.forward * 0.75f + Vector3.up * 1.05f;
			Quaternion val2 = Quaternion.LookRotation(((Component)avatar).transform.forward, Vector3.up);
			GameObject val3 = null;
			try
			{
				val3 = PhotonNetwork.InstantiateRoomObject(resourcePath, val, val2, (byte)0, (object[])null);
			}
			catch (Exception ex)
			{
				LogGate.WarnThrottled(PropHuntPlugin.Log, "[Empress Prop Hunt] Hunter handgun spawn failed: " + ex.Message);
				return false;
			}
			PhotonView val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<PhotonView>() : null);
			if ((Object)(object)val4 == (Object)null)
			{
				return false;
			}
			_hunterWeaponViewId = val4.ViewID;
			ItemGun component = val3.GetComponent<ItemGun>();
			if ((Object)(object)component != (Object)null)
			{
				GameAccess.RefillBattery(component);
			}
			object[] array = new object[2] { "PH1", _hunterWeaponViewId };
			PhotonNetwork.RaiseEvent((byte)106, (object)array, new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)1
			}, SendOptions.SendReliable);
			PropHuntPlugin.Log.LogInfo((object)"[Empress Prop Hunt] Hunter handgun spawned.");
			return true;
		}

		private bool TryFindHunterGunItem(out Item item, out string resourcePath)
		{
			item = null;
			resourcePath = "";
			if ((Object)(object)_cachedGunItem != (Object)null)
			{
				PrefabRef prefabRef = GameAccess.ItemPrefabRef(_cachedGunItem);
				resourcePath = GameAccess.ResourcePath(prefabRef);
				item = _cachedGunItem;
				if (!string.IsNullOrEmpty(resourcePath))
				{
					return true;
				}
			}
			Dictionary<string, Item> dictionary = GameAccess.ItemDictionary();
			if (dictionary == null || dictionary.Count == 0)
			{
				return false;
			}
			int num = int.MinValue;
			foreach (KeyValuePair<string, Item> item2 in dictionary)
			{
				Item value = item2.Value;
				if ((Object)(object)value == (Object)null || GameAccess.IsItemDisabled(value))
				{
					continue;
				}
				PrefabRef prefabRef2 = GameAccess.ItemPrefabRef(value);
				GameObject val = GameAccess.LoadPrefab(prefabRef2);
				if ((Object)(object)val == (Object)null || (Object)(object)val.GetComponentInChildren<ItemGun>(true) == (Object)null)
				{
					continue;
				}
				string text = (item2.Key + " " + GameAccess.ItemDisplayName(value) + " " + ((Object)val).name).ToLowerInvariant();
				int num2 = 0;
				if (text.Contains("handgun"))
				{
					num2 += 200;
				}
				if (text.Contains("pistol"))
				{
					num2 += 180;
				}
				if (text.Contains("gun"))
				{
					num2 += 120;
				}
				if (text.Contains("weapon"))
				{
					num2 += 30;
				}
				if (text.Contains("laser") || text.Contains("orb") || text.Contains("staff"))
				{
					num2 -= 100;
				}
				if (num2 > num)
				{
					string text2 = GameAccess.ResourcePath(prefabRef2);
					if (!string.IsNullOrEmpty(text2))
					{
						num = num2;
						item = value;
						resourcePath = text2;
					}
				}
			}
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			_cachedGunItem = item;
			return true;
		}

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		}

		private void OnEnable()
		{
			PhotonNetwork.AddCallbackTarget((object)this);
			SceneManager.sceneLoaded += OnSceneLoaded_ResetOrDie;
		}

		private void OnDisable()
		{
			PhotonNetwork.RemoveCallbackTarget((object)this);
			SceneManager.sceneLoaded -= OnSceneLoaded_ResetOrDie;
		}

		private void OnSceneLoaded_ResetOrDie(Scene scene, LoadSceneMode mode)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0076: Expected O, but got Unknown
			bool flag = !SemiFunc.MenuLevel() && (Object)(object)LevelGenerator.Instance != (Object)null && (Object)(object)GameDirector.instance != (Object)null;
			HardResetUI(!flag);
			if (!flag)
			{
				DeactivateManager("scene changed to menu/lobby");
				return;
			}
			try
			{
				Player localPlayer = PhotonNetwork.LocalPlayer;
				if (localPlayer != null)
				{
					Hashtable val = new Hashtable();
					((Dictionary<object, object>)val).Add((object)"PH_PropVID", (object)0);
					((Dictionary<object, object>)val).Add((object)"PH_Locked", (object)0);
					localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
				}
			}
			catch
			{
			}
			Room currentRoom = PhotonNetwork.CurrentRoom;
			ApplyRoomState((currentRoom != null) ? ((RoomInfo)currentRoom).CustomProperties : null);
			try
			{
				EnsureControllersOnAllAvatars();
				SyncAllPlayerDisguises();
			}
			catch
			{
			}
			if (!_preHideArmed)
			{
				((MonoBehaviour)this).StartCoroutine(ArmPreHideWhenGameplayReady());
			}
		}

		private void Start()
		{
			//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_008d: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00aa: Expected O, but got Unknown
			if (PhotonNetwork.IsMasterClient && !((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).ContainsKey((object)"PH_Active"))
			{
				List<Player> list = PhotonNetwork.PlayerList.Where((Player p) => !p.IsInactive).ToList();
				if (list.Count > 0)
				{
					Player val = list[new Random().Next(list.Count)];
					Room currentRoom = PhotonNetwork.CurrentRoom;
					Hashtable val2 = new Hashtable();
					((Dictionary<object, object>)val2).Add((object)"PH_Active", (object)1);
					((Dictionary<object, object>)val2).Add((object)"PH_Hunter", (object)val.ActorNumber);
					currentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
					PropHuntPlugin.Log.LogInfo((object)$"[Empress Prop Hunt] Master picked Hunter actor {val.ActorNumber}.");
				}
			}
			Room currentRoom2 = PhotonNetwork.CurrentRoom;
			ApplyRoomState((currentRoom2 != null) ? ((RoomInfo)currentRoom2).CustomProperties : null);
			EnsureControllersOnAllAvatars();
			SyncAllPlayerDisguises();
			if (!_preHideArmed)
			{
				((MonoBehaviour)this).StartCoroutine(ArmPreHideWhenGameplayReady());
			}
		}

		private IEnumerator ArmPreHideWhenGameplayReady()
		{
			while (!GameAccess.IsMainState())
			{
				yield return null;
			}
			while (GameAccess.PlayerList() == null || GameAccess.PlayerList().Count == 0)
			{
				yield return null;
			}
			yield return (object)new WaitForSeconds(0.25f);
			_preHideArmed = true;
			_preHideUntil = Time.time + Mathf.Max(1f, PreHideSeconds);
			if (_localRole == PHRole.Hunter)
			{
				_hunterLockUntil = Time.time + Mathf.Max(1f, HunterLockSeconds);
				Flash($"Hunter locked for {Mathf.CeilToInt(HunterLockSeconds)}s.");
			}
			if (PhotonNetwork.IsMasterClient)
			{
				((MonoBehaviour)this).StartCoroutine(HostHealPassesDuringAndAfterPrehide());
			}
		}

		private IEnumerator HostHealPassesDuringAndAfterPrehide()
		{
			HostTopOffAll();
			yield return (object)new WaitForSeconds(Mathf.Max(0.25f, PreHideSeconds * 0.5f));
			HostTopOffAll();
			while (PreHideActive)
			{
				yield return null;
			}
			HostTopOffAll();
			yield return (object)new WaitForSeconds(0.75f);
			HostTopOffAll();
		}

		private void HostTopOffAll()
		{
			try
			{
				List<PlayerAvatar> list = GameAccess.PlayerList();
				if (list == null || list.Count == 0)
				{
					return;
				}
				foreach (PlayerAvatar item in list)
				{
					PlayerHealth val = GameAccess.Health(item);
					if ((Object)(object)item == (Object)null || (Object)(object)val == (Object)null)
					{
						continue;
					}
					try
					{
						val.HealOther(val.maxHealth, true);
					}
					catch (Exception ex)
					{
						ManualLogSource log = PropHuntPlugin.Log;
						int? obj;
						if (item == null)
						{
							obj = null;
						}
						else
						{
							PhotonView photonView = item.photonView;
							if (photonView == null)
							{
								obj = null;
							}
							else
							{
								Player owner = photonView.Owner;
								obj = ((owner != null) ? new int?(owner.ActorNumber) : null);
							}
						}
						int? num = obj;
						LogGate.WarnThrottled(log, $"[Empress Prop Hunt] Heal failed for actor {num.GetValueOrDefault(-1)}: {ex.Message}");
					}
				}
			}
			catch (Exception ex2)
			{
				LogGate.WarnThrottled(PropHuntPlugin.Log, "[Empress Prop Hunt] HostTopOffAll guarded: " + ex2.Message);
			}
		}

		private IEnumerator HostHealPlayerWhenReady(int actorNumber)
		{
			if (!PhotonNetwork.IsMasterClient)
			{
				yield break;
			}
			float t = 4f;
			while (t > 0f)
			{
				PlayerAvatar val = FindAvatarByActor(actorNumber);
				PlayerHealth health = GameAccess.Health(val);
				if ((Object)(object)val != (Object)null && (Object)(object)health != (Object)null)
				{
					try
					{
						health.HealOther(health.maxHealth, true);
					}
					catch
					{
					}
					yield return (object)new WaitForSeconds(0.5f);
					try
					{
						health.HealOther(health.maxHealth, true);
						break;
					}
					catch
					{
						break;
					}
				}
				t -= Time.deltaTime;
				yield return null;
			}
		}

		private void HardResetUI(bool clearRole)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			_ending = false;
			_endMsg = "";
			_whoWon = PHWinner.None;
			_hudShown = false;
			_flashMsg = "";
			_flashMsgUntil = 0f;
			_roundArmed = false;
			_roundEndRealtime = 0.0;
			_deadActors.Clear();
			_gun = null;
			_hunterLockUntil = 0f;
			_preHideArmed = false;
			_preHideUntil = 0f;
			_positionLocked = false;
			_positionLockAvatar = Vector3.zero;
			_positionLockController = Vector3.zero;
			if (clearRole)
			{
				_localRole = PHRole.None;
			}
			_cachedPropPhotonViewId = 0;
		}

		private void DeactivateManager(string why)
		{
			try
			{
				if ((Object)(object)Instance == (Object)(object)this)
				{
					Instance = null;
				}
				((Behaviour)this).enabled = false;
				PropHuntPlugin.Log.LogInfo((object)("[Empress Prop Hunt] Manager stopped (" + why + ")."));
			}
			catch
			{
			}
		}

		public override void OnLeftRoom()
		{
			HardResetUI(clearRole: true);
			DeactivateManager("left room");
		}

		public override void OnDisconnected(DisconnectCause cause)
		{
			HardResetUI(clearRole: true);
			DeactivateManager("disconnected");
		}

		public override void OnJoinedRoom()
		{
			Room currentRoom = PhotonNetwork.CurrentRoom;
			ApplyRoomState((currentRoom != null) ? ((RoomInfo)currentRoom).CustomProperties : null);
			EnsureControllersOnAllAvatars();
			SyncAllPlayerDisguises();
			if (!_preHideArmed)
			{
				((MonoBehaviour)this).StartCoroutine(ArmPreHideWhenGameplayReady());
			}
		}

		public override void OnPlayerEnteredRoom(Player newPlayer)
		{
			((MonoBehaviour)this).StartCoroutine(ApplyDisguiseForPlayerWhenReady(newPlayer));
			((MonoBehaviour)this).StartCoroutine(HostHealPlayerWhenReady(newPlayer.ActorNumber));
		}

		private IEnumerator ApplyDisguiseForPlayerWhenReady(Player p)
		{
			float t = 3f;
			while (t > 0f)
			{
				PlayerAvatar val = FindAvatarByActor(p.ActorNumber);
				if ((Object)(object)val != (Object)null)
				{
					ApplyOnePlayerDisguise(p, val);
					break;
				}
				t -= Time.deltaTime;
				yield return null;
			}
		}

		private void Update()
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.MenuLevel() || (Object)(object)LevelGenerator.Instance == (Object)null || (Object)(object)GameDirector.instance == (Object)null || !PhotonNetwork.InRoom || _localRole == PHRole.None)
			{
				return;
			}
			RefreshConfigValues();
			if (_ending)
			{
				TryLockControls();
				if (PhotonNetwork.IsMasterClient && Time.time >= _endUntil)
				{
					_ending = false;
					SafeAdvanceScene();
				}
				return;
			}
			PlayerAvatar val = FindLocalAvatar();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (!_hudShown)
			{
				((MonoBehaviour)this).StartCoroutine(HUDBurst());
				_hudShown = true;
			}
			if (!_roundArmed && _preHideArmed && !PreHideActive)
			{
				_roundArmed = true;
				_roundEndRealtime = Time.time + Mathf.Max(5f, RoundSeconds);
			}
			if (PhotonNetwork.IsMasterClient && _roundArmed && (double)Time.time >= _roundEndRealtime)
			{
				_roundArmed = false;
				BroadcastMatchEnd(PHWinner.Hiders, "Time expired");
			}
			if (_localRole == PHRole.Hider)
			{
				PropDisguiseController component = ((Component)val).GetComponent<PropDisguiseController>();
				if ((Object)(object)component == (Object)null || !component.IsDisguised)
				{
					UpdateCachedTargetFromPhysGrab();
				}
				if (Input.GetKeyDown(KeyHiderToggle))
				{
					ToggleDisguise(val);
				}
				if (Input.GetKeyDown(KeyPositionLock))
				{
					TogglePositionLock(val);
				}
				if (Input.GetKeyDown(KeyDisguiseViewToggle) && (Object)(object)component != (Object)null && component.IsDisguised)
				{
					bool flag = component.ToggleDisguiseView();
					Flash(flag ? "View: third-person" : "View: first-person");
				}
				TickPositionLock(val);
			}
			else
			{
				if (_localRole != PHRole.Hunter)
				{
					return;
				}
				if ((Object)(object)_gun == (Object)null)
				{
					_gun = ((Component)val).gameObject.GetComponent<HunterWeaponController>() ?? ((Component)val).gameObject.AddComponent<HunterWeaponController>();
				}
				_gun.Manager = this;
				_gun.Tick(val);
				if (!IsHunterLocked)
				{
					return;
				}
				try
				{
					PlayerController instance = PlayerController.instance;
					if ((Object)(object)instance != (Object)null)
					{
						instance.OverrideSpeed(0f, 0.2f);
					}
				}
				catch
				{
				}
			}
		}

		private void RefreshConfigValues()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0029: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			if (PropHuntPlugin.CfgKeyDisguiseToggle != null)
			{
				KeyHiderToggle = PropHuntPlugin.CfgKeyDisguiseToggle.Value;
			}
			if (PropHuntPlugin.CfgKeyViewToggle != null)
			{
				KeyDisguiseViewToggle = PropHuntPlugin.CfgKeyViewToggle.Value;
			}
			if (PropHuntPlugin.CfgKeyPositionLock != null)
			{
				KeyPositionLock = PropHuntPlugin.CfgKeyPositionLock.Value;
			}
			if (PropHuntPlugin.CfgGunRangeMeters != null)
			{
				GunRangeMeters = Mathf.Max(1f, PropHuntPlugin.CfgGunRangeMeters.Value);
			}
		}

		private void TogglePositionLock(PlayerAvatar me)
		{
			//IL_0072: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			if (_positionLocked)
			{
				_positionLocked = false;
				SetLocalVisualLock(me, locked: false);
				SetLocalLockProperty(locked: false);
				Flash("Position unlocked.");
				return;
			}
			PropDisguiseController propDisguiseController = (((Object)(object)me != (Object)null) ? ((Component)me).GetComponent<PropDisguiseController>() : null);
			if ((Object)(object)propDisguiseController == (Object)null || !propDisguiseController.IsDisguised)
			{
				Flash("Disguise first.");
				return;
			}
			_positionLocked = true;
			_positionLockAvatar = ((Component)me).transform.position;
			_positionLockController = (((Object)(object)PlayerController.instance != (Object)null) ? ((Component)PlayerController.instance).transform.position : _positionLockAvatar);
			propDisguiseController.SetVisualPoseLocked(locked: true);
			SetLocalLockProperty(locked: true);
			Flash("Position locked.");
		}

		private void TickPositionLock(PlayerAvatar me)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (!_positionLocked)
			{
				return;
			}
			PropDisguiseController propDisguiseController = (((Object)(object)me != (Object)null) ? ((Component)me).GetComponent<PropDisguiseController>() : null);
			if ((Object)(object)me == (Object)null || (Object)(object)propDisguiseController == (Object)null || !propDisguiseController.IsDisguised || _localRole != PHRole.Hider)
			{
				_positionLocked = false;
				SetLocalVisualLock(me, locked: false);
				SetLocalLockProperty(locked: false);
				return;
			}
			try
			{
				PlayerController instance = PlayerController.instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.OverrideSpeed(0f, 0.25f);
				}
				GameAccess.FreezeLocalPlayerPosition(me, _positionLockAvatar, _positionLockController);
			}
			catch
			{
			}
		}

		private void SetLocalVisualLock(PlayerAvatar me, bool locked)
		{
			try
			{
				PropDisguiseController propDisguiseController = (((Object)(object)me != (Object)null) ? ((Component)me).GetComponent<PropDisguiseController>() : null);
				if ((Object)(object)propDisguiseController != (Object)null)
				{
					propDisguiseController.SetVisualPoseLocked(locked);
				}
			}
			catch
			{
			}
		}

		private void SetLocalLockProperty(bool locked)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002b: Expected O, but got Unknown
			try
			{
				Player localPlayer = PhotonNetwork.LocalPlayer;
				if (localPlayer != null)
				{
					Hashtable val = new Hashtable();
					((Dictionary<object, object>)val).Add((object)"PH_Locked", (object)(locked ? 1 : 0));
					localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
				}
			}
			catch
			{
			}
		}

		private void BroadcastMatchEnd(PHWinner winner, string reason)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			object[] array = new object[3]
			{
				"PH1",
				(int)winner,
				reason ?? ""
			};
			PhotonNetwork.RaiseEvent((byte)103, (object)array, new RaiseEventOptions
			{
				Receivers = (ReceiverGroup)1
			}, SendOptions.SendReliable);
			StartEndBannerLocal(winner, reason);
		}

		private void StartEndBannerLocal(PHWinner winner, string reason)
		{
			_whoWon = winner;
			_endMsg = winner switch
			{
				PHWinner.Hiders => "HIDERS WIN!", 
				PHWinner.Hunter => "HUNTER WINS!", 
				_ => "DRAW", 
			};
			if (!string.IsNullOrEmpty(reason))
			{
				_endMsg = _endMsg + "  (" + reason + ")";
			}
			_ending = true;
			_endUntil = Time.time + 10f;
			TryLockControls();
		}

		private void RepickHunterForNextRound()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00c4: Expected O, but got Unknown
			if (!PhotonNetwork.IsMasterClient || !PhotonNetwork.InRoom)
			{
				return;
			}
			List<Player> list = PhotonNetwork.PlayerList.Where((Player p) => !p.IsInactive).ToList();
			if (list.Count != 0)
			{
				List<Player> list2 = ((list.Count > 1) ? list.Where((Player p) => p.ActorNumber != _hunterActor).ToList() : list);
				if (list2.Count == 0)
				{
					list2 = list;
				}
				int actorNumber = list2[new Random().Next(list2.Count)].ActorNumber;
				Room currentRoom = PhotonNetwork.CurrentRoom;
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)"PH_Active", (object)1);
				((Dictionary<object, object>)val).Add((object)"PH_Hunter", (object)actorNumber);
				currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
				PropHuntPlugin.Log.LogInfo((object)$"[Empress Prop Hunt] Next-round hunter: {actorNumber} (was {_hunterActor}).");
			}
		}

		private void SafeAdvanceScene()
		{
			if (PhotonNetwork.IsMasterClient)
			{
				RepickHunterForNextRound();
				ClearDisguisesBeforeLevelChange();
				GameAccess.ChangeToRandomRunLevel();
			}
		}

		private void ClearDisguisesBeforeLevelChange()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_003b: Expected O, but got Unknown
			try
			{
				Player[] playerList = PhotonNetwork.PlayerList;
				foreach (Player obj in playerList)
				{
					Hashtable val = new Hashtable();
					((Dictionary<object, object>)val).Add((object)"PH_PropVID", (object)0);
					((Dictionary<object, object>)val).Add((object)"PH_Locked", (object)0);
					obj.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
				}
			}
			catch
			{
			}
			try
			{
				List<PlayerAvatar> list = GameAccess.PlayerList();
				if (list == null)
				{
					return;
				}
				foreach (PlayerAvatar item in list)
				{
					if (!((Object)(object)item == (Object)null))
					{
						PropDisguiseController component = ((Component)item).GetComponent<PropDisguiseController>();
						if ((Object)(object)component != (Object)null)
						{
							component.ApplyClearLocal();
						}
					}
				}
			}
			catch
			{
			}
		}

		private void TryLockControls()
		{
			try
			{
				PlayerController instance = PlayerController.instance;
				if ((Object)(object)instance != (Object)null)
				{
					instance.InputDisable(0.25f);
					instance.OverrideSpeed(0f, 0.3f);
					instance.OverrideLookSpeed(0.2f, 0.15f, 0.15f, 0.3f);
				}
			}
			catch
			{
			}
		}

		private IEnumerator HUDBurst()
		{
			float t = 1.5f;
			while (t > 0f)
			{
				t -= Time.deltaTime;
				yield return null;
			}
		}

		private void OnGUI()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Expected O, but got Unknown
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_0442: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_044e: 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_047d: Expected O, but got Unknown
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.MenuLevel() || (Object)(object)LevelGenerator.Instance == (Object)null || (Object)(object)GameDirector.instance == (Object)null || !PhotonNetwork.InRoom || _localRole == PHRole.None)
			{
				return;
			}
			GUI.depth = 0;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(20f, 20f, 720f, 180f);
			string text = ((_localRole == PHRole.Hunter) ? "EMPRESS PROP HUNT - HUNTER\nShoot disguised valuables with the hunter handgun." : $"PROP HUNT — HIDER\n{KeyHiderToggle}: Toggle disguise  |  {KeyDisguiseViewToggle}: Toggle view  |  {KeyPositionLock}: Lock position");
			if (!_ending)
			{
				GUI.Box(val, text);
			}
			float num = ((Rect)(ref val)).yMax + 6f;
			if (_localRole == PHRole.Hider && !_ending && PreHideActive)
			{
				float num2 = Mathf.Max(0f, _preHideUntil - Time.time);
				int num3 = Mathf.FloorToInt(num2 / 60f);
				int num4 = Mathf.FloorToInt(num2 % 60f);
				GUI.Label(new Rect(((Rect)(ref val)).x + 8f, num, ((Rect)(ref val)).width, 24f), $"Hide time: {num3:00}:{num4:00}");
				num += 22f;
			}
			if (_roundArmed && !_ending)
			{
				float num5 = Mathf.Max(0f, (float)(_roundEndRealtime - (double)Time.time));
				int num6 = Mathf.FloorToInt(num5 / 60f);
				int num7 = Mathf.FloorToInt(num5 % 60f);
				GUI.Label(new Rect(((Rect)(ref val)).x + 8f, num, ((Rect)(ref val)).width, 24f), $"Time left: {num6:00}:{num7:00}");
				num += 22f;
			}
			if (_localRole == PHRole.Hunter && !_ending && IsHunterLocked)
			{
				int num8 = Mathf.CeilToInt(_hunterLockUntil - Time.time);
				GUI.Label(new Rect(((Rect)(ref val)).x + 8f, num, ((Rect)(ref val)).width, 24f), $"Hunter lock: {num8}s");
				num += 22f;
			}
			if (_localRole == PHRole.Hider && !_ending)
			{
				string text2 = ((_cachedPropPhotonViewId != 0 && (Object)(object)PhotonView.Find(_cachedPropPhotonViewId) != (Object)null) ? "Target locked" : "Look at a Valuable to lock target");
				GUI.Label(new Rect(((Rect)(ref val)).x + 8f, num, ((Rect)(ref val)).width, 24f), "Disguise: " + text2);
				num += 22f;
				if (_positionLocked)
				{
					GUI.Label(new Rect(((Rect)(ref val)).x + 8f, num, ((Rect)(ref val)).width, 24f), $"Position locked ({KeyPositionLock} to release)");
					num += 22f;
				}
			}
			if (Time.time < _flashMsgUntil)
			{
				GUI.Label(new Rect(30f, num + 8f, ((Rect)(ref val)).width, 24f), _flashMsg);
			}
			if (_ending)
			{
				string text3 = (PhotonNetwork.IsMasterClient ? Mathf.CeilToInt(Mathf.Max(0f, _endUntil - Time.time)).ToString() : "…");
				Rect val2 = new Rect(0f, 0f, (float)Screen.width, (float)Screen.height);
				GUI.color = new Color(0f, 0f, 0f, 0.55f);
				GUI.DrawTexture(val2, (Texture)(object)Texture2D.whiteTexture);
				GUI.color = Color.white;
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontStyle = (FontStyle)1,
					fontSize = Mathf.RoundToInt(Mathf.Clamp((float)Screen.width * 0.06f, 32f, 72f)),
					wordWrap = false
				};
				val3.normal.textColor = Color.white;
				GUI.Label(new Rect(0f, (float)Screen.height * 0.35f, (float)Screen.width, 80f), _endMsg, val3);
				GUIStyle val4 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = Mathf.RoundToInt(Mathf.Clamp((float)Screen.width * 0.03f, 18f, 36f)),
					wordWrap = false
				};
				val4.normal.textColor = new Color(1f, 1f, 1f, 0.9f);
				GUI.Label(new Rect(0f, (float)Screen.height * 0.35f + 68f, (float)Screen.width, 60f), "Next round starting in " + text3, val4);
			}
		}

		internal void Flash(string msg, float dur = 1.5f)
		{
			_flashMsg = msg;
			_flashMsgUntil = Time.time + dur;
		}

		public override void OnRoomPropertiesUpdate(Hashtable changed)
		{
			ApplyRoomState(changed);
		}

		public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps)
		{
			if (!((Dictionary<object, object>)(object)changedProps).ContainsKey((object)"PH_PropVID") && !((Dictionary<object, object>)(object)changedProps).ContainsKey((object)"PH_Locked"))
			{
				return;
			}
			PlayerAvatar val = FindAvatarByActor(targetPlayer.ActorNumber);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			PropDisguiseController propDisguiseController = ((Component)val).GetComponent<PropDisguiseController>() ?? ((Component)val).gameObject.AddComponent<PropDisguiseController>();
			if (((Dictionary<object, object>)(object)changedProps).ContainsKey((object)"PH_PropVID") && TryToInt(changedProps[(object)"PH_PropVID"], out var val2))
			{
				if (val2 == 0 || (Object)(object)PhotonView.Find(val2) == (Object)null)
				{
					propDisguiseController.ApplyClearLocal();
				}
				else
				{
					propDisguiseController.ApplyDisguiseLocal(val2, 0.0001f);
				}
			}
			int val3;
			bool visualPoseLocked = ((Dictionary<object, object>)(object)targetPlayer.CustomProperties).ContainsKey((object)"PH_Locked") && TryToInt(targetPlayer.CustomProperties[(object)"PH_Locked"], out val3) && val3 == 1;
			propDisguiseController.SetVisualPoseLocked(visualPoseLocked);
		}

		public override void OnPlayerLeftRoom(Player otherPlayer)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_0097: Expected O, but got Unknown
			if (PhotonNetwork.IsMasterClient && otherPlayer != null && otherPlayer.ActorNumber == _hunterActor)
			{
				List<Player> list = PhotonNetwork.PlayerList.Where((Player p) => !p.IsInactive).ToList();
				if (list.Count > 0)
				{
					Player val = list[new Random().Next(list.Count)];
					Room currentRoom = PhotonNetwork.CurrentRoom;
					Hashtable val2 = new Hashtable();
					((Dictionary<object, object>)val2).Add((object)"PH_Hunter", (object)val.ActorNumber);
					currentRoom.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
					PropHuntPlugin.Log.LogInfo((object)$"[Empress Prop Hunt] Hunter left; new hunter {val.ActorNumber}.");
				}
			}
		}

		private void ApplyRoomState(Hashtable props)
		{
			if (props == null || !((Dictionary<object, object>)(object)props).ContainsKey((object)"PH_Active"))
			{
				return;
			}
			bool flag = (int)props[(object)"PH_Active"] == 1;
			int num = (_hunterActor = (((Dictionary<object, object>)(object)props).ContainsKey((object)"PH_Hunter") ? ((int)props[(object)"PH_Hunter"]) : (-1)));
			Player localPlayer = PhotonNetwork.LocalPlayer;
			_localRole = (flag ? ((localPlayer.ActorNumber == num) ? PHRole.Hunter : PHRole.Hider) : PHRole.None);
			PropHuntPlugin.Log.LogInfo((object)$"[Empress Prop Hunt] Role set: {_localRole} (hunter actor={num}).");
			if (_localRole == PHRole.Hunter)
			{
				PlayerAvatar val = FindLocalAvatar();
				if ((Object)(object)val != (Object)null)
				{
					_gun = ((Component)val).gameObject.GetComponent<HunterWeaponController>() ?? ((Component)val).gameObject.AddComponent<HunterWeaponController>();
					_gun.Manager = this;
				}
			}
			_deadActors.Clear();
			_ending = false;
			_roundArmed = false;
			_roundEndRealtime = 0.0;
		}

		public void RequestEliminate(int targetActorNumber)
		{
			//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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			if (PhotonNetwork.InRoom)
			{
				object[] array = new object[3]
				{
					"PH1",
					PhotonNetwork.LocalPlayer.ActorNumber,
					targetActorNumber
				};
				PhotonNetwork.RaiseEvent((byte)101, (object)array, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)1
				}, SendOptions.SendReliable);
			}
		}

		public void OnEvent(EventData e)
		{
			try
			{
				if (HandleHunterWeaponEvent(e))
				{
					return;
				}
				int val4;
				if (e.Code == 101)
				{
					if (e.CustomData is object[] array && array.Length >= 3 && array[0] is string text && !(text != "PH1") && TryToInt(array[1], out var val) && val == _hunterActor && TryToInt(array[2], out var val2) && val2 > 0 && PhotonNetwork.LocalPlayer.ActorNumber == val2)
					{
						KillLocalPlayerClean();
					}
				}
				else if (e.Code == 102)
				{
					if (e.CustomData is object[] array2 && array2.Length >= 2 && array2[0] is string text2 && !(text2 != "PH1") && TryToInt(array2[1], out var val3) && PhotonNetwork.IsMasterClient)
					{
						_deadActors.Add(val3);
						if (val3 == _hunterActor)
						{
							_roundArmed = false;
							BroadcastMatchEnd(PHWinner.Hiders, "Hunter eliminated");
						}
						else if (AllHidersDead())
						{
							_roundArmed = false;
							BroadcastMatchEnd(PHWinner.Hunter, "All hiders eliminated");
						}
					}
				}
				else if (e.Code == 103 && e.CustomData is object[] array3 && array3.Length >= 3 && array3[0] is string text3 && !(text3 != "PH1") && TryToInt(array3[1], out val4))
				{
					string reason = (array3[2] as string) ?? "";
					StartEndBannerLocal((PHWinner)val4, reason);
				}
			}
			catch (Exception ex)
			{
				LogGate.WarnThrottled(PropHuntPlugin.Log, "[Empress Prop Hunt] OnEvent guarded: " + ex.Message);
			}
		}

		private bool AllHidersDead()
		{
			Player[] playerList = PhotonNetwork.PlayerList;
			foreach (Player val in playerList)
			{
				if (!val.IsInactive && val.ActorNumber != _hunterActor && !_deadActors.Contains(val.ActorNumber))
				{
					return false;
				}
			}
			return true;
		}

		private void KillLocalPlayerClean()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				PlayerAvatar val = FindLocalAvatar();
				if ((Object)(object)val != (Object)null)
				{
					val.PlayerDeath(0);
					return;
				}
			}
			catch
			{
			}
			try
			{
				PlayerAvatar val2 = FindLocalAvatar();
				PlayerHealth val3 = GameAccess.Health(val2);
				if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null)
				{
					val3.HurtOther(9999, ((Component)val2).transform.position, false, -1, false);
				}
			}
			catch (Exception ex)
			{
				LogGate.WarnThrottled(PropHuntPlugin.Log, "[Empress Prop Hunt] KillLocalPlayerClean: " + ex.Message);
			}
		}

		private void EnsureControllersOnAllAvatars()
		{
			List<PlayerAvatar> list = GameAccess.PlayerList();
			if (list == null)
			{
				return;
			}
			foreach (PlayerAvatar item in list)
			{
				if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).GetComponent<PropDisguiseController>() == (Object)null)
				{
					((Component)item).gameObject.AddComponent<PropDisguiseController>();
				}
			}
		}

		private void SyncAllPlayerDisguises()
		{
			Player[] playerList = PhotonNetwork.PlayerList;
			foreach (Player val in playerList)
			{
				PlayerAvatar val2 = FindAvatarByActor(val.ActorNumber);
				if (!((Object)(object)val2 == (Object)null))
				{
					ApplyOnePlayerDisguise(val, val2);
				}
			}
		}

		private void ApplyOnePlayerDisguise(Player pl, PlayerAvatar av)
		{
			if (pl != null && !((Object)(object)av == (Object)null) && ((Dictionary<object, object>)(object)pl.CustomProperties).ContainsKey((object)"PH_PropVID") && TryToInt(pl.CustomProperties[(object)"PH_PropVID"], out var val))
			{
				PropDisguiseController propDisguiseController = ((Component)av).GetComponent<PropDisguiseController>() ?? ((Component)av).gameObject.AddComponent<PropDisguiseController>();
				if (val == 0 || (Object)(object)PhotonView.Find(val) == (Object)null)
				{
					propDisguiseController.ApplyClearLocal();
					return;
				}
				propDisguiseController.ApplyDisguiseLocal(val, 0.0001f);
				int val2;
				bool visualPoseLocked = ((Dictionary<object, object>)(object)pl.CustomProperties).ContainsKey((object)"PH_Locked") && TryToInt(pl.CustomProperties[(object)"PH_Locked"], out val2) && val2 == 1;
				propDisguiseController.SetVisualPoseLocked(visualPoseLocked);
			}
		}

		private PlayerAvatar FindLocalAvatar()
		{
			List<PlayerAvatar> list = GameAccess.PlayerList();
			if (list == null)
			{
				return null;
			}
			foreach (PlayerAvatar item in list)
			{
				if ((Object)(object)item != (Object)null && (Object)(object)item.photonView != (Object)null && item.photonView.IsMine)
				{
					return item;
				}
			}
			return null;
		}

		private PlayerAvatar FindAvatarByActor(int actorNr)
		{
			List<PlayerAvatar> list = GameAccess.PlayerList();
			if (list == null)
			{
				return null;
			}
			foreach (PlayerAvatar item in list)
			{
				if (!((Object)(object)item == (Object)null) && !((Object)(object)item.photonView == (Object)null) && item.photonView.Owner != null && item.photonView.Owner.ActorNumber == actorNr)
				{
					return item;
				}
			}
			return null;
		}

		private ValuableObject GetTargetValuable()
		{
			PhysGrabObject val = PhysGrabber.instance?.currentlyLookingAtPhysGrabObject;
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			return ((Component)val).GetComponent<ValuableObject>();
		}

		private void UpdateCachedTargetFromPhysGrab()
		{
			try
			{
				ValuableObject targetValuable = GetTargetValuable();
				if (!((Object)(object)targetValuable == (Object)null))
				{
					PhotonView component = ((Component)targetValuable).GetComponent<PhotonView>();
					if ((Object)(object)component != (Object)null && component.ViewID != 0)
					{
						_cachedPropPhotonViewId = component.ViewID;
					}
				}
			}
			catch
			{
			}
		}

		private void ToggleDisguise(PlayerAvatar me)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0051: Expected O, but got Unknown
			//IL_00d2: 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_00e8: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_0100: Expected O, but got Unknown
			PropDisguiseController propDisguiseController = ((Component)me).GetComponent<PropDisguiseController>() ?? ((Component)me).gameObject.AddComponent<PropDisguiseController>();
			if (propDisguiseController.IsDisguised)
			{
				Player localPlayer = PhotonNetwork.LocalPlayer;
				Hashtable val = new Hashtable();
				((Dictionary<object, object>)val).Add((object)"PH_PropVID", (object)0);
				((Dictionary<object, object>)val).Add((object)"PH_Locked", (object)0);
				localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
				me.photonView.RPC("PH_RPC_TinyOff", (RpcTarget)4, new object[1] { me.photonView.ViewID });
				propDisguiseController.ApplyClearLocal();
				_positionLocked = false;
				Flash("Disguise cleared.");
			}
			else if (_cachedPropPhotonViewId == 0 || (Object)(object)PhotonView.Find(_cachedPropPhotonViewId) == (Object)null)
			{
				Flash("No disguise target. Look at a Valuable.");
			}
			else
			{
				int cachedPropPhotonViewId = _cachedPropPhotonViewId;
				Player localPlayer2 = PhotonNetwork.LocalPlayer;
				Hashtable val2 = new Hashtable();
				((Dictionary<object, object>)val2).Add((object)"PH_PropVID", (object)cachedPropPhotonViewId);
				((Dictionary<object, object>)val2).Add((object)"PH_Locked", (object)0);
				localPlayer2.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
				me.photonView.RPC("PH_RPC_TinyOn", (RpcTarget)4, new object[3]
				{
					me.photonView.ViewID,
					cachedPropPhotonViewId,
					0.0001f
				});
				propDisguiseController.ApplyDisguiseLocal(cachedPropPhotonViewId, 0.0001f);
				_positionLocked = false;
				Flash("Disguised.");
			}
		}

		private static bool TryToInt(object o, out int val)
		{
			try
			{
				if (o is int num)
				{
					val = num;
					return true;
				}
				if (o is byte b)
				{
					val = b;
					return true;
				}
				if (o is short num2)
				{
					val = num2;
					return true;
				}
				if (o is long num3)
				{
					val = (int)num3;
					return true;
				}
				if (o is float num4)
				{
					val = (int)num4;
					return true;
				}
				if (o is double num5)
				{
					val = (int)num5;
					return true;
				}
				if (o is string s && int.TryParse(s, out var result))
				{
					val = result;
					return true;
				}
			}
			catch
			{
			}
			val = -1;
			return false;
		}
	}
	[BepInPlugin("empress.repo.prophunt", "Empress Prop Hunt", "1.9.0")]
	public class PropHuntPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static Harmony Harmony;

		internal static ConfigEntry<float> CfgPreHideSeconds;

		internal static ConfigEntry<float> CfgHunterLockSeconds;

		internal static ConfigEntry<float> CfgRoundSeconds;

		internal static ConfigEntry<float> CfgGunRangeMeters;

		internal static ConfigEntry<KeyCode> CfgKeyDisguiseToggle;

		internal static ConfigEntry<KeyCode> CfgKeyViewToggle;

		internal static ConfigEntry<KeyCode> CfgKeyPositionLock;

		internal static ConfigEntry<bool> CfgDisableEnemies;

		internal static ConfigEntry<bool> CfgMaxOutValuables;

		private void Awake()
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			Harmony = new Harmony("empress.repo.prophunt");
			CfgPreHideSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "PreHideSeconds", 30f, "Seconds of hide time before the round starts.");
			CfgHunterLockSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "HunterLockSeconds", 30f, "Seconds the Hunter is locked during pre-hide.");
			CfgRoundSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Gameplay", "RoundSeconds", 300f, "Live round duration in seconds.");
			CfgGunRangeMeters = ((BaseUnityPlugin)this).Config.Bind<float>("Hunter", "GunRangeMeters", 60f, "Hunter handgun hit range in meters.");
			CfgKeyDisguiseToggle = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "HiderDisguiseKey", (KeyCode)118, "Hider: toggle disguise.");
			CfgKeyViewToggle = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "HiderViewToggleKey", (KeyCode)99, "Hider: toggle first/third person.");
			CfgKeyPositionLock = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "HiderPositionLockKey", (KeyCode)120, "Hider: lock position while disguised.");
			CfgDisableEnemies = ((BaseUnityPlugin)this).Config.Bind<bool>("Round Rules", "DisableEnemies", true, "Disable enemy spawns during Prop Hunt rounds.");
			CfgMaxOutValuables = ((BaseUnityPlugin)this).Config.Bind<bool>("Round Rules", "MaxOutValuables", true, "Spawn more valuables for hider choices.");
			Harmony.PatchAll();
			SceneManager.sceneLoaded += OnSceneLoaded;
			((MonoBehaviour)this).StartCoroutine(LevelWatcher());
			Log.LogInfo((object)"[Empress Prop Hunt] Loaded v1.9.0.");
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
		}

		private IEnumerator LevelWatcher()
		{
			while (true)
			{
				yield return (object)new WaitForSeconds(0.5f);
				if (SemiFunc.IsMultiplayer() && PhotonNetwork.InRoom && !SemiFunc.MenuLevel() && !((Object)(object)LevelGenerator.Instance == (Object)null) && !((Object)(object)GameDirector.instance == (Object)null))
				{
					List<PlayerAvatar> list = GameAccess.PlayerList();
					bool num = list != null && list.Count > 0;
					bool flag = GameAccess.IsMainState();
					if (num && flag && (Object)(object)PropHuntManager.Instance == (Object)null)
					{
						GameObject val = new GameObject("PropHuntManager");
						val.transform.parent = null;
						((Object)val).hideFlags = (HideFlags)61;
						Object.DontDestroyOnLoad((Object)val);
						PropHuntManager propHuntManager = val.AddComponent<PropHuntManager>();
						propHuntManager.PreHideSeconds = Mathf.Max(1f, CfgPreHideSeconds.Value);
						propHuntManager.HunterLockSeconds = Mathf.Max(0f, CfgHunterLockSeconds.Value);
						propHuntManager.RoundSeconds = Mathf.Max(5f, CfgRoundSeconds.Value);
						propHuntManager.GunRangeMeters = Mathf.Max(1f, CfgGunRangeMeters.Value);
						propHuntManager.KeyHiderToggle = CfgKeyDisguiseToggle.Value;
						propHuntManager.KeyDisguiseViewToggle = CfgKeyViewToggle.Value;
						propHuntManager.KeyPositionLock = CfgKeyPositionLock.Value;
						Log.LogInfo((object)"[Empress Prop Hunt] Manager created.");
					}
				}
			}
		}
	}
	public enum PHRole
	{
		None,
		Hunter,
		Hider
	}
	public enum PHWinner
	{
		None,
		Hunter,
		Hiders,
		Draw
	}
	internal static class LogGate
	{
		private static float _nextWarnTime;

		public static void WarnThrottled(ManualLogSource log, string msg, float everySeconds = 2f)
		{
			if (!(Time.realtimeSinceStartup < _nextWarnTime))
			{
				_nextWarnTime = Time.realtimeSinceStartup + everySeconds;
				log.LogWarning((object)msg);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeath")]
	public static class PH_Patch_PlayerDeath
	{
		private static void Postfix(PlayerAvatar __instance)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			try
			{
				if (PhotonNetwork.InRoom)
				{
					object obj;
					if (__instance == null)
					{
						obj = null;
					}
					else
					{
						PhotonView photonView = __instance.photonView;
						obj = ((photonView != null) ? photonView.Owner : null);
					}
					Player val = (Player)obj;
					if (val != null)
					{
						object[] array = new object[2] { "PH1", val.ActorNumber };
						PhotonNetwork.RaiseEvent((byte)102, (object)array, new RaiseEventOptions
						{
							Receivers = (ReceiverGroup)1
						}, SendOptions.SendReliable);
					}
				}
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "OnPhotonSerializeView")]
	public static class PH_SpoofCrouch_OnSerialize
	{
		private static void Prefix(PlayerAvatar __instance, PhotonStream stream, PhotonMessageInfo info, ref object __state)
		{
			__state = null;
			try
			{
				if (stream.IsWriting)
				{
					PropDisguiseController component = ((Component)__instance).GetComponent<PropDisguiseController>();
					if (!((Object)(object)component == (Object)null) && component.IsDisguised)
					{
						bool isCrouching = GameAccess.GetIsCrouching(__instance);
						__state = isCrouching;
						GameAccess.SetIsCrouching(__instance, value: true);
					}
				}
			}
			catch
			{
			}
		}

		private static void Postfix(PlayerAvatar __instance, PhotonStream stream, PhotonMessageInfo info, object __state)
		{
			try
			{
				if (stream.IsWriting && __state is bool)
				{
					bool value = (bool)__state;
					GameAccess.SetIsCrouching(__instance, value);
				}
			}
			catch
			{
			}
		}
	}
	public class PropDisguiseController : MonoBehaviourPun
	{
		private PlayerAvatar _avatar;

		private PlayerAvatarVisuals _visuals;

		private GameObject _disguiseRoot;

		private Transform _tinyTarget;

		private Vector3 _tinyOrigScale;

		private bool _hasTinyOrig;

		private GameObject _flashlightGO;

		private bool _visualPoseLocked;

		private Vector3 _visualLockWorldPosition;

		private Quaternion _visualLockWorldRotation;

		private bool _thirdEnabled;

		private bool _camBaseValid;

		private Transform _camOrigParent;

		private Vector3 _camOrigLocalPos;

		private float _camBack;

		private float _camUp;

		private Vector3 _camVel;

		private float _camSmoothTime = 0.08f;

		private static readonly string[] VISUALS_NAMES = new string[5] { "Player Visuals", "PlayerVisuals", "Player Visual", "Player_Visuals", "Visuals" };

		private static readonly string[] RIG_NAMES = new string[6] { "[RIG]", "RIG", "Rig", "Armature", "Root", "RootTransform" };

		private static readonly string[] FLASH_NAMES = new string[7] { "flashlight", "flash_light", "flash", "torch", "headlamp", "head_lamp", "lamp" };

		public bool IsDisguised { get; private set; }

		public bool TryRaycastDisguise(Ray ray, float maxDistance, out float distance)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			distance = 0f;
			if (!IsDisguised || (Object)(object)_disguiseRoot == (Object)null)
			{
				return false;
			}
			float num = maxDistance;
			bool flag = false;
			Renderer[] componentsInChildren = _disguiseRoot.GetComponentsInChildren<Renderer>(true);
			float num2 = default(float);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && val.enabled)
				{
					Bounds bounds = val.bounds;
					if (((Bounds)(ref bounds)).IntersectRay(ray, ref num2) && !(num2 < 0f) && !(num2 > num))
					{
						num = num2;
						flag = true;
					}
				}
			}
			if (!flag)
			{
				return false;
			}
			distance = num;
			return true;
		}

		private void Awake()
		{
			_avatar = ((Component)this).GetComponent<PlayerAvatar>();
			CacheVisualRefs();
		}

		private void CacheVisualRefs()
		{
			if ((Object)(object)_visuals == (Object)null)
			{
				_visuals = ((Component)this).GetComponentInChildren<PlayerAvatarVisuals>(true);
			}
			if ((Object)(object)_flashlightGO == (Object)null)
			{
				Transform val = FindFlashlightTransform(((Component)this).transform);
				if ((Object)(object)val != (Object)null)
				{
					_flashlightGO = ((Component)val).gameObject;
				}
			}
		}

		public void ApplyDisguiseLocal(int propVid, float tinyFactor)
		{
			DoApply(propVid, tinyFactor);
		}

		public void ApplyClearLocal()
		{
			DoClear();
		}

		[PunRPC]
		public void PH_RPC_TinyOn(int playerViewID, int propPhotonViewId, float tinyFactor)
		{
			if (!((Object)(object)((MonoBehaviourPun)this).photonView == (Object)null) && ((MonoBehaviourPun)this).photonView.ViewID == playerViewID && !((MonoBehaviourPun)this).photonView.IsMine)
			{
				DoApply(propPhotonViewId, tinyFactor);
			}
		}

		[PunRPC]
		public void PH_RPC_TinyOff(int playerViewID)
		{
			if (!((Object)(object)((MonoBehaviourPun)this).photonView == (Object)null) && ((MonoBehaviourPun)this).photonView.ViewID == playerViewID && !((MonoBehaviourPun)this).photonView.IsMine)
			{
				DoClear();
			}
		}

		private void DoApply(int propPhotonViewId, float tinyFactor)
		{
			CacheVisualRefs();
			float factor = Mathf.Clamp(tinyFactor, 0.0001f, 0.1f);
			if (!BuildOrRefreshClone(propPhotonViewId))
			{
				DoClear();
				return;
			}
			ApplyTinyToVisualRig(factor);
			PhysGrabber val = GameAccess.AvatarGrabber(_avatar);
			if ((Object)(object)val != (Object)null)
			{
				((Behaviour)val).enabled = false;
			}
			if ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.IsMine)
			{
				SetupLocalViewOffsets();
			}
			IsDisguised = true;
		}

		private void DoClear()
		{
			//IL_0066: 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)
			CacheVisualRefs();
			SetVisualPoseLocked(locked: false);
			ClearTinyOnVisualRig();
			PhysGrabber val = GameAccess.AvatarGrabber(_avatar);
			if ((Object)(object)val != (Object)null)
			{
				((Behaviour)val).enabled = true;
			}
			IsDisguised = false;
			if ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.IsMine)
			{
				_thirdEnabled = false;
				RestoreLocalViewOffsets();
				_camOrigParent = null;
				_camOrigLocalPos = Vector3.zero;
			}
			RemoveClone();
		}

		private void ApplyTinyToVisualRig(float factor)
		{
			//IL_0056: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			_tinyTarget = ResolveTinyTarget(((Component)_avatar).transform);
			if (!((Object)(object)_tinyTarget == (Object)null))
			{
				if (!_hasTinyOrig)
				{
					_tinyOrigScale = _tinyTarget.localScale;
					_hasTinyOrig = true;
				}
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(factor, factor, factor);
				Vector3 val2 = _tinyTarget.localScale - val;
				if (((Vector3)(ref val2)).sqrMagnitude > 1E-08f)
				{
					_tinyTarget.localScale = val;
				}
				Light[] componentsInChildren = ((Component)this).GetComponentsInChildren<Light>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Behaviour)componentsInChildren[i]).enabled = false;
				}
			}
		}

		private void ClearTinyOnVisualRig()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_tinyTarget != (Object)null && _hasTinyOrig)
			{
				_tinyTarget.localScale = _tinyOrigScale;
			}
			Light[] componentsInChildren = ((Component)this).GetComponentsInChildren<Light>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Behaviour)componentsInChildren[i]).enabled = true;
			}
		}

		private Transform FindFlashlightTransform(Transform root)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			string[] fLASH_NAMES = FLASH_NAMES;
			foreach (string text in fLASH_NAMES)
			{
				Transform val = root.Find(text) ?? root.Find(ToTitle(text));
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			Queue<Transform> queue = new Queue<Transform>();
			queue.Enqueue(root);
			while (queue.Count > 0)
			{
				Transform val2 = queue.Dequeue();
				string cn = Normalize(((Object)val2).name);
				if (FLASH_NAMES.Any((string n) => cn.Contains(Normalize(n))))
				{
					return val2;
				}
				foreach (Transform item2 in val2)
				{
					Transform item = item2;
					queue.Enqueue(item);
				}
			}
			Light[] componentsInChildren = ((Component)root).GetComponentsInChildren<Light>(true);
			foreach (Light val3 in componentsInChildren)
			{
				Transform t = ((Component)val3).transform;
				while ((Object)(object)t != (Object)null && (Object)(object)t != (Object)(object)root)
				{
					if (FLASH_NAMES.Any((string n) => Normalize(((Object)t).name).Contains(Normalize(n))))
					{
						return t;
					}
					t = t.parent;
				}
			}
			return null;
		}

		private static string ToTitle(string s)
		{
			if (!string.IsNullOrEmpty(s))
			{
				return char.ToUpperInvariant(s[0]) + s.Substring(1);
			}
			return s;
		}

		private Transform ResolveTinyTarget(Transform avatarRoot)
		{
			if ((Object)(object)avatarRoot == (Object)null)
			{
				return null;
			}
			Transform val = FindLooseBFS(FindNearestAncestorWhoseSubtreeHasLoose(avatarRoot, VISUALS_NAMES) ?? avatarRoot, VISUALS_NAMES);
			Transform val2 = (((Object)(object)val != (Object)null) ? FindLooseBFS(val, RIG_NAMES) : null);
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = FindLooseBFS(avatarRoot, RIG_NAMES);
			}
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			Renderer componentInChildren = ((Component)avatarRoot).GetComponentInChildren<Renderer>(true);
			if (!((Object)(object)componentInChildren != (Object)null))
			{
				return avatarRoot;
			}
			return ((Component)componentInChildren).transform;
		}

		private static Transform FindLooseBFS(Transform root, params string[] names)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			string[] source = names.Select(Normalize).ToArray();
			foreach (Transform item in root)
			{
				Transform val = item;
				string cn2 = Normalize(((Object)val).name);
				if (source.Any((string t) => t == cn2))
				{
					return val;
				}
			}
			Queue<Transform> queue = new Queue<Transform>();
			queue.Enqueue(root);
			while (queue.Count > 0)
			{
				foreach (Transform item2 in queue.Dequeue())
				{
					Transform val2 = item2;
					string cn = Normalize(((Object)val2).name);
					if (source.Any((string t) => t == cn || cn.Contains(t)))
					{
						return val2;
					}
					queue.Enqueue(val2);
				}
			}
			return null;
		}

		private static Transform FindNearestAncestorWhoseSubtreeHasLoose(Transform start, params string[] names)
		{
			Transform val = start;
			while ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)FindLooseBFS(val, names) != (Object)null)
				{
					return val;
				}
				val = val.parent;
			}
			return null;
		}

		private static string Normalize(string s)
		{
			if (string.IsNullOrEmpty(s))
			{
				return "";
			}
			s = s.ToLowerInvariant();
			return new string(s.Where((char ch) => ch != ' ' && ch != '_' && ch != '-' && ch != '[' && ch != ']' && ch != '(' && ch != ')' && ch != '{' && ch != '}' && ch != '.').ToArray());
		}

		private bool BuildOrRefreshClone(int propPhotonViewId)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			RemoveClone();
			PhotonView val = PhotonView.Find(propPhotonViewId);
			if ((Object)(object)val == (Object)null)
			{
				PropHuntPlugin.Log.LogWarning((object)$"[Empress Prop Hunt] Valuable view {propPhotonViewId} not found.");
				return false;
			}
			_disguiseRoot = new GameObject("PH_Disguise");
			_disguiseRoot.transform.SetParent(((Component)_avatar).transform, false);
			_disguiseRoot.transform.localPosition = Vector3.zero;
			_disguiseRoot.transform.localRotation = Quaternion.identity;
			_disguiseRoot.transform.localScale = Vector3.one;
			int avatarLayer = 0;
			CloneRelativeModel(((Component)val).transform, _disguiseRoot.transform, avatarLayer);
			Collider[] componentsInChildren = _disguiseRoot.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren[i]);
			}
			Rigidbody[] componentsInChildren2 = _disguiseRoot.GetComponentsInChildren<Rigidbody>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.Destroy((Object)(object)componentsInChildren2[i]);
			}
			return true;
		}

		private void RemoveClone()
		{
			if ((Object)(object)_disguiseRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_disguiseRoot);
				_disguiseRoot = null;
			}
		}

		public void SetVisualPoseLocked(bool locked)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_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)
			if (!locked)
			{
				_visualPoseLocked = false;
				if ((Object)(object)_disguiseRoot != (Object)null)
				{
					_disguiseRoot.transform.localPosition = Vector3.zero;
					_disguiseRoot.transform.localRotation = Quaternion.identity;
				}
			}
			else if (IsDisguised && !((Object)(object)_disguiseRoot == (Object)null))
			{
				_visualLockWorldPosition = _disguiseRoot.transform.position;
				_visualLockWorldRotation = _disguiseRoot.transform.rotation;
				_visualPoseLocked = true;
				MaintainVisualLockPose();
			}
		}

		private void MaintainVisualLockPose()
		{
			//IL_004f: 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_0060: 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_006b: 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)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (_visualPoseLocked && !((Object)(object)_disguiseRoot == (Object)null))
			{
				Transform transform = _disguiseRoot.transform;
				Transform parent = transform.parent;
				if ((Object)(object)parent == (Object)null)
				{
					transform.position = _visualLockWorldPosition;
					transform.rotation = _visualLockWorldRotation;
				}
				else
				{
					transform.localPosition = parent.InverseTransformPoint(_visualLockWorldPosition);
					transform.localRotation = Quaternion.Inverse(parent.rotation) * _visualLockWorldRotation;
				}
			}
		}

		private void CloneRelativeModel(Transform srcRoot, Transform dstRoot, int avatarLayer)
		{
			CloneNodeRecursive(srcRoot, dstRoot, avatarLayer, isRoot: true);
		}

		private void CloneNodeRecursive(Transform src, Transform dstParent, int avatarLayer, bool isRoot)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Expected O, but got Unknown
			GameObject val = new GameObject(((Object)src).name + "_PH");
			val.layer = avatarLayer;
			val.transform.SetParent(dstParent, false);
			if (isRoot)
			{
				val.transform.localPosition = Vector3.zero;
				val.transform.localRotation = Quaternion.identity;
				val.transform.localScale = src.localScale;
			}
			else
			{
				val.transform.localPosition = src.localPosition;
				val.transform.localRotation = src.localRotation;
				val.transform.localScale = src.localScale;
			}
			MeshFilter component = ((Component)src).GetComponent<MeshFilter>();
			MeshRenderer component2 = ((Component)src).GetComponent<MeshRenderer>();
			SkinnedMeshRenderer component3 = ((Component)src).GetComponent<SkinnedMeshRenderer>();
			if ((Object)(object)component2 != (Object)null && (Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
			{
				MeshFilter obj = val.AddComponent<MeshFilter>();
				MeshRenderer val2 = val.AddComponent<MeshRenderer>();
				obj.sharedMesh = component.sharedMesh;
				((Renderer)val2).sharedMaterials = ((Renderer)component2).sharedMaterials;
				((Renderer)val2).enabled = true;
				((Renderer)val2).forceRenderingOff = false;
			}
			else if ((Object)(object)component3 != (Object)null && (Object)(object)component3.sharedMesh != (Object)null)
			{
				Mesh val3 = new Mesh();
				try
				{
					component3.BakeMesh(val3);
				}
				catch
				{
					val3 = Object.Instantiate<Mesh>(component3.sharedMesh);
				}
				MeshFilter val4 = val.AddComponent<MeshFilter>();
				MeshRenderer obj3 = val.AddComponent<MeshRenderer>();
				val4.sharedMesh = val3;
				((Renderer)obj3).sharedMaterials = ((Renderer)component3).sharedMaterials;
				((Renderer)obj3).enabled = true;
				((Renderer)obj3).forceRenderingOff = false;
			}
			for (int i = 0; i < src.childCount; i++)
			{
				CloneNodeRecursive(src.GetChild(i), val.transform, avatarLayer, isRoot: false);
			}
		}

		private void SetupLocalViewOffsets()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			_thirdEnabled = true;
			Camera main = Camera.main;
			if (!((Object)(object)main == (Object)null))
			{
				if ((Object)(object)_camOrigParent == (Object)null && !_camBaseValid)
				{
					_camOrigParent = ((Component)main).transform.parent;
					_camOrigLocalPos = ((Component)main).transform.localPosition;
				}
				if ((Obje