Decompiled source of ControlCompany v1.3.4

ControlCompany.dll

Decompiled 22 minutes ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ControlCompany.Core;
using ControlCompany.Core.Config;
using ControlCompany.Core.Enemy;
using ControlCompany.Core.Enemy.NonStandardEnemy;
using ControlCompany.Core.Extentions;
using ControlCompany.Core.Input;
using ControlCompany.Core.UI;
using ControlCompany.Patches;
using Dissonance;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ControlCompany")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ControlCompany")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("dfed064e-ab44-4aa7-b361-7a59370d39a8")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ControlCompany
{
	[BepInPlugin("ControlCompany.ControlCompany", "ControlCompany", "1.3.4")]
	public class ControlCompanyPlugin : BaseUnityPlugin
	{
		private const string modGUID = "ControlCompany.ControlCompany";

		private const string modName = "ControlCompany";

		private const string modVersion = "1.3.4";

		private readonly Harmony harmony = new Harmony("ControlCompany.ControlCompany");

		public static ControlCompanyPlugin Instance;

		internal ManualLogSource logger;

		private bool isInitialized;

		private bool ranInitializationScripts;

		internal Harmony HarmonyInstance => harmony;

		private void Awake()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			if ((Object)Instance == (Object)null)
			{
				Instance = this;
			}
			logger = Logger.CreateLogSource("ControlCompany.ControlCompany");
			logger.LogInfo((object)"Loaded ControlCompany. Patching.");
			ApplyPatches();
			logger.LogInfo((object)"Completed patching. Initializing.");
			GameObject val = new GameObject("control_company_config_manager");
			val.AddComponent<ConfigManager>();
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)val);
			logger.LogInfo((object)"Completed initialization.");
			isInitialized = true;
		}

		private void ApplyPatches()
		{
			Patch(typeof(ControlCompanyPlugin));
			Patch(typeof(HUDManagerPatch));
			Patch(typeof(StartOfRoundPatch));
			Patch(typeof(PlayerControllerBPatch));
			Patch(typeof(EnemyAIPatch));
			Patch(typeof(TimeOfDayPatch));
			Patch(typeof(SoundManagerPatch));
			Patch(typeof(LobbyListPatch));
		}

		private void Patch(Type patchClass)
		{
			try
			{
				harmony.PatchAll(patchClass);
				logger.LogInfo((object)("Patched " + patchClass.Name));
			}
			catch (Exception ex)
			{
				logger.LogError((object)("FAILED to apply " + patchClass.Name + " - the game probably changed the method it targets: " + ex));
			}
		}
	}
}
namespace ControlCompany.Patches
{
	[HarmonyPatch(typeof(EnemyAI))]
	internal class EnemyAIPatch
	{
		[HarmonyPatch("ChangeOwnershipOfEnemy")]
		[HarmonyPrefix]
		private static bool ChangeOwnershipOfEnemyPrefix(EnemyAI __instance, ref ulong newOwnerClientId)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_009b: 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)
			//IL_00ab: Expected O, but got Unknown
			//IL_00ab: Expected O, but got Unknown
			if ((Object)ControlCenter.Instance != (Object)null && ControlCenter.Instance.CurrentMode == ControlCenter.Mode.ENEMY)
			{
				if ((Object)ControlCenter.Instance.CurrentControlledEnemy != (Object)null)
				{
					bool flag = ControlCenter.Instance.GetHostPlayer().actualClientId == newOwnerClientId || ControlCenter.Instance.CurrentControlledEnemy.IsAIControlled;
					if (((object)ControlCenter.Instance.CurrentControlledEnemy).GetType() == typeof(EnemyAIController))
					{
						EnemyAIController enemyAIController = (EnemyAIController)ControlCenter.Instance.CurrentControlledEnemy;
						flag = flag || (Object)enemyAIController.EnemyAI != (Object)__instance;
					}
					return flag;
				}
				return true;
			}
			return true;
		}

		[HarmonyPatch("ChangeEnemyOwnerServerRpc")]
		[HarmonyPrefix]
		private static bool ChangeEnemyOwnerServerRpcPrefix(EnemyAI __instance, ref ulong clientId)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_009b: 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)
			//IL_00ab: Expected O, but got Unknown
			//IL_00ab: Expected O, but got Unknown
			if ((Object)ControlCenter.Instance != (Object)null && ControlCenter.Instance.CurrentMode == ControlCenter.Mode.ENEMY)
			{
				if ((Object)ControlCenter.Instance.CurrentControlledEnemy != (Object)null)
				{
					bool flag = ControlCenter.Instance.GetHostPlayer().actualClientId == clientId || ControlCenter.Instance.CurrentControlledEnemy.IsAIControlled;
					if (((object)ControlCenter.Instance.CurrentControlledEnemy).GetType() == typeof(EnemyAIController))
					{
						EnemyAIController enemyAIController = (EnemyAIController)ControlCenter.Instance.CurrentControlledEnemy;
						flag = flag || (Object)enemyAIController.EnemyAI != (Object)__instance;
					}
					return flag;
				}
				return true;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(HUDManager))]
	internal class HUDManagerPatch
	{
		[HarmonyPatch("CanPlayerScan")]
		[HarmonyPostfix]
		private static void CanPlayerScanPostfix(ref bool __result)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			if (__result && (Object)ControlCenter.Instance != (Object)null)
			{
				__result = ControlCenter.Instance.CurrentMode == ControlCenter.Mode.HOST;
			}
		}

		[HarmonyPatch("UpdateHealthUI")]
		[HarmonyPrefix]
		private static bool UpdateHealthUIPrefix()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)ControlCenter.Instance != (Object)null)
			{
				return ControlCenter.Instance.CurrentMode == ControlCenter.Mode.HOST;
			}
			return true;
		}
	}
	internal class LobbyListPatch
	{
		public const char SERVER_NAME_FILTER = '\u200b';

		[HarmonyPatch(typeof(MenuManager), "ConfirmHostButton")]
		[HarmonyPrefix]
		private static void AddServerNameChar(MenuManager __instance)
		{
			string text = __instance.lobbyNameInputField.text;
			if (!ConfigManager.Instance.DisableModForSelf && __instance.hostSettings_LobbyPublic)
			{
				if (!Enumerable.Contains(text, '\u200b'))
				{
					text = ((text.Length > 3) ? text.Insert(text.Length - 2, '\u200b'.ToString()) : ("\u200b" + text));
				}
				if (!text.Trim().StartsWith("[MODDED]"))
				{
					text = "[MODDED] " + text;
				}
				__instance.lobbyNameInputField.text = text;
			}
			else
			{
				__instance.lobbyNameInputField.text = text.RemoveChar('\u200b');
			}
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal class PlayerControllerBPatch
	{
		[HarmonyPatch("PlayerLookInput")]
		[HarmonyPrefix]
		private static bool PlayerLookInputPrefix()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)ControlCenter.Instance != (Object)null)
			{
				return ControlCenter.Instance.CurrentMode == ControlCenter.Mode.HOST;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(SoundManager))]
	internal class SoundManagerPatch
	{
		[HarmonyPatch("SetEarsRinging")]
		[HarmonyPrefix]
		private static bool SetEarsRingingPrefix()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)ControlCenter.Instance != (Object)null)
			{
				return ControlCenter.Instance.CurrentMode == ControlCenter.Mode.HOST;
			}
			return true;
		}
	}
	internal class StartOfRoundPatch
	{
		[HarmonyPatch(typeof(StartOfRound), "ShipHasLeft")]
		[HarmonyPrefix]
		private static void ShipHasLeftPrefix()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)ControlCenter.Instance != (Object)null)
			{
				ControlCenter.Instance.EndOfRoundCleanUp();
			}
		}

		[HarmonyPatch(typeof(RoundManager), "RefreshEnemiesList")]
		[HarmonyPostfix]
		private static void StartGamePostfix()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)ControlCenter.Instance != (Object)null)
			{
				ControlCenter.Instance.StartOfRoundInitialization();
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		private static void CreateControlCenter()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				CompatReport.Run(ControlCompanyPlugin.Instance.HarmonyInstance);
			}
			catch (Exception ex)
			{
				ControlCompanyPlugin.Instance.logger.LogWarning((object)("[compat] report could not run: " + ex.Message));
			}
			if (!ConfigManager.Instance.DisableModForSelf)
			{
				GameObject val = new GameObject("control_company_control_center");
				val.AddComponent<ControlCenter>();
				val.AddComponent<UIManager>();
			}
		}
	}
	[HarmonyPatch(typeof(TimeOfDay))]
	internal class TimeOfDayPatch
	{
		[HarmonyPatch("VoteShipToLeaveEarly")]
		[HarmonyPrefix]
		private static bool VoteToLeaveEarly()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)ControlCenter.Instance != (Object)null)
			{
				return ControlCenter.Instance.CurrentMode == ControlCenter.Mode.HOST;
			}
			return true;
		}
	}
}
namespace ControlCompany.Core
{
	internal static class CompatReport
	{
		private static bool done;

		private static readonly (Type type, string member)[] Fields = new(Type, string)[16]
		{
			(typeof(RadMechAI), "visibleThreatsMask"),
			(typeof(RadMechAI), "shootTimer"),
			(typeof(RadMechAI), "walkStepTimer"),
			(typeof(RadMechAI), "takingStep"),
			(typeof(FlowerSnakeEnemy), "leaping"),
			(typeof(JesterAI), "inKillAnimation"),
			(typeof(CentipedeAI), "clingingToDeadBody"),
			(typeof(ForestGiantAI), "inEatingPlayerAnimation"),
			(typeof(ClaySurgeonAI), "beatTimer"),
			(typeof(SpringManAI), "hasStopped"),
			(typeof(SpringManAI), "stoppingMovement"),
			(typeof(SpringManAI), "currentAnimSpeed"),
			(typeof(MaskedPlayerEnemy), "inKillAnimation"),
			(typeof(MaskedPlayerEnemy), "crouching"),
			(typeof(NutcrackerEnemyAI), "reloadingGun"),
			(typeof(DoorLock), "isDoorOpened")
		};

		private static readonly (Type type, string member)[] Methods = new(Type, string)[11]
		{
			(typeof(PlayerControllerB), "NearOtherPlayers"),
			(typeof(BaboonBirdAI), "CanGrabScrap"),
			(typeof(BaboonBirdAI), "GrabItemAndSync"),
			(typeof(BaboonBirdAI), "DropHeldItemAndSync"),
			(typeof(CentipedeAI), "RaycastToCeiling"),
			(typeof(HoarderBugAI), "ChooseNestPosition"),
			(typeof(HoarderBugAI), "GrabTargetItemIfClose"),
			(typeof(HoarderBugAI), "DropItemAndCallDropRPC"),
			(typeof(FlowermanAI), "DropPlayerBody"),
			(typeof(Turret), "SwitchTurretMode"),
			(typeof(MaskedPlayerEnemy), "TeleportMaskedEnemyAndSync")
		};

