Decompiled source of Menu Overhaul v1.0.2

MenuOverhaul.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using InControl;
using LevelEditor;
using SFQoL;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.PostProcessing;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyCompany("MenuOverhaul")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+2249409fdb523b9ec820643cddfc880e7a556439")]
[assembly: AssemblyProduct("MenuOverhaul")]
[assembly: AssemblyTitle("MenuOverhaul")]
[assembly: AssemblyVersion("1.0.1.0")]
namespace SFQoL
{
	internal static class Compat
	{
		private static bool searched;

		private static FieldInfo roundsActive;

		private static PropertyInfo roundsArmed;

		private static FieldInfo cardPicking;

		private static bool cardSearched;

		public static bool Rounds
		{
			get
			{
				Find();
				try
				{
					if ((object)roundsArmed != null && (bool)roundsArmed.GetValue(null, null))
					{
						return true;
					}
					if ((object)roundsActive != null && (bool)roundsActive.GetValue(null))
					{
						return true;
					}
				}
				catch
				{
				}
				return false;
			}
		}

		public static bool CardScreen
		{
			get
			{
				if (!cardSearched)
				{
					Type type = RoundsType("StickRounds.CardPick");
					cardSearched = (object)type != null || Time.frameCount > 1;
					if ((object)type != null)
					{
						cardPicking = type.GetField("Picking", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					}
				}
				try
				{
					return (object)cardPicking != null && (bool)cardPicking.GetValue(null);
				}
				catch
				{
					return false;
				}
			}
		}

		public static bool RoundsMatch
		{
			get
			{
				Find();
				try
				{
					return (object)roundsActive != null && (bool)roundsActive.GetValue(null) && !GameManager.stillInMenu;
				}
				catch
				{
					return false;
				}
			}
		}

		private static Type RoundsType(string name)
		{
			if (!Chainloader.PluginInfos.TryGetValue("stickfight.stickrounds", out var value) || (Object)(object)value.Instance == (Object)null)
			{
				return null;
			}
			return ((object)value.Instance).GetType().Assembly.GetType(name, throwOnError: false);
		}

		private static void Find()
		{
			if (!searched)
			{
				Type type = RoundsType("StickRounds.RoundsMode");
				searched = (object)type != null || Time.frameCount > 1;
				if ((object)type != null)
				{
					roundsActive = type.GetField("Active", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
					roundsArmed = type.GetProperty("Armed", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				}
			}
		}

		public static bool IsBotDevice(InputDevice d)
		{
			if (d != null)
			{
				return ((object)d).GetType().Name == "BotDevice";
			}
			return false;
		}
	}
	internal static class QolConfig
	{
		public static ConfigEntry<bool> Enabled(ConfigFile config, string section, string description)
		{
			return config.Bind<bool>(section, "Enabled", true, description);
		}

		private static Dictionary<ConfigDefinition, string> Orphans(ConfigFile config)
		{
			return Traverse.Create((object)config).Property("OrphanedEntries", (object[])null).GetValue<Dictionary<ConfigDefinition, string>>();
		}

		public static string Old(ConfigFile config, string section, string key)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			Dictionary<ConfigDefinition, string> dictionary = Orphans(config);
			if (dictionary == null || !dictionary.TryGetValue(new ConfigDefinition(section, key), out var value))
			{
				return null;
			}
			return value;
		}

		public static void SetOld(ConfigFile config, string section, string key, string value)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			Dictionary<ConfigDefinition, string> dictionary = Orphans(config);
			if (dictionary != null)
			{
				dictionary[new ConfigDefinition(section, key)] = value;
			}
		}

		public static void DropOld(ConfigFile config)
		{
			Dictionary<ConfigDefinition, string> dictionary = Orphans(config);
			if (dictionary != null && dictionary.Count != 0)
			{
				dictionary.Clear();
				config.Save();
			}
		}
	}
	internal static class Ui
	{
		public static readonly Color Panel = new Color(0.176f, 0.176f, 0.176f);

		public static readonly Color Strip = new Color(0.147f, 0.147f, 0.147f);

		public static readonly Color Item = new Color(0.265f, 0.265f, 0.265f);

		public static readonly Color Grey = new Color(0.6f, 0.6f, 0.6f);

		private static TMP_FontAsset font;

		private static Sprite box;

		private static bool boxSearched;

		private static Camera menuCam;

		private static float menuCamSearchAt;

		public static TMP_FontAsset Font
		{
			get
			{
				if ((Object)(object)font == (Object)null)
				{
					GameManager instance = GameManager.Instance;
					if ((Object)(object)instance != (Object)null && (Object)(object)instance.winText != (Object)null)
					{
						font = ((TMP_Text)instance.winText).font;
					}
					if ((Object)(object)font == (Object)null)
					{
						TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
						foreach (TMP_FontAsset val in array)
						{
							if (((Object)val).name.StartsWith("Anton"))
							{
								font = val;
								break;
							}
						}
					}
				}
				return font;
			}
		}

		public static Sprite BoxSprite
		{
			get
			{
				if ((Object)(object)box == (Object)null && !boxSearched)
				{
					boxSearched = true;
					Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>();
					foreach (Sprite val in array)
					{
						if (((Object)val).name == "box")
						{
							box = val;
							break;
						}
					}
				}
				return box;
			}
		}

		public static int MenuLayer
		{
			get
			{
				int num = LayerMask.NameToLayer("MENU");
				if (num < 0)
				{
					return 31;
				}
				return num;
			}
		}

		public static void Attach(Canvas c)
		{
			//IL_00dd: 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_00aa: Invalid comparison between Unknown and I4
			if ((Object)(object)c == (Object)null)
			{
				return;
			}
			if (((Object)(object)menuCam == (Object)null || !((Behaviour)menuCam).isActiveAndEnabled) && Time.unscaledTime >= menuCamSearchAt)
			{
				menuCamSearchAt = Time.unscaledTime + 1f;
				menuCam = null;
				Camera[] allCameras = Camera.allCameras;
				foreach (Camera val in allCameras)
				{
					if (((Object)val).name == "Camera_Pause" && (val.cullingMask & (1 << MenuLayer)) != 0)
					{
						menuCam = val;
						break;
					}
				}
			}
			if ((Object)(object)menuCam != (Object)null && ((Behaviour)menuCam).isActiveAndEnabled)
			{
				if ((int)c.renderMode != 1 || (Object)(object)c.worldCamera != (Object)(object)menuCam)
				{
					c.renderMode = (RenderMode)1;
					c.worldCamera = menuCam;
					c.planeDistance = 1f;
				}
			}
			else if ((int)c.renderMode != 0)
			{
				c.renderMode = (RenderMode)0;
			}
		}

		public static Canvas MakeCanvas(string name, int order)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name)
			{
				layer = MenuLayer
			};
			Object.DontDestroyOnLoad((Object)val);
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)0;
			val2.sortingOrder = order;
			Attach(val2);
			CanvasScaler obj = val.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)1;
			obj.referenceResolution = new Vector2(1920f, 1080f);
			obj.matchWidthOrHeight = 0.5f;
			return val2;
		}

		public static RectTransform Rect(Transform parent, string name)
		{
			//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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0076: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) })
			{
				layer = ((Component)parent).gameObject.layer
			};
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			val2.anchorMax = val3;
			val2.anchorMin = val3;
			val2.pivot = new Vector2(0.5f, 0.5f);
			return val2;
		}

		public static Image Box(Transform parent, string name, Color color, Vector2 pos, Vector2 size, bool rounded = false)
		{
			//IL_0008: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = Rect(parent, name);
			obj.anchoredPosition = pos;
			obj.sizeDelta = size;
			Image val = ((Component)obj).gameObject.AddComponent<Image>();
			((Graphic)val).color = color;
			((Graphic)val).raycastTarget = false;
			if (rounded && (Object)(object)BoxSprite != (Object)null)
			{
				val.sprite = BoxSprite;
				Vector4 border = BoxSprite.border;
				if (((Vector4)(ref border)).sqrMagnitude > 0f)
				{
					val.type = (Type)1;
				}
			}
			return val;
		}

		public static void Fill(RectTransform rt, float inset)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: 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)
			rt.anchorMin = Vector2.zero;
			rt.anchorMax = Vector2.one;
			rt.offsetMin = new Vector2(inset, inset);
			rt.offsetMax = new Vector2(0f - inset, 0f - inset);
		}

		public static TextMeshProUGUI Text(Transform parent, string name, string text, float size, Color color, TextAlignmentOptions align)
		{
			//IL_0032: 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)
			TextMeshProUGUI val = ((Component)Rect(parent, name)).gameObject.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)Font != (Object)null)
			{
				((TMP_Text)val).font = Font;
			}
			((TMP_Text)val).fontSize = size;
			((Graphic)val).color = color;
			((TMP_Text)val).alignment = align;
			((TMP_Text)val).enableWordWrapping = false;
			((TMP_Text)val).richText = true;
			((Graphic)val).raycastTarget = false;
			((TMP_Text)val).text = text;
			return val;
		}

		public static Color PlayerColor(Controller c)
		{
			//IL_00bf: 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_0065: 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)
			if ((Object)(object)c != (Object)null)
			{
				SpriteRenderer componentInChildren = ((Component)c).GetComponentInChildren<SpriteRenderer>();
				SetColorWhenDamaged val = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).GetComponent<SetColorWhenDamaged>() : null);
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)c).GetComponentInChildren<SetColorWhenDamaged>(true);
				}
				if ((Object)(object)val != (Object)null && val.startColor.a > 0f)
				{
					Color startColor = val.startColor;
					startColor.a = 1f;
					return startColor;
				}
				ControllerHandler instance = ControllerHandler.Instance;
				if ((Object)(object)instance != (Object)null && instance.colors != null && c.playerID >= 0 && c.playerID < instance.colors.Length && (Object)(object)instance.colors[c.playerID] != (Object)null)
				{
					return instance.colors[c.playerID].color;
				}
			}
			return Color.white;
		}

		public static Color SlotColor(int id)
		{
			//IL_0052: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			ControllerHandler instance = ControllerHandler.Instance;
			if ((Object)(object)instance != (Object)null && instance.colors != null && id >= 0 && id < instance.colors.Length && (Object)(object)instance.colors[id] != (Object)null)
			{
				Color color = instance.colors[id].color;
				color.a = 1f;
				return color;
			}
			return Color.white;
		}

		public static string Hex(Color c)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			return "#" + ((int)(Mathf.Clamp01(c.r) * 255f)).ToString("X2") + ((int)(Mathf.Clamp01(c.g) * 255f)).ToString("X2") + ((int)(Mathf.Clamp01(c.b) * 255f)).ToString("X2");
		}

		public static string Colored(string text, Color c)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return "<color=" + Hex(c) + ">" + text + "</color>";
		}

		public static Color WithAlpha(Color c, float a)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			c.a = a;
			return c;
		}
	}
}
namespace MenuOverhaul
{
	internal static class Fixes
	{
		[HarmonyPatch(typeof(PauseManager), "Pause")]
		private static class ResetEditorButton
		{
			private static void Prefix(PauseManager __instance)
			{
				Transform val = (((Object)(object)__instance.pauseMenu != (Object)null) ? __instance.pauseMenu.transform : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				Transform val2 = ((((Object)val).name == "Buttons") ? val : FindDeep(((Object)(object)val.parent != (Object)null) ? val.parent : val, "Buttons"));
				if (!((Object)(object)val2 == (Object)null))
				{
					Transform val3 = val2.Find("Editor");
					Transform val4 = val2.Find("EditorConfirmation");
					if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val4 == (Object)null) && ((Component)val4).gameObject.activeSelf)
					{
						((Component)val4).gameObject.SetActive(false);
						((Component)val3).gameObject.SetActive(true);
					}
				}
			}

