Decompiled source of CDEV AdvancedArmorStand v0.1.0

plugins/CDEV.AdvancedArmorStand/CDEV.AdvancedArmorStand.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("CDEV.AdvancedArmorStand")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+efb24945142928ac03192750576c1d4fe797e026")]
[assembly: AssemblyProduct("CDEV.AdvancedArmorStand")]
[assembly: AssemblyTitle("CDEV.AdvancedArmorStand")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
[module: UnverifiableCode]
[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 CDEV.AdvancedArmorStand
{
	[BepInPlugin("cdev.advancedarmorstand", "CDEV.AdvancedArmorStand", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class AdvancedArmorStandPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			AddLocalization();
			_harmony = new Harmony("cdev.advancedarmorstand");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
		}

		private void OnDestroy()
		{
			StandSession.Current?.Close();
			StandButtons.DestroyAll();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private static void AddLocalization()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "cdev_aas_open", "Open" },
				{ "cdev_aas_changepose", "Change pose" },
				{ "cdev_aas_equip", "Equip" },
				{ "cdev_aas_swap", "Swap" },
				{ "cdev_aas_hang", "Hang" },
				{ "cdev_aas_takeall", "Take off" },
				{ "cdev_aas_busy", "The armor stand is busy, try again" },
				{ "cdev_aas_cell_helmet", "Helmet" },
				{ "cdev_aas_cell_chest", "Chest" },
				{ "cdev_aas_cell_legs", "Legs" },
				{ "cdev_aas_cell_cape", "Cape" },
				{ "cdev_aas_cell_trinket", "Trinket" },
				{ "cdev_aas_cell_utility", "Utility" },
				{ "cdev_aas_cell_weapon", "Weapon" },
				{ "cdev_aas_cell_offhand", "Shield" },
				{ "cdev_aas_cell_twohanded", "Two-handed: takes both hands" },
				{ "cdev_aas_cell_ammo", "Ammo" },
				{ "cdev_aas_cell_hint", "Empty stand slot\nRight-click: skip when swapping" },
				{ "cdev_aas_cell_excluded", "Skipped when swapping\nRight-click: include again" }
			});
			text = "Russian";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "cdev_aas_open", "Открыть" },
				{ "cdev_aas_changepose", "Сменить позу" },
				{ "cdev_aas_equip", "Надеть" },
				{ "cdev_aas_swap", "Обменяться" },
				{ "cdev_aas_hang", "Повесить" },
				{ "cdev_aas_takeall", "Снять" },
				{ "cdev_aas_busy", "Стойка занята, попробуйте ещё раз" },
				{ "cdev_aas_cell_helmet", "Шлем" },
				{ "cdev_aas_cell_chest", "Нагрудник" },
				{ "cdev_aas_cell_legs", "Поножи" },
				{ "cdev_aas_cell_cape", "Плащ" },
				{ "cdev_aas_cell_trinket", "Тринкет" },
				{ "cdev_aas_cell_utility", "Пояс" },
				{ "cdev_aas_cell_weapon", "Оружие" },
				{ "cdev_aas_cell_offhand", "Щит" },
				{ "cdev_aas_cell_twohanded", "Двуручное: занимает обе руки" },
				{ "cdev_aas_cell_ammo", "Стрелы" },
				{ "cdev_aas_cell_hint", "Пустой слот стойки\nПКМ: не трогать при обмене" },
				{ "cdev_aas_cell_excluded", "Не участвует в обмене\nПКМ: снова включить" }
			});
		}
	}
	internal static class StandButtons
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__7_0;

			public static UnityAction <>9__7_1;

			public static UnityAction <>9__7_2;

			public static UnityAction <>9__7_3;

			internal void <Show>b__7_0()
			{
				StandSession.Current?.Exchange();
			}

			internal void <Show>b__7_1()
			{
				StandSession.Current?.Exchange();
			}

			internal void <Show>b__7_2()
			{
				StandSession.Current?.Exchange();
			}

			internal void <Show>b__7_3()
			{
				StandSession.Current?.TakeAll();
			}
		}

		private static readonly string[] ForeignButtonNames = new string[4] { "quickStackToContainerButton", "storeAllButton", "sortContainerButton", "restockFromContainerButton" };

		private static Button _equip;

		private static Button _swap;

		private static Button _hang;

		private static Button _takeAll;

		private static readonly List<GameObject> Hidden = new List<GameObject>();

		private static bool _modified;

		internal static void Show(StandSession session)
		{
			//IL_0074: 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_007f: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_takeAllButton == (Object)null)
			{
				return;
			}
			if ((Object)(object)_equip == (Object)null || (Object)(object)_swap == (Object)null || (Object)(object)_hang == (Object)null || (Object)(object)_takeAll == (Object)null)
			{
				DestroyAll();
				object obj = <>c.<>9__7_0;
				if (obj == null)
				{
					UnityAction val = delegate
					{
						StandSession.Current?.Exchange();
					};
					<>c.<>9__7_0 = val;
					obj = (object)val;
				}
				_equip = Create(instance, "CDEV_AdvancedArmorStand_Equip", (UnityAction)obj);
				object obj2 = <>c.<>9__7_1;
				if (obj2 == null)
				{
					UnityAction val2 = delegate
					{
						StandSession.Current?.Exchange();
					};
					<>c.<>9__7_1 = val2;
					obj2 = (object)val2;
				}
				_swap = Create(instance, "CDEV_AdvancedArmorStand_Swap", (UnityAction)obj2);
				object obj3 = <>c.<>9__7_2;
				if (obj3 == null)
				{
					UnityAction val3 = delegate
					{
						StandSession.Current?.Exchange();
					};
					<>c.<>9__7_2 = val3;
					obj3 = (object)val3;
				}
				_hang = Create(instance, "CDEV_AdvancedArmorStand_Hang", (UnityAction)obj3);
				object obj4 = <>c.<>9__7_3;
				if (obj4 == null)
				{
					UnityAction val4 = delegate
					{
						StandSession.Current?.TakeAll();
					};
					<>c.<>9__7_3 = val4;
					obj4 = (object)val4;
				}
				_takeAll = Create(instance, "CDEV_AdvancedArmorStand_TakeAll", (UnityAction)obj4);
			}
			SetLabel(_equip, "$cdev_aas_equip");
			SetLabel(_swap, "$cdev_aas_swap");
			SetLabel(_hang, "$cdev_aas_hang");
			SetLabel(_takeAll, "$cdev_aas_takeall");
			_modified = true;
			Refresh(session);
		}

		internal static void Refresh(StandSession session)
		{
			InventoryGui instance = InventoryGui.instance;
			if (!_modified || (Object)(object)instance == (Object)null || (Object)(object)_takeAll == (Object)null || (Object)(object)instance.m_currentContainer != (Object)(object)session.Container)
			{
				return;
			}
			HideIfActive(((Object)(object)instance.m_takeAllButton != (Object)null) ? ((Component)instance.m_takeAllButton).gameObject : null);
			HideIfActive(((Object)(object)instance.m_stackAllButton != (Object)null) ? ((Component)instance.m_stackAllButton).gameObject : null);
			HideIfActive(WeightBox(instance));
			Transform val = (((Object)(object)instance.m_takeAllButton != (Object)null) ? ((Component)instance.m_takeAllButton).transform.parent : null);
			if ((Object)(object)val != (Object)null)
			{
				string[] foreignButtonNames = ForeignButtonNames;
				foreach (string text in foreignButtonNames)
				{
					Transform val2 = val.Find(text);
					HideIfActive(((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : null);
				}
			}
			session.RefreshPlan();
			Button val3 = ((session.Mode == ExchangeMode.Equip) ? _equip : ((session.Mode == ExchangeMode.Swap) ? _swap : ((session.Mode == ExchangeMode.Hang) ? _hang : null)));
			bool hasItems = session.HasItems;
			SetActive(_equip, (Object)(object)val3 == (Object)(object)_equip);
			SetActive(_swap, (Object)(object)val3 == (Object)(object)_swap);
			SetActive(_hang, (Object)(object)val3 == (Object)(object)_hang);
			SetActive(_takeAll, hasItems);
			if (StandPanel.Applied)
			{
				float gap = StandPanel.Gap;
				float num = (StandPanel.Width - 3f * gap) / 2f;
				bool flag = (Object)(object)val3 != (Object)null && hasItems;
				float num2 = (flag ? gap : ((StandPanel.Width - num) / 2f));
				float x = (flag ? (2f * gap + num) : num2);
				Place(_equip, num2, num);
				Place(_swap, num2, num);
				Place(_hang, num2, num);
				Place(_takeAll, x, num);
			}
		}

		private static void Place(Button button, float x, float width)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Component)button).transform;
			Rect rect = val.rect;
			if (!Mathf.Approximately(((Rect)(ref rect)).width, width))
			{
				val.SetSizeWithCurrentAnchors((Axis)0, width);
			}
			rect = val.rect;
			if (!Mathf.Approximately(((Rect)(ref rect)).height, 34f))
			{
				val.SetSizeWithCurrentAnchors((Axis)1, 34f);
			}
			StandPanel.PlaceTopLeft(val, StandPanel.PanelPoint(x, StandPanel.ButtonsTop));
		}

		internal static void Hide()
		{
			InventoryGui instance = InventoryGui.instance;
			Container val = (((Object)(object)instance != (Object)null) ? instance.m_currentContainer : null);
			if ((Object)(object)val != (Object)null && !StandSession.Containers.Contains(val))
			{
				Restore();
			}
		}

		internal static void OnInventoryShow(Container container)
		{
			if ((Object)(object)container == (Object)null || !StandSession.Containers.Contains(container))
			{
				Restore();
			}
		}

		internal static void Restore()
		{
			if (!_modified)
			{
				return;
			}
			SetActive(_equip, active: false);
			SetActive(_swap, active: false);
			SetActive(_hang, active: false);
			SetActive(_takeAll, active: false);
			foreach (GameObject item in Hidden)
			{
				if ((Object)(object)item != (Object)null)
				{
					item.SetActive(true);
				}
			}
			Hidden.Clear();
			StandPanel.Restore();
			_modified = false;
		}

		internal static void DestroyAll()
		{
			Restore();
			Button[] array = (Button[])(object)new Button[4] { _equip, _swap, _hang, _takeAll };
			foreach (Button val in array)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
			_equip = null;
			_swap = null;
			_hang = null;
			_takeAll = null;
		}

		private static void SetActive(Button button, bool active)
		{
			if ((Object)(object)button != (Object)null && ((Component)button).gameObject.activeSelf != active)
			{
				((Component)button).gameObject.SetActive(active);
			}
		}

		private static void HideIfActive(GameObject go)
		{
			if (!((Object)(object)go == (Object)null) && go.activeSelf)
			{
				go.SetActive(false);
				if (!Hidden.Contains(go))
				{
					Hidden.Add(go);
				}
			}
		}

		private static GameObject WeightBox(InventoryGui gui)
		{
			if ((Object)(object)gui.m_containerWeight == (Object)null || (Object)(object)gui.m_container == (Object)null)
			{
				return null;
			}
			Transform parent = gui.m_containerWeight.transform.parent;
			if (!((Object)(object)parent != (Object)null) || !((Object)(object)parent.parent == (Object)(object)((Component)gui.m_container).transform))
			{
				return null;
			}
			return ((Component)parent).gameObject;
		}

		private static void SetLabel(Button button, string label)
		{
			TMP_Text componentInChildren = ((Component)button).GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null && Localization.instance != null)
			{
				componentInChildren.text = Localization.instance.Localize(label);
			}
		}

		private static Button Create(InventoryGui gui, string name, UnityAction onClick)
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			Button takeAllButton = gui.m_takeAllButton;
			UIGamePad component = ((Component)takeAllButton).GetComponent<UIGamePad>();
			bool enabled = (Object)(object)component != (Object)null && ((Behaviour)component).enabled;
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = false;
			}
			Button val = Object.Instantiate<Button>(takeAllButton, ((Component)takeAllButton).transform.parent);
			if ((Object)(object)component != (Object)null)
			{
				((Behaviour)component).enabled = enabled;
			}
			((Object)val).name = name;
			UIGamePad[] componentsInChildren = ((Component)val).GetComponentsInChildren<UIGamePad>(true);
			foreach (UIGamePad val2 in componentsInChildren)
			{
				if ((Object)(object)val2.m_hint != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val2.m_hint.gameObject);
				}
				Object.DestroyImmediate((Object)(object)val2);
			}
			UIInputHint[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<UIInputHint>(true);
			foreach (UIInputHint val3 in componentsInChildren2)
			{
				Object.DestroyImmediate((Object)(object)val3);
			}
			Localize[] componentsInChildren3 = ((Component)val).GetComponentsInChildren<Localize>(true);
			foreach (Localize val4 in componentsInChildren3)
			{
				Object.DestroyImmediate((Object)(object)val4);
			}
			val.onClick = new ButtonClickedEvent();
			((UnityEvent)val.onClick).AddListener(onClick);
			RectTransform val5 = (RectTransform)((Component)val).transform;
			val5.anchorMin = new Vector2(0.5f, 0.5f);
			val5.anchorMax = new Vector2(0.5f, 0.5f);
			((Component)val).gameObject.SetActive(false);
			return val;
		}
	}
	internal static class StandHover
	{
		private static readonly StringBuilder Builder = new StringBuilder(256);

		internal static string Get(ArmorStand stand)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)stand == (Object)null || Localization.instance == null)
			{
				return string.Empty;
			}
			Builder.Length = 0;
			Builder.Append(stand.m_name);
			if (!PrivateArea.CheckAccess(((Component)stand).transform.position, 0f, false, false))
			{
				Builder.Append("\n$piece_noaccess");
				return Localization.instance.Localize(Builder.ToString());
			}
			Builder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] $cdev_aas_open");
			if ((Object)(object)stand.m_changePoseSwitch != (Object)null)
			{
				Builder.Append("\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] $cdev_aas_changepose");
			}
			Builder.Append("\n[<color=yellow><b>$KEY_HotbarUse</b></color>] $piece_itemstand_attach");
			return Localization.instance.Localize(Builder.ToString());
		}
	}
	internal enum CellKind
	{
		Helmet,
		Chest,
		Legs,
		Cape,
		Trinket,
		Utility,
		Weapon,
		Offhand,
		Ammo
	}
	internal readonly struct StandCell
	{
		internal readonly CellKind Kind;

		internal readonly int Physical;

		internal readonly Vector2i GridPos;

		internal StandCell(CellKind kind, int physical, Vector2i gridPos)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Kind = kind;
			Physical = physical;
			GridPos = gridPos;
		}
	}
	internal static class StandLayout
	{
		internal const int Width = 3;

		internal const int Height = 3;

		private static readonly ConditionalWeakTable<ArmorStand, StandCell[]> Cache = new ConditionalWeakTable<ArmorStand, StandCell[]>();

		internal static StandCell[] Get(ArmorStand stand)
		{
			return Cache.GetValue(stand, Build);
		}

		internal static Vector2i GridPosOf(CellKind kind)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_005e: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			return (Vector2i)(kind switch
			{
				CellKind.Ammo => new Vector2i(0, 0), 
				CellKind.Helmet => new Vector2i(1, 0), 
				CellKind.Cape => new Vector2i(2, 0), 
				CellKind.Weapon => new Vector2i(0, 1), 
				CellKind.Chest => new Vector2i(1, 1), 
				CellKind.Offhand => new Vector2i(2, 1), 
				CellKind.Trinket => new Vector2i(0, 2), 
				CellKind.Legs => new Vector2i(1, 2), 
				_ => new Vector2i(2, 2), 
			});
		}

		private static StandCell[] Build(ArmorStand stand)
		{
			bool[] used = new bool[stand.m_slots.Count];
			int physical = TakeVis(stand, used, (VisSlot)6);
			int physical2 = TakeVis(stand, used, (VisSlot)4);
			int physical3 = TakeVis(stand, used, (VisSlot)5);
			int physical4 = TakeVis(stand, used, (VisSlot)7);
			int physical5 = TakeVis(stand, used, (VisSlot)8);
			int num = TakeVis(stand, used, (VisSlot)1);
			if (num < 0)
			{
				num = TakeSupporting(stand, used, (ItemType)3);
			}
			int num2 = TakeVis(stand, used, (VisSlot)0);
			if (num2 < 0)
			{
				num2 = TakeSupporting(stand, used, (ItemType)5);
			}
			int physical6 = TakeSpare(used);
			int physical7 = TakeSpare(used);
			List<StandCell> list = new List<StandCell>(9);
			Add(list, CellKind.Helmet, physical);
			Add(list, CellKind.Chest, physical2);
			Add(list, CellKind.Legs, physical3);
			Add(list, CellKind.Cape, physical4);
			Add(list, CellKind.Trinket, physical6);
			Add(list, CellKind.Utility, physical5);
			Add(list, CellKind.Weapon, num);
			Add(list, CellKind.Offhand, num2);
			Add(list, CellKind.Ammo, physical7);
			return list.ToArray();
		}

		private static void Add(List<StandCell> cells, CellKind kind, int physical)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (physical >= 0)
			{
				cells.Add(new StandCell(kind, physical, GridPosOf(kind)));
			}
		}

		private static int TakeVis(ArmorStand stand, bool[] used, VisSlot vis)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < used.Length; i++)
			{
				if (!used[i] && stand.m_slots[i].m_slot == vis)
				{
					used[i] = true;
					return i;
				}
			}
			return -1;
		}

		private static int TakeSupporting(ArmorStand stand, bool[] used, ItemType type)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < used.Length; i++)
			{
				List<ItemType> supportedTypes = stand.m_slots[i].m_supportedTypes;
				if (!used[i] && supportedTypes != null && supportedTypes.Contains(type))
				{
					used[i] = true;
					return i;
				}
			}
			return -1;
		}

		private static int TakeSpare(bool[] used)
		{
			for (int num = used.Length - 1; num >= 0; num--)
			{
				if (!used[num])
				{
					used[num] = true;
					return num;
				}
			}
			return -1;
		}

		internal static bool IsStorageOnly(CellKind kind)
		{
			if (kind != CellKind.Trinket)
			{
				return kind == CellKind.Ammo;
			}
			return true;
		}

		internal static bool IsStorageOnlyType(ItemType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)type != 24)
			{
				return (int)type == 9;
			}
			return true;
		}

		internal static bool Accepts(ArmorStand stand, StandCell cell, ItemData item)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Invalid comparison between Unknown and I4
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (item == null || (Object)(object)item.m_dropPrefab == (Object)null)
			{
				return false;
			}
			ItemType itemType = item.m_shared.m_itemType;
			switch (cell.Kind)
			{
			case CellKind.Trinket:
				return (int)itemType == 24;
			case CellKind.Ammo:
				return (int)itemType == 9;
			default:
				if (cell.Kind == CellKind.Offhand && item.IsTwoHanded())
				{
					return false;
				}
				if (!IsStorageOnlyType(itemType) && stand.CanAttach(stand.m_slots[cell.Physical], item))
				{
					return StandSlots.HasVisual(item);
				}
				return false;
			}
		}

		internal static bool IsBow(ItemData item)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if (item != null)
			{
				return (int)item.m_shared.m_itemType == 4;
			}
			return false;
		}

		internal static bool IsShield(ItemData item)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			if (item != null)
			{
				return (int)item.m_shared.m_itemType == 5;
			}
			return false;
		}

		internal static bool IsMelee(ItemData item)
		{
			if (item != null && IsHandGear(item) && !IsBow(item))
			{
				return !IsShield(item);
			}
			return false;
		}

		internal static int MaxStack(StandCell cell, ItemData item)
		{
			if (cell.Kind != CellKind.Ammo)
			{
				return 1;
			}
			return Math.Max(1, item.m_shared.m_maxStackSize);
		}

		internal static bool IsHand(CellKind kind)
		{
			if (kind != CellKind.Weapon)
			{
				return kind == CellKind.Offhand;
			}
			return true;
		}

		internal static bool IsHandGear(ItemData item)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_0011: 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_0015: Invalid comparison between Unknown and I4
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			ItemType itemType = item.m_shared.m_itemType;
			if ((int)itemType <= 14)
			{
				if (itemType - 3 <= 2 || (int)itemType == 14)
				{
					goto IL_0028;
				}
			}
			else if ((int)itemType == 20 || (int)itemType == 22)
			{
				goto IL_0028;
			}
			return false;
			IL_0028:
			return true;
		}

		internal static ItemData WornFor(Player player, CellKind kind)
		{
			return (ItemData)(kind switch
			{
				CellKind.Helmet => ((Humanoid)player).m_helmetItem, 
				CellKind.Chest => ((Humanoid)player).m_chestItem, 
				CellKind.Legs => ((Humanoid)player).m_legItem, 
				CellKind.Cape => ((Humanoid)player).m_shoulderItem, 
				CellKind.Utility => ((Humanoid)player).m_utilityItem, 
				CellKind.Trinket => ((Humanoid)player).m_trinketItem, 
				CellKind.Ammo => ((Humanoid)player).m_ammoItem, 
				_ => null, 
			});
		}
	}
	internal static class StandLock
	{
		private static readonly int OpenedByKey = StringExtensionMethods.GetStableHashCode("cdev.advancedarmorstand.openedby");

		internal static bool IsHeldByOther(ZDO zdo)
		{
			long num = zdo.GetLong(OpenedByKey, 0L);
			if (num != 0L && num != ZDOMan.GetSessionID())
			{
				return num == zdo.GetOwner();
			}
			return false;
		}

		internal static void Take(ZDO zdo)
		{
			zdo.Set(OpenedByKey, ZDOMan.GetSessionID());
		}

		internal static void Release(ZDO zdo)
		{
			if (zdo.IsOwner() && zdo.GetLong(OpenedByKey, 0L) == ZDOMan.GetSessionID())
			{
				zdo.Set(OpenedByKey, 0L);
			}
		}
	}
	internal static class StandPanel
	{
		private const float MinGap = 8f;

		internal const float ButtonHeight = 34f;

		private static RectTransform _panel;

		private static RectTransform _grid;

		private static GameObject _sunken;

		private static Vector2 _panelSize;

		private static Vector2 _gridOffsetMin;

		private static Vector2 _gridOffsetMax;

		private static bool _sunkenWasActive;

		internal static bool Applied { get; private set; }

		internal static float Gap { get; private set; }

		internal static float Width { get; private set; }

		internal static float ButtonsTop { get; private set; }

		internal static void Apply(InventoryGui gui, InventoryGrid grid, StandSession session)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//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_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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Expected O, but got Unknown
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Expected O, but got Unknown
			if ((Object)(object)gui.m_container == (Object)null || grid.m_elements.Count == 0 || (Object)(object)grid.m_elements[0] == (Object)null)
			{
				return;
			}
			if (Applied && (Object)(object)_panel != (Object)(object)gui.m_container)
			{
				Applied = false;
			}
			if (!Applied)
			{
				_panel = gui.m_container;
				_grid = (RectTransform)((Component)grid).transform;
				_panelSize = _panel.sizeDelta;
				_gridOffsetMin = _grid.offsetMin;
				_gridOffsetMax = _grid.offsetMax;
				Transform val = ((Transform)_panel).Find("sunken");
				_sunken = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null);
				_sunkenWasActive = (Object)(object)_sunken != (Object)null && _sunken.activeSelf;
				Applied = true;
			}
			if ((Object)(object)_sunken != (Object)null && _sunken.activeSelf)
			{
				_sunken.SetActive(false);
			}
			RectTransform val2 = (RectTransform)((Component)grid.m_elements[0]).transform;
			Rect rect = val2.rect;
			float width = ((Rect)(ref rect)).width;
			float num = Mathf.Max(grid.m_elementSpace - width, 8f);
			float num2 = TitleBottom(gui);
			float num3 = num2 + num;
			float num4 = 3f * width + 2f * num;
			float width2 = 4f * num + 3f * width;
			float num5 = num3 + num4 + num;
			float height = num5 + 34f + num;
			Gap = num;
			Width = width2;
			ButtonsTop = num5;
			SetSize(_panel, width2, height);
			SetOffsets(_grid, new Vector2(num, num), new Vector2(0f - num, 0f - num3));
			Vector2 val4 = default(Vector2);
			for (int i = 0; i < grid.m_elements.Count; i++)
			{
				InventoryElement val3 = grid.m_elements[i];
				if (!((Object)(object)val3 == (Object)null))
				{
					Vector2i position = val3.Position;
					((Vector2)(ref val4))..ctor(num + (float)position.x * (width + num), 0f - (num3 + (float)position.y * (width + num)));
					PlaceTopLeft((RectTransform)((Component)val3).transform, ((Transform)_panel).TransformPoint(Vector2.op_Implicit(val4)));
				}
			}
		}

		internal static void Restore()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (Applied)
			{
				if ((Object)(object)_panel != (Object)null)
				{
					_panel.sizeDelta = _panelSize;
				}
				if ((Object)(object)_grid != (Object)null)
				{
					_grid.offsetMin = _gridOffsetMin;
					_grid.offsetMax = _gridOffsetMax;
				}
				if ((Object)(object)_sunken != (Object)null && _sunkenWasActive)
				{
					_sunken.SetActive(true);
				}
				Applied = false;
			}
		}

		internal static void PlaceTopLeft(RectTransform rect, Vector3 worldTopLeft)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0026: 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_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_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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			Rect rect2 = rect.rect;
			Vector3 val = ((Transform)rect).TransformPoint(new Vector3(((Rect)(ref rect2)).xMin, ((Rect)(ref rect2)).yMax, 0f));
			Vector3 val2 = val - worldTopLeft;
			if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
			{
				((Transform)rect).position = ((Transform)rect).position + (worldTopLeft - val);
			}
		}

		internal static Vector3 PanelPoint(float x, float yFromTop)
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_panel != (Object)null))
			{
				return Vector3.zero;
			}
			return ((Transform)_panel).TransformPoint(new Vector3(x, 0f - yFromTop, 0f));
		}

		private static float TitleBottom(InventoryGui gui)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0048: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)gui.m_containerName == (Object)null)
			{
				return 31f;
			}
			RectTransform rectTransform = gui.m_containerName.rectTransform;
			RectTransform panel = _panel;
			Rect rect = rectTransform.rect;
			Vector3 val = ((Transform)panel).InverseTransformPoint(((Transform)rectTransform).TransformPoint(new Vector3(0f, ((Rect)(ref rect)).yMin, 0f)));
			return 0f - val.y;
		}

		private static void SetSize(RectTransform rect, float width, float height)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			Rect rect2 = rect.rect;
			if (!Mathf.Approximately(((Rect)(ref rect2)).width, width))
			{
				rect.SetSizeWithCurrentAnchors((Axis)0, width);
			}
			rect2 = rect.rect;
			if (!Mathf.Approximately(((Rect)(ref rect2)).height, height))
			{
				rect.SetSizeWithCurrentAnchors((Axis)1, height);
			}
		}

		private static void SetOffsets(RectTransform rect, Vector2 offsetMin, Vector2 offsetMax)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (rect.offsetMin != offsetMin)
			{
				rect.offsetMin = offsetMin;
			}
			if (rect.offsetMax != offsetMax)
			{
				rect.offsetMax = offsetMax;
			}
		}
	}
	internal static class StandPlaceholders
	{
		internal static readonly Color Tint = new Color(0.55f, 0.55f, 0.55f, 0.3f);

		private static readonly Dictionary<CellKind, Sprite> Cache = new Dictionary<CellKind, Sprite>();

		private static ObjectDB _cachedFor;

		internal static Sprite Get(CellKind kind)
		{
			ObjectDB instance = ObjectDB.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			if ((Object)(object)_cachedFor != (Object)(object)instance)
			{
				Cache.Clear();
				_cachedFor = instance;
			}
			if (!Cache.TryGetValue(kind, out var value))
			{
				value = Find(instance, kind);
				Cache[kind] = value;
			}
			return value;
		}

		private static Sprite Find(ObjectDB db, CellKind kind)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			Sprite val = IconOf(db.GetItemPrefab(PrefabName(kind)));
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			ItemType val2 = FallbackType(kind);
			foreach (GameObject item in db.m_items)
			{
				ItemDrop val3 = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val3 != (Object)null && val3.m_itemData.m_shared.m_itemType == val2)
				{
					Sprite val4 = IconOf(item);
					if ((Object)(object)val4 != (Object)null)
					{
						return val4;
					}
				}
			}
			return null;
		}

		private static Sprite IconOf(GameObject prefab)
		{
			ItemDrop val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null);
			Sprite[] array = (((Object)(object)val != (Object)null) ? val.m_itemData.m_shared.m_icons : null);
			if (array == null || array.Length == 0)
			{
				return null;
			}
			return array[0];
		}

		private static string PrefabName(CellKind kind)
		{
			return kind switch
			{
				CellKind.Helmet => "HelmetLeather", 
				CellKind.Chest => "ArmorLeatherChest", 
				CellKind.Legs => "ArmorLeatherLegs", 
				CellKind.Cape => "CapeDeerHide", 
				CellKind.Trinket => "TrinketBronzeHealth", 
				CellKind.Utility => "BeltStrength", 
				CellKind.Weapon => "SwordBronze", 
				CellKind.Ammo => "ArrowWood", 
				_ => "ShieldWood", 
			};
		}

		private static ItemType FallbackType(CellKind kind)
		{
			return (ItemType)(kind switch
			{
				CellKind.Helmet => 6, 
				CellKind.Chest => 7, 
				CellKind.Legs => 11, 
				CellKind.Cape => 17, 
				CellKind.Trinket => 24, 
				CellKind.Utility => 18, 
				CellKind.Weapon => 3, 
				CellKind.Ammo => 9, 
				_ => 5, 
			});
		}

		internal static string NameKey(CellKind kind)
		{
			return kind switch
			{
				CellKind.Helmet => "$cdev_aas_cell_helmet", 
				CellKind.Chest => "$cdev_aas_cell_chest", 
				CellKind.Legs => "$cdev_aas_cell_legs", 
				CellKind.Cape => "$cdev_aas_cell_cape", 
				CellKind.Trinket => "$cdev_aas_cell_trinket", 
				CellKind.Utility => "$cdev_aas_cell_utility", 
				CellKind.Weapon => "$cdev_aas_cell_weapon", 
				CellKind.Ammo => "$cdev_aas_cell_ammo", 
				_ => "$cdev_aas_cell_offhand", 
			};
		}
	}
	internal enum ExchangeMode
	{
		None,
		Equip,
		Swap,
		Hang
	}
	internal sealed class StandSession : MonoBehaviour
	{
		private struct Move
		{
			internal int Cell;

			internal ItemData OnStand;

			internal ItemData FromPlayer;
		}

		private enum HotbarPick
		{
			OneHandedMelee,
			AnyMelee,
			Shield,
			Bow
		}

		private readonly List<Move> _plan = new List<Move>(9);

		private ItemData _giveWeapon;

		private ItemData _giveOffhand;

		private readonly List<ItemData> _inventorySnapshot = new List<ItemData>(64);

		private int _planArriving;

		private int _planLeaving;

		private bool _oneHandedOnly;

		private const float OwnershipTimeout = 3f;

		internal static readonly HashSet<Container> Containers = new HashSet<Container>();

		private static readonly int ExcludedKey = StringExtensionMethods.GetStableHashCode("cdev.advancedarmorstand.excluded");

		private ZNetView _nview;

		private StandCell[] _cells;

		private int _slotCount;

		private bool[] _foreign;

		private readonly List<int> _strays = new List<int>();

		private ItemData[] _written;

		private int[] _writtenStack;

		private int _excludedMask;

		private uint _lastRevision;

		private bool _suspendSync;

		private bool _dirty;

		private bool _ended;

		internal ExchangeMode Mode { get; private set; }

		internal bool HasItems
		{
			get
			{
				if (Inventory.m_inventory.Count <= 0)
				{
					return _strays.Count > 0;
				}
				return true;
			}
		}

		internal static StandSession Current { get; private set; }

		internal ArmorStand Stand { get; private set; }

		internal Container Container { get; private set; }

		internal Inventory Inventory { get; private set; }

		internal int StrayCount => _strays.Count;

		internal void RefreshPlan()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				_plan.Clear();
				Mode = ExchangeMode.None;
			}
			else
			{
				BuildPlan(localPlayer);
			}
		}

		internal void Exchange()
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!CanAct(localPlayer))
			{
				return;
			}
			BuildPlan(localPlayer);
			if (Mode == ExchangeMode.None)
			{
				return;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			if (FreeSlotsAfterRemoving(inventory) < _planArriving)
			{
				((Character)localPlayer).Message((MessageType)2, "$inventory_full", 0, (Sprite)null, false);
				return;
			}
			foreach (Move item in _plan)
			{
				if (item.FromPlayer != null)
				{
					if (((Humanoid)localPlayer).IsItemEquiped(item.FromPlayer))
					{
						((Humanoid)localPlayer).UnequipItem(item.FromPlayer, false);
					}
					inventory.RemoveItem(item.FromPlayer);
				}
			}
			foreach (Move item2 in _plan)
			{
				if (item2.OnStand != null)
				{
					Inventory.m_inventory.Remove(item2.OnStand);
				}
				if (item2.FromPlayer != null)
				{
					item2.FromPlayer.m_equipped = false;
					item2.FromPlayer.m_gridPos = PosOf(item2.Cell);
					Inventory.m_inventory.Add(item2.FromPlayer);
				}
			}
			foreach (Move item3 in _plan)
			{
				if (item3.OnStand != null)
				{
					if (inventory.AddItem(item3.OnStand))
					{
						((Humanoid)localPlayer).EquipItem(item3.OnStand, true);
					}
					else
					{
						ReturnToPlayer(item3.OnStand);
					}
				}
			}
			FinishAction();
		}

		internal void TakeAll()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!CanAct(localPlayer) || !HasItems)
			{
				return;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			if (inventory.GetEmptySlots() < Inventory.m_inventory.Count + _strays.Count)
			{
				((Character)localPlayer).Message((MessageType)2, "$inventory_full", 0, (Sprite)null, false);
				return;
			}
			ItemData[] array = Inventory.m_inventory.ToArray();
			foreach (ItemData val in array)
			{
				Inventory.m_inventory.Remove(val);
				if (!inventory.AddItem(val))
				{
					ReturnToPlayer(val);
				}
			}
			int[] array2 = _strays.ToArray();
			foreach (int index in array2)
			{
				ItemData val2 = StandSlots.Load(Stand, index);
				if (val2 != null)
				{
					StandSlots.Clear(Stand, index);
					if (!inventory.AddItem(val2))
					{
						ReturnToPlayer(val2);
					}
				}
			}
			FinishAction();
			Reload();
		}

		private void BuildPlan(Player player)
		{
			BuildPlan(player, includeHotbar: false);
			if (_planArriving == 0)
			{
				BuildPlan(player, includeHotbar: true);
				Mode = ((_planLeaving > 0) ? ExchangeMode.Hang : ExchangeMode.None);
			}
			else if (_planLeaving == 0)
			{
				Mode = ExchangeMode.Equip;
			}
			else
			{
				BuildPlan(player, includeHotbar: true);
				Mode = ExchangeMode.Swap;
			}
		}

		private void BuildPlan(Player player, bool includeHotbar)
		{
			_plan.Clear();
			_planArriving = 0;
			_planLeaving = 0;
			SelectHands(player, includeHotbar);
			for (int i = 0; i < _slotCount; i++)
			{
				if (!_foreign[i] && !IsExcluded(i))
				{
					CellKind kind = _cells[i].Kind;
					ItemData val = ItemIn(i);
					ItemData val2 = (ItemData)(kind switch
					{
						CellKind.Weapon => _giveWeapon, 
						CellKind.Offhand => _giveOffhand, 
						CellKind.Ammo => PickAmmo(player, i, val != null), 
						_ => PickWorn(StandLayout.WornFor(player, kind), i), 
					});
					if (val != null || val2 != null)
					{
						_plan.Add(new Move
						{
							Cell = i,
							OnStand = val,
							FromPlayer = val2
						});
						_planArriving += ((val != null) ? 1 : 0);
						_planLeaving += ((val2 != null) ? 1 : 0);
					}
				}
			}
		}

		private ItemData PickAmmo(Player player, int cell, bool standHasAmmo)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Invalid comparison between Unknown and I4
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Invalid comparison between Unknown and I4
			ItemData val = null;
			for (int i = 0; i < _plan.Count; i++)
			{
				if (val != null)
				{
					break;
				}
				ItemData fromPlayer = _plan[i].FromPlayer;
				if (fromPlayer != null && (int)fromPlayer.m_shared.m_itemType == 4)
				{
					val = fromPlayer;
				}
			}
			if (val == null && !standHasAmmo)
			{
				return null;
			}
			ItemData val2 = PickWorn(((Humanoid)player).m_ammoItem, cell);
			if (val2 != null || val == null)
			{
				return val2;
			}
			ItemData val3 = null;
			List<ItemData> inventory = ((Humanoid)player).GetInventory().m_inventory;
			for (int j = 0; j < inventory.Count; j++)
			{
				ItemData val4 = inventory[j];
				if ((int)val4.m_shared.m_itemType == 9 && !(val4.m_shared.m_ammoType != val.m_shared.m_ammoType) && (val3 == null || val4.m_gridPos.y < val3.m_gridPos.y || (val4.m_gridPos.y == val3.m_gridPos.y && val4.m_gridPos.x < val3.m_gridPos.x)) && CanPlace(cell, val4) && !IsPlanned(val4))
				{
					val3 = val4;
				}
			}
			return val3;
		}

		private ItemData PickWorn(ItemData worn, int cell)
		{
			if (worn == null || !CanPlace(cell, worn) || IsPlanned(worn))
			{
				return null;
			}
			return worn;
		}

		private void SelectHands(Player player, bool includeHotbar)
		{
			_giveWeapon = null;
			_giveOffhand = null;
			int num = CellOf(CellKind.Weapon);
			int num2 = CellOf(CellKind.Offhand);
			bool oneHandedOnly = num2 >= 0 && IsExcluded(num2) && ItemIn(num2) != null;
			bool flag = num >= 0 && IsExcluded(num) && TwoHanderInWeaponCell() != null;
			if (num >= 0 && IsExcluded(num))
			{
				num = -1;
			}
			if (num2 >= 0 && (IsExcluded(num2) || flag))
			{
				num2 = -1;
			}
			_oneHandedOnly = oneHandedOnly;
			ItemData rightItem = ((Humanoid)player).m_rightItem;
			ItemData leftItem = ((Humanoid)player).m_leftItem;
			ItemData val = (StandLayout.IsBow(leftItem) ? leftItem : (StandLayout.IsBow(rightItem) ? rightItem : null));
			if (val != null)
			{
				_giveWeapon = Placeable(num, val);
				return;
			}
			ItemData val2 = null;
			if (num2 >= 0)
			{
				val2 = (StandLayout.IsShield(leftItem) ? Placeable(num2, leftItem) : null);
				if (val2 == null && includeHotbar)
				{
					val2 = FindInHotbar(player, num2, HotbarPick.Shield);
				}
			}
			ItemData val3 = null;
			if (num >= 0)
			{
				val3 = (StandLayout.IsMelee(rightItem) ? Placeable(num, rightItem) : null);
				if (val3 == null && StandLayout.IsMelee(leftItem))
				{
					val3 = Placeable(num, leftItem);
				}
				if (val3 == null && includeHotbar)
				{
					if (val2 != null)
					{
						val3 = FindInHotbar(player, num, HotbarPick.OneHandedMelee);
					}
					if (val3 == null)
					{
						val3 = FindInHotbar(player, num, HotbarPick.AnyMelee);
					}
				}
			}
			if (val3 == null && val2 == null && includeHotbar && num >= 0)
			{
				val3 = FindInHotbar(player, num, HotbarPick.Bow);
			}
			_giveWeapon = val3;
			_giveOffhand = ((val3 != null && val3.IsTwoHanded()) ? null : val2);
		}

		private ItemData Placeable(int cell, ItemData item)
		{
			if (cell < 0 || item == null || !CanPlace(cell, item) || IsPlanned(item))
			{
				return null;
			}
			if (!_oneHandedOnly || _cells[cell].Kind != CellKind.Weapon || !item.IsTwoHanded())
			{
				return item;
			}
			return null;
		}

		private ItemData FindInHotbar(Player player, int cell, HotbarPick pick)
		{
			ItemData val = null;
			List<ItemData> inventory = ((Humanoid)player).GetInventory().m_inventory;
			for (int i = 0; i < inventory.Count; i++)
			{
				ItemData val2 = inventory[i];
				if (val2.m_gridPos.y == 0 && !val2.m_equipped && (val == null || val.m_gridPos.x > val2.m_gridPos.x) && pick switch
				{
					HotbarPick.OneHandedMelee => StandLayout.IsMelee(val2) && !val2.IsTwoHanded(), 
					HotbarPick.AnyMelee => StandLayout.IsMelee(val2), 
					HotbarPick.Shield => StandLayout.IsShield(val2), 
					_ => StandLayout.IsBow(val2), 
				} && Placeable(cell, val2) != null)
				{
					val = val2;
				}
			}
			return val;
		}

		private bool IsPlanned(ItemData item)
		{
			for (int i = 0; i < _plan.Count; i++)
			{
				if (_plan[i].FromPlayer == item)
				{
					return true;
				}
			}
			return false;
		}

		private int FreeSlotsAfterRemoving(Inventory inventory)
		{
			List<ItemData> inventory2 = inventory.m_inventory;
			_inventorySnapshot.Clear();
			_inventorySnapshot.AddRange(inventory2);
			try
			{
				foreach (Move item in _plan)
				{
					if (item.FromPlayer != null)
					{
						inventory2.Remove(item.FromPlayer);
					}
				}
				return inventory.GetEmptySlots();
			}
			finally
			{
				inventory2.Clear();
				inventory2.AddRange(_inventorySnapshot);
				_inventorySnapshot.Clear();
			}
		}

		private bool CanAct(Player player)
		{
			if ((Object)(object)player != (Object)null && (Object)(object)Current == (Object)(object)this && !_ended && (Object)(object)_nview != (Object)null && _nview.IsValid())
			{
				return _nview.IsOwner();
			}
			return false;
		}

		private void FinishAction()
		{
			Inventory.Changed(false, false);
			Flush();
			PlayEffect();
		}

		private void PlayEffect()
		{
			//IL_001b: 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_002e: 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)
			EffectList effects = Stand.m_effects;
			if (effects != null)
			{
				effects.Create(((Component)Stand).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
		}

		internal static bool IsOpenOn(ArmorStand stand)
		{
			if ((Object)(object)Current != (Object)null)
			{
				return (Object)(object)Current.Stand == (Object)(object)stand;
			}
			return false;
		}

		internal static void RequestOpen(ArmorStand stand, Player player)
		{
			if (!((Object)(object)stand == (Object)null) && !((Object)(object)player == (Object)null) && !IsOpenOn(stand))
			{
				((MonoBehaviour)stand).StartCoroutine(OpenRoutine(stand, player));
			}
		}

		private static IEnumerator OpenRoutine(ArmorStand stand, Player player)
		{
			ZNetView nview = stand.m_nview;
			if ((Object)(object)nview == (Object)null || !nview.IsValid() || (Object)(object)InventoryGui.instance == (Object)null || StandLayout.Get(stand).Length == 0 || !PrivateArea.CheckAccess(((Component)stand).transform.position, 0f, true, false))
			{
				yield break;
			}
			if (StandLock.IsHeldByOther(nview.GetZDO()))
			{
				((Character)player).Message((MessageType)2, "$msg_inuse", 0, (Sprite)null, false);
				yield break;
			}
			if (!nview.IsOwner())
			{
				nview.InvokeRPC("RPC_RequestOwn", Array.Empty<object>());
				float deadline = Time.time + 3f;
				while ((Object)(object)stand != (Object)null && nview.IsValid() && !nview.IsOwner() && Time.time < deadline)
				{
					yield return null;
				}
				if ((Object)(object)stand == (Object)null || !nview.IsValid() || (Object)(object)player == (Object)null)
				{
					yield break;
				}
				if (!nview.IsOwner())
				{
					((Character)player).Message((MessageType)2, "$cdev_aas_busy", 0, (Sprite)null, false);
					yield break;
				}
			}
			if (!StandLock.IsHeldByOther(nview.GetZDO()) && !IsOpenOn(stand) && !((Object)(object)InventoryGui.instance == (Object)null))
			{
				Current?.Close();
				Create(stand);
			}
		}

		private static void Create(ArmorStand stand)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("CDEV_AdvancedArmorStand_Inventory");
			val.SetActive(false);
			val.transform.SetParent(((Component)stand).transform, false);
			StandSession standSession = val.AddComponent<StandSession>();
			Container val2 = val.AddComponent<Container>();
			Containers.Add(val2);
			val2.m_name = stand.m_name;
			val2.m_width = 3;
			val2.m_height = 3;
			val2.m_rootObjectOverride = stand.m_nview;
			val2.m_privacy = (PrivacySetting)2;
			val2.m_checkGuardStone = false;
			val.SetActive(true);
			standSession.Init(stand, val2);
			Current = standSession;
			InventoryGui.instance.Show(val2, 1);
			StandButtons.Show(standSession);
		}

		private void Init(ArmorStand stand, Container container)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			Stand = stand;
			Container = container;
			_nview = stand.m_nview;
			_cells = StandLayout.Get(stand);
			_slotCount = _cells.Length;
			_foreign = new bool[_slotCount];
			_written = (ItemData[])(object)new ItemData[_slotCount];
			_writtenStack = new int[_slotCount];
			Inventory = new Inventory(stand.m_name, (Sprite)null, container.m_width, container.m_height);
			container.m_nview = _nview;
			container.m_inventory = Inventory;
			StandLock.Take(_nview.GetZDO());
			Reload();
			AdoptStrays();
			Inventory inventory = Inventory;
			inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(OnInventoryChanged));
		}

		private void Update()
		{
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_currentContainer != (Object)(object)Container)
			{
				End();
				return;
			}
			if ((Object)(object)Stand == (Object)null || (Object)(object)_nview == (Object)null || !_nview.IsValid() || !_nview.IsOwner() || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				instance.CloseContainer();
				End();
				return;
			}
			Flush();
			uint dataRevision = _nview.GetZDO().DataRevision;
			if (dataRevision == _lastRevision)
			{
				return;
			}
			RefreshStrays();
			_excludedMask = _nview.GetZDO().GetInt(ExcludedKey, 0);
			if (SlotsDifferFromView())
			{
				if (instance.m_dragInventory == Inventory)
				{
					instance.SetupDragItem((ItemData)null, (Inventory)null, 1);
				}
				Reload();
			}
			_lastRevision = _nview.GetZDO().DataRevision;
		}

		private void LateUpdate()
		{
			if (!_ended && (Object)(object)Current == (Object)(object)this)
			{
				StandButtons.Refresh(this);
			}
		}

		private void OnDestroy()
		{
			End();
		}

		internal void Close()
		{
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_currentContainer == (Object)(object)Container)
			{
				instance.CloseContainer();
			}
			End();
		}

		private void End()
		{
			if (!_ended)
			{
				Flush();
				_ended = true;
				if ((Object)(object)Current == (Object)(object)this)
				{
					Current = null;
					StandButtons.Hide();
				}
				if ((Object)(object)_nview != (Object)null && _nview.IsValid())
				{
					StandLock.Release(_nview.GetZDO());
				}
				Containers.Remove(Container);
				if ((Object)(object)this != (Object)null && (Object)(object)((Component)this).gameObject != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
		}

		internal bool CanPlace(int index, ItemData item)
		{
			if (index >= 0 && index < _slotCount && !_foreign[index])
			{
				return StandLayout.Accepts(Stand, _cells[index], item);
			}
			return false;
		}

		internal CellKind KindOf(int index)
		{
			return _cells[index].Kind;
		}

		private int Phys(int index)
		{
			return _cells[index].Physical;
		}

		internal int CellOf(CellKind kind)
		{
			for (int i = 0; i < _slotCount; i++)
			{
				if (_cells[i].Kind == kind)
				{
					return i;
				}
			}
			return -1;
		}

		internal ItemData TwoHanderInWeaponCell()
		{
			int num = CellOf(CellKind.Weapon);
			ItemData val = ((num >= 0) ? ItemIn(num) : null);
			if (val == null || !val.IsTwoHanded())
			{
				return null;
			}
			return val;
		}

		internal Vector2i PosOf(int index)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return _cells[index].GridPos;
		}

		internal int SlotAt(Vector2i pos)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < _slotCount; i++)
			{
				if (_cells[i].GridPos.x == pos.x && _cells[i].GridPos.y == pos.y)
				{
					return i;
				}
			}
			return -1;
		}

		private int MaxStack(int index, ItemData item)
		{
			return StandLayout.MaxStack(_cells[index], item);
		}

		private ItemData ItemIn(int index)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			Vector2i val = PosOf(index);
			return Inventory.GetItemAt(val.x, val.y);
		}

		private void Reload()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			_suspendSync = true;
			try
			{
				Inventory.m_inventory.Clear();
				for (int i = 0; i < _slotCount; i++)
				{
					_written[i] = null;
					_foreign[i] = false;
					if (StandSlots.StoredHash(Stand, Phys(i)) != 0)
					{
						ItemData val = StandSlots.Load(Stand, Phys(i));
						if (val == null || !StandLayout.Accepts(Stand, _cells[i], val))
						{
							_foreign[i] = true;
							continue;
						}
						val.m_stack = Mathf.Min(val.m_stack, MaxStack(i, val));
						val.m_gridPos = PosOf(i);
						Inventory.m_inventory.Add(val);
						_written[i] = val;
						_writtenStack[i] = val.m_stack;
					}
				}
				Inventory.Changed(false, false);
			}
			finally
			{
				_suspendSync = false;
			}
			RefreshStrays();
			_excludedMask = _nview.GetZDO().GetInt(ExcludedKey, 0);
			_lastRevision = _nview.GetZDO().DataRevision;
		}

		internal bool IsExcluded(int index)
		{
			return (_excludedMask & (1 << (int)_cells[index].Kind)) != 0;
		}

		internal void ToggleExcluded(int index)
		{
			if (index >= 0 && index < _slotCount && !_ended && _nview.IsValid() && _nview.IsOwner())
			{
				_excludedMask ^= 1 << (int)_cells[index].Kind;
				_nview.GetZDO().Set(ExcludedKey, _excludedMask, false);
				_lastRevision = _nview.GetZDO().DataRevision;
			}
		}

		private void RefreshStrays()
		{
			_strays.Clear();
			int count = Stand.m_slots.Count;
			for (int i = 0; i < count; i++)
			{
				int num = StandSlots.StoredHash(Stand, i);
				if (num != 0 && !IsShown(i) && (Object)(object)ObjectDB.instance != (Object)null && (Object)(object)ObjectDB.instance.GetItemPrefab(num) != (Object)null)
				{
					_strays.Add(i);
				}
			}
		}

		private bool IsShown(int physical)
		{
			for (int i = 0; i < _slotCount; i++)
			{
				if (_cells[i].Physical == physical)
				{
					return !_foreign[i];
				}
			}
			return false;
		}

		private void AdoptStrays()
		{
			bool flag = false;
			int[] array = _strays.ToArray();
			foreach (int num in array)
			{
				ItemData val = StandSlots.Load(Stand, num);
				if (val == null)
				{
					continue;
				}
				for (int j = 0; j < _slotCount; j++)
				{
					if (_cells[j].Physical != num && StandSlots.StoredHash(Stand, Phys(j)) == 0 && StandLayout.Accepts(Stand, _cells[j], val))
					{
						StandSlots.Store(Stand, Phys(j), val, Mathf.Min(val.m_stack, MaxStack(j, val)));
						StandSlots.Clear(Stand, num);
						flag = true;
						break;
					}
				}
			}
			if (flag)
			{
				Stand.UpdateSupports();
				Reload();
			}
		}

		private bool SlotsDifferFromView()
		{
			for (int i = 0; i < _slotCount; i++)
			{
				if (!_foreign[i])
				{
					ItemData val = ItemIn(i);
					int num = StandSlots.StoredHash(Stand, Phys(i));
					int num2 = ((val != null && (Object)(object)val.m_dropPrefab != (Object)null) ? StringExtensionMethods.GetStableHashCode(((Object)val.m_dropPrefab).name) : 0);
					if (num != num2)
					{
						return true;
					}
				}
			}
			return false;
		}

		private void OnInventoryChanged()
		{
			if (!_suspendSync && !_ended)
			{
				_dirty = true;
			}
		}

		private void Flush()
		{
			if (!_dirty || _ended || (Object)(object)Stand == (Object)null || (Object)(object)_nview == (Object)null || !_nview.IsValid() || !_nview.IsOwner())
			{
				return;
			}
			_dirty = false;
			_suspendSync = true;
			try
			{
				Normalize();
				WriteSlots();
				Inventory.Changed(false, false);
			}
			catch (Exception ex)
			{
				AdvancedArmorStandPlugin.Log.LogError((object)("Armor stand sync failed: " + ex));
			}
			finally
			{
				_suspendSync = false;
			}
		}

		private void Normalize()
		{
			//IL_0033: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			List<ItemData> inventory = Inventory.m_inventory;
			ItemData[] array = (ItemData[])(object)new ItemData[_slotCount];
			List<ItemData> list = new List<ItemData>();
			ItemData[] array2 = inventory.ToArray();
			foreach (ItemData val in array2)
			{
				int num = SlotAt(val.m_gridPos);
				bool flag = num >= 0 && array[num] == null && CanPlace(num, val);
				val.m_equipped = false;
				if (flag)
				{
					array[num] = val;
				}
				else
				{
					list.Add(val);
				}
			}
			for (int j = 0; j < _slotCount; j++)
			{
				TrimStack(j, array[j]);
			}
			foreach (ItemData item in list)
			{
				int num2 = -1;
				for (int k = 0; k < _slotCount; k++)
				{
					if (num2 >= 0)
					{
						break;
					}
					if (array[k] == null && CanPlace(k, item))
					{
						num2 = k;
					}
				}
				if (num2 < 0)
				{
					num2 = ReplaceableCell(array, item);
					if (num2 >= 0)
					{
						inventory.Remove(array[num2]);
						ReturnToPlayer(array[num2]);
						array[num2] = null;
					}
				}
				if (num2 < 0)
				{
					inventory.Remove(item);
					ReturnToPlayer(item);
				}
				else
				{
					TrimStack(num2, item);
					item.m_gridPos = PosOf(num2);
					array[num2] = item;
				}
			}
			ResolveHands(inventory, array);
		}

		private int ReplaceableCell(ItemData[] placed, ItemData item)
		{
			for (int i = 0; i < _slotCount; i++)
			{
				if (placed[i] != null && IsOld(i, placed[i]) && CanPlace(i, item))
				{
					return i;
				}
			}
			return -1;
		}

		private bool IsOld(int index, ItemData item)
		{
			return _written[index] == item;
		}

		private void ResolveHands(List<ItemData> items, ItemData[] placed)
		{
			int num = CellOf(CellKind.Weapon);
			int num2 = CellOf(CellKind.Offhand);
			if (num >= 0 && num2 >= 0 && placed[num] != null && placed[num2] != null && placed[num].IsTwoHanded())
			{
				int num3 = ((!IsOld(num2, placed[num2]) && IsOld(num, placed[num])) ? num : num2);
				items.Remove(placed[num3]);
				ReturnToPlayer(placed[num3]);
				placed[num3] = null;
			}
		}

		private void TrimStack(int index, ItemData item)
		{
			if (item != null)
			{
				int num = MaxStack(index, item);
				if (item.m_stack > num)
				{
					ItemData val = item.Clone();
					val.m_stack = item.m_stack - num;
					item.m_stack = num;
					ReturnToPlayer(val);
				}
			}
		}

		private void WriteSlots()
		{
			bool flag = false;
			for (int i = 0; i < _slotCount; i++)
			{
				if (_foreign[i])
				{
					continue;
				}
				ItemData val = ItemIn(i);
				int num = StandSlots.StoredHash(Stand, Phys(i));
				if (val == null)
				{
					if (num != 0)
					{
						StandSlots.Clear(Stand, Phys(i));
						flag = true;
					}
					_written[i] = null;
				}
				else if (_written[i] != val || _writtenStack[i] != val.m_stack || num != StringExtensionMethods.GetStableHashCode(((Object)val.m_dropPrefab).name))
				{
					StandSlots.Store(Stand, Phys(i), val, val.m_stack);
					_written[i] = val;
					_writtenStack[i] = val.m_stack;
					flag = true;
				}
			}
			if (flag)
			{
				Stand.UpdateSupports();
			}
			_lastRevision = _nview.GetZDO().DataRevision;
		}

		private void ReturnToPlayer(ItemData item)
		{
			//IL_0043: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer != (Object)null) || !((Humanoid)localPlayer).GetInventory().AddItem(item))
			{
				Transform val = (((Object)(object)localPlayer != (Object)null) ? ((Component)localPlayer).transform : ((Component)Stand).transform);
				ItemDrop.DropItem(item, item.m_stack, val.position + val.forward + Vector3.up, Quaternion.identity);
			}
		}

		internal bool PlaceFromPlayer(Player player, ItemData item, int preferredSlot)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			int num = -1;
			if (preferredSlot >= 0 && preferredSlot < _slotCount && ItemIn(preferredSlot) == null && CanPlace(preferredSlot, item))
			{
				num = preferredSlot;
			}
			for (int i = 0; i < _slotCount; i++)
			{
				if (num >= 0)
				{
					break;
				}
				if (ItemIn(i) == null && CanPlace(i, item))
				{
					num = i;
				}
			}
			for (int j = 0; j < _slotCount; j++)
			{
				if (num >= 0)
				{
					break;
				}
				if (CanPlace(j, item))
				{
					num = j;
				}
			}
			if (num < 0 || !((Humanoid)player).GetInventory().ContainsItem(item))
			{
				return false;
			}
			int num2 = Mathf.Min(item.m_stack, MaxStack(num, item));
			ItemData val = item.Clone();
			val.m_stack = num2;
			val.m_equipped = false;
			val.m_gridPos = PosOf(num);
			((Humanoid)player).UnequipItem(item, true);
			((Humanoid)player).GetInventory().RemoveItem(item, num2);
			Inventory.m_inventory.Add(val);
			Inventory.Changed(false, false);
			Flush();
			PlayEffect();
			return true;
		}
	}
	internal static class StandSlots
	{
		internal static int StoredHash(ArmorStand stand, int index)
		{
			return stand.m_nview.GetZDO().GetInt(ArmorStand.s_itemKeyHashes[index], 0);
		}

		internal static bool HasVisual(ItemData item)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			ItemType itemType = item.m_shared.m_itemType;
			if ((int)itemType == 7 || (int)itemType == 11)
			{
				return true;
			}
			Transform transform = item.m_dropPrefab.transform;
			for (int i = 0; i < transform.childCount; i++)
			{
				string name = ((Object)((Component)transform.GetChild(i)).gameObject).name;
				if (name == "attach" || name == "attach_skin")
				{
					return true;
				}
			}
			return false;
		}

		internal static ItemData Load(ArmorStand stand, int index)
		{
			int num = StoredHash(stand, index);
			if (num == 0)
			{
				return null;
			}
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(num) : null);
			ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return null;
			}
			ItemData val3 = val2.m_itemData.Clone();
			val3.m_dropPrefab = val;
			ItemDrop.LoadFromZDO(val3, stand.m_nview.GetZDO(), index);
			val3.m_stack = Mathf.Max(1, val3.m_stack);
			val3.m_equipped = false;
			return val3;
		}

		internal static void Store(ArmorStand stand, int index, ItemData item, int stack = 1)
		{
			ZDO zDO = stand.m_nview.GetZDO();
			ItemData val = item.Clone();
			val.m_stack = Mathf.Max(1, stack);
			val.m_equipped = false;
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)item.m_dropPrefab).name);
			zDO.Set(ArmorStand.s_itemKeyHashes[index], stableHashCode, false);
			ItemDrop.SaveToZDO(val, zDO, index);
			stand.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SetVisualItem", new object[3] { index, stableHashCode, val.m_variant });
		}

		internal static void Clear(ArmorStand stand, int index)
		{
			stand.m_nview.GetZDO().Set(ArmorStand.s_itemKeyHashes[index], 0, false);
			stand.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SetVisualItem", new object[3] { index, 0, 0 });
		}
	}
	internal static class BuildInfo
	{
		public const string Name = "CDEV.AdvancedArmorStand";

		public const string Guid = "cdev.advancedarmorstand";

		public const string Version = "0.1.0";
	}
}
namespace CDEV.AdvancedArmorStand.Patches
{
	[HarmonyPatch(typeof(ArmorStand))]
	internal static class ArmorStandPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void AwakePostfix(ArmorStand __instance)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			if ((Object)(object)__instance.m_nview == (Object)null || __instance.m_nview.GetZDO() == null)
			{
				return;
			}
			ArmorStand stand = __instance;
			TooltipCallback onHover = (TooltipCallback)(() => StandHover.Get(stand));
			foreach (ArmorStandSlot slot in stand.m_slots)
			{
				if ((Object)(object)slot.m_switch != (Object)null)
				{
					slot.m_switch.m_onHover = onHover;
				}
			}
			if ((Object)(object)stand.m_changePoseSwitch != (Object)null)
			{
				stand.m_changePoseSwitch.m_onHover = onHover;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("SetVisualItem")]
		private static void SetVisualItemPrefix(ref int itemHash)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (itemHash != 0 && !((Object)(object)ObjectDB.instance == (Object)null))
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemHash);
				ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val != (Object)null && StandLayout.IsStorageOnlyType(val.m_itemData.m_shared.m_itemType))
				{
					itemHash = 0;
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("UseItem")]
		private static bool UseItemPrefix(ArmorStand __instance, Switch caller, Humanoid user, ItemData item, ref bool __result)
		{
			try
			{
				if (item == null || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid())
				{
					return true;
				}
				Player val = (Player)(object)((user is Player) ? user : null);
				if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				if (StandSession.IsOpenOn(__instance))
				{
					if (!StandSession.Current.PlaceFromPlayer(val, item, -1))
					{
						((Character)val).Message((MessageType)2, "$piece_armorstand_cantattach", 0, (Sprite)null, false);
					}
					__result = true;
					return false;
				}
				if (StandLock.IsHeldByOther(__instance.m_nview.GetZDO()))
				{
					((Character)val).Message((MessageType)2, "$msg_inuse", 0, (Sprite)null, false);
					__result = true;
					return false;
				}
			}
			catch (Exception ex)
			{
				AdvancedArmorStandPlugin.Log.LogError((object)("ArmorStand.UseItem prefix failed: " + ex));
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Container))]
	internal static class ContainerPatches
	{
		private static bool IsSession(Container container)
		{
			return StandSession.Containers.Contains(container);
		}

		[HarmonyPrefix]
		[HarmonyPatch("Awake")]
		private static bool AwakePrefix(Container __instance)
		{
			return !IsSession(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch("Load")]
		private static bool LoadPrefix(Container __instance, ref bool __result)
		{
			if (!IsSession(__instance))
			{
				return true;
			}
			__result = false;
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("Save")]
		private static bool SavePrefix(Container __instance)
		{
			return !IsSession(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch("CheckForChanges")]
		private static bool CheckForChangesPrefix(Container __instance)
		{
			return !IsSession(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch("OnDestroyed")]
		private static bool OnDestroyedPrefix(Container __instance)
		{
			return !IsSession(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch("DropAllItems", new Type[] { typeof(GameObject) })]
		private static bool DropAllItemsPrefix(Container __instance)
		{
			return !IsSession(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch("DropAllItems", new Type[] { })]
		private static bool DropAllItemsNoArgsPrefix(Container __instance)
		{
			return !IsSession(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch("SetInUse")]
		private static bool SetInUsePrefix(Container __instance, bool inUse)
		{
			if (!IsSession(__instance))
			{
				return true;
			}
			__instance.m_inUse = inUse;
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("StackAll")]
		private static bool StackAllPrefix(Container __instance)
		{
			return !IsSession(__instance);
		}

		[HarmonyPrefix]
		[HarmonyPatch("TakeAll")]
		private static bool TakeAllPrefix(Container __instance, ref bool __result)
		{
			if (!IsSession(__instance))
			{
				return true;
			}
			StandSession.Current?.TakeAll();
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnStackAll")]
	internal static class InventoryGuiStackAllPatch
	{
		private static bool Prefix(InventoryGui __instance)
		{
			if ((Object)(object)__instance.m_currentContainer == (Object)null || !StandSession.Containers.Contains(__instance.m_currentContainer))
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnTakeAll")]
	internal static class InventoryGuiTakeAllPatch
	{
		private static bool Prefix(InventoryGui __instance)
		{
			if ((Object)(object)__instance.m_currentContainer == (Object)null || !StandSession.Containers.Contains(__instance.m_currentContainer))
			{
				return true;
			}
			StandSession.Current?.TakeAll();
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "DropItem")]
	internal static class InventoryGridDropItemPatch
	{
		private static bool Prefix(InventoryGrid __instance, Inventory fromInventory, ItemData item, int amount, ref Vector2i pos, ref bool __result)
		{
			//IL_0081: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				StandSession current = StandSession.Current;
				if ((Object)(object)current == (Object)null || item == null)
				{
					return true;
				}
				Inventory inventory = current.Inventory;
				Inventory inventory2 = __instance.m_inventory;
				if (inventory2 != inventory && fromInventory != inventory)
				{
					return true;
				}
				bool flag = true;
				if (inventory2 == inventory && item.IsTwoHanded() && current.SlotAt(pos) == current.CellOf(CellKind.Offhand))
				{
					int num = current.CellOf(CellKind.Weapon);
					if (num >= 0)
					{
						pos = current.PosOf(num);
					}
				}
				if (inventory2 == inventory)
				{
					flag = current.CanPlace(current.SlotAt(pos), item);
				}
				ItemData itemAt = inventory2.GetItemAt(pos.x, pos.y);
				if (flag && fromInventory == inventory && itemAt != null && itemAt != item && WouldSwap(itemAt, item, amount))
				{
					flag = current.CanPlace(current.SlotAt(item.m_gridPos), itemAt);
				}
				if (flag)
				{
					return true;
				}
				__result = false;
				return false;
			}
			catch (Exception ex)
			{
				AdvancedArmorStandPlugin.Log.LogError((object)("InventoryGrid.DropItem prefix failed: " + ex));
				return true;
			}
		}

		private static bool WouldSwap(ItemData atTarget, ItemData dragged, int amount)
		{
			if (atTarget.m_shared.m_name != dragged.m_shared.m_name || (dragged.m_shared.m_maxQuality > 1 && atTarget.m_quality != dragged.m_quality) || atTarget.m_shared.m_maxStackSize == 1)
			{
				return dragged.m_stack == amount;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "UpdateInventory")]
	internal static class InventoryGridStandCellsPatch
	{
		private static readonly Color ExcludedColor = new Color(0.7f, 0.12f, 0.08f, 0.45f);

		private static readonly ConditionalWeakTable<InventoryElement, GameObject> Overlays = new ConditionalWeakTable<InventoryElement, GameObject>();

		private static void Postfix(InventoryGrid __instance, Inventory inventory)
		{
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)__instance != (Object)(object)instance.m_containerGrid)
			{
				return;
			}
			StandSession current = StandSession.Current;
			bool flag = (Object)(object)current != (Object)null && inventory == current.Inventory;
			if (flag)
			{
				StandPanel.Apply(instance, __instance, current);
			}
			else if (__instance.m_width == 3 && __instance.m_elements.Count == 3 * __instance.m_height)
			{
				VanillaPositions(__instance);
			}
			InventoryElement val = (flag ? __instance.GetHoveredElement() : null);
			for (int i = 0; i < __instance.m_elements.Count; i++)
			{
				InventoryElement val2 = __instance.m_elements[i];
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				int num = (flag ? current.SlotAt(val2.Position) : (-1));
				bool flag2 = !flag || num >= 0;
				if (((Component)val2).gameObject.activeSelf != flag2)
				{
					((Component)val2).gameObject.SetActive(flag2);
				}
				bool flag3 = num >= 0 && current.IsExcluded(num);
				SetExcludedOverlay(val2, flag3);
				if (num >= 0 && !val2.m_used)
				{
					CellKind cellKind = current.KindOf(num);
					ItemData val3 = ((cellKind == CellKind.Offhand) ? current.TwoHanderInWeaponCell() : null);
					if (val3 != null)
					{
						ShowOccupiedBy(val2, val3);
					}
					else
					{
						ShowPlaceholder(val2, cellKind, flag3);
					}
				}
				else if (flag3 && (Object)(object)val2 == (Object)(object)val && (Object)(object)val2.m_tooltip != (Object)null && Localization.instance != null)
				{
					UITooltip tooltip = val2.m_tooltip;
					tooltip.Set(tooltip.m_topic, tooltip.m_text + Localization.instance.Localize("\n\n<color=#ff8060>$cdev_aas_cell_excluded</color>"), tooltip.m_anchor, tooltip.m_fixedPosition);
				}
			}
		}

		private static void VanillaPositions(InventoryGrid grid)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_0061: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			float elementSpace = grid.m_elementSpace;
			Rect rect = ((RectTransform)((Component)grid).transform).rect;
			float num = ((Rect)(ref rect)).width / 2f - (float)grid.m_width * elementSpace / 2f;
			Vector2 val2 = default(Vector2);
			for (int i = 0; i < grid.m_height; i++)
			{
				for (int j = 0; j < grid.m_width; j++)
				{
					RectTransform val = (RectTransform)((Component)grid.m_elements[i * grid.m_width + j]).transform;
					((Vector2)(ref val2))..ctor(num + (float)j * elementSpace, (float)(-i) * elementSpace);
					if (val.anchoredPosition != val2)
					{
						val.anchoredPosition = val2;
					}
				}
			}
		}

		private static void ShowOccupiedBy(InventoryElement element, ItemData item)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			Sprite[] icons = item.m_shared.m_icons;
			if (icons != null && icons.Length != 0 && (Object)(object)element.m_icon != (Object)null)
			{
				((Behaviour)element.m_icon).enabled = true;
				element.m_icon.sprite = icons[Mathf.Clamp(item.m_variant, 0, icons.Length - 1)];
				((Graphic)element.m_icon).color = StandPlaceholders.Tint;
			}
			if ((Object)(object)element.m_tooltip != (Object)null && Localization.instance != null)
			{
				element.m_tooltip.m_topic = Localization.instance.Localize(item.m_shared.m_name);
				element.m_tooltip.m_text = Localization.instance.Localize("$cdev_aas_cell_twohanded");
			}
		}

		private static void SetExcludedOverlay(InventoryElement element, bool excluded)
		{
			if (!Overlays.TryGetValue(element, out var value))
			{
				if (!excluded)
				{
					return;
				}
				value = CreateOverlay(element);
				Overlays.Add(element, value);
			}
			if ((Object)(object)value != (Object)null && value.activeSelf != excluded)
			{
				value.SetActive(excluded);
			}
		}

		private static GameObject CreateOverlay(InventoryElement element)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("CDEV_AdvancedArmorStand_Excluded", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(((Component)element).transform, false);
			((Transform)val2).SetAsFirstSibling();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			Image component = val.GetComponent<Image>();
			Image component2 = ((Component)element).GetComponent<Image>();
			if ((Object)(object)component2 != (Object)null)
			{
				component.sprite = component2.sprite;
				component.type = component2.type;
			}
			((Graphic)component).color = ExcludedColor;
			((Graphic)component).raycastTarget = false;
			return val;
		}

		private static void ShowPlaceholder(InventoryElement element, CellKind kind, bool excluded)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			Sprite val = StandPlaceholders.Get(kind);
			if ((Object)(object)val != (Object)null && (Object)(object)element.m_icon != (Object)null)
			{
				((Behaviour)element.m_icon).enabled = true;
				element.m_icon.sprite = val;
				((Graphic)element.m_icon).color = StandPlaceholders.Tint;
			}
			if ((Object)(object)element.m_tooltip != (Object)null && Localization.instance != null)
			{
				element.m_tooltip.m_topic = Localization.instance.Localize(StandPlaceholders.NameKey(kind));
				element.m_tooltip.m_text = Localization.instance.Localize(excluded ? "$cdev_aas_cell_excluded" : "$cdev_aas_cell_hint");
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")]
	internal static class InventoryGuiRightClickPatch
	{
		private static bool Prefix(InventoryGrid grid, Vector2i pos)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				StandSession current = StandSession.Current;
				if ((Object)(object)current == (Object)null || (Object)(object)grid == (Object)null || grid.GetInventory() != current.Inventory)
				{
					return true;
				}
				current.ToggleExcluded(current.SlotAt(pos));
				return false;
			}
			catch (Exception ex)
			{
				AdvancedArmorStandPlugin.Log.LogError((object)("InventoryGui.OnRightClickItem prefix failed: " + ex));
				return true;
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Show")]
	internal static class InventoryGuiShowPatch
	{
		[HarmonyPriority(800)]
		private static void Prefix(Container container)
		{
			try
			{
				StandButtons.OnInventoryShow(container);
			}
			catch (Exception ex)
			{
				AdvancedArmorStandPlugin.Log.LogError((object)("InventoryGui.Show prefix failed: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(Switch), "Interact", new Type[]
	{
		typeof(Humanoid),
		typeof(bool),
		typeof(bool)
	})]
	internal static class SwitchInteractPatch
	{
		private static bool Prefix(Switch __instance, Humanoid character, bool hold, bool alt, ref bool __result)
		{
			try
			{
				ArmorStand componentInParent = ((Component)__instance).GetComponentInParent<ArmorStand>();
				if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent.m_nview == (Object)null || !componentInParent.m_nview.IsValid())
				{
					return true;
				}
				if (!((Object)(object)__instance == (Object)(object)componentInParent.m_changePoseSwitch) && !ServesSlot(componentInParent, __instance))
				{
					return true;
				}
				if (hold)
				{
					__result = false;
					return false;
				}
				if (alt && (Object)(object)componentInParent.m_changePoseSwitch != (Object)null && componentInParent.m_changePoseSwitch.m_onUse != null)
				{
					__result = componentInParent.m_changePoseSwitch.m_onUse.Invoke(componentInParent.m_changePoseSwitch, character, (ItemData)null);
					return false;
				}
				Player val = (Player)(object)((character is Player) ? character : null);
				if ((Object)(object)val != (Object)null && (Object)(object)val == (Object)(object)Player.m_localPlayer)
				{
					StandSession.RequestOpen(componentInParent, val);
				}
				__result = true;
				return false;
			}
			catch (Exception ex)
			{
				AdvancedArmorStandPlugin.Log.LogError((object)("Switch.Interact prefix failed: " + ex));
				return true;
			}
		}

		private static bool ServesSlot(ArmorStand stand, Switch sw)
		{
			foreach (ArmorStandSlot slot in stand.m_slots)
			{
				if ((Object)(object)slot.m_switch == (Object)(object)sw)
				{
					return true;
				}
			}
			return false;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}