Decompiled source of TrexPredator v0.1.3

BepInEx\plugins\MuckTrexMod.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyTitle("MuckTrexMod")]
[assembly: AssemblyDescription("Trex Predator for Muck")]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyCompany("DCMOD")]
[assembly: AssemblyProduct("TrexPredator")]
[assembly: AssemblyFileVersion("0.1.3.0")]
[assembly: AssemblyVersion("0.1.3.0")]
namespace MuckTrexMod;

public static class GameReflection
{
	private static readonly string[] PlayerComponentHints = new string[5] { "PlayerMovement", "PlayerStatus", "PlayerInventory", "OnlinePlayerMovement", "LocalClient" };

	private static readonly string[] DamageMethodNames = new string[7] { "Damage", "Hurt", "TakeDamage", "DamagePlayer", "Hit", "RpcDamage", "ServerDamage" };

	private static readonly string[] GoldMethodNames = new string[7] { "AddGold", "AddCoins", "AddCoin", "AddMoney", "AddCurrency", "GiveGold", "GiveMoney" };

	private static readonly string[] GoldMemberNames = new string[5] { "gold", "coins", "coin", "money", "cash" };

	public static List<GameObject> GetPlayerObjects()
	{
		Dictionary<int, GameObject> dictionary = new Dictionary<int, GameObject>();
		TryAddTaggedPlayers(dictionary);
		TryAddPlayersByComponents(dictionary);
		List<GameObject> list = new List<GameObject>();
		foreach (GameObject value in dictionary.Values)
		{
			if (value != null && value.activeInHierarchy && !((Object)value).name.ToLowerInvariant().Contains("trex"))
			{
				list.Add(value);
			}
		}
		return list;
	}

	public static GameObject TryGetLocalPlayerObject()
	{
		Camera main = Camera.main;
		if (main != null)
		{
			GameObject val = FindPlayerRoot(((Component)main).gameObject);
			if (val != null)
			{
				return val;
			}
		}
		List<GameObject> playerObjects = GetPlayerObjects();
		if (playerObjects.Count <= 0)
		{
			return null;
		}
		return playerObjects[0];
	}

	public static GameObject FindPlayerRoot(GameObject source)
	{
		if (source == null)
		{
			return null;
		}
		for (Transform val = source.transform; val != null; val = val.parent)
		{
			if (LooksLikePlayer(((Component)val).gameObject))
			{
				return ((Component)val).gameObject;
			}
		}
		Transform root = source.transform.root;
		if (root != null && LooksLikePlayer(((Component)root).gameObject))
		{
			return ((Component)root).gameObject;
		}
		return null;
	}

	public static bool LooksLikePlayer(GameObject gameObject)
	{
		if (gameObject == null || !gameObject.activeInHierarchy)
		{
			return false;
		}
		try
		{
			if (gameObject.CompareTag("Player"))
			{
				return true;
			}
		}
		catch
		{
		}
		Component[] components = gameObject.GetComponents<Component>();
		for (int i = 0; i < components.Length; i++)
		{
			if (components[i] == null)
			{
				continue;
			}
			string name = ((object)components[i]).GetType().Name;
			for (int j = 0; j < PlayerComponentHints.Length; j++)
			{
				if (name.IndexOf(PlayerComponentHints[j], StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
		}
		return false;
	}

	public static bool TryDamagePlayer(GameObject player, float amount, Vector3 sourcePosition)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		if (player == null)
		{
			return false;
		}
		List<Component> list = CollectComponents(player);
		for (int i = 0; i < list.Count; i++)
		{
			Component val = list[i];
			if (val == null)
			{
				continue;
			}
			Type type = ((object)val).GetType();
			for (int j = 0; j < DamageMethodNames.Length; j++)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (string.Equals(methodInfo.Name, DamageMethodNames[j], StringComparison.OrdinalIgnoreCase) && TryBuildDamageArgs(methodInfo.GetParameters(), amount, sourcePosition, out var args))
					{
						try
						{
							methodInfo.Invoke(val, args);
							return true;
						}
						catch
						{
						}
					}
				}
			}
		}
		return TrySubtractHealth(player, amount);
	}

	public static bool TryGiveGold(GameObject player, int amount)
	{
		if (amount <= 0)
		{
			return true;
		}
		if (player != null && TryGiveGoldToComponents(CollectComponents(player), amount))
		{
			return true;
		}
		List<Component> components = CollectGlobalInventoryComponents();
		if (TryGiveGoldToComponents(components, amount))
		{
			return true;
		}
		return false;
	}