			private static Transform FindDeep(Transform t, string name)
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Expected O, but got Unknown
				if (((Object)t).name == name)
				{
					return t;
				}
				foreach (Transform item in t)
				{
					Transform val = FindDeep(item, name);
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
				return null;
			}
		}

		internal static Runner Host;

		private static readonly List<KeyValuePair<TMP_Text, bool>> bumperHints = new List<KeyValuePair<TMP_Text, bool>>();

		private static InputDeviceStyle hintStyle = (InputDeviceStyle)(-1);

		public static void TickHints()
		{
			//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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if (!PauseManager.isPaused || bumperHints.Count == 0)
			{
				return;
			}
			InputDeviceStyle pauserStyle = PauseLock.PauserStyle;
			if (pauserStyle == hintStyle)
			{
				return;
			}
			hintStyle = pauserStyle;
			foreach (KeyValuePair<TMP_Text, bool> bumperHint in bumperHints)
			{
				if ((Object)(object)bumperHint.Key != (Object)null)
				{
					bumperHint.Key.text = PadLayout.Name((InputControlType)(bumperHint.Value ? 17 : 18), pauserStyle);
				}
			}
		}

		public static void SelectLater(GameObject go)
		{
			if ((Object)(object)Host != (Object)null && (Object)(object)go != (Object)null)
			{
				((MonoBehaviour)Host).StartCoroutine(Select(go));
			}
		}

		private static IEnumerator Select(GameObject go)
		{
			yield return (object)new WaitForEndOfFrame();
			if ((Object)(object)go != (Object)null && go.activeInHierarchy && (Object)(object)EventSystem.current != (Object)null)
			{
				EventSystem.current.SetSelectedGameObject(go);
			}
		}

		internal static Transform Find(Transform root, string path)
		{
			if (!((Object)(object)root != (Object)null))
			{
				return null;
			}
			return root.Find(path);
		}

