-- We got to do this shit because enqueueInventory calls enqueueItem -- And enqueueItem calls enqueueInventory -- So unless we define them both before using them -- We will get an error saying either is undefined local enqueueItem local enqueueSlot local enqueueInventory local _ ---@alias FilterPredicate fun(item: Barotrauma.Item, inventoryRef?: Barotrauma.ItemInventory, slotRef: Barotrauma.ItemInventory.Slot): boolean ---@param item Barotrauma.Item ---@param queue Barotrauma.Item[] ---@param predicate? FilterPredicate ---@param loadRefs? boolean ---@param slotRef? Barotrauma.ItemInventory.Slot ---@param inventoryRef? Barotrauma.ItemInventory ---@return Barotrauma.Item[], string? enqueueItem = function(item, queue, predicate, loadRefs, slotRef, inventoryRef) queue = queue or {} predicate = predicate or function() return true end -- debugPrint(string.format("Enqueuing item: %s", item.Prefab.Identifier.Value)) -- local err -- This should make it breadth first, right...? -- No, not yet... if not item then return queue, "No item" end local ok, stop = predicate(item, inventoryRef, slotRef) if ok then queue[#queue + 1] = item end if stop then return queue, "Stop" end if item.OwnInventory then -- As far as I know every item has only one inventory -- Only machines have multiple -- So inventrorY should be fine here -- debugPrint("Item has its own inventory, enqueuing inventory...") if loadRefs then queue, _ = enqueueInventory(item.OwnInventory, queue, predicate, loadRefs) else queue, _ = enqueueInventory(item.OwnInventory, queue, predicate) end -- if err then -- debugPrint(string.format("Error enqueuing inventory: %s", err)) -- end end -- debugPrint(string.format("Item enqueued. Current queue size: %d", #queue)) return queue, nil end ---@param slot Barotrauma.ItemInventory.Slot ---@param queue Barotrauma.Item[] ---@param predicate? FilterPredicate ---@param loadRefs? boolean ---@param inventoryRef? Barotrauma.ItemInventory ---@return Barotrauma.Item[], string? enqueueSlot = function(slot, queue, predicate, loadRefs, inventoryRef) queue = queue or {} predicate = predicate or function() return true end -- debugPrint(string.format("Enqueuing slot with %d items.", #slot.items)) -- 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 if not slot then return queue, "No slot" end if not slot.items then return queue, "No items" end for _, item in ipairs(slot.items) do -- Only the final leaf nodes decide upon the predicate if loadRefs then queue, err = enqueueItem(item, queue, predicate, loadRefs, inventoryRef, slot) else queue, err = enqueueItem(item, queue, predicate) end if err then return queue, err end end -- debugPrint(string.format("Finished enqueuing slot. Current queue size: %d", #queue)) return queue end ---@param inventory Barotrauma.ItemInventory ---@param queue Barotrauma.Item[] ---@param predicate? FilterPredicate ---@param loadRefs? boolean ---@return Barotrauma.Item[], string? enqueueInventory = function(inventory, queue, predicate, loadRefs) queue = queue or {} predicate = predicate or function() return true end -- debugPrint(string.format("Enqueuing inventory with %d slots.", #inventory.slots)) local err if not inventory then return queue, "No inventory" end if not inventory.slots then return queue, "No slots" end for _, slot in ipairs(inventory.slots) do -- Only the final leaf nodes decide upon the predicate if loadRefs then queue, err = enqueueSlot(slot, queue, predicate, loadRefs, inventory) else queue, err = enqueueSlot(slot, queue, predicate) end if err then return queue, err end end -- debugPrint(string.format("Finished enqueuing inventory. Current queue size: %d", #queue)) return queue end return { enqueueItem = enqueueItem, enqueueSlot = enqueueSlot, enqueueInventory = enqueueInventory }