Completely rework the stacking to be a little more better
This commit is contained in:
@@ -115,6 +115,94 @@ local function moveItemsTo(slot, itemLocation)
|
||||
end
|
||||
end
|
||||
|
||||
---@param item Barotrauma.Item
|
||||
---@param itemTree table<string, ItemLocation[]>
|
||||
---@return string
|
||||
local function tryMoveItem(item, itemTree)
|
||||
local location = itemTree[item.Prefab.Identifier.Value]
|
||||
if not location then return nil, "No locations for item, not stacking" end
|
||||
|
||||
local moved = false
|
||||
-- First try to move to existing stacks
|
||||
for _, itemLocation in ipairs(location) do
|
||||
if itemLocation.maxFits > 0 then
|
||||
moved = moved or itemLocation.inventory.TryPutItem(item, itemLocation.slotIndex, false, true, nil)
|
||||
itemLocation.maxFits = itemLocation.inventory.HowManyCanBePut(item.Prefab, itemLocation.slotIndex)
|
||||
end
|
||||
end
|
||||
|
||||
-- If we can not find an existing stack
|
||||
-- Then move to any of the empty slots
|
||||
if not moved then
|
||||
for _, itemLocation in ipairs(itemTree['empty']) do
|
||||
moved = moved or itemLocation.inventory.TryPutItem(item, itemLocation.slotIndex, false, true, nil)
|
||||
itemLocation.maxFits = itemLocation.inventory.HowManyCanBePut(item.Prefab, itemLocation.slotIndex)
|
||||
end
|
||||
end
|
||||
|
||||
-- If we still can not move the item give up
|
||||
if not moved then return "Failed to find valid location for item" end
|
||||
return nil
|
||||
end
|
||||
|
||||
---@param items Barotrauma.Item[]
|
||||
---@param itemTree table<string, ItemLocation[]>
|
||||
---@return string[]
|
||||
local function tryMoveItems(items, itemTree)
|
||||
local errs = {}
|
||||
for _, item in ipairs(items) do
|
||||
local err = tryMoveItem(item, itemTree)
|
||||
-- oops, this one failed, continue...
|
||||
if err then
|
||||
errs[#errs + 1] = string.format("Failed to move item: %s", item.Prefab.Identifier.Value)
|
||||
end
|
||||
end
|
||||
return errs
|
||||
end
|
||||
|
||||
---@param item Barotrauma.Item
|
||||
---@param queue Barotrauma.Item[]
|
||||
---@return Barotrauma.Item[], string
|
||||
local function enqueueItem(item, queue)
|
||||
queue = queue or {}
|
||||
queue[#queue + 1] = item
|
||||
return queue
|
||||
end
|
||||
|
||||
---@param slot Barotrauma.ItemInventory.Slot
|
||||
---@param queue Barotrauma.Item[]
|
||||
---@return Barotrauma.Item[], string
|
||||
local function enqueueSlot(slot, queue)
|
||||
queue = queue or {}
|
||||
-- We don't want to shadow queue
|
||||
local err
|
||||
-- If the slot is empty there's nothing to iterate
|
||||
-- And we will naturally return queue as is
|
||||
for _, item in ipairs(slot.items) do
|
||||
queue, err = enqueueItem(item, queue)
|
||||
if err then
|
||||
print("Error enqueuing item: " .. err)
|
||||
end
|
||||
end
|
||||
return queue
|
||||
end
|
||||
|
||||
---@param inventory Barotrauma.ItemInventory
|
||||
---@param queue Barotrauma.Item[]
|
||||
---@return Barotrauma.Item[], string[]
|
||||
local function enqueueInventory(inventory, queue)
|
||||
queue = queue or {}
|
||||
-- We don't want to shadow queue
|
||||
local err
|
||||
for _, slot in ipairs(inventory.slots) do
|
||||
queue, err = enqueueSlot(slot, queue)
|
||||
if err then
|
||||
print("Error enqueuing slot: " .. err)
|
||||
end
|
||||
end
|
||||
return queue
|
||||
end
|
||||
|
||||
local function stackInventoryItems(inventory, itemTree)
|
||||
debugPrint("Starting to stack inventory items...")
|
||||
for slotIndex, slot in ipairs(inventory.slots) do
|
||||
@@ -152,6 +240,43 @@ local function stackInventoryItems(inventory, itemTree)
|
||||
debugPrint("Completed stacking inventory items.")
|
||||
end
|
||||
|
||||
local function stackPlayerInventoryItems(inventory, itemTree)
|
||||
debugPrint("Starting to stack player inventory items...")
|
||||
for slotIndex, slot in ipairs(inventory.slots) do
|
||||
debugPrint("Checking slot index: " .. slotIndex)
|
||||
-- Cannot stack items if there are no items...
|
||||
if #slot.items > 0 then
|
||||
---@type Barotrauma.Item
|
||||
local item = slot.items[1]
|
||||
local identifier = item.Prefab.Identifier.Value
|
||||
debugPrint("Item at slot " .. slotIndex .. " is " .. identifier)
|
||||
|
||||
---@type ItemLocation[]
|
||||
local locations = itemTree[identifier]
|
||||
-- If there are no locations for this item
|
||||
-- Then there's nowhere to move it
|
||||
if locations then
|
||||
for _, location in ipairs(locations) do
|
||||
moveItemsTo(slot, location)
|
||||
if #slot.items == 0 then break end
|
||||
end
|
||||
|
||||
-- If we have processed all the locations and we still have items to move
|
||||
-- Then put them into the empty slots:
|
||||
if #slot.items > 0 then
|
||||
for _, location in ipairs(itemTree['empty']) do
|
||||
moveItemsTo(slot, location)
|
||||
if #slot.items == 0 then break end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
debugPrint("Slot index " .. slotIndex .. " is empty.")
|
||||
end
|
||||
end
|
||||
debugPrint("Completed stacking inventory items.")
|
||||
end
|
||||
|
||||
-- This is a bit fucking sucky.....
|
||||
-- But I really don't know better
|
||||
-- Maybe it will be fine...
|
||||
@@ -186,6 +311,32 @@ local function sortItemtreeBySlots(itemTree)
|
||||
return itemTree
|
||||
end
|
||||
|
||||
---@param inventory Barotrauma.ItemInventory
|
||||
---@return table<string, ItemLocation[]>, string
|
||||
local function tryBuildItemTree(inventory)
|
||||
local itemTree = {}
|
||||
debugPrint("Preparing to stack items into the bag...")
|
||||
local bagSlot = inventory.slots[8]
|
||||
if bagSlot then
|
||||
debugPrint("Bag slot found at index 8 with " .. #bagSlot.items .. " items.")
|
||||
if #bagSlot.items > 0 then
|
||||
local item = bagSlot.items[1]
|
||||
debugPrint("Found item in bag slot: " .. item.Name)
|
||||
if item and item.OwnInventory then
|
||||
debugPrint("Item has its own inventory, building item tree for it...")
|
||||
itemTree = buildItemTree(item.OwnInventory, itemTree)
|
||||
else
|
||||
return itemTree, "Bag does not have its own inventory."
|
||||
end
|
||||
else
|
||||
return itemTree, "Bag slot is empty."
|
||||
end
|
||||
else
|
||||
return itemTree, "No bag slot found at index 8."
|
||||
end
|
||||
return itemTree, nil
|
||||
end
|
||||
|
||||
-- Function to quickly stack items from inventory to containers
|
||||
local function quickStackItems(character)
|
||||
if not character then
|
||||
@@ -201,35 +352,27 @@ local function quickStackItems(character)
|
||||
return
|
||||
end
|
||||
|
||||
local itemTree = {}
|
||||
itemTree = buildItemTree(inventory, itemTree)
|
||||
local itemTree, err = tryBuildItemTree(inventory)
|
||||
if err then
|
||||
debugPrint("Error building item tree: " .. err)
|
||||
return
|
||||
end
|
||||
itemTree = sortItemtreeBySlots(itemTree)
|
||||
|
||||
debugPrint("Preparing to stack items into the bag...")
|
||||
local bagSlot = inventory.slots[8]
|
||||
if bagSlot then
|
||||
debugPrint("Bag slot found at index 8 with " .. #bagSlot.items .. " items.")
|
||||
if #bagSlot.items > 0 then
|
||||
local item = bagSlot.items[1]
|
||||
debugPrint("Found item in bag slot: " .. item.Name)
|
||||
if item and item.OwnInventory then
|
||||
debugPrint("Item has its own inventory, building item tree for it...")
|
||||
itemTree = buildItemTree(item.OwnInventory, itemTree)
|
||||
else
|
||||
debugPrint("Item does not have its own inventory.")
|
||||
end
|
||||
else
|
||||
debugPrint("Bag slot is empty.")
|
||||
end
|
||||
else
|
||||
debugPrint("No bag slot found at index 8.")
|
||||
local toMove = enqueueInventory(inventory)
|
||||
for _, item in ipairs(toMove) do
|
||||
print("Item: " .. item.Prefab.Identifier.Value)
|
||||
end
|
||||
local errors = tryMoveItems(toMove, itemTree)
|
||||
for _, error in ipairs(errors) do
|
||||
print("Error stacking item: " .. error)
|
||||
end
|
||||
|
||||
stackInventoryItems(item.OwnInventory, itemTree)
|
||||
local openContainerInventory = getOpenContainer()
|
||||
if openContainerInventory then
|
||||
stackInventoryItems(openContainerInventory, itemTree)
|
||||
end
|
||||
-- stackPlayerInventoryItems(inventory, itemTree)
|
||||
-- local openContainerInventory = getOpenContainer()
|
||||
-- if openContainerInventory then
|
||||
-- stackInventoryItems(openContainerInventory, itemTree)
|
||||
-- end
|
||||
|
||||
--local handItems = {}
|
||||
--for _, slotIndex in ipairs(CONFIG.HAND_SLOTS) do
|
||||
|
||||
Reference in New Issue
Block a user