using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetterEmote.AssetScripts;
using BetterEmote.Compatibility;
using BetterEmote.Netcode;
using BetterEmote.Patches;
using BetterEmote.Utils;
using GameNetcodeStuff;
using HarmonyLib;
using LCVR;
using LethalCompanyInputUtils.Api;
using Microsoft.CodeAnalysis;
using RuntimeNetcodeRPCValidator;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Animations.Rigging;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("BetterEmotes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Alters the integration method of more emotes")]
[assembly: AssemblyFileVersion("1.5.4.0")]
[assembly: AssemblyInformationalVersion("1.5.4+561235a28e56ee423d85929cbcfdf7e683579870")]
[assembly: AssemblyProduct("BetterEmotes")]
[assembly: AssemblyTitle("BetterEmotes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.5.4.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 BetterEmote
{
[BepInPlugin("BetterEmotes", "BetterEmotes", "1.5.4")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
private static readonly string AssetPath = "Assets/MoreEmotes";
public static ManualLogSource Logger;
public static Dictionary<string, long> lastLog = new Dictionary<string, long>();
private void Awake()
{
//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_0045: Expected O, but got Unknown
//IL_0045: 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_0065: 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_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0094: 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)
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"BetterEmotes loading...");
loadAssetBundles();
Settings.LoadFromConfig(((BaseUnityPlugin)this).Config);
Settings.Keybinds = new Keybinds();
Harmony val = new Harmony("BetterEmotes");
Patcher.patchCompat(val);
val.PatchAll(typeof(EmotePatch));
val.PatchAll(typeof(SignChatPatch));
val.PatchAll(typeof(RoundPatch));
val.PatchAll(typeof(EmoteKeybindPatch));
NetcodeValidator val2 = new NetcodeValidator("BetterEmotes");
val2.PatchAll();
val2.BindToPreExistingObjectByBehaviour<SyncVRState, PlayerControllerB>();
val2.BindToPreExistingObjectByBehaviour<SignEmoteText, PlayerControllerB>();
val2.BindToPreExistingObjectByBehaviour<SyncAnimatorToOthers, PlayerControllerB>();
Logger.LogInfo((object)"BetterEmotes loaded");
}
private void loadAssetBundles()
{
string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "BetterEmotes");
string text = Path.Combine(path, "animatorbundle");
string text2 = Path.Combine(path, "animationsbundle");
try
{
loadAnimatorControllers(AssetBundle.LoadFromFile(text));
loadAnimationObjects(AssetBundle.LoadFromFile(text2));
}
catch (Exception ex)
{
Logger.LogError((object)("Failed to load AssetBundles. Make sure \"animatorsbundle\" and \"animationsbundle\" are inside the MoreEmotes folder.\nError: " + ex.Message));
}
}
private void loadAnimatorControllers(AssetBundle bundle)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Expected O, but got Unknown
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Expected O, but got Unknown
EmotePatch.local = (RuntimeAnimatorController)new AnimatorOverrideController(bundle.LoadAsset<RuntimeAnimatorController>(Path.Combine(AssetPath, "NEWmetarig.controller")));
EmotePatch.others = (RuntimeAnimatorController)new AnimatorOverrideController(bundle.LoadAsset<RuntimeAnimatorController>(Path.Combine(AssetPath, "NEWmetarigOtherPlayers.controller")));
}
private void loadAnimationObjects(AssetBundle bundle)
{
CustomAudioAnimationEvent.claps[0] = bundle.LoadAsset<AudioClip>(Path.Combine(AssetPath, "SingleClapEmote1.wav"));
CustomAudioAnimationEvent.claps[1] = bundle.LoadAsset<AudioClip>(Path.Combine(AssetPath, "SingleClapEmote2.wav"));
LocalPlayer.LegsPrefab = bundle.LoadAsset<GameObject>(Path.Combine(AssetPath, "Resources/plegs.prefab"));
LocalPlayer.SignPrefab = bundle.LoadAsset<GameObject>(Path.Combine(AssetPath, "Resources/Sign.prefab"));
LocalPlayer.SignUIPrefab = bundle.LoadAsset<GameObject>(Path.Combine(AssetPath, "Resources/SignTextUI.prefab"));
EmoteKeybindPatch.WheelPrefab = bundle.LoadAsset<GameObject>(Path.Combine(AssetPath, "Resources/MoreEmotesMenu.prefab"));
}
public static void Debug(string message)
{
if (Settings.Debug)
{
Logger.LogDebug((object)("[DEBUG] " + message));
}
}
public static void Trace(string message)
{
if (!Settings.Trace)
{
return;
}
long num = DateTimeOffset.Now.ToUnixTimeMilliseconds();
if (lastLog.ContainsKey(message))
{
long num2 = lastLog[message];
if ((float)(num - num2) > Settings.LogDelay * 1000f)
{
Logger.LogDebug((object)("[TRACE] " + message));
lastLog[message] = num;
}
}
else
{
Logger.LogDebug((object)("[TRACE] " + message));
lastLog.Add(message, num);
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "BetterEmotes";
public const string PLUGIN_NAME = "BetterEmotes";
public const string PLUGIN_VERSION = "1.5.4";
}
}
namespace BetterEmote.Utils
{
public enum Emote
{
Dance = 1,
Point,
Middle_Finger,
Clap,
Shy,
Griddy,
Twerk,
Salute,
Prisyadka,
Sign
}
public enum DoubleEmote
{
Double_Clap = 1004,
Double_Middle_Finger = 1003
}
public enum AltEmote
{
Sign_Text = 1010
}
internal class EmoteDefs
{
public static int getEmoteNumber(Emote emote)
{
return (int)emote;
}
public static int getEmoteNumber(DoubleEmote emote)
{
return (int)emote;
}
public static int getEmoteNumber(AltEmote emote)
{
return (int)emote;
}
public static int getEmoteNumber(string name)
{
return (int)Enum.Parse(typeof(Emote), name);
}
public static Emote getEmote(string name)
{
try
{
return (Emote)Enum.Parse(typeof(Emote), name);
}
catch (Exception)
{
try
{
return (DoubleEmote)Enum.Parse(typeof(DoubleEmote), name) switch
{
DoubleEmote.Double_Middle_Finger => Emote.Middle_Finger,
DoubleEmote.Double_Clap => Emote.Clap,
_ => Emote.Dance,
};
}
catch (Exception)
{
if ((AltEmote)Enum.Parse(typeof(AltEmote), name) == AltEmote.Sign_Text)
{
return Emote.Sign;
}
return Emote.Dance;
}
}
}
public static DoubleEmote getDoubleEmote(string name)
{
return (DoubleEmote)Enum.Parse(typeof(DoubleEmote), name);
}
public static AltEmote getAltEmote(string name)
{
return (AltEmote)Enum.Parse(typeof(AltEmote), name);
}
public static int getEmoteCount()
{
return Enum.GetNames(typeof(Emote)).Length;
}
public static int normalizeEmoteNumber(int number)
{
if (number >= 1000)
{
number -= 1000;
}
return number;
}
}
internal class GameValues
{
public static PlayerControllerB localPlayerController
{
get
{
StartOfRound instance = StartOfRound.Instance;
if (!((Object)(object)instance != (Object)null))
{
return null;
}
return instance.localPlayerController;
}
}
public static bool localPlayerUsingController
{
get
{
StartOfRound instance = StartOfRound.Instance;
if (!((Object)(object)instance != (Object)null))
{
return false;
}
return instance.localPlayerUsingController;
}
}
}
public class Keybinds : LcInputActions
{
public InputAction MiddleFinger => ((LcInputActions)this).Asset["Middle_Finger"];
public InputAction Clap => ((LcInputActions)this).Asset["Clap"];
public InputAction Shy => ((LcInputActions)this).Asset["Shy"];
public InputAction Griddy => ((LcInputActions)this).Asset["Griddy"];
public InputAction Twerk => ((LcInputActions)this).Asset["Twerk"];
public InputAction Salute => ((LcInputActions)this).Asset["Salute"];
public InputAction Prisyadka => ((LcInputActions)this).Asset["Prisyadka"];
public InputAction Sign => ((LcInputActions)this).Asset["Sign"];
public InputAction SignSubmit => ((LcInputActions)this).Asset["SignSubmit"];
public InputAction SignCancel => ((LcInputActions)this).Asset["SignCancel"];
public InputAction EmoteWheel => ((LcInputActions)this).Asset["EmoteWheel"];
public InputAction EmoteWheelNextPage => ((LcInputActions)this).Asset["EmoteWheelNextPage"];
public InputAction EmoteWheelPreviousPage => ((LcInputActions)this).Asset["EmoteWheelPreviousPage"];
public InputAction EmoteWheelController => ((LcInputActions)this).Asset["EmoteWheelController"];
public override void CreateInputActions(in InputActionMapBuilder builder)
{
((LcInputActions)this).CreateInputActions(ref builder);
if (Settings.DefaultInputList.Length != 0)
{
string[] names = Enum.GetNames(typeof(Emote));
foreach (string text in names)
{
if (EmoteDefs.getEmoteNumber(text) > 2)
{
builder.NewActionBinding().WithActionId(text).WithActionType((InputActionType)1)
.WithKbmPath(Settings.DefaultInputList[EmoteDefs.getEmoteNumber(text)].keyboard)
.WithBindingName(text)
.WithGamepadPath(Settings.DefaultInputList[EmoteDefs.getEmoteNumber(text)].controller)
.Finish();
}
}
}
builder.NewActionBinding().WithActionId("SignSubmit").WithActionType((InputActionType)1)
.WithKbmPath(Settings.SignSubmitInput.keyboard)
.WithGamepadPath(Settings.SignSubmitInput.controller)
.WithBindingName("Sign Submit")
.Finish();
builder.NewActionBinding().WithActionId("SignCancel").WithActionType((InputActionType)1)
.WithKbmPath(Settings.SignCancelInput.keyboard)
.WithGamepadPath(Settings.SignCancelInput.controller)
.WithBindingName("Sign Cancel")
.Finish();
builder.NewActionBinding().WithActionId("EmoteWheel").WithActionType((InputActionType)1)
.WithKbmPath(Settings.EmoteWheelInput.keyboard)
.WithGamepadPath(Settings.EmoteWheelInput.controller)
.WithBindingName("Emote Wheel")
.Finish();
builder.NewActionBinding().WithActionId("EmoteWheelNextPage").WithActionType((InputActionType)1)
.WithKbmPath(Settings.EmoteWheelNextInput.keyboard)
.WithGamepadPath(Settings.EmoteWheelNextInput.controller)
.WithBindingName("Emote Wheel Next Page")
.Finish();
builder.NewActionBinding().WithActionId("EmoteWheelPreviousPage").WithActionType((InputActionType)1)
.WithKbmPath(Settings.EmoteWheelPreviousInput.keyboard)
.WithGamepadPath(Settings.EmoteWheelPreviousInput.controller)
.WithBindingName("Emote Wheel Previous Page")
.Finish();
builder.NewActionBinding().WithActionId("EmoteWheelController").WithActionType((InputActionType)0)
.WithGamepadPath(Settings.EmoteWheelMoveInput.controller)
.WithBindingName("Emote Wheel Selector")
.Finish();
}
public static InputBind getDisplayStrings(InputAction action)
{
Plugin.Debug("getDisplayStrings()");
return new InputBind(InputActionRebindingExtensions.GetBindingDisplayString(action, 0, (DisplayStringOptions)0) ?? "", (InputActionRebindingExtensions.GetBindingDisplayString(action, 1, (DisplayStringOptions)0) ?? "").Replace("Left Stick", "LS").Replace("Right Stick", "RS"));
}
public static string formatInputBind(InputBind bind)
{
Plugin.Trace("formatInputBind()");
if ((bind.keyboard == null || bind.keyboard == "") && (bind.controller == null || bind.controller == ""))
{
return "";
}
if (bind.keyboard == null || bind.keyboard == "")
{
return "[" + bind.controller + "]";
}
if (bind.controller == null || bind.controller == "")
{
return "[" + bind.keyboard + "]";
}
return "[" + bind.keyboard + "/" + bind.controller + "]";
}
public InputAction getByEmote(Emote emote)
{
PlayerInput component = GameObject.Find("PlayerSettingsObject").GetComponent<PlayerInput>();
return (InputAction)(emote switch
{
Emote.Middle_Finger => MiddleFinger,
Emote.Clap => Clap,
Emote.Shy => Shy,
Emote.Griddy => Griddy,
Emote.Twerk => Twerk,
Emote.Salute => Salute,
Emote.Prisyadka => Prisyadka,
Emote.Sign => Sign,
Emote.Dance => component.currentActionMap.FindAction("Emote1", false),
Emote.Point => component.currentActionMap.FindAction("Emote2", false),
_ => throw new Exception("Attempted to get input of unknown emote"),
});
}
}
public class Settings
{
private static readonly string KeyLabel = "Emote Keys";
private static readonly string EnabledLabel = "Enabled Emotes";
private static readonly string ControllerLabel = "Emote Controller Bindings";
private static readonly string EmoteSettingsLabel = "Emote Settings";
private static readonly string DebugSettingsLabel = "Debug Settings";
public static bool Debug = false;
public static bool Trace = false;
public static Keybinds Keybinds;
public static bool StopOnOuter = false;
public static bool[] EnabledList = Array.Empty<bool>();
public static InputBind[] DefaultInputList = Array.Empty<InputBind>();
public static InputBind EmoteWheelInput = new InputBind("<Keyboard>/v", "<Gamepad>/leftShoulder");
public static InputBind EmoteWheelNextInput = new InputBind("<Mouse>/scroll/up", "<Gamepad>/dpad/right");
public static InputBind EmoteWheelPreviousInput = new InputBind("<Mouse>/scroll/down", "<Gamepad>/dpad/left");
public static InputBind EmoteWheelMoveInput = new InputBind("", "<Gamepad>/rightStick");
public static InputBind SignSubmitInput = new InputBind("<Keyboard>/enter", "<Gamepad>/buttonWest");
public static InputBind SignCancelInput = new InputBind("<Mouse>/rightButton", "<Gamepad>/buttonEast");
public static float GriddySpeed = 0.5f;
public static float PrisyadkaSpeed = 0.34f;
public static float EmoteCooldown = 0.2f;
public static float SignTextCooldown = 0.1f;
public static bool DisableSpeedChange = false;
public static bool DisableModelOverride = false;
public static float ControllerDeadzone = 0.25f;
public static float LogDelay = 1f;
public static void DebugAllSettings()
{
Plugin.Debug($"Debug: {Debug}");
Plugin.Debug($"Trace: {Trace}");
Plugin.Debug($"StopOnOuter: {StopOnOuter}");
Plugin.Debug("EnabledList: " + string.Join(", ", EnabledList));
Plugin.Debug("DefaultInputList: " + string.Join(", ", DefaultInputList));
Plugin.Debug($"EmoteWheelInput: {EmoteWheelInput}");
Plugin.Debug($"EmoteWheelNextInput: {EmoteWheelNextInput}");
Plugin.Debug($"EmoteWheelPreviousInput: {EmoteWheelPreviousInput}");
Plugin.Debug($"EmoteWheelMoveInput: {EmoteWheelMoveInput}");
Plugin.Debug($"SignSubmitInput: {SignSubmitInput}");
Plugin.Debug($"SignCancelInput: {SignCancelInput}");
Plugin.Debug($"GriddySpeed: {GriddySpeed}");
Plugin.Debug($"PrisyadkaSpeed: {PrisyadkaSpeed}");
Plugin.Debug($"EmoteCooldown: {EmoteCooldown}");
Plugin.Debug($"SignTextCooldown: {SignTextCooldown}");
Plugin.Debug($"DisableSpeedChange: {DisableSpeedChange}");
Plugin.Debug($"DisableModelOverride: {DisableModelOverride}");
Plugin.Debug($"ControllerDeadzone: {ControllerDeadzone}");
Plugin.Debug($"LogDelay: {LogDelay}");
}
public static float ValidateGreaterThanEqualToZero(float value)
{
if (!(value < 0f))
{
return value;
}
return 0f;
}
public static string ValidatePrefix(string prefix, string value)
{
return ValidatePrefixes(new string[1] { prefix }, prefix, value);
}
public static string ValidatePrefixes(string[] prefixes, string defaultPrefix, string value)
{
if (value.Equals(""))
{
return "";
}
foreach (string text in prefixes)
{
if (value.ToLower().StartsWith(text.ToLower()))
{
return value;
}
}
return defaultPrefix + "/" + value;
}
public static void LoadFromConfig(ConfigFile config)
{
EnabledList = new bool[EmoteDefs.getEmoteCount() + 1];
DefaultInputList = new InputBind[EmoteDefs.getEmoteCount() + 1];
string[] names = Enum.GetNames(typeof(Emote));
foreach (string text in names)
{
if (EmoteDefs.getEmoteNumber(text) > 2)
{
string keyboard = "";
int emoteNumber = EmoteDefs.getEmoteNumber(text);
if (emoteNumber <= 10)
{
keyboard = $"<Keyboard>/{emoteNumber % 10}";
}
DefaultInputList[emoteNumber] = GetFromConfig(config, new InputBind(keyboard, ""), text, text + " emote");
}
EnabledList[EmoteDefs.getEmoteNumber(text)] = config.Bind<bool>(EnabledLabel, "Enable " + text, true, "Toggle " + text + " emote key").Value;
}
SignSubmitInput = GetFromConfig(config, SignSubmitInput, "Sign Submit", "sign submit");
SignCancelInput = GetFromConfig(config, SignCancelInput, "Sign Cancel", "sign cancel");
EmoteWheelInput = GetFromConfig(config, EmoteWheelInput, "Emote Wheel", "emote wheel");
EmoteWheelNextInput = GetFromConfig(config, EmoteWheelNextInput, "Emote Wheel Next Page", "emote wheel next page");
EmoteWheelPreviousInput = GetFromConfig(config, EmoteWheelPreviousInput, "Emote Wheel Previous Page", "emote wheel next page");
EmoteWheelMoveInput.controller = ValidatePrefix("<Gamepad>", config.Bind<string>(ControllerLabel, "Emote Wheel Move", EmoteWheelMoveInput.controller, "Default controller binding for the emote wheel movement").Value);
ControllerDeadzone = ValidateGreaterThanEqualToZero(config.Bind<float>(ControllerLabel, "Emote Wheel Deadzone", ControllerDeadzone, "Default controller deadzone for emote selection").Value);
GriddySpeed = ValidateGreaterThanEqualToZero(config.Bind<float>(EmoteSettingsLabel, "Griddy Speed", GriddySpeed, "Speed of griddy relative to regular speed").Value);
PrisyadkaSpeed = ValidateGreaterThanEqualToZero(config.Bind<float>(EmoteSettingsLabel, "Prisyadka Speed", PrisyadkaSpeed, "Speed of Prisyadka relative to regular speed").Value);
EmoteCooldown = ValidateGreaterThanEqualToZero(config.Bind<float>(EmoteSettingsLabel, "Cooldown", EmoteCooldown, "Time (in seconds) to wait before being able to switch emotes").Value);
SignTextCooldown = ValidateGreaterThanEqualToZero(config.Bind<float>(EmoteSettingsLabel, "Sign Text Cooldown", SignTextCooldown, "Time (in seconds) to wait before being able to finish typing (was hard coded into MoreEmotes)").Value);
StopOnOuter = config.Bind<bool>(EmoteSettingsLabel, "Stop on outer", StopOnOuter, "Whether or not to stop emoting when mousing to outside the emote wheel").Value;
LogDelay = ValidateGreaterThanEqualToZero(config.Bind<float>(DebugSettingsLabel, "Trace Delay", LogDelay, "Time (in seconds) to wait before writing the same trace line, trace messages are very spammy").Value);
Debug = config.Bind<bool>(DebugSettingsLabel, "Debug", Debug, "Whether or not to enable debug log messages, bepinex also needs to be configured to show debug logs").Value;
Trace = config.Bind<bool>(DebugSettingsLabel, "Trace", Trace, "Whether or not to enable trace log messages, bepinex also needs to be configured to show debug logs").Value;
DisableSpeedChange = config.Bind<bool>(DebugSettingsLabel, "Disable Speed Changed", DisableSpeedChange, "Whether or not to disable speed changes that might affect other mods").Value;
DisableModelOverride = config.Bind<bool>(DebugSettingsLabel, "Disable Self Emote", DisableModelOverride, "Whether or not to disable overriding the player model, can help with conflicting mods").Value;
}
private static InputBind GetFromConfig(ConfigFile config, InputBind defaultBind, string name, string description)
{
return new InputBind(ValidatePrefixes(new string[2] { "<Keyboard>", "<Mouse>" }, "<Keyboard>", config.Bind<string>(KeyLabel, name + " Key", defaultBind.keyboard, "Default keybind for the " + description).Value), ValidatePrefix("<Gamepad>", config.Bind<string>(ControllerLabel, name + " Button", defaultBind.controller, "Default controller binding for the " + description).Value));
}
}
public struct InputBind
{
public string keyboard;
public string controller;
public InputBind(string keyboard, string controller)
{
this.keyboard = "";
this.controller = "";
this.keyboard = keyboard;
this.controller = controller;
}
public override string ToString()
{
return "('" + keyboard + "', '" + controller + "')";
}
}
}
namespace BetterEmote.Patches
{
internal class EmoteKeybindPatch
{
public static bool EmoteWheelIsOpened;
private static EmoteWheel SelectionWheel;
public static GameObject WheelPrefab;
[HarmonyPatch(typeof(RoundManager), "Awake")]
[HarmonyPostfix]
private static void AwakePost(RoundManager __instance)
{
Plugin.Debug("EmoteKeybindPatch.AwakePost()");
GameObject gameObject = ((Component)((Component)GameObject.Find("Systems").gameObject.transform.Find("UI")).gameObject.transform.Find("Canvas")).gameObject;
if ((Object)(object)WheelPrefab != (Object)null)
{
SelectionWheel = Object.Instantiate<GameObject>(WheelPrefab, gameObject.transform).AddComponent<EmoteWheel>();
}
}
[HarmonyPatch(typeof(PlayerControllerB), "Start")]
[HarmonyPostfix]
private static void StartPostfix(PlayerControllerB __instance)
{
Plugin.Debug("EmoteKeybindPatch.StartPostfix()");
if (Settings.Keybinds != null && !Settings.DisableModelOverride)
{
Settings.Keybinds.MiddleFinger.performed += onEmoteKeyMiddleFinger;
Settings.Keybinds.Griddy.performed += onEmoteKeyGriddy;
Settings.Keybinds.Shy.performed += onEmoteKeyShy;
Settings.Keybinds.Clap.performed += onEmoteKeyClap;
Settings.Keybinds.Salute.performed += onEmoteKeySalute;
Settings.Keybinds.Prisyadka.performed += onEmoteKeyPrisyadka;
Settings.Keybinds.Sign.performed += onEmoteKeySign;
Settings.Keybinds.Twerk.performed += onEmoteKeyTwerk;
Settings.Keybinds.SignSubmit.performed += onSignKeySubmit;
Settings.Keybinds.SignCancel.performed += onSignKeyCancel;
Settings.Keybinds.EmoteWheel.started += onEmoteKeyWheelStarted;
Settings.Keybinds.EmoteWheel.canceled += onEmoteKeyWheelCanceled;
Settings.Keybinds.EmoteWheelNextPage.performed += onEmoteKeyWheelNext;
Settings.Keybinds.EmoteWheelPreviousPage.performed += onEmoteKeyWheelPrevious;
Settings.Keybinds.MiddleFinger.Enable();
Settings.Keybinds.Griddy.Enable();
Settings.Keybinds.Shy.Enable();
Settings.Keybinds.Clap.Enable();
Settings.Keybinds.Salute.Enable();
Settings.Keybinds.Prisyadka.Enable();
Settings.Keybinds.Sign.Enable();
Settings.Keybinds.Twerk.Enable();
Settings.Keybinds.SignSubmit.Enable();
Settings.Keybinds.SignCancel.Enable();
Settings.Keybinds.EmoteWheel.Enable();
Settings.Keybinds.EmoteWheelNextPage.Enable();
Settings.Keybinds.EmoteWheelPreviousPage.Enable();
}
}
[HarmonyPatch(typeof(PlayerControllerB), "OnDisable")]
[HarmonyPostfix]
public static void OnDisablePostfix(PlayerControllerB __instance)
{
Plugin.Debug("EmoteKeybindPatch.OnDisablePostfix()");
if (Settings.Keybinds != null && (Object)(object)__instance == (Object)(object)GameValues.localPlayerController)
{
Settings.Keybinds.MiddleFinger.performed -= onEmoteKeyMiddleFinger;
Settings.Keybinds.Griddy.performed -= onEmoteKeyGriddy;
Settings.Keybinds.Shy.performed -= onEmoteKeyShy;
Settings.Keybinds.Clap.performed -= onEmoteKeyClap;
Settings.Keybinds.Salute.performed -= onEmoteKeySalute;
Settings.Keybinds.Prisyadka.performed -= onEmoteKeyPrisyadka;
Settings.Keybinds.Sign.performed -= onEmoteKeySign;
Settings.Keybinds.Twerk.performed -= onEmoteKeyTwerk;
Settings.Keybinds.SignSubmit.performed -= onSignKeySubmit;
Settings.Keybinds.SignCancel.performed -= onSignKeyCancel;
Settings.Keybinds.EmoteWheel.started -= onEmoteKeyWheelStarted;
Settings.Keybinds.EmoteWheel.canceled -= onEmoteKeyWheelCanceled;
Settings.Keybinds.EmoteWheelNextPage.performed -= onEmoteKeyWheelNext;
Settings.Keybinds.EmoteWheelPreviousPage.performed -= onEmoteKeyWheelPrevious;
Settings.Keybinds.MiddleFinger.Disable();
Settings.Keybinds.Griddy.Disable();
Settings.Keybinds.Shy.Disable();
Settings.Keybinds.Clap.Disable();
Settings.Keybinds.Salute.Disable();
Settings.Keybinds.Prisyadka.Disable();
Settings.Keybinds.Sign.Disable();
Settings.Keybinds.Twerk.Disable();
Settings.Keybinds.SignSubmit.Disable();
Settings.Keybinds.SignCancel.Disable();
Settings.Keybinds.EmoteWheel.Disable();
Settings.Keybinds.EmoteWheelNextPage.Disable();
Settings.Keybinds.EmoteWheelPreviousPage.Disable();
}
}
public static void onSignKeySubmit(CallbackContext context)
{
Plugin.Debug("onSignKeySubmit()");
if (((ButtonControl)Keyboard.current[(Key)52]).isPressed || ((ButtonControl)Keyboard.current[(Key)51]).isPressed)
{
Plugin.Debug("They have one of the shifts pressed");
}
else if (!Settings.DisableModelOverride && (Object)(object)LocalPlayer.CustomSignInputField != (Object)null && LocalPlayer.CustomSignInputField.IsSignUIOpen)
{
LocalPlayer.CustomSignInputField.SubmitText();
}
}
public static void onSignKeyCancel(CallbackContext context)
{
Plugin.Debug("onSignKeyCancel()");
if (!Settings.DisableModelOverride && (Object)(object)LocalPlayer.CustomSignInputField != (Object)null && LocalPlayer.CustomSignInputField.IsSignUIOpen)
{
LocalPlayer.CustomSignInputField.Close(cancelAction: true);
}
}
public static void onEmoteKeyWheelStarted(CallbackContext context)
{
Plugin.Debug("onEmoteKeyWheelStarted()");
if (EmoteWheelIsOpened || !((Object)(object)GameValues.localPlayerController != (Object)null) || GameValues.localPlayerController.isPlayerDead || GameValues.localPlayerController.inTerminalMenu || GameValues.localPlayerController.isTypingChat || GameValues.localPlayerController.quickMenuManager.isMenuOpen || (!((Object)(object)LocalPlayer.CustomSignInputField == (Object)null) && LocalPlayer.CustomSignInputField.IsSignUIOpen))
{
return;
}
EmoteWheelIsOpened = true;
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)2;
EmoteWheel selectionWheel = SelectionWheel;
if (selectionWheel != null)
{
GameObject gameObject = ((Component)selectionWheel).gameObject;
if (gameObject != null)
{
gameObject.SetActive(EmoteWheelIsOpened);
}
}
GameValues.localPlayerController.quickMenuManager.isMenuOpen = true;
GameValues.localPlayerController.disableLookInput = true;
}
public static void onEmoteKeyWheelCanceled(CallbackContext context)
{
//IL_0094: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("onEmoteKeyWheelCanceled()");
if (!EmoteWheelIsOpened || !((Object)(object)GameValues.localPlayerController != (Object)null) || !((Object)(object)SelectionWheel != (Object)null))
{
return;
}
GameValues.localPlayerController.quickMenuManager.isMenuOpen = false;
GameValues.localPlayerController.disableLookInput = false;
if (SelectionWheel.selectedEmoteID >= Settings.EnabledList.Length)
{
if (SelectionWheel.stopEmote)
{
GameValues.localPlayerController.performingEmote = false;
GameValues.localPlayerController.StopPerformingEmoteServerRpc();
GameValues.localPlayerController.timeSinceStartingEmote = 0f;
}
}
else
{
CheckEmoteInput(context, Settings.EnabledList[SelectionWheel.selectedEmoteID], SelectionWheel.selectedEmoteID, GameValues.localPlayerController);
}
Cursor.visible = false;
Cursor.lockState = (CursorLockMode)1;
EmoteWheelIsOpened = false;
((Component)SelectionWheel).gameObject.SetActive(EmoteWheelIsOpened);
}
public static void onEmoteKeyWheelNext(CallbackContext context)
{
Plugin.Debug("onEmoteKeyWheelNext()");
if (EmoteWheelIsOpened)
{
SelectionWheel?.alterPage(1);
}
}
public static void onEmoteKeyWheelPrevious(CallbackContext context)
{
Plugin.Debug("onEmoteKeyWheelPrevious()");
if (EmoteWheelIsOpened)
{
SelectionWheel?.alterPage(-1);
}
}
public static void onEmoteKeyMiddleFinger(CallbackContext context)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("onEmoteKeyMiddleFinger()");
onEmoteKeyPerformed(context, Emote.Middle_Finger);
}
public static void onEmoteKeyGriddy(CallbackContext context)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("onEmoteKeyGriddy()");
onEmoteKeyPerformed(context, Emote.Griddy);
}
public static void onEmoteKeyShy(CallbackContext context)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("onEmoteKeyShy()");
onEmoteKeyPerformed(context, Emote.Shy);
}
public static void onEmoteKeyClap(CallbackContext context)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("onEmoteKeyClap()");
onEmoteKeyPerformed(context, Emote.Clap);
}
public static void onEmoteKeySalute(CallbackContext context)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("onEmoteKeySalute()");
onEmoteKeyPerformed(context, Emote.Salute);
}
public static void onEmoteKeyPrisyadka(CallbackContext context)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("onEmoteKeyPrisyadka()");
onEmoteKeyPerformed(context, Emote.Prisyadka);
}
public static void onEmoteKeySign(CallbackContext context)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("onEmoteKeySign()");
onEmoteKeyPerformed(context, Emote.Sign);
}
public static void onEmoteKeyTwerk(CallbackContext context)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("onEmoteKeyTwerk()");
onEmoteKeyPerformed(context, Emote.Twerk);
}
public static void onEmoteKeyPerformed(CallbackContext context, Emote emote)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
CheckEmoteInput(context, Settings.EnabledList[(int)emote], (int)emote, GameValues.localPlayerController);
}
private static void CheckEmoteInput(CallbackContext context, bool enabled, int emoteID, PlayerControllerB player)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug($"CheckEmoteInput({enabled}, {emoteID})");
if (enabled && (Object)(object)player != (Object)null && !player.isTypingChat)
{
player.PerformEmote(context, emoteID);
}
}
}
internal class EmotePatch
{
public static AssetBundle animationsBundle;
public static AssetBundle animatorBundle;
public static RuntimeAnimatorController local;
public static RuntimeAnimatorController others;
public static bool[] playersPerformingEmotes = new bool[40];
private static SyncAnimatorToOthers syncAnimator;
public static SyncVRState syncVR;
[HarmonyPatch(typeof(PlayerControllerB), "Start")]
[HarmonyPostfix]
[HarmonyPriority(200)]
private static void StartPostfix(PlayerControllerB __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
Plugin.Debug("EmotePatch.StartPostfix()");
((Component)((Component)((Component)__instance).gameObject.transform.Find("ScavengerModel")).transform.Find("metarig")).gameObject.AddComponent<CustomAudioAnimationEvent>().player = __instance;
LocalPlayer.BaseSpeed = __instance.movementSpeed;
((Component)__instance).gameObject.AddComponent<CustomAnimationObjects>();
LocalPlayer.SpawnSign(__instance);
}
}
[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
[HarmonyPostfix]
private static void ConnectClientToPlayerObjectPostfix(PlayerControllerB __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
Plugin.Debug("EmotePatch.ConnectClientToPlayerObjectPostfix()");
if ((Object)(object)syncVR != (Object)null)
{
syncVR.RequestVRStateFromOthers();
syncVR.UpdateVRStateForOthers(Settings.DisableModelOverride);
}
}
}
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
[HarmonyPrefix]
[HarmonyPriority(200)]
private static void UpdatePrefix(PlayerControllerB __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
Plugin.Trace("PlayerControllerB.UpdatePrefix()");
if (__instance.performingEmote)
{
playersPerformingEmotes[__instance.playerClientId] = true;
}
else if (playersPerformingEmotes[__instance.playerClientId])
{
playersPerformingEmotes[__instance.playerClientId] = false;
ResetIKWeights(__instance);
}
}
}
[HarmonyPatch(typeof(PlayerControllerB), "Update")]
[HarmonyPostfix]
private static void UpdatePostfix(PlayerControllerB __instance)
{
if ((Object)(object)__instance == (Object)null)
{
return;
}
Plugin.Trace("PlayerControllerB.UpdatePostfix()");
if (!__instance.isPlayerControlled || !((NetworkBehaviour)__instance).IsOwner)
{
if ((Object)(object)syncVR != (Object)null && SyncVRState.vrPlayers.ContainsKey(__instance.playerClientId) && !SyncVRState.vrPlayers[__instance.playerClientId])
{
__instance.playerBodyAnimator.runtimeAnimatorController = others;
}
return;
}
if ((Object)(object)__instance.playerBodyAnimator != (Object)(object)local)
{
if (LocalPlayer.IsPlayerFirstFrame && !Settings.DisableModelOverride)
{
LocalPlayer.SpawnLegs(__instance);
}
if (!Settings.DisableModelOverride)
{
__instance.playerBodyAnimator.runtimeAnimatorController = local;
}
if (LocalPlayer.IsPlayerFirstFrame)
{
Plugin.Debug("isPlayerFirstFrame");
syncVR = ((Component)__instance).GetComponent<SyncVRState>();
syncAnimator = ((Component)__instance).GetComponent<SyncAnimatorToOthers>();
LocalPlayer.IsPlayerFirstFrame = false;
if (!Settings.DisableModelOverride)
{
LocalPlayer.OnFirstLocalPlayerFrameWithNewAnimator(__instance);
}
if ((Object)(object)syncVR != (Object)null)
{
syncVR.RequestVRStateFromOthers();
syncVR.UpdateVRStateForOthers(Settings.DisableModelOverride);
}
Plugin.Debug("SpawnPlayerAnimation");
__instance.SpawnPlayerAnimation();
}
}
if (!Settings.DisableSpeedChange)
{
__instance.movementSpeed = LocalPlayer.BaseSpeed;
if (__instance.CheckConditionsForEmote() && __instance.performingEmote)
{
if (LocalPlayer.CurrentEmoteID == EmoteDefs.getEmoteNumber(Emote.Griddy))
{
__instance.movementSpeed = LocalPlayer.BaseSpeed * Settings.GriddySpeed;
}
else if (LocalPlayer.CurrentEmoteID == EmoteDefs.getEmoteNumber(Emote.Prisyadka))
{
__instance.movementSpeed = LocalPlayer.BaseSpeed * Settings.PrisyadkaSpeed;
}
}
}
if (!Settings.DisableModelOverride)
{
__instance.localArmsRotationTarget = (LocalPlayer.IsArmsSeparatedFromCamera ? LocalPlayer.freeArmsTarget : LocalPlayer.lockedArmsTarget);
}
}
private static void ResetIKWeights(PlayerControllerB player)
{
Plugin.Debug("ResetIKWeights()");
object obj;
if (player == null)
{
obj = null;
}
else
{
Animator playerBodyAnimator = player.playerBodyAnimator;
if (playerBodyAnimator == null)
{
obj = null;
}
else
{
Transform transform3 = ((Component)playerBodyAnimator).transform;
obj = ((transform3 != null) ? transform3.Find("Rig 1") : null);
}
}
Transform transform = (Transform)obj;
if ((Object)(object)transform != (Object)null)
{
try
{
string[] source = new string[2] { "RightArm", "LeftArm" };
string[] source2 = new string[2] { "RightLeg", "LeftLeg" };
source.ToList().ForEach(delegate(string name)
{
((RigConstraint<ChainIKConstraintJob, ChainIKConstraintData, ChainIKConstraintJobBinder<ChainIKConstraintData>>)(object)((Component)transform.Find(name)).GetComponent<ChainIKConstraint>()).weight = 1f;
});
source2.ToList().ForEach(delegate(string name)
{
((RigConstraint<TwoBoneIKConstraintJob, TwoBoneIKConstraintData, TwoBoneIKConstraintJobBinder<TwoBoneIKConstraintData>>)(object)((Component)transform.Find(name)).GetComponent<TwoBoneIKConstraint>()).weight = 1f;
});
Transform transform2 = ((Component)player.playerBodyAnimator).transform.Find("ScavengerModelArmsOnly").Find("metarig").Find("spine.003")
.Find("RigArms");
source.ToList().ForEach(delegate(string name)
{
((RigConstraint<ChainIKConstraintJob, ChainIKConstraintData, ChainIKConstraintJobBinder<ChainIKConstraintData>>)(object)((Component)transform2.Find(name)).GetComponent<ChainIKConstraint>()).weight = 1f;
});
return;
}
catch (NullReferenceException)
{
Plugin.Logger.LogWarning((object)"Unable to reset IK weights, if this is spammed please report it");
return;
}
}
Plugin.Debug("ResetIKWeights transform is null");
}
[HarmonyPatch(typeof(PlayerControllerB), "PerformEmote")]
[HarmonyPrefix]
private static bool PerformEmotePrefix(ref CallbackContext context, int emoteID, PlayerControllerB __instance)
{
if ((Object)(object)__instance == (Object)null)
{
return true;
}
Plugin.Debug($"PerformEmotePrefix({emoteID})");
int localEmoteID = emoteID;
if (LocalPlayer.CheckIfTooManyEmotesIsPlaying(__instance) && localEmoteID > EmoteDefs.getEmoteNumber(Emote.Point))
{
Plugin.Debug("Is custom emote with too many emotes currently playing");
return false;
}
if ((!((NetworkBehaviour)__instance).IsOwner || !__instance.isPlayerControlled || (((NetworkBehaviour)__instance).IsServer && !__instance.isHostPlayerObject)) && !__instance.isTestingPlayer)
{
Plugin.Debug("Is player controllered or owner check failed");
return false;
}
if ((Object)(object)syncVR != (Object)null)
{
Plugin.Debug("syncVR not null, updating");
syncVR.RequestVRStateFromOthers();
syncVR.UpdateVRStateForOthers(Settings.DisableModelOverride);
}
if ((Object)(object)LocalPlayer.CustomSignInputField != (Object)null && LocalPlayer.CustomSignInputField.IsSignUIOpen && localEmoteID != EmoteDefs.getEmoteNumber(AltEmote.Sign_Text))
{
Plugin.Debug("Sign UI is open, is this a sign?");
return false;
}
if (localEmoteID > 0 && localEmoteID <= EmoteDefs.getEmoteNumber(Emote.Point) && !EmoteKeybindPatch.EmoteWheelIsOpened && !((CallbackContext)(ref context)).performed)
{
Plugin.Debug("Normal emote with no emote wheel or context performed");
return false;
}
string[] names = Enum.GetNames(typeof(DoubleEmote));
foreach (string text in names)
{
Plugin.Debug("Checking double emote " + text);
int emoteNumber = EmoteDefs.getEmoteNumber(EmoteDefs.getEmote(text));
bool flag = false;
if (LocalPlayer.CurrentEmoteID == localEmoteID && localEmoteID >= EmoteDefs.getEmoteNumber(Emote.Point) && __instance.performingEmote && (!__instance.isHoldingObject || !flag))
{
Plugin.Debug("Damn, emote ids match with all other checks");
if (localEmoteID == emoteNumber)
{
Plugin.Debug("Adding offset");
localEmoteID += 1000;
}
else if (localEmoteID > 1000)
{
Plugin.Debug("Removing offset");
localEmoteID -= 1000;
}
}
}
Plugin.Debug($"localEmoteID after: {localEmoteID}");
if ((localEmoteID != LocalPlayer.CurrentEmoteID && localEmoteID <= EmoteDefs.getEmoteNumber(Emote.Point)) || !__instance.performingEmote)
{
Plugin.Debug("Ressetting IKWeights because its not a custom emote");
ResetIKWeights(__instance);
}
Plugin.Trace($"__instance.inSpecialInteractAnimation: {__instance.inSpecialInteractAnimation}");
Plugin.Trace($"__instance.isPlayerDead: {__instance.isPlayerDead}");
Plugin.Trace($"__instance.isJumping: {__instance.isJumping}");
Plugin.Trace($"__instance.moveInputVector.x: {__instance.moveInputVector.x}");
Plugin.Trace($"__instance.isWalking: {__instance.isWalking}");
Plugin.Trace($"__instance.isSprinting: {__instance.isSprinting}");
Plugin.Trace($"__instance.isCrouching: {__instance.isCrouching}");
Plugin.Trace($"__instance.isClimbingLadder: {__instance.isClimbingLadder}");
Plugin.Trace($"__instance.isGrabbingObjectAnimation: {__instance.isGrabbingObjectAnimation}");
Plugin.Trace($"__instance.inTerminalMenu: {__instance.inTerminalMenu}");
Plugin.Trace($"__instance.isTypingChat: {__instance.isTypingChat}");
int currentEmoteID = LocalPlayer.CurrentEmoteID;
LocalPlayer.CurrentEmoteID = localEmoteID;
if (__instance.CheckConditionsForEmote())
{
Plugin.Debug("Check conditions passed");
if (__instance.timeSinceStartingEmote >= Settings.EmoteCooldown)
{
Plugin.Debug("Time elapsed since last emote cooldown");
Action action = delegate
{
Plugin.Debug($"Starting emote {localEmoteID}");
__instance.timeSinceStartingEmote = 0f;
__instance.playerBodyAnimator.SetInteger("emoteNumber", localEmoteID);
__instance.performingEmote = true;
__instance.StartPerformingEmoteServerRpc();
syncAnimator?.UpdateEmoteIDForOthers(localEmoteID);
LocalPlayer.TogglePlayerBadges(enabled: false);
};
if (localEmoteID == EmoteDefs.getEmoteNumber(Emote.Prisyadka) && !Settings.DisableModelOverride)
{
Plugin.Debug("Adding UpdateLegsMaterial for Prisyadka");
action = (Action)Delegate.Combine(action, (Action)delegate
{
LocalPlayer.UpdateLegsMaterial(__instance);
});
}
else if (localEmoteID == EmoteDefs.getEmoteNumber(Emote.Sign) && !Settings.DisableModelOverride)
{
Plugin.Debug("Adding customSignInputField setActive for Sign");
action = (Action)Delegate.Combine(action, (Action)delegate
{
((Component)LocalPlayer.CustomSignInputField).gameObject.SetActive(true);
});
}
action();
return false;
}
LocalPlayer.CurrentEmoteID = currentEmoteID;
Plugin.Debug("Emote cooldown still in effect, try again soon");
return false;
}
LocalPlayer.CurrentEmoteID = currentEmoteID;
Plugin.Debug("Check confitions failed");
return false;
}
[HarmonyPatch(typeof(PlayerControllerB), "CheckConditionsForEmote")]
[HarmonyPostfix]
private static void postfixCheckConditions(ref bool __result, PlayerControllerB __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
Plugin.Trace($"prefixCheckConditions({LocalPlayer.CurrentEmoteID})");
if (LocalPlayer.CurrentEmoteID == EmoteDefs.getEmoteNumber(Emote.Griddy) || LocalPlayer.CurrentEmoteID == EmoteDefs.getEmoteNumber(Emote.Prisyadka))
{
__result = !__instance.inSpecialInteractAnimation && !__instance.isPlayerDead && !__instance.isJumping && __instance.moveInputVector.x == 0f && !__instance.isSprinting && !__instance.isCrouching && !__instance.isClimbingLadder && !__instance.isGrabbingObjectAnimation && !__instance.inTerminalMenu && !__instance.isTypingChat;
}
else if (LocalPlayer.CurrentEmoteID == EmoteDefs.getEmoteNumber(Emote.Sign) || LocalPlayer.CurrentEmoteID == EmoteDefs.getEmoteNumber(AltEmote.Sign_Text))
{
__result = !__instance.inSpecialInteractAnimation && !__instance.isPlayerDead && !__instance.isJumping && !__instance.isWalking && !__instance.isCrouching && !__instance.isClimbingLadder && !__instance.isGrabbingObjectAnimation && !__instance.inTerminalMenu;
}
}
}
[HarmonyPatch(typeof(PlayerControllerB), "StopPerformingEmoteServerRpc")]
[HarmonyPostfix]
private static void StopPerformingEmoteServerPrefix(PlayerControllerB __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
Plugin.Debug("StopPerformingEmoteServerPrefix()");
if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled)
{
__instance.playerBodyAnimator.SetInteger("emoteNumber", 0);
syncAnimator?.UpdateEmoteIDForOthers(0);
LocalPlayer.CurrentEmoteID = 0;
}
LocalPlayer.TogglePlayerBadges(enabled: true);
}
}
}
internal class RoundPatch
{
[HarmonyPatch(typeof(RoundManager), "Awake")]
[HarmonyPostfix]
private static void AwakePost()
{
Plugin.Debug("AwakePost()");
Settings.DebugAllSettings();
if (!Settings.DisableModelOverride)
{
GameObject gameObject = ((Component)((Component)GameObject.Find("Systems").gameObject.transform.Find("UI")).gameObject.transform.Find("Canvas")).gameObject;
LocalPlayer.CustomSignInputField = Object.Instantiate<GameObject>(LocalPlayer.SignUIPrefab, gameObject.transform).AddComponent<SignUI>();
}
LocalPlayer.IsPlayerFirstFrame = true;
}
}
internal class SignChatPatch
{
[HarmonyPatch(typeof(HUDManager), "EnableChat_performed")]
[HarmonyPrefix]
private static bool OpenChatPrefix()
{
if (!((Object)(object)LocalPlayer.CustomSignInputField == (Object)null))
{
return !LocalPlayer.CustomSignInputField.IsSignUIOpen;
}
return true;
}
[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
[HarmonyPrefix]
private static bool SubmitChatPrefix()
{
if (!((Object)(object)LocalPlayer.CustomSignInputField == (Object)null))
{
return !LocalPlayer.CustomSignInputField.IsSignUIOpen;
}
return true;
}
}
}
namespace BetterEmote.Netcode
{
public class SignEmoteText : NetworkBehaviour
{
private PlayerControllerB playerInstance;
private TextMeshPro signModelText;
private void Start()
{
Plugin.Debug("Start()");
playerInstance = ((Component)this).GetComponent<PlayerControllerB>();
PlayerControllerB obj = playerInstance;
object obj2;
if (obj == null)
{
obj2 = null;
}
else
{
Transform transform = ((Component)obj).transform;
if (transform == null)
{
obj2 = null;
}
else
{
Transform obj3 = transform.Find("ScavengerModel");
if (obj3 == null)
{
obj2 = null;
}
else
{
Transform obj4 = obj3.Find("metarig");
if (obj4 == null)
{
obj2 = null;
}
else
{
Transform obj5 = obj4.Find("Sign");
if (obj5 == null)
{
obj2 = null;
}
else
{
Transform obj6 = obj5.Find("Text");
obj2 = ((obj6 != null) ? ((Component)obj6).GetComponent<TextMeshPro>() : null);
}
}
}
}
}
signModelText = (TextMeshPro)obj2;
}
public void UpdateSignText(string newText)
{
Plugin.Debug("UpdateSignText(" + newText + ")");
if ((Object)(object)playerInstance != (Object)null && ((NetworkBehaviour)playerInstance).IsOwner && playerInstance.isPlayerControlled)
{
UpdateSignTextServerRpc(newText);
}
}
[ServerRpc(RequireOwnership = false)]
private void UpdateSignTextServerRpc(string newText)
{
Plugin.Debug("UpdateSignTextServerRpc(" + newText + ")");
UpdateSignTextClientRpc(newText);
}
[ClientRpc]
private void UpdateSignTextClientRpc(string newText)
{
Plugin.Debug("UpdateSignTextClientRpc(" + newText + ")");
if ((Object)(object)signModelText != (Object)null)
{
((TMP_Text)signModelText).text = newText;
}
}
}
public class SyncAnimatorToOthers : NetworkBehaviour
{
private PlayerControllerB playerInstance;
private void Start()
{
playerInstance = ((Component)this).GetComponent<PlayerControllerB>();
}
public void UpdateEmoteIDForOthers(int newID)
{
Plugin.Debug($"UpdateEmoteIDForOthers({newID}, {((NetworkBehaviour)playerInstance).IsOwner}, {playerInstance.isPlayerControlled})");
if (((NetworkBehaviour)playerInstance).IsOwner && playerInstance.isPlayerControlled)
{
UpdateCurrentEmoteIDServerRpc(newID);
}
}
[ServerRpc(RequireOwnership = false)]
private void UpdateCurrentEmoteIDServerRpc(int newID)
{
Plugin.Debug($"UpdateCurrentEmoteIDServerRpc({newID})");
UpdateCurrentEmoteIDClientRpc(newID);
}
[ClientRpc]
private void UpdateCurrentEmoteIDClientRpc(int newID)
{
Plugin.Debug($"UpdateCurrentEmoteIDClientRpc({newID}, {((NetworkBehaviour)playerInstance).IsOwner}, {playerInstance.isPlayerControlled})");
if (!((NetworkBehaviour)playerInstance).IsOwner || !playerInstance.isPlayerControlled)
{
playerInstance.playerBodyAnimator.SetInteger("emoteNumber", newID);
}
}
}
public class SyncVRState : NetworkBehaviour
{
private PlayerControllerB playerInstance;
public static Dictionary<ulong, bool> vrPlayers = new Dictionary<ulong, bool>();
private void Start()
{
playerInstance = ((Component)this).GetComponent<PlayerControllerB>();
}
public void UpdateVRStateForOthers(bool isVR)
{
Plugin.Debug($"UpdateVRStatusForOthers({isVR}, {playerInstance.playerClientId}, {((NetworkBehaviour)playerInstance).IsOwner}, {playerInstance.isPlayerControlled})");
if ((Object)(object)playerInstance != (Object)null && ((NetworkBehaviour)playerInstance).IsOwner && playerInstance.isPlayerControlled)
{
UpdateVRStateServerRpc(isVR, playerInstance.playerClientId);
}
}
public void RequestVRStateFromOthers()
{
Plugin.Debug($"RequestVRStateFromOthers({((NetworkBehaviour)playerInstance).IsOwner}, {playerInstance.isPlayerControlled})");
if ((Object)(object)playerInstance != (Object)null && ((NetworkBehaviour)playerInstance).IsOwner && playerInstance.isPlayerControlled)
{
RequestedVRStateServerRpc();
}
}
[ServerRpc(RequireOwnership = false)]
private void RequestedVRStateServerRpc()
{
Plugin.Debug("RequestedVRState()");
RequestedVRStateClientRpc();
}
[ClientRpc]
private void RequestedVRStateClientRpc()
{
Plugin.Debug($"RequestedVRStateClientRpc({Settings.DisableModelOverride}, {GameValues.localPlayerController.playerClientId})");
if ((Object)(object)playerInstance != (Object)null && !((NetworkBehaviour)playerInstance).IsOwner)
{
UpdateVRStateServerRpc(Settings.DisableModelOverride, GameValues.localPlayerController.playerClientId);
}
}
[ServerRpc(RequireOwnership = false)]
private void UpdateVRStateServerRpc(bool isVR, ulong clientId)
{
Plugin.Debug($"UpdateVRStateServerRpc({isVR}, {clientId})");
UpdateVRStateClientRpc(isVR, clientId);
}
[ClientRpc]
private void UpdateVRStateClientRpc(bool isVRChange, ulong clientId)
{
Plugin.Debug($"UpdateVRStateClientRpc({isVRChange}, {clientId})");
vrPlayers[clientId] = isVRChange;
}
}
}
namespace BetterEmote.Compatibility
{
[Patcher.CompatPatch("io.daxcess.lcvr")]
[HarmonyPatch]
internal class LCVRChecks
{
[HarmonyPatch(typeof(InitializeGame), "Start")]
[HarmonyPostfix]
private static void StartPostfix()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("LCVRChecks.StartPostfix()");
try
{
if (((Enum)Plugin.Flags).HasFlag((Enum)(object)(Flags)1))
{
Plugin.Debug("Found VR mode on LCVR, disabiling self emotes");
Settings.DisableModelOverride = true;
}
}
catch (Exception ex)
{
Plugin.Logger.LogWarning((object)("Unable to hook into LCVR to see if the player is VR " + ex.Message));
}
}
}
[Patcher.CompatPatch("Stoneman.LethalProgression")]
[HarmonyPatch]
internal class LethalProgression
{
[HarmonyPatch(typeof(InitializeGame), "Start")]
[HarmonyPostfix]
private static void StartPostfix()
{
Plugin.Debug("LethalProgression.StartPostfix()");
Settings.DisableSpeedChange = true;
}
}
[Patcher.CompatPatch("com.malco.lethalcompany.moreshipupgrades")]
[HarmonyPatch]
internal class MoreShipUpgrades
{
[HarmonyPatch(typeof(InitializeGame), "Start")]
[HarmonyPostfix]
private static void StartPostfix()
{
Plugin.Debug("MoreShipUpgrades.StartPostfix()");
Settings.DisableSpeedChange = true;
}
}
internal class Patcher
{
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
internal class CompatPatchAttribute : Attribute
{
public string Dependency { get; }
public CompatPatchAttribute(string dependency)
{
Dependency = dependency;
base..ctor();
}
}
public static void patchCompat(Harmony patcher)
{
Plugin.Debug("patchCompat()");
CollectionExtensions.Do<Type>((IEnumerable<Type>)AccessTools.GetTypesFromAssembly(Assembly.GetExecutingAssembly()), (Action<Type>)delegate(Type type)
{
try
{
CompatPatchAttribute compatPatchAttribute = (CompatPatchAttribute)Attribute.GetCustomAttribute(type, typeof(CompatPatchAttribute));
if (compatPatchAttribute != null)
{
Plugin.Debug("Checking for mod to patch: " + compatPatchAttribute.Dependency);
if (hasMod(compatPatchAttribute.Dependency))
{
Plugin.Debug("Patching now");
patcher.CreateClassProcessor(type).Patch();
}
}
}
catch (Exception ex)
{
Plugin.Logger.LogError((object)$"Failed to apply patches from {type}: {ex.Message}");
}
});
}
public static bool hasMod(string guid)
{
Plugin.Debug("Compatibility.hasMod(" + guid + ")");
foreach (PluginInfo value in Chainloader.PluginInfos.Values)
{
Plugin.Debug("Checking against " + value.Metadata.GUID);
if (value.Metadata.GUID == guid)
{
Plugin.Debug("has mod!");
return true;
}
}
return false;
}
}
}
namespace BetterEmote.AssetScripts
{
public class CustomAnimationObjects : MonoBehaviour
{
private PlayerControllerB playerInstance;
private MeshRenderer sign;
private GameObject signText;
private SkinnedMeshRenderer legs;
private void Start()
{
Plugin.Debug("CustomAnimationObjects.Start()");
playerInstance = ((Component)this).GetComponent<PlayerControllerB>();
}
private void Update()
{
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
Plugin.Trace("CustomAnimationObjects.Update()");
if ((Object)(object)sign == (Object)null || (Object)(object)signText == (Object)null)
{
FindSign();
return;
}
try
{
((Component)sign).transform.localPosition = ((Component)sign).transform.parent.Find("spine").localPosition;
if ((Object)(object)playerInstance == (Object)null)
{
return;
}
if ((Object)(object)legs == (Object)null && ((NetworkBehaviour)playerInstance).IsOwner && playerInstance.isPlayerControlled && !Settings.DisableModelOverride)
{
FindLegs();
return;
}
DisableEverything();
if (!playerInstance.performingEmote)
{
return;
}
Animator playerBodyAnimator = playerInstance.playerBodyAnimator;
int num = ((playerBodyAnimator != null) ? playerBodyAnimator.GetInteger("emoteNumber") : 0);
if (num == EmoteDefs.getEmoteNumber(Emote.Prisyadka))
{
if ((Object)(object)legs != (Object)null)
{
((Renderer)legs).enabled = true;
}
if (((NetworkBehaviour)playerInstance).IsOwner && !Settings.DisableModelOverride)
{
LocalPlayer.IsArmsSeparatedFromCamera = true;
}
}
else if ((Object)(object)sign != (Object)null && (num == EmoteDefs.getEmoteNumber(Emote.Sign) || num == EmoteDefs.getEmoteNumber(AltEmote.Sign_Text)))
{
((Renderer)sign).enabled = true;
if ((Object)(object)signText != (Object)null && !signText.activeSelf)
{
Plugin.Trace("Sign isnt active self");
signText.SetActive(true);
}
if (((NetworkBehaviour)playerInstance).IsOwner && !Settings.DisableModelOverride)
{
LocalPlayer.IsArmsSeparatedFromCamera = true;
}
}
}
catch (Exception ex)
{
Plugin.Debug("Custom animation update failed " + ex.Message);
}
}
private void DisableEverything()
{
Plugin.Trace("DisableEverything()");
if ((Object)(object)legs != (Object)null)
{
((Renderer)legs).enabled = false;
}
((Renderer)sign).enabled = false;
if (signText.activeSelf)
{
signText.SetActive(false);
}
if ((Object)(object)playerInstance != (Object)null && ((NetworkBehaviour)playerInstance).IsOwner && playerInstance.isPlayerControlled && !Settings.DisableModelOverride)
{
LocalPlayer.IsArmsSeparatedFromCamera = false;
}
}
private void FindSign()
{
Plugin.Debug("FindSign()");
if ((Object)(object)sign == (Object)null && (Object)(object)playerInstance != (Object)null)
{
Plugin.Debug("Sign is null and player exists");
sign = ((Component)((Component)playerInstance).transform.Find("ScavengerModel").Find("metarig").Find("Sign")).GetComponent<MeshRenderer>();
}
if ((Object)(object)signText == (Object)null && (Object)(object)sign != (Object)null)
{
Plugin.Debug("Sign text is null and sign exists");
signText = ((Component)((Component)sign).transform.Find("Text")).gameObject;
}
}
private void FindLegs()
{
Plugin.Debug("FindLegs()");
if ((Object)(object)legs == (Object)null && (Object)(object)playerInstance != (Object)null)
{
Plugin.Debug("Legs are null and player exists");
try
{
legs = ((Component)((Component)playerInstance).transform.Find("ScavengerModel").Find("LEGS")).GetComponent<SkinnedMeshRenderer>();
}
catch (Exception)
{
Plugin.Logger.LogWarning((object)"Unable to find custom legs, this should be corrected soon.");
}
}
}
}
public class CustomAudioAnimationEvent : MonoBehaviour
{
private Animator animator;
private AudioSource SoundsSource;
public static AudioClip[] claps = (AudioClip[])(object)new AudioClip[2];
public PlayerControllerB player;
private void Start()
{
animator = ((Component)this).GetComponent<Animator>();
SoundsSource = player.movementAudio;
}
public void PlayClapSound()
{
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)player != (Object)null && player.performingEmote && (!((NetworkBehaviour)player).IsOwner || !player.isPlayerControlled || getCurrentEmoteID() == 4))
{
bool flag = player.isInHangarShipRoom && (player.playersManager?.hangarDoorsClosed ?? false);
RoundManager.Instance.PlayAudibleNoise(((Component)player).transform.position, 22f, 0.6f, 0, flag, 6);
SoundsSource.pitch = Random.Range(0.59f, 0.79f);
if (claps != null && claps.Length != 0)
{
SoundsSource.PlayOneShot(claps[Random.Range(0, claps.Length)]);
}
}
}
public void PlayFootstepSound()
{
if ((Object)(object)player != (Object)null && player.performingEmote && (!((NetworkBehaviour)player).IsOwner || !player.isPlayerControlled || getCurrentEmoteID() == 6))
{
player.PlayFootstepLocal();
player.PlayFootstepServer();
}
}
private int getCurrentEmoteID()
{
Animator obj = animator;
return EmoteDefs.normalizeEmoteNumber((obj != null) ? obj.GetInteger("emoteNumber") : 0);
}
}
internal class EmoteWheel : MonoBehaviour
{
private static readonly int TotalBlocks = 8;
private static readonly float SelectionArrowDelaySpeed = 20f;
private static readonly float PageCooldown = 0.1f;
public static readonly float WheelMovementOffset = 3.3f;
private float ignoreRadius = 235f;
private float stopRadius = 470f;
public RectTransform selectionBlock;
public RectTransform selectionArrow;
public Text emoteInformation;
public Text pageInformation;
public GameObject[] pages = Array.Empty<GameObject>();
public bool stopEmote;
public bool controller;
private int currentBlock = 1;
public int pageNumber;
public int selectedEmoteID;
private float angle;
private float pageCurrentCooldown = PageCooldown;
private Vector2 centerScreen;
private StickControl joystick;
private void Awake()
{
Plugin.Debug("EmoteWheel.Awake()");
findGraphics();
findPages(((Component)this).gameObject.transform.Find("FunctionalContent"));
updatePageInfo();
}
private void OnEnable()
{
//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_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: 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_0069: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("EmoteWheel.OnEnable()");
centerScreen = new Vector2((float)(Screen.width / 2), (float)(Screen.height / 2));
Cursor.visible = true;
if (!GameValues.localPlayerUsingController)
{
Mouse.current.WarpCursorPosition(centerScreen);
}
string text = "";
Enumerator<InputBinding> enumerator = Settings.Keybinds.EmoteWheelController.bindings.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
InputBinding current = enumerator.Current;
if (((InputBinding)(ref current)).effectivePath != null && ((InputBinding)(ref current)).effectivePath.Length > 0)
{
text = ((InputBinding)(ref current)).effectivePath;
}
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
if (Gamepad.current != null)
{
if (text == "<Gamepad>/leftStick")
{
joystick = Gamepad.current.leftStick;
}
else
{
joystick = Gamepad.current.rightStick;
}
}
else
{
joystick = null;
}
if ((float)(Screen.width / Screen.height) >= 1f)
{
ignoreRadius = (float)Screen.height * 0.365f / 2f;
stopRadius = (float)Screen.height * 0.729f / 2f;
}
else
{
ignoreRadius = (float)Screen.width * 0.183f / 2f;
stopRadius = (float)Screen.width * 0.368f / 2f;
}
}
private void findGraphics()
{
Plugin.Debug("EmoteWheel.findGraphics()");
try
{
Transform transform = ((Component)this).gameObject.transform;
object obj;
if (transform == null)
{
obj = null;
}
else
{
Transform obj2 = transform.Find("Graphics");
if (obj2 == null)
{
obj = null;
}
else
{
GameObject gameObject = ((Component)obj2).gameObject;
if (gameObject == null)
{
obj = null;
}
else
{
Transform transform2 = gameObject.transform;
if (transform2 == null)
{
obj = null;
}
else
{
Transform obj3 = transform2.Find("SelectionArrow");
if (obj3 == null)
{
obj = null;
}
else
{
GameObject gameObject2 = ((Component)obj3).gameObject;
obj = ((gameObject2 != null) ? gameObject2.GetComponent<RectTransform>() : null);
}
}
}
}
}
selectionArrow = (RectTransform)obj;
Transform transform3 = ((Component)this).gameObject.transform;
object obj4;
if (transform3 == null)
{
obj4 = null;
}
else
{
Transform obj5 = transform3.Find("SelectedEmote");
if (obj5 == null)
{
obj4 = null;
}
else
{
GameObject gameObject3 = ((Component)obj5).gameObject;
obj4 = ((gameObject3 != null) ? gameObject3.GetComponent<RectTransform>() : null);
}
}
selectionBlock = (RectTransform)obj4;
Transform transform4 = ((Component)this).gameObject.transform;
object obj6;
if (transform4 == null)
{
obj6 = null;
}
else
{
Transform obj7 = transform4.Find("Graphics");
if (obj7 == null)
{
obj6 = null;
}
else
{
GameObject gameObject4 = ((Component)obj7).gameObject;
if (gameObject4 == null)
{
obj6 = null;
}
else
{
Transform transform5 = gameObject4.transform;
if (transform5 == null)
{
obj6 = null;
}
else
{
Transform obj8 = transform5.Find("EmoteInfo");
obj6 = ((obj8 != null) ? ((Component)obj8).GetComponent<Text>() : null);
}
}
}
}
emoteInformation = (Text)obj6;
Transform transform6 = ((Component)this).gameObject.transform;
object obj9;
if (transform6 == null)
{
obj9 = null;
}
else
{
Transform obj10 = transform6.Find("Graphics");
if (obj10 == null)
{
obj9 = null;
}
else
{
GameObject gameObject5 = ((Component)obj10).gameObject;
if (gameObject5 == null)
{
obj9 = null;
}
else
{
Transform transform7 = gameObject5.transform;
if (transform7 == null)
{
obj9 = null;
}
else
{
Transform obj11 = transform7.Find("PageNumber");
obj9 = ((obj11 != null) ? ((Component)obj11).GetComponent<Text>() : null);
}
}
}
}
pageInformation = (Text)obj9;
}
catch (Exception ex)
{
Plugin.Debug("Unable to find graphics " + ex.Message);
}
}
private void findPages(Transform contentParent)
{
pages = (GameObject[])(object)new GameObject[((Component)contentParent).transform.childCount];
updatePageInfo();
for (int i = 0; i < ((Component)contentParent).transform.childCount; i++)
{
pages[i] = ((Component)((Component)contentParent).transform.GetChild(i)).gameObject;
}
}
private void Update()
{
Plugin.Trace("EmoteWheel.Update()");
wheelSelection();
updateSelectionArrow();
if (pageCurrentCooldown > 0f)
{
pageCurrentCooldown -= Time.deltaTime;
}
if ((Object)(object)selectionBlock != (Object)null && ((Component)selectionBlock).gameObject.activeSelf)
{
Plugin.Trace("Selection block active self");
selectedEmoteID = currentBlock + Mathf.RoundToInt((float)(TotalBlocks / 4)) + TotalBlocks * pageNumber;
}
else
{
Plugin.Trace("Selection block nooo active self");
selectedEmoteID = EmoteDefs.getEmoteCount() + 2;
}
displayEmoteInfo();
}
private void wheelSelection()
{
//IL_0051: 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_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_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: 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_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: 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_0091: 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_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_0165: Unknown result type (might be due to invalid IL or missing references)
//IL_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_0233: Unknown result type (might be due to invalid IL or missing references)
//IL_0243: Unknown result type (might be due to invalid IL or missing references)
//IL_0257: Unknown result type (might be due to invalid IL or missing references)
Plugin.Trace("EmoteWheel.wheelSelection()");
Vector2 zero;
Vector2 val;
if (joystick != null && GameValues.localPlayerUsingController)
{
if (Vector2.Distance(Vector2.zero, ((InputControl<Vector2>)(object)joystick).ReadValue()) < WheelMovementOffset / 100f)
{
return;
}
zero = Vector2.zero;
val = ((InputControl<Vector2>)(object)joystick).ReadValue();
}
else
{
if (Vector2.Distance(centerScreen, ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue()) < WheelMovementOffset)
{
return;
}
zero = centerScreen;
val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue();
}
Vector2 val2 = val - zero;
double num = Math.Pow(val2.x, 2.0) + Math.Pow(val2.y, 2.0);
bool flag;
bool flag2;
if (GameValues.localPlayerUsingController)
{
flag = num <= Math.Pow(Settings.ControllerDeadzone, 2.0);
flag2 = false;
}
else
{
flag = num < Math.Pow(ignoreRadius, 2.0);
flag2 = num >= Math.Pow(stopRadius, 2.0);
}
int num2 = ((!(val2.x > 0f)) ? ((val2.y > 0f) ? 2 : 3) : ((val2.y > 0f) ? 1 : 4));
float num3 = 180 * (num2 - ((num2 <= 2) ? 1 : 2));
angle = Mathf.Atan(val2.y / val2.x) * (180f / MathF.PI) + num3;
if (angle == 90f)
{
angle = 270f;
}
else if (angle == 270f)
{
angle = 90f;
}
float num4 = 360 / TotalBlocks;
currentBlock = Mathf.RoundToInt((angle - num4 * 1.5f) / num4);
if (flag)
{
RectTransform obj = selectionBlock;
if (obj != null)
{
GameObject gameObject = ((Component)obj).gameObject;
if (gameObject != null)
{
gameObject.SetActive(false);
}
}
return;
}
if ((Object)(object)selectionBlock != (Object)null)
{
GameObject gameObject2 = ((Component)selectionBlock).gameObject;
if (gameObject2 != null)
{
gameObject2.SetActive(true);
}
((Transform)selectionBlock).localRotation = Quaternion.Euler(((Component)this).transform.rotation.z, ((Component)this).transform.rotation.y, num4 * (float)currentBlock);
}
if (!flag2)
{
return;
}
if (Settings.StopOnOuter)
{
RectTransform obj2 = selectionBlock;
if (obj2 != null)
{
GameObject gameObject3 = ((Component)obj2).gameObject;
if (gameObject3 != null)
{
gameObject3.SetActive(false);
}
}
stopEmote = true;
}
else
{
stopEmote = false;
}
}
public void alterPage(int byValue)
{
Plugin.Trace("EmoteWheel.pageSelection()");
if (!(pageCurrentCooldown <= 0f))
{
return;
}
GameObject[] array = pages;
foreach (GameObject obj in array)
{
if (obj != null)
{
obj.SetActive(false);
}
}
pageNumber = (pageNumber + byValue + pages.Length) % pages.Length;
GameObject obj2 = pages[pageNumber];
if (obj2 != null)
{
obj2.SetActive(true);
}
pageCurrentCooldown = PageCooldown;
updatePageInfo();
}
private void updatePageInfo()
{
Plugin.Trace($"EmoteWheel.updatePageInfo({pageNumber}, {pages.Length})");
if ((Object)(object)pageInformation != (Object)null)
{
pageInformation.text = $"<color=#fe6b02><</color> Page {pageNumber + 1}/{pages.Length} <color=#fe6b02>></color>";
}
}
private void displayEmoteInfo()
{
Plugin.Trace($"EmoteWheel.displayEmoteInfo({selectedEmoteID})");
InputBind bind = ((selectedEmoteID > EmoteDefs.getEmoteCount()) ? new InputBind("", "") : Keybinds.getDisplayStrings(Settings.Keybinds.getByEmote((Emote)selectedEmoteID)));
string text = "Empty";
if (selectedEmoteID <= EmoteDefs.getEmoteCount())
{
Plugin.Trace("selectedEmoteID less or equal to emotes length");
Emote emote = (Emote)selectedEmoteID;
text = emote.ToString().Replace("_", " ");
}
if ((Object)(object)emoteInformation != (Object)null)
{
emoteInformation.text = text + "\n" + Keybinds.formatInputBind(bind);
}
}
private void updateSelectionArrow()
{
//IL_002d: 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_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
Plugin.Trace("EmoteWheel.updateSelectionArrow()");
Quaternion val = Quaternion.Euler(0f, 0f, angle - (float)(360 / TotalBlocks) * 2f);
if ((Object)(object)selectionArrow != (Object)null)
{
((Transform)selectionArrow).localRotation = Quaternion.Lerp(((Transform)selectionArrow).localRotation, val, Time.deltaTime * SelectionArrowDelaySpeed);
}
}
}
internal class LocalPlayer
{
public static GameObject LegsPrefab;
public static GameObject SignPrefab;
public static GameObject SignUIPrefab;
private static GameObject LevelBadge;
private static GameObject BetaBadge;
public static Transform freeArmsTarget;
public static Transform lockedArmsTarget;
private static Transform legsMesh;
public static int CurrentEmoteID;
public static bool IsPlayerFirstFrame;
public static bool IsArmsSeparatedFromCamera;
public static float BaseSpeed;
public static SignUI CustomSignInputField;
public static void OnFirstLocalPlayerFrameWithNewAnimator(PlayerControllerB player)
{
Plugin.Debug("OnFirstLocalPlayerFrameWithNewAnimator()");
if ((Object)(object)CustomSignInputField != (Object)null)
{
CustomSignInputField.Player = player;
}
try
{
freeArmsTarget = Object.Instantiate<Transform>(player.localArmsRotationTarget, player.localArmsRotationTarget.parent.parent);
lockedArmsTarget = player.localArmsRotationTarget;
Transform obj = ((Component)player).transform.Find("ScavengerModel").Find("metarig").Find("spine")
.Find("spine.001")
.Find("spine.002")
.Find("spine.003");
LevelBadge = ((Component)obj.Find("LevelSticker")).gameObject;
BetaBadge = ((Component)obj.Find("BetaBadge")).gameObject;
}
catch (Exception ex)
{
Plugin.Debug("Unable to init first frame objects: " + ex.Message);
}
}
public static void SpawnSign(PlayerControllerB player)
{
//IL_0078: 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)
Plugin.Debug("SpawnSign()");
try
{
GameObject val = Object.Instantiate<GameObject>(SignPrefab, ((Component)((Component)((Component)player).transform.Find("ScavengerModel")).transform.Find("metarig")).transform);
if ((Object)(object)val != (Object)null)
{
Plugin.Debug("Sign object not null");
((Object)val).name = "Sign";
val.transform.SetSiblingIndex(6);
val.transform.localPosition = new Vector3(0.029f, -0.45f, 1.3217f);
val.transform.localRotation = Quaternion.Euler(65.556f, 180f, 180f);
}
}
catch (Exception ex)
{
Plugin.Debug("Unable to spawn sign: " + ex.Message);
}
}
public static void SpawnLegs(PlayerControllerB player)
{
//IL_00e4: 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)
Plugin.Debug("SpawnLegs()");
try
{
GameObject obj = Object.Instantiate<GameObject>(LegsPrefab, ((Component)((Component)player.playerBodyAnimator).transform.parent).transform);
legsMesh = obj.transform.Find("Mesh");
((Object)legsMesh).name = "LEGS";
Transform transform = ((Component)legsMesh).transform;
Animator playerBodyAnimator = player.playerBodyAnimator;
object parent;
if (playerBodyAnimator == null)
{
parent = null;
}
else
{
Transform transform2 = ((Component)playerBodyAnimator).transform;
parent = ((transform2 != null) ? transform2.parent : null);
}
transform.parent = (Transform)parent;
Transform transform3 = obj.transform;
object obj2;
if (transform3 == null)
{
obj2 = null;
}
else
{
Transform obj3 = transform3.Find("Armature");
obj2 = ((obj3 != null) ? ((Component)obj3).gameObject : null);
}
GameObject val = (GameObject)obj2;
if ((Object)(object)val != (Object)null)
{
((Object)val).name = "FistPersonLegs";
Transform transform4 = val.transform;
Animator playerBodyAnimator2 = player.playerBodyAnimator;
transform4.parent = ((playerBodyAnimator2 != null) ? ((Component)playerBodyAnimator2).transform : null);
val.transform.position = new Vector3(0f, 0.197f, 0f);
val.transform.localScale = new Vector3(13.99568f, 13.99568f, 13.99568f);
}
Object.Destroy((Object)(object)obj);
}
catch (Exception ex)
{
Plugin.Debug("Unable to spawn legs: " + ex.Message);
}
}
public static void UpdateLegsMaterial(PlayerControllerB player)
{
Plugin.Debug("UpdateLegsMaterial()");
if ((Object)(object)legsMesh == (Object)null)
{
return;
}
SkinnedMeshRenderer component = ((Component)legsMesh).GetComponent<SkinnedMeshRenderer>();
if ((Object)(object)component == (Object)null)
{
return;
}
Animator playerBodyAnimator = player.playerBodyAnimator;
object obj;
if (playerBodyAnimator == null)
{
obj = null;
}
else
{
Transform transform = ((Component)playerBodyAnimator).transform;
if (transform == null)
{
obj = null;
}
else
{
Transform parent = transform.parent;
if (parent == null)
{
obj = null;
}
else
{
Transform transform2 = ((Component)parent).transform;
if (transform2 == null)
{
obj = null;
}
else
{
Transform obj2 = transform2.Find("LOD1");
if (obj2 == null)
{
obj = null;
}
else
{
GameObject gameObject = ((Component)obj2).gameObject;
if (gameObject == null)
{
obj = null;
}
else
{
SkinnedMeshRenderer component2 = gameObject.GetComponent<SkinnedMeshRenderer>();
obj = ((component2 != null) ? ((Renderer)component2).material : null);
}
}
}
}
}
}
Material val = (Material)obj;
if (!((Object)(object)val == (Object)null))
{
((Renderer)component).material = val;
}
}
public static bool CheckIfTooManyEmotesIsPlaying(PlayerControllerB player)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("CheckIfTooManyEmotesIsPlaying()");
Animator playerBodyAnimator = player.playerBodyAnimator;
if ((Object)(object)playerBodyAnimator != (Object)null)
{
try
{
AnimatorStateInfo currentAnimatorStateInfo = playerBodyAnimator.GetCurrentAnimatorStateInfo(1);
return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Dance1") && player.performingEmote && GetAnimatorEmoteClipName(playerBodyAnimator) != "Dance1";
}
catch (Exception)
{
return false;
}
}
return false;
}
private static string GetAnimatorEmoteClipName(Animator animator)
{
Plugin.Debug("GetAnimatorEmoteClipName()");
try
{
return ((Object)((AnimatorClipInfo)(ref animator.GetCurrentAnimatorClipInfo(1)[0])).clip).name;
}
catch (Exception)
{
return "";
}
}
public static void TogglePlayerBadges(bool enabled)
{
Plugin.Debug($"TogglePlayerBadges({enabled})");
if ((Object)(object)BetaBadge != (Object)null)
{
((Renderer)BetaBadge.GetComponent<MeshRenderer>()).enabled = enabled;
}
if ((Object)(object)LevelBadge != (Object)null)
{
((Renderer)LevelBadge.GetComponent<MeshRenderer>()).enabled = enabled;
}
else if (Settings.DisableModelOverride)
{
Plugin.Debug("Couldn't find the level badge (its fine for the settings)");
}
else
{
Plugin.Logger.LogError((object)"Couldn't find the level badge");
}
}
}
public class SignUI : MonoBehaviour
{
public PlayerControllerB Player;
private TMP_InputField inputField;
private TMP_Text previewText;
private Text charactersLeftText;
private Text submitText;
private Text cancelText;
private Button submitButton;
private Button cancelButton;
public bool IsSignUIOpen;
private void Awake()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Expected O, but got Unknown
Plugin.Debug("SignUI.Awake()");
FindComponents();
Button obj = submitButton;
if (obj != null)
{
ButtonClickedEvent onClick = obj.onClick;
if (onClick != null)
{
((UnityEvent)onClick).AddListener(new UnityAction(SubmitText));
}
}
Button obj2 = cancelButton;
if (obj2 != null)
{
ButtonClickedEvent onClick2 = obj2.onClick;
if (onClick2 != null)
{
((UnityEvent)onClick2).AddListener((UnityAction)delegate
{
Close(cancelAction: true);
});
}
}
TMP_InputField obj3 = inputField;
if (obj3 != null)
{
((UnityEvent<string>)(object)obj3.onValueChanged)?.AddListener((UnityAction<string>)delegate(string fieldText)
{
UpdatePreviewText(fieldText);
UpdateCharactersLeftText();
});
}
}
private void OnEnable()
{
Plugin.Debug("SignUI.OnEnable()");
Player.isTypingChat = true;
IsSignUIOpen = true;
if ((Object)(object)inputField != (Object)null)
{
((Selectable)inputField).Select();
inputField.text = string.Empty;
}
if ((Object)(object)previewText != (Object)null)
{
previewText.text = "PREVIEW";
}
updateKeybindText();
Player.disableLookInput = true;
}
public void updateKeybindText()
{
Plugin.Debug("SignUI.updateKeybindText()");
InputBind displayStrings = Keybinds.getDisplayStrings(Settings.Keybinds.SignSubmit);
InputBind displayStrings2 = Keybinds.getDisplayStrings(Settings.Keybinds.SignCancel);
if ((Object)(object)submitText != (Object)null)
{
submitText.text = "<color=orange>" + Keybinds.formatInputBind(displayStrings) + "</color> Submit";
}
if ((Object)(object)cancelText != (Object)null)
{
cancelText.text = "<color=orange>" + Keybinds.formatInputBind(displayStrings2) + "</color> Cancel";
}
}
private void Update()
{
Plugin.Trace("SignUI.Update()");
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)2;
if (!Player.performingEmote)
{
Plugin.Debug("SignUI Player isnt performing emote");
Close(cancelAction: true);
}
if (Player.quickMenuManager.isMenuOpen || EmoteKeybindPatch.EmoteWheelIsOpened)
{
Plugin.Debug("Menu is open or right mouse button is clicked");
Close(cancelAction: true);
}
}
private void FindComponents()
{
Plugin.Debug("SignUI.FindComponents()");
try
{
Transform obj = ((Component)this).transform.Find("InputField");
inputField = ((obj != null) ? ((Component)obj).GetComponent<TMP_InputField>() : null);
Transform obj2 = ((Component)this).transform.Find("CharsLeft");
charactersLeftText = ((obj2 != null) ? ((Component)obj2).GetComponent<Text>() : null);
Transform obj3 = ((Component)this).transform.Find("Submit");
submitButton = ((obj3 != null) ? ((Component)obj3).GetComponent<Button>() : null);
Transform obj4 = ((Component)this).transform.Find("Cancel");
cancelButton = ((obj4 != null) ? ((Component)obj4).GetComponent<Button>() : null);
Transform obj5 = ((Component)this).transform.Find("Sign");
object obj6;
if (obj5 == null)
{
obj6 = null;
}
else
{
Transform transform = ((Component)obj5).transform;
if (transform == null)
{
obj6 = null;
}
else
{
Transform obj7 = transform.Find("Text");
obj6 = ((obj7 != null) ? ((Component)obj7).GetComponent<TMP_Text>() : null);
}
}
previewText = (TMP_Text)obj6;
Transform obj8 = ((Component)this).transform.Find("Submit");
object obj9;
if (obj8 == null)
{
obj9 = null;
}
else
{
Transform transform2 = ((Component)obj8).transform;
if (transform2 == null)
{
obj9 = null;
}
else
{
Transform obj10 = transform2.Find("Text");
obj9 = ((obj10 != null) ? ((Component)obj10).GetComponent<Text>() : null);
}
}
submitText = (Text)obj9;
Transform obj11 = ((Component)this).transform.Find("Cancel");
object obj12;
if (obj11 == null)
{
obj12 = null;
}
else
{
Transform transform3 = ((Component)obj11).transform;
if (transform3 == null)
{
obj12 = null;
}
else
{
Transform obj13 = transform3.Find("Text");
obj12 = ((obj13 != null) ? ((Component)obj13).GetComponent<Text>() : null);
}
}
cancelText = (Text)obj12;
}
catch (Exception arg)
{
Plugin.Debug($"Unable to find components for sign UI {arg}");
}
}
private void UpdateCharactersLeftText()
{
Plugin.Debug("SignUI.UpdateCharactersLeftText()");
if ((Object)(object)charactersLeftText != (Object)null)
{
Text obj = charactersLeftText;
TMP_InputField obj2 = inputField;
int num = ((obj2 != null) ? obj2.characterLimit : 0);
TMP_InputField obj3 = inputField;
obj.text = $"CHARACTERS LEFT: <color=yellow>{num - ((obj3 == null) ? null : obj3.text?.Length).GetValueOrDefault()}</color>";
}
}
private void UpdatePreviewText(string text)
{
Plugin.Debug("SignUI.UpdatePreviewText(" + text + ")");
if ((Object)(object)previewText != (Object)null)
{
previewText.text = text;
}
}
public void SubmitText()
{
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
Plugin.Debug("SignUI.SubmitText()");
TMP_InputField obj = inputField;
if (((obj == null) ? null : obj.text?.Equals(string.Empty)).GetValueOrDefault(true))
{
Close(cancelAction: true);
return;
}
if ((Object)(object)inputField != (Object)null)
{
Plugin.Debug("Submitted " + inputField.text + " to server");
((Component)Player).GetComponent<SignEmoteText>().UpdateSignText(inputField.text);
}
if (Player.timeSinceStartingEmote > Settings.SignTextCooldown)
{
Plugin.Debug("Time elapsed, time to perform");
Player.PerformEmote(default(CallbackContext), EmoteDefs.getEmoteNumber(AltEmote.Sign_Text));
}
Close(cancelAction: false);
}
public void Close(bool cancelAction)
{
Plugin.Debug($"SignUI.Close({cancelAction})");
Player.isTypingChat = false;
IsSignUIOpen = false;
if (cancelAction)
{
Player.performingEmote = false;
Player.StopPerformingEmoteServerRpc();
}
if (!Player.quickMenuManager.isMenuOpen)
{
Cursor.visible = false;
Cursor.lockState = (CursorLockMode)1;
}
Player.disableLookInput = false;
((Component)this).gameObject.SetActive(false);
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}