Decompiled source of SCP682 v1.0.1

plugins/SCP682/ProjectSCP.SCP682.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
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 GameNetcodeStuff;
using IL;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using MonoMod.Cil;
using On;
using ProjectSCP.SCP682.NetcodePatcher;
using SCP682.Configuration;
using SCP682.Hooks;
using SCP682.SCPEnemy;
using SCP682.SCPEnemy.DoorBreak;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ProjectSCP.SCP682")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+743dd18b12e870911f281ec57f41e474533878c1")]
[assembly: AssemblyProduct("SCP682")]
[assembly: AssemblyTitle("ProjectSCP.SCP682")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SCP682
{
	internal static class AddEnemyScript
	{
		internal static void SCP682AI(EnemyType enemyType, AssetBundle assets)
		{
			GameObject enemyPrefab = enemyType.enemyPrefab;
			SCP682AI sCP682AI = enemyPrefab.AddComponent<SCP682AI>();
			((EnemyAI)sCP682AI).enemyType = enemyType;
			((EnemyAI)sCP682AI).creatureAnimator = enemyPrefab.GetComponentInChildren<Animator>();
			((EnemyAI)sCP682AI).creatureVoice = ((Component)enemyPrefab.transform.Find("ModelRoot/CrocodileModel/CG/Pelvis/CreatureVoice")).GetComponent<AudioSource>();
			((EnemyAI)sCP682AI).creatureSFX = ((Component)enemyPrefab.transform.Find("CreatureSFX")).GetComponent<AudioSource>();
			((EnemyAI)sCP682AI).eye = enemyPrefab.transform.Find("Eye");
			((EnemyAI)sCP682AI).dieSFX = assets.LoadAsset<AudioClip>("SkibidiDeath");
			((EnemyAI)sCP682AI).enemyBehaviourStates = (EnemyBehaviourState[])(object)new EnemyBehaviourState[20];
			((EnemyAI)sCP682AI).AIIntervalTime = 0.2f;
			((EnemyAI)sCP682AI).agent = enemyPrefab.GetComponent<NavMeshAgent>();
			((EnemyAI)sCP682AI).updatePositionThreshold = 0.1f;
			((EnemyAI)sCP682AI).syncMovementSpeed = 0.22f;
			((EnemyAI)sCP682AI).enemyHP = 18;
			EnemyAICollisionDetect componentInChildren = enemyPrefab.GetComponentInChildren<EnemyAICollisionDetect>();
			componentInChildren.mainScript = (EnemyAI)(object)sCP682AI;
			DoorDestroyerCollider doorDestroyerCollider = ((Component)componentInChildren).gameObject.AddComponent<DoorDestroyerCollider>();
			doorDestroyerCollider.AI = sCP682AI;
		}

		internal static void RemoveComponent<T>(this GameObject gameObject) where T : Component
		{
			T component = gameObject.GetComponent<T>();
			Object.Destroy((Object)(object)component);
		}
	}
	[BepInPlugin("ProjectSCP.SCP682", "SCP682", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		public static AssetBundle? modAssets;

		internal static EnemyType SCP682ET;

		internal static PluginConfig BoundConfig { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Stopwatch stopwatch = Stopwatch.StartNew();
			Logger.LogInfo((object)"Plugin ProjectSCP.SCP682 1.0.1 started loading...");
			BoundConfig = new PluginConfig(((BaseUnityPlugin)this).Config);
			InitializeNetworkBehaviours();
			string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "SCP682Assets");
			modAssets = AssetBundle.LoadFromFile(Path.Combine(path, "scp682assets"));
			if (modAssets == null)
			{
				Logger.LogError((object)"Failed to load custom assets.");
				return;
			}
			SFX.InitializeSFX(modAssets);
			SCP682ET = modAssets.LoadAsset<EnemyType>("SCP682ET");
			TerminalNode val = modAssets.LoadAsset<TerminalNode>("SCP682TN");
			AssetBundle val2 = AssetBundle.LoadFromFile(Path.Combine(path, "scp682videobundle"));
			VideoClip displayVideo = val2.LoadAsset<VideoClip>("SCP682Spin");
			val.displayVideo = displayVideo;
			AddEnemyScript.SCP682AI(SCP682ET, modAssets);
			NetworkPrefabs.RegisterNetworkPrefab(SCP682ET.enemyPrefab);
			Enemies.RegisterEnemy(SCP682ET, 20, (LevelTypes)(-1), val, (TerminalKeyword)null);
			JesterListHook.Init();
			ApparatusTakenHook.Init();
			CaveDwellerList.Init();
			stopwatch.Stop();
			Logger.LogInfo((object)string.Format("{0} loaded in {1}ms!", "ProjectSCP.SCP682", stopwatch.ElapsedMilliseconds));
		}

		private static void InitializeNetworkBehaviours()
		{
			Type[] array;
			try
			{
				array = Assembly.GetExecutingAssembly().GetTypes();
			}
			catch (ReflectionTypeLoadException ex)
			{
				array = ex.Types.Where((Type t) => t != null).ToArray();
			}
			Type[] array2 = array;
			foreach (Type type in array2)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array3 = methods;
				foreach (MethodInfo methodInfo in array3)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	internal static class PLog
	{
		internal static void Log(object data)
		{
			Plugin.Logger.LogInfo(data);
		}

		internal static void LogWarning(object data)
		{
			Plugin.Logger.LogWarning(data);
		}

		internal static void LogError(object data)
		{
			Plugin.Logger.LogError(data);
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ProjectSCP.SCP682";

		public const string PLUGIN_NAME = "SCP682";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace SCP682.Hooks
{
	internal static class ApparatusTakenHook
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_DisconnectFromMachinery <0>__LungProp_DisconnectFromMachinery;

			public static Manipulator <1>__LungProp_EquipItem;
		}

		internal static void Init()
		{
			//IL_0010: 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_001b: Expected O, but got Unknown
			//IL_0030: 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_003b: Expected O, but got Unknown
			object obj = <>O.<0>__LungProp_DisconnectFromMachinery;
			if (obj == null)
			{
				hook_DisconnectFromMachinery val = LungProp_DisconnectFromMachinery;
				<>O.<0>__LungProp_DisconnectFromMachinery = val;
				obj = (object)val;
			}
			LungProp.DisconnectFromMachinery += (hook_DisconnectFromMachinery)obj;
			object obj2 = <>O.<1>__LungProp_EquipItem;
			if (obj2 == null)
			{
				Manipulator val2 = LungProp_EquipItem;
				<>O.<1>__LungProp_EquipItem = val2;
				obj2 = (object)val2;
			}
			LungProp.EquipItem += (Manipulator)obj2;
		}

		private static void LungProp_EquipItem(ILContext il)
		{
		}

		private static IEnumerator LungProp_DisconnectFromMachinery(orig_DisconnectFromMachinery orig, LungProp self)
		{
			IEnumerator origIEnumerator = orig.Invoke(self);
			while (origIEnumerator.MoveNext())
			{
				yield return origIEnumerator.Current;
			}
			if (Random.Range(0, 2) == 0)
			{
				SpawnSCP682(outside: true);
			}
			else
			{
				SpawnSCP682(outside: false);
			}
		}

		internal static void SpawnSCP682(bool outside)
		{
			//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)
			//IL_0099: 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_00a7: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkManager.Singleton.IsHost && Plugin.SCP682ET.numberSpawned <= 0)
			{
				RoundManager instance = RoundManager.Instance;
				GameObject[] array;
				if (outside)
				{
					array = GameObject.FindGameObjectsWithTag("OutsideAINode");
					instance.currentOutsideEnemyPower += Plugin.SCP682ET.PowerLevel;
				}
				else
				{
					array = GameObject.FindGameObjectsWithTag("AINode");
					instance.currentEnemyPower += Plugin.SCP682ET.PowerLevel;
				}
				EnemyType sCP682ET = Plugin.SCP682ET;
				sCP682ET.numberSpawned++;
				Vector3 position = array[instance.AnomalyRandom.Next(0, array.Length)].transform.position;
				position = instance.GetRandomNavMeshPositionInBoxPredictable(position, 10f, default(NavMeshHit), instance.AnomalyRandom, instance.GetLayermaskForEnemySizeLimit(Plugin.SCP682ET));
				position = instance.PositionWithDenialPointsChecked(position, array, Plugin.SCP682ET);
				NetworkObjectReference val = instance.SpawnEnemyGameObject(position, 0f, 1, Plugin.SCP682ET);
				NetworkObject val2 = default(NetworkObject);
				if (!((NetworkObjectReference)(ref val)).TryGet(ref val2, (NetworkManager)null))
				{
					Plugin.Logger.LogError((object)"Couldn't get network object for spawned enemy!");
					return;
				}
				SCP682AI component = ((Component)val2).GetComponent<SCP682AI>();
				((EnemyAI)component).enemyType.isOutsideEnemy = outside;
			}
		}
	}
	internal static class CaveDwellerList
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Start <0>__CaveDwellerAI_Start;
		}

		public static List<CaveDwellerAI?> caveDwellerEnemies = new List<CaveDwellerAI>();

		internal static void Init()
		{
			//IL_0010: 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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__CaveDwellerAI_Start;
			if (obj == null)
			{
				hook_Start val = CaveDwellerAI_Start;
				<>O.<0>__CaveDwellerAI_Start = val;
				obj = (object)val;
			}
			CaveDwellerAI.Start += (hook_Start)obj;
		}

		private static void CaveDwellerAI_Start(orig_Start orig, CaveDwellerAI self)
		{
			orig.Invoke(self);
			caveDwellerEnemies.Add(self);
		}

		public static IEnumerable<CaveDwellerAI> GetBabyCaveDwellers()
		{
			for (int i = 0; i < caveDwellerEnemies.Count; i++)
			{
				CaveDwellerAI val = caveDwellerEnemies[i];
				if ((Object)(object)val == (Object)null || ((EnemyAI)val).currentBehaviourStateIndex != 0)
				{
					caveDwellerEnemies.RemoveAt(i);
					i--;
				}
				else
				{
					yield return val;
				}
			}
		}
	}
	internal static class JesterListHook
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Start <0>__JesterAI_Start;
		}

		public static List<JesterAI?> jesterEnemies = new List<JesterAI>();

		internal static void Init()
		{
			//IL_0010: 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_001b: Expected O, but got Unknown
			object obj = <>O.<0>__JesterAI_Start;
			if (obj == null)
			{
				hook_Start val = JesterAI_Start;
				<>O.<0>__JesterAI_Start = val;
				obj = (object)val;
			}
			JesterAI.Start += (hook_Start)obj;
		}

		private static void JesterAI_Start(orig_Start orig, JesterAI self)
		{
			orig.Invoke(self);
			jesterEnemies.Add(self);
		}

		public static IEnumerable<JesterAI> GetJesters()
		{
			for (int i = 0; i < jesterEnemies.Count; i++)
			{
				JesterAI val = jesterEnemies[i];
				if ((Object)(object)val == (Object)null)
				{
					jesterEnemies.RemoveAt(i);
					i--;
				}
				else
				{
					yield return val;
				}
			}
		}
	}
}
namespace SCP682.SCPEnemy
{
	public abstract class ModEnemyAI<T> : ModEnemyAINetworkLayer where T : ModEnemyAI<T>
	{
		public abstract class AIBehaviorState : AIBase
		{
			public abstract List<AIStateTransition> Transitions { get; set; }

