summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesecons/internal.lua96
-rw-r--r--mesecons/services.lua25
-rw-r--r--mesecons/util.lua10
-rw-r--r--mesecons_gates/init.lua298
-rw-r--r--mesecons_mvps/init.lua6
-rw-r--r--mesecons_pistons/init.lua10
6 files changed, 158 insertions, 287 deletions
diff --git a/mesecons/internal.lua b/mesecons/internal.lua
index cee90d2..d62df1f 100644
--- a/mesecons/internal.lua
+++ b/mesecons/internal.lua
@@ -240,7 +240,10 @@ function mesecon.changesignal(pos, node, rulename, newstate, depth)
return
end
- mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, rulename, 1 / 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)
end
-- Conductors
@@ -514,10 +517,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 mesecon.cmpSpecial(inputrule, outputrule) then
- return true, inputrule
- end
+ return true, inputrule
end
end
end
@@ -537,10 +537,7 @@ function mesecon.rules_link_rule_all(output, rule)
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
- table.insert(rules, inputrule)
- end
+ table.insert(rules, inputrule)
end
end
return rules
@@ -558,10 +555,7 @@ function mesecon.rules_link_rule_all_inverted(input, rule)
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then
- if outputrule.sx == nil or rule.sx == nil
- or mesecon.cmpSpecial(outputrule, rule) then
- table.insert(rules, mesecon.invertRule(outputrule))
- end
+ table.insert(rules, mesecon.invertRule(outputrule))
end
end
return rules
@@ -612,20 +606,11 @@ end
function mesecon.rotate_rules_right(rules)
local nr = {}
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, {
- x = -rule.z,
- y = rule.y,
- z = rule.x})
- end
+ table.insert(nr, {
+ x = -rule.z,
+ y = rule.y,
+ z = rule.x,
+ name = rule.name})
end
return nr
end
@@ -633,20 +618,11 @@ end
function mesecon.rotate_rules_left(rules)
local nr = {}
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, {
- x = rule.z,
- y = rule.y,
- z = -rule.x})
- end
+ table.insert(nr, {
+ x = rule.z,
+ y = rule.y,
+ z = -rule.x,
+ name = rule.name})
end
return nr
end
@@ -654,20 +630,11 @@ end
function mesecon.rotate_rules_down(rules)
local nr = {}
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, {
- x = -rule.y,
- y = rule.x,
- z = rule.z})
- end
+ table.insert(nr, {
+ x = -rule.y,
+ y = rule.x,
+ z = rule.z,
+ name = rule.name})
end
return nr
end
@@ -675,20 +642,11 @@ end
function mesecon.rotate_rules_up(rules)
local nr = {}
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, {
- x = rule.y,
- y = -rule.x,
- z = rule.z})
- end
+ table.insert(nr, {
+ x = rule.y,
+ y = -rule.x,
+ z = rule.z,
+ name = rule.name})
end
return nr
end
diff --git a/mesecons/services.lua b/mesecons/services.lua
index 36d9b80..215fb31 100644
--- a/mesecons/services.lua
+++ b/mesecons/services.lua
@@ -27,12 +27,27 @@ mesecon.on_placenode = function (pos, node)
-- Effectors: Send changesignal and activate or deactivate
if mesecon.is_effector(node.name) then
- if mesecon.is_powered(pos) then
- mesecon.changesignal(pos, node, mesecon.effector_get_rules(node), "on", 1)
- mesecon.activate(pos, node, nil, 1)
+ local powered_rules = {}
+ local unpowered_rules = {}
+
+ -- for each input rule, check if powered
+ for _, r in ipairs(mesecon.effector_get_rules(node)) do
+ local powered = mesecon.is_powered(pos, r)
+ if powered then table.insert(powered_rules, r)
+ else table.insert(unpowered_rules, r) end
+
+ local state = powered and mesecon.state.on or mesecon.state.off
+ mesecon.changesignal(pos, node, r, state, 1)
+ end
+
+ if (#powered_rules > 0) then
+ for _, r in ipairs(powered_rules) do
+ mesecon.activate(pos, node, r, 1)
+ end
else
- mesecon.changesignal(pos, node, mesecon.effector_get_rules(node), "off", 1)
- mesecon.deactivate(pos, node, nil, 1)
+ for _, r in ipairs(unpowered_rules) do
+ mesecon.deactivate(pos, node, r, 1)
+ end
end
end
end
diff --git a/mesecons/util.lua b/mesecons/util.lua
index 11cc95a..a64e00c 100644
--- a/mesecons/util.lua
+++ b/mesecons/util.lua
@@ -62,7 +62,7 @@ function mesecon.rule2bit(findrule, allrules)
end
for m,metarule in ipairs( allrules) do
for _, rule in ipairs(metarule ) do
- if mesecon.cmpPos(findrule, rule) and mesecon.cmpSpecial(findrule, rule) then
+ if mesecon.cmpPos(findrule, rule) then
return m
end
end
@@ -82,7 +82,7 @@ function mesecon.rule2metaindex(findrule, allrules)
for m, metarule in ipairs( allrules) do
for _, rule in ipairs(metarule ) do
- if mesecon.cmpPos(findrule, rule) and mesecon.cmpSpecial(findrule, rule) then
+ if mesecon.cmpPos(findrule, rule) then
return m
end
end
@@ -153,7 +153,7 @@ function mesecon.set_bit(binary,bit,value)
end
function mesecon.invertRule(r)
- return {x = -r.x, y = -r.y, z = -r.z, sx = r.sx, sy = r.sy, sz = r.sz}
+ return {x = -r.x, y = -r.y, z = -r.z}
end
function mesecon.addPosRule(p, r)
@@ -164,10 +164,6 @@ 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
if type(table) ~= "table" then return table end -- no need to copy
local newtable = {}
diff --git a/mesecons_gates/init.lua b/mesecons_gates/init.lua
index 345c32c..2b6771a 100644
--- a/mesecons_gates/init.lua
+++ b/mesecons_gates/init.lua
@@ -1,222 +1,124 @@
-function gate_rotate_rules(node)
+local nodebox = {
+ type = "fixed",
+ fixed = {{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }},
+}
+
+local function gate_rotate_rules(node, rules)
for rotations = 0, node.param2 - 1 do
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
-function gate_get_output_rules(node)
- rules = {{x=1, y=0, z=0}}
- return gate_rotate_rules(node)
+local function gate_get_output_rules(node)
+ return gate_rotate_rules(node, {{x=1, y=0, z=0}})
end
-function gate_get_input_rules_oneinput(node)
- rules = {{x=-1, y=0, z=0}, {x=1, y=0, z=0}}
- return gate_rotate_rules(node)
+local function gate_get_input_rules_oneinput(node)
+ return gate_rotate_rules(node, {{x=-1, y=0, z=0}})
end
-function gate_get_input_rules_twoinputs(node)
- rules = {
- {x=0, y=0, z=1},
- {x=0, y=0, z=-1},
- {x=1, y=0, z=0}}
- return gate_rotate_rules(node)
+local function gate_get_input_rules_twoinputs(node)
+ return gate_rotate_rules(node, {{x=0, y=0, z=1, name="input1"},
+ {x=0, y=0, z=-1, name="input2"}})
end
-function update_gate(pos, node, rulename, newstate)
- yc_update_real_portstates(pos, node, rulename, newstate)
- gate = get_gate(pos)
- L = rotate_ports(
- yc_get_real_portstates(pos),
- minetest.get_node(pos).param2
- )
- if gate == "diode" then
- set_gate(pos, L.a)
- elseif gate == "not" then
- set_gate(pos, not L.a)
- elseif gate == "nand" then
- set_gate(pos, not(L.b and L.d))
- elseif gate == "and" then
- set_gate(pos, L.b and L.d)
- elseif gate == "xor" then
- set_gate(pos, (L.b and not L.d) or (not L.b and L.d))
+local function set_gate(pos, node, state)
+ local gate = minetest.registered_nodes[node.name]
+
+ if mesecon.do_overheat(pos) then
+ minetest.remove_node(pos)
+ mesecon.receptor_off(pos, gate_get_output_rules(node))
+ minetest.add_item(pos, gate.drop)
+ elseif state then
+ minetest.swap_node(pos, {name = gate.onstate, param2=node.param2})
+ mesecon.receptor_on(pos, gate_get_output_rules(node))
+ else
+ minetest.swap_node(pos, {name = gate.offstate, param2=node.param2})
+ mesecon.receptor_off(pos, gate_get_output_rules(node))
end
end
-function set_gate(pos, on)
- gate = get_gate(pos)
- local meta = minetest.get_meta(pos)
- if on ~= gate_state(pos) then
- if mesecon.do_overheat(pos) then
- pop_gate(pos)
- else
- local node = minetest.get_node(pos)
- if on then
- minetest.swap_node(pos, {name = "mesecons_gates:"..gate.."_on", param2=node.param2})
- mesecon.receptor_on(pos,
- gate_get_output_rules(node))
- else
- minetest.swap_node(pos, {name = "mesecons_gates:"..gate.."_off", param2=node.param2})
- mesecon.receptor_off(pos,
- gate_get_output_rules(node))
- end
- end
- end
-end
+local function update_gate(pos, node, link, newstate)
+ local gate = minetest.registered_nodes[node.name]
-function get_gate(pos)
- return minetest.registered_nodes[minetest.get_node(pos).name].mesecons_gate
-end
+ if gate.inputnumber == 1 then
+ set_gate(pos, node, gate.assess(newstate == "on"))
+ elseif gate.inputnumber == 2 then
+ local meta = minetest.get_meta(pos)
+ meta:set_int(link.name, newstate == "on" and 1 or 0)
-function gate_state(pos)
- name = minetest.get_node(pos).name
- return string.find(name, "_on") ~= nil
+ local val1 = meta:get_int("input1") == 1
+ local val2 = meta:get_int("input2") == 1
+ set_gate(pos, node, gate.assess(val1, val2))
+ end
end
-function pop_gate(pos)
- gate = get_gate(pos)
- minetest.remove_node(pos)
- minetest.after(0.2, function (pos)
- mesecon.receptor_off(pos, mesecon.rules.flat)
- end , pos) -- wait for pending parsings
- minetest.add_item(pos, "mesecons_gates:"..gate.."_off")
+function register_gate(name, inputnumber, assess, recipe)
+ local get_inputrules = inputnumber == 2 and gate_get_input_rules_twoinputs or
+ gate_get_input_rules_oneinput
+ local description = "Mesecons Logic Gate: "..name
+
+ local basename = "mesecons_gates:"..name
+ mesecon.register_node(basename, {
+ description = description,
+ inventory_image = "jeija_gate_off.png^jeija_gate_"..name..".png",
+ paramtype = "light",
+ paramtype2 = "facedir",
+ drawtype = "nodebox",
+ drop = basename.."_off",
+ selection_box = nodebox,
+ node_box = nodebox,
+ walkable = true,
+ sounds = default.node_sound_stone_defaults(),
+ assess = assess,
+ onstate = basename.."_on",
+ offstate = basename.."_off",
+ inputnumber = inputnumber
+ },{
+ tiles = {"jeija_microcontroller_bottom.png^".."jeija_gate_off.png^"..
+ "jeija_gate_"..name..".png"},
+ groups = {dig_immediate = 2},
+ mesecons = { receptor = {
+ state = "off",
+ rules = gate_get_output_rules
+ }, effector = {
+ rules = get_inputrules,
+ action_change = update_gate
+ }}
+ },{
+ tiles = {"jeija_microcontroller_bottom.png^".."jeija_gate_on.png^"..
+ "jeija_gate_"..name..".png"},
+ groups = {dig_immediate = 2, not_in_creative_inventory = 1},
+ mesecons = { receptor = {
+ state = "on",
+ rules = gate_get_output_rules
+ }, effector = {
+ rules = get_inputrules,
+ action_change = update_gate
+ }}
+ })
+
+ minetest.register_craft({output = basename.."_off", recipe = recipe})
end
-function rotate_ports(L, param2)
- for rotations=0, param2-1 do
- port = L.a
- L.a = L.b
- L.b = L.c
- L.c = L.d
- L.d = port
- end
- return L
-end
+register_gate("diode", 1, function (input) return input end,
+ {{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons_torch:mesecon_torch_on"}})
-gates = {
-{name = "diode", inputnumber = 1},
-{name = "not" , inputnumber = 1},
-{name = "nand" , inputnumber = 2},
-{name = "and" , inputnumber = 2},
-{name = "xor" , inputnumber = 2}}
+register_gate("not", 1, function (input) return not input end,
+ {{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons:mesecon"}})
-local onoff, drop, nodename, description, groups
-for _, gate in ipairs(gates) do
- if gate.inputnumber == 1 then
- get_rules = gate_get_input_rules_oneinput
- elseif gate.inputnumber == 2 then
- get_rules = gate_get_input_rules_twoinputs
- end
- for on = 0, 1 do
- nodename = "mesecons_gates:"..gate.name
- if on == 1 then
- onoff = "on"
- drop = nodename.."_off"
- nodename = nodename.."_"..onoff
- description = "You hacker you!"
- groups = {dig_immediate=2, not_in_creative_inventory=1, overheat = 1}
- else
- onoff = "off"
- drop = nil
- nodename = nodename.."_"..onoff
- description = gate.name.." Gate"
- groups = {dig_immediate=2, overheat = 1}
- end
-
- tiles = "jeija_microcontroller_bottom.png^"..
- "jeija_gate_"..onoff..".png^"..
- "jeija_gate_"..gate.name..".png"
-
- node_box = {
- type = "fixed",
- fixed = {
- {-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 },
- },
- }
-
- local mesecon_state
- if on == 1 then
- mesecon_state = mesecon.state.on
- else
- mesecon_state = mesecon.state.off
- end
-
- minetest.register_node(nodename, {
- description = description,
- paramtype = "light",
- paramtype2 = "facedir",
- drawtype = "nodebox",
- tiles = {tiles},
- inventory_image = tiles,
- selection_box = node_box,
- node_box = node_box,
- walkable = true,
- on_construct = function(pos)
- local meta = minetest.get_meta(pos)
- update_gate(pos)
- end,
- groups = groups,
- drop = drop,
- sounds = default.node_sound_stone_defaults(),
- mesecons_gate = gate.name,
- mesecons =
- {
- receptor =
- {
- state = mesecon_state,
- rules = gate_get_output_rules
- },
- effector =
- {
- rules = get_rules,
- action_change = update_gate
- }
- }
- })
- end
-end
+register_gate("and", 2, function (val1, val2) return val1 and val2 end,
+ {{"mesecons:mesecon", "", ""},
+ {"", "mesecons_materials:silicon", "mesecons:mesecon"},
+ {"mesecons:mesecon", "", ""}})
+
+register_gate("nand", 2, function (val1, val2) return not (val1 and val2) end,
+ {{"mesecons:mesecon", "", ""},
+ {"", "mesecons_materials:silicon", "mesecons_torch:mesecon_torch_on"},
+ {"mesecons:mesecon", "", ""}})
-minetest.register_craft({
- output = 'mesecons_gates:diode_off',
- recipe = {
- {'', '', ''},
- {'mesecons:mesecon', 'mesecons_torch:mesecon_torch_on', 'mesecons_torch:mesecon_torch_on'},
- {'', '', ''},
- },
-})
-
-minetest.register_craft({
- output = 'mesecons_gates:not_off',
- recipe = {
- {'', '', ''},
- {'mesecons:mesecon', 'mesecons_torch:mesecon_torch_on', 'mesecons:mesecon'},
- {'', '', ''},
- },
-})
-
-minetest.register_craft({
- output = 'mesecons_gates:and_off',
- recipe = {
- {'mesecons:mesecon', '', ''},
- {'', 'mesecons_materials:silicon', 'mesecons:mesecon'},
- {'mesecons:mesecon', '', ''},
- },
-})
-
-minetest.register_craft({
- output = 'mesecons_gates:nand_off',
- recipe = {
- {'mesecons:mesecon', '', ''},
- {'', 'mesecons_materials:silicon', 'mesecons_torch:mesecon_torch_on'},
- {'mesecons:mesecon', '', ''},
- },
-})
-
-minetest.register_craft({
- output = 'mesecons_gates:xor_off',
- recipe = {
- {'mesecons:mesecon', '', ''},
- {'', 'mesecons_materials:silicon', 'mesecons_materials:silicon'},
- {'mesecons:mesecon', '', ''},
- },
-})
+register_gate("xor", 2, function (val1, val2) return (val1 or val2) and not (val1 and val2) end,
+ {{"mesecons:mesecon", "", ""},
+ {"", "mesecons_materials:silicon", "mesecons_materials:silicon"},
+ {"mesecons:mesecon", "", ""}})
diff --git a/mesecons_mvps/init.lua b/mesecons_mvps/init.lua
index 163ad28..bcbda17 100644
--- a/mesecons_mvps/init.lua
+++ b/mesecons_mvps/init.lua
@@ -94,7 +94,7 @@ function mesecon.mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: directio
-- add nodes
for _, n in ipairs(nodes) do
- np = mesecon.addPosRule(n.pos, dir)
+ local np = mesecon.addPosRule(n.pos, dir)
minetest.add_node(np, n.node)
minetest.get_meta(np):from_table(n.meta)
end
@@ -123,8 +123,8 @@ mesecon.register_on_mvps_move(function(moved_nodes)
end)
function mesecon.mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons)
- np = mesecon.addPosRule(pos, dir)
- nn = minetest.get_node(np)
+ local np = mesecon.addPosRule(pos, dir)
+ local nn = minetest.get_node(np)
if ((not minetest.registered_nodes[nn.name]) --unregistered node
or minetest.registered_nodes[nn.name].liquidtype == "none") --non-liquid node
diff --git a/mesecons_pistons/init.lua b/mesecons_pistons/init.lua
index b247039..71e63e7 100644
--- a/mesecons_pistons/init.lua
+++ b/mesecons_pistons/init.lua
@@ -55,8 +55,8 @@ piston_get_direction = function(dir, node)
end
local piston_remove_pusher = function(pos, node)
- pistonspec = minetest.registered_nodes[node.name].mesecons_piston
- dir = piston_get_direction(pistonspec.dir, node)
+ local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
+ local dir = piston_get_direction(pistonspec.dir, node)
local pusherpos = mesecon.addPosRule(pos, dir)
local pushername = minetest.get_node(pusherpos).name
@@ -100,9 +100,9 @@ local piston_off = function(pos, node)
piston_remove_pusher(pos, node)
if pistonspec.sticky then
- dir = piston_get_direction(pistonspec.dir, node)
- pullpos = mesecon.addPosRule(pos, dir)
- stack = mesecon.mvps_pull_single(pullpos, dir)
+ local dir = piston_get_direction(pistonspec.dir, node)
+ local pullpos = mesecon.addPosRule(pos, dir)
+ local stack = mesecon.mvps_pull_single(pullpos, dir)
mesecon.mvps_process_stack(pos, dir, stack)
end
end