Decompiled source of NodKraiSuitsVol2 v2.0.0

NodKrai2.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Dissonance;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using ModelReplacement;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("NodKrai2")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("NodKrai2")]
[assembly: AssemblyTitle("NodKrai2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
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;
		}
	}
}
namespace EmotionController
{
	[BepInPlugin("Konk.NodKraiSuits2", "NodKrai Suits Vol2", "2.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class EmotionControllerPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "Konk.NodKraiSuits2";

		private readonly Harmony _harmony = new Harmony("Konk.EmotionControllerFontaineSuits1");

		public static ConfigEntry<bool> Emotions;

		public static ConfigEntry<Key> GlowToggleKeyConfig;

		public static ConfigEntry<bool> CombatModeEnabledConfig;

		public static string MsgGlowSet => "Konk.NodKraiSuits2_EC_GlowSet";

		public static string MsgGlowBroadcast => "Konk.NodKraiSuits2_EC_GlowBroadcast";

		public static string MsgGlowRequest => "Konk.NodKraiSuits2_EC_GlowRequest";

		private void Awake()
		{
			GlowToggleKeyConfig = ((BaseUnityPlugin)this).Config.Bind<Key>("Glow (May Not Be Applicable)", "ToggleKey", (Key)26, "Key that manually toggles the glow on/off. Always active regardless of Combat Mode.");
			CombatModeEnabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Glow (May Not Be Applicable)", "CombatModeEnabled", true, "If true, using a weapon also pulses the glow on (holds, then fades) in addition to manual toggling.");
			Emotions = ((BaseUnityPlugin)this).Config.Bind<bool>("Facial Movements", "Facial Movements", true, "If true, eye tracking, blinking, mouth movements, and glowing bits are enabled on associated models.");
			if (Emotions.Value)
			{
				_harmony.PatchAll(typeof(EmotionControllerPatches));
				_harmony.PatchAll(typeof(WeaponGlowPatches));
			}
		}
	}
	public enum GlowMode
	{
		Manual,
		CombatPulse
	}
	internal class EmotionControllerRegistrationRunner : MonoBehaviour
	{
		public IEnumerator PollAndRegister()
		{
			while (!EmotionControllerPatches.TryRegisterOnce())
			{
				yield return (object)new WaitForSeconds(0.5f);
			}
			EmotionControllerPatches.ResetRegistrationCoroutineFlag();
		}
	}
	internal static class EmotionControllerPatches
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static HandleNamedMessageDelegate <>9__8_0;

			public static HandleNamedMessageDelegate <>9__8_1;

			public static HandleNamedMessageDelegate <>9__8_2;

			internal void <TryRegisterOnce>b__8_0(ulong senderClientId, FastBufferReader reader)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				if (NetworkManager.Singleton.IsServer)
				{
					ulong targetNetId = default(ulong);
					((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref targetNetId, default(ForPrimitives));
					float intensity = default(float);
					((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref intensity, default(ForPrimitives));
					InvokeOnController(targetNetId, "ServerReceiveGlowSet", intensity);
				}
			}

			internal void <TryRegisterOnce>b__8_1(ulong senderClientId, FastBufferReader reader)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				ulong targetNetId = default(ulong);
				((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref targetNetId, default(ForPrimitives));
				float intensity = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref intensity, default(ForPrimitives));
				InvokeOnController(targetNetId, "ApplyGlowStateFromNetwork", intensity);
			}

			internal void <TryRegisterOnce>b__8_2(ulong senderClientId, FastBufferReader reader)
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				if (NetworkManager.Singleton.IsServer)
				{
					ulong num = default(ulong);
					((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num, default(ForPrimitives));
					InvokeOnControllerWithClient(num, "ServerSendGlowStateTo", senderClientId, num);
				}
			}
		}

		private static bool _messagesRegistered;

		private const string RegisteredFlagKey = "EmotionController_GlowMessagesRegistered";

		private static bool _registrationCoroutineStarted;

		private static CustomMessagingManager _registeredMessagingManager;

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		private static void StartOfRound_Awake_Postfix()
		{
			AddEmotionControllerToPrefabs("StartOfRound.Awake");
			RegisterGlowMessagesIfNeeded();
		}

		[HarmonyPatch(typeof(GameNetworkManager), "Start")]
		[HarmonyPostfix]
		private static void GameNetworkManager_Start_Postfix()
		{
			AddEmotionControllerToPrefabs("GameNetworkManager.Start");
			RegisterGlowMessagesIfNeeded();
		}

		internal static void ResetRegistrationCoroutineFlag()
		{
			_registrationCoroutineStarted = false;
		}