			public abstract IEnumerator OnStateEntered();

			public virtual void Update()
			{
			}

			public virtual void LateUpdate()
			{
			}

			public virtual void AIInterval()
			{
			}

			public virtual void OnCollideWithPlayer(Collider other)
			{
			}

			public virtual void OnCollideWithEnemy(Collider other, EnemyAI? collidedEnemy)
			{
			}

			public abstract IEnumerator OnStateExit();
		}

		public abstract class AIStateTransition : AIBase
		{
			public abstract bool CanTransitionBeTaken();

			public virtual void AIInterval()
			{
			}

			public abstract AIBehaviorState NextState();

			public virtual void OnCollideWithPlayer(Collider other)
			{
			}
		}

		public abstract class AIBase
		{
			public T self;

			public NavMeshAgent Agent => ((EnemyAI)self).agent;

			public PlayerControllerB? TargetPlayer
			{
				get
				{
					return self.targetPlayer;
				}
				set
				{
					self.targetPlayer = value;
				}
			}

			public Random EnemyRandom => self.enemyRandom;

			public Animator CreatureAnimator => ((EnemyAI)self).creatureAnimator;

			public AudioSource CreatureSFX => ((EnemyAI)self).creatureSFX;

			public AudioSource CreatureVoice => ((EnemyAI)self).creatureVoice;
		}

		private class TransitionType
		{
			internal readonly Type type;

			internal readonly bool isTransition;

			public TransitionType(Type type, bool isTransition)
			{
				this.type = type;
				this.isTransition = isTransition;
				base..ctor();
			}
		}

		public enum PlayerState
		{
			Dead,
			Outside,
			Inside,
			Ship
		}

		private static readonly Dictionary<(string, Type), TransitionType> _typeNameAndInstanceTypeToTransitionType = new Dictionary<(string, Type), TransitionType>();

		internal AIBehaviorState activeState;

		internal Type? previousStateType;

		internal Random enemyRandom;

		internal float AITimer;

		internal bool printDebugs;

		internal PlayerState myValidState = PlayerState.Inside;

		internal AIStateTransition nextTransition;

		internal List<AIStateTransition> globalTransitions = new List<AIStateTransition>();

		internal T self;

		private PlayerControllerB? _lastSyncedTargetPlayer;

		public PlayerControllerB? targetPlayer
		{
			get
			{
				if (((NetworkBehaviour)this).IsOwner && (Object)(object)((EnemyAI)this).targetPlayer != (Object)(object)_lastSyncedTargetPlayer)
				{
					if (((EnemyAI)this).targetPlayer != null)
					{
						SetTargetServerRpc((int)((EnemyAI)this).targetPlayer.actualClientId);
					}
					else
					{
						SetTargetServerRpc(-1);
					}
				}
				return ((EnemyAI)this).targetPlayer;
			}
			set
			{
				if (!((Object)(object)value == (Object)(object)_lastSyncedTargetPlayer) || !((Object)(object)_lastSyncedTargetPlayer == (Object)(object)((EnemyAI)this).targetPlayer))
				{
					if (value != null)
					{
						SetTargetServerRpc((int)value.actualClientId);
					}
					else
					{
						SetTargetServerRpc(-1);
					}
				}
			}
		}

		internal abstract T GetThis();

		internal abstract AIBehaviorState GetInitialState();

		public override string __getTypeName()
		{
			return ((object)this).GetType().Name;
		}

		public override void Start()
		{
			self = GetThis();
			activeState = GetInitialState();
			enemyRandom = new Random(StartOfRound.Instance.randomMapSeed + ((EnemyAI)this).thisEnemyIndex);
			myValidState = (((EnemyAI)this).enemyType.isOutsideEnemy ? PlayerState.Outside : PlayerState.Inside);
			((EnemyAI)this).creatureAnimator.Rebind();
			((EnemyAI)this).Start();
			if (!((EnemyAI)this).agent.isOnNavMesh && ((NetworkBehaviour)this).IsOwner)
			{
				DebugLog("CREATURE " + ((NetworkBehaviour)this).__getTypeName() + " WAS NOT PLACED ON NAVMESH, DESTROYING...");
				((EnemyAI)this).KillEnemyOnOwnerClient(false);
			}
			_transitionCoroutineInProgress = ((MonoBehaviour)this).StartCoroutine(InitializeAndEnterState(activeState, self, enemyRandom));
		}

		public override void Update()
		{
			if (((EnemyAI)this).isEnemyDead)
			{
				return;
			}
			((EnemyAI)this).Update();
			AITimer += Time.deltaTime;
			if (((NetworkBehaviour)this).IsOwner)
			{
				if (_transitionCoroutineInProgress != null)
				{
					return;
				}
				foreach (AIStateTransition allTransition in GetAllTransitions())
				{
					if (allTransition.CanTransitionBeTaken() && ((NetworkBehaviour)this).IsOwner)
					{
						nextTransition = allTransition;
						TransitionStateServerRpc(nextTransition.ToString(), enemyRandom.Next());
						return;
					}
				}
			}
			activeState.Update();
		}

		internal void LateUpdate()
		{
			if (_transitionCoroutineInProgress == null)
			{
				activeState.LateUpdate();
			}
		}

		public override void DoAIInterval()
		{
			((EnemyAI)this).DoAIInterval();
			if (_transitionCoroutineInProgress != null)
			{
				return;
			}
			foreach (AIStateTransition allTransition in GetAllTransitions())
			{
				allTransition.AIInterval();
			}
			activeState.AIInterval();
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			((EnemyAI)this).OnCollideWithPlayer(other);
			activeState.OnCollideWithPlayer(other);
			foreach (AIStateTransition allTransition in GetAllTransitions())
			{
				allTransition.OnCollideWithPlayer(other);
			}
		}

		public override void OnCollideWithEnemy(Collider other, EnemyAI? collidedEnemy = null)
		{
			((EnemyAI)this).OnCollideWithEnemy(other, collidedEnemy);
			activeState.OnCollideWithEnemy(other, collidedEnemy);
		}

		private IEnumerable<AIStateTransition> GetAllTransitions()
		{
			foreach (AIStateTransition globalTransition in globalTransitions)
			{
				InitializeStateTransition(globalTransition, self);
				yield return globalTransition;
			}
			foreach (AIStateTransition transition in activeState.Transitions)
			{
				InitializeStateTransition(transition, self);
				yield return transition;
			}
		}

		private IEnumerator InitializeAndEnterState(AIBehaviorState activeState, T self, Random enemyRandom)
		{
			activeState.self = self;
			yield return ((MonoBehaviour)this).StartCoroutine(activeState.OnStateEntered());
			_transitionCoroutineInProgress = null;
		}

		private void InitializeStateTransition(AIStateTransition transition, T self)
		{
			transition.self = self;
		}

		internal void DebugLog(object data)
		{
			if (printDebugs)
			{
				PLog.Log(data);
			}
		}

		internal void OverrideState(AIBehaviorState state)
		{
			if (!((EnemyAI)this).isEnemyDead)
			{
				TransitionStateServerRpc(state.ToString(), enemyRandom.Next());
			}
		}

		internal override IEnumerator TransitionState(string stateOrTransitionName, int randomSeed)
		{
			AIStateTransition localNextTransition = null;
			if (!_typeNameAndInstanceTypeToTransitionType.TryGetValue((stateOrTransitionName, ((object)self).GetType()), out TransitionType transitionOrBehavior))
			{
				ValidateAndCacheTransitionType(stateOrTransitionName, ref transitionOrBehavior);
			}
			if (transitionOrBehavior.isTransition)
			{
				localNextTransition = (AIStateTransition)Activator.CreateInstance(transitionOrBehavior.type);
				InitializeStateTransition(localNextTransition, self);
				if (localNextTransition.NextState().GetType() == activeState.GetType())
				{
					yield break;
				}
			}
			DebugLog($"{((NetworkBehaviour)this).__getTypeName()} #{((EnemyAI)self).thisEnemyIndex} is Exiting:  {activeState}");
			yield return ((MonoBehaviour)this).StartCoroutine(activeState.OnStateExit());
			Type type = activeState.GetType();
			if (localNextTransition != null)
			{
				DebugLog($"{((NetworkBehaviour)this).__getTypeName()} #{((EnemyAI)self).thisEnemyIndex} is Transitioning via:  {localNextTransition}");
				activeState = localNextTransition.NextState();
			}
			else
			{
				DebugLog($"{((NetworkBehaviour)this).__getTypeName()} #{((EnemyAI)self).thisEnemyIndex} is Transitioning via: State Override");
				activeState = (AIBehaviorState)Activator.CreateInstance(transitionOrBehavior.type);
			}
			previousStateType = type;
			DebugLog($"{((NetworkBehaviour)this).__getTypeName()} #{((EnemyAI)self).thisEnemyIndex} is Entering:  {activeState}");
			((MonoBehaviour)this).StartCoroutine(InitializeAndEnterState(activeState, self, new Random(randomSeed)));
			StartOfRound.Instance.ClientPlayerList.TryGetValue(NetworkManager.Singleton.LocalClientId, out var value);
			DebugLog($"CREATURE: {((Object)((EnemyAI)this).enemyType).name} #{((EnemyAI)self).thisEnemyIndex} STATE: {activeState} ON PLAYER: #{value} ({StartOfRound.Instance.allPlayerScripts[value].playerUsername})");
		}

		private void ValidateAndCacheTransitionType(string stateOrTransitionName, [NotNull] ref TransitionType? transitionOrBehavior)
		{
			Type type = Type.GetType(stateOrTransitionName) ?? throw new ArgumentException("'" + stateOrTransitionName + "' wasn't found as a type!", "stateOrTransitionName");
			if (type.IsSubclassOf(typeof(AIStateTransition)))
			{
				transitionOrBehavior = new TransitionType(type, isTransition: true);
				_typeNameAndInstanceTypeToTransitionType.Add((stateOrTransitionName, ((object)self).GetType()), transitionOrBehavior);
				return;
			}
			if (type.IsSubclassOf(typeof(AIBehaviorState)))
			{
				transitionOrBehavior = new TransitionType(type, isTransition: false);
				_typeNameAndInstanceTypeToTransitionType.Add((stateOrTransitionName, ((object)self).GetType()), transitionOrBehavior);
				return;
			}
			throw new ArgumentException("'" + stateOrTransitionName + "' is neither an AIStateTransition nor an AIBehaviorState!", "stateOrTransitionName");
		}

		protected override void SetTarget(int PlayerID)
		{
			if (PlayerID == -1)
			{
				((EnemyAI)this).targetPlayer = null;
				_lastSyncedTargetPlayer = null;
				DebugLog($"Clearing target on {this}");
			}
			else if ((Object)(object)StartOfRound.Instance.allPlayerScripts[PlayerID] == (Object)null)
			{
				DebugLog($"Index invalid! {this}");
			}
			else
			{
				((EnemyAI)this).targetPlayer = StartOfRound.Instance.allPlayerScripts[PlayerID];
				_lastSyncedTargetPlayer = ((EnemyAI)this).targetPlayer;
				DebugLog($"{this} setting target to: {((EnemyAI)this).targetPlayer.playerUsername}");
			}
		}

		internal AIBehaviorState? CreatePreviousState()
		{
			if ((object)previousStateType == null)
			{
				return null;
			}
			return (AIBehaviorState)Activator.CreateInstance(previousStateType);
		}

		internal bool AnimationIsFinished(string AnimName, int layerIndex)
		{
			//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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			AnimatorStateInfo currentAnimatorStateInfo = ((EnemyAI)this).creatureAnimator.GetCurrentAnimatorStateInfo(layerIndex);
			if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName(AnimName))
			{
				DebugLog(((NetworkBehaviour)this).__getTypeName() + ": Checking for animation " + AnimName + ", but current animation is " + ((Object)((AnimatorClipInfo)(ref ((EnemyAI)this).creatureAnimator.GetCurrentAnimatorClipInfo(layerIndex)[0])).clip).name);
				return true;
			}
			currentAnimatorStateInfo = ((EnemyAI)this).creatureAnimator.GetCurrentAnimatorStateInfo(layerIndex);
			return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime >= 1f;
		}

		internal bool PlayerCanBeTargeted(PlayerControllerB myPlayer)
		{
			return GetPlayerState(myPlayer) == myValidState;
		}

		internal PlayerState GetPlayerState(PlayerControllerB myPlayer)
		{
			if (myPlayer.isPlayerDead)
			{
				return PlayerState.Dead;
			}
			if (myPlayer.isInsideFactory)
			{
				return PlayerState.Inside;
			}
			if (myPlayer.isInHangarShipRoom)
			{
				return PlayerState.Ship;
			}
			return PlayerState.Outside;
		}

		internal void MoveTimerValue(ref float Timer, bool ShouldRaise = false)
		{
			if (ShouldRaise)
			{
				Timer += Time.deltaTime;
			}
			else if (!(Timer <= 0f))
			{
				Timer -= Time.deltaTime;
			}
		}

