diff --git a/mesecons/init.lua b/mesecons/init.lua index cfcc771..67b33c9 100644 --- a/mesecons/init.lua +++ b/mesecons/init.lua @@ -76,7 +76,6 @@ mesecon.queue:add_function("receptor_on", function (pos, rules, voltage, opaques local node = mesecon.get_node_force(pos) local os=opaquespread or mesecon.is_receptor_opaquespread(node.name) - -- Call turnon on all linking positions for _, rule in pairs(mesecon.flattenrules(rules)) do local np = vector.add(pos, rule) @@ -119,7 +118,6 @@ mesecon.queue:add_function("receptor_off", function (pos, rules, opaquespread) for _, rec in pairs(rec_on) do --rules??? -> mesecon.receptor_get_rules(node) local node = mesecon.get_node_force(rec) - local meta = minetest.get_meta(rec) local voltage = meta:get_string("mesecon_voltage")~="" and meta:get_int("mesecon_voltage") or 15 mesecon.receptor_on(rec, mesecon.receptor_get_rules(node), voltage) @@ -133,29 +131,29 @@ function mesecon.receptor_off(pos, rules, opaquespread) mesecon.queue:add_action(pos, "receptor_off", {rules, opaquespread}, nil, rules) end -mesecon.queue:add_function("conductor_off", function (pos, rules) - local node = mesecon.get_node_force(pos) - rules = rules or mesecon.conductor_get_rules(node) - for _, rule in ipairs(mesecon.flattenrules(rules)) do +mesecon.queue:add_function("conductor_off", function (pos, rules, node) + local n = node or mesecon.get_node_force(pos) + local r = rules or mesecon.conductor_get_rules(n) + for _, rule in ipairs(mesecon.flattenrules(r)) do mesecon.vm_begin() - mesecon.changesignal(pos, node, rule, mesecon.state.off, 2) - local res, rec_on = mesecon.turnoff(pos, rule) + local np = vector.add(pos, rule) + local res, rec_on = mesecon.turnoff(np, rule) if (res) then mesecon.vm_commit() else mesecon.vm_abort() for _, rec in pairs(rec_on) do - local node = mesecon.get_node_force(rec) + local nn = mesecon.get_node_force(rec) local meta = minetest.get_meta(rec) local voltage = meta:get_string("mesecon_voltage")~="" and meta:get_int("mesecon_voltage") or 15 - mesecon.receptor_on(rec, mesecon.receptor_get_rules(node), voltage) + mesecon.receptor_on(rec, mesecon.receptor_get_rules(nn), voltage) end end end end) -function mesecon.conductor_off(pos, rules) - mesecon.queue:add_action(pos, "conductor_off", {rules}, nil, rules) +function mesecon.conductor_off(pos, rules, node) + mesecon.queue:add_action(pos, "conductor_off", {rules, node}, nil, rules) end --Services like turnoff receptor on dignode and so on diff --git a/mesecons/internal.lua b/mesecons/internal.lua index b11d236..0b34ed5 100644 --- a/mesecons/internal.lua +++ b/mesecons/internal.lua @@ -398,7 +398,6 @@ end -- looked at, activating / changing all effectors along the way. function mesecon.turnon(pos, link, voltage) voltage = voltage or 15 - local pn = get_node_force(pos) local frontiers = {{pos = pos, link = link, voltage = voltage}} @@ -422,7 +421,6 @@ function mesecon.turnon(pos, link, voltage) local np = vector.add(f.pos, r) for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do --aktuelle spannung an nachbarn übergeben - --wenn nachbar wire -> v-1 sonst v local nnode = get_node_force(np) if mesecon.is_conductor(nnode.name) then @@ -504,17 +502,17 @@ end -- link = link the effector is connected to, -- depth = indicates order in which signals wire fired, higher is later -- } -function mesecon.turnoff(pos, link) +function mesecon.turnoff(pos, link, tnode) --muss alle receptor_on zurückliefern -- komplett durchgehen, nicht abbrechen - local frontiers = {{pos = pos, link = link}} + local frontiers = {{pos = pos, link = link, node = tnode}} local signals = {} local rec_on = {} local depth = 1 while frontiers[1] do local f = table.remove(frontiers, 1) - local node = get_node_force(f.pos) + local node = f.node or get_node_force(f.pos) if node and mesecon.is_conductor_on(node, f.link) then local rules = mesecon.conductor_get_rules(node) @@ -537,7 +535,6 @@ function mesecon.turnoff(pos, link) end mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link)) - local meta = minetest.get_meta(f.pos) --if mesecon.is_conductor_on(node, f.link) then --spannung neu rechnen @@ -594,7 +591,7 @@ function mesecon.turnoff(pos, link) end depth = depth + 1 end - + if not next(rec_on) then --nur, wenn kein receptor_on gefunden for _, sig in pairs(signals) do @@ -673,7 +670,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos) if sourcepos == nil then sourcepos = {} end - + local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth, voltage, fc, os) local spread = false local cond = fc @@ -700,7 +697,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos) np.opaquespread=mesecon.is_receptor_opaquespread(nn.name) insert(sourcepos, np) if spread_tmp then spread = true end - end + end end end end @@ -739,9 +736,6 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos) end -- Return FALSE if not powered, return list of sources if is powered - - - if (#sourcepos == 0) then return false, false, 0, false, false else diff --git a/mesecons/services.lua b/mesecons/services.lua index 773fa87..99cbac3 100644 --- a/mesecons/services.lua +++ b/mesecons/services.lua @@ -24,11 +24,9 @@ function mesecon.on_placenode(pos, node) pos.conductor=true local sources, _, voltage, fromConductor = mesecon.is_powered(pos) if sources and voltage>=1 then - voltage = fromConductor and voltage-1 or voltage local meta = minetest.get_meta(pos) meta:set_int("mesecon_voltage", voltage) - -- also call receptor_on if itself is powered already, so that neighboring -- conductors will be activated (when pushing an on-conductor with a piston) for _, s in ipairs(sources) do @@ -39,7 +37,7 @@ function mesecon.on_placenode(pos, node) mesecon.receptor_on (pos, mesecon.conductor_get_rules(node), voltage-1) elseif mesecon.is_conductor_on(node) then minetest.swap_node(pos, {name = mesecon.get_conductor_off(node)}) - end + end end -- Effectors: Send changesignal and activate or deactivate @@ -74,7 +72,6 @@ function mesecon.on_placenode(pos, node) if opaquespread then mesecon.receptor_on(pos, nil, voltage) else - local neighbors = mesecon.mcl_get_neighbors(pos) for n=1, #neighbors do local npos = neighbors[n].pos @@ -110,7 +107,7 @@ function mesecon.on_dignode(pos, node, direct_dig) local regnode = minetest.registered_nodes[node.name] if (regnode and regnode.mesecons and not regnode.on_destruct) or not direct_dig then if mesecon.is_conductor_on(node) then - mesecon.conductor_off(pos, mesecon.conductor_get_rules(node)) + mesecon.conductor_off(pos, mesecon.conductor_get_rules(node), node) elseif mesecon.is_receptor_on(node.name) then mesecon.receptor_off(pos, mesecon.receptor_get_rules(node), mesecon.is_receptor_opaquespread(node.name)) end @@ -123,7 +120,7 @@ function mesecon.on_dignode(pos, node, direct_dig) local nlink = neighbors[n].link local nnode = minetest.get_node(npos) if mesecon.is_conductor_on(nnode) then - mesecon.conductor_off(npos, mesecon.conductor_get_rules(nnode)) + mesecon.conductor_off(npos, mesecon.conductor_get_rules(nnode), nnode) -- Disable neighbor effectors unless they are in a special ignore group elseif mesecon.is_effector_on(nnode.name) and mesecon.is_powered(npos) == false and minetest.get_item_group(nnode.name, "mesecon_ignore_opaque_dig") == 0 then mesecon.changesignal(npos, nnode, nlink, mesecon.state.off, 1) diff --git a/mesecons/util.lua b/mesecons/util.lua index 0029f8e..60c0ebf 100644 --- a/mesecons/util.lua +++ b/mesecons/util.lua @@ -33,8 +33,8 @@ function mesecon.register_autoconnect_hook(name, fct) function mesecon.execute_autoconnect_hooks_now(pos, node) function mesecon.execute_autoconnect_hooks_queue(pos, node) -function mesecon.tabletostring(tbl) -function mesecon.postostring(pos) +function mesecon.tab2str(tbl) +function mesecon.pos2str(pos) --]] function mesecon.move_node(pos, newpos) @@ -507,29 +507,29 @@ function mesecon.execute_autoconnect_hooks_queue(pos, node) end -function mesecon.tabletostring(tbl) +function mesecon.tab2str(tbl) if type(tbl) ~= "table" then return tostring(tbl) else local tmp = "" for k,v in pairs(tbl) do if tmp ~="" then tmp = tmp .. " / " end - tmp = tmp .. tostring(k).."=" .. (type(v) == "table" and ("{"..mesecon.tabletostring(v).."}") or tostring(v)) + tmp = tmp .. tostring(k).."=" .. (type(v) == "table" and ("{"..mesecon.tab2str(v).."}") or tostring(v)) end return tmp end end -function mesecon.postostring(pos) +function mesecon.pos2str(pos) return pos.x .. "/" .. pos.y .. "/" .. pos.z end function mesecon.rules_sub(source_rules, sub) local t = {} - for i = 1, #sub do t[mesecon.postostring(sub[i])] = true end + for i = 1, #sub do t[mesecon.pos2str(sub[i])] = true end local res = mesecon.tablecopy(source_rules) for i = #res, 1, -1 do - if t[mesecon.postostring(res[i])] then table.remove(res, i) end + if t[mesecon.pos2str(res[i])] then table.remove(res, i) end end return res end diff --git a/mesecons_wires/init.lua b/mesecons_wires/init.lua index ad36c39..690e6f7 100644 --- a/mesecons_wires/init.lua +++ b/mesecons_wires/init.lua @@ -42,8 +42,6 @@ local function wire_getconnect(from_pos, self_pos, from_rule) for _, r in ipairs(mesecon.flattenrules(rules)) do if (vector.equals(vector.add(self_pos, r), from_pos)) then - -- can connect -> check constraint - -- 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})) @@ -53,18 +51,18 @@ local function wire_getconnect(from_pos, self_pos, from_rule) 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, 2 end end - + -- receptor -> always if mesecon.is_receptor(node.name) then return true, 3 end -- conductor -> always 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)) 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 + if (mesecon.is_receptor(zmnode.name) or mesecon.is_conductor(zmnode.name)) 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, 6 end @@ -75,8 +73,8 @@ local function wire_getconnect(from_pos, self_pos, from_rule) end 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)) 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 + if (mesecon.is_receptor(zpnode.name) or mesecon.is_conductor(zpnode.name)) 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, 9 end @@ -85,14 +83,26 @@ local function wire_getconnect(from_pos, self_pos, from_rule) 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, 10 end end + if mesecon.is_effector(node.name) then + --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 end 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)) 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 + if (mesecon.is_receptor(xmnode.name) or mesecon.is_conductor(xmnode.name)) 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, 13 end @@ -103,8 +113,8 @@ local function wire_getconnect(from_pos, self_pos, from_rule) end 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)) 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 + if (mesecon.is_receptor(xpnode.name) or mesecon.is_conductor(xpnode.name)) 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, 16 end @@ -113,8 +123,19 @@ local function wire_getconnect(from_pos, self_pos, from_rule) 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, 17 end end + if mesecon.is_effector(node.name) then + --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 + end end - return true, 0 end end @@ -161,7 +182,6 @@ local function wire_updateconnect(pos) ..(nid[8] or "0")..(nid[9] or "0")..(nid[10] or "0")..(nid[11] or "0") local state_suffix = string.find(minetest.get_node(pos).name, "_off") and "_off" or "_on" - local orules = mesecon.get_any_inputrules(mesecon.get_node_force(pos)) mesecon.swap_node_force(pos, "mesecons:wire_"..nodeid..state_suffix) local nrules = mesecon.get_any_inputrules(mesecon.get_node_force(pos)) @@ -432,8 +452,6 @@ local function register_wires2() if nodeid:sub(1,8) == "00000000" then nodebox.fixed = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16} end - - --rules berechnen, nur nötige verwenden local nrules = {} for i=0,11 do @@ -442,7 +460,7 @@ local function register_wires2() end end table.insert(nrules,wire_rules[12+1]) --ym (always) - + --[[ 00100000 @@ -472,14 +490,13 @@ komplett flat {x= 0, y=-1, z= 1}, --zpym 9 {x=-1, y=-1, z= 0}, --xmym 10 {x= 0, y=-1, z=-1}, --zmym 11 - + 0,4, 8 1,5, 9 2,6,10 3,7,11 --]] - - + --[[ {x= 1, y= 0, z= 0, spread=true}, --xp {x= 0, y= 0, z= 1, spread=true}, --zp @@ -494,9 +511,9 @@ komplett flat {x=-1, y=-1, z= 0}, --xmym {x= 0, y=-1, z=-1}} --zmym {x= 0, y=-1, z= 0, spread=true}, --ym (always) - ---]] - + +--]] + local meseconspec_off = { conductor = { --rules = wire_rules, rules = nrules,