	public static bool TryDisablePlayerControl(GameObject player, bool disabled)
	{
		if (player == null)
		{
			return false;
		}
		bool result = false;
		List<Component> list = CollectComponents(player);
		for (int i = 0; i < list.Count; i++)
		{
			Component obj = list[i];
			Behaviour val = (Behaviour)(object)((obj is Behaviour) ? obj : null);
			if (val != null)
			{
				string name = ((object)val).GetType().Name;
				if (name.IndexOf("PlayerMovement", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("PlayerController", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					val.enabled = !disabled;
					result = true;
				}
			}
		}
		return result;
	}

	public static void TryApplyKnockback(GameObject player, Vector3 impulse)
	{
		//IL_0019: 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_003a: Unknown result type (might be due to invalid IL or missing references)
		if (player == null)
		{
			return;
		}
		Rigidbody val = player.GetComponent<Rigidbody>();
		if (val == null)
		{
			val = player.GetComponentInChildren<Rigidbody>();
		}
		if (val != null)
		{
			val.AddForce(impulse, (ForceMode)0);
			return;
		}
		CharacterController component = player.GetComponent<CharacterController>();
		if (component != null && ((Collider)component).enabled)
		{
			component.Move(impulse * Time.deltaTime);
		}
	}

	public static bool TryGetCurrentDay(out int day)
	{
		day = 0;
		MonoBehaviour[] array = Resources.FindObjectsOfTypeAll<MonoBehaviour>();
		foreach (MonoBehaviour val in array)
		{
			if (val != null && ((Component)val).gameObject != null && ((Scene)(ref ((Component)val).gameObject.scene)).IsValid())
			{
				Type type = ((object)val).GetType();
				string name = type.Name;
				if ((name.IndexOf("Day", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Game", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Time", StringComparison.OrdinalIgnoreCase) >= 0) && TryReadDayMember(type, val, out var day2))
				{
					day = day2;
					return true;
				}
			}
		}
		return false;
	}

	private static void TryAddTaggedPlayers(Dictionary<int, GameObject> results)
	{
		try
		{
			GameObject[] array = GameObject.FindGameObjectsWithTag("Player");
			for (int i = 0; i < array.Length; i++)
			{
				AddUnique(results, array[i]);
			}
		}
		catch
		{
		}
	}

	private static void TryAddPlayersByComponents(Dictionary<int, GameObject> results)
	{
		MonoBehaviour[] array = Resources.FindObjectsOfTypeAll<MonoBehaviour>();
		foreach (MonoBehaviour val in array)
		{
			if (val == null || ((Component)val).gameObject == null || !((Scene)(ref ((Component)val).gameObject.scene)).IsValid())
			{
				continue;
			}
			string name = ((object)val).GetType().Name;
			for (int j = 0; j < PlayerComponentHints.Length; j++)
			{
				if (name.IndexOf(PlayerComponentHints[j], StringComparison.OrdinalIgnoreCase) >= 0)
				{
					AddUnique(results, ((Component)val).gameObject);
					break;
				}
			}
		}
	}

	private static void AddUnique(Dictionary<int, GameObject> results, GameObject gameObject)
	{
		if (gameObject != null)
		{
			GameObject val = FindPlayerRoot(gameObject);
			if (val == null)
			{
				val = gameObject;
			}
			int instanceID = ((Object)val).GetInstanceID();
			if (!results.ContainsKey(instanceID))
			{
				results.Add(instanceID, val);
			}
		}
	}

	private static List<Component> CollectComponents(GameObject gameObject)
	{
		List<Component> list = new List<Component>();
		if (gameObject == null)
		{
			return list;
		}
		list.AddRange(gameObject.GetComponents<Component>());
		list.AddRange(gameObject.GetComponentsInChildren<Component>(true));
		list.AddRange(gameObject.GetComponentsInParent<Component>(true));
		return list;
	}

	private static List<Component> CollectGlobalInventoryComponents()
	{
		List<Component> list = new List<Component>();
		MonoBehaviour[] array = Resources.FindObjectsOfTypeAll<MonoBehaviour>();
		foreach (MonoBehaviour val in array)
		{
			if (val != null && ((Component)val).gameObject != null && ((Scene)(ref ((Component)val).gameObject.scene)).IsValid())
			{
				string name = ((object)val).GetType().Name;
				if (name.IndexOf("Inventory", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Money", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Gold", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Coin", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					list.Add((Component)(object)val);
				}
			}
		}
		return list;
	}

	private static bool TryBuildDamageArgs(ParameterInfo[] parameters, float amount, Vector3 sourcePosition, out object[] args)
	{
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		args = null;
		if (parameters.Length > 5)
		{
			return false;
		}
		args = new object[parameters.Length];
		for (int i = 0; i < parameters.Length; i++)
		{
			Type parameterType = parameters[i].ParameterType;
			if (parameterType == typeof(int))
			{
				args[i] = Mathf.RoundToInt(amount);
				continue;
			}
			if (parameterType == typeof(float))
			{
				args[i] = amount;
				continue;
			}
			if (parameterType == typeof(double))
			{
				args[i] = (double)amount;
				continue;
			}
			if (parameterType == typeof(Vector3))
			{
				args[i] = sourcePosition;
				continue;
			}
			if (parameterType == typeof(bool))
			{
				args[i] = false;
				continue;
			}
			if (parameterType == typeof(string))
			{
				args[i] = "Trex";
				continue;
			}
			if (typeof(Object).IsAssignableFrom(parameterType))
			{
				args[i] = null;
				continue;
			}
			return false;
		}
		return true;
	}

	private static bool TrySubtractHealth(GameObject player, float amount)
	{
		List<Component> list = CollectComponents(player);
		for (int i = 0; i < list.Count; i++)
		{
			Component val = list[i];
			if (val != null)
			{
				Type type = ((object)val).GetType();
				if (TrySubtractHealthMember(type, val, "hp", amount) || TrySubtractHealthMember(type, val, "health", amount) || TrySubtractHealthMember(type, val, "currentHealth", amount))
				{
					return true;
				}
			}
		}
		return false;
	}

	private static bool TrySubtractHealthMember(Type type, object instance, string memberName, float amount)
	{
		FieldInfo field = type.GetField(memberName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (field != null)
		{
			try
			{
				if (field.FieldType == typeof(int))
				{
					field.SetValue(instance, Math.Max(0, (int)field.GetValue(instance) - Mathf.RoundToInt(amount)));
					return true;
				}
				if (field.FieldType == typeof(float))
				{
					field.SetValue(instance, Mathf.Max(0f, (float)field.GetValue(instance) - amount));
					return true;
				}
			}
			catch
			{
			}
		}
		PropertyInfo property = type.GetProperty(memberName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		if (property != null && property.CanRead && property.CanWrite)
		{
			try
			{
				if (property.PropertyType == typeof(int))
				{
					property.SetValue(instance, Math.Max(0, (int)property.GetValue(instance, null) - Mathf.RoundToInt(amount)), null);
					return true;
				}
				if (property.PropertyType == typeof(float))
				{
					property.SetValue(instance, Mathf.Max(0f, (float)property.GetValue(instance, null) - amount), null);
					return true;
				}
			}
			catch
			{
			}
		}
		return false;
	}

	private static bool TryGiveGoldToComponents(List<Component> components, int amount)
	{
		for (int i = 0; i < components.Count; i++)
		{
			Component val = components[i];
			if (val != null && (TryInvokeGoldMethod(val, amount) || TryAddGoldMember(val, amount)))
			{
				return true;
			}
		}
		return false;
	}

	private static bool TryInvokeGoldMethod(Component component, int amount)
	{
		Type type = ((object)component).GetType();
		MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (MethodInfo methodInfo in methods)
		{
			bool flag = false;
			for (int j = 0; j < GoldMethodNames.Length; j++)
			{
				if (string.Equals(methodInfo.Name, GoldMethodNames[j], StringComparison.OrdinalIgnoreCase))
				{
					flag = true;
					break;
				}
			}
			if (!flag)
			{
				continue;
			}
			ParameterInfo[] parameters = methodInfo.GetParameters();
			if (parameters.Length == 1 && TryConvertInt(amount, parameters[0].ParameterType, out var value))
			{
				try
				{
					methodInfo.Invoke(component, new object[1] { value });
					return true;
				}
				catch
				{
				}
			}
		}
		return false;
	}

	private static bool TryAddGoldMember(Component component, int amount)
	{
		Type type = ((object)component).GetType();
		for (int i = 0; i < GoldMemberNames.Length; i++)
		{
			string name = GoldMemberNames[i];
			FieldInfo field = type.GetField(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				try
				{
					if (field.FieldType == typeof(int))
					{
						field.SetValue(component, (int)field.GetValue(component) + amount);
						return true;
					}
					if (field.FieldType == typeof(float))
					{
						field.SetValue(component, (float)field.GetValue(component) + (float)amount);
						return true;
					}
				}
				catch
				{
				}
			}
			PropertyInfo property = type.GetProperty(name, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(property != null) || !property.CanRead || !property.CanWrite)
			{
				continue;
			}
			try
			{
				if (property.PropertyType == typeof(int))
				{
					property.SetValue(component, (int)property.GetValue(component, null) + amount, null);
					return true;
				}
				if (property.PropertyType == typeof(float))
				{
					property.SetValue(component, (float)property.GetValue(component, null) + (float)amount, null);
					return true;
				}
			}
			catch
			{
			}
		}
		return false;
	}

	private static bool TryConvertInt(int amount, Type type, out object value)
	{
		value = null;
		if (type == typeof(int))
		{
			value = amount;
			return true;
		}
		if (type == typeof(float))
		{
			value = (float)amount;
			return true;
		}
		if (type == typeof(double))
		{
			value = (double)amount;
			return true;
		}
		return false;
	}

	private static bool TryReadDayMember(Type type, object instance, out int day)
	{
		day = 0;
		FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (FieldInfo fieldInfo in fields)
		{
			if (!LooksLikeDayName(fieldInfo.Name) || fieldInfo.FieldType != typeof(int))
			{
				continue;
			}
			try
			{
				int num = (int)fieldInfo.GetValue(fieldInfo.IsStatic ? null : instance);
				if (num >= 0 && num < 10000)
				{
					day = num;
					return true;
				}
			}
			catch
			{
			}
		}
		PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (PropertyInfo propertyInfo in properties)
		{
			if (!LooksLikeDayName(propertyInfo.Name) || propertyInfo.PropertyType != typeof(int) || !propertyInfo.CanRead)
			{
				continue;
			}
			try
			{
				MethodInfo getMethod = propertyInfo.GetGetMethod(nonPublic: true);
				int num2 = (int)propertyInfo.GetValue((getMethod != null && getMethod.IsStatic) ? null : instance, null);
				if (num2 >= 0 && num2 < 10000)
				{
					day = num2;
					return true;
				}
			}
			catch
			{
			}
		}
		return false;
	}

	private static bool LooksLikeDayName(string name)
	{
		if (string.IsNullOrEmpty(name))
		{
			return false;
		}
		string text = name.ToLowerInvariant();
		switch (text)
		{
		default:
			return text.IndexOf("currentday") >= 0;
		case "day":
		case "days":
		case "currentday":
		case "daycount":
		case "currentdaynumber":
			return true;
		}
	}
}
public static class RuntimeObjLoader
{
	private sealed class ObjMaterial
	{
		public string Name;

		public string DiffuseTexture;

		public Color Color = Color.white;

		public float Alpha = 1f;
	}

	private sealed class MeshBuilder
	{
		public string Name;

		public string MaterialName;

		public readonly List<Vector3> Vertices = new List<Vector3>();

		public readonly List<Vector3> Normals = new List<Vector3>();

		public readonly List<Vector2> Uvs = new List<Vector2>();

		public readonly List<int> Indices = new List<int>();

		public readonly Dictionary<string, int> VertexMap = new Dictionary<string, int>();
	}

	public static GameObject Load(string objPath, Transform parent)
	{
		//IL_030b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0312: Expected O, but got Unknown
		//IL_0365: Unknown result type (might be due to invalid IL or missing references)
		//IL_036c: Expected O, but got Unknown
		//IL_0380: Unknown result type (might be due to invalid IL or missing references)
		//IL_0387: Expected O, but got Unknown
		//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		string directoryName = Path.GetDirectoryName(objPath);
		Dictionary<string, ObjMaterial> dictionary = new Dictionary<string, ObjMaterial>(StringComparer.OrdinalIgnoreCase);
		List<Vector3> list = new List<Vector3>();
		List<Vector3> list2 = new List<Vector3>();
		List<Vector2> list3 = new List<Vector2>();
		List<MeshBuilder> list4 = new List<MeshBuilder>();
		MeshBuilder meshBuilder = null;
		string text = "TrexMesh";
		string text2 = "default";
		string[] array = File.ReadAllLines(objPath);
		for (int i = 0; i < array.Length; i++)
		{
			string text3 = array[i].Trim();
			if (text3.Length == 0 || text3.StartsWith("#", StringComparison.Ordinal))
			{
				continue;
			}
			if (text3.StartsWith("mtllib ", StringComparison.Ordinal))
			{
				string path = text3.Substring(7).Trim();
				string text4 = Path.Combine(directoryName, path);
				if (File.Exists(text4))
				{
					LoadMaterials(text4, dictionary);
				}
			}
			else if (text3.StartsWith("o ", StringComparison.Ordinal) || text3.StartsWith("g ", StringComparison.Ordinal))
			{
				text = SanitizeName(text3.Substring(2).Trim());
				meshBuilder = null;
			}
			else if (text3.StartsWith("usemtl ", StringComparison.Ordinal))
			{
				text2 = text3.Substring(7).Trim();
				meshBuilder = null;
			}
			else if (text3.StartsWith("v ", StringComparison.Ordinal))
			{
				string[] array2 = SplitParts(text3);
				if (array2.Length >= 4)
				{
					float num = ParseFloat(array2[1]);
					float num2 = ParseFloat(array2[2]);
					float num3 = ParseFloat(array2[3]);
					list.Add(new Vector3(num, num3, num2));
				}
			}
			else if (text3.StartsWith("vn ", StringComparison.Ordinal))
			{
				string[] array3 = SplitParts(text3);
				if (array3.Length >= 4)
				{
					float num4 = ParseFloat(array3[1]);
					float num5 = ParseFloat(array3[2]);
					float num6 = ParseFloat(array3[3]);
					Vector3 val = new Vector3(num4, num6, num5);
					list2.Add(((Vector3)(ref val)).normalized);
				}
			}
			else if (text3.StartsWith("vt ", StringComparison.Ordinal))
			{
				string[] array4 = SplitParts(text3);
				if (array4.Length >= 3)
				{
					list3.Add(new Vector2(ParseFloat(array4[1]), ParseFloat(array4[2])));
				}
			}
			else
			{
				if (!text3.StartsWith("f ", StringComparison.Ordinal))
				{
					continue;
				}
				if (meshBuilder == null)
				{
					meshBuilder = new MeshBuilder();
					meshBuilder.Name = text + "_" + SanitizeName(text2);
					meshBuilder.MaterialName = text2;
					list4.Add(meshBuilder);
				}
				string[] array5 = SplitParts(text3);
				if (array5.Length >= 4)
				{
					int[] array6 = new int[array5.Length - 1];
					for (int j = 1; j < array5.Length; j++)
					{
						array6[j - 1] = AddFaceVertex(meshBuilder, array5[j], list, list2, list3);
					}
					for (int k = 1; k < array6.Length - 1; k++)
					{
						meshBuilder.Indices.Add(array6[0]);
						meshBuilder.Indices.Add(array6[k]);
						meshBuilder.Indices.Add(array6[k + 1]);
					}
				}
			}
		}
		GameObject val2 = new GameObject(Path.GetFileNameWithoutExtension(objPath));
		val2.transform.SetParent(parent, false);
		Dictionary<string, Material> dictionary2 = CreateUnityMaterials(directoryName, dictionary);
		for (int l = 0; l < list4.Count; l++)
		{
			MeshBuilder meshBuilder2 = list4[l];
			if (meshBuilder2.Vertices.Count != 0 && meshBuilder2.Indices.Count != 0)
			{
				GameObject val3 = new GameObject(meshBuilder2.Name);
				val3.transform.SetParent(val2.transform, false);
				Mesh val4 = new Mesh();
				((Object)val4).name = meshBuilder2.Name;
				if (meshBuilder2.Vertices.Count > 65000)
				{
					val4.indexFormat = (IndexFormat)1;
				}
				val4.SetVertices(meshBuilder2.Vertices);
				val4.SetTriangles(meshBuilder2.Indices, 0);
				if (meshBuilder2.Uvs.Count == meshBuilder2.Vertices.Count)
				{
					val4.SetUVs(0, meshBuilder2.Uvs);
				}
				if (meshBuilder2.Normals.Count == meshBuilder2.Vertices.Count)
				{
					val4.SetNormals(meshBuilder2.Normals);
				}
				else
				{
					val4.RecalculateNormals();
				}
				val4.RecalculateBounds();
				MeshFilter val5 = val3.AddComponent<MeshFilter>();
				val5.sharedMesh = val4;
				MeshRenderer val6 = val3.AddComponent<MeshRenderer>();
				if (!dictionary2.TryGetValue(meshBuilder2.MaterialName, out var value))
				{
					value = GetDefaultMaterial();
				}
				((Renderer)val6).sharedMaterial = value;
			}
		}
		return val2;
	}

	private static int AddFaceVertex(MeshBuilder builder, string token, List<Vector3> sourceVertices, List<Vector3> sourceNormals, List<Vector2> sourceUvs)
	{
		//IL_0086: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		if (builder.VertexMap.TryGetValue(token, out var value))
		{
			return value;
		}
		string[] array = token.Split(new char[1] { '/' });
		int num = ResolveIndex((array.Length > 0) ? array[0] : null, sourceVertices.Count);
		int num2 = ResolveIndex((array.Length > 1) ? array[1] : null, sourceUvs.Count);
		int num3 = ResolveIndex((array.Length > 2) ? array[2] : null, sourceNormals.Count);
		builder.Vertices.Add((num >= 0) ? sourceVertices[num] : Vector3.zero);
		builder.Uvs.Add((num2 >= 0) ? sourceUvs[num2] : Vector2.zero);
		builder.Normals.Add((num3 >= 0) ? sourceNormals[num3] : Vector3.up);
		int num4 = builder.Vertices.Count - 1;
		builder.VertexMap[token] = num4;
		return num4;
	}

	private static int ResolveIndex(string raw, int count)
	{
		if (string.IsNullOrEmpty(raw))
		{
			return -1;
		}
		if (!int.TryParse(raw, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result))
		{
			return -1;
		}
		if (result > 0)
		{
			return result - 1;
		}
		if (result < 0)
		{
			return count + result;
		}
		return -1;
	}

	private static void LoadMaterials(string mtlPath, Dictionary<string, ObjMaterial> materials)
	{
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		string directoryName = Path.GetDirectoryName(mtlPath);
		ObjMaterial objMaterial = null;
		string[] array = File.ReadAllLines(mtlPath);
		for (int i = 0; i < array.Length; i++)
		{
			string text = array[i].Trim();
			if (text.Length == 0 || text.StartsWith("#", StringComparison.Ordinal))
			{
				continue;
			}
			if (text.StartsWith("newmtl ", StringComparison.Ordinal))
			{
				objMaterial = new ObjMaterial();
				objMaterial.Name = text.Substring(7).Trim();
				materials[objMaterial.Name] = objMaterial;
			}
			else
			{
				if (objMaterial == null)
				{
					continue;
				}
				if (text.StartsWith("Kd ", StringComparison.Ordinal))
				{
					string[] array2 = SplitParts(text);
					if (array2.Length >= 4)
					{
						objMaterial.Color = new Color(ParseFloat(array2[1]), ParseFloat(array2[2]), ParseFloat(array2[3]), objMaterial.Alpha);
					}
				}
				else if (text.StartsWith("d ", StringComparison.Ordinal))
				{
					string[] array3 = SplitParts(text);
					if (array3.Length >= 2)
					{
						objMaterial.Alpha = Mathf.Clamp01(ParseFloat(array3[1]));
						objMaterial.Color.a = objMaterial.Alpha;
					}
				}
				else if (text.StartsWith("map_Kd ", StringComparison.Ordinal))
				{
					string text2 = ExtractTexturePath(text.Substring(7).Trim());
					objMaterial.DiffuseTexture = Path.GetFullPath(Path.Combine(directoryName, text2.Replace('/', Path.DirectorySeparatorChar)));
				}
			}
		}
	}

	private static Dictionary<string, Material> CreateUnityMaterials(string objRootDir, Dictionary<string, ObjMaterial> sourceMaterials)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Expected O, but got Unknown
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Expected O, but got Unknown
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		Dictionary<string, Material> dictionary = new Dictionary<string, Material>(StringComparer.OrdinalIgnoreCase);
		foreach (KeyValuePair<string, ObjMaterial> sourceMaterial in sourceMaterials)
		{
			ObjMaterial value = sourceMaterial.Value;
			Material val = new Material((Shader.Find("Standard") != null) ? Shader.Find("Standard") : Shader.Find("Diffuse"));
			((Object)val).name = value.Name;
			val.color = value.Color;
			if (!string.IsNullOrEmpty(value.DiffuseTexture) && File.Exists(value.DiffuseTexture))
			{
				Texture2D val2 = new Texture2D(2, 2, (TextureFormat)0, true);
				((Object)val2).name = Path.GetFileNameWithoutExtension(value.DiffuseTexture);
				val2.LoadImage(File.ReadAllBytes(value.DiffuseTexture));
				val2.wrapMode = (TextureWrapMode)0;
				val.mainTexture = (Texture)(object)val2;
			}
			if (value.Alpha < 0.99f)
			{
				val.SetFloat("_Mode", 3f);
				val.SetInt("_SrcBlend", 0);
				val.SetInt("_DstBlend", 1);
				val.SetInt("_ZWrite", 0);
				val.DisableKeyword("_ALPHATEST_ON");
				val.EnableKeyword("_ALPHABLEND_ON");
				val.DisableKeyword("_ALPHAPREMULTIPLY_ON");
				val.renderQueue = 3000;
			}
			dictionary[sourceMaterial.Key] = val;
		}
		if (!dictionary.ContainsKey("default"))
		{
			dictionary["default"] = GetDefaultMaterial();
		}
		return dictionary;
	}

	private static Material GetDefaultMaterial()
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		Material val = new Material((Shader.Find("Standard") != null) ? Shader.Find("Standard") : Shader.Find("Diffuse"));
		val.color = new Color(0.32f, 0.22f, 0.13f);
		return val;
	}

	private static string ExtractTexturePath(string raw)
	{
		if (raw.IndexOf(" -", StringComparison.Ordinal) >= 0)
		{
			string[] array = raw.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			for (int num = array.Length - 1; num >= 0; num--)
			{
				if (!array[num].StartsWith("-", StringComparison.Ordinal))
				{
					return array[num];
				}
			}
		}
		return raw.Trim(new char[1] { '"' });
	}

	private static string SanitizeName(string name)
	{
		if (string.IsNullOrEmpty(name))
		{
			return "Mesh";
		}
		char[] array = name.ToCharArray();
		for (int i = 0; i < array.Length; i++)
		{
			if (!char.IsLetterOrDigit(array[i]) && array[i] != '_' && array[i] != '-')
			{
				array[i] = '_';
			}
		}
		return new string(array);
	}

	private static string[] SplitParts(string line)
	{
		return line.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
	}

	private static float ParseFloat(string value)
	{
		return float.Parse(value, CultureInfo.InvariantCulture);
	}
}
public sealed class TrexDamageBridge : MonoBehaviour
{
	private TrexEnemy enemy;

	private TrexSettings settings;

	private readonly Dictionary<int, float> recentContacts = new Dictionary<int, float>();

	public void Initialize(TrexEnemy owner, TrexSettings config)
	{
		enemy = owner;
		settings = config;
	}

	private void Update()
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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 (enemy == null || enemy.IsDead || settings == null || !Input.GetMouseButtonDown(0))
		{
			return;
		}
		Camera main = Camera.main;
		if (main != null)
		{
			Ray val = main.ScreenPointToRay(Input.mousePosition);
			RaycastHit val2 = default(RaycastHit);
			if (Physics.Raycast(val, ref val2, 11f) && val2.collider != null && (((Component)val2.collider).transform == ((Component)this).transform || ((Component)val2.collider).transform.IsChildOf(((Component)this).transform)))
			{
				GameObject attacker = GameReflection.TryGetLocalPlayerObject();
				enemy.TakeDamage(settings.ClickHitDamage.Value, attacker);
			}
		}
	}

	private void OnCollisionEnter(Collision collision)
	{
		HandleContact(collision.collider);
	}

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

	public void Damage(float amount)
	{
		enemy.TakeDamage(amount, null);
	}

	public void Damage(int amount)
	{
		enemy.TakeDamage(amount, null);
	}

	public void Hurt(float amount)
	{
		enemy.TakeDamage(amount, null);
	}

	public void Hurt(int amount)
	{
		enemy.TakeDamage(amount, null);
	}

	public void Hit(float amount)
	{
		enemy.TakeDamage(amount, null);
	}

	public void Hit(int amount)
	{
		enemy.TakeDamage(amount, null);
	}

	public void TakeDamage(float amount)
	{
		enemy.TakeDamage(amount, null);
	}

	public void TakeDamage(int amount)
	{
		enemy.TakeDamage(amount, null);
	}

	private void HandleContact(Collider other)
	{
		if (other == null || enemy == null || enemy.IsDead)
		{
			return;
		}
		GameObject gameObject = ((Component)other).gameObject;
		if (gameObject == null || gameObject.transform.IsChildOf(((Component)this).transform))
		{
			return;
		}
		string text = ((Object)gameObject).name.ToLowerInvariant();
		if (text.IndexOf("sword") >= 0 || text.IndexOf("axe") >= 0 || text.IndexOf("pickaxe") >= 0 || text.IndexOf("arrow") >= 0 || text.IndexOf("projectile") >= 0 || text.IndexOf("bullet") >= 0 || text.IndexOf("rock") >= 0)
		{
			int instanceID = other.GetInstanceID();
			if (!recentContacts.TryGetValue(instanceID, out var value) || !(Time.time - value < 0.35f))
			{
				recentContacts[instanceID] = Time.time;
				enemy.TakeDamage(settings.ClickHitDamage.Value, gameObject);
			}
		}
	}
}
public static class TrexEffects
{
	public static ParticleSystem CreateBloodParticles(Transform parent)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: 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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Expected O, but got Unknown
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Trex Chew Blood");
		val.transform.SetParent(parent, false);
		val.transform.localPosition = Vector3.zero;
		ParticleSystem val2 = val.AddComponent<ParticleSystem>();
		_ = val2.main;
		new Color(0.55f, 0f, 0f, 0.95f);
		_ = val2.emission;
		_ = val2.shape;
		_ = val2.velocityOverLifetime;
		new MinMaxCurve(1.2f, 3.6f);
		new MinMaxCurve(-2.2f, 0.4f);
		ParticleSystemRenderer component = val.GetComponent<ParticleSystemRenderer>();
		if (component != null)
		{
			Shader val3 = Shader.Find("Particles/Standard Unlit");
			if (val3 == null)
			{
				val3 = Shader.Find("Legacy Shaders/Particles/Alpha Blended");
			}
			if (val3 != null)
			{
				Material val4 = new Material(val3);
				val4.color = new Color(0.55f, 0f, 0f, 0.9f);
				((Renderer)component).material = val4;
			}
		}
		return val2;
	}
}
public sealed class TrexEnemy : MonoBehaviour
{
	private TrexPlugin plugin;