		private const BindingFlags Flags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		public static void Run(Harmony harmony)
		{
			if (done)
			{
				return;
			}
			done = true;
			ManualLogSource logger = ControlCompanyPlugin.Instance.logger;
			try
			{
				int num = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.gameVersionNum : (-1));
				logger.LogInfo((object)$"[compat] ControlCompany 1.3.4 on Lethal Company version number {num}");
				int num2 = 0;
				(Type, string)[] fields = Fields;
				for (int i = 0; i < fields.Length; i++)
				{
					var (type, member) = fields[i];
					if (!Find(type, (Type t) => t.GetField(member, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null))
					{
						num2++;
						logger.LogWarning((object)("[compat] MISSING field " + type.Name + "." + member));
					}
				}
				fields = Methods;
				for (int i = 0; i < fields.Length; i++)
				{
					var (type2, member2) = fields[i];
					if (!Find(type2, (Type t) => t.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Any((MethodInfo m) => m.Name == member2)))
					{
						num2++;
						logger.LogWarning((object)("[compat] MISSING method " + type2.Name + "." + member2));
					}
				}
				List<MethodBase> list = harmony.GetPatchedMethods().ToList();
				logger.LogInfo((object)string.Format("[compat] Harmony patches applied to {0} game methods (expected 11): {1}", list.Count, string.Join(", ", list.Select((MethodBase m) => m.DeclaringType.Name + "." + m.Name))));
				logger.LogInfo((object)((num2 == 0) ? "[compat] All reflected game members found." : $"[compat] {num2} reflected game member(s) missing - the matching monster abilities will be skipped."));
			}
			catch (Exception ex)
			{
				logger.LogWarning((object)("[compat] report failed: " + ex.Message));
			}
		}

		private static bool Find(Type type, Func<Type, bool> test)
		{
			Type type2 = type;
			while (type2 != null)
			{
				if (test(type2))
				{
					return true;
				}
				type2 = type2.BaseType;
			}
			return false;
		}
	}
	internal static class Constants
	{
		public static Dictionary<int, string> ALL_LAYERS_DICT = (from index in Enumerable.Range(0, 32)
			where !string.IsNullOrEmpty(LayerMask.LayerToName(index))
			select index).ToDictionary((int index) => index, (int index) => LayerMask.LayerToName(index));

		public static string PLAYER_LOS_LAYERNAME = "LineOfSight";

		public static int PLAYER_LOS_LAYERINDEX = LayerMask.NameToLayer(PLAYER_LOS_LAYERNAME);

