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 ArmorGallery v1.0.5
ArmorGallery.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace ArmorGallery; public enum RotationMode { Sequential, RandomRow, Chaos } [BepInPlugin("com.drakosdj.armorgallery", "ArmorGallery", "1.0.5")] public class ArmorGalleryPlugin : BaseUnityPlugin { public static ArmorGalleryPlugin instance; public static ConfigEntry<bool> configEnabled; public static ConfigEntry<float> configRotationInterval; public static ConfigEntry<float> configLinkRadius; public static ConfigEntry<int> configMaxLinkedChests; public static ConfigEntry<float> configMaxLinkDistance; public static ConfigEntry<KeyCode> configPrevChestKey; public static ConfigEntry<KeyCode> configNextChestKey; public static ConfigEntry<RotationMode> configRotationMode; public static ConfigEntry<KeyCode> configModifierKey; public static ConfigEntry<KeyCode> configPoseModifierKey; public static ConfigEntry<bool> configRandomizePoseOnCycle; public static ConfigEntry<bool> configRandomizeStanceOnCycle; private void Awake() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown instance = this; configEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable the automatic cycling of armor stand sets."); configRotationInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RotationInterval", 60f, "Time in seconds between set rotations."); configLinkRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LinkRadius", 20f, "Maximum distance in meters to find a chest to link."); configMaxLinkedChests = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxLinkedChests", 6, new ConfigDescription("Maximum number of chests that can be linked to a single Armor Stand.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 12), new object[0])); configMaxLinkDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaxLinkDistance", 20f, new ConfigDescription("Maximum distance in meters between an Armor Stand and a linked chest.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 30f), new object[0])); configPrevChestKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "PrevChestKey", (KeyCode)113, "Hotkey to navigate to the previous linked chest in the UI."); configNextChestKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "NextChestKey", (KeyCode)101, "Hotkey to navigate to the next linked chest in the UI."); configRotationMode = ((BaseUnityPlugin)this).Config.Bind<RotationMode>("General", "RotationMode", RotationMode.Sequential, "Set cycling mode: Sequential (cycles row by row in order), RandomRow (picks a random set row each cycle), Chaos (mix-and-matches individual armor and weapon slots from random rows)."); configRotationMode.SettingChanged += delegate { foreach (ArmorGalleryRotator s_allRotator in ArmorGalleryRotator.s_allRotators) { if ((Object)(object)s_allRotator != (Object)null && (Object)(object)s_allRotator.m_stand != (Object)null) { s_allRotator.UpdateStandVisualsFromActiveRow(); } } }; configRandomizePoseOnCycle = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RandomizePoseOnCycle", false, "When enabled, automatically chooses a random pose for the Armor Stand on each rotation cycle."); configRandomizeStanceOnCycle = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RandomizeStanceOnCycle", false, "When enabled, randomly alternates weapons between Equipped and Stowed on each rotation cycle."); configModifierKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ModifierKey", (KeyCode)304, "Modifier key to hold while pressing Use to toggle gallery linking mode on/off."); configPoseModifierKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "PoseModifierKey", (KeyCode)308, "Modifier key to hold while pressing Use to cycle armor stand pose."); Harmony val = new Harmony("com.drakosdj.armorgallery"); val.PatchAll(); Debug.Log((object)"[ArmorGallery] Plugin loaded successfully!"); } public static string GetUseKeyName() { try { if (ZInput.instance != null) { string boundKeyString = ZInput.instance.GetBoundKeyString("Use", false); if (!string.IsNullOrEmpty(boundKeyString)) { return boundKeyString; } } } catch { } return "Use"; } } [HarmonyPatch(typeof(ArmorStand), "Awake")] public static class ArmorStand_Awake_Patch { public static void Postfix(ArmorStand __instance) { if ((Object)(object)((Component)__instance).GetComponent<ArmorGalleryRotator>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<ArmorGalleryRotator>(); } } } [HarmonyPatch(typeof(Switch), "GetHoverText")] public static class Switch_GetHoverText_Patch { public static void Postfix(Switch __instance, ref string __result) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return; } ArmorStand componentInParent = ((Component)__instance).GetComponentInParent<ArmorStand>(); if ((Object)(object)componentInParent == (Object)null) { return; } ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ArmorGalleryRotator component2 = ((Component)componentInParent).GetComponent<ArmorGalleryRotator>(); if ((Object)(object)component2 == (Object)null) { return; } string useKeyName = ArmorGalleryPlugin.GetUseKeyName(); string arg = ((object)ArmorGalleryPlugin.configModifierKey.Value).ToString(); string text = ((object)ArmorGalleryPlugin.configPoseModifierKey.Value).ToString(); int num = component2.GetCurrentPose() + 1; int maxPoses = component2.GetMaxPoses(); if ((Object)(object)ArmorGalleryRotator.s_activeLinkingStand == (Object)(object)component2) { int linkedChestCount = component2.GetLinkedChestCount(); string arg2 = string.Format("<color=#FFD700>[Armor Gallery: In Linking Mode ({0} chest{1} linked)]</color>", linkedChestCount, (linkedChestCount == 1) ? "" : "s"); string arg3 = $"\n[{arg} + {useKeyName}] Exit Linking Mode"; __result = $"{__result}\n{arg2}{arg3}"; } else if (component.GetZDO().GetBool("InLinkMode", false) && (Object)(object)ArmorGalleryRotator.s_activeLinkingStand != (Object)(object)component2) { string text2 = component.GetZDO().GetString("LinkUser", "another player"); if (string.IsNullOrEmpty(text2)) { text2 = "another player"; } string arg4 = $"<color=#FFAA00>[Armor Gallery: Currently being edited by {text2}]</color>"; string arg5 = $"\n[{text} + {useKeyName}] Change Pose ({num}/{maxPoses})"; __result = $"{__result}\n{arg4}{arg5}"; } else if (component.GetZDO().GetBool("RotationEnabled", false)) { int linkedChestCount2 = component2.GetLinkedChestCount(); string arg2 = string.Format("<color=#FFD700>[Armor Gallery: Locked - Linked ({0} chest{1})]</color>", linkedChestCount2, (linkedChestCount2 == 1) ? "" : "s"); string text3 = $"\n[{useKeyName}] Open Gallery Chest"; string text4 = $"\n[{arg} + {useKeyName}] Edit Linked Chests"; string arg5 = $"\n[{text} + {useKeyName}] Change Pose ({num}/{maxPoses})"; __result = $"{__result}\n{arg2}{text3}{text4}{arg5}"; } else { string arg2 = "<color=#AAAAAA>[Armor Gallery: Unlinked]</color>"; string text4 = $"\n[{arg} + {useKeyName}] Enter Linking Mode"; string arg5 = $"\n[{text} + {useKeyName}] Change Pose ({num}/{maxPoses})"; __result = $"{__result}\n{arg2}{text4}{arg5}"; } } } [HarmonyPatch(typeof(ArmorStand), "UseItem")] public static class ArmorStand_UseItem_Patch { public static bool Prefix(ArmorStand __instance, Switch caller, Humanoid user, ItemData item, ref bool __result) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) ArmorGalleryRotator component = ((Component)__instance).GetComponent<ArmorGalleryRotator>(); if (Input.GetKey(ArmorGalleryPlugin.configModifierKey.Value)) { if ((Object)(object)component != (Object)null) { component.ToggleLinkingMode(); } __result = true; return false; } if (Input.GetKey(ArmorGalleryPlugin.configPoseModifierKey.Value)) { if ((Object)(object)component != (Object)null) { component.CyclePose(); } __result = true; return false; } if ((Object)(object)ArmorGalleryRotator.s_activeLinkingStand != (Object)null) { if ((Object)(object)ArmorGalleryRotator.s_activeLinkingStand == (Object)(object)component) { string useKeyName = ArmorGalleryPlugin.GetUseKeyName(); string arg = ((object)ArmorGalleryPlugin.configModifierKey.Value).ToString(); Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val != (Object)null) { ((Character)val).Message((MessageType)2, string.Format("Armor Gallery: Aim at chests and press [{0}] to toggle link, or [{1} + {0}] to exit Linking Mode.", useKeyName, arg), 0, (Sprite)null, false); } } __result = true; return false; } ZNetView component2 = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component2 != (Object)null && component2.IsValid() && component2.GetZDO().GetBool("RotationEnabled", false)) { if (item != null) { Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val != (Object)null) { ((Character)val).Message((MessageType)2, "Armor Stand is locked by Armor Gallery. Manage gear in the linked chest.", 0, (Sprite)null, false); } __result = true; return false; } if ((Object)(object)caller != (Object)(object)__instance.m_changePoseSwitch) { Container val2 = (((Object)(object)component != (Object)null) ? component.GetPrimaryChest() : null); if ((Object)(object)val2 != (Object)null) { val2.Interact(user, false, false); } else { Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val != (Object)null) { string useKeyName = ArmorGalleryPlugin.GetUseKeyName(); string arg = ((object)ArmorGalleryPlugin.configModifierKey.Value).ToString(); string arg2 = ((object)ArmorGalleryPlugin.configPoseModifierKey.Value).ToString(); ((Character)val).Message((MessageType)2, string.Format("Armor Gallery: Manage items in chest, [{0} + {1}] for Pose, or [{2} + {1}] to edit links.", arg2, useKeyName, arg), 0, (Sprite)null, false); } } __result = true; return false; } } return true; } } [HarmonyPatch(typeof(ArmorStand), "DropItem")] public static class ArmorStand_DropItem_Patch { public static bool Prefix(ArmorStand __instance, int index) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("RotationEnabled", false)) { return false; } return true; } } [HarmonyPatch(typeof(ArmorStand), "OnDestroyed")] public static class ArmorStand_OnDestroyed_Patch { public static bool Prefix(ArmorStand __instance) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("RotationEnabled", false)) { return false; } return true; } } [HarmonyPatch(typeof(ArmorStand), "UpdateVisual")] public static class ArmorStand_UpdateVisual_Patch { public static bool Prefix(ArmorStand __instance) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("RotationEnabled", false)) { return false; } return true; } } [HarmonyPatch(typeof(ArmorStand), "HaveAttachment")] public static class ArmorStand_HaveAttachment_Patch { public static bool Prefix(ArmorStand __instance, int index, ref bool __result) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("RotationEnabled", false)) { __result = true; return false; } return true; } } public static class ArmorGalleryMessaging { public static void SendMessageToPlayer(long sender, Vector3 position, string msg) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) bool flag = false; if (sender != 0 && sender != 0) { foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer != (Object)null) { ZNetView component = ((Component)allPlayer).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null && component.GetZDO().GetOwner() == sender) { component.InvokeRPC(sender, "Message", new object[3] { 2, msg, 0 }); flag = true; break; } } } } if (!flag) { Player.MessageAllInRange(position, 6f, (MessageType)2, msg, (Sprite)null); } } } [HarmonyPatch(typeof(ArmorStand), "RPC_DropItem")] public static class ArmorStand_RPC_DropItem_Patch { public static bool Prefix(ArmorStand __instance, long sender, int index) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("RotationEnabled", false)) { ArmorGalleryMessaging.SendMessageToPlayer(sender, ((Component)__instance).transform.position, "Armor Gallery: Manage armor sets in the linked chest."); return false; } return true; } } [HarmonyPatch(typeof(ArmorStand), "RPC_DropItemByName")] public static class ArmorStand_RPC_DropItemByName_Patch { public static bool Prefix(ArmorStand __instance, long sender, string name) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("RotationEnabled", false)) { ArmorGalleryMessaging.SendMessageToPlayer(sender, ((Component)__instance).transform.position, "Armor Gallery: Manage armor sets in the linked chest."); return false; } return true; } } [HarmonyPatch(typeof(ArmorStand), "RPC_DestroyAttachment")] public static class ArmorStand_RPC_DestroyAttachment_Patch { public static bool Prefix(ArmorStand __instance, long sender, int index) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("RotationEnabled", false)) { ArmorGalleryMessaging.SendMessageToPlayer(sender, ((Component)__instance).transform.position, "Armor Gallery: Manage armor sets in the linked chest."); return false; } return true; } } public class ArmorGalleryRotator : MonoBehaviour { public struct SetRef { public Container Chest; public int ChestIndex; public int ChestRow; public int GlobalSetNumber; } public static ArmorGalleryRotator s_activeLinkingStand = null; public static readonly List<ArmorGalleryRotator> s_allRotators = new List<ArmorGalleryRotator>(); internal ArmorStand m_stand; private readonly List<Container> m_linkedChests = new List<Container>(); private readonly List<ZDOID> m_linkedChestZDOIDs = new List<ZDOID>(); private readonly List<GameObject> m_connectionInstances = new List<GameObject>(); private float m_timer; internal int m_activeSetIndex = 0; private bool m_isSyncing = false; private bool m_wasChestInUse = false; private bool m_wasAlreadyEnabledBeforeLinking = false; private bool m_initialVisualsLoaded = false; public static readonly int AG_LOCKED_HASH = StringExtensionMethods.GetStableHashCode("AG_LOCKED"); private static int[] s_itemKeyHashes; private static int[] s_variantKeyHashes; private float m_hudMsgTimer = 0f; private static readonly FieldInfo[] s_currentHashFields = new FieldInfo[13] { typeof(VisEquipment).GetField("m_currentHelmetItemHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentChestItemHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentLegItemHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentShoulderItemHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentLeftItemHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentRightItemHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentLeftBackItemHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentRightBackItemHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentUtilityItemHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentTrinketItemHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentShoulderItemVariant", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentLeftItemVariant", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), typeof(VisEquipment).GetField("m_currentLeftBackItemVariant", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) }; private static GameObject s_connectionPrefab; private static readonly VisSlot[] UI_COLUMN_SLOTS = (VisSlot[])(object)new VisSlot[6] { (VisSlot)6, (VisSlot)4, (VisSlot)5, default(VisSlot), (VisSlot)1, (VisSlot)7 }; public int GetLinkedChestCount() { if (m_linkedChestZDOIDs.Count == 0 && (Object)(object)m_stand != (Object)null) { ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("RotationEnabled", false)) { LoadLinkedChestsFromZDO(); } } if (m_linkedChests.Count < m_linkedChestZDOIDs.Count) { ResolveLinkedContainers(); } return Mathf.Max(m_linkedChests.Count, m_linkedChestZDOIDs.Count); } public List<ZDOID> GetLinkedChestZDOIDs() { return m_linkedChestZDOIDs; } public Container GetPrimaryChest() { List<Container> linkedChests = GetLinkedChests(); if (linkedChests.Count > 0 && (Object)(object)linkedChests[0] != (Object)null) { return linkedChests[0]; } if (m_linkedChestZDOIDs.Count > 0) { ResolveLinkedContainers(); if (m_linkedChests.Count > 0 && (Object)(object)m_linkedChests[0] != (Object)null) { return m_linkedChests[0]; } } return null; } public Container GetLinkedChest() { return GetPrimaryChest(); } public List<Container> GetLinkedChests() { if (m_linkedChestZDOIDs.Count == 0 && (Object)(object)m_stand != (Object)null) { ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("RotationEnabled", false)) { LoadLinkedChestsFromZDO(); } } ValidateAndPruneLinkedChests(); return m_linkedChests; } private void RebuildZDOIDsFromChests() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) m_linkedChestZDOIDs.Clear(); for (int i = 0; i < m_linkedChests.Count; i++) { Container val = m_linkedChests[i]; if (!((Object)(object)val != (Object)null)) { continue; } ZNetView component = ((Component)val).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { ZDOID uid = component.GetZDO().m_uid; if (!((ZDOID)(ref uid)).IsNone() && !m_linkedChestZDOIDs.Contains(uid)) { m_linkedChestZDOIDs.Add(uid); } } } } public bool IsChestLinked(Container chest) { //IL_004e: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)chest == (Object)null) { return false; } if (m_linkedChests.Contains(chest)) { return true; } ZNetView component = ((Component)chest).GetComponent<ZNetView>(); ZDOID val = (((Object)(object)component != (Object)null && component.IsValid()) ? component.GetZDO().m_uid : ZDOID.None); if (!((ZDOID)(ref val)).IsNone() && m_linkedChestZDOIDs.Contains(val)) { if (!m_linkedChests.Contains(chest)) { m_linkedChests.Add(chest); } return true; } ZNetView val2 = (((Object)(object)m_stand != (Object)null) ? ((Component)m_stand).GetComponent<ZNetView>() : null); if ((Object)(object)val2 == (Object)null || !val2.IsValid()) { return false; } int num = val2.GetZDO().GetInt("LinkedChestCount", -1); if (num > 0) { for (int i = 0; i < num; i++) { if (!((ZDOID)(ref val)).IsNone() && val2.GetZDO().GetZDOID("LinkedChest_" + i) == val) { if (!m_linkedChestZDOIDs.Contains(val)) { m_linkedChestZDOIDs.Add(val); } if (!m_linkedChests.Contains(chest)) { m_linkedChests.Add(chest); } return true; } Vector3 vec = val2.GetZDO().GetVec3("LinkedChestPos_" + i, Vector3.zero); if (vec != Vector3.zero && Vector3.Distance(((Component)chest).transform.position, vec) < 0.5f) { if (!((ZDOID)(ref val)).IsNone() && !m_linkedChestZDOIDs.Contains(val)) { m_linkedChestZDOIDs.Add(val); } if (!m_linkedChests.Contains(chest)) { m_linkedChests.Add(chest); } return true; } } } if (!((ZDOID)(ref val)).IsNone() && val2.GetZDO().GetZDOID("LinkedChestID") == val) { if (!m_linkedChestZDOIDs.Contains(val)) { m_linkedChestZDOIDs.Add(val); } if (!m_linkedChests.Contains(chest)) { m_linkedChests.Add(chest); } return true; } return false; } public int GetCurrentPose() { if ((Object)(object)m_stand == (Object)null) { return 0; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return 0; } return component.GetZDO().GetInt(ZDOVars.s_pose, 0); } public int GetMaxPoses() { return ((Object)(object)m_stand != (Object)null && m_stand.m_poseCount > 0) ? m_stand.m_poseCount : 8; } public void CyclePose() { if ((Object)(object)m_stand == (Object)null) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { int maxPoses = GetMaxPoses(); int num = component.GetZDO().GetInt(ZDOVars.s_pose, 0); int num2 = (num + 1) % maxPoses; component.InvokeRPC(0L, "RPC_SetPose", new object[1] { num2 }); if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, $"Armor Stand: Pose {num2 + 1}/{maxPoses}", 0, (Sprite)null, false); } } } public void SetPose(int poseIndex) { if (!((Object)(object)m_stand == (Object)null)) { ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid()) { int maxPoses = GetMaxPoses(); int num = Mathf.Clamp(poseIndex, 0, maxPoses - 1); component.InvokeRPC(0L, "RPC_SetPose", new object[1] { num }); } } } public void SetRandomPose() { int maxPoses = GetMaxPoses(); if (maxPoses <= 1) { return; } List<int> list = new List<int>(); for (int i = 0; i < maxPoses; i++) { if (i != 14) { list.Add(i); } } if (list.Count != 0) { int pose = list[Random.Range(0, list.Count)]; SetPose(pose); } } private static int[] GetItemKeyHashes() { if (s_itemKeyHashes == null) { FieldInfo field = typeof(ArmorStand).GetField("s_itemKeyHashes", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { s_itemKeyHashes = (int[])field.GetValue(null); } } return s_itemKeyHashes; } private static int[] GetVariantKeyHashes() { if (s_variantKeyHashes == null) { FieldInfo field = typeof(ArmorStand).GetField("s_variantKeyHashes", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { s_variantKeyHashes = (int[])field.GetValue(null); } } return s_variantKeyHashes; } private void Awake() { m_stand = ((Component)this).GetComponent<ArmorStand>(); m_timer = Random.Range(0f, ArmorGalleryPlugin.configRotationInterval.Value * 0.25f); if (!s_allRotators.Contains(this)) { s_allRotators.Add(this); } } private void Start() { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated()) { ((Behaviour)this).enabled = false; } else { if ((Object)(object)m_stand == (Object)null) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("RotationEnabled", false)) { if (!component.IsOwner()) { component.ClaimOwnership(); } ((MonoBehaviour)m_stand).CancelInvoke("UpdateVisual"); LoadLinkedChestsFromZDO(); PurgeLegacyStandZDOItemData(); if (m_linkedChests.Count > 0) { UpdateStandVisualsFromActiveRow(); m_initialVisualsLoaded = true; } } } } private void PurgeLegacyStandZDOItemData() { //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_stand == (Object)null) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } int[] itemKeyHashes = GetItemKeyHashes(); if (itemKeyHashes == null) { return; } bool flag = false; for (int i = 0; i < itemKeyHashes.Length; i++) { int num = component.GetZDO().GetInt(itemKeyHashes[i], 0); string text = ((num == 0) ? component.GetZDO().GetString(itemKeyHashes[i], "") : null); if ((num != 0 && num != AG_LOCKED_HASH) || (!string.IsNullOrEmpty(text) && text != "AG_LOCKED")) { GameObject val = null; if ((Object)(object)ObjectDB.instance != (Object)null) { if (num != 0) { val = ObjectDB.instance.GetItemPrefab(num); } else if (!string.IsNullOrEmpty(text)) { val = ObjectDB.instance.GetItemPrefab(text); } } if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<ItemDrop>() != (Object)null) { Vector3 val2 = (((Object)(object)m_stand.m_dropSpawnPoint != (Object)null) ? m_stand.m_dropSpawnPoint.position : (((Component)m_stand).transform.position + Vector3.up * 0.5f)); Quaternion val3 = (((Object)(object)m_stand.m_dropSpawnPoint != (Object)null) ? m_stand.m_dropSpawnPoint.rotation : Quaternion.identity); GameObject val4 = Object.Instantiate<GameObject>(val, val2, val3); ItemDrop component2 = val4.GetComponent<ItemDrop>(); if ((Object)(object)component2 != (Object)null) { ItemDrop.LoadFromZDO(component2.m_itemData, component.GetZDO(), i); Rigidbody component3 = val4.GetComponent<Rigidbody>(); if ((Object)(object)component3 != (Object)null) { component3.linearVelocity = Vector3.up * 4f; } flag = true; } } } component.GetZDO().Set(itemKeyHashes[i], AG_LOCKED_HASH, false); component.GetZDO().Set(ZDOVars.s_item + i, ""); } component.GetZDO().Set("AG_Locked", true); if (flag && (Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "<color=#FFD700>Armor Gallery: Gear attached during vanilla session was safely dropped at the stand.</color>", 0, (Sprite)null, false); } } private void Update() { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) if (!ArmorGalleryPlugin.configEnabled.Value || (Object)(object)m_stand == (Object)null) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } bool flag = (Object)(object)s_activeLinkingStand == (Object)(object)this; bool flag2 = component.GetZDO().GetBool("InLinkMode", false); if (flag || flag2) { UpdateConnectionEffectsContinuous(); if (flag && (Object)(object)Player.m_localPlayer != (Object)null) { m_hudMsgTimer += Time.deltaTime; if (m_hudMsgTimer >= 0.5f) { m_hudMsgTimer = 0f; string useKeyName = ArmorGalleryPlugin.GetUseKeyName(); string arg = ((object)ArmorGalleryPlugin.configModifierKey.Value).ToString(); int linkedChestCount = GetLinkedChestCount(); string arg2 = string.Format("{0} chest{1} linked", linkedChestCount, (linkedChestCount == 1) ? "" : "s"); string text = string.Format("<color=#FFD700><b>[ARMOR GALLERY: LINKING MODE]</b></color>\n<color=#FFFFFF>{0}\n• Aim at chest + [{1}] to toggle link\n• Aim at stand + [{2} + {1}] to exit</color>", arg2, useKeyName, arg); ((Character)Player.m_localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false); } } } else if (m_connectionInstances.Count > 0) { StopConnectionEffects(); } if (!component.GetZDO().GetBool("RotationEnabled", false) || ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated()) || (Object)(object)Player.m_localPlayer == (Object)null) { return; } if (m_linkedChestZDOIDs.Count == 0) { LoadLinkedChestsFromZDO(); } if (m_linkedChests.Count < m_linkedChestZDOIDs.Count) { ResolveLinkedContainers(); } if ((Object)(object)s_activeLinkingStand != (Object)(object)this) { Player closestPlayer = Player.GetClosestPlayer(((Component)m_stand).transform.position, 64f); if ((Object)(object)closestPlayer == (Object)null || (Object)(object)closestPlayer != (Object)(object)Player.m_localPlayer) { return; } } if (!component.IsOwner()) { component.ClaimOwnership(); } if (!m_initialVisualsLoaded && m_linkedChests.Count > 0) { ((MonoBehaviour)m_stand).CancelInvoke("UpdateVisual"); UpdateStandVisualsFromActiveRow(); m_initialVisualsLoaded = true; } if (m_linkedChests.Count == 0) { return; } bool flag3 = false; for (int i = 0; i < m_linkedChests.Count; i++) { if ((Object)(object)m_linkedChests[i] != (Object)null && m_linkedChests[i].IsInUse()) { flag3 = true; break; } } if (m_wasChestInUse && !flag3) { UpdateStandVisualsFromActiveRow(); } m_wasChestInUse = flag3; m_timer += Time.deltaTime; if (m_timer >= ArmorGalleryPlugin.configRotationInterval.Value) { m_timer = 0f; TryRotateSet(); } } public void SaveLinkedChestsToZDO() { //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_stand == (Object)null) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } if (!component.IsOwner()) { component.ClaimOwnership(); } if ((Object)(object)s_activeLinkingStand == (Object)(object)this || (m_linkedChests.Count > 0 && m_linkedChests.Count >= m_linkedChestZDOIDs.Count)) { RebuildZDOIDsFromChests(); } else { for (int i = 0; i < m_linkedChests.Count; i++) { Container val = m_linkedChests[i]; if (!((Object)(object)val != (Object)null)) { continue; } ZNetView component2 = ((Component)val).GetComponent<ZNetView>(); if ((Object)(object)component2 != (Object)null && component2.IsValid()) { ZDOID uid = component2.GetZDO().m_uid; if (!((ZDOID)(ref uid)).IsNone() && !m_linkedChestZDOIDs.Contains(uid)) { m_linkedChestZDOIDs.Add(uid); } } } } int num = component.GetZDO().GetInt("LinkedChestCount", 0); component.GetZDO().Set("LinkedChestCount", m_linkedChestZDOIDs.Count); for (int i = 0; i < m_linkedChestZDOIDs.Count; i++) { component.GetZDO().Set("LinkedChest_" + i, m_linkedChestZDOIDs[i]); if (i < m_linkedChests.Count && (Object)(object)m_linkedChests[i] != (Object)null) { component.GetZDO().Set("LinkedChestPos_" + i, ((Component)m_linkedChests[i]).transform.position); } } for (int i = m_linkedChestZDOIDs.Count; i < num; i++) { component.GetZDO().Set("LinkedChest_" + i, ZDOID.None); component.GetZDO().Set("LinkedChestPos_" + i, Vector3.zero); } if (m_linkedChestZDOIDs.Count > 0) { component.GetZDO().Set("LinkedChestID", m_linkedChestZDOIDs[0]); } else { component.GetZDO().Set("LinkedChestID", ZDOID.None); } component.GetZDO().Set("RotationEnabled", m_linkedChestZDOIDs.Count > 0); Debug.Log((object)$"[ArmorGallery] SaveLinkedChestsToZDO: stand at {((Component)m_stand).transform.position}, count={m_linkedChestZDOIDs.Count}"); } public void LoadLinkedChestsFromZDO() { //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_stand == (Object)null) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } m_linkedChestZDOIDs.Clear(); int num = component.GetZDO().GetInt("LinkedChestCount", -1); if (num > 0) { for (int i = 0; i < num; i++) { ZDOID zDOID = component.GetZDO().GetZDOID("LinkedChest_" + i); if (!((ZDOID)(ref zDOID)).IsNone()) { if (!m_linkedChestZDOIDs.Contains(zDOID)) { m_linkedChestZDOIDs.Add(zDOID); } continue; } Vector3 vec = component.GetZDO().GetVec3("LinkedChestPos_" + i, Vector3.zero); if (vec != Vector3.zero) { m_linkedChestZDOIDs.Add(ZDOID.None); } } } if (m_linkedChestZDOIDs.Count == 0) { ZDOID zDOID2 = component.GetZDO().GetZDOID("LinkedChestID"); if (!((ZDOID)(ref zDOID2)).IsNone() && !m_linkedChestZDOIDs.Contains(zDOID2)) { m_linkedChestZDOIDs.Add(zDOID2); } } Debug.Log((object)$"[ArmorGallery] LoadLinkedChestsFromZDO: stand at {((Component)m_stand).transform.position}, ZDO count={num}, loaded ZDOIDs={m_linkedChestZDOIDs.Count}"); ResolveLinkedContainers(); } public void ResolveLinkedContainers() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) for (int num = m_linkedChests.Count - 1; num >= 0; num--) { if ((Object)(object)m_linkedChests[num] == (Object)null) { m_linkedChests.RemoveAt(num); } } if ((Object)(object)ZNetScene.instance == (Object)null || (Object)(object)m_stand == (Object)null) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); for (int num = 0; num < m_linkedChestZDOIDs.Count; num++) { ZDOID val = m_linkedChestZDOIDs[num]; GameObject val2 = null; if (!((ZDOID)(ref val)).IsNone()) { for (int i = 0; i < m_linkedChests.Count; i++) { Container val3 = m_linkedChests[i]; if ((Object)(object)val3 != (Object)null) { ZNetView component2 = ((Component)val3).GetComponent<ZNetView>(); if ((Object)(object)component2 != (Object)null && component2.IsValid() && component2.GetZDO().m_uid == val) { val2 = ((Component)val3).gameObject; break; } } } if ((Object)(object)val2 == (Object)null) { val2 = ZNetScene.instance.FindInstance(val); } } if ((Object)(object)val2 == (Object)null && (Object)(object)component != (Object)null && component.IsValid()) { Vector3 vec = component.GetZDO().GetVec3("LinkedChestPos_" + num, Vector3.zero); if (vec != Vector3.zero) { Collider[] array = Physics.OverlapSphere(vec, 0.5f); for (int j = 0; j < array.Length; j++) { Container val3 = ((Component)array[j]).GetComponentInParent<Container>(); if (!((Object)(object)val3 != (Object)null) || !IsAcceptableContainer(val3, out var _)) { continue; } val2 = ((Component)val3).gameObject; ZNetView component2 = ((Component)val3).GetComponent<ZNetView>(); if ((Object)(object)component2 != (Object)null && component2.IsValid()) { ZDOID uid = component2.GetZDO().m_uid; if (!((ZDOID)(ref uid)).IsNone()) { m_linkedChestZDOIDs[num] = uid; component.GetZDO().Set("LinkedChest_" + num, uid); } } break; } } } if ((Object)(object)val2 != (Object)null) { Container val3 = val2.GetComponent<Container>(); if ((Object)(object)val3 != (Object)null && !m_linkedChests.Contains(val3)) { m_linkedChests.Add(val3); } } } } private void ValidateAndPruneLinkedChests() { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_activeLinkingStand != (Object)(object)this) { if (m_linkedChests.Count < m_linkedChestZDOIDs.Count || m_linkedChests.Count == 0) { ResolveLinkedContainers(); } return; } bool flag = false; for (int num = m_linkedChests.Count - 1; num >= 0; num--) { Container val = m_linkedChests[num]; if (!((Object)(object)val == (Object)null)) { float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position); if (num2 > ArmorGalleryPlugin.configMaxLinkDistance.Value) { Debug.Log((object)$"[ArmorGallery] Chest at {((Component)val).transform.position} exceeded max distance ({num2:F1}m > {ArmorGalleryPlugin.configMaxLinkDistance.Value}m), unlinking."); m_linkedChests.RemoveAt(num); flag = true; } } } if (flag) { RebuildZDOIDsFromChests(); SaveLinkedChestsToZDO(); } } public void ToggleLinkingMode() { string useKeyName = ArmorGalleryPlugin.GetUseKeyName(); ZNetView component; if ((Object)(object)s_activeLinkingStand == (Object)(object)this) { s_activeLinkingStand = null; ValidateAndPruneLinkedChests(); component = ((Component)m_stand).GetComponent<ZNetView>(); if (!((Object)(object)component != (Object)null) || !component.IsValid()) { return; } if (!component.IsOwner()) { component.ClaimOwnership(); } component.GetZDO().Set("InLinkMode", false); component.GetZDO().Set("LinkUser", ""); component.GetZDO().Set("LinkUserID", 0L); if (m_linkedChests.Count > 0 || m_linkedChestZDOIDs.Count > 0) { if (!m_wasAlreadyEnabledBeforeLinking) { SaveStandItemsToChest(); } component.GetZDO().Set("RotationEnabled", true); component.GetZDO().Set("AG_Locked", true); SaveLinkedChestsToZDO(); m_timer = 0f; m_initialVisualsLoaded = true; UpdateStandVisualsFromActiveRow(); StopConnectionEffects(); if ((Object)(object)Player.m_localPlayer != (Object)null) { int linkedChestCount = GetLinkedChestCount(); ((Character)Player.m_localPlayer).Message((MessageType)2, string.Format("Armor Gallery: Linking Mode Finished ({0} chest{1} linked)", linkedChestCount, (linkedChestCount == 1) ? "" : "s"), 0, (Sprite)null, false); } } else { ClearStandItemsAndVisuals(unlinking: true); ClearLink(); StopConnectionEffects(); if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Armor Gallery: Linking Mode Finished (Unlinked)", 0, (Sprite)null, false); } } return; } component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { bool flag = component.GetZDO().GetBool("InLinkMode", false); long num = component.GetZDO().GetLong("LinkUserID", 0L); long num2 = (((Object)(object)Player.m_localPlayer != (Object)null) ? Player.m_localPlayer.GetPlayerID() : 0); if (flag && num != 0 && num != num2) { string text = component.GetZDO().GetString("LinkUser", "another player"); if (string.IsNullOrEmpty(text)) { text = "another player"; } if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, $"Armor Gallery: Stand is currently being edited by {text}!", 0, (Sprite)null, false); } return; } if (!component.IsOwner()) { component.ClaimOwnership(); } m_wasAlreadyEnabledBeforeLinking = component.GetZDO().GetBool("RotationEnabled", false); component.GetZDO().Set("InLinkMode", true); component.GetZDO().Set("LinkUser", ((Object)(object)Player.m_localPlayer != (Object)null) ? Player.m_localPlayer.GetPlayerName() : "A Viking"); component.GetZDO().Set("LinkUserID", num2); } s_activeLinkingStand = this; LoadLinkedChestsFromZDO(); UpdateConnectionEffectsContinuous(); if ((Object)(object)Player.m_localPlayer != (Object)null) { int linkedChestCount = GetLinkedChestCount(); ((Character)Player.m_localPlayer).Message((MessageType)2, string.Format("Armor Gallery: Linking Mode Started ({0} chest{1} linked).\nLook at a chest and press [{2}] to toggle link.", linkedChestCount, (linkedChestCount == 1) ? "" : "s", useKeyName), 0, (Sprite)null, false); } } public static ArmorGalleryRotator GetRotatorLinkingChest(Container chest) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)chest == (Object)null) { return null; } foreach (ArmorGalleryRotator s_allRotator in s_allRotators) { if ((Object)(object)s_allRotator != (Object)null && (Object)(object)s_allRotator.m_stand != (Object)null && s_allRotator.IsChestLinked(chest)) { return s_allRotator; } } float num = ArmorGalleryPlugin.configMaxLinkDistance.Value + 2f; Collider[] array = Physics.OverlapSphere(((Component)chest).transform.position, num); Collider[] array2 = array; foreach (Collider val in array2) { ArmorStand componentInParent = ((Component)val).GetComponentInParent<ArmorStand>(); if ((Object)(object)componentInParent != (Object)null) { ArmorGalleryRotator current = ((Component)componentInParent).GetComponent<ArmorGalleryRotator>(); if ((Object)(object)current != (Object)null && current.IsChestLinked(chest)) { return current; } } } return null; } public static bool IsAcceptableContainer(Container container, out string failReason) { failReason = ""; if ((Object)(object)container == (Object)null) { failReason = "Invalid container!"; return false; } string prefabName = Utils.GetPrefabName(((Component)container).gameObject); if (prefabName != "piece_chest_wood" && prefabName != "piece_chest_barrel" && prefabName != "piece_chest" && prefabName != "piece_chest_blackmetal" && prefabName != "piece_chest_grausten" && prefabName != "piece_chest_warderobe") { failReason = "Only standard chests (Wood, Barrel, Reinforced, Black Metal, Grausten) and Wardrobes can be linked!"; return false; } return true; } public bool ToggleChestLink(Container chest) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)chest == (Object)null) { return false; } float num = Vector3.Distance(((Component)this).transform.position, ((Component)chest).transform.position); if (num > ArmorGalleryPlugin.configMaxLinkDistance.Value) { if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, $"Armor Gallery: Container is too far away ({num:F1}m > {ArmorGalleryPlugin.configMaxLinkDistance.Value}m max)!", 0, (Sprite)null, false); } return false; } if (!IsAcceptableContainer(chest, out var failReason)) { if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Armor Gallery: " + failReason, 0, (Sprite)null, false); } return false; } if (IsChestLinked(chest)) { Container val = null; for (int i = 0; i < m_linkedChests.Count; i++) { if ((Object)(object)m_linkedChests[i] == (Object)(object)chest || ((Object)(object)m_linkedChests[i] != (Object)null && Vector3.Distance(((Component)m_linkedChests[i]).transform.position, ((Component)chest).transform.position) < 0.2f)) { val = m_linkedChests[i]; break; } } if ((Object)(object)val != (Object)null) { m_linkedChests.Remove(val); } else { m_linkedChests.Remove(chest); } RebuildZDOIDsFromChests(); SaveLinkedChestsToZDO(); if (m_linkedChests.Count == 0 && m_linkedChestZDOIDs.Count == 0) { ClearStandItemsAndVisuals(unlinking: true); ClearLink(); } else { UpdateStandVisualsFromActiveRow(); } ShowConnectionEffects(6f); if ((Object)(object)Player.m_localPlayer != (Object)null) { int linkedChestCount = GetLinkedChestCount(); ((Character)Player.m_localPlayer).Message((MessageType)2, string.Format("Armor Gallery: Chest Unlinked ({0} chest{1} remaining)", linkedChestCount, (linkedChestCount == 1) ? "" : "s"), 0, (Sprite)null, false); } return true; } ArmorGalleryRotator rotatorLinkingChest = GetRotatorLinkingChest(chest); if ((Object)(object)rotatorLinkingChest != (Object)null && (Object)(object)rotatorLinkingChest != (Object)(object)this) { if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Armor Gallery: Chest is already linked to another Armor Stand!", 0, (Sprite)null, false); } return false; } if (m_linkedChests.Count >= ArmorGalleryPlugin.configMaxLinkedChests.Value) { if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, $"Armor Gallery: Maximum linked chests reached ({m_linkedChests.Count}/{ArmorGalleryPlugin.configMaxLinkedChests.Value})!", 0, (Sprite)null, false); } return false; } if (!m_linkedChests.Contains(chest)) { m_linkedChests.Add(chest); } RebuildZDOIDsFromChests(); SaveLinkedChestsToZDO(); ShowConnectionEffects(6f); if ((Object)(object)Player.m_localPlayer != (Object)null) { int linkedChestCount = GetLinkedChestCount(); ((Character)Player.m_localPlayer).Message((MessageType)2, $"Armor Gallery: Chest Linked ({linkedChestCount}/{ArmorGalleryPlugin.configMaxLinkedChests.Value} chests linked)", 0, (Sprite)null, false); } return true; } public void OnChestDestroyed(Container chest) { if ((Object)(object)chest != (Object)null) { m_linkedChests.Remove(chest); RebuildZDOIDsFromChests(); SaveLinkedChestsToZDO(); if (m_linkedChestZDOIDs.Count == 0 && m_linkedChests.Count == 0) { ClearStandItemsAndVisuals(unlinking: true); ClearLink(); } else { UpdateStandVisualsFromActiveRow(); } } } public List<SetRef> GetAllPopulatedSets() { List<SetRef> list = new List<SetRef>(); List<Container> linkedChests = GetLinkedChests(); int num = 1; for (int i = 0; i < linkedChests.Count; i++) { Container val = linkedChests[i]; if ((Object)(object)val == (Object)null) { continue; } Inventory inventory = val.GetInventory(); if (inventory == null) { continue; } int height = inventory.GetHeight(); int width = inventory.GetWidth(); int num2 = Math.Min(width, 6); for (int j = 0; j < height; j++) { bool flag = false; for (int k = 0; k < num2; k++) { if (inventory.GetItemAt(k, j) != null) { flag = true; break; } } if (flag) { list.Add(new SetRef { Chest = val, ChestIndex = i, ChestRow = j, GlobalSetNumber = num }); } num++; } } return list; } public List<int> GetPopulatedRows(Inventory chestInventory) { List<int> list = new List<int>(); if (chestInventory == null) { return list; } int height = chestInventory.GetHeight(); int width = chestInventory.GetWidth(); int num = Math.Min(width, 6); for (int i = 0; i < height; i++) { bool flag = false; for (int j = 0; j < num; j++) { if (chestInventory.GetItemAt(j, i) != null) { flag = true; break; } } if (flag) { list.Add(i); } } return list; } private void TryRotateSet() { List<Container> linkedChests = GetLinkedChests(); if (linkedChests.Count == 0) { return; } for (int i = 0; i < linkedChests.Count; i++) { if ((Object)(object)linkedChests[i] != (Object)null && linkedChests[i].IsInUse()) { return; } } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } if (!component.IsOwner()) { component.ClaimOwnership(); } List<SetRef> allPopulatedSets = GetAllPopulatedSets(); if (allPopulatedSets.Count != 0) { if (ArmorGalleryPlugin.configRandomizePoseOnCycle.Value) { SetRandomPose(); } if (ArmorGalleryPlugin.configRandomizeStanceOnCycle.Value) { SetRandomWeaponsEquipped(); } switch (ArmorGalleryPlugin.configRotationMode.Value) { case RotationMode.Chaos: UpdateStandVisualsChaos(); break; case RotationMode.RandomRow: { m_activeSetIndex = Random.Range(0, allPopulatedSets.Count); SetRef setRef = allPopulatedSets[m_activeSetIndex]; UpdateStandVisuals(setRef.Chest, setRef.ChestRow, setRef.GlobalSetNumber); break; } default: { m_activeSetIndex = (m_activeSetIndex + 1) % allPopulatedSets.Count; SetRef setRef = allPopulatedSets[m_activeSetIndex]; UpdateStandVisuals(setRef.Chest, setRef.ChestRow, setRef.GlobalSetNumber); break; } } } } public bool FindFirstEmptyChestRow(out Container targetChest, out int targetRow) { targetChest = null; targetRow = -1; List<Container> linkedChests = GetLinkedChests(); for (int i = 0; i < linkedChests.Count; i++) { Container val = linkedChests[i]; if ((Object)(object)val == (Object)null) { continue; } Inventory inventory = val.GetInventory(); if (inventory == null) { continue; } int height = inventory.GetHeight(); int width = inventory.GetWidth(); for (int j = 0; j < height; j++) { bool flag = true; for (int k = 0; k < width; k++) { if (inventory.GetItemAt(k, j) != null) { flag = false; break; } } if (flag) { targetChest = val; targetRow = j; return true; } } } return false; } public void ClearStandItemsAndVisuals(bool unlinking = false) { //IL_01b4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_stand == (Object)null) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } if (!component.IsOwner()) { component.ClaimOwnership(); } int[] itemKeyHashes = GetItemKeyHashes(); int[] variantKeyHashes = GetVariantKeyHashes(); int num = ((!unlinking) ? AG_LOCKED_HASH : 0); for (int i = 0; i < m_stand.m_slots.Count; i++) { if (itemKeyHashes != null && i < itemKeyHashes.Length) { component.GetZDO().Set(itemKeyHashes[i], num, false); } if (variantKeyHashes != null && i < variantKeyHashes.Length) { component.GetZDO().Set(variantKeyHashes[i], 0, false); } component.GetZDO().Set(ZDOVars.s_item + i, ""); if (i < m_stand.m_slots.Count && m_stand.m_slots[i] != null) { m_stand.m_slots[i].m_visualHash = 0; m_stand.m_slots[i].m_visualVariant = -1; } if ((Object)(object)m_stand.m_visEquipment != (Object)null && i < m_stand.m_slots.Count && m_stand.m_slots[i] != null) { m_stand.m_visEquipment.SetItem(m_stand.m_slots[i].m_slot, 0, 0, 0); } component.InvokeRPC(0L, "RPC_SetVisualItem", new object[3] { i, 0, 0 }); } component.GetZDO().Set(ZDOVars.s_helmetItem, 0, false); component.GetZDO().Set(ZDOVars.s_chestItem, 0, false); component.GetZDO().Set(ZDOVars.s_legItem, 0, false); component.GetZDO().Set(ZDOVars.s_shoulderItem, 0, false); component.GetZDO().Set(ZDOVars.s_shoulderItemVariant, 0, false); component.GetZDO().Set(ZDOVars.s_rightItem, 0, false); component.GetZDO().Set(ZDOVars.s_rightBackItem, 0, false); component.GetZDO().Set(ZDOVars.s_leftItem, 0, false); component.GetZDO().Set(ZDOVars.s_leftBackItem, 0, false); component.GetZDO().Set(ZDOVars.s_utilityItem, 0, false); if (!((Object)(object)m_stand.m_visEquipment != (Object)null)) { return; } FieldInfo[] array = s_currentHashFields; foreach (FieldInfo fieldInfo in array) { if (fieldInfo != null) { fieldInfo.SetValue(m_stand.m_visEquipment, -1); } } m_stand.m_visEquipment.CustomUpdate(0f, 0f); } public void ClearLink() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) StopConnectionEffects(); m_linkedChests.Clear(); m_linkedChestZDOIDs.Clear(); m_initialVisualsLoaded = false; ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { int num = component.GetZDO().GetInt("LinkedChestCount", 0); for (int i = 0; i < num; i++) { component.GetZDO().Set("LinkedChest_" + i, ZDOID.None); component.GetZDO().Set("LinkedChestPos_" + i, Vector3.zero); } component.GetZDO().Set("RotationEnabled", false); component.GetZDO().Set("AG_Locked", false); component.GetZDO().Set("LinkedChestID", ZDOID.None); component.GetZDO().Set("LinkedChestCount", 0); component.GetZDO().Set("InLinkMode", false); component.GetZDO().Set("LinkUser", ""); component.GetZDO().Set("LinkUserID", 0L); } if ((Object)(object)m_stand != (Object)null) { ((MonoBehaviour)m_stand).InvokeRepeating("UpdateVisual", 1f, 4f); } } public static GameObject GetConnectionPrefab() { if ((Object)(object)s_connectionPrefab != (Object)null) { return s_connectionPrefab; } if ((Object)(object)ZNetScene.instance != (Object)null) { string[] array = new string[7] { "piece_workbench_ext1", "piece_workbench_ext2", "piece_workbench_ext3", "piece_workbench_ext4", "piece_forge_ext1", "piece_forge_ext2", "piece_forge_ext3" }; string[] array2 = array; foreach (string text in array2) { GameObject prefab = ZNetScene.instance.GetPrefab(text); if ((Object)(object)prefab != (Object)null) { StationExtension component = prefab.GetComponent<StationExtension>(); if ((Object)(object)component != (Object)null && (Object)(object)component.m_connectionPrefab != (Object)null) { s_connectionPrefab = component.m_connectionPrefab; return s_connectionPrefab; } } } } return null; } public void UpdateConnectionEffectsContinuous() { //IL_0067: 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_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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)m_stand == (Object)null) { return; } List<Container> linkedChests = GetLinkedChests(); if (linkedChests.Count == 0) { StopConnectionEffects(); return; } GameObject connectionPrefab = GetConnectionPrefab(); if ((Object)(object)connectionPrefab == (Object)null) { return; } Vector3 val = ((Component)m_stand).transform.position + Vector3.up * 0.9f; while (m_connectionInstances.Count < linkedChests.Count) { GameObject item = Object.Instantiate<GameObject>(connectionPrefab, val, Quaternion.identity); m_connectionInstances.Add(item); } while (m_connectionInstances.Count > linkedChests.Count) { int index = m_connectionInstances.Count - 1; if ((Object)(object)m_connectionInstances[index] != (Object)null) { Object.Destroy((Object)(object)m_connectionInstances[index]); } m_connectionInstances.RemoveAt(index); } for (int i = 0; i < linkedChests.Count; i++) { Container val2 = linkedChests[i]; GameObject item = m_connectionInstances[i]; if ((Object)(object)val2 != (Object)null && (Object)(object)item != (Object)null) { Vector3 val3 = ((Component)val2).transform.position + Vector3.up * 0.4f; Vector3 val4 = val - val3; item.transform.position = val3; item.transform.rotation = Quaternion.LookRotation(((Vector3)(ref val4)).normalized); item.transform.localScale = new Vector3(1f, 1f, ((Vector3)(ref val4)).magnitude); } } } public void ShowConnectionEffects(float duration = 4f) { UpdateConnectionEffectsContinuous(); ((MonoBehaviour)this).CancelInvoke("StopConnectionEffects"); ((MonoBehaviour)this).Invoke("StopConnectionEffects", duration); } public void StopConnectionEffects() { for (int i = 0; i < m_connectionInstances.Count; i++) { if ((Object)(object)m_connectionInstances[i] != (Object)null) { Object.Destroy((Object)(object)m_connectionInstances[i]); } } m_connectionInstances.Clear(); } private void OnDisable() { StopConnectionEffects(); } private void OnDestroy() { StopConnectionEffects(); s_allRotators.Remove(this); if (!((Object)(object)s_activeLinkingStand == (Object)(object)this)) { return; } s_activeLinkingStand = null; if ((Object)(object)m_stand != (Object)null) { ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { component.GetZDO().Set("InLinkMode", false); component.GetZDO().Set("LinkUser", ""); component.GetZDO().Set("LinkUserID", 0L); } } } private static string GetItemPrefabName(ItemData item) { if (item == null) { return ""; } if ((Object)(object)item.m_dropPrefab != (Object)null) { return ((Object)item.m_dropPrefab).name; } if ((Object)(object)ObjectDB.instance != (Object)null) { foreach (GameObject item2 in ObjectDB.instance.m_items) { if ((Object)(object)item2 != (Object)null) { ItemDrop component = item2.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null && component.m_itemData != null && component.m_itemData.m_shared != null && component.m_itemData.m_shared.m_name == item.m_shared.m_name) { return ((Object)item2).name; } } } } return ""; } private static int GetStandSlotIndexForVisSlot(ArmorStand stand, VisSlot targetSlot) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Invalid comparison between Unknown and I4 //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Invalid comparison between Unknown and I4 if ((Object)(object)stand == (Object)null || stand.m_slots == null) { return -1; } for (int i = 0; i < stand.m_slots.Count; i++) { if (stand.m_slots[i] != null) { VisSlot slot = stand.m_slots[i].m_slot; if (slot == targetSlot) { return i; } if ((int)targetSlot == 0 && ((int)slot == 0 || (int)slot == 2)) { return i; } if ((int)targetSlot == 1 && ((int)slot == 1 || (int)slot == 3)) { return i; } } } return -1; } public void UpdateStandVisualsFromActiveRow() { List<SetRef> allPopulatedSets = GetAllPopulatedSets(); if (allPopulatedSets.Count == 0) { Container primaryChest = GetPrimaryChest(); if ((Object)(object)primaryChest != (Object)null) { UpdateStandVisuals(primaryChest, 0, 1); } return; } if (m_activeSetIndex >= allPopulatedSets.Count) { m_activeSetIndex = 0; } if (ArmorGalleryPlugin.configRotationMode.Value == RotationMode.Chaos) { UpdateStandVisualsChaos(); return; } SetRef setRef = allPopulatedSets[m_activeSetIndex]; UpdateStandVisuals(setRef.Chest, setRef.ChestRow, setRef.GlobalSetNumber); } public void UpdateStandVisuals(Container chest, int row, int globalSetNumber) { //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Invalid comparison between Unknown and I4 //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Invalid comparison between Unknown and I4 //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Invalid comparison between Unknown and I4 //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Invalid comparison between Unknown and I4 //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Invalid comparison between Unknown and I4 //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_031e: Invalid comparison between Unknown and I4 //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_0426: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Invalid comparison between Unknown and I4 //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Invalid comparison between Unknown and I4 //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Invalid comparison between Unknown and I4 //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Invalid comparison between Unknown and I4 //IL_0577: Unknown result type (might be due to invalid IL or missing references) if (m_isSyncing || (Object)(object)chest == (Object)null || (Object)(object)m_stand == (Object)null) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } if (!component.IsOwner()) { component.ClaimOwnership(); } Inventory inventory = chest.GetInventory(); if (inventory == null) { return; } int[] itemKeyHashes = GetItemKeyHashes(); int[] variantKeyHashes = GetVariantKeyHashes(); if (itemKeyHashes == null) { return; } m_isSyncing = true; component.GetZDO().Set("ActiveSetRow", row); component.GetZDO().Set("ActiveGlobalSet", globalSetNumber); for (int i = 0; i < m_stand.m_slots.Count; i++) { if (m_stand.m_slots[i] != null) { m_stand.m_slots[i].m_visualHash = 0; m_stand.m_slots[i].m_visualVariant = -1; } } if ((Object)(object)m_stand.m_visEquipment != (Object)null) { for (int j = 0; j < s_currentHashFields.Length; j++) { if (s_currentHashFields[j] != null) { s_currentHashFields[j].SetValue(m_stand.m_visEquipment, -1); } } } ItemData val = null; ItemData val2 = null; ItemData val3 = null; ItemData val4 = null; ItemData val5 = null; ItemData val6 = null; ItemData itemAt = inventory.GetItemAt(0, row); ItemData itemAt2 = inventory.GetItemAt(1, row); ItemData itemAt3 = inventory.GetItemAt(2, row); ItemData itemAt4 = inventory.GetItemAt(3, row); ItemData itemAt5 = inventory.GetItemAt(4, row); ItemData itemAt6 = inventory.GetItemAt(5, row); if (itemAt != null && (int)itemAt.m_shared.m_itemType == 6) { val = itemAt; } if (itemAt2 != null && (int)itemAt2.m_shared.m_itemType == 7) { val2 = itemAt2; } if (itemAt3 != null && (int)itemAt3.m_shared.m_itemType == 11) { val3 = itemAt3; } if (itemAt4 != null && (int)itemAt4.m_shared.m_itemType == 5) { val4 = itemAt4; } if (itemAt5 != null && InventoryGrid_DropItem_Patch.IsItemValidForSlot(4, itemAt5)) { val5 = itemAt5; } if (itemAt6 != null && (int)itemAt6.m_shared.m_itemType == 17) { val6 = itemAt6; } int width = inventory.GetWidth(); for (int k = 0; k < width; k++) { ItemData itemAt7 = inventory.GetItemAt(k, row); if (itemAt7 != null) { ItemType itemType = itemAt7.m_shared.m_itemType; if (val == null && (int)itemType == 6) { val = itemAt7; } else if (val2 == null && (int)itemType == 7) { val2 = itemAt7; } else if (val3 == null && (int)itemType == 11) { val3 = itemAt7; } else if (val4 == null && (int)itemType == 5) { val4 = itemAt7; } else if (val5 == null && InventoryGrid_DropItem_Patch.IsItemValidForSlot(4, itemAt7)) { val5 = itemAt7; } else if (val6 == null && (int)itemType == 17) { val6 = itemAt7; } } } ItemData[] array = (ItemData[])(object)new ItemData[6] { val, val2, val3, val4, val5, val6 }; for (int l = 0; l < UI_COLUMN_SLOTS.Length; l++) { VisSlot val7 = UI_COLUMN_SLOTS[l]; int standSlotIndexForVisSlot = GetStandSlotIndexForVisSlot(m_stand, val7); ItemData val8 = array[l]; string itemPrefabName = GetItemPrefabName(val8); int num = val8?.m_variant ?? 0; bool flag = val8 != null && InventoryGrid_DropItem_Patch.IsItemValidForSlot(l, val8, inventory, row); int num2 = ((flag && !string.IsNullOrEmpty(itemPrefabName)) ? StringExtensionMethods.GetStableHashCode(itemPrefabName) : 0); int num3 = (flag ? num : 0); if (standSlotIndexForVisSlot >= 0 && standSlotIndexForVisSlot < itemKeyHashes.Length) { component.GetZDO().Set(itemKeyHashes[standSlotIndexForVisSlot], AG_LOCKED_HASH, false); if (variantKeyHashes != null && standSlotIndexForVisSlot < variantKeyHashes.Length) { component.GetZDO().Set(variantKeyHashes[standSlotIndexForVisSlot], num3, false); } if (standSlotIndexForVisSlot < m_stand.m_slots.Count && m_stand.m_slots[standSlotIndexForVisSlot] != null) { m_stand.m_slots[standSlotIndexForVisSlot].m_visualHash = num2; m_stand.m_slots[standSlotIndexForVisSlot].m_visualVariant = num3; } if ((Object)(object)m_stand.m_visEquipment != (Object)null) { m_stand.m_visEquipment.SetItem(val7, num2, num3, val8?.m_quality ?? 1); } component.InvokeRPC(0L, "RPC_SetVisualItem", new object[3] { standSlotIndexForVisSlot, num2, num3 }); } } ApplyWeaponStance(val5, val4); if ((Object)(object)m_stand.m_visEquipment != (Object)null) { m_stand.m_visEquipment.CustomUpdate(0f, 0f); } m_isSyncing = false; } public void UpdateStandVisualsChaos() { //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) if (m_isSyncing || (Object)(object)m_stand == (Object)null) { return; } List<Container> linkedChests = GetLinkedChests(); if (linkedChests.Count == 0) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } if (!component.IsOwner()) { component.ClaimOwnership(); } int[] itemKeyHashes = GetItemKeyHashes(); int[] variantKeyHashes = GetVariantKeyHashes(); if (itemKeyHashes == null) { return; } m_isSyncing = true; for (int i = 0; i < m_stand.m_slots.Count; i++) { if (m_stand.m_slots[i] != null) { m_stand.m_slots[i].m_visualHash = 0; m_stand.m_slots[i].m_visualVariant = -1; } } if ((Object)(object)m_stand.m_visEquipment != (Object)null) { for (int j = 0; j < s_currentHashFields.Length; j++) { if (s_currentHashFields[j] != null) { s_currentHashFields[j].SetValue(m_stand.m_visEquipment, -1); } } } ItemData randomItemInColumnAcrossChests = GetRandomItemInColumnAcrossChests(0); ItemData randomItemInColumnAcrossChests2 = GetRandomItemInColumnAcrossChests(1); ItemData randomItemInColumnAcrossChests3 = GetRandomItemInColumnAcrossChests(2); ItemData randomItemInColumnAcrossChests4 = GetRandomItemInColumnAcrossChests(3); ItemData randomItemInColumnAcrossChests5 = GetRandomItemInColumnAcrossChests(4); ItemData randomItemInColumnAcrossChests6 = GetRandomItemInColumnAcrossChests(5); ItemData[] array = (ItemData[])(object)new ItemData[6] { randomItemInColumnAcrossChests, randomItemInColumnAcrossChests2, randomItemInColumnAcrossChests3, randomItemInColumnAcrossChests4, randomItemInColumnAcrossChests5, randomItemInColumnAcrossChests6 }; for (int k = 0; k < UI_COLUMN_SLOTS.Length; k++) { VisSlot val = UI_COLUMN_SLOTS[k]; int standSlotIndexForVisSlot = GetStandSlotIndexForVisSlot(m_stand, val); ItemData val2 = array[k]; string itemPrefabName = GetItemPrefabName(val2); int num = val2?.m_variant ?? 0; bool flag = val2 != null && InventoryGrid_DropItem_Patch.IsItemValidForSlot(k, val2); int num2 = ((flag && !string.IsNullOrEmpty(itemPrefabName)) ? StringExtensionMethods.GetStableHashCode(itemPrefabName) : 0); int num3 = (flag ? num : 0); if (standSlotIndexForVisSlot >= 0 && standSlotIndexForVisSlot < itemKeyHashes.Length) { component.GetZDO().Set(itemKeyHashes[standSlotIndexForVisSlot], AG_LOCKED_HASH, false); if (variantKeyHashes != null && standSlotIndexForVisSlot < variantKeyHashes.Length) { component.GetZDO().Set(variantKeyHashes[standSlotIndexForVisSlot], num3, false); } if (standSlotIndexForVisSlot < m_stand.m_slots.Count && m_stand.m_slots[standSlotIndexForVisSlot] != null) { m_stand.m_slots[standSlotIndexForVisSlot].m_visualHash = num2; m_stand.m_slots[standSlotIndexForVisSlot].m_visualVariant = num3; } if ((Object)(object)m_stand.m_visEquipment != (Object)null) { m_stand.m_visEquipment.SetItem(val, num2, num3, val2?.m_quality ?? 1); } component.InvokeRPC(0L, "RPC_SetVisualItem", new object[3] { standSlotIndexForVisSlot, num2, num3 }); } } ApplyWeaponStance(randomItemInColumnAcrossChests5, randomItemInColumnAcrossChests4); if ((Object)(object)m_stand.m_visEquipment != (Object)null) { m_stand.m_visEquipment.CustomUpdate(0f, 0f); } m_isSyncing = false; } private void ApplyWeaponStance(ItemData weaponItem, ItemData shieldItem) { ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } bool weaponsEquipped = GetWeaponsEquipped(); bool flag = weaponItem != null && InventoryGrid_DropItem_Patch.IsTwoHandedWeapon(weaponItem); string itemPrefabName = GetItemPrefabName(weaponItem); string itemPrefabName2 = GetItemPrefabName(shieldItem); if (weaponsEquipped) { component.GetZDO().Set(ZDOVars.s_rightItem, (!string.IsNullOrEmpty(itemPrefabName)) ? StringExtensionMethods.GetStableHashCode(itemPrefabName) : 0, false); component.GetZDO().Set(ZDOVars.s_rightBackItem, 0, false); if (flag) { component.GetZDO().Set(ZDOVars.s_leftBackItem, (!string.IsNullOrEmpty(itemPrefabName2)) ? StringExtensionMethods.GetStableHashCode(itemPrefabName2) : 0, false); component.GetZDO().Set(ZDOVars.s_leftItem, 0, false); } else { component.GetZDO().Set(ZDOVars.s_leftItem, (!string.IsNullOrEmpty(itemPrefabName2)) ? StringExtensionMethods.GetStableHashCode(itemPrefabName2) : 0, false); component.GetZDO().Set(ZDOVars.s_leftBackItem, 0, false); } } else { component.GetZDO().Set(ZDOVars.s_rightItem, 0, false); component.GetZDO().Set(ZDOVars.s_leftItem, 0, false); component.GetZDO().Set(ZDOVars.s_rightBackItem, (!string.IsNullOrEmpty(itemPrefabName)) ? StringExtensionMethods.GetStableHashCode(itemPrefabName) : 0, false); component.GetZDO().Set(ZDOVars.s_leftBackItem, (!string.IsNullOrEmpty(itemPrefabName2)) ? StringExtensionMethods.GetStableHashCode(itemPrefabName2) : 0, false); } } private ItemData GetRandomItemInColumnAcrossChests(int col) { List<ItemData> list = new List<ItemData>(); List<Container> linkedChests = GetLinkedChests(); for (int i = 0; i < linkedChests.Count; i++) { Container val = linkedChests[i]; if ((Object)(object)val == (Object)null) { continue; } Inventory inventory = val.GetInventory(); if (inventory == null) { continue; } int height = inventory.GetHeight(); int width = inventory.GetWidth(); for (int j = 0; j < height; j++) { for (int k = 0; k < width; k++) { ItemData itemAt = inventory.GetItemAt(k, j); if (itemAt != null && InventoryGrid_DropItem_Patch.IsItemValidForSlot(col, itemAt, inventory, j)) { list.Add(itemAt); } } } } if (list.Count == 0) { return null; } return list[Random.Range(0, list.Count)]; } private bool SaveStandItemsToChest() { //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) List<Container> linkedChests = GetLinkedChests(); if (linkedChests.Count == 0) { return false; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return false; } int[] itemKeyHashes = GetItemKeyHashes(); int[] variantKeyHashes = GetVariantKeyHashes(); if (itemKeyHashes == null) { return false; } bool flag = false; for (int i = 0; i < m_stand.m_slots.Count; i++) { if (itemKeyHashes != null && i < itemKeyHashes.Length) { int num = component.GetZDO().GetInt(itemKeyHashes[i], 0); string text = ((num == 0) ? component.GetZDO().GetString(itemKeyHashes[i], "") : null); if ((num != 0 && num != AG_LOCKED_HASH) || (!string.IsNullOrEmpty(text) && text != "AG_LOCKED")) { flag = true; break; } } } if (!flag) { m_activeSetIndex = 0; return true; } if (!FindFirstEmptyChestRow(out var targetChest, out var targetRow)) { Debug.Log((object)"[ArmorGallery] All linked chests are full — cannot save stand items."); if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Armor Gallery: All linked chests are full!", 0, (Sprite)null, false); } return false; } ZNetView component2 = ((Component)targetChest).GetComponent<ZNetView>(); if ((Object)(object)component2 != (Object)null && component2.IsValid() && !component2.IsOwner()) { component2.ClaimOwnership(); } Inventory inventory = targetChest.GetInventory(); if (inventory == null) { return false; } m_isSyncing = true; bool flag2 = false; for (int j = 0; j < UI_COLUMN_SLOTS.Length; j++) { VisSlot targetSlot = UI_COLUMN_SLOTS[j]; int standSlotIndexForVisSlot = GetStandSlotIndexForVisSlot(m_stand, targetSlot); if (standSlotIndexForVisSlot < 0 || standSlotIndexForVisSlot >= itemKeyHashes.Length) { continue; } int num = component.GetZDO().GetInt(itemKeyHashes[standSlotIndexForVisSlot], 0); string text = ((num == 0) ? component.GetZDO().GetString(itemKeyHashes[standSlotIndexForVisSlot], "") : null); if ((num == 0 || num == AG_LOCKED_HASH) && (string.IsNullOrEmpty(text) || text == "AG_LOCKED")) { continue; } GameObject val = null; if ((Object)(object)ObjectDB.instance != (Object)null) { if (num != 0) { val = ObjectDB.instance.GetItemPrefab(num); } else if (!string.IsNullOrEmpty(text)) { val = ObjectDB.instance.GetItemPrefab(text); } } if ((Object)(object)val == (Object)null) { continue; } ItemDrop component3 = val.GetComponent<ItemDrop>(); if (!((Object)(object)component3 == (Object)null)) { ItemData val2 = component3.m_itemData.Clone(); ItemDrop.LoadFromZDO(val2, component.GetZDO(), standSlotIndexForVisSlot); val2.m_gridPos = new Vector2i(j, targetRow); inventory.AddItem(val2, new Vector2i(j, targetRow)); flag2 = true; component.GetZDO().Set(itemKeyHashes[standSlotIndexForVisSlot], 0, false); component.GetZDO().Set(ZDOVars.s_item + standSlotIndexForVisSlot, ""); if (variantKeyHashes != null && standSlotIndexForVisSlot < variantKeyHashes.Length) { component.GetZDO().Set(variantKeyHashes[standSlotIndexForVisSlot], 0, false); } string arg = ((!string.IsNullOrEmpty(val2.m_shared.m_name)) ? val2.m_shared.m_name : (((Object)(object)val != (Object)null) ? ((Object)val).name : "unknown")); Debug.Log((object)$"[ArmorGallery] Saved stand item '{arg}' to chest row {targetRow}"); } } m_isSyncing = false; if (flag2 && inventory.m_onChanged != null) { inventory.m_onChanged(); } return true; } public bool GetWeaponsEquipped() { if ((Object)(object)m_stand == (Object)null) { return false; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); return (Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("WeaponsEquipped", false); } public void ToggleWeaponsEquipped() { if ((Object)(object)m_stand == (Object)null) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { if (!component.IsOwner()) { component.ClaimOwnership(); } bool flag = component.GetZDO().GetBool("WeaponsEquipped", false); component.GetZDO().Set("WeaponsEquipped", !flag); UpdateStandVisualsFromActiveRow(); } } public void SetWeaponsEquipped(bool equipped) { if ((Object)(object)m_stand == (Object)null) { return; } ZNetView component = ((Component)m_stand).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { if (!component.IsOwner()) { component.ClaimOwnership(); } component.GetZDO().Set("WeaponsEquipped", equipped); } } public void SetRandomWeaponsEquipped() { bool weaponsEquipped = Random.value > 0.5f; SetWeaponsEquipped(weaponsEquipped); } } [HarmonyPatch(typeof(InventoryGui), "Show", new Type[] { typeof(Container), typeof(int) })] public static class InventoryGui_Show_Patch { public static void Postfix(InventoryGui __instance, Container container) { ArmorGalleryUI.OnShowContainer(__instance, container); } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class InventoryGui_Hide_Patch { public static void Postfix(InventoryGui __instance) { ArmorGalleryUI.OnHideContainer(__instance); } } [HarmonyPatch(typeof(InventoryGui), "CloseContainer")] public static class InventoryGui_CloseContainer_Patch { public static void Postfix(InventoryGui __instance) { ArmorGalleryUI.OnHideContainer(__instance); } } [HarmonyPatch(typeof(InventoryGui), "UpdateContainer", new Type[] { typeof(Player) })] public static class InventoryGui_UpdateContainer_Patch { public static bool Prefix(InventoryGui __instance, Player player) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)player == (Object)null) { return true; } Container val = ((!(ArmorGalleryUI.currentContainerField != null)) ? ((Container)null) : ((Container)ArmorGalleryUI.currentContainerField.GetValue(__instance))); if ((Object)(object)val != (Object)null) { ArmorStand linkedArmorStand = ArmorGalleryUI.GetLinkedArmorStand(val); if ((Object)(object)linkedArmorStand != (Object)null) { __instance.m_autoCloseDistance = ArmorGalleryPlugin.configMaxLinkDistance.Value + 5f; ZNetView component = ((Component)val).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && !component.IsOwner()) { component.ClaimOwnership(); } } else { __instance.m_autoCloseDistance = 4f; } } return true; } public static void Postfix(InventoryGui __instance, Player player) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_container == (Object)null) { return; } Container val = ((!(ArmorGalleryUI.currentContainerField != null)) ? ((Container)null) : ((Container)ArmorGalleryUI.currentContainerField.GetValue(__instance))); if ((Object)(object)val == (Object)null) { return; } ArmorStand linkedArmorStand = ArmorGalleryUI.GetLinkedArmorStand(val); if ((Object)(object)linkedArmorStand == (Object)null) { return; } if ((Object)(object)ArmorGalleryUI.activeContainer != (Object)(object)val) { ArmorGalleryUI.OnShowContainer(__instance, val); } if ((Object)(object)ArmorGalleryUI.activeStand != (Object)null) { if (!ArmorGalleryUI.HasValidUIElements()) { ArmorGalleryUI.InjectUI(__instance, val); } else { ArmorGalleryUI.EnforceGridTransform(__instance); } } } } [HarmonyPatch(typeof(InventoryGrid), "UpdateInventory", new Type[] { typeof(Inventory), typeof(Player), typeof(ItemData) })] public static class InventoryGrid_UpdateInventory_Patch { public static void Postfix(InventoryGrid __instance, Inventory inventory, Player player, ItemData dragItem) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown if ((Object)(object)InventoryGui.instance == (Object)null || (Object)(object)ArmorGalleryUI.activeContainer == (Object)null || (Object)(object)ArmorGalleryUI.activeStand == (Object)null) { return; } InventoryGrid val = (InventoryGrid)ArmorGalleryUI.containerGridField.GetValue(InventoryGui.instance); if (!((Object)(object)__instance != (Object)(object)val)) { if (!ArmorGalleryUI.HasValidUIElements()) { ArmorGalleryUI.InjectUI(InventoryGui.instance, ArmorGalleryUI.activeContainer); } else { ArmorGalleryUI.UpdateMisplacedSlotHighlights(InventoryGui.instance, ArmorGalleryUI.activeContainer); } } } } [HarmonyPatch(typeof(InventoryGrid), "DropItem")] public static class InventoryGrid_DropItem_Patch { public static bool Prefix(InventoryGrid __instance, Inventory fromInventory, ItemData item, int amount, Vector2i pos, ref bool __result) { Inventory inventory = __instance.GetInventory(); if ((Object)(object)ArmorGalleryUI.activeStand != (Object)null && (Object)(object)ArmorGalleryUI.activeContainer != (Object)null && inventory != null) { ArmorGalleryRotator component = ((Component)ArmorGalleryUI.activeStand).GetComponent<ArmorGalleryRotator>(); if ((Object)(object)component != (Object)null && component.IsChestLinked(ArmorGalleryUI.activeContainer) && ArmorGalleryUI.activeContainer.GetInventory() == inventory && !IsItemValidForSlot(pos.x, item, inventory, pos.y)) { __result = false; return false; } } return true; } public static bool IsTwoHandedWeapon(ItemData item) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 if (item == null) { return false; } ItemType itemType = item.m_shared.m_itemType; ItemType attachOverride = item.m_shared.m_attachOverride; if ((int)itemType == 14 || (int)itemType == 22 || (int)itemType == 4 || (int)attachOverride == 4 || (int)attachOverride == 14 || (int)attachOverride == 22) { return true; } string text = ((item.m_shared.m_name != null) ? item.m_shared.m_name.ToLower() : ""); string text2 = (((Object)(object)item.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name.ToLower() : ""); if (text.Contains("bow") || text.Contains("crossbow") || text2.Contains("bow") || text2.Contains("crossbow") || text.Contains("dual") || text.Contains("berserker") || text2.Contains("early") || text2.Contains("dual")) { return true; } return false; } public static bool IsItemValidForSlot(int slotIndex, ItemData item, Inventory inv = null, int row = -1) { //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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Invalid comparison between Unknown and I4 //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Invalid comparison between Unknown and I4 //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Invalid comparison between Unknown and I4 //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 if (item == null) { return true; } ItemType itemType = item.m_shared.m_itemType; return slotIndex switch { 0 => (int)itemType == 6, 1 => (int)itemType == 7, 2 => (int)itemType == 11, 3 => (int)itemType == 5, 4 => (int)itemType == 3 || (int)itemType == 14 || (int)itemType == 22 || (int)itemType == 15 || (int)itemType == 4, 5 => (int)itemType == 17, _ => true, }; } } [HarmonyPatch(typeof(Container), "Interact")] public static class Container_Interact_Patch { public static bool Prefix(Container __instance, Humanoid character, bool hold, bool alt, ref bool __result) { if ((Object)(object)ArmorGalleryRotator.s_activeLinkingStand != (Object)null) { ArmorGalleryRotator.s_activeLinkingStand.ToggleChestLink(__instance); __result = true; return false; } return true; } } [HarmonyPatch(typeof(Container), "GetHoverText")] public static class Container_GetHoverText_Patch { public static void Postfix(Container __instance, ref string __result) { if ((Object)(object)__instance == (Object)null || (Object)(object)ArmorGalleryRotator.s_activeLinkingStand == (Object)null || !ArmorGalleryRotator.IsAcceptableContainer(__instance, out var _)) { return; } string useKeyName = ArmorGalleryPlugin.GetUseKeyName(); if (ArmorGalleryRotator.s_activeLinkingStand.IsChestLinked(__instance)) { __result += $"\n<color=#FF4444>[{useKeyName}] Unlink from Armor Stand</color>"; return; } ArmorGalleryRotator rotatorLinkingChest = ArmorGalleryRotator.GetRotatorLinkingChest(__instance); if ((Object)(object)rotatorLinkingChest != (Object)null && (Object)(object)rotatorLinkingChest != (Object)(object)ArmorGalleryRotator.s_activeLinkingStand) { __result += "\n<color=#FFAA00>[Chest already linked to another Armor Stand]</color>"; } else { __result += $"\n<color=#00FF00>[{useKeyName}] Link to Armor Stand</color>"; } } } [HarmonyPatch(typeof(Container), "OnDestroyed")] public static class Container_OnDestroyed_Patch { public static void Prefix(Container __instance) { if ((Object)(object)__instance == (Object)null) { return; } foreach (ArmorGalleryRotator s_allRotator in ArmorGalleryRotator.s_allRotators) { if ((Object)(object)s_allRotator != (Object)null && s_allRotator.IsChestLinked(__instance)) { s_allRotator.OnChestDestroyed(__instance); } } } } [HarmonyPatch(typeof(InventoryGui), "Update")] public static class InventoryGui_Update_Patch { public static void Postfix(InventoryGui __instance) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || !__instance.IsContainerOpen() || (Object)(object)ArmorGalleryUI.activeStand == (Object)null || (Object)(object)ArmorGalleryUI.activeContainer == (Object)null) { return; } ArmorGalleryRotator component = ((Component)ArmorGalleryUI.activeStand).GetComponent<ArmorGalleryRotator>(); if ((Object)(object)component == (Object)null) { return; } List<Container> linkedChests = component.GetLinkedChests(); if (linkedChests.Count <= 1) { return; } int num = linkedChests.IndexOf(ArmorGalleryUI.activeContainer); if (num < 0) { return; } if (Input.GetKeyDown(ArmorGalleryPlugin.configPrevChestKey.Value)) { if (num > 0) { ZInput.ResetButtonStatus("Use"); ZInput.ResetButtonStatus("JoyUse"); ArmorGalleryUI.SwitchToContainer(__instance, linkedChests[num - 1]); } } else if (Input.GetKeyDown(ArmorGalleryPlugin.configNextChestKey.Value) && num < linkedChests.Count - 1) { ZInput.ResetButtonStatus("Use"); ZInput.ResetButtonStatus("JoyUse"); ArmorGalleryUI.SwitchToContainer(__instance, linkedChests[num + 1]); } } } public static class ArmorGalleryUI { public static ArmorStand activeStand = null; public static List<GameObject> uiElements = new List<GameObject>(); public static FieldInfo currentContainerField = typeof(InventoryGui).GetField("m_currentContainer", BindingFlags.Instance | BindingFlags.NonPublic); public static FieldInfo containerGridField = typeof(InventoryGui).GetField("m_containerGrid", BindingFlags.Instance | BindingFlags.NonPublic); private static FieldInfo firstContainerUpdateField = typeof(InventoryGui).GetField("m_firstContainerUpdate", BindingFlags.Instance | BindingFlags.NonPublic); private static FieldInfo gridWidthField = typeof(InventoryGrid).GetField("m_width", BindingFlags.Instance | BindingFlags.NonPublic); private static FieldInfo gridHeightField = typeof(InventoryGrid).GetField("m_height", BindingFlags.Instance | BindingFlags.NonPublic); private static FieldInfo elem