Decompiled source of VKTR DiamondHUD v1.1.1

DiamondHotbar.dll

Decompiled a day 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 System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
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: AssemblyVersion("0.0.0.0")]
namespace DiamondHotbar;

public enum Dir
{
	Up,
	Down,
	Left,
	Right,
	Ammo
}
public static class Categories
{
	private static string _baitAmmoType;

	private static float _baitNextTry;

	private static readonly string[] NoNames = new string[0];

	private static string _toolRaw;

	private static string _torchRaw;

	private static string _rodRaw;

	private static string _spearExRaw;

	private static string _bombRaw;

	private static string _circletRaw;

	private static string _beltRaw;

	private static string[] _toolNames = NoNames;

	private static string[] _torchNames = NoNames;

	private static string[] _rodNames = NoNames;

	private static string[] _spearExNames = NoNames;

	private static string[] _bombNames = NoNames;

	private static string[] _circletNames = NoNames;

	private static string[] _beltNames = NoNames;

	private static readonly Comparison<ItemData> ByGridPos = delegate(ItemData a, ItemData b)
	{
		int y = a.m_gridPos.y;
		int y2 = b.m_gridPos.y;
		return (y == y2) ? a.m_gridPos.x.CompareTo(b.m_gridPos.x) : y.CompareTo(y2);
	};

	public static bool IsPickaxe(ItemData it)
	{
		return it.m_shared.m_damages.m_pickaxe > 0f;
	}

	public static bool IsBomb(ItemData it)
	{
		if (MatchesNames(it, Parse(Plugin.ExtraBombNames?.Value, ref _bombRaw, ref _bombNames)))
		{
			return true;
		}
		if (IsWeapon(it) && ConsumesItself(it))
		{
			return it.m_shared.m_maxStackSize > 1;
		}
		return false;
	}

	public static bool IsProjectileWeapon(ItemData it)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Invalid comparison between Unknown and I4
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Invalid comparison between Unknown and I4
		if (!IsWeapon(it))
		{
			return false;
		}
		SkillType skillType = it.m_shared.m_skillType;
		if ((int)skillType == 8 || (int)skillType == 14)
		{
			return true;
		}
		return false;
	}

	public static bool IsOffHandWeapon(ItemData it)
	{
		return IsProjectileWeapon(it);
	}

	public static bool IsRangedSlot(ItemData it)
	{
		if (!IsOffHandWeapon(it))
		{
			return IsThrownSpear(it);
		}
		return true;
	}

	public static bool IsMainHandWeapon(ItemData it)
	{
		if (IsWeapon(it) && !IsRangedSlot(it))
		{
			return !IsBomb(it);
		}
		return false;
	}

	public static bool IsWeapon(ItemData it)
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Invalid comparison between Unknown and I4
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Invalid comparison between Unknown and I4
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		if (IsTool(it))
		{
			return false;
		}
		if (IsTorchLike(it))
		{
			return false;
		}
		ItemType itemType = it.m_shared.m_itemType;
		if (itemType - 3 <= 1 || (int)itemType == 14 || (int)itemType == 22)
		{
			return true;
		}
		return false;
	}

	public static bool IsTorchLike(ItemData it)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Invalid comparison between Unknown and I4
		if ((int)it.m_shared.m_itemType != 15)
		{
			return MatchesNames(it, Parse(Plugin.TorchNames?.Value, ref _torchRaw, ref _torchNames));
		}
		return true;
	}

	public static bool IsOneHandedAxe(ItemData it)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		if ((int)it.m_shared.m_skillType == 7)
		{
			return !it.IsTwoHanded();
		}
		return false;
	}

	public static bool IsAxeAsWeapon(ItemData it)
	{
		if (IsOneHandedAxe(it))
		{
			return InHotbar(it);
		}
		return false;
	}

	public static bool IsFishingRod(ItemData it)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Invalid comparison between Unknown and I4
		if (!MatchesNames(it, Parse(Plugin.RodNames?.Value, ref _rodRaw, ref _rodNames)))
		{
			return (int)it.m_shared.m_skillType == 104;
		}
		return true;
	}

	public static string BaitAmmoType()
	{
		if (_baitAmmoType != null)
		{
			return _baitAmmoType;
		}
		if (Time.unscaledTime < _baitNextTry)
		{
			return null;
		}
		_baitNextTry = Time.unscaledTime + 2f;
		ObjectDB instance = ObjectDB.instance;
		if ((Object)(object)instance == (Object)null)
		{
			return null;
		}
		foreach (GameObject item in instance.m_items)
		{
			ItemDrop val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null);
			ItemData val2 = (((Object)(object)val != (Object)null) ? val.m_itemData : null);
			if (val2?.m_shared != null && IsFishingRod(val2) && !string.IsNullOrEmpty(val2.m_shared.m_ammoType))
			{
				_baitAmmoType = val2.m_shared.m_ammoType;
				break;
			}
		}
		return _baitAmmoType;
	}

	public static bool IsBait(ItemData it)
	{
		string text = BaitAmmoType();
		if (!string.IsNullOrEmpty(text))
		{
			return it.m_shared.m_ammoType == text;
		}
		return false;
	}

	public static bool IsAmmoFor(ItemData it, ItemData weapon)
	{
		//IL_0029: 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_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Invalid comparison between Unknown and I4
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Invalid comparison between Unknown and I4
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Invalid comparison between Unknown and I4
		string text = weapon?.m_shared?.m_ammoType;
		if (string.IsNullOrEmpty(text))
		{
			return false;
		}
		ItemType itemType = it.m_shared.m_itemType;
		if ((int)itemType != 2 && (int)itemType != 9 && (int)itemType != 23)
		{
			return false;
		}
		return it.m_shared.m_ammoType == text;
	}

	public static bool IsTool(ItemData it)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Invalid comparison between Unknown and I4
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Invalid comparison between Unknown and I4
		if ((int)it.m_shared.m_itemType == 2)
		{
			return false;
		}
		if (IsFishingRod(it))
		{
			return true;
		}
		if (IsOneHandedAxe(it))
		{
			return !InHotbar(it);
		}
		if (MatchesExtraToolName(it))
		{
			return true;
		}
		if ((int)it.m_shared.m_itemType == 19)
		{
			return true;
		}
		if (IsPickaxe(it))
		{
			return true;
		}
		if ((int)it.m_shared.m_skillType == 105)
		{
			return true;
		}
		if ((Object)(object)it.m_shared.m_buildPieces != (Object)null)
		{
			return Plugin.BuildToolsInToolSlot.Value;
		}
		return false;
	}

	private static bool MatchesExtraToolName(ItemData it)
	{
		return MatchesNames(it, Parse(Plugin.ExtraToolNames?.Value, ref _toolRaw, ref _toolNames));
	}

	private static string[] Parse(string csv, ref string cachedRaw, ref string[] cached)
	{
		if (csv == cachedRaw)
		{
			return cached;
		}
		cachedRaw = csv;
		if (string.IsNullOrEmpty(csv))
		{
			cached = NoNames;
			return cached;
		}
		string[] array = csv.Split(',');
		List<string> list = new List<string>(array.Length);
		string[] array2 = array;
		for (int i = 0; i < array2.Length; i++)
		{
			string text = array2[i].Trim();
			if (text.Length > 0)
			{
				list.Add(text);
			}
		}
		cached = list.ToArray();
		return cached;
	}

	private static bool MatchesNames(ItemData it, string[] names)
	{
		if (names.Length == 0)
		{
			return false;
		}
		string text = (((Object)(object)it.m_dropPrefab != (Object)null) ? ((Object)it.m_dropPrefab).name : null);
		string name = it.m_shared.m_name;
		foreach (string value in names)
		{
			if (text != null && text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
			if (name != null && name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return true;
			}
		}
		return false;
	}

	public static string Describe(ItemData it)
	{
		if (IsFishingRod(it))
		{
			return "rod";
		}
		if (IsBomb(it))
		{
			return "bomb";
		}
		if (IsRangedWeapon(it))
		{
			return "ranged";
		}
		if (IsWeapon(it))
		{
			return "weapon";
		}
		if (IsTool(it))
		{
			return "tool";
		}
		if (IsAmmo(it))
		{
			return "ammo";
		}
		if (IsConsumable(it))
		{
			return "consumable";
		}
		if (IsShield(it))
		{
			return "shield";
		}
		return "-";
	}

	public static void LogOneHandedAxes(ManualLogSource log)
	{
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Invalid comparison between Unknown and I4
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Invalid comparison between Unknown and I4
		ObjectDB instance = ObjectDB.instance;
		if ((Object)(object)instance == (Object)null)
		{
			return;
		}
		StringBuilder stringBuilder = new StringBuilder("one-handed axes in ObjectDB:\n");
		StringBuilder stringBuilder2 = new StringBuilder("torch / utility candidates in ObjectDB (for TorchNames):\n");
		foreach (GameObject item in instance.m_items)
		{
			ItemDrop val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null);
			ItemData val2 = (((Object)(object)val != (Object)null) ? val.m_itemData : null);
			if (val2?.m_shared != null)
			{
				if (IsOneHandedAxe(val2))
				{
					stringBuilder.AppendLine($"  {((Object)item).name,-22} {val2.m_shared.m_name,-26} chop={val2.m_shared.m_damages.m_chop}");
				}
				if ((int)val2.m_shared.m_itemType == 15 || (int)val2.m_shared.m_itemType == 18)
				{
					stringBuilder2.AppendLine($"  {((Object)item).name,-22} {val2.m_shared.m_name,-26} type={val2.m_shared.m_itemType}");
				}
			}
		}
		log.LogInfo((object)stringBuilder.ToString());
		log.LogInfo((object)stringBuilder2.ToString());
	}

	public static void LogClassification(Player player, ManualLogSource log)
	{
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null)
		{
			return;
		}
		StringBuilder stringBuilder = new StringBuilder("item classification:\n");
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (allItem?.m_shared != null)
			{
				stringBuilder.AppendLine($"  {Describe(allItem),-7} {allItem.m_shared.m_name,-28} type={allItem.m_shared.m_itemType} " + $"skill={allItem.m_shared.m_skillType} ammoType='{allItem.m_shared.m_ammoType}' " + $"consumes={ConsumesItself(allItem)} thrownSpear={IsThrownSpear(allItem)} " + $"pickaxeDmg={allItem.m_shared.m_damages.m_pickaxe} " + $"buildPieces={(Object)(object)allItem.m_shared.m_buildPieces != (Object)null} " + "prefab=" + (((Object)(object)allItem.m_dropPrefab != (Object)null) ? ((Object)allItem.m_dropPrefab).name : "?"));
			}
		}
		log.LogInfo((object)stringBuilder.ToString());
	}

	public static bool IsSpear(ItemData it)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		return (int)it.m_shared.m_skillType == 5;
	}

	public static bool IsThrownSpear(ItemData it)
	{
		if (!IsSpear(it))
		{
			return false;
		}
		if (MatchesNames(it, Parse(Plugin.SpearExcludeNames?.Value, ref _spearExRaw, ref _spearExNames)))
		{
			return false;
		}
		return ConsumesItself(it);
	}

	public static bool ConsumesItself(ItemData it)
	{
		Attack attack = it.m_shared.m_attack;
		Attack secondaryAttack = it.m_shared.m_secondaryAttack;
		if (attack == null || !attack.m_consumeItem)
		{
			return secondaryAttack?.m_consumeItem ?? false;
		}
		return true;
	}

	public static bool SameKind(ItemData a, ItemData b)
	{
		if (a?.m_shared != null && b?.m_shared != null)
		{
			return a.m_shared.m_name == b.m_shared.m_name;
		}
		return false;
	}

	public static int CountKind(Player player, ItemData like)
	{
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null || like?.m_shared == null)
		{
			return 0;
		}
		int num = 0;
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (SameKind(allItem, like))
			{
				num += ((allItem.m_stack <= 0) ? 1 : allItem.m_stack);
			}
		}
		return num;
	}

	public static ItemData FirstSpareOf(Player player, string name)
	{
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null)
		{
			return null;
		}
		ItemData val2 = null;
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (allItem?.m_shared != null && !(allItem.m_shared.m_name != name) && !InHotbar(allItem) && (val2 == null || allItem.m_gridPos.y < val2.m_gridPos.y || (allItem.m_gridPos.y == val2.m_gridPos.y && allItem.m_gridPos.x < val2.m_gridPos.x)))
			{
				val2 = allItem;
			}
		}
		return val2;
	}

	public static bool IsAmmo(ItemData it)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Invalid comparison between Unknown and I4
		return (int)it.m_shared.m_itemType == 9;
	}

	public static bool IsConsumable(ItemData it)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		if ((int)it.m_shared.m_itemType == 2)
		{
			return !IsBomb(it);
		}
		return false;
	}

	public static bool IsShield(ItemData it)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		return (int)it.m_shared.m_itemType == 5;
	}

	public static bool InHotbar(ItemData it)
	{
		return it.m_gridPos.y == 0;
	}

	public static bool HotbarOnly(Dir dir)
	{
		if (dir != Dir.Ammo)
		{
			return dir != Dir.Down;
		}
		return false;
	}

	public static List<ItemData> Collect(Player player, Dir dir, bool hotbarOnly)
	{
		List<ItemData> list = new List<ItemData>();
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null)
		{
			return list;
		}
		ItemData val2 = ((dir == Dir.Ammo) ? ((Humanoid)player).GetCurrentWeapon() : null);
		if (val2?.m_shared == null || string.IsNullOrEmpty(val2.m_shared.m_ammoType))
		{
			val2 = null;
		}
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (allItem?.m_shared != null && (!hotbarOnly || InHotbar(allItem)) && dir switch
			{
				Dir.Up => IsMainHandWeapon(allItem), 
				Dir.Down => IsTool(allItem), 
				Dir.Left => IsRangedSlot(allItem), 
				Dir.Right => IsConsumable(allItem) || IsBomb(allItem), 
				Dir.Ammo => val2 != null && IsAmmoFor(allItem, val2), 
				_ => false, 
			})
			{
				list.Add(allItem);
			}
		}
		list.Sort(ByGridPos);
		return list;
	}

	public static bool IsRangedWeapon(ItemData it)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: 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_001a: Invalid comparison between Unknown and I4
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Invalid comparison between Unknown and I4
		if (!IsWeapon(it))
		{
			return false;
		}
		SkillType skillType = it.m_shared.m_skillType;
		if (skillType - 8 <= 2 || (int)skillType == 14)
		{
			return true;
		}
		return false;
	}

	public static bool IsCirclet(ItemData it)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		if ((int)it.m_shared.m_itemType == 6)
		{
			return MatchesNames(it, Parse(Plugin.CircletNames?.Value, ref _circletRaw, ref _circletNames));
		}
		return false;
	}

	public static bool IsMegingjord(ItemData it)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Invalid comparison between Unknown and I4
		if ((int)it.m_shared.m_itemType == 18)
		{
			return MatchesNames(it, Parse(Plugin.MegingjordNames?.Value, ref _beltRaw, ref _beltNames));
		}
		return false;
	}

	public static ItemData FindMegingjord(Player player)
	{
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null)
		{
			return null;
		}
		ItemData val2 = null;
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (allItem?.m_shared != null && IsMegingjord(allItem) && (val2 == null || allItem.m_gridPos.y < val2.m_gridPos.y || (allItem.m_gridPos.y == val2.m_gridPos.y && allItem.m_gridPos.x < val2.m_gridPos.x)))
			{
				val2 = allItem;
			}
		}
		return val2;
	}

	public static ItemData FindCirclet(Player player)
	{
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null)
		{
			return null;
		}
		ItemData val2 = null;
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (allItem?.m_shared != null && IsCirclet(allItem) && (val2 == null || allItem.m_gridPos.y < val2.m_gridPos.y || (allItem.m_gridPos.y == val2.m_gridPos.y && allItem.m_gridPos.x < val2.m_gridPos.x)))
			{
				val2 = allItem;
			}
		}
		return val2;
	}

	public static List<ItemData> CollectTorches(Player player)
	{
		List<ItemData> list = new List<ItemData>();
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null)
		{
			return list;
		}
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (allItem?.m_shared != null && IsTorchLike(allItem))
			{
				list.Add(allItem);
			}
		}
		list.Sort(ByGridPos);
		return list;
	}

	public static List<ItemData> CollectAmmoFor(Player player, ItemData weapon)
	{
		List<ItemData> list = new List<ItemData>();
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null || weapon == null)
		{
			return list;
		}
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (allItem?.m_shared != null && IsAmmoFor(allItem, weapon))
			{
				list.Add(allItem);
			}
		}
		list.Sort(ByGridPos);
		return list;
	}

	public static List<ItemData> CollectUtility(Player player)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Invalid comparison between Unknown and I4
		List<ItemData> list = new List<ItemData>();
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null)
		{
			return list;
		}
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (allItem?.m_shared != null && (int)allItem.m_shared.m_itemType == 18 && !IsTorchLike(allItem))
			{
				list.Add(allItem);
			}
		}
		list.Sort(ByGridPos);
		return list;
	}

	public static List<ItemData> CollectShields(Player player)
	{
		List<ItemData> list = new List<ItemData>();
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null)
		{
			return list;
		}
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (allItem?.m_shared != null && IsShield(allItem) && InHotbar(allItem))
			{
				list.Add(allItem);
			}
		}
		list.Sort(ByGridPos);
		return list;
	}
}
public class DiamondController
{
	public struct SlotInfo
	{
		public ItemData Item;

		public int Index;

		public int Count;
	}

	private class Hold
	{
		public string Button;

		public bool Held;

		public bool Fresh;

		public bool Fired;

		public float Since;

		public int UndoIndex;
	}

	private const string BtnUp = "JoyDPadUp";

	private const string BtnDown = "JoyDPadDown";

	private const string BtnLeft = "JoyDPadLeft";

	private const string BtnRight = "JoyDPadRight";

	private const string BtnGuard = "JoyBlock";

	private readonly Dictionary<Dir, int> _index = new Dictionary<Dir, int>
	{
		{
			Dir.Up,
			0
		},
		{
			Dir.Down,
			0
		},
		{
			Dir.Left,
			0
		},
		{
			Dir.Right,
			0
		},
		{
			Dir.Ammo,
			0
		}
	};

	private readonly ManualLogSource _log;

	private static int _gpConsumedFrame = -10;

	private static bool _invokingHolster;

	private static int _gateFrame = -1;

	private static string _gateResult;

	private string _keyRaw;

	private KeyCode _key;

	private readonly Dictionary<Dir, Hold> _holds = new Dictionary<Dir, Hold>
	{
		{
			Dir.Down,
			new Hold
			{
				Button = "JoyDPadDown"
			}
		},
		{
			Dir.Left,
			new Hold
			{
				Button = "JoyDPadLeft"
			}
		},
		{
			Dir.Right,
			new Hold
			{
				Button = "JoyDPadRight"
			}
		}
	};

	private bool _gpHeld;

	private bool _crouchWas;

	private static bool _invokingGp;

	private static string _tapButton;

	private static bool _tapConsumed;

	private static readonly Dictionary<string, int> _latched = new Dictionary<string, int>();

	private static readonly string[] Shadowed = new string[5] { "JoyUse", "JoyJump", "JoyInventory", "JoyBuildMenu", "JoySit" };

	private static readonly string[] GuardClaimables = new string[4] { "JoyButtonA", "JoyButtonB", "JoyButtonX", "JoyButtonY" };

	private static int _claimedFrame = -1;

	private static readonly string[] ProbeNames = new string[12]
	{
		"JoyButtonA", "JoyButtonB", "JoyButtonX", "JoyButtonY", "JoyLBumper", "JoyRBumper", "JoyLTrigger", "JoyRTrigger", "JoyLStick", "JoyRStick",
		"JoyBack", "JoyMenu"
	};

	private readonly Dictionary<Dir, List<ItemData>> _listCache = new Dictionary<Dir, List<ItemData>>();

	private static int _listVersion;

	private int _cachedVersion = -1;

	private Player _cachedPlayer;

	private float _rebuiltAt;

	private ItemData _watchRight;

	private ItemData _watchLeft;

	private bool _watchInventoryOpen;

	private Dir _selectDir;

	private ItemData _selectItem;

	private float _selectAt;

	private bool _selectActive;

	private ItemData _intent;

	private int _torchIndex;

	private ItemData _preTorchMainHand;

	private ItemData _preTorchShield;

	private string _prevHelmetName;

	private static readonly string[] GearSlots = new string[6] { "chest", "legs", "helmet", "utility", "shoulder", "trinket" };

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

	private int _utilityVersion = -1;

	private Player _utilityFor;

	private List<ItemData> _utility = new List<ItemData>();

	private int _utilityIndex;

	private ItemData _ammoBeforeBait;

	private ItemData _restoreAmmo;

	private float _restoreAmmoUntil;

	private ItemData _pendingEquip;

	private float _pendingEquipUntil;

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

	private int _poolVersion = -1;

	private ItemData _poolItem;

	private int _poolCount;

	private int _torchVersion = -1;

	private float _torchesAt;

	private Player _torchFor;

	private List<ItemData> _torches = new List<ItemData>();

	private Player _profileFor;

	private static readonly Dir[] EquipSlots = new Dir[3]
	{
		Dir.Up,
		Dir.Down,
		Dir.Left
	};

	private static bool HoldsArmed => Plugin.DPadHoldSeconds.Value > 0f;

	public DiamondController(ManualLogSource log)
	{
		_log = log;
	}

	public static bool SuppressGuardianPower()
	{
		if (!_invokingGp)
		{
			return Time.frameCount - _gpConsumedFrame <= 1;
		}
		return false;
	}

	public static bool SuppressAutoHolster()
	{
		if (!Plugin.SuppressVanillaAutoHolster.Value)
		{
			return false;
		}
		if (_invokingHolster)
		{
			return false;
		}
		if (!ShouldBeActive())
		{
			return false;
		}
		if (ZInput.GetButtonDown("Hide"))
		{
			return false;
		}
		return true;
	}

	public static bool ShouldBeActive()
	{
		return BlockedBy() == null;
	}

	public static string BlockedBy()
	{
		if (_gateFrame == Time.frameCount)
		{
			return _gateResult;
		}
		_gateFrame = Time.frameCount;
		_gateResult = ComputeBlockedBy();
		return _gateResult;
	}

