Fix goto disasters

This commit is contained in:
2025-03-29 19:30:36 +01:00
parent b7f090626d
commit 7115a9fe36

View File

@@ -3,22 +3,22 @@ if SERVER then return end
-- Register necessary types and make fields accessible -- Register necessary types and make fields accessible
LuaUserData.RegisterType("Barotrauma.Items.Components.ItemContainer+SlotRestrictions") LuaUserData.RegisterType("Barotrauma.Items.Components.ItemContainer+SlotRestrictions")
LuaUserData.RegisterType( LuaUserData.RegisterType(
'System.Collections.Immutable.ImmutableArray`1[[Barotrauma.Items.Components.ItemContainer+SlotRestrictions, Barotrauma]]') 'System.Collections.Immutable.ImmutableArray`1[[Barotrauma.Items.Components.ItemContainer+SlotRestrictions, Barotrauma]]')
LuaUserData.MakeFieldAccessible(Descriptors['Barotrauma.Items.Components.ItemContainer'], 'slotRestrictions') LuaUserData.MakeFieldAccessible(Descriptors['Barotrauma.Items.Components.ItemContainer'], 'slotRestrictions')
LuaUserData.MakeFieldAccessible(Descriptors['Barotrauma.ItemInventory'], 'slots') LuaUserData.MakeFieldAccessible(Descriptors['Barotrauma.ItemInventory'], 'slots')
LuaUserData.MakeFieldAccessible(Descriptors["Barotrauma.CharacterInventory"], "slots") LuaUserData.MakeFieldAccessible(Descriptors["Barotrauma.CharacterInventory"], "slots")
-- Configuration -- Configuration
local CONFIG = { local CONFIG = {
TRIGGER_KEY = Keys.F, -- Key to press for quick stacking TRIGGER_KEY = Keys.F, -- Key to press for quick stacking
BAG_TAGS = { "container", "cargocontainer" }, -- Tags that identify bags/containers BAG_TAGS = { "container", "cargocontainer" }, -- Tags that identify bags/containers
MAX_ITEMS_TO_PROCESS = 100, -- Safety limit to prevent infinite loops MAX_ITEMS_TO_PROCESS = 100, -- Safety limit to prevent infinite loops
PREFER_EXISTING_STACKS = true, -- Prefer stacking into existing item stacks PREFER_EXISTING_STACKS = true, -- Prefer stacking into existing item stacks
CHECK_ALL_CONTAINERS = true, -- Check all containers in inventory, not just bag slot CHECK_ALL_CONTAINERS = true, -- Check all containers in inventory, not just bag slot
PRIMARY_BAG_SLOT = 8, -- Slot number for the primary bag (typically slot 8) PRIMARY_BAG_SLOT = 8, -- Slot number for the primary bag (typically slot 8)
SKIP_HAND_SLOTS = true, -- Skip hand slots when processing items SKIP_HAND_SLOTS = true, -- Skip hand slots when processing items
HAND_SLOTS = { 6, 7 }, -- Slot numbers for hands (typically slots 6 and 7) HAND_SLOTS = { 6, 7 }, -- Slot numbers for hands (typically slots 6 and 7)
SKIP_DIVING_GEAR = true, -- Skip diving gear when processing items SKIP_DIVING_GEAR = true, -- Skip diving gear when processing items
DIVING_GEAR_TAGS = { "divingsuit", "divingmask", "oxygensource" } -- Tags for diving gear DIVING_GEAR_TAGS = { "divingsuit", "divingmask", "oxygensource" } -- Tags for diving gear
} }
@@ -62,7 +62,7 @@ local function findContainersInInventory(character)
if CONFIG.CHECK_ALL_CONTAINERS then if CONFIG.CHECK_ALL_CONTAINERS then
for slotIndex, slot in ipairs(inventory.slots) do for slotIndex, slot in ipairs(inventory.slots) do
-- Skip the primary bag slot as we already processed it -- Skip the primary bag slot as we already processed it
if slotIndex == CONFIG.PRIMARY_BAG_SLOT then goto continue end if slotIndex == CONFIG.PRIMARY_BAG_SLOT then goto continueSlot end
-- Skip hand slots if configured to do so -- Skip hand slots if configured to do so
if CONFIG.SKIP_HAND_SLOTS then if CONFIG.SKIP_HAND_SLOTS then
@@ -73,7 +73,7 @@ local function findContainersInInventory(character)
break break
end end
end end
if isHandSlot then goto continue end if isHandSlot then goto continueSlot end
end end
for _, item in ipairs(slot.items) do for _, item in ipairs(slot.items) do
@@ -82,7 +82,7 @@ local function findContainersInInventory(character)
end end
end end
::continue:: ::continueSlot::
end end
end end
@@ -124,88 +124,94 @@ local function tryStackItemInSlot(container, sourceItem, slotIndex)
return false return false
end end
-- Function to process a single inventory slot
local function processInventorySlot(playerInv, slotIndex, containers, processedCount, stackedCount)
-- Check if this slot should be skipped (hand slots)
if CONFIG.SKIP_HAND_SLOTS then
for _, handSlot in ipairs(CONFIG.HAND_SLOTS) do
if slotIndex == handSlot then
return processedCount, stackedCount
end
end
end
local slot = playerInv.slots[slotIndex]
if not slot then return processedCount, stackedCount end
-- Process items in the slot
for i = #slot.items, 1, -1 do -- Iterate backwards to safely remove
local item = slot.items[i]
local success = false
-- Skip containers themselves
if isContainer(item) then goto nextItem end
-- Skip diving gear if configured to do so
if isDivingGear(item) then goto nextItem end
processedCount = processedCount + 1
if processedCount > CONFIG.MAX_ITEMS_TO_PROCESS then
print("QuickStack: Safety limit reached")
return processedCount, stackedCount
end
-- Try each container in order
for _, container in ipairs(containers) do
local containerInv = container.OwnInventory
if not containerInv then goto nextContainer end
-- First try to stack with existing stacks if configured to do so
if CONFIG.PREFER_EXISTING_STACKS then
for bagSlotIndex = 0, #containerInv.slots - 1 do
for _, containerItem in ipairs(containerInv.slots[bagSlotIndex + 1].items) do
if canStackWith(containerItem, item) then
success = tryStackItemInSlot(containerInv, item, bagSlotIndex)
if success then break end
end
end
if success then break end
end
end
-- If not stacked yet, try any valid slot
if not success then
for bagSlotIndex = 0, #containerInv.slots - 1 do
success = tryStackItemInSlot(containerInv, item, bagSlotIndex)
if success then break end
end
end
if success then
stackedCount = stackedCount + 1
break -- Stop trying containers if we succeeded
end
::nextContainer::
end
::nextItem::
end
return processedCount, stackedCount
end
-- Function to quick stack items into containers -- Function to quick stack items into containers
local function quickStackToContainers(character, containers) local function quickStackToContainers(character, containers)
if not character or #containers == 0 then return end if not character or #containers == 0 then return 0 end
local playerInv = character.Inventory local playerInv = character.Inventory
local processedCount = 0 local processedCount = 0
local stackedCount = 0 local stackedCount = 0
-- Process inventory slots -- Process each inventory slot
for slotIndex = 1, #playerInv.slots do for slotIndex = 1, #playerInv.slots do
-- Skip hand slots if configured to do so processedCount, stackedCount = processInventorySlot(
if CONFIG.SKIP_HAND_SLOTS then playerInv,
local isHandSlot = false slotIndex,
for _, handSlot in ipairs(CONFIG.HAND_SLOTS) do containers,
if slotIndex == handSlot then processedCount,
isHandSlot = true stackedCount
break )
end
end
if isHandSlot then goto continue end
end
local slot = playerInv.slots[slotIndex]
if not slot then goto continue end
-- Process items in the slot
for i = #slot.items, 1, -1 do -- Iterate backwards to safely remove
local item = slot.items[i]
-- Declare success variable outside any potential goto jumps
local success = false
-- Skip containers themselves
if isContainer(item) then goto nextItem end
-- Skip diving gear if configured to do so
if isDivingGear(item) then goto nextItem end
processedCount = processedCount + 1
if processedCount > CONFIG.MAX_ITEMS_TO_PROCESS then
print("QuickStack: Safety limit reached")
return stackedCount
end
-- Try to stack the item into the containers
-- Try each container in order
for _, container in ipairs(containers) do
local containerInv = container.OwnInventory
if not containerInv then goto nextContainer end
-- First try to stack with existing stacks if configured to do so
if CONFIG.PREFER_EXISTING_STACKS then
for bagSlotIndex = 0, #containerInv.slots - 1 do
for _, containerItem in ipairs(containerInv.slots[bagSlotIndex + 1].items) do
if canStackWith(containerItem, item) then
success = tryStackItemInSlot(containerInv, item, bagSlotIndex)
if success then break end
end
end
if success then break end
end
end
-- If not stacked yet, try any valid slot
if not success then
for bagSlotIndex = 0, #containerInv.slots - 1 do
success = tryStackItemInSlot(containerInv, item, bagSlotIndex)
if success then break end
end
end
if success then
stackedCount = stackedCount + 1
break -- Stop trying containers if we succeeded
end
::nextContainer::
end
::nextItem::
end
::continue::
end end
return stackedCount return stackedCount