Fix bugs with multi-rules conductors (like crossing) that have param2

This commit is contained in:
Novatux 2014-01-04 14:15:41 +01:00
parent b0f81a8c62
commit d5b39951a4
3 changed files with 95 additions and 52 deletions

View File

@ -124,7 +124,6 @@ end
function mesecon:receptor_off_i(pos, rules) function mesecon:receptor_off_i(pos, rules)
rules = rules or mesecon.rules.default rules = rules or mesecon.rules.default
for _, rule in ipairs(mesecon:flattenrules(rules)) do for _, rule in ipairs(mesecon:flattenrules(rules)) do
local np = mesecon:addPosRule(pos, rule) local np = mesecon:addPosRule(pos, rule)
local link, rulename = mesecon:rules_link(pos, np, rules) local link, rulename = mesecon:rules_link(pos, np, rules)

View File

@ -32,10 +32,10 @@
-- CONDUCTORS -- CONDUCTORS
-- mesecon:is_conductor(nodename) --> Returns true if nodename is a conductor -- mesecon:is_conductor(nodename) --> Returns true if nodename is a conductor
-- mesecon:is_conductor_on(nodename) --> Returns true if nodename is a conductor with state = mesecon.state.on -- mesecon:is_conductor_on(node) --> Returns true if node is a conductor with state = mesecon.state.on
-- mesecon:is_conductor_off(nodename) --> Returns true if nodename is a conductor with state = mesecon.state.off -- mesecon:is_conductor_off(node) --> Returns true if node is a conductor with state = mesecon.state.off
-- mesecon:get_conductor_on(offstate) --> Returns the onstate nodename of the conductor with the name offstate -- mesecon:get_conductor_on(node_off) --> Returns the onstate nodename of the conductor
-- mesecon:get_conductor_off(onstate) --> Returns the offstate nodename of the conductor with the name onstate -- mesecon:get_conductor_off(node_on) --> Returns the offstate nodename of the conductor
-- mesecon:conductor_get_rules(node) --> Returns the input+output rules of a conductor (mesecon.rules.default if none specified) -- mesecon:conductor_get_rules(node) --> Returns the input+output rules of a conductor (mesecon.rules.default if none specified)
-- HIGH-LEVEL Internals -- HIGH-LEVEL Internals
@ -303,36 +303,36 @@ end
-- Conductors -- Conductors
function mesecon:is_conductor_on(nodename, rulename) function mesecon:is_conductor_on(node, rulename)
local conductor = mesecon:get_conductor(nodename) local conductor = mesecon:get_conductor(node.name)
if conductor then if conductor then
if conductor.state then if conductor.state then
return conductor.state == mesecon.state.on return conductor.state == mesecon.state.on
end end
if conductor.states then if conductor.states then
if not rulename then if not rulename then
return mesecon:getstate(nodename, conductor.states) ~= 1 return mesecon:getstate(node.name, conductor.states) ~= 1
end end
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[nodename])) local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node))
local binstate = mesecon:getbinstate(nodename, conductor.states) local binstate = mesecon:getbinstate(node.name, conductor.states)
return mesecon:get_bit(binstate, bit) return mesecon:get_bit(binstate, bit)
end end
end end
return false return false
end end
function mesecon:is_conductor_off(nodename, rulename) function mesecon:is_conductor_off(node, rulename)
local conductor = mesecon:get_conductor(nodename) local conductor = mesecon:get_conductor(node.name)
if conductor then if conductor then
if conductor.state then if conductor.state then
return conductor.state == mesecon.state.off return conductor.state == mesecon.state.off
end end
if conductor.states then if conductor.states then
if not rulename then if not rulename then
return mesecon:getstate(nodename, conductor.states) == 1 return mesecon:getstate(node.name, conductor.states) == 1
end end
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[nodename])) local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node))
local binstate = mesecon:getbinstate(nodename, conductor.states) local binstate = mesecon:getbinstate(node.name, conductor.states)
return not mesecon:get_bit(binstate, bit) return not mesecon:get_bit(binstate, bit)
end end
end end
@ -347,15 +347,15 @@ function mesecon:is_conductor(nodename)
return false return false
end end
function mesecon:get_conductor_on(offstate, rulename) function mesecon:get_conductor_on(node_off, rulename)
local conductor = mesecon:get_conductor(offstate) local conductor = mesecon:get_conductor(node_off.name)
if conductor then if conductor then
if conductor.onstate then if conductor.onstate then
return conductor.onstate return conductor.onstate
end end
if conductor.states then if conductor.states then
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[offstate])) local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node_off))
local binstate = mesecon:getbinstate(offstate, conductor.states) local binstate = mesecon:getbinstate(node_off.name, conductor.states)
binstate = mesecon:set_bit(binstate, bit, "1") binstate = mesecon:set_bit(binstate, bit, "1")
return conductor.states[tonumber(binstate,2)+1] return conductor.states[tonumber(binstate,2)+1]
end end
@ -363,15 +363,15 @@ function mesecon:get_conductor_on(offstate, rulename)
return offstate return offstate
end end
function mesecon:get_conductor_off(onstate, rulename) function mesecon:get_conductor_off(node_on, rulename)
local conductor = mesecon:get_conductor(onstate) local conductor = mesecon:get_conductor(node_on.name)
if conductor then if conductor then
if conductor.offstate then if conductor.offstate then
return conductor.offstate return conductor.offstate
end end
if conductor.states then if conductor.states then
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[onstate])) local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node_on))
local binstate = mesecon:getbinstate(onstate, conductor.states) local binstate = mesecon:getbinstate(node_on.name, conductor.states)
binstate = mesecon:set_bit(binstate, bit, "0") binstate = mesecon:set_bit(binstate, bit, "0")
return conductor.states[tonumber(binstate,2)+1] return conductor.states[tonumber(binstate,2)+1]
end end
@ -396,7 +396,7 @@ end
function mesecon:is_power_on(pos, rulename) function mesecon:is_power_on(pos, rulename)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if mesecon:is_conductor_on(node.name, rulename) or mesecon:is_receptor_on(node.name) then if mesecon:is_conductor_on(node, rulename) or mesecon:is_receptor_on(node.name) then
return true return true
end end
return false return false
@ -404,7 +404,7 @@ end
function mesecon:is_power_off(pos, rulename) function mesecon:is_power_off(pos, rulename)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if mesecon:is_conductor_off(node.name, rulename) or mesecon:is_receptor_off(node.name) then if mesecon:is_conductor_off(node, rulename) or mesecon:is_receptor_off(node.name) then
return true return true
end end
return false return false
@ -413,7 +413,7 @@ end
function mesecon:turnon(pos, rulename) function mesecon:turnon(pos, rulename)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if mesecon:is_conductor_off(node.name, rulename) then if mesecon:is_conductor_off(node, rulename) then
local rules = mesecon:conductor_get_rules(node) local rules = mesecon:conductor_get_rules(node)
if not rulename then if not rulename then
@ -425,7 +425,7 @@ function mesecon:turnon(pos, rulename)
return return
end end
minetest.add_node(pos, {name = mesecon:get_conductor_on(node.name, rulename), param2 = node.param2}) minetest.add_node(pos, {name = mesecon:get_conductor_on(node, rulename), param2 = node.param2})
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
local np = mesecon:addPosRule(pos, rule) local np = mesecon:addPosRule(pos, rule)
@ -446,7 +446,7 @@ end
function mesecon:turnoff(pos, rulename) function mesecon:turnoff(pos, rulename)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if mesecon:is_conductor_on(node.name, rulename) then if mesecon:is_conductor_on(node, rulename) then
local rules = mesecon:conductor_get_rules(node) local rules = mesecon:conductor_get_rules(node)
--[[ --[[
if not rulename then if not rulename then
@ -458,7 +458,7 @@ function mesecon:turnoff(pos, rulename)
return return
end end
--]] --]]
minetest.add_node(pos, {name = mesecon:get_conductor_off(node.name, rulename), param2 = node.param2}) minetest.add_node(pos, {name = mesecon:get_conductor_off(node, rulename), param2 = node.param2})
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
local np = mesecon:addPosRule(pos, rule) local np = mesecon:addPosRule(pos, rule)
@ -543,11 +543,15 @@ function mesecon:rules_link(output, input, dug_outputrules) --output/input are p
for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do
-- Check if input accepts from output -- Check if input accepts from output
if mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then if mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then
if inputrule.sx == nil or outputrule.sx == nil or
(inputrule.sx == outputrule.sx and inputrule.sy == outputrule.sy
and inputrule.sz == outputrule.sz) then
return true, inputrule return true, inputrule
end end
end end
end end
end end
end
return false return false
end end
@ -565,7 +569,7 @@ function mesecon:is_powered(pos, rule)
local np = mesecon:addPosRule(pos, rule) local np = mesecon:addPosRule(pos, rule)
local nn = minetest.get_node(np) local nn = minetest.get_node(np)
if (mesecon:is_conductor_on (nn.name, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name)) if (mesecon:is_conductor_on (nn, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name))
and mesecon:rules_link(np, pos) then and mesecon:rules_link(np, pos) then
return true return true
end end
@ -574,7 +578,7 @@ function mesecon:is_powered(pos, rule)
local np = mesecon:addPosRule(pos, rule) local np = mesecon:addPosRule(pos, rule)
local nn = minetest.get_node(np) local nn = minetest.get_node(np)
if (mesecon:is_conductor_on (nn.name, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name)) if (mesecon:is_conductor_on (nn, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name))
and mesecon:rules_link(np, pos) then and mesecon:rules_link(np, pos) then
return true return true
end end
@ -587,43 +591,83 @@ end
function mesecon:rotate_rules_right(rules) function mesecon:rotate_rules_right(rules)
local nr = {} local nr = {}
for i, rule in ipairs(rules) do for i, rule in ipairs(rules) do
if rule.sx then
table.insert(nr, {
x = -rule.z,
y = rule.y,
z = rule.x,
sx = -rule.sz,
sy = rule.sy,
sz = rule.sx})
else
table.insert(nr, { table.insert(nr, {
x = -rule.z, x = -rule.z,
y = rule.y, y = rule.y,
z = rule.x}) z = rule.x})
end end
end
return nr return nr
end end
function mesecon:rotate_rules_left(rules) function mesecon:rotate_rules_left(rules)
local nr = {} local nr = {}
for i, rule in ipairs(rules) do for i, rule in ipairs(rules) do
if rule.sx then
table.insert(nr, {
x = rule.z,
y = rule.y,
z = -rule.x,
sx = rule.sz,
sy = rule.sy,
sz = -rule.sx})
else
table.insert(nr, { table.insert(nr, {
x = rule.z, x = rule.z,
y = rule.y, y = rule.y,
z = -rule.x}) z = -rule.x})
end end
end
return nr return nr
end end
function mesecon:rotate_rules_down(rules) function mesecon:rotate_rules_down(rules)
local nr = {} local nr = {}
for i, rule in ipairs(rules) do for i, rule in ipairs(rules) do
if rule.sx then
table.insert(nr, {
x = -rule.y,
y = rule.x,
z = rule.z,
sx = -rule.sy,
sy = rule.sx,
sz = rule.sz})
else
table.insert(nr, { table.insert(nr, {
x = -rule.y, x = -rule.y,
y = rule.x, y = rule.x,
z = rule.z}) z = rule.z})
end end
end
return nr return nr
end end
function mesecon:rotate_rules_up(rules) function mesecon:rotate_rules_up(rules)
local nr = {} local nr = {}
for i, rule in ipairs(rules) do for i, rule in ipairs(rules) do
if rule.sx then
table.insert(nr, {
x = rule.y,
y = -rule.x,
z = rule.z,
sx = rule.sy,
sy = -rule.sx,
sz = rule.sz})
else
table.insert(nr, { table.insert(nr, {
x = rule.y, x = rule.y,
y = -rule.x, y = -rule.x,
z = rule.z}) z = rule.z})
end end
end
return nr return nr
end end

View File

@ -9,16 +9,16 @@ mesecon.on_placenode = function (pos, node)
mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on") mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on")
mesecon:activate(pos, node) mesecon:activate(pos, node)
end end
elseif mesecon:is_conductor_on(node.name) then elseif mesecon:is_conductor_on(node) then
minetest.swap_node(pos, {name = mesecon:get_conductor_off(node.name)}) minetest.swap_node(pos, {name = mesecon:get_conductor_off(node)})
elseif mesecon:is_effector_on (node.name) then elseif mesecon:is_effector_on (node.name) then
mesecon:deactivate(pos, node) mesecon:deactivate(pos, node)
end end
end end
mesecon.on_dignode = function (pos, node) mesecon.on_dignode = function (pos, node)
if mesecon:is_conductor_on(node.name) then if mesecon:is_conductor_on(node) then
mesecon:receptor_off(pos, mesecon:conductor_get_rules(node)) mesecon:receptor_off_i(pos, mesecon:conductor_get_rules(node))
elseif mesecon:is_receptor_on(node.name) then elseif mesecon:is_receptor_on(node.name) then
mesecon:receptor_off(pos, mesecon:receptor_get_rules(node)) mesecon:receptor_off(pos, mesecon:receptor_get_rules(node))
end end