Decompiled source of EchoStalker v0.2.3

EchoStalker.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("oance")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Prototype custom enemy for R.E.P.O.")]
[assembly: AssemblyFileVersion("0.2.3.0")]
[assembly: AssemblyInformationalVersion("0.2.3")]
[assembly: AssemblyProduct("EchoStalker")]
[assembly: AssemblyTitle("EchoStalker")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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 EchoStalker
{
	[BepInPlugin("oance.EchoStalker", "EchoStalker", "0.2.3")]
	[BepInProcess("REPO.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "oance.EchoStalker";

		public const string PluginName = "EchoStalker";

		public const string PluginVersion = "0.2.3";

		public const string RepoLibGuid = "REPOLib";

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		internal static PrototypeConfig Settings { get; private set; }

		internal static bool IsInitialized
		{
			get
			{
				if ((Object)(object)Instance != (Object)null)
				{
					return Settings != null;
				}
				return false;
			}
		}

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		private void Awake()
		{
			Instance = this;
			Settings = new PrototypeConfig(((BaseUnityPlugin)this).Config);
			Logger.LogInfo((object)"oance.EchoStalker v0.2.3 loaded; waiting for the Echo Stalker REPOLib bundle.");
		}
	}
	internal sealed class PrototypeConfig
	{
		internal ConfigEntry<float> RoamSpeed { get; }

		internal ConfigEntry<float> ChaseSpeed { get; }

		internal ConfigEntry<int> CaptureDamage { get; }

		internal ConfigEntry<float> CaptureDamageInterval { get; }

		internal PrototypeConfig(ConfigFile config)
		{
			RoamSpeed = config.Bind<float>("Movement", "RoamSpeed", 1.7f, "Movement speed while roaming.");
			ChaseSpeed = config.Bind<float>("Movement", "ChaseBaseSpeed", 8.5f, "Base movement speed while chasing a player. This v0.2 key supersedes the prototype's old ChaseSpeed setting; the monster also gains catch-up speed at range.");
			CaptureDamage = config.Bind<int>("Capture", "Damage", 20, "Nonlethal damage dealt on capture and on each latched damage tick.");
			CaptureDamageInterval = config.Bind<float>("Capture", "DamageInterval", 5f, "Seconds between nonlethal damage ticks while latched to a player.");
		}
	}
}
namespace EchoStalker.Runtime
{
	public sealed class EchoStalkerController : MonoBehaviour
	{
		private static readonly int AnimatorState = Animator.StringToHash("State");

		private static readonly int AnimatorDeath = Animator.StringToHash("Death");

		private static readonly FieldInfo? AudioCurrentSnapshotField = typeof(AudioManager).GetField("currentSnapshot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly HashSet<int> AudioIsolationOwners = new HashSet<int>();

		private static SoundSnapshot audioSnapshotBeforeIsolation = (SoundSnapshot)1;

		private static bool audioSnapshotStored;

		[Header("Required R.E.P.O. components")]
		[SerializeField]
		private Enemy enemy;

		[SerializeField]
		private EnemyNavMeshAgent agent;

		[SerializeField]
		private EnemyHealth health;

		[SerializeField]
		private EnemyVision vision;

		[SerializeField]
		private EnemyStateSpawn spawnState;

		[SerializeField]
		private EnemyStateDespawn despawnState;

		[SerializeField]
		private EnemyStateStunned stunnedState;

		[SerializeField]
		private Collider bodyCollider;

		private PhotonView photonView;

		[Header("Origins")]
		[SerializeField]
		private Transform visionOrigin;

		[SerializeField]
		private Transform attackOrigin;

		[SerializeField]
		private Transform visualRoot;

		[Header("Presentation")]
		[SerializeField]
		private Animator? animator;

		[SerializeField]
		private Sound? spawnSound;

		[SerializeField]
		private Sound? ambientSound;

		[SerializeField]
		private Sound? alertSound;

		[SerializeField]
		private Sound? attackSound;

		[SerializeField]
		private Sound? captiveSound;

		[SerializeField]
		private Sound? hurtSound;

		[SerializeField]
		private Sound? deathSound;

		[Header("Senses")]
		[SerializeField]
		[Min(1f)]
		private float senseRange = 16f;

		[Header("Roaming")]
		[SerializeField]
		[Min(0.1f)]
		private float roamSpeed = 1.7f;

		[SerializeField]
		[Min(0.1f)]
		private float roamAcceleration = 6f;

		[SerializeField]
		[Min(0.1f)]
		private float roamRepathTime = 2.5f;

		[Header("Chase")]
		[SerializeField]
		[Min(0f)]
		private float alertTime = 0.85f;

		[SerializeField]
		[Min(0.1f)]
		private float chaseSpeed = 8.5f;

		[SerializeField]
		[Min(0.1f)]
		private float chaseAcceleration = 34f;

		[Header("Capture")]
		[SerializeField]
		[Min(0.1f)]
		private float captureRange = 2.1f;

		[SerializeField]
		[Min(0f)]
		private float captureWindup = 0.55f;

		[SerializeField]
		[Min(0f)]
		private int captureDamage = 20;

		[SerializeField]
		[Min(0.25f)]
		private float captureDamageInterval = 5f;

		[SerializeField]
		[Min(0.25f)]
		private float sitDistance = 0.7f;

		[SerializeField]
		[Min(0.1f)]
		private float sitFollowSpeed = 5f;

		[SerializeField]
		[Min(0.1f)]
		private float sitFollowAcceleration = 18f;

		[SerializeField]
		[Min(0.05f)]
		private float sitDeadZone = 0.22f;

		[SerializeField]
		[Min(0.1f)]
		private float sitTurnSpeed = 7f;

		[SerializeField]
		[Min(0.1f)]
		private float captureDamageConfirmTimeout = 1.25f;

		[Header("Thrown object impacts")]
		[SerializeField]
		[Min(0.1f)]
		private float thrownObjectMinSpeed = 2.5f;

		[SerializeField]
		[Min(0.1f)]
		private float thrownObjectMediumSpeed = 5f;

		[SerializeField]
		[Min(0.1f)]
		private float thrownObjectHeavySpeed = 8f;

		[SerializeField]
		[Min(0f)]
		private float thrownObjectDamagePerMass = 5f;

		[SerializeField]
		[Min(0f)]
		private float thrownObjectStunMass = 2f;

		[SerializeField]
		[Min(0f)]
		private float thrownObjectHitCooldown = 0.35f;

		[Header("Lifecycle")]
		[SerializeField]
		[Min(0f)]
		private float stateDespawnDelay = 0.65f;

		[SerializeField]
		[Min(0f)]
		private float deathDespawnDelay = 2.2f;

		private PlayerAvatar? target;

		private EnemyState observedState;

		private LayerMask visionMask;

		private float stateTime;

		private float repathTime;

		private bool hitApplied;

		private bool targetClaimed;

		private bool captureCommitted;

		private bool captureHealthReady;

		private bool captureDamageExpected;

		private bool captureDamageConfirmed;

		private bool captureDamageObserved;

		private bool captureHitInFlight;

		private int lowestObservedTargetHealth;

		private int healthFloorBeforePendingHit;

		private int claimedTargetViewId = -1;

		private int captureHitSequence;

		private int pendingCaptureHitSequence;

		private int lastProcessedCaptureHitMasterActorNumber = -1;

		private int lastProcessedCaptureHitSequence;

		private int lastProcessedCaptureHitTargetViewId = -1;

		private int lastProcessedCaptureHitPostHealth;

		private bool lastProcessedCaptureHitHealDetected;

		private float captureHitRequestedTime;

		private float captureAcknowledgedTime;

		private float nextCaptureDamageTime;

		private Vector3 sitOffsetDirection;

		private Quaternion visualRootInitialLocalRotation;

		private bool localCaptureHealthReady;

		private bool localCaptureAudioReleased;

		private int localLowestObservedTargetHealth;

		private bool holdsAudioIsolation;

		private bool captiveMixerAssigned;

		private bool captivePlaybackStartedLogged;

		private bool captivePlaybackWarningLogged;

		private float captivePlaybackRequestedTime;

		private bool dead;

		private bool deathFinished;

		private bool despawnCommitted;

		private float deathTime;

		private float nextThrownObjectHitTime;

		private bool setupIsValid;

		private bool IsHost => SemiFunc.IsMasterClientOrSingleplayer();

		private void Awake()
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Expected O, but got Unknown
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Expected O, but got Unknown
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Expected O, but got Unknown
			if (enemy == null)
			{
				enemy = ((Component)this).GetComponent<Enemy>();
			}
			if (agent == null)
			{
				agent = ((Component)this).GetComponent<EnemyNavMeshAgent>();
			}
			if (health == null)
			{
				health = ((Component)this).GetComponent<EnemyHealth>();
			}
			if (vision == null)
			{
				vision = ((Component)this).GetComponentInChildren<EnemyVision>(true);
			}
			if (spawnState == null)
			{
				spawnState = ((Component)this).GetComponentInChildren<EnemyStateSpawn>(true);
			}
			if (despawnState == null)
			{
				despawnState = ((Component)this).GetComponentInChildren<EnemyStateDespawn>(true);
			}
			if (stunnedState == null)
			{
				stunnedState = ((Component)this).GetComponentInChildren<EnemyStateStunned>(true);
			}
			if (bodyCollider == null)
			{
				bodyCollider = ((Component)this).GetComponent<Collider>();
			}
			if (photonView == null)
			{
				photonView = ((Component)this).GetComponent<PhotonView>();
			}
			if (visionOrigin == null)
			{
				visionOrigin = ((Component)this).transform;
			}
			if (attackOrigin == null)
			{
				attackOrigin = ((Component)this).transform;
			}
			if (visualRoot == null)
			{
				visualRoot = ((Component)this).transform;
			}
			visualRootInitialLocalRotation = visualRoot.localRotation;
			visionMask = SemiFunc.LayerMaskGetVisionObstruct();
			ConfigureCaptiveAudioSource();
			DisableVanillaStates<EnemyStateRoaming>();
			DisableVanillaStates<EnemyStateChaseBegin>();
			DisableVanillaStates<EnemyStateChase>();
			DisableVanillaStates<EnemyStateChaseSlow>();
			DisableVanillaStates<EnemyStateChaseEnd>();
			if (Plugin.IsInitialized)
			{
				roamSpeed = Mathf.Max(0.1f, Plugin.Settings.RoamSpeed.Value);
				chaseSpeed = Mathf.Max(0.1f, Plugin.Settings.ChaseSpeed.Value);
				captureDamage = Mathf.Max(0, Plugin.Settings.CaptureDamage.Value);
				captureDamageInterval = Mathf.Max(0.25f, Plugin.Settings.CaptureDamageInterval.Value);
			}
			setupIsValid = ValidateSetup();
			if (!setupIsValid)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			health.onDeathStart.AddListener(new UnityAction(OnDeathStart));
			health.onDeath.AddListener(new UnityAction(OnDeath));
			health.onHurt.AddListener(new UnityAction(OnHurt));
			spawnState.OnSpawn.AddListener(new UnityAction(OnSpawn));
		}

		private void OnDestroy()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			ReleaseAudioIsolation();
			if ((Object)(object)health != (Object)null)
			{
				UnityEvent onDeathStart = health.onDeathStart;
				if (onDeathStart != null)
				{
					onDeathStart.RemoveListener(new UnityAction(OnDeathStart));
				}
				UnityEvent onDeath = health.onDeath;
				if (onDeath != null)
				{
					onDeath.RemoveListener(new UnityAction(OnDeath));
				}
				UnityEvent onHurt = health.onHurt;
				if (onHurt != null)
				{
					onHurt.RemoveListener(new UnityAction(OnHurt));
				}
			}
			if ((Object)(object)spawnState != (Object)null)
			{
				UnityEvent onSpawn = spawnState.OnSpawn;
				if (onSpawn != null)
				{
					onSpawn.RemoveListener(new UnityAction(OnSpawn));
				}
			}
			Sound? obj = ambientSound;
			if (obj != null)
			{
				obj.Stop();
			}
			Sound? obj2 = captiveSound;
			if (obj2 != null)
			{
				obj2.Stop();
			}
		}

		private void OnDisable()
		{
			ReleaseAudioIsolation();
			Sound? obj = captiveSound;
			if (obj != null)
			{
				obj.Stop();
			}
		}

		private void Update()
		{
			//IL_000f: 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_0017: 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_0020: 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_0034: 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_003a: Invalid comparison between Unknown and I4
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Invalid comparison between Unknown and I4
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Invalid comparison between Unknown and I4
			//IL_00b7: 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_0125: Invalid comparison between Unknown and I4
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Invalid comparison between Unknown and I4
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Invalid comparison between Unknown and I4
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Invalid comparison between Unknown and I4
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Expected I4, but got Unknown
			if (!setupIsValid)
			{
				return;
			}
			EnemyState currentState = enemy.CurrentState;
			if (currentState != observedState)
			{
				observedState = currentState;
				EnterState(currentState);
			}
			bool flag = !dead && (int)currentState != 0 && (int)currentState != 11 && (int)currentState != 6;
			Sound? obj = ambientSound;
			if (obj != null)
			{
				obj.PlayLoop(flag, 0.25f, 0.25f, 1f, 1f);
			}
			bool captureStateActive = !dead && (int)currentState == 6;
			bool flag2 = UpdateLocalCaptureAudio(captureStateActive);
			Sound? obj2 = captiveSound;
			if (obj2 != null)
			{
				obj2.PlayLoop(flag2, 4f, 8f, 1f, 1f);
			}
			ReportCaptivePlayback(captureStateActive, flag2);
			UpdateReplicatedPresentation(currentState);
			if (targetClaimed && !dead)
			{
				MaintainClaimProtection();
			}
			if (dead)
			{
				agent.Stop(0.1f);
				if (deathFinished)
				{
					deathTime += Time.deltaTime;
					if (IsHost && deathTime >= deathDespawnDelay)
					{
						CommitDespawn();
					}
				}
			}
			else if ((int)currentState == 11)
			{
				agent.Stop(0.1f);
				stateTime += Time.deltaTime;
				if (IsHost && stateTime >= stateDespawnDelay)
				{
					CommitDespawn();
				}
			}
			else
			{
				if (!IsHost)
				{
					return;
				}
				if ((int)currentState == 9 && targetClaimed)
				{
					stunnedState.Reset();
					SetState((EnemyState)(captureCommitted ? 6 : 4));
					return;
				}
				if (((int)currentState <= 1 || (int)currentState == 9) ? true : false)
				{
					agent.Stop(0.1f);
					return;
				}
				stateTime += Time.deltaTime;
				switch (currentState - 2)
				{
				case 0:
					UpdateRoam();
					break;
				case 1:
					UpdateAlert();
					break;
				case 2:
					UpdateChase();
					break;
				case 3:
					UpdateCaptureWindup();
					break;
				case 4:
					UpdateCaptured();
					break;
				}
			}
		}

		private void OnCollisionEnter(Collision collision)
		{
			//IL_0069: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			if (!setupIsValid || !IsHost || dead || targetClaimed || !health.objectHurt || Time.time < nextThrownObjectHitTime)
			{
				return;
			}
			Rigidbody rigidbody = collision.rigidbody;
			if ((Object)(object)rigidbody == (Object)null || ((Object)(object)((Component)rigidbody).GetComponent<PhysGrabObject>() == (Object)null && (Object)(object)((Component)rigidbody).GetComponentInParent<PhysGrabObject>() == (Object)null))
			{
				return;
			}
			Vector3 val = collision.relativeVelocity;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (!(magnitude < thrownObjectMinSpeed))
			{
				nextThrownObjectHitTime = Time.time + thrownObjectHitCooldown;
				float num = ((magnitude >= thrownObjectHeavySpeed) ? 3f : ((magnitude >= thrownObjectMediumSpeed) ? 2f : 1f));
				int num2 = Mathf.Max(1, Mathf.RoundToInt(thrownObjectDamagePerMass * num * Mathf.Max(0.5f, rigidbody.mass) * Mathf.Max(0f, health.objectHurtMultiplier)));
				val = ((Component)this).transform.position - rigidbody.worldCenterOfMass;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				health.Hurt(num2, normalized);
				UnityEvent onObjectHurt = health.onObjectHurt;
				if (onObjectHurt != null)
				{
					onObjectHurt.Invoke();
				}
				if (!dead && health.objectHurtStun && rigidbody.mass >= thrownObjectStunMass)
				{
					stunnedState.Set(2f);
				}
			}
		}

		private void EnterState(EnemyState state)
		{
			//IL_003c: 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_0070: Expected I4, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected I4, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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)
			stateTime = 0f;
			repathTime = 0f;
			hitApplied = false;
			if ((Object)(object)animator != (Object)null)
			{
				animator.SetInteger(AnimatorState, (int)state);
			}
			switch (state - 1)
			{
			case 0:
				dead = false;
				deathFinished = false;
				despawnCommitted = false;
				deathTime = 0f;
				nextThrownObjectHitTime = 0f;
				target = null;
				targetClaimed = false;
				captureCommitted = false;
				captureHealthReady = false;
				captureDamageExpected = false;
				captureDamageConfirmed = false;
				captureDamageObserved = false;
				captureHitInFlight = false;
				lowestObservedTargetHealth = 0;
				healthFloorBeforePendingHit = 0;
				claimedTargetViewId = -1;
				pendingCaptureHitSequence = 0;
				captureHitRequestedTime = 0f;
				captureAcknowledgedTime = 0f;
				nextCaptureDamageTime = 0f;
				sitOffsetDirection = Vector3.zero;
				ResetLocalCaptureAudioState();
				ReleaseAudioIsolation();
				visualRoot.localRotation = visualRootInitialLocalRotation;
				health.OverrideDamageResistance(0f, 0f);
				stunnedState.OverrideDisable(0f);
				bodyCollider.enabled = true;
				Play(spawnSound);
				break;
			case 2:
			{
				if (enemy.TargetPlayerViewID > 0)
				{
					claimedTargetViewId = enemy.TargetPlayerViewID;
				}
				ResetLocalCaptureAudioState();
				targetClaimed = true;
				MaintainClaimProtection();
				EnemyNavMeshAgent obj3 = agent;
				if (obj3 != null)
				{
					obj3.Stop(0.1f);
				}
				Play(alertSound);
				break;
			}
			case 3:
				targetClaimed = true;
				MaintainClaimProtection();
				break;
			case 4:
			{
				targetClaimed = true;
				MaintainClaimProtection();
				EnemyNavMeshAgent obj2 = agent;
				if (obj2 != null)
				{
					obj2.Stop(0.1f);
				}
				Play(attackSound);
				break;
			}
			case 5:
			{
				targetClaimed = true;
				captureCommitted = true;
				MaintainClaimProtection();
				EnemyNavMeshAgent obj5 = agent;
				if (obj5 != null)
				{
					obj5.Stop(0.1f);
				}
				bodyCollider.enabled = false;
				nextCaptureDamageTime = Time.time + captureDamageInterval;
				break;
			}
			case 8:
			{
				EnemyNavMeshAgent obj4 = agent;
				if (obj4 != null)
				{
					obj4.Stop(0.1f);
				}
				break;
			}
			case 10:
			{
				despawnCommitted = false;
				EnemyNavMeshAgent obj = agent;
				if (obj != null)
				{
					obj.Stop(0.1f);
				}
				StopLoops();
				ReleaseAudioIsolation();
				break;
			}
			case 1:
			case 6:
			case 7:
			case 9:
				break;
			}
		}

		private void UpdateRoam()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Invalid comparison between Unknown and I4
			agent.UpdateAgent(roamSpeed, roamAcceleration);
			repathTime -= Time.deltaTime;
			if (repathTime <= 0f || !agent.HasPath())
			{
				Vector3 destination = default(Vector3);
				if (SemiFunc.EnemyRoamPoint(enemy, ref destination))
				{
					agent.SetDestination(destination);
				}
				repathTime = roamRepathTime;
			}
			PlayerAvatar val = FindTarget(senseRange);
			if (IsTargetUsable(val))
			{
				target = val;
				claimedTargetViewId = val.photonView.ViewID;
				targetClaimed = true;
				MaintainClaimProtection();
				enemy.SetChaseTarget(val);
				if ((int)enemy.CurrentState != 3)
				{
					target = null;
					claimedTargetViewId = -1;
					targetClaimed = false;
				}
			}
		}

		private void UpdateAlert()
		{
			agent.Stop(0.1f);
			if (!IsTargetUsable(target))
			{
				RecoverReplicatedTarget();
			}
			if (!IsTargetUsable(target))
			{
				SetState((EnemyState)11);
			}
			else if (stateTime >= alertTime)
			{
				SetState((EnemyState)4);
			}
		}

		private void UpdateChase()
		{
			//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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			if (!IsTargetUsable(target))
			{
				RecoverReplicatedTarget();
			}
			if (!IsTargetUsable(target))
			{
				SetState((EnemyState)11);
				return;
			}
			PlayerAvatar val = target;
			Vector3 position = val.playerTransform.position;
			float num = Vector3.Distance(((Component)this).transform.position, position);
			enemy.SetChaseTimer();
			float num2 = chaseSpeed + Mathf.Clamp((num - 4f) * 0.65f, 0f, 4f);
			agent.UpdateAgent(num2, chaseAcceleration);
			agent.SetDestination(position);
			if (num <= captureRange && SemiFunc.PlayerVisionCheckPosition(attackOrigin.position, position, captureRange + 0.5f, val, true))
			{
				SetState((EnemyState)5);
			}
		}

		private void UpdateCaptureWindup()
		{
			agent.Stop(0.1f);
			if (!IsTargetUsable(target))
			{
				RecoverReplicatedTarget();
			}
			if (!IsTargetUsable(target))
			{
				SetState((EnemyState)11);
			}
			else if (!hitApplied && stateTime >= captureWindup)
			{
				if (!TryCaptureTarget())
				{
					SetState((EnemyState)4);
					return;
				}
				hitApplied = true;
				SetState((EnemyState)6);
			}
		}

		private void UpdateCaptured()
		{
			if (!IsTargetUsable(target))
			{
				RecoverReplicatedTarget();
			}
			if (!IsTargetUsable(target) || (Object)(object)target.playerHealth == (Object)null || target.playerHealth.health <= 0)
			{
				SetState((EnemyState)11);
				return;
			}
			MoveBesideTarget(target);
			PlayerHealth playerHealth = target.playerHealth;
			if (!captureHealthReady)
			{
				if (playerHealth.healthSet)
				{
					captureHealthReady = true;
					lowestObservedTargetHealth = playerHealth.health;
					captureDamageConfirmed = true;
					captureDamageObserved = true;
					captureHitInFlight = false;
				}
				return;
			}
			int num = playerHealth.health;
			if (!captureDamageConfirmed)
			{
				if (Time.time - captureHitRequestedTime >= captureDamageConfirmTimeout)
				{
					SetState((EnemyState)11);
				}
			}
			else if (!captureDamageObserved)
			{
				if (num <= lowestObservedTargetHealth)
				{
					captureDamageObserved = true;
					lowestObservedTargetHealth = num;
				}
				else if (Time.time - captureAcknowledgedTime >= 0.35f)
				{
					SetState((EnemyState)11);
				}
			}
			else if (num > lowestObservedTargetHealth)
			{
				SetState((EnemyState)11);
			}
			else
			{
				lowestObservedTargetHealth = Mathf.Min(lowestObservedTargetHealth, num);
				if (Time.time >= nextCaptureDamageTime)
				{
					BeginCaptureDamageHit(playerHealth);
				}
			}
		}

		private PlayerAvatar? FindTarget(float range)
		{
			//IL_0007: 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)
			return SemiFunc.PlayerGetNearestPlayerAvatarWithinRange(range, visionOrigin.position, true, visionMask);
		}

		private bool TryCaptureTarget()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0058: 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)
			if (!IsTargetUsable(target) || (Object)(object)target.playerHealth == (Object)null)
			{
				return false;
			}
			Vector3 position = target.playerTransform.position;
			if (Vector3.Distance(attackOrigin.position, position) > captureRange + 0.5f || !SemiFunc.PlayerVisionCheckPosition(attackOrigin.position, position, captureRange + 0.5f, target, true))
			{
				return false;
			}
			PlayerHealth playerHealth = target.playerHealth;
			if (!playerHealth.healthSet)
			{
				return false;
			}
			captureHealthReady = playerHealth.healthSet;
			lowestObservedTargetHealth = playerHealth.health;
			captureCommitted = true;
			SetSitOffset(target);
			BeginCaptureDamageHit(playerHealth);
			return true;
		}

		private void BeginCaptureDamageHit(PlayerHealth targetHealth)
		{
			if (targetHealth.healthSet)
			{
				lowestObservedTargetHealth = Mathf.Min(lowestObservedTargetHealth, targetHealth.health);
				healthFloorBeforePendingHit = lowestObservedTargetHealth;
				captureDamageExpected = captureDamage > 0 && targetHealth.health > 1;
				captureDamageConfirmed = !captureDamageExpected;
				captureDamageObserved = !captureDamageExpected;
				captureHitInFlight = captureDamageExpected;
				captureHitRequestedTime = Time.time;
				nextCaptureDamageTime = Time.time + captureDamageInterval;
				if (captureDamageExpected)
				{
					pendingCaptureHitSequence = ++captureHitSequence;
					SendNonlethalCaptureHit(targetHealth, pendingCaptureHitSequence);
				}
			}
		}

		private void SendNonlethalCaptureHit(PlayerHealth targetHealth, int hitSequence)
		{
			int num = SemiFunc.EnemyGetIndex(enemy);
			if (!GameManager.Multiplayer())
			{
				int num2 = ApplyNonlethalCaptureHit(targetHealth, captureDamage, num);
				ConfirmCaptureHit(targetHealth.photonView.ViewID, hitSequence, num2);
				RecordLocalCaptureHealth(num2);
				return;
			}
			photonView.RPC("CaptureHitRPC", (RpcTarget)0, new object[5]
			{
				targetHealth.photonView.ViewID,
				hitSequence,
				healthFloorBeforePendingHit,
				captureDamage,
				num
			});
		}

		[PunRPC]
		private void CaptureHitRPC(int targetViewId, int hitSequence, int expectedHealthFloor, int requestedDamage, int enemyIndex, PhotonMessageInfo info)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a3: 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_00a8: Invalid comparison between Unknown and I4
			if (!SemiFunc.MasterOnlyRPC(info))
			{
				return;
			}
			PhotonView val = PhotonView.Find(targetViewId);
			if ((Object)(object)val == (Object)null || !val.IsMine)
			{
				return;
			}
			PlayerHealth val2 = ((Component)val).GetComponent<PlayerHealth>() ?? ((Component)val).GetComponentInChildren<PlayerHealth>(true) ?? ((Component)val).GetComponentInParent<PlayerHealth>();
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Player sender = info.Sender;
			int num = ((sender != null) ? sender.ActorNumber : (-1));
			if (num == lastProcessedCaptureHitMasterActorNumber && hitSequence <= lastProcessedCaptureHitSequence)
			{
				if (hitSequence == lastProcessedCaptureHitSequence && targetViewId == lastProcessedCaptureHitTargetViewId)
				{
					SendCaptureHitResult(targetViewId, hitSequence, lastProcessedCaptureHitPostHealth, lastProcessedCaptureHitHealDetected);
				}
				return;
			}
			EnemyState currentState = enemy.CurrentState;
			bool flag = currentState - 3 <= 3;
			bool flag2 = flag;
			if (((Behaviour)this).enabled && setupIsValid && !dead && flag2 && (claimedTargetViewId <= 0 || targetViewId == claimedTargetViewId))
			{
				bool flag3 = localCaptureAudioReleased || val2.health > Mathf.Max(1, expectedHealthFloor) || (localCaptureHealthReady && val2.health > localLowestObservedTargetHealth);
				int num2 = val2.health;
				if (flag3)
				{
					localCaptureAudioReleased = true;
					ReleaseAudioIsolation();
				}
				else
				{
					num2 = ApplyNonlethalCaptureHit(val2, requestedDamage, enemyIndex);
					RecordLocalCaptureHealth(num2);
				}
				lastProcessedCaptureHitMasterActorNumber = num;
				lastProcessedCaptureHitSequence = hitSequence;
				lastProcessedCaptureHitTargetViewId = targetViewId;
				lastProcessedCaptureHitPostHealth = num2;
				lastProcessedCaptureHitHealDetected = flag3;
				SendCaptureHitResult(targetViewId, hitSequence, num2, flag3);
			}
		}

		private void SendCaptureHitResult(int targetViewId, int hitSequence, int postHitHealth, bool healDetected)
		{
			photonView.RPC("CaptureHitResultRPC", (RpcTarget)2, new object[4] { targetViewId, hitSequence, postHitHealth, healDetected });
		}

		[PunRPC]
		private void CaptureHitResultRPC(int targetViewId, int hitSequence, int postHitHealth, bool healDetected, PhotonMessageInfo info)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient || !captureCommitted || !captureHitInFlight || targetViewId != claimedTargetViewId || hitSequence != pendingCaptureHitSequence || postHitHealth < 1)
			{
				return;
			}
			EnemyState currentState = enemy.CurrentState;
			if ((int)currentState != 5 && (int)currentState != 6)
			{
				return;
			}
			PhotonView val = PhotonView.Find(targetViewId);
			if (!((Object)(object)val == (Object)null) && SemiFunc.OwnerOnlyRPC(info, val))
			{
				if (healDetected || postHitHealth > healthFloorBeforePendingHit)
				{
					captureHitInFlight = false;
					SetState((EnemyState)11);
				}
				else
				{
					ConfirmCaptureHit(targetViewId, hitSequence, postHitHealth);
				}
			}
		}

		private void ConfirmCaptureHit(int targetViewId, int hitSequence, int postHitHealth)
		{
			if (hitSequence == pendingCaptureHitSequence && (!GameManager.Multiplayer() || targetViewId == claimedTargetViewId))
			{
				captureHitInFlight = false;
				captureDamageConfirmed = true;
				captureDamageObserved = !captureDamageExpected;
				lowestObservedTargetHealth = Mathf.Min(healthFloorBeforePendingHit, Mathf.Max(1, postHitHealth));
				captureAcknowledgedTime = Time.time;
			}
		}

		private static int ApplyNonlethalCaptureHit(PlayerHealth targetHealth, int requestedDamage, int enemyIndex)
		{
			int num = Mathf.Min(Mathf.Max(0, requestedDamage), Mathf.Max(0, targetHealth.health - 1));
			if (num > 0)
			{
				targetHealth.Hurt(num, false, enemyIndex, false);
			}
			return targetHealth.health;
		}

		private void MoveBesideTarget(PlayerAvatar activeTarget)
		{
			//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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			if (((Vector3)(ref sitOffsetDirection)).sqrMagnitude < 0.5f)
			{
				SetSitOffset(activeTarget);
			}
			Vector3 position = activeTarget.playerTransform.position;
			Vector3 val = position + sitOffsetDirection * sitDistance;
			NavMeshHit val2 = default(NavMeshHit);
			val = ((!NavMesh.SamplePosition(val, ref val2, 1.5f, -1)) ? position : ((NavMeshHit)(ref val2)).position);
			Vector3 val3 = val - ((Component)this).transform.position;
			val3.y = 0f;
			if (((Vector3)(ref val3)).magnitude > sitDeadZone)
			{
				agent.UpdateAgent(sitFollowSpeed, sitFollowAcceleration);
				agent.SetDestination(val);
			}
			else
			{
				agent.Stop(0.1f);
			}
		}

		private void SetSitOffset(PlayerAvatar activeTarget)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 right = activeTarget.playerTransform.right;
			right.y = 0f;
			if (((Vector3)(ref right)).sqrMagnitude < 0.01f)
			{
				right = Vector3.right;
			}
			((Vector3)(ref right)).Normalize();
			Vector3 val = ((Component)this).transform.position - activeTarget.playerTransform.position;
			val.y = 0f;
			float num = ((Vector3.Dot(val, right) < 0f) ? (-1f) : 1f);
			sitOffsetDirection = right * num;
		}

		private void RecoverReplicatedTarget()
		{
			if (IsClaimedTarget(enemy.TargetPlayerAvatar))
			{
				target = enemy.TargetPlayerAvatar;
			}
		}

		private void MaintainClaimProtection()
		{
			health.OverrideDamageResistance(1f, 0.5f);
			stunnedState.OverrideDisable(0.5f);
		}

		private bool UpdateLocalCaptureAudio(bool captureStateActive)
		{
			ConfigureCaptiveAudioSource();
			if (!captureStateActive)
			{
				ReleaseAudioIsolation();
				return false;
			}
			PlayerAvatar val = (PlayerAvatar)(IsClaimedTarget(target) ? ((object)target) : ((object)enemy.TargetPlayerAvatar));
			if (!IsClaimedTarget(val) || !IsLocalPlayer(val))
			{
				ReleaseAudioIsolation();
				return false;
			}
			PlayerHealth playerHealth = val.playerHealth;
			if (playerHealth.healthSet)
			{
				if (!localCaptureHealthReady)
				{
					RecordLocalCaptureHealth(playerHealth.health);
				}
				else if (playerHealth.health > localLowestObservedTargetHealth)
				{
					localCaptureAudioReleased = true;
				}
				else
				{
					localLowestObservedTargetHealth = Mathf.Min(localLowestObservedTargetHealth, playerHealth.health);
				}
			}
			if (localCaptureAudioReleased)
			{
				ReleaseAudioIsolation();
				return false;
			}
			AcquireAudioIsolation();
			return true;
		}

		private void RecordLocalCaptureHealth(int currentHealth)
		{
			int num = Mathf.Max(1, currentHealth);
			if (!localCaptureHealthReady)
			{
				localCaptureHealthReady = true;
				localCaptureAudioReleased = false;
				localLowestObservedTargetHealth = num;
			}
			else
			{
				localLowestObservedTargetHealth = Mathf.Min(localLowestObservedTargetHealth, num);
			}
		}

		private void ResetLocalCaptureAudioState()
		{
			localCaptureHealthReady = false;
			localCaptureAudioReleased = false;
			localLowestObservedTargetHealth = 0;
		}

		private void ConfigureCaptiveAudioSource()
		{
			AudioSource val = captiveSound?.Source;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			captiveSound.StartTimeOverride = 0f;
			val.ignoreListenerPause = true;
			val.ignoreListenerVolume = false;
			val.priority = 0;
			if (!captiveMixerAssigned && !((Object)(object)AudioManager.instance == (Object)null) && !((Object)(object)AudioManager.instance.AudioCutscene == (Object)null))
			{
				AudioSource component = AudioManager.instance.AudioCutscene.GetComponent<AudioSource>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.outputAudioMixerGroup != (Object)null)
				{
					val.outputAudioMixerGroup = component.outputAudioMixerGroup;
					captiveMixerAssigned = true;
				}
			}
		}

		private void AcquireAudioIsolation()
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			AudioManager instance = AudioManager.instance;
			if (holdsAudioIsolation || (Object)(object)captiveSound?.Source == (Object)null || (Object)(object)instance == (Object)null || !captiveMixerAssigned)
			{
				return;
			}
			int instanceID = ((Object)this).GetInstanceID();
			if (AudioIsolationOwners.Add(instanceID) && AudioIsolationOwners.Count == 1)
			{
				if (!TryGetCurrentSoundSnapshot(instance, out audioSnapshotBeforeIsolation))
				{
					audioSnapshotBeforeIsolation = (SoundSnapshot)1;
				}
				audioSnapshotStored = true;
				instance.SetSoundSnapshot((SoundSnapshot)3, 0.05f);
			}
			holdsAudioIsolation = true;
		}

		private void ReleaseAudioIsolation()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Invalid comparison between Unknown and I4
			if (!holdsAudioIsolation)
			{
				return;
			}
			Sound? obj = captiveSound;
			if (obj != null)
			{
				obj.Stop();
			}
			AudioIsolationOwners.Remove(((Object)this).GetInstanceID());
			holdsAudioIsolation = false;
			if (AudioIsolationOwners.Count == 0 && audioSnapshotStored)
			{
				AudioManager instance = AudioManager.instance;
				if ((Object)(object)instance != (Object)null && (!TryGetCurrentSoundSnapshot(instance, out var snapshot) || (int)snapshot == 3))
				{
					instance.SetSoundSnapshot(audioSnapshotBeforeIsolation, 0.1f);
				}
				audioSnapshotStored = false;
			}
		}

		private static bool TryGetCurrentSoundSnapshot(AudioManager audioManager, out SoundSnapshot snapshot)
		{
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected I4, but got Unknown
			if (AudioCurrentSnapshotField?.GetValue(audioManager) is SoundSnapshot val)
			{
				snapshot = (SoundSnapshot)(int)val;
				return true;
			}
			snapshot = (SoundSnapshot)1;
			return false;
		}

		private void ReportCaptivePlayback(bool captureStateActive, bool captiveActive)
		{
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Invalid comparison between Unknown and I4
			//IL_00d9: 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_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			AudioSource val = captiveSound?.Source;
			if (!captureStateActive)
			{
				captivePlaybackStartedLogged = false;
				captivePlaybackWarningLogged = false;
				captivePlaybackRequestedTime = 0f;
			}
			else
			{
				if (!captiveActive || (Object)(object)val == (Object)null)
				{
					return;
				}
				if (captivePlaybackRequestedTime <= 0f)
				{
					captivePlaybackRequestedTime = Time.unscaledTime;
				}
				AudioClip clip = val.clip;
				if (val.isPlaying)
				{
					if (!captivePlaybackStartedLogged && Plugin.IsInitialized)
					{
						string arg = (((Object)(object)val.outputAudioMixerGroup != (Object)null) ? ((Object)val.outputAudioMixerGroup).name : "direct output");
						Plugin.Logger.LogInfo((object)("Captive audio started: clip='" + (((clip != null) ? ((Object)clip).name : null) ?? "<none>") + "', loadState=" + (((clip != null) ? ((object)clip.loadState/*cast due to .constrained prefix*/).ToString() : null) ?? "missing") + ", " + $"volume={val.volume:F2}, mixer='{arg}'."));
					}
					captivePlaybackStartedLogged = true;
					return;
				}
				bool flag = (Object)(object)clip != (Object)null && (int)clip.loadState == 3;
				if (!captivePlaybackWarningLogged && (flag || Time.unscaledTime - captivePlaybackRequestedTime >= 1.5f) && Plugin.IsInitialized)
				{
					Plugin.Logger.LogWarning((object)("Captive audio was requested but is not playing: clip='" + (((clip != null) ? ((Object)clip).name : null) ?? "<none>") + "', loadState=" + (((clip != null) ? ((object)clip.loadState/*cast due to .constrained prefix*/).ToString() : null) ?? "missing") + ", " + $"sourceEnabled={((Behaviour)val).enabled}, active={((Component)val).gameObject.activeInHierarchy}, " + $"mixerAssigned={(Object)(object)val.outputAudioMixerGroup != (Object)null}."));
					captivePlaybackWarningLogged = true;
				}
			}
		}

		private static bool IsLocalPlayer(PlayerAvatar player)
		{
			if ((Object)(object)PlayerController.instance != (Object)null && (Object)(object)player == (Object)(object)PlayerController.instance.playerAvatarScript)
			{
				return true;
			}
			if (!GameManager.Multiplayer())
			{
				return (Object)(object)PlayerController.instance == (Object)null;
			}
			if ((Object)(object)player.photonView != (Object)null)
			{
				return player.photonView.IsMine;
			}
			return false;
		}

		private bool IsClaimedTarget(PlayerAvatar? player)
		{
			if (IsTargetUsable(player) && (Object)(object)player.photonView != (Object)null)
			{
				if (claimedTargetViewId > 0)
				{
					return player.photonView.ViewID == claimedTargetViewId;
				}
				return true;
			}
			return false;
		}

		private void UpdateReplicatedPresentation(EnemyState state)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			bodyCollider.enabled = !dead && (int)state != 6 && (int)state != 11;
			if ((int)state != 6 || (Object)(object)visualRoot == (Object)null)
			{
				return;
			}
			PlayerAvatar val = (PlayerAvatar)(IsClaimedTarget(target) ? ((object)target) : ((object)enemy.TargetPlayerAvatar));
			if (IsClaimedTarget(val))
			{
				Vector3 val2 = val.playerTransform.position - visualRoot.position;
				val2.y = 0f;
				if (!(((Vector3)(ref val2)).sqrMagnitude < 0.01f))
				{
					Quaternion val3 = Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up);
					visualRoot.rotation = Quaternion.Slerp(visualRoot.rotation, val3, 1f - Mathf.Exp((0f - sitTurnSpeed) * Time.deltaTime));
				}
			}
		}

		private void SetState(EnemyState next)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (IsHost && !dead && enemy.CurrentState != next)
			{
				enemy.CurrentState = next;
			}
		}

		private void OnHurt()
		{
			if (!targetClaimed)
			{
				Play(hurtSound);
			}
		}

		private void OnDeathStart()
		{
			dead = true;
			deathFinished = false;
			despawnCommitted = false;
			deathTime = 0f;
			EnemyNavMeshAgent obj = agent;
			if (obj != null)
			{
				obj.Stop(0.5f);
			}
			StopLoops();
			Play(deathSound);
			Animator? obj2 = animator;
			if (obj2 != null)
			{
				obj2.SetTrigger(AnimatorDeath);
			}
		}

		private void OnDeath()
		{
			deathFinished = true;
			deathTime = 0f;
		}

		private void OnSpawn()
		{
			if (IsHost)
			{
				SemiFunc.EnemySpawn(enemy);
			}
		}

		private void Play(Sound? sound)
		{
			if (sound != null)
			{
				sound.Play(((Component)this).transform, 1f, 1f, 1f, 1f);
			}
		}

		private void StopLoops()
		{
			Sound? obj = ambientSound;
			if (obj != null)
			{
				obj.PlayLoop(false, 0.1f, 0.25f, 1f, 1f);
			}
			Sound? obj2 = captiveSound;
			if (obj2 != null)
			{
				obj2.PlayLoop(false, 0.1f, 0.25f, 1f, 1f);
			}
			ReleaseAudioIsolation();
		}

		private bool ValidateSetup()
		{
			string missing = string.Empty;
			AppendMissing((Object)(object)enemy == (Object)null, "Enemy");
			AppendMissing((Object)(object)agent == (Object)null, "EnemyNavMeshAgent");
			AppendMissing((Object)(object)health == (Object)null, "EnemyHealth");
			AppendMissing((Object)(object)vision == (Object)null, "EnemyVision");
			AppendMissing((Object)(object)spawnState == (Object)null, "EnemyStateSpawn");
			AppendMissing((Object)(object)despawnState == (Object)null, "EnemyStateDespawn");
			AppendMissing((Object)(object)stunnedState == (Object)null, "EnemyStateStunned");
			AppendMissing((Object)(object)bodyCollider == (Object)null, "body Collider");
			AppendMissing((Object)(object)photonView == (Object)null, "PhotonView");
			AppendMissing((Object)(object)visualRoot == (Object)null, "visual root");
			AppendMissing((Object)(object)((Component)this).GetComponentInChildren<EnemyStateChase>(true) == (Object)null, "EnemyStateChase marker");
			AppendMissing((Object)(object)health != (Object)null && health.onDeathStart == null, "EnemyHealth.onDeathStart");
			AppendMissing((Object)(object)health != (Object)null && health.onDeath == null, "EnemyHealth.onDeath");
			AppendMissing((Object)(object)health != (Object)null && health.onHurt == null, "EnemyHealth.onHurt");
			AppendMissing((Object)(object)spawnState != (Object)null && spawnState.OnSpawn == null, "EnemyStateSpawn.OnSpawn");
			AppendMissing(ambientSound == null || (Object)(object)ambientSound.Source == (Object)null, "ambient Sound.Source");
			AppendMissing(captiveSound == null || (Object)(object)captiveSound.Source == (Object)null, "captive Sound.Source");
			if (missing.Length == 0)
			{
				return true;
			}
			Debug.LogError((object)("[EchoStalker] Prefab setup is incomplete (" + missing + "). Disabling custom AI on '" + ((Object)this).name + "'."), (Object)(object)this);
			return false;
			void AppendMissing(bool condition, string item)
			{
				if (condition)
				{
					missing += ((missing.Length == 0) ? item : (", " + item));
				}
			}
		}

		private static bool IsTargetUsable(PlayerAvatar? player)
		{
			if ((Object)(object)player != (Object)null && !player.isDisabled && (Object)(object)player.playerTransform != (Object)null && (Object)(object)player.playerHealth != (Object)null)
			{
				return player.playerHealth.health > 0;
			}
			return false;
		}

		private void DisableVanillaStates<T>() where T : Behaviour
		{
			T[] componentsInChildren = ((Component)this).GetComponentsInChildren<T>(true);
			foreach (T val in componentsInChildren)
			{
				((Behaviour)val).enabled = false;
			}
		}

		private void CommitDespawn()
		{
			if (!despawnCommitted && IsHost)
			{
				despawnCommitted = true;
				despawnState.Despawn();
			}
		}
	}
	public sealed class FriendMonsterVisualAnimator : MonoBehaviour
	{
		private readonly struct JointPose
		{
			internal Transform Transform { get; }

			internal Quaternion Rotation { get; }

			internal JointPose(Transform transform)
			{
				//IL_0009: 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)
				Transform = transform;
				Rotation = transform.localRotation;
			}
		}

		private static readonly int MouthOpenProperty = Shader.PropertyToID("_MouthOpen");

		[SerializeField]
		private Enemy enemy;

		private readonly List<JointPose> fingers = new List<JointPose>();

		private Transform? rig;

		private Transform? torso;

		private Transform? head;

		private Transform? leftShoulder;

		private Transform? rightShoulder;

		private Transform? leftElbow;

		private Transform? rightElbow;

		private Transform? leftWrist;

		private Transform? rightWrist;

		private Transform? leftHip;

		private Transform? rightHip;

		private Transform? mouth;

		private Renderer? faceRenderer;

		private MaterialPropertyBlock? faceProperties;

		private Vector3 rigPosition;

		private Vector3 torsoPosition;

		private Vector3 headPosition;

		private Vector3 mouthScale;

		private Quaternion torsoRotation;

		private Quaternion headRotation;

		private Quaternion leftShoulderRotation;

		private Quaternion rightShoulderRotation;

		private Quaternion leftElbowRotation;

		private Quaternion rightElbowRotation;

		private Quaternion leftWristRotation;

		private Quaternion rightWristRotation;

		private Quaternion leftHipRotation;

		private Quaternion rightHipRotation;

		private float phaseOffset;

		private float renderedMouthOpen;

		private bool ready;

		private void Awake()
		{
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			if (enemy == null)
			{
				enemy = ((Component)this).GetComponentInParent<Enemy>();
			}
			rig = FindDescendant("Friend Rig");
			torso = FindDescendant("Torso Pivot");
			head = FindDescendant("Head Pivot");
			leftShoulder = FindDescendant("Left Shoulder Pivot");
			rightShoulder = FindDescendant("Right Shoulder Pivot");
			leftElbow = FindDescendant("Left Elbow Pivot");
			rightElbow = FindDescendant("Right Elbow Pivot");
			leftWrist = FindDescendant("Left Wrist Pivot");
			rightWrist = FindDescendant("Right Wrist Pivot");
			leftHip = FindDescendant("Left Hip Pivot");
			rightHip = FindDescendant("Right Hip Pivot");
			mouth = FindDescendant("Mouth");
			Transform? obj = FindDescendant("Friend Face Decal");
			faceRenderer = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null);
			faceProperties = ((!((Object)(object)faceRenderer != (Object)null)) ? ((MaterialPropertyBlock)null) : new MaterialPropertyBlock());
			ready = (Object)(object)enemy != (Object)null && (Object)(object)rig != (Object)null && (Object)(object)torso != (Object)null && (Object)(object)head != (Object)null && (Object)(object)leftShoulder != (Object)null && (Object)(object)rightShoulder != (Object)null && (Object)(object)leftElbow != (Object)null && (Object)(object)rightElbow != (Object)null && (Object)(object)leftWrist != (Object)null && (Object)(object)rightWrist != (Object)null && (Object)(object)leftHip != (Object)null && (Object)(object)rightHip != (Object)null && (Object)(object)mouth != (Object)null;
			if (!ready)
			{
				((Behaviour)this).enabled = false;
				return;
			}
			rigPosition = rig.localPosition;
			torsoPosition = torso.localPosition;
			headPosition = head.localPosition;
			mouthScale = mouth.localScale;
			torsoRotation = torso.localRotation;
			headRotation = head.localRotation;
			leftShoulderRotation = leftShoulder.localRotation;
			rightShoulderRotation = rightShoulder.localRotation;
			leftElbowRotation = leftElbow.localRotation;
			rightElbowRotation = rightElbow.localRotation;
			leftWristRotation = leftWrist.localRotation;
			rightWristRotation = rightWrist.localRotation;
			leftHipRotation = leftHip.localRotation;
			rightHipRotation = rightHip.localRotation;
			phaseOffset = (float)(((Object)this).GetInstanceID() & 0xFF) * (1f / 32f);
			Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name.StartsWith("Finger ", StringComparison.Ordinal) || ((Object)val).name == "Thumb")
				{
					fingers.Add(new JointPose(val));
				}
			}
		}

		private void Update()
		{
			//IL_000f: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected I4, but got Unknown
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_0532: Unknown result type (might be due to invalid IL or missing references)
			//IL_0545: Unknown result type (might be due to invalid IL or missing references)
			//IL_055f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Unknown result type (might be due to invalid IL or missing references)
			//IL_058c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_062d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0662: Unknown result type (might be due to invalid IL or missing references)
			//IL_0669: Unknown result type (might be due to invalid IL or missing references)
			//IL_0674: Unknown result type (might be due to invalid IL or missing references)
			//IL_0676: Invalid comparison between Unknown and I4
			if (ready)
			{
				EnemyState currentState = enemy.CurrentState;
				float num = Time.time + phaseOffset;
				float num2 = 0f;
				float num3 = 0f;
				float num4 = 0f;
				float num5 = 0f;
				float num6 = 0f;
				float num7 = 0f;
				float num8 = 0f;
				float num9 = 0f;
				float num10 = 0f;
				float num11 = 0f;
				float num12 = 4f;
				float num13 = 0f;
				float num14 = 10f;
				switch (currentState - 2)
				{
				case 0:
					num2 = num * 2.4f;
					num3 = Mathf.Abs(Mathf.Sin(num2)) * 0.035f;
					num8 = 15f;
					num11 = 5f;
					num12 = 7f;
					num13 = 0.08f;
					num14 = 6f;
					break;
				case 1:
					num2 = num * 5f;
					num4 = -0.18f;
					num5 = -16f;
					num6 = 12f;
					num7 = -28f;
					num9 = 12f;
					num10 = -18f;
					num11 = 12f;
					num12 = 2f;
					num13 = 0.35f;
					num14 = 13f;
					break;
				case 2:
					num2 = num * 9.5f;
					num3 = Mathf.Abs(Mathf.Sin(num2)) * 0.09f;
					num5 = -13f;
					num6 = 9f;
					num7 = -8f;
					num8 = 54f;
					num9 = 8f;
					num10 = -24f;
					num11 = 24f;
					num12 = 16f + Mathf.Sin(num2 * 1.7f) * 13f;
					num13 = 0.35f + Mathf.Abs(Mathf.Sin(num2 * 0.55f)) * 0.35f;
					num14 = 18f;
					break;
				case 3:
					num2 = num * 8f;
					num4 = -0.12f;
					num5 = -20f;
					num6 = 14f;
					num7 = -72f;
					num9 = 10f;
					num10 = -22f;
					num11 = 18f;
					num12 = 8f + Mathf.Sin(num2) * 7f;
					num13 = 0.65f;
					num14 = 20f;
					break;
				case 4:
					num2 = num * 7.5f;
					num4 = -0.42f;
					num3 = Mathf.Sin(num2 * 0.5f) * 0.025f;
					num5 = -7f + Mathf.Sin(num2 * 0.45f) * 5f;
					num6 = Mathf.Sin(num2 * 0.65f) * 8f;
					num7 = -48f;
					num8 = 20f;
					num9 = 28f;
					num10 = -48f;
					num11 = 38f;
					num12 = 18f + Mathf.Sin(num2 * 1.6f) * 17f;
					num13 = SpeechEnvelope(num);
					num14 = 16f;
					break;
				case 7:
					num4 = -0.28f;
					num5 = 24f;
					num6 = -20f;
					num7 = 25f;
					num10 = 18f;
					num12 = 32f;
					num14 = 9f;
					break;
				}
				float num15 = Mathf.Sin(num2);
				float num16 = Mathf.Sin(num2 + MathF.PI);
				float num17 = Mathf.Sin(num2 * 1.9f);
				float num18 = 1f - Mathf.Exp((0f - num14) * Time.deltaTime);
				rig.localPosition = Vector3.Lerp(rig.localPosition, rigPosition + Vector3.up * (num4 + num3), num18);
				torso.localPosition = Vector3.Lerp(torso.localPosition, torsoPosition + Vector3.up * (num3 * 0.25f), num18);
				head.localPosition = Vector3.Lerp(head.localPosition, headPosition + new Vector3(num17 * 0.012f, num3 * 0.4f, 0f), num18);
				Rotate(torso, torsoRotation, new Vector3(num5, 0f, num17 * 2.5f), num18);
				Rotate(head, headRotation, new Vector3(num6, num17 * 4f, (0f - num17) * 2f), num18);
				Rotate(leftShoulder, leftShoulderRotation, new Vector3(num7 + num15 * num8, 0f, num9), num18);
				Rotate(rightShoulder, rightShoulderRotation, new Vector3(num7 + num16 * num8, 0f, 0f - num9), num18);
				Rotate(leftElbow, leftElbowRotation, new Vector3(num10 - num16 * 12f, 0f, 0f), num18);
				Rotate(rightElbow, rightElbowRotation, new Vector3(num10 - num15 * 12f, 0f, 0f), num18);
				Rotate(leftWrist, leftWristRotation, new Vector3(num17 * num11, (0f - num15) * num11 * 0.5f, num15 * num11), num18);
				Rotate(rightWrist, rightWristRotation, new Vector3((0f - num17) * num11, (0f - num16) * num11 * 0.5f, num16 * num11), num18);
				Rotate(leftHip, leftHipRotation, new Vector3(num16 * num8 * 0.55f, 0f, 0f), num18);
				Rotate(rightHip, rightHipRotation, new Vector3(num15 * num8 * 0.55f, 0f, 0f), num18);
				for (int i = 0; i < fingers.Count; i++)
				{
					JointPose jointPose = fingers[i];
					float num19 = Mathf.Sin(num2 * 1.35f + (float)i * 0.73f) * 8f;
					jointPose.Transform.localRotation = Quaternion.Slerp(jointPose.Transform.localRotation, jointPose.Rotation * Quaternion.Euler(num12 + num19, 0f, 0f), num18);
				}
				mouth.localScale = Vector3.Lerp(mouth.localScale, new Vector3(mouthScale.x, mouthScale.y * (1f + num13 * 2.2f), mouthScale.z), num18);
				UpdateFaceMouth(((int)currentState == 6) ? num13 : 0f, num18);
			}
		}

		private void OnDisable()
		{
			UpdateFaceMouth(0f, 1f);
		}

		private static float SpeechEnvelope(float phase)
		{
			float num = Mathf.Abs(Mathf.Sin(phase * 10.7f + Mathf.Sin(phase * 2.3f) * 1.4f));
			float num2 = 0.38f + Mathf.Abs(Mathf.Sin(phase * 1.37f + 0.4f)) * 0.62f;
			return Mathf.Clamp01((num - 0.16f) * 1.3f * num2);
		}

		private void UpdateFaceMouth(float target, float blend)
		{
			if (!((Object)(object)faceRenderer == (Object)null) && faceProperties != null)
			{
				renderedMouthOpen = Mathf.Lerp(renderedMouthOpen, target, blend);
				faceRenderer.GetPropertyBlock(faceProperties);
				faceProperties.SetFloat(MouthOpenProperty, renderedMouthOpen);
				faceRenderer.SetPropertyBlock(faceProperties);
			}
		}

		private static void Rotate(Transform? joint, Quaternion rest, Vector3 euler, float blend)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)joint == (Object)null))
			{
				joint.localRotation = Quaternion.Slerp(joint.localRotation, rest * Quaternion.Euler(euler), blend);
			}
		}

		private Transform? FindDescendant(string targetName)
		{
			Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name == targetName)
				{
					return val;
				}
			}
			return null;
		}
	}
}