		public static LayerMask PLAYER_LOS_LAYERMASK = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { PLAYER_LOS_LAYERNAME }));

		public static string PLAYER_LAYERNAME = "Player";

		public static int PLAYER_LAYERINDEX = LayerMask.NameToLayer(PLAYER_LAYERNAME);

		public static LayerMask PLAYER_LAYERMASK = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { PLAYER_LAYERNAME }));

		public static string PLAYER_VISOR_LAYERNAME = "HelmetVisor";

		public static int PLAYER_VISOR_LAYERINDEX = LayerMask.NameToLayer(PLAYER_VISOR_LAYERNAME);

		public static LayerMask PLAYER_VISOR_LAYERMASK = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { PLAYER_VISOR_LAYERNAME }));

		public static string ITERACTABLE_OBJ_LAYERNAME = "InteractableObject";

		public static int ITERACTABLE_OBJ_LAYERINDEX = LayerMask.NameToLayer(ITERACTABLE_OBJ_LAYERNAME);

		public static LayerMask ITERACTABLE_OBJ_LAYERMASK = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { ITERACTABLE_OBJ_LAYERNAME }));

		public static string PROPS_OBJ_LAYERNAME = "Props";

		public static int PROPS_OBJ_LAYERINDEX = LayerMask.NameToLayer(PROPS_OBJ_LAYERNAME);

		public static LayerMask PROPS_LAYERMASK = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { PROPS_OBJ_LAYERNAME }));

		public static string ENEMIES_OBJ_LAYERNAME = "Enemies";

		public static int ENEMIES_OBJ_LAYERINDEX = LayerMask.NameToLayer(ENEMIES_OBJ_LAYERNAME);

		public static LayerMask ENEMIES_LAYERMASK = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { ENEMIES_OBJ_LAYERNAME }));

		public static string PLAYER_RAGDOLL_LAYERNAME = "PlayerRagdoll";

		public static int PLAYER_RAGDOLL_LAYERINDEX = LayerMask.NameToLayer(PLAYER_RAGDOLL_LAYERNAME);

		public static LayerMask PLAYER_RAGDOLL_LAYERMASK = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { PLAYER_RAGDOLL_LAYERNAME }));

		public static string PHYSICS_OBJECT_LAYERNAME = "PhysicsObject";

		public static int PHYSICS_OBJECT_LAYERINDEX = LayerMask.NameToLayer(PHYSICS_OBJECT_LAYERNAME);

		public static LayerMask PHYSICS_OBJECT_LAYERMASK = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { PHYSICS_OBJECT_LAYERNAME }));
	}
	internal class ControlCenter : MonoBehaviour
	{
		public enum Mode
		{
			HOST,
			GHOST,
			ENEMY
		}

		public static ControlCenter Instance;

		private CustomPlayerController ghostController;

		private GameObject ghost;

		private EnemyController currentControlledEnemy;

		private int currentTargetIndex;

		private PlayerControllerB currentTarget;

		private Mode currentMode;

		private bool allowAllEnemies;

		private bool initialMicPushToTalkSetting;

		private bool isExtendedModeEnabled;

		private bool scrapSpawnMode;

		private int currentSpawnScrapPage;

		private const int scrapSpawnPageSize = 10;

		private int currentSpawnEnemiesPage;

		private const int spawnEnemiesPageSize = 12;

		private List<ControllableEnemy> currentSpawnableEnemyList = new List<ControllableEnemy>();

		private bool loadedConfig;

		private bool showUI = true;

		private float gameStartedTime;

		private bool inRoundEndPhase;

		private bool isGhostIndoors;

		private List<ControllableEnemy> allIndoorEnemies = new List<ControllableEnemy>();

		private List<ControllableEnemy> allOutdoorEnemies = new List<ControllableEnemy>();

		private List<ControllableEnemy> indoorEnemiesOfLevel = new List<ControllableEnemy>();

		private List<ControllableEnemy> outdoorEnemiesOfLevel = new List<ControllableEnemy>();

		public Mode CurrentMode => currentMode;

		public EnemyController CurrentControlledEnemy => currentControlledEnemy;

		public bool IsGhostIndoors
		{
			get
			{
				return isGhostIndoors;
			}
			set
			{
				isGhostIndoors = value;
			}
		}

		private void Awake()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)Instance == (Object)null)
			{
				Instance = this;
			}
		}

		private void OnEnable()
		{
			if (!loadedConfig)
			{
				loadedConfig = true;
				ConfigManager.Instance.LoadPlayerConfig(reload: true);
			}
		}

		private void Update()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Expected O, but got Unknown
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			if (!IsGameStarted())
			{
				return;
			}
			if (((ButtonControl)InputKeys.TOGGLE_UI_KEY).wasPressedThisFrame)
			{
				showUI = !showUI;
			}
			gameStartedTime += Time.deltaTime;
			if (!IsHost() || inRoundEndPhase)
			{
				return;
			}
			if (((Object)currentTarget == (Object)null || !currentTarget.isPlayerControlled || currentTarget.isPlayerDead) && GetAlivePlayers().Count > 0)
			{
				SetNextTargetPlayer(1);
			}
			if ((Object)ghost == (Object)null)
			{
				GameObject val = new GameObject("ghost");
				ghostController = val.AddComponent<CustomPlayerController>();
				ghostController.Initialize(GetHostPlayer().playerActions, CustomPlayerController.CameraMode.FIRST_PERSON);
				ghost = val;
				ghost.SetActive(false);
				ControlCompanyPlugin.Instance.logger.LogInfo((object)"Creating ghost");
			}
			if (currentMode != Mode.HOST)
			{
				GetHostPlayer().isTypingChat = true;
			}
			if (IsListeningFromHost() && !IsHostDead() && currentMode != Mode.HOST)
			{
				if ((Object)ghostController != (Object)null)
				{
					((Behaviour)ghostController.AudioListener).enabled = false;
				}
				if ((Object)currentControlledEnemy != (Object)null)
				{
					((Behaviour)currentControlledEnemy.AudioListener).enabled = false;
				}
				((Behaviour)GetHostPlayer().activeAudioListener).enabled = true;
				ChangeAudioListener(GetHostPlayer().activeAudioListener);
			}
			else if (currentMode == Mode.GHOST)
			{
				if ((Object)ghostController != (Object)null && ghostController.IsInitialized)
				{
					((Behaviour)GetHostPlayer().activeAudioListener).enabled = false;
					((Behaviour)ghostController.AudioListener).enabled = true;
					ChangeAudioListener(ghostController.AudioListener);
				}
			}
			else if (currentMode == Mode.ENEMY)
			{
				if (((Object)currentControlledEnemy != (Object)null) & currentControlledEnemy.IsInitialized)
				{
					((Behaviour)GetHostPlayer().activeAudioListener).enabled = false;
					((Behaviour)currentControlledEnemy.AudioListener).enabled = true;
					ChangeAudioListener(currentControlledEnemy.AudioListener);
				}
			}
			else if (currentMode == Mode.HOST)
			{
				ChangeAudioListener(GetHostPlayer().activeAudioListener);
			}
			InputUpdate();
		}

		private void InputUpdate()
		{
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Expected O, but got Unknown
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: 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_031d: Unknown result type (might be due to invalid IL or missing references)
			if (!IsGameStarted() || !IsHost() || inRoundEndPhase || (ConfigManager.Instance.DisableWhileUsingTerminal && GetHostPlayer().inTerminalMenu))
			{
				return;
			}
			if (((ButtonControl)InputKeys.EXTENDED_MODE_KEY).wasPressedThisFrame)
			{
				isExtendedModeEnabled = !isExtendedModeEnabled;
				allowAllEnemies = isExtendedModeEnabled;
				SetNextSpawnEnemiesPage(0);
			}
			switch (currentMode)
			{
			case Mode.ENEMY:
				if (!currentControlledEnemy.IsAIControlled && currentControlledEnemy.CanControlEnemy())
				{
					if (InputKeys.ENEMY_PRIMARY_SKILL_BUTTON.wasPressedThisFrame)
					{
						currentControlledEnemy.UsePrimarySkill();
					}
					else if (InputKeys.ENEMY_PRIMARY_SKILL_BUTTON.wasReleasedThisFrame)
					{
						currentControlledEnemy.ReleasePrimarySkill();
					}
					else if (InputKeys.ENEMY_SECONDARY_SKILL_BUTTON.wasPressedThisFrame)
					{
						currentControlledEnemy.UseSecondarySkill();
					}
					else if (InputKeys.ENEMY_SECONDARY_SKILL_BUTTON.wasReleasedThisFrame)
					{
						currentControlledEnemy.ReleaseSecondarySkill();
					}
					currentControlledEnemy.SetLockEnemyRotation(((ButtonControl)InputKeys.LOCK_ENEMY_ROTATION_KEY).isPressed);
				}
				if (((ButtonControl)InputKeys.EXIT_KEY).wasPressedThisFrame)
				{
					EnableGhost(enable: true, ((Component)currentControlledEnemy).transform.position);
					ghostController.EnableLight(isGhostIndoors);
					currentControlledEnemy.DestroyAndCleanUp();
					currentMode = Mode.GHOST;
				}
				else if (((ButtonControl)InputKeys.ENEMY_TOGGLE_AI_KEY).wasPressedThisFrame)
				{
					currentControlledEnemy.ToggleAIControl();
				}
				else if (((ButtonControl)InputKeys.ENEMY_TOGGLE_LIGHT_KEY).wasPressedThisFrame)
				{
					currentControlledEnemy.ToggleLight();
				}
				break;
			case Mode.HOST:
				if (((ButtonControl)InputKeys.HOST_GHOST_MODE_KEY).wasPressedThisFrame)
				{
					isGhostIndoors = IsTargetInside();
					EnableGhost(enable: true, ((Component)currentTarget).gameObject.transform.position);
					ghostController.EnableLight(isGhostIndoors);
					EnableHostPlayer(enable: false);
					currentMode = Mode.GHOST;
				}
				else if (((ButtonControl)InputKeys.CYCLE_KEY_LEFT).wasPressedThisFrame)
				{
					SetNextTargetPlayer(-1);
				}
				else if (((ButtonControl)InputKeys.CYCLE_KEY_RIGHT).wasPressedThisFrame)
				{
					SetNextTargetPlayer(1);
				}
				if (!isExtendedModeEnabled)
				{
					break;
				}
				if (((ButtonControl)InputKeys.HOST_TELEPORT_TO_ENTRANCE_KEY).wasPressedThisFrame)
				{
					if (!GetHostPlayer().isPlayerDead)
					{
						EntranceTeleport mainEntrance = GetMainEntrance(getMainEntranceThatIsOutside: true);
						if ((Object)mainEntrance != (Object)null)
						{
							mainEntrance.TeleportPlayer();
						}
					}
				}
				else if (((ButtonControl)InputKeys.HOST_GIVE_CREDITS_KEY).wasPressedThisFrame)
				{
					Terminal obj = Object.FindObjectOfType<Terminal>();
					obj.groupCredits += 100;
				}
				break;
			case Mode.GHOST:
				if (!scrapSpawnMode)
				{
					List<ControllableEnemy> pagedSpawnableEnemies = GetPagedSpawnableEnemies();
					for (int i = 0; i < InputKeys.GHOST_SPAWN_ENEMY_KEYS.Count && i < pagedSpawnableEnemies.Count; i++)
					{
						if (!((ButtonControl)InputKeys.GHOST_SPAWN_ENEMY_KEYS[i]).wasPressedThisFrame)
						{
							continue;
						}
						if (ConfigManager.Instance.UseEnemySpawningBehaviour)
						{
							Random random = new Random(StartOfRound.Instance.randomMapSeed + 888);
							if (isGhostIndoors)
							{
								RoundManager.Instance.RefreshEnemyVents();
								EnemyVent[] allEnemyVents = RoundManager.Instance.allEnemyVents;
								if (allEnemyVents.Count() > 0)
								{
									EnemyVent val = allEnemyVents[random.Next(allEnemyVents.Count())];
									currentControlledEnemy = SpawnControllableEnemy(pagedSpawnableEnemies[i], val.floorNode.position, val.floorNode.rotation);
								}
								else
								{
									currentControlledEnemy = SpawnControllableEnemy(pagedSpawnableEnemies[i], ghost.transform.position, ghost.transform.rotation);
								}
							}
							else
							{
								GameObject[] array = GameObject.FindGameObjectsWithTag("OutsideAINode");
								if (array.Count() > 0)
								{
									currentControlledEnemy = SpawnControllableEnemy(pagedSpawnableEnemies[i], array[random.Next(array.Count())].transform.position, ghost.transform.rotation);
								}
								else
								{
									currentControlledEnemy = SpawnControllableEnemy(pagedSpawnableEnemies[i], ghost.transform.position, ghost.transform.rotation);
								}
							}
						}
						else
						{
							currentControlledEnemy = SpawnControllableEnemy(pagedSpawnableEnemies[i], ghost.transform.position, ghost.transform.rotation);
						}
						EnableGhost(enable: false);
						currentMode = Mode.ENEMY;
						break;
					}
				}
				else
				{
					List<Item> list = ExtensionMethods.Chunk(GetSpawnableScraps(), 10).ToList()[currentSpawnScrapPage].ToList();
					for (int j = 0; j < InputKeys.GHOST_SPAWN_ENEMY_KEYS.Count && j < list.Count; j++)
					{
						if (((ButtonControl)InputKeys.GHOST_SPAWN_ENEMY_KEYS[j]).wasPressedThisFrame)
						{
							SpawnScrap(list[j], ghost.transform.position);
							break;
						}
					}
				}
				if (((ButtonControl)InputKeys.EXIT_KEY).wasPressedThisFrame)
				{
					EnableGhost(enable: false);
					EnableHostPlayer(enable: true);
					currentMode = Mode.HOST;
					GetHostPlayer().isTypingChat = false;
				}
				else if (((ButtonControl)InputKeys.CYCLE_KEY_LEFT).wasPressedThisFrame)
				{
					SetNextSpawnEnemiesPage(-1);
				}
				else if (((ButtonControl)InputKeys.CYCLE_KEY_RIGHT).wasPressedThisFrame)
				{
					SetNextSpawnEnemiesPage(1);
				}
				_ = ((ButtonControl)Keyboard.current.upArrowKey).wasPressedThisFrame;
				if (scrapSpawnMode && ((ButtonControl)Keyboard.current.downArrowKey).wasPressedThisFrame)
				{
					int num = Mathf.CeilToInt((float)GetSpawnableScraps().Count / 10f);
					ControlCompanyPlugin.Instance.logger.LogMessage((object)$"Total scraps: {GetSpawnableScraps().Count()}, final page of scrap: {num}");
					currentSpawnScrapPage++;
					if (currentSpawnScrapPage >= num)
					{
						currentSpawnScrapPage = 0;
					}
				}
				break;
			}
		}

		private void ChangeAudioListener(AudioListener audioListener)
		{
			StartOfRound.Instance.audioListener = audioListener;
		}

		private EntranceTeleport GetMainEntrance(bool getMainEntranceThatIsOutside)
		{
			EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>(false);
			foreach (EntranceTeleport val in array)
			{
				if (val.entranceId != 0)
				{
					continue;
				}
				if (getMainEntranceThatIsOutside)
				{
					if (val.isEntranceToBuilding)
					{
						return val;
					}
				}
				else if (!val.isEntranceToBuilding)
				{
					return val;
				}
			}
			return null;
		}

		private bool IsTargetInside()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			if ((Object)currentTarget != (Object)null)
			{
				return currentTarget.isInsideFactory;
			}
			return false;
		}

		private void OnGUI()
		{
			if (!IsGameStarted() || !showUI)
			{
				return;
			}
			if (!IsHost())
			{
				if (gameStartedTime < 30f)
				{
					UIManager.Instance.RenderNotHostLabel(((InputControl)InputKeys.TOGGLE_UI_KEY).displayName);
				}
			}
			else
			{
				if (inRoundEndPhase || (ConfigManager.Instance.DisableWhileUsingTerminal && GetHostPlayer().inTerminalMenu))
				{
					return;
				}
				switch (currentMode)
				{
				case Mode.ENEMY:
					UIManager.Instance.RenderEnemyControls(((InputControl)InputKeys.ENEMY_PRIMARY_SKILL_BUTTON).shortDisplayName, ((InputControl)InputKeys.ENEMY_SECONDARY_SKILL_BUTTON).shortDisplayName, ((InputControl)InputKeys.ENEMY_TOGGLE_AI_KEY).displayName, ((InputControl)InputKeys.EXIT_KEY).displayName, ((InputControl)InputKeys.HOST_LISTEN_KEY).displayName, currentControlledEnemy, GetHostPlayer());
					break;
				case Mode.HOST:
					UIManager.Instance.RenderHostControls(((InputControl)InputKeys.HOST_GHOST_MODE_KEY).displayName, ((InputControl)InputKeys.CYCLE_KEY_LEFT).displayName, ((InputControl)InputKeys.CYCLE_KEY_RIGHT).displayName, currentTarget, isExtendedModeEnabled, ((InputControl)InputKeys.HOST_GIVE_CREDITS_KEY).displayName, ((InputControl)InputKeys.HOST_TELEPORT_TO_ENTRANCE_KEY).displayName, ((InputControl)InputKeys.TOGGLE_UI_KEY).displayName);
					break;
				case Mode.GHOST:
				{
					bool showEnemyPaging = GetSpawnableEnemies(isGhostIndoors).Count > 12;
					List<IEnumerable<Item>> list = ExtensionMethods.Chunk(GetSpawnableScraps(), 10).ToList();
					List<Item> scraps = ((list.Count > 0) ? list[currentSpawnScrapPage].ToList() : new List<Item>());
					UIManager.Instance.RenderGhostControls(InputKeys.GHOST_SPAWN_ENEMY_KEYS.Select((KeyControl key) => ((InputControl)key).displayName).ToList(), ((InputControl)InputKeys.EXIT_KEY).displayName, ((InputControl)InputKeys.CYCLE_KEY_LEFT).displayName, ((InputControl)InputKeys.CYCLE_KEY_RIGHT).displayName, ((InputControl)InputKeys.HOST_LISTEN_KEY).displayName, showEnemyPaging, GetPagedSpawnableEnemies(), scraps, GetHostPlayer(), scrapSpawnMode);
					break;
				}
				}
			}
		}

		private bool IsHostDead()
		{
			return GetHostPlayer().isPlayerDead;
		}

		private void EnableGhost(bool enable)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			EnableGhost(enable, Vector3.zero);
		}

		private void EnableGhost(bool enable, Vector3 position)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (enable)
			{
				ghost.transform.position = position + new Vector3(0f, 0.5f, 0f);
				ghost.transform.rotation = Quaternion.identity;
				ghost.SetActive(true);
				ChangeAudioListener(ghostController.AudioListener);
				SetNextSpawnEnemiesPage(0);
			}
			else
			{
				ghost.SetActive(false);
			}
		}

		private void EnableHostPlayer(bool enable)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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)
			PlayerControllerB hostPlayer = GetHostPlayer();
			MovementActions movement;
			if (enable)
			{
				if (ConfigManager.Instance.ForcePushToTalkWhileInMonsterMode)
				{
					ResetMicPushToTalk();
				}
				((Behaviour)GetHostPlayer().activeAudioListener).enabled = true;
				movement = hostPlayer.playerActions.Movement;
				((MovementActions)(ref movement)).PingScan.Enable();
				ChangeAudioListener(hostPlayer.activeAudioListener);
				((Behaviour)StartOfRound.Instance.activeCamera).enabled = true;
			}
			else
			{
				if (ConfigManager.Instance.ForcePushToTalkWhileInMonsterMode)
				{
					ForceMicPushToTalk();
				}
				((Behaviour)GetHostPlayer().activeAudioListener).enabled = false;
				movement = hostPlayer.playerActions.Movement;
				((MovementActions)(ref movement)).PingScan.Disable();
				((Behaviour)StartOfRound.Instance.activeCamera).enabled = false;
			}
		}

		private void EnablePlayer2DMics(bool enable, List<PlayerControllerB> players)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			foreach (PlayerControllerB player in players)
			{
				if (player.isHostPlayerObject)
				{
					continue;
				}
				AudioSource currentVoiceChatAudioSource = player.currentVoiceChatAudioSource;
				if (enable)
				{
					if ((Object)currentVoiceChatAudioSource != (Object)null)
					{
						currentVoiceChatAudioSource.spatialBlend = 0f;
					}
					player.currentVoiceChatIngameSettings.set2D = true;
					player.voicePlayerState.Volume = 1f;
				}
				else
				{
					if ((Object)currentVoiceChatAudioSource != (Object)null)
					{
						currentVoiceChatAudioSource.spatialBlend = 1f;
					}
					player.currentVoiceChatIngameSettings.set2D = false;
					player.voicePlayerState.Volume = 0f;
				}
			}
		}

		private void SetNextTargetPlayer(int direction)
		{
			List<PlayerControllerB> alivePlayers = GetAlivePlayers();
			if (alivePlayers.Count == 0)
			{
				SetCurrentTargetToHost();
				ControlCompanyPlugin.Instance.logger.LogMessage((object)"Alive player count is zero");
			}
			else
			{
				currentTargetIndex += direction;
				if (currentTargetIndex >= alivePlayers.Count)
				{
					currentTargetIndex = 0;
				}
				else if (currentTargetIndex < 0)
				{
					currentTargetIndex = alivePlayers.Count - 1;
				}
				currentTargetIndex = Mathf.Clamp(currentTargetIndex, 0, alivePlayers.Count - 1);
				currentTarget = alivePlayers[currentTargetIndex];
			}
			ControlCompanyPlugin.Instance.logger.LogMessage((object)$"Current target index: {currentTargetIndex}");
			ControlCompanyPlugin.Instance.logger.LogMessage((object)("Setting next target to: " + currentTarget?.playerUsername));
		}

		public void SetCurrentTargetToHost()
		{
			currentTargetIndex = 0;
			currentTarget = GetHostPlayer();
			ControlCompanyPlugin.Instance.logger.LogMessage((object)"Setting next target to host");
		}

		private void SetNextSpawnEnemiesPage(int direction)
		{
			List<ControllableEnemy> spawnableEnemies = GetSpawnableEnemies(isGhostIndoors);
			if (spawnableEnemies == null || spawnableEnemies.Count == 0)
			{
				currentSpawnableEnemyList = new List<ControllableEnemy>();
				return;
			}
			if (spawnableEnemies.Count > 12)
			{
				List<IEnumerable<ControllableEnemy>> list = ExtensionMethods.Chunk(spawnableEnemies, 12).ToList();
				currentSpawnEnemiesPage += direction;
				if (currentSpawnEnemiesPage >= list.Count)
				{
					currentSpawnEnemiesPage = 0;
				}
				else if (currentSpawnEnemiesPage < 0)
				{
					currentSpawnEnemiesPage = list.Count - 1;
				}
				currentSpawnEnemiesPage = Mathf.Clamp(currentSpawnEnemiesPage, 0, list.Count - 1);
			}
			else
			{
				currentSpawnEnemiesPage = 0;
			}
			currentSpawnableEnemyList = ExtensionMethods.Chunk(GetSpawnableEnemies(isGhostIndoors), 12).ToList()[currentSpawnEnemiesPage].ToList();
		}

		public List<SpawnableEnemyWithRarity> GetDaytimeEnemies()
		{
			return new List<SpawnableEnemyWithRarity>(GetCurrentLevel().DaytimeEnemies);
		}

		public void StartOfRoundInitialization()
		{
			initialMicPushToTalkSetting = IngamePlayerSettings.Instance.settings.pushToTalk;
			allIndoorEnemies = GetAllIndoorEnemiesAcrossAllMapsList();
			allOutdoorEnemies = GetAllOutdoorEnemiesAcrossAllMapsList();
			indoorEnemiesOfLevel = new List<ControllableEnemy>(from enemy in GetCurrentLevel().Enemies
				select ControllableEnemy.FromSpawnableEnemy(enemy) into x
				where x != null
				select x);
			outdoorEnemiesOfLevel = new List<ControllableEnemy>(from enemy in GetCurrentLevel().OutsideEnemies.Concat(GetCurrentLevel().DaytimeEnemies)
				select ControllableEnemy.FromSpawnableEnemy(enemy) into x
				where x != null
				select x);
			ControllableEnemy maskedEnemy = GetMaskedEnemy();
			indoorEnemiesOfLevel.Add(maskedEnemy);
			outdoorEnemiesOfLevel.Add(maskedEnemy);
			allIndoorEnemies.Add(maskedEnemy);
			allOutdoorEnemies.Add(maskedEnemy);
			ControllableEnemy companyMonsterEnemy = GetCompanyMonsterEnemy();
			if (companyMonsterEnemy != null)
			{
				indoorEnemiesOfLevel.Add(companyMonsterEnemy);
				outdoorEnemiesOfLevel.Add(companyMonsterEnemy);
				allIndoorEnemies.Add(companyMonsterEnemy);
				allOutdoorEnemies.Add(companyMonsterEnemy);
			}
			ControllableEnemy secretEnemy = GetSecretEnemy();
			if (secretEnemy != null)
			{
				indoorEnemiesOfLevel.Insert(0, secretEnemy);
				allIndoorEnemies.Insert(0, secretEnemy);
			}
			indoorEnemiesOfLevel = indoorEnemiesOfLevel.DedupeBy((ControllableEnemy enemy) => enemy.EnemyName).ToList();
			outdoorEnemiesOfLevel = outdoorEnemiesOfLevel.DedupeBy((ControllableEnemy enemy) => enemy.EnemyName).ToList();
			allIndoorEnemies = allIndoorEnemies.DedupeBy((ControllableEnemy enemy) => enemy.EnemyName).ToList();
			allOutdoorEnemies = allOutdoorEnemies.DedupeBy((ControllableEnemy enemy) => enemy.EnemyName).ToList();
			gameStartedTime = 0f;
			SetCurrentTargetToHost();
			ResetToDefault();
			inRoundEndPhase = false;
			ControlCompanyPlugin.Instance.logger.LogMessage((object)"Start of round initialization completed.");
		}

		public void EndOfRoundCleanUp()
		{
			ResetToDefault();
			inRoundEndPhase = true;
			ControlCompanyPlugin.Instance.logger.LogMessage((object)"End of round clean up completed.");
		}

		private void ResetToDefault()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			StartOfRound.Instance.audioListener = GetHostPlayer().activeAudioListener;
			GetHostPlayer().isTypingChat = false;
			currentMode = Mode.HOST;
			if ((Object)ghost != (Object)null)
			{
				Object.Destroy((Object)ghost);
				ghost = null;
			}
			if ((Object)currentControlledEnemy != (Object)null)
			{
				currentControlledEnemy.DestroyAndCleanUp();
			}
			currentSpawnableEnemyList = new List<ControllableEnemy>();
			currentSpawnEnemiesPage = 0;
			EnableHostPlayer(enable: true);
			ControlCompanyPlugin.Instance.logger.LogMessage((object)"Reset to default.");
		}

		public bool IsListeningFromHost()
		{
			return ((ButtonControl)InputKeys.HOST_LISTEN_KEY).isPressed;
		}

		public PlayerControllerB GetHostPlayer()
		{
			return RoundManager.Instance.playersManager.allPlayerObjects[0].GetComponentInChildren<PlayerControllerB>();
		}

		public List<PlayerControllerB> GetDeadPlayers()
		{
			return (from player in GetAllPlayers()
				where player.isPlayerDead
				select player).ToList();
		}

		public List<PlayerControllerB> GetAlivePlayers()
		{
			return (from player in GetAllPlayers()
				where !player.isPlayerDead
				select player).ToList();
		}

		public List<PlayerControllerB> GetAllPlayers()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			List<PlayerControllerB> list = new List<PlayerControllerB>();
			GameObject[] allPlayerObjects = RoundManager.Instance.playersManager.allPlayerObjects;
			for (int i = 0; i < allPlayerObjects.Length; i++)
			{
				PlayerControllerB componentInChildren = allPlayerObjects[i].GetComponentInChildren<PlayerControllerB>();
				if ((Object)componentInChildren != (Object)null && componentInChildren.isPlayerControlled)
				{
					list.Add(componentInChildren);
				}
			}
			return list;
		}

		public bool DoesCurrentLevelExist()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return (Object)GetCurrentLevel() != (Object)null;
		}

		public bool IsGameStarted()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			if ((Object)RoundManager.Instance != (Object)null && (Object)RoundManager.Instance.currentLevel != (Object)null && (Object)GameNetworkManager.Instance != (Object)null && GameNetworkManager.Instance.gameHasStarted && (Object)StartOfRound.Instance != (Object)null)
			{
				return !StartOfRound.Instance.inShipPhase;
			}
			return false;
		}

		public SelectableLevel GetCurrentLevel()
		{
			return RoundManager.Instance.currentLevel;
		}

		public StartOfRound GetPlayersManager()
		{
			return RoundManager.Instance.playersManager;
		}

		private bool IsHost()
		{
			return ((NetworkBehaviour)RoundManager.Instance).IsHost;
		}

		public List<Item> GetSpawnableScraps()
		{
			return StartOfRound.Instance.allItemsList.itemsList;
		}

		public List<ControllableEnemy> GetPagedSpawnableEnemies()
		{
			return currentSpawnableEnemyList;
		}

		public List<ControllableEnemy> GetSpawnableEnemies(bool isIndoor)
		{
			List<ControllableEnemy> list = ((!isIndoor) ? GetSpawnableOutdoorEnemies() : GetSpawnableIndoorEnemies());
			if (list == null || list.Count == 0)
			{
				list = new List<ControllableEnemy>();
			}
			return list;
		}

		public List<ControllableEnemy> GetSpawnableIndoorEnemies()
		{
			if (!allowAllEnemies)
			{
				return GetAllowListedIndoorEnemies();
			}
			return GetIndoorEnemyList();
		}

		public List<ControllableEnemy> GetAllowListedIndoorEnemies()
		{
			return (from enemy in GetIndoorEnemyList()
				where enemy.Allowlisted
				select enemy).ToList();
		}

		public List<ControllableEnemy> GetIndoorEnemyList()
		{
			if (!allowAllEnemies)
			{
				return indoorEnemiesOfLevel;
			}
			return allIndoorEnemies;
		}

		public List<ControllableEnemy> GetAllIndoorEnemiesAcrossAllMapsList()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			HashSet<string> hashSet = new HashSet<string>();
			List<ControllableEnemy> list = new List<ControllableEnemy>();
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				if (!((Object)val != (Object)null))
				{
					continue;
				}
				foreach (SpawnableEnemyWithRarity enemy in val.Enemies)
				{
					if ((Object)enemy.enemyType != (Object)null && !hashSet.Contains(enemy.enemyType.enemyName))
					{
						hashSet.Add(enemy.enemyType.enemyName);
						ControllableEnemy controllableEnemy = ControllableEnemy.FromSpawnableEnemy(enemy);
						if (controllableEnemy != null)
						{
							list.Add(controllableEnemy);
						}
					}
				}
			}
			return list;
		}

		public List<ControllableEnemy> GetSpawnableOutdoorEnemies()
		{
			if (!allowAllEnemies)
			{
				return GetAllowListedOutdoorEnemies();
			}
			return GetOutdoorEnemyList();
		}

		public List<ControllableEnemy> GetAllowListedOutdoorEnemies()
		{
			return (from enemy in GetOutdoorEnemyList()
				where enemy.Allowlisted
				select enemy).ToList();
		}

		public List<ControllableEnemy> GetOutdoorEnemyList()
		{
			if (!allowAllEnemies)
			{
				return outdoorEnemiesOfLevel;
			}
			return allOutdoorEnemies;
		}

		public List<ControllableEnemy> GetAllOutdoorEnemiesAcrossAllMapsList()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			if (GetCurrentLevel().OutsideEnemies.Count == 0)
			{
				return new List<ControllableEnemy>();
			}
			HashSet<string> hashSet = new HashSet<string>();
			List<ControllableEnemy> list = new List<ControllableEnemy>();
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			foreach (SelectableLevel val in levels)
			{
				if (!((Object)val != (Object)null))
				{
					continue;
				}
				foreach (SpawnableEnemyWithRarity item in val.OutsideEnemies.Concat(val.DaytimeEnemies))
				{
					if ((Object)item.enemyType != (Object)null && !hashSet.Contains(item.enemyType.enemyName))
					{
						hashSet.Add(item.enemyType.enemyName);
						ControllableEnemy controllableEnemy = ControllableEnemy.FromSpawnableEnemy(item);
						if (controllableEnemy != null)
						{
							list.Add(controllableEnemy);
						}
					}
				}
			}
			return list;
		}

		public ControllableEnemy GetMaskedEnemy()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			for (int i = 0; i < levels.Length; i++)
			{
				foreach (SpawnableEnemyWithRarity enemy in levels[i].Enemies)
				{
					EnemyType enemyType = enemy.enemyType;
					object obj;
					if ((Object)(object)enemyType == (Object)null)
					{
						obj = null;
					}
					else
					{
						GameObject enemyPrefab = enemyType.enemyPrefab;
						obj = (((Object)(object)enemyPrefab != (Object)null) ? enemyPrefab.GetComponent<EnemyAI>() : null);
					}
					EnemyAI val = (EnemyAI)obj;
					if ((Object)val != (Object)null && ((object)val).GetType() == typeof(MaskedPlayerEnemy))
					{
						return ControllableEnemy.FromSpawnableEnemy(enemy);
					}
				}
			}
			return null;
		}

		private ControllableEnemy GetSecretEnemy()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			Object[] array = Resources.FindObjectsOfTypeAll(typeof(EnemyAI));
			for (int i = 0; i < array.Length; i++)
			{
				EnemyAI val = (EnemyAI)array[i];
				if (((object)val).GetType() == typeof(TestEnemy))
				{
					return ControllableEnemy.FromEnemyAI(val);
				}
			}
			return null;
		}

		private GameObject SpawnScrap(Item scrap, Vector3 position)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			GameObject obj = Object.Instantiate<GameObject>(scrap.spawnPrefab, position, Quaternion.identity);
			GrabbableObject componentInChildren = obj.GetComponentInChildren<GrabbableObject>();
			((Component)componentInChildren).transform.rotation = Quaternion.Euler(componentInChildren.itemProperties.restingRotation);
			obj.GetComponentInChildren<NetworkObject>().Spawn(true);
			return obj;
		}

		private EnemyController SpawnControllableEnemy(ControllableEnemy controllableEnemy, Vector3 position, Quaternion rotation)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0072: 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)
			Vector3 val = (controllableEnemy.OverrideEnemySpawnLocation ? controllableEnemy.EnemySpawnLocationOverride : (position + new Vector3(0f, 0.5f, 0f)));
			GameObject val2 = (controllableEnemy.OverrideEnemyPrefab ? controllableEnemy.EnemyGameObject : Object.Instantiate<GameObject>(controllableEnemy.EnemyPrefab, val, Quaternion.identity));
			if (!controllableEnemy.OverrideEnemyPrefab)
			{
				val2.GetComponentInChildren<NetworkObject>().Spawn(true);
			}
			GameObject val3 = new GameObject("enemy_controller");
			val3.transform.position = val;
			val3.transform.rotation = rotation;
			if (controllableEnemy.CreateAndAttachEnemyControllerFunc == null)
			{
				throw new Exception("Controllable enemy does not have a function defined to create and attach an enemy controller!");
			}
			EnemyController enemyController = controllableEnemy.CreateAndAttachEnemyControllerFunc(val2, val3);
			enemyController.InitializeEnemyController(GetHostPlayer().playerActions, val2);
			enemyController.EnableLight(isGhostIndoors);
			ChangeAudioListener(enemyController.AudioListener);
			return enemyController;
		}

		private GameObject GetTurretPrefab()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			for (int i = 0; i < levels.Length; i++)
			{
				SpawnableMapObject[] spawnableMapObjects = levels[i].spawnableMapObjects;
				foreach (SpawnableMapObject val in spawnableMapObjects)
				{
					object obj;
					if (val == null)
					{
						obj = null;
					}
					else
					{
						GameObject prefabToSpawn = val.prefabToSpawn;
						obj = (((Object)(object)prefabToSpawn != (Object)null) ? prefabToSpawn.GetComponentInChildren<Turret>() : null);
					}
					if ((Object)obj != (Object)null)
					{
						return val.prefabToSpawn;
					}
				}
			}
			return null;
		}

		private EnemyController SpawnControllableTurret(Vector3 position, Quaternion rotation)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_002c: 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_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)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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)
			GameObject turretPrefab = GetTurretPrefab();
			if ((Object)turretPrefab == (Object)null)
			{
				ControlCompanyPlugin.Instance.logger.LogDebug((object)"Cannot find turret prefab in current level");
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(turretPrefab, position, rotation);
			val.GetComponentInChildren<NetworkObject>().Spawn(true);
			GameObject val2 = new GameObject("enemy_controller");
			val2.transform.position = position + new Vector3(0f, 0.5f, 0f);
			val2.transform.rotation = rotation;
			TurretEnemyController turretEnemyController = val2.AddComponent<TurretEnemyController>();
			turretEnemyController.InitializeEnemyController(GetHostPlayer().playerActions, val);
			turretEnemyController.EnableLight(enable: true);
			return turretEnemyController;
		}

		private ControllableEnemy GetCompanyMonsterEnemy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			DepositItemsDesk val = Object.FindObjectOfType<DepositItemsDesk>();
			if ((Object)val == (Object)null)
			{
				return null;
			}
			GameObject val2 = GameObject.Find("BellDinger");
			return new ControllableEnemy
			{
				EnemyName = "Company Monster",
				OverrideEnemyPrefab = true,
				EnemyGameObject = ((Component)val).gameObject,
				Allowlisted = true,
				OverrideEnemySpawnLocation = true,
				EnemySpawnLocationOverride = (((Object)val2 != (Object)null) ? val2.transform.position : ((Component)val).transform.position),
				CreateAndAttachEnemyControllerFunc = (GameObject enemyGameObject, GameObject enemyController) => enemyController.AddComponent<CompanyMonsterController>()
			};
		}

		private DissonanceComms GetMic()
		{
			return StartOfRound.Instance.voiceChatModule;
		}

		private void ForceMicPushToTalk()
		{
			IngamePlayerSettings.Instance.settings.pushToTalk = true;
		}

		private void ResetMicPushToTalk()
		{
			IngamePlayerSettings.Instance.settings.pushToTalk = initialMicPushToTalkSetting;
		}
	}
	internal class CustomPlayerController : MonoBehaviour
	{
		public enum CameraMode
		{
			THIRD_PERSON,
			FIRST_PERSON
		}

		protected bool isInitialized;

		protected bool hasControl;

		protected bool canMove;

		protected bool canRotate;

		protected bool canJump;

		protected CameraMode camMode;

		protected CharacterController characterController;

		protected GameObject cameraGameObjectParent;

		protected GameObject cameraGameObject;

		protected Camera camera;

		protected Light light;

		protected PlayerActions playerActions;

		protected DoorOpener doorOpener;

		private AudioListener audioListener;

		private float runSpeed = 9f;

		private float walkSpeed = 7f;

		private float camDistance = -3.5f;

		private float camHeight = 2f;

		private float gravity = -20f;

		private float jumpHeight = 4.5f;

		private float currentYVelocity;

		private List<Collider> collidersToIgnore = new List<Collider>();

		public float RunSpeed
		{
			get
			{
				return runSpeed;
			}
			set
			{
				runSpeed = value;
			}
		}

		public float WalkSpeed
		{
			get
			{
				return walkSpeed;
			}
			set
			{
				walkSpeed = value;
			}
		}

		public float Gravity
		{
			get
			{
				return gravity;
			}
			set
			{
				gravity = value;
			}
		}

		public AudioListener AudioListener
		{
			get
			{
				return audioListener;
			}
			set
			{
				audioListener = value;
			}
		}

		public bool IsInitialized
		{
			get
			{
				return isInitialized;
			}
			set
			{
				isInitialized = value;
			}
		}

		public void Initialize(PlayerActions playerActions, CameraMode camMode, List<Collider> collidersToIgnore = null)
		{
			if (!isInitialized)
			{
				this.playerActions = playerActions;
				this.camMode = camMode;
				if (collidersToIgnore != null)
				{
					this.collidersToIgnore = collidersToIgnore;
				}
				characterController = InitializeCharacterController();
				camera = InitializeCamera();
				light = InitializeLight(((Component)camera).gameObject);
				doorOpener = ((Component)this).gameObject.AddComponent<DoorOpener>();
				EnableControl(enable: true);
				isInitialized = true;
			}
		}

		public void EnableLight(bool enable)
		{
			((Behaviour)light).enabled = enable;
		}

		public void EnableCamera(bool enable)
		{
			((Behaviour)camera).enabled = enable;
		}

		public void ToggleLight()
		{
			((Behaviour)light).enabled = !((Behaviour)light).enabled;
		}

		public void EnableControl(bool enable)
		{
			hasControl = enable;
			canMove = enable;
			canRotate = enable;
			canJump = enable;
		}

		public bool IsMoving()
		{
			//IL_0006: 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)
			Vector3 velocity = characterController.velocity;
			return ((Vector3)(ref velocity)).sqrMagnitude > 0f;
		}

		public void SetCamHeight(float camHeight)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			this.camHeight = camHeight;
			cameraGameObjectParent.transform.localPosition = new Vector3(0f, camHeight, 0f);
		}

		public void SetCamDistance(float camDistance)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			this.camDistance = camDistance;
			cameraGameObject.transform.localPosition = new Vector3(0f, 0f, (camMode == CameraMode.THIRD_PERSON) ? camDistance : 0f);
		}

		protected virtual void LateUpdate()
		{
			if (isInitialized && hasControl)
			{
				if (canMove)
				{
					Move();
				}
				if (canRotate)
				{
					Rotate();
				}
				if (((ButtonControl)InputKeys.CONTROLLER_USE_KEY).wasPressedThisFrame)
				{
					doorOpener.DetectAndOpenDoors(3f);
				}
			}
		}

		protected virtual Vector3 MoveInput()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			return Vector2.op_Implicit(IngamePlayerSettings.Instance.playerInput.actions.FindAction("Move", false).ReadValue<Vector2>());
		}

		protected virtual bool IsSprinting()
		{
			return IngamePlayerSettings.Instance.playerInput.actions.FindAction("Sprint", false).ReadValue<float>() > 0f;
		}

		protected virtual void Move()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_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_0036: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: 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)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			bool flag = IsSprinting();
			Vector3 val = MoveInput();
			Vector3 val2 = ((Component)this).transform.right * val.x;
			Vector3 val3 = ((Component)this).transform.forward * val.y;
			bool isGrounded = characterController.isGrounded;
			if (isGrounded && currentYVelocity < 0f)
			{
				currentYVelocity = 0f;
			}
			if (canJump && isGrounded && ((ButtonControl)InputKeys.CONTROLLER_JUMP_KEY).wasPressedThisFrame)
			{
				currentYVelocity += Mathf.Sqrt(jumpHeight * (0f - gravity));
			}
			currentYVelocity += gravity * Time.deltaTime;
			characterController.Move(((val2 + val3) * (flag ? runSpeed : walkSpeed) + new Vector3(0f, currentYVelocity, 0f)) * Time.deltaTime);
		}

		protected virtual void Rotate()
		{
			//IL_0006: 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)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			MovementActions movement = playerActions.Movement;
			Vector2 val = ((MovementActions)(ref movement)).Look.ReadValue<Vector2>() * 0.008f * (float)IngamePlayerSettings.Instance.settings.lookSensitivity;
			if (IngamePlayerSettings.Instance.settings.invertYAxis)
			{
				val.y *= -1f;
			}
			((Component)this).transform.Rotate(new Vector3(0f, val.x, 0f));
			cameraGameObjectParent.transform.Rotate(new Vector3(0f - val.y, 0f, 0f));
		}

		private Light InitializeLight(GameObject lightParent)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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: 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)
			GameObject val = new GameObject("controller_light");
			val.transform.SetParent(lightParent.transform);
			val.transform.localPosition = new Vector3(0f, 0.5f, 0f);
			val.transform.localRotation = Quaternion.identity;
			Light obj = val.AddComponent<Light>();
			obj.range = 15f;
			obj.intensity = 225f;
			obj.cullingMask = -1;
			return obj;
		}

		private CharacterController InitializeCharacterController()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			CharacterController controller = ((Component)this).gameObject.AddComponent<CharacterController>();
			((Collider)(object)controller).SetExcludeLayers(((LayerMask)(ref Constants.PLAYER_LOS_LAYERMASK)).value | ((LayerMask)(ref Constants.ITERACTABLE_OBJ_LAYERMASK)).value | ((LayerMask)(ref Constants.ENEMIES_LAYERMASK)).value | ((LayerMask)(ref Constants.PROPS_LAYERMASK)).value | ((LayerMask)(ref Constants.PLAYER_RAGDOLL_LAYERMASK)).value);
			controller.center = new Vector3(0f, 0.55f, 0f);
			controller.height = 0.4f;
			ControlCenter.Instance.GetAllPlayers().ForEach(delegate(PlayerControllerB p)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Expected O, but got Unknown
				if ((Object)p != (Object)null)
				{
					((Component)p).GetComponentsInChildren<Collider>().ToList().ForEach(delegate(Collider c)
					{
						//IL_0007: Unknown result type (might be due to invalid IL or missing references)
						//IL_0011: Expected O, but got Unknown
						Physics.IgnoreCollision(c, (Collider)controller);
					});
				}
			});
			if (collidersToIgnore.Count() > 0)
			{
				foreach (Collider item in collidersToIgnore)
				{
					Physics.IgnoreCollision(item, (Collider)controller);
				}
			}
			controller.slopeLimit = 60f;
			controller.stepOffset = 0.4f;
			return controller;
		}

		private Camera InitializeCamera()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("controller_cam_parent");
			val.transform.SetParent(((Component)this).transform);
			val.transform.localRotation = Quaternion.identity;
			val.transform.localPosition = new Vector3(0f, camHeight, 0f);
			GameObject val2 = new GameObject("controller_cam");
			val2.transform.SetParent(val.transform);
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localPosition = new Vector3(0f, 0f, (camMode == CameraMode.THIRD_PERSON) ? camDistance : 0f);
			Camera val3 = val2.AddComponent<Camera>();
			audioListener = val2.AddComponent<AudioListener>();
			cameraGameObject = val2;
			cameraGameObjectParent = val;
			Camera gameplayCamera = ControlCenter.Instance.GetHostPlayer().gameplayCamera;
			val3.cullingMask = gameplayCamera.cullingMask;
			val3.farClipPlane = gameplayCamera.farClipPlane;
			HDAdditionalCameraData component = ((Component)gameplayCamera).gameObject.GetComponent<HDAdditionalCameraData>();
			CopyHDCameraData(val3, component);
			return val3;
		}

		private void CopyHDCameraData(Camera cam, HDAdditionalCameraData dataToCopy)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)dataToCopy != (Object)null)
			{
				HDAdditionalCameraData val = ((Component)cam).gameObject.GetComponent<HDAdditionalCameraData>();
				if ((Object)val == (Object)null)
				{
					val = ((Component)cam).gameObject.AddComponent<HDAdditionalCameraData>();
				}
				if ((Object)val != (Object)null)
				{
					val.customRenderingSettings = true;
					val.renderingPathCustomFrameSettingsOverrideMask.mask = dataToCopy.renderingPathCustomFrameSettingsOverrideMask.mask;
					SetCustomPass(val, dataToCopy);
					SetVolumetricFog(val, dataToCopy);
					SetLOD(val, dataToCopy);
					SetAliasing(val, dataToCopy);
					SetShadowQuality(val, dataToCopy);
				}
			}
		}

		private void SetCustomPass(HDAdditionalCameraData camData, HDAdditionalCameraData dataToCopy)
		{
			((FrameSettings)(ref camData.renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)6, ((FrameSettings)(ref dataToCopy.renderingPathCustomFrameSettings)).IsEnabled((FrameSettingsField)6));
		}

		private void SetVolumetricFog(HDAdditionalCameraData camData, HDAdditionalCameraData dataToCopy)
		{
			((FrameSettings)(ref camData.renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)28, ((FrameSettings)(ref dataToCopy.renderingPathCustomFrameSettings)).IsEnabled((FrameSettingsField)28));
		}

		private void SetLOD(HDAdditionalCameraData camData, HDAdditionalCameraData dataToCopy)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			camData.renderingPathCustomFrameSettings.lodBiasMode = dataToCopy.renderingPathCustomFrameSettings.lodBiasMode;
			camData.renderingPathCustomFrameSettings.lodBias = dataToCopy.renderingPathCustomFrameSettings.lodBias;
		}

		private void SetAliasing(HDAdditionalCameraData camData, HDAdditionalCameraData dataToCopy)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			camData.antialiasing = dataToCopy.antialiasing;
		}

		private void SetShadowQuality(HDAdditionalCameraData camData, HDAdditionalCameraData dataToCopy)
		{
			((FrameSettings)(ref camData.renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)20, ((FrameSettings)(ref dataToCopy.renderingPathCustomFrameSettings)).IsEnabled((FrameSettingsField)20));
		}
	}
	internal class DoorOpener : MonoBehaviour
	{
		public void DetectAndOpenDoors(float range)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, range);
			for (int i = 0; i < array.Length; i++)
			{
				DoorLock componentInChildren = ((Component)array[i]).GetComponentInChildren<DoorLock>();
				if ((Object)componentInChildren != (Object)null)
				{
					OpenDoor(componentInChildren);
				}
			}
		}

		public void OpenDoor(DoorLock doorLock)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)doorLock != (Object)null && !doorLock.GetFieldValue<bool>("isDoorOpened"))
			{
				doorLock.OpenDoorAsEnemyServerRpc();
				((Component)doorLock).gameObject.GetComponent<AnimatedObjectTrigger>().TriggerAnimationNonPlayer(false, true, false);
			}
		}
	}
	internal class EnemyAIController : EnemyController
	{
		private EnemyAI enemyAI;

		private NavMeshAgent enemyAIAgent;

		private float originalAgentAngularSpeed;

		private float originalAgentSpeed;

		private Vector3 enemyPositionOffset = Vector3.zero;

		private bool useLerpRotation;

		public EnemyAI EnemyAI => enemyAI;

		public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0086: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			if (!isInitialized)
			{
				List<Collider> list = enemyGameObject.GetComponentsInChildren<Collider>().ToList();
				Initialize(playerActions, CameraMode.THIRD_PERSON, list);
				CharacterController collider = characterController;
				((Collider)(object)collider).SetExcludeLayers(((Collider)(object)collider).GetExcludeLayers() & ~((LayerMask)(ref Constants.ITERACTABLE_OBJ_LAYERMASK)).value);
				enemyAI = GetEnemyAIFromEnemyGameObject(enemyGameObject);
				if ((Object)enemyAI == (Object)null)
				{
					throw new Exception("Enemy gameobject does not have EnemyAI script attached.");
				}
				((Component)enemyAI).gameObject.LogLayer();
				enemyGameObject.transform.position = ((Component)this).transform.position;
				enemyGameObject.transform.rotation = ((Component)this).transform.rotation;
				base.enemyGameObject = enemyGameObject;
				enemyAIAgent = enemyGameObject.GetComponentInChildren<NavMeshAgent>();
				if ((Object)enemyAIAgent != (Object)null)
				{
					originalAgentAngularSpeed = enemyAIAgent.angularSpeed;
					originalAgentSpeed = enemyAIAgent.speed;
				}
				ConfigureEnemyAttributes(enemyAI);
				EnableAIControl(enabled: false);
			}
		}

		protected override void LateUpdate()
		{
			//IL_00ed: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if (!isInitialized)
			{
				return;
			}
			base.LateUpdate();
			if (!isAIControlled)
			{
				if (!CanControlEnemy())
				{
					return;
				}
				if (controlEnemyMovement)
				{
					enemyGameObject.transform.position = ((Component)this).transform.position + enemyPositionOffset;
				}
				if (!controlEnemyRotation || lockEnemyRotationInput)
				{
					return;
				}
				Vector3 velocity = characterController.velocity;
				if (((Vector3)(ref velocity)).sqrMagnitude > 0.1f)
				{
					if (useLerpRotation)
					{
						enemyGameObject.transform.rotation = Quaternion.Lerp(enemyGameObject.transform.rotation, ((Component)this).transform.rotation, 8f * Time.deltaTime);
					}
					else
					{
						enemyGameObject.transform.rotation = ((Component)this).transform.rotation;
					}
				}
			}
			else
			{
				((Component)this).transform.position = enemyGameObject.transform.position;
			}
		}

		protected EnemyAI GetEnemyAIFromEnemyGameObject(GameObject enemyObj)
		{
			return enemyObj.GetComponentInChildren<EnemyAI>();
		}

		private void ConfigureEnemyAttributes(EnemyAI enemyAI)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			EnemyAttributes enemyAttributes = enemyAI.GetEnemyAttributes();
			base.WalkSpeed = enemyAttributes.WalkSpeed;
			base.RunSpeed = enemyAttributes.RunSpeed;
			SetCamDistance(enemyAttributes.CamDistance);
			SetCamHeight(enemyAttributes.CamHeight);
			controlEnemyRotation = enemyAttributes.PlayerControlsRotation;
			controlEnemyMovement = true;
			enemyPositionOffset = enemyAttributes.EnemyPositionOffset;
			useLerpRotation = enemyAttributes.UseLerpRotation;
		}

		protected virtual void ConfigureEnemyHandicap(EnemyAI enemyAI)
		{
		}

		public override bool CanControlEnemy()
		{
			return !enemyAI.isEnemyDead;
		}

		protected override void Move()
		{
			if (!enemyAI.isEnemyDead)
			{
				base.Move();
			}
		}

		public void SwitchAIState(int stateIndex)
		{
			CheckInitialized();
			if (!isAIControlled)
			{
				enemyAI.SwitchToBehaviourState(stateIndex);
			}
		}

		protected override void ToggleAIControlTrue()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)enemyAIAgent != (Object)null)
			{
				enemyAIAgent.angularSpeed = originalAgentAngularSpeed;
				enemyAIAgent.speed = originalAgentSpeed;
				enemyAIAgent.isStopped = false;
				enemyAIAgent.Warp(enemyGameObject.transform.position);
				enemyAIAgent.updatePosition = true;
			}
		}

		protected override void ToggleAIControlFalse()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			if ((Object)enemyAI != (Object)null)
			{
				try
				{
					enemyAI.ChangeOwnershipOfEnemy(ControlCenter.Instance.GetHostPlayer().actualClientId);
				}
				catch (Exception ex)
				{
					ControlCompanyPlugin.Instance.logger.LogDebug((object)("Cannot give host control: " + ex.Message));
				}
			}
			if ((Object)enemyAIAgent != (Object)null)
			{
				enemyAIAgent.angularSpeed = 0f;
				enemyAIAgent.speed = 0f;
				enemyAIAgent.isStopped = true;
				enemyAIAgent.updatePosition = false;
			}
			((Component)this).transform.SetParent((Transform)null);
		}

		protected override bool ShouldDestroyEnemyGameObjectOnCleanUp()
		{
			return !enemyAI.isEnemyDead;
		}

		public override string GetSecondarySkillName()
		{
			return "Secondary Skill";
		}

		protected override void UseSecondarySkillAction()
		{
			enemyAI.SwitchToBehaviourState(1);
		}

		protected override void EnableAIControl(bool enabled)
		{
			base.EnableAIControl(enabled);
			canMove = !isAIControlled;
		}
	}
	internal class EnemyController : CustomPlayerController
	{
		protected GameObject enemyGameObject;

		protected bool isAIControlled;

		protected bool controlEnemyRotation = true;

		protected bool controlEnemyMovement = true;

		protected bool lockEnemyRotationInput;

		public bool IsAIControlled => isAIControlled;

		public virtual void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject)
		{
		}

		public virtual bool CanControlEnemy()
		{
			return true;
		}

		public void SetLockEnemyRotation(bool lockEnemyRotationInput)
		{
			this.lockEnemyRotationInput = lockEnemyRotationInput;
		}

		public void UsePrimarySkill()
		{
			CheckInitialized();
			if (!isAIControlled)
			{
				UsePrimarySkillAction();
			}
		}

		protected virtual void UsePrimarySkillAction()
		{
		}

		public void ReleasePrimarySkill()
		{
			CheckInitialized();
			if (!isAIControlled)
			{
				ReleasePrimarySkillAction();
			}
		}

		protected virtual void ReleasePrimarySkillAction()
		{
		}

		public void UseSecondarySkill()
		{
			CheckInitialized();
			if (!isAIControlled)
			{
				UseSecondarySkillAction();
			}
		}

		protected virtual void UseSecondarySkillAction()
		{
		}

		public void ReleaseSecondarySkill()
		{
			CheckInitialized();
			if (!isAIControlled)
			{
				ReleaseSecondarySkillAction();
			}
		}

		protected virtual void ReleaseSecondarySkillAction()
		{
		}

		protected virtual void EnableAIControl(bool enabled)
		{
			CheckInitialized();
			isAIControlled = enabled;
			ControlCompanyPlugin.Instance.logger.LogMessage((object)$"Enable AI control: {enabled}");
			if (IsAIControlled)
			{
				ToggleAIControlTrue();
			}
			else
			{
				ToggleAIControlFalse();
			}
		}

		protected virtual void ToggleAIControlTrue()
		{
		}

		protected virtual void ToggleAIControlFalse()
		{
		}

		public virtual void ToggleAIControl()
		{
			CheckInitialized();
			isAIControlled = !isAIControlled;
			EnableAIControl(isAIControlled);
		}

		public virtual void DestroyAndCleanUp()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (ShouldDestroyEnemyGameObjectOnCleanUp())
			{
				Object.Destroy((Object)enemyGameObject);
			}
			Object.Destroy((Object)((Component)this).gameObject);
		}

		protected virtual bool ShouldDestroyEnemyGameObjectOnCleanUp()
		{
			return true;
		}

		public virtual string GetPrimarySkillName()
		{
			return "";
		}

		public virtual string GetSecondarySkillName()
		{
			return "";
		}

		protected void CheckInitialized()
		{
			if (!isInitialized)
			{
				throw new Exception("Not initialized yet.");
			}
		}

		protected virtual void OnControllerColliderHit(ControllerColliderHit hit)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			DoorLock component = hit.gameObject.GetComponent<DoorLock>();
			if ((Object)component != (Object)null)
			{
				doorOpener.OpenDoor(component);
			}
		}
	}
}
namespace ControlCompany.Core.UI
{
	public class UIInstruction
	{
		public string InputKey { get; set; }

