From 5904abbd79c1ee611f620b60c214823567f3a5f0 Mon Sep 17 00:00:00 2001 From: Jeija Date: Mon, 10 Dec 2012 19:46:24 +0100 Subject: [PATCH] Port gates (finally) --- mesecons/internal.lua | 55 ++++------ mesecons_gates/init.lua | 222 ++++++++++++++++++---------------------- 2 files changed, 122 insertions(+), 155 deletions(-) diff --git a/mesecons/internal.lua b/mesecons/internal.lua index 8337f62..f6873ea 100644 --- a/mesecons/internal.lua +++ b/mesecons/internal.lua @@ -62,8 +62,7 @@ function mesecon:is_effector_on(nodename) if minetest.registered_nodes[nodename] and minetest.registered_nodes[nodename].mesecons and minetest.registered_nodes[nodename].mesecons.effector - and (minetest.registered_nodes[nodename].mesecons.effector.action_off - or minetest.registered_nodes[nodename].mesecons.effector.action_change) then + and minetest.registered_nodes[nodename].mesecons.effector.action_off then return true end for _, effector in ipairs(mesecon.effectors) do --TODO @@ -78,8 +77,7 @@ function mesecon:is_effector_off(nodename) if minetest.registered_nodes[nodename] and minetest.registered_nodes[nodename].mesecons and minetest.registered_nodes[nodename].mesecons.effector - and (minetest.registered_nodes[nodename].mesecons.effector.action_on - or minetest.registered_nodes[nodename].mesecons.effector.action_change) then + and minetest.registered_nodes[nodename].mesecons.effector.action_on then return true end for _, effector in ipairs(mesecon.effectors) do --TODO @@ -109,12 +107,12 @@ function mesecon:effector_get_input_rules(node) return rules end end - for i, effector in ipairs(mesecon.effectors) do + for _, effector in ipairs(mesecon.effectors) do if effector.onstate == node.name or effector.offstate == node.name then if effector.get_input_rules ~= nil then return effector.get_input_rules(node.param2) - elseif mesecon.effectors[i].input_rules ~=nil then + elseif effector.input_rules ~=nil then return effector.input_rules else return mesecon:get_rules("default") @@ -126,8 +124,7 @@ end --Signals -function mesecon:activate(pos) - local node = minetest.env:get_node(pos) +function mesecon:activate(pos, node) if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].mesecons and minetest.registered_nodes[node.name].mesecons.effector @@ -139,8 +136,7 @@ function mesecon:activate(pos) end end -function mesecon:deactivate(pos) --TODO - local node = minetest.env:get_node(pos) +function mesecon:deactivate(pos, node) --TODO if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].mesecons and minetest.registered_nodes[node.name].mesecons.effector @@ -152,15 +148,14 @@ function mesecon:deactivate(pos) --TODO end end -function mesecon:changesignal(pos) --TODO - local node = minetest.env:get_node(pos) +function mesecon:changesignal(pos, node) --TODO if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].mesecons and minetest.registered_nodes[node.name].mesecons.effector and minetest.registered_nodes[node.name].mesecons.effector.action_change then minetest.registered_nodes[node.name].mesecons.effector.action_change(pos, node) end - for i, action in ipairs(mesecon.actions_change) do + for _, action in ipairs(mesecon.actions_change) do action(pos, node) end end @@ -168,15 +163,11 @@ end --Rules function mesecon:add_rules(name, rules) - table.insert(mesecon.rules, {name = name, rules = rules}) + mesecon.rules[name] = rules end function mesecon:get_rules(name) - for i, rule in ipairs(mesecon.rules) do - if rule.name==name then - return rule.rules - end - end + return mesecon.rules[name] end -- Conductors @@ -187,7 +178,7 @@ function mesecon:get_conductor_on(offstate) and minetest.registered_nodes[offstate].mesecons.conductor then return minetest.registered_nodes[offstate].mesecons.conductor.onstate end - for i, conductor in ipairs(mesecon.conductors) do --TODO + for _, conductor in ipairs(mesecon.conductors) do --TODO if conductor.offstate == offstate then return conductor.onstate end @@ -201,7 +192,7 @@ function mesecon:get_conductor_off(onstate) and minetest.registered_nodes[onstate].mesecons.conductor then return minetest.registered_nodes[onstate].mesecons.conductor.offstate end - for i, conductor in ipairs(mesecon.conductors) do --TODO + for _, conductor in ipairs(mesecon.conductors) do --TODO if conductor.onstate == onstate then return conductor.offstate end @@ -255,7 +246,7 @@ function mesecon:conductor_get_rules(node) return rules end end - for i, conductor in ipairs(mesecon.conductors) do --TODO + for _, conductor in ipairs(mesecon.conductors) do --TODO if conductor.onstate == node.name or conductor.offstate == node.name then if conductor.get_rules ~= nil then @@ -302,9 +293,9 @@ function mesecon:turnon(pos) end if mesecon:is_effector(node.name) then - mesecon:changesignal(pos) + mesecon:changesignal(pos, node) if mesecon:is_effector_off(node.name) then - mesecon:activate(pos) + mesecon:activate(pos, node) end end end @@ -326,10 +317,10 @@ function mesecon:turnoff(pos) --receptor rules used because output could have be end if mesecon:is_effector(node.name) then - mesecon:changesignal(pos) + mesecon:changesignal(pos, node) if mesecon:is_effector_on(node.name) and not mesecon:is_powered(pos) then - mesecon:deactivate(pos) + mesecon:deactivate(pos, node) end end end @@ -349,18 +340,14 @@ function mesecon:connected_to_pw_src(pos, checked) local node = minetest.env:get_node_or_nil(pos) if node == nil then return false, checked end + if not mesecon:is_conductor(node.name) then return false, checked end if mesecon:is_powered_by_receptor(pos) then --return if conductor is powered return true, checked end --Check if conductors around are connected - if mesecon:is_conductor(node.name) then - rules = mesecon:conductor_get_rules(node) - elseif mesecon:is_effector(node.name) then - rules = mesecon:effector_get_input_rules(node) - else - return false, checked - end + local connected + local rules = mesecon:conductor_get_rules(node) for _, rule in ipairs(rules) do local np = mesecon:addPosRule(pos, rule) @@ -465,7 +452,7 @@ function mesecon:is_powered_by_receptor(pos) return false end - for i, rule in ipairs(rules) do + for _, rule in ipairs(rules) do local rcpt_pos = mesecon:addPosRule(pos, rule) rcpt_node = minetest.env:get_node(rcpt_pos) diff --git a/mesecons_gates/init.lua b/mesecons_gates/init.lua index 67a090f..dabefd5 100644 --- a/mesecons_gates/init.lua +++ b/mesecons_gates/init.lua @@ -1,57 +1,111 @@ -local outrules = { - {x=1, y=0, z=0}, -} - -local oneinput = { - {x=-1, y=0, z=0}, - {x=1, y=0, z=0}, -} - -local twoinputs = { - {x=0, y=0, z=1}, - {x=0, y=0, z=-1}, - {x=1, y=0, z=0}, -} - -function get_gate_rules(param2, onlyout, singleinput) - if not param2 then return end - if onlyout then - rules = outrules - else - if singleinput then - rules = oneinput - else - rules = twoinputs - end - end - for rotations = 0, param2 - 1 do +function gate_rotate_rules(node) + for rotations = 0, node.param2 - 1 do rules = mesecon:rotate_rules_left(rules) end return rules end -function get_gate_rules_one(node) - print("gettin"..dump(node).." | PARAM2: "..node.param2) - return get_gate_rules(node.param2, false, true) +function gate_get_output_rules(node) + rules = {{x=1, y=0, z=0}} + return gate_rotate_rules(node) end -function get_gate_rules_two(node) - return get_gate_rules(node.param2, false, false) +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) end -function get_gate_rules_out(node) - return get_gate_rules(node.param2, true) +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) end -gates = {"diode", "not", "nand", "and", "xor"} -for g in ipairs(gates) do gate = gates[g] - if g < 3 then - get_rules = get_gate_rules_one - else - get_rules = get_gate_rules_two +function update_gate(pos) + gate = get_gate(pos) + L = rotate_ports( + yc_get_real_portstates(pos), + minetest.env: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)) end - for on=0,1 do - nodename = "mesecons_gates:"..gate +end + +function set_gate(pos, on) + gate = get_gate(pos) + local meta = minetest.env:get_meta(pos) + if on ~= gate_state(pos) then + yc_heat(meta) + minetest.after(0.5, yc_cool, meta) + if yc_overheat(meta) then + pop_gate(pos) + else + if on then + mesecon:swap_node(pos, "mesecons_gates:"..gate.."_on") + mesecon:receptor_on(pos, + gate_get_output_rules(minetest.env:get_node(pos))) + else + mesecon:swap_node(pos, "mesecons_gates:"..gate.."_off") + mesecon:receptor_off(pos, + gate_get_output_rules(minetest.env:get_node(pos))) + end + end + end +end + +function get_gate(pos) + return minetest.registered_nodes[minetest.env:get_node(pos).name].mesecons_gate +end + +function gate_state(pos) + name = minetest.env:get_node(pos).name + return string.find(name, "_on") ~= nil +end + +function pop_gate(pos) + gate = get_gate(pos) + minetest.env:remove_node(pos) + minetest.after(0.2, yc_overheat_off, pos) + minetest.env:add_item(pos, "mesecons_gates:"..gate.."_off") +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 + +gates = { +{name = "diode", inputnumber = 1}, +{name = "not" , inputnumber = 1}, +{name = "nand" , inputnumber = 2}, +{name = "and" , inputnumber = 2}, +{name = "xor" , inputnumber = 2}} + +for i, 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" @@ -61,13 +115,13 @@ for g in ipairs(gates) do gate = gates[g] else onoff = "off" nodename = nodename.."_"..onoff - description = gate.." Gate" + description = gate.name.." Gate" groups = {dig_immediate=2} end tiles = "jeija_microcontroller_bottom.png^".. "jeija_gate_"..onoff..".png^".. - "jeija_gate_"..gate..".png" + "jeija_gate_"..gate.name..".png" node_box = { type = "fixed", @@ -100,98 +154,24 @@ for g in ipairs(gates) do gate = gates[g] end, groups = groups, drop = drop, + mesecons_gate = gate.name, mesecons = { receptor = { state = mesecon_state, - rules = get_gate_rules_out + rules = gate_get_output_rules }, effector = { rules = get_rules, - action_change = function (pos, node) - update_gate(pos) - end + action_change = update_gate } } }) end end -function get_gate(pos) - return - string.gsub( - string.gsub( - string.gsub( - minetest.env:get_node(pos).name - , "mesecons_gates:", "") --gate - ,"_on", "") - ,"_off", "") -end - -function gate_state(pos) - name = minetest.env:get_node(pos).name - return string.find(name, "_on") ~= nil -end - -function pop_gate(pos) - gate = get_gate(pos) - minetest.env:remove_node(pos) - minetest.after(0.2, yc_overheat_off, pos) - minetest.env:add_item(pos, "mesecons_gates:"..gate.."_off") -end - -function set_gate(pos, on) - gate = get_gate(pos) - local meta = minetest.env:get_meta(pos) - if on ~= gate_state(pos) then - yc_heat(meta) - minetest.after(0.5, yc_cool, meta) - if yc_overheat(meta) then - pop_gate(pos) - else - if on then - mesecon:swap_node(pos, "mesecons_gates:"..gate.."_on") - mesecon:receptor_on(pos, get_gate_rules(param2, true)) - else - mesecon:swap_node(pos, "mesecons_gates:"..gate.."_off") - mesecon:receptor_off(pos, all_rules) - end - end - end -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 - -function update_gate(pos) - gate = get_gate(pos) - L = rotate_ports( - yc_get_real_portstates(pos), - minetest.env: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)) - end -end - minetest.register_craft({ output = 'mesecons_gates:diode_off', recipe = {