		public IEnumerable<PlayerControllerB> AllPlayers()
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (!val.isPlayerDead && val.isPlayerControlled)
				{
					yield return val;
				}
			}
		}

		public PlayerControllerB? IsAnyPlayerWithinLOS(int range = 45, float width = 60f, int proximityAwareness = -1, bool DoLinecast = true, bool PrintResults = false, bool SortByDistance = false)
		{
			//IL_004c: 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)
			float num = range;
			PlayerControllerB result = null;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (!val.isPlayerDead && val.isPlayerControlled && IsTargetPlayerWithinLOS(val, range, width, proximityAwareness, DoLinecast, PrintResults))
				{
					if (!SortByDistance)
					{
						return val;
					}
					float num2 = Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position);
					if (num2 < num)
					{
						num = num2;
						result = val;
					}
				}
			}
			return result;
		}

		public bool IsTargetPlayerWithinLOS(PlayerControllerB player, int range = 45, float width = 60f, int proximityAwareness = -1, bool DoLinecast = true, bool PrintResults = false)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_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_007e: 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)
			float num = Vector3.Distance(((Component)this).transform.position, ((Component)player.gameplayCamera).transform.position);
			bool flag = num < (float)range;
			float num2 = Vector3.Angle(((Component)((EnemyAI)this).eye).transform.forward, ((Component)player.gameplayCamera).transform.position - ((Component)((EnemyAI)this).eye).transform.position);
			bool flag2 = num2 < width;
			bool flag3 = num < (float)proximityAwareness;
			bool flag4 = DoLinecast && Physics.Linecast(((Component)((EnemyAI)this).eye).transform.position, ((Component)player).transform.position, StartOfRound.Instance.collidersRoomDefaultAndFoliage, (QueryTriggerInteraction)1);
			if (PrintResults)
			{
				DebugLog($"Target in Distance: {flag} ({num})" + $"Target within view cone: {flag2} ({num2})" + $"LOSBlocked: {flag4}");
			}
			if (!(flag && flag2))
			{
				if (flag3)
				{
					return !flag4;
				}
				return false;
			}
			return true;
		}

		public bool IsTargetPlayerWithinLOS(int range = 45, float width = 60f, int proximityAwareness = -1, bool DoLinecast = true, bool PrintResults = false)
		{
			if ((Object)(object)targetPlayer == (Object)null)
			{
				DebugLog(((NetworkBehaviour)this).__getTypeName() + " called Target Player LOS check called with null target player; returning false!");
				return false;
			}
			return IsTargetPlayerWithinLOS(targetPlayer, range, width, proximityAwareness, DoLinecast, PrintResults);
		}

		public PlayerControllerB FindNearestPlayer(bool ValidateNav = false)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB val = null;
			float num = 20000f;
			for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
			{
				PlayerControllerB val2 = StartOfRound.Instance.allPlayerScripts[i];
				if (!ValidateNav || ((EnemyAI)this).agent.CalculatePath(((Component)val2).transform.position, ((EnemyAI)this).path1))
				{
					float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position);
					if (num2 < num)
					{
						val = val2;
						num = num2;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				DebugLog("There is somehow no closest player. get fucked");
				return null;
			}
			return val;
		}

		internal bool IsPlayerReachable()
		{
			if ((Object)(object)targetPlayer == (Object)null)
			{
				PLog.LogError("Player Reach Test has no target player or passed in argument!");
				return false;
			}
			return IsPlayerReachable(targetPlayer);
		}

		internal bool IsPlayerReachable(PlayerControllerB? playerToCheck)
		{
			//IL_0010: 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_0025: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Invalid comparison between Unknown and I4
			if (playerToCheck == null)
			{
				return false;
			}
			Vector3 navMeshPosition = RoundManager.Instance.GetNavMeshPosition(((Component)playerToCheck).transform.position, RoundManager.Instance.navHit, 2.7f, -1);
			if (!RoundManager.Instance.GotNavMeshPositionResult)
			{
				DebugLog("Player Reach Test: No NavMesh position");
				return false;
			}
			((EnemyAI)this).agent.CalculatePath(navMeshPosition, ((EnemyAI)this).agent.path);
			bool flag = (int)((EnemyAI)this).agent.path.status == 0;
			DebugLog($"Player Reach Test: {flag}");
			return flag;
		}

		internal float PlayerDistanceFromShip(PlayerControllerB playerToCheck)
		{
			//IL_0019: 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)
			if (playerToCheck == null)
			{
				PLog.LogError("PlayerNearShip check has no target player or passed in argument!");
				return -1f;
			}
			float num = Vector3.Distance(((Component)playerToCheck).transform.position, ((Component)StartOfRound.Instance.shipBounds).transform.position);
			DebugLog($"PlayerNearShip check: {num}");
			return num;
		}

		internal bool PlayerWithinRange(PlayerControllerB player, float range, bool includeYAxis = true)
		{
			return DistanceFromPlayer(player, includeYAxis) <= range;
		}

		private float DistanceFromTargetPlayer(bool IncludeYAxis)
		{
			if ((Object)(object)targetPlayer == (Object)null)
			{
				PLog.LogError($"{this} attempted DistanceFromTargetPlayer with null target; returning -1!");
				return -1f;
			}
			return DistanceFromPlayer(targetPlayer, IncludeYAxis);
		}

		private float DistanceFromPlayer(PlayerControllerB player, bool IncludeYAxis)
		{
			//IL_0027: 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_004e: 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_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_0009: 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)
			if (IncludeYAxis)
			{
				return Vector3.Distance(((Component)player).transform.position, ((Component)this).transform.position);
			}
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(((Component)player).transform.position.x, ((Component)player).transform.position.z);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(((Component)this).transform.position.x, ((Component)this).transform.position.z);
			return Vector2.Distance(val, val2);
		}

		public void SetEnemyOutside(bool toOutside)
		{
			if (toOutside)
			{
				myValidState = PlayerState.Outside;
				((EnemyAI)this).SetEnemyOutside(true);
			}
			else
			{
				myValidState = PlayerState.Inside;
				((EnemyAI)this).SetEnemyOutside(false);
			}
		}

		protected override void TeleportSelfToOtherEntrance(bool isOutside)
		{
			//IL_0015: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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)
			EntranceTeleport val = RoundManager.FindMainEntranceScript(!isOutside);
			Vector3 navMeshPosition = RoundManager.Instance.GetNavMeshPosition(val.entrancePoint.position, default(NavMeshHit), 5f, -1);
			if (((NetworkBehaviour)this).IsOwner)
			{
				((Behaviour)((EnemyAI)this).agent).enabled = false;
				((Component)this).transform.position = navMeshPosition;
				((Behaviour)((EnemyAI)this).agent).enabled = true;
			}
			else
			{
				((Component)this).transform.position = navMeshPosition;
			}
			((EnemyAI)this).serverPosition = navMeshPosition;
			SetEnemyOutside(!isOutside);
			PlayEntranceOpeningSound(val);
		}

		private void PlayEntranceOpeningSound(EntranceTeleport entrance)
		{
			if (entrance.doorAudios != null && entrance.doorAudios.Length != 0)
			{
				entrance.entrancePointAudio.PlayOneShot(entrance.doorAudios[0]);
				WalkieTalkie.TransmitOneShotAudio(entrance.entrancePointAudio, entrance.doorAudios[0], 1f);
			}
		}

		internal void EnterSpecialAnimationWithPlayer(PlayerControllerB player, bool stopMovementCalculations = true)
		{
			if (player.inSpecialInteractAnimation && (Object)(object)player.currentTriggerInAnimationWith != (Object)null)
			{
				player.currentTriggerInAnimationWith.CancelAnimationExternally();
			}
			player.inSpecialInteractAnimation = true;
			player.inAnimationWithEnemy = (EnemyAI)(object)self;
			((EnemyAI)self).inSpecialAnimationWithPlayer = player;
			if (stopMovementCalculations)
			{
				((EnemyAI)self).inSpecialAnimation = true;
			}
		}

		internal bool TryGetValidPlayerFromCollision(Collider other, [NotNullWhen(true)] out PlayerControllerB? player, bool allowNonLocalPlayer = false)
		{
			player = null;
			if (((EnemyAI)this).isEnemyDead)
			{
				return false;
			}
			if (!((EnemyAI)this).ventAnimationFinished)
			{
				return false;
			}
			if (((EnemyAI)this).stunNormalizedTimer >= 0f)
			{
				return false;
			}
			player = ((Component)other).gameObject.GetComponent<PlayerControllerB>();
			if ((Object)(object)player == (Object)null || (!allowNonLocalPlayer && (Object)(object)player != (Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				return false;
			}
			if (!((EnemyAI)this).PlayerIsTargetable(player, false, false))
			{
				return false;
			}
			return true;
		}

		internal bool IsPlayerInsideCollider(PlayerControllerB? player, Collider collider, float colliderScale = 1f)
		{
			//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_0016: 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_0024: 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_0034: 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)
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			int num = 8;
			Bounds bounds = collider.bounds;
			Vector3 center = ((Bounds)(ref bounds)).center;
			bounds = collider.bounds;
			Collider[] array = Physics.OverlapBox(center, ((Bounds)(ref bounds)).extents / 2f * colliderScale, Quaternion.identity, num);
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				if (((Component)val).CompareTag("Player") && TryGetValidPlayerFromCollision(val, out PlayerControllerB player2, allowNonLocalPlayer: true) && (Object)(object)player2 == (Object)(object)player)
				{
					return true;
				}
			}
			return false;
		}

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

		protected internal override string __getTypeName()
		{
			return "ModEnemyAI`1";
		}
	}
	public abstract class ModEnemyAINetworkLayer : EnemyAI
	{
		internal Coroutine? _transitionCoroutineInProgress;

		[ServerRpc]
		internal void TransitionStateServerRpc(string stateName, int randomSeed)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Invalid comparison between Unknown and I4
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (((NetworkBehaviour)this).OwnerClientId != networkManager.LocalClientId)
				{
					if ((int)networkManager.LogLevel <= 1)
					{
						Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
					}
					return;
				}
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1357830014u, val, (RpcDelivery)0);
				bool flag = stateName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(stateName, false);
				}
				BytePacker.WriteValueBitPacked(val2, randomSeed);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1357830014u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				TransitionStateClientRpc(stateName, randomSeed);
			}
		}

		[ClientRpc]
		internal void TransitionStateClientRpc(string stateName, int randomSeed)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(755577249u, val, (RpcDelivery)0);
				bool flag = stateName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(stateName, false);
				}
				BytePacker.WriteValueBitPacked(val2, randomSeed);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 755577249u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				_transitionCoroutineInProgress = ((MonoBehaviour)this).StartCoroutine(TransitionState(stateName, randomSeed));
			}
		}

		internal abstract IEnumerator TransitionState(string stateOrTransitionName, int randomSeed);

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

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

		protected abstract void SetTarget(int PlayerID);

		[ServerRpc(RequireOwnership = false)]
		internal void SetAnimTriggerOnServerRpc(string name)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(217962959u, val, (RpcDelivery)0);
				bool flag = name != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(name, false);
				}
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 217962959u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && ((NetworkBehaviour)this).IsServer)
			{
				base.creatureAnimator.SetTrigger(name);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		internal void SetAnimBoolOnServerRpc(string name, bool state)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(4090843431u, val, (RpcDelivery)0);
				bool flag = name != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(name, false);
				}
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref state, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4090843431u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && ((NetworkBehaviour)this).IsServer)
			{
				base.creatureAnimator.SetBool(name, state);
			}
		}

		[ClientRpc]
		public void TeleportSelfToOtherEntranceClientRpc(bool isOutside)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val = default(ClientRpcParams);
					FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(463666875u, val, (RpcDelivery)0);
					((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref isOutside, default(ForPrimitives));
					((NetworkBehaviour)this).__endSendClientRpc(ref val2, 463666875u, val, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
				{
					TeleportSelfToOtherEntrance(isOutside);
				}
			}
		}

		protected abstract void TeleportSelfToOtherEntrance(bool isOutside);

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

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_ModEnemyAINetworkLayer()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(1357830014u, new RpcReceiveHandler(__rpc_handler_1357830014));
			NetworkManager.__rpc_func_table.Add(755577249u, new RpcReceiveHandler(__rpc_handler_755577249));
			NetworkManager.__rpc_func_table.Add(314908443u, new RpcReceiveHandler(__rpc_handler_314908443));
			NetworkManager.__rpc_func_table.Add(2468484041u, new RpcReceiveHandler(__rpc_handler_2468484041));
			NetworkManager.__rpc_func_table.Add(217962959u, new RpcReceiveHandler(__rpc_handler_217962959));
			NetworkManager.__rpc_func_table.Add(4090843431u, new RpcReceiveHandler(__rpc_handler_4090843431));
			NetworkManager.__rpc_func_table.Add(463666875u, new RpcReceiveHandler(__rpc_handler_463666875));
		}

		private static void __rpc_handler_1357830014(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			//IL_00a8: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
				return;
			}
			bool flag = default(bool);
			((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
			string stateName = null;
			if (flag)
			{
				((FastBufferReader)(ref reader)).ReadValueSafe(ref stateName, false);
			}
			int randomSeed = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref randomSeed);
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((ModEnemyAINetworkLayer)(object)target).TransitionStateServerRpc(stateName, randomSeed);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}

		private static void __rpc_handler_755577249(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: 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_005b: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string stateName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref stateName, false);
				}
				int randomSeed = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref randomSeed);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((ModEnemyAINetworkLayer)(object)target).TransitionStateClientRpc(stateName, randomSeed);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_314908443(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if (rpcParams.Server.Receive.SenderClientId != target.OwnerClientId)
			{
				if ((int)networkManager.LogLevel <= 1)
				{
					Debug.LogError((object)"Only the owner can invoke a ServerRpc that requires ownership!");
				}
			}
			else
			{
				int targetServerRpc = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref targetServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ModEnemyAINetworkLayer)(object)target).SetTargetServerRpc(targetServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

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

		private static void __rpc_handler_217962959(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: 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_0061: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string animTriggerOnServerRpc = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref animTriggerOnServerRpc, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ModEnemyAINetworkLayer)(object)target).SetAnimTriggerOnServerRpc(animTriggerOnServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_4090843431(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string name = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref name, false);
				}
				bool state = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref state, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ModEnemyAINetworkLayer)(object)target).SetAnimBoolOnServerRpc(name, state);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_463666875(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: 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_0044: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool isOutside = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref isOutside, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((ModEnemyAINetworkLayer)(object)target).TeleportSelfToOtherEntranceClientRpc(isOutside);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "ModEnemyAINetworkLayer";
		}
	}
	internal class SCP682AI : ModEnemyAI<SCP682AI>, IVisibleThreat
	{
		public enum Speed
		{
			Stopped = 0,
			Walking = 3,
			Running = 10
		}

		public enum EnemyScale
		{
			Small,
			Big
		}

		private static class Anim
		{
			internal const string isMoving = "isMoving";

			internal const string isMovingInverted = "isMovingInverted";

			internal const string isRunning = "isRunning";

			internal const string isOnShip = "isOnShip";

			internal const string doKillEnemy = "KillEnemy";

			internal const string doRevive = "doRevive";

			internal const string doBite = "doBite";

			internal const string doRoar = "doRoar";
		}

		private class WanderToShipState : AIBehaviorState
		{
			public override List<AIStateTransition> Transitions { get; set; } = new List<ModEnemyAI<SCP682AI>.AIStateTransition>(3)
			{
				new OnShipAmbushState.ArrivedAtShipTransition(),
				new InvestigatePlayerTransition(),
				new AttackEnemyState.TargetEnemyTransition()
			};


			public override IEnumerator OnStateEntered()
			{
				self.AnimatorSetBool("isMoving", value: true);
				yield break;
			}

			public override void AIInterval()
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				((EnemyAI)self).SetDestinationToPosition(self.PosOnTopOfShip, false);
			}

			public override IEnumerator OnStateExit()
			{
				yield break;
			}
		}

		private class OnShipAmbushState : AIBehaviorState
		{
			internal class ArrivedAtShipTransition : AIStateTransition
			{
				public override bool CanTransitionBeTaken()
				{
					//IL_0006: 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)
					if (Vector3.Distance(self.PosOnTopOfShip, ((Component)self).gameObject.transform.position) < 3f)
					{
						return true;
					}
					return false;
				}

				public override AIBehaviorState NextState()
				{
					return new OnShipAmbushState();
				}
			}

			private class AmbushPlayerFromShipTransition : AIStateTransition
			{
				public override bool CanTransitionBeTaken()
				{
					if ((Object)(object)self.PlayerHeardFromNoise != (Object)null)
					{
						base.TargetPlayer = self.PlayerHeardFromNoise;
						if (!self.PlayerWithinRange(base.TargetPlayer, 30f))
						{
							return false;
						}
						return true;
					}
					base.TargetPlayer = self.FindNearestPlayer();
					return false;
				}

				public override AIBehaviorState NextState()
				{
					return new FromAmbushJumpPlayerState();
				}
			}

			private class BoredOfAmbushTransition : AIStateTransition
			{
				private float boredOfAmbushTimer = 35f;

				public override bool CanTransitionBeTaken()
				{
					boredOfAmbushTimer -= Time.deltaTime;
					if (boredOfAmbushTimer <= 0f)
					{
						return true;
					}
					return false;
				}

				public override AIBehaviorState NextState()
				{
					return new WanderThroughEntranceState();
				}
			}

			public override List<AIStateTransition> Transitions { get; set; } = new List<ModEnemyAI<SCP682AI>.AIStateTransition>(2)
			{
				new AmbushPlayerFromShipTransition(),
				new BoredOfAmbushTransition()
			};


			public override IEnumerator OnStateEntered()
			{
				self.AnimatorSetBool("isMoving", value: false);
				self.AnimatorSetBool("isOnShip", value: true);
				base.Agent.SetDestination(((Component)base.Agent).transform.position);
				((EnemyAI)self).destination = ((Component)base.Agent).transform.position;
				((Behaviour)base.Agent).enabled = false;
				((Component)self).gameObject.transform.position = self.PosOnTopOfShip;
				if (self.changeScaleCoroutine != null)
				{
					((MonoBehaviour)self).StopCoroutine(self.changeScaleCoroutine);
				}
				((MonoBehaviour)self).StartCoroutine(self.ChangeEnemyScaleTo(EnemyScale.Small));
				yield break;
			}

			public override void Update()
			{
				//IL_0040: 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_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_0079: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)base.TargetPlayer == (Object)null))
				{
					self.turnCompass.LookAt(((Component)base.TargetPlayer).transform);
					((Component)self).transform.rotation = Quaternion.Lerp(((Component)self).transform.rotation, Quaternion.Euler(new Vector3(0f, self.turnCompass.eulerAngles.y, 0f)), 1f * Time.deltaTime);
				}
			}

			public override IEnumerator OnStateExit()
			{
				self.AnimatorSetBool("isMoving", value: true);
				self.AnimatorSetBool("isOnShip", value: false);
				((Behaviour)base.Agent).enabled = true;
				if (self.changeScaleCoroutine != null)
				{
					((MonoBehaviour)self).StopCoroutine(self.changeScaleCoroutine);
				}
				((MonoBehaviour)self).StartCoroutine(self.ChangeEnemyScaleTo(EnemyScale.Big));
				yield break;
			}
		}

		private class FromAmbushJumpPlayerState : AIBehaviorState
		{
			private class TouchTargetPlayerAndStartDraggingTransition : AIStateTransition
			{
				public override bool CanTransitionBeTaken()
				{
					return self.IsPlayerInsideCollider(base.TargetPlayer, (Collider)(object)self.mainCollider);
				}

				public override AIBehaviorState NextState()
				{
					return new DragPlayerState();
				}
			}

			public override List<AIStateTransition> Transitions { get; set; } = new List<ModEnemyAI<SCP682AI>.AIStateTransition>(2)
			{
				new TouchTargetPlayerAndStartDraggingTransition(),
				new LostPlayerTransition()
			};


			public override IEnumerator OnStateEntered()
			{
				if ((Object)(object)base.TargetPlayer == (Object)null)
				{
					Plugin.Logger.LogError((object)"Trying to ambush player, but targetPlayer is null! Not jumping.");
					((MonoBehaviour)self).StartCoroutine(self.RoarAndRunCoroutine());
					yield break;
				}
				if (base.TargetPlayer.isInHangarShipRoom)
				{
					self.DebugLog("TargetPlayer is inside ship, attacking without a jump.");
					((MonoBehaviour)self).StartCoroutine(self.RoarAndRunCoroutine());
					yield break;
				}
				Vector3 val = ((Component)base.TargetPlayer).transform.position - Vector3.Scale(new Vector3(10f, 0f, 10f), ((Component)base.TargetPlayer).transform.forward);
				NavMeshHit val2 = default(NavMeshHit);
				if (!NavMesh.SamplePosition(val, ref val2, 10f, -1))
				{
					Plugin.Logger.LogWarning((object)"Trying to ambush player, but didn't find NavMesh near target player! Not jumping.");
					((MonoBehaviour)self).StartCoroutine(self.RoarAndRunCoroutine());
					yield break;
				}
				Vector3 positionBehindPlayer = ((NavMeshHit)(ref val2)).position;
				Vector3 positionInBetweenInAir = (positionBehindPlayer + positionBehindPlayer) / 2f + Vector3.up * 10f;
				Vector3 originalPosition = ((Component)self).transform.position;
				base.Agent.speed = 0f;
				self.AnimatorSetBool("isRunning", value: true);
				((Behaviour)base.Agent).enabled = false;
				float normalizedTimer = 0f;
				while (normalizedTimer <= 1f)
				{
					float num = Time.deltaTime / 1.5f;
					normalizedTimer += num;
					Vector3 val3 = Vector3.Lerp(originalPosition, positionInBetweenInAir, normalizedTimer);
					Vector3 val4 = Vector3.Lerp(positionInBetweenInAir, positionBehindPlayer, normalizedTimer);
					((Component)self).transform.position = Vector3.Lerp(val3, val4, normalizedTimer);
					yield return null;
				}
				((Component)self).transform.position = positionBehindPlayer;
				((Behaviour)base.Agent).enabled = true;
				base.Agent.Warp(positionBehindPlayer);
				self.AnimatorSetBool("isRunning", value: false);
				((MonoBehaviour)self).StartCoroutine(self.RoarAndRunCoroutine());
			}

			public override void AIInterval()
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				base.TargetPlayer = self.FindNearestPlayer();
				((EnemyAI)self).SetDestinationToPosition(((Component)base.TargetPlayer).transform.position, false);
			}

			public override IEnumerator OnStateExit()
			{
				self.SetAgentSpeedAndAnimations(Speed.Walking);
				yield break;
			}
		}

		private class DragPlayerState : AIBehaviorState
		{
			private class DraggedPlayerEnoughTransition : AIStateTransition
			{
				private float draggedPlayerTimer;

				public override bool CanTransitionBeTaken()
				{
					draggedPlayerTimer += Time.deltaTime;
					if (draggedPlayerTimer > 15f)
					{
						return true;
					}
					return false;
				}

				public override AIBehaviorState NextState()
				{
					return new AttackPlayerState();
				}
			}

			private EntranceTeleport facilityEntrance;

			private float realMouthOrStableReverseMouth;

			private bool exitingThisState;

			public override List<AIStateTransition> Transitions { get; set; } = new List<ModEnemyAI<SCP682AI>.AIStateTransition>(1)
			{
				new DraggedPlayerEnoughTransition()
			};


			public override IEnumerator OnStateEntered()
			{
				base.TargetPlayer = self.FindNearestPlayer();
				self.EnterSpecialAnimationWithPlayer(base.TargetPlayer, stopMovementCalculations: false);
				if (((NetworkBehaviour)self).IsOwner)
				{
					facilityEntrance = RoundManager.FindMainEntranceScript(((EnemyAI)self).isOutside);
					if ((Object)(object)facilityEntrance == (Object)null)
					{
						PLog.LogError("Can't pathfind to entrance because it doesn't exist.");
						yield break;
					}
					if (!((EnemyAI)self).SetDestinationToPosition(facilityEntrance.entrancePoint.position, true))
					{
						PLog.LogError("Facility door is unreachable!");
						yield break;
					}
				}
				self.AnimatorSetBool("isMovingInverted", value: true);
				self.PlayVoice(SFX.VoiceCode.TearYouApart_DraggingPlayer);
				base.Agent.speed = 0f;
				realMouthOrStableReverseMouth = 0f;
				float normalizedTimer2 = 0f;
				while (normalizedTimer2 <= 4.2f)
				{
					normalizedTimer2 += Time.deltaTime;
					Update();
					yield return null;
				}
				base.Agent.speed = 3f;
				if (((NetworkBehaviour)self).IsOwner)
				{
					AIInterval();
				}
				normalizedTimer2 = 0f;
				while (normalizedTimer2 < 1f)
				{
					normalizedTimer2 = (realMouthOrStableReverseMouth = normalizedTimer2 + Time.deltaTime);
					Update();
					yield return null;
				}
				realMouthOrStableReverseMouth = 1f;
				base.Agent.speed = 7f;
			}

			public override void AIInterval()
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				if (((NetworkBehaviour)self).IsOwner && !((EnemyAI)self).SetDestinationToPosition(facilityEntrance.entrancePoint.position, true))
				{
					PLog.LogError("Facility door is unreachable!");
				}
			}

			public override void Update()
			{
				//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0115: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)((EnemyAI)self).inSpecialAnimationWithPlayer == (Object)null)
				{
					if (exitingThisState)
					{
						return;
					}
					Plugin.Logger.LogWarning((object)"Somehow `inSpecialAnimationWithPlayer` is null while dragging, setting it anyways.");
					((EnemyAI)self).CancelSpecialAnimationWithPlayer();
					if ((Object)(object)base.TargetPlayer == (Object)null)
					{
						Plugin.Logger.LogError((object)"Nvm, target player is somehow also null.");
						return;
					}
					self.EnterSpecialAnimationWithPlayer(base.TargetPlayer, stopMovementCalculations: false);
					if ((Object)(object)((EnemyAI)self).inSpecialAnimationWithPlayer == (Object)null)
					{
						Plugin.Logger.LogError((object)"Uhh, `inSpecialAnimationWithPlayer` is still null even after setting it? (This should never happen.)");
						return;
					}
				}
				if ((Object)(object)((EnemyAI)self).inSpecialAnimationWithPlayer.inAnimationWithEnemy != (Object)(object)self)
				{
					Plugin.Logger.LogWarning((object)"Player is no longer in special animation with this enemy!");
					self.OverrideState(new AttackPlayerState());
				}
				else
				{
					((Component)((EnemyAI)self).inSpecialAnimationWithPlayer).transform.position = Vector3.Lerp(((Component)base.CreatureVoice).transform.position + new Vector3(0f, -1f, 0f), self.reversedMouthPosition.position, realMouthOrStableReverseMouth);
				}
			}

			public override IEnumerator OnStateExit()
			{
				exitingThisState = true;
				base.Agent.speed = 0f;
				self.AnimatorSetBool("isMovingInverted", value: false);
				((EnemyAI)self).CancelSpecialAnimationWithPlayer();
				yield return (object)new WaitForSeconds(2f);
			}
		}

		private class WanderThroughEntranceState : AIBehaviorState
		{
			public class EnterEntranceTransition : AIStateTransition
			{
				private EntranceTeleport? _et;

				public override bool CanTransitionBeTaken()
				{
					//IL_0029: 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)
					if (_et == null)
					{
						_et = RoundManager.FindMainEntranceScript(((EnemyAI)self).isOutside);
					}
					if (Vector3.Distance(_et.entrancePoint.position, ((Component)self).gameObject.transform.position) < 4.5f)
					{
						self.TeleportSelfToOtherEntranceClientRpc(((EnemyAI)self).isOutside);
						self.blacklistedEnemies.Clear();
						return true;
					}
					return false;
				}

				public override AIBehaviorState NextState()
				{
					if (((EnemyAI)self).isOutside)
					{
						return new WanderToShipState();
					}
					return new AtFacilityWanderingState();
				}
			}

			private EntranceTeleport facilityEntrance;

			public override List<AIStateTransition> Transitions { get; set; } = new List<ModEnemyAI<SCP682AI>.AIStateTransition>(2)
			{
				new InvestigatePlayerTransition(),
				new AttackEnemyState.TargetEnemyTransition()
			};


			public override IEnumerator OnStateEntered()
			{
				self.AnimatorSetBool("isMoving", value: true);
				facilityEntrance = RoundManager.FindMainEntranceScript(((EnemyAI)self).isOutside);
				Transitions.Add(new EnterEntranceTransition());
				yield break;
			}

			public override void AIInterval()
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				if (!((EnemyAI)self).SetDestinationToPosition(facilityEntrance.entrancePoint.position, true))
				{
					PLog.LogWarning("Facility door is unreachable! Wandering instead.");
					self.OverrideState(new AtFacilityWanderingState());
				}
			}

			public override IEnumerator OnStateExit()
			{
				if (self.changeScaleCoroutine != null)
				{
					((MonoBehaviour)self).StopCoroutine(self.changeScaleCoroutine);
				}
				if (((EnemyAI)self).isOutside)
				{
					((MonoBehaviour)self).StartCoroutine(self.ChangeEnemyScaleTo(EnemyScale.Big));
				}
				else
				{
					((MonoBehaviour)self).StartCoroutine(self.ChangeEnemyScaleTo(EnemyScale.Small));
				}
				yield break;
			}
		}

		private class AtFacilityWanderingState : AIBehaviorState
		{
			private class BoredOfFacilityTransition : AIStateTransition
			{
				private float debugMSGTimer = 120f;

				public override bool CanTransitionBeTaken()
				{
					if (!((EnemyAI)self).isOutside)
					{
						foreach (JesterAI jester in JesterListHook.GetJesters())
						{
							if (((EnemyAI)jester).currentBehaviourStateIndex == 2)
							{
								self.DebugLog("[BoredOfFacilityTransition] Holy hell, a jester is going wild! I'm going to leave the facility.");
								return true;
							}
						}
					}
					self.boredOfWanderingFacilityTimer -= Time.deltaTime;
					if (debugMSGTimer - self.boredOfWanderingFacilityTimer > 10f)
					{
						debugMSGTimer = self.boredOfWanderingFacilityTimer;
						self.DebugLog(string.Format("[{0}] Time until bored: {1}", "BoredOfFacilityTransition", self.boredOfWanderingFacilityTimer));
					}
					if (self.boredOfWanderingFacilityTimer <= 0f)
					{
						return true;
					}
					return false;
				}

				public override AIBehaviorState NextState()
				{
					self.boredOfWanderingFacilityTimer = 120f;
					return new WanderThroughEntranceState();
				}
			}

			public override List<AIStateTransition> Transitions { get; set; } = new List<ModEnemyAI<SCP682AI>.AIStateTransition>(4)
			{
				new BoredOfFacilityTransition(),
				new AtFacilityEatNoisyJesterState.FindNoisyJesterTransition(),
				new InvestigatePlayerTransition(),
				new AttackEnemyState.TargetEnemyTransition()
			};


			public override IEnumerator OnStateEntered()
			{
				self.AnimatorSetBool("isMoving", value: true);
				((EnemyAI)self).StartSearch(((Component)self).transform.position, (AISearchRoutine)null);
				yield break;
			}

			public override IEnumerator OnStateExit()
			{
				((EnemyAI)self).StopSearch(((EnemyAI)self).currentSearch, true);
				yield break;
			}
		}

		private class AtFacilityEatNoisyJesterState : AIBehaviorState
		{
			internal class FindNoisyJesterTransition : AIStateTransition
			{
				public override bool CanTransitionBeTaken()
				{
					if (((EnemyAI)self).isOutside)
					{
						return false;
					}
					foreach (JesterAI jester in JesterListHook.GetJesters())
					{
						if (jester.farAudio.isPlaying)
						{
							self.targetEnemy = (MonoBehaviour?)(object)jester;
							return true;
						}
					}
					return false;
				}

				public override AIBehaviorState NextState()
				{
					return new AtFacilityEatNoisyJesterState();
				}
			}

			private class NoisyJesterEatenTransition : AIStateTransition
			{
				public override bool CanTransitionBeTaken()
				{
					return (Object)(object)self.targetEnemy == (Object)null;
				}

				public override AIBehaviorState NextState()
				{
					return new AtFacilityWanderingState();
				}
			}

			private JesterAI targetJester;

			private bool voiceClipPlayed;

			public override List<AIStateTransition> Transitions { get; set; } = new List<ModEnemyAI<SCP682AI>.AIStateTransition>(1)
			{
				new NoisyJesterEatenTransition()
			};


			public override IEnumerator OnStateEntered()
			{
				MonoBehaviour? targetEnemy = self.targetEnemy;
				JesterAI val = (JesterAI)(object)((targetEnemy is JesterAI) ? targetEnemy : null);
				if (val == null)
				{
					self.OverrideState(new AtFacilityWanderingState());
					yield break;
				}
				targetJester = val;
				self.AnimatorSetBool("isMoving", value: true);
				self.SetAgentSpeedAndAnimations(Speed.Running);
			}

			public override void AIInterval()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0072: 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_003e: 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)
				if (!((Object)(object)self.targetEnemy == (Object)null))
				{
					Vector3 position = ((Component)((EnemyAI)targetJester).agent).transform.position;
					if (!voiceClipPlayed && Vector3.Distance(position, ((Component)self).transform.position) < 20f)
					{
						voiceClipPlayed = true;
						base.CreatureSFX.PlayOneShot(SFX.Voice.Silence_ChargeJester);
					}
					if (Vector3.Distance(position, ((Component)self).transform.position) < 3f && ((NetworkBehaviour)self).IsHost)
					{
						((EnemyAI)targetJester).KillEnemyClientRpc(true);
					}
					((EnemyAI)self).SetDestinationToPosition(position, false);
				}
			}

			public override IEnumerator OnStateExit()
			{
				self.SetAgentSpeedAndAnimations(Speed.Walking);
				yield break;
			}
		}

		private class DeadTemporarilyState : AIBehaviorState
		{
			private class DeadTemporarilyUntilAwakeTransition : AIStateTransition
			{
				private float timer;

				public override bool CanTransitionBeTaken()
				{
					timer += Time.deltaTime;
					if (timer > 60f)
					{
						return true;
					}
					return false;
				}

				public override AIBehaviorState NextState()
				{
					return new WanderThroughEntranceState();
				}
			}

			public override List<AIStateTransition> Transitions { get; set; } = new List<ModEnemyAI<SCP682AI>.AIStateTransition>(1)
			{
				new DeadTemporarilyUntilAwakeTransition()
			};


			public override IEnumerator OnStateEntered()
			{
				base.CreatureVoice.PlayOneShot(SFX.defeated.FromRandom(base.EnemyRandom));
				base.Agent.isStopped = true;
				self.AnimatorSetTrigger("KillEnemy");
				yield break;
			}

			public override void AIInterval()
			{
				AnimationClip clip = ((AnimatorClipInfo)(ref base.CreatureAnimator.GetCurrentAnimatorClipInfo(0)[0])).clip;
				if (((Object)clip).name != "CG_death")
				{
					self.DebugLog("Should be dead, but current animation clip isn't dead clip. Setting clip to dead.");
					self.DebugLog("Animation clip was: " + ((Object)clip).name);
					self.AnimatorSetTrigger("KillEnemy");
				}
			}

			public override IEnumerator OnStateExit()
			{
				((EnemyAI)self).enemyHP = self._defaultHealth;
				base.Agent.isStopped = false;
				self.AnimatorSetTrigger("doRevive");
				self.globalAudio.PlayOneShot(SFX.spawn.FromRandom(base.EnemyRandom));
				self.PlayVoice(SFX.VoiceCode.FullRant_UponRevival);
				self.SetAgentSpeedAndAnimations(Speed.Walking);
				yield break;
			}
		}

		internal class AttackEnemyState : AIBehaviorState
		{
			internal class TargetEnemyTransition : AIStateTransition
			{
				public override bool CanTransitionBeTaken()
				{
					return (Object)(object)self.targetEnemy != (Object)null;
				}

				public override void AIInterval()
				{
					if (self.TryTargetEnemyInProximity(out MonoBehaviour enemy))
					{
						self.targetEnemy = enemy;
					}
				}

				public override AIBehaviorState NextState()
				{
					return new AttackEnemyState();
				}
			}

			private class EnemyKilledTransition : AIStateTransition
			{
				public override bool CanTransitionBeTaken()
				{
					if ((Object)(object)self.targetEnemy == (Object)null)
					{
						return true;
					}
					MonoBehaviour? targetEnemy = self.targetEnemy;
					EnemyAI val = (EnemyAI)(object)((targetEnemy is EnemyAI) ? targetEnemy : null);
					if (val != null && val.isEnemyDead)
					{
						return true;
					}
					return false;
				}

				public override AIBehaviorState NextState()
				{
					return self.CreatePreviousState();
				}
			}

			private int cantPathfindToEnemyCountdown = 10;

			public override List<AIStateTransition> Transitions { get; set; } = new List<ModEnemyAI<SCP682AI>.AIStateTransition>(1)
			{
				new EnemyKilledTransition()
			};


			public override IEnumerator OnStateEntered()
			{
				if (((NetworkBehaviour)self).IsOwner && (Object)(object)self.targetEnemy == (Object)null)
				{
					yield break;
				}
				yield return ((MonoBehaviour)self).StartCoroutine(self.RoarAndRunCoroutine());
				MonoBehaviour targetEnemy = self.targetEnemy;
				if (!(targetEnemy is BaboonBirdAI))
				{
					if (!(targetEnemy is ForestGiantAI))
					{
						if (targetEnemy is MouthDogAI)
						{
							PlayVoice(SFX.VoiceCode.Disgrace_EngageEyelessDog);
							yield break;
						}
						MonoBehaviour? targetEnemy2 = self.targetEnemy;
						EnemyAI val = (EnemyAI)(object)((targetEnemy2 is EnemyAI) ? targetEnemy2 : null);
						if (val != null && !val.isOutside)
						{
							PlayVoice(SFX.VoiceCode.Worms_EngageIndoorEnemies);
						}
					}
					else
					{
						PlayVoice(SFX.VoiceCode.Abomination_EngageForestGiant);
					}
				}
				else
				{
					PlayVoice(SFX.VoiceCode.Bothersome_EngageBaboonHawk);
				}
				void PlayVoice(SFX.VoiceCode clipCode)
				{
					((MonoBehaviour)self).StartCoroutine(self.PlayVoiceInSeconds(clipCode, 3f));
				}
			}

			public override void AIInterval()
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Invalid comparison between Unknown and I4
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)self.targetEnemy == (Object)null) && !((EnemyAI)self).SetDestinationToPosition(((Component)self.targetEnemy).transform.position, true))
				{
					PLog.LogWarning("Can't pathfind to target enemy!");
					cantPathfindToEnemyCountdown--;
					if (cantPathfindToEnemyCountdown <= 0)
					{
						PLog.LogWarning("Giving up on target enemy because couldn't reach it.");
						self.blacklistedEnemies.Add(self.targetEnemy);
						self.targetEnemy = null;
					}
					if ((int)((EnemyAI)self).path1.status == 1)
					{
						((EnemyAI)self).SetDestinationToPosition(((EnemyAI)self).path1.corners[^1], false);
					}
				}
			}

			public override void OnCollideWithEnemy(Collider other, EnemyAI? collidedEnemy)
			{
				if (self.attackCooldown > 0f || (Object)(object)collidedEnemy == (Object)null || !((NetworkBehaviour)self).IsOwner || !collidedEnemy.enemyType.canDie || collidedEnemy.isEnemyDead)
				{
					return;
				}
				self.AnimatorSetTriggerServerRpc("doBite");
				CaveDwellerAI val = (CaveDwellerAI)(object)((collidedEnemy is CaveDwellerAI) ? collidedEnemy : null);
				if (val != null)
				{
					if (((NetworkBehaviour)self).IsHost)
					{
						if (((EnemyAI)val).currentBehaviourStateIndex == 0)
						{
							val.TransformIntoAdult();
						}
						else
						{
							((EnemyAI)val).KillEnemyClientRpc(true);
						}
					}
				}
				else
				{
					collidedEnemy.HitEnemyServerRpc(10, -1, true, -1);
				}
				self.attackCooldown = 5f;
			}

			public override IEnumerator OnStateExit()
			{
				self.targetEnemy = null;
				self.SetAgentSpeedAndAnimations(Speed.Walking);
				yield break;
			}
		}

		internal class InvestigatePlayerState : AIBehaviorState
		{
			public override List<AIStateTransition> Transitions { get; set; } = new List<ModEnemyAI<SCP682AI>.AIStateTransition>(2)
			{
				new AttackPlayerTransition(),
				new LostPlayerTransition()
			};


			public override IEnumerator OnStateEntered()
			{
				self.AnimatorSetBool("isMoving", value: true);
				yield break;
			}

			public override void AIInterval()
			{
				//IL_0023: 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_0041: Invalid comparison between Unknown and I4
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				base.TargetPlayer = self.FindNearestPlayer();
				if (!((EnemyAI)self).SetDestinationToPosition(((Component)base.TargetPlayer).transform.position, true))
				{
					if ((int)((EnemyAI)self).path1.status == 1)
					{
						((EnemyAI)self).SetDestinationToPosition(((EnemyAI)self).path1.corners[^1], false);
					}
					self.DoRoarShockwaveAttackIfCan(Speed.Walking);
				}
			}

			public override void OnCollideWithPlayer(Collider other)
			{
				self.AttackCollideWithPlayer(other);
			}

			public override IEnumerator OnStateExit()
			{
				if (self.roarAttackInProgress)
				{
					((MonoBehaviour)self).StopCoroutine(self.RoarAndRunCoroutine());
				}
				yield break;
			}
		}

		internal class AttackPlayerState : AIBehaviorState
		{
			public override List<AIStateTransition> Transitions { get; set; } = new List<ModEnemyAI<SCP682AI>.AIStateTransition>(1)
			{
				new LostPlayerTransition()
			};


			public override IEnumerator OnStateEntered()
			{
				((MonoBehaviour)self).StartCoroutine(self.RoarAndRunCoroutine());
				yield break;
			}

			public override void AIInterval()
			{
				//IL_0023: 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_0041: Invalid comparison between Unknown and I4
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				base.TargetPlayer = self.FindNearestPlayer();
				if (!((EnemyAI)self).SetDestinationToPosition(((Component)base.TargetPlayer).transform.position, true))
				{
					if ((int)((EnemyAI)self).path1.status == 1)
					{
						((EnemyAI)self).SetDestinationToPosition(((EnemyAI)self).path1.corners[^1], false);
					}
					self.DoRoarShockwaveAttackIfCan(Speed.Running);
				}
			}

			public override void OnCollideWithPlayer(Collider other)
			{
				self.AttackCollideWithPlayer(other);
			}

			public override IEnumerator OnStateExit()
			{
				if (self.roarAttackInProgress)
				{
					((MonoBehaviour)self).StopCoroutine(self.RoarAndRunCoroutine());
				}
				self.SetAgentSpeedAndAnimations(Speed.Walking);
				yield break;
			}
		}

		private class InvestigatePlayerTransition : AIStateTransition
		{
			public override bool CanTransitionBeTaken()
			{
				if (self.activeState is AttackPlayerState)
				{
					return false;
				}
				PlayerControllerB val = ((EnemyAI)self).CheckLineOfSightForPlayer(45f, 30, 15);
				if ((Object)(object)val == (Object)null)
				{
					val = self.PlayerHeardFromNoise;
					if ((Object)(object)val == (Object)null)
					{
						return false;
					}
				}
				else if (val.isInHangarShipRoom)
				{
					val = ((EnemyAI)self).CheckLineOfSightForPlayer(45f, 30, -1);
					if ((Object)(object)val == (Object)null)
					{
						return false;
					}
				}
				return true;
			}

			public override AIBehaviorState NextState()
			{
				return new InvestigatePlayerState();
			}
		}

		private class AttackPlayerTransition : AIStateTransition
		{
			private float aggressionTimer = 10f;

			public override bool CanTransitionBeTaken()
			{
				aggressionTimer -= Time.deltaTime;
				if (aggressionTimer > 0f)
				{
					return false;
				}
				PlayerControllerB val = ((EnemyAI)self).CheckLineOfSightForPlayer(45f, 30, 15);
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				self.PlayVoice(SFX.VoiceCode.Useless_ChasingPlayerForSomeTime);
				return true;
			}

			public override AIBehaviorState NextState()
			{
				return new AttackPlayerState();
			}
		}

		private class LostPlayerTransition : AIStateTransition
		{
			private const float defaultPlayerLostTimer = 9f;

			private float playerLostTimer = 9f;

			public override bool CanTransitionBeTaken()
			{
				PlayerControllerB val = ((EnemyAI)self).CheckLineOfSightForPlayer(45f, 30, 15);
				if ((Object)(object)val != (Object)null)
				{
					playerLostTimer = 9f;
					return false;
				}
				playerLostTimer -= Time.deltaTime;
				if (playerLostTimer <= 0f)
				{
					self.PlayVoice(SFX.VoiceCode.Cowards_LostPlayer);
					return true;
				}
				return false;
			}

			public override AIBehaviorState NextState()
			{
				if (((EnemyAI)self).isOutside)
				{
					return new WanderThroughEntranceState();
				}
				return new AtFacilityWanderingState();
			}
		}

		internal static List<GameObject> SCP682Objects = new List<GameObject>();

		private const float defaultBoredOfWanderingFacilityTimer = 120f;

		private float boredOfWanderingFacilityTimer = 120f;

		private MonoBehaviour? targetEnemy;

		internal List<MonoBehaviour?> blacklistedEnemies = new List<MonoBehaviour>();

		private PlayerControllerB? _playerHeardFromNoise;

		private float _playerHeardFromNoiseTimer;

		internal bool roarAttackInProgress;

		private LineRenderer lineRenderer;

		private BoxCollider mainCollider;

		internal Transform turnCompass;

		internal Transform crocodileModel;

		internal Transform reversedMouthPosition;

		private const float defaultAttackCooldown = 5f;

		private float attackCooldown = 5f;

		private Coroutine? changeScaleCoroutine;

		private List<PlayerControllerB> playersAttackedSelf = new List<PlayerControllerB>();

		private int _defaultHealth;

		internal AudioSource globalAudio;

		internal static Collider[] tempCollisionArr = (Collider[])(object)new Collider[20];

		internal NavMeshPath? tempPath = new NavMeshPath();

		internal const int visibleThreatsMask = 524296;

		private Vector3 PosOnTopOfShip => StartOfRound.Instance.insideShipPositions[0].position + new Vector3(-2f, 5f, 3f);

		internal PlayerControllerB? PlayerHeardFromNoise
		{
			get
			{
				if (_playerHeardFromNoiseTimer > 1f)
				{
					return null;
				}
				return _playerHeardFromNoise;
			}
			set
			{
				_playerHeardFromNoise = value;
			}
		}

		ThreatType IVisibleThreat.type => (ThreatType)6;

		int IVisibleThreat.GetThreatLevel(Vector3 seenByPosition)
		{
			return 10;
		}

		int IVisibleThreat.GetInterestLevel()
		{
			return 0;
		}

		Transform IVisibleThreat.GetThreatLookTransform()
		{
			return ((EnemyAI)this).eye;
		}

		Transform IVisibleThreat.GetThreatTransform()
		{
			return ((Component)this).transform;
		}

		Vector3 IVisibleThreat.GetThreatVelocity()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)this).IsOwner)
			{
				return Vector3.zero;
			}
			return ((EnemyAI)this).agent.velocity;
		}

		float IVisibleThreat.GetVisibility()
		{
			if (((EnemyAI)this).enemyHP <= 0)
			{
				return 0f;
			}
			return 1f;
		}

		int IVisibleThreat.SendSpecialBehaviour(int id)
		{
			return 0;
		}

		internal override SCP682AI GetThis()
		{
			return this;
		}

		internal override AIBehaviorState GetInitialState()
		{
			return new WanderThroughEntranceState();
		}

		public override void Start()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			SCP682Objects.Add(((Component)this).gameObject);
			_defaultHealth = ((EnemyAI)this).enemyHP;
			lineRenderer = ((Component)this).gameObject.AddComponent<LineRenderer>();
			mainCollider = ((Component)this).gameObject.GetComponentInChildren<BoxCollider>();
			turnCompass = ((Component)((Component)this).transform.Find("TurnCompass")).GetComponent<Transform>();
			crocodileModel = ((Component)this).transform.Find("ModelRoot");
			reversedMouthPosition = crocodileModel.Find("CrocodileModel/ReversedMouthPosition");
			globalAudio = ((Component)this).GetComponent<AudioSource>();
			float num = 1f;
			crocodileModel.localScale = new Vector3(num, num, num);
			if (((NetworkBehaviour)this).IsHost)
			{
				if (((EnemyAI)this).enemyType.isOutsideEnemy)
				{
					SyncScaleOnSpawnClientRPC(EnemyScale.Big);
				}
				else
				{
					SyncScaleOnSpawnClientRPC(EnemyScale.Small);
				}
			}
			base.Start();
			globalAudio.PlayOneShot(SFX.spawn.FromRandom(enemyRandom));
			DebugLog($"Am I an outside enemy? {((EnemyAI)this).enemyType.isOutsideEnemy}");
		}

		[ClientRpc]
		private void SyncScaleOnSpawnClientRPC(EnemyScale scale)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2726260803u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<EnemyScale>(ref scale, default(ForEnums));
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2726260803u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (scale == EnemyScale.Big)
				{
					SetEnemyOutside(toOutside: true);
				}
				else
				{
					SetEnemyOutside(toOutside: false);
				}
				changeScaleCoroutine = ((MonoBehaviour)this).StartCoroutine(ChangeEnemyScaleTo(EnemyScale.Big));
			}
		}

		public override void Update()
		{
			attackCooldown -= Time.deltaTime;
			_playerHeardFromNoiseTimer += Time.deltaTime;
			base.Update();
		}

		public override void KillEnemy(bool destroy = false)
		{
		}

		public IEnumerator BashDoorAnimation(Action bashDoor)
		{
			if (activeState is InvestigatePlayerState)
			{
				AnimatorSetTrigger("doBite");
				yield return (object)new WaitForSeconds(0.2f);
			}
			bashDoor();
		}

		public override void HitEnemy(int force = 1, PlayerControllerB? playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
		{
			if (((EnemyAI)this).enemyHP <= 0 && activeState is DeadTemporarilyState)
			{
				return;
			}
			if ((Object)(object)playerWhoHit != (Object)null)
			{
				if (playersAttackedSelf.Count == 0)
				{
					playersAttackedSelf.Add(playerWhoHit);
					((EnemyAI)this).creatureVoice.PlayOneShot(SFX.Voice

plugins/SCP682/SCP682Assets/ProjectSCP.SCP682.UnityRef.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using Microsoft.CodeAnalysis;
using SCP682.UnityRef.Extensions;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ProjectSCP.SCP682.UnityRef")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+743dd18b12e870911f281ec57f41e474533878c1")]
[assembly: AssemblyProduct("SCP682 Unity Reference")]
[assembly: AssemblyTitle("ProjectSCP.SCP682.UnityRef")]
[assembly: AssemblyVersion("0.1.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
[BepInPlugin("ProjectSCP.SCP682.UnityRef", "SCP682.UnityRef", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
}
namespace SCP682.UnityRef
{
	public class SCP682AnimatorAudio : MonoBehaviour
	{
		[field: SerializeField]
		public AudioSource CreatureSFX { get; private set; }

		[field: SerializeField]
		public AudioSource CreatureVoice { get; private set; }

		[field: SerializeField]
		public List<AudioClip> WalkSFX { get; private set; } = new List<AudioClip>();


		[field: SerializeField]
		public List<AudioClip> RunSFX { get; private set; } = new List<AudioClip>();


		[field: SerializeField]
		public List<AudioClip> RoarSFX { get; private set; } = new List<AudioClip>();


		[field: SerializeField]
		public List<AudioClip> BiteSFX { get; private set; } = new List<AudioClip>();


		public void PlayWalkSFX()
		{
			CreatureSFX.PlayOneShot(WalkSFX.Random());
		}

		public void PlayRunSFX()
		{
			CreatureSFX.PlayOneShot(RunSFX.Random());
		}

		public void PlayRoarSFX()
		{
			CreatureVoice.PlayOneShot(RoarSFX.Random());
		}

		public void PlayBiteSFX()
		{
			CreatureVoice.PlayOneShot(BiteSFX.Random());
		}
	}
}
namespace SCP682.UnityRef.Extensions
{
	internal static class AudioClipExtensions
	{
		private static readonly Random random = new Random();

		public static AudioClip Random(this List<AudioClip> clips)
		{
			return clips[random.Next(clips.Count)];
		}
	}
}