		public string ActionText { get; set; }
	}
	internal class UIManager : MonoBehaviour
	{
		private const float GUI_LABEL_HEIGHT = 36f;

		private const float GUI_LABEL_WIDTH = 750f;

		private const float GUI_PADDING = 32f;

		private const int GUI_FONT_SIZE = 28;

		private const FontStyle GUI_FONT_WEIGHT = (FontStyle)0;

		public static UIManager Instance;

		private void Awake()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)Instance == (Object)null)
			{
				Instance = this;
			}
		}

		public void RenderNotHostLabel(string toggleUIKey)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)3,
				fontSize = 24,
				fontStyle = (FontStyle)0
			};
			val.normal.textColor = Color.red;
			RenderTextTopLeftCorner("Not hosting. ControlCompany mod is disabled. Press " + toggleUIKey + " to hide.", 0f, val, 1000f);
		}

		public void RenderEnemyControls(string primaryKey, string secondaryKey, string aiControlKey, string exitKey, string listenFromHostKey, EnemyController enemyController, PlayerControllerB hostPlayer)
		{
			string primarySkillName = enemyController.GetPrimarySkillName();
			string secondarySkillName = enemyController.GetSecondarySkillName();
			List<UIInstruction> list = new List<UIInstruction>();
			if (enemyController.IsAIControlled)
			{
				list.Add(new UIInstruction
				{
					InputKey = aiControlKey,
					ActionText = "Take control"
				});
			}
			else
			{
				if (!Utility.IsNullOrWhiteSpace(primarySkillName))
				{
					list.Add(new UIInstruction
					{
						InputKey = primaryKey,
						ActionText = primarySkillName
					});
				}
				if (!Utility.IsNullOrWhiteSpace(secondarySkillName))
				{
					list.Add(new UIInstruction
					{
						InputKey = secondaryKey,
						ActionText = secondarySkillName
					});
				}
				list.Add(new UIInstruction
				{
					InputKey = aiControlKey,
					ActionText = "AI control"
				});
			}
			list.Add(new UIInstruction
			{
				InputKey = exitKey,
				ActionText = "Exit"
			});
			RenderPlayerStatus(hostPlayer, listenFromHostKey);
			float height = 0f;
			height = RenderEnemyStatus(enemyController, height);
			RenderEnemySkills(list, height);
		}

		public void RenderHostControls(string ghostModeKey, string cycleLeftKey, string cycleRightKey, PlayerControllerB currentTarget, bool isExtendedModeEnabled, string creditsKey, string entranceTeleportKey, string toggleUIKey)
		{
			List<UIInstruction> list = new List<UIInstruction>();
			list.Add(new UIInstruction
			{
				InputKey = ghostModeKey,
				ActionText = "Ghost mode"
			});
			list.Add(new UIInstruction
			{
				InputKey = cycleLeftKey + "/" + cycleRightKey,
				ActionText = "Change target"
			});
			list.Add(new UIInstruction
			{
				InputKey = toggleUIKey,
				ActionText = "Hide UI"
			});
			if (isExtendedModeEnabled)
			{
				list.Add(new UIInstruction
				{
					InputKey = creditsKey,
					ActionText = "Give credits"
				});
				list.Add(new UIInstruction
				{
					InputKey = entranceTeleportKey,
					ActionText = "Teleport to entrance"
				});
			}
			RenderHostControlList(list, currentTarget);
		}

		public void RenderGhostControls(List<string> enemySpawnKeys, string exitKey, string cycleLeftKey, string cycleRightKey, string listenFromHostKey, bool showEnemyPaging, List<ControllableEnemy> enemies, List<Item> scraps, PlayerControllerB hostPlayer, bool scrapSpawnMode)
		{
			List<UIInstruction> list = new List<UIInstruction>();
			if (!scrapSpawnMode)
			{
				if (enemies != null && enemies.Count > 0)
				{
					if (showEnemyPaging)
					{
						list.Add(new UIInstruction
						{
							InputKey = cycleLeftKey + "/" + cycleRightKey,
							ActionText = "Change page"
						});
					}
					for (int i = 0; i < enemies.Count && i < enemySpawnKeys.Count; i++)
					{
						_ = enemies[i].EnemyPrefab;
						list.Add(new UIInstruction
						{
							InputKey = enemySpawnKeys[i],
							ActionText = "Control " + enemies[i].EnemyName
						});
					}
				}
			}
			else
			{
				for (int j = 0; j < scraps.Count && j < enemySpawnKeys.Count; j++)
				{
					list.Add(new UIInstruction
					{
						InputKey = enemySpawnKeys[j],
						ActionText = "Spawn " + scraps[j].itemName
					});
				}
			}
			list.Add(new UIInstruction
			{
				InputKey = exitKey,
				ActionText = "Exit"
			});
			RenderPlayerStatus(hostPlayer, listenFromHostKey);
			RenderGhostControlList(list);
		}

		private void RenderGhostControlList(List<UIInstruction> ghostControls)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0030: Expected O, but got Unknown
			if (ghostControls.Count <= 0)
			{
				return;
			}
			GUIStyle style = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)5,
				fontSize = 28,
				fontStyle = (FontStyle)0
			};
			float num = 0f;
			foreach (UIInstruction ghostControl in ghostControls)
			{
				RenderTextTopRightCorner(ghostControl.InputKey + ": " + ghostControl.ActionText, num, style);
				num += 36f;
			}
		}

		private float RenderMicStatus(float height, PlayerControllerB hostPlayer)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_00aa: 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)
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)3,
				fontSize = 28,
				fontStyle = (FontStyle)0
			};
			float num = height;
			if (IngamePlayerSettings.Instance.settings.micEnabled && (Object)StartOfRound.Instance.voiceChatModule != (Object)null)
			{
				if (!StartOfRound.Instance.voiceChatModule.IsMuted)
				{
					val.normal.textColor = Color.green;
					RenderTextTopLeftCorner(string.Format("{0} mic enabled", hostPlayer.isPlayerDead ? "Dead" : "Player"), num, val);
				}
				else
				{
					val.normal.textColor = Color.red;
					RenderTextTopLeftCorner(string.Format("{0} mic disabled (push to talk)", hostPlayer.isPlayerDead ? "Dead" : "Player"), num, val);
				}
				num += 36f;
			}
			return num;
		}

		private float RenderPlayerStatus(PlayerControllerB hostPlayer, string listenFromHostKey)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0046: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected O, but got Unknown
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			GUIStyle val = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)3,
				fontSize = 28,
				fontStyle = (FontStyle)0
			};
			if (hostPlayer.isPlayerDead)
			{
				val.normal.textColor = Color.red;
			}
			else
			{
				val.normal.textColor = Color.green;
			}
			float num = 0f;
			RenderTextTopLeftCorner(string.Format("Player status: {0}", hostPlayer.isPlayerDead ? "Dead" : "Alive"), num, val);
			num += 36f;
			if (!hostPlayer.isPlayerDead)
			{
				GUIStyle val2 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)3,
					fontSize = 28,
					fontStyle = (FontStyle)0
				};
				bool flag = !HostIsNearOtherPlayers(hostPlayer);
				if (flag)
				{
					val2.normal.textColor = Color.green;
				}
				else
				{
					val2.normal.textColor = Color.red;
				}
				RenderTextTopLeftCorner(string.Format("Player proximity: {0}", flag ? "Alone" : "Near others"), num, val2);
				num += 36f;
				GUIStyle val3 = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)3,
					fontSize = 28,
					fontStyle = (FontStyle)0
				};
				bool flag2 = ControlCenter.Instance.IsListeningFromHost();
				if (flag2)
				{
					val3.normal.textColor = Color.green;
				}
				else
				{
					val3.normal.textColor = Color.red;
				}
				RenderTextTopLeftCorner(string.Format("Listening from host: {0}", flag2 ? "Yes" : ("No (hold " + listenFromHostKey + ")")), num, val3);
				num += 36f;
			}
			return num + RenderMicStatus(num, hostPlayer);
		}

		private void RenderHostControlList(List<UIInstruction> hostControls, PlayerControllerB currentTarget)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0030: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			if (hostControls.Count <= 0)
			{
				return;
			}
			GUIStyle style = new GUIStyle(GUI.skin.label)
			{
				alignment = (TextAnchor)5,
				fontSize = 28,
				fontStyle = (FontStyle)0
			};
			float num = 0f;
			if ((Object)currentTarget != (Object)null)
			{
				RenderTextTopRightCorner("Spawn target: " + currentTarget.playerUsername, num, style);
				num += 36f;
			}
			foreach (UIInstruction hostControl in hostControls)
			{
				RenderTextTopRightCorner(hostControl.InputKey + ": " + hostControl.ActionText, num, style);
				num += 36f;
			}
		}

		private float RenderEnemyStatus(EnemyController enemyController, float height)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0030: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			float num = height;
			if (enemyController.IsAIControlled)
			{
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)5,
					fontSize = 28,
					fontStyle = (FontStyle)0
				};
				val.normal.textColor = Color.red;
				RenderTextTopRightCorner("AI controlled", num, val);
				num += 36f;
			}
			return num;
		}

		private float RenderEnemySkills(List<UIInstruction> playerEnemyControls, float height)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0031: Expected O, but got Unknown
			float num = height;
			if (playerEnemyControls.Count > 0)
			{
				GUIStyle style = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)5,
					fontSize = 28,
					fontStyle = (FontStyle)0
				};
				foreach (UIInstruction playerEnemyControl in playerEnemyControls)
				{
					RenderTextTopRightCorner(playerEnemyControl.InputKey + ": " + playerEnemyControl.ActionText, num, style);
					num += 36f;
				}
			}
			return num;
		}

		private void RenderTextMiddle(string text, float yPos, GUIStyle style)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			GUI.Label(new Rect((float)Screen.width / 2f - 375f, yPos + 32f, 750f, 36f), text, style);
		}

		private void RenderTextTopRightCorner(string text, float yPos, GUIStyle style)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			GUI.Label(new Rect((float)Screen.width - 750f - 32f, yPos + 32f, 750f, 36f), text, style);
		}

		private void RenderTextTopLeftCorner(string text, float yPos, GUIStyle style, float widthOverride = -1f)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			GUI.Label(new Rect(32f, yPos + 32f, (widthOverride > 0f) ? widthOverride : 750f, 36f), text, style);
		}

		private bool HostIsNearOtherPlayers(PlayerControllerB hostPlayer)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_008b: Expected O, but got Unknown
			//IL_0094: 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)
			try
			{
				if (hostPlayer.Call("NearOtherPlayers", hostPlayer, 17f) is bool result)
				{
					return result;
				}
			}
			catch (Exception ex)
			{
				ControlCompanyPlugin.Instance.logger.LogDebug((object)("NearOtherPlayers failed, using distance fallback: " + ex.Message));
			}
			foreach (PlayerControllerB alivePlayer in ControlCenter.Instance.GetAlivePlayers())
			{
				if ((Object)alivePlayer != (Object)hostPlayer && Vector3.Distance(((Component)alivePlayer).transform.position, ((Component)hostPlayer).transform.position) <= 17f)
				{
					return true;
				}
			}
			return false;
		}
	}
}
namespace ControlCompany.Core.Input
{
	public static class InputKeys
	{
		public static KeyControl EXIT_KEY = Key((Keyboard k) => k.escapeKey);

