Decompiled source of Deltarune Emotes v1.0.0

DeltaruneEmotes.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EmotesAPI;
using HG.BlendableTypes;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RoR2;
using RoR2.ConVar;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DeltaruneEmotes
{
	internal static class Afterimages
	{
		public sealed class Style
		{
			public float interval;

			public float lifetime;

			public float startAlpha;

			public float fadeIn;

			public float startBack;

			public float driftBack;

			public Color rim;

			public Color fill;

			public float fillAlpha;

			public bool playersOnly;
		}

		private sealed class Part
		{
			public Transform transform;

			public MeshFilter filter;

			public MeshRenderer renderer;

			public Mesh baked;
		}

		private sealed class Ghost
		{
			public GameObject root;

			public readonly List<Part> parts = new List<Part>();

			public float age;

			public float drift;

			public Vector3 origin;

			public Quaternion anchor;

			public Style style;
		}

		private sealed class Trail
		{
			public CharacterBody body;

			public Style style;

			public readonly List<Ghost> ghosts = new List<Ghost>();

			public float untilNext;

			public float speed;

			public Vector3? last;

			public bool active;
		}

		public static readonly Style Knight = new Style
		{
			interval = 0.06f,
			lifetime = 0.55f,
			startAlpha = 0.45f,
			fadeIn = 0.1f,
			startBack = 0.25f,
			driftBack = 3.2f,
			rim = Color.white,
			fill = Color.black,
			fillAlpha = 0.3f
		};

		public static readonly Style Jevil = new Style
		{
			interval = 0.075f,
			lifetime = 0.3f,
			startAlpha = 0.35f,
			fadeIn = 0.04f,
			playersOnly = true,
			rim = new Color(0.78f, 0.68f, 1f),
			fill = new Color(0.3f, 0.2f, 0.55f),
			fillAlpha = 0.55f
		};

		public static readonly Style JevilBetween = new Style
		{
			interval = 0f,
			lifetime = 0.4f,
			startAlpha = 0.45f,
			fadeIn = 0.03f,
			rim = new Color(0.78f, 0.68f, 1f),
			fill = new Color(0.3f, 0.2f, 0.55f),
			fillAlpha = 0.55f
		};

		private const float NoDriftSpeed = 6f;

		public static Material material;

		private static readonly Dictionary<BoneMapper, Trail> trails = new Dictionary<BoneMapper, Trail>();

		private static readonly Stack<Ghost> pool = new Stack<Ghost>();

		private static readonly List<BoneMapper> gone = new List<BoneMapper>();

		private static MaterialPropertyBlock block;

		private static readonly int alphaId = Shader.PropertyToID("_Alpha");

		private static readonly int rimId = Shader.PropertyToID("_RimColor");

		private static readonly int fillId = Shader.PropertyToID("_FillColor");

		private static readonly int fillAlphaId = Shader.PropertyToID("_FillAlpha");

		public static void Burst(BoneMapper m, Vector3 offset, Style style)
		{
			//IL_0095: 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_009a: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody val = (Object.op_Implicit((Object)(object)m) ? m.mapperBody : null);
			Transform val2 = ((Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.modelLocator)) ? val.modelLocator.modelTransform : null);
			if (Object.op_Implicit((Object)(object)material) && Object.op_Implicit((Object)(object)val2))
			{
				if (!trails.TryGetValue(m, out var value))
				{
					Dictionary<BoneMapper, Trail> dictionary = trails;
					Trail obj = new Trail
					{
						body = val,
						style = style
					};
					value = obj;
					dictionary[m] = obj;
				}
				Vector3 val3 = (Object.op_Implicit((Object)(object)val.characterDirection) ? val.characterDirection.forward : val2.forward);
				val3.y = 0f;
				if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
				{
					val3 = Vector3.forward;
				}
				Quaternion anchor = Quaternion.LookRotation(((Vector3)(ref val3)).normalized, Vector3.up);
				Ghost ghost = Spawn(val2, Props.RendererFor(m), val2.position, anchor);
				if (ghost != null)
				{
					ghost.origin = val2.position + offset;
					ghost.anchor = anchor;
					ghost.drift = 0f;
					ghost.style = style;
					value.ghosts.Add(ghost);
				}
			}
		}

		public static void Update(List<(BoneMapper mapper, Style style)> dancing, float dt)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: 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_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: 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_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)material))
			{
				return;
			}
			if (block == null)
			{
				block = new MaterialPropertyBlock();
			}
			foreach (Trail value3 in trails.Values)
			{
				value3.active = false;
			}
			foreach (var (val, style) in dancing)
			{
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.mapperBody))
				{
					if (!trails.TryGetValue(val, out var value))
					{
						Dictionary<BoneMapper, Trail> dictionary = trails;
						Trail obj = new Trail
						{
							body = val.mapperBody
						};
						value = obj;
						dictionary[val] = obj;
					}
					value.style = style;
					value.active = true;
				}
			}
			foreach (KeyValuePair<BoneMapper, Trail> trail in trails)
			{
				Trail value2 = trail.Value;
				CharacterBody body = value2.body;
				Transform val2 = ((Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.modelLocator)) ? body.modelLocator.modelTransform : null);
				if (!Object.op_Implicit((Object)(object)val2))
				{
					Clear(value2);
					gone.Add(trail.Key);
					continue;
				}
				Vector3 val3 = (Object.op_Implicit((Object)(object)body.characterDirection) ? body.characterDirection.forward : val2.forward);
				val3.y = 0f;
				if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
				{
					val3 = Vector3.forward;
				}
				Quaternion anchor = Quaternion.LookRotation(((Vector3)(ref val3)).normalized, Vector3.up);
				Vector3 position = val2.position;
				float num = Mathf.Max(0.5f, body.radius);
				Vector3? last = value2.last;
				if (last.HasValue)
				{
					Vector3 valueOrDefault = last.GetValueOrDefault();
					if (dt > 0f)
					{
						value2.speed = Mathf.Lerp(value2.speed, Vector3.Distance(position, valueOrDefault) / dt, 1f - Mathf.Exp((0f - dt) * 10f));
					}
				}
				value2.last = position;
				Style style2 = value2.style;
				CharacterModel component = ((Component)val2).GetComponent<CharacterModel>();
				bool flag = !Object.op_Implicit((Object)(object)component) || component.corpseFade > 0.6f;
				if (value2.active && style2.interval > 0f && (value2.untilNext -= dt) <= 0f && flag)
				{
					value2.untilNext = style2.interval;
					Ghost ghost = Spawn(val2, Props.RendererFor(trail.Key), position, anchor);
					if (ghost != null)
					{
						ghost.origin = position;
						ghost.anchor = anchor;
						ghost.drift = 1f - Mathf.Clamp01(value2.speed / 6f);
						ghost.style = style2;
						value2.ghosts.Add(ghost);
					}
				}
				for (int num2 = value2.ghosts.Count - 1; num2 >= 0; num2--)
				{
					Ghost ghost2 = value2.ghosts[num2];
					Style style3 = ghost2.style ?? style2;
					ghost2.age += dt;
					if (ghost2.age >= style3.lifetime)
					{
						Release(ghost2);
						value2.ghosts.RemoveAt(num2);
					}
					else
					{
						float num3 = ghost2.age / style3.lifetime;
						Vector3 val4 = new Vector3(0f, 0f, 0f - style3.startBack - style3.driftBack * ghost2.age) * (num * ghost2.drift);
						ghost2.root.transform.SetPositionAndRotation(ghost2.origin + ghost2.anchor * val4, ghost2.anchor);
						block.SetFloat(alphaId, style3.startAlpha * Mathf.Clamp01(ghost2.age / style3.fadeIn) * (1f - num3) * (1f - num3));
						block.SetColor(rimId, style3.rim);
						block.SetColor(fillId, style3.fill);
						block.SetFloat(fillAlphaId, style3.fillAlpha);
						foreach (Part part in ghost2.parts)
						{
							((Renderer)part.renderer).SetPropertyBlock(block);
						}
					}
				}
				if (!value2.active && value2.ghosts.Count == 0)
				{
					gone.Add(trail.Key);
				}
			}
			foreach (BoneMapper item in gone)
			{
				trails.Remove(item);
			}
			gone.Clear();
		}

		private static Ghost Spawn(Transform model, Renderer prop, Vector3 origin, Quaternion anchor)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_0090: 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_0097: 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)
			//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_00a3: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_0147: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			CharacterModel component = ((Component)model).GetComponent<CharacterModel>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return null;
			}
			Ghost ghost = null;
			while (pool.Count > 0 && (ghost == null || !Object.op_Implicit((Object)(object)ghost.root)))
			{
				ghost = pool.Pop();
			}
			if (ghost == null || !Object.op_Implicit((Object)(object)ghost.root))
			{
				ghost = new Ghost
				{
					root = new GameObject("KnightAfterimage")
				};
				Object.DontDestroyOnLoad((Object)(object)ghost.root);
			}
			ghost.age = 0f;
			ghost.root.SetActive(true);
			ghost.root.transform.SetPositionAndRotation(origin, anchor);
			Matrix4x4 val = Matrix4x4.TRS(origin, anchor, Vector3.one);
			Matrix4x4 inverse = ((Matrix4x4)(ref val)).inverse;
			int num = 0;
			MeshFilter val3 = default(MeshFilter);
			foreach (Renderer item in Renderers(component, prop))
			{
				if (!Object.op_Implicit((Object)(object)item) || !item.enabled || !((Component)item).gameObject.activeInHierarchy)
				{
					continue;
				}
				Vector3 localScale = Vector3.one;
				SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((item is SkinnedMeshRenderer) ? item : null);
				Mesh sharedMesh;
				if (val2 != null)
				{
					if (!Object.op_Implicit((Object)(object)val2.sharedMesh))
					{
						continue;
					}
					Part part = PartAt(ghost, num);
					if (!Object.op_Implicit((Object)(object)part.baked))
					{
						part.baked = new Mesh
						{
							name = "KnightAfterimage"
						};
					}
					val2.BakeMesh(part.baked, false);
					sharedMesh = part.baked;
				}
				else
				{
					if (!(item is MeshRenderer) || !((Component)item).TryGetComponent<MeshFilter>(ref val3) || !Object.op_Implicit((Object)(object)val3.sharedMesh))
					{
						continue;
					}
					sharedMesh = val3.sharedMesh;
					localScale = ((Component)item).transform.lossyScale;
				}
				Part part2 = PartAt(ghost, num++);
				part2.filter.sharedMesh = sharedMesh;
				((Component)part2.transform).gameObject.layer = ((Component)item).gameObject.layer;
				Matrix4x4 val4 = inverse * ((Component)item).transform.localToWorldMatrix;
				part2.transform.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref val4)).GetColumn(3));
				part2.transform.localRotation = Quaternion.LookRotation(Vector4.op_Implicit(((Matrix4x4)(ref val4)).GetColumn(2)), Vector4.op_Implicit(((Matrix4x4)(ref val4)).GetColumn(1)));
				part2.transform.localScale = localScale;
				((Component)part2.transform).gameObject.SetActive(true);
			}
			for (int i = num; i < ghost.parts.Count; i++)
			{
				((Component)ghost.parts[i].transform).gameObject.SetActive(false);
			}
			if (num == 0)
			{
				Release(ghost);
				return null;
			}
			return ghost;
		}

		private static IEnumerable<Renderer> Renderers(CharacterModel cm, Renderer extra)
		{
			RendererInfo[] baseRendererInfos = cm.baseRendererInfos;
			foreach (RendererInfo val in baseRendererInfos)
			{
				yield return val.renderer;
			}
			if (Object.op_Implicit((Object)(object)extra))
			{
				yield return extra;
			}
		}

		private static Part PartAt(Ghost g, int i)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			while (g.parts.Count <= i)
			{
				GameObject val = new GameObject("part");
				val.transform.SetParent(g.root.transform, false);
				MeshRenderer val2 = val.AddComponent<MeshRenderer>();
				((Renderer)val2).sharedMaterial = material;
				((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val2).receiveShadows = false;
				((Renderer)val2).lightProbeUsage = (LightProbeUsage)0;
				((Renderer)val2).reflectionProbeUsage = (ReflectionProbeUsage)0;
				g.parts.Add(new Part
				{
					transform = val.transform,
					filter = val.AddComponent<MeshFilter>(),
					renderer = val2
				});
			}
			return g.parts[i];
		}

		private static void Release(Ghost g)
		{
			if (Object.op_Implicit((Object)(object)g.root))
			{
				g.root.SetActive(false);
				pool.Push(g);
			}
		}

		private static void Clear(Trail t)
		{
			foreach (Ghost ghost in t.ghosts)
			{
				Release(ghost);
			}
			t.ghosts.Clear();
		}
	}
	internal static class CameraLift
	{
		internal static Dictionary<string, Vector3> Offsets = new Dictionary<string, Vector3>
		{
			["ToolbotBody"] = new Vector3(0f, 3f, -3f),
			["CaptainBody"] = new Vector3(0f, 1.2f, -2f)
		};

		private const float EaseIn = 0.6f;

		private const float EaseOut = 0.6f;

		private static CameraTargetParams lifted;

		private static CameraParamsOverrideHandle handle;

		public static void Update(List<(BoneMapper mapper, Props.Prop prop)> holding)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: 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)
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null);
			CameraTargetParams val2 = null;
			Vector3 value = default(Vector3);
			if (Object.op_Implicit((Object)(object)val) && Offsets.TryGetValue(BodyCatalog.GetBodyName(val.bodyIndex), out value))
			{
				foreach (var (val3, prop) in holding)
				{
					if (Object.op_Implicit((Object)(object)val3) && (Object)(object)val3.mapperBody == (Object)(object)val && (prop == Props.Aqua || prop == Props.AquaHops))
					{
						val2 = ((Component)val).GetComponent<CameraTargetParams>();
						break;
					}
				}
			}
			if (!((Object)(object)val2 == (Object)(object)lifted))
			{
				if (Object.op_Implicit((Object)(object)lifted))
				{
					lifted.RemoveParamsOverride(handle, 0.6f);
				}
				lifted = val2;
				handle = default(CameraParamsOverrideHandle);
				if (Object.op_Implicit((Object)(object)val2))
				{
					CharacterCameraParamsData val4 = (Object.op_Implicit((Object)(object)val2.cameraParams) ? val2.cameraParams.data : CharacterCameraParamsData.basic);
					handle = val2.AddParamsOverride(new CameraParamsOverrideRequest
					{
						cameraParamsData = new CharacterCameraParamsData
						{
							idealLocalCameraPos = BlendableVector3.op_Implicit(val4.idealLocalCameraPos.value + value)
						},
						priority = 0.05f
					}, 0.6f);
				}
			}
		}
	}
	internal static class Chaos
	{
		public sealed class Timing
		{
			public int visits;

			public float squash;

			public float squashAmount;

			public bool fade;

			public int clipFrames;

			public float appear;

			public float fadeIn;

			public float fadeOut;

			public float gone;

			public float vanishSquish;

			public Afterimages.Style afterimage;

			public float afterimageAt;
		}

		private sealed class Touched
		{
			public CharacterModel model;

			public Vector3 scale;

			public int marked = -1;

			public Vector3? previous;

			public Vector3 local;

			public bool replaced;
		}

		private static readonly Dictionary<BoneMapper, Touched> touched = new Dictionary<BoneMapper, Touched>();

		private static readonly List<BoneMapper> gone = new List<BoneMapper>();

		public static float Alpha(Timing t, float phase)
		{
			if (!t.fade)
			{
				if (t.clipFrames <= 0)
				{
					return 1f;
				}
				float num = phase * (float)t.clipFrames;
				float num2 = Mathf.Ceil(Mathf.Round(phase * (float)t.visits) * (float)t.clipFrames / (float)t.visits) - 1f;
				if (!(num > num2) || !(num < num2 + 1f))
				{
					return 1f;
				}
				return 0f;
			}
			float num3 = Mathf.Repeat(phase * (float)t.visits, 1f);
			return Mathf.SmoothStep(0f, 1f, (num3 - t.appear) / (t.fadeIn - t.appear)) * (1f - Mathf.SmoothStep(0f, 1f, (num3 - t.fadeOut) / (t.gone - t.fadeOut)));
		}

		public static void Update(List<(BoneMapper mapper, Timing timing)> dancers)
		{
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: 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_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_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_0519: Unknown result type (might be due to invalid IL or missing references)
			//IL_051b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0580: 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)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: 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_048a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0496: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0504: Unknown result type (might be due to invalid IL or missing references)
			//IL_0509: Unknown result type (might be due to invalid IL or missing references)
			//IL_050e: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_059b: Unknown result type (might be due to invalid IL or missing references)
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			//IL_059f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c6: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<BoneMapper, Touched> pair in touched)
			{
				if (!Object.op_Implicit((Object)(object)pair.Key) || !dancers.Exists(((BoneMapper mapper, Timing timing) d) => (Object)(object)d.mapper == (Object)(object)pair.Key))
				{
					gone.Add(pair.Key);
				}
			}
			foreach (BoneMapper item3 in gone)
			{
				Restore(touched[item3]);
				touched.Remove(item3);
			}
			gone.Clear();
			RaycastHit val6 = default(RaycastHit);
			RaycastHit val9 = default(RaycastHit);
			foreach (var dancer in dancers)
			{
				BoneMapper item = dancer.mapper;
				Timing item2 = dancer.timing;
				CharacterBody val = (Object.op_Implicit((Object)(object)item) ? item.mapperBody : null);
				CharacterModel val2 = ((Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.modelLocator) && Object.op_Implicit((Object)(object)val.modelLocator.modelTransform)) ? ((Component)val.modelLocator.modelTransform).GetComponent<CharacterModel>() : null);
				if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)item.a2))
				{
					continue;
				}
				if (!touched.TryGetValue(item, out var value) || !Object.op_Implicit((Object)(object)value.model))
				{
					Dictionary<BoneMapper, Touched> dictionary = touched;
					Touched obj = new Touched
					{
						model = val2,
						scale = ((Component)val2).transform.localScale,
						local = ((Component)val2).transform.localPosition,
						replaced = val.modelLocator.autoUpdateModelTransform
					};
					value = obj;
					dictionary[item] = obj;
				}
				AnimatorStateInfo currentAnimatorStateInfo = item.a2.GetCurrentAnimatorStateInfo(0);
				float num = Mathf.Repeat(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime, 1f);
				float num2 = (val2.corpseFade = Alpha(item2, num));
				float num3 = Mathf.Repeat(num * (float)item2.visits, 1f) - item2.appear;
				float num4 = ((num3 < 0f || num3 >= item2.squash) ? 0f : (item2.fade ? Mathf.Sin((float)Math.PI * num3 / item2.squash) : (1f - Mathf.SmoothStep(0f, 1f, num3 / item2.squash))));
				Transform boneTransform = item.a2.GetBoneTransform((HumanBodyBones)0);
				Transform boneTransform2 = item.a2.GetBoneTransform((HumanBodyBones)5);
				Transform boneTransform3 = item.a2.GetBoneTransform((HumanBodyBones)6);
				Transform parent = ((Component)val2).transform.parent;
				Vector3 val3 = ((value.replaced || !Object.op_Implicit((Object)(object)parent)) ? ((Component)val2).transform.position : parent.TransformPoint(value.local));
				float num5 = ((Component)val2).transform.localScale.y / Mathf.Max(0.0001f, value.scale.y);
				float num6 = ((Object.op_Implicit((Object)(object)boneTransform2) && Object.op_Implicit((Object)(object)boneTransform3)) ? ((Mathf.Min(boneTransform2.position.y, boneTransform3.position.y) - ((Component)val2).transform.position.y) / Mathf.Max(0.05f, num5)) : 0f);
				float num7 = Mathf.Max(item2.squashAmount * num4, item2.vanishSquish * (1f - num2));
				((Component)val2).transform.localScale = Vector3.Scale(value.scale, new Vector3(1f, 1f - num7, 1f));
				Vector3 val4 = Vector3.up * Mathf.Clamp(num6 * num7, 0f, 2f);
				if (Object.op_Implicit((Object)(object)boneTransform))
				{
					Vector3 val5 = val3 + Vector3.up * 2f;
					Vector3 down = Vector3.down;
					LayerIndex world = LayerIndex.world;
					if (Physics.Raycast(val5, down, ref val6, 6f, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask)))
					{
						float num8 = float.NegativeInfinity;
						Transform[] array = (Transform[])(object)new Transform[3] { boneTransform, boneTransform2, boneTransform3 };
						foreach (Transform val7 in array)
						{
							if (Object.op_Implicit((Object)(object)val7))
							{
								Vector3 val8 = new Vector3(val7.position.x, ((RaycastHit)(ref val6)).point.y + 6f, val7.position.z);
								Vector3 down2 = Vector3.down;
								world = LayerIndex.world;
								if (Physics.Raycast(val8, down2, ref val9, 14f, LayerMask.op_Implicit(((LayerIndex)(ref world)).mask)))
								{
									num8 = Mathf.Max(num8, ((RaycastHit)(ref val9)).point.y);
								}
							}
						}
						if (num8 > float.NegativeInfinity)
						{
							val4 += Vector3.up * Mathf.Clamp(num8 - ((RaycastHit)(ref val6)).point.y, 0f, 4f);
						}
					}
				}
				((Component)val2).transform.position = val3 + val4;
				int num10 = (int)(num * (float)item2.visits);
				if (!Object.op_Implicit((Object)(object)boneTransform) || item2.afterimage == null || num10 == value.marked || !(Mathf.Repeat(num * (float)item2.visits, 1f) >= item2.afterimageAt))
				{
					continue;
				}
				Vector3 val10 = Seen(val2, boneTransform);
				Vector3? previous = value.previous;
				if (previous.HasValue)
				{
					Vector3 valueOrDefault = previous.GetValueOrDefault();
					Vector3 val11 = valueOrDefault - val10;
					if (((Vector3)(ref val11)).sqrMagnitude > 0.09f)
					{
						Afterimages.Burst(item, (valueOrDefault - val10) / 2f, item2.afterimage);
					}
				}
				value.previous = val10;
				value.marked = num10;
			}
		}

		private static Vector3 Seen(CharacterModel cm, Transform hips)
		{
			//IL_000d: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			RendererInfo[] baseRendererInfos = cm.baseRendererInfos;
			for (int i = 0; i < baseRendererInfos.Length; i++)
			{
				Renderer renderer = baseRendererInfos[i].renderer;
				SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
				if (val != null && ((Renderer)val).enabled && ((Component)val).gameObject.activeInHierarchy)
				{
					Bounds bounds = ((Renderer)val).bounds;
					return ((Bounds)(ref bounds)).center;
				}
			}
			return hips.position;
		}

		private static void Restore(Touched t)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)t.model))
			{
				t.model.corpseFade = 1f;
				((Component)t.model).transform.localScale = t.scale;
				if (!t.replaced && Object.op_Implicit((Object)(object)((Component)t.model).transform.parent))
				{
					((Component)t.model).transform.localPosition = t.local;
				}
			}
		}
	}
	[BepInPlugin("com.chaz.deltaruneemotes", "DeltaruneEmotes", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class DeltaruneEmotesPlugin : BaseUnityPlugin
	{
		private sealed class Emote
		{
			public string clip;

			public string name;

			public string song;

			public float songBPM;

			public float danceBPM;

			public Afterimages.Style afterimages;

			public Chaos.Timing chaos;

			public bool oneShot;

			public bool keepGameMusic;

			public Props.Prop[] props;

			public Chain[] straight;

			public float? headDown;

			public bool strings;

			public Track track;
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static AnimationChanged <0>__OnAnimChanged;
		}

		public const string GUID = "com.chaz.deltaruneemotes";

		public const string Version = "1.0.0";

		private static readonly Emote[] emotes = new Emote[12]
		{
			new Emote
			{
				clip = "TennaDance",
				name = "It's TV Time!",
				song = "tvtime.sdm",
				songBPM = 147.35f,
				danceBPM = 125.218475f
			},
			new Emote
			{
				clip = "KnightHover",
				name = "Black Knife",
				song = "blackknife.sdm",
				songBPM = 147.45f,
				danceBPM = 125.21739f,
				afterimages = Afterimages.Knight,
				props = new Props.Prop[1] { Props.Sword },
				straight = new Chain[2]
				{
					new Chain
					{
						upper = (HumanBodyBones)1,
						lower = (HumanBodyBones)3,
						end = (HumanBodyBones)5,
						aim = new Vector3(-0.08f, 0f, -1f)
					},
					new Chain
					{
						upper = (HumanBodyBones)13,
						lower = (HumanBodyBones)15,
						end = (HumanBodyBones)17,
						aim = new Vector3(-0.1f, 0.42f, -0.91f)
					}
				}
			},
			new Emote
			{
				clip = "FlowerMan",
				name = "Flower Man",
				song = "flowerman.sdm",
				songBPM = 160f,
				danceBPM = 160f,
				props = new Props.Prop[1] { Props.Cape },
				straight = new Chain[1]
				{
					new Chain
					{
						upper = (HumanBodyBones)1,
						lower = (HumanBodyBones)3,
						end = (HumanBodyBones)5,
						aim = new Vector3(-0.03f, 0.05f, -1f)
					}
				}
			},
			new Emote
			{
				clip = "Pink",
				name = "Pink",
				song = "pink.sdm",
				songBPM = 180f,
				danceBPM = 180f,
				props = new Props.Prop[1] { Props.Staff }
			},
			new Emote
			{
				clip = "Gerson",
				name = "HammerOfJustice",
				song = "gerson.sdm",
				songBPM = 160f,
				danceBPM = 160f,
				props = new Props.Prop[1] { Props.Hammer },
				straight = new Chain[1]
				{
					new Chain
					{
						upper = (HumanBodyBones)8,
						lower = (HumanBodyBones)9,
						end = (HumanBodyBones)10,
						aim = new Vector3(0f, 1.6f, 1f),
						aimLower = new Vector3(0f, 0.2f, 1f)
					}
				},
				headDown = 8f
			},
			new Emote
			{
				clip = "Queen",
				name = "Queen",
				song = "queen.sdm",
				songBPM = 144f,
				danceBPM = 144f,
				props = new Props.Prop[3]
				{
					Props.Chair,
					Props.Flame,
					Props.Glass
				}
			},
			new Emote
			{
				clip = "Helloooo",
				name = "Helloooo",
				song = "hello.sdm",
				songBPM = 1f,
				danceBPM = 1f,
				oneShot = true,
				keepGameMusic = true
			},
			new Emote
			{
				clip = "Jevil",
				name = "The World Revolving",
				song = "jevil.sdm",
				songBPM = 191.4f,
				danceBPM = 191.15044f,
				afterimages = Afterimages.Jevil,
				chaos = new Chaos.Timing
				{
					visits = 22,
					clipFrames = 904,
					squash = 0.25f,
					squashAmount = 0.3f,
					afterimage = Afterimages.JevilBetween,
					afterimageAt = 0.45f
				}
			},
			new Emote
			{
				clip = "BigShot",
				name = "BigShot",
				song = "bigshot.sdm",
				songBPM = 140f,
				danceBPM = 137.14285f,
				strings = true
			},
			new Emote
			{
				clip = "Guardian",
				name = "Guardian",
				song = "guardian.sdm",
				songBPM = 140f,
				danceBPM = 139.80582f,
				props = new Props.Prop[3]
				{
					Props.KrisSword,
					Props.Susie,
					Props.Ralsei
				}
			},
			new Emote
			{
				clip = "PetalDance",
				name = "Who Might You Be?",
				song = "petal.sdm",
				songBPM = 120f,
				danceBPM = 120f,
				props = new Props.Prop[1] { Props.Aqua }
			},
			new Emote
			{
				clip = "PetalParty",
				name = "Petal Dance",
				song = "petalparty.sdm",
				songBPM = 145f,
				danceBPM = 145.45454f,
				props = new Props.Prop[3]
				{
					Props.SethBack,
					Props.SusieBack,
					Props.AquaHops
				}
			}
		};

		internal static ManualLogSource Log;

		private const float MusicGain = 1.38f;

		private static ConfigEntry<bool> allowMovement;

		private static ConfigEntry<bool> syncDance;

		private static ConfigEntry<bool> dimGameMusic;

		private static ConfigEntry<bool> afterimages;

		private static ConfigEntry<float> volume;

		private static ConfigEntry<float> fullVolumeRange;

		private static ConfigEntry<float> hearingRange;

		private static readonly Dictionary<string, Emote> byName = new Dictionary<string, Emote>();

		private static readonly List<(BoneMapper, Afterimages.Style)> trailing = new List<(BoneMapper, Afterimages.Style)>();

		private static readonly List<(BoneMapper, Chaos.Timing)> chaotic = new List<(BoneMapper, Chaos.Timing)>();

		private static readonly List<(BoneMapper, Props.Prop)> holding = new List<(BoneMapper, Props.Prop)>();

		private static bool? alliesEmote;

		private const string AlliesEmoteGUID = "com.chaz.allalliesemote";

		private static readonly List<(BoneMapper, Chain[])> straightening = new List<(BoneMapper, Chain[])>();

		private static readonly List<(BoneMapper, float)> heading = new List<(BoneMapper, float)>();

		private static readonly List<BoneMapper> stringing = new List<BoneMapper>();

		private static ConfigEntry<bool> neoStrings;

		private static FieldInfo animClipsField;

		private static FieldInfo allMappersField;

		private static FieldInfo clipNameField;

		private static FieldInfo emoteAnimatorField;

		private static FieldInfo stopOnMoveField;

		private static FieldInfo dimField;

		private static FieldInfo emotesVolumeField;

		private static bool AlliesEmote()
		{
			bool valueOrDefault = alliesEmote == true;
			if (!alliesEmote.HasValue)
			{
				valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.chaz.allalliesemote");
				alliesEmote = valueOrDefault;
				return valueOrDefault;
			}
			return valueOrDefault;
		}

		private void Awake()
		{
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Expected O, but got Unknown
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			allowMovement = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "AllowMovement", true, "Keep dancing while walking, sprinting and jumping (attacking still stops the emote).");
			syncDance = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "SyncDanceToMusic", true, "Dance at each song's tempo.");
			dimGameMusic = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "DimGameMusic", true, "Lower the game's music near someone doing one of these emotes (CustomEmotesAPI's dimming, like BadAssEmotes' music emotes).");
			afterimages = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "KnightAfterimages", true, "Show the Roaring Knight's trail of afterimages behind anyone doing Black Knife.");
			Props.Sword.enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "KnightSword", true, "Put the Knight's sword in the hand of any player doing Black Knife (drones and pets copying the emote don't get one).");
			Props.Hammer.enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "GersonHammer", true, "Give any player doing HammerOfJustice Gerson's hammer (drones and pets copying the emote don't get one).");
			Props.Staff.enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "PinkStaff", true, "Give any player doing Pink her staff (drones and pets copying the emote don't get one).");
			neoStrings = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "BigShotStrings", true, "Hang any player doing BigShot from Spamton NEO's green puppet strings (drones and pets copying the emote don't get them).");
			Props.Susie.enabled = (Props.Ralsei.enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "GuardianParty", true, "Have Susie and Ralsei stand beside any player doing Guardian (drones and pets copying the emote don't get them)."));
			Props.Aqua.enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "WhoMightYouBeAqua", true, "Have Aqua spin on the head of anyone doing Who Might You Be?, players and (with All Allies Emote) the drones, turrets and pets copying them.");
			Props.SethBack.enabled = (Props.SusieBack.enabled = (Props.AquaHops.enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "PetalDanceFriends", true, "Have Seth and Susie stand behind any player doing Petal Dance, with Aqua hopping between your heads (drones and pets copying the emote don't get them).")));
			Props.KrisSword.enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "GuardianSword", true, "Give any player doing Guardian Kris's sword (drones and pets copying the emote don't get one).");
			Props.Chair.enabled = (Props.Flame.enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "QueenChair", true, "Sit any player doing Queen in her flying chair (drones and pets copying the emote don't get one)."));
			Props.Glass.enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "QueenGlass", true, "Give any player doing Queen her glass of acid (drones and pets copying the emote don't get one).");
			Props.Cape.enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "FlowerManCape", true, "Give any player doing Flower Man Flowery's cape (drones and pets copying the emote don't get one).");
			volume = ((BaseUnityPlugin)this).Config.Bind<float>("Music", "Volume", 1f, new ConfigDescription("Music volume. Also scaled by the game's Master and SFX volume and CustomEmotesAPI's Emotes Volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			fullVolumeRange = ((BaseUnityPlugin)this).Config.Bind<float>("Music", "FullVolumeRange", 10f, "Other players' emote music is at full volume within this many metres...");
			hearingRange = ((BaseUnityPlugin)this).Config.Bind<float>("Music", "HearingRange", 60f, "...and fades out completely at this distance.");
			Assembly assembly = typeof(CustomEmotesAPI).Assembly;
			animClipsField = AccessTools.Field(typeof(BoneMapper), "animClips");
			allMappersField = AccessTools.Field(typeof(BoneMapper), "allMappers");
			clipNameField = AccessTools.Field(typeof(BoneMapper), "currentClipName");
			emoteAnimatorField = AccessTools.Field(typeof(BoneMapper), "a2");
			stopOnMoveField = AccessTools.Field(typeof(CustomAnimationClip), "stopOnMove");
			dimField = AccessTools.Field(typeof(CustomAnimationClip), "dimAudioWhenClose");
			emotesVolumeField = AccessTools.Field(assembly.GetType("EmotesAPI.Settings"), "EmotesVolume");
			RegisterEmotes();
			((Component)this).gameObject.AddComponent<LatePose>();
			MusicPlayer.Start();
			object obj = <>O.<0>__OnAnimChanged;
			if (obj == null)
			{
				AnimationChanged val = OnAnimChanged;
				<>O.<0>__OnAnimChanged = val;
				obj = (object)val;
			}
			CustomEmotesAPI.animChanged += (AnimationChanged)obj;
			allowMovement.SettingChanged += delegate
			{
				ApplyEmoteSettings();
			};
			dimGameMusic.SettingChanged += delegate
			{
				ApplyEmoteSettings();
			};
		}

		private void OnDestroy()
		{
			MusicPlayer.Stop();
		}

		internal static void AfterPose()
		{
			Joints.Straighten(straightening);
			Joints.LevelHeads(heading);
			Strings.Update(stringing);
			Props.Update(holding);
			CameraLift.Update(holding);
			Chaos.Update(chaotic);
			Afterimages.Update(trailing, Time.deltaTime);
		}

		private static byte[] Resource(string name)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
			using MemoryStream memoryStream = new MemoryStream();
			if (stream == null)
			{
				return null;
			}
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		private static void RegisterEmotes()
		{
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			AssetBundle val = AssetBundle.LoadFromMemory(Resource("deltaruneemotes"));
			if (!Object.op_Implicit((Object)(object)val))
			{
				Log.LogError((object)"Couldn't load the embedded emote bundle.");
				return;
			}
			Afterimages.material = val.LoadAsset<Material>("KnightAfterimage");
			if (!Object.op_Implicit((Object)(object)Afterimages.material))
			{
				Log.LogError((object)"The bundle has no KnightAfterimage material; Black Knife won't have afterimages.");
			}
			Props.Load(val);
			Emote[] array = emotes;
			foreach (Emote emote in array)
			{
				AnimationClip val2 = val.LoadAsset<AnimationClip>(emote.clip);
				if (!Object.op_Implicit((Object)(object)val2))
				{
					Log.LogError((object)("The bundle has no clip \"" + emote.clip + "\"."));
					continue;
				}
				emote.track = Track.Load(Resource(emote.song));
				if (emote.track != null)
				{
					emote.track.oneShot = emote.oneShot;
				}
				if (emote.track == null)
				{
					Log.LogError((object)("Couldn't read the embedded song " + emote.song + "; \"" + emote.name + "\" will be silent."));
				}
				((Object)val2).name = emote.name;
				AnimationClipParams val3 = new AnimationClipParams();
				val3.animationClip = (AnimationClip[])(object)new AnimationClip[1] { val2 };
				val3.looping = !emote.oneShot;
				val3.dimWhenClose = dimGameMusic.Value && !emote.keepGameMusic;
				val3.stopWhenMove = !allowMovement.Value;
				val3.stopWhenAttack = true;
				val3.visible = true;
				val3.syncAnim = true;
				CustomEmotesAPI.AddCustomAnimation(val3);
				byName[emote.name] = emote;
				bool flag = CustomEmotesAPI.allClipNames.Contains(emote.name);
				Log.LogInfo((object)string.Format("Registered \"{0}\" ({1:0.00} s, humanoid={2}, in emote list: {3})", emote.name, val2.length, val2.humanMotion, flag ? "yes" : "NO"));
			}
		}

		private static void ApplyEmoteSettings()
		{
			try
			{
				IDictionary dictionary = (IDictionary)animClipsField.GetValue(null);
				Emote[] array = emotes;
				foreach (Emote emote in array)
				{
					if (dictionary != null && dictionary.Contains(emote.name))
					{
						stopOnMoveField.SetValue(dictionary[emote.name], !allowMovement.Value);
						dimField.SetValue(dictionary[emote.name], dimGameMusic.Value && !emote.keepGameMusic);
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Couldn't update the emote settings: " + ex));
			}
		}

		private static void OnAnimChanged(string newAnimation, BoneMapper mapper)
		{
			if (!Object.op_Implicit((Object)(object)mapper) || !byName.TryGetValue(newAnimation, out var value))
			{
				return;
			}
			float num = (syncDance.Value ? (value.songBPM / value.danceBPM) : 1f);
			mapper.SetAnimationSpeed(num);
			CustomAnimationClip currentClip = mapper.currentClip;
			if (currentClip == null || !currentClip.syncronizeAnimation || !Object.op_Implicit((Object)(object)mapper.a2) || currentClip.syncPos >= CustomAnimationClip.syncTimer.Count)
			{
				return;
			}
			if (value.oneShot)
			{
				MusicPlayer.Restart++;
				return;
			}
			float length = currentClip.clip[0].length;
			if (length > 0f)
			{
				mapper.a2.Play("Loop", -1, CustomAnimationClip.syncTimer[currentClip.syncPos] * num % length / length);
			}
		}

		private void Update()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			List<BoneMapper> list = allMappersField.GetValue(null) as List<BoneMapper>;
			Camera main = Camera.main;
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null);
			Vector3 val2 = (Object.op_Implicit((Object)(object)val) ? val.corePosition : (Object.op_Implicit((Object)(object)main) ? ((Component)main).transform.position : Vector3.zero));
			float num = -1f;
			float num2 = 0f;
			Emote emote = null;
			trailing.Clear();
			chaotic.Clear();
			holding.Clear();
			straightening.Clear();
			heading.Clear();
			stringing.Clear();
			if (list != null)
			{
				foreach (BoneMapper item in list)
				{
					if (!Object.op_Implicit((Object)(object)item) || !byName.TryGetValue(((string)clipNameField.GetValue(item)) ?? "", out var value))
					{
						continue;
					}
					object? value2 = emoteAnimatorField.GetValue(item);
					Animator val3 = (Animator)((value2 is Animator) ? value2 : null);
					if (!Object.op_Implicit((Object)(object)val3) || !((Behaviour)val3).enabled || ((!Object.op_Implicit((Object)(object)item.mapperBody) || !item.mapperBody.isPlayerControlled) && !AlliesEmote()))
					{
						continue;
					}
					if (value.afterimages != null && (afterimages.Value || value.afterimages != Afterimages.Knight) && (!value.afterimages.playersOnly || (Object.op_Implicit((Object)(object)item.mapperBody) && item.mapperBody.isPlayerControlled)))
					{
						trailing.Add((item, value.afterimages));
					}
					if (value.chaos != null)
					{
						chaotic.Add((item, value.chaos));
					}
					if (value.props != null && Object.op_Implicit((Object)(object)item.mapperBody))
					{
						Props.Prop[] props = value.props;
						foreach (Props.Prop prop in props)
						{
							if (prop.enabled.Value && (prop.allies || item.mapperBody.isPlayerControlled))
							{
								holding.Add((item, prop));
							}
						}
					}
					if (value.straight != null)
					{
						straightening.Add((item, value.straight));
					}
					float? headDown = value.headDown;
					if (headDown.HasValue)
					{
						float valueOrDefault = headDown.GetValueOrDefault();
						heading.Add((item, valueOrDefault));
					}
					if (value.strings && neoStrings.Value && Object.op_Implicit((Object)(object)item.mapperBody) && item.mapperBody.isPlayerControlled)
					{
						stringing.Add(item);
					}
					if (value.track == null)
					{
						continue;
					}
					Vector3 position = ((Component)item).transform.position;
					float num3 = Vector3.Distance(val2, position);
					float num4 = Mathf.Max(0f, fullVolumeRange.Value);
					float num5 = Mathf.Max(num4 + 0.01f, hearingRange.Value);
					float num6 = ((num3 <= num4) ? 1f : Mathf.Clamp01(1f - (num3 - num4) / (num5 - num4)));
					if (!(num6 <= num))
					{
						num = num6;
						emote = value;
						float num7;
						if (!Object.op_Implicit((Object)(object)main) || !(num3 > 1f))
						{
							num7 = 0f;
						}
						else
						{
							Vector3 val4 = position - ((Component)main).transform.position;
							num7 = Vector3.Dot(((Vector3)(ref val4)).normalized, ((Component)main).transform.right) * 0.35f;
						}
						num2 = num7;
					}
				}
			}
			MusicPlayer.Paused = PauseManager.isPaused;
			MusicPlayer.Wanted = emote != null;
			if (emote != null)
			{
				MusicPlayer.Song = emote.track;
				float num8 = num * 1.38f * Mathf.Max(0f, volume.Value) * GameVolume("volume_master") * GameVolume("volume_sfx") * EmotesVolume();
				MusicPlayer.TargetLeft = num8 * Mathf.Min(1f, 1f - num2);
				MusicPlayer.TargetRight = num8 * Mathf.Min(1f, 1f + num2);
			}
		}

		private static float EmotesVolume()
		{
			try
			{
				return (emotesVolumeField?.GetValue(null) is ConfigEntry<float> val) ? Mathf.Clamp01(val.Value / 100f) : 1f;
			}
			catch
			{
				return 1f;
			}
		}

		private static float GameVolume(string name)
		{
			try
			{
				BaseConVar val = (Object.op_Implicit((Object)(object)Console.instance) ? Console.instance.FindConVar(name) : null);
				if (val != null && float.TryParse(val.GetString(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
				{
					return Mathf.Clamp01(result / 100f);
				}
			}
			catch
			{
			}
			return 1f;
		}
	}
	internal sealed class Chain
	{
		public HumanBodyBones upper;

		public HumanBodyBones lower;

		public HumanBodyBones end;

		public Vector3? aim;

		public Vector3? aimLower;
	}
	internal static class Joints
	{
		private static readonly Dictionary<BoneMapper, Dictionary<Transform, Transform>> pinned = new Dictionary<BoneMapper, Dictionary<Transform, Transform>>();

		private static readonly List<BoneMapper> gone = new List<BoneMapper>();

		private static readonly Dictionary<BoneMapper, (Transform head, Transform mesh, Quaternion bind)> heads = new Dictionary<BoneMapper, (Transform, Transform, Quaternion)>();

		public static void Straighten(List<(BoneMapper mapper, Chain[] chains)> dancers)
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0280: 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_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: 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_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: 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_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: 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_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			foreach (BoneMapper key in pinned.Keys)
			{
				if (!Object.op_Implicit((Object)(object)key))
				{
					gone.Add(key);
				}
			}
			foreach (BoneMapper item3 in gone)
			{
				pinned.Remove(item3);
			}
			gone.Clear();
			foreach (var dancer in dancers)
			{
				BoneMapper item = dancer.mapper;
				Chain[] item2 = dancer.chains;
				Animator val = (Object.op_Implicit((Object)(object)item) ? item.a2 : null);
				if (!Object.op_Implicit((Object)(object)val) || !val.isHuman)
				{
					continue;
				}
				Dictionary<Transform, Transform> bones = Pinned(item);
				CharacterBody mapperBody = item.mapperBody;
				Vector3 val2 = ((Object.op_Implicit((Object)(object)mapperBody) && Object.op_Implicit((Object)(object)mapperBody.characterDirection)) ? mapperBody.characterDirection.forward : ((Component)item).transform.forward);
				val2.y = 0f;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
				{
					val2 = Vector3.forward;
				}
				((Vector3)(ref val2)).Normalize();
				Vector3 val3 = Vector3.Cross(Vector3.up, val2);
				Chain[] array = item2;
				foreach (Chain chain in array)
				{
					Transform val4 = Model(bones, val, chain.upper);
					Transform val5 = Model(bones, val, chain.lower);
					Transform val6 = Model(bones, val, chain.end);
					if (!Object.op_Implicit((Object)(object)val4) || !Object.op_Implicit((Object)(object)val5) || !Object.op_Implicit((Object)(object)val6))
					{
						continue;
					}
					Vector3 val7 = val5.position - val4.position;
					Vector3? aim = chain.aim;
					if (aim.HasValue)
					{
						Vector3 valueOrDefault = aim.GetValueOrDefault();
						if (((Vector3)(ref val7)).sqrMagnitude > 1E-08f)
						{
							Vector3 val8 = val3 * valueOrDefault.x + val2 * valueOrDefault.y + Vector3.up * valueOrDefault.z;
							val4.rotation = Quaternion.FromToRotation(val7, val8) * val4.rotation;
							val7 = val5.position - val4.position;
						}
					}
					Vector3 val9 = val6.position - val5.position;
					aim = chain.aimLower;
					if (aim.HasValue)
					{
						Vector3 valueOrDefault2 = aim.GetValueOrDefault();
						val7 = val3 * valueOrDefault2.x + val2 * valueOrDefault2.y + Vector3.up * valueOrDefault2.z;
					}
					if (!(((Vector3)(ref val7)).sqrMagnitude < 1E-08f) && !(((Vector3)(ref val9)).sqrMagnitude < 1E-08f))
					{
						val5.rotation = Quaternion.FromToRotation(val9, val7) * val5.rotation;
					}
				}
			}
		}

		public static void LevelHeads(List<(BoneMapper mapper, float down)> dancers)
		{
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: 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_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			foreach (BoneMapper key in heads.Keys)
			{
				if (!Object.op_Implicit((Object)(object)key))
				{
					gone.Add(key);
				}
			}
			foreach (BoneMapper item in gone)
			{
				heads.Remove(item);
			}
			gone.Clear();
			foreach (var (val, num) in dancers)
			{
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.a2))
				{
					continue;
				}
				if (!heads.TryGetValue(val, out (Transform, Transform, Quaternion) value) || !Object.op_Implicit((Object)(object)value.Item1) || !Object.op_Implicit((Object)(object)value.Item2))
				{
					value = (heads[val] = BindHead(val));
				}
				if (Object.op_Implicit((Object)(object)value.Item1) && Object.op_Implicit((Object)(object)value.Item2))
				{
					CharacterBody mapperBody = val.mapperBody;
					Vector3 val2 = ((Object.op_Implicit((Object)(object)mapperBody) && Object.op_Implicit((Object)(object)mapperBody.characterDirection)) ? mapperBody.characterDirection.forward : ((Component)val).transform.forward);
					val2.y = 0f;
					if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f))
					{
						Vector3 val3 = Vector3.Cross(Vector3.up, ((Vector3)(ref val2)).normalized);
						value.Item1.rotation = Quaternion.AngleAxis(num, val3) * value.Item2.rotation * value.Item3;
					}
				}
			}
		}

		private static (Transform, Transform, Quaternion) BindHead(BoneMapper m)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ModelBone(m, (HumanBodyBones)10);
			Transform val2 = ((Object.op_Implicit((Object)(object)m.mapperBody) && Object.op_Implicit((Object)(object)m.mapperBody.modelLocator)) ? m.mapperBody.modelLocator.modelTransform : null);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
			{
				return (null, null, Quaternion.identity);
			}
			SkinnedMeshRenderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val3 in componentsInChildren)
			{
				Transform[] bones = val3.bones;
				Mesh sharedMesh = val3.sharedMesh;
				if (bones != null && Object.op_Implicit((Object)(object)sharedMesh))
				{
					int num = Array.IndexOf(bones, val);
					if (num >= 0 && num < sharedMesh.bindposes.Length)
					{
						Matrix4x4 inverse = ((Matrix4x4)(ref sharedMesh.bindposes[num])).inverse;
						return (val, ((Component)val3).transform, Quaternion.LookRotation(Vector4.op_Implicit(((Matrix4x4)(ref inverse)).GetColumn(2)), Vector4.op_Implicit(((Matrix4x4)(ref inverse)).GetColumn(1))));
					}
				}
			}
			return (val, null, Quaternion.identity);
		}

		public static Transform ModelBone(BoneMapper m, HumanBodyBones b)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)m) || !Object.op_Implicit((Object)(object)m.a2))
			{
				return null;
			}
			return Model(Pinned(m), m.a2, b);
		}

		private static Transform Model(Dictionary<Transform, Transform> bones, Animator anim, HumanBodyBones b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Transform boneTransform = anim.GetBoneTransform(b);
			if (!Object.op_Implicit((Object)(object)boneTransform) || !bones.TryGetValue(boneTransform, out var value))
			{
				return null;
			}
			return value;
		}

		private static Dictionary<Transform, Transform> Pinned(BoneMapper m)
		{
			if (pinned.TryGetValue(m, out var value) && value.Count > 0)
			{
				return value;
			}
			value = new Dictionary<Transform, Transform>();
			Transform val = ((Object.op_Implicit((Object)(object)m.mapperBody) && Object.op_Implicit((Object)(object)m.mapperBody.modelLocator)) ? m.mapperBody.modelLocator.modelTransform : ((Component)m).transform.parent);
			if (Object.op_Implicit((Object)(object)val))
			{
				EmoteConstraint[] componentsInChildren = ((Component)val).GetComponentsInChildren<EmoteConstraint>(true);
				foreach (EmoteConstraint val2 in componentsInChildren)
				{
					if (Object.op_Implicit((Object)(object)val2.emoteBone) && Object.op_Implicit((Object)(object)val2.originalBone))
					{
						value[val2.emoteBone] = val2.originalBone;
					}
				}
			}
			return pinned[m] = value;
		}
	}
	[DefaultExecutionOrder(32000)]
	internal class LatePose : MonoBehaviour
	{
		private void LateUpdate()
		{
			DeltaruneEmotesPlugin.AfterPose();
		}
	}
	internal sealed class Track
	{
		public readonly byte[] data;

		public readonly int frames;

		public readonly int leftStart;

		public readonly int rightStart;

		public bool oneShot;

		private Track(byte[] data, int frames, int leftStart, int rightStart)
		{
			this.data = data;
			this.frames = frames;
			this.leftStart = leftStart;
			this.rightStart = rightStart;
		}

		public static Track Load(byte[] sdm)
		{
			if (sdm == null || sdm.Length < 14 || sdm[0] != 83 || sdm[1] != 68 || sdm[2] != 77 || sdm[3] != 65)
			{
				return null;
			}
			int num = BitConverter.ToInt32(sdm, 4);
			int num2 = BitConverter.ToInt16(sdm, 8);
			int num3 = BitConverter.ToInt32(sdm, 10);
			int num4 = (num3 + 1) / 2;
			if (num != 44100 || num2 < 1 || sdm.Length < 14 + num2 * num4)
			{
				return null;
			}
			return new Track(sdm, num3, 14, (num2 > 1) ? (14 + num4) : 14);
		}
	}
	internal static class MusicPlayer
	{
		private struct WaveFormat
		{
			public short wFormatTag;

			public short nChannels;

			public int nSamplesPerSec;

			public int nAvgBytesPerSec;

			public short nBlockAlign;

			public short wBitsPerSample;

			public short cbSize;
		}

		private struct WaveHeader
		{
			public IntPtr lpData;

			public int dwBufferLength;

			public int dwBytesRecorded;

			public IntPtr dwUser;

			public int dwFlags;

			public int dwLoops;

			public IntPtr lpNext;

			public IntPtr reserved;
		}

		private class Channel
		{
			public int start;

			public int value;

			public int index;

			public void Reset(int at)
			{
				start = at;
				value = (index = 0);
			}

			public short Next(byte[] data, int frame)
			{
				int num = data[start + (frame >> 1)];
				int num2 = (((frame & 1) == 0) ? (num >> 4) : (num & 0xF));
				int num3 = Steps[index];
				index = Math.Min(88, Math.Max(0, index + IndexStep[num2]));
				int num4 = num3 >> 3;
				if ((num2 & 4) != 0)
				{
					num4 += num3;
				}
				if ((num2 & 2) != 0)
				{
					num4 += num3 >> 1;
				}
				if ((num2 & 1) != 0)
				{
					num4 += num3 >> 2;
				}
				value = (((num2 & 8) != 0) ? (value - num4) : (value + num4));
				value = Math.Max(-32768, Math.Min(32767, value));
				return (short)value;
			}
		}

		public const int Rate = 44100;

		private const int BufferFrames = 2205;

		private const int BufferCount = 8;

		private const int WAVE_MAPPER = -1;

		private const int CALLBACK_EVENT = 327680;

		private const int WHDR_DONE = 1;

		private static readonly int headerSize = Marshal.SizeOf(typeof(WaveHeader));

		private static readonly int flagsOffset = (int)Marshal.OffsetOf(typeof(WaveHeader), "dwFlags");

		private static readonly short[] Steps = new short[89]
		{
			7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
			19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
			50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
			130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
			337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
			876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
			2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
			5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
			15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
		};

		private static readonly sbyte[] IndexStep = new sbyte[16]
		{
			-1, -1, -1, -1, 2, 4, 6, 8, -1, -1,
			-1, -1, 2, 4, 6, 8
		};

		public static volatile bool Wanted;

		public static volatile bool Paused;

		public static volatile Track Song;

		public static volatile float TargetLeft;

		public static volatile float TargetRight;

		public static volatile int Restart;

		internal static long FramesWritten;

		internal static volatile bool DeviceOpen;

		internal static volatile Track Playing;

		private static readonly Channel left = new Channel();

		private static readonly Channel right = new Channel();

		private static Thread thread;

		private static volatile bool quit;

		[DllImport("winmm.dll")]
		private static extern int waveOutOpen(out IntPtr handle, int deviceId, ref WaveFormat format, IntPtr callback, IntPtr instance, int flags);

		[DllImport("winmm.dll")]
		private static extern int waveOutPrepareHeader(IntPtr handle, IntPtr header, int size);

		[DllImport("winmm.dll")]
		private static extern int waveOutWrite(IntPtr handle, IntPtr header, int size);

		[DllImport("winmm.dll")]
		private static extern int waveOutUnprepareHeader(IntPtr handle, IntPtr header, int size);

		[DllImport("winmm.dll")]
		private static extern int waveOutPause(IntPtr handle);

		[DllImport("winmm.dll")]
		private static extern int waveOutRestart(IntPtr handle);

		[DllImport("winmm.dll")]
		private static extern int waveOutReset(IntPtr handle);

		[DllImport("winmm.dll")]
		private static extern int waveOutClose(IntPtr handle);

		public static void Start()
		{
			if (thread == null)
			{
				quit = false;
				thread = new Thread(Run)
				{
					IsBackground = true,
					Name = "DeltaruneEmotes"
				};
				thread.Start();
			}
		}

		public static void Stop()
		{
			quit = true;
			thread?.Join(500);
			thread = null;
		}

		private static void Run()
		{
			AutoResetEvent autoResetEvent = new AutoResetEvent(initialState: false);
			IntPtr[] array = new IntPtr[8];
			IntPtr[] array2 = new IntPtr[8];
			bool[] array3 = new bool[8];
			byte[] array4 = new byte[8820];
			for (int i = 0; i < 8; i++)
			{
				array[i] = Marshal.AllocHGlobal(headerSize);
				array2[i] = Marshal.AllocHGlobal(array4.Length);
			}
			IntPtr handle = IntPtr.Zero;
			bool flag = false;
			int num = 0;
			int restart = Restart;
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			try
			{
				while (!quit)
				{
					autoResetEvent.WaitOne(20);
					Track song = Song;
					bool flag2 = Wanted && song != null;
					if (handle == IntPtr.Zero)
					{
						if (!flag2)
						{
							continue;
						}
						WaveFormat format = new WaveFormat
						{
							wFormatTag = 1,
							nChannels = 2,
							nSamplesPerSec = 44100,
							wBitsPerSample = 16,
							nBlockAlign = 4,
							nAvgBytesPerSec = 176400
						};
						if (waveOutOpen(out handle, -1, ref format, autoResetEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, 327680) != 0)
						{
							handle = IntPtr.Zero;
							Thread.Sleep(1000);
							continue;
						}
						for (int j = 0; j < 8; j++)
						{
							Marshal.StructureToPtr(new WaveHeader
							{
								lpData = array2[j],
								dwBufferLength = array4.Length
							}, array[j], fDeleteOld: false);
							waveOutPrepareHeader(handle, array[j], headerSize);
							array3[j] = false;
						}
						Playing = null;
						num2 = (num3 = (num4 = 0f));
						flag = false;
						DeviceOpen = true;
					}
					if (Playing != song && (Playing == null || num2 <= 0f) && song != null)
					{
						Playing = song;
						num = 0;
						left.Reset(song.leftStart);
						right.Reset(song.rightStart);
					}
					Track playing = Playing;
					if (playing != song)
					{
						flag2 = false;
					}
					if (playing != null && playing.oneShot && (restart != Restart || (!flag2 && num2 <= 0f)))
					{
						num = 0;
						left.Reset(playing.leftStart);
						right.Reset(playing.rightStart);
					}
					restart = Restart;
					if (Paused != flag)
					{
						flag = Paused;
						if (flag)
						{
							waveOutPause(handle);
						}
						else
						{
							waveOutRestart(handle);
						}
					}
					bool flag3 = false;
					for (int k = 0; k < 8; k++)
					{
						if (array3[k] && (Marshal.ReadInt32(array[k], flagsOffset) & 1) == 0)
						{
							flag3 = true;
							continue;
						}
						array3[k] = false;
						if (playing == null || (!flag2 && num2 <= 0f))
						{
							continue;
						}
						num2 = (flag2 ? 1f : 0f);
						float num5 = TargetLeft * num2;
						float num6 = TargetRight * num2;
						for (int l = 0; l < 2205; l++)
						{
							float num7 = ((float)l + 1f) / 2205f;
							float num8 = num3 + (num5 - num3) * num7;
							float num9 = num4 + (num6 - num4) * num7;
							if (playing.oneShot && num >= playing.frames)
							{
								num8 = (num9 = 0f);
							}
							int val = 0;
							int val2 = 0;
							if (num < playing.frames)
							{
								val = (int)((float)left.Next(playing.data, num) * num8);
								val2 = (int)((float)right.Next(playing.data, num) * num9);
								num++;
							}
							if (num >= playing.frames && !playing.oneShot)
							{
								num = 0;
								left.Reset(playing.leftStart);
								right.Reset(playing.rightStart);
							}
							val = Math.Max(-32768, Math.Min(32767, val));
							val2 = Math.Max(-32768, Math.Min(32767, val2));
							array4[l * 4] = (byte)val;
							array4[l * 4 + 1] = (byte)(val >> 8);
							array4[l * 4 + 2] = (byte)val2;
							array4[l * 4 + 3] = (byte)(val2 >> 8);
						}
						num3 = num5;
						num4 = num6;
						Marshal.Copy(array4, 0, array2[k], array4.Length);
						waveOutWrite(handle, array[k], headerSize);
						flag3 = (array3[k] = true);
						FramesWritten += 2205L;
					}
					if (!flag2 && num2 <= 0f && !flag3)
					{
						Close(ref handle, array);
					}
				}
			}
			catch (Exception ex)
			{
				DeltaruneEmotesPlugin.Log.LogWarning((object)("Music stream stopped: " + ex));
			}
			finally
			{
				Close(ref handle, array);
				for (int m = 0; m < 8; m++)
				{
					Marshal.FreeHGlobal(array[m]);
					Marshal.FreeHGlobal(array2[m]);
				}
				autoResetEvent.Close();
			}
		}

		private static void Close(ref IntPtr handle, IntPtr[] headers)
		{
			if (!(handle == IntPtr.Zero))
			{
				waveOutReset(handle);
				foreach (IntPtr header in headers)
				{
					waveOutUnprepareHeader(handle, header, headerSize);
				}
				waveOutClose(handle);
				handle = IntPtr.Zero;
				DeviceOpen = false;
			}
		}
	}
	internal static class Props
	{
		public sealed class Prop
		{
			public string asset;

			public string material;

			public Color? outline;

			public HumanBodyBones hand = (HumanBodyBones)18;

			public HumanBodyBones? throughHand;

			public float lengthPerHeight;

			public float pitch;

			public bool behind;

			public float flutter;

			public bool upright;

			public Vector3 pivot;

			public float flicker;

			public bool seat;

			public bool onModel;

			public float companion;

			public float onHead;

			public float spin;

			public Vector3 top;

			public Prop[] hopVia;

			public float hopBeat;

			public bool allies;

			public ConfigEntry<bool> enabled;

			public Mesh mesh;

			public Material mat;
		}

		private sealed class Held
		{
			public Prop prop;

			public GameObject go;

			public MeshRenderer renderer;

			public MaterialPropertyBlock block;

			public float born;

			public Transform head;

			public Vector3 headTop;

			public int samples;

			public Transform model;

			public Vector3 modelScale;
		}

		private const float OutlinePerHeight = 0.0065f;

		public static readonly Prop Sword = new Prop
		{
			asset = "BlackKnife",
			lengthPerHeight = 0.8625f,
			pitch = 10f
		};

		public static readonly Prop Cape = new Prop
		{
			asset = "FloweryCape",
			lengthPerHeight = 0.62f,
			pitch = 8f,
			behind = true,
			flutter = 0.08f,
			hand = (HumanBodyBones)17
		};

		public static readonly Prop Staff = new Prop
		{
			asset = "PinkStaff",
			material = "VertexColorOutline",
			outline = new Color(0.3f, 0.08f, 0.18f),
			lengthPerHeight = 0.85f,
			hand = (HumanBodyBones)17,
			throughHand = (HumanBodyBones)18
		};

		public static readonly Prop Hammer = new Prop
		{
			asset = "GersonHammer",
			material = "VertexColorOutline",
			outline = new Color(0.1f, 0.08f, 0.07f),
			lengthPerHeight = 1.05f,
			behind = true,
			pitch = -4f
		};

		public static readonly Prop Chair = new Prop
		{
			asset = "QueenChair",
			material = "VertexColorOutline",
			outline = new Color(0.06f, 0.06f, 0.22f),
			lengthPerHeight = 0.5688f,
			hand = (HumanBodyBones)0,
			upright = true,
			seat = true
		};

		public static readonly Prop Flame = new Prop
		{
			asset = "QueenFlame",
			material = "VertexColorOutline",
			outline = new Color(0.45f, 0.08f, 0.02f),
			lengthPerHeight = 0.14f,
			hand = (HumanBodyBones)0,
			upright = true,
			seat = true,
			pivot = new Vector3(0f, 0.02f, -0.3f),
			flicker = 0.12f
		};

		public static readonly Prop Glass = new Prop
		{
			asset = "QueenGlass",
			material = "VertexColorOutline",
			outline = new Color(0.08f, 0.12f, 0.3f),
			lengthPerHeight = 0.082f,
			upright = true,
			onModel = true,
			pivot = new Vector3(0f, 0.01f, 0.045f)
		};

		public static readonly Prop KrisSword = new Prop
		{
			asset = "KrisSword",
			material = "VertexColorOutline",
			outline = new Color(0.25f, 0.05f, 0.1f),
			lengthPerHeight = 0.55f,
			pitch = -38f
		};

		public static readonly Prop Susie = new Prop
		{
			asset = "PartySusie",
			material = "VertexColorOutline",
			outline = new Color(0.06f, 0.03f, 0.08f),
			lengthPerHeight = 1.151f,
			hand = (HumanBodyBones)0,
			companion = 1.15f,
			pivot = new Vector3(-0.62f, -0.05f, 0f)
		};

		public static readonly Prop Ralsei = new Prop
		{
			asset = "PartyRalsei",
			material = "VertexColorOutline",
			outline = new Color(0.06f, 0.08f, 0.06f),
			lengthPerHeight = 0.47f,
			hand = (HumanBodyBones)0,
			companion = 0.95f,
			pivot = new Vector3(0.58f, -0.05f, 0f)
		};

		public static readonly Prop Aqua = new Prop
		{
			asset = "PetalAqua",
			material = "VertexColorOutline",
			outline = new Color(0.02f, 0.18f, 0.2f),
			lengthPerHeight = 0.538f,
			hand = (HumanBodyBones)10,
			onHead = 0.34f,
			spin = 1f,
			allies = true
		};

		public static readonly Prop SethBack = new Prop
		{
			asset = "PartySeth",
			material = "VertexColorOutline",
			outline = new Color(0.12f, 0.04f, 0.16f),
			lengthPerHeight = 0.415f,
			hand = (HumanBodyBones)0,
			companion = 1f,
			pivot = new Vector3(-0.55f, -0.75f, 0f),
			top = new Vector3(0.047f, 0.067f, 0.976f)
		};

		public static readonly Prop SusieBack = new Prop
		{
			asset = "PetalSusie",
			material = "VertexColorOutline",
			outline = new Color(0.06f, 0.03f, 0.08f),
			lengthPerHeight = 0.593f,
			hand = (HumanBodyBones)0,
			companion = 1.15f,
			pivot = new Vector3(0.6f, -0.75f, 0f),
			top = new Vector3(0.053f, 0.135f, 0.972f)
		};

		public static readonly Prop AquaHops = new Prop
		{
			asset = "PetalAqua",
			material = "VertexColorOutline",
			outline = new Color(0.02f, 0.18f, 0.2f),
			lengthPerHeight = 0.538f,
			hand = (HumanBodyBones)10,
			onHead = 0.4f,
			spin = 1.2083334f,
			hopVia = new Prop[2] { SethBack, SusieBack },
			hopBeat = 0.41379312f
		};

		private static readonly Prop[] all = new Prop[14]
		{
			Sword, Cape, Staff, Hammer, Chair, Flame, Glass, KrisSword, Susie, Ralsei,
			Aqua, SethBack, SusieBack, AquaHops
		};

		private static readonly Prop[] hoppers = new Prop[1] { AquaHops };

		private const float HopArc = 0.5f;

		private const float SquashTime = 0.25f;

		private const float SquashDepth = 0.12f;

		private const float HopAir = 0.96f;

		private static readonly Dictionary<BoneMapper, float> steady = new Dictionary<BoneMapper, float>();

		private static readonly Dictionary<(BoneMapper, Prop), Held> held = new Dictionary<(BoneMapper, Prop), Held>();

		private static readonly List<(BoneMapper, Prop)> gone = new List<(BoneMapper, Prop)>();

		private static readonly int outlineId = Shader.PropertyToID("_OutlineWorld");

		private static readonly int flutterId = Shader.PropertyToID("_FlutterAmp");

		private static readonly int outlineColorId = Shader.PropertyToID("_OutlineColor");

		private static Mesh baked;

		private static readonly List<Vector3> verts = new List<Vector3>();

		private const float SeatPerBody = 1.352f;

		private const float SeatPerHipWidth = 3.8f;

		private const float SeatBelowHips = 0.05f;

		private const float BackBehindChest = 0.1f;

		public static void Load(AssetBundle bundle)
		{
			Prop[] array = all;
			foreach (Prop prop in array)
			{
				GameObject val = bundle.LoadAsset<GameObject>(prop.asset);
				object mesh;
				if (!Object.op_Implicit((Object)(object)val))
				{
					mesh = null;
				}
				else
				{
					MeshFilter componentInChildren = val.GetComponentInChildren<MeshFilter>();
					mesh = ((componentInChildren != null) ? componentInChildren.sharedMesh : null);
				}
				prop.mesh = (Mesh)mesh;
				prop.mat = bundle.LoadAsset<Material>(prop.material ?? prop.asset);
				if (!Object.op_Implicit((Object)(object)prop.mesh) || !Object.op_Implicit((Object)(object)prop.mat))
				{
					DeltaruneEmotesPlugin.Log.LogError((object)("The bundle has no " + prop.asset + " mesh/material; that prop won't show."));
				}
			}
			Strings.material = bundle.LoadAsset<Material>("VertexColorOutline");
		}

		public static float DancerHeight(BoneMapper m)
		{
			if (!Object.op_Implicit((Object)(object)m) || !steady.TryGetValue(m, out var value))
			{
				float? num = ModelHeight(m);
				if (!num.HasValue)
				{
					if (!Object.op_Implicit((Object)(object)m) || !Object.op_Implicit((Object)(object)m.a2))
					{
						return 1.8f;
					}
					return Height(m.a2);
				}
				return num.GetValueOrDefault();
			}
			return value;
		}

		public static Renderer RendererFor(BoneMapper m)
		{
			if (Object.op_Implicit((Object)(object)m))
			{
				foreach (KeyValuePair<(BoneMapper, Prop), Held> item in held)
				{
					if ((Object)(object)item.Key.Item1 == (Object)(object)m && Object.op_Implicit((Object)(object)item.Value.go) && item.Value.go.activeSelf)
					{
						return (Renderer)(object)item.Value.renderer;
					}
				}
			}
			return null;
		}

		public static void Update(List<(BoneMapper mapper, Prop prop)> holding)
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: 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_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: 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_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_047c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_052b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0530: Unknown result type (might be due to invalid IL or missing references)
			//IL_0534: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0514: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_051d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0554: Unknown result type (might be due to invalid IL or missing references)
			//IL_0559: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0562: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_056e: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0584: Unknown result type (might be due to invalid IL or missing references)
			//IL_0592: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_059c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05be: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0635: Unknown result type (might be due to invalid IL or missing references)
			//IL_064a: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<(BoneMapper, Prop), Held> item5 in Props.held)
			{
				if (!Object.op_Implicit((Object)(object)item5.Key.Item1) || !holding.Contains(item5.Key))
				{
					gone.Add(item5.Key);
				}
			}
			foreach (var item6 in gone)
			{
				if (Object.op_Implicit((Object)(object)Props.held[item6].go))
				{
					Object.Destroy((Object)(object)Props.held[item6].go);
				}
				if (Object.op_Implicit((Object)(object)Props.held[item6].model))
				{
					Props.held[item6].model.localScale = Props.held[item6].modelScale;
				}
				if (item6.Item2.hopVia != null)
				{
					steady.Remove(item6.Item1);
				}
				Props.held.Remove(item6);
			}
			gone.Clear();
			foreach (var item7 in holding)
			{
				BoneMapper item = item7.mapper;
				Prop item2 = item7.prop;
				Animator val = (Object.op_Implicit((Object)(object)item) ? item.a2 : null);
				CharacterBody val2 = (Object.op_Implicit((Object)(object)item) ? item.mapperBody : null);
				Transform val3 = ((Object.op_Implicit((Object)(object)val) && val.isHuman) ? val.GetBoneTransform(item2.hand) : null);
				if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)item2.mesh) || !Object.op_Implicit((Object)(object)item2.mat))
				{
					continue;
				}
				if (!Props.held.TryGetValue((item, item2), out var value) || !Object.op_Implicit((Object)(object)value.go))
				{
					value = (Props.held[(item, item2)] = Create(item2));
				}
				Vector3 val4 = (Object.op_Implicit((Object)(object)val2.characterDirection) ? val2.characterDirection.forward : ((Component)val2).transform.forward);
				val4.y = 0f;
				if (((Vector3)(ref val4)).sqrMagnitude < 0.0001f)
				{
					val4 = Vector3.forward;
				}
				((Vector3)(ref val4)).Normalize();
				Bounds bounds;
				if (item2.seat)
				{
					(Vector3, float)? tuple = Seat(item, val4);
					if (tuple.HasValue)
					{
						(Vector3, float) valueOrDefault = tuple.GetValueOrDefault();
						Vector3 item3 = valueOrDefault.Item1;
						float item4 = valueOrDefault.Item2;
						Quaternion val5 = Quaternion.LookRotation(val4, Vector3.up);
						value.go.transform.SetPositionAndRotation(item3 + val5 * new Vector3(item2.pivot.x, item2.pivot.z, item2.pivot.y) * item4, val5);
						float num = ((item2.flicker > 0f) ? (1f + item2.flicker * (2f * Mathf.PerlinNoise(Time.time * 14f, (float)((Object)item).GetInstanceID() * 0.37f) - 1f)) : 1f);
						Transform transform = value.go.transform;
						Vector3 one = Vector3.one;
						float num2 = num * item4 * item2.lengthPerHeight;
						bounds = item2.mesh.bounds;
						transform.localScale = one * (num2 / Mathf.Max(0.01f, ((Bounds)(ref bounds)).size.z));
						Finish(value, val2, item2, item4 / 0.88f);
						continue;
					}
				}
				if (item2.companion > 0f)
				{
					Companion(item, val2, item2, value, val4);
					continue;
				}
				if (item2.hopVia != null)
				{
					HopOnHeads(item, val2, item2, value, val4);
					continue;
				}
				if (item2.onHead > 0f)
				{
					OnHead(item, val2, item2, value, val4);
					continue;
				}
				float num3;
				if (item2.onModel)
				{
					Transform val6 = Joints.ModelBone(item, item2.hand);
					if (Object.op_Implicit((Object)(object)val6))
					{
						val3 = val6;
					}
					num3 = ModelHeight(item) ?? Height(val);
				}
				else
				{
					num3 = Height(val);
				}
				Vector3 val7 = (item2.behind ? (-val4) : val4);
				Vector3 val8 = Quaternion.AngleAxis(item2.pitch, Vector3.Cross(Vector3.up, val7)) * val7;
				HumanBodyBones? throughHand = item2.throughHand;
				object obj;
				if (throughHand.HasValue)
				{
					HumanBodyBones valueOrDefault2 = throughHand.GetValueOrDefault();
					obj = val.GetBoneTransform(valueOrDefault2);
				}
				else
				{
					obj = null;
				}
				Transform val9 = (Transform)obj;
				if (Object.op_Implicit((Object)(object)val9))
				{
					Vector3 val10 = val9.position - val3.position;
					if (((Vector3)(ref val10)).sqrMagnitude > 1E-06f)
					{
						val10 = val9.position - val3.position;
						val8 = ((Vector3)(ref val10)).normalized;
					}
				}
				bounds = item2.mesh.bounds;
				float num4 = Mathf.Max(0.01f, ((Bounds)(ref bounds)).size.z);
				Quaternion val11 = Quaternion.LookRotation(item2.upright ? val4 : val8, Vector3.up);
				Vector3 val12 = val3.position + (Vector3.Cross(Vector3.up, val4) * item2.pivot.x + val4 * item2.pivot.y + Vector3.up * item2.pivot.z) * num3;
				value.go.transform.SetPositionAndRotation(val12, val11);
				float num5 = ((item2.flicker > 0f) ? (1f + item2.flicker * (2f * Mathf.PerlinNoise(Time.time * 14f, (float)((Object)item).GetInstanceID() * 0.37f) - 1f)) : 1f);
				value.go.transform.localScale = Vector3.one * (num5 * item2.lengthPerHeight * num3 / num4);
				Finish(value, val2, item2, num3);
			}
		}

		private static void Companion(BoneMapper m, CharacterBody body, Prop prop, Held h, Vector3 facing)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unkn