	private static string ComputeBlockedBy()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return "no local player";
		}
		if (Plugin.RequireGamepad.Value && !ZInput.IsGamepadActive())
		{
			return "gamepad not active";
		}
		if (InventoryGui.IsVisible())
		{
			return "inventory open";
		}
		if (Menu.IsVisible())
		{
			return "menu open";
		}
		if (Minimap.IsOpen())
		{
			return "map open";
		}
		if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())
		{
			return "chat focused";
		}
		if ((Object)(object)Hud.instance != (Object)null && !Hud.instance.IsVisible())
		{
			return "hud hidden";
		}
		if (!Priv.TakeInput(localPlayer))
		{
			return "player not taking input";
		}
		if (!Plugin.ActiveInPlaceMode.Value && ((Character)localPlayer).InPlaceMode())
		{
			return "build mode";
		}
		if (Hud.IsPieceSelectionVisible())
		{
			return "piece selection open";
		}
		if (Hud.InRadial())
		{
			return "radial open";
		}
		return null;
	}

	public static bool IsBusy(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return true;
		}
		if (((Character)player).InAttack() || ((Character)player).InDodge())
		{
			return true;
		}
		if (Priv.UsingItem((Humanoid)(object)player))
		{
			return true;
		}
		return false;
	}

	public static bool IsEquipping(Player player)
	{
		if ((Object)(object)player != (Object)null)
		{
			if (player.GetActionQueueCount() <= 0)
			{
				return ((Character)player).InMinorAction();
			}
			return true;
		}
		return false;
	}

	private static bool GuardLocks(Player player, bool guard, Dir dir)
	{
		if (guard || ((Character)player).IsBlocking())
		{
			if (dir != Dir.Up)
			{
				return dir == Dir.Down;
			}
			return true;
		}
		return false;
	}

	private KeyCode ToggleKey()
	{
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		string value = Plugin.ImmersiveToggleKey.Value;
		if (value == _keyRaw)
		{
			return _key;
		}
		_keyRaw = value;
		_key = (KeyCode)((!string.IsNullOrEmpty(value) && Enum.TryParse<KeyCode>(value, ignoreCase: true, out KeyCode result)) ? ((int)result) : 0);
		if ((int)_key == 0 && !string.IsNullOrEmpty(value))
		{
			_log.LogWarning((object)("ImmersiveToggleKey '" + value + "' is not a Unity KeyCode name."));
		}
		return _key;
	}

	private void ToggleImmersiveKey(Player player)
	{
		//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_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		KeyCode val = ToggleKey();
		if ((int)val != 0 && ZInput.GetKeyDown(val, false))
		{
			bool flag = !Plugin.ImmersiveMode.Value;
			Plugin.ImmersiveMode.Value = flag;
			if (player != null)
			{
				((Character)player).Message((MessageType)1, "Immersive HUD: " + (flag ? "$hud_on" : "$hud_off"), 0, (Sprite)null, false);
			}
		}
	}

	public void Update()
	{
		TrackTapPress();
		ToggleImmersiveKey(Player.m_localPlayer);
		LoadProfile(Player.m_localPlayer);
		WatchListTriggers(Player.m_localPlayer);
		UpdateAmmoRestore(Player.m_localPlayer);
		if (!ShouldBeActive())
		{
			_pendingEquip = null;
			CancelScheduledEquip();
			{
				foreach (Hold value in _holds.Values)
				{
					value.Held = false;
				}
				return;
			}
		}
		Player localPlayer = Player.m_localPlayer;
		TrackInputEdges(localPlayer);
		UpdateScheduledEquip(localPlayer);
		UpdatePendingEquip(localPlayer);
		if (IsBusy(localPlayer))
		{
			return;
		}
		bool button = ZInput.GetButton("JoyBlock");
		ProbeButtons();
		UpdateHolds(localPlayer, button);
		if (ClassicGuardianPower(localPlayer))
		{
			return;
		}
		if (Fired(Plugin.Shield, button))
		{
			ToggleShieldHand(localPlayer);
		}
		else if (Fired(Plugin.Consume, button))
		{
			if (!ZInput.GetButtonDown("JoyBuildMenu") || !((Character)localPlayer).InPlaceMode())
			{
				ConsumeCurrent(localPlayer);
			}
		}
		else if (Fired(Plugin.Torch, button))
		{
			ToggleTorch(localPlayer);
		}
		else if (Fired(Plugin.Utility, button))
		{
			if (GearRestorePending(localPlayer))
			{
				RestoreGear(localPlayer);
			}
			else
			{
				CycleUtility(localPlayer);
			}
		}
		else if (Fired(Plugin.Holster, button))
		{
			ToggleHolster(localPlayer);
		}
		else if (Fired(Plugin.Sit, button))
		{
			ToggleSit(localPlayer);
		}
		else if (FiredTap(Plugin.Stealth, button))
		{
			ToggleCrouch(localPlayer);
		}
		else if (AmmoWindowTakesInput(localPlayer) && HeavyAttackDown())
		{
			CycleAmmo(localPlayer);
		}
		else if (ZInput.GetButtonDown("JoyDPadUp"))
		{
			if (!GuardLocks(localPlayer, button, Dir.Up))
			{
				CycleAndEquip(localPlayer, Dir.Up);
			}
		}
		else if (FreshPress(Dir.Down))
		{
			if (!GuardLocks(localPlayer, button, Dir.Down))
			{
				CycleAndEquip(localPlayer, Dir.Down);
			}
		}
		else if (FreshPress(Dir.Left))
		{
			if (HeldTorch(localPlayer) != null)
			{
				CycleTorch(localPlayer);
			}
			else
			{
				CycleAndEquip(localPlayer, Dir.Left);
			}
		}
		else if (FreshPress(Dir.Right))
		{
			Cycle(localPlayer, Dir.Right);
		}
	}

	private static bool FiredTap(Plugin.Combo combo, bool guard)
	{
		if (string.IsNullOrEmpty(combo.Button))
		{
			return false;
		}
		if (combo.Guard != guard)
		{
			return false;
		}
		if (_tapConsumed)
		{
			return false;
		}
		if (!ZInput.GetButtonUp(combo.Button))
		{
			return false;
		}
		return ZInput.GetButtonLastPressedTimer(combo.Button) < Plugin.TapSeconds.Value;
	}

	private void TrackInputEdges(Player player)
	{
		if (ZInput.GetButtonDown("JoyDPadDown"))
		{
			_gpConsumedFrame = Time.frameCount;
		}
		foreach (KeyValuePair<Dir, Hold> hold in _holds)
		{
			Hold value = hold.Value;
			bool button = ZInput.GetButton(value.Button);
			value.Fresh = button && !value.Held;
			if (value.Fresh)
			{
				value.Since = Time.unscaledTime;
				value.Fired = false;
				value.UndoIndex = (_index.TryGetValue(hold.Key, out var value2) ? value2 : 0);
			}
			value.Held = button;
		}
		if (!ZInput.GetButton("JoyLStick") || !ZInput.GetButton("JoyRStick"))
		{
			_gpHeld = false;
			_crouchWas = (Object)(object)player != (Object)null && Priv.CrouchToggled(player);
		}
	}

	private bool Spent(Dir dir)
	{
		if (_holds.TryGetValue(dir, out var value))
		{
			return value.Fired;
		}
		return false;
	}

	private bool FreshPress(Dir dir)
	{
		if (!_holds.TryGetValue(dir, out var value))
		{
			return false;
		}
		if (!HoldsArmed)
		{
			return ZInput.GetButtonDown(value.Button);
		}
		return value.Fresh;
	}

	private void UpdateHolds(Player player, bool guard)
	{
		float value = Plugin.DPadHoldSeconds.Value;
		if (value <= 0f)
		{
			return;
		}
		foreach (KeyValuePair<Dir, Hold> hold in _holds)
		{
			Hold value2 = hold.Value;
			if (!value2.Fired && value2.Held)
			{
				if (guard || ((Character)player).IsBlocking())
				{
					value2.Fired = true;
				}
				else if (!(Time.unscaledTime - value2.Since < value))
				{
					value2.Fired = true;
					FireHold(player, hold.Key, value2);
					break;
				}
			}
		}
	}

	private void FireHold(Player player, Dir dir, Hold h)
	{
		switch (dir)
		{
		case Dir.Down:
			CancelScheduledEquip();
			_index[Dir.Down] = h.UndoIndex;
			ToggleSit(player);
			break;
		case Dir.Left:
			_index[Dir.Left] = h.UndoIndex;
			ToggleTorch(player);
			break;
		case Dir.Right:
			JumpToFirstConsumable(player);
			break;
		}
	}

	private void JumpToFirstConsumable(Player player)
	{
		List<ItemData> list = ItemsFor(player, Dir.Right);
		for (int i = 0; i < list.Count; i++)
		{
			if (!Categories.IsBomb(list[i]))
			{
				_index[Dir.Right] = i;
				break;
			}
		}
	}

	public static bool SuppressCrouchNow()
	{
		if (!Plugin.SuppressVanillaCrouch.Value)
		{
			return false;
		}
		if (string.IsNullOrEmpty(Plugin.Stealth.Button))
		{
			return false;
		}
		return ShouldBeActive();
	}

	private bool ClassicGuardianPower(Player player)
	{
		if (!Plugin.ClassicGuardianPowerCombo.Value || !Plugin.OnClassicMap)
		{
			_gpHeld = false;
			return false;
		}
		if (_gpHeld)
		{
			return false;
		}
		if (!ZInput.GetButton("JoyLStick") || !ZInput.GetButton("JoyRStick"))
		{
			return false;
		}
		_gpHeld = true;
		_invokingGp = true;
		try
		{
			player.StartGuardianPower();
		}
		finally
		{
			_invokingGp = false;
		}
		if (Priv.CrouchToggled(player) != _crouchWas)
		{
			Priv.SetCrouch(player, _crouchWas);
		}
		return true;
	}

	private void ToggleSit(Player player)
	{
		if (!((Object)(object)player == (Object)null))
		{
			if (((Character)player).InEmote() && ((Character)player).IsSitting())
			{
				Priv.StopEmote(player);
			}
			else
			{
				player.StartEmote("sit", false);
			}
		}
	}

	private void ToggleCrouch(Player player)
	{
		if (!((Object)(object)player == (Object)null))
		{
			Priv.SetCrouch(player, !Priv.CrouchToggled(player));
		}
	}

	private static bool Fired(Plugin.Combo combo, bool guard)
	{
		if (string.IsNullOrEmpty(combo.Button))
		{
			return false;
		}
		if (combo.Guard != guard)
		{
			return false;
		}
		if (!Pressed(combo.Button))
		{
			return false;
		}
		if (Plugin.Stealth.Button == combo.Button)
		{
			_tapConsumed = true;
		}
		return true;
	}

	private static void TrackTapPress()
	{
		string button = Plugin.Stealth.Button;
		if (button != _tapButton)
		{
			_tapButton = button;
			_tapConsumed = false;
		}
		if (!string.IsNullOrEmpty(button) && ZInput.GetButtonDown(button))
		{
			_tapConsumed = false;
		}
	}

	private static bool Pressed(string button)
	{
		if (ZInput.GetButtonDown(button))
		{
			return true;
		}
		if (_latched.TryGetValue(button, out var value))
		{
			return value == Time.frameCount;
		}
		return false;
	}

	private static bool GuardCombo(string button)
	{
		if (!Owns(Plugin.Shield, button) && !Owns(Plugin.Consume, button) && !Owns(Plugin.Torch, button) && !Owns(Plugin.Holster, button) && !Owns(Plugin.Sit, button) && !Owns(Plugin.Stealth, button))
		{
			return Owns(Plugin.Utility, button);
		}
		return true;
	}

	private static bool Owns(Plugin.Combo combo, string button)
	{
		if (combo.Guard)
		{
			return combo.Button == button;
		}
		return false;
	}

	public static void ClaimGuardButton(string button)
	{
		if (!Plugin.GuardOwnsMacroButtons.Value || !GuardCombo(button) || !ShouldBeActive() || !ZInput.GetButton("JoyBlock") || !ZInput.GetButtonDown(button))
		{
			return;
		}
		_latched[button] = Time.frameCount;
		ZInput.ResetButtonStatus(button);
		string[] shadowed = Shadowed;
		foreach (string text in shadowed)
		{
			if (ZInput.GetButtonDown(text))
			{
				ZInput.ResetButtonStatus(text);
			}
		}
	}

	public static void ClaimVanillaSit()
	{
		if (Plugin.SuppressVanillaSit != null && Plugin.SuppressVanillaSit.Value && ShouldBeActive() && (ZInput.GetButtonUp("JoySit") || ZInput.GetButtonDown("JoySit")))
		{
			ZInput.ResetButtonStatus("JoySit");
		}
	}

	public static void ClaimGuardButtons()
	{
		if (_claimedFrame != Time.frameCount)
		{
			_claimedFrame = Time.frameCount;
			string[] guardClaimables = GuardClaimables;
			for (int i = 0; i < guardClaimables.Length; i++)
			{
				ClaimGuardButton(guardClaimables[i]);
			}
		}
	}

	private void ProbeButtons()
	{
		if (!Plugin.DebugButtons.Value)
		{
			return;
		}
		string[] probeNames = ProbeNames;
		foreach (string text in probeNames)
		{
			if (ZInput.GetButtonDown(text))
			{
				_log.LogInfo((object)string.Format("[button] {0} pressed (guard={1})", text, ZInput.GetButton("JoyBlock")));
			}
		}
	}

	private void EquipVanilla(Player player, ItemData item)
	{
		Priv.ToggleEquipped(player, item);
		InvalidateLists();
	}

	private void ConsumeVanilla(Player player, ItemData item)
	{
		((Humanoid)player).UseItem((Inventory)null, item, false);
		InvalidateLists();
	}

	public static void Invalidate()
	{
		_listVersion++;
	}

	private List<ItemData> ItemsFor(Player player, Dir dir)
	{
		float value = Plugin.ListRefreshSeconds.Value;
		bool flag = value > 0f && Time.unscaledTime - _rebuiltAt > value;
		if (_cachedVersion != _listVersion || (Object)(object)_cachedPlayer != (Object)(object)player || flag)
		{
			_cachedVersion = _listVersion;
			_cachedPlayer = player;
			_rebuiltAt = Time.unscaledTime;
			_listCache.Clear();
		}
		if (!_listCache.TryGetValue(dir, out var value2))
		{
			value2 = Categories.Collect(player, dir, Categories.HotbarOnly(dir));
			_listCache[dir] = value2;
		}
		return value2;
	}

	private void InvalidateLists()
	{
		Invalidate();
	}

	private void WatchListTriggers(Player player)
	{
		bool flag = InventoryGui.IsVisible();
		if (_watchInventoryOpen && !flag)
		{
			Invalidate();
		}
		_watchInventoryOpen = flag;
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		ItemData val = Priv.RightItem((Humanoid)(object)player);
		ItemData val2 = Priv.LeftItem((Humanoid)(object)player);
		if (val != _watchRight || val2 != _watchLeft)
		{
			bool num = _watchRight != null && Categories.IsFishingRod(_watchRight);
			bool flag2 = val != null && Categories.IsFishingRod(val);
			_watchRight = val;
			_watchLeft = val2;
			Invalidate();
			if (num && !flag2 && Plugin.RestoreAmmoAfterFishing.Value && !Priv.ItemsHolstered((Humanoid)(object)player))
			{
				RestoreAmmoAfterFishing(player);
			}
			SyncToEquipped(player);
		}
	}

	private ItemData Cycle(Player player, Dir dir)
	{
		List<ItemData> list = ItemsFor(player, dir);
		if (list.Count == 0)
		{
			return null;
		}
		int num = (_index.TryGetValue(dir, out var value) ? value : 0);
		num = (num + 1) % list.Count;
		_index[dir] = num;
		return list[num];
	}

	private void CycleAndEquip(Player player, Dir dir)
	{
		ItemData item = Info(player, dir).Item;
		if (item == null)
		{
			return;
		}
		if (Priv.IsStashed((Humanoid)(object)player, item) || (Priv.ItemsHolstered((Humanoid)(object)player) && item.m_equipped))
		{
			Priv.ShowHandItems((Humanoid)(object)player, onlyRightHand: false, animation: true);
			InvalidateLists();
			return;
		}
		bool flag = _selectActive && _selectDir == dir;
		if (item.m_equipped || flag)
		{
			ItemData val = Cycle(player, dir);
			if (val != null)
			{
				ScheduleEquip(player, dir, val);
			}
		}
		else
		{
			ScheduleEquip(player, dir, item);
		}
	}

	private void CancelScheduledEquip()
	{
		_selectActive = false;
		_selectItem = null;
	}

	private static bool EquipsInstantly(ItemData it)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: 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_000e: Invalid comparison between Unknown and I4
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Invalid comparison between Unknown and I4
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Invalid comparison between Unknown and I4
		ItemType itemType = it.m_shared.m_itemType;
		if ((int)itemType == 2)
		{
			return true;
		}
		if ((int)itemType == 9 || (int)itemType == 23)
		{
			return it.m_shared.m_equipDuration <= 0f;
		}
		return false;
	}

	private void ScheduleEquip(Player player, Dir dir, ItemData item)
	{
		if (item != null)
		{
			if ((!HoldsArmed || !_holds.ContainsKey(dir)) && (EquipsInstantly(item) || Plugin.EquipDelay.Value <= 0f))
			{
				_selectActive = false;
				_selectItem = null;
				ApplySelection(player, dir, item);
			}
			else
			{
				_selectDir = dir;
				_selectItem = item;
				_selectAt = Time.time + Plugin.EquipDelay.Value;
				_selectActive = true;
			}
		}
	}

	private void UpdateScheduledEquip(Player player)
	{
		if (!_selectActive)
		{
			return;
		}
		if ((Object)(object)player == (Object)null)
		{
			_selectActive = false;
			_selectItem = null;
		}
		else
		{
			if (Time.time < _selectAt || IsBusy(player) || (HoldsArmed && !Spent(_selectDir) && _holds.TryGetValue(_selectDir, out var value) && ZInput.GetButton(value.Button)))
			{
				return;
			}
			ItemData selectItem = _selectItem;
			Dir selectDir = _selectDir;
			_selectActive = false;
			_selectItem = null;
			if (selectItem != null && !selectItem.m_equipped)
			{
				Inventory inventory = ((Humanoid)player).GetInventory();
				if (inventory != null && inventory.ContainsItem(selectItem))
				{
					ApplySelection(player, selectDir, selectItem);
				}
			}
		}
	}

	private void ApplySelection(Player player, Dir dir, ItemData item)
	{
		if (dir == Dir.Ammo)
		{
			RememberDisplacedAmmo(((Humanoid)player).GetAmmoItem(), item);
			if (item.m_shared.m_equipDuration > 0f)
			{
				EquipBaitVanilla(player, item);
				return;
			}
			((Humanoid)player).EquipItem(item, true);
			InvalidateLists();
		}
		else
		{
			EquipVanilla(player, item);
			_intent = item;
			RequestAutoShield(player, item);
			RequestAutoBait(player, item);
			LearnPairing(player, item);
		}
	}

	private void LearnPairing(Player player, ItemData item)
	{
		if (!Plugin.AutoShield.Value || item?.m_shared == null)
		{
			return;
		}
		ItemData val = null;
		ItemData val2 = null;
		if (Categories.IsShield(item))
		{
			val2 = item;
			val = Priv.RightItem((Humanoid)(object)player);
		}
		else if (Categories.IsWeapon(item) && !Categories.IsTorchLike(item) && !Categories.IsOffHandWeapon(item) && !Categories.IsBomb(item) && AllowsShield(item))
		{
			val = item;
			val2 = EquippedShield(player);
		}
		if (val != null && val2 != null && Categories.IsWeapon(val) && !Categories.IsTorchLike(val) && AllowsShield(val) && HeldTorch(player) == null)
		{
			string text = Key(val);
			string text2 = Key(val2);
			if (text != null && text2 != null && (!_combos.TryGetValue(text, out var value) || !(value == text2)))
			{
				_combos[text] = text2;
				SaveProfile(player);
			}
		}
	}

	private static bool AllowsShield(ItemData right)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: 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)
		//IL_001f: Invalid comparison between Unknown and I4
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Invalid comparison between Unknown and I4
		if (right == null)
		{
			return true;
		}
		if (right.IsTwoHanded())
		{
			return false;
		}
		SkillType skillType = right.m_shared.m_skillType;
		if (skillType - 8 <= 2 || (int)skillType == 14)
		{
			return false;
		}
		Attack attack = right.m_shared.m_attack;
		if (attack != null && (attack.m_attackEitr > 0f || attack.m_drawEitrDrain > 0f))
		{
			return false;
		}
		return true;
	}

	public static ItemData HeldTorch(Player player)
	{
		ItemData val = Priv.LeftItem((Humanoid)(object)player);
		if (val != null && Categories.IsTorchLike(val))
		{
			return val;
		}
		ItemData val2 = Priv.RightItem((Humanoid)(object)player);
		if (val2 != null && Categories.IsTorchLike(val2))
		{
			return val2;
		}
		ItemData val3 = Priv.UtilityItem((Humanoid)(object)player);
		if (val3 == null || !Categories.IsTorchLike(val3))
		{
			return null;
		}
		return val3;
	}

	private void ToggleTorch(Player player)
	{
		CancelScheduledEquip();
		ItemData val = HeldTorch(player);
		if (val != null)
		{
			EquipVanilla(player, val);
			if (_preTorchShield != null && !_preTorchShield.m_equipped)
			{
				Priv.QueueEquipAction(player, _preTorchShield);
			}
			else if (_preTorchMainHand != null && !_preTorchMainHand.m_equipped)
			{
				RequestPendingEquip(_preTorchMainHand);
			}
			_preTorchShield = null;
			_preTorchMainHand = null;
			InvalidateLists();
		}
		else
		{
			if (ToggleCirclet(player))
			{
				return;
			}
			List<ItemData> list = Torches(player);
			if (list.Count == 0)
			{
				return;
			}
			if (_torchIndex >= list.Count)
			{
				_torchIndex = 0;
			}
			ItemData item = list[_torchIndex];
			ItemData val2 = Priv.RightItem((Humanoid)(object)player);
			ItemData val3 = Priv.LeftItem((Humanoid)(object)player);
			_preTorchMainHand = val2;
			_preTorchShield = null;
			ItemData val4 = val2 ?? ((val3 != null && Categories.IsWeapon(val3)) ? val3 : null);
			if (!PairableWeapon(val4))
			{
				ItemData val5 = FirstHotbarOneHanded(player);
				if (val5 != null && !val5.m_equipped)
				{
					Priv.QueueEquipAction(player, val5);
					_preTorchMainHand = val4;
				}
			}
			else
			{
				ItemData val6 = EquippedShield(player);
				if (val6 != null)
				{
					Priv.QueueUnequipAction(player, val6);
					_preTorchShield = val6;
				}
			}
			Priv.QueueEquipAction(player, item);
			InvalidateLists();
		}
	}

	private bool ToggleCirclet(Player player)
	{
		if (((player != null) ? ((Humanoid)player).GetInventory() : null) == null)
		{
			return false;
		}
		ItemData val = Priv.HelmetItem((Humanoid)(object)player);
		if (val != null && Categories.IsCirclet(val))
		{
			EquipVanilla(player, val);
			ItemData val2 = FindByName(player, _prevHelmetName);
			_prevHelmetName = null;
			SaveProfile(player);
			if (val2 != null && !val2.m_equipped)
			{
				RequestPendingEquip(val2);
			}
			InvalidateLists();
			return true;
		}
		ItemData val3 = Categories.FindCirclet(player);
		if (val3 == null)
		{
			return false;
		}
		_prevHelmetName = Key(val);
		SaveProfile(player);
		EquipVanilla(player, val3);
		InvalidateLists();
		return true;
	}

	private void CycleTorch(Player player)
	{
		List<ItemData> list = Torches(player);
		if (list.Count < 2)
		{
			return;
		}
		ItemData val = HeldTorch(player);
		if (val != null)
		{
			int num = list.IndexOf(val);
			_torchIndex = (num + 1) % list.Count;
			ItemData val2 = list[_torchIndex];
			if (val2 != val)
			{
				ScheduleEquip(player, Dir.Left, val2);
			}
		}
	}

	private static ItemData Worn(Player player, string slot)
	{
		return (ItemData)(slot switch
		{
			"chest" => Priv.ChestItem((Humanoid)(object)player), 
			"legs" => Priv.LegItem((Humanoid)(object)player), 
			"helmet" => Priv.HelmetItem((Humanoid)(object)player), 
			"utility" => Priv.UtilityItem((Humanoid)(object)player), 
			"shoulder" => Priv.ShoulderItem((Humanoid)(object)player), 
			"trinket" => Priv.TrinketItem((Humanoid)(object)player), 
			_ => null, 
		});
	}

	public void RecordDeathGear(Player player)
	{
		if (!Plugin.RestoreGearAfterDeath.Value || (Object)(object)player == (Object)null)
		{
			return;
		}
		try
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			string[] gearSlots = GearSlots;
			foreach (string text in gearSlots)
			{
				string text2 = Key(Worn(player, text));
				if (text2 != null)
				{
					dictionary[text] = text2;
				}
			}
			if (dictionary.Count == 0)
			{
				return;
			}
			_deathGear.Clear();
			foreach (KeyValuePair<string, string> item in dictionary)
			{
				_deathGear[item.Key] = item.Value;
			}
			SaveProfile(player);
		}
		catch (Exception ex)
		{
			_log.LogWarning((object)("Could not record the death loadout: " + ex.Message));
		}
	}

	private bool GearRestorePending(Player player)
	{
		if (!Plugin.RestoreGearAfterDeath.Value || _deathGear.Count == 0)
		{
			return false;
		}
		string[] gearSlots = GearSlots;
		foreach (string text in gearSlots)
		{
			if (_deathGear.ContainsKey(text) && Worn(player, text) == null)
			{
				return true;
			}
		}
		_deathGear.Clear();
		SaveProfile(player);
		return false;
	}

	private void RestoreGear(Player player)
	{
		CancelScheduledEquip();
		if (Plugin.AutoMegingjord.Value && ((Character)player).IsEncumbered())
		{
			ItemData val = Categories.FindMegingjord(player);
			if (val != null && !val.m_equipped)
			{
				Priv.QueueEquipAction(player, val);
			}
		}
		string[] gearSlots = GearSlots;
		foreach (string text in gearSlots)
		{
			if (_deathGear.TryGetValue(text, out var value) && Worn(player, text) == null)
			{
				ItemData val2 = FindByName(player, value);
				if (val2 != null && !val2.m_equipped && !player.IsEquipActionQueued(val2))
				{
					Priv.QueueEquipAction(player, val2);
				}
			}
		}
		InvalidateLists();
	}

	private List<ItemData> Utility(Player player)
	{
		if (_utilityVersion == _listVersion && (Object)(object)_utilityFor == (Object)(object)player)
		{
			return _utility;
		}
		_utilityVersion = _listVersion;
		_utilityFor = player;
		_utility = Categories.CollectUtility(player);
		return _utility;
	}

	private void CycleUtility(Player player)
	{
		List<ItemData> list = Utility(player);
		if (list.Count != 0)
		{
			ItemData val = Priv.UtilityItem((Humanoid)(object)player);
			int num = ((val != null) ? list.IndexOf(val) : (-1));
			_utilityIndex = ((num >= 0) ? ((num + 1) % list.Count) : (_utilityIndex % list.Count));
			ItemData item = list[_utilityIndex];
			EquipVanilla(player, item);
		}
	}

	private void ToggleHolster(Player player)
	{
		CancelScheduledEquip();
		if (Priv.ItemsHolstered((Humanoid)(object)player))
		{
			Priv.ShowHandItems((Humanoid)(object)player, onlyRightHand: false, animation: true);
			InvalidateLists();
		}
		else if (Priv.RightItem((Humanoid)(object)player) != null || Priv.LeftItem((Humanoid)(object)player) != null)
		{
			_invokingHolster = true;
			try
			{
				((Humanoid)player).HideHandItems(false, true);
			}
			finally
			{
				_invokingHolster = false;
			}
			InvalidateLists();
		}
	}

	public static bool FifthWindowShows(Player player)
	{
		if (AmmoWeapon(player) == null)
		{
			return EquippedShield(player) != null;
		}
		return true;
	}

	public static ItemData AmmoWeapon(Player player)
	{
		ItemData val = (((Object)(object)player != (Object)null) ? ((Humanoid)player).GetCurrentWeapon() : null);
		if (val?.m_shared == null)
		{
			return null;
		}
		if (!string.IsNullOrEmpty(val.m_shared.m_ammoType))
		{
			return val;
		}
		return null;
	}

	private static bool AmmoWindowTakesInput(Player player)
	{
		ItemData val = AmmoWeapon(player);
		if (val != null)
		{
			return !val.HaveSecondaryAttack();
		}
		return false;
	}

	private static bool HeavyAttackDown()
	{
		if (!ZInput.GetButtonDown("JoySecondaryAttack"))
		{
			return ZInput.GetButtonDown("SecondaryAttack");
		}
		return true;
	}

	private void CycleAmmo(Player player)
	{
		if (ItemsFor(player, Dir.Ammo).Count != 0)
		{
			ItemData ammoItem = ((Humanoid)player).GetAmmoItem();
			ItemData item = Info(player, Dir.Ammo).Item;
			bool flag = _selectActive && _selectDir == Dir.Ammo;
			ItemData val = ((flag || (ammoItem != null && ammoItem == item)) ? Cycle(player, Dir.Ammo) : item);
			if (val != null && (flag || val != ammoItem))
			{
				ScheduleEquip(player, Dir.Ammo, val);
			}
		}
	}

	private void RememberDisplacedAmmo(ItemData loaded, ItemData incoming)
	{
		if (loaded != null && !Categories.IsBait(loaded) && incoming != null && Categories.IsBait(incoming))
		{
			_ammoBeforeBait = loaded;
		}
	}

	private void RestoreAmmoAfterFishing(Player player)
	{
		ItemData ammoBeforeBait = _ammoBeforeBait;
		_ammoBeforeBait = null;
		if (ammoBeforeBait != null && !((Object)(object)player == (Object)null) && ((Humanoid)player).GetAmmoItem() != ammoBeforeBait)
		{
			_restoreAmmo = ammoBeforeBait;
			_restoreAmmoUntil = Time.time + 3f;
		}
	}

	private void UpdateAmmoRestore(Player player)
	{
		if (_restoreAmmo == null)
		{
			return;
		}
		if ((Object)(object)player == (Object)null || Time.time > _restoreAmmoUntil || ((Humanoid)player).GetAmmoItem() == _restoreAmmo)
		{
			_restoreAmmo = null;
			return;
		}
		Inventory inventory = ((Humanoid)player).GetInventory();
		if (inventory == null || !inventory.ContainsItem(_restoreAmmo))
		{
			_restoreAmmo = null;
		}
		else if (!IsBusy(player) && !IsEquipping(player))
		{
			((Humanoid)player).EquipItem(_restoreAmmo, false);
			_restoreAmmo = null;
			InvalidateLists();
		}
	}

	private void EquipBaitVanilla(Player player, ItemData bait)
	{
		Priv.QueueEquipAction(player, bait);
		InvalidateLists();
	}

	private void ToggleShieldHand(Player player)
	{
		CancelScheduledEquip();
		ItemData val = EquippedShield(player);
		if (val != null)
		{
			string text = Key(Priv.RightItem((Humanoid)(object)player));
			if (text != null && _combos.Remove(text))
			{
				SaveProfile(player);
			}
			EquipVanilla(player, val);
			return;
		}
		if (FirstHotbarShield(player) == null)
		{
			ItemData val2 = FirstHotbarWeapon(player);
			if (val2 != null && !val2.m_equipped)
			{
				EquipVanilla(player, val2);
				SyncSlot(player, Dir.Up, val2);
			}
			return;
		}
		ItemData val3 = PairableOrNull(Priv.RightItem((Humanoid)(object)player)) ?? (Plugin.AutoShieldWeapon.Value ? PairableOrNull(Info(player, Dir.Up).Item) : null) ?? FirstHotbarOneHanded(player);
		if (val3 != null)
		{
			if (!val3.m_equipped)
			{
				EquipVanilla(player, val3);
				SyncSlot(player, Dir.Up, val3);
			}
			string value;
			ItemData val4 = (_combos.TryGetValue(Key(val3), out value) ? FindByName(player, value) : FirstHotbarShield(player));
			if (val4 != null && !val4.m_equipped)
			{
				RequestPendingEquip(val4);
			}
		}
	}

	private static ItemData PairableOrNull(ItemData it)
	{
		if (!PairableWeapon(it))
		{
			return null;
		}
		return it;
	}

	private static bool PairableWeapon(ItemData it)
	{
		if (it?.m_shared != null && Categories.IsWeapon(it) && !Categories.IsTorchLike(it) && !Categories.IsBomb(it) && !Categories.IsOffHandWeapon(it))
		{
			return AllowsShield(it);
		}
		return false;
	}

	private static ItemData FirstHotbarWeapon(Player player)
	{
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null)
		{
			return null;
		}
		ItemData val2 = null;
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (allItem?.m_shared != null && Categories.InHotbar(allItem) && Categories.IsWeapon(allItem) && !Categories.IsBomb(allItem) && (val2 == null || allItem.m_gridPos.x < val2.m_gridPos.x))
			{
				val2 = allItem;
			}
		}
		return val2;
	}

	private static ItemData FirstHotbarOneHanded(Player player)
	{
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val == null)
		{
			return null;
		}
		ItemData val2 = null;
		foreach (ItemData allItem in val.GetAllItems())
		{
			if (PairableWeapon(allItem) && Categories.InHotbar(allItem) && (val2 == null || allItem.m_gridPos.x < val2.m_gridPos.x))
			{
				val2 = allItem;
			}
		}
		return val2;
	}

	private void SyncSlot(Player player, Dir dir, ItemData item)
	{
		InvalidateLists();
		int num = ItemsFor(player, dir).IndexOf(item);
		if (num >= 0)
		{
			_index[dir] = num;
		}
	}

	public static ItemData EquippedShield(Player player)
	{
		ItemData val = Priv.LeftItem((Humanoid)(object)player);
		if (val == null || !Categories.IsShield(val))
		{
			return null;
		}
		return val;
	}

	private static ItemData FirstHotbarShield(Player player)
	{
		List<ItemData> list = Categories.CollectShields(player);
		if (list.Count <= 0)
		{
			return null;
		}
		return list[0];
	}

	private static string Key(ItemData it)
	{
		return it?.m_shared?.m_name;
	}

	private ItemData FindByName(Player player, string name)
	{
		if (string.IsNullOrEmpty(name))
		{
			return null;
		}
		Inventory inventory = ((Humanoid)player).GetInventory();
		if (inventory == null)
		{
			return null;
		}
		foreach (ItemData allItem in inventory.GetAllItems())
		{
			if (allItem?.m_shared != null && allItem.m_shared.m_name == name)
			{
				return allItem;
			}
		}
		return null;
	}

	private void RequestAutoShield(Player player, ItemData weapon)
	{
		if (Plugin.AutoShield.Value && weapon != null && Categories.IsWeapon(weapon) && AllowsShield(weapon) && !Categories.IsOffHandWeapon(weapon) && !Categories.IsBomb(weapon) && HeldTorch(player) == null && _combos.TryGetValue(Key(weapon), out var value))
		{
			ItemData val = FindByName(player, value);
			if (val != null && !val.m_equipped)
			{
				EquipVanilla(player, val);
				RequestPendingEquip(val);
			}
		}
	}

	private void RequestAutoBait(Player player, ItemData item)
	{
		if (item == null || !Categories.IsFishingRod(item))
		{
			return;
		}
		ItemData ammoItem = ((Humanoid)player).GetAmmoItem();
		if (ammoItem == null || !Categories.IsAmmoFor(ammoItem, item))
		{
			List<ItemData> list = Categories.CollectAmmoFor(player, item);
			if (list.Count != 0)
			{
				RememberDisplacedAmmo(ammoItem, list[0]);
				Priv.QueueEquipAction(player, list[0]);
				_index[Dir.Ammo] = 0;
				InvalidateLists();
			}
		}
	}

	private List<ItemData> Torches(Player player)
	{
		float value = Plugin.ListRefreshSeconds.Value;
		if ((!(value > 0f) || !(Time.unscaledTime - _torchesAt > value)) && _torchVersion == _listVersion && (Object)(object)_torchFor == (Object)(object)player)
		{
			return _torches;
		}
		_torchVersion = _listVersion;
		_torchesAt = Time.unscaledTime;
		_torchFor = player;
		_torches = Categories.CollectTorches(player);
		return _torches;
	}

	public int SpearPool(Player player, ItemData item)
	{
		if (item == null || !Categories.IsThrownSpear(item))
		{
			return 0;
		}
		if (_poolVersion == _listVersion && _poolItem == item)
		{
			return _poolCount;
		}
		_poolVersion = _listVersion;
		_poolItem = item;
		_poolCount = Categories.CountKind(player, item);
		return _poolCount;
	}

	public void RestockSpear(Player player, Vector2i pos, string name)
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		if (!Plugin.SpearRestock.Value)
		{
			return;
		}
		Inventory val = ((player != null) ? ((Humanoid)player).GetInventory() : null);
		if (val != null && val.GetItemAt(pos.x, pos.y) == null)
		{
			ItemData val2 = Categories.FirstSpareOf(player, name);
			if (val2 != null && val.MoveItemToThis(val, val2, val2.m_stack, pos.x, pos.y))
			{
				Invalidate();
				RequestPendingEquip(val2);
			}
		}
	}

	private void SaveProfile(Player player)
	{
		Profile.Save(player, _combos, _prevHelmetName, _deathGear);
	}

	private void LoadProfile(Player player)
	{
		if (!((Object)(object)player == (Object)null) && !((Object)(object)player == (Object)(object)_profileFor) && player.GetPlayerID() != 0L)
		{
			_profileFor = player;
			Profile.Load(player, _combos, out _prevHelmetName, _deathGear);
			SyncToEquipped(player);
		}
	}

	private void SyncToEquipped(Player player)
	{
		if ((Object)(object)player == (Object)null || _selectActive)
		{
			return;
		}
		if (_intent != null)
		{
			if (!_intent.m_equipped && player.IsEquipActionQueued(_intent))
			{
				return;
			}
			_intent = null;
		}
		ItemData val = Priv.RightItem((Humanoid)(object)player);
		ItemData val2 = Priv.LeftItem((Humanoid)(object)player);
		Dir[] equipSlots = EquipSlots;
		foreach (Dir dir in equipSlots)
		{
			List<ItemData> list = ItemsFor(player, dir);
			for (int j = 0; j < list.Count; j++)
			{
				ItemData val3 = list[j];
				if (val3 == val || val3 == val2)
				{
					_index[dir] = j;
					break;
				}
			}
		}
	}

	private void RequestPendingEquip(ItemData item)
	{
		_pendingEquip = item;
		_pendingEquipUntil = Time.time + 3f;
	}

	private void UpdatePendingEquip(Player player)
	{
		if (_pendingEquip != null)
		{
			if (_pendingEquip.m_equipped || Time.time > _pendingEquipUntil)
			{
				_pendingEquip = null;
			}
			else if (!player.IsEquipActionQueued(_pendingEquip) && !IsBusy(player))
			{
				EquipVanilla(player, _pendingEquip);
				_pendingEquip = null;
			}
		}
	}

	private void ConsumeCurrent(Player player)
	{
		ItemData item = Info(player, Dir.Right).Item;
		if (item == null)
		{
			return;
		}
		if (Categories.IsBomb(item))
		{
			CancelScheduledEquip();
			if (!item.m_equipped)
			{
				EquipVanilla(player, item);
			}
		}
		else
		{
			ConsumeVanilla(player, item);
		}
	}

	public SlotInfo Info(Player player, Dir dir)
	{
		List<ItemData> list = ItemsFor(player, dir);
		if (list.Count == 0)
		{
			return default(SlotInfo);
		}
		int value;
		int num = (_index.TryGetValue(dir, out value) ? value : 0);
		if (num >= list.Count)
		{
			num = 0;
			_index[dir] = 0;
		}
		return new SlotInfo
		{
			Item = list[num],
			Index = num,
			Count = list.Count
		};
	}

	public SlotInfo Display(Player player, Dir dir)
	{
		if ((Object)(object)player == (Object)null)
		{
			return Info(player, dir);
		}
		switch (dir)
		{
		case Dir.Ammo:
		{
			if (AmmoWeapon(player) == null)
			{
				ItemData val3 = EquippedShield(player);
				if (val3 != null)
				{
					return new SlotInfo
					{
						Item = val3,
						Index = 0,
						Count = 1
					};
				}
				return default(SlotInfo);
			}
			ItemData ammoItem = ((Humanoid)player).GetAmmoItem();
			List<ItemData> list3 = ItemsFor(player, Dir.Ammo);
			int num3 = ((ammoItem != null) ? list3.IndexOf(ammoItem) : (-1));
			if (num3 < 0)
			{
				return Info(player, Dir.Ammo);
			}
			return new SlotInfo
			{
				Item = ammoItem,
				Index = num3,
				Count = list3.Count
			};
		}
		default:
			return Info(player, dir);
		case Dir.Left:
		{
			ItemData val = HeldTorch(player);
			if (val != null)
			{
				List<ItemData> list = Torches(player);
				int num = list.IndexOf(val);
				return new SlotInfo
				{
					Item = val,
					Index = ((num >= 0) ? num : 0),
					Count = list.Count
				};
			}
			List<ItemData> list2 = ItemsFor(player, Dir.Left);
			ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon();
			ItemData val2 = ((currentWeapon != null && Categories.IsRangedSlot(currentWeapon)) ? currentWeapon : null);
			if (val2 == null)
			{
				return Info(player, Dir.Left);
			}
			int num2 = list2.IndexOf(val2);
			return new SlotInfo
			{
				Item = val2,
				Index = ((num2 >= 0) ? num2 : 0),
				Count = list2.Count
			};
		}
		}
	}

	public static bool IsHeldOrStashed(Player player, ItemData item)
	{
		if (item != null)
		{
			if (!item.m_equipped)
			{
				return Priv.IsStashed((Humanoid)(object)player, item);
			}
			return true;
		}
		return false;
	}
}
public class DiamondHud : MonoBehaviour
{
	private class Slot
	{
		public RectTransform Root;

