Add Importer configuration for types of machines to import into

This commit is contained in:
Zenon Seth 2024-07-31 12:42:34 +01:00
parent cf30e6736a
commit 6679350fb7
5 changed files with 101 additions and 41 deletions

View File

@ -3,27 +3,46 @@ local S = logistica.TRANSLATOR
local PULL_LIST_PICKER = "pull_pick"
local ON_OFF_BUTTON = "on_off_btn"
local CBX_REQ = "cbxreq"
local CBX_MAS = "cbxmas"
local CBX_SUP = "cbxsup"
local CBX_TRA = "cbxtra"
local FORMSPEC_NAME = "logistica_storinject"
local NUM_FILTER_SLOTS = 8
local PUT_INTO_TOOLTIP = S("Select what types of machines this Importer will put items into.\nMachine priority is from top to bottom, e.g. Trashcans, if enabled,\nare always the last machine type that items are put into.")
local injectorForms = {}
local function get_add_into_section(pos, x, y)
local chst = function(idx) if logistica.injector_get_put_into_state(pos, idx) == true then return "true" else return "false" end end
return
"label["..(x)..","..(y + 0.5)..";Put in (?):]"..
"checkbox["..(x + 1.3)..","..(y + 0.0)..";"..CBX_REQ..";Requesters;"..chst(1).."]"..
"checkbox["..(x + 1.3)..","..(y + 0.4)..";"..CBX_MAS..";Mass/Item Storage;"..chst(2).."]"..
"checkbox["..(x + 1.3)..","..(y + 0.8)..";"..CBX_SUP..";Supply Chests;"..chst(3).."]"..
"checkbox["..(x + 1.3)..","..(y + 1.2)..";"..CBX_TRA..";Trashcans;"..chst(4).."]"..
"tooltip["..(x)..","..(y + 0.2)..";1,0.6;"..PUT_INTO_TOOLTIP.."]"
end
local function get_injector_formspec(pos)
local posForm = "nodemeta:"..pos.x..","..pos.y..","..pos.z
local pullPos = logistica.get_injector_target(pos)
local selectedList = logistica.get_injector_target_list(pos)
local isOn = logistica.is_machine_on(pos)
return "formspec_version[4]" ..
"size["..logistica.inv_size(10.7, 8.75).."]" ..
return "formspec_version[4]"..
"size["..logistica.inv_size(10.7, 9.45).."]"..
logistica.ui.background..
"label[0.5,0.3;"..S("Network Importer take items from target and add them to the network").."]"..
"label[0.5,0.8;"..S("Filter: Import only filtered. If empty, imports all items.").."]"..
"list["..posForm..";filter;0.5,1.0;"..NUM_FILTER_SLOTS..",1;0]"..
logistica.player_inv_formspec(0.5,3.3)..
logistica.player_inv_formspec(0.5,4.0)..
"listring[current_player;main]"..
"listring["..posForm..";filter]"..
logistica.ui.pull_list_picker(PULL_LIST_PICKER, 0.5, 2.5, pullPos, selectedList, S("Take items from:"))..
logistica.ui.on_off_btn(isOn, 4.5, 2.3, ON_OFF_BUTTON, S("Enable"))
logistica.ui.pull_list_picker(PULL_LIST_PICKER, 0.5, 2.8, pullPos, selectedList, S("Take items from:"))..
logistica.ui.on_off_btn(isOn, 4.0, 2.6, ON_OFF_BUTTON, S("Enable"))..
get_add_into_section(pos, 6.5, 2.3)
end
local function show_injector_formspec(playerName, pos)
@ -47,7 +66,15 @@ local function on_player_receive_fields(player, formname, fields)
elseif fields[ON_OFF_BUTTON] then
logistica.toggle_machine_on_off(pos)
show_injector_formspec(player:get_player_name(), pos)
elseif fields[PULL_LIST_PICKER] then
elseif fields[CBX_REQ] ~= nil then
logistica.injector_set_put_into_state(pos, 1, fields[CBX_REQ])
elseif fields[CBX_MAS] ~= nil then
logistica.injector_set_put_into_state(pos, 2, fields[CBX_MAS])
elseif fields[CBX_SUP] ~= nil then
logistica.injector_set_put_into_state(pos, 3, fields[CBX_SUP])
elseif fields[CBX_TRA] ~= nil then
logistica.injector_set_put_into_state(pos, 4, fields[CBX_TRA])
elseif fields[PULL_LIST_PICKER] then -- this has to be last, because its always sent
local selected = fields[PULL_LIST_PICKER]
if logistica.is_allowed_pull_list(selected) then
logistica.set_injector_target_list(pos, selected)

