Decompiled source of LoxLorax v1.0.8

BepInEx/plugins/LoxLorax/LoxLorax.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace LoxLorax;

public sealed class LoraxDeath : MonoBehaviour
{
	internal static readonly HashSet<LoraxDeath> Active = new HashSet<LoraxDeath>();

	private readonly List<Mesh> bakedMeshes = new List<Mesh>();

	private Transform body;

	private Transform head;

	private Vector3 bodyStart;

	private Vector3 headStart;

	private Vector3 forward;

	private Vector3 right;

	private Quaternion headRotation;

	private Renderer[] headRenderers;

	private float age;

	private float groundY;

	private bool landed;

	internal static void Create(Transform source, Ragdoll corpse)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		if (Object.op_Implicit((Object)(object)((Component)corpse).GetComponent<LoraxDeathHandled>()))
		{
			return;
		}
		GameObject val = new GameObject("Lorax head-off sky launch");
		LoraxDeath loraxDeath = val.AddComponent<LoraxDeath>();
		try
		{
			loraxDeath.Build(source);
			((Component)corpse).gameObject.AddComponent<LoraxDeathHandled>();
			Renderer[] componentsInChildren = ((Component)corpse).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				if (val2 is MeshRenderer || val2 is SkinnedMeshRenderer)
				{
					val2.forceRenderingOff = true;
				}
			}
			Active.Add(loraxDeath);
		}
		catch
		{
			Object.Destroy((Object)(object)val);
			throw;
		}
	}

	private void Build(Transform source)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Expected O, but got Unknown
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Expected O, but got Unknown
		//IL_0177: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0241: 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_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_025e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Unknown result type (might be due to invalid IL or missing references)
		//IL_027b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0282: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		body = new GameObject("Headless Lorax body").transform;
		head = new GameObject("Detached Lorax head").transform;
		body.SetParent(((Component)this).transform, false);
		head.SetParent(((Component)this).transform, false);
		body.position = source.position;
		Transform val = source.Find("Head");
		if (!Object.op_Implicit((Object)(object)val))
		{
			throw new InvalidOperationException("Lorax head group missing from model.");
		}
		head.position = val.position;
		int num = 0;
		int num2 = 0;
		Renderer[] componentsInChildren = ((Component)source).GetComponentsInChildren<Renderer>();
		foreach (Renderer val2 in componentsInChildren)
		{
			bool flag = ((Component)val2).transform.IsChildOf(val);
			SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((val2 is SkinnedMeshRenderer) ? val2 : null);
			Mesh val5;
			if (Object.op_Implicit((Object)(object)val3))
			{
				Mesh val4 = new Mesh();
				((Object)val4).name = "Lorax death snapshot";
				val4.indexFormat = val3.sharedMesh.indexFormat;
				val5 = val4;
				bakedMeshes.Add(val5);
				val3.BakeMesh(val5, true);
			}
			else
			{
				MeshFilter component = ((Component)val2).GetComponent<MeshFilter>();
				if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component.sharedMesh))
				{
					continue;
				}
				val5 = component.sharedMesh;
			}
			GameObject val6 = new GameObject(((Object)val2).name);
			val6.layer = ((Component)val2).gameObject.layer;
			GameObject val7 = val6;
			val7.transform.SetPositionAndRotation(((Component)val2).transform.position, ((Component)val2).transform.rotation);
			val7.transform.localScale = ((Component)val2).transform.lossyScale;
			val7.transform.SetParent((!flag) ? body : head, true);
			val7.AddComponent<MeshFilter>().sharedMesh = val5;
			MeshRenderer val8 = val7.AddComponent<MeshRenderer>();
			((Renderer)val8).sharedMaterials = val2.sharedMaterials;
			((Renderer)val8).shadowCastingMode = val2.shadowCastingMode;
			if (flag)
			{
				num2++;
			}
			else
			{
				num++;
			}
		}
		if (num2 == 0 || num == 0)
		{
			throw new InvalidOperationException("Incomplete Lorax death snapshot.");
		}
		bodyStart = body.position;
		headStart = head.position;
		headRotation = head.rotation;
		forward = source.forward;
		right = source.right;
		groundY = source.position.y;
		int mask = LayerMask.GetMask(new string[3] { "terrain", "static_solid", "piece" });
		RaycastHit val9 = default(RaycastHit);
		if (Physics.Raycast(source.position + Vector3.up * 2f, Vector3.down, ref val9, 100f, mask, (QueryTriggerInteraction)1))
		{
			groundY = ((RaycastHit)(ref val9)).point.y;
		}
		headRenderers = ((Component)head).GetComponentsInChildren<Renderer>();
	}

	private void Update()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: 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_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: 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_0079: Unknown result type (might be due to invalid IL or missing references)
		//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_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: 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_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: 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_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_0268: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		age += Time.deltaTime;
		float num = Mathf.Max(0f, age - 0.12f);
		body.position = bodyStart + (Vector3.up * 80f + forward * 14f + right * 8f) * num - Vector3.up * (1.5f * num * num);
		body.rotation = Quaternion.Euler(num * 155f, num * 45f, num * 85f);
		if (age > 8f)
		{
			((Component)body).gameObject.SetActive(false);
		}
		if (!landed)
		{
			head.position = headStart + (Vector3.up * 7f + forward * 4f - right * 2f) * age - Vector3.up * (7f * age * age);
			head.rotation = Quaternion.Euler(age * 130f, age * 60f, age * 75f) * headRotation;
			float num2 = float.PositiveInfinity;
			Renderer[] array = headRenderers;
			foreach (Renderer val in array)
			{
				float num3 = num2;
				Bounds bounds = val.bounds;
				num2 = Mathf.Min(num3, ((Bounds)(ref bounds)).min.y);
			}
			if (age > 0.35f && num2 <= groundY)
			{
				Transform obj = head;
				obj.position += Vector3.up * (groundY - num2 + 0.03f);
				landed = true;
			}
		}
		if (age > 11f)
		{
			head.localScale = Vector3.one * Mathf.Clamp01(12f - age);
		}
		if (age >= 12f)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
		}
	}

	private void OnDestroy()
	{
		Active.Remove(this);
		foreach (Mesh bakedMesh in bakedMeshes)
		{
			if (Object.op_Implicit((Object)(object)bakedMesh))
			{
				Object.Destroy((Object)(object)bakedMesh);
			}
		}
	}
}
public sealed class LoraxDeathHandled : MonoBehaviour
{
}
internal sealed class LoxAnimation
{
	internal static readonly string[] BoneNames = new string[17]
	{
		"Hip", "spine1", "Spine2", "Neck", "Head", "Frontupperleg.l", "Frontlowerleg.l", "Frontfoot.l", "Frontupperleg.r", "Frontlowerleg.r",
		"Frontfoot.r", "Backupperleg.l", "Backlowerleg.l", "Backfoot.l", "Backupperleg.r", "Backlowerleg.r", "Backfoot.r"
	};

