Decompiled source of LCBeatBoxerMod v0.3.4

LCBeatBoxerMod.dll

Decompiled a month ago
using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using HarmonyLib.Tools;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Animations.Rigging;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
public class HitboxScript : MonoBehaviour
{
	private static ManualLogSource Logger = Plugin.Logger;

	private static int debugLogLevel = -1;

	[Header("Manager")]
	public bool isManager;

	public EnemyAI mainScript;

	public HitboxScript[] allHitboxes;

	[Space(3f)]
	[Header("Hitbox")]
	public Collider hitboxCollider;

	public HitboxScript managerHitbox;

	[Space]
	public int attackPower;

	public Vector3 attackForce;

	public int deathAnimIndex;

	[Space]
	public bool canHitPlayers;

	public bool canHitEnemies;

	private List<int> hitPlayerIDs = new List<int>();

	private List<int> hitEnemyIDs = new List<int>();

	private void Start()
	{
		if (debugLogLevel == -1)
		{
			debugLogLevel = Plugin.DebugLogLevel();
		}
		if (!isManager)
		{
			return;
		}
		managerHitbox = this;
		HitboxScript[] array = allHitboxes;
		foreach (HitboxScript hitboxScript in array)
		{
			hitboxScript.hitboxCollider.enabled = false;
			hitboxScript.managerHitbox = this;
			if ((Object)(object)mainScript != (Object)null)
			{
				hitboxScript.mainScript = mainScript;
			}
			else
			{
				Log(((Object)hitboxScript).name + " started without mainTransform, using own transform to calculate directions and cannot play punch SFX", 2);
			}
		}
	}

	private void OnTriggerEnter(Collider other)
	{
		PerformAttackOnHitbox(other);
	}

	private void PerformAttackOnHitbox(Collider other)
	{
		//IL_0071: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: Unknown result type (might be due to invalid IL or missing references)
		if (canHitPlayers && ((Component)other).CompareTag("Player"))
		{
			PlayerControllerB component = ((Component)other).GetComponent<PlayerControllerB>();
			if (!PerformHitPlayerCheck(component) || !((Object)(object)component == (Object)(object)GameNetworkManager.Instance.localPlayerController))
			{
				return;
			}
			Log($"{((Object)this).name} PerformAttack({other}) // hitPlayer: {component} | attackPower {attackPower} | attackForce {attackForce} | deathAnimIndex {deathAnimIndex}");
			Transform val = (((Object)(object)mainScript != (Object)null) ? ((Component)mainScript).transform : ((Component)this).transform);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(val.forward.x * attackForce.z, attackForce.y, val.forward.z * attackForce.x);
			if (attackPower > 0)
			{
				component.DamagePlayer(attackPower, true, true, (CauseOfDeath)6, deathAnimIndex, false, val2);
				if ((Object)(object)mainScript == (Object)null)
				{
					Log("mainScript on hitbox " + ((Object)this).name + " is null, cannot call enemy-dependent functionality", 2);
				}
				else if (mainScript is TheBeatAI)
				{
					_ = mainScript;
				}
				else if (mainScript is TheBoxerAI)
				{
					TheBoxerAI obj = mainScript as TheBoxerAI;
					obj.PlaySFX(obj.punchSFX);
				}
			}
			if (!component.isPlayerDead)
			{
				component.externalForceAutoFade = val2 * 2f;
			}
		}
		else
		{
			if (attackPower <= 0 || !canHitEnemies || !((Component)other).CompareTag("Enemy"))
			{
				return;
			}
			EnemyAICollisionDetect component2 = ((Component)other).GetComponent<EnemyAICollisionDetect>();
			if (!PerformHitEnemyCheck(component2) || !((NetworkBehaviour)mainScript).IsOwner)
			{
				return;
			}
			int num = attackPower / 10;
			Log($"{((Object)this).name} PerformAttack({other}) // hitEnemy: {component2.mainScript} | enemyAttackPower {num}");
			if (!((Object)(object)mainScript != (Object)null))
			{
				_ = ((Component)this).transform;
			}
			else
			{
				_ = ((Component)mainScript).transform;
			}
			if (num > 0)
			{
				component2.mainScript.HitEnemyOnLocalClient(num, default(Vector3), (PlayerControllerB)null, true, -1);
				if ((Object)(object)mainScript == (Object)null)
				{
					Log("mainScript on hitbox " + ((Object)this).name + " is null, cannot call enemy-dependent functionality", 2);
				}
				else if (mainScript is TheBeatAI)
				{
					_ = mainScript;
				}
				else if (mainScript is TheBoxerAI)
				{
					TheBoxerAI obj2 = mainScript as TheBoxerAI;
					obj2.PlaySFX(obj2.punchSFX);
				}
			}
		}
	}

	private bool PerformHitPlayerCheck(PlayerControllerB hitPlayer)
	{
		if ((Object)(object)hitPlayer == (Object)null || !hitPlayer.isPlayerControlled)
		{
			return false;
		}
		int item = (int)hitPlayer.playerClientId;
		bool num = !hitPlayerIDs.Contains(item);
		if (num)
		{
			hitPlayerIDs.Add(item);
			if (!managerHitbox.hitPlayerIDs.Contains(item))
			{
				managerHitbox.hitPlayerIDs.Add(item);
			}
		}
		return num;
	}

	private bool PerformHitEnemyCheck(EnemyAICollisionDetect hitEnemy)
	{
		if ((Object)(object)mainScript == (Object)null || (Object)(object)hitEnemy == (Object)null || (Object)(object)hitEnemy.mainScript == (Object)null)
		{
			return false;
		}
		EnemyAI val = hitEnemy.mainScript;
		if ((Object)(object)mainScript == (Object)(object)val || val.isEnemyDead || mainScript.isOutside != val.isOutside)
		{
			return false;
		}
		int enemyIndexInRoundManager = Plugin.GetEnemyIndexInRoundManager(val);
		bool num = !hitEnemyIDs.Contains(enemyIndexInRoundManager);
		if (num)
		{
			hitEnemyIDs.Add(enemyIndexInRoundManager);
			if (!managerHitbox.hitEnemyIDs.Contains(enemyIndexInRoundManager))
			{
				managerHitbox.hitEnemyIDs.Add(enemyIndexInRoundManager);
			}
		}
		return num;
	}

	public void SetEnemyVulnerable(string setVulnerableTo)
	{
		if ((Object)(object)mainScript == (Object)null)
		{
			Log("called SetEnemyVulnerable on " + ((Object)this).name + " with null mainScript", 2);
			return;
		}
		LogAI($"{((Object)this).name}: SetEnemyVulnerable({setVulnerableTo}) on {mainScript} #{((NetworkBehaviour)mainScript).NetworkObjectId}");
		if (mainScript is TheBeatAI)
		{
			_ = mainScript;
		}
		else if (mainScript is TheBoxerAI)
		{
			TheBoxerAI theBoxerAI = mainScript as TheBoxerAI;
			if ((Object)(object)theBoxerAI != (Object)null)
			{
				theBoxerAI.SetEnemyVulnerable(Plugin.ConvertToBool(setVulnerableTo));
			}
		}
	}

	public void SetEnemyInSpecialAnimTo(string setInSpecialAnimationTo)
	{
		if ((Object)(object)mainScript == (Object)null)
		{
			Log("called SetEnemyInSpecialAnimTo on " + ((Object)this).name + " with null mainScript", 2);
			return;
		}
		bool flag = Plugin.ConvertToBool(setInSpecialAnimationTo);
		LogAI($"{((Object)this).name}: SetEnemyInSpecialAnimTo({flag}) on {mainScript} #{((NetworkBehaviour)mainScript).NetworkObjectId}");
		if (mainScript is TheBeatAI)
		{
			(mainScript as TheBeatAI).SetEnemyInSpecialAnimation(flag);
		}
		else if (mainScript is TheBoxerAI)
		{
			(mainScript as TheBoxerAI).SetEnemyInSpecialAnimation(flag);
		}
	}

	public void OnAttackStart()
	{
		if ((Object)(object)mainScript == (Object)null)
		{
			Log("called OnAttackStart on " + ((Object)this).name + " with null mainScript", 2);
			return;
		}
		Log(((Object)this).name + ": OnAttackStart()");
		managerHitbox.hitPlayerIDs.Clear();
		managerHitbox.hitEnemyIDs.Clear();
		HitboxScript[] array = allHitboxes;
		foreach (HitboxScript hitboxScript in array)
		{
			LogAI($"clearing hitIDs on {hitboxScript}");
			hitboxScript.hitPlayerIDs.Clear();
			hitboxScript.hitEnemyIDs.Clear();
		}
	}

	public void DisableAllHitboxes()
	{
		//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)
		LogAI("called DisableAllHitboxes on " + ((Object)this).name);
		if (isManager)
		{
			HitboxScript[] array = allHitboxes;
			foreach (HitboxScript obj in array)
			{
				obj.attackPower = 0;
				obj.deathAnimIndex = 0;
				obj.attackForce = Vector3.zero;
				obj.hitboxCollider.enabled = false;
			}
		}
	}

	public void PlaySFXOnEnemy(int clipCase)
	{
		if ((Object)(object)mainScript == (Object)null)
		{
			Log("called PlaySFXOnEnemy on " + ((Object)this).name + " with null mainScript", 2);
			return;
		}
		LogAI($"{((Object)this).name}: PlaySFXOnEnemy({clipCase}) on {mainScript} #{((NetworkBehaviour)mainScript).NetworkObjectId}");
		if (mainScript is TheBeatAI)
		{
			(mainScript as TheBeatAI).PlaySFX(null, audibleNoise: true, isAudience: false, sync: false, clipCase);
		}
		else if (mainScript is TheBoxerAI)
		{
			(mainScript as TheBoxerAI).PlaySFX(null, audibleNoise: true, isAudience: false, sync: false, clipCase);
		}
	}

