Decompiled source of testmodding v1.0.1

item/controltest.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("controltest")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("controltest")]
[assembly: AssemblyTitle("controltest")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace ControlCompany
{
	[BepInPlugin("ControlCompany.ControlCompany", "ControlCompany", "1.2.1")]
	public class ControlCompanyPlugin : BaseUnityPlugin
	{
		private const string modGUID = "ControlCompany.ControlCompany";

		private const string modName = "ControlCompany";

		private const string modVersion = "1.2.1";

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

		public static ControlCompanyPlugin Instance;

		internal ManualLogSource logger;

		private bool isInitialized = false;

		private bool ranInitializationScripts = false;

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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()
		{
			harmony.PatchAll(typeof(ControlCompanyPlugin));
			harmony.PatchAll(typeof(HUDManagerPatch));
			harmony.PatchAll(typeof(StartOfRoundPatch));
			harmony.PatchAll(typeof(PlayerControllerBPatch));
			harmony.PatchAll(typeof(EnemyAIPatch));
			harmony.PatchAll(typeof(TimeOfDayPatch));
			harmony.PatchAll(typeof(SoundManagerPatch));
			harmony.PatchAll(typeof(LobbyListPatch));
		}
	}
}
namespace ControlCompany.Core
{
	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 = 0;

		private PlayerControllerB currentTarget;

		private Mode currentMode = Mode.HOST;

		private bool allowAllEnemies = false;

		private bool initialMicPushToTalkSetting = false;

		private bool isExtendedModeEnabled = false;

		private bool scrapSpawnMode = false;

		private int currentSpawnScrapPage = 0;

		private const int scrapSpawnPageSize = 10;

		private int currentSpawnEnemiesPage = 0;

		private const int spawnEnemiesPageSize = 12;

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

		private bool loadedConfig = false;

		private bool showUI = true;

		private float gameStartedTime = 0f;

		private bool inRoundEndPhase = false;

		private bool isGhostIndoors = false;

		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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Expected O, but got Unknown
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Expected O, but got Unknown
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Expected O, but got Unknown
			if (!IsGameStarted())
			{
				return;
			}
			if (((ButtonControl)InputKeys.TOGGLE_UI_KEY).wasPressedThisFrame)
			{
				showUI = !showUI;
			}
			gameStartedTime += Time.deltaTime;
			if (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 != 0)
			{
				GetHostPlayer().isTypingChat = true;
			}
			if (IsListeningFromHost() && !IsHostDead() && currentMode != 0)
			{
				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_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Expected O, but got Unknown
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			if (!IsGameStarted() || 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 val2 = Object.FindObjectOfType<Terminal>();
					val2.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);
				}
				if (((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);
			EntranceTeleport[] array2 = array;
			foreach (EntranceTeleport val in array2)
			{
				if (val.entranceId != 0)
				{
					continue;
				}
				if (getMainEntranceThatIsOutside)
				{
					if (val.isEntranceToBuilding)
					{
						return val;
					}
				}
				else if (!val.isEntranceToBuilding)
				{
					return val;
				}
			}
			return null;
		}

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

		private void OnGUI()
		{
			if (!IsGameStarted() || !showUI || 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_0003: Unknown result type (might be due to invalid IL or missing references)
			EnableGhost(enable, Vector3.zero);
		}

		private void EnableGhost(bool enable, Vector3 position)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB hostPlayer = GetHostPlayer();
			MovementActions val;
			if (enable)
			{
				if (ConfigManager.Instance.ForcePushToTalkWhileInMonsterMode)
				{
					ResetMicPushToTalk();
				}
				((Behaviour)GetHostPlayer().activeAudioListener).enabled = true;
				MovementActions movement = hostPlayer.playerActions.Movement;
				val = movement;
				((MovementActions)(ref val)).PingScan.Enable();
				ChangeAudioListener(hostPlayer.activeAudioListener);
				((Behaviour)StartOfRound.Instance.activeCamera).enabled = true;
			}
			else
			{
				if (ConfigManager.Instance.ForcePushToTalkWhileInMonsterMode)
				{
					ForceMicPushToTalk();
				}
				((Behaviour)GetHostPlayer().activeAudioListener).enabled = false;
				MovementActions movement = hostPlayer.playerActions.Movement;
				val = movement;
				((MovementActions)(ref val)).PingScan.Disable();
				((Behaviour)StartOfRound.Instance.activeCamera).enabled = false;
			}
		}

		private void EnablePlayer2DMics(bool enable, List<PlayerControllerB> players)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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
			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()
		{
			allIndoorEnemies = GetAllIndoorEnemiesAcrossAllMapsList();
			allOutdoorEnemies = GetAllOutdoorEnemiesAcrossAllMapsList();
			indoorEnemiesOfLevel = new List<ControllableEnemy>(GetCurrentLevel().Enemies.Select((SpawnableEnemyWithRarity enemy) => ControllableEnemy.FromSpawnableEnemy(enemy)));
			outdoorEnemiesOfLevel = new List<ControllableEnemy>(GetCurrentLevel().OutsideEnemies.Select((SpawnableEnemyWithRarity enemy) => ControllableEnemy.FromSpawnableEnemy(enemy)));
			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;
			initialMicPushToTalkSetting = IngamePlayerSettings.Instance.settings.pushToTalk;
			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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			return (Object)GetCurrentLevel() != (Object)null;
		}

		public bool IsGameStarted()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			return (Object)RoundManager.Instance != (Object)null && (Object)RoundManager.Instance.currentLevel != (Object)null && (Object)GameNetworkManager.Instance != (Object)null && GameNetworkManager.Instance.gameHasStarted && (Object)StartOfRound.Instance != (Object)null && !StartOfRound.Instance.inShipPhase;
		}

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

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

		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()
		{
			return allowAllEnemies ? GetIndoorEnemyList() : GetAllowListedIndoorEnemies();
		}

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

		public List<ControllableEnemy> GetIndoorEnemyList()
		{
			return allowAllEnemies ? allIndoorEnemies : indoorEnemiesOfLevel;
		}

		public List<ControllableEnemy> GetAllIndoorEnemiesAcrossAllMapsList()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			HashSet<string> hashSet = new HashSet<string>();
			List<ControllableEnemy> list = new List<ControllableEnemy>();
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			SelectableLevel[] array = levels;
			foreach (SelectableLevel val in array)
			{
				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);
						list.Add(ControllableEnemy.FromSpawnableEnemy(enemy));
					}
				}
			}
			return list;
		}

		public List<ControllableEnemy> GetSpawnableOutdoorEnemies()
		{
			return allowAllEnemies ? GetOutdoorEnemyList() : GetAllowListedOutdoorEnemies();
		}

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

		public List<ControllableEnemy> GetOutdoorEnemyList()
		{
			return allowAllEnemies ? allOutdoorEnemies : outdoorEnemiesOfLevel;
		}

		public List<ControllableEnemy> GetAllOutdoorEnemiesAcrossAllMapsList()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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;
			SelectableLevel[] array = levels;
			foreach (SelectableLevel val in array)
			{
				if (!((Object)val != (Object)null))
				{
					continue;
				}
				foreach (SpawnableEnemyWithRarity outsideEnemy in val.OutsideEnemies)
				{
					if ((Object)outsideEnemy.enemyType != (Object)null && !hashSet.Contains(outsideEnemy.enemyType.enemyName))
					{
						hashSet.Add(outsideEnemy.enemyType.enemyName);
						list.Add(ControllableEnemy.FromSpawnableEnemy(outsideEnemy));
					}
				}
			}
			return list;
		}

		public ControllableEnemy GetMaskedEnemy()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			SelectableLevel[] array = levels;
			foreach (SelectableLevel val in array)
			{
				foreach (SpawnableEnemyWithRarity enemy in val.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 val2 = (EnemyAI)obj;
					if ((Object)val2 != (Object)null && ((object)val2).GetType() == typeof(MaskedPlayerEnemy))
					{
						return ControllableEnemy.FromSpawnableEnemy(enemy);
					}
				}
			}
			return null;
		}

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

		private GameObject SpawnScrap(Item scrap, Vector3 position)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(scrap.spawnPrefab, position, Quaternion.identity);
			GrabbableObject componentInChildren = val.GetComponentInChildren<GrabbableObject>();
			((Component)componentInChildren).transform.rotation = Quaternion.Euler(componentInChildren.itemProperties.restingRotation);
			val.GetComponentInChildren<NetworkObject>().Spawn(true);
			return val;
		}

		private EnemyController SpawnControllableEnemy(ControllableEnemy controllableEnemy, Vector3 position, Quaternion rotation)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_001e: 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_003a: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = (controllableEnemy.OverrideEnemySpawnLocation ? controllableEnemy.EnemySpawnLocationOverride : (position + new Vector3(0f, 0.5f, 0f)));
			GameObject val2 = (GameObject)(controllableEnemy.OverrideEnemyPrefab ? ((object)controllableEnemy.EnemyGameObject) : ((object)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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			SelectableLevel[] levels = StartOfRound.Instance.levels;
			SelectableLevel[] array = levels;
			foreach (SelectableLevel val in array)
			{
				SpawnableMapObject[] spawnableMapObjects = val.spawnableMapObjects;
				SpawnableMapObject[] array2 = spawnableMapObjects;
				foreach (SpawnableMapObject val2 in array2)
				{
					object obj;
					if (val2 == null)
					{
						obj = null;
					}
					else
					{
						GameObject prefabToSpawn = val2.prefabToSpawn;
						obj = (((Object)(object)prefabToSpawn != (Object)null) ? prefabToSpawn.GetComponentInChildren<Turret>() : null);
					}
					if ((Object)obj != (Object)null)
					{
						return val2.prefabToSpawn;
					}
				}
			}
			return null;
		}

		private EnemyController SpawnControllableTurret(Vector3 position, Quaternion rotation)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0036: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0082: 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)
			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 DoorOpener : MonoBehaviour
	{
		public void DetectAndOpenDoors(float range)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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 EnemyController : CustomPlayerController
	{
		protected GameObject enemyGameObject;

		protected bool isAIControlled = false;

		protected bool controlEnemyRotation = true;

		protected bool controlEnemyMovement = true;

		protected bool lockEnemyRotationInput = false;

		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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			DoorLock component = hit.gameObject.GetComponent<DoorLock>();
			if ((Object)component != (Object)null)
			{
				doorOpener.OpenDoor(component);
			}
		}
	}
	internal class EnemyAIController : EnemyController
	{
		private EnemyAI enemyAI;

		private NavMeshAgent enemyAIAgent;

		private float originalAgentAngularSpeed;

		private float originalAgentSpeed;

		private Vector3 enemyPositionOffset = Vector3.zero;

		private bool useLerpRotation = false;

		public EnemyAI EnemyAI => enemyAI;

		public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject)
		{
			//IL_0031: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			if (!isInitialized)
			{
				List<Collider> list = enemyGameObject.GetComponentsInChildren<Collider>().ToList();
				Initialize(playerActions, CameraMode.THIRD_PERSON, list);
				CharacterController val = characterController;
				((Collider)val).excludeLayers = LayerMask.op_Implicit(LayerMask.op_Implicit(((Collider)val).excludeLayers) | (1 << LayerMask.op_Implicit(Constants.ITERACTABLE_OBJ_LAYERMASK)));
				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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0097: 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_009d: 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_0113: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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;
				Vector3 val = velocity;
				if (((Vector3)(ref val)).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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0059: 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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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 CustomPlayerController : MonoBehaviour
	{
		public enum CameraMode
		{
			THIRD_PERSON,
			FIRST_PERSON
		}

		protected bool isInitialized = false;

		protected bool hasControl = false;

		protected bool canMove = false;

		protected bool canRotate = false;

		protected bool canJump = false;

		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 ToggleLight()
		{
			((Behaviour)light).enabled = !((Behaviour)light).enabled;
		}

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

		public bool IsMoving()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_000e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 velocity = characterController.velocity;
			Vector3 val = velocity;
			return ((Vector3)(ref val)).sqrMagnitude > 0f;
		}

		public void SetCamHeight(float camHeight)
		{
			//IL_001e: 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_002d: 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 void Move()
		{
			//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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			bool flag = IngamePlayerSettings.Instance.playerInput.actions.FindAction("Sprint", false).ReadValue<float>() > 0f;
			Vector3 val = Vector2.op_Implicit(IngamePlayerSettings.Instance.playerInput.actions.FindAction("Move", false).ReadValue<Vector2>());
			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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_000e: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			MovementActions movement = playerActions.Movement;
			MovementActions val = movement;
			Vector2 val2 = ((MovementActions)(ref val)).Look.ReadValue<Vector2>() * 0.008f * (float)IngamePlayerSettings.Instance.settings.lookSensitivity;
			if (IngamePlayerSettings.Instance.settings.invertYAxis)
			{
				val2.y *= -1f;
			}
			((Component)this).transform.Rotate(new Vector3(0f, val2.x, 0f));
			cameraGameObjectParent.transform.Rotate(new Vector3(0f - val2.y, 0f, 0f));
		}

		private Light InitializeLight(GameObject lightParent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			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 val2 = val.AddComponent<Light>();
			val2.range = 15f;
			val2.intensity = 225f;
			val2.cullingMask = -1;
			return val2;
		}

		private CharacterController InitializeCharacterController()
		{
			//IL_001e: 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_0032: 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_0047: 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_005c: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			CharacterController controller = ((Component)this).gameObject.AddComponent<CharacterController>();
			((Collider)controller).excludeLayers = LayerMask.op_Implicit(LayerMask.op_Implicit(GetLayerMask(LayerMask.op_Implicit(Constants.PLAYER_LOS_LAYERMASK))) | LayerMask.op_Implicit(GetLayerMask(LayerMask.op_Implicit(Constants.ITERACTABLE_OBJ_LAYERMASK))) | LayerMask.op_Implicit(GetLayerMask(LayerMask.op_Implicit(Constants.ENEMIES_LAYERMASK))) | LayerMask.op_Implicit(GetLayerMask(LayerMask.op_Implicit(Constants.PROPS_LAYERMASK))) | LayerMask.op_Implicit(GetLayerMask(LayerMask.op_Implicit(Constants.PLAYER_RAGDOLL_LAYERMASK))));
			controller.center = new Vector3(0f, 0.55f, 0f);
			controller.height = 0.4f;
			ControlCenter.Instance.GetAllPlayers().ForEach(delegate(PlayerControllerB p)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Expected O, but got Unknown
				if ((Object)p != (Object)null)
				{
					((Component)p).GetComponentsInChildren<Collider>().ToList().ForEach(delegate(Collider c)
					{
						//IL_0008: Unknown result type (might be due to invalid IL or missing references)
						//IL_0012: 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;
			static LayerMask GetLayerMask(int layer)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: 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)
				return LayerMask.op_Implicit(1 << layer);
			}
		}

		private Camera InitializeCamera()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0024: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_0073: 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)
			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_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0063: 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)
			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)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			FrameSettings renderingPathCustomFrameSettings = camData.renderingPathCustomFrameSettings;
			FrameSettings renderingPathCustomFrameSettings2 = dataToCopy.renderingPathCustomFrameSettings;
			((FrameSettings)(ref renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)6, ((FrameSettings)(ref renderingPathCustomFrameSettings2)).IsEnabled((FrameSettingsField)6));
		}

		private void SetVolumetricFog(HDAdditionalCameraData camData, HDAdditionalCameraData dataToCopy)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			FrameSettings renderingPathCustomFrameSettings = camData.renderingPathCustomFrameSettings;
			FrameSettings renderingPathCustomFrameSettings2 = dataToCopy.renderingPathCustomFrameSettings;
			((FrameSettings)(ref renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)28, ((FrameSettings)(ref renderingPathCustomFrameSettings2)).IsEnabled((FrameSettingsField)28));
		}

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

		private void SetAliasing(HDAdditionalCameraData camData, HDAdditionalCameraData dataToCopy)
		{
			//IL_0003: 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)
			camData.antialiasing = dataToCopy.antialiasing;
		}

		private void SetShadowQuality(HDAdditionalCameraData camData, HDAdditionalCameraData dataToCopy)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			FrameSettings renderingPathCustomFrameSettings = camData.renderingPathCustomFrameSettings;
			FrameSettings renderingPathCustomFrameSettings2 = dataToCopy.renderingPathCustomFrameSettings;
			((FrameSettings)(ref renderingPathCustomFrameSettings)).SetEnabled((FrameSettingsField)20, ((FrameSettings)(ref renderingPathCustomFrameSettings2)).IsEnabled((FrameSettingsField)20));
		}
	}
}
namespace ControlCompany.Core.Config
{
	internal class ConfigManager : MonoBehaviour
	{
		public static ConfigManager Instance;

