BepInEx/plugins/Stan/Hamunii.ExampleEnemy.dll

Decompiled 9 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExampleEnemy;
using ExampleEnemy.Configuration;
using GameNetcodeStuff;
using Hamunii.ExampleEnemy.NetcodePatcher;
using HarmonyLib;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[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: AssemblyCompany("Hamunii.ExampleEnemy")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.3")]
[assembly: AssemblyProduct("ExampleEnemy")]
[assembly: AssemblyTitle("Hamunii.ExampleEnemy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ExampleEnemy
{
	public struct StanStalkState : INetworkSerializable, IEquatable<StanStalkState>
	{
		public Vector3 Position;

		public Quaternion Rotation;

		public bool Visible;

		public int Encounter;

		public unsafe void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
		{
			//IL_0027: 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_003e: 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)
			serializer.SerializeValue(ref Position);
			serializer.SerializeValue(ref Rotation);
			((BufferSerializer<bool>*)(&serializer))->SerializeValue<bool>(ref Visible, default(ForPrimitives));
			((BufferSerializer<int>*)(&serializer))->SerializeValue<int>(ref Encounter, default(ForPrimitives));
		}

		public bool Equals(StanStalkState other)
		{
			//IL_0001: 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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			return Position == other.Position && Rotation == other.Rotation && Visible == other.Visible && Encounter == other.Encounter;
		}
	}
	public class ExampleEnemyAI : EnemyAI
	{
		[Header("Stan visuals and victim-only audio")]
		public GameObject stanModel = null;

		public Transform stanHead = null;

		public AudioSource localScareAudio = null;

		public AudioClip[] jumpscareClips = Array.Empty<AudioClip>();

		[Header("Outdoor scream (shared 3D sound)")]
		public AudioClip distantScreamClip = null;

		public float screamCooldown = 60f;

		public float screamRandomExtraDelay = 30f;

		public float screamMinimumDistance = 20f;

		public float screamMaximumDistance = 40f;

		[Range(0f, 1f)]
		public float screamVolume = 0.7f;

		private static float nextGlobalScream;

		private static readonly HashSet<ExampleEnemyAI> activeServerStans = new HashSet<ExampleEnemyAI>();

		public Transform turnCompass = null;

		public Transform attackArea = null;

		[Header("Stalking (no walking, chasing or damage)")]
		public float minimumStalkDistance = 12f;

		public float maximumStalkDistance = 24f;

		public float minimumCooldown = 60f;

		public float maximumCooldown = 60f;

		public float minimumDisappearDelay = 0.3f;

		public float maximumDisappearDelay = 0.5f;

		public float maximumVisibleTime = 40f;

		public float spottingRange = 45f;

		[Range(1f, 60f)]
		public float spottingAngle = 20f;

		public float modelYawOffset = 180f;

		private readonly NetworkVariable<StanStalkState> stalkState = new NetworkVariable<StanStalkState>(default(StanStalkState), (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		private Random random = null;

		private Coroutine? vanishRoutine;

		private bool prepared;

		private bool pendingSpot;

		private float nextAppearance;

		private float visibleUntil;

		private float nextSpotReport;

		private int lastScareEncounter = -1;

		private int geometryMask;

		private float nextAppearanceDiagnostic;

		private Vector3 HeadPosition => ((Object)(object)stanHead != (Object)null) ? stanHead.position : (((Component)this).transform.position + Vector3.up * 1.7f);

		public override void OnNetworkSpawn()
		{
			((NetworkBehaviour)this).OnNetworkSpawn();
			NetworkVariable<StanStalkState> obj = stalkState;
			obj.OnValueChanged = (OnValueChangedDelegate<StanStalkState>)(object)Delegate.Combine((Delegate?)(object)obj.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<StanStalkState>(OnStalkStateChanged));
		}

		public override void OnNetworkDespawn()
		{
			activeServerStans.Remove(this);
			NetworkVariable<StanStalkState> obj = stalkState;
			obj.OnValueChanged = (OnValueChangedDelegate<StanStalkState>)(object)Delegate.Remove((Delegate?)(object)obj.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<StanStalkState>(OnStalkStateChanged));
			if (vanishRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(vanishRoutine);
			}
			((NetworkBehaviour)this).OnNetworkDespawn();
		}

		public override void Start()
		{
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Expected O, but got Unknown
			((EnemyAI)this).Start();
			EnemyAICollisionDetect[] componentsInChildren = ((Component)this).GetComponentsInChildren<EnemyAICollisionDetect>(true);
			foreach (EnemyAICollisionDetect val in componentsInChildren)
			{
				val.mainScript = (EnemyAI)(object)this;
			}
			base.isOutside = true;
			random = new Random(StartOfRound.Instance.randomMapSeed + base.thisEnemyIndex * 7919);
			geometryMask = StartOfRound.Instance.collidersAndRoomMaskAndDefault;
			if ((Object)(object)stanModel == (Object)null)
			{
				Transform obj = ((Component)this).transform.Find("StanEnemy");
				stanModel = ((obj != null) ? ((Component)obj).gameObject : null);
			}
			if ((Object)(object)stanModel == (Object)null)
			{
				Plugin.Logger.LogError((object)"StanEnemy visual is missing; disabling stalking AI.");
				((Behaviour)this).enabled = false;
				return;
			}
			if ((Object)(object)stanHead == (Object)null)
			{
				Transform[] componentsInChildren2 = stanModel.GetComponentsInChildren<Transform>(true);
				foreach (Transform val2 in componentsInChildren2)
				{
					if (((Object)val2).name == "Head")
					{
						stanHead = val2;
						break;
					}
				}
			}
			if ((Object)(object)localScareAudio == (Object)null)
			{
				Transform obj2 = ((Component)this).transform.Find("LocalScareAudio");
				localScareAudio = ((obj2 != null) ? ((Component)obj2).GetComponent<AudioSource>() : null);
			}
			if ((Object)(object)localScareAudio == (Object)null)
			{
				GameObject val3 = new GameObject("LocalScareAudio");
				val3.transform.SetParent(((Component)this).transform, false);
				localScareAudio = val3.AddComponent<AudioSource>();
				localScareAudio.volume = 0.5f;
			}
			localScareAudio.playOnAwake = false;
			localScareAudio.loop = false;
			localScareAudio.spatialBlend = 0f;
			localScareAudio.dopplerLevel = 0f;
			localScareAudio.Stop();
			if ((Object)(object)base.creatureVoice != (Object)null)
			{
				base.creatureVoice.Stop();
				base.creatureVoice.playOnAwake = false;
			}
			if ((Object)(object)base.creatureSFX != (Object)null)
			{
				base.creatureSFX.Stop();
				base.creatureSFX.playOnAwake = false;
			}
			Transform val4 = ((Component)this).transform.Find("ExampleEnemyModel");
			if ((Object)(object)val4 != (Object)null)
			{
				((Component)val4).gameObject.SetActive(false);
			}
			Animator[] componentsInChildren3 = stanModel.GetComponentsInChildren<Animator>(true);
			foreach (Animator val5 in componentsInChildren3)
			{
				((Behaviour)val5).enabled = false;
			}
			Collider[] componentsInChildren4 = ((Component)this).GetComponentsInChildren<Collider>(true);
			foreach (Collider val6 in componentsInChildren4)
			{
				val6.enabled = false;
			}
			if ((Object)(object)base.agent != (Object)null)
			{
				((Behaviour)base.agent).enabled = true;
				base.agent.updatePosition = false;
				base.agent.updateRotation = false;
				base.agent.speed = 0f;
				if (base.agent.isOnNavMesh)
				{
					base.agent.isStopped = true;
				}
			}
			base.movingTowardsTargetPlayer = false;
			base.moveTowardsDestination = false;
			prepared = true;
			ApplyState(stalkState.Value);
			if (((NetworkBehaviour)this).IsServer)
			{
				activeServerStans.RemoveWhere((ExampleEnemyAI stan) => (Object)(object)stan == (Object)null || !((NetworkBehaviour)stan).IsSpawned);
				if (activeServerStans.Count == 0)
				{
					nextGlobalScream = Time.time + RandomBetween(screamCooldown, screamCooldown + screamRandomExtraDelay);
				}
				activeServerStans.Add(this);
				nextAppearance = Time.time + RandomBetween(minimumCooldown, maximumCooldown);
				Plugin.Logger.LogInfo((object)$"[Stan AI] Initialized id={((NetworkBehaviour)this).NetworkObjectId}; hidden for {nextAppearance - Time.time:0}s; jumpscares={jumpscareClips.Length}; distantScream={(Object)(object)distantScreamClip != (Object)null}.");
			}
		}

		public override void Update()
		{
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			if (!prepared || !((NetworkBehaviour)this).IsSpawned || (Object)(object)StartOfRound.Instance == (Object)null)
			{
				return;
			}
			if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled && base.agent.isOnNavMesh && !base.agent.isStopped)
			{
				base.agent.isStopped = true;
			}
			if (((NetworkBehaviour)this).IsServer)
			{
				if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
				{
					if (stalkState.Value.Visible)
					{
						HideWithoutScare();
					}
					return;
				}
				if (stalkState.Value.Visible && !HasOutdoorPlayer())
				{
					HideWithoutScare();
				}
				if ((Object)(object)distantScreamClip != (Object)null && Time.time >= nextGlobalScream)
				{
					if (TryOutdoorScream())
					{
						nextGlobalScream = Time.time + RandomBetween(Mathf.Max(60f, screamCooldown), Mathf.Max(60f, screamCooldown) + Mathf.Max(0f, screamRandomExtraDelay));
					}
					else
					{
						nextGlobalScream = Time.time + 3f;
					}
				}
				if (!stalkState.Value.Visible && !pendingSpot && Time.time >= nextAppearance)
				{
					if (!TryAppear())
					{
						nextAppearance = Time.time + 3f;
						if (Time.time >= nextAppearanceDiagnostic)
						{
							nextAppearanceDiagnostic = Time.time + 15f;
							Plugin.Logger.LogInfo((object)(HasOutdoorPlayer() ? "[Stan AI] Waiting for a reachable, unseen outdoor stalking position; retrying in 3s." : "[Stan AI] Waiting for a living player outside the facility and ship."));
						}
					}
				}
				else if (stalkState.Value.Visible && !pendingSpot && Time.time >= visibleUntil)
				{
					HideWithoutScare();
				}
			}
			PlayerControllerB player = GameNetworkManager.Instance?.localPlayerController;
			if (stalkState.Value.Visible && Eligible(player) && Time.time >= nextSpotReport && IsLookingAt(player, HeadPosition, spottingAngle, spottingRange))
			{
				nextSpotReport = Time.time + 0.25f;
				ReportSpottedServerRpc(stalkState.Value.Encounter);
			}
		}

		public override void DoAIInterval()
		{
		}

		public override void OnCollideWithPlayer(Collider other)
		{
		}

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

		private bool Eligible(PlayerControllerB? player)
		{
			return (Object)(object)player != (Object)null && player.isPlayerControlled && !player.isPlayerDead && !player.isInsideFactory && !player.isInHangarShipRoom;
		}

		private bool HasOutdoorPlayer()
		{
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB player in allPlayerScripts)
			{
				if (Eligible(player))
				{
					return true;
				}
			}
			return false;
		}

		private bool TryOutdoorScream()
		{
			//IL_008c: 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_00ab: 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_00b5: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_010e: 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_012b: 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_0142: Invalid comparison between Unknown and I4
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			if (allPlayerScripts.Length == 0)
			{
				return false;
			}
			int num = random.Next(allPlayerScripts.Length);
			NavMeshHit val3 = default(NavMeshHit);
			NavMeshHit val5 = default(NavMeshHit);
			for (int i = 0; i < allPlayerScripts.Length; i++)
			{
				PlayerControllerB val = allPlayerScripts[(num + i) % allPlayerScripts.Length];
				if (!Eligible(val))
				{
					continue;
				}
				for (int j = 0; j < 16; j++)
				{
					float num2 = RandomBetween(0f, MathF.PI * 2f);
					float num3 = RandomBetween(screamMinimumDistance, screamMaximumDistance);
					Vector3 val2 = ((Component)val).transform.position + new Vector3(Mathf.Sin(num2), 0f, Mathf.Cos(num2)) * num3;
					if (!NavMesh.SamplePosition(val2, ref val3, 3f, -1) || Mathf.Abs(((NavMeshHit)(ref val3)).position.y - ((Component)val).transform.position.y) > 5f)
					{
						continue;
					}
					NavMeshPath val4 = new NavMeshPath();
					if (NavMesh.SamplePosition(((Component)val).transform.position, ref val5, 3f, -1) && NavMesh.CalculatePath(((NavMeshHit)(ref val5)).position, ((NavMeshHit)(ref val3)).position, -1, val4) && (int)val4.status <= 0)
					{
						Vector3 val6 = ((NavMeshHit)(ref val3)).position + Vector3.up * 2f;
						if (!Physics.CheckSphere(val6, 0.4f, geometryMask, (QueryTriggerInteraction)1))
						{
							PlayOutdoorScreamClientRpc(val6, RandomBetween(0.95f, 1.05f));
							return true;
						}
					}
				}
			}
			return false;
		}

		[ClientRpc]
		public void PlayOutdoorScreamClientRpc(Vector3 sourcePosition, float pitch)
		{
			//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_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0115: 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 val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(2965938531u, val2, (RpcDelivery)0);
				((FastBufferWriter)(ref val)).WriteValueSafe(ref sourcePosition);
				((FastBufferWriter)(ref val)).WriteValueSafe<float>(ref pitch, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 2965938531u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				if (!((Object)(object)distantScreamClip == (Object)null))
				{
					GameObject val3 = new GameObject("StanOutdoorScream");
					val3.transform.position = sourcePosition;
					AudioSource val4 = val3.AddComponent<AudioSource>();
					val4.playOnAwake = false;
					val4.loop = false;
					val4.clip = distantScreamClip;
					val4.spatialBlend = 1f;
					val4.rolloffMode = (AudioRolloffMode)1;
					val4.minDistance = 10f;
					val4.maxDistance = 100f;
					val4.dopplerLevel = 0f;
					val4.volume = screamVolume;
					val4.pitch = pitch;
					val4.Play();
					Object.Destroy((Object)(object)val3, distantScreamClip.length / Mathf.Max(0.1f, pitch) + 0.5f);
				}
			}
		}

		private bool ClearSight(Vector3 from, Vector3 to)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return !Physics.Linecast(from, to, geometryMask, (QueryTriggerInteraction)1);
		}

		private bool IsLookingAt(PlayerControllerB player, Vector3 point, float angle, float range)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_007f: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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)
			Camera gameplayCamera = player.gameplayCamera;
			if ((Object)(object)gameplayCamera == (Object)null)
			{
				return false;
			}
			Vector3 val = point - ((Component)gameplayCamera).transform.position;
			if (((Vector3)(ref val)).sqrMagnitude > range * range || Vector3.Angle(((Component)gameplayCamera).transform.forward, val) > angle)
			{
				return false;
			}
			Vector3 val2 = gameplayCamera.WorldToViewportPoint(point);
			return val2.z > 0f && val2.x > 0f && val2.x < 1f && val2.y > 0f && val2.y < 1f && ClearSight(((Component)gameplayCamera).transform.position, point);
		}

		[ServerRpc(RequireOwnership = false)]
		public void ReportSpottedServerRpc(int encounter, ServerRpcParams rpcParams = default(ServerRpcParams))
		{
			//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)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: 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_01b5: 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))
			{
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendServerRpc(1671309556u, rpcParams, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, encounter);
				((NetworkBehaviour)this).__endSendServerRpc(ref val, 1671309556u, rpcParams, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsServer && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if (!prepared || pendingSpot || !stalkState.Value.Visible || encounter != stalkState.Value.Encounter || base.isEnemyDead)
			{
				return;
			}
			PlayerControllerB val2 = null;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val3 in allPlayerScripts)
			{
				if (Eligible(val3) && val3.actualClientId == rpcParams.Receive.SenderClientId)
				{
					val2 = val3;
					break;
				}
			}
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.gameplayCamera == (Object)null) && !(Vector3.Distance(((Component)val2.gameplayCamera).transform.position, HeadPosition) > spottingRange) && ClearSight(((Component)val2.gameplayCamera).transform.position, HeadPosition))
			{
				pendingSpot = true;
				vanishRoutine = ((MonoBehaviour)this).StartCoroutine(VanishAfterDelay(encounter, rpcParams.Receive.SenderClientId));
			}
		}

		private IEnumerator VanishAfterDelay(int encounter, ulong victimClientId)
		{
			yield return (object)new WaitForSeconds(RandomBetween(minimumDisappearDelay, maximumDisappearDelay));
			if (((NetworkBehaviour)this).IsSpawned && !base.isEnemyDead && stalkState.Value.Visible && stalkState.Value.Encounter == encounter)
			{
				StanStalkState state = stalkState.Value;
				state.Visible = false;
				stalkState.Value = state;
				if (((NetworkBehaviour)this).NetworkManager.ConnectedClients.ContainsKey(victimClientId))
				{
					PlayVictimScareClientRpc(encounter, new ClientRpcParams
					{
						Send = new ClientRpcSendParams
						{
							TargetClientIds = new ulong[1] { victimClientId }
						}
					});
				}
				nextAppearance = Time.time + RandomBetween(minimumCooldown, maximumCooldown);
			}
			pendingSpot = false;
			vanishRoutine = null;
		}

		[ClientRpc]
		public void PlayVictimScareClientRpc(int encounter, ClientRpcParams rpcParams = default(ClientRpcParams))
		{
			//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)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(3473626919u, rpcParams, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, encounter);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 3473626919u, rpcParams, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if (!prepared || encounter <= lastScareEncounter)
			{
				return;
			}
			lastScareEncounter = encounter;
			if (encounter == stalkState.Value.Encounter)
			{
				stanModel.SetActive(false);
			}
			PlayerControllerB player = GameNetworkManager.Instance?.localPlayerController;
			if (Eligible(player) && !((Object)(object)localScareAudio == (Object)null) && jumpscareClips.Length != 0)
			{
				AudioClip val2 = jumpscareClips[Random.Range(0, jumpscareClips.Length)];
				if ((Object)(object)val2 != (Object)null)
				{
					localScareAudio.PlayOneShot(val2);
				}
			}
		}

		private bool TryAppear()
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Expected O, but got Unknown
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Invalid comparison between Unknown and I4
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			if (allPlayerScripts.Length == 0)
			{
				return false;
			}
			int num = random.Next(allPlayerScripts.Length);
			NavMeshHit val3 = default(NavMeshHit);
			NavMeshHit val6 = default(NavMeshHit);
			for (int i = 0; i < allPlayerScripts.Length; i++)
			{
				PlayerControllerB val = allPlayerScripts[(num + i) % allPlayerScripts.Length];
				if (!Eligible(val) || (Object)(object)val.gameplayCamera == (Object)null)
				{
					continue;
				}
				for (int j = 0; j < 24; j++)
				{
					float num2 = RandomBetween(0f, MathF.PI * 2f);
					float num3 = RandomBetween(minimumStalkDistance, maximumStalkDistance);
					Vector3 val2 = ((Component)val).transform.position + new Vector3(Mathf.Sin(num2), 0f, Mathf.Cos(num2)) * num3;
					int num4 = (((Object)(object)base.agent != (Object)null) ? base.agent.areaMask : (-1));
					if (!NavMesh.SamplePosition(val2, ref val3, 2f, num4) || Mathf.Abs(((NavMeshHit)(ref val3)).position.y - ((Component)val).transform.position.y) > 3f)
					{
						continue;
					}
					float num5 = Vector3.Distance(((Component)val).transform.position, ((NavMeshHit)(ref val3)).position);
					if (num5 < minimumStalkDistance || num5 > maximumStalkDistance)
					{
						continue;
					}
					Vector3 val4 = ((NavMeshHit)(ref val3)).position + Vector3.up * 1.7f;
					if (!ClearSight(((Component)val.gameplayCamera).transform.position, val4) || Physics.CheckCapsule(((NavMeshHit)(ref val3)).position + Vector3.up * 0.45f, ((NavMeshHit)(ref val3)).position + Vector3.up * 1.6f, 0.35f, geometryMask, (QueryTriggerInteraction)1))
					{
						continue;
					}
					NavMeshPath val5 = new NavMeshPath();
					if (!NavMesh.SamplePosition(((Component)val).transform.position, ref val6, 2f, num4) || !NavMesh.CalculatePath(((NavMeshHit)(ref val6)).position, ((NavMeshHit)(ref val3)).position, num4, val5) || (int)val5.status > 0)
					{
						continue;
					}
					bool flag = false;
					PlayerControllerB[] array = allPlayerScripts;
					foreach (PlayerControllerB val7 in array)
					{
						if (Eligible(val7) && (Vector3.Distance(((Component)val7).transform.position, ((NavMeshHit)(ref val3)).position) < 8f || IsLookingAt(val7, val4, 65f, spottingRange)))
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						Vector3 val8 = ((Component)val.gameplayCamera).transform.position - ((NavMeshHit)(ref val3)).position;
						val8.y = 0f;
						stalkState.Value = new StanStalkState
						{
							Position = ((NavMeshHit)(ref val3)).position,
							Rotation = Quaternion.LookRotation(((Vector3)(ref val8)).normalized, Vector3.up) * Quaternion.Euler(0f, modelYawOffset, 0f),
							Visible = true,
							Encounter = stalkState.Value.Encounter + 1
						};
						visibleUntil = Time.time + Mathf.Max(1f, maximumVisibleTime);
						Plugin.Logger.LogInfo((object)$"[Stan AI] Visible encounter={stalkState.Value.Encounter} at {((NavMeshHit)(ref val3)).position}.");
						return true;
					}
				}
			}
			return false;
		}

		private void HideWithoutScare()
		{
			StanStalkState value = stalkState.Value;
			value.Visible = false;
			stalkState.Value = value;
			nextAppearance = Time.time + RandomBetween(minimumCooldown, maximumCooldown);
		}

		private void OnStalkStateChanged(StanStalkState previous, StanStalkState current)
		{
			if (prepared)
			{
				ApplyState(current);
			}
		}

		private void ApplyState(StanStalkState state)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (state.Encounter > 0)
			{
				((Component)this).transform.SetPositionAndRotation(state.Position, state.Rotation);
				if ((Object)(object)base.agent != (Object)null && ((Behaviour)base.agent).enabled)
				{
					base.agent.Warp(state.Position);
					if (base.agent.isOnNavMesh)
					{
						base.agent.isStopped = true;
					}
				}
				base.serverPosition = state.Position;
			}
			stanModel.SetActive(state.Visible && lastScareEncounter != state.Encounter);
		}

		private float RandomBetween(float minimum, float maximum)
		{
			return Mathf.Max(0f, minimum) + (float)random.NextDouble() * Mathf.Max(0f, maximum - Mathf.Max(0f, minimum));
		}

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

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(2965938531u, new RpcReceiveHandler(__rpc_handler_2965938531), "PlayOutdoorScreamClientRpc");
			((NetworkBehaviour)this).__registerRpc(1671309556u, new RpcReceiveHandler(__rpc_handler_1671309556), "ReportSpottedServerRpc");
			((NetworkBehaviour)this).__registerRpc(3473626919u, new RpcReceiveHandler(__rpc_handler_3473626919), "PlayVictimScareClientRpc");
			((EnemyAI)this).__initializeRpcs();
		}

		private static void __rpc_handler_2965938531(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//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)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				Vector3 sourcePosition = default(Vector3);
				((FastBufferReader)(ref reader)).ReadValueSafe(ref sourcePosition);
				float pitch = default(float);
				((FastBufferReader)(ref reader)).ReadValueSafe<float>(ref pitch, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ExampleEnemyAI)(object)target).PlayOutdoorScreamClientRpc(sourcePosition, pitch);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1671309556(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int encounter = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref encounter);
				ServerRpcParams server = rpcParams.Server;
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ExampleEnemyAI)(object)target).ReportSpottedServerRpc(encounter, server);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3473626919(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int encounter = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref encounter);
				ClientRpcParams client = rpcParams.Client;
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((ExampleEnemyAI)(object)target).PlayVictimScareClientRpc(encounter, client);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "ExampleEnemyAI";
		}
	}
	[BepInPlugin("Hamunii.ExampleEnemy", "Stan", "1.0.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger = null;

		public static AssetBundle? ModAssets;

		private static EnemyType stanType = null;

		private static bool spawnedThisLanding;

		private static float nextSpawnCheck;

		private static float nextSpawnDiagnostic;

		private static string lastSpawnStage = "";

		private static bool spawnWatchdogReady;

		private static RoundManager? timerOwner;

		private static Coroutine? spawnLoop;

		internal static PluginConfig BoundConfig { get; private set; } = null;

		private void Awake()
		{
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Expected O, but got Unknown
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			BoundConfig = new PluginConfig(((BaseUnityPlugin)this).Config);
			InitializeNetworkBehaviours();
			ModAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "modassets"));
			if ((Object)(object)ModAssets == (Object)null)
			{
				Logger.LogError((object)"Failed to load Stan's modassets bundle.");
				return;
			}
			stanType = ModAssets.LoadAsset<EnemyType>("ExampleEnemy");
			TerminalNode val = ModAssets.LoadAsset<TerminalNode>("ExampleEnemyTN");
			TerminalKeyword val2 = ModAssets.LoadAsset<TerminalKeyword>("ExampleEnemyTK");
			if ((Object)(object)stanType == (Object)null || (Object)(object)stanType.enemyPrefab == (Object)null)
			{
				Logger.LogError((object)"Stan's EnemyType or prefab is missing.");
				return;
			}
			stanType.enemyName = "Stan";
			stanType.isOutsideEnemy = true;
			stanType.isDaytimeEnemy = false;
			stanType.spawningDisabled = false;
			stanType.MaxCount = 1;
			if ((Object)(object)val != (Object)null)
			{
				val.creatureName = "Stan";
				val.displayText = "Stan\n\nA silent outdoor stalker. He vanishes shortly after being spotted.\n";
			}
			if ((Object)(object)val2 != (Object)null)
			{
				val2.word = "stan";
			}
			ScanNodeProperties[] componentsInChildren = stanType.enemyPrefab.GetComponentsInChildren<ScanNodeProperties>(true);
			foreach (ScanNodeProperties val3 in componentsInChildren)
			{
				val3.headerText = "Stan";
			}
			Transform val4 = stanType.enemyPrefab.transform.Find("StanEnemy");
			if ((Object)(object)val4 != (Object)null)
			{
				((Component)val4).gameObject.SetActive(false);
			}
			ExampleEnemyAI component = stanType.enemyPrefab.GetComponent<ExampleEnemyAI>();
			if ((Object)(object)component == (Object)null)
			{
				Logger.LogError((object)"Stan prefab has no stalking AI component.");
				return;
			}
			int num = 0;
			EnemyAICollisionDetect[] componentsInChildren2 = stanType.enemyPrefab.GetComponentsInChildren<EnemyAICollisionDetect>(true);
			foreach (EnemyAICollisionDetect val5 in componentsInChildren2)
			{
				val5.mainScript = (EnemyAI)(object)component;
				num++;
			}
			Logger.LogInfo((object)$"Stan prefab ready: repaired {num} collision AI references.");
			NetworkPrefabs.RegisterNetworkPrefab(stanType.enemyPrefab);
			Enemies.RegisterEnemy(stanType, 0, (LevelTypes)(-1), val, val2);
			spawnWatchdogReady = true;
			Harmony val6 = new Harmony("Hamunii.ExampleEnemy.StanSpawn");
			string[] array = new string[4] { "LoadNewLevel", "FinishGeneratingLevel", "SpawnDaytimeEnemiesOutside", "SpawnEnemiesOutside" };
			foreach (string text in array)
			{
				val6.Patch((MethodBase)AccessTools.Method(typeof(RoundManager), text, (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "LevelLifecyclePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			Logger.LogInfo((object)"[Stan spawn] Level lifecycle hooks installed (spawn repair 4).");
			Update();
			Logger.LogInfo((object)$"Stan spawn watchdog enabled. Plugin active: {((Behaviour)this).isActiveAndEnabled}.");
			Logger.LogInfo((object)"Stan registered: outdoor-only on every moon, 60-second appearance cooldown.");
		}

		internal static void Update()
		{
			if (!spawnWatchdogReady || (Object)(object)stanType == (Object)null || Time.unscaledTime < nextSpawnCheck)
			{
				return;
			}
			nextSpawnCheck = Time.unscaledTime + 1f;
			try
			{
				CheckStanSpawn();
			}
			catch (Exception ex)
			{
				SpawnDiagnostic("exception", "Spawn watchdog recovered from an error: " + ex, warning: true);
			}
		}

		private static void LevelLifecyclePostfix(RoundManager __instance)
		{
			Logger.LogInfo((object)"[Stan spawn] Game level lifecycle callback received.");
			if ((Object)(object)timerOwner != (Object)null && spawnLoop != null)
			{
				((MonoBehaviour)timerOwner).StopCoroutine(spawnLoop);
			}
			timerOwner = __instance;
			spawnLoop = ((MonoBehaviour)__instance).StartCoroutine(LevelSpawnLoop(__instance));
			Update();
		}

		private static IEnumerator LevelSpawnLoop(RoundManager owner)
		{
			Logger.LogInfo((object)"[Stan spawn] RoundManager coroutine is running.");
			while ((Object)(object)owner != (Object)null)
			{
				Update();
				yield return (object)new WaitForSecondsRealtime(1f);
			}
			timerOwner = null;
		}

		private static void SpawnDiagnostic(string stage, string message, bool warning = false)
		{
			if (!(stage == lastSpawnStage) || !(Time.unscaledTime < nextSpawnDiagnostic))
			{
				lastSpawnStage = stage;
				nextSpawnDiagnostic = Time.unscaledTime + 15f;
				if (warning)
				{
					Logger.LogWarning((object)("[Stan spawn] " + message));
				}
				else
				{
					Logger.LogInfo((object)("[Stan spawn] " + message));
				}
			}
		}

		private static void CheckStanSpawn()
		{
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager singleton = NetworkManager.Singleton;
			StartOfRound instance = StartOfRound.Instance;
			RoundManager instance2 = RoundManager.Instance;
			if ((Object)(object)singleton == (Object)null || !singleton.IsListening)
			{
				spawnedThisLanding = false;
				SpawnDiagnostic("network", "Waiting for a host session.");
			}
			else if (!singleton.IsServer)
			{
				SpawnDiagnostic("client", "Remote client: only the host creates Stan.");
			}
			else if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null)
			{
				SpawnDiagnostic("round", "Waiting for round managers.");
			}
			else if (instance.inShipPhase || instance.shipIsLeaving)
			{
				spawnedThisLanding = false;
				SpawnDiagnostic("orbit", $"Waiting for landing: inShipPhase={instance.inShipPhase}, leaving={instance.shipIsLeaving}.");
			}
			else if (!instance.shipHasLanded)
			{
				SpawnDiagnostic("landing", "Landing sequence is still running.");
			}
			else
			{
				if (spawnedThisLanding)
				{
					return;
				}
				bool flag = false;
				ExampleEnemyAI[] array = Object.FindObjectsOfType<ExampleEnemyAI>();
				foreach (ExampleEnemyAI exampleEnemyAI in array)
				{
					if (((NetworkBehaviour)exampleEnemyAI).IsSpawned && !((EnemyAI)exampleEnemyAI).isEnemyDead)
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					spawnedThisLanding = true;
					SpawnDiagnostic("existing", "Existing networked Stan found; avoiding a duplicate.");
					return;
				}
				NavMeshAgent componentInChildren = stanType.enemyPrefab.GetComponentInChildren<NavMeshAgent>(true);
				int num = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.agentTypeID : 0);
				if (!TryOutdoorPoint(instance2, instance, num, out Vector3 position, out string reason))
				{
					SpawnDiagnostic("navigation", reason, warning: true);
					return;
				}
				SpawnDiagnostic("spawning", $"Landing ready. Spawning at {position}, agent type={num}.");
				NetworkObjectReference val = instance2.SpawnEnemyGameObject(position, 0f, -1, stanType);
				NetworkObject val2 = default(NetworkObject);
				if (((NetworkObjectReference)(ref val)).TryGet(ref val2, (NetworkManager)null))
				{
					spawnedThisLanding = true;
					Logger.LogInfo((object)$"[Stan spawn] Network spawn confirmed; id={val2.NetworkObjectId}. First appearance waits 60 seconds.");
				}
				else
				{
					SpawnDiagnostic("reference", "Spawn call returned no resolvable network object; retrying.", warning: true);
				}
			}
		}

		private static bool TryOutdoorPoint(RoundManager manager, StartOfRound round, int agentType, out Vector3 position, out string reason)
		{
			//IL_0003: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			NavMeshQueryFilter val = default(NavMeshQueryFilter);
			((NavMeshQueryFilter)(ref val)).agentTypeID = agentType;
			((NavMeshQueryFilter)(ref val)).areaMask = -1;
			NavMeshQueryFilter val2 = val;
			GameObject[] outsideAINodes = manager.outsideAINodes;
			int num = ((outsideAINodes != null) ? outsideAINodes.Length : 0);
			if (manager.outsideAINodes != null)
			{
				GameObject[] outsideAINodes2 = manager.outsideAINodes;
				NavMeshHit val4 = default(NavMeshHit);
				foreach (GameObject val3 in outsideAINodes2)
				{
					if ((Object)(object)val3 != (Object)null && NavMesh.SamplePosition(val3.transform.position, ref val4, 10f, val2))
					{
						position = ((NavMeshHit)(ref val4)).position;
						reason = "cached outdoor node";
						return true;
					}
				}
			}
			GameObject[] array = GameObject.FindGameObjectsWithTag("OutsideAINode");
			GameObject[] array2 = array;
			NavMeshHit val6 = default(NavMeshHit);
			foreach (GameObject val5 in array2)
			{
				if ((Object)(object)val5 != (Object)null && NavMesh.SamplePosition(val5.transform.position, ref val6, 10f, val2))
				{
					position = ((NavMeshHit)(ref val6)).position;
					reason = "fresh outdoor node";
					return true;
				}
			}
			PlayerControllerB[] allPlayerScripts = round.allPlayerScripts;
			NavMeshHit val8 = default(NavMeshHit);
			foreach (PlayerControllerB val7 in allPlayerScripts)
			{
				if ((Object)(object)val7 != (Object)null && val7.isPlayerControlled && !val7.isPlayerDead && !val7.isInsideFactory && !val7.isInHangarShipRoom && NavMesh.SamplePosition(((Component)val7).transform.position, ref val8, 4f, val2))
				{
					position = ((NavMeshHit)(ref val8)).position;
					reason = "outdoor player navigation";
					return true;
				}
			}
			position = default(Vector3);
			reason = $"No outdoor NavMesh position yet: cachedNodes={num}, sceneNodes={array.Length}, agentType={agentType}. Retrying automatically.";
			return false;
		}

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

		public const string PLUGIN_NAME = "Stan";

		public const string PLUGIN_VERSION = "1.0.3";
	}
}
namespace ExampleEnemy.Configuration
{
	public class PluginConfig
	{
		public ConfigEntry<int> SpawnWeight;

		public PluginConfig(ConfigFile cfg)
		{
			SpawnWeight = cfg.Bind<int>("General", "Spawn weight", 20, "The spawn chance weight for ExampleEnemy, relative to other existing enemies.\nGoes up from 0, lower is more rare, 100 and up is very common.");
			ClearUnusedEntries(cfg);
		}

		private void ClearUnusedEntries(ConfigFile cfg)
		{
			PropertyInfo property = ((object)cfg).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(cfg, null);
			dictionary.Clear();
			cfg.Save();
		}
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
			NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializable<StanStalkState>();
			NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<StanStalkState>();
		}
	}
}
namespace Hamunii.ExampleEnemy.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}