Decompiled source of Dracula Flow Headman v1.0.0

plugins/HeadmanVoiceLines/HeadmanVoiceLines.dll

Decompiled 7 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("HeadmanVoiceLines")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("HP")]
[assembly: AssemblyProduct("HeadmanVoiceLines")]
[assembly: AssemblyCopyright("Copyright © HP 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("2c9dd7b1-80e1-471e-878b-e0cd7c5f897a")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HeadmanVoiceLines;

[BepInPlugin("com.yourname.headmanvoicelines", "Headman Voice Lines", "2.2.0")]
public class HeadmanVoiceLinesPlugin : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	internal static List<AudioClip> VoiceLines = new List<AudioClip>();

	internal static List<AudioClip> AttackLines = new List<AudioClip>();

	internal static string PluginFolder;

	internal static AssetBundle ModelBundle;

	internal static GameObject CustomModelPrefab;

	internal static float MinTimeBetweenLines = 5f;

	internal static float MaxTimeBetweenLines = 13f;

	internal static float VoiceVolume = 0.7f;

	private void Awake()
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		PluginFolder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		LoadVoiceLines();
		LoadModelBundle();
		Harmony val = new Harmony("com.yourname.headmanvoicelines");
		val.PatchAll();
		Log.LogInfo((object)"Headman Voice Lines + Model Swap plugin started!");
	}

	private void LoadModelBundle()
	{
		string text = Path.Combine(PluginFolder, "headmanmod");
		if (!File.Exists(text))
		{
			Log.LogWarning((object)("Asset bundle not found at: " + text));
			return;
		}
		ModelBundle = AssetBundle.LoadFromFile(text);
		if ((Object)(object)ModelBundle == (Object)null)
		{
			Log.LogError((object)"Failed to load asset bundle!");
			return;
		}
		GameObject[] array = ModelBundle.LoadAllAssets<GameObject>();
		Log.LogInfo((object)$"Found {array.Length} GameObjects in bundle");
		if (array.Length != 0)
		{
			CustomModelPrefab = array[0];
			Log.LogInfo((object)("Loaded model: " + ((Object)CustomModelPrefab).name));
		}
		else
		{
			Log.LogError((object)"No GameObjects found in asset bundle!");
		}
	}

	private void LoadVoiceLines()
	{
		string path = Path.Combine(PluginFolder, "VoiceLines");
		if (!Directory.Exists(path))
		{
			Directory.CreateDirectory(path);
			return;
		}
		string[] files = Directory.GetFiles(path, "*.wav");
		foreach (string text in files)
		{
			AudioClip val = LoadWavFile(text);
			if ((Object)(object)val != (Object)null)
			{
				VoiceLines.Add(val);
				Log.LogInfo((object)("Loaded voice line: " + Path.GetFileName(text)));
			}
		}
		string[] files2 = Directory.GetFiles(path, "*.ogg");
		foreach (string text2 in files2)
		{
			AudioClip val2 = LoadOggFile(text2);
			if ((Object)(object)val2 != (Object)null)
			{
				VoiceLines.Add(val2);
				Log.LogInfo((object)("Loaded voice line: " + Path.GetFileName(text2)));
			}
		}
		Log.LogInfo((object)$"Loaded {VoiceLines.Count} voice line(s).");
		string path2 = Path.Combine(PluginFolder, "AttackLines");
		if (!Directory.Exists(path2))
		{
			Directory.CreateDirectory(path2);
			Log.LogInfo((object)"Created AttackLines folder (add .wav files for chase voice lines)");
			return;
		}
		string[] files3 = Directory.GetFiles(path2, "*.wav");
		foreach (string text3 in files3)
		{
			AudioClip val3 = LoadWavFile(text3);
			if ((Object)(object)val3 != (Object)null)
			{
				AttackLines.Add(val3);
				Log.LogInfo((object)("Loaded attack line: " + Path.GetFileName(text3)));
			}
		}
		string[] files4 = Directory.GetFiles(path2, "*.ogg");
		foreach (string text4 in files4)
		{
			AudioClip val4 = LoadOggFile(text4);
			if ((Object)(object)val4 != (Object)null)
			{
				AttackLines.Add(val4);
				Log.LogInfo((object)("Loaded attack line: " + Path.GetFileName(text4)));
			}
		}
		Log.LogInfo((object)$"Loaded {AttackLines.Count} attack line(s).");
	}

	private AudioClip LoadWavFile(string filePath)
	{
		try
		{
			byte[] array = File.ReadAllBytes(filePath);
			int num = BitConverter.ToInt16(array, 22);
			int num2 = BitConverter.ToInt32(array, 24);
			int num3 = BitConverter.ToInt16(array, 34);
			int num4;
			for (int i = 12; i < array.Length - 8; i += 8 + num4)
			{
				string @string = Encoding.ASCII.GetString(array, i, 4);
				num4 = BitConverter.ToInt32(array, i + 4);
				if (!(@string == "data"))
				{
					continue;
				}
				i += 8;
				int num5 = num4 / (num3 / 8) / num;
				float[] array2 = new float[num5 * num];
				switch (num3)
				{
				case 16:
				{
					for (int k = 0; k < array2.Length && i + k * 2 + 1 < array.Length; k++)
					{
						short num6 = BitConverter.ToInt16(array, i + k * 2);
						array2[k] = (float)num6 / 32768f;
					}
					break;
				}
				case 8:
				{
					for (int j = 0; j < array2.Length && i + j < array.Length; j++)
					{
						array2[j] = (float)(array[i + j] - 128) / 128f;
					}
					break;
				}
				}
				AudioClip val = AudioClip.Create(Path.GetFileNameWithoutExtension(filePath), num5, num, num2, false);
				val.SetData(array2, 0);
				return val;
			}
			return null;
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Error loading WAV: " + ex.Message));
			return null;
		}
	}

	private AudioClip LoadOggFile(string filePath)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Invalid comparison between Unknown and I4
		try
		{
			string text = "file:///" + filePath.Replace("\\", "/");
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)14);
			audioClip.SendWebRequest();
			while (!audioClip.isDone)
			{
				Thread.Sleep(10);
			}
			if ((int)audioClip.result == 1)
			{
				AudioClip content = DownloadHandlerAudioClip.GetContent(audioClip);
				((Object)content).name = Path.GetFileNameWithoutExtension(filePath);
				return content;
			}
			return null;
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Error loading OGG: " + ex.Message));
			return null;
		}
	}
}
public static class PluginInfo
{
	public const string PLUGIN_GUID = "com.yourname.headmanvoicelines";