		private bool isInitialized;

		private bool loadedConfig = false;

		private const string KEYBIND_CONFIG = "Keybinds";

		private const string KEYBIND_CONFIG_HOST_MODE = "Keybinds.PlayerMode";

		private const string KEYBIND_CONFIG_GHOST_MODE = "Keybinds.GhostMode";

		private const string KEYBIND_CONFIG_ENEMY_MODE = "Keybinds.MonsterMode";

		private const string GENERAL_CONIG = "General";

		private bool forcePushToTalkWhileInMonsterMode = true;

		private bool disableModForSelf = false;

		private bool useEnemySpawningBehaviour = false;

		private bool disableWhileUsingTerminal = true;

		public bool ForcePushToTalkWhileInMonsterMode => forcePushToTalkWhileInMonsterMode;

		public bool DisableModForSelf => disableModForSelf;

		public bool UseEnemySpawningBehaviour => useEnemySpawningBehaviour;

		public bool DisableWhileUsingTerminal => disableWhileUsingTerminal;

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

		private void Update()
		{
			if (!loadedConfig && ((BaseUnityPlugin)ControlCompanyPlugin.Instance).Config != null)
			{
				loadedConfig = true;
				ControlCompanyPlugin.Instance.logger.LogInfo((object)"Initial keybind load");
				LoadPlayerConfig(reload: false);
			}
		}