	private TrexSettings settings;

	private NavMeshAgent agent;

	private GameObject target;

	private GameObject lastDamager;

	private TrexProceduralAnimator proceduralAnimator;

	private ParticleSystem bloodParticles;

	private Transform mouthAnchor;

	private Vector3 roamDestination;

	private float nextRoamPickTime;

	private float nextTargetScanTime;

	private float nextAttackTime;

	private float currentHp;

	private bool chewing;

	private bool dead;

	public bool IsDead => dead;

	public void Initialize(TrexPlugin owner, TrexSettings config, NavMeshAgent navAgent)
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		plugin = owner;
		settings = config;
		agent = navAgent;
		currentHp = settings.MaxHp.Value;
		GameObject val = TrexModelFactory.CreateModel(plugin, settings, ((Component)this).transform, out mouthAnchor, out proceduralAnimator);
		if (val != null)
		{
			((Object)val).name = "Trex Visual";
		}
		if (mouthAnchor == null)
		{
			mouthAnchor = new GameObject("Trex Mouth Anchor").transform;
			mouthAnchor.SetParent(((Component)this).transform, false);
			mouthAnchor.localPosition = new Vector3(0f, 3.8f, 3.5f);
		}
		bloodParticles = TrexEffects.CreateBloodParticles(mouthAnchor);
		TrexDamageBridge trexDamageBridge = ((Component)this).gameObject.AddComponent<TrexDamageBridge>();
		trexDamageBridge.Initialize(this, settings);
		PickNewRoamDestination();
	}

