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 0000000..e9d01ba Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_digiline_detector_tube_end.png differ diff --git a/mods/pipeworks/textures/pipeworks_digiline_detector_tube_inv.png b/mods/pipeworks/textures/pipeworks_digiline_detector_tube_inv.png new file mode 100644 index 0000000..0ed763a Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_digiline_detector_tube_inv.png differ 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 0000000..6f07886 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_digiline_detector_tube_noctr.png differ 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 0000000..86ded6f Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_digiline_detector_tube_plain.png differ diff --git a/mods/pipeworks/textures/pipeworks_digiline_detector_tube_short.png b/mods/pipeworks/textures/pipeworks_digiline_detector_tube_short.png new file mode 100644 index 0000000..6729c53 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_digiline_detector_tube_short.png differ 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 0000000..c1ffa53 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_digiline_filter_input.png differ 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 0000000..4c57d0a Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_digiline_filter_output.png differ diff --git a/mods/pipeworks/textures/pipeworks_digiline_filter_side.png b/mods/pipeworks/textures/pipeworks_digiline_filter_side.png new file mode 100644 index 0000000..6a77896 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_digiline_filter_side.png differ 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 0000000..04ffda0 Binary files /dev/null and b/mods/pipeworks/textures/pipeworks_digiline_filter_top.png differ