Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of LoxLorax v1.0.8
BepInEx/plugins/LoxLorax/LoxLorax.dll
Decompiled 2 weeks agousing 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(); } }