	public void PlayAudienceOnEnemy(int clipCase)
	{
		if ((Object)(object)mainScript == (Object)null)
		{
			Log("called PlayAudienceOnEnemy on " + ((Object)this).name + " with null mainScript", 2);
			return;
		}
		LogAI($"{((Object)this).name}: PlayAudienceOnEnemy({clipCase}) on {mainScript} #{((NetworkBehaviour)mainScript).NetworkObjectId}");
		if (mainScript is TheBeatAI)
		{
			(mainScript as TheBeatAI).PlaySFX(null, audibleNoise: true, isAudience: true, sync: false, clipCase);
		}
		else if (mainScript is TheBoxerAI)
		{
			(mainScript as TheBoxerAI).PlaySFX(null, audibleNoise: true, isAudience: true, sync: false, clipCase);
		}
	}

	public void SpecialAnimEvent(int eventCase)
	{
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)mainScript == (Object)null)
		{
			Log("called SpecialAnimEvent on " + ((Object)this).name + " with null mainScript", 2);
			return;
		}
		LogAI($"{((Object)this).name}: SpecialAnimEvent({eventCase}) on {mainScript} #{((NetworkBehaviour)mainScript).NetworkObjectId}");
		if (mainScript is TheBeatAI)
		{
			_ = mainScript;
		}
		else
		{
			if (!(mainScript is TheBoxerAI))
			{
				return;
			}
			TheBoxerAI theBoxerAI = mainScript as TheBoxerAI;
			switch (eventCase)
			{
			default:
				theBoxerAI.SetSpotlight(theBoxerAI.enemySpotlight, sync: false, enableLight: false);
				break;
			case 1:
				theBoxerAI.SpawnShovelAndSync();
				break;
			case 2:
				theBoxerAI.EndGiveShovelAnim();
				break;
			case 3:
				mainScript.enemyType.canBeStunned = false;
				StunGrenadeItem.StunExplosion(((Component)mainScript).transform.position, true, 1f, 7.5f, 1f, false, (PlayerControllerB)null, (PlayerControllerB)null, 0f);
				mainScript.enemyType.canBeStunned = true;
				break;
			case 4:
			{
				PlayerControllerB localPlayerController = StartOfRound.Instance.localPlayerController;
				if (!localPlayerController.isPlayerControlled || localPlayerController.isInsideFactory || (Object)(object)localPlayerController.inAnimationWithEnemy != (Object)null)
				{
					break;
				}
				float num = Vector3.Distance(((Component)localPlayerController).transform.position, ((Component)mainScript).transform.position);
				if (num > 10f)
				{
					break;
				}
				Vector3 val = mainScript.eye.forward * (num / 1.1f) + Vector3.up * 33f;
				if (num < 2f)
				{
					localPlayerController.DamagePlayer(10, true, true, (CauseOfDeath)3, 0, false, val);
					int item = (int)localPlayerController.playerClientId;
					if (!managerHitbox.hitPlayerIDs.Contains(item))
					{
						managerHitbox.hitPlayerIDs.Add(item);
					}
				}
				if (!localPlayerController.isPlayerDead)
				{
					localPlayerController.externalForceAutoFade += val;
				}
				break;
			}
			}
		}
	}

	public void CheckAttackHitOnManager()
	{
		if ((Object)(object)mainScript == (Object)null)
		{
			Log("called CheckAttackHitOnManager on " + ((Object)this).name + " with null mainScript", 2);
			return;
		}
		bool flag = false;
		if (mainScript is TheBeatAI)
		{
			_ = mainScript;
		}
		else if (mainScript is TheBoxerAI)
		{
			TheBoxerAI theBoxerAI = mainScript as TheBoxerAI;
			if ((Object)(object)theBoxerAI != (Object)null && ((NetworkBehaviour)theBoxerAI).IsOwner)
			{
				Log($"{theBoxerAI} hit {managerHitbox.hitPlayerIDs.Count} PLAYERS and {managerHitbox.hitEnemyIDs.Count} ENEMIES", 1);
				if (managerHitbox.hitPlayerIDs.Count != 0)
				{
					flag = theBoxerAI.OnHitSuccessful(managerHitbox.hitPlayerIDs.ToArray(), forPlayers: true);
				}
				if (!flag && hitEnemyIDs.Count != 0)
				{
					flag = theBoxerAI.OnHitSuccessful(managerHitbox.hitEnemyIDs.ToArray(), forPlayers: false);
				}
			}
		}
		if (flag)
		{
			managerHitbox.hitPlayerIDs.Clear();
			managerHitbox.hitEnemyIDs.Clear();
		}
	}

	public void CheckAttackHit(int hitboxIndex)
	{
		if ((Object)(object)mainScript == (Object)null)
		{
			Log("called CheckAttackHit on " + ((Object)this).name + " with null mainScript", 2);
		}
		else if (hitboxIndex < 0 || hitboxIndex >= allHitboxes.Length)
		{
			Log($"called CheckAttackHitOnHitbox with invalid hitboxIndex {hitboxIndex}", 2);
		}
		else
		{
			allHitboxes[hitboxIndex].CheckAttackHitOnHitbox(mainScript);
		}
	}

	private void CheckAttackHitOnHitbox(EnemyAI enemyScript)
	{
		bool flag = false;
		if (!(enemyScript is TheBeatAI) && enemyScript is TheBoxerAI)
		{
			TheBoxerAI theBoxerAI = enemyScript as TheBoxerAI;
			if ((Object)(object)theBoxerAI != (Object)null && ((NetworkBehaviour)theBoxerAI).IsOwner)
			{
				Log($"{theBoxerAI} hit {hitPlayerIDs.Count} PLAYERS and {hitEnemyIDs.Count} ENEMIES", 1);
				if (hitPlayerIDs.Count != 0)
				{
					flag = theBoxerAI.OnHitSuccessful(hitPlayerIDs.ToArray(), forPlayers: true);
				}
				if (!flag && hitEnemyIDs.Count != 0)
				{
					flag = theBoxerAI.OnHitSuccessful(hitEnemyIDs.ToArray(), forPlayers: false);
				}
			}
		}
		if (flag)
		{
			hitPlayerIDs.Clear();
			hitEnemyIDs.Clear();
		}
	}

	private void Log(string message, int type = 0)
	{
		if (debugLogLevel >= 1)
		{
			switch (type)
			{
			case 0:
				Logger.LogDebug((object)message);
				break;
			case 1:
				Logger.LogInfo((object)message);
				break;
			case 2:
				Logger.LogWarning((object)message);
				break;
			case 3:
				Logger.LogError((object)message);
				break;
			}
		}
	}

	private void LogAI(string message, int type = 0)
	{
		if (debugLogLevel >= 2)
		{
			switch (type)
			{
			case 0:
				Logger.LogDebug((object)message);
				break;
			case 1:
				Logger.LogInfo((object)message);
				break;
			case 2:
				Logger.LogWarning((object)message);
				break;
			case 3:
				Logger.LogError((object)message);
				break;
			}
		}
	}
}
public class TheBeatAI : EnemyAI
{
	private static ManualLogSource Logger = Plugin.Logger;

	private static int debugLogLevel = -1;

	private float tempTimer;

	private bool setItemLocally;

	private bool reachedHideSpot;

	private bool everyoneOutside;

	private bool seenDuringThisAmbush;

	private int timesStartedAmbush;

	private bool fakeAudioThisAmbush;

	private bool enraged;

	private bool attemptingItemRetrieve;

	private int hpAmbushStart;

	private float timeLastCollisionLocalPlayer;

	private float timeLastVoiceChatLocalPlayer;

	private float timeLastLookingAt;

	private Transform fleeToWhileCalculating;

	private Vector3 lookingAt;

	[Space(3f)]
	[Header("MOVEMENT")]
	public float roamSpeed;

	public float hideSpeed;

	public float chaseSpeed;

	public float enragedSpeed;

	public AISearchRoutine roamingSearch;

	[Tooltip("Low numbers are closer to the enemy transform, high numbers are closer to the point it finds for players/entrances.")]
	[Range(0f, 1f)]
	public float lerpMidpoint;

	[Space(3f)]
	[Header("SENSES")]
	public int seeDistance;

	public float seeWidth;

	public int[] awarenessDistancePerState;

	public float noiseThreshold;

	public float noiseLookThreshold;

	public float noiseDistanceDropoffPower;

	public Transform turnCompass;

	public Collider killBox;

	[Space(3f)]
	[Header("SFX")]
	[Header("Enemy")]
	public AudioSource realAudio;

	public AudioClip intimidateSFX;

	public AudioClip punchHitSFX;

	public AudioClip punchMissSFX;

	public AudioClip caughtSFX;

	public AudioClip reelSFX;

	[Range(0f, 1f)]
	public float footstepsVolume;

	[Range(0f, 1f)]
	public float runningVolume;

	public PlayAudioAnimationEvent animationAudio;

	[Header("Audience")]
	public AudioSource crowdVoices;

	public static AudioSource beatAudience;

	public AudioClip successCheer;

	[Space(3f)]
	[Header("ITEM")]
	public Item itemToSpawn;

	public BeatAudioItem linkedItem;

	public Transform holdItemParentObject;

	public Coroutine pickItemPositionCoroutine;

	[Space(3f)]
	[Header("PARAMETERS")]
	public float maxSearchDistance;

	public float minDistanceBetweenFarawayNodes;

	public float maxDistanceBetweenFarawayNodes;

	public float verticalOffsetDropoffDivider;

