Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CDEV AdvancedArmorStand v0.1.0
plugins/CDEV.AdvancedArmorStand/CDEV.AdvancedArmorStand.dll
Decompiled a day agousing 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) { } } }