Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Valheim Too Many Emotes v1.0.0
plugins/Valheim_TooManyEmotes.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Managers; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Animations; using UnityEngine.Events; using UnityEngine.Playables; using UnityEngine.Rendering; using UnityEngine.UI; using Valheim.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [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 TooManyEmotes { public class Emote { public string Name; public AnimationClip Clip; public AnimationClip LoopClip; public bool IsPose; public string GroupName = ""; public int Layer = -1; public bool RandomInGroup; public string VariantName = ""; public List<Emote> Group; public bool Loops { get { if (!((Motion)Clip).isLooping) { return (Object)(object)LoopClip != (Object)null; } return true; } } public override string ToString() { return Name; } } public class EmoteEntry { public enum Kinds { Single, Random, Band } public string Key; public Kinds Kind; public List<Emote> Emotes = new List<Emote>(); public string Label => Translations.EmoteLabel(Key); } public static class EmoteBrowser { private enum Tab { Favorites, All, Vanilla, Tme } [CompilerGenerated] private static class <>O { public static UnityAction <0>__Close; public static UnityAction <1>__Stop; } private const float Width = 560f; private const float Height = 680f; private const float RowHeight = 30f; private static GameObject panel; private static InputField search; private static RectTransform content; private static Text countText; private static readonly Dictionary<Tab, Button> tabButtons = new Dictionary<Tab, Button>(); private static Tab tab = Tab.All; private static string builtLanguage; private static readonly CompareInfo Compare = CultureInfo.InvariantCulture.CompareInfo; public static bool IsOpen { get { if ((Object)(object)panel != (Object)null) { return panel.activeSelf; } return false; } } internal static List<MenuItem> Shown { get; private set; } = new List<MenuItem>(); public static void Toggle() { if (IsOpen) { Close(); } else { Open(); } } public static void Open() { if ((Object)(object)GUIManager.CustomGUIFront == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } string selectedLanguage = Localization.instance.GetSelectedLanguage(); if ((Object)(object)panel == (Object)null || builtLanguage != selectedLanguage) { if ((Object)(object)panel != (Object)null) { Object.Destroy((Object)(object)panel); } Build(); builtLanguage = selectedLanguage; } panel.SetActive(true); GUIManager.BlockInput(true); if (tab == Tab.Favorites && Favorites.Keys.Count == 0) { tab = Tab.All; } Refresh(); search.ActivateInputField(); } public static void Close() { if (IsOpen) { panel.SetActive(false); GUIManager.BlockInput(false); } } private static void Build() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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_013a: Expected O, but got Unknown //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0283: 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_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Expected O, but got Unknown //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Expected O, but got Unknown //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) //IL_049b: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Expected O, but got Unknown GUIManager instance = GUIManager.Instance; panel = instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 560f, 680f, true); ((Object)panel).name = "TooManyEmotesBrowser"; instance.CreateText(Translations.Ui("browser_title"), panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -32f), instance.AveriaSerifBold, 28, instance.ValheimOrange, true, Color.black, 440f, 40f, false).GetComponent<Text>().alignment = (TextAnchor)4; ButtonClickedEvent onClick = instance.CreateButton("X", panel.transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-38f, -34f), 40f, 40f).GetComponent<Button>().onClick; object obj = <>O.<0>__Close; if (obj == null) { UnityAction val = Close; <>O.<0>__Close = val; obj = (object)val; } ((UnityEvent)onClick).AddListener((UnityAction)obj); search = instance.CreateInputField(panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -80f), (ContentType)0, Translations.Ui("search"), 18, 500f, 34f).GetComponent<InputField>(); ((UnityEvent<string>)(object)search.onValueChanged).AddListener((UnityAction<string>)delegate { Refresh(); }); float num = 125f; (Tab, string)[] array = new(Tab, string)[4] { (Tab.Favorites, "favorites"), (Tab.All, "all"), (Tab.Vanilla, "vanilla"), (Tab.Tme, "category") }; tabButtons.Clear(); for (int num2 = 0; num2 < array.Length; num2++) { (Tab, string) tuple = array[num2]; Tab which = tuple.Item1; string item = tuple.Item2; GameObject obj2 = instance.CreateButton(Translations.Ui(item), panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(-250f + num * ((float)num2 + 0.5f), -124f), num - 6f, 36f); Text componentInChildren = obj2.GetComponentInChildren<Text>(); componentInChildren.resizeTextForBestFit = true; componentInChildren.resizeTextMinSize = 10; componentInChildren.resizeTextMaxSize = 16; Button component = obj2.GetComponent<Button>(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { tab = which; Refresh(); }); tabButtons[which] = component; } GameObject obj3 = instance.CreateScrollView(panel.transform, false, true, 8f, 4f, instance.ValheimScrollbarHandleColorBlock, new Color(0f, 0f, 0f, 0.4f), 500f, 430f); RectTransform val2 = (RectTransform)obj3.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; val2.anchoredPosition = new Vector2(0f, -14f); content = obj3.GetComponentInChildren<ScrollRect>().content; VerticalLayoutGroup component2 = ((Component)content).GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = 2f; ((LayoutGroup)component2).padding = new RectOffset(4, 4, 4, 4); countText = instance.CreateText("", panel.transform, new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(110f, 34f), instance.AveriaSerif, 16, Color.white, true, Color.black, 180f, 30f, false).GetComponent<Text>(); ButtonClickedEvent onClick2 = instance.CreateButton(Translations.Ui("stop"), panel.transform, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-110f, 34f), 160f, 36f).GetComponent<Button>().onClick; object obj4 = <>O.<1>__Stop; if (obj4 == null) { UnityAction val4 = EmotePlayer.Stop; <>O.<1>__Stop = val4; obj4 = (object)val4; } ((UnityEvent)onClick2).AddListener((UnityAction)obj4); panel.SetActive(false); } private static List<MenuItem> ItemsOf(Tab which) { return which switch { Tab.Favorites => MenuCatalog.FavoriteItems, Tab.Vanilla => MenuCatalog.Vanilla, Tab.Tme => MenuCatalog.TmeWithParts, _ => MenuCatalog.All, }; } private static bool Matches(MenuItem item, string filter) { if (filter.Length != 0) { return Compare.IndexOf(item.Label, filter, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace) >= 0; } return true; } private static void Refresh() { if ((Object)(object)panel == (Object)null) { return; } foreach (KeyValuePair<Tab, Button> tabButton in tabButtons) { ((Selectable)tabButton.Value).interactable = tabButton.Key != tab; } string filter = search.text.Trim(); Shown = (from i in ItemsOf(tab) where Matches(i, filter) select i).ToList(); for (int num = ((Transform)content).childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Transform)content).GetChild(num)).gameObject); } foreach (MenuItem item in Shown) { AddRow(item); } countText.text = Translations.Ui("count", Shown.Count); if (tab == Tab.Favorites && Shown.Count == 0 && filter.Length == 0) { AddMessage(Translations.Ui("no_favorites")); } } private static void AddRow(MenuItem item) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0055: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown GUIManager instance = GUIManager.Instance; GameObject val = new GameObject("Row", new Type[2] { typeof(RectTransform), typeof(LayoutElement) }); val.transform.SetParent((Transform)(object)content, false); ((RectTransform)val.transform).sizeDelta = new Vector2(470f, 30f); val.GetComponent<LayoutElement>().preferredHeight = 30f; GameObject obj = instance.CreateToggle(val.transform, 24f, 24f); RectTransform val2 = (RectTransform)obj.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; val2.anchoredPosition = new Vector2(16f, 0f); Toggle component = obj.GetComponent<Toggle>(); component.isOn = Favorites.Contains(item.Key); ((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate(bool on) { if (on != Favorites.Contains(item.Key)) { Favorites.Toggle(item.Key); } }); GameObject obj2 = instance.CreateButton(item.Label, val.transform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(250f, 0f), 420f, 28f); Text componentInChildren = obj2.GetComponentInChildren<Text>(); componentInChildren.alignment = (TextAnchor)3; componentInChildren.fontSize = 16; ((Graphic)componentInChildren).rectTransform.offsetMin = new Vector2(10f, 0f); ((UnityEvent)obj2.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { item.Play(); }); } private static void AddMessage(string text) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) GUIManager instance = GUIManager.Instance; GameObject obj = instance.CreateText(text, (Transform)(object)content, Vector2.zero, Vector2.one, Vector2.zero, instance.AveriaSerif, 16, Color.white, true, Color.black, 460f, 80f, false); obj.AddComponent<LayoutElement>().preferredHeight = 80f; obj.GetComponent<Text>().alignment = (TextAnchor)4; } internal static void Update() { if (IsOpen) { if ((Object)(object)Player.m_localPlayer == (Object)null) { Close(); } else if (ZInput.GetKeyDown((KeyCode)27, false)) { Close(); } } } internal static void Destroy() { if ((Object)(object)panel != (Object)null) { Object.Destroy((Object)(object)panel); panel = null; } } } [HarmonyPatch(typeof(Menu), "Update")] internal static class MenuEscapePatch { private static bool Prefix() { return !EmoteBrowser.IsOpen; } } public class EmoteController : MonoBehaviour { private const float FadeInTime = 0.25f; private const float FadeOutTime = 0.3f; private const float MaxAirTime = 0.4f; private static readonly int ZdoEmote = StringExtensionMethods.GetStableHashCode("TME_emote"); private static readonly int ZdoId = StringExtensionMethods.GetStableHashCode("TME_id"); private static readonly int ZdoStart = StringExtensionMethods.GetStableHashCode("TME_start"); private static readonly FieldRef<Character, Animator> AnimatorRef = AccessTools.FieldRefAccess<Character, Animator>("m_animator"); private static readonly FieldRef<Character, ZNetView> NViewRef = AccessTools.FieldRefAccess<Character, ZNetView>("m_nview"); private static readonly FieldRef<Humanoid, ItemData> HiddenRightRef = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_hiddenRightItem"); private static readonly FieldRef<Humanoid, ItemData> HiddenLeftRef = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_hiddenLeftItem"); private static readonly MethodInfo ShowHandItemsMethod = AccessTools.Method(typeof(Humanoid), "ShowHandItems", (Type[])null, (Type[])null); private static readonly MethodInfo VanillaStopEmoteMethod = AccessTools.Method(typeof(Player), "StopEmote", (Type[])null, (Type[])null); private static readonly MethodInfo SetCrouchMethod = AccessTools.Method(typeof(Player), "SetCrouch", (Type[])null, (Type[])null); internal static readonly Dictionary<Animator, EmoteController> Active = new Dictionary<Animator, EmoteController>(); internal static readonly Dictionary<Player, EmoteController> Emoting = new Dictionary<Player, EmoteController>(); private Player player; private Animator animator; private ZNetView nview; private PlayableGraph graph; private AnimationPlayableOutput output; private AnimationMixerPlayable mixer; private AnimationClipPlayable introPlayable; private AnimationClipPlayable loopPlayable; private bool inLoopPhase; private float weight; private float targetWeight; private bool savedApplyRootMotion; private int appliedId = -1; private float airTime; internal bool stoppingVanilla; private bool inSession; private bool hidItems; private float inactiveSince = -1f; public Emote Current { get; private set; } public bool IsEmoting { get { if (Current != null) { return targetWeight > 0f; } return false; } } public float Weight { get { if (!((PlayableGraph)(ref graph)).IsValid()) { return 0f; } return weight; } } public Animator Animator => animator; public Player Player => player; private bool IsOwner { get { if ((Object)(object)nview != (Object)null && nview.IsValid()) { return nview.IsOwner(); } return false; } } private ZDO Zdo { get { if (!((Object)(object)nview != (Object)null) || !nview.IsValid()) { return null; } return nview.GetZDO(); } } public float CurrentTime { get { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (((PlayableGraph)(ref graph)).IsValid() && Current != null) { if (!inLoopPhase) { return (float)PlayableExtensions.GetTime<AnimationClipPlayable>(introPlayable); } return Current.Clip.length + (float)PlayableExtensions.GetTime<AnimationClipPlayable>(loopPlayable); } return 0f; } } internal bool InSession => inSession; internal bool HidItems => hidItems; public static EmoteController For(Player player) { if ((Object)(object)player == (Object)null) { return null; } EmoteController emoteController = ((Component)player).GetComponent<EmoteController>(); if ((Object)(object)emoteController == (Object)null) { emoteController = ((Component)player).gameObject.AddComponent<EmoteController>(); } return emoteController; } internal static float WeightOf(Animator animator) { if (!((Object)(object)animator != (Object)null) || !Active.TryGetValue(animator, out var value) || !((Object)(object)value != (Object)null)) { return 0f; } return value.Weight; } private void Awake() { player = ((Component)this).GetComponent<Player>(); animator = AnimatorRef.Invoke((Character)(object)player); nview = NViewRef.Invoke((Character)(object)player); } internal static void Trace(string message) { if (Plugin.Verbose) { Plugin.Log.LogMessage((object)("[EmoteController] " + message)); } } public string DescribeGraph() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!((PlayableGraph)(ref graph)).IsValid()) { return "graph=none"; } string text = $"graph playing={((PlayableGraph)(ref graph)).IsPlaying()} outputWeight={PlayableOutputExtensions.GetWeight<AnimationPlayableOutput>(output):0.00} weight={weight:0.00} target={targetWeight:0.00} "; object arg = PlayableExtensions.GetTime<AnimationClipPlayable>(introPlayable); Emote current = Current; return text + $"intro t={arg:0.00}/{((current != null) ? new float?(current.Clip.length) : ((float?)null)):0.00} loopPhase={inLoopPhase}"; } public string DescribeState() { return $"dead={((Character)player).IsDead()} ground={((Character)player).IsOnGround()} swim={((Character)player).IsSwimming()} attached={((Character)player).IsAttached()} " + $"ship={((Character)player).IsAttachedToShip()} attack={((Character)player).InAttack()} dodge={((Character)player).InDodge()} stagger={((Character)player).IsStaggering()} " + $"canMove={((Character)player).CanMove()} bow={((Character)player).IsDrawingBow()} teleport={((Character)player).IsTeleporting()} bed={((Character)player).InBed()} " + "right=" + (((Humanoid)player).RightItem?.m_shared.m_name ?? "none") + " left=" + (((Humanoid)player).LeftItem?.m_shared.m_name ?? "none"); } public bool CanEmote() { bool flag = IsOwner && Zdo.GetString(ZDOVars.s_emote, "") != ""; if ((Object)(object)player != (Object)null && (Object)(object)animator != (Object)null && animator.isHuman && IsOwner && !((Character)player).IsDead() && ((Character)player).IsOnGround() && !((Character)player).IsSwimming() && (((Character)player).CanMove() || flag) && !((Character)player).InAttack() && !((Character)player).InDodge() && !((Character)player).IsDrawingBow() && !((Character)player).IsStaggering() && !((Character)player).IsAttached() && !((Character)player).IsAttachedToShip() && !((Character)player).IsTeleporting()) { return !((Character)player).InBed(); } return false; } public bool RequestPlay(Emote emote, float startTime = 0f) { if (emote == null) { return false; } if (!CanEmote()) { Trace("cannot emote " + emote.Name + ": " + DescribeState()); return false; } BeginSession(); stoppingVanilla = true; try { VanillaStopEmoteMethod.Invoke(player, null); } finally { stoppingVanilla = false; } SetCrouchMethod.Invoke(player, new object[1] { false }); ZDO zdo = Zdo; zdo.Set(ZdoEmote, emote.Name); zdo.Set(ZdoStart, ZNet.instance.GetTime().Ticks - (long)(startTime * 10000000f)); zdo.Set(ZdoId, zdo.GetInt(ZdoId, 0) + 1, false); SyncFromZdo(); return true; } public void RequestStop() { ZDO zdo = Zdo; if (zdo != null && IsOwner && !(zdo.GetString(ZdoEmote, "") == "")) { zdo.Set(ZdoEmote, ""); zdo.Set(ZdoId, zdo.GetInt(ZdoId, 0) + 1, false); SyncFromZdo(); } } private string InterruptReason() { if (((Character)player).IsDead()) { return "dead"; } if (((Character)player).IsSwimming()) { return "swimming"; } if (((Character)player).IsAttached() || ((Character)player).IsAttachedToShip()) { return "attached"; } if (((Character)player).InAttack()) { return "attack"; } if (((Character)player).InDodge()) { return "dodge"; } if (((Character)player).IsStaggering()) { return "stagger"; } if (((Character)player).IsTeleporting()) { return "teleport"; } if (((Character)player).InBed()) { return "bed"; } if (((Character)player).IsDrawingBow()) { return "bow"; } if (airTime > 0.4f) { return "airborne"; } return null; } private void BeginSession() { if (!inSession) { Trace("session begins: " + DescribeState()); inSession = true; inactiveSince = -1f; hidItems = false; if (Plugin.HideHandItems.Value && (((Humanoid)player).RightItem != null || ((Humanoid)player).LeftItem != null)) { hidItems = ((Humanoid)player).HideHandItems(false, true); Trace($"hand items hidden: {hidItems}"); } } } private void UpdateSession() { if (!inSession) { return; } if (IsEmoting) { inactiveSince = -1f; return; } if (inactiveSince < 0f) { inactiveSince = Time.time; } if (Time.time - inactiveSince < 0.3f) { return; } inSession = false; Trace($"session ends (hid items: {hidItems})"); if (hidItems && !((Character)player).IsDead()) { hidItems = false; if (((Humanoid)player).RightItem == null && ((Humanoid)player).LeftItem == null && (HiddenRightRef.Invoke((Humanoid)(object)player) != null || HiddenLeftRef.Invoke((Humanoid)(object)player) != null) && (!((Character)player).IsSwimming() || ((Character)player).IsOnGround())) { Trace("showing hand items again"); ShowHandItemsMethod.Invoke(player, new object[2] { false, true }); } } } private void SyncFromZdo() { ZDO zdo = Zdo; if (zdo == null || !EmoteLibrary.Ready) { return; } int num = zdo.GetInt(ZdoId, 0); if (num == appliedId) { return; } appliedId = num; string text = zdo.GetString(ZdoEmote, ""); if (string.IsNullOrEmpty(text) || !EmoteLibrary.ByName.TryGetValue(text, out var value)) { if (!string.IsNullOrEmpty(text)) { Trace("unknown emote '" + text + "' on " + player.GetPlayerName()); } FadeOut(); } else { float num2 = Mathf.Max(0f, (float)((double)(ZNet.instance.GetTime().Ticks - zdo.GetLong(ZdoStart, 0L)) / 10000000.0)); if (!value.Loops && !value.IsPose && num2 >= value.Clip.length) { FadeOut(); } else { Begin(value, num2); } } } private void Begin(Emote emote, float startTime) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) bool num = ((PlayableGraph)(ref graph)).IsValid(); if (num) { ((PlayableGraph)(ref graph)).Destroy(); } else { savedApplyRootMotion = animator.applyRootMotion; } graph = PlayableGraph.Create("TooManyEmotes_" + player.GetPlayerID()); ((PlayableGraph)(ref graph)).SetTimeUpdateMode((DirectorUpdateMode)1); output = AnimationPlayableOutput.Create(graph, "Emote", animator); mixer = AnimationMixerPlayable.Create(graph, 2); introPlayable = AnimationClipPlayable.Create(graph, emote.Clip); ((PlayableGraph)(ref graph)).Connect<AnimationClipPlayable, AnimationMixerPlayable>(introPlayable, 0, mixer, 0); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(mixer, 0, 1f); if ((Object)(object)emote.LoopClip != (Object)null) { loopPlayable = AnimationClipPlayable.Create(graph, emote.LoopClip); ((PlayableGraph)(ref graph)).Connect<AnimationClipPlayable, AnimationMixerPlayable>(loopPlayable, 0, mixer, 1); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(mixer, 1, 0f); PlayableExtensions.Pause<AnimationClipPlayable>(loopPlayable); } PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationMixerPlayable>(output, mixer); animator.applyRootMotion = false; Current = emote; inLoopPhase = false; if (startTime > 0f) { if (PlayableExtensions.IsValid<AnimationClipPlayable>(loopPlayable) && startTime >= emote.Clip.length) { PlayableExtensions.SetTime<AnimationClipPlayable>(introPlayable, (double)emote.Clip.length); PlayableExtensions.Pause<AnimationClipPlayable>(introPlayable); PlayableExtensions.SetTime<AnimationClipPlayable>(loopPlayable, (double)((startTime - emote.Clip.length) % Mathf.Max(emote.LoopClip.length, 0.01f))); PlayableExtensions.Play<AnimationClipPlayable>(loopPlayable); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(mixer, 0, 0f); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(mixer, 1, 1f); inLoopPhase = true; } else if (emote.IsPose && !((Motion)emote.Clip).isLooping) { PlayableExtensions.SetTime<AnimationClipPlayable>(introPlayable, (double)Mathf.Min(startTime, emote.Clip.length)); } else { PlayableExtensions.SetTime<AnimationClipPlayable>(introPlayable, (double)(((Motion)emote.Clip).isLooping ? (startTime % Mathf.Max(emote.Clip.length, 0.01f)) : startTime)); } } if (!num) { weight = 0f; } targetWeight = 1f; PlayableOutputExtensions.SetWeight<AnimationPlayableOutput>(output, weight); ((PlayableGraph)(ref graph)).Play(); Active[animator] = this; Emoting[player] = this; Trace($"started {emote.Name} on {player.GetPlayerName()} at {startTime:0.00} s: {DescribeGraph()}"); } private void FadeOut() { targetWeight = 0f; Emoting.Remove(player); } internal void SnapWeight() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (((PlayableGraph)(ref graph)).IsValid()) { weight = targetWeight; PlayableOutputExtensions.SetWeight<AnimationPlayableOutput>(output, weight); } } private void Update() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } SyncFromZdo(); if (IsOwner) { airTime = (((Character)player).IsOnGround() ? 0f : (airTime + Time.deltaTime)); if (IsEmoting) { string text = InterruptReason(); if (text != null) { Trace("interrupted (" + text + "): " + DescribeState()); RequestStop(); } } UpdateSession(); } if (((PlayableGraph)(ref graph)).IsValid()) { if (targetWeight > 0f) { AdvancePhase(); } float num = ((targetWeight > weight) ? 0.25f : 0.3f); weight = Mathf.MoveTowards(weight, targetWeight, Time.deltaTime / num); PlayableOutputExtensions.SetWeight<AnimationPlayableOutput>(output, weight); if (weight <= 0f && targetWeight <= 0f) { Teardown(); } } } private void LateUpdate() { if (((PlayableGraph)(ref graph)).IsValid() && Current != null && weight > 0f) { FingerCurl.Apply(animator, inLoopPhase ? Current.LoopClip : Current.Clip, weight); } } private void AdvancePhase() { //IL_000a: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) if (inLoopPhase || PlayableExtensions.GetTime<AnimationClipPlayable>(introPlayable) < (double)Current.Clip.length) { return; } if (PlayableExtensions.IsValid<AnimationClipPlayable>(loopPlayable)) { PlayableExtensions.SetTime<AnimationClipPlayable>(loopPlayable, 0.0); PlayableExtensions.Play<AnimationClipPlayable>(loopPlayable); PlayableExtensions.Pause<AnimationClipPlayable>(introPlayable); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(mixer, 0, 0f); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(mixer, 1, 1f); inLoopPhase = true; } else if (Current.IsPose && !((Motion)Current.Clip).isLooping) { PlayableExtensions.Pause<AnimationClipPlayable>(introPlayable); } else if (!((Motion)Current.Clip).isLooping) { if (IsOwner) { RequestStop(); } else { FadeOut(); } } } private void Teardown() { if (((PlayableGraph)(ref graph)).IsValid()) { Trace("teardown " + Current?.Name); ((PlayableGraph)(ref graph)).Destroy(); if ((Object)(object)animator != (Object)null) { animator.applyRootMotion = savedApplyRootMotion; } } if ((Object)(object)animator != (Object)null) { Active.Remove(animator); } Emoting.Remove(player); Current = null; inLoopPhase = false; weight = 0f; targetWeight = 0f; } private void OnDisable() { Teardown(); } private void OnDestroy() { Teardown(); } } public static class EmoteLibrary { private static readonly string[] BundleNames = new string[6] { "emotes_complementary", "emotes_0", "emotes_1", "emotes_2", "emotes_3", "emotes_special" }; public static readonly List<Emote> All = new List<Emote>(); public static readonly Dictionary<string, Emote> ByName = new Dictionary<string, Emote>(); public static readonly List<EmoteEntry> Entries = new List<EmoteEntry>(); public static readonly Dictionary<string, EmoteEntry> EntryByKey = new Dictionary<string, EmoteEntry>(); internal static readonly List<AssetBundle> Bundles = new List<AssetBundle>(); public static bool Ready { get; private set; } internal static IEnumerable<string> BundleFileNames => BundleNames; public static IEnumerator Load(string assetsDir) { Stopwatch timer = Stopwatch.StartNew(); Dictionary<string, AnimationClip> clips = new Dictionary<string, AnimationClip>(); string[] bundleNames = BundleNames; foreach (string path in bundleNames) { string path2 = Path.Combine(assetsDir, path); AssetBundleCreateRequest bundleRequest = AssetBundle.LoadFromFileAsync(path2); yield return bundleRequest; AssetBundle assetBundle = bundleRequest.assetBundle; if ((Object)(object)assetBundle == (Object)null) { Plugin.Log.LogError((object)("Failed to load emote bundle " + path2)); continue; } Bundles.Add(assetBundle); AssetBundleRequest assetsRequest = assetBundle.LoadAllAssetsAsync<AnimationClip>(); yield return assetsRequest; foreach (AnimationClip item in assetsRequest.allAssets.OfType<AnimationClip>()) { if (!clips.ContainsKey(((Object)item).name)) { clips.Add(((Object)item).name, item); } } } Build(clips); Ready = true; MenuCatalog.Invalidate(); Plugin.Log.LogMessage((object)$"Emote library loaded in {timer.ElapsedMilliseconds} ms (in the background)"); } private static void Build(Dictionary<string, AnimationClip> clips) { Dictionary<string, List<Emote>> dictionary = new Dictionary<string, List<Emote>>(); foreach (AnimationClip item in clips.Values.OrderBy<AnimationClip, string>((AnimationClip c) => ((Object)c).name, StringComparer.Ordinal)) { if (((Object)item).name.EndsWith("_loop") && clips.ContainsKey(((Object)item).name.Substring(0, ((Object)item).name.Length - 5) + "_start")) { continue; } Emote emote = Parse(item, clips); if (emote == null || ByName.ContainsKey(emote.Name)) { continue; } All.Add(emote); ByName.Add(emote.Name, emote); if (emote.GroupName.Length != 0) { if (!dictionary.TryGetValue(emote.GroupName, out var value)) { dictionary.Add(emote.GroupName, value = new List<Emote>()); } value.Add(emote); emote.Group = value; } } foreach (Emote item2 in All.Where((Emote e) => e.GroupName.Length == 0)) { AddEntry(new EmoteEntry { Key = item2.Name, Kind = EmoteEntry.Kinds.Single, Emotes = { item2 } }); } foreach (KeyValuePair<string, List<Emote>> item3 in dictionary) { List<Emote> value2 = item3.Value; bool flag = value2.Any((Emote e) => e.Layer >= 0); if (flag) { value2.Sort((Emote a, Emote b) => a.Layer.CompareTo(b.Layer)); } AddEntry(new EmoteEntry { Key = item3.Key, Kind = ((!flag) ? EmoteEntry.Kinds.Random : EmoteEntry.Kinds.Band), Emotes = value2.ToList() }); } Plugin.Log.LogMessage((object)$"Loaded {clips.Count} clips: {All.Count} emotes, {Entries.Count} menu entries, {dictionary.Count} groups."); } private static void AddEntry(EmoteEntry entry) { Entries.Add(entry); EntryByKey[entry.Key] = entry; } private static Emote Parse(AnimationClip clip, Dictionary<string, AnimationClip> clips) { Emote emote = new Emote { Clip = clip }; string text = ((Object)clip).name; if (text.EndsWith("_start") && clips.TryGetValue(text.Substring(0, text.Length - 6) + "_loop", out var value)) { emote.LoopClip = value; text = text.Substring(0, text.Length - 6); } else if (text.EndsWith("_pose")) { emote.IsPose = true; text = text.Substring(0, text.Length - 5); } if (text.Contains(".")) { string[] array = text.Split('.'); if (array.Length == 2 && array[1].Length == 0) { emote.Name = text; return emote; } if (array.Length > 3 || array[0].Length == 0) { Plugin.Log.LogWarning((object)("Unexpected emote name format: " + ((Object)clip).name)); return null; } emote.GroupName = array[0]; emote.VariantName = array[^1]; if (array.Length == 3) { string text2 = array[1].ToLowerInvariant(); if (text2.StartsWith("layer_") && int.TryParse(text2.Substring(6), out var result)) { emote.Layer = result; } else if (text2 == "random") { emote.RandomInGroup = true; } } if (emote.GroupName.EndsWith("_pose")) { emote.IsPose = true; } } emote.Name = text; return emote; } } public static class EmotePreview { [CompilerGenerated] private static class <>O { public static CameraCallback <0>__OnPreCull; public static CameraCallback <1>__OnPostRender; } private const int TextureSize = 512; private const float RestartPause = 0.6f; private const float PoseHold = 1.5f; private static readonly Vector3 Origin = new Vector3(0f, 6000f, 0f); private static readonly Color Background = new Color(0.075f, 0.065f, 0.055f, 1f); private static readonly FieldRef<Character, Animator> AnimatorRef = AccessTools.FieldRefAccess<Character, Animator>("m_animator"); private static readonly string[] HandItemFields = new string[2] { "m_rightItemInstance", "m_leftItemInstance" }; private static RenderTexture texture; private static Camera camera; private static readonly List<Light> lights = new List<Light>(); private static int layer = -1; private static GameObject holder; private static Animator animator; private static PlayableGraph graph; private static AnimationMixerPlayable mixer; private static AnimationClipPlayable intro; private static AnimationClipPlayable loop; private static MenuItem shown; private static Emote emote; private static string vanillaName; private static bool vanillaOneShot; private static float startedAt; private static float endedAt = -1f; private static readonly int EmoteTag = Animator.StringToHash("emote"); private static AmbientMode savedAmbientMode; private static Color savedAmbient; private static bool savedFog; private static bool overridden; public static Texture Texture => (Texture)(object)texture; public static bool Active => (Object)(object)holder != (Object)null; internal static Animator PreviewAnimator => animator; internal static Camera PreviewCamera => camera; private static void Trace(string message) { if (Plugin.Verbose) { Plugin.Log.LogMessage((object)("[EmotePreview] " + message)); } } public static bool Begin(Player player) { End(); Animator val = (((Object)(object)player != (Object)null) ? AnimatorRef.Invoke((Character)(object)player) : null); if ((Object)(object)val == (Object)null || !val.isHuman) { return false; } if (!EnsureStage()) { return false; } try { BuildCopy(player, val); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Emote preview unavailable: " + ex)); End(); return false; } ((Behaviour)camera).enabled = true; Trace($"model copied: {holder.GetComponentsInChildren<Renderer>().Length} renderers"); return true; } public static void End() { StopAll(); if ((Object)(object)holder != (Object)null) { Object.Destroy((Object)(object)holder); } holder = null; animator = null; shown = null; if ((Object)(object)camera != (Object)null) { ((Behaviour)camera).enabled = false; } } public static void Show(MenuItem item) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (item == shown || (Object)(object)animator == (Object)null) { return; } Trace("show " + (item?.Key ?? "nothing")); shown = item; StopAll(); if (!(item is TmeItem tmeItem)) { if (!(item is TmePartItem tmePartItem)) { if (item is VanillaItem vanillaItem) { Emote attributeOfType = Utils.GetAttributeOfType<Emote>((Enum)(object)vanillaItem.Emote); vanillaName = ((object)vanillaItem.Emote/*cast due to .constrained prefix*/).ToString().ToLower(); vanillaOneShot = attributeOfType?.OneShot ?? true; PlayVanilla(); } } else { PlayTme(tmePartItem.Part); } } else { PlayTme(tmeItem.Entry.Emotes[0]); } } public static void Update() { if (!((Object)(object)animator == (Object)null)) { if (emote != null && ((PlayableGraph)(ref graph)).IsValid()) { UpdateTme(); } else if (vanillaName != null) { UpdateVanilla(); } } } public static void LateUpdate() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)animator == (Object)null) && emote != null && ((PlayableGraph)(ref graph)).IsValid()) { bool flag = PlayableExtensions.IsValid<AnimationClipPlayable>(loop) && PlayableExtensions.GetInputWeight<AnimationMixerPlayable>(mixer, 1) > 0f; FingerCurl.Apply(animator, flag ? emote.LoopClip : emote.Clip, 1f); } } private static void PlayTme(Emote which) { //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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) emote = which; graph = PlayableGraph.Create("TooManyEmotes_Preview"); ((PlayableGraph)(ref graph)).SetTimeUpdateMode((DirectorUpdateMode)2); AnimationPlayableOutput val = AnimationPlayableOutput.Create(graph, "Preview", animator); mixer = AnimationMixerPlayable.Create(graph, 2); intro = AnimationClipPlayable.Create(graph, which.Clip); ((PlayableGraph)(ref graph)).Connect<AnimationClipPlayable, AnimationMixerPlayable>(intro, 0, mixer, 0); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(mixer, 0, 1f); if ((Object)(object)which.LoopClip != (Object)null) { loop = AnimationClipPlayable.Create(graph, which.LoopClip); ((PlayableGraph)(ref graph)).Connect<AnimationClipPlayable, AnimationMixerPlayable>(loop, 0, mixer, 1); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(mixer, 1, 0f); PlayableExtensions.Pause<AnimationClipPlayable>(loop); } PlayableOutputExtensions.SetSourcePlayable<AnimationPlayableOutput, AnimationMixerPlayable>(val, mixer); PlayableOutputExtensions.SetWeight<AnimationPlayableOutput>(val, 1f); ((PlayableGraph)(ref graph)).Play(); endedAt = -1f; startedAt = Time.unscaledTime; } private static void UpdateTme() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_00a6: 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_0114: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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) if (PlayableExtensions.IsValid<AnimationClipPlayable>(loop) && PlayableExtensions.GetInputWeight<AnimationMixerPlayable>(mixer, 1) > 0f) { return; } if (endedAt >= 0f) { if (Time.unscaledTime - endedAt >= (emote.IsPose ? 1.5f : 0.6f)) { PlayableExtensions.SetTime<AnimationClipPlayable>(intro, 0.0); PlayableExtensions.Play<AnimationClipPlayable>(intro); endedAt = -1f; } } else if (!((Motion)emote.Clip).isLooping && !(PlayableExtensions.GetTime<AnimationClipPlayable>(intro) < (double)emote.Clip.length)) { if (PlayableExtensions.IsValid<AnimationClipPlayable>(loop)) { PlayableExtensions.SetTime<AnimationClipPlayable>(loop, 0.0); PlayableExtensions.Play<AnimationClipPlayable>(loop); PlayableExtensions.Pause<AnimationClipPlayable>(intro); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(mixer, 0, 0f); PlayableExtensions.SetInputWeight<AnimationMixerPlayable>(mixer, 1, 1f); } else { PlayableExtensions.SetTime<AnimationClipPlayable>(intro, (double)emote.Clip.length); PlayableExtensions.Pause<AnimationClipPlayable>(intro); endedAt = Time.unscaledTime; } } } private static void PlayVanilla() { animator.ResetTrigger("emote_stop"); if (vanillaOneShot) { animator.SetTrigger("emote_" + vanillaName); } else { animator.SetBool("emote_" + vanillaName, true); } startedAt = Time.unscaledTime; endedAt = -1f; } private static void UpdateVanilla() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (vanillaOneShot && !(Time.unscaledTime - startedAt < 0.5f)) { AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(0); if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).tagHash == EmoteTag || animator.IsInTransition(0)) { endedAt = -1f; } else if (endedAt < 0f) { endedAt = Time.unscaledTime; } else if (Time.unscaledTime - endedAt >= 0.6f) { PlayVanilla(); } } } private static void StopAll() { if (((PlayableGraph)(ref graph)).IsValid()) { ((PlayableGraph)(ref graph)).Destroy(); } emote = null; if ((Object)(object)animator != (Object)null && vanillaName != null) { if (!vanillaOneShot) { animator.SetBool("emote_" + vanillaName, false); } animator.ResetTrigger("emote_" + vanillaName); animator.SetTrigger("emote_stop"); } vanillaName = null; endedAt = -1f; } private static bool EnsureStage() { //IL_0073: 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_0088: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_015a: 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_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0174: 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_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018f: 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_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: 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_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Expected O, but got Unknown //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Expected O, but got Unknown //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Expected O, but got Unknown //IL_02c3: 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_029b: Expected O, but got Unknown if ((Object)(object)camera != (Object)null) { ExcludeLayerFromGame(); return true; } int num = 31; while (num >= 8 && layer < 0) { if (string.IsNullOrEmpty(LayerMask.LayerToName(num))) { layer = num; } num--; } if (layer < 0) { Plugin.Log.LogWarning((object)"Emote preview unavailable: no free layer"); return false; } Camera mainCamera = Utils.GetMainCamera(); if ((Object)(object)mainCamera == (Object)null) { return false; } texture = new RenderTexture(512, 512, 24, (RenderTextureFormat)0) { name = "TooManyEmotes_Preview" }; GameObject val = new GameObject("TooManyEmotes_PreviewStage"); Object.DontDestroyOnLoad((Object)(object)val); GameObject val2 = new GameObject("Camera"); val2.transform.SetParent(val.transform, false); camera = val2.AddComponent<Camera>(); camera.CopyFrom(mainCamera); ((Behaviour)camera).enabled = false; camera.clearFlags = (CameraClearFlags)2; camera.backgroundColor = Background; camera.cullingMask = 1 << layer; camera.fieldOfView = 30f; camera.nearClipPlane = 0.1f; camera.farClipPlane = 30f; camera.useOcclusionCulling = false; camera.depth = -50f; camera.targetTexture = texture; Vector3 val3 = Origin + Vector3.up * 0.88f; val2.transform.position = val3 + new Vector3(1.7f, 0.35f, 5.1f); val2.transform.LookAt(val3); AddLight(val, "Key", new Color(1f, 0.93f, 0.82f), 1.15f, new Vector3(35f, 200f, 0f)); AddLight(val, "Fill", new Color(0.65f, 0.75f, 1f), 0.45f, new Vector3(10f, 120f, 0f)); AddLight(val, "Rim", new Color(1f, 0.8f, 0.55f), 0.6f, new Vector3(20f, 20f, 0f)); CameraCallback onPreCull = Camera.onPreCull; object obj = <>O.<0>__OnPreCull; if (obj == null) { CameraCallback val4 = OnPreCull; <>O.<0>__OnPreCull = val4; obj = (object)val4; } Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)onPreCull, (Delegate?)obj); CameraCallback onPostRender = Camera.onPostRender; object obj2 = <>O.<1>__OnPostRender; if (obj2 == null) { CameraCallback val5 = OnPostRender; <>O.<1>__OnPostRender = val5; obj2 = (object)val5; } Camera.onPostRender = (CameraCallback)Delegate.Combine((Delegate?)(object)onPostRender, (Delegate?)obj2); ExcludeLayerFromGame(); Trace($"stage: layer {layer}, path {camera.actualRenderingPath}, hdr {camera.allowHDR}"); return true; } private static void AddLight(GameObject parent, string name, Color color, float intensity, Vector3 euler) { //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) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) GameObject val = new GameObject(name); val.transform.SetParent(parent.transform, false); val.transform.rotation = Quaternion.Euler(euler); Light val2 = val.AddComponent<Light>(); val2.type = (LightType)1; val2.color = color; val2.intensity = intensity; val2.shadows = (LightShadows)0; val2.cullingMask = 1 << layer; lights.Add(val2); } private static void ExcludeLayerFromGame() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 int num = ~(1 << layer); Camera[] allCameras = Camera.allCameras; foreach (Camera val in allCameras) { if ((Object)(object)val != (Object)(object)camera) { val.cullingMask &= num; } } Light[] array = Object.FindObjectsByType<Light>((FindObjectsSortMode)0); foreach (Light val2 in array) { if ((int)val2.type == 1 && !lights.Contains(val2)) { val2.cullingMask &= num; } } } private static void OnPreCull(Camera cam) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)cam != (Object)(object)camera) && !overridden) { overridden = true; savedAmbientMode = RenderSettings.ambientMode; savedAmbient = RenderSettings.ambientLight; savedFog = RenderSettings.fog; RenderSettings.ambientMode = (AmbientMode)3; RenderSettings.ambientLight = new Color(0.42f, 0.4f, 0.38f); RenderSettings.fog = false; } } private static void OnPostRender(Camera cam) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)cam != (Object)(object)camera) && overridden) { overridden = false; RenderSettings.ambientMode = savedAmbientMode; RenderSettings.ambientLight = savedAmbient; RenderSettings.fog = savedFog; } } private static void BuildCopy(Player player, Animator source) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) holder = new GameObject("TooManyEmotes_PreviewModel"); holder.SetActive(false); holder.transform.position = Origin; GameObject gameObject = ((Component)source).gameObject; GameObject val = Object.Instantiate<GameObject>(gameObject, holder.transform, false); ((Object)val).name = "Visual"; val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = gameObject.transform.localScale; Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true); Renderer[] componentsInChildren2 = val.GetComponentsInChildren<Renderer>(true); MaterialPropertyBlock val2 = new MaterialPropertyBlock(); for (int i = 0; i < componentsInChildren.Length && i < componentsInChildren2.Length; i++) { if (componentsInChildren[i].HasPropertyBlock()) { componentsInChildren[i].GetPropertyBlock(val2); componentsInChildren2[i].SetPropertyBlock(val2); } } foreach (SkinnedMeshRenderer item in componentsInChildren2.OfType<SkinnedMeshRenderer>()) { item.updateWhenOffscreen = true; } VisEquipment component = ((Component)player).GetComponent<VisEquipment>(); string[] handItemFields = HandItemFields; foreach (string text in handItemFields) { GameObject val3 = (GameObject)(((Object)(object)component != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); string text2 = (((Object)(object)val3 != (Object)null) ? PathFrom(gameObject.transform, val3.transform) : null); Transform val4 = ((text2 != null) ? val.transform.Find(text2) : null); if ((Object)(object)val4 != (Object)null) { ((Component)val4).gameObject.SetActive(false); } } Strip<MonoBehaviour>(val); Strip<Joint>(val); Strip<Cloth>(val); Strip<Collider>(val); Strip<Rigidbody>(val); Strip<AudioSource>(val); Strip<Light>(val); Transform[] componentsInChildren3 = val.GetComponentsInChildren<Transform>(true); for (int j = 0; j < componentsInChildren3.Length; j++) { ((Component)componentsInChildren3[j]).gameObject.layer = layer; } animator = val.GetComponent<Animator>(); animator.cullingMode = (AnimatorCullingMode)0; animator.applyRootMotion = false; animator.updateMode = (AnimatorUpdateMode)2; animator.fireEvents = false; holder.SetActive(true); animator.SetBool("wakeup", false); for (int k = 0; k < animator.layerCount && k < source.layerCount; k++) { AnimatorStateInfo currentAnimatorStateInfo = source.GetCurrentAnimatorStateInfo(k); animator.Play(((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash, k, ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime); } animator.Update(0f); } private static void Strip<T>(GameObject root) where T : Component { for (int i = 0; i < 3; i++) { T[] componentsInChildren = root.GetComponentsInChildren<T>(true); if (componentsInChildren.Length == 0) { break; } T[] array = componentsInChildren; for (int j = 0; j < array.Length; j++) { Object.DestroyImmediate((Object)(object)array[j]); } } } private static string PathFrom(Transform root, Transform child) { List<string> list = new List<string>(); Transform val = child; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { list.Add(((Object)val).name); val = val.parent; } if (!child.IsChildOf(root)) { return null; } list.Reverse(); return string.Join("/", list); } } public class EmoteWheel : MonoBehaviour { public enum Tab { Favorites, All, Vanilla, Tme } private class Control { public RectTransform Rect; public TextMeshProUGUI Text; public Action OnClick; } private const float InnerRatio = 0.5f; private const float TapTime = 0.25f; private const float StickDeadZone = 0.5f; private static readonly (Tab tab, string key)[] Tabs = new(Tab, string)[4] { (Tab.Favorites, "favorites"), (Tab.All, "all"), (Tab.Vanilla, "vanilla"), (Tab.Tme, "category") }; private static readonly Color Orange = new Color(1f, 0.64f, 0.25f); private static readonly Color LabelColor = new Color(0.9f, 0.87f, 0.8f); private static readonly Color FavoriteColor = new Color(1f, 0.8f, 0.35f); private static readonly Color DimColor = new Color(0.62f, 0.6f, 0.56f); internal static ConfigEntry<KeyboardShortcut> OpenKey; internal static ConfigEntry<KeyboardShortcut> FavoriteKey; internal static ConfigEntry<KeyboardShortcut> BrowserKey; internal static ConfigEntry<int> SlotsPerPage; internal static ConfigEntry<bool> ShowPreview; private static EmoteWheel instance; private static Tab lastTab = Tab.Tme; private static int closedFrame = -10; private static int chooserFrame = -1; private bool open; private bool sticky; private bool clickArmed; private bool padArmed; private float openedAt; private int openedFrame; private int slots; private float radius; internal static bool IgnorePointer; private static readonly MethodInfo StopEmoteMethod = AccessTools.Method(typeof(Player), "StopEmote", (Type[])null, (Type[])null); private readonly List<Control> controls = new List<Control>(); private Control hoveredControl; private RectTransform root; private Image highlight; private Image previewDisk; private RawImage previewImage; private readonly List<TextMeshProUGUI> labels = new List<TextMeshProUGUI>(); private readonly List<Image> icons = new List<Image>(); private readonly List<(Tab tab, Control control)> tabControls = new List<(Tab, Control)>(); private Control previousPage; private Control nextPage; private TextMeshProUGUI pageText; private TextMeshProUGUI nameText; private TextMeshProUGUI detailText; private TextMeshProUGUI hintText; private static Sprite ringSprite; private static Sprite diskSprite; private static Sprite edgeSprite; public static bool IsOpen { get { if ((Object)(object)instance != (Object)null) { return instance.open; } return false; } } internal static bool BlocksGame { get { if (!IsOpen) { return Time.frameCount <= closedFrame; } return true; } } internal static EmoteWheel Instance => instance; public Tab CurrentTab { get; private set; } = Tab.Tme; public int Page { get; private set; } public int Hovered { get; private set; } = -1; public List<MenuItem> Items { get; private set; } = new List<MenuItem>(); public int PageCount => Math.Max(1, (Items.Count + slots - 1) / slots); public int Slots => slots; public MenuItem HoveredItem { get { if (Hovered < 0 || Page * slots + Hovered >= Items.Count) { return null; } return Items[Page * slots + Hovered]; } } private Camera EventCamera { get { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Canvas componentInParent = ((Component)this).GetComponentInParent<Canvas>(); if (!((Object)(object)componentInParent == (Object)null) && (int)componentInParent.renderMode != 0) { return componentInParent.worldCamera; } return null; } } private float BandWidth => radius * 0.5f; private float MidRadius => radius * 1.5f / 2f; public static void Bind(ConfigFile config) { //IL_0012: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown OpenKey = config.Bind<KeyboardShortcut>("Wheel", "Open key", new KeyboardShortcut((KeyCode)96, Array.Empty<KeyCode>()), "Opens the Too Many Emotes wheel directly. Hold, aim, release to play; or tap, then click. The wheel is also in the game's emote wheel (Too Many Emotes)."); FavoriteKey = config.Bind<KeyboardShortcut>("Wheel", "Favorite key", new KeyboardShortcut((KeyCode)102, Array.Empty<KeyCode>()), "Adds the emote under the cursor to the favorites, or removes it (gamepad: d-pad down)."); BrowserKey = config.Bind<KeyboardShortcut>("Wheel", "Browser key", new KeyboardShortcut((KeyCode)98, Array.Empty<KeyCode>()), "Opens the emote browser (search field) from the wheel."); SlotsPerPage = config.Bind<int>("Wheel", "Emotes per page", 12, new ConfigDescription("Emotes shown around the wheel at once.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(6, 16), Array.Empty<object>())); ShowPreview = config.Bind<bool>("Wheel", "Preview", true, "Shows the emote under the cursor, played by a copy of your character, in the centre of the wheel."); } public static void Open(bool sticky) { //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) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)GUIManager.CustomGUIFront == (Object)null) { return; } if (!EmoteLibrary.Ready) { ((Character)localPlayer).Message((MessageType)2, Translations.Ui("loading"), 0, (Sprite)null, false); return; } if ((Object)(object)instance == (Object)null) { GameObject val = new GameObject("TooManyEmotes_Wheel", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(GUIManager.CustomGUIFront.transform, false); instance = val.AddComponent<EmoteWheel>(); } instance.DoOpen(sticky); } public static void Close() { instance?.DoClose(); } private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)((Component)this).transform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); val.pivot = val2; Vector2 anchorMin = (val.anchorMax = val2); val.anchorMin = anchorMin; val.anchoredPosition = Vector2.zero; ((Component)this).gameObject.SetActive(false); } private void DoOpen(bool sticky) { //IL_00eb: 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) if (!open) { slots = Mathf.Clamp(SlotsPerPage.Value, 6, 16); ((Component)this).gameObject.SetActive(true); Build(); open = true; this.sticky = sticky; clickArmed = (padArmed = false); openedAt = Time.unscaledTime; openedFrame = Time.frameCount; Hovered = -1; ((Component)this).transform.SetAsLastSibling(); bool active = ShowPreview.Value && EmotePreview.Begin(Player.m_localPlayer); ((Component)previewDisk).gameObject.SetActive(active); previewImage.texture = EmotePreview.Texture; Tab tab = ((lastTab == Tab.Favorites && Favorites.Keys.Count == 0) ? Tab.Tme : lastTab); SetTab(tab, keepPage: true); if (!ZInput.IsGamepadActive()) { ZInput.SetMousePosition(RectTransformUtility.WorldToScreenPoint(EventCamera, ((Component)this).transform.position)); } GameCamera obj = GameCamera.instance; if (obj != null) { obj.UpdateMouseCapture(); } } } private void DoClose() { if (open) { open = false; closedFrame = Time.frameCount; ((Component)this).gameObject.SetActive(false); EmotePreview.End(); GameCamera obj = GameCamera.instance; if (obj != null) { obj.UpdateMouseCapture(); } } } private void OnDisable() { if (open) { open = false; EmotePreview.End(); } } private static void OpenChooser() { Hud val = Hud.instance; if (!((Object)(object)val == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null)) { RadialBase radialMenu = val.m_radialMenu; radialMenu.CanOpen = true; radialMenu.Open((IRadialConfig)(object)val.m_config, (IRadialConfig)null); if (radialMenu.Active) { radialMenu.HoverObject = null; radialMenu.Open((IRadialConfig)(object)RadialData.SO.EmoteGroupConfig, (IRadialConfig)null); } } } internal static void StaticUpdate() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (chooserFrame >= 0 && Time.frameCount > chooserFrame) { chooserFrame = -1; OpenChooser(); } if (!IsOpen && !Hud.InRadial() && KeyDown(OpenKey.Value) && CanOpen()) { Open(sticky: false); } } private static bool CanOpen() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead() && !((Character)localPlayer).InPlaceMode() && !Console.IsVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible() && !Minimap.IsOpen() && !TextInput.IsVisible() && !StoreGui.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Hud.IsPieceSelectionVisible()) { return !EmoteBrowser.IsOpen; } return false; } private static bool KeyDown(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && ZInput.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey, false)) { return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode k) => ZInput.GetKey(k, false)); } return false; } private static bool KeyHeld(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && ZInput.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey, false)) { return ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode k) => ZInput.GetKey(k, false)); } return false; } private void Update() { //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) if (!open) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || localPlayer.IsSleeping() || Menu.IsVisible() || Console.IsVisible() || InventoryGui.IsVisible() || Minimap.IsOpen() || ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())) { DoClose(); return; } EmotePreview.Update(); bool flag = Time.frameCount == openedFrame; if (ZInput.GetKeyDown((KeyCode)27, false) || ZInput.GetButtonDown("JoyRadialClose") || ZInput.GetButtonDown("JoyMenu") || ZInput.GetButtonDown("Chat") || ZInput.GetButtonDown("JoyChat") || ZInput.GetButtonDown("Map") || ZInput.GetButtonDown("JoyMap") || ZInput.GetButtonDown("Console") || (!flag && (ZInput.GetButtonDown("OpenEmote") || ZInput.GetButtonDown("OpenRadial") || ZInput.GetButtonDown("JoyRadial") || (sticky && KeyDown(OpenKey.Value))))) { DoClose(); return; } if (ZInput.GetMouseButtonUp(1) || ZInput.GetButtonUp("JoyRadialBack")) { DoClose(); chooserFrame = Time.frameCount; return; } if (KeyDown(BrowserKey.Value)) { DoClose(); EmoteBrowser.Open(); return; } UpdateAim(); int num = 0; float mouseScrollWheel = ZInput.GetMouseScrollWheel(); if (mouseScrollWheel < 0f) { num++; } else if (mouseScrollWheel > 0f) { num--; } if (ZInput.GetButtonDown("JoyDPadRight")) { num++; } if (ZInput.GetButtonDown("JoyDPadLeft")) { num--; } if (num != 0) { SetPage(Page + num); } if (ZInput.GetKeyDown((KeyCode)9, false) || ZInput.GetButtonDown("JoyDPadUp")) { NextTab((!ZInput.GetKey((KeyCode)304, false)) ? 1 : (-1)); } if (KeyDown(FavoriteKey.Value) || ZInput.GetButtonDown("JoyDPadDown") || ZInput.GetButtonDown("JoyRadialSecondaryInteract")) { ToggleFavorite(); } if (ZInput.GetMouseButtonDown(0)) { clickArmed = true; } if (ZInput.GetButtonDown("JoyRadialInteract")) { padArmed = true; } if (clickArmed && ZInput.GetMouseButtonUp(0)) { clickArmed = false; if (!ClickControls()) { Confirm(); } } else if (padArmed && ZInput.GetButtonUp("JoyRadialInteract")) { Confirm(); } else if (!sticky && !KeyHeld(OpenKey.Value)) { if (Time.unscaledTime - openedAt < 0.25f && HoveredItem == null) { sticky = true; } else { Confirm(); } } } private void LateUpdate() { if (open) { EmotePreview.LateUpdate(); } } private void UpdateAim() { Control control = hoveredControl; AimAt(); if (hoveredControl != control) { Refresh(); } } private void AimAt() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) hoveredControl = null; if (IgnorePointer) { return; } if (ZInput.IsExclusiveGamepadActive()) { Vector2 value = ZInput.GetValue<Vector2>("RadialStick"); if (((Vector2)(ref value)).magnitude >= 0.5f) { SetAim(((Vector2)(ref value)).normalized); } return; } Vector2 pointer = Vector2.op_Implicit(ZInput.pointerPosition); hoveredControl = controls.FirstOrDefault((Control c) => ((Component)c.Rect).gameObject.activeInHierarchy && RectTransformUtility.RectangleContainsScreenPoint(c.Rect, pointer, EventCamera)); Vector2 val = default(Vector2); if (hoveredControl != null) { SetHovered(-1); } else if (RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)((Component)this).transform, pointer, EventCamera, ref val)) { SetAim(val / radius); } } public void SetAim(Vector2 aim) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) int hovered = ((((Vector2)(ref aim)).magnitude < 0.425f) ? (-1) : SlotAt(aim)); SetHovered(hovered); } public void SetHovered(int slot) { if (slot >= 0 && Page * slots + slot >= Items.Count) { slot = -1; } if (slot != Hovered) { Hovered = slot; EmotePreview.Show(HoveredItem); Refresh(); } } private int SlotAt(Vector2 aim) { //IL_0000: 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) float num = Mathf.Atan2(aim.x, aim.y) * 57.29578f; float num2 = 360f / (float)slots; return Mathf.FloorToInt(Mathf.Repeat(num + num2 / 2f, 360f) / num2) % slots; } private static float SlotAngle(int slot, int count) { return (float)slot * 360f / (float)count; } public void Confirm() { MenuItem hoveredItem = HoveredItem; DoClose(); if (hoveredItem != null) { hoveredItem.Play(); return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null && ((Character)localPlayer).InEmote()) { StopEmoteMethod.Invoke(localPlayer, null); } } public void ToggleFavorite() { MenuItem hoveredItem = HoveredItem; if (hoveredItem != null) { bool flag = Favorites.Toggle(hoveredItem.Key); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, Translations.Ui(flag ? "fav_added" : "fav_removed", hoveredItem.Label), 0, (Sprite)null, false); } if (CurrentTab == Tab.Favorites) { SetTab(Tab.Favorites, keepPage: true); } Refresh(); } } public void SetTab(Tab tab, bool keepPage = false) { int page = ((keepPage && tab == CurrentTab) ? Page : 0); CurrentTab = tab; lastTab = tab; Items = ItemsOf(tab); SetPage(page); } public void NextTab(int direction) { int num = Array.FindIndex(Tabs, ((Tab tab, string key) t) => t.tab == CurrentTab); SetTab(Tabs[(int)Mathf.Repeat((float)(num + direction), (float)Tabs.Length)].tab); } public void SetPage(int page) { int pageCount = PageCount; Page = (page % pageCount + pageCount) % pageCount; if (HoveredItem == null) { Hovered = -1; } EmotePreview.Show(HoveredItem); Refresh(); } private static List<MenuItem> ItemsOf(Tab tab) { return tab switch { Tab.Favorites => MenuCatalog.FavoriteItems, Tab.All => MenuCatalog.All, Tab.Vanilla => MenuCatalog.Vanilla, _ => MenuCatalog.TmeWithParts, }; } private bool ClickControls() { if (hoveredControl == null) { return false; } hoveredControl.OnClick(); return true; } private void Refresh() { //IL_01c4: 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_021b: 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_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_031e: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) if (labels.Count != slots) { return; } for (int i = 0; i < slots; i++) { int num = Page * slots + i; MenuItem menuItem = ((num < Items.Count) ? Items[num] : null); Sprite val = menuItem?.Icon; ((Component)icons[i]).gameObject.SetActive((Object)(object)val != (Object)null); icons[i].sprite = val; ((TMP_Text)labels[i]).text = menuItem?.Label ?? ""; ((TMP_Text)labels[i]).rectTransform.anchoredPosition = SlotCentre(i) - (Vector2)(((Object)(object)val != (Object)null) ? new Vector2(0f, BandWidth * 0.17f) : Vector2.zero); bool flag = menuItem != null && Favorites.Contains(menuItem.Key); ((Graphic)labels[i]).color = ((i == Hovered) ? Color.white : (flag ? FavoriteColor : LabelColor)); ((TMP_Text)labels[i]).fontStyle = (FontStyles)((i == Hovered) ? 1 : 0); } ((Behaviour)highlight).enabled = Hovered >= 0; if (Hovered >= 0) { ((Transform)((Graphic)highlight).rectTransform).localRotation = Quaternion.Euler(0f, 0f, 180f / (float)slots - SlotAngle(Hovered, slots)); } foreach (var tabControl in tabControls) { Tab item = tabControl.tab; Control item2 = tabControl.control; bool flag2 = item == CurrentTab; ((Graphic)item2.Text).color = (flag2 ? Orange : ((item2 == hoveredControl) ? Color.white : DimColor)); ((TMP_Text)item2.Text).fontStyle = (FontStyles)(flag2 ? 1 : 0); } LayoutTabs(); ((TMP_Text)pageText).text = Translations.Ui("page", Page + 1, PageCount); ((Component)previousPage.Rect).gameObject.SetActive(PageCount > 1); ((Component)nextPage.Rect).gameObject.SetActive(PageCount > 1); ((Graphic)previousPage.Text).color = ((previousPage == hoveredControl) ? Color.white : DimColor); ((Graphic)nextPage.Text).color = ((nextPage == hoveredControl) ? Color.white : DimColor); MenuItem hoveredItem = HoveredItem; Player localPlayer = Player.m_localPlayer; if (hoveredItem != null) { ((TMP_Text)nameText).text = hoveredItem.Label; ((TMP_Text)detailText).text = (Favorites.Contains(hoveredItem.Key) ? Translations.Ui("favorite") : ""); } else { ((TMP_Text)nameText).text = (((Object)(object)localPlayer != (Object)null && ((Character)localPlayer).InEmote()) ? Translations.Ui("stop") : ((Items.Count != 0) ? "" : ((CurrentTab == Tab.Favorites) ? Translations.Ui("no_favorites_short") : Translations.Ui("nothing")))); ((TMP_Text)detailText).text = ""; } ((TMP_Text)hintText).text = (ZInput.IsGamepadActive() ? Translations.Ui("hint_pad") : Translations.Ui("hint_mouse", ((object)FavoriteKey.Value/*cast due to .constrained prefix*/).ToString(), ((object)BrowserKey.Value/*cast due to .constrained prefix*/).ToString())); } private Vector2 SlotCentre(int slot) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) float num = SlotAngle(slot, slots) * ((float)Math.PI / 180f); return new Vector2(Mathf.Sin(num), Mathf.Cos(num)) * MidRadius; } private void LayoutTabs() { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) float num = (0f - (tabControls.Sum(((Tab tab, Control control) t) => ((TMP_Text)t.control.Text).preferredWidth) + 34f * (float)(tabControls.Count - 1))) / 2f; foreach (var tabControl in tabControls) { Control item = tabControl.control; float preferredWidth = ((TMP_Text)item.Text).preferredWidth; item.Rect.sizeDelta = new Vector2(preferredWidth + 12f, 34f); item.Rect.anchoredPosition = new Vector2(num + preferredWidth / 2f, radius + 34f); num += preferredWidth + 34f; } } private void Build() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Unknown result type (might be due to invalid IL or missing references) //IL_04b4: Expected O, but got Unknown //IL_0500: Unknown result type (might be due to invalid IL or missing references) //IL_0525: Unknown result type (might be due to invalid IL or missing references) //IL_0561: Unknown result type (might be due to invalid IL or missing references) //IL_057e: Unknown result type (might be due to invalid IL or missing references) //IL_05be: Unknown result type (might be due to invalid IL or missing references) //IL_05e1: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Unknown result type (might be due to invalid IL or missing references) //IL_063d: Unknown result type (might be due to invalid IL or missing references) //IL_0660: Unknown result type (might be due to invalid IL or missing references) //IL_0670: Unknown result type (might be due to invalid IL or missing references) //IL_077c: Unknown result type (might be due to invalid IL or missing references) //IL_07a3: Unknown result type (might be due to invalid IL or missing references) //IL_07b3: Unknown result type (might be due to invalid IL or missing references) //IL_07f9: Unknown result type (might be due to invalid IL or missing references) //IL_0820: Unknown result type (might be due to invalid IL or missing references) //IL_0866: Unknown result type (might be due to invalid IL or missing references) //IL_088d: Unknown result type (might be due to invalid IL or missing references) //IL_08ce: Unknown result type (might be due to invalid IL or missing references) //IL_08f5: Unknown result type (might be due to invalid IL or missing references) //IL_0905: Unknown result type (might be due to invalid IL or missing references) root = (RectTransform)((Component)this).transform; RectTransform val = (RectTransform)((Transform)root).parent; Rect rect = val.rect; float width = ((Rect)(ref rect)).width; rect = val.rect; float num = Mathf.Min(width, ((Rect)(ref rect)).height); float num2 = Mathf.Max(180f, num * 0.34f); if (labels.Count == slots && Mathf.Approximately(num2, radius)) { return; } radius = num2; foreach (Transform item2 in (Transform)root) { Object.Destroy((Object)(object)((Component)item2).gameObject); } labels.Clear(); icons.Clear(); controls.Clear(); tabControls.Clear(); EnsureSprites(); root.sizeDelta = new Vector2(radius * 2f, radius * 2f); NewImage("Shade", diskSprite, new Color(0f, 0f, 0f, 0.4f), radius * 2.06f); NewImage("Band", ringSprite, new Color(0.09f, 0.08f, 0.07f, 0.82f), radius * 2f); NewImage("Edge", edgeSprite, new Color(Orange.r, Orange.g, Orange.b, 0.35f), radius * 2f); highlight = NewImage("Highlight", ringSprite, new Color(Orange.r, Orange.g, Orange.b, 0.45f), radius * 2f); highlight.type = (Type)3; highlight.fillMethod = (FillMethod)4; highlight.fillOrigin = 2; highlight.fillClockwise = true; highlight.fillAmount = 1f / (float)slots; float bandWidth = BandWidth; float midRadius = MidRadius; float num3 = 2f * midRadius * Mathf.Sin((float)Math.PI / (float)slots); for (int i = 0; i < slots; i++) { float num4 = (SlotAngle(i, slots) + 180f / (float)slots) * ((float)Math.PI / 180f); Image obj = NewImage("Separator" + i, null, new Color(1f, 0.85f, 0.6f, 0.14f), 0f); ((Graphic)obj).rectTransform.sizeDelta = new Vector2(2f, bandWidth * 0.92f); ((Graphic)obj).rectTransform.anchoredPosition = new Vector2(Mathf.Sin(num4), Mathf.Cos(num4)) * midRadius; ((Transform)((Graphic)obj).rectTransform).localRotation = Quaternion.Euler(0f, 0f, (0f - num4) * 57.29578f); Image val2 = NewImage("Icon" + i, null, Color.white, bandWidth * 0.34f); val2.preserveAspect = true; ((Graphic)val2).rectTransform.anchoredPosition = SlotCentre(i) + new Vector2(0f, bandWidth * 0.17f); icons.Add(val2); TextMeshProUGUI val3 = NewText("Label" + i, 24f, 13f); ((TMP_Text)val3).rectTransform.sizeDelta = new Vector2(Mathf.Min(bandWidth * 1.02f, num3 * 0.9f), bandWidth * 0.56f); ((TMP_Text)val3).rectTransform.anchoredPosition = SlotCentre(i); labels.Add(val3); } float num5 = radius * 0.5f; previewDisk = NewImage("Preview", diskSprite, new Color(0.075f, 0.065f, 0.055f, 1f), num5 * 1.9f); ((Component)previewDisk).gameObject.AddComponent<Mask>().showMaskGraphic = true; GameObject val4 = new GameObject("Texture", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent(((Component)previewDisk).transform, false); previewImage = val4.AddComponent<RawImage>(); ((Graphic)previewImage).raycastTarget = false; ((Graphic)previewImage).rectTransform.sizeDelta = new Vector2(num5 * 1.9f, num5 * 1.9f); Image obj2 = NewImage("NameBack", null, new Color(0f, 0f, 0f, 0.5f), 0f); ((Transform)((Graphic)obj2).rectTransform).SetParent(((Component)previewDisk).transform, false); ((Graphic)obj2).rectTransform.sizeDelta = new Vector2(num5 * 1.9f, num5 * 0.44f); ((Graphic)obj2).rectTransform.anchoredPosition = new Vector2(0f, (0f - num5) * 0.66f); nameText = NewText("Name", 26f, 14f); ((TMP_Text)nameText).rectTransform.sizeDelta = new Vector2(num5 * 1.45f, num5 * 0.3f); ((TMP_Text)nameText).rectTransform.anchoredPosition = new Vector2(0f, (0f - num5) * 0.6f); ((TMP_Text)nameText).fontStyle = (FontStyles)1; ((Graphic)nameText).color = Color.white; detailText = NewText("Detail", 15f, 11f); ((TMP_Text)detailText).rectTransform.sizeDelta = new Vector2(num5 * 1.2f, num5 * 0.14f); ((TMP_Text)detailText).rectTransform.anchoredPosition = new Vector2(0f, (0f - num5) * 0.8f); ((Graphic)detailText).color = FavoriteColor; (Tab, string)[] tabs = Tabs; for (int j = 0; j < tabs.Length; j++) { (Tab, string) tuple = tabs[j]; Tab tab = tuple.Item1; string item = tuple.Item2; Control control = NewControl("Tab_" + tab, Translations.Ui(item), 22f, delegate { SetTab(tab); }); ((TMP_Text)control.Text).enableAutoSizing = false; ((TMP_Text)control.Text).fontSize = 22f; ((TMP_Text)control.Text).textWrappingMode = (TextWrappingModes)0; tabControls.Add((tab, control)); } pageText = NewText("Page", 18f, 12f); ((TMP_Text)pageText).rectTransform.sizeDelta = new Vector2(220f, 30f); ((TMP_Text)pageText).rectTransform.anchoredPosition = new Vector2(0f, 0f - radius - 26f); ((Graphic)pageText).color = DimColor; previousPage = NewControl("PreviousPage", "<", 28f, delegate { SetPage(Page - 1); }); previousPage.Rect.sizeDelta = new Vector2(44f, 36f); previousPage.Rect.anchoredPosition = new Vector2(-130f, 0f - radius - 26f); nextPage = NewControl("NextPage", ">", 28f, delegate { SetPage(Page + 1); }); nextPage.Rect.sizeDelta = new Vector2(44f, 36f); nextPage.Rect.anchoredPosition = new Vector2(130f, 0f - radius - 26f); hintText = NewText("Hint", 15f, 10f); ((TMP_Text)hintText).rectTransform.sizeDelta = new Vector2(radius * 2.6f, 26f); ((TMP_Text)hintText).rectTransform.anchoredPosition = new Vector2(0f, 0f - radius - 58f); ((Graphic)hintText).color = DimColor; } private Control NewControl(string name, string text, float fontSize, Action onClick) { TextMeshProUGUI val = NewText(name, fontSize, fontSize * 0.6f); ((TMP_Text)val).text = text; Control control = new Control { Rect = ((TMP_Text)val).rectTransform, Text = val, OnClick = onClick }; controls.Add(control); return control; } private Image NewImage(string name, Sprite sprite, Color color, float size) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_004f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)root, false); Image obj = val.AddComponent<Image>(); obj.sprite = sprite; ((Graphic)obj).color = color; ((Graphic)obj).raycastTarget = false; ((Graphic)obj).rectTransform.sizeDelta = new Vector2(size, size); return obj; } private TextMeshProUGUI NewText(string name, float maxSize, float minSize) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.SetActive(false); val.transform.SetParent((Transform)(object)root, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val2).font = TmeRadial.Font; val.SetActive(true); ((TMP_Text)val2).alignment = (TextAlignmentOptions)514; ((TMP_Text)val2).enableAutoSizing = true; ((TMP_Text)val2).fontSizeMin = minSize; ((TMP_Text)val2).fontSizeMax = maxSize; ((TMP_Text)val2).textWrappingMode = (TextWrappingModes)1;