diff options
-rw-r--r-- | mesecons/internal.lua | 57 | ||||
-rw-r--r-- | mesecons/util.lua | 22 |
2 files changed, 58 insertions, 21 deletions
diff --git a/mesecons/internal.lua b/mesecons/internal.lua index 8ca22a1..a76d5e8 100644 --- a/mesecons/internal.lua +++ b/mesecons/internal.lua @@ -412,7 +412,7 @@ end function mesecon:turnon(pos, rulename) local node = minetest.get_node(pos) - + if mesecon:is_conductor_off(node, rulename) then local rules = mesecon:conductor_get_rules(node) @@ -429,7 +429,7 @@ function mesecon:turnon(pos, rulename) for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do local np = mesecon:addPosRule(pos, rule) - local link, rulename = mesecon:rules_link(pos, np) + local link, rulename = mesecon:rules_link_rule(pos, rule) if link then mesecon:turnon(np, rulename) @@ -462,7 +462,7 @@ function mesecon:turnoff(pos, rulename) for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do local np = mesecon:addPosRule(pos, rule) - local link, rulename = mesecon:rules_link(pos, np) + local link, rulename = mesecon:rules_link_rule(pos, rule) if link then mesecon:turnoff(np, rulename) @@ -498,23 +498,25 @@ function mesecon:connected_to_receptor(pos, rulename) end function mesecon:find_receptor_on(pos, checked, rulename) - -- 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 - return false, checked - end - end - - -- add current position to checked - table.insert(checked, {x=pos.x, y=pos.y, z=pos.z}) local node = minetest.get_node(pos) if mesecon:is_receptor_on(node.name) then + -- add current position to checked + table.insert(checked, {x=pos.x, y=pos.y, z=pos.z}) return true end if mesecon:is_conductor(node.name) then local rules = mesecon:conductor_get_rules(node) + local metaindex = mesecon:rule2metaindex(rulename, rules) + -- find out if node has already been checked (to prevent from endless loop) + for _, cp in ipairs(checked) do + if mesecon:cmpPos(cp, pos) and cp.metaindex == metaindex then + return false, checked + end + end + -- add current position to checked + table.insert(checked, {x=pos.x, y=pos.y, z=pos.z, metaindex = metaindex}) for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do local np = mesecon:addPosRule(pos, rule) if mesecon:rules_link(np, pos) then @@ -523,6 +525,14 @@ function mesecon:find_receptor_on(pos, checked, rulename) end end end + else + -- 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 + return false, checked + end + end + table.insert(checked, {x=pos.x, y=pos.y, z=pos.z}) end return false @@ -543,9 +553,7 @@ function mesecon:rules_link(output, input, dug_outputrules) --output/input are p for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do -- Check if input accepts from output 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 + if inputrule.sx == nil or outputrule.sx == nil or mesecon:cmpSpecial(inputrule, outputrule) then return true, inputrule end end @@ -555,6 +563,25 @@ function mesecon:rules_link(output, input, dug_outputrules) --output/input are p return false end +function mesecon:rules_link_rule(output, rule) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule + local input = mesecon:addPosRule(output, rule) + local inputnode = minetest.get_node(input) + local inputrules = mesecon:get_any_inputrules (inputnode) + if not inputrules then + return + end + + for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do + -- Check if input accepts from output + if mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then + if inputrule.sx == nil or rule.sx == nil or mesecon:cmpSpecial(inputrule, rule) then + return true, inputrule + end + end + end + return false +end + function mesecon:rules_link_anydir(pos1, pos2) return mesecon:rules_link(pos1, pos2) or mesecon:rules_link(pos2, pos1) end diff --git a/mesecons/util.lua b/mesecons/util.lua index aac369b..9e22935 100644 --- a/mesecons/util.lua +++ b/mesecons/util.lua @@ -62,18 +62,18 @@ function mesecon:rule2bit(findrule, allrules) end for m,metarule in ipairs( allrules) do for _, rule in ipairs(metarule ) do - if mesecon:cmpPos(findrule, rule) then + if mesecon:cmpPos(findrule, rule) and mesecon:cmpSpecial(findrule, rule) then return m end end end end -function mesecon:rule2meta(findrule, allrules) +function mesecon:rule2metaindex(findrule, allrules) --get the metarule the rule is in, or allrules if allrules[1].x then - return allrules + return nil end if not(findrule) then @@ -82,13 +82,19 @@ function mesecon:rule2meta(findrule, allrules) for m, metarule in ipairs( allrules) do for _, rule in ipairs(metarule ) do - if mesecon:cmpPos(findrule, rule) then - return metarule + if mesecon:cmpPos(findrule, rule) and mesecon:cmpSpecial(findrule, rule) then + return m end end end end +function mesecon:rule2meta(findrule, allrules) + local index = mesecon:rule2metaindex(findrule, allrules) + if index == nil then return allrules end + return allrules[index] +end + if convert_base then print( "base2dec is tonumber(num,base1)\n".. @@ -141,7 +147,7 @@ function mesecon:set_bit(binary,bit,value) end function mesecon:invertRule(r) - return {x = -r.x, y = -r.y, z = -r.z} + return {x = -r.x, y = -r.y, z = -r.z, sx = r.sx, sy = r.sy, sz = r.sz} end function mesecon:addPosRule(p, r) @@ -152,6 +158,10 @@ function mesecon:cmpPos(p1, p2) return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z) end +function mesecon:cmpSpecial(r1, r2) + return (r1.sx == r2.sx and r1.sy == r2.sy and r1.sz == r2.sz) +end + function mesecon:tablecopy(table) -- deep table copy local newtable = {} |