View File

@ -119,16 +119,19 @@ To get a Network Importer working you must:
- Select which inventory of the target node to take from - some nodes have multiple inventories, and one must be selected.
- Make sure you press the Enable button to enable its functionality.
- Optionally, you can configure the importer to only pull specific items by placing them in the Filter List. If the list is empty, the importer will indiscriminately attempt to pull any item, slot by slot, from its input node.
- Optionally, select which machine types the importer will try to insert items into.
Network importers scan 1 slot, and rotate which slot they take from each time they tick.
Network Importers prioritize where they put their items in this order:
Network Importers prioritize where they put their items in this order, assuming the type of machine to import into is enabled in the Importer's interface:
- Fill the requests of any Requesters on the network
- Fill any Mass Storage that can handle this item
- Fill any Mass or Item Storages (depending on whether item is stackable or not) that can handle this item
- Fill any passive supply chests (if the chests are configured to accept items from the network)
- Trash the item if there's any Trashcans connected that accept this kind of item. (see Trashcan)
Using the Importer's GUI, you can enable or disable each of the 4 types of machines to import items into, and any disabled won't be added into. If no machine type is enabled to import into, then the Importer won't add any items at all. Note that even when a machine type is enabled, the Importer obeys the configuration of those machines, e.g. if a Passive Supply Chest is marked as "Don't allow storing from network" then the importer won't add into it.
There's 2 version of the Network Importer:
- Slow Network Importer: Takes up to 10 items from a slot at a time, and tries to insert it in the network.

View File

@ -380,7 +380,7 @@ function logistica.access_point_on_put(inv, listname, index, stack, player)
end
if listname == INV_INSERT then
local stackToAdd = inv:get_stack(listname, index)
local leftover = logistica.insert_item_in_network(stackToAdd, networkId, false, true)
local leftover = logistica.insert_item_in_network(stackToAdd, networkId, false, false, false, false, true)
stack:set_count(leftover)
local error = nil
if not stack:is_empty() then

View File

@ -1,4 +1,5 @@
local META_INJECTOR_LISTNAME = "tarinjlist"
local META_PUT_INTO_PREFIX = "putinto"
local TIMER_DURATION_SHORT = 1
local TIMER_DURATION_LONG = 3
@ -15,6 +16,10 @@ local function get_injector_rate(nodeName)
return 0
end
local function get_put_into_state(meta, index)
return meta:get_int(META_PUT_INTO_PREFIX..index) == 0 --check if == 0 because by default we assume all are on
end
local function get_next_injector_filtered_slot(targetMeta, targetList, targetInv, injInv)
local tmpSlot = logistica.get_next_filled_item_slot(targetMeta, targetList)
if injInv:is_empty("filter") then return tmpSlot end
@ -85,7 +90,15 @@ function logistica.on_injector_timer(pos, elapsed)
local targetStackSize = copyStack:get_count()
local numToTake = math.min(targetStackSize, maxStack)
copyStack:set_count(numToTake)
local numRemaining = logistica.insert_item_in_network(copyStack, networkId)
local numRemaining = logistica.insert_item_in_network(
copyStack,
networkId,
false,
not get_put_into_state(meta, 1),
not get_put_into_state(meta, 2),
not get_put_into_state(meta, 3),
not get_put_into_state(meta, 4)
)
numRemaining = targetStackSize - numToTake + numRemaining
copyStack:set_count(numRemaining)
targetInv:set_stack(targetList, targetSlot, copyStack)
@ -93,3 +106,14 @@ function logistica.on_injector_timer(pos, elapsed)
logistica.start_node_timer(pos, TIMER_DURATION_SHORT)
return false
end
-- returns true/false
function logistica.injector_get_put_into_state(pos, index)
return get_put_into_state(get_meta(pos), index)
end
-- state must be "true"/"false" as a string
function logistica.injector_set_put_into_state(pos, index, state)
local value = 1 ; if state == "true" then value = 0 end
return get_meta(pos):set_int(META_PUT_INTO_PREFIX..index, value)
end

