Implement stacking from open containers
This commit is contained in:
@@ -469,73 +469,18 @@ local function stackInventoryItems(inventory, itemTree)
|
||||
debugPrint("Completed stacking inventory items.")
|
||||
end
|
||||
|
||||
-- Find the currently open container - improved version
|
||||
-- This is a bit fucking sucky.....
|
||||
-- But I really don't know better
|
||||
-- Maybe it will be fine...
|
||||
---@return Barotrauma.ItemInventory
|
||||
local function getOpenContainer()
|
||||
debugPrint("Attempting to find open container...")
|
||||
|
||||
local openContainer = nil
|
||||
local hasVisibleInventory = false
|
||||
|
||||
-- Method 1: Try to use Inventory.CurrentInventory or similar properties
|
||||
pcall(function()
|
||||
if Inventory and Inventory.CurrentContainer and Inventory.CurrentContainer.Owner then
|
||||
openContainer = Inventory.CurrentContainer.Owner
|
||||
hasVisibleInventory = true
|
||||
debugPrint("Found open container via CurrentContainer: " .. openContainer.Name)
|
||||
for item in Item.ItemList do
|
||||
---@cast item Barotrauma.Item
|
||||
if item and item.OwnInventory then
|
||||
if item.OwnInventory.visualSlots and #item.OwnInventory.visualSlots > 0 then
|
||||
return item.OwnInventory
|
||||
end
|
||||
end)
|
||||
|
||||
if hasVisibleInventory and openContainer then return openContainer end
|
||||
|
||||
-- Method 2: Check if Inventory.OpenInventories exists and has entries
|
||||
pcall(function()
|
||||
if Inventory and Inventory.OpenInventories and #Inventory.OpenInventories > 0 then
|
||||
-- Get the last opened inventory
|
||||
for _, inv in ipairs(Inventory.OpenInventories) do
|
||||
if inv and inv.Owner and inv.Owner ~= Character.Controlled then
|
||||
openContainer = inv.Owner
|
||||
hasVisibleInventory = true
|
||||
debugPrint("Found open container via OpenInventories: " .. openContainer.Name)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if hasVisibleInventory and openContainer then return openContainer end
|
||||
|
||||
-- Method 3: Check if currently selected item is interacting with a container
|
||||
pcall(function()
|
||||
if Character.Controlled and Character.Controlled.SelectedItem then
|
||||
local selectedItem = Character.Controlled.SelectedItem
|
||||
-- Check if selected item is interacting with something
|
||||
if selectedItem.InteractingWith and selectedItem.InteractingWith.OwnInventory and
|
||||
selectedItem.InteractingWith ~= Character.Controlled then
|
||||
openContainer = selectedItem.InteractingWith
|
||||
hasVisibleInventory = true
|
||||
debugPrint("Found open container via current interaction: " .. openContainer.Name)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if hasVisibleInventory and openContainer then return openContainer end
|
||||
|
||||
-- For safety, add a visual check - only return a container if it has a visible UI element
|
||||
if openContainer then
|
||||
-- Verify this container actually has a visible UI
|
||||
local isVisible = false
|
||||
|
||||
pcall(function()
|
||||
-- Common method to check if inventory is visible - look for visual components
|
||||
if openContainer.OwnInventory and openContainer.OwnInventory.visualSlots and
|
||||
#openContainer.OwnInventory.visualSlots > 0 then
|
||||
isVisible = true
|
||||
end
|
||||
end)
|
||||
|
||||
if not isVisible then
|
||||
debugPrint("Container found but not visibly open in UI: " .. openContainer.Name)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -543,72 +488,6 @@ local function getOpenContainer()
|
||||
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
|
||||
|
||||
debugPrint("Stacking from open container: " .. openContainer.Name)
|
||||
|
||||
local itemsMoved = 0
|
||||
local openContainerInv = openContainer.OwnInventory
|
||||
|
||||
-- Create a cache of processable items to avoid redundant checks
|
||||
local itemsToProcess = {}
|
||||
local processedIdentifiers = {}
|
||||
|
||||
-- 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]
|
||||
local identifierValue = item.Prefab.Identifier.Value
|
||||
|
||||
-- Skip container items
|
||||
if item.OwnInventory then
|
||||
debugPrint("Skipping container item: " .. item.Name)
|
||||
goto nextItem
|
||||
end
|
||||
|
||||
-- Skip if we've already processed an item of this type
|
||||
if processedIdentifiers[identifierValue] then
|
||||
debugPrint("Already processed items of type: " .. identifierValue .. " from open container")
|
||||
goto nextItem
|
||||
end
|
||||
|
||||
table.insert(itemsToProcess, {
|
||||
item = item,
|
||||
slotIndex = slotIndex
|
||||
})
|
||||
|
||||
-- Mark identifier as scheduled for processing
|
||||
processedIdentifiers[identifierValue] = true
|
||||
|
||||
::nextItem::
|
||||
end
|
||||
end
|
||||
|
||||
-- Now process the collected items - this greatly reduces redundant container checks
|
||||
for _, itemData in ipairs(itemsToProcess) do
|
||||
local item = itemData.item
|
||||
|
||||
debugPrint("Processing item from container: " .. item.Name)
|
||||
|
||||
-- Try to move the item to each player container
|
||||
for _, container in ipairs(playerContainers) do
|
||||
debugPrint("Trying to stack " .. item.Name .. " into " .. container.Name)
|
||||
if moveItemToContainer(item, container.OwnInventory) then
|
||||
debugPrint("Stacked " .. item.Name .. " from open container into " .. container.Name)
|
||||
itemsMoved = itemsMoved + 1
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return itemsMoved
|
||||
end
|
||||
|
||||
-- We would like to fill larger stacks first
|
||||
---@param itemTree table<string, ItemLocation[]>
|
||||
---@return table<string, ItemLocation[]>
|
||||
@@ -642,6 +521,10 @@ local function quickStackItems(character)
|
||||
local itemTree = buildItemTree(inventory, {})
|
||||
itemTree = sortItemtreeBySlots(itemTree)
|
||||
stackInventoryItems(inventory, itemTree)
|
||||
local openContainerInventory = getOpenContainer()
|
||||
if openContainerInventory then
|
||||
stackInventoryItems(openContainerInventory, itemTree)
|
||||
end
|
||||
|
||||
-- Find all containers in player inventory, including nested ones
|
||||
-- local containers = findAllContainers(inventory, {})
|
||||
|
||||
Reference in New Issue
Block a user