From d91e0b66cb7971ba54d071a0955f17d1a7b0162e Mon Sep 17 00:00:00 2001 From: Jeija Date: Wed, 26 Dec 2012 22:54:28 +0100 Subject: Re-write pistons from scratch, propably fixes a lot of bugs and doesn't cause too many new ones. --- mesecons_mvps/init.lua | 117 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 87 insertions(+), 30 deletions(-) (limited to 'mesecons_mvps') diff --git a/mesecons_mvps/init.lua b/mesecons_mvps/init.lua index 3903910..57c538d 100644 --- a/mesecons_mvps/init.lua +++ b/mesecons_mvps/init.lua @@ -2,42 +2,99 @@ mesecon.mvps_stoppers={} -function mesecon:is_mvps_stopper(nodename) - local i=1 - repeat - i=i+1 - if mesecon.mvps_stoppers[i]==nodename then return true end - until mesecon.mvps_stoppers[i]==nil - return false +function mesecon:is_mvps_stopper(node, pushdir, stack, stackid) + local get_stopper = mesecon.mvps_stoppers[node.name] + if type (get_stopper) == "function" then + get_stopper = get_stopper(node, pushdir, stack, stackid) + end + return get_stopper end -function mesecon:register_mvps_stopper(nodename) - local i=1 - repeat - i=i+1 - if mesecon.mvps_stoppers[i]==nil then break end - until false - mesecon.mvps_stoppers[i]=nodename +function mesecon:register_mvps_stopper(nodename, get_stopper) + if get_stopper == nil then + get_stopper = true + end + mesecon.mvps_stoppers[nodename] = get_stopper end -function mesecon:mvps_push(pos, direction) -- pos: pos of mvps; direction: direction of push - pos.x=pos.x+direction.x - pos.y=pos.y+direction.y - pos.z=pos.z+direction.z +function mesecon:mvps_process_stack(stack) + -- update mesecons for placed nodes ( has to be done after all nodes have been added ) + for _, n in ipairs(stack) do + mesecon.on_placenode(n.pos, n.node) + mesecon:update_autoconnect(n.pos) + end +end - local lpos = {x=pos.x, y=pos.y, z=pos.z} - local lnode = minetest.env:get_node(lpos) - local newnode - minetest.env:remove_node(lpos) - while not(lnode.name == "ignore" or lnode.name == "air" or not(minetest.registered_nodes[lnode.name].liquidtype == "none")) do - lpos.x=lpos.x+direction.x - lpos.y=lpos.y+direction.y - lpos.z=lpos.z+direction.z - newnode = lnode - lnode = minetest.env:get_node(lpos) - minetest.env:add_node(lpos, newnode) - nodeupdate(lpos) +function mesecon:mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: direction of push; maximum: maximum nodes to be pushed + np = {x = pos.x, y = pos.y, z = pos.z} + + -- determine the number of nodes to be pushed + local nodes = {} + while true do + nn = minetest.env:get_node_or_nil(np) + if not nn or #nodes > maximum then + -- don't push at all, something is in the way (unloaded map or too many nodes) + return + end + + if nn.name == "air" + or minetest.registered_nodes[nn.name].liquidtype ~= "none" then --is liquid + break + end + + table.insert (nodes, {node = nn, pos = np}) + + np = mesecon:addPosRule(np, dir) + end + + -- determine if one of the nodes blocks the push + for id, n in ipairs(nodes) do + if mesecon:is_mvps_stopper(n.node, dir, nodes, id) then + return end + end + + -- remove all nodes + for _, n in ipairs(nodes) do + minetest.env:remove_node(n.pos) + nodeupdate(n.pos) + end + + -- update mesecons for removed nodes ( has to be done after all nodes have been removed ) + for _, n in ipairs(nodes) do + mesecon.on_dignode(n.pos, n.node) + mesecon:update_autoconnect(n.pos) + end + + -- add nodes + for _, n in ipairs(nodes) do + np = mesecon:addPosRule(n.pos, dir) + minetest.env:add_node(np, n.node) + nodeupdate(np) + end + + for i in ipairs(nodes) do + nodes[i].pos = mesecon:addPosRule(nodes[i].pos, dir) + end + + return true, nodes +end + +function mesecon:mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons) + np = mesecon:addPosRule(pos, dir) + nn = minetest.env:get_node(np) + + if minetest.registered_nodes[nn.name].liquidtype == "none" + and not mesecon:is_mvps_stopper(nn, {x = -dir.x, y = -dir.y, z = -dir.z}, {{pos = np, node = nn}}, 1) then + minetest.env:remove_node(np) + minetest.env:add_node(pos, nn) + + nodeupdate(np) + nodeupdate(pos) + mesecon.on_dignode(np, nn) + mesecon:update_autoconnect(np) + end + return {{pos = np, node = nn}} end function mesecon:mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: direction of pull -- cgit v1.2.3 From 7fe4947056656982ee9af9fad8d67d14e7086c9a Mon Sep 17 00:00:00 2001 From: Jeija Date: Thu, 27 Dec 2012 09:28:04 +0100 Subject: Bugfix foes for pistons, delayyrs, gates and microcontrollers. Rework delayers. --- mesecons/init.lua | 3 +- mesecons/internal.lua | 35 ++++++++++++------ mesecons_delayer/init.lua | 90 +++++++++++++++++------------------------------ mesecons_mvps/init.lua | 2 +- 4 files changed, 60 insertions(+), 70 deletions(-) (limited to 'mesecons_mvps') diff --git a/mesecons/init.lua b/mesecons/init.lua index f53a5bf..011c96f 100644 --- a/mesecons/init.lua +++ b/mesecons/init.lua @@ -70,6 +70,7 @@ dofile(minetest.get_modpath("mesecons").."/internal.lua"); -- Deprecated stuff -- To be removed in future releases +-- Currently there is nothing here dofile(minetest.get_modpath("mesecons").."/legacy.lua"); -- API @@ -100,7 +101,7 @@ function mesecon:receptor_off(pos, rules) end -print("[OK] mesecons") +print("[OK] Mesecons") --The actual wires dofile(minetest.get_modpath("mesecons").."/wires.lua"); diff --git a/mesecons/internal.lua b/mesecons/internal.lua index c7efd1a..2d84787 100644 --- a/mesecons/internal.lua +++ b/mesecons/internal.lua @@ -331,9 +331,26 @@ function mesecon:turnoff(pos, rulename) end -function mesecon:connected_to_receptor(pos, checked) - checked = checked or {} +function mesecon:connected_to_receptor(pos) + local node = minetest.env:get_node(pos) + + -- Check if conductors around are connected + local rules = mesecon:get_any_inputrules(node) + if not rules then return false end + + for _, rule in ipairs(rules) do + local np = mesecon:addPosRule(pos, rule) + if mesecon:rules_link(np, pos) then + if mesecon:find_receptor_on(np, {}) then + return true + end + end + end + return false +end + +function mesecon:find_receptor_on(pos, checked) -- find out if node has already been checked (to prevent from endless loop) for _, cp in ipairs(checked) do if mesecon:cmpPos(cp, pos) then @@ -343,27 +360,25 @@ function mesecon:connected_to_receptor(pos, checked) -- add current position to checked table.insert(checked, {x=pos.x, y=pos.y, z=pos.z}) - local node = minetest.env:get_node(pos) + if mesecon:is_receptor_on(node.name) then + return true + end + if mesecon:is_conductor(node.name) then - -- Check if conductors around are connected local rules = mesecon:conductor_get_rules(node) - for _, rule in ipairs(rules) do local np = mesecon:addPosRule(pos, rule) if mesecon:rules_link(np, pos) then - connected, checked = mesecon:connected_to_receptor(np, checked) - if connected then + if mesecon:find_receptor_on(np, checked) then return true end end end - elseif mesecon:is_receptor_on(node.name) then - return true end - return false, checked + return false end function mesecon:rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule diff --git a/mesecons_delayer/init.lua b/mesecons_delayer/init.lua index 6bdb72d..2175c3c 100644 --- a/mesecons_delayer/init.lua +++ b/mesecons_delayer/init.lua @@ -1,28 +1,16 @@ -- Function that get the input/output rules of the delayer local delayer_get_output_rules = function(node) - local rules = {} - if node.param2 == 0 then - table.insert(rules, {x = 1, y = 0, z = 0}) - elseif node.param2 == 2 then - table.insert(rules, {x =-1, y = 0, z = 0}) - elseif node.param2 == 1 then - table.insert(rules, {x = 0, y = 0, z =-1}) - elseif node.param2 == 3 then - table.insert(rules, {x = 0, y = 0, z = 1}) + local rules = {{x = 0, y = 0, z = 1}} + for i = 0, node.param2 do + rules = mesecon:rotate_rules_left(rules) end return rules end local delayer_get_input_rules = function(node) - local rules = {} - if node.param2 == 0 then - table.insert(rules, {x =-1, y = 0, z = 0}) - elseif node.param2 == 2 then - table.insert(rules, {x = 1, y = 0, z = 0}) - elseif node.param2 == 1 then - table.insert(rules, {x = 0, y = 0, z = 1}) - elseif node.param2 == 3 then - table.insert(rules, {x = 0, y = 0, z =-1}) + local rules = {{x = 0, y = 0, z = -1}} + for i = 0, node.param2 do + rules = mesecon:rotate_rules_left(rules) end return rules end @@ -30,54 +18,30 @@ end -- Functions that are called after the delay time local delayer_turnon = function(params) - local rules = delayer_get_output_rules(params) + local rules = delayer_get_output_rules(params.node) mesecon:receptor_on(params.pos, rules) end local delayer_turnoff = function(params) - local rules = delayer_get_output_rules(params) + local rules = delayer_get_output_rules(params.node) mesecon:receptor_off(params.pos, rules) end -local delayer_update = function(pos, node) - if string.find(node.name, "mesecons_delayer:delayer_off")~=nil then - local time = 0 - if node.name=="mesecons_delayer:delayer_off_1" then - mesecon:swap_node(pos, "mesecons_delayer:delayer_on_1") - time=0.1 - elseif node.name=="mesecons_delayer:delayer_off_2" then - mesecon:swap_node(pos, "mesecons_delayer:delayer_on_2") - time=0.3 - elseif node.name=="mesecons_delayer:delayer_off_3" then - mesecon:swap_node(pos, "mesecons_delayer:delayer_on_3") - time=0.5 - elseif node.name=="mesecons_delayer:delayer_off_4" then - mesecon:swap_node(pos, "mesecons_delayer:delayer_on_4") - time=1 - end - minetest.after(time, delayer_turnon, {pos=pos, param2=node.param2}) - end +local delayer_activate = function(pos, node) + local def = minetest.registered_nodes[node.name] + local time = def.delayer_time + mesecon:swap_node(pos, def.delayer_onstate) + minetest.after(time, delayer_turnon , {pos = pos, node = node}) +end - if string.find(node.name, "mesecons_delayer:delayer_on")~=nil then - local time = 0 - if node.name=="mesecons_delayer:delayer_on_1" then - mesecon:swap_node(pos, "mesecons_delayer:delayer_off_1") - time=0.1 - elseif node.name=="mesecons_delayer:delayer_on_2" then - mesecon:swap_node(pos, "mesecons_delayer:delayer_off_2") - time=0.3 - elseif node.name=="mesecons_delayer:delayer_on_3" then - mesecon:swap_node(pos, "mesecons_delayer:delayer_off_3") - time=0.5 - elseif node.name=="mesecons_delayer:delayer_on_4" then - mesecon:swap_node(pos, "mesecons_delayer:delayer_off_4") - time=1 - end - minetest.after(time, delayer_turnoff, {pos=pos, param2=node.param2}) - end +local delayer_deactivate = function(pos, node) + local def = minetest.registered_nodes[node.name] + local time = def.delayer_time + mesecon:swap_node(pos, def.delayer_offstate) + minetest.after(time, delayer_turnoff, {pos = pos, node = node}) end ---Actually register the 2 (states) x 4 (delay times) delayers +-- Register the 2 (states) x 4 (delay times) delayers for i = 1, 4 do local groups = {} @@ -87,6 +51,12 @@ else groups = {bendy=2,snappy=1,dig_immediate=2, not_in_creative_inventory=1} end +local delaytime +if i == 1 then delaytime = 0.1 +elseif i == 2 then delaytime = 0.3 +elseif i == 3 then delaytime = 0.5 +elseif i == 4 then delaytime = 1.0 end + boxes = {{ -6/16, -8/16, -6/16, 6/16, -7/16, 6/16 }, -- the main slab { -2/16, -7/16, -4/16, 2/16, -26/64, -3/16 }, -- the jeweled "on" indicator @@ -138,6 +108,8 @@ minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), { mesecon:swap_node(pos,"mesecons_delayer:delayer_off_1") end end, + delayer_time = delaytime, + delayer_onstate = "mesecons_delayer:delayer_on_"..tostring(i), mesecons = { receptor = { @@ -147,7 +119,7 @@ minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), { effector = { rules = delayer_get_input_rules, - action_change = delayer_update + action_on = delayer_activate } } }) @@ -190,6 +162,8 @@ minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), { mesecon:swap_node(pos,"mesecons_delayer:delayer_on_1") end end, + delayer_time = delaytime, + delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i), mesecons = { receptor = { @@ -199,7 +173,7 @@ minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), { effector = { rules = delayer_get_input_rules, - action_change = delayer_update + action_off = delayer_deactivate } } }) diff --git a/mesecons_mvps/init.lua b/mesecons_mvps/init.lua index 57c538d..98bbc94 100644 --- a/mesecons_mvps/init.lua +++ b/mesecons_mvps/init.lua @@ -20,7 +20,7 @@ end function mesecon:mvps_process_stack(stack) -- update mesecons for placed nodes ( has to be done after all nodes have been added ) for _, n in ipairs(stack) do - mesecon.on_placenode(n.pos, n.node) + mesecon.on_placenode(n.pos, minetest.env:get_node(n.pos)) mesecon:update_autoconnect(n.pos) end end -- cgit v1.2.3 From c062411fa18100c6aa0645d6b7663be42268602d Mon Sep 17 00:00:00 2001 From: Jeija Date: Thu, 27 Dec 2012 20:38:12 +0100 Subject: Fix another two piston-related bugs --- mesecons_mvps/init.lua | 2 +- mesecons_pistons/init.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'mesecons_mvps') diff --git a/mesecons_mvps/init.lua b/mesecons_mvps/init.lua index 98bbc94..9f8242b 100644 --- a/mesecons_mvps/init.lua +++ b/mesecons_mvps/init.lua @@ -94,7 +94,7 @@ function mesecon:mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: dire mesecon.on_dignode(np, nn) mesecon:update_autoconnect(np) end - return {{pos = np, node = nn}} + return {{pos = np, node = {param2 = 0, name = "air"}}, {pos = pos, node = nn}} end function mesecon:mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: direction of pull diff --git a/mesecons_pistons/init.lua b/mesecons_pistons/init.lua index 576c03a..a51e16e 100644 --- a/mesecons_pistons/init.lua +++ b/mesecons_pistons/init.lua @@ -660,7 +660,7 @@ local piston_get_stopper = function (node, dir, stack, stackid) end mesecon:register_mvps_stopper("mesecons_pistons:piston_normal_on", piston_get_stopper) -mesecon:register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_pusher_get_stopper) +mesecon:register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_get_stopper) mesecon:register_mvps_stopper("mesecons_pistons:piston_up_normal_on", piston_up_down_get_stopper) mesecon:register_mvps_stopper("mesecons_pistons:piston_up_sticky_on", piston_up_down_get_stopper) -- cgit v1.2.3