		public void LoadPlayerConfig(bool reload)
		{
			ConfigFile config = ((BaseUnityPlugin)ControlCompanyPlugin.Instance).Config;
			if (config != null)
			{
				if (reload)
				{
					config.Reload();
				}
				LoadConfig(config);
			}
		}

		private void LoadConfig(ConfigFile config)
		{
			ControlCompanyPlugin.Instance.logger.LogInfo((object)"Loading config");
			useEnemySpawningBehaviour = config.Bind<bool>("General", "use_enemy_spawning_behaviour", false, (ConfigDescription)null).Value;
			disableWhileUsingTerminal = config.Bind<bool>("General", "disable_while_using_terminal", true, (ConfigDescription)null).Value;
			disableModForSelf = config.Bind<bool>("General", "disable_mod_for_self", false, (ConfigDescription)null).Value;
			forcePushToTalkWhileInMonsterMode = config.Bind<bool>("General", "force_push_to_talk_in_monster_mode", true, (ConfigDescription)null).Value;
			ConfigEntry<string> keyEntry = config.Bind<string>("Keybinds", "extended_mode_key", "0", (ConfigDescription)null);
			ConfigEntry<string> keyEntry2 = config.Bind<string>("Keybinds", "exit_mode_key", "esc", (ConfigDescription)null);
			ConfigEntry<string> keyEntry3 = config.Bind<string>("Keybinds", "open_door", "e", (ConfigDescription)null);
			ConfigEntry<string> keyEntry4 = config.Bind<string>("Keybinds", "toggle_ui", "u", (ConfigDescription)null);
			ConfigEntry<string> keyEntry5 = config.Bind<string>("Keybinds", "cycle_left_key", "o", (ConfigDescription)null);
			ConfigEntry<string> keyEntry6 = config.Bind<string>("Keybinds", "cycle_right_key", "p", (ConfigDescription)null);
			ConfigEntry<string> keyEntry7 = config.Bind<string>("Keybinds", "listen_from_player", "alt", (ConfigDescription)null);
			InputKeys.CONTROLLER_USE_KEY = GetKeyControlFromConfig(keyEntry3, InputKeys.CONTROLLER_USE_KEY);
			InputKeys.EXTENDED_MODE_KEY = GetKeyControlFromConfig(keyEntry, InputKeys.EXTENDED_MODE_KEY);
			InputKeys.EXIT_KEY = GetKeyControlFromConfig(keyEntry2, InputKeys.EXIT_KEY);
			InputKeys.TOGGLE_UI_KEY = GetKeyControlFromConfig(keyEntry4, InputKeys.TOGGLE_UI_KEY);
			InputKeys.CYCLE_KEY_LEFT = GetKeyControlFromConfig(keyEntry5, InputKeys.CYCLE_KEY_LEFT);
			InputKeys.CYCLE_KEY_RIGHT = GetKeyControlFromConfig(keyEntry6, InputKeys.CYCLE_KEY_RIGHT);
			InputKeys.HOST_LISTEN_KEY = GetKeyControlFromConfig(keyEntry7, InputKeys.HOST_LISTEN_KEY);
			ConfigEntry<string> keyEntry8 = config.Bind<string>("Keybinds.PlayerMode", "ghost_mode_key", "f1", (ConfigDescription)null);
			InputKeys.HOST_GHOST_MODE_KEY = GetKeyControlFromConfig(keyEntry8, InputKeys.HOST_GHOST_MODE_KEY);
			ConfigEntry<string> keyEntry9 = config.Bind<string>("Keybinds.PlayerMode", "extended_teleport_to_entrance_key", "9", (ConfigDescription)null);
			ConfigEntry<string> keyEntry10 = config.Bind<string>("Keybinds.PlayerMode", "extended_give_credits_key", "8", (ConfigDescription)null);
			InputKeys.HOST_TELEPORT_TO_ENTRANCE_KEY = GetKeyControlFromConfig(keyEntry9, InputKeys.HOST_TELEPORT_TO_ENTRANCE_KEY);
			InputKeys.HOST_GIVE_CREDITS_KEY = GetKeyControlFromConfig(keyEntry10, InputKeys.HOST_GIVE_CREDITS_KEY);
			ConfigEntry<string> keyEntry11 = config.Bind<string>("Keybinds.GhostMode", "jump", "space", (ConfigDescription)null);
			InputKeys.CONTROLLER_JUMP_KEY = GetKeyControlFromConfig(keyEntry11, InputKeys.CONTROLLER_JUMP_KEY);
			ConfigEntry<string> keyEntry12 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_1", "f1", (ConfigDescription)null);
			ConfigEntry<string> keyEntry13 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_2", "f2", (ConfigDescription)null);
			ConfigEntry<string> keyEntry14 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_3", "f3", (ConfigDescription)null);
			ConfigEntry<string> keyEntry15 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_4", "f4", (ConfigDescription)null);
			ConfigEntry<string> keyEntry16 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_5", "f5", (ConfigDescription)null);
			ConfigEntry<string> keyEntry17 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_6", "f6", (ConfigDescription)null);
			ConfigEntry<string> keyEntry18 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_7", "f7", (ConfigDescription)null);
			ConfigEntry<string> keyEntry19 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_8", "f8", (ConfigDescription)null);
			ConfigEntry<string> keyEntry20 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_9", "f9", (ConfigDescription)null);
			ConfigEntry<string> keyEntry21 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_10", "f10", (ConfigDescription)null);
			ConfigEntry<string> keyEntry22 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_11", "f11", (ConfigDescription)null);
			ConfigEntry<string> keyEntry23 = config.Bind<string>("Keybinds.GhostMode", "control_enemy_12", "f12", (ConfigDescription)null);
			InputKeys.GHOST_SPAWN_ENEMY_1 = GetKeyControlFromConfig(keyEntry12, InputKeys.GHOST_SPAWN_ENEMY_1);
			InputKeys.GHOST_SPAWN_ENEMY_2 = GetKeyControlFromConfig(keyEntry13, InputKeys.GHOST_SPAWN_ENEMY_2);
			InputKeys.GHOST_SPAWN_ENEMY_3 = GetKeyControlFromConfig(keyEntry14, InputKeys.GHOST_SPAWN_ENEMY_3);
			InputKeys.GHOST_SPAWN_ENEMY_4 = GetKeyControlFromConfig(keyEntry15, InputKeys.GHOST_SPAWN_ENEMY_4);
			InputKeys.GHOST_SPAWN_ENEMY_5 = GetKeyControlFromConfig(keyEntry16, InputKeys.GHOST_SPAWN_ENEMY_5);
			InputKeys.GHOST_SPAWN_ENEMY_6 = GetKeyControlFromConfig(keyEntry17, InputKeys.GHOST_SPAWN_ENEMY_6);
			InputKeys.GHOST_SPAWN_ENEMY_7 = GetKeyControlFromConfig(keyEntry18, InputKeys.GHOST_SPAWN_ENEMY_7);
			InputKeys.GHOST_SPAWN_ENEMY_8 = GetKeyControlFromConfig(keyEntry19, InputKeys.GHOST_SPAWN_ENEMY_8);
			InputKeys.GHOST_SPAWN_ENEMY_9 = GetKeyControlFromConfig(keyEntry20, InputKeys.GHOST_SPAWN_ENEMY_9);
			InputKeys.GHOST_SPAWN_ENEMY_10 = GetKeyControlFromConfig(keyEntry21, InputKeys.GHOST_SPAWN_ENEMY_10);
			InputKeys.GHOST_SPAWN_ENEMY_11 = GetKeyControlFromConfig(keyEntry22, InputKeys.GHOST_SPAWN_ENEMY_11);
			InputKeys.GHOST_SPAWN_ENEMY_12 = GetKeyControlFromConfig(keyEntry23, InputKeys.GHOST_SPAWN_ENEMY_12);
			InputKeys.GHOST_SPAWN_ENEMY_KEYS = new List<KeyControl>
			{
				InputKeys.GHOST_SPAWN_ENEMY_1,
				InputKeys.GHOST_SPAWN_ENEMY_2,
				InputKeys.GHOST_SPAWN_ENEMY_3,
				InputKeys.GHOST_SPAWN_ENEMY_4,
				InputKeys.GHOST_SPAWN_ENEMY_5,
				InputKeys.GHOST_SPAWN_ENEMY_6,
				InputKeys.GHOST_SPAWN_ENEMY_7,
				InputKeys.GHOST_SPAWN_ENEMY_8,
				InputKeys.GHOST_SPAWN_ENEMY_9,
				InputKeys.GHOST_SPAWN_ENEMY_10,
				InputKeys.GHOST_SPAWN_ENEMY_11,
				InputKeys.GHOST_SPAWN_ENEMY_12
			};
			ConfigEntry<string> keyEntry24 = config.Bind<string>("Keybinds.MonsterMode", "toggle_ai_key", "f1", (ConfigDescription)null);
			InputKeys.ENEMY_TOGGLE_AI_KEY = GetKeyControlFromConfig(keyEntry24, InputKeys.ENEMY_TOGGLE_AI_KEY);
			ConfigEntry<string> keyEntry25 = config.Bind<string>("Keybinds.MonsterMode", "toggle_light", "l", (ConfigDescription)null);
			InputKeys.ENEMY_TOGGLE_LIGHT_KEY = GetKeyControlFromConfig(keyEntry25, InputKeys.ENEMY_TOGGLE_LIGHT_KEY);
			ControlCompanyPlugin.Instance.logger.LogInfo((object)"Done loading keybinds");
		}

