From 6fcaa3f31bc78b0c937b225a464025091233418d Mon Sep 17 00:00:00 2001 From: LeMagnesium Date: Thu, 1 Sep 2016 11:55:12 +0200 Subject: [PATCH] [pipeworks] Update - Fix global variable "rules" for #68 - Update the mod from its upstream repository - Convert globalstep in luaentity.lua into a loop using `minetest.after` --- mods/pipeworks/autocrafter.lua | 11 +- mods/pipeworks/compat.lua | 8 + mods/pipeworks/default_settings.txt | 3 +- mods/pipeworks/depends.txt | 1 + mods/pipeworks/description.txt | 1 + mods/pipeworks/devices.lua | 4 +- mods/pipeworks/filter-injector.lua | 225 ++++++++++++++++-- mods/pipeworks/init.lua | 8 +- mods/pipeworks/item_transport.lua | 5 +- mods/pipeworks/luaentity.lua | 44 ++-- mods/pipeworks/mod.conf | 1 + .../pipeworks_digiline_detector_tube_end.png | Bin 0 -> 1068 bytes .../pipeworks_digiline_detector_tube_inv.png | Bin 0 -> 765 bytes ...pipeworks_digiline_detector_tube_noctr.png | Bin 0 -> 892 bytes ...pipeworks_digiline_detector_tube_plain.png | Bin 0 -> 1500 bytes ...pipeworks_digiline_detector_tube_short.png | Bin 0 -> 526 bytes .../pipeworks_digiline_filter_input.png | Bin 0 -> 234 bytes .../pipeworks_digiline_filter_output.png | Bin 0 -> 217 bytes .../pipeworks_digiline_filter_side.png | Bin 0 -> 236 bytes .../pipeworks_digiline_filter_top.png | Bin 0 -> 236 bytes 20 files changed, 254 insertions(+), 57 deletions(-) create mode 100644 mods/pipeworks/description.txt create mode 100644 mods/pipeworks/mod.conf create mode 100644 mods/pipeworks/textures/pipeworks_digiline_detector_tube_end.png create mode 100644 mods/pipeworks/textures/pipeworks_digiline_detector_tube_inv.png create mode 100644 mods/pipeworks/textures/pipeworks_digiline_detector_tube_noctr.png create mode 100644 mods/pipeworks/textures/pipeworks_digiline_detector_tube_plain.png create mode 100644 mods/pipeworks/textures/pipeworks_digiline_detector_tube_short.png create mode 100644 mods/pipeworks/textures/pipeworks_digiline_filter_input.png create mode 100644 mods/pipeworks/textures/pipeworks_digiline_filter_output.png create mode 100644 mods/pipeworks/textures/pipeworks_digiline_filter_side.png create mode 100644 mods/pipeworks/textures/pipeworks_digiline_filter_top.png diff --git a/mods/pipeworks/autocrafter.lua b/mods/pipeworks/autocrafter.lua index def9603..faf5381 100755 --- a/mods/pipeworks/autocrafter.lua +++ b/mods/pipeworks/autocrafter.lua @@ -183,7 +183,14 @@ local function update_meta(meta, enabled) default.gui_bg_img.. default.gui_slots.. default.get_hotbar_bg(0,7) .. - "list[current_player;main;0,7;8,4;]") + "list[current_player;main;0,7;8,4;]" .. + "listring[current_player;main]".. + "listring[context;src]" .. + "listring[context;dst]" .. + "listring[current_player;main]".. + "listring[context;recipe]" .. + "listring[context;output]" + ) -- toggling the button doesn't quite call for running a recipe change check -- so instead we run a minimal version for infotext setting only @@ -223,7 +230,7 @@ local function upgrade_autocrafter(pos, meta) if not recipe then return end for idx, stack in ipairs(recipe) do if not stack:is_empty() then - minetest.item_drop(stack, "", pos) + minetest.add_item(pos, stack) stack:set_count(1) stack:set_wear(0) inv:set_stack("recipe", idx, stack) diff --git a/mods/pipeworks/compat.lua b/mods/pipeworks/compat.lua index c89e492..9c956e6 100755 --- a/mods/pipeworks/compat.lua +++ b/mods/pipeworks/compat.lua @@ -15,6 +15,10 @@ minetest.override_item("default:furnace", { insert_object = function(pos, node, stack, direction) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() + local timer = minetest.get_node_timer(pos) + if not timer:is_started() then + timer:start(1.0) + end if direction.y == 1 then return inv:add_item("fuel",stack) else @@ -60,6 +64,10 @@ minetest.override_item("default:furnace_active", { insert_object = function(pos,node,stack,direction) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() + local timer = minetest.get_node_timer(pos) + if not timer:is_started() then + timer:start(1.0) + end if direction.y == 1 then return inv:add_item("fuel", stack) else diff --git a/mods/pipeworks/default_settings.txt b/mods/pipeworks/default_settings.txt index bbf02ce..41a3f7a 100755 --- a/mods/pipeworks/default_settings.txt +++ b/mods/pipeworks/default_settings.txt @@ -10,6 +10,7 @@ pipeworks.enable_pipe_devices = true pipeworks.enable_redefines = true pipeworks.enable_mese_tube = true pipeworks.enable_detector_tube = true +pipeworks.enable_digiline_detector_tube = true pipeworks.enable_conductor_tube = true pipeworks.enable_accelerator_tube = true pipeworks.enable_crossing_tube = true @@ -19,4 +20,4 @@ pipeworks.enable_one_way_tube = true pipeworks.enable_priority_tube = true pipeworks.enable_cyclic_mode = true -pipeworks.delete_item_on_clearobject = true \ No newline at end of file +pipeworks.delete_item_on_clearobject = true diff --git a/mods/pipeworks/depends.txt b/mods/pipeworks/depends.txt index 02a542c..dff9dfb 100755 --- a/mods/pipeworks/depends.txt +++ b/mods/pipeworks/depends.txt @@ -1,3 +1,4 @@ default mesecons? mesecons_mvps? +digilines? diff --git a/mods/pipeworks/description.txt b/mods/pipeworks/description.txt new file mode 100644 index 0000000..9e6e800 --- /dev/null +++ b/mods/pipeworks/description.txt @@ -0,0 +1 @@ +This mod uses nodeboxes to supply a complete set of 3D pipes and tubes, along devices that work with them. diff --git a/mods/pipeworks/devices.lua b/mods/pipeworks/devices.lua index c96ad97..f7f6f45 100755 --- a/mods/pipeworks/devices.lua +++ b/mods/pipeworks/devices.lua @@ -3,7 +3,7 @@ local pipereceptor_on = nil local pipereceptor_off = nil -if mesecon then +if minetest.get_modpath("mesecons") then pipereceptor_on = { receptor = { state = mesecon.state.on, @@ -35,6 +35,8 @@ local pipes_devicelist = { "storage_tank_10" } +local rules = pipeworks.mesecons_rules -- Enough with the undefined global variable // MFF (Mg|01/07/2016 for #68) + -- Now define the nodes. local states = { "on", "off" } diff --git a/mods/pipeworks/filter-injector.lua b/mods/pipeworks/filter-injector.lua index bcfcbc9..7fbabc2 100755 --- a/mods/pipeworks/filter-injector.lua +++ b/mods/pipeworks/filter-injector.lua @@ -12,7 +12,30 @@ end local function set_filter_formspec(data, meta) local itemname = data.wise_desc.." Filter-Injector" - local formspec = "size[8,8.5]".. + + local formspec + if data.digiline then + formspec = "size[8,2.7]".. + "item_image[0,0;1,1;pipeworks:"..data.name.."]".. + "label[1,0;"..minetest.formspec_escape(itemname).."]".. + "field[0.3,1.5;8.0,1;channel;Channel;${channel}]".. + fs_helpers.cycling_button(meta, "button[0,2;4,1", "slotseq_mode", + {"Sequence slots by Priority", + "Sequence slots Randomly", + "Sequence slots by Rotation"}).. + fs_helpers.cycling_button(meta, "button[4,2;4,1", "exmatch_mode", + {"Exact match - off", + "Exact match - on "}) + else + local exmatch_button = "" + if data.stackwise then + exmatch_button = + fs_helpers.cycling_button(meta, "button[4,3.5;4,1", "exmatch_mode", + {"Exact match - off", + "Exact match - on "}) + end + + formspec = "size[8,8.5]".. "item_image[0,0;1,1;pipeworks:"..data.name.."]".. "label[1,0;"..minetest.formspec_escape(itemname).."]".. "label[0,1;Prefer item types:]".. @@ -21,12 +44,15 @@ local function set_filter_formspec(data, meta) {"Sequence slots by Priority", "Sequence slots Randomly", "Sequence slots by Rotation"}).. - "list[current_player;main;0,4.5;8,4;]" + exmatch_button.. + "list[current_player;main;0,4.5;8,4;]" .. + "listring[]" + end meta:set_string("formspec", formspec) end -- todo SOON: this function has *way too many* parameters -local function grabAndFire(data,slotseq_mode,filtmeta,frominv,frominvname,frompos,fromnode,filterfor,fromtube,fromdef,dir,fakePlayer,all) +local function grabAndFire(data,slotseq_mode,exmatch_mode,filtmeta,frominv,frominvname,frompos,fromnode,filterfor,fromtube,fromdef,dir,fakePlayer,all) local sposes = {} for spos,stack in ipairs(frominv:get_list(frominvname)) do local matches @@ -79,7 +105,11 @@ local function grabAndFire(data,slotseq_mode,filtmeta,frominv,frominvname,frompo if all then count = math.min(stack:get_count(), doRemove) if filterfor.count and filterfor.count > 1 then - count = math.min(filterfor.count, count) + if exmatch_mode ~= 0 and filterfor.count > count then + return false + else + count = math.min(filterfor.count, count) + end end else count = 1 @@ -103,7 +133,7 @@ local function grabAndFire(data,slotseq_mode,filtmeta,frominv,frominvname,frompo return false end -local function punch_filter(data, filtpos, filtnode) +local function punch_filter(data, filtpos, filtnode, msg) local filtmeta = minetest.get_meta(filtpos) local filtinv = filtmeta:get_inventory() local owner = filtmeta:get_string("owner") @@ -119,21 +149,110 @@ local function punch_filter(data, filtpos, filtnode) if not fromdef then return end local fromtube = fromdef.tube if not (fromtube and fromtube.input_inventory) then return end + + local slotseq_mode + local exact_match + local filters = {} - for _, filterstack in ipairs(filtinv:get_list("main")) do - local filtername = filterstack:get_name() - local filtercount = filterstack:get_count() - if filtername ~= "" then table.insert(filters, {name = filtername, count = filtercount}) end + if data.digiline then + local t_msg = type(msg) + if t_msg == "table" then + local slotseq = msg.slotseq + local t_slotseq = type(slotseq) + if t_slotseq == "number" and slotseq >= 0 and slotseq <= 2 then + slotseq_mode = slotseq + elseif t_slotseq == "string" then + slotseq = string.lower(slotseq) + if slotseq == "priority" then + slotseq_mode = 0 + elseif slotseq == "random" then + slotseq_mode = 1 + elseif slotseq == "rotation" then + slotseq_mode = 2 + end + end + + local exmatch = msg.exmatch + local t_exmatch = type(exmatch) + if t_exmatch == "number" and exmatch >= 0 and exmatch <= 1 then + exact_match = exmatch + elseif t_exmatch == "boolean" then + exact_match = exmatch and 1 or 0 + end + + local slotseq_index = msg.slotseq_index + if type(slotseq_index) == "number" then + -- This should allow any valid index, but I'm not completely sure what + -- constitutes a valid index, so I'm only allowing resetting it to 1. + if slotseq_index == 1 then + filtmeta:set_int("slotseq_index", slotseq_index) + set_filter_infotext(data, filtmeta) + end + end + + if slotseq_mode ~= nil then + filtmeta:set_int("slotseq_mode", slotseq_mode) + end + + if exact_match ~= nil then + filtmeta:set_int("exmatch_mode", exact_match) + end + + if slotseq_mode ~= nil or exact_match ~= nil then + set_filter_formspec(data, filtmeta) + end + + if msg.nofire then + return + end + + if type(msg.name) == "string" then + table.insert(filters, {name = msg.name, count = tonumber(msg.count) or 1}) + else + for _, filter in ipairs(msg) do + local t_filter = type(filter) + if t_filter == "table" then + if type(filter.name) == "string" then + table.insert(filters, {name = filter.name, count = tonumber(filter.count) or 1}) + end + elseif t_filter == "string" then + local filterstack = ItemStack(filter) + local filtername = filterstack:get_name() + local filtercount = filterstack:get_count() + if filtername ~= "" then table.insert(filters, {name = filtername, count = filtercount}) end + end + end + end + elseif t_msg == "string" then + local filterstack = ItemStack(msg) + local filtername = filterstack:get_name() + local filtercount = filterstack:get_count() + if filtername ~= "" then table.insert(filters, {name = filtername, count = filtercount}) end + end + else + for _, filterstack in ipairs(filtinv:get_list("main")) do + local filtername = filterstack:get_name() + local filtercount = filterstack:get_count() + if filtername ~= "" then table.insert(filters, {name = filtername, count = filtercount}) end + end end if #filters == 0 then table.insert(filters, "") end - local slotseq_mode = filtmeta:get_int("slotseq_mode") + + if slotseq_mode == nil then + slotseq_mode = filtmeta:get_int("slotseq_mode") + end + + if exact_match == nil then + exact_match = filtmeta:get_int("exmatch_mode") + end + local frommeta = minetest.get_meta(frompos) local frominv = frommeta:get_inventory() if fromtube.before_filter then fromtube.before_filter(frompos) end for _, frominvname in ipairs(type(fromtube.input_inventory) == "table" and fromtube.input_inventory or {fromtube.input_inventory}) do local done = false for _, filterfor in ipairs(filters) do - if grabAndFire(data, slotseq_mode, filtmeta, frominv, frominvname, frompos, fromnode, filterfor, fromtube, fromdef, dir, fakePlayer, data.stackwise) then + if grabAndFire(data, slotseq_mode, exact_match, filtmeta, frominv, frominvname, frompos, fromnode, filterfor, fromtube, fromdef, dir, fakePlayer, data.stackwise) then done = true break end @@ -154,8 +273,14 @@ for _, data in ipairs({ wise_desc = "Stackwise", stackwise = true, }, + { -- register even if no digilines + name = "digiline_filter", + wise_desc = "Digiline", + stackwise = true, + digiline = true, + }, }) do - minetest.register_node("pipeworks:"..data.name, { + local node = { description = data.wise_desc.." Filter-Injector", tiles = { "pipeworks_"..data.name.."_top.png", @@ -181,14 +306,6 @@ for _, data in ipairs({ pipeworks.after_place(pos) end, after_dig_node = pipeworks.after_dig, - on_receive_fields = function(pos, formname, fields, sender) - if not pipeworks.may_configure(pos, sender) then return end - fs_helpers.on_receive_fields(pos, fields) - local meta = minetest.get_meta(pos) - meta:set_int("slotseq_index", 1) - set_filter_formspec(data, meta) - set_filter_infotext(data, meta) - end, allow_metadata_inventory_put = function(pos, listname, index, stack, player) if not pipeworks.may_configure(pos, player) then return 0 end return stack:get_count() @@ -206,18 +323,63 @@ for _, data in ipairs({ local inv = meta:get_inventory() return inv:is_empty("main") end, - mesecons = { + tube = {connect_sides = {right = 1}}, + } + + if data.digiline then + node.groups.mesecon = nil + if not minetest.get_modpath("digilines") then + node.groups.not_in_creative_inventory = 1 + end + + node.on_receive_fields = function(pos, formname, fields, sender) + if not pipeworks.may_configure(pos, sender) then return end + fs_helpers.on_receive_fields(pos, fields) + + if fields.channel then + minetest.get_meta(pos):set_string("channel", fields.channel) + end + + local meta = minetest.get_meta(pos) + --meta:set_int("slotseq_index", 1) + set_filter_formspec(data, meta) + set_filter_infotext(data, meta) + end + node.digiline = { + effector = { + action = function(pos, node, channel, msg) + local meta = minetest.get_meta(pos) + local setchan = meta:get_string("channel") + if setchan ~= channel then return end + + punch_filter(data, pos, node, msg) + end, + }, + } + else + node.on_receive_fields = function(pos, formname, fields, sender) + if not pipeworks.may_configure(pos, sender) then return end + fs_helpers.on_receive_fields(pos, fields) + local meta = minetest.get_meta(pos) + meta:set_int("slotseq_index", 1) + set_filter_formspec(data, meta) + set_filter_infotext(data, meta) + end + node.mesecons = { effector = { action_on = function(pos, node) punch_filter(data, pos, node) end, }, - }, - tube = {connect_sides = {right = 1}}, - on_punch = function (pos, node, puncher) + } + node.on_punch = function (pos, node, puncher) punch_filter(data, pos, node) - end, - }) + end + end + + + + minetest.register_node("pipeworks:"..data.name, node) end minetest.register_craft( { @@ -237,3 +399,14 @@ minetest.register_craft( { { "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" } }, }) + +if minetest.get_modpath("digilines") then + minetest.register_craft( { + output = "pipeworks:digiline_filter 2", + recipe = { + { "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" }, + { "group:stick", "digilines:wire_std_00000000", "homedecor:plastic_sheeting" }, + { "default:steel_ingot", "default:steel_ingot", "homedecor:plastic_sheeting" } + }, + }) +end diff --git a/mods/pipeworks/init.lua b/mods/pipeworks/init.lua index 5165617..b093812 100755 --- a/mods/pipeworks/init.lua +++ b/mods/pipeworks/init.lua @@ -16,9 +16,11 @@ pipeworks.modpath = minetest.get_modpath("pipeworks") dofile(pipeworks.modpath.."/default_settings.txt") -- Read the external config file if it exists. -if io.open(pipeworks.worldpath.."/pipeworks_settings.txt","r") then - dofile(pipeworks.worldpath.."/pipeworks_settings.txt") - io.close() +local worldsettingspath = pipeworks.worldpath.."/pipeworks_settings.txt" +local worldsettingsfile = io.open(worldsettingspath, "r") +if worldsettingsfile then + worldsettingsfile:close() + dofile(worldsettingspath) end -- Random variables diff --git a/mods/pipeworks/item_transport.lua b/mods/pipeworks/item_transport.lua index 037cad7..ee17611 100755 --- a/mods/pipeworks/item_transport.lua +++ b/mods/pipeworks/item_transport.lua @@ -249,7 +249,10 @@ luaentity.register_entity("pipeworks:tubed_item", { if not found_next then drop_pos = minetest.find_node_near(vector.add(self.start_pos, velocity), 1, "air") if drop_pos then - minetest.item_drop(stack, "", drop_pos) + -- Using add_item instead of item_drop since this makes pipeworks backward + -- compatible with Minetest 0.4.13. + -- Using item_drop here makes Minetest 0.4.13 crash. + minetest.add_item(drop_pos, stack) self:remove() return end diff --git a/mods/pipeworks/luaentity.lua b/mods/pipeworks/luaentity.lua index e13c613..68d1660 100755 --- a/mods/pipeworks/luaentity.lua +++ b/mods/pipeworks/luaentity.lua @@ -29,7 +29,7 @@ local function read_entities() end local function write_entities() - for _, entity in pairs(luaentity.entities) do + for _, entity in pairs(luaentity.entities or {}) do setmetatable(entity, nil) for _, attached in pairs(entity._attached_entities) do if attached.entity then @@ -53,31 +53,29 @@ end local active_blocks = {} -- These only contain active blocks near players (i.e., not forceloaded ones) local handle_active_blocks_step = 2 -local handle_active_blocks_timer = 0 -minetest.register_globalstep(function(dtime) - handle_active_blocks_timer = handle_active_blocks_timer + dtime - if handle_active_blocks_timer >= handle_active_blocks_step then - handle_active_blocks_timer = handle_active_blocks_timer - handle_active_blocks_step - local active_block_range = tonumber(minetest.setting_get("active_block_range")) or 2 - local new_active_blocks = {} - for _, player in ipairs(minetest.get_connected_players()) do - local blockpos = get_blockpos(player:getpos()) - local minp = vector.subtract(blockpos, active_block_range) - local maxp = vector.add(blockpos, active_block_range) +local function active_blocks_step() + local active_block_range = tonumber(minetest.setting_get("active_block_range")) or 2 + local new_active_blocks = {} + for _, player in ipairs(minetest.get_connected_players()) do + local blockpos = get_blockpos(player:getpos()) + local minp = vector.subtract(blockpos, active_block_range) + local maxp = vector.add(blockpos, active_block_range) - for x = minp.x, maxp.x do - for y = minp.y, maxp.y do - for z = minp.z, maxp.z do - local pos = {x = x, y = y, z = z} - new_active_blocks[minetest.hash_node_position(pos)] = pos - end - end - end + for x = minp.x, maxp.x do + for y = minp.y, maxp.y do + for z = minp.z, maxp.z do + local pos = {x = x, y = y, z = z} + new_active_blocks[minetest.hash_node_position(pos)] = pos + end + end end - active_blocks = new_active_blocks - -- todo: callbacks on block load/unload end -end) + active_blocks = new_active_blocks + -- todo: callbacks on block load/unload + + minetest.after(handle_active_blocks_step, active_blocks_step) +end +minetest.after(0, active_blocks_step) local function is_active(pos) return active_blocks[minetest.hash_node_position(get_blockpos(pos))] ~= nil diff --git a/mods/pipeworks/mod.conf b/mods/pipeworks/mod.conf new file mode 100644 index 0000000..d9d2984 --- /dev/null +++ b/mods/pipeworks/mod.conf @@ -0,0 +1 @@ +name = pipeworks diff --git a/mods/pipeworks/textures/pipeworks_digiline_detector_tube_end.png b/mods/pipeworks/textures/pipeworks_digiline_detector_tube_end.png new file mode 100644 index 0000000000000000000000000000000000000000..e9d01bae4c895d88ab7b2d180c7801b32b726c19 GIT binary patch literal 1068 zcmV+{1k?M8P)^2dM&Pp9%LymL!PGd^#Bzo8wi8V}VEU2Aa z4;#u!dAFig`aU*%x#8VCwaU@hkfS3Xo`D}jfsJ4o^Whn&A|D$n$hncb0X9TXa$~0y zpZgYgN<~6U?s_9%=_nfMsMq&}6u&t^;D)}^M*ES8A~}3?r5;U$8OcC+!J{7b#2BOQ zg&u@TjY2tmkPl`kLM`2y3LFzk6DW6VgbI~o94SM`^nK-yhdm)e#~W&)`I)X($9%gx zWQ!!<7jMO;DEFlo9`aq9|IEvEa>%m3_hsn)$oAXxbSnSa?Bc`Wc&MFrDQ5-08awL^ z6cmt=K$W?Y#v`9d=vYwmC*ek}1#IYA z(@5!>aN&wPr=nF7pTZt2>H5w^O2?9mNwk8zq>-%QPk9ea>3HHIrE5XM3l8Lb$k-SG zjOfZ}tmxX%@N}NSksM;)AS;yw)^xpa7AM(0&;C0VMUm}}Kl7qIA~-yGp7&kdix-VIze429?D=ewRKC&p+! z44jdSOyEzXQX|KohkqC~kl{c`Aszz67kB6?;VT{Xj4?xHv?qKi)I(3YMg?lDT-W#R z2g(m+=qP^}_+DQQ`vc=dVHEH=;pg0Vy%X5*{WUjo>0-kKM`{b+C3iz?ID>*(!MlSV zU?UpEoULfR^#W}8?vb;YRw^dg2!j)6F|ECEvEkeuXw0c?A=45Yp;ysZP>Uf~J#6$% z!c`3AY=n)zU(gX#C>I-2J-=|Zpi&+-22nPrF{k!I<|%B1`b5InjK(VJW24_Mc%rf7 zEK?dA+Amqqc;+k_JJ^VHN^8p5YiO|H_*+^rXB$soL+XTgQ);>6V8a9@?_z34X|Uma mJ#Zt_5*sSaxDor3PyG+7WQ2jMDLr-o0000(`)YR40)z;S5*VotB*x1?G+1uOO+}zyV-QC{a-Y2H>3;+NC z0d!JMQvg8b*k%9#00Cl4M??UK1szBL000SaNLh0L01FcU01FcV0GgZ_00007bV*G` z2jBz}5-ByFCKL_uzZ#@fk-eDu^QS;MyEs8ZZ*cq+&Vl4{B+IX=s z*c<1e76nw;Qy8TYwIy;waw-9C73=uKkx?A1BG8*HU%*?IBA25V6xQQJDvbkw3CRp(5gLM2)2 z%$^)Uvb8h0!IO0VI#Y|Dj1Ynok2xx1v^;vTA!linW~taYs<+BsYn;ZJoz^&2X)A~h v8u_j>((d=~wfT?Le}|twd>G+>O%ow3thOsh00000NkvXXu0mjf5n*=e literal 0 HcmV?d00001 diff --git a/mods/pipeworks/textures/pipeworks_digiline_detector_tube_noctr.png b/mods/pipeworks/textures/pipeworks_digiline_detector_tube_noctr.png new file mode 100644 index 0000000000000000000000000000000000000000..6f078863ad8536cccf35545ae01af85357d491ca GIT binary patch literal 892 zcmV-?1B3jDP)-F& zgQ7t$Dw<4fP3`{K=U6~9VkKpz&*5|NWW|Nrbul5r4Hssfz{G?753P`sTn{nf=pC&) zPPR&7!jCFC_Z+?H5EH}jKqup9D-|Y!Z#A8SqqVrlgwQ!h1&t@FVSouwt~q+5@j?}A zOenjcXHII3F)_NY>3ja=`IwMiNy6EB>uF4Qx+0EWQCk`lGT!sYBk(H{nDC;MKOTWP zbTOg4f(wQ1VM2Hn7dA@qxgVaRR4BycW)QndhheP4!O#_ZF4SQtqkCKGcp`#WdcyJU zbutGcgzKi9O*vU` zw&1!IXSbXz=~;5sjGj3s51dW8Zq8Z8$(+uN#)Rvh=qzYVx%88-Tk)BcuS@96=^Jy+ zioPYCHGLDVnbY@^qcuHquA0*Gz|oq%gll5@aykq8R$Q~B@0nJb<=Z0v?@*RyzS;jS z%4%2SRlx^!nbq5QUDZ``c>Ooq98e`MZRz>%?Iv8DivGq z%>OG;Bk7NX6ynZ9e6u5430G-<5ClP_0__M_iX|7Sk#c?MTgr_**BQ!aI0~%L4?R97 z+=2_QHv$u`yW~P4ZA=8-o<_pE>?Xp5H7aS8yxZv!Cc-$SwczA!;9b>8YvWNfQey{ah5{$6k}rOmh_~Q%Ep9LkI$SX z)XKrcD9mScW;CA39fb*BAINAu(OHB;Obmx54|L|Va-}h$-HL?HBdu&~VItIPPNuY8 z{Qwh|`@%^|Yvl+`NS*O+N~5qWOaxxVyOhRW2AFWZ@3@d_i3#QBTu5EXr~U_J>fxan SDlsbn0000< literal 0 HcmV?d00001 diff --git a/mods/pipeworks/textures/pipeworks_digiline_detector_tube_plain.png b/mods/pipeworks/textures/pipeworks_digiline_detector_tube_plain.png new file mode 100644 index 0000000000000000000000000000000000000000..86ded6f9e00b20f7c196deccd7596c10211d84f3 GIT binary patch literal 1500 zcmV<21ta>2P)Cf>sHv%`s;a81tE;T6tgWrBuCA`H zudlGMu(7eRva+(Xv$M3cw6(Rhwzjsnx3{>sxVgExy1Kf%ySu!+yuH1>zP`S{zrVo1 zz`?=6!otGC!^6bH#KpzM#>U3S$H&OX$jQmc%F4>i%gfBn%+1Zs&d$!y&(F}%(9zM+ z($dn?)6>+{)YaA1*4Eb7*VowC*xA|H+S=OO+}z&Y-r(Ti;o;%t=H`cAS8V_Q00DGT zPE!Ct=GbNc0004EOGiWihy@);00009a7bBm000XU000XU0RWnu7ytkO2XskIMF-#n z5)vshF*E@c000CdNklToR z4=#XNO-F=fj9D|T7>LjepEb9Z#p6C1Rm-Yr+R0I|p<8yX*05{EQd-JLKc&)XNls^F zMNa3GT+XbYRZP2aqPY#z(5l9nT`y|KxYlRQE<2XhaLoFtdFs|R$2O(SY&xaL86};S zo+(mR&ZZRAG#%9~=~m^qUeq*4t=4VL=KHYQy&K=$PDky*c;elAeb1lxl6>&4u)BG% zvr~Av_vii}J8xv^+h}q#oX`Eg`?tO6^lloM-wp|R{ODO~i#3N*hR7L@7?98=AZ7Ll zykzNpI!ok&gaNS@D{TU@a!BAemJSq|g(fRaVqI3c1TxAiLfgdlvkD7+Rz4HECgB>$ z$pu0?#CD`S3oQ~l#Lii10y*h5kxdr%(ph31RtCg6L|Oz+fV{Lz^Hzth%FBRr&do4JngX6j{!t zQ%^HFC7nJoEvupGE$1)SDw|GOGd1nhK>JXsS1e7pY^UhDZryV2s-|b8Y2*V|mdtvo?5Z`VX7D&oAG7A`k%kCezh=$YtRTWQ?g+G58XVOT zp_V-Y9!pcZjEGvJN2p8ezGxsquiO#p5gTeJh;WQKp&qe`TS0_+G$qm^a04UTM1)hF z5or_X!PqJyqT~)(>4AUQKtxIRNa*2N6-1cU#T6@UW>ysu<=Uu4q($J0QPo0(W6v27 zx+K!Al@L)Xd7KmJ5E@xFB5d8KP2_^m;8;aO%^nhK68h@6h*0$#Vm(6rs)h*D9jqxG)c}xh1XyMhtgcToen~)-A3Q zj0El}3`!1L*y3u735GiwgCd3P(cor@5#bKQpeEQ@iyMWBJ??k_js#oK01z0smR#GX^0>FZd+zmyZvv4_kb|z{NxeOMnjr z!N!jm#F&U+W4Nh8*w_gdgpq{J$4$p!qa!YS{7Z)>`~H6Fe&ug@(>HbV zR@CRF*|k~o)0o!eUDum>S9Pxi!RAUqn{AZxh|5GRw@Dz$dx=)WyfBek1WQ5DI#@YM zGASYk8&UWWa~3GE=0f|NNNf~&BGQbcb{y$3UwS-}&w?wd1!l9^Z1xTP0gxpkntUO| QJpcdz07*qoM6N<$f*K{?ng9R* literal 0 HcmV?d00001 diff --git a/mods/pipeworks/textures/pipeworks_digiline_filter_input.png b/mods/pipeworks/textures/pipeworks_digiline_filter_input.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ffa53bcaaa96ca6d71e636b9654159b7f6332a GIT binary patch literal 234 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa4)6(awYD@54G#2lcTG-Aa0uNm zrR=MysOVs89TyWNz_HXFsEo6~BeIx*fm;}a85w5HkpK#^mw5WRvft+s66O+PU^m+f z6iV`RaSY+OuG_nt^MC;lYbeY4N2Wn6HV!VAb_vQI*m!An!?8X)w>@6RWeq-OHwOl9 zKA2IcVBF0+#UX?%==JX~x6o%QR#Q$E3D+7m{#2^EldS*!%O&p$f$7Jy1ysMU37eAg YFHFUlGp^6t5ojBOr>mdKI;Vst0Atxl-~a#s literal 0 HcmV?d00001 diff --git a/mods/pipeworks/textures/pipeworks_digiline_filter_output.png b/mods/pipeworks/textures/pipeworks_digiline_filter_output.png new file mode 100644 index 0000000000000000000000000000000000000000..4c57d0abdb5de861e850384dee0c32dc3c628b5f GIT binary patch literal 217 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa2=EDU^>lYlPE4@2G!G39bO_zA zsHo^*YaJI8#rmo)38;p%z$3Dlfq`2Xgc%uT&5-~KvX^-Jy0YKr5fbK7+_7u&CZJG= zr;B3<$Mw>)8wC#-a4EE+D83Uv6C8FZzf%Y+Yy85}Sb4q9e0KQC4aR2}S literal 0 HcmV?d00001 diff --git a/mods/pipeworks/textures/pipeworks_digiline_filter_top.png b/mods/pipeworks/textures/pipeworks_digiline_filter_top.png new file mode 100644 index 0000000000000000000000000000000000000000..04ffda01e6a136ac44b7ceef4f9506ee9c96fc97 GIT binary patch literal 236 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPGa4)6(awYD@54G#2lcTG-AkW%(_ z2;Hx!s2CR$gol_Eal|aox4|Am;%E0haHns+?g(q8zi<3v6IuHcL3CZCzb=$Y_0RT4LJi#%mX3 zGA>W!bhB^&Vv&#HXxUHx3vIVCg!0LPq3tpET3 literal 0 HcmV?d00001