Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of InventoryActions v1.0.0
InventoryActions.dll
Decompiled 5 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.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<ConfigEntryBase>? 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<ConfigEntryBase> <1>__DrawRestockTargetStackLimitsConfig; public static Func<KeyCode, string> <2>__GetShortcutKeyDisplayText; public static Func<Player, Container?> <3>__TryGetHoverQuickStackContext; public static Func<Player, Container, bool> <4>__TryQuickStackFromHoveredContainer; public static Func<Player, Container?> <5>__TryGetHoverRestockContext; public static Func<Player, Container, bool> <6>__TryRestockFromHoveredContainer; public static Func<char, bool> <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<char, bool> <>9__55_0; public static Func<string, bool> <>9__64_0; public static Func<Vector2i, int> <>9__72_0; public static Func<Vector2i, int> <>9__72_1; public static Func<Vector2i, string> <>9__72_2; public static Func<ItemData, bool> <>9__85_1; public static Func<ItemData, int> <>9__85_2; public static Func<ItemData, int> <>9__85_3; public static Func<ItemData, int> <>9__86_1; public static Func<ItemData, int> <>9__86_2; public static Comparison<ItemData> <>9__89_1; public static Func<ItemData, bool> <>9__91_0; public static Func<ItemData, string> <>9__91_1; public static Comparison<ItemData> <>9__92_1; public static Comparison<ItemData> <>9__96_1; public static Func<ItemData, bool> <>9__105_0; public static Func<ItemData, ItemData> <>9__107_0; public static Func<ItemData, bool> <>9__108_0; public static Func<ItemData, <>f__AnonymousType0<string, int, int>> <>9__108_1; public static Func<IGrouping<<>f__AnonymousType0<string, int, int>, ItemData>, List<ItemData>> <>9__108_2; public static Func<ItemData, int> <>9__108_3; public static Comparison<(Container Container, float DistanceSq)> <>9__130_0; public static Func<FieldInfo, bool> <>9__142_0; public static Func<PropertyInfo, bool> <>9__142_1; public static Func<ItemData, int> <>9__148_1; public static Func<ItemData, int> <>9__148_2; public static Func<RestockTargetLimitEditorRow, bool> <>9__165_0; public static Func<RestockTargetLimitEditorRow, string> <>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 <BindConfigs>b__40_0(object _, EventArgs _) { RefreshFavoriteBorders(); } internal void <BindConfigs>b__40_1(object _, EventArgs _) { RefreshRestockTargetStackLimits(); } internal bool <GetFavoriteFilePath>b__55_0(char ch) { bool flag = char.IsLetterOrDigit(ch); if (!flag) { bool flag2 = ((ch == '-' || ch == '_') ? true : false); flag = flag2; } return flag; } internal bool <GetShortcutDisplayText>b__64_0(string part) { return !string.IsNullOrWhiteSpace(part); } internal int <SaveFavorites>b__72_0(Vector2i slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return slot.y; } internal int <SaveFavorites>b__72_1(Vector2i slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return slot.x; } internal string <SaveFavorites>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 <SafeTakeAllItems>b__85_1(ItemData item) { return item?.m_shared != null; } internal int <SafeTakeAllItems>b__85_2(ItemData item) { return item.m_gridPos.y; } internal int <SafeTakeAllItems>b__85_3(ItemData item) { return item.m_gridPos.x; } internal int <MoveContainerItemSafelyToPlayer>b__86_1(ItemData target) { return target.m_gridPos.y; } internal int <MoveContainerItemSafelyToPlayer>b__86_2(ItemData target) { return target.m_gridPos.x; } internal int <QuickStackIntoContainers>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 <QuickStackItemsIntoContainer>b__91_0(ItemData item) { return item?.m_shared != null; } internal string <QuickStackItemsIntoContainer>b__91_1(ItemData item) { return item.m_shared.m_name; } internal int <StoreAllToCurrentContainer>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 <RestockFromContainer>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 <SortContainerInventory>b__105_0(ItemData item) { return item?.m_shared != null; } internal ItemData <SortInventoryInternal>b__107_0(ItemData item) { return item; } internal bool <MergeSortableStacks>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<string, int, int> <MergeSortableStacks>b__108_1(ItemData item) { return new { item.m_shared.m_name, item.m_quality, item.m_worldLevel }; } internal List<ItemData> <MergeSortableStacks>b__108_2(IGrouping<<>f__AnonymousType0<string, int, int>, ItemData> grouping) { return grouping.ToList(); } internal int <MergeSortableStacks>b__108_3(ItemData item) { return item.m_stack; } internal int <GetActionContainers>b__130_0((Container Container, float DistanceSq) left, (Container Container, float DistanceSq) right) { return left.DistanceSq.CompareTo(right.DistanceSq); } internal bool <GetSfxVolumeMemberCache>b__142_0(FieldInfo field) { if (field.FieldType == typeof(float) && IsSfxVolumeMemberName(field.Name)) { return !IsUnsupportedSfxVolumeMemberName(field.Name); } return false; } internal bool <GetSfxVolumeMemberCache>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 <MoveItemToInventoryTopFirst>b__148_1(ItemData target) { return target.m_gridPos.y; } internal int <MoveItemToInventoryTopFirst>b__148_2(ItemData target) { return target.m_gridPos.x; } internal bool <SerializeRestockTargetLimitEditorRows>b__165_0(RestockTargetLimitEditorRow row) { if (string.IsNullOrWhiteSpace(row.Item)) { return !string.IsNullOrWhiteSpace(row.Amount); } return true; } internal string <SerializeRestockTargetLimitEditorRows>b__165_1(RestockTargetLimitEditorRow row) { return row.Item.Trim() + ": " + row.Amount.Trim(); } internal void <UpdateContainerActionButtons>b__177_0() { StoreAllToCurrentContainer(Player.m_localPlayer); } internal void <UpdateContainerActionButtons>b__177_1() { RestockFromCurrentContainer(Player.m_localPlayer); } internal void <UpdatePlayerActionPanel>b__179_0() { SortPlayerInventory(Player.m_localPlayer); } internal void <EnsureContainerSortButton>b__186_0() { SortCurrentContainer(Player.m_localPlayer); } } [CompilerGenerated] private sealed class <GetInventorySlotsTopFirst>d__150 : IEnumerable<Vector2i>, IEnumerable, IEnumerator<Vector2i>, IDisposable, IEnumerator { private int <>1__state; private Vector2i <>2__current; private int <>l__initialThreadId; private Inventory inventory; public Inventory <>3__inventory; private int <width>5__2; private int <height>5__3; private int <y>5__4; private int <x>5__5; Vector2i IEnumerator<Vector2i>.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 <GetInventorySlotsTopFirst>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; <x>5__5++; goto IL_008e; } <>1__state = -1; <width>5__2 = Math.Max(1, inventory.GetWidth()); <height>5__3 = Math.Max(0, inventory.GetHeight()); <y>5__4 = 0; goto IL_00ac; IL_008e: if (<x>5__5 < <width>5__2) { <>2__current = new Vector2i(<x>5__5, <y>5__4); <>1__state = 1; return true; } <y>5__4++; goto IL_00ac; IL_00ac: if (<y>5__4 < <height>5__3) { <x>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<Vector2i> IEnumerable<Vector2i>.GetEnumerator() { <GetInventorySlotsTopFirst>d__150 <GetInventorySlotsTopFirst>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetInventorySlotsTopFirst>d__ = this; } else { <GetInventorySlotsTopFirst>d__ = new <GetInventorySlotsTopFirst>d__150(0); } <GetInventorySlotsTopFirst>d__.inventory = <>3__inventory; return <GetInventorySlotsTopFirst>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<Vector2i>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetRestockTargetLookupTokens>d__101 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IDisposable, IEnumerator { private int <>1__state; private string? <>2__current; private int <>l__initialThreadId; private ItemData item; public ItemData <>3__item; private string <sharedName>5__2; string IEnumerator<string>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRestockTargetLookupTokens>d__101(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <sharedName>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(<sharedName>5__2); <>1__state = 4; return true; case 4: <>1__state = -1; if (Localization.instance != null && !string.IsNullOrWhiteSpace(<sharedName>5__2)) { <>2__current = Localization.instance.Localize(<sharedName>5__2); <>1__state = 5; return true; } break; case 5: { <>1__state = -1; break; } IL_0091: <sharedName>5__2 = item.m_shared?.m_name ?? ""; <>2__current = <sharedName>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<string> IEnumerable<string>.GetEnumerator() { <GetRestockTargetLookupTokens>d__101 <GetRestockTargetLookupTokens>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetRestockTargetLookupTokens>d__ = this; } else { <GetRestockTargetLookupTokens>d__ = new <GetRestockTargetLookupTokens>d__101(0); } <GetRestockTargetLookupTokens>d__.item = <>3__item; return <GetRestockTargetLookupTokens>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<string>)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<Toggle> _serverConfigLocked = null; private static ConfigEntry<Toggle> _enableInventoryTrashPanel = null; private static ConfigEntry<float> _areaQuickStackRange = null; private static ConfigEntry<float> _areaRestockRange = null; private static ConfigEntry<Color> _favoriteBorderColor = null; private static ConfigEntry<float> _containerHoverHoldDuration = null; private static ConfigEntry<int> _containerActionSuccessFxMode = null; private static ConfigEntry<float> _containerActionSuccessFxVolume = null; private static ConfigEntry<KeyboardShortcut> _favoriteModifierKey = null; private static ConfigEntry<KeyboardShortcut> _containerRestockKey = null; private static ConfigEntry<string> _restockTargetStackLimitsConfig = null; private static readonly Color FavoriteBorderDefaultColor = new Color(0.1f, 0.55f, 1f, 0.95f); private static readonly Dictionary<Type, SfxVolumeMemberCache> SfxVolumeMembersByType = new Dictionary<Type, SfxVolumeMemberCache>(); private static readonly List<RestockTargetLimitEditorRow> RestockTargetLimitEditorRows = new List<RestockTargetLimitEditorRow>(); 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<Toggle>(_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<float>(0f, 50f), Array.Empty<object>())); _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<float>(0f, 50f), Array.Empty<object>())); _favoriteModifierKey = ConfigEntry<KeyboardShortcut>("2 - Client", "Favorite Modifier Key", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), 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<KeyboardShortcut>("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<Color>("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<float>(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<int>(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<float>(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<T> ConfigEntry<T>(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<object>()), synchronizedSetting); } private static ConfigEntry<T> ConfigEntry<T>(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<T> val2 = ((BaseUnityPlugin)_instance).Config.Bind<T>(group, name, value, val); ConfigSync.AddConfigEntry<T>(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<string> 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<InventoryGridElementMarker>() ?? element.m_go.AddComponent<InventoryGridElementMarker>(); if (inventoryGridElementMarker.FavoriteBorderImages.Length == 0) { inventoryGridElementMarker.FavoriteBorderImages = ((Component)val).GetComponentsInChildren<Image>(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<InventoryGridElementMarker>() ?? go.AddComponent<InventoryGridElementMarker>(); 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<RectTransform>() : 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<Image>(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<Image>()).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<InventoryGridElementMarker>(); 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<TombStone>(); 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<Vector2i> playerActionSlots = GetPlayerActionSlots(player, playerInventory2, includeHotbar: false, blockFavorites: true); HashSet<Vector2i> allowedSlots = new HashSet<Vector2i>(playerActionSlots); List<Vector2i> emptySlots = playerActionSlots.Where((Vector2i slot) => playerInventory2.GetItemAt(slot.x, slot.y) == null).ToList(); List<ItemData> 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<Vector2i> emptySlots, HashSet<Vector2i> 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<Vector2i> 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<ItemData> 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<ItemData> candidates) { if (containerInventory == null || candidates.Count == 0) { return 0; } HashSet<string> hashSet = new HashSet<string>(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<ItemData> 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<ItemData> 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(<GetRestockTargetLookupTokens>d__101))] private static IEnumerable<string?> GetRestockTargetLookupTokens(ItemData item) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetRestockTargetLookupTokens>d__101(-2) { <>3__item = item }; } private static int RestockTargetsFromContainer(Inventory playerInventory, Inventory containerInventory, List<ItemData> 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<Vector2i> 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<Vector2i> playerActionSlots = GetPlayerActionSlots(player2, inventory, includeHotbar: false, blockFavorites: true); HashSet<Vector2i> allowedSet = new HashSet<Vector2i>(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<Vector2i> allowedSlots, Func<ItemData, bool> 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<ItemData> 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<ItemData, int> 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<ItemData> toMerge, Inventory inventory) { bool result = false; foreach (List<ItemData> 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<Vector2i> 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<Vector2i> list = new List<Vector2i>(); 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<Vector2i> GetAllInventorySlots(Inventory inventory) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) List<Vector2i> list = new List<Vector2i>(); 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<Player, Container?> getContext, Func<Player, Container, bool> 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<Container>(); } 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[<color=yellow><b>" + containerRestockKeyDisplayText + "</b></color>] (" + 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<Container, int> 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<Container> { anchorContainer })); int num = (includeArea ? GetContainerActionSuccessFxMode() : 0); int played = 0; int num2 = 0; foreach (Container item in (List<Container>)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<Container> 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<Container> list = new List<Container>(); HashSet<Container> hashSet = new HashSet<Container>(); 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<TombStone>() != (Object)null || (Object)(object)((Component)container).GetComponentInParent<TombStone>() != (Object)null || (Object)(object)((Component)container.m_nview).GetComponent<Player>() != (Object)null || (Object)(object)((Component)((Component)container).transform.root).GetComponentInChildren<Ship>() != (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<GameObject>(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<Component>(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