		internal static Transform Grid(Transform root, string row)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (((Object)val).name == "Grid" && (Object)(object)val.Find(row) != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		public static void Setup(PauseManager pm)
		{
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)pm).transform.Find("Menu");
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Pause menu not found.");
				return;
			}
			TMP_Text[] componentsInChildren = ((Component)val).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val2 in componentsInChildren)
			{
				if (val2.text != null)
				{
					string text = val2.text.Trim();
					if (text == "Game Options")
					{
						text = "GAME OPTIONS";
					}
					if (text == "GAME SETTINGS" && (Object)(object)val2.transform.parent != (Object)null && (Object)(object)val2.transform.parent.parent != (Object)null && ((Object)val2.transform.parent.parent).name == "Options" && (Object)(object)val2.transform.parent.parent.parent != (Object)null && ((Object)val2.transform.parent.parent.parent).name == "GameSettingsMask")
					{
						text = "GAME OPTIONS";
					}
					if (text != val2.text)
					{
						val2.text = text;
					}
				}
			}
			((MonoBehaviour)Host).StartCoroutine(MatchButtonText(val));
			bumperHints.Clear();
			hintStyle = (InputDeviceStyle)(-1);
			componentsInChildren = ((Component)val).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val3 in componentsInChildren)
			{
				if (val3.text == "LB" || val3.text == "RB")
				{
					bumperHints.Add(new KeyValuePair<TMP_Text, bool>(val3, val3.text == "LB"));
				}
			}
			Transform val4 = Find(val, "Mask/Buttons/EditorConfirmation");
			Transform val5 = Find(val, "Mask/Buttons/Editor");
			if ((Object)(object)val4 != (Object)null && (Object)(object)val5 != (Object)null && (Object)(object)((Component)val4).GetComponent<EditorUnconfirm>() == (Object)null)
			{
				((Component)val4).gameObject.AddComponent<EditorUnconfirm>().Editor = ((Component)val5).gameObject;
			}
			Transform root = Find(val, "GameSettingsMask/Options/Grid");
			Selectable val6 = Sel(Find(root, "Maps/OptionsButton"));
			Selectable val7 = Sel(Find(root, "Back/Button"));
			if ((Object)(object)val6 != (Object)null && (Object)(object)val7 != (Object)null)
			{
				Link(val6, val7);
				Link(val7, null, val6);
			}
		}

		public static void AddSliders(PauseManager pm)
		{
			Transform val = ((Component)pm).transform.Find("Menu");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			OptionsButton[] componentsInChildren = ((Component)val).GetComponentsInChildren<OptionsButton>(true);
			foreach (OptionsButton b in componentsInChildren)
			{
				if (Sliders.IsPercent(b))
				{
					Sliders.Add(b);
				}
			}
		}

		private static IEnumerator MatchButtonText(Transform menu)
		{
			yield return null;
			yield return null;
			TMP_Text val = Text(Find(menu, "Mask/Buttons/GameSettings"));
			TMP_Text val2 = Text(Find(menu, "Mask/Buttons/Keybindings"));
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
			{
				val.ForceMeshUpdate();
				val2.ForceMeshUpdate();
				float fontSize = Mathf.Min(val.fontSize, val2.fontSize);
				val.enableAutoSizing = false;
				val2.enableAutoSizing = false;
				val.fontSize = fontSize;
				val2.fontSize = fontSize;
			}
		}

		private static TMP_Text Text(Transform t)
		{
			if (!((Object)(object)t != (Object)null))
			{
				return null;
			}
			return ((Component)t).GetComponentInChildren<TMP_Text>(true);
		}

		private static Selectable Sel(Transform t)
		{
			if (!((Object)(object)t != (Object)null))
			{
				return null;
			}
			return ((Component)t).GetComponent<Selectable>();
		}

		private static void Link(Selectable s, Selectable up = null, Selectable down = null, Selectable left = null, Selectable right = null, bool clearSides = false)
		{
			//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_005c: Unknown result type (might be due to invalid IL or missing references)
			Navigation navigation = s.navigation;
			((Navigation)(ref navigation)).mode = (Mode)4;
			if ((Object)(object)up != (Object)null)
			{
				((Navigation)(ref navigation)).selectOnUp = up;
			}
			if ((Object)(object)down != (Object)null)
			{
				((Navigation)(ref navigation)).selectOnDown = down;
			}
			if ((Object)(object)left != (Object)null || clearSides)
			{
				((Navigation)(ref navigation)).selectOnLeft = left;
			}
			if ((Object)(object)right != (Object)null || clearSides)
			{
				((Navigation)(ref navigation)).selectOnRight = right;
			}
			s.navigation = navigation;
		}
	}
	internal class Runner : MonoBehaviour
	{
		private readonly Dictionary<TMP_Text, Color> recoloured = new Dictionary<TMP_Text, Color>();

		private readonly HashSet<GameObject> lit = new HashSet<GameObject>();

		private readonly HashSet<GameObject> want = new HashSet<GameObject>();

		private static readonly FieldRef<Selectable, bool> pointerInside = AccessTools.FieldRefAccess<Selectable, bool>("<isPointerInside>k__BackingField");

		private void Update()
		{
			PauseLock.Tick();
			GraphicsMenu.Tick();
			KeybindPage.Tick();
			Label.Tick(GraphicsMenu.Pause);
			Fixes.TickHints();
		}

		private void LateUpdate()
		{
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			EventSystem current = EventSystem.current;
			GameObject val = (((Object)(object)current != (Object)null) ? current.currentSelectedGameObject : null);
			if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<ArrowHandler>() != (Object)null)
			{
				return;
			}
			want.Clear();
			if (PauseManager.isPaused)
			{
				if ((Object)(object)val != (Object)null && NeedsLight(val))
				{
					want.Add(val);
				}
				foreach (Selectable allSelectable in Selectable.allSelectables)
				{
					if ((Object)(object)allSelectable != (Object)null && pointerInside.Invoke(allSelectable) && allSelectable.interactable && NeedsLight(((Component)allSelectable).gameObject))
					{
						want.Add(((Component)allSelectable).gameObject);
					}
				}
			}
			if (want.SetEquals(lit))
			{
				return;
			}
			Restore();
			foreach (GameObject item in want)
			{
				lit.Add(item);
				TMP_Text[] componentsInChildren = item.GetComponentsInChildren<TMP_Text>();
				foreach (TMP_Text val2 in componentsInChildren)
				{
					recoloured[val2] = ((Graphic)val2).color;
					((Graphic)val2).color = new Color(1f, 1f, 1f, ((Graphic)val2).color.a);
				}
			}
		}

		private void Restore()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<TMP_Text, Color> item in recoloured)
			{
				if ((Object)(object)item.Key != (Object)null)
				{
					((Graphic)item.Key).color = item.Value;
				}
			}
			recoloured.Clear();
			lit.Clear();
		}

		private static bool NeedsLight(GameObject go)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00b6: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)GraphicsMenu.Pause == (Object)null || !go.transform.IsChildOf(((Component)GraphicsMenu.Pause).transform))
			{
				return false;
			}
			if ((Object)(object)go.GetComponent<WhiteTextOnHover>() != (Object)null || (Object)(object)go.GetComponent<SlotInput>() != (Object)null)
			{
				return false;
			}
			Selectable component = go.GetComponent<Selectable>();
			if ((Object)(object)component == (Object)null || (int)component.transition != 1 || !(component.targetGraphic is Image) || (Object)(object)((Component)component.targetGraphic).gameObject != (Object)(object)go)
			{
				return false;
			}
			Color color = component.targetGraphic.color;
			ColorBlock colors = component.colors;
			Color val = color * ((ColorBlock)(ref colors)).highlightedColor;
			colors = component.colors;
			Color val2 = val * ((ColorBlock)(ref colors)).colorMultiplier;
			return 0.2126f * val2.r + 0.7152f * val2.g + 0.0722f * val2.b < 0.4f;
		}
	}
	[HarmonyPatch(typeof(PauseManager), "Start")]
	internal static class StartPatch
	{
		private static void Postfix(PauseManager __instance)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Fixes.Host == (Object)null)
			{
				GameObject val = new GameObject("MenuOverhaul");
				Object.DontDestroyOnLoad((Object)val);
				((Object)val).hideFlags = (HideFlags)61;
				Fixes.Host = val.AddComponent<Runner>();
			}
			PauseLock.Release();
			Sliders.Clear();
			Graphics.Find(__instance);
			Fixes.Setup(__instance);
			GraphicsMenu.Build(__instance);
			Label.Build(__instance);
			try
			{
				KeybindPage.Build(__instance);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Couldn't rebuild KEYBINDINGS: " + ex));
			}
			ModPage.Install(__instance);
			MouseNav.Install(((Component)__instance).gameObject);
			PausePage.InstallAll(__instance);
			if ((Object)(object)GraphicsMenu.KeysRow != (Object)null)
			{
				try
				{
					PauseButtons.Remove(__instance, "Keybindings");
				}
				catch (Exception ex2)
				{
					Plugin.Log.LogError((object)("Couldn't fold KEYBINDINGS into OPTIONS: " + ex2));
				}
			}
			Fixes.AddSliders(__instance);
		}
	}
	[HarmonyPatch(typeof(PauseManager), "BackToPause")]
	internal static class BackPatch
	{
		private static GameObject from;

		private static bool Prefix(PauseManager __instance)
		{
			from = null;
			if (!PauseManager.isPaused)
			{
				return true;
			}
			KeybindingButtonHandler val = (((Object)(object)__instance.keybindingMenu != (Object)null) ? __instance.keybindingMenu.GetComponent<KeybindingButtonHandler>() : null);
			if ((Object)(object)val != (Object)null && val.WaitingForInput)
			{
				val.ExitWaitingState();
				return false;
			}
			if (GraphicsMenu.Open)
			{
				GraphicsMenu.ClosePage();
				return false;
			}
			if (ModPage.Showing)
			{
				if (!ModPage.Current.Back())
				{
					return false;
				}
				from = ModPage.Current.ModsButton;
				return true;
			}
			PausePage showing = PausePage.Showing;
			if ((Object)(object)showing != (Object)null)
			{
				if (!showing.Back())
				{
					return false;
				}
				from = showing.OpenButton;
				return true;
			}
			KeybindPage.Closed();
			if (!__instance.keybindingAnim.state1 && (Object)(object)GraphicsMenu.KeysRow != (Object)null)
			{
				__instance.isInKeybindingMenu = false;
				__instance.Options();
				if (!PauseManager.usedKeyboard)
				{
					Fixes.SelectLater(((Component)GraphicsMenu.KeysRow).gameObject);
				}
				return false;
			}
			Transform val2 = ((Component)__instance).transform.Find("Menu/Mask/Buttons");
			if ((Object)(object)val2 == (Object)null)
			{
				return true;
			}
			if (!__instance.optionsAnim.state1)
			{
				from = Child(val2, "Options");
			}
			else if (!__instance.gameSettingsAnim.state1)
			{
				from = Child(val2, "GameSettings");
			}
			else if (!__instance.keybindingAnim.state1)
			{
				from = Child(val2, "Keybindings");
			}
			return true;
		}

		private static GameObject Child(Transform t, string name)
		{
			Transform val = t.Find(name);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return ((Component)val).gameObject;
		}

		private static void Postfix()
		{
			if ((Object)(object)from != (Object)null && !PauseManager.usedKeyboard)
			{
				Fixes.SelectLater(from);
			}
			from = null;
		}
	}
	[HarmonyPatch(typeof(PauseManager), "Keybindings")]
	internal static class KeybindingsPatch
	{
		private static void Postfix()
		{
			if (PauseManager.isPaused)
			{
				KeybindPage.Opened();
			}
		}
	}
	[HarmonyPatch(typeof(PauseManager), "CloseMapSelect")]
	internal static class CloseMapPatch
	{
		private static void Postfix(PauseManager __instance, bool __runOriginal)
		{
			if (__runOriginal && !PauseManager.usedKeyboard)
			{
				Transform val = Fixes.Find(Fixes.Grid(__instance.gameOptionsMenu.transform, "Maps"), "Maps/OptionsButton");
				if ((Object)(object)val != (Object)null)
				{
					Fixes.SelectLater(((Component)val).gameObject);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PauseManager), "CloseWeaponSelect")]
	internal static class CloseWeaponPatch
	{
		private static void Postfix(PauseManager __instance, bool __runOriginal)
		{
			if (__runOriginal && !PauseManager.usedKeyboard)
			{
				Transform val = Fixes.Find(Fixes.Grid(__instance.gameOptionsMenu.transform, "Weapons"), "Weapons/OptionsButton");
				if ((Object)(object)val != (Object)null)
				{
					Fixes.SelectLater(((Component)val).gameObject);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PauseManager), "Pause")]
	internal static class PausePatch
	{
		private static void Postfix()
		{
			GraphicsMenu.Hide();
			if ((Object)(object)ModPage.Current != (Object)null)
			{
				ModPage.Current.HideNow();
			}
			PausePage.HideAll();
		}
	}
	[HarmonyPatch(typeof(PauseManager), "Resume")]
	internal static class ResumePatch
	{
		private static void Postfix()
		{
			if (!PauseManager.isPaused)
			{
				GraphicsMenu.Hide();
			}
		}
	}
	internal class EditorUnconfirm : MonoBehaviour, IDeselectHandler, IEventSystemHandler
	{
		public GameObject Editor;

		public void OnDeselect(BaseEventData e)
		{
			if (!((Object)(object)Editor == (Object)null) && ((Component)this).gameObject.activeSelf)
			{
				((Component)this).gameObject.SetActive(false);
				Editor.SetActive(true);
			}
		}
	}
	internal static class Graphics
	{
		private sealed class Original
		{
			public Settings bloom;

			public bool bloomOn;

			public Settings vignette;

			public bool vignetteOn;

			public Settings aberration;

			public bool aberrationOn;

			public Settings grading;

			public Settings dof;

			public bool dofOn;

			public Settings motion;

			public bool motionOn;

			public Settings grain;

			public bool grainOn;
		}

		[HarmonyPatch(typeof(PauseManager), "Update")]
		private static class KeepSharp
		{
			private static readonly FieldRef<PauseManager, PostProcessingBehaviour> post = AccessTools.FieldRefAccess<PauseManager, PostProcessingBehaviour>("post");

			private static void Postfix(PauseManager __instance)
			{
				PostProcessingBehaviour val = post.Invoke(__instance);
				if (Plugin.PauseBlur.Value)
				{
					if (PauseManager.isPaused && (Object)(object)val != (Object)null && (Object)(object)val.profile == (Object)(object)__instance.standard && (Object)(object)__instance.blur != (Object)null)
					{
						val.profile = __instance.blur;
					}
				}
				else if ((Object)(object)val != (Object)null && (Object)(object)val.profile == (Object)(object)__instance.blur && (Object)(object)__instance.standard != (Object)null)
				{
					val.profile = __instance.standard;
				}
			}
		}

		private static readonly Dictionary<PostProcessingProfile, Original> originals = new Dictionary<PostProcessingProfile, Original>();

		internal static PostProcessingProfile Play;

		internal static PostProcessingProfile Paused;

		internal static PostProcessingProfile Menu;

		private static Original Keep(PostProcessingProfile p)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_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)
			if (originals.TryGetValue(p, out var value))
			{
				return value;
			}
			value = new Original
			{
				bloom = p.bloom.settings,
				bloomOn = ((PostProcessingModel)p.bloom).enabled,
				vignette = p.vignette.settings,
				vignetteOn = ((PostProcessingModel)p.vignette).enabled,
				aberration = p.chromaticAberration.settings,
				aberrationOn = ((PostProcessingModel)p.chromaticAberration).enabled,
				grading = p.colorGrading.settings,
				dof = p.depthOfField.settings,
				dofOn = ((PostProcessingModel)p.depthOfField).enabled,
				motion = p.motionBlur.settings,
				motionOn = ((PostProcessingModel)p.motionBlur).enabled,
				grain = p.grain.settings,
				grainOn = ((PostProcessingModel)p.grain).enabled
			};
			originals[p] = value;
			return value;
		}

		public static void Find(PauseManager pm)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pm != (Object)null)
			{
				if ((Object)(object)pm.standard != (Object)null)
				{
					Play = pm.standard;
				}
				if ((Object)(object)pm.blur != (Object)null)
				{
					Paused = pm.blur;
				}
			}
			Camera[] array = Resources.FindObjectsOfTypeAll<Camera>();
			foreach (Camera val in array)
			{
				if (((Object)val).name != "Camera_Pause")
				{
					continue;
				}
				Scene scene = ((Component)val).gameObject.scene;
				if (((Scene)(ref scene)).IsValid())
				{
					PostProcessingBehaviour component = ((Component)val).GetComponent<PostProcessingBehaviour>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.profile != (Object)null)
					{
						Menu = component.profile;
					}
				}
			}
			Apply();
		}

		private static float LevelScale(Level l, float low, float high)
		{
			return l switch
			{
				Level.Low => low, 
				Level.High => high, 
				_ => 1f, 
			};
		}

		public static void Apply()
		{
			//IL_0076: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			PostProcessingProfile[] array = (PostProcessingProfile[])(object)new PostProcessingProfile[3] { Play, Paused, Menu };
			foreach (PostProcessingProfile val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Original original = Keep(val);
					bool flag = (Object)(object)val == (Object)(object)Paused && (Object)(object)val != (Object)(object)Play;
					bool num = (Object)(object)val == (Object)(object)Menu && (Object)(object)val != (Object)(object)Play;
					Settings bloom = original.bloom;
					bloom.bloom.intensity *= LevelScale(Plugin.Bloom.Value, 0.5f, 2.2f);
					val.bloom.settings = bloom;
					((PostProcessingModel)val.bloom).enabled = original.bloomOn && Plugin.Bloom.Value != Level.Off;
					Level level = (flag ? Level.Default : Plugin.Vignette.Value);
					Level level2 = (flag ? Level.Default : Plugin.Aberration.Value);
					Settings vignette = original.vignette;
					vignette.intensity *= LevelScale(level, 0.5f, 1.5f);
					val.vignette.settings = vignette;
					((PostProcessingModel)val.vignette).enabled = original.vignetteOn && level != Level.Off;
					Settings aberration = original.aberration;
					aberration.intensity *= LevelScale(level2, 0.5f, 2.5f);
					val.chromaticAberration.settings = aberration;
					((PostProcessingModel)val.chromaticAberration).enabled = original.aberrationOn && level2 != Level.Off;
					Settings grading = original.grading;
					if (!num)
					{
						grading.basic.postExposure += Exposure();
						grading.basic.contrast = Mathf.Clamp(grading.basic.contrast + Slider(Plugin.Contrast.Value) * 0.5f, 0f, 2f);
						grading.basic.saturation = Mathf.Clamp(grading.basic.saturation * ColourScale(Plugin.Saturation.Value), 0f, 2f);
					}
					val.colorGrading.settings = grading;
					if (!num && !flag)
					{
						Settings grain = original.grain;
						grain.intensity = ((Plugin.Grain.Value == Amount.Low) ? 0.2f : ((Plugin.Grain.Value == Amount.Medium) ? 0.4f : 0.7f));
						grain.size = 1f;
						grain.colored = false;
						val.grain.settings = grain;
						((PostProcessingModel)val.grain).enabled = Plugin.Grain.Value != Amount.Off;
					}
				}
			}
		}

		private static float Slider(int v)
		{
			return (float)(Mathf.Clamp(v, 0, 100) - 50) / 50f;
		}

		private static float Exposure()
		{
			return Slider(Plugin.Brightness.Value) * 0.8f;
		}

		private static float ColourScale(int v)
		{
			float num = Slider(v);
			if (!(num <= 0f))
			{
				return 1f + num * 0.8f;
			}
			return 1f + num;
		}
	}
	internal static class GraphicsMenu
	{
		private sealed class Row
		{
			public string Label;

			public ConfigEntryBase Entry;

			public string[] Values;

			public OptionsButton Button;

			public bool Slider;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__14_0;

			internal void <Build>b__14_0()
			{
				if (PauseManager.isPaused)
				{
					Pause.Keybindings();
				}
			}
		}

		private static readonly List<Row> rows = new List<Row>();

		private static readonly FieldRef<OptionsButton, int> index = AccessTools.FieldRefAccess<OptionsButton, int>("currentIndex");

		private static readonly FieldRef<OptionsButton, TextMeshProUGUI> text = AccessTools.FieldRefAccess<OptionsButton, TextMeshProUGUI>("text");

		internal static PauseManager Pause;

		internal static CodeStateAnimation Page;

		internal static OptionsButton OpenRow;

		internal static OptionsButton KeysRow;

		internal static bool Open;

		internal static Selectable First;

		private const string Prefix = "MenuOverhaul.";

		private static void Define()
		{
			rows.Clear();
			Add("BLOOM", (ConfigEntryBase)(object)Plugin.Bloom, "OFF", "LOW", "DEFAULT", "HIGH");
			Add("VIGNETTE", (ConfigEntryBase)(object)Plugin.Vignette, "OFF", "LOW", "DEFAULT", "HIGH");
			Add("ABERRATION", (ConfigEntryBase)(object)Plugin.Aberration, "OFF", "LOW", "DEFAULT", "HIGH");
			Add("PAUSE BLUR", (ConfigEntryBase)(object)Plugin.PauseBlur, "OFF", "ON");
			Add("BRIGHTNESS", Plugin.Brightness);
			Add("CONTRAST", Plugin.Contrast);
			Add("SATURATION", Plugin.Saturation);
			Add("FILM GRAIN", (ConfigEntryBase)(object)Plugin.Grain, "OFF", "LOW", "MEDIUM", "HIGH");
		}

		private static void Add(string label, ConfigEntryBase entry, params string[] values)
		{
			rows.Add(new Row
			{
				Label = label,
				Entry = entry,
				Values = values
			});
		}

		private static void Add(string label, ConfigEntry<int> entry)
		{
			string[] array = new string[11];
			for (int i = 0; i <= 10; i++)
			{
				array[i] = (i * 10).ToString();
			}
			rows.Add(new Row
			{
				Label = label,
				Entry = (ConfigEntryBase)(object)entry,
				Values = array,
				Slider = true
			});
		}

		public static void Build(PauseManager pm)
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Expected O, but got Unknown
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			Pause = pm;
			Open = false;
			Page = null;
			OpenRow = null;
			KeysRow = null;
			First = null;
			Define();
			try
			{
				Transform val = Fixes.Grid(pm.optionsMenu.transform, "Shake");
				Transform val2 = (((Object)(object)val != (Object)null) ? val.parent : null);
				Transform val3 = (((Object)(object)val != (Object)null) ? val.Find("Shake") : null);
				Transform val4 = (((Object)(object)val != (Object)null) ? val.Find("AA") : null);
				if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null)
				{
					Plugin.Log.LogWarning((object)"The OPTIONS page isn't laid out as expected; graphics settings not added.");
					return;
				}
				Transform transform = Object.Instantiate<GameObject>(((Component)val3).gameObject, val, false).transform;
				((Object)transform).name = "MenuOverhaul.Graphics";
				transform.SetSiblingIndex(val4.GetSiblingIndex() + 1);
				SetLabel(transform, "GRAPHICS");
				OpenRow = ((Component)transform).GetComponentInChildren<OptionsButton>();
				OpenRow.values = new string[1] { "EDIT" };
				((UnityEvent)((Component)OpenRow).GetComponent<Button>().onClick).AddListener(new UnityAction(OpenPage));
				Transform transform2 = Object.Instantiate<GameObject>(((Component)val3).gameObject, val, false).transform;
				((Object)transform2).name = "MenuOverhaul.Keybindings";
				transform2.SetSiblingIndex(transform.GetSiblingIndex());
				SetLabel(transform2, "KEYBINDINGS");
				KeysRow = ((Component)transform2).GetComponentInChildren<OptionsButton>();
				KeysRow.values = new string[1] { "EDIT" };
				ButtonClickedEvent onClick = ((Component)KeysRow).GetComponent<Button>().onClick;
				object obj = <>c.<>9__14_0;
				if (obj == null)
				{
					UnityAction val5 = delegate
					{
						if (PauseManager.isPaused)
						{
							Pause.Keybindings();
						}
					};
					<>c.<>9__14_0 = val5;
					obj = (object)val5;
				}
				((UnityEvent)onClick).AddListener((UnityAction)obj);
				Chain(val);
				Transform parent = val2.parent;
				GameObject val6 = Object.Instantiate<GameObject>(((Component)parent).gameObject, parent.parent, false);
				((Object)val6).name = "GraphicsMask";
				val6.transform.SetSiblingIndex(parent.GetSiblingIndex() + 1);
				Page = val6.GetComponent<CodeStateAnimation>();
				Page.state1 = true;
				Transform child = val6.transform.GetChild(0);
				((Object)child).name = "Graphics";
				Transform val7 = child.Find("GameObject/Text");
				if ((Object)(object)val7 != (Object)null)
				{
					((Component)val7).GetComponent<TMP_Text>().text = "GRAPHICS";
				}
				Transform val8 = child.Find("Grid");
				Transform template = val8.Find("Shake");
				Transform val9 = val8.Find("Back");
				Transform item = (((Object)(object)val9 != (Object)null && val9.GetSiblingIndex() > 0) ? val8.GetChild(val9.GetSiblingIndex() - 1) : null);
				HashSet<Transform> hashSet = new HashSet<Transform> { val9, item };
				BuildRows(val8, template, 0);
				foreach (Row row in rows)
				{
					hashSet.Add(((Component)row.Button).transform.parent);
				}
				List<GameObject> list = new List<GameObject>();
				foreach (Transform item2 in val8)
				{
					Transform val10 = item2;
					if (!hashSet.Contains(val10))
					{
						list.Add(((Component)val10).gameObject);
					}
				}
				foreach (GameObject item3 in list)
				{
					item3.SetActive(false);
					Object.Destroy((Object)(object)item3);
				}
				SelectMe[] componentsInChildren = val6.GetComponentsInChildren<SelectMe>(true);
				for (int num = 0; num < componentsInChildren.Length; num++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren[num]);
				}
				val4.SetParent(val8, false);
				val4.SetSiblingIndex(0);
				Chain(val);
				Selectable component = ((Component)((Component)val4).GetComponentInChildren<OptionsButton>()).GetComponent<Selectable>();
				Transform val11 = child.Find("Arrows");
				if ((Object)(object)val11 != (Object)null)
				{
					Navigation navigation = component.navigation;
					((Navigation)(ref navigation)).selectOnLeft = Sel(val11.Find("Left"));
					((Navigation)(ref navigation)).selectOnRight = Sel(val11.Find("Right"));
					component.navigation = navigation;
				}
				First = component;
				ChainPage(val8, val9, component);
				Refresh();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Couldn't add the graphics settings: " + ex));
			}
		}

		private static void BuildRows(Transform grid, Transform template, int at)
		{
			for (int i = 0; i < rows.Count; i++)
			{
				Transform transform = Object.Instantiate<GameObject>(((Component)template).gameObject, grid, false).transform;
				((Object)transform).name = "MenuOverhaul." + rows[i].Entry.Definition.Key;
				transform.SetSiblingIndex(at + i);
				SetLabel(transform, rows[i].Label);
				OptionsButton componentInChildren = ((Component)transform).GetComponentInChildren<OptionsButton>();
				SelectMe[] componentsInChildren = ((Component)transform).GetComponentsInChildren<SelectMe>(true);
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren[j]);
				}
				componentInChildren.values = rows[i].Values;
				rows[i].Button = componentInChildren;
				if (rows[i].Slider)
				{
					Sliders.Add(componentInChildren);
				}
			}
		}

		private static void SetLabel(Transform row, string label)
		{
			TMP_Text[] componentsInChildren = ((Component)row).GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val in componentsInChildren)
			{
				if ((Object)(object)((Component)val).GetComponentInParent<OptionsButton>() == (Object)null)
				{
					val.text = label;
				}
			}
		}

		private static void Chain(Transform grid)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			List<Selectable> list = new List<Selectable>();
			foreach (Transform item in grid)
			{
				Transform val = item;
				if (((Component)val).gameObject.activeSelf)
				{
					OptionsButton componentInChildren = ((Component)val).GetComponentInChildren<OptionsButton>();
					Selectable val2 = (Selectable)(((Object)(object)componentInChildren != (Object)null) ? ((object)((Component)componentInChildren).GetComponent<Selectable>()) : ((object)((Component)val).GetComponentInChildren<Button>()));
					if ((Object)(object)val2 != (Object)null)
					{
						list.Add(val2);
					}
				}
			}
			for (int i = 0; i < list.Count; i++)
			{
				Navigation navigation = list[i].navigation;
				((Navigation)(ref navigation)).mode = (Mode)4;
				((Navigation)(ref navigation)).selectOnUp = list[(i + list.Count - 1) % list.Count];
				((Navigation)(ref navigation)).selectOnDown = list[(i + 1) % list.Count];
				list[i].navigation = navigation;
			}
		}

		private static Selectable Sel(Transform t)
		{
			if (!((Object)(object)t != (Object)null))
			{
				return null;
			}
			return ((Component)t).GetComponent<Selectable>();
		}

		private static void ChainPage(Transform grid, Transform back, Selectable first)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			List<Selectable> list = new List<Selectable>();
			if ((Object)(object)first != (Object)null)
			{
				list.Add(first);
			}
			foreach (Row row in rows)
			{
				list.Add(((Component)row.Button).GetComponent<Selectable>());
			}
			Button val = (((Object)(object)back != (Object)null) ? ((Component)back).GetComponentInChildren<Button>() : null);
			if ((Object)(object)val != (Object)null)
			{
				list.Add((Selectable)(object)val);
			}
			for (int i = 0; i < list.Count; i++)
			{
				Navigation navigation = list[i].navigation;
				((Navigation)(ref navigation)).mode = (Mode)4;
				((Navigation)(ref navigation)).selectOnUp = list[(i + list.Count - 1) % list.Count];
				((Navigation)(ref navigation)).selectOnDown = list[(i + 1) % list.Count];
				list[i].navigation = navigation;
			}
		}

		public static void Refresh()
		{
			foreach (Row row in rows)
			{
				if (!((Object)(object)row.Button == (Object)null))
				{
					int num = Convert.ToInt32(row.Entry.BoxedValue);
					int num2 = Mathf.Clamp(row.Slider ? Mathf.RoundToInt((float)num / 10f) : num, 0, row.Values.Length - 1);
					index.Invoke(row.Button) = num2;
					Texts.Set((TMP_Text)(object)(text.Invoke(row.Button) ?? ((Component)row.Button).GetComponentInChildren<TextMeshProUGUI>()), row.Slider ? num.ToString() : row.Values[num2]);
				}
			}
		}

		private static Row Find(OptionsButton b)
		{
			foreach (Row row in rows)
			{
				if ((Object)(object)row.Button == (Object)(object)b)
				{
					return row;
				}
			}
			return null;
		}

		public static bool IsOurs(OptionsButton b)
		{
			if ((Object)(object)b != (Object)null)
			{
				if (!((Object)(object)b == (Object)(object)OpenRow) && !((Object)(object)b == (Object)(object)KeysRow))
				{
					return Find(b) != null;
				}
				return true;
			}
			return false;
		}

		public static void Move(OptionsButton b, int dir)
		{
			Row row = Find(b);
			if (row != null)
			{
				if (row.Slider)
				{
					row.Entry.BoxedValue = Mathf.Clamp(Convert.ToInt32(row.Entry.BoxedValue) + dir * 10, 0, 100);
					Refresh();
					return;
				}
				if ((object)row.Entry.SettingType == typeof(bool))
				{
					row.Entry.BoxedValue = !(bool)row.Entry.BoxedValue;
					Refresh();
					return;
				}
				int num = row.Values.Length;
				int value = (Convert.ToInt32(row.Entry.BoxedValue) + dir + num) % num;
				row.Entry.BoxedValue = Enum.ToObject(row.Entry.SettingType, value);
				Refresh();
			}
		}

		public static void OpenPage()
		{
			if (!((Object)(object)Page == (Object)null) && !((Object)(object)Pause == (Object)null) && PauseManager.isPaused && !Open)
			{
				Open = true;
				Pause.isInOptionsMenu = true;
				Pause.optionsAnim.state1 = true;
				Page.state1 = false;
				Pause.sinceTransition = 0f;
				if (!PauseManager.usedKeyboard && (Object)(object)First != (Object)null)
				{
					Fixes.SelectLater(((Component)First).gameObject);
				}
			}
		}

		public static void ClosePage()
		{
			Open = false;
			if ((Object)(object)Page != (Object)null)
			{
				Page.state1 = true;
			}
			Pause.optionsAnim.state1 = false;
			Pause.isInOptionsMenu = true;
			Pause.sinceTransition = 0f;
			if (!PauseManager.usedKeyboard && (Object)(object)OpenRow != (Object)null)
			{
				Fixes.SelectLater(((Component)OpenRow).gameObject);
			}
		}

		public static void Hide()
		{
			Open = false;
			if ((Object)(object)Page != (Object)null)
			{
				Page.state1 = true;
			}
		}

		public static void Tick()
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if (!Open || (Object)(object)Page == (Object)null || PauseManager.usedKeyboard)
			{
				return;
			}
			EventSystem current = EventSystem.current;
			if ((Object)(object)current == (Object)null)
			{
				return;
			}
			GameObject currentSelectedGameObject = current.currentSelectedGameObject;
			if (((Object)(object)currentSelectedGameObject != (Object)null && currentSelectedGameObject.transform.IsChildOf(((Component)Page).transform)) || Pause.sinceTransition < 0.3f)
			{
				return;
			}
			foreach (InputDevice device in InputManager.Devices)
			{
				if (!PauseLock.Owns(device))
				{
					continue;
				}
				if (!OneAxisInputControl.op_Implicit((OneAxisInputControl)(object)device.AnyButton))
				{
					Vector2 value = device.LeftStick.Value;
					if (!(((Vector2)(ref value)).magnitude > 0.1f))
					{
						value = device.DPad.Value;
						if (!(((Vector2)(ref value)).magnitude > 0.1f))
						{
							continue;
						}
					}
				}
				if ((Object)(object)First != (Object)null)
				{
					Fixes.SelectLater(((Component)First).gameObject);
				}
				Pause.sinceTransition = 0f;
				break;
			}
		}
	}
	[HarmonyPatch(typeof(OptionsButton), "MoveIndexRight")]
	internal static class MoveRightPatch
	{
		private static bool Prefix(OptionsButton __instance)
		{
			if (KeybindPage.IsOurs(__instance))
			{
				KeybindPage.Toggle();
				return false;
			}
			if (Sliders.AtEnd(__instance, 100))
			{
				return false;
			}
			if (!GraphicsMenu.IsOurs(__instance))
			{
				return true;
			}
			GraphicsMenu.Move(__instance, 1);
			return false;
		}
	}
	[HarmonyPatch(typeof(OptionsButton), "MoveIndexLeft")]
	internal static class MoveLeftPatch
	{
		private static bool Prefix(OptionsButton __instance)
		{
			if (KeybindPage.IsOurs(__instance))
			{
				KeybindPage.Toggle();
				return false;
			}
			if (Sliders.AtEnd(__instance, 0))
			{
				return false;
			}
			if (!GraphicsMenu.IsOurs(__instance))
			{
				return true;
			}
			GraphicsMenu.Move(__instance, -1);
			return false;
		}
	}
	[HarmonyPatch(typeof(OptionsButton), "Start")]
	internal static class ButtonStartPatch
	{
		private static void Postfix(OptionsButton __instance)
		{
			if (GraphicsMenu.IsOurs(__instance))
			{
				GraphicsMenu.Refresh();
			}
		}
	}
	internal static class KeybindPage
	{
		private sealed class Seat
		{
			public Controller Player;

			public InputDevice Device;

			public int Column;

			public int Row;

			public int Bottom = 1;

			public InputControlType[][] Pending;

			public InputControlType[][] Saved;

			public bool Listening;

			public bool Armed;

			public bool Fresh = true;

			public readonly List<InputControlType> Held = new List<InputControlType>();

			public float RepeatAt;

			public int HeldDir;
		}

		private const int ActionRows = 4;

		private const int ResetRow = 4;

		private const int BottomRow = 5;

		private const int Keyboard = 0;

		private const int Save = 1;

		private const int Back = 2;

		public static bool PadView;

		private static PauseManager pm;

		private static KeybindingButtonHandler handler;

		private static Transform hud;

		private static RectTransform grid;

		private static RectTransform table;

		private static Transform arrows;

		private static GameObject noPads;

		private static Image[,] cells;

		private static TMP_Text[,] cellTexts;

		private static TMP_Text[] tags;

		private static Image[] bottoms;

		private static TMP_Text[] bottomTexts;

		private static readonly List<Seat> seats = new List<Seat>();

		private static Color boxColor = Color.white;

		private static Color boxText = new Color(0.169f, 0.169f, 0.169f);

		private static Color selColor = new Color(0.12f, 0.12f, 0.16f);

		private static OptionsButton modeButton;

		private static GameObject modeRow;

		private static GameObject modeGap;

		private static Selectable arrowLeft;

		private static Selectable arrowRight;

		private static Selectable reset;

		private static Selectable back;

		private static readonly List<Selectable[]> keyboardRows = new List<Selectable[]>();

		private const float ColumnStep = 150f;

		private const float ColumnWidth = 132f;

		private const float FirstColumn = -60f;

		private const float RowStep = 55f;

		private const float TopRow = 265f;

		private const float CellHeight = 42f;

		private static readonly TMP_Text[] tips = (TMP_Text[])(object)new TMP_Text[1];

		private static readonly string[] PlayerTags = new string[4] { "P1", "P2", "P3", "P4" };

		private static bool releasing;

		private static int leftFrame = -10;

		public static bool Built => (Object)(object)grid != (Object)null;

		public static bool Busy
		{
			get
			{
				if (PadView)
				{
					return PauseManager.isPaused;
				}
				return false;
			}
		}

		public static bool JustLeft => Time.frameCount - leftFrame <= 1;

		public static void Build(PauseManager pause)
		{
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_046d: Expected O, but got Unknown
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Expected O, but got Unknown
			//IL_0540: Unknown result type (might be due to invalid IL or missing references)
			//IL_0559: Unknown result type (might be due to invalid IL or missing references)
			//IL_0591: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0931: Unknown result type (might be due to invalid IL or missing references)
			//IL_0954: Unknown result type (might be due to invalid IL or missing references)
			//IL_060e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0613: Unknown result type (might be due to invalid IL or missing references)
			//IL_0614: Unknown result type (might be due to invalid IL or missing references)
			//IL_0626: Unknown result type (might be due to invalid IL or missing references)
			//IL_062d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0634: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0655: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a04: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a0b: Expected O, but got Unknown
			//IL_0a20: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a27: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a3a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a5d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b9f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bf0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c28: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c66: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c75: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c89: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c99: Unknown result type (might be due to invalid IL or missing references)
			//IL_0af6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b15: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b2a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b3f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b49: Unknown result type (might be due to invalid IL or missing references)
			//IL_0726: Unknown result type (might be due to invalid IL or missing references)
			//IL_072b: Unknown result type (might be due to invalid IL or missing references)
			//IL_072c: Unknown result type (might be due to invalid IL or missing references)
			//IL_073e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0745: Unknown result type (might be due to invalid IL or missing references)
			//IL_074c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0757: Unknown result type (might be due to invalid IL or missing references)
			//IL_0761: Unknown result type (might be due to invalid IL or missing references)
			//IL_0778: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0846: Unknown result type (might be due to invalid IL or missing references)
			//IL_0850: Unknown result type (might be due to invalid IL or missing references)
			pm = pause;
			if (PadView || releasing)
			{
				releasing = false;
				PauseLock.Block(on: false);
			}
			PadView = false;
			grid = null;
			seats.Clear();
			keyboardRows.Clear();
			handler = pm.keybindingMenu.GetComponent<KeybindingButtonHandler>();
			hud = (((Object)(object)handler != (Object)null && (Object)(object)handler.KeybindHud != (Object)null) ? handler.KeybindHud.transform : null);
			Transform val = (((Object)(object)hud != (Object)null) ? hud.Find("THROW") : null);
			Transform val2 = (((Object)(object)hud != (Object)null) ? hud.Find("UP") : null);
			Transform val3 = (((Object)(object)hud != (Object)null) ? hud.Find("Spacing (1)") : null);
			reset = Sel(((Object)(object)hud != (Object)null) ? hud.Find("Back/Reset") : null);
			back = Sel(((Object)(object)hud != (Object)null) ? hud.Find("Back/Button") : null);
			arrows = (((Object)(object)handler != (Object)null) ? ((Component)handler).transform.Find("Arrows") : null);
			arrowLeft = Sel(((Object)(object)arrows != (Object)null) ? arrows.Find("Left") : null);
			arrowRight = Sel(((Object)(object)arrows != (Object)null) ? arrows.Find("Right") : null);
			Transform val4 = (((Object)(object)val != (Object)null) ? FindButton(val, alt: false) : null);
			Transform val5 = (((Object)(object)val != (Object)null) ? val.Find("Text (1)") : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)reset == (Object)null || (Object)(object)back == (Object)null || (Object)(object)arrowLeft == (Object)null || (Object)(object)val4 == (Object)null || (Object)(object)val5 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"KEYBINDINGS isn't laid out as expected; left as the game made it.");
				return;
			}
			Image component = ((Component)val4).GetComponent<Image>();
			Button component2 = ((Component)val4).GetComponent<Button>();
			if ((Object)(object)component != (Object)null)
			{
				boxColor = ((Graphic)component).color;
			}
			TMP_Text componentInChildren = ((Component)val4).GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				boxText = ((Graphic)componentInChildren).color;
			}
			if ((Object)(object)component2 != (Object)null)
			{
				Color val6 = boxColor;
				ColorBlock colors = ((Selectable)component2).colors;
				selColor = val6 * ((ColorBlock)(ref colors)).highlightedColor;
			}
			selColor.a = 1f;
			for (int i = val2.GetSiblingIndex(); i <= val.GetSiblingIndex(); i++)
			{
				Transform child = hud.GetChild(i);
				if (((Component)child).gameObject.activeSelf)
				{
					Selectable val7 = Sel(FindButton(child, alt: false));
					Selectable val8 = Sel(FindButton(child, alt: true));
					if ((Object)(object)val7 != (Object)null && (Object)(object)val8 != (Object)null)
					{
						keyboardRows.Add((Selectable[])(object)new Selectable[2] { val7, val8 });
					}
				}
			}
			modeRow = Object.Instantiate<GameObject>(((Component)val).gameObject, hud, false);
			((Object)modeRow).name = "MenuOverhaul.Mode";
			modeRow.transform.SetSiblingIndex(0);
			TMP_Text[] componentsInChildren = modeRow.GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val9 in componentsInChildren)
			{
				if ((Object)(object)val9.transform.parent == (Object)(object)modeRow.transform)
				{
					val9.text = "EDITING";
				}
			}
			KeybindingText[] componentsInChildren2 = modeRow.GetComponentsInChildren<KeybindingText>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[j]);
			}
			SelectMe[] componentsInChildren3 = modeRow.GetComponentsInChildren<SelectMe>(true);
			for (int j = 0; j < componentsInChildren3.Length; j++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[j]);
			}
			Transform val10 = FindButton(modeRow.transform, alt: true);
			if ((Object)(object)val10 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)((Component)val10).gameObject);
			}
			Transform val11 = FindButton(modeRow.transform, alt: false);
			Button component3 = ((Component)val11).GetComponent<Button>();
			component3.onClick = new ButtonClickedEvent();
			((UnityEvent)component3.onClick).AddListener(new UnityAction(Toggle));
			modeButton = ((Component)val11).gameObject.AddComponent<OptionsButton>();
			modeButton.values = new string[1] { "KEYBOARD" };
			TMP_Text componentInChildren2 = ((Component)val11).GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren2 != (Object)null)
			{
				componentInChildren2.enableWordWrapping = false;
				componentInChildren2.enableAutoSizing = true;
				componentInChildren2.fontSizeMin = 20f;
				componentInChildren2.fontSizeMax = 40f;
			}
			modeGap = Object.Instantiate<GameObject>(((Component)val3).gameObject, hud, false);
			((Object)modeGap).name = "MenuOverhaul.ModeSpacing";
			modeGap.transform.SetSiblingIndex(1);
			KeyboardNavigation();
			grid = Ui.Rect(((Component)handler).transform, "MenuOverhaul.PadGrid");
			grid.anchoredPosition = Vector2.zero;
			grid.sizeDelta = new Vector2(1000f, 800f);
			((Component)grid).gameObject.SetActive(false);
			table = Ui.Rect((Transform)(object)grid, "Table");
			table.sizeDelta = grid.sizeDelta;
			cells = new Image[5, 4];
			cellTexts = new TMP_Text[5, 4];
			tags = (TMP_Text[])(object)new TMP_Text[4];
			Vector2 val13 = default(Vector2);
			for (int k = 0; k <= 4; k++)
			{
				string text = ((k < 4) ? PadLayout.Labels[k] : "");
				if (k < 4)
				{
					GameObject obj = Object.Instantiate<GameObject>(((Component)val5).gameObject, (Transform)(object)table, false);
					((Object)obj).name = "Label " + text;
					RectTransform val12 = (RectTransform)obj.transform;
					((Vector2)(ref val13))..ctor(0.5f, 0.5f);
					val12.anchorMax = val13;
					val12.anchorMin = val13;
					val12.pivot = new Vector2(0f, 0.5f);
					val12.anchoredPosition = new Vector2(-400f, Y(k));
					obj.GetComponent<TMP_Text>().text = text;
				}
				for (int l = 0; l < 4; l++)
				{
					GameObject val14 = Object.Instantiate<GameObject>(((Component)val4).gameObject, (Transform)(object)table, false);
					((Object)val14).name = "Cell " + k + "," + l;
					componentsInChildren2 = val14.GetComponentsInChildren<KeybindingText>(true);
					for (int j = 0; j < componentsInChildren2.Length; j++)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren2[j]);
					}
					componentsInChildren3 = val14.GetComponentsInChildren<SelectMe>(true);
					for (int j = 0; j < componentsInChildren3.Length; j++)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren3[j]);
					}
					Selectable[] componentsInChildren4 = val14.GetComponentsInChildren<Selectable>(true);
					for (int j = 0; j < componentsInChildren4.Length; j++)
					{
						Object.DestroyImmediate((Object)(object)componentsInChildren4[j]);
					}
					RectTransform val15 = (RectTransform)val14.transform;
					((Vector2)(ref val13))..ctor(0.5f, 0.5f);
					val15.anchorMax = val13;
					val15.anchorMin = val13;
					val15.pivot = new Vector2(0.5f, 0.5f);
					val15.sizeDelta = new Vector2(132f, (k < 4) ? 42f : 42f);
					val15.anchoredPosition = new Vector2(X(l), (k < 4) ? Y(k) : (Y(k) - 15f));
					cells[k, l] = val14.GetComponent<Image>();
					cellTexts[k, l] = val14.GetComponentInChildren<TMP_Text>(true);
					if ((Object)(object)cellTexts[k, l] != (Object)null)
					{
						TMP_Text val16 = cellTexts[k, l];
						val16.enableWordWrapping = false;
						val16.fontSizeMax = Mathf.Min(val16.fontSize, 40f);
						val16.fontSizeMin = 16f;
						val16.enableAutoSizing = true;
						val16.rectTransform.sizeDelta = new Vector2(108f, val16.rectTransform.sizeDelta.y);
					}
					if (k == 4 && (Object)(object)cellTexts[k, l] != (Object)null)
					{
						cellTexts[k, l].text = "RESET";
					}
				}
			}
			for (int m = 0; m < 4; m++)
			{
				tags[m] = (TMP_Text)(object)Ui.Text((Transform)(object)table, "Tag " + m, "", 45f, Color.white, (TextAlignmentOptions)514);
				tags[m].font = ((Component)val5).GetComponent<TMP_Text>().font;
				tags[m].fontSharedMaterial = ((Component)val5).GetComponent<TMP_Text>().fontSharedMaterial;
				tags[m].rectTransform.sizeDelta = new Vector2(132f, 60f);
				tags[m].rectTransform.anchoredPosition = new Vector2(X(m), 320f);
			}
			Transform transform = ((Component)back).transform;
			bottoms = (Image[])(object)new Image[3];
			bottomTexts = (TMP_Text[])(object)new TMP_Text[3];
			string[] array = new string[3] { "KEYBOARD", "SAVE", "BACK" };
			for (int n = 0; n < 3; n++)
			{
				GameObject val17 = Object.Instantiate<GameObject>(((Component)transform).gameObject, (Transform)(object)grid, false);
				((Object)val17).name = array[n];
				Selectable[] componentsInChildren4 = val17.GetComponentsInChildren<Selectable>(true);
				for (int j = 0; j < componentsInChildren4.Length; j++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren4[j]);
				}
				RectTransform val18 = (RectTransform)val17.transform;
				((Vector2)(ref val13))..ctor(0.5f, 0.5f);
				val18.anchorMax = val13;
				val18.anchorMin = val13;
				val18.pivot = new Vector2(0.5f, 0.5f);
				val18.anchoredPosition = new Vector2((float)(n - 1) * 230f, Y(5) - 40f);
				bottoms[n] = val17.GetComponent<Image>();
				bottomTexts[n] = val17.GetComponentInChildren<TMP_Text>(true);
				if ((Object)(object)bottomTexts[n] != (Object)null)
				{
					bottomTexts[n].text = array[n];
					bottomTexts[n].enableAutoSizing = true;
					bottomTexts[n].fontSizeMax = bottomTexts[n].fontSize;
					bottomTexts[n].fontSizeMin = 20f;
					RectTransform rectTransform = bottomTexts[n].rectTransform;
					float num = ((Mathf.Abs(((Transform)rectTransform).localScale.x) > 0.01f) ? Mathf.Abs(((Transform)rectTransform).localScale.x) : 1f);
					rectTransform.sizeDelta = new Vector2((val18.sizeDelta.x - 40f) / num, rectTransform.sizeDelta.y);
				}
			}
			for (int num2 = 0; num2 < tips.Length; num2++)
			{
				tips[num2] = (TMP_Text)(object)Ui.Text((Transform)(object)grid, "Tip " + num2, "", 24f, new Color(0.6f, 0.6f, 0.6f), (TextAlignmentOptions)514);
				tips[num2].font = ((Component)val5).GetComponent<TMP_Text>().font;
				tips[num2].rectTransform.anchoredPosition = new Vector2(0f, Y(5) - 110f - 30f * (float)num2);
			}
			SetTip((InputDeviceStyle)0);
			noPads = ((Component)Ui.Text((Transform)(object)grid, "NoPads", "NO CONTROLLERS JOINED", 45f, Color.white, (TextAlignmentOptions)514)).gameObject;
			noPads.GetComponent<TMP_Text>().font = ((Component)val5).GetComponent<TMP_Text>().font;
			((RectTransform)noPads.transform).sizeDelta = new Vector2(900f, 80f);
			((RectTransform)noPads.transform).anchoredPosition = new Vector2(0f, Y(1));
		}

		private static void SetTip(InputDeviceStyle style)
		{
			//IL_000a: 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_0063: 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)
			string[] array = new string[1] { PadLayout.Name((InputControlType)19, style) + " ON AN ACTION, THEN HOLD ONE OR TWO BUTTONS AND LET GO TO SET THEM" };
			for (int i = 0; i < tips.Length; i++)
			{
				if (!((Object)(object)tips[i] == (Object)null))
				{
					tips[i].text = array[i];
					tips[i].rectTransform.sizeDelta = tips[i].GetPreferredValues(array[i]) + new Vector2(4f, 0f);
				}
			}
		}

		private static InputDeviceStyle TipStyle()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			foreach (InputDevice device in InputManager.Devices)
			{
				if (PauseLock.IsPauser(device))
				{
					return device.DeviceStyle;
				}
			}
			if (seats.Count <= 0 || seats[0].Device == null)
			{
				return (InputDeviceStyle)0;
			}
			return seats[0].Device.DeviceStyle;
		}

		private static float X(int column)
		{
			return -60f + (float)column * 150f;
		}

		private static float Y(int row)
		{
			return 265f - (float)row * 55f;
		}

		private static Selectable Sel(Transform t)
		{
			if (!((Object)(object)t != (Object)null))
			{
				return null;
			}
			return ((Component)t).GetComponent<Selectable>();
		}

		private static Transform FindButton(Transform row, bool alt)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			foreach (Transform item in row)
			{
				Transform val = item;
				if (((Object)val).name.StartsWith("KeybindingButton") && ((Object)val).name.EndsWith("_ALT") == alt)
				{
					return val;
				}
			}
			return null;
		}

		public static bool IsOurs(OptionsButton b)
		{
			if ((Object)(object)b != (Object)null)
			{
				return (Object)(object)b == (Object)(object)modeButton;
			}
			return false;
		}

		public static void Toggle()
		{
			if (seats.Count > 0)
			{
				ShowPads(pads: true);
			}
		}

		private static void Link(Selectable s, Selectable up, Selectable down, Selectable left, Selectable right)
		{
			//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_0031: Unknown result type (might be due to invalid IL or missing references)
			Navigation navigation = s.navigation;
			((Navigation)(ref navigation)).mode = (Mode)4;
			((Navigation)(ref navigation)).selectOnUp = up;
			((Navigation)(ref navigation)).selectOnDown = down;
			((Navigation)(ref navigation)).selectOnLeft = left;
			((Navigation)(ref navigation)).selectOnRight = right;
			s.navigation = navigation;
		}

		private static void KeyboardNavigation()
		{
			if (keyboardRows.Count != 0)
			{
				Selectable component = ((Component)FindButton(modeRow.transform, alt: false)).GetComponent<Selectable>();
				int count = keyboardRows.Count;
				Link(component, back, keyboardRows[0][0], arrowLeft, arrowRight);
				for (int i = 0; i < count; i++)
				{
					Link(keyboardRows[i][0], (i > 0) ? keyboardRows[i - 1][0] : component, (i < count - 1) ? keyboardRows[i + 1][0] : reset, keyboardRows[i][1], keyboardRows[i][1]);
					Link(keyboardRows[i][1], (i > 0) ? keyboardRows[i - 1][1] : component, (i < count - 1) ? keyboardRows[i + 1][1] : back, keyboardRows[i][0], keyboardRows[i][0]);
				}
				Link(reset, keyboardRows[count - 1][0], component, back, back);
				Link(back, keyboardRows[count - 1][1], component, reset, reset);
			}
		}

		public static void Opened()
		{
			if (!Built)
			{
				return;
			}
			seats.Clear();
			ControllerHandler instance = ControllerHandler.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				List<Controller> list = new List<Controller>();
				foreach (Controller player in instance.players)
				{
					if (PadLayout.IsPad(player))
					{
						list.Add(player);
					}
				}
				list.Sort((Controller a, Controller b) => a.playerID.CompareTo(b.playerID));
				foreach (Controller item in list)
				{
					seats.Add(new Seat
					{
						Player = item,
						Device = ((PlayerActionSet)item.PlayerActions).Device,
						Column = seats.Count,
						Pending = PadLayout.Get(item.playerID),
						Saved = PadLayout.Get(item.playerID)
					});
				}
			}
			ShowPads(seats.Count > 0 && !PauseLock.KeyboardPaused);
		}

		private static void ShowPads(bool pads)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			bool padView = PadView;
			PadView = pads;
			((Component)grid).gameObject.SetActive(pads);
			((Component)hud).gameObject.SetActive(!pads);
			if ((Object)(object)arrows != (Object)null)
			{
				((Component)arrows).gameObject.SetActive(!pads);
			}
			if (pads)
			{
				if ((Object)(object)EventSystem.current != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject((GameObject)null);
				}
				releasing = false;
				PauseLock.Block(on: true);
				foreach (Seat seat in seats)
				{
					seat.Listening = false;
					seat.Row = 0;
					seat.Fresh = true;
					seat.Held.Clear();
				}
				SetTip(TipStyle());
				Draw();
			}
			else
			{
				if (padView)
				{
					Unblock();
				}
				else
				{
					PauseLock.Block(on: false);
				}
				Selectable val = ((keyboardRows.Count > 0) ? keyboardRows[0][0] : null);
				if (!PauseManager.usedKeyboard && (Object)(object)val != (Object)null)
				{
					Fixes.SelectLater(((Component)val).gameObject);
				}
			}
		}

		private static void Unblock()
		{
			releasing = true;
			leftFrame = Time.frameCount;
		}

		private static bool MenuButtonHeld()
		{
			foreach (InputDevice device in InputManager.Devices)
			{
				if (!Compat.IsBotDevice(device) && (((OneAxisInputControl)device.Action1).IsPressed || ((OneAxisInputControl)device.Action2).IsPressed || ((OneAxisInputControl)device.Command).IsPressed))
				{
					return true;
				}
			}
			return false;
		}

		public static void Closed()
		{
			if (Built)
			{
				if (PadView)
				{
					Unblock();
				}
				PadView = false;
				seats.Clear();
				((Component)grid).gameObject.SetActive(false);
				((Component)hud).gameObject.SetActive(true);
				if ((Object)(object)arrows != (Object)null)
				{
					((Component)arrows).gameObject.SetActive(true);
				}
			}
		}

		private static void Leave(bool save)
		{
			if (save)
			{
				foreach (Seat seat in seats)
				{
					PadLayout.Put(seat.Player.playerID, seat.Pending);
				}
				PadLayout.ApplyAll();
				Plugin.Log.LogInfo((object)"Controller layouts saved.");
			}
			pm.BackToPause();
		}

		private static int Dir(InputDevice d, bool vertical)
		{
			float num = (vertical ? (d.DPad.Y + d.LeftStick.Y) : (d.DPad.X + d.LeftStick.X));
			if (!(num > 0.5f))
			{
				if (!(num < -0.5f))
				{
					return 0;
				}
				return -1;
			}
			return 1;
		}

		public static void Tick()
		{
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			if (releasing && !PadView && !MenuButtonHeld())
			{
				releasing = false;
				PauseLock.Block(on: false);
			}
			if (!Built || !PadView)
			{
				return;
			}
			if (!PauseManager.isPaused)
			{
				Closed();
				return;
			}
			bool flag = false;
			foreach (Seat seat2 in seats)
			{
				if (seat2.Device != null && InputManager.Devices.Contains(seat2.Device))
				{
					flag = true;
					break;
				}
			}
			foreach (InputDevice device2 in InputManager.Devices)
			{
				if ((!((OneAxisInputControl)device2.Action2).WasPressed && !device2.CommandWasPressed) || (!PauseLock.IsPauser(device2) && (flag || Compat.IsBotDevice(device2))))
				{
					continue;
				}
				bool flag2 = false;
				foreach (Seat seat3 in seats)
				{
					if (seat3.Device == device2)
					{
						flag2 = true;
					}
				}
				if (!flag2)
				{
					Leave(save: false);
					return;
				}
			}
			Seat seat = null;
			bool save = false;
			foreach (Seat seat4 in seats)
			{
				InputDevice device = seat4.Device;
				if (device == null || !InputManager.Devices.Contains(device))
				{
					continue;
				}
				if (seat4.Listening)
				{
					InputControlType[] bindable;
					if (!seat4.Armed)
					{
						bool flag3 = ((OneAxisInputControl)device.Command).IsPressed;
						bindable = PadLayout.Bindable;
						foreach (InputControlType val in bindable)
						{
							if (((OneAxisInputControl)device.GetControl(val)).IsPressed)
							{
								flag3 = true;
							}
						}
						seat4.Armed = !flag3;
						continue;
					}
					if (device.CommandWasPressed)
					{
						seat4.Listening = false;
						seat4.Held.Clear();
						continue;
					}
					bool flag4 = false;
					bindable = PadLayout.Bindable;
					foreach (InputControlType val2 in bindable)
					{
						if (((OneAxisInputControl)device.GetControl(val2)).IsPressed)
						{
							flag4 = true;
							if (!seat4.Held.Contains(val2) && seat4.Held.Count < 2)
							{
								seat4.Held.Add(val2);
							}
						}
					}
					if (!flag4 && seat4.Held.Count > 0)
					{
						PadLayout.Assign(seat4.Pending, seat4.Row, seat4.Held);
						seat4.Held.Clear();
						seat4.Listening = false;
						seat4.Fresh = true;
					}
					continue;
				}
				if (seat4.Fresh)
				{
					if (((OneAxisInputControl)device.Action1).IsPressed || ((OneAxisInputControl)device.Action2).IsPressed || ((OneAxisInputControl)device.Command).IsPressed)
					{
						continue;
					}
					seat4.Fresh = false;
				}
				if (Time.unscaledTime < seat4.RepeatAt && (((OneAxisInputControl)device.Action1).IsPressed || ((OneAxisInputControl)device.Action2).IsPressed))
				{
					continue;
				}
				int num = Dir(device, vertical: true);
				int num2 = ((seat4.Row == 5) ? Dir(device, vertical: false) : 0);
				int num3 = ((num == 0) ? ((num2 != 0) ? ((num2 > 0) ? 3 : 4) : 0) : ((num > 0) ? 1 : 2));
				if (num3 == 0)
				{
					seat4.HeldDir = 0;
				}
				else if (num3 != seat4.HeldDir || Time.unscaledTime >= seat4.RepeatAt)
				{
					seat4.RepeatAt = Time.unscaledTime + ((num3 != seat4.HeldDir) ? 0.4f : 0.12f);
					seat4.HeldDir = num3;
					if (num > 0)
					{
						seat4.Row = (seat4.Row + 5) % 6;
					}
					else if (num < 0)
					{
						seat4.Row = (seat4.Row + 1) % 6;
					}
					else
					{
						seat4.Bottom = (seat4.Bottom + ((num2 > 0) ? 1 : 2)) % 3;
					}
				}
				if (((OneAxisInputControl)device.Action1).WasPressed)
				{
					if (seat4.Row < 4)
					{
						seat4.Listening = true;
						seat4.Armed = false;
						continue;
					}
					if (seat4.Row == 4)
					{
						seat4.Pending = PadLayout.Default();
						continue;
					}
					if (seat4.Bottom == 0)
					{
						ShowPads(pads: false);
						return;
					}
					seat = seat4;
					save = seat4.Bottom == 1;
				}
				else if ((((OneAxisInputControl)device.Action2).WasPressed || device.CommandWasPressed) && PauseLock.IsPauser(device))
				{
					seat = seat4;
					save = false;
				}
			}
			if (seat != null)
			{
				Leave(save);
			}
			else
			{
				Draw();
			}
		}

		private static void Draw()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_0101: Invalid comparison between Unknown and I4
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: 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_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)noPads != (Object)null)
			{
				noPads.SetActive(seats.Count == 0);
			}
			if (seats.Count > 0)
			{
				float num = -400f;
				float num2 = X(seats.Count - 1) + 66f;
				table.anchoredPosition = new Vector2((0f - (num + num2)) / 2f, 0f);
			}
			for (int i = 0; i < 4; i++)
			{
				Seat seat = ((i < seats.Count) ? seats[i] : null);
				((Component)tags[i]).gameObject.SetActive(seat != null);
				for (int j = 0; j <= 4; j++)
				{
					((Component)cells[j, i]).gameObject.SetActive(seat != null);
				}
				if (seat == null)
				{
					continue;
				}
				Color val = Ui.PlayerColor(seat.Player);
				int playerID = seat.Player.playerID;
				if ((int)tags[i].alignment != 514)
				{
					tags[i].alignment = (TextAlignmentOptions)514;
				}
				Texts.Set(tags[i], (playerID >= 0 && playerID < PlayerTags.Length) ? PlayerTags[playerID] : ("P" + (playerID + 1)));
				((Graphic)tags[i]).color = val;
				for (int k = 0; k <= 4; k++)
				{
					bool flag = seat.Row == k;
					((Graphic)cells[k, i]).color = (flag ? selColor : boxColor);
					TMP_Text val2 = cellTexts[k, i];
					if (!((Object)(object)val2 == (Object)null))
					{
						if (k < 4)
						{
							bool flag2 = !Same(seat.Pending[k], seat.Saved[k]);
							InputDeviceStyle style = (InputDeviceStyle)((seat.Device != null) ? ((int)seat.Device.DeviceStyle) : 0);
							Texts.Set(val2, (!flag || !seat.Listening) ? (PadLayout.Names(seat.Pending[k], style) + (flag2 ? "*" : "")) : ((seat.Held.Count > 0) ? PadLayout.Names(seat.Held.ToArray(), style) : "PRESS"));
						}
						Color color = (flag ? val : boxText);
						if (flag && seat.Listening)
						{
							color.a = 0.55f + 0.45f * Mathf.Abs(Mathf.Sin(Time.unscaledTime * 5f));
						}
						((Graphic)val2).color = color;
					}
				}
			}
			for (int l = 0; l < 3; l++)
			{
				Seat seat2 = null;
				foreach (Seat seat3 in seats)
				{
					if (seat3.Row == 5 && seat3.Bottom == l)
					{
						seat2 = seat3;
						break;
					}
				}
				((Graphic)bottoms[l]).color = ((seat2 != null) ? selColor : boxColor);
				if ((Object)(object)bottomTexts[l] != (Object)null)
				{
					((Graphic)bottomTexts[l]).color = ((seat2 != null) ? Ui.PlayerColor(seat2.Player) : boxText);
				}
			}
		}

		private static bool Same(InputControlType[] a, InputControlType[] b)
		{
			if (a.Length != b.Length)
			{
				return false;
			}
			for (int i = 0; i < a.Length; i++)
			{
				if ((int)a[i] != (int)b[i])
				{
					return false;
				}
			}
			return true;
		}
	}
	internal sealed class MapPage : TwoPanePage
	{
		internal static MapPage Instance;

		private static readonly FieldRef<MapSelectionHandler, List<MapCategoryUI>> categoriesRef = AccessTools.FieldRefAccess<MapSelectionHandler, List<MapCategoryUI>>("m_Categories");

		private static readonly FieldRef<MapSelectionHandler, Toggle> randomToggleRef = AccessTools.FieldRefAccess<MapSelectionHandler, Toggle>("m_RandomOrderMapsToggle");

		private static readonly FieldRef<MapSelectionHandler, bool> randomRef = AccessTools.FieldRefAccess<MapSelectionHandler, bool>("m_RandomOrderMaps");

		private static readonly FieldRef<MapSelectionHandler, Texture2D> defaultTexRef = AccessTools.FieldRefAccess<MapSelectionHandler, Texture2D>("m_DefaultPreviewTexture");

		private static readonly FieldRef<MapSelectionHandler, MapSelectionPreviewUI> previewRef = AccessTools.FieldRefAccess<MapSelectionHandler, MapSelectionPreviewUI>("m_PreviewUI");

		private static readonly FieldRef<MapSelectionPreviewUI, Image> previewImageRef = AccessTools.FieldRefAccess<MapSelectionPreviewUI, Image>("m_Image");

		private static readonly FieldRef<PauseManager, CodeStateAnimation> mapAnimRef = AccessTools.FieldRefAccess<PauseManager, CodeStateAnimation>("mapAnim");

		private static readonly MethodInfo toggleMap = AccessTools.Method(typeof(MapSelectionHandler), "ToggleMapActive", (Type[])null, (Type[])null);

		private static readonly MethodInfo saveMaps = AccessTools.Method(typeof(MapSelectionHandler), "UpdateSavedData", (Type[])null, (Type[])null);

		private MapSelectionHandler handler;

		private readonly List<MapCategoryUI> shownCats = new List<MapCategoryUI>();

		private readonly List<CanvasGroup> concealed = new List<CanvasGroup>();

		private Image previewImage;

		private readonly Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>();

		private readonly List<Object> made = new List<Object>();

		private Sprite defaultSprite;

		private SingleMapUI previewed;

		private readonly Dictionary<SingleMapUI, string> names = new Dictionary<SingleMapUI, string>();

		private int orderShown = -1;

		protected override bool IsOpen
		{
			get
			{
				if ((Object)(object)pause == (Object)null || !PauseManager.isPaused)
				{
					return false;
				}
				CodeStateAnimation val = mapAnimRef.Invoke(pause);
				if ((Object)(object)val != (Object)null)
				{
					return !val.state1;
				}
				return false;
			}
		}

		protected override int CategoryCount => shownCats.Count;

		private bool Random => randomRef.Invoke(handler);

		private string OrderText
		{
			get
			{
				if (!Random)
				{
					return "PLAYED IN ORDER";
				}
				return "RANDOM ORDER";
			}
		}

		public static void Create(MapSelectionHandler handler)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			PauseManager val = ((Component)handler).GetComponent<PauseManager>();
			if ((Object)(object)val == (Object)null)
			{
				val = Object.FindObjectOfType<PauseManager>();
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val.mapSelection == (Object)null)
			{
				throw new Exception("the pause menu wasn't found");
			}
			Transform val2 = val.mapSelection.transform.Find("Scaler");
			if ((Object)(object)val2 == (Object)null || (Object)(object)val2.Find("MapCategories") == (Object)null)
			{
				throw new Exception("the game's map rows weren't found");
			}
			if (categoriesRef.Invoke(handler) == null)
			{
				throw new Exception("the game's map list wasn't found");
			}
			Transform val3 = val2.Find("BackButton");
			GameObject val4 = new GameObject("MenuOverhaul.MapPage", new Type[1] { typeof(RectTransform) });
			val4.layer = ((Component)val2).gameObject.layer;
			val4.transform.SetParent(val2, false);
			MapPage mapPage = val4.AddComponent<MapPage>();
			try
			{
				mapPage.handler = handler;
				mapPage.UsePreview();
				mapPage.Init((RectTransform)val4.transform, ((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<Button>() : null, val);
				mapPage.Build();
				string[] array = new string[5] { "MapCategories", "Selector", "Arrows", "RandomOrderButton", "MapPreview" };
				foreach (string text in array)
				{
					mapPage.Hide(val2.Find(text));
				}
				MapSelectionPreviewUI val5 = previewRef.Invoke(handler);
				if ((Object)(object)val5 != (Object)null)
				{
					mapPage.Hide(((Component)val5).transform);
					Image val6 = previewImageRef.Invoke(val5);
					if ((Object)(object)val6 != (Object)null)
					{
						mapPage.Hide(((Component)val6).transform);
					}
				}
				Transform val7 = val2.Find("TitleText");
				if (val7 is RectTransform)
				{
					((RectTransform)val7).anchoredPosition = new Vector2(0f, 392f);
				}
			}
			catch
			{
				mapPage.Undo();
				Object.DestroyImmediate((Object)(object)val4);
				throw;
			}
			Instance = mapPage;
		}

		private void Hide(Transform t)
		{
			if (!((Object)(object)t == (Object)null))
			{
				TwoPanePage.Conceal(((Component)t).gameObject);
				concealed.Add(((Component)t).GetComponent<CanvasGroup>());
			}
		}

		private void Undo()
		{
			foreach (CanvasGroup item in concealed)
			{
				if ((Object)(object)item != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)item);
				}
			}
			concealed.Clear();
			RestoreBack();
		}

		protected override void BuildExtra()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			previewImage = Ui.Box(((Component)PreviewFrame).transform, "Preview", Color.white, Vector2.zero, new Vector2(498f, 256f));
			previewImage.preserveAspect = true;
			((Behaviour)previewImage).enabled = false;
		}

		protected override void Refresh()
		{
			shownCats.Clear();
			names.Clear();
			previewed = null;
			List<MapCategoryUI> list = categoriesRef.Invoke(handler);
			if (list == null)
			{
				return;
			}
			foreach (MapCategoryUI item in list)
			{
				if (item != null && item.CategoryMaps.Count > 0)
				{
					shownCats.Add(item);
				}
			}
		}

		protected override string CategoryName(int c)
		{
			return DisplayName(shownCats[c]);
		}

		protected override bool CategoryOn(int c)
		{
			return shownCats[c].IsActive;
		}

		protected override int ItemCount(int c)
		{
			if (c < 0 || c >= shownCats.Count)
			{
				return 0;
			}
			return shownCats[c].CategoryMaps.Count;
		}

		protected override bool ItemOn(int c, int i)
		{
			if (Map(c, i) != null)
			{
				return Map(c, i).IsLocallyActive;
			}
			return false;
		}

		protected override string ItemName(int c, int i)
		{
			SingleMapUI val = Map(c, i);
			if (val == null)
			{
				return "";
			}
			if (!names.TryGetValue(val, out var value))
			{
				value = (names[val] = MapName(shownCats[c], val));
			}
			return value;
		}

		private SingleMapUI Map(int c, int i)
		{
			if (c < 0 || c >= shownCats.Count)
			{
				return null;
			}
			List<SingleMapUI> categoryMaps = shownCats[c].CategoryMaps;
			if (i < 0 || i >= categoryMaps.Count)
			{
				return null;
			}
			return categoryMaps[i];
		}

		private unsafe static bool Is(MapCategoryUI c, MapWorldsEnum world)
		{
			return string.Equals(c.CategoryName, ((object)(*(MapWorldsEnum*)(&world))/*cast due to .constrained prefix*/).ToString(), StringComparison.OrdinalIgnoreCase);
		}

		private static string DisplayName(MapCategoryUI c)
		{
			if (Is(c, (MapWorldsEnum)10))
			{
				return "MY MAPS";
			}
			if (Is(c, (MapWorldsEnum)11))
			{
				return "WORKSHOP";
			}
			return (c.CategoryName ?? "").ToUpperInvariant();
		}

		private static string MapName(MapCategoryUI c, SingleMapUI m)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			string text = m.MapName ?? "";
			string text2 = c.CategoryName ?? "";
			if ((int)m.MapTypeEnum == 0 && text2.Length > 0 && text.Length > text2.Length && text.StartsWith(text2, StringComparison.OrdinalIgnoreCase))
			{
				string text3 = text.Substring(text2.Length);