using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using InventoryActions.LocalizationManager; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("InventoryActions")] [assembly: AssemblyDescription("Standalone inventory actions for Valheim")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("InventoryActions")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("1FBE0C8C-42DE-4C9A-9C7F-74280DC0B9AB")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace InventoryActions { [BepInPlugin("sighsorry.InventoryActions", "InventoryActions", "1.0.0")] [BepInIncompatibility("sighsorry.InventorySlots")] [BepInIncompatibility("goldenrevolver.quick_stack_store")] public sealed class InventoryActionsPlugin : BaseUnityPlugin { public enum Toggle { Off, On } private sealed class AcceptableShortcuts : AcceptableValueBase { public AcceptableShortcuts() : base(typeof(KeyboardShortcut)) { } public override object Clamp(object value) { return value; } public override bool IsValid(object value) { return true; } public override string ToDescriptionString() { return "# Acceptable values: " + string.Join(", ", UnityInput.Current.SupportedKeyCodes); } } private sealed class ConfigurationManagerAttributes { public int? Order { get; set; } public bool? Browsable { get; set; } public Action? CustomDrawer { get; set; } } private enum RestockMode { CurrentContainerMatchingStacks, AreaFavoriteRestock } private readonly struct SfxVolumeMemberCache { public FieldInfo[] Fields { get; } public PropertyInfo[] Properties { get; } public SfxVolumeMemberCache(FieldInfo[] fields, PropertyInfo[] properties) { Fields = fields; Properties = properties; } } private sealed class RestockTargetLimitEditorRow { public string Item { get; set; } public string Amount { get; set; } public RestockTargetLimitEditorRow(string item, string amount) { Item = item; Amount = amount; } } [CompilerGenerated] private static class <>O { public static Action <0>__HandleLocalizationComplete; public static Action <1>__DrawRestockTargetStackLimitsConfig; public static Func <2>__GetShortcutKeyDisplayText; public static Func <3>__TryGetHoverQuickStackContext; public static Func <4>__TryQuickStackFromHoveredContainer; public static Func <5>__TryGetHoverRestockContext; public static Func <6>__TryRestockFromHoveredContainer; public static Func <7>__IsDigit; public static UnityAction <8>__TryClickInventoryTrashPanel; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static EventHandler <>9__40_0; public static EventHandler <>9__40_1; public static Func <>9__55_0; public static Func <>9__64_0; public static Func <>9__72_0; public static Func <>9__72_1; public static Func <>9__72_2; public static Func <>9__85_1; public static Func <>9__85_2; public static Func <>9__85_3; public static Func <>9__86_1; public static Func <>9__86_2; public static Comparison <>9__89_1; public static Func <>9__91_0; public static Func <>9__91_1; public static Comparison <>9__92_1; public static Comparison <>9__96_1; public static Func <>9__105_0; public static Func <>9__107_0; public static Func <>9__108_0; public static Funcf__AnonymousType0> <>9__108_1; public static Funcf__AnonymousType0, ItemData>, List> <>9__108_2; public static Func <>9__108_3; public static Comparison<(Container Container, float DistanceSq)> <>9__130_0; public static Func <>9__142_0; public static Func <>9__142_1; public static Func <>9__148_1; public static Func <>9__148_2; public static Func <>9__165_0; public static Func <>9__165_1; public static UnityAction <>9__177_0; public static UnityAction <>9__177_1; public static UnityAction <>9__179_0; public static UnityAction <>9__186_0; internal void b__40_0(object _, EventArgs _) { RefreshFavoriteBorders(); } internal void b__40_1(object _, EventArgs _) { RefreshRestockTargetStackLimits(); } internal bool b__55_0(char ch) { bool flag = char.IsLetterOrDigit(ch); if (!flag) { bool flag2 = ((ch == '-' || ch == '_') ? true : false); flag = flag2; } return flag; } internal bool b__64_0(string part) { return !string.IsNullOrWhiteSpace(part); } internal int b__72_0(Vector2i slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return slot.y; } internal int b__72_1(Vector2i slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return slot.x; } internal string b__72_2(Vector2i slot) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) return $"{slot.x},{slot.y}"; } internal bool b__85_1(ItemData item) { return item?.m_shared != null; } internal int b__85_2(ItemData item) { return item.m_gridPos.y; } internal int b__85_3(ItemData item) { return item.m_gridPos.x; } internal int b__86_1(ItemData target) { return target.m_gridPos.y; } internal int b__86_2(ItemData target) { return target.m_gridPos.x; } internal int b__89_1(ItemData a, ItemData b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return -CompareGridOrder(a.m_gridPos, b.m_gridPos); } internal bool b__91_0(ItemData item) { return item?.m_shared != null; } internal string b__91_1(ItemData item) { return item.m_shared.m_name; } internal int b__92_1(ItemData a, ItemData b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return CompareGridOrder(a.m_gridPos, b.m_gridPos); } internal int b__96_1(ItemData a, ItemData b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) return -CompareGridOrder(a.m_gridPos, b.m_gridPos); } internal bool b__105_0(ItemData item) { return item?.m_shared != null; } internal ItemData b__107_0(ItemData item) { return item; } internal bool b__108_0(ItemData item) { if (item?.m_shared != null && item.m_stack < item.m_shared.m_maxStackSize) { return CanUseContainerActionStacking(item); } return false; } internal <>f__AnonymousType0 b__108_1(ItemData item) { return new { item.m_shared.m_name, item.m_quality, item.m_worldLevel }; } internal List b__108_2(IGrouping<<>f__AnonymousType0, ItemData> grouping) { return grouping.ToList(); } internal int b__108_3(ItemData item) { return item.m_stack; } internal int b__130_0((Container Container, float DistanceSq) left, (Container Container, float DistanceSq) right) { return left.DistanceSq.CompareTo(right.DistanceSq); } internal bool b__142_0(FieldInfo field) { if (field.FieldType == typeof(float) && IsSfxVolumeMemberName(field.Name)) { return !IsUnsupportedSfxVolumeMemberName(field.Name); } return false; } internal bool b__142_1(PropertyInfo property) { if (property.PropertyType == typeof(float) && property.CanRead && property.CanWrite && property.GetIndexParameters().Length == 0 && IsSfxVolumeMemberName(property.Name)) { return !IsUnsupportedSfxVolumeMemberName(property.Name); } return false; } internal int b__148_1(ItemData target) { return target.m_gridPos.y; } internal int b__148_2(ItemData target) { return target.m_gridPos.x; } internal bool b__165_0(RestockTargetLimitEditorRow row) { if (string.IsNullOrWhiteSpace(row.Item)) { return !string.IsNullOrWhiteSpace(row.Amount); } return true; } internal string b__165_1(RestockTargetLimitEditorRow row) { return row.Item.Trim() + ": " + row.Amount.Trim(); } internal void b__177_0() { StoreAllToCurrentContainer(Player.m_localPlayer); } internal void b__177_1() { RestockFromCurrentContainer(Player.m_localPlayer); } internal void b__179_0() { SortPlayerInventory(Player.m_localPlayer); } internal void b__186_0() { SortCurrentContainer(Player.m_localPlayer); } } [CompilerGenerated] private sealed class d__150 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private Vector2i <>2__current; private int <>l__initialThreadId; private Inventory inventory; public Inventory <>3__inventory; private int 5__2; private int 5__3; private int 5__4; private int 5__5; Vector2i IEnumerator.Current { [DebuggerHidden] get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return <>2__current; } } [DebuggerHidden] public d__150(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; 5__5++; goto IL_008e; } <>1__state = -1; 5__2 = Math.Max(1, inventory.GetWidth()); 5__3 = Math.Max(0, inventory.GetHeight()); 5__4 = 0; goto IL_00ac; IL_008e: if (5__5 < 5__2) { <>2__current = new Vector2i(5__5, 5__4); <>1__state = 1; return true; } 5__4++; goto IL_00ac; IL_00ac: if (5__4 < 5__3) { 5__5 = 0; goto IL_008e; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__150 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__150(0); } d__.inventory = <>3__inventory; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } [CompilerGenerated] private sealed class d__101 : IEnumerable, IEnumerable, IEnumerator, IDisposable, IEnumerator { private int <>1__state; private string? <>2__current; private int <>l__initialThreadId; private ItemData item; public ItemData <>3__item; private string 5__2; string IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__101(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (item == null) { return false; } <>2__current = GetItemPrefabName(item); <>1__state = 1; return true; case 1: <>1__state = -1; if (!IsUnityNull((Object?)(object)item.m_dropPrefab)) { <>2__current = ((Object)item.m_dropPrefab).name; <>1__state = 2; return true; } goto IL_0091; case 2: <>1__state = -1; goto IL_0091; case 3: <>1__state = -1; <>2__current = RestockTargetLimitCore.StripLocalizationToken(5__2); <>1__state = 4; return true; case 4: <>1__state = -1; if (Localization.instance != null && !string.IsNullOrWhiteSpace(5__2)) { <>2__current = Localization.instance.Localize(5__2); <>1__state = 5; return true; } break; case 5: { <>1__state = -1; break; } IL_0091: 5__2 = item.m_shared?.m_name ?? ""; <>2__current = 5__2; <>1__state = 3; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { d__101 d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; d__ = this; } else { d__ = new d__101(0); } d__.item = <>3__item; return d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)this).GetEnumerator(); } } internal const string ModName = "InventoryActions"; internal const string ModVersion = "1.0.0"; internal const string Author = "sighsorry"; internal const string ModGUID = "sighsorry.InventoryActions"; private const int PlayerInventoryWidth = 8; private const int VanillaPlayerRows = 4; private const string FavoriteBorderName = "InventoryActions_FavoriteBorder"; private const float FavoriteBorderThickness = 2f; private const string ClientConfigSection = "2 - Client"; private const string RestockConfigSection = "3 - Restock"; private const string GeneralConfigSection = "1 - General"; private const float ContainerHoverHoldDurationDefault = 0.5f; private const float ContainerHoverHoldDurationMin = 0.1f; private const float ContainerHoverHoldDurationMax = 0.5f; private const string ContainerActionSuccessFxPrefabName = "fx_HildirChest_Unlock"; private const int ContainerActionSuccessFxMaxMode = 12; internal static readonly ManualLogSource Log = Logger.CreateLogSource("InventoryActions"); private readonly Harmony _harmony = new Harmony("sighsorry.InventoryActions"); private static InventoryActionsPlugin _instance = null; private static readonly InventoryActionRuntimeState Runtime = new InventoryActionRuntimeState(); private static readonly ConfigSync ConfigSync = new ConfigSync("sighsorry.InventoryActions") { DisplayName = "InventoryActions", CurrentVersion = "1.0.0", MinimumRequiredVersion = "1.0.0" }; private static ConfigEntry _serverConfigLocked = null; private static ConfigEntry _enableInventoryTrashPanel = null; private static ConfigEntry _areaQuickStackRange = null; private static ConfigEntry _areaRestockRange = null; private static ConfigEntry _favoriteBorderColor = null; private static ConfigEntry _containerHoverHoldDuration = null; private static ConfigEntry _containerActionSuccessFxMode = null; private static ConfigEntry _containerActionSuccessFxVolume = null; private static ConfigEntry _favoriteModifierKey = null; private static ConfigEntry _containerRestockKey = null; private static ConfigEntry _restockTargetStackLimitsConfig = null; private static readonly Color FavoriteBorderDefaultColor = new Color(0.1f, 0.55f, 1f, 0.95f); private static readonly Dictionary SfxVolumeMembersByType = new Dictionary(); private static readonly List RestockTargetLimitEditorRows = new List(); private static string _restockTargetLimitEditorLastValue = ""; private const float SortButtonOutsideGap = 1f; private const float TrashPanelGap = 8f; private static readonly Vector2 InventorySortButtonFixedOffset = new Vector2(2f, 2f); private const string PlayerActionPanelName = "InventoryActions_PlayerActionPanel"; private const string TrashPanelName = "InventoryActions_TrashPanel"; private const string TrashButtonName = "InventoryActions_TrashButton"; private const string TrashIconName = "InventoryActions_TrashIcon"; private const string TrashConfirmDialogName = "InventoryActions_TrashConfirmDialog"; internal static bool IsDedicatedServer { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)SystemInfo.graphicsDeviceType != 4) { if (Application.isBatchMode) { return string.Equals(Paths.ProcessName, "valheim_server", StringComparison.OrdinalIgnoreCase); } return false; } return true; } } private void Awake() { _instance = this; Localizer.OnLocalizationComplete += HandleLocalizationComplete; Localizer.Load((BaseUnityPlugin)(object)this); BindConfigs(); _harmony.PatchAll(); Log.LogInfo((object)"InventoryActions loaded."); } private void Update() { if (!IsDedicatedServer) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || IsUnityNull((Object?)(object)localPlayer) || localPlayer.m_isLoading) { ResetContainerHold(Runtime.AreaQuickStackHold); ResetContainerHold(Runtime.AreaRestockHold); } else { HandleHoverActions(localPlayer); } } } private void OnDestroy() { Localizer.OnLocalizationComplete -= HandleLocalizationComplete; _harmony.UnpatchSelf(); ((BaseUnityPlugin)this).Config.Save(); } private static void HandleLocalizationComplete() { Runtime.UiLocalizationVersion++; } private static void BindConfigs() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_0168: 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_019c: Expected O, but got Unknown //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Expected O, but got Unknown //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Expected O, but got Unknown //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Expected O, but got Unknown //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Expected O, but got Unknown _serverConfigLocked = ConfigEntry("1 - General", "Lock Configuration", Toggle.On, "When enabled, only server admins can modify this mod's synced configuration."); ConfigSync.AddLockingConfigEntry(_serverConfigLocked); _enableInventoryTrashPanel = ConfigEntry("1 - General", "Enable Inventory Trash Panel", Toggle.On, "When enabled, shows a trash panel below the player inventory. Dropping a held player-inventory item on it opens a confirmation dialog before deleting the held amount."); _areaQuickStackRange = ConfigEntry("1 - General", "Area Quick Stack Range", 10f, new ConfigDescription("Range in meters for hover Area Quick Stack. Set to 0 to disable area quick stack. The opened-container Place stacks button only uses the current container.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 50f), Array.Empty())); _areaRestockRange = ConfigEntry("1 - General", "Area Take Stacks Range", 10f, new ConfigDescription("Range in meters for hover Area Take Stacks. Set to 0 to disable area take stacks. The opened-container Take stacks button only uses the current container.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 50f), Array.Empty())); _favoriteModifierKey = ConfigEntry("2 - Client", "Favorite Modifier Key", new KeyboardShortcut((KeyCode)308, Array.Empty()), new ConfigDescription("Hold this and left-click a player inventory cell to toggle that favorite slot. Alt accepts both LeftAlt and RightAlt.", (AcceptableValueBase)(object)new AcceptableShortcuts(), new object[1] { new ConfigurationManagerAttributes { Order = 900 } }), synchronizedSetting: false); _containerRestockKey = ConfigEntry("2 - Client", "Container Restock Key", new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new ConfigDescription("Hold this while hovering a container to take stacks into favorite slots from that container and nearby containers. Alt accepts both LeftAlt and RightAlt.", (AcceptableValueBase)(object)new AcceptableShortcuts(), new object[1] { new ConfigurationManagerAttributes { Order = 890 } }), synchronizedSetting: false); _favoriteBorderColor = ConfigEntry("2 - Client", "Favorite Border Color", FavoriteBorderDefaultColor, new ConfigDescription("Color for favorite slot borders. Uses the same RRGGBBAA color format as InventorySlots color configs. Not synced with server.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 880 } }), synchronizedSetting: false); _favoriteBorderColor.SettingChanged += delegate { RefreshFavoriteBorders(); }; _containerHoverHoldDuration = ConfigEntry("2 - Client", "Container Hover Hold Duration", 0.5f, new ConfigDescription("Seconds a container must stay hovered while holding E or the Container Restock Key before hover quick stack/restock fires. Lower values make pass-by container actions more responsive. Not synced with server.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 0.5f), new object[1] { new ConfigurationManagerAttributes { Order = 870 } }), synchronizedSetting: false); _containerActionSuccessFxMode = ConfigEntry("2 - Client", "Container Action Success FX Mode", 4, new ConfigDescription("Chest-unlock FX mode for hover hold area actions. 0 disables FX. 1 spawns FX at the interacted container. 2-12 spawns FX at each container whose stack changed, up to this many containers. Opened-container buttons do not spawn FX.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 12), new object[1] { new ConfigurationManagerAttributes { Order = 860 } }), synchronizedSetting: false); _containerActionSuccessFxVolume = ConfigEntry("2 - Client", "Container Action Success FX Volume", 1f, new ConfigDescription("Volume multiplier for InventoryActions container action success FX audio. 0 mutes the FX sound and 1 keeps the original prefab volume.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), new object[1] { new ConfigurationManagerAttributes { Order = 850 } }), synchronizedSetting: false); _restockTargetStackLimitsConfig = ConfigEntry("3 - Restock", "Restock Target Stack Limits", "", new ConfigDescription("Client-only per-item target stack caps for Take stacks/restock into favorite slots. Keys may be prefab names, internal item names, or localized item names in the current client language, such as Stone: 10, Coins: 500. Separate entries with commas, semicolons, or new lines. Empty uses each item's normal max stack; 0 prevents restocking that item.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 700, CustomDrawer = DrawRestockTargetStackLimitsConfig } }), synchronizedSetting: false); _restockTargetStackLimitsConfig.SettingChanged += delegate { RefreshRestockTargetStackLimits(); }; RefreshRestockTargetStackLimits(); } private static ConfigEntry ConfigEntry(string group, string name, T value, string description, bool synchronizedSetting = true) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown return ConfigEntry(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty()), synchronizedSetting); } private static ConfigEntry ConfigEntry(string group, string name, T value, ConfigDescription description, bool synchronizedSetting = true) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown ConfigDescription val = new ConfigDescription(description.Description + " [" + (synchronizedSetting ? "Synced with Server" : "Not Synced with Server") + "]", description.AcceptableValues, description.Tags); ConfigEntry val2 = ((BaseUnityPlugin)_instance).Config.Bind(group, name, value, val); ConfigSync.AddConfigEntry(val2).SynchronizedConfig = synchronizedSetting; return val2; } private static bool IsUnityNull(Object? obj) { return obj == (Object)null; } private static bool IsOutOfBounds(Inventory inventory, Vector2i pos) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (inventory != null && pos.x >= 0 && pos.y >= 0 && pos.x < inventory.GetWidth()) { return pos.y >= inventory.GetHeight(); } return true; } private static Inventory? GetPlayerInventory(Player? player) { if (!((Object)(object)player != (Object)null)) { return null; } return ((Humanoid)player).GetInventory(); } private static bool IsPlayerInventory(Player? player, Inventory? inventory) { if ((Object)(object)player != (Object)null && inventory != null) { return inventory == GetPlayerInventory(player); } return false; } private static bool IsPlayerActionCell(Inventory inventory, Vector2i pos, bool includeHotbar) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (IsOutOfBounds(inventory, pos) || pos.y >= Math.Min(4, inventory.GetHeight())) { return false; } return pos.y > 0 || includeHotbar; } private static bool IsHotbarCell(Vector2i pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return pos.y == 0; } private static bool IsRegularActionItem(Player player, Inventory inventory, ItemData item, bool includeHotbar) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (item?.m_shared != null) { return IsPlayerActionCell(inventory, item.m_gridPos, includeHotbar); } return false; } private static bool HasNoCustomData(ItemData item) { if (item.m_customData != null) { return item.m_customData.Count == 0; } return true; } private static bool CanUseContainerActionStacking(ItemData item) { if (item?.m_shared != null) { return HasNoCustomData(item); } return false; } private static string GetPlayerId(Player player) { Game instance = Game.instance; PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null); if (val == null) { return player.GetPlayerID().ToString(); } return val.GetPlayerID().ToString(); } private static string GetFavoriteFilePath(string playerId) { string text = new string(playerId.Where(delegate(char ch) { bool flag = char.IsLetterOrDigit(ch); if (!flag) { bool flag2 = ((ch == '-' || ch == '_') ? true : false); flag = flag2; } return flag; }).ToArray()); if (string.IsNullOrWhiteSpace(text)) { text = "unknown"; } return Path.Combine(Paths.ConfigPath, "InventoryActions.Favorites." + text + ".txt"); } private static string LocalizeUi(string token, string fallback) { if (Localization.instance == null || string.IsNullOrWhiteSpace(token)) { return fallback; } string text = Localization.instance.Localize(token); if (!string.IsNullOrWhiteSpace(text) && !string.Equals(text, token, StringComparison.Ordinal)) { return text; } return fallback; } private static string GetLocalizedItemName(ItemData item) { string text = item?.m_shared?.m_name ?? ""; if (Localization.instance == null) { return text; } return Localization.instance.Localize(text); } private static void ShowActionResult(Player player, string action, int moved) { if (!((Object)(object)player == (Object)null)) { string text = LocalizeUi("$inventoryslots_action_result_format", "{action}: {count}").Replace("{action}", action).Replace("{count}", moved.ToString()); ((Character)player).Message((MessageType)2, text, 0, (Sprite)null); } } private static bool ShouldBlockGlobalHotkeys(Player? player = null) { if ((Object)(object)player != (Object)null && (player.m_isLoading || ((Character)player).InCutscene())) { return true; } if ((Object)(object)Chat.instance != (Object)null && !IsUnityNull((Object?)(object)Chat.instance) && Chat.instance.HasFocus()) { return true; } if (Console.IsVisible() || TextInput.IsVisible() || Menu.IsVisible() || Minimap.IsOpen() || Minimap.InTextInput() || StoreGui.IsVisible() || GameCamera.InFreeFly()) { return true; } if ((Object)(object)TextViewer.instance != (Object)null && !IsUnityNull((Object?)(object)TextViewer.instance) && TextViewer.instance.IsVisible()) { return true; } if ((Object)(object)ZNet.instance != (Object)null && !IsUnityNull((Object?)(object)ZNet.instance)) { return ZNet.instance.InPasswordDialog(); } return false; } private static bool IsShortcutHeldAllowingAltPair(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !AreShortcutModifiersHeldAllowingAltPair(shortcut)) { return false; } return IsShortcutMainKeyHeldAllowingAltPair(shortcut); } private static bool AreShortcutModifiersHeldAllowingAltPair(KeyboardShortcut shortcut) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if (!IsShortcutModifierHeldAllowingAltPair(modifier)) { return false; } } return true; } private static bool IsShortcutModifierHeldAllowingAltPair(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (key - 307 <= 1) { if (!Input.GetKey((KeyCode)308)) { return Input.GetKey((KeyCode)307); } return true; } return Input.GetKey(key); } private static bool IsShortcutMainKeyHeldAllowingAltPair(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) KeyCode mainKey = ((KeyboardShortcut)(ref shortcut)).MainKey; if (mainKey - 307 <= 1) { if (!Input.GetKey((KeyCode)308)) { return Input.GetKey((KeyCode)307); } return true; } return Input.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey); } private static string GetShortcutDisplayText(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) { return ""; } IEnumerable values = from part in ((KeyboardShortcut)(ref shortcut)).Modifiers.Select(GetShortcutKeyDisplayText).Concat(new string[1] { GetShortcutKeyDisplayText(((KeyboardShortcut)(ref shortcut)).MainKey) }) where !string.IsNullOrWhiteSpace(part) select part; return string.Join("+", values); } private static string GetShortcutKeyDisplayText(KeyCode key) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 //IL_0032: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected I4, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0076: 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_009e: Expected I4, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 string text = ((object)(KeyCode)(ref key)).ToString(); if (text.StartsWith("Alpha", StringComparison.Ordinal)) { return text.Substring("Alpha".Length); } if ((int)key <= 27) { if ((int)key == 0) { return ""; } if ((int)key == 13) { return "Enter"; } if ((int)key == 27) { return "Esc"; } } else { if ((int)key == 32) { return "Spc"; } switch (key - 303) { case 4: case 5: return "Alt"; case 2: case 3: return "Ctrl"; case 0: case 1: return "Shift"; } switch (key - 323) { case 0: return "M1"; case 1: return "M2"; case 2: return "M3"; case 3: return "M4"; case 4: return "M5"; case 5: return "M6"; case 6: return "M7"; } } return text; } internal static bool HandleFavoriteClick(InventoryGrid grid, UIInputHandler clickHandler) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (!ShouldHandleFavoriteClick(grid)) { return true; } Player localPlayer = Player.m_localPlayer; Inventory playerInventory = GetPlayerInventory(localPlayer); if (playerInventory == null || grid.m_inventory != playerInventory) { return true; } Vector2i buttonPos = grid.GetButtonPos(((Component)clickHandler).gameObject); if (buttonPos.x < 0 || buttonPos.y < 0 || IsOutOfBounds(playerInventory, buttonPos)) { return true; } if (!IsPlayerActionCell(playerInventory, buttonPos, includeHotbar: true)) { return true; } ToggleFavoriteSlot(localPlayer, buttonPos); return false; } private static bool ShouldHandleFavoriteClick(InventoryGrid grid) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)grid == (Object)null || (Object)(object)InventoryGui.instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return false; } Player localPlayer = Player.m_localPlayer; if (localPlayer.m_isLoading || ((Character)localPlayer).IsTeleporting()) { return false; } if ((Object)(object)InventoryGui.instance.m_dragGo != (Object)null || (Object)(object)grid != (Object)(object)InventoryGui.instance.m_playerGrid) { return false; } if (_favoriteModifierKey != null) { return IsShortcutHeldAllowingAltPair(_favoriteModifierKey.Value); } return false; } private static void ToggleFavoriteSlot(Player player, Vector2i pos) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) EnsureFavoritesLoaded(player); if (!Runtime.FavoriteSlots.Add(pos)) { Runtime.FavoriteSlots.Remove(pos); } SaveFavorites(player); RefreshFavoriteBorders(); } private static bool IsFavoriteProtected(Player player, Inventory inventory, ItemData item) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (item?.m_shared != null && IsPlayerInventory(player, inventory)) { return IsFavoriteSlot(player, item.m_gridPos); } return false; } private static bool IsFavoriteSlot(Player player, Vector2i pos) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) EnsureFavoritesLoaded(player); return Runtime.FavoriteSlots.Contains(pos); } private static void EnsureFavoritesLoaded(Player player) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } string playerId = GetPlayerId(player); if (string.Equals(Runtime.LoadedFavoritesPlayerId, playerId, StringComparison.Ordinal)) { return; } Runtime.FavoriteSlots.Clear(); Runtime.LoadedFavoritesPlayerId = playerId; string favoriteFilePath = GetFavoriteFilePath(playerId); if (!File.Exists(favoriteFilePath)) { return; } try { string[] array = File.ReadAllLines(favoriteFilePath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0 && !text.StartsWith("#", StringComparison.Ordinal)) { string[] array2 = text.Split(new char[1] { ',' }); if (array2.Length == 2 && int.TryParse(array2[0].Trim(), out var result) && int.TryParse(array2[1].Trim(), out var result2) && result >= 0 && result2 >= 0) { Runtime.FavoriteSlots.Add(new Vector2i(result, result2)); } } } } catch (Exception ex) { Log.LogWarning((object)("Failed to load InventoryActions favorites from " + favoriteFilePath + ": " + ex.Message)); } } private static void SaveFavorites(Player player) { if ((Object)(object)player == (Object)null) { return; } string playerId = GetPlayerId(player); Runtime.LoadedFavoritesPlayerId = playerId; string favoriteFilePath = GetFavoriteFilePath(playerId); try { string[] contents = (from slot in Runtime.FavoriteSlots orderby slot.y, slot.x select $"{slot.x},{slot.y}").ToArray(); File.WriteAllLines(favoriteFilePath, contents); } catch (Exception ex) { Log.LogWarning((object)("Failed to save InventoryActions favorites to " + favoriteFilePath + ": " + ex.Message)); } } private static void RefreshFavoriteBorders() { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance?.m_playerGrid == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null)) { UpdateFavoriteBorders(instance.m_playerGrid, Player.m_localPlayer); } } private static void UpdateFavoriteBorders(InventoryGrid grid, Player player) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_010f: Unknown result type (might be due to invalid IL or missing references) Inventory playerInventory = GetPlayerInventory(player); if (grid?.m_elements == null || playerInventory == null || grid.m_inventory != playerInventory) { return; } EnsureFavoritesLoaded(player); foreach (Element element in grid.m_elements) { if ((Object)(object)element?.m_go == (Object)null || IsUnityNull((Object?)(object)element.m_go)) { continue; } if (!element.m_go.activeSelf) { SetFavoriteBorderActive(element, active: false); continue; } Vector2i buttonPos = grid.GetButtonPos(element.m_go); if (IsOutOfBounds(playerInventory, buttonPos) || !Runtime.FavoriteSlots.Contains(buttonPos)) { SetFavoriteBorderActive(element, active: false); continue; } RectTransform val = EnsureFavoriteBorder(element); if (!((Object)(object)val == (Object)null)) { InventoryGridElementMarker inventoryGridElementMarker = element.m_go.GetComponent() ?? element.m_go.AddComponent(); if (inventoryGridElementMarker.FavoriteBorderImages.Length == 0) { inventoryGridElementMarker.FavoriteBorderImages = ((Component)val).GetComponentsInChildren(true); } Image[] favoriteBorderImages = inventoryGridElementMarker.FavoriteBorderImages; for (int i = 0; i < favoriteBorderImages.Length; i++) { ((Graphic)favoriteBorderImages[i]).color = GetFavoriteBorderColor(); } ((Component)val).gameObject.SetActive(true); ((Transform)val).SetAsLastSibling(); } } } private static Color GetFavoriteBorderColor() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (_favoriteBorderColor == null) { return FavoriteBorderDefaultColor; } return _favoriteBorderColor.Value; } private static RectTransform? EnsureFavoriteBorder(Element element) { //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_0110: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: 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_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)element?.m_go == (Object)null || IsUnityNull((Object?)(object)element.m_go)) { return null; } GameObject go = element.m_go; InventoryGridElementMarker inventoryGridElementMarker = go.GetComponent() ?? go.AddComponent(); RectTransform val = (((Object)(object)inventoryGridElementMarker.FavoriteBorder != (Object)null && !IsUnityNull((Object?)(object)inventoryGridElementMarker.FavoriteBorder)) ? inventoryGridElementMarker.FavoriteBorder : null); if ((Object)(object)val == (Object)null) { Transform val2 = go.transform.Find("InventoryActions_FavoriteBorder"); val = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent() : null); } if ((Object)(object)val == (Object)null) { val = (RectTransform)new GameObject("InventoryActions_FavoriteBorder", new Type[1] { typeof(RectTransform) }).transform; ((Transform)val).SetParent(go.transform, false); CreateFavoriteBorderSide(val, "Top", new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, 2f), Vector2.zero); CreateFavoriteBorderSide(val, "Bottom", new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 2f), Vector2.zero); CreateFavoriteBorderSide(val, "Left", new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 0.5f), new Vector2(2f, 0f), Vector2.zero); CreateFavoriteBorderSide(val, "Right", new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(1f, 0.5f), new Vector2(2f, 0f), Vector2.zero); } val.anchorMin = Vector2.zero; val.anchorMax = Vector2.one; val.offsetMin = Vector2.zero; val.offsetMax = Vector2.zero; ((Transform)val).localScale = Vector3.one; ((Transform)val).localRotation = Quaternion.identity; inventoryGridElementMarker.FavoriteBorder = val; if (inventoryGridElementMarker.FavoriteBorderImages.Length == 0) { inventoryGridElementMarker.FavoriteBorderImages = ((Component)val).GetComponentsInChildren(true); } return val; } private static void CreateFavoriteBorderSide(RectTransform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 sizeDelta, Vector2 anchoredPosition) { //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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)parent, false); val2.anchorMin = anchorMin; val2.anchorMax = anchorMax; val2.pivot = pivot; val2.sizeDelta = sizeDelta; val2.anchoredPosition = anchoredPosition; ((Transform)val2).localScale = Vector3.one; ((Transform)val2).localRotation = Quaternion.identity; ((Graphic)val.GetComponent()).raycastTarget = false; } private static void SetFavoriteBorderActive(Element element, bool active) { if (!((Object)(object)element?.m_go == (Object)null) && !IsUnityNull((Object?)(object)element.m_go)) { InventoryGridElementMarker component = element.m_go.GetComponent(); Transform val = (Transform)(((Object)(object)component?.FavoriteBorder != (Object)null && !IsUnityNull((Object?)(object)component.FavoriteBorder)) ? ((object)component.FavoriteBorder) : ((object)element.m_go.transform.Find("InventoryActions_FavoriteBorder"))); if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf != active) { ((Component)val).gameObject.SetActive(active); } } } internal static bool TryHandleVanillaPlaceStacks(InventoryGui gui) { if ((Object)(object)gui == (Object)null || (Object)(object)gui.m_currentContainer == (Object)null) { return false; } if (!CanMutateContainerDirectly(gui.m_currentContainer, allowLocalWithoutZNetView: true)) { return false; } QuickStackCurrentContainer(Player.m_localPlayer); return true; } internal static bool TryHandleContainerStackAll(Container container) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.m_isLoading || (Object)(object)container == (Object)null || container.m_inventory == null) { return false; } if (!CanMutateContainerDirectly(container, allowLocalWithoutZNetView: true)) { return false; } Inventory playerInventory = GetPlayerInventory(localPlayer); if (playerInventory == null) { return false; } QuickStackIntoContainers(localPlayer, playerInventory, container, includeArea: true); return true; } internal static bool TryHandleSafeTakeAll(InventoryGui gui) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.m_isLoading || (Object)(object)gui == (Object)null || (Object)(object)gui.m_currentContainer == (Object)null || gui.m_currentContainer.m_inventory == null) { return false; } Container currentContainer = gui.m_currentContainer; if (!CanMutateContainerDirectly(currentContainer, allowLocalWithoutZNetView: true)) { ((Character)localPlayer).Message((MessageType)2, LocalizeUi("$inventoryslots_container_not_ready", "Container is not ready."), 0, (Sprite)null); return true; } Inventory playerInventory = GetPlayerInventory(localPlayer); Inventory inventory = currentContainer.m_inventory; if (playerInventory == null || inventory == null) { return false; } TombStone component = ((Component)currentContainer).GetComponent(); gui.SetupDragItem((ItemData)null, (Inventory)null, 0); int num = SafeTakeAllItems(localPlayer, playerInventory, inventory); if (num > 0) { playerInventory.Changed(); inventory.Changed(); } if ((Object)(object)component != (Object)null && inventory.NrOfItems() == 0) { component.OnTakeAllSuccess(); } ShowActionResult(localPlayer, LocalizeUi("$inventoryslots_action_take_all", "Take All"), num); return true; } internal static bool TryHandleTopFirstMoveSelectedItem(InventoryGui gui, InventoryGrid grid, ItemData item, Modifier mod) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gui == (Object)null || (Object)(object)grid == (Object)null || item?.m_shared == null || (int)mod != 2 || item.m_shared.m_questItem || (Object)(object)gui.m_dragGo != (Object)null) { return false; } Player localPlayer = Player.m_localPlayer; Container currentContainer = gui.m_currentContainer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsTeleporting() || (Object)(object)currentContainer == (Object)null || currentContainer.m_inventory == null || !CanMutateContainerDirectly(currentContainer, allowLocalWithoutZNetView: true)) { return false; } Inventory playerInventory = GetPlayerInventory(localPlayer); Inventory inventory = grid.GetInventory(); Inventory inventory2 = currentContainer.m_inventory; if (playerInventory == null || inventory == null) { return false; } Inventory val = null; if (inventory == inventory2) { val = playerInventory; } else if (inventory == playerInventory) { val = inventory2; } if (val == null) { return false; } if (!CanMoveItemToInventoryTopFirst(inventory, val, item)) { return true; } if (inventory == playerInventory && ((Humanoid)localPlayer).IsItemEquiped(item)) { ((Humanoid)localPlayer).RemoveEquipAction(item); ((Humanoid)localPlayer).UnequipItem(item, false); } if (MoveItemToInventoryTopFirst(inventory, val, item) > 0) { playerInventory.Changed(); inventory2.Changed(); gui.m_moveItemEffects.Create(((Component)gui).transform.position, Quaternion.identity, (Transform)null, 1f, -1); } return true; } private static int SafeTakeAllItems(Player player, Inventory playerInventory, Inventory containerInventory) { Inventory playerInventory2 = playerInventory; List playerActionSlots = GetPlayerActionSlots(player, playerInventory2, includeHotbar: false, blockFavorites: true); HashSet allowedSlots = new HashSet(playerActionSlots); List emptySlots = playerActionSlots.Where((Vector2i slot) => playerInventory2.GetItemAt(slot.x, slot.y) == null).ToList(); List list = (from item in containerInventory.m_inventory where item?.m_shared != null orderby item.m_gridPos.y, item.m_gridPos.x select item).ToList(); int num = 0; foreach (ItemData item in list) { if (containerInventory.m_inventory.Contains(item)) { int stack = item.m_stack; if (MoveContainerItemSafelyToPlayer(playerInventory2, containerInventory, item, emptySlots, allowedSlots) > 0 && (!containerInventory.m_inventory.Contains(item) || item.m_stack < stack)) { num++; } } } return num; } private static int MoveContainerItemSafelyToPlayer(Inventory playerInventory, Inventory containerInventory, ItemData source, List emptySlots, HashSet allowedSlots) { //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) HashSet allowedSlots2 = allowedSlots; ItemData source2 = source; int num = 0; if (CanMergeForSafeMove(source2)) { foreach (ItemData item in (from target in playerInventory.m_inventory where target?.m_shared != null && allowedSlots2.Contains(target.m_gridPos) && CanMergeForSafeMove(target) && HasSameStackIdentity(target, source2) && target.m_stack < target.m_shared.m_maxStackSize orderby target.m_gridPos.y, target.m_gridPos.x select target).ToList()) { if (!containerInventory.m_inventory.Contains(source2) || source2.m_stack <= 0) { break; } int num2 = Math.Min(item.m_shared.m_maxStackSize - item.m_stack, source2.m_stack); if (num2 > 0) { int stack = source2.m_stack; bool moveSucceeded = playerInventory.MoveItemToThis(containerInventory, source2, num2, item.m_gridPos.x, item.m_gridPos.y); num += CountMovedFromContainerSource(containerInventory, source2, stack, num2, moveSucceeded); } } } while (containerInventory.m_inventory.Contains(source2) && source2.m_stack > 0 && emptySlots.Count > 0) { Vector2i val = emptySlots[0]; emptySlots.RemoveAt(0); int stack2 = source2.m_stack; int stack3 = source2.m_stack; bool moveSucceeded2 = playerInventory.MoveItemToThis(containerInventory, source2, stack3, val.x, val.y); int num3 = CountMovedFromContainerSource(containerInventory, source2, stack2, stack3, moveSucceeded2); num += num3; if (num3 == 0) { break; } } return num; } private static bool CanMergeForSafeMove(ItemData item) { if (item?.m_shared != null && item.m_shared.m_maxStackSize > 1) { return CanUseContainerActionStacking(item); } return false; } private static void QuickStackCurrentContainer(Player? player) { if (TryGetActionContext(player, out Player localPlayer, out Inventory playerInventory, out Container container, out Inventory _)) { QuickStackIntoContainers(localPlayer, playerInventory, container, includeArea: false); } } private static void QuickStackIntoContainers(Player localPlayer, Inventory playerInventory, Container container, bool includeArea) { Player localPlayer2 = localPlayer; Inventory playerInventory2 = playerInventory; List candidates = playerInventory2.m_inventory.Where((ItemData item) => ShouldQuickStackItem(localPlayer2, playerInventory2, item, includeHotbar: false)).ToList(); candidates.Sort((ItemData a, ItemData b) => -CompareGridOrder(a.m_gridPos, b.m_gridPos)); InventoryGui instance = InventoryGui.instance; if (instance != null) { instance.SetupDragItem((ItemData)null, (Inventory)null, 0); } int moved = RunContainerTransferAcrossContainers(localPlayer2, container, includeArea, areaForQuickStack: true, (Container targetContainer) => QuickStackItemsIntoContainer(playerInventory2, targetContainer.m_inventory, candidates), delegate { playerInventory2.Changed(); }); ShowActionResult(localPlayer2, LocalizeUi("$inventoryslots_action_stack", "Stack"), moved); } private static bool ShouldQuickStackItem(Player player, Inventory inventory, ItemData item, bool includeHotbar) { if (item?.m_shared != null && item.m_shared.m_maxStackSize > 1 && IsRegularActionItem(player, inventory, item, includeHotbar) && !IsFavoriteProtected(player, inventory, item)) { return CanUseContainerActionStacking(item); } return false; } private static int QuickStackItemsIntoContainer(Inventory playerInventory, Inventory containerInventory, List candidates) { if (containerInventory == null || candidates.Count == 0) { return 0; } HashSet hashSet = new HashSet(from item in containerInventory.m_inventory where item?.m_shared != null select item.m_shared.m_name, StringComparer.OrdinalIgnoreCase); if (hashSet.Count == 0) { return 0; } int num = 0; foreach (ItemData candidate in candidates) { if (playerInventory.m_inventory.Contains(candidate) && candidate?.m_shared != null && hashSet.Contains(candidate.m_shared.m_name) && MoveItemToInventoryTopFirst(playerInventory, containerInventory, candidate) > 0) { num++; } } if (num > 0) { containerInventory.Changed(); } return num; } private static void StoreAllToCurrentContainer(Player? player) { if (!TryGetActionContext(player, out Player localPlayer, out Inventory playerInventory, out Container _, out Inventory containerInventory)) { return; } List list = playerInventory.m_inventory.Where((ItemData item) => ShouldStoreAllItem(localPlayer, playerInventory, item, includeHotbar: false, includeEquipped: false)).ToList(); list.Sort((ItemData a, ItemData b) => CompareGridOrder(a.m_gridPos, b.m_gridPos)); InventoryGui instance = InventoryGui.instance; if (instance != null) { instance.SetupDragItem((ItemData)null, (Inventory)null, 0); } int num = 0; foreach (ItemData item in list) { if (playerInventory.m_inventory.Contains(item) && MoveItemToInventoryTopFirst(playerInventory, containerInventory, item) > 0) { num++; } } if (num > 0) { playerInventory.Changed(); containerInventory.Changed(); } ShowActionResult(localPlayer, LocalizeUi("$inventoryslots_action_place_all", "Place All"), num); } private static bool ShouldStoreAllItem(Player player, Inventory inventory, ItemData item, bool includeHotbar, bool includeEquipped) { if (item?.m_shared != null && IsRegularActionItem(player, inventory, item, includeHotbar) && !IsFavoriteProtected(player, inventory, item)) { if (!includeEquipped) { return !item.m_equipped; } return true; } return false; } private static void RestockFromCurrentContainer(Player? player) { if (TryGetActionContext(player, out Player localPlayer, out Inventory playerInventory, out Container container, out Inventory _)) { RestockFromContainer(localPlayer, playerInventory, container, RestockMode.CurrentContainerMatchingStacks); } } private static void RefreshRestockTargetStackLimits() { Runtime.RestockTargetStackLimits = RestockTargetLimitCore.Parse(_restockTargetStackLimitsConfig?.Value); } private static void RestockFromContainer(Player localPlayer, Inventory playerInventory, Container container, RestockMode mode) { Player localPlayer2 = localPlayer; Inventory playerInventory2 = playerInventory; if (!((Object)(object)localPlayer2 == (Object)null) && playerInventory2 != null && !((Object)(object)container == (Object)null) && container.m_inventory != null) { bool includeArea = mode == RestockMode.AreaFavoriteRestock; List targets = playerInventory2.m_inventory.Where((ItemData item) => ShouldTakeStacksTarget(localPlayer2, playerInventory2, item, includeHotbar: false, mode)).ToList(); targets.Sort((ItemData a, ItemData b) => -CompareGridOrder(a.m_gridPos, b.m_gridPos)); InventoryGui instance = InventoryGui.instance; if (instance != null) { instance.SetupDragItem((ItemData)null, (Inventory)null, 0); } int moved = RunContainerTransferAcrossContainers(localPlayer2, container, includeArea, areaForQuickStack: false, (Container sourceContainer) => RestockTargetsFromContainer(playerInventory2, sourceContainer.m_inventory, targets, mode), delegate { playerInventory2.Changed(); }); ShowActionResult(localPlayer2, LocalizeUi("$inventoryslots_action_take_stacks", "Take stacks"), moved); } } private static bool ShouldTakeStacksTarget(Player player, Inventory inventory, ItemData item, bool includeHotbar, RestockMode mode) { if (mode != RestockMode.AreaFavoriteRestock) { return ShouldTakeMatchingStackItem(player, inventory, item, includeHotbar); } return ShouldRestockFavoriteItem(player, inventory, item); } private static bool ShouldRestockFavoriteItem(Player player, Inventory inventory, ItemData item) { //IL_0010: 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) if (item?.m_shared == null || !IsPlayerActionCell(inventory, item.m_gridPos, includeHotbar: true) || !IsFavoriteSlot(player, item.m_gridPos) || !CanUseContainerActionStacking(item)) { return false; } int restockTargetStack = GetRestockTargetStack(item); if (item.m_shared.m_maxStackSize > 1) { return item.m_stack < restockTargetStack; } return false; } private static bool ShouldTakeMatchingStackItem(Player player, Inventory inventory, ItemData item, bool includeHotbar) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (item?.m_shared != null && IsRegularActionItem(player, inventory, item, includeHotbar) && !IsFavoriteSlot(player, item.m_gridPos) && CanUseContainerActionStacking(item) && item.m_shared.m_maxStackSize > 1) { return item.m_stack < item.m_shared.m_maxStackSize; } return false; } private static int GetRestockTargetStack(ItemData item) { if (item?.m_shared != null) { return RestockTargetLimitCore.ResolveTargetStackLimit(Runtime.RestockTargetStackLimits, GetRestockTargetLookupTokens(item), item.m_shared.m_maxStackSize); } return 0; } [IteratorStateMachine(typeof(d__101))] private static IEnumerable GetRestockTargetLookupTokens(ItemData item) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__101(-2) { <>3__item = item }; } private static int RestockTargetsFromContainer(Inventory playerInventory, Inventory containerInventory, List targets, RestockMode mode) { if (containerInventory == null || targets.Count == 0) { return 0; } int num = 0; foreach (ItemData target in targets) { if (!playerInventory.m_inventory.Contains(target)) { continue; } int num2 = ((mode == RestockMode.AreaFavoriteRestock) ? GetRestockTargetStack(target) : target.m_shared.m_maxStackSize); int num3 = target.m_stack; int num4 = containerInventory.m_inventory.Count - 1; while (num4 >= 0 && num3 < num2) { ItemData val = containerInventory.m_inventory[num4]; if (CanRestockFromContainerItem(target, val)) { int num5 = Math.Min(num2 - num3, val.m_stack); if (num5 > 0) { int stack = val.m_stack; bool moveSucceeded = playerInventory.MoveItemToThis(containerInventory, val, num5, target.m_gridPos.x, target.m_gridPos.y); int num6 = CountMovedFromContainerSource(containerInventory, val, stack, num5, moveSucceeded); num3 += num6; num += num6; } } num4--; } } if (num > 0) { containerInventory.Changed(); } return num; } private static bool CanRestockFromContainerItem(ItemData target, ItemData source) { if (target?.m_shared != null && source?.m_shared != null && CanUseContainerActionStacking(target) && CanUseContainerActionStacking(source)) { return HasSameStackIdentity(target, source); } return false; } private static void SortCurrentContainer(Player? player) { if (!((Object)(object)player == (Object)null) && !player.m_isLoading && !((Object)(object)InventoryGui.instance == (Object)null)) { Container currentContainer = InventoryGui.instance.m_currentContainer; if ((Object)(object)currentContainer == (Object)null || currentContainer.m_inventory == null) { ShowActionResult(player, LocalizeUi("$inventoryslots_action_container", "Container"), 0); return; } if (!CanMutateContainerDirectly(currentContainer, allowLocalWithoutZNetView: true)) { ((Character)player).Message((MessageType)2, LocalizeUi("$inventoryslots_container_not_ready", "Container is not ready."), 0, (Sprite)null); return; } int moved = SortContainerInventory(currentContainer); ShowActionResult(player, LocalizeUi("$inventoryslots_action_sort", "Sort"), moved); } } private static int SortContainerInventory(Container container) { if ((Object)(object)container == (Object)null || container.m_inventory == null) { return 0; } List allInventorySlots = GetAllInventorySlots(container.m_inventory); return SortInventoryInternal(container.m_inventory, allInventorySlots, (ItemData item) => item?.m_shared != null); } private static void SortPlayerInventory(Player? player) { Player player2 = player; if ((Object)(object)player2 == (Object)null || player2.m_isLoading) { return; } Inventory inventory = GetPlayerInventory(player2); if (inventory != null) { List playerActionSlots = GetPlayerActionSlots(player2, inventory, includeHotbar: false, blockFavorites: true); HashSet allowedSet = new HashSet(playerActionSlots); InventoryGui instance = InventoryGui.instance; if (instance != null) { instance.SetupDragItem((ItemData)null, (Inventory)null, 0); } int moved = SortInventoryInternal(inventory, playerActionSlots, (ItemData item) => item?.m_shared != null && allowedSet.Contains(item.m_gridPos) && !IsFavoriteProtected(player2, inventory, item)); ShowActionResult(player2, LocalizeUi("$inventoryslots_action_sort_inventory", "Sort Inv"), moved); } } private static int SortInventoryInternal(Inventory inventory, List allowedSlots, Func shouldSort) { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: 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) //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (inventory == null || allowedSlots.Count == 0) { return 0; } List list = inventory.m_inventory.Where(shouldSort).ToList(); if (list.Count == 0) { return 0; } bool flag = MergeSortableStacks(list, inventory); int inventoryWidth = Mathf.Max(1, inventory.GetWidth()); Dictionary originalIndices = list.ToDictionary((ItemData item) => item, (ItemData item) => item.m_gridPos.y * inventoryWidth + item.m_gridPos.x); list.Sort((ItemData a, ItemData b) => CompareItemsForSort(a, b, originalIndices[a], originalIndices[b])); int num = 0; int num2 = Math.Min(list.Count, allowedSlots.Count); for (int i = 0; i < num2; i++) { if (list[i].m_gridPos != allowedSlots[i]) { num++; flag = true; list[i].m_gridPos = allowedSlots[i]; } } if (flag) { inventory.Changed(); } return num; } private static bool MergeSortableStacks(List toMerge, Inventory inventory) { bool result = false; foreach (List item in (from item in toMerge where item?.m_shared != null && item.m_stack < item.m_shared.m_maxStackSize && CanUseContainerActionStacking(item) group item by new { item.m_shared.m_name, item.m_quality, item.m_worldLevel } into grouping select grouping.ToList()).ToList()) { if (item.Count <= 1) { continue; } int num = item.Sum((ItemData item) => item.m_stack); int maxStackSize = item[0].m_shared.m_maxStackSize; foreach (ItemData item2 in item.ToList()) { if (num <= 0) { if (item2.m_stack != 0) { item2.m_stack = 0; result = true; } inventory.RemoveItem(item2); toMerge.Remove(item2); result = true; } else { int num2 = Math.Min(maxStackSize, num); if (item2.m_stack != num2) { item2.m_stack = num2; result = true; } num -= item2.m_stack; } } } return result; } private static int CompareItemsForSort(ItemData a, ItemData b, int aOriginalIndex, int bOriginalIndex) { int num = GetItemSortCategory(a).CompareTo(GetItemSortCategory(b)); if (num != 0) { return num; } num = string.Compare(GetLocalizedItemName(a), GetLocalizedItemName(b), StringComparison.OrdinalIgnoreCase); if (num != 0) { return num; } num = -a.m_quality.CompareTo(b.m_quality); if (num != 0) { return num; } num = -a.m_stack.CompareTo(b.m_stack); if (num == 0) { return aOriginalIndex.CompareTo(bOriginalIndex); } return num; } private static int GetItemSortCategory(ItemData item) { object obj; if (item == null) { obj = null; } else { SharedData shared = item.m_shared; obj = ((shared != null) ? ((object)(ItemType)(ref shared.m_itemType)).ToString() : null); } if (obj == null) { obj = ""; } switch ((string)obj) { case "OneHandedWeapon": case "TwoHandedWeapon": case "Torch": case "Tool": case "Shield": case "TwoHandedWeaponLeft": case "Bow": return 10; case "Ammo": case "AmmoNonEquipable": return 20; case "Chest": case "Legs": case "Helmet": case "Shoulder": case "Utility": return 30; case "Fish": case "Consumable": return 40; case "Material": return 50; case "Trophie": return 60; default: return 90; } } private static List GetPlayerActionSlots(Player player, Inventory inventory, bool includeHotbar, bool blockFavorites = false) { //IL_0041: 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_004c: Unknown result type (might be due to invalid IL or missing references) List list = new List(); int num = Math.Min(4, inventory.GetHeight()); EnsureFavoritesLoaded(player); Vector2i val = default(Vector2i); for (int i = 0; i < num; i++) { for (int j = 0; j < inventory.GetWidth(); j++) { ((Vector2i)(ref val))..ctor(j, i); if ((!blockFavorites || !Runtime.FavoriteSlots.Contains(val)) && IsPlayerActionCell(inventory, val, includeHotbar)) { list.Add(val); } } } return list; } private static List GetAllInventorySlots(Inventory inventory) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) List list = new List(); for (int i = 0; i < inventory.GetHeight(); i++) { for (int j = 0; j < inventory.GetWidth(); j++) { list.Add(new Vector2i(j, i)); } } return list; } private static bool TryGetActionContext(Player? player, out Player localPlayer, out Inventory playerInventory, out Container container, out Inventory containerInventory) { localPlayer = null; playerInventory = null; container = null; containerInventory = null; if ((Object)(object)player == (Object)null || player.m_isLoading || (Object)(object)InventoryGui.instance == (Object)null) { return false; } Container currentContainer = InventoryGui.instance.m_currentContainer; if ((Object)(object)currentContainer == (Object)null || currentContainer.m_inventory == null) { ShowActionResult(player, LocalizeUi("$inventoryslots_action_container", "Container"), 0); return false; } if (!CanMutateContainerDirectly(currentContainer, allowLocalWithoutZNetView: true)) { ((Character)player).Message((MessageType)2, LocalizeUi("$inventoryslots_container_not_ready", "Container is not ready."), 0, (Sprite)null); return false; } Inventory playerInventory2 = GetPlayerInventory(player); if (playerInventory2 == null) { return false; } localPlayer = player; playerInventory = playerInventory2; container = currentContainer; containerInventory = currentContainer.m_inventory; return true; } private static void HandleHoverActions(Player player) { if (InventoryGui.IsVisible() || ShouldBlockGlobalHotkeys(player)) { ResetContainerHold(Runtime.AreaQuickStackHold); ResetContainerHold(Runtime.AreaRestockHold); } else { HandleContainerHoldHotkey(player, Runtime.AreaQuickStackHold, IsContainerQuickStackShortcutHeld() && !IsContainerRestockShortcutHeld(), TryGetHoverQuickStackContext, TryQuickStackFromHoveredContainer); HandleContainerHoldHotkey(player, Runtime.AreaRestockHold, IsContainerRestockShortcutHeld(), TryGetHoverRestockContext, TryRestockFromHoveredContainer); } } private static void HandleContainerHoldHotkey(Player player, ContainerHoldActionState hold, bool shortcutHeld, Func getContext, Func executeAction) { Container val = (shortcutHeld ? getContext(player) : null); if ((Object)(object)val == (Object)null) { ResetContainerHold(hold); return; } if (IsUnityNull((Object?)(object)hold.Container) || (Object)(object)hold.Container != (Object)(object)val) { hold.Container = val; hold.StartTime = Time.time; hold.Triggered = false; } if (!hold.Triggered && !(Time.time - hold.StartTime < Mathf.Clamp(_containerHoverHoldDuration.Value, 0.1f, 0.5f))) { if (executeAction(player, val)) { hold.Triggered = true; } else { ResetContainerHold(hold); } } } private static void ResetContainerHold(ContainerHoldActionState hold) { hold.Container = null; hold.StartTime = -1f; hold.Triggered = false; } private static Container? TryGetHoverQuickStackContext(Player player) { Container hoveredContainer = GetHoveredContainer(player); if ((Object)(object)hoveredContainer == (Object)null || player.m_isLoading || hoveredContainer.m_inventory == null || !CanHandleContainerAction(player, hoveredContainer)) { return null; } return hoveredContainer; } private static Container? TryGetHoverRestockContext(Player player) { Container hoveredContainer = GetHoveredContainer(player); if ((Object)(object)hoveredContainer == (Object)null || !CanHandleContainerAction(player, hoveredContainer)) { return null; } return hoveredContainer; } private static bool TryQuickStackFromHoveredContainer(Player player, Container container) { Inventory playerInventory = GetPlayerInventory(player); if (playerInventory == null || !CanHandleContainerAction(player, container)) { return false; } QuickStackIntoContainers(player, playerInventory, container, includeArea: true); return true; } private static bool TryRestockFromHoveredContainer(Player player, Container container) { Inventory playerInventory = GetPlayerInventory(player); if (playerInventory == null || !CanHandleContainerAction(player, container)) { return false; } RestockFromContainer(player, playerInventory, container, RestockMode.AreaFavoriteRestock); return true; } private static Container? GetHoveredContainer(Player player) { GameObject val = (((Object)(object)player != (Object)null) ? ((Humanoid)player).GetHoverObject() : null); if (!IsUnityNull((Object?)(object)val)) { return val.GetComponentInParent(); } return null; } internal static bool ShouldSuppressContainerInteractForRestock(Container container, Humanoid character) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)character != (Object)(object)localPlayer || InventoryGui.IsVisible() || !IsContainerRestockShortcutHeld()) { return false; } if ((Object)(object)GetHoveredContainer(localPlayer) == (Object)(object)container) { return CanHandleContainerAction(localPlayer, container); } return false; } internal static void AppendContainerActionHoverText(Container container, ref string text) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !localPlayer.m_isLoading && !string.IsNullOrWhiteSpace(text) && CanHandleContainerAction(localPlayer, container)) { string containerRestockKeyDisplayText = GetContainerRestockKeyDisplayText(); if (!string.IsNullOrWhiteSpace(containerRestockKeyDisplayText)) { text = text + "\n[" + containerRestockKeyDisplayText + "] (" + LocalizeUi("$inventoryslots_hold_to_restock", "Hold to restock") + ")"; } } } internal static void RegisterContainer(Container container) { if ((Object)(object)container != (Object)null && !Runtime.KnownContainers.Contains(container)) { Runtime.KnownContainers.Add(container); } } internal static void UnregisterContainer(Container container) { if ((Object)(object)container != (Object)null) { Runtime.KnownContainers.Remove(container); } } private static int RunContainerTransferAcrossContainers(Player localPlayer, Container anchorContainer, bool includeArea, bool areaForQuickStack, Func transfer, Action onMoved) { if ((Object)(object)localPlayer == (Object)null || (Object)(object)anchorContainer == (Object)null || transfer == null) { return 0; } IList obj = (includeArea ? ((IList)GetActionContainers(localPlayer, anchorContainer, areaForQuickStack)) : ((IList)new List { anchorContainer })); int num = (includeArea ? GetContainerActionSuccessFxMode() : 0); int played = 0; int num2 = 0; foreach (Container item in (List)obj) { if (!((Object)(object)item == (Object)null) && !IsUnityNull((Object?)(object)item) && item.m_inventory != null) { int num3 = transfer(item); if (num3 > 0) { num2 += num3; played = TryPlayChangedContainerActionSuccessFx(localPlayer, item, num, played); } } } if (num2 > 0) { onMoved?.Invoke(); if (num == 1) { PlayContainerActionSuccessFx(localPlayer, anchorContainer); } } return num2; } private static bool IsContainerQuickStackShortcutHeld() { if (!ZInput.GetButton("Use")) { return ZInput.GetButton("JoyUse"); } return true; } private static bool IsContainerRestockShortcutHeld() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (_containerRestockKey != null) { KeyboardShortcut value = _containerRestockKey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey != 0) { return IsShortcutHeldAllowingAltPair(_containerRestockKey.Value); } } return false; } private static string GetContainerRestockKeyDisplayText() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (_containerRestockKey == null) { return ""; } return GetShortcutDisplayText(_containerRestockKey.Value); } private static List GetActionContainers(Player player, Container currentContainer, bool areaForQuickStack) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) List list = new List(); HashSet hashSet = new HashSet(); if ((Object)(object)currentContainer != (Object)null && currentContainer.m_inventory != null && hashSet.Add(currentContainer)) { list.Add(currentContainer); } float num = (areaForQuickStack ? _areaQuickStackRange.Value : _areaRestockRange.Value); if (num <= 0f || (Object)(object)currentContainer == (Object)null || IsUnityNull((Object?)(object)currentContainer)) { return list; } Vector3 position = ((Component)currentContainer).transform.position; float rangeSq = num * num; List<(Container, float)> list2 = new List<(Container, float)>(); for (int num2 = Runtime.KnownContainers.Count - 1; num2 >= 0; num2--) { Container val = Runtime.KnownContainers[num2]; float distanceSq; if ((Object)(object)val == (Object)null || IsUnityNull((Object?)(object)val)) { Runtime.KnownContainers.RemoveAt(num2); } else if (!hashSet.Contains(val) && IsAreaContainerAllowed(player, val, currentContainer, position, rangeSq, out distanceSq)) { list2.Add((val, distanceSq)); hashSet.Add(val); } } list2.Sort(((Container Container, float DistanceSq) left, (Container Container, float DistanceSq) right) => left.DistanceSq.CompareTo(right.DistanceSq)); foreach (var item2 in list2) { Container item = item2.Item1; list.Add(item); } return list; } private static bool CanHandleContainerAction(Player player, Container container) { if ((Object)(object)player != (Object)null && !player.m_isLoading && (Object)(object)container != (Object)null && container.m_inventory != null && CanMutateContainerDirectly(container, allowLocalWithoutZNetView: true)) { return HasContainerPlayerAccess(player, container, flashGuardStone: false); } return false; } private static bool IsAreaContainerAllowed(Player player, Container container, Container? currentContainer, Vector3 origin, float rangeSq, out float distanceSq) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) distanceSq = float.MaxValue; if ((Object)(object)player == (Object)null || (Object)(object)container == (Object)null || (Object)(object)container == (Object)(object)currentContainer || container.m_inventory == null || (Object)(object)container.m_nview == (Object)null || !container.m_nview.IsValid() || !container.m_nview.IsOwner()) { return false; } Vector3 val = ((Component)container).transform.position - origin; distanceSq = ((Vector3)(ref val)).sqrMagnitude; if (distanceSq > rangeSq) { return false; } if ((Object)(object)((Component)container).GetComponent() != (Object)null || (Object)(object)((Component)container).GetComponentInParent() != (Object)null || (Object)(object)((Component)container.m_nview).GetComponent() != (Object)null || (Object)(object)((Component)((Component)container).transform.root).GetComponentInChildren() != (Object)null) { return false; } if ((Object)(object)container.m_piece != (Object)null && !container.m_piece.IsPlacedByPlayer()) { return false; } if (!IsContainerInUse(container)) { return HasContainerPlayerAccess(player, container, flashGuardStone: true); } return false; } private static bool HasContainerPlayerAccess(Player player, Container container, bool flashGuardStone) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)container == (Object)null) { return false; } if (container.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)container).transform.position, 0f, flashGuardStone, false)) { return false; } return container.CheckAccess(player.GetPlayerID()); } private static bool IsContainerInUse(Container container) { if ((Object)(object)container == (Object)null) { return true; } if (container.IsInUse() || ((Object)(object)container.m_wagon != (Object)null && container.m_wagon.InUse())) { return true; } ZDO val = (((Object)(object)container.m_nview != (Object)null) ? container.m_nview.GetZDO() : null); if (val != null) { return val.GetInt("InUse", 0) == 1; } return false; } private static bool CanMutateContainerDirectly(Container container, bool allowLocalWithoutZNetView = false) { if ((Object)(object)container == (Object)null) { return false; } if ((Object)(object)container.m_nview == (Object)null || !container.m_nview.IsValid()) { return allowLocalWithoutZNetView; } return container.m_nview.IsOwner(); } private static int GetContainerActionSuccessFxMode() { return Mathf.Clamp((_containerActionSuccessFxMode == null) ? 1 : _containerActionSuccessFxMode.Value, 0, 12); } private static float GetContainerActionSuccessFxVolume() { return Mathf.Clamp01((_containerActionSuccessFxVolume != null) ? _containerActionSuccessFxVolume.Value : 1f); } private static int TryPlayChangedContainerActionSuccessFx(Player player, Container container, int mode, int played) { if (mode < 2 || played >= mode) { return played; } PlayContainerActionSuccessFx(player, container); return played + 1; } private static void PlayContainerActionSuccessFx(Player player, Container container) { //IL_0059: 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) if (!((Object)(object)player == (Object)null) && !IsUnityNull((Object?)(object)player) && !((Object)(object)container == (Object)null) && !IsUnityNull((Object?)(object)container) && !((Object)(object)ZNetScene.instance == (Object)null)) { GameObject prefab = ZNetScene.instance.GetPrefab("fx_HildirChest_Unlock"); if (!((Object)(object)prefab == (Object)null) && !IsUnityNull((Object?)(object)prefab)) { ApplyContainerActionSuccessFxVolume(Object.Instantiate(prefab, ((Component)container).transform.position, ((Component)container).transform.rotation)); } } } private static void ApplyContainerActionSuccessFxVolume(GameObject instance) { float containerActionSuccessFxVolume = GetContainerActionSuccessFxVolume(); if ((Object)(object)instance == (Object)null || IsUnityNull((Object?)(object)instance) || containerActionSuccessFxVolume >= 0.999f) { return; } Component[] componentsInChildren = instance.GetComponentsInChildren(true); foreach (Component val in componentsInChildren) { if ((Object)(object)val != (Object)null && !IsUnityNull((Object?)(object)val)) { ScaleSfxComponentVolume(val, containerActionSuccessFxVolume); } } } private static void ScaleSfxComponentVolume(Component component, float volumeScale) { Type type = ((object)component).GetType(); if (IsUnityAudioSource(type)) { ScaleUnityAudioSourceVolume(component, type, volumeScale); } else { if (!IsLikelySfxComponent(type)) { return; } SfxVolumeMemberCache sfxVolumeMemberCache = GetSfxVolumeMemberCache(type); FieldInfo[] fields = sfxVolumeMemberCache.Fields; foreach (FieldInfo fieldInfo in fields) { try { fieldInfo.SetValue(component, Mathf.Max(0f, (float)fieldInfo.GetValue(component) * volumeScale)); } catch { } } PropertyInfo[] properties = sfxVolumeMemberCache.Properties; foreach (PropertyInfo propertyInfo in properties) { try { propertyInfo.SetValue(component, Mathf.Max(0f, (float)propertyInfo.GetValue(component) * volumeScale)); } catch { } } } } private static SfxVolumeMemberCache GetSfxVolumeMemberCache(Type type) { if (SfxVolumeMembersByType.TryGetValue(type, out var value)) { return value; } value = new SfxVolumeMemberCache((from field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where field.FieldType == typeof(float) && IsSfxVolumeMemberName(field.Name) && !IsUnsupportedSfxVolumeMemberName(field.Name) select field).ToArray(), (from property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) where property.PropertyType == typeof(float) && property.CanRead && property.CanWrite && property.GetIndexParameters().Length == 0 && IsSfxVolumeMemberName(property.Name) && !IsUnsupportedSfxVolumeMemberName(property.Name) select property).ToArray()); SfxVolumeMembersByType[type] = value; return value; } private static bool IsLikelySfxComponent(Type type) { string name = type.Name; if (name.IndexOf("SFX", StringComparison.OrdinalIgnoreCase) < 0) { return name.IndexOf("Audio", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static bool IsSfxVolumeMemberName(string name) { if (name.IndexOf("volume", StringComparison.OrdinalIgnoreCase) < 0) { return name.IndexOf("vol", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static bool IsUnsupportedSfxVolumeMemberName(string name) { if (!string.Equals(name, "minVolume", StringComparison.OrdinalIgnoreCase)) { return string.Equals(name, "maxVolume", StringComparison.OrdinalIgnoreCase); } return true; } private static bool IsUnityAudioSource(Type type) { return string.Equals(type.FullName, "UnityEngine.AudioSource", StringComparison.Ordinal); } private static void ScaleUnityAudioSourceVolume(Component component, Type type, float volumeScale) { PropertyInfo property = type.GetProperty("volume", BindingFlags.Instance | BindingFlags.Public); if (property == null || !property.CanRead || !property.CanWrite) { return; } try { property.SetValue(component, Mathf.Max(0f, (float)property.GetValue(component) * volumeScale)); } catch { } } private static int MoveItemToInventoryTopFirst(Inventory sourceInventory, Inventory targetInventory, ItemData source) { //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) ItemData source2 = source; if (sourceInventory == null || targetInventory == null || source2?.m_shared == null || !sourceInventory.m_inventory.Contains(source2)) { return 0; } int num = 0; if (CanStackForTopFirstMove(source2)) { foreach (ItemData item in (from target in targetInventory.m_inventory where CanStackIntoTargetForTopFirstMove(target, source2) orderby target.m_gridPos.y, target.m_gridPos.x select target).ToList()) { if (!sourceInventory.m_inventory.Contains(source2) || source2.m_stack <= 0) { break; } int num2 = Math.Min(item.m_shared.m_maxStackSize - item.m_stack, source2.m_stack); if (num2 > 0) { int stack = source2.m_stack; bool moveSucceeded = targetInventory.MoveItemToThis(sourceInventory, source2, num2, item.m_gridPos.x, item.m_gridPos.y); num += CountMovedFromContainerSource(sourceInventory, source2, stack, num2, moveSucceeded); } } } foreach (Vector2i item2 in GetInventorySlotsTopFirst(targetInventory)) { if (!sourceInventory.m_inventory.Contains(source2) || source2.m_stack <= 0) { break; } if (targetInventory.GetItemAt(item2.x, item2.y) == null) { int stack2 = source2.m_stack; int stack3 = source2.m_stack; bool moveSucceeded2 = targetInventory.MoveItemToThis(sourceInventory, source2, stack3, item2.x, item2.y); int num3 = CountMovedFromContainerSource(sourceInventory, source2, stack2, stack3, moveSucceeded2); num += num3; if (num3 == 0) { break; } } } return num; } private static bool CanMoveItemToInventoryTopFirst(Inventory sourceInventory, Inventory targetInventory, ItemData source) { ItemData source2 = source; Inventory targetInventory2 = targetInventory; if (sourceInventory == null || targetInventory2 == null || source2?.m_shared == null || !sourceInventory.m_inventory.Contains(source2)) { return false; } if (CanStackForTopFirstMove(source2) && targetInventory2.m_inventory.Any((ItemData target) => CanStackIntoTargetForTopFirstMove(target, source2))) { return true; } return GetInventorySlotsTopFirst(targetInventory2).Any((Vector2i slot) => targetInventory2.GetItemAt(slot.x, slot.y) == null); } [IteratorStateMachine(typeof(d__150))] private static IEnumerable GetInventorySlotsTopFirst(Inventory inventory) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__150(-2) { <>3__inventory = inventory }; } private static bool CanStackForTopFirstMove(ItemData item) { if (item?.m_shared != null && item.m_shared.m_maxStackSize > 1) { return CanUseContainerActionStacking(item); } return false; } private static bool CanStackIntoTargetForTopFirstMove(ItemData target, ItemData source) { if (target?.m_shared != null && source?.m_shared != null && CanStackForTopFirstMove(target) && CanStackForTopFirstMove(source) && HasSameStackIdentity(target, source)) { return target.m_stack < target.m_shared.m_maxStackSize; } return false; } private static bool HasSameStackIdentity(ItemData left, ItemData right) { if (left?.m_shared != null && right?.m_shared != null && string.Equals(left.m_shared.m_name, right.m_shared.m_name, StringComparison.OrdinalIgnoreCase) && left.m_quality == right.m_quality) { return (float)left.m_worldLevel == (float)right.m_worldLevel; } return false; } private static string GetItemPrefabName(ItemData item) { return RestockTargetLimitCore.CleanPrefabNameForLookup(((Object)(object)item?.m_dropPrefab != (Object)null) ? ((Object)item.m_dropPrefab).name : ""); } private static int CountMovedFromContainerSource(Inventory sourceInventory, ItemData sourceItem, int before, int requestedAmount, bool moveSucceeded) { int num = (sourceInventory.m_inventory.Contains(sourceItem) ? sourceItem.m_stack : 0); int num2 = Math.Max(0, before - num); if (!(num2 == 0 && moveSucceeded)) { return num2; } return requestedAmount; } private static int CompareGridOrder(Vector2i a, Vector2i b) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) int num = a.y.CompareTo(b.y); if (num == 0) { return a.x.CompareTo(b.x); } return num; } private static void DrawRestockTargetStackLimitsConfig(ConfigEntryBase entry) { string text = (entry.BoxedValue as string) ?? ""; if (!string.Equals(text, _restockTargetLimitEditorLastValue, StringComparison.Ordinal)) { RestockTargetLimitEditorRows.Clear(); RestockTargetLimitEditorRows.AddRange(ParseRestockTargetLimitEditorRows(text)); _restockTargetLimitEditorLastValue = text; } GUILayout.BeginVertical(Array.Empty()); for (int i = 0; i < RestockTargetLimitEditorRows.Count; i++) { RestockTargetLimitEditorRow restockTargetLimitEditorRow = RestockTargetLimitEditorRows[i]; GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label("Item", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(44f) }); string text2 = GUILayout.TextField(restockTargetLimitEditorRow.Item, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.MinWidth(130f) }); GUILayout.Label("Max", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(28f) }); string text3 = FilterUnsignedIntText(GUILayout.TextField(restockTargetLimitEditorRow.Amount, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) })); bool num = GUILayout.Button("-", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) }); GUILayout.EndHorizontal(); if (num) { RestockTargetLimitEditorRows.RemoveAt(i--); UpdateRestockTargetStackLimitsConfigEntry(entry); } else if (!string.Equals(text2, restockTargetLimitEditorRow.Item, StringComparison.Ordinal) || !string.Equals(text3, restockTargetLimitEditorRow.Amount, StringComparison.Ordinal)) { restockTargetLimitEditorRow.Item = text2; restockTargetLimitEditorRow.Amount = text3; UpdateRestockTargetStackLimitsConfigEntry(entry); } } GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) })) { RestockTargetLimitEditorRows.Add(new RestockTargetLimitEditorRow("", "")); UpdateRestockTargetStackLimitsConfigEntry(entry); } GUILayout.Label("Add restock limit", Array.Empty()); GUILayout.EndHorizontal(); GUILayout.EndVertical(); } private static List ParseRestockTargetLimitEditorRows(string raw) { List list = new List(); string[] array = raw.Replace("\r", "\n").Split(new char[3] { '\n', ',', ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length == 0) { continue; } int num = text.IndexOf('#'); if (num >= 0) { text = text.Substring(0, num).Trim(); } if (text.Length != 0) { int num2 = FindRestockTargetLimitEditorSeparator(text); if (num2 <= 0) { list.Add(new RestockTargetLimitEditorRow(text, "")); } else { list.Add(new RestockTargetLimitEditorRow(text.Substring(0, num2).Trim(), FilterUnsignedIntText(text.Substring(num2 + 1).Trim()))); } } } return list; } private static int FindRestockTargetLimitEditorSeparator(string entry) { int num = entry.IndexOf(':'); int num2 = entry.IndexOf('='); if (num < 0) { return num2; } if (num2 < 0) { return num; } return Math.Min(num, num2); } private static string FilterUnsignedIntText(string value) { if (!string.IsNullOrWhiteSpace(value)) { return new string(value.Where(char.IsDigit).ToArray()); } return ""; } private static void UpdateRestockTargetStackLimitsConfigEntry(ConfigEntryBase entry) { string text = (_restockTargetLimitEditorLastValue = SerializeRestockTargetLimitEditorRows()); if (!string.Equals((entry.BoxedValue as string) ?? "", text, StringComparison.Ordinal)) { entry.BoxedValue = text; } } private static string SerializeRestockTargetLimitEditorRows() { return string.Join("\n", from row in RestockTargetLimitEditorRows where !string.IsNullOrWhiteSpace(row.Item) || !string.IsNullOrWhiteSpace(row.Amount) select row.Item.Trim() + ": " + row.Amount.Trim()); } internal static void UpdateInventoryActionsUi(InventoryGui gui) { if ((Object)(object)gui == (Object)null || !InventoryGui.IsVisible()) { HideInventoryActionPanels(); return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.m_isLoading || (Object)(object)gui.m_playerGrid == (Object)null) { HideInventoryActionPanels(); return; } UpdateContainerActionButtons(gui); UpdatePlayerActionPanel(gui, gui.m_playerGrid, localPlayer); UpdateTrashPanel(gui, gui.m_playerGrid, localPlayer); UpdateFavoriteBorders(gui.m_playerGrid, localPlayer); } internal static void HideInventoryActionPanels() { SetActionPanelActive(Runtime.PlayerActionPanel, active: false); SetActionPanelActive(Runtime.TrashPanel, active: false); RestoreContainerActionButtonLayout(); SetButtonActive(Runtime.ContainerStoreAllButton, active: false); SetButtonActive(Runtime.ContainerRestockButton, active: false); SetButtonActive(Runtime.ContainerSortButton, active: false); CloseInventoryTrashConfirmDialog(); } private static void UpdateContainerActionButtons(InventoryGui gui) { //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected O, but got Unknown //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown if ((Object)(object)gui.m_currentContainer == (Object)null || (Object)(object)gui.m_takeAllButton == (Object)null || (Object)(object)gui.m_stackAllButton == (Object)null) { RestoreContainerActionButtonLayout(); HideContainerActionButtons(); return; } Container currentContainer = gui.m_currentContainer; Transform transform = ((Component)gui.m_takeAllButton).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); Transform transform2 = ((Component)gui.m_stackAllButton).transform; RectTransform val2 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null); Transform obj = ((val != null) ? ((Transform)val).parent : null); RectTransform val3 = (RectTransform)(object)((obj is RectTransform) ? obj : null); Transform obj2 = ((val2 != null) ? ((Transform)val2).parent : null); RectTransform val4 = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null) { RestoreContainerActionButtonLayout(); HideContainerActionButtons(); return; } CaptureRectTransformSnapshot(ref Runtime.TakeAllButtonOriginal, val); CaptureRectTransformSnapshot(ref Runtime.StackAllButtonOriginal, val2); RestoreContainerActionButtonLayout(); SetActionButtonLabel(gui.m_takeAllButton, LocalizeUi("$inventoryslots_button_take_all", "Take all")); SetActionButtonLabel(gui.m_stackAllButton, LocalizeUi("$inventoryslots_button_place_stacks", "Place stacks")); if (!CanMutateContainerDirectly(currentContainer, allowLocalWithoutZNetView: true)) { HideContainerActionButtons(); return; } AlignContainerActionButtonRows(val, val2); float buttonHeight = Mathf.Clamp(Mathf.Max(GetRectHeight(val), GetRectHeight(val2)), 24f, 36f); float rectWidth = GetRectWidth(val); float rectWidth2 = GetRectWidth(val2); InventoryActionRuntimeState runtime = Runtime; Button takeAllButton = gui.m_takeAllButton; string label = LocalizeUi("$inventoryslots_button_place_all", "Place all"); object obj3 = <>c.<>9__177_0; if (obj3 == null) { UnityAction val5 = delegate { StoreAllToCurrentContainer(Player.m_localPlayer); }; <>c.<>9__177_0 = val5; obj3 = (object)val5; } runtime.ContainerStoreAllButton = EnsureActionButton(val3, takeAllButton, "InventoryActions_StoreAllButton", label, (UnityAction)obj3); LayoutButtonPair(val, Runtime.ContainerStoreAllButton, rectWidth, buttonHeight, 4f, addedButtonOnRight: true); SetTooltip(Runtime.ContainerStoreAllButton, LocalizeUi("$inventoryslots_button_place_all", "Place all"), "Move all non-favorited regular inventory items into the current container."); InventoryActionRuntimeState runtime2 = Runtime; Button stackAllButton = gui.m_stackAllButton; string label2 = LocalizeUi("$inventoryslots_button_take_stacks", "Take stacks"); object obj4 = <>c.<>9__177_1; if (obj4 == null) { UnityAction val6 = delegate { RestockFromCurrentContainer(Player.m_localPlayer); }; <>c.<>9__177_1 = val6; obj4 = (object)val6; } runtime2.ContainerRestockButton = EnsureActionButton(val4, stackAllButton, "InventoryActions_RestockButton", label2, (UnityAction)obj4); LayoutButtonPair(val2, Runtime.ContainerRestockButton, rectWidth2, buttonHeight, 4f, addedButtonOnRight: false); SetTooltip(Runtime.ContainerRestockButton, LocalizeUi("$inventoryslots_button_take_stacks", "Take stacks"), "Fill matching non-favorited partial stacks from the current container."); Runtime.ContainerSortButton = EnsureContainerSortButton(val2, gui.m_takeAllButton, buttonHeight); SetTooltip(Runtime.ContainerSortButton, LocalizeUi("$inventoryslots_action_sort", "Sort"), "Sort the current container."); SetButtonActive(Runtime.ContainerStoreAllButton, active: true); SetButtonActive(Runtime.ContainerRestockButton, active: true); SetButtonActive(Runtime.ContainerSortButton, active: true); SetButtonInteractable(Runtime.ContainerStoreAllButton, interactable: true); SetButtonInteractable(Runtime.ContainerRestockButton, interactable: true); SetButtonInteractable(Runtime.ContainerSortButton, interactable: true); } private static void AlignContainerActionButtonRows(RectTransform takeAllRect, RectTransform stackAllRect) { //IL_0014: 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_0031: 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_0047: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)takeAllRect == (Object)null) && !((Object)(object)stackAllRect == (Object)null)) { float num = Mathf.Max(((Transform)takeAllRect).localPosition.y, ((Transform)stackAllRect).localPosition.y); ((Transform)takeAllRect).localPosition = new Vector3(((Transform)takeAllRect).localPosition.x, num, ((Transform)takeAllRect).localPosition.z); ((Transform)stackAllRect).localPosition = new Vector3(((Transform)stackAllRect).localPosition.x, num, ((Transform)stackAllRect).localPosition.z); } } private static void UpdatePlayerActionPanel(InventoryGui gui, InventoryGrid playerGrid, Player player) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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_0111: Expected O, but got Unknown if ((Object)(object)playerGrid.m_gridRoot == (Object)null || (Object)(object)gui.m_takeAllButton == (Object)null) { SetActionPanelActive(Runtime.PlayerActionPanel, active: false); return; } Runtime.PlayerActionPanel = EnsureActionPanel(playerGrid.m_gridRoot, "InventoryActions_PlayerActionPanel", Runtime.PlayerActionPanel); if ((Object)(object)Runtime.PlayerActionPanel == (Object)null) { return; } float containerSortButtonSize = GetContainerSortButtonSize(gui); int displayedPlayerRows = GetDisplayedPlayerRows(playerGrid); Runtime.PlayerActionPanel.sizeDelta = new Vector2(containerSortButtonSize, containerSortButtonSize); ((Transform)Runtime.PlayerActionPanel).localScale = Vector3.one; ((Transform)Runtime.PlayerActionPanel).localRotation = Quaternion.identity; Vector3 inventorySortPanelPosition = GetInventorySortPanelPosition(playerGrid, containerSortButtonSize, displayedPlayerRows); ((Transform)Runtime.PlayerActionPanel).localPosition = inventorySortPanelPosition; DisableActionPanelChildren(Runtime.PlayerActionPanel); RectTransform? playerActionPanel = Runtime.PlayerActionPanel; Button takeAllButton = gui.m_takeAllButton; object obj = <>c.<>9__179_0; if (obj == null) { UnityAction val = delegate { SortPlayerInventory(Player.m_localPlayer); }; <>c.<>9__179_0 = val; obj = (object)val; } Button? button = EnsureActionButton(playerActionPanel, takeAllButton, "InventoryActions_PlayerSortButton", "S", (UnityAction)obj); LayoutActionButton(button, 0, containerSortButtonSize, containerSortButtonSize, 6f); SetTooltip(button, "Sort inventory", "Sort non-favorited player inventory slots outside the hotbar."); SetActionPanelActive(Runtime.PlayerActionPanel, active: true); } private static void UpdateTrashPanel(InventoryGui gui, InventoryGrid playerGrid, Player player) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0120: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown if (!_enableInventoryTrashPanel.Value.IsOn() || (Object)(object)gui == (Object)null || (Object)(object)playerGrid == (Object)null || (Object)(object)playerGrid.m_gridRoot == (Object)null || (Object)(object)gui.m_takeAllButton == (Object)null || !InventoryGui.IsVisible()) { SetActionPanelActive(Runtime.TrashPanel, active: false); return; } Runtime.TrashPanel = EnsureActionPanel(playerGrid.m_gridRoot, "InventoryActions_TrashPanel", Runtime.TrashPanel); if (!((Object)(object)Runtime.TrashPanel == (Object)null)) { float num = Mathf.Max(1f, playerGrid.m_elementSpace); float num2 = Mathf.Clamp(num * 0.72f, 42f, 58f); Runtime.TrashPanel.sizeDelta = new Vector2(num2, num2); ((Transform)Runtime.TrashPanel).localScale = Vector3.one; ((Transform)Runtime.TrashPanel).localRotation = Quaternion.identity; int displayedPlayerRows = GetDisplayedPlayerRows(playerGrid); float containerSortButtonSize = GetContainerSortButtonSize(gui); Vector3 inventorySortPanelPosition = GetInventorySortPanelPosition(playerGrid, containerSortButtonSize, displayedPlayerRows); Vector3 gridOrigin = GetGridOrigin(playerGrid); ((Transform)Runtime.TrashPanel).localPosition = gridOrigin + new Vector3(inventorySortPanelPosition.x - gridOrigin.x + (containerSortButtonSize - num2) * 0.5f, (float)(-Mathf.Max(1, displayedPlayerRows)) * num - 8f, 0f); DisableActionPanelChildren(Runtime.TrashPanel); RectTransform? trashPanel = Runtime.TrashPanel; Button takeAllButton = gui.m_takeAllButton; object obj = <>O.<8>__TryClickInventoryTrashPanel; if (obj == null) { UnityAction val = TryClickInventoryTrashPanel; <>O.<8>__TryClickInventoryTrashPanel = val; obj = (object)val; } Button val2 = EnsureActionButton(trashPanel, takeAllButton, "InventoryActions_TrashButton", "", (UnityAction)obj); RectTransform val3 = LayoutActionButton(val2, 0, num2, num2, 0f); if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null) { ConfigureInventoryTrashButton(val2, num2); bool canTrash = CanStartInventoryTrash(gui, player, showMessage: false); SetButtonInteractable(val2, HasHeldTrashCandidate(gui)); SetInventoryTrashButtonVisual(val2, canTrash); } SetActionPanelActive(Runtime.TrashPanel, active: true); if ((Object)(object)((Transform)Runtime.TrashPanel).parent != (Object)null && ((Transform)Runtime.TrashPanel).GetSiblingIndex() != ((Transform)Runtime.TrashPanel).parent.childCount - 1) { ((Transform)Runtime.TrashPanel).SetAsLastSibling(); } } } private static Vector3 GetGridOrigin(InventoryGrid grid) { //IL_0009: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) if ((Object)(object)grid == (Object)null) { return Vector3.zero; } Transform transform = ((Component)grid).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val != null) { float num = ((grid.m_inventory != null) ? grid.m_inventory.GetWidth() : grid.m_width); Rect rect = val.rect; return new Vector3(((Rect)(ref rect)).width / 2f - num * grid.m_elementSpace / 2f, 0f, 0f); } return new Vector3((float)(-(((grid.m_inventory != null) ? grid.m_inventory.GetWidth() : 8) - 1)) * grid.m_elementSpace * 0.5f, 0f, 0f); } private static int GetDisplayedPlayerRows(InventoryGrid playerGrid) { return Mathf.Max(1, Math.Min(4, (playerGrid.m_inventory != null) ? playerGrid.m_inventory.GetHeight() : 4)); } private static int GetInventoryGridWidth(InventoryGrid playerGrid) { return Mathf.Max(1, (playerGrid.m_inventory != null) ? playerGrid.m_inventory.GetWidth() : 8); } private static Vector3 GetInventorySortPanelPosition(InventoryGrid playerGrid, float buttonSize, int rows) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_004c: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(1f, playerGrid.m_elementSpace); return GetGridOrigin(playerGrid) + new Vector3((float)GetInventoryGridWidth(playerGrid) * num + 1f, (float)(-Mathf.Max(1, rows)) * num + buttonSize, 0f) + Vector2.op_Implicit(InventorySortButtonFixedOffset); } private static void LayoutButtonPair(RectTransform vanillaButton, Button? addedButton, float originalWidth, float buttonHeight, float gap, bool addedButtonOnRight) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)vanillaButton == (Object)null) && !((Object)(object)addedButton == (Object)null)) { RectTransform val = (RectTransform)((Component)addedButton).transform; CopyRectTransformFrame(vanillaButton, val); float num = Mathf.Max(1f, (originalWidth - gap) * 0.5f); float num2 = (num + gap) * 0.5f; Vector3 localPosition = ((Transform)vanillaButton).localPosition; Vector3 localPosition2 = localPosition + new Vector3(addedButtonOnRight ? (0f - num2) : num2, 0f, 0f); Vector3 localPosition3 = localPosition + new Vector3(addedButtonOnRight ? num2 : (0f - num2), 0f, 0f); LayoutButtonRect(vanillaButton, num, buttonHeight, localPosition2); LayoutButtonRect(val, num, buttonHeight, localPosition3); } } private static Button? EnsureContainerSortButton(RectTransform stackButton, Button template, float buttonHeight) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_0086: Unknown result type (might be due to invalid IL or missing references) Transform obj = ((stackButton != null) ? ((Transform)stackButton).parent : null); RectTransform val = (RectTransform)(((object)((obj is RectTransform) ? obj : null)) ?? ((object)/*isinst with value type is only supported in some contexts*/)); if ((Object)(object)val == (Object)null) { return null; } object obj2 = <>c.<>9__186_0; if (obj2 == null) { UnityAction val2 = delegate { SortCurrentContainer(Player.m_localPlayer); }; <>c.<>9__186_0 = val2; obj2 = (object)val2; } Button val3 = EnsureActionButton(val, template, "InventoryActions_ContainerSortButton", "S", (UnityAction)obj2); if ((Object)(object)val3 == (Object)null) { return null; } RectTransform val4 = (RectTransform)((Component)val3).transform; RectTransform val5 = (RectTransform)(((object)stackButton) ?? ((object)(RectTransform)((Component)template).transform)); CopyRectTransformFrame(val5, val4); LayoutButtonRect(val4, buttonHeight, buttonHeight, ((Transform)val5).localPosition + new Vector3(GetRectWidth(val5) * 0.5f + 1f + buttonHeight * 0.5f, 0f, 0f)); return val3; } private static void LayoutButtonRect(RectTransform rect, float width, float height, Vector3 localPosition) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) rect.sizeDelta = new Vector2(width, height); ((Transform)rect).localPosition = localPosition; ((Transform)rect).localScale = Vector3.one; ((Transform)rect).localRotation = Quaternion.identity; } private static RectTransform? LayoutActionButton(Button? button, int index, float buttonWidth, float buttonHeight, float gap) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown if ((Object)(object)button == (Object)null) { return null; } RectTransform val = (RectTransform)((Component)button).transform; val.anchorMin = new Vector2(0f, 1f); val.anchorMax = new Vector2(0f, 1f); val.pivot = new Vector2(0f, 1f); val.sizeDelta = new Vector2(buttonWidth, buttonHeight); val.anchoredPosition = new Vector2((float)index * (buttonWidth + gap), 0f); ((Transform)val).localScale = Vector3.one; ((Transform)val).localRotation = Quaternion.identity; ((Component)button).gameObject.SetActive(true); return val; } private static Button? EnsureActionButton(RectTransform panel, Button template, string name, string label, UnityAction action) { Transform val = ((Transform)panel).Find(name); Button val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent