Decompiled source of DrakeModsLibs v0.11.2

DrakeModsLibs.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DrakeModsLibs.API;
using DrakeModsLibs.Data;
using DrakeModsLibs.Display;
using DrakeModsLibs.Forge.Gltf;
using DrakeModsLibs.Input;
using DrakeModsLibs.Integration;
using DrakeModsLibs.Patches;
using DrakeModsLibs.Runtime;
using DrakeModsLibs.Stack;
using DrakeModsLibs.Sync;
using DrakeModsLibs.Tags;
using DrakeModsLibs.UI;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("DrakeModsLibs")]
[assembly: AssemblyDescription("Shared customization library for Drake mods.")]
[assembly: AssemblyCompany("DrakesWorkshop")]
[assembly: AssemblyProduct("DrakeModsLibs")]
[assembly: ComVisible(false)]
[assembly: Guid("a1111111-1111-4111-8111-111111111101")]
[assembly: AssemblyFileVersion("0.3.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.3.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DrakeModsLibs
{
	[BepInPlugin("com.drakemods.libs", "DrakeModsLibs", "0.11.2")]
	public class CustomizeLibsPlugin : BaseUnityPlugin
	{
		private readonly Harmony _harmony = new Harmony("drakemods.DrakeModsLibs");

		public const string CompanyName = "DrakeMods";

		public const string ModName = "DrakeModsLibs";

		public const string Version = "0.11.2";

		public const string GUID = "com.drakemods.libs";

		private void Awake()
		{
			DrakeIntegrationConfig.Bind(((BaseUnityPlugin)this).Config);
			MenuBindingRegistry.SetLogger(((BaseUnityPlugin)this).Logger);
			MenuBindingRegistry.Register("drake.inventory.context", "inventory.context", 0, () => DrakeIntegrationConfig.InventoryOpenModifier, "DrakeModsLibs");
			HarmonyPatchHub.ApplyAll(_harmony, ((BaseUnityPlugin)this).Logger);
			PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabs;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DrakeModsLibs 0.11.2 loaded (display patches, DrakeConfigSync API, shared wood UI + inventory context host).");
		}

		private void OnVanillaPrefabs()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabs;
			InventoryContextLocalization.Register();
		}
	}
	internal static class HarmonyPatchHub
	{
		internal static void ApplyAll(Harmony harmony, ManualLogSource log)
		{
			InventoryStackPatches.Apply(harmony, log);
			ItemTooltipPatches.Apply(harmony, log);
			DropHudMessagePatches.ApplyDropItemPendingCapture(harmony, log);
			harmony.PatchAll(typeof(HarmonyPatchHub).Assembly);
			DropHudMessagePatches.ApplyMessageHudShowMessage(harmony, log);
			log.LogInfo((object)"[DrakeModsLibs] Display Harmony patches applied.");
		}
	}
}
namespace DrakeModsLibs.UI
{
	public static class DrakeButtonSfx
	{
		private static readonly string[] OptionalClearFieldNames = new string[4] { "m_selectSfxPrefab", "m_selectSfxPrefabVibrationOnly", "m_enterSfxPrefab", "m_enterSfxPrefabVibrationOnly" };

		private static readonly FieldInfo[] SoftenFields = ResolveSoftenFields();

		private static FieldInfo[] ResolveSoftenFields()
		{
			List<FieldInfo> list = new List<FieldInfo>();
			Type typeFromHandle = typeof(ButtonSfx);
			string[] optionalClearFieldNames = OptionalClearFieldNames;
			foreach (string text in optionalClearFieldNames)
			{
				FieldInfo fieldInfo = AccessTools.Field(typeFromHandle, text);
				if (fieldInfo != null)
				{
					list.Add(fieldInfo);
				}
			}
			return list.ToArray();
		}

		public static void Soften(GameObject? root)
		{
			if (!Object.op_Implicit((Object)(object)root))
			{
				return;
			}
			ButtonSfx[] componentsInChildren = root.GetComponentsInChildren<ButtonSfx>(true);
			foreach (ButtonSfx val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					FieldInfo[] softenFields = SoftenFields;
					foreach (FieldInfo fieldInfo in softenFields)
					{
						fieldInfo.SetValue(val, null);
					}
				}
			}
		}

		public static Button SoftenButton(GameObject buttonGo)
		{
			Soften(buttonGo);
			return buttonGo.GetComponent<Button>();
		}
	}
	public sealed class DrakeConfirmPanel
	{
		private const float BodyTop = 76f;

		private const float BodyMinHeight = 64f;

		private const float FooterHeight = 38f;

		private const float TextInset = 14f;

		private const float ButtonBottom = 35f;

		private readonly string _panelName;

		private readonly DrakePanelOptions _options;

		private GameObject? _panel;

		private RectTransform? _panelRt;

		private Text? _titleText;

		private ScrollRect? _bodyScroll;

		private RectTransform? _bodyScrollRt;

		private RectTransform? _bodyContent;

		private Text? _bodyText;

		private Button? _yesButton;

		private Button? _noButton;

		private Action? _onYes;

		private Action? _onNo;

		private bool _releaseInputOnClose;

		public bool IsOpen => Object.op_Implicit((Object)(object)_panel) && _panel.activeSelf;

		private float TextWidth => _options.Width - 28f;

		public DrakeConfirmPanel(string panelName = "drake_confirm_panel", DrakePanelOptions? options = null)
		{
			_panelName = (string.IsNullOrEmpty(panelName) ? "drake_confirm_panel" : panelName);
			_options = options ?? new DrakePanelOptions();
		}

		public void Show(string title, string body, Action? onYes, Action? onNo = null, string yesLabel = "Yes", string noLabel = "No")
		{
			if (GUIManager.Instance != null && Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				Ensure();
				if (Object.op_Implicit((Object)(object)_panel) && !((Object)(object)_titleText == (Object)null) && !((Object)(object)_bodyText == (Object)null) && Object.op_Implicit((Object)(object)_yesButton) && Object.op_Implicit((Object)(object)_noButton))
				{
					_onYes = onYes;
					_onNo = onNo;
					_titleText.text = title ?? "";
					_bodyText.text = body ?? "";
					SetButtonLabel(_yesButton, yesLabel);
					SetButtonLabel(_noButton, noLabel);
					Layout();
					_releaseInputOnClose = !DrakeGuiInput.IsBlocked;
					_panel.SetActive(true);
					_panel.transform.SetAsLastSibling();
					DrakeGuiInput.EnsureBlocked();
				}
			}
		}

		public void Close()
		{
			if (Object.op_Implicit((Object)(object)_panel))
			{
				_panel.SetActive(false);
			}
			if (_releaseInputOnClose)
			{
				DrakeGuiInput.EnsureUnblocked();
			}
			_releaseInputOnClose = false;
			_onYes = null;
			_onNo = null;
		}

		private void Layout()
		{
			//IL_0065: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_panelRt) && Object.op_Implicit((Object)(object)_bodyText) && Object.op_Implicit((Object)(object)_bodyScrollRt) && Object.op_Implicit((Object)(object)_bodyScroll) && Object.op_Implicit((Object)(object)_bodyContent))
			{
				RectTransform rectTransform = ((Graphic)_bodyText).rectTransform;
				rectTransform.sizeDelta = new Vector2(TextWidth, rectTransform.sizeDelta.y);
				float num = Mathf.Max(DrakeLayout.MeasureHeight(_bodyText), 64f);
				float num2 = Mathf.Max(64f, _options.MaxHeight - 76f - 38f);
				float num3 = Mathf.Clamp(num, 64f, num2);
				float num4 = Mathf.Clamp(76f + num3 + 38f, _options.MinHeight, _options.MaxHeight);
				_panelRt.sizeDelta = new Vector2(_options.Width, num4);
				_bodyScrollRt.sizeDelta = new Vector2(TextWidth, num3);
				rectTransform.sizeDelta = new Vector2(TextWidth, num);
				DrakeLayout.SetContentHeight(_bodyScroll, num, num3);
			}
		}

		private void Ensure()
		{
			//IL_0048: 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_005c: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Expected O, but got Unknown
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_panel) && GUIManager.Instance != null && Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				_panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, _options.Width, _options.MinHeight, false);
				((Object)_panel).name = _panelName;
				_panelRt = _panel.GetComponent<RectTransform>();
				_titleText = GUIManager.Instance.CreateText("", _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -40f), GUIManager.Instance.AveriaSerifBold, 20, GUIManager.Instance.ValheimOrange, true, Color.black, TextWidth, 44f, false).GetComponent<Text>();
				_titleText.alignment = (TextAnchor)4;
				_bodyScroll = DrakeLayout.CreateScrollArea(_panel.transform, "body", TextWidth, 64f, new Vector2(0f, -76f), out _bodyContent);
				_bodyScrollRt = (RectTransform)((Component)_bodyScroll).transform;
				_bodyText = GUIManager.Instance.CreateText("", ((Component)_bodyContent).transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), Vector2.zero, GUIManager.Instance.AveriaSerifBold, 14, Color.white, true, Color.black, TextWidth, 64f, false).GetComponent<Text>();
				((Graphic)_bodyText).rectTransform.pivot = new Vector2(0.5f, 1f);
				_bodyText.alignment = (TextAnchor)1;
				_bodyText.horizontalOverflow = (HorizontalWrapMode)0;
				_bodyText.verticalOverflow = (VerticalWrapMode)1;
				_yesButton = DrakeButtonSfx.SoftenButton(GUIManager.Instance.CreateButton("Yes", _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2((0f - _options.ButtonWidth) / 2f, 35f), _options.ButtonWidth, _options.ButtonHeight));
				((UnityEvent)_yesButton.onClick).AddListener((UnityAction)delegate
				{
					Action onYes = _onYes;
					Close();
					onYes?.Invoke();
				});
				_noButton = DrakeButtonSfx.SoftenButton(GUIManager.Instance.CreateButton("No", _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(_options.ButtonWidth / 2f, 35f), _options.ButtonWidth, _options.ButtonHeight));
				((UnityEvent)_noButton.onClick).AddListener((UnityAction)delegate
				{
					Action onNo = _onNo;
					Close();
					onNo?.Invoke();
				});
				DrakeButtonSfx.Soften(_panel);
				_panel.SetActive(false);
			}
		}

		private static void SetButtonLabel(Button button, string label)
		{
			Text componentInChildren = ((Component)button).GetComponentInChildren<Text>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				componentInChildren.text = label;
			}
		}
	}
	public static class DrakeGuiInput
	{
		private static bool _inputBlocked;

		public static bool IsBlocked => _inputBlocked;

		public static void EnsureBlocked()
		{
			if (!_inputBlocked)
			{
				GUIManager.BlockInput(true);
				_inputBlocked = true;
			}
		}

		public static void EnsureUnblocked()
		{
			if (_inputBlocked)
			{
				GUIManager.BlockInput(false);
				_inputBlocked = false;
			}
		}
	}
	public sealed class DrakeMenuAction
	{
		public string Label { get; }

		public Action OnClick { get; }

		public bool Enabled { get; set; }

		public DrakeMenuAction(string label, Action onClick, bool enabled = true)
		{
			Label = label ?? "";
			OnClick = onClick ?? ((Action)delegate
			{
			});
			Enabled = enabled;
		}
	}
	internal static class DrakeLayout
	{
		public static float MeasureHeight(Text text)
		{
			return Mathf.Ceil(text.preferredHeight);
		}

		public static ScrollRect CreateScrollArea(Transform parent, string name, float width, float height, Vector2 anchoredPosition, out RectTransform content)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_005a: 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_0086: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Expected O, but got Unknown
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(ScrollRect)
			});
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			val2.anchorMin = new Vector2(0.5f, 1f);
			val2.anchorMax = new Vector2(0.5f, 1f);
			val2.pivot = new Vector2(0.5f, 1f);
			val2.anchoredPosition = anchoredPosition;
			val2.sizeDelta = new Vector2(width, height);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = new Color(0f, 0f, 0f, 0f);
			((Graphic)component).raycastTarget = false;
			GameObject val3 = new GameObject("viewport", new Type[2]
			{
				typeof(RectTransform),
				typeof(RectMask2D)
			});
			val3.transform.SetParent(val.transform, false);
			RectTransform val4 = (RectTransform)val3.transform;
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = Vector2.zero;
			val4.offsetMax = Vector2.zero;
			GameObject val5 = new GameObject("content", new Type[1] { typeof(RectTransform) });
			val5.transform.SetParent(val3.transform, false);
			content = (RectTransform)val5.transform;
			content.anchorMin = new Vector2(0f, 1f);
			content.anchorMax = new Vector2(1f, 1f);
			content.pivot = new Vector2(0.5f, 1f);
			content.anchoredPosition = Vector2.zero;
			content.sizeDelta = new Vector2(0f, height);
			ScrollRect component2 = val.GetComponent<ScrollRect>();
			component2.viewport = val4;
			component2.content = content;
			component2.horizontal = false;
			component2.vertical = false;
			component2.movementType = (MovementType)2;
			return component2;
		}

		public static void SetContentHeight(ScrollRect scroll, float contentHeight, float viewportHeight)
		{
			//IL_000a: 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)
			RectTransform content = scroll.content;
			content.sizeDelta = new Vector2(content.sizeDelta.x, contentHeight);
			bool raycastTarget = (scroll.vertical = contentHeight > viewportHeight + 0.5f);
			((Graphic)((Component)scroll).GetComponent<Image>()).raycastTarget = raycastTarget;
			scroll.verticalNormalizedPosition = 1f;
		}
	}
	public sealed class DrakePanelOptions
	{
		public float Width { get; set; } = 300f;

		public float MinHeight { get; set; } = 178f;

		public float MaxHeight { get; set; } = 420f;

		public float ButtonWidth { get; set; } = 110f;

		public float ButtonHeight { get; set; } = 30f;

		public float RowGap { get; set; } = 40f;
	}
	public sealed class DrakeNumericStepper
	{
		private int _value;

		private bool _suppress;

		private Action<int>? _onChanged;

		public GameObject Root { get; }

		public InputField? Field { get; }

		public Button? MinusButton { get; }

		public Button? PlusButton { get; }

		public int Min { get; private set; }

		public int Max { get; private set; }

		public int Value
		{
			get
			{
				return _value;
			}
			set
			{
				SetValue(value, notify: true);
			}
		}

		private DrakeNumericStepper(GameObject root, InputField? field, Button? minus, Button? plus, int min, int max, int initial, Action<int>? onChanged)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			Root = root;
			Field = field;
			MinusButton = minus;
			PlusButton = plus;
			Min = min;
			Max = max;
			_onChanged = onChanged;
			_value = Mathf.Clamp(initial, min, max);
			if ((Object)(object)MinusButton != (Object)null)
			{
				((UnityEvent)MinusButton.onClick).AddListener((UnityAction)delegate
				{
					Step(-1);
				});
			}
			if ((Object)(object)PlusButton != (Object)null)
			{
				((UnityEvent)PlusButton.onClick).AddListener((UnityAction)delegate
				{
					Step(1);
				});
			}
			if ((Object)(object)Field != (Object)null)
			{
				Field.characterLimit = Math.Max(1, max.ToString().Length);
				((UnityEvent<string>)(object)Field.onEndEdit).AddListener((UnityAction<string>)OnEndEdit);
				if ((Object)(object)Field.textComponent != (Object)null)
				{
					Field.textComponent.alignment = (TextAnchor)4;
				}
			}
			SyncField();
		}

		public void SetValueWithoutNotify(int value)
		{
			SetValue(value, notify: false);
		}

		public void SetOnChanged(Action<int>? onChanged)
		{
			_onChanged = onChanged;
		}

		public void SetRange(int min, int max, bool notifyIfClamped = false)
		{
			if (max < min)
			{
				int num = max;
				max = min;
				min = num;
			}
			Min = min;
			Max = max;
			if ((Object)(object)Field != (Object)null)
			{
				Field.characterLimit = Math.Max(1, max.ToString().Length);
			}
			int value = _value;
			SetValue(_value, notify: false);
			if (notifyIfClamped && value != _value)
			{
				_onChanged?.Invoke(_value);
			}
		}

		public void SetInteractable(bool interactable)
		{
			if ((Object)(object)Field != (Object)null)
			{
				((Selectable)Field).interactable = interactable;
			}
			if ((Object)(object)MinusButton != (Object)null)
			{
				((Selectable)MinusButton).interactable = interactable;
			}
			if ((Object)(object)PlusButton != (Object)null)
			{
				((Selectable)PlusButton).interactable = interactable;
			}
		}

		public static DrakeNumericStepper? Create(Transform parent, Vector2 anchoredPosition, int min, int max, int initial, Action<int>? onChanged = null, float buttonSize = 40f, float fieldWidth = 64f, float height = 32f, float gap = 12f)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: 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_01c6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)parent == (Object)null || GUIManager.Instance == null)
			{
				return null;
			}
			if (max < min)
			{
				int num = max;
				max = min;
				min = num;
			}
			GameObject val = new GameObject("drake_numeric_stepper", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			component.anchorMax = val2;
			component.anchorMin = val2;
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = anchoredPosition;
			float num2 = buttonSize * 2f + fieldWidth + gap * 2f;
			component.sizeDelta = new Vector2(num2, height);
			float num3 = 0f;
			float num4 = 0f - (fieldWidth * 0.5f + gap + buttonSize * 0.5f);
			float num5 = fieldWidth * 0.5f + gap + buttonSize * 0.5f;
			Button minus = DrakeButtonSfx.SoftenButton(GUIManager.Instance.CreateButton("−", val.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(num4, 0f), buttonSize, height));
			GameObject val3 = GUIManager.Instance.CreateInputField(val.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(num3, 0f), (ContentType)2, initial.ToString(), 18, fieldWidth, height);
			Button plus = DrakeButtonSfx.SoftenButton(GUIManager.Instance.CreateButton("+", val.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(num5, 0f), buttonSize, height));
			InputField field = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<InputField>() : null);
			return new DrakeNumericStepper(val, field, minus, plus, min, max, initial, onChanged);
		}

		private void Step(int delta)
		{
			SetValue(_value + delta, notify: true);
		}

		private void OnEndEdit(string raw)
		{
			if (!_suppress)
			{
				if (!int.TryParse(raw, out var result))
				{
					SyncField();
				}
				else
				{
					SetValue(result, notify: true);
				}
			}
		}

		private void SetValue(int value, bool notify)
		{
			int num = Mathf.Clamp(value, Min, Max);
			bool flag = num != _value;
			_value = num;
			SyncField();
			if (notify && flag)
			{
				_onChanged?.Invoke(_value);
			}
		}

		private void SyncField()
		{
			if ((Object)(object)Field == (Object)null)
			{
				return;
			}
			_suppress = true;
			try
			{
				Field.text = _value.ToString();
			}
			finally
			{
				_suppress = false;
			}
		}
	}
	public sealed class DrakeSlider
	{
		private static readonly Color TrackColor = new Color(0.11f, 0.09f, 0.07f, 0.95f);

		private static readonly Color HandleColor = new Color(0.96f, 0.9f, 0.78f, 1f);

		private readonly Func<float, string> _format;

		private Action<float>? _onChanged;

		public GameObject Root { get; }

		public Slider Slider { get; }

		public Text? Label { get; }

		public Text? ValueText { get; }

		public float Value
		{
			get
			{
				return Slider.value;
			}
			set
			{
				Slider.value = value;
			}
		}

		private DrakeSlider(GameObject root, Slider slider, Text? label, Text? valueText, Func<float, string> format, Action<float>? onChanged)
		{
			Root = root;
			Slider = slider;
			Label = label;
			ValueText = valueText;
			_format = format;
			_onChanged = onChanged;
			((UnityEvent<float>)(object)Slider.onValueChanged).AddListener((UnityAction<float>)delegate(float v)
			{
				SyncText();
				_onChanged?.Invoke(v);
			});
			SyncText();
		}

		public void SetValueWithoutNotify(float value)
		{
			Slider.SetValueWithoutNotify(value);
			SyncText();
		}

		public void SetOnChanged(Action<float>? onChanged)
		{
			_onChanged = onChanged;
		}

		public void SetInteractable(bool interactable)
		{
			((Selectable)Slider).interactable = interactable;
		}

		public static DrakeSlider? Create(Transform parent, Vector2 anchoredPosition, string label, float min, float max, float initial, Action<float>? onChanged = null, Func<float, string>? format = null, float width = 300f, float height = 24f, float labelWidth = 80f, float valueWidth = 48f, int fontSize = 13, bool wholeNumbers = false)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_008e: 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_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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)parent == (Object)null || GUIManager.Instance == null)
			{
				return null;
			}
			if (max < min)
			{
				float num = max;
				max = min;
				min = num;
			}
			GameObject val = new GameObject("drake_slider", new Type[2]
			{
				typeof(RectTransform),
				typeof(HorizontalLayoutGroup)
			});
			val.transform.SetParent(parent, false);
			RectTransform val2 = (RectTransform)val.transform;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			val2.pivot = val3;
			Vector2 anchorMin = (val2.anchorMax = val3);
			val2.anchorMin = anchorMin;
			val2.anchoredPosition = anchoredPosition;
			val2.sizeDelta = new Vector2(width, height);
			HorizontalLayoutGroup component = val.GetComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component).spacing = 8f;
			((LayoutGroup)component).childAlignment = (TextAnchor)4;
			bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true);
			((HorizontalOrVerticalLayoutGroup)component).childControlWidth = childControlWidth;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = true;
			Text label2 = MakeText(val.transform, label, labelWidth, fontSize, (TextAnchor)5, flexible: false);
			Slider val5 = BuildSlider(val.transform, height);
			Text valueText = MakeText(val.transform, "", valueWidth, fontSize, (TextAnchor)3, flexible: false);
			val5.minValue = min;
			val5.maxValue = max;
			val5.wholeNumbers = wholeNumbers;
			val5.SetValueWithoutNotify(Mathf.Clamp(initial, min, max));
			return new DrakeSlider(val, val5, label2, valueText, format ?? ((Func<float, string>)((float v) => v.ToString("0.00"))), onChanged);
		}

		private void SyncText()
		{
			if ((Object)(object)ValueText != (Object)null)
			{
				ValueText.text = _format(Slider.value);
			}
		}

		private static Slider BuildSlider(Transform parent, float height)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0079: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_0160: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("slider", new Type[3]
			{
				typeof(RectTransform),
				typeof(Slider),
				typeof(LayoutElement)
			});
			val.transform.SetParent(parent, false);
			LayoutElement component = val.GetComponent<LayoutElement>();
			component.flexibleWidth = 1f;
			component.minWidth = 60f;
			component.preferredHeight = height;
			RectTransform rt = Child(val.transform, "track", TrackColor);
			Stretch(rt, new Vector2(0f, 0.35f), new Vector2(1f, 0.65f));
			GameObject val2 = new GameObject("fill_area", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent(val.transform, false);
			Stretch((RectTransform)val2.transform, new Vector2(0f, 0.35f), new Vector2(1f, 0.65f));
			RectTransform val3 = Child(val2.transform, "fill", GUIManager.Instance.ValheimOrange);
			Stretch(val3, Vector2.zero, new Vector2(0f, 1f));
			GameObject val4 = new GameObject("handle_area", new Type[1] { typeof(RectTransform) });
			val4.transform.SetParent(val.transform, false);
			RectTransform val5 = (RectTransform)val4.transform;
			Stretch(val5, Vector2.zero, Vector2.one);
			val5.offsetMin = new Vector2(6f, 0f);
			val5.offsetMax = new Vector2(-6f, 0f);
			RectTransform val6 = Child(val4.transform, "handle", HandleColor);
			val6.anchorMin = new Vector2(0f, 0f);
			val6.anchorMax = new Vector2(0f, 1f);
			val6.sizeDelta = new Vector2(12f, 0f);
			Slider component2 = val.GetComponent<Slider>();
			component2.fillRect = val3;
			component2.handleRect = val6;
			((Selectable)component2).targetGraphic = (Graphic)(object)((Component)val6).GetComponent<Image>();
			component2.direction = (Direction)0;
			return component2;
		}

		private static RectTransform Child(Transform parent, string name, Color color)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			((Graphic)val.GetComponent<Image>()).color = color;
			return (RectTransform)val.transform;
		}

		private static void Stretch(RectTransform rt, Vector2 anchorMin, Vector2 anchorMax)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0019: 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)
			rt.anchorMin = anchorMin;
			rt.anchorMax = anchorMax;
			Vector2 offsetMin = (rt.offsetMax = Vector2.zero);
			rt.offsetMin = offsetMin;
		}

		private static Text MakeText(Transform parent, string text, float width, int fontSize, TextAnchor anchor, bool flexible)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0068: 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)
			GameObject val = new GameObject("text", new Type[3]
			{
				typeof(RectTransform),
				typeof(Text),
				typeof(LayoutElement)
			});
			val.transform.SetParent(parent, false);
			Text component = val.GetComponent<Text>();
			component.font = GUIManager.Instance.AveriaSerifBold;
			component.fontSize = fontSize;
			component.alignment = anchor;
			((Graphic)component).color = new Color(0.72f, 0.65f, 0.5f);
			component.text = text;
			((Graphic)component).raycastTarget = false;
			LayoutElement component2 = val.GetComponent<LayoutElement>();
			component2.preferredWidth = width;
			component2.flexibleWidth = (flexible ? 1f : 0f);
			return component;
		}
	}
	public static class DrakeTabHost
	{
		private sealed class EscapeCloser : MonoBehaviour
		{
			private Action? _close;

			public void Bind(Action close)
			{
				_close = close;
			}

			private void Update()
			{
				if (((Component)this).gameObject.activeInHierarchy && _close != null && Input.GetKeyDown((KeyCode)27))
				{
					_close();
				}
			}
		}

		private const float TabWidth = 72f;

		private const float TabHeight = 28f;

		private const float TabGap = 4f;

		private const float StripOffsetY = 178f;

		private const float StripOffsetX = 8f;

		private static readonly List<DrakeTabRegistration> Registrations = new List<DrakeTabRegistration>();

		private static GameObject? _stripRoot;

		private static RectTransform? _tabStrip;

		private static readonly List<Button> _tabButtons = new List<Button>();

		private static ItemData? _currentItem;

		private static string? _activeTabId;

		private static Action? _onClosed;

		private static bool _opening;

		public static bool IsOpen => _currentItem != null && (!string.IsNullOrEmpty(_activeTabId) || (Object.op_Implicit((Object)(object)_stripRoot) && _stripRoot.activeSelf));

		public static string? ActiveTabId => _activeTabId;

		public static ItemData? CurrentItem => _currentItem;

		public static void Register(string id, string title, int priority, Func<ItemData, bool> isAvailable, Action<DrakeTabPageContext> show, Func<ItemData, bool>? claimDefault = null, Action? hide = null, Func<string>? getHintPhrase = null, Func<string>? getTitle = null)
		{
			if (string.IsNullOrEmpty(id))
			{
				return;
			}
			for (int i = 0; i < Registrations.Count; i++)
			{
				if (Registrations[i].Id == id)
				{
					Registrations[i] = new DrakeTabRegistration(id, title, priority, isAvailable, show, claimDefault, hide, getHintPhrase, getTitle);
					ApplyConfigOverride(Registrations[i]);
					return;
				}
			}
			DrakeTabRegistration drakeTabRegistration = new DrakeTabRegistration(id, title, priority, isAvailable, show, claimDefault, hide, getHintPhrase, getTitle);
			ApplyConfigOverride(drakeTabRegistration);
			Registrations.Add(drakeTabRegistration);
		}

		public static List<DrakeTabRegistration> GetUsableTabs(ItemData? item)
		{
			if (item == null)
			{
				return new List<DrakeTabRegistration>();
			}
			return GetAvailable(item).ToList();
		}

		public static int GetUsableCount(ItemData? item)
		{
			return GetUsableTabs(item).Count;
		}

		public static bool TryOpenInventoryContext(ItemData? item, string? preferredTabId = null, Action? onClosed = null)
		{
			return OpenForItem(item, preferredTabId, onClosed);
		}

		public static void SetPriority(string id, int priority)
		{
			DrakeTabRegistration drakeTabRegistration = Find(id);
			if (drakeTabRegistration != null)
			{
				drakeTabRegistration.Priority = priority;
				ApplyConfigOverride(drakeTabRegistration);
			}
		}

		public static void RaisePriority(string id, int delta)
		{
			SetPriority(id, (Find(id)?.Priority ?? 0) + delta);
		}

		public static bool TryGetPriority(string id, out int priority)
		{
			DrakeTabRegistration drakeTabRegistration = Find(id);
			if (drakeTabRegistration == null)
			{
				priority = 0;
				return false;
			}
			priority = drakeTabRegistration.Priority;
			return true;
		}

		public static bool OpenForItem(ItemData? item, string? preferredTabId = null, Action? onClosed = null)
		{
			if (item == null || GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				return false;
			}
			List<DrakeTabRegistration> list = GetAvailable(item).ToList();
			if (list.Count == 0)
			{
				return false;
			}
			_onClosed = onClosed;
			_currentItem = item;
			if (list.Count > 1)
			{
				EnsureTabStrip();
				if (!Object.op_Implicit((Object)(object)_stripRoot) || (Object)(object)_tabStrip == (Object)null)
				{
					return false;
				}
				RebuildTabs(list);
				_stripRoot.SetActive(true);
				_stripRoot.transform.SetAsLastSibling();
			}
			else
			{
				HideStrip();
			}
			string tabId = ResolveDefaultTabId(item, list, preferredTabId);
			SwitchTo(tabId, list, hidePrevious: false);
			return true;
		}

		public static void NotifyFeatureClosed(string? tabId = null)
		{
			if (!_opening && (string.IsNullOrEmpty(tabId) || _activeTabId == null || !(_activeTabId != tabId)))
			{
				_currentItem = null;
				_activeTabId = null;
				HideStrip();
				Action onClosed = _onClosed;
				_onClosed = null;
				onClosed?.Invoke();
			}
		}

		public static void Close()
		{
			if (!_opening)
			{
				DrakeTabRegistration drakeTabRegistration = Find(_activeTabId ?? "");
				_activeTabId = null;
				_currentItem = null;
				HideStrip();
				try
				{
					drakeTabRegistration?.Hide?.Invoke();
				}
				catch (Exception)
				{
				}
				Action onClosed = _onClosed;
				_onClosed = null;
				onClosed?.Invoke();
			}
		}

		private static void SwitchTo(string tabId, List<DrakeTabRegistration> available, bool hidePrevious = true)
		{
			DrakeTabRegistration drakeTabRegistration = available.FirstOrDefault((DrakeTabRegistration r) => r.Id == tabId) ?? available[0];
			string activeTabId = _activeTabId;
			if (hidePrevious && !string.IsNullOrEmpty(activeTabId) && activeTabId != drakeTabRegistration.Id)
			{
				try
				{
					Find(activeTabId)?.Hide?.Invoke();
				}
				catch (Exception)
				{
				}
			}
			_activeTabId = drakeTabRegistration.Id;
			HighlightTabs(available);
			_opening = true;
			try
			{
				Transform contentRoot = (Transform)(((Object)(object)_tabStrip != (Object)null) ? ((object)_tabStrip) : ((object)GUIManager.CustomGUIFront.transform));
				drakeTabRegistration.Show(new DrakeTabPageContext(_currentItem, drakeTabRegistration.Id, contentRoot));
			}
			catch (Exception)
			{
			}
			finally
			{
				_opening = false;
			}
			if (Object.op_Implicit((Object)(object)_stripRoot) && _stripRoot.activeSelf)
			{
				_stripRoot.transform.SetAsLastSibling();
			}
		}

		private static string ResolveDefaultTabId(ItemData item, List<DrakeTabRegistration> available, string? preferredTabId)
		{
			string forced = DrakeIntegrationConfig.ForceDefaultTabId;
			if (!string.IsNullOrWhiteSpace(forced) && available.Any((DrakeTabRegistration r) => r.Id == forced))
			{
				return forced;
			}
			if (!string.IsNullOrEmpty(preferredTabId) && available.Any((DrakeTabRegistration r) => r.Id == preferredTabId))
			{
				return preferredTabId;
			}
			if (!DrakeIntegrationConfig.DisableClaimDefault)
			{
				DrakeTabRegistration drakeTabRegistration = (from r in available
					where SafeClaim(r, item)
					orderby r.Priority descending
					select r).ThenBy<DrakeTabRegistration, string>((DrakeTabRegistration r) => r.Id, StringComparer.Ordinal).FirstOrDefault();
				if (drakeTabRegistration != null)
				{
					return drakeTabRegistration.Id;
				}
			}
			return available.OrderByDescending((DrakeTabRegistration r) => r.Priority).ThenBy<DrakeTabRegistration, string>((DrakeTabRegistration r) => r.Id, StringComparer.Ordinal).First()
				.Id;
		}

		private static bool SafeClaim(DrakeTabRegistration reg, ItemData item)
		{
			try
			{
				return reg.ClaimDefault(item);
			}
			catch
			{
				return false;
			}
		}

		private static IEnumerable<DrakeTabRegistration> GetAvailable(ItemData item)
		{
			foreach (DrakeTabRegistration reg in Registrations)
			{
				bool ok;
				try
				{
					ok = reg.IsAvailable(item);
				}
				catch
				{
					ok = false;
				}
				if (ok)
				{
					yield return reg;
				}
			}
		}

		private static DrakeTabRegistration? Find(string id)
		{
			return string.IsNullOrEmpty(id) ? null : Registrations.FirstOrDefault((DrakeTabRegistration r) => r.Id == id);
		}

		private static void ApplyConfigOverride(DrakeTabRegistration reg)
		{
			if (DrakeIntegrationConfig.TryGetPriorityOverride(reg.Id, out var priority))
			{
				reg.Priority = priority;
			}
		}

		private static void EnsureTabStrip()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0088: 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_00a3: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_stripRoot) && GUIManager.Instance != null && Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				_stripRoot = new GameObject("drake_tab_strip_root", new Type[1] { typeof(RectTransform) });
				_stripRoot.transform.SetParent(GUIManager.CustomGUIFront.transform, false);
				RectTransform component = _stripRoot.GetComponent<RectTransform>();
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0.5f, 0.5f);
				component.anchorMax = val;
				component.anchorMin = val;
				component.pivot = new Vector2(0.5f, 0.5f);
				component.anchoredPosition = new Vector2(8f, 178f);
				component.sizeDelta = new Vector2(280f, 36f);
				GameObject val2 = new GameObject("tabs", new Type[1] { typeof(RectTransform) });
				val2.transform.SetParent(_stripRoot.transform, false);
				_tabStrip = val2.GetComponent<RectTransform>();
				_tabStrip.anchorMin = new Vector2(1f, 0.5f);
				_tabStrip.anchorMax = new Vector2(1f, 0.5f);
				_tabStrip.pivot = new Vector2(1f, 0.5f);
				_tabStrip.anchoredPosition = Vector2.zero;
				_tabStrip.sizeDelta = new Vector2(280f, 32f);
				EscapeCloser escapeCloser = _stripRoot.AddComponent<EscapeCloser>();
				escapeCloser.Bind(Close);
				_stripRoot.SetActive(false);
			}
		}

		private static void HideStrip()
		{
			if (Object.op_Implicit((Object)(object)_stripRoot))
			{
				_stripRoot.SetActive(false);
			}
		}

		private static void RebuildTabs(List<DrakeTabRegistration> available)
		{
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Expected O, but got Unknown
			if ((Object)(object)_tabStrip == (Object)null || GUIManager.Instance == null)
			{
				return;
			}
			foreach (Button tabButton in _tabButtons)
			{
				if (Object.op_Implicit((Object)(object)tabButton))
				{
					Object.Destroy((Object)(object)((Component)tabButton).gameObject);
				}
			}
			_tabButtons.Clear();
			List<DrakeTabRegistration> list = available.OrderByDescending((DrakeTabRegistration r) => r.Priority).ThenBy<DrakeTabRegistration, string>((DrakeTabRegistration r) => r.Id, StringComparer.Ordinal).ToList();
			for (int num = 0; num < list.Count; num++)
			{
				DrakeTabRegistration drakeTabRegistration = list[num];
				int num2 = num;
				float num3 = 0f - ((float)num2 * 76f + 36f);
				Button val = DrakeButtonSfx.SoftenButton(GUIManager.Instance.CreateButton(drakeTabRegistration.Title, (Transform)(object)_tabStrip, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(num3, 0f), 72f, 28f));
				string capturedId = drakeTabRegistration.Id;
				((UnityEvent)val.onClick).AddListener((UnityAction)delegate
				{
					if (_currentItem != null)
					{
						List<DrakeTabRegistration> list2 = GetAvailable(_currentItem).ToList();
						if (list2.Count != 0 && !(capturedId == _activeTabId))
						{
							SwitchTo(capturedId, list2);
						}
					}
				});
				_tabButtons.Add(val);
			}
		}

		private static void HighlightTabs(List<DrakeTabRegistration> available)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			if (_tabButtons.Count == 0 || GUIManager.Instance == null)
			{
				return;
			}
			List<DrakeTabRegistration> list = available.OrderByDescending((DrakeTabRegistration r) => r.Priority).ThenBy<DrakeTabRegistration, string>((DrakeTabRegistration r) => r.Id, StringComparer.Ordinal).ToList();
			for (int num = 0; num < _tabButtons.Count && num < list.Count; num++)
			{
				Button val = _tabButtons[num];
				if (Object.op_Implicit((Object)(object)val))
				{
					Text componentInChildren = ((Component)val).GetComponentInChildren<Text>(true);
					if (Object.op_Implicit((Object)(object)componentInChildren))
					{
						bool flag = list[num].Id == _activeTabId;
						((Graphic)componentInChildren).color = (flag ? GUIManager.Instance.ValheimOrange : Color.white);
					}
				}
			}
		}
	}
	public sealed class DrakeTabPageContext
	{
		public ItemData Item { get; }

		public string TabId { get; }

		public Transform ContentRoot { get; }

		public DrakeTabPageContext(ItemData item, string tabId, Transform contentRoot)
		{
			Item = item;
			TabId = tabId ?? "";
			ContentRoot = contentRoot;
		}
	}
	public sealed class DrakeTabRegistration
	{
		private readonly string _fallbackTitle;

		public const int DefaultRenamePriority = 100;

		public const int DefaultFeaturePriority = 200;

		public const int DefaultReskinPriority = 50;

		public const string RenameItTabId = "renameit";

		public const string ReskinItTabId = "reskinit";

		public const string LockSmithKeyPassTabId = "locksmith.keypass";

		public string Id { get; }

		public string Title => SafeTitle();

		public int Priority { get; internal set; }

		public Func<ItemData, bool> IsAvailable { get; }

		public Func<ItemData, bool> ClaimDefault { get; }

		public Action<DrakeTabPageContext> Show { get; }

		public Action? Hide { get; }

		public Func<string> GetHintPhrase { get; }

		public Func<string> GetTitle { get; }

		public DrakeTabRegistration(string id, string title, int priority, Func<ItemData, bool> isAvailable, Action<DrakeTabPageContext> show, Func<ItemData, bool>? claimDefault = null, Action? hide = null, Func<string>? getHintPhrase = null, Func<string>? getTitle = null)
		{
			if (string.IsNullOrEmpty(id))
			{
				throw new ArgumentException("Tab id required.", "id");
			}
			Id = id;
			_fallbackTitle = (string.IsNullOrEmpty(title) ? id : title);
			Priority = priority;
			IsAvailable = isAvailable ?? ((Func<ItemData, bool>)((ItemData _) => false));
			Show = show ?? ((Action<DrakeTabPageContext>)delegate
			{
			});
			ClaimDefault = claimDefault ?? ((Func<ItemData, bool>)((ItemData _) => false));
			Hide = hide;
			GetHintPhrase = getHintPhrase ?? ((Func<string>)(() => ""));
			GetTitle = getTitle ?? ((Func<string>)(() => _fallbackTitle));
		}

		private string SafeTitle()
		{
			try
			{
				string text = GetTitle?.Invoke();
				return string.IsNullOrEmpty(text) ? _fallbackTitle : text;
			}
			catch
			{
				return _fallbackTitle;
			}
		}
	}
	public sealed class DrakeTextPromptPanel
	{
		private const float Width = 360f;

		private const float Height = 200f;

		private readonly string _panelName;

		private GameObject? _panel;

		private Text? _titleText;

		private InputField? _input;

		private Button? _okButton;

		private Button? _cancelButton;

		private Action<string>? _onOk;

		public bool IsOpen => Object.op_Implicit((Object)(object)_panel) && _panel.activeSelf;

		public DrakeTextPromptPanel(string panelName = "drake_text_prompt")
		{
			_panelName = (string.IsNullOrEmpty(panelName) ? "drake_text_prompt" : panelName);
		}

		public void Show(string title, string initialText, Action<string> onOk, Action? onCancel = null, int charLimit = 64, string okLabel = "Ok", string cancelLabel = "Cancel")
		{
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				return;
			}
			Ensure();
			if (Object.op_Implicit((Object)(object)_panel) && !((Object)(object)_titleText == (Object)null) && Object.op_Implicit((Object)(object)_input) && Object.op_Implicit((Object)(object)_okButton) && Object.op_Implicit((Object)(object)_cancelButton))
			{
				_onOk = onOk;
				_titleText.text = title ?? "";
				_input.characterLimit = Math.Max(1, charLimit);
				_input.text = initialText ?? "";
				SetButtonLabel(_okButton, okLabel);
				SetButtonLabel(_cancelButton, cancelLabel);
				((UnityEventBase)_cancelButton.onClick).RemoveAllListeners();
				((UnityEvent)_cancelButton.onClick).AddListener((UnityAction)delegate
				{
					Close();
					onCancel?.Invoke();
				});
				((UnityEventBase)_okButton.onClick).RemoveAllListeners();
				((UnityEvent)_okButton.onClick).AddListener((UnityAction)delegate
				{
					string obj = (((Object)(object)_input != (Object)null) ? _input.text.Trim() : "");
					Action<string> onOk2 = _onOk;
					Close();
					onOk2?.Invoke(obj);
				});
				_panel.SetActive(true);
				_panel.transform.SetAsLastSibling();
				DrakeGuiInput.EnsureBlocked();
				_input.ActivateInputField();
			}
		}

		public void Close()
		{
			if (Object.op_Implicit((Object)(object)_panel))
			{
				_panel.SetActive(false);
			}
			DrakeGuiInput.EnsureUnblocked();
			_onOk = null;
		}

		private void Ensure()
		{
			//IL_0048: 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_005c: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_panel) && GUIManager.Instance != null && Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				_panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 360f, 200f, false);
				((Object)_panel).name = _panelName;
				_titleText = GUIManager.Instance.CreateText("", _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -40f), GUIManager.Instance.AveriaSerifBold, 20, GUIManager.Instance.ValheimOrange, true, Color.black, 300f, 36f, false).GetComponent<Text>();
				_titleText.alignment = (TextAnchor)4;
				_input = GUIManager.Instance.CreateInputField(_panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 8f), (ContentType)0, "", 18, 300f, 34f).GetComponent<InputField>();
				_cancelButton = DrakeButtonSfx.SoftenButton(GUIManager.Instance.CreateButton("Cancel", _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(-70f, 36f), 110f, 30f));
				_okButton = DrakeButtonSfx.SoftenButton(GUIManager.Instance.CreateButton("Ok", _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(70f, 36f), 110f, 30f));
				DrakeButtonSfx.Soften(_panel);
				_panel.SetActive(false);
			}
		}

		private static void SetButtonLabel(Button button, string label)
		{
			Text componentInChildren = ((Component)button).GetComponentInChildren<Text>(true);
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				componentInChildren.text = label;
			}
		}
	}
	public static class DrakeToggleLayout
	{
		private const float DefaultBox = 24f;

		private const float LabelToBoxGap = 12f;

		public static void ApplyLabelLeftBoxRight(GameObject jotunnToggleGo, string labelText, float rowWidth = 260f, float rowHeight = 28f, float boxSize = 24f)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_00c2: 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_00dd: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: 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_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)jotunnToggleGo == (Object)null)
			{
				return;
			}
			RectTransform component = jotunnToggleGo.GetComponent<RectTransform>();
			Vector2 val = default(Vector2);
			if ((Object)(object)component != (Object)null)
			{
				((Vector2)(ref val))..ctor(0.5f, 0.5f);
				component.anchorMax = val;
				component.anchorMin = val;
				component.pivot = new Vector2(0.5f, 0.5f);
				component.anchoredPosition = Vector2.zero;
				component.sizeDelta = new Vector2((rowWidth > 0f) ? rowWidth : 260f, rowHeight);
			}
			Transform obj = jotunnToggleGo.transform.Find("Background");
			RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
			if (val2 != null)
			{
				((Vector2)(ref val))..ctor(1f, 0.5f);
				val2.anchorMax = val;
				val2.anchorMin = val;
				val2.pivot = new Vector2(1f, 0.5f);
				val2.anchoredPosition = new Vector2(-4f, 0f);
				val2.sizeDelta = new Vector2(boxSize, boxSize);
				Transform obj2 = ((Transform)val2).Find("Checkmark");
				RectTransform val3 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null);
				if (val3 != null)
				{
					((Vector2)(ref val))..ctor(0.5f, 0.5f);
					val3.anchorMax = val;
					val3.anchorMin = val;
					val3.pivot = new Vector2(0.5f, 0.5f);
					val3.anchoredPosition = Vector2.zero;
					val3.sizeDelta = new Vector2(boxSize * 0.67f, boxSize * 0.67f);
				}
			}
			Text componentInChildren = jotunnToggleGo.GetComponentInChildren<Text>(true);
			if (!((Object)(object)componentInChildren == (Object)null))
			{
				if (GUIManager.Instance != null)
				{
					componentInChildren.font = GUIManager.Instance.AveriaSerifBold;
					componentInChildren.fontSize = 16;
				}
				componentInChildren.text = labelText ?? "";
				((Graphic)componentInChildren).color = Color.white;
				componentInChildren.alignment = (TextAnchor)3;
				componentInChildren.horizontalOverflow = (HorizontalWrapMode)1;
				componentInChildren.verticalOverflow = (VerticalWrapMode)0;
				((Graphic)componentInChildren).raycastTarget = false;
				RectTransform rectTransform = ((Graphic)componentInChildren).rectTransform;
				rectTransform.anchorMin = new Vector2(0f, 0f);
				rectTransform.anchorMax = new Vector2(1f, 1f);
				rectTransform.pivot = new Vector2(0f, 0.5f);
				rectTransform.offsetMin = new Vector2(8f, 0f);
				rectTransform.offsetMax = new Vector2(0f - (boxSize + 12f), 0f);
			}
		}

		public static GameObject CreateRow(Transform parent, string name, Vector2 anchoredPosition, float width = 260f, float height = 28f)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0043: 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_005c: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			component.anchorMax = val2;
			component.anchorMin = val2;
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = anchoredPosition;
			component.sizeDelta = new Vector2(width, height);
			return val;
		}
	}
	public sealed class DrakeWoodActionMenu
	{
		private sealed class EscapeCloser : MonoBehaviour
		{
			private Action? _close;

			public void Bind(Action close)
			{
				_close = close;
			}

			private void Update()
			{
				if (((Component)this).gameObject.activeInHierarchy && _close != null && Input.GetKeyDown((KeyCode)27))
				{
					_close();
				}
			}
		}

		private const float CancelWidth = 64f;

		private const float HeaderTitleOnly = 58f;

		private const float HeaderWithSubtitle = 86f;

		private const float FooterWithCancel = 50f;

		private const float FooterNoCancel = 12f;

		private const float ContentPadding = 8f;

		private readonly string _panelName;

		private readonly DrakePanelOptions _options;

		private GameObject? _panel;

		private RectTransform? _panelRt;

		private Text? _titleText;

		private Text? _subtitleText;

		private ScrollRect? _scroll;

		private RectTransform? _scrollRt;

		private RectTransform? _content;

		private readonly List<Button> _actionButtons = new List<Button>();

		private Button? _cancelButton;

		private EscapeCloser? _escapeCloser;

		private Action? _onClosed;

		private bool _showCancel;

		public bool IsOpen => Object.op_Implicit((Object)(object)_panel) && _panel.activeSelf;

		public DrakeWoodActionMenu(string panelName = "drake_wood_action_menu", DrakePanelOptions? options = null)
		{
			_panelName = (string.IsNullOrEmpty(panelName) ? "drake_wood_action_menu" : panelName);
			_options = options ?? new DrakePanelOptions
			{
				Width = 320f,
				MinHeight = 240f,
				MaxHeight = 640f,
				ButtonWidth = 200f,
				ButtonHeight = 32f,
				RowGap = 40f
			};
		}

		public void Open(string title, string? subtitle, IReadOnlyList<DrakeMenuAction> actions, string cancelLabel = "Cancel", Action? onClosed = null, bool showCancel = true)
		{
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected O, but got Unknown
			if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				return;
			}
			_onClosed = onClosed;
			_showCancel = showCancel;
			EnsurePanel();
			if (!Object.op_Implicit((Object)(object)_panel) || (Object)(object)_titleText == (Object)null)
			{
				return;
			}
			_titleText.text = title ?? "";
			if ((Object)(object)_subtitleText != (Object)null)
			{
				bool flag = !string.IsNullOrEmpty(subtitle);
				((Component)_subtitleText).gameObject.SetActive(flag);
				if (flag)
				{
					_subtitleText.text = subtitle;
				}
			}
			IReadOnlyList<DrakeMenuAction> readOnlyList = actions ?? Array.Empty<DrakeMenuAction>();
			EnsureActionButtonCount(readOnlyList.Count);
			for (int i = 0; i < _actionButtons.Count; i++)
			{
				Button val = _actionButtons[i];
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				if (i >= readOnlyList.Count)
				{
					((Component)val).gameObject.SetActive(false);
					continue;
				}
				DrakeMenuAction drakeMenuAction = readOnlyList[i];
				((Component)val).gameObject.SetActive(true);
				((Selectable)val).interactable = drakeMenuAction.Enabled;
				Text componentInChildren = ((Component)val).GetComponentInChildren<Text>(true);
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					componentInChildren.text = drakeMenuAction.Label;
				}
				((UnityEventBase)val.onClick).RemoveAllListeners();
				DrakeMenuAction captured = drakeMenuAction;
				((UnityEvent)val.onClick).AddListener((UnityAction)delegate
				{
					if (!captured.Enabled)
					{
						return;
					}
					try
					{
						captured.OnClick();
					}
					catch (Exception)
					{
					}
				});
			}
			if (Object.op_Implicit((Object)(object)_cancelButton))
			{
				((Component)_cancelButton).gameObject.SetActive(showCancel);
				if (showCancel)
				{
					Text componentInChildren2 = ((Component)_cancelButton).GetComponentInChildren<Text>(true);
					if (Object.op_Implicit((Object)(object)componentInChildren2))
					{
						componentInChildren2.text = cancelLabel;
					}
				}
			}
			Layout(readOnlyList.Count, !string.IsNullOrEmpty(subtitle), showCancel);
			_panel.SetActive(true);
			_panel.transform.SetAsLastSibling();
			DrakeGuiInput.EnsureBlocked();
		}

		public void Close()
		{
			Close(invokeClosed: true);
		}

		public void CloseSilent()
		{
			Close(invokeClosed: false);
		}

		private void Close(bool invokeClosed)
		{
			if (Object.op_Implicit((Object)(object)_panel))
			{
				_panel.SetActive(false);
			}
			DrakeGuiInput.EnsureUnblocked();
			if (invokeClosed)
			{
				Action onClosed = _onClosed;
				_onClosed = null;
				onClosed?.Invoke();
			}
		}

		private void EnsurePanel()
		{
			//IL_005b: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Expected O, but got Unknown
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)_panel) && GUIManager.Instance != null && Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				_actionButtons.Clear();
				_panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), _options.Width, _options.MinHeight, false);
				((Object)_panel).name = _panelName;
				_panelRt = _panel.GetComponent<RectTransform>();
				_titleText = GUIManager.Instance.CreateText("", _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -40f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, _options.ButtonWidth + 40f, 36f, false).GetComponent<Text>();
				_titleText.alignment = (TextAnchor)4;
				_subtitleText = GUIManager.Instance.CreateText("", _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -72f), GUIManager.Instance.AveriaSerifBold, 14, new Color(1f, 0f, 1f), true, Color.black, _options.ButtonWidth + 40f, 28f, false).GetComponent<Text>();
				_subtitleText.alignment = (TextAnchor)4;
				((Component)_subtitleText).gameObject.SetActive(false);
				_scroll = DrakeLayout.CreateScrollArea(_panel.transform, "rows", _options.Width, 0f, Vector2.zero, out RectTransform content);
				_content = content;
				_scrollRt = (RectTransform)((Component)_scroll).transform;
				_cancelButton = DrakeButtonSfx.SoftenButton(GUIManager.Instance.CreateButton("Cancel", _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 36f), 64f, 28f));
				((UnityEvent)_cancelButton.onClick).AddListener(new UnityAction(Close));
				_escapeCloser = _panel.AddComponent<EscapeCloser>();
				_escapeCloser.Bind(Close);
				DrakeButtonSfx.Soften(_panel);
				_panel.SetActive(false);
			}
		}

		private void EnsureActionButtonCount(int needed)
		{
			//IL_0041: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_content) && GUIManager.Instance != null)
			{
				while (_actionButtons.Count < needed)
				{
					Button item = DrakeButtonSfx.SoftenButton(GUIManager.Instance.CreateButton("", ((Component)_content).transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), Vector2.zero, _options.ButtonWidth, _options.ButtonHeight));
					_actionButtons.Add(item);
				}
			}
		}

		private void Layout(int actionCount, bool hasSubtitle, bool showCancel)
		{
			//IL_00bf: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)_panelRt) || !Object.op_Implicit((Object)(object)_scrollRt) || !Object.op_Implicit((Object)(object)_scroll) || !Object.op_Implicit((Object)(object)_content))
			{
				return;
			}
			float num = (hasSubtitle ? 86f : 58f) + 8f;
			float num2 = (showCancel ? 50f : 12f) + 8f;
			float num3 = (float)Math.Max(actionCount, 1) * _options.RowGap;
			float num4 = Mathf.Clamp(num + num3 + num2, _options.MinHeight, _options.MaxHeight);
			float num5 = num4 - num - num2;
			_panelRt.sizeDelta = new Vector2(_options.Width, num4);
			_scrollRt.anchoredPosition = new Vector2(0f, 0f - num);
			_scrollRt.sizeDelta = new Vector2(_options.Width, num5);
			DrakeLayout.SetContentHeight(_scroll, num3, num5);
			for (int i = 0; i < _actionButtons.Count; i++)
			{
				Button val = _actionButtons[i];
				if (Object.op_Implicit((Object)(object)val) && ((Component)val).gameObject.activeSelf)
				{
					RectTransform component = ((Component)val).GetComponent<RectTransform>();
					if (Object.op_Implicit((Object)(object)component))
					{
						component.anchoredPosition = new Vector2(0f, 0f - (_options.RowGap / 2f + (float)i * _options.RowGap));
						component.sizeDelta = new Vector2(_options.ButtonWidth, _options.ButtonHeight);
					}
				}
			}
		}
	}
}
namespace DrakeModsLibs.Tags
{
	public delegate bool CustomizeEditValidator(ItemData? item, Player? player);
	public static class CustomizationGatekeeper
	{
		private sealed class DeferredAuthorityRegistration
		{
			public CustomizeOperation Operations;

