Transfer items between inventories with limit
Posted: Sun Nov 03, 2024 3:54 am
Hi, I've been looking for a way to transfer items from one inventory to another with a limit and I'm having trouble finding the appropriate API call.
I can think of at least 2 places in the game where it seems this functionality is already implemented in the game:
- when inserters pick up items from an inventory
- when bots pick up items from an inventory
In both cases, the inserter and the bots might not pick up the entire stack and have a limit on the max number of items they can hold.
I raised this question in the #mod-dev-help channel on the Factorio discord and received a couple of suggestions but unfortunately none of them worked out. Here's the link to that question if you want to see the ideas: https://discord.com/channels/1396775903 ... 8800197632. Among the suggestions were:
- Use LuaInverntory.insert({name, count}). While this works for "normal" items, it doesn't preserve stack information like ammo usage, health, spoilage, tags, etc.
- Use LuaInventory.insert(LuaItemStack). While this preserves stack infromation, it doesn't have an option to limit the number of transferred items.
Another suggestion is to manually set stack counts to "split" the stack into a portion to keep in the inventory and a portion to transfer. Unfortunately this doesn't work because setting LuaItemStack.count seems to reset stack information.
It's definitely possible to re-implement all the edge case interactions around ammo, health, spoilage and tags but that logic would be pretty hard to write and test, especially if that logic already exists for inserters and bots.
Is there a recommended way to do this? If not, would it be possible to extend the API to add first-class support for this use case?
I have a couple of ideas for some API extensions that would make this possible without requiring modders to re-implement logic.
Idea 1: Set maximum item counts on LuaInventory
Once this is set, items will never be inserted into the inventory past the max_count, similar to the inventory bar today. This would be nice because it covers all ways of inserting items which would add useful flexibility to LuaInventory but I imagine it would be difficult to implement and probably require a couple more helper methods for getting and clearing max item counts.
Idea 2: Add a new method to transfer up to a max count of items from one inventory to another
This is similar to Idea 1 except it doesn't require storing any data on LuaInventory so hopefully it would be easier to implement.
Idea 3: Extend the existing insert method with an optional max count argument
This is nice because it doesn't even require making a new function but would require looping over item stacks in Lua compared to Idea 2 where the loop could be done in C++.
It would be really nice if any of those methods returned some additional information like:
- What are the updated item counts in the "transferred from" and "transferred to" inventories?
- Were all items moved or are there remaining items in the other inventory/stack?
What do people think?
I can think of at least 2 places in the game where it seems this functionality is already implemented in the game:
- when inserters pick up items from an inventory
- when bots pick up items from an inventory
In both cases, the inserter and the bots might not pick up the entire stack and have a limit on the max number of items they can hold.
I raised this question in the #mod-dev-help channel on the Factorio discord and received a couple of suggestions but unfortunately none of them worked out. Here's the link to that question if you want to see the ideas: https://discord.com/channels/1396775903 ... 8800197632. Among the suggestions were:
- Use LuaInverntory.insert({name, count}). While this works for "normal" items, it doesn't preserve stack information like ammo usage, health, spoilage, tags, etc.
- Use LuaInventory.insert(LuaItemStack). While this preserves stack infromation, it doesn't have an option to limit the number of transferred items.
Another suggestion is to manually set stack counts to "split" the stack into a portion to keep in the inventory and a portion to transfer. Unfortunately this doesn't work because setting LuaItemStack.count seems to reset stack information.
It's definitely possible to re-implement all the edge case interactions around ammo, health, spoilage and tags but that logic would be pretty hard to write and test, especially if that logic already exists for inserters and bots.
Is there a recommended way to do this? If not, would it be possible to extend the API to add first-class support for this use case?
I have a couple of ideas for some API extensions that would make this possible without requiring modders to re-implement logic.
Idea 1: Set maximum item counts on LuaInventory
Code: Select all
LuaInventory.set_max_item_count({name, quality?}, max_count)
Idea 2: Add a new method to transfer up to a max count of items from one inventory to another
Code: Select all
LuaInventory.insert_from_inventory(other_inventory, {name, quality?}, max_count)
Idea 3: Extend the existing insert method with an optional max count argument
Code: Select all
-- current method signature:
LuaInventory.insert(items) → uint
-- proposed method signature:
LuaInventory.insert(items, max_count?) → uint
It would be really nice if any of those methods returned some additional information like:
- What are the updated item counts in the "transferred from" and "transferred to" inventories?
- Were all items moved or are there remaining items in the other inventory/stack?
What do people think?