Decompiled source of All Allies Emote v1.0.0

AllAlliesEmote.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EmotesAPI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using R2API.Networking;
using R2API.Networking.Interfaces;
using RiskOfOptions;
using RiskOfOptions.Options;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

[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 AllAlliesEmote
{
	[BepInPlugin("com.chaz.allalliesemote", "All Allies Emote", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class AllAlliesEmotePlugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action<CharacterBody> <0>__OnBodyStart;

			public static AnimationChanged <1>__OnAnimChanged;
		}

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

		public const string Name = "All Allies Emote";

		public const string Version = "1.0.0";

		private const string EmotesGUID = "com.weliveinasociety.CustomEmotesAPI";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> alliesEmote;

		internal static ConfigEntry<bool> fallbackDance;

		internal static ConfigEntry<bool> allyAudio;

		private void Awake()
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			alliesEmote = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Allies emote with you", true, "When you emote, all of your allies (drones, turrets, item pets...) emote with you. Teammates and their allies are never affected.");
			fallbackDance = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Dance for allies without emotes", true, "Allies that can't be given an emote skeleton (rare: ones without a skinned model) bob and sway to the beat instead.");
			allyAudio = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Ally emote sounds", false, "Let each ally play its own copy of an emote's sound (for emotes whose sound isn't shared). Off, only you are heard.");
			if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
			{
				ModSettings.Register();
			}
			new Harmony("com.chaz.allalliesemote").PatchAll(typeof(AllyAudio));
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate
			{
				try
				{
					AllyRigs.RelinkAll();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Emote skeleton repair failed: " + ex));
				}
			});
			CharacterBody.onBodyStartGlobal += Allies.OnBodyStart;
			object obj = <>O.<1>__OnAnimChanged;
			if (obj == null)
			{
				AnimationChanged val = Allies.OnAnimChanged;
				<>O.<1>__OnAnimChanged = val;
				obj = (object)val;
			}
			CustomEmotesAPI.animChanged += (AnimationChanged)obj;
		}

		private void Update()
		{
			if (Object.op_Implicit((Object)(object)Run.instance))
			{
				Allies.Tick();
			}
		}

		private void LateUpdate()
		{
			if (Object.op_Implicit((Object)(object)Run.instance))
			{
				Allies.KeepInStep();
			}
		}
	}
	internal static class AllyAudio
	{
		[HarmonyPatch(typeof(AkSoundEngine), "PostEvent", new Type[]
		{
			typeof(string),
			typeof(GameObject)
		})]
		[HarmonyPrefix]
		private static bool PostEvent(GameObject __1, ref uint __result)
		{
			if (Object.op_Implicit((Object)(object)__1) && !AllAlliesEmotePlugin.allyAudio.Value && Allies.silenced.Contains(__1))
			{
				__result = 0u;
				return false;
			}
			return true;
		}
	}
	internal static class Allies
	{
		private struct Ally
		{
			public CharacterBody body;

			public CharacterMaster owner;

			public BoneMapper mapper;
		}

		private const float ScanInterval = 0.25f;

		private const string TurretTauntGUID = "com.kanggamming.EngineerTurretTaunt";

		internal static readonly HashSet<GameObject> silenced = new HashSet<GameObject>();

		private static readonly List<Ally> allies = new List<Ally>();

		private static readonly Dictionary<CharacterBody, BoneMapper> mappers = new Dictionary<CharacterBody, BoneMapper>();

		private static readonly Dictionary<CharacterBody, (string clip, int start)> sent = new Dictionary<CharacterBody, (string, int)>();

		private static readonly Dictionary<CharacterMaster, (int start, float at)> ownerStarts = new Dictionary<CharacterMaster, (int, float)>();

		private static readonly Dictionary<BoneMapper, int> justStarted = new Dictionary<BoneMapper, int>();

		private static float nextScan;

		private static float MirrorDelay
		{
			get
			{
				if (!Chainloader.PluginInfos.ContainsKey("com.kanggamming.EngineerTurretTaunt"))
				{
					return 0f;
				}
				return 0.2f;
			}
		}

		public static CharacterMaster OwnerOf(CharacterBody body)
		{
			CharacterMaster val = (Object.op_Implicit((Object)(object)body) ? body.master : null);
			if (!Object.op_Implicit((Object)(object)val) || Object.op_Implicit((Object)(object)val.playerCharacterMasterController))
			{
				return null;
			}
			for (int i = 0; i < 8; i++)
			{
				CharacterMaster val2 = (Object.op_Implicit((Object)(object)val.minionOwnership) ? val.minionOwnership.ownerMaster : null);
				if (!Object.op_Implicit((Object)(object)val2))
				{
					return null;
				}
				if (Object.op_Implicit((Object)(object)val2.playerCharacterMasterController))
				{
					return val2;
				}
				val = val2;
			}
			return null;
		}

		public static string ClipOf(CharacterMaster player)
		{
			return ClipOf(MapperOf(Object.op_Implicit((Object)(object)player) ? player.GetBody() : null));
		}

		private static string ClipOf(BoneMapper mapper)
		{
			if (!Object.op_Implicit((Object)(object)mapper) || mapper.currentClip == null || string.IsNullOrEmpty(mapper.currentClipName))
			{
				return "none";
			}
			return mapper.currentClipName;
		}

		private static BoneMapper MapperOf(CharacterBody body)
		{
			if (!Object.op_Implicit((Object)(object)body))
			{
				return null;
			}
			if (mappers.TryGetValue(body, out var value) && Object.op_Implicit((Object)(object)value))
			{
				return value;
			}
			Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
			value = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponentInChildren<BoneMapper>(true) : null);
			if (Object.op_Implicit((Object)(object)value))
			{
				mappers[body] = value;
			}
			return value;
		}

		public static void OnBodyStart(CharacterBody body)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.teamComponent) && (int)body.teamComponent.teamIndex == 1 && (!Object.op_Implicit((Object)(object)body.master) || !Object.op_Implicit((Object)(object)body.master.playerCharacterMasterController)) && !body.isPlayerControlled)
			{
				AllyRigs.ReplaceBroken(body);
				AllyRigs.Ensure(body);
			}
		}

		public static void OnAnimChanged(string newAnimation, BoneMapper mapper)
		{
			CharacterBody val = (Object.op_Implicit((Object)(object)mapper) ? mapper.mapperBody : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				if (Object.op_Implicit((Object)(object)val.master) && Object.op_Implicit((Object)(object)val.master.playerCharacterMasterController))
				{
					ownerStarts.TryGetValue(val.master, out (int, float) value);
					ownerStarts[val.master] = (value.Item1 + 1, Time.unscaledTime);
				}
				else if (newAnimation != "none")
				{
					justStarted[mapper] = Time.frameCount;
				}
			}
		}

		public static void KeepInStep()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			foreach (Ally ally in allies)
			{
				BoneMapper mapper = ally.mapper;
				if (!Object.op_Implicit((Object)(object)mapper) || !Object.op_Implicit((Object)(object)mapper.a2) || !Object.op_Implicit((Object)(object)mapper.mapperBody))
				{
					continue;
				}
				string text = ClipOf(mapper);
				BoneMapper val = ((text == "none") ? null : MapperOf(Object.op_Implicit((Object)(object)ally.owner) ? ally.owner.GetBody() : null));
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.a2) || ClipOf(val) != text)
				{
					continue;
				}
				AnimatorStateInfo currentAnimatorStateInfo = val.a2.GetCurrentAnimatorStateInfo(0);
				if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("none") || ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).length <= 0f)
				{
					continue;
				}
				mapper.a2.speed = val.a2.speed;
				AnimatorStateInfo currentAnimatorStateInfo2 = mapper.a2.GetCurrentAnimatorStateInfo(0);
				if (!justStarted.ContainsKey(mapper))
				{
					if (((AnimatorStateInfo)(ref currentAnimatorStateInfo2)).fullPathHash != ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash)
					{
						continue;
					}
					float num = ((AnimatorStateInfo)(ref currentAnimatorStateInfo2)).normalizedTime - ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime;
					if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).loop)
					{
						num -= Mathf.Round(num);
					}
					if (Mathf.Abs(num) * ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).length < 0.05f)
					{
						continue;
					}
				}
				mapper.a2.Play(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash, 0, ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime + Time.deltaTime * val.a2.speed / ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).length);
				justStarted.Remove(mapper);
			}
			if (justStarted.Count <= 0)
			{
				return;
			}
			foreach (BoneMapper item in (from kv in justStarted
				where !Object.op_Implicit((Object)(object)kv.Key) || Time.frameCount - kv.Value > 30
				select kv.Key).ToList())
			{
				justStarted.Remove(item);
			}
		}

		public static void Tick()
		{
			if (Time.unscaledTime >= nextScan)
			{
				nextScan = Time.unscaledTime + 0.25f;
				Scan();
			}
			foreach (LocalUser readOnlyLocalUsers in LocalUserManager.readOnlyLocalUsersList)
			{
				if (Object.op_Implicit((Object)(object)readOnlyLocalUsers.cachedMaster))
				{
					Mirror(readOnlyLocalUsers.cachedMaster);
				}
			}
		}

		private static void Scan()
		{
			allies.Clear();
			silenced.Clear();
			Forget(mappers);
			Forget(sent);
			foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList)
			{
				CharacterMaster val = OwnerOf(readOnlyInstances);
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				AllyRigs.Ensure(readOnlyInstances);
				BoneMapper val2 = MapperOf(readOnlyInstances);
				allies.Add(new Ally
				{
					body = readOnlyInstances,
					owner = val,
					mapper = val2
				});
				if (Object.op_Implicit((Object)(object)val2))
				{
					silenced.Add(((Component)val2).gameObject);
					if (!Object.op_Implicit((Object)(object)((Component)val2).GetComponent<RigAnchor>()))
					{
						((Component)val2).gameObject.AddComponent<RigAnchor>().mapper = val2;
					}
				}
				else if (AllAlliesEmotePlugin.fallbackDance.Value && Object.op_Implicit((Object)(object)readOnlyInstances.modelLocator) && Object.op_Implicit((Object)(object)readOnlyInstances.modelLocator.modelTransform))
				{
					AllyDance allyDance = ((Component)readOnlyInstances).GetComponent<AllyDance>();
					if (!Object.op_Implicit((Object)(object)allyDance))
					{
						allyDance = ((Component)readOnlyInstances).gameObject.AddComponent<AllyDance>();
					}
					allyDance.owner = val;
				}
			}
		}

		private static void Forget<T>(Dictionary<CharacterBody, T> map)
		{
			List<CharacterBody> list = new List<CharacterBody>();
			foreach (CharacterBody key in map.Keys)
			{
				if (!Object.op_Implicit((Object)(object)key))
				{
					list.Add(key);
				}
			}
			foreach (CharacterBody item in list)
			{
				map.Remove(item);
			}
		}

		private static void Mirror(CharacterMaster player)
		{
			BoneMapper mapper = MapperOf(player.GetBody());
			string text = (AllAlliesEmotePlugin.alliesEmote.Value ? ClipOf(mapper) : "none");
			ownerStarts.TryGetValue(player, out (int, float) value);
			foreach (Ally ally in allies)
			{
				if ((Object)(object)ally.owner != (Object)(object)player || !Object.op_Implicit((Object)(object)ally.mapper) || !Object.op_Implicit((Object)(object)ally.body) || !Object.op_Implicit((Object)(object)ally.mapper.mapperBody))
				{
					continue;
				}
				sent.TryGetValue(ally.body, out (string, int) value2);
				if (value2.Item1 == text && value2.Item2 == value.Item1)
				{
					continue;
				}
				string text2 = ClipOf(ally.mapper);
				if (text == "none")
				{
					if (value2.Item1 != null && value2.Item1 != "none" && text2 != "none")
					{
						Send(ally.body, "none", -2);
					}
					sent[ally.body] = (text, value.Item1);
				}
				else if (!(Time.unscaledTime - value.Item2 < MirrorDelay))
				{
					if (MirrorDelay > 0f && text2 == text && value2.Item1 == null)
					{
						sent[ally.body] = (text, value.Item1);
						continue;
					}
					Send(ally.body, text, Variant(mapper));
					sent[ally.body] = (text, value.Item1);
				}
			}
		}

		private static int Variant(BoneMapper mapper)
		{
			CustomAnimationClip val = (Object.op_Implicit((Object)(object)mapper) ? mapper.currentClip : null);
			if (val == null || val.clip == null || val.clip.Length < 2)
			{
				return -2;
			}
			RuntimeAnimatorController runtimeAnimatorController = mapper.a2.runtimeAnimatorController;
			AnimatorOverrideController val2 = (AnimatorOverrideController)(object)((runtimeAnimatorController is AnimatorOverrideController) ? runtimeAnimatorController : null);
			if (val2 == null)
			{
				return -2;
			}
			List<KeyValuePair<AnimationClip, AnimationClip>> list = new List<KeyValuePair<AnimationClip, AnimationClip>>();
			val2.GetOverrides(list);
			foreach (KeyValuePair<AnimationClip, AnimationClip> item in list)
			{
				if (!Object.op_Implicit((Object)(object)item.Value))
				{
					continue;
				}
				for (int i = 0; i < val.clip.Length; i++)
				{
					if ((Object)(object)val.clip[i] == (Object)(object)item.Value || (val.secondaryClip != null && i < val.secondaryClip.Length && (Object)(object)val.secondaryClip[i] == (Object)(object)item.Value))
					{
						return i;
					}
				}
			}
			return -2;
		}

		private static void Send(CharacterBody body, string clip, int variant)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			NetMessageExtensions.Send((INetMessage)new SyncAnimationToServer(((NetworkBehaviour)body).netId, clip, variant), (NetworkDestination)2);
		}
	}
	[DefaultExecutionOrder(10000)]
	internal class AllyDance : MonoBehaviour
	{
		private const float BeatsPerSecond = 2f;

		private const float BlendSpeed = 4f;

		public CharacterMaster owner;

		private CharacterBody body;

		private Transform model;

		private Vector3 basePosition;

		private Vector3 appliedPosition;

		private Quaternion baseRotation;

		private Quaternion appliedRotation;

		private bool applied;

		private float weight;

		private int style;

		private string clip;

		private void Awake()
		{
			body = ((Component)this).GetComponent<CharacterBody>();
		}

		private void LateUpdate()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: 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_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: 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_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: 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_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_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: 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_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null);
			if ((Object)(object)val != (Object)(object)model)
			{
				model = val;
				applied = false;
			}
			if (!Object.op_Implicit((Object)(object)model))
			{
				return;
			}
			if (applied && model.localPosition == appliedPosition && model.localRotation == appliedRotation)
			{
				model.SetLocalPositionAndRotation(basePosition, baseRotation);
			}
			applied = false;
			string text = Allies.ClipOf(owner);
			bool flag = text != "none" && AllAlliesEmotePlugin.alliesEmote.Value && AllAlliesEmotePlugin.fallbackDance.Value && Object.op_Implicit((Object)(object)body.healthComponent) && body.healthComponent.alive;
			weight = Mathf.MoveTowards(weight, flag ? 1f : 0f, Time.deltaTime * 4f);
			if (!(weight <= 0f))
			{
				if (flag && text != clip)
				{
					clip = text;
					style = (int)((uint)clip.GetHashCode() % 3u);
				}
				float num = Mathf.Clamp(body.bestFitRadius, 0.5f, 4f);
				float num2 = Time.time * 2f;
				float num3 = Mathf.Abs(Mathf.Sin((float)Math.PI * num2));
				float num4 = Mathf.Sin((float)Math.PI * num2 * 0.5f);
				float num5;
				Quaternion val2;
				switch (style)
				{
				case 0:
					num5 = 0.15f * num3;
					val2 = Quaternion.Euler(0f, 25f * num4, 10f * Mathf.Sin((float)Math.PI * num2));
					break;
				case 1:
					num5 = 0.1f * num3;
					val2 = Quaternion.Euler(0f, Time.time * 270f % 360f, 0f);
					break;
				default:
					num5 = 0.05f * num3;
					val2 = Quaternion.Euler(-20f * num3, 0f, 8f * num4);
					break;
				}
				basePosition = model.localPosition;
				baseRotation = model.localRotation;
				appliedPosition = basePosition + baseRotation * Vector3.up * (num5 * num * weight);
				appliedRotation = baseRotation * Quaternion.Slerp(Quaternion.identity, val2, weight);
				model.SetLocalPositionAndRotation(appliedPosition, appliedRotation);
				applied = true;
			}
		}

		private void OnDisable()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (applied && Object.op_Implicit((Object)(object)model) && model.localPosition == appliedPosition && model.localRotation == appliedRotation)
			{
				model.SetLocalPositionAndRotation(basePosition, baseRotation);
			}
			applied = false;
		}
	}
	internal static class AllyRigs
	{
		private const string Dancer = "RoR2/Base/Bandit2/Bandit2Body.prefab";

		private static readonly Dictionary<string, string> sameModelAs = new Dictionary<string, string>
		{
			["DTGunnerDroneBody"] = "RoR2/Base/Drones/Drone1Body.prefab",
			["DTHealingDroneBody"] = "RoR2/Base/Drones/Drone2Body.prefab",
			["FriendUnitBody"] = "RoR2/DLC3/DefectiveUnit/DefectiveUnitBody.prefab",
			["DevotedLemurianBody"] = "RoR2/Base/Lemurian/LemurianBody.prefab",
			["DevotedLemurianBruiserBody"] = "RoR2/Base/LemurianBruiser/LemurianBruiserBody.prefab"
		};

		private static readonly MethodInfo applyAnimationStuff = AccessTools.Method("AnimationReplacements:ApplyAnimationStuff", new Type[6]
		{
			typeof(GameObject),
			typeof(GameObject),
			typeof(int),
			typeof(bool),
			typeof(bool),
			typeof(bool)
		}, (Type[])null);

		private static readonly List<BoneMapper> allMappers = (List<BoneMapper>)AccessTools.Field(typeof(BoneMapper), "allMappers").GetValue(null);

		private static readonly HashSet<CharacterBody> tried = new HashSet<CharacterBody>();

		private static readonly HashSet<string> brokenRigs = new HashSet<string> { "DroneCommanderBody" };

		public static bool Ensure(CharacterBody body)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.modelLocator)) ? body.modelLocator.modelTransform : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			if (Object.op_Implicit((Object)(object)((Component)val).GetComponentInChildren<BoneMapper>(true)))
			{
				return true;
			}
			if (!tried.Add(body))
			{
				return false;
			}
			tried.RemoveWhere((CharacterBody b) => !Object.op_Implicit((Object)(object)b));
			try
			{
				string bodyName = BodyCatalog.GetBodyName(body.bodyIndex);
				if (sameModelAs.TryGetValue(bodyName ?? "", out var value) && Copy(body, val, value))
				{
					return true;
				}
				return Generic(body, val);
			}
			catch (Exception arg)
			{
				AllAlliesEmotePlugin.Log.LogWarning((object)$"{((Object)body).name}: couldn't add an emote skeleton: {arg}");
				return false;
			}
		}

		private static bool Copy(CharacterBody body, Transform model, string sourceKey)
		{
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			BoneMapper val = DonorMapper(sourceKey);
			if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.smr1))
			{
				return false;
			}
			HashSet<string> rigNames = new HashSet<string>(from b in val.smr1.bones
				where Object.op_Implicit((Object)(object)b)
				select ((Object)b).name);
			(SkinnedMeshRenderer, int, int) tuple = (from r in ((Component)model).GetComponentsInChildren<SkinnedMeshRenderer>(true)
				select (r: r, matched: r.bones.Count((Transform b) => Object.op_Implicit((Object)(object)b) && rigNames.Contains(((Object)b).name)), count: r.bones.Count((Transform b) => Object.op_Implicit((Object)(object)b))) into x
				orderby x.matched descending
				select x).FirstOrDefault();
			if ((Object)(object)tuple.Item1 == (Object)null || tuple.Item2 == 0 || (float)tuple.Item2 < 0.6f * (float)Mathf.Min(rigNames.Count, tuple.Item3))
			{
				return false;
			}
			Transform val2 = CopyRig(val);
			BoneMapper val3 = Attach(body, model, ((Component)val2).gameObject);
			if (!Object.op_Implicit((Object)(object)val3))
			{
				return false;
			}
			val3.scale = val.scale;
			((Component)val3).transform.localPosition = ((Component)val).transform.localPosition;
			AllAlliesEmotePlugin.Log.LogInfo((object)$"{((Object)body).name}: emotes added ({((Object)((Component)val).transform.parent).name}'s skeleton, {tuple.Item2} bones)");
			return true;
		}

		private static bool Generic(CharacterBody body, Transform model)
		{
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			BoneMapper donor = DonorMapper("RoR2/Base/Bandit2/Bandit2Body.prefab");
			if (!Object.op_Implicit((Object)(object)donor) || !Object.op_Implicit((Object)(object)donor.a2) || !Object.op_Implicit((Object)(object)donor.a2.avatar))
			{
				return false;
			}
			Transform val = TopBone(model);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			Transform val2 = CopyRig(donor);
			Transform[] all = ((Component)val2).GetComponentsInChildren<Transform>(true);
			Transform val3 = Find((HumanBodyBones)0);
			Transform val4 = Find((HumanBodyBones)5);
			if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val4))
			{
				Object.Destroy((Object)(object)((Component)val2.parent).gameObject);
				return false;
			}
			SkinnedMeshRenderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Transform transform = new GameObject("AllyEmoteProxy").transform;
			transform.SetParent(model, false);
			Transform transform2 = new GameObject(((Object)val).name).transform;
			transform2.SetParent(transform, false);
			SkinnedMeshRenderer obj = new GameObject("AllyEmoteBones").AddComponent<SkinnedMeshRenderer>();
			((Component)obj).transform.SetParent(val2, false);
			obj.bones = (Transform[])(object)new Transform[1] { transform2 };
			BoneMapper val5 = Attach(body, model, ((Component)val2).gameObject);
			if (!Object.op_Implicit((Object)(object)val5))
			{
				Object.Destroy((Object)(object)((Component)transform).gameObject);
				return false;
			}
			float num = val5.a2.humanScale * Mathf.Abs(((Component)val5).transform.lossyScale.y);
			if (num <= 0.01f)
			{
				num = Vector3.Distance(val3.position, val4.position);
			}
			float num2 = Size(model, ((Component)val5).transform);
			if (num > 0.01f && num2 > 0f)
			{
				Transform transform3 = ((Component)val5).transform;
				transform3.localScale *= Mathf.Clamp(num2 * 0.4f, 0.3f, 2f) / num;
			}
			transform2.SetPositionAndRotation(val.position, val.rotation);
			val5.revertTransform = true;
			RigAnchor rigAnchor = ((Component)val2).gameObject.AddComponent<RigAnchor>();
			rigAnchor.mapper = val5;
			rigAnchor.follow = val3;
			rigAnchor.reach = Mathf.Max(num2, 1.5f);
			rigAnchor.proxy = transform2;
			rigAnchor.bone = val;
			AllAlliesEmotePlugin.Log.LogInfo((object)$"{((Object)body).name}: emotes added (its {((Object)val).name} follows the dance, size {num2:0.0} m)");
			return true;
			Transform Find(HumanBodyBones b)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				string n = HumanBone(donor, b);
				return ((IEnumerable<Transform>)all).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == n));
			}
		}

		public static void ReplaceBroken(CharacterBody body)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.modelLocator)) ? body.modelLocator.modelTransform : null);
			if (Object.op_Implicit((Object)(object)val) && brokenRigs.Contains(BodyCatalog.GetBodyName(body.bodyIndex) ?? ""))
			{
				BoneMapper componentInChildren = ((Component)val).GetComponentInChildren<BoneMapper>(true);
				if (Object.op_Implicit((Object)(object)componentInChildren) && (!Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<RigAnchor>()) || !Object.op_Implicit((Object)(object)((Component)componentInChildren).GetComponent<RigAnchor>().follow)))
				{
					Object.DestroyImmediate((Object)(object)((Component)componentInChildren).gameObject);
					tried.Remove(body);
					Ensure(body);
				}
			}
		}

		private static Transform TopBone(Transform model)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			List<Transform> list = (from b in ((Component)model).GetComponentsInChildren<SkinnedMeshRenderer>(true).SelectMany((SkinnedMeshRenderer r) => r.bones)
				where Object.op_Implicit((Object)(object)b) && (Object)(object)b != (Object)(object)model
				select b).Distinct().ToList();
			if (list.Count > 0)
			{
				return list.OrderBy(Depth).First();
			}
			Transform val = null;
			int num = 0;
			foreach (Transform item in model)
			{
				Transform val2 = item;
				int num2 = ((Component)val2).GetComponentsInChildren<MeshRenderer>(true).Length;
				if (num2 > num)
				{
					num = num2;
					val = val2;
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			SkinnedMeshRenderer obj = new GameObject("AllyEmoteBones").AddComponent<SkinnedMeshRenderer>();
			((Component)obj).transform.SetParent(model, false);
			obj.bones = (Transform[])(object)new Transform[1] { val };
			return val;
		}

		private static int Depth(Transform t)
		{
			int num = 0;
			Transform parent = t.parent;
			while (Object.op_Implicit((Object)(object)parent))
			{
				num++;
				parent = parent.parent;
			}
			return num;
		}

		private static string HumanBone(BoneMapper mapper, HumanBodyBones bone)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			HumanBone val = ((IEnumerable<HumanBone>)mapper.a2.avatar.humanDescription.human).FirstOrDefault((Func<HumanBone, bool>)((HumanBone h) => ((HumanBone)(ref h)).humanName == HumanTrait.BoneName[bone]));
			return ((HumanBone)(ref val)).boneName;
		}

		private static float Size(Transform model, Transform rig)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00d1: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			Bounds? val = null;
			Renderer[] componentsInChildren = ((Component)model).GetComponentsInChildren<Renderer>();
			Bounds val3;
			foreach (Renderer val2 in componentsInChildren)
			{
				if (((Component)val2).transform.IsChildOf(rig) || val2 is ParticleSystemRenderer)
				{
					continue;
				}
				val3 = val2.bounds;
				if (!(((Bounds)(ref val3)).size == Vector3.zero))
				{
					if (!val.HasValue)
					{
						val = val2.bounds;
						continue;
					}
					Bounds value = val.Value;
					((Bounds)(ref value)).Encapsulate(val2.bounds);
					val = value;
				}
			}
			if (val.HasValue)
			{
				float[] array = new float[3];
				val3 = val.Value;
				array[0] = ((Bounds)(ref val3)).size.x;
				val3 = val.Value;
				array[1] = ((Bounds)(ref val3)).size.y;
				val3 = val.Value;
				array[2] = ((Bounds)(ref val3)).size.z;
				return Mathf.Max(array);
			}
			return 0f;
		}

		private static BoneMapper DonorMapper(string key)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Addressables.LoadAssetAsync<GameObject>((object)key).WaitForCompletion();
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return val.GetComponentInChildren<BoneMapper>(true);
		}

		private static Transform CopyRig(BoneMapper donor)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("AllAlliesEmote holder");
			val.SetActive(false);
			GameObject obj = Object.Instantiate<GameObject>(((Component)donor).gameObject, val.transform);
			((Object)obj).name = ((Object)((Component)donor).gameObject).name;
			Object.DestroyImmediate((Object)(object)obj.GetComponent<BoneMapper>());
			return obj.transform;
		}

		private static BoneMapper Attach(CharacterBody body, Transform model, GameObject rig)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			Transform parent = rig.transform.parent;
			BoneMapper val;
			try
			{
				val = (BoneMapper)applyAnimationStuff.Invoke(null, new object[6]
				{
					((Component)body).gameObject,
					rig,
					0,
					true,
					false,
					true
				});
			}
			finally
			{
				if (Object.op_Implicit((Object)(object)parent) && ((Object)parent).name == "AllAlliesEmote holder")
				{
					Object.Destroy((Object)(object)((Component)parent).gameObject);
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			allMappers.Remove(val);
			RelinkToModel(val, model);
			return val;
		}

		public static bool RelinkToModel(BoneMapper mapper, Transform model)
		{
			if (!Object.op_Implicit((Object)(object)mapper) || !Object.op_Implicit((Object)(object)mapper.smr1) || !Object.op_Implicit((Object)(object)mapper.smr2) || !((Component)mapper.smr2).transform.IsChildOf(((Component)mapper).transform))
			{
				return false;
			}
			HashSet<string> rigNames = new HashSet<string>(from b in mapper.smr1.bones
				where Object.op_Implicit((Object)(object)b)
				select ((Object)b).name);
			SkinnedMeshRenderer val = (from r in ((Component)model).GetComponentsInChildren<SkinnedMeshRenderer>(true)
				where !((Component)r).transform.IsChildOf(((Component)mapper).transform)
				orderby r.bones.Count((Transform b) => Object.op_Implicit((Object)(object)b) && rigNames.Contains(((Object)b).name)) descending
				select r).FirstOrDefault();
			if (!Object.op_Implicit((Object)(object)val) || !val.bones.Any((Transform b) => Object.op_Implicit((Object)(object)b) && rigNames.Contains(((Object)b).name)))
			{
				return false;
			}
			mapper.smr2 = val;
			return true;
		}

		public static void RelinkAll()
		{
			foreach (GameObject allBodyPrefab in BodyCatalog.allBodyPrefabs)
			{
				Transform val = ((Object.op_Implicit((Object)(object)allBodyPrefab) && Object.op_Implicit((Object)(object)allBodyPrefab.GetComponent<ModelLocator>())) ? allBodyPrefab.GetComponent<ModelLocator>().modelTransform : null);
				BoneMapper val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponentInChildren<BoneMapper>(true) : null);
				if (RelinkToModel(val2, val))
				{
					AllAlliesEmotePlugin.Log.LogInfo((object)(((Object)allBodyPrefab).name + ": emote skeleton was linked to itself, now linked to " + ((Object)val2.smr2).name));
				}
			}
		}
	}
	internal static class ModSettings
	{
		public const string RiskOfOptionsGUID = "com.rune580.riskofoptions";

		public static void Register()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			ModSettingsManager.SetModDescription("When you emote, all of your allies emote with you.");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(AllAlliesEmotePlugin.alliesEmote));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(AllAlliesEmotePlugin.fallbackDance));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(AllAlliesEmotePlugin.allyAudio));
		}
	}
	[DefaultExecutionOrder(-10)]
	internal class RigAnchor : MonoBehaviour
	{
		private struct Pose
		{
			public Transform bone;

			public Vector3 position;

			public Quaternion rotation;
		}

		public BoneMapper mapper;

		public Transform follow;

		public Transform proxy;

		public Transform bone;

		public float reach = 2f;

		private List<Pose> rest;

		private List<EmoteConstraint> pins;

		private bool wasPinned;

		private string anchoredFor;

		private int settling;

		private const int SettleFrames = 3;

		private Vector3 offsetPosition;

		private Vector3 anchorPosition;

		private Quaternion offsetRotation;

		private static readonly FieldRef<EmoteConstraint, Vector3> savedPosition = AccessTools.FieldRefAccess<EmoteConstraint, Vector3>("originalPosition");

		private static readonly FieldRef<EmoteConstraint, Quaternion> savedRotation = AccessTools.FieldRefAccess<EmoteConstraint, Quaternion>("originalRotation");

		private void Start()
		{
			if (Object.op_Implicit((Object)(object)mapper) && Object.op_Implicit((Object)(object)mapper.a2))
			{
				mapper.a2.cullingMode = (AnimatorCullingMode)0;
				if (Object.op_Implicit((Object)(object)follow))
				{
					mapper.a2.applyRootMotion = false;
				}
			}
		}

		private void LateUpdate()
		{
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: 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_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: 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_0196: 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_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: 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_01fe: 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_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: 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_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: 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_02a8: 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_02b8: 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_0231: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)mapper) || (pins == null && !FindPins()))
			{
				return;
			}
			if (!pins.Any((EmoteConstraint c) => Object.op_Implicit((Object)(object)c) && c.constraintActive))
			{
				if (wasPinned)
				{
					foreach (Pose item in rest)
					{
						if (Object.op_Implicit((Object)(object)item.bone))
						{
							item.bone.SetLocalPositionAndRotation(item.position, item.rotation);
						}
					}
				}
				wasPinned = false;
				anchoredFor = null;
				Record();
				return;
			}
			wasPinned = true;
			if (Object.op_Implicit((Object)(object)follow) && Object.op_Implicit((Object)(object)proxy) && Object.op_Implicit((Object)(object)bone))
			{
				string currentClipName = mapper.currentClipName;
				if (anchoredFor != currentClipName)
				{
					anchoredFor = currentClipName;
					settling = 0;
				}
				Pose pose = rest.FirstOrDefault((Pose p) => (Object)(object)p.bone == (Object)(object)bone);
				Transform parent = bone.parent;
				Vector3 val = ((!Object.op_Implicit((Object)(object)pose.bone)) ? bone.position : (Object.op_Implicit((Object)(object)parent) ? parent.TransformPoint(pose.position) : pose.position));
				Quaternion val2 = ((!Object.op_Implicit((Object)(object)pose.bone)) ? bone.rotation : (Object.op_Implicit((Object)(object)parent) ? (parent.rotation * pose.rotation) : pose.rotation));
				if (settling < 3)
				{
					settling++;
					proxy.SetPositionAndRotation(val, val2);
					offsetRotation = Quaternion.Inverse(follow.rotation) * val2;
					offsetPosition = Quaternion.Inverse(follow.rotation) * (val - follow.position);
					anchorPosition = (Object.op_Implicit((Object)(object)parent) ? parent.InverseTransformPoint(val) : val);
				}
				else
				{
					Vector3 val3 = follow.position + follow.rotation * offsetPosition;
					Vector3 val4 = (Object.op_Implicit((Object)(object)bone.parent) ? bone.parent.TransformPoint(anchorPosition) : anchorPosition);
					proxy.SetPositionAndRotation(val4 + Vector3.ClampMagnitude(val3 - val4, reach), follow.rotation * offsetRotation);
				}
			}
		}

		private bool FindPins()
		{
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Transform parent = ((Component)mapper).transform.parent;
			if (!Object.op_Implicit((Object)(object)parent))
			{
				return false;
			}
			List<EmoteConstraint> list = (from c in ((Component)parent).GetComponentsInChildren<EmoteConstraint>(true)
				where Object.op_Implicit((Object)(object)c.originalBone) && !c.originalBone.IsChildOf(((Component)mapper).transform) && Object.op_Implicit((Object)(object)c.emoteBone)
				select c).ToList();
			if (list.Count == 0)
			{
				return false;
			}
			pins = list;
			rest = (from b in list.Select((EmoteConstraint c) => c.originalBone).Distinct()
				select new Pose
				{
					bone = b
				}).ToList();
			Record();
			int i;
			for (i = 0; i < rest.Count; i++)
			{
				EmoteConstraint val = ((IEnumerable<EmoteConstraint>)list).FirstOrDefault((Func<EmoteConstraint, bool>)((EmoteConstraint x) => (Object)(object)x.originalBone == (Object)(object)rest[i].bone && x.constraintActive));
				if (Object.op_Implicit((Object)(object)val))
				{
					rest[i] = new Pose
					{
						bone = rest[i].bone,
						position = savedPosition.Invoke(val),
						rotation = savedRotation.Invoke(val)
					};
				}
			}
			return true;
		}

		private void Record()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < rest.Count; i++)
			{
				Pose value = rest[i];
				if (Object.op_Implicit((Object)(object)value.bone))
				{
					value.position = value.bone.localPosition;
					value.rotation = value.bone.localRotation;
					rest[i] = value;
				}
			}
		}
	}
}