Decompiled source of Coilhead Enemy v1.0.0

BepInEx\plugins\Empress-Coilhead\Coilhead.dll

Decompiled 4 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.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using REPOLib.Modules;
using REPOLib.Objects.Sdk;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Networking;

[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("Empress")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Coilhead")]
[assembly: AssemblyTitle("Coilhead")]
[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 Empress.REPO.Coilhead
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Empress.REPO.Coilhead", "Empress REPO Coilhead", "1.0.0")]
	public sealed class EmpressRepoCoilheadPlugin : BaseUnityPlugin
	{
		private const string CoilheadBundleFileName = "empresscoilhead";

		private const float CoilheadBundleVisualScale = 0.88f;

		private const string CoilheadAlbedoTextureFileName = "SpringManTexV2.png";

		private const string CoilheadNormalTextureFileName = "SpringManNormalTex.png";

		private static readonly string[] CoilheadBundlePrefabCandidates = new string[4] { "SpringMan", "Coilhead", "Spring Man", "Coil Head" };

		private static readonly FieldInfo EnemySetupField = AccessTools.Field(typeof(EnemyContent), "_setup");

		private static readonly FieldInfo SpawnObjectsField = AccessTools.Field(typeof(EnemyContent), "_spawnObjects");

		internal const string PluginGuid = "Empress.REPO.Coilhead";

		internal const string PluginName = "Empress REPO Coilhead";

		internal const string PluginVersion = "1.0.0";

		internal const string TemplatePrefabName = "EmpressCoilheadPrefab";

		private static Harmony? _harmony;

		private static bool _registered;

		private static MethodInfo? _spawnManagerRefreshMethod;

		private static AssetBundle? _coilheadBundle;

		private static GameObject? _coilheadVisualPrefab;

		private static Material? _coilheadVisibleMaterial;

		private static Texture2D? _coilheadAlbedoTexture;

		private static Texture2D? _coilheadNormalTexture;

		internal static ManualLogSource Log { get; private set; } = null;


		internal static string PluginDirectory { get; private set; } = string.Empty;


		private void Awake()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Plugin location: " + ((BaseUnityPlugin)this).Info.Location));
			PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? string.Empty;
			((Component)this).transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			if (_harmony == null)
			{
				_harmony = new Harmony("Empress.REPO.Coilhead");
			}
			PatchTemplateGuards(_harmony);
			((MonoBehaviour)this).StartCoroutine(EmpressRepoCoilheadAudioBank.LoadAudioAsync(((BaseUnityPlugin)this).Logger));
			RegisterEnemy();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded Empress REPO Coilhead v1.0.0");
		}

		private void RegisterEnemy()
		{
			if (!_registered)
			{
				GameObject item = CoilheadTemplateBootstrap.CreateTemplate(((BaseUnityPlugin)this).Logger);
				RarityPreset val = ScriptableObject.CreateInstance<RarityPreset>();
				((Object)val).hideFlags = (HideFlags)61;
				((Object)val).name = "Rarity - Coilhead";
				val.chance = 60f;
				EnemySetup val2 = ScriptableObject.CreateInstance<EnemySetup>();
				((Object)val2).hideFlags = (HideFlags)61;
				((Object)val2).name = "Enemy - Coilhead";
				val2.spawnObjects = new List<PrefabRef>();
				val2.levelsCompletedCondition = false;
				val2.levelsCompletedMin = 0;
				val2.levelsCompletedMax = 10;
				val2.rarityPreset = val;
				val2.runsPlayed = 0;
				EnemyContent val3 = ScriptableObject.CreateInstance<EnemyContent>();
				((Object)val3).hideFlags = (HideFlags)61;
				((Object)val3).name = "EnemyContentEmpressCoilhead";
				EnemySetupField.SetValue(val3, val2);
				SpawnObjectsField.SetValue(val3, new List<GameObject> { item });
				Enemies.RegisterEnemy(val3);
				_registered = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered the Coilhead enemy with REPOLib.");
			}
		}

		internal static void ConfigureRuntimeInstance(EnemyParent enemyParent, Enemy enemy, EnemyStateSpawn stateSpawn, EnemyStateStunned stateStunned, PhotonView rootPhotonView, PhotonView enemyPhotonView, Transform centerTransform)
		{
			//IL_0010: 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_012e: 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)
			Transform centerTransform2;
			Transform headTransform;
			Animator visualAnimator;
			Transform visualRoot = BuildCoilheadVisualRig(enemy, out centerTransform2, out headTransform, out visualAnimator);
			enemy.Type = (EnemyType)3;
			enemy.CenterTransform = centerTransform2;
			enemy.KillLookAtTransform = headTransform;
			enemy.CustomValuableSpawnTransform = centerTransform2;
			enemy.CurrentState = (EnemyState)1;
			AudioSource voiceSource = CreateAudioSource(((Component)enemy).gameObject, "CoilheadVoice", 1f, 10f, 0.95f);
			AudioSource movementSource = CreateAudioSource(((Component)enemy).gameObject, "CoilheadMovement", 1f, 9f, 0.8f);
			EmpressRepoCoilheadController empressRepoCoilheadController = ((Component)enemy).GetComponent<EmpressRepoCoilheadController>() ?? ((Component)enemy).gameObject.AddComponent<EmpressRepoCoilheadController>();
			empressRepoCoilheadController.VisualRoot = visualRoot;
			empressRepoCoilheadController.CenterTransform = centerTransform2;
			empressRepoCoilheadController.HeadTransform = headTransform;
			empressRepoCoilheadController.VisualAnimator = visualAnimator;
			empressRepoCoilheadController.VoiceSource = voiceSource;
			empressRepoCoilheadController.MovementSource = movementSource;
			empressRepoCoilheadController.SpringStopClips = EmpressRepoCoilheadAudioBank.GetSpringStopClips();
			empressRepoCoilheadController.SpringWobbleClips = EmpressRepoCoilheadAudioBank.GetSpringWobbleClips();
			empressRepoCoilheadController.KillClip = EmpressRepoCoilheadAudioBank.KillClip;
			empressRepoCoilheadController.CooldownClip = EmpressRepoCoilheadAudioBank.CooldownClip;
			empressRepoCoilheadController.InitializeRuntime();
			RepoEnemyAccess.SetEnemyParentEnemy(enemyParent, enemy);
			RepoEnemyAccess.SetEnemyParent(enemy, enemyParent);
			RepoEnemyAccess.SetPhotonView(enemy, enemyPhotonView);
			RepoEnemyAccess.SetStateSpawn(enemy, stateSpawn);
			RepoEnemyAccess.SetHasStateSpawn(enemy, value: true);
			RepoEnemyAccess.SetStateStunned(enemy, stateStunned);
			RepoEnemyAccess.SetHasStateStunned(enemy, value: true);
			RepoEnemyAccess.SetVisionMask(enemy, LayerMask.op_Implicit(LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()) + LayerMask.GetMask(new string[1] { "HideTriggers" })));
			RepoEnemyAccess.SetTargetPlayerViewId(enemy, -1);
			RepoEnemyAccess.SetNavMeshAgent(enemy, empressRepoCoilheadController.NavAgent);
			RepoEnemyAccess.SetHasNavMeshAgent(enemy, (Object)(object)empressRepoCoilheadController.NavAgent != (Object)null);
			RepoEnemyAccess.SetStateSpawnEnemy(stateSpawn, enemy);
			RepoEnemyAccess.SetStateStunnedEnemy(stateStunned, enemy);
			rootPhotonView.ObservedComponents = new List<Component> { (Component)(object)enemyParent };
			enemyPhotonView.ObservedComponents = new List<Component> { (Component)(object)enemy };
		}

		internal static void RefreshSpawnManagerEnemyNames()
		{
			Type type = AccessTools.TypeByName("SpawnManager.Managers.EnemyManager");
			if (!(type == null))
			{
				if ((object)_spawnManagerRefreshMethod == null)
				{
					_spawnManagerRefreshMethod = AccessTools.Method(type, "RefreshAllEnemyNames", (Type[])null, (Type[])null);
				}
				_spawnManagerRefreshMethod?.Invoke(null, null);
			}
		}

		private static Transform BuildCoilheadVisualRig(Enemy enemy, out Transform centerTransform, out Transform headTransform, out Animator? visualAnimator)
		{
			if (TryBuildBundleVisualRig(((Component)enemy).transform, out Transform visualRoot, out centerTransform, out headTransform, out visualAnimator))
			{
				return visualRoot;
			}
			visualAnimator = null;
			return BuildFallbackVisualRig(((Component)enemy).transform, out centerTransform, out headTransform);
		}

		private static bool TryBuildBundleVisualRig(Transform attachRoot, out Transform visualRoot, out Transform centerTransform, out Transform headTransform, out Animator? visualAnimator)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			visualRoot = null;
			centerTransform = null;
			headTransform = null;
			visualAnimator = null;
			GameObject val = LoadCoilheadVisualPrefab();
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val, attachRoot);
			((Object)val2).name = "CoilheadVisualRoot";
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			Transform transform = val2.transform;
			transform.localScale *= 0.88f;
			SetVisualLayerRecursively(val2.transform, ResolveVisualLayer("Enemy"));
			HideBundleHelperObjects(val2.transform);
			ConvertBundleMaterials(val2);
			Collider[] componentsInChildren = val2.GetComponentsInChildren<Collider>(true);
			foreach (Collider val3 in componentsInChildren)
			{
				val3.enabled = false;
			}
			visualRoot = val2.transform;
			visualAnimator = val2.GetComponentInChildren<Animator>(true);
			if ((Object)(object)visualAnimator != (Object)null)
			{
				((Behaviour)visualAnimator).enabled = true;
				visualAnimator.applyRootMotion = false;
				visualAnimator.cullingMode = (AnimatorCullingMode)0;
				visualAnimator.Rebind();
				visualAnimator.Update(0f);
			}
			Transform val4 = FindChildByName(val2.transform, "HeadTarget") ?? FindChildByName(val2.transform, "Head") ?? FindChildByName(val2.transform, "springBone.002_end");
			headTransform = val4 ?? val2.transform;
			Bounds? combinedRendererBounds = GetCombinedRendererBounds(val2);
			GameObject val5 = new GameObject("CoilheadCenter");
			val5.transform.SetParent(attachRoot, false);
			Transform transform2 = val5.transform;
			Vector3 position;
			if (!combinedRendererBounds.HasValue)
			{
				position = attachRoot.position + Vector3.up * 1.35f;
			}
			else
			{
				Bounds valueOrDefault = combinedRendererBounds.GetValueOrDefault();
				position = ((Bounds)(ref valueOrDefault)).center;
			}
			transform2.position = position;
			val5.transform.rotation = Quaternion.identity;
			centerTransform = val5.transform;
			Log.LogInfo((object)"Using asset bundle visual prefab for Coilhead.");
			return true;
		}

		private static void ConvertBundleMaterials(GameObject instance)
		{
			Shader val = Shader.Find("Standard");
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)"[Coilhead] Could not find Standard shader for material conversion.");
				return;
			}
			Material val2 = BuildPreferredVisibleMaterial(val);
			Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
			Renderer[] componentsInChildren = instance.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val3 in componentsInChildren)
			{
				if (!val3.enabled || ShouldHideBundleHelperObject(((Component)val3).transform))
				{
					val3.enabled = false;
					continue;
				}
				Material[] sharedMaterials = val3.sharedMaterials;
				if ((Object)(object)val2 != (Object)null && sharedMaterials.Length != 0)
				{
					Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
					for (int j = 0; j < array.Length; j++)
					{
						array[j] = val2;
					}
					val3.sharedMaterials = array;
					continue;
				}
				bool flag = false;
				for (int k = 0; k < sharedMaterials.Length; k++)
				{
					Material val4 = sharedMaterials[k];
					if (!((Object)(object)val4 == (Object)null))
					{
						if (!dictionary.TryGetValue(val4, out var value))
						{
							value = ConvertMaterialToBuiltIn(val4, val);
							dictionary.Add(val4, value);
						}
						if (sharedMaterials[k] != value)
						{
							sharedMaterials[k] = value;
							flag = true;
						}
					}
				}
				if (flag)
				{
					val3.sharedMaterials = sharedMaterials;
				}
			}
		}

		private static void HideBundleHelperObjects(Transform root)
		{
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (ShouldHideBundleHelperObject(val))
				{
					((Component)val).gameObject.SetActive(false);
				}
			}
		}

		private static bool ShouldHideBundleHelperObject(Transform candidate)
		{
			string name = ((Object)candidate).name;
			return name.IndexOf("MapDot", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("ScanNode", StringComparison.OrdinalIgnoreCase) >= 0;
		}

		private static Material? BuildPreferredVisibleMaterial(Shader standardShader)
		{
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Expected O, but got Unknown
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_coilheadVisibleMaterial != (Object)null)
			{
				return _coilheadVisibleMaterial;
			}
			if ((Object)(object)_coilheadBundle == (Object)null)
			{
				return null;
			}
			Material val = null;
			string[] array = new string[3] { "SpringManTex", "SpringMan", "Coilhead" };
			foreach (string text in array)
			{
				val = _coilheadBundle.LoadAsset<Material>(text);
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				Material[] array2 = _coilheadBundle.LoadAllAssets<Material>();
				foreach (Material val2 in array2)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						if (((Object)val2).name.IndexOf("spring", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)val2).name.IndexOf("coil", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							val = val2;
							break;
						}
						if (val == null)
						{
							val = val2;
						}
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				_coilheadVisibleMaterial = ConvertMaterialToBuiltIn(val, standardShader);
			}
			else
			{
				_coilheadVisibleMaterial = new Material(standardShader)
				{
					name = "CoilheadBuiltIn"
				};
				((Object)_coilheadVisibleMaterial).hideFlags = (HideFlags)61;
			}
			Texture2D val3 = ResolvePreferredTexture("SpringManTexV2.png", ref _coilheadAlbedoTexture, isNormalMap: false);
			Texture2D val4 = ResolvePreferredTexture("SpringManNormalTex.png", ref _coilheadNormalTexture, isNormalMap: true);
			if ((Object)(object)val3 != (Object)null)
			{
				_coilheadVisibleMaterial.mainTexture = (Texture)(object)val3;
				_coilheadVisibleMaterial.SetTexture("_MainTex", (Texture)(object)val3);
			}
			if ((Object)(object)val4 != (Object)null)
			{
				_coilheadVisibleMaterial.SetTexture("_BumpMap", (Texture)(object)val4);
				_coilheadVisibleMaterial.EnableKeyword("_NORMALMAP");
				_coilheadVisibleMaterial.SetFloat("_BumpScale", 0.68f);
			}
			_coilheadVisibleMaterial.color = Color.white;
			_coilheadVisibleMaterial.SetFloat("_Metallic", 0.074f);
			_coilheadVisibleMaterial.SetFloat("_Glossiness", 0.545f);
			((Object)_coilheadVisibleMaterial).hideFlags = (HideFlags)61;
			return _coilheadVisibleMaterial;
		}

		private static Texture2D? ResolvePreferredTexture(string expectedFileName, ref Texture2D? cache, bool isNormalMap)
		{
			if ((Object)(object)cache != (Object)null)
			{
				return cache;
			}
			string text = ResolvePluginFile(expectedFileName);
			if (!string.IsNullOrEmpty(text))
			{
				cache = LoadTextureFromDisk(text, expectedFileName, isNormalMap);
				if ((Object)(object)cache != (Object)null)
				{
					return cache;
				}
			}
			if ((Object)(object)_coilheadBundle == (Object)null)
			{
				return null;
			}
			Texture2D[] array = _coilheadBundle.LoadAllAssets<Texture2D>();
			foreach (Texture2D val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string text2 = ((Object)val).name ?? string.Empty;
					bool flag = string.Equals(text2, Path.GetFileNameWithoutExtension(expectedFileName), StringComparison.OrdinalIgnoreCase) || string.Equals(text2, expectedFileName, StringComparison.OrdinalIgnoreCase);
					if (!flag)
					{
						flag = ((!isNormalMap) ? ((text2.IndexOf("springman", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("coilhead", StringComparison.OrdinalIgnoreCase) >= 0) && text2.IndexOf("normal", StringComparison.OrdinalIgnoreCase) < 0) : (text2.IndexOf("normal", StringComparison.OrdinalIgnoreCase) >= 0));
					}
					if (flag)
					{
						cache = val;
						return cache;
					}
				}
			}
			return null;
		}

		private static Texture2D? LoadTextureFromDisk(string path, string textureName, bool isNormalMap)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			try
			{
				byte[] array = File.ReadAllBytes(path);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, isNormalMap)
				{
					name = Path.GetFileNameWithoutExtension(textureName),
					wrapMode = (TextureWrapMode)0,
					filterMode = (FilterMode)1,
					hideFlags = (HideFlags)61
				};
				if (!ImageConversion.LoadImage(val, array, false))
				{
					Object.Destroy((Object)(object)val);
					return null;
				}
				val.Apply(true, false);
				return val;
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[Coilhead] Failed to load texture '" + path + "': " + ex.Message));
				return null;
			}
		}

		private static Material ConvertMaterialToBuiltIn(Material original, Shader standardShader)
		{
			//IL_0002: 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_001f: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(standardShader)
			{
				name = ((Object)original).name + "_BuiltIn"
			};
			Texture val2 = (original.HasProperty("_BaseColorMap") ? original.GetTexture("_BaseColorMap") : (original.HasProperty("_MainTex") ? original.GetTexture("_MainTex") : null));
			Texture val3 = (original.HasProperty("_NormalMap") ? original.GetTexture("_NormalMap") : (original.HasProperty("_BumpMap") ? original.GetTexture("_BumpMap") : null));
			if ((Object)(object)val2 != (Object)null)
			{
				val.mainTexture = val2;
				val.SetTexture("_MainTex", val2);
			}
			if ((Object)(object)val3 != (Object)null)
			{
				val.SetTexture("_BumpMap", val3);
				val.EnableKeyword("_NORMALMAP");
			}
			if (original.HasProperty("_BaseColor"))
			{
				val.color = original.GetColor("_BaseColor");
			}
			else if (original.HasProperty("_Color"))
			{
				val.color = original.GetColor("_Color");
			}
			if (original.HasProperty("_Metallic"))
			{
				val.SetFloat("_Metallic", original.GetFloat("_Metallic"));
			}
			if (original.HasProperty("_Smoothness"))
			{
				val.SetFloat("_Glossiness", original.GetFloat("_Smoothness"));
			}
			else if (original.HasProperty("_Glossiness"))
			{
				val.SetFloat("_Glossiness", original.GetFloat("_Glossiness"));
			}
			if (original.HasProperty("_BumpScale"))
			{
				val.SetFloat("_BumpScale", original.GetFloat("_BumpScale"));
			}
			else if (original.HasProperty("_NormalScale"))
			{
				val.SetFloat("_BumpScale", original.GetFloat("_NormalScale"));
			}
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}

		private static Transform BuildFallbackVisualRig(Transform attachRoot, out Transform centerTransform, out Transform headTransform)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0020: 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_0053: 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_0089: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("CoilheadVisualRoot");
			val.transform.SetParent(attachRoot, false);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			Material seedMaterial = FindSeedMaterial(val);
			Material material = CreateTintedMaterial(seedMaterial, new Color(0.68f, 0.67f, 0.61f));
			Material material2 = CreateTintedMaterial(seedMaterial, new Color(0.18f, 0.17f, 0.16f));
			Material material3 = CreateTintedMaterial(seedMaterial, new Color(1f, 0.2f, 0.15f));
			Transform val2 = CreatePiece("Body", (PrimitiveType)2, val.transform, new Vector3(0f, 1.25f, 0f), new Vector3(0.28f, 0.62f, 0.28f), material);
			for (int i = 0; i < 6; i++)
			{
				float num = 0.48f + (float)i * 0.2f;
				CreatePiece($"SpringLoop{i}", (PrimitiveType)2, val.transform, new Vector3(0f, num, 0f), new Vector3(0.22f, 0.012f, 0.22f), material2, (Vector3?)new Vector3(90f, 0f, 0f));
			}
			Transform val3 = CreatePiece("Head", (PrimitiveType)1, val.transform, new Vector3(0f, 2.05f, 0f), new Vector3(0.34f, 0.42f, 0.34f), material);
			CreatePiece("Eye", (PrimitiveType)0, val3, new Vector3(0f, 0.05f, 0.22f), new Vector3(0.16f, 0.16f, 0.08f), material3);
			CreatePiece("LeftLeg", (PrimitiveType)2, val.transform, new Vector3(-0.12f, 0.45f, 0f), new Vector3(0.07f, 0.45f, 0.07f), material);
			CreatePiece("RightLeg", (PrimitiveType)2, val.transform, new Vector3(0.12f, 0.45f, 0f), new Vector3(0.07f, 0.45f, 0.07f), material);
			centerTransform = new GameObject("CoilheadCenter").transform;
			centerTransform.SetParent(attachRoot, false);
			centerTransform.localPosition = new Vector3(0f, 1.35f, 0f);
			headTransform = val3;
			return val.transform;
		}

		private static GameObject? LoadCoilheadVisualPrefab()
		{
			if ((Object)(object)_coilheadVisualPrefab != (Object)null)
			{
				return _coilheadVisualPrefab;
			}
			string text = ResolvePluginFile("empresscoilhead");
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			try
			{
				if (_coilheadBundle == null)
				{
					_coilheadBundle = AssetBundle.LoadFromFile(text);
				}
				if ((Object)(object)_coilheadBundle == (Object)null)
				{
					Log.LogWarning((object)("[Coilhead] Failed to load asset bundle at " + text));
					return null;
				}
				string[] coilheadBundlePrefabCandidates = CoilheadBundlePrefabCandidates;
				foreach (string text2 in coilheadBundlePrefabCandidates)
				{
					GameObject val = _coilheadBundle.LoadAsset<GameObject>(text2);
					if ((Object)(object)val != (Object)null)
					{
						_coilheadVisualPrefab = val;
						return _coilheadVisualPrefab;
					}
				}
				GameObject[] array = _coilheadBundle.LoadAllAssets<GameObject>();
				foreach (GameObject val2 in array)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						_coilheadVisualPrefab = val2;
						Log.LogWarning((object)("[Coilhead] Falling back to first prefab '" + ((Object)val2).name + "' from asset bundle."));
						return _coilheadVisualPrefab;
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[Coilhead] Failed while loading visual asset bundle: " + ex.Message));
			}
			return null;
		}

		internal static string? ResolvePluginFile(string fileName)
		{
			if (string.IsNullOrWhiteSpace(PluginDirectory) || !Directory.Exists(PluginDirectory))
			{
				return null;
			}
			string text = Path.Combine(PluginDirectory, fileName);
			if (File.Exists(text))
			{
				return text;
			}
			try
			{
				foreach (string item in Directory.EnumerateFiles(PluginDirectory, fileName, SearchOption.AllDirectories))
				{
					if (File.Exists(item))
					{
						return item;
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[Coilhead] Failed while searching for '" + fileName + "' in plugin directory: " + ex.Message));
			}
			return null;
		}

		private static Transform? FindChildByName(Transform root, string name)
		{
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (string.Equals(((Object)val).name, name, StringComparison.OrdinalIgnoreCase))
				{
					return val;
				}
			}
			return null;
		}

		private static Bounds? GetCombinedRendererBounds(GameObject gameObject)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0061: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			Bounds value = default(Bounds);
			Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!flag)
				{
					value = val.bounds;
					flag = true;
				}
				else
				{
					((Bounds)(ref value)).Encapsulate(val.bounds);
				}
			}
			return flag ? new Bounds?(value) : null;
		}

		private static int ResolveVisualLayer(string layerName)
		{
			int num = LayerMask.NameToLayer(layerName);
			return (num >= 0) ? num : 0;
		}

		private static void SetVisualLayerRecursively(Transform root, int layer)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			((Component)root).gameObject.layer = layer;
			foreach (Transform item in root)
			{
				Transform root2 = item;
				SetVisualLayerRecursively(root2, layer);
			}
		}

		private static Material FindSeedMaterial(GameObject prefab)
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if ((Object)(object)val.sharedMaterial != (Object)null)
				{
					return val.sharedMaterial;
				}
			}
			GameObject val2 = GameObject.CreatePrimitive((PrimitiveType)3);
			try
			{
				Renderer component = val2.GetComponent<Renderer>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMaterial != (Object)null)
				{
					return component.sharedMaterial;
				}
			}
			finally
			{
				Object.Destroy((Object)(object)val2);
			}
			string[] array = new string[4] { "Standard", "Universal Render Pipeline/Lit", "HDRP/Lit", "Sprites/Default" };
			foreach (string text in array)
			{
				Shader val3 = Shader.Find(text);
				if ((Object)(object)val3 != (Object)null)
				{
					return new Material(val3);
				}
			}
			throw new InvalidOperationException("Could not resolve a fallback material for the Coilhead visuals.");
		}

		private static Material CreateTintedMaterial(Material seedMaterial, Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: 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)
			Material val = new Material(seedMaterial);
			if (val.HasProperty("_BaseColor"))
			{
				val.SetColor("_BaseColor", color);
			}
			if (val.HasProperty("_Color"))
			{
				val.SetColor("_Color", color);
			}
			return val;
		}

		private static AudioSource CreateAudioSource(GameObject owner, string name, float spatialBlend, float maxDistance, float volume)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(owner.transform, false);
			AudioSource val2 = val.AddComponent<AudioSource>();
			val2.playOnAwake = false;
			val2.loop = false;
			val2.spatialBlend = spatialBlend;
			val2.rolloffMode = (AudioRolloffMode)1;
			val2.minDistance = 1f;
			val2.maxDistance = maxDistance;
			val2.dopplerLevel = 0f;
			val2.volume = volume;
			return val2;
		}

		private static Transform CreatePiece(string name, PrimitiveType primitiveType, Transform parent, Vector3 localPosition, Vector3 localScale, Material material, Vector3? localEulerAngles = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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)
			GameObject val = GameObject.CreatePrimitive(primitiveType);
			((Object)val).name = name;
			val.transform.SetParent(parent, false);
			val.transform.localPosition = localPosition;
			val.transform.localScale = localScale;
			val.transform.localRotation = Quaternion.Euler((Vector3)(((??)localEulerAngles) ?? Vector3.zero));
			Collider[] components = val.GetComponents<Collider>();
			foreach (Collider val2 in components)
			{
				val2.enabled = false;
			}
			Renderer component = val.GetComponent<Renderer>();
			if ((Object)(object)component != (Object)null)
			{
				component.sharedMaterial = material;
			}
			return val.transform;
		}

		private static void PatchTemplateGuards(Harmony harmony)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Expected O, but got Unknown
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Expected O, but got Unknown
			harmony.Patch((MethodBase)AccessTools.Method(typeof(EnemyParent), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(typeof(EmpressRepoCoilheadPlugin), "SkipTemplateEnemyParentAwake", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(EnemyParent), "Update", (Type[])null, (Type[])null), new HarmonyMethod(typeof(EmpressRepoCoilheadPlugin), "SkipTemplateEnemyParentUpdate", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Enemy), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(typeof(EmpressRepoCoilheadPlugin), "SkipTemplateEnemyAwake", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Enemy), "Start", (Type[])null, (Type[])null), new HarmonyMethod(typeof(EmpressRepoCoilheadPlugin), "SkipTemplateEnemyStart", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(Enemy), "Update", (Type[])null, (Type[])null), new HarmonyMethod(typeof(EmpressRepoCoilheadPlugin), "SkipTemplateEnemyUpdate", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(EnemyNavMeshAgent), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(typeof(EmpressRepoCoilheadPlugin), "SkipTemplateEnemyNavMeshAgentAwake", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(EnemyNavMeshAgent), "OnEnable", (Type[])null, (Type[])null), new HarmonyMethod(typeof(EmpressRepoCoilheadPlugin), "SkipTemplateEnemyNavMeshAgentOnEnable", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(EnemyNavMeshAgent), "Update", (Type[])null, (Type[])null), new HarmonyMethod(typeof(EmpressRepoCoilheadPlugin), "SkipTemplateEnemyNavMeshAgentUpdate", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(EnemyStateSpawn), "Update", (Type[])null, (Type[])null), new HarmonyMethod(typeof(EmpressRepoCoilheadPlugin), "SkipTemplateEnemyStateSpawnUpdate", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeof(EnemyStateStunned), "Update", (Type[])null, (Type[])null), new HarmonyMethod(typeof(EmpressRepoCoilheadPlugin), "SkipTemplateEnemyStateStunnedUpdate", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static bool SkipTemplateEnemyParentAwake(EnemyParent __instance)
		{
			return !CoilheadTemplateBootstrap.IsTemplateInstance(((Component)__instance).gameObject);
		}

		private static bool SkipTemplateEnemyParentUpdate(EnemyParent __instance)
		{
			return !CoilheadTemplateBootstrap.IsTemplateInstance(((Component)__instance).gameObject);
		}

		private static bool SkipTemplateEnemyAwake(Enemy __instance)
		{
			return !CoilheadTemplateBootstrap.IsTemplateInstance(((Component)__instance).gameObject);
		}

		private static bool SkipTemplateEnemyStart(Enemy __instance)
		{
			return !CoilheadTemplateBootstrap.IsTemplateInstance(((Component)__instance).gameObject);
		}

		private static bool SkipTemplateEnemyUpdate(Enemy __instance)
		{
			return !CoilheadTemplateBootstrap.IsTemplateInstance(((Component)__instance).gameObject);
		}

		private static bool SkipTemplateEnemyNavMeshAgentAwake(EnemyNavMeshAgent __instance)
		{
			return !CoilheadTemplateBootstrap.IsTemplateInstance(((Component)__instance).gameObject);
		}

		private static bool SkipTemplateEnemyNavMeshAgentOnEnable(EnemyNavMeshAgent __instance)
		{
			return !CoilheadTemplateBootstrap.IsTemplateInstance(((Component)__instance).gameObject);
		}

		private static bool SkipTemplateEnemyNavMeshAgentUpdate(EnemyNavMeshAgent __instance)
		{
			return !CoilheadTemplateBootstrap.IsTemplateInstance(((Component)__instance).gameObject);
		}

		private static bool SkipTemplateEnemyStateSpawnUpdate(EnemyStateSpawn __instance)
		{
			return !CoilheadTemplateBootstrap.IsTemplateInstance(((Component)__instance).gameObject);
		}

		private static bool SkipTemplateEnemyStateStunnedUpdate(EnemyStateStunned __instance)
		{
			return !CoilheadTemplateBootstrap.IsTemplateInstance(((Component)__instance).gameObject);
		}
	}
	[HarmonyPatch(typeof(EnemyDirector), "Start")]
	internal static class EmpressRepoCoilheadEnemyDirectorStartPatch
	{
		private static void Postfix()
		{
			EmpressRepoCoilheadPlugin.RefreshSpawnManagerEnemyNames();
		}
	}
	internal static class RepoEnemyAccess
	{
		private static readonly FieldRef<EnemyParent, Enemy> EnemyParentEnemyRef = AccessTools.FieldRefAccess<EnemyParent, Enemy>("Enemy");

		private static readonly FieldRef<EnemyParent, bool> EnemyParentSetupDoneRef = AccessTools.FieldRefAccess<EnemyParent, bool>("SetupDone");

		private static readonly FieldRef<Enemy, EnemyParent> EnemyEnemyParentRef = AccessTools.FieldRefAccess<Enemy, EnemyParent>("EnemyParent");

		private static readonly FieldRef<Enemy, bool> EnemyHasNavMeshAgentRef = AccessTools.FieldRefAccess<Enemy, bool>("HasNavMeshAgent");

		private static readonly FieldRef<Enemy, bool> EnemyHasStateSpawnRef = AccessTools.FieldRefAccess<Enemy, bool>("HasStateSpawn");

		private static readonly FieldRef<Enemy, bool> EnemyHasStateStunnedRef = AccessTools.FieldRefAccess<Enemy, bool>("HasStateStunned");

		private static readonly FieldRef<Enemy, EnemyNavMeshAgent> EnemyNavMeshAgentRef = AccessTools.FieldRefAccess<Enemy, EnemyNavMeshAgent>("NavMeshAgent");

		private static readonly FieldRef<Enemy, PhotonView> EnemyPhotonViewRef = AccessTools.FieldRefAccess<Enemy, PhotonView>("PhotonView");

		private static readonly FieldRef<Enemy, EnemyStateSpawn> EnemyStateSpawnRef = AccessTools.FieldRefAccess<Enemy, EnemyStateSpawn>("StateSpawn");

		private static readonly FieldRef<Enemy, EnemyStateStunned> EnemyStateStunnedRef = AccessTools.FieldRefAccess<Enemy, EnemyStateStunned>("StateStunned");

		private static readonly FieldRef<Enemy, int> EnemyTargetPlayerViewIdRef = AccessTools.FieldRefAccess<Enemy, int>("TargetPlayerViewID");

		private static readonly FieldRef<Enemy, LayerMask> EnemyVisionMaskRef = AccessTools.FieldRefAccess<Enemy, LayerMask>("VisionMask");

		private static readonly FieldRef<EnemyStateSpawn, Enemy> EnemyStateSpawnEnemyRef = AccessTools.FieldRefAccess<EnemyStateSpawn, Enemy>("Enemy");

		private static readonly FieldRef<EnemyStateStunned, Enemy> EnemyStateStunnedEnemyRef = AccessTools.FieldRefAccess<EnemyStateStunned, Enemy>("enemy");

		internal static void SetSetupDone(EnemyParent enemyParent, bool value)
		{
			EnemyParentSetupDoneRef.Invoke(enemyParent) = value;
		}

		internal static void SetEnemyParentEnemy(EnemyParent enemyParent, Enemy enemy)
		{
			EnemyParentEnemyRef.Invoke(enemyParent) = enemy;
		}

		internal static void SetEnemyParent(Enemy enemy, EnemyParent enemyParent)
		{
			EnemyEnemyParentRef.Invoke(enemy) = enemyParent;
		}

		internal static void SetPhotonView(Enemy enemy, PhotonView photonView)
		{
			EnemyPhotonViewRef.Invoke(enemy) = photonView;
		}

		internal static void SetNavMeshAgent(Enemy enemy, EnemyNavMeshAgent navMeshAgent)
		{
			EnemyNavMeshAgentRef.Invoke(enemy) = navMeshAgent;
		}

		internal static void SetHasNavMeshAgent(Enemy enemy, bool value)
		{
			EnemyHasNavMeshAgentRef.Invoke(enemy) = value;
		}

		internal static void SetStateSpawn(Enemy enemy, EnemyStateSpawn stateSpawn)
		{
			EnemyStateSpawnRef.Invoke(enemy) = stateSpawn;
		}

		internal static void SetHasStateSpawn(Enemy enemy, bool value)
		{
			EnemyHasStateSpawnRef.Invoke(enemy) = value;
		}

		internal static void SetStateStunned(Enemy enemy, EnemyStateStunned stateStunned)
		{
			EnemyStateStunnedRef.Invoke(enemy) = stateStunned;
		}

		internal static void SetHasStateStunned(Enemy enemy, bool value)
		{
			EnemyHasStateStunnedRef.Invoke(enemy) = value;
		}

		internal static void SetVisionMask(Enemy enemy, LayerMask visionMask)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			EnemyVisionMaskRef.Invoke(enemy) = visionMask;
		}

		internal static void SetTargetPlayerViewId(Enemy enemy, int viewId)
		{
			EnemyTargetPlayerViewIdRef.Invoke(enemy) = viewId;
		}

		internal static void SetStateSpawnEnemy(EnemyStateSpawn stateSpawn, Enemy enemy)
		{
			EnemyStateSpawnEnemyRef.Invoke(stateSpawn) = enemy;
		}

		internal static void SetStateStunnedEnemy(EnemyStateStunned stateStunned, Enemy enemy)
		{
			EnemyStateStunnedEnemyRef.Invoke(stateStunned) = enemy;
		}
	}
	[DefaultExecutionOrder(-100)]
	internal sealed class CoilheadTemplateBootstrap : MonoBehaviour
	{
		private const string EnableObjectName = "EnableObject";

		private const string EnemyObjectName = "CoilheadEnemy";

		private const string CenterObjectName = "Center";

		private const string TemplateContainerName = "EmpressCoilheadTemplateContainer";

		private static readonly HashSet<int> TemplateInstanceIds = new HashSet<int>();

		private static GameObject? _templateContainer;

		private bool _runtimeBuilt;

		internal static GameObject CreateTemplate(ManualLogSource log)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = EnsureTemplateContainer();
			GameObject val2 = new GameObject("EmpressCoilheadPrefab")
			{
				layer = ResolveLayer("Enemy")
			};
			val2.transform.SetParent(val.transform, false);
			TemplateInstanceIds.Add(((Object)val2).GetInstanceID());
			((Object)val2).hideFlags = (HideFlags)61;
			val2.transform.position = new Vector3(0f, -5000f, 0f);
			BuildTemplateCore(val2.transform);
			log.LogInfo((object)"Created Coilhead template core.");
			return val2;
		}

		internal static bool IsTemplateInstance(GameObject gameObject)
		{
			Transform val = gameObject.transform;
			while ((Object)(object)val.parent != (Object)null)
			{
				val = val.parent;
			}
			return TemplateInstanceIds.Contains(((Object)((Component)val).gameObject).GetInstanceID());
		}

		private static GameObject EnsureTemplateContainer()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if ((Object)(object)_templateContainer != (Object)null)
			{
				return _templateContainer;
			}
			_templateContainer = new GameObject("EmpressCoilheadTemplateContainer");
			((Object)_templateContainer).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)_templateContainer);
			_templateContainer.SetActive(false);
			return _templateContainer;
		}

		private static void BuildTemplateCore(Transform root)
		{
			//IL_0044: 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_0068: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			int layer = ResolveLayer("Enemy");
			((Component)root).gameObject.layer = layer;
			TrySetTag(((Component)root).gameObject, "Enemy");
			EnemyParent val = ((Component)root).gameObject.AddComponent<EnemyParent>();
			PhotonView val2 = ((Component)root).gameObject.AddComponent<PhotonView>();
			val2.Synchronization = (ViewSynchronization)3;
			((Behaviour)val2).enabled = false;
			((Component)root).gameObject.AddComponent<CoilheadTemplateBootstrap>();
			GameObject val3 = new GameObject("EnableObject");
			val3.transform.SetParent(root, false);
			val3.layer = layer;
			TrySetTag(val3, "Enemy");
			GameObject val4 = new GameObject("CoilheadEnemy");
			val4.transform.SetParent(val3.transform, false);
			val4.transform.localPosition = Vector3.zero;
			val4.layer = layer;
			val4.SetActive(false);
			TrySetTag(val4, "Enemy");
			GameObject val5 = new GameObject("Center");
			val5.transform.SetParent(val4.transform, false);
			val5.transform.localPosition = new Vector3(0f, 1.35f, 0f);
			PhotonView val6 = val4.AddComponent<PhotonView>();
			val6.Synchronization = (ViewSynchronization)3;
			((Behaviour)val6).enabled = false;
			CapsuleCollider val7 = val4.AddComponent<CapsuleCollider>();
			val7.center = new Vector3(0f, 1.35f, 0f);
			val7.height = 3f;
			val7.radius = 0.45f;
			EnemyStateSpawn stateSpawn = val4.AddComponent<EnemyStateSpawn>();
			EnemyStateStunned stateStunned = val4.AddComponent<EnemyStateStunned>();
			Enemy val8 = val4.AddComponent<Enemy>();
			val.enemyName = "Coilhead";
			val.difficulty = (Difficulty)2;
			val.actionMultiplier = 1.55f;
			val.overchargeMultiplier = 1.25f;
			val.EnableObject = val3;
			val.SpawnedTimeMin = 25f;
			val.SpawnedTimeMax = 45f;
			val.DespawnedTimeMin = 18f;
			val.DespawnedTimeMax = 28f;
			RepoEnemyAccess.SetSetupDone(val, value: false);
			RepoEnemyAccess.SetEnemyParentEnemy(val, val8);
			RepoEnemyAccess.SetEnemyParent(val8, val);
			RepoEnemyAccess.SetPhotonView(val8, val6);
			val8.CenterTransform = val5.transform;
			val8.KillLookAtTransform = val5.transform;
			val8.CustomValuableSpawnTransform = val5.transform;
			RepoEnemyAccess.SetStateSpawn(val8, stateSpawn);
			RepoEnemyAccess.SetHasStateSpawn(val8, value: true);
			RepoEnemyAccess.SetStateStunned(val8, stateStunned);
			RepoEnemyAccess.SetHasStateStunned(val8, value: true);
			RepoEnemyAccess.SetVisionMask(val8, LayerMask.op_Implicit(LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()) + LayerMask.GetMask(new string[1] { "HideTriggers" })));
			RepoEnemyAccess.SetTargetPlayerViewId(val8, -1);
			val8.CurrentState = (EnemyState)1;
			RepoEnemyAccess.SetStateSpawnEnemy(stateSpawn, val8);
			RepoEnemyAccess.SetStateStunnedEnemy(stateStunned, val8);
			val4.SetActive(true);
			val2.ObservedComponents = new List<Component> { (Component)(object)val };
			val6.ObservedComponents = new List<Component> { (Component)(object)val8 };
			SetLayerRecursively(root, layer);
			TrySetTagRecursively(root, "Enemy");
		}

		private void Start()
		{
			if (IsTemplateInstance(((Component)this).gameObject) || _runtimeBuilt)
			{
				return;
			}
			_runtimeBuilt = true;
			try
			{
				BuildRuntimeInstance();
			}
			catch (Exception arg)
			{
				EmpressRepoCoilheadPlugin.Log.LogError((object)$"Failed to finish Coilhead spawn: {arg}");
			}
		}

		private void BuildRuntimeInstance()
		{
			if (!TryResolveCore(out EnemyParent enemyParent, out Enemy enemy, out EnemyStateSpawn stateSpawn, out EnemyStateStunned stateStunned, out PhotonView rootPhotonView, out PhotonView enemyPhotonView, out Transform centerTransform))
			{
				throw new InvalidOperationException("Coilhead core components were not present on spawned clone.");
			}
			SetHideFlagsRecursively(((Component)this).transform, (HideFlags)0);
			((Behaviour)rootPhotonView).enabled = true;
			((Behaviour)enemyPhotonView).enabled = true;
			EnsureRuntimeNavMeshAgent(enemy);
			EmpressRepoCoilheadPlugin.ConfigureRuntimeInstance(enemyParent, enemy, stateSpawn, stateStunned, rootPhotonView, enemyPhotonView, centerTransform);
		}

		private bool TryResolveCore(out EnemyParent enemyParent, out Enemy enemy, out EnemyStateSpawn stateSpawn, out EnemyStateStunned stateStunned, out PhotonView rootPhotonView, out PhotonView enemyPhotonView, out Transform centerTransform)
		{
			enemyParent = ((Component)this).GetComponent<EnemyParent>();
			rootPhotonView = ((Component)this).GetComponent<PhotonView>();
			enemy = ((Component)this).GetComponentInChildren<Enemy>(true);
			stateSpawn = ((Component)this).GetComponentInChildren<EnemyStateSpawn>(true);
			stateStunned = ((Component)this).GetComponentInChildren<EnemyStateStunned>(true);
			PhotonView val = (((Object)(object)enemy != (Object)null) ? ((Component)enemy).GetComponent<PhotonView>() : null);
			Transform val2 = (((Object)(object)enemy != (Object)null && (Object)(object)enemy.CenterTransform != (Object)null) ? enemy.CenterTransform : ((Component)this).transform.Find("EnableObject/CoilheadEnemy/Center"));
			enemyPhotonView = val;
			centerTransform = val2;
			return (Object)(object)enemyParent != (Object)null && (Object)(object)enemy != (Object)null && (Object)(object)stateSpawn != (Object)null && (Object)(object)stateStunned != (Object)null && (Object)(object)rootPhotonView != (Object)null && (Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null;
		}

		private static EnemyNavMeshAgent EnsureRuntimeNavMeshAgent(Enemy enemy)
		{
			//IL_0068: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			if (TryFindNearestNavMeshPoint(enemy, out var hit))
			{
				((Component)enemy).transform.position = ((NavMeshHit)(ref hit)).position;
				if ((Object)(object)((Component)enemy).transform.parent != (Object)null)
				{
					((Component)enemy).transform.parent.position = ((NavMeshHit)(ref hit)).position;
				}
			}
			else
			{
				EmpressRepoCoilheadPlugin.Log.LogWarning((object)$"[Coilhead] Could not find nearby NavMesh for spawned Coilhead at {((Component)enemy).transform.position}.");
			}
			NavMeshAgent val = ((Component)enemy).GetComponent<NavMeshAgent>() ?? ((Component)enemy).gameObject.AddComponent<NavMeshAgent>();
			ConfigureNavMeshAgent(val);
			EnemyNavMeshAgent val2 = ((Component)enemy).GetComponent<EnemyNavMeshAgent>() ?? ((Component)enemy).gameObject.AddComponent<EnemyNavMeshAgent>();
			val2.Agent = val;
			val2.updateRotation = false;
			val2.DefaultSpeed = val.speed;
			val2.DefaultAcceleration = val.acceleration;
			((Behaviour)val2).enabled = false;
			if (!((Behaviour)val).enabled && TryFindNearestNavMeshPoint(enemy, out var hit2))
			{
				((Behaviour)val).enabled = true;
				val.Warp(((NavMeshHit)(ref hit2)).position);
			}
			return val2;
		}

		private static bool TryFindNearestNavMeshPoint(Enemy enemy, out NavMeshHit hit)
		{
			//IL_000f: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0066: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])(object)new Vector3[3]
			{
				((Component)enemy).transform.position,
				((Object)(object)((Component)enemy).transform.parent != (Object)null) ? ((Component)enemy).transform.parent.position : ((Component)enemy).transform.position,
				((Object)(object)enemy.EnemyParent != (Object)null) ? ((Component)enemy.EnemyParent).transform.position : ((Component)enemy).transform.position
			};
			float[] array2 = new float[5] { 6f, 12f, 24f, 48f, 96f };
			Vector3[] array3 = array;
			foreach (Vector3 val in array3)
			{
				float[] array4 = array2;
				foreach (float num in array4)
				{
					if (NavMesh.SamplePosition(val, ref hit, num, -1))
					{
						return true;
					}
				}
			}
			hit = default(NavMeshHit);
			return false;
		}

		private static void ConfigureNavMeshAgent(NavMeshAgent navMeshAgent)
		{
			navMeshAgent.speed = 6.25f;
			navMeshAgent.acceleration = 60f;
			navMeshAgent.angularSpeed = 240f;
			navMeshAgent.stoppingDistance = 0.8f;
			navMeshAgent.radius = 0.42f;
			navMeshAgent.height = 2.9f;
			navMeshAgent.autoTraverseOffMeshLink = true;
			navMeshAgent.obstacleAvoidanceType = (ObstacleAvoidanceType)4;
		}

		private static int ResolveLayer(string layerName)
		{
			int num = LayerMask.NameToLayer(layerName);
			return (num >= 0) ? num : 0;
		}

		private static void SetHideFlagsRecursively(Transform root, HideFlags hideFlags)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			((Object)((Component)root).gameObject).hideFlags = hideFlags;
			foreach (Transform item in root)
			{
				Transform root2 = item;
				SetHideFlagsRecursively(root2, hideFlags);
			}
		}

		private static void SetLayerRecursively(Transform root, int layer)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			((Component)root).gameObject.layer = layer;
			foreach (Transform item in root)
			{
				Transform root2 = item;
				SetLayerRecursively(root2, layer);
			}
		}

		private static void TrySetTagRecursively(Transform root, string tag)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			TrySetTag(((Component)root).gameObject, tag);
			foreach (Transform item in root)
			{
				Transform root2 = item;
				TrySetTagRecursively(root2, tag);
			}
		}

		private static void TrySetTag(GameObject gameObject, string tag)
		{
			try
			{
				gameObject.tag = tag;
			}
			catch (UnityException)
			{
			}
		}
	}
	internal static class EmpressRepoCoilheadAudioBank
	{
		private static readonly string[] SpringStopFileNames = new string[4] { "Spring1.ogg", "Spring1_0.ogg", "Spring2.ogg", "Spring3.ogg" };

		private static readonly string[] SpringWobbleFileNames = new string[2] { "SpringWobble1.ogg", "SpringWobble2.ogg" };

		private const string KillFileName = "KillPlayerSpring.ogg";

		private static bool _started;

		private static readonly List<AudioClip> LoadedSpringStops = new List<AudioClip>();

		private static readonly List<AudioClip> LoadedSpringWobbles = new List<AudioClip>();

		internal static AudioClip? KillClip { get; private set; }

		internal static AudioClip? CooldownClip { get; private set; }

		internal static IEnumerator LoadAudioAsync(ManualLogSource log)
		{
			if (_started)
			{
				yield break;
			}
			_started = true;
			string[] springStopFileNames = SpringStopFileNames;
			foreach (string fileName in springStopFileNames)
			{
				yield return LoadClipAsync(fileName, delegate(AudioClip clip)
				{
					LoadedSpringStops.Add(clip);
				}, log);
			}
			string[] springWobbleFileNames = SpringWobbleFileNames;
			foreach (string fileName2 in springWobbleFileNames)
			{
				yield return LoadClipAsync(fileName2, delegate(AudioClip clip)
				{
					LoadedSpringWobbles.Add(clip);
				}, log);
			}
			yield return LoadClipAsync("KillPlayerSpring.ogg", delegate(AudioClip clip)
			{
				KillClip = clip;
			}, log);
			CooldownClip = ((LoadedSpringWobbles.Count > 0) ? LoadedSpringWobbles[0] : ((LoadedSpringStops.Count > 0) ? LoadedSpringStops[0] : null));
			log.LogInfo((object)$"Coilhead audio load complete. stops={LoadedSpringStops.Count}, wobbles={LoadedSpringWobbles.Count}, kill={(Object)(object)KillClip != (Object)null}");
		}

		internal static AudioClip[] GetSpringStopClips()
		{
			return (AudioClip[])((LoadedSpringStops.Count > 0) ? ((Array)LoadedSpringStops.ToArray()) : ((Array)Array.Empty<AudioClip>()));
		}

		internal static AudioClip[] GetSpringWobbleClips()
		{
			return (AudioClip[])((LoadedSpringWobbles.Count > 0) ? ((Array)LoadedSpringWobbles.ToArray()) : ((Array)Array.Empty<AudioClip>()));
		}

		private static IEnumerator LoadClipAsync(string fileName, Action<AudioClip> assign, ManualLogSource log)
		{
			string resolvedPath = EmpressRepoCoilheadPlugin.ResolvePluginFile(fileName);
			if (string.IsNullOrEmpty(resolvedPath))
			{
				log.LogWarning((object)("Coilhead audio clip '" + fileName + "' was not found under " + EmpressRepoCoilheadPlugin.PluginDirectory));
				yield break;
			}
			UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip("file:///" + resolvedPath.Replace("\\", "/"), GetAudioType(resolvedPath));
			try
			{
				yield return request.SendWebRequest();
				if ((int)request.result != 1)
				{
					log.LogWarning((object)("Failed to load Coilhead audio clip from " + resolvedPath + ": " + request.error));
					yield break;
				}
				AudioClip clip = DownloadHandlerAudioClip.GetContent(request);
				((Object)clip).name = Path.GetFileNameWithoutExtension(fileName);
				((Object)clip).hideFlags = (HideFlags)61;
				assign(clip);
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
		}

		private static AudioType GetAudioType(string path)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.GetExtension(path).ToLowerInvariant();
			if (1 == 0)
			{
			}
			AudioType result = ((text == ".wav") ? ((AudioType)20) : ((!(text == ".mp3")) ? ((AudioType)14) : ((AudioType)13)));
			if (1 == 0)
			{
			}
			return result;
		}
	}
	public sealed class EmpressRepoCoilheadController : MonoBehaviour
	{
		private enum CoilheadState
		{
			Roaming,
			Hunting,
			Cooldown
		}

		private const float WatchAngle = 34f;

		private const float WatchRange = 55f;

		private const float KillRange = 1.85f;

		private const float RoamSpeed = 3.75f;

		private const float ChaseSpeed = 6.4f;

		private const float CooldownDuration = 10f;

		private const float CooldownMoveTime = 9f;

		public Transform VisualRoot = null;

		public Transform CenterTransform = null;

		public Transform HeadTransform = null;

		public Animator? VisualAnimator;

		public AudioSource VoiceSource = null;

		public AudioSource MovementSource = null;

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

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

		public AudioClip? KillClip;

		public AudioClip? CooldownClip;

		private Enemy _enemy = null;

		private EnemyParent _enemyParent = null;

		private PhotonView _photonView = null;

		private EnemyNavMeshAgent? _navAgent;

		private PlayerAvatar? _targetPlayer;

		private CoilheadState _state;

		private bool _frozen = true;

		private bool _initialized;

		private bool _spawnedPrevious;

		private float _stateTimer;

		private float _targetRefreshTimer;

		private float _killCooldown;

		private float _continuousMoveTimer;

		private float _roamRetargetTimer;

		private Vector3 _roamDestination;

		private Vector3 _lastPosition;

		private bool _hasLastPosition;

		private float _movementSpeed;

		private int _boingVariant;

		private bool _animatorHasWalkSpeed;

		private bool _animatorHasOnCooldown;

		private bool _animatorHasSpringBoing;

		private bool _animatorHasSpringBoingPosition2;

		private float _movementAudioTimer;

		private int _movementAudioIndex;

		private CoilheadState _previousState;

		internal EnemyNavMeshAgent? NavAgent => _navAgent;

		private void Awake()
		{
			_enemy = ((Component)this).GetComponent<Enemy>();
			_enemyParent = ((Component)this).GetComponentInParent<EnemyParent>() ?? ((Component)this).GetComponent<EnemyParent>() ?? ((Component)this).GetComponentInChildren<EnemyParent>(true);
			_photonView = ((Component)this).GetComponent<PhotonView>();
			_navAgent = (EnemyNavMeshAgent?)(_enemy.HasNavMeshAgent ? ((object)_enemy.NavMeshAgent) : ((object)FindNearbyComponent<EnemyNavMeshAgent>((Component)(object)_enemy)));
		}

		public void InitializeRuntime()
		{
			if (!_initialized)
			{
				if ((Object)(object)VisualAnimator != (Object)null)
				{
					((Behaviour)VisualAnimator).enabled = true;
					VisualAnimator.applyRootMotion = false;
					_animatorHasWalkSpeed = HasAnimatorParameter(VisualAnimator, "walkSpeed", (AnimatorControllerParameterType)1);
					_animatorHasOnCooldown = HasAnimatorParameter(VisualAnimator, "OnCooldown", (AnimatorControllerParameterType)4);
					_animatorHasSpringBoing = HasAnimatorParameter(VisualAnimator, "springBoing", (AnimatorControllerParameterType)9);
					_animatorHasSpringBoingPosition2 = HasAnimatorParameter(VisualAnimator, "springBoingPosition2", (AnimatorControllerParameterType)9);
				}
				_state = CoilheadState.Roaming;
				_previousState = _state;
				_frozen = true;
				_targetRefreshTimer = 0f;
				_roamRetargetTimer = 0f;
				_movementAudioTimer = 0f;
				_movementAudioIndex = 0;
				_initialized = true;
				UpdateAnimatorState(forceSpring: false);
			}
		}

		private static T? FindNearbyComponent<T>(Component component) where T : Component
		{
			return component.GetComponent<T>() ?? component.GetComponentInChildren<T>(true) ?? component.GetComponentInParent<T>(true);
		}

		private void Update()
		{
			//IL_005a: 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_0037: 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)
			if (!_initialized)
			{
				return;
			}
			if (_hasLastPosition && Time.deltaTime > 0f)
			{
				_movementSpeed = Vector3.Distance(((Component)this).transform.position, _lastPosition) / Time.deltaTime;
			}
			_lastPosition = ((Component)this).transform.position;
			_hasLastPosition = true;
			_stateTimer += Time.deltaTime;
			if (_killCooldown > 0f)
			{
				_killCooldown -= Time.deltaTime;
			}
			bool flag = (Object)(object)_enemyParent != (Object)null && _enemyParent.Spawned && ((Object)(object)_enemyParent.EnableObject == (Object)null || _enemyParent.EnableObject.activeSelf);
			if (flag != _spawnedPrevious)
			{
				_spawnedPrevious = flag;
				if (flag)
				{
					ResetBehaviour();
				}
			}
			if (!flag)
			{
				_frozen = true;
				StopMovementAudio();
				UpdateAnimatorState(forceSpring: false);
				return;
			}
			if (HasAuthority())
			{
				RunAuthorityLogic();
			}
			UpdateAudioState();
			UpdateAnimatorState(forceSpring: false);
		}

		private void ResetBehaviour()
		{
			_state = CoilheadState.Roaming;
			_frozen = true;
			_stateTimer = 0f;
			_targetRefreshTimer = 0f;
			_continuousMoveTimer = 0f;
			_roamRetargetTimer = 0f;
			_targetPlayer = null;
			RepoEnemyAccess.SetTargetPlayerViewId(_enemy, -1);
			StopAllAudio();
			StopMoving();
			BroadcastState();
		}

		private bool HasAuthority()
		{
			return !SemiFunc.IsMultiplayer() || PhotonNetwork.IsMasterClient;
		}

		private void RunAuthorityLogic()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			_targetRefreshTimer -= Time.deltaTime;
			if (_targetRefreshTimer <= 0f)
			{
				_targetRefreshTimer = 0.35f;
				AcquireNearestTarget(65f);
			}
			bool frozen = IsAnyPlayerWatchingMe();
			SetFrozen(frozen);
			if (_state == CoilheadState.Cooldown)
			{
				HandleCooldown();
				return;
			}
			if (_frozen)
			{
				_continuousMoveTimer = 0f;
				StopMoving();
				return;
			}
			if ((Object)(object)_targetPlayer != (Object)null && IsTargetValid(_targetPlayer))
			{
				SetState(CoilheadState.Hunting);
				MoveTowards(((Component)_targetPlayer).transform.position, 6.4f);
			}
			else
			{
				SetState(CoilheadState.Roaming);
				HandleRoam();
			}
			if (_movementSpeed > 0.35f)
			{
				_continuousMoveTimer += Time.deltaTime;
			}
			else
			{
				_continuousMoveTimer = Mathf.Max(0f, _continuousMoveTimer - Time.deltaTime * 2f);
			}
			if (_continuousMoveTimer >= 9f)
			{
				EnterCooldown();
			}
			else
			{
				TryKillNearbyPlayer();
			}
		}

		private void HandleCooldown()
		{
			StopMoving();
			if (_stateTimer >= 10f)
			{
				_state = CoilheadState.Roaming;
				_stateTimer = 0f;
				_continuousMoveTimer = 0f;
				BroadcastState();
			}
		}

		private void EnterCooldown()
		{
			_state = CoilheadState.Cooldown;
			_stateTimer = 0f;
			_continuousMoveTimer = 0f;
			StopMoving();
			PlayCooldownClip();
			BroadcastState();
		}

		private void HandleRoam()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			_roamRetargetTimer -= Time.deltaTime;
			if (_roamRetargetTimer <= 0f || !_navAgentHasPath())
			{
				_roamRetargetTimer = Random.Range(2.6f, 4.4f);
				_roamDestination = PickRoamDestination();
			}
			MoveTowards(_roamDestination, 3.75f);
		}

		private bool _navAgentHasPath()
		{
			return (Object)(object)_navAgent != (Object)null && (Object)(object)_navAgent.Agent != (Object)null && _navAgent.Agent.hasPath;
		}

		private Vector3 PickRoamDestination()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_0038: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)this).transform.position;
			NavMeshHit val3 = default(NavMeshHit);
			for (int i = 0; i < 8; i++)
			{
				Vector2 val = Random.insideUnitCircle * Random.Range(4f, 10f);
				Vector3 val2 = position + new Vector3(val.x, 0f, val.y);
				if (NavMesh.SamplePosition(val2, ref val3, 8f, -1))
				{
					return ((NavMeshHit)(ref val3)).position;
				}
			}
			return position;
		}

		private void MoveTowards(Vector3 targetPosition, float speed)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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)
			if ((Object)(object)_navAgent == (Object)null || (Object)(object)_navAgent.Agent == (Object)null)
			{
				return;
			}
			try
			{
				_navAgent.UpdateAgent(speed, Mathf.Max(28f, speed * 8f));
				_navAgent.SetDestination(targetPosition);
				Vector3 desiredVelocity = _navAgent.Agent.desiredVelocity;
				if (((Vector3)(ref desiredVelocity)).sqrMagnitude > 0.01f)
				{
					FaceAlongDirection(desiredVelocity, 14f);
				}
				else
				{
					FaceTowards(targetPosition, 12f);
				}
			}
			catch
			{
				StopMoving();
			}
		}

		private void StopMoving()
		{
			if ((Object)(object)_navAgent != (Object)null)
			{
				_navAgent.Stop(0.15f);
				_navAgent.ResetPath();
			}
		}

		private void FaceAlongDirection(Vector3 worldDirection, float turnSpeed)
		{
			//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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = worldDirection;
			val.y = 0f;
			if (!(((Vector3)(ref val)).sqrMagnitude <= 0.001f))
			{
				Quaternion val2 = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
				((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, val2, turnSpeed * Time.deltaTime);
			}
		}

		private void FaceTowards(Vector3 worldPosition, float turnSpeed)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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)
			Vector3 val = worldPosition - ((Component)this).transform.position;
			val.y = 0f;
			if (!(((Vector3)(ref val)).sqrMagnitude <= 0.001f))
			{
				Quaternion val2 = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
				((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, val2, turnSpeed * Time.deltaTime);
			}
		}

		private void AcquireNearestTarget(float maxDistance)
		{
			//IL_0065: 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)
			if ((Object)(object)GameDirector.instance == (Object)null)
			{
				_targetPlayer = null;
				RepoEnemyAccess.SetTargetPlayerViewId(_enemy, -1);
				return;
			}
			float num = maxDistance;
			PlayerAvatar val = null;
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (IsTargetValid(player))
				{
					float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position);
					if (num2 < num)
					{
						num = num2;
						val = player;
					}
				}
			}
			_targetPlayer = val;
			RepoEnemyAccess.SetTargetPlayerViewId(_enemy, ((Object)(object)val != (Object)null) ? val.photonView.ViewID : (-1));
		}

		private bool IsAnyPlayerWatchingMe()
		{
			//IL_0039: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: 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)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)GameDirector.instance == (Object)null)
			{
				return false;
			}
			Vector3 val = (((Object)(object)HeadTransform != (Object)null) ? HeadTransform.position : CenterTransform.position);
			int num = LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct());
			RaycastHit val4 = default(RaycastHit);
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (!IsTargetValid(player))
				{
					continue;
				}
				Transform val2 = (((Object)(object)player.PlayerVisionTarget != (Object)null && (Object)(object)player.PlayerVisionTarget.VisionTransform != (Object)null) ? player.PlayerVisionTarget.VisionTransform : (((Object)(object)player.localCamera != (Object)null) ? ((Component)player.localCamera).transform : ((Component)player).transform));
				Vector3 val3 = val - val2.position;
				float magnitude = ((Vector3)(ref val3)).magnitude;
				if (!(magnitude <= 0.05f) && !(magnitude > 55f))
				{
					float num2 = Vector3.Angle(val2.forward, val3);
					if (!(num2 > 34f) && (!Physics.Linecast(val2.position, val, ref val4, num, (QueryTriggerInteraction)1) || ((RaycastHit)(ref val4)).transform.IsChildOf(((Component)this).transform) || ((RaycastHit)(ref val4)).transform.IsChildOf(((Component)player).transform)))
					{
						return true;
					}
				}
			}
			return false;
		}

		private void SetFrozen(bool frozen)
		{
			if (_frozen != frozen)
			{
				_frozen = frozen;
				bool flag = frozen;
				int num = -1;
				if (flag)
				{
					num = _boingVariant++ % 2;
					TriggerSpringAnimation(num);
					PlaySpringStopClip(num);
				}
				if (SemiFunc.IsMultiplayer())
				{
					_photonView.RPC("SyncFrozenRpc", (RpcTarget)1, new object[2] { frozen, num });
				}
			}
		}

		private void SetState(CoilheadState newState)
		{
			if (_state != newState)
			{
				_previousState = _state;
				_state = newState;
				_stateTimer = 0f;
				BroadcastState();
			}
		}

		private void BroadcastState()
		{
			if (SemiFunc.IsMultiplayer())
			{
				_photonView.RPC("SyncStateRpc", (RpcTarget)1, new object[1] { (int)_state });
			}
		}

		[PunRPC]
		private void SyncStateRpc(int state, PhotonMessageInfo info)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.MasterOnlyRPC(info))
			{
				_state = (CoilheadState)state;
				_stateTimer = 0f;
				if (_state == CoilheadState.Cooldown && _previousState != CoilheadState.Cooldown)
				{
					PlayCooldownClip();
				}
				_previousState = _state;
			}
		}

		[PunRPC]
		private void SyncFrozenRpc(bool frozen, int springVariant, PhotonMessageInfo info)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.MasterOnlyRPC(info))
			{
				_frozen = frozen;
				if (springVariant >= 0)
				{
					TriggerSpringAnimation(springVariant);
					PlaySpringStopClip(springVariant);
				}
			}
		}

		private void TriggerSpringAnimation(int variant)
		{
			if (!((Object)(object)VisualAnimator == (Object)null))
			{
				if (variant % 2 == 0 && _animatorHasSpringBoing)
				{
					VisualAnimator.SetTrigger("springBoing");
				}
				else if (_animatorHasSpringBoingPosition2)
				{
					VisualAnimator.SetTrigger("springBoingPosition2");
				}
				else if (_animatorHasSpringBoing)
				{
					VisualAnimator.SetTrigger("springBoing");
				}
			}
		}

		private void UpdateAnimatorState(bool forceSpring)
		{
			if (!((Object)(object)VisualAnimator == (Object)null))
			{
				float num = 0f;
				if (!_frozen && _state != CoilheadState.Cooldown)
				{
					num = ((_state == CoilheadState.Hunting) ? 6f : 3.2f);
				}
				if (_animatorHasWalkSpeed)
				{
					VisualAnimator.SetFloat("walkSpeed", num);
				}
				if (_animatorHasOnCooldown)
				{
					VisualAnimator.SetBool("OnCooldown", _state == CoilheadState.Cooldown);
				}
				if (forceSpring)
				{
					TriggerSpringAnimation(_boingVariant++ % 2);
				}
			}
		}

		private void UpdateAudioState()
		{
			if (_state == CoilheadState.Cooldown || _frozen)
			{
				StopMovementAudio();
				return;
			}
			if (_movementSpeed < 0.4f || SpringWobbleClips.Length == 0 || (Object)(object)MovementSource == (Object)null)
			{
				StopMovementAudio();
				return;
			}
			_movementAudioTimer -= Time.deltaTime;
			float movementAudioTimer = Mathf.Lerp(0.7f, 0.28f, Mathf.InverseLerp(3.75f, 9.4f, _movementSpeed));
			if (!(_movementAudioTimer > 0f))
			{
				AudioClip val = SpringWobbleClips[_movementAudioIndex % SpringWobbleClips.Length];
				if ((Object)(object)val != (Object)null)
				{
					MovementSource.pitch = Mathf.Lerp(0.92f, 1.08f, Mathf.InverseLerp(3.75f, 9.4f, _movementSpeed));
					MovementSource.PlayOneShot(val);
				}
				_movementAudioIndex++;
				_movementAudioTimer = movementAudioTimer;
			}
		}

		private void PlaySpringStopClip(int variant)
		{
			if (!((Object)(object)VoiceSource == (Object)null) && SpringStopClips.Length != 0)
			{
				AudioClip val = SpringStopClips[Mathf.Abs(variant) % SpringStopClips.Length];
				if (!((Object)(object)val == (Object)null))
				{
					VoiceSource.pitch = 1f;
					VoiceSource.PlayOneShot(val);
				}
			}
		}

		private void PlayCooldownClip()
		{
			if (!((Object)(object)VoiceSource == (Object)null) && !((Object)(object)CooldownClip == (Object)null))
			{
				VoiceSource.pitch = 1f;
				VoiceSource.PlayOneShot(CooldownClip);
			}
		}

		private void StopMovementAudio()
		{
			if (!((Object)(object)MovementSource == (Object)null))
			{
				if (MovementSource.isPlaying)
				{
					MovementSource.Stop();
				}
				_movementAudioTimer = 0f;
			}
		}

		private void TryKillNearbyPlayer()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			if (_killCooldown > 0f || _frozen || _state == CoilheadState.Cooldown || (Object)(object)GameDirector.instance == (Object)null)
			{
				return;
			}
			PlayerAvatar val = null;
			float num = 1.85f;
			foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
			{
				if (IsTargetValid(player))
				{
					float num2 = Vector3.Distance(CenterTransform.position, ((Component)player).transform.position);
					if (num2 <= num)
					{
						num = num2;
						val = player;
					}
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
				val.playerHealth.HurtOther(999, ((Component)val).transform.position, false, SemiFunc.EnemyGetIndex(_enemy));
				_killCooldown = 1f;
				PlayKillCue();
				if (SemiFunc.IsMultiplayer())
				{
					_photonView.RPC("PlayKillCueRpc", (RpcTarget)1, Array.Empty<object>());
				}
			}
		}

		[PunRPC]
		private void PlayKillCueRpc(PhotonMessageInfo info)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.MasterOnlyRPC(info))
			{
				PlayKillCue();
			}
		}

		private void PlayKillCue()
		{
			if (!((Object)(object)VoiceSource == (Object)null) && !((Object)(object)KillClip == (Object)null))
			{
				VoiceSource.pitch = 1f;
				VoiceSource.PlayOneShot(KillClip);
			}
		}

		private void StopAllAudio()
		{
			AudioSource voiceSource = VoiceSource;
			if (voiceSource != null)
			{
				voiceSource.Stop();
			}
			AudioSource movementSource = MovementSource;
			if (movementSource != null)
			{
				movementSource.Stop();
			}
			_movementAudioTimer = 0f;
		}

		private static bool HasAnimatorParameter(Animator animator, string parameterName, AnimatorControllerParameterType parameterType)
		{
			//IL_0013: 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)
			AnimatorControllerParameter[] parameters = animator.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				if (val.type == parameterType && string.Equals(val.name, parameterName, StringComparison.Ordinal))
				{
					return true;
				}
			}
			return false;
		}

		private bool IsTargetValid(PlayerAvatar? player)
		{
			return (Object)(object)player != (Object)null && !player.isDisabled && !player.deadSet && (Object)(object)player.playerHealth != (Object)null;
		}
	}
}