From 6679350fb7f6e06a7f4454585f33c7cd585ba5a4 Mon Sep 17 00:00:00 2001 From: Zenon Seth Date: Wed, 31 Jul 2024 12:42:34 +0100 Subject: [PATCH] Add Importer configuration for types of machines to import into --- api/injector.lua | 39 ++++++++++++++++--- guide/guide_desc_machines.lua | 7 +++- logic/access_point_formspec.lua | 2 +- logic/injector.lua | 26 ++++++++++++- logic/network_storage.lua | 68 ++++++++++++++++++--------------- 5 files changed, 101 insertions(+), 41 deletions(-) diff --git a/api/injector.lua b/api/injector.lua index 71632cc..23d597f 100644 --- a/api/injector.lua +++ b/api/injector.lua @@ -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) diff --git a/guide/guide_desc_machines.lua b/guide/guide_desc_machines.lua index e337255..730c72b 100644 --- a/guide/guide_desc_machines.lua +++ b/guide/guide_desc_machines.lua @@ -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. diff --git a/logic/access_point_formspec.lua b/logic/access_point_formspec.lua index 75cbb88..14fe1fd 100644 --- a/logic/access_point_formspec.lua +++ b/logic/access_point_formspec.lua @@ -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 diff --git a/logic/injector.lua b/logic/injector.lua index 40dac8f..b06dda5 100644 --- a/logic/injector.lua +++ b/logic/injector.lua @@ -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 diff --git a/logic/network_storage.lua b/logic/network_storage.lua index 0b19d0f..032572c 100644 --- a/logic/network_storage.lua +++ b/logic/network_storage.lua @@ -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