		private KeyControl GetKeyControlFromConfig(ConfigEntry<string> keyEntry, KeyControl defaultKey)
		{
			try
			{
				KeyControl val = Keyboard.current.FindKeyOnCurrentKeyboardLayout(keyEntry.Value);
				if (val != null)
				{
					return val;
				}
				ControlCompanyPlugin.Instance.logger.LogWarning((object)$"Cannot rebind key for {((ConfigEntryBase)keyEntry).Definition.Key} to {keyEntry.Value}: Cannot find key {((ConfigEntryBase)keyEntry).Definition.Key} on keyboard layout. Using default key ${defaultKey}");
				return defaultKey;
			}
			catch (Exception ex)
			{
				ControlCompanyPlugin.Instance.logger.LogWarning((object)$"Cannot rebind key for {((ConfigEntryBase)keyEntry).Definition.Key} to {keyEntry.Value}: {ex.Message}. Using default key ${defaultKey}");
				return defaultKey;
			}
		}
	}
	public class EnemyAttributes
	{
		public float WalkSpeed { get; set; } = 5f;


		public float RunSpeed { get; set; } = 7f;


		public bool PlayerControlsRotation { get; set; } = true;


		public float CamHeight { get; set; } = 2f;


		public float CamDistance { get; set; } = -3.5f;