	public float maxPlayerDistanceToPath;

	public float maxItemSpawnTime;

	public float maxHideSpotTime;

	public float minNodesNecessary;

	public float collisionCooldown;

	public int turnPlayerIterations;

	public override void Start()
	{
		((EnemyAI)this).Start();
		hpAmbushStart = base.enemyHP;
		if ((Object)(object)beatAudience == (Object)null)
		{
			((Component)crowdVoices).transform.SetParent(RoundManager.Instance.spawnedScrapContainer);
			beatAudience = crowdVoices;
		}
		if (debugLogLevel == -1)
		{
			debugLogLevel = Plugin.DebugLogLevel();
			base.DebugEnemy = debugLogLevel >= 1;
			base.debugEnemyAI = debugLogLevel >= 2;
		}
		if (((NetworkBehaviour)this).IsServer)
		{
			SpawnItemServerRpc(holdItemAfterSpawn: true);
		}
	}

	public override void Update()
	{
		//IL_0031: 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_006c: 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_008c: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
		((EnemyAI)this).Update();
		if (base.isEnemyDead || !base.ventAnimationFinished)
		{
			return;
		}
		if ((Object)(object)base.inSpecialAnimationWithPlayer != (Object)null)
		{
			DetectNewSighting(((Component)base.inSpecialAnimationWithPlayer).transform.position);
		}
		if (Time.realtimeSinceStartup - timeLastLookingAt < 1f)
		{
			turnCompass.LookAt(lookingAt);
			((Component)this).transform.eulerAngles = new Vector3(((Component)this).transform.eulerAngles.x, turnCompass.eulerAngles.y, ((Component)this).transform.eulerAngles.z);
		}
		switch (base.currentBehaviourStateIndex)
		{
		case 0:
			base.syncMovementSpeed = 0.42f;
			animationAudio.playAudibleNoise = false;
			break;
		case 1:
			base.syncMovementSpeed = 0.13f;
			animationAudio.playAudibleNoise = false;
			if (StartOfRound.Instance.localPlayerController.HasLineOfSightToPosition(base.eye.position, 45f, 60, -1f, -1))
			{
				StartOfRound.Instance.localPlayerController.IncreaseFearLevelOverTime(0.4f, 0.5f);
			}
			break;
		case 2:
			base.syncMovementSpeed = 0.19f;
			animationAudio.playAudibleNoise = true;
			break;
		}
		if (((NetworkBehaviour)this).IsOwner && (base.currentBehaviourStateIndex == 1 || (setItemLocally && (!reachedHideSpot || everyoneOutside)) || (base.currentBehaviourStateIndex == 2 && (Object)(object)base.targetPlayer == (Object)null)))
		{
			tempTimer += Time.deltaTime;
		}
	}

