From 58cd5947d513db337e62147ce0942dc3afdfd9a7 Mon Sep 17 00:00:00 2001 From: Oversword Date: Mon, 11 Apr 2022 03:06:40 +0100 Subject: [PATCH 1/2] Digilines chest compat with terumet; More efficient digilines compat with tubelib --- init.lua | 1 + techpack/digilines.lua | 9 +- terumet/digiline_chest.lua | 164 +++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 terumet/digiline_chest.lua diff --git a/init.lua b/init.lua index 5333787..53d9b1d 100644 --- a/init.lua +++ b/init.lua @@ -78,6 +78,7 @@ dofile(bls.modpath .. "/terumet/alloy_smelter.lua") dofile(bls.modpath .. "/terumet/ore_saw.lua") dofile(bls.modpath .. "/terumet/reformer.lua") dofile(bls.modpath .. "/terumet/vulcanizer.lua") +dofile(bls.modpath .. "/terumet/digiline_chest.lua") dofile(bls.modpath .. "/tool_damage_alert.lua") dofile(bls.modpath .. "/update_initial_privs.lua") dofile(bls.modpath .. "/unified_inventory/inventory_categories.lua") diff --git a/techpack/digilines.lua b/techpack/digilines.lua index 731f747..2a75ccb 100644 --- a/techpack/digilines.lua +++ b/techpack/digilines.lua @@ -1,13 +1,18 @@ if not minetest.global_exists("digiline") then return end if not minetest.global_exists("tubelib") then return end - +local channel_prefix = 'tubelib_' +local channel_prefix_l = #channel_prefix local digiline_conf = { receptor = {}, effector = { action = function(pos, node, channel, msg) + if #channel < channel_prefix_l+1 + or string.sub(channel, 1, channel_prefix_l) ~= channel_prefix + then return end + local tubelib_number = tubelib.get_node_number(pos) - local request_channel = "tubelib_"..tubelib_number + local request_channel = channel_prefix..tubelib_number if request_channel ~= channel then return end if type(msg) == 'table' and msg.cmd then diff --git a/terumet/digiline_chest.lua b/terumet/digiline_chest.lua new file mode 100644 index 0000000..f964d18 --- /dev/null +++ b/terumet/digiline_chest.lua @@ -0,0 +1,164 @@ +if not minetest.global_exists("terumet") then return end +if not minetest.global_exists("digilines") then return end +if not minetest.registered_nodes["digilines:chest"] then return end + +local terumet_machines = { + "terumet:mach_asmelt", + "terumet:mach_asmelt_lit", + "terumet:mach_crusher", + "terumet:mach_crusher_lit", + "terumet:mach_htfurn", + "terumet:mach_htfurn_lit", + "terumet:mach_htr_furnace", + "terumet:mach_htr_furnace_lit", + "terumet:mach_lavam", + "terumet:mach_lavam_lit", + "terumet:mach_repm", + "terumet:mach_vcoven", + "terumet:mach_vulcan", +} + +local function inv_to_string(inv, list_name) + local rep = "" + local list = inv:get_list(list_name) + if list then + for _,stack in ipairs(list) do + rep = rep..stack:to_string().."," + end + end + return rep, list +end + +local function send_message(pos, action, stack, from_slot, to_slot, side) + local channel = minetest.get_meta(pos):get_string("channel") + local msg = { + action = action, + stack = stack and stack:to_table(), + from_slot = from_slot, + to_slot = to_slot, + -- Duplicate the vector in case the caller expects it not to change. + side = side and vector.new(side) + } + digilines.receptor_send(pos, digilines.rules.default, channel, msg) +end + + +-- Checks if the inventory has become empty and, if so, sends an empty message. +local function check_empty(pos, inv) + if inv:is_empty("main") then + send_message(pos, "empty") + end +end + +-- Checks if the inventory has become full for a particular type of item and, +-- if so, sends a full message. +local function check_full(pos, inv, stack) + local one_item_stack = ItemStack(stack) + one_item_stack:set_count(1) + if not inv:room_for_item("main", one_item_stack) then + send_message(pos, "full", one_item_stack) + end +end + +local function send_inventory_updates(pos, inv, side, orig_list, new_list) + for i,orig_stack in ipairs(orig_list) do + local new_stack = new_list[i] + if orig_stack:get_count() ~= new_stack:get_count() + or orig_stack:get_name() ~= new_stack:get_name() + then + local taken, put + if orig_stack:get_name() == new_stack:get_name() then + local taken_count = orig_stack:get_count()-new_stack:get_count() + if taken_count > 0 then + orig_stack:set_count(taken_count) + taken = orig_stack + elseif taken_count < 0 then + orig_stack:set_count(-taken_count) + put = orig_stack + end + else + if orig_stack:get_count() > 0 then + taken = orig_stack + end + if new_stack:get_count() > 0 then + put = new_stack + end + end + if taken then + send_message(pos, "ttake", taken, i, nil, side) + end + if put then + send_message(pos, "tput", put, nil, i, side) + end + + if taken and not put then + check_empty(pos, inv) + elseif put then + check_full(pos, inv, put) + end + end + end +end + +local function timer_override(existing_on_timer, pos, dtime) + local machine = terumet.machine.readonly_state(pos) + local node = minetest.get_node(pos) + machine.rot = terumet.util3d.param2_to_rotation(node.param2) + + local input_inv, input_inv_name = terumet.machine.get_input(machine) + local input_pos = terumet.util3d.get_relative_pos(machine.rot, machine.pos, machine.input_side) + local do_input_logic = input_inv_name == 'main' and minetest.get_node(input_pos).name == "digilines:chest" + + local output_inv, output_inv_name = terumet.machine.get_output(machine) + local output_pos = terumet.util3d.get_relative_pos(machine.rot, machine.pos, machine.output_side) + local do_output_logic = output_inv_name == 'main' and minetest.get_node(output_pos).name == "digilines:chest" + + local orig_input + local orig_input_list + if do_input_logic then + orig_input, orig_input_list = inv_to_string(input_inv, input_inv_name) + end + + local orig_output + local orig_output_list + if do_output_logic then + orig_output, orig_output_list = inv_to_string(output_inv, output_inv_name) + end + + local ret = existing_on_timer(pos, dtime) + + if do_input_logic then + local new_input, new_input_list = inv_to_string(input_inv, input_inv_name) + if new_input ~= orig_input then + local input_side = vector.subtract(pos, input_pos) + send_inventory_updates(input_pos, input_inv, input_side, orig_input_list, new_input_list) + end + end + + if do_output_logic then + local new_output, new_output_list = inv_to_string(output_inv, output_inv_name) + if new_output ~= orig_output then + local output_side = vector.subtract(pos, output_pos) + send_inventory_updates(output_pos, output_inv, output_side, orig_output_list, new_output_list) + end + end + + return ret +end + +local function digiline_chest_compat(node_name) + local existing_def = minetest.registered_nodes[node_name] + if not existing_def then return end + + local existing_on_timer = existing_def.on_timer + + minetest.override_item(node_name, { + on_timer = function (pos, dtime) + return timer_override(existing_on_timer, pos, dtime) + end + }) +end + +for _,node_name in ipairs(terumet_machines) do + digiline_chest_compat(node_name) +end From 5da70bb2104ffa135be448d3105c0e410809d431 Mon Sep 17 00:00:00 2001 From: Oversword Date: Mon, 11 Apr 2022 19:01:03 +0100 Subject: [PATCH 2/2] Digiline global --- terumet/digiline_chest.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terumet/digiline_chest.lua b/terumet/digiline_chest.lua index f964d18..5151b7c 100644 --- a/terumet/digiline_chest.lua +++ b/terumet/digiline_chest.lua @@ -39,7 +39,7 @@ local function send_message(pos, action, stack, from_slot, to_slot, side) -- Duplicate the vector in case the caller expects it not to change. side = side and vector.new(side) } - digilines.receptor_send(pos, digilines.rules.default, channel, msg) + digiline.receptor_send(pos, digiline.rules.default, channel, msg) end