			public DeferredEditHandler Handler = null;
		}

		private static readonly Dictionary<CustomizeOperation, List<CustomizeEditValidator>> Validators = new Dictionary<CustomizeOperation, List<CustomizeEditValidator>>();

		private static readonly List<TagBlockRule> TagBlockRules = new List<TagBlockRule>();

		private static readonly List<ItemExclusionRule> ItemExclusions = new List<ItemExclusionRule>();

		private static readonly Dictionary<string, DeferredAuthorityRegistration> DeferredAuthorities = new Dictionary<string, DeferredAuthorityRegistration>(StringComparer.OrdinalIgnoreCase);

		private static bool _defaultTagRulesRegistered;

		public static Func<Player?, bool>? TagBypass { get; set; }

		private static void EnsureDefaultTagRules()
		{
			if (!_defaultTagRulesRegistered)
			{
				_defaultTagRulesRegistered = true;
				RegisterTagBlockRule("Drake_NoRename", CustomizeOperation.RenameName, suppressRenameInventoryUi: true);
				RegisterTagBlockRule("Drake_NoDesc", CustomizeOperation.RenameDescription);
				RegisterTagBlockRule("Drake_NoCraftedByEdit", CustomizeOperation.EditCraftedBy);
				RegisterTagBlockRule("Drake_QuestItem", CustomizeOperation.AllEdits, suppressRenameInventoryUi: true);
				RegisterTagBlockRule("Drake_HardNoRename", CustomizeOperation.RenameName, suppressRenameInventoryUi: true, hardLock: true);
				RegisterTagBlockRule("Drake_HardNoDesc", CustomizeOperation.RenameDescription, suppressRenameInventoryUi: false, hardLock: true);
				RegisterTagBlockRule("Drake_HardNoCraftedBy", CustomizeOperation.EditCraftedBy, suppressRenameInventoryUi: false, hardLock: true);
				RegisterTagBlockRule("Drake_Immutable", CustomizeOperation.AllEdits, suppressRenameInventoryUi: true, hardLock: true);
				RegisterTagBlockRule("Drake_QuestItem", CustomizeOperation.ReskinIcon | CustomizeOperation.ReskinModel | CustomizeOperation.ReskinColor);
				RegisterTagBlockRule("Drake_Immutable", CustomizeOperation.ReskinIcon | CustomizeOperation.ReskinModel | CustomizeOperation.ReskinColor, suppressRenameInventoryUi: false, hardLock: true);
				RegisterTagBlockRule("Drake_DeferSuppressUi", CustomizeOperation.None, suppressRenameInventoryUi: true);
			}
		}

