Decompiled source of ItemMarkers v1.0.0

ItemMarkers.dll

Decompiled 10 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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ItemMarkers.Core;
using Microsoft.CodeAnalysis;
using RoR2;
using RoR2.Artifacts;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;
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("Morslord")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ItemMarkers")]
[assembly: AssemblyTitle("ItemMarkers")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ItemMarkers
{
	public sealed class DiamondGraphic : MaskableGraphic
	{
		private Color borderColor;

		private bool border;

		public void SetColors(Color fill, bool hasBorder, Color outline)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (!(((Graphic)this).color == fill) || border != hasBorder || !(borderColor == outline))
			{
				((Graphic)this).color = fill;
				border = hasBorder;
				borderColor = outline;
				((Graphic)this).SetVerticesDirty();
			}
		}

		protected override void OnPopulateMesh(VertexHelper mesh)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0078: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_012f: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//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_0169: 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_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_019e: 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_01a9: 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)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_01d3: 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_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: 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_01f8: Unknown result type (might be due to invalid IL or missing references)
			mesh.Clear();
			Rect pixelAdjustedRect = ((Graphic)this).GetPixelAdjustedRect();
			Vector2 center = ((Rect)(ref pixelAdjustedRect)).center;
			float num = Mathf.Min(((Rect)(ref pixelAdjustedRect)).width, ((Rect)(ref pixelAdjustedRect)).height) * 0.5f;
			float num2 = (border ? Mathf.Max(0f, num - 1.25f) : num);
			Vector2[] array = (Vector2[])(object)new Vector2[4]
			{
				Vector2.up,
				Vector2.right,
				Vector2.down,
				Vector2.left
			};
			mesh.AddVert(Vector2.op_Implicit(center), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero));
			for (int i = 0; i < 4; i++)
			{
				mesh.AddVert(Vector2.op_Implicit(center + array[i] * num2), Color32.op_Implicit(((Graphic)this).color), Vector4.op_Implicit(Vector2.zero));
			}
			for (int j = 0; j < 4; j++)
			{
				mesh.AddTriangle(0, j + 1, (j + 1) % 4 + 1);
			}
			if (border)
			{
				for (int k = 0; k < 4; k++)
				{
					int num3 = (k + 1) % 4;
					int currentVertCount = mesh.currentVertCount;
					mesh.AddVert(Vector2.op_Implicit(center + array[k] * num), Color32.op_Implicit(borderColor), Vector4.op_Implicit(Vector2.zero));
					mesh.AddVert(Vector2.op_Implicit(center + array[num3] * num), Color32.op_Implicit(borderColor), Vector4.op_Implicit(Vector2.zero));
					mesh.AddVert(Vector2.op_Implicit(center + array[num3] * num2), Color32.op_Implicit(borderColor), Vector4.op_Implicit(Vector2.zero));
					mesh.AddVert(Vector2.op_Implicit(center + array[k] * num2), Color32.op_Implicit(borderColor), Vector4.op_Implicit(Vector2.zero));
					mesh.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2);
					mesh.AddTriangle(currentVertCount, currentVertCount + 2, currentVertCount + 3);
				}
			}
		}
	}
	internal sealed class HudMarkerLayer : IDisposable
	{
		private readonly HUD hud;

		private readonly RectTransform root;

		private readonly List<MarkerView> views = new List<MarkerView>(60);

		private readonly NearestMarkers<MarkerTarget> nearest = new NearestMarkers<MarkerTarget>();

		private readonly TMP_FontAsset? font;

		private readonly PickupIconCache icons;

		public bool IsValid
		{
			get
			{
				if (Object.op_Implicit((Object)(object)hud) && Object.op_Implicit((Object)(object)root) && Object.op_Implicit((Object)(object)hud.mainContainer))
				{
					return (Object)(object)((Transform)root).parent == (Object)(object)hud.mainContainer.transform;
				}
				return false;
			}
		}

		public HudMarkerLayer(HUD hud, PickupIconCache icons)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			this.hud = hud;
			this.icons = icons;
			GameObject val = new GameObject("Morslord.ItemMarkers.Hud", new Type[1] { typeof(RectTransform) });
			val.layer = hud.mainContainer.layer;
			root = val.GetComponent<RectTransform>();
			((Transform)root).SetParent(hud.mainContainer.transform, false);
			root.anchorMin = Vector2.zero;
			root.anchorMax = Vector2.one;
			root.offsetMin = (root.offsetMax = Vector2.zero);
			TMP_Text componentInChildren = ((Component)hud).GetComponentInChildren<TMP_Text>(true);
			font = (Object.op_Implicit((Object)(object)componentInChildren) ? componentInChildren.font : TMP_Settings.defaultFontAsset);
		}

		public void Select(List<MarkerTarget> targets, MarkerSettings settings)
		{
			//IL_0078: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			nearest.Clear();
			Camera val = (Object.op_Implicit((Object)(object)hud.cameraRigController) ? hud.cameraRigController.sceneCam : null);
			if ((Object)(object)val == (Object)null || !Object.op_Implicit((Object)(object)val))
			{
				Hide();
				return;
			}
			Vector3 val2 = (Object.op_Implicit((Object)(object)hud.targetBodyObject) ? hud.targetBodyObject.transform.position : ((Component)val).transform.position);
			foreach (MarkerTarget target in targets)
			{
				if (target.IsAlive)
				{
					Vector3 val3 = target.Source.transform.position - val2;
					float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
					if (MarkerRules.ShouldShowAtDistance(sqrMagnitude, settings.HideWithinDistance.Value))
					{
						nearest.Consider(target, sqrMagnitude, target.Identity, settings.MaximumMarkers.Value);
					}
				}
			}
			while (views.Count < nearest.Count)
			{
				views.Add(new MarkerView(root, font, icons));
			}
			for (int i = 0; i < views.Count; i++)
			{
				if (i < nearest.Count)
				{
					views[i].Bind(nearest[i]);
				}
				else
				{
					views[i].Hide();
				}
			}
		}

		public void Render(MarkerSettings settings)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: 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_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: 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_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: 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_01a4: 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_01b8: 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)
			Camera val = (Object.op_Implicit((Object)(object)hud.cameraRigController) ? hud.cameraRigController.sceneCam : null);
			if ((Object)(object)val == (Object)null || !Object.op_Implicit((Object)(object)val) || !((Behaviour)val).isActiveAndEnabled || !hud.mainContainer.activeInHierarchy || !Object.op_Implicit((Object)(object)Run.instance) || settings.MaximumMarkers.Value == 0)
			{
				Hide();
				return;
			}
			Vector3 val2 = (Object.op_Implicit((Object)(object)hud.targetBodyObject) ? hud.targetBodyObject.transform.position : ((Component)val).transform.position);
			float num = MarkerRules.ScaleFromPercent(settings.MarkerSize.Value);
			for (int i = 0; i < nearest.Count; i++)
			{
				MarkerTarget markerTarget = nearest[i];
				if (markerTarget.IsAlive && i < MarkerRules.ClampLimit(settings.MaximumMarkers.Value))
				{
					MarkerCategory category = markerTarget.Category;
					UniquePickup pickup = markerTarget.Pickup;
					if (settings.Allows(category, ((UniquePickup)(ref pickup)).isTempItem, markerTarget.Pickup.isRental))
					{
						Vector3 val3 = markerTarget.Source.transform.position - val2;
						float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
						if (!MarkerRules.ShouldShowAtDistance(sqrMagnitude, settings.HideWithinDistance.Value))
						{
							views[i].Hide();
							continue;
						}
						Vector3 val4 = val.WorldToViewportPoint(markerTarget.Position);
						float x = val4.x;
						float y = val4.y;
						float z = val4.z;
						Rect rect = root.rect;
						float width = ((Rect)(ref rect)).width;
						rect = root.rect;
						if (!MarkerProjection.TryPlace(x, y, z, width, ((Rect)(ref rect)).height, 45f * num, 48f * num, out var placement))
						{
							views[i].Hide();
							continue;
						}
						float distance = Mathf.Sqrt(sqrMagnitude);
						views[i].Show(new Vector2(placement.X, placement.Y), num, distance);
						continue;
					}
				}
				views[i].Hide();
			}
		}

		public void Hide()
		{
			foreach (MarkerView view in views)
			{
				view.Hide();
			}
		}

		public void Dispose()
		{
			if (Object.op_Implicit((Object)(object)root))
			{
				Object.Destroy((Object)(object)((Component)root).gameObject);
			}
			views.Clear();
			nearest.Clear();
		}
	}
	internal sealed class MarkerView
	{
		private readonly RectTransform root;

		private readonly Image image;

		private readonly RawImage textureImage;

		private readonly DiamondGraphic diamond;

		private readonly TextMeshProUGUI distanceLabel;

		private readonly PickupIconCache icons;

		private int previousDistance = -1;

		public MarkerView(RectTransform parent, TMP_FontAsset? font, PickupIconCache icons)
		{
			//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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: 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_01e2: Unknown result type (might be due to invalid IL or missing references)
			this.icons = icons;
			root = MakeRect("Marker", (Transform)(object)parent, new Vector2(90f, 84f), Vector2.zero);
			image = ((Component)MakeRect("Item Icon", (Transform)(object)root, new Vector2(32f, 32f), new Vector2(0f, 6f))).gameObject.AddComponent<Image>();
			image.preserveAspect = true;
			((Graphic)image).raycastTarget = false;
			textureImage = ((Component)MakeRect("Item Texture", (Transform)(object)root, new Vector2(32f, 32f), new Vector2(0f, 6f))).gameObject.AddComponent<RawImage>();
			((Graphic)textureImage).raycastTarget = false;
			diamond = ((Component)MakeRect("Command Diamond", (Transform)(object)root, new Vector2(18f, 18f), new Vector2(0f, 6f))).gameObject.AddComponent<DiamondGraphic>();
			((Graphic)diamond).raycastTarget = false;
			distanceLabel = ((Component)MakeRect("Distance", (Transform)(object)root, new Vector2(90f, 22f), new Vector2(0f, -22f))).gameObject.AddComponent<TextMeshProUGUI>();
			if (Object.op_Implicit((Object)(object)font))
			{
				((TMP_Text)distanceLabel).font = font;
			}
			((TMP_Text)distanceLabel).fontSize = 14f;
			((TMP_Text)distanceLabel).alignment = (TextAlignmentOptions)514;
			((Graphic)distanceLabel).color = Color.white;
			((Graphic)distanceLabel).raycastTarget = false;
			((TMP_Text)distanceLabel).enableWordWrapping = false;
			Shadow obj = ((Component)distanceLabel).gameObject.AddComponent<Shadow>();
			obj.effectColor = Color.black;
			obj.effectDistance = new Vector2(1f, -1f);
			Hide();
		}

		public void Bind(MarkerTarget target)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			Sprite val = (target.Command ? null : icons.Resolve(target.Definition));
			image.sprite = val;
			((Behaviour)image).enabled = !target.Command && Object.op_Implicit((Object)(object)val);
			textureImage.texture = target.Definition.iconTexture;
			((Behaviour)textureImage).enabled = !target.Command && !Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)target.Definition.iconTexture);
			((Behaviour)diamond).enabled = target.Command;
			if (target.Command)
			{
				Color fill = (target.LunarEquipment ? Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)5)) : target.Definition.baseColor);
				diamond.SetColors(fill, target.LunarEquipment, Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)4)));
			}
		}

		public void Show(Vector2 position, float scale, float distance)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Component)root).gameObject.activeSelf)
			{
				((Component)root).gameObject.SetActive(true);
			}
			root.anchoredPosition = position;
			((Transform)root).localScale = Vector3.one * scale;
			int num = Mathf.Max(0, Mathf.RoundToInt(distance));
			if (num != previousDistance)
			{
				((TMP_Text)distanceLabel).SetText("{0:0} m", (float)num);
				previousDistance = num;
			}
		}

		public void Hide()
		{
			if (((Component)root).gameObject.activeSelf)
			{
				((Component)root).gameObject.SetActive(false);
			}
		}

		private static RectTransform MakeRect(string name, Transform parent, Vector2 size, Vector2 offset)
		{
			//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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = new GameObject(name, new Type[1] { typeof(RectTransform) })
			{
				layer = ((Component)parent).gameObject.layer
			}.GetComponent<RectTransform>();
			((Transform)component).SetParent(parent, false);
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			component.pivot = val;
			Vector2 anchorMin = (component.anchorMax = val);
			component.anchorMin = anchorMin;
			component.sizeDelta = size;
			component.anchoredPosition = offset;
			return component;
		}
	}
	internal readonly struct MarkerTarget
	{
		public Component Source { get; }

		public UniquePickup Pickup { get; }

		public bool Command { get; }

		public PickupDef Definition { get; }

		public MarkerCategory Category { get; }

		public bool LunarEquipment { get; }

		public int Identity { get; }

		public bool IsAlive
		{
			get
			{
				//IL_0049: 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_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				if (Object.op_Implicit((Object)(object)Source) && Source.gameObject.activeInHierarchy)
				{
					if (!Command)
					{
						return ((GenericPickupController)Source).pickup == Pickup;
					}
					return ((PickupPickerController)Source).available;
				}
				return false;
			}
		}

		public Vector3 Position => Source.transform.position + Vector3.up * 0.8f;

		public MarkerTarget(Component source, UniquePickup pickup, bool command, PickupDef definition, MarkerCategory category, bool lunarEquipment)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Source = source;
			Pickup = pickup;
			Command = command;
			Definition = definition;
			Category = category;
			LunarEquipment = lunarEquipment;
			Identity = ((Object)source).GetInstanceID();
		}
	}
	internal static class PickupDiscovery
	{
		private static readonly FieldInfo? CommandPrefab = typeof(CommandArtifactManager).GetField("commandCubePrefab", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

		public static void Collect(List<MarkerTarget> targets, MarkerSettings settings)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			targets.Clear();
			foreach (GenericPickupController instances in InstanceTracker.GetInstancesList<GenericPickupController>())
			{
				if (Object.op_Implicit((Object)(object)instances) && ((Behaviour)instances).isActiveAndEnabled && TryDescribe(instances.pickup, settings, out PickupDef def, out MarkerCategory category, out bool lunarEquipment))
				{
					targets.Add(new MarkerTarget((Component)(object)instances, instances.pickup, command: false, def, category, lunarEquipment));
				}
			}
			foreach (PickupPickerController instances2 in InstanceTracker.GetInstancesList<PickupPickerController>())
			{
				if (Object.op_Implicit((Object)(object)instances2) && ((Behaviour)instances2).isActiveAndEnabled && instances2.available && IsCommandEssence(instances2) && TryDescribeCommand(instances2, settings, out UniquePickup pickup, out PickupDef def2, out MarkerCategory category2, out bool lunar))
				{
					targets.Add(new MarkerTarget((Component)(object)instances2, pickup, command: true, def2, category2, lunar));
				}
			}
		}

		private static bool TryDescribe(UniquePickup pickup, MarkerSettings settings, out PickupDef? def, out MarkerCategory category, out bool lunarEquipment)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			//IL_0026: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			def = PickupCatalog.GetPickupDef(pickup.pickupIndex);
			category = MarkerCategory.Unknown;
			lunarEquipment = false;
			if (def == null)
			{
				return false;
			}
			if ((int)def.equipmentIndex != -1)
			{
				EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(def.equipmentIndex);
				if (!Object.op_Implicit((Object)(object)equipmentDef))
				{
					return false;
				}
				lunarEquipment = equipmentDef.isLunar;
				category = MarkerCategory.Equipment;
			}
			else if ((int)def.itemIndex != -1)
			{
				ItemDef itemDef = ItemCatalog.GetItemDef(def.itemIndex);
				if (!Object.op_Implicit((Object)(object)itemDef) || itemDef.hidden)
				{
					return false;
				}
				category = MarkerRules.Classify(((object)itemDef.tier/*cast due to .constrained prefix*/).ToString(), equipment: false);
			}
			return settings.Allows(category, ((UniquePickup)(ref pickup)).isTempItem, pickup.isRental);
		}

		private static bool TryDescribeCommand(PickupPickerController picker, MarkerSettings settings, out UniquePickup pickup, out PickupDef? def, out MarkerCategory category, out bool lunar)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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)
			//IL_0094: 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)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			pickup = default(UniquePickup);
			def = null;
			category = MarkerCategory.Unknown;
			lunar = false;
			bool flag = false;
			if (picker.options == null)
			{
				return false;
			}
			Option[] options = picker.options;
			for (int i = 0; i < options.Length; i++)
			{
				Option val = options[i];
				if (val.available && TryDescribe(val.pickup, settings, out PickupDef def2, out MarkerCategory category2, out bool lunarEquipment))
				{
					if (flag && (category != category2 || lunar != lunarEquipment || ((UniquePickup)(ref pickup)).isTempItem != ((UniquePickup)(ref val.pickup)).isTempItem || pickup.isRental != val.pickup.isRental))
					{
						return false;
					}
					if (!flag)
					{
						pickup = val.pickup;
						def = def2;
						category = category2;
						lunar = lunarEquipment;
						flag = true;
					}
				}
			}
			if (flag && picker.pickupThatGeneratedOptions.HasValue)
			{
				UniquePickup value = picker.pickupThatGeneratedOptions.Value;
				if (!settings.Allows(category, ((UniquePickup)(ref value)).isTempItem, value.isRental))
				{
					return false;
				}
				pickup.isRental |= value.isRental;
				if (((UniquePickup)(ref value)).isTempItem)
				{
					pickup.decayValue = value.decayValue;
				}
			}
			return flag;
		}

		private static bool IsCommandEssence(PickupPickerController picker)
		{
			//IL_005c: 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_006c: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			if (picker.isDelusionChoice || picker.isRebirthChoice)
			{
				return false;
			}
			object? obj = CommandPrefab?.GetValue(null);
			GameObject val = (GameObject)((obj is GameObject) ? obj : null);
			if ((Object)(object)val == (Object)null || !Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			NetworkIdentity component = val.GetComponent<NetworkIdentity>();
			NetworkIdentity component2 = ((Component)picker).GetComponent<NetworkIdentity>();
			if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2))
			{
				NetworkHash128 assetId = component.assetId;
				if (((NetworkHash128)(ref assetId)).IsValid())
				{
					assetId = component.assetId;
					if (((NetworkHash128)(ref assetId)).Equals(component2.assetId))
					{
						if (!CreatesPickup((UnityEventBase?)(object)picker.onPickupSelected, picker))
						{
							return CreatesPickup((UnityEventBase?)(object)picker.onUniquePickupSelected, picker);
						}
						return true;
					}
				}
			}
			return false;
		}

		private static bool CreatesPickup(UnityEventBase? selectionEvent, PickupPickerController picker)
		{
			if (selectionEvent == null)
			{
				return false;
			}
			for (int i = 0; i < selectionEvent.GetPersistentEventCount(); i++)
			{
				if (selectionEvent.GetPersistentTarget(i) == (Object)(object)picker && selectionEvent.GetPersistentMethodName(i) == "CreatePickup")
				{
					return true;
				}
			}
			return false;
		}
	}
	internal sealed class PickupIconCache
	{
		private sealed class SpriteRequest : IAssetRequest<Sprite>, IDisposable
		{
			private AsyncOperationHandle<Sprite> handle;

			private bool released;

			public bool IsDone
			{
				get
				{
					if (!released && handle.IsValid())
					{
						return handle.IsDone;
					}
					return false;
				}
			}

			public Sprite? Asset
			{
				get
				{
					//IL_000e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0014: Invalid comparison between Unknown and I4
					if (!IsDone || (int)handle.Status != 1)
					{
						return null;
					}
					return handle.Result;
				}
			}

			public Exception? Error
			{
				get
				{
					//IL_000e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0014: Invalid comparison between Unknown and I4
					if (!IsDone || (int)handle.Status != 2)
					{
						return null;
					}
					return handle.OperationException ?? new InvalidOperationException("Addressable sprite load failed.");
				}
			}

			public SpriteRequest(object key)
			{
				//IL_0008: 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)
				handle = Addressables.LoadAssetAsync<Sprite>(key);
			}

			public void Dispose()
			{
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				if (!released)
				{
					released = true;
					if (handle.IsValid())
					{
						Addressables.Release<Sprite>(handle);
					}
					handle = default(AsyncOperationHandle<Sprite>);
				}
			}
		}

		private readonly AsyncAssetCache<object, Sprite> sprites;

		private readonly ManualLogSource log;

		private int failures;

		public PickupIconCache(ManualLogSource log)
		{
			this.log = log;
			sprites = new AsyncAssetCache<object, Sprite>((object key) => new SpriteRequest(key), ReportFailure);
		}

		public Sprite? Resolve(PickupDef definition)
		{
			Sprite icon = definition.GetIcon();
			if (Object.op_Implicit((Object)(object)icon))
			{
				return icon;
			}
			AssetReferenceT<Sprite> iconReference = definition.GetIconReference();
			if (iconReference == null || !((AssetReference)iconReference).RuntimeKeyIsValid())
			{
				return null;
			}
			return sprites.Get(((AssetReference)iconReference).RuntimeKey);
		}

		public void Clear()
		{
			sprites.Clear();
			failures = 0;
		}

		private void ReportFailure(object key, Exception error)
		{
			if (failures < 5)
			{
				log.LogWarning((object)("ItemMarkers could not load/release pickup icon '" + key?.ToString() + "': " + error));
			}
			else if (failures == 5)
			{
				log.LogWarning((object)"Further pickup icon errors are suppressed until the next run.");
			}
			failures++;
		}
	}
	internal static class OptionalOptionsMenu
	{
		public const string Guid = "com.rune580.riskofoptions";

		private static Texture2D? modIconTexture;

		private static Sprite? modIcon;

		public static void Register(MarkerSettings settings, ManualLogSource log)
		{
			if (!Chainloader.PluginInfos.TryGetValue("com.rune580.riskofoptions", out var value))
			{
				return;
			}
			try
			{
				Assembly assembly = ((object)value.Instance).GetType().Assembly;
				Type type = RequiredType(assembly, "RiskOfOptions.ModSettingsManager");
				Type type2 = RequiredType(assembly, "RiskOfOptions.Options.BaseOption");
				MethodInfo add = type.GetMethod("AddOption", new Type[3]
				{
					type2,
					typeof(string),
					typeof(string)
				}) ?? throw new MissingMethodException("RiskOfOptions.ModSettingsManager.AddOption");
				object optionConfig = NewConfig(assembly, "IntSliderConfig", ("min", 0), ("max", 60));
				object optionConfig2 = NewConfig(assembly, "IntSliderConfig", ("min", 0), ("max", 50), ("formatString", "{0} m"));
				object optionConfig3 = NewConfig(assembly, "StepSliderConfig", ("min", 50f), ("max", 200f), ("increment", 5f), ("remapManualInputToStep", true));
				Add("IntSliderOption", (ConfigEntryBase)(object)settings.MaximumMarkers, optionConfig);
				Add("StepSliderOption", (ConfigEntryBase)(object)settings.MarkerSize, optionConfig3);
				Add("IntSliderOption", (ConfigEntryBase)(object)settings.HideWithinDistance, optionConfig2);
				Add("CheckBoxOption", (ConfigEntryBase)(object)settings.ShowTemporary);
				Add("CheckBoxOption", (ConfigEntryBase)(object)settings.ShowEthereal);
				foreach (ConfigEntry<bool> value2 in settings.Categories.Values)
				{
					Add("CheckBoxOption", (ConfigEntryBase)(object)value2);
				}
				type.GetMethod("SetModDescription", new Type[3]
				{
					typeof(string),
					typeof(string),
					typeof(string)
				})?.Invoke(null, new object[3] { "Client-side ground item and Command essence markers by Morslord.", "com.morslord.itemmarkers", "ItemMarkers" });
				RegisterIcon(type, log);
				log.LogInfo((object)("Registered " + (5 + settings.Categories.Count) + " ItemMarkers options in RiskOfOptions."));
				void Add(string optionName, ConfigEntryBase entry, object? obj2 = null)
				{
					Type type3 = RequiredType(assembly, "RiskOfOptions.Options." + optionName);
					object obj = ((obj2 == null) ? Activator.CreateInstance(type3, entry) : Activator.CreateInstance(type3, entry, obj2));
					add.Invoke(null, new object[3] { obj, "com.morslord.itemmarkers", "ItemMarkers" });
				}
			}
			catch (Exception ex)
			{
				log.LogError((object)("RiskOfOptions registration failed. BepInEx configuration remains available. " + ex));
			}
		}

		private static void RegisterIcon(Type manager, ManualLogSource log)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				MethodInfo methodInfo = manager.GetMethod("SetModIcon", new Type[3]
				{
					typeof(Sprite),
					typeof(string),
					typeof(string)
				}) ?? throw new MissingMethodException("RiskOfOptions.ModSettingsManager.SetModIcon(Sprite, string, string)");
				if (!Object.op_Implicit((Object)(object)modIcon))
				{
					using Stream stream = typeof(OptionalOptionsMenu).Assembly.GetManifestResourceStream("ItemMarkers.Resources.ModIcon.png") ?? throw new InvalidOperationException("Embedded ItemMarkers mod icon is missing.");
					using MemoryStream memoryStream = new MemoryStream();
					stream.CopyTo(memoryStream);
					Texture2D val = (modIconTexture = new Texture2D(2, 2, (TextureFormat)4, false));
					if (!ImageConversion.LoadImage(val, memoryStream.ToArray(), true))
					{
						throw new InvalidOperationException("Embedded ItemMarkers mod icon could not be decoded as PNG.");
					}
					((Object)val).name = "ItemMarkers Mod Icon";
					((Texture)val).filterMode = (FilterMode)1;
					((Texture)val).wrapMode = (TextureWrapMode)1;
					modIcon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
					if (!Object.op_Implicit((Object)(object)modIcon))
					{
						throw new InvalidOperationException("Could not create ItemMarkers mod icon sprite.");
					}
					((Object)modIcon).name = "ItemMarkers Mod Icon";
				}
				methodInfo.Invoke(null, new object[3] { modIcon, "com.morslord.itemmarkers", "ItemMarkers" });
				log.LogInfo((object)"Registered embedded ItemMarkers mod icon in RiskOfOptions.");
			}
			catch (Exception ex)
			{
				ReleaseIcon();
				log.LogWarning((object)("RiskOfOptions mod icon registration failed; settings remain available. " + ex));
			}
		}

		public static void ReleaseIcon()
		{
			if (Object.op_Implicit((Object)(object)modIcon))
			{
				Object.Destroy((Object)(object)modIcon);
			}
			if (Object.op_Implicit((Object)(object)modIconTexture))
			{
				Object.Destroy((Object)(object)modIconTexture);
			}
			modIcon = null;
			modIconTexture = null;
		}

		private static Type RequiredType(Assembly assembly, string name)
		{
			return assembly.GetType(name, throwOnError: true);
		}

		private static object NewConfig(Assembly assembly, string name, params (string name, object value)[] values)
		{
			Type type = RequiredType(assembly, "RiskOfOptions.OptionConfigs." + name);
			object obj = Activator.CreateInstance(type);
			for (int i = 0; i < values.Length; i++)
			{
				(string, object) tuple = values[i];
				(type.GetField(tuple.Item1) ?? throw new MissingFieldException(type.FullName, tuple.Item1)).SetValue(obj, tuple.Item2);
			}
			return obj;
		}
	}
	[BepInPlugin("com.morslord.itemmarkers", "ItemMarkers", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class ItemMarkersPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.morslord.itemmarkers";

		public const string PluginName = "ItemMarkers";

		public const string PluginVersion = "1.0.0";

		public const string ConfigFileName = "local.itemmarkers.cfg";

		private MarkerSettings settings;

		private PickupIconCache? icons;

		private Run? iconRun;

		private readonly List<MarkerTarget> targets = new List<MarkerTarget>(128);

		private readonly Dictionary<HUD, HudMarkerLayer> layers = new Dictionary<HUD, HudMarkerLayer>();

		private readonly List<HUD> staleHuds = new List<HUD>();

		private float nextSweep;

		private float nextErrorLog;

		private void Awake()
		{
			try
			{
				settings = new MarkerSettings(OpenMarkerConfig());
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Could not initialize local.itemmarkers.cfg; ItemMarkers is disabled to avoid replacing existing settings. " + ex));
				((Behaviour)this).enabled = false;
				return;
			}
			icons = new PickupIconCache(((BaseUnityPlugin)this).Logger);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"ItemMarkers 1.0.0 by Morslord initialized. Local HUD only.");
		}

		private ConfigFile OpenMarkerConfig()
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			string text = Path.Combine(Paths.ConfigPath, "local.itemmarkers.cfg");
			string text2 = Path.Combine(Paths.ConfigPath, "com.morslord.itemmarkers.cfg");
			if (!File.Exists(text) && File.Exists(text2))
			{
				File.Copy(text2, text, overwrite: false);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Copied existing settings to local.itemmarkers.cfg; the original configuration is retained.");
			}
			return new ConfigFile(text, true, ((BaseUnityPlugin)this).Info.Metadata);
		}

		private void Start()
		{
			OptionalOptionsMenu.Register(settings, ((BaseUnityPlugin)this).Logger);
		}

		private void LateUpdate()
		{
			try
			{
				if (iconRun != Run.instance)
				{
					ClearLayers();
					icons?.Clear();
					iconRun = Run.instance;
				}
				if (!Object.op_Implicit((Object)(object)Run.instance) || HUD.readOnlyInstanceList.Count == 0 || MarkerRules.ClampLimit(settings.MaximumMarkers.Value) == 0)
				{
					ClearLayers();
					targets.Clear();
					nextSweep = 0f;
					return;
				}
				if (Time.unscaledTime >= nextSweep)
				{
					nextSweep = Time.unscaledTime + 0.2f;
					PickupDiscovery.Collect(targets, settings);
					RefreshHuds();
					foreach (HudMarkerLayer value in layers.Values)
					{
						value.Select(targets, settings);
					}
				}
				foreach (HudMarkerLayer value2 in layers.Values)
				{
					value2.Render(settings);
				}
			}
			catch (Exception ex)
			{
				ClearLayers();
				targets.Clear();
				nextSweep = Time.unscaledTime + 2f;
				if (Time.unscaledTime >= nextErrorLog)
				{
					nextErrorLog = Time.unscaledTime + 10f;
					((BaseUnityPlugin)this).Logger.LogError((object)("ItemMarkers HUD update failed; retrying discovery after two seconds. " + ex));
				}
			}
		}

		private void RefreshHuds()
		{
			staleHuds.Clear();
			foreach (KeyValuePair<HUD, HudMarkerLayer> layer in layers)
			{
				if (!Object.op_Implicit((Object)(object)layer.Key) || !layer.Value.IsValid || !HUD.readOnlyInstanceList.Contains(layer.Key))
				{
					staleHuds.Add(layer.Key);
				}
			}
			foreach (HUD staleHud in staleHuds)
			{
				layers[staleHud].Dispose();
				layers.Remove(staleHud);
			}
			foreach (HUD readOnlyInstance in HUD.readOnlyInstanceList)
			{
				if (Object.op_Implicit((Object)(object)readOnlyInstance) && Object.op_Implicit((Object)(object)readOnlyInstance.mainContainer) && Object.op_Implicit((Object)(object)readOnlyInstance.cameraRigController) && !layers.ContainsKey(readOnlyInstance))
				{
					layers.Add(readOnlyInstance, new HudMarkerLayer(readOnlyInstance, icons));
				}
			}
		}

		private void OnDisable()
		{
			ClearLayers();
			icons?.Clear();
			iconRun = null;
		}

		private void OnDestroy()
		{
			ClearLayers();
			icons?.Clear();
			iconRun = null;
			OptionalOptionsMenu.ReleaseIcon();
		}

		private void ClearLayers()
		{
			foreach (HudMarkerLayer value in layers.Values)
			{
				value.Dispose();
			}
			layers.Clear();
		}
	}
	internal sealed class MarkerSettings
	{
		public readonly ConfigEntry<int> MaximumMarkers;

		public readonly ConfigEntry<float> MarkerSize;

		public readonly ConfigEntry<int> HideWithinDistance;

		public readonly ConfigEntry<bool> ShowTemporary;

		public readonly ConfigEntry<bool> ShowEthereal;

		public readonly Dictionary<MarkerCategory, ConfigEntry<bool>> Categories = new Dictionary<MarkerCategory, ConfigEntry<bool>>();

		public MarkerSettings(ConfigFile config)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			MaximumMarkers = config.Bind<int>("Markers", "Maximum Markers", 60, new ConfigDescription("Maximum simultaneous markers, including Command essences.\n\n0 hides all markers. The nearest eligible pickups are preferred.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 60), Array.Empty<object>()));
			MarkerSize = config.Bind<float>("Markers", "Marker Size", 100f, new ConfigDescription("Marker size as a percentage.\n\nApplies to the icon or diamond and the distance label. Steps of 5 percent.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(50f, 200f), Array.Empty<object>()));
			HideWithinDistance = config.Bind<int>("Markers", "Hide Within Distance", 5, new ConfigDescription("Hide item and Command essence markers when closer than this distance in meters.\n\n0 disables proximity hiding. Steps of 1 meter. Nearby hidden pickups do not use marker slots.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>()));
			ShowTemporary = config.Bind<bool>("Item Variants", "Temporary Items", true, "Show temporary items with a decay duration.\n\nThe item's category filter must also be enabled.");
			ShowEthereal = config.Bind<bool>("Item Variants", "Ethereal Items", true, "Show Ethereal items that last for the current stage.\n\nThe item's category filter must also be enabled. This filter is separate from temporary items.");
			foreach (MarkerCategory value in Enum.GetValues(typeof(MarkerCategory)))
			{
				if (value != MarkerCategory.Unknown)
				{
					Categories.Add(value, config.Bind<bool>("Item Categories", value.ToString(), true, "Show " + value.ToString() + " pickups and their Command essences.\n\nTemporary and Ethereal variants must also pass their respective filters."));
				}
			}
		}

		public bool Allows(MarkerCategory category, bool temporary, bool ethereal)
		{
			ConfigEntry<bool> value;
			return MarkerRules.Allows(category, Categories.TryGetValue(category, out value) && value.Value, temporary, ethereal, ShowTemporary.Value, ShowEthereal.Value);
		}
	}
}
namespace ItemMarkers.Core
{
	public interface IAssetRequest<TAsset> : IDisposable where TAsset : class
	{
		bool IsDone { get; }

		TAsset? Asset { get; }

		Exception? Error { get; }
	}
	public sealed class AsyncAssetCache<TKey, TAsset> where TKey : notnull where TAsset : class
	{
		private sealed class Entry
		{
			public IAssetRequest<TAsset>? Request;

			public bool FailureReported;
		}

		private readonly Dictionary<TKey, Entry> entries = new Dictionary<TKey, Entry>();

		private readonly Func<TKey, IAssetRequest<TAsset>> load;

		private readonly Action<TKey, Exception> reportError;

		public AsyncAssetCache(Func<TKey, IAssetRequest<TAsset>> load, Action<TKey, Exception> reportError)
		{
			this.load = load;
			this.reportError = reportError;
		}

		public TAsset? Get(TKey key)
		{
			if (!entries.TryGetValue(key, out Entry value))
			{
				value = new Entry();
				entries.Add(key, value);
				try
				{
					value.Request = load(key);
				}
				catch (Exception error)
				{
					ReportOnce(key, value, error);
				}
			}
			IAssetRequest<TAsset> request = value.Request;
			if (request == null || !request.IsDone)
			{
				return null;
			}
			if (request.Error != null)
			{
				ReportOnce(key, value, request.Error);
				return null;
			}
			TAsset? asset = request.Asset;
			if (asset == null)
			{
				ReportOnce(key, value, new InvalidOperationException("Asset load completed without an asset."));
			}
			return asset;
		}

		public void Clear()
		{
			foreach (KeyValuePair<TKey, Entry> entry in entries)
			{
				try
				{
					entry.Value.Request?.Dispose();
				}
				catch (Exception arg)
				{
					reportError(entry.Key, arg);
				}
			}
			entries.Clear();
		}

		private void ReportOnce(TKey key, Entry entry, Exception error)
		{
			if (!entry.FailureReported)
			{
				entry.FailureReported = true;
				reportError(key, error);
			}
		}
	}
	public enum MarkerCategory
	{
		Unknown,
		White,
		Green,
		Red,
		Boss,
		Lunar,
		Void,
		Hallowed,
		Hex,
		Pages,
		Equipment
	}
	public static class MarkerRules
	{
		public static MarkerCategory Classify(string tier, bool equipment)
		{
			if (equipment)
			{
				return MarkerCategory.Equipment;
			}
			switch (tier)
			{
			case "Tier1":
				return MarkerCategory.White;
			case "Tier2":
				return MarkerCategory.Green;
			case "Tier3":
				return MarkerCategory.Red;
			case "Boss":
				return MarkerCategory.Boss;
			case "Lunar":
				return MarkerCategory.Lunar;
			case "Cursed":
				return MarkerCategory.Hallowed;
			case "Hex":
				return MarkerCategory.Hex;
			case "Page":
				return MarkerCategory.Pages;
			default:
				if (!tier.StartsWith("Void", StringComparison.Ordinal))
				{
					return MarkerCategory.Unknown;
				}
				return MarkerCategory.Void;
			}
		}

		public static bool Allows(MarkerCategory category, bool categoryEnabled, bool temporary, bool ethereal, bool showTemporary, bool showEthereal)
		{
			if (category != MarkerCategory.Unknown && categoryEnabled && (!temporary || showTemporary))
			{
				return !ethereal || showEthereal;
			}
			return false;
		}

		public static int ClampLimit(int value)
		{
			return Math.Max(0, Math.Min(60, value));
		}

		public static bool ShouldShowAtDistance(float distanceSquared, int hideWithinMeters)
		{
			if (!IsFinite(distanceSquared) || distanceSquared < 0f)
			{
				return false;
			}
			int num = Math.Max(0, Math.Min(50, hideWithinMeters));
			if (num != 0)
			{
				return distanceSquared >= (float)(num * num);
			}
			return true;
		}

		public static float ScaleFromPercent(float value)
		{
			if (!IsFinite(value))
			{
				return 1f;
			}
			return (float)Math.Round(Math.Max(50f, Math.Min(200f, value)) / 5f, MidpointRounding.AwayFromZero) * 0.05f;
		}

		public static bool IsFinite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}
	}
	public readonly struct MarkerPlacement
	{
		public float X { get; }

		public float Y { get; }

		public bool AtEdge { get; }

		public MarkerPlacement(float x, float y, bool atEdge)
		{
			X = x;
			Y = y;
			AtEdge = atEdge;
		}
	}
	public static class MarkerProjection
	{
		public static bool TryPlace(float viewportX, float viewportY, float depth, float width, float height, float marginX, float marginY, out MarkerPlacement placement)
		{
			placement = default(MarkerPlacement);
			if (!MarkerRules.IsFinite(viewportX) || !MarkerRules.IsFinite(viewportY) || !MarkerRules.IsFinite(depth) || !MarkerRules.IsFinite(width) || !MarkerRules.IsFinite(height) || width <= 0f || height <= 0f)
			{
				return false;
			}
			float num = (viewportX - 0.5f) * width;
			float num2 = (viewportY - 0.5f) * height;
			float num3 = Math.Max(1f, width / 2f - marginX);
			float num4 = Math.Max(1f, height / 2f - marginY);
			bool flag = depth <= 0f || Math.Abs(num) > num3 || Math.Abs(num2) > num4;
			if (depth <= 0f)
			{
				num = 0f - num;
				num2 = 0f - num2;
			}
			if (flag)
			{
				if (Math.Abs(num) + Math.Abs(num2) < 0.001f)
				{
					num2 = -1f;
				}
				float num5 = Math.Max(Math.Abs(num) / num3, Math.Abs(num2) / num4);
				num /= num5;
				num2 /= num5;
			}
			placement = new MarkerPlacement(num, num2, flag);
			if (MarkerRules.IsFinite(num))
			{
				return MarkerRules.IsFinite(num2);
			}
			return false;
		}
	}
	public sealed class NearestMarkers<T>
	{
		private readonly List<(T value, float distance, int identity)> entries = new List<(T, float, int)>(60);

		public int Count => entries.Count;

		public T this[int index] => entries[index].value;

		public void Clear()
		{
			entries.Clear();
		}

		public void Consider(T value, float distanceSquared, int identity, int limit)
		{
			limit = MarkerRules.ClampLimit(limit);
			if (limit == 0 || !MarkerRules.IsFinite(distanceSquared) || distanceSquared < 0f)
			{
				return;
			}
			int i;
			for (i = 0; i < entries.Count && (entries[i].distance < distanceSquared || (entries[i].distance == distanceSquared && entries[i].identity < identity)); i++)
			{
			}
			if (i < limit)
			{
				entries.Insert(i, (value, distanceSquared, identity));
				if (entries.Count > limit)
				{
					entries.RemoveAt(entries.Count - 1);
				}
			}
		}
	}
}