LuaInventory::get_filtered_slots()
Posted: Fri Jan 05, 2024 8:42 pm
What?
I'd like to get a method to get the indices of all filtered slots in an inventory:LuaInventory::get_filtered_slots() --> Array of uint
Why?
We already have LuaInventory::is_filtered(), which returns true if the inventory supports filters and has at least one filter set, and LuaInventory:get_filter(index), which will get the filter of a certain slot. Checking for LuaInventory::is_filtered() allows me to skip looking for filtered inventory slots if the inventory has no filters set. But once I know that the inventory has filters, I must use something like this to find the slots that have a filter:Code: Select all
if inventory.is_filtered() then
for slot, #inventory do
if inventory.get_filter(slot) then
-- Do stuff
end
end
end
Code: Select all
if inventory.is_filtered() then
local filtered = inventory.get_filtered_slots()
for s, slot in ipairs(filtered) do
if inventory.get_filter(slot) then
-- Do stuff
end
end
end
Use case:
Autodrive allows car-based vehicles equipped with a "logistic sensor" to autotrash and request items in their trunk. When such a vehicle is standing within an area covered by a roboport, it will create a hidden requester and a hidden active-provider chest. It then will scan the inventory, looking for special items like armors or blueprints (can only be provided) and common items. Slots filtered for common items will be counted as requests if stack.count < LuaItemPrototype::stack_size, while the contents of unfiltered slots will be provided.On each turn, we process 10 trunk slots: We set filters in the hidden requester chest if any requested items are still missing, and move provided items to the active provider chest, if there is any space left. This is repeated until the entire inventory has been scanned. On the start of the next turn, all items that have been delivered to the hidden requester will be inserted back into the trunk (where they will automatically fill the filtered slots), all tables will be reset, and we start over scanning the inventory from slot 1.
Now suppose the inventory looks like this: In the latest version of Autodrive, the hidden requester chest would be set to request 400 copper plates, and 5 stacks of copper plates would be transferred to the hidden active-provider chest. The bots would then move 400 of the copper plates from the provider into the requester chest and clear out the remaining 100 copper plates from the provider chest. However, it would be more efficient if I'd directly move 4 of the 5 provided stacks to the filtered slots, without involving any bots.
In my WIP version, I've taken a slightly different approach: On each turn, I check for each unfiltered slot with common items whether the item is also on the list of requested items. If it is, I try to insert the stack into the trunk (will go to a filtered slot), reduce the amount of requested items, as well as the amount of items in the unfiltered slot. Only the remaining provided items are then moved to the active provider. However, this still isn't satisfying. With the trunk inventory above, the following would happen:
- Turn 1: Two stacks of copper-plates are found. As there are no requests yet, they are moved to the active provider,
- Turn 2: Four empty stacks filtered for copper-plates are found, as well as one stack of copper-plates. This will be moved to the first filtered slot, leaving three slots for which filters will be added in the requester.
- Turn 3: Two more stacks of copper-plates are found. They should be moved to the next two filtered slots, and two requests should be removed from the requester chest.