Decompiled source of AAABuildMenu v1.0.4

AAABuildMenu.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.ObjectPool;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("AAABuildMenu")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: AssemblyProduct("AAABuildMenu")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: AssemblyFileVersion("1.0.4")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.4.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		public ExtensionMarkerAttribute(string name)
		{
		}
	}
}
namespace LocalizationManager
{
	[PublicAPI]
	public class Localizer
	{
		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		private static BaseUnityPlugin? _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		public static event Action? OnLocalizationComplete;

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out string value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value2))
			{
				text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += delegate
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static void Load()
		{
			_ = plugin;
		}

		public static void LoadLocalizationLater(Localization __instance)
		{
			LoadLocalization(Localization.instance, __instance.GetSelectedLanguage());
		}

		public static void SafeCallLocalizeComplete()
		{
			Localizer.OnLocalizationComplete?.Invoke();
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
				where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
				select f)
			{
				string[] array = Path.GetFileNameWithoutExtension(item).Split(new char[1] { '.' });
				if (array.Length >= 2)
				{
					string text = array[1];
					if (dictionary.ContainsKey(text))
					{
						Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
					}
					else
					{
						dictionary[text] = item;
					}
				}
			}
			byte[] array2 = LoadTranslationFromAssembly("English");
			if (array2 == null)
			{
				throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml.");
			}
			Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array2));
			if (dictionary2 == null)
			{
				throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text2 = null;
			if (language != "English")
			{
				if (dictionary.TryGetValue(language, out var value))
				{
					text2 = File.ReadAllText(value);
				}
				else
				{
					byte[] array3 = LoadTranslationFromAssembly(language);
					if (array3 != null)
					{
						text2 = Encoding.UTF8.GetString(array3);
					}
				}
			}
			if (text2 == null && dictionary.TryGetValue("English", out var value2))
			{
				text2 = File.ReadAllText(value2);
			}
			if (text2 != null)
			{
				foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>())
				{
					dictionary2[item2.Key] = item2.Value;
				}
			}
			loadedTexts[language] = dictionary2;
			foreach (KeyValuePair<string, string> item3 in dictionary2)
			{
				UpdatePlaceholderText(__instance, item3.Key);
			}
		}

		static Localizer()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string>(2) { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "SetupGui", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalizationLater", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "SafeCallLocalizeComplete", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static byte[]? LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
	public static class LocalizationManagerVersion
	{
		public const string Version = "1.4.1";
	}
}
namespace AAABuildMenu
{
	public static class BuildMenuKeyHints
	{
		private static GameObject? _rowHolder;

		private static GameObject? _favoriteRow;

		private static GameObject? _pinRow;

		private static GameObject? _searchRow;

		private const string FavoriteToken = "$aaabuildmenu_hint_favorite";

		private const string PinToken = "$aaabuildmenu_hint_pin";

		private const string SearchToken = "$aaabuildmenu_hint_search";

		private static TMP_Text? _favoriteKey;

		private static TMP_Text? _pinKey;

		private static TMP_Text? _searchKey;

		private static TMP_Text? _favoriteLabel;

		private static TMP_Text? _pinLabel;

		private static TMP_Text? _searchLabel;

		private static bool _configHooked;

		private static KeyHints? _owner;

		public static void Refresh(KeyHints kh)
		{
			if (!((Object)(object)kh == (Object)null) && !((Object)(object)kh.m_buildHints == (Object)null))
			{
				if ((Object)(object)_owner != (Object)(object)kh)
				{
					_rowHolder = (_favoriteRow = (_pinRow = (_searchRow = null)));
					_favoriteKey = (_pinKey = (_searchKey = null));
					_favoriteLabel = (_pinLabel = (_searchLabel = null));
					_owner = kh;
				}
				if (AAABuildMenuPlugin.ShowKeyHints.Value.IsOff())
				{
					SetActive(_rowHolder, active: false);
					return;
				}
				EnsureRows(kh);
				SetActive(_favoriteRow, active: true);
				SetActive(_pinRow, AAABuildMenuPlugin.EnablePinning.Value.IsOn());
				SetActive(_searchRow, AAABuildMenuPlugin.EnableSearch.Value.IsOn());
				Transform keyboardGroup = GetKeyboardGroup(kh);
				bool flag = (Object)(object)keyboardGroup != (Object)null && ((Component)keyboardGroup).gameObject.activeInHierarchy;
				SetActive(_rowHolder, Hud.IsPieceSelectionVisible() && flag);
			}
		}

		private static Transform? GetKeyboardGroup(KeyHints kh)
		{
			UIInputHint component = kh.m_buildHints.GetComponent<UIInputHint>();
			GameObject val = (((Object)(object)component != (Object)null) ? component.m_mouseKeyboardHint : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.transform;
		}

		private static void EnsureRows(KeyHints kh)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			Transform keyboardGroup = GetKeyboardGroup(kh);
			Transform val = (((Object)(object)keyboardGroup != (Object)null) ? FindHintItemTemplate(keyboardGroup) : null);
			if (!((Object)(object)keyboardGroup == (Object)null) && !((Object)(object)val == (Object)null))
			{
				if ((Object)(object)_rowHolder == (Object)null)
				{
					_rowHolder = CreateRowHolder(kh, (RectTransform)keyboardGroup);
				}
				Transform transform = _rowHolder.transform;
				Transform template = keyboardGroup.Find("Copy") ?? val;
				string mouseLeft = GetKeycapText(keyboardGroup.Find("Place")) ?? "Mouse-1";
				if ((Object)(object)_favoriteRow == (Object)null)
				{
					_favoriteRow = CreateClickRow(template, transform, "AAABuildMenu_FavoriteHint", "$aaabuildmenu_hint_favorite", mouseLeft, out _favoriteKey, out _favoriteLabel);
				}
				if ((Object)(object)_pinRow == (Object)null)
				{
					_pinRow = CreateClickRow(template, transform, "AAABuildMenu_PinHint", "$aaabuildmenu_hint_pin", mouseLeft, out _pinKey, out _pinLabel);
				}
				if ((Object)(object)_searchRow == (Object)null)
				{
					_searchRow = CreateSingleKeyRow(val, transform, "AAABuildMenu_SearchHint", "$aaabuildmenu_hint_search", out _searchKey, out _searchLabel);
				}
				ApplyKeyText();
				HookConfigOnce();
			}
		}

