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;
}
}
}