	private static readonly string[] VileBoneNames = new string[17]
	{
		"Hip", "Spine_01", "Chest", "Neck", "Head", "Front_UpperLeg.L", "Front_LowerLeg.L", "Front_Foot.L", "Front_UpperLeg.R", "Front_LowerLeg.R",
		"Front_Foot.R", "Back_UpperLeg.L", "Back_LowerLeg.L", "Back_Foot.L", "Back_UpperLeg.R", "Back_LowerLeg.R", "Back_Foot.R"
	};

	internal readonly Transform[] Bones;

	private readonly Transform owner;

	private readonly Transform[] source;

	private readonly Vector3[] restPositions;

	private readonly Vector3[] anchors;

	private readonly Quaternion[] inverseRestRotations;

	private readonly Matrix4x4[] inverseRestMatrices;

	private readonly bool followNativePose;

	private readonly Transform[] nativeToes;

	private readonly Vector3[][] pawVertices;

	private readonly Animator animator;

	private readonly AnimatorCullingMode previousCulling;

	private readonly List<AnimatorClipInfo> clips = new List<AnimatorClipInfo>();

	private float biteImpact = 0.4f;

	private readonly string biteClip;

	internal LoxAnimation(Transform owner, Transform root, GameObject original, Vector3[] anchors, Vector3[][] pawVertices, bool vile = false)
	{
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: 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_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_031e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0327: Unknown result type (might be due to invalid IL or missing references)
		//IL_032c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0331: Unknown result type (might be due to invalid IL or missing references)
		//IL_0348: Unknown result type (might be due to invalid IL or missing references)
		//IL_034d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0352: Unknown result type (might be due to invalid IL or missing references)
		//IL_036b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0370: Unknown result type (might be due to invalid IL or missing references)
		//IL_0375: Unknown result type (might be due to invalid IL or missing references)
		//IL_038e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0393: Unknown result type (might be due to invalid IL or missing references)
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_040b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0458: Unknown result type (might be due to invalid IL or missing references)
		//IL_045d: Unknown result type (might be due to invalid IL or missing references)
		LoxAnimation loxAnimation = this;
		this.owner = owner;
		this.anchors = anchors;
		followNativePose = vile;
		this.pawVertices = pawVertices;
		string[] sourceNames = ((!vile) ? BoneNames : VileBoneNames);
		biteClip = ((!vile) ? "Attack" : "Attack Bite");
		SkinnedMeshRenderer skin = (from r in original.GetComponentsInChildren<SkinnedMeshRenderer>(true)
			where Object.op_Implicit((Object)(object)r.sharedMesh) && sourceNames.All((string name) => r.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == name))
			orderby r.sharedMesh.vertexCount descending
			select r).FirstOrDefault();
		if (!Object.op_Implicit((Object)(object)skin))
		{
			throw new InvalidOperationException("Lox animation skeleton was not found.");
		}
		Matrix4x4[] bindposes = skin.sharedMesh.bindposes;
		Matrix4x4 val = owner.worldToLocalMatrix * ((Component)skin).transform.localToWorldMatrix;
		if (vile)
		{
			int num = Array.FindIndex(skin.bones, (Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == "Root");
			if (num < 0 || num >= bindposes.Length)
			{
				throw new InvalidOperationException("Vile root binding was not found.");
			}
			val = owner.worldToLocalMatrix * skin.bones[num].localToWorldMatrix * bindposes[num];
			string[] array = new string[4] { "Front_Toe.L", "Front_Toe.R", "Back_Toe.L", "Back_Toe.R" };
			nativeToes = array.Select((string name) => ((IEnumerable<Transform>)skin.bones).FirstOrDefault((Func<Transform, bool>)((Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == name))).ToArray();
			if (nativeToes.Any((Transform toe) => !Object.op_Implicit((Object)(object)toe)) || pawVertices.Length != 4 || pawVertices.Any((Vector3[] paw) => paw.Length == 0))
			{
				throw new InvalidOperationException("Vile paw contact references were not found.");
			}
		}
		source = (Transform[])(object)new Transform[BoneNames.Length];
		restPositions = (Vector3[])(object)new Vector3[BoneNames.Length];
		inverseRestRotations = (Quaternion[])(object)new Quaternion[BoneNames.Length];
		inverseRestMatrices = (Matrix4x4[])(object)new Matrix4x4[BoneNames.Length];
		Bones = (Transform[])(object)new Transform[BoneNames.Length];
		for (int i = 0; i < Bones.Length; i++)
		{
			int num2 = Array.FindIndex(skin.bones, (Transform b) => Object.op_Implicit((Object)(object)b) && ((Object)b).name == sourceNames[i]);
			if (num2 < 0 || num2 >= bindposes.Length)
			{
				throw new InvalidOperationException("Creature animation bone missing: " + sourceNames[i]);
			}
			source[i] = skin.bones[num2];
			Matrix4x4 val2 = val * ((Matrix4x4)(ref bindposes[num2])).inverse;
			ref Vector3 reference = ref restPositions[i];
			reference = Vector4.op_Implicit(((Matrix4x4)(ref val2)).GetColumn(3));
			ref Quaternion reference2 = ref inverseRestRotations[i];
			reference2 = Quaternion.Inverse(((Matrix4x4)(ref val2)).rotation);
			ref Matrix4x4 reference3 = ref inverseRestMatrices[i];
			reference3 = ((Matrix4x4)(ref val2)).inverse;
		}
		for (int num3 = 0; num3 < Bones.Length; num3++)
		{
			Bones[num3] = new GameObject("Lorax bone " + BoneNames[num3]).transform;
			Bones[num3].SetParent(root, false);
			Bones[num3].localPosition = anchors[num3];
		}
		animator = original.GetComponentInChildren<Animator>();
		if (!Object.op_Implicit((Object)(object)animator))
		{
			throw new InvalidOperationException("Lox animator was not found.");
		}
		previousCulling = animator.cullingMode;
		AnimationClip val3 = ((IEnumerable<AnimationClip>)animator.runtimeAnimatorController.animationClips).FirstOrDefault((Func<AnimationClip, bool>)((AnimationClip c) => ((Object)c).name == loxAnimation.biteClip));
		if (Object.op_Implicit((Object)(object)val3) && val3.length > 0f)
		{
			AnimationEvent val4 = ((IEnumerable<AnimationEvent>)val3.events).FirstOrDefault((Func<AnimationEvent, bool>)((AnimationEvent e) => e.functionName == "Hit" || e.functionName == "OnAttackTrigger"));
			if (val4 != null)
			{
				biteImpact = Mathf.Clamp(val4.time / val3.length, 0.15f, 0.8f);
			}
		}
		animator.cullingMode = (AnimatorCullingMode)0;
	}

	internal void Update(bool enabled)
	{
		//IL_00d1: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		//IL_0058: 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_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: 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_0092: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < Bones.Length; i++)
		{
			if (!Object.op_Implicit((Object)(object)source[i]))
			{
				continue;
			}
			if (followNativePose && enabled)
			{
				Matrix4x4 val = owner.worldToLocalMatrix * source[i].localToWorldMatrix * inverseRestMatrices[i];
				Bones[i].localPosition = ((Matrix4x4)(ref val)).MultiplyPoint3x4(anchors[i] * 4.2f) / 4.2f;
				Bones[i].localRotation = ((Matrix4x4)(ref val)).rotation;
				Bones[i].localScale = ((Matrix4x4)(ref val)).lossyScale;
				continue;
			}
			Bones[i].localScale = Vector3.one;
			Vector3 val2 = (owner.InverseTransformPoint(source[i].position) - restPositions[i]) / 4.2f;
			if (i >= 5)
			{
				val2.x *= 0.65f;
			}
			Bones[i].localPosition = ((!enabled) ? anchors[i] : (anchors[i] + val2));
			Bones[i].localRotation = ((!enabled) ? Quaternion.identity : (Quaternion.Inverse(owner.rotation) * source[i].rotation * inverseRestRotations[i]));
		}
		if (enabled && followNativePose)
		{
			MatchPawContact();
		}
		if (enabled && !followNativePose)
		{
			EmphasizeBite();
		}
	}

	private void MatchPawContact()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: 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_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: 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_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)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < 4; i++)
		{
			Transform val = Bones[7 + i * 3];
			Matrix4x4 val2 = Matrix4x4.TRS(val.localPosition, val.localRotation, val.localScale);
			float num = float.PositiveInfinity;
			Vector3[] array = pawVertices[i];
			foreach (Vector3 val3 in array)
			{
				num = Mathf.Min(num, ((Matrix4x4)(ref val2)).MultiplyPoint3x4(val3).y);
			}
			float num2 = owner.InverseTransformPoint(nativeToes[i].position).y / 4.2f;
			Vector3 val4 = Vector3.up * (num2 - num);
			val.localPosition += val4;
			Transform obj = Bones[6 + i * 3];
			obj.localPosition += val4 * 0.5f;
		}
	}

	private void EmphasizeBite()
	{
		//IL_0018: 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_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		float num;
		if (animator.IsInTransition(0))
		{
			AnimatorTransitionInfo animatorTransitionInfo = animator.GetAnimatorTransitionInfo(0);
			num = Mathf.Clamp01(((AnimatorTransitionInfo)(ref animatorTransitionInfo)).normalizedTime);
		}
		else
		{
			num = 0f;
		}
		float num2 = num;
		animator.GetCurrentAnimatorClipInfo(0, clips);
		AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
		AddBitePose(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime, 1f - num2);
		if (animator.IsInTransition(0))
		{
			animator.GetNextAnimatorClipInfo(0, clips);
			AnimatorStateInfo nextAnimatorStateInfo = animator.GetNextAnimatorStateInfo(0);
			AddBitePose(((AnimatorStateInfo)(ref nextAnimatorStateInfo)).normalizedTime, num2);
		}
	}

	private void AddBitePose(float time, float transitionWeight)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: 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_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0212: Unknown result type (might be due to invalid IL or missing references)
		//IL_0236: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: 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_025b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0260: Unknown result type (might be due to invalid IL or missing references)
		//IL_0267: Unknown result type (might be due to invalid IL or missing references)
		//IL_026c: Unknown result type (might be due to invalid IL or missing references)
		float num = 0f;
		foreach (AnimatorClipInfo clip in clips)
		{
			AnimatorClipInfo current = clip;
			if (Object.op_Implicit((Object)(object)((AnimatorClipInfo)(ref current)).clip) && ((Object)((AnimatorClipInfo)(ref current)).clip).name == biteClip)
			{
				num += ((AnimatorClipInfo)(ref current)).weight;
			}
		}
		num *= transitionWeight;
		if (!(num <= 0f) && !(time < 0f) && !(time > 1f))
		{
			float num2 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(Mathf.Max(0f, biteImpact - 0.25f), biteImpact - 0.1f, time)) * (1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(biteImpact - 0.1f, biteImpact, time)));
			float num3 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(biteImpact - 0.09f, biteImpact, time)) * (1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(biteImpact + 0.04f, Mathf.Min(1f, biteImpact + 0.32f), time)));
			Vector3 val = new Vector3(0f, 0.055f * num2 - 0.075f * num3, -0.1f * num2 + 0.23f * num3) * num;
			float num4 = (-18f * num2 + 26f * num3) * num;
			Transform obj = Bones[4];
			obj.localPosition += val;
			Bones[4].localRotation = Quaternion.Euler(num4, 0f, 0f) * Bones[4].localRotation;
			Transform obj2 = Bones[3];
			obj2.localPosition += val * 0.65f;
			Bones[3].localRotation = Quaternion.Euler(num4 * 0.45f, 0f, 0f) * Bones[3].localRotation;
			Transform obj3 = Bones[2];
			obj3.localPosition += val * 0.2f;
		}
	}

	internal void Restore()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)animator))
		{
			animator.cullingMode = previousCulling;
		}
	}

	internal static Vector3[] CreateAnchors(IList<string> groups, IList<Vector3> pivots)
	{
		//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_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: 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)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		if (groups.Count != 6 || groups[5] != "Head")
		{
			throw new InvalidOperationException("Animation requires the 1.0.3 model asset. Copy both mod files.");
		}
		float num = pivots[1].y / 0.48f;
		Vector3[] array = (Vector3[])(object)new Vector3[BoneNames.Length];
		ref Vector3 reference = ref array[0];
		reference = new Vector3(0f, 0.53f, -0.4f) * num;
		ref Vector3 reference2 = ref array[1];
		reference2 = new Vector3(0f, 0.54f, -0.12f) * num;
		ref Vector3 reference3 = ref array[2];
		reference3 = new Vector3(0f, 0.6f, 0.27f) * num;
		ref Vector3 reference4 = ref array[3];
		reference4 = new Vector3(0f, 0.64f, 0.43f) * num;
		ref Vector3 reference5 = ref array[4];
		reference5 = pivots[5];
		for (int i = 1; i <= 4; i++)
		{
			int num2 = 5 + (i - 1) * 3;
			float num3 = ((i % 2 != 1) ? 1f : (-1f));
			Vector3 val = pivots[i];
			array[num2] = val;
			ref Vector3 reference6 = ref array[num2 + 1];
			reference6 = new Vector3(val.x + num3 * 0.016f * num, 0.22f * num, val.z);
			ref Vector3 reference7 = ref array[num2 + 2];
			reference7 = new Vector3(val.x + num3 * 0.02f * num, 0.057f * num, val.z + 0.075f * num);
		}
		return array;
	}

	internal static BoneWeight Weight(Vector3 vertex, int group, Vector3[] anchors)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		switch (group)
		{
		case 5:
			return Blend(4, 4, 0f);
		default:
		{
			int num = 5 + (group - 1) * 3;
			float y = anchors[num + 1].y;
			float y2 = anchors[num + 2].y;
			float num2 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(y2 + 0.075f, y2 + 0.015f, vertex.y));
			if (num2 > 0f)
			{
				return Blend(num + 1, num + 2, num2);
			}
			float blend = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(y + 0.09f, y - 0.06f, vertex.y));
			return Blend(num, num + 1, blend);
		}
		case 0:
			if (vertex.z < anchors[1].z)
			{
				return Blend(0, 1, Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(anchors[0].z, anchors[1].z, vertex.z)));
			}
			if (vertex.z < anchors[2].z)
			{
				return Blend(1, 2, Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(anchors[1].z, anchors[2].z, vertex.z)));
			}
			return Blend(2, 3, Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(anchors[2].z, anchors[3].z, vertex.z)));
		}
	}

	private static BoneWeight Blend(int a, int b, float blend)
	{
		//IL_0002: 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)
		BoneWeight result = default(BoneWeight);
		((BoneWeight)(ref result)).boneIndex0 = a;
		((BoneWeight)(ref result)).weight0 = 1f - blend;
		((BoneWeight)(ref result)).boneIndex1 = b;
		((BoneWeight)(ref result)).weight1 = blend;
		return result;
	}
}
internal sealed class ModelAsset : IDisposable
{
	private readonly List<Object> owned = new List<Object>();