		public static void RegisterTagBlockRule(string tagKey, CustomizeOperation blockedOperations)
		{
			RegisterTagBlockRule(tagKey, blockedOperations, suppressRenameInventoryUi: false, hardLock: false);
		}

		public static void RegisterTagBlockRule(string tagKey, CustomizeOperation blockedOperations, bool suppressRenameInventoryUi)
		{
			RegisterTagBlockRule(tagKey, blockedOperations, suppressRenameInventoryUi, hardLock: false);
		}

		public static void RegisterTagBlockRule(string tagKey, CustomizeOperation blockedOperations, bool suppressRenameInventoryUi, bool hardLock)
		{
			if (!string.IsNullOrEmpty(tagKey))
			{
				TagBlockRules.Add(new TagBlockRule(tagKey, blockedOperations, suppressRenameInventoryUi, hardLock));
			}
		}

		public static void RegisterItemExclusion(ItemExclusionRule rule)
		{
			if (!string.IsNullOrWhiteSpace(rule.Match) && rule.BlockedOperations != CustomizeOperation.None)
			{
				ItemExclusions.Add(rule);
			}
		}

		public static void RegisterValidator(CustomizeOperation operation, CustomizeEditValidator validator)
		{
			if (!Validators.TryGetValue(operation, out List<CustomizeEditValidator> value))
			{
				value = new List<CustomizeEditValidator>();
				Validators[operation] = value;
			}
			value.Add(validator);
		}