		private static void ApplyKeyText()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_favoriteKey != (Object)null)
			{
				_favoriteKey.text = Format(AAABuildMenuPlugin.QuickFavoriteModifier.Value);
			}
			if ((Object)(object)_pinKey != (Object)null)
			{
				_pinKey.text = Format(AAABuildMenuPlugin.QuickPinModifier.Value);
			}
			if ((Object)(object)_searchKey != (Object)null)
			{
				_searchKey.text = Format(AAABuildMenuPlugin.FocusSearchKey.Value);
			}
		}

		private static void OnLanguageChanged()
		{
			if ((Object)(object)_favoriteLabel != (Object)null)
			{
				_favoriteLabel.text = Localization.instance.Localize("$aaabuildmenu_hint_favorite");
			}
			if ((Object)(object)_pinLabel != (Object)null)
			{
				_pinLabel.text = Localization.instance.Localize("$aaabuildmenu_hint_pin");
			}
			if ((Object)(object)_searchLabel != (Object)null)
			{
				_searchLabel.text = Localization.instance.Localize("$aaabuildmenu_hint_search");
			}
		}

		private static void HookConfigOnce()
		{
			if (!_configHooked)
			{
				_configHooked = true;
				AAABuildMenuPlugin.QuickFavoriteModifier.SettingChanged += Apply;
				AAABuildMenuPlugin.QuickPinModifier.SettingChanged += Apply;
				AAABuildMenuPlugin.FocusSearchKey.SettingChanged += Apply;
				Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(OnLanguageChanged));
			}
			static void Apply(object _, EventArgs __)
			{
				ApplyKeyText();
			}
		}

		private static GameObject CreateRowHolder(KeyHints kh, RectTransform vanillaRow)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_004d: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			GameObject val = new GameObject("AAABuildMenu_HintRow");
			val.transform.SetParent(kh.m_buildHints.transform, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = vanillaRow.anchorMin;
			obj.anchorMax = vanillaRow.anchorMax;
			obj.pivot = vanillaRow.pivot;
			obj.sizeDelta = vanillaRow.sizeDelta;
			Rect rect = vanillaRow.rect;
			float num = ((Rect)(ref rect)).height;
			if (num <= 1f)
			{
				num = 34f;
			}
			obj.anchoredPosition = vanillaRow.anchoredPosition + new Vector2(0f, num + 6f);
			HorizontalLayoutGroup component = ((Component)vanillaRow).GetComponent<HorizontalLayoutGroup>();
			HorizontalLayoutGroup val2 = val.AddComponent<HorizontalLayoutGroup>();
			if ((Object)(object)component != (Object)null)
			{
				((HorizontalOrVerticalLayoutGroup)val2).spacing = ((HorizontalOrVerticalLayoutGroup)component).spacing;
				((LayoutGroup)val2).padding = ((LayoutGroup)component).padding;
				((LayoutGroup)val2).childAlignment = ((LayoutGroup)component).childAlignment;
				((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = ((HorizontalOrVerticalLayoutGroup)component).childControlWidth;
				((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = ((HorizontalOrVerticalLayoutGroup)component).childControlHeight;
				((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth;
				((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight;
				return val;
			}
			((LayoutGroup)val2).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false;
			return val;
		}

		private static GameObject CreateClickRow(Transform template, Transform container, string name, string labelToken, string mouseLeft, out TMP_Text? modifierKey, out TMP_Text? label)
		{
			GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, container);
			((Object)val).name = name;
			val.transform.SetAsLastSibling();
			List<TMP_Text> list = CollectKeycaps(val.transform);
			modifierKey = ((list.Count > 0) ? list[0] : null);
			if (list.Count >= 2)
			{
				list[1].text = mouseLeft;
			}
			label = SetLabel(val.transform, labelToken);
			val.SetActive(false);
			return val;
		}

		private static GameObject CreateSingleKeyRow(Transform template, Transform container, string name, string labelToken, out TMP_Text? key, out TMP_Text? label)
		{
			GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, container);
			((Object)val).name = name;
			val.transform.SetAsLastSibling();
			Transform val2 = val.transform.Find("key_bkg/Key");
			key = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<TMP_Text>() : null);
			label = SetLabel(val.transform, labelToken);
			val.SetActive(false);
			return val;
		}

		private static TMP_Text? SetLabel(Transform row, string labelToken)
		{
			Transform val = row.Find("Text");
			TMP_Text val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<TMP_Text>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			Localize component = ((Component)val2).GetComponent<Localize>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			val2.text = Localization.instance.Localize(labelToken);
			val2.textWrappingMode = (TextWrappingModes)0;
			val2.overflowMode = (TextOverflowModes)0;
			return val2;
		}

		private static List<TMP_Text> CollectKeycaps(Transform row)
		{
			List<TMP_Text> list = new List<TMP_Text>();
			for (int i = 0; i < row.childCount; i++)
			{
				Transform child = row.GetChild(i);
				if (((Object)child).name.StartsWith("key_bkg"))
				{
					Transform val = child.Find("Key");
					TMP_Text val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<TMP_Text>() : null);
					if ((Object)(object)val2 != (Object)null)
					{
						list.Add(val2);
					}
				}
			}
			return list;
		}

		private static string? GetKeycapText(Transform? item)
		{
			if ((Object)(object)item == (Object)null)
			{
				return null;
			}
			Transform val = item.Find("key_bkg/Key");
			TMP_Text val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<TMP_Text>() : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return val2.text;
		}

		private static Transform? FindHintItemTemplate(Transform keyboardGroup)
		{
			for (int i = 0; i < keyboardGroup.childCount; i++)
			{
				Transform child = keyboardGroup.GetChild(i);
				if (!((Object)child).name.StartsWith("AAABuildMenu_") && (Object)(object)child.Find("key_bkg/Key") != (Object)null && (Object)(object)child.Find("Text") != (Object)null)
				{
					return child;
				}
			}
			return null;
		}

		private static void SetActive(GameObject? go, bool active)
		{
			if ((Object)(object)go != (Object)null && go.activeSelf != active)
			{
				go.SetActive(active);
			}
		}

		private static string Format(KeyboardShortcut shortcut)
		{
			//IL_0002: 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)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0)
			{
				return "";
			}
			List<string> list = ((KeyboardShortcut)(ref shortcut)).Modifiers.Select(Pretty).ToList();
			list.Add(Pretty(((KeyboardShortcut)(ref shortcut)).MainKey));
			return string.Join("+", list);
		}

		private unsafe static string Pretty(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected I4, but got Unknown
			switch (key - 303)
			{
			case 0:
			case 1:
				return "Shift";
			case 2:
			case 3:
				return "Ctrl";
			case 4:
			case 5:
				return "Alt";
			default:
				return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
			}
		}
	}
	[RequireComponent(typeof(CanvasGroup))]
	public abstract class BuildMenuGripHandle : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IBeginDragHandler, IDragHandler, IEndDragHandler
	{
		private CanvasGroup _cg;

		private float _scale = 1f;

		private bool _dragging;

		private bool _hovered;

		protected virtual void Awake()
		{
			_cg = ((Component)this).GetComponent<CanvasGroup>();
			Canvas componentInParent = ((Component)this).GetComponentInParent<Canvas>();
			if ((Object)(object)componentInParent != (Object)null && componentInParent.scaleFactor > 0f)
			{
				_scale = componentInParent.scaleFactor;
			}
		}

		private void Update()
		{
			float num = ((_dragging || _hovered) ? 1f : 0f);
			_cg.alpha = Mathf.MoveTowards(_cg.alpha, num, Time.unscaledDeltaTime * 8f);
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			_hovered = true;
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			_hovered = false;
		}

		public void OnBeginDrag(PointerEventData eventData)
		{
			_dragging = true;
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			Apply(eventData.delta / _scale);
		}

		public void OnEndDrag(PointerEventData eventData)
		{
			_dragging = false;
			DragEnded();
		}

		protected abstract void Apply(Vector2 scaledDelta);

		protected virtual void DragEnded()
		{
			EnhancedBuildMenu.OnGripDragEnd();
		}
	}
	public class DelegateGripHandle : BuildMenuGripHandle
	{
		public Action<Vector2>? Dragged;

		public Action? Ended;

		protected override void Apply(Vector2 scaledDelta)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Dragged?.Invoke(scaledDelta);
		}

		protected override void DragEnded()
		{
			Ended?.Invoke();
		}
	}
	public class BuildMenuResizeHandle : BuildMenuGripHandle
	{
		protected override void Apply(Vector2 scaledDelta)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			EnhancedBuildMenu.OnResizeDrag(scaledDelta);
		}
	}
	public class BuildMenuMoveHandle : BuildMenuGripHandle
	{
		protected override void Apply(Vector2 scaledDelta)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			EnhancedBuildMenu.OnMoveDrag(scaledDelta);
		}
	}
	[HarmonyPatch]
	public static class ClassicBuildMenu
	{
		private const string PieceManagerHarmonyId = "org.bepinex.helpers.PieceManager";

		private const string JotunnHarmonyId = "com.jotunn.jotunn";

		private static bool? _tabManagerPresent;

		internal static bool Enabled => AAABuildMenuPlugin.UseClassicMenu.Value.IsOn();

		private static bool TabManagerPresent
		{
			get
			{
				bool valueOrDefault = _tabManagerPresent == true;
				if (!_tabManagerPresent.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.jotunn.jotunn") || AppDomain.CurrentDomain.GetAssemblies().Any(delegate(Assembly a)
					{
						try
						{
							return a.GetType("PieceManager.PiecePrefabManager", throwOnError: false) != null;
						}
						catch
						{
							return false;
						}
					});
					_tabManagerPresent = valueOrDefault;
					return valueOrDefault;
				}
				return valueOrDefault;
			}
		}

		private static bool On(Hud? hud)
		{
			if (Enabled && (Object)(object)hud != (Object)null && (Object)(object)hud.m_pieceSelectionWindow != (Object)null)
			{
				return (Object)(object)hud.m_buildUi != (Object)null;
			}
			return false;
		}

		private static void SetWindow(Hud hud, bool open)
		{
			hud.m_pieceSelectionWindow.SetActive(open);
			if ((Object)(object)hud.m_closePieceSelectionButton != (Object)null)
			{
				((Component)hud.m_closePieceSelectionButton).gameObject.SetActive(open);
			}
		}

		internal static void OnSettingChanged()
		{
			Hud instance = Hud.instance;
			if ((Object)(object)instance != (Object)null)
			{
				if (Enabled && !EnhancedBuildMenu.IsInitialized && AAABuildMenuPlugin.EnableEnhancedMenu.Value.IsOn() && !EnhancedBuildMenuPatches.ConflictingMenuModInstalled())
				{
					EnhancedBuildMenu.InitializeUI(instance);
				}
				if ((Object)(object)instance.m_pieceSelectionWindow != (Object)null)
				{
					SetWindow(instance, open: false);
				}
				if ((Object)(object)instance.m_buildUi != (Object)null && ((Component)instance.m_buildUi).gameObject.activeSelf)
				{
					instance.m_buildUi.Close();
				}
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.m_buildPieces != (Object)null)
			{
				localPlayer.UpdateAvailablePiecesList();
			}
		}

		[HarmonyPatch(typeof(Hud), "TogglePieceSelection")]
		[HarmonyPrefix]
		private static bool Hud_TogglePieceSelection(Hud __instance)
		{
			if (!On(__instance))
			{
				return true;
			}
			__instance.m_hoveredPiece = null;
			if (__instance.m_pieceSelectionWindow.activeSelf)
			{
				PlayerController.SetTakeInputDelay(0.2f);
				SetWindow(__instance, open: false);
			}
			else
			{
				if (((Component)__instance.m_buildUi).gameObject.activeSelf)
				{
					__instance.m_buildUi.Close();
				}
				SetWindow(__instance, open: true);
				__instance.UpdateBuild(Player.m_localPlayer, true);
			}
			return false;
		}

		[HarmonyPatch(typeof(Hud), "HidePieceSelection")]
		[HarmonyPrefix]
		private static bool Hud_HidePieceSelection()
		{
			Hud instance = Hud.instance;
			if (!On(instance))
			{
				return true;
			}
			instance.m_pressedPiece = null;
			instance.m_closePieceSelection = 2;
			return false;
		}

		[HarmonyPatch(typeof(Hud), "IsPieceSelectionVisible")]
		[HarmonyPrefix]
		private static bool Hud_IsPieceSelectionVisible(ref bool __result)
		{
			Hud instance = Hud.instance;
			if (!On(instance))
			{
				return true;
			}
			__result = instance.m_buildHud.activeSelf && instance.m_pieceSelectionWindow.activeSelf;
			return false;
		}

		[HarmonyPatch(typeof(Hud), "InBuildUi")]
		[HarmonyPostfix]
		private static void Hud_InBuildUi(ref bool __result)
		{
			if (!__result && On(Hud.instance))
			{
				__result = Hud.IsPieceSelectionVisible();
			}
		}

		[HarmonyPatch(typeof(Hud), "OnLeftClickCategory")]
		[HarmonyPrefix]
		private static void Hud_OnLeftClickCategory()
		{
			if (On(Hud.instance))
			{
				EnhancedBuildMenu.OnCategoryPicked();
			}
		}

		[HarmonyPatch(typeof(BuildUi), "OpenBuildMenu")]
		[HarmonyPrefix]
		private static bool BuildUi_OpenBuildMenu()
		{
			return !On(Hud.instance);
		}

		[HarmonyPatch(typeof(Hud), "UpdateBuild")]
		[HarmonyPrefix]
		[HarmonyPriority(0)]
		[HarmonyAfter(new string[] { "org.bepinex.helpers.PieceManager", "com.jotunn.jotunn" })]
		private static bool Hud_UpdateBuild(Hud __instance, Player player, bool forceUpdateAllBuildStatuses)
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			if (!On(__instance))
			{
				return true;
			}
			EnhancedBuildMenuPatches.BeforeUpdateBuild(player);
			if (((Component)__instance.m_buildUi).gameObject.activeSelf)
			{
				__instance.m_buildUi.Close();
			}
			if (!((Character)player).InPlaceMode())
			{
				__instance.m_hoveredPiece = null;
				__instance.m_buildHud.SetActive(false);
				SetWindow(__instance, open: false);
				return false;
			}
			if (__instance.m_closePieceSelection > 0)
			{
				__instance.m_closePieceSelection--;
				if (__instance.m_closePieceSelection <= 0 && __instance.m_pieceSelectionWindow.activeSelf)
				{
					__instance.m_hoveredPiece = null;
					SetWindow(__instance, open: false);
					Character.SetTakeInputDelay(0.2f);
					PlayerController.SetTakeInputDelay(0.2f);
				}
			}
			Piece val = default(Piece);
			Vector2Int val2 = default(Vector2Int);
			int num = default(int);
			PieceCategory val3 = default(PieceCategory);
			PieceTable pieceTable = default(PieceTable);
			player.GetBuildSelection(ref val, ref val2, ref num, ref val3, ref pieceTable);
			__instance.m_buildHud.SetActive(!__instance.m_radialMenu.Active);
			if (__instance.m_pieceSelectionWindow.activeSelf)
			{
				__instance.UpdatePieceList(player, val2, val3, forceUpdateAllBuildStatuses);
				UpdateTabs(__instance, player, pieceTable, val3);
				Localization.instance.Localize(__instance.m_buildHud.transform);
			}
			if ((Object)(object)__instance.m_hoveredPiece != (Object)null && (ZInput.IsGamepadActive() || !player.IsPieceAvailable(__instance.m_hoveredPiece)))
			{
				__instance.m_hoveredPiece = null;
			}
			__instance.SetupPieceInfo(((Object)(object)__instance.m_hoveredPiece != (Object)null) ? __instance.m_hoveredPiece : val);
			return false;
		}

		private static void UpdateTabs(Hud hud, Player player, PieceTable pieceTable, PieceCategory category)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			hud.m_pieceCategoryRoot.SetActive(pieceTable.m_categories.Count > 0);
			if (pieceTable.m_categories.Count == 0)
			{
				return;
			}
			EnsureTabCount(hud, pieceTable.m_categories.Count);
			for (int i = 0; i < hud.m_pieceCategoryTabs.Length; i++)
			{
				GameObject val = hud.m_pieceCategoryTabs[i];
				bool flag = i < pieceTable.m_categories.Count;
				val.SetActive(flag);
				if (!flag)
				{
					continue;
				}
				string arg = TabLabel(pieceTable, i);
				PieceCategory val2 = pieceTable.m_categories[i];
				int num = EnhancedBuildMenu.UnfilteredCount(val2, player.GetAvailableBuildPiecesInCategory(val2));
				string text = $"{arg} [<color=yellow>{num}</color>]";
				Transform val3 = val.transform.Find("Selected");
				bool flag2 = pieceTable.m_categories[i] == category;
				if ((Object)(object)val3 != (Object)null)
				{
					((Component)val3).gameObject.SetActive(flag2);
					if (flag2)
					{
						((Component)val3).GetComponentInChildren<TMP_Text>().text = text;
					}
				}
				if (!flag2 || (Object)(object)val3 == (Object)null)
				{
					val.GetComponentInChildren<TMP_Text>().text = text;
				}
			}
		}

		private static string TabLabel(PieceTable table, int i)
		{
			//IL_0007: 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)
			string text = ((object)table.m_categories[i]/*cast due to .constrained prefix*/).ToString();
			string text2 = ((i < table.m_categoryLabels.Count) ? table.m_categoryLabels[i] : "");
			if (!string.IsNullOrWhiteSpace(text2) && !string.Equals(text2, text, StringComparison.OrdinalIgnoreCase))
			{
				return text2;
			}
			string text3 = "biome_" + text.ToLowerInvariant();
			if (Localization.instance.m_translations.ContainsKey(text3))
			{
				return "$" + text3;
			}
			return Regex.Replace(text, "(?<=[a-z])(?=[A-Z])", " ");
		}

		private static void EnsureTabCount(Hud hud, int needed)
		{
			if (TabManagerPresent)
			{
				return;
			}
			GameObject[] pieceCategoryTabs = hud.m_pieceCategoryTabs;
			if (pieceCategoryTabs.Length >= needed || pieceCategoryTabs.Length == 0)
			{
				return;
			}
			GameObject val = pieceCategoryTabs[^1];
			GameObject[] array = (GameObject[])(object)new GameObject[needed];
			Array.Copy(pieceCategoryTabs, array, pieceCategoryTabs.Length);
			for (int i = pieceCategoryTabs.Length; i < needed; i++)
			{
				GameObject val2 = Object.Instantiate<GameObject>(val, val.transform.parent);
				((Object)val2).name = "Tab" + i;
				UIInputHandler component = val2.GetComponent<UIInputHandler>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_onLeftDown = (Action<UIInputHandler>)Delegate.Combine(component.m_onLeftDown, new Action<UIInputHandler>(hud.OnLeftClickCategory));
				}
				array[i] = val2;
			}
			hud.m_pieceCategoryTabs = array;
		}

		[HarmonyPatch(typeof(Player), "UpdateBuildGuiInput")]
		[HarmonyPrefix]
		private static bool Player_UpdateBuildGuiInput(Player __instance)
		{
			if (!On(Hud.instance))
			{
				return true;
			}
			try
			{
				if (ZInput.IsNonClassicFunctionality() && ZInput.IsGamepadActive())
				{
					AlternativeLayoutInput(__instance);
				}
				else
				{
					DefaultInput(__instance);
				}
			}
			catch (Exception ex)
			{
				AAABuildMenuPlugin.LogErrorOnce("classic build menu input", ex);
			}
			return false;
		}

		private static void DefaultInput(Player player)
		{
			if (!Hud.IsPieceSelectionVisible())
			{
				if (ZInput.GetButtonDown("BuildMenu") && !PlayerController.HasInputDelay && !Hud.InRadial())
				{
					Hud.instance.TogglePieceSelection();
				}
				else if (ZInput.GetButtonDown("JoyUse") && !PlayerController.HasInputDelay && !Hud.InRadial())
				{
					Hud.instance.TogglePieceSelection();
				}
				return;
			}
			if (ZInput.GetKeyDown((KeyCode)27, true) || ZInput.GetButtonDown("JoyButtonB") || ZInput.GetButtonDown("BuildMenu"))
			{
				Hud.HidePieceSelection();
			}
			if (ZInput.GetButtonDown("JoyUse"))
			{
				Hud.HidePieceSelection();
				player.PlayButtonSound();
			}
			MenuNavigation(player);
		}

		private static void AlternativeLayoutInput(Player player)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			PieceTable buildPieces = player.m_buildPieces;
			if (!Hud.IsPieceSelectionVisible())
			{
				if (ZInput.GetButtonDown("JoyBuildMenu") && !PlayerController.HasInputDelay && !Hud.InRadial() && player.m_lastBuildStateFrames > 1)
				{
					player.m_lastBuildStateFrames = 0;
					for (int i = 0; i < buildPieces.m_selectedPiece.Length; i++)
					{
						buildPieces.m_lastSelectedPiece[i] = buildPieces.m_selectedPiece[i];
					}
					Hud.instance.TogglePieceSelection();
				}
				return;
			}
			if (ZInput.GetKeyDown((KeyCode)27, true) || ZInput.GetButtonDown("JoyButtonB") || ZInput.GetButtonDown("BuildMenu"))
			{
				for (int j = 0; j < buildPieces.m_selectedPiece.Length; j++)
				{
					buildPieces.m_selectedPiece[j] = buildPieces.m_lastSelectedPiece[j];
				}
				Hud.HidePieceSelection();
				player.SetupPlacementGhost();
			}
			if (ZInput.GetButtonDown("JoyButtonA"))
			{
				Hud.HidePieceSelection();
				player.PlayButtonSound();
			}
			MenuNavigation(player);
		}

		private static void MenuNavigation(Player player)
		{
			PieceTable buildPieces = player.m_buildPieces;
			player.m_scrollCurrAmount += ZInput.GetMouseScrollWheel();
			if (ZInput.GetButtonDown("JoyTabLeft") || ZInput.GetButtonDown("TabLeft") || player.m_scrollCurrAmount > player.m_scrollAmountThreshold)
			{
				player.m_scrollCurrAmount = 0f;
				EnhancedBuildMenu.OnCategoryPicked();
				buildPieces.PrevCategory();
				player.UpdateAvailablePiecesList();
			}
			if (ZInput.GetButtonDown("JoyTabRight") || ZInput.GetButtonDown("TabRight") || player.m_scrollCurrAmount < 0f - player.m_scrollAmountThreshold)
			{
				player.m_scrollCurrAmount = 0f;
				EnhancedBuildMenu.OnCategoryPicked();
				buildPieces.NextCategory();
				player.UpdateAvailablePiecesList();
			}
			if (ZInput.GetButtonDown("JoyLStickLeft") || ZInput.GetButtonDown("JoyDPadLeft"))
			{
				buildPieces.LeftPiece();
				player.SetupPlacementGhost();
			}
			if (ZInput.GetButtonDown("JoyLStickRight") || ZInput.GetButtonDown("JoyDPadRight"))
			{
				buildPieces.RightPiece();
				player.SetupPlacementGhost();
			}
			if (ZInput.GetButtonDown("JoyLStickUp") || ZInput.GetButtonDown("JoyDPadUp"))
			{
				buildPieces.UpPiece();
				player.SetupPlacementGhost();
			}
			if (ZInput.GetButtonDown("JoyLStickDown") || ZInput.GetButtonDown("JoyDPadDown"))
			{
				buildPieces.DownPiece();
				player.SetupPlacementGhost();
			}
		}
	}
	public static class EnhancedBuildMenu
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Func<Piece, bool> <0>__PieceUsesAnySelectedMaterial;

			public static Func<Piece, int> <1>__TotalResourceCost;

			public static UnityAction<string> <2>__OnSearchTextChanged;

			public static UnityAction <3>__ClearSearch;

			public static UnityAction <4>__ResetAllFilters;

			public static UnityAction <5>__CycleSortMode;

			public static UnityAction <6>__DeselectCurrent;
		}

		internal static int Columns = 15;

		private const float ScrollbarGutter = 10f;

		private static GameObject _searchBarObject = null;

		private static TMP_InputField _searchInputField = null;

		private static ScrollRect _scrollRect = null;

		private static GameObject _clearSearchButton = null;

		private static bool _isInitialized;

		private static readonly PieceFilterState _currentFilter = new PieceFilterState();

		private static GameObject _filterButtonRow = null;

		private static FilterButton? _allButton;

		private static FilterButton _canCraftButton = null;

		private static FilterButton _missingMaterialsButton = null;

		private static FilterButton _favoritesButton = null;

		private static FilterButton? _recentButton;

		private static GameObject _sortButton = null;

		private static TMP_Text _sortButtonText = null;

		private static TMP_Text _matchCountText = null;

		private static GameObject _materialsButton = null;

		private static GameObject _materialsDropdown = null;

		private static TMP_InputField _materialsSearchField = null;

		private static readonly HashSet<string> _selectedMaterials = new HashSet<string>();

		private static readonly Dictionary<GameObject, GameObject> _favoriteStars = new Dictionary<GameObject, GameObject>();

		private static readonly Dictionary<GameObject, GameObject> _favoriteBorders = new Dictionary<GameObject, GameObject>();

		private static Sprite _favoriteBorderSprite = null;

		private static readonly Dictionary<GameObject, GameObject> _pinIndicators = new Dictionary<GameObject, GameObject>();

		private static bool _pinConfigHooked;

		private static readonly Dictionary<Piece, string> _prefabNameCache = new Dictionary<Piece, string>();

		private static readonly Dictionary<PieceCategory, List<Piece>> _categoryMasters = new Dictionary<PieceCategory, List<Piece>>();

		private static Coroutine? _searchDebounceCoroutine;

		private const float SearchDebounceDelay = 0.15f;

		private static Vector2 _origContentSize;

		private static Vector2 _origContentAnchoredPos;

		private static bool _origCaptured;

		private static bool _maskAdjusted;

		private static Vector2 _origMaskOffsetMax;

		private static bool _origMaskCaptured;

		private static bool _liveConfigHooked;

		private const float SearchStripHeight = 30f;

		private const float FilterStripHeight = 26f;

		private const float CountStripHeight = 18f;

		private const float StripGap = 2f;

		private static TMP_FontAsset _uiFont = null;

		private static GameObject _tooltipPrefab = null;

		private static Sprite _buttonSprite = null;

		private static Hud _hud = null;

		private static RectTransform _resizeHandle = null;

		private static RectTransform _moveHandle = null;

		private static Sprite _vanillaButtonSprite = null;

		private static SpriteState _vanillaButtonSpriteState;

		private static ColorBlock _vanillaButtonColors;

		private static bool _vanillaButtonUsesSpriteSwap;

		private static bool _vanillaButtonResolved;

		private static bool _hasVanillaButton;

		private static readonly Color InactiveButtonColor = Color.white;

		private static readonly Color ActiveButtonColor = new Color(1f, 0.78f, 0.36f, 1f);

		private static PieceCategory _lastScrollCategory = (PieceCategory)(-999);

		internal static Piece? SelectedPiece;

		private static readonly HashSet<string> _badPieces = new HashSet<string>();

		private static RectTransform _materialsListContent = null;

		private const float MatDropdownPad = 4f;

		private const float MatSearchHeight = 26f;

		private const float MatScrollbarWidth = 9f;

		private static readonly Color InactiveFilterColor = InactiveButtonColor;

		private static readonly Color ActiveFilterColor = ActiveButtonColor;

		private static Vector2 _origWindowSize;

		private static Vector2 _origWindowPos;

		private static bool _origWinCaptured;

		private static readonly Color GripColor = new Color(0.565f, 0.792f, 0.976f, 0.85f);

		private static bool _sharedReady;

		private static readonly Dictionary<string, Sprite?> _spriteCache = new Dictionary<string, Sprite>();

		private static Sprite[] _allSprites = null;

		private static GameObject? _clickSfxPrefab;

		private static bool _sfxResolved;

		public static bool Active
		{
			get
			{
				if (_isInitialized && AAABuildMenuPlugin.EnableEnhancedMenu.Value.IsOn())
				{
					return ClassicBuildMenu.Enabled;
				}
				return false;
			}
		}

		public static bool NeedsRefresh { get; set; }

		public static bool IsInitialized => _isInitialized;

		private static bool SearchEnabled => AAABuildMenuPlugin.EnableSearch.Value.IsOn();

		private static bool FiltersEnabled => AAABuildMenuPlugin.EnableFilters.Value.IsOn();

		private static bool CountEnabled => AAABuildMenuPlugin.ShowMatchCount.Value.IsOn();

		internal static bool SharedReady => _sharedReady;

		internal static bool ShouldConsumeScroll()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			if (!Active || !Hud.IsPieceSelectionVisible())
			{
				return false;
			}
			Vector2 val = Vector2.op_Implicit(Input.mousePosition);
			if ((Object)(object)_scrollRect != (Object)null && (Object)(object)_scrollRect.viewport != (Object)null && RectTransformUtility.RectangleContainsScreenPoint(_scrollRect.viewport, val, (Camera)null))
			{
				return true;
			}
			if ((Object)(object)_materialsDropdown != (Object)null && _materialsDropdown.activeSelf && RectTransformUtility.RectangleContainsScreenPoint((RectTransform)_materialsDropdown.transform, val, (Camera)null))
			{
				return true;
			}
			return false;
		}

		internal static float CellSpacing(Hud hud)
		{
			return (((Object)(object)hud != (Object)null && hud.m_pieceIconSpacing > 0f) ? hud.m_pieceIconSpacing : 64f) * Mathf.Clamp(AAABuildMenuPlugin.IconScale.Value, 0.5f, 2f);
		}

		internal static int ComputeColumns(Hud hud)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hud == (Object)null)
			{
				return 15;
			}
			float num = CellSpacing(hud);
			float num2;
			if (!((Object)(object)_scrollRect != (Object)null) || !((Object)(object)_scrollRect.viewport != (Object)null))
			{
				num2 = 15f * num;
			}
			else
			{
				Rect rect = _scrollRect.viewport.rect;
				num2 = ((Rect)(ref rect)).width;
			}
			return Mathf.Clamp(Mathf.FloorToInt((num2 - 10f) / num + 0.01f), 1, 64);
		}

		internal static int RowCount(int count)
		{
			return Mathf.Max(1, Mathf.CeilToInt((float)count / (float)Columns));
		}

		internal static string PrefabName(Piece piece)
		{
			if ((Object)(object)piece == (Object)null)
			{
				return string.Empty;
			}
			if (_prefabNameCache.TryGetValue(piece, out string value))
			{
				return value;
			}
			value = Utils.GetPrefabName(((Component)piece).gameObject);
			_prefabNameCache[piece] = value;
			return value;
		}

		public static void InitializeUI(Hud hud)
		{
			if ((Object)(object)hud == (Object)null)
			{
				return;
			}
			if (_isInitialized && _hud != hud)
			{
				ResetForNewScene();
			}
			if (_isInitialized)
			{
				return;
			}
			try
			{
				AAABuildMenuPlugin.AAABuildMenuLogger.LogInfo((object)"Initializing Enhanced Build Menu...");
				_hud = hud;
				CacheVanillaButtonSprite(hud);
				CloneVanillaButtonStyle();
				ApplySavedWindowTransform(hud);
				SetupScrollView(hud);
				BuildHeaderUI(hud);
				HookPinIndicatorConfig();
				HookLiveConfig();
				_isInitialized = true;
				AAABuildMenuPlugin.AAABuildMenuLogger.LogInfo((object)"Enhanced Build Menu initialized successfully!");
			}
			catch (Exception ex)
			{
				AAABuildMenuPlugin.AAABuildMenuLogger.LogError((object)("Failed to initialize Enhanced Build Menu: " + ex.Message));
				AAABuildMenuPlugin.AAABuildMenuLogger.LogError((object)ex.StackTrace);
				_isInitialized = false;
			}
		}

		private static void ResetForNewScene()
		{
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			_isInitialized = false;
			_hud = null;
			_scrollRect = null;
			_searchBarObject = null;
			_searchInputField = null;
			_clearSearchButton = null;
			_filterButtonRow = null;
			_matchCountText = null;
			_sortButton = null;
			_sortButtonText = null;
			_materialsButton = null;
			_materialsDropdown = null;
			_materialsSearchField = null;
			_materialsListContent = null;
			_resizeHandle = null;
			_moveHandle = null;
			_allButton = (_recentButton = null);
			_canCraftButton = (_missingMaterialsButton = (_favoritesButton = null));
			_favoriteStars.Clear();
			_favoriteBorders.Clear();
			_pinIndicators.Clear();
			_prefabNameCache.Clear();
			_categoryMasters.Clear();
			_uiFont = null;
			_tooltipPrefab = null;
			_buttonSprite = null;
			_favoriteBorderSprite = null;
			_vanillaButtonSprite = null;
			_vanillaButtonResolved = false;
			_hasVanillaButton = false;
			_vanillaButtonUsesSpriteSwap = false;
			_spriteCache.Clear();
			_allSprites = null;
			_clickSfxPrefab = null;
			_sfxResolved = false;
			_origCaptured = false;
			_maskAdjusted = false;
			_origMaskCaptured = false;
			_origWinCaptured = false;
			_currentFilter.Reset();
			_selectedMaterials.Clear();
			_searchDebounceCoroutine = null;
			SelectedPiece = null;
			_lastScrollCategory = (PieceCategory)(-999);
			Columns = 15;
			NeedsRefresh = false;
		}

		private static void BuildHeaderUI(Hud hud)
		{
			ReserveHeaderSpace(hud);
			if (AAABuildMenuPlugin.EnableResize.Value.IsOn())
			{
				CreateResizeHandle(hud);
				CreateMoveHandle(hud);
			}
			if (AAABuildMenuPlugin.EnableSearch.Value.IsOn())
			{
				CreateSearchBar(hud);
			}
			if (AAABuildMenuPlugin.EnableFilters.Value.IsOn())
			{
				CreateFilterButtons(hud);
			}
			if (AAABuildMenuPlugin.ShowMatchCount.Value.IsOn())
			{
				CreateMatchCountLabel(hud);
			}
			RectTransform resizeHandle = _resizeHandle;
			if (resizeHandle != null)
			{
				((Transform)resizeHandle).SetAsLastSibling();
			}
			RectTransform moveHandle = _moveHandle;
			if (moveHandle != null)
			{
				((Transform)moveHandle).SetAsLastSibling();
			}
		}

		private static void RebuildEnhancedUI()
		{
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			if (!_isInitialized || (Object)(object)_hud == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)_searchBarObject != (Object)null)
				{
					Object.Destroy((Object)(object)_searchBarObject);
				}
				if ((Object)(object)_filterButtonRow != (Object)null)
				{
					Object.Destroy((Object)(object)_filterButtonRow);
				}
				if ((Object)(object)_matchCountText != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)_matchCountText).gameObject);
				}
				if ((Object)(object)_materialsDropdown != (Object)null)
				{
					Object.Destroy((Object)(object)_materialsDropdown);
				}
				if ((Object)(object)_resizeHandle != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)_resizeHandle).gameObject);
				}
				if ((Object)(object)_moveHandle != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)_moveHandle).gameObject);
				}
				_searchBarObject = null;
				_filterButtonRow = null;
				_matchCountText = null;
				_materialsButton = null;
				_materialsDropdown = null;
				_materialsSearchField = null;
				_resizeHandle = null;
				_moveHandle = null;
				_sortButton = null;
				_sortButtonText = null;
				_allButton = (_recentButton = null);
				_canCraftButton = (_missingMaterialsButton = (_favoritesButton = null));
				if (_origMaskCaptured && (Object)(object)_hud.m_pieceListMask != (Object)null)
				{
					_hud.m_pieceListMask.offsetMax = _origMaskOffsetMax;
				}
				_maskAdjusted = false;
				BuildHeaderUI(_hud);
				NeedsRefresh = true;
			}
			catch (Exception ex)
			{
				AAABuildMenuPlugin.AAABuildMenuLogger.LogError((object)("Error rebuilding enhanced UI: " + ex.Message));
			}
		}

		private static void HookLiveConfig()
		{
			if (!_liveConfigHooked)
			{
				_liveConfigHooked = true;
				AAABuildMenuPlugin.EnableSearch.SettingChanged += Rebuild;
				AAABuildMenuPlugin.EnableFilters.SettingChanged += Rebuild;
				AAABuildMenuPlugin.ShowMatchCount.SettingChanged += Rebuild;
				AAABuildMenuPlugin.EnableResize.SettingChanged += Rebuild;
				AAABuildMenuPlugin.EnableRecentFilter.SettingChanged += Rebuild;
				AAABuildMenuPlugin.SearchAllCategories.SettingChanged += Rebuild;
				AAABuildMenuPlugin.DefaultSortMode.SettingChanged += delegate
				{
					UpdateSortButtonLabel();
					NeedsRefresh = true;
				};
			}
			static void Rebuild(object _, EventArgs __)
			{
				RebuildEnhancedUI();
			}
		}

		private static void SetupScrollView(Hud hud)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hud.m_pieceListRoot == (Object)null || (Object)(object)hud.m_pieceListMask == (Object)null)
			{
				AAABuildMenuPlugin.AAABuildMenuLogger.LogWarning((object)"Piece list root/mask is null, cannot setup scroll view");
				return;
			}
			Transform transform = ((Component)hud.m_pieceListMask).transform;
			_scrollRect = ((Component)transform).GetComponent<ScrollRect>();
			if ((Object)(object)_scrollRect == (Object)null)
			{
				_scrollRect = ((Component)transform).gameObject.AddComponent<ScrollRect>();
			}
			RectTransform pieceListRoot = hud.m_pieceListRoot;
			if (!_origCaptured)
			{
				_origContentSize = pieceListRoot.sizeDelta;
				_origContentAnchoredPos = pieceListRoot.anchoredPosition;
				_origCaptured = true;
			}
			_scrollRect.content = pieceListRoot;
			_scrollRect.viewport = hud.m_pieceListMask;
			_scrollRect.horizontal = false;
			_scrollRect.vertical = true;
			_scrollRect.movementType = (MovementType)2;
			_scrollRect.inertia = true;
			_scrollRect.decelerationRate = 0.135f;
			_scrollRect.scrollSensitivity = ((hud.m_pieceIconSpacing > 0f) ? hud.m_pieceIconSpacing : 64f) * 4f;
			if ((Object)(object)((Component)hud.m_pieceListMask).GetComponent<Mask>() == (Object)null && (Object)(object)((Component)hud.m_pieceListMask).GetComponent<RectMask2D>() == (Object)null)
			{
				((Component)hud.m_pieceListMask).gameObject.AddComponent<RectMask2D>();
			}
			if ((Object)(object)((Component)hud.m_pieceListMask).GetComponent<Graphic>() == (Object)null)
			{
				Image obj = ((Component)hud.m_pieceListMask).gameObject.AddComponent<Image>();
				((Graphic)obj).color = new Color(0f, 0f, 0f, 0f);
				((Graphic)obj).raycastTarget = true;
			}
			CreateScrollbar(hud);
			AAABuildMenuPlugin.AAABuildMenuLogger.LogInfo((object)"ScrollRect configured successfully");
		}

		internal static TMP_FontAsset GetUiFont(Hud hud)
		{
			if ((Object)(object)_uiFont != (Object)null)
			{
				return _uiFont;
			}
			if ((Object)(object)hud != (Object)null && (Object)(object)hud.m_buildSelection != (Object)null && (Object)(object)hud.m_buildSelection.font != (Object)null)
			{
				_uiFont = hud.m_buildSelection.font;
			}
			else
			{
				_uiFont = Resources.FindObjectsOfTypeAll<TMP_FontAsset>().FirstOrDefault();
			}
			return _uiFont;
		}

		internal static TMP_Text CreateText(Transform parent, string name, TMP_FontAsset font, float fontSize, Color color, TextAlignmentOptions align, bool stretch = 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_000d: 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_0039: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.SetActive(false);
			val.transform.SetParent(parent, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			if ((Object)(object)font != (Object)null)
			{
				((TMP_Text)val2).font = font;
			}
			((TMP_Text)val2).fontSize = fontSize;
			((Graphic)val2).color = color;
			((TMP_Text)val2).alignment = align;
			if (stretch)
			{
				RectTransform rectTransform = ((TMP_Text)val2).rectTransform;
				rectTransform.anchorMin = Vector2.zero;
				rectTransform.anchorMax = Vector2.one;
				rectTransform.sizeDelta = Vector2.zero;
				rectTransform.anchoredPosition = Vector2.zero;
			}
			val.SetActive(true);
			return (TMP_Text)(object)val2;
		}

		private static GameObject GetTooltipPrefab(Hud hud)
		{
			if ((Object)(object)_tooltipPrefab != (Object)null)
			{
				return _tooltipPrefab;
			}
			UITooltip val = (((Object)(object)hud.m_pieceIconPrefab != (Object)null) ? hud.m_pieceIconPrefab.GetComponent<UITooltip>() : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val.m_tooltipPrefab == (Object)null)
			{
				val = hud.m_pieceSelectionWindow.GetComponentInChildren<UITooltip>(true);
			}
			if ((Object)(object)val != (Object)null)
			{
				_tooltipPrefab = val.m_tooltipPrefab;
			}
			return _tooltipPrefab;
		}

		internal static UITooltip AddTooltip(GameObject go, string text, Hud hud)
		{
			UITooltip val = go.AddComponent<UITooltip>();
			val.m_text = text;
			GameObject tooltipPrefab = GetTooltipPrefab(hud);
			if ((Object)(object)tooltipPrefab != (Object)null)
			{
				val.m_tooltipPrefab = tooltipPrefab;
			}
			return val;
		}

		private static void CreateScrollbar(Hud hud)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("EnhancedMenuScrollbar");
			val.transform.SetParent(((Component)hud.m_pieceListMask).transform, false);
			RectTransform obj = val.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(1f, 0f);
			obj.anchorMax = new Vector2(1f, 1f);
			obj.pivot = new Vector2(1f, 0.5f);
			obj.anchoredPosition = new Vector2(-1f, 0f);
			obj.sizeDelta = new Vector2(9f, 0f);
			Image obj2 = val.AddComponent<Image>();
			StyleButtonImage(obj2);
			((Graphic)obj2).color = new Color(0.191f, 0.078f, 0.078f, 1f);
			GameObject val2 = new GameObject("Handle");
			val2.transform.SetParent(val.transform, false);
			RectTransform val3 = val2.AddComponent<RectTransform>();
			val3.anchorMin = Vector2.zero;
			val3.anchorMax = Vector2.one;
			val3.sizeDelta = Vector2.zero;
			Image val4 = val2.AddComponent<Image>();
			StyleButtonImage(val4);
			((Graphic)val4).color = new Color(0.8529f, 0.725f, 0.5331f, 1f);
			Scrollbar val5 = val.AddComponent<Scrollbar>();
			val5.handleRect = val3;
			val5.direction = (Direction)2;
			((Selectable)val5).targetGraphic = (Graphic)(object)val4;
			DisableNavigationAndSelection((Selectable)(object)val5);
			_scrollRect.verticalScrollbar = val5;
			_scrollRect.verticalScrollbarVisibility = (ScrollbarVisibility)1;
			AAABuildMenuPlugin.AAABuildMenuLogger.LogDebug((object)"Scrollbar created successfully");
		}

		public static void RenderPieceList(Hud hud, Player player, Vector2Int selectedNr, PieceCategory category, bool updateAllBuildStatuses)
		{
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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)
			List<Piece> list = player.GetBuildPieces() ?? new List<Piece>();
			int count = list.Count;
			Columns = ComputeColumns(hud);
			int num = ((Vector2Int)(ref selectedNr)).y * Columns + ((Vector2Int)(ref selectedNr)).x;
			if (num >= 0 && num < count)
			{
				SelectedPiece = list[num];
			}
			EnsureIconCount(hud, Mathf.Max(count, 1));
			float num2 = CellSpacing(hud);
			for (int i = 0; i < hud.m_pieceIcons.Count; i++)
			{
				PieceIconData val = hud.m_pieceIcons[i];
				if ((Object)(object)val?.m_go == (Object)null)
				{
					continue;
				}
				int num3 = i % Columns;
				int num4 = i / Columns;
				Piece val2 = ((i < count) ? list[i] : null);
				if ((Object)(object)val2 != (Object)null)
				{
					if (!val.m_go.activeSelf)
					{
						val.m_go.SetActive(true);
					}
					RectTransform val3 = (RectTransform)val.m_go.transform;
					val3.anchorMin = new Vector2(0f, 1f);
					val3.anchorMax = new Vector2(0f, 1f);
					((Transform)val3).localScale = Vector3.one;
					val3.sizeDelta = new Vector2(num2, num2);
					val3.anchoredPosition = new Vector2((float)num3 * num2, (float)(-num4) * num2);
					val.m_marker.SetActive(new Vector2Int(num3, num4) == selectedNr);
					val.m_icon.sprite = val2.m_icon;
					((Behaviour)val.m_icon).enabled = true;
					val.m_tooltip.m_text = val2.m_name;
					val.m_upgrade.SetActive(val2.m_isUpgrade);
				}
				else
				{
					val.m_marker.SetActive(false);
					((Behaviour)val.m_icon).enabled = false;
					val.m_tooltip.m_text = "";
					val.m_upgrade.SetActive(false);
					if (val.m_go.activeSelf)
					{
						val.m_go.SetActive(false);
					}
				}
			}
			UpdateBuildStatus(hud, list, player);
			if (updateAllBuildStatuses || hud.m_lastPieceCategory != category)
			{
				UpdateBuildStatusAll(hud, list, player);
				hud.m_lastPieceCategory = category;
			}
			bool num5 = category != _lastScrollCategory;
			_lastScrollCategory = category;
			UpdateScrollViewContentSize(count, num2);
			UpdateMatchCount(count);
			if (num5)
			{
				ScrollToTop();
				if (GlobalActive())
				{
					NeedsRefresh = true;
				}
			}
			if (AAABuildMenuPlugin.EnableEnhancedMenu.Value.IsOn())
			{
				UpdateFavoriteStars(hud, list);
				UpdatePinIndicators(hud, list);
			}
		}

		private static void UpdateBuildStatus(Hud hud, List<Piece> pieces, Player player)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			if (hud.m_pieceIcons.Count != 0)
			{
				if (hud.m_pieceIconUpdateIndex >= hud.m_pieceIcons.Count)
				{
					hud.m_pieceIconUpdateIndex = 0;
				}
				int pieceIconUpdateIndex = hud.m_pieceIconUpdateIndex;
				PieceIconData val = hud.m_pieceIcons[pieceIconUpdateIndex];
				if ((Object)(object)val?.m_icon != (Object)null && pieceIconUpdateIndex < pieces.Count)
				{
					((Graphic)val.m_icon).color = (CanBuild(player, pieces[pieceIconUpdateIndex]) ? Color.white : Hud.s_colorRedBlueZeroAlpha);
				}
				hud.m_pieceIconUpdateIndex++;
			}
		}

		private static void UpdateBuildStatusAll(Hud hud, List<Piece> pieces, Player player)
		{
			//IL_004a: 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)
			for (int i = 0; i < hud.m_pieceIcons.Count; i++)
			{
				PieceIconData val = hud.m_pieceIcons[i];
				if (!((Object)(object)val?.m_icon == (Object)null))
				{
					((Graphic)val.m_icon).color = ((i >= pieces.Count || CanBuild(player, pieces[i])) ? Color.white : Hud.s_colorRedBlueZeroAlpha);
				}
			}
			hud.m_pieceIconUpdateIndex = 0;
		}

		internal static bool CanBuild(Player player, Piece? piece)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)piece == (Object)null)
			{
				return false;
			}
			try
			{
				return player.HaveRequirements(piece, (RequirementMode)0);
			}
			catch (Exception ex)
			{
				NoteBadPiece(piece, ex, "HaveRequirements");
				return false;
			}
		}

		internal static void NoteBadPiece(Piece? piece, Exception ex, string where)
		{
			string text = (((Object)(object)piece != (Object)null) ? PrefabName(piece) : "<null>");
			if (_badPieces.Add(text + where))
			{
				AAABuildMenuPlugin.AAABuildMenuLogger.LogWarning((object)("Piece '" + text + "' threw in " + where + " (" + ex.GetType().Name + ": " + ex.Message + ") — ignoring it. Whichever mod adds it has a broken build requirement."));
			}
		}

		private static void EnsureIconCount(Hud hud, int required)
		{
			while (hud.m_pieceIcons.Count < required)
			{
				hud.m_pieceIcons.Add(CreatePieceIcon(hud));
			}
		}

		private static PieceIconData CreatePieceIcon(Hud hud)
		{
			//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_001e: 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_0045: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(hud.m_pieceIconPrefab, (Transform)(object)hud.m_pieceListRoot);
			PieceIconData val2 = new PieceIconData
			{
				m_go = val,
				m_tooltip = val.GetComponent<UITooltip>(),
				m_icon = ((Component)val.transform.Find("icon")).GetComponent<Image>(),
				m_marker = ((Component)val.transform.Find("selected")).gameObject,
				m_upgrade = ((Component)val.transform.Find("upgrade")).gameObject
			};
			((Graphic)val2.m_icon).color = Hud.s_colorRedBlueZeroAlpha;
			UIInputHandler component = val.GetComponent<UIInputHandler>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_onLeftDown = (Action<UIInputHandler>)Delegate.Combine(component.m_onLeftDown, new Action<UIInputHandler>(hud.OnLeftClickPiece));
				component.m_onRightDown = (Action<UIInputHandler>)Delegate.Combine(component.m_onRightDown, new Action<UIInputHandler>(hud.OnRightClickPiece));
				component.m_onPointerEnter = (Action<UIInputHandler>)Delegate.Combine(component.m_onPointerEnter, new Action<UIInputHandler>(hud.OnHoverPiece));
				component.m_onPointerExit = (Action<UIInputHandler>)Delegate.Combine(component.m_onPointerExit, new Action<UIInputHandler>(hud.OnHoverPieceExit));
			}
			return val2;
		}

		public static Vector2Int GetSelectedGridAll(Hud hud, UIInputHandler ih)
		{
			//IL_0019: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			if (hud?.m_pieceIcons == null || (Object)(object)ih == (Object)null)
			{
				return new Vector2Int(-1, -1);
			}
			for (int i = 0; i < hud.m_pieceIcons.Count; i++)
			{
				if ((Object)(object)hud.m_pieceIcons[i]?.m_go == (Object)(object)((Component)ih).gameObject)
				{
					return new Vector2Int(i % Columns, i / Columns);
				}
			}
			return new Vector2Int(-1, -1);
		}

		private static void UpdateScrollViewContentSize(int pieceCount, float spacing)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_scrollRect == (Object)null) && !((Object)(object)_scrollRect.content == (Object)null))
			{
				float num = (float)Mathf.Max(1, Mathf.CeilToInt((float)pieceCount / (float)Columns)) * spacing + spacing * 0.25f;
				_scrollRect.content.sizeDelta = new Vector2((float)Columns * spacing, num);
			}
		}

		private static void ScrollToTop()
		{
			PinContentTop();
		}

		private static void PinContentTop()
		{
			//IL_003a: 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)
			if (!((Object)(object)_scrollRect == (Object)null) && !((Object)(object)_scrollRect.content == (Object)null))
			{
				_scrollRect.verticalNormalizedPosition = 1f;
				RectTransform content = _scrollRect.content;
				content.anchoredPosition = new Vector2(content.anchoredPosition.x, 0f);
			}
		}

		private static bool HasActiveFilter()
		{
			if (string.IsNullOrWhiteSpace(_currentFilter.SearchTerm) && _selectedMaterials.Count <= 0 && !_currentFilter.ShowOnlyCraftable && !_currentFilter.ShowMissingMaterials && !_currentFilter.ShowFavoritesOnly && !_currentFilter.ShowRecentOnly)
			{
				return _currentFilter.ShowAll;
			}
			return true;
		}

		private static bool NeedsCustomView()
		{
			if (!HasActiveFilter())
			{
				return AAABuildMenuPlugin.DefaultSortMode.Value != AAABuildMenuPlugin.PieceSortMode.Vanilla;
			}
			return true;
		}

		private static bool GlobalActive()
		{
			if (AAABuildMenuPlugin.SearchAllCategories.Value.IsOn())
			{
				return HasActiveFilter();
			}
			return false;
		}

		public static void CaptureMasterAndApply(Player player, PieceTable pieceTable)
		{
			if (_isInitialized && !((Object)(object)player == (Object)null) && !((Object)(object)pieceTable == (Object)null) && !((Object)(object)player != (Object)(object)Player.m_localPlayer))
			{
				_categoryMasters.Clear();
				for (int i = 0; i < pieceTable.m_availablePiecesByCategory.Count; i++)
				{
					_categoryMasters[(PieceCategory)i] = new List<Piece>(pieceTable.m_availablePiecesByCategory[i]);
				}
				if (NeedsCustomView())
				{
					ApplyFilter(player, pieceTable, scrollToTop: false);
				}
			}
		}

		private static List<Piece> GetGlobalAggregate()
		{
			HashSet<Piece> hashSet = new HashSet<Piece>();
			List<Piece> list = new List<Piece>();
			foreach (List<Piece> value in _categoryMasters.Values)
			{
				foreach (Piece item in value)
				{
					if ((Object)(object)item != (Object)null && hashSet.Add(item))
					{
						list.Add(item);
					}
				}
			}
			return list;
		}

		public static void ApplyFilter(Player player, PieceTable pieceTable, bool scrollToTop)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected I4, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			if (!_isInitialized || (Object)(object)player == (Object)null || (Object)(object)pieceTable == (Object)null)
			{
				return;
			}
			PieceCategory selectedCategory = pieceTable.GetSelectedCategory();
			int num = (int)selectedCategory;
			if (num >= 0 && num < pieceTable.m_availablePiecesByCategory.Count)
			{
				if (!_categoryMasters.TryGetValue(selectedCategory, out List<Piece> value))
				{
					value = new List<Piece>(pieceTable.m_availablePiecesByCategory[num]);
					_categoryMasters[selectedCategory] = value;
				}
				Piece val = SelectedPiece ?? pieceTable.GetSelectedPiece();
				List<Piece> list = ComputeView((List<Piece>)(GlobalActive() ? ((IList)GetGlobalAggregate()) : ((IList)value)), player);
				RestoreUnselectedCategories(pieceTable, num);
				List<Piece> list2 = pieceTable.m_availablePiecesByCategory[num];
				list2.Clear();
				list2.AddRange(list);
				int num2 = (((Object)(object)val != (Object)null) ? list.IndexOf(val) : (-1));
				if (num2 < 0)
				{
					num2 = 0;
				}
				pieceTable.SetSelected(new Vector2Int(num2 % Columns, num2 / Columns));
				Piece val2 = (SelectedPiece = ((num2 < list.Count) ? list[num2] : null));
				if ((Object)(object)val2 != (Object)null && val != val2 && ((Character)player).InPlaceMode())
				{
					player.SetupPlacementGhost();
				}
				NeedsRefresh = false;
				if (scrollToTop)
				{
					ScrollToTop();
				}
			}
		}

		internal static void EnsureGhostMatchesSelection(Player player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.m_buildPieces == (Object)null || !((Character)player).InPlaceMode())
			{
				return;
			}
			Piece selectedPiece = player.m_buildPieces.GetSelectedPiece();
			if (!((Object)(object)selectedPiece == (Object)null))
			{
				GameObject placementGhost = player.m_placementGhost;
				if (!((Object)(object)placementGhost != (Object)null) || !(Utils.GetPrefabName(placementGhost) == PrefabName(selectedPiece)))
				{
					player.SetupPlacementGhost();
				}
			}
		}

		private static void RestoreUnselectedCategories(PieceTable pieceTable, int selectedIndex)
		{
			for (int i = 0; i < pieceTable.m_availablePiecesByCategory.Count; i++)
			{
				if (i != selectedIndex && _categoryMasters.TryGetValue((PieceCategory)i, out List<Piece> value))
				{
					List<Piece> list = pieceTable.m_availablePiecesByCategory[i];
					if (!SameContents(list, value))
					{
						list.Clear();
						list.AddRange(value);
					}
				}
			}
		}

		private static bool SameContents(List<Piece> a, List<Piece> b)
		{
			if (a.Count != b.Count)
			{
				return false;
			}
			for (int i = 0; i < a.Count; i++)
			{
				if (a[i] != b[i])
				{
					return false;
				}
			}
			return true;
		}

		private static List<Piece> ComputeView(List<Piece> source, Player player)
		{
			IEnumerable<Piece> enumerable = source.Where((Piece p) => (Object)(object)p != (Object)null);
			SearchQuery searchQuery = SearchQuery.Parse(_currentFilter.SearchTerm);
			if (!searchQuery.IsEmpty)
			{
				enumerable = enumerable.Where(((SearchQuery)searchQuery).Matches);
			}
			if (_selectedMaterials.Count > 0)
			{
				enumerable = enumerable.Where(PieceUsesAnySelectedMaterial);
			}
			if (_currentFilter.ShowOnlyCraftable)
			{
				enumerable = enumerable.Where((Piece p) => CanBuild(player, p));
			}
			else if (_currentFilter.ShowMissingMaterials)
			{
				enumerable = enumerable.Where((Piece p) => !CanBuild(player, p));
			}
			if (_currentFilter.ShowFavoritesOnly)
			{
				enumerable = enumerable.Where((Piece p) => BuildMenuDataManager.IsFavorite(Utils.GetPrefabName(((Component)p).gameObject)));
			}
			if (_currentFilter.ShowRecentOnly)
			{
				List<string> recent = BuildMenuDataManager.GetRecentPieces();
				return (from p in enumerable
					where recent.Contains(Utils.GetPrefabName(((Component)p).gameObject))
					orderby recent.IndexOf(Utils.GetPrefabName(((Component)p).gameObject))
					select p).ToList();
			}
			return ApplySort(enumerable).ToList();
		}

		private static bool PieceUsesAnySelectedMaterial(Piece piece)
		{
			if (piece?.m_resources == null)
			{
				return false;
			}
			Requirement[] resources = piece.m_resources;
			foreach (Requirement val in resources)
			{
				if (!((Object)(object)val?.m_resItem == (Object)null) && _selectedMaterials.Contains(Utils.GetPrefabName(((Component)val.m_resItem).gameObject).ToLowerInvariant()))
				{
					return true;
				}
			}
			return false;
		}

		internal static IEnumerable<Piece> ApplySort(IEnumerable<Piece> pieces)
		{
			return AAABuildMenuPlugin.DefaultSortMode.Value switch
			{
				AAABuildMenuPlugin.PieceSortMode.Alphabetical => pieces.OrderBy<Piece, string>((Piece p) => Localization.instance.Localize(p.m_name), StringComparer.OrdinalIgnoreCase), 
				AAABuildMenuPlugin.PieceSortMode.Cost => pieces.OrderBy(TotalResourceCost), 
				AAABuildMenuPlugin.PieceSortMode.UsageFrequency => pieces.OrderByDescending((Piece p) => BuildMenuDataManager.GetUsageCount(Utils.GetPrefabName(((Component)p).gameObject))), 
				_ => pieces, 
			};
		}

		private static int TotalResourceCost(Piece piece)
		{
			if (piece.m_resources == null)
			{
				return 0;
			}
			int num = 0;
			Requirement[] resources = piece.m_resources;
			for (int i = 0; i < resources.Length; i++)
			{
				num += resources[i]?.m_amount ?? 0;
			}
			return num;
		}

		private static void CreateSearchBar(Hud hud)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_007c: 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_0091: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			TMP_FontAsset uiFont = GetUiFont(hud);
			_searchBarObject = new GameObject("EnhancedMenuSearchBar");
			_searchBarObject.SetActive(false);
			_searchBarObject.transform.SetParent(hud.m_pieceSelectionWindow.transform, false);
			RectTransform rect = _searchBarObject.AddComponent<RectTransform>();
			AnchorAboveViewport(hud, rect, SearchStripOffset(), 30f);
			Image obj = _searchBarObject.AddComponent<Image>();
			StyleButtonImage(obj);
			((Graphic)obj).color = new Color(0f, 0f, 0f, 0.65f);
			GameObject val = new GameObject("InputField");
			val.transform.SetParent(_searchBarObject.transform, false);
			RectTransform obj2 = val.AddComponent<RectTransform>();
			obj2.anchorMin = Vector2.zero;
			obj2.anchorMax = Vector2.one;
			obj2.offsetMin = new Vector2(6f, 3f);
			obj2.offsetMax = new Vector2(-36f, -3f);
			_searchInputField = val.AddComponent<TMP_InputField>();
			GameObject val2 = new GameObject("TextArea");
			val2.transform.SetParent(val.transform, false);
			RectTransform val3 = val2.AddComponent<RectTransform>();
			val3.anchorMin = Vector2.zero;
			val3.anchorMax = Vector2.one;
			val3.offsetMin = new Vector2(8f, 0f);
			val3.offsetMax = new Vector2(-8f, 0f);
			val2.AddComponent<RectMask2D>();
			TMP_Text val4 = CreateText(val2.transform, "Placeholder", uiFont, 14f, new Color(0.6f, 0.6f, 0.6f, 0.6f), (TextAlignmentOptions)4097, stretch: true);
			val4.text = Localization.instance.Localize("$aaabuildmenu_search_placeholder");
			TMP_Text textComponent = CreateText(val2.transform, "Text", uiFont, 14f, Color.white, (TextAlignmentOptions)4097, stretch: true);
			_searchInputField.textViewport = val3;
			_searchInputField.textComponent = textComponent;
			_searchInputField.placeholder = (Graphic)(object)val4;
			_searchInputField.fontAsset = uiFont;
			_searchInputField.pointSize = 14f;
			_searchInputField.lineType = (LineType)0;
			_searchInputField.characterLimit = 100;
			((UnityEvent<string>)(object)_searchInputField.onValueChanged).AddListener((UnityAction<string>)OnSearchTextChanged);
			DisableNavigationAndSelection((Selectable)(object)_searchInputField);
			CreateClearButton(hud, uiFont);
			_searchBarObject.SetActive(true);
			AAABuildMenuPlugin.AAABuildMenuLogger.LogInfo((object)"Search bar created successfully");
		}

		private static void CreateClearButton(Hud hud, TMP_FontAsset font)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			_clearSearchButton = new GameObject("ClearButton");
			_clearSearchButton.SetActive(false);
			_clearSearchButton.transform.SetParent(_searchBarObject.transform, false);
			RectTransform obj = _clearSearchButton.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(1f, 0.5f);
			obj.anchorMax = new Vector2(1f, 0.5f);
			obj.pivot = new Vector2(1f, 0.5f);
			obj.anchoredPosition = new Vector2(-4f, 0f);
			obj.sizeDelta = new Vector2(26f, 26f);
			Image img = _clearSearchButton.AddComponent<Image>();
			Button obj2 = _clearSearchButton.AddComponent<Button>();
			StyleVanillaButton(obj2, img);
			ButtonClickedEvent onClick = obj2.onClick;
			object obj3 = <>O.<3>__ClearSearch;
			if (obj3 == null)
			{
				UnityAction val = ClearSearch;
				<>O.<3>__ClearSearch = val;
				obj3 = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj3);
			AttachClickSfx(_clearSearchButton);
			CreateText(_clearSearchButton.transform, "Text", font, 18f, Color.white, (TextAlignmentOptions)514, stretch: true).text = "X";
			AAABuildMenuPlugin.AAABuildMenuLogger.LogDebug((object)"Clear button created");
		}

		private static void OnSearchTextChanged(string text)
		{
			if ((Object)(object)_clearSearchButton != (Object)null)
			{
				_clearSearchButton.SetActive(!string.IsNullOrEmpty(text));
			}
			if (!((Object)(object)Hud.instance == (Object)null))
			{
				if (_searchDebounceCoroutine != null)
				{
					((MonoBehaviour)Hud.instance).StopCoroutine(_searchDebounceCoroutine);
				}
				_searchDebounceCoroutine = ((MonoBehaviour)Hud.instance).StartCoroutine(DebounceSearch(text));
			}
		}

		private static IEnumerator DebounceSearch(string text)
		{
			yield return (object)new WaitForSeconds(0.15f);
			_currentFilter.SearchTerm = text;
			NeedsRefresh = true;
		}

		internal static void OnCategoryPicked()
		{
			if (Active && !AAABuildMenuPlugin.ClearSearchOnCategoryChange.Value.IsOff() && (((Object)(object)_searchInputField != (Object)null && !string.IsNullOrEmpty(_searchInputField.text)) || !string.IsNullOrEmpty(_currentFilter.SearchTerm)))
			{
				ClearSearch();
			}
		}

		internal static int UnfilteredCount(PieceCategory category, int live)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (!Active || !_categoryMasters.TryGetValue(category, out List<Piece> value))
			{
				return live;
			}
			return value.Count;
		}

		private static void ClearSearch()
		{
			if ((Object)(object)_searchInputField != (Object)null)
			{
				_searchInputField.text = "";
			}
			_currentFilter.SearchTerm = "";
			NeedsRefresh = true;
		}

		private static void CreateFilterButtons(Hud hud)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			_filterButtonRow = new GameObject("EnhancedMenuFilterButtons");
			_filterButtonRow.SetActive(false);
			_filterButtonRow.transform.SetParent(hud.m_pieceSelectionWindow.transform, false);
			RectTransform rect = _filterButtonRow.AddComponent<RectTransform>();
			AnchorAboveViewport(hud, rect, FilterStripOffset(), 26f);
			HorizontalLayoutGroup obj = _filterButtonRow.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 6f;
			((LayoutGroup)obj).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = true;
			bool flag = AAABuildMenuPlugin.SearchAllCategories.Value.IsOn();
			if (flag)
			{
				_allButton = CreateFilterButton(hud, Localization.instance.Localize("$aaabuildmenu_filter_all"), Localization.instance.Localize("$aaabuildmenu_filter_all_tip"), FilterType.All);
			}
			_canCraftButton = CreateFilterButton(hud, Localization.instance.Localize("$aaabuildmenu_filter_cancraft"), Localization.instance.Localize("$aaabuildmenu_filter_cancraft_tip") + (flag ? Localization.instance.Localize("$aaabuildmenu_filter_allcategories_suffix") : ""), FilterType.CanCraft);
			_missingMaterialsButton = CreateFilterButton(hud, Localization.instance.Localize("$aaabuildmenu_filter_missing"), Localization.instance.Localize("$aaabuildmenu_filter_missing_tip"), FilterType.MissingMaterials);
			_favoritesButton = CreateFilterButton(hud, Localization.instance.Localize("$aaabuildmenu_filter_favorites"), Localization.instance.Localize("$aaabuildmenu_filter_favorites_tip"), FilterType.Favorites);
			if (AAABuildMenuPlugin.EnableRecentFilter.Value.IsOn())
			{
				_recentButton = CreateFilterButton(hud, Localization.instance.Localize("$aaabuildmenu_filter_recent"), Localization.instance.Localize("$aaabuildmenu_filter_recent_tip"), FilterType.Recent);
			}
			CreateSortButton(hud);
			CreateMaterialsButton(hud);
			CreateResetButton(hud);
			_filterButtonRow.SetActive(true);
			AAABuildMenuPlugin.AAABuildMenuLogger.LogInfo((object)"Filter buttons created");
		}

		private static void CreateResetButton(Hud hud)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0075: 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_00af: Expected O, but got Unknown
			//IL_00b5: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			GameObject val = new GameObject("ResetButton");
			val.transform.SetParent(_filterButtonRow.transform, false);
			LayoutElement obj = val.AddComponent<LayoutElement>();
			obj.minWidth = 56f;
			obj.flexibleWidth = 1f;
			Image img = val.AddComponent<Image>();
			Button val2 = val.AddComponent<Button>();
			StyleVanillaButton(val2, img);
			CreateText(val.transform, "Text", GetUiFont(hud), 12f, new Color(1f, 0.8f, 0.8f), (TextAlignmentOptions)514, stretch: true).text = Localization.instance.Localize("$aaabuildmenu_reset");
			AddTooltip(val, Localization.instance.Localize("$aaabuildmenu_reset_tip"), hud);
			AttachClickSfx(val);
			ButtonClickedEvent onClick = val2.onClick;
			object obj2 = <>O.<4>__ResetAllFilters;
			if (obj2 == null)
			{
				UnityAction val3 = ResetAllFilters;
				<>O.<4>__ResetAllFilters = val3;
				obj2 = (object)val3;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj2);
		}

		private static void CreateSortButton(Hud hud)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			_sortButton = new GameObject("SortButton");
			_sortButton.transform.SetParent(_filterButtonRow.transform, false);
			LayoutElement obj = _sortButton.AddComponent<LayoutElement>();
			obj.minWidth = 70f;
			obj.flexibleWidth = 1f;
			Image img = _sortButton.AddComponent<Image>();
			Button obj2 = _sortButton.AddComponent<Button>();
			StyleVanillaButton(obj2, img);
			_sortButtonText = CreateText(_sortButton.transform, "Text", GetUiFont(hud), 12f, Color.white, (TextAlignmentOptions)514, stretch: true);
			UpdateSortButtonLabel();
			AddTooltip(_sortButton, Localization.instance.Localize("$aaabuildmenu_sort_tip"), hud);
			AttachClickSfx(_sortButton);
			ButtonClickedEvent onClick = obj2.onClick;
			object obj3 = <>O.<5>__CycleSortMode;
			if (obj3 == null)
			{
				UnityAction val = CycleSortMode;
				<>O.<5>__CycleSortMode = val;
				obj3 = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj3);
		}

		private static void CycleSortMode()
		{
			AAABuildMenuPlugin.PieceSortMode[] array = (AAABuildMenuPlugin.PieceSortMode[])Enum.GetValues(typeof(AAABuildMenuPlugin.PieceSortMode));
			int num = (Array.IndexOf(array, AAABuildMenuPlugin.DefaultSortMode.Value) + 1) % array.Length;
			AAABuildMenuPlugin.DefaultSortMode.Value = array[num];
			UpdateSortButtonLabel();
			NeedsRefresh = true;
		}

		private static void UpdateSortButtonLabel()
		{
			if ((Object)(object)_sortButtonText != (Object)null)
			{
				_sortButtonText.text = Localization.instance.Localize("$aaabuildmenu_sort_label") + " " + Localization.instance.Localize("$aaabuildmenu_sort_" + AAABuildMenuPlugin.DefaultSortMode.Value.ToString().ToLowerInvariant());
			}
		}

		private static void CreateMaterialsButton(Hud hud)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			_materialsButton = new GameObject("MaterialsButton");
			_materialsButton.transform.SetParent(_filterButtonRow.transform, false);
			LayoutElement obj = _materialsButton.AddComponent<LayoutElement>();
			obj.minWidth = 80f;
			obj.flexibleWidth = 1f;
			Image img = _materialsButton.AddComponent<Image>();
			Button obj2 = _materialsButton.AddComponent<Button>();
			StyleVanillaButton(obj2, img);
			CreateText(_materialsButton.transform, "Text", GetUiFont(hud), 12f, Color.white, (TextAlignmentOptions)514, stretch: true).text = Localization.instance.Localize("$aaabuildmenu_materials");
			AddTooltip(_materialsButton, Localization.instance.Localize("$aaabuildmenu_materials_tip"), hud);
			AttachClickSfx(_materialsButton);
			((UnityEvent)obj2.onClick).AddListener((UnityAction)delegate
			{
				ToggleMaterialsDropdown(hud);
			});
		}

		private static void ToggleMaterialsDropdown(Hud hud)
		{
			if ((Object)(object)_materialsDropdown != (Object)null && _materialsDropdown.activeSelf)
			{
				_materialsDropdown.SetActive(false);
				return;
			}
			BuildMaterialsDropdown(hud);
			if ((Object)(object)_materialsDropdown != (Object)null)
			{
				if ((Object)(object)_materialsSearchField != (Object)null)
				{
					_materialsSearchField.text = "";
				}
				PopulateMaterialsDropdown(hud);
				PositionMaterialsDropdown(hud);
				_materialsDropdown.SetActive(true);
				_materialsDropdown.transform.SetAsLastSibling();
			}
		}

		private static void PositionMaterialsDropdown(Hud hud)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_0091: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_materialsDropdown == (Object)null) && !((Object)(object)_materialsButton == (Object)null))
			{
				RectTransform val = (RectTransform)hud.m_pieceSelectionWindow.transform;
				RectTransform val2 = (RectTransform)_materialsButton.transform;
				RectTransform val3 = (RectTransform)_materialsDropdown.transform;
				Canvas.ForceUpdateCanvases();
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				Vector3[] array2 = (Vector3[])(object)new Vector3[4];
				val.GetWorldCorners(array);
				val2.GetWorldCorners(array2);
				Vector3 val4 = ((Transform)val).InverseTransformPoint(array[1]);
				Vector3 val5 = ((Transform)val).InverseTransformPoint(array2[0]);
				val3.anchoredPosition = new Vector2(val5.x - val4.x, val5.y - val4.y - 2f);
			}
		}

		private static void BuildMaterialsDropdown(Hud hud)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to inv