Decompiled source of Poltergeist v1.1.0

BepInEx/plugins/Poltergeist.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using CSync.Extensions;
using CSync.Lib;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using Microsoft.CodeAnalysis;
using Poltergeist.GhostInteractibles;
using Poltergeist.GhostInteractibles.Specific;
using Poltergeist.NetcodePatcher;
using TMPro;
using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Poltergeist")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A template for Lethal Company")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b7aebd7ab6b99f47259e793f76ba9b2a5c18a72b")]
[assembly: AssemblyProduct("Poltergeist")]
[assembly: AssemblyTitle("Poltergeist")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializable<NetworkTransformState>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedValueEquals<NetworkTransformState>();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Poltergeist
{
	public class GhostHead : NetworkBehaviour
	{
		public static Dictionary<PlayerControllerB, GhostHead> headMapping = new Dictionary<PlayerControllerB, GhostHead>();

		private bool initialized;

		public bool isActive;

		public bool isHostHead;

		private Light light;

		private Renderer renderer;

		private const int KEYFRAMES = 6;

		private static float[] keyTimes = new float[6] { 0f, 1f, 1.4f, 1.8f, 2.2f, 3f };

		private static float[] visibilities = new float[6] { 0f, 1f, 1f, 0.5f, 1f, 0f };

		private int keyIndex = 999;

		private float startTime;

		private Material matInstance;

		private ColorAdjustments colorAdj;

		private float maxOpacity = 1f;

		private float maxIntensity = 1f;

		private Color filterCol = Color.white;

		private void Awake()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			light = ((Component)this).GetComponentInChildren<Light>();
			renderer = ((Component)this).GetComponentInChildren<Renderer>();
			matInstance = renderer.material;
			maxOpacity = matInstance.color.a;
			maxIntensity = light.intensity;
		}

		private void LateUpdate()
		{
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			if (!initialized && (Object)(object)SpectatorCamController.instance != (Object)null && ((NetworkBehaviour)this).IsOwner && (!((NetworkBehaviour)this).IsServer || isHostHead))
			{
				initialized = true;
				SpectatorCamController.instance.head = this;
				renderer.enabled = false;
				Object.Instantiate<GameObject>(Poltergeist.colorVolObject).GetComponent<Volume>().profile.TryGet<ColorAdjustments>(ref colorAdj);
				((VolumeParameter)colorAdj.colorFilter).overrideState = true;
				filterCol = ((VolumeParameter<Color>)(object)colorAdj.colorFilter).value;
				((VolumeParameter<Color>)(object)colorAdj.colorFilter).value = Color.white;
				Poltergeist.DebugLog("Assigning head to local client");
			}
			if (keyIndex >= 6)
			{
				return;
			}
			if (Time.time >= startTime + keyTimes[keyIndex])
			{
				keyIndex++;
			}
			if (keyIndex == 6)
			{
				((Behaviour)light).enabled = false;
				((Component)renderer).gameObject.layer = 23;
				light.intensity = maxIntensity;
				matInstance.color = new Color(matInstance.color.r, matInstance.color.g, matInstance.color.b, maxOpacity);
				if ((Object)(object)colorAdj != (Object)null)
				{
					((VolumeParameter<Color>)(object)colorAdj.colorFilter).value = Color.white;
				}
				return;
			}
			float num = keyTimes[keyIndex] - keyTimes[keyIndex - 1];
			float num2 = (Time.time - (startTime + keyTimes[keyIndex - 1])) / num;
			float num3 = Mathf.Lerp(visibilities[keyIndex - 1], visibilities[keyIndex], num2);
			Color color = matInstance.color;
			matInstance.color = new Color(color.r, color.g, color.b, num3 * maxOpacity);
			light.intensity = num3 * maxIntensity;
			if ((Object)(object)colorAdj != (Object)null)
			{
				((VolumeParameter<Color>)(object)colorAdj.colorFilter).value = Color.Lerp(Color.white, filterCol, num3);
			}
		}

		public void Deactivate()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			((Component)this).transform.position = StartOfRound.Instance.notSpawnedPosition.position;
		}

		[ClientRpc]
		public void ManifestClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)base.__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1243495895u, val, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1243495895u, val, (RpcDelivery)0);
				}
				if ((int)base.__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					PlayFlickerAnim();
				}
			}
		}

		[ServerRpc]
		public void ManifestServerRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1669939383u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1669939383u, val, (RpcDelivery)0);
			}
			if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ManifestClientRpc();
			}
		}

		public bool PlayFlickerAnim()
		{
			if (keyIndex < 6)
			{
				return false;
			}
			keyIndex = 1;
			startTime = Time.time;
			((Behaviour)light).enabled = true;
			((Component)renderer).gameObject.layer = 0;
			return true;
		}

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_GhostHead()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(1243495895u, new RpcReceiveHandler(__rpc_handler_1243495895));
			NetworkManager.__rpc_func_table.Add(1669939383u, new RpcReceiveHandler(__rpc_handler_1669939383));
		}

		private static void __rpc_handler_1243495895(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((GhostHead)(object)target).ManifestClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1669939383(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
			}
			else
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((GhostHead)(object)target).ManifestServerRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "GhostHead";
		}
	}
	[DisallowMultipleComponent]
	public class HeadTransform : NetworkTransform
	{
		protected override void Awake()
		{
			((NetworkTransform)this).Awake();
			base.SyncScaleX = false;
			base.SyncScaleY = false;
			base.SyncScaleZ = false;
		}

		protected override bool OnIsServerAuthoritative()
		{
			return false;
		}

		protected override void __initializeVariables()
		{
			((NetworkTransform)this).__initializeVariables();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "HeadTransform";
		}
	}
	[HarmonyPatch]
	public static class Patches
	{
		public static bool vanillaMode;

		public static GrabbableObject ignoreObj;

		public static bool shouldGameOver;

		public static bool camControllerActive;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(SandSpiderAI), "TriggerChaseWithPlayer")]
		public static bool PreventSpiderBug(PlayerControllerB playerScript)
		{
			return (Object)(object)playerScript != (Object)null;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(ManualCameraRenderer), "MeetsCameraEnabledConditions")]
		public static IEnumerable<CodeInstruction> MonitorDontCheckPlayerLocation(IEnumerable<CodeInstruction> instructions, ILGenerator il)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			Label label = il.DefineLabel();
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Ldfld && (FieldInfo)list[i].operand == AccessTools.Field(typeof(PlayerControllerB), "isInHangarShipRoom"))
				{
					Poltergeist.DebugLog("Found expected structure for monitor transpiler!");
					num = i - 1;
					list[i + 2].labels.Add(label);
					break;
				}
			}
			List<CodeInstruction> list2 = new List<CodeInstruction>();
			list2.Add(new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(Patches), "camControllerActive")));
			list2.Add(new CodeInstruction(OpCodes.Brtrue_S, (object)label));
			if (num != -1)
			{
				list.InsertRange(num, list2);
			}
			return list;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(StartOfRound), "SetSpectateCameraToGameOverMode")]
		public static bool PreventSpectateFollow(bool enableGameOver)
		{
			shouldGameOver = enableGameOver;
			return vanillaMode;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
		public static void OverrideSpectateCam(PlayerControllerB __instance)
		{
			if (!vanillaMode)
			{
				__instance.playersManager.overrideSpectateCamera = true;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(StartOfRound), "SwitchCamera")]
		public static void ManageCameraController(StartOfRound __instance, Camera newCamera)
		{
			if ((Object)(object)newCamera == (Object)(object)__instance.spectateCamera)
			{
				SpectatorCamController.instance.EnableCam();
			}
			else
			{
				SpectatorCamController.instance.DisableCam();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		public static void MakeCamController(StartOfRound __instance)
		{
			((Component)__instance.spectateCamera).gameObject.AddComponent<SpectatorCamController>();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(InteractTrigger), "Start")]
		public static void AddGhostInteractor(InteractTrigger __instance)
		{
			if ((Object)(object)((Component)__instance).gameObject.GetComponent<DoorLock>() != (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<BasicInteractible>().costType = CostType.DOOR;
				return;
			}
			if (((Object)__instance).name.Equals("LightSwitch") || ((Object)(object)((Component)__instance).transform.parent != (Object)null && ((Object)((Component)__instance).transform.parent).name.Contains("storage")))
			{
				((Component)__instance).gameObject.AddComponent<BasicInteractible>();
				return;
			}
			Transform parent = ((Component)__instance).transform.parent;
			if ((Object)(object)parent != (Object)null && (((Object)parent).name.Contains("Pumpkin") || ((Object)parent).name.Contains("Television") || ((Object)parent).name.Contains("Record") || ((Object)parent).name.Contains("Romantic") || ((Object)parent).name.Contains("Shower") || ((Object)parent).name.Contains("Toilet") || ((Object)parent).name.Contains("Plushie")))
			{
				((Component)__instance).gameObject.AddComponent<BasicInteractible>();
			}
			else if ((Object)(object)parent != (Object)null && (((Object)parent).name.Equals("StartButton") || ((Object)parent).name.Equals("StopButton")))
			{
				((Component)__instance).gameObject.AddComponent<BasicInteractible>().costType = CostType.SHIPDOOR;
			}
			else if ((Object)(object)((Component)__instance).gameObject.GetComponent<SteamValveHazard>() != (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<BasicInteractible>().costType = CostType.VALVE;
			}
			else if ((Object)(object)parent != (Object)null && ((Object)parent).name.Equals("BellDinger"))
			{
				((Component)__instance).gameObject.AddComponent<BasicInteractible>().costType = CostType.COMPANYBELL;
			}
			else if (((Object)__instance).name.Contains("LeverSwitchHandle"))
			{
				((Component)__instance).gameObject.AddComponent<BasicInteractible>().costType = CostType.HANGARDOOR;
			}
			else if ((Object)(object)((Component)__instance).GetComponent<ShipAlarmCord>() != (Object)null)
			{
				BasicInteractible basicInteractible = ((Component)__instance).gameObject.AddComponent<BasicInteractible>();
				basicInteractible.costType = CostType.MISC;
				basicInteractible.isHeld = true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		public static void AddInteractorForProp(GrabbableObject __instance)
		{
			if ((NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) && (__instance is NoisemakerProp || __instance is BoomboxItem || __instance is RadarBoosterItem || __instance is RemoteProp))
			{
				GameObject obj = Object.Instantiate<GameObject>(Poltergeist.propInteractibleObject, ((Component)__instance).transform);
				obj.GetComponent<NetworkObject>().Spawn(false);
				obj.transform.parent = ((Component)__instance).transform;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(TerminalAccessibleObject), "Start")]
		public static void AddInteractorForBigDoors(TerminalAccessibleObject __instance)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if (((Object)__instance).name.Contains("BigDoor"))
			{
				GameObject val = new GameObject();
				val.transform.parent = ((Component)__instance).transform;
				val.transform.localPosition = new Vector3(0f, 2.4f, 0f);
				val.transform.localEulerAngles = Vector3.zero;
				val.transform.localScale = Vector3.one;
				val.layer = LayerMask.NameToLayer("Ignore Raycast");
				((Object)val).name = "GhostInteractable";
				BoxCollider obj = val.AddComponent<BoxCollider>();
				obj.size = new Vector3(0.7f, 4f, 3f);
				((Collider)obj).isTrigger = true;
				val.AddComponent<BigDoorInteractible>();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(EnemyAI), "Start")]
		[HarmonyPatch(typeof(MaskedPlayerEnemy), "Start")]
		public static void AddInteractorForEnemies(EnemyAI __instance)
		{
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				Poltergeist.DebugLog("Making interactor for " + ((Object)__instance).name);
				GameObject obj = Object.Instantiate<GameObject>(Poltergeist.enemyInteractibleObject, ((Component)__instance).transform);
				obj.GetComponent<NetworkObject>().Spawn(false);
				obj.transform.parent = ((Component)__instance).transform;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(WhoopieCushionTrigger), "OnTriggerEnter")]
		public static void WhoopiePatch(WhoopieCushionTrigger __instance, Collider other)
		{
			if ((Object)(object)((Component)other).gameObject.GetComponent<GhostHead>() != (Object)null)
			{
				Poltergeist.DebugLog("Ghost touched whoopie cushion");
				__instance.itemScript.FartWithDebounce();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MaskedPlayerEnemy), "Start")]
		public static void RegisterMasked(MaskedPlayerEnemy __instance)
		{
			if ((Object)(object)__instance.mimickingPlayer != (Object)null)
			{
				SpectatorCamController.masked.Add(__instance);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MaskedPlayerEnemy), "OnDestroy")]
		public static void DeregisterMasked(MaskedPlayerEnemy __instance)
		{
			if ((Object)(object)__instance.mimickingPlayer != (Object)null)
			{
				SpectatorCamController.masked.Remove(__instance);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		public static void LoadNetworkPrefabs()
		{
			if (!((Object)(object)Poltergeist.propInteractibleObject != (Object)null))
			{
				Poltergeist.propInteractibleObject = Poltergeist.poltergeistAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/PropInteractible.prefab");
				Poltergeist.propInteractibleObject.AddComponent<PropInteractible>();
				Poltergeist.enemyInteractibleObject = Poltergeist.poltergeistAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/EnemyInteractible.prefab");
				Poltergeist.enemyInteractibleObject.AddComponent<EnemyInteractible>();
				Poltergeist.ghostHeadObject = Poltergeist.poltergeistAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/ghosthead.prefab");
				Poltergeist.ghostHeadObject.AddComponent<HeadTransform>();
				Poltergeist.ghostHeadObject.AddComponent<GhostHead>();
				NetworkManager.Singleton.AddNetworkPrefab(Poltergeist.propInteractibleObject);
				NetworkManager.Singleton.AddNetworkPrefab(Poltergeist.enemyInteractibleObject);
				NetworkManager.Singleton.AddNetworkPrefab(Poltergeist.ghostHeadObject);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "Awake")]
		public static void MakeGhostHeads(PlayerControllerB __instance)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				GameObject obj = Object.Instantiate<GameObject>(Poltergeist.ghostHeadObject);
				GhostHead component = obj.GetComponent<GhostHead>();
				obj.transform.position = __instance.playersManager.notSpawnedPosition.position;
				GhostHead.headMapping.Add(__instance, component);
				obj.GetComponent<NetworkObject>().Spawn(false);
				component.isHostHead = (Object)(object)((Component)__instance).gameObject == (Object)(object)__instance.playersManager.allPlayerObjects[0];
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "OnClientConnect")]
		public static void AssignPlayerHead(StartOfRound __instance, ulong clientId)
		{
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				int num = __instance.ClientPlayerList[clientId];
				((Component)GhostHead.headMapping[__instance.allPlayerScripts[num]]).GetComponent<NetworkObject>().ChangeOwnership(clientId);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
		public static void ClearHeadDict()
		{
			GhostHead.headMapping.Clear();
			Poltergeist.DebugLog("Cleared dict after local dc");
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(StartOfRound), "OnPlayerDC")]
		public static void HandleHeadOnDC(StartOfRound __instance, int playerObjectNumber)
		{
			if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer)
			{
				PlayerControllerB key = __instance.allPlayerScripts[playerObjectNumber];
				if (GhostHead.headMapping.ContainsKey(key))
				{
					GhostHead ghostHead = GhostHead.headMapping[key];
					Poltergeist.DebugLog("Moving head after client dc: " + ((NetworkBehaviour)ghostHead).IsOwner);
					ghostHead.Deactivate();
				}
			}
		}
	}
	[BepInPlugin("coderCleric.Poltergeist", "Poltergeist", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency("com.sigurd.csync", "5.0.1")]
	public class Poltergeist : BaseUnityPlugin
	{
		public const string MOD_GUID = "coderCleric.Poltergeist";

		public const string MOD_NAME = "Poltergeist";

		public const string MOD_VERSION = "1.1.0";

		public static GameObject propInteractibleObject;

		public static GameObject enemyInteractibleObject;

		public static GameObject ghostHeadObject;

		public static GameObject colorVolObject;

		private static Poltergeist instance;

		public static AssetBundle poltergeistAssetBundle;

		public static PoltergeistConfig Config { get; private set; }

		private void Awake()
		{
			instance = this;
			Config = new PoltergeistConfig(((BaseUnityPlugin)this).Config);
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			new PoltergeistCustomInputs();
			poltergeistAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "bundles", "poltergeist"));
			colorVolObject = poltergeistAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/ghosthead_postprocess.prefab");
			NetcodePatcher();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin coderCleric.Poltergeist v1.1.0 is loaded!");
		}

		private static void NetcodePatcher()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}

		public static void DebugLog(string msg)
		{
			((BaseUnityPlugin)instance).Logger.LogInfo((object)msg);
		}
	}
	public class PoltergeistConfig : SyncedConfig2<PoltergeistConfig>
	{
		public ConfigEntry<bool> DefaultToVanilla { get; private set; }

		public ConfigEntry<float> LightIntensity { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> MaxPower { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> PowerRegen { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> AliveForMax { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> TimeForAggro { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> HitsForAggro { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> DoorCost { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> BigDoorCost { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> NoisyItemCost { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> ValveCost { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> ShipDoorCost { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> CompanyBellCost { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> PesterCost { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> ManifestCost { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> MiscCost { get; private set; }

		public PoltergeistConfig(ConfigFile cfg)
			: base("coderCleric.Poltergeist")
		{
			//IL_0017: 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: Expected O, but got Unknown
			//IL_0032: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0070: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00ae: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Expected O, but got Unknown
			//IL_00ec: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_0122: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_0160: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Expected O, but got Unknown
			//IL_0196: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Expected O, but got Unknown
			//IL_01d4: Expected O, but got Unknown
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Expected O, but got Unknown
			//IL_0212: Expected O, but got Unknown
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Expected O, but got Unknown
			//IL_0250: Expected O, but got Unknown
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Expected O, but got Unknown
			//IL_028e: Expected O, but got Unknown
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Expected O, but got Unknown
			//IL_02cc: Expected O, but got Unknown
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Expected O, but got Unknown
			//IL_030a: Expected O, but got Unknown
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Expected O, but got Unknown
			//IL_0348: Expected O, but got Unknown
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Expected O, but got Unknown
			//IL_0386: Expected O, but got Unknown
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Expected O, but got Unknown
			//IL_03c4: Expected O, but got Unknown
			DefaultToVanilla = cfg.Bind<bool>(new ConfigDefinition("Client-Side", "DefaultToVanilla"), false, new ConfigDescription("If true, you will be placed into the default spectate mode when you die.", (AcceptableValueBase)null, Array.Empty<object>()));
			LightIntensity = cfg.Bind<float>(new ConfigDefinition("Client-Side", "LightIntensity"), 8f, new ConfigDescription("The intensity of the ghost light.\n", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			MaxPower = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced", "Max power"), 100f, new ConfigDescription("The maximum amount of power that will be available to the ghosts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			PowerRegen = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced", "Power regen"), 5f, new ConfigDescription("How much power the ghosts regenerate per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			AliveForMax = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, new ConfigDefinition("Synced", "Alive for max power"), 1, new ConfigDescription("The maximum number of players that can be alive for the ghosts to have max power.\n(As soon as this number or fewer players are left alive, ghosts will be at max power.)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, int.MaxValue), Array.Empty<object>()));
			TimeForAggro = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced", "Pester aggro timespan"), 3f, new ConfigDescription("How many seconds can be between pesterings for an enemy to get mad at a nearby player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			HitsForAggro = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, new ConfigDefinition("Synced", "Aggro hit requirement"), 2, new ConfigDescription("How many times an enemy has to be pestered in the timespan in order to get mad at a nearby player.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, int.MaxValue), Array.Empty<object>()));
			DoorCost = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced: Costs", "Door cost"), 10f, new ConfigDescription("The power required to open/close regular doors.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			BigDoorCost = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced: Costs", "Big door cost"), 50f, new ConfigDescription("The power required to open/close larger doors.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			NoisyItemCost = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced: Costs", "Noisy item cost"), 5f, new ConfigDescription("The power required to use noisy items.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			ValveCost = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced: Costs", "Valve cost"), 20f, new ConfigDescription("The power required to turn valves.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			ShipDoorCost = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced: Costs", "Ship door cost"), 30f, new ConfigDescription("The power required to use the ship doors.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			CompanyBellCost = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced: Costs", "Company bell cost"), 15f, new ConfigDescription("The power required to ring the bell at the company building.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			PesterCost = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced: Costs", "Pester cost"), 20f, new ConfigDescription("The power required to pester enemies.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			ManifestCost = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced: Costs", "Manifest cost"), 80f, new ConfigDescription("The power required to manifest in the realm of the living.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			MiscCost = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, new ConfigDefinition("Synced: Costs", "Misc cost"), 10f, new ConfigDescription("The power required to do any interactions not covered by another section.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue), Array.Empty<object>()));
			ConfigManager.Register<PoltergeistConfig>((SyncedConfig2<PoltergeistConfig>)this);
		}
	}
	public class PoltergeistCustomInputs : LcInputActions
	{
		public static PoltergeistCustomInputs instance { get; private set; }

		[InputAction("<Mouse>/leftButton", Name = "Toggle Ghost Light")]
		public InputAction SwitchLightButton { get; private set; }

		[InputAction("<Mouse>/scroll/up", Name = "Accelerate")]
		public InputAction AccelerateButton { get; private set; }

		[InputAction("<Mouse>/scroll/down", Name = "Decelerate")]
		public InputAction DecelerateButton { get; private set; }

		[InputAction("<Keyboard>/e", Name = "Ghost Interact")]
		public InputAction InteractButton { get; private set; }

		[InputAction("<Keyboard>/q", Name = "Toggle Spectate Mode")]
		public InputAction ToggleButton { get; private set; }

		[InputAction("<Keyboard>/r", Name = "Up")]
		public InputAction UpKey { get; private set; }

		[InputAction("<Keyboard>/f", Name = "Down")]
		public InputAction DownKey { get; private set; }

		[InputAction("<Keyboard>/l", Name = "Lock Altitude")]
		public InputAction LockKey { get; private set; }

		[InputAction("<Keyboard>/c", Name = "Manifest")]
		public InputAction ManifestKey { get; private set; }

		[InputAction("<Keyboard>/h", Name = "Toggle Controls")]
		public InputAction ToggleControlsKey { get; private set; }

		public PoltergeistCustomInputs()
		{
			instance = this;
		}

		public static string GetInteractString()
		{
			return GetKeyString(instance.InteractButton);
		}

		public static string GetKeyString(InputAction action)
		{
			string[] array = InputActionRebindingExtensions.GetBindingDisplayString(action, (DisplayStringOptions)0, (string)null).Split(" | ");
			bool flag = false;
			bool flag2 = false;
			if (array[0].Length > 0)
			{
				flag = true;
			}
			if (array[1].Length > 0)
			{
				flag2 = true;
			}
			string text = "";
			if (flag)
			{
				text += array[0];
			}
			if (flag && flag2)
			{
				text += " | ";
			}
			if (flag2)
			{
				text += array[1];
			}
			return text;
		}
	}
	public class SpectatorCamController : MonoBehaviour
	{
		public static SpectatorCamController instance = null;

		private Camera cam;

		private float camMoveSpeed = 5f;

		private Light[] lights = (Light[])(object)new Light[4];

		private float maxPower = 100f;

		private float power;

		private PlayerControllerB clientPlayer;

		public GhostHead head;

		private IGhostInteractible currentGhostInteractible;

		private Transform hintPanelRoot;

		private Transform hintPanelOrigParent;

		private Transform deathUIRoot;

		private TextMeshProUGUI controlsText;

		private bool controlsHidden = true;

		private float accelTime = -1f;

		private float decelTime = -1f;

		public static List<MaskedPlayerEnemy> masked = new List<MaskedPlayerEnemy>();

		private bool altitudeLock;

		public float Power => power;

		public PlayerControllerB ClientPlayer => clientPlayer;

		private void Awake()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)instance != (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			instance = this;
			for (int i = 0; i < 4; i++)
			{
				Vector3 eulerAngles = default(Vector3);
				switch (i)
				{
				case 0:
					((Vector3)(ref eulerAngles))..ctor(50f, 0f, 0f);
					break;
				case 1:
					((Vector3)(ref eulerAngles))..ctor(120f, 0f, 0f);
					break;
				case 2:
					((Vector3)(ref eulerAngles))..ctor(50f, 90f, 0f);
					break;
				case 3:
					((Vector3)(ref eulerAngles))..ctor(50f, -90f, 0f);
					break;
				}
				GameObject val = new GameObject("GhostLight" + i);
				Light val2 = val.AddComponent<Light>();
				HDAdditionalLightData val3 = val.AddComponent<HDAdditionalLightData>();
				val.transform.eulerAngles = eulerAngles;
				val2.type = (LightType)1;
				val2.shadows = (LightShadows)0;
				val2.intensity = Poltergeist.Config.LightIntensity.Value;
				((Object)val).hideFlags = (HideFlags)52;
				val3.affectsVolumetric = false;
				lights[i] = val2;
			}
			cam = ((Component)this).GetComponent<Camera>();
			Camera obj = cam;
			obj.cullingMask |= 0x800000;
			DisableCam();
		}

		public void EnableCam()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (!((Behaviour)this).enabled)
			{
				((Behaviour)this).enabled = true;
				head.isActive = true;
				if (!Patches.vanillaMode)
				{
					((Component)this).transform.parent = null;
					Transform transform = ((Component)StartOfRound.Instance.activeCamera).transform;
					((Component)this).transform.position = transform.position;
					((Component)this).transform.rotation = transform.rotation;
					Patches.camControllerActive = true;
				}
				if ((Object)(object)hintPanelRoot == (Object)null)
				{
					hintPanelRoot = ((Component)HUDManager.Instance.tipsPanelAnimator).transform.parent;
					hintPanelOrigParent = hintPanelRoot.parent;
					deathUIRoot = ((Component)HUDManager.Instance.SpectateBoxesContainer).transform.parent;
					GameObject val = Object.Instantiate<GameObject>(((Component)HUDManager.Instance.holdButtonToEndGameEarlyText).gameObject, deathUIRoot);
					controlsText = val.GetComponent<TextMeshProUGUI>();
					((Object)val).name = "PoltergeistControlsText";
				}
				hintPanelRoot.parent = deathUIRoot;
				power = 0f;
				IGhostOnlyInteractible.SetGhostActivation(active: true);
				UpdateControlText();
			}
		}

		private void UpdateControlText()
		{
			if (controlsHidden)
			{
				((TMP_Text)controlsText).text = "Show Poltergeist Controls; [" + PoltergeistCustomInputs.GetKeyString(PoltergeistCustomInputs.instance.ToggleControlsKey) + "]";
				return;
			}
			string text = "Hide Poltergeist Controls; [" + PoltergeistCustomInputs.GetKeyString(PoltergeistCustomInputs.instance.ToggleControlsKey) + "]\n";
			text = text + "Switch Spectate Mode; [" + PoltergeistCustomInputs.GetKeyString(PoltergeistCustomInputs.instance.ToggleButton) + "]\n\n";
			if (!Patches.vanillaMode)
			{
				text = text + "Increase Speed; [" + PoltergeistCustomInputs.GetKeyString(PoltergeistCustomInputs.instance.AccelerateButton) + "]\n";
				text = text + "Decrease Speed; [" + PoltergeistCustomInputs.GetKeyString(PoltergeistCustomInputs.instance.DecelerateButton) + "]\n";
				text = text + "Up; [" + PoltergeistCustomInputs.GetKeyString(PoltergeistCustomInputs.instance.UpKey) + "]\n";
				text = text + "Down; [" + PoltergeistCustomInputs.GetKeyString(PoltergeistCustomInputs.instance.DownKey) + "]\n";
				text = text + "Lock Altitude; [" + PoltergeistCustomInputs.GetKeyString(PoltergeistCustomInputs.instance.LockKey) + "]\n\n";
				text = text + "Toggle Ghost Light; [" + PoltergeistCustomInputs.GetKeyString(PoltergeistCustomInputs.instance.SwitchLightButton) + "]\n";
				text = text + "Manifest; [" + PoltergeistCustomInputs.GetKeyString(PoltergeistCustomInputs.instance.ManifestKey) + "] (Cost: " + Poltergeist.Config.ManifestCost.Value + ")";
			}
			((TMP_Text)controlsText).text = text;
		}

		public void DisableCam()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			if (((Behaviour)this).enabled)
			{
				((Behaviour)this).enabled = false;
				Light[] array = lights;
				for (int i = 0; i < array.Length; i++)
				{
					((Behaviour)array[i]).enabled = false;
				}
				Patches.vanillaMode = Poltergeist.Config.DefaultToVanilla.Value;
				Patches.camControllerActive = false;
				altitudeLock = false;
				if ((Object)(object)head != (Object)null)
				{
					head.isActive = false;
					((Component)head).transform.position = StartOfRound.Instance.notSpawnedPosition.position;
				}
				if ((Object)(object)hintPanelRoot != (Object)null)
				{
					hintPanelRoot.parent = hintPanelOrigParent;
				}
				IGhostOnlyInteractible.SetGhostActivation(active: false);
				controlsHidden = true;
			}
		}

		private void SwitchLight(CallbackContext context)
		{
			if (((CallbackContext)(ref context)).performed && !Patches.vanillaMode && clientPlayer.isPlayerDead && !clientPlayer.isTypingChat && !clientPlayer.quickMenuManager.isMenuOpen)
			{
				Light[] array = lights;
				foreach (Light obj in array)
				{
					((Behaviour)obj).enabled = !((Behaviour)obj).enabled;
				}
			}
		}

		public void TeleportToPlayer(PlayerControllerB player)
		{
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			((object)HUDManager.Instance).GetType().GetMethod("DisplaySpectatorTip", BindingFlags.Instance | BindingFlags.NonPublic);
			if (player.isPlayerDead)
			{
				MaskedPlayerEnemy val = null;
				foreach (MaskedPlayerEnemy item in masked)
				{
					if ((Object)(object)item.mimickingPlayer == (Object)(object)player)
					{
						val = item;
						break;
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					if (!((EnemyAI)val).isEnemyDead)
					{
						Transform val2 = ((Component)val).transform.Find("ScavengerModel/metarig/spine/spine.001/spine.002/spine.003/spine.004");
						((Component)this).transform.position = val2.position + val2.up * 0.2f;
						((Component)this).transform.eulerAngles = new Vector3(val2.eulerAngles.x, val2.eulerAngles.y, 0f);
					}
					else
					{
						((Component)this).transform.position = ((Component)val).transform.position + Vector3.up;
					}
				}
				else if ((Object)(object)player.deadBody != (Object)null && !player.deadBody.deactivated)
				{
					((Component)this).transform.position = ((Component)player.deadBody).transform.position + Vector3.up;
				}
				else
				{
					HUDManager.Instance.DisplayTip("Can't Teleport", "Specified player is dead with no body!", true, false, "LC_Tip1");
				}
			}
			else if (!player.isPlayerControlled)
			{
				HUDManager.Instance.DisplayTip("Can't Teleport", "Specified player is not connected!", true, false, "LC_Tip1");
			}
			else
			{
				((Component)this).transform.position = ((Component)player.gameplayCamera).transform.position;
				((Component)this).transform.rotation = ((Component)player.gameplayCamera).transform.rotation;
				clientPlayer.spectatedPlayerScript = player;
				clientPlayer.SetSpectatedPlayerEffects(false);
			}
		}

		private void DoInteract(CallbackContext context)
		{
			if (((CallbackContext)(ref context)).performed && !Patches.vanillaMode && !clientPlayer.isTypingChat && !clientPlayer.quickMenuManager.isMenuOpen && currentGhostInteractible != null)
			{
				power -= currentGhostInteractible.Interact(((Component)clientPlayer).transform);
			}
		}

		private void Accelerate(CallbackContext context)
		{
			if (!Patches.vanillaMode)
			{
				accelTime = Time.time + 0.3f;
				decelTime = -1f;
			}
		}

		private void Decelerate(CallbackContext context)
		{
			if (!Patches.vanillaMode)
			{
				decelTime = Time.time + 0.3f;
				accelTime = -1f;
			}
		}

		private void SwitchModes(CallbackContext context)
		{
			if (!((CallbackContext)(ref context)).performed || clientPlayer.isTypingChat || clientPlayer.quickMenuManager.isMenuOpen)
			{
				return;
			}
			Patches.vanillaMode = !Patches.vanillaMode;
			if (Patches.vanillaMode)
			{
				Light[] array = lights;
				for (int i = 0; i < array.Length; i++)
				{
					((Behaviour)array[i]).enabled = false;
				}
				clientPlayer.spectatedPlayerScript = null;
				currentGhostInteractible = null;
				((TMP_Text)clientPlayer.cursorTip).text = "";
				StartOfRound.Instance.SetSpectateCameraToGameOverMode(Patches.shouldGameOver, clientPlayer);
				Patches.camControllerActive = false;
				UpdateControlText();
			}
			else
			{
				((Component)this).transform.parent = null;
				Patches.camControllerActive = true;
				UpdateControlText();
			}
		}

		private void LockAltitude(CallbackContext context)
		{
			if (((CallbackContext)(ref context)).performed && !Patches.vanillaMode && !clientPlayer.isTypingChat && !clientPlayer.quickMenuManager.isMenuOpen)
			{
				altitudeLock = !altitudeLock;
			}
		}

		private void ManifestHead(CallbackContext context)
		{
			if (((CallbackContext)(ref context)).performed && !Patches.vanillaMode && !clientPlayer.isTypingChat && !clientPlayer.quickMenuManager.isMenuOpen && power >= Poltergeist.Config.ManifestCost.Value)
			{
				head.ManifestServerRpc();
				power -= Poltergeist.Config.ManifestCost.Value;
			}
		}

		private void ToggleControlVis(CallbackContext context)
		{
			if (((CallbackContext)(ref context)).performed && !clientPlayer.isTypingChat && !clientPlayer.quickMenuManager.isMenuOpen)
			{
				controlsHidden = !controlsHidden;
				UpdateControlText();
			}
		}

		private void OnEnable()
		{
			PoltergeistCustomInputs.instance.SwitchLightButton.performed += SwitchLight;
			PoltergeistCustomInputs.instance.InteractButton.performed += DoInteract;
			PoltergeistCustomInputs.instance.AccelerateButton.performed += Accelerate;
			PoltergeistCustomInputs.instance.DecelerateButton.performed += Decelerate;
			PoltergeistCustomInputs.instance.ToggleButton.performed += SwitchModes;
			PoltergeistCustomInputs.instance.LockKey.performed += LockAltitude;
			PoltergeistCustomInputs.instance.ManifestKey.performed += ManifestHead;
			PoltergeistCustomInputs.instance.ToggleControlsKey.performed += ToggleControlVis;
		}

		private void OnDisable()
		{
			PoltergeistCustomInputs.instance.SwitchLightButton.performed -= SwitchLight;
			PoltergeistCustomInputs.instance.InteractButton.performed -= DoInteract;
			PoltergeistCustomInputs.instance.AccelerateButton.performed -= Accelerate;
			PoltergeistCustomInputs.instance.DecelerateButton.performed -= Decelerate;
			PoltergeistCustomInputs.instance.ToggleButton.performed -= SwitchModes;
			PoltergeistCustomInputs.instance.LockKey.performed -= LockAltitude;
			PoltergeistCustomInputs.instance.ManifestKey.performed -= ManifestHead;
			PoltergeistCustomInputs.instance.ToggleControlsKey.performed -= ToggleControlVis;
		}

		private void OnDestroy()
		{
			Light[] array = lights;
			foreach (Light val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
				}
			}
		}

		private void PositionControlText()
		{
			//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)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((TMP_Text)controlsText).transform;
			Bounds textBounds = ((TMP_Text)HUDManager.Instance.holdButtonToEndGameEarlyVotesText).textBounds;
			if (textBounds.m_Extents.y < 0f)
			{
				transform.position = new Vector3(transform.position.x, ((TMP_Text)HUDManager.Instance.holdButtonToEndGameEarlyVotesText).transform.position.y, transform.position.z);
				return;
			}
			float x = transform.localPosition.x;
			float y = (((Bounds)(ref textBounds)).min + ((TMP_Text)HUDManager.Instance.holdButtonToEndGameEarlyVotesText).transform.localPosition).y;
			Bounds bounds = ((TMP_Text)controlsText).bounds;
			transform.localPosition = new Vector3(x, y - (((Bounds)(ref bounds)).extents.y + 22f), transform.localPosition.z);
		}

		private void LateUpdate()
		{
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0471: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0574: Unknown result type (might be due to invalid IL or missing references)
			//IL_0578: Invalid comparison between Unknown and I4
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_056e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0571: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_0569: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Expected I4, but got Unknown
			//IL_05dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_073d: Unknown result type (might be due to invalid IL or missing references)
			//IL_064d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)clientPlayer == (Object)null)
			{
				clientPlayer = StartOfRound.Instance.localPlayerController;
				if ((Object)(object)clientPlayer == (Object)null)
				{
					return;
				}
			}
			float num = -1 * Poltergeist.Config.AliveForMax.Value;
			float num2 = 0f;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (val.isPlayerDead)
				{
					num += 1f;
					num2 += 1f;
				}
				else if (val.isPlayerControlled)
				{
					num += 1f;
				}
			}
			num2 = Mathf.Min(num2, num);
			if (num <= 0f)
			{
				maxPower = Poltergeist.Config.MaxPower.Value;
			}
			else
			{
				maxPower = num2 / num * Poltergeist.Config.MaxPower.Value;
			}
			power = Mathf.Min(maxPower, power + Poltergeist.Config.PowerRegen.Value * Time.deltaTime);
			if (clientPlayer.isTypingChat || clientPlayer.quickMenuManager.isMenuOpen || Patches.vanillaMode)
			{
				currentGhostInteractible = null;
				if ((Object)(object)head != (Object)null && head.isActive)
				{
					((Component)head).transform.position = ((Component)this).transform.position;
					((Component)head).transform.rotation = ((Component)this).transform.rotation;
				}
				return;
			}
			Vector2 val2 = IngamePlayerSettings.Instance.playerInput.actions.FindAction("Move", false).ReadValue<Vector2>();
			MovementActions movement = clientPlayer.playerActions.Movement;
			Vector2 val3 = ((MovementActions)(ref movement)).Look.ReadValue<Vector2>() * 0.008f * (float)IngamePlayerSettings.Instance.settings.lookSensitivity;
			if (!IngamePlayerSettings.Instance.settings.invertYAxis)
			{
				val3.y *= -1f;
			}
			bool num3 = IngamePlayerSettings.Instance.playerInput.actions.FindAction("Sprint", false).ReadValue<float>() > 0.3f;
			((Component)this).transform.Rotate(0f, val3.x, 0f, (Space)0);
			float num4 = ((Component)this).transform.eulerAngles.x % 360f + val3.y;
			if (num4 < 270f && num4 > 90f)
			{
				if (270f - num4 < num4 - 90f)
				{
					((Component)this).transform.eulerAngles = new Vector3(270f, ((Component)this).transform.eulerAngles.y, 0f);
				}
				else
				{
					((Component)this).transform.eulerAngles = new Vector3(90f, ((Component)this).transform.eulerAngles.y, 0f);
				}
			}
			else
			{
				((Component)this).transform.eulerAngles = new Vector3(num4, ((Component)this).transform.eulerAngles.y, 0f);
			}
			float num5 = camMoveSpeed;
			if (num3)
			{
				num5 *= 5f;
			}
			Vector3 val4 = ((Component)this).transform.right * val2.x * num5 * Time.deltaTime;
			Vector3 val5;
			if (!altitudeLock)
			{
				val5 = ((Component)this).transform.forward * val2.y * num5 * Time.deltaTime;
			}
			else
			{
				val5 = (((double)((Component)this).transform.forward.y < -0.99) ? ((Component)this).transform.up : ((!((double)((Component)this).transform.forward.y > 0.99)) ? ((Component)this).transform.forward : (((Component)this).transform.up * -1f)));
				val5.y = 0f;
				val5 = ((Vector3)(ref val5)).normalized;
				val5 = val5 * val2.y * num5 * Time.deltaTime;
			}
			Transform transform = ((Component)this).transform;
			transform.position += val4 + val5;
			float num6 = (PoltergeistCustomInputs.instance.UpKey.ReadValue<float>() - PoltergeistCustomInputs.instance.DownKey.ReadValue<float>()) * num5 * Time.deltaTime;
			Transform transform2 = ((Component)this).transform;
			transform2.position += Vector3.up * num6;
			if (accelTime > Time.time)
			{
				camMoveSpeed += Time.deltaTime * camMoveSpeed;
				camMoveSpeed = Mathf.Clamp(camMoveSpeed, 0f, 100f);
			}
			else if (decelTime > Time.time)
			{
				camMoveSpeed -= Time.deltaTime * camMoveSpeed;
				camMoveSpeed = Mathf.Clamp(camMoveSpeed, 0f, 100f);
			}
			((TMP_Text)HUDManager.Instance.spectatingPlayerText).text = "Power: " + power.ToString("F0") + " / " + maxPower.ToString("F0");
			int num7 = -1;
			for (Key val6 = (Key)41; (int)val6 <= 50; val6 = (Key)(val6 + 1))
			{
				if (((ButtonControl)Keyboard.current[val6]).wasPressedThisFrame)
				{
					num7 = val6 - 41;
					break;
				}
			}
			if (num7 != -1)
			{
				PlayerControllerB[] allPlayerScripts2 = StartOfRound.Instance.allPlayerScripts;
				if (num7 >= allPlayerScripts2.Length)
				{
					HUDManager.Instance.DisplayTip("Cannot Teleport", "Specified player index is invalid!", true, false, "LC_Tip1");
				}
				else
				{
					TeleportToPlayer(allPlayerScripts2[num7]);
				}
			}
			currentGhostInteractible = null;
			((TMP_Text)clientPlayer.cursorTip).text = "";
			RaycastHit val7 = default(RaycastHit);
			if (Physics.Raycast(((Component)this).transform.position, ((Component)this).transform.forward, ref val7, 5f, 525120) && ((Component)((RaycastHit)(ref val7)).collider).gameObject.layer != 8)
			{
				IGhostInteractible component = ((Component)((RaycastHit)(ref val7)).collider).gameObject.GetComponent<NaiveInteractible>();
				if (component == null)
				{
					foreach (Transform item in ((Component)((RaycastHit)(ref val7)).collider).transform)
					{
						component = ((Component)item).GetComponent<NetworkedInteractible>();
						if (component != null)
						{
							break;
						}
					}
				}
				if (component != null)
				{
					currentGhostInteractible = component;
					((TMP_Text)clientPlayer.cursorTip).text = component.GetTipText();
				}
			}
			if ((Object)(object)head != (Object)null && head.isActive)
			{
				((Component)head).transform.position = ((Component)this).transform.position;
				((Component)head).transform.rotation = ((Component)this).transform.rotation;
			}
			PositionControlText();
			allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val8 in allPlayerScripts)
			{
				if ((Object)(object)val8 != (Object)(object)clientPlayer && val8.isPlayerControlled)
				{
					val8.ShowNameBillboard();
					val8.usernameBillboard.LookAt(((Component)this).transform.position);
				}
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Poltergeist";

		public const string PLUGIN_NAME = "Poltergeist";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace Poltergeist.GhostInteractibles
{
	public interface IGhostInteractible
	{
		float GetCost();

		float Interact(Transform playerTransform);

		string GetTipText();
	}
	public interface IGhostOnlyInteractible : IGhostInteractible
	{
		protected static List<IGhostOnlyInteractible> managedInteractibles = new List<IGhostOnlyInteractible>();

		void SetActivation(bool activation);

		static void Register(IGhostOnlyInteractible interactible)
		{
			managedInteractibles.Add(interactible);
		}

		static void Unregister(IGhostOnlyInteractible interactible)
		{
			managedInteractibles.Remove(interactible);
		}

		static void SetGhostActivation(bool active)
		{
			foreach (IGhostOnlyInteractible managedInteractible in managedInteractibles)
			{
				managedInteractible.SetActivation(active);
			}
		}
	}
	public abstract class NaiveInteractible : MonoBehaviour, IGhostInteractible
	{
		public abstract float Interact(Transform playerTransform);

		public abstract float GetCost();

		public abstract string GetTipText();
	}
	public abstract class NetworkedInteractible : NetworkBehaviour, IGhostInteractible
	{
		public abstract float Interact(Transform playerTransform);

		public abstract float GetCost();

		public abstract string GetTipText();

		protected override void __initializeVariables()
		{
			((NetworkBehaviour)this).__initializeVariables();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "NetworkedInteractible";
		}
	}
}
namespace Poltergeist.GhostInteractibles.Specific
{
	public enum CostType
	{
		DOOR,
		VALVE,
		SHIPDOOR,
		COMPANYBELL,
		HANGARDOOR,
		MISC
	}
	public class BasicInteractible : NaiveInteractible
	{
		public CostType costType = CostType.MISC;

		private InteractTrigger trigger;

		private float interactDuration = 1f;

		private float interactTime;

		public bool isHeld;

		private void Awake()
		{
			trigger = ((Component)this).GetComponent<InteractTrigger>();
		}

		public override float GetCost()
		{
			return costType switch
			{
				CostType.DOOR => Poltergeist.Config.DoorCost.Value, 
				CostType.VALVE => Poltergeist.Config.ValveCost.Value, 
				CostType.SHIPDOOR => Poltergeist.Config.ShipDoorCost.Value, 
				CostType.COMPANYBELL => Poltergeist.Config.CompanyBellCost.Value, 
				CostType.HANGARDOOR => Poltergeist.Config.BigDoorCost.Value, 
				_ => Poltergeist.Config.MiscCost.Value, 
			};
		}

		public override float Interact(Transform playerTransform)
		{
			if (SpectatorCamController.instance.Power < GetCost())
			{
				return 0f;
			}
			if (trigger.interactable && (!trigger.interactCooldown || trigger.currentCooldownValue <= 0f))
			{
				if (!isHeld)
				{
					trigger.Interact(playerTransform);
				}
				else
				{
					interactTime = interactDuration;
				}
				return GetCost();
			}
			return 0f;
		}

		public override string GetTipText()
		{
			string text = "";
			if (SpectatorCamController.instance.Power < GetCost())
			{
				return "Not Enough Power (" + GetCost().ToString("F0") + ")";
			}
			if (!trigger.interactable)
			{
				return trigger.disabledHoverTip;
			}
			text = new StringBuilder(trigger.hoverTip).Replace("[LMB]", "[" + PoltergeistCustomInputs.GetInteractString() + "]").ToString();
			return text + " (" + GetCost().ToString("F0") + ")";
		}

		private void Update()
		{
			interactTime -= Time.deltaTime;
			if (interactTime > 0f && trigger.holdInteraction)
			{
				trigger.HoldInteractNotFilled();
			}
		}
	}
	public class BigDoorInteractible : NaiveInteractible, IGhostOnlyInteractible, IGhostInteractible
	{
		private TerminalAccessibleObject bigDoorObj;

		private void Awake()
		{
			bigDoorObj = ((Component)((Component)this).transform.parent).gameObject.GetComponent<TerminalAccessibleObject>();
			IGhostOnlyInteractible.Register(this);
		}

		public override float GetCost()
		{
			return Poltergeist.Config.BigDoorCost.Value;
		}

		public override float Interact(Transform playerTransform)
		{
			if (SpectatorCamController.instance.Power < GetCost())
			{
				return 0f;
			}
			if ((bool)typeof(TerminalAccessibleObject).GetField("isPoweredOn", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(bigDoorObj))
			{
				bigDoorObj.SetDoorToggleLocalClient();
				return GetCost();
			}
			return 0f;
		}

		public override string GetTipText()
		{
			string text = "";
			if (SpectatorCamController.instance.Power < GetCost())
			{
				return "Not Enough Power (" + GetCost().ToString("F0") + ")";
			}
			if ((bool)typeof(TerminalAccessibleObject).GetField("isPoweredOn", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(bigDoorObj))
			{
				text = "Toggle door : [" + PoltergeistCustomInputs.GetInteractString() + "]";
				return text + " (" + GetCost().ToString("F0") + ")";
			}
			return "Door is unpowered";
		}

		public void SetActivation(bool activation)
		{
			if (activation)
			{
				((Component)this).gameObject.layer = LayerMask.NameToLayer("InteractableObject");
			}
			else
			{
				((Component)this).gameObject.layer = LayerMask.NameToLayer("Ignore Raycast");
			}
		}

		private void OnDestroy()
		{
			IGhostOnlyInteractible.Unregister(this);
		}
	}
	public class EnemyDetector : NaiveInteractible
	{
		public EnemyInteractible enemyInteractible;

		public void RegisterInteractible(EnemyInteractible enemyInteractible)
		{
			this.enemyInteractible = enemyInteractible;
		}

		public override float GetCost()
		{
			return enemyInteractible.GetCost();
		}

		public override float Interact(Transform playerTransform)
		{
			return enemyInteractible.Interact(playerTransform);
		}

		public override string GetTipText()
		{
			return enemyInteractible.GetTipText();
		}
	}
	public class EnemyInteractible : NetworkedInteractible
	{
		private EnemyAI enemy;

		private float lastInteractTime;

		private int consecutiveHits;

		private EnemyDetector[] detectors;

		private void Start()
		{
			Transform parent = ((Component)this).transform.parent;
			enemy = ((Component)parent).GetComponent<EnemyAI>();
			EnemyAICollisionDetect[] componentsInChildren = ((Component)parent).GetComponentsInChildren<EnemyAICollisionDetect>();
			int num = componentsInChildren.Length;
			detectors = new EnemyDetector[num];
			for (int i = 0; i < num; i++)
			{
				detectors[i] = ((Component)componentsInChildren[i]).gameObject.AddComponent<EnemyDetector>();
				detectors[i].RegisterInteractible(this);
			}
		}

		public override float GetCost()
		{
			return Poltergeist.Config.PesterCost.Value;
		}

		public override float Interact(Transform playerTransform)
		{
			if (SpectatorCamController.instance.Power < GetCost())
			{
				return 0f;
			}
			if (enemy.isEnemyDead)
			{
				return 0f;
			}
			if (lastInteractTime + Poltergeist.Config.TimeForAggro.Value < Time.time)
			{
				consecutiveHits = 1;
			}
			else
			{
				consecutiveHits++;
			}
			if (consecutiveHits < Poltergeist.Config.HitsForAggro.Value)
			{
				InteractServerRpc(-1);
			}
			else
			{
				Poltergeist.DebugLog("Pestered " + ((Object)((Component)enemy).gameObject).name + " into targeting a player");
				PlayerControllerB closestPlayer = enemy.GetClosestPlayer(true, true, true);
				if ((Object)(object)closestPlayer != (Object)null)
				{
					InteractServerRpc((int)closestPlayer.playerClientId);
				}
				else
				{
					InteractServerRpc(-1);
				}
			}
			lastInteractTime = Time.time;
			return GetCost();
		}

		public void InteractLocallyOnly(PlayerControllerB accusedPlayer)
		{
			Poltergeist.DebugLog("Interacting locally with " + ((Object)((Component)enemy).gameObject).name);
			enemy.HitEnemy(0, accusedPlayer, true, -1);
		}

		public override string GetTipText()
		{
			if (enemy.isEnemyDead)
			{
				return "Enemy is dead";
			}
			if (SpectatorCamController.instance.Power < GetCost())
			{
				return "Not Enough Power (" + GetCost().ToString("F0") + ")";
			}
			return string.Concat("Pester enemy : [" + PoltergeistCustomInputs.GetInteractString() + "]", " (", GetCost().ToString("F0"), ")");
		}

		[ClientRpc]
		public void InteractClientRpc(int accussedID)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(26984558u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, accussedID);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 26984558u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (accussedID == -1)
				{
					InteractLocallyOnly(null);
				}
				else
				{
					InteractLocallyOnly(StartOfRound.Instance.allPlayerScripts[accussedID]);
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void InteractServerRpc(int accussedID)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2342660931u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, accussedID);
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2342660931u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					InteractClientRpc(accussedID);
				}
			}
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_EnemyInteractible()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(26984558u, new RpcReceiveHandler(__rpc_handler_26984558));
			NetworkManager.__rpc_func_table.Add(2342660931u, new RpcReceiveHandler(__rpc_handler_2342660931));
		}

		private static void __rpc_handler_26984558(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int accussedID = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref accussedID);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((EnemyInteractible)(object)target).InteractClientRpc(accussedID);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2342660931(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int accussedID = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref accussedID);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((EnemyInteractible)(object)target).InteractServerRpc(accussedID);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "EnemyInteractible";
		}
	}
	public class PropInteractible : NetworkedInteractible
	{
		private GrabbableObject prop;

		private void Start()
		{
			prop = ((Component)((Component)this).transform.parent).GetComponent<GrabbableObject>();
		}

		public override float GetCost()
		{
			return Poltergeist.Config.NoisyItemCost.Value;
		}

		public override float Interact(Transform playerTransform)
		{
			if (SpectatorCamController.instance.Power < GetCost())
			{
				return 0f;
			}
			if (prop.RequireCooldown() || !prop.UseItemBatteries(!prop.itemProperties.holdButtonUse, true))
			{
				return 0f;
			}
			Patches.ignoreObj = prop;
			InteractServerRpc((int)SpectatorCamController.instance.ClientPlayer.playerClientId, prop.isBeingUsed);
			InteractLocallyOnly();
			return GetCost();
		}

		public void InteractLocallyOnly()
		{
			Poltergeist.DebugLog("Interacting locally with " + ((Object)((Component)prop).gameObject).name);
			prop.ItemActivate(prop.isBeingUsed, true);
		}

		public override string GetTipText()
		{
			if (SpectatorCamController.instance.Power < GetCost())
			{
				return "Not Enough Power (" + GetCost().ToString("F0") + ")";
			}
			return string.Concat("Use item : [" + PoltergeistCustomInputs.GetInteractString() + "]", " (", GetCost().ToString("F0"), ")");
		}

		[ClientRpc]
		public void InteractClientRpc(int playerID, bool isBeingUsed)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2503838551u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerID);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isBeingUsed, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2503838551u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost) && (!((Object)(object)SpectatorCamController.instance.ClientPlayer != (Object)null) || playerID != (int)SpectatorCamController.instance.ClientPlayer.playerClientId))
				{
					prop.isBeingUsed = isBeingUsed;
					InteractLocallyOnly();
				}
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void InteractServerRpc(int playerID, bool isBeingUsed)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					ServerRpcParams val = default(ServerRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1197697737u, val, (RpcDelivery)0);
					BytePacker.WriteValueBitPacked(val2, playerID);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isBeingUsed, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1197697737u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					InteractClientRpc(playerID, isBeingUsed);
				}
			}
		}

		protected override void __initializeVariables()
		{
			base.__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_PropInteractible()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(2503838551u, new RpcReceiveHandler(__rpc_handler_2503838551));
			NetworkManager.__rpc_func_table.Add(1197697737u, new RpcReceiveHandler(__rpc_handler_1197697737));
		}

		private static void __rpc_handler_2503838551(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerID = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerID);
				bool isBeingUsed = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref isBeingUsed, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((PropInteractible)(object)target).InteractClientRpc(playerID, isBeingUsed);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1197697737(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerID = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerID);
				bool isBeingUsed = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref isBeingUsed, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((PropInteractible)(object)target).InteractServerRpc(playerID, isBeingUsed);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string __getTypeName()
		{
			return "PropInteractible";
		}
	}
}
namespace Poltergeist.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}