Decompiled source of Security Droid Enemy v1.0.1

Tornadoo.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Omniscye")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1a503a09dbe2a5b04a820afc634d715fb9799116")]
[assembly: AssemblyProduct("Tornadoo")]
[assembly: AssemblyTitle("Tornadoo")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Tornadoo
{
	[BepInPlugin("Omniscye.Tornadoo", "Tornadoo", "1.0")]
	public class Tornadoo : BaseUnityPlugin
	{
		internal static Tornadoo Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

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

		internal Harmony? Harmony { get; set; }

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Patch();
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
		}
	}
}
namespace Empress.Security
{
	[HarmonyPatch]
	internal static class GrabPatchesLocal
	{
		[HarmonyPatch(typeof(PhysGrabObject), "GrabStarted")]
		[HarmonyPostfix]
		private static void PhysGrabObject_GrabStarted_Postfix(PhysGrabObject __instance, PhysGrabber player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			PlayerAvatar componentInParent = ((Component)player).GetComponentInParent<PlayerAvatar>();
			if (!Object.op_Implicit((Object)(object)componentInParent) || (Object)(object)((Component)__instance).GetComponent<ValuableObject>() == (Object)null)
			{
				return;
			}
			SecurityDroneManager.OnValuableGrabStarted(componentInParent, __instance);
			if (!SecurityDroneManager.IsAuthority())
			{
				PhotonView component = ((Component)player).GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null && component.ViewID > 0)
				{
					SecurityDroneEventRouter.SendHeldUpdate(held: true, component.ViewID);
				}
			}
		}

		[HarmonyPatch(typeof(PhysGrabObject), "GrabEnded")]
		[HarmonyPostfix]
		private static void PhysGrabObject_GrabEnded_Postfix(PhysGrabObject __instance, PhysGrabber player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			PlayerAvatar componentInParent = ((Component)player).GetComponentInParent<PlayerAvatar>();
			if (!Object.op_Implicit((Object)(object)componentInParent))
			{
				return;
			}
			SecurityDroneManager.OnGrabEnded(componentInParent, __instance);
			if (!SecurityDroneManager.IsAuthority())
			{
				PhotonView component = ((Component)player).GetComponent<PhotonView>();
				if ((Object)(object)component != (Object)null && component.ViewID > 0)
				{
					SecurityDroneEventRouter.SendHeldUpdate(held: false, component.ViewID);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PhysGrabObject))]
	internal static class GrabPatchesRPC
	{
		[CompilerGenerated]
		private sealed class <TargetGrabRPCs>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private MethodBase <>2__current;

			private int <>l__initialThreadId;

			private Type <t>5__1;

			private List<MethodInfo>.Enumerator <>s__2;

			private MethodInfo <m>5__3;

