170 lines
5.8 KiB
Lua
170 lines
5.8 KiB
Lua
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.MakeFieldAccessible(Descriptors['Barotrauma.Items.Components.ItemContainer'], 'slotRestrictions')
|
|
LuaUserData.MakeFieldAccessible(Descriptors['Barotrauma.ItemInventory'], 'slots')
|
|
LuaUserData.MakeFieldAccessible(Descriptors["Barotrauma.CharacterInventory"], "slots")
|
|
|
|
-- Simple configuration
|
|
local HAND_SLOTS = { 6, 7 }
|
|
local PRIORITY_CONTAINERS = { "toolbelt", "backpack", "pouch" } -- Identifiers for priority containers
|
|
|
|
-- Helper function to move an item to a container, but only if matching items exist
|
|
local function moveItemToContainer(item, containerInv)
|
|
if not item or not containerInv then return false end
|
|
|
|
print("[QuickStack] Attempting to stack with existing items in container (" .. #containerInv.slots .. " slots)")
|
|
|
|
-- Only try to find matching items to stack with
|
|
local foundMatchingItem = false
|
|
|
|
-- Check if the container has any matching items first
|
|
for slotIndex = 0, #containerInv.slots - 1 do
|
|
for _, containerItem in ipairs(containerInv.slots[slotIndex + 1].items) do
|
|
if containerItem.Prefab.Identifier.Equals(item.Prefab.Identifier) then
|
|
foundMatchingItem = true
|
|
print("[QuickStack] Found matching item in container")
|
|
break
|
|
end
|
|
end
|
|
if foundMatchingItem then break end
|
|
end
|
|
|
|
-- If no matching items exist in the container, don't move the item
|
|
if not foundMatchingItem then
|
|
print("[QuickStack] No matching items in container, skipping")
|
|
return false
|
|
end
|
|
|
|
-- Try to stack with existing items
|
|
for slotIndex = 0, #containerInv.slots - 1 do
|
|
for _, containerItem in ipairs(containerInv.slots[slotIndex + 1].items) do
|
|
if containerItem.Prefab.Identifier.Equals(item.Prefab.Identifier) then
|
|
-- Try to stack with existing item
|
|
print("[QuickStack] Stacking with existing item")
|
|
if containerInv.TryPutItem(item, slotIndex, true, false, nil) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- We don't try to place in empty slots anymore, only stack with existing items
|
|
print("[QuickStack] Failed to stack with existing items")
|
|
return false
|
|
end
|
|
|
|
-- Sort containers by priority
|
|
local function sortContainersByPriority(containers)
|
|
table.sort(containers, function(a, b)
|
|
local aPriority = -1
|
|
local bPriority = -1
|
|
|
|
-- Check priority for first container
|
|
for i, identifier in ipairs(PRIORITY_CONTAINERS) do
|
|
if a.Prefab.Identifier.Value:find(identifier) then
|
|
aPriority = i
|
|
break
|
|
end
|
|
end
|
|
|
|
-- Check priority for second container
|
|
for i, identifier in ipairs(PRIORITY_CONTAINERS) do
|
|
if b.Prefab.Identifier.Value:find(identifier) then
|
|
bPriority = i
|
|
break
|
|
end
|
|
end
|
|
|
|
return aPriority < bPriority
|
|
end)
|
|
|
|
return containers
|
|
end
|
|
|
|
-- Function to quickly stack items from inventory to containers
|
|
local function quickStackItems(character)
|
|
if not character then return end
|
|
print("[QuickStack] Function called")
|
|
|
|
local inventory = character.Inventory
|
|
if not inventory or not inventory.slots then return end
|
|
|
|
-- First identify all containers in inventory
|
|
local containers = {}
|
|
|
|
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")
|
|
if #containers == 0 then
|
|
print("[QuickStack] No containers with inventory found!")
|
|
return
|
|
end
|
|
|
|
-- Sort containers by priority
|
|
containers = sortContainersByPriority(containers)
|
|
|
|
local itemsMoved = 0
|
|
|
|
-- Process inventory slots
|
|
for slotIndex, slot in ipairs(inventory.slots) do
|
|
-- Skip hand slots
|
|
local isHandSlot = false
|
|
for _, handSlot in ipairs(HAND_SLOTS) do
|
|
if slotIndex == handSlot then
|
|
isHandSlot = true
|
|
break
|
|
end
|
|
end
|
|
if isHandSlot then goto continueSlot end
|
|
|
|
-- 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 container
|
|
for _, container in ipairs(containers) do
|
|
if moveItemToContainer(item, container.OwnInventory) then
|
|
print("[QuickStack] Stacked " .. item.Name .. " into " .. container.Name)
|
|
itemsMoved = itemsMoved + 1
|
|
break
|
|
end
|
|
end
|
|
|
|
::nextItem::
|
|
end
|
|
|
|
::continueSlot::
|
|
end
|
|
|
|
if itemsMoved > 0 then
|
|
print("[QuickStack] Stacked " .. itemsMoved .. " items into containers")
|
|
else
|
|
print("[QuickStack] No matching items to stack")
|
|
end
|
|
end
|
|
|
|
-- Hook into player control to listen for key press
|
|
Hook.Patch("Barotrauma.Character", "ControlLocalPlayer", function(instance, ptable)
|
|
if not PlayerInput.KeyHit(Keys.F) then return end
|
|
|
|
local character = instance
|
|
if not character then return end
|
|
|
|
quickStackItems(character)
|
|
end, Hook.HookMethodType.After)
|