Fill an item stack from an inventory/container

Place to ask discuss and request the modding support of Factorio. Don't request mods here.
SyncViews
Filter Inserter
Filter Inserter
Posts: 295
Joined: Thu Apr 21, 2016 3:17 pm
Contact:

Fill an item stack from an inventory/container

Post by SyncViews »

Filling a stack (or larger container) with content from other inventories has some pitfalls. LuaInventory.find_item_stack looks like a good start, but if the items in the inventory are not stacked as much as they could be, it needs to be called multiple times as items are removed. Additionally damaged and undamaged items do not stack, but they have the same item name so find_item_stack will return which ever is first.

For example consider the gun turrets in this chest:
Annotation 2020-09-05 025840.png
Annotation 2020-09-05 025840.png (33.7 KiB) Viewed 1522 times

Code: Select all

-- doesn't handle uncompressed stacks without a loop
-- doesn't handle damaged vs undamaged items
existing_stack.transfer_stack(inventory.find_item_stack(existing_stack.name))
This can be worked around but need a bunch of Lua checking each inventory slot.

Something like:

LuaInventory.fill_stack(stack, item_name) → boolean
Fill stack with items from this inventory
Parameters
stack :: LuaItemStack Stack to fill, may be empty
item_name :: string Item to fill stack with. If stack is non-empty, must be the same as stack.name
Return value
true if stack is now full

Code: Select all

function fill_stack(self, stack, item_name)
  local stack_size = game.item_prototypes[item_name].stack_size
  if stack.valid_for_read then
    assert(item_name == stack.name)
    if stack.count == stack_size then
      return true -- full already, do nothing
    end
  end -- else empty stack
  
  for i=1,#self do
    stack.transfer_stack(self[i]) -- no-op if not stackable
    if stack.valid_for_read and stack.count >= stack_size then
      return true -- full, finished
    end
  end
  
  return false -- not full
end
Extending `LuaInventory.find_item_stack` to differentiate damaged and undamaged items in some way would be another option which I think covers all cases if called in a loop until it returns nil.

Code: Select all

inventory.find_item_stack('gun-turret') -- as now, don't care, whichever comes first
inventory.find_item_stack('gun-turret', true) -- only find damaged items
inventory.find_item_stack('gun-turret', false) -- only find undamaged items
---

The full use case was to try and fill as many of the filtered (blue, as per LuaInventory.get_filter(slot_index)) slots in a wagon as possible pulling form another container. Probably the entire thing is too specific.
User avatar
micromario
Fast Inserter
Fast Inserter
Posts: 107
Joined: Thu Apr 05, 2018 11:53 am
Contact:

Re: Fill an item stack from an inventory/container

Post by micromario »

+1

I've had this same issue in the past, although the extra lua to check the entire inventory isn't that bad
Post Reply

Return to “Modding interface requests”