		public string EnemyName { get; set; } = "";


		public Vector3 EnemyPositionOffset { get; set; } = Vector3.zero;


		public bool UseLerpRotation { get; set; } = true;

	}
	internal static class EnemyConfiguration
	{
		public static HashSet<Type> ALLOWLISTED_ENEMIES = new HashSet<Type>
		{
			typeof(BlobAI),
			typeof(NutcrackerEnemyAI),
			typeof(HoarderBugAI),
			typeof(CrawlerAI),
			typeof(PufferAI),
			typeof(CentipedeAI),
			typeof(JesterAI),
			typeof(ForestGiantAI),
			typeof(BaboonBirdAI),
			typeof(FlowermanAI),
			typeof(MaskedPlayerEnemy),
			typeof(SpringManAI),
			typeof(SandWormAI),
			typeof(MouthDogAI)
		};

		public static HashSet<Type> EXPERIMENTAL_ENEMIES = new HashSet<Type>();

		public const float DEFAULT_WALK_SPEED = 5f;

		public const float DEFAULT_RUN_SPEED = 7f;

		public const float DEFAULT_CAM_DISTANCE = -3.5f;

		public const float DEFAULT_CAM_HEIGHT = 2f;

		public const bool DEFAULT_PLAYER_CONTROLS_ROTATION = true;

