Decompiled source of Vecna v2.0.1

plugins/Reiko888.Vecna.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Dawn.Utils;
using Dusk;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Reiko888.Vecna.NetcodePatcher;
using TMPro;
using Unity.Collections;
using Unity.Jobs;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Audio;
using UnityEngine.Rendering;
using UnityEngine.Rendering.HighDefinition;
using UnityEngine.SceneManagement;
using UnityEngine.VFX;

[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("Reiko888.Vecna")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+b7928fab729006c1cc348acbee31e895d0ca152f")]
[assembly: AssemblyProduct("Vecna")]
[assembly: AssemblyTitle("Reiko888.Vecna")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Vecna
{
	public class DormantVecnaClone : MonoBehaviour, IHittable
	{
		public Animator cloneAnimator;

		public float detectionRadius = 15f;

		public Transform vecnaSpawnPoint;

		private bool hasTriggered = false;

		private Dictionary<PlayerControllerB, float> playerStayTimes = new Dictionary<PlayerControllerB, float>();

		public bool Hit(int force, Vector3 hitDirection, PlayerControllerB playerWhoHit, bool playHitSFX = false, int hitID = -1)
		{
			if (!hasTriggered)
			{
				TriggerWakeUpServerRpc();
				return true;
			}
			return false;
		}

		private void OnTriggerStay(Collider other)
		{
			if (hasTriggered || !((Component)other).CompareTag("Player"))
			{
				return;
			}
			PlayerControllerB component = ((Component)other).GetComponent<PlayerControllerB>();
			if ((Object)(object)component != (Object)null && !component.isPlayerDead)
			{
				if (!playerStayTimes.ContainsKey(component))
				{
					playerStayTimes[component] = 0f;
				}
				playerStayTimes[component] += Time.deltaTime;
				if (playerStayTimes[component] >= 5f)
				{
					TriggerWakeUpServerRpc();
				}
			}
		}

		private void OnTriggerExit(Collider other)
		{
			if (((Component)other).CompareTag("Player"))
			{
				PlayerControllerB component = ((Component)other).GetComponent<PlayerControllerB>();
				if ((Object)(object)component != (Object)null && playerStayTimes.ContainsKey(component))
				{
					playerStayTimes.Remove(component);
				}
			}
		}

		public void TriggerWakeUpServerRpc()
		{
			if (hasTriggered)
			{
				return;
			}
			hasTriggered = true;
			bool flag = false;
			foreach (VecnaAI activeInstance in VecnaAI.ActiveInstances)
			{
				if ((Object)(object)activeInstance != (Object)null)
				{
					activeInstance.TriggerCloneWakeUpServerRpc();
					flag = true;
				}
			}
			if (!flag)
			{
				VecnaAI vecnaAI = Object.FindObjectOfType<VecnaAI>();
				if ((Object)(object)vecnaAI != (Object)null)
				{
					vecnaAI.TriggerCloneWakeUpServerRpc();
				}
			}
		}

		public void DetachCloneLocally()
		{
			hasTriggered = true;
			if ((Object)(object)cloneAnimator != (Object)null)
			{
				cloneAnimator.SetTrigger("detach");
			}
		}

		public void StartWakeUpRoutine()
		{
			((MonoBehaviour)this).StartCoroutine(WakeUpRoutine());
		}

		private IEnumerator WakeUpRoutine()
		{
			yield return (object)new WaitForSeconds(5.5f);
			foreach (VecnaAI vecna in VecnaAI.ActiveInstances)
			{
				if ((Object)(object)vecna != (Object)null)
				{
					Vector3 spawnPos = (((Object)(object)vecnaSpawnPoint != (Object)null) ? vecnaSpawnPoint.position : ((Component)this).transform.position);
					vecna.WakeUpInLair(spawnPos);
				}
			}
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}
	public class HauntVisibilityRegistry
	{
		private sealed class EntityState
		{
			public readonly HashSet<string> tags = new HashSet<string>();

			public readonly HashSet<Renderer> disabledRenderers = new HashSet<Renderer>();

			public readonly HashSet<Light> disabledLights = new HashSet<Light>();

			public readonly HashSet<Rigidbody> disabledGravitys = new HashSet<Rigidbody>();

			public readonly HashSet<Collider> disabledColliders = new HashSet<Collider>();

			public readonly HashSet<TextMeshProUGUI> disabledTextMeshes = new HashSet<TextMeshProUGUI>();

			public readonly HashSet<DecalProjector> disabledDecals = new HashSet<DecalProjector>();

			public readonly HashSet<InteractTrigger> disabledInteractTriggers = new HashSet<InteractTrigger>();

			public readonly HashSet<ParticleSystem> disabledParticles = new HashSet<ParticleSystem>();

			public readonly Dictionary<AudioSource, float> audioVolumes = new Dictionary<AudioSource, float>();

			public readonly Dictionary<Component, List<string>> cachedCosmetics = new Dictionary<Component, List<string>>();
		}

		private static readonly Dictionary<GameObject, EntityState> VisibilityStates = new Dictionary<GameObject, EntityState>();

		public static void Hide(GameObject entity, string tag)
		{
			if (!((Object)(object)entity == (Object)null))
			{
				if (string.IsNullOrWhiteSpace(tag))
				{
					tag = "default";
				}
				CleanupDeadEntries();
				if (!VisibilityStates.TryGetValue(entity, out EntityState value))
				{
					value = new EntityState();
					VisibilityStates[entity] = value;
				}
				HideInternal(entity, value);
				value.tags.Add(tag);
			}
		}

		public static void Restore(GameObject entity, string tag)
		{
			if ((Object)(object)entity == (Object)null)
			{
				return;
			}
			if (string.IsNullOrWhiteSpace(tag))
			{
				tag = "default";
			}
			if (VisibilityStates.TryGetValue(entity, out EntityState value))
			{
				value.tags.Remove(tag);
				if (value.tags.Count == 0)
				{
					RestoreInternal(entity, value);
				}
			}
		}

		public static void ForceRestore(GameObject entity)
		{
			if ((Object)(object)entity != (Object)null && VisibilityStates.TryGetValue(entity, out EntityState value))
			{
				RestoreInternal(entity, value);
			}
		}

		public static bool IsHidden(GameObject entity)
		{
			return (Object)(object)entity != (Object)null && VisibilityStates.ContainsKey(entity);
		}

		private static void HideInternal(GameObject entity, EntityState state)
		{
			try
			{
				Type type = Type.GetType("MoreCompany.Cosmetics.CosmeticApplication, MoreCompany");
				if (type != null)
				{
					Component[] componentsInChildren = entity.GetComponentsInChildren(type, true);
					Component[] array = componentsInChildren;
					foreach (Component val in array)
					{
						if ((Object)(object)val == (Object)null)
						{
							continue;
						}
						FieldInfo field = type.GetField("spawnedCosmeticsIds", BindingFlags.Instance | BindingFlags.Public);
						if (field != null && field.GetValue(val) is List<string> { Count: >0 } list)
						{
							List<string> value = new List<string>(list);
							state.cachedCosmetics[val] = value;
							MethodInfo method = type.GetMethod("ClearCosmetics", BindingFlags.Instance | BindingFlags.Public);
							if (method != null)
							{
								method.Invoke(val, null);
							}
						}
					}
				}
				Type type2 = Type.GetType("ModelReplacement.MoreCompanyCosmeticManager, ModelReplacementAPI");
				if (type2 != null)
				{
					Component component = entity.GetComponent(type2);
					if ((Object)(object)component != (Object)null)
					{
						MethodInfo method2 = type2.GetMethod("UpdateModelReplacement", BindingFlags.Instance | BindingFlags.Public);
						if (method2 != null)
						{
							ModelReplacementAPISoftCompat.BypassCosmeticPrefix = true;
							method2.Invoke(component, null);
							ModelReplacementAPISoftCompat.BypassCosmeticPrefix = false;
						}
					}
				}
			}
			catch (Exception arg)
			{
				ModelReplacementAPISoftCompat.BypassCosmeticPrefix = false;
				Plugin.Logger.LogError((object)$"VECNA: Error clearing cosmetics in HideInternal: {arg}");
			}
			Renderer[] componentsInChildren2 = entity.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 != (Object)null && val2.enabled && ((Object)((Component)val2).gameObject).name != "ScavengerModelArmsOnly" && !((Object)((Component)val2).gameObject).name.Contains("CloneNametag"))
				{
					val2.enabled = false;
					state.disabledRenderers.Add(val2);
				}
			}
			Light[] componentsInChildren3 = entity.GetComponentsInChildren<Light>(true);
			foreach (Light val3 in componentsInChildren3)
			{
				if ((Object)(object)val3 != (Object)null && ((Behaviour)val3).enabled && !((Object)((Component)val3).gameObject).name.ToLower().Contains("map") && !((Object)((Component)val3).gameObject).name.ToLower().Contains("nightvision"))
				{
					((Behaviour)val3).enabled = false;
					state.disabledLights.Add(val3);
				}
			}
			Rigidbody[] componentsInChildren4 = entity.GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val4 in componentsInChildren4)
			{
				if ((Object)(object)val4 != (Object)null && val4.useGravity)
				{
					val4.useGravity = false;
					state.disabledGravitys.Add(val4);
				}
			}
			Collider[] componentsInChildren5 = entity.GetComponentsInChildren<Collider>(true);
			foreach (Collider val5 in componentsInChildren5)
			{
				if ((Object)(object)val5 != (Object)null && val5.enabled && ((Object)((Component)val5).gameObject).name != "PlayerPhysicsBox" && ((Object)((Component)val5).gameObject).name != "ItemOnlySlot" && !((Object)(object)((Component)val5).GetComponentInParent<DoorLock>() != (Object)null))
				{
					val5.enabled = false;
					state.disabledColliders.Add(val5);
				}
			}
			TextMeshProUGUI[] componentsInChildren6 = entity.GetComponentsInChildren<TextMeshProUGUI>(true);
			foreach (TextMeshProUGUI val6 in componentsInChildren6)
			{
				if ((Object)(object)val6 != (Object)null && ((Behaviour)val6).enabled)
				{
					((Behaviour)val6).enabled = false;
					state.disabledTextMeshes.Add(val6);
				}
			}
			DecalProjector[] componentsInChildren7 = entity.GetComponentsInChildren<DecalProjector>(true);
			foreach (DecalProjector val7 in componentsInChildren7)
			{
				if ((Object)(object)val7 != (Object)null && ((Behaviour)val7).enabled)
				{
					((Behaviour)val7).enabled = false;
					state.disabledDecals.Add(val7);
				}
			}
			InteractTrigger[] componentsInChildren8 = entity.GetComponentsInChildren<InteractTrigger>(true);
			foreach (InteractTrigger val8 in componentsInChildren8)
			{
				if ((Object)(object)val8 != (Object)null && val8.interactable && !((Object)(object)((Component)val8).GetComponentInParent<DoorLock>() != (Object)null))
				{
					val8.interactable = false;
					state.disabledInteractTriggers.Add(val8);
				}
			}
			ParticleSystem[] componentsInChildren9 = entity.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val9 in componentsInChildren9)
			{
				if ((Object)(object)val9 != (Object)null && val9.isPlaying)
				{
					val9.Stop(true, (ParticleSystemStopBehavior)1);
					state.disabledParticles.Add(val9);
				}
			}
			AudioSource[] componentsInChildren10 = entity.GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource val10 in componentsInChildren10)
			{
				if ((Object)(object)val10 != (Object)null && val10.volume > 0f)
				{
					state.audioVolumes[val10] = val10.volume;
					val10.volume = 0f;
				}
			}
		}

		private static void RestoreInternal(GameObject entity, EntityState state)
		{
			foreach (Renderer disabledRenderer in state.disabledRenderers)
			{
				if ((Object)(object)disabledRenderer != (Object)null)
				{
					disabledRenderer.enabled = true;
				}
			}
			foreach (Light disabledLight in state.disabledLights)
			{
				if ((Object)(object)disabledLight != (Object)null)
				{
					((Behaviour)disabledLight).enabled = true;
				}
			}
			foreach (Rigidbody disabledGravity in state.disabledGravitys)
			{
				if ((Object)(object)disabledGravity != (Object)null)
				{
					disabledGravity.useGravity = true;
				}
			}
			foreach (Collider disabledCollider in state.disabledColliders)
			{
				if ((Object)(object)disabledCollider != (Object)null)
				{
					disabledCollider.enabled = true;
				}
			}
			foreach (TextMeshProUGUI disabledTextMesh in state.disabledTextMeshes)
			{
				if ((Object)(object)disabledTextMesh != (Object)null)
				{
					((Behaviour)disabledTextMesh).enabled = true;
				}
			}
			foreach (DecalProjector disabledDecal in state.disabledDecals)
			{
				if ((Object)(object)disabledDecal != (Object)null)
				{
					((Behaviour)disabledDecal).enabled = true;
				}
			}
			foreach (InteractTrigger disabledInteractTrigger in state.disabledInteractTriggers)
			{
				if ((Object)(object)disabledInteractTrigger != (Object)null)
				{
					disabledInteractTrigger.interactable = true;
				}
			}
			foreach (ParticleSystem disabledParticle in state.disabledParticles)
			{
				if ((Object)(object)disabledParticle != (Object)null && (Object)(object)((Component)disabledParticle).gameObject != (Object)null)
				{
					disabledParticle.Play(true);
				}
			}
			foreach (KeyValuePair<AudioSource, float> audioVolume in state.audioVolumes)
			{
				if ((Object)(object)audioVolume.Key != (Object)null)
				{
					audioVolume.Key.volume = audioVolume.Value;
				}
			}
			state.tags.Clear();
			VisibilityStates.Remove(entity);
			if (state.cachedCosmetics.Count <= 0)
			{
				return;
			}
			List<string> list = new List<string>();
			foreach (KeyValuePair<Component, List<string>> cachedCosmetic in state.cachedCosmetics)
			{
				foreach (string item in cachedCosmetic.Value)
				{
					if (!list.Contains(item))
					{
						list.Add(item);
					}
				}
			}
			if (list.Count > 0 && (Object)(object)HUDManager.Instance != (Object)null)
			{
				((MonoBehaviour)HUDManager.Instance).StartCoroutine(RestoreCosmeticsCoroutine(entity, list));
			}
		}

		private static IEnumerator RestoreCosmeticsCoroutine(GameObject entity, List<string> ids)
		{
			if ((Object)(object)entity == (Object)null)
			{
				yield break;
			}
			Type cosmeticManagerType = Type.GetType("ModelReplacement.MoreCompanyCosmeticManager, ModelReplacementAPI");
			Type bodyReplacementType = Type.GetType("ModelReplacement.BodyReplacementBase, ModelReplacementAPI");
			if (bodyReplacementType != null)
			{
				Component bodyReplacement = entity.GetComponent(bodyReplacementType);
				if ((Object)(object)bodyReplacement != (Object)null)
				{
					FieldInfo replacementModelField = bodyReplacementType.GetField("replacementModel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (replacementModelField != null)
					{
						float timer = 0f;
						while (replacementModelField.GetValue(bodyReplacement) == null && timer < 5f)
						{
							yield return (object)new WaitForSeconds(0.1f);
							timer += 0.1f;
						}
					}
				}
			}
			try
			{
				Type cosmeticAppType = Type.GetType("MoreCompany.Cosmetics.CosmeticApplication, MoreCompany");
				if (cosmeticAppType != null && ids.Count > 0)
				{
					Component[] cosmeticApps = entity.GetComponentsInChildren(cosmeticAppType, true);
					MethodInfo applyMethod = cosmeticAppType.GetMethod("ApplyCosmetic", BindingFlags.Instance | BindingFlags.Public);
					if (applyMethod != null)
					{
						Component[] array = cosmeticApps;
						foreach (Component cosmeticApp in array)
						{
							if ((Object)(object)cosmeticApp == (Object)null)
							{
								continue;
							}
							Plugin.Logger.LogInfo((object)$"VECNA: Coroutine re-applying {ids.Count} cosmetics on {((Object)entity).name}");
							foreach (string id in ids)
							{
								applyMethod.Invoke(cosmeticApp, new object[2] { id, true });
							}
							FieldInfo spawnedCosmeticsField = cosmeticAppType.GetField("spawnedCosmetics", BindingFlags.Instance | BindingFlags.Public);
							if (!(spawnedCosmeticsField != null) || !(spawnedCosmeticsField.GetValue(cosmeticApp) is IList list))
							{
								continue;
							}
							foreach (object cosmeticObj in list)
							{
								MonoBehaviour cosmeticBehaviour = (MonoBehaviour)((cosmeticObj is MonoBehaviour) ? cosmeticObj : null);
								if (cosmeticBehaviour != null)
								{
									Transform transform = ((Component)cosmeticBehaviour).transform;
									transform.localScale *= 0.38f;
								}
							}
						}
					}
				}
			}
			catch (Exception)
			{
			}
			try
			{
				if (!(cosmeticManagerType != null) || !(bodyReplacementType != null))
				{
					yield break;
				}
				Component cosmeticManager = entity.GetComponent(cosmeticManagerType);
				Component bodyReplacement2 = entity.GetComponent(bodyReplacementType);
				if ((Object)(object)cosmeticManager != (Object)null && (Object)(object)bodyReplacement2 != (Object)null)
				{
					MethodInfo reportMethod = cosmeticManagerType.GetMethod("ReportBodyReplacementAddition", BindingFlags.Instance | BindingFlags.Public);
					if (reportMethod != null)
					{
						ModelReplacementAPISoftCompat.BypassCosmeticPrefix = true;
						reportMethod.Invoke(cosmeticManager, new object[1] { bodyReplacement2 });
						ModelReplacementAPISoftCompat.BypassCosmeticPrefix = false;
					}
				}
			}
			catch (Exception)
			{
				ModelReplacementAPISoftCompat.BypassCosmeticPrefix = false;
			}
		}

		private static void CleanupDeadEntries()
		{
			List<GameObject> list = null;
			foreach (KeyValuePair<GameObject, EntityState> visibilityState in VisibilityStates)
			{
				if ((Object)(object)visibilityState.Key == (Object)null)
				{
					if (list == null)
					{
						list = new List<GameObject>();
					}
					list.Add(visibilityState.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (GameObject item in list)
			{
				VisibilityStates.Remove(item);
			}
		}
	}
	public static class MelaniesVoiceCompat
	{
		private static PropertyInfo piPlayerAudioGroup;

		private static PropertyInfo piPlayerScript;

		private static PropertyInfo piGroupVolume;

		public static void Patch(Harmony harmony)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			try
			{
				Type type = Type.GetType("com.github.zehsteam.MelaniesVoice.MonoBehaviours.VoiceController, com.github.zehsteam.MelaniesVoice");
				if (type != null)
				{
					MethodInfo methodInfo = AccessTools.Method(type, "UpdateVoiceVolume", (Type[])null, (Type[])null);
					if (methodInfo != null)
					{
						piPlayerAudioGroup = AccessTools.Property(type, "PlayerAudioGroup");
						piPlayerScript = AccessTools.Property(type, "PlayerScript");
						HarmonyMethod val = new HarmonyMethod(AccessTools.Method(typeof(MelaniesVoiceCompat), "UpdateVoiceVolumePostfix", (Type[])null, (Type[])null));
						harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
				}
			}
			catch (Exception arg)
			{
				Debug.LogWarning((object)$"VECNA: Failed to apply Melanie's Voice patch: {arg}");
			}
		}

		private static void UpdateVoiceVolumePostfix(object __instance)
		{
			if (__instance == null)
			{
				return;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if ((Object)(object)localPlayerController == (Object)null || !localPlayerController.isPlayerControlled || localPlayerController.isPlayerDead)
			{
				return;
			}
			object? obj = piPlayerScript?.GetValue(__instance, null);
			PlayerControllerB val = (PlayerControllerB)((obj is PlayerControllerB) ? obj : null);
			if (!((Object)(object)val != (Object)null) || !((Object)(object)val != (Object)(object)localPlayerController))
			{
				return;
			}
			bool flag = VecnaAI.IsPlayerInUpsideDown(localPlayerController);
			bool flag2 = VecnaAI.IsPlayerInUpsideDown(val);
			if (flag == flag2)
			{
				return;
			}
			object obj2 = piPlayerAudioGroup?.GetValue(__instance, null);
			if (obj2 == null)
			{
				return;
			}
			if (piGroupVolume == null)
			{
				piGroupVolume = AccessTools.Property(obj2.GetType(), "Volume");
			}
			float num = ((piGroupVolume != null) ? ((float)piGroupVolume.GetValue(obj2, null)) : 0f);
			if (num > 0f)
			{
				bool flag3 = (localPlayerController.speakingToWalkieTalkie && val.holdingWalkieTalkie) || (val.speakingToWalkieTalkie && localPlayerController.holdingWalkieTalkie);
				float num2 = ((!flag) ? (flag3 ? 1f : 0f) : (flag3 ? 1f : 0.1f));
				if (piGroupVolume != null && piGroupVolume.CanWrite)
				{
					piGroupVolume.SetValue(obj2, num * num2, null);
				}
			}
		}
	}
	[BepInPlugin("Reiko888.Vecna", "Vecna", "2.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		public const string modGUID = "Reiko888.Vecna";

		public const string modName = "Vecna";

		public const string modVersion = "2.0.0";

		public static Plugin Instance = null;

		internal static ManualLogSource Logger = null;

		internal static readonly Harmony harmony = new Harmony("Reiko888.Vecna");

		internal static DuskMod mod = null;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Logger = ((BaseUnityPlugin)this).Logger;
			AssetBundle val = AssetBundleUtils.LoadBundle(Assembly.GetExecutingAssembly(), "vecna_cont");
			mod = DuskMod.RegisterMod((BaseUnityPlugin)(object)this, val);
			mod.RegisterContentHandlers();
			harmony.PatchAll(Assembly.GetExecutingAssembly());
			MelaniesVoiceCompat.Patch(harmony);
			ModelReplacementAPISoftCompat.Patch(harmony);
			MoreCompanySoftCompat.Patch(harmony);
			Logger.LogInfo((object)"Plugin Vecna is loaded!");
		}
	}
	public enum VecnaPhase
	{
		Cooldown,
		ClockStalking,
		ClockSpotted,
		HauntChase,
		HuntEveryone
	}
	public class VecnaAI : EnemyAI
	{
		private static readonly int AnimBlastDoor = Animator.StringToHash("blastDoor");

		private static readonly int AnimBlastDoorDone = Animator.StringToHash("blastDoorDone");

		public static VecnaLairPortal activeEntrancePortal;

		public static VecnaLairPortal activeExitPortal;

		public static bool isPlayerInLair = false;

		public GameObject atticPrefab;

		public GameObject lairEntrancePortalPrefab;

		public GameObject dormantVecnaClonePrefab;

		public bool isInLair = false;

		public GameObject portalSpawnNode;

		private EntranceTeleport[] allTeleports;

		[Header("Audio")]
		public AudioSource vecnaSnapAudioSource;

		public AudioClip playerSnapClip;

		public AudioSource breathingAudioSource;

		public AudioSource footstepsAudio;

		public AudioClip[] breathingClips;

		public AudioClip[] executionVoiceLines;

		public AudioClip[] clockSpotTaunts;

		public AudioClip[] clockTickingClips;

		public AudioClip[] escapeVoiceLines;

		public AudioClip finalChimeClip;

		[Space(5f)]
		public AudioClip clockChime1;

		public AudioClip clockChime2;

		public AudioClip clockChime3;

		public AudioClip doorTelekinesisClip;

		public AudioClip liftTelekinesisClip;

		public AudioClip vecnafpexecution;

		public AudioClip vehicleLiftVoiceLine;

		[Header("Vecna Audio Expansion")]
		public AudioClip pullingPlayerSFX;

		public AudioClip[] outOfLOSVoiceLines;

		public AudioClip stunnedVoiceClip;

		public AudioClip[] pullTauntVoiceLines;

		private float outOfLOSTimer = 0f;

		[Header("Variables")]
		public bool canKill = false;

		public float SFXVolumeLerpTo = 1f;

		public AudioSource chimechase;

		public float spawnTimer = 0f;

		public float unspottedTimer = 0f;

		public BoomboxItem[] cachedBoomboxes;

		public GameObject activeClone = null;

		public Animator activeCloneAnim = null;

		private BoomboxItem rescuingBoombox;

		public const int UPSIDE_DOWN_LAYER = 25;

		public int storedCameraMask = -1;

		public Camera storedCamera = null;

		public GameObject ClonePrefab;

		public float boomboxRescueTimer = 0f;

		public bool isPortalOpen = false;

		public GameObject currentClock;

		public GameObject ClockPrefab;

		public float stareTimer = 0f;

		public float clockTimer = 0f;

		public PlayerControllerB cursingPlayer;

		public bool cursingLocalPlayer;

		public List<SkinnedMeshRenderer> victimBodyRenderers = new List<SkinnedMeshRenderer>();

		public List<SkinnedMeshRenderer> nonVictimBodyRenderers = new List<SkinnedMeshRenderer>();

		public List<MeshRenderer> victimDefaultMeshRenderers = new List<MeshRenderer>();

		public List<MeshRenderer> nonVictimDefaultMeshRenderers = new List<MeshRenderer>();

		public List<Component> victimDecalProjectors = new List<Component>();

		public List<Component> nonVictimDecalProjectors = new List<Component>();

		private Random vecnaCurseRandom;

		private bool initializedRandomSeed;

		public float hauntCooldownTimer = 0f;

		public bool cloneWasTeleportedToShip = false;

		[Header("Door Prying")]
		public HangarShipDoor shipDoor;

		public bool isPryingDoor = false;

		private float pryingDoorAnimTime = 0f;

		public float pryOpenDoorAnimLength = 3f;

		public AudioClip shipAlarm;

		public AudioClip breakAndEnter;

		private bool hasTriggeredThrowAnim = false;

		public VecnaPortalManager portalManager;

		public GameObject portalPrefab;

		public GameObject[] outsideNodes;

		public GameObject[] insideNodes;

		public float chaseTimer = 0f;

		[Header("Telekinesis Abilities")]
		public AudioClip telekinesisWindupSFX;

		public AudioClip telePushExecuteSFX;

		[Header("VFX")]
		public ParticleSystem teleDoorParticle;

		public ParticleSystem telePushParticle;

		public ParticleSystem telePullParticle;

		public VisualEffect auraVisualEffect;

		public ParticleSystem teleBlastParticle;

		[Header("Animator Swapping")]
		public RuntimeAnimatorController vecnaPullLocalAnimator;

		public RuntimeAnimatorController vecnaPullRemoteAnimator;

		private static readonly Dictionary<ulong, RuntimeAnimatorController> _SAVED_ANIMATORS = new Dictionary<ulong, RuntimeAnimatorController>();

		private AnimatorStateInfo _savedState;

		private float _savedNormalizedTime;

		private bool _savedCrouching;

		private bool _savedWalking;

		private bool _savedJumping;

		private bool _savedSprinting;

		private float telekinesisChargeTimer = 0f;

		private float telekinesisCooldown = 0f;

		private bool isCastingTelekinesis = false;

		private bool isPullingPlayer = false;

		private VecnaPhase? queuedPhase = null;

		private Vector3 serverPortalPos;

		public Vector3 serverVictimClonePos = Vector3.zero;

		public bool isTeleportingVictimFromVecna = false;

		private bool hasTauntedForCurrentClock = false;

		private bool lastSpectatingState = false;

		public static HashSet<GrabbableObject> levelSpawnedScrap = new HashSet<GrabbableObject>();

		private List<GrabbableObject> cachedGrabbableObjects = new List<GrabbableObject>();

		private DoorLock[] cachedDoors;

		private float doorSlamTimer = 0f;

		private float slowScanTimer = 0f;

		private float flickerTimer = 0f;

		private Dictionary<Light, float> originalLightIntensities = new Dictionary<Light, float>();

		private Dictionary<DoorLock, float> telekinesisCooldowns = new Dictionary<DoorLock, float>();

		public GameObject activeFakeBody = null;

		public VecnaLairTrigger lairTrigger;

		private bool enemyMeshEnabled;

		private int timesClockSpawned;

		private bool hasStartedChase;

		private Vector3 victimStartingPosition;

		public Vector3 localVictimClonePos;

		private bool serverSpawnedClone;

		public float clockLifetimeTimer = 0f;

		private float blastCooldownTimer;

		private float serverTelekinesisCooldownTimer;

		private bool waitingForPhaseChange = false;

		[Header("Config variables")]
		private float boomboxRescueRadius;

		private float clockSpawnInterval;

		private float hauntChaseSpeed;

		private float huntEveryoneChaseSpeed;

		private float hauntChaseTime;

		private float blastCooldown;

		private float telekinCooldown;

		private int telekinesisBaseDmg;

		private int blastBaseDmg;

		private int vecnaHP;

		private float telePushKnockback;

		private float teleThrowHeight;

		private bool isLightFlickerOn;

		public static List<VecnaAI> ActiveInstances = new List<VecnaAI>();

		public bool isHuntingEveryone => currentLocalPhase == VecnaPhase.HuntEveryone;

		[HideInInspector]
		public VecnaPhase currentLocalPhase => (VecnaPhase)base.currentBehaviourStateIndex;

		public bool IsPlayerInLair(PlayerControllerB player)
		{
			//IL_006e: 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)
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if ((Object)(object)lairTrigger != (Object)null)
			{
				lairTrigger.playersInLair.RemoveAll((PlayerControllerB p) => (Object)(object)p == (Object)null || p.isPlayerDead || !p.isPlayerControlled || !(((Component)p).transform.position.x > 1000f) || !(((Component)p).transform.position.z > 1000f));
				return lairTrigger.playersInLair.Contains(player);
			}
			return ((Component)player).transform.position.x > 1000f && ((Component)player).transform.position.z > 1000f;
		}

		public override void Awake()
		{
			((EnemyAI)this).Awake();
			portalManager = new VecnaPortalManager(this);
			cachedDoors = Object.FindObjectsOfType<DoorLock>();
			ActiveInstances.Add(this);
		}

		public override void Start()
		{
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Start();
			levelSpawnedScrap.Clear();
			base.updatePositionThreshold = 0.5f;
			hauntChaseSpeed = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<float>("Vecna chase speed in haunt").Value;
			boomboxRescueRadius = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<float>("Boombox detection radius").Value;
			clockSpawnInterval = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<float>("Interval between clock spawns").Value;
			huntEveryoneChaseSpeed = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<float>("Chase speed whem hunting everyone").Value;
			hauntChaseTime = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<float>("Haunt chase duration").Value;
			blastCooldown = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<float>("Blast cooldown").Value;
			telekinCooldown = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<float>("Telekinesis cooldown").Value;
			telekinesisBaseDmg = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<int>("Telekinesis base damage").Value;
			blastBaseDmg = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<int>("Telekinesis blast base damage").Value;
			vecnaHP = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<int>("Vecna HP").Value;
			telePushKnockback = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<float>("Telekinesis knockback strength").Value;
			teleThrowHeight = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<float>("Telekinesis throw height").Value;
			isLightFlickerOn = ((AssetBundleLoader<VecnaContentHandler.VecnaAssets>)(object)ContentHandler<VecnaContentHandler>.Instance.vecnaAssets).GetConfig<bool>("Haunt light flickering").Value;
			base.enemyHP = vecnaHP;
			shipDoor = Object.FindObjectOfType<HangarShipDoor>();
			if (!RoundManager.Instance.hasInitializedLevelRandomSeed)
			{
				RoundManager.Instance.InitializeRandomNumberGenerators();
			}
			outsideNodes = GameObject.FindGameObjectsWithTag("OutsideAINode");
			insideNodes = GameObject.FindGameObjectsWithTag("AINode");
			if (((NetworkBehaviour)this).IsServer)
			{
				SpawnLairAndPortal();
			}
			ChoosePlayerToCurse();
			((EnemyAI)this).EnableEnemyMesh(false, true, true);
			enemyMeshEnabled = false;
			StopAllSFX();
			Debug.Log((object)"!!!VECNA CURSE TAKEN HOLD!!!");
			ScanNodeProperties componentInChildren = ((Component)this).GetComponentInChildren<ScanNodeProperties>(true);
			GameObject val = GameObject.Find("LairDetect");
			if ((Object)(object)val == (Object)null)
			{
				Transform[] array = Resources.FindObjectsOfTypeAll<Transform>();
				foreach (Transform val2 in array)
				{
					if (((Object)val2).name == "LairDetect")
					{
						Scene scene = ((Component)val2).gameObject.scene;
						if (((Scene)(ref scene)).isLoaded)
						{
							val = ((Component)val2).gameObject;
							break;
						}
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				lairTrigger = val.GetComponent<VecnaLairTrigger>();
				if ((Object)(object)lairTrigger == (Object)null)
				{
					lairTrigger = val.AddComponent<VecnaLairTrigger>();
				}
			}
		}

		public void ChangePhaseSafely(VecnaPhase newPhase)
		{
			//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)
			//IL_0087: 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)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			waitingForPhaseChange = true;
			if (base.inSpecialAnimation)
			{
				queuedPhase = newPhase;
			}
			else if (((NetworkBehaviour)this).IsServer)
			{
				SyncPhaseSafelyClientRpc((int)newPhase, timesClockSpawned);
				if (newPhase == VecnaPhase.HauntChase)
				{
					if ((Object)(object)cursingPlayer != (Object)null)
					{
						victimStartingPosition = ((Component)cursingPlayer).transform.position;
						serverVictimClonePos = ((Component)cursingPlayer).transform.position;
					}
					bool isOutsideState = (Object)(object)cursingPlayer != (Object)null && !cursingPlayer.isInsideFactory;
					if (TryFindingChaseSpawnPosition(out var spawnPos))
					{
						SyncHauntChaseStartClientRpc(spawnPos, isOutsideState);
						return;
					}
					Vector3 spawnPos2 = (((Object)(object)cursingPlayer != (Object)null) ? ((Component)cursingPlayer).transform.position : ((Component)this).transform.position);
					SyncHauntChaseStartClientRpc(spawnPos2, isOutsideState);
				}
			}
			else
			{
				ChangePhaseServerRpc((int)newPhase, timesClockSpawned);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void ChangePhaseServerRpc(int newPhaseIndex, int currentTimesClockSpawned)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_007e: 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_00db: 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 != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val2 = default(ServerRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(877925408u, val2, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, newPhaseIndex);
				BytePacker.WriteValueBitPacked(val, currentTimesClockSpawned);
				((NetworkBehaviour)this).__endSendServerRpc(ref val, 877925408u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				timesClockSpawned = currentTimesClockSpawned;
				if (newPhaseIndex == 0)
				{
					hauntCooldownTimer = clockSpawnInterval;
				}
				ChangePhaseSafely((VecnaPhase)newPhaseIndex);
			}
		}

		[ClientRpc]
		private void SyncPhaseSafelyClientRpc(int newPhaseIndex, int currentTimesClockSpawned)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_007e: 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_00db: 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 != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1035905404u, val2, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, newPhaseIndex);
				BytePacker.WriteValueBitPacked(val, currentTimesClockSpawned);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 1035905404u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				VecnaPhase vecnaPhase = currentLocalPhase;
				timesClockSpawned = currentTimesClockSpawned;
				base.currentBehaviourStateIndex = newPhaseIndex;
				if (newPhaseIndex == 0)
				{
					hauntCooldownTimer = clockSpawnInterval;
				}
				if (vecnaPhase != (VecnaPhase)newPhaseIndex)
				{
					OnLocalPhaseChanged(vecnaPhase, (VecnaPhase)newPhaseIndex);
				}
				waitingForPhaseChange = false;
			}
		}

		[ClientRpc]
		public void SyncVictimClientRpc(int victimPlayerId)
		{
			//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)
			//IL_00ce: 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 != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(131674874u, val2, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, victimPlayerId);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 131674874u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				if (victimPlayerId < 0)
				{
					cursingPlayer = null;
					cursingLocalPlayer = false;
					return;
				}
				cursingPlayer = StartOfRound.Instance.allPlayerScripts[victimPlayerId];
				cursingLocalPlayer = (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)cursingPlayer;
				((MonoBehaviour)this).StartCoroutine(NosebleedRoutine(cursingPlayer));
				Debug.Log((object)$"VECNA: Network synced! The victim is {cursingPlayer.playerUsername}. Local: {cursingLocalPlayer}");
				PopulateCullingListsDynamically();
			}
		}

		private void PopulateCullingListsDynamically()
		{
			victimBodyRenderers.Clear();
			nonVictimBodyRenderers.Clear();
			victimDefaultMeshRenderers.Clear();
			nonVictimDefaultMeshRenderers.Clear();
			victimDecalProjectors.Clear();
			nonVictimDecalProjectors.Clear();
			if ((Object)(object)cursingPlayer != (Object)null)
			{
				CullModelReplacement(cursingPlayer, isCursingPlayer: true);
				SkinnedMeshRenderer[] componentsInChildren = ((Component)cursingPlayer).GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer val in componentsInChildren)
				{
					if (!((Object)(object)val != (Object)null) || !(((Object)((Component)val).gameObject).name != "ScavengerModelArmsOnly") || ((Object)((Component)val).gameObject).name.Contains("CloneNametag"))
					{
						continue;
					}
					bool flag = false;
					for (int j = 0; j < cursingPlayer.ItemSlots.Length; j++)
					{
						if ((Object)(object)cursingPlayer.ItemSlots[j] != (Object)null && ((Component)val).transform.IsChildOf(((Component)cursingPlayer.ItemSlots[j]).transform))
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						victimBodyRenderers.Add(val);
					}
				}
				MeshRenderer[] componentsInChildren2 = ((Component)cursingPlayer).GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val2 in componentsInChildren2)
				{
					if (!((Object)(object)val2 != (Object)null) || ((Component)val2).gameObject.layer != 0 || ((Object)((Component)val2).gameObject).name.Contains("CloneNametag"))
					{
						continue;
					}
					bool flag2 = false;
					for (int l = 0; l < cursingPlayer.ItemSlots.Length; l++)
					{
						if ((Object)(object)cursingPlayer.ItemSlots[l] != (Object)null && ((Component)val2).transform.IsChildOf(((Component)cursingPlayer.ItemSlots[l]).transform))
						{
							flag2 = true;
							break;
						}
					}
					if (!flag2)
					{
						victimDefaultMeshRenderers.Add(val2);
					}
				}
				Component[] componentsInChildren3 = ((Component)cursingPlayer).GetComponentsInChildren<Component>(true);
				foreach (Component val3 in componentsInChildren3)
				{
					if ((Object)(object)val3 != (Object)null && ((object)val3).GetType().FullName == "UnityEngine.Rendering.HighDefinition.DecalProjector")
					{
						victimDecalProjectors.Add(val3);
					}
				}
			}
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val4 in allPlayerScripts)
			{
				if (!((Object)(object)val4 != (Object)null) || !((Object)(object)val4 != (Object)(object)cursingPlayer) || !val4.isPlayerControlled)
				{
					continue;
				}
				CullModelReplacement(val4, isCursingPlayer: false);
				SkinnedMeshRenderer[] componentsInChildren4 = ((Component)val4).GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer val5 in componentsInChildren4)
				{
					if (!((Object)(object)val5 != (Object)null) || !(((Object)((Component)val5).gameObject).name != "ScavengerModelArmsOnly") || ((Object)((Component)val5).gameObject).name.Contains("CloneNametag"))
					{
						continue;
					}
					bool flag3 = false;
					for (int num2 = 0; num2 < val4.ItemSlots.Length; num2++)
					{
						if ((Object)(object)val4.ItemSlots[num2] != (Object)null && ((Component)val5).transform.IsChildOf(((Component)val4.ItemSlots[num2]).transform))
						{
							flag3 = true;
							break;
						}
					}
					if (!flag3)
					{
						nonVictimBodyRenderers.Add(val5);
					}
				}
				MeshRenderer[] componentsInChildren5 = ((Component)val4).GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val6 in componentsInChildren5)
				{
					if (!((Object)(object)val6 != (Object)null) || ((Component)val6).gameObject.layer != 0 || ((Object)((Component)val6).gameObject).name.Contains("CloneNametag"))
					{
						continue;
					}
					bool flag4 = false;
					for (int num4 = 0; num4 < val4.ItemSlots.Length; num4++)
					{
						if ((Object)(object)val4.ItemSlots[num4] != (Object)null && ((Component)val6).transform.IsChildOf(((Component)val4.ItemSlots[num4]).transform))
						{
							flag4 = true;
							break;
						}
					}
					if (!flag4)
					{
						nonVictimDefaultMeshRenderers.Add(val6);
					}
				}
				Component[] componentsInChildren6 = ((Component)val4).GetComponentsInChildren<Component>(true);
				foreach (Component val7 in componentsInChildren6)
				{
					if ((Object)(object)val7 != (Object)null && ((object)val7).GetType().FullName == "UnityEngine.Rendering.HighDefinition.DecalProjector")
					{
						nonVictimDecalProjectors.Add(val7);
					}
				}
			}
		}

		private void CullModelReplacement(PlayerControllerB p, bool isCursingPlayer)
		{
			Component val = null;
			Component[] components = ((Component)p).GetComponents<Component>();
			foreach (Component val2 in components)
			{
				if ((Object)(object)val2 != (Object)null && ((object)val2).GetType().Name == "BodyReplacementBase")
				{
					val = val2;
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				Type type = ((object)val).GetType();
				string[] array = new string[3] { "replacementModel", "replacementViewModel", "replacementModelShadow" };
				string[] array2 = array;
				foreach (string name in array2)
				{
					FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field == null)
					{
						continue;
					}
					object? value = field.GetValue(val);
					GameObject val3 = (GameObject)((value is GameObject) ? value : null);
					if ((Object)(object)val3 == (Object)null)
					{
						continue;
					}
					Renderer[] componentsInChildren = val3.GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val4 in componentsInChildren)
					{
						if ((Object)(object)val4 == (Object)null || ((Object)((Component)val4).gameObject).name.Contains("CloneNametag"))
						{
							continue;
						}
						SkinnedMeshRenderer val5 = (SkinnedMeshRenderer)(object)((val4 is SkinnedMeshRenderer) ? val4 : null);
						if (val5 != null)
						{
							if (isCursingPlayer)
							{
								victimBodyRenderers.Add(val5);
							}
							else
							{
								nonVictimBodyRenderers.Add(val5);
							}
							continue;
						}
						MeshRenderer val6 = (MeshRenderer)(object)((val4 is MeshRenderer) ? val4 : null);
						if (val6 != null)
						{
							if (isCursingPlayer)
							{
								victimDefaultMeshRenderers.Add(val6);
							}
							else
							{
								nonVictimDefaultMeshRenderers.Add(val6);
							}
						}
					}
				}
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"VECNA: Error culling model replacement for {p.playerUsername}: {arg}");
			}
		}

		private Vector3 CalculatePortalPosition()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_00e7: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_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_009b: 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)
			GameObject[] array = (cursingPlayer.isInsideFactory ? insideNodes : outsideNodes);
			if (array != null)
			{
				GameObject[] array2 = array;
				foreach (GameObject val in array2)
				{
					if (!((Object)(object)val == (Object)null))
					{
						float num = Vector3.Distance(((Component)cursingPlayer).transform.position, val.transform.position);
						if (num > 10f && num < 35f)
						{
							return val.transform.position + Vector3.up * 1.5f;
						}
					}
				}
			}
			return ((Component)cursingPlayer).transform.position + ((Component)cursingPlayer).transform.forward * 15f + Vector3.up * 1.5f;
		}

		private void SetDecalEnabled(Component decal, bool enabled)
		{
			if ((Object)(object)decal == (Object)null)
			{
				return;
			}
			try
			{
				PropertyInfo property = ((object)decal).GetType().GetProperty("enabled");
				if (property != null)
				{
					property.SetValue(decal, enabled);
				}
			}
			catch (Exception arg)
			{
				Debug.LogWarning((object)$"VECNA: Failed to set DecalProjector enabled to {enabled}: {arg}");
			}
		}

		private void OnLocalPhaseChanged(VecnaPhase oldPhase, VecnaPhase newPhase)
		{
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			Debug.Log((object)$"VECNA: Local Phase Changed from {oldPhase} to {newPhase}");
			if (newPhase == VecnaPhase.HauntChase)
			{
				if (!IsVictimOrSpectatingVictim())
				{
					SpawnPlayerClone();
				}
				if ((Object)(object)cursingPlayer != (Object)null)
				{
					VecnaVFXHelper.TogglePlayerThirdPersonModel(this, cursingPlayer, isVisible: false);
				}
				if (IsVictimOrSpectatingVictim())
				{
					SetMapObjectsVisibility(visible: false);
				}
				else
				{
					if (!((Object)(object)cursingPlayer != (Object)null))
					{
						return;
					}
					HauntVisibilityRegistry.Hide(((Component)cursingPlayer).gameObject, "VecnaHaunt");
					if (cursingPlayer.ItemSlots == null)
					{
						return;
					}
					GrabbableObject[] itemSlots = cursingPlayer.ItemSlots;
					foreach (GrabbableObject val in itemSlots)
					{
						if ((Object)(object)val != (Object)null)
						{
							HauntVisibilityRegistry.Hide(((Component)val).gameObject, "VecnaHaunt");
						}
					}
				}
				return;
			}
			if (oldPhase == VecnaPhase.HauntChase)
			{
				if (cursingLocalPlayer)
				{
					EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>();
					EntranceTeleport[] array2 = array;
					foreach (EntranceTeleport val2 in array2)
					{
						InteractTrigger component = ((Component)val2).GetComponent<InteractTrigger>();
						if ((Object)(object)component != (Object)null)
						{
							component.interactable = true;
						}
					}
				}
				if (newPhase == VecnaPhase.HuntEveryone && ((NetworkBehaviour)this).IsServer && (Object)(object)cursingPlayer != (Object)null && (Object)(object)activeClone != (Object)null && !cursingPlayer.isPlayerDead)
				{
					TeleportSurvivingVictimClientRpc((int)cursingPlayer.playerClientId, activeClone.transform.position, cloneWasTeleportedToShip);
				}
				SetMapObjectsVisibility(visible: true);
			}
			if (newPhase == VecnaPhase.Cooldown)
			{
				StopAllSFX();
			}
			if (newPhase == VecnaPhase.HuntEveryone && (Object)(object)currentClock != (Object)null)
			{
				Object.Destroy((Object)(object)currentClock);
				currentClock = null;
			}
			DestroyActiveClone();
			if (portalManager != null)
			{
				portalManager.DestroyEscapePortal();
			}
			if ((Object)(object)cursingPlayer != (Object)null)
			{
				VecnaVFXHelper.TogglePlayerThirdPersonModel(this, cursingPlayer, isVisible: true);
			}
			if (newPhase != VecnaPhase.HuntEveryone)
			{
				enemyMeshEnabled = false;
				((EnemyAI)this).EnableEnemyMesh(false, true, true);
			}
			else if ((Object)(object)base.enemyType != (Object)null)
			{
				base.enemyType.canDie = true;
				base.enemyType.canBeStunned = true;
			}
		}

		private void SetMapObjectsVisibility(bool visible)
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (!((Object)(object)val != (Object)null))
				{
					continue;
				}
				if (visible)
				{
					HauntVisibilityRegistry.Restore(((Component)val).gameObject, "VecnaHaunt");
					if (val.ItemSlots == null)
					{
						continue;
					}
					GrabbableObject[] itemSlots = val.ItemSlots;
					foreach (GrabbableObject val2 in itemSlots)
					{
						if ((Object)(object)val2 != (Object)null)
						{
							HauntVisibilityRegistry.Restore(((Component)val2).gameObject, "VecnaHaunt");
						}
					}
				}
				else
				{
					if (!val.isPlayerControlled || !((Object)(object)val != (Object)(object)cursingPlayer))
					{
						continue;
					}
					HauntVisibilityRegistry.Hide(((Component)val).gameObject, "VecnaHaunt");
					if (val.ItemSlots == null)
					{
						continue;
					}
					GrabbableObject[] itemSlots2 = val.ItemSlots;
					foreach (GrabbableObject val3 in itemSlots2)
					{
						if ((Object)(object)val3 != (Object)null)
						{
							HauntVisibilityRegistry.Hide(((Component)val3).gameObject, "VecnaHaunt");
						}
					}
				}
			}
			HashSet<GameObject> hashSet = new HashSet<GameObject>();
			if ((Object)(object)cursingPlayer != (Object)null && cursingPlayer.ItemSlots != null)
			{
				GrabbableObject[] itemSlots3 = cursingPlayer.ItemSlots;
				foreach (GrabbableObject val4 in itemSlots3)
				{
					if ((Object)(object)val4 != (Object)null)
					{
						hashSet.Add(((Component)val4).gameObject);
					}
				}
			}
			foreach (GrabbableObject cachedGrabbableObject in cachedGrabbableObjects)
			{
				if ((Object)(object)cachedGrabbableObject != (Object)null && !hashSet.Contains(((Component)cachedGrabbableObject).gameObject))
				{
					cachedGrabbableObject.EnableItemMeshes(visible);
				}
			}
			if (!((Object)(object)RoundManager.Instance != (Object)null) || RoundManager.Instance.SpawnedEnemies == null)
			{
				return;
			}
			foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
			{
				if ((Object)(object)spawnedEnemy != (Object)null && (Object)(object)spawnedEnemy != (Object)(object)this)
				{
					if (visible)
					{
						HauntVisibilityRegistry.Restore(((Component)spawnedEnemy).gameObject, "VecnaHaunt");
					}
					else if (!spawnedEnemy.isEnemyDead)
					{
						HauntVisibilityRegistry.Hide(((Component)spawnedEnemy).gameObject, "VecnaHaunt");
					}
				}
			}
		}

		private void UpdateCachedGrabbables()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			cachedGrabbableObjects.Clear();
			if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.propsContainer != (Object)null)
			{
				foreach (Transform item in StartOfRound.Instance.propsContainer)
				{
					Transform val = item;
					if ((Object)(object)val != (Object)null && ((Component)val).CompareTag("PhysicsProp"))
					{
						GrabbableObject component = ((Component)val).GetComponent<GrabbableObject>();
						if ((Object)(object)component != (Object)null)
						{
							cachedGrabbableObjects.Add(component);
						}
					}
				}
			}
			if ((Object)(object)RoundManager.Instance != (Object)null && (Object)(object)RoundManager.Instance.mapPropsContainer != (Object)null)
			{
				foreach (Transform item2 in RoundManager.Instance.mapPropsContainer.transform)
				{
					Transform val2 = item2;
					if ((Object)(object)val2 != (Object)null && ((Component)val2).CompareTag("PhysicsProp"))
					{
						GrabbableObject component2 = ((Component)val2).GetComponent<GrabbableObject>();
						if ((Object)(object)component2 != (Object)null)
						{
							cachedGrabbableObjects.Add(component2);
						}
					}
				}
			}
			GameObject val3 = GameObject.Find("HangarShip");
			if ((Object)(object)val3 != (Object)null)
			{
				GrabbableObject[] componentsInChildren = val3.GetComponentsInChildren<GrabbableObject>(true);
				GrabbableObject[] array = componentsInChildren;
				foreach (GrabbableObject val4 in array)
				{
					if ((Object)(object)val4 != (Object)null)
					{
						cachedGrabbableObjects.Add(val4);
					}
				}
			}
			foreach (GrabbableObject item3 in levelSpawnedScrap)
			{
				if ((Object)(object)item3 != (Object)null)
				{
					cachedGrabbableObjects.Add(item3);
				}
			}
		}

		private void SpawnLairAndPortal()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			VecnaLairPortal vecnaLairPortal = null;
			if ((Object)(object)atticPrefab != (Object)null)
			{
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(1500f, -200f, 1500f);
				GameObject val2 = Object.Instantiate<GameObject>(atticPrefab, val, Quaternion.identity);
				NetworkObject component = val2.GetComponent<NetworkObject>();
				if ((Object)(object)component != (Object)null)
				{
					component.Spawn(false);
				}
				else
				{
					Debug.LogWarning((object)"VECNA: atticPrefab is missing a NetworkObject component!");
				}
				vecnaLairPortal = (activeExitPortal = val2.GetComponentInChildren<VecnaLairPortal>());
			}
			VecnaLairPortal vecnaLairPortal2 = null;
			if ((Object)(object)lairEntrancePortalPrefab != (Object)null && insideNodes != null && insideNodes.Length != 0)
			{
				GameObject val3 = insideNodes[Random.Range(0, insideNodes.Length)];
				if ((Object)(object)val3 != (Object)null)
				{
					portalSpawnNode = val3;
					Vector3 val4 = val3.transform.position;
					RaycastHit val5 = default(RaycastHit);
					if (Physics.Raycast(val3.transform.position + Vector3.up * 1.5f, Vector3.down, ref val5, 10f, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
					{
						val4 = ((RaycastHit)(ref val5)).point + Vector3.up * 0.15f;
					}
					GameObject val6 = Object.Instantiate<GameObject>(lairEntrancePortalPrefab, val4, Quaternion.identity);
					NetworkObject component2 = val6.GetComponent<NetworkObject>();
					if ((Object)(object)component2 != (Object)null)
					{
						component2.Spawn(false);
					}
					else
					{
						Debug.LogWarning((object)"VECNA: lairEntrancePortalPrefab is missing a NetworkObject component!");
					}
					vecnaLairPortal2 = (activeEntrancePortal = val6.GetComponent<VecnaLairPortal>());
				}
			}
			if ((Object)(object)vecnaLairPortal != (Object)null && (Object)(object)vecnaLairPortal2 != (Object)null)
			{
				vecnaLairPortal2.teleportDestination = ((Component)vecnaLairPortal).transform;
				vecnaLairPortal.teleportDestination = ((Component)vecnaLairPortal2).transform;
			}
			Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
			foreach (Collider val7 in componentsInChildren)
			{
				if (!((Object)(object)val7 != (Object)null))
				{
					continue;
				}
				if ((Object)(object)vecnaLairPortal != (Object)null)
				{
					Collider[] componentsInChildren2 = ((Component)vecnaLairPortal).GetComponentsInChildren<Collider>(true);
					foreach (Collider val8 in componentsInChildren2)
					{
						Physics.IgnoreCollision(val7, val8, true);
					}
				}
				if ((Object)(object)vecnaLairPortal2 != (Object)null)
				{
					Collider[] componentsInChildren3 = ((Component)vecnaLairPortal2).GetComponentsInChildren<Collider>(true);
					foreach (Collider val9 in componentsInChildren3)
					{
						Physics.IgnoreCollision(val7, val9, true);
					}
				}
			}
		}

		private void OnEnable()
		{
			VecnaEventManager.OnShipLeft += OnShipLeft;
			VecnaEventManager.OnPlayerDied += OnVictimDied;
			VecnaEventManager.OnPlayerDisconnect += OnVictimDisconnected;
		}

		private void OnDisable()
		{
			VecnaEventManager.OnShipLeft -= OnShipLeft;
			VecnaEventManager.OnPlayerDied -= OnVictimDied;
			VecnaEventManager.OnPlayerDisconnect -= OnVictimDisconnected;
		}

		private void OnShipLeft()
		{
			if (currentLocalPhase == VecnaPhase.HauntChase || currentLocalPhase == VecnaPhase.ClockStalking)
			{
				ResetHaunt(repelledByMusic: true);
			}
		}

		private void OnVictimDied(PlayerControllerB deadPlayer)
		{
			if (((NetworkBehaviour)this).IsServer && !((Object)(object)cursingPlayer != (Object)(object)deadPlayer))
			{
				if (currentLocalPhase != VecnaPhase.Cooldown)
				{
					ResetHaunt(repelledByMusic: false);
				}
				else if (currentLocalPhase == VecnaPhase.Cooldown && hauntCooldownTimer <= 0f)
				{
					Debug.Log((object)"Target missing/dead. Choosing new victim!");
					ChoosePlayerToCurse();
					ChangePhaseSafely(VecnaPhase.ClockStalking);
				}
			}
		}

		private void OnVictimDisconnected(PlayerControllerB disconnectedPlayer)
		{
			OnVictimDied(disconnectedPlayer);
		}

		[ClientRpc]
		public void TeleportSurvivingVictimClientRpc(int playerId, Vector3 clonePos, bool cloneWasTeleportedToShip)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_0097: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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 != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1906456759u, val2, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, playerId);
				((FastBufferWriter)(ref val)).WriteValueSafe(ref clonePos);
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref cloneWasTeleportedToShip, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 1906456759u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			PlayerControllerB val3 = StartOfRound.Instance.allPlayerScripts[playerId];
			if ((Object)(object)val3 == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				isTeleportingVictimFromVecna = true;
				((Collider)val3.thisController).enabled = false;
				val3.TeleportPlayer(clonePos, false, 0f, false, true);
				if (cloneWasTeleportedToShip && val3.isInsideFactory)
				{
					val3.isInsideFactory = false;
				}
				((Collider)val3.thisController).enabled = true;
				isTeleportingVictimFromVecna = false;
			}
		}

		public void ResetHaunt(bool repelledByMusic, bool playerKilled = false)
		{
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			if (isHuntingEveryone && !StartOfRound.Instance.shipIsLeaving)
			{
				return;
			}
			if ((Object)(object)cursingPlayer != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)cursingPlayer)
			{
				EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>();
				EntranceTeleport[] array2 = array;
				foreach (EntranceTeleport val in array2)
				{
					InteractTrigger component = ((Component)val).GetComponent<InteractTrigger>();
					if ((Object)(object)component != (Object)null)
					{
						component.interactable = true;
					}
				}
			}
			if (!playerKilled && (Object)(object)cursingPlayer != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)cursingPlayer)
			{
				PlayEscapeVoiceLineToVictim();
			}
			enemyMeshEnabled = false;
			((EnemyAI)this).EnableEnemyMesh(false, true, true);
			if (((NetworkBehaviour)this).IsServer)
			{
				if ((Object)(object)cursingPlayer != (Object)null)
				{
					Vector3 clonePos = ((serverVictimClonePos != Vector3.zero) ? serverVictimClonePos : (((Object)(object)activeClone != (Object)null) ? activeClone.transform.position : ((localVictimClonePos != Vector3.zero) ? localVictimClonePos : victimStartingPosition)));
					TeleportSurvivingVictimClientRpc((int)cursingPlayer.playerClientId, clonePos, cloneWasTeleportedToShip);
				}
				DestroyActiveClone();
				isPortalOpen = false;
				serverVictimClonePos = Vector3.zero;
			}
			hasStartedChase = false;
			stareTimer = 0f;
			chaseTimer = 0f;
			timesClockSpawned = 0;
			hasTauntedForCurrentClock = false;
			base.movingTowardsTargetPlayer = false;
			if ((Object)(object)base.agent != (Object)null && base.agent.isOnNavMesh)
			{
				base.agent.speed = 0f;
				base.agent.velocity = Vector3.zero;
				base.agent.isStopped = true;
				base.agent.ResetPath();
			}
			hauntCooldownTimer = clockSpawnInterval;
			if (portalManager != null)
			{
				portalManager.DestroyEscapePortal();
			}
			serverSpawnedClone = false;
			boomboxRescueTimer = 0f;
			hauntCooldownTimer = clockSpawnInterval;
			if (playerKilled)
			{
				Debug.Log((object)"VECNA: Player killed successfully. Sequence complete.");
			}
			isInLair = false;
			base.isOutside = false;
			if (((NetworkBehaviour)this).IsServer)
			{
				SyncLairStateClientRpc(inLair: false);
				SyncOutsideStateClientRpc(outside: false);
			}
			StopAllSFX();
			ChangePhaseSafely(VecnaPhase.Cooldown);
			cursingPlayer = null;
			cursingLocalPlayer = false;
		}

		private void PerformSlowEnvironmentScan()
		{
			slowScanTimer += Time.deltaTime;
			if (slowScanTimer >= 2f)
			{
				slowScanTimer = 0f;
				cachedBoomboxes = Object.FindObjectsOfType<BoomboxItem>();
				UpdateCachedGrabbables();
			}
		}

		public override void OnDestroy()
		{
			((EnemyAI)this).OnDestroy();
			if ((Object)(object)currentClock != (Object)null)
			{
				Object.Destroy((Object)(object)currentClock);
			}
			DestroyActiveClone();
			if ((Object)(object)activeFakeBody != (Object)null)
			{
				Object.Destroy((Object)(object)activeFakeBody);
				activeFakeBody = null;
			}
			StopAllSFX();
			Debug.Log((object)"Destroyed. Round wiped and memory cleared.");
		}

		public void ChoosePlayerToCurse()
		{
			timesClockSpawned = 0;
			clockTimer = 0f;
			if (!initializedRandomSeed)
			{
				vecnaCurseRandom = new Random(StartOfRound.Instance.randomMapSeed + 158);
				initializedRandomSeed = true;
			}
			float num = 0f;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			int num5 = StartOfRound.Instance.allPlayerScripts.Length;
			for (int i = 0; i < num5; i++)
			{
				PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[i];
				if (!((Object)(object)val == (Object)null))
				{
					if (StartOfRound.Instance.gameStats != null && StartOfRound.Instance.gameStats.allPlayerStats != null && i < StartOfRound.Instance.gameStats.allPlayerStats.Length && StartOfRound.Instance.gameStats.allPlayerStats[i].turnAmount > num3)
					{
						num3 = StartOfRound.Instance.gameStats.allPlayerStats[i].turnAmount;
						num4 = i;
					}
					if (val.insanityLevel > num)
					{
						num = val.insanityLevel;
						num2 = i;
					}
				}
			}
			int[] array = new int[num5];
			for (int j = 0; j < num5; j++)
			{
				PlayerControllerB val2 = StartOfRound.Instance.allPlayerScripts[j];
				if ((Object)(object)val2 == (Object)null || !val2.isPlayerControlled || val2.isPlayerDead)
				{
					array[j] = 0;
					continue;
				}
				array[j] += 80;
				if (num2 == j && num > 1f)
				{
					array[j] += 50;
				}
				if (num4 == j)
				{
					array[j] += 30;
				}
				if (!val2.hasBeenCriticallyInjured)
				{
					array[j] += 10;
				}
				if ((Object)(object)val2.currentlyHeldObjectServer != (Object)null && val2.currentlyHeldObjectServer.scrapValue > 150)
				{
					array[j] += 30;
				}
			}
			int randomWeightedIndex = RoundManager.Instance.GetRandomWeightedIndex(array, vecnaCurseRandom);
			cursingPlayer = StartOfRound.Instance.allPlayerScripts[randomWeightedIndex];
			if ((Object)(object)cursingPlayer == (Object)null)
			{
				cursingPlayer = GameNetworkManager.Instance.localPlayerController;
			}
			if ((Object)(object)cursingPlayer != (Object)null)
			{
				((EnemyAI)this).ChangeOwnershipOfEnemy(cursingPlayer.actualClientId);
				cursingLocalPlayer = (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)cursingPlayer;
				if (((NetworkBehaviour)this).IsServer)
				{
					SyncVictimClientRpc((int)cursingPlayer.playerClientId);
				}
			}
		}

		private IEnumerator NosebleedRoutine(PlayerControllerB victim)
		{
			yield return (object)new WaitForSeconds(5f);
			if ((Object)(object)victim != (Object)null && !victim.isPlayerDead)
			{
				victim.bloodDropTimer = -1f;
				victim.DropBlood(Vector3.down, true, false);
				yield return (object)new WaitForSeconds(1.5f);
				if ((Object)(object)victim != (Object)null && !victim.isPlayerDead)
				{
					victim.bloodDropTimer = -1f;
					victim.DropBlood(Vector3.down, true, false);
				}
				yield return (object)new WaitForSeconds(2f);
				if ((Object)(object)victim != (Object)null && !victim.isPlayerDead)
				{
					victim.bloodDropTimer = -1f;
					victim.DropBlood(Vector3.down, true, false);
				}
			}
		}

		public override void HitEnemy(int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
		{
			if (currentLocalPhase != VecnaPhase.HuntEveryone)
			{
				return;
			}
			((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitID);
			if (!base.isEnemyDead)
			{
				base.enemyHP -= force;
				if (base.enemyHP <= 0)
				{
					((EnemyAI)this).KillEnemyOnOwnerClient(false);
				}
			}
		}

		public override void SetEnemyStunned(bool setToStunned, float setToStunTime = 1f, PlayerControllerB setStunnedByPlayer = null)
		{
			if (currentLocalPhase != VecnaPhase.HuntEveryone)
			{
				return;
			}
			((EnemyAI)this).SetEnemyStunned(setToStunned, setToStunTime, setStunnedByPlayer);
			if (setToStunned)
			{
				isCastingTelekinesis = false;
				isPullingPlayer = false;
				if ((Object)(object)base.creatureVoice != (Object)null && base.creatureVoice.loop)
				{
					base.creatureVoice.Stop();
					base.creatureVoice.loop = false;
				}
				if ((Object)(object)base.creatureVoice != (Object)null && (Object)(object)stunnedVoiceClip != (Object)null)
				{
					base.creatureVoice.PlayOneShot(stunnedVoiceClip, 1f);
				}
				if ((Object)(object)base.creatureAnimator != (Object)null)
				{
					base.creatureAnimator.SetTrigger("isStunned");
					base.creatureAnimator.SetBool("isPulling", false);
				}
			}
		}

		public override void KillEnemy(bool destroy = false)
		{
			if (currentLocalPhase == VecnaPhase.HuntEveryone)
			{
				((EnemyAI)this).KillEnemy(destroy);
				if ((Object)(object)base.creatureVoice != (Object)null && (Object)(object)base.dieSFX != (Object)null)
				{
					base.creatureVoice.PlayOneShot(base.dieSFX, 1f);
				}
				if ((Object)(object)base.creatureAnimator != (Object)null)
				{
					base.creatureAnimator.SetTrigger("vecnaDie");
				}
				if ((Object)(object)auraVisualEffect != (Object)null)
				{
					auraVisualEffect.Stop();
				}
				StopAllSFX();
			}
		}

		private void StartPullingPlayer()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			isPullingPlayer = true;
			if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).isActiveAndEnabled && base.agent.isOnNavMesh)
			{
				base.agent.speed = 0f;
				base.agent.velocity = Vector3.zero;
				base.agent.isStopped = true;
				base.agent.ResetPath();
			}
			if ((Object)(object)telePullParticle != (Object)null)
			{
				telePullParticle.Play();
			}
		}

		private void StopPullingPlayer()
		{
			isPullingPlayer = false;
			if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).isActiveAndEnabled && base.agent.isOnNavMesh)
			{
				base.agent.isStopped = false;
			}
			if ((Object)(object)telePullParticle != (Object)null)
			{
				telePullParticle.Stop();
			}
		}

		public override void DoAIInterval()
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: 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_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_073b: Unknown result type (might be due to invalid IL or missing references)
			//IL_074d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0759: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0834: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_07df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: 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_0818: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_058c: Unknown result type (might be due to invalid IL or missing references)
			//IL_059e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0621: Unknown result type (might be due to invalid IL or missing references)
			//IL_0633: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0688: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).DoAIInterval();
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			if (isPullingPlayer || base.inSpecialAnimation || base.stunNormalizedTimer > 0f)
			{
				if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).isActiveAndEnabled && base.agent.isOnNavMesh)
				{
					base.agent.speed = 0f;
					base.agent.velocity = Vector3.zero;
					base.agent.isStopped = true;
					base.agent.ResetPath();
				}
				return;
			}
			if (isInLair)
			{
				if ((Object)(object)lairTrigger != (Object)null)
				{
					string text = string.Join(", ", lairTrigger.playersInLair.ConvertAll((PlayerControllerB p) => p.playerUsername));
				}
				if (((NetworkBehaviour)this).IsOwner)
				{
					bool flag = false;
					if ((Object)(object)lairTrigger != (Object)null)
					{
						flag = lairTrigger.playersInLair.Count > 0;
					}
					if (!flag && (Object)(object)activeEntrancePortal != (Object)null)
					{
						Vector3 val = (((Object)(object)portalSpawnNode != (Object)null) ? portalSpawnNode.transform.position : ((Component)activeEntrancePortal).transform.position);
						if (((Behaviour)base.agent).isActiveAndEnabled)
						{
							base.agent.ResetPath();
						}
						base.movingTowardsTargetPlayer = false;
						((Behaviour)base.agent).enabled = false;
						((Component)this).transform.position = val;
						base.serverPosition = val;
						((Behaviour)base.agent).enabled = true;
						bool flag2 = base.agent.Warp(val);
						base.isOutside = false;
						isInLair = false;
						TeleportVecnaThroughPortalServerRpc(val, inLair: false);
					}
				}
				if (((NetworkBehaviour)this).IsOwner && isInLair)
				{
					PlayerControllerB val2 = null;
					float num = 9999f;
					if ((Object)(object)lairTrigger != (Object)null)
					{
						foreach (PlayerControllerB item in lairTrigger.playersInLair)
						{
							float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)item).transform.position);
							if (num2 < num)
							{
								num = num2;
								val2 = item;
							}
						}
					}
					if ((Object)(object)val2 != (Object)null)
					{
						base.targetPlayer = val2;
						((EnemyAI)this).SetMovingTowardsTargetPlayer(val2);
					}
				}
			}
			if ((currentLocalPhase != VecnaPhase.HauntChase && !isHuntingEveryone) || !((NetworkBehaviour)this).IsOwner || isInLair)
			{
				return;
			}
			if (isHuntingEveryone)
			{
				if (BreakIntoShip())
				{
					return;
				}
				PlayerControllerB val3 = null;
				float num3 = 9999f;
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val4 in allPlayerScripts)
				{
					if (!((Object)(object)val4 == (Object)null) && !val4.isPlayerDead && val4.isPlayerControlled)
					{
						float num5 = Vector3.Distance(((Component)this).transform.position, ((Component)val4).transform.position);
						if (num5 < num3 && num5 < 100f && !Physics.Linecast(((Component)this).transform.position + Vector3.up, ((Component)val4.gameplayCamera).transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
						{
							val3 = val4;
							num3 = num5;
						}
					}
				}
				if ((Object)(object)val3 != (Object)null)
				{
					base.targetPlayer = val3;
					cursingPlayer = val3;
				}
				else
				{
					((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f, false, false, true);
					if ((Object)(object)base.targetPlayer == (Object)null)
					{
						PlayerControllerB targetPlayer = null;
						float num6 = 9999f;
						PlayerControllerB[] allPlayerScripts2 = StartOfRound.Instance.allPlayerScripts;
						foreach (PlayerControllerB val5 in allPlayerScripts2)
						{
							if (!((Object)(object)val5 == (Object)null) && !val5.isPlayerDead && val5.isPlayerControlled)
							{
								float num8 = Vector3.Distance(((Component)this).transform.position, ((Component)val5).transform.position);
								if (num8 < num6)
								{
									num6 = num8;
									targetPlayer = val5;
								}
							}
						}
						base.targetPlayer = targetPlayer;
					}
					if ((Object)(object)base.targetPlayer != (Object)null)
					{
						cursingPlayer = base.targetPlayer;
					}
				}
				if (!((Object)(object)base.targetPlayer != (Object)null) || !((Behaviour)base.agent).isActiveAndEnabled || !base.agent.isOnNavMesh)
				{
					return;
				}
				bool flag3 = IsPlayerInLair(base.targetPlayer);
				if (!isInLair && flag3)
				{
					VecnaLairPortal vecnaLairPortal = activeEntrancePortal;
					if ((Object)(object)vecnaLairPortal != (Object)null)
					{
						((EnemyAI)this).SetDestinationToPosition(((Component)vecnaLairPortal).transform.position, true);
						if (Vector3.Distance(((Component)this).transform.position, ((Component)vecnaLairPortal).transform.position) < 3f)
						{
							vecnaLairPortal.TeleportVecna(this);
						}
					}
				}
				else if (!isInLair && base.isOutside != !base.targetPlayer.isInsideFactory)
				{
					EntranceTeleport closestDoorToVecna = GetClosestDoorToVecna();
					if (!((Object)(object)closestDoorToVecna != (Object)null))
					{
						return;
					}
					((EnemyAI)this).SetDestinationToPosition(((Component)closestDoorToVecna).transform.position, false);
					if (Vector3.Distance(((Component)this).transform.position, ((Component)closestDoorToVecna).transform.position) < 4f)
					{
						EntranceTeleport correspondingDoor = GetCorrespondingDoor(closestDoorToVecna);
						if ((Object)(object)correspondingDoor != (Object)null)
						{
							bool setOutside = !base.targetPlayer.isInsideFactory;
							TeleportEnemyClientRpc(correspondingDoor.entrancePoint.position, setOutside);
						}
					}
				}
				else
				{
					((EnemyAI)this).SetDestinationToPosition(((Component)base.targetPlayer).transform.position, true);
				}
				return;
			}
			PlayerControllerB val6 = cursingPlayer;
			if (!((Object)(object)val6 != (Object)null) || !((Behaviour)base.agent).isActiveAndEnabled || !base.agent.isOnNavMesh)
			{
				return;
			}
			bool flag4 = !val6.isInsideFactory;
			bool flag5 = IsPlayerInLair(val6);
			if (!isInLair && flag5)
			{
				VecnaLairPortal vecnaLairPortal2 = activeEntrancePortal;
				if ((Object)(object)vecnaLairPortal2 != (Object)null)
				{
					((EnemyAI)this).SetDestinationToPosition(((Component)vecnaLairPortal2).transform.position, true);
					if (Vector3.Distance(((Component)this).transform.position, ((Component)vecnaLairPortal2).transform.position) < 3f)
					{
						vecnaLairPortal2.TeleportVecna(this);
					}
				}
			}
			else if (!isInLair && base.isOutside != flag4)
			{
				EntranceTeleport closestDoorToVecna2 = GetClosestDoorToVecna();
				if (!((Object)(object)closestDoorToVecna2 != (Object)null))
				{
					return;
				}
				((EnemyAI)this).SetDestinationToPosition(((Component)closestDoorToVecna2).transform.position, false);
				if (Vector3.Distance(((Component)this).transform.position, ((Component)closestDoorToVecna2).transform.position) < 4f)
				{
					EntranceTeleport correspondingDoor2 = GetCorrespondingDoor(closestDoorToVecna2);
					if ((Object)(object)correspondingDoor2 != (Object)null)
					{
						TeleportEnemyClientRpc(correspondingDoor2.entrancePoint.position, flag4);
					}
				}
			}
			else
			{
				((EnemyAI)this).SetDestinationToPosition(((Component)val6).transform.position, true);
			}
		}

		public override void Update()
		{
			//IL_003a: 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_005a: 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_0081: 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_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_0652: Unknown result type (might be due to invalid IL or missing references)
			//IL_0640: Unknown result type (might be due to invalid IL or missing references)
			//IL_0657: Unknown result type (might be due to invalid IL or missing references)
			//IL_065b: 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_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cb1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a3a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d1c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d2c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d50: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d55: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d5f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d64: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d79: Unknown result type (might be due to invalid IL or missing references)
			if (isPryingDoor && base.inSpecialAnimation && (Object)(object)shipDoor != (Object)null)
			{
				((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, shipDoor.outsideDoorPoint.position, 7f * Time.deltaTime);
				((Component)this).transform.rotation = Quaternion.Lerp(((Component)this).transform.rotation, shipDoor.outsideDoorPoint.rotation, 7f * Time.deltaTime);
				pryingDoorAnimTime = Mathf.Min(pryingDoorAnimTime + Time.deltaTime / pryOpenDoorAnimLength, 1f);
				shipDoor.shipDoorsAnimator.SetFloat("pryOpenDoor", pryingDoorAnimTime);
				if (pryingDoorAnimTime >= 0.5f && !hasTriggeredThrowAnim)
				{
					if ((Object)(object)base.creatureAnimator != (Object)null)
					{
						base.creatureAnimator.SetTrigger("teleThrow");
					}
					hasTriggeredThrowAnim = true;
				}
				BreakIntoShip();
				return;
			}
			if (((NetworkBehaviour)this).IsServer && serverTelekinesisCooldownTimer > 0f)
			{
				serverTelekinesisCooldownTimer -= Time.deltaTime;
			}
			if (queuedPhase.HasValue && !base.inSpecialAnimation)
			{
				ChangePhaseSafely(queuedPhase.Value);
				queuedPhase = null;
			}
			((EnemyAI)this).Update();
			PerformSlowEnvironmentScan();
			UpdateGlobalVisuals();
			HandleBreathing();
			if (isHuntingEveryone && ((NetworkBehaviour)this).IsOwner)
			{
				if (blastCooldownTimer > 0f)
				{
					blastCooldownTimer -= Time.deltaTime;
				}
				else if (!isCastingTelekinesis && !base.inSpecialAnimation)
				{
					bool flag = false;
					PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
					foreach (PlayerControllerB val in allPlayerScripts)
					{
						if ((Object)(object)val != (Object)null && !val.isPlayerDead && val.isPlayerControlled && Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position) < 2.5f)
						{
							flag = true;
							break;
						}
					}
					if (flag)
					{
						blastCooldownTimer = blastCooldown;
						RequestBlastServerRpc();
					}
				}
			}
			if (base.currentBehaviourStateIndex != 4)
			{
				if (!((NetworkBehaviour)this).IsOwner && !isHuntingEveryone)
				{
					if (enemyMeshEnabled)
					{
						enemyMeshEnabled = false;
						((EnemyAI)this).EnableEnemyMesh(false, true, false);
					}
				}
				else if ((Object)(object)cursingPlayer != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)(object)cursingPlayer && !isHuntingEveryone)
				{
					((EnemyAI)this).ChangeOwnershipOfEnemy(cursingPlayer.actualClientId);
				}
			}
			if (isInLair && (Object)(object)lairTrigger != (Object)null)
			{
				Collider component = ((Component)lairTrigger).GetComponent<Collider>();
				if ((Object)(object)component != (Object)null)
				{
					Bounds bounds = component.bounds;
					if (!((Bounds)(ref bounds)).Contains(((Component)this).transform.position))
					{
						isInLair = false;
						base.isOutside = false;
						if (((NetworkBehaviour)this).IsServer)
						{
							SyncLairStateClientRpc(inLair: false);
							SyncOutsideStateClientRpc(outside: false);
							((EnemyAI)this).SyncPositionToClients();
						}
					}
				}
			}
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			if (((NetworkBehaviour)this).IsServer)
			{
				if (base.currentBehaviourStateIndex == 3 || base.currentBehaviourStateIndex == 4)
				{
					bool flag2 = false;
					if (base.currentBehaviourStateIndex == 3 && (Object)(object)cursingPlayer != (Object)null)
					{
						flag2 = !cursingPlayer.HasLineOfSightToPosition(((Component)this).transform.position, 60f, 60, 2f, -1);
					}
					else if (base.currentBehaviourStateIndex == 4)
					{
						bool flag3 = false;
						PlayerControllerB[] allPlayerScripts2 = StartOfRound.Instance.allPlayerScripts;
						foreach (PlayerControllerB val2 in allPlayerScripts2)
						{
							if ((Object)(object)val2 != (Object)null && val2.isPlayerControlled && !val2.isPlayerDead && val2.HasLineOfSightToPosition(((Component)this).transform.position, 60f, 60, 2f, -1))
							{
								flag3 = true;
								break;
							}
						}
						flag2 = !flag3;
					}
					if (flag2)
					{
						outOfLOSTimer += Time.deltaTime;
						if (outOfLOSTimer >= 20f)
						{
							outOfLOSTimer = 0f;
							if (outOfLOSVoiceLines != null && outOfLOSVoiceLines.Length != 0)
							{
								int clipIndex = Random.Range(0, outOfLOSVoiceLines.Length);
								PlayOutOfLOSVoiceLineClientRpc(clipIndex);
							}
						}
					}
					else
					{
						outOfLOSTimer = 0f;
					}
				}
				else
				{
					outOfLOSTimer = 0f;
				}
			}
			if (currentLocalPhase != VecnaPhase.HauntChase)
			{
				hasStartedChase = false;
				serverSpawnedClone = false;
				flickerTimer = 0f;
			}
			else
			{
				flickerTimer += Time.deltaTime;
				if (isLightFlickerOn && flickerTimer >= 1.5f)
				{
					flickerTimer = 0f;
					Vector3 clonePos = (((Object)(object)activeClone != (Object)null) ? activeClone.transform.position : localVictimClonePos);
					((MonoBehaviour)this).StartCoroutine(FlickerPoweredLightsNearClone(clonePos, flickerFlashlights: true, disableFlashlights: true));
				}
			}
			BoomboxCheck();
			if (portalManager != null)
			{
				portalManager.UpdatePortalRotation();
			}
			doorSlamTimer += Time.deltaTime;
			if (doorSlamTimer > 1.5f)
			{
				doorSlamTimer = 0f;
				SlamNearbyDoorsCheck();
			}
			if (((NetworkBehaviour)this).IsServer && base.currentBehaviourStateIndex >= 1 && base.currentBehaviourStateIndex < 4 && !base.inSpecialAnimation && ((Object)(object)cursingPlayer == (Object)null || cursingPlayer.isPlayerDead || !cursingPlayer.isPlayerControlled))
			{
				Debug.Log((object)"VECNA: Target died/DC'd mid-hunt! Resetting to Cooldown...");
				ResetHaunt(repelledByMusic: false);
				return;
			}
			if ((Object)(object)footstepsAudio != (Object)null)
			{
				if (base.currentBehaviourStateIndex == 3)
				{
					footstepsAudio.volume = (IsVictimOrSpectatingVictim() ? 1f : 0f);
					if ((Object)(object)breathingAudioSource != (Object)null)
					{
						breathingAudioSource.volume = (IsVictimOrSpectatingVictim() ? 1f : 0f);
					}
				}
				else if (base.currentBehaviourStateIndex == 4)
				{
					footstepsAudio.volume = 1f;
					if ((Object)(object)breathingAudioSource != (Object)null)
					{
						breathingAudioSource.volume = 1f;
					}
				}
				else
				{
					footstepsAudio.volume = 0f;
					if ((Object)(object)breathingAudioSource != (Object)null)
					{
						breathingAudioSource.volume = 0f;
					}
				}
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
				if (!((NetworkBehaviour)this).IsServer)
				{
					break;
				}
				if (hauntCooldownTimer > 0f)
				{
					hauntCooldownTimer -= Time.deltaTime;
					break;
				}
				if ((Object)(object)cursingPlayer == (Object)null || cursingPlayer.isPlayerDead || !cursingPlayer.isPlayerControlled)
				{
					Debug.Log((object)"VECNA: Target missing/dead. Choosing new victim!");
					ChoosePlayerToCurse();
				}
				if (timesClockSpawned > 0)
				{
					ChangePhaseSafely(VecnaPhase.ClockStalking);
					break;
				}
				clockTimer += Time.deltaTime;
				if (clockTimer >= 3f)
				{
					clockTimer = 0f;
					ChangePhaseSafely(VecnaPhase.ClockStalking);
				}
				break;
			case 1:
				if (!((NetworkBehaviour)this).IsOwner || (Object)(object)cursingPlayer == (Object)null)
				{
					break;
				}
				if (timesClockSpawned >= 3)
				{
					if ((Object)(object)GetPlayerVehicle(cursingPlayer) == (Object)null)
					{
						ChangePhaseSafely(VecnaPhase.HauntChase);
					}
				}
				else if ((Object)(object)currentClock == (Object)null && !waitingForPhaseChange)
				{
					if (!IsMusicPlayingNearVictim())
					{
						TrySpawningClock();
						clockLifetimeTimer = 0f;
						stareTimer = 0f;
					}
				}
				else
				{
					if (!((Object)(object)currentClock != (Object)null))
					{
						break;
					}
					clockLifetimeTimer += Time.deltaTime;
					if (cursingPlayer.HasLineOfSightToPosition(currentClock.transform.position, 60f, 60, 2f, -1))
					{
						if (stareTimer == 0f && !hasTauntedForCurrentClock)
						{
							hasTauntedForCurrentClock = true;
							SpotClock(timesClockSpawned);
						}
						stareTimer += Time.deltaTime;
					}
					else if (stareTimer > 2f)
					{
						DisappearClock();
					}
					else if (stareTimer > 0f)
					{
						stareTimer = 0f;
					}
					if (clockLifetimeTimer > 20f && (Object)(object)currentClock != (Object)null && stareTimer == 0f)
					{
						if ((Object)(object)HUDManager.Instance != (Object)null)
						{
							HUDManager.Instance.DisplayTip("????", "a clock tolled in the distance", true, false, "LC_Tip1");
						}
						DisappearClock();
					}
				}
				break;
			case 2:
				break;
			case 3:
				if (((NetworkBehaviour)this).IsOwner && !hasStartedChase)
				{
					hasStartedChase = true;
					InitializeHauntChase();
					((EnemyAI)this).SetMovingTowardsTargetPlayer(cursingPlayer);
				}
				if (((NetworkBehaviour)this).IsServer && !base.inSpecialAnimation)
				{
					chaseTimer += Time.deltaTime;
					if (chaseTimer >= hauntChaseTime)
					{
						chaseTimer = 0f;
						Debug.Log((object)$"VECNA: HauntChase {hauntChaseTime}s limit reached! Returning to cooldown.");
						ResetHaunt(repelledByMusic: false);
					}
				}
				break;
			case 4:
			{
				enemyMeshEnabled = true;
				((EnemyAI)this).EnableEnemyMesh(true, true, true);
				if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).isActiveAndEnabled && base.agent.isOnNavMesh)
				{
					if (!isPullingPlayer && !base.inSpecialAnimation && base.stunNormalizedTimer <= 0f)
					{
						base.agent.speed = huntEveryoneChaseSpeed;
						base.agent.isStopped = false;
					}
					else
					{
						base.agent.speed = 0f;
						base.agent.velocity = Vector3.zero;
						base.agent.isStopped = true;
					}
				}
				if (!((NetworkBehaviour)this).IsOwner || !((Object)(object)base.targetPlayer != (Object)null) || isCastingTelekinesis || base.inSpecialAnimation || !(base.stunNormalizedTimer <= 0f))
				{
					break;
				}
				float num = Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position);
				bool flag4 = num <= 15f && (num < 3f || !Physics.Linecast(((Component)this).transform.position + Vector3.up * 1.5f, ((Component)base.targetPlayer.gameplayCamera).transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault));
				if (telekinesisCooldown > 0f)
				{
					telekinesisCooldown -= Time.deltaTime;
				}
				if (flag4)
				{
					telekinesisChargeTimer += Time.deltaTime;
					bool flag5 = num <= 2.5f;
					if (telekinesisCooldown <= 0f && (flag5 || telekinesisChargeTimer >= 2f))
					{
						telekinesisChargeTimer = 0f;
						telekinesisCooldown = 8f;
						if (base.targetPlayer.health < 30)