	private readonly List<Mesh> meshes = new List<Mesh>();

	private readonly List<Material> materials = new List<Material>();

	private readonly List<int> materialIds = new List<int>();

	private readonly List<int> groupIds = new List<int>();

	private readonly List<string> groupNames = new List<string>();

	private readonly List<Vector3> pivots = new List<Vector3>();

	internal Vector3[] AnimationAnchors;

	internal Vector3[][] PawVertices;

	internal static ModelAsset Load(string path, bool undead = false)
	{
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Expected O, but got Unknown
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_031c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Expected O, but got Unknown
		//IL_043c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0441: Unknown result type (might be due to invalid IL or missing references)
		//IL_0461: Unknown result type (might be due to invalid IL or missing references)
		//IL_0466: Unknown result type (might be due to invalid IL or missing references)
		//IL_0480: Unknown result type (might be due to invalid IL or missing references)
		//IL_0485: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f4: Expected O, but got Unknown
		//IL_0585: Unknown result type (might be due to invalid IL or missing references)
		//IL_058a: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_05fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0602: Unknown result type (might be due to invalid IL or missing references)
		//IL_0639: Unknown result type (might be due to invalid IL or missing references)
		//IL_063e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0693: Unknown result type (might be due to invalid IL or missing references)
		//IL_06aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_06af: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_06cb: Unknown result type (might be due to invalid IL or missing references)
		ModelAsset model = new ModelAsset();
		try
		{
			using (BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)))
			{
				if (binaryReader.ReadUInt32() != 844648268)
				{
					throw new InvalidDataException("Unsupported model format.");
				}
				Shader[] source = Resources.FindObjectsOfTypeAll<Shader>();
				Shader val = ((IEnumerable<Shader>)source).FirstOrDefault((Func<Shader, bool>)((Shader s) => ((Object)s).name == "Custom/Creature" && s.isSupported)) ?? ((IEnumerable<Shader>)source).FirstOrDefault((Func<Shader, bool>)((Shader s) => ((Object)s).name == "Standard" && s.isSupported));
				if (!Object.op_Implicit((Object)(object)val))
				{
					throw new InvalidOperationException("No supported creature shader is loaded.");
				}
				int num = Count(binaryReader, 1, 128);
				for (int num2 = 0; num2 < num; num2++)
				{
					Material val2 = new Material(val);
					((Object)val2).name = "Lorax material " + num2;
					Material val3 = val2;
					model.owned.Add((Object)(object)val3);
					val3.color = new Color(Float(binaryReader), Float(binaryReader), Float(binaryReader), Float(binaryReader));
					if (undead && (num2 == 9 || num2 == 10) && val3.HasProperty("_EmissionColor"))
					{
						val3.EnableKeyword("_EMISSION");
						val3.SetColor("_EmissionColor", new Color(1f, 0.06f, 0.65f) * 1.8f);
					}
					val3.SetFloat("_Glossiness", 0.1f);
					val3.SetFloat("_Metallic", 0f);
					if (val3.HasProperty("_UseStyles"))
					{
						val3.SetFloat("_UseStyles", 0f);
					}
					if (val3.HasProperty("_UseGlossmap"))
					{
						val3.SetFloat("_UseGlossmap", 0f);
					}
					if (val3.HasProperty("_BumpScale"))
					{
						val3.SetFloat("_BumpScale", 0f);
					}
					if (val3.HasProperty("_Cull"))
					{
						val3.SetFloat("_Cull", 2f);
					}
					int num3 = Count(binaryReader, 0, 16777216);
					if (num3 > 0)
					{
						Texture2D val4 = new Texture2D(2, 2, (TextureFormat)4, true);
						model.owned.Add((Object)(object)val4);
						byte[] array = binaryReader.ReadBytes(num3);
						if (array.Length != num3 || !ImageConversion.LoadImage(val4, array, true))
						{
							throw new InvalidDataException("Invalid model texture.");
						}
						val3.mainTexture = (Texture)(object)val4;
					}
					model.materials.Add(val3);
				}
				int num4 = Count(binaryReader, 1, 32);
				for (int num5 = 0; num5 < num4; num5++)
				{
					int num6 = Count(binaryReader, 1, 128);
					byte[] array2 = binaryReader.ReadBytes(num6);
					if (array2.Length != num6)
					{
						throw new EndOfStreamException();
					}
					model.groupNames.Add(Encoding.UTF8.GetString(array2));
					model.pivots.Add(new Vector3(Float(binaryReader), Float(binaryReader), Float(binaryReader)));
				}
				model.AnimationAnchors = LoxAnimation.CreateAnchors(model.groupNames, model.pivots);
				HashSet<Vector3>[] array3 = (from _ in Enumerable.Range(0, 4)
					select new HashSet<Vector3>()).ToArray();
				int num7 = Count(binaryReader, 1, 256);
				int num8 = 0;
				for (int num9 = 0; num9 < num7; num9++)
				{
					int item = Count(binaryReader, 0, num - 1);
					int groupId = Count(binaryReader, 0, num4 - 1);
					int num10 = Count(binaryReader, 3, 200000);
					num8 += num10;
					if (num8 > 500000)
					{
						throw new InvalidDataException("Model exceeds vertex budget.");
					}
					Vector3[] array4 = (Vector3[])(object)new Vector3[num10];
					Vector3[] array5 = (Vector3[])(object)new Vector3[num10];
					Vector2[] array6 = (Vector2[])(object)new Vector2[num10];
					for (int num11 = 0; num11 < num10; num11++)
					{
						ref Vector3 reference = ref array4[num11];
						reference = new Vector3(Float(binaryReader), Float(binaryReader), Float(binaryReader));
						ref Vector3 reference2 = ref array5[num11];
						reference2 = new Vector3(Float(binaryReader), Float(binaryReader), Float(binaryReader));
						ref Vector2 reference3 = ref array6[num11];
						reference3 = new Vector2(Float(binaryReader), Float(binaryReader));
					}
					int num12 = Count(binaryReader, 3, 1500000);
					if (num12 % 3 != 0)
					{
						throw new InvalidDataException("Incomplete triangle.");
					}
					int[] array7 = new int[num12];
					for (int num13 = 0; num13 < array7.Length; num13++)
					{
						array7[num13] = Count(binaryReader, 0, num10 - 1);
					}
					Mesh val5 = new Mesh();
					((Object)val5).name = "Lorax mesh " + num9;
					val5.indexFormat = (IndexFormat)(num10 > 65535);
					Mesh val6 = val5;
					model.owned.Add((Object)(object)val6);
					val6.vertices = array4;
					val6.normals = array5;
					val6.uv = array6;
					Color32[] array8 = (Color32[])(object)new Color32[num10];
					for (int num14 = 0; num14 < num10; num14++)
					{
						ref Color32 reference4 = ref array8[num14];
						reference4 = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
					}
					val6.colors32 = array8;
					BoneWeight[] array9 = (BoneWeight[])(object)new BoneWeight[num10];
					for (int num15 = 0; num15 < num10; num15++)
					{
						ref BoneWeight reference5 = ref array9[num15];
						reference5 = LoxAnimation.Weight(array4[num15] + model.pivots[groupId], groupId, model.AnimationAnchors);
						if (groupId >= 1 && groupId <= 4)
						{
							int num16 = 7 + (groupId - 1) * 3;
							BoneWeight val7 = array9[num15];
							if ((((BoneWeight)(ref val7)).boneIndex0 == num16 && ((BoneWeight)(ref val7)).weight0 >= 0.99999f) || (((BoneWeight)(ref val7)).boneIndex1 == num16 && ((BoneWeight)(ref val7)).weight1 >= 0.99999f))
							{
								array3[groupId - 1].Add(array4[num15] + model.pivots[groupId] - model.AnimationAnchors[num16]);
							}
						}
					}
					val6.boneWeights = array9;
					val6.bindposes = model.AnimationAnchors.Select((Vector3 anchor) => Matrix4x4.Translate(model.pivots[groupId] - anchor)).ToArray();
					val6.triangles = array7;
					val6.RecalculateBounds();
					val6.UploadMeshData(true);
					model.meshes.Add(val6);
					model.materialIds.Add(item);
					model.groupIds.Add(groupId);
				}
				model.PawVertices = array3.Select(Enumerable.ToArray).ToArray();
				if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
				{
					throw new InvalidDataException("Unexpected trailing model data.");
				}
			}
			return model;
		}
		catch
		{
			model.Dispose();
			throw;
		}
	}

	private static int Count(BinaryReader reader, int min, int max)
	{
		int num = reader.ReadInt32();
		if (num < min || num > max)
		{
			throw new InvalidDataException("Model value outside supported range.");
		}
		return num;
	}

	private static float Float(BinaryReader reader)
	{
		float num = reader.ReadSingle();
		if (float.IsNaN(num) || float.IsInfinity(num))
		{
			throw new InvalidDataException("Non-finite model value.");
		}
		return num;
	}

	internal Transform Instantiate(Transform parent, int layer, bool skinned = true)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Expected O, but got Unknown
		//IL_00f9: 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)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Lorax replacement");
		val.transform.SetParent(parent, false);
		try
		{
			Transform[] array = (Transform[])(object)new Transform[groupNames.Count];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new GameObject(groupNames[i]).transform;
				array[i].SetParent(val.transform, false);
				array[i].localPosition = pivots[i];
			}
			for (int j = 0; j < meshes.Count; j++)
			{
				GameObject val2 = new GameObject("Lorax part " + j);
				val2.layer = layer;
				GameObject val3 = val2;
				val3.transform.SetParent(array[groupIds[j]], false);
				Renderer val5;
				if (skinned)
				{
					SkinnedMeshRenderer val4 = val3.AddComponent<SkinnedMeshRenderer>();
					val4.sharedMesh = meshes[j];
					val4.quality = (SkinQuality)2;
					((Renderer)val4).localBounds = new Bounds(new Vector3(0f, 0.5f, 0f) - pivots[groupIds[j]], new Vector3(3f, 3f, 4f));
					val5 = (Renderer)(object)val4;
				}
				else
				{
					val3.AddComponent<MeshFilter>().sharedMesh = meshes[j];
					val5 = (Renderer)(object)val3.AddComponent<MeshRenderer>();
				}
				val5.sharedMaterial = materials[materialIds[j]];
				val5.shadowCastingMode = (ShadowCastingMode)1;
				val5.receiveShadows = true;
			}
			return val.transform;
		}
		catch
		{
			Object.Destroy((Object)(object)val);
			throw;
		}
	}

	public void Dispose()
	{
		foreach (Object item in owned)
		{
			if (Object.op_Implicit(item))
			{
				Object.Destroy(item);
			}
		}
		owned.Clear();
	}
}
[BepInPlugin("com.loxlorax.mod", "Lox Lorax", "1.0.8")]
public sealed class Plugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Humanoid), "Start")]
	private static class HumanoidStart
	{
		private static void Postfix(Character __instance)
		{
			Attach(__instance);
		}
	}

	[HarmonyPatch(typeof(Humanoid), "OnRagdollCreated")]
	private static class LoxDeath
	{
		private static void Postfix(Humanoid __instance, Ragdoll __0)
		{
			LoraxVisual component = ((Component)__instance).GetComponent<LoraxVisual>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.PlayDeath(__0);
			}
		}
	}

	[HarmonyPatch(typeof(Ragdoll), "Start")]
	private static class RemoteLoxDeath
	{
		private static void Postfix(Ragdoll __instance)
		{
			if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<LoraxDeathHandled>()) && IsReplacementCorpse(__instance, out var vile))
			{
				Death(__instance, null, vile);
			}
		}
	}

	public const string Id = "com.loxlorax.mod";

	internal static Plugin Instance;

	internal ModelAsset Model;

	internal ModelAsset VileModel;

	internal ConfigEntry<float> Height;

	internal ConfigEntry<float> VileHeight;

	internal ConfigEntry<float> Yaw;

	internal ConfigEntry<float> VerticalOffset;

	internal ConfigEntry<bool> Motion;

	internal ConfigEntry<bool> ReplaceVile;

	internal ConfigEntry<bool> Enabled;

	internal ConfigEntry<KeyboardShortcut> ToggleKey;

	private Harmony harmony;

	private string modelPath;

	private bool modelFailed;

	private bool vileModelFailed;

	private bool replacementReported;

	private bool vileReplacementReported;

	private void Awake()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Expected O, but got Unknown
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Expected O, but got Unknown
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Invalid comparison between Unknown and I4
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Expected O, but got Unknown
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Replace living lox and Vile visuals. Can be changed while playing.");
		ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Enable or disable all Lorax replacements immediately. The choice is saved.");
		Height = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Height", 4.2f, new ConfigDescription("Model height in metres. Does not change the lox hitbox.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 8f), Array.Empty<object>()));
		Yaw = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Yaw", 0f, "Rotation around the vertical axis, in degrees.");
		VerticalOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "VerticalOffset", 0f, "Vertical adjustment in metres.");
		Motion = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance", "Motion", true, "Follow the original lox animations for legs, body and head.");
		ReplaceVile = ((BaseUnityPlugin)this).Config.Bind<bool>("Vile", "Enabled", true, "Replace Vile (Unbjorn) with the undead Lorax. Restart after changing.");
		VileHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Vile", "Height", 4.2f, new ConfigDescription("Undead Lorax height in metres. Does not change the Vile hitbox.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 8f), Array.Empty<object>()));
		modelPath = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "lorax.llmesh");
		if ((int)SystemInfo.graphicsDeviceType == 4)
		{
			return;
		}
		try
		{
			harmony = new Harmony("com.loxlorax.mod");
			harmony.PatchAll(typeof(Plugin).Assembly);
			if (Enabled.Value)
			{
				Character[] array = Character.GetAllCharacters().ToArray();
				foreach (Character character in array)
				{
					Attach(character);
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Concat("Lox Lorax ready. Press ", ToggleKey.Value, " to enable or disable replacements."));
		}
		catch (Exception ex)
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
				harmony = null;
			}
			if (Model != null)
			{
				Model.Dispose();
				Model = null;
			}
			if (VileModel != null)
			{
				VileModel.Dispose();
				VileModel = null;
			}
			((BaseUnityPlugin)this).Logger.LogError((object)("Lox Lorax could not initialize " + modelPath + ". Vanilla visuals are kept. " + ex.Message));
		}
	}

	private void Update()
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		if (ToggleKey != null)
		{
			KeyboardShortcut value = ToggleKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				SetEnabled(!Enabled.Value, notify: true);
			}
		}
	}

	private void SetEnabled(bool value, bool notify)
	{
		Enabled.Value = value;
		((BaseUnityPlugin)this).Config.Save();
		if (value)
		{
			Character[] array = Character.GetAllCharacters().ToArray();
			foreach (Character character in array)
			{
				Attach(character);
			}
		}
		else
		{
			LoraxVisual[] array2 = LoraxVisual.Active.ToArray();
			foreach (LoraxVisual loraxVisual in array2)
			{
				if (Object.op_Implicit((Object)(object)loraxVisual))
				{
					loraxVisual.Restore();
					Object.Destroy((Object)(object)loraxVisual);
				}
			}
		}
		string text = "Lox Lorax " + ((!value) ? "disabled" : "enabled");
		((BaseUnityPlugin)this).Logger.LogInfo((object)(text + "."));
		if (notify && Object.op_Implicit((Object)(object)MessageHud.instance))
		{
			MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false, true);
		}
	}

	internal static void Attach(Character character)
	{
		if (!Object.op_Implicit((Object)(object)Instance) || !Object.op_Implicit((Object)(object)character) || Instance.Enabled == null || !Instance.Enabled.Value)
		{
			return;
		}
		string name = ((Object)((Component)character).gameObject).name;
		bool flag = name == "Unbjorn" || name == "Unbjorn(Clone)";
		if ((!flag && name != "Lox" && name != "Lox(Clone)") || (flag && !Instance.ReplaceVile.Value) || character.IsDead() || Object.op_Implicit((Object)(object)((Component)character).GetComponent<LoraxVisual>()) || !Instance.EnsureModel(flag))
		{
			return;
		}
		LoraxVisual loraxVisual = ((Component)character).gameObject.AddComponent<LoraxVisual>();
		try
		{
			loraxVisual.Initialize(character, Instance, flag);
			if (flag && !Instance.vileReplacementReported)
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Undead Lorax replacement attached to Vile (Unbjorn); original body hidden.");
				Instance.vileReplacementReported = true;
			}
			if (!flag && !Instance.replacementReported)
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)"Lorax replacement attached to a living lox; original body hidden.");
				Instance.replacementReported = true;
			}
		}
		catch (Exception ex)
		{
			loraxVisual.Restore();
			Object.Destroy((Object)(object)loraxVisual);
			((BaseUnityPlugin)Instance).Logger.LogError((object)("Could not replace creature visuals: " + ex));
		}
	}

	private bool EnsureModel(bool vile = false)
	{
		if ((!vile) ? modelFailed : vileModelFailed)
		{
			return false;
		}
		if (((!vile) ? Model : VileModel) != null)
		{
			return true;
		}
		try
		{
			if (vile)
			{
				VileModel = ModelAsset.Load(Path.Combine(Path.GetDirectoryName(modelPath), "vile-lorax.llmesh"), undead: true);
			}
			else
			{
				Model = ModelAsset.Load(modelPath);
			}
			return true;
		}
		catch (Exception ex)
		{
			if (vile)
			{
				vileModelFailed = true;
			}
			else
			{
				modelFailed = true;
			}
			((BaseUnityPlugin)this).Logger.LogError((object)("Could not load " + ((!vile) ? "Lorax" : "undead Lorax") + " model; keeping vanilla creature. " + ex));
			return false;
		}
	}

	internal static void Death(Ragdoll corpse, Transform liveModel = null, bool vile = false)
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)Instance) || !Object.op_Implicit((Object)(object)corpse) || Object.op_Implicit((Object)(object)((Component)corpse).GetComponent<LoraxDeathHandled>()) || !Instance.EnsureModel(vile))
		{
			return;
		}
		Transform val = null;
		try
		{
			if (!Object.op_Implicit((Object)(object)liveModel))
			{
				Renderer componentInChildren = ((Component)corpse).GetComponentInChildren<Renderer>();
				val = ((!vile) ? Instance.Model : Instance.VileModel).Instantiate(null, Object.op_Implicit((Object)(object)componentInChildren) ? ((Component)componentInChildren).gameObject.layer : 0, skinned: false);
				val.SetPositionAndRotation(((Component)corpse).transform.position + Vector3.up * Instance.VerticalOffset.Value, ((Component)corpse).transform.rotation * Quaternion.Euler(0f, Instance.Yaw.Value, 0f));
				val.localScale = Vector3.one * ((!vile) ? Instance.Height.Value : Instance.VileHeight.Value);
				liveModel = val;
			}
			LoraxDeath.Create(liveModel, corpse);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)Instance).Logger.LogError((object)("Could not play Lorax death effect; vanilla corpse retained. " + ex));
		}
		finally
		{
			if (Object.op_Implicit((Object)(object)val))
			{
				((Component)val).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}
	}

	private static bool IsReplacementCorpse(Ragdoll corpse, out bool vile)
	{
		vile = false;
		if (!Object.op_Implicit((Object)(object)Instance) || Instance.Enabled == null || !Instance.Enabled.Value || !Object.op_Implicit((Object)(object)ZNetScene.instance))
		{
			return false;
		}
		string[] array = new string[2] { "Lox", "Unbjorn" };
		foreach (string text in array)
		{
			bool flag = text == "Unbjorn";
			if (flag && (!Object.op_Implicit((Object)(object)Instance) || !Instance.ReplaceVile.Value))
			{
				continue;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(text);
			Character val = ((!Object.op_Implicit((Object)(object)prefab)) ? null : prefab.GetComponent<Character>());
			if (!Object.op_Implicit((Object)(object)val) || val.m_deathEffects == null || val.m_deathEffects.m_effectPrefabs == null)
			{
				continue;
			}
			EffectData[] effectPrefabs = val.m_deathEffects.m_effectPrefabs;
			foreach (EffectData val2 in effectPrefabs)
			{
				if (Object.op_Implicit((Object)(object)val2.m_prefab) && Object.op_Implicit((Object)(object)val2.m_prefab.GetComponent<Ragdoll>()) && (((Object)corpse).name == ((Object)val2.m_prefab).name || ((Object)corpse).name == ((Object)val2.m_prefab).name + "(Clone)"))
				{
					vile = flag;
					return true;
				}
			}
		}
		return false;
	}

	private void OnDestroy()
	{
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		LoraxVisual[] array = LoraxVisual.Active.ToArray();
		foreach (LoraxVisual loraxVisual in array)
		{
			if (Object.op_Implicit((Object)(object)loraxVisual))
			{
				loraxVisual.Restore();
				Object.Destroy((Object)(object)loraxVisual);
			}
		}
		LoraxDeath[] array2 = LoraxDeath.Active.ToArray();
		foreach (LoraxDeath loraxDeath in array2)
		{
			if (Object.op_Implicit((Object)(object)loraxDeath))
			{
				Object.Destroy((Object)(object)((Component)loraxDeath).gameObject);
			}
		}
		if (Model != null)
		{
			Model.Dispose();
		}
		if (VileModel != null)
		{
			VileModel.Dispose();
		}
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}
}
[DefaultExecutionOrder(10000)]
public sealed class LoraxVisual : MonoBehaviour
{
	internal static readonly HashSet<LoraxVisual> Active = new HashSet<LoraxVisual>();

	private readonly Dictionary<Renderer, bool> originals = new Dictionary<Renderer, bool>();

	private Character character;

	private Plugin plugin;

	private Transform modelRoot;

	private LoxAnimation animation;

	private bool isVile;

	internal void Initialize(Character owner, Plugin settings, bool vile)
	{
		character = owner;
		isVile = vile;
		plugin = settings;
		GameObject originalVisual = default(GameObject);
		ref GameObject reference = ref originalVisual;
		object? value = AccessTools.Field(typeof(Character), "m_visual").GetValue(owner);
		reference = (GameObject)((value is GameObject) ? value : null);
		if (!Object.op_Implicit((Object)(object)originalVisual))
		{
			throw new InvalidOperationException("Lox visual root was not found.");
		}
		Renderer[] array = (from r in originalVisual.GetComponentsInChildren<Renderer>(true)
			where (r is SkinnedMeshRenderer || r is MeshRenderer) && !IsSaddle(((Component)r).transform, originalVisual.transform)
			select r).ToArray();
		if (array.Length == 0)
		{
			throw new InvalidOperationException("Lox body renderers were not found.");
		}
		ModelAsset modelAsset = ((!vile) ? plugin.Model : plugin.VileModel);
		modelRoot = modelAsset.Instantiate(((Component)this).transform, ((Component)array[0]).gameObject.layer);
		animation = new LoxAnimation(((Component)this).transform, modelRoot, originalVisual, modelAsset.AnimationAnchors, modelAsset.PawVertices, vile);
		SkinnedMeshRenderer[] componentsInChildren = ((Component)modelRoot).GetComponentsInChildren<SkinnedMeshRenderer>();
		foreach (SkinnedMeshRenderer val in componentsInChildren)
		{
			val.bones = animation.Bones;
			val.rootBone = modelRoot;
		}
		Renderer[] array2 = array;
		foreach (Renderer val2 in array2)
		{
			originals.Add(val2, val2.forceRenderingOff);
			val2.forceRenderingOff = true;
		}
		Active.Add(this);
		UpdatePose();
	}