		internal static void RegisterGlowMessagesIfNeeded()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			if (!TryRegisterOnce() && !_registrationCoroutineStarted)
			{
				_registrationCoroutineStarted = true;
				EmotionControllerRegistrationRunner emotionControllerRegistrationRunner = new GameObject("EC_RegistrationRunner").AddComponent<EmotionControllerRegistrationRunner>();
				Object.DontDestroyOnLoad((Object)(object)((Component)emotionControllerRegistrationRunner).gameObject);
				((MonoBehaviour)emotionControllerRegistrationRunner).StartCoroutine(emotionControllerRegistrationRunner.PollAndRegister());
			}
		}

		internal static bool TryRegisterOnce()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			NetworkManager singleton = NetworkManager.Singleton;
			if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null)
			{
				return false;
			}
			CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager;
			if (_registeredMessagingManager == customMessagingManager)
			{
				return true;
			}
			string msgGlowSet = EmotionControllerPlugin.MsgGlowSet;
			object obj = <>c.<>9__8_0;
			if (obj == null)
			{
				HandleNamedMessageDelegate val = delegate(ulong senderClientId, FastBufferReader reader)
				{
					//IL_001a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0020: Unknown result type (might be due to invalid IL or missing references)
					//IL_002d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0033: Unknown result type (might be due to invalid IL or missing references)
					if (NetworkManager.Singleton.IsServer)
					{
						ulong targetNetId = default(ulong);
						((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref targetNetId, default(ForPrimitives));
						float intensity = default(float);
						((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref intensity, default(ForPrimitives));
						InvokeOnController(targetNetId, "ServerReceiveGlowSet", intensity);
					}
				};
				<>c.<>9__8_0 = val;
				obj = (object)val;
			}
			customMessagingManager.RegisterNamedMessageHandler(msgGlowSet, (HandleNamedMessageDelegate)obj);
			string msgGlowBroadcast = EmotionControllerPlugin.MsgGlowBroadcast;
			object obj2 = <>c.<>9__8_1;
			if (obj2 == null)
			{
				HandleNamedMessageDelegate val2 = delegate(ulong senderClientId, FastBufferReader reader)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_001a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0020: Unknown result type (might be due to invalid IL or missing references)
					ulong targetNetId = default(ulong);
					((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref targetNetId, default(ForPrimitives));
					float intensity = default(float);
					((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref intensity, default(ForPrimitives));
					InvokeOnController(targetNetId, "ApplyGlowStateFromNetwork", intensity);
				};
				<>c.<>9__8_1 = val2;
				obj2 = (object)val2;
			}
			customMessagingManager.RegisterNamedMessageHandler(msgGlowBroadcast, (HandleNamedMessageDelegate)obj2);
			string msgGlowRequest = EmotionControllerPlugin.MsgGlowRequest;
			object obj3 = <>c.<>9__8_2;
			if (obj3 == null)
			{
				HandleNamedMessageDelegate val3 = delegate(ulong senderClientId, FastBufferReader reader)
				{
					//IL_001a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0020: Unknown result type (might be due to invalid IL or missing references)
					if (NetworkManager.Singleton.IsServer)
					{
						ulong num = default(ulong);
						((FastBufferReader)(ref reader)).ReadValueSafe<ulong>(ref num, default(ForPrimitives));
						InvokeOnControllerWithClient(num, "ServerSendGlowStateTo", senderClientId, num);
					}
				};
				<>c.<>9__8_2 = val3;
				obj3 = (object)val3;
			}
			customMessagingManager.RegisterNamedMessageHandler(msgGlowRequest, (HandleNamedMessageDelegate)obj3);
			_registeredMessagingManager = customMessagingManager;
			Debug.Log((object)$"[EmotionController] Glow custom messages registered (client {singleton.LocalClientId}).");
			return true;
		}

		private static void InvokeOnController(ulong targetNetId, string methodName, float intensity)
		{
			if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(targetNetId, out var value))
			{
				Component val = FindComponentByTypeName(((Component)value).gameObject, "EmotionController");
				if (!((Object)(object)val == (Object)null))
				{
					((object)val).GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public)?.Invoke(val, new object[1] { intensity });
				}
			}
		}

		private static void InvokeOnControllerWithClient(ulong targetNetId, string methodName, ulong senderClientId, ulong netObjId)
		{
			if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(targetNetId, out var value))
			{
				Component val = FindComponentByTypeName(((Component)value).gameObject, "EmotionController");
				if (!((Object)(object)val == (Object)null))
				{
					((object)val).GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public)?.Invoke(val, new object[2] { senderClientId, netObjId });
				}
			}
		}

		private static void mlog_Info(string msg)
		{
			Debug.Log((object)msg);
		}

		private static void AddEmotionControllerToPrefabs(string callerName)
		{
			try
			{
				GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>();
				int num = 0;
				int num2 = 0;
				GameObject[] array2 = array;
				foreach (GameObject val in array2)
				{
					if ((Object)(object)val.GetComponent<PlayerControllerB>() == (Object)null)
					{
						continue;
					}
					Component val2 = FindComponentByTypeName(val, "EmotionController");
					if ((Object)(object)val2 != (Object)null)
					{
						if (MergeThisDllsNameListsInto(val, val2))
						{
							num2++;
						}
						continue;
					}
					NetworkObject component = val.GetComponent<NetworkObject>();
					val.AddComponent<EmotionController>();
					if ((Object)(object)val.GetComponent<HeadTrackController>() == (Object)null)
					{
						val.AddComponent<HeadTrackController>();
					}
					num++;
				}
			}
			catch (Exception)
			{
			}
		}

		internal static Component FindComponentByTypeName(GameObject go, string typeName, string expectedAssemblyName = null)
		{
			Component[] components = go.GetComponents<Component>();
			Component[] array = components;
			foreach (Component val in array)
			{
				if (!((Object)(object)val == (Object)null) && !(((object)val).GetType().Name != typeName) && (expectedAssemblyName == null || !(((object)val).GetType().Assembly.GetName().Name != expectedAssemblyName)))
				{
					return val;
				}
			}
			return null;
		}

		private static bool MergeThisDllsNameListsInto(GameObject go, Component existingEmotionController)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			bool flag = false;
			GameObject val = new GameObject("EmotionControllerDefaultsTemp");
			try
			{
				EmotionController sourceComponent = val.AddComponent<EmotionController>();
				HeadTrackController sourceComponent2 = val.AddComponent<HeadTrackController>();
				flag |= MergeStringListField(existingEmotionController, (Component)(object)sourceComponent, "allowedModelNames");
				flag |= MergeStringListField(existingEmotionController, (Component)(object)sourceComponent, "nonBlinkingModelNames");
				flag |= MergeStringListField(existingEmotionController, (Component)(object)sourceComponent, "nonMouthMovementModelNames");
				flag |= MergeStringListField(existingEmotionController, (Component)(object)sourceComponent, "blinkLeftNames");
				flag |= MergeStringListField(existingEmotionController, (Component)(object)sourceComponent, "blinkRightNames");
				flag |= MergeStringListField(existingEmotionController, (Component)(object)sourceComponent, "mouthBlendShapeNames");
				Component val2 = FindComponentByTypeName(go, "HeadTrackController");
				if ((Object)(object)val2 != (Object)null)
				{
					flag |= MergeStringListField(val2, (Component)(object)sourceComponent2, "nonEyeTrackingModelNames");
					flag |= MergeStringListField(val2, (Component)(object)sourceComponent2, "childModelNames");
					flag |= MergeStringListField(val2, (Component)(object)sourceComponent2, "headBonePaths");
					flag |= MergeStringListField(val2, (Component)(object)sourceComponent2, "leftEyeBonePaths");
					flag |= MergeStringListField(val2, (Component)(object)sourceComponent2, "rightEyeBonePaths");
				}
			}
			finally
			{
				Object.DestroyImmediate((Object)(object)val);
			}
			return flag;
		}

		private static bool MergeStringListField(Component targetComponent, Component sourceComponent, string fieldName)
		{
			FieldInfo field = ((object)targetComponent).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);
			FieldInfo field2 = ((object)sourceComponent).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);
			if (field == null)
			{
				return false;
			}
			if (field2 == null)
			{
				return false;
			}
			if (field.FieldType != typeof(List<string>))
			{
				return false;
			}
			if (field2.FieldType != typeof(List<string>))
			{
				return false;
			}
			List<string> list = field.GetValue(targetComponent) as List<string>;
			List<string> list2 = field2.GetValue(sourceComponent) as List<string>;
			if (list == null)
			{
				list = new List<string>();
				field.SetValue(targetComponent, list);
			}
			if (list2 == null || list2.Count == 0)
			{
				return false;
			}
			bool result = false;
			foreach (string value in list2)
			{
				if (!string.IsNullOrEmpty(value) && !list.Exists((string existing) => string.Equals(existing, value, StringComparison.OrdinalIgnoreCase)))
				{
					list.Add(value);
					result = true;
				}
			}
			return result;
		}
	}
	internal static class WeaponGlowPatches
	{
		private static readonly FieldInfo ShovelPreviousPlayerHeldByField = typeof(Shovel).GetField("previousPlayerHeldBy", BindingFlags.Instance | BindingFlags.NonPublic);

		[HarmonyPatch(typeof(Shovel), "HitShovel")]
		[HarmonyPostfix]
		private static void Shovel_HitShovel_Postfix(Shovel __instance, bool cancel)
		{
			if (!cancel)
			{
				PlayerControllerB player = null;
				if (ShovelPreviousPlayerHeldByField != null)
				{
					object? value = ShovelPreviousPlayerHeldByField.GetValue(__instance);
					player = (PlayerControllerB)((value is PlayerControllerB) ? value : null);
				}
				TryPulse(player);
			}
		}

		[HarmonyPatch(typeof(KnifeItem), "HitKnife")]
		[HarmonyPostfix]
		private static void KnifeItem_HitKnife_Postfix(KnifeItem __instance, bool cancel)
		{
			if (!cancel)
			{
				TryPulse(__instance.previousPlayerHeldBy);
			}
		}

		[HarmonyPatch(typeof(ShotgunItem), "ShootGun")]
		[HarmonyPostfix]
		private static void ShotgunItem_ShootGun_Postfix(ShotgunItem __instance)
		{
			TryPulse(((GrabbableObject)__instance).playerHeldBy);
		}

		private static void TryPulse(PlayerControllerB player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)GameNetworkManager.Instance?.localPlayerController))
			{
				Component val = EmotionControllerPatches.FindComponentByTypeName(((Component)player).gameObject, "EmotionController");
				if (!((Object)(object)val == (Object)null))
				{
					((object)val).GetType().GetMethod("RegisterCombatPulse", BindingFlags.Instance | BindingFlags.Public)?.Invoke(val, null);
				}
			}
		}
	}
	public class EmotionController : NetworkBehaviour
	{
		private struct GlowTarget
		{
			public Material material;

			public Color originalEmission;

			public Color onColor;
		}

		private PlayerControllerB _player;

		public List<string> blinkLeftNames = new List<string> { "Eye_WinkB_L" };

		public List<string> blinkRightNames = new List<string> { "Eye_WinkB_R" };

		public List<string> mouthBlendShapeNames = new List<string> { "Mouth_A01" };

		public float minBlinkInterval = 2f;

		public float maxBlinkInterval = 6f;

		public float blinkDuration = 0.18f;

		public bool autoRefreshOnMissingTarget = true;

		private SkinnedMeshRenderer _targetRenderer;

		private int _blinkLeftIndex = -1;

		private int _blinkRightIndex = -1;

		private float _nextBlinkTime;

		private Coroutine _blinkRoutine;

		public float mouthSensitivity = 25f;

		public float mouthMaxWeight = 100f;

		public float mouthSmoothing = 64f;

		public float mouthNoiseFloor = 0.02f;

		private int _mouthShapeIndex = -1;

		private float _currentMouthWeight = 0f;

		private VoicePlayerState _voice;

		private const float CombatGlowHoldDuration = 5f;

		private const float CombatGlowDecayDuration = 5f;

		private float _combatGlowTimer = 0f;

		private bool _manualGlowOn = false;

		private List<GlowTarget> _glowTargets = new List<GlowTarget>();

		private float _glowIntensity = 0f;

		private float _lastSentGlowIntensity = 0f;

		private float _glowNetworkSendInterval = 0.1f;

		private float _glowNetworkSendTimer = 0f;

		public List<string> allowedModelNames = new List<string> { "Nefer", "Jahoda", "Linnea", "Lauma" };

		public List<string> nonBlinkingModelNames = new List<string>();

		public List<string> nonMouthMovementModelNames = new List<string>();

		private bool _blinkDisabledForThisModel = false;

		private bool _mouthDisabledForThisModel = false;

		private bool _modelAllowed = true;

		private bool _hasCheckedAllowList = false;

		private GameObject _lastCheckedModelRoot;

		private static FieldInfo _captureField;

		private static FieldInfo _amplitudeField;

		private static PropertyInfo _amplitudeProp;

		public PlayerControllerB Player => _player;

		public GameObject GetModelRootForExternalUse()
		{
			return GetReplacementModelRoot();
		}

		public override void OnNetworkSpawn()
		{
			EmotionControllerPatches.RegisterGlowMessagesIfNeeded();
			ApplyGlowState(_glowIntensity);
			if (!((NetworkBehaviour)this).IsOwner)
			{
				RequestGlowStateFromServer();
			}
		}

		private unsafe void RequestGlowStateFromServer()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)NetworkManager.Singleton == (Object)null)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(8, (Allocator)2, -1);
			try
			{
				ulong networkObjectId = ((NetworkBehaviour)this).NetworkObjectId;
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref networkObjectId, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(EmotionControllerPlugin.MsgGlowRequest, 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		public unsafe void ServerSendGlowStateTo(ulong targetClientId, ulong netObjId)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(12, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref netObjId, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref _glowIntensity, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(EmotionControllerPlugin.MsgGlowBroadcast, targetClientId, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		public unsafe void ServerReceiveGlowSet(float intensity)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			_glowIntensity = intensity;
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(12, (Allocator)2, -1);
			try
			{
				ulong networkObjectId = ((NetworkBehaviour)this).NetworkObjectId;
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref networkObjectId, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref intensity, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll(EmotionControllerPlugin.MsgGlowBroadcast, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private unsafe void SendGlowStateToServer(float intensity)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)NetworkManager.Singleton == (Object)null)
			{
				return;
			}
			if (((NetworkBehaviour)this).IsServer)
			{
				ServerReceiveGlowSet(intensity);
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(12, (Allocator)2, -1);
			try
			{
				ulong networkObjectId = ((NetworkBehaviour)this).NetworkObjectId;
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref networkObjectId, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref intensity, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(EmotionControllerPlugin.MsgGlowSet, 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		public void ApplyGlowStateFromNetwork(float intensity)
		{
			if (!((NetworkBehaviour)this).IsOwner)
			{
				_glowIntensity = intensity;
				ApplyGlowState(intensity);
			}
		}

		public void SetGlowIntensity(float intensity)
		{
			intensity = Mathf.Clamp01(intensity);
			_glowIntensity = intensity;
			ApplyGlowState(intensity);
			_glowNetworkSendTimer -= Time.deltaTime;
			bool flag = Mathf.Abs(intensity - _lastSentGlowIntensity) > 0.01f;
			bool flag2 = _glowNetworkSendTimer <= 0f;
			if (flag && flag2)
			{
				_lastSentGlowIntensity = intensity;
				_glowNetworkSendTimer = _glowNetworkSendInterval;
				SendGlowStateToServer(intensity);
			}
		}

		private bool IsModelAllowed(GameObject modelRoot)
		{
			if (allowedModelNames == null || allowedModelNames.Count == 0)
			{
				return false;
			}
			string baseModelName = GetBaseModelName(modelRoot);
			return IsModelInExclusionList(baseModelName, allowedModelNames);
		}

		private void Awake()
		{
			_player = ((Component)this).GetComponent<PlayerControllerB>();
			if ((Object)(object)_player == (Object)null)
			{
				((Behaviour)this).enabled = false;
			}
		}

		private void Start()
		{
			RefreshBlendShapeTarget();
			RefreshMouthBlendShapeTarget();
			RefreshGlowTargets();
			InitVoice();
			ScheduleNextBlink();
		}

		private void Update()
		{
			GameObject replacementModelRoot = GetReplacementModelRoot();
			if ((Object)(object)replacementModelRoot != (Object)(object)_lastCheckedModelRoot)
			{
				_lastCheckedModelRoot = replacementModelRoot;
				_hasCheckedAllowList = false;
				_targetRenderer = null;
				_blinkLeftIndex = -1;
				_blinkRightIndex = -1;
				_mouthShapeIndex = -1;
				_glowTargets.Clear();
				RefreshBlendShapeTarget();
				if ((Object)(object)_targetRenderer != (Object)null)
				{
					RefreshMouthBlendShapeTarget();
					RefreshGlowTargets();
				}
			}
			if (_hasCheckedAllowList && !_modelAllowed)
			{
				return;
			}
			if (((Object)(object)_targetRenderer == (Object)null || (!_blinkDisabledForThisModel && (_blinkLeftIndex < 0 || _blinkRightIndex < 0))) && autoRefreshOnMissingTarget)
			{
				RefreshBlendShapeTarget();
				if ((Object)(object)_targetRenderer != (Object)null)
				{
					RefreshMouthBlendShapeTarget();
					RefreshGlowTargets();
				}
			}
			if (_mouthShapeIndex < 0 && (Object)(object)_targetRenderer != (Object)null && !_mouthDisabledForThisModel && autoRefreshOnMissingTarget)
			{
				RefreshMouthBlendShapeTarget();
			}
			if (_glowTargets.Count == 0 && (Object)(object)_targetRenderer != (Object)null && autoRefreshOnMissingTarget)
			{
				RefreshGlowTargets();
			}
			if (!_blinkDisabledForThisModel && (Object)(object)_targetRenderer != (Object)null && _blinkLeftIndex >= 0 && _blinkRightIndex >= 0 && Time.time >= _nextBlinkTime && _blinkRoutine == null)
			{
				_blinkRoutine = ((MonoBehaviour)this).StartCoroutine(BlinkRoutine());
			}
			if (_voice == null)
			{
				InitVoice();
			}
			UpdateTalking();
			HandleGlowInput();
		}

		public override void OnDestroy()
		{
			((NetworkBehaviour)this).OnDestroy();
		}

		public void RefreshBlendShapeTarget()
		{
			_targetRenderer = null;
			_blinkLeftIndex = -1;
			_blinkRightIndex = -1;
			GameObject replacementModelRoot = GetReplacementModelRoot();
			if ((Object)(object)replacementModelRoot == (Object)null)
			{
				return;
			}
			_modelAllowed = IsModelAllowed(replacementModelRoot);
			_hasCheckedAllowList = true;
			if (!_modelAllowed)
			{
				return;
			}
			string baseModelName = GetBaseModelName(replacementModelRoot);
			_blinkDisabledForThisModel = IsModelInExclusionList(baseModelName, nonBlinkingModelNames);
			_mouthDisabledForThisModel = IsModelInExclusionList(baseModelName, nonMouthMovementModelNames);
			SkinnedMeshRenderer[] componentsInChildren = replacementModelRoot.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			if (componentsInChildren.Length == 0)
			{
				return;
			}
			if (_blinkDisabledForThisModel)
			{
				SkinnedMeshRenderer[] array = componentsInChildren;
				foreach (SkinnedMeshRenderer val in array)
				{
					if ((Object)(object)val.sharedMesh != (Object)null)
					{
						_targetRenderer = val;
						break;
					}
				}
				return;
			}
			SkinnedMeshRenderer[] array2 = componentsInChildren;
			foreach (SkinnedMeshRenderer val2 in array2)
			{
				Mesh sharedMesh = val2.sharedMesh;
				if (!((Object)(object)sharedMesh == (Object)null))
				{
					int num = FindBlendShapeIndex(sharedMesh, blinkLeftNames);
					int num2 = FindBlendShapeIndex(sharedMesh, blinkRightNames);
					if (num >= 0 && num2 >= 0)
					{
						_targetRenderer = val2;
						_blinkLeftIndex = num;
						_blinkRightIndex = num2;
						break;
					}
				}
			}
		}

		private void RefreshMouthBlendShapeTarget()
		{
			_mouthShapeIndex = -1;
			if ((Object)(object)_targetRenderer == (Object)null || _mouthDisabledForThisModel)
			{
				return;
			}
			Mesh sharedMesh = _targetRenderer.sharedMesh;
			if ((Object)(object)sharedMesh == (Object)null)
			{
				return;
			}
			foreach (string mouthBlendShapeName in mouthBlendShapeNames)
			{
				for (int i = 0; i < sharedMesh.blendShapeCount; i++)
				{
					if (sharedMesh.GetBlendShapeName(i).IndexOf(mouthBlendShapeName, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						_mouthShapeIndex = i;
						return;
					}
				}
			}
		}

		private void InitVoice()
		{
			try
			{
				if ((Object)(object)_player == (Object)null)
				{
					return;
				}
				Type type = ((object)_player).GetType();
				FieldInfo field = type.GetField("voicePlayerState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					object? value = field.GetValue(_player);
					VoicePlayerState val = (VoicePlayerState)((value is VoicePlayerState) ? value : null);
					if (val != null)
					{
						_voice = val;
						return;
					}
				}
				PropertyInfo property = type.GetProperty("voicePlayerState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null)
				{
					object? value2 = property.GetValue(_player);
					VoicePlayerState val2 = (VoicePlayerState)((value2 is VoicePlayerState) ? value2 : null);
					if (val2 != null)
					{
						_voice = val2;
						return;
					}
				}
				StartOfRound instance = StartOfRound.Instance;
				if ((Object)(object)instance != (Object)null && (Object)(object)instance.voiceChatModule != (Object)null)
				{
					string text = null;
					FieldInfo field2 = type.GetField("playerUsername", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field2 != null)
					{
						text = field2.GetValue(_player) as string;
					}
					bool flag = (Object)(object)_player == (Object)(object)GameNetworkManager.Instance?.localPlayerController;
					if (string.IsNullOrEmpty(text) && flag)
					{
						text = instance.voiceChatModule.LocalPlayerName;
					}
					if (!string.IsNullOrEmpty(text))
					{
						_voice = instance.voiceChatModule.FindPlayer(text);
					}
				}
			}
			catch (Exception)
			{
				_voice = null;
			}
		}

		private void UpdateTalking()
		{
			if (_mouthDisabledForThisModel || (Object)(object)_targetRenderer == (Object)null || _mouthShapeIndex < 0)
			{
				return;
			}
			float num;
			if ((Object)(object)_player == (Object)(object)GameNetworkManager.Instance?.localPlayerController)
			{
				num = GetLocalMicAmplitude();
			}
			else
			{
				if (_voice == null)
				{
					InitVoice();
				}
				num = 0f;
				if (_voice != null)
				{
					try
					{
						num = _voice.Amplitude;
					}
					catch
					{
					}
				}
			}
			float num2 = num - mouthNoiseFloor;
			if (num2 < 0f)
			{
				num2 = 0f;
			}
			float num3 = Mathf.Clamp01(num2 * mouthSensitivity) * mouthMaxWeight;
			_currentMouthWeight = Mathf.Lerp(_currentMouthWeight, num3, Time.deltaTime * mouthSmoothing);
			_targetRenderer.SetBlendShapeWeight(_mouthShapeIndex, _currentMouthWeight);
		}

		private void ScheduleNextBlink()
		{
			float num = Random.Range(minBlinkInterval, maxBlinkInterval);
			_nextBlinkTime = Time.time + num;
		}

		private IEnumerator BlinkRoutine()
		{
			if ((Object)(object)_targetRenderer == (Object)null || _blinkLeftIndex < 0 || _blinkRightIndex < 0)
			{
				_blinkRoutine = null;
				yield break;
			}
			float half = blinkDuration * 0.5f;
			float t = 0f;
			while (t < half)
			{
				t += Time.deltaTime;
				SafeSetWeight(Mathf.Lerp(0f, 100f, t / half));
				yield return null;
			}
			SafeSetWeight(100f);
			t = 0f;
			while (t < half)
			{
				t += Time.deltaTime;
				SafeSetWeight(Mathf.Lerp(100f, 0f, t / half));
				yield return null;
			}
			SafeSetWeight(0f);
			_blinkRoutine = null;
			ScheduleNextBlink();
		}

		private void SafeSetWeight(float weight)
		{
			if (!((Object)(object)_targetRenderer == (Object)null))
			{
				if (_blinkLeftIndex >= 0)
				{
					_targetRenderer.SetBlendShapeWeight(_blinkLeftIndex, weight);
				}
				if (_blinkRightIndex >= 0)
				{
					_targetRenderer.SetBlendShapeWeight(_blinkRightIndex, weight);
				}
			}
		}

		private int FindBlendShapeIndex(Mesh mesh, List<string> candidates)
		{
			foreach (string candidate in candidates)
			{
				for (int i = 0; i < mesh.blendShapeCount; i++)
				{
					if (mesh.GetBlendShapeName(i).IndexOf(candidate, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return i;
					}
				}
			}
			return -1;
		}

		private GameObject GetReplacementModelRoot()
		{
			BodyReplacementBase component = ((Component)this).GetComponent<BodyReplacementBase>();
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			return component.replacementModel;
		}

		private void RefreshGlowTargets()
		{
			//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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			_glowTargets.Clear();
			GameObject replacementModelRoot = GetReplacementModelRoot();
			if ((Object)(object)replacementModelRoot == (Object)null)
			{
				return;
			}
			SkinnedMeshRenderer[] componentsInChildren = replacementModelRoot.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			SkinnedMeshRenderer[] array = componentsInChildren;
			foreach (SkinnedMeshRenderer val in array)
			{
				Material[] materials = ((Renderer)val).materials;
				bool flag = false;
				foreach (Material val2 in materials)
				{
					if (!((Object)(object)val2 == (Object)null) && val2.HasProperty("_Emissive_Color"))
					{
						string materialBaseName = (((Object)val2).name.EndsWith(" (Instance)") ? ((Object)val2).name.Substring(0, ((Object)val2).name.Length - " (Instance)".Length) : ((Object)val2).name);
						if (TryParseGlowMaterial(materialBaseName, out var color))
						{
							_glowTargets.Add(new GlowTarget
							{
								material = val2,
								originalEmission = val2.GetColor("_Emissive_Color"),
								onColor = color
							});
							flag = true;
						}
					}
				}
				if (flag)
				{
					((Renderer)val).materials = materials;
				}
			}
			ApplyGlowState(_glowIntensity);
		}

		private void ApplyGlowState(float intensity)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			foreach (GlowTarget glowTarget in _glowTargets)
			{
				if (!((Object)(object)glowTarget.material == (Object)null))
				{
					Color val = Color.Lerp(Color.black, glowTarget.onColor, intensity);
					if (intensity > 0.001f)
					{
						glowTarget.material.EnableKeyword("_EMISSIVE_SIMPLE");
						glowTarget.material.DisableKeyword("_EMISSIVE_ANIMATION");
						glowTarget.material.SetColor("_Emissive_Color", val);
					}
					else
					{
						glowTarget.material.SetColor("_Emissive_Color", Color.black);
						glowTarget.material.DisableKeyword("_EMISSIVE_SIMPLE");
						glowTarget.material.DisableKeyword("_EMISSIVE_ANIMATION");
					}
				}
			}
		}

		private void HandleGlowInput()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)this).IsOwner)
			{
				return;
			}
			if (Keyboard.current != null)
			{
				KeyControl val = Keyboard.current[EmotionControllerPlugin.GlowToggleKeyConfig.Value];
				if (val != null && ((ButtonControl)val).wasPressedThisFrame)
				{
					_manualGlowOn = !_manualGlowOn;
				}
			}
			float num = 0f;
			if (EmotionControllerPlugin.CombatModeEnabledConfig.Value)
			{
				if (_combatGlowTimer > 0f)
				{
					_combatGlowTimer = Mathf.Max(0f, _combatGlowTimer - Time.deltaTime);
				}
				num = ((!(_combatGlowTimer > 5f)) ? (_combatGlowTimer / 5f) : 1f);
			}
			float num2 = (_manualGlowOn ? 1f : 0f);
			float glowIntensity = Mathf.Max(num2, num);
			SetGlowIntensity(glowIntensity);
		}

		public void RegisterCombatPulse()
		{
			if (((NetworkBehaviour)this).IsOwner && EmotionControllerPlugin.CombatModeEnabledConfig.Value)
			{
				_combatGlowTimer = 10f;
			}
		}

		private string GetBaseModelName(GameObject modelRoot)
		{
			if ((Object)(object)modelRoot == (Object)null)
			{
				return string.Empty;
			}
			string text = ((Object)modelRoot).name;
			int num = text.IndexOf('(');
			if (num >= 0)
			{
				text = text.Substring(0, num).TrimEnd();
			}
			return text;
		}

		private static bool TryParseGlowMaterial(string materialBaseName, out Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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)
			color = Color.black;
			if (string.IsNullOrEmpty(materialBaseName) || !materialBaseName.StartsWith("GlowMaterial", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			string text = materialBaseName.Substring("GlowMaterial".Length);
			if (text.Length != 2 || !text.All(char.IsDigit))
			{
				return false;
			}
			int num = int.Parse(text);
			float num2 = ((num == 0) ? 1f : ((float)num / 100f));
			color = Color.HSVToRGB(0f, 0f, num2);
			return true;
		}

		private bool IsModelInExclusionList(string baseName, List<string> exclusionList)
		{
			if (string.IsNullOrEmpty(baseName))
			{
				return false;
			}
			foreach (string exclusion in exclusionList)
			{
				if (string.IsNullOrEmpty(exclusion) || !string.Equals(baseName, exclusion, StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				return true;
			}
			return false;
		}

		public bool IsModelAllowedForExternalUse()
		{
			return !_hasCheckedAllowList || _modelAllowed;
		}

		private float GetLocalMicAmplitude()
		{
			try
			{
				StartOfRound instance = StartOfRound.Instance;
				if ((Object)(object)instance == (Object)null || (Object)(object)instance.voiceChatModule == (Object)null)
				{
					return 0f;
				}
				object voiceChatModule = instance.voiceChatModule;
				if (_captureField == null)
				{
					_captureField = voiceChatModule.GetType().GetField("_capture", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				object obj = _captureField?.GetValue(voiceChatModule);
				if (obj == null)
				{
					Debug.Log((object)"[EC] capturePipeline null");
					return 0f;
				}
				if (_amplitudeField == null && _amplitudeProp == null)
				{
					_amplitudeField = obj.GetType().GetField("Amplitude", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (_amplitudeField == null)
					{
						_amplitudeProp = obj.GetType().GetProperty("Amplitude", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					}
				}
				if (((_amplitudeField != null) ? _amplitudeField.GetValue(obj) : _amplitudeProp?.GetValue(obj)) is float result)
				{
					return result;
				}
				Debug.Log((object)"[EC] amplitude member not found or wrong type");
			}
			catch (Exception ex)
			{
				Debug.Log((object)("[EC] GetLocalMicAmplitude exception: " + ex));
			}
			return 0f;
		}
	}
	[DefaultExecutionOrder(32000)]
	public class HeadTrackController : MonoBehaviour
	{
		private enum LookTargetType
		{
			None,
			Enemy,
			Talker,
			Item,
			Interactable
		}

		public List<string> headBonePaths = new List<string> { "Armature/Hips/Spine/Chest/Upper Chest/Neck/Head", "Armature/Root.001/Hips/Spine/Chest/Upper Chest/Neck/Head" };

		public List<string> leftEyeBonePaths = new List<string> { "Armature/Hips/Spine/Chest/Upper Chest/Neck/Head/Left Eye", "Armature/Root.001/Hips/Spine/Chest/Upper Chest/Neck/Head/Left Eye" };

		public List<string> rightEyeBonePaths = new List<string> { "Armature/Hips/Spine/Chest/Upper Chest/Neck/Head/Right Eye", "Armature/Root.001/Hips/Spine/Chest/Upper Chest/Neck/Head/Right Eye" };

		public float maxHeadAngle = 30f;

		public float maxEyeAngle = 25f;

		public float turnSpeed = 6f;

		public float eyeTurnSpeed = 10f;

		private Transform _leftEyeBone;

		private Transform _rightEyeBone;

		private Quaternion _leftEyeRestLocalRotation;

		private Quaternion _rightEyeRestLocalRotation;

		private Quaternion _smoothedHeadLocalRotation;

		private Quaternion _smoothedLeftEyeLocalRotation;

		private Quaternion _smoothedRightEyeLocalRotation;

		private bool _hasSmoothedHead = false;

		private bool _hasSmoothedEyes = false;

		public float pickupSearchRadius = 4f;

		public LayerMask lookableLayerMask;

		public float talkerSearchRadius = 6f;

		public float enemySearchRadius = 8f;

		public float targetReevaluateInterval = 0f;

		public float talkerHoldDuration = 3f;

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

		private PlayerControllerB _player;

		private Transform _headBone;

		private Quaternion _headBoneRestLocalRotation;

		private Transform _currentLookTarget;

		private float _nextReevaluateTime;

		public float maxHeadYawAngle = 40f;

		public float maxHeadPitchUpAngle = 18f;

		public float maxHeadPitchDownAngle = 25f;

		private static FieldInfo _voiceField;

		private Transform _lastLoggedTarget;

		private GameObject _lastCheckedModelRoot;

		public float maxFacingAngle = 60f;

		private Component _cachedEmotionController;

		public float itemGlanceDuration = 2.5f;

		public float itemGlanceCooldown = 0f;

		private LookTargetType _currentLookTargetType = LookTargetType.None;

		private float _glanceTimer = 0f;

		private float _glanceCooldownTimer = 0f;

		private Dictionary<Transform, float> _recentGlanceExpiry = new Dictionary<Transform, float>();

		public float glanceMemoryDuration = 60f;

		public List<string> childModelNames = new List<string> { "Nahida" };

		public float childModelHeadPitchOffset = 15f;

		private bool _isChildModelForThisModel = false;

		public List<string> nonEyeTrackingModelNames = new List<string>();

		private bool _eyeTrackingDisabledForThisModel = false;

		private void Awake()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			_player = ((Component)this).GetComponent<PlayerControllerB>();
			if ((Object)(object)_player == (Object)null)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			lookableLayerMask = LayerMask.op_Implicit(LayerMask.GetMask(new string[5] { "Enemies", "Player", "Props", "InteractableObject", "MapHazards" }));
		}

		private Component GetEmotionController()
		{
			if ((Object)(object)_cachedEmotionController == (Object)null)
			{
				Component[] components = ((Component)this).GetComponents<Component>();
				Component[] array = components;
				foreach (Component val in array)
				{
					if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == "EmotionController")
					{
						_cachedEmotionController = val;
						break;
					}
				}
			}
			return _cachedEmotionController;
		}

		private GameObject GetModelRootFromController()
		{
			Component emotionController = GetEmotionController();
			if ((Object)(object)emotionController == (Object)null)
			{
				return null;
			}
			object? obj = ((object)emotionController).GetType().GetMethod("GetModelRootForExternalUse", BindingFlags.Instance | BindingFlags.Public)?.Invoke(emotionController, null);
			return (GameObject)((obj is GameObject) ? obj : null);
		}

		private bool IsModelAllowedFromController()
		{
			Component emotionController = GetEmotionController();
			if ((Object)(object)emotionController == (Object)null)
			{
				return true;
			}
			MethodInfo method = ((object)emotionController).GetType().GetMethod("IsModelAllowedForExternalUse", BindingFlags.Instance | BindingFlags.Public);
			return method != null && (bool)method.Invoke(emotionController, null);
		}

		private void LateUpdate()
		{
			if (!((Object)(object)_headBone == (Object)null))
			{
				ApplyHeadRotation();
				ApplyEyeRotation();
			}
		}

		private void Update()
		{
			GameObject modelRootFromController = GetModelRootFromController();
			if ((Object)(object)modelRootFromController != (Object)(object)_lastCheckedModelRoot)
			{
				_lastCheckedModelRoot = modelRootFromController;
				_headBone = null;
				_leftEyeBone = null;
				_rightEyeBone = null;
				_hasSmoothedHead = false;
				_hasSmoothedEyes = false;
			}
			if ((Object)(object)_headBone == (Object)null)
			{
				if (!IsModelAllowedFromController())
				{
					return;
				}
				TryResolveHeadBone();
				if ((Object)(object)_headBone == (Object)null)
				{
					return;
				}
			}
			if (_glanceTimer > 0f)
			{
				_glanceTimer -= Time.deltaTime;
			}
			if (_glanceCooldownTimer > 0f)
			{
				_glanceCooldownTimer -= Time.deltaTime;
			}
			if (Time.time >= _nextReevaluateTime)
			{
				_nextReevaluateTime = Time.time + targetReevaluateInterval;
				PickBestLookTarget();
			}
		}

		private void TryResolveHeadBone()
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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_0182: 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)
			if (!IsModelAllowedFromController())
			{
				return;
			}
			GameObject modelRootFromController = GetModelRootFromController();
			if ((Object)(object)modelRootFromController == (Object)null)
			{
				return;
			}
			string baseModelName = GetBaseModelName(modelRootFromController);
			_eyeTrackingDisabledForThisModel = IsModelInExclusionList(baseModelName, nonEyeTrackingModelNames);
			_isChildModelForThisModel = IsModelInExclusionList(baseModelName, childModelNames);
			foreach (string headBonePath in headBonePaths)
			{
				Transform val = modelRootFromController.transform.Find(headBonePath);
				if ((Object)(object)val != (Object)null)
				{
					_headBone = val;
					_headBoneRestLocalRotation = val.localRotation;
					break;
				}
			}
			if (_eyeTrackingDisabledForThisModel)
			{
				return;
			}
			foreach (string leftEyeBonePath in leftEyeBonePaths)
			{
				Transform val2 = modelRootFromController.transform.Find(leftEyeBonePath);
				if ((Object)(object)val2 != (Object)null)
				{
					_leftEyeBone = val2;
					_leftEyeRestLocalRotation = val2.localRotation;
					break;
				}
			}
			foreach (string rightEyeBonePath in rightEyeBonePaths)
			{
				Transform val3 = modelRootFromController.transform.Find(rightEyeBonePath);
				if ((Object)(object)val3 != (Object)null)
				{
					_rightEyeBone = val3;
					_rightEyeRestLocalRotation = val3.localRotation;
					break;
				}
			}
		}

		private void PickBestLookTarget()
		{
			if ((Object)(object)_player == (Object)null || (Object)(object)_headBone == (Object)null)
			{
				return;
			}
			PruneExpiredGlanceMemory();
			Transform val = FindNearestEnemy();
			if ((Object)(object)val != (Object)null)
			{
				SetLookTarget(val, LookTargetType.Enemy);
				return;
			}
			Transform val2 = FindNearestTalkingPlayer();
			if ((Object)(object)val2 != (Object)null)
			{
				SetLookTarget(val2, LookTargetType.Talker);
				return;
			}
			if (_glanceCooldownTimer > 0f)
			{
				SetLookTarget(null, LookTargetType.None);
				return;
			}
			if (_currentLookTargetType == LookTargetType.Item || _currentLookTargetType == LookTargetType.Interactable)
			{
				if (!(_glanceTimer > 0f))
				{
					if ((Object)(object)_currentLookTarget != (Object)null)
					{
						_recentGlanceExpiry[_currentLookTarget] = Time.time + glanceMemoryDuration;
					}
					_glanceCooldownTimer = itemGlanceCooldown;
					SetLookTarget(null, LookTargetType.None);
				}
				return;
			}
			Transform val3 = FindNearestPickupable();
			if ((Object)(object)val3 != (Object)null && !IsRecentlyGlanced(val3))
			{
				SetLookTarget(val3, LookTargetType.Item);
				return;
			}
			Transform val4 = FindNearestInteractable();
			if ((Object)(object)val4 != (Object)null && !IsRecentlyGlanced(val4))
			{
				SetLookTarget(val4, LookTargetType.Interactable);
			}
			else
			{
				SetLookTarget(null, LookTargetType.None);
			}
		}

		private bool IsRecentlyGlanced(Transform target)
		{
			float value;
			return _recentGlanceExpiry.TryGetValue(target, out value) && Time.time < value;
		}

		private void PruneExpiredGlanceMemory()
		{
			if (_recentGlanceExpiry.Count == 0)
			{
				return;
			}
			List<Transform> list = null;
			foreach (KeyValuePair<Transform, float> item in _recentGlanceExpiry)
			{
				if ((Object)(object)item.Key == (Object)null || Time.time >= item.Value)
				{
					if (list == null)
					{
						list = new List<Transform>();
					}
					list.Add(item.Key);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (Transform item2 in list)
			{
				_recentGlanceExpiry.Remove(item2);
			}
		}

		private void SetLookTarget(Transform target, LookTargetType type)
		{
			bool flag = (Object)(object)target != (Object)(object)_currentLookTarget;
			_currentLookTarget = target;
			_currentLookTargetType = type;
			if (flag)
			{
				LogTargetChangeIfNeeded();
				if (type == LookTargetType.Item || type == LookTargetType.Interactable)
				{
					_glanceTimer = itemGlanceDuration;
				}
				else
				{
					_glanceTimer = 0f;
				}
			}
		}

		private void LogTargetChangeIfNeeded()
		{
			if ((Object)(object)_currentLookTarget != (Object)(object)_lastLoggedTarget)
			{
				_lastLoggedTarget = _currentLookTarget;
			}
		}

		private string GetBaseModelName(GameObject modelRoot)
		{
			if ((Object)(object)modelRoot == (Object)null)
			{
				return string.Empty;
			}
			string text = ((Object)modelRoot).name;
			int num = text.IndexOf('(');
			if (num >= 0)
			{
				text = text.Substring(0, num).TrimEnd();
			}
			return text;
		}

		private bool IsModelInExclusionList(string baseName, List<string> exclusionList)
		{
			if (string.IsNullOrEmpty(baseName))
			{
				return false;
			}
			foreach (string exclusion in exclusionList)
			{
				if (string.IsNullOrEmpty(exclusion) || !string.Equals(baseName, exclusion, StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}
				return true;
			}
			return false;
		}

		private Transform FindNearestEnemy()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(_headBone.position, enemySearchRadius, LayerMask.op_Implicit(lookableLayerMask), (QueryTriggerInteraction)2);
			Transform result = null;
			float num = float.MaxValue;
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				EnemyAICollisionDetect componentInParent = ((Component)val).GetComponentInParent<EnemyAICollisionDetect>();
				if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.mainScript == (Object)null) && !componentInParent.mainScript.isEnemyDead && IsWithinFacingCone(((Component)componentInParent.mainScript).transform.position))
				{
					float num2 = Vector3.Distance(_headBone.position, ((Component)componentInParent.mainScript).transform.position);
					if (num2 < num)
					{
						num = num2;
						result = ((Component)componentInParent.mainScript).transform;
					}
				}
			}
			return result;
		}

		private Transform FindNearestPickupable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(_headBone.position, pickupSearchRadius, LayerMask.op_Implicit(lookableLayerMask), (QueryTriggerInteraction)2);
			Transform result = null;
			float num = float.MaxValue;
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				GrabbableObject componentInParent = ((Component)val).GetComponentInParent<GrabbableObject>();
				if (!((Object)(object)componentInParent == (Object)null) && !componentInParent.isHeld && !componentInParent.isPocketed && IsWithinFacingCone(((Component)componentInParent).transform.position))
				{
					float num2 = Vector3.Distance(_headBone.position, ((Component)componentInParent).transform.position);
					if (num2 < num)
					{
						num = num2;
						result = ((Component)componentInParent).transform;
					}
				}
			}
			return result;
		}

		private Transform FindNearestInteractable()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(_headBone.position, pickupSearchRadius, LayerMask.op_Implicit(lookableLayerMask), (QueryTriggerInteraction)2);
			Transform result = null;
			float num = float.MaxValue;
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				InteractTrigger componentInParent = ((Component)val).GetComponentInParent<InteractTrigger>();
				if (!((Object)(object)componentInParent == (Object)null) && IsWithinFacingCone(((Component)componentInParent).transform.position))
				{
					float num2 = Vector3.Distance(_headBone.position, ((Component)componentInParent).transform.position);
					if (num2 < num)
					{
						num = num2;
						result = ((Component)componentInParent).transform;
					}
				}
			}
			return result;
		}

		private Transform FindNearestTalkingPlayer()
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			StartOfRound instance = StartOfRound.Instance;
			if ((Object)(object)instance == (Object)null || instance.allPlayerScripts == null)
			{
				return null;
			}
			Transform result = null;
			float num = float.MaxValue;
			PlayerControllerB[] allPlayerScripts = instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)_player || !val.isPlayerControlled || val.isPlayerDead)
				{
					continue;
				}
				float playerVoiceAmplitude = GetPlayerVoiceAmplitude(val);
				if (playerVoiceAmplitude >= 0.03f)
				{
					_lastHeardTalkingTime[val] = Time.time;
				}
				if (_lastHeardTalkingTime.TryGetValue(val, out var value) && Time.time - value <= talkerHoldDuration)
				{
					float num2 = Vector3.Distance(_headBone.position, ((Component)val).transform.position);
					if (!(num2 > talkerSearchRadius) && IsWithinFacingCone(((Component)val).transform.position) && num2 < num)
					{
						num = num2;
						result = (((Object)(object)val.gameplayCamera != (Object)null) ? ((Component)val.gameplayCamera).transform : ((Component)val).transform);
					}
				}
			}
			return result;
		}

		private float GetPlayerVoiceAmplitude(PlayerControllerB other)
		{
			try
			{
				if (_voiceField == null)
				{
					_voiceField = typeof(PlayerControllerB).GetField("voicePlayerState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				if (_voiceField != null)
				{
					object? value = _voiceField.GetValue(other);
					VoicePlayerState val = (VoicePlayerState)((value is VoicePlayerState) ? value : null);
					if (val != null)
					{
						float amplitude = val.Amplitude;
						if (amplitude > 0f)
						{
							return amplitude;
						}
					}
				}
				StartOfRound instance = StartOfRound.Instance;
				if ((Object)(object)instance != (Object)null && (Object)(object)instance.voiceChatModule != (Object)null && (Object)(object)other == (Object)(object)GameNetworkManager.Instance?.localPlayerController)
				{
					string localPlayerName = instance.voiceChatModule.LocalPlayerName;
					if (!string.IsNullOrEmpty(localPlayerName))
					{
						VoicePlayerState val2 = instance.voiceChatModule.FindPlayer(localPlayerName);
						if (val2 != null)
						{
							return val2.Amplitude;
						}
					}
				}
			}
			catch
			{
			}
			return 0f;
		}

		private void ApplyHeadRotation()
		{
			//IL_0026: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val;
			if ((Object)(object)_currentLookTarget == (Object)null)
			{
				val = _headBoneRestLocalRotation;
			}
			else
			{
				Vector3 val2 = _currentLookTarget.position - _headBone.position;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
				{
					val = _headBoneRestLocalRotation;
				}
				else
				{
					((Vector3)(ref val2)).Normalize();
					Vector3 directionLocal = _headBone.parent.InverseTransformDirection(val2);
					float pitchBiasDegrees = (_isChildModelForThisModel ? childModelHeadPitchOffset : 0f);
					val = ClampDirectionYawPitch(_headBoneRestLocalRotation, directionLocal, maxHeadYawAngle, maxHeadPitchUpAngle, maxHeadPitchDownAngle, pitchBiasDegrees);
				}
			}
			if (!_hasSmoothedHead)
			{
				_smoothedHeadLocalRotation = val;
				_hasSmoothedHead = true;
			}
			else
			{
				_smoothedHeadLocalRotation = Quaternion.Slerp(_smoothedHeadLocalRotation, val, Time.deltaTime * turnSpeed);
			}
			_headBone.localRotation = _smoothedHeadLocalRotation;
		}

		private static Quaternion ClampDirectionYawPitch(Quaternion restLocalRotation, Vector3 directionLocal, float maxYaw, float maxPitchUp, float maxPitchDown, float pitchBiasDegrees = 0f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = restLocalRotation * Vector3.forward;
			Vector3 val2 = restLocalRotation * Vector3.right;
			Vector3 val3 = restLocalRotation * Vector3.up;
			float num = Vector3.Dot(directionLocal, val);
			float num2 = Vector3.Dot(directionLocal, val2);
			float num3 = Vector3.Dot(directionLocal, val3);
			float num4 = Mathf.Atan2(num2, num) * 57.29578f;
			float num5 = Mathf.Atan2(num3, num) * 57.29578f;
			num5 -= pitchBiasDegrees;
			num4 = Mathf.Clamp(num4, 0f - maxYaw, maxYaw);
			num5 = ((num5 >= 0f) ? Mathf.Clamp(num5, 0f, maxPitchUp) : Mathf.Clamp(num5, 0f - maxPitchDown, 0f));
			return restLocalRotation * Quaternion.Euler(0f - num5, num4, 0f);
		}

		private void ApplyEyeRotation()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_leftEyeBone == (Object)null) && !((Object)(object)_rightEyeBone == (Object)null))
			{
				Quaternion val;
				Quaternion val2;
				if ((Object)(object)_currentLookTarget == (Object)null)
				{
					val = _leftEyeRestLocalRotation;
					val2 = _rightEyeRestLocalRotation;
				}
				else
				{
					val = ComputeEyeTargetRotation(_leftEyeBone, _leftEyeRestLocalRotation);
					val2 = ComputeEyeTargetRotation(_rightEyeBone, _rightEyeRestLocalRotation);
				}
				if (!_hasSmoothedEyes)
				{
					_smoothedLeftEyeLocalRotation = val;
					_smoothedRightEyeLocalRotation = val2;
					_hasSmoothedEyes = true;
				}
				else
				{
					_smoothedLeftEyeLocalRotation = Quaternion.Slerp(_smoothedLeftEyeLocalRotation, val, Time.deltaTime * eyeTurnSpeed);
					_smoothedRightEyeLocalRotation = Quaternion.Slerp(_smoothedRightEyeLocalRotation, val2, Time.deltaTime * eyeTurnSpeed);
				}
				_leftEyeBone.localRotation = _smoothedLeftEyeLocalRotation;
				_rightEyeBone.localRotation = _smoothedRightEyeLocalRotation;
			}
		}

		private Quaternion ComputeEyeTargetRotation(Transform eyeBone, Quaternion eyeRestLocalRotation)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = _currentLookTarget.position - eyeBone.position;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				return eyeRestLocalRotation;
			}
			((Vector3)(ref val)).Normalize();
			Vector3 direction = eyeBone.parent.InverseTransformDirection(val);
			Vector3 val2 = eyeRestLocalRotation * Vector3.forward;
			Vector3 normalized = ((Vector3)(ref val2)).normalized;
			Vector3 val3 = ClampDirectionToCone(normalized, direction, maxEyeAngle);
			Quaternion val4 = Quaternion.FromToRotation(normalized, val3);
			return val4 * eyeRestLocalRotation;
		}

		private bool IsWithinFacingCone(Vector3 targetPosition)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_player == (Object)null)
			{
				return true;
			}
			Vector3 val = targetPosition - ((Component)_player).transform.position;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				return true;
			}
			float num = Vector3.Angle(((Component)_player).transform.forward, val);
			return num <= maxFacingAngle;
		}

		private static Vector3 ClampDirectionToCone(Vector3 forward, Vector3 direction, float maxAngleDegrees)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			float num = Vector3.Angle(forward, direction);
			if (num <= maxAngleDegrees)
			{
				return direction;
			}
			return Vector3.RotateTowards(forward, direction, maxAngleDegrees * (MathF.PI / 180f), 0f);
		}
	}
}
namespace AR
{
	[BepInPlugin("ModelReplacementCameraVisualsNodKraiSuits2", "Konk.NodKraiSuitsVol2", "2.0.0")]
	public class CameraVisuals : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("CameraVisualsNodKraiSuits2");

