Decompiled source of Refined Emotions v1.3.7

BepInEx/plugins/RepoEmoteWheel/RepoEmoteWheel.dll

Decompiled 2 hours ago
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;
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: AssemblyCompany("RepoEmoteWheel")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.3.7.0")]
[assembly: AssemblyInformationalVersion("1.3.7+781a68f838e38df1ae8f979819adde3a857a41d9")]
[assembly: AssemblyProduct("RepoEmoteWheel")]
[assembly: AssemblyTitle("RepoEmoteWheel")]
[assembly: AssemblyVersion("1.3.7.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 RepoEmoteWheel
{
	[DefaultExecutionOrder(-10000)]
	public sealed class ExpressionPose : MonoBehaviour
	{
		private PlayerExpression expression;

		private PlayerAvatarVisuals visuals;

		private Transform left;

		private Transform right;

		private Quaternion leftRotation;

		private Quaternion rightRotation;

		private Vector3 leftPosition;

		private Vector3 rightPosition;

		private Vector3 leftScale;

		private Vector3 rightScale;

		private Vector3 leftPalm;

		private Vector3 rightPalm;

		private readonly float[] weights = new float[7];

		private bool applied;

		private PlayerAvatarRightArm rightControl;

		private static readonly FieldRef<PlayerAvatar, bool> Tumbling = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isTumbling");

		private static readonly FieldRef<PhysGrabber, bool> Grabbing = AccessTools.FieldRefAccess<PhysGrabber, bool>("physGrabBeamActive");

		private static readonly FieldRef<MapToolController, bool> MapActive = AccessTools.FieldRefAccess<MapToolController, bool>("Active");

		private void Awake()
		{
			//IL_00aa: 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)
			//IL_00c5: 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)
			expression = ((Component)this).GetComponent<PlayerExpression>();
			visuals = ((Component)this).GetComponent<PlayerAvatarVisuals>();
			PlayerAvatarLeftArm component = ((Component)this).GetComponent<PlayerAvatarLeftArm>();
			PlayerAvatarRightArm val = (rightControl = ((Component)this).GetComponent<PlayerAvatarRightArm>());
			left = (Object.op_Implicit((Object)(object)component) ? component.leftArmTransform : null);
			right = (Object.op_Implicit((Object)(object)val) ? val.rightArmTransform : null);
			if (!Object.op_Implicit((Object)(object)expression) || !Object.op_Implicit((Object)(object)visuals) || !Object.op_Implicit((Object)(object)left) || !Object.op_Implicit((Object)(object)right))
			{
				((Behaviour)this).enabled = false;
				return;
			}
			leftPalm = PalmOffset(left, "Flashlight Target Client", 0.471f);
			rightPalm = PalmOffset(right, "Grabber Target", 0.5133f);
		}

		private void Update()
		{
			Restore();
		}

		private void LateUpdate()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Invalid comparison between Unknown and I4
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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_0175: 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_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Plugin.Instance) || !Object.op_Implicit((Object)(object)LevelGenerator.Instance) || !LevelGenerator.Instance.Generated || SemiFunc.MenuLevel())
			{
				return;
			}
			PlayerAvatar playerAvatar = expression.playerAvatar;
			if (Object.op_Implicit((Object)(object)playerAvatar) && ((Behaviour)playerAvatar).isActiveAndEnabled && !Tumbling.Invoke(playerAvatar) && (int)visuals.currentPose != 2 && (int)visuals.currentPose != 3 && (!Object.op_Implicit((Object)(object)playerAvatar.physGrabber) || !Grabbing.Invoke(playerAvatar.physGrabber)) && (!Object.op_Implicit((Object)(object)rightControl) || !Object.op_Implicit((Object)(object)rightControl.mapToolController) || !MapActive.Invoke(rightControl.mapToolController)))
			{
				for (int i = 0; i < weights.Length; i++)
				{
					weights[i] = ((i < expression.expressions.Count) ? expression.expressions[i].weight : 0f);
				}
				if (!(PoseWeights.Normalize(weights) < 0.001f))
				{
					leftRotation = left.localRotation;
					rightRotation = right.localRotation;
					leftPosition = left.localPosition;
					rightPosition = right.localPosition;
					leftScale = left.localScale;
					rightScale = right.localScale;
					applied = true;
					ApplyArm(left, leftPalm, -1);
					ApplyArm(right, rightPalm, 1);
				}
			}
		}

		private static Vector3 PalmOffset(Transform arm, string marker, float fallbackLength)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//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)
			Transform[] componentsInChildren = ((Component)arm).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name == marker)
				{
					return arm.InverseTransformPoint(val.position);
				}
			}
			return Vector3.forward * fallbackLength;
		}

		private void ApplyArm(Transform arm, Vector3 palm, int side)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_002c: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00df: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: 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_00ef: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: 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)
			Quaternion rotation = arm.rotation;
			Quaternion val = rotation;
			float num = weights[0];
			float num2 = weights[0];
			Vector3 localScale = arm.localScale;
			MoveShoulder(arm, side);
			Vector3 val2 = arm.TransformVector(new Vector3(palm.x, palm.y, 0f));
			Vector3 val3 = arm.TransformVector(new Vector3(0f, 0f, palm.z));
			for (int i = 1; i <= 6 && i < expression.expressions.Count; i++)
			{
				float num3 = weights[i];
				if (!(num3 < 0.0001f))
				{
					Vector3 val4 = Direction(i, arm, side);
					float num4 = ((i >= 5) ? PoseWeights.ReachScale(((Vector3)(ref val2)).sqrMagnitude, ((Vector3)(ref val3)).sqrMagnitude, Vector3.Dot(val2, val3), ((Vector3)(ref val4)).magnitude) : 1f);
					Vector3 val5 = ((i >= 5) ? (val2 + val3 * num4) : arm.forward);
					Quaternion val6 = ((((Vector3)(ref val4)).sqrMagnitude > 0.0001f) ? (Quaternion.FromToRotation(val5, val4) * rotation) : rotation);
					num += num3;
					val = Quaternion.Slerp(val, val6, num3 / num);
					num2 += num3 * num4;
				}
			}
			arm.rotation = val;
			arm.localScale = new Vector3(localScale.x, localScale.y, localScale.z * num2);
		}

		private void MoveShoulder(Transform arm, int side)
		{
			//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_0037: 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_0056: 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_0060: 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_006a: 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)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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)
			Transform val = (Object.op_Implicit((Object)(object)visuals.bodyTopSideTransform) ? visuals.bodyTopSideTransform : ((Component)visuals).transform);
			Vector3 val2 = val.InverseTransformPoint(arm.position);
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor((0f - val2.x) * 0.3f, 0f, 0.2f);
			Vector3 val4 = val2 + val3 * weights[2];
			val4 += Vector3.forward * (0.18f * weights[6]);
			if (side > 0)
			{
				val4 += Vector3.back * (0.15f * weights[3]);
			}
			arm.position = val.TransformPoint(val4);
		}

		private Vector3 Direction(int index, Transform arm, int side)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0098: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)visuals).transform;
			switch (index)
			{
			case 1:
				return RaisedArmDirection(side, 130f);
			case 2:
				return transform.TransformDirection(new Vector3((float)side * 0.35f, -1f, 0.2f));
			case 3:
				if (side >= 0)
				{
					return RaisedArmDirection(side, 100f, 30f);
				}
				return PointingDirection(arm);
			case 4:
				return transform.TransformDirection(new Vector3((float)(-side) * 0.25f, -0.35f, -1f));
			case 5:
				return HeadTarget((float)side * 0.3f, 0.02f, 0f, top: true) - arm.position;
			case 6:
				return HeadTarget((float)side * 0.1f, -0.01f, 0.3f, top: false) - arm.position;
			default:
				return Vector3.zero;
			}
		}

		private Vector3 PointingDirection(Transform arm)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_003e: 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)
			//IL_004f: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = (Object.op_Implicit((Object)(object)visuals.bodyTopSideTransform) ? visuals.bodyTopSideTransform : ((Component)visuals).transform);
			Vector3 val = obj.InverseTransformPoint(arm.position);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(0f, val.y, 1.5f);
			return obj.TransformPoint(val2) - arm.position;
		}

		private Vector3 RaisedArmDirection(int side, float degreesFromDown, float degreesBack = 10f)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			float num = degreesFromDown * (MathF.PI / 180f);
			float num2 = degreesBack * (MathF.PI / 180f);
			return ((Component)visuals).transform.TransformDirection(new Vector3((float)side * Mathf.Sin(num) * Mathf.Cos(num2), 0f - Mathf.Cos(num), (0f - Mathf.Sin(num)) * Mathf.Sin(num2)));
		}

		private Vector3 HeadTarget(float x, float y, float z, bool top)
		{
			//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_0054: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Transform val = (top ? visuals.attachPointTopHeadMiddle : visuals.attachPointJawBottom);
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = visuals.headSideTransform;
			}
			Vector3 val2 = (Object.op_Implicit((Object)(object)val) ? val : ((Component)visuals).transform).TransformVector(new Vector3(x, y, z));
			return (Object.op_Implicit((Object)(object)val) ? val.position : ((Component)visuals).transform.position) + val2;
		}

		private void Restore()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (applied)
			{
				if (Object.op_Implicit((Object)(object)left))
				{
					left.localRotation = leftRotation;
					left.localPosition = leftPosition;
					left.localScale = leftScale;
				}
				if (Object.op_Implicit((Object)(object)right))
				{
					right.localRotation = rightRotation;
					right.localPosition = rightPosition;
					right.localScale = rightScale;
				}
				applied = false;
			}
		}

		private void OnDisable()
		{
			Restore();
		}

		private void OnDestroy()
		{
			Restore();
		}
	}
	internal sealed class HoldState
	{
		private bool blocked;

		internal bool Active { get; private set; }

		internal void Tick(bool allowed, bool held)
		{
			if (!held)
			{
				blocked = false;
			}
			else if (!allowed)
			{
				blocked = true;
			}
			Active = allowed && held && !blocked;
		}

		internal void Cancel(bool held)
		{
			Active = false;
			blocked = held;
		}
	}
	[BepInPlugin("local.repo.mmbemotewheel", "Refined Emotions", "1.3.7")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Id = "local.repo.mmbemotewheel";

		internal static Plugin Instance;

		internal readonly WheelState State = new WheelState();

		internal const float Duration = 5f;

		private ConfigEntry<string> button;

		private KeyCode buttonCode = (KeyCode)325;

		private ConfigEntry<string> selfViewButton;

		private KeyCode selfViewCode = (KeyCode)118;

		private RuntimeHost runtime;

		private Harmony harmony;

		private Vector2 pointer;

		private bool heldLast;

		private bool updateReported;

		private string lastBlockReason;

		private float nextDiagnostic;

		private int closedFrame = -1;

		private WheelView view;

		private static readonly FieldRef<MenuManager, MenuPage> MenuPage = AccessTools.FieldRefAccess<MenuManager, MenuPage>("currentMenuPage");

		private static readonly FieldRef<PlayerAvatar, bool> Disabled = AccessTools.FieldRefAccess<PlayerAvatar, bool>("isDisabled");

		private static readonly FieldRef<PlayerExpression, bool> LocalExpression = AccessTools.FieldRefAccess<PlayerExpression, bool>("isLocal");

		private SelfView selfView => runtime?.SelfView;

		internal bool SelfViewHeld => Input.GetKey(selfViewCode);

		private float Scale => Mathf.Min((float)Screen.width / 1000f, (float)Screen.height / 800f);

		private bool Held => Input.GetKey(buttonCode);

		internal bool BlockLook
		{
			get
			{
				if (!State.IsOpen && closedFrame != Time.frameCount && (!Object.op_Implicit((Object)(object)selfView) || !selfView.Active))
				{
					if (Held)
					{
						return Allowed();
					}
					return false;
				}
				return true;
			}
		}

		private void Awake()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Expected O, but got Unknown
			Instance = this;
			button = ((BaseUnityPlugin)this).Config.Bind<string>("Emote wheel", "Button", "Mouse2", new ConfigDescription("Hold to open the wheel, release to emote. Mouse2 is middle mouse.", (AcceptableValueBase)(object)new AcceptableValueList<string>(WheelBinding.Buttons), Array.Empty<object>()));
			ReadButton();
			button.SettingChanged += ButtonChanged;
			selfViewButton = ((BaseUnityPlugin)this).Config.Bind<string>("Emote wheel", "Self-view", "V", new ConfigDescription("Hold to look at yourself from the front. Release to return to first person.", (AcceptableValueBase)(object)new AcceptableValueList<string>(WheelBinding.Buttons), Array.Empty<object>()));
			ReadSelfViewButton();
			selfViewButton.SettingChanged += SelfViewButtonChanged;
			harmony = new Harmony("local.repo.mmbemotewheel");
			harmony.PatchAll(typeof(Plugin));
			runtime = new RuntimeHost(this);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Refined Emotions initialized; waiting for scene runtime. Hold " + ((object)Unsafe.As<KeyCode, KeyCode>(ref buttonCode)/*cast due to .constrained prefix*/).ToString() + ", point, release. Duration: " + 5f + "s."));
		}

		private void ReadButton()
		{
			//IL_0026: 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)
			if (!Enum.TryParse<KeyCode>(button.Value, out buttonCode) || (int)buttonCode == 0)
			{
				buttonCode = (KeyCode)325;
			}
		}

		private void ReadSelfViewButton()
		{
			//IL_0023: 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)
			if (!Enum.TryParse<KeyCode>(selfViewButton.Value, out selfViewCode) || (int)selfViewCode == 0)
			{
				selfViewCode = (KeyCode)118;
			}
		}

		private void SelfViewButtonChanged(object sender, EventArgs args)
		{
			ReadSelfViewButton();
			selfView?.Cancel();
		}

		internal void ReportSelfView(bool active)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Self-view " + (active ? "started" : "ended") + "."));
		}

		private void ButtonChanged(object sender, EventArgs args)
		{
			ReadButton();
			heldLast = Held;
			State.Tick(Time.unscaledTime, allowed: false, heldLast, cancel: false, 0.0, 0.0, 55.0, 5.0);
			closedFrame = Time.frameCount;
		}

		[HarmonyPatch(typeof(PlayerExpression), "Start")]
		[HarmonyPostfix]
		private static void AddPoses(PlayerExpression __instance)
		{
			if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<ExpressionPose>()))
			{
				((Component)__instance).gameObject.AddComponent<ExpressionPose>();
			}
		}

		internal bool Allowed()
		{
			return BlockReason() == null;
		}

		private string BlockReason()
		{
			if (!Application.isFocused)
			{
				return "window not focused";
			}
			if (!Object.op_Implicit((Object)(object)PlayerAvatar.instance))
			{
				return "no local avatar";
			}
			if (!Object.op_Implicit((Object)(object)PlayerAvatar.instance.playerExpression))
			{
				return "no expression component";
			}
			if (Disabled.Invoke(PlayerAvatar.instance))
			{
				return "avatar disabled/dead";
			}
			if (!Object.op_Implicit((Object)(object)LevelGenerator.Instance) || !LevelGenerator.Instance.Generated)
			{
				return "level loading";
			}
			if (!Object.op_Implicit((Object)(object)GameDirector.instance))
			{
				return "no game director";
			}
			if (GameDirector.instance.DisableInput)
			{
				return "game input disabled";
			}
			if (!Object.op_Implicit((Object)(object)MenuManager.instance))
			{
				return "no menu manager";
			}
			if (Object.op_Implicit((Object)(object)MenuPage.Invoke(MenuManager.instance)))
			{
				return "menu open: " + ((Object)MenuPage.Invoke(MenuManager.instance)).name;
			}
			if (SemiFunc.MenuLevel())
			{
				return "menu level";
			}
			if (Object.op_Implicit((Object)(object)ChatManager.instance) && !ChatManager.instance.StateIsInactive())
			{
				return "chat active";
			}
			return null;
		}

		internal void Tick()
		{
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: 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_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			if (!updateReported)
			{
				updateReported = true;
				ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
				Mouse current = Mouse.current;
				logger.LogInfo((object)("Wheel Update running; mouse=" + (((current != null) ? ((InputControl)current).displayName : null) ?? "none")));
				foreach (MethodBase patchedMethod in harmony.GetPatchedMethods())
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Patched: " + patchedMethod.DeclaringType.Name + "." + patchedMethod.Name));
				}
			}
			if (Time.unscaledTime >= nextDiagnostic)
			{
				nextDiagnostic = Time.unscaledTime + 1f;
				string text = BlockReason() ?? "ready";
				if (text != lastBlockReason)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Wheel state: " + text));
					lastBlockReason = text;
				}
			}
			bool held = Held;
			if (held != heldLast)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)(((object)Unsafe.As<KeyCode, KeyCode>(ref buttonCode)/*cast due to .constrained prefix*/).ToString() + " " + (held ? "down" : "up") + "; " + (BlockReason() ?? "ready")));
			}
			if (held && !heldLast)
			{
				pointer = Vector2.zero;
			}
			else if (State.IsOpen && Mouse.current != null)
			{
				Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).delta).ReadValue();
				pointer += new Vector2(val.x, 0f - val.y) / Mathf.Max(Scale, 0.1f);
				pointer = Vector2.ClampMagnitude(pointer, 172f);
			}
			bool cancel = Keyboard.current != null && ((ButtonControl)Keyboard.current.escapeKey).wasPressedThisFrame;
			bool isOpen = State.IsOpen;
			int active = State.Active;
			State.Tick(Time.unscaledTime, Allowed(), held, cancel, pointer.x, pointer.y, 55.0, 5.0);
			heldLast = held;
			if (isOpen && !State.IsOpen)
			{
				closedFrame = Time.frameCount;
			}
			if (active == State.Active)
			{
				return;
			}
			if (State.Active >= 0)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"Expression {State.Active + 1} ({Name(State.Active)}) started; {5f:0.0}s.");
				if (Object.op_Implicit((Object)(object)PlayerExpressionsUI.instance))
				{
					PlayerExpressionsUI.instance.ShrinkReset();
				}
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Wheel expression ended.");
			}
		}

		internal void Render()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (view == null && State.IsOpen)
			{
				view = new WheelView();
			}
			view?.Render(State, pointer, Scale, Allowed());
		}

		private string Name(int index)
		{
			PlayerExpression val = (Object.op_Implicit((Object)(object)PlayerAvatar.instance) ? PlayerAvatar.instance.playerExpression : null);
			if (Object.op_Implicit((Object)(object)val) && val.expressions.Count > index + 1)
			{
				return val.expressions[index + 1].expressionName;
			}
			return "Expression " + (index + 1);
		}

		[HarmonyPatch(typeof(InputManager), "GetMouseX")]
		[HarmonyPrefix]
		private static bool MouseX(ref float __result)
		{
			return FilterMouse(ref __result);
		}

		[HarmonyPatch(typeof(InputManager), "GetMouseY")]
		[HarmonyPrefix]
		private static bool MouseY(ref float __result)
		{
			return FilterMouse(ref __result);
		}

		private static bool FilterMouse(ref float result)
		{
			if (!Object.op_Implicit((Object)(object)Instance) || !Instance.BlockLook)
			{
				return true;
			}
			result = 0f;
			return false;
		}

		[HarmonyPatch(typeof(PlayerExpression), "Update")]
		[HarmonyPrefix]
		private static void ApplyExpression(PlayerExpression __instance)
		{
			if (Object.op_Implicit((Object)(object)Instance) && Instance.State.Active >= 0 && Instance.Allowed() && !((double)Time.unscaledTime >= Instance.State.EndsAt) && LocalExpression.Invoke(__instance))
			{
				int num = Instance.State.Active + 1;
				if (__instance.expressions.Count > num)
				{
					__instance.OverrideExpressionSet(num, 100f);
				}
			}
		}

		internal void CancelWheel()
		{
			State.Tick(Time.unscaledTime, allowed: false, Held, cancel: false, 0.0, 0.0, 55.0, 5.0);
		}

		private void OnDestroy()
		{
			if (button != null)
			{
				button.SettingChanged -= ButtonChanged;
			}
			if (selfViewButton != null)
			{
				selfViewButton.SettingChanged -= SelfViewButtonChanged;
			}
			runtime?.Dispose();
			ExpressionPose[] array = Object.FindObjectsOfType<ExpressionPose>();
			for (int i = 0; i < array.Length; i++)
			{
				Object.Destroy((Object)(object)array[i]);
			}
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			view?.Dispose();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	internal static class PoseWeights
	{
		internal static float Normalize(float[] weights)
		{
			float num = 0f;
			for (int i = 0; i < weights.Length; i++)
			{
				num += (weights[i] = Math.Max(0f, weights[i]));
			}
			if (num < 0.0001f)
			{
				return 0f;
			}
			for (int j = 0; j < weights.Length; j++)
			{
				weights[j] /= num;
			}
			return 1f - weights[0];
		}

		internal static float ReachScale(float sidewaysSquared, float forwardSquared, float dot, float targetLength)
		{
			if (forwardSquared < 1E-06f)
			{
				return 1f;
			}
			double val = dot * dot + forwardSquared * (targetLength * targetLength - sidewaysSquared);
			return Math.Max(0.01f, (float)(((double)(0f - dot) + Math.Sqrt(Math.Max(0.0, val))) / (double)forwardSquared));
		}
	}
	internal sealed class RuntimeHost : IDisposable
	{
		private readonly Plugin owner;

		private GameObject root;

		private bool disposed;

		internal SelfView SelfView { get; private set; }

		internal RuntimeHost(Plugin owner)
		{
			this.owner = owner;
			SceneManager.sceneLoaded += SceneLoaded;
		}

		private void SceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			if (!disposed && !Object.op_Implicit((Object)(object)root) && Object.op_Implicit((Object)(object)owner))
			{
				root = new GameObject("Refined Emotions Runtime");
				Object.DontDestroyOnLoad((Object)(object)root);
				root.AddComponent<WheelRuntime>().Owner = owner;
				SelfView = root.AddComponent<SelfView>();
			}
		}

		public void Dispose()
		{
			if (!disposed)
			{
				disposed = true;
				SceneManager.sceneLoaded -= SceneLoaded;
				if (Object.op_Implicit((Object)(object)SelfView))
				{
					SelfView.Cancel();
				}
				if (Object.op_Implicit((Object)(object)root))
				{
					root.SetActive(false);
					Object.Destroy((Object)(object)root);
				}
				root = null;
				SelfView = null;
			}
		}
	}
	public sealed class WheelRuntime : MonoBehaviour
	{
		internal Plugin Owner;

		private void Update()
		{
			if (Object.op_Implicit((Object)(object)Owner))
			{
				Owner.Tick();
			}
		}

		private void LateUpdate()
		{
			if (Object.op_Implicit((Object)(object)Owner))
			{
				Owner.Render();
			}
		}

		private void OnApplicationFocus(bool focused)
		{
			if (!focused && Object.op_Implicit((Object)(object)Owner))
			{
				Owner.CancelWheel();
			}
		}

		private void OnDisable()
		{
			if (Object.op_Implicit((Object)(object)Owner))
			{
				Owner.CancelWheel();
			}
		}
	}
	[DefaultExecutionOrder(-11000)]
	public sealed class SelfView : MonoBehaviour
	{
		private readonly HoldState hold = new HoldState();

		private Transform cameraTransform;

		private Vector3 savedPosition;

		private Quaternion savedRotation;

		private bool applied;

		private PlayerAvatar avatar;

		private static readonly FieldRef<CameraPosition, bool> PositionOverridden = AccessTools.FieldRefAccess<CameraPosition, bool>("overridePositionActive");

		internal bool Active => hold.Active;

		private static bool NativeCameraOverride
		{
			get
			{
				if (Object.op_Implicit((Object)(object)CameraPosition.instance))
				{
					return PositionOverridden.Invoke(CameraPosition.instance);
				}
				return false;
			}
		}

		private void Update()
		{
			RestoreCamera();
			Plugin instance = Plugin.Instance;
			bool active = Active;
			hold.Tick(Object.op_Implicit((Object)(object)instance) && instance.Allowed() && !NativeCameraOverride && Object.op_Implicit((Object)(object)PlayerAvatar.instance.playerAvatarVisuals) && Object.op_Implicit((Object)(object)CameraUtils.Instance) && Object.op_Implicit((Object)(object)CameraUtils.Instance.MainCamera), Object.op_Implicit((Object)(object)instance) && instance.SelfViewHeld);
			if (!Active)
			{
				ReleaseAvatar();
				if (active)
				{
					instance?.ReportSelfView(active: false);
				}
				return;
			}
			if ((Object)(object)avatar != (Object)(object)PlayerAvatar.instance)
			{
				ReleaseAvatar();
				avatar = PlayerAvatar.instance;
			}
			avatar.playerAvatarVisuals.ShowSelfOverride(Mathf.Max(0.1f, Time.deltaTime * 2f));
			PhysGrabber physGrabber = avatar.physGrabber;
			if (physGrabber != null)
			{
				physGrabber.SetThirdPerson(true);
			}
			FlashlightController flashlightController = avatar.flashlightController;
			if (flashlightController != null)
			{
				flashlightController.SetThirdPerson(true);
			}
			if (!active)
			{
				instance.ReportSelfView(active: true);
			}
		}

		private void LateUpdate()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: 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_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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: 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_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			Plugin instance = Plugin.Instance;
			if (!Active)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)instance) || !instance.Allowed() || NativeCameraOverride || !Object.op_Implicit((Object)(object)avatar) || !Object.op_Implicit((Object)(object)avatar.playerAvatarVisuals) || !Object.op_Implicit((Object)(object)CameraUtils.Instance) || !Object.op_Implicit((Object)(object)CameraUtils.Instance.MainCamera))
			{
				Cancel();
				return;
			}
			PlayerAvatarVisuals playerAvatarVisuals = avatar.playerAvatarVisuals;
			Vector3 val = Vector3.ProjectOnPlane(((Component)playerAvatarVisuals).transform.forward, Vector3.up);
			Vector3 val2 = ((Vector3)(ref val)).normalized;
			if (((Vector3)(ref val2)).sqrMagnitude < 0.01f)
			{
				val2 = ((Component)avatar).transform.forward;
			}
			Vector3 val3 = playerAvatarVisuals.headLookAtTransform.position - Vector3.up * 0.35f;
			Vector3 val4 = val2 * 3f + Vector3.up * 0.15f;
			float num = ((Vector3)(ref val4)).magnitude;
			Vector3 val5 = val4 / num;
			int num2 = LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()) & ~LayerMask.GetMask(new string[1] { "Player" });
			RaycastHit val6 = default(RaycastHit);
			if (Physics.SphereCast(val3, 0.18f, val5, ref val6, num, num2, (QueryTriggerInteraction)1))
			{
				num = Mathf.Max(0.05f, ((RaycastHit)(ref val6)).distance - 0.05f);
			}
			cameraTransform = ((Component)CameraUtils.Instance.MainCamera).transform;
			savedPosition = cameraTransform.localPosition;
			savedRotation = cameraTransform.localRotation;
			applied = true;
			Vector3 val7 = val3 + val5 * num;
			cameraTransform.SetPositionAndRotation(val7, Quaternion.LookRotation(val3 - val7, Vector3.up));
		}

		private void RestoreCamera()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (applied)
			{
				if (Object.op_Implicit((Object)(object)cameraTransform))
				{
					cameraTransform.localPosition = savedPosition;
					cameraTransform.localRotation = savedRotation;
				}
				applied = false;
			}
		}

		private void ReleaseAvatar()
		{
			if (!Object.op_Implicit((Object)(object)avatar))
			{
				return;
			}
			if (!NativeCameraOverride)
			{
				if (Object.op_Implicit((Object)(object)avatar.playerAvatarVisuals))
				{
					avatar.playerAvatarVisuals.ShowSelfOverride(0f);
				}
				PhysGrabber physGrabber = avatar.physGrabber;
				if (physGrabber != null)
				{
					physGrabber.SetThirdPerson(false);
				}
				FlashlightController flashlightController = avatar.flashlightController;
				if (flashlightController != null)
				{
					flashlightController.SetThirdPerson(false);
				}
			}
			avatar = null;
		}

		internal void Cancel()
		{
			bool active = Active;
			hold.Cancel(Object.op_Implicit((Object)(object)Plugin.Instance) && Plugin.Instance.SelfViewHeld);
			RestoreCamera();
			ReleaseAvatar();
			if (active && Object.op_Implicit((Object)(object)Plugin.Instance))
			{
				Plugin.Instance.ReportSelfView(active: false);
			}
		}

		private void OnApplicationFocus(bool focused)
		{
			if (!focused)
			{
				Cancel();
			}
		}

		private void OnDisable()
		{
			Cancel();
		}

		private void OnDestroy()
		{
			Cancel();
		}
	}
	internal static class WheelArt
	{
		internal struct EyePose
		{
			public float UpperAngle;

			public float UpperClosed;

			public float LowerAngle;

			public float LowerClosed;

			public float Pupil;

			public float OffsetX;

			public float OffsetY;
		}

		internal static byte[] Eyes(EyePose left, EyePose right, int width = 160, int height = 80)
		{
			byte[] array = new byte[width * height * 4];
			for (int i = 0; i < height; i++)
			{
				for (int j = 0; j < width; j++)
				{
					double num = ((j < width / 2) ? ((double)width * 0.29) : ((double)width * 0.71));
					EyePose eyePose = ((j < width / 2) ? left : right);
					double num2 = ((double)j + 0.5 - num) / ((double)width * 0.19);
					double num3 = ((double)i + 0.5 - (double)height * 0.5) / ((double)height * 0.39);
					double num4 = num2 * num2 + num3 * num3;
					if (num4 > 1.13)
					{
						continue;
					}
					int i2 = (i * width + j) * 4;
					if (num4 > 1.0)
					{
						Put(array, i2, 12, 12, 10, 240);
						continue;
					}
					double num5 = Math.Cos((double)eyePose.UpperClosed * Math.PI / 180.0);
					double num6 = 0.0 - Math.Cos((double)eyePose.LowerClosed * Math.PI / 180.0);
					double num7 = num3 - Math.Tan((double)eyePose.UpperAngle * Math.PI / 180.0) * num2;
					double num8 = num3 - Math.Tan((double)eyePose.LowerAngle * Math.PI / 180.0) * num2;
					if (!(num7 <= num5) || !(num8 >= num6))
					{
						double num9 = 0.8 + 0.2 * (num3 + 1.0) / 2.0;
						Put(array, i2, (byte)(64.0 * num9), (byte)(62.0 * num9), (byte)(53.0 * num9), 245);
						if (num5 < 0.0 && num6 > 0.0 && Math.Abs(num3) < 0.04 && Math.Abs(num2) < 0.88)
						{
							Put(array, i2, 184, 180, 157, byte.MaxValue);
						}
						continue;
					}
					double num10 = Math.Max(0.68, 1.0 - 0.14 * (num2 * num2 + (num3 - 0.35) * (num3 - 0.35)));
					Put(array, i2, (byte)(243.0 * num10), (byte)(240.0 * num10), (byte)(217.0 * num10), byte.MaxValue);
					double num11 = num2 - Math.Sin((double)eyePose.OffsetY * Math.PI / 180.0) * 0.7;
					double num12 = num3 + Math.Sin((double)eyePose.OffsetX * Math.PI / 180.0) * 0.7;
					double num13 = Math.Max(0.075, Math.Min(0.62, (double)eyePose.Pupil * 0.3));
					if (num11 * num11 + num12 * num12 < num13 * num13)
					{
						Put(array, i2, 13, 14, 12, byte.MaxValue);
					}
				}
			}
			return array;
		}

		internal static byte[] Ring(bool highlight, int size = 384)
		{
			byte[] array = new byte[size * size * 4];
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					double num = ((double)j + 0.5 - (double)size / 2.0) / ((double)size / 2.0);
					double num2 = ((double)i + 0.5 - (double)size / 2.0) / ((double)size / 2.0);
					double num3 = Math.Sqrt(num * num + num2 * num2);
					double num4 = Math.Atan2(num, num2);
					double num5 = (num4 + Math.PI * 2.0 + Math.PI / 6.0) % (Math.PI / 3.0);
					if (num3 < 0.31 || num3 > 0.99 || num5 < 0.018 || num5 > 1.0291975511965976 || (highlight && Math.Abs(num4) > 0.5055987755982988))
					{
						continue;
					}
					int i2 = (i * size + j) * 4;
					if (highlight)
					{
						if (num3 > 0.967)
						{
							Put(array, i2, 214, 178, 77, 240);
						}
						else
						{
							Put(array, i2, 150, 128, 67, 55);
						}
					}
					else if (num3 > 0.98 || num3 < 0.322)
					{
						Put(array, i2, 160, 155, 133, 60);
					}
					else
					{
						Put(array, i2, 13, 14, 12, 175);
					}
				}
			}
			return array;
		}

		internal static byte[] Pointer(int size = 20)
		{
			byte[] array = new byte[size * size * 4];
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					int num = size - 1 - i;
					if (j >= 2 && num >= 2 && !((double)j > (double)num * 0.72 + 2.0) && num <= size - 3)
					{
						Put(array, (i * size + j) * 4, 232, 188, 66, byte.MaxValue);
					}
				}
			}
			return array;
		}

		private static void Put(byte[] p, int i, byte r, byte g, byte b, byte a)
		{
			p[i] = r;
			p[i + 1] = g;
			p[i + 2] = b;
			p[i + 3] = a;
		}
	}
	internal static class WheelBinding
	{
		internal static readonly string[] Buttons = (from name in Enum.GetNames(typeof(KeyCode))
			where name != "None" && name != "Escape" && !name.StartsWith("Joystick", StringComparison.Ordinal)
			select name).ToArray();
	}
	public sealed class WheelState
	{
		public const int Count = 6;

		private bool wasHeld;

		public bool IsOpen { get; private set; }

		public int Hovered { get; private set; } = -1;

		public int Active { get; private set; } = -1;

		public double EndsAt { get; private set; }

		public static int Sector(double x, double y, double deadZone)
		{
			if (x * x + y * y < deadZone * deadZone)
			{
				return -1;
			}
			double num = Math.Atan2(x, 0.0 - y) + Math.PI / 6.0;
			if (num < 0.0)
			{
				num += Math.PI * 2.0;
			}
			return (int)(num / (Math.PI / 3.0)) % 6;
		}

		public void Tick(double now, bool allowed, bool held, bool cancel, double x, double y, double deadZone, double duration)
		{
			if (Active >= 0 && now >= EndsAt)
			{
				Active = -1;
			}
			if (!allowed || cancel)
			{
				IsOpen = false;
				Hovered = -1;
				Active = -1;
				wasHeld = held;
				return;
			}
			if (held && !wasHeld)
			{
				IsOpen = true;
				Active = -1;
			}
			if (IsOpen)
			{
				Hovered = Sector(x, y, deadZone);
				if (!held)
				{
					Active = Hovered;
					EndsAt = now + duration;
					IsOpen = false;
				}
			}
			wasHeld = held;
		}
	}
	internal sealed class WheelView : IDisposable
	{
		private readonly GameObject root;

		private readonly Canvas canvas;

		private readonly CanvasGroup group;

		private readonly CanvasGroup wheelGroup;

		private readonly RectTransform wheel;

		private readonly RawImage selection;

		private readonly RawImage cursor;

		private readonly RawImage[] eyes = (RawImage[])(object)new RawImage[6];

		private readonly float[] hover = new float[6];

		private readonly Texture2D[] portraits = (Texture2D[])(object)new Texture2D[6];

		private readonly Texture2D background;

		private readonly Texture2D highlight;

		private readonly Texture2D pointerTexture;

		private readonly Image cancelA;

		private readonly Image cancelB;

		private PlayerExpression source;

		private float visible;

		private int lastSelected = -1;

		internal WheelView()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: 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)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: 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_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			root = new GameObject("Refined Emotions UI", new Type[3]
			{
				typeof(RectTransform),
				typeof(Canvas),
				typeof(CanvasGroup)
			});
			Object.DontDestroyOnLoad((Object)(object)root);
			canvas = root.GetComponent<Canvas>();
			canvas.renderMode = (RenderMode)0;
			canvas.sortingOrder = 32000;
			group = root.GetComponent<CanvasGroup>();
			group.blocksRaycasts = false;
			group.interactable = false;
			wheel = Rect("Wheel", root.transform, Vector2.zero, new Vector2(360f, 360f));
			wheelGroup = ((Component)wheel).gameObject.AddComponent<CanvasGroup>();
			background = Texture(WheelArt.Ring(highlight: false), 384, 384, "Wheel background");
			highlight = Texture(WheelArt.Ring(highlight: true), 384, 384, "Wheel selection");
			pointerTexture = Texture(WheelArt.Pointer(), 20, 20, "Wheel pointer");
			Image("Background", (Transform)(object)wheel, Vector2.zero, new Vector2(360f, 360f), (Texture)(object)background);
			selection = Image("Selection", (Transform)(object)wheel, Vector2.zero, new Vector2(360f, 360f), (Texture)(object)highlight);
			for (int i = 0; i < eyes.Length; i++)
			{
				float num = (float)i * MathF.PI / 3f;
				eyes[i] = Image("Expression " + (i + 1), (Transform)(object)wheel, new Vector2(Mathf.Sin(num) * 122f, Mathf.Cos(num) * 122f), new Vector2(94f, 47f), null);
			}
			cancelA = Line("Cancel A", (Transform)(object)wheel, Vector2.zero, new Vector2(12f, 1.5f), 45f);
			cancelB = Line("Cancel B", (Transform)(object)wheel, Vector2.zero, new Vector2(12f, 1.5f), -45f);
			cursor = Image("Pointer", (Transform)(object)wheel, Vector2.zero, new Vector2(15f, 15f), (Texture)(object)pointerTexture);
			((Graphic)cursor).rectTransform.pivot = new Vector2(0.1f, 0.9f);
			group.alpha = 0f;
		}

		internal void Render(WheelState state, Vector2 pointer, float scale, bool allowed)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: 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)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			canvas.scaleFactor = Mathf.Max(0.1f, scale);
			float num = Mathf.Min(Time.unscaledDeltaTime, 0.05f);
			bool flag = state.IsOpen && allowed;
			visible = Mathf.MoveTowards(visible, (float)(flag ? 1 : 0), num * (float)(flag ? 9 : 14));
			if (flag && Object.op_Implicit((Object)(object)PlayerAvatar.instance))
			{
				PrepareEyes(PlayerAvatar.instance.playerExpression);
			}
			((Component)wheel).gameObject.SetActive(visible > 0f);
			group.alpha = 1f;
			wheelGroup.alpha = visible;
			((Transform)wheel).localScale = Vector3.one * Mathf.Lerp(0.94f, 1f, 1f - (1f - visible) * (1f - visible));
			if (flag)
			{
				lastSelected = state.Hovered;
			}
			((Behaviour)selection).enabled = lastSelected >= 0;
			((Transform)((Graphic)selection).rectTransform).localRotation = Quaternion.Euler(0f, 0f, (float)(-lastSelected * 60));
			for (int i = 0; i < eyes.Length; i++)
			{
				hover[i] = Mathf.Lerp(hover[i], (float)((flag && state.Hovered == i) ? 1 : 0), 1f - Mathf.Exp((0f - num) * 20f));
				((Transform)((Graphic)eyes[i]).rectTransform).localScale = Vector3.one * Mathf.Lerp(1f, 1.13f, hover[i]);
				((Graphic)eyes[i]).color = Color.Lerp(new Color(0.83f, 0.83f, 0.79f, 1f), Color.white, hover[i]);
			}
			Color val = default(Color);
			((Color)(ref val))..ctor(0.8f, 0.78f, 0.67f, (state.Hovered < 0) ? 0.7f : 0.22f);
			Image obj = cancelA;
			Color color = (((Graphic)cancelB).color = val);
			((Graphic)obj).color = color;
			((Graphic)cursor).rectTransform.anchoredPosition = new Vector2(pointer.x, 0f - pointer.y);
			((Behaviour)canvas).enabled = visible > 0f;
		}

		private void PrepareEyes(PlayerExpression expression)
		{
			if (!Object.op_Implicit((Object)(object)expression) || (Object)(object)source == (Object)(object)expression)
			{
				return;
			}
			source = expression;
			for (int i = 0; i < eyes.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)portraits[i]))
				{
					Object.Destroy((Object)(object)portraits[i]);
				}
				if (expression.expressions.Count > i + 1)
				{
					ExpressionSettings val = expression.expressions[i + 1];
					portraits[i] = Texture(WheelArt.Eyes(Pose(val.leftEye), Pose(val.rightEye)), 160, 80, "Eyes: " + val.expressionName);
					eyes[i].texture = (Texture)(object)portraits[i];
				}
			}
		}

		private static WheelArt.EyePose Pose(EyeSettings eye)
		{
			return new WheelArt.EyePose
			{
				UpperAngle = eye.upperLidAngle,
				UpperClosed = eye.upperLidClosedPercent,
				LowerAngle = eye.lowerLidAngle,
				LowerClosed = eye.lowerLidClosedPercent,
				Pupil = eye.pupilSize,
				OffsetX = eye.pupilOffsetRotationX,
				OffsetY = eye.pupilOffsetRotationY
			};
		}

		private static Texture2D Texture(byte[] pixels, int width, int height, string name)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_0017: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			Texture2D val = new Texture2D(width, height, (TextureFormat)4, false)
			{
				name = name,
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)1
			};
			val.LoadRawTextureData(pixels);
			val.Apply(false, true);
			return val;
		}

		private static RectTransform Rect(string name, Transform parent, Vector2 position, Vector2 size)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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)
			RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>();
			((Transform)component).SetParent(parent, false);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			component.anchorMax = val;
			component.anchorMin = val;
			component.anchoredPosition = position;
			component.sizeDelta = size;
			return component;
		}

		private static RawImage Image(string name, Transform parent, Vector2 position, Vector2 size, Texture texture)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			RawImage obj = ((Component)Rect(name, parent, position, size)).gameObject.AddComponent<RawImage>();
			obj.texture = texture;
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private static Image Line(string name, Transform parent, Vector2 position, Vector2 size, float angle)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = Rect(name, parent, position, size);
			((Transform)obj).localRotation = Quaternion.Euler(0f, 0f, angle);
			Image obj2 = ((Component)obj).gameObject.AddComponent<Image>();
			((Graphic)obj2).raycastTarget = false;
			return obj2;
		}

		public void Dispose()
		{
			Object.Destroy((Object)(object)root);
			Object.Destroy((Object)(object)background);
			Object.Destroy((Object)(object)highlight);
			Object.Destroy((Object)(object)pointerTexture);
			Texture2D[] array = portraits;
			foreach (Texture2D val in array)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}
	}
}