		public Image Icon;

		public TMP_Text Amount;

		public GuiBar Durability;

		public TMP_Text Binding;

		public GameObject Equipped;

		public GameObject Queued;

		public GameObject Selection;

		public ItemData Shown;

		public CanvasGroup Group;

		public float EmptySince;

		public TMP_Text Pool;

		public TMP_Text Quality;

		public int ShownStack = -1;

		public int ShownPool = -1;

		public int ShownQuality = -1;

		public Image Bkg;

		public Color BkgColor;

		public Image Highlight;

		public Color HighlightColor;
	}

	public static DiamondHud Instance;

	private readonly Dictionary<Dir, Slot> _slots = new Dictionary<Dir, Slot>();

	private DiamondController _controller;

	private CanvasGroup _group;

	private static bool _loggedHierarchy;

	private Biome _paintedBiome = (Biome)(-1);

	private int _paintedConfig = -1;

	private Slot _torch;

	private GameObject _torchPrefab;

	private Image _torchBkg;

	private int _torchLayout = -1;

	private int _torchColors = -1;

	private Color _torchBkgColor;

	private Color _torchBarColor;

	private RectTransform _gp;

	private Transform _gpParent;

	private int _gpIndex;

	private Vector2 _gpAnchorMin;

	private Vector2 _gpAnchorMax;

