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 VanillaInventoryPlus v1.0.1
BepInEx\plugins\VanillaInventoryPlus\VanillaInventoryPlus.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("VanillaInventoryPlus")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+ee94069e7ecc47ad74ebfc893ac760ee7342f633")] [assembly: AssemblyProduct("VanillaInventoryPlus")] [assembly: AssemblyTitle("VanillaInventoryPlus")] [assembly: AssemblyVersion("1.0.0.0")] internal sealed class ConfigurationManagerAttributes { public int? Order; } namespace VanillaInventoryPlus; internal static class NearbyStashButton { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__1_0; internal void <Create>b__1_0() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { NearbyStashManager.Run(localPlayer); } } } private static Sprite _icon; internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize) { //IL_0060: 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_006b: Expected O, but got Unknown if ((Object)(object)_icon == (Object)null) { _icon = SpriteLoader.Load("stash_nearby.png"); } ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_StashNearby", _icon, buttonWidth, buttonHeight, iconSize); ((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners(); ButtonClickedEvent onClick = toolbarButtonView.Button.onClick; object obj = <>c.<>9__1_0; if (obj == null) { UnityAction val = delegate { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { NearbyStashManager.Run(localPlayer); } }; <>c.<>9__1_0 = val; obj = (object)val; } ((UnityEvent)onClick).AddListener((UnityAction)obj); TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_stash_nearby", "$vit_stash_nearby_desc", GetHotkeyText); } private unsafe static string GetHotkeyText() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (ModConfig.NearbyStashEnableHotkey == null || !ModConfig.NearbyStashEnableHotkey.Value || ModConfig.NearbyStashHotkey == null) { return null; } KeyboardShortcut value = ModConfig.NearbyStashHotkey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0) { return null; } return ((object)(*(KeyboardShortcut*)(&value))/*cast due to .constrained prefix*/).ToString(); } } internal static class PlayerSortNameButton { private static Sprite _icon; internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown if ((Object)(object)_icon == (Object)null) { _icon = SpriteLoader.Load("sort_name.png"); } ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_PlayerSortName", _icon, buttonWidth, buttonHeight, iconSize); ((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners(); ((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick)); TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_name", "$vit_sort_name_desc"); } private static void OnClick() { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null)) { bool nextDirection = PlayerSortState.GetNextDirection(ContainerSortMode.Name, defaultAscending: true); PlayerInventorySorter.Sort(instance, ContainerSortMode.Name, nextDirection); PlayerSortState.Set(ContainerSortMode.Name, nextDirection); } } } internal static class PlayerSortTypeButton { private static Sprite _icon; internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown if ((Object)(object)_icon == (Object)null) { _icon = SpriteLoader.Load("sort_type_thin.png"); } ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_PlayerSortType", _icon, buttonWidth, buttonHeight, iconSize); ((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners(); ((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick)); TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_type", "$vit_sort_type_desc"); } private static void OnClick() { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null)) { bool nextDirection = PlayerSortState.GetNextDirection(ContainerSortMode.Type, defaultAscending: true); PlayerInventorySorter.Sort(instance, ContainerSortMode.Type, nextDirection); PlayerSortState.Set(ContainerSortMode.Type, nextDirection); } } } internal static class PlayerSortWeightButton { private static Sprite _icon; internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown if ((Object)(object)_icon == (Object)null) { _icon = SpriteLoader.Load("sort_weight.png"); } ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_PlayerSortWeight", _icon, buttonWidth, buttonHeight, iconSize); ((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners(); ((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick)); TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_weight", "$vit_sort_weight_desc"); } private static void OnClick() { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null)) { bool nextDirection = PlayerSortState.GetNextDirection(ContainerSortMode.Weight, defaultAscending: false); PlayerInventorySorter.Sort(instance, ContainerSortMode.Weight, nextDirection); PlayerSortState.Set(ContainerSortMode.Weight, nextDirection); } } } internal static class SortNameButton { private static Sprite _icon; internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown if ((Object)(object)_icon == (Object)null) { _icon = SpriteLoader.Load("sort_name.png"); } ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_SortName", _icon, buttonWidth, buttonHeight, iconSize); ((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners(); ((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick)); TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_name", "$vit_sort_name_desc"); } private static void OnClick() { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null)) { bool nextDirection = SortState.GetNextDirection(ContainerSortMode.Name, defaultAscending: true); InventorySorter.SortOpenContainer(instance, ContainerSortMode.Name, nextDirection); SortState.Set(ContainerSortMode.Name, nextDirection); } } } internal static class SortTypeButton { private static Sprite _icon; private static Sprite _thinIcon; internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize, bool useThinIcon) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown if ((Object)(object)_icon == (Object)null) { _icon = SpriteLoader.Load("sort_type.png"); } if (useThinIcon && (Object)(object)_thinIcon == (Object)null) { _thinIcon = SpriteLoader.Load("sort_type_thin.png"); } Sprite icon = ((useThinIcon && (Object)(object)_thinIcon != (Object)null) ? _thinIcon : _icon); ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_SortType", icon, buttonWidth, buttonHeight, iconSize); ((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners(); ((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick)); TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_type", "$vit_sort_type_desc"); } private static void OnClick() { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null)) { bool nextDirection = SortState.GetNextDirection(ContainerSortMode.Type, defaultAscending: true); InventorySorter.SortOpenContainer(instance, ContainerSortMode.Type, nextDirection); SortState.Set(ContainerSortMode.Type, nextDirection); } } } internal static class SortWeightButton { private static Sprite _icon; internal static void Create(GameObject template, Transform parent, float buttonWidth, float buttonHeight, float iconSize) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown if ((Object)(object)_icon == (Object)null) { _icon = SpriteLoader.Load("sort_weight.png"); } ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(template, parent, "VIT_SortWeight", _icon, buttonWidth, buttonHeight, iconSize); ((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners(); ((UnityEvent)toolbarButtonView.Button.onClick).AddListener(new UnityAction(OnClick)); TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_sort_weight", "$vit_sort_weight_desc"); } private static void OnClick() { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null)) { bool nextDirection = SortState.GetNextDirection(ContainerSortMode.Weight, defaultAscending: false); InventorySorter.SortOpenContainer(instance, ContainerSortMode.Weight, nextDirection); SortState.Set(ContainerSortMode.Weight, nextDirection); } } } internal static class StackAllButton { private static Sprite _icon; private static Sprite _thinIcon; internal static void Create(Transform source, Transform parent, float buttonWidth, float buttonHeight, float iconSize, bool useThinIcon) { //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown if ((Object)(object)source == (Object)null || (Object)(object)parent == (Object)null) { return; } Button vanillaButton = ((Component)source).GetComponent<Button>(); if (!((Object)(object)vanillaButton == (Object)null)) { if ((Object)(object)_icon == (Object)null) { _icon = SpriteLoader.Load("stack.png"); } if (useThinIcon && (Object)(object)_thinIcon == (Object)null) { _thinIcon = SpriteLoader.Load("stack_thin.png"); } Sprite icon = ((useThinIcon && (Object)(object)_thinIcon != (Object)null) ? _thinIcon : _icon); ToolbarButtonView toolbarButtonView = ToolbarButtonFactory.Create(((Component)source).gameObject, parent, "VIT_StackAll", icon, buttonWidth, buttonHeight, iconSize); ((UnityEventBase)toolbarButtonView.Button.onClick).RemoveAllListeners(); ((UnityEvent)toolbarButtonView.Button.onClick).AddListener((UnityAction)delegate { ((UnityEvent)vanillaButton.onClick).Invoke(); CompactCurrentContainer(); SortState.Clear(); }); TooltipUtility.Add(toolbarButtonView.GameObject, "$vit_stack_all", "$vit_stack_all_desc"); ((Component)source).gameObject.SetActive(false); } } private static void CompactCurrentContainer() { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { return; } Container value = Traverse.Create((object)instance).Field<Container>("m_currentContainer").Value; if ((Object)(object)value == (Object)null) { return; } Inventory inventory = value.GetInventory(); if (inventory == null) { return; } List<ItemData> list = new List<ItemData>(inventory.GetAllItems()); bool flag = false; for (int i = 0; i < list.Count; i++) { ItemData val = list[i]; if (val == null || val.m_shared == null) { continue; } int maxStackSize = val.m_shared.m_maxStackSize; if (maxStackSize <= 1 || val.m_stack >= maxStackSize) { continue; } for (int j = i + 1; j < list.Count; j++) { ItemData val2 = list[j]; if (val2 == null || val2.m_shared == null || !CanStackTogether(val, val2)) { continue; } int num = maxStackSize - val.m_stack; if (num <= 0) { break; } int num2 = Mathf.Min(num, val2.m_stack); if (num2 > 0) { val.m_stack += num2; val2.m_stack -= num2; flag = true; if (val2.m_stack <= 0) { inventory.RemoveItem(val2); list[j] = null; } } } } if (flag) { Traverse.Create((object)inventory).Method("Changed", new object[2] { true, false }).GetValue(); Traverse.Create((object)value).Method("Save", Array.Empty<object>()).GetValue(); Traverse.Create((object)instance).Method("UpdateContainer", Array.Empty<object>()).GetValue(); } } private static bool CanStackTogether(ItemData first, ItemData second) { if (first == null || second == null || first.m_shared == null || second.m_shared == null) { return false; } if (first.m_shared.m_maxStackSize <= 1 || second.m_shared.m_maxStackSize <= 1) { return false; } if (first.m_shared.m_name == second.m_shared.m_name && first.m_quality == second.m_quality) { return first.m_variant == second.m_variant; } return false; } } internal static class TakeAllButton { private static Sprite _icon; private const float BottomMargin = 12f; private const float IconPadding = 4f; internal static void Create(Transform originalTakeAll) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown if ((Object)(object)originalTakeAll == (Object)null) { return; } RectTransform component = ((Component)originalTakeAll).GetComponent<RectTransform>(); Button vanillaButton = ((Component)originalTakeAll).GetComponent<Button>(); if ((Object)(object)component == (Object)null || (Object)(object)vanillaButton == (Object)null) { return; } if ((Object)(object)_icon == (Object)null) { _icon = SpriteLoader.Load("take_all.png"); } float width = GetWidth(component, 100f); float height = GetHeight(component, 30f); GameObject val = Object.Instantiate<GameObject>(((Component)originalTakeAll).gameObject, originalTakeAll.parent); ((Object)val).name = "VIT_TakeAll"; RectTransform component2 = val.GetComponent<RectTransform>(); Button component3 = val.GetComponent<Button>(); if ((Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null) { Object.Destroy((Object)(object)val); return; } component2.sizeDelta = new Vector2(width, height); LayoutElement component4 = val.GetComponent<LayoutElement>(); if ((Object)(object)component4 != (Object)null) { component4.minWidth = width; component4.preferredWidth = width; component4.minHeight = height; component4.preferredHeight = height; component4.flexibleWidth = 0f; component4.flexibleHeight = 0f; } component2.anchorMin = new Vector2(0.5f, 0f); component2.anchorMax = new Vector2(0.5f, 0f); component2.pivot = new Vector2(0.5f, 1f); component2.anchoredPosition = new Vector2(0f, -12f); ApplyDisplayMode(val, width, height); ((UnityEventBase)component3.onClick).RemoveAllListeners(); ((UnityEvent)component3.onClick).AddListener((UnityAction)delegate { if ((Object)(object)vanillaButton != (Object)null) { ((UnityEvent)vanillaButton.onClick).Invoke(); } SortState.Clear(); }); TooltipUtility.Add(val, "$vit_take_all", "$vit_take_all_desc"); val.transform.SetAsLastSibling(); val.SetActive(true); ((Component)originalTakeAll).gameObject.SetActive(false); } private static void ApplyDisplayMode(GameObject buttonObject, float buttonWidth, float buttonHeight) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) TakeAllDisplayMode value = ModConfig.TakeAllMode.Value; TMP_Text[] componentsInChildren = buttonObject.GetComponentsInChildren<TMP_Text>(true); TMP_Text[] array; if (value == TakeAllDisplayMode.Text) { array = componentsInChildren; for (int i = 0; i < array.Length; i++) { ((Component)array[i]).gameObject.SetActive(true); } return; } array = componentsInChildren; for (int i = 0; i < array.Length; i++) { ((Component)array[i]).gameObject.SetActive(false); } GameObject val = new GameObject("Icon", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(buttonObject.transform, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = Vector2.zero; float num = Mathf.Max(8f, buttonHeight - 4f); component.sizeDelta = new Vector2(num, num); Image component2 = val.GetComponent<Image>(); component2.sprite = _icon; component2.preserveAspect = true; ((Graphic)component2).raycastTarget = false; ((Graphic)component2).color = ((ModConfig.IconColor != null) ? ModConfig.IconColor.Value : Color.white); } private static float GetWidth(RectTransform rect, float fallback) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rect != (Object)null) { Rect rect2 = rect.rect; if (((Rect)(ref rect2)).width > 1f) { rect2 = rect.rect; return ((Rect)(ref rect2)).width; } } if ((Object)(object)rect != (Object)null && rect.sizeDelta.x > 1f) { return rect.sizeDelta.x; } return fallback; } private static float GetHeight(RectTransform rect, float fallback) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rect != (Object)null) { Rect rect2 = rect.rect; if (((Rect)(ref rect2)).height > 1f) { rect2 = rect.rect; return ((Rect)(ref rect2)).height; } } if ((Object)(object)rect != (Object)null && rect.sizeDelta.y > 1f) { return rect.sizeDelta.y; } return fallback; } } internal static class ExtraSlotsCompatibility { private const string ExtraSlotsGuid = "shudnal.ExtraSlots"; private const string ExtraSlotsApiTypeName = "ExtraSlots.API"; internal static bool TryGetRegularInventoryHeight(Inventory inventory, out int height) { height = 0; if (inventory == null) { return false; } int height2 = inventory.GetHeight(); if (height2 <= 0) { return false; } if (!Chainloader.PluginInfos.TryGetValue("shudnal.ExtraSlots", out var value)) { height = height2; return true; } if (value == null || (Object)(object)value.Instance == (Object)null) { LogCompatibilityFailure("plugin instance is unavailable"); return false; } try { Type type = ((object)value.Instance).GetType().Assembly.GetType("ExtraSlots.API", throwOnError: false); if (type == null) { LogCompatibilityFailure("ExtraSlots.API was not found"); return false; } MethodInfo method = type.GetMethod("GetInventoryHeightPlayer", BindingFlags.Static | BindingFlags.Public); if (method == null) { LogCompatibilityFailure("GetInventoryHeightPlayer() was not found"); return false; } if (!(method.Invoke(null, null) is int num)) { LogCompatibilityFailure("GetInventoryHeightPlayer() returned an unexpected value"); return false; } if (num <= 0 || num > height2) { LogCompatibilityFailure("invalid player inventory height: " + num + " / full height: " + height2); return false; } height = num; return true; } catch (Exception ex) { LogCompatibilityFailure(ex.GetType().Name + ": " + ex.Message); return false; } } private static void LogCompatibilityFailure(string reason) { Plugin.Log.LogWarning((object)("Extra Slots compatibility: " + reason + ". Player inventory operation was skipped to protect extra-slot items.")); } } [HarmonyPatch(typeof(InventoryGui), "Awake")] internal static class InventoryGuiPatch { [HarmonyPostfix] [HarmonyPriority(200)] private static void Postfix(InventoryGui __instance) { InventoryUiBuilder.Build(__instance); } } internal enum ContainerSortMode { Name, Weight, Type } internal static class InventorySorter { internal static void SortOpenContainer(InventoryGui gui, ContainerSortMode mode, bool ascending) { //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)gui == (Object)null) { Plugin.Log.LogWarning((object)"Cannot sort: InventoryGui is null."); return; } Container value = Traverse.Create((object)gui).Field<Container>("m_currentContainer").Value; if ((Object)(object)value == (Object)null) { Plugin.Log.LogWarning((object)"Cannot sort: no container is open."); return; } Inventory inventory = value.GetInventory(); if (inventory == null) { Plugin.Log.LogWarning((object)"Cannot sort: container inventory is null."); return; } IEnumerable<ItemData> source = from item in inventory.GetAllItems() where item != null && item.m_shared != null select item; List<ItemData> list = mode switch { ContainerSortMode.Weight => (!ascending) ? source.OrderByDescending((ItemData item) => item.GetWeight(-1)).ThenBy<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ToList() : source.OrderBy((ItemData item) => item.GetWeight(-1)).ThenBy<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ToList(), ContainerSortMode.Type => (!ascending) ? source.OrderByDescending<ItemData, string>(GetItemTypeName, StringComparer.OrdinalIgnoreCase).ThenBy<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ToList() : source.OrderBy<ItemData, string>(GetItemTypeName, StringComparer.OrdinalIgnoreCase).ThenBy<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ToList(), _ => (!ascending) ? source.OrderByDescending<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ThenBy((ItemData item) => item.m_quality).ThenBy((ItemData item) => item.m_variant) .ToList() : source.OrderBy<ItemData, string>(GetLocalizedName, StringComparer.CurrentCultureIgnoreCase).ThenBy((ItemData item) => item.m_quality).ThenBy((ItemData item) => item.m_variant) .ToList(), }; int width = inventory.GetWidth(); if (width <= 0) { Plugin.Log.LogWarning((object)"Cannot sort: invalid inventory width."); return; } for (int num = 0; num < list.Count; num++) { int num2 = num % width; int num3 = num / width; list[num].m_gridPos = new Vector2i(num2, num3); } Traverse.Create((object)inventory).Method("Changed", new object[2] { true, false }).GetValue(); Traverse.Create((object)value).Method("Save", Array.Empty<object>()).GetValue(); Traverse.Create((object)gui).Method("UpdateContainer", new object[1] { Player.m_localPlayer }).GetValue(); Plugin.Log.LogInfo((object)("Container sorted: " + mode.ToString() + " / " + (ascending ? "ascending" : "descending") + " / " + list.Count + " items.")); } catch (Exception ex) { Plugin.Log.LogError((object)"Error while sorting container:"); Plugin.Log.LogError((object)ex); } } private static string GetLocalizedName(ItemData item) { if (item == null || item.m_shared == null) { return ""; } if (Localization.instance == null) { return item.m_shared.m_name ?? ""; } return Localization.instance.Localize(item.m_shared.m_name); } private static string GetItemTypeName(ItemData item) { if (item == null || item.m_shared == null) { return ""; } return ((object)Unsafe.As<ItemType, ItemType>(ref item.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString(); } } internal static class InventoryUiBuilder { private static bool _refreshPending; internal static void Build(InventoryGui gui) { if ((Object)(object)gui == (Object)null) { return; } Transform val = ((Component)gui).transform.Find("root/Player/Container"); Transform val2 = ((Component)gui).transform.Find("root/Player"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"Container UI was not found."); return; } Transform val3 = val.Find("StackAll"); Transform val4 = val.Find("TakeAll"); if ((Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)"Vanilla StackAll was not found."); return; } ((Component)val3).gameObject.SetActive(true); if ((Object)(object)val4 != (Object)null) { ((Component)val4).gameObject.SetActive(true); } float buttonHeight = GetButtonHeight(((Component)val3).GetComponent<RectTransform>(), 30f); float num = Mathf.Max(22f, buttonHeight - 4f); bool flag = ToolbarLayout.IsCompactHorizontalMode(); float buttonWidth = buttonHeight; float num2 = (flag ? (buttonHeight * 0.65f) : buttonHeight); float iconSize = (flag ? Mathf.Max(9f, num2 - 2f) : num); int num3 = 0; if (ModConfig.ShowSortNameButton.Value) { num3++; } if (ModConfig.ShowSortWeightButton.Value) { num3++; } if (ModConfig.ShowSortTypeButton.Value) { num3++; } if (ModConfig.ShowStackAllButton.Value) { num3++; } if (num3 > 0) { Transform transform = ToolbarLayout.Create(val, num3, buttonWidth, num2).transform; if (ModConfig.ShowSortNameButton.Value) { SortNameButton.Create(((Component)val3).gameObject, transform, buttonWidth, num2, iconSize); } if (ModConfig.ShowSortWeightButton.Value) { SortWeightButton.Create(((Component)val3).gameObject, transform, buttonWidth, num2, iconSize); } if (ModConfig.ShowSortTypeButton.Value) { SortTypeButton.Create(((Component)val3).gameObject, transform, buttonWidth, num2, iconSize, flag); } if (ModConfig.ShowStackAllButton.Value) { StackAllButton.Create(val3, transform, buttonWidth, num2, iconSize, flag); } } if (ModConfig.ShowTakeAllButton.Value && (Object)(object)val4 != (Object)null) { TakeAllButton.Create(val4); } if ((Object)(object)val2 != (Object)null) { PlayerSortToolbarBuilder.Build(((Component)val3).gameObject, val2, buttonHeight); } ApplyVanillaButtonVisibility(val3, val4); } internal static void RequestRefresh() { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null) && !_refreshPending) { _refreshPending = true; ((MonoBehaviour)instance).StartCoroutine(RefreshNextFrame(instance)); } } private static IEnumerator RefreshNextFrame(InventoryGui gui) { Cleanup(gui); yield return null; _refreshPending = false; if (!((Object)(object)gui == (Object)null)) { Build(gui); } } private static void Cleanup(InventoryGui gui) { if ((Object)(object)gui == (Object)null) { return; } Transform val = ((Component)gui).transform.Find("root/Player/Container"); Transform val2 = ((Component)gui).transform.Find("root/Player"); if ((Object)(object)val != (Object)null) { Transform stackAll = val.Find("StackAll"); Transform takeAll = val.Find("TakeAll"); ApplyVanillaButtonVisibility(stackAll, takeAll); Transform val3 = val.Find("VIT_ContainerToolbar"); if ((Object)(object)val3 != (Object)null) { Object.Destroy((Object)(object)((Component)val3).gameObject); } Transform val4 = val.Find("VIT_TakeAll"); if ((Object)(object)val4 != (Object)null) { Object.Destroy((Object)(object)((Component)val4).gameObject); } } if ((Object)(object)val2 != (Object)null) { Transform val5 = val2.Find("VIT_PlayerSortToolbar"); if ((Object)(object)val5 != (Object)null) { Object.Destroy((Object)(object)((Component)val5).gameObject); } } TooltipManager.Hide(); } private static void ApplyVanillaButtonVisibility(Transform stackAll, Transform takeAll) { bool flag = ModConfig.HideVanillaStackAllButton != null && ModConfig.HideVanillaStackAllButton.Value; bool flag2 = ModConfig.HideVanillaTakeAllButton != null && ModConfig.HideVanillaTakeAllButton.Value; if ((Object)(object)stackAll != (Object)null) { bool flag3 = ModConfig.ShowStackAllButton != null && ModConfig.ShowStackAllButton.Value; bool active = !flag && !flag3; ((Component)stackAll).gameObject.SetActive(active); } if ((Object)(object)takeAll != (Object)null) { bool flag4 = ModConfig.ShowTakeAllButton != null && ModConfig.ShowTakeAllButton.Value; bool active2 = !flag2 && !flag4; ((Component)takeAll).gameObject.SetActive(active2); } } private static float GetButtonHeight(RectTransform rect, float fallback) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rect != (Object)null) { Rect rect2 = rect.rect; if (((Rect)(ref rect2)).height > 1f) { rect2 = rect.rect; return ((Rect)(ref rect2)).height; } } if ((Object)(object)rect != (Object)null && rect.sizeDelta.y > 1f) { return rect.sizeDelta.y; } return fallback; } } internal static class LocalizationManager { private static readonly Dictionary<string, Dictionary<string, string>> _translations = new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase); private static bool _loaded; internal static string Translate(string localizationKey) { EnsureLoaded(); if (string.IsNullOrWhiteSpace(localizationKey)) { return ""; } string text = localizationKey.Trim(); if (text.StartsWith("$")) { text = text.Substring(1); } if (!_translations.TryGetValue(text, out var value)) { return localizationKey; } string currentLanguage = GetCurrentLanguage(); if (value.TryGetValue(currentLanguage, out var value2) && !string.IsNullOrWhiteSpace(value2)) { return value2; } if (value.TryGetValue("English", out var value3) && !string.IsNullOrWhiteSpace(value3)) { return value3; } return localizationKey; } private static void EnsureLoaded() { if (_loaded) { return; } _loaded = true; using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("VanillaInventoryPlus.Resources.localization.tsv")) { if (stream == null) { Plugin.Log.LogError((object)"Localization resource not found: VanillaInventoryPlus.Resources.localization.tsv"); return; } using StreamReader streamReader = new StreamReader(stream); string text = streamReader.ReadLine(); if (string.IsNullOrWhiteSpace(text)) { Plugin.Log.LogError((object)"Localization file is empty."); return; } string[] array = text.Split('\t'); if (array.Length < 2) { Plugin.Log.LogError((object)"Localization TSV has invalid header."); return; } array[0] = array[0].Trim().Trim('\ufeff'); string text2; while ((text2 = streamReader.ReadLine()) != null) { if (string.IsNullOrWhiteSpace(text2) || text2.TrimStart().StartsWith("#")) { continue; } string[] array2 = text2.Split('\t'); if (array2.Length == 0) { continue; } string text3 = array2[0].Trim(); if (string.IsNullOrWhiteSpace(text3)) { continue; } if (text3.StartsWith("$")) { text3 = text3.Substring(1); } Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); for (int i = 1; i < array.Length; i++) { string text4 = array[i].Trim(); if (!string.IsNullOrWhiteSpace(text4)) { string value = ((i < array2.Length) ? array2[i].Trim() : ""); dictionary[text4] = value; } } _translations[text3] = dictionary; } } Plugin.Log.LogInfo((object)("Localization file loaded. " + _translations.Count + " keys.")); } private static string GetCurrentLanguage() { try { if (Localization.instance == null) { return "English"; } string value = Traverse.Create((object)Localization.instance).Method("GetSelectedLanguage", Array.Empty<object>()).GetValue<string>(); if (string.IsNullOrWhiteSpace(value)) { return "English"; } return value; } catch { return "English"; } } } internal enum ToolbarSide { RightTop, LeftTop, LeftDown, DownLeft, DownRight } internal enum PlayerToolbarSide { DownLeft, DownRight } internal enum TakeAllDisplayMode { Icon, Text } internal static class ModConfig { internal static ConfigEntry<Color> IconColor; internal static ConfigEntry<bool> HideVanillaStackAllButton; internal static ConfigEntry<bool> HideVanillaTakeAllButton; internal static ConfigEntry<bool> ShowSortNameButton; internal static ConfigEntry<bool> ShowSortWeightButton; internal static ConfigEntry<bool> ShowSortTypeButton; internal static ConfigEntry<bool> ShowStackAllButton; internal static ConfigEntry<bool> ShowTakeAllButton; internal static ConfigEntry<bool> ShowPlayerSortNameButton; internal static ConfigEntry<bool> ShowPlayerSortWeightButton; internal static ConfigEntry<bool> ShowPlayerSortTypeButton; internal static ConfigEntry<bool> ShowNearbyStashButton; internal static ConfigEntry<PlayerToolbarSide> PlayerInventoryToolbarSide; internal static ConfigEntry<TakeAllDisplayMode> TakeAllMode; internal static ConfigEntry<ToolbarSide> ContainerToolbarSide; internal static ConfigEntry<bool> ContainerToolbarSmallHorizontalButtons; internal static ConfigEntry<float> ContainerToolbarSpacing; internal static ConfigEntry<float> ContainerToolbarOffsetX; internal static ConfigEntry<float> ContainerToolbarOffsetY; internal static ConfigEntry<float> NearbyStashRadius; internal static ConfigEntry<bool> NearbyStashPlayerBuiltOnly; internal static ConfigEntry<bool> NearbyStashProtectHotbar; internal static ConfigEntry<bool> NearbyStashEnableHotkey; internal static ConfigEntry<KeyboardShortcut> NearbyStashHotkey; internal static void Bind(ConfigFile config) { //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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Expected O, but got Unknown //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Expected O, but got Unknown //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Expected O, but got Unknown //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Expected O, but got Unknown //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Expected O, but got Unknown //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Expected O, but got Unknown //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Expected O, but got Unknown //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Expected O, but got Unknown //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Expected O, but got Unknown //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Expected O, but got Unknown //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Expected O, but got Unknown //IL_046b: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Expected O, but got Unknown //IL_04a7: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Expected O, but got Unknown //IL_04d1: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_0501: Expected O, but got Unknown //IL_0533: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Expected O, but got Unknown //IL_056f: Unknown result type (might be due to invalid IL or missing references) //IL_0579: Expected O, but got Unknown //IL_05bd: Unknown result type (might be due to invalid IL or missing references) //IL_05c7: Expected O, but got Unknown //IL_05f9: Unknown result type (might be due to invalid IL or missing references) //IL_0603: Expected O, but got Unknown IconColor = config.Bind<Color>("Appearance", "IconColor", Color32.op_Implicit(new Color32(byte.MaxValue, (byte)161, (byte)61, byte.MaxValue)), new ConfigDescription("Color tint for all custom icons.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 10 } })); HideVanillaStackAllButton = config.Bind<bool>("Buttons", "HideVanillaStackAll", false, new ConfigDescription("Hide the original vanilla Stack All button.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 70 } })); HideVanillaTakeAllButton = config.Bind<bool>("Buttons", "HideVanillaTakeAll", false, new ConfigDescription("Hide the original vanilla Take All button.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 60 } })); ShowStackAllButton = config.Bind<bool>("Buttons", "ShowCustomStackAll", true, new ConfigDescription("Replace the vanilla Stack All button with the custom toolbar button.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 50 } })); ShowTakeAllButton = config.Bind<bool>("Buttons", "ShowCustomTakeAll", true, new ConfigDescription("Replace the vanilla Take All button with the custom button.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 40 } })); ShowSortNameButton = config.Bind<bool>("Buttons", "ShowSortName", true, new ConfigDescription("Show the Sort by Name button in the container toolbar.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 30 } })); ShowSortTypeButton = config.Bind<bool>("Buttons", "ShowSortType", true, new ConfigDescription("Show the Sort by Type button in the container toolbar.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 20 } })); ShowSortWeightButton = config.Bind<bool>("Buttons", "ShowSortWeight", true, new ConfigDescription("Show the Sort by Weight button in the container toolbar.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 10 } })); ShowPlayerSortNameButton = config.Bind<bool>("Player Inventory Buttons", "ShowSortName", true, new ConfigDescription("Show the Sort by Name button in the player inventory.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 50 } })); ShowPlayerSortWeightButton = config.Bind<bool>("Player Inventory Buttons", "ShowSortWeight", true, new ConfigDescription("Show the Sort by Weight button in the player inventory.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 40 } })); ShowPlayerSortTypeButton = config.Bind<bool>("Player Inventory Buttons", "ShowSortType", true, new ConfigDescription("Show the Sort by Type button in the player inventory.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 30 } })); ShowNearbyStashButton = config.Bind<bool>("Player Inventory Buttons", "ShowNearbyStash", true, new ConfigDescription("Show the Nearby Stash button in the player inventory.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 20 } })); PlayerInventoryToolbarSide = config.Bind<PlayerToolbarSide>("Player Inventory Buttons", "Side", PlayerToolbarSide.DownRight, new ConfigDescription("Position of the player inventory toolbar.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 10 } })); ContainerToolbarOffsetX = config.Bind<float>("Container Inventory Toolbar", "OffsetX", 0f, new ConfigDescription("Additional horizontal toolbar offset in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-80f, 80f), new object[1] { new ConfigurationManagerAttributes { Order = 50 } })); ContainerToolbarOffsetY = config.Bind<float>("Container Inventory Toolbar", "OffsetY", 0f, new ConfigDescription("Additional vertical toolbar offset in pixels.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-80f, 80f), new object[1] { new ConfigurationManagerAttributes { Order = 40 } })); ContainerToolbarSpacing = config.Bind<float>("Container Inventory Toolbar", "Spacing", 2f, new ConfigDescription("Distance between enabled toolbar buttons.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 30 } })); ContainerToolbarSmallHorizontalButtons = config.Bind<bool>("Container Inventory Toolbar", "SmallHorizontalButtons", true, new ConfigDescription("Use compact rectangular buttons for DownLeft and DownRight positions only.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 20 } })); ContainerToolbarSide = config.Bind<ToolbarSide>("Container Inventory Toolbar", "Side", ToolbarSide.DownRight, new ConfigDescription("Position of the container toolbar.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 10 } })); NearbyStashEnableHotkey = config.Bind<bool>("Nearby Stash", "EnableHotkey", true, new ConfigDescription("Enable the hotkey for stashing matching items to nearby chests.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 50 } })); NearbyStashHotkey = config.Bind<KeyboardShortcut>("Nearby Stash", "Hotkey", new KeyboardShortcut((KeyCode)115, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new ConfigDescription("Hotkey for stashing matching items to nearby chests.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 40 } })); NearbyStashPlayerBuiltOnly = config.Bind<bool>("Nearby Stash", "PlayerBuiltOnly", true, new ConfigDescription("Only use chests placed by players.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 30 } })); NearbyStashProtectHotbar = config.Bind<bool>("Nearby Stash", "ProtectHotbar", false, new ConfigDescription("When enabled, do not move items from the first inventory row.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 20 } })); NearbyStashRadius = config.Bind<float>("Nearby Stash", "Radius", 10f, new ConfigDescription("Search radius for nearby chests in meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), new object[1] { new ConfigurationManagerAttributes { Order = 10 } })); TakeAllMode = config.Bind<TakeAllDisplayMode>("Take All", "DisplayMode", TakeAllDisplayMode.Icon, new ConfigDescription("Display the custom Take All button as an icon or as vanilla text.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 10 } })); RegisterUiRefreshEvents(); } private static void RegisterUiRefreshEvents() { IconColor.SettingChanged += OnUiSettingChanged; HideVanillaStackAllButton.SettingChanged += OnUiSettingChanged; HideVanillaTakeAllButton.SettingChanged += OnUiSettingChanged; ShowSortNameButton.SettingChanged += OnUiSettingChanged; ShowSortWeightButton.SettingChanged += OnUiSettingChanged; ShowSortTypeButton.SettingChanged += OnUiSettingChanged; ShowStackAllButton.SettingChanged += OnUiSettingChanged; ShowTakeAllButton.SettingChanged += OnUiSettingChanged; ShowPlayerSortNameButton.SettingChanged += OnUiSettingChanged; ShowPlayerSortWeightButton.SettingChanged += OnUiSettingChanged; ShowPlayerSortTypeButton.SettingChanged += OnUiSettingChanged; ShowNearbyStashButton.SettingChanged += OnUiSettingChanged; PlayerInventoryToolbarSide.SettingChanged += OnUiSettingChanged; ContainerToolbarSide.SettingChanged += OnUiSettingChanged; ContainerToolbarSpacing.SettingChanged += OnUiSettingChanged; ContainerToolbarSmallHorizontalButtons.SettingChanged += OnUiSettingChanged; ContainerToolbarOffsetX.SettingChanged += OnUiSettingChanged; ContainerToolbarOffsetY.SettingChanged += OnUiSettingChanged; TakeAllMode.SettingChanged += OnUiSettingChanged; } private static void OnUiSettingChanged(object sender, EventArgs args) { InventoryUiBuilder.RequestRefresh(); } } internal static class NearbyStashManager { private static Container _currentContainer; private static bool _running; private static bool _receivedResponse; private static int _movedItems; private const float ResponseTimeout = 2f; internal static void Run(Player player) { if (!((Object)(object)player == (Object)null) && !_running) { float radius = Mathf.Max(0.5f, ModConfig.NearbyStashRadius.Value); List<Container> list = FindNearbyContainers(player, radius); if (list.Count == 0) { ShowMessage(player, "$vit_stash_no_chests"); } else { ((MonoBehaviour)player).StartCoroutine(ProcessContainers(player, list)); } } } private static List<Container> FindNearbyContainers(Player player, float radius) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) Vector3 playerPosition = ((Component)player).transform.position; Container[] array = Object.FindObjectsByType<Container>((FindObjectsInactive)0, (FindObjectsSortMode)0); List<Container> list = new List<Container>(); Container[] array2 = array; foreach (Container val in array2) { if (IsValidContainer(val, player, playerPosition, radius)) { list.Add(val); } } return list.OrderBy((Container container) => Vector3.SqrMagnitude(((Component)container).transform.position - playerPosition)).ToList(); } private static bool IsValidContainer(Container container, Player player, Vector3 playerPosition, float radius) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)container == (Object)null || (Object)(object)((Component)container).transform == (Object)null) { return false; } if (Vector3.SqrMagnitude(((Component)container).transform.position - playerPosition) > radius * radius) { return false; } if (container.GetInventory() == null) { return false; } ZNetView nView = GetNView(container); if ((Object)(object)nView == (Object)null || !nView.IsValid()) { return false; } if ((Object)(object)container.m_wagon != (Object)null) { return false; } if ((Object)(object)((Component)container).GetComponentInParent<Ship>() != (Object)null) { return false; } Piece componentInParent = ((Component)container).GetComponentInParent<Piece>(); if ((Object)(object)componentInParent == (Object)null) { return false; } if (ModConfig.NearbyStashPlayerBuiltOnly.Value && !componentInParent.IsPlacedByPlayer()) { return false; } if (container.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false)) { return false; } try { if (!Traverse.Create((object)container).Method("CheckAccess", new object[1] { player.GetPlayerID() }).GetValue<bool>()) { return false; } } catch { return false; } return true; } private static IEnumerator ProcessContainers(Player player, List<Container> containers) { _running = true; _movedItems = 0; foreach (Container container in containers) { if (!((Object)(object)container == (Object)null) && HasAnythingToStack(container, player)) { _currentContainer = container; _receivedResponse = false; Plugin.Log.LogInfo((object)("Nearby stash: requesting " + ((Object)container).name)); container.StackAll(); float timer = 0f; while (!_receivedResponse && timer < 2f) { timer += Time.unscaledDeltaTime; yield return null; } if (!_receivedResponse) { Plugin.Log.LogWarning((object)("Nearby stash timeout: " + ((Object)container).name)); } yield return null; } } _currentContainer = null; _running = false; if (_movedItems > 0) { string text = string.Format(LocalizationManager.Translate("$vit_stash_moved"), _movedItems); ShowRawMessage(player, text); } else { ShowMessage(player, "$vit_stash_nothing"); } } private static bool HasAnythingToStack(Container container, Player player) { if ((Object)(object)container == (Object)null || (Object)(object)player == (Object)null) { return false; } Inventory inventory = container.GetInventory(); if (inventory == null) { return false; } if (!TryGetPlayerInventoryArea(player, out var inventory2, out var width, out var regularHeight)) { return false; } foreach (ItemData allItem in inventory2.GetAllItems()) { if (CanMoveItem(allItem, player, width, regularHeight) && inventory.ContainsItemByName(allItem.m_shared.m_name)) { return true; } } return false; } private static bool CanMoveItem(ItemData item, Player player, int inventoryWidth, int regularHeight) { if (item == null || item.m_shared == null) { return false; } int x = item.m_gridPos.x; int y = item.m_gridPos.y; if (x < 0 || x >= inventoryWidth || y < 0 || y >= regularHeight) { return false; } if ((Object)(object)player != (Object)null && ((Humanoid)player).IsItemEquiped(item)) { return false; } if (ModConfig.NearbyStashProtectHotbar.Value && y == 0) { return false; } return true; } private static bool TryGetPlayerInventoryArea(Player player, out Inventory inventory, out int width, out int regularHeight) { inventory = null; width = 0; regularHeight = 0; if ((Object)(object)player == (Object)null) { return false; } inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return false; } width = inventory.GetWidth(); if (width <= 0) { return false; } if (!ExtraSlotsCompatibility.TryGetRegularInventoryHeight(inventory, out regularHeight)) { return false; } if (regularHeight <= 0) { return false; } return true; } internal static bool IsCurrentRequest(Container container) { if (_running && (Object)(object)_currentContainer != (Object)null) { return (Object)(object)container == (Object)(object)_currentContainer; } return false; } internal static bool TryHandleStackResponse(Container container, bool granted) { if (!IsCurrentRequest(container)) { return false; } try { if (!granted) { Plugin.Log.LogInfo((object)("Nearby stash denied: " + ((Object)container).name)); return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return true; } ZNetView nView = GetNView(container); if ((Object)(object)nView == (Object)null || !nView.IsValid()) { Plugin.Log.LogWarning((object)("Nearby stash: invalid ZNetView for " + ((Object)container).name)); return true; } if (!nView.IsOwner()) { nView.ClaimOwnership(); } if (!nView.IsOwner()) { Plugin.Log.LogWarning((object)("Nearby stash: ownership failed for " + ((Object)container).name)); return true; } int num = StackMatching(container, localPlayer); if (num > 0) { _movedItems += num; Plugin.Log.LogInfo((object)("Nearby stash: moved " + num + " to " + ((Object)container).name)); } return true; } catch (Exception ex) { Plugin.Log.LogError((object)("Nearby stash response failed for " + ((Object)container).name + ": " + ex)); return true; } finally { _receivedResponse = true; } } private static int StackMatching(Container container, Player player) { if ((Object)(object)container == (Object)null || (Object)(object)player == (Object)null) { return 0; } ZNetView nView = GetNView(container); if ((Object)(object)nView == (Object)null || !nView.IsValid() || !nView.IsOwner()) { return 0; } Inventory inventory = container.GetInventory(); if (inventory == null) { return 0; } if (!TryGetPlayerInventoryArea(player, out var inventory2, out var width, out var regularHeight)) { return 0; } List<ItemData> list = new List<ItemData>(inventory2.GetAllItems()); int num = 0; foreach (ItemData item in list) { if (CanMoveItem(item, player, width, regularHeight) && inventory.ContainsItemByName(item.m_shared.m_name)) { int stack = item.m_stack; int num2; if (inventory.AddItem(item)) { inventory2.RemoveItem(item); num2 = stack; } else { num2 = stack - item.m_stack; } if (num2 > 0) { num += num2; } } } if (num <= 0) { return 0; } MarkInventoryChanged(inventory); MarkInventoryChanged(inventory2); SaveContainer(container); return num; } private static ZNetView GetNView(Container container) { if ((Object)(object)container == (Object)null) { return null; } try { ZNetView value = Traverse.Create((object)container).Field<ZNetView>("m_nview").Value; if ((Object)(object)value != (Object)null) { return value; } } catch { } return ((Component)container).GetComponent<ZNetView>(); } private static void MarkInventoryChanged(Inventory inventory) { if (inventory != null) { Traverse.Create((object)inventory).Method("Changed", new object[2] { false, false }).GetValue(); } } private static void SaveContainer(Container container) { if (!((Object)(object)container == (Object)null)) { Traverse.Create((object)container).Method("Save", Array.Empty<object>()).GetValue(); } } private static void ShowMessage(Player player, string key) { ShowRawMessage(player, LocalizationManager.Translate(key)); } private static void ShowRawMessage(Player player, string text) { if (!((Object)(object)player == (Object)null) && !string.IsNullOrWhiteSpace(text)) { ((Character)player).Message((MessageType)2, text, 0, (Sprite)null, false); } } } [HarmonyPatch(typeof(Container), "RPC_StackResponse")] internal static class ContainerStackResponsePatch { [HarmonyPrefix] private static bool Prefix(Container __instance, bool granted) { if (!NearbyStashManager.TryHandleStackResponse(__instance, granted)) { return true; } return false; } } internal static class PlayerInventorySorter { internal static void Sort(InventoryGui gui, ContainerSortMode mode, bool ascending) { //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gui == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (inventory == null) { return; } int width = inventory.GetWidth(); if (width <= 0 || !ExtraSlotsCompatibility.TryGetRegularInventoryHeight(inventory, out var regularHeight) || regularHeight <= 1) { return; } List<ItemData> list = new List<ItemData>(inventory.GetAllItems()); List<ItemData> list2 = list.Where((ItemData item) => IsInsideSortableArea(item, width, regularHeight)).ToList(); if (list2.Count == 0) { return; } List<Vector2i> list3 = BuildAvailableSlots(list, list2, width, regularHeight); if (list3.Count < list2.Count) { Plugin.Log.LogWarning((object)"Player inventory sorting aborted: not enough regular inventory cells."); return; } CompactStacks(inventory, list2); List<ItemData> list4 = (mode switch { ContainerSortMode.Weight => ascending ? list2.OrderBy((ItemData item) => item.GetWeight(-1)).ThenBy(GetLocalizedName) : list2.OrderByDescending((ItemData item) => item.GetWeight(-1)).ThenBy(GetLocalizedName), ContainerSortMode.Type => ascending ? list2.OrderBy(GetItemType).ThenBy(GetLocalizedName) : list2.OrderByDescending(GetItemType).ThenBy(GetLocalizedName), _ => ascending ? list2.OrderBy(GetLocalizedName).ThenBy((ItemData item) => item.m_quality).ThenBy((ItemData item) => item.m_variant) : list2.OrderByDescending(GetLocalizedName).ThenBy((ItemData item) => item.m_quality).ThenBy((ItemData item) => item.m_variant), }).ToList(); for (int num = 0; num < list4.Count; num++) { list4[num].m_gridPos = list3[num]; } Traverse.Create((object)inventory).Method("Changed", new object[2] { true, false }).GetValue(); Traverse.Create((object)gui).Method("UpdateInventory", new object[1] { localPlayer }).GetValue(); } private static bool IsInsideSortableArea(ItemData item, int width, int regularHeight) { if (item == null || item.m_shared == null) { return false; } int x = item.m_gridPos.x; int y = item.m_gridPos.y; if (x < 0 || x >= width) { return false; } if (y <= 0) { return false; } if (y >= regularHeight) { return false; } return true; } private static List<Vector2i> BuildAvailableSlots(List<ItemData> allItems, List<ItemData> sortableItems, int width, int regularHeight) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) HashSet<ItemData> hashSet = new HashSet<ItemData>(sortableItems); HashSet<int> hashSet2 = new HashSet<int>(); foreach (ItemData allItem in allItems) { if (allItem != null && !hashSet.Contains(allItem)) { int x = allItem.m_gridPos.x; int y = allItem.m_gridPos.y; if (x >= 0 && x < width && y > 0 && y < regularHeight) { int item = y * width + x; hashSet2.Add(item); } } } List<Vector2i> list = new List<Vector2i>(); for (int i = 1; i < regularHeight; i++) { for (int j = 0; j < width; j++) { int item2 = i * width + j; if (!hashSet2.Contains(item2)) { list.Add(new Vector2i(j, i)); } } } return list; } private static void CompactStacks(Inventory inventory, List<ItemData> items) { if (inventory == null || items == null || items.Count == 0) { return; } for (int i = 0; i < items.Count; i++) { ItemData val = items[i]; if (val == null || val.m_shared == null) { continue; } int maxStackSize = val.m_shared.m_maxStackSize; if (maxStackSize <= 1 || val.m_stack >= maxStackSize) { continue; } for (int j = i + 1; j < items.Count; j++) { ItemData val2 = items[j]; if (!CanStackTogether(val, val2)) { continue; } int num = maxStackSize - val.m_stack; if (num <= 0) { break; } int num2 = Math.Min(num, val2.m_stack); if (num2 > 0) { val.m_stack += num2; val2.m_stack -= num2; if (val2.m_stack <= 0) { inventory.RemoveItem(val2); items.RemoveAt(j); j--; } } } } } private static bool CanStackTogether(ItemData first, ItemData second) { if (first == null || second == null || first.m_shared == null || second.m_shared == null) { return false; } if (first.m_shared.m_maxStackSize <= 1 || second.m_shared.m_maxStackSize <= 1) { return false; } if (first.m_shared.m_name == second.m_shared.m_name && first.m_quality == second.m_quality && first.m_variant == second.m_variant) { return first.m_shared.m_maxStackSize == second.m_shared.m_maxStackSize; } return false; } private static string GetLocalizedName(ItemData item) { if (item == null || item.m_shared == null) { return ""; } if (Localization.instance == null) { return item.m_shared.m_name ?? ""; } return Localization.instance.Localize(item.m_shared.m_name); } private static string GetItemType(ItemData item) { if (item == null || item.m_shared == null) { return ""; } return ((object)Unsafe.As<ItemType, ItemType>(ref item.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString(); } } internal static class PlayerSortState { private static ContainerSortMode? _activeMode; private static bool _ascending; internal static bool GetNextDirection(ContainerSortMode mode, bool defaultAscending) { if (_activeMode == mode) { return !_ascending; } return defaultAscending; } internal static void Set(ContainerSortMode mode, bool ascending) { _activeMode = mode; _ascending = ascending; } internal static void Clear() { _activeMode = null; } } internal static class PlayerSortToolbarBuilder { private const float Spacing = 2f; internal static void Build(GameObject buttonTemplate, Transform playerTransform, float standardButtonSize) { if ((Object)(object)buttonTemplate == (Object)null || (Object)(object)playerTransform == (Object)null) { return; } bool flag = ModConfig.ShowPlayerSortNameButton != null && ModConfig.ShowPlayerSortNameButton.Value; bool flag2 = ModConfig.ShowPlayerSortWeightButton != null && ModConfig.ShowPlayerSortWeightButton.Value; bool flag3 = ModConfig.ShowPlayerSortTypeButton != null && ModConfig.ShowPlayerSortTypeButton.Value; bool flag4 = ModConfig.ShowNearbyStashButton != null && ModConfig.ShowNearbyStashButton.Value; int num = 0; if (flag) { num++; } if (flag2) { num++; } if (flag3) { num++; } if (flag4) { num++; } if (num != 0) { float num2 = standardButtonSize * 0.65f; float iconSize = Mathf.Max(9f, num2 - 2f); float totalWidth = standardButtonSize * (float)num + 2f * (float)(num - 1); Transform transform = PlayerSortToolbarLayout.Create(playerTransform, totalWidth, num2, 2f).transform; if (flag) { PlayerSortNameButton.Create(buttonTemplate, transform, standardButtonSize, num2, iconSize); } if (flag2) { PlayerSortWeightButton.Create(buttonTemplate, transform, standardButtonSize, num2, iconSize); } if (flag3) { PlayerSortTypeButton.Create(buttonTemplate, transform, standardButtonSize, num2, iconSize); } if (flag4) { NearbyStashButton.Create(buttonTemplate, transform, standardButtonSize, num2, iconSize); } } } } [BepInPlugin("dellarion.valheim.vanillainventoryplus", "Vanilla Inventory Plus", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "dellarion.valheim.vanillainventoryplus"; public const string PluginName = "Vanilla Inventory Plus"; public const string PluginVersion = "1.0.1"; internal static ManualLogSource Log; private Harmony _harmony; private void Awake() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ModConfig.Bind(((BaseUnityPlugin)this).Config); _harmony = new Harmony("dellarion.valheim.vanillainventoryplus"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Vanilla Inventory Plus 1.0.1 loaded!"); } private void Update() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (ModConfig.NearbyStashEnableHotkey == null || ModConfig.NearbyStashHotkey == null || !ModConfig.NearbyStashEnableHotkey.Value) { return; } KeyboardShortcut value = ModConfig.NearbyStashHotkey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { NearbyStashManager.Run(localPlayer); } } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class SortState { private static ContainerSortMode? _activeMode; private static bool _ascending; internal static bool GetNextDirection(ContainerSortMode mode, bool defaultAscending) { if (_activeMode == mode) { return !_ascending; } return defaultAscending; } internal static void Set(ContainerSortMode mode, bool ascending) { _activeMode = mode; _ascending = ascending; } internal static void Clear() { _activeMode = null; } } internal static class SpriteLoader { internal static Sprite Load(string fileName) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) string text = "VanillaInventoryPlus.Resources." + fileName; using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text); if (stream == null) { Plugin.Log.LogError((object)("Icon resource not found: " + text)); return null; } byte[] array; using (BinaryReader binaryReader = new BinaryReader(stream)) { array = binaryReader.ReadBytes((int)stream.Length); } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ((Object)val).name = fileName; if (!ImageConversion.LoadImage(val, array, false)) { Plugin.Log.LogError((object)("Failed to load icon: " + fileName)); Object.Destroy((Object)(object)val); return null; } ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = fileName; return obj; } } internal static class TooltipManager { private const float CursorOffsetX = 18f; private const float CursorOffsetY = -18f; private const float MaxWidth = 360f; private const float MinWidth = 120f; private const float PaddingX = 12f; private const float PaddingY = 8f; private const float LineSpacing = 4f; private const float MinBodyFontSize = 16f; private const float MinHotkeyFontSize = 14f; private static readonly Color TitleColor = Color32.op_Implicit(new Color32(byte.MaxValue, (byte)161, (byte)61, byte.MaxValue)); private static GameObject _root; private static RectTransform _rect; private static Canvas _canvas; private static RectTransform _canvasRect; private static TMP_Text _titleText; private static TMP_Text _bodyText; private static TMP_Text _hotkeyText; internal static void EnsureExists(GameObject source, TMP_Text template) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return; } Canvas componentInParent = source.GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent == (Object)null) { return; } if ((Object)(object)_root != (Object)null && (Object)(object)_canvas == (Object)(object)componentInParent) { ApplyTextStyle(template); return; } if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _canvas = componentInParent; Transform transform = ((Component)componentInParent).transform; _canvasRect = (RectTransform)(object)((transform is RectTransform) ? transform : null); _root = new GameObject("VIT_Tooltip", new Type[3] { typeof(RectTransform), typeof(Image), typeof(TooltipCursorFollower) }); _root.transform.SetParent(((Component)componentInParent).transform, false); _rect = _root.GetComponent<RectTransform>(); _rect.anchorMin = new Vector2(0.5f, 0.5f); _rect.anchorMax = new Vector2(0.5f, 0.5f); _rect.pivot = new Vector2(0f, 1f); Image component = _root.GetComponent<Image>(); ((Graphic)component).color = new Color(0.05f, 0.05f, 0.05f, 0.96f); ((Graphic)component).raycastTarget = false; _titleText = CreateText("Title"); _bodyText = CreateText("Body"); _hotkeyText = CreateText("Hotkey"); ApplyTextStyle(template); _root.SetActive(false); } internal static void Show(string localizationKey) { Show(localizationKey, null, null); } internal static void Show(string titleKey, string descriptionKey, string hotkey) { if (!((Object)(object)_root == (Object)null)) { string text = Translate(titleKey); string text2 = Translate(descriptionKey); string text3 = string.Empty; if (!string.IsNullOrWhiteSpace(hotkey)) { string text4 = Translate("$vit_hotkey"); text3 = "\n" + text4 + ": <color=#FFA13D>" + hotkey + "</color>"; } _titleText.text = text; _bodyText.text = text2; _hotkeyText.text = text3; ((Component)_titleText).gameObject.SetActive(!string.IsNullOrWhiteSpace(text)); ((Component)_bodyText).gameObject.SetActive(!string.IsNullOrWhiteSpace(text2)); ((Component)_hotkeyText).gameObject.SetActive(!string.IsNullOrWhiteSpace(text3)); _root.SetActive(true); _root.transform.SetAsLastSibling(); RebuildLayout(); UpdatePosition(); } } internal static void Hide() { if ((Object)(object)_root != (Object)null) { _root.SetActive(false); } } internal static void UpdatePosition() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root == (Object)null) && _root.activeSelf && !((Object)(object)_rect == (Object)null) && !((Object)(object)_canvasRect == (Object)null)) { Camera val = (((int)_canvas.renderMode == 0) ? null : _canvas.worldCamera); Vector2 val2 = default(Vector2); if (RectTransformUtility.ScreenPointToLocalPointInRectangle(_canvasRect, Vector2.op_Implicit(Input.mousePosition), val, ref val2)) { Vector2 val3 = val2 + new Vector2(18f, -18f); Rect rect = _canvasRect.rect; float x = _rect.sizeDelta.x; float y = _rect.sizeDelta.y; val3.x = Mathf.Clamp(val3.x, ((Rect)(ref rect)).xMin, ((Rect)(ref rect)).xMax - x); val3.y = Mathf.Clamp(val3.y, ((Rect)(ref rect)).yMin + y, ((Rect)(ref rect)).yMax); _rect.anchoredPosition = val3; } } } private static TMP_Text CreateText(string objectName) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(objectName, new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val.transform.SetParent(_root.transform, false); TMP_Text component = val.GetComponent<TMP_Text>(); component.alignment = (TextAlignmentOptions)257; component.textWrappingMode = (TextWrappingModes)1; component.overflowMode = (TextOverflowModes)0; ((Graphic)component).raycastTarget = false; component.richText = true; return component; } private static void ApplyTextStyle(TMP_Text template) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) float num = 16f; if ((Object)(object)template != (Object)null) { if ((Object)(object)template.font != (Object)null) { _titleText.font = template.font; _bodyText.font = template.font; _hotkeyText.font = template.font; } num = Mathf.Max(16f, template.fontSize); } _titleText.fontSize = num + 1f; _titleText.fontStyle = (FontStyles)1; ((Graphic)_titleText).color = TitleColor; _bodyText.fontSize = num; _bodyText.fontStyle = (FontStyles)0; ((Graphic)_bodyText).color = Color.white; _hotkeyText.fontSize = Mathf.Max(14f, num - 1f); _hotkeyText.fontStyle = (FontStyles)0; ((Graphic)_hotkeyText).color = Color.white; } private static void RebuildLayout() { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) float num = 336f; float num2 = 96f; num2 = Mathf.Max(num2, GetPreferredWidth(_titleText, num)); num2 = Mathf.Max(num2, GetPreferredWidth(_bodyText, num)); num2 = Mathf.Max(num2, GetPreferredWidth(_hotkeyText, num)); num2 = Mathf.Min(num2, num); float preferredHeight = GetPreferredHeight(_titleText, num2); float preferredHeight2 = GetPreferredHeight(_bodyText, num2); float preferredHeight3 = GetPreferredHeight(_hotkeyText, num2); int num3 = 0; if (((Component)_titleText).gameObject.activeSelf) { num3++; } if (((Component)_bodyText).gameObject.activeSelf) { num3++; } if (((Component)_hotkeyText).gameObject.activeSelf) { num3++; } float num4 = (float)Mathf.Max(0, num3 - 1) * 4f; float num5 = 16f + preferredHeight + preferredHeight2 + preferredHeight3 + num4; _rect.sizeDelta = new Vector2(num2 + 24f, num5); float y = -8f; PositionText(_titleText, num2, preferredHeight, ref y); PositionText(_bodyText, num2, preferredHeight2, ref y); PositionText(_hotkeyText, num2, preferredHeight3, ref y); } private static void PositionText(TMP_Text text, float width, float height, ref float y) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)text == (Object)null) && ((Component)text).gameObject.activeSelf) { RectTransform rectTransform = text.rectTransform; rectTransform.anchorMin = new Vector2(0f, 1f); rectTransform.anchorMax = new Vector2(0f, 1f); rectTransform.pivot = new Vector2(0f, 1f); rectTransform.anchoredPosition = new Vector2(12f, y); rectTransform.sizeDelta = new Vector2(width, height); y -= height + 4f; } } private static float GetPreferredWidth(TMP_Text text, float maxWidth) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)text == (Object)null || !((Component)text).gameObject.activeSelf) { return 0f; } return text.GetPreferredValues(text.text, maxWidth, 0f).x; } private static float GetPreferredHeight(TMP_Text text, float width) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)text == (Object)null || !((Component)text).gameObject.activeSelf) { return 0f; } return text.GetPreferredValues(text.text, width, 0f).y; } private static string Translate(string localizationKey) { if (string.IsNullOrWhiteSpace(localizationKey)) { return string.Empty; } return LocalizationManager.Translate(localizationKey); } } internal sealed class TooltipCursorFollower : MonoBehaviour { private void Update() { TooltipManager.UpdatePosition(); } } internal sealed class ButtonTooltip : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { private string _titleKey; private string _descriptionKey; private Func<string> _hotkeyProvider; internal void Setup(string titleKey, string descriptionKey = null, Func<string> hotkeyProvider = null) { _titleKey = titleKey; _descriptionKey = descriptionKey; _hotkeyProvider = hotkeyProvider; TMP_Text componentInChildren = ((Component)this).GetComponentInChildren<TMP_Text>(true); TooltipManager.EnsureExists(((Component)this).gameObject, componentInChildren); } public void OnPointerEnter(PointerEventData eventData) { string hotkey = ((_hotkeyProvider != null) ? _hotkeyProvider() : null); TooltipManager.Show(_titleKey, _descriptionKey, hotkey); } public void OnPointerExit(PointerEventData eventData) { TooltipManager.Hide(); } private void OnDisable() { TooltipManager.Hide(); } } internal static class PlayerSortToolbarLayout { private const float VerticalOffset = -6f; internal static GameObject Create(Transform parent, float totalWidth, float toolbarHeight, float spacing) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown GameObject val = new GameObject("VIT_PlayerSortToolbar", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(PlayerToolbarGridFollower) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.sizeDelta = new Vector2(totalWidth, toolbarHeight); HorizontalLayoutGroup component2 = val.GetComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = spacing; ((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false; val.GetComponent<PlayerToolbarGridFollower>().Setup(component, ((Component)parent).GetComponent<RectTransform>(), ModConfig.PlayerInventoryToolbarSide.Value, -6f); val.transform.SetAsLastSibling(); return val; } } internal sealed class PlayerToolbarGridFollower : MonoBehaviour { private RectTransform _toolbarRect; private RectTransform _parentRect; private InventoryGrid _playerGrid; private Transform _gridRoot; private PlayerToolbarSide _side; private float _verticalOffset; private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4]; internal void Setup(RectTransform toolbarRect, RectTransform parentRect, PlayerToolbarSide side, float verticalOffset) { _toolbarRect = toolbarRect; _parentRect = parentRect; _side = side; _verticalOffset = verticalOffset; FindGrid(); UpdatePosition(); } private void LateUpdate() { if ((Object)(object)_playerGrid == (Object)null || (Object)(object)_gridRoot == (Object)null || (Object)(object)_parentRect == (Object)null || (Object)(object)_toolbarRect == (Object)null) { FindGrid(); } UpdatePosition(); } private void FindGrid() { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null) { _playerGrid = null; _gridRoot = null; return; } try { _playerGrid = Traverse.Create((object)instance).Field<InventoryGrid>("m_playerGrid").Value; } catch { _playerGrid = null; } if ((Object)(object)_playerGrid == (Object)null) { _gridRoot = null; return; } try { object value = Traverse.Create((object)_playerGrid).Field("m_gridRoot").GetValue(); GameObject val = (GameObject)((value is GameObject) ? value : null); if (val != null) { _gridRoot = val.transform; return; } Transform val2 = (Transform)((value is Transform) ? value : null); if (val2 != null) { _gridRoot = val2; return; } Component val3 = (Component)((value is Component) ? value : null); if (val3 != null) { _gridRoot = val3.transform; return; } } catch { } _gridRoot = null; } private void UpdatePosition() { //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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_01a4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_toolbarRect == (Object)null || (Object)(object)_parentRect == (Object)null || (Object)(object)_playerGrid == (Object)null || (Object)(object)_gridRoot == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (inventory == null) { return; } int width = inventory.GetWidth(); if (width <= 0 || !ExtraSlotsCompatibility.TryGetRegularInventoryHeight(inventory, out var height) || height <= 0) { return; } int num2; int num = (num2 = (height - 1) * width) + width - 1; if (num2 < 0 || num < 0 || num2 >= _gridRoot.childCount || num >= _gridRoot.childCount) { return; } Transform child = _gridRoot.GetChild(num2); Transform child2 = _gridRoot.GetChild(num); if ((Object)(object)child == (Object)null || (Object)(object)child2 == (Object)null) { return; } RectTransform component = ((Component)child).GetComponent<RectTransform>(); RectTransform component2 = ((Component)child2).GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null)) { Vector3 val; if (_side == PlayerToolbarSide.DownLeft) { component.GetWorldCorners(_corners); val = _corners[0]; _toolbarRect.pivot = new Vector2(0f, 1f); } else { component2.GetWorldCorners(_corners); val = _corners[3]; _toolbarRect.pivot = new Vector2(1f, 1f); } Vector3 val2 = ((Transform)_parentRect).InverseTransformPoint(val); ((Transform)_toolbarRect).localPosition = new Vector3(val2.x, val2.y + _verticalOffset, 0f); } } } internal sealed class ToolbarButtonView { internal GameObject GameObject; internal RectTransform Rect; internal Button Button; internal Image Icon; } internal static class ToolbarButtonFactory { internal static ToolbarButtonView Create(GameObject template, Transform parent, string objectName, Sprite icon, float buttonSize, float iconSize) { return Create(template, parent, objectName, icon, buttonSize, buttonSize, iconSize); } internal static ToolbarButtonView Create(GameObject template, Transform parent, string objectName, Sprite icon, float buttonWidth, float buttonHeight, float iconSize) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(template, parent); ((Object)val).name = objectName; Button component = val.GetComponent<Button>(); RectTransform component2 = val.GetComponent<RectTransform>(); component2.sizeDelta = new Vector2(buttonWidth, buttonHeight); LayoutElement val2 = val.GetComponent<LayoutElement>(); if ((Object)(object)val2 == (Object)null) { val2 = val.AddComponent<LayoutElement>(); } val2.minWidth = buttonWidth; val2.minHeight = buttonHeight; val2.preferredWidth = buttonWidth; val2.preferredHeight = buttonHeight; val2.flexibleWidth = 0f; val2.flexibleHeight = 0f; TMP_Text[] componentsInChildren = val.GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.SetActive(false); } GameObject val3 = new GameObject("Icon", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent(val.transform, false); RectTransform component3 = val3.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0.5f, 0.5f); component3.anchorMax = new Vector2(0.5f, 0.5f); component3.pivot = new Vector2(0.5f, 0.5f); component3.anchoredPosition = Vector2.zero; component3.sizeDelta = new Vector2(iconSize, iconSize); Image component4 = val3.GetComponent<Image>(); component4.sprite = icon; component4.preserveAspect = true; ((Graphic)component4).raycastTarget = false; ((Graphic)component4).color = ((ModConfig.IconColor != null) ? ModConfig.IconColor.Value : Color.white); val.SetActive(true); return new ToolbarButtonView { GameObject = val, Rect = component2, Button = component, Icon = component4 }; } } internal static class ToolbarLayout { private const float BaseMargin = 12f; private const float HorizontalEdgeMargin = 8f; private const float CompactBottomMargin = 1f; internal static bool IsCompactHorizontalMode() { if (ModConfig.ContainerToolbarSmallHorizontalButtons == null || !ModConfig.ContainerToolbarSmallHorizontalButtons.Value) { return false; } ToolbarSide value = ModConfig.ContainerToolbarSide.Value; if (value != ToolbarSide.DownLeft) { return value == ToolbarSide.DownRight; } return true; } internal static GameObject Create(Transform parent, int buttonCount, float buttonWidth, float buttonHeight) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) ToolbarSide value = ModConfig.ContainerToolbarSide.Value; bool flag = IsVertical(value); bool compactHorizontal = IsCompactHorizontalMode(); GameObject val = ((!flag) ? new GameObject("VIT_ContainerToolbar", new Type[2] { typeof(RectTransform), typeof(HorizontalLayoutGroup) }) : new GameObject("VIT_ContainerToolbar", new Type[2] { typeof(RectTransform), typeof(VerticalLayoutGroup) })); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); float value2 = ModConfig.ContainerToolbarSpacing.Value; int num = Mathf.Max(0, buttonCount - 1); if (flag) { component.sizeDelta = new Vector2(buttonWidth, buttonHeight * (float)buttonCount + value2 * (float)num); VerticalLayoutGroup component2 = val.GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = value2; ((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false; } else { component.sizeDelta = new Vector2(buttonWidth * (float)buttonCount + value2 * (float)num, buttonHeight); HorizontalLayoutGroup component3 = val.GetComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component3).spacing = value2; ((HorizontalOrVerticalLayoutGroup)component3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandHeight = false; } Position(component, value, compactHorizontal); val.transform.SetAsLastSibling(); return val; } private static bool IsVertical(ToolbarSide side) { if (side != ToolbarSide.RightTop && side != ToolbarSide.LeftTop) { return side == ToolbarSide.LeftDown; } return true; } private static void Position(RectTransform rect, ToolbarSide side, bool compactHorizontal) { //IL_004c: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_015a: 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_0185: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) float value = ModConfig.ContainerToolbarOffsetX.Value; float value2 = ModConfig.ContainerToolbarOffsetY.Value; float num = (compactHorizontal ? 1f : 12f); switch (side) { case ToolbarSide.RightTop: rect.anchorMin = new Vector2(1f, 1f); rect.anchorMax = new Vector2(1f, 1f); rect.pivot = new Vector2(0f, 1f); rect.anchoredPosition = new Vector2(12f + value, value2); break; case ToolbarSide.LeftTop: rect.anchorMin = new Vector2(0f, 1f); rect.anchorMax = new Vector2(0f, 1f); rect.pivot = new Vector2(1f, 1f); rect.anchoredPosition = new Vector2(-12f + value, value2); break; case ToolbarSide.LeftDown: rect.anchorMin = new Vector2(0f, 0f); rect.anchorMax = new Vector2(0f, 0f); rect.pivot = new Vector2(1f, 0f); rect.anchoredPosition = new Vector2(-12f + value, value2); break; case ToolbarSide.DownLeft: rect.anchorMin = new Vector2(0f, 0f); rect.anchorMax = new Vector2(0f, 0f); rect.pivot = new Vector2(0f, 1f); rect.anchoredPosition = new Vector2(8f + value, 0f - num + value2); break; case ToolbarSide.DownRight: rect.anchorMin = new Vector2(1f, 0f); rect.anchorMax = new Vector2(1f, 0f); rect.pivot = new Vector2(1f, 1f); rect.anchoredPosition = new Vector2(-8f + value, 0f - num + value2); break; } } } internal static class TooltipUtility { internal static void Add(GameObject buttonObject, string titleKey, string descriptionKey = null, Func<string> hotkeyProvider = null) { if (!((Object)(object)buttonObject == (Object)null)) { ButtonTooltip buttonTooltip = buttonObject.GetComponent<ButtonTooltip>(); if ((Object)(object)buttonTooltip == (Object)null) { buttonTooltip = buttonObject.AddComponent<ButtonTooltip>(); } buttonTooltip.Setup(titleKey, descriptionKey, hotkeyProvider); } } }