Decompiled source of SCP173 v1.0.1

plugins/SCP173/ProjectSCP.SCP173.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using LethalBestiary.Modules;
using Microsoft.CodeAnalysis;
using ProjectSCP.SCP173.NetcodePatcher;
using SCP173.Configuration;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[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.SCP173")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+efa15d1c79b705651581fe3bf59ac8c95670bfcd")]
[assembly: AssemblyProduct("SCP173")]
[assembly: AssemblyTitle("ProjectSCP.SCP173")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializable<NetworkBehaviourReference>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<NetworkBehaviourReference>();
	}
}
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 SCP173
{
	internal class ExampleEnemyAI : EnemyAI
	{
		private enum State
		{
			SearchingForPlayer,
			StickingInFrontOfPlayer,
			HeadSwingAttackInProgress
		}

		public Transform turnCompass;

		public Transform attackArea;

		private float timeSinceHittingLocalPlayer;

		private float timeSinceNewRandPos;

		private Vector3 positionRandomness;

		private Vector3 StalkPos;

		private Random enemyRandom;

		private bool isDeadAnimationDone;

		[Conditional("DEBUG")]
		private void LogIfDebugBuild(string text)
		{
			Plugin.Logger.LogInfo((object)text);
		}

		public override void Start()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Start();
			timeSinceHittingLocalPlayer = 0f;
			base.creatureAnimator.SetTrigger("startWalk");
			timeSinceNewRandPos = 0f;
			positionRandomness = new Vector3(0f, 0f, 0f);
			enemyRandom = new Random(StartOfRound.Instance.randomMapSeed + base.thisEnemyIndex);
			isDeadAnimationDone = false;
			base.currentBehaviourStateIndex = 0;
			((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null);
		}

		public override void Update()
		{
			//IL_0091: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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)
			((EnemyAI)this).Update();
			if (base.isEnemyDead)
			{
				if (!isDeadAnimationDone)
				{
					isDeadAnimationDone = true;
					base.creatureVoice.Stop();
					base.creatureVoice.PlayOneShot(base.dieSFX);
				}
				return;
			}
			timeSinceHittingLocalPlayer += Time.deltaTime;
			timeSinceNewRandPos += Time.deltaTime;
			int currentBehaviourStateIndex = base.currentBehaviourStateIndex;
			if ((Object)(object)base.targetPlayer != (Object)null && (currentBehaviourStateIndex == 1 || currentBehaviourStateIndex == 2))
			{
				turnCompass.LookAt(((Component)base.targetPlayer.gameplayCamera).transform.position);
				((Component)this).transform.rotation = Quaternion.Lerp(((Component)this).transform.rotation, Quaternion.Euler(new Vector3(0f, turnCompass.eulerAngles.y, 0f)), 4f * Time.deltaTime);
			}
			if (base.stunNormalizedTimer > 0f)
			{
				base.agent.speed = 0f;
			}
		}

		public override void DoAIInterval()
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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)
			((EnemyAI)this).DoAIInterval();
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
				base.agent.speed = 3f;
				if (FoundClosestPlayerInRange(25f, 3f))
				{
					((EnemyAI)this).StopSearch(base.currentSearch, true);
					((EnemyAI)this).SwitchToBehaviourClientRpc(1);
				}
				break;
			case 1:
				base.agent.speed = 5f;
				if (!TargetClosestPlayerInAnyCase() || (Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) > 20f && !((EnemyAI)this).CheckLineOfSightForPosition(((Component)base.targetPlayer).transform.position, 45f, 60, -1f, (Transform)null)))
				{
					((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null);
					((EnemyAI)this).SwitchToBehaviourClientRpc(0);
				}
				else
				{
					StickingInFrontOfPlayer();
				}
				break;
			case 2:
				break;
			}
		}

		private bool FoundClosestPlayerInRange(float range, float senseRange)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).TargetClosestPlayer(1.5f, true, 70f);
			if ((Object)(object)base.targetPlayer == (Object)null)
			{
				((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f);
				range = senseRange;
			}
			if ((Object)(object)base.targetPlayer != (Object)null)
			{
				return Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < range;
			}
			return false;
		}

		private bool TargetClosestPlayerInAnyCase()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			base.mostOptimalDistance = 2000f;
			base.targetPlayer = null;
			for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++)
			{
				base.tempDist = Vector3.Distance(((Component)this).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position);
				if (base.tempDist < base.mostOptimalDistance)
				{
					base.mostOptimalDistance = base.tempDist;
					base.targetPlayer = StartOfRound.Instance.allPlayerScripts[i];
				}
			}
			if ((Object)(object)base.targetPlayer == (Object)null)
			{
				return false;
			}
			return true;
		}

		private void StickingInFrontOfPlayer()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)base.targetPlayer == (Object)null) && ((NetworkBehaviour)this).IsOwner && timeSinceNewRandPos > 0.7f)
			{
				timeSinceNewRandPos = 0f;
				if (enemyRandom.Next(0, 5) == 0)
				{
					((MonoBehaviour)this).StartCoroutine(SwingAttack());
				}
				else
				{
					positionRandomness = new Vector3((float)enemyRandom.Next(-2, 2), 0f, (float)enemyRandom.Next(-2, 2));
					StalkPos = ((Component)base.targetPlayer).transform.position - Vector3.Scale(new Vector3(-5f, 0f, -5f), ((Component)base.targetPlayer).transform.forward) + positionRandomness;
				}
				((EnemyAI)this).SetDestinationToPosition(StalkPos, false);
			}
		}

		private IEnumerator SwingAttack()
		{
			((EnemyAI)this).SwitchToBehaviourClientRpc(2);
			StalkPos = ((Component)base.targetPlayer).transform.position;
			((EnemyAI)this).SetDestinationToPosition(StalkPos, false);
			yield return (object)new WaitForSeconds(0.5f);
			if (!base.isEnemyDead)
			{
				DoAnimationClientRpc("swingAttack");
				yield return (object)new WaitForSeconds(0.35f);
				SwingAttackHitClientRpc();
				if (base.currentBehaviourStateIndex == 2)
				{
					((EnemyAI)this).SwitchToBehaviourClientRpc(1);
				}
			}
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (!(timeSinceHittingLocalPlayer < 1f))
			{
				PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false);
				if ((Object)(object)val != (Object)null)
				{
					timeSinceHittingLocalPlayer = 0f;
					val.DamagePlayer(20, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
				}
			}
		}

		public override void HitEnemy(int force = 1, PlayerControllerB? playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
		{
			((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitID);
			if (!base.isEnemyDead)
			{
				base.enemyHP -= force;
				if (((NetworkBehaviour)this).IsOwner && base.enemyHP <= 0 && !base.isEnemyDead)
				{
					((MonoBehaviour)this).StopCoroutine(SwingAttack());
					((MonoBehaviour)this).StopCoroutine(base.searchCoroutine);
					((EnemyAI)this).KillEnemyOnOwnerClient(false);
				}
			}
		}

		[ClientRpc]
		public void DoAnimationClientRpc(string animationName)
		{
			//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 != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2467579342u, val, (RpcDelivery)0);
				bool flag = animationName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(animationName, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2467579342u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				base.creatureAnimator.SetTrigger(animationName);
			}
		}

		[ClientRpc]
		public void SwingAttackHitClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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(3641797616u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3641797616u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			int num = 8;
			Collider[] array = Physics.OverlapBox(attackArea.position, attackArea.localScale, Quaternion.identity, num);
			if (array.Length == 0)
			{
				return;
			}
			Collider[] array2 = array;
			foreach (Collider val3 in array2)
			{
				PlayerControllerB val4 = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(val3, false, false);
				if ((Object)(object)val4 != (Object)null)
				{
					timeSinceHittingLocalPlayer = 0f;
					val4.DamagePlayer(40, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
				}
			}
		}

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

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

		private static void __rpc_handler_2467579342(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 animationName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref animationName, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((ExampleEnemyAI)(object)target).DoAnimationClientRpc(animationName);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

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

		protected internal override string __getTypeName()
		{
			return "ExampleEnemyAI";
		}
	}
	public static class NavMeshPathExtensions
	{
		public static Vector3 SamplePathPosition(NavMeshPath path, float distance)
		{
			//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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			Vector3 result = path.corners[0];
			float num = distance;
			for (int i = 1; i < path.corners.Length; i++)
			{
				float num2 = Vector3.Distance(path.corners[i - 1], path.corners[i]);
				if (num < num2)
				{
					result = Vector3.Lerp(path.corners[i - 1], path.corners[i], num / num2);
					break;
				}
				num -= num2;
			}
			return result;
		}

		public static bool CheckCondition(Vector3 point)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return point.y > 1f;
		}

		public static float GetPathLength(this NavMeshPath path)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			for (int i = 1; i < path.corners.Length; i++)
			{
				num += Vector3.Distance(path.corners[i - 1], path.corners[i]);
			}
			return num;
		}
	}
	[BepInPlugin("ProjectSCP.SCP173", "SCP173", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		public static AssetBundle? ModAssets;

		internal static PluginConfig BoundConfig { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			BoundConfig = new PluginConfig(((BaseUnityPlugin)this).Config);
			InitializeNetworkBehaviours();
			string path = "scp173modassets";
			ModAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), path));
			if ((Object)(object)ModAssets == (Object)null)
			{
				Logger.LogError((object)"Failed to load custom assets.");
				return;
			}
			EnemyType val = ModAssets.LoadAsset<EnemyType>("SCP173");
			TerminalNode val2 = ModAssets.LoadAsset<TerminalNode>("Scp173TN");
			TerminalKeyword val3 = ModAssets.LoadAsset<TerminalKeyword>("Scp173TK");
			NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab);
			Enemies.RegisterEnemy(val, BoundConfig.SpawnWeight.Value, (LevelTypes)(-1), val2, val3);
			Logger.LogInfo((object)"Plugin ProjectSCP.SCP173 is loaded!");
		}

		private static void InitializeNetworkBehaviours()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ProjectSCP.SCP173";

		public const string PLUGIN_NAME = "SCP173";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace SCP173.SCP173
{
	public class ModEnemyAI : EnemyAI
	{
		public abstract class AIBehaviorState
		{
			public Vector2 RandomRange = new Vector2(0f, 0f);

			public int MyRandomInt;

			public Scp173AI self;

			public NavMeshAgent agent;

			public Random enemyRandom;

			public abstract List<AIStateTransition> Transitions { get; set; }

			public abstract void OnStateEntered(Animator creatureAnimator);

			public virtual void UpdateBehavior(Animator creatureAnimator)
			{
			}

			public virtual void AIInterval(Animator creatureAnimator)
			{
			}

			public abstract void OnStateExit(Animator creatureAnimator);
		}

		public abstract class AIStateTransition
		{
			public Scp173AI self;

			public abstract bool CanTransitionBeTaken();

			public abstract AIBehaviorState NextState();
		}

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

		internal AIBehaviorState InitialState;

		internal AIBehaviorState ActiveState;

		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 List<AIStateTransition> AllTransitions = new List<AIStateTransition>();

		internal Scp173AI self;

		[NonSerialized]
		private NetworkVariable<NetworkBehaviourReference> _playerNetVar = new NetworkVariable<NetworkBehaviourReference>(default(NetworkBehaviourReference), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		public PlayerControllerB SynchronisedTargetPlayer
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Expected O, but got Unknown
				return (PlayerControllerB)NetworkBehaviourReference.op_Implicit(_playerNetVar.Value);
			}
			set
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)value == (Object)null)
				{
					_playerNetVar.Value = NetworkBehaviourReference.op_Implicit((NetworkBehaviour)null);
				}
				else
				{
					_playerNetVar.Value = new NetworkBehaviourReference((NetworkBehaviour)(object)value);
				}
			}
		}

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

		public override void DoAIInterval()
		{
			((EnemyAI)this).DoAIInterval();
			ActiveState.AIInterval(base.creatureAnimator);
		}

		public override void Start()
		{
			((EnemyAI)this).Start();
			ActiveState = InitialState;
			enemyRandom = new Random(StartOfRound.Instance.randomMapSeed + base.thisEnemyIndex);
			if (base.enemyType.isOutsideEnemy)
			{
				MyValidState = PlayerState.Outside;
			}
			else
			{
				MyValidState = PlayerState.Inside;
			}
			if (!base.agent.isOnNavMesh && ((NetworkBehaviour)this).IsOwner)
			{
				LogDebug("CREATURE " + ((NetworkBehaviour)this).__getTypeName() + " WAS NOT PLACED ON NAVMESH, DESTROYING...");
				((EnemyAI)this).KillEnemyOnOwnerClient(false);
			}
			base.creatureAnimator.Rebind();
			ActiveState.self = self;
			ActiveState.agent = base.agent;
			ActiveState.enemyRandom = enemyRandom;
			ActiveState.OnStateEntered(base.creatureAnimator);
		}

		public override void Update()
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			if (base.isEnemyDead)
			{
				return;
			}
			((EnemyAI)this).Update();
			AITimer += Time.deltaTime;
			bool flag = true;
			AllTransitions.Clear();
			AllTransitions.AddRange(GlobalTransitions);
			AllTransitions.AddRange(ActiveState.Transitions);
			foreach (AIStateTransition allTransition in AllTransitions)
			{
				allTransition.self = self;
				if (allTransition.CanTransitionBeTaken() && ((NetworkBehaviour)this).IsOwner)
				{
					flag = false;
					nextTransition = allTransition;
					TransitionStateServerRpc(nextTransition.ToString(), GenerateNextRandomInt(nextTransition.NextState().RandomRange));
					return;
				}
			}
			if (flag)
			{
				ActiveState.UpdateBehavior(base.creatureAnimator);
			}
		}

		internal void LogDebug(object data)
		{
			if (PrintDebugs)
			{
				Plugin.Logger.LogInfo(data);
			}
		}

		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;
			}
		}

		internal void OverrideState(AIBehaviorState state)
		{
			if (!base.isEnemyDead)
			{
				ActiveState = state;
				ActiveState.self = self;
				ActiveState.agent = base.agent;
				ActiveState.enemyRandom = enemyRandom;
				ActiveState.OnStateEntered(base.creatureAnimator);
			}
		}

		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)base.eye).transform.forward, ((Component)player.gameplayCamera).transform.position - ((Component)base.eye).transform.position);
			bool flag2 = num2 < width;
			bool flag3 = num < (float)proximityAwareness;
			bool flag4 = DoLinecast && Physics.Linecast(((Component)base.eye).transform.position, ((Component)player).transform.position, StartOfRound.Instance.collidersRoomDefaultAndFoliage, (QueryTriggerInteraction)1);
			if (PrintResults)
			{
				LogDebug($"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)base.targetPlayer == (Object)null)
			{
				LogDebug(((NetworkBehaviour)this).__getTypeName() + " called Target Player LOS check called with null target player; returning false!");
				return false;
			}
			return IsTargetPlayerWithinLOS(base.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 || base.agent.CalculatePath(((Component)val2).transform.position, base.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)
			{
				LogDebug("There is somehow no closest player. get fucked");
				return null;
			}
			return val;
		}

		internal bool IsPlayerReachable()
		{
			if ((Object)(object)base.targetPlayer == (Object)null)
			{
				Plugin.Logger.LogError((object)"Player Reach Test has no target player or passed in argument!");
				return false;
			}
			return IsPlayerReachable(base.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
			Vector3 navMeshPosition = RoundManager.Instance.GetNavMeshPosition(((Component)base.targetPlayer).transform.position, RoundManager.Instance.navHit, 2.7f, -1);
			if (!RoundManager.Instance.GotNavMeshPositionResult)
			{
				LogDebug("Player Reach Test: No NavMesh position");
				return false;
			}
			base.agent.CalculatePath(navMeshPosition, base.agent.path);
			bool flag = (int)base.agent.path.status == 0;
			LogDebug($"Player Reach Test: {flag}");
			return flag;
		}

		internal float PlayerDistanceFromShip(PlayerControllerB? PlayerToCheck = null)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)PlayerToCheck == (Object)null)
			{
				if ((Object)(object)base.targetPlayer == (Object)null)
				{
					Plugin.Logger.LogError((object)"PlayerNearShip check has no target player or passed in argument!");
					return -1f;
				}
				PlayerToCheck = base.targetPlayer;
			}
			float num = Vector3.Distance(((Component)base.targetPlayer).transform.position, ((Component)StartOfRound.Instance.shipBounds).transform.position);
			LogDebug($"PlayerNearShip check: {num}");
			return num;
		}

		internal bool PlayerWithinRange(float Range, bool IncludeYAxis = true)
		{
			LogDebug($"Distance from target player: {DistanceFromTargetPlayer(IncludeYAxis)}");
			return DistanceFromTargetPlayer(IncludeYAxis) <= Range;
		}

		internal bool PlayerWithinRange(PlayerControllerB player, float Range, bool IncludeYAxis = true)
		{
			return DistanceFromTargetPlayer(player, IncludeYAxis) <= Range;
		}

		private float DistanceFromTargetPlayer(bool IncludeYAxis)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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)
			if ((Object)(object)base.targetPlayer == (Object)null)
			{
				Plugin.Logger.LogError((object)$"{this} attempted DistanceFromTargetPlayer with null target; returning -1!");
				return -1f;
			}
			if (IncludeYAxis)
			{
				return Vector3.Distance(((Component)base.targetPlayer).transform.position, ((Component)this).transform.position);
			}
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(((Component)base.targetPlayer).transform.position.x, ((Component)base.targetPlayer).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);
		}

		private float DistanceFromTargetPlayer(PlayerControllerB player, bool IncludeYAxis)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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)base.targetPlayer).transform.position.x, ((Component)base.targetPlayer).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);
		}

		internal bool AnimationIsFinished(string AnimName)
		{
			//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 = base.creatureAnimator.GetCurrentAnimatorStateInfo(0);
			if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName(AnimName))
			{
				LogDebug(((NetworkBehaviour)this).__getTypeName() + ": Checking for animation " + AnimName + ", but current animation is " + ((Object)((AnimatorClipInfo)(ref base.creatureAnimator.GetCurrentAnimatorClipInfo(0)[0])).clip).name);
				return true;
			}
			currentAnimatorStateInfo = base.creatureAnimator.GetCurrentAnimatorStateInfo(0);
			return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime >= 1f;
		}

		internal int GenerateNextRandomInt(Vector2 Range)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Range = nextTransition.NextState().RandomRange;
			return enemyRandom.Next((int)Range.x, (int)Range.y);
		}

		[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(2082601448u, 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, 2082601448u, 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(371120224u, 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, 371120224u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost) && ((NetworkBehaviour)this).IsServer)
			{
				base.creatureAnimator.SetBool(name, state);
			}
		}

		[ServerRpc]
		internal void TransitionStateServerRpc(string StateName, int RandomInt)
		{
			//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(2465494607u, 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, RandomInt);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2465494607u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				TransitionStateClientRpc(StateName, RandomInt);
			}
		}

		[ClientRpc]
		internal void TransitionStateClientRpc(string StateName, int RandomInt)
		{
			//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(4108904228u, 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, RandomInt);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4108904228u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				TransitionState(StateName, RandomInt);
			}
		}

		internal void TransitionState(string StateName, int RandomInt)
		{
			Type type = Type.GetType(StateName);
			AIStateTransition aIStateTransition = (AIStateTransition)Activator.CreateInstance(type);
			aIStateTransition.self = self;
			if (!(aIStateTransition.NextState().GetType() == ActiveState.GetType()))
			{
				LogDebug($"{((NetworkBehaviour)this).__getTypeName()} #{self} is Exiting:  {ActiveState}");
				ActiveState.OnStateExit(base.creatureAnimator);
				LogDebug($"{((NetworkBehaviour)this).__getTypeName()} #{self} is Transitioning via:  {aIStateTransition}");
				ActiveState = aIStateTransition.NextState();
				ActiveState.MyRandomInt = RandomInt;
				ActiveState.self = self;
				ActiveState.agent = base.agent;
				ActiveState.enemyRandom = enemyRandom;
				LogDebug($"{((NetworkBehaviour)this).__getTypeName()} #{self} is Entering:  {ActiveState}");
				ActiveState.OnStateEntered(base.creatureAnimator);
				StartOfRound.Instance.ClientPlayerList.TryGetValue(NetworkManager.Singleton.LocalClientId, out var value);
				LogDebug($"CREATURE: {((Object)base.enemyType).name} #{self} STATE: {ActiveState} ON PLAYER: #{value} ({StartOfRound.Instance.allPlayerScripts[value].playerUsername})");
			}
		}

		[ServerRpc]
		internal 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(4082017191u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, PlayerID);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 4082017191u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				SetTargetClientRpc(PlayerID);
			}
		}

		[ClientRpc]
		internal 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)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3445875023u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, PlayerID);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3445875023u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				if (PlayerID == -1)
				{
					base.targetPlayer = null;
					LogDebug($"Clearing target on {this}");
				}
				else if ((Object)(object)StartOfRound.Instance.allPlayerScripts[PlayerID] == (Object)null)
				{
					LogDebug($"Index invalid! {this}");
				}
				else
				{
					base.targetPlayer = StartOfRound.Instance.allPlayerScripts[PlayerID];
					LogDebug($"{this} setting target to: {base.targetPlayer.playerUsername}");
				}
			}
		}

		protected override void __initializeVariables()
		{
			if (_playerNetVar == null)
			{
				throw new Exception("ModEnemyAI._playerNetVar cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)_playerNetVar).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_playerNetVar, "_playerNetVar");
			((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)_playerNetVar);
			((EnemyAI)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_ModEnemyAI()
		{
			//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
			NetworkManager.__rpc_func_table.Add(2082601448u, new RpcReceiveHandler(__rpc_handler_2082601448));
			NetworkManager.__rpc_func_table.Add(371120224u, new RpcReceiveHandler(__rpc_handler_371120224));
			NetworkManager.__rpc_func_table.Add(2465494607u, new RpcReceiveHandler(__rpc_handler_2465494607));
			NetworkManager.__rpc_func_table.Add(4108904228u, new RpcReceiveHandler(__rpc_handler_4108904228));
			NetworkManager.__rpc_func_table.Add(4082017191u, new RpcReceiveHandler(__rpc_handler_4082017191));
			NetworkManager.__rpc_func_table.Add(3445875023u, new RpcReceiveHandler(__rpc_handler_3445875023));
		}

		private static void __rpc_handler_2082601448(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;
				((ModEnemyAI)(object)target).SetAnimTriggerOnServerRpc(animTriggerOnServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_371120224(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;
				((ModEnemyAI)(object)target).SetAnimBoolOnServerRpc(name, state);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_2465494607(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 randomInt = default(int);
			ByteUnpacker.ReadValueBitPacked(reader, ref randomInt);
			target.__rpc_exec_stage = (__RpcExecStage)1;
			((ModEnemyAI)(object)target).TransitionStateServerRpc(stateName, randomInt);
			target.__rpc_exec_stage = (__RpcExecStage)0;
		}

		private static void __rpc_handler_4108904228(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 randomInt = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref randomInt);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((ModEnemyAI)(object)target).TransitionStateClientRpc(stateName, randomInt);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_4082017191(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;
				((ModEnemyAI)(object)target).SetTargetServerRpc(targetServerRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3445875023(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;
				((ModEnemyAI)(object)target).SetTargetClientRpc(targetClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "ModEnemyAI";
		}
	}
	public class Scp173AI : ModEnemyAI
	{
		private class RoamingPhase : AIBehaviorState
		{
			internal class FoundSomeone : AIStateTransition
			{
				public override bool CanTransitionBeTaken()
				{
					if (!((NetworkBehaviour)self).IsHost)
					{
						return false;
					}
					((EnemyAI)self).targetPlayer = self.CheckIfAPlayerHasLineOfSightToCollider();
					if ((Object)(object)((EnemyAI)self).targetPlayer != (Object)null)
					{
						Plugin.Logger.LogInfo((object)("Player " + ((Object)((EnemyAI)self).targetPlayer).name + " has a line of sight"));
						self.SetTargetClientRpc(((EnemyAI)self).targetPlayer.playerClientId);
						return true;
					}
					return false;
				}

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

			internal class NoOnelooked : AIStateTransition
			{
				private int _time = Plugin.BoundConfig.AmmountOfTimeWaiting.Value;

				public override bool CanTransitionBeTaken()
				{
					if (_time <= 0)
					{
						return true;
					}
					_time--;
					return false;
				}

				public override AIBehaviorState NextState()
				{
					self.OverrideState(new RoamingPhase());
					return new RoamingPhase();
				}
			}

			public override List<AIStateTransition> Transitions { get; set; } = new List<AIStateTransition>(2)
			{
				new FoundSomeone(),
				new NoOnelooked()
			};


			public override void OnStateEntered(Animator creatureAnimator)
			{
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: 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)
				if (!((NetworkBehaviour)self).NetworkManager.IsClient)
				{
					self.ResetTargetPlayerClientRpc();
					agent.ResetPath();
					GameObject[] insideAINodes = RoundManager.Instance.insideAINodes;
					Vector3 position;
					try
					{
						position = insideAINodes[Random.Range(0, RoundManager.Instance.insideAINodes.Length)].transform.position;
					}
					catch (Exception)
					{
						position = RoundManager.Instance.insideAINodes[0].transform.position;
						Plugin.Logger.LogError((object)"We had some problem finding specifics");
						throw;
					}
					if (self.AnyPlayerHasLineOfSightToPosition(position))
					{
						OnStateEntered(creatureAnimator);
						return;
					}
					agent.Warp(position);
					((EnemyAI)self).SyncPositionToClients();
				}
			}

			public override void AIInterval(Animator creatureAnimator)
			{
			}

			public override void OnStateExit(Animator creatureAnimator)
			{
			}
		}

		private class ChasePhase : AIBehaviorState
		{
			internal class SnappingNeck : AIStateTransition
			{
				private bool shouldSync = true;

				public float interval = Plugin.BoundConfig.LeapDistance.Value;

				public int maxIteration = Plugin.BoundConfig.NumberOfLeapPerFrame.Value;

				public override bool CanTransitionBeTaken()
				{
					//IL_002e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0033: Unknown result type (might be due to invalid IL or missing references)
					//IL_0034: 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_0041: Unknown result type (might be due to invalid IL or missing references)
					//IL_0051: Unknown result type (might be due to invalid IL or missing references)
					//IL_0073: Unknown result type (might be due to invalid IL or missing references)
					//IL_007f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0086: Unknown result type (might be due to invalid IL or missing references)
					//IL_008b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0092: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
					//IL_00d2: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
					//IL_0109: Unknown result type (might be due to invalid IL or missing references)
					//IL_0127: Unknown result type (might be due to invalid IL or missing references)
					//IL_0139: Unknown result type (might be due to invalid IL or missing references)
					//IL_01af: Unknown result type (might be due to invalid IL or missing references)
					//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
					//IL_016a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0182: Unknown result type (might be due to invalid IL or missing references)
					if (!((NetworkBehaviour)self).IsHost || self.AnyPlayerHasLineOfSightToCollider())
					{
						return false;
					}
					int num = 0;
					Vector3 val = ((Component)((EnemyAI)self).agent).transform.position;
					Vector3 val2 = val;
					float num2 = Vector3.Distance(((Component)self).transform.position, ((EnemyAI)self).agent.destination);
					NavMeshHit val4 = default(NavMeshHit);
					while (num2 > 0f || num < maxIteration)
					{
						num++;
						float num3 = Mathf.Min(interval, num2);
						Vector3 val3 = Vector3.MoveTowards(val, ((EnemyAI)self).agent.destination, num3);
						num2 -= num3;
						if (NavMesh.SamplePosition(val3, ref val4, interval, -1))
						{
							val3 = ((NavMeshHit)(ref val4)).position;
							if (!self.AnyPlayerHasLineOfSightToPosition(val3))
							{
								val2 = val3;
								shouldSync = true;
								if (Vector3.Distance(val3, ((Component)((EnemyAI)self).targetPlayer).transform.position) < 0.3f && !self.AnyPlayerHasLineOfSightToCollider())
								{
									if (shouldSync)
									{
										((EnemyAI)self).agent.Warp(val2);
										RotateAgentTowardsTarget(((Component)((EnemyAI)self).targetPlayer).transform.position);
										((EnemyAI)self).SyncPositionToClients();
										shouldSync = false;
									}
									Plugin.Logger.LogInfo((object)"Went to second phase through First condition");
									return true;
								}
								val = val3;
								continue;
							}
							if (shouldSync)
							{
								((EnemyAI)self).agent.Warp(val2);
								RotateAgentTowardsTarget(((Component)((EnemyAI)self).targetPlayer).transform.position);
								((EnemyAI)self).SyncPositionToClients();
								shouldSync = false;
							}
							return false;
						}
						Plugin.Logger.LogError((object)"Next position is not on the NavMesh.");
						break;
					}
					return false;
				}

				private void RotateAgentTowardsTarget(Vector3 targetPosition)
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					//IL_001b: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0023: Unknown result type (might be due to invalid IL or missing references)
					//IL_0030: Unknown result type (might be due to invalid IL or missing references)
					//IL_0031: Unknown result type (might be due to invalid IL or missing references)
					//IL_0036: 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_005d: Unknown result type (might be due to invalid IL or missing references)
					Vector3 val = targetPosition - ((Component)((EnemyAI)self).agent).transform.position;
					Vector3 normalized = ((Vector3)(ref val)).normalized;
					normalized.y = 0f;
					Quaternion val2 = Quaternion.LookRotation(normalized);
					((Component)((EnemyAI)self).agent).transform.rotation = Quaternion.Euler(0f, ((Quaternion)(ref val2)).eulerAngles.y, 0f);
				}

				public override AIBehaviorState NextState()
				{
					//IL_005f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0065: Unknown result type (might be due to invalid IL or missing references)
					Plugin.Logger.LogInfo((object)"We somehow triggered!");
					((EnemyAI)self).creatureSFX.PlayOneShot(self.snapNeck[Random.Range(0, self.snapNeck.Length)]);
					((EnemyAI)self).targetPlayer.DamagePlayer(Plugin.BoundConfig.AmmountOfDamage.Value, false, true, (CauseOfDeath)4, 1, false, default(Vector3));
					return new JustKilledSomeone();
				}
			}

			internal class LostTarget : AIStateTransition
			{
				public override bool CanTransitionBeTaken()
				{
					if (!((NetworkBehaviour)self).IsHost)
					{
						return false;
					}
					if ((Object)(object)((EnemyAI)self).targetPlayer == (Object)null)
					{
						return true;
					}
					PlayerControllerB targetPlayer = ((EnemyAI)self).targetPlayer;
					if (!targetPlayer.isPlayerControlled || !targetPlayer.isInsideFactory)
					{
						targetPlayer = self.CheckIfAPlayerHasLineOfSightToCollider();
						if ((Object)(object)targetPlayer != (Object)null)
						{
							((EnemyAI)self).targetPlayer = targetPlayer;
							return false;
						}
						return true;
					}
					return false;
				}

				public override AIBehaviorState NextState()
				{
					self.ResetTargetPlayerClientRpc();
					return new RoamingPhase();
				}
			}

			public override List<AIStateTransition> Transitions { get; set; } = new List<AIStateTransition>(2)
			{
				new SnappingNeck(),
				new LostTarget()
			};


			public override void OnStateEntered(Animator creatureAnimator)
			{
				((EnemyAI)self).creatureSFX.PlayOneShot(self.horror[Random.Range(0, self.horror.Length)]);
			}

			public override void AIInterval(Animator creatureAnimator)
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				if (!((NetworkBehaviour)self).IsHost)
				{
					return;
				}
				if (!((EnemyAI)self).targetPlayer.HasLineOfSightToPosition(((Component)self).transform.position, 45f, 60, -1f))
				{
					PlayerControllerB val = self.CheckIfAPlayerHasLineOfSightToCollider();
					if ((Object)(object)val != (Object)null)
					{
						((EnemyAI)self).targetPlayer = val;
						self.SetTargetClientRpc(val.playerClientId);
					}
				}
				((EnemyAI)self).SetDestinationToPosition(((Component)((EnemyAI)self).targetPlayer).transform.position, false);
			}

			public override void OnStateExit(Animator creatureAnimator)
			{
			}
		}

		private class JustKilledSomeone : AIBehaviorState
		{
			internal class Waiting : AIStateTransition
			{
				private int timeRemaining = Plugin.BoundConfig.TicksAfterKilling.Value;

				public override bool CanTransitionBeTaken()
				{
					if (timeRemaining <= 0)
					{
						return true;
					}
					timeRemaining--;
					return false;
				}

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

			public override List<AIStateTransition> Transitions { get; set; } = new List<AIStateTransition>(1)
			{
				new Waiting()
			};


			public override void OnStateEntered(Animator creatureAnimator)
			{
			}

			public override void AIInterval(Animator creatureAnimator)
			{
			}

			public override void OnStateExit(Animator creatureAnimator)
			{
			}
		}

		[SerializeField]
		public AudioClip[] horror;

		[SerializeField]
		public AudioClip[] snapNeck;

		public BoxCollider visionCollider;

		public override void Start()
		{
			self = this;
			InitialState = new RoamingPhase();
			((EnemyAI)self).agent.isStopped = true;
			((EnemyAI)self).agent.acceleration = 0f;
			base.Start();
		}

		public override void HitEnemy(int force = 1, PlayerControllerB? playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
		{
			((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitID);
		}

		public override void DoAIInterval()
		{
			base.DoAIInterval();
			Plugin.Logger.LogInfo((object)("Current behaviour : " + ActiveState.GetType().Name));
		}

		private PlayerControllerB? CheckIfAPlayerHasLineOfSightToCollider()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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)
			Bounds bounds = ((Collider)visionCollider).bounds;
			Vector3[] boundingBoxCheckPoints = GetBoundingBoxCheckPoints(bounds);
			foreach (PlayerControllerB item in RoundManager.Instance.playersManager.allPlayerScripts.Where((PlayerControllerB p) => p.isPlayerControlled && !p.isPlayerDead))
			{
				Vector3[] array = boundingBoxCheckPoints;
				foreach (Vector3 val in array)
				{
					if (item.HasLineOfSightToPosition(val, 45f, 60, -1f))
					{
						return item;
					}
				}
			}
			return null;
		}

		private bool AnyPlayerHasLineOfSightToCollider()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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)
			Bounds bounds = ((Collider)visionCollider).bounds;
			Vector3[] boundingBoxCheckPoints = GetBoundingBoxCheckPoints(bounds);
			foreach (PlayerControllerB item in RoundManager.Instance.playersManager.allPlayerScripts.Where((PlayerControllerB p) => p.isPlayerControlled && !p.isPlayerDead))
			{
				Vector3[] array = boundingBoxCheckPoints;
				foreach (Vector3 val in array)
				{
					if (item.HasLineOfSightToPosition(val, 45f, 60, -1f))
					{
						return true;
					}
				}
			}
			return false;
		}

		private bool AnyPlayerHasLineOfSightToPosition(Vector3 targetPosition)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			foreach (PlayerControllerB item in RoundManager.Instance.playersManager.allPlayerScripts.Where((PlayerControllerB p) => p.isPlayerControlled && !p.isPlayerDead))
			{
				if (item.HasLineOfSightToPosition(targetPosition, 45f, 60, -1f))
				{
					return true;
				}
			}
			return false;
		}

		private Vector3[] GetBoundingBoxCheckPoints(Bounds bounds)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			return (Vector3[])(object)new Vector3[8]
			{
				((Bounds)(ref bounds)).center,
				((Bounds)(ref bounds)).min,
				((Bounds)(ref bounds)).max,
				new Vector3(((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.z),
				new Vector3(((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.y, ((Bounds)(ref bounds)).min.z),
				new Vector3(((Bounds)(ref bounds)).max.x, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).min.z),
				new Vector3(((Bounds)(ref bounds)).max.x, ((Bounds)(ref bounds)).max.y, ((Bounds)(ref bounds)).min.z),
				new Vector3(((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.y, ((Bounds)(ref bounds)).max.z)
			};
		}

		[ClientRpc]
		private void SetTargetClientRpc(ulong clientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3912702345u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, clientId);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3912702345u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				ulong clientId2 = clientId;
				((EnemyAI)this).targetPlayer = ((IEnumerable<PlayerControllerB>)RoundManager.Instance.playersManager.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB p) => p.isPlayerControlled && !p.isPlayerDead && p.playerClientId == clientId2));
			}
		}

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

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

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

		private static void __rpc_handler_3912702345(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)
			{
				ulong targetClientRpc = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref targetClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((Scp173AI)(object)target).SetTargetClientRpc(targetClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

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

		protected internal override string __getTypeName()
		{
			return "Scp173AI";
		}
	}
}
namespace SCP173.Configuration
{
	public class PluginConfig
	{
		public ConfigEntry<int> SpawnWeight;

		public ConfigEntry<int> TicksAfterKilling;

		public ConfigEntry<int> AmmountOfDamage;

		public ConfigEntry<float> LeapDistance;

		public ConfigEntry<int> NumberOfLeapPerFrame;

		public ConfigEntry<int> AmmountOfTimeWaiting;

		public PluginConfig(ConfigFile cfg)
		{
			SpawnWeight = cfg.Bind<int>("General", "Spawn weight", 25, "The spawn chance weight for SCP173, relative to other existing enemies.\nGoes up from 0, lower is more rare, 100 and up is very common.");
			TicksAfterKilling = cfg.Bind<int>("Behaviour", "Frame after killing", 1000, "How much time in frames will SCP 173 stop moving and doing anything after killing a player");
			AmmountOfDamage = cfg.Bind<int>("Behaviour", "Amount of damage he does on contact", 100, "At 100, he will 1 shot you. Put it to less if you want him to be way more forgiving");
			LeapDistance = cfg.Bind<float>("Performance", "Distance for each TP", 1f, "SCP 173 works by teleporting a small distance at a super fast speed, each time detecting if he is seen in his new position. The smaller the interval, the more precise SCP173 will be in his teleport, but this also mean that he won't kill you on the same frame you looked away if to small");
			NumberOfLeapPerFrame = cfg.Bind<int>("Performance", "Number Of TP Iteration per frame", 100, "Multiply this value by the Distance for each TP value to get the maximum distance he can do per frame. Do note that this value can affect performance if set to high. Putting it to low will lead to slower speed.");
			AmmountOfTimeWaiting = cfg.Bind<int>("Behaviour", "Number Of TP Iteration per frame", 1500, "SCP 173 works by teleporting around the facility, waiting a few frame for someone to see it, and then teleporting somewhere else. This value represent how much time will he wait at the same location in frame");
			ClearUnusedEntries(cfg);
		}

		private void ClearUnusedEntries(ConfigFile cfg)
		{
			PropertyInfo property = ((object)cfg).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(cfg, null);
			dictionary.Clear();
			cfg.Save();
		}
	}
}
namespace ProjectSCP.SCP173.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}