		public static Dictionary<Type, EnemyAttributes> ENEMY_ATTRIBUTES = new Dictionary<Type, EnemyAttributes>
		{
			{
				typeof(BlobAI),
				new EnemyAttributes
				{
					WalkSpeed = 1f,
					RunSpeed = 2f,
					PlayerControlsRotation = false,
					EnemyName = "Blob"
				}
			},
			{
				typeof(CrawlerAI),
				new EnemyAttributes
				{
					WalkSpeed = 6f,
					RunSpeed = 12f,
					EnemyName = "Thumper"
				}
			},
			{
				typeof(JesterAI),
				new EnemyAttributes
				{
					WalkSpeed = 4f,
					RunSpeed = 6f,
					EnemyName = "Jester"
				}
			},
			{
				typeof(ForestGiantAI),
				new EnemyAttributes
				{
					WalkSpeed = 6f,
					RunSpeed = 8f,
					CamDistance = -7f,
					CamHeight = 10f,
					EnemyName = "Forest Keeper"
				}
			},
			{
				typeof(MouthDogAI),
				new EnemyAttributes
				{
					WalkSpeed = 3f,
					RunSpeed = 7f,
					CamDistance = -5f,
					CamHeight = 5f,
					EnemyName = "Eyeless Dog"
				}
			},
			{
				typeof(FlowermanAI),
				new EnemyAttributes
				{
					EnemyName = "Bracken",
					RunSpeed = 8f
				}
			},
			{
				typeof(PufferAI),
				new EnemyAttributes
				{
					EnemyName = "Spore Lizard"
				}
			},
			{
				typeof(HoarderBugAI),
				new EnemyAttributes
				{
					EnemyName = "Hoarding Bug"
				}
			},
			{
				typeof(CentipedeAI),
				new EnemyAttributes
				{
					EnemyName = "Snare Flea",
					CamHeight = 1.5f,
					CamDistance = -3f
				}
			},
			{
				typeof(SpringManAI),
				new EnemyAttributes
				{
					EnemyName = "Coil-Head",
					WalkSpeed = 5f,
					RunSpeed = 6f
				}
			},
			{
				typeof(SandSpiderAI),
				new EnemyAttributes
				{
					EnemyName = "Bunker Spider"
				}
			},
			{
				typeof(DressGirlAI),
				new EnemyAttributes
				{
					EnemyName = "Ghost Girl"
				}
			},
			{
				typeof(MaskedPlayerEnemy),
				new EnemyAttributes
				{
					EnemyName = "Masked",
					UseLerpRotation = false
				}
			},
			{
				typeof(TestEnemy),
				new EnemyAttributes
				{
					WalkSpeed = 6f,
					RunSpeed = 8f,
					EnemyName = "Obunga",
					EnemyPositionOffset = new Vector3(0f, 1.5f, 0f),
					CamDistance = -4f,
					CamHeight = 3f
				}
			}
		};

		private static readonly EnemyAttributes DEFAULT_ATTRIBUTES = new EnemyAttributes();

		public static Dictionary<Type, Func<GameObject, EnemyAIController>> ENEMY_CONTROLLERS = new Dictionary<Type, Func<GameObject, EnemyAIController>>
		{
			{
				typeof(NutcrackerEnemyAI),
				(GameObject controller) => controller.AddComponent<NutcrackerEnemyController>()
			},
			{
				typeof(CentipedeAI),
				(GameObject controller) => controller.AddComponent<CentipedeEnemyController>()
			},
			{
				typeof(PufferAI),
				(GameObject controller) => controller.AddComponent<PufferEnemyController>()
			},
			{
				typeof(JesterAI),
				(GameObject controller) => controller.AddComponent<JesterEnemyController>()
			},
			{
				typeof(ForestGiantAI),
				(GameObject controller) => controller.AddComponent<ForestGiantEnemyController>()
			},
			{
				typeof(MouthDogAI),
				(GameObject controller) => controller.AddComponent<MouthDogEnemyController>()
			},
			{
				typeof(HoarderBugAI),
				(GameObject controller) => controller.AddComponent<HoardingBugEnemyController>()
			},
			{
				typeof(FlowermanAI),
				(GameObject controller) => controller.AddComponent<FlowermanEnemyController>()
			},
			{
				typeof(BaboonBirdAI),
				(GameObject controller) => controller.AddComponent<BaboonBirdEnemyController>()
			},
			{
				typeof(BlobAI),
				(GameObject controller) => controller.AddComponent<BlobEnemyController>()
			},
			{
				typeof(MaskedPlayerEnemy),
				(GameObject controller) => controller.AddComponent<MaskedPlayerEnemyController>()
			},
			{
				typeof(SpringManAI),
				(GameObject controller) => controller.AddComponent<SpringManEnemyController>()
			},
			{
				typeof(SandWormAI),
				(GameObject controller) => controller.AddComponent<SandWormEnemyController>()
			},
			{
				typeof(TestEnemy),
				(GameObject controller) => controller.AddComponent<SecretTestEnemyController>()
			}
		};

