Decompiled source of ItemPickupList v0.3.10

plugins\ItemPickupList\ItemPickupList.dll

Decompiled 14 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.ContentManagement;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
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("ItemPickupList")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ItemPickupList")]
[assembly: AssemblyTitle("ItemPickupList")]
[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 ItemPickupList
{
	public enum ListPosition
	{
		TopLeft,
		TopCenter,
		TopRight,
		MiddleLeft,
		Center,
		MiddleRight,
		BottomLeft,
		BottomCenter,
		BottomRight
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("rfaael.ItemPickupList", "ItemPickupList", "0.3.10")]
	public class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__TestList;
		}

		public static ConfigEntry<bool> Enabled;

		public static ConfigEntry<ListPosition> Position;

		public static ConfigEntry<float> OffsetX;

		public static ConfigEntry<float> OffsetY;

		public static ConfigEntry<float> Scale;

		public static ConfigEntry<float> BaseDuration;

		public static ConfigEntry<float> SpeedPerQueued;

		public static ConfigEntry<float> MaxSpeed;

		public static ConfigEntry<float> SpawnInterval;

		public static ConfigEntry<int> MaxVisible;

		public static ConfigEntry<KeyboardShortcut> TestKey;

		internal static ManualLogSource Log;

		private Harmony harmony;

		private Texture2D modIconTexture;

		private Sprite modIconSprite;

		private static FieldInfo notificationDataField;

		private static FieldInfo transformationField;

		private static bool receivedNotification;

		private static readonly HashSet<Type> unknownDataTypes = new HashSet<Type>();

		private bool keyWasDown;

		private void Awake()
		{
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable the pickup list. When disabled, use the default game notifications.");
			Position = ((BaseUnityPlugin)this).Config.Bind<ListPosition>("Position", "Preset", ListPosition.MiddleLeft, "Screen anchor for the pickup list.");
			OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "X", 0f, "Horizontal offset from the selected anchor (positive = right).");
			OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "Y", 0f, "Vertical offset from the selected anchor (positive = up).");
			Scale = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "Scale", 1f, "Scale of the pickup list.");
			BaseDuration = ((BaseUnityPlugin)this).Config.Bind<float>("List", "Base duration", 4f, "Seconds each entry remains visible without queue acceleration.");
			SpeedPerQueued = ((BaseUnityPlugin)this).Config.Bind<float>("List", "Acceleration per item", 0.35f, "Speed increase for each additional queued or visible entry.");
			MaxSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("List", "Maximum speed", 6f, "Maximum notification speed multiplier.");
			SpawnInterval = ((BaseUnityPlugin)this).Config.Bind<float>("List", "Entry interval", 0.35f, "Seconds between new entries without queue acceleration.");
			MaxVisible = ((BaseUnityPlugin)this).Config.Bind<int>("List", "Maximum visible", 6, "Maximum number of entries visible at the same time.");
			TestKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Preview", "Preview shortcut", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Shortcut to preview example items in the list.");
			TestKey.SettingChanged += TestKeyChanged;
			RegisterOptions();
			RegisterModIcon();
			PickupListUI.Create();
			PatchNotifications();
		}

		private unsafe void Update()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if (!Application.isFocused)
			{
				keyWasDown = true;
				return;
			}
			KeyboardShortcut value = TestKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
			{
				keyWasDown = false;
				return;
			}
			bool key = Input.GetKey(((KeyboardShortcut)(ref value)).MainKey);
			bool num = key && !keyWasDown;
			keyWasDown = key;
			if (!num)
			{
				return;
			}
			KeyboardShortcut val;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if ((int)modifier != 0 && !Input.GetKey(modifier))
				{
					ManualLogSource log = Log;
					string? text = ((object)(*(KeyCode*)(&modifier))/*cast due to .constrained prefix*/).ToString();
					val = value;
					log.LogInfo((object)("Preview skipped: hold " + text + ". Configured shortcut: " + ((object)(*(KeyboardShortcut*)(&val))/*cast due to .constrained prefix*/).ToString()));
					return;
				}
			}
			ManualLogSource log2 = Log;
			val = value;
			log2.LogInfo((object)("Preview shortcut pressed: " + ((object)(*(KeyboardShortcut*)(&val))/*cast due to .constrained prefix*/).ToString()));
			TestList();
		}

		private unsafe void TestKeyChanged(object sender, EventArgs args)
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0034: 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)
			KeyboardShortcut value = TestKey.Value;
			KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey;
			keyWasDown = (int)mainKey != 0 && Input.GetKey(mainKey);
			ManualLogSource log = Log;
			value = TestKey.Value;
			log.LogInfo((object)("Preview shortcut updated: " + ((object)(*(KeyboardShortcut*)(&value))/*cast due to .constrained prefix*/).ToString()));
		}

		private void RegisterModIcon()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				using (Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("ItemPickupList.ModIcon.png"))
				{
					if (stream == null)
					{
						throw new FileNotFoundException("Embedded mod icon was not found.");
					}
					using MemoryStream memoryStream = new MemoryStream();
					stream.CopyTo(memoryStream);
					modIconTexture = new Texture2D(2, 2, (TextureFormat)4, false);
					if (!ImageConversion.LoadImage(modIconTexture, memoryStream.ToArray(), true))
					{
						throw new InvalidOperationException("Embedded mod icon is not a valid image.");
					}
				}
				((Object)modIconTexture).name = "ItemPickupList Mod Icon";
				((Object)modIconTexture).hideFlags = (HideFlags)61;
				((Texture)modIconTexture).wrapMode = (TextureWrapMode)1;
				((Texture)modIconTexture).filterMode = (FilterMode)1;
				modIconSprite = Sprite.Create(modIconTexture, new Rect(0f, 0f, (float)((Texture)modIconTexture).width, (float)((Texture)modIconTexture).height), new Vector2(0.5f, 0.5f), 100f);
				((Object)modIconSprite).name = "ItemPickupList Mod Icon";
				((Object)modIconSprite).hideFlags = (HideFlags)61;
				ModSettingsManager.SetModIcon(modIconSprite, "rfaael.ItemPickupList", "ItemPickupList");
			}
			catch (Exception ex)
			{
				if (Object.op_Implicit((Object)(object)modIconSprite))
				{
					Object.Destroy((Object)(object)modIconSprite);
				}
				if (Object.op_Implicit((Object)(object)modIconTexture))
				{
					Object.Destroy((Object)(object)modIconTexture);
				}
				modIconSprite = null;
				modIconTexture = null;
				Log.LogWarning((object)("Failed to register the Risk of Options mod icon: " + ex));
			}
		}

		private void ResetToDefaults()
		{
			bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet;
			try
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
				foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in ((BaseUnityPlugin)this).Config)
				{
					item.Value.BoxedValue = item.Value.DefaultValue;
				}
				((BaseUnityPlugin)this).Config.Save();
				Log.LogInfo((object)"All ItemPickupList settings have been restored to defaults.");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to restore default settings: " + ex));
			}
			finally
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet;
			}
		}

		private void RegisterOptions()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_008d: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			//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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Expected O, but got Unknown
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: 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_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Expected O, but got Unknown
			//IL_01be: 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_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Expected O, but got Unknown
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Expected O, but got Unknown
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Expected O, but got Unknown
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Expected O, but got Unknown
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Expected O, but got Unknown
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Expected O, but got Unknown
			ModSettingsManager.SetModDescription("Displays pickups in a configurable HUD list that speeds up as the queue grows.");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled));
			ModSettingsManager.AddOption((BaseOption)new GenericButtonOption("Reset to defaults", "General", "Restore all ItemPickupList settings to their original defaults, including position, speed, visibility, and the F8 preview shortcut. Changes are saved immediately. If a control still shows its old value, reopen the mod settings page.", "Reset all", new UnityAction(ResetToDefaults)));
			ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)Position));
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(OffsetX, new StepSliderConfig
			{
				min = -1200f,
				max = 1200f,
				increment = 5f,
				FormatString = "{0:0}"
			}));
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(OffsetY, new StepSliderConfig
			{
				min = -700f,
				max = 700f,
				increment = 5f,
				FormatString = "{0:0}"
			}));
			ModSettingsManager.AddOption((BaseOption)new SliderOption(Scale, new SliderConfig
			{
				min = 0.5f,
				max = 2f,
				FormatString = "{0:0.00}x"
			}));
			object obj = <>O.<0>__TestList;
			if (obj == null)
			{
				UnityAction val = TestList;
				<>O.<0>__TestList = val;
				obj = (object)val;
			}
			ModSettingsManager.AddOption((BaseOption)new GenericButtonOption("Preview list", "Position", "Show five random example items to preview the list position.", "Preview", (UnityAction)obj));
			ModSettingsManager.AddOption((BaseOption)new KeyBindOption(TestKey));
			ModSettingsManager.AddOption((BaseOption)new SliderOption(BaseDuration, new SliderConfig
			{
				min = 0.5f,
				max = 15f,
				FormatString = "{0:0.0}s"
			}));
			ModSettingsManager.AddOption((BaseOption)new SliderOption(SpeedPerQueued, new SliderConfig
			{
				min = 0f,
				max = 2f,
				FormatString = "{0:0.00}"
			}));
			ModSettingsManager.AddOption((BaseOption)new SliderOption(MaxSpeed, new SliderConfig
			{
				min = 1f,
				max = 15f,
				FormatString = "{0:0.0}x"
			}));
			ModSettingsManager.AddOption((BaseOption)new SliderOption(SpawnInterval, new SliderConfig
			{
				min = 0.05f,
				max = 2f,
				FormatString = "{0:0.00}s"
			}));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(MaxVisible, new IntSliderConfig
			{
				min = 1,
				max = 15
			}));
		}

		public static void GetAnchor(ListPosition p, out float ax, out float ay)
		{
			switch (p)
			{
			case ListPosition.TopLeft:
				ax = 0f;
				ay = 1f;
				break;
			case ListPosition.TopCenter:
				ax = 0.5f;
				ay = 1f;
				break;
			case ListPosition.TopRight:
				ax = 1f;
				ay = 1f;
				break;
			case ListPosition.MiddleLeft:
				ax = 0f;
				ay = 0.5f;
				break;
			case ListPosition.Center:
				ax = 0.5f;
				ay = 0.5f;
				break;
			case ListPosition.MiddleRight:
				ax = 1f;
				ay = 0.5f;
				break;
			case ListPosition.BottomLeft:
				ax = 0f;
				ay = 0f;
				break;
			case ListPosition.BottomCenter:
				ax = 0.5f;
				ay = 0f;
				break;
			default:
				ax = 1f;
				ay = 0f;
				break;
			}
		}

		private void PatchNotifications()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			harmony = new Harmony("rfaael.ItemPickupList");
			int num = 0;
			MethodInfo[] methods = typeof(CharacterMasterNotificationQueue).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name != "PushNotification" || methodInfo.ReturnType != typeof(void))
				{
					continue;
				}
				ParameterInfo[] parameters = methodInfo.GetParameters();
				if (parameters.Length != 2 || parameters[0].ParameterType.Name != "NotificationInfo" || parameters[1].ParameterType != typeof(float))
				{
					continue;
				}
				Type parameterType = parameters[0].ParameterType;
				notificationDataField = AccessTools.Field(parameterType, "data");
				transformationField = AccessTools.Field(parameterType, "transformation");
				if (notificationDataField == null || transformationField == null)
				{
					Log.LogError((object)"Unsupported NotificationInfo format. Available fields:");
					FieldInfo[] fields = parameterType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					foreach (FieldInfo fieldInfo in fields)
					{
						Log.LogError((object)(fieldInfo.FieldType.FullName + " " + fieldInfo.Name));
					}
				}
				else
				{
					try
					{
						harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin).GetMethod("NotificationPrefix", BindingFlags.Static | BindingFlags.NonPublic)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						num++;
						Log.LogInfo((object)("Hooked local notification queue: " + methodInfo));
					}
					catch (Exception ex)
					{
						Log.LogError((object)("Failed to hook " + methodInfo?.ToString() + ": " + ex));
					}
				}
			}
			if (num != 0)
			{
				return;
			}
			Log.LogError((object)"No notification queue was hooked. Include this log in your bug report.");
			methods = typeof(CharacterMasterNotificationQueue).GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (methodInfo2.Name.StartsWith("Push"))
				{
					Log.LogInfo((object)("Available API: " + methodInfo2));
				}
			}
		}

		private static bool NotificationPrefix(CharacterMasterNotificationQueue __instance, object __0)
		{
			try
			{
				if (!Enabled.Value || !Object.op_Implicit((Object)(object)__instance) || __0 == null)
				{
					return true;
				}
				if (!receivedNotification)
				{
					receivedNotification = true;
					Log.LogInfo((object)"The queue received a game notification.");
				}
				if (transformationField.GetValue(__0) != null)
				{
					return true;
				}
				CharacterMaster component = ((Component)__instance).GetComponent<CharacterMaster>();
				if (!Object.op_Implicit((Object)(object)component) || !IsLocalMaster(component))
				{
					return true;
				}
				object value = notificationDataField.GetValue(__0);
				if (!TryBuildData(component, value, out var data))
				{
					if (value != null && unknownDataTypes.Add(value.GetType()))
					{
						Log.LogInfo((object)("Notification kept on the default HUD: " + value.GetType().FullName));
					}
					return true;
				}
				bool flag = Enqueue(component, data);
				Log.LogInfo((object)("Pickup: " + data.Name + " -> " + (flag ? "list" : "default HUD")));
				return !flag;
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to process notification (using the default HUD): " + ex));
				return true;
			}
		}

		private void OnDestroy()
		{
			if (TestKey != null)
			{
				TestKey.SettingChanged -= TestKeyChanged;
			}
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			if (Object.op_Implicit((Object)(object)PickupListUI.Instance))
			{
				Object.Destroy((Object)(object)((Component)PickupListUI.Instance).gameObject);
			}
			PickupListUI.Instance = null;
			if (Object.op_Implicit((Object)(object)modIconSprite))
			{
				Object.Destroy((Object)(object)modIconSprite);
			}
			if (Object.op_Implicit((Object)(object)modIconTexture))
			{
				Object.Destroy((Object)(object)modIconTexture);
			}
		}

		private static bool TryBuildData(CharacterMaster master, object arg, out PickupData data)
		{
			//IL_0013: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Invalid comparison between Unknown and I4
			//IL_0079: 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_005e: Invalid comparison between Unknown and I4
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Invalid comparison between Unknown and I4
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Invalid comparison between Unknown and I4
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			data = default(PickupData);
			ItemDef val = (ItemDef)((arg is ItemDef) ? arg : null);
			if (val != null)
			{
				return TryItem(master, val.itemIndex, out data);
			}
			EquipmentDef val2 = (EquipmentDef)((arg is EquipmentDef) ? arg : null);
			if (val2 != null)
			{
				return TryEquipment(val2.equipmentIndex, out data);
			}
			PickupDef val3 = (PickupDef)((arg is PickupDef) ? arg : null);
			if (val3 != null)
			{
				if ((int)val3.itemIndex != -1)
				{
					return TryItem(master, val3.itemIndex, out data);
				}
				if ((int)val3.equipmentIndex != -1)
				{
					return TryEquipment(val3.equipmentIndex, out data);
				}
				return false;
			}
			if (arg is ItemIndex)
			{
				return TryItem(master, (ItemIndex)arg, out data);
			}
			if (arg is EquipmentIndex)
			{
				return TryEquipment((EquipmentIndex)arg, out data);
			}
			if (arg is PickupIndex)
			{
				PickupDef pickupDef = PickupCatalog.GetPickupDef((PickupIndex)arg);
				if (pickupDef == null)
				{
					return false;
				}
				if ((int)pickupDef.itemIndex != -1)
				{
					return TryItem(master, pickupDef.itemIndex, out data);
				}
				if ((int)pickupDef.equipmentIndex != -1)
				{
					return TryEquipment(pickupDef.equipmentIndex, out data);
				}
			}
			return false;
		}

		private static bool TryItem(CharacterMaster master, ItemIndex idx, out PickupData data)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			data = default(PickupData);
			ItemDef itemDef = ItemCatalog.GetItemDef(idx);
			if ((Object)(object)itemDef == (Object)null)
			{
				return false;
			}
			PickupDef pickupDef = PickupCatalog.GetPickupDef(PickupCatalog.FindPickupIndex(idx));
			int count = ((!((Object)(object)master != (Object)null) || !((Object)(object)master.inventory != (Object)null)) ? 1 : master.inventory.GetItemCountEffective(idx));
			data = new PickupData
			{
				Icon = itemDef.pickupIconSprite,
				IconReference = itemDef.pickupIconSpriteReference,
				Name = Language.GetString(itemDef.nameToken),
				Desc = Language.GetString(itemDef.pickupToken),
				Color = (pickupDef?.baseColor ?? Color.white),
				Count = count
			};
			return true;
		}

		private static bool TryEquipment(EquipmentIndex idx, out PickupData data)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			data = default(PickupData);
			EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(idx);
			if ((Object)(object)equipmentDef == (Object)null)
			{
				return false;
			}
			PickupDef pickupDef = PickupCatalog.GetPickupDef(PickupCatalog.FindPickupIndex(idx));
			data = new PickupData
			{
				Icon = equipmentDef.pickupIconSprite,
				IconReference = equipmentDef.pickupIconSpriteReference,
				Name = Language.GetString(equipmentDef.nameToken),
				Desc = Language.GetString(equipmentDef.pickupToken),
				Color = (pickupDef?.baseColor ?? Color.white),
				Count = 1
			};
			return true;
		}

		private static bool IsLocalMaster(CharacterMaster master)
		{
			foreach (LocalUser readOnlyLocalUsers in LocalUserManager.readOnlyLocalUsersList)
			{
				if (readOnlyLocalUsers != null && (Object)(object)readOnlyLocalUsers.cachedMaster == (Object)(object)master)
				{
					return true;
				}
			}
			PlayerCharacterMasterController playerCharacterMasterController = master.playerCharacterMasterController;
			if (Object.op_Implicit((Object)(object)playerCharacterMasterController) && Object.op_Implicit((Object)(object)playerCharacterMasterController.networkUser))
			{
				return playerCharacterMasterController.networkUser.localUser != null;
			}
			return false;
		}

		private static bool Enqueue(CharacterMaster master, PickupData data)
		{
			PickupListUI instance = PickupListUI.Instance;
			if (!Object.op_Implicit((Object)(object)instance) || !IsLocalMaster(master))
			{
				return false;
			}
			instance.Enqueue(data);
			return true;
		}

		private unsafe static void TestList()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			PickupListUI instance = PickupListUI.Instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				Log.LogWarning((object)"Preview: the list has not been created yet.");
				return;
			}
			if (ItemCatalog.itemCount <= 0)
			{
				Log.LogWarning((object)"Preview: the item catalog is still loading. Try again once the menu has loaded.");
				return;
			}
			int num = 0;
			int num2 = 0;
			while (num < 5 && num2 < 200)
			{
				num2++;
				ItemIndex val = (ItemIndex)Random.Range(0, ItemCatalog.itemCount);
				try
				{
					ItemDef itemDef = ItemCatalog.GetItemDef(val);
					if (!((Object)(object)itemDef == (Object)null) && !itemDef.hidden && TryItem(null, val, out var data))
					{
						instance.Enqueue(data);
						num++;
					}
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("Preview: failed to prepare item " + ((object)(*(ItemIndex*)(&val))/*cast due to .constrained prefix*/).ToString() + ": " + ex));
				}
			}
			if (num == 0)
			{
				Log.LogWarning((object)"Preview: no valid items were found in the catalog.");
			}
			else
			{
				Log.LogInfo((object)("Preview: " + num + " items added to the list."));
			}
		}
	}
	public struct PickupData
	{
		public Sprite Icon;

		public AssetReferenceT<Sprite> IconReference;

		public string Name;

		public string Desc;

		public Color Color;

		public int Count;
	}
	public class PickupIconLoader : MonoBehaviour
	{
		private AssetOrDirectReference<Sprite> loadedIcon;

		private Image image;

		public void Load(Image target, AssetReferenceT<Sprite> reference, Sprite direct)
		{
			image = target;
			Show(direct);
			if (reference == null || !((AssetReference)reference).RuntimeKeyIsValid())
			{
				return;
			}
			try
			{
				loadedIcon = AssetOrDirectReference<Sprite>.GetNewInstance(reference, true, direct, (Action<Sprite>)Show, (Action<Sprite>)null);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Failed to load icon: " + ex));
			}
		}

		private void Show(Sprite sprite)
		{
			if (Object.op_Implicit((Object)(object)image))
			{
				image.sprite = sprite;
				((Behaviour)image).enabled = (Object)(object)sprite != (Object)null;
			}
		}

		private void OnDestroy()
		{
			image = null;
			if (loadedIcon != null)
			{
				loadedIcon.Reset();
				loadedIcon = null;
			}
		}
	}
	public class PickupListUI : MonoBehaviour
	{
		private class Entry
		{
			public GameObject Go;

			public RectTransform Rt;

			public CanvasGroup Group;

			public float Age;

			public float CurY;
		}

		public static PickupListUI Instance;

		private const float Width = 380f;

		private const float Height = 56f;

		private const float Gap = 6f;

		private const float Margin = 20f;

		private const float SlideTime = 0.25f;

		private const float FadeTime = 0.5f;

		private RectTransform root;

		private TMP_FontAsset font;

		private readonly Queue<PickupData> waiting = new Queue<PickupData>();

		private readonly List<Entry> active = new List<Entry>();

		private float spawnTimer;

		private bool errorLogged;

		public static void Create()
		{
			//IL_0025: 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_0030: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ItemPickupListCanvas", new Type[2]
			{
				typeof(Canvas),
				typeof(CanvasScaler)
			});
			Object.DontDestroyOnLoad((Object)val);
			Canvas component = val.GetComponent<Canvas>();
			component.renderMode = (RenderMode)0;
			component.sortingOrder = 500;
			CanvasScaler component2 = val.GetComponent<CanvasScaler>();
			component2.uiScaleMode = (ScaleMode)1;
			component2.referenceResolution = new Vector2(1920f, 1080f);
			component2.screenMatchMode = (ScreenMatchMode)0;
			component2.matchWidthOrHeight = 0.5f;
			Instance = val.AddComponent<PickupListUI>();
		}

		private void Awake()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ItemPickupListRoot", new Type[1] { typeof(RectTransform) });
			root = (RectTransform)val.transform;
			((Transform)root).SetParent(((Component)this).transform, false);
			root.sizeDelta = new Vector2(380f, 0f);
		}

		public void Enqueue(PickupData data)
		{
			waiting.Enqueue(data);
		}

		private TMP_FontAsset FindFont()
		{
			HGTextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<HGTextMeshProUGUI>();
			foreach (HGTextMeshProUGUI val in array)
			{
				if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)((TMP_Text)val).font))
				{
					return ((TMP_Text)val).font;
				}
			}
			return TMP_Settings.defaultFontAsset;
		}

		private static float TargetY(int i, int count, float ay)
		{
			float num = 62f;
			if (ay >= 1f)
			{
				return -28f - (float)i * num;
			}
			if (ay <= 0f)
			{
				return 28f + (float)(count - 1 - i) * num;
			}
			return ((float)(count - 1) * 0.5f - (float)i) * num;
		}

		private void Update()
		{
			try
			{
				Tick();
			}
			catch (Exception ex)
			{
				if (!errorLogged)
				{
					errorLogged = true;
					Plugin.Log.LogError((object)("Pickup list error: " + ex));
				}
			}
		}

		private void Tick()
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)root))
			{
				return;
			}
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			Plugin.GetAnchor(Plugin.Position.Value, out var ax, out var ay);
			float num = ((ax < 0.5f) ? 20f : ((ax > 0.5f) ? (-20f) : 0f));
			float num2 = ((ay < 0.5f) ? 20f : ((ay > 0.5f) ? (-20f) : 0f));
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(ax, ay);
			RectTransform obj = root;
			RectTransform obj2 = root;
			Vector2 val2 = (root.pivot = val);
			Vector2 anchorMin = (obj2.anchorMax = val2);
			obj.anchorMin = anchorMin;
			root.anchoredPosition = new Vector2(num + Plugin.OffsetX.Value, num2 + Plugin.OffsetY.Value);
			((Transform)root).localScale = Vector3.one * Plugin.Scale.Value;
			for (int num3 = active.Count - 1; num3 >= 0; num3--)
			{
				if ((Object)(object)active[num3].Go == (Object)null)
				{
					active.RemoveAt(num3);
				}
			}
			int num4 = waiting.Count + active.Count;
			float num5 = 1f + (float)Mathf.Max(0, num4 - 1) * Plugin.SpeedPerQueued.Value;
			num5 = Mathf.Min(num5, Plugin.MaxSpeed.Value);
			spawnTimer -= unscaledDeltaTime * num5;
			if (waiting.Count > 0 && active.Count < Plugin.MaxVisible.Value && spawnTimer <= 0f)
			{
				PickupData d = waiting.Dequeue();
				spawnTimer = Plugin.SpawnInterval.Value;
				try
				{
					Entry entry = Spawn(d);
					active.Add(entry);
					entry.CurY = TargetY(active.Count - 1, active.Count, ay);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("Failed to create list entry (" + d.Name + "): " + ex));
				}
			}
			float value = Plugin.BaseDuration.Value;
			for (int num6 = active.Count - 1; num6 >= 0; num6--)
			{
				Entry entry2 = active[num6];
				entry2.Age += unscaledDeltaTime * num5;
				if (entry2.Age >= value)
				{
					Object.Destroy((Object)(object)entry2.Go);
					active.RemoveAt(num6);
				}
			}
			float num7 = ((ax < 0.5f) ? (-1f) : ((ax > 0.5f) ? 1f : 0f));
			Vector2 val5 = default(Vector2);
			((Vector2)(ref val5))..ctor(ax, 0.5f);
			for (int i = 0; i < active.Count; i++)
			{
				Entry entry3 = active[i];
				float num8 = TargetY(i, active.Count, ay);
				entry3.CurY = Mathf.Lerp(entry3.CurY, num8, 1f - Mathf.Exp(-14f * unscaledDeltaTime));
				RectTransform rt = entry3.Rt;
				RectTransform rt2 = entry3.Rt;
				val2 = (entry3.Rt.pivot = val5);
				anchorMin = (rt2.anchorMax = val2);
				rt.anchorMin = anchorMin;
				float num9 = Mathf.Clamp01(entry3.Age / 0.25f);
				float num10 = 1f - (1f - num9) * (1f - num9);
				float num11 = num7 * Mathf.Lerp(410f, 0f, num10);
				entry3.Rt.anchoredPosition = new Vector2(num11, entry3.CurY);
				float num12 = Mathf.Clamp01((value - entry3.Age) / 0.5f);
				entry3.Group.alpha = Mathf.Min(num9, num12);
			}
		}

		private Entry Spawn(PickupData d)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//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_00c8: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: 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_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)font))
			{
				font = FindFont();
			}
			GameObject val = new GameObject("Pickup", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasGroup),
				typeof(Image)
			});
			try
			{
				RectTransform val2 = (RectTransform)val.transform;
				((Transform)val2).SetParent((Transform)(object)root, false);
				val2.sizeDelta = new Vector2(380f, 56f);
				((Graphic)val.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.55f);
				GameObject val3 = new GameObject("Icon", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				RectTransform val4 = (RectTransform)val3.transform;
				((Transform)val4).SetParent((Transform)(object)val2, false);
				Vector2 anchorMin = (val4.anchorMax = new Vector2(0f, 0.5f));
				val4.anchorMin = anchorMin;
				val4.pivot = new Vector2(0f, 0.5f);
				val4.sizeDelta = new Vector2(48f, 48f);
				val4.anchoredPosition = new Vector2(4f, 0f);
				Image component = val3.GetComponent<Image>();
				component.preserveAspect = true;
				((Graphic)component).raycastTarget = false;
				val3.AddComponent<PickupIconLoader>().Load(component, d.IconReference, d.Icon);
				GameObject val6 = new GameObject("Text", new Type[2]
				{
					typeof(RectTransform),
					typeof(HGTextMeshProUGUI)
				});
				RectTransform val7 = (RectTransform)val6.transform;
				((Transform)val7).SetParent((Transform)(object)val2, false);
				val7.anchorMin = Vector2.zero;
				val7.anchorMax = Vector2.one;
				val7.offsetMin = new Vector2(60f, 2f);
				val7.offsetMax = new Vector2(-6f, -2f);
				HGTextMeshProUGUI component2 = val6.GetComponent<HGTextMeshProUGUI>();
				if (Object.op_Implicit((Object)(object)font))
				{
					((TMP_Text)component2).font = font;
				}
				((TMP_Text)component2).fontSize = 18f;
				((TMP_Text)component2).alignment = (TextAlignmentOptions)4097;
				((TMP_Text)component2).enableWordWrapping = false;
				((TMP_Text)component2).overflowMode = (TextOverflowModes)1;
				string text = ColorUtility.ToHtmlStringRGB(d.Color);
				string text2 = ((d.Count > 1) ? (" <size=80%>x" + d.Count + "</size>") : "");
				((TMP_Text)component2).text = "<color=#" + text + ">" + d.Name + "</color>" + text2 + "\n<size=70%><color=#CCCCCC>" + d.Desc + "</color></size>";
				CanvasGroup component3 = val.GetComponent<CanvasGroup>();
				component3.alpha = 0f;
				component3.blocksRaycasts = false;
				component3.interactable = false;
				return new Entry
				{
					Go = val,
					Rt = val2,
					Group = component3,
					Age = 0f,
					CurY = 0f
				};
			}
			catch
			{
				Object.Destroy((Object)(object)val);
				throw;
			}
		}
	}
}