From 0b344c5e888854487ee600c76214e7d02dd73b1d Mon Sep 17 00:00:00 2001 From: Henry Behrendt Date: Sat, 4 Sep 2021 22:04:12 +0200 Subject: [PATCH] wiring --- mesecons/init.lua | 8 ++-- mesecons/internal.lua | 49 ++++++++++++++++--------- mesecons/services.lua | 2 +- mesecons_wires/init.lua | 81 +++++++++++++---------------------------- 4 files changed, 63 insertions(+), 77 deletions(-) diff --git a/mesecons/init.lua b/mesecons/init.lua index cefe831..bf99311 100644 --- a/mesecons/init.lua +++ b/mesecons/init.lua @@ -97,7 +97,10 @@ end mesecon.queue:add_function("receptor_off", function (pos, rules) rules = rules or mesecon.rules.default - minetest.log("action", mesecon.postostring(pos) .. "-->" .. "receptor_off-> ".." rules="..mesecon.tabletostring(rules)) + + local node = mesecon.get_node_force(pos) + local os=mesecon.is_receptor_opaquespread(node.name) + -- Call turnoff on all linking positions for _, rule in ipairs(mesecon.flattenrules(rules)) do local np = vector.add(pos, rule) @@ -109,8 +112,8 @@ mesecon.queue:add_function("receptor_off", function (pos, rules) -- Turnoff returns true if turnoff process was successful, no onstate receptor -- was found along the way. Commit changes that were made in voxelmanip. If turnoff -- returns true, an onstate receptor was found, abort voxelmanip transaction. + if os then rulename.opaquespread=os end local res, rec_on = mesecon.turnoff(np, rulename) - minetest.log("action", mesecon.postostring(np) .. "-->" .. "receptor_off.turnoff-> ".." rulename="..mesecon.tabletostring(rulename).." res="..mesecon.tabletostring(res).." rec_on="..mesecon.tabletostring(rec_on)) if (res) then mesecon.vm_commit() else @@ -129,7 +132,6 @@ mesecon.queue:add_function("receptor_off", function (pos, rules) end) function mesecon.receptor_off(pos, rules) - minetest.log("action", mesecon.postostring(pos) .. "-->" .. "receptor_off-> ".." rules="..mesecon.tabletostring(rules) .. "trace="..debug.traceback()) mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) end diff --git a/mesecons/internal.lua b/mesecons/internal.lua index 503cc16..9739bc2 100644 --- a/mesecons/internal.lua +++ b/mesecons/internal.lua @@ -51,6 +51,8 @@ -- mesecon.turnoff(pos, link) +local rs_tick = 0.05 + local equals = vector.equals local get_node_force = mesecon.get_node_force local invertRule = mesecon.invertRule @@ -214,14 +216,14 @@ mesecon.queue:add_function("activate", function (pos, rulename) end end) -function mesecon.activate(pos, node, rulename, depth) +function mesecon.activate(pos, node, rulename, depth, time) if rulename == nil then for _,rule in pairs(mesecon.effector_get_rules(node)) do - mesecon.activate(pos, node, rule, depth + 1) + mesecon.activate(pos, node, rule, depth + 1, time) end return end - mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / depth) + mesecon.queue:add_action(pos, "activate", {rulename}, time, rulename, 1 / depth) end @@ -237,14 +239,14 @@ mesecon.queue:add_function("deactivate", function (pos, rulename) end end) -function mesecon.deactivate(pos, node, rulename, depth) +function mesecon.deactivate(pos, node, rulename, depth, time) if rulename == nil then for _,rule in pairs(mesecon.effector_get_rules(node)) do - mesecon.deactivate(pos, node, rule, depth + 1) + mesecon.deactivate(pos, node, rule, depth + 1, time) end return end - mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / depth) + mesecon.queue:add_action(pos, "deactivate", {rulename}, time, rulename, 1 / depth) end @@ -260,10 +262,10 @@ mesecon.queue:add_function("change", function (pos, rulename, changetype) end end) -function mesecon.changesignal(pos, node, rulename, newstate, depth) +function mesecon.changesignal(pos, node, rulename, newstate, depth, time) if rulename == nil then for _,rule in pairs(mesecon.effector_get_rules(node)) do - mesecon.changesignal(pos, node, rule, newstate, depth + 1) + mesecon.changesignal(pos, node, rule, newstate, depth + 1, time) end return end @@ -271,7 +273,7 @@ function mesecon.changesignal(pos, node, rulename, newstate, depth) -- Include "change" in overwritecheck so that it cannot be overwritten -- by "active" / "deactivate" that will be called upon the node at the same time. local overwritecheck = {"change", rulename} - mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, overwritecheck, 1 / depth) + mesecon.queue:add_action(pos, "change", {rulename, newstate}, time, overwritecheck, 1 / depth) end -- Conductors @@ -293,7 +295,6 @@ function mesecon.is_conductor_on(node, rulename) return mesecon.get_bit(binstate, bit) end end - return false end @@ -570,14 +571,13 @@ function mesecon.turnoff(pos, link) local rules = mesecon.conductor_get_rules(node) for _, r in pairs(mesecon.rule2meta(f.link, rules)) do local np = vector.add(f.pos, r) - + minetest.log("action", mesecon.postostring(pos) .. "-->" .. "turnoff.insert_rec_on0-> ".. mesecon.postostring(f.pos) .. " rule="..mesecon.tabletostring(r)) -- Check if an onstate receptor is connected. If that is the case, -- abort this turnoff process by returning false. `receptor_off` will -- discard all the changes that we made in the voxelmanip: for _, l in pairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do if is_receptor_on(get_node_force(np).name) then insert(rec_on, np) - --return false end end @@ -610,8 +610,9 @@ function mesecon.turnoff(pos, link) -- Warning: A LOT of nodes need to be looked at for this to work local fpos = f.pos for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do - local np = {x=fpos.x+r.x, y=fpos.y+r.y, z=fpos.z+r.z} + local np = vector.add(f.pos, r) local n = get_node_force(np) + minetest.log("action", mesecon.postostring(pos) .. "-->" .. "turnoff.rule2meta-> ".. mesecon.postostring(np) .. " link="..mesecon.tabletostring(r).. " name=" .. n.name) if n and is_receptor_on(n.name) and mesecon.get_receptor(n.name).opaquespread then local receptorrules = receptor_get_rules(n) for _, rr in pairs(receptorrules) do @@ -620,14 +621,26 @@ function mesecon.turnoff(pos, link) --return false end end + elseif mesecon.is_effector(n.name) then + insert(signals, { + pos = np, + node = n, + link = r, + depth = depth + }) + elseif mesecon.is_conductor_on(n) and f.link.opaquespread then + insert(frontiers, {pos = np, link = r}) end - --[[ for _, l in pairs(mesecon.rules_link_rule_all(fpos, r)) do - local nlink = copy(l) - nlink.spread = false - insert(frontiers, {pos = np, link = nlink}) + local lp = vector.add(np, l) + local ln = get_node_force(lp) + minetest.log("action", mesecon.postostring(pos) .. "-->" .. "turnoff.rules_link_rule_all-> ".. mesecon.postostring(lp) .. " link="..mesecon.tabletostring(l).. " name=" .. ln.name.." os="..tostring(f.link.opaquespread)) + if mesecon.is_effector(ln.name) then + local nlink = copy(l) + if not f.link.opaquespread then nlink.spread = false end + insert(frontiers, {pos = np, link = nlink}) + end end - --]] end end diff --git a/mesecons/services.lua b/mesecons/services.lua index b61bb60..dc5f072 100644 --- a/mesecons/services.lua +++ b/mesecons/services.lua @@ -153,7 +153,7 @@ function mesecon.on_dignode(pos, node) mesecon.receptor_off(pos, mesecon.conductor_get_rules(node)) elseif mesecon.is_receptor_on(node.name) then minetest.log("action", mesecon.postostring(pos) .. "-->" .. "on_dignode.is_receptor_on") - mesecon.receptor_off(pos, mesecon.receptor_get_rules(node)) + mesecon.receptor_off(pos, mesecon.receptor_get_rules(node), mesecon.is_receptor_opaquespread(node.name)) end if minetest.get_item_group(node.name, "opaque") == 1 then --local sources = mesecon.is_powered(pos) diff --git a/mesecons_wires/init.lua b/mesecons_wires/init.lua index de68656..f9d6904 100644 --- a/mesecons_wires/init.lua +++ b/mesecons_wires/init.lua @@ -47,110 +47,79 @@ local function wire_getconnect(from_pos, self_pos, from_rule) -- no upper-connect with opaqu block above me if from_rule.y==1 then local ufnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=1, z=0})) - if minetest.get_item_group(ufnode.name, "opaque") == 1 then return false end + if minetest.get_item_group(ufnode.name, "opaque") == 1 then return false, 1 end end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 01") if from_rule.y==-1 then local nfnode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x, y=0, z=from_rule.z})) - if minetest.get_item_group(nfnode.name, "opaque") == 1 then return false end + if minetest.get_item_group(nfnode.name, "opaque") == 1 then return false, 2 end end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 02") -- receptor -> always - if mesecon.is_receptor(node.name) then return true end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 03") + if mesecon.is_receptor(node.name) then return true, 3 end -- conductor -> always - if mesecon.is_conductor(node.name) then return true end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 04") + if mesecon.is_conductor(node.name) then return true, 4 end if from_rule.x==1 or from_rule.x==-1 then + local xpmnode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x, y=0, z=0})) --check blocks z=+-1 local zmnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=0, z=-1})) - if mesecon.is_receptor(zmnode.name) or mesecon.is_conductor(zmnode.name) then return false end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 05") + if (mesecon.is_receptor(zmnode.name) or mesecon.is_conductor(zmnode.name)) and not (minetest.get_item_group(xpmnode.name, "opaque") == 1) then return false, 5 end if minetest.get_item_group(zmnode.name, "opaque") == 1 then --check upper local zmypnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y= 1, z=-1})) - if mesecon.is_conductor(zmypnode.name) then return false end + if mesecon.is_conductor(zmypnode.name) then return false, 6 end elseif zmnode.name=="air" then --check lower local zmymnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=-1, z=-1})) - if mesecon.is_conductor(zmymnode.name) then return false end + if mesecon.is_conductor(zmymnode.name) then return false, 7 end end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 06") - + local zpnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=0, z= 1})) - if mesecon.is_receptor(zpnode.name) or mesecon.is_conductor(zpnode.name) then return false end + if (mesecon.is_receptor(zpnode.name) or mesecon.is_conductor(zpnode.name)) and not (minetest.get_item_group(xpmnode.name, "opaque") == 1) then return false, 8 end if minetest.get_item_group(zpnode.name, "opaque") == 1 then --check upper local zpypnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=1, z= 1})) - if mesecon.is_conductor(zpypnode.name) then return false end + if mesecon.is_conductor(zpypnode.name) then return false, 9 end elseif zpnode.name=="air" then --check lower local zpymnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=-1, z= 1})) - if mesecon.is_conductor(zpymnode.name) then return false end + if mesecon.is_conductor(zpymnode.name) then return false, 10 end end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 07") - --check block behind - local xnode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x*-1, y=0, z=0})) - if xnode.name=="air" then - --check lower - xnode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x*-1, y=-1, z=0})) - elseif minetest.get_item_group(xnode.name, "opaque") == 1 then - --check upper - xnode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x*-1, y= 1, z=0})) - end - if not(mesecon.is_receptor(xnode.name) or mesecon.is_conductor(xnode.name)) then return false end - end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 08") + if from_rule.z==1 or from_rule.z==-1 then + local zpmnode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=0, z=from_rule.z})) --check blocks x=+-1 local xmnode = mesecon.get_node_force(vector.add(from_pos, {x=-1, y=0, z=0})) - if mesecon.is_receptor(xmnode.name) or mesecon.is_conductor(xmnode.name) then return false end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 09") + if (mesecon.is_receptor(xmnode.name) or mesecon.is_conductor(xmnode.name)) and not (minetest.get_item_group(zpmnode.name, "opaque") == 1) then return false, 12 end if minetest.get_item_group(xmnode.name, "opaque") == 1 then --check upper local xmypnode = mesecon.get_node_force(vector.add(from_pos, {x=-1, y=1, z=0})) - if mesecon.is_conductor(xmypnode.name) then return false end + if mesecon.is_conductor(xmypnode.name) then return false, 13 end elseif xmnode.name=="air" then --check lower local xmymnode = mesecon.get_node_force(vector.add(from_pos, {x=-1, y=-1, z= 0})) - if mesecon.is_conductor(xmymnode.name) then return false end + if mesecon.is_conductor(xmymnode.name) then return false, 14 end end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 10") + local xpnode = mesecon.get_node_force(vector.add(from_pos, {x= 1, y=0, z=0})) - if mesecon.is_receptor(xpnode.name) or mesecon.is_conductor(xpnode.name) then return false end + if (mesecon.is_receptor(xpnode.name) or mesecon.is_conductor(xpnode.name)) and not (minetest.get_item_group(zpmnode.name, "opaque") == 1) then return false, 15 end if minetest.get_item_group(xpnode.name, "opaque") == 1 then --check upper local xpypnode = mesecon.get_node_force(vector.add(from_pos, {x= 1, y=1, z=0})) - if mesecon.is_conductor(xpypnode.name) then return false end + if mesecon.is_conductor(xpypnode.name) then return false, 16 end elseif xpnode.name=="air" then --check lower local xpymnode = mesecon.get_node_force(vector.add(from_pos, {x=1, y=-1, z= 0})) - if mesecon.is_conductor(xpymnode.name) then return false end + if mesecon.is_conductor(xpymnode.name) then return false, 17 end end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 11") - --check block behind - local znode = mesecon.get_node_force(vector.add(from_pos, {x=0, y=0, z=from_rule.z*-1})) - if znode.name=="air" then - --check lower - znode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x*-1, y=-1, z=0})) - elseif minetest.get_item_group(znode.name, "opaque") == 1 then - --check upper - znode = mesecon.get_node_force(vector.add(from_pos, {x=from_rule.x*-1, y= 1, z=0})) - end - if not(mesecon.is_receptor(znode.name) or mesecon.is_conductor(znode.name)) then return false end - --minetest.log("action", mesecon.postostring(from_pos) .. "-->" .. "wire_getconnect->" .. mesecon.postostring(from_pos).." - 12") end - - - return true + return true, 0 end end end - return false + return false, -1 end -- Update this node @@ -158,7 +127,9 @@ local function wire_updateconnect(pos) local connections = {} --check all rules for _, r in ipairs(wire_rules) do - if wire_getconnect(pos, vector.add(pos, r), r) then + local res, val = wire_getconnect(pos, vector.add(pos, r), r) + --minetest.log("action", mesecon.postostring(pos) .. "-->" .. "wire_updateconnect->" .. " self_pos="..mesecon.postostring(vector.add(pos, r)) .. " " .. tostring(res).." "..tostring (val)) + if res then table.insert(connections, r) end end