	private void Update()
	{
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: 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_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: 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)
		if (dead)
		{
			return;
		}
		if (chewing)
		{
			UpdateAnimation(0f, chasing: true, isChewing: true);
			return;
		}
		if (Time.time >= nextTargetScanTime)
		{
			nextTargetScanTime = Time.time + 0.8f;
			target = FindClosestPlayer(settings.AggroRange.Value);
		}
		if (target != null)
		{
			float num = Vector3.Distance(((Component)this).transform.position, target.transform.position);
			if (num <= settings.EatRange.Value && Time.time >= nextAttackTime)
			{
				((MonoBehaviour)this).StartCoroutine(ChewAndSpit(target));
				return;
			}
			MoveToward(target.transform.position, settings.ChaseSpeed.Value);
			FaceToward(target.transform.position);
			UpdateAnimation(1f, chasing: true, isChewing: false);
		}
		else
		{
			if (Time.time >= nextRoamPickTime || Vector3.Distance(((Component)this).transform.position, roamDestination) < 4f)
			{
				PickNewRoamDestination();
			}
			MoveToward(roamDestination, settings.WalkSpeed.Value);
			FaceToward(roamDestination);
			UpdateAnimation(0.45f, chasing: false, isChewing: false);
		}
	}

	public void TakeDamage(float amount, GameObject attacker)
	{
		if (!dead && !(amount <= 0f))
		{
			lastDamager = attacker;
			currentHp -= amount;
			if (proceduralAnimator != null)
			{
				proceduralAnimator.FlashHit();
			}
			if (currentHp <= 0f)
			{
				Die();
			}
		}
	}

	public void Damage(float amount)
	{
		TakeDamage(amount, null);
	}

	public void Damage(int amount)
	{
		TakeDamage(amount, null);
	}

	public void Hurt(float amount)
	{
		TakeDamage(amount, null);
	}

	public void Hurt(int amount)
	{
		TakeDamage(amount, null);
	}

	public void Hit(float amount)
	{
		TakeDamage(amount, null);
	}

	public void Hit(int amount)
	{
		TakeDamage(amount, null);
	}

	public void TakeDamage(int amount)
	{
		TakeDamage(amount, null);
	}

	private void Die()
	{
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		dead = true;
		((MonoBehaviour)this).StopAllCoroutines();
		if (agent != null)
		{
			((Behaviour)agent).enabled = false;
		}
		Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>();
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			componentsInChildren[i].enabled = false;
		}
		if (proceduralAnimator != null)
		{
			proceduralAnimator.PlayDeath();
		}
		GameObject val = GameReflection.FindPlayerRoot(lastDamager);
		if (val == null)
		{
			val = GameReflection.TryGetLocalPlayerObject();
		}
		if (!GameReflection.TryGiveGold(val, settings.KillGoldReward.Value))
		{
			TrexGoldPickup.Spawn(((Component)this).transform.position + Vector3.up * 0.5f, settings.KillGoldReward.Value);
		}
		MonoBehaviour.Destroy((Object)(object)((Component)this).gameObject, 12f);
	}

	private IEnumerator ChewAndSpit(GameObject victim)
	{
		if (victim == null)
		{
			yield break;
		}
		chewing = true;
		nextAttackTime = Time.time + settings.AttackCooldown.Value;
		target = null;
		if (agent != null)
		{
			try
			{
				agent.ResetPath();
			}
			catch
			{
			}
		}
		GameReflection.TryDisablePlayerControl(victim, disabled: true);
		float endTime = Time.time + Mathf.Max(0.2f, settings.ChewDuration.Value);
		float nextDamageTick = 0f;
		while (Time.time < endTime && victim != null && !dead)
		{
			FaceToward(victim.transform.position);
			if (settings.HoldVictimDuringChew.Value)
			{
				Vector3 val = mouthAnchor.position - ((Component)this).transform.forward * 0.65f;
				victim.transform.position = Vector3.Lerp(victim.transform.position, val, Time.deltaTime * 12f);
			}
			if (Time.time >= nextDamageTick)
			{
				nextDamageTick = Time.time + Mathf.Max(0.1f, settings.ChewDamageTickSeconds.Value);
				GameReflection.TryDamagePlayer(victim, settings.Damage.Value, mouthAnchor.position);
				if (bloodParticles != null)
				{
					bloodParticles.Emit(28);
				}
			}
			if (proceduralAnimator != null)
			{
				proceduralAnimator.ChewPulse();
			}
			yield return null;
		}
		if (victim != null)
		{
			GameReflection.TryDisablePlayerControl(victim, disabled: false);
			GameReflection.TryApplyKnockback(victim, ((Component)this).transform.forward * 18f + Vector3.up * 6f);
		}
		chewing = false;
	}

	private GameObject FindClosestPlayer(float range)
	{
		//IL_0021: 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)
		List<GameObject> playerObjects = GameReflection.GetPlayerObjects();
		GameObject result = null;
		float num = range;
		for (int i = 0; i < playerObjects.Count; i++)
		{
			GameObject val = playerObjects[i];
			if (val != null)
			{
				float num2 = Vector3.Distance(((Component)this).transform.position, val.transform.position);
				if (num2 < num)
				{
					result = val;
					num = num2;
				}
			}
		}
		return result;
	}

	private void PickNewRoamDestination()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0028: 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_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: 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_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		Vector2 insideUnitCircle = Random.insideUnitCircle;
		Vector2 val = ((Vector2)(ref insideUnitCircle)).normalized;
		if (((Vector2)(ref val)).sqrMagnitude < 0.1f)
		{
			val = Vector2.right;
		}
		Vector3 source = ((Component)this).transform.position + new Vector3(val.x, 0f, val.y) * Random.Range(18f, settings.RoamRadius.Value);
		source.y += 80f;
		if (TrexWorldManager.TryGroundPosition(source, out var position))
		{
			roamDestination = position;
		}
		else
		{
			roamDestination = ((Component)this).transform.position + ((Component)this).transform.forward * 20f;
		}
		nextRoamPickTime = Time.time + Random.Range(7f, 16f);
	}

	private void MoveToward(Vector3 destination, float speed)
	{
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		if (agent != null && ((Behaviour)agent).enabled)
		{
			try
			{
				agent.speed = speed;
				agent.SetDestination(destination);
				return;
			}
			catch
			{
			}
		}
		Vector3 val = destination - ((Component)this).transform.position;
		val.y = 0f;
		if (((Vector3)(ref val)).sqrMagnitude > 0.1f)
		{
			Transform transform = ((Component)this).transform;
			transform.position += ((Vector3)(ref val)).normalized * speed * Time.deltaTime;
		}
		if (TrexWorldManager.TryGroundPosition(((Component)this).transform.position + Vector3.up * 30f, out var position))
		{
			((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, position, Time.deltaTime * 8f);
		}
	}

	private void FaceToward(Vector3 destination)
	{
		//IL_0000: 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_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_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_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_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: 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)
		Vector3 val = destination - ((Component)this).transform.position;
		val.y = 0f;
		if (!(((Vector3)(ref val)).sqrMagnitude < 0.01f))
		{
			Quaternion val2 = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
			((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, val2, Time.deltaTime * 4.5f);
		}
	}

	private void UpdateAnimation(float speed, bool chasing, bool isChewing)
	{
		if (proceduralAnimator != null)
		{
			proceduralAnimator.SetState(speed, chasing, isChewing);
		}
	}
}
public sealed class TrexGoldPickup : MonoBehaviour
{
	private int amount;

	public static void Spawn(Vector3 position, int goldAmount)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected O, but got Unknown
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Trex Gold Reward " + goldAmount);
		val.transform.position = position;
		TrexGoldPickup trexGoldPickup = val.AddComponent<TrexGoldPickup>();
		trexGoldPickup.amount = goldAmount;
		SphereCollider val2 = val.AddComponent<SphereCollider>();
		((Collider)val2).isTrigger = true;
		val2.radius = 2.4f;
		Rigidbody val3 = val.AddComponent<Rigidbody>();
		val3.useGravity = false;
		val3.isKinematic = true;
		Material val4 = new Material((Shader.Find("Standard") != null) ? Shader.Find("Standard") : Shader.Find("Diffuse"));
		val4.color = new Color(1f, 0.73f, 0.12f);
		for (int i = 0; i < 8; i++)
		{
			GameObject val5 = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)val5).name = "Trex Gold Coin";
			val5.transform.SetParent(val.transform, false);
			float num = (float)Math.PI * 2f * (float)i / 8f;
			val5.transform.localPosition = new Vector3(Mathf.Cos(num) * 0.65f, 0.2f + (float)i * 0.035f, Mathf.Sin(num) * 0.65f);
			val5.transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
			val5.transform.localScale = new Vector3(0.38f, 0.045f, 0.38f);
			Renderer component = val5.GetComponent<Renderer>();
			if (component != null)
			{
				component.material = val4;
			}
			Collider component2 = val5.GetComponent<Collider>();
			if (component2 != null)
			{
				MonoBehaviour.Destroy((Object)(object)component2);
			}
		}
		MonoBehaviour.Destroy((Object)(object)val, 90f);
	}

	private void Update()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		((Component)this).transform.Rotate(Vector3.up, 90f * Time.deltaTime, (Space)0);
	}

	private void OnTriggerEnter(Collider other)
	{
		if (other != null)
		{
			GameObject val = GameReflection.FindPlayerRoot(((Component)other).gameObject);
			if (val != null && GameReflection.TryGiveGold(val, amount))
			{
				MonoBehaviour.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
}
public static class TrexModelFactory
{
	public static GameObject CreateModel(TrexPlugin plugin, TrexSettings settings, Transform parent, out Transform mouthAnchor, out TrexProceduralAnimator animator)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: 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_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		mouthAnchor = null;
		animator = null;
		GameObject val = TryCreateFromAssetBundle(plugin, parent);
		if (val == null)
		{
			val = TryCreateFromObj(plugin, parent);
		}
		if (val == null)
		{
			val = CreatePrimitiveTrex(parent);
		}
		val.transform.localPosition = Vector3.zero;
		val.transform.localRotation = Quaternion.identity;
		val.transform.localScale = Vector3.one * Mathf.Max(0.05f, settings.ModelScale.Value);
		Bounds val2 = CalculateBounds(val);
		Transform val3 = FindChildByName(val.transform, "jaw");
		if (val3 == null)
		{
			val3 = FindChildByName(val.transform, "teeth");
		}
		GameObject val4 = new GameObject("Trex Mouth Anchor");
		mouthAnchor = val4.transform;
		mouthAnchor.SetParent(val.transform, false);
		Vector3 position = default(Vector3);
		((Vector3)(ref position))..ctor(val2.center.x, val2.min.y + val2.size.y * 0.74f, val2.max.z - val2.size.z * 0.08f);
		mouthAnchor.position = position;
		animator = val.AddComponent<TrexProceduralAnimator>();
		animator.Initialize(val.transform, val3, mouthAnchor);
		return val;
	}

	private static GameObject TryCreateFromAssetBundle(TrexPlugin plugin, Transform parent)
	{
		string path = Path.Combine(plugin.PluginDirectory, "assets");
		string[] array = new string[3]
		{
			Path.Combine(path, "Trex.assetbundle"),
			Path.Combine(path, "trex.assetbundle"),
			Path.Combine(path, "trex")
		};
		for (int i = 0; i < array.Length; i++)
		{
			if (!File.Exists(array[i]))
			{
				continue;
			}
			try
			{
				AssetBundle val = AssetBundle.LoadFromFile(array[i]);
				if (val == null)
				{
					continue;
				}
				GameObject val2 = val.LoadAsset<GameObject>("TrexEnemy");
				if (val2 == null)
				{
					GameObject[] array2 = val.LoadAllAssets<GameObject>();
					if (array2 != null && array2.Length > 0)
					{
						val2 = array2[0];
					}
				}
				if (val2 == null)
				{
					val.Unload(false);
					continue;
				}
				GameObject val3 = Object.Instantiate<GameObject>(val2, parent);
				((Object)val3).name = "Trex AssetBundle Model";
				plugin.LogInfo("Loaded Trex model from asset bundle: " + array[i]);
				return val3;
			}
			catch (Exception ex)
			{
				plugin.LogWarning("Failed to load Trex asset bundle '" + array[i] + "': " + ex.Message);
			}
		}
		return null;
	}

	private static GameObject TryCreateFromObj(TrexPlugin plugin, Transform parent)
	{
		string text = Path.Combine(plugin.PluginDirectory, "assets\\trex_obj\\Tyrannosaurus_Male_Merged_MESH.obj");
		if (!File.Exists(text))
		{
			text = Path.Combine(plugin.PluginDirectory, "assets\\trex_obj\\Tyrannosaurus_Male_MESH.obj");
		}
		if (!File.Exists(text))
		{
			plugin.LogWarning("Trex OBJ model was not found. Using primitive fallback.");
			return null;
		}
		try
		{
			GameObject val = RuntimeObjLoader.Load(text, parent);
			((Object)val).name = "Trex OBJ Model";
			plugin.LogInfo("Loaded Trex model from OBJ: " + text);
			return val;
		}
		catch (Exception exception)
		{
			plugin.LogError("Failed to load Trex OBJ model.", exception);
			return null;
		}
	}

	private static GameObject CreatePrimitiveTrex(Transform parent)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Expected O, but got Unknown
		//IL_0050: 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_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: 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_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_0248: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Trex Primitive Model");
		val.transform.SetParent(parent, false);
		Material val2 = new Material((Shader.Find("Standard") != null) ? Shader.Find("Standard") : Shader.Find("Diffuse"));
		val2.color = new Color(0.32f, 0.22f, 0.13f);
		Material val3 = new Material(val2);
		val3.color = new Color(0.15f, 0.1f, 0.07f);
		CreatePrimitivePart("Body", (PrimitiveType)2, val.transform, new Vector3(0f, 2.6f, 0f), new Vector3(2.4f, 2f, 4.8f), val2);
		CreatePrimitivePart("Head", (PrimitiveType)0, val.transform, new Vector3(0f, 3.6f, 3.2f), new Vector3(1.8f, 1f, 1.7f), val2);
		CreatePrimitivePart("Jaw", (PrimitiveType)0, val.transform, new Vector3(0f, 3.1f, 3.7f), new Vector3(1.5f, 0.35f, 1.3f), val3);
		CreatePrimitivePart("Tail", (PrimitiveType)2, val.transform, new Vector3(0f, 2.45f, -3.2f), new Vector3(0.9f, 0.9f, 4.4f), val2).transform.localRotation = Quaternion.Euler(90f, 0f, 0f);
		CreatePrimitivePart("Left Leg", (PrimitiveType)2, val.transform, new Vector3(-0.8f, 1.2f, -0.8f), new Vector3(0.6f, 1.9f, 0.6f), val2);
		CreatePrimitivePart("Right Leg", (PrimitiveType)2, val.transform, new Vector3(0.8f, 1.2f, -0.8f), new Vector3(0.6f, 1.9f, 0.6f), val2);
		CreatePrimitivePart("Left Arm", (PrimitiveType)2, val.transform, new Vector3(-1.1f, 2.8f, 1.2f), new Vector3(0.22f, 0.9f, 0.22f), val3).transform.localRotation = Quaternion.Euler(55f, 0f, 20f);
		CreatePrimitivePart("Right Arm", (PrimitiveType)2, val.transform, new Vector3(1.1f, 2.8f, 1.2f), new Vector3(0.22f, 0.9f, 0.22f), val3).transform.localRotation = Quaternion.Euler(55f, 0f, -20f);
		return val;
	}

	private static GameObject CreatePrimitivePart(string name, PrimitiveType type, Transform parent, Vector3 localPosition, Vector3 localScale, Material material)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: 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_002f: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = GameObject.CreatePrimitive(type);
		((Object)val).name = name;
		val.transform.SetParent(parent, false);
		val.transform.localPosition = localPosition;
		val.transform.localScale = localScale;
		Renderer component = val.GetComponent<Renderer>();
		if (component != null)
		{
			component.material = material;
		}
		Collider component2 = val.GetComponent<Collider>();
		if (component2 != null)
		{
			Object.Destroy((Object)(object)component2);
		}
		return val;
	}

	private static Transform FindChildByName(Transform root, string contains)
	{
		string value = contains.ToLowerInvariant();
		Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			if (((Object)componentsInChildren[i]).name.ToLowerInvariant().IndexOf(value) >= 0)
			{
				return componentsInChildren[i];
			}
		}
		return null;
	}

	private static Bounds CalculateBounds(GameObject root)
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: 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_005d: 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)
		Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true);
		if (componentsInChildren.Length == 0)
		{
			return new Bounds(root.transform.position + new Vector3(0f, 2.5f, 2.5f), new Vector3(3f, 5f, 5f));
		}
		Bounds bounds = componentsInChildren[0].bounds;
		for (int i = 1; i < componentsInChildren.Length; i++)
		{
			((Bounds)(ref bounds)).Encapsulate(componentsInChildren[i].bounds);
		}
		return bounds;
	}
}
[BepInPlugin("local.muck.trexpredator", "Trex Predator", "0.1.3")]
public sealed class TrexPlugin : BaseUnityPlugin
{
	public const string PluginGuid = "local.muck.trexpredator";

