Decompiled source of CommandQueueExtendedIconFix v1.2.0

CommandQueueIconFix.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RoR2;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CommandQueueIconFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CommandQueueIconFix")]
[assembly: AssemblyTitle("CommandQueueIconFix")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CommandQueueIconFix
{
	[BepInPlugin("local.commandqueue.iconfix", "CommandQueueExtended Icon Fix", "1.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class CommandQueueIconFixPlugin : BaseUnityPlugin
	{
		public enum TooltipPosition
		{
			BottomCenter,
			Cursor
		}

		public const string PluginGuid = "local.commandqueue.iconfix";

		public const string PluginName = "CommandQueueExtended Icon Fix";

		public const string PluginVersion = "1.2.0";

		private const string OverlayName = "CommandQueueIconFix_ItemIcon";

		private const string CountName = "CommandQueueIconFix_OwnedCount";

		private const string HitAreaName = "CommandQueueIconFix_TooltipHitArea";

		private const string IconResourceName = "CommandQueueIconFix.icon.png";

		private const float RefreshInterval = 0.2f;

		private const float LookingGlassLookupInterval = 5f;

		private const BindingFlags DeclaredMethods = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static CommandQueueIconFixPlugin instance;

		private static GameObject vanillaItemIconPrefab;

		private static bool failedToFindPrefab;

		private static int exceptionCount;

		private static int tooltipExceptionCount;

		private static int hoverExceptionCount;

		private static int tooltipRecoveryLogCount;

		private static readonly Color UnownedCountColor = new Color(0.5f, 0.5f, 0.5f, 1f);

		[ThreadStatic]
		private static PickupDef currentPickup;

		private static readonly FieldInfo TooltipOwnerField = AccessTools.Field(typeof(TooltipController), "owner");

		private readonly List<QueueChoiceTag> trackedChoices = new List<QueueChoiceTag>();

		private ConfigEntry<TooltipPosition> tooltipPosition;

		private ConfigEntry<bool> ignoreEnableInspect;

		private Sprite riskOfOptionsIcon;

		private Texture2D riskOfOptionsIconTexture;

		private Harmony harmony;

		private MethodInfo lookingGlassDescription;

		private float nextRefresh;

		private float nextLookingGlassLookup;

		private bool loggedLookingGlassException;

		private bool loggedLookingGlassMismatch;

		private bool loggedCounterException;

		private void Awake()
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Expected O, but got Unknown
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Expected O, but got Unknown
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Expected O, but got Unknown
			instance = this;
			tooltipPosition = ((BaseUnityPlugin)this).Config.Bind<TooltipPosition>("Tooltips", "Position", TooltipPosition.BottomCenter, "Position of item tooltips in the Command Queue item-selection grid. BottomCenter shows them at the bottom center of the screen; Cursor uses the game's normal tooltip position. Inspect tooltips are shown when Enable Inspect is enabled, or when IgnoreEnableInspect is enabled in this plugin.");
			ignoreEnableInspect = ((BaseUnityPlugin)this).Config.Bind<bool>("Tooltips", "IgnoreEnableInspect", false, "Show Command Queue item tooltips even when the game's Enable Inspect option is disabled. Does not change the game's own setting. Changes apply immediately; owned-item counters are unaffected.");
			tooltipPosition.SettingChanged += OnTooltipPositionChanged;
			ignoreEnableInspect.SettingChanged += OnIgnoreInspectChanged;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Tooltip position=" + tooltipPosition.Value.ToString() + "; ignore Enable Inspect=" + ignoreEnableInspect.Value + "; native inspect is still read from the local Risk of Rain 2 profile."));
			RegisterRiskOfOptionsIfAvailable();
			try
			{
				if (TooltipOwnerField == null)
				{
					throw new MissingFieldException("RoR2.UI.TooltipController", "owner");
				}
				harmony = new Harmony("local.commandqueue.iconfix");
				harmony.Patch((MethodBase)AccessTools.Method(typeof(TooltipController), "LateUpdate", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(CommandQueueIconFixPlugin), "RepositionQueueTooltip", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Command Queue tooltip positioning patch installed.");
				MethodInfo methodInfo = AccessTools.Method(typeof(TooltipController), "RemoveTooltip", new Type[2]
				{
					typeof(MPEventSystem),
					typeof(TooltipProvider)
				}, (Type[])null);
				if (methodInfo != null)
				{
					harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(CommandQueueIconFixPlugin), "KeepHoveredQueueTooltip", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Command Queue hovered-tooltip lifetime guard installed.");
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Cannot patch native tooltip removal. Hover recovery remains available.");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Cannot install optional tooltip patches: " + ex));
			}
			Type type = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
				select assembly.GetType("CommandQueue.UIManager", throwOnError: false)).FirstOrDefault((Type type2) => type2 != null);
			if (type == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Cannot find CommandQueue.UIManager. Check that CommandQueueExtended 2.0.0 is installed and enabled.");
				return;
			}
			if (harmony == null)
			{
				harmony = new Harmony("local.commandqueue.iconfix");
			}
			int num = 0;
			foreach (Type item in FindNestedTypes(type))
			{
				MethodInfo[] methods = item.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo2 in methods)
				{
					if (methodInfo2.Name.Contains("<CreateQueueContainer>") && methodInfo2.GetMethodBody() != null)
					{
						try
						{
							harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(CommandQueueIconFixPlugin), "ReplaceLegacyGridSprites", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null);
							num++;
						}
						catch (Exception ex2)
						{
							((BaseUnityPlugin)this).Logger.LogError((object)("Cannot patch " + methodInfo2.Name + ": " + ex2));
						}
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("v1.2.0 installed Harmony patches on " + num + " CreateQueueContainer callback(s)."));
			if (num == 0)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"No matching callbacks found: this mod version may have changed.");
			}
		}

		private void OnTooltipPositionChanged(object sender, EventArgs args)
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Tooltip position changed to " + tooltipPosition.Value.ToString() + " (effective immediately)."));
		}

		private void OnIgnoreInspectChanged(object sender, EventArgs args)
		{
			nextRefresh = 0f;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Ignore Enable Inspect changed to " + ignoreEnableInspect.Value + " (effective immediately; game setting unchanged)."));
		}

		private static string GetLocalizedInspectOptionName()
		{
			string[] array = new string[5] { "OPTION_ENABLE_INSPECT_NAME", "OPTION_GAMEPLAY_ENABLE_INSPECT_NAME", "OPTION_ENABLEINSPECT_NAME", "OPTION_INSPECT_NAME", "OPTION_GAMEPLAY_INSPECT_NAME" };
			try
			{
				string[] array2 = array;
				foreach (string text in array2)
				{
					string text2 = Language.GetString(text);
					if (!string.IsNullOrWhiteSpace(text2) && !string.Equals(text2, text, StringComparison.Ordinal))
					{
						return text2;
					}
				}
			}
			catch
			{
			}
			return "Enable Inspect";
		}

		private void RegisterRiskOfOptionsIfAvailable()
		{
			Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly assembly2) => assembly2.GetType("RiskOfOptions.ModSettingsManager", throwOnError: false) != null);
			if (assembly == null)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"RiskOfOptions not installed; tooltip position and inspect override remain configurable through BepInEx.");
				return;
			}
			try
			{
				Type type = assembly.GetType("RiskOfOptions.ModSettingsManager", throwOnError: true);
				Type type2 = assembly.GetType("RiskOfOptions.Options.BaseOption", throwOnError: true);
				Type type3 = assembly.GetType("RiskOfOptions.Options.ChoiceOption", throwOnError: true);
				Type? type4 = assembly.GetType("RiskOfOptions.OptionConfigs.ChoiceConfig", throwOnError: true);
				object obj = Activator.CreateInstance(type4);
				type4.GetField("name").SetValue(obj, "Tooltip Position");
				type4.GetField("category").SetValue(obj, "Tooltips");
				type4.GetField("description").SetValue(obj, "Position of the item description when hovering over an available Command Queue item. Follows the game's Enable Inspect option unless Ignore Enable Inspect is enabled. Changes apply immediately.");
				type4.GetField("restartRequired").SetValue(obj, false);
				object obj2 = Activator.CreateInstance(type3, tooltipPosition, obj);
				MethodInfo method = type.GetMethod("AddOption", new Type[3]
				{
					type2,
					typeof(string),
					typeof(string)
				});
				if (method == null)
				{
					throw new MissingMethodException("RiskOfOptions.ModSettingsManager", "AddOption");
				}
				method.Invoke(null, new object[3] { obj2, "local.commandqueue.iconfix", "CommandQueueExtended Icon Fix" });
				((BaseUnityPlugin)this).Logger.LogInfo((object)"RiskOfOptions registered Tooltip Position dropdown (BottomCenter / Cursor); no restart required.");
				try
				{
					Type type5 = assembly.GetType("RiskOfOptions.Options.CheckBoxOption", throwOnError: true);
					Type? type6 = assembly.GetType("RiskOfOptions.OptionConfigs.CheckBoxConfig", throwOnError: true);
					object obj3 = Activator.CreateInstance(type6);
					type6.GetField("name").SetValue(obj3, "Ignore " + GetLocalizedInspectOptionName());
					type6.GetField("category").SetValue(obj3, "Tooltips");
					type6.GetField("description").SetValue(obj3, "When enabled, Command Queue item tooltips appear even if the game's Enable Inspect setting is off. The normal game setting is not modified. Changes apply immediately.");
					type6.GetField("restartRequired").SetValue(obj3, false);
					object obj4 = Activator.CreateInstance(type5, ignoreEnableInspect, obj3);
					method.Invoke(null, new object[3] { obj4, "local.commandqueue.iconfix", "CommandQueueExtended Icon Fix" });
					((BaseUnityPlugin)this).Logger.LogInfo((object)"RiskOfOptions registered Ignore Enable Inspect checkbox; no restart required.");
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not register optional RiskOfOptions Ignore Enable Inspect checkbox. The BepInEx setting still works: " + ex));
				}
				try
				{
					RegisterRiskOfOptionsIcon(type);
				}
				catch (Exception ex2)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not register optional RiskOfOptions icon: " + ex2));
				}
				try
				{
					MethodInfo method2 = type.GetMethod("SetModDescription", new Type[3]
					{
						typeof(string),
						typeof(string),
						typeof(string)
					});
					if (method2 != null)
					{
						method2.Invoke(null, new object[3] { "Restores CommandQueueExtended item icons and adds owned-item counters and inspect tooltips.", "local.commandqueue.iconfix", "CommandQueueExtended Icon Fix" });
					}
				}
				catch (Exception ex3)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not set optional RiskOfOptions mod description: " + ex3));
				}
			}
			catch (Exception ex4)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("RiskOfOptions detected, but Tooltip Position could not be registered. The .cfg setting still works: " + ex4));
			}
		}

		private void RegisterRiskOfOptionsIcon(Type managerType)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = null;
			string text = null;
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using (Stream stream = executingAssembly.GetManifestResourceStream("CommandQueueIconFix.icon.png"))
			{
				if (stream != null)
				{
					using (MemoryStream memoryStream = new MemoryStream())
					{
						stream.CopyTo(memoryStream);
						array = memoryStream.ToArray();
					}
					text = "embedded resource";
				}
			}
			if (array == null)
			{
				string directoryName = Path.GetDirectoryName(executingAssembly.Location);
				if (!string.IsNullOrEmpty(directoryName))
				{
					string text2 = Path.Combine(directoryName, "icon.png");
					if (File.Exists(text2))
					{
						array = File.ReadAllBytes(text2);
						text = text2;
					}
				}
			}
			if (array == null)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"RiskOfOptions icon not found. Put icon.png beside CommandQueueIconFix.dll, or put it in the project directory before building to embed it.");
				return;
			}
			if (array.Length > 4194304)
			{
				throw new InvalidDataException("RiskOfOptions icon PNG is larger than 4 MiB.");
			}
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			try
			{
				if (!ImageConversion.LoadImage(val, array, false))
				{
					throw new InvalidDataException("RiskOfOptions icon.png is not a valid PNG.");
				}
				Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
				if ((Object)(object)val2 == (Object)null)
				{
					throw new InvalidOperationException("Could not create icon Sprite.");
				}
				MethodInfo method = managerType.GetMethod("SetModIcon", new Type[3]
				{
					typeof(Sprite),
					typeof(string),
					typeof(string)
				});
				if (method == null)
				{
					Object.Destroy((Object)(object)val2);
					throw new MissingMethodException("RiskOfOptions.ModSettingsManager", "SetModIcon(Sprite, string, string)");
				}
				try
				{
					method.Invoke(null, new object[3] { val2, "local.commandqueue.iconfix", "CommandQueueExtended Icon Fix" });
				}
				catch
				{
					Object.Destroy((Object)(object)val2);
					throw;
				}
				riskOfOptionsIconTexture = val;
				riskOfOptionsIcon = val2;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("RiskOfOptions mod icon registered from " + text + "."));
			}
			catch
			{
				if ((Object)(object)riskOfOptionsIconTexture != (Object)(object)val)
				{
					Object.Destroy((Object)(object)val);
				}
				throw;
			}
		}

		private static IEnumerable<Type> FindNestedTypes(Type type)
		{
			yield return type;
			Type[] nestedTypes = type.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
			foreach (Type type2 in nestedTypes)
			{
				foreach (Type item in FindNestedTypes(type2))
				{
					yield return item;
				}
			}
		}

		public static IEnumerable<CodeInstruction> ReplaceLegacyGridSprites(IEnumerable<CodeInstruction> instructions, MethodBase __originalMethod)
		{
			MethodInfo capture = AccessTools.Method(typeof(CommandQueueIconFixPlugin), "CapturePickup", (Type[])null, (Type[])null);
			MethodInfo assign = AccessTools.Method(typeof(CommandQueueIconFixPlugin), "AssignItemIcon", (Type[])null, (Type[])null);
			int captures = 0;
			int assignments = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Ldfld && instruction.operand is FieldInfo fieldInfo && fieldInfo.DeclaringType == typeof(PickupDef) && fieldInfo.Name == "iconSprite")
				{
					instruction.opcode = OpCodes.Call;
					instruction.operand = capture;
					captures++;
				}
				else if ((instruction.opcode == OpCodes.Call || instruction.opcode == OpCodes.Callvirt) && instruction.operand is MethodInfo methodInfo && methodInfo.DeclaringType == typeof(Image) && methodInfo.Name == "set_sprite")
				{
					instruction.opcode = OpCodes.Call;
					instruction.operand = assign;
					assignments++;
				}
				yield return instruction;
			}
			if (captures <= 0 && assignments <= 0)
			{
				yield break;
			}
			CommandQueueIconFixPlugin commandQueueIconFixPlugin = instance;
			if (commandQueueIconFixPlugin != null)
			{
				((BaseUnityPlugin)commandQueueIconFixPlugin).Logger.LogInfo((object)("Replaced icon calls in " + __originalMethod.DeclaringType?.FullName + "." + __originalMethod.Name + ": " + captures + " pickup capture(s), " + assignments + " Image.sprite setter(s)."));
			}
			if (captures != 1 || assignments < 1)
			{
				CommandQueueIconFixPlugin commandQueueIconFixPlugin2 = instance;
				if (commandQueueIconFixPlugin2 != null)
				{
					((BaseUnityPlugin)commandQueueIconFixPlugin2).Logger.LogWarning((object)"Unexpected icon IL pattern. This patch is intended for CommandQueueExtended 2.0.0.");
				}
			}
		}

		public static Sprite CapturePickup(PickupDef definition)
		{
			currentPickup = definition;
			return definition?.iconSprite;
		}

		public static void AssignItemIcon(Image target, Sprite originalSprite)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			PickupDef val = currentPickup;
			currentPickup = null;
			if ((Object)(object)target == (Object)null)
			{
				return;
			}
			if (val == null || (int)val.itemIndex == -1 || (Object)(object)instance == (Object)null)
			{
				target.sprite = originalSprite;
				return;
			}
			try
			{
				if (!instance.TryInstallItemIcon(target, val.itemIndex))
				{
					target.sprite = originalSprite;
				}
			}
			catch (Exception ex)
			{
				target.sprite = originalSprite;
				if (exceptionCount++ < 5)
				{
					((BaseUnityPlugin)instance).Logger.LogError((object)("Failed ItemIcon for " + ((object)Unsafe.As<ItemIndex, ItemIndex>(ref val.itemIndex)/*cast due to .constrained prefix*/).ToString() + ": " + ex));
				}
			}
		}

		private static GameObject FindItemIconPrefab()
		{
			if ((Object)(object)vanillaItemIconPrefab != (Object)null)
			{
				return vanillaItemIconPrefab;
			}
			if (failedToFindPrefab)
			{
				return null;
			}
			try
			{
				GameObject val = LegacyResourcesAPI.Load<GameObject>("Prefabs/HUDSimple");
				HUD val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<HUD>() : null);
				ItemInventoryDisplay val3 = (((Object)(object)val2 != (Object)null) ? val2.itemInventoryDisplay : null);
				vanillaItemIconPrefab = (((Object)(object)val3 != (Object)null) ? val3.itemIconPrefab : null);
				if ((Object)(object)vanillaItemIconPrefab == (Object)null || (Object)(object)vanillaItemIconPrefab.GetComponent<ItemIcon>() == (Object)null)
				{
					CommandQueueIconFixPlugin commandQueueIconFixPlugin = instance;
					if (commandQueueIconFixPlugin != null)
					{
						((BaseUnityPlugin)commandQueueIconFixPlugin).Logger.LogError((object)"HUDSimple itemIconPrefab is missing or does not have RoR2.UI.ItemIcon.");
					}
					failedToFindPrefab = true;
					return null;
				}
				CommandQueueIconFixPlugin commandQueueIconFixPlugin2 = instance;
				if (commandQueueIconFixPlugin2 != null)
				{
					((BaseUnityPlugin)commandQueueIconFixPlugin2).Logger.LogInfo((object)("Reusing HUDSimple ItemIcon prefab: " + ((Object)vanillaItemIconPrefab).name));
				}
				return vanillaItemIconPrefab;
			}
			catch (Exception ex)
			{
				failedToFindPrefab = true;
				CommandQueueIconFixPlugin commandQueueIconFixPlugin3 = instance;
				if (commandQueueIconFixPlugin3 != null)
				{
					((BaseUnityPlugin)commandQueueIconFixPlugin3).Logger.LogError((object)("Cannot load HUDSimple ItemIcon prefab: " + ex));
				}
				return null;
			}
		}

		private unsafe bool TryInstallItemIcon(Image legacyImage, ItemIndex itemIndex)
		{
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = FindItemIconPrefab();
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Transform val2 = ((Component)legacyImage).transform.Find("CommandQueueIconFix_ItemIcon");
			bool flag = false;
			ItemIcon component;
			if ((Object)(object)val2 != (Object)null)
			{
				GameObject gameObject = ((Component)val2).gameObject;
				component = gameObject.GetComponent<ItemIcon>();
				if ((Object)(object)component == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Existing icon overlay has no ItemIcon: " + ((object)(*(ItemIndex*)(&itemIndex))/*cast due to .constrained prefix*/).ToString()));
					return false;
				}
			}
			else
			{
				GameObject gameObject = Object.Instantiate<GameObject>(val, ((Component)legacyImage).transform, false);
				((Object)gameObject).name = "CommandQueueIconFix_ItemIcon";
				component = gameObject.GetComponent<ItemIcon>();
				RectTransform component2 = gameObject.GetComponent<RectTransform>();
				if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
				{
					Object.Destroy((Object)(object)gameObject);
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Cannot create an ItemIcon and RectTransform for " + ((object)(*(ItemIndex*)(&itemIndex))/*cast due to .constrained prefix*/).ToString()));
					return false;
				}
				component2.anchorMin = Vector2.zero;
				component2.anchorMax = Vector2.one;
				component2.pivot = new Vector2(0.5f, 0.5f);
				component2.offsetMin = Vector2.zero;
				component2.offsetMax = Vector2.zero;
				((Transform)component2).localScale = Vector3.one;
				((Transform)component2).localRotation = Quaternion.identity;
				gameObject.transform.SetAsLastSibling();
				Graphic[] componentsInChildren = gameObject.GetComponentsInChildren<Graphic>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].raycastTarget = false;
				}
				CanvasGroup val3 = gameObject.GetComponent<CanvasGroup>();
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = gameObject.AddComponent<CanvasGroup>();
				}
				val3.blocksRaycasts = false;
				val3.interactable = false;
				flag = true;
			}
			component.SetItemIndex(itemIndex, 1);
			legacyImage.sprite = null;
			legacyImage.overrideSprite = null;
			((Behaviour)legacyImage).enabled = false;
			try
			{
				RegisterQueueChoice(legacyImage, component, itemIndex);
			}
			catch (Exception ex)
			{
				if (!loggedCounterException)
				{
					loggedCounterException = true;
					((BaseUnityPlugin)this).Logger.LogError((object)("Could not attach Command Queue count/tooltip: " + ex));
				}
			}
			if (flag)
			{
				((MonoBehaviour)this).StartCoroutine(RebindItemIcon(component, itemIndex));
			}
			return true;
		}

		private unsafe IEnumerator RebindItemIcon(ItemIcon icon, ItemIndex itemIndex)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			yield return null;
			if ((Object)(object)icon == (Object)null)
			{
				yield break;
			}
			try
			{
				icon.SetItemIndex(itemIndex, 1);
			}
			catch (Exception ex)
			{
				if (exceptionCount++ < 5)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("ItemIcon.SetItemIndex failed for " + ((object)(*(ItemIndex*)(&itemIndex))/*cast due to .constrained prefix*/).ToString() + ": " + ex));
				}
			}
		}

		private unsafe void RegisterQueueChoice(Image legacyImage, ItemIcon icon, ItemIndex itemIndex)
		{
			//IL_0076: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: 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_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			MPButton componentInParent = ((Component)legacyImage).GetComponentInParent<MPButton>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Cannot find the Command Queue choice button for " + ((object)(*(ItemIndex*)(&itemIndex))/*cast due to .constrained prefix*/).ToString()));
				return;
			}
			QueueChoiceTag queueChoiceTag = ((Component)componentInParent).GetComponent<QueueChoiceTag>();
			if ((Object)(object)queueChoiceTag == (Object)null)
			{
				queueChoiceTag = ((Component)componentInParent).gameObject.AddComponent<QueueChoiceTag>();
				queueChoiceTag.Hud = ((Component)componentInParent).GetComponentInParent<HUD>();
			}
			if (!trackedChoices.Contains(queueChoiceTag))
			{
				trackedChoices.Add(queueChoiceTag);
			}
			queueChoiceTag.ItemIndex = itemIndex;
			queueChoiceTag.Icon = icon;
			queueChoiceTag.Tooltip = ((Component)componentInParent).GetComponent<TooltipProvider>();
			if ((Object)(object)queueChoiceTag.Tooltip == (Object)null)
			{
				queueChoiceTag.Tooltip = ((Component)componentInParent).gameObject.AddComponent<TooltipProvider>();
			}
			queueChoiceTag.Tooltip.AllowTooltipOnNavigationSelect = false;
			queueChoiceTag.Tooltip.removeTooltipOnDeselect = false;
			EnsureTooltipHitArea(componentInParent);
			Transform val = ((Component)legacyImage).transform.Find("CommandQueueIconFix_OwnedCount");
			if ((Object)(object)val != (Object)null)
			{
				queueChoiceTag.Counter = ((Component)val).GetComponent<TextMeshProUGUI>();
			}
			if ((Object)(object)queueChoiceTag.Counter == (Object)null)
			{
				GameObject val2 = new GameObject("CommandQueueIconFix_OwnedCount", new Type[2]
				{
					typeof(RectTransform),
					typeof(TextMeshProUGUI)
				})
				{
					layer = ((Component)legacyImage).gameObject.layer
				};
				val2.transform.SetParent(((Component)legacyImage).transform, false);
				RectTransform component = val2.GetComponent<RectTransform>();
				component.anchorMin = Vector2.one;
				component.anchorMax = Vector2.one;
				component.pivot = Vector2.one;
				component.anchoredPosition = new Vector2(-2f, -1f);
				component.sizeDelta = new Vector2(33f, 16f);
				TextMeshProUGUI component2 = val2.GetComponent<TextMeshProUGUI>();
				if ((Object)(object)icon.stackText != (Object)null && (Object)(object)((TMP_Text)icon.stackText).font != (Object)null)
				{
					((TMP_Text)component2).font = ((TMP_Text)icon.stackText).font;
				}
				((TMP_Text)component2).fontSize = 13f;
				((TMP_Text)component2).enableAutoSizing = true;
				((TMP_Text)component2).fontSizeMin = 10f;
				((TMP_Text)component2).fontSizeMax = 13f;
				((TMP_Text)component2).fontStyle = (FontStyles)1;
				((TMP_Text)component2).alignment = (TextAlignmentOptions)260;
				((Graphic)component2).color = Color.white;
				((TMP_Text)component2).outlineColor = Color32.op_Implicit(Color.black);
				((TMP_Text)component2).outlineWidth = 0.18f;
				((Graphic)component2).raycastTarget = false;
				((TMP_Text)component2).text = "x0";
				queueChoiceTag.Counter = component2;
			}
			((TMP_Text)queueChoiceTag.Counter).transform.SetAsLastSibling();
			queueChoiceTag.LastCount = int.MinValue;
			RefreshChoice(queueChoiceTag);
		}

		private static void EnsureTooltipHitArea(MPButton button)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)button).transform.Find("CommandQueueIconFix_TooltipHitArea");
			Image val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Image>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				GameObject val3 = new GameObject("CommandQueueIconFix_TooltipHitArea", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				})
				{
					layer = ((Component)button).gameObject.layer
				};
				val3.transform.SetParent(((Component)button).transform, false);
				RectTransform component = val3.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = Vector2.zero;
				component.offsetMax = Vector2.zero;
				val2 = val3.GetComponent<Image>();
			}
			((Graphic)val2).color = new Color(1f, 1f, 1f, 0f);
			((Graphic)val2).raycastTarget = true;
			((Component)val2).transform.SetAsLastSibling();
		}

		private static MPEventSystem ResolveChoiceEventSystem(LocalUser user)
		{
			return (MPEventSystem)(((object)((user != null) ? user.eventSystem : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/));
		}

		internal static void HandleChoicePointerEnter(QueueChoiceTag tag, PointerEventData eventData)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)instance == (Object)null || (Object)(object)tag == (Object)null)
			{
				return;
			}
			tag.Hovered = true;
			tag.PointerPosition = ((eventData != null) ? eventData.position : Vector2.zero);
			tag.RecoveryAttempts = 0;
			tag.NextRecoveryTime = 0f;
			try
			{
				LocalUser choiceUser = GetChoiceUser(tag);
				MPEventSystem val = (tag.LastEventSystem = ResolveChoiceEventSystem(choiceUser));
				if (IsInspectEnabled(choiceUser) && !((Object)(object)tag.Tooltip == (Object)null) && ((Behaviour)tag.Tooltip).isActiveAndEnabled && !((Object)(object)val == (Object)null) && (!string.IsNullOrEmpty(tag.Tooltip.titleText) || !string.IsNullOrEmpty(tag.Tooltip.bodyText)) && (!((Object)(object)val.currentTooltipProvider == (Object)(object)tag.Tooltip) || !((Object)(object)val.currentTooltip != (Object)null)))
				{
					if ((Object)(object)val.currentTooltipProvider == (Object)(object)tag.Tooltip && (Object)(object)val.currentTooltip == (Object)null)
					{
						TooltipController.RemoveTooltip(val, tag.Tooltip);
					}
					TooltipController.SetTooltip(val, tag.Tooltip, tag.PointerPosition, (RectTransform)null);
				}
			}
			catch (Exception ex)
			{
				if (hoverExceptionCount++ < 5)
				{
					((BaseUnityPlugin)instance).Logger.LogError((object)("Command Queue tooltip enter failed for " + ((object)Unsafe.As<ItemIndex, ItemIndex>(ref tag.ItemIndex)/*cast due to .constrained prefix*/).ToString() + ": " + ex));
				}
			}
		}

		internal static void HandleChoicePointerExit(QueueChoiceTag tag, PointerEventData eventData)
		{
			if ((Object)(object)instance == (Object)null || (Object)(object)tag == (Object)null)
			{
				return;
			}
			tag.Hovered = false;
			tag.RecoveryAttempts = 0;
			try
			{
				MPEventSystem val = tag.LastEventSystem ?? ResolveChoiceEventSystem(GetChoiceUser(tag));
				if ((Object)(object)val != (Object)null && (Object)(object)tag.Tooltip != (Object)null)
				{
					TooltipController.RemoveTooltip(val, tag.Tooltip);
				}
			}
			catch (Exception ex)
			{
				if (hoverExceptionCount++ < 5)
				{
					((BaseUnityPlugin)instance).Logger.LogWarning((object)("Command Queue tooltip exit failed: " + ex));
				}
			}
			tag.LastEventSystem = null;
		}

		public static bool KeepHoveredQueueTooltip(MPEventSystem __0, TooltipProvider __1)
		{
			if ((Object)(object)instance == (Object)null || (Object)(object)__0 == (Object)null || (Object)(object)__1 == (Object)null)
			{
				return true;
			}
			QueueChoiceTag component = ((Component)__1).GetComponent<QueueChoiceTag>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.Tooltip != (Object)(object)__1 || !component.Hovered || !((Behaviour)component).isActiveAndEnabled || !((Behaviour)__1).isActiveAndEnabled || !((Component)component).gameObject.activeInHierarchy || !IsInspectEnabled(GetChoiceUser(component)))
			{
				return true;
			}
			if ((Object)(object)__0.currentTooltipProvider != (Object)(object)__1 || (Object)(object)__0.currentTooltip == (Object)null)
			{
				return true;
			}
			return false;
		}

		private void LateUpdate()
		{
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			foreach (QueueChoiceTag trackedChoice in trackedChoices)
			{
				if ((Object)(object)trackedChoice == (Object)null || !trackedChoice.Hovered || (Object)(object)trackedChoice.Tooltip == (Object)null || !((Behaviour)trackedChoice.Tooltip).isActiveAndEnabled || !((Component)trackedChoice).gameObject.activeInHierarchy || !IsInspectEnabled(GetChoiceUser(trackedChoice)))
				{
					continue;
				}
				MPEventSystem val = trackedChoice.LastEventSystem ?? ResolveChoiceEventSystem(GetChoiceUser(trackedChoice));
				if ((Object)(object)val == (Object)null || ((Object)(object)val.currentTooltipProvider == (Object)(object)trackedChoice.Tooltip && (Object)(object)val.currentTooltip != (Object)null) || ((Object)(object)val.currentTooltipProvider != (Object)(object)trackedChoice.Tooltip && (Object)(object)val.currentTooltip != (Object)null) || Time.unscaledTime < trackedChoice.NextRecoveryTime || trackedChoice.RecoveryAttempts >= 4)
				{
					continue;
				}
				trackedChoice.NextRecoveryTime = Time.unscaledTime + 0.2f;
				trackedChoice.RecoveryAttempts++;
				try
				{
					if ((Object)(object)val.currentTooltipProvider == (Object)(object)trackedChoice.Tooltip && (Object)(object)val.currentTooltip == (Object)null)
					{
						TooltipController.RemoveTooltip(val, trackedChoice.Tooltip);
					}
					TooltipController.SetTooltip(val, trackedChoice.Tooltip, trackedChoice.PointerPosition, (RectTransform)null);
					if (tooltipRecoveryLogCount++ < 3)
					{
						((BaseUnityPlugin)this).Logger.LogDebug((object)("Recovered Command Queue tooltip for item=" + ((object)Unsafe.As<ItemIndex, ItemIndex>(ref trackedChoice.ItemIndex)/*cast due to .constrained prefix*/).ToString() + ", attempt=" + trackedChoice.RecoveryAttempts + "."));
					}
				}
				catch (Exception ex)
				{
					if (tooltipExceptionCount++ < 3)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not recover hovered Command Queue tooltip: " + ex));
					}
				}
			}
		}

		private static LocalUser GetChoiceUser(QueueChoiceTag tag)
		{
			if ((Object)(object)tag.Hud != (Object)null && tag.Hud.localUserViewer != null)
			{
				return tag.Hud.localUserViewer;
			}
			return LocalUserManager.GetFirstLocalUser();
		}

		private static bool IsInspectEnabled(LocalUser user)
		{
			if (!((Object)(object)instance != (Object)null) || instance.ignoreEnableInspect == null || !instance.ignoreEnableInspect.Value)
			{
				if (user != null && user.userProfile != null)
				{
					return user.userProfile.useInspectFeature;
				}
				return false;
			}
			return true;
		}

		private void Update()
		{
			if (Time.unscaledTime < nextRefresh)
			{
				return;
			}
			nextRefresh = Time.unscaledTime + 0.2f;
			TryFindLookingGlass();
			for (int num = trackedChoices.Count - 1; num >= 0; num--)
			{
				QueueChoiceTag queueChoiceTag = trackedChoices[num];
				if ((Object)(object)queueChoiceTag == (Object)null || (Object)(object)queueChoiceTag.Tooltip == (Object)null || (Object)(object)queueChoiceTag.Counter == (Object)null)
				{
					trackedChoices.RemoveAt(num);
				}
				else
				{
					try
					{
						RefreshChoice(queueChoiceTag);
					}
					catch (Exception ex)
					{
						if (!loggedCounterException)
						{
							loggedCounterException = true;
							((BaseUnityPlugin)this).Logger.LogError((object)("Error updating Command Queue items: " + ex));
						}
					}
				}
			}
		}

		private void RefreshChoice(QueueChoiceTag tag)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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)
			//IL_0124: 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)
			LocalUser choiceUser = GetChoiceUser(tag);
			CharacterMaster val = ((choiceUser != null) ? choiceUser.cachedMaster : null);
			Inventory val2 = (((Object)(object)val != (Object)null) ? val.inventory : null);
			int num = (((Object)(object)val2 != (Object)null) ? val2.GetItemCountEffective(tag.ItemIndex) : 0);
			if (tag.LastCount != num || (Object)(object)tag.LastMaster != (Object)(object)val || tag.UsingLookingGlass != (lookingGlassDescription != null))
			{
				((TMP_Text)tag.Counter).text = "x" + num;
				((Graphic)tag.Counter).color = ((num == 0) ? UnownedCountColor : Color.white);
				tag.LastCount = num;
				tag.LastMaster = val;
				tag.UsingLookingGlass = lookingGlassDescription != null;
				ItemDef itemDef = ItemCatalog.GetItemDef(tag.ItemIndex);
				if ((Object)(object)itemDef != (Object)null)
				{
					tag.Tooltip.SetContent(new TooltipContent
					{
						titleToken = itemDef.nameToken,
						titleColor = Color32.op_Implicit(ColorCatalog.GetColor(itemDef.darkColorIndex)),
						bodyToken = itemDef.descriptionToken,
						bodyColor = Color.white,
						overrideTitleText = null,
						overrideBodyText = GetDescription(itemDef, num, val),
						disableTitleRichText = false,
						disableBodyRichText = false
					});
				}
			}
			bool flag = IsInspectEnabled(choiceUser);
			if (((Behaviour)tag.Tooltip).enabled != flag)
			{
				((Behaviour)tag.Tooltip).enabled = flag;
			}
		}

		private void TryFindLookingGlass()
		{
			if (lookingGlassDescription != null || Time.unscaledTime < nextLookingGlassLookup)
			{
				return;
			}
			nextLookingGlassLookup = Time.unscaledTime + 5f;
			Type type = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
				select assembly.GetType("LookingGlass.ItemStatsNameSpace.ItemStats", throwOnError: false)).FirstOrDefault((Type candidate) => candidate != null);
			if (!(type == null))
			{
				lookingGlassDescription = type.GetMethod("GetItemDescription", BindingFlags.Static | BindingFlags.Public, null, new Type[5]
				{
					typeof(ItemDef),
					typeof(int),
					typeof(CharacterMaster),
					typeof(bool),
					typeof(bool)
				}, null);
				if (lookingGlassDescription != null)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"LookingGlass item descriptions are available.");
				}
				else if (!loggedLookingGlassMismatch)
				{
					loggedLookingGlassMismatch = true;
					((BaseUnityPlugin)this).Logger.LogWarning((object)"LookingGlass is loaded but its description API differs; using normal game descriptions.");
				}
			}
		}

		private string GetDescription(ItemDef definition, int count, CharacterMaster master)
		{
			if (lookingGlassDescription != null && (Object)(object)master != (Object)null)
			{
				try
				{
					string text = lookingGlassDescription.Invoke(null, new object[5] { definition, count, master, true, false }) as string;
					if (!string.IsNullOrEmpty(text))
					{
						return text;
					}
				}
				catch (Exception ex)
				{
					if (!loggedLookingGlassException)
					{
						loggedLookingGlassException = true;
						((BaseUnityPlugin)this).Logger.LogWarning((object)("LookingGlass description failed, using vanilla text: " + ex));
					}
				}
			}
			string text2 = Language.GetString(definition.descriptionToken);
			if (string.IsNullOrEmpty(text2))
			{
				text2 = Language.GetString(definition.pickupToken);
			}
			return text2;
		}

		public static void RepositionQueueTooltip(TooltipController __instance)
		{
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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)
			try
			{
				if ((Object)(object)instance == (Object)null || (Object)(object)__instance == (Object)null || TooltipOwnerField == null)
				{
					return;
				}
				object? value = TooltipOwnerField.GetValue(__instance);
				MPEventSystem val = (MPEventSystem)((value is MPEventSystem) ? value : null);
				if ((Object)(object)val == (Object)null || (Object)(object)val.currentTooltip != (Object)(object)__instance)
				{
					return;
				}
				TooltipProvider currentTooltipProvider = val.currentTooltipProvider;
				if ((Object)(object)currentTooltipProvider == (Object)null || (Object)(object)((Component)currentTooltipProvider).GetComponent<QueueChoiceTag>() == (Object)null)
				{
					return;
				}
				RectTransform tooltipFlipTransform = __instance.tooltipFlipTransform;
				RectTransform tooltipCenterTransform = __instance.tooltipCenterTransform;
				if ((Object)(object)tooltipFlipTransform == (Object)null || (Object)(object)tooltipCenterTransform == (Object)null)
				{
					return;
				}
				QueueTooltipLayoutState queueTooltipLayoutState = ((Component)__instance).GetComponent<QueueTooltipLayoutState>();
				if (instance.tooltipPosition.Value == TooltipPosition.Cursor)
				{
					if ((Object)(object)queueTooltipLayoutState != (Object)null && queueTooltipLayoutState.Saved)
					{
						tooltipFlipTransform.anchorMin = queueTooltipLayoutState.OriginalMin;
						tooltipFlipTransform.anchorMax = queueTooltipLayoutState.OriginalMax;
						tooltipFlipTransform.pivot = queueTooltipLayoutState.OriginalPivot;
						tooltipFlipTransform.anchoredPosition = queueTooltipLayoutState.OriginalPosition;
						queueTooltipLayoutState.Saved = false;
					}
					return;
				}
				if ((Object)(object)queueTooltipLayoutState == (Object)null)
				{
					queueTooltipLayoutState = ((Component)__instance).gameObject.AddComponent<QueueTooltipLayoutState>();
				}
				if (!queueTooltipLayoutState.Saved)
				{
					queueTooltipLayoutState.OriginalMin = tooltipFlipTransform.anchorMin;
					queueTooltipLayoutState.OriginalMax = tooltipFlipTransform.anchorMax;
					queueTooltipLayoutState.OriginalPivot = tooltipFlipTransform.pivot;
					queueTooltipLayoutState.OriginalPosition = tooltipFlipTransform.anchoredPosition;
					queueTooltipLayoutState.Saved = true;
				}
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(0.5f, 0f);
				tooltipFlipTransform.anchorMin = val2;
				tooltipFlipTransform.anchorMax = val2;
				tooltipFlipTransform.pivot = val2;
				tooltipFlipTransform.anchoredPosition = Vector2.zero;
				((Transform)tooltipCenterTransform).position = new Vector3((float)Screen.width * 0.5f, Mathf.Max(16f, (float)Screen.height * 0.02f), 0f);
			}
			catch (Exception ex)
			{
				if (tooltipExceptionCount++ < 3)
				{
					CommandQueueIconFixPlugin commandQueueIconFixPlugin = instance;
					if (commandQueueIconFixPlugin != null)
					{
						((BaseUnityPlugin)commandQueueIconFixPlugin).Logger.LogError((object)("Command Queue tooltip positioning failed: " + ex));
					}
				}
			}
		}

		private void OnDestroy()
		{
			if (tooltipPosition != null)
			{
				tooltipPosition.SettingChanged -= OnTooltipPositionChanged;
			}
			if (ignoreEnableInspect != null)
			{
				ignoreEnableInspect.SettingChanged -= OnIgnoreInspectChanged;
			}
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			instance = null;
			vanillaItemIconPrefab = null;
			trackedChoices.Clear();
		}
	}
	public sealed class QueueChoiceTag : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
	{
		public ItemIndex ItemIndex;

		public ItemIcon Icon;

		public TooltipProvider Tooltip;

		public TextMeshProUGUI Counter;

		public HUD Hud;

		public int LastCount = int.MinValue;

		public CharacterMaster LastMaster;

		public bool UsingLookingGlass;

		public bool Hovered;

		public MPEventSystem LastEventSystem;

		public Vector2 PointerPosition;

		public int RecoveryAttempts;

		public float NextRecoveryTime;

		public void OnPointerEnter(PointerEventData eventData)
		{
			CommandQueueIconFixPlugin.HandleChoicePointerEnter(this, eventData);
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			CommandQueueIconFixPlugin.HandleChoicePointerExit(this, eventData);
		}
	}
	public sealed class QueueTooltipLayoutState : MonoBehaviour
	{
		public bool Saved;

		public Vector2 OriginalMin;

		public Vector2 OriginalMax;

		public Vector2 OriginalPivot;

		public Vector2 OriginalPosition;
	}
}