	public const string PLUGIN_NAME = "Headman Voice Lines";

	public const string PLUGIN_VERSION = "2.2.0";
}
public class HeadmanVoiceLinePlayer : MonoBehaviour
{
	private AudioSource voiceSource;

	private float nextLineTime;

	private object enemyObject;

	private PropertyInfo currentStateProp;

	private FieldInfo _currentStateField;

	private Type enemyStateType;

	private object stateRoaming;

	private object stateSneak;

	private object stateChase;

	private object stateChaseSlow;

	private object stateChaseBegin;

	private object stateChaseEnd;

	private object stateLookUnder;

	private object stateInvestigate;

	private bool isSetup = false;

	private Transform jawTransform;

	private float jawTalkAngle = 20f;

	private float jawBiteAngle = 40f;

	private float jawSpeed = 8f;

	private float jawTalkSpeed = 12f;

	private float currentJawAngle = 0f;

	private object previousState = null;

	private object playerHealthObj;

	private FieldInfo playerHealthField;

	private PropertyInfo playerHealthProp;

	private float lastKnownHealth = -1f;

	private float biteSnapTime = 0f;

	private float biteSnapDuration = 0.5f;

	private void Start()
	{
		voiceSource = ((Component)this).gameObject.AddComponent<AudioSource>();
		voiceSource.spatialBlend = 1f;
		voiceSource.rolloffMode = (AudioRolloffMode)1;
		voiceSource.minDistance = 2f;
		voiceSource.maxDistance = 30f;
		voiceSource.volume = HeadmanVoiceLinesPlugin.VoiceVolume;
		voiceSource.playOnAwake = false;
		SetupReflection();
		SwapModel();
		ResetTimer();
	}