	public const string PluginName = "Trex Predator";

	public const string PluginVersion = "0.1.3";

	public static TrexPlugin Instance;

	public static TrexSettings Settings;

	public string PluginDirectory { get; private set; }

	private void Awake()
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		Instance = this;
		PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
		Settings = TrexSettings.Bind(((BaseUnityPlugin)this).Config);
		GameObject val = new GameObject("MuckTrexWorldManager");
		MonoBehaviour.DontDestroyOnLoad((Object)(object)val);
		TrexWorldManager trexWorldManager = val.AddComponent<TrexWorldManager>();
		trexWorldManager.Initialize(this, Settings);
		LogInfo("Loaded. Assets directory: " + Path.Combine(PluginDirectory, "assets"));
	}

	public void LogInfo(string message)
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)message);
	}

	public void LogWarning(string message)
	{
		((BaseUnityPlugin)this).Logger.LogWarning((object)message);
	}

	public void LogError(string message, Exception exception)
	{
		((BaseUnityPlugin)this).Logger.LogError((object)(message + Environment.NewLine + exception));
	}
}
public sealed class TrexSettings
{
	public ConfigEntry<bool> Enabled;

	public ConfigEntry<float> MaxHp;

	public ConfigEntry<float> Damage;

	public ConfigEntry<int> KillGoldReward;

