diff --git a/QuickStackToBag/Lua/Autorun/init.lua b/QuickStackToBag/Lua/Autorun/init.lua index 2e5ce2c..78cadbd 100644 --- a/QuickStackToBag/Lua/Autorun/init.lua +++ b/QuickStackToBag/Lua/Autorun/init.lua @@ -2,8 +2,7 @@ if SERVER then return end -- Register necessary types and make fields accessible LuaUserData.RegisterType("Barotrauma.Items.Components.ItemContainer+SlotRestrictions") -LuaUserData.RegisterType( - 'System.Collections.Immutable.ImmutableArray`1[[Barotrauma.Items.Components.ItemContainer+SlotRestrictions, Barotrauma]]') +LuaUserData.RegisterType('System.Collections.Immutable.ImmutableArray`1[[Barotrauma.Items.Components.ItemContainer+SlotRestrictions, Barotrauma]]') LuaUserData.MakeFieldAccessible(Descriptors['Barotrauma.Items.Components.ItemContainer'], 'slotRestrictions') LuaUserData.MakeFieldAccessible(Descriptors['Barotrauma.ItemInventory'], 'slots') LuaUserData.MakeFieldAccessible(Descriptors["Barotrauma.CharacterInventory"], "slots") @@ -85,6 +84,90 @@ local function sortContainersByPriority(containers) return containers end +-- Recursively find all containers in the player's inventory, including nested ones +local function findAllContainers(inventory, containers) + if not inventory or not inventory.slots then return containers end + + containers = containers or {} + + for _, slot in ipairs(inventory.slots) do + for _, item in ipairs(slot.items) do + if item.OwnInventory then + -- Add this container + print("[QuickStack] Found container: " .. item.Name .. " (" .. item.Prefab.Identifier.Value .. ")") + table.insert(containers, item) + + -- Recursively search inside this container + findAllContainers(item.OwnInventory, containers) + end + end + end + + return containers +end + +-- Find the currently open container using the better approach with opened GUIs +local function getOpenContainer() + -- Check if any ItemContainer GUIs are open + for _, gui in pairs(GUI.OpenGuis) do + if gui.UserData ~= nil and gui.UserData.Inventory ~= nil then + -- Make sure it's not the player's inventory + if gui.UserData.Item ~= nil and gui.UserData.Item.Inventory ~= Character.Controlled.Inventory then + print("[QuickStack] Found open container: " .. gui.UserData.Item.Name) + return gui.UserData.Item + end + end + end + + -- Try an alternative approach using opened inventories + for _, inventory in pairs(ItemInventory.OpenInventories) do + if inventory.Owner ~= nil and inventory.Owner.Inventory ~= Character.Controlled.Inventory then + -- Found a non-player inventory + print("[QuickStack] Found open inventory: " .. inventory.Owner.Name) + return inventory.Owner + end + end + + print("[QuickStack] No open container found") + return nil +end + +-- Function to stack from open container to player containers +local function stackFromOpenContainer(character, playerContainers, openContainer) + if not character or not openContainer or not openContainer.OwnInventory then return 0 end + + print("[QuickStack] Stacking from open container: " .. openContainer.Name) + + local itemsMoved = 0 + local openContainerInv = openContainer.OwnInventory + + -- Process each slot in the open container + for slotIndex = 0, #openContainerInv.slots - 1 do + local slot = openContainerInv.slots[slotIndex + 1] + + -- Process items in the slot + for i = #slot.items, 1, -1 do + local item = slot.items[i] + + -- Skip container items + if item.OwnInventory then goto nextItem end + + -- Try to move the item to each player container + for _, container in ipairs(playerContainers) do + if moveItemToContainer(item, container.OwnInventory) then + print("[QuickStack] Stacked " .. item.Name .. " from open container into " .. container.Name) + itemsMoved = itemsMoved + 1 + break + end + end + + ::nextItem:: + end + end + + return itemsMoved +end + -- Function to quickly stack items from inventory to containers local function quickStackItems(character) if not character then return end @@ -93,20 +176,10 @@ local function quickStackItems(character) local inventory = character.Inventory if not inventory or not inventory.slots then return end - -- First identify all containers in inventory - local containers = {} + -- Find all containers in player inventory, including nested ones + local containers = findAllContainers(inventory, {}) - for slotIndex, slot in ipairs(inventory.slots) do - for _, item in ipairs(slot.items) do - -- Add to containers if it has its own inventory - if item.OwnInventory then - print("[QuickStack] Found container: " .. item.Name .. " (" .. item.Prefab.Identifier.Value .. ")") - table.insert(containers, item) - end - end - end - - print("[QuickStack] Found " .. #containers .. " containers") + print("[QuickStack] Found " .. #containers .. " containers (including nested)") if #containers == 0 then print("[QuickStack] No containers with inventory found!") return @@ -151,6 +224,13 @@ local function quickStackItems(character) ::continueSlot:: end + -- Check if there's an open container to stack from + local openContainer = getOpenContainer() + if openContainer then + local openContainerItemsMoved = stackFromOpenContainer(character, containers, openContainer) + itemsMoved = itemsMoved + openContainerItemsMoved + end + if itemsMoved > 0 then print("[QuickStack] Stacked " .. itemsMoved .. " items into containers") else