diff options
author | khonkhortisan <khonkhortisan@gmail.com> | 2013-06-19 19:38:34 -0700 |
---|---|---|
committer | khonkhortisan <khonkhortisan@gmail.com> | 2013-06-20 09:30:26 -0700 |
commit | 885899cbaf6ccb2d22a3495131204ea0d01131ed (patch) | |
tree | 93269364b92cfa582cbd027f428934161fb9c82d /mesecons | |
parent | 6efe579f68eff1deaa08cf34e44d0c0411f8c498 (diff) | |
download | mesecons-885899cbaf6ccb2d22a3495131204ea0d01131ed.tar mesecons-885899cbaf6ccb2d22a3495131204ea0d01131ed.tar.gz mesecons-885899cbaf6ccb2d22a3495131204ea0d01131ed.tar.bz2 mesecons-885899cbaf6ccb2d22a3495131204ea0d01131ed.tar.xz mesecons-885899cbaf6ccb2d22a3495131204ea0d01131ed.zip |
Crossover
Diffstat (limited to 'mesecons')
-rw-r--r-- | mesecons/init.lua | 6 | ||||
-rw-r--r-- | mesecons/internal.lua | 134 | ||||
-rw-r--r-- | mesecons/services.lua | 2 | ||||
-rw-r--r-- | mesecons/util.lua | 137 |
4 files changed, 241 insertions, 38 deletions
diff --git a/mesecons/init.lua b/mesecons/init.lua index 7f6fe5d..587937a 100644 --- a/mesecons/init.lua +++ b/mesecons/init.lua @@ -79,7 +79,7 @@ dofile(minetest.get_modpath("mesecons").."/legacy.lua"); function mesecon:receptor_on(pos, rules) rules = rules or mesecon.rules.default - for _, rule in ipairs(rules) do + for _, rule in ipairs(mesecon:flattenrules(rules)) do local np = mesecon:addPosRule(pos, rule) local link, rulename = mesecon:rules_link(pos, np, rules) if link then @@ -91,11 +91,11 @@ end function mesecon:receptor_off(pos, rules) rules = rules or mesecon.rules.default - for _, rule in ipairs(rules) do + for _, rule in ipairs(mesecon:flattenrules(rules)) do local np = mesecon:addPosRule(pos, rule) local link, rulename = mesecon:rules_link(pos, np, rules) if link then - if not mesecon:connected_to_receptor(np) then + if not mesecon:connected_to_receptor(np, mesecon:invertRule(rule)) then mesecon:turnoff(np, rulename) else mesecon:changesignal(np, minetest.env:get_node(np), rulename, mesecon.state.off) diff --git a/mesecons/internal.lua b/mesecons/internal.lua index 5e243cf..8ab0bf6 100644 --- a/mesecons/internal.lua +++ b/mesecons/internal.lua @@ -212,18 +212,38 @@ end -- Conductors -function mesecon:is_conductor_on(nodename) +function mesecon:is_conductor_on(nodename, rulename) local conductor = mesecon:get_conductor(nodename) - if conductor and conductor.state == mesecon.state.on then - return true + if conductor then + if conductor.state then + return conductor.state == mesecon.state.on + end + if conductor.states then + if not rulename then + return mesecon:getstate(nodename, conductor.states) ~= 1 + end + local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[nodename])) + local binstate = mesecon:getbinstate(nodename, conductor.states) + return mesecon:get_bit(binstate, bit) + end end return false end -function mesecon:is_conductor_off(nodename) +function mesecon:is_conductor_off(nodename, rulename) local conductor = mesecon:get_conductor(nodename) - if conductor and conductor.state == mesecon.state.off then - return true + if conductor then + if conductor.state then + return conductor.state == mesecon.state.off + end + if conductor.states then + if not rulename then + return mesecon:getstate(nodename, conductor.states) == 1 + end + local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[nodename])) + local binstate = mesecon:getbinstate(nodename, conductor.states) + return not mesecon:get_bit(binstate, bit) + end end return false end @@ -236,20 +256,36 @@ function mesecon:is_conductor(nodename) return false end -function mesecon:get_conductor_on(offstate) +function mesecon:get_conductor_on(offstate, rulename) local conductor = mesecon:get_conductor(offstate) if conductor then - return conductor.onstate + if conductor.onstate then + return conductor.onstate + end + if conductor.states then + local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[offstate])) + local binstate = mesecon:getbinstate(offstate, conductor.states) + binstate = mesecon:set_bit(binstate, bit, "1") + return conductor.states[tonumber(binstate,2)+1] + end end - return false + return offstate end -function mesecon:get_conductor_off(onstate) +function mesecon:get_conductor_off(onstate, rulename) local conductor = mesecon:get_conductor(onstate) if conductor then - return conductor.offstate + if conductor.offstate then + return conductor.offstate + end + if conductor.states then + local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[onstate])) + local binstate = mesecon:getbinstate(onstate, conductor.states) + binstate = mesecon:set_bit(binstate, bit, "0") + return conductor.states[tonumber(binstate,2)+1] + end end - return false + return onstate end function mesecon:conductor_get_rules(node) @@ -267,17 +303,17 @@ end -- some more general high-level stuff -function mesecon:is_power_on(pos) +function mesecon:is_power_on(pos, rulename) local node = minetest.env:get_node(pos) - if mesecon:is_conductor_on(node.name) or mesecon:is_receptor_on(node.name) then + if mesecon:is_conductor_on(node.name, rulename) or mesecon:is_receptor_on(node.name) then return true end return false end -function mesecon:is_power_off(pos) +function mesecon:is_power_off(pos, rulename) local node = minetest.env:get_node(pos) - if mesecon:is_conductor_off(node.name) or mesecon:is_receptor_off(node.name) then + if mesecon:is_conductor_off(node.name, rulename) or mesecon:is_receptor_off(node.name) then return true end return false @@ -286,11 +322,21 @@ end function mesecon:turnon(pos, rulename) local node = minetest.env:get_node(pos) - if mesecon:is_conductor_off(node.name) then + if mesecon:is_conductor_off(node.name, rulename) then local rules = mesecon:conductor_get_rules(node) - minetest.env:add_node(pos, {name = mesecon:get_conductor_on(node.name), param2 = node.param2}) - for _, rule in ipairs(rules) do + if not rulename then + for _, rule in ipairs(mesecon:flattenrules(rules)) do + if mesecon:connected_to_receptor(pos, rule) then + mesecon:turnon(pos, rule) + end + end + return + end + + minetest.env:add_node(pos, {name = mesecon:get_conductor_on(node.name, rulename), param2 = node.param2}) + + for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do local np = mesecon:addPosRule(pos, rule) local link, rulename = mesecon:rules_link(pos, np) @@ -309,11 +355,21 @@ end function mesecon:turnoff(pos, rulename) local node = minetest.env:get_node(pos) - if mesecon:is_conductor_on(node.name) then + if mesecon:is_conductor_on(node.name, rulename) then local rules = mesecon:conductor_get_rules(node) - minetest.env:add_node(pos, {name = mesecon:get_conductor_off(node.name), param2 = node.param2}) + --[[ + if not rulename then + for _, rule in ipairs(mesecon:flattenrules(rules)) do + if mesecon:is_powered(pos, rule) then + mesecon:turnoff(pos, rule) + end + end + return + end + --]] + minetest.env:add_node(pos, {name = mesecon:get_conductor_off(node.name, rulename), param2 = node.param2}) - for _, rule in ipairs(rules) do + for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do local np = mesecon:addPosRule(pos, rule) local link, rulename = mesecon:rules_link(pos, np) @@ -331,17 +387,17 @@ function mesecon:turnoff(pos, rulename) end -function mesecon:connected_to_receptor(pos) +function mesecon:connected_to_receptor(pos, rulename) local node = minetest.env:get_node(pos) -- Check if conductors around are connected local rules = mesecon:get_any_inputrules(node) if not rules then return false end - for _, rule in ipairs(rules) do + for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do local np = mesecon:addPosRule(pos, rule) if mesecon:rules_link(np, pos) then - if mesecon:find_receptor_on(np, {}) then + if mesecon:find_receptor_on(np, {}, mesecon:invertRule(rule)) then return true end end @@ -350,7 +406,7 @@ function mesecon:connected_to_receptor(pos) return false end -function mesecon:find_receptor_on(pos, checked) +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 @@ -368,10 +424,10 @@ function mesecon:find_receptor_on(pos, checked) if mesecon:is_conductor(node.name) then local rules = mesecon:conductor_get_rules(node) - for _, rule in ipairs(rules) do + for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do local np = mesecon:addPosRule(pos, rule) if mesecon:rules_link(np, pos) then - if mesecon:find_receptor_on(np, checked) then + if mesecon:find_receptor_on(np, checked, mesecon:invertRule(rule)) then return true end end @@ -390,13 +446,13 @@ function mesecon:rules_link(output, input, dug_outputrules) --output/input are p return end - for _, outputrule in ipairs(outputrules) do + for _, outputrule in ipairs(mesecon:flattenrules(outputrules)) do -- Check if output sends to input if mesecon:cmpPos(mesecon:addPosRule(output, outputrule), input) then - for _, inputrule in ipairs(inputrules) do + for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do -- Check if input accepts from output if mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then - return true, inputrule.name + return true, inputrule end end end @@ -408,16 +464,26 @@ function mesecon:rules_link_anydir(pos1, pos2) return mesecon:rules_link(pos1, pos2) or mesecon:rules_link(pos2, pos1) end -function mesecon:is_powered(pos) +function mesecon:is_powered(pos, rule) local node = minetest.env:get_node(pos) local rules = mesecon:get_any_inputrules(node) if not rules then return false end - for _, rule in ipairs(rules) do + if not rule then + for _, rule in ipairs(mesecon:flattenrules(rules)) do + local np = mesecon:addPosRule(pos, rule) + local nn = minetest.env:get_node(np) + + if (mesecon:is_conductor_on (nn.name, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name)) + and mesecon:rules_link(np, pos) then + return true + end + end + else local np = mesecon:addPosRule(pos, rule) local nn = minetest.env:get_node(np) - if (mesecon:is_conductor_on (nn.name) or mesecon:is_receptor_on (nn.name)) + if (mesecon:is_conductor_on (nn.name, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name)) and mesecon:rules_link(np, pos) then return true end diff --git a/mesecons/services.lua b/mesecons/services.lua index a2f9d01..4260a2e 100644 --- a/mesecons/services.lua +++ b/mesecons/services.lua @@ -5,7 +5,7 @@ mesecon.on_placenode = function (pos) elseif mesecon:is_powered(pos) then if mesecon:is_conductor(node.name) then mesecon:turnon (pos) - mesecon:receptor_on (pos, mesecon:conductor_get_rules(node)) + --mesecon:receptor_on (pos, mesecon:conductor_get_rules(node)) else mesecon:changesignal(pos, node) mesecon:activate(pos, node) diff --git a/mesecons/util.lua b/mesecons/util.lua index 08b46d1..12d2af1 100644 --- a/mesecons/util.lua +++ b/mesecons/util.lua @@ -14,6 +14,143 @@ function mesecon:move_node(pos, newpos) minetest.env:get_meta(pos):from_table(meta) end +--[[ new functions: +mesecon:flattenrules(allrules) +mesecon:rule2bit(findrule, allrules) +mesecon:rule2meta(findrule, allrules) +dec2bin(n) +mesecon:getstate(nodename, states) +mesecon:getbinstate(nodename, states) +mesecon:get_bit(binary, bit) +mesecon:set_bit(binary, bit, value) +mesecon:invertRule(r) +--]] + +function mesecon:flattenrules(allrules) +--[[ + { + { + {xyz}, + {xyz}, + }, + { + {xyz}, + {xyz}, + }, + } +--]] + if allrules[1] and + allrules[1].x then + return allrules + end + + local shallowrules = {} + for _, metarule in ipairs( allrules) do + for _, rule in ipairs(metarule ) do + table.insert(shallowrules, rule) + end + end + return shallowrules +--[[ + { + {xyz}, + {xyz}, + {xyz}, + {xyz}, + } +--]] +end + +function mesecon:rule2bit(findrule, allrules) + --get the bit of the metarule the rule is in, or bit 1 + if (allrules[1] and + allrules[1].x) or + not findrule then + return 1 + end + for m,metarule in ipairs( allrules) do + for _, rule in ipairs(metarule ) do + if mesecon:cmpPos(findrule, rule) then + return m + end + end + end +end + +function mesecon:rule2meta(findrule, allrules) + --get the metarule the rule is in, or allrules + + if allrules[1].x then + return allrules + end + + if not(findrule) then + return mesecon:flattenrules(allrules) + end + + for m, metarule in ipairs( allrules) do + for _, rule in ipairs(metarule ) do + if mesecon:cmpPos(findrule, rule) then + return metarule + end + end + end +end + +if convert_base then + print( + "base2dec is tonumber(num,base1)\n".. + "commonlib needs dec2base(num,base2)\n".. + "and it needs base2base(num,base1,base2),\n".. + "which is dec2base(tonumber(num,base1),base2)" + ) +else + function dec2bin(n) + local x, y = math.floor(n / 2), n % 2 + if (n > 1) then + return dec2bin(x)..y + else + return ""..y + end + end +end + +function mesecon:getstate(nodename, states) + for state, name in ipairs(states) do + if name == nodename then + return state + end + end + error(nodename.." doesn't mention itself in "..dump(states)) +end + +function mesecon:getbinstate(nodename, states) + return dec2bin(mesecon:getstate(nodename, states)-1) +end + +function mesecon:get_bit(binary,bit) + bit = bit or 1 + local c = binary:len()-(bit-1) + return binary:sub(c,c) == "1" +end + +function mesecon:set_bit(binary,bit,value) + if value == "1" then + if not mesecon:get_bit(binary,bit) then + return dec2bin(tonumber(binary,2)+math.pow(2,bit-1)) + end + elseif value == "0" then + if mesecon:get_bit(binary,bit) then + return dec2bin(tonumber(binary,2)-math.pow(2,bit-1)) + end + end + return binary + +end + +function mesecon:invertRule(r) + return {x = -r.x, y = -r.y, z = -r.z} +end function mesecon:addPosRule(p, r) return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z} |