		private static CameraVisuals Instance;

		public static Vector3 baseSize;

		public static ManualLogSource mls;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			mls = ((BaseUnityPlugin)this).Logger;
			harmony.PatchAll(typeof(CameraVisuals));
			mls.LogInfo((object)"CAMERA HEIGHTS LOADED");
		}

		[HarmonyPatch(typeof(ModelReplacementAPI), "SetPlayerModelReplacement")]
		[HarmonyPostfix]
		public static void DetectCamera(PlayerControllerB player)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)player).gameObject;
			Transform val = gameObject.transform.Find("ScavengerModel").Find("metarig").Find("CameraContainer");
			if ((Object)(object)val != (Object)null)
			{
				GameObject gameObject2 = ((Component)val).gameObject;
				if (Object.op_Implicit((Object)(object)gameObject.GetComponent<LINNEA>()))
				{
					gameObject.transform.Find("ScavengerModel").Find("metarig").Find("CameraContainer")
						.Find("MainCamera")
						.Find("HUDHelmetPosition")
						.localPosition = new Vector3(0.01f, -0.058f, -0.063f);
					gameObject.transform.localScale = new Vector3(0.885f, 0.885f, 0.885f);
					((BodyReplacementBase)gameObject.GetComponent<LINNEA>()).replacementViewModel.transform.localScale = new Vector3(1.7f, 1.7f, 1.7f);
				}
				if (Object.op_Implicit((Object)(object)gameObject.GetComponent<JAHODA>()))
				{
					gameObject.transform.Find("ScavengerModel").Find("metarig").Find("CameraContainer")
						.Find("MainCamera")
						.Find("HUDHelmetPosition")
						.localPosition = new Vector3(0.01f, -0.058f, -0.063f);
					gameObject.transform.localScale = new Vector3(0.885f, 0.885f, 0.885f);
					((BodyReplacementBase)gameObject.GetComponent<JAHODA>()).replacementViewModel.transform.localScale = new Vector3(1.7f, 1.7f, 1.7f);
				}
				if (Object.op_Implicit((Object)(object)gameObject.GetComponent<NEFER>()))
				{
					gameObject.transform.Find("ScavengerModel").Find("metarig").Find("CameraContainer")
						.Find("MainCamera")
						.Find("HUDHelmetPosition")
						.localPosition = new Vector3(0.01f, -0.048f, -0.063f);
					gameObject.transform.localScale = new Vector3(1f, 1f, 1f);
					((BodyReplacementBase)gameObject.GetComponent<NEFER>()).replacementViewModel.transform.localScale = new Vector3(1.7f, 1.7f, 1.7f);
				}
				if (Object.op_Implicit((Object)(object)gameObject.GetComponent<LAUMA>()))
				{
					gameObject.transform.Find("ScavengerModel").Find("metarig").Find("CameraContainer")
						.Find("MainCamera")
						.Find("HUDHelmetPosition")
						.localPosition = new Vector3(0.01f, -0.048f, -0.063f);
					gameObject.transform.localScale = new Vector3(1.025f, 1.025f, 1.025f);
					((BodyReplacementBase)gameObject.GetComponent<LAUMA>()).replacementViewModel.transform.localScale = new Vector3(1.7f, 1.7f, 1.7f);
					if (Plugin.Antlers.Value)
					{
						((Component)((BodyReplacementBase)gameObject.GetComponent<LAUMA>()).replacementModel.transform.Find("Antlers")).gameObject.SetActive(true);
						((Component)((BodyReplacementBase)gameObject.GetComponent<LAUMA>()).replacementModelShadow.transform.Find("Antlers")).gameObject.SetActive(true);
					}
					if (!Plugin.Antlers.Value)
					{
						((Component)((BodyReplacementBase)gameObject.GetComponent<LAUMA>()).replacementModel.transform.Find("Antlers")).gameObject.SetActive(false);
						((Component)((BodyReplacementBase)gameObject.GetComponent<LAUMA>()).replacementModelShadow.transform.Find("Antlers")).gameObject.SetActive(false);
					}
				}
			}
			else
			{
				mls.LogInfo((object)"Child GameObject not found.");
			}
		}

		[HarmonyPatch(typeof(ModelReplacementAPI), "RemovePlayerModelReplacement")]
		[HarmonyPostfix]
		public static void ResetCamera(PlayerControllerB player)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)player).gameObject;
			gameObject.transform.localScale = new Vector3(1f, 1f, 1f);
			gameObject.transform.Find("ScavengerModel").Find("metarig").Find("CameraContainer")
				.Find("MainCamera")
				.Find("HUDHelmetPosition")
				.localPosition = new Vector3(0.01f, -0.048f, -0.063f);
		}

		[HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")]
		[HarmonyPostfix]
		public static void DetectCamera()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			baseSize = ((Component)localPlayerController).gameObject.transform.localScale;
			if (baseSize == new Vector3(0.885f, 0.885f, 0.885f))
			{
				((Component)localPlayerController).gameObject.transform.Find("ScavengerModel/metarig/CameraContainer/MainCamera").localPosition = new Vector3(0f, 0.25f, -0.1f);
			}
			if (baseSize == new Vector3(1f, 1f, 1f))
			{
				((Component)localPlayerController).gameObject.transform.Find("ScavengerModel/metarig/CameraContainer/MainCamera").localPosition = new Vector3(0f, -0.05f, -0.2f);
			}
			if (baseSize == new Vector3(1.025f, 1.025f, 1.025f))
			{
				((Component)localPlayerController).gameObject.transform.Find("ScavengerModel/metarig/CameraContainer/MainCamera").localPosition = new Vector3(0f, -0.075f, -0.2f);
			}
		}

		[HarmonyPatch(typeof(Terminal), "QuitTerminal")]
		[HarmonyPostfix]
		public static void ResetCamera()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			((Component)localPlayerController).gameObject.transform.Find("ScavengerModel/metarig/CameraContainer/MainCamera").localPosition = new Vector3(0f, 0f, 0f);
		}
	}
}
namespace ModelReplacement
{
	public class NEFER : BodyReplacementBase
	{
		protected override GameObject LoadAssetsAndReturnModel()
		{
			string text = "Nefer";
			return Assets.MainAssetBundle.LoadAsset<GameObject>(text);
		}
	}
	public class JAHODA : BodyReplacementBase
	{
		protected override GameObject LoadAssetsAndReturnModel()
		{
			string text = "Jahoda";
			return Assets.MainAssetBundle.LoadAsset<GameObject>(text);
		}
	}
	public class LINNEA : BodyReplacementBase
	{
		protected override GameObject LoadAssetsAndReturnModel()
		{
			string text = "Linnea";
			return Assets.MainAssetBundle.LoadAsset<GameObject>(text);
		}
	}
	public class LAUMA : BodyReplacementBase
	{
		protected override GameObject LoadAssetsAndReturnModel()
		{
			string text = "Lauma";
			return Assets.MainAssetBundle.LoadAsset<GameObject>(text);
		}
	}
	[BepInPlugin("NodKraiSuitsVol2.Konk", "NodKraiSuitsVol2", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static ConfigFile config;

		public static ConfigEntry<bool> Antlers { get; private set; }

		private static void InitConfig()
		{
		}

		private void Awake()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			config = ((BaseUnityPlugin)this).Config;
			InitConfig();
			Assets.PopulateAssets();
			ModelReplacementAPI.RegisterSuitModelReplacement("Nefer", typeof(NEFER));
			ModelReplacementAPI.RegisterSuitModelReplacement("Linnea", typeof(LINNEA));
			ModelReplacementAPI.RegisterSuitModelReplacement("Jahoda", typeof(JAHODA));
			ModelReplacementAPI.RegisterSuitModelReplacement("Lauma", typeof(LAUMA));
			Harmony val = new Harmony("NodKraiSuitsVol2.Konk");
			val.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin NodKraiSuitsVol2.Konk is loaded!");
		}
	}
	public static class Assets
	{
		public static string mainAssetBundleName = "NodKraiSuitsVol2";

		public static AssetBundle MainAssetBundle = null;

		private static string GetAssemblyName()
		{
			return Assembly.GetExecutingAssembly().GetName().Name.Replace(" ", "_");
		}

		public static void PopulateAssets()
		{
			if ((Object)(object)MainAssetBundle == (Object)null)
			{
				Console.WriteLine(GetAssemblyName() + "." + mainAssetBundleName);
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetAssemblyName() + "." + mainAssetBundleName);
				MainAssetBundle = AssetBundle.LoadFromStream(stream);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}