Decompiled source of BetrValheim v4.46.0

plugins/BetrValheim.dll

Decompiled 2 hours 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.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BetrValheim.Collect;
using BetrValheim.Config;
using BetrValheim.Core;
using BetrValheim.Crafting;
using BetrValheim.Drawers;
using BetrValheim.Portals;
using BetrValheim.Refill;
using BetrValheim.UI;
using BetrValheim.Visuals;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.UI;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("DezzyCode")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("DezzyCode")]
[assembly: AssemblyDescription("Craft from containers and auto-fill refineries and production stations.")]
[assembly: AssemblyFileVersion("4.46.0.0")]
[assembly: AssemblyInformationalVersion("4.46.0+3212dc9cbc61f28e0929e6ecae7ff2453368044d")]
[assembly: AssemblyProduct("BetrValheim")]
[assembly: AssemblyTitle("BetrValheim")]
[assembly: AssemblyVersion("4.46.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BetrValheim
{
	[BepInPlugin("dezzycode.valheim.easywork", "BetrValheim", "4.46.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal sealed class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ZNetScene), "Awake")]
		private static class SceneAwake
		{
			private static void Postfix()
			{
				OnWorldChanged();
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		private static class ObjectDbAwake
		{
			private static void Postfix()
			{
				ItemNames.Invalidate();
				DrawerItems.Reset();
				ItemSources.InvalidateCounts();
			}
		}

		[HarmonyPatch(typeof(Game), "Logout")]
		private static class GameLogout
		{
			private static void Prefix()
			{
				OnWorldChanged();
			}
		}

		public const string Guid = "dezzycode.valheim.easywork";

		public const string Name = "BetrValheim";

		public const string Version = "4.46.0";

		private Harmony _harmony;

		public static readonly List<string> PatchFailures = new List<string>();

		public static Plugin Instance { get; private set; }

		public static bool Active
		{
			get
			{
				if (Cfg.ModEnabled != null && Cfg.ModEnabled.Value && (Object)(object)ZNetScene.instance != (Object)null)
				{
					return (Object)(object)Player.m_localPlayer != (Object)null;
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			Instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			Cfg.Bind(((BaseUnityPlugin)this).Config);
			((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged;
			Filters.Init();
			PortalNetwork.Init();
			MutedMist.Init();
			MutedSails.Init();
			MinimapLogo.Init();
			_harmony = new Harmony("dezzycode.valheim.easywork");
			ApplyPatches();
			GUIManager.OnCustomGUIAvailable += BetrValheimPanel.Build;
			SynchronizationManager.OnConfigurationSynchronized += OnConfigSynchronized;
			if (PatchFailures.Count == 0)
			{
				Log.Info("BetrValheim 4.46.0 loaded, all patches applied.");
				return;
			}
			Log.Error(string.Format("{0} {1} loaded with {2} failed patch(es): ", "BetrValheim", "4.46.0", PatchFailures.Count) + string.Join(", ", PatchFailures.ToArray()));
			Log.Error("The affected feature is off. Please report this log line.");
		}

		private void ApplyPatches()
		{
			PatchFailures.Clear();
			Type[] types = typeof(Plugin).Assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0)
				{
					try
					{
						_harmony.CreateClassProcessor(type).Patch();
						Log.Debug("Patched " + type.FullName + ".");
					}
					catch (Exception ex)
					{
						PatchFailures.Add(type.Name);
						Log.Error("Patch " + type.FullName + " failed: " + ex.Message);
					}
				}
			}
		}

		private void Start()
		{
			DrawerPiece.Register();
		}

		private void OnDestroy()
		{
			GUIManager.OnCustomGUIAvailable -= BetrValheimPanel.Build;
			SynchronizationManager.OnConfigurationSynchronized -= OnConfigSynchronized;
			((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged;
			BetrValheimPanel.Destroy();
			ExtraInventory.DestroyHud();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private static void OnConfigSynchronized(object sender, ConfigurationSynchronizationEventArgs args)
		{
			if (args.UpdatedPluginGUIDs == null || args.UpdatedPluginGUIDs.Contains("dezzycode.valheim.easywork"))
			{
				ItemSources.InvalidateCounts();
				Log.Info(args.InitialSynchronization ? "Server configuration received." : "Server configuration updated.");
				BetrValheimPanel.RefreshValues();
				Refiller.Reset();
				Collector.Reset();
			}
		}

		private static void OnSettingChanged(object sender, SettingChangedEventArgs args)
		{
			ItemSources.InvalidateCounts();
		}

		private void Update()
		{
			PortalNetwork.Tick();
			if (!GUIManager.IsHeadless())
			{
				BetrValheimPanel.CloseOnEscapeWithoutMenu();
				ExtraInventory.Tick();
				DrawerIndex.TickAll();
				if (HotkeyPressed())
				{
					BetrValheimPanel.Toggle();
				}
				Refiller.Tick(Player.m_localPlayer);
				Collector.Tick(Player.m_localPlayer);
			}
		}

		private static bool HotkeyPressed()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (GUIManager.IsHeadless() || Cfg.ToggleKey == null || ZInput.instance == null)
			{
				return false;
			}
			if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus())
			{
				return false;
			}
			KeyboardShortcut value = Cfg.ToggleKey.Value;
			return ((KeyboardShortcut)(ref value)).IsDown();
		}

		public static void OnWorldChanged()
		{
			ContainerIndex.Clear();
			StationIndex.Clear();
			StationKinds.ClearCache();
			ItemNames.Invalidate();
			DrawerItems.Reset();
			ItemSources.InvalidateCounts();
			Prefab.ClearCache();
			Refiller.Reset();
			Collector.Reset();
			BatchCrafting.Reset();
			CraftingScope.Reset();
		}
	}
}
namespace BetrValheim.Visuals
{
	internal static class MutedMist
	{
		[HarmonyPatch(typeof(ParticleMist), "Awake")]
		private static class MistAwakePatch
		{
			private static void Postfix()
			{
				Apply();
			}
		}

		private static ParticleMist _mist;

		private static Material _material;

		private static float _originalAlpha;

		private static float Opacity
		{
			get
			{
				if (Cfg.MistOpacity == null)
				{
					return 1f;
				}
				return Mathf.Clamp01((float)Cfg.MistOpacity.Value / 100f);
			}
		}

		internal static void Init()
		{
			Cfg.MistOpacity.SettingChanged += delegate
			{
				Apply();
			};
		}

		private static void Apply()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			ParticleMist instance = ParticleMist.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if ((Object)(object)instance != (Object)(object)_mist)
			{
				_mist = null;
				_material = null;
				if (Opacity >= 1f)
				{
					return;
				}
				ParticleSystemRenderer component = ((Component)instance).GetComponent<ParticleSystemRenderer>();
				if ((Object)(object)component == (Object)null)
				{
					return;
				}
				_mist = instance;
				_material = ((Renderer)component).material;
				_originalAlpha = _material.color.a;
			}
			if (!((Object)(object)_material == (Object)null))
			{
				Color color = _material.color;
				color.a = _originalAlpha * Opacity;
				_material.color = color;
			}
		}
	}
	internal static class MutedSails
	{
		private sealed class SailState : MonoBehaviour
		{
			public bool Swapped;

			public SkinnedMeshRenderer[] Renderers;

			public Material[][] Originals;
		}

		[HarmonyPatch(typeof(Ship), "OnEnable")]
		private static class ShipEnablePatch
		{
			private static void Postfix(Ship __instance)
			{
				if (_everTransparent || Opacity < 1f)
				{
					Pending.Add(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Ship), "OnDisable")]
		private static class ShipDisablePatch
		{
			private static void Postfix(Ship __instance)
			{
				Pending.Remove(__instance);
			}
		}

		[HarmonyPatch(typeof(Ship), "UpdateSailSize")]
		private static class SailSizePatch
		{
			private static void Postfix(Ship __instance)
			{
				if (Pending.Count != 0 && Pending.Remove(__instance))
				{
					Apply(__instance, ((Component)__instance).GetComponent<SailState>());
				}
			}
		}

		private const string ShaderName = "Custom/LitParticles";

		private static readonly HashSet<Ship> Pending = new HashSet<Ship>();

		private static bool _everTransparent;

		private static Shader _shader;

		private static bool _shaderMissing;

		private static readonly Dictionary<Material, Material> Transparent = new Dictionary<Material, Material>();

		private static readonly Dictionary<Material, Color> BaseColors = new Dictionary<Material, Color>();

		private static float Opacity
		{
			get
			{
				if (Cfg.SailOpacity == null)
				{
					return 1f;
				}
				return Mathf.Clamp01((float)Cfg.SailOpacity.Value / 100f);
			}
		}

		internal static void Init()
		{
			Cfg.SailOpacity.SettingChanged += delegate
			{
				UpdateAlpha();
				foreach (IMonoUpdater instance in Ship.Instances)
				{
					Ship val = (Ship)(object)((instance is Ship) ? instance : null);
					if (val != null && (Object)(object)val != (Object)null)
					{
						Pending.Add(val);
					}
				}
			};
		}

		private static void Apply(Ship ship, SailState state)
		{
			if (Player.IsPlacementGhost(((Component)ship).gameObject))
			{
				return;
			}
			if ((Object)(object)state == (Object)null)
			{
				state = ((Component)ship).gameObject.AddComponent<SailState>();
				state.Renderers = SailRenderers(ship);
			}
			bool flag = Opacity < 1f;
			if (flag == state.Swapped)
			{
				return;
			}
			if (flag)
			{
				if (!EnsureShader())
				{
					return;
				}
				state.Originals = new Material[state.Renderers.Length][];
				for (int i = 0; i < state.Renderers.Length; i++)
				{
					SkinnedMeshRenderer val = state.Renderers[i];
					if (!((Object)(object)val == (Object)null))
					{
						Material[] sharedMaterials = ((Renderer)val).sharedMaterials;
						state.Originals[i] = sharedMaterials;
						Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
						for (int j = 0; j < sharedMaterials.Length; j++)
						{
							array[j] = TransparentCopy(sharedMaterials[j]);
						}
						((Renderer)val).sharedMaterials = array;
					}
				}
				_everTransparent = true;
			}
			else
			{
				for (int k = 0; k < state.Renderers.Length; k++)
				{
					SkinnedMeshRenderer val2 = state.Renderers[k];
					if ((Object)(object)val2 != (Object)null && state.Originals != null && state.Originals[k] != null)
					{
						((Renderer)val2).sharedMaterials = state.Originals[k];
					}
				}
				state.Originals = null;
			}
			state.Swapped = flag;
			if ((Object)(object)ship.m_sailCloth != (Object)null)
			{
				ship.m_sailCloth.SetParameterChange();
			}
		}

		private static SkinnedMeshRenderer[] SailRenderers(Ship ship)
		{
			List<SkinnedMeshRenderer> list = new List<SkinnedMeshRenderer>();
			if ((Object)(object)ship.m_sailCloth != (Object)null)
			{
				list.AddRange(((Component)ship.m_sailCloth).GetComponentsInChildren<SkinnedMeshRenderer>(true));
			}
			if ((Object)(object)ship.m_sailObject != (Object)null)
			{
				SkinnedMeshRenderer[] componentsInChildren = ship.m_sailObject.GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer item in componentsInChildren)
				{
					if (!list.Contains(item))
					{
						list.Add(item);
					}
				}
			}
			return list.ToArray();
		}

		private static bool EnsureShader()
		{
			if ((Object)(object)_shader != (Object)null)
			{
				return true;
			}
			if (_shaderMissing)
			{
				return false;
			}
			_shader = Cache.GetPrefab<Shader>("Custom/LitParticles") ?? Shader.Find("Custom/LitParticles");
			if ((Object)(object)_shader != (Object)null)
			{
				return true;
			}
			_shaderMissing = true;
			Log.Warning("The game has no shader Custom/LitParticles; sails stay as they are.");
			return false;
		}

		private static Material TransparentCopy(Material original)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)original == (Object)null)
			{
				return null;
			}
			if (Transparent.TryGetValue(original, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			value = new Material(_shader)
			{
				name = ((Object)original).name + " (BetrValheim transparent)"
			};
			if (original.HasProperty("_MainTex"))
			{
				value.SetTexture("_MainTex", original.GetTexture("_MainTex"));
				value.SetTextureScale("_MainTex", original.GetTextureScale("_MainTex"));
				value.SetTextureOffset("_MainTex", original.GetTextureOffset("_MainTex"));
			}
			Color val = (original.HasProperty("_Color") ? original.GetColor("_Color") : Color.white);
			BaseColors[value] = val;
			value.color = WithAlpha(val);
			Transparent[original] = value;
			return value;
		}

		private static Color WithAlpha(Color baseColor)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			baseColor.a *= Opacity;
			return baseColor;
		}

		private static void UpdateAlpha()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			foreach (Material value2 in Transparent.Values)
			{
				if ((Object)(object)value2 != (Object)null && BaseColors.TryGetValue(value2, out var value))
				{
					value2.color = WithAlpha(value);
				}
			}
		}
	}
}
namespace BetrValheim.UI
{
	internal static class BetrValheimPanel
	{
		private abstract class Row
		{
			public ConfigEntryBase Entry;

			public bool AdminOnly;

			public abstract void Pull();

			public abstract void SetInteractable(bool value);
		}

		private sealed class ToggleRow : Row
		{
			public Button Control;

			public ConfigEntry<bool> Typed;

			public string OnKey = "btn.on";

			public string OffKey = "btn.off";

			public override void Pull()
			{
				//IL_004f: 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)
				Text componentInChildren = ((Component)Control).GetComponentInChildren<Text>();
				componentInChildren.text = Loc.T(Typed.Value ? OnKey : OffKey);
				((Graphic)componentInChildren).color = (Typed.Value ? GUIManager.Instance.ValheimOrange : GUIManager.Instance.ValheimBeige);
			}

			public override void SetInteractable(bool value)
			{
				((Selectable)Control).interactable = value;
			}
		}

		private sealed class NumberRow : Row
		{
			public InputField Control;

			public Slider Slider;

			public ConfigEntry<float> Float;

			public ConfigEntry<int> Int;

			public override void Pull()
			{
				if ((Object)(object)Slider != (Object)null)
				{
					Slider.SetValueWithoutNotify((Float != null) ? Float.Value : ((float)Int.Value));
				}
				Control.text = ((Float != null) ? Float.Value.ToString("0.##", CultureInfo.InvariantCulture) : Int.Value.ToString(CultureInfo.InvariantCulture));
			}

			public override void SetInteractable(bool value)
			{
				((Selectable)Control).interactable = value;
				if ((Object)(object)Slider != (Object)null)
				{
					((Selectable)Slider).interactable = value;
				}
				Control.readOnly = !value;
			}

			public void Commit()
			{
				int result2;
				if (Float != null)
				{
					if (float.TryParse(Control.text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
					{
						Float.Value = Clamp(Float, result);
					}
				}
				else if (int.TryParse(Control.text, NumberStyles.Integer, CultureInfo.InvariantCulture, out result2))
				{
					Int.Value = Clamp(Int, result2);
				}
				Pull();
			}

			private static T Clamp<T>(ConfigEntry<T> entry, T value)
			{
				ConfigDescription description = ((ConfigEntryBase)entry).Description;
				AcceptableValueBase val = ((description != null) ? description.AcceptableValues : null);
				if (val == null)
				{
					return value;
				}
				return (T)val.Clamp((object)value);
			}
		}

		private sealed class TextRow : Row
		{
			public InputField Control;

			public ConfigEntry<string> Typed;

			public override void Pull()
			{
				Control.text = Typed.Value ?? string.Empty;
			}

			public override void SetInteractable(bool value)
			{
				((Selectable)Control).interactable = value;
				Control.readOnly = !value;
			}
		}

		private sealed class KeyRow : Row
		{
			public Dropdown Control;

			public ConfigEntry<KeyCode> Typed;

			public override void Pull()
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				Control.SetValueWithoutNotify(Math.Max(0, Array.IndexOf(Cfg.SlotKeys, Typed.Value)));
			}

			public override void SetInteractable(bool value)
			{
				((Selectable)Control).interactable = value;
			}
		}

		private sealed class LanguageRow : Row
		{
			public Dropdown Control;

			public override void Pull()
			{
				Control.SetValueWithoutNotify((int)Cfg.Language.Value);
			}

			public override void SetInteractable(bool value)
			{
				((Selectable)Control).interactable = value;
			}
		}

		private enum Category
		{
			General,
			Sources,
			Crafting,
			Refill,
			Collect,
			Inventory,
			Portals,
			Stations,
			Timers,
			Environment,
			Interface
		}

		[HarmonyPatch(typeof(Menu), "Update")]
		private static class EscapeClosesPatch
		{
			private static bool Prefix()
			{
				if (!IsVisible || Menu.IsVisible() || !EscapePressed())
				{
					return true;
				}
				SetVisible(visible: false);
				return false;
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__51_0;

			public static UnityAction<int> <>9__63_0;

			public static Predicate<Row> <>9__69_0;

			public static Predicate<Row> <>9__69_1;

			internal void <CreateFooter>b__51_0()
			{
				SetVisible(visible: false);
			}

			internal void <AddLanguage>b__63_0(int index)
			{
				if (Cfg.Language.Value != (UiLanguage)index)
				{
					Cfg.Language.Value = (UiLanguage)index;
					Loc.Refresh();
					Rebuild();
				}
			}

			internal bool <ApplyPermissions>b__69_0(Row row)
			{
				return row.AdminOnly;
			}

			internal bool <ApplyPermissions>b__69_1(Row row)
			{
				return !row.AdminOnly;
			}
		}

		private const float PanelWidth = 1020f;

		private const float PanelHeight = 760f;

		private const float SidebarLeft = 18f;

		private const string LogoFile = "BetrValheim_logo.png";

		private const float LogoTop = 14f;

		private const float LogoHeight = 66f;

		private const float SidebarWidth = 196f;

		private const float CategoryStep = 48f;

		private const float ContentLeft = 228f;

		private const float ContentTop = 118f;

		private const float ContentBottom = 86f;

		private const float RowHeight = 48f;

		private const float ControlWidth = 150f;

		private const float ControlMargin = 16f;

		private static readonly List<Row> Rows = new List<Row>(32);

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

		private static GameObject _panel;

		private static Transform _content;

		private static ScrollRect _scroll;

		private static Text _statusText;

		private static Text _adminText;

		private static Text _titleText;

		private static Sprite _logo;

		private static bool _logoMissing;

		private static Text _hintText;

		private static Category _category = Category.General;

		private static bool _inputBlocked;

		private static bool _sharedChanged;

		private static int _rowIndex;

		private static MethodInfo _pushToServer;

		public static bool IsVisible
		{
			get
			{
				if ((Object)(object)_panel != (Object)null)
				{
					return _panel.activeSelf;
				}
				return false;
			}
		}

		public static void Build()
		{
			if ((Object)(object)_panel != (Object)null || GUIManager.Instance == null || GUIManager.IsHeadless())
			{
				return;
			}
			try
			{
				Loc.Refresh();
				CreatePanel();
			}
			catch (Exception arg)
			{
				Log.Error($"Could not build the BetrValheim window: {arg}");
				Destroy();
			}
		}

		public static void Destroy()
		{
			SetInputBlocked(blocked: false);
			Rows.Clear();
			CategoryButtons.Clear();
			_content = null;
			_scroll = null;
			_statusText = null;
			_adminText = null;
			_titleText = null;
			_hintText = null;
			if ((Object)(object)_panel != (Object)null)
			{
				Object.Destroy((Object)(object)_panel);
				_panel = null;
			}
		}

		public static void Toggle()
		{
			if ((Object)(object)_panel == (Object)null)
			{
				Build();
			}
			if (!((Object)(object)_panel == (Object)null))
			{
				SetVisible(!_panel.activeSelf);
			}
		}

		public static void SetVisible(bool visible)
		{
			if (!((Object)(object)_panel == (Object)null) && _panel.activeSelf != visible)
			{
				if (visible)
				{
					Loc.Refresh();
					ShowCategory(_category);
					UpdateStatus();
					ScrollSpeed.Apply(_scroll);
				}
				else
				{
					CommitSharedChanges();
				}
				_panel.SetActive(visible);
				SetInputBlocked(visible);
			}
		}

		private static void SetInputBlocked(bool blocked)
		{
			if (_inputBlocked != blocked)
			{
				_inputBlocked = blocked;
				GUIManager.BlockInput(blocked);
			}
		}

		public static void RefreshValues()
		{
			if ((Object)(object)_panel == (Object)null)
			{
				return;
			}
			foreach (Row row in Rows)
			{
				row.Pull();
			}
			ApplyPermissions();
		}

		private static void Rebuild()
		{
			bool isVisible = IsVisible;
			Category category = _category;
			Destroy();
			Build();
			_category = category;
			if ((Object)(object)_panel != (Object)null && isVisible)
			{
				Loc.Refresh();
				ShowCategory(category);
				UpdateStatus();
				_panel.SetActive(true);
				_inputBlocked = false;
				SetInputBlocked(blocked: true);
			}
		}

		private static void CreatePanel()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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)
			_panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 1020f, 760f, true);
			_panel.SetActive(false);
			bool num = CreateLogo();
			if (!num)
			{
				_titleText = Label(Loc.T("title"), _panel.transform, 24, bold: true, GUIManager.Instance.ValheimOrange);
				Place(((Component)_titleText).gameObject, 18f, 18f, 16f, 42f);
				_titleText.alignment = (TextAnchor)3;
			}
			float num2 = (num ? 86f : 46f);
			_adminText = Label(string.Empty, _panel.transform, 14, bold: false, Color.white);
			Place(((Component)_adminText).gameObject, 18f, 18f, num2, num2 + 22f);
			_adminText.alignment = (TextAnchor)3;
			CreateSidebar();
			CreateContent();
			CreateFooter();
			ShowCategory(_category);
		}

		private static bool CreateLogo()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0059: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			Sprite val = LogoSprite();
			if (!((Object)(object)val == (Object)null))
			{
				Rect rect = val.rect;
				if (!(((Rect)(ref rect)).height <= 0f))
				{
					GameObject val2 = new GameObject("EW_Logo", new Type[1] { typeof(RectTransform) });
					val2.transform.SetParent(_panel.transform, false);
					Image obj = val2.AddComponent<Image>();
					obj.sprite = val;
					obj.preserveAspect = true;
					((Graphic)obj).raycastTarget = false;
					rect = val.rect;
					float num = 66f * ((Rect)(ref rect)).width;
					rect = val.rect;
					float num2 = num / ((Rect)(ref rect)).height;
					Place(val2, 18f, 1002f - num2, 14f, 80f);
					return true;
				}
			}
			return false;
		}

		internal static Sprite LogoSprite()
		{
			return Beside("BetrValheim_logo.png", ref _logo, ref _logoMissing, "the logo");
		}

		private static Sprite Beside(string name, ref Sprite cached, ref bool missing, string without)
		{
			if (((Object)(object)cached != (Object)null) | missing)
			{
				return cached;
			}
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			string text = ((directoryName != null) ? Path.Combine(directoryName, name) : null);
			if (text == null || !File.Exists(text))
			{
				missing = true;
				Log.Debug(name + " is not beside the plugin; the window goes without " + without + ".");
				return null;
			}
			cached = AssetUtils.LoadSpriteFromFile(text);
			missing = (Object)(object)cached == (Object)null;
			return cached;
		}

		private static void CreateSidebar()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_00c3: Expected O, but got Unknown
			CategoryButtons.Clear();
			float num = 118f;
			Category[] array = (Category[])Enum.GetValues(typeof(Category));
			foreach (Category category in array)
			{
				Category captured = category;
				GameObject go = GUIManager.Instance.CreateButton(Loc.T(KeyFor(category)), _panel.transform, new Vector2(0f, 1f), new Vector2(0f, 1f), Vector2.zero, 196f, 42f);
				Place(go, 18f, 806f, num, num + 42f);
				Button val = ConfigureButton(go);
				((UnityEvent)val.onClick).AddListener((UnityAction)delegate
				{
					ShowCategory(captured);
				});
				CategoryButtons.Add(val);
				num += 48f;
			}
		}

		private static void CreateContent()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Expected O, but got Unknown
			GameObject obj = GUIManager.Instance.CreateScrollView(_panel.transform, false, true, 10f, 5f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, new Color(0f, 0f, 0f, 0.35f), 774f, 556f);
			Place(obj, 228f, 18f, 118f, 674f);
			ScrollRect componentInChildren = obj.GetComponentInChildren<ScrollRect>(true);
			if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.content == (Object)null)
			{
				throw new InvalidOperationException("Jotunn's scroll view has no content rect.");
			}
			_content = ((Component)componentInChildren.content).transform;
			_scroll = componentInChildren;
			ScrollSpeed.Apply(componentInChildren);
			VerticalLayoutGroup obj2 = Ensure<VerticalLayoutGroup>(((Component)_content).gameObject);
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			((LayoutGroup)obj2).childAlignment = (TextAnchor)0;
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 2f;
			((LayoutGroup)obj2).padding = new RectOffset(0, 0, 4, 12);
			ContentSizeFitter obj3 = Ensure<ContentSizeFitter>(((Component)_content).gameObject);
			obj3.horizontalFit = (FitMode)0;
			obj3.verticalFit = (FitMode)2;
		}

		private static void CreateFooter()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			_hintText = Label(Loc.T("saved"), _panel.transform, 13, bold: false, new Color(0.7f, 0.7f, 0.65f));
			Place(((Component)_hintText).gameObject, 228f, 198f, 682f, 702f);
			_hintText.alignment = (TextAnchor)3;
			_statusText = Label(string.Empty, _panel.transform, 13, bold: false, Color.white);
			Place(((Component)_statusText).gameObject, 228f, 198f, 704f, 726f);
			_statusText.alignment = (TextAnchor)3;
			GameObject go = GUIManager.Instance.CreateButton(Loc.T("btn.close"), _panel.transform, new Vector2(0f, 1f), new Vector2(0f, 1f), Vector2.zero, 160f, 42f);
			Place(go, 842f, 18f, 686f, 728f);
			ButtonClickedEvent onClick = ConfigureButton(go).onClick;
			object obj = <>c.<>9__51_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					SetVisible(visible: false);
				};
				<>c.<>9__51_0 = val;
				obj = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			Text obj2 = Label("by DezzyCode", _panel.transform, 13, bold: false, new Color(0.84f, 0.78f, 0.6f, 0.5f));
			Place(((Component)obj2).gameObject, 18f, 806f, 704f, 726f);
			obj2.alignment = (TextAnchor)3;
		}

		private static bool EscapePressed()
		{
			if (!ZInput.GetKeyDown((KeyCode)27, false))
			{
				return ZInput.GetButtonDown("JoyButtonB");
			}
			return true;
		}

		public static void CloseOnEscapeWithoutMenu()
		{
			if (IsVisible && (Object)(object)Menu.instance == (Object)null && EscapePressed())
			{
				SetVisible(visible: false);
			}
		}

		private static string KeyFor(Category category)
		{
			return category switch
			{
				Category.General => "cat.general", 
				Category.Sources => "cat.sources", 
				Category.Crafting => "cat.crafting", 
				Category.Refill => "cat.refill", 
				Category.Collect => "cat.collect", 
				Category.Inventory => "cat.inventory", 
				Category.Portals => "cat.portals", 
				Category.Stations => "cat.stations", 
				Category.Timers => "cat.timers", 
				Category.Environment => "cat.environment", 
				_ => "cat.interface", 
			};
		}

		private static void ShowCategory(Category category)
		{
			_category = category;
			if (!((Object)(object)_content == (Object)null))
			{
				for (int num = _content.childCount - 1; num >= 0; num--)
				{
					Object.Destroy((Object)(object)((Component)_content.GetChild(num)).gameObject);
				}
				Rows.Clear();
				_rowIndex = 0;
				switch (category)
				{
				case Category.General:
					AddHint("general.hint");
					AddToggle(Cfg.ModEnabled, "ModEnabled");
					AddNumber(Cfg.ScanInterval, null, "ScanInterval");
					break;
				case Category.Sources:
					AddHint("sources.hint");
					AddToggle(Cfg.UseContainers, "UseContainers");
					AddToggle(Cfg.UseForeignPrivateContainers, "UseForeignPrivateContainers");
					AddToggle(Cfg.UseDrawers, "UseDrawers");
					AddToggle(Cfg.UseGroundItems, "UseGroundItems");
					AddNumber(null, Cfg.KeepInContainer, "KeepInContainer");
					AddText(Cfg.ReservedItems, "ReservedItems");
					break;
				case Category.Crafting:
					AddHint("crafting.hint");
					AddToggle(Cfg.CraftFromContainers, "CraftFromContainers");
					AddToggle(Cfg.BuildFromContainers, "BuildFromContainers");
					AddNumber(Cfg.CraftRange, null, "CraftRange");
					AddToggle(Cfg.MultiCraftEnabled, "MultiCraftEnabled");
					AddToggle(Cfg.AutoRepairEnabled, "AutoRepairEnabled");
					break;
				case Category.Refill:
					AddHint("refill.hint");
					AddToggle(Cfg.RefillEnabled, "RefillEnabled");
					AddToggle(Cfg.RefillFuel, "RefillFuel");
					AddToggle(Cfg.RefillMaterial, "RefillMaterial");
					AddNumber(Cfg.StationSupplyRange, null, "StationSupplyRange");
					AddText(Cfg.BlockedStationItems, "BlockedStationItems");
					break;
				case Category.Collect:
					AddHint("collect.hint");
					AddToggle(Cfg.CollectEnabled, "CollectEnabled");
					AddNumber(Cfg.CollectRange, null, "CollectRange");
					AddToggle(Cfg.DrawersFirst, "DrawersFirst", null, "btn.drawers", "btn.chests");
					AddToggle(Cfg.DrawerAutoAssign, "DrawerAutoAssign");
					break;
				case Category.Inventory:
					AddHint("inventory.hint");
					AddToggle(Cfg.ExtraInventory, "ExtraInventory");
					AddToggle(Cfg.EquipmentPage, "EquipmentPage");
					AddKeyChoice(Cfg.QuickSlotKey, "QuickSlotKey");
					AddKeyChoice(Cfg.FoodSlotKey, "FoodSlotKey");
					AddKeyChoice(Cfg.AmmoSlotKey, "AmmoSlotKey");
					AddToggle(Cfg.TrashBin, "TrashBin");
					break;
				case Category.Portals:
					AddHint("portals.hint");
					AddToggle(Cfg.PortalPicker, "PortalPicker");
					AddToggle(Cfg.PortalsOnMap, "PortalsOnMap");
					AddToggle(Cfg.PortalsOnMinimap, "PortalsOnMinimap");
					AddToggle(Cfg.PortalNames, "PortalNames");
					break;
				case Category.Stations:
					AddHint("stations.hint");
					AddToggle(Cfg.StationSmelter, "StationSmelter");
					AddToggle(Cfg.StationKiln, "StationKiln");
					AddToggle(Cfg.StationBlastFurnace, "StationBlastFurnace");
					AddToggle(Cfg.StationCookingStation, "StationCookingStation");
					AddToggle(Cfg.StationFermenter, "StationFermenter");
					AddToggle(Cfg.StationWindmill, "StationWindmill");
					AddToggle(Cfg.StationSpinningWheel, "StationSpinningWheel");
					AddToggle(Cfg.StationEitrRefinery, "StationEitrRefinery");
					AddToggle(Cfg.StationCampfire, "StationCampfire");
					AddToggle(Cfg.StationHearth, "StationHearth");
					AddToggle(Cfg.StationStandingTorch, "StationStandingTorch");
					AddToggle(Cfg.StationWallTorch, "StationWallTorch");
					AddToggle(Cfg.StationBrazier, "StationBrazier");
					AddToggle(Cfg.StationBonfire, "StationBonfire");
					AddToggle(Cfg.StationOtherFireplace, "StationOtherFireplace");
					break;
				case Category.Timers:
					AddHint("timers.hint");
					AddToggle(Cfg.TimersEnabled, "TimersEnabled");
					AddToggle(Cfg.TimerFermenters, "TimerFermenters");
					AddToggle(Cfg.TimerCooking, "TimerCooking");
					AddToggle(Cfg.TimerProcessing, "TimerProcessing");
					AddToggle(Cfg.TimerBurnTime, "TimerBurnTime");
					AddToggle(Cfg.TimerQueueTime, "TimerQueueTime");
					break;
				case Category.Environment:
					AddHint("environment.hint");
					AddNumber(null, Cfg.SailOpacity, "SailOpacity");
					AddNumber(null, Cfg.MistOpacity, "MistOpacity");
					break;
				case Category.Interface:
					AddHint("interface.hint");
					AddLanguage();
					AddHotkeyInfo();
					AddToggle(Cfg.MinimapLogo, "MinimapLogo");
					AddToggle(Cfg.ShowStatusMessages, "ShowStatusMessages");
					AddToggle(Cfg.VerboseLog, "VerboseLog");
					break;
				}
				ApplyPermissions();
				HighlightCategory();
			}
		}

		private static void HighlightCategory()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			Category[] array = (Category[])Enum.GetValues(typeof(Category));
			for (int i = 0; i < CategoryButtons.Count && i < array.Length; i++)
			{
				Text componentInChildren = ((Component)CategoryButtons[i]).GetComponentInChildren<Text>();
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((Graphic)componentInChildren).color = (Color)((array[i] == _category) ? GUIManager.Instance.ValheimOrange : new Color(0.85f, 0.83f, 0.78f));
				}
			}
		}

		private static void AddHint(string key)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			string text = Loc.T(key);
			if (!(text == key))
			{
				GameObject val = new GameObject("Hint", new Type[2]
				{
					typeof(RectTransform),
					typeof(LayoutElement)
				});
				val.transform.SetParent(_content, false);
				LayoutElement component = val.GetComponent<LayoutElement>();
				component.preferredHeight = 38f;
				component.minHeight = 38f;
				component.flexibleWidth = 1f;
				Text obj = Label(text, val.transform, 13, bold: false, new Color(0.84f, 0.78f, 0.6f));
				obj.alignment = (TextAnchor)3;
				obj.horizontalOverflow = (HorizontalWrapMode)0;
				StretchIn(((Component)obj).gameObject, 14f, 14f, 4f, 34f);
			}
		}

		private static GameObject CreateRow(string labelKey, string descriptionKey, bool adminOnly, bool numeric = false)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Row", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(LayoutElement)
			});
			val.transform.SetParent(_content, false);
			Image component = val.GetComponent<Image>();
			((Graphic)component).color = ((_rowIndex % 2 == 0) ? new Color(1f, 1f, 1f, 0.035f) : new Color(0f, 0f, 0f, 0.12f));
			((Graphic)component).raycastTarget = false;
			LayoutElement component2 = val.GetComponent<LayoutElement>();
			component2.preferredHeight = (numeric ? 92f : 48f);
			component2.minHeight = component2.preferredHeight;
			component2.flexibleWidth = 1f;
			_rowIndex++;
			Text obj = Label(Loc.T(labelKey), val.transform, 17, bold: false, (Color)((adminOnly && !IsAdmin()) ? new Color(0.62f, 0.6f, 0.56f) : Color.white));
			obj.alignment = (TextAnchor)6;
			StretchIn(((Component)obj).gameObject, 14f, numeric ? 16f : 182f, 4f, 26f);
			string text = descriptionKey ?? (labelKey + ".d");
			string text2 = Loc.T(text);
			if (text2 != text)
			{
				Text obj2 = Label(text2, val.transform, 12, bold: false, new Color(0.68f, 0.66f, 0.6f));
				obj2.alignment = (TextAnchor)0;
				StretchIn(((Component)obj2).gameObject, 14f, numeric ? 16f : 182f, 26f, numeric ? 56f : 46f);
			}
			return val;
		}

		private static void AddToggle(ConfigEntry<bool> entry, string key, string descriptionKey = null, string onKey = "btn.on", string offKey = "btn.off")
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			if (entry == null)
			{
				return;
			}
			bool adminOnly = IsAdminOnly((ConfigEntryBase)(object)entry);
			GameObject val = CreateRow(key, descriptionKey, adminOnly);
			GameObject obj = GUIManager.Instance.CreateButton("", val.transform, Vector2.zero, Vector2.zero, Vector2.zero, 110f, 34f);
			obj.transform.SetParent(val.transform, false);
			AnchorRight(obj, 110f, 34f);
			Button val2 = ConfigureButton(obj);
			ToggleRow handler = new ToggleRow
			{
				Control = val2,
				Typed = entry,
				Entry = (ConfigEntryBase)(object)entry,
				AdminOnly = adminOnly,
				OnKey = onKey,
				OffKey = offKey
			};
			handler.Pull();
			((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
			{
				if (!adminOnly || IsAdmin())
				{
					entry.Value = !entry.Value;
					handler.Pull();
					OnChanged(adminOnly);
				}
			});
			Rows.Add(handler);
		}

		private static void AddNumber(ConfigEntry<float> floatEntry, ConfigEntry<int> intEntry, string key)
		{
			//IL_0059: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: 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_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			ConfigEntryBase val = (ConfigEntryBase)(((object)floatEntry) ?? ((object)intEntry));
			if (val == null)
			{
				return;
			}
			bool adminOnly = IsAdminOnly(val);
			GameObject val2 = CreateRow(key, null, adminOnly, numeric: true);
			GameObject val3 = GUIManager.Instance.CreateInputField(val2.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), Vector2.zero, (ContentType)3, RangeHint(val), 16, 150f, 30f);
			val3.transform.localScale = Vector3.one;
			AnchorRight(val3, 80f, 30f);
			RectTransform component = val3.GetComponent<RectTransform>();
			component.anchoredPosition += new Vector2(0f, -22f);
			NumberRow handler = new NumberRow
			{
				Control = val3.GetComponent<InputField>(),
				Float = floatEntry,
				Int = intEntry,
				Entry = val,
				AdminOnly = adminOnly
			};
			GameObject obj = DefaultControls.CreateSlider(GUIManager.Instance.ValheimControlResources);
			obj.transform.SetParent(val2.transform, false);
			obj.layer = 5;
			RectTransform component2 = obj.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 0f);
			component2.anchorMax = new Vector2(1f, 0f);
			component2.offsetMin = new Vector2(20f, 12f);
			component2.offsetMax = new Vector2(-116f, 38f);
			Slider component3 = obj.GetComponent<Slider>();
			GUIManager.Instance.ApplySliderStyle(component3, new Vector2(22f, 24f));
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)component3).navigation = navigation;
			if (floatEntry != null && val.Description.AcceptableValues is AcceptableValueRange<float> val4)
			{
				component3.minValue = val4.MinValue;
				component3.maxValue = val4.MaxValue;
			}
			else if (intEntry != null && val.Description.AcceptableValues is AcceptableValueRange<int> val5)
			{
				component3.minValue = val5.MinValue;
				component3.maxValue = val5.MaxValue;
			}
			component3.wholeNumbers = intEntry != null;
			handler.Slider = component3;
			handler.Pull();
			((UnityEvent<float>)(object)component3.onValueChanged).AddListener((UnityAction<float>)delegate(float value)
			{
				if (adminOnly && !IsAdmin())
				{
					handler.Pull();
				}
				else
				{
					if (floatEntry != null)
					{
						floatEntry.Value = (float)Math.Round(value, 1);
					}
					else
					{
						intEntry.Value = Mathf.RoundToInt(value);
					}
					handler.Pull();
					OnChanged(adminOnly);
				}
			});
			((UnityEvent<string>)(object)handler.Control.onEndEdit).AddListener((UnityAction<string>)delegate
			{
				if (adminOnly && !IsAdmin())
				{
					handler.Pull();
				}
				else
				{
					handler.Commit();
					OnChanged(adminOnly);
				}
			});
			Rows.Add(handler);
		}

		private static void AddText(ConfigEntry<string> entry, string key)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (entry == null)
			{
				return;
			}
			bool adminOnly = IsAdminOnly((ConfigEntryBase)(object)entry);
			GameObject val = CreateRow(key, null, adminOnly);
			GameObject val2 = GUIManager.Instance.CreateInputField(val.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), Vector2.zero, (ContentType)0, "Wood, Coal", 15, 150f, 30f);
			val2.transform.localScale = Vector3.one;
			AnchorRight(val2, 150f, 30f);
			TextRow handler = new TextRow
			{
				Control = val2.GetComponent<InputField>(),
				Typed = entry,
				Entry = (ConfigEntryBase)(object)entry,
				AdminOnly = adminOnly
			};
			handler.Pull();
			((UnityEvent<string>)(object)handler.Control.onEndEdit).AddListener((UnityAction<string>)delegate(string value)
			{
				if (adminOnly && !IsAdmin())
				{
					handler.Pull();
				}
				else if (entry.Value != value)
				{
					entry.Value = value;
					OnChanged(adminOnly);
				}
			});
			Rows.Add(handler);
		}

		private static void AddLanguage()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateRow("Language", null, adminOnly: false);
			GameObject obj = GUIManager.Instance.CreateDropDown(val.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), Vector2.zero, 15, 150f, 30f);
			obj.transform.localScale = Vector3.one;
			AnchorRight(obj, 150f, 30f);
			Dropdown component = obj.GetComponent<Dropdown>();
			component.ClearOptions();
			component.AddOptions(new List<string>
			{
				Loc.T("lang.auto"),
				"English",
				"Deutsch"
			});
			LanguageRow languageRow = new LanguageRow
			{
				Control = component,
				Entry = (ConfigEntryBase)(object)Cfg.Language,
				AdminOnly = false
			};
			languageRow.Pull();
			((UnityEvent<int>)(object)component.onValueChanged).AddListener((UnityAction<int>)delegate(int index)
			{
				if (Cfg.Language.Value != (UiLanguage)index)
				{
					Cfg.Language.Value = (UiLanguage)index;
					Loc.Refresh();
					Rebuild();
				}
			});
			Rows.Add(languageRow);
		}

		private static void AddKeyChoice(ConfigEntry<KeyCode> entry, string key)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (entry == null)
			{
				return;
			}
			GameObject val = CreateRow(key, null, adminOnly: false);
			GameObject obj = GUIManager.Instance.CreateDropDown(val.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), Vector2.zero, 15, 150f, 30f);
			obj.transform.localScale = Vector3.one;
			AnchorRight(obj, 150f, 30f);
			Dropdown component = obj.GetComponent<Dropdown>();
			component.ClearOptions();
			List<string> list = new List<string>();
			KeyCode[] slotKeys = Cfg.SlotKeys;
			for (int i = 0; i < slotKeys.Length; i++)
			{
				list.Add(Loc.T("key." + ((object)slotKeys[i]/*cast due to .constrained prefix*/).ToString()));
			}
			component.AddOptions(list);
			if ((Object)(object)component.captionText != (Object)null)
			{
				component.captionText.horizontalOverflow = (HorizontalWrapMode)1;
				component.captionText.resizeTextForBestFit = true;
				component.captionText.resizeTextMinSize = 10;
				component.captionText.resizeTextMaxSize = 15;
			}
			KeyRow keyRow = new KeyRow
			{
				Control = component,
				Typed = entry,
				Entry = (ConfigEntryBase)(object)entry,
				AdminOnly = false
			};
			keyRow.Pull();
			((UnityEvent<int>)(object)component.onValueChanged).AddListener((UnityAction<int>)delegate(int index)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Invalid comparison between Unknown and I4
				if (index >= 0 && index < Cfg.SlotKeys.Length && (int)entry.Value != (int)Cfg.SlotKeys[index])
				{
					entry.Value = Cfg.SlotKeys[index];
					OnChanged(adminOnly: false);
				}
			});
			Rows.Add(keyRow);
		}

		private static void AddHotkeyInfo()
		{
			//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_003e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateRow("ToggleKey", null, adminOnly: false);
			Text obj = Label(((object)Cfg.ToggleKey.Value/*cast due to .constrained prefix*/).ToString(), val.transform, 16, bold: false, new Color(0.85f, 0.83f, 0.78f));
			obj.alignment = (TextAnchor)5;
			AnchorRight(((Component)obj).gameObject, 150f, 30f);
		}

		private static string RangeHint(ConfigEntryBase entry)
		{
			ConfigDescription description = entry.Description;
			AcceptableValueBase val = ((description != null) ? description.AcceptableValues : null);
			if (val == null)
			{
				return null;
			}
			return val.ToDescriptionString().Replace("# Acceptable value range: ", "");
		}

		private static void OnChanged(bool adminOnly)
		{
			if (adminOnly)
			{
				_sharedChanged = true;
			}
			Refiller.Reset();
			UpdateStatus();
		}

		private static void CommitSharedChanges()
		{
			if (_sharedChanged)
			{
				_sharedChanged = false;
				if (IsAdmin())
				{
					PushToServer();
				}
			}
		}

		private static void ApplyPermissions()
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			bool flag = IsAdmin();
			foreach (Row row in Rows)
			{
				row.SetInteractable(flag || !row.AdminOnly);
			}
			if ((Object)(object)_adminText != (Object)null)
			{
				bool flag2 = Rows.Exists((Row row) => row.AdminOnly);
				bool flag3 = Rows.Exists((Row row) => !row.AdminOnly);
				string key = ((!flag2) ? "settings.personal" : ((!flag) ? "admin.no" : (flag3 ? "settings.crafting" : "admin.yes")));
				_adminText.text = Loc.T(key);
				((Graphic)_adminText).color = ((flag2 && !flag) ? new Color(0.9f, 0.8f, 0.55f) : new Color(0.75f, 0.85f, 0.7f));
			}
			if ((Object)(object)_hintText != (Object)null)
			{
				_hintText.text = Loc.T("saved");
			}
		}

		private static void UpdateStatus()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_statusText == (Object)null))
			{
				if (Plugin.PatchFailures.Count > 0)
				{
					((Graphic)_statusText).color = new Color(1f, 0.45f, 0.4f);
					_statusText.text = Loc.T("status.patches");
				}
				else
				{
					((Graphic)_statusText).color = Color.white;
					_statusText.text = string.Empty;
				}
			}
		}

		private static bool IsAdmin()
		{
			if (SynchronizationManager.Instance != null)
			{
				return SynchronizationManager.Instance.PlayerIsAdmin;
			}
			return true;
		}

		private static bool IsAdminOnly(ConfigEntryBase entry)
		{
			ConfigDescription description = entry.Description;
			object[] array = ((description != null) ? description.Tags : null);
			if (array == null)
			{
				return false;
			}
			object[] array2 = array;
			foreach (object obj in array2)
			{
				ConfigurationManagerAttributes val = (ConfigurationManagerAttributes)((obj is ConfigurationManagerAttributes) ? obj : null);
				if (val != null && val.IsAdminOnly)
				{
					return true;
				}
			}
			return false;
		}

		private static void PushToServer()
		{
			if (SynchronizationManager.Instance == null)
			{
				return;
			}
			if (_pushToServer == null)
			{
				_pushToServer = AccessTools.Method(typeof(SynchronizationManager), "SynchronizeChangedConfig", (Type[])null, (Type[])null);
				if (_pushToServer == null)
				{
					Log.Warning("Jotunn config push method not found; settings stay local until the next sync.");
					return;
				}
			}
			try
			{
				_pushToServer.Invoke(SynchronizationManager.Instance, null);
			}
			catch (Exception ex)
			{
				Log.Error("Could not push the configuration to the server: " + ex.Message);
			}
		}

		private static Text Label(string text, Transform parent, int size, bool bold, Color color)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GUIManager.Instance.CreateText(text, parent, new Vector2(0f, 1f), new Vector2(0f, 1f), Vector2.zero, bold ? GUIManager.Instance.AveriaSerifBold : GUIManager.Instance.AveriaSerif, size, color, true, Color.black, 200f, 24f, false);
			obj.transform.localScale = Vector3.one;
			return obj.GetComponent<Text>();
		}

		private static void Place(GameObject go, float left, float right, float top, float bottom)
		{
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)go.transform;
			val.anchorMin = new Vector2(0f, 1f);
			val.anchorMax = new Vector2(1f, 1f);
			val.pivot = new Vector2(0.5f, 1f);
			val.offsetMin = new Vector2(left, 0f - bottom);
			val.offsetMax = new Vector2(0f - right, 0f - top);
		}

		private static void StretchIn(GameObject go, float left, float right, float top, float bottom)
		{
			Place(go, left, right, top, bottom);
		}

		private static void AnchorRight(GameObject go, float width, float height)
		{
			//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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)go.transform;
			val.anchorMin = new Vector2(1f, 0.5f);
			val.anchorMax = new Vector2(1f, 0.5f);
			val.pivot = new Vector2(1f, 0.5f);
			val.sizeDelta = new Vector2(width, height);
			val.anchoredPosition = new Vector2(-16f, 0f);
		}

		private static Button ConfigureButton(GameObject go)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			Button component = go.GetComponent<Button>();
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)component).navigation = navigation;
			ButtonSfx component2 = go.GetComponent<ButtonSfx>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.m_selectSfxPrefab = null;
				component2.m_selectSfxPrefabVibrationOnly = null;
			}
			return component;
		}

		private static T Ensure<T>(GameObject go) where T : Component
		{
			T component = go.GetComponent<T>();
			if (!((Object)(object)component != (Object)null))
			{
				return go.AddComponent<T>();
			}
			return component;
		}
	}
	internal static class EquipmentSlots
	{
		public enum Kind
		{
			None,
			Helmet,
			Chest,
			Legs,
			Cape,
			Trinket,
			Utility,
			Food,
			Ammo,
			Key,
			Quick
		}

		public const int Width = 8;

		public const int Height = 5;

		private static readonly Kind[,] Layout;

		public const int LayoutVersion = 4;

		private static readonly Dictionary<int, Kind[,]> Earlier;

		private const int KindCount = 11;

		private static readonly int[] Counts;

		private static readonly int[,] Numbers;

		private static readonly Vector2i[,] Slots;

		static EquipmentSlots()
		{
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			Layout = Build("H U U . . K F A", "P U U . . K F A", "C T . . . . F A", "L . . . . . . .", ". . Q Q Q Q Q Q");
			Earlier = new Dictionary<int, Kind[,]>
			{
				[1] = Build("H C L P T . K K", "U U U U . F F F", "Q Q Q Q Q Q . .", "A A A . . . . .", ". . . . . . . ."),
				[2] = Build("H U Q Q Q Q Q Q", "C U . . . . . .", "L U F F F . K K", "P U . . . . . .", "T . A A A . . ."),
				[3] = Build("H U . . . A A A", "P U . . . F F F", "C U . . . . K K", "L U . . . . . .", "T . Q Q Q Q Q Q")
			};
			Counts = new int[11];
			Numbers = new int[8, 5];
			Slots = new Vector2i[11, 41];
			for (int i = 0; i < 5; i++)
			{
				for (int j = 0; j < 8; j++)
				{
					int num = (int)Layout[j, i];
					int num2 = ++Counts[num];
					Numbers[j, i] = num2;
					Slots[num, num2] = new Vector2i(j, i);
				}
			}
		}

		public static Vector2i FromLayout(int version, Vector2i pos)
		{
			//IL_0037: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_0088: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			if (version == 4 || !Earlier.TryGetValue(version, out var value) || pos.x < 0 || pos.y < 0 || pos.x >= 8 || pos.y >= 5)
			{
				return pos;
			}
			Kind kind = value[pos.x, pos.y];
			if (kind == Kind.None)
			{
				return pos;
			}
			int num = 0;
			for (int i = 0; i < 5; i++)
			{
				for (int j = 0; j < 8; j++)
				{
					if (value[j, i] != kind)
					{
						continue;
					}
					num++;
					if (j == pos.x && i == pos.y)
					{
						Vector2i val = Slot(kind, num);
						if (val.x < 0)
						{
							return pos;
						}
						return val;
					}
				}
			}
			return pos;
		}

		private static Kind[,] Build(params string[] rows)
		{
			Kind[,] array = new Kind[8, 5];
			for (int i = 0; i < 5; i++)
			{
				string[] array2 = rows[i].Split(new char[1] { ' ' });
				for (int j = 0; j < 8; j++)
				{
					switch (array2[j])
					{
					case "H":
						array[j, i] = Kind.Helmet;
						break;
					case "C":
						array[j, i] = Kind.Chest;
						break;
					case "L":
						array[j, i] = Kind.Legs;
						break;
					case "P":
						array[j, i] = Kind.Cape;
						break;
					case "T":
						array[j, i] = Kind.Trinket;
						break;
					case "U":
						array[j, i] = Kind.Utility;
						break;
					case "F":
						array[j, i] = Kind.Food;
						break;
					case "A":
						array[j, i] = Kind.Ammo;
						break;
					case "K":
						array[j, i] = Kind.Key;
						break;
					case "Q":
						array[j, i] = Kind.Quick;
						break;
					default:
						array[j, i] = Kind.None;
						break;
					}
				}
			}
			return array;
		}

		public static Kind At(int x, int y)
		{
			if (x < 0 || y < 0 || x >= 8 || y >= 5)
			{
				return Kind.None;
			}
			return Layout[x, y];
		}

		public static Kind At(Vector2i pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return At(pos.x, pos.y);
		}

		public static int Count(Kind kind)
		{
			if (kind < Kind.None || (int)kind >= Counts.Length)
			{
				return 0;
			}
			return Counts[(int)kind];
		}

		public static int Number(Vector2i pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (pos.x >= 0 && pos.y >= 0 && pos.x < 8 && pos.y < 5)
			{
				return Numbers[pos.x, pos.y];
			}
			return Counts[0];
		}

		public static Vector2i Slot(Kind kind, int number)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (kind < Kind.None || (int)kind >= Counts.Length || number <= 0 || number > Counts[(int)kind])
			{
				return new Vector2i(-1, -1);
			}
			return Slots[(int)kind, number];
		}

		public static Vector2i Home(Inventory slots, ItemData item)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Vector2i val = default(Vector2i);
			((Vector2i)(ref val))..ctor(-1, -1);
			for (int i = 0; i < 5; i++)
			{
				for (int j = 0; j < 8; j++)
				{
					Kind kind = Layout[j, i];
					if (kind != Kind.None && kind != Kind.Quick && Fits(kind, item))
					{
						ItemData itemAt = slots.GetItemAt(j, i);
						if (itemAt == null)
						{
							return new Vector2i(j, i);
						}
						if (itemAt != item && val.x < 0)
						{
							((Vector2i)(ref val))..ctor(j, i);
						}
					}
				}
			}
			return val;
		}

		public static bool Fits(Vector2i pos, ItemData item)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return Fits(At(pos), item);
		}

		public static bool Fits(Kind kind, ItemData item)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Invalid comparison between Unknown and I4
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Invalid comparison between Unknown and I4
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Invalid comparison between Unknown and I4
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Invalid comparison between Unknown and I4
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Invalid comparison between Unknown and I4
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Invalid comparison between Unknown and I4
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Invalid comparison between Unknown and I4
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Invalid comparison between Unknown and I4
			SharedData val = item?.m_shared;
			if (val == null)
			{
				return false;
			}
			switch (kind)
			{
			case Kind.Helmet:
				return (int)val.m_itemType == 6;
			case Kind.Chest:
				return (int)val.m_itemType == 7;
			case Kind.Legs:
				return (int)val.m_itemType == 11;
			case Kind.Cape:
				return (int)val.m_itemType == 17;
			case Kind.Trinket:
				return (int)val.m_itemType == 24;
			case Kind.Utility:
				return (int)val.m_itemType == 18;
			case Kind.Food:
				if ((int)val.m_itemType == 2)
				{
					if (!(val.m_food > 0f) && !(val.m_foodStamina > 0f))
					{
						return val.m_foodEitr > 0f;
					}
					return true;
				}
				return false;
			case Kind.Ammo:
				return (int)val.m_itemType == 9;
			case Kind.Key:
				if (!val.m_questItem)
				{
					return (int)val.m_itemType == 16;
				}
				return true;
			case Kind.Quick:
				return true;
			default:
				return false;
			}
		}

		public static bool MayDrop(Inventory target, bool targetIsSlots, bool fromIsSlots, ItemData item, int amount, Vector2i pos)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (targetIsSlots && !Fits(pos, item))
			{
				return false;
			}
			ItemData val = ((target != null) ? target.GetItemAt(pos.x, pos.y) : null);
			if (val != null && val != item && item.m_stack == amount && (val.m_shared.m_name != item.m_shared.m_name || (item.m_shared.m_maxQuality > 1 && val.m_quality != item.m_quality) || val.m_shared.m_maxStackSize == 1) && fromIsSlots)
			{
				return Fits(item.m_gridPos, val);
			}
			return true;
		}

		public static bool Add(Inventory slots, ItemData item, Action<int, int> placeAt)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 5; i++)
			{
				if (item.m_stack <= 0)
				{
					break;
				}
				for (int j = 0; j < 8; j++)
				{
					if (item.m_stack <= 0)
					{
						break;
					}
					ItemData itemAt = slots.GetItemAt(j, i);
					if (itemAt != null && itemAt.IsSameType(item) && itemAt.m_stack < itemAt.m_shared.m_maxStackSize)
					{
						placeAt(j, i);
					}
				}
			}
			for (int k = 0; k < 2; k++)
			{
				if (item.m_stack <= 0)
				{
					break;
				}
				bool flag = k == 1;
				for (int l = 0; l < 5; l++)
				{
					if (item.m_stack <= 0)
					{
						break;
					}
					for (int m = 0; m < 8; m++)
					{
						if (item.m_stack <= 0)
						{
							break;
						}
						if (At(m, l) == Kind.Quick == flag && slots.GetItemAt(m, l) == null && Fits(new Vector2i(m, l), item))
						{
							placeAt(m, l);
						}
					}
				}
			}
			return item.m_stack == 0;
		}
	}
	internal static class ExtraInventory
	{
		[HarmonyPatch(typeof(Player), "Update")]
		private static class AmmoHotkeyPatch
		{
			private static void Prefix(Player __instance)
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !AmmoInputAllowed())
				{
					return;
				}
				for (int i = 0; i < AmmoKeys.Length; i++)
				{
					if (((ButtonControl)Keyboard.current[AmmoInputKeys[i]]).wasPressedThisFrame)
					{
						Vector2i val = EquipmentSlots.Slot(EquipmentSlots.Kind.Ammo, i + 1);
						ItemData itemAt = Equipment.GetItemAt(val.x, val.y);
						if (itemAt != null && ((Humanoid)__instance).GetAmmoItem() != itemAt)
						{
							((Humanoid)__instance).EquipItem(itemAt, true);
						}
						break;
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZInput), "GetButtonDown")]
		private static class AmmoButtonPatch
		{
			private static void Postfix(string name, ref bool __result)
			{
				if (!__result)
				{
					return;
				}
				ZInput instance = ZInput.instance;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					ButtonDef buttonDef = instance.GetButtonDef(name);
					obj = ((buttonDef != null) ? buttonDef.ButtonAction.activeControl : null);
				}
				InputControl val = (InputControl)obj;
				if (val == null || (object)val.device != Keyboard.current)
				{
					return;
				}
				for (int i = 0; i < AmmoInputKeys.Length; i++)
				{
					if ((object)val == Keyboard.current[AmmoInputKeys[i]] && OwnsAmmoKey(AmmoKeys[i]))
					{
						__result = false;
						break;
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZInput), "GetKeyDown")]
		private static class AmmoRawKeyPatch
		{
			private static void Postfix(KeyCode key, ref bool __result)
			{
				//IL_0004: Unknown result type (might be due to invalid IL or missing references)
				if (__result && OwnsAmmoKey(key))
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		private static class CraftDestinationPatch
		{
			private static void Prefix(InventoryGui __instance, out Tuple<Inventory, string> __state)
			{
				__state = Tuple.Create<Inventory, string>(_upgradePage, _upgradeName);
				ItemData val = UpgradeItem.Invoke(__instance);
				_upgradePage = (Available ? FindPage(val) : null);
				object upgradeName;
				if (val == null)
				{
					upgradeName = null;
				}
				else
				{
					GameObject dropPrefab = val.m_dropPrefab;
					upgradeName = ((dropPrefab != null) ? ((Object)dropPrefab).name : null);
				}
				_upgradeName = (string)upgradeName;
			}

			private static void Finalizer(Tuple<Inventory, string> __state)
			{
				_upgradePage = __state.Item1;
				_upgradeName = __state.Item2;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(string),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(long),
			typeof(string),
			typeof(Vector2i),
			typeof(bool),
			typeof(bool),
			typeof(bool)
		})]
		private static class CreatePlayerItemPatch
		{
			[HarmonyPriority(0)]
			private static bool Prefix(Inventory __instance, string name, int stack, int quality, int variant, long crafterID, string crafterName, Vector2i position, bool cheated, bool pickedUp, bool dropIfFullInv, ref ItemData __result)
			{
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: 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)
				if (!IsMain(__instance) || _routingCreate)
				{
					return true;
				}
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(name);
				if ((Object)(object)itemPrefab == (Object)null)
				{
					return true;
				}
				ItemData val = itemPrefab.GetComponent<ItemDrop>().m_itemData.Clone();
				val.m_quality = quality;
				val.m_worldLevel = (byte)Game.m_worldLevel;
				val.m_stack = stack;
				bool flag = _upgradePage != null && name == _upgradeName && position.x >= 0;
				if (!flag && InventoryTransfers.Capacity(__instance, val) >= stack)
				{
					return true;
				}
				_routingCreate = true;
				bool routingAdd = _routingAdd;
				_routingAdd = true;
				try
				{
					if (flag)
					{
						__result = _upgradePage.AddItem(name, stack, quality, variant, crafterID, crafterName, position, cheated, pickedUp, dropIfFullInv);
						return false;
					}
					List<Inventory> list = new List<Inventory>();
					list.Add(__instance);
					list.AddRange(Visible);
					int num = stack;
					foreach (Inventory item in list)
					{
						int num2 = Math.Min(num, InventoryTransfers.Capacity(item, val));
						if (num2 > 0)
						{
							ItemData val2 = item.AddItem(name, num2, quality, variant, crafterID, crafterName, new Vector2i(-1, -1), cheated, pickedUp, dropIfFullInv);
							if (val2 == null)
							{
								break;
							}
							__result = val2;
							num -= num2;
							if (num == 0)
							{
								break;
							}
						}
					}
					if (num > 0)
					{
						__result = __instance.AddItem(name, num, quality, variant, crafterID, crafterName, new Vector2i(-1, -1), cheated, pickedUp, dropIfFullInv) ?? __result;
					}
					return false;
				}
				finally
				{
					_routingCreate = false;
					_routingAdd = routingAdd;
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Load", new Type[] { typeof(ZPackage) })]
		private static class LoadPatch
		{
			private static void Postfix(Player __instance)
			{
				Read(__instance);
				DressPreview(__instance);
			}
		}

		[HarmonyPatch(typeof(Player), "Save", new Type[] { typeof(ZPackage) })]
		private static class SavePatch
		{
			private static void Prefix(Player __instance)
			{
				Write(__instance);
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Show")]
		private static class ShowPatch
		{
			private static void Postfix(InventoryGui __instance)
			{
				Build(__instance);
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "UpdateContainer")]
		private static class UpdatePatch
		{
			private static void Postfix(InventoryGui __instance)
			{
				Refresh(__instance);
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
		private static class MovePatch
		{
			private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Modifier mod)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Invalid comparison between Unknown and I4
				//IL_009c: 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_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				if ((int)mod != 2 || item == null || (Object)(object)_grid == (Object)null || (Object)(object)grid != (Object)(object)_grid || DragItem.Invoke(__instance) != null || item.m_shared.m_questItem)
				{
					return true;
				}
				Container val = OpenChest.Invoke(__instance);
				if ((Object)(object)val == (Object)null)
				{
					return true;
				}
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsTeleporting())
				{
					return false;
				}
				((Humanoid)localPlayer).RemoveEquipAction(item);
				((Humanoid)localPlayer).UnequipItem(item, true);
				val.GetInventory().MoveItemToThis(grid.GetInventory(), item);
				__instance.m_moveItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				return false;
			}
		}

		private sealed class DeathState
		{
			public Inventory Main;

			public List<ItemData> MainItems;

			public int Height;

			public readonly Dictionary<ItemData, Vector2i> Positions = new Dictionary<ItemData, Vector2i>();
		}

		[HarmonyPatch(typeof(Player), "CreateTombStone")]
		private static class DeathPatch
		{
			private static void Prefix(Player __instance, out DeathState __state)
			{
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_010c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				__state = null;
				if (!Ready || (Object)(object)__instance != (Object)(object)_owner || _deathTransfer)
				{
					return;
				}
				Inventory inventory = ((Humanoid)__instance).GetInventory();
				__state = new DeathState
				{
					Main = inventory,
					MainItems = Items.Invoke(inventory),
					Height = inventory.GetHeight()
				};
				List<ItemData> list = new List<ItemData>(__state.MainItems);
				foreach (ItemData mainItem in __state.MainItems)
				{
					MarkHome(mainItem, -1, mainItem.m_gridPos);
				}
				int num = 0;
				for (int i = 0; i < _pages.Length; i++)
				{
					foreach (ItemData item in Items.Invoke(_pages[i]))
					{
						MarkHome(item, i, item.m_gridPos);
						__state.Positions.Add(item, item.m_gridPos);
						item.m_gridPos = new Vector2i(num % inventory.GetWidth(), __state.Height + num / inventory.GetWidth());
						list.Add(item);
						num++;
					}
				}
				_deathTransfer = true;
				Items.Invoke(inventory) = list;
				inventory.SetHeight(__state.Height + (num + inventory.GetWidth() - 1) / inventory.GetWidth());
			}

			private static void Finalizer(DeathState __state)
			{
				//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				if (__state == null)
				{
					return;
				}
				Inventory[] pages;
				try
				{
					HashSet<ItemData> survivors = new HashSet<ItemData>(Items.Invoke(__state.Main));
					foreach (ItemData item in survivors)
					{
						ClearHome(item);
					}
					__state.MainItems.RemoveAll((ItemData item) => !survivors.Contains(item));
					Items.Invoke(__state.Main) = __state.MainItems;
					pages = _pages;
					foreach (Inventory val in pages)
					{
						Items.Invoke(val).RemoveAll((ItemData item) => !survivors.Contains(item));
						foreach (ItemData item2 in Items.Invoke(val))
						{
							item2.m_gridPos = __state.Positions[item2];
						}
					}
					__state.Main.SetHeight(__state.Height);
				}
				finally
				{
					_deathTransfer = false;
				}
				Notify(__state.Main);
				pages = _pages;
				for (int num = 0; num < pages.Length; num++)
				{
					Notify(pages[num]);
				}
				Write(_owner);
			}
		}

		[HarmonyPatch]
		private static class ContainerDragPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				yield return AccessTools.Method(typeof(InventoryGui), "UpdateContainer", (Type[])null, (Type[])null);
				yield return AccessTools.Method(typeof(InventoryGui), "CloseContainer", (Type[])null, (Type[])null);
			}

			private static void Prefix(out bool __state)
			{
				__state = _preservePageDrag;
				_preservePageDrag = true;
			}

			private static void Finalizer(bool __state)
			{
				_preservePageDrag = __state;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "SetupDragItem")]
		private static class KeepPageDragPatch
		{
			private static bool Prefix(InventoryGui __instance, ItemData item)
			{
				if (!_preservePageDrag || item != null || !Enabled)
				{
					return true;
				}
				Inventory val = DragInventory.Invoke(__instance);
				ItemData val2 = DragItem.Invoke(__instance);
				if (OwnsInventory(val) && val2 != null)
				{
					return !val.ContainsItem(val2);
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Hide")]
		private static class HideDragPatch
		{
			private static void Prefix(out bool __state)
			{
				__state = _preservePageDrag;
				_preservePageDrag = false;
			}

			private static void Finalizer(bool __state)
			{
				_preservePageDrag = __state;
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "DropItem")]
		private static class SlotDropPatch
		{
			private static bool Prefix(InventoryGrid __instance, Inventory fromInventory, ItemData item, int amount, Vector2i pos, ref bool __result)
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				Inventory inventory = __instance.GetInventory();
				ClearHome(item);
				if (item == null || (!IsEquipment(inventory) && !IsEquipment(fromInventory)))
				{
					return true;
				}
				if (EquipmentSlots.MayDrop(inventory, IsEquipment(inventory), IsEquipment(fromInventory), item, amount, pos))
				{
					return true;
				}
				__result = false;
				return false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(bool)
		})]
		private static class SlotPlacePatch
		{
			private static bool Prefix(Inventory __instance, ItemData item, int x, int y, ref bool __result)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				if (!IsEquipment(__instance) || Fits(new Vector2i(x, y), item))
				{
					return true;
				}
				__result = false;
				return false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
		private static class SlotAddPatch
		{
			[HarmonyPriority(800)]
			private static bool Prefix(Inventory __instance, ItemData item, ref bool __result)
			{
				if (!IsEquipment(__instance) || item == null)
				{
					return true;
				}
				__result = EquipmentSlots.Add(__instance, item, delegate(int x, int y)
				{
					AddAt(__instance, item, x, y);
				});
				return false;
			}

			private static void AddAt(Inventory inventory, ItemData item, int x, int y)
			{
				PlaceAt(inventory, item, item.m_stack, x, y, arg6: false);
			}
		}

		[HarmonyPatch(typeof(Humanoid), "EquipItem")]
		private static class SlotOnEquipPatch
		{
			[HarmonyPriority(0)]
			private static void Postfix(Humanoid __instance, ItemData item, bool __result)
			{
				if (__result && (Object)(object)__instance == (Object)(object)_owner && Available && EquipmentOn)
				{
					SendToSlot(item);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "UseHotbarItem")]
		private static class SlotHotkeyPatch
		{
			private static bool Prefix(Player __instance, int index)
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance != (Object)(object)_owner || !Available || !EquipmentOn)
				{
					return true;
				}
				bool key = ZInput.GetKey(SlotKey(EquipmentSlots.Kind.Quick), false);
				bool flag = !key && ZInput.GetKey(SlotKey(EquipmentSlots.Kind.Food), false);
				if (!key && !flag)
				{
					return true;
				}
				Vector2i val = EquipmentSlots.Slot(key ? EquipmentSlots.Kind.Quick : EquipmentSlots.Kind.Food, index);
				ItemData val2 = ((val.x >= 0) ? Equipment.GetItemAt(val.x, val.y) : null);
				if (val2 == null)
				{
					return flag;
				}
				((Humanoid)__instance).UseItem(Equipment, val2, false);
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
		private static class RefusedSlotPatch
		{
			private static void Postfix(InventoryGrid __instance)
			{
				//IL_00e8: 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_0142: Unknown result type (might be due to invalid IL or missing references)
				//IL_014c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				InventoryGui instance = InventoryGui.instance;
				List<InventoryElement> list = Elements.Invoke(__instance);
				if ((Object)(object)instance == (Object)null || list == null)
				{
					return;
				}
				ItemData val = DragItem.Invoke(instance);
				Inventory inventory = DragInventory.Invoke(instance);
				Inventory inventory2 = __instance.GetInventory();
				bool flag = val != null && Available && (IsEquipment(inventory2) || IsEquipment(inventory));
				if (!flag && RedBackgrounds.Count == 0)
				{
					return;
				}
				foreach (InventoryElement item in list)
				{
					Image val2 = (Image)(((Object)(object)item != (Object)null && (Object)(object)item.m_button != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					Color value;
					if (flag && !EquipmentSlots.MayDrop(inventory2, IsEquipment(inventory2), IsEquipment(inventory), val, DragAmount.Invoke(instance), item.Position))
					{
						if (!RedBackgrounds.ContainsKey(val2))
						{
							RedBackgrounds[val2] = ((Graphic)val2).color;
						}
						((Graphic)val2).color = new Color(Refused.r, Refused.g, Refused.b, RedBackgrounds[val2].a);
					}
					else if (RedBackgrounds.TryGetValue(val2, out value))
					{
						((Graphic)val2).color = value;
						RedBackgrounds.Remove(val2);
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
		private static class SlotShiftClickPatch
		{
			private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Modifier mod)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Invalid comparison between Unknown and I4
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				if ((int)mod != 1 || item == null || item.m_stack != 1 || (Object)(object)grid == (Object)null || DragItem.Invoke(__instance) != null || !Available || !EquipmentOn)
				{
					return true;
				}
				Player localPlayer = Player.m_localPlayer;
				Inventory inventory = grid.GetInventory();
				Inventory equipment = Equipment;
				if ((Object)(object)localPlayer == (Object)null || (Object)(object)localPlayer != (Object)(object)_owner || inventory == null || equipment == null || ((Character)localPlayer).IsTeleporting())
				{
					return true;
				}
				if (!((inventory == equipment) ? TakeOff(localPlayer, equipment, item) : PutOn(localPlayer, inventory, equipment, item)))
				{
					return true;
				}
				__instance.m_moveItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				return false;
			}

			private static bool PutOn(Player player, Inventory from, Inventory slots, ItemData item)
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				bool flag = from == ((Humanoid)player).GetInventory() || OwnsInventory(from);
				if (item.m_shared.m_questItem && !flag)
				{
					return false;
				}
				Vector2i val = EquipmentSlots.Home(slots, item);
				if (val.x < 0)
				{
					return false;
				}
				return Move(player, from, item, slots, val);
			}

			private static bool TakeOff(Player player, Inventory slots, ItemData item)
			{
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				Inventory inventory = ((Humanoid)player).GetInventory();
				for (int i = 0; i < 2; i++)
				{
					for (int j = ((i == 0) ? 1 : 0); j < ((i != 0) ? 1 : inventory.GetHeight()); j++)
					{
						for (int k = 0; k < inventory.GetWidth(); k++)
						{
							if (inventory.GetItemAt(k, j) == null)
							{
								return Move(player, slots, item, inventory, new Vector2i(k, j));
							}
						}
					}
				}
				Inventory[] visible = Visible;
				foreach (Inventory val in visible)
				{
					for (int m = 0; m < 5; m++)
					{
						for (int n = 0; n < 8; n++)
						{
							if (val.GetItemAt(n, m) == null)
							{
								return Move(player, slots, item, val, new Vector2i(n, m));
							}
						}
					}
				}
				return false;
			}

			private static bool Move(Player player, Inventory from, ItemData item, Inventory to, Vector2i pos)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: 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_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0101: Unknown result type (might be due to invalid IL or missing references)
				//IL_0107: Unknown result type (might be due to invalid IL or missing references)
				if (!EquipmentSlots.MayDrop(to, IsEquipment(to), IsEquipment(from), item, item.m_stack, pos))
				{
					return false;
				}
				ItemData itemAt = to.GetItemAt(pos.x, pos.y);
				bool num = ((Humanoid)player).IsItemEquiped(item);
				bool flag = itemAt != null && ((Humanoid)player).IsItemEquiped(itemAt);
				Vector2i gridPos = item.m_gridPos;
				((Humanoid)player).RemoveEquipAction(item);
				((Humanoid)player).UnequipItem(item, false);
				if (itemAt != null)
				{
					((Humanoid)player).RemoveEquipAction(itemAt);
					((Humanoid)player).UnequipItem(itemAt, false);
				}
				bool result;
				if (itemAt != null && itemAt != item)
				{
					from.RemoveItem(item);
					from.MoveItemToThis(to, itemAt, itemAt.m_stack, gridPos.x, gridPos.y);
					result = to.MoveItemToThis(from, item, item.m_stack, pos.x, pos.y);
				}
				else
				{
					result = to.MoveItemToThis(from, item, item.m_stack, pos.x, pos.y);
				}
				if (num)
				{
					ItemData itemAt2 = to.GetItemAt(pos.x, pos.y);
					if (itemAt2 != null)
					{
						((Humanoid)player).EquipItem(itemAt2, false);
					}
				}
				if (flag)
				{
					ItemData itemAt3 = from.GetItemAt(gridPos.x, gridPos.y);
					if (itemAt3 != null)
					{
						((Humanoid)player).EquipItem(itemAt3, false);
					}
				}
				return result;
			}
		}

		private struct Spot
		{
			public int Col;

			public int Row;

			public bool Known;
		}

		private struct Cell
		{
			public Vector2i Pos;

			public Spot Spot;

			public Rect Box;
		}

		private sealed class HudSlot
		{
			public Vector2i Pos;

			public Vector2i Cell;

			public EquipmentSlots.Kind Kind;

			public int Number;

			public int Row;

			public GameObject Go;

			public Image Icon;

			public GuiBar Durability;

			public TMP_Text Amount;

			public GameObject Equipped;

			public TMP_Text Binding;

			public ItemData Item;

			public Sprite EmptySprite;

			public Sprite LastSprite;

			public int LastStack = int.MinValue;

			public int LastMaxStack = int.MinValue;

			public float LastDurability = -1f;

			public bool LastBroken;
		}

		[HarmonyPatch(typeof(InventoryGrid), "UpdateGamepad")]
		private static class FocusFramePatch
		{
			private static bool Prefix(InventoryGrid __instance)
			{
				if (!((Object)(object)_focusGrid != (Object)(object)__instance))
				{
					return _focusFrame != Time.frameCount;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "MoveToLowerInventoryGrid")]
		private static class NavigateDownPatch
		{
			private static bool Prefix(InventoryGui __instance, Vector2i previousGridPosition)
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				if (!Available || (Object)(object)_grid == (Object)null || !_panel.activeInHierarchy || !__instance.m_playerGrid.m_uiGroup.IsActive)
				{
					return true;
				}
				ChangePage(0);
				Focus(__instance, _grid, previousGridPosition.x, 0);
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "MoveToUpperInventoryGrid")]
		private static class NavigateUpPatch
		{
			private static bool Prefix(InventoryGui __instance, Vector2i previousGridPosition)
			{
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				if (!Available || (Object)(object)_grid == (Object)null || !_panel.activeInHierarchy || !ChestGrid.Invoke(__instance).m_uiGroup.IsActive)
				{
					return true;
				}
				ChangePage(2);
				Focus(__instance, _grid, previousGridPosition.x, 4);
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "GetSelectedGamepadElement")]
		private static class SelectedPagePatch
		{
			private static bool Prefix(ref RectTransform __result)
			{
				if (!Available || (Object)(object)_grid == (Object)null || (Object)(object)_pageGroup == (Object)null || !_pageGroup.IsActive || !_panel.activeInHierarchy)
				{
					return true;
				}
				__result = _grid.GetGamepadSelectedElement();
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "ClearTouchSelection")]
		private static class ClearPageTouchPatch
		{
			private static void Postfix()
			{
				if ((Object)(object)_grid != (Object)null)
				{
					_grid.ClearTouchSelection();
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
		private static class InternalQuestMovePatch
		{
			private static void Prefix(InventoryGui __instance, InventoryGrid grid, out bool __state)
			{
				__state = _internalPlayerMove;
				Inventory val = DragInventory.Invoke(__instance);
				Inventory inventory = grid.GetInventory();
				_internalPlayerMove = Available && DragItem.Invoke(__instance) != null && (val == ((Humanoid)_owner).GetInventory() || OwnsInventory(val)) && (inventory == ((Humanoid)_owner).GetInventory() || OwnsInventory(inventory));
			}

			private static void Finalizer(bool __state)
			{
				_internalPlayerMove = __state;
			}

			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				FieldInfo quest = AccessTools.Field(typeof(SharedData), "m_questItem");
				MethodInfo check = AccessTools.Method(typeof(ExtraInventory), "RestrictedQuestItem", (Type[])null, (Type[])null);
				foreach (CodeInstruction instruction in instructions)
				{
					if (instruction.opcode == OpCodes.Ldfld && object.Equals(instruction.operand, quest))
					{
						instruction.opcode = OpCodes.Call;
						instruction.operand = check;
					}
					yield return instruction;
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "OnDestroy")]
		private static class DestroyPageUiPatch
		{
			private static void Prefix()
			{
				if ((Object)(object)_panel != (Object)null)
				{
					Object.Destroy((Object)(object)_panel);
				}
				if ((Object)(object)_rail != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)_rail).gameObject);
				}
				_panel = null;
				_grid = null;
				_rail = null;
				_pageGroup = null;
				_focusGrid = null;
			}
		}

		[HarmonyPatch]
		private static class PlayerQueriesPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				HashSet<string> names = new HashSet<string>
				{
					"CountItems", "CountItemsByName", "CountItemsByType", "HaveItem", "ContainsItem", "ContainsItemByName", "GetAmmoItem", "GetEquippedItems", "GetWornItems", "GetValuableItems",
					"GetAllItemsOfType", "GetAllItemsSortedByName", "GetAllItemsInGridOrder", "GetAllPieceTables", "ItemCheated", "AnyCheatedItem", "CheatedDamagingItemEquipped", "IsTeleportable"
				};
				MethodInfo[] methods = typeof(Inventory).GetMethods(BindingFlags.Instance | BindingFlags.Public);
				foreach (MethodInfo methodInfo in methods)
				{
					if (names.Contains(methodInfo.Name) || (methodInfo.Name == "GetAllItems" && methodInfo.GetParameters().Length != 0) || (methodInfo.Name == "GetItem" && methodInfo.GetParameters()[0].ParameterType == typeof(string)))
					{
						yield return methodInfo;
					}
				}
			}

			[HarmonyPriority(800)]
			private static void Prefix(Inventory __instance, out List<ItemData> __state)
			{
				__state = null;
				if (IsMain(__instance) && _queryInventory == null)
				{
					__state = Items.Invoke(__instance);
					Items.Invoke(__instance) = FillQueryItems(__instance);
					_queryInventory = __instance;
				}
			}

			private static void Finalizer(Inventory __instance, List<ItemData> __state)
			{
				if (__state != null)
				{
					Items.Invoke(__instance) = __state;
					_queryInventory = null;
					QueryItems.Clear();
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "GetAllItems", new Type[] { })]
		private static class PlayerListPatch
		{
			private static void Postfix(Inventory __instance, ref List<ItemData> __result)
			{