		public static EnemyAttributes GetEnemyAttributes(this EnemyAI enemyAI)
		{
			return ExtensionMethods.GetValueOrDefault(ENEMY_ATTRIBUTES, ((object)enemyAI).GetType(), DEFAULT_ATTRIBUTES);
		}

		public static bool IsEnemyAllowlisted(this EnemyAI enemyAI)
		{
			return ALLOWLISTED_ENEMIES.Contains(((object)enemyAI).GetType());
		}

		public static bool IsEnemyExperimental(this EnemyAI enemyAI)
		{
			return EXPERIMENTAL_ENEMIES.Contains(((object)enemyAI).GetType());
		}

		public static string GetEnemyName(this EnemyAI enemyAI)
		{
			EnemyAttributes valueOrDefault = ExtensionMethods.GetValueOrDefault(ENEMY_ATTRIBUTES, ((object)enemyAI).GetType(), null);
			if (valueOrDefault == null)
			{
				return enemyAI.enemyType?.enemyName ?? ((Object)((Component)enemyAI).gameObject).name;
			}
			return valueOrDefault.EnemyName;
		}

		public static EnemyAIController GetAndAttachEnemyController(this EnemyAI enemyAI, GameObject controller)
		{
			Func<GameObject, EnemyAIController> valueOrDefault = ExtensionMethods.GetValueOrDefault(ENEMY_CONTROLLERS, ((object)enemyAI).GetType(), (GameObject c) => c.AddComponent<EnemyAIController>());
			return valueOrDefault(controller);
		}
	}
}
namespace ControlCompany.Core.Enemy
{
	internal class SecretTestEnemyController : EnemyAIController
	{
		private TestEnemy testEnemy;

		public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			testEnemy = (TestEnemy)GetEnemyAIFromEnemyGameObject(enemyGameObject);
			base.InitializeEnemyController(playerActions, enemyGameObject);
		}

		protected override void UseSecondarySkillAction()
		{
		}