	private static bool IsSaddle(Transform node, Transform root)
	{
		Transform val = node;
		while (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)root)
		{
			if (((Object)val).name.IndexOf("saddle", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)val).name.Equals("Sadel", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			val = val.parent;
		}
		return false;
	}

	private void LateUpdate()
	{
		if (Object.op_Implicit((Object)(object)modelRoot) && Object.op_Implicit((Object)(object)character) && Object.op_Implicit((Object)(object)plugin))
		{
			UpdatePose();
		}
	}

	private void UpdatePose()
	{
		//IL_0020: 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_005a: 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)
		modelRoot.localPosition = new Vector3(0f, plugin.VerticalOffset.Value, 0f);
		modelRoot.localRotation = Quaternion.Euler(0f, plugin.Yaw.Value, 0f);
		modelRoot.localScale = Vector3.one * ((!isVile) ? plugin.Height.Value : plugin.VileHeight.Value);
		animation.Update(plugin.Motion.Value);
	}

	internal void PlayDeath(Ragdoll corpse)
	{
		if (Object.op_Implicit((Object)(object)modelRoot))
		{
			Plugin.Death(corpse, modelRoot, isVile);
		}
	}

	internal void Restore()
	{
		if (animation != null)
		{
			animation.Restore();
			animation = null;
		}
		foreach (KeyValuePair<Renderer, bool> original in originals)
		{
			if (Object.op_Implicit((Object)(object)original.Key))
			{
				original.Key.forceRenderingOff = original.Value;
			}
		}
		originals.Clear();
		if (Object.op_Implicit((Object)(object)modelRoot))
		{
			((Component)modelRoot).gameObject.SetActive(false);
			Object.Destroy((Object)(object)((Component)modelRoot).gameObject);
			modelRoot = null;
		}
		Active.Remove(this);
	}

	private void OnDestroy()
	{
		Restore();
	}
}