	private Vector2 _gpPivot;

	private Vector2 _gpPos;

	private Vector2 _gpSize;

	private Vector3 _gpScale;

	private bool _gpAdopted;

	private Slot _belt;

	private int _beltColors = -1;

	private Color _beltBkgColor;

	private RectTransform _status;

	private Transform _statusParent;

	private int _statusIndex;

	private int _statusLayout = -1;

	private Vector2 _statusAnchorMin;

	private Vector2 _statusAnchorMax;

	private Vector2 _statusPivot;

	private Vector2 _statusPos;

	private Vector3 _statusScale;

	private bool _statusAdopted;

	private static int _warnedFor = -1;

	private int _layout = -1;

	private bool _qualityDressed;

	private float _nextDressTry;

	private TMP_Text _hint;

	private string _hintText;

	private string _hintFor;

	private TMP_Text _hintHeavy;

	private string _heavyText;

	private int _hintScale = -1;

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

	private static float _glyphsUntil;

	private float _nextReport;

	private string _sig = string.Empty;

	private float _lastChange = -999f;

	private static readonly StringBuilder SigBuilder = new StringBuilder(64);

	public static void Ensure(DiamondController controller)
	{
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Instance != (Object)null)
		{
			return;
		}
		Hud instance = Hud.instance;
		if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.m_rootObject == (Object)null))
		{
			HotkeyBar componentInChildren = ((Component)instance).GetComponentInChildren<HotkeyBar>(true);
			if (!((Object)(object)componentInChildren == (Object)null) && !((Object)(object)componentInChildren.m_elementPrefab == (Object)null))
			{
				GameObject val = new GameObject("DiamondHotbar", new Type[2]
				{
					typeof(RectTransform),
					typeof(CanvasGroup)
				});
				val.transform.SetParent(instance.m_rootObject.transform, false);
				Instance = val.AddComponent<DiamondHud>();
				Instance._controller = controller;
				Instance.Build(componentInChildren.m_elementPrefab);
			}
		}
	}

	public static void Destroy_()
	{
		if (!((Object)(object)Instance == (Object)null))
		{
			Instance.ReleaseGuardianPower();
			Instance.ReleaseStatusList();
			if ((Object)(object)Instance._torch?.Root != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)Instance._torch.Root).gameObject);
			}
			Object.Destroy((Object)(object)((Component)Instance).gameObject);
			Instance = null;
		}
	}

	private static Color BiomeColor(Biome biome)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Invalid comparison between Unknown and I4
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Invalid comparison between Unknown and I4
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected I4, but got Unknown
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Invalid comparison between Unknown and I4
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Invalid comparison between Unknown and I4
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Invalid comparison between Unknown and I4
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Invalid comparison between Unknown and I4
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Invalid comparison between Unknown and I4
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Invalid comparison between Unknown and I4
		string hex;
		if ((int)biome <= 16)
		{
			switch (biome - 1)
			{
			case 0:
				goto IL_0051;
			case 1:
				goto IL_006b;
			case 3:
				goto IL_0078;
			case 2:
				goto IL_00c6;
			}
			if ((int)biome != 8)
			{
				if ((int)biome != 16)
				{
					goto IL_00c6;
				}
				hex = Plugin.ColorPlains.Value;
			}
			else
			{
				hex = Plugin.ColorBlackForest.Value;
			}
		}
		else if ((int)biome <= 64)
		{
			if ((int)biome != 32)
			{
				if ((int)biome != 64)
				{
					goto IL_00c6;
				}
				hex = Plugin.ColorDeepNorth.Value;
			}
			else
			{
				hex = Plugin.ColorAshlands.Value;
			}
		}
		else if ((int)biome != 256)
		{
			if ((int)biome != 512)
			{
				goto IL_00c6;
			}
			hex = Plugin.ColorMistlands.Value;
		}
		else
		{
			hex = Plugin.ColorOcean.Value;
		}
		goto IL_00c8;
		IL_006b:
		hex = Plugin.ColorSwamp.Value;
		goto IL_00c8;
		IL_0078:
		hex = Plugin.ColorMountain.Value;
		goto IL_00c8;
		IL_00c6:
		hex = null;
		goto IL_00c8;
		IL_0051:
		hex = Plugin.ColorMeadows.Value;
		goto IL_00c8;
		IL_00c8:
		return Parse(hex, Color.white);
	}

	private void PaintWindowColors(Player player)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: 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_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: 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_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: 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_00cc: 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_00de: 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_0138: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: 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_010d: 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_0155: 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_016c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player == (Object)null)
		{
			return;
		}
		bool value = Plugin.BiomeTint.Value;
		Biome val = (Biome)((!value) ? (-1) : ((int)player.GetCurrentBiome()));
		float num = (value ? Mathf.Clamp01(Plugin.BiomeTintStrength.Value) : 0f);
		float num2 = Mathf.Clamp01(Plugin.WindowDarken.Value);
		if (val == _paintedBiome && Plugin.ConfigVersion == _paintedConfig)
		{
			return;
		}
		_paintedBiome = val;
		_paintedConfig = Plugin.ConfigVersion;
		Color val2 = (value ? BiomeColor(val) : Color.white);
		Color val3 = default(Color);
		foreach (KeyValuePair<Dir, Slot> slot in _slots)
		{
			Slot value2 = slot.Value;
			if (value2 != null)
			{
				if ((Object)(object)value2.Bkg != (Object)null)
				{
					Color bkgColor = value2.BkgColor;
					((Color)(ref val3))..ctor(bkgColor.r * num2, bkgColor.g * num2, bkgColor.b * num2, bkgColor.a);
					Color color = ((num > 0f) ? Color.Lerp(val3, val2, num) : val3);
					color.a = bkgColor.a;
					((Graphic)value2.Bkg).color = color;
				}
				if ((Object)(object)value2.Highlight != (Object)null)
				{
					Color highlightColor = value2.HighlightColor;
					Color color2 = ((num > 0f) ? Color.Lerp(highlightColor, val2, num) : highlightColor);
					color2.a = highlightColor.a;
					((Graphic)value2.Highlight).color = color2;
				}
			}
		}
	}

	private void EnsureTorchWindow()
	{
		if (_torch != null || (Object)(object)_torchPrefab == (Object)null || !Plugin.ShowTorchWindow.Value)
		{
			return;
		}
		Hud instance = Hud.instance;
		Transform val = (((Object)(object)instance != (Object)null && (Object)(object)instance.m_rootObject != (Object)null) ? instance.m_rootObject.transform : null);
		if (!((Object)(object)val == (Object)null))
		{
			_torch = MakeSlot(_torchPrefab, "TorchWindow", val);
			if ((Object)(object)_torch?.Root == (Object)null)
			{
				_torch = null;
				return;
			}
			ApplyTorchLayout();
			_torchBkg = FindByName<Image>((Transform)(object)_torch.Root, new string[1] { "bkg" });
			((Component)_torch.Root).gameObject.SetActive(false);
		}
	}

	private void ApplyTorchLayout()
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: 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)
		if (!((Object)(object)_torch?.Root == (Object)null) && _torchLayout != Plugin.ConfigVersion)
		{
			_torchLayout = Plugin.ConfigVersion;
			RectTransform root = _torch.Root;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(Plugin.TorchWindowAnchorX.Value, Plugin.TorchWindowAnchorY.Value);
			root.anchorMax = val;
			root.anchorMin = val;
			root.pivot = new Vector2(0.5f, 0.5f);
			root.anchoredPosition = new Vector2(Plugin.TorchWindowOffsetX.Value, Plugin.TorchWindowOffsetY.Value);
			((Transform)root).localScale = Vector3.one;
		}
	}

	private static Color Parse(string hex, Color fallback)
	{
		//IL_000c: 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)
		Color result = default(Color);
		if (!ColorUtility.TryParseHtmlString(hex, ref result))
		{
			return fallback;
		}
		return result;
	}

	private static ItemData BurningTorch(Player player)
	{
		if ((Object)(object)player == (Object)null)
		{
			return null;
		}
		ItemData val = Priv.LeftItem((Humanoid)(object)player);
		ItemData val2 = Priv.RightItem((Humanoid)(object)player);
		ItemData val3 = ((val != null && Categories.IsTorchLike(val)) ? val : ((val2 != null && Categories.IsTorchLike(val2)) ? val2 : null));
		if (val3 == null || !val3.m_shared.m_useDurability)
		{
			return null;
		}
		return val3;
	}

	private void PaintTorchWindow(Player player)
	{
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: 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_022e: Unknown result type (might be due to invalid IL or missing references)
		EnsureTorchWindow();
		if ((Object)(object)_torch?.Root == (Object)null)
		{
			return;
		}
		ApplyTorchLayout();
		ItemData val = (Plugin.ShowTorchWindow.Value ? BurningTorch(player) : null);
		bool flag = val != null;
		if (((Component)_torch.Root).gameObject.activeSelf != flag)
		{
			((Component)_torch.Root).gameObject.SetActive(flag);
		}
		if (!flag)
		{
			return;
		}
		if ((Object)(object)_torch.Icon != (Object)null)
		{
			if (_torch.Shown != val)
			{
				_torch.Icon.sprite = val.GetIcon();
				_torch.Shown = val;
			}
			((Behaviour)_torch.Icon).enabled = (Object)(object)_torch.Icon.sprite != (Object)null;
		}
		if ((Object)(object)_torch.Amount != (Object)null)
		{
			_torch.Amount.text = string.Empty;
		}
		Toggle(_torch.Equipped, on: false);
		Toggle(_torch.Queued, on: false);
		if ((Object)(object)_torch.Quality != (Object)null)
		{
			Toggle(((Component)_torch.Quality).gameObject, on: false);
		}
		if (_torchColors != Plugin.ConfigVersion)
		{
			_torchColors = Plugin.ConfigVersion;
			_torchBkgColor = Parse(Plugin.TorchWindowBackground.Value, new Color(0.1f, 0.08f, 0.06f, 0.9f));
			_torchBarColor = Parse(Plugin.TorchWindowBar.Value, new Color(0.8f, 0.47f, 0.13f, 1f));
		}
		if ((Object)(object)_torchBkg != (Object)null)
		{
			((Graphic)_torchBkg).color = _torchBkgColor;
		}
		if ((Object)(object)_torch.Durability != (Object)null)
		{
			((Component)_torch.Durability).gameObject.SetActive(true);
			_torch.Durability.SetValue(val.GetDurabilityPercentage());
			_torch.Durability.SetColor(_torchBarColor);
		}
	}

	private static bool DiamondOwnsHud()
	{
		if (Plugin.RequireGamepad.Value)
		{
			return ZInput.IsGamepadActive();
		}
		return true;
	}

	private void AdoptGuardianPower()
	{
		//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_006d: 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_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00a0: 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_00b1: 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)
		if (!_gpAdopted)
		{
			Hud instance = Hud.instance;
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.m_gpRoot == (Object)null))
			{
				_gp = instance.m_gpRoot;
				_gpParent = ((Transform)_gp).parent;
				_gpIndex = ((Transform)_gp).GetSiblingIndex();
				_gpAnchorMin = _gp.anchorMin;
				_gpAnchorMax = _gp.anchorMax;
				_gpPivot = _gp.pivot;
				_gpPos = _gp.anchoredPosition;
				_gpSize = _gp.sizeDelta;
				_gpScale = ((Transform)_gp).localScale;
				((Transform)_gp).SetParent(((Component)this).transform, false);
				((Transform)_gp).SetAsFirstSibling();
				_gpAdopted = true;
				ApplyGuardianPowerLayout();
			}
		}
	}

	private void BuildBeltWindow(GameObject prefab)
	{
		_belt = MakeSlot(prefab, "Belt");
		if ((Object)(object)_belt?.Root == (Object)null)
		{
			_belt = null;
			return;
		}
		if ((Object)(object)_belt.Amount != (Object)null)
		{
			((Component)_belt.Amount).gameObject.SetActive(false);
		}
		if ((Object)(object)_belt.Quality != (Object)null)
		{
			((Component)_belt.Quality).gameObject.SetActive(false);
		}
		if ((Object)(object)_belt.Pool != (Object)null)
		{
			((Component)_belt.Pool).gameObject.SetActive(false);
		}
		if ((Object)(object)_belt.Durability != (Object)null)
		{
			((Component)_belt.Durability).gameObject.SetActive(false);
		}
		Toggle(_belt.Equipped, on: false);
		Toggle(_belt.Queued, on: false);
		((Component)_belt.Root).gameObject.SetActive(false);
	}

	private void ApplyBeltLayout()
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: 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)
		if (!((Object)(object)_belt?.Root == (Object)null))
		{
			_belt.Root.anchoredPosition = Vector2.zero;
			((Transform)_belt.Root).localScale = Vector3.one * Plugin.HudScale.Value * Plugin.BeltWindowScale.Value;
		}
	}

	private void PaintBeltWindow(Player player)
	{
		//IL_012a: 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_0158: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_belt?.Root == (Object)null)
		{
			return;
		}
		ItemData val = ((Plugin.ShowBeltWindow.Value && (Object)(object)player != (Object)null) ? Priv.UtilityItem((Humanoid)(object)player) : null);
		if (val != null && Categories.IsTorchLike(val))
		{
			val = null;
		}
		bool flag = val != null;
		if (((Component)_belt.Root).gameObject.activeSelf != flag)
		{
			((Component)_belt.Root).gameObject.SetActive(flag);
		}
		if (!flag)
		{
			_belt.Shown = null;
			return;
		}
		if ((Object)(object)_belt.Icon != (Object)null)
		{
			if (_belt.Shown != val)
			{
				_belt.Icon.sprite = val.GetIcon();
				_belt.Shown = val;
			}
			((Behaviour)_belt.Icon).enabled = (Object)(object)_belt.Icon.sprite != (Object)null;
		}
		if (_beltColors != Plugin.ConfigVersion)
		{
			_beltColors = Plugin.ConfigVersion;
			_beltBkgColor = Parse(Plugin.BeltWindowBackground.Value, new Color(0.1f, 0.08f, 0.06f, 0.9f));
		}
		if ((Object)(object)_belt.Bkg != (Object)null)
		{
			((Graphic)_belt.Bkg).color = _beltBkgColor;
		}
	}

	private bool GuardianPowerSpot(out Transform parent, out Vector2 aMin, out Vector2 aMax, out Vector2 pivot, out Vector2 pos)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: 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_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: 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_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: 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)
		if (_gpAdopted && (Object)(object)_gpParent != (Object)null)
		{
			parent = _gpParent;
			aMin = _gpAnchorMin;
			aMax = _gpAnchorMax;
			pivot = _gpPivot;
			pos = _gpPos;
			return true;
		}
		Hud instance = Hud.instance;
		RectTransform val = (((Object)(object)instance != (Object)null) ? instance.m_gpRoot : null);
		if ((Object)(object)val == (Object)null || (Object)(object)((Transform)val).parent == (Object)null)
		{
			parent = null;
			aMin = (aMax = (pivot = (pos = Vector2.zero)));
			return false;
		}
		parent = ((Transform)val).parent;
		aMin = val.anchorMin;
		aMax = val.anchorMax;
		pivot = val.pivot;
		pos = val.anchoredPosition;
		return true;
	}

	private void AdoptStatusList()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: 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_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_00a2: 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_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		Hud instance = Hud.instance;
		if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_statusEffectListRoot == (Object)null)
		{
			return;
		}
		if (!_statusAdopted)
		{
			_status = instance.m_statusEffectListRoot;
			_statusParent = ((Transform)_status).parent;
			_statusIndex = ((Transform)_status).GetSiblingIndex();
			_statusAnchorMin = _status.anchorMin;
			_statusAnchorMax = _status.anchorMax;
			_statusPivot = _status.pivot;
			_statusPos = _status.anchoredPosition;
			_statusScale = ((Transform)_status).localScale;
			_statusAdopted = true;
			_statusLayout = -1;
		}
		if (_statusLayout != Plugin.ConfigVersion)
		{
			if (!GuardianPowerSpot(out var parent, out var aMin, out var aMax, out var pivot, out var pos))
			{
				return;
			}
			_statusLayout = Plugin.ConfigVersion;
			if ((Object)(object)((Transform)_status).parent != (Object)(object)parent)
			{
				((Transform)_status).SetParent(parent, false);
			}
			_status.anchorMin = aMin;
			_status.anchorMax = aMax;
			_status.pivot = pivot;
			_status.anchoredPosition = pos + new Vector2(Plugin.StatusListOffsetX.Value, Plugin.StatusListOffsetY.Value);
			((Transform)_status).localScale = Vector3.one * Plugin.StatusListScale.Value;
		}
		MirrorStatusRow();
		ScaleStatusTimers();
	}

	private void MirrorStatusRow()
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: 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_00cc: 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)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_status == (Object)null || !Plugin.StatusListLeftToRight.Value)
		{
			return;
		}
		float num = float.MaxValue;
		float num2 = float.MinValue;
		for (int i = 0; i < ((Transform)_status).childCount; i++)
		{
			Transform child = ((Transform)_status).GetChild(i);
			if (!((Component)child).gameObject.activeSelf)
			{
				continue;
			}
			RectTransform val = (RectTransform)(object)((child is RectTransform) ? child : null);
			if (val != null)
			{
				float x = val.anchoredPosition.x;
				if (x < num)
				{
					num = x;
				}
				if (x > num2)
				{
					num2 = x;
				}
			}
		}
		if (num >= 0f || num2 > 0f)
		{
			return;
		}
		for (int j = 0; j < ((Transform)_status).childCount; j++)
		{
			Transform child2 = ((Transform)_status).GetChild(j);
			if (((Component)child2).gameObject.activeSelf)
			{
				RectTransform val2 = (RectTransform)(object)((child2 is RectTransform) ? child2 : null);
				if (val2 != null)
				{
					Vector2 anchoredPosition = val2.anchoredPosition;
					val2.anchoredPosition = new Vector2(0f - anchoredPosition.x, anchoredPosition.y);
				}
			}
		}
	}

	private void ReleaseStatusList()
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		if (_statusAdopted)
		{
			_statusAdopted = false;
			if (!((Object)(object)_status == (Object)null) && !((Object)(object)_statusParent == (Object)null))
			{
				((Transform)_status).SetParent(_statusParent, false);
				((Transform)_status).SetSiblingIndex(_statusIndex);
				_status.anchorMin = _statusAnchorMin;
				_status.anchorMax = _statusAnchorMax;
				_status.pivot = _statusPivot;
				_status.anchoredPosition = _statusPos;
				((Transform)_status).localScale = _statusScale;
			}
		}
	}

	private void ScaleStatusTimers()
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_status == (Object)null)
		{
			return;
		}
		Vector3 val = Vector3.one * Plugin.StatusTimerScale.Value;
		for (int i = 0; i < ((Transform)_status).childCount; i++)
		{
			Transform child = ((Transform)_status).GetChild(i);
			if (((Component)child).gameObject.activeSelf)
			{
				Transform val2 = child.Find("TimeText");
				if ((Object)(object)val2 != (Object)null && val2.localScale != val)
				{
					val2.localScale = val;
				}
			}
		}
	}

	private void ApplyGuardianPowerLayout()
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: 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_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		if (_gpAdopted && !((Object)(object)_gp == (Object)null))
		{
			RectTransform gp = _gp;
			RectTransform gp2 = _gp;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			gp2.anchorMax = val;
			gp.anchorMin = val;
			_gp.pivot = new Vector2(0.5f, 0.5f);
			_gp.anchoredPosition = Vector2.zero;
			((Transform)_gp).localScale = Vector3.one * Plugin.GuardianPowerScale.Value;
		}
	}

	private void ReleaseGuardianPower()
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		if (_gpAdopted)
		{
			_gpAdopted = false;
			if (!((Object)(object)_gp == (Object)null) && !((Object)(object)_gpParent == (Object)null))
			{
				((Transform)_gp).SetParent(_gpParent, false);
				((Transform)_gp).SetSiblingIndex(_gpIndex);
				_gp.anchorMin = _gpAnchorMin;
				_gp.anchorMax = _gpAnchorMax;
				_gp.pivot = _gpPivot;
				_gp.anchoredPosition = _gpPos;
				_gp.sizeDelta = _gpSize;
				((Transform)_gp).localScale = _gpScale;
			}
		}
	}

	private void Build(GameObject elementPrefab)
	{
		_group = ((Component)this).GetComponent<CanvasGroup>();
		_group.interactable = false;
		_group.blocksRaycasts = false;
		_group.alpha = 0f;
		if (Plugin.LogPrefabHierarchy.Value && !_loggedHierarchy)
		{
			_loggedHierarchy = true;
			StringBuilder stringBuilder = new StringBuilder("hotbar element prefab hierarchy:\n");
			DumpHierarchy(elementPrefab.transform, 0, stringBuilder);
			Plugin.Instance.Log.LogInfo((object)stringBuilder.ToString());
		}
		_slots[Dir.Up] = MakeSlot(elementPrefab, "Up");
		_slots[Dir.Down] = MakeSlot(elementPrefab, "Down");
		_slots[Dir.Left] = MakeSlot(elementPrefab, "Left");
		BuildPoolLabel(_slots[Dir.Left]);
		_slots[Dir.Right] = MakeSlot(elementPrefab, "Right");
		_slots[Dir.Ammo] = MakeSlot(elementPrefab, "Ammo");
		_torchPrefab = elementPrefab;
		BuildBeltWindow(elementPrefab);
		BuildConsumeHint();
		BuildMacroHints();
		ApplyLayout();
	}

	private static Vector2 Offset(Dir dir, float r)
	{
		//IL_0022: 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_0031: 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_0040: 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_006d: 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_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		return (Vector2)(dir switch
		{
			Dir.Up => new Vector2(0f, r), 
			Dir.Down => new Vector2(0f, 0f - r), 
			Dir.Left => new Vector2(0f - r, 0f), 
			Dir.Ammo => new Vector2(0f - r + Plugin.AmmoSlotOffsetX.Value, Plugin.AmmoSlotGap.Value), 
			_ => new Vector2(r, 0f), 
		});
	}

	private void ApplyLayout()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Expected O, but got Unknown
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: 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)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_014c: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		RectTransform val = (RectTransform)((Component)this).transform;
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(Plugin.HudAnchorX.Value, Plugin.HudAnchorY.Value);
		val.anchorMax = val2;
		val.anchorMin = val2;
		val.pivot = new Vector2(0.5f, 0.5f);
		val.anchoredPosition = new Vector2(Plugin.HudOffsetX.Value, Plugin.HudOffsetY.Value);
		val.sizeDelta = Vector2.zero;
		float value = Plugin.HudRadius.Value;
		float value2 = Plugin.HudScale.Value;
		foreach (KeyValuePair<Dir, Slot> slot in _slots)
		{
			if (!((Object)(object)slot.Value?.Root == (Object)null))
			{
				slot.Value.Root.anchoredPosition = Offset(slot.Key, value);
				((Transform)slot.Value.Root).localScale = Vector3.one * value2 * ((slot.Key == Dir.Ammo) ? Plugin.AmmoSlotScale.Value : 1f);
				if (slot.Key == Dir.Ammo && (Object)(object)slot.Value.Amount != (Object)null)
				{
					slot.Value.Amount.transform.localScale = Vector3.one * Plugin.AmmoCountScale.Value;
				}
			}
		}
		ApplyGuardianPowerLayout();
		ApplyBeltLayout();
		_layout = Plugin.ConfigVersion;
		WarnIfOffScreen(val);
	}

	private static void WarnIfOffScreen(RectTransform rt)
	{
		//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_0007: 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_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		Vector3 position = ((Transform)rt).position;
		if ((position.x < 0f || position.x > (float)Screen.width || position.y < 0f || position.y > (float)Screen.height) && Plugin.ConfigVersion != _warnedFor)
		{
			_warnedFor = Plugin.ConfigVersion;
			Plugin.Instance.Log.LogWarning((object)($"Diamond centre is off screen at {position} (screen {Screen.width}x{Screen.height}). " + "Check AnchorX/AnchorY and PixelOffsetX/PixelOffsetY."));
		}
	}

	private static void DumpHierarchy(Transform t, int depth, StringBuilder sb)
	{
		sb.Append(' ', depth * 2).Append(((Object)t).name);
		Component[] components = ((Component)t).GetComponents<Component>();
		foreach (Component val in components)
		{
			if ((Object)(object)val != (Object)null && !(val is Transform))
			{
				sb.Append(" [").Append(((object)val).GetType().Name).Append(']');
			}
		}
		sb.AppendLine();
		for (int j = 0; j < t.childCount; j++)
		{
			DumpHierarchy(t.GetChild(j), depth + 1, sb);
		}
	}

	private Slot MakeSlot(GameObject prefab, string name)
	{
		return MakeSlot(prefab, name, ((Component)this).transform);
	}

	private Slot MakeSlot(GameObject prefab, string name, Transform parent)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Expected O, but got Unknown
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: U