Decompiled source of PeakMoreEmotes v1.1.2

plugins/PeakMoreEmotes/PeakMoreEmotes.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Playables;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PeakMoreEmotes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.2.0")]
[assembly: AssemblyInformationalVersion("1.1.2+4694deedab7a66f1a775897e4983ef85bf70d156")]
[assembly: AssemblyProduct("PeakMoreEmotes")]
[assembly: AssemblyTitle("PeakMoreEmotes")]
[assembly: AssemblyVersion("1.1.2.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 PeakMoreEmotes
{
	[BepInPlugin("local.peak.moreemotes", "PEAK 更多动作", "1.1.2")]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal sealed class Move
		{
			public EmoteWheelData Data;

			public AnimationClip Clip;

			public float Speed;

			public string Zh;

			public string En;

			public bool Retarget;

			public float Duration
			{
				get
				{
					if (!(Clip.length < 0.1f))
					{
						return Clip.length / Speed;
					}
					return 5f;
				}
			}
		}

		internal sealed class Playback
		{
			public Move Move;

			public AnimatorOverrideController Controller;

			public RuntimeAnimatorController Base;

			public AnimationClip Original;

			public float Started;

			public float PreviousSpeed;

			public float PreviousIK;
		}

		private sealed class PhysicalPose
		{
			private readonly Transform[] transforms;

			private readonly Vector3[] positions;

			private readonly Quaternion[] rotations;

			private readonly Vector3[] scales;

			internal PhysicalPose(Animator animator)
			{
				transforms = ((Component)animator).GetComponentsInChildren<Transform>(true);
				positions = transforms.Select((Transform t) => t.localPosition).ToArray();
				rotations = transforms.Select((Transform t) => t.localRotation).ToArray();
				scales = transforms.Select((Transform t) => t.localScale).ToArray();
			}

			internal void Restore()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: 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)
				for (int i = 0; i < transforms.Length; i++)
				{
					Transform val = transforms[i];
					if (Object.op_Implicit((Object)(object)val))
					{
						val.SetLocalPositionAndRotation(positions[i], rotations[i]);
						val.localScale = scales[i];
					}
				}
			}
		}

		[HarmonyPatch(typeof(EmoteWheel), "InitWheel")]
		private static class WheelPatch
		{
			private static void Prefix(EmoteWheel __instance)
			{
				Extend(__instance);
			}
		}

		[HarmonyPatch(typeof(EmoteWheel), "Update")]
		private static class ScrollPatch
		{
			private static readonly MethodInfo Tab = AccessTools.Method(typeof(EmoteWheel), "Tab", (Type[])null, (Type[])null);

			private static void Postfix(EmoteWheel __instance)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				if (Input.mouseScrollDelta.y != 0f)
				{
					Tab.Invoke(__instance, new object[1] { (Input.mouseScrollDelta.y < 0f) ? 1 : (-1) });
				}
			}
		}

		[HarmonyPatch(typeof(LocalizedText), "GetText", new Type[]
		{
			typeof(string),
			typeof(bool)
		})]
		private static class NamePatch
		{
			private static bool Prefix(string id, ref string __result)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Invalid comparison between Unknown and I4
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Invalid comparison between Unknown and I4
				Move move = Find(id);
				if (move == null)
				{
					return true;
				}
				bool flag = (int)LocalizedText.CURRENT_LANGUAGE == 9 || (int)LocalizedText.CURRENT_LANGUAGE == 10;
				__result = (flag ? move.Zh : move.En);
				return false;
			}
		}

		[HarmonyPatch(typeof(CharacterAnimations), "RPCA_PlayRemove")]
		private static class PlayPatch
		{
			private static bool Prefix(CharacterAnimations __instance, ref string emoteName, ref PhysicalPose __state)
			{
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Expected O, but got Unknown
				//IL_017b: 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)
				Character val = CharacterRef.Invoke(__instance);
				Animator animator = val.refs.animator;
				if (!Object.op_Implicit((Object)(object)animator) || string.IsNullOrEmpty(emoteName))
				{
					return true;
				}
				Playback orCreateValue = Playing.GetOrCreateValue(__instance);
				if (Find(emoteName) != null || (Object.op_Implicit((Object)(object)orCreateValue.Controller) && (Object)(object)animator.runtimeAnimatorController == (Object)(object)orCreateValue.Controller))
				{
					__state = new PhysicalPose(animator);
				}
				if (orCreateValue.Move != null)
				{
					Stop(__instance, orCreateValue);
				}
				Move move = Find(emoteName);
				if (move == null)
				{
					if (emoteName.StartsWith("PeakMoreEmotes_", StringComparison.Ordinal))
					{
						return false;
					}
					if (Object.op_Implicit((Object)(object)orCreateValue.Controller) && (Object)(object)animator.runtimeAnimatorController == (Object)(object)orCreateValue.Controller)
					{
						orCreateValue.Controller["A_Scout_Emote_Dance2"] = orCreateValue.Original;
					}
					return true;
				}
				if (val.data.dead || val.data.fullyPassedOut || val.data.isClimbing || val.data.isRopeClimbing)
				{
					return false;
				}
				try
				{
					if (!Object.op_Implicit((Object)(object)orCreateValue.Controller) || (Object)(object)animator.runtimeAnimatorController != (Object)(object)orCreateValue.Controller)
					{
						orCreateValue.Base = animator.runtimeAnimatorController;
						orCreateValue.Controller = new AnimatorOverrideController(orCreateValue.Base);
						orCreateValue.Original = orCreateValue.Controller["A_Scout_Emote_Dance2"];
						if (!Object.op_Implicit((Object)(object)orCreateValue.Original))
						{
							throw new InvalidOperationException("Missing override slot A_Scout_Emote_Dance2");
						}
						animator.runtimeAnimatorController = (RuntimeAnimatorController)(object)orCreateValue.Controller;
						PlayableGraph playableGraph = animator.playableGraph;
						if (((PlayableGraph)(ref playableGraph)).IsValid())
						{
							((PlayableGraph)(ref playableGraph)).SetTimeUpdateMode((DirectorUpdateMode)3);
							((PlayableGraph)(ref playableGraph)).Stop();
						}
					}
					orCreateValue.Controller["A_Scout_Emote_Dance2"] = (AnimationClip)(move.Retarget ? ((object)(((IEnumerable<AnimationClip>)orCreateValue.Base.animationClips).FirstOrDefault((Func<AnimationClip, bool>)((AnimationClip c) => ((Object)c).name == "A_Scout_Idle3")) ?? orCreateValue.Original)) : ((object)move.Clip));
					orCreateValue.Move = move;
					orCreateValue.Started = Time.time;
					orCreateValue.PreviousSpeed = animator.speed;
					orCreateValue.PreviousIK = val.data.overrideIKForSeconds;
					val.data.overrideIKForSeconds = move.Duration;
					if (move.Retarget)
					{
						(((Component)val).GetComponent<RepoRetarget>() ?? ((Component)val).gameObject.AddComponent<RepoRetarget>()).Begin(animator, move.Clip);
					}
					emoteName = "A_Scout_Emote_Dance2";
					((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"Playing {move.En} on {((Object)val).name}, duration={move.Duration:0.00}s");
					return true;
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)Instance).Logger.LogError((object)ex);
					orCreateValue.Move = null;
					return false;
				}
			}

			private static Exception Finalizer(Exception __exception, PhysicalPose __state)
			{
				__state?.Restore();
				return __exception;
			}
		}

		[HarmonyPatch(typeof(Bodypart), "SaveAnimationData")]
		private static class RagdollPosePatch
		{
			private static void Prefix(Bodypart __instance)
			{
				if (!Time.inFixedTimeStep)
				{
					return;
				}
				RepoRetarget componentInParent = ((Component)__instance).GetComponentInParent<RepoRetarget>();
				if (Object.op_Implicit((Object)(object)componentInParent) && componentInParent.Active)
				{
					List<Bodypart> partList = ((Component)__instance).GetComponentInParent<Character>().refs.ragdoll.partList;
					if (partList.Count > 0 && (Object)(object)partList[0] == (Object)(object)__instance)
					{
						componentInParent.CapturePhysicsPose();
					}
				}
			}
		}

		[HarmonyPatch(typeof(CharacterAnimations), "Update")]
		private static class TimingPatch
		{
			private static void Prefix(CharacterAnimations __instance)
			{
				if (Playing.TryGetValue(__instance, out var value) && value.Move != null)
				{
					SinceStart.Invoke(__instance) = Mathf.Min(SinceStart.Invoke(__instance), 1f);
				}
			}

			private static void Postfix(CharacterAnimations __instance)
			{
				if (Playing.TryGetValue(__instance, out var value) && value.Move != null)
				{
					Character val = CharacterRef.Invoke(__instance);
					if (!Emoting.Invoke(__instance) || Time.time - value.Started >= value.Move.Duration || val.data.dead || val.data.fullyPassedOut || val.data.isClimbing || val.data.isRopeClimbing || (Object)(object)val.refs.animator.runtimeAnimatorController != (Object)(object)value.Controller)
					{
						Stop(__instance, value);
					}
					else
					{
						val.refs.animator.speed = value.Move.Speed;
					}
				}
			}
		}

		public const string Id = "local.peak.moreemotes";

		internal const string Prefix = "PeakMoreEmotes_";

		internal const string Slot = "A_Scout_Emote_Dance2";

		internal static Plugin Instance;

		internal static readonly List<Move> Moves = new List<Move>();

		internal static readonly ConditionalWeakTable<CharacterAnimations, Playback> Playing = new ConditionalWeakTable<CharacterAnimations, Playback>();

		internal static readonly ConditionalWeakTable<EmoteWheel, object> Wheels = new ConditionalWeakTable<EmoteWheel, object>();

		internal static readonly FieldRef<CharacterAnimations, Character> CharacterRef = AccessTools.FieldRefAccess<CharacterAnimations, Character>("character");

		internal static readonly FieldRef<CharacterAnimations, bool> Emoting = AccessTools.FieldRefAccess<CharacterAnimations, bool>("emoting");

		internal static readonly FieldRef<CharacterAnimations, float> SinceStart = AccessTools.FieldRefAccess<CharacterAnimations, float>("sinceEmoteStart");

		private Harmony harmony;

		private ConfigEntry<bool> modEnabled;

		private ConfigEntry<bool> variations;

		private readonly List<AssetBundle> bundles = new List<AssetBundle>();

		private void Awake()
		{
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Expected O, but got Unknown
			Instance = this;
			modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "启用更多动作(修改后重启游戏)。");
			variations = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "TempoVariations", true, "额外加入5个节奏变体;关闭时只添加3个独立动作素材。");
			if (modEnabled.Value)
			{
				string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
				Load(directoryName, "default_dance.bundle", "Assets/Fortnite_Default_Dance.anim", "Assets/default_dance_icon.png", "default_dance", "默认舞", "Default Dance", new float[4] { 1f, 0.7f, 1.35f, 1.7f });
				Load(directoryName, "twerk.bundle", "Assets/Twerk.anim", "Assets/Twerk.png", "twerk", "扭胯舞", "Twerk", new float[3] { 1f, 0.7f, 1.35f });
				Load(directoryName, "middle_finger.bundle", "Assets/Middle_Finger.anim", "Assets/middle_finger.png", "middle_finger", "竖中指", "Middle Finger", new float[1] { 1f });
				if (((BaseUnityPlugin)this).Config.Bind<bool>("General", "RepoEmotes", true, "添加 SomeEmotesREPO 2.0.1 的27个重定向动作/姿势,重启生效。").Value)
				{
					LoadRepo(directoryName);
				}
				if (Moves.Count == 0)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)"没有可用动作素材,保留原版轮盘。");
					return;
				}
				harmony = new Harmony("local.peak.moreemotes");
				harmony.PatchAll(typeof(Plugin).Assembly);
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Loaded {Moves.Count} wheel entries; R wheel extends automatically.");
			}
		}

		private void LoadRepo(string root)
		{
			string text = Path.Combine(root, "repo_emotes.bundle");
			if (!File.Exists(text))
			{
				return;
			}
			try
			{
				AssetBundle val = AssetBundle.LoadFromFile(text);
				if (!Object.op_Implicit((Object)(object)val))
				{
					throw new IOException("Cannot load REPO emote bundle");
				}
				bundles.Add(val);
				RepoRetarget.Prefab = val.LoadAsset<GameObject>("assets/emotebundle/emote.prefab");
				if (!Object.op_Implicit((Object)(object)RepoRetarget.Prefab))
				{
					throw new IOException("Missing source humanoid rig");
				}
				Dictionary<string, string> dictionary = new Dictionary<string, string>
				{
					["Air Horse Gallop"] = "骑马舞",
					["Baby Shark"] = "鲨鱼宝宝",
					["Bboy Uprock"] = "街舞步伐",
					["Bellydancing"] = "肚皮舞",
					["Breakdance Uprock"] = "霹雳舞步",
					["Brooklyn Uprock"] = "布鲁克林街舞",
					["Can Can"] = "康康舞",
					["Capoeira"] = "卡波耶拉",
					["Dancing"] = "欢快舞蹈",
					["Dancing Running Man"] = "奔跑舞",
					["Female Dance Pose 1"] = "舞蹈姿势一",
					["Female Dance Pose 2"] = "舞蹈姿势二",
					["Hip Hop Dancing 1"] = "嘻哈舞一",
					["Hip Hop Dancing 2"] = "嘻哈舞二",
					["Hip Hop Dancing 3"] = "嘻哈舞三",
					["House Dancing"] = "浩室舞",
					["Jazz Dancing"] = "爵士舞",
					["Male Dance Pose"] = "舞蹈定格",
					["Robot Hip Hop Dance"] = "机械嘻哈舞",
					["Samba Dancing 1"] = "桑巴舞一",
					["Samba Dancing 2"] = "桑巴舞二",
					["Samba Dancing 3"] = "桑巴舞三",
					["Shuffling"] = "曳步舞",
					["Swing Dancing"] = "摇摆舞",
					["Thriller"] = "颤栗舞",
					["Tut Hip Hop Dance"] = "手臂几何舞",
					["Twist Dance"] = "扭扭舞"
				};
				using RepoRetarget.SourceRig sourceRig = new RepoRetarget.SourceRig();
				foreach (AnimationClip item in val.LoadAllAssets<AnimationClip>().OrderBy<AnimationClip, string>((AnimationClip x) => ((Object)x).name, StringComparer.Ordinal))
				{
					if (dictionary.TryGetValue(((Object)item).name, out var value) && ((Motion)item).isHumanMotion)
					{
						EmoteWheelData val2 = ScriptableObject.CreateInstance<EmoteWheelData>();
						val2.anim = (val2.emoteName = "PeakMoreEmotes_repo_" + ((Object)item).name.Replace(' ', '_'));
						val2.emoteSprite = sourceRig.Icon(item);
						val2.requireGrounded = true;
						Moves.Add(new Move
						{
							Data = val2,
							Clip = item,
							Speed = 1f,
							Zh = value,
							En = ((Object)item).name,
							Retarget = true
						});
					}
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("REPO source loaded: " + Moves.Count((Move x) => x.Retarget) + " retargeted emotes/poses."));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("REPO pack: " + ex));
			}
		}

		private void Load(string root, string file, string clipPath, string iconPath, string id, string zh, string en, float[] speeds)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(root, file));
				if (!Object.op_Implicit((Object)(object)val))
				{
					throw new IOException("Cannot load bundle " + file);
				}
				bundles.Add(val);
				AnimationClip val2 = val.LoadAsset<AnimationClip>(clipPath);
				Texture2D val3 = val.LoadAsset<Texture2D>(iconPath);
				if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val3))
				{
					throw new IOException("Missing clip/icon in " + file);
				}
				Sprite emoteSprite = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), new Vector2(0.5f, 0.5f));
				for (int i = 0; i < speeds.Length && (i <= 0 || variations.Value); i++)
				{
					string text = ((i == 0) ? "" : $" ×{speeds[i]:0.##}");
					EmoteWheelData val4 = ScriptableObject.CreateInstance<EmoteWheelData>();
					val4.anim = (val4.emoteName = "PeakMoreEmotes_" + id + "_" + i);
					val4.emoteSprite = emoteSprite;
					val4.requireGrounded = true;
					Moves.Add(new Move
					{
						Data = val4,
						Clip = val2,
						Speed = speeds[i],
						Zh = zh + text,
						En = en + text
					});
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Asset OK: {id}, {val2.length:0.00}s, {((Object)val2).name}");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)(file + ": " + ex.Message));
			}
		}

		internal static Move Find(string name)
		{
			return Moves.Find((Move m) => m.Data.anim == name);
		}

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

		internal static void Extend(EmoteWheel wheel)
		{
			if (!Wheels.TryGetValue(wheel, out var _))
			{
				int num = wheel.data.Length;
				int num2 = (num + Moves.Count + 7) / 8 * 8;
				Array.Resize(ref wheel.data, num2);
				for (int i = 0; i < Moves.Count; i++)
				{
					wheel.data[num + i] = Moves[i].Data;
				}
				wheel.pages = num2 / 8;
				Wheels.Add(wheel, new object());
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)$"Wheel extended: {num} existing + {Moves.Count} custom, {wheel.pages} pages.");
			}
		}

		internal static void Stop(CharacterAnimations animations, Playback state)
		{
			Character obj = CharacterRef.Invoke(animations);
			Animator animator = obj.refs.animator;
			state.Move = null;
			Emoting.Invoke(animations) = false;
			animator.SetBool("Emote", false);
			animator.speed = state.PreviousSpeed;
			obj.data.overrideIKForSeconds = state.PreviousIK;
			((Component)obj).GetComponent<RepoRetarget>()?.Release();
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	[DefaultExecutionOrder(24000)]
	public sealed class RepoRetarget : MonoBehaviour
	{
		private sealed class Binding
		{
			internal Transform Target;

			internal Transform Source;

			internal Quaternion Offset;

			internal Quaternion Previous;
		}

		internal sealed class SourceRig : IDisposable
		{
			private readonly GameObject instance;

			private readonly Animator animator;

			private readonly Dictionary<string, Transform> bones;

			private readonly Dictionary<Transform, Vector3> restPosition = new Dictionary<Transform, Vector3>();

			private readonly Dictionary<Transform, Quaternion> restRotation = new Dictionary<Transform, Quaternion>();

			private PlayableGraph graph;

			private AnimationClipPlayable playable;

			public string ClipName { get; private set; } = "";

			public float LegLength { get; }

			public SourceRig()
			{
				//IL_0178: 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_01bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e2: 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)
				instance = Object.Instantiate<GameObject>(Prefab);
				((Object)instance).name = "PeakMoreEmotes source rig (hidden)";
				Object.DontDestroyOnLoad((Object)(object)instance);
				Renderer[] componentsInChildren = instance.GetComponentsInChildren<Renderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].enabled = false;
				}
				animator = instance.GetComponentInChildren<Animator>();
				if (!Object.op_Implicit((Object)(object)animator) || !Object.op_Implicit((Object)(object)animator.avatar) || !animator.avatar.isHuman)
				{
					throw new InvalidOperationException("REPO source needs a humanoid Avatar");
				}
				animator.cullingMode = (AnimatorCullingMode)0;
				animator.applyRootMotion = false;
				bones = (from t in instance.GetComponentsInChildren<Transform>(true)
					group t by ((Object)t).name.Replace("mixamorig:", "")).ToDictionary((IGrouping<string, Transform> g) => g.Key, (IGrouping<string, Transform> g) => g.First());
				foreach (Transform value in bones.Values)
				{
					restPosition[value] = Position(value);
					restRotation[value] = Rotation(value);
				}
				LegLength = Vector3.Distance(RestPosition(Bone("LeftUpLeg")), RestPosition(Bone("LeftLeg"))) + Vector3.Distance(RestPosition(Bone("LeftLeg")), RestPosition(Bone("LeftFoot")));
				animator.runtimeAnimatorController = null;
			}

			public Transform Bone(string n)
			{
				if (!bones.TryGetValue(n, out var value))
				{
					return null;
				}
				return value;
			}

			public Vector3 Position(Transform t)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				return ((Component)animator).transform.InverseTransformPoint(t.position);
			}

			public Quaternion Rotation(Transform t)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				return Quaternion.Inverse(((Component)animator).transform.rotation) * t.rotation;
			}

			public Vector3 RestPosition(Transform t)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				return restPosition[t];
			}

			public Quaternion RestRotation(Transform t)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				return restRotation[t];
			}

			public void Play(AnimationClip clip)
			{
				//IL_0029: 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_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				if (((PlayableGraph)(ref graph)).IsValid())
				{
					((PlayableGraph)(ref graph)).Destroy();
				}
				graph = PlayableGraph.Create("PEAK REPO " + ((Object)clip).name);
				((PlayableGraph)(ref graph)).SetTimeUpdateMode((DirectorUpdateMode)3);
				playable = AnimationClipPlayable.Create(graph, clip);
				((AnimationClipPlayable)(ref playable)).SetApplyFootIK(false);
				((AnimationClipPlayable)(ref playable)).SetApplyPlayableIK(false);
				PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationClipPlayable>(AnimationPlayableOutput.Create(graph, "Humanoid sample", animator), playable);
				((PlayableGraph)(ref graph)).Play();
				ClipName = ((Object)clip).name;
				Sample(0f);
			}

			public void Sample(float t)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				PlayableExtensions.SetTime<AnimationClipPlayable>(playable, (double)t);
				((PlayableGraph)(ref graph)).Evaluate(0f);
			}

			public void Pause()
			{
				if (((PlayableGraph)(ref graph)).IsValid())
				{
					((PlayableGraph)(ref graph)).Stop();
				}
			}

			public void Dispose()
			{
				if (((PlayableGraph)(ref graph)).IsValid())
				{
					((PlayableGraph)(ref graph)).Destroy();
				}
				if (Object.op_Implicit((Object)(object)instance))
				{
					Object.Destroy((Object)(object)instance);
				}
			}

			public Sprite Icon(AnimationClip clip)
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Expected O, but got Unknown
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_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_01e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01eb: 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_026d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0278: 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_02c7: 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_0200: 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_021c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0228: Unknown result type (might be due to invalid IL or missing references)
				Play(clip);
				Sample(Mathf.Min(clip.length * 0.35f, 1.3f));
				Texture2D val = new Texture2D(96, 96, (TextureFormat)4, false);
				Color[] pixels = (Color[])(object)new Color[9216];
				Color color = new Color(0.2f, 0.55f, 0.65f, 1f);
				(string, string)[] array = new(string, string)[14]
				{
					("Hips", "Spine2"),
					("Spine2", "Neck"),
					("Neck", "Head"),
					("LeftArm", "RightArm"),
					("LeftArm", "LeftForeArm"),
					("LeftForeArm", "LeftHand"),
					("RightArm", "RightForeArm"),
					("RightForeArm", "RightHand"),
					("Hips", "LeftUpLeg"),
					("Hips", "RightUpLeg"),
					("LeftUpLeg", "LeftLeg"),
					("LeftLeg", "LeftFoot"),
					("RightUpLeg", "RightLeg"),
					("RightLeg", "RightFoot")
				};
				for (int i = 0; i < array.Length; i++)
				{
					(string, string) tuple = array[i];
					Vector2 val2 = Project(Bone(tuple.Item1));
					Vector2 val3 = Project(Bone(tuple.Item2));
					int num = Mathf.CeilToInt(Vector2.Distance(val2, val3));
					for (int j = 0; j <= num; j++)
					{
						Vector2 val4 = Vector2.Lerp(val2, val3, (num == 0) ? 0f : ((float)j / (float)num));
						Dot(Mathf.RoundToInt(val4.x), Mathf.RoundToInt(val4.y), 2);
					}
				}
				Vector2 val5 = Project(Bone("Head"));
				Dot(Mathf.RoundToInt(val5.x), Mathf.RoundToInt(val5.y + 3f), 6);
				val.SetPixels(pixels);
				val.Apply();
				return Sprite.Create(val, new Rect(0f, 0f, 96f, 96f), new Vector2(0.5f, 0.5f));
				void Dot(int x, int y, int radius)
				{
					//IL_0043: Unknown result type (might be due to invalid IL or missing references)
					//IL_0048: Unknown result type (might be due to invalid IL or missing references)
					for (int k = -radius; k <= radius; k++)
					{
						for (int l = -radius; l <= radius; l++)
						{
							if (k * k + l * l <= radius * radius && x + k >= 0 && x + k < 96 && y + l >= 0 && y + l < 96)
							{
								pixels[(y + l) * 96 + x + k] = color;
							}
						}
					}
				}
				Vector2 Project(Transform t)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0026: Unknown result type (might be due to invalid IL or missing references)
					//IL_003a: Unknown result type (might be due to invalid IL or missing references)
					Vector3 val6 = Position(t);
					return new Vector2(48f + val6.x / LegLength * 33f, 12f + val6.y / LegLength * 33f);
				}
			}
		}

		internal static GameObject Prefab;

		private SourceRig source;

		private Animator target;

		private readonly List<Binding> bindings = new List<Binding>();

		private float started;

		private Transform hip;

		private Transform[] contacts;

		private float bodyScale = 1f;

		private Character character;

		private static readonly (string target, string source, string child)[] Map = new(string, string, string)[18]
		{
			("Hip", "Hips", "Spine"),
			("Mid", "Spine", "Spine1"),
			("Torso", "Spine2", "Neck"),
			("Head", "Head", "HeadTop_End"),
			("S_Shoulder_L", "LeftShoulder", "LeftArm"),
			("Arm_L", "LeftArm", "LeftForeArm"),
			("Elbow_L", "LeftForeArm", "LeftHand"),
			("Hand_L", "LeftHand", "LeftHandMiddle1"),
			("S_Shoulder_R", "RightShoulder", "RightArm"),
			("Arm_R", "RightArm", "RightForeArm"),
			("Elbow_R", "RightForeArm", "RightHand"),
			("Hand_R", "RightHand", "RightHandMiddle1"),
			("Leg_L", "LeftUpLeg", "LeftLeg"),
			("Knee_L", "LeftLeg", "LeftFoot"),
			("Foot_L", "LeftFoot", "LeftToeBase"),
			("Leg_R", "RightUpLeg", "RightLeg"),
			("Knee_R", "RightLeg", "RightFoot"),
			("Foot_R", "RightFoot", "RightToeBase")
		};

		public bool Active { get; private set; }

		public int BoneCount => bindings.Count;

		public string ClipName => source?.ClipName ?? "";

		public float PoseMotion { get; private set; }

		public int PhysicsPoseUpdates { get; private set; }

		public float LastPoseFixedTime { get; private set; }

		internal void Begin(Animator animator, AnimationClip clip)
		{
			if (source == null)
			{
				source = new SourceRig();
			}
			if ((Object)(object)target != (Object)(object)animator || bindings.Count == 0)
			{
				Bind(animator);
			}
			started = Time.fixedTime;
			source.Play(clip);
			Active = true;
		}

		private void Bind(Animator animator)
		{
			//IL_00e4: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: 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_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_064b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0650: Unknown result type (might be due to invalid IL or missing references)
			//IL_0658: Unknown result type (might be due to invalid IL or missing references)
			//IL_065d: Unknown result type (might be due to invalid IL or missing references)
			//IL_066a: Unknown result type (might be due to invalid IL or missing references)
			//IL_066f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0466: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_0505: 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_0528: Unknown result type (might be due to invalid IL or missing references)
			//IL_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			target = animator;
			character = ((Component)this).GetComponent<Character>();
			bindings.Clear();
			Dictionary<string, Transform> transforms = (from t in ((Component)animator).GetComponentsInChildren<Transform>(true)
				group t by ((Object)t).name).ToDictionary((IGrouping<string, Transform> g) => g.Key, (IGrouping<string, Transform> g) => g.First());
			Dictionary<Transform, Matrix4x4> dictionary = new Dictionary<Transform, Matrix4x4>();
			SkinnedMeshRenderer[] componentsInChildren = ((Component)animator).GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val in componentsInChildren)
			{
				if (!Object.op_Implicit((Object)(object)val.sharedMesh))
				{
					continue;
				}
				Matrix4x4[] bindposes = val.sharedMesh.bindposes;
				Transform[] bones = val.bones;
				Matrix4x4 val2 = ((Component)animator).transform.worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix;
				for (int num2 = 0; num2 < Math.Min(bindposes.Length, bones.Length); num2++)
				{
					if (Object.op_Implicit((Object)(object)bones[num2]) && !dictionary.ContainsKey(bones[num2]))
					{
						dictionary[bones[num2]] = val2 * ((Matrix4x4)(ref bindposes[num2])).inverse;
					}
				}
			}
			(string, string, string)[] map = Map;
			for (int num = 0; num < map.Length; num++)
			{
				(string, string, string) tuple = map[num];
				if (!transforms.TryGetValue(tuple.Item1, out var value))
				{
					continue;
				}
				Transform val3 = source.Bone(tuple.Item2);
				Transform val4 = source.Bone(tuple.Item3);
				if (Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)val4) && dictionary.TryGetValue(value, out var value2))
				{
					Transform value3 = null;
					if (tuple.Item1 == "Hip")
					{
						transforms.TryGetValue("Mid", out value3);
					}
					else if (tuple.Item1 == "Mid")
					{
						transforms.TryGetValue("Torso", out value3);
					}
					else if (tuple.Item1 == "Torso")
					{
						transforms.TryGetValue("Head", out value3);
					}
					else if (tuple.Item1 == "Head")
					{
						value3 = null;
					}
					else if (tuple.Item1.StartsWith("S_Shoulder"))
					{
						transforms.TryGetValue("Arm_" + tuple.Item1.Last(), out value3);
					}
					else if (tuple.Item1.StartsWith("Arm_"))
					{
						transforms.TryGetValue("Elbow_" + tuple.Item1.Last(), out value3);
					}
					else if (tuple.Item1.StartsWith("Elbow_"))
					{
						transforms.TryGetValue("Hand_" + tuple.Item1.Last(), out value3);
					}
					else if (tuple.Item1.StartsWith("Hand_"))
					{
						transforms.TryGetValue("Middle_1_" + tuple.Item1.Last(), out value3);
					}
					else if (tuple.Item1.StartsWith("Leg_"))
					{
						transforms.TryGetValue("Knee_" + tuple.Item1.Last(), out value3);
					}
					else if (tuple.Item1.StartsWith("Knee_"))
					{
						transforms.TryGetValue("Foot_" + tuple.Item1.Last(), out value3);
					}
					else if (tuple.Item1.StartsWith("Foot_"))
					{
						transforms.TryGetValue("S_Toe_1_" + tuple.Item1.Last(), out value3);
					}
					Vector3 val5 = source.RestPosition(val4) - source.RestPosition(val3);
					Matrix4x4 value4;
					Vector3 val6 = ((Object.op_Implicit((Object)(object)value3) && dictionary.TryGetValue(value3, out value4)) ? Vector4.op_Implicit(((Matrix4x4)(ref value4)).GetColumn(3) - ((Matrix4x4)(ref value2)).GetColumn(3)) : Vector3.up);
					Quaternion val7 = ((((Vector3)(ref val5)).sqrMagnitude > 1E-08f && ((Vector3)(ref val6)).sqrMagnitude > 1E-08f) ? Quaternion.FromToRotation(val6, val5) : Quaternion.identity);
					Quaternion offset = Quaternion.Inverse(source.RestRotation(val3)) * val7 * ((Matrix4x4)(ref value2)).rotation;
					bindings.Add(new Binding
					{
						Target = value,
						Source = val3,
						Offset = offset
					});
				}
			}
			if (bindings.Count < 14)
			{
				throw new InvalidOperationException("Scout rig has only " + bindings.Count + " mapped bones");
			}
			hip = transforms["Hip"];
			contacts = (from n in new string[5] { "Foot_L", "Foot_R", "Hand_L", "Hand_R", "Head" }.Where(transforms.ContainsKey)
				select transforms[n]).ToArray();
			float num3 = 1f;
			if (dictionary.TryGetValue(transforms["Leg_L"], out var value5) && dictionary.TryGetValue(transforms["Knee_L"], out var value6) && dictionary.TryGetValue(transforms["Foot_L"], out var value7))
			{
				num3 = Vector3.Distance(Vector4.op_Implicit(((Matrix4x4)(ref value5)).GetColumn(3)), Vector4.op_Implicit(((Matrix4x4)(ref value6)).GetColumn(3))) + Vector3.Distance(Vector4.op_Implicit(((Matrix4x4)(ref value6)).GetColumn(3)), Vector4.op_Implicit(((Matrix4x4)(ref value7)).GetColumn(3)));
			}
			bodyScale = num3 / source.LegLength;
			Plugin.Instance.LoggerForRetarget($"Scout REPO mapping ready: {bindings.Count} bones, body scale {bodyScale:0.000}");
		}

		internal void CapturePhysicsPose()
		{
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: 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_0149: 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_015d: 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_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: 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_01ee: 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)
			if (!Active || !Object.op_Implicit((Object)(object)target) || !Object.op_Implicit((Object)(object)character))
			{
				return;
			}
			if (!Plugin.Playing.TryGetValue(character.refs.animations, out var value) || value.Move == null || !value.Move.Retarget)
			{
				Release();
				return;
			}
			source.Sample(Mathf.Max(0f, Time.fixedTime - started));
			float num = Mathf.Clamp01((Time.fixedTime - started) / 0.18f);
			float num2 = contacts.Where((Transform t) => ((Object)t).name.StartsWith("Foot_")).Min((Transform t) => t.position.y);
			PoseMotion = 0f;
			foreach (Binding binding in bindings)
			{
				Quaternion val = ((Component)target).transform.rotation * source.Rotation(binding.Source) * binding.Offset;
				PoseMotion += Quaternion.Angle(binding.Previous, val);
				binding.Previous = val;
				binding.Target.rotation = Quaternion.Slerp(binding.Target.rotation, val, num);
			}
			float num3 = Mathf.Clamp(num2 - contacts.Min((Transform t) => t.position.y), -0.9f, 0.9f);
			Transform obj = hip;
			obj.position += Vector3.up * num3 * num;
			PhysicsPoseUpdates++;
			LastPoseFixedTime = Time.fixedTime;
		}

		internal void Release()
		{
			if (Active)
			{
				Active = false;
				source?.Pause();
			}
		}

		private void OnDestroy()
		{
			Release();
			source?.Dispose();
			source = null;
		}
	}
}