		public static void RegisterDeferredEditAuthority(string authorityId, CustomizeOperation operations, DeferredEditHandler handler)
		{
			if (!string.IsNullOrEmpty(authorityId) && handler != null && operations != CustomizeOperation.None)
			{
				DeferredAuthorities[authorityId] = new DeferredAuthorityRegistration
				{
					Operations = operations,
					Handler = handler
				};
			}
		}

		public static bool IsBlockedByTag(CustomizeOperation operation, ItemData? item)
		{
			if (item == null)
			{
				return true;
			}
			EnsureDefaultTagRules();
			foreach (TagBlockRule tagBlockRule in TagBlockRules)
			{
				if ((tagBlockRule.BlockedOperations & operation) == 0 || !DrakeTagManager.HasTag(item, tagBlockRule.TagKey))
				{
					continue;
				}
				return true;
			}
			return IsSoftOrHardExcluded(operation, item);
		}

		public static bool IsHardBlockedByTag(CustomizeOperation operation, ItemData? item)
		{
			if (item == null)
			{
				return true;
			}
			EnsureDefaultTagRules();
			foreach (TagBlockRule tagBlockRule in TagBlockRules)
			{
				if (!tagBlockRule.HardLock || (tagBlockRule.BlockedOperations & operation) == 0 || !DrakeTagManager.HasTag(item, tagBlockRule.TagKey))
				{
					continue;
				}
				return true;
			}
			return IsHardExcluded(operation, item);
		}