		public static KeyControl EXTENDED_MODE_KEY = Key((Keyboard k) => k.digit0Key);

		public static KeyControl TOGGLE_UI_KEY = Key((Keyboard k) => k.uKey);

		public static KeyControl CYCLE_KEY_LEFT = Key((Keyboard k) => k.oKey);

		public static KeyControl CYCLE_KEY_RIGHT = Key((Keyboard k) => k.pKey);

		public static KeyControl HOST_LISTEN_KEY = Key((Keyboard k) => k.leftAltKey);

		public static KeyControl HOST_GHOST_MODE_KEY = Key((Keyboard k) => k.f1Key);

		public static KeyControl HOST_GIVE_CREDITS_KEY = Key((Keyboard k) => k.digit8Key);

		public static KeyControl HOST_TELEPORT_TO_ENTRANCE_KEY = Key((Keyboard k) => k.digit9Key);

		public static KeyControl GHOST_SPAWN_ENEMY_1 = Key((Keyboard k) => k.f1Key);

		public static KeyControl GHOST_SPAWN_ENEMY_2 = Key((Keyboard k) => k.f2Key);

		public static KeyControl GHOST_SPAWN_ENEMY_3 = Key((Keyboard k) => k.f3Key);

		public static KeyControl GHOST_SPAWN_ENEMY_4 = Key((Keyboard k) => k.f4Key);