		public override string GetSecondarySkillName()
		{
			return "";
		}
	}
	internal class ControllableEnemy
	{
		public GameObject EnemyPrefab { get; set; }

		public string EnemyName { get; set; }

		public bool OverrideEnemyPrefab { get; set; }

		public GameObject EnemyGameObject { get; set; }

		public bool OverrideEnemySpawnLocation { get; set; }

		public bool Allowlisted { get; set; }

		public Vector3 EnemySpawnLocationOverride { get; set; }

		public Func<GameObject, GameObject, EnemyController> CreateAndAttachEnemyControllerFunc { get; set; }

		public static ControllableEnemy FromSpawnableEnemy(SpawnableEnemyWithRarity spawnableEnemy)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			GameObject enemyPrefab = spawnableEnemy.enemyType.enemyPrefab;
			EnemyAI componentInChildren = enemyPrefab.GetComponentInChildren<EnemyAI>();
			string enemyName = (((Object)componentInChildren == (Object)null) ? spawnableEnemy.enemyType.enemyName : componentInChildren.GetEnemyName());
			return new ControllableEnemy
			{
				EnemyName = enemyName,
				EnemyPrefab = enemyPrefab,
				OverrideEnemyPrefab = false,
				OverrideEnemySpawnLocation = false,
				Allowlisted = componentInChildren.IsEnemyAllowlisted(),
				CreateAndAttachEnemyControllerFunc = delegate(GameObject enemyGameObject, GameObject enemyController)
				{
					EnemyAI componentInChildren2 = enemyGameObject.GetComponentInChildren<EnemyAI>();
					return componentInChildren2.GetAndAttachEnemyController(enemyController);
				}
			};
		}

		public static ControllableEnemy FromEnemyAI(EnemyAI enemyAI)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			GameObject enemyPrefab = enemyAI.enemyType.enemyPrefab;
			string enemyName = (((Object)enemyAI == (Object)null) ? enemyAI.enemyType.enemyName : enemyAI.GetEnemyName());
			return new ControllableEnemy
			{
				EnemyName = enemyName,
				EnemyPrefab = enemyPrefab,
				OverrideEnemyPrefab = false,
				OverrideEnemySpawnLocation = false,
				Allowlisted = enemyAI.IsEnemyAllowlisted(),
				CreateAndAttachEnemyControllerFunc = delegate(GameObject enemyGameObject, GameObject enemyController)
				{
					EnemyAI componentInChildren = enemyGameObject.GetComponentInChildren<EnemyAI>();
					return componentInChildren.GetAndAttachEnemyController(enemyController);
				}
			};
		}
	}
	internal class SandWormEnemyController : EnemyAIController
	{
		private SandWormAI sandWormAI;

		private bool usedEmerge = false;

		public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			sandWormAI = (SandWormAI)GetEnemyAIFromEnemyGameObject(enemyGameObject);
			base.InitializeEnemyController(playerActions, enemyGameObject);
		}

		protected override void Move()
		{
			if (!IsEmerged() && !usedEmerge)
			{
				base.Move();
			}
		}

		protected override void LateUpdate()
		{
			base.LateUpdate();
			controlEnemyRotation = !IsEmerged() && !usedEmerge;
			if (IsEmerged())
			{
				usedEmerge = true;
			}
		}

		protected override void UseSecondarySkillAction()
		{
			if (!IsEmerged() && !usedEmerge)
			{
				usedEmerge = true;
				sandWormAI.StartEmergeAnimation();
			}
		}

		public override string GetSecondarySkillName()
		{
			return usedEmerge ? "" : "Emerge";
		}

		private bool IsEmerged()
		{
			return sandWormAI.inEmergingState || sandWormAI.emerged;
		}
	}
	internal class SpringManEnemyController : EnemyAIController
	{
		private SpringManAI springMan;

		private float initialWalkSpeed;

		private float initialRunSpeed;

		private bool holdingForceMove = false;

		public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			springMan = (SpringManAI)GetEnemyAIFromEnemyGameObject(enemyGameObject);
			base.InitializeEnemyController(playerActions, enemyGameObject);
			initialWalkSpeed = base.WalkSpeed;
			initialRunSpeed = base.RunSpeed;
		}

		protected override void LateUpdate()
		{
			base.LateUpdate();
			bool flag = springMan.GetFieldValue<bool>("hasStopped") || springMan.GetFieldValue<bool>("stoppingMovement");
			controlEnemyRotation = !flag || holdingForceMove;
			float fieldValue = springMan.GetFieldValue<float>("currentAnimSpeed");
			base.WalkSpeed = initialWalkSpeed * (1f + fieldValue / 6f);
			base.RunSpeed = initialRunSpeed * (1f + fieldValue / 6f);
		}

		protected override void Move()
		{
			if ((!springMan.GetFieldValue<bool>("hasStopped") && !springMan.GetFieldValue<bool>("stoppingMovement")) || holdingForceMove)
			{
				base.Move();
			}
		}

		protected override void UseSecondarySkillAction()
		{
			holdingForceMove = true;
		}

		protected override void ReleaseSecondarySkillAction()
		{
			CheckInitialized();
			if (!isAIControlled)
			{
				holdingForceMove = false;
			}
		}

		public override string GetSecondarySkillName()
		{
			return "(HOLD) Force move";
		}
	}
	internal class MaskedPlayerEnemyController : EnemyAIController
	{
		private MaskedPlayerEnemy maskedEnemy;

		private float entranceDoorOpenRange = 2.5f;

		private float useEntranceDoorCooldown = 2f;

		private float timeSinceLastEntranceDoorUse = 0f;

		private bool canUseEntranceDoorOnCollision = true;

		public override void InitializeEnemyController(PlayerActions playerActions, GameObject enemyGameObject)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			maskedEnemy = (MaskedPlayerEnemy)GetEnemyAIFromEnemyGameObject(enemyGameObject);
			base.InitializeEnemyController(playerActions, enemyGameObject);
			canJump = true;
		}

		protected override void LateUpdate()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			base.LateUpdate();
			bool fieldValue = maskedEnemy.GetFieldValue<bool>("inKillAnimation");
			bool fieldValue2 = maskedEnemy.GetFieldValue<bool>("crouching");
			controlEnemyRotation = !fieldValue && !fieldValue2;
			if (!canUseEntranceDoorOnCollision)
			{
				timeSinceLastEntranceDoorUse += Time.deltaTime;
				if (timeSinceLastEntranceDoorUse >= useEntranceDoorCooldown)
				{
					canUseEntranceDoorOnCollision = true;
					timeSinceLastEntranceDoorUse = 0f;
				}
			}
			MovementActions movement = playerActions.Movement;
			MovementActions val = movement;
			if (((MovementActions)(ref val)).Interact.WasPressedThisFrame())
			{
				ScanNearbyAndOpenMainEntranceDoor();
				return;
			}
			movement = playerActions.Movement;
			val = movement;
			if (((MovementActions)(ref val)).Crouch.WasPressedThisFrame())
			{
				Crouch(!fieldValue2);
			}
		}

		protected override void Move()
		{
			bool fieldValue = maskedEnemy.GetFieldValue<bool>("inKillAnimation");
			bool fieldValue2 = maskedEnemy.GetFieldValue<bool>("crouching");
			if (!fieldValue && !fieldValue2)
			{
				base.Move();
			}
		}

		protected override void UseSecondarySkillAction()
		{
		}

		private void Crouch(bool crouching)
		{
			maskedEnemy.SetCrouchingServerRpc(crouching);
		}

		private void ScanNearbyAndOpenMainEntranceDoor()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, entranceDoorOpenRange);
			for (int i = 0; i < array.Length; i++)
			{
				EntranceTeleport componentInChildren = ((Component)array[i]).GetComponentInChildren<EntranceTeleport>();
				if ((Object)componentInChildren != (Object)null && componentInChildren.entranceId == 0)
				{
					UseEntranceDoor();
				}
			}
		}

		private void UseEntranceDoor()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			((Collider)characterController).enabled = false;
			Vector3 position = RoundManager.FindMainEntrancePosition(true, !((EnemyAI)maskedEnemy).isOutside);
			((Component)this).transform.position = position;
			maskedEnemy.Call("TeleportMaskedEnemyAndSync", RoundManager.FindMainEntrancePosition(true, !((EnemyAI)maskedEnemy).isOutside), !((EnemyAI)maskedEnemy).isOutside);
			((Collider)characterController).enabled = true;
			canUseEntranceDoorOnCollision = false;
			ControlCenter.Instance.IsGhostIndoors = !((EnemyAI)maskedEnemy).isOutside;
		}

		protected override void OnControllerColliderHit(ControllerColliderHit hit)
		{
			//IL_0021: Unknown result type (might be due to invali