			MethodBase IEnumerator<MethodBase>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TargetGrabRPCs>d__0(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<t>5__1 = null;
				<>s__2 = default(List<MethodInfo>.Enumerator);
				<m>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					int num = <>1__state;
					if (num != 0)
					{
						if (num != 1)
						{
							return false;
						}
						<>1__state = -3;
						goto IL_00bd;
					}
					<>1__state = -1;
					<t>5__1 = typeof(PhysGrabObject);
					<>s__2 = AccessTools.GetDeclaredMethods(<t>5__1).GetEnumerator();
					<>1__state = -3;
					goto IL_00c5;
					IL_00bd:
					<m>5__3 = null;
					goto IL_00c5;
					IL_00c5:
					if (<>s__2.MoveNext())
					{
						<m>5__3 = <>s__2.Current;
						if (<m>5__3.Name == "GrabPlayerAddRPC" || <m>5__3.Name == "GrabPlayerRemoveRPC")
						{
							<>2__current = <m>5__3;
							<>1__state = 1;
							return true;
						}
						goto IL_00bd;
					}
					<>m__Finally1();
					<>s__2 = default(List<MethodInfo>.Enumerator);
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				((IDisposable)<>s__2).Dispose();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
			{
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					return this;
				}
				return new <TargetGrabRPCs>d__0(0);
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<MethodBase>)this).GetEnumerator();
			}
		}

		[IteratorStateMachine(typeof(<TargetGrabRPCs>d__0))]
		[HarmonyTargetMethods]
		private static IEnumerable<MethodBase> TargetGrabRPCs()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TargetGrabRPCs>d__0(-2);
		}

		[HarmonyPostfix]
		private static void Postfix_AllGrabRPCs(PhysGrabObject __instance, MethodBase __originalMethod, object[] __args)
		{
			if (!SecurityDroneManager.IsAuthority() || !Object.op_Implicit((Object)(object)__instance) || (Object)(object)((Component)__instance).GetComponent<ValuableObject>() == (Object)null)
			{
				return;
			}
			int num = -1;
			for (int i = 0; i < __args.Length; i++)
			{
				if (__args[i] is int num2)
				{
					num = num2;
					break;
				}
			}
			if (num < 0)
			{
				return;
			}
			PhotonView val = PhotonView.Find(num);
			PhysGrabber val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<PhysGrabber>() : null);
			PlayerAvatar val3 = (Object.op_Implicit((Object)(object)val2) ? ((Component)val2).GetComponentInParent<PlayerAvatar>() : null);
			if (Object.op_Implicit((Object)(object)val3))
			{
				if (__originalMethod.Name == "GrabPlayerAddRPC")
				{
					SecurityDroneManager.OnValuableGrabStarted(val3, __instance);
				}
				else
				{
					SecurityDroneManager.OnGrabEnded(val3, __instance);
				}
			}
		}
	}
	[RequireComponent(typeof(NavMeshAgent))]
	[DisallowMultipleComponent]
	public class SecurityDroneController : MonoBehaviour
	{
		private enum State
		{
			Patrol,
			Pursue,
			Warning,
			Cooldown
		}

		[CompilerGenerated]
		private sealed class <WarningRoutine>d__53 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PlayerAvatar player;

			public SecurityDroneController <>4__this;

			private float <t>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WarningRoutine>d__53(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (<>4__this._state == State.Warning)
					{
						return false;
					}
					<>4__this._state = State.Warning;
					SecurityDroneEventRouter.BroadcastFX(SecurityDroneEventRouter.Ev.WarnFX, ((Component)<>4__this).transform.position);
					<t>5__1 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<t>5__1 < <>4__this._warningDelay && SecurityDroneManager.PlayerStillHoldingValuable(player))
				{
					<t>5__1 += Time.deltaTime;
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if (SecurityDroneManager.PlayerStillHoldingValuable(player))
				{
					<>4__this.DoAttack(player);
				}
				<>4__this._target = null;
				<>4__this._state = State.Cooldown;
				<>4__this.ForceNextPatrolDestination();
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private AudioSource _sfx;

		private AudioSource _amb;

		private AudioClip[] _warningClips;

		private AudioClip _ambientClip;

		private AudioClip _stunClip;

		private float _warningVol = 0.3f;

		private float _ambientVol = 0.3f;

		private float _stunVol = 0.3f;

		private NavMeshAgent _agent;

		private Animator _anim;

		private int _damage;

		private float _warningDelay;

		private float _patrolRadius;

		private float _engageDistance;

		private LayerMask _visionMask;

		private PlayerAvatar _target;

		private float _repathTimer;

		private Transform[] _levelPoints;

		private Transform _truckPoint;

		private float _idleUntil;

		private Transform _currentPatrolTarget;

		private bool _movingToPatrol;

		private float _stuckTimer;

		private Vector3 _lastPos;

		private const float _warnSfxCooldown = 10f;

		private float _nextWarnSfxTime;

		private State _state = State.Patrol;

		private Vector3 _netPos;

		private Quaternion _netRot;

		private bool _hasNetPose;

		private const float PoseSnapDist = 5f;

		private const float PoseLerpRate = 10f;

		private float _poseSendTimer;

		private const float PoseSendInterval = 0.1f;

		private void OnEnable()
		{
			SecurityDroneManager.Register(this);
			if (Object.op_Implicit((Object)(object)_amb) && Object.op_Implicit((Object)(object)_ambientClip) && !_amb.isPlaying)
			{
				_amb.clip = _ambientClip;
				_amb.volume = _ambientVol;
				_amb.loop = true;
				_amb.Play();
			}
		}

		private void OnDisable()
		{
			SecurityDroneManager.Unregister(this);
			if (Object.op_Implicit((Object)(object)_amb) && _amb.isPlaying)
			{
				_amb.Stop();
			}
		}

		public void Setup(int damage, float warningDelay, float patrolRadius, float engageDistance, LayerMask visionMask)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			_damage = damage;
			_warningDelay = warningDelay;
			_patrolRadius = patrolRadius;
			_engageDistance = engageDistance;
			_visionMask = visionMask;
		}

		public void AssignAudio(AudioClip[] warnings, AudioClip ambient, AudioClip stun, float warningVol, float ambientVol, float stunVol)
		{
			_warningClips = warnings;
			_ambientClip = ambient;
			_stunClip = stun;
			_warningVol = Mathf.Clamp01(warningVol);
			_ambientVol = Mathf.Clamp01(ambientVol);
			_stunVol = Mathf.Clamp01(stunVol);
			if (Object.op_Implicit((Object)(object)_amb) && Object.op_Implicit((Object)(object)_ambientClip))
			{
				if ((Object)(object)_amb.clip != (Object)(object)_ambientClip)
				{
					_amb.clip = _ambientClip;
				}
				_amb.volume = _ambientVol;
				_amb.loop = true;
				if (!_amb.isPlaying)
				{
					_amb.Play();
				}
			}
		}

		private void Awake()
		{
			_agent = ((Component)this).GetComponent<NavMeshAgent>();
			_anim = ((Component)this).GetComponent<Animator>();
			_sfx = ((Component)this).GetComponent<AudioSource>() ?? ((Component)this).gameObject.AddComponent<AudioSource>();
			_sfx.playOnAwake = false;
			_sfx.loop = false;
			_sfx.spatialBlend = 1f;
			_sfx.dopplerLevel = 0f;
			_sfx.rolloffMode = (AudioRolloffMode)0;
			_sfx.minDistance = 8f;
			_sfx.maxDistance = 15f;
			_amb = ((Component)this).gameObject.AddComponent<AudioSource>();
			_amb.playOnAwake = false;
			_amb.loop = true;
			_amb.spatialBlend = 1f;
			_amb.dopplerLevel = 0f;
			_amb.rolloffMode = (AudioRolloffMode)0;
			_amb.minDistance = 8f;
			_amb.maxDistance = 15f;
			if (Object.op_Implicit((Object)(object)_agent))
			{
				_agent.stoppingDistance = 1.5f;
			}
		}

		private void Start()
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			LevelGenerator instance = LevelGenerator.Instance;
			if ((Object)(object)instance != (Object)null && instance.Generated)
			{
				_truckPoint = (Object.op_Implicit((Object)(object)instance.LevelPathTruck) ? ((Component)instance.LevelPathTruck).transform : null);
				if (instance.LevelPathPoints != null)
				{
					_levelPoints = (from p in instance.LevelPathPoints
						where (Object)(object)p != (Object)null
						select ((Component)p).transform).ToArray();
				}
			}
			_idleUntil = Time.time + Random.Range(10f, 30f);
			_lastPos = ((Component)this).transform.position;
			if (!SecurityDroneManager.IsAuthority() && Object.op_Implicit((Object)(object)_agent) && ((Behaviour)_agent).enabled)
			{
				((Behaviour)_agent).enabled = false;
			}
		}

		private void Update()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			if (SecurityDroneManager.IsAuthority())
			{
				HostTick();
				if (SecurityDroneManager.CanStreamPose())
				{
					_poseSendTimer += Time.deltaTime;
					if (_poseSendTimer >= 0.1f)
					{
						_poseSendTimer = 0f;
						object[] array = new object[2]
						{
							((Component)this).transform.position,
							((Component)this).transform.rotation
						};
						PhotonNetwork.RaiseEvent((byte)105, (object)array, new RaiseEventOptions
						{
							Receivers = (ReceiverGroup)0
						}, SendOptions.SendUnreliable);
					}
				}
			}
			else
			{
				ClientTick();
			}
		}

		private void HostTick()
		{
			switch (_state)
			{
			case State.Patrol:
				PatrolTick();
				break;
			case State.Pursue:
				PursueTick();
				break;
			case State.Warning:
				break;
			case State.Cooldown:
				CooldownTick();
				break;
			}
		}

		private void ClientTick()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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_0073: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (_hasNetPose)
			{
				if (Vector3.Distance(((Component)this).transform.position, _netPos) > 5f)
				{
					((Component)this).transform.SetPositionAndRotation(_netPos, _netRot);
					return;
				}
				((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, _netPos, Time.deltaTime * 10f);
				((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, _netRot, Time.deltaTime * 10f);
			}
		}

		public void ApplyNetworkPose(Vector3 pos, Quaternion rot)
		{
			//IL_0002: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			_netPos = pos;
			_netRot = rot;
			_hasNetPose = true;
		}

		public void ConsiderEngage(PlayerAvatar player)
		{
			//IL_0025: 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)
			if (Object.op_Implicit((Object)(object)player) && _state != State.Warning && Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) <= _engageDistance && HasLineOfSight(player))
			{
				_target = player;
				_state = State.Pursue;
			}
		}

		private void PatrolTick()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_agent) || !_agent.isOnNavMesh)
			{
				return;
			}
			if (_movingToPatrol)
			{
				if (!_agent.pathPending && _agent.remainingDistance <= 0.5f)
				{
					_movingToPatrol = false;
					_idleUntil = Time.time + Random.Range(10f, 30f);
					_agent.isStopped = true;
					return;
				}
				Vector3 val = ((Component)this).transform.position - _lastPos;
				float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
				_stuckTimer = ((sqrMagnitude < 0.0004f) ? (_stuckTimer + Time.deltaTime) : 0f);
				_lastPos = ((Component)this).transform.position;
				if (_stuckTimer > 2f)
				{
					_stuckTimer = 0f;
					ForceNextPatrolDestination();
				}
			}
			else if (Time.time < _idleUntil)
			{
				if (!_agent.isStopped)
				{
					_agent.isStopped = true;
				}
			}
			else
			{
				ForceNextPatrolDestination();
			}
		}

		private void ForceNextPatrolDestination()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			_agent.isStopped = false;
			_currentPatrolTarget = ChooseNextLevelPoint();
			if ((Object)(object)_currentPatrolTarget != (Object)null)
			{
				Vector3 position = _currentPatrolTarget.position;
				NavMeshHit val = default(NavMeshHit);
				if (NavMesh.SamplePosition(position, ref val, 3f, -1))
				{
					position = ((NavMeshHit)(ref val)).position;
				}
				if (_agent.isOnNavMesh)
				{
					_agent.SetDestination(position);
				}
				else
				{
					_agent.Warp(position);
				}
				_movingToPatrol = true;
				_lastPos = ((Component)this).transform.position;
				_stuckTimer = 0f;
			}
			else
			{
				PickNewPatrolPoint();
				_movingToPatrol = true;
				_lastPos = ((Component)this).transform.position;
				_stuckTimer = 0f;
			}
		}

		private void PursueTick()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_target == (Object)null)
			{
				_state = State.Patrol;
			}
			else if (Object.op_Implicit((Object)(object)_agent) && _agent.isOnNavMesh)
			{
				_agent.isStopped = false;
				_repathTimer -= Time.deltaTime;
				if (_repathTimer <= 0f)
				{
					_repathTimer = 0.15f;
					_agent.SetDestination(((Component)_target).transform.position);
				}
				if (Vector3.Distance(((Component)this).transform.position, ((Component)_target).transform.position) <= 4f)
				{
					((MonoBehaviour)this).StartCoroutine(WarningRoutine(_target));
				}
			}
		}

		private void CooldownTick()
		{
			if (Object.op_Implicit((Object)(object)_agent) && _agent.isOnNavMesh && (!_agent.hasPath || _agent.remainingDistance < 0.5f))
			{
				_state = State.Patrol;
				_movingToPatrol = false;
				_currentPatrolTarget = null;
				_idleUntil = 0f;
				_agent.isStopped = false;
			}
		}

		private bool HasLineOfSight(PlayerAvatar player)
		{
			//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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)player))
			{
				return false;
			}
			Vector3 val = ((Component)this).transform.position + Vector3.up * 1.2f;
			Transform val2 = null;
			try
			{
				val2 = (((Object)(object)player.PlayerVisionTarget != (Object)null) ? player.PlayerVisionTarget.VisionTransform : null);
			}
			catch
			{
			}
			Vector3 val3 = (((Object)(object)val2 != (Object)null) ? val2.position : ((Component)player).transform.position);
			RaycastHit val4 = default(RaycastHit);
			if (Physics.Linecast(val, val3, ref val4, LayerMask.op_Implicit(_visionMask)))
			{
				return (Object)(object)((Component)((RaycastHit)(ref val4)).collider).GetComponentInParent<PlayerAvatar>() == (Object)(object)player;
			}
			return true;
		}

		private void PickNewPatrolPoint()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0036: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_agent))
			{
				return;
			}
			Vector3 val = Random.insideUnitSphere * _patrolRadius + ((Component)this).transform.position;
			NavMeshHit val2 = default(NavMeshHit);
			if (NavMesh.SamplePosition(val, ref val2, _patrolRadius, -1))
			{
				if (_agent.isOnNavMesh)
				{
					_agent.SetDestination(((NavMeshHit)(ref val2)).position);
				}
				else
				{
					_agent.Warp(((NavMeshHit)(ref val2)).position);
				}
			}
		}

		private Transform ChooseNextLevelPoint()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (_levelPoints == null || _levelPoints.Length == 0)
			{
				return null;
			}
			Vector3 here = ((Component)this).transform.position;
			IEnumerable<Transform> source = _levelPoints.AsEnumerable();
			if ((Object)(object)_truckPoint != (Object)null)
			{
				source = source.Where((Transform t) => Vector3.Distance(t.position, _truckPoint.position) > 6f);
			}
			source = source.Where((Transform t) => Vector3.Distance(t.position, here) > 12f);
			List<Transform> list = source.ToList();
			if (list.Count == 0)
			{
				list = _levelPoints.ToList();
			}
			return list[Random.Range(0, list.Count)];
		}

		[IteratorStateMachine(typeof(<WarningRoutine>d__53))]
		private IEnumerator WarningRoutine(PlayerAvatar player)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WarningRoutine>d__53(0)
			{
				<>4__this = this,
				player = player
			};
		}

		private void DoAttack(PlayerAvatar player)
		{
			//IL_0009: 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)
			SecurityDroneEventRouter.BroadcastFX(SecurityDroneEventRouter.Ev.AttackFX, ((Component)this).transform.position);
			if (!SecurityDroneManager.IsAuthority())
			{
				return;
			}
			if (player != null)
			{
				PlayerHealth playerHealth = player.playerHealth;
				if (playerHealth != null)
				{
					playerHealth.Hurt(_damage, true, -1);
				}
			}
			PlayerTumble val = (((Object)(object)player != (Object)null) ? player.tumble : null);
			if ((Object)(object)val != (Object)null)
			{
				val.TumbleRequest(true, false);
				val.TumbleOverrideTime(2f);
			}
			TrySpawnStunFX(((Component)player).transform.position);
		}

		internal void PlayWarningLocal()
		{
			if (!((Object)(object)_sfx == (Object)null) && !(Time.time < _nextWarnSfxTime))
			{
				_nextWarnSfxTime = Time.time + 10f;
				AudioClip val = null;
				if (_warningClips != null && _warningClips.Length != 0)
				{
					val = _warningClips[Random.Range(0, _warningClips.Length)];
				}
				if (Object.op_Implicit((Object)(object)val))
				{
					_sfx.volume = _warningVol;
					_sfx.PlayOneShot(val);
				}
			}
		}

		internal void PlayAttackAnimLocal()
		{
			if (Object.op_Implicit((Object)(object)_anim))
			{
				_anim.SetTrigger("attack");
			}
			if ((Object)(object)_stunClip != (Object)null && (Object)(object)_sfx != (Object)null)
			{
				_sfx.volume = _stunVol;
				_sfx.PlayOneShot(_stunClip);
			}
		}

		private static void TrySpawnStunFX(Vector3 pos)
		{
			//IL_001b: 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)
			try
			{
				GameObject val = Resources.Load<GameObject>("Effects/Part Prefab Explosion");
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				GameObject val2 = Object.Instantiate<GameObject>(val, pos, Quaternion.identity);
				ParticlePrefabExplosion component = val2.GetComponent<ParticlePrefabExplosion>();
				if ((Object)(object)component != (Object)null)
				{
					component.explosionSize = 0.6f;
					component.explosionDamage = 0;
					component.explosionDamageEnemy = 0;
					component.forceMultiplier = 1.5f;
					AudioSource[] componentsInChildren = val2.GetComponentsInChildren<AudioSource>(true);
					foreach (AudioSource val3 in componentsInChildren)
					{
						val3.mute = true;
					}
				}
			}
			catch
			{
			}
		}
	}
	public class SecurityDroneEventRouter : MonoBehaviourPunCallbacks, IOnEventCallback
	{
		public enum Ev : byte
		{
			Spawn = 101,
			WarnFX,
			AttackFX,
			Despawn,
			Pose,
			HeldAdd,
			HeldRemove
		}

		private static bool _callbackHooked;

		private static GameObject _activeDrone;

		private static SecurityDroneController _ctrl;

		private static GameObject _prefab;

		private static AudioClip[] _warnClips;

		private static AudioClip _ambClip;

		private static AudioClip _stunClip;

		private static float _warnVol = 1f;

		private static float _ambVol = 0.35f;

		private static float _stunVol = 0.3f;

		internal static void SetPrefab(GameObject prefab)
		{
			_prefab = prefab;
		}

		internal static void SetAudio(AudioClip[] warnClips, AudioClip amb, AudioClip stun, float warnVol, float ambVol, float stunVol)
		{
			_warnClips = warnClips;
			_ambClip = amb;
			_stunClip = stun;
			_warnVol = Mathf.Clamp01(warnVol);
			_ambVol = Mathf.Clamp01(ambVol);
			_stunVol = Mathf.Clamp01(stunVol);
		}

		private void OnEnable()
		{
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void OnDisable()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			if (_callbackHooked)
			{
				PhotonNetwork.RemoveCallbackTarget((object)this);
			}
			_callbackHooked = false;
		}

		public override void OnJoinedRoom()
		{
			EnsureCallbackHooked();
		}

		public override void OnLeftRoom()
		{
			if (_callbackHooked)
			{
				PhotonNetwork.RemoveCallbackTarget((object)this);
				_callbackHooked = false;
			}
			LocalDespawn();
		}

		private void OnSceneLoaded(Scene s, LoadSceneMode m)
		{
			LocalDespawn();
			if (PhotonNetwork.InRoom)
			{
				EnsureCallbackHooked();
			}
		}

		private void EnsureCallbackHooked()
		{
			if (!_callbackHooked)
			{
				PhotonNetwork.AddCallbackTarget((object)this);
				_callbackHooked = true;
			}
		}

		internal static void BroadcastSpawn(Vector3 pos, Quaternion rot, int damage, float warnDelay, float patrolRadius, float engageDist, int visionMask)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0087: Expected O, but got Unknown
			CreateLocalDrone(pos, rot, damage, warnDelay, patrolRadius, engageDist, visionMask);
			if (PhotonNetwork.InRoom && PhotonNetwork.IsConnectedAndReady)
			{
				object[] array = new object[7] { pos, rot, damage, warnDelay, patrolRadius, engageDist, visionMask };
				PhotonNetwork.RaiseEvent((byte)101, (object)array, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, SendOptions.SendReliable);
			}
		}

		internal static void BroadcastFX(Ev fx, Vector3 at)
		{
			//IL_001d: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			PlayFXLocal(fx);
			if (PhotonNetwork.InRoom && PhotonNetwork.IsConnectedAndReady)
			{
				PhotonNetwork.RaiseEvent((byte)fx, (object)at, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, SendOptions.SendUnreliable);
			}
		}

		internal static void BroadcastDespawn()
		{
			//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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			LocalDespawn();
			if (PhotonNetwork.InRoom && PhotonNetwork.IsConnectedAndReady)
			{
				PhotonNetwork.RaiseEvent((byte)104, (object)null, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)0
				}, SendOptions.SendReliable);
			}
		}

		internal static void SendHeldUpdate(bool held, int physGrabberViewId)
		{
			//IL_002a: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			if (PhotonNetwork.InRoom && PhotonNetwork.IsConnectedAndReady)
			{
				Ev ev = (held ? Ev.HeldAdd : Ev.HeldRemove);
				PhotonNetwork.RaiseEvent((byte)ev, (object)physGrabberViewId, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)2
				}, SendOptions.SendReliable);
			}
		}

		private static void CreateLocalDrone(Vector3 pos, Quaternion rot, int damage, float warnDelay, float patrolRadius, float engageDist, int visionMask)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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)
			if (!Object.op_Implicit((Object)(object)_activeDrone) && !((Object)(object)_prefab == (Object)null))
			{
				NavMeshHit val = default(NavMeshHit);
				if (NavMesh.SamplePosition(pos, ref val, 4f, -1))
				{
					pos = ((NavMeshHit)(ref val)).position + Vector3.up * 0.4f;
				}
				_activeDrone = Object.Instantiate<GameObject>(_prefab, pos, rot);
				((Object)_activeDrone).name = "SecurityDrone";
				NavMeshAgent component = _activeDrone.GetComponent<NavMeshAgent>();
				if (Object.op_Implicit((Object)(object)component) && ((Behaviour)component).enabled)
				{
					component.Warp(pos);
					component.stoppingDistance = 1.5f;
				}
				_ctrl = _activeDrone.GetComponent<SecurityDroneController>();
				if (Object.op_Implicit((Object)(object)_ctrl))
				{
					_ctrl.Setup(damage, warnDelay, patrolRadius, engageDist, LayerMask.op_Implicit(visionMask));
					_ctrl.AssignAudio(_warnClips, _ambClip, _stunClip, _warnVol, _ambVol, _stunVol);
				}
			}
		}

		private static void LocalDespawn()
		{
			if (Object.op_Implicit((Object)(object)_activeDrone))
			{
				Object.Destroy((Object)(object)_activeDrone);
			}
			_activeDrone = null;
			_ctrl = null;
		}

		private static void PlayFXLocal(Ev fx)
		{
			if (!((Object)(object)_ctrl == (Object)null))
			{
				switch (fx)
				{
				case Ev.WarnFX:
					_ctrl.PlayWarningLocal();
					break;
				case Ev.AttackFX:
					_ctrl.PlayAttackAnimLocal();
					break;
				}
			}
		}

		public void OnEvent(EventData e)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Ev code = (Ev)e.Code;
				switch (code)
				{
				case Ev.Spawn:
					if (!SecurityDroneManager.IsAuthority() && e.CustomData is object[] array && array.Length >= 7)
					{
						Vector3 pos = (Vector3)array[0];
						Quaternion rot = (Quaternion)array[1];
						int damage = (int)array[2];
						float warnDelay = (float)array[3];
						float patrolRadius = (float)array[4];
						float engageDist = (float)array[5];
						int visionMask = (int)array[6];
						CreateLocalDrone(pos, rot, damage, warnDelay, patrolRadius, engageDist, visionMask);
					}
					break;
				case Ev.WarnFX:
				case Ev.AttackFX:
					PlayFXLocal(code);
					break;
				case Ev.Despawn:
					LocalDespawn();
					break;
				case Ev.Pose:
					if (!SecurityDroneManager.IsAuthority() && !((Object)(object)_ctrl == (Object)null) && e.CustomData is object[] array2 && array2.Length >= 2)
					{
						Vector3 pos2 = (Vector3)array2[0];
						Quaternion rot2 = (Quaternion)array2[1];
						_ctrl.ApplyNetworkPose(pos2, rot2);
					}
					break;
				case Ev.HeldAdd:
				case Ev.HeldRemove:
				{
					if (!SecurityDroneManager.IsAuthority())
					{
						break;
					}
					object customData = e.CustomData;
					if (!(customData is int))
					{
						break;
					}
					int num = (int)customData;
					if (1 == 0)
					{
						break;
					}
					PhotonView val = PhotonView.Find(num);
					PhysGrabber val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<PhysGrabber>() : null);
					PlayerAvatar val3 = (Object.op_Implicit((Object)(object)val2) ? ((Component)val2).GetComponentInParent<PlayerAvatar>() : null);
					if (Object.op_Implicit((Object)(object)val3))
					{
						if (code == Ev.HeldAdd)
						{
							SecurityDroneManager.MarkHeld(val3);
						}
						else
						{
							SecurityDroneManager.ClearHeld(val3);
						}
					}
					break;
				}
				}
			}
			catch
			{
			}
		}
	}
	public static class SecurityDroneManager
	{
		private static readonly List<SecurityDroneController> _drones = new List<SecurityDroneController>();

		private static readonly Dictionary<int, PhysGrabObject> _playerHeldValuable = new Dictionary<int, PhysGrabObject>();

		public static void Register(SecurityDroneController drone)
		{
			if ((Object)(object)drone != (Object)null && !_drones.Contains(drone))
			{
				_drones.Add(drone);
			}
		}

		public static void Unregister(SecurityDroneController drone)
		{
			if ((Object)(object)drone != (Object)null)
			{
				_drones.Remove(drone);
			}
		}

		public static void OnValuableGrabStarted(PlayerAvatar avatar, PhysGrabObject grabbed)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)avatar))
			{
				_playerHeldValuable[((Object)avatar).GetInstanceID()] = (Object.op_Implicit((Object)(object)grabbed) ? grabbed : null);
				if (IsAuthority())
				{
					FindNearest(((Component)avatar).transform.position)?.ConsiderEngage(avatar);
				}
			}
		}

		public static void OnGrabEnded(PlayerAvatar avatar, PhysGrabObject grabbed)
		{
			if (Object.op_Implicit((Object)(object)avatar))
			{
				_playerHeldValuable.Remove(((Object)avatar).GetInstanceID());
			}
		}

		public static void MarkHeld(PlayerAvatar avatar)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)avatar))
			{
				if (!_playerHeldValuable.ContainsKey(((Object)avatar).GetInstanceID()))
				{
					_playerHeldValuable[((Object)avatar).GetInstanceID()] = null;
				}
				if (IsAuthority())
				{
					FindNearest(((Component)avatar).transform.position)?.ConsiderEngage(avatar);
				}
			}
		}

		public static void ClearHeld(PlayerAvatar avatar)
		{
			if (Object.op_Implicit((Object)(object)avatar))
			{
				_playerHeldValuable.Remove(((Object)avatar).GetInstanceID());
			}
		}

		public static bool PlayerStillHoldingValuable(PlayerAvatar avatar)
		{
			if (!Object.op_Implicit((Object)(object)avatar))
			{
				return false;
			}
			return _playerHeldValuable.ContainsKey(((Object)avatar).GetInstanceID());
		}

		private static SecurityDroneController FindNearest(Vector3 pos)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			SecurityDroneController result = null;
			float num = float.PositiveInfinity;
			foreach (SecurityDroneController drone in _drones)
			{
				if (Object.op_Implicit((Object)(object)drone))
				{
					float num2 = Vector3.Distance(((Component)drone).transform.position, pos);
					if (num2 < num)
					{
						num = num2;
						result = drone;
					}
				}
			}
			return result;
		}

		public static bool IsAuthority()
		{
			return !GameManager.Multiplayer() || PhotonNetwork.IsMasterClient;
		}

		public static bool CanStreamPose()
		{
			return PhotonNetwork.InRoom && PhotonNetwork.IsConnectedAndReady && IsAuthority();
		}
	}
	[BepInPlugin("empress.repo.securitydrone", "Security Drone (Pumpkin-Gated + Audio)", "1.3.1")]
	public class SecurityDronePlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <WaitLevelThenSpawn>d__22 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public SecurityDronePlugin <>4__this;

			private float <t>5__1;

			private Transform <tSpawn>5__2;

			private Vector3 <pos>5__3;

			private Quaternion <rot>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitLevelThenSpawn>d__22(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<tSpawn>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0190: 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_019f: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (_spawnRoutineRunning || _spawnedThisScene)
					{
						return false;
					}
					_spawnRoutineRunning = true;
					<t>5__1 = 0f;
					goto IL_008a;
				case 1:
					<>1__state = -1;
					goto IL_008a;
				case 2:
					<>1__state = -1;
					goto IL_00ee;
				case 3:
					{
						<>1__state = -1;
						break;
					}
					IL_00ee:
					if (((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated) && <t>5__1 < 30f)
					{
						<t>5__1 += Time.unscaledDeltaTime;
						<>2__current = null;
						<>1__state = 2;
						return true;
					}
					break;
					IL_008a:
					if (!IsGameplayScene() && <t>5__1 < 30f)
					{
						<t>5__1 += Time.unscaledDeltaTime;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					if (!PhotonNetwork.InRoom && PhotonNetwork.IsConnected)
					{
						_spawnRoutineRunning = false;
						return false;
					}
					goto IL_00ee;
				}
				if (!NavMeshReady() && <t>5__1 < 30f)
				{
					<t>5__1 += Time.unscaledDeltaTime;
					<>2__current = null;
					<>1__state = 3;
					return true;
				}
				if (!SecurityDroneManager.IsAuthority())
				{
					_spawnRoutineRunning = false;
					return false;
				}
				<tSpawn>5__2 = PickRandomSpawnPoint();
				<pos>5__3 = <tSpawn>5__2.position + Vector3.up * 0.4f;
				<rot>5__4 = <tSpawn>5__2.rotation;
				SecurityDroneEventRouter.BroadcastSpawn(<pos>5__3, <rot>5__4, Damage, WarningDelay, PatrolPointRadius, EngageDistance, ((LayerMask)(ref VisionMask)).value);
				_spawnedThisScene = true;
				_spawnRoutineRunning = false;
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string PluginGuid = "empress.repo.securitydrone";

		public const string PluginName = "Security Drone (Pumpkin-Gated + Audio)";

		public const string PluginVersion = "1.3.1";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private static AssetBundle _bundle;

		private static GameObject _dronePrefab;

		public static int Damage = 10;

		public static float WarningDelay = 2f;

		public static float PatrolPointRadius = 18f;

		public static float EngageDistance = 30f;

		public static LayerMask VisionMask = LayerMask.op_Implicit(-1);

		public static float WarningVolume = 0.3f;

		public static float AmbientVolume = 0.3f;

		public static float StunVolume = 0.3f;

		private static bool _spawnRoutineRunning;

		private static bool _spawnedThisScene;

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("empress.repo.securitydrone");
			try
			{
				_harmony.PatchAll(typeof(SecurityDronePlugin).Assembly);
				LoadBundle();
				if ((Object)(object)_dronePrefab == (Object)null)
				{
					Log.LogError((object)"Drone prefab not found in AssetBundle 'security' with name 'Drone'.");
				}
				GameObject val = new GameObject("SecurityDrone_RouterHost");
				Object.DontDestroyOnLoad((Object)(object)val);
				((Object)val).hideFlags = (HideFlags)52;
				val.AddComponent<SecurityDroneEventRouter>();
				SecurityDroneEventRouter.SetPrefab(_dronePrefab);
				AudioClip[] warnClips = LoadWarningClips();
				AudioClip amb = LoadAmbientClip();
				AudioClip stun = LoadStunClip();
				SecurityDroneEventRouter.SetAudio(warnClips, amb, stun, WarningVolume, AmbientVolume, StunVolume);
				SceneManager.sceneLoaded += OnSceneLoaded;
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Init failed: {arg}");
			}
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void OnSceneLoaded(Scene s, LoadSceneMode m)
		{
			_spawnRoutineRunning = false;
			_spawnedThisScene = false;
			((MonoBehaviour)this).StopAllCoroutines();
			if ((PhotonNetwork.InRoom || !PhotonNetwork.IsConnected) && (Object)(object)_dronePrefab != (Object)null)
			{
				((MonoBehaviour)this).StartCoroutine(WaitLevelThenSpawn());
			}
		}

		private static bool IsGameplayScene()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			string text = ((Scene)(ref activeScene)).name ?? string.Empty;
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			if (text.IndexOf("Lobby", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return false;
			}
			if (text.IndexOf("Menu", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return false;
			}
			return text.IndexOf("Level", StringComparison.OrdinalIgnoreCase) >= 0;
		}

		private static bool NavMeshReady()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			NavMeshTriangulation val = NavMesh.CalculateTriangulation();
			return val.vertices != null && val.vertices.Length != 0 && val.indices != null && val.indices.Length != 0;
		}

		[IteratorStateMachine(typeof(<WaitLevelThenSpawn>d__22))]
		private IEnumerator WaitLevelThenSpawn()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitLevelThenSpawn>d__22(0)
			{
				<>4__this = this
			};
		}

		private static Transform PickRandomSpawnPoint()
		{
			//IL_0093: 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_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Expected O, but got Unknown
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			LevelGenerator instance = LevelGenerator.Instance;
			if ((Object)(object)instance != (Object)null && instance.Generated && instance.LevelPathPoints != null && instance.LevelPathPoints.Count > 0)
			{
				List<LevelPoint> list = instance.LevelPathPoints.Where((LevelPoint p) => (Object)(object)p != (Object)null).ToList();
				if ((Object)(object)instance.LevelPathTruck != (Object)null)
				{
					Vector3 truckPos = ((Component)instance.LevelPathTruck).transform.position;
					list = (from p in list.OrderBy((LevelPoint p) => Vector3.Distance(truckPos, ((Component)p).transform.position)).Skip(3)
						where Vector3.Distance(truckPos, ((Component)p).transform.position) > 6f
						select p).ToList();
					if (list.Count == 0)
					{
						list = instance.LevelPathPoints.Where((LevelPoint p) => (Object)(object)p != (Object)null).ToList();
					}
				}
				LevelPoint val = list[Random.Range(0, list.Count)];
				return ((Component)val).transform;
			}
			SpawnPoint[] array = Object.FindObjectsOfType<SpawnPoint>();
			if (array == null || array.Length == 0)
			{
				GameObject val2 = new GameObject("SecurityDrone_SpawnFallback");
				val2.transform.position = Vector3.up;
				return val2.transform;
			}
			return ((Component)array[Random.Range(0, array.Length)]).transform;
		}

		private static void LoadBundle()
		{
			if ((Object)(object)_bundle != (Object)null)
			{
				return;
			}
			try
			{
				string pluginPath = Paths.PluginPath;
				string[] array = Directory.GetFiles(pluginPath, "security", SearchOption.AllDirectories).Concat(Directory.GetFiles(pluginPath, "security.*", SearchOption.AllDirectories)).ToArray();
				string[] array2 = array;
				foreach (string text in array2)
				{
					try
					{
						_bundle = AssetBundle.LoadFromFile(text);
						if (!Object.op_Implicit((Object)(object)_bundle))
						{
							continue;
						}
						_dronePrefab = _bundle.LoadAsset<GameObject>("Drone");
						if (Object.op_Implicit((Object)(object)_dronePrefab))
						{
							if (!Object.op_Implicit((Object)(object)_dronePrefab.GetComponent<NavMeshAgent>()))
							{
								_dronePrefab.AddComponent<NavMeshAgent>();
							}
							if (!Object.op_Implicit((Object)(object)_dronePrefab.GetComponent<AudioSource>()))
							{
								_dronePrefab.AddComponent<AudioSource>();
							}
							if (!Object.op_Implicit((Object)(object)_dronePrefab.GetComponent<Animator>()))
							{
								_dronePrefab.AddComponent<Animator>();
							}
							if (!Object.op_Implicit((Object)(object)_dronePrefab.GetComponent<SecurityDroneController>()))
							{
								_dronePrefab.AddComponent<SecurityDroneController>();
							}
							Log.LogInfo((object)("Loaded AssetBundle at " + text + " with Drone prefab."));
							return;
						}
					}
					catch (Exception ex)
					{
						Log.LogWarning((object)("Failed to load bundle at " + text + ": " + ex.Message));
					}
				}
				Log.LogWarning((object)"No security AssetBundle found. Place your bundle named 'security' in the plugins folder.");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"LoadBundle failed: {arg}");
			}
		}

		private static AudioClip[] LoadWarningClips()
		{
			if ((Object)(object)_bundle == (Object)null)
			{
				return Array.Empty<AudioClip>();
			}
			string[][] array = new string[6][]
			{
				new string[1] { "warningClip" },
				new string[1] { "warning" },
				new string[1] { "warning_01" },
				new string[1] { "warning_02" },
				new string[1] { "warning_03" },
				new string[1] { "warning_04" }
			};
			List<AudioClip> list = new List<AudioClip>();
			string[][] array2 = array;
			foreach (string[] array3 in array2)
			{
				string[] array4 = array3;
				foreach (string text in array4)
				{
					AudioClip val = _bundle.LoadAsset<AudioClip>(text);
					if ((Object)(object)val != (Object)null)
					{
						list.Add(val);
					}
				}
			}
			return list.ToArray();
		}

		private static AudioClip LoadAmbientClip()
		{
			if ((Object)(object)_bundle == (Object)null)
			{
				return null;
			}
			string[] array = new string[4] { "ambient_loop", "drone_amb", "drone_loop", "ambience" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				AudioClip val = _bundle.LoadAsset<AudioClip>(text);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static AudioClip LoadStunClip()
		{
			if ((Object)(object)_bundle == (Object)null)
			{
				return null;
			}
			string[] array = new string[3] { "shoot", "stun", "zap" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				AudioClip val = _bundle.LoadAsset<AudioClip>(text);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
}