	public ConfigEntry<int> MaxAlive;

	public ConfigEntry<float> SpawnDelaySeconds;

	public ConfigEntry<float> FallbackDayLengthSeconds;

	public ConfigEntry<float> SpawnMinDistanceFromPlayer;

	public ConfigEntry<float> SpawnMaxDistanceFromPlayer;

	public ConfigEntry<float> RoamRadius;

	public ConfigEntry<float> AggroRange;

	public ConfigEntry<float> EatRange;

	public ConfigEntry<float> ChewDuration;

	public ConfigEntry<float> ChewDamageTickSeconds;

	public ConfigEntry<float> AttackCooldown;

	public ConfigEntry<float> WalkSpeed;

	public ConfigEntry<float> ChaseSpeed;

	public ConfigEntry<float> ModelScale;

	public ConfigEntry<float> ClickHitDamage;

	public ConfigEntry<bool> HoldVictimDuringChew;

	public ConfigEntry<bool> SpawnOnFirstWorldReady;

	public static TrexSettings Bind(ConfigFile config)
	{
		TrexSettings trexSettings = new TrexSettings();
		trexSettings.Enabled = config.Bind<bool>("General", "Enabled", true, "Master toggle for Trex spawning and AI.");
		trexSettings.MaxHp = config.Bind<float>("Stats", "MaxHp", 5000f, "Trex health. Intentionally high.");
		trexSettings.Damage = config.Bind<float>("Stats", "Damage", 35f, "Damage applied on each chew tick.");
		trexSettings.KillGoldReward = config.Bind<int>("Stats", "KillGoldReward", 300, "Gold awarded when a Trex dies.");
		trexSettings.MaxAlive = config.Bind<int>("Spawning", "MaxAlive", 24, "Maximum Trexes alive at once. A new one is still attempted each day until this cap.");
		trexSettings.SpawnDelaySeconds = config.Bind<float>("Spawning", "SpawnDelaySeconds", 12f, "Minimum scene time before the first Trex can spawn.");
		trexSettings.FallbackDayLengthSeconds = config.Bind<float>("Spawning", "FallbackDayLengthSeconds", 600f, "Used only when Muck's current day cannot be reflected.");
		trexSettings.SpawnMinDistanceFromPlayer = config.Bind<float>("Spawning", "SpawnMinDistanceFromPlayer", 80f, "Minimum spawn distance from a player.");
		trexSettings.SpawnMaxDistanceFromPlayer = config.Bind<float>("Spawning", "SpawnMaxDistanceFromPlayer", 160f, "Maximum spawn distance from a player.");
		trexSettings.RoamRadius = config.Bind<float>("AI", "RoamRadius", 95f, "Random roaming radius around the current Trex position.");
		trexSettings.AggroRange = config.Bind<float>("AI", "AggroRange", 45f, "Distance where the Trex starts chasing players.");
		trexSettings.EatRange = config.Bind<float>("AI", "EatRange", 4.5f, "Distance where the Trex starts the chew/spit attack.");
		trexSettings.ChewDuration = config.Bind<float>("AI", "ChewDuration", 2.4f, "How long the chew animation holds the victim.");
		trexSettings.ChewDamageTickSeconds = config.Bind<float>("AI", "ChewDamageTickSeconds", 0.55f, "Seconds between damage ticks while chewing.");
		trexSettings.AttackCooldown = config.Bind<float>("AI", "AttackCooldown", 4.5f, "Seconds after a chew before another chew can start.");
		trexSettings.WalkSpeed = config.Bind<float>("AI", "WalkSpeed", 2.5f, "Roaming speed.");
		trexSettings.ChaseSpeed = config.Bind<float>("AI", "ChaseSpeed", 6.2f, "Chase speed.");
		trexSettings.ModelScale = config.Bind<float>("Visuals", "ModelScale", 1f, "Scale applied to the loaded Trex model.");
		trexSettings.ClickHitDamage = config.Bind<float>("Combat", "ClickHitDamage", 65f, "Fallback damage applied when the local player clicks the Trex collider.");
		trexSettings.HoldVictimDuringChew = config.Bind<bool>("Combat", "HoldVictimDuringChew", true, "Temporarily pins the victim near the Trex mouth during the chew animation.");
		trexSettings.SpawnOnFirstWorldReady = config.Bind<bool>("Spawning", "SpawnOnFirstWorldReady", true, "Spawn once as soon as players are detected, then once per day.");
		return trexSettings;
	}
}
public sealed class TrexProceduralAnimator : MonoBehaviour
{
	private Transform visualRoot;