		public static bool IsDeferredFor(CustomizeOperation operation, ItemData? item)
		{
			if (item == null || operation == CustomizeOperation.None)
			{
				return false;
			}
			if (DrakeTagManager.HasTag(item, "Drake_DeferEdits") && (operation & CustomizeOperation.AllEdits) != CustomizeOperation.None)
			{
				return true;
			}
			if ((operation & CustomizeOperation.RenameName) != CustomizeOperation.None && DrakeTagManager.HasTag(item, "Drake_DeferRename"))
			{
				return true;
			}
			if ((operation & CustomizeOperation.RenameDescription) != CustomizeOperation.None && DrakeTagManager.HasTag(item, "Drake_DeferDesc"))
			{
				return true;
			}
			if ((operation & CustomizeOperation.EditCraftedBy) != CustomizeOperation.None && DrakeTagManager.HasTag(item, "Drake_DeferCraftedBy"))
			{
				return true;
			}
			string authorityId;
			return TryGetDeferredExclusionAuthority(operation, item, out authorityId);
		}

		public static string? GetEditAuthorityId(ItemData? item)
		{
			if (item?.m_customData == null)
			{
				return null;
			}
			if (!item.m_customData.TryGetValue("Drake_EditAuthority", out var value))
			{
				return null;
			}
			return string.IsNullOrWhiteSpace(value) ? null : value.Trim();
		}

