This commit is contained in:
Henry Behrendt 2021-09-04 22:04:12 +02:00
parent a2ebe94ff2
commit 0b344c5e88
4 changed files with 63 additions and 77 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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