Decompiled source of NativeController v0.4.0

NativeController.dll

Decompiled 6 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MenuLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.LowLevel;
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("NativeController")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.4.0.0")]
[assembly: AssemblyInformationalVersion("0.4.0+b75637d02e1cce8289824b0174baeb5321858c01")]
[assembly: AssemblyProduct("NativeController")]
[assembly: AssemblyTitle("NativeController")]
[assembly: AssemblyVersion("0.4.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NativeController
{
	internal class AimAssist : MonoBehaviour
	{
		internal static bool HasTarget;

		internal static Vector3 TargetPosition;

		private const float CastRadius = 0.4f;

		private const float LosMargin = 0.5f;

		private const float AcquireFraction = 0.6f;

		private const float SwitchMarginDeg = 4f;

		private const float MinDwellSeconds = 0.15f;

		private const float PointSmoothTime = 0.08f;

		private static readonly FieldRef<PhysGrabber, PhysGrabObject> GrabbedRef = AccessTools.FieldRefAccess<PhysGrabber, PhysGrabObject>("grabbedPhysGrabObject");

		private static readonly FieldRef<EnemyParent, Enemy> EnemyRef = AccessTools.FieldRefAccess<EnemyParent, Enemy>("Enemy");

		private static readonly FieldRef<EnemyParent, bool> SpawnedRef = AccessTools.FieldRefAccess<EnemyParent, bool>("Spawned");

		private int _itemMask;

		private int _losMask;

		private bool _masksReady;

		private GameObject _lastTarget;

		private float _dwellTimer;

		private Vector3 _smoothedPoint;

		private Vector3 _pointVel;

		private void Update()
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Enabled.Value || !Plugin.AimAssistEnabled.Value)
			{
				Forget();
				return;
			}
			CameraAim instance = CameraAim.Instance;
			Camera main = Camera.main;
			if ((Object)(object)instance == (Object)null || (Object)(object)main == (Object)null)
			{
				Forget();
				return;
			}
			EnsureMasks();
			if (_dwellTimer > 0f)
			{
				_dwellTimer -= Time.deltaTime;
			}
			Vector3 position = ((Component)main).transform.position;
			Vector3 forward = ((Component)main).transform.forward;
			if ((!Plugin.AimAssistEnemies.Value || !IsArmed() || !TryFindEnemy(position, forward, out var pos, out var go)) && (!Plugin.AimAssistItems.Value || !TryFindItem(position, forward, out pos, out go)))
			{
				Forget();
				return;
			}
			if ((Object)(object)go != (Object)(object)_lastTarget)
			{
				_lastTarget = go;
				_smoothedPoint = pos;
				_pointVel = Vector3.zero;
				_dwellTimer = 0.15f;
				Plugin.Log.LogDebug((object)("[AimAssist] target -> " + ((Object)go).name));
			}
			else
			{
				_smoothedPoint = Vector3.SmoothDamp(_smoothedPoint, pos, ref _pointVel, 0.08f);
			}
			TargetPosition = _smoothedPoint;
			HasTarget = true;
		}

		private void OnDisable()
		{
			Forget();
		}

		private void Forget()
		{
			HasTarget = false;
			if ((Object)(object)_lastTarget != (Object)null)
			{
				_lastTarget = null;
				Plugin.Log.LogDebug((object)"[AimAssist] target -> none");
			}
		}

		private static bool IsArmed()
		{
			PhysGrabber instance = PhysGrabber.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			PhysGrabObject val = GrabbedRef.Invoke(instance);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			GameObject gameObject = ((Component)val).gameObject;
			if (!((Object)(object)gameObject.GetComponentInChildren<ItemGun>() != (Object)null) && !((Object)(object)gameObject.GetComponentInChildren<ItemMelee>() != (Object)null))
			{
				return (Object)(object)gameObject.GetComponentInChildren<ValuableWizardStaff>() != (Object)null;
			}
			return true;
		}

		private bool TryFindEnemy(Vector3 origin, Vector3 fwd, out Vector3 pos, out GameObject go)
		{
			//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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: 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_0124: 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_013b: 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)
			pos = Vector3.zero;
			go = null;
			EnemyDirector instance = EnemyDirector.instance;
			if ((Object)(object)instance == (Object)null || instance.enemiesSpawned == null)
			{
				return false;
			}
			float value = Plugin.AimAssistMaxAngle.Value;
			float num = value * 0.6f;
			float value2 = Plugin.AimAssistEnemyRange.Value;
			GameObject bestGo = null;
			float num2 = value;
			Vector3 bestPos = Vector3.zero;
			GameObject curGo = null;
			float curAngle = value;
			Vector3 curPos = Vector3.zero;
			foreach (EnemyParent item in instance.enemiesSpawned)
			{
				if ((Object)(object)item == (Object)null || !SpawnedRef.Invoke(item))
				{
					continue;
				}
				Enemy val = EnemyRef.Invoke(item);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				Transform val2 = (((Object)(object)val.CenterTransform != (Object)null) ? val.CenterTransform : ((Component)val).transform);
				GameObject gameObject = ((Component)val).gameObject;
				float maxAngle = (((Object)(object)gameObject == (Object)(object)_lastTarget) ? value : num);
				if (Passes(origin, fwd, val2.position, value2, maxAngle, out var angle))
				{
					if ((Object)(object)gameObject == (Object)(object)_lastTarget)
					{
						curGo = gameObject;
						curAngle = angle;
						curPos = val2.position;
					}
					if (angle < num2)
					{
						num2 = angle;
						bestGo = gameObject;
						bestPos = val2.position;
					}
				}
			}
			return Resolve(bestGo, num2, bestPos, curGo, curAngle, curPos, out pos, out go);
		}

		private bool TryFindItem(Vector3 origin, Vector3 fwd, out Vector3 pos, out GameObject go)
		{
			//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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			pos = Vector3.zero;
			go = null;
			float value = Plugin.AimAssistMaxAngle.Value;
			float num = value * 0.6f;
			float value2 = Plugin.AimAssistItemRange.Value;
			RaycastHit[] array = Physics.SphereCastAll(origin, 0.4f, fwd, value2, _itemMask, (QueryTriggerInteraction)2);
			GameObject bestGo = null;
			float num2 = value;
			Vector3 bestPos = Vector3.zero;
			GameObject curGo = null;
			float curAngle = value;
			Vector3 curPos = Vector3.zero;
			RaycastHit[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				RaycastHit val = array2[i];
				if (!((Component)((RaycastHit)(ref val)).collider).CompareTag("Phys Grab Object"))
				{
					continue;
				}
				PhysGrabObject componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<PhysGrabObject>();
				if ((Object)(object)componentInParent == (Object)null)
				{
					continue;
				}
				GameObject gameObject = ((Component)componentInParent).gameObject;
				Vector3 centerPoint = componentInParent.centerPoint;
				float maxAngle = (((Object)(object)gameObject == (Object)(object)_lastTarget) ? value : num);
				if (Passes(origin, fwd, centerPoint, value2, maxAngle, out var angle))
				{
					if ((Object)(object)gameObject == (Object)(object)_lastTarget)
					{
						curGo = gameObject;
						curAngle = angle;
						curPos = centerPoint;
					}
					if (angle < num2)
					{
						num2 = angle;
						bestGo = gameObject;
						bestPos = centerPoint;
					}
				}
			}
			return Resolve(bestGo, num2, bestPos, curGo, curAngle, curPos, out pos, out go);
		}

		private bool Resolve(GameObject bestGo, float bestAngle, Vector3 bestPos, GameObject curGo, float curAngle, Vector3 curPos, out Vector3 pos, out GameObject go)
		{
			//IL_003e: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)curGo != (Object)null && ((Object)(object)bestGo == (Object)(object)curGo || _dwellTimer > 0f || bestAngle > curAngle - 4f))
			{
				pos = curPos;
				go = curGo;
				return true;
			}
			pos = bestPos;
			go = bestGo;
			return (Object)(object)go != (Object)null;
		}

		private bool Passes(Vector3 origin, Vector3 fwd, Vector3 target, float range, float maxAngle, out float angle)
		{
			//IL_0008: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_003b: 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)
			angle = 999f;
			Vector3 val = target - origin;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < 0.05f || magnitude > range)
			{
				return false;
			}
			angle = Vector3.Angle(fwd, val);
			if (angle > maxAngle)
			{
				return false;
			}
			if (Physics.Raycast(origin, val / magnitude, magnitude - 0.5f, _losMask))
			{
				return false;
			}
			return true;
		}

		private void EnsureMasks()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (!_masksReady)
			{
				_itemMask = (_losMask = LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct())) & ~LayerMask.GetMask(new string[1] { "Player" });
				_masksReady = true;
			}
		}
	}
	internal static class ButtonNames
	{
		internal enum Control
		{
			South,
			East,
			West,
			North,
			LB,
			RB,
			LT,
			RT,
			L3,
			R3,
			DpadLeft,
			DpadUp,
			DpadRight,
			DpadDown,
			Start,
			Select,
			LStick,
			RStick
		}

		internal static string Of(Control c, ControllerDetect.Kind kind)
		{
			return kind switch
			{
				ControllerDetect.Kind.PlayStation => Ps(c), 
				ControllerDetect.Kind.Switch => Sw(c), 
				_ => Xbox(c), 
			};
		}

		private static string Xbox(Control c)
		{
			return c switch
			{
				Control.South => "A", 
				Control.East => "B", 
				Control.West => "X", 
				Control.North => "Y", 
				Control.LB => "LB", 
				Control.RB => "RB", 
				Control.LT => "LT", 
				Control.RT => "RT", 
				Control.L3 => "L3", 
				Control.R3 => "R3", 
				Control.DpadLeft => "←", 
				Control.DpadUp => "↑", 
				Control.DpadRight => "→", 
				Control.DpadDown => "↓", 
				Control.Start => "Menu", 
				Control.Select => "View", 
				Control.LStick => "L-Stick", 
				Control.RStick => "R-Stick", 
				_ => "?", 
			};
		}

		private static string Ps(Control c)
		{
			return c switch
			{
				Control.South => "✕", 
				Control.East => "○", 
				Control.West => "□", 
				Control.North => "△", 
				Control.LB => "L1", 
				Control.RB => "R1", 
				Control.LT => "L2", 
				Control.RT => "R2", 
				Control.L3 => "L3", 
				Control.R3 => "R3", 
				Control.DpadLeft => "←", 
				Control.DpadUp => "↑", 
				Control.DpadRight => "→", 
				Control.DpadDown => "↓", 
				Control.Start => "Options", 
				Control.Select => "Create", 
				Control.LStick => "L-Stick", 
				Control.RStick => "R-Stick", 
				_ => "?", 
			};
		}

		private static string Sw(Control c)
		{
			return c switch
			{
				Control.South => "B", 
				Control.East => "A", 
				Control.West => "Y", 
				Control.North => "X", 
				Control.LB => "L", 
				Control.RB => "R", 
				Control.LT => "ZL", 
				Control.RT => "ZR", 
				Control.L3 => "L3", 
				Control.R3 => "R3", 
				Control.DpadLeft => "←", 
				Control.DpadUp => "↑", 
				Control.DpadRight => "→", 
				Control.DpadDown => "↓", 
				Control.Start => "+", 
				Control.Select => "-", 
				Control.LStick => "L-Stick", 
				Control.RStick => "R-Stick", 
				_ => "?", 
			};
		}
	}
	internal class ChatKeyboard : MonoBehaviour
	{
		private static readonly FieldRef<ChatManager, bool> ChatActiveRef = AccessTools.FieldRefAccess<ChatManager, bool>("chatActive");

		private static readonly FieldRef<ChatManager, string> ChatMessageRef = AccessTools.FieldRefAccess<ChatManager, string>("chatMessage");

		private static readonly Action<ChatManager, ChatState> StateSet = AccessTools.MethodDelegate<Action<ChatManager, ChatState>>(AccessTools.Method(typeof(ChatManager), "StateSet", (Type[])null, (Type[])null), (object)null, true);

		internal static bool Open;

		private const int MaxChatLength = 50;

		private const float RepeatDelay = 0.4f;

		private const float RepeatRate = 0.12f;

		private const float PadOpenWindow = 0.25f;

		private static readonly string[] CharRows = new string[4] { "1234567890", "QWERTYUIOP", "ASDFGHJKL'", "ZXCVBNM,.?" };

		private const int SpecialRow = 4;

		private static readonly string[] SpecialKeys = new string[3] { "!", "SPACE", "SEND" };

		private int _row;

		private int _col;

		private bool _selectArmed;

		private float _lastSelectPress = -10f;

		private bool _prevChatActive;

		private int _heldX;

		private int _heldY;

		private float _repeatTimer;

		private GUIStyle _key;

		private GUIStyle _keyHover;

		private GUIStyle _hint;

		private float _styleScale = -1f;

		private static bool _warned;

		private static readonly string[][] KeyLabels = BuildKeyLabels();

		private string _hints;

		private ControllerDetect.Kind _hintsKind;

		private bool _hintsBuilt;

		private static string[][] BuildKeyLabels()
		{
			string[][] array = new string[CharRows.Length][];
			for (int i = 0; i < CharRows.Length; i++)
			{
				array[i] = new string[CharRows[i].Length];
				for (int j = 0; j < CharRows[i].Length; j++)
				{
					array[i][j] = CharRows[i][j].ToString();
				}
			}
			return array;
		}

		internal static void ResetState()
		{
			Open = false;
		}

		private void Update()
		{
			ChatManager instance = ChatManager.instance;
			Gamepad current = Gamepad.current;
			if ((Object)(object)instance == (Object)null || !Plugin.Enabled.Value || !Plugin.ChatKeyboardEnabled.Value)
			{
				Open = false;
				return;
			}
			bool flag;
			try
			{
				flag = ChatActiveRef.Invoke(instance);
			}
			catch (Exception e)
			{
				WarnOnce(e);
				Open = false;
				return;
			}
			if (current != null && current.selectButton.wasPressedThisFrame)
			{
				_lastSelectPress = Time.unscaledTime;
			}
			if (!flag)
			{
				Open = false;
				_prevChatActive = false;
				return;
			}
			if (!_prevChatActive)
			{
				_prevChatActive = true;
				if (current != null && Time.unscaledTime - _lastSelectPress < 0.25f)
				{
					Open = true;
					_row = 1;
					_col = 0;
					_selectArmed = false;
					_heldX = 0;
					_heldY = 0;
					_repeatTimer = 0f;
				}
			}
			if (!Open || current == null)
			{
				return;
			}
			if (!current.selectButton.isPressed && !current.selectButton.wasReleasedThisFrame)
			{
				_selectArmed = true;
			}
			try
			{
				HandleNavigation(current);
				HandleButtons(instance, current);
			}
			catch (Exception e2)
			{
				WarnOnce(e2);
			}
		}

		private void HandleNavigation(Gamepad gp)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_003e: 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)
			Vector2 val = ((InputControl<Vector2>)(object)gp.leftStick).ReadValue();
			float num = Mathf.Max(Plugin.StickDeadzone.Value, 0.35f);
			int num2 = ((Mathf.Abs(val.x) > num) ? Math.Sign(val.x) : 0);
			int num3 = ((Mathf.Abs(val.y) > num) ? (-Math.Sign(val.y)) : 0);
			int num4 = (gp.dpad.left.isPressed ? (-1) : 0) + (gp.dpad.right.isPressed ? 1 : 0);
			int num5 = (gp.dpad.up.isPressed ? (-1) : 0) + (gp.dpad.down.isPressed ? 1 : 0);
			if (num4 == 0)
			{
				num4 = num2;
			}
			if (num5 == 0)
			{
				num5 = num3;
			}
			if (num4 == 0 && num5 == 0)
			{
				_heldX = 0;
				_heldY = 0;
				return;
			}
			if (num4 != _heldX || num5 != _heldY)
			{
				_heldX = num4;
				_heldY = num5;
				_repeatTimer = 0.4f;
				MoveCursor(num4, num5);
				return;
			}
			_repeatTimer -= Time.unscaledDeltaTime;
			if (_repeatTimer <= 0f)
			{
				_repeatTimer = 0.12f;
				MoveCursor(num4, num5);
			}
		}

		private void MoveCursor(int dx, int dy)
		{
			if (dy != 0)
			{
				int num = ColsIn(_row);
				float num2 = ((num > 1) ? ((float)_col / (float)(num - 1)) : 0f);
				_row = (_row + dy + 5) % 5;
				int num3 = ColsIn(_row);
				_col = Mathf.Clamp(Mathf.RoundToInt(num2 * (float)(num3 - 1)), 0, num3 - 1);
			}
			if (dx != 0)
			{
				int num4 = ColsIn(_row);
				_col = (_col + dx + num4) % num4;
			}
		}

		private static int ColsIn(int row)
		{
			if (row != 4)
			{
				return CharRows[row].Length;
			}
			return SpecialKeys.Length;
		}

		private void HandleButtons(ChatManager chat, Gamepad gp)
		{
			if (gp.buttonSouth.wasPressedThisFrame)
			{
				if (_row == 4)
				{
					if (_col == 1)
					{
						TypeChar(chat, " ");
					}
					else if (_col == 2)
					{
						SendOrClose(chat);
					}
					else
					{
						TypeChar(chat, "!");
					}
				}
				else
				{
					TypeChar(chat, char.ToLowerInvariant(CharRows[_row][_col]).ToString());
				}
			}
			if (gp.buttonWest.wasPressedThisFrame)
			{
				TypeChar(chat, " ");
			}
			if (gp.startButton.wasPressedThisFrame)
			{
				SendOrClose(chat);
			}
			if (_selectArmed && gp.selectButton.wasReleasedThisFrame)
			{
				Cancel(chat);
			}
		}

		private void TypeChar(ChatManager chat, string s)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if ((ChatMessageRef.Invoke(chat) ?? "").Length >= 50)
			{
				((SemiUI)ChatUI.instance).SemiUITextFlashColor(Color.red, 0.2f);
				((SemiUI)ChatUI.instance).SemiUISpringShakeX(10f, 10f, 0.3f);
				((SemiUI)ChatUI.instance).SemiUISpringScale(0.05f, 5f, 0.2f);
				MenuManager.instance.MenuEffectClick((MenuClickEffectType)2, (MenuPage)null, 1f, 1f, true);
			}
			else
			{
				chat.AddLetterToChat(s);
				((SemiUI)ChatUI.instance).SemiUITextFlashColor(Color.yellow, 0.2f);
				((SemiUI)ChatUI.instance).SemiUISpringShakeY(2f, 5f, 0.2f);
				MenuManager.instance.MenuEffectClick((MenuClickEffectType)4, (MenuPage)null, 2f, 0.2f, true);
			}
		}

		private void SendOrClose(ChatManager chat)
		{
			if ((ChatMessageRef.Invoke(chat) ?? "") != "")
			{
				chat.ForceConfirmChat();
				return;
			}
			StateSet(chat, (ChatState)0);
			Open = false;
		}

		private void Cancel(ChatManager chat)
		{
			StateSet(chat, (ChatState)0);
			((SemiUI)ChatUI.instance).SemiUISpringShakeX(10f, 10f, 0.3f);
			((SemiUI)ChatUI.instance).SemiUISpringScale(0.05f, 5f, 0.2f);
			MenuManager.instance.MenuEffectClick((MenuClickEffectType)2, (MenuPage)null, 1f, 1f, true);
			Open = false;
		}

		private static void WarnOnce(Exception e)
		{
			if (!_warned)
			{
				_warned = true;
				Plugin.Log.LogWarning((object)("[ChatKeyboard] Error (further warnings suppressed): " + e.Message));
			}
		}

		private void OnGUI()
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			if (!Open)
			{
				return;
			}
			float value = Plugin.ChatKeyboardScale.Value;
			EnsureStyles(value);
			float num = 34f * value;
			float num2 = 4f * value;
			float num3 = 10f * value;
			float num4 = 10f * num + 9f * num2;
			float num5 = num4 + 2f * num3;
			float num6 = 22f * value;
			float num7 = 5f * (num + num2) - num2 + 2f * num3 + num6;
			float num8 = ((float)Screen.width - num5) / 2f;
			float num9 = (float)Screen.height - num7 - 40f * value;
			GUI.color = new Color(0f, 0f, 0f, 0.55f);
			GUI.DrawTexture(new Rect(num8, num9, num5, num7), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = Color.white;
			for (int i = 0; i < 4; i++)
			{
				for (int j = 0; j < CharRows[i].Length; j++)
				{
					DrawKey(new Rect(num8 + num3 + (float)j * (num + num2), num9 + num3 + (float)i * (num + num2), num, num), KeyLabels[i][j], i == _row && j == _col);
				}
			}
			float num10 = num9 + num3 + 4f * (num + num2);
			float num11 = (num4 - num - 2f * num2) / 2f;
			DrawKey(new Rect(num8 + num3, num10, num, num), "!", _row == 4 && _col == 0);
			DrawKey(new Rect(num8 + num3 + num + num2, num10, num11, num), "SPACE", _row == 4 && _col == 1);
			DrawKey(new Rect(num8 + num3 + num + num2 + num11 + num2, num10, num11, num), "SEND", _row == 4 && _col == 2);
			ControllerDetect.Kind current = ControllerDetect.Current;
			if (!_hintsBuilt || current != _hintsKind)
			{
				_hintsBuilt = true;
				_hintsKind = current;
				_hints = ButtonNames.Of(ButtonNames.Control.South, current) + " type    " + ButtonNames.Of(ButtonNames.Control.East, current) + " backspace    " + ButtonNames.Of(ButtonNames.Control.West, current) + " space    " + ButtonNames.Of(ButtonNames.Control.Start, current) + " send    " + ButtonNames.Of(ButtonNames.Control.Select, current) + " close";
			}
			GUI.Label(new Rect(num8, num10 + num + num2, num5, num6), _hints, _hint);
		}

		private void DrawKey(Rect rect, string label, bool hovered)
		{
			//IL_0032: 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_003c: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			GUI.color = (hovered ? new Color(0.3f, 0.26f, 0.08f, 0.95f) : new Color(0.1f, 0.1f, 0.1f, 0.9f));
			GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = Color.white;
			GUI.Label(rect, label, hovered ? _keyHover : _key);
		}

		private void EnsureStyles(float scale)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0053: 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)
			//IL_0075: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			if (_key == null || !Mathf.Approximately(_styleScale, scale))
			{
				_styleScale = scale;
				_key = new GUIStyle(GUI.skin.label)
				{
					fontSize = (int)(15f * scale),
					alignment = (TextAnchor)4
				};
				_key.normal.textColor = Color.white;
				_keyHover = new GUIStyle(_key)
				{
					fontStyle = (FontStyle)1
				};
				_keyHover.normal.textColor = new Color(1f, 0.85f, 0.3f);
				_hint = new GUIStyle(GUI.skin.label)
				{
					fontSize = (int)(12f * scale),
					alignment = (TextAnchor)4
				};
				_hint.normal.textColor = new Color(0.75f, 0.77f, 0.85f);
			}
		}
	}
	[HarmonyPatch]
	internal static class ChatKeyboardMapGuard
	{
		[HarmonyPatch(typeof(InputManager), "KeyDown")]
		[HarmonyPostfix]
		private static void KeyDownPostfix(InputKey key, ref bool __result)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if (__result && (int)key == 8 && ChatKeyboard.Open)
			{
				__result = false;
			}
		}

		[HarmonyPatch(typeof(InputManager), "KeyHold")]
		[HarmonyPostfix]
		private static void KeyHoldPostfix(InputKey key, ref bool __result)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if (__result && (int)key == 8 && ChatKeyboard.Open)
			{
				__result = false;
			}
		}
	}
	internal static class ControllerDetect
	{
		internal enum Kind
		{
			None,
			Xbox,
			PlayStation,
			Switch,
			Generic
		}

		internal enum Style
		{
			Auto,
			Xbox,
			PlayStation,
			Switch
		}

		private static Kind _detected;

		private static bool _padActiveInit;

		internal static Kind Current => ((Plugin.GlyphStyle != null) ? Plugin.GlyphStyle.Value : Style.Auto) switch
		{
			Style.Xbox => Kind.Xbox, 
			Style.PlayStation => Kind.PlayStation, 
			Style.Switch => Kind.Switch, 
			_ => _detected, 
		};

		internal static bool PadActive { get; private set; }

		internal static bool PadTouchedThisLevel { get; private set; }

		internal static void ResetLevelTouch()
		{
			PadTouchedThisLevel = false;
		}

		internal static void TrackActiveInput()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_006b: 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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			Gamepad current = Gamepad.current;
			if (current == null)
			{
				PadActive = false;
				_padActiveInit = true;
				return;
			}
			if (!_padActiveInit)
			{
				_padActiveInit = true;
				PadActive = true;
			}
			Vector2 val = ((InputControl<Vector2>)(object)current.leftStick).ReadValue();
			if (!(((Vector2)(ref val)).sqrMagnitude > 0.02f))
			{
				val = ((InputControl<Vector2>)(object)current.rightStick).ReadValue();
				if (!(((Vector2)(ref val)).sqrMagnitude > 0.02f) && !(((InputControl<Vector2>)(object)current.dpad).ReadValue() != Vector2.zero) && !current.buttonSouth.isPressed && !current.buttonEast.isPressed && !current.buttonWest.isPressed && !current.buttonNorth.isPressed && !current.leftTrigger.isPressed && !current.rightTrigger.isPressed && !current.leftShoulder.isPressed && !current.rightShoulder.isPressed && !current.startButton.isPressed && !current.selectButton.isPressed && !current.leftStickButton.isPressed && !current.rightStickButton.isPressed)
				{
					Mouse current2 = Mouse.current;
					int num;
					if (current2 != null)
					{
						val = ((InputControl<Vector2>)(object)((Pointer)current2).delta).ReadValue();
						num = ((((Vector2)(ref val)).sqrMagnitude > 4f || current2.leftButton.isPressed || current2.rightButton.isPressed) ? 1 : 0);
					}
					else
					{
						num = 0;
					}
					Keyboard current3 = Keyboard.current;
					bool flag = current3 != null && ((ButtonControl)current3.anyKey).isPressed;
					if (((uint)num | (flag ? 1u : 0u)) != 0)
					{
						PadActive = false;
					}
					return;
				}
			}
			PadActive = true;
			PadTouchedThisLevel = true;
		}

		internal static void Init()
		{
			Detect();
			InputSystem.onDeviceChange += delegate(InputDevice device, InputDeviceChange change)
			{
				if (device is Gamepad)
				{
					Detect();
				}
			};
		}

		private static void Detect()
		{
			Gamepad current = Gamepad.current;
			Kind kind = Classify(current);
			if (kind != _detected)
			{
				_detected = kind;
				string arg = ((current == null) ? "none" : (((InputControl)current).displayName + " (layout=" + ((InputControl)current).layout + ")"));
				Style style = ((Plugin.GlyphStyle != null) ? Plugin.GlyphStyle.Value : Style.Auto);
				string arg2 = ((style == Style.Auto) ? "" : $" (glyph override active: {style})");
				Plugin.Log.LogInfo((object)$"[Gamepad] Detected controller: {kind} — {arg}{arg2}");
			}
		}

		private static Kind Classify(Gamepad gp)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (gp == null)
			{
				return Kind.None;
			}
			InputDeviceDescription description = ((InputDevice)gp).description;
			string text = (((InputDeviceDescription)(ref description)).manufacturer + " " + ((InputDeviceDescription)(ref description)).product + " " + ((InputControl)gp).layout + " " + ((InputControl)gp).name).ToLowerInvariant();
			if (text.Contains("dualsense") || text.Contains("dualshock") || text.Contains("sony") || text.Contains("playstation") || text.Contains("wireless controller"))
			{
				return Kind.PlayStation;
			}
			if (text.Contains("switch") || text.Contains("pro controller") || text.Contains("nintendo") || text.Contains("joy-con"))
			{
				return Kind.Switch;
			}
			if (text.Contains("xinput") || text.Contains("xbox"))
			{
				return Kind.Xbox;
			}
			return Kind.Generic;
		}
	}
	internal static class ControllerGlyphs
	{
		private static Font _symbol;

		private static bool _tried;

		private static GUIStyle _shapeStyle;

		private static Font Symbol()
		{
			if (!_tried)
			{
				_tried = true;
				try
				{
					_symbol = Font.CreateDynamicFontFromOSFont(new string[4] { "Arial Unicode MS", "Segoe UI Symbol", "Segoe UI", "Arial" }, 16);
				}
				catch
				{
					_symbol = null;
				}
			}
			return _symbol;
		}

		private static bool IsSymbol(char c)
		{
			if (c != '○' && c != '□' && c != '△' && c != '←' && c != '↑' && c != '→')
			{
				return c == '↓';
			}
			return true;
		}

		private static bool HasSymbol(string s)
		{
			for (int i = 0; i < s.Length; i++)
			{
				if (IsSymbol(s[i]))
				{
					return true;
				}
			}
			return false;
		}

		internal static void DrawLabel(Rect rect, string text, GUIStyle style)
		{
			//IL_0017: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00ba: 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_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			Font val = Symbol();
			if ((Object)(object)val == (Object)null || !HasSymbol(text))
			{
				GUI.Label(rect, text, style);
				return;
			}
			if (_shapeStyle == null)
			{
				_shapeStyle = new GUIStyle();
			}
			_shapeStyle.font = val;
			_shapeStyle.fontSize = style.fontSize;
			_shapeStyle.fontStyle = style.fontStyle;
			_shapeStyle.alignment = (TextAnchor)0;
			_shapeStyle.normal.textColor = style.normal.textColor;
			float num = ((Rect)(ref rect)).x;
			int i = 0;
			while (i < text.Length)
			{
				if (IsSymbol(text[i]))
				{
					string text2 = text[i].ToString();
					float x = _shapeStyle.CalcSize(new GUIContent(text2)).x;
					GUI.Label(new Rect(num, ((Rect)(ref rect)).y, x, ((Rect)(ref rect)).height), text2, _shapeStyle);
					num += x;
					i++;
					continue;
				}
				int num2 = i;
				for (; i < text.Length && !IsSymbol(text[i]); i++)
				{
				}
				string text3 = text.Substring(num2, i - num2);
				float x2 = style.CalcSize(new GUIContent(text3)).x;
				GUI.Label(new Rect(num, ((Rect)(ref rect)).y, x2, ((Rect)(ref rect)).height), text3, style);
				num += x2;
			}
		}
	}
	internal class ControllerLayoutOverlay : MonoBehaviour
	{
		private static readonly FieldRef<MenuManager, int> StateRef = AccessTools.FieldRefAccess<MenuManager, int>("currentMenuState");

		internal static bool Visible;

		private static int _openFrame;

		private GUIStyle _title;

		private GUIStyle _row;

		private GUIStyle _key;

		internal static void Toggle()
		{
			Visible = !Visible;
			if (Visible)
			{
				_openFrame = Time.frameCount;
			}
		}

		private static bool MenuOpen()
		{
			MenuManager instance = MenuManager.instance;
			if ((Object)(object)instance != (Object)null)
			{
				return StateRef.Invoke(instance) == 0;
			}
			return false;
		}

		private void Update()
		{
			if (!Plugin.Enabled.Value)
			{
				Visible = false;
				return;
			}
			Gamepad current = Gamepad.current;
			if (current == null)
			{
				Visible = false;
				return;
			}
			if (Visible && Time.frameCount > _openFrame + 1 && (AnyButtonPressed(current) || MouseClicked()))
			{
				Visible = false;
			}
			if (!MenuOpen())
			{
				Visible = false;
			}
		}

		private static bool MouseClicked()
		{
			Mouse current = Mouse.current;
			if (current != null)
			{
				if (!current.leftButton.wasPressedThisFrame)
				{
					return current.rightButton.wasPressedThisFrame;
				}
				return true;
			}
			return false;
		}

		private static bool AnyButtonPressed(Gamepad gp)
		{
			if (!gp.buttonSouth.wasPressedThisFrame && !gp.buttonEast.wasPressedThisFrame && !gp.buttonWest.wasPressedThisFrame && !gp.buttonNorth.wasPressedThisFrame && !gp.leftShoulder.wasPressedThisFrame && !gp.rightShoulder.wasPressedThisFrame && !gp.leftTrigger.wasPressedThisFrame && !gp.rightTrigger.wasPressedThisFrame && !gp.dpad.up.wasPressedThisFrame && !gp.dpad.down.wasPressedThisFrame && !gp.dpad.left.wasPressedThisFrame && !gp.dpad.right.wasPressedThisFrame && !gp.startButton.wasPressedThisFrame && !gp.selectButton.wasPressedThisFrame && !gp.leftStickButton.wasPressedThisFrame)
			{
				return gp.rightStickButton.wasPressedThisFrame;
			}
			return true;
		}

		private void OnGUI()
		{
			//IL_002d: 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_00ac: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_0154: Unknown result type (might be due to invalid IL or missing references)
			if (!Visible)
			{
				return;
			}
			EnsureStyles();
			List<KeyValuePair<string, string>> list = Rows(ControllerDetect.Current);
			GUI.color = new Color(0f, 0f, 0f, 0.6f);
			GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture);
			float num = 520f;
			float num2 = 26f;
			float num3 = 60f + (float)list.Count * num2;
			float num4 = ((float)Screen.width - num) / 2f;
			float num5 = ((float)Screen.height - num3) / 2f;
			GUI.color = new Color(0.1f, 0.1f, 0.1f, 0.95f);
			GUI.DrawTexture(new Rect(num4, num5, num, num3), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = Color.white;
			GUI.Label(new Rect(num4, num5 + 12f, num, 30f), "Controller Layout", _title);
			float num6 = num5 + 50f;
			foreach (KeyValuePair<string, string> item in list)
			{
				GUI.Label(new Rect(num4 + 24f, num6, num * 0.55f, num2), item.Key, _row);
				ControllerGlyphs.DrawLabel(new Rect(num4 + num * 0.55f, num6, num * 0.4f, num2), item.Value, _key);
				num6 += num2;
			}
		}

		private static List<KeyValuePair<string, string>> Rows(ControllerDetect.Kind k)
		{
			List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
			list.Add(R("Move / Look", N(ButtonNames.Control.LStick) + " / " + N(ButtonNames.Control.RStick)));
			list.Add(R("Jump", N(ButtonNames.Control.South)));
			list.Add(R("Interact", N(ButtonNames.Control.West)));
			list.Add(R("Tumble", N(ButtonNames.Control.East)));
			list.Add(R("Map", N(ButtonNames.Control.North)));
			list.Add(R("Sprint / Crouch", N(ButtonNames.Control.L3) + " / " + N(ButtonNames.Control.R3)));
			list.Add(R("Grab / Rotate", N(ButtonNames.Control.RT) + " / " + N(ButtonNames.Control.LT)));
			list.Add(R("Push / Pull", N(ButtonNames.Control.RB) + " / " + N(ButtonNames.Control.LB)));
			list.Add(R("Pause / Chat", N(ButtonNames.Control.Start) + " / " + N(ButtonNames.Control.Select)));
			list.Add(R("Inventory 1 / 2 / 3", N(ButtonNames.Control.DpadLeft) + " / " + N(ButtonNames.Control.DpadUp) + " / " + N(ButtonNames.Control.DpadRight)));
			list.Add(R("Emotes", "hold " + N(ButtonNames.Control.DpadDown)));
			list.Add(R("View this layout", "Settings menu"));
			list.Add(R("Menu: Select / Back", N(ButtonNames.Control.South) + " / " + N(ButtonNames.Control.East)));
			return list;
			string N(ButtonNames.Control c)
			{
				return ButtonNames.Of(c, k);
			}
			static KeyValuePair<string, string> R(string a, string b)
			{
				return new KeyValuePair<string, string>(a, b);
			}
		}

		private void EnsureStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_003f: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_009f: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			if (_title == null)
			{
				_title = new GUIStyle(GUI.skin.label)
				{
					fontSize = 22,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				_title.normal.textColor = Color.white;
				_row = new GUIStyle(GUI.skin.label)
				{
					fontSize = 16
				};
				_row.normal.textColor = Color.white;
				_key = new GUIStyle(GUI.skin.label)
				{
					fontSize = 16,
					fontStyle = (FontStyle)1
				};
				_key.normal.textColor = new Color(1f, 0.85f, 0.3f);
			}
		}
	}
	internal class EmoteWheel : MonoBehaviour
	{
		private static readonly FieldRef<MenuManager, int> MenuStateRef = AccessTools.FieldRefAccess<MenuManager, int>("currentMenuState");

		private static readonly FieldRef<ChatManager, bool> ChatActiveRef = AccessTools.FieldRefAccess<ChatManager, bool>("chatActive");

		private static readonly Action<PlayerExpression, int, float, bool> DoExpression = AccessTools.MethodDelegate<Action<PlayerExpression, int, float, bool>>(AccessTools.Method(typeof(PlayerExpression), "DoExpression", (Type[])null, (Type[])null), (object)null, true);

		internal static bool Open;

		private const int SegmentCount = 6;

		private const float MinDeflection = 0.35f;

		private static readonly Dictionary<int, float> Active = new Dictionary<int, float>();

		private static readonly List<int> Expired = new List<int>();

		private static string[] _labels;

		private static bool _warned;

		private int _hovered;

		private static Transform _previewCam;

		private static bool _camMoved;

		private static Vector3 _camHomeLocal;

		private GUIStyle _title;

		private GUIStyle _label;

		private GUIStyle _labelHover;

		private GUIStyle _labelActive;

		internal static void ResetState()
		{
			Active.Clear();
			_labels = null;
			Open = false;
			_previewCam = null;
			_camMoved = false;
		}

		private void Update()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Enabled.Value || !Plugin.EmoteWheelEnabled.Value)
			{
				Close();
				return;
			}
			Gamepad current = Gamepad.current;
			if (current == null || !InGameplay())
			{
				Close();
				return;
			}
			if (current.dpad.down.isPressed)
			{
				Open = true;
				_hovered = HoveredSegment(((InputControl<Vector2>)(object)current.rightStick).ReadValue());
			}
			else if (Open)
			{
				int hovered = _hovered;
				Close();
				if (hovered != 0)
				{
					ToggleExpression(hovered);
				}
			}
			DriveActiveExpressions();
		}

		private void LateUpdate()
		{
			//IL_0059: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (!Open && Active.Count <= 0)
			{
				RestoreCamera();
				return;
			}
			PlayerExpressionsUI instance = PlayerExpressionsUI.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Transform val = FindPreviewCamera(instance);
			if (!((Object)(object)val == (Object)null))
			{
				if (!_camMoved)
				{
					_camHomeLocal = val.localPosition;
					_camMoved = true;
				}
				val.localPosition = _camHomeLocal;
				val.position += val.forward * (0f - Plugin.EmoteZoomOut.Value) + val.up * (0f - Plugin.EmoteCameraLower.Value);
			}
		}

		private static Transform FindPreviewCamera(PlayerExpressionsUI ui)
		{
			if ((Object)(object)_previewCam != (Object)null)
			{
				return _previewCam;
			}
			if ((Object)(object)ui.PlayerAvatarMenu == (Object)null)
			{
				return null;
			}
			PlayerAvatarMenu component = ui.PlayerAvatarMenu.GetComponent<PlayerAvatarMenu>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.cameraAndStuff == (Object)null)
			{
				return null;
			}
			Camera componentInChildren = ((Component)component.cameraAndStuff).GetComponentInChildren<Camera>(true);
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return null;
			}
			_previewCam = ((Component)componentInChildren).transform;
			return _previewCam;
		}

		private static void RestoreCamera()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (_camMoved)
			{
				_camMoved = false;
				if ((Object)(object)_previewCam != (Object)null)
				{
					_previewCam.localPosition = _camHomeLocal;
				}
			}
		}

		private static void DriveActiveExpressions()
		{
			if (Active.Count == 0)
			{
				return;
			}
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.playerExpression == (Object)null)
			{
				return;
			}
			PlayerExpression val = (((Object)(object)PlayerExpressionsUI.instance != (Object)null) ? PlayerExpressionsUI.instance.playerExpression : null);
			Expired.Clear();
			if (Plugin.EmoteDurationSeconds.Value > 0f)
			{
				foreach (int item in new List<int>(Active.Keys))
				{
					Active[item] -= Time.deltaTime;
					if (Active[item] <= 0f)
					{
						Expired.Add(item);
					}
				}
				foreach (int item2 in Expired)
				{
					Active.Remove(item2);
				}
				if (Active.Count == 0)
				{
					return;
				}
			}
			try
			{
				foreach (int key in Active.Keys)
				{
					DoExpression(instance.playerExpression, key, 100f, arg4: true);
					if ((Object)(object)val != (Object)null)
					{
						val.OverrideExpressionSet(key, 100f);
					}
				}
			}
			catch (Exception ex)
			{
				if (!_warned)
				{
					Plugin.Log.LogWarning((object)("[EmoteWheel] DoExpression failed: " + ex.Message));
					_warned = true;
				}
			}
		}

		private void Close()
		{
			Open = false;
			_hovered = 0;
		}

		private static bool InGameplay()
		{
			MenuManager instance = MenuManager.instance;
			if ((Object)(object)instance != (Object)null && MenuStateRef.Invoke(instance) == 0)
			{
				return false;
			}
			ChatManager instance2 = ChatManager.instance;
			if ((Object)(object)instance2 != (Object)null && ChatActiveRef.Invoke(instance2))
			{
				return false;
			}
			return (Object)(object)PlayerAvatar.instance != (Object)null;
		}

		private int HoveredSegment(Vector2 stick)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(Plugin.StickDeadzone.Value, 0.35f);
			if (((Vector2)(ref stick)).magnitude < num)
			{
				return 0;
			}
			float num2 = Mathf.Atan2(stick.x, stick.y) * 57.29578f;
			if (num2 < 0f)
			{
				num2 += 360f;
			}
			return Mathf.FloorToInt((num2 + 30f) % 360f / 60f) + 1;
		}

		private static void ToggleExpression(int index)
		{
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.playerExpression == (Object)null)
			{
				return;
			}
			try
			{
				if (Active.Remove(index))
				{
					Plugin.Log.LogDebug((object)$"[EmoteWheel] Expression {index} OFF");
					return;
				}
				Active.Clear();
				DoExpression(instance.playerExpression, index, 100f, arg4: true);
				float value = Plugin.EmoteDurationSeconds.Value;
				Active[index] = ((value > 0f) ? value : float.PositiveInfinity);
				Plugin.Log.LogDebug((object)$"[EmoteWheel] Expression {index} ON");
			}
			catch (Exception ex)
			{
				if (!_warned)
				{
					Plugin.Log.LogWarning((object)("[EmoteWheel] Expression call failed: " + ex.Message));
					_warned = true;
				}
			}
		}

		private void OnGUI()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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)
			//IL_009a: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: 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)
			if (Open)
			{
				EnsureStyles();
				EnsureLabels();
				float num = (float)Screen.width / 2f;
				float num2 = (float)Screen.height / 2f;
				float num3 = 170f;
				GUI.color = new Color(0f, 0f, 0f, 0.35f);
				GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture);
				GUI.color = Color.white;
				GUI.Label(new Rect(num - 200f, num2 - num3 - 70f, 400f, 30f), "Emotes", _title);
				for (int i = 1; i <= 6; i++)
				{
					float num4 = (float)(i - 1) * 60f * (MathF.PI / 180f);
					float num5 = num + Mathf.Sin(num4) * num3;
					float num6 = num2 - Mathf.Cos(num4) * num3;
					Rect val = new Rect(num5 - 80f, num6 - 20f, 160f, 40f);
					GUI.color = ((i == _hovered) ? new Color(0.3f, 0.26f, 0.08f, 0.95f) : new Color(0.1f, 0.1f, 0.1f, 0.9f));
					GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture);
					GUI.color = Color.white;
					GUIStyle val2 = ((i == _hovered) ? _labelHover : (Active.ContainsKey(i) ? _labelActive : _label));
					GUI.Label(val, _labels[i], val2);
				}
			}
		}

		private static void EnsureLabels()
		{
			if (_labels != null)
			{
				return;
			}
			_labels = new string[7];
			List<ExpressionSettings> list = null;
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance != (Object)null && (Object)(object)instance.playerExpression != (Object)null)
			{
				list = instance.playerExpression.expressions;
			}
			for (int i = 1; i <= 6; i++)
			{
				string text = null;
				if (list != null && i < list.Count && list[i] != null)
				{
					text = list[i].expressionName;
				}
				_labels[i] = (string.IsNullOrEmpty(text) ? $"Expression {i}" : text);
			}
		}

		private void EnsureStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_003f: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0078: 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_009a: Expected O, but got Unknown
			//IL_00b4: 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)
			//IL_00d6: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			if (_title == null)
			{
				_title = new GUIStyle(GUI.skin.label)
				{
					fontSize = 22,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				_title.normal.textColor = Color.white;
				_label = new GUIStyle(GUI.skin.label)
				{
					fontSize = 16,
					alignment = (TextAnchor)4
				};
				_label.normal.textColor = Color.white;
				_labelHover = new GUIStyle(_label)
				{
					fontStyle = (FontStyle)1
				};
				_labelHover.normal.textColor = new Color(1f, 0.85f, 0.3f);
				_labelActive = new GUIStyle(_label)
				{
					fontStyle = (FontStyle)1
				};
				_labelActive.normal.textColor = new Color(0.55f, 0.8f, 1f);
			}
		}
	}
	[HarmonyPatch(typeof(InputManager), "InitializeInputs")]
	internal static class GamepadBindingsPatch
	{
		private static InputManager _injected;

		[HarmonyPostfix]
		public static void Postfix(InputManager __instance)
		{
			if (!Plugin.Enabled.Value || _injected == __instance)
			{
				return;
			}
			_injected = __instance;
			try
			{
				Bind(__instance, (InputKey)0, "<Gamepad>/leftStick");
				Bind(__instance, (InputKey)1, "<Gamepad>/buttonSouth");
				Bind(__instance, (InputKey)2, "<Gamepad>/buttonWest");
				Bind(__instance, (InputKey)14, "<Gamepad>/buttonEast");
				Bind(__instance, (InputKey)8, "<Gamepad>/buttonNorth");
				Bind(__instance, (InputKey)15, "<Gamepad>/leftStickPress");
				Bind(__instance, (InputKey)12, "<Gamepad>/rightStickPress");
				Bind(__instance, (InputKey)10, "<Gamepad>/rightTrigger");
				Bind(__instance, (InputKey)11, "<Gamepad>/leftTrigger");
				Bind(__instance, (InputKey)6, "<Gamepad>/start");
				Bind(__instance, (InputKey)7, "<Gamepad>/select");
				Bind(__instance, (InputKey)13, "<Gamepad>/buttonEast");
				Bind(__instance, (InputKey)19, "<Gamepad>/dpad/left");
				Bind(__instance, (InputKey)20, "<Gamepad>/dpad/up");
				Bind(__instance, (InputKey)21, "<Gamepad>/dpad/right");
				Plugin.Log.LogInfo((object)"[Gamepad] Bindings injected.");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"[Gamepad] Binding injection failed: {arg}");
			}
		}

		internal static void Bind(InputManager im, InputKey key, string path, string processors = null)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0058: 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)
			InputAction action = im.GetAction(key);
			if (action == null)
			{
				Plugin.Log.LogWarning((object)$"[Gamepad] No action for {key}");
				return;
			}
			bool enabled = action.enabled;
			if (enabled)
			{
				action.Disable();
			}
			if (string.IsNullOrEmpty(processors))
			{
				InputActionSetupExtensions.AddBinding(action, path, (string)null, (string)null, (string)null);
			}
			else
			{
				BindingSyntax val = InputActionSetupExtensions.AddBinding(action, path, (string)null, (string)null, (string)null);
				((BindingSyntax)(ref val)).WithProcessors(processors);
			}
			if (enabled)
			{
				action.Enable();
			}
		}
	}
	internal class GrabPromptOverlay : MonoBehaviour
	{
		private struct Prompt
		{
			public string Rich;

			public string Plain;
		}

		private struct SlotLabel
		{
			public TextMeshProUGUI Text;

			public string Original;

			public int SpotIndex;
		}

		private static readonly FieldRef<MenuManager, int> MenuStateRef = AccessTools.FieldRefAccess<MenuManager, int>("currentMenuState");

		private static FieldRef<Aim, State> _aimStateRef;

		private static bool _aimRefFailed;

		private ControllerDetect.Kind _cachedKind = (ControllerDetect.Kind)(-1);

		private Prompt _grab;

		private Prompt _letGo;

		private Prompt _rotate;

		private Prompt _climb;

		private Prompt _rightLine;

		private Prompt _leftLine;

		private GUIStyle _style;

		private bool _showArrows;

		private bool _labelsSwapped;

		private InventorySpot[] _spots;

		private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4];

		private readonly List<SlotLabel> _slotLabels = new List<SlotLabel>(8);

		private void Update()
		{
			//IL_00bb: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected I4, but got Unknown
			ControllerDetect.TrackActiveInput();
			InputDisplayPatch.TickCacheInvalidation();
			_rightLine = default(Prompt);
			_leftLine = default(Prompt);
			_showArrows = false;
			if (!Plugin.Enabled.Value || !Plugin.PromptsEnabled.Value || Gamepad.current == null || !ControllerDetect.PadActive || EmoteWheel.Open)
			{
				return;
			}
			MenuManager instance = MenuManager.instance;
			if ((Object)(object)instance != (Object)null && MenuStateRef.Invoke(instance) == 0)
			{
				return;
			}
			_showArrows = Plugin.InventoryArrows.Value && ControllerDetect.PadTouchedThisLevel;
			Aim instance2 = Aim.instance;
			if ((Object)(object)instance2 == (Object)null || !EnsureAimRef())
			{
				return;
			}
			EnsureNames();
			State val = _aimStateRef.Invoke(instance2);
			switch (val - 1)
			{
			case 0:
				_rightLine = _grab;
				break;
			case 1:
			case 2:
				if (Plugin.GrabToggle.Value)
				{
					_rightLine = _letGo;
				}
				_leftLine = _rotate;
				break;
			case 4:
				_rightLine = _climb;
				break;
			case 3:
				break;
			}
		}

		private static bool EnsureAimRef()
		{
			if (_aimStateRef != null)
			{
				return true;
			}
			if (_aimRefFailed)
			{
				return false;
			}
			try
			{
				_aimStateRef = AccessTools.FieldRefAccess<Aim, State>("currentState");
				return true;
			}
			catch (Exception ex)
			{
				_aimRefFailed = true;
				Plugin.Log.LogWarning((object)("[Prompts] Aim.currentState unavailable — prompts disabled: " + ex.Message));
				return false;
			}
		}

		private void EnsureNames()
		{
			ControllerDetect.Kind current = ControllerDetect.Current;
			if (current != _cachedKind || _grab.Plain == null)
			{
				_cachedKind = current;
				string button = ButtonNames.Of(ButtonNames.Control.RT, current);
				string button2 = ButtonNames.Of(ButtonNames.Control.LT, current);
				_grab = Make("GRAB", button);
				_letGo = Make("LET GO", button);
				_rotate = Make("ROTATE", button2);
				_climb = Make("CLIMB", button);
			}
		}

		private static Prompt Make(string action, string button)
		{
			return new Prompt
			{
				Rich = "<color=#FFA21C>" + action + "</color> <color=#FFFFFF>[" + button + "]</color>",
				Plain = action + " [" + button + "]"
			};
		}

		private void LateUpdate()
		{
			if (!_showArrows && !_labelsSwapped)
			{
				return;
			}
			if (NeedSlotLabelRefresh())
			{
				_slotLabels.Clear();
				_labelsSwapped = false;
				_spots = Object.FindObjectsOfType<InventorySpot>();
				InventorySpot[] spots = _spots;
				foreach (InventorySpot val in spots)
				{
					int inventorySpotIndex = val.inventorySpotIndex;
					if (inventorySpotIndex < 0 || inventorySpotIndex > 2)
					{
						continue;
					}
					string text = (inventorySpotIndex + 1).ToString();
					TextMeshProUGUI[] componentsInChildren = ((Component)val).GetComponentsInChildren<TextMeshProUGUI>(true);
					foreach (TextMeshProUGUI val2 in componentsInChildren)
					{
						if ((Object)(object)val2 == (Object)(object)val.noItem || ((TMP_Text)val2).text.Trim() == text)
						{
							_slotLabels.Add(new SlotLabel
							{
								Text = val2,
								Original = ((TMP_Text)val2).text,
								SpotIndex = inventorySpotIndex
							});
						}
					}
				}
				if (_slotLabels.Count == 0)
				{
					return;
				}
			}
			ControllerDetect.Kind current = ControllerDetect.Current;
			foreach (SlotLabel slotLabel in _slotLabels)
			{
				if ((Object)(object)slotLabel.Text == (Object)null)
				{
					continue;
				}
				if (_showArrows)
				{
					string text2 = ((slotLabel.SpotIndex == 0) ? ButtonNames.Of(ButtonNames.Control.DpadLeft, current) : ((slotLabel.SpotIndex == 1) ? ButtonNames.Of(ButtonNames.Control.DpadUp, current) : ButtonNames.Of(ButtonNames.Control.DpadRight, current)));
					if (((TMP_Text)slotLabel.Text).text != text2)
					{
						((TMP_Text)slotLabel.Text).text = text2;
					}
				}
				else if (((TMP_Text)slotLabel.Text).text != slotLabel.Original)
				{
					((TMP_Text)slotLabel.Text).text = slotLabel.Original;
				}
			}
			_labelsSwapped = _showArrows;
		}

		private bool NeedSlotLabelRefresh()
		{
			if (_spots == null || _spots.Length == 0 || (Object)(object)_spots[0] == (Object)null || _slotLabels.Count == 0)
			{
				return true;
			}
			foreach (SlotLabel slotLabel in _slotLabels)
			{
				if ((Object)(object)slotLabel.Text == (Object)null)
				{
					return true;
				}
			}
			return false;
		}

		private void OnGUI()
		{
			if (_rightLine.Plain == null && _leftLine.Plain == null)
			{
				return;
			}
			EnsureStyles();
			if (TryInventoryScreenBounds(out var minX, out var maxX, out var centerY))
			{
				float guiCenterY = (float)Screen.height - centerY;
				if (_rightLine.Plain != null)
				{
					DrawChip(_rightLine, maxX + 14f, guiCenterY, rightSide: true);
				}
				if (_leftLine.Plain != null)
				{
					DrawChip(_leftLine, minX - 14f, guiCenterY, rightSide: false);
				}
				return;
			}
			float cx = (float)Screen.width / 2f;
			float num = (float)Screen.height / 2f + 35f;
			if (_rightLine.Plain != null)
			{
				DrawChipCentered(_rightLine, cx, num);
				num += 28f;
			}
			if (_leftLine.Plain != null)
			{
				DrawChipCentered(_leftLine, cx, num);
			}
		}

		private void DrawChip(Prompt p, float anchorX, float guiCenterY, bool rightSide)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0011: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			float num = _style.CalcSize(new GUIContent(p.Plain)).x + 18f;
			Rect val = new Rect(rightSide ? anchorX : (anchorX - num), guiCenterY - 12f, num, 24f);
			GUI.color = new Color(0.08f, 0.08f, 0.08f, 0.85f);
			GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = Color.white;
			GUI.Label(val, p.Rich, _style);
		}

		private void DrawChipCentered(Prompt p, float cx, float y)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0011: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			float num = _style.CalcSize(new GUIContent(p.Plain)).x + 18f;
			Rect val = new Rect(cx - num / 2f, y, num, 24f);
			GUI.color = new Color(0.08f, 0.08f, 0.08f, 0.85f);
			GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = Color.white;
			GUI.Label(val, p.Rich, _style);
		}

		private bool TryInventoryScreenBounds(out float minX, out float maxX, out float centerY)
		{
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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_015f: Unknown result type (might be due to invalid IL or missing references)
			minX = float.MaxValue;
			maxX = float.MinValue;
			centerY = 0f;
			CameraOverlay instance = CameraOverlay.instance;
			RenderTextureMain instance2 = RenderTextureMain.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null || (Object)(object)instance2.overlayRawImage == (Object)null)
			{
				return false;
			}
			Camera component = ((Component)instance).GetComponent<Camera>();
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			if (_spots == null || _spots.Length == 0 || (Object)(object)_spots[0] == (Object)null)
			{
				_spots = Object.FindObjectsOfType<InventorySpot>();
				if (_spots.Length == 0)
				{
					return false;
				}
			}
			((Graphic)instance2.overlayRawImage).rectTransform.GetWorldCorners(_corners);
			Vector2 val = Vector2.op_Implicit(_corners[0]);
			Vector2 val2 = Vector2.op_Implicit(_corners[2]);
			float num = 0f;
			int num2 = 0;
			InventorySpot[] spots = _spots;
			foreach (InventorySpot val3 in spots)
			{
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				Transform transform = ((Component)val3).transform;
				RectTransform val4 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if ((Object)(object)val4 == (Object)null)
				{
					continue;
				}
				val4.GetWorldCorners(_corners);
				for (int j = 0; j < 4; j++)
				{
					Vector3 val5 = component.WorldToViewportPoint(_corners[j]);
					float num3 = Mathf.Lerp(val.x, val2.x, val5.x);
					float num4 = Mathf.Lerp(val.y, val2.y, val5.y);
					if (num3 < minX)
					{
						minX = num3;
					}
					if (num3 > maxX)
					{
						maxX = num3;
					}
					num += num4;
				}
				num2++;
			}
			if (num2 == 0)
			{
				return false;
			}
			centerY = num / (float)(num2 * 4);
			return true;
		}

		private void EnsureStyles()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (_style == null)
			{
				_style = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4,
					richText = true
				};
				_style.normal.textColor = Color.white;
			}
		}
	}
	[HarmonyPatch]
	internal static class InputDisplayPatch
	{
		private static readonly FieldRef<MenuManager, int> MenuStateRef = AccessTools.FieldRefAccess<MenuManager, int>("currentMenuState");

		private static readonly FieldRef<ItemAttributes, string> ItemTagRef = AccessTools.FieldRefAccess<ItemAttributes, string>("itemTag");

		private static bool _lastControllerActive;

		[HarmonyPatch(typeof(InputManager), "InputDisplayGet")]
		[HarmonyPostfix]
		private static void InputDisplayGetPostfix(InputKey _inputKey, KeyType _keyType, MovementDirection _movementDirection, ref string __result)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Invalid comparison between Unknown and I4
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Enabled.Value || !Plugin.ControllerKeyTags.Value || Gamepad.current == null || !ControllerDetect.PadActive)
			{
				return;
			}
			MenuManager instance = MenuManager.instance;
			if ((Object)(object)instance != (Object)null && MenuStateRef.Invoke(instance) == 0)
			{
				return;
			}
			if ((int)_keyType == 1)
			{
				__result = (((int)_movementDirection == 0) ? "L-STICK" : "");
				return;
			}
			string text = NameFor(_inputKey, ControllerDetect.Current);
			if (text != null)
			{
				__result = text.ToUpper();
			}
		}

		private static string NameFor(InputKey key, ControllerDetect.Kind kind)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected I4, but got Unknown
			switch (key - 1)
			{
			case 0:
				return B(ButtonNames.Control.South, kind);
			case 1:
				return B(ButtonNames.Control.West, kind);
			case 13:
				return B(ButtonNames.Control.East, kind);
			case 7:
				return B(ButtonNames.Control.North, kind);
			case 14:
				return "L3";
			case 11:
				return "R3";
			case 9:
				return B(ButtonNames.Control.RT, kind);
			case 10:
				return B(ButtonNames.Control.LT, kind);
			case 5:
				return B(ButtonNames.Control.Start, kind);
			case 6:
				return B(ButtonNames.Control.Select, kind);
			case 18:
				return B(ButtonNames.Control.DpadLeft, kind);
			case 19:
				return B(ButtonNames.Control.DpadUp, kind);
			case 20:
				return B(ButtonNames.Control.DpadRight, kind);
			case 3:
				return B(ButtonNames.Control.RB, kind);
			case 4:
				return B(ButtonNames.Control.LB, kind);
			case 25:
			case 26:
			case 27:
			case 28:
			case 29:
			case 30:
				return B(ButtonNames.Control.DpadDown, kind) + " (wheel)";
			default:
				return null;
			}
		}

		private static string B(ButtonNames.Control c, ControllerDetect.Kind kind)
		{
			return ButtonNames.Of(c, kind);
		}

		internal static void TickCacheInvalidation()
		{
			if (!Plugin.Enabled.Value || !Plugin.ControllerKeyTags.Value)
			{
				return;
			}
			bool flag = ControllerDetect.PadActive && Gamepad.current != null;
			if (flag == _lastControllerActive)
			{
				return;
			}
			_lastControllerActive = flag;
			try
			{
				ItemAttributes[] array = Object.FindObjectsOfType<ItemAttributes>();
				foreach (ItemAttributes val in array)
				{
					ItemTagRef.Invoke(val) = "";
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("[Prompts] item tag cache clear failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(InputManager))]
	internal static class LookPatch
	{
		private const float AimSpeedFloor = 0.0001f;

		[HarmonyPatch("GetMouseX")]
		[HarmonyPostfix]
		public static void GetMouseXPostfix(ref float __result)
		{
			//IL_0024: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00ae: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00c2: 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)
			//IL_00e6: 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_00ea: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Enabled.Value || EmoteWheel.Open)
			{
				return;
			}
			Gamepad current = Gamepad.current;
			if (current != null)
			{
				float num = Deadzone(((InputControl<Vector2>)(object)current.rightStick).ReadValue().x);
				if (Plugin.InvertX.Value)
				{
					num = 0f - num;
				}
				__result += num * Plugin.LookSpeedX.Value;
			}
			if (!Plugin.AimAssistEnabled.Value || !AimAssist.HasTarget)
			{
				return;
			}
			CameraAim instance = CameraAim.Instance;
			Camera main = Camera.main;
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)main == (Object)null))
			{
				Vector3 forward = ((Component)main).transform.forward;
				Vector3 val = AimAssist.TargetPosition - ((Component)main).transform.position;
				Vector3 val2 = Vector3.ProjectOnPlane(forward, Vector3.up);
				Vector3 val3 = Vector3.ProjectOnPlane(val, Vector3.up);
				if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f) && !(((Vector3)(ref val3)).sqrMagnitude < 0.0001f))
				{
					float axisErrDeg = Vector3.SignedAngle(val2, val3, Vector3.up);
					float totalErrDeg = Vector3.Angle(forward, val);
					__result += Correction(axisErrDeg, totalErrDeg, __result, instance.AimSpeedMouse);
				}
			}
		}

		[HarmonyPatch("GetMouseY")]
		[HarmonyPostfix]
		public static void GetMouseYPostfix(ref float __result)
		{
			//IL_0024: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.Enabled.Value || EmoteWheel.Open)
			{
				return;
			}
			Gamepad current = Gamepad.current;
			if (current != null)
			{
				float num = Deadzone(((InputControl<Vector2>)(object)current.rightStick).ReadValue().y);
				if (Plugin.InvertY.Value)
				{
					num = 0f - num;
				}
				__result += num * Plugin.LookSpeedY.Value;
			}
			if (Plugin.AimAssistEnabled.Value && AimAssist.HasTarget)
			{
				CameraAim instance = CameraAim.Instance;
				Camera main = Camera.main;
				if (!((Object)(object)instance == (Object)null) && !((Object)(object)main == (Object)null))
				{
					Vector3 forward = ((Component)main).transform.forward;
					Vector3 val = AimAssist.TargetPosition - ((Component)main).transform.position;
					float num2 = Mathf.Asin(Mathf.Clamp(((Vector3)(ref val)).normalized.y, -1f, 1f)) * 57.29578f;
					float num3 = Mathf.Asin(Mathf.Clamp(((Vector3)(ref forward)).normalized.y, -1f, 1f)) * 57.29578f;
					float axisErrDeg = num2 - num3;
					float totalErrDeg = Vector3.Angle(forward, val);
					__result += Correction(axisErrDeg, totalErrDeg, __result, instance.AimSpeedMouse);
				}
			}
		}

		private static float Correction(float axisErrDeg, float totalErrDeg, float playerResult, float aimSpeed)
		{
			aimSpeed = Mathf.Max(0.0001f, aimSpeed);
			float value = Plugin.AimAssistDeadZone.Value;
			float value2 = Plugin.AimAssistMaxAngle.Value;
			float num = ((totalErrDeg <= value) ? 0f : ((!(totalErrDeg >= value2)) ? Mathf.SmoothStep(0f, 1f, (totalErrDeg - value) / Mathf.Max(0.001f, value2 - value)) : 1f));
			if (num <= 0f)
			{
				return 0f;
			}
			float num2 = Plugin.AimAssistGain.Value * axisErrDeg * num;
			float num3 = Mathf.Abs(playerResult) * aimSpeed;
			float num4 = ((!(num3 > Plugin.AimAssistActiveThreshold.Value)) ? Mathf.Min(Plugin.AimAssistIdleDrift.Value * num, Plugin.AimAssistMaxDegPerFrame.Value) : Mathf.Min(Plugin.AimAssistMaxFraction.Value * num3, Plugin.AimAssistMaxDegPerFrame.Value));
			return Mathf.Clamp(num2, 0f - num4, num4) / aimSpeed;
		}

		private static float Deadzone(float v)
		{
			float value = Plugin.StickDeadzone.Value;
			if (!(Mathf.Abs(v) < value))
			{
				return v;
			}
			return 0f;
		}
	}
	[HarmonyPatch(typeof(MenuButton), "ProcessHover")]
	internal static class MenuButtonHoverPatch
	{
		private static readonly FieldRef<MenuButton, bool> HoveringRef = AccessTools.FieldRefAccess<MenuButton, bool>("hovering");

		private static readonly FieldInfo ButtonTextField = AccessTools.Field(typeof(MenuButton), "buttonText");

		private static PropertyInfo s_colorProp;

		[HarmonyPostfix]
		public static void Postfix(MenuButton __instance)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (!MenuNavigator.ControllerActive)
			{
				return;
			}
			bool flag = __instance == MenuNavigator.Selected;
			HoveringRef.Invoke(__instance) = flag;
			object obj = ((ButtonTextField != null) ? ButtonTextField.GetValue(__instance) : null);
			if (obj != null)
			{
				if (s_colorProp == null)
				{
					s_colorProp = obj.GetType().GetProperty("color");
				}
				s_colorProp?.SetValue(obj, flag ? __instance.colorHover : __instance.colorNormal);
			}
			if (flag)
			{
				__instance.OnHovering();
			}
		}
	}
	internal class MenuNavigator : MonoBehaviour
	{
		private static readonly FieldRef<MenuManager, int> StateRef = AccessTools.FieldRefAccess<MenuManager, int>("currentMenuState");

		private static readonly FieldRef<MenuManager, List<MenuButton>> ButtonsRef = AccessTools.FieldRefAccess<MenuManager, List<MenuButton>>("allMenuButtons");

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

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

		private static readonly FieldRef<MenuPage, bool> AddedOnTopRef = AccessTools.FieldRefAccess<MenuPage, bool>("addedPageOnTop");

		private static readonly FieldRef<MenuButton, MenuPage> ParentPageRef = AccessTools.FieldRefAccess<MenuButton, MenuPage>("parentPage");

		private static readonly FieldRef<MenuButton, bool> DisabledRef = AccessTools.FieldRefAccess<MenuButton, bool>("disabled");

		private static readonly FieldRef<MenuButton, bool> HoveringRef = AccessTools.FieldRefAccess<MenuButton, bool>("hovering");

		private static readonly FieldRef<MenuPage, PageState> PageStateRef = AccessTools.FieldRefAccess<MenuPage, PageState>("currentPageState");

		private static readonly MethodInfo OnSelectMethod = AccessTools.Method(typeof(MenuButton), "OnSelect", (Type[])null, (Type[])null);

		private static readonly FieldInfo ButtonTextField = AccessTools.Field(typeof(MenuButton), "buttonText");

		private static PropertyInfo s_textProp;

		private static readonly Vector3[] s_corners = (Vector3[])(object)new Vector3[4];

		internal static MenuButton Selected;

		internal static bool ControllerActive;

		private MenuButton _selected;

		private bool _active;

		private float _navCooldown;

		private GUIStyle _style;

		private MenuPage _focusPage;

		private MenuPage _focusOverride;

		private MenuPage _lastTop;

		private readonly Dictionary<MenuPage, MenuButton> _lastByPage = new Dictionary<MenuPage, MenuButton>();

		private static FieldInfo s_repoLastClicked;

		private static bool s_repoLookupDone;

		private bool MenuOpen(out MenuManager mm)
		{
			mm = MenuManager.instance;
			if ((Object)(object)mm != (Object)null)
			{
				return StateRef.Invoke(mm) == 0;
			}
			return false;
		}

		private void Update()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			ControllerActive = false;
			Selected = null;
			if (!Plugin.Enabled.Value)
			{
				return;
			}
			Gamepad current = Gamepad.current;
			if (current == null)
			{
				return;
			}
			if (!MenuOpen(out var mm))
			{
				_selected = null;
				_focusOverride = null;
				_focusPage = null;
				_lastTop = null;
				_lastByPage.Clear();
				return;
			}
			ResolveFocus(mm);
			List<MenuButton> list = Candidates(mm, _focusPage);
			if (list.Count == 0)
			{
				_selected = null;
				return;
			}
			if (AnyControllerInput(current))
			{
				_active = true;
			}
			if (Mouse.current != null)
			{
				Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).delta).ReadValue();
				if (((Vector2)(ref val)).sqrMagnitude > 4f)
				{
					_active = false;
				}
			}
			if (_active)
			{
				if ((Object)(object)_selected == (Object)null || !list.Contains(_selected))
				{
					_selected = Reseed(list);
				}
				HandleNavigation(current, list);
				if (current.buttonSouth.wasPressedThisFrame)
				{
					Select(_selected);
				}
				if (current.buttonEast.wasPressedThisFrame)
				{
					Back(list);
				}
				if ((Object)(object)_focusPage != (Object)null && (Object)(object)_selected != (Object)null)
				{
					_lastByPage[_focusPage] = _selected;
				}
				Selected = _selected;
				ControllerActive = true;
			}
			else
			{
				MenuButton val2 = ((IEnumerable<MenuButton>)list).FirstOrDefault((Func<MenuButton, bool>)((MenuButton b) => HoveringRef.Invoke(b)));
				if ((Object)(object)val2 != (Object)null)
				{
					_selected = val2;
				}
			}
		}

		private static bool AnyControllerInput(Gamepad gp)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (!gp.dpad.up.isPressed && !gp.dpad.down.isPressed && !gp.dpad.left.isPressed && !gp.dpad.right.isPressed)
			{
				Vector2 val = ((InputControl<Vector2>)(object)gp.leftStick).ReadValue();
				if (!(((Vector2)(ref val)).sqrMagnitude > 0.2f) && !gp.buttonSouth.wasPressedThisFrame && !gp.buttonEast.wasPressedThisFrame)
				{
					return gp.selectButton.wasPressedThisFrame;
				}
			}
			return true;
		}

		private MenuPage DefaultFocus(MenuManager mm)
		{
			List<MenuPage> list = AddedPagesRef.Invoke(mm);
			if (list != null)
			{
				for (int num = list.Count - 1; num >= 0; num--)
				{
					if (IsFocusableAdded(list[num]))
					{
						return list[num];
					}
				}
			}
			return CurrentPageRef.Invoke(mm);
		}

		private bool IsLive(MenuManager mm, MenuPage p)
		{
			if ((Object)(object)p == (Object)null)
			{
				return false;
			}
			if ((Object)(object)p == (Object)(object)CurrentPageRef.Invoke(mm))
			{
				return IsActivePage(p);
			}
			List<MenuPage> list = AddedPagesRef.Invoke(mm);
			if (list != null && list.Contains(p))
			{
				return IsFocusableAdded(p);
			}
			return false;
		}

		private void ResolveFocus(MenuManager mm)
		{
			MenuPage val = DefaultFocus(mm);
			if ((Object)(object)val != (Object)(object)_lastTop)
			{
				_focusOverride = null;
				_lastTop = val;
			}
			if ((Object)(object)_focusOverride != (Object)null && !IsLive(mm, _focusOverride))
			{
				_focusOverride = null;
			}
			MenuPage val2 = _focusOverride ?? val;
			if ((Object)(object)val2 != (Object)(object)_focusPage)
			{
				_focusPage = val2;
				_selected = null;
			}
		}

		private List<MenuButton> Candidates(MenuManager mm, MenuPage focus)
		{
			List<MenuButton> list = ButtonsRef.Invoke(mm);
			List<MenuButton> list2 = new List<MenuButton>();
			if (list == null)
			{
				return list2;
			}
			if ((Object)(object)focus != (Object)null)
			{
				foreach (MenuButton item in list)
				{
					if (Usable(item))
					{
						MenuPage val = ParentPageRef.Invoke(item);
						if ((Object)(object)val == (Object)(object)focus || ((Object)(object)val == (Object)null && (Object)(object)((Component)item).GetComponentInParent<MenuPage>() == (Object)(object)focus))
						{
							list2.Add(item);
						}
					}
				}
				if (list2.Count > 0)
				{
					AddCulledScrollRows(list2);
					return list2;
				}
			}
			foreach (MenuButton item2 in list)
			{
				if (Usable(item2))
				{
					MenuPage val2 = ParentPageRef.Invoke(item2);
					if ((Object)(object)val2 == (Object)null || AddedOnTopRef.Invoke(val2) || IsActivePage(val2))
					{
						list2.Add(item2);
					}
				}
			}
			return list2;
		}

		private static void AddCulledScrollRows(List<MenuButton> list)
		{
			MenuScrollBox val = null;
			for (int i = 0; i < list.Count; i++)
			{
				val = ((Component)list[i]).GetComponentInParent<MenuScrollBox>();
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val.scroller == (Object)null)
			{
				return;
			}
			MenuButton[] componentsInChildren = ((Component)val.scroller).GetComponentsInChildren<MenuButton>(true);
			foreach (MenuButton val2 in componentsInChildren)
			{
				if (Usable(val2) && !list.Contains(val2))
				{
					list.Add(val2);
				}
			}
		}

		private List<MenuButton> PageButtons(MenuManager mm, MenuPage page)
		{
			List<MenuButton> list = ButtonsRef.Invoke(mm);
			List<MenuButton> list2 = new List<MenuButton>();
			if (list == null)
			{
				return list2;
			}
			foreach (MenuButton item in list)
			{
				if (Usable(item) && (Object)(object)ParentPageRef.Invoke(item) == (Object)(object)page)
				{
					list2.Add(item);
				}
			}
			return list2;
		}

		private static bool Usable(MenuButton b)
		{
			if ((Object)(object)b != (Object)null && !DisabledRef.Invoke(b))
			{
				return (Object)(object)b.rectTransformSelection != (Object)null;
			}
			return false;
		}

		private static bool IsActivePage(MenuPage p)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			if ((Object)(object)p == (Object)null)
			{
				return true;
			}
			PageState val = PageStateRef.Invoke(p);
			if ((int)val != 3)
			{
				return (int)val != 2;
			}
			return false;
		}

		private static bool IsFocusableAdded(MenuPage p)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			if ((Object)(object)p == (Object)null)
			{
				return false;
			}
			PageState val = PageStateRef.Invoke(p);
			if ((int)val != 2)
			{
				return (int)val != 5;
			}
			return false;
		}

		private static string Label(MenuButton b)
		{
			if ((Object)(object)b == (Object)null)
			{
				return "<null>";
			}
			object obj = ((ButtonTextField != null) ? ButtonTextField.GetValue(b) : null);
			if (obj != null)
			{
				if (s_textProp == null)
				{
					s_textProp = obj.GetType().GetProperty("text");
				}
				if (s_textProp?.GetValue(obj) is string text && !string.IsNullOrEmpty(text))
				{
					return text;
				}
			}
			return ((Object)((Component)b).gameObject).name;
		}

		private static Vector2 ScreenPos(MenuButton b)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)b).transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val != (Object)null)
			{
				val.GetWorldCorners(s_corners);
				Vector3 val2 = (s_corners[0] + s_corners[2]) * 0.5f;
				return new Vector2(val2.x, val2.y);
			}
			Vector3 position = ((Component)b).transform.position;
			return new Vector2(position.x, position.y);
		}

		private static MenuButton Topmost(List<MenuButton> c)
		{
			return (from b in c
				orderby ScreenPos(b).y descending, ScreenPos(b).x
				select b).First();
		}

		private MenuButton Reseed(List<MenuButton> candidates)
		{
			if ((Object)(object)_focusPage != (Object)null && _lastByPage.TryGetValue(_focusPage, out var value) && (Object)(object)value != (Object)null && candidates.Contains(value))
			{
				return value;
			}
			return Topmost(candidates);
		}

		private void HandleNavigation(Gamepad gp, List<MenuButton> candidates)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//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_00b4: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: 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_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			if (_navCooldown > 0f)
			{
				_navCooldown -= Time.deltaTime;
			}
			Vector2 val = new Vector2((gp.dpad.right.isPressed ? 1f : 0f) - (gp.dpad.left.isPressed ? 1f : 0f), (gp.dpad.up.isPressed ? 1f : 0f) - (gp.dpad.down.isPressed ? 1f : 0f)) + ((InputControl<Vector2>)(object)gp.leftStick).ReadValue();
			if (((Vector2)(ref val)).magnitude < 0.4f)
			{
				_navCooldown = 0f;
			}
			else
			{
				if (_navCooldown > 0f)
				{
					return;
				}
				_navCooldown = 0.22f;
				Vector2 val2 = ((Mathf.Abs(val.x) > Mathf.Abs(val.y)) ? new Vector2(Mathf.Sign(val.x), 0f) : new Vector2(0f, Mathf.Sign(val.y)));
				MenuScrollBox box = (((Object)(object)_selected != (Object)null) ? ((Component)_selected).GetComponentInParent<MenuScrollBox>() : null);
				MenuButton val3 = null;
				if ((Object)(object)box != (Object)null)
				{
					val3 = NearestInDirection(candidates.Where((MenuButton b) => (Object)(object)((Component)b).GetComponentInParent<MenuScrollBox>() == (Object)(object)box).ToList(), _selected, val2);
				}
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = NearestInDirection(candidates, _selected, val2);
				}
				if ((!((Object)(object)val3 == (Object)null) || !(Mathf.Abs(val2.x) > 0.5f) || !TrySwitchPanel((!(val2.x < 0f)) ? 1 : (-1))) && (Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)_selected)
				{
					_selected = val3;
					ScrollIntoView(val3);
					if ((Object)(object)MenuManager.instance != (Object)null)
					{
						MenuManager.instance.MenuEffectHover(-1f, -1f);
					}
				}
			}
		}

		private bool TrySwitchPanel(int sign)
		{
			MenuManager instance = MenuManager.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			MenuPage val = CurrentPageRef.Invoke(instance);
			MenuPage val2 = DefaultFocus(instance);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val == (Object)null || (Object)(object)val2 == (Object)(object)val)
			{
				return false;
			}
			MenuPage val3 = ((sign >= 0) ? (((Object)(object)_focusPage != (Object)(object)val2) ? val2 : null) : (((Object)(object)_focusPage == (Object)(object)val2) ? val : null));
			if ((Object)(object)val3 == (Object)null)
			{
				return false;
			}
			List<MenuButton> list = PageButtons(instance, val3);
			if (list.Count == 0)
			{
				return false;
			}
			_focusOverride = val3;
			_focusPage = val3;
			_selected = Reseed(list);
			ScrollIntoView(_selected);
			if ((Object)(object)MenuManager.instance != (Object)null)
			{
				MenuManager.instance.MenuEffectHover(-1f, -1f);
			}
			return true;
		}

		private static void ScrollIntoView(MenuButton b)
		{
			if ((Object)(object)b == (Object)null)
			{
				return;
			}
			MenuScrollBox componentInParent = ((Component)b).GetComponentInParent<MenuScrollBox>();
			if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent.scroller == (Object)null))
			{
				Transform val = ((Component)b).transform;
				while ((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)(object)componentInParent.scroller)
				{
					val = val.parent;
				}
				RectTransform val2 = (RectTransform)(((object)((val is RectTransform) ? val : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/));
				componentInParent.ScrollToChild(val2, 0f);
			}
		}

		private static MenuButton NearestInDirection(List<MenuButton> candidates, MenuButton from, Vector2 dir)
		{
			//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_00d2: 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_00d8: 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_00df: 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_00ed: 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_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)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_016a: Unknown result typ