	private void SwapModel()
	{
		//IL_05b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_05cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_070c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0713: Unknown result type (might be due to invalid IL or missing references)
		//IL_0728: Unknown result type (might be due to invalid IL or missing references)
		//IL_073a: Unknown result type (might be due to invalid IL or missing references)
		//IL_074c: Unknown result type (might be due to invalid IL or missing references)
		//IL_12c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_12ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0922: Unknown result type (might be due to invalid IL or missing references)
		//IL_0929: Expected O, but got Unknown
		//IL_0929: Unknown result type (might be due to invalid IL or missing references)
		//IL_092e: Unknown result type (might be due to invalid IL or missing references)
		//IL_13ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_13ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_13bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_13c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_09a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_095c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0961: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d97: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d9c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0da0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0dac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0db1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0db5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c6e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c74: Expected O, but got Unknown
		//IL_0c88: Unknown result type (might be due to invalid IL or missing references)
		//IL_09c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0984: Unknown result type (might be due to invalid IL or missing references)
		//IL_0989: Unknown result type (might be due to invalid IL or missing references)
		//IL_10c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_10cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_10d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_10d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_09e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_10fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_1111: Unknown result type (might be due to invalid IL or missing references)
		//IL_1116: Unknown result type (might be due to invalid IL or missing references)
		//IL_112d: Unknown result type (might be due to invalid IL or missing references)
		//IL_1132: Unknown result type (might be due to invalid IL or missing references)
		//IL_1136: Unknown result type (might be due to invalid IL or missing references)
		//IL_1142: Unknown result type (might be due to invalid IL or missing references)
		//IL_1147: Unknown result type (might be due to invalid IL or missing references)
		//IL_114b: Unknown result type (might be due to invalid IL or missing references)
		//IL_11d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_11dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_11e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_11ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_11f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_11f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_1243: Unknown result type (might be due to invalid IL or missing references)
		//IL_1248: Unknown result type (might be due to invalid IL or missing references)
		//IL_124c: Unknown result type (might be due to invalid IL or missing references)
		//IL_1258: Unknown result type (might be due to invalid IL or missing references)
		//IL_125d: Unknown result type (might be due to invalid IL or missing references)
		//IL_1261: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e6a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e6f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ed0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0edf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0eee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0efd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f0c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f1b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e85: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e8b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e90: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e95: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e97: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e9d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ea2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ea7: Unknown result type (might be due to invalid IL or missing references)
		//IL_106b: Unknown result type (might be due to invalid IL or missing references)
		//IL_1070: Unknown result type (might be due to invalid IL or missing references)
		//IL_1074: Unknown result type (might be due to invalid IL or missing references)
		//IL_1080: Unknown result type (might be due to invalid IL or missing references)
		//IL_1085: Unknown result type (might be due to invalid IL or missing references)
		//IL_1089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bc2: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)HeadmanVoiceLinesPlugin.CustomModelPrefab == (Object)null)
		{
			HeadmanVoiceLinesPlugin.Log.LogWarning((object)"No custom model to swap!");
			return;
		}
		try
		{
			Type type = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				type = assembly.GetType("EnemyHeadController");
				if (type != null)
				{
					break;
				}
			}
			if (type == null)
			{
				return;
			}
			Component val = ((Component)this).GetComponent(type);
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)this).GetComponentInParent(type);
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform val2 = val.transform;
			while ((Object)(object)val2.parent != (Object)null)
			{
				Type type2 = null;
				Assembly[] assemblies2 = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly2 in assemblies2)
				{
					type2 = assembly2.GetType("EnemyParent");
					if (type2 != null)
					{
						break;
					}
				}
				if (type2 != null && (Object)(object)((Component)val2).GetComponent(type2) != (Object)null)
				{
					break;
				}
				val2 = val2.parent;
			}
			HeadmanVoiceLinesPlugin.Log.LogInfo((object)("Head enemy root: " + ((Object)val2).name));
			Renderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Renderer>(true);
			HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"Found {componentsInChildren.Length} renderers on Head enemy");
			Material val3 = null;
			Shader val4 = null;
			Texture2D val5 = null;
			HashSet<string> hashSet = new HashSet<string>();
			int num = -1;
			Renderer[] array = componentsInChildren;
			foreach (Renderer val6 in array)
			{
				if ((Object)(object)val6.sharedMaterial != (Object)null && (Object)(object)val6.sharedMaterial.shader != (Object)null)
				{
					string name = ((Object)val6.sharedMaterial.shader).name;
					hashSet.Add(name);
					HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  Renderer '{((Object)((Component)val6).gameObject).name}' shader='{name}' layer={((Component)val6).gameObject.layer} type={((object)val6).GetType().Name}");
				}
			}
			HeadmanVoiceLinesPlugin.Log.LogInfo((object)("All shaders used by Head enemy: " + string.Join(", ", hashSet)));
			string[] array2 = new string[3] { "Hurtable/Hurtable", "Hurtable/Hurtable Alpha Clip", "Standard" };
			string[] array3 = array2;
			foreach (string text in array3)
			{
				if ((Object)(object)val4 != (Object)null)
				{
					break;
				}
				Renderer[] array4 = componentsInChildren;
				foreach (Renderer val7 in array4)
				{
					if ((Object)(object)val7.sharedMaterial != (Object)null && (Object)(object)val7.sharedMaterial.shader != (Object)null && ((Object)val7.sharedMaterial.shader).name == text && !(((object)val7).GetType().Name == "ParticleSystemRenderer") && !(((Object)((Component)val7).gameObject).name == "Debug"))
					{
						val4 = val7.sharedMaterial.shader;
						val3 = val7.sharedMaterial;
						num = ((Component)val7).gameObject.layer;
						if ((Object)(object)val7.sharedMaterial.mainTexture != (Object)null)
						{
							Texture mainTexture = val7.sharedMaterial.mainTexture;
							val5 = (Texture2D)(object)((mainTexture is Texture2D) ? mainTexture : null);
						}
						HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"STOLEN shader: '{((Object)val4).name}' from renderer '{((Object)((Component)val7).gameObject).name}' layer={num} (preferred match)");
						break;
					}
				}
			}
			if ((Object)(object)val4 == (Object)null)
			{
				Renderer[] array5 = componentsInChildren;
				foreach (Renderer val8 in array5)
				{
					if (!(((object)val8).GetType().Name == "ParticleSystemRenderer") && !((Object)(object)val8.sharedMaterial == (Object)null) && !((Object)(object)val8.sharedMaterial.shader == (Object)null) && !((Object)val8.sharedMaterial.shader).name.Contains("Particle"))
					{
						val4 = val8.sharedMaterial.shader;
						val3 = val8.sharedMaterial;
						num = ((Component)val8).gameObject.layer;
						if ((Object)(object)val8.sharedMaterial.mainTexture != (Object)null)
						{
							Texture mainTexture2 = val8.sharedMaterial.mainTexture;
							val5 = (Texture2D)(object)((mainTexture2 is Texture2D) ? mainTexture2 : null);
						}
						HeadmanVoiceLinesPlugin.Log.LogInfo((object)("STOLEN shader: '" + ((Object)val4).name + "' from renderer '" + ((Object)((Component)val8).gameObject).name + "' (fallback non-particle)"));
						break;
					}
				}
			}
			if ((Object)(object)val4 != (Object)null)
			{
				HeadmanVoiceLinesPlugin.Log.LogInfo((object)("  Material: '" + ((Object)val3).name + "'"));
				HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  Layer: {num}");
				for (int num2 = 0; num2 < val4.GetPropertyCount(); num2++)
				{
					string propertyName = val4.GetPropertyName(num2);
					ShaderPropertyType propertyType = val4.GetPropertyType(num2);
					HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  Shader prop [{num2}]: '{propertyName}' type={propertyType}");
				}
			}
			else
			{
				HeadmanVoiceLinesPlugin.Log.LogWarning((object)"Could not find any suitable non-particle shader!");
			}
			Renderer[] array6 = componentsInChildren;
			foreach (Renderer val9 in array6)
			{
				val9.enabled = false;
			}
			HeadmanVoiceLinesPlugin.Log.LogInfo((object)"Disabled all original Head renderers");
			Transform val10 = null;
			Transform[] componentsInChildren2 = ((Component)val2).GetComponentsInChildren<Transform>(true);
			Transform[] array7 = componentsInChildren2;
			foreach (Transform val11 in array7)
			{
				if (((Object)val11).name == "Mesh" && (Object)(object)val11.parent != (Object)null && ((Object)val11.parent).name == "Enable")
				{
					val10 = val11;
					break;
				}
			}
			if ((Object)(object)val10 == (Object)null)
			{
				val10 = val.transform;
				HeadmanVoiceLinesPlugin.Log.LogInfo((object)"Mesh transform not found, attaching to controller");
			}
			else
			{
				HeadmanVoiceLinesPlugin.Log.LogInfo((object)("Attaching to Mesh transform: " + ((Object)val10).name));
			}
			GameObject val12 = Object.Instantiate<GameObject>(HeadmanVoiceLinesPlugin.CustomModelPrefab, val10.position, val10.rotation, val10);
			val12.transform.localPosition = Vector3.zero;
			val12.transform.localRotation = Quaternion.identity;
			val12.transform.localScale = Vector3.one;
			int num6 = (val12.layer = ((num >= 0) ? num : ((Component)val2).gameObject.layer));
			Transform[] componentsInChildren3 = val12.GetComponentsInChildren<Transform>(true);
			foreach (Transform val13 in componentsInChildren3)
			{
				((Component)val13).gameObject.layer = num6;
			}
			HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"Set custom model layer to {num6} (headEnemyRoot layer={((Component)val2).gameObject.layer})");
			Renderer[] componentsInChildren4 = val12.GetComponentsInChildren<Renderer>(true);
			HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"Custom model has {componentsInChildren4.Length} renderers");
			Texture2D val14 = null;
			if ((Object)(object)HeadmanVoiceLinesPlugin.ModelBundle != (Object)null)
			{
				Texture2D[] array8 = HeadmanVoiceLinesPlugin.ModelBundle.LoadAllAssets<Texture2D>();
				HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"Found {array8.Length} textures in bundle");
				Texture2D[] array9 = array8;
				foreach (Texture2D val15 in array9)
				{
					HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  Bundle texture: '{((Object)val15).name}' ({((Texture)val15).width}x{((Texture)val15).height})");
					if ((Object)(object)val14 == (Object)null)
					{
						val14 = val15;
					}
				}
			}
			Renderer[] array10 = componentsInChildren4;
			Vector3 val20 = default(Vector3);
			Vector3 val21 = default(Vector3);
			foreach (Renderer val16 in array10)
			{
				val16.enabled = true;
				((Component)val16).gameObject.SetActive(true);
				int num10 = ((num >= 0) ? num : ((Component)val2).gameObject.layer);
				((Component)val16).gameObject.layer = num10;
				Material[] materials = val16.materials;
				for (int num11 = 0; num11 < materials.Length; num11++)
				{
					if ((Object)(object)val4 != (Object)null)
					{
						Material val17 = new Material(val4);
						Color val18 = Color.white;
						if ((Object)(object)materials[num11] != (Object)null)
						{
							if (materials[num11].HasProperty("_Color"))
							{
								val18 = materials[num11].color;
							}
							else if (materials[num11].HasProperty("_BaseColor"))
							{
								val18 = materials[num11].GetColor("_BaseColor");
							}
						}
						if (val17.HasProperty("_AlbedoColor"))
						{
							val17.SetColor("_AlbedoColor", val18);
						}
						if (val17.HasProperty("_Color"))
						{
							val17.color = val18;
						}
						if (val17.HasProperty("_BaseColor"))
						{
							val17.SetColor("_BaseColor", val18);
						}
						if ((Object)(object)val14 != (Object)null)
						{
							if (val17.HasProperty("_AlbedoTexture"))
							{
								val17.SetTexture("_AlbedoTexture", (Texture)(object)val14);
							}
							if (val17.HasProperty("_MainTex"))
							{
								val17.SetTexture("_MainTex", (Texture)(object)val14);
							}
							if (val17.HasProperty("_BaseMap"))
							{
								val17.SetTexture("_BaseMap", (Texture)(object)val14);
							}
							if (val17.HasProperty("_BaseColorMap"))
							{
								val17.SetTexture("_BaseColorMap", (Texture)(object)val14);
							}
						}
						if (val17.HasProperty("_Mode"))
						{
							val17.SetFloat("_Mode", 0f);
						}
						if (val17.HasProperty("_SrcBlend"))
						{
							val17.SetFloat("_SrcBlend", 1f);
						}
						if (val17.HasProperty("_DstBlend"))
						{
							val17.SetFloat("_DstBlend", 0f);
						}
						if (val17.HasProperty("_ZWrite"))
						{
							val17.SetFloat("_ZWrite", 1f);
						}
						val17.renderQueue = -1;
						if (val17.HasProperty("_ColorOverlayAmount"))
						{
							val17.SetFloat("_ColorOverlayAmount", 0f);
						}
						if (val17.HasProperty("_Smoothness"))
						{
							val17.SetFloat("_Smoothness", 0.3f);
						}
						if (val17.HasProperty("_Metallic"))
						{
							val17.SetFloat("_Metallic", 0f);
						}
						materials[num11] = val17;
						HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  Applied shader '{((Object)val4).name}' to material {num11} on '{((Object)((Component)val16).gameObject).name}' color={val18} layer={num10}");
						continue;
					}
					HeadmanVoiceLinesPlugin.Log.LogWarning((object)"No stolen shader available! Trying fallbacks...");
					string[] array11 = new string[8] { "Standard", "HDRP/Lit", "HDRP/Unlit", "Universal Render Pipeline/Lit", "Universal Render Pipeline/Unlit", "Unlit/Color", "Unlit/Texture", "Sprites/Default" };
					string[] array12 = array11;
					foreach (string text2 in array12)
					{
						Shader val19 = Shader.Find(text2);
						if ((Object)(object)val19 != (Object)null)
						{
							materials[num11] = new Material(val19);
							materials[num11].color = new Color(0.79f, 0.66f, 0.57f);
							HeadmanVoiceLinesPlugin.Log.LogInfo((object)("  Using fallback shader: " + text2));
							break;
						}
					}
				}
				val16.materials = materials;
				HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  Enabled renderer: {((object)val16).GetType().Name} on '{((Object)((Component)val16).gameObject).name}' layer={((Component)val16).gameObject.layer}");
				MeshFilter component = ((Component)val16).GetComponent<MeshFilter>();
				Bounds bounds;
				if ((Object)(object)component != (Object)null && (Object)(object)component.mesh != (Object)null)
				{
					Mesh mesh = component.mesh;
					HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  MESH DIAG: vertices={mesh.vertexCount} subMeshCount={mesh.subMeshCount} isReadable={mesh.isReadable}");
					ManualLogSource log = HeadmanVoiceLinesPlugin.Log;
					bounds = mesh.bounds;
					object arg = ((Bounds)(ref bounds)).center;
					bounds = mesh.bounds;
					log.LogInfo((object)$"  MESH DIAG: bounds center={arg} size={((Bounds)(ref bounds)).size}");
					if (mesh.isReadable)
					{
						Vector3[] vertices = mesh.vertices;
						int[] triangles = mesh.triangles;
						Vector2[] uv = mesh.uv;
						Vector3[] normals = mesh.normals;
						HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  MESH DIAG: tris={triangles.Length / 3} uvs={uv.Length} normals={normals.Length}");
						((Vector3)(ref val20))..ctor(float.MaxValue, float.MaxValue, float.MaxValue);
						((Vector3)(ref val21))..ctor(float.MinValue, float.MinValue, float.MinValue);
						int num13 = 0;
						for (int num14 = 0; num14 < vertices.Length; num14++)
						{
							if (vertices[num14] == Vector3.zero)
							{
								num13++;
							}
							val20 = Vector3.Min(val20, vertices[num14]);
							val21 = Vector3.Max(val21, vertices[num14]);
						}
						HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  VERTEX DIAG: min=({val20.x:F4},{val20.y:F4},{val20.z:F4}) max=({val21.x:F4},{val21.y:F4},{val21.z:F4})");
						HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  VERTEX DIAG: zeroVerts={num13}/{vertices.Length}");
						for (int num15 = 0; num15 < Mathf.Min(5, vertices.Length); num15++)
						{
							HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  VERTEX[{num15}]: ({vertices[num15].x:F4},{vertices[num15].y:F4},{vertices[num15].z:F4})");
						}
						for (int num16 = 0; num16 < Mathf.Min(9, triangles.Length); num16 += 3)
						{
							HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  TRI[{num16 / 3}]: {triangles[num16]},{triangles[num16 + 1]},{triangles[num16 + 2]}");
						}
						mesh.RecalculateBounds();
						ManualLogSource log2 = HeadmanVoiceLinesPlugin.Log;
						bounds = mesh.bounds;
						object arg2 = ((Bounds)(ref bounds)).center;
						bounds = mesh.bounds;
						log2.LogInfo((object)$"  MESH DIAG: Recalculated bounds center={arg2} size={((Bounds)(ref bounds)).size}");
						if (normals.Length == 0)
						{
							mesh.RecalculateNormals();
							HeadmanVoiceLinesPlugin.Log.LogInfo((object)"  MESH DIAG: Recalculated normals");
						}
					}
					bounds = mesh.bounds;
					Vector3 size = ((Bounds)(ref bounds)).size;
					if (((Vector3)(ref size)).magnitude < 0.01f)
					{
						mesh.bounds = new Bounds(new Vector3(0f, 0.017f, 0f), new Vector3(0.1f, 0.1f, 0.1f));
						ManualLogSource log3 = HeadmanVoiceLinesPlugin.Log;
						bounds = mesh.bounds;
						object arg3 = ((Bounds)(ref bounds)).center;
						bounds = mesh.bounds;
						log3.LogInfo((object)$"  MESH DIAG: Forced bounds center={arg3} size={((Bounds)(ref bounds)).size}");
					}
				}
				else
				{
					SkinnedMeshRenderer val22 = (SkinnedMeshRenderer)(object)((val16 is SkinnedMeshRenderer) ? val16 : null);
					if ((Object)(object)val22 != (Object)null && (Object)(object)val22.sharedMesh != (Object)null)
					{
						Mesh sharedMesh = val22.sharedMesh;
						HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  SKINNED MESH DIAG: vertices={sharedMesh.vertexCount} triangles={sharedMesh.triangles.Length / 3}");
						ManualLogSource log4 = HeadmanVoiceLinesPlugin.Log;
						bounds = sharedMesh.bounds;
						object arg4 = ((Bounds)(ref bounds)).center;
						bounds = sharedMesh.bounds;
						log4.LogInfo((object)$"  SKINNED MESH DIAG: bounds center={arg4} size={((Bounds)(ref bounds)).size}");
					}
					else
					{
						HeadmanVoiceLinesPlugin.Log.LogWarning((object)("  MESH DIAG: No MeshFilter or mesh found on '" + ((Object)((Component)val16).gameObject).name + "'!"));
					}
				}
				ManualLogSource log5 = HeadmanVoiceLinesPlugin.Log;
				bounds = val16.bounds;
				object arg5 = ((Bounds)(ref bounds)).center;
				bounds = val16.bounds;
				log5.LogInfo((object)$"  RENDERER bounds: center={arg5} size={((Bounds)(ref bounds)).size}");
			}
			HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"Custom model active: {val12.activeSelf}, activeInHierarchy: {val12.activeInHierarchy}");
			HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"Custom model position: {val12.transform.position}");
			HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"Custom model worldScale: {val12.transform.lossyScale}");
			Transform val23 = val12.transform;
			while ((Object)(object)val23 != (Object)null)
			{
				HeadmanVoiceLinesPlugin.Log.LogInfo((object)$"  HIERARCHY: '{((Object)val23).name}' active={((Component)val23).gameObject.activeSelf} layer={((Component)val23).gameObject.layer}");
				val23 = val23.parent;
			}
			Transform[] componentsInChildren5 = val12.GetComponentsInChildren<Transform>(true);
			foreach (Transform val24 in componentsInChildren5)
			{
				if (((Object)val24).name == "Head_Jaw")
				{
					jawTransform = val24;
					ManualLogSource log6 = HeadmanVoiceLinesPlugin.Log;
					string name2 = ((Object)val24).name;
					object arg6 = val24.localPosition;
					Quaternion localRotation = val24.localRotation;
					log6.LogInfo((object)$"Found jaw transform: '{name2}' localPos={arg6} localRot={((Quaternion)(ref localRotation)).eulerAngles}");
					break;
				}
			}
			if ((Object)(object)jawTransform == (Object)null)
			{
				HeadmanVoiceLinesPlugin.Log.LogWarning((object)"Head_Jaw transform not found! Jaw animation won't work.");
			}
			HeadmanVoiceLinesPlugin.Log.LogInfo((object)"Model swap complete!");
		}
		catch (Exception ex)
		{
			HeadmanVoiceLinesPlugin.Log.LogError((object)("Error swapping model: " + ex.Message));
			HeadmanVoiceLinesPlugin.Log.LogError((object)("Stack trace: " + ex.StackTrace));
		}
	}

	private void SetupReflection()
	{
		try
		{
			Type type = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				type = assembly.GetType("Enemy");
				if (type != null)
				{
					break;
				}
			}
			if (type == null)
			{
				return;
			}
			Type type2 = null;
			Assembly[] assemblies2 = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly2 in assemblies2)
			{
				type2 = assembly2.GetType("EnemyHeadController");
				if (type2 != null)
				{
					break;
				}
			}
			if (type2 == null)
			{
				return;
			}
			Component val = ((Component)this).GetComponentInParent(type2);
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)this).GetComponent(type2);
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			FieldInfo field = type2.GetField("Enemy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return;
			}
			enemyObject = field.GetValue(val);
			if (enemyObject == null)
			{
				return;
			}
			currentStateProp = type.GetProperty("CurrentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (currentStateProp == null)
			{
				_currentStateField = type.GetField("CurrentState", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			Assembly[] assemblies3 = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly3 in assemblies3)
			{
				enemyStateType = assembly3.GetType("EnemyState");
				if (enemyStateType != null)
				{
					break;
				}
			}
			if (enemyStateType == null)
			{
				return;
			}
			stateRoaming = Enum.Parse(enemyStateType, "Roaming");
			stateSneak = Enum.Parse(enemyStateType, "Sneak");
			stateChase = Enum.Parse(enemyStateType, "Chase");
			stateChaseSlow = Enum.Parse(enemyStateType, "ChaseSlow");
			stateChaseBegin = Enum.Parse(enemyStateType, "ChaseBegin");
			stateLookUnder = Enum.Parse(enemyStateType, "LookUnder");
			try
			{
				stateChaseEnd = Enum.Parse(enemyStateType, "ChaseEnd");
			}
			catch
			{
				stateChaseEnd = null;
			}
			try
			{
				stateInvestigate = Enum.Parse(enemyStateType, "Investigate");
			}
			catch
			{
				stateInvestigate = null;
			}
			try
			{
				Type type3 = null;
				Assembly[] assemblies4 = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly4 in assemblies4)
				{
					type3 = assembly4.GetType("PlayerHealth");
					if (type3 != null)
					{
						break;
					}
				}
				if (type3 != null)
				{
					Object obj3 = Object.FindObjectOfType(type3);
					Component val2 = (Component)(object)((obj3 is Component) ? obj3 : null);
					if ((Object)(object)val2 != (Object)null)
					{
						playerHealthObj = val2;
						playerHealthField = type3.GetField("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (playerHealthField == null)
						{
							playerHealthField = type3.GetField("Health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						}
						if (playerHealthField == null)
						{
							playerHealthField = type3.GetField("hp", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						}
						if (playerHealthField == null)
						{
							playerHealthProp = type3.GetProperty("health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
							if (playerHealthProp == null)
							{
								playerHealthProp = type3.GetProperty("Health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
							}
						}
						HeadmanVoiceLinesPlugin.Log.LogInfo((object)("Found PlayerHealth: field=" + playerHealthField?.Name + " prop=" + playerHealthProp?.Name));
					}
				}
			}
			catch (Exception ex)
			{
				HeadmanVoiceLinesPlugin.Log.LogWarning((object)("Could not find player health: " + ex.Message));
			}
			isSetup = true;
		}
		catch (Exception ex2)
		{
			HeadmanVoiceLinesPlugin.Log.LogError((object)("Reflection setup error: " + ex2.Message));
		}
	}

	private object GetCurrentState()
	{
		if (enemyObject == null)
		{
			return null;
		}
		try
		{
			if (currentStateProp != null)
			{
				return currentStateProp.GetValue(enemyObject, null);
			}
			if (_currentStateField != null)
			{
				return _currentStateField.GetValue(enemyObject);
			}
		}
		catch
		{
		}
		return null;
	}

	private void Update()
	{
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		if (!isSetup || HeadmanVoiceLinesPlugin.VoiceLines.Count == 0)
		{
			return;
		}
		object currentState = GetCurrentState();
		bool flag = (Object)(object)voiceSource != (Object)null && voiceSource.isPlaying;
		bool flag2 = false;
		if (currentState != null)
		{
			flag2 = currentState.Equals(stateChase) || currentState.Equals(stateChaseSlow) || currentState.Equals(stateChaseBegin);
		}
		if (currentState != null && previousState != null && currentState.Equals(stateChaseBegin) && !previousState.Equals(stateChaseBegin) && HeadmanVoiceLinesPlugin.AttackLines.Count > 0)
		{
			PlayRandomAttackLine();
		}
		previousState = currentState;
		if (!flag && Time.time >= nextLineTime)
		{
			if (IsInMovingState())
			{
				if (flag2 && HeadmanVoiceLinesPlugin.AttackLines.Count > 0)
				{
					PlayRandomAttackLine();
				}
				else
				{
					PlayRandomLine();
				}
			}
			ResetTimer();
		}
		if ((Object)(object)jawTransform != (Object)null)
		{
			bool flag3 = false;
			if (currentState != null && stateChaseEnd != null)
			{
				flag3 = currentState.Equals(stateChaseEnd);
			}
			bool flag4 = (Object)(object)voiceSource != (Object)null && voiceSource.isPlaying;
			if (flag3)
			{
				currentJawAngle = 0f;
			}
			else if (flag2)
			{
				float num = jawBiteAngle;
				currentJawAngle = Mathf.Lerp(currentJawAngle, num, Time.deltaTime * jawSpeed);
			}
			else if (flag4)
			{
				float num2 = (Mathf.Sin(Time.time * jawTalkSpeed) + 1f) * 0.5f;
				currentJawAngle = num2 * jawTalkAngle;
			}
			else
			{
				currentJawAngle = Mathf.Lerp(currentJawAngle, 0f, Time.deltaTime * jawSpeed);
			}
			jawTransform.localRotation = Quaternion.Euler(currentJawAngle, 0f, 0f);
		}
	}

	private bool IsInMovingState()
	{
		object currentState = GetCurrentState();
		if (currentState == null)
		{
			return false;
		}
		try
		{
			bool flag = currentState.Equals(stateRoaming) || currentState.Equals(stateSneak) || currentState.Equals(stateChase) || currentState.Equals(stateChaseSlow) || currentState.Equals(stateChaseBegin) || currentState.Equals(stateLookUnder);
			if (stateInvestigate != null)
			{
				flag = flag || currentState.Equals(stateInvestigate);
			}
			return flag;
		}
		catch
		{
			return false;
		}
	}

	private void PlayRandomLine()
	{
		if (!((Object)(object)voiceSource == (Object)null) && HeadmanVoiceLinesPlugin.VoiceLines.Count != 0)
		{
			int index = Random.Range(0, HeadmanVoiceLinesPlugin.VoiceLines.Count);
			AudioClip clip = HeadmanVoiceLinesPlugin.VoiceLines[index];
			voiceSource.clip = clip;
			voiceSource.pitch = 1f;
			voiceSource.Play();
		}
	}

	private void PlayRandomAttackLine()
	{
		if (!((Object)(object)voiceSource == (Object)null) && HeadmanVoiceLinesPlugin.AttackLines.Count != 0)
		{
			int index = Random.Range(0, HeadmanVoiceLinesPlugin.AttackLines.Count);
			AudioClip clip = HeadmanVoiceLinesPlugin.AttackLines[index];
			voiceSource.clip = clip;
			voiceSource.pitch = 1f;
			voiceSource.Play();
		}
	}

	private void ResetTimer()
	{
		nextLineTime = Time.time + Random.Range(HeadmanVoiceLinesPlugin.MinTimeBetweenLines, HeadmanVoiceLinesPlugin.MaxTimeBetweenLines);
	}
}
[HarmonyPatch]
public class EnemyHeadControllerAwakePatch
{
	private static MethodBase TargetMethod()
	{
		Type type = null;
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			type = assembly.GetType("EnemyHeadController");
			if (type != null)
			{
				break;
			}
		}
		if (type == null)
		{
			return null;
		}
		MethodInfo method = type.GetMethod("Awake", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (method == null)
		{
			method = type.GetMethod("OnSpawn", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}
		return method;
	}

	private static void Postfix(object __instance)
	{
		try
		{
			Component val = (Component)((__instance is Component) ? __instance : null);
			if ((Object)(object)val != (Object)null && (Object)(object)val.gameObject.GetComponent<HeadmanVoiceLinePlayer>() == (Object)null)
			{
				val.gameObject.AddComponent<HeadmanVoiceLinePlayer>();
			}
		}
		catch (Exception ex)
		{
			HeadmanVoiceLinesPlugin.Log.LogError((object)("Error in patch: " + ex.Message));
		}
	}
}