View File

@ -284,7 +284,7 @@ function logistica.insert_item_into_item_storage(pos, inv, inputStack, dryRun)
end
-- attempts to insert the given itemstack in the network, returns how many items remain
function logistica.insert_item_in_network(itemstack, networkId, dryRun, ignoreTrashcans)
function logistica.insert_item_in_network(itemstack, networkId, dryRun, ignoreRequesters, ignoreStorages, ignoreSuppliers, ignoreTrashcans)
local network = logistica.get_network_by_id_or_nil(networkId)
if not itemstack or itemstack:is_empty() then return 0 end
if not network then return itemstack:get_count() end
@ -292,42 +292,48 @@ function logistica.insert_item_in_network(itemstack, networkId, dryRun, ignoreTr
local workingStack = ItemStack(itemstack)
-- check requesters first
local listOfRequestersInNeedOfItem = network.requester_cache[itemstack:get_name()] or {}
for hash, _ in pairs(listOfRequestersInNeedOfItem) do
local pos = h2p(hash)
logistica.load_position(pos)
local leftover = logistica.insert_itemstack_for_requester(pos, workingStack, true)
if leftover <= 0 then return 0 end -- we took all items
workingStack:set_count(leftover)
if not ignoreRequesters then
local listOfRequestersInNeedOfItem = network.requester_cache[itemstack:get_name()] or {}
for hash, _ in pairs(listOfRequestersInNeedOfItem) do
local pos = h2p(hash)
logistica.load_position(pos)
local leftover = logistica.insert_itemstack_for_requester(pos, workingStack, true)
if leftover <= 0 then return 0 end -- we took all items
workingStack:set_count(leftover)
end
end
-- check storages
local storages = {}
local addFunc = nil
if itemstack:get_stack_max() <= 1 then
storages = network.item_storage
addFunc = logistica.insert_item_into_item_storage
else
storages = network.storage_cache[itemstack:get_name()] or {}
addFunc = logistica.insert_item_into_mass_storage
end
for hash, _ in pairs(storages) do
local pos = h2p(hash)
logistica.load_position(pos)
local inv = get_meta(pos):get_inventory()
local remainingStack = addFunc(pos, inv, workingStack, dryRun)
if remainingStack:is_empty() then return 0 end -- we took all items
workingStack = remainingStack
if not ignoreStorages then
local storages = {}
local addFunc = nil
if itemstack:get_stack_max() <= 1 then
storages = network.item_storage
addFunc = logistica.insert_item_into_item_storage
else
storages = network.storage_cache[itemstack:get_name()] or {}
addFunc = logistica.insert_item_into_mass_storage
end
for hash, _ in pairs(storages) do
local pos = h2p(hash)
logistica.load_position(pos)
local inv = get_meta(pos):get_inventory()
local remainingStack = addFunc(pos, inv, workingStack, dryRun)
if remainingStack:is_empty() then return 0 end -- we took all items
workingStack = remainingStack
end
end
-- try to add to passive suppliers that accept this
local suppliers = network.suppliers
for hash, _ in pairs(suppliers) do
local pos = h2p(hash)
logistica.load_position(pos)
local leftover = logistica.put_item_in_supplier(pos, workingStack)
if leftover:is_empty() then return 0 end
workingStack = leftover
if not ignoreSuppliers then
local suppliers = network.suppliers
for hash, _ in pairs(suppliers) do
local pos = h2p(hash)
logistica.load_position(pos)
local leftover = logistica.put_item_in_supplier(pos, workingStack)
if leftover:is_empty() then return 0 end
workingStack = leftover
end
end
-- [Keep this last] delete the item if any trashcan accepts it