	public override void DoAIInterval()
	{
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_028e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0354: Unknown result type (might be due to invalid IL or missing references)
		//IL_0372: 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_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: 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)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_089c: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_050e: Unknown result type (might be due to invalid IL or missing references)
		//IL_051e: Unknown result type (might be due to invalid IL or missing references)
		//IL_063a: Unknown result type (might be due to invalid IL or missing references)
		//IL_064c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0657: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f5: Unknown result type (might be due to invalid IL or missing references)
		((EnemyAI)this).DoAIInterval();
		if (base.isEnemyDead || !base.ventAnimationFinished || StartOfRound.Instance.allPlayersDead)
		{
			return;
		}
		if (tempTimer == 99f)
		{
			ResetVariables(moveToAmbush: true);
			return;
		}
		base.useSecondaryAudiosOnAnimatedObjects = base.currentBehaviourStateIndex == 2;
		switch (base.currentBehaviourStateIndex)
		{
		case 0:
			if (setItemLocally)
			{
				if (roamingSearch.inProgress)
				{
					Log("STOP search // ROAM (0)");
					((EnemyAI)this).StopSearch(roamingSearch, true);
				}
				if (!reachedHideSpot)
				{
					if ((Object)(object)base.favoriteSpot != (Object)null)
					{
						LogAI("going to HIDE");
						((EnemyAI)this).SetDestinationToPosition(base.favoriteSpot.position, false);
						base.agent.speed = hideSpeed;
						if (tempTimer > maxHideSpotTime)
						{
							Log("TIMER: Unable to reach favoriteSpot, pausing", 3);
							OnReachHideSpot();
							tempTimer = 0f;
						}
						else if (Vector3.Distance(((Component)this).transform.position, base.favoriteSpot.position) < 1f)
						{
							Log("reached hide spot, starting sound");
							OnReachHideSpot();
						}
					}
					break;
				}
				if (PlayersOutside(onlyTargetPlayer: false, unlimitedAwareness: true))
				{
					if (tempTimer > 10f)
					{
						Log($"currentBehaviourStateIndex: {base.currentBehaviourStateIndex} | reachedHideSpot: {reachedHideSpot} | tempTimer: {tempTimer}");
						ResetVariables();
						break;
					}
				}
				else
				{
					tempTimer = 0f;
				}
				PlayerControllerB val = AnyPlayerHasLineOfSight();
				if ((Object)(object)val != (Object)null)
				{
					Log($"playerSeeing: {val} | reachedHideSpot: {reachedHideSpot} | targetPlayer & moving: {base.targetPlayer} | {base.movingTowardsTargetPlayer}");
					base.targetPlayer = val;
					GoIntoChase();
				}
				else
				{
					PlayerControllerB closestPlayer = ((EnemyAI)this).GetClosestPlayer(true, false, false);
					if ((Object)(object)closestPlayer != (Object)null && Vector3.Distance(((Component)this).transform.position, ((Component)closestPlayer).transform.position) < 5f)
					{
						Log("distance between Enemy and ClosestPlayer below 5, moving to chase");
						base.targetPlayer = closestPlayer;
						GoIntoChase();
					}
				}
			}
			else if (!roamingSearch.inProgress)
			{
				Log("START search // ROAM (0)");
				((EnemyAI)this).StartSearch(GetMidpoint(), roamingSearch);
				SetAnimation("WalkHunched");
				base.agent.speed = roamSpeed;
				ToggleAudioServerRpc(footstepsVolume, roamSpeed);
			}
			else
			{
				PlayerControllerB val2 = ((EnemyAI)this).CheckLineOfSightForPlayer(seeWidth, seeDistance, -1);
				if ((Object)(object)val2 != (Object)null)
				{
					Log("enemy spotted player, moving to state 1");
					MoveToAmbush(val2);
				}
			}
			break;
		case 1:
		{
			if (roamingSearch.inProgress)
			{
				Log("STOP search // ROAM (1)");
				((EnemyAI)this).StopSearch(roamingSearch, true);
			}
			if (base.inSpecialAnimation)
			{
				base.agent.speed = 0f;
				break;
			}
			PlayerControllerB val3 = AnyPlayerHasLineOfSight(null, ((Component)this).transform.position);
			if ((Object)(object)val3 != (Object)null)
			{
				DetectNewSighting(((Component)val3).transform.position, lookImmediately: true);
				Log($"playerSeeingInHide {val3}");
				base.agent.speed = (base.inSpecialAnimation ? 0f : chaseSpeed);
				if (!seenDuringThisAmbush && !enraged)
				{
					seenDuringThisAmbush = true;
					enraged = true;
					((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer);
					Log("CHASE PLAYER UNTIL OUT OF SIGHT!!!", 3);
					ToggleAudioServerRpc(runningVolume, base.agent.speed);
					base.agent.speed = 0f;
					SetAnimation("Intimidate");
					SetAnimation(null, sync: true, "WalkUprightSpeedMultiplier", 3f);
					break;
				}
			}
			else if (enraged)
			{
				Log("player lost sight during ambush chase");
				enraged = false;
				ToggleAudioServerRpc(0f, hideSpeed);
				SetAnimation(null, sync: true, "WalkUprightSpeedMultiplier", 5f);
			}
			if (!enraged && realAudio.volume > 0f)
			{
				ToggleAudioServerRpc(0f, hideSpeed);
			}
			if (attemptingItemRetrieve && !enraged)
			{
				if (!GetValidItemRetrieve())
				{
					Log("GetValidItemRetrieve() interrupted attemptingItemRetrieve!!! setting up for new item!", 1);
					SeverItemLinkServerRpc();
					attemptingItemRetrieve = false;
					break;
				}
				LogAI($"Trying to retrieve item {linkedItem}!");
				((EnemyAI)this).SetDestinationToPosition(((Component)linkedItem).transform.position, false);
				if (Vector3.Distance(holdItemParentObject.position, ((Component)linkedItem).transform.position) < 4f)
				{
					Log($"owner grabbing {linkedItem} #{((NetworkBehaviour)linkedItem).NetworkObjectId}", 1);
					GrabLinkedItem();
					attemptingItemRetrieve = false;
				}
			}
			if ((Object)(object)base.targetNode == (Object)null)
			{
				if (pickItemPositionCoroutine == null)
				{
					pickItemPositionCoroutine = ((MonoBehaviour)this).StartCoroutine(PickItemPosition());
				}
				base.agent.speed = hideSpeed;
				if (!attemptingItemRetrieve)
				{
					if ((Object)(object)fleeToWhileCalculating == (Object)null)
					{
						fleeToWhileCalculating = GetFleeToWhileCalculating(val3);
					}
					else if (!enraged)
					{
						LogAI("trying to hide out of sight");
						base.agent.speed = hideSpeed;
						((EnemyAI)this).SetDestinationToPosition(fleeToWhileCalculating.position, false);
					}
				}
			}
			else
			{
				if (enraged || attemptingItemRetrieve)
				{
					break;
				}
				if (!fakeAudioThisAmbush)
				{
					Log("spawn by: MODULO", 2);
					SpawnItemAndHide();
					break;
				}
				((EnemyAI)this).SetDestinationToPosition(base.targetNode.position, true);
				if (Vector3.Distance(((Component)this).transform.position, base.targetNode.position) < 1f)
				{
					Log("spawn by: DISTANCE");
					SpawnItemAndHide();
				}
				else if (tempTimer > maxItemSpawnTime)
				{
					Log("spawn by: TIMER", 3);
					SpawnItemAndHide();
				}
			}
			break;
		}
		case 2:
		{
			if (roamingSearch.inProgress)
			{
				Log("STOP search // ROAM (2)");
				((EnemyAI)this).StopSearch(roamingSearch, true);
			}
			PlayerControllerB validPlayerHoldingItem = GetValidPlayerHoldingItem();
			bool unlimitedAwareness = enraged || (Object)(object)validPlayerHoldingItem != (Object)null;
			if (PlayersOutside(onlyTargetPlayer: true, unlimitedAwareness) && tempTimer > 5f)
			{
				ResetVariables();
				break;
			}
			if (!base.inSpecialAnimation)
			{
				if (base.stunNormalizedTimer > 0f)
				{
					base.agent.speed = 0f;
					if (realAudio.volume != 0f)
					{
						ToggleAudioServerRpc(0f, 0f);
					}
					if ((Object)(object)base.stunnedByPlayer != (Object)null)
					{
						base.targetPlayer = base.stunnedByPlayer;
					}
					Log($"stunned: volume: {realAudio.volume} | targetPlayer {base.targetPlayer}");
					break;
				}
				base.agent.speed = (enraged ? enragedSpeed : chaseSpeed);
				if ((Object)(object)base.targetPlayer == (Object)null || ((Object)(object)validPlayerHoldingItem != (Object)null && (Object)(object)base.targetPlayer != (Object)(object)validPlayerHoldingItem))
				{
					if ((Object)(object)validPlayerHoldingItem != (Object)null)
					{
						base.targetPlayer = validPlayerHoldingItem;
					}
					else
					{
						base.targetPlayer = ((EnemyAI)this).GetClosestPlayer(true, false, false);
					}
				}
				else if (PlayersOutside(onlyTargetPlayer: true, unlimitedAwareness))
				{
					tempTimer = 0f;
					base.targetPlayer = null;
					base.movingTowardsTargetPlayer = false;
				}
				Log($"going to PLAYER ({base.targetPlayer})");
				ChaseNewPlayer(base.targetPlayer);
				if (realAudio.volume != runningVolume)
				{
					ToggleAudioServerRpc(runningVolume, base.agent.speed);
				}
			}
			else
			{
				base.agent.speed = 0f;
			}
			if ((Object)(object)base.targetPlayer == (Object)(object)StartOfRound.Instance.localPlayerController && Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < realAudio.maxDistance * 0.7f)
			{
				base.targetPlayer.JumpToFearLevel(0.7f, true);
			}
			break;
		}
		}
	}

	public override void FinishedCurrentSearchRoutine()
	{
		((EnemyAI)this).FinishedCurrentSearchRoutine();
		if (roamingSearch.inProgress)
		{
			Log("STOP search // ROAM (finished)");
			((EnemyAI)this).StopSearch(roamingSearch, true);
		}
	}

	private IEnumerator PickItemPosition()
	{
		Log("STARTING COROUTINE PickItemPosition()!!!", 3);
		LogAI($"allAINodes.Length = {base.allAINodes.Length}", 1);
		Vector3 startPos = ((Component)this).transform.position;
		List<GameObject> possibleHideNodes2 = new List<GameObject>();
		PlayerControllerB fromPlayer = (((Object)(object)base.targetPlayer != (Object)null) ? base.targetPlayer : ((EnemyAI)this).GetClosestPlayer(false, false, false));
		for (int a2 = 0; a2 < base.allAINodes.Length; a2++)
		{
			yield return null;
			GameObject val = base.allAINodes[a2];
			Light val2 = null;
			Color color = Color.red;
			LogAI($"A) checking node {val} {val.transform.position}");
			bool flag = false;
			float num = Vector3.Distance(startPos, val.transform.position);
			NavMeshPath val3 = new NavMeshPath();
			if (num > maxSearchDistance)
			{
				flag = true;
				color = Color.yellow;
				LogAI("nodeOutOfReach: maxSearchDistance");
			}
			else if (!base.agent.CalculatePath(val.transform.position, val3))
			{
				flag = true;
				color = Color.yellow;
				LogAI("nodeOutOfReach: CalculatePatch()");
			}
			else if (Vector3.Distance(val3.corners[val3.corners.Length - 1], RoundManager.Instance.GetNavMeshPosition(val.transform.position, RoundManager.Instance.navHit, 2.7f, -1)) > 1f)
			{
				flag = true;
				color = Color.yellow;
				LogAI("nodeOutOfReach: GetNavMeshPosition()");
			}
			LogAI($"ownDistance: {num} | outOfReach: {flag}", 1);
			float num2 = 999f;
			if (!flag)
			{
				for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
				{
					PlayerControllerB val4 = StartOfRound.Instance.allPlayerScripts[i];
					if ((Object)(object)val4 == (Object)null || !val4.isPlayerControlled || !val4.isInsideFactory)
					{
						continue;
					}
					LogAI($"checking player {val4}");
					if ((Object)(object)AnyPlayerHasLineOfSight(val4, val.transform.position) != (Object)null)
					{
						LogAI($"!!!Player can see node at {val.transform.position}, skipping!!!", 2);
						flag = true;
						continue;
					}
					float num3 = Vector3.Distance(((Component)val4).transform.position, val.transform.position);
					if ((Object)(object)val4 != (Object)(object)fromPlayer)
					{
						num3 *= (float)(StartOfRound.Instance.connectedPlayersAmount + 1);
					}
					else if (TargetPlayerCloserAlongPath(val3, fromPlayer))
					{
						LogAI($"!!!Node at {val.transform.position} at end of path too close to targetPlayer, skipping???", 2);
						flag = true;
						continue;
					}
					LogAI($"playerDistance = {num3}", 1);
					if (num3 < num2)
					{
						num2 = num3;
					}
				}
			}
			if (!flag && num < num2)
			{
				LogAI($"node eligible, adding (distance: {num} VS {num2})", 2);
				possibleHideNodes2.Add(val);
				color = Color.green;
			}
			if ((Object)(object)val2 != (Object)null)
			{
				val2.color = color;
			}
		}
		LogAI($"finished search [A] of allAINodes with Count {possibleHideNodes2.Count}", 3);
		if ((float)possibleHideNodes2.Count < minNodesNecessary)
		{
			Log($"counted enemy having access to too little of level (<{minNodesNecessary} = {(float)possibleHideNodes2.Count < minNodesNecessary}), going straight into chase", 3);
			GoIntoChase();
			yield break;
		}
		GameObject secondNode = null;
		possibleHideNodes2 = possibleHideNodes2.OrderBy((GameObject g) => Vector3.Distance(startPos, g.transform.position)).ToList();
		GameObject farthestNode = possibleHideNodes2[possibleHideNodes2.Count - 1];
		Log($"picked farthest node {farthestNode} at distance {Vector3.Distance(startPos, farthestNode.transform.position)}");
		for (int a2 = 0; a2 < possibleHideNodes2.Count; a2++)
		{
			yield return null;
			LogAI($"B) searching at [{a2}]", 1);
			GameObject val5 = possibleHideNodes2[a2];
			if ((Object)(object)val5 == (Object)(object)farthestNode)
			{
				continue;
			}
			float num4 = Vector3.Distance(val5.transform.position, farthestNode.transform.position);
			LogAI($"distanceFromFarthestNode = {num4}");
			if (num4 < minDistanceBetweenFarawayNodes || num4 > maxDistanceBetweenFarawayNodes)
			{
				LogAI("too far");
				continue;
			}
			LogAI($"calculating for secondNode {val5} {val5.transform.position} || secondNode == null? {(Object)(object)secondNode == (Object)null}");
			bool flag2 = false;
			float num5 = Mathf.Abs(farthestNode.transform.position.y - val5.transform.position.y) / verticalOffsetDropoffDivider;
			LogAI($"verticalOffset = {num5}");
			if (num5 + num4 > maxDistanceBetweenFarawayNodes)
			{
				LogAI("VerticalOffsetMode.DecreaseWithDivider", 2);
				flag2 = true;
			}
			if (!flag2 && !Physics.Linecast(val5.transform.position + Vector3.up * 0.5f, farthestNode.transform.position + Vector3.up * 1f, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
			{
				LogAI("no colliders in Linecast between farthest node and this checked second node, meaning hasLOS, skipping secondNode", 2);
				flag2 = true;
			}
			if (!flag2 || (Object)(object)secondNode == (Object)null)
			{
				secondNode = val5;
				LogAI($"picked new secondNode {secondNode.transform.position}", 1);
			}
		}
		LogAI($"finished search [B] with secondNode: {secondNode}");
		if ((Object)(object)secondNode == (Object)null)
		{
			Log("failed to find targetNode, returning ChooseFarthestNodeFromPosition", 3);
			secondNode = ((Component)((EnemyAI)this).ChooseFarthestNodeFromPosition(startPos, true, 0, false, (int)maxSearchDistance, 0)).gameObject;
		}
		else
		{
			Log($"picked second node {secondNode} at distance {Vector3.Distance(startPos, secondNode.transform.position)} and distance from farthest node: {Vector3.Distance(farthestNode.transform.position, secondNode.transform.position)}");
		}
		base.targetNode = secondNode.transform;
		Log($"set targetNode to (second): {base.targetNode.position}", 3);
		base.favoriteSpot = farthestNode.transform;
		Log($"favoriteSpot (farthest): {base.favoriteSpot.position}", 2);
		pickItemPositionCoroutine = null;
	}

	private void StopPickItemPositionCoroutine()
	{
		if (pickItemPositionCoroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(pickItemPositionCoroutine);
			pickItemPositionCoroutine = null;
		}
	}

	private Transform GetFleeToWhileCalculating(PlayerControllerB fleeFrom = null)
	{
		//IL_001a: 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_0036: Expected O, but got Unknown
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: 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)
		Log("Getting fleeToWhileCalculating!!!", 3);
		Transform val = ((Component)this).transform;
		Transform val2 = ((EnemyAI)this).ChooseFarthestNodeFromPosition(((Component)this).transform.position, false, 0, false, (int)maxSearchDistance, 0);
		NavMeshPath val3 = new NavMeshPath();
		if ((Object)(object)fleeFrom == (Object)null)
		{
			fleeFrom = ((EnemyAI)this).GetClosestPlayer(false, false, false);
		}
		if (base.agent.CalculatePath(val2.position, val3))
		{
			if (TargetPlayerCloserAlongPath(val3, fleeFrom))
			{
				val2 = ((EnemyAI)this).ChooseFarthestNodeFromPosition(val2.position, false, 0, false, (int)maxSearchDistance * 2, 0);
				LogAI($"getting new farthestNode {val2}");
			}
			else
			{
				LogAI($"managed to finish first path to farthestNode {val2}", 1);
			}
			val = val2;
		}
		else
		{
			Log("failed to get toReturn!", 3);
		}
		Log($"sending toReturn {val} fleeToWhileCalculating {val.position}", 1);
		return val;
	}

	private Vector3 GetMidpoint(Vector3 startPos = default(Vector3))
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_0026: 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_002f: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: 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_0082: 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_009c: 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_0073: 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_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: 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)
		Log("Getting midpoint!!!", 3);
		Vector3 val = ((Component)this).transform.position;
		Vector3 val2 = Vector3.zero;
		Vector3 zero = Vector3.zero;
		PlayerControllerB val3 = null;
		if (startPos == default(Vector3))
		{
			Log("calculating from nearest player or entrance", 1);
			val3 = (((Object)(object)base.targetPlayer != (Object)null) ? base.targetPlayer : ((EnemyAI)this).GetClosestPlayer(false, false, false));
			if ((Object)(object)val3 != (Object)null)
			{
				val2 = ((Component)val3).transform.position;
			}
			else
			{
				Vector3 val4 = RoundManager.FindMainEntrancePosition(false, false);
				Log($"had to search for entrance and found {val4}");
				if (val4 != Vector3.zero)
				{
					val2 = val4;
				}
			}
		}
		else
		{
			val2 = startPos;
		}
		if (val2 == Vector3.zero)
		{
			Log("point to calculate midpoint from is zero, returning own transform");
			return val;
		}
		zero = ((EnemyAI)this).ChooseClosestNodeToPosition(Vector3.Lerp(((Component)this).transform.position, val2, lerpMidpoint), false, 0).position;
		if (!base.agent.CalculatePath(zero, base.path1))
		{
			LogAI("CalculatePath()", 2);
		}
		else if (Vector3.Distance(base.path1.corners[base.path1.corners.Length - 1], RoundManager.Instance.GetNavMeshPosition(zero, RoundManager.Instance.navHit, 2.7f, -1)) > 1f)
		{
			LogAI("GetNavMeshPosition()", 2);
		}
		else
		{
			val = zero;
			Log($"success! player: {val3} | calculateMidpointFrom {val2} | toReturn {val}", 2);
		}
		Log($"GetMidpoint() sending toReturn {val}", 1);
		return val;
	}