		public static bool TryEvaluateDeferred(CustomizeOperation operation, ItemData? item, Player? player, out bool allowed)
		{
			allowed = false;
			if (!IsDeferredFor(operation, item))
			{
				return false;
			}
			string authorityId = GetEditAuthorityId(item);
			if (authorityId == null)
			{
				TryGetDeferredExclusionAuthority(operation, item, out authorityId);
			}
			if (authorityId == null || !DeferredAuthorities.TryGetValue(authorityId, out DeferredAuthorityRegistration value) || (value.Operations & operation) == 0)
			{
				allowed = false;
				return true;
			}
			try
			{
				allowed = value.Handler(item, player, operation);
			}
			catch (Exception)
			{
				allowed = false;
			}
			return true;
		}

		public static bool IsRenameInventorySuppressed(ItemData? item)
		{
			return IsRenameInventorySuppressed(item, Player.m_localPlayer);
		}

		public static bool IsRenameInventorySuppressed(ItemData? item, Player? player)
		{
			if (item == null)
			{
				return false;
			}
			EnsureDefaultTagRules();
			bool flag = false;
			try
			{
				flag = TagBypass?.Invoke(player) ?? false;
			}
			catch
			{
				flag = false;
			}
			foreach (TagBlockRule tagBlockRule in TagBlockRules)
			{
				if (tagBlockRule.SuppressRenameInventoryUi && DrakeTagManager.HasTag(item, tagBlockRule.TagKey))
				{
					if (tagBlockRule.HardLock)
					{
						return true;
					}
					if (!flag)
					{
						return true;
					}
				}
			}
			foreach (ItemExclusionRule itemExclusion in ItemExclusions)
			{
				if (itemExclusion.SuppressRenameInventoryUi && ItemNameMatch.Matches(item, itemExclusion.Match))
				{
					if (itemExclusion.HardLock)
					{
						return true;
					}
					if (!flag)
					{
						return true;
					}
				}
			}
			return false;
		}