		public static KeyControl GHOST_SPAWN_ENEMY_5 = Key((Keyboard k) => k.f5Key);

		public static KeyControl GHOST_SPAWN_ENEMY_6 = Key((Keyboard k) => k.f6Key);

		public static KeyControl GHOST_SPAWN_ENEMY_7 = Key((Keyboard k) => k.f7Key);

		public static KeyControl GHOST_SPAWN_ENEMY_8 = Key((Keyboard k) => k.f8Key);

		public static KeyControl GHOST_SPAWN_ENEMY_9 = Key((Keyboard k) => k.f9Key);

		public static KeyControl GHOST_SPAWN_ENEMY_10 = Key((Keyboard k) => k.f10Key);

		public static KeyControl GHOST_SPAWN_ENEMY_11 = Key((Keyboard k) => k.f11Key);

		public static KeyControl GHOST_SPAWN_ENEMY_12 = Key((Keyboard k) => k.f12Key);

		public static List<KeyControl> GHOST_SPAWN_ENEMY_KEYS = new List<KeyControl>();

		public static KeyControl ENEMY_TOGGLE_AI_KEY = Key((Keyboard k) => k.f1Key);

		public static ButtonControl ENEMY_PRIMARY_SKILL_BUTTON;

		public static ButtonControl ENEMY_SECONDARY_SKILL_BUTTON;

		public static KeyControl LOCK_ENEMY_ROTATION_KEY;

		public static KeyControl ENEMY_TOGGLE_LIGHT_KEY;

		public static KeyControl CONTROLLER_USE_KEY;

		public static KeyControl CONTROLLER_JUMP_KEY;

		private static KeyControl Key(Func<Keyboard, KeyControl> pick)
		{
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return null;
			}
			return pick(current);
		}

		static InputKeys()
		{
			Mouse current = Mouse.current;
			ENEMY_PRIMARY_SKILL_BUTTON = ((current != null) ? current.leftButton : null);
			Mouse current2 = Mouse.current;
			ENEMY_SECONDARY_SKILL_BUTTON = ((current2 != null) ? current2.rightButton : null);