	private bool TargetPlayerCloserAlongPath(NavMeshPath path, PlayerControllerB fleeFrom = null)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: 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)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)fleeFrom == (Object)null)
		{
			fleeFrom = ((!((Object)(object)base.targetPlayer != (Object)null)) ? ((EnemyAI)this).GetClosestPlayer(false, false, false) : base.targetPlayer);
			if ((Object)(object)fleeFrom == (Object)null)
			{
				return false;
			}
		}
		for (int i = 0; i < path.corners.Length; i++)
		{
			Vector3 val = path.corners[i];
			float num = Vector3.Distance(((Component)this).transform.position, val);
			float num2 = Vector3.Distance(((Component)fleeFrom).transform.position, val);
			if (num > num2 && num2 < maxPlayerDistanceToPath)
			{
				LogAI($"player {num2} closer than I {num} to corner [{i}] {val}", 2);
				return true;
			}
		}
		return false;
	}

	private PlayerControllerB AnyPlayerHasLineOfSight(PlayerControllerB checkFromPlayer = null, Vector3 pos = default(Vector3))
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: 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_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: 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)
		if (pos == default(Vector3))
		{
			pos = base.eye.position;
		}
		if ((Object)(object)checkFromPlayer == (Object)null)
		{
			for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
			{
				PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[i];
				if ((Object)(object)val != (Object)null && val.isPlayerControlled && val.HasLineOfSightToPosition(pos, 50f, 40, -1f, -1))
				{
					return val;
				}
			}
		}
		else if (checkFromPlayer.isPlayerControlled && checkFromPlayer.HasLineOfSightToPosition(pos, 50f, 40, -1f, -1))
		{
			return checkFromPlayer;
		}
		return null;
	}

	private PlayerControllerB GetValidPlayerHoldingItem()
	{
		if ((Object)(object)linkedItem == (Object)null)
		{
			return null;
		}
		if ((Object)(object)((GrabbableObject)linkedItem).playerHeldBy == (Object)null)
		{
			return null;
		}
		if (!((GrabbableObject)linkedItem).playerHeldBy.isPlayerControlled)
		{
			return null;
		}
		if (!((GrabbableObject)linkedItem).playerHeldBy.isInsideFactory)
		{
			return null;
		}
		return ((GrabbableObject)linkedItem).playerHeldBy;
	}

	private bool PlayersOutside(bool onlyTargetPlayer = false, bool unlimitedAwareness = false, float overrideAwarenessDistance = -1f)
	{
		//IL_005e: 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_00be: 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)
		if (overrideAwarenessDistance == -1f)
		{
			overrideAwarenessDistance = awarenessDistancePerState[base.currentBehaviourStateIndex % awarenessDistancePerState.Length];
		}
		if (onlyTargetPlayer)
		{
			if ((Object)(object)base.targetPlayer != (Object)null && base.targetPlayer.isPlayerControlled && base.targetPlayer.isInsideFactory && (unlimitedAwareness || Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < overrideAwarenessDistance))
			{
				everyoneOutside = false;
				return everyoneOutside;
			}
		}
		else
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && val.isInsideFactory && (unlimitedAwareness || Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position) < overrideAwarenessDistance))
				{
					everyoneOutside = false;
					return everyoneOutside;
				}
			}
		}
		everyoneOutside = true;
		return everyoneOutside;
	}

	private void ResetVariables(bool moveToAmbush = false)
	{
		if (!((NetworkBehaviour)this).IsServer)
		{
			Log("non-server owner trying to reset, relinquishing control back to player #0 in hopes they notice no one is outside during chase, to reset properly", 2);
			((EnemyAI)this).ChangeOwnershipOfEnemy(StartOfRound.Instance.allPlayerScripts[0].actualClientId);
			return;
		}
		Log("RESET!!!", 2);
		BeatAudioItem[] array = Object.FindObjectsByType<BeatAudioItem>((FindObjectsSortMode)0);
		foreach (BeatAudioItem obj in array)
		{
			obj.ToggleFakeAudio(setTo: false, sync: true);
			obj.ToggleAlarm(setTo: false, sync: true);
		}
		setItemLocally = false;
		reachedHideSpot = false;
		base.movingTowardsTargetPlayer = false;
		base.favoriteSpot = null;
		base.targetNode = null;
		tempTimer = 0f;
		fleeToWhileCalculating = null;
		pickItemPositionCoroutine = null;
		seenDuringThisAmbush = false;
		enraged = false;
		attemptingItemRetrieve = false;
		Log("set everything back", 1);
		if (moveToAmbush)
		{
			Log("moving to ambush");
			seenDuringThisAmbush = true;
			MoveToAmbush(base.targetPlayer);
		}
		else
		{
			base.targetPlayer = null;
			if (base.currentBehaviourStateIndex != 0)
			{
				Log("exiting chase");
				((EnemyAI)this).SwitchToBehaviourState(0);
			}
		}
		Log("Successfully reached end of ResetOnEveryoneOutside()", 1);
	}

	private void DetectNewSighting(Vector3 lookPos, bool lookImmediately = false)
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: 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_0057: Unknown result type (might be due to invalid IL or missing references)
		timeLastLookingAt = Time.realtimeSinceStartup;
		lookingAt = lookPos;
		if (lookImmediately)
		{
			turnCompass.LookAt(lookPos);
			((Component)this).transform.eulerAngles = new Vector3(((Component)this).transform.eulerAngles.x, turnCompass.eulerAngles.y, ((Component)this).transform.eulerAngles.z);
		}
	}

	private void MoveToAmbush(PlayerControllerB setTargetPlayer = null)
	{
		if (((NetworkBehaviour)this).IsServer && base.currentBehaviourStateIndex != 1 && !setItemLocally && !reachedHideSpot)
		{
			timesStartedAmbush++;
			fakeAudioThisAmbush = timesStartedAmbush % 2 == 1;
			Log($"timesStartedAmbush: {timesStartedAmbush} || modulo: {timesStartedAmbush % 2} || fakeAudioThisAmbush: {fakeAudioThisAmbush}");
			base.agent.speed = 0f;
			base.targetNode = null;
			tempTimer = 0f;
			if ((Object)(object)setTargetPlayer != (Object)null)
			{
				base.targetPlayer = setTargetPlayer;
				Log($"started ambush with targetPlayer {base.targetPlayer}");
			}
			SetAnimation("WalkUpright", sync: true, "WalkUprightSpeedMultiplier", 5f);
			if (roamingSearch.inProgress)
			{
				Log("STOP search // ROAM (ambush)");
				((EnemyAI)this).StopSearch(roamingSearch, true);
			}
			attemptingItemRetrieve = GetValidItemRetrieve(calculatePath: true);
			if (!attemptingItemRetrieve)
			{
				Log($"unlinking linkedItem {linkedItem} due to invalid attemptingItemRetrieve {attemptingItemRetrieve}");
				SeverItemLinkServerRpc();
			}
			((EnemyAI)this).SwitchToBehaviourState(1);
			ToggleAudioServerRpc(0f, hideSpeed);
		}
	}

	public void GoIntoChase(bool enrage = false)
	{
		if (((NetworkBehaviour)this).IsServer && base.currentBehaviourStateIndex != 2)
		{
			SyncHPAmbushStartServerRpc(base.enemyHP);
			if ((Object)(object)linkedItem != (Object)null && linkedItem.itemAnimator.GetBool("Footsteps"))
			{
				linkedItem.itemAnimator.SetBool("Footsteps", false);
			}
			enraged = enrage;
			StopPickItemPositionCoroutine();
			((EnemyAI)this).SwitchToBehaviourState(2);
			SetAnimation("WalkUpright", sync: true, "WalkUprightSpeedMultiplier", 3f);
		}
	}

	private void SpawnItemAndHide()
	{
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		if (!((NetworkBehaviour)this).IsServer)
		{
			return;
		}
		setItemLocally = true;
		if (fakeAudioThisAmbush)
		{
			if ((Object)(object)linkedItem == (Object)null || (Object)(object)((GrabbableObject)linkedItem).parentObject != (Object)(object)holdItemParentObject)
			{
				SpawnItemServerRpc(holdItemAfterSpawn: false);
			}
			else
			{
				Log($"owner dropping {linkedItem} #{((NetworkBehaviour)linkedItem).NetworkObjectId}", 1);
				DropLinkedItem();
			}
		}
		reachedHideSpot = false;
		tempTimer = 0f;
		if ((Object)(object)base.favoriteSpot == (Object)null)
		{
			Log("ChooseFarthestNodeFromPosition()!!", 3);
			base.favoriteSpot = ((EnemyAI)this).ChooseFarthestNodeFromPosition(base.targetNode.position, true, 0, true, (int)maxDistanceBetweenFarawayNodes, 0);
		}
		Log("spawned item, going back to state 0");
		((EnemyAI)this).SwitchToBehaviourState(0);
	}

	private void OnReachHideSpot()
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		if (((NetworkBehaviour)this).IsServer)
		{
			reachedHideSpot = true;
			base.movingTowardsTargetPlayer = false;
			tempTimer = 0f;
			((Component)this).transform.Rotate(new Vector3(0f, 180f, 0f), (Space)1);
			if (fakeAudioThisAmbush && (Object)(object)linkedItem != (Object)null)
			{
				Log("should call Idle here");
				SetAnimation("Idle");
				linkedItem.ToggleFakeAudio(setTo: true, sync: true);
			}
			else
			{
				Log($"fakeAudioThisAmbush: {fakeAudioThisAmbush} | linkedItem: {linkedItem}");
				SetAnimation("Ambush");
				ToggleAudioServerRpc(footstepsVolume);
			}
		}
	}

	private bool GetValidItemRetrieve(bool calculatePath = false)
	{
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: 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)
		if ((Object)(object)linkedItem == (Object)null)
		{
			LogAI("retrieve False: null");
			return false;
		}
		if (!((GrabbableObject)linkedItem).hasBeenHeld)
		{
			LogAI("retrieve True: !hasBeenHeld");
			return true;
		}
		if ((Object)(object)((GrabbableObject)linkedItem).parentObject == (Object)(object)holdItemParentObject)
		{
			LogAI("retrieve True: holding");
			return true;
		}
		if (!((GrabbableObject)linkedItem).isInFactory || (Object)(object)((GrabbableObject)linkedItem).playerHeldBy != (Object)null || ((GrabbableObject)linkedItem).deactivated || !((GrabbableObject)linkedItem).grabbable || !((GrabbableObject)linkedItem).grabbableToEnemies)
		{
			LogAI("retrieve False: misc");
			return false;
		}
		if (calculatePath)
		{
			Log("GetValidItemRetrieve(): trying to calculate path");
			if (!base.agent.CalculatePath(((Component)linkedItem).transform.position, base.path1))
			{
				Log("CalculatePath()", 2);
				return false;
			}
			if (Vector3.Distance(base.path1.corners[base.path1.corners.Length - 1], RoundManager.Instance.GetNavMeshPosition(((Component)linkedItem).transform.position, RoundManager.Instance.navHit, 2.7f, -1)) > 1f)
			{
				Log("GetNavMeshPosition()", 2);
				return false;
			}
			Log("successfully going for item retrieve");
		}
		LogAI("retrieve True");
		return true;
	}

	public override void DetectNoise(Vector3 noisePosition, float noiseLoudness, int timesPlayedInOneSpot = 0, int noiseID = 0)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		((EnemyAI)this).DetectNoise(noisePosition, noiseLoudness, timesPlayedInOneSpot, noiseID);
		if (noiseID != 546 && noiseID != 202251)
		{
			if (!((NetworkBehaviour)this).IsOwner && noiseID == 75 && Time.realtimeSinceStartup - timeLastVoiceChatLocalPlayer > 3f)
			{
				Log($"non-owner detected noise with ID {noiseID}, passing to server");
				timeLastVoiceChatLocalPlayer = Time.realtimeSinceStartup;
				PassNoiseToOwnerServerRpc(noisePosition, noiseLoudness);
			}
			else if (OnDetectNoiseValid())
			{
				DetectNoiseOwner(noisePosition, noiseLoudness, noiseID);
			}
		}
	}

	[ServerRpc(RequireOwnership = false)]
	private void PassNoiseToOwnerServerRpc(Vector3 noisePosition, float noiseLoudness)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: 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_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: 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 != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2430531890u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe(ref noisePosition);
				((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref noiseLoudness, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2430531890u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				PassNoiseToOwnerClientRpc(noisePosition, noiseLoudness);
			}
		}
	}

	[ClientRpc]
	private void PassNoiseToOwnerClientRpc(Vector3 noisePosition, float noiseLoudness)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: 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_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
		{
			ClientRpcParams val = default(ClientRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2592962014u, val, (RpcDelivery)0);
			((FastBufferWriter)(ref val2)).WriteValueSafe(ref noisePosition);
			((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref noiseLoudness, default(ForPrimitives));
			((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2592962014u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if (((NetworkBehaviour)this).IsOwner)
			{
				DetectNoiseOwner(noisePosition, noiseLoudness);
			}
		}
	}

	private void DetectNoiseOwner(Vector3 noisePosition, float noiseLoudness, int noiseID = 0)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		if (noiseID == 6 || noiseID == 7)
		{
			noiseLoudness = 0.6f;
		}
		float num = Mathf.Max(1f, 80f - Mathf.Pow(Vector3.Distance(((Component)this).transform.position, noisePosition), noiseDistanceDropoffPower));
		float num2 = noiseLoudness * 100f;
		float num3 = num + num2;
		LogAI($"(ID: {noiseID}) // {num} + {num2} = {num3}");
		if (num3 >= noiseLookThreshold)
		{
			Log("looking at");
			DetectNewSighting(noisePosition);
		}
		if (num3 >= noiseThreshold)
		{
			Log("passed threshold");
			MoveToAmbush();
		}
	}

	private bool OnDetectNoiseValid()
	{
		if (!((NetworkBehaviour)this).IsOwner)
		{
			LogAI("DetectNoise(): not owner");
			return false;
		}
		if (!base.ventAnimationFinished)
		{
			LogAI("DetectNoise(): in vent animation");
			return false;
		}
		if (base.isEnemyDead)
		{
			LogAI("DetectNoise(): dead");
			return false;
		}
		if (base.inSpecialAnimation)
		{
			LogAI("DetectNoise(): inSpecialAnimation");
			return false;
		}
		if (base.stunNormalizedTimer > 0f)
		{
			LogAI("DetectNoise(): stunNormalizedTimer");
			return false;
		}
		if (base.currentBehaviourStateIndex == 0 && setItemLocally && !reachedHideSpot)
		{
			LogAI("DetectNoise(): in 0 and moving to hideSpot");
			return false;
		}
		if (base.currentBehaviourStateIndex == 1 && (attemptingItemRetrieve || enraged))
		{
			LogAI("DetectNoise(): in 1 and focused on item or player");
			return false;
		}
		if (base.currentBehaviourStateIndex == 2 && (Object)(object)base.targetPlayer != (Object)null)
		{
			LogAI("DetectNoise(): in 2 and chasing player");
			return false;
		}
		if (PlayersOutside())
		{
			LogAI("DetectNoise(): everyone outside awareness radius");
			return false;
		}
		return true;
	}

	public override void SetEnemyStunned(bool setToStunned, float setToStunTime = 1f, PlayerControllerB setStunnedByPlayer = null)
	{
		((EnemyAI)this).SetEnemyStunned(setToStunned, setToStunTime, setStunnedByPlayer);
		GoIntoChase();
	}

	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.targetPlayer = playerWhoHit;
			GoIntoChase(enrage: true);
			PlaySFX(intimidateSFX, audibleNoise: true, isAudience: false, sync: false);
			base.enemyHP -= force;
			Log($"HP: {base.enemyHP}");
			if (base.enemyHP <= 0)
			{
				((EnemyAI)this).KillEnemyOnOwnerClient(false);
			}
		}
	}

	public override void KillEnemy(bool destroy = false)
	{
		((EnemyAI)this).KillEnemy(destroy);
		StopPickItemPositionCoroutine();
	}

	public override void OnCollideWithPlayer(Collider other)
	{
		if (Time.realtimeSinceStartup - timeLastCollisionLocalPlayer > collisionCooldown)
		{
			PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, base.inSpecialAnimation, false);
			if ((Object)(object)val != (Object)null && (base.currentBehaviourStateIndex != 2 || (Object)(object)val == (Object)(object)base.targetPlayer))
			{
				((EnemyAI)this).OnCollideWithPlayer(other);
				timeLastCollisionLocalPlayer = Time.realtimeSinceStartup;
				PerformPlayerCollision(val);
			}
		}
	}

	private void PerformPlayerCollision(PlayerControllerB localPlayer)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: 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_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_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: 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_0068: 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_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		Vector3 zero = Vector3.zero;
		switch (base.currentBehaviourStateIndex)
		{
		case 0:
			zero = base.eye.forward * 3f + Vector3.up * 15f;
			localPlayer.DamagePlayer(10, true, true, (CauseOfDeath)12, 0, false, zero);
			if (!localPlayer.isPlayerDead)
			{
				localPlayer.externalForceAutoFade += zero;
			}
			if (((NetworkBehaviour)this).IsOwner)
			{
				if (!setItemLocally)
				{
					MoveToAmbush(localPlayer);
				}
			}
			else
			{
				CollisionLogicServerRpc();
			}
			break;
		case 1:
			zero = base.eye.forward * 5f + Vector3.up * 25f;
			localPlayer.DamagePlayer(20, true, true, (CauseOfDeath)12, 0, false, zero);
			if (!localPlayer.isPlayerDead)
			{
				localPlayer.externalForceAutoFade += zero;
			}
			if (((NetworkBehaviour)this).IsOwner)
			{
				enraged = false;
			}
			else
			{
				CollisionLogicServerRpc();
			}
			break;
		case 2:
		{
			bool doPreAttackAnimation = !enraged || localPlayer.isCrouching;
			((MonoBehaviour)this).StartCoroutine(AttackPlayer(localPlayer, doPreAttackAnimation));
			CollisionLogicServerRpc((int)localPlayer.playerClientId, doPreAttackAnimation);
			break;
		}
		}
	}

	private IEnumerator AttackPlayer(PlayerControllerB player, bool doPreAttackAnimation)
	{
		Log("starting collision coroutine!!", 1);
		base.agent.speed = 0f;
		realAudio.volume = 0f;
		base.inSpecialAnimationWithPlayer = player;
		if (doPreAttackAnimation)
		{
			PlaySFX(caughtSFX, audibleNoise: false, isAudience: false, sync: false);
			SetAnimation("AttackStart", sync: false);
			player.inAnimationWithEnemy = (EnemyAI)(object)this;
			player.inSpecialInteractAnimation = true;
			player.isCrouching = false;
			player.playerBodyAnimator.SetBool("crouching", false);
			RoundManager.Instance.tempTransform.position = ((Component)player).transform.position;
			RoundManager.Instance.tempTransform.LookAt(((Component)this).transform.position);
			Quaternion startingPlayerRot = ((Component)player).transform.rotation;
			Quaternion targetPlayerRot = RoundManager.Instance.tempTransform.rotation;
			for (int i = 0; i < turnPlayerIterations; i++)
			{
				((Component)player).transform.rotation = Quaternion.Lerp(startingPlayerRot, targetPlayerRot, (float)i / (float)turnPlayerIterations);
				((Component)player).transform.eulerAngles = new Vector3(0f, ((Component)player).transform.eulerAngles.y, 0f);
				yield return null;
			}
		}
		if ((Object)(object)linkedItem != (Object)null)
		{
			linkedItem.ToggleFakeAudio(setTo: false);
			if ((Object)(object)((GrabbableObject)linkedItem).playerHeldBy == (Object)null)
			{
				linkedItem.ToggleAlarm(setTo: false);
			}
		}
		player.inSpecialInteractAnimation = false;
		player.inAnimationWithEnemy = null;
		base.inSpecialAnimationWithPlayer = null;
		yield return null;
		player.averageVelocity = 0f;
		player.velocityLastFrame = Vector3.zero;
		SetAnimation("Attack", sync: false);
		PlaySFX(reelSFX, audibleNoise: false, isAudience: false, sync: false);
		yield return (object)new WaitForSeconds(0.6f);
		base.creatureSFX.Stop();
		Vector3 position = player.playerEye.position;
		bool hasKilled = true;
		Bounds bounds = killBox.bounds;
		if (((Bounds)(ref bounds)).Contains(position))
		{
			Log("KillPlayer: playerEye in killBox");
			player.KillPlayer(Vector3.zero, true, (CauseOfDeath)6, 8, default(Vector3), false);
			PlaySFX(punchHitSFX);
		}
		else
		{
			bounds = killBox.bounds;
			if (((Bounds)(ref bounds)).Contains(new Vector3(position.x, ((Component)killBox).transform.position.y, position.z)))
			{
				float y = position.y;
				float y2 = ((Component)killBox).transform.position.y;
				bounds = killBox.bounds;
				if (y > y2 - ((Bounds)(ref bounds)).extents.y && position.y < ((Component)killBox).transform.position.y + 3f)
				{
					Log("KillPlayer: playerEye in killBox.x && killBox.z, playerEye > killBox.y - 0.5 && playereye < killBox.y + 3");
					player.KillPlayer(Vector3.zero, true, (CauseOfDeath)6, 7, default(Vector3), false);
					PlaySFX(punchHitSFX);
					goto IL_0438;
				}
			}
			Log("KillPlayer: fail");
			hasKilled = false;
			PlaySFX(punchMissSFX);
		}
		goto IL_0438;
		IL_0438:
		yield return (object)new WaitForSeconds(0.6f);
		if (hasKilled)
		{
			PlaySFX(successCheer, audibleNoise: false, isAudience: true);
		}
		CheckEnragedAfterAttack();
	}

	private IEnumerator AttackPlayerNonLocal(PlayerControllerB player, bool doPreAttackAnimation)
	{
		Log("starting collision coroutine NON LOCAL!!!", 2);
		base.agent.speed = 0f;
		realAudio.volume = 0f;
		base.inSpecialAnimationWithPlayer = player;
		if (doPreAttackAnimation)
		{
			PlaySFX(caughtSFX, audibleNoise: false, isAudience: false, sync: false);
			SetAnimation("AttackStart", sync: false);
			player.inAnimationWithEnemy = (EnemyAI)(object)this;
			player.inSpecialInteractAnimation = true;
			for (int i = 0; i < turnPlayerIterations; i++)
			{
				yield return null;
			}
		}
		if ((Object)(object)linkedItem != (Object)null)
		{
			linkedItem.ToggleFakeAudio(setTo: false);
			if ((Object)(object)((GrabbableObject)linkedItem).playerHeldBy == (Object)null)
			{
				linkedItem.ToggleAlarm(setTo: false);
			}
		}
		player.inSpecialInteractAnimation = false;
		player.inAnimationWithEnemy = null;
		base.inSpecialAnimationWithPlayer = null;
		yield return null;
		player.averageVelocity = 0f;
		player.velocityLastFrame = Vector3.zero;
		SetAnimation("Attack", sync: false);
		PlaySFX(reelSFX, audibleNoise: false, isAudience: false, sync: false);
		yield return (object)new WaitForSeconds(1.2f);
		CheckEnragedAfterAttack();
	}

	private void CheckEnragedAfterAttack()
	{
		enraged = base.enemyHP < hpAmbushStart || (Object)(object)GetValidPlayerHoldingItem() != (Object)null;
		Log($"enraged: {enraged}");
		if (enraged)
		{
			return;
		}
		if (((NetworkBehaviour)this).IsServer)
		{
			Log("SERVER READYING UP TO RESET VARIABLES AND MOVE TO AMBUSH!!", 1);
			if (((NetworkBehaviour)this).IsOwner)
			{
				ResetVariables(moveToAmbush: true);
			}
			else
			{
				tempTimer = 99f;
			}
		}
		else if (((NetworkBehaviour)this).IsOwner)
		{
			Log("OWNER READYING UP TO GIVE CONTROL BACK TO SERVER!!", 1);
			((EnemyAI)this).ChangeOwnershipOfEnemy(StartOfRound.Instance.allPlayerScripts[0].actualClientId);
		}
	}

	public void SetEnemyInSpecialAnimation(bool setInSpecialAnimationTo)
	{
		base.inSpecialAnimation = setInSpecialAnimationTo;
		LogAI($"inSpecialAnimation = {base.inSpecialAnimation}");
	}

	[ServerRpc(RequireOwnership = false)]
	private void CollisionLogicServerRpc(int sentBy = -1, bool doPreAttackAnimation = true)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: 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_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3087885578u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, sentBy);
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref doPreAttackAnimation, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3087885578u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				CollisionLogicClientRpc(sentBy, doPreAttackAnimation);
			}
		}
	}

	[ClientRpc]
	private void CollisionLogicClientRpc(int sentBy = -1, bool doPreAttackAnimation = true)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: 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_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
		{
			ClientRpcParams val = default(ClientRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2055034921u, val, (RpcDelivery)0);
			BytePacker.WriteValueBitPacked(val2, sentBy);
			((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref doPreAttackAnimation, default(ForPrimitives));
			((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2055034921u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
		{
			return;
		}
		((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
		if (sentBy != -1 && sentBy == (int)GameNetworkManager.Instance.localPlayerController.playerClientId)
		{
			return;
		}
		Log($"CollisionLogicClientRpc(): currentBehaviourStateIndex {base.currentBehaviourStateIndex} | sentBy {sentBy}");
		sentBy = (int)GetValidPlayer(sentBy).playerClientId;
		switch (base.currentBehaviourStateIndex)
		{
		case 0:
			if (((NetworkBehaviour)this).IsOwner && !setItemLocally)
			{
				MoveToAmbush(StartOfRound.Instance.allPlayerScripts[sentBy]);
			}
			break;
		case 1:
			if (((NetworkBehaviour)this).IsOwner)
			{
				enraged = false;
			}
			break;
		case 2:
			((MonoBehaviour)this).StartCoroutine(AttackPlayerNonLocal(StartOfRound.Instance.allPlayerScripts[sentBy], doPreAttackAnimation));
			break;
		}
	}

	[ServerRpc(RequireOwnership = false)]
	private void SpawnItemServerRpc(bool holdItemAfterSpawn)
	{
		//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)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: 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(1509949983u, val, (RpcDelivery)0);
			((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref holdItemAfterSpawn, default(ForPrimitives));
			((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1509949983u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost))
		{
			return;
		}
		((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
		GameObject val3 = Object.Instantiate<GameObject>(itemToSpawn.spawnPrefab, ((Component)this).transform.position + Vector3.up * 2f, Quaternion.identity, RoundManager.Instance.spawnedScrapContainer);
		NetworkObject component = val3.GetComponent<NetworkObject>();
		component.Spawn(false);
		if (holdItemAfterSpawn)
		{
			BeatAudioItem component2 = val3.GetComponent<BeatAudioItem>();
			if ((Object)(object)component2 == (Object)null)
			{
				Log("host failed to get itemScript in SpawnItemServerRpc()", 3);
				return;
			}
			GrabLinkedItemLocal(component2);
			SpawnItemClientRpc(NetworkObjectReference.op_Implicit(component));
		}
	}

	[ClientRpc]
	private void SpawnItemClientRpc(NetworkObjectReference itemNOR)
	{
		//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)
		//IL_00dc: 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)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
		{
			ClientRpcParams val = default(ClientRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4046887583u, val, (RpcDelivery)0);
			((FastBufferWriter)(ref val2)).WriteValueSafe<NetworkObjectReference>(ref itemNOR, default(ForNetworkSerializable));
			((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4046887583u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if (!((NetworkBehaviour)this).IsServer)
			{
				((MonoBehaviour)this).StartCoroutine(WaitForSpawnedItem(itemNOR));
			}
		}
	}

	private IEnumerator WaitForSpawnedItem(NetworkObjectReference itemNOR)
	{
		//IL_000e: 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)
		NetworkObject netObj = null;
		float startTime = Time.realtimeSinceStartup;
		while (Time.realtimeSinceStartup - startTime < 8f && !((NetworkObjectReference)(ref itemNOR)).TryGet(ref netObj, (NetworkManager)null))
		{
			yield return (object)new WaitForSeconds(0.03f);
		}
		if ((Object)(object)netObj == (Object)null)
		{
			Log("failed to get netObj on client!", 3);
			yield break;
		}
		yield return (object)new WaitForEndOfFrame();
		BeatAudioItem component = ((Component)netObj).gameObject.GetComponent<BeatAudioItem>();
		if ((Object)(object)component == (Object)null)
		{
			Log("client failed to get itemScript in WaitForSpawnedItem()", 3);
		}
		else
		{
			GrabLinkedItemLocal(component);
		}
	}

	[ServerRpc(RequireOwnership = false)]
	private void ToggleAudioServerRpc(float newVolume, float agentSpeed = -1f)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: 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_0098: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: 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 != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(750633870u, val, (RpcDelivery)0);
				((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref newVolume, default(ForPrimitives));
				((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref agentSpeed, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 750633870u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				ToggleAudioClientRpc(newVolume, agentSpeed);
			}
		}
	}

	[ClientRpc]
	private void ToggleAudioClientRpc(float newVolume, float agentSpeed = -1f)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: 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_0098: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager == null || !networkManager.IsListening)
		{
			return;
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
		{
			ClientRpcParams val = default(ClientRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2000840382u, val, (RpcDelivery)0);
			((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref newVolume, default(ForPrimitives));
			((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref agentSpeed, default(ForPrimitives));
			((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2000840382u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if (agentSpeed == -1f)
			{
				agentSpeed = base.agent.speed;
			}
			base.agent.speed = agentSpeed;
			if (newVolume == -1f)
			{
				newVolume = realAudio.volume;
			}
			realAudio.volume = newVolume;
		}
	}

	[ServerRpc(RequireOwnership = false)]
	private void SyncHPAmbushStartServerRpc(int hpAmbushStartValue)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Invalid comparison between Unknown and I4
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
		if (networkManager != null && networkManager.IsListening)
		{
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1893334989u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, hpAmbushStartValue);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1893334989u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				SyncHPAmbushStartClientRpc(hpAmbushStartValue);
			}
		}
	}

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

	public void ChaseNewPlayer(PlayerControllerB player)
	{
		if (!((Object)(object)player == (Object)null) && ((NetworkBehaviour)this).IsOwner && (!base.movingTowardsTargetPlayer || ((NetworkBehaviour)player).OwnerClientId != ((NetworkBehaviour)this).NetworkObject.OwnerClientId))
		{
			Log("started new chase on owner, should sync AI-Calculation to chased player " + player.playerUsername, 2);
			((EnemyAI)this).ChangeOwnershipOfEnemy(player.actualClientId);
			ChasePlayerServerRpc((int)player.playerClientId);
		}
	}

	[ServerRpc(RequireOwnership = false)]
	private void ChasePlayerServerRpc(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)
		//IL_00ce: 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 != 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				ServerRpcParams val = default(ServerRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(118970262u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, playerID);
				((NetworkBehaviour)this).__endSendServerRpc(ref val2, 118970262u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				ChasePlayerClientRpc(playerID);
			}
		}
	}

	[ClientRpc]
	private void ChasePlayerClientRpc(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)
		//IL_00ce: 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 != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(221236223u, val, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, playerID);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 221236223u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				ChaseNewPlayerOnLocalClient(StartOfRound.Instance.allPlayerScripts[playerID]);
			}
		}
	}

	private void ChaseNewPlayerOnLocalClient(PlayerControllerB playerToChase)
	{
		((EnemyAI)this).SetMovingTowardsTargetPlayer(playerToChase);
	}

	private PlayerControllerB GetValidPlayer(int playerID, bool getClosestPlayer = false)
	{
		if (playerID >= 0 && playerID < StartOfRound.Instance.allPlayerScripts.Length)
		{
			return StartOfRound.Instance.allPlayerScripts[playerID];
		}
		if (getClosestPlayer)
		{
			PlayerControllerB closestPlayer = ((EnemyAI)this).GetClosestPlayer(false, false, false);
			if ((Object)(object)closestPlayer != (Object)null)
			{
				return closestPlayer;
			}
		}
		return StartOfRound.Instance.allPlayerScripts[0];
	}

	private void SetAnimation(string animString = null, bool sync = true, string paramString = null, float paramFloat = 1f)
	{
		SetAnimationLocal(animString, paramString, paramFloat);
		if (sync)
		{
			SetAnimationServerRpc((int)GameNetworkManager.Instance.localPlayerController.playerClientId, animString, paramString, paramFloat);
		}
	}

	[ServerRpc(RequireOwnership = false)]
	private void SetAnimationServerRpc(int sentBy, string animString, string paramString, float paramFloat)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: 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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: 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 != 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			ServerRpcParams val = default(ServerRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3422828450u, val, (RpcDelivery)0);
			BytePacker.WriteValueBitPacked(val2, sentBy);
			bool flag = animString != null;
			((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
			if (flag)
			{
				((FastBufferWriter)(ref val2)).WriteValueSafe(animString, false);
			}
			bool flag2 = paramString != null;
			((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives));
			if (flag2)
			{
				((FastBufferWriter)(ref val2)).WriteValueSafe(paramString, false);
			}
			((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref paramFloat, default(ForPrimitives));
			((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3422828450u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost))
		{
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			SetAnimationClientRpc(sentBy, animString, paramString, paramFloat);
		}
	}

	[ClientRpc]
	private void SetAnimationClientRpc(int sentBy, string animString, string paramString, float paramFloat)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_013a: 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_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: 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 != 1 && (networkManager.IsServer || networkManager.IsHost))
		{
			ClientRpcParams val = default(ClientRpcParams);
			FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4043217162u, val, (RpcDelivery)0);
			BytePacker.WriteValueBitPacked(val2, sentBy);
			bool flag = animString != null;
			((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
			if (flag)
			{
				((FastBufferWriter)(ref val2)).WriteValueSafe(animString, false);
			}
			bool flag2 = paramString != null;
			((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag2, default(ForPrimitives));
			if (flag2)
			{
				((FastBufferWriter)(ref val2)).WriteValueSafe(paramString, false);
			}
			((FastBufferWriter)(ref val2)).WriteValueSafe<float>(ref paramFloat, default(ForPrimitives));
			((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4043217162u, val, (RpcDelivery)0);
		}
		if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
		{
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;