		public static bool CanPerform(CustomizeOperation operation, ItemData? item, Player? player)
		{
			if (item == null)
			{
				return false;
			}
			EnsureDefaultTagRules();
			if (IsHardBlockedByTag(operation, item))
			{
				return false;
			}
			if (TryEvaluateDeferred(operation, item, player, out var allowed))
			{
				if (!allowed)
				{
					return false;
				}
				return RunValidators(operation, item, player);
			}
			if (IsSoftBlocked(operation, item))
			{
				Func<Player?, bool>? tagBypass = TagBypass;
				if (tagBypass == null || !tagBypass(player))
				{
					return false;
				}
			}
			return RunValidators(operation, item, player);
		}

		private static bool IsSoftBlocked(CustomizeOperation operation, ItemData? item)
		{
			foreach (TagBlockRule tagBlockRule in TagBlockRules)
			{
				if (tagBlockRule.HardLock || (tagBlockRule.BlockedOperations & operation) == 0 || !DrakeTagManager.HasTag(item, tagBlockRule.TagKey))
				{
					continue;
				}
				return true;
			}
			foreach (ItemExclusionRule itemExclusion in ItemExclusions)
			{
				if (itemExclusion.IsDeferred || itemExclusion.HardLock || (itemExclusion.BlockedOperations & operation) == 0 || !ItemNameMatch.Matches(item, itemExclusion.Match))
				{
					continue;
				}
				return true;
			}
			return false;
		}

		private static bool IsHardExcluded(CustomizeOperation operation, ItemData? item)
		{
			foreach (ItemExclusionRule itemExclusion in ItemExclusions)
			{
				if (!itemExclusion.HardLock || itemExclusion.IsDeferred || (itemExclusion.BlockedOperations & operation) == 0 || !ItemNameMatch.Matches(item, itemExclusion.Match))
				{
					continue;
				}
				return true;
			}
			return false;
		}

		private static bool IsSoftOrHardExcluded(CustomizeOperation operation, ItemData? item)
		{
			foreach (ItemExclusionRule itemExclusion in ItemExclusions)
			{
				if (itemExclusion.IsDeferred || (itemExclusion.BlockedOperations & operation) == 0 || !ItemNameMatch.Matches(item, itemExclusion.Match))
				{
					continue;
				}
				return true;
			}
			return false;
		}

		private static bool TryGetDeferredExclusionAuthority(CustomizeOperation operation, ItemData? item, out string? authorityId)
		{
			authorityId = null;
			foreach (ItemExclusionRule itemExclusion in ItemExclusions)
			{
				if (!itemExclusion.IsDeferred || (itemExclusion.BlockedOperations & operation) == 0 || !ItemNameMatch.Matches(item, itemExclusion.Match))
				{
					continue;
				}
				authorityId = itemExclusion.DeferredAuthorityId;
				return true;
			}
			return false;
		}

		private static bool RunValidators(CustomizeOperation operation, ItemData? item, Player? player)
		{
			if (!Validators.TryGetValue(operation, out List<CustomizeEditValidator> value) || value.Count == 0)
			{
				return true;
			}
			foreach (CustomizeEditValidator item2 in value)
			{
				if (!item2(item, player))
				{
					return false;
				}
			}
			return true;
		}
	}
	public static class DrakeTagManager
	{
		public static bool HasTag(ItemData? item, string tagKey)
		{
			if (item?.m_customData == null || string.IsNullOrEmpty(tagKey))
			{
				return false;
			}
			string value;
			return item.m_customData.TryGetValue(tagKey, out value) && (value == "1" || string.Equals(value, "true", StringComparison.OrdinalIgnoreCase));
		}

		public static void SetTag(ItemData item, string tagKey)
		{
			if (!string.IsNullOrEmpty(tagKey))
			{
				if (item.m_customData == null)
				{
					item.m_customData = new Dictionary<string, string>();
				}
				item.m_customData[tagKey] = "1";
			}
		}

		public static void ClearTag(ItemData item, string tagKey)
		{
			if (item.m_customData != null && !string.IsNullOrEmpty(tagKey))
			{
				item.m_customData.Remove(tagKey);
			}
		}
	}
	internal static class ItemNameMatch
	{
		public static bool Matches(ItemData? item, string? token)
		{
			if (item?.m_shared == null || string.IsNullOrWhiteSpace(token))
			{
				return false;
			}
			token = token.Trim();
			string name = item.m_shared.m_name;
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			if (name.Equals(token, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if ((Object)(object)item.m_dropPrefab != (Object)null && !string.IsNullOrEmpty(((Object)item.m_dropPrefab).name) && ((Object)item.m_dropPrefab).name.Equals(token, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if (Localization.instance != null)
			{
				string text = Localization.instance.Localize(name);
				if (!string.IsNullOrEmpty(text) && text.Equals(token, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}
	}
}
namespace DrakeModsLibs.Progression
{
	public static class DrakeDiscovery
	{
		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		private static class CraftTrackingPatch
		{
			private static void Postfix(Player player)
			{
				try
				{
					if ((Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer)
					{
						RecordCraftedFromInventory(player);
					}
				}
				catch (Exception)
				{
				}
			}
		}

		public const string CraftedKey = "Drake_Crafted";

		private static Player? _cachedFor;

		private static string? _cachedRaw;

		private static HashSet<string> _crafted = new HashSet<string>(StringComparer.Ordinal);

		private static HashSet<string>? _craftable;

		private static ObjectDB? _craftableFor;

		public static bool HasSeen(Player? player, string sharedName)
		{
			return (Object)(object)player != (Object)null && !string.IsNullOrEmpty(sharedName) && player.IsMaterialKnown(sharedName);
		}

		public static bool HasCrafted(Player? player, string prefabName)
		{
			return (Object)(object)player != (Object)null && !string.IsNullOrEmpty(prefabName) && Load(player).Contains(prefabName);
		}

		public static bool IsCraftable(string prefabName)
		{
			ObjectDB instance = ObjectDB.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			if (_craftable == null || (Object)(object)_craftableFor != (Object)(object)instance)
			{
				_craftableFor = instance;
				_craftable = new HashSet<string>(from r in instance.m_recipes
					where (Object)(object)r != (Object)null && r.m_enabled && (Object)(object)r.m_item != (Object)null
					select ((Object)((Component)r.m_item).gameObject).name, StringComparer.Ordinal);
			}
			return _craftable.Contains(prefabName);
		}

		public static void RecordCraftedFromInventory(Player player)
		{
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return;
			}
			long playerID = player.GetPlayerID();
			HashSet<string> hashSet = Load(player);
			bool flag = false;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				string text = (Object.op_Implicit((Object)(object)allItem?.m_dropPrefab) ? ((Object)allItem.m_dropPrefab).name : null);
				if (allItem != null && allItem.m_crafterID == playerID && !string.IsNullOrEmpty(text) && hashSet.Add(text))
				{
					flag = true;
				}
			}
			if (flag)
			{
				Save(player, hashSet);
			}
		}

		private static HashSet<string> Load(Player player)
		{
			player.m_customData.TryGetValue("Drake_Crafted", out var value);
			if (value == null)
			{
				value = "";
			}
			if ((Object)(object)_cachedFor != (Object)(object)player || !string.Equals(value, _cachedRaw, StringComparison.Ordinal))
			{
				_cachedFor = player;
				_cachedRaw = value;
				_crafted = new HashSet<string>(from s in value.Split(new char[1] { ',' })
					where s.Length > 0
					select s, StringComparer.Ordinal);
			}
			return _crafted;
		}

		private static void Save(Player player, HashSet<string> set)
		{
			string text = string.Join(",", set.OrderBy<string, string>((string s) => s, StringComparer.Ordinal));
			player.m_customData["Drake_Crafted"] = text;
			_cachedRaw = text;
		}
	}
	public static class DrakeProgression
	{
		public static readonly string[] BossKeys = new string[7] { "defeated_eikthyr", "defeated_gdking", "defeated_bonemass", "defeated_dragon", "defeated_goblinking", "defeated_queen", "defeated_fader" };

		private static readonly Dictionary<string, string> BossNames = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			["defeated_eikthyr"] = "Eikthyr",
			["defeated_gdking"] = "The Elder",
			["defeated_bonemass"] = "Bonemass",
			["defeated_dragon"] = "Moder",
			["defeated_goblinking"] = "Yagluth",
			["defeated_queen"] = "The Queen",
			["defeated_fader"] = "Fader"
		};

		private static readonly Dictionary<string, string[]> Anchors = new Dictionary<string, string[]>
		{
			["defeated_eikthyr"] = new string[8] { "HardAntler", "CopperOre", "Copper", "CopperScrap", "TinOre", "Tin", "Bronze", "TrophyEikthyr" },
			["defeated_gdking"] = new string[13]
			{
				"CryptKey", "IronScrap", "IronOre", "Iron", "ElderBark", "Chain", "Ooze", "WitheredBone", "Root", "Guck",
				"Entrails", "BloodBag", "TrophyTheElder"
			},
			["defeated_bonemass"] = new string[12]
			{
				"Wishbone", "SilverOre", "Silver", "Obsidian", "WolfPelt", "WolfFang", "WolfClaw", "FreezeGland", "DragonEgg", "Crystal",
				"JuteRed", "TrophyBonemass"
			},
			["defeated_dragon"] = new string[11]
			{
				"DragonTear", "BlackMetalScrap", "BlackMetal", "Barley", "Flax", "LoxPelt", "LoxMeat", "Needle", "Tar", "GoblinTotem",
				"TrophyDragonQueen"
			},
			["defeated_goblinking"] = new string[13]
			{
				"YagluthDrop", "Sap", "SoftTissue", "Eitr", "BlackCore", "Carapace", "Mandible", "YggdrasilWood", "ScaleHide", "BlackMarble",
				"Bilebag", "RoyalJelly", "TrophyGoblinKing"
			},
			["defeated_queen"] = new string[15]
			{
				"QueenDrop", "FlametalOre", "Flametal", "FlametalOreNew", "FlametalNew", "CharredBone", "AskHide", "AskBladder", "Blackwood", "Grausten",
				"MoltenCore", "CelestialFeather", "MorgenSinew", "MorgenHeart", "TrophySeekerQueen"
			},
			["defeated_fader"] = new string[2] { "FaderDrop", "TrophyFader" }
		};

		private static Dictionary<string, int>? _anchorIndex;

		private static readonly Dictionary<string, int> Derived = new Dictionary<string, int>(StringComparer.Ordinal);

		private static Dictionary<string, List<Recipe>>? _recipesByItem;

		private static ObjectDB? _builtFor;

		public static string DescribeKey(string key)
		{
			string value;
			return BossNames.TryGetValue(key, out value) ? value : key;
		}

		public static bool IsKeyUnlocked(string key, Player? player)
		{
			if (string.IsNullOrEmpty(key))
			{
				return true;
			}
			if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey(key))
			{
				return true;
			}
			return (Object)(object)player != (Object)null && ((Humanoid)player).HaveUniqueKey(key);
		}

		public static string? RequiredKey(string prefabName, IReadOnlyDictionary<string, string>? overrides = null, IReadOnlyDictionary<string, string>? aliases = null)
		{
			if (string.IsNullOrEmpty(prefabName))
			{
				return null;
			}
			if (overrides != null && overrides.TryGetValue(prefabName, out string value))
			{
				return (string.IsNullOrWhiteSpace(value) || value.Equals("none", StringComparison.OrdinalIgnoreCase)) ? null : value;
			}
			int num = TierOf(prefabName);
			if (num < 0)
			{
				return null;
			}
			string text = BossKeys[num];
			string value2;
			return (aliases != null && aliases.TryGetValue(text, out value2) && !string.IsNullOrWhiteSpace(value2)) ? value2 : text;
		}

		public static Dictionary<string, string> ParsePairs(string? csv)
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			if (string.IsNullOrWhiteSpace(csv))
			{
				return dictionary;
			}
			string[] array = csv.Split(',', ';');
			foreach (string text in array)
			{
				int num = text.IndexOf('=');
				if (num > 0)
				{
					string text2 = text.Substring(0, num).Trim();
					if (text2.Length > 0)
					{
						dictionary[text2] = text.Substring(num + 1).Trim();
					}
				}
			}
			return dictionary;
		}

		private static int TierOf(string prefabName)
		{
			EnsureBuilt();
			return Resolve(prefabName, new HashSet<string>(StringComparer.Ordinal));
		}

		private static int Resolve(string prefabName, HashSet<string> visiting)
		{
			if (Derived.TryGetValue(prefabName, out var value))
			{
				return value;
			}
			if (!visiting.Add(prefabName))
			{
				return -1;
			}
			int value2;
			int num = (_anchorIndex.TryGetValue(prefabName, out value2) ? value2 : (-1));
			if (_recipesByItem.TryGetValue(prefabName, out List<Recipe> value3))
			{
				int num2 = int.MaxValue;
				foreach (Recipe item in value3)
				{
					int num3 = -1;
					Requirement[] array = item.m_resources ?? Array.Empty<Requirement>();
					foreach (Requirement val in array)
					{
						if ((Object)(object)val?.m_resItem != (Object)null)
						{
							num3 = Math.Max(num3, Resolve(((Object)((Component)val.m_resItem).gameObject).name, visiting));
						}
					}
					num2 = Math.Min(num2, num3);
				}
				if (num2 != int.MaxValue)
				{
					num = Math.Max(num, num2);
				}
			}
			visiting.Remove(prefabName);
			Derived[prefabName] = num;
			return num;
		}

		private static void EnsureBuilt()
		{
			ObjectDB instance = ObjectDB.instance;
			if (_anchorIndex == null)
			{
				_anchorIndex = new Dictionary<string, int>(StringComparer.Ordinal);
				for (int i = 0; i < BossKeys.Length; i++)
				{
					string[] array = Anchors[BossKeys[i]];
					foreach (string key in array)
					{
						_anchorIndex[key] = i;
					}
				}
			}
			if (_recipesByItem != null && (Object)(object)_builtFor == (Object)(object)instance)
			{
				return;
			}
			_builtFor = instance;
			Derived.Clear();
			_recipesByItem = new Dictionary<string, List<Recipe>>(StringComparer.Ordinal);
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			foreach (Recipe item in instance.m_recipes.Where((Recipe r) => (Object)(object)r != (Object)null && r.m_enabled && (Object)(object)r.m_item != (Object)null))
			{
				string name = ((Object)((Component)item.m_item).gameObject).name;
				if (!_recipesByItem.TryGetValue(name, out List<Recipe> value))
				{
					value = (_recipesByItem[name] = new List<Recipe>());
				}
				value.Add(item);
			}
		}
	}
}
namespace DrakeModsLibs.Permissions
{
	public static class DrakeItemCategory
	{
		private static readonly Dictionary<string, Func<ItemData, bool>> Aliases = new Dictionary<string, Func<ItemData, bool>>(StringComparer.OrdinalIgnoreCase)
		{
			["armor"] = delegate(ItemData i)
			{
				//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: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Invalid comparison between Unknown and I4
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Invalid comparison between Unknown and I4
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Invalid comparison between Unknown and I4
				ItemType itemType = i.m_shared.m_itemType;
				return (itemType - 6 <= 1 || (int)itemType == 11 || (int)itemType == 17) ? true : false;
			},
			["weapons"] = delegate(ItemData i)
			{
				//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: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Invalid comparison between Unknown and I4
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Invalid comparison between Unknown and I4
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Invalid comparison between Unknown and I4
				ItemType itemType = i.m_shared.m_itemType;
				return (itemType - 3 <= 1 || (int)itemType == 14 || (int)itemType == 22) ? true : false;
			},
			["tools"] = delegate(ItemData i)
			{
				//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_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Invalid comparison between Unknown and I4
				SkillType skillType = i.m_shared.m_skillType;
				return skillType - 12 <= 1;
			},
			["ranged"] = delegate(ItemData i)
			{
				//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_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_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Invalid comparison between Unknown and I4
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Invalid comparison between Unknown and I4
				ItemType itemType = i.m_shared.m_itemType;
				bool flag = (((int)itemType == 4 || (int)itemType == 9) ? true : false);
				bool flag2 = flag;
				bool flag3 = flag2;
				if (!flag3)
				{
					SkillType skillType = i.m_shared.m_skillType;
					bool flag4 = (((int)skillType == 8 || (int)skillType == 14) ? true : false);
					flag3 = flag4;
				}
				return flag3;
			},
			["melee"] = delegate(ItemData i)
			{
				//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: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Expected I4, but got Unknown
				SkillType skillType = i.m_shared.m_skillType;
				switch (skillType - 1)
				{
				case 0:
				case 1:
				case 2:
				case 3:
				case 4:
				case 6:
				case 10:
				case 11:
					return true;
				default:
					return false;
				}
			},
			["shields"] = (ItemData i) => (int)i.m_shared.m_itemType == 5,
			["ammo"] = (ItemData i) => (int)i.m_shared.m_itemType == 9,
			["fish"] = (ItemData i) => (int)i.m_shared.m_itemType == 21
		};

		public static void RegisterAlias(string token, Func<ItemData, bool> matches)
		{
			if (!string.IsNullOrWhiteSpace(token) && matches != null)
			{