	private Transform jaw;

	private Transform mouthAnchor;

	private Renderer[] renderers;

	private Color[] originalColors;

	private float speed;

	private bool chasing;

	private bool chewing;

	private bool dead;

	private float chewPulse;

	private float hitFlash;

	private Vector3 baseLocalPosition;

	private Quaternion baseLocalRotation;

	private Quaternion jawBaseRotation;

	public void Initialize(Transform root, Transform jawTransform, Transform mouth)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		visualRoot = root;
		jaw = jawTransform;
		mouthAnchor = mouth;
		baseLocalPosition = visualRoot.localPosition;
		baseLocalRotation = visualRoot.localRotation;
		if (jaw != null)
		{
			jawBaseRotation = jaw.localRotation;
		}
		renderers = ((Component)this).GetComponentsInChildren<Renderer>(true);
		originalColors = (Color[])(object)new Color[renderers.Length];
		for (int i = 0; i < renderers.Length; i++)
		{
			if (renderers[i] != null && renderers[i].material != null)
			{
				ref Color reference = ref originalColors[i];
				reference = renderers[i].material.color;
			}
		}
	}

	public void SetState(float normalizedSpeed, bool isChasing, bool isChewing)
	{
		speed = Mathf.Clamp01(normalizedSpeed);
		chasing = isChasing;
		chewing = isChewing;
	}

	public void ChewPulse()
	{
		chewPulse = 1f;
	}

	public void FlashHit()
	{
		hitFlash = 1f;
	}

	public void PlayDeath()
	{
		dead = true;
		chewing = false;
		speed = 0f;
	}

	private void Update()
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: 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_004f: 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_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//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)
		if (visualRoot == null)
		{
			return;
		}
		float time = Time.time;
		if (dead)
		{
			visualRoot.localRotation = Quaternion.Slerp(visualRoot.localRotation, Quaternion.Euler(0f, 0f, 86f), Time.deltaTime * 1.5f);
			visualRoot.localPosition = Vector3.Lerp(visualRoot.localPosition, baseLocalPosition + Vector3.down * 0.55f, Time.deltaTime * 1.2f);
			UpdateHitFlash();
			return;
		}
		float num = Mathf.Sin(time * (chasing ? 8.5f : 5.2f));
		float num2 = num * 0.08f * Mathf.Max(0.15f, speed);
		float num3 = Mathf.Sin(time * (chasing ? 4.5f : 2.7f)) * 2.8f * Mathf.Max(0.1f, speed);
		visualRoot.localPosition = baseLocalPosition + Vector3.up * num2;
		visualRoot.localRotation = baseLocalRotation * Quaternion.Euler(0f, 0f, num3);
		if (jaw != null)
		{
			chewPulse = Mathf.MoveTowards(chewPulse, 0f, Time.deltaTime * 3.2f);
			float num4 = (chewing ? Mathf.Abs(Mathf.Sin(time * 19f)) : chewPulse);
			jaw.localRotation = jawBaseRotation * Quaternion.Euler(Mathf.Lerp(0f, 22f, num4), 0f, 0f);
		}
		if (mouthAnchor != null)
		{
			mouthAnchor.localRotation = Quaternion.identity;
		}
		UpdateHitFlash();
	}

	private void UpdateHitFlash()
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		if (renderers == null)
		{
			return;
		}
		hitFlash = Mathf.MoveTowards(hitFlash, 0f, Time.deltaTime * 3.5f);
		for (int i = 0; i < renderers.Length; i++)
		{
			if (renderers[i] != null && renderers[i].material != null)
			{
				Color val = ((originalColors != null && i < originalColors.Length) ? originalColors[i] : Color.white);
				renderers[i].material.color = Color.Lerp(val, Color.red, hitFlash * 0.45f);
			}
		}
	}
}
public sealed class TrexWorldManager : MonoBehaviour
{
	private TrexPlugin plugin;

	private TrexSettings settings;

	private readonly List<TrexEnemy> liveTrexes = new List<TrexEnemy>();

	private int lastSpawnedDay = int.MinValue;

	private bool spawnedInitial;

	private float nextThinkTime;

	public void Initialize(TrexPlugin owner, TrexSettings config)
	{
		plugin = owner;
		settings = config;
	}

	private void Update()
	{
		if (settings == null || !settings.Enabled.Value || Time.unscaledTime < nextThinkTime)
		{
			return;
		}
		nextThinkTime = Time.unscaledTime + 2f;
		PruneDeadTrexes();
		if (Time.timeSinceLevelLoad < settings.SpawnDelaySeconds.Value)
		{
			return;
		}
		List<GameObject> playerObjects = GameReflection.GetPlayerObjects();
		if (playerObjects.Count != 0)
		{
			if (!GameReflection.TryGetCurrentDay(out var day))
			{
				day = Mathf.FloorToInt(Time.timeSinceLevelLoad / Mathf.Max(30f, settings.FallbackDayLengthSeconds.Value));
			}
			if (settings.SpawnOnFirstWorldReady.Value && !spawnedInitial)
			{
				spawnedInitial = true;
				lastSpawnedDay = day;
				TrySpawnTrex(playerObjects, day);
			}
			else if (day != lastSpawnedDay)
			{
				lastSpawnedDay = day;
				TrySpawnTrex(playerObjects, day);
			}
		}
	}

	private void PruneDeadTrexes()
	{
		for (int num = liveTrexes.Count - 1; num >= 0; num--)
		{
			if (liveTrexes[num] == null || liveTrexes[num].IsDead)
			{
				liveTrexes.RemoveAt(num);
			}
		}
	}

	private void TrySpawnTrex(List<GameObject> players, int day)
	{
		//IL_01df: 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_0060: Expected O, but got Unknown
		//IL_0066: 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_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: 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)
		if (liveTrexes.Count >= settings.MaxAlive.Value)
		{
			return;
		}
		if (!TryFindSpawnPosition(players, out var position))
		{
			plugin.LogWarning("Could not find a Trex spawn position for day " + day + ".");
			return;
		}
		GameObject val = new GameObject("Trex Predator Day " + day);
		val.transform.position = position;
		val.transform.rotation = Quaternion.Euler(0f, Random.Range(0f, 360f), 0f);
		Rigidbody val2 = val.AddComponent<Rigidbody>();
		val2.isKinematic = true;
		val2.useGravity = false;
		CapsuleCollider val3 = val.AddComponent<CapsuleCollider>();
		val3.radius = 1.8f;
		val3.height = 5.5f;
		val3.center = new Vector3(0f, 2.75f, 0f);
		NavMeshAgent val4 = null;
		try
		{
			val4 = val.AddComponent<NavMeshAgent>();
			val4.radius = 1.8f;
			val4.height = 5.5f;
			val4.baseOffset = 0f;
			val4.speed = settings.WalkSpeed.Value;
			val4.angularSpeed = 180f;
			val4.acceleration = 16f;
			val4.stoppingDistance = Mathf.Max(2f, settings.EatRange.Value * 0.6f);
		}
		catch (Exception ex)
		{
			plugin.LogWarning("NavMeshAgent could not be attached; using direct movement. " + ex.Message);
		}
		TrexEnemy trexEnemy = val.AddComponent<TrexEnemy>();
		trexEnemy.Initialize(plugin, settings, val4);
		liveTrexes.Add(trexEnemy);
		plugin.LogInfo("Spawned Trex for day " + day + " at " + position);
	}

	private bool TryFindSpawnPosition(List<GameObject> players, out Vector3 position)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		position = Vector3.zero;
		for (int i = 0; i < 40; i++)
		{
			GameObject val = players[Random.Range(0, players.Count)];
			Vector2 insideUnitCircle = Random.insideUnitCircle;
			Vector2 val2 = ((Vector2)(ref insideUnitCircle)).normalized;
			if (((Vector2)(ref val2)).sqrMagnitude < 0.1f)
			{
				val2 = Vector2.right;
			}
			float num = Random.Range(settings.SpawnMinDistanceFromPlayer.Value, settings.SpawnMaxDistanceFromPlayer.Value);
			Vector3 source = val.transform.position + new Vector3(val2.x * num, 120f, val2.y * num);
			if (TryGroundPosition(source, out position))
			{
				return true;
			}
		}
		Vector3 source2 = players[0].transform.position + new Vector3(settings.SpawnMinDistanceFromPlayer.Value, 120f, 0f);
		return TryGroundPosition(source2, out position);
	}

	public static bool TryGroundPosition(Vector3 source, out Vector3 position)
	{
		//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_0007: 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_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		position = source;
		NavMeshHit val = default(NavMeshHit);
		if (NavMesh.SamplePosition(source, ref val, 80f, -1))
		{
			position = val.position;
			return true;
		}
		RaycastHit val2 = default(RaycastHit);
		if (Physics.Raycast(source, Vector3.down, ref val2, 300f))
		{
			position = val2.point;
			return true;
		}
		if (Terrain.activeTerrain != null)
		{
			Vector3 val3 = source;
			val3.y = Terrain.activeTerrain.SampleHeight(source) + ((Component)Terrain.activeTerrain).transform.position.y;
			position = val3;
			return true;
		}
		source.y = 0f;
		position = source;
		return true;
	}
}