diff --git a/mods/mesecons/mesecons/actionqueue.lua b/mods/mesecons/mesecons/actionqueue.lua index a5daf887..fa4079ff 100644 --- a/mods/mesecons/mesecons/actionqueue.lua +++ b/mods/mesecons/mesecons/actionqueue.lua @@ -12,19 +12,19 @@ function mesecon.queue:add_action(pos, func, params, time, overwritecheck, prior -- Create Action Table: time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution priority = priority or 1 - local action = { pos=mesecon:tablecopy(pos), + local action = { pos=mesecon.tablecopy(pos), func=func, - params=mesecon:tablecopy(params), + params=mesecon.tablecopy(params or {}), time=time, - owcheck=(overwritecheck and mesecon:tablecopy(overwritecheck)) or nil, + owcheck=(overwritecheck and mesecon.tablecopy(overwritecheck)) or nil, priority=priority} local toremove = nil -- Otherwise, add the action to the queue if overwritecheck then -- check if old action has to be overwritten / removed: for i, ac in ipairs(mesecon.queue.actions) do - if(mesecon:cmpPos(pos, ac.pos) - and mesecon:cmpAny(overwritecheck, ac.owcheck)) then + if(mesecon.cmpPos(pos, ac.pos) + and mesecon.cmpAny(overwritecheck, ac.owcheck)) then toremove = i break end @@ -44,7 +44,8 @@ end -- However, even that does not work in some cases, that's why we delay the time the globalsteps -- start to be execute by 5 seconds local get_highest_priority = function (actions) - local highestp = -1, highesti + local highestp = -1 + local highesti for i, ac in ipairs(actions) do if ac.priority > highestp then highestp = ac.priority @@ -56,10 +57,13 @@ local get_highest_priority = function (actions) end local m_time = 0 +local resumetime = mesecon.setting("resumetime", 4) minetest.register_globalstep(function (dtime) m_time = m_time + dtime - if (m_time < MESECONS_RESUMETIME) then return end -- don't even try if server has not been running for XY seconds - local actions = mesecon:tablecopy(mesecon.queue.actions) + -- don't even try if server has not been running for XY seconds; resumetime = time to wait + -- after starting the server before processing the ActionQueue, don't set this too low + if (m_time < resumetime) then return end + local actions = mesecon.tablecopy(mesecon.queue.actions) local actions_now={} mesecon.queue.actions = {} diff --git a/mods/mesecons/mesecons/init.lua b/mods/mesecons/mesecons/init.lua index 3132955a..096e509f 100644 --- a/mods/mesecons/mesecons/init.lua +++ b/mods/mesecons/mesecons/init.lua @@ -47,15 +47,14 @@ mesecon.queue.funcs={} -- contains all ActionQueue functions -- Settings dofile(minetest.get_modpath("mesecons").."/settings.lua") --- Presets (eg default rules) -dofile(minetest.get_modpath("mesecons").."/presets.lua"); - - -- Utilities like comparing positions, -- adding positions and rules, -- mostly things that make the source look cleaner dofile(minetest.get_modpath("mesecons").."/util.lua"); +-- Presets (eg default rules) +dofile(minetest.get_modpath("mesecons").."/presets.lua"); + -- The ActionQueue -- Saves all the actions that have to be execute in the future dofile(minetest.get_modpath("mesecons").."/actionqueue.lua"); @@ -67,11 +66,6 @@ dofile(minetest.get_modpath("mesecons").."/actionqueue.lua"); -- like calling action_on/off/change dofile(minetest.get_modpath("mesecons").."/internal.lua"); --- Deprecated stuff --- To be removed in future releases --- Currently there is nothing here -dofile(minetest.get_modpath("mesecons").."/legacy.lua"); - -- API -- these are the only functions you need to remember @@ -79,8 +73,8 @@ mesecon.queue:add_function("receptor_on", function (pos, rules) rules = rules or mesecon.rules.default -- if area (any of the rule targets) is not loaded, keep trying and call this again later - for _, rule in ipairs(mesecon:flattenrules(rules)) do - local np = mesecon:addPosRule(pos, rule) + for _, rule in ipairs(mesecon.flattenrules(rules)) do + local np = mesecon.addPosRule(pos, rule) -- if area is not loaded, keep trying if minetest.get_node_or_nil(np) == nil then mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) @@ -89,16 +83,16 @@ mesecon.queue:add_function("receptor_on", function (pos, rules) end -- execute action - for _, rule in ipairs(mesecon:flattenrules(rules)) do - local np = mesecon:addPosRule(pos, rule) - local rulenames = mesecon:rules_link_rule_all(pos, rule) + for _, rule in ipairs(mesecon.flattenrules(rules)) do + local np = mesecon.addPosRule(pos, rule) + local rulenames = mesecon.rules_link_rule_all(pos, rule) for _, rulename in ipairs(rulenames) do - mesecon:turnon(np, rulename) + mesecon.turnon(np, rulename) end end end) -function mesecon:receptor_on(pos, rules) +function mesecon.receptor_on(pos, rules) mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) end @@ -106,34 +100,38 @@ mesecon.queue:add_function("receptor_off", function (pos, rules) rules = rules or mesecon.rules.default -- if area (any of the rule targets) is not loaded, keep trying and call this again later - for _, rule in ipairs(mesecon:flattenrules(rules)) do - local np = mesecon:addPosRule(pos, rule) + for _, rule in ipairs(mesecon.flattenrules(rules)) do + local np = mesecon.addPosRule(pos, rule) if minetest.get_node_or_nil(np) == nil then mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) return end end - for _, rule in ipairs(mesecon:flattenrules(rules)) do - local np = mesecon:addPosRule(pos, rule) - local rulenames = mesecon:rules_link_rule_all(pos, rule) + for _, rule in ipairs(mesecon.flattenrules(rules)) do + local np = mesecon.addPosRule(pos, rule) + local rulenames = mesecon.rules_link_rule_all(pos, rule) for _, rulename in ipairs(rulenames) do - if not mesecon:connected_to_receptor(np, mesecon:invertRule(rule)) then - mesecon:turnoff(np, rulename) + if not mesecon.connected_to_receptor(np, mesecon.invertRule(rule)) then + mesecon.turnoff(np, rulename) else - mesecon:changesignal(np, minetest.get_node(np), rulename, mesecon.state.off, 2) + mesecon.changesignal(np, minetest.get_node(np), rulename, mesecon.state.off, 2) end end end end) -function mesecon:receptor_off(pos, rules) +function mesecon.receptor_off(pos, rules) mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) end print("[OK] Mesecons") +-- Deprecated stuff +-- To be removed in future releases +dofile(minetest.get_modpath("mesecons").."/legacy.lua"); + --The actual wires dofile(minetest.get_modpath("mesecons").."/wires.lua"); diff --git a/mods/mesecons/mesecons/internal.lua b/mods/mesecons/mesecons/internal.lua index 6ed8f742..d62df1ff 100644 --- a/mods/mesecons/mesecons/internal.lua +++ b/mods/mesecons/mesecons/internal.lua @@ -1,62 +1,58 @@ -- Internal.lua - The core of mesecons -- --- For more practical developer resources see mesecons.tk +-- For more practical developer resources see http://mesecons.net/developers.php -- -- Function overview --- mesecon:get_effector(nodename) --> Returns the mesecons.effector -specifictation in the nodedef by the nodename --- mesecon:get_receptor(nodename) --> Returns the mesecons.receptor -specifictation in the nodedef by the nodename --- mesecon:get_conductor(nodename) --> Returns the mesecons.conductor-specifictation in the nodedef by the nodename --- mesecon:get_any_inputrules (node) --> Returns the rules of a node if it is a conductor or an effector --- mesecon:get_any_outputrules (node) --> Returns the rules of a node if it is a conductor or a receptor +-- mesecon.get_effector(nodename) --> Returns the mesecons.effector -specifictation in the nodedef by the nodename +-- mesecon.get_receptor(nodename) --> Returns the mesecons.receptor -specifictation in the nodedef by the nodename +-- mesecon.get_conductor(nodename) --> Returns the mesecons.conductor-specifictation in the nodedef by the nodename +-- mesecon.get_any_inputrules (node) --> Returns the rules of a node if it is a conductor or an effector +-- mesecon.get_any_outputrules (node) --> Returns the rules of a node if it is a conductor or a receptor -- RECEPTORS --- mesecon:is_receptor(nodename) --> Returns true if nodename is a receptor --- mesecon:is_receptor_on(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.on --- mesecon:is_receptor_off(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.off --- mesecon:receptor_get_rules(node) --> Returns the rules of the receptor (mesecon.rules.default if none specified) +-- mesecon.is_receptor(nodename) --> Returns true if nodename is a receptor +-- mesecon.is_receptor_on(nodename --> Returns true if nodename is an receptor with state = mesecon.state.on +-- mesecon.is_receptor_off(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.off +-- mesecon.receptor_get_rules(node) --> Returns the rules of the receptor (mesecon.rules.default if none specified) -- EFFECTORS --- mesecon:is_effector(nodename) --> Returns true if nodename is an effector --- mesecon:is_effector_on(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_off --- mesecon:is_effector_off(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_on --- mesecon:effector_get_rules(node) --> Returns the input rules of the effector (mesecon.rules.default if none specified) +-- mesecon.is_effector(nodename) --> Returns true if nodename is an effector +-- mesecon.is_effector_on(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_off +-- mesecon.is_effector_off(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_on +-- mesecon.effector_get_rules(node) --> Returns the input rules of the effector (mesecon.rules.default if none specified) -- SIGNALS --- mesecon:activate(pos, node, recdepth) --> Activates the effector node at the specific pos (calls nodedef.mesecons.effector.action_on), higher recdepths are executed later --- mesecon:deactivate(pos, node, recdepth) --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off), " --- mesecon:changesignal(pos, node, rulename, newstate) --> Changes the effector node at the specific pos (calls nodedef.mesecons.effector.action_change), " - --- RULES --- mesecon:add_rules(name, rules) | deprecated? --> Saves rules table by name --- mesecon:get_rules(name, rules) | deprecated? --> Loads rules table with name +-- mesecon.activate(pos, node, depth) --> Activates the effector node at the specific pos (calls nodedef.mesecons.effector.action_on), higher depths are executed later +-- mesecon.deactivate(pos, node, depth) --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off), higher depths are executed later +-- mesecon.changesignal(pos, node, rulename, newstate, depth) --> Changes the effector node at the specific pos (calls nodedef.mesecons.effector.action_change), higher depths are executed later -- CONDUCTORS --- mesecon:is_conductor(nodename) --> Returns true if nodename is a conductor --- mesecon:is_conductor_on(node) --> Returns true if node is a conductor with state = mesecon.state.on --- mesecon:is_conductor_off(node) --> Returns true if node is a conductor with state = mesecon.state.off --- mesecon:get_conductor_on(node_off) --> Returns the onstate nodename of the conductor --- 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.is_conductor(nodename) --> Returns true if nodename is a conductor +-- mesecon.is_conductor_on(node --> Returns true if node is a conductor with state = mesecon.state.on +-- mesecon.is_conductor_off(node) --> Returns true if node is a conductor with state = mesecon.state.off +-- mesecon.get_conductor_on(node_off) --> Returns the onstate nodename of the conductor +-- 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) -- HIGH-LEVEL Internals --- mesecon:is_power_on(pos) --> Returns true if pos emits power in any way --- mesecon:is_power_off(pos) --> Returns true if pos does not emit power in any way --- mesecon:turnon(pos, rulename) --> Returns true whatever there is at pos. Calls itself for connected nodes (if pos is a conductor) --> recursive, the rulename is the name of the input rule that caused calling turnon; Uses third parameter recdepth internally to determine how far away the current node is from the initial pos as it uses recursion --- mesecon:turnoff(pos, rulename) --> Turns off whatever there is at pos. Calls itself for connected nodes (if pos is a conductor) --> recursive, the rulename is the name of the input rule that caused calling turnoff; Uses third parameter recdepth internally to determine how far away the current node is from the initial pos as it uses recursion --- mesecon:connected_to_receptor(pos) --> Returns true if pos is connected to a receptor directly or via conductors; calls itself if pos is a conductor --> recursive --- mesecon:rules_link(output, input, dug_outputrules) --> Returns true if outputposition + outputrules = inputposition and inputposition + inputrules = outputposition (if the two positions connect) --- mesecon:rules_link_anydir(outp., inp., d_outpr.) --> Same as rules mesecon:rules_link but also returns true if output and input are swapped --- mesecon:is_powered(pos) --> Returns true if pos is powered by a receptor or a conductor +-- mesecon.is_power_on(pos) --> Returns true if pos emits power in any way +-- mesecon.is_power_off(pos) --> Returns true if pos does not emit power in any way +-- mesecon.turnon(pos, link) --> link is the input rule that caused calling turnon, turns on every connected node, iterative +-- mesecon.turnoff(pos, link) --> link is the input rule that caused calling turnoff, turns off every connected node, iterative +-- mesecon.connected_to_receptor(pos, link) --> Returns true if pos is connected to a receptor directly or via conductors, iterative +-- mesecon.rules_link(output, input, dug_outputrules) --> Returns true if outputposition + outputrules = inputposition and inputposition + inputrules = outputposition (if the two positions connect) +-- mesecon.rules_link_anydir(outp., inp., d_outpr.) --> Same as rules mesecon.rules_link but also returns true if output and input are swapped +-- mesecon.is_powered(pos) --> Returns true if pos is powered by a receptor or a conductor --- RULES ROTATION helpsers --- mesecon:rotate_rules_right(rules) --- mesecon:rotate_rules_left(rules) --- mesecon:rotate_rules_up(rules) --- mesecon:rotate_rules_down(rules) +-- RULES ROTATION helpers +-- mesecon.rotate_rules_right(rules) +-- mesecon.rotate_rules_left(rules) +-- mesecon.rotate_rules_up(rules) +-- mesecon.rotate_rules_down(rules) -- These functions return rules that have been rotated in the specific direction -- General -function mesecon:get_effector(nodename) +function mesecon.get_effector(nodename) if minetest.registered_nodes[nodename] and minetest.registered_nodes[nodename].mesecons and minetest.registered_nodes[nodename].mesecons.effector then @@ -64,7 +60,7 @@ function mesecon:get_effector(nodename) end end -function mesecon:get_receptor(nodename) +function mesecon.get_receptor(nodename) if minetest.registered_nodes[nodename] and minetest.registered_nodes[nodename].mesecons and minetest.registered_nodes[nodename].mesecons.receptor then @@ -72,7 +68,7 @@ function mesecon:get_receptor(nodename) end end -function mesecon:get_conductor(nodename) +function mesecon.get_conductor(nodename) if minetest.registered_nodes[nodename] and minetest.registered_nodes[nodename].mesecons and minetest.registered_nodes[nodename].mesecons.conductor then @@ -80,52 +76,55 @@ function mesecon:get_conductor(nodename) end end -function mesecon:get_any_outputrules (node) - if mesecon:is_conductor(node.name) then - return mesecon:conductor_get_rules(node) - elseif mesecon:is_receptor(node.name) then - return mesecon:receptor_get_rules(node) +function mesecon.get_any_outputrules (node) + if mesecon.is_conductor(node.name) then + return mesecon.conductor_get_rules(node) + elseif mesecon.is_receptor(node.name) then + return mesecon.receptor_get_rules(node) end - return false end -function mesecon:get_any_inputrules (node) - if mesecon:is_conductor(node.name) then - return mesecon:conductor_get_rules(node) - elseif mesecon:is_effector(node.name) then - return mesecon:effector_get_rules(node) +function mesecon.get_any_inputrules (node) + if mesecon.is_conductor(node.name) then + return mesecon.conductor_get_rules(node) + elseif mesecon.is_effector(node.name) then + return mesecon.effector_get_rules(node) end - return false +end + +function mesecon.get_any_rules (node) + return mesecon.mergetable(mesecon.get_any_inputrules(node) or {}, + mesecon.get_any_outputrules(node) or {}) end -- Receptors -- Nodes that can power mesecons -function mesecon:is_receptor_on(nodename) - local receptor = mesecon:get_receptor(nodename) +function mesecon.is_receptor_on(nodename) + local receptor = mesecon.get_receptor(nodename) if receptor and receptor.state == mesecon.state.on then return true end return false end -function mesecon:is_receptor_off(nodename) - local receptor = mesecon:get_receptor(nodename) +function mesecon.is_receptor_off(nodename) + local receptor = mesecon.get_receptor(nodename) if receptor and receptor.state == mesecon.state.off then return true end return false end -function mesecon:is_receptor(nodename) - local receptor = mesecon:get_receptor(nodename) +function mesecon.is_receptor(nodename) + local receptor = mesecon.get_receptor(nodename) if receptor then return true end return false end -function mesecon:receptor_get_rules(node) - local receptor = mesecon:get_receptor(node.name) +function mesecon.receptor_get_rules(node) + local receptor = mesecon.get_receptor(node.name) if receptor then local rules = receptor.rules if type(rules) == 'function' then @@ -140,32 +139,32 @@ end -- Effectors -- Nodes that can be powered by mesecons -function mesecon:is_effector_on(nodename) - local effector = mesecon:get_effector(nodename) +function mesecon.is_effector_on(nodename) + local effector = mesecon.get_effector(nodename) if effector and effector.action_off then return true end return false end -function mesecon:is_effector_off(nodename) - local effector = mesecon:get_effector(nodename) +function mesecon.is_effector_off(nodename) + local effector = mesecon.get_effector(nodename) if effector and effector.action_on then return true end return false end -function mesecon:is_effector(nodename) - local effector = mesecon:get_effector(nodename) +function mesecon.is_effector(nodename) + local effector = mesecon.get_effector(nodename) if effector then return true end return false end -function mesecon:effector_get_rules(node) - local effector = mesecon:get_effector(node.name) +function mesecon.effector_get_rules(node) + local effector = mesecon.get_effector(node.name) if effector then local rules = effector.rules if type(rules) == 'function' then @@ -183,159 +182,150 @@ end -- Activation: mesecon.queue:add_function("activate", function (pos, rulename) - node = minetest.get_node(pos) - effector = mesecon:get_effector(node.name) + local node = minetest.get_node(pos) + local effector = mesecon.get_effector(node.name) if effector and effector.action_on then effector.action_on(pos, node, rulename) end end) -function mesecon:activate(pos, node, rulename, recdepth) +function mesecon.activate(pos, node, rulename, depth) if rulename == nil then - for _,rule in ipairs(mesecon:effector_get_rules(node)) do - mesecon:activate(pos, node, rule, recdepth + 1) + for _,rule in ipairs(mesecon.effector_get_rules(node)) do + mesecon.activate(pos, node, rule, depth + 1) end return end - mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / recdepth) + mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / depth) end -- Deactivation mesecon.queue:add_function("deactivate", function (pos, rulename) - node = minetest.get_node(pos) - effector = mesecon:get_effector(node.name) + local node = minetest.get_node(pos) + local effector = mesecon.get_effector(node.name) if effector and effector.action_off then effector.action_off(pos, node, rulename) end end) -function mesecon:deactivate(pos, node, rulename, recdepth) +function mesecon.deactivate(pos, node, rulename, depth) if rulename == nil then - for _,rule in ipairs(mesecon:effector_get_rules(node)) do - mesecon:deactivate(pos, node, rule, recdepth + 1) + for _,rule in ipairs(mesecon.effector_get_rules(node)) do + mesecon.deactivate(pos, node, rule, depth + 1) end return end - mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / recdepth) + mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / depth) end -- Change mesecon.queue:add_function("change", function (pos, rulename, changetype) - node = minetest.get_node(pos) - effector = mesecon:get_effector(node.name) + local node = minetest.get_node(pos) + local effector = mesecon.get_effector(node.name) if effector and effector.action_change then effector.action_change(pos, node, rulename, changetype) end end) -function mesecon:changesignal(pos, node, rulename, newstate, recdepth) +function mesecon.changesignal(pos, node, rulename, newstate, depth) if rulename == nil then - for _,rule in ipairs(mesecon:effector_get_rules(node)) do - mesecon:changesignal(pos, node, rule, newstate, recdepth + 1) + for _,rule in ipairs(mesecon.effector_get_rules(node)) do + mesecon.changesignal(pos, node, rule, newstate, depth + 1) end return end - mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, rulename, 1 / recdepth) -end - --- ######### --- # Rules # "Database" for rulenames --- ######### - -function mesecon:add_rules(name, rules) - mesecon.rules[name] = rules -end - -function mesecon:get_rules(name) - return mesecon.rules[name] + -- 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 -function mesecon:is_conductor_on(node, rulename) - local conductor = mesecon:get_conductor(node.name) +function mesecon.is_conductor_on(node, rulename) + local conductor = mesecon.get_conductor(node.name) 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(node.name, conductor.states) ~= 1 + return mesecon.getstate(node.name, conductor.states) ~= 1 end - local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node)) - local binstate = mesecon:getbinstate(node.name, conductor.states) - return mesecon:get_bit(binstate, bit) + local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node)) + local binstate = mesecon.getbinstate(node.name, conductor.states) + return mesecon.get_bit(binstate, bit) end end return false end -function mesecon:is_conductor_off(node, rulename) - local conductor = mesecon:get_conductor(node.name) +function mesecon.is_conductor_off(node, rulename) + local conductor = mesecon.get_conductor(node.name) 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(node.name, conductor.states) == 1 + return mesecon.getstate(node.name, conductor.states) == 1 end - local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node)) - local binstate = mesecon:getbinstate(node.name, conductor.states) - return not mesecon:get_bit(binstate, bit) + local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node)) + local binstate = mesecon.getbinstate(node.name, conductor.states) + return not mesecon.get_bit(binstate, bit) end end return false end -function mesecon:is_conductor(nodename) - local conductor = mesecon:get_conductor(nodename) +function mesecon.is_conductor(nodename) + local conductor = mesecon.get_conductor(nodename) if conductor then return true end return false end -function mesecon:get_conductor_on(node_off, rulename) - local conductor = mesecon:get_conductor(node_off.name) +function mesecon.get_conductor_on(node_off, rulename) + local conductor = mesecon.get_conductor(node_off.name) if conductor then if conductor.onstate then return conductor.onstate end if conductor.states then - local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node_off)) - local binstate = mesecon:getbinstate(node_off.name, conductor.states) - binstate = mesecon:set_bit(binstate, bit, "1") + local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_off)) + local binstate = mesecon.getbinstate(node_off.name, conductor.states) + binstate = mesecon.set_bit(binstate, bit, "1") return conductor.states[tonumber(binstate,2)+1] end end return offstate end -function mesecon:get_conductor_off(node_on, rulename) - local conductor = mesecon:get_conductor(node_on.name) +function mesecon.get_conductor_off(node_on, rulename) + local conductor = mesecon.get_conductor(node_on.name) if conductor then if conductor.offstate then return conductor.offstate end if conductor.states then - local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node_on)) - local binstate = mesecon:getbinstate(node_on.name, conductor.states) - binstate = mesecon:set_bit(binstate, bit, "0") + local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_on)) + local binstate = mesecon.getbinstate(node_on.name, conductor.states) + binstate = mesecon.set_bit(binstate, bit, "0") return conductor.states[tonumber(binstate,2)+1] end end return onstate end -function mesecon:conductor_get_rules(node) - local conductor = mesecon:get_conductor(node.name) +function mesecon.conductor_get_rules(node) + local conductor = mesecon.get_conductor(node.name) if conductor then local rules = conductor.rules if type(rules) == 'function' then @@ -349,128 +339,127 @@ end -- some more general high-level stuff -function mesecon:is_power_on(pos, rulename) +function mesecon.is_power_on(pos, rulename) local node = minetest.get_node(pos) - if mesecon:is_conductor_on(node, 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 end return false end -function mesecon:is_power_off(pos, rulename) +function mesecon.is_power_off(pos, rulename) local node = minetest.get_node(pos) - if mesecon:is_conductor_off(node, 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 end return false end -function mesecon:turnon(pos, rulename, recdepth) - recdepth = recdepth or 2 - if (recdepth > STACK_SIZE) then return end - local node = minetest.get_node(pos) +function mesecon.turnon(pos, link) + local frontiers = {{pos = pos, link = link}} - if(node.name == "ignore") then - -- try turning on later again - mesecon.queue:add_action( - pos, "turnon", {rulename, recdepth + 1}, nil, true) - end - - if mesecon:is_conductor_off(node, rulename) then - local rules = mesecon:conductor_get_rules(node) + local depth = 1 + while frontiers[depth] do + local f = frontiers[depth] + local node = minetest.get_node_or_nil(f.pos) - if not rulename then - for _, rule in ipairs(mesecon:flattenrules(rules)) do - if mesecon:connected_to_receptor(pos, rule) then - mesecon:turnon(pos, rule, recdepth + 1) + -- area not loaded, postpone action + if not node then + mesecon.queue:add_action(f.pos, "turnon", {link}, nil, true) + elseif mesecon.is_conductor_off(node, f.link) then + local rules = mesecon.conductor_get_rules(node) + + minetest.swap_node(f.pos, {name = mesecon.get_conductor_on(node, f.link), + param2 = node.param2}) + + -- call turnon on neighbors: normal rules + for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do + local np = mesecon.addPosRule(f.pos, r) + + -- area not loaded, postpone action + if not minetest.get_node_or_nil(np) then + mesecon.queue:add_action(np, "turnon", {rulename}, + nil, true) + else + local links = mesecon.rules_link_rule_all(f.pos, r) + for _, l in ipairs(links) do + table.insert(frontiers, {pos = np, link = l}) + end end end - return - end - - minetest.swap_node(pos, {name = mesecon:get_conductor_on(node, rulename), param2 = node.param2}) - - for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do - local np = mesecon:addPosRule(pos, rule) - if(minetest.get_node(np).name == "ignore") then - -- try turning on later again - mesecon.queue:add_action( - np, "turnon", {rulename, recdepth + 1}, nil, true) - else - local rulenames = mesecon:rules_link_rule_all(pos, rule) - - for _, rulename in ipairs(rulenames) do - mesecon:turnon(np, rulename, recdepth + 1) - end + elseif mesecon.is_effector(node.name) then + mesecon.changesignal(f.pos, node, f.link, mesecon.state.on, depth) + if mesecon.is_effector_off(node.name) then + mesecon.activate(f.pos, node, f.link, depth) end end - elseif mesecon:is_effector(node.name) then - mesecon:changesignal(pos, node, rulename, mesecon.state.on, recdepth) - if mesecon:is_effector_off(node.name) then - mesecon:activate(pos, node, rulename, recdepth) - end + depth = depth + 1 end end mesecon.queue:add_function("turnon", function (pos, rulename, recdepth) - mesecon:turnon(pos, rulename, recdepth) + mesecon.turnon(pos, rulename, recdepth) end) -function mesecon:turnoff(pos, rulename, recdepth) - recdepth = recdepth or 2 - if (recdepth > STACK_SIZE) then return end - local node = minetest.get_node(pos) +function mesecon.turnoff(pos, link) + local frontiers = {{pos = pos, link = link}} - if(node.name == "ignore") then - -- try turning on later again - mesecon.queue:add_action( - pos, "turnoff", {rulename, recdepth + 1}, nil, true) - end + local depth = 1 + while frontiers[depth] do + local f = frontiers[depth] + local node = minetest.get_node_or_nil(f.pos) - if mesecon:is_conductor_on(node, rulename) then - local rules = mesecon:conductor_get_rules(node) - minetest.swap_node(pos, {name = mesecon:get_conductor_off(node, rulename), param2 = node.param2}) + -- area not loaded, postpone action + if not node then + mesecon.queue:add_action(f.pos, "turnoff", {link}, nil, true) + elseif mesecon.is_conductor_on(node, f.link) then + local rules = mesecon.conductor_get_rules(node) - for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do - local np = mesecon:addPosRule(pos, rule) - if(minetest.get_node(np).name == "ignore") then - -- try turning on later again - mesecon.queue:add_action( - np, "turnoff", {rulename, recdepth + 1}, nil, true) - else - local rulenames = mesecon:rules_link_rule_all(pos, rule) + minetest.swap_node(f.pos, {name = mesecon.get_conductor_off(node, f.link), + param2 = node.param2}) - for _, rulename in ipairs(rulenames) do - mesecon:turnoff(np, rulename, recdepth + 1) + -- call turnoff on neighbors: normal rules + for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do + local np = mesecon.addPosRule(f.pos, r) + + -- area not loaded, postpone action + if not minetest.get_node_or_nil(np) then + mesecon.queue:add_action(np, "turnoff", {rulename}, + nil, true) + else + local links = mesecon.rules_link_rule_all(f.pos, r) + for _, l in ipairs(links) do + table.insert(frontiers, {pos = np, link = l}) + end end end + elseif mesecon.is_effector(node.name) then + mesecon.changesignal(f.pos, node, f.link, mesecon.state.off, depth) + if mesecon.is_effector_on(node.name) and not mesecon.is_powered(f.pos) then + mesecon.deactivate(f.pos, node, f.link, depth) + end end - elseif mesecon:is_effector(node.name) then - mesecon:changesignal(pos, node, rulename, mesecon.state.off, recdepth) - if mesecon:is_effector_on(node.name) - and not mesecon:is_powered(pos) then - mesecon:deactivate(pos, node, rulename, recdepth + 1) - end + depth = depth + 1 end end mesecon.queue:add_function("turnoff", function (pos, rulename, recdepth) - mesecon:turnoff(pos, rulename, recdepth) + mesecon.turnoff(pos, rulename, recdepth) end) -function mesecon:connected_to_receptor(pos, rulename) +function mesecon.connected_to_receptor(pos, link) local node = minetest.get_node(pos) -- Check if conductors around are connected - local rules = mesecon:get_any_inputrules(node) + local rules = mesecon.get_any_inputrules(node) if not rules then return false end - for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do - local rulenames = mesecon:rules_link_rule_all_inverted(pos, rule) - for _, rname in ipairs(rulenames) do - local np = mesecon:addPosRule(pos, rname) - if mesecon:find_receptor_on(np, {}, mesecon:invertRule(rname)) then + for _, rule in ipairs(mesecon.rule2meta(link, rules)) do + local links = mesecon.rules_link_rule_all_inverted(pos, rule) + for _, l in ipairs(links) do + local np = mesecon.addPosRule(pos, l) + if mesecon.find_receptor_on(np, mesecon.invertRule(l)) then return true end end @@ -479,68 +468,56 @@ function mesecon:connected_to_receptor(pos, rulename) return false end -function mesecon:find_receptor_on(pos, checked, rulename, recdepth) - recdepth = recdepth or 2 - if (recdepth > STACK_SIZE) then return true end -- ignore request - local node = minetest.get_node(pos) +function mesecon.find_receptor_on(pos, link) + local frontiers = {{pos = pos, link = link}} + local checked = {} - 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 + -- List of positions that have been searched for onstate receptors + local depth = 1 + while frontiers[depth] do + local f = frontiers[depth] + local node = minetest.get_node_or_nil(f.pos) - 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 rulenames = mesecon:rules_link_rule_all_inverted(pos, rule) - for _, rname in ipairs(rulenames) do - local np = mesecon:addPosRule(pos, rname) - if mesecon:find_receptor_on(np, checked, mesecon:invertRule(rname), recdepth + 1) then - return true + if not node then return false end + if mesecon.is_receptor_on(node.name) then return true end + if mesecon.is_conductor_on(node, f.link) then + local rules = mesecon.conductor_get_rules(node) + + -- call turnoff on neighbors: normal rules + for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do + local np = mesecon.addPosRule(f.pos, r) + + local links = mesecon.rules_link_rule_all_inverted(f.pos, r) + for _, l in ipairs(links) do + local checkedstring = np.x..np.y..np.z..l.x..l.y..l.z + if not checked[checkedstring] then + table.insert(frontiers, {pos = np, link = l}) + checked[checkedstring] = true + end 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}) + depth = depth + 1 end - - return false end -function mesecon:rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule +function mesecon.rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule local outputnode = minetest.get_node(output) local inputnode = minetest.get_node(input) - local outputrules = dug_outputrules or mesecon:get_any_outputrules (outputnode) - local inputrules = mesecon:get_any_inputrules (inputnode) + local outputrules = dug_outputrules or mesecon.get_any_outputrules (outputnode) + local inputrules = mesecon.get_any_inputrules (inputnode) if not outputrules or not inputrules then return end - for _, outputrule in ipairs(mesecon:flattenrules(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(mesecon:flattenrules(inputrules)) do + if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then + 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 + if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then + return true, inputrule end end end @@ -548,161 +525,128 @@ function mesecon:rules_link(output, input, dug_outputrules) --output/input are p return false end -function mesecon:rules_link_rule_all(output, rule) --output/input are positions (outputrules optional, used if node has been dug), second return value: affected input rules - local input = mesecon:addPosRule(output, rule) +function mesecon.rules_link_rule_all(output, rule) + local input = mesecon.addPosRule(output, rule) local inputnode = minetest.get_node(input) - local inputrules = mesecon:get_any_inputrules (inputnode) + local inputrules = mesecon.get_any_inputrules (inputnode) if not inputrules then return {} end local rules = {} - for _, inputrule in ipairs(mesecon:flattenrules(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 - if inputrule.sx == nil or rule.sx == nil or mesecon:cmpSpecial(inputrule, rule) then - rules[#rules+1] = inputrule - end + if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then + table.insert(rules, inputrule) end end return rules end -function mesecon:rules_link_rule_all_inverted(input, rule) - --local irule = mesecon:invertRule(rule) - local output = mesecon:addPosRule(input, rule) +function mesecon.rules_link_rule_all_inverted(input, rule) + --local irule = mesecon.invertRule(rule) + local output = mesecon.addPosRule(input, rule) local outputnode = minetest.get_node(output) - local outputrules = mesecon:get_any_outputrules (outputnode) + local outputrules = mesecon.get_any_outputrules (outputnode) if not outputrules then return {} end local rules = {} - 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 - rules[#rules+1] = mesecon:invertRule(outputrule) - end + for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do + if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then + table.insert(rules, mesecon.invertRule(outputrule)) end end return rules end -function mesecon:rules_link_anydir(pos1, pos2) - return mesecon:rules_link(pos1, pos2) or mesecon:rules_link(pos2, pos1) +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, rule) +function mesecon.is_powered(pos, rule) local node = minetest.get_node(pos) - local rules = mesecon:get_any_inputrules(node) + local rules = mesecon.get_any_inputrules(node) if not rules then return false end + -- List of nodes that send out power to pos + local sourcepos = {} + if not rule then - for _, rule in ipairs(mesecon:flattenrules(rules)) do - local rulenames = mesecon:rules_link_rule_all_inverted(pos, rule) + for _, rule in ipairs(mesecon.flattenrules(rules)) do + local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) for _, rname in ipairs(rulenames) do - local np = mesecon:addPosRule(pos, rname) + local np = mesecon.addPosRule(pos, rname) local nn = minetest.get_node(np) - if (mesecon:is_conductor_on (nn, mesecon:invertRule(rname)) or mesecon:is_receptor_on (nn.name)) then - return true + if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) + or mesecon.is_receptor_on (nn.name)) then + table.insert(sourcepos, np) end end end else - local rulenames = mesecon:rules_link_rule_all_inverted(pos, rule) + local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) for _, rname in ipairs(rulenames) do - local np = mesecon:addPosRule(pos, rname) + local np = mesecon.addPosRule(pos, rname) local nn = minetest.get_node(np) - if (mesecon:is_conductor_on (nn, mesecon:invertRule(rname)) or mesecon:is_receptor_on (nn.name)) then - return true + if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) + or mesecon.is_receptor_on (nn.name)) then + table.insert(sourcepos, np) end end end - - return false + + -- Return FALSE if not powered, return list of sources if is powered + if (#sourcepos == 0) then return false + else return sourcepos end end --Rules rotation Functions: -function mesecon:rotate_rules_right(rules) +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 -function mesecon:rotate_rules_left(rules) +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 -function mesecon:rotate_rules_down(rules) +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 -function mesecon:rotate_rules_up(rules) +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/mods/mesecons/mesecons/legacy.lua b/mods/mesecons/mesecons/legacy.lua index 89c87cab..6d8ccca0 100644 --- a/mods/mesecons/mesecons/legacy.lua +++ b/mods/mesecons/mesecons/legacy.lua @@ -1,32 +1,30 @@ -minetest.swap_node = minetest.swap_node or function(pos, node) - local data = minetest.get_meta(pos):to_table() - minetest.add_node(pos, node) - minetest.get_meta(pos):from_table(data) +-- Ugly hack to prevent breaking compatibility with other mods +-- Just remove the following two functions to delete the hack, to be done when other mods have updated +function mesecon.receptor_on(self, pos, rules) + if (self.receptor_on) then + print("[Mesecons] Warning: A mod with mesecon support called mesecon:receptor_on.") + print("[Mesecons] If you are the programmer of this mod, please update it ") + print("[Mesecons] to use mesecon.receptor_on instead. mesecon:* is deprecated") + print("[Mesecons] Otherwise, please make sure you're running the latest version") + print("[Mesecons] of that mod and inform the mod creator.") + else + rules = pos + pos = self + end + mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) end -local rules = {} -rules.a = {x = -1, y = 0, z = 0, name="A"} -rules.b = {x = 0, y = 0, z = 1, name="B"} -rules.c = {x = 1, y = 0, z = 0, name="C"} -rules.d = {x = 0, y = 0, z = -1, name="D"} - -function legacy_update_ports(pos) - local meta = minetest.get_meta(pos) - L = { - a = mesecon:is_power_on(mesecon:addPosRule(pos, rules.a), - mesecon:invertRule(rules.a)) and - mesecon:rules_link(mesecon:addPosRule(pos, rules.a), pos), - b = mesecon:is_power_on(mesecon:addPosRule(pos, rules.b), - mesecon:invertRule(rules.b)) and - mesecon:rules_link(mesecon:addPosRule(pos, rules.b), pos), - c = mesecon:is_power_on(mesecon:addPosRule(pos, rules.c), - mesecon:invertRule(rules.c)) and - mesecon:rules_link(mesecon:addPosRule(pos, rules.c), pos), - d = mesecon:is_power_on(mesecon:addPosRule(pos, rules.d), - mesecon:invertRule(rules.d)) and - mesecon:rules_link(mesecon:addPosRule(pos, rules.d), pos), - } - local n = (L.a and 1 or 0) + (L.b and 2 or 0) + (L.c and 4 or 0) + (L.d and 8 or 0) + 1 - meta:set_int("real_portstates", n) - return L +function mesecon.receptor_off(self, pos, rules) + if (self.receptor_off) then + print("[Mesecons] Warning: A mod with mesecon support called mesecon:receptor_off.") + print("[Mesecons] If you are the programmer of this mod, please update it ") + print("[Mesecons] to use mesecon.receptor_off instead. mesecon:* is deprecated") + print("[Mesecons] Otherwise, please make sure you're running the latest version") + print("[Mesecons] of that mod and inform the mod creator.") + else + rules = pos + pos = self + end + mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) end + diff --git a/mods/mesecons/mesecons/presets.lua b/mods/mesecons/mesecons/presets.lua index 6c8d3eac..ea4bd65a 100644 --- a/mods/mesecons/mesecons/presets.lua +++ b/mods/mesecons/mesecons/presets.lua @@ -15,6 +15,8 @@ mesecon.rules.default = {x=0, y=1, z=-1}, {x=0, y=-1, z=-1}} +mesecon.rules.pplate = mesecon.mergetable(mesecon.rules.default, {{x=0, y=-2, z=0}}) + mesecon.rules.buttonlike = {{x = 1, y = 0, z = 0}, {x = 1, y = 1, z = 0}, @@ -32,11 +34,11 @@ mesecon.rules.flat = mesecon.rules.buttonlike_get = function(node) local rules = mesecon.rules.buttonlike if node.param2 == 2 then - rules=mesecon:rotate_rules_left(rules) + rules=mesecon.rotate_rules_left(rules) elseif node.param2 == 3 then - rules=mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules)) + rules=mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules)) elseif node.param2 == 0 then - rules=mesecon:rotate_rules_right(rules) + rules=mesecon.rotate_rules_right(rules) end return rules end diff --git a/mods/mesecons/mesecons/services.lua b/mods/mesecons/mesecons/services.lua index b0b45e01..215fb318 100644 --- a/mods/mesecons/mesecons/services.lua +++ b/mods/mesecons/mesecons/services.lua @@ -1,44 +1,68 @@ -- Dig and place services mesecon.on_placenode = function (pos, node) + mesecon.update_autoconnect(pos, node) + -- Receptors: Send on signal when active - if mesecon:is_receptor_on(node.name) then - mesecon:receptor_on(pos, mesecon:receptor_get_rules(node)) + if mesecon.is_receptor_on(node.name) then + mesecon.receptor_on(pos, mesecon.receptor_get_rules(node)) end -- Conductors: Send turnon signal when powered or replace by respective offstate conductor -- if placed conductor is an onstate one - if mesecon:is_conductor(node.name) then - if mesecon:is_powered(pos) then + if mesecon.is_conductor(node.name) then + local sources = mesecon.is_powered(pos) + if sources then -- also call receptor_on if itself is powered already, so that neighboring -- conductors will be activated (when pushing an on-conductor with a piston) - mesecon:turnon (pos) - mesecon:receptor_on (pos, mesecon:conductor_get_rules(node)) - elseif mesecon:is_conductor_off(node.name) then - minetest.swap_node(pos, {name = mesecon:get_conductor_off(node)}) + for _, s in ipairs(sources) do + local rule = {x = pos.x - s.x, y = pos.y - s.y, z = pos.z - s.z} + mesecon.turnon(pos, rule) + end + --mesecon.receptor_on (pos, mesecon.conductor_get_rules(node)) + elseif mesecon.is_conductor_on(node) then + minetest.swap_node(pos, {name = mesecon.get_conductor_off(node)}) end end -- 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) + if mesecon.is_effector(node.name) then + 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 mesecon.on_dignode = function (pos, node) - if mesecon:is_conductor_on(node) then - mesecon:receptor_off(pos, mesecon:conductor_get_rules(node)) - elseif mesecon:is_receptor_on(node.name) then - mesecon:receptor_off(pos, mesecon:receptor_get_rules(node)) + if mesecon.is_conductor_on(node) then + mesecon.receptor_off(pos, mesecon.conductor_get_rules(node)) + elseif mesecon.is_receptor_on(node.name) then + mesecon.receptor_off(pos, mesecon.receptor_get_rules(node)) end + mesecon.queue:add_action(pos, "update_autoconnect", {node}) end +mesecon.queue:add_function("update_autoconnect", mesecon.update_autoconnect) + minetest.register_on_placenode(mesecon.on_placenode) minetest.register_on_dignode(mesecon.on_dignode) @@ -52,7 +76,7 @@ mesecon.do_overheat = function(pos) heat = heat + 1 meta:set_int("heat", heat) - if heat < OVERHEAT_MAX then + if heat < mesecon.setting("overheat_max", 20) then mesecon.queue:add_action(pos, "cooldown", {}, 1, nil, 0) else return true diff --git a/mods/mesecons/mesecons/settings.lua b/mods/mesecons/mesecons/settings.lua index 147fd71d..fb03dff8 100644 --- a/mods/mesecons/mesecons/settings.lua +++ b/mods/mesecons/mesecons/settings.lua @@ -1,14 +1,10 @@ -- SETTINGS -BLINKY_PLANT_INTERVAL = 3 -NEW_STYLE_WIRES = true -- true = new nodebox wires, false = old raillike wires -PRESSURE_PLATE_INTERVAL = 0.1 -OBJECT_DETECTOR_RADIUS = 6 -PISTON_MAXIMUM_PUSH = 15 -MOVESTONE_MAXIMUM_PUSH = 100 -MESECONS_RESUMETIME = 4 -- time to wait when starting the server before - -- processing the ActionQueue, don't set this too low -OVERHEAT_MAX = 20 -- maximum heat of any component that directly sends an output - -- signal when the input changes (e.g. luacontroller, gates) - -- Unit: actions per second, checks are every 1 second -STACK_SIZE = 3000 -- Recursive functions will abort when this is reached. Therefore, - -- this is also limits the maximum circuit size. +function mesecon.setting(setting, default) + if type(default) == "bool" then + return minetest.setting_getbool("mesecon."..setting) or default + elseif type(default) == "string" then + return minetest.setting_get("mesecon."..setting) or default + elseif type(default) == "number" then + return tonumber(minetest.setting_get("mesecon."..setting) or default) + end +end diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_crossing_off.png b/mods/mesecons/mesecons/textures/jeija_mesecon_crossing_off.png deleted file mode 100644 index 4e3ca032..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_crossing_off.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_crossing_on.png b/mods/mesecons/mesecons/textures/jeija_mesecon_crossing_on.png deleted file mode 100644 index 4518fa7d..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_crossing_on.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_curved_off.png b/mods/mesecons/mesecons/textures/jeija_mesecon_curved_off.png deleted file mode 100644 index b34335fc..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_curved_off.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_curved_on.png b/mods/mesecons/mesecons/textures/jeija_mesecon_curved_on.png deleted file mode 100644 index fa882e43..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_curved_on.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_inverter_off.png b/mods/mesecons/mesecons/textures/jeija_mesecon_inverter_off.png deleted file mode 100644 index bd4de1b0..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_inverter_off.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_inverter_on.png b/mods/mesecons/mesecons/textures/jeija_mesecon_inverter_on.png deleted file mode 100644 index be41599e..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_inverter_on.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_on.png b/mods/mesecons/mesecons/textures/jeija_mesecon_on.png deleted file mode 100644 index d7ebeecb..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_on.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_plug.png b/mods/mesecons/mesecons/textures/jeija_mesecon_plug.png deleted file mode 100644 index 8a4d2817..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_plug.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_socket_off.png b/mods/mesecons/mesecons/textures/jeija_mesecon_socket_off.png deleted file mode 100644 index ad3f6014..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_socket_off.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_socket_on.png b/mods/mesecons/mesecons/textures/jeija_mesecon_socket_on.png deleted file mode 100644 index 6a9c4804..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_socket_on.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_t_junction_off.png b/mods/mesecons/mesecons/textures/jeija_mesecon_t_junction_off.png deleted file mode 100644 index 71318465..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_t_junction_off.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_t_junction_on.png b/mods/mesecons/mesecons/textures/jeija_mesecon_t_junction_on.png deleted file mode 100644 index a6609ee1..00000000 Binary files a/mods/mesecons/mesecons/textures/jeija_mesecon_t_junction_on.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/jeija_mesecon_off.png b/mods/mesecons/mesecons/textures/mesecons_wire_inv.png similarity index 100% rename from mods/mesecons/mesecons/textures/jeija_mesecon_off.png rename to mods/mesecons/mesecons/textures/mesecons_wire_inv.png diff --git a/mods/mesecons/mesecons/textures/wires_full_off.png b/mods/mesecons/mesecons/textures/mesecons_wire_off.png similarity index 100% rename from mods/mesecons/mesecons/textures/wires_full_off.png rename to mods/mesecons/mesecons/textures/mesecons_wire_off.png diff --git a/mods/mesecons/mesecons/textures/wires_full_on.png b/mods/mesecons/mesecons/textures/mesecons_wire_on.png similarity index 100% rename from mods/mesecons/mesecons/textures/wires_full_on.png rename to mods/mesecons/mesecons/textures/mesecons_wire_on.png diff --git a/mods/mesecons/mesecons/textures/wires_bump_off.png b/mods/mesecons/mesecons/textures/wires_bump_off.png deleted file mode 100644 index 1e0bd747..00000000 Binary files a/mods/mesecons/mesecons/textures/wires_bump_off.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/wires_bump_on.png b/mods/mesecons/mesecons/textures/wires_bump_on.png deleted file mode 100644 index da9a6617..00000000 Binary files a/mods/mesecons/mesecons/textures/wires_bump_on.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/wires_inv.png b/mods/mesecons/mesecons/textures/wires_inv.png deleted file mode 100644 index 626f8d4f..00000000 Binary files a/mods/mesecons/mesecons/textures/wires_inv.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/wires_off.png b/mods/mesecons/mesecons/textures/wires_off.png deleted file mode 100644 index 757d339b..00000000 Binary files a/mods/mesecons/mesecons/textures/wires_off.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/wires_on.png b/mods/mesecons/mesecons/textures/wires_on.png deleted file mode 100644 index 57bb82d0..00000000 Binary files a/mods/mesecons/mesecons/textures/wires_on.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/wires_vertical_off.png b/mods/mesecons/mesecons/textures/wires_vertical_off.png deleted file mode 100644 index ba8d4726..00000000 Binary files a/mods/mesecons/mesecons/textures/wires_vertical_off.png and /dev/null differ diff --git a/mods/mesecons/mesecons/textures/wires_vertical_on.png b/mods/mesecons/mesecons/textures/wires_vertical_on.png deleted file mode 100644 index 172fa65f..00000000 Binary files a/mods/mesecons/mesecons/textures/wires_vertical_on.png and /dev/null differ diff --git a/mods/mesecons/mesecons/util.lua b/mods/mesecons/mesecons/util.lua index 91d435a7..a64e00ce 100644 --- a/mods/mesecons/mesecons/util.lua +++ b/mods/mesecons/mesecons/util.lua @@ -1,4 +1,4 @@ -function mesecon:move_node(pos, newpos) +function mesecon.move_node(pos, newpos) local node = minetest.get_node(pos) local meta = minetest.get_meta(pos):to_table() minetest.remove_node(pos) @@ -7,18 +7,18 @@ function mesecon:move_node(pos, newpos) end --[[ new functions: -mesecon:flattenrules(allrules) -mesecon:rule2bit(findrule, allrules) -mesecon:rule2meta(findrule, allrules) +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) +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) +function mesecon.flattenrules(allrules) --[[ { { @@ -53,7 +53,7 @@ function mesecon:flattenrules(allrules) --]] end -function mesecon:rule2bit(findrule, allrules) +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 @@ -62,14 +62,14 @@ 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 end end -function mesecon:rule2metaindex(findrule, allrules) +function mesecon.rule2metaindex(findrule, allrules) --get the metarule the rule is in, or allrules if allrules[1].x then @@ -77,20 +77,20 @@ function mesecon:rule2metaindex(findrule, allrules) end if not(findrule) then - return mesecon:flattenrules(allrules) + return mesecon.flattenrules(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 end end -function mesecon:rule2meta(findrule, allrules) - local index = mesecon:rule2metaindex(findrule, allrules) +function mesecon.rule2meta(findrule, allrules) + local index = mesecon.rule2metaindex(findrule, allrules) if index == nil then if allrules[1].x then return allrules @@ -119,7 +119,7 @@ else end end -function mesecon:getstate(nodename, states) +function mesecon.getstate(nodename, states) for state, name in ipairs(states) do if name == nodename then return state @@ -128,23 +128,23 @@ function mesecon:getstate(nodename, states) error(nodename.." doesn't mention itself in "..dump(states)) end -function mesecon:getbinstate(nodename, states) - return dec2bin(mesecon:getstate(nodename, states)-1) +function mesecon.getbinstate(nodename, states) + return dec2bin(mesecon.getstate(nodename, states)-1) end -function mesecon:get_bit(binary,bit) +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) +function mesecon.set_bit(binary,bit,value) if value == "1" then - if not mesecon:get_bit(binary,bit) 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 + if mesecon.get_bit(binary,bit) then return dec2bin(tonumber(binary,2)-math.pow(2,bit-1)) end end @@ -152,29 +152,25 @@ 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} +function mesecon.invertRule(r) + return {x = -r.x, y = -r.y, z = -r.z} end -function mesecon:addPosRule(p, r) +function mesecon.addPosRule(p, r) return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z} end -function mesecon:cmpPos(p1, p2) +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 +function mesecon.tablecopy(table) -- deep table copy if type(table) ~= "table" then return table end -- no need to copy local newtable = {} for idx, item in pairs(table) do if type(item) == "table" then - newtable[idx] = mesecon:tablecopy(item) + newtable[idx] = mesecon.tablecopy(item) else newtable[idx] = item end @@ -183,13 +179,53 @@ function mesecon:tablecopy(table) -- deep table copy return newtable end -function mesecon:cmpAny(t1, t2) +function mesecon.cmpAny(t1, t2) if type(t1) ~= type(t2) then return false end if type(t1) ~= "table" and type(t2) ~= "table" then return t1 == t2 end for i, e in pairs(t1) do - if not mesecon:cmpAny(e, t2[i]) then return false end + if not mesecon.cmpAny(e, t2[i]) then return false end end return true end + +-- does not overwrite values; number keys (ipairs) are appended, not overwritten +function mesecon.mergetable(source, dest) + local rval = mesecon.tablecopy(dest) + + for k, v in pairs(source) do + rval[k] = dest[k] or mesecon.tablecopy(v) + end + for i, v in ipairs(source) do + table.insert(rval, mesecon.tablecopy(v)) + end + + return rval +end + +function mesecon.register_node(name, spec_common, spec_off, spec_on) + spec_common.drop = spec_common.drop or name .. "_off" + spec_common.__mesecon_basename = name + spec_on.__mesecon_state = "on" + spec_off.__mesecon_state = "off" + + spec_on = mesecon.mergetable(spec_common, spec_on); + spec_off = mesecon.mergetable(spec_common, spec_off); + + minetest.register_node(name .. "_on", spec_on) + minetest.register_node(name .. "_off", spec_off) +end + +-- swap onstate and offstate nodes, returns new state +function mesecon.flipstate(pos, node) + local nodedef = minetest.registered_nodes[node.name] + local newstate + if (nodedef.__mesecon_state == "on") then newstate = "off" end + if (nodedef.__mesecon_state == "off") then newstate = "on" end + + minetest.swap_node(pos, {name = nodedef.__mesecon_basename .. "_" .. newstate, + param2 = node.param2}) + + return newstate +end diff --git a/mods/mesecons/mesecons/wires.lua b/mods/mesecons/mesecons/wires.lua index 499c7814..40c85413 100644 --- a/mods/mesecons/mesecons/wires.lua +++ b/mods/mesecons/mesecons/wires.lua @@ -1,280 +1,250 @@ --- naming scheme: wire:(xp)(zp)(xm)(zm)_on/off --- The conditions in brackets define whether there is a mesecon at that place or not --- 1 = there is one; 0 = there is none --- y always means y+ +-- naming scheme: wire:(xp)(zp)(xm)(zm)(xpyp)(zpyp)(xmyp)(zmyp)_on/off +-- where x= x direction, z= z direction, y= y direction, p = +1, m = -1, e.g. xpym = {x=1, y=-1, z=0} +-- The (xp)/(zpyp)/.. statements shall be replaced by either 0 or 1 +-- Where 0 means the wire has no visual connection to that direction and +-- 1 means that the wire visually connects to that other node. -box_center = {-1/16, -.5, -1/16, 1/16, -.5+1/16, 1/16} -box_bump1 = { -2/16, -8/16, -2/16, 2/16, -13/32, 2/16 } +-- ####################### +-- ## Update wire looks ## +-- ####################### -box_xp = {1/16, -.5, -1/16, 8/16, -.5+1/16, 1/16} -box_zp = {-1/16, -.5, 1/16, 1/16, -.5+1/16, 8/16} -box_xm = {-8/16, -.5, -1/16, -1/16, -.5+1/16, 1/16} -box_zm = {-1/16, -.5, -8/16, 1/16, -.5+1/16, -1/16} +-- self_pos = pos of any mesecon node, from_pos = pos of conductor to getconnect for +local wire_getconnect = function (from_pos, self_pos) + local node = minetest.get_node(self_pos) + if minetest.registered_nodes[node.name] + and minetest.registered_nodes[node.name].mesecons then + -- rules of node to possibly connect to + local rules = {} + if (minetest.registered_nodes[node.name].mesecon_wire) then + rules = mesecon.rules.default + else + rules = mesecon.get_any_rules(node) + end -box_xpy = {.5-1/16, -.5+1/16, -1/16, .5, .4999+1/16, 1/16} -box_zpy = {-1/16, -.5+1/16, .5-1/16, 1/16, .4999+1/16, .5} -box_xmy = {-.5, -.5+1/16, -1/16, -.5+1/16, .4999+1/16, 1/16} -box_zmy = {-1/16, -.5+1/16, -.5, 1/16, .4999+1/16, -.5+1/16} + for _, r in ipairs(mesecon.flattenrules(rules)) do + if (mesecon.cmpPos(mesecon.addPosRule(self_pos, r), from_pos)) then + return true + end + end + end + return false +end --- Registering the wires +-- Update this node +local wire_updateconnect = function (pos) + local connections = {} -for xp=0, 1 do -for zp=0, 1 do -for xm=0, 1 do -for zm=0, 1 do -for xpy=0, 1 do -for zpy=0, 1 do -for xmy=0, 1 do -for zmy=0, 1 do - if (xpy == 1 and xp == 0) or (zpy == 1 and zp == 0) - or (xmy == 1 and xm == 0) or (zmy == 1 and zm == 0) then break end + for _, r in ipairs(mesecon.rules.default) do + if wire_getconnect(pos, mesecon.addPosRule(pos, r)) then + table.insert(connections, r) + end + end - local groups - local nodeid = tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm ).. - tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy) + local nid = {} + for _, vec in ipairs(connections) do + -- flat component + if vec.x == 1 then nid[0] = "1" end + if vec.z == 1 then nid[1] = "1" end + if vec.x == -1 then nid[2] = "1" end + if vec.z == -1 then nid[3] = "1" end - if nodeid == "00000000" then - groups = {dig_immediate = 3, mesecon_conductor_craftable=1} - wiredesc = "Mesecon" + -- slopy component + if vec.y == 1 then + if vec.x == 1 then nid[4] = "1" end + if vec.z == 1 then nid[5] = "1" end + if vec.x == -1 then nid[6] = "1" end + if vec.z == -1 then nid[7] = "1" end + end + end + + local nodeid = (nid[0] or "0")..(nid[1] or "0")..(nid[2] or "0")..(nid[3] or "0") + ..(nid[4] or "0")..(nid[5] or "0")..(nid[6] or "0")..(nid[7] or "0") + + local state_suffix = string.find(minetest.get_node(pos).name, "_off") and "_off" or "_on" + minetest.set_node(pos, {name = "mesecons:wire_"..nodeid..state_suffix}) +end + +local update_on_place_dig = function (pos, node) + -- Update placed node (get_node again as it may have been dug) + local nn = minetest.get_node(pos) + if (minetest.registered_nodes[nn.name]) + and (minetest.registered_nodes[nn.name].mesecon_wire) then + wire_updateconnect(pos) + end + + -- Update nodes around it + local rules = {} + if minetest.registered_nodes[node.name] + and minetest.registered_nodes[node.name].mesecon_wire then + rules = mesecon.rules.default else - groups = {dig_immediate = 3, not_in_creative_inventory = 1} - wiredesc = "Mesecons Wire (ID: "..nodeid..")" + rules = mesecon.get_any_rules(node) + end + if (not rules) then return end + + for _, r in ipairs(mesecon.flattenrules(rules)) do + local np = mesecon.addPosRule(pos, r) + if minetest.registered_nodes[minetest.get_node(np).name] + and minetest.registered_nodes[minetest.get_node(np).name].mesecon_wire then + wire_updateconnect(np) + end + end +end + +function mesecon.update_autoconnect(pos, node) + if (not node) then node = minetest.get_node(pos) end + update_on_place_dig(pos, node) +end + +-- ############################ +-- ## Wire node registration ## +-- ############################ +-- Nodeboxes: +local box_center = {-1/16, -.5, -1/16, 1/16, -.5+1/16, 1/16} +local box_bump1 = { -2/16, -8/16, -2/16, 2/16, -13/32, 2/16 } + +local nbox_nid = +{ + [0] = {1/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}, -- x positive + [1] = {-1/16, -.5, 1/16, 1/16, -.5+1/16, 8/16}, -- z positive + [2] = {-8/16, -.5, -1/16, -1/16, -.5+1/16, 1/16}, -- x negative + [3] = {-1/16, -.5, -8/16, 1/16, -.5+1/16, -1/16}, -- z negative + + [4] = {.5-1/16, -.5+1/16, -1/16, .5, .4999+1/16, 1/16}, -- x positive up + [5] = {-1/16, -.5+1/16, .5-1/16, 1/16, .4999+1/16, .5}, -- z positive up + [6] = {-.5, -.5+1/16, -1/16, -.5+1/16, .4999+1/16, 1/16}, -- x negative up + [7] = {-1/16, -.5+1/16, -.5, 1/16, .4999+1/16, -.5+1/16} -- z negative up +} + +local tiles_off = { "mesecons_wire_off.png" } +local tiles_on = { "mesecons_wire_on.png" } + +local selectionbox = +{ + type = "fixed", + fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5} +} + +-- go to the next nodeid (ex.: 01000011 --> 01000100) +local nid_inc = function() end +nid_inc = function (nid) + local i = 0 + while nid[i-1] ~= 1 do + nid[i] = (nid[i] ~= 1) and 1 or 0 + i = i + 1 end - local nodebox = {} - local adjx = false - local adjz = false - if xp == 1 then table.insert(nodebox, box_xp) adjx = true end - if zp == 1 then table.insert(nodebox, box_zp) adjz = true end - if xm == 1 then table.insert(nodebox, box_xm) adjx = true end - if zm == 1 then table.insert(nodebox, box_zm) adjz = true end - if xpy == 1 then table.insert(nodebox, box_xpy) end - if zpy == 1 then table.insert(nodebox, box_zpy) end - if xmy == 1 then table.insert(nodebox, box_xmy) end - if zmy == 1 then table.insert(nodebox, box_zmy) end - - if adjx and adjz and (xp + zp + xm + zm > 2) then - table.insert(nodebox, box_bump1) - tiles_off = { - "wires_bump_off.png", - "wires_bump_off.png", - "wires_vertical_off.png", - "wires_vertical_off.png", - "wires_vertical_off.png", - "wires_vertical_off.png" - } - tiles_on = { - "wires_bump_on.png", - "wires_bump_on.png", - "wires_vertical_on.png", - "wires_vertical_on.png", - "wires_vertical_on.png", - "wires_vertical_on.png" - } - else - table.insert(nodebox, box_center) - tiles_off = { - "wires_off.png", - "wires_off.png", - "wires_vertical_off.png", - "wires_vertical_off.png", - "wires_vertical_off.png", - "wires_vertical_off.png" - } - tiles_on = { - "wires_on.png", - "wires_on.png", - "wires_vertical_on.png", - "wires_vertical_on.png", - "wires_vertical_on.png", - "wires_vertical_on.png" - } + -- BUT: Skip impossible nodeids: + if ((nid[0] == 0 and nid[4] == 1) or (nid[1] == 0 and nid[5] == 1) + or (nid[2] == 0 and nid[6] == 1) or (nid[3] == 0 and nid[7] == 1)) then + return nid_inc(nid) end - if nodeid == "00000000" then - nodebox = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16} - end + return i <= 8 +end - minetest.register_node("mesecons:wire_"..nodeid.."_off", { - description = wiredesc, - drawtype = "nodebox", - tiles = tiles_off, --- inventory_image = "wires_inv.png", --- wield_image = "wires_inv.png", - inventory_image = "jeija_mesecon_off.png", - wield_image = "jeija_mesecon_off.png", - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5} - }, - node_box = { - type = "fixed", - fixed = nodebox - }, - groups = groups, - walkable = false, - stack_max = 99, - drop = "mesecons:wire_00000000_off", - mesecons = {conductor={ +register_wires = function() + local nid = {} + while true do + -- Create group specifiction and nodeid string (see note above for details) + local nodeid = (nid[0] or "0")..(nid[1] or "0")..(nid[2] or "0")..(nid[3] or "0") + ..(nid[4] or "0")..(nid[5] or "0")..(nid[6] or "0")..(nid[7] or "0") + + -- Calculate nodebox + local nodebox = {type = "fixed", fixed={box_center}} + for i=0,7 do + if nid[i] == 1 then + table.insert(nodebox.fixed, nbox_nid[i]) + end + end + + -- Add bump to nodebox if curved + if (nid[0] == 1 and nid[1] == 1) or (nid[1] == 1 and nid[2] == 1) + or (nid[2] == 1 and nid[3] == 1) or (nid[3] == 1 and nid[0] == 1) then + table.insert(nodebox.fixed, box_bump1) + end + + -- If nothing to connect to, still make a nodebox of a straight wire + if nodeid == "00000000" then + nodebox.fixed = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16} + end + + local rules = {} + if (nid[0] == 1) then table.insert(rules, vector.new( 1, 0, 0)) end + if (nid[1] == 1) then table.insert(rules, vector.new( 0, 0, 1)) end + if (nid[2] == 1) then table.insert(rules, vector.new(-1, 0, 0)) end + if (nid[3] == 1) then table.insert(rules, vector.new( 0, 0, -1)) end + + if (nid[0] == 1) then table.insert(rules, vector.new( 1, -1, 0)) end + if (nid[1] == 1) then table.insert(rules, vector.new( 0, -1, 1)) end + if (nid[2] == 1) then table.insert(rules, vector.new(-1, -1, 0)) end + if (nid[3] == 1) then table.insert(rules, vector.new( 0, -1, -1)) end + + if (nid[4] == 1) then table.insert(rules, vector.new( 1, 1, 0)) end + if (nid[5] == 1) then table.insert(rules, vector.new( 0, 1, 1)) end + if (nid[6] == 1) then table.insert(rules, vector.new(-1, 1, 0)) end + if (nid[7] == 1) then table.insert(rules, vector.new( 0, 1, -1)) end + + local meseconspec_off = { conductor = { + rules = rules, state = mesecon.state.off, onstate = "mesecons:wire_"..nodeid.."_on" }} - }) - minetest.register_node("mesecons:wire_"..nodeid.."_on", { - description = "Wire ID:"..nodeid, - drawtype = "nodebox", - tiles = tiles_on, --- inventory_image = "wires_inv.png", --- wield_image = "wires_inv.png", - inventory_image = "jeija_mesecon_off.png", - wield_image = "jeija_mesecon_off.png", - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5} - }, - node_box = { - type = "fixed", - fixed = nodebox - }, - groups = {dig_immediate = 3, mesecon = 2, not_in_creative_inventory = 1}, - walkable = false, - stack_max = 99, - drop = "mesecons:wire_00000000_off", - mesecons = {conductor={ + local meseconspec_on = { conductor = { + rules = rules, state = mesecon.state.on, offstate = "mesecons:wire_"..nodeid.."_off" }} - }) -end -end -end -end -end -end -end -end --- Updating the wires: --- Place the right connection wire + local groups_on = {dig_immediate = 3, mesecon_conductor_craftable = 1, + not_in_creative_inventory = 1} + local groups_off = {dig_immediate = 3, mesecon_conductor_craftable = 1} + if nodeid ~= "00000000" then + groups_off["not_in_creative_inventory"] = 1 + end -local update_on_place_dig = function (pos, node) - if minetest.registered_nodes[node.name] - and minetest.registered_nodes[node.name].mesecons then - mesecon:update_autoconnect(pos) + mesecon.register_node("mesecons:wire_"..nodeid, { + description = "Mesecon", + drawtype = "nodebox", + inventory_image = "mesecons_wire_inv.png", + wield_image = "mesecons_wire_inv.png", + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + selection_box = selectionbox, + node_box = nodebox, + walkable = false, + drop = "mesecons:wire_00000000_off", + mesecon_wire = true + }, {tiles = tiles_off, mesecons = meseconspec_off, groups = groups_off}, + {tiles = tiles_on, mesecons = meseconspec_on, groups = groups_on}) + + if (nid_inc(nid) == false) then return end end end +register_wires() -minetest.register_on_placenode(update_on_place_dig) -minetest.register_on_dignode(update_on_place_dig) - -function mesecon:update_autoconnect(pos, secondcall, replace_old) - local xppos = {x=pos.x+1, y=pos.y, z=pos.z} - local zppos = {x=pos.x, y=pos.y, z=pos.z+1} - local xmpos = {x=pos.x-1, y=pos.y, z=pos.z} - local zmpos = {x=pos.x, y=pos.y, z=pos.z-1} - - local xpympos = {x=pos.x+1, y=pos.y-1, z=pos.z} - local zpympos = {x=pos.x, y=pos.y-1, z=pos.z+1} - local xmympos = {x=pos.x-1, y=pos.y-1, z=pos.z} - local zmympos = {x=pos.x, y=pos.y-1, z=pos.z-1} - - local xpypos = {x=pos.x+1, y=pos.y+1, z=pos.z} - local zpypos = {x=pos.x, y=pos.y+1, z=pos.z+1} - local xmypos = {x=pos.x-1, y=pos.y+1, z=pos.z} - local zmypos = {x=pos.x, y=pos.y+1, z=pos.z-1} - - if secondcall == nil then - mesecon:update_autoconnect(xppos, true) - mesecon:update_autoconnect(zppos, true) - mesecon:update_autoconnect(xmpos, true) - mesecon:update_autoconnect(zmpos, true) - - mesecon:update_autoconnect(xpypos, true) - mesecon:update_autoconnect(zpypos, true) - mesecon:update_autoconnect(xmypos, true) - mesecon:update_autoconnect(zmypos, true) - - mesecon:update_autoconnect(xpympos, true) - mesecon:update_autoconnect(zpympos, true) - mesecon:update_autoconnect(xmympos, true) - mesecon:update_autoconnect(zmympos, true) - end - - nodename = minetest.get_node(pos).name - if string.find(nodename, "mesecons:wire_") == nil and not replace_old then return nil end - - if mesecon:rules_link_anydir(pos, xppos) then xp = 1 else xp = 0 end - if mesecon:rules_link_anydir(pos, xmpos) then xm = 1 else xm = 0 end - if mesecon:rules_link_anydir(pos, zppos) then zp = 1 else zp = 0 end - if mesecon:rules_link_anydir(pos, zmpos) then zm = 1 else zm = 0 end - - if mesecon:rules_link_anydir(pos, xpympos) then xp = 1 end - if mesecon:rules_link_anydir(pos, xmympos) then xm = 1 end - if mesecon:rules_link_anydir(pos, zpympos) then zp = 1 end - if mesecon:rules_link_anydir(pos, zmympos) then zm = 1 end - - if mesecon:rules_link_anydir(pos, xpypos) then xpy = 1 else xpy = 0 end - if mesecon:rules_link_anydir(pos, zpypos) then zpy = 1 else zpy = 0 end - if mesecon:rules_link_anydir(pos, xmypos) then xmy = 1 else xmy = 0 end - if mesecon:rules_link_anydir(pos, zmypos) then zmy = 1 else zmy = 0 end - - if xpy == 1 then xp = 1 end - if zpy == 1 then zp = 1 end - if xmy == 1 then xm = 1 end - if zmy == 1 then zm = 1 end - - local nodeid = tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm ).. - tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy) - - - if string.find(nodename, "_off") ~= nil then - minetest.set_node(pos, {name = "mesecons:wire_"..nodeid.."_off"}) - else - minetest.set_node(pos, {name = "mesecons:wire_"..nodeid.."_on" }) - end -end - -if not minetest.registered_nodes["default:stone_with_mese"] then --before MESE update, use old recipes - minetest.register_craft({ - output = "mesecons:wire_00000000_off 18", - recipe = { - {"default:mese"}, - } - }) -else - - minetest.register_craft({ - type = "cooking", - output = "mesecons:wire_00000000_off 2", - recipe = "default:mese_crystal_fragment", - cooktime = 3, - }) - - minetest.register_craft({ - type = "cooking", - output = "mesecons:wire_00000000_off 18", - recipe = "default:mese_crystal", - cooktime = 15, - }) - - minetest.register_craft({ - type = "cooking", - output = "mesecons:wire_00000000_off 162", - recipe = "default:mese", - cooktime = 30, - }) - -end +-- ############## +-- ## Crafting ## +-- ############## +minetest.register_craft({ + type = "cooking", + output = "mesecons:wire_00000000_off 2", + recipe = "default:mese_crystal_fragment", + cooktime = 3, +}) minetest.register_craft({ type = "cooking", - output = "mesecons:wire_00000000_off 16", + output = "mesecons:wire_00000000_off 18", recipe = "default:mese_crystal", + cooktime = 15, +}) + +minetest.register_craft({ + type = "cooking", + output = "mesecons:wire_00000000_off 162", + recipe = "default:mese", + cooktime = 30, }) diff --git a/mods/mesecons/mesecons_blinkyplant/init.lua b/mods/mesecons/mesecons_blinkyplant/init.lua index f0ab81f9..c3bb3f74 100644 --- a/mods/mesecons/mesecons_blinkyplant/init.lua +++ b/mods/mesecons/mesecons_blinkyplant/init.lua @@ -1,98 +1,51 @@ -- The BLINKY_PLANT -minetest.register_node("mesecons_blinkyplant:blinky_plant", { - drawtype = "plantlike", - visual_scale = 1, - tiles = {"jeija_blinky_plant_off.png"}, - inventory_image = "jeija_blinky_plant_off.png", - walkable = false, - groups = {dig_immediate=3, not_in_creative_inventory=1}, - drop="mesecons_blinkyplant:blinky_plant_off 1", - description="Deactivated Blinky Plant", - sounds = default.node_sound_leaves_defaults(), - selection_box = { - type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3}, - }, - mesecons = {receptor = { - state = mesecon.state.off - }}, - on_rightclick = function(pos, node, clicker) - minetest.set_node(pos, {name="mesecons_blinkyplant:blinky_plant_off"}) - end -}) -minetest.register_node("mesecons_blinkyplant:blinky_plant_off", { - drawtype = "plantlike", - visual_scale = 1, - tiles = {"jeija_blinky_plant_off.png"}, - inventory_image = "jeija_blinky_plant_off.png", - paramtype = "light", - walkable = false, - groups = {dig_immediate=3, mesecon=2}, - description="Blinky Plant", - sounds = default.node_sound_leaves_defaults(), - selection_box = { - type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3}, - }, - mesecons = {receptor = { - state = mesecon.state.off - }}, - on_rightclick = function(pos, node, clicker) - minetest.set_node(pos, {name="mesecons_blinkyplant:blinky_plant"}) - end -}) - -minetest.register_node("mesecons_blinkyplant:blinky_plant_on", { - drawtype = "plantlike", - visual_scale = 1, - tiles = {"jeija_blinky_plant_on.png"}, - inventory_image = "jeija_blinky_plant_off.png", - paramtype = "light", - walkable = false, - groups = {dig_immediate=3, not_in_creative_inventory=1, mesecon=2}, - drop="mesecons_blinkyplant:blinky_plant_off 1", - light_source = LIGHT_MAX-7, - description = "Blinky Plant", - sounds = default.node_sound_leaves_defaults(), - selection_box = { - type = "fixed", - fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3}, - }, - mesecons = {receptor = { - state = mesecon.state.on - }}, - on_rightclick = function(pos, node, clicker) - minetest.set_node(pos, {name = "mesecons_blinkyplant:blinky_plant"}) - mesecon:receptor_off(pos) +local toggle_timer = function (pos) + local timer = minetest.get_node_timer(pos) + if timer:is_started() then + timer:stop() + else + timer:start(mesecon.setting("blinky_plant_interval", 3)) end +end + +local on_timer = function (pos) + local node = minetest.get_node(pos) + if(mesecon.flipstate(pos, node) == "on") then + mesecon.receptor_on(pos) + else + mesecon.receptor_off(pos) + end + toggle_timer(pos) +end + +mesecon.register_node("mesecons_blinkyplant:blinky_plant", { + description="Blinky Plant", + drawtype = "plantlike", + inventory_image = "jeija_blinky_plant_off.png", + paramtype = "light", + walkable = false, + sounds = default.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3}, + }, + on_timer = on_timer, + on_rightclick = toggle_timer, + on_construct = toggle_timer +},{ + tiles = {"jeija_blinky_plant_off.png"}, + groups = {dig_immediate=3}, + mesecons = {receptor = { state = mesecon.state.off }} +},{ + tiles = {"jeija_blinky_plant_on.png"}, + groups = {dig_immediate=3, not_in_creative_inventory=1}, + mesecons = {receptor = { state = mesecon.state.on }} }) minetest.register_craft({ output = "mesecons_blinkyplant:blinky_plant_off 1", - recipe = { - {"","group:mesecon_conductor_craftable",""}, - {"","group:mesecon_conductor_craftable",""}, - {"default:sapling","default:sapling","default:sapling"}, - } + recipe = { {"","group:mesecon_conductor_craftable",""}, + {"","group:mesecon_conductor_craftable",""}, + {"default:sapling","default:sapling","default:sapling"}} }) - -minetest.register_abm({ - nodenames = { - "mesecons_blinkyplant:blinky_plant_off", - "mesecons_blinkyplant:blinky_plant_on" - }, - interval = BLINKY_PLANT_INTERVAL, - chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - if node.name == "mesecons_blinkyplant:blinky_plant_off" then - minetest.add_node(pos, {name="mesecons_blinkyplant:blinky_plant_on"}) - mesecon:receptor_on(pos) - else - minetest.add_node(pos, {name="mesecons_blinkyplant:blinky_plant_off"}) - mesecon:receptor_off(pos) - end - nodeupdate(pos) - end, -}) - diff --git a/mods/mesecons/mesecons_button/init.lua b/mods/mesecons/mesecons_button/init.lua index f4a91984..f147d8f5 100644 --- a/mods/mesecons/mesecons_button/init.lua +++ b/mods/mesecons/mesecons_button/init.lua @@ -8,7 +8,7 @@ mesecon.button_turnoff = function (pos) minetest.swap_node(pos, {name = "mesecons_button:button_off", param2=node.param2}) minetest.sound_play("mesecons_button_pop", {pos=pos}) local rules = mesecon.rules.buttonlike_get(node) - mesecon:receptor_off(pos, rules) + mesecon.receptor_off(pos, rules) end end @@ -42,7 +42,7 @@ minetest.register_node("mesecons_button:button_off", { description = "Button", on_punch = function (pos, node) minetest.swap_node(pos, {name = "mesecons_button:button_on", param2=node.param2}) - mesecon:receptor_on(pos, mesecon.rules.buttonlike_get(node)) + mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node)) minetest.sound_play("mesecons_button_push", {pos=pos}) minetest.after(1, mesecon.button_turnoff, pos) end, diff --git a/mods/mesecons/mesecons_compatibility/init.lua b/mods/mesecons/mesecons_compatibility/init.lua index 5bdce27b..0ad04b2a 100644 --- a/mods/mesecons/mesecons_compatibility/init.lua +++ b/mods/mesecons/mesecons_compatibility/init.lua @@ -15,6 +15,17 @@ doors = {} -- selection_box_top -- only_placer_can_open: if true only the player who placed the door can -- open it +local function is_right(pos) + local r1 = minetest.get_node({x=pos.x-1, y=pos.y, z=pos.z}) + local r2 = minetest.get_node({x=pos.x, y=pos.y, z=pos.z-1}) + if string.find(r1.name, "door_") or string.find(r2.name, "door_") then + if string.find(r1.name, "_1") or string.find(r2.name, "_1") then + return true + else + return false + end + end +end function doors:register_door(name, def) def.groups.not_in_creative_inventory = 1 @@ -59,6 +70,19 @@ function doors:register_door(name, def) meta = minetest.get_meta(pos):to_table() minetest.set_node(pos, {name=replace, param2=p2}) minetest.get_meta(pos):from_table(meta) + + local snd_1 = "_close" + local snd_2 = "_open" + if params[1] == 3 then + snd_1 = "_open" + snd_2 = "_close" + end + + if is_right(pos) then + minetest.sound_play("door"..snd_1, {pos = pos, gain = 0.3, max_hear_distance = 10}) + else + minetest.sound_play("door"..snd_2, {pos = pos, gain = 0.3, max_hear_distance = 10}) + end end local function on_mesecons_signal_open (pos, node) diff --git a/mods/mesecons/mesecons_delayer/init.lua b/mods/mesecons/mesecons_delayer/init.lua index 239d3784..ba4067f8 100644 --- a/mods/mesecons/mesecons_delayer/init.lua +++ b/mods/mesecons/mesecons_delayer/init.lua @@ -2,7 +2,7 @@ local delayer_get_output_rules = function(node) local rules = {{x = 0, y = 0, z = 1}} for i = 0, node.param2 do - rules = mesecon:rotate_rules_left(rules) + rules = mesecon.rotate_rules_left(rules) end return rules end @@ -10,7 +10,7 @@ end local delayer_get_input_rules = function(node) local rules = {{x = 0, y = 0, z = -1}} for i = 0, node.param2 do - rules = mesecon:rotate_rules_left(rules) + rules = mesecon.rotate_rules_left(rules) end return rules end diff --git a/mods/mesecons/mesecons_detector/init.lua b/mods/mesecons/mesecons_detector/init.lua index 8d2f53c9..1a8595d4 100644 --- a/mods/mesecons/mesecons_detector/init.lua +++ b/mods/mesecons/mesecons_detector/init.lua @@ -23,7 +23,7 @@ end -- returns true if player was found, false if not local object_detector_scan = function (pos) - local objs = minetest.get_objects_inside_radius(pos, OBJECT_DETECTOR_RADIUS) + local objs = minetest.get_objects_inside_radius(pos, mesecon.setting("detector_radius", 6)) for k, obj in pairs(objs) do local isname = obj:get_player_name() -- "" is returned if it is not a player; "" ~= nil! local scanname = minetest.get_meta(pos):get_string("scanname") @@ -55,7 +55,8 @@ minetest.register_node("mesecons_detector:object_detector_off", { groups = {cracky=3}, description="Player Detector", mesecons = {receptor = { - state = mesecon.state.off + state = mesecon.state.off, + rules = mesecon.rules.pplate }}, on_construct = object_detector_make_formspec, on_receive_fields = object_detector_on_receive_fields, @@ -70,7 +71,8 @@ minetest.register_node("mesecons_detector:object_detector_on", { groups = {cracky=3,not_in_creative_inventory=1}, drop = 'mesecons_detector:object_detector_off', mesecons = {receptor = { - state = mesecon.state.on + state = mesecon.state.on, + rules = mesecon.rules.pplate }}, on_construct = object_detector_make_formspec, on_receive_fields = object_detector_on_receive_fields, @@ -94,7 +96,7 @@ minetest.register_abm( action = function(pos) if object_detector_scan(pos) then minetest.swap_node(pos, {name = "mesecons_detector:object_detector_on"}) - mesecon:receptor_on(pos) + mesecon.receptor_on(pos, mesecon.rules.pplate) end end, }) @@ -106,7 +108,7 @@ minetest.register_abm( action = function(pos) if not object_detector_scan(pos) then minetest.swap_node(pos, {name = "mesecons_detector:object_detector_off"}) - mesecon:receptor_off(pos) + mesecon.receptor_off(pos, mesecon.rules.pplate) end end, }) @@ -248,7 +250,7 @@ minetest.register_abm( action = function(pos, node) if node_detector_scan(pos) then minetest.swap_node(pos, {name = "mesecons_detector:node_detector_on", param2 = node.param2}) - mesecon:receptor_on(pos) + mesecon.receptor_on(pos) end end, }) @@ -260,7 +262,7 @@ minetest.register_abm( action = function(pos, node) if not node_detector_scan(pos) then minetest.swap_node(pos, {name = "mesecons_detector:node_detector_off", param2 = node.param2}) - mesecon:receptor_off(pos) + mesecon.receptor_off(pos) end end, }) diff --git a/mods/mesecons/mesecons_extrawires/corner.lua b/mods/mesecons/mesecons_extrawires/corner.lua index d7f7a029..003275a4 100644 --- a/mods/mesecons/mesecons_extrawires/corner.lua +++ b/mods/mesecons/mesecons_extrawires/corner.lua @@ -15,7 +15,7 @@ local corner_get_rules = function (node) {x = 0, y = 0, z = -1}} for i = 0, node.param2 do - rules = mesecon:rotate_rules_left(rules) + rules = mesecon.rotate_rules_left(rules) end return rules diff --git a/mods/mesecons/mesecons_extrawires/mesewire.lua b/mods/mesecons/mesecons_extrawires/mesewire.lua index cbb882ea..150178c1 100644 --- a/mods/mesecons/mesecons_extrawires/mesewire.lua +++ b/mods/mesecons/mesecons_extrawires/mesewire.lua @@ -8,12 +8,7 @@ local mesewire_rules = {x = 0, y = 0, z =-1}, } -minetest.register_node(":default:mese", { - description = "Mese Block", - tiles = {minetest.registered_nodes["default:mese"].tiles[1]}, - is_ground_content = true, - groups = {cracky=1}, - sounds = default.node_sound_stone_defaults(), +minetest.override_item("default:mese", { mesecons = {conductor = { state = mesecon.state.off, onstate = "mesecons_extrawires:mese_powered", diff --git a/mods/mesecons/mesecons_extrawires/tjunction.lua b/mods/mesecons/mesecons_extrawires/tjunction.lua index c5f36a21..680dc99a 100644 --- a/mods/mesecons/mesecons_extrawires/tjunction.lua +++ b/mods/mesecons/mesecons_extrawires/tjunction.lua @@ -16,7 +16,7 @@ local tjunction_get_rules = function (node) {x = 0, y = 0, z = -1}} for i = 0, node.param2 do - rules = mesecon:rotate_rules_left(rules) + rules = mesecon.rotate_rules_left(rules) end return rules diff --git a/mods/mesecons/mesecons_extrawires/vertical.lua b/mods/mesecons/mesecons_extrawires/vertical.lua index 16de55e1..cac2ae23 100644 --- a/mods/mesecons/mesecons_extrawires/vertical.lua +++ b/mods/mesecons/mesecons_extrawires/vertical.lua @@ -18,7 +18,7 @@ local bottom_box = { local vertical_rules = { {x=0, y=1, z=0}, - {x=0, y=-1, z=0}, + {x=0, y=-1, z=0} } local top_rules = { @@ -26,7 +26,7 @@ local top_rules = { {x=-1,y=0, z=0}, {x=0,y=0, z=1}, {x=0,y=0, z=-1}, - {x=0,y=-1, z=0}, + {x=0,y=-1, z=0} } local bottom_rules = { @@ -35,107 +35,79 @@ local bottom_rules = { {x=0, y=0, z=1}, {x=0, y=0, z=-1}, {x=0, y=1, z=0}, + {x=0, y=2, z=0} -- receive power from pressure plate / detector / ... 2 nodes above } local vertical_updatepos = function (pos) local node = minetest.get_node(pos) - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].is_vertical_conductor then - local node_above = minetest.get_node(mesecon:addPosRule(pos, vertical_rules[1])) - local node_below = minetest.get_node(mesecon:addPosRule(pos, vertical_rules[2])) + if minetest.registered_nodes[node.name] + and minetest.registered_nodes[node.name].is_vertical_conductor then + local node_above = minetest.get_node(mesecon.addPosRule(pos, vertical_rules[1])) + local node_below = minetest.get_node(mesecon.addPosRule(pos, vertical_rules[2])) local namestate = minetest.registered_nodes[node.name].vertical_conductor_state - local above = minetest.registered_nodes[node_above.name] and minetest.registered_nodes[node_above.name].is_vertical_conductor - local below = minetest.registered_nodes[node_below.name] and minetest.registered_nodes[node_below.name].is_vertical_conductor + local above = minetest.registered_nodes[node_above.name] + and minetest.registered_nodes[node_above.name].is_vertical_conductor + local below = minetest.registered_nodes[node_below.name] + and minetest.registered_nodes[node_below.name].is_vertical_conductor + local basename = "mesecons_extrawires:vertical_" if above and below then -- above and below: vertical mesecon - minetest.add_node(pos, {name = "mesecons_extrawires:vertical_" .. namestate}) + minetest.add_node(pos, {name = basename .. namestate}) elseif above and not below then -- above only: bottom - minetest.add_node(pos, {name = "mesecons_extrawires:vertical_bottom_" .. namestate}) + minetest.add_node(pos, {name = basename .. "bottom_" .. namestate}) elseif not above and below then -- below only: top - minetest.add_node(pos, {name = "mesecons_extrawires:vertical_top_" .. namestate}) - else -- no vertical wire above, no vertical wire below: use default wire - minetest.add_node(pos, {name = "mesecons_extrawires:vertical_" .. namestate}) + minetest.add_node(pos, {name = basename .. "top_" .. namestate}) + else -- no vertical wire above, no vertical wire below: use bottom + minetest.add_node(pos, {name = basename .. "bottom_" .. namestate}) end + mesecon.update_autoconnect(pos) end end local vertical_update = function (pos, node) vertical_updatepos(pos) -- this one - vertical_updatepos(mesecon:addPosRule(pos, vertical_rules[1])) -- above - vertical_updatepos(mesecon:addPosRule(pos, vertical_rules[2])) -- below + vertical_updatepos(mesecon.addPosRule(pos, vertical_rules[1])) -- above + vertical_updatepos(mesecon.addPosRule(pos, vertical_rules[2])) -- below end -- Vertical wire -minetest.register_node("mesecons_extrawires:vertical_on", { +mesecon.register_node("mesecons_extrawires:vertical", { description = "Vertical mesecon", drawtype = "nodebox", - tiles = {"wires_vertical_on.png"}, walkable = false, paramtype = "light", sunlight_propagates = true, - groups = {dig_immediate=3, not_in_creative_inventory=1}, selection_box = vertical_box, node_box = vertical_box, is_vertical_conductor = true, - vertical_conductor_state = "on", - mesecons = {conductor = { - state = mesecon.state.on, - offstate = "mesecons_extrawires:vertical_off", - rules = vertical_rules, - }}, drop = "mesecons_extrawires:vertical_off", after_place_node = vertical_update, - after_dig_node = vertical_update, -}) - -minetest.register_node("mesecons_extrawires:vertical_off", { - description = "Vertical mesecon", - drawtype = "nodebox", - tiles = {"wires_vertical_off.png"}, - walkable = false, - paramtype = "light", - sunlight_propagates = true, + after_dig_node = vertical_update +},{ + tiles = {"mesecons_wire_off.png"}, groups = {dig_immediate=3}, - selection_box = vertical_box, - node_box = vertical_box, - is_vertical_conductor = true, vertical_conductor_state = "off", mesecons = {conductor = { state = mesecon.state.off, onstate = "mesecons_extrawires:vertical_on", rules = vertical_rules, - }}, - after_place_node = vertical_update, - after_dig_node = vertical_update, -}) - --- Vertical wire top -minetest.register_node("mesecons_extrawires:vertical_top_on", { - description = "Vertical mesecon", - drawtype = "nodebox", - tiles = {"wires_full_on.png","wires_full_on.png","wires_vertical_on.png"}, - walkable = false, - paramtype = "light", - sunlight_propagates = true, + }} +},{ + tiles = {"mesecons_wire_on.png"}, groups = {dig_immediate=3, not_in_creative_inventory=1}, - selection_box = top_box, - node_box = top_box, - is_vertical_conductor = true, vertical_conductor_state = "on", mesecons = {conductor = { state = mesecon.state.on, - offstate = "mesecons_extrawires:vertical_top_off", - rules = top_rules, - }}, - drop = "mesecons_extrawires:vertical_off", - after_place_node = vertical_update, - after_dig_node = vertical_update, + offstate = "mesecons_extrawires:vertical_off", + rules = vertical_rules, + }} }) -minetest.register_node("mesecons_extrawires:vertical_top_off", { +-- Vertical wire top +mesecon.register_node("mesecons_extrawires:vertical_top", { description = "Vertical mesecon", drawtype = "nodebox", - tiles = {"wires_full_off.png","wires_full_off.png","wires_vertical_off.png"}, walkable = false, paramtype = "light", sunlight_propagates = true, @@ -143,43 +115,31 @@ minetest.register_node("mesecons_extrawires:vertical_top_off", { selection_box = top_box, node_box = top_box, is_vertical_conductor = true, + drop = "mesecons_extrawires:vertical_off", + after_place_node = vertical_update, + after_dig_node = vertical_update +},{ + tiles = {"mesecons_wire_off.png"}, vertical_conductor_state = "off", mesecons = {conductor = { state = mesecon.state.off, onstate = "mesecons_extrawires:vertical_top_on", rules = top_rules, - }}, - drop = "mesecons_extrawires:vertical_off", - after_place_node = vertical_update, - after_dig_node = vertical_update, + }} +},{ + tiles = {"mesecons_wire_on.png"}, + vertical_conductor_state = "on", + mesecons = {conductor = { + state = mesecon.state.on, + offstate = "mesecons_extrawires:vertical_top_off", + rules = top_rules, + }} }) -- Vertical wire bottom -minetest.register_node("mesecons_extrawires:vertical_bottom_on", { +mesecon.register_node("mesecons_extrawires:vertical_bottom", { description = "Vertical mesecon", drawtype = "nodebox", - tiles = {"wires_full_on.png","wires_full_on.png","wires_vertical_on.png"}, - walkable = false, - paramtype = "light", - sunlight_propagates = true, - vertical_conductor_state = "on", - groups = {dig_immediate = 3, not_in_creative_inventory = 1}, - selection_box = bottom_box, - node_box = bottom_box, - mesecons = {conductor = { - state = mesecon.state.on, - offstate = "mesecons_extrawires:vertical_bottom_off", - rules = bottom_rules, - }}, - drop = "mesecons_extrawires:vertical_off", - after_place_node = vertical_update, - after_dig_node = vertical_update, -}) - -minetest.register_node("mesecons_extrawires:vertical_bottom_off", { - description = "Vertical mesecon", - drawtype = "nodebox", - tiles = {"wires_full_off.png","wires_full_off.png","wires_vertical_off.png"}, walkable = false, paramtype = "light", sunlight_propagates = true, @@ -187,15 +147,25 @@ minetest.register_node("mesecons_extrawires:vertical_bottom_off", { selection_box = bottom_box, node_box = bottom_box, is_vertical_conductor = true, + drop = "mesecons_extrawires:vertical_off", + after_place_node = vertical_update, + after_dig_node = vertical_update +},{ + tiles = {"mesecons_wire_off.png"}, vertical_conductor_state = "off", mesecons = {conductor = { state = mesecon.state.off, onstate = "mesecons_extrawires:vertical_bottom_on", rules = bottom_rules, - }}, - drop = "mesecons_extrawires:vertical_off", - after_place_node = vertical_update, - after_dig_node = vertical_update, + }} +},{ + tiles = {"mesecons_wire_on.png"}, + vertical_conductor_state = "on", + mesecons = {conductor = { + state = mesecon.state.on, + offstate = "mesecons_extrawires:vertical_bottom_off", + rules = bottom_rules, + }} }) minetest.register_craft({ diff --git a/mods/mesecons/mesecons_gates/init.lua b/mods/mesecons/mesecons_gates/init.lua index a22edf68..2b6771ab 100644 --- a/mods/mesecons/mesecons_gates/init.lua +++ b/mods/mesecons/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) + 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 - -function gate_state(pos) - name = minetest.get_node(pos).name - return string.find(name, "_on") ~= nil -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") -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}} - -local onoff, drop, nodename, description, groups -for _, gate in ipairs(gates) do if gate.inputnumber == 1 then - get_rules = gate_get_input_rules_oneinput + set_gate(pos, node, gate.assess(newstate == "on")) 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 + local meta = minetest.get_meta(pos) + meta:set_int(link.name, newstate == "on" and 1 or 0) - 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 - } - } - }) + local val1 = meta:get_int("input1") == 1 + local val2 = meta:get_int("input2") == 1 + set_gate(pos, node, gate.assess(val1, val2)) end end -minetest.register_craft({ - output = 'mesecons_gates:diode_off', - recipe = { - {'', '', ''}, - {'mesecons:mesecon', 'mesecons_torch:mesecon_torch_on', 'mesecons_torch:mesecon_torch_on'}, - {'', '', ''}, - }, -}) +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 -minetest.register_craft({ - output = 'mesecons_gates:not_off', - recipe = { - {'', '', ''}, - {'mesecons:mesecon', 'mesecons_torch:mesecon_torch_on', 'mesecons:mesecon'}, - {'', '', ''}, - }, -}) + 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 = 'mesecons_gates:and_off', - recipe = { - {'mesecons:mesecon', '', ''}, - {'', 'mesecons_materials:silicon', 'mesecons:mesecon'}, - {'mesecons:mesecon', '', ''}, - }, -}) + minetest.register_craft({output = basename.."_off", recipe = recipe}) +end -minetest.register_craft({ - output = 'mesecons_gates:nand_off', - recipe = { - {'mesecons:mesecon', '', ''}, - {'', 'mesecons_materials:silicon', 'mesecons_torch:mesecon_torch_on'}, - {'mesecons:mesecon', '', ''}, - }, -}) +register_gate("diode", 1, function (input) return input end, + {{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons_torch:mesecon_torch_on"}}) -minetest.register_craft({ - output = 'mesecons_gates:xor_off', - recipe = { - {'mesecons:mesecon', '', ''}, - {'', 'mesecons_materials:silicon', 'mesecons_materials:silicon'}, - {'mesecons:mesecon', '', ''}, - }, -}) +register_gate("not", 1, function (input) return not input end, + {{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons:mesecon"}}) + +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", "", ""}}) + +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/mods/mesecons/mesecons_hydroturbine/init.lua b/mods/mesecons/mesecons_hydroturbine/init.lua index ef5ccae8..36bd4986 100644 --- a/mods/mesecons/mesecons_hydroturbine/init.lua +++ b/mods/mesecons/mesecons_hydroturbine/init.lua @@ -66,7 +66,7 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_off"}, if minetest.get_node(waterpos).name=="default:water_flowing" then minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"}) nodeupdate(pos) - mesecon:receptor_on(pos) + mesecon.receptor_on(pos) end end, }) @@ -80,7 +80,7 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_on"}, if minetest.get_node(waterpos).name~="default:water_flowing" then minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"}) nodeupdate(pos) - mesecon:receptor_off(pos) + mesecon.receptor_off(pos) end end, }) diff --git a/mods/mesecons/mesecons_insulated/init.lua b/mods/mesecons/mesecons_insulated/init.lua index 9fdf494e..c6fc05ee 100644 --- a/mods/mesecons/mesecons_insulated/init.lua +++ b/mods/mesecons/mesecons_insulated/init.lua @@ -2,7 +2,7 @@ function insulated_wire_get_rules(node) local rules = {{x = 1, y = 0, z = 0}, {x =-1, y = 0, z = 0}} if node.param2 == 1 or node.param2 == 3 then - return mesecon:rotate_rules_right(rules) + return mesecon.rotate_rules_right(rules) end return rules end @@ -41,7 +41,7 @@ minetest.register_node("mesecons_insulated:insulated_on", { minetest.register_node("mesecons_insulated:insulated_off", { drawtype = "nodebox", - description = "insulated mesecons", + description = "Insulated Mesecon", tiles = { "jeija_insulated_wire_sides_off.png", "jeija_insulated_wire_sides_off.png", @@ -78,7 +78,3 @@ minetest.register_craft({ {"mesecons_materials:fiber", "mesecons_materials:fiber", "mesecons_materials:fiber"}, } }) - -mesecon:add_rules("insulated", { -{x = 1, y = 0, z = 0}, -{x =-1, y = 0, z = 0}}) diff --git a/mods/mesecons/mesecons_lightstone/init.lua b/mods/mesecons/mesecons_lightstone/init.lua index 7bb550d1..5ed8f15b 100644 --- a/mods/mesecons/mesecons_lightstone/init.lua +++ b/mods/mesecons/mesecons_lightstone/init.lua @@ -14,7 +14,7 @@ local lightstone_rules = { {x=0, y=-1, z=0}, } -function mesecon:lightstone_add(name, base_item, texture_off, texture_on) +function mesecon.lightstone_add(name, base_item, texture_off, texture_on) minetest.register_node("mesecons_lightstone:lightstone_" .. name .. "_off", { tiles = {texture_off}, groups = {cracky=2, mesecon_effector_off = 1, mesecon = 2}, @@ -52,9 +52,9 @@ function mesecon:lightstone_add(name, base_item, texture_off, texture_on) end -mesecon:lightstone_add("red", "default:clay_brick", "jeija_lightstone_red_off.png", "jeija_lightstone_red_on.png") -mesecon:lightstone_add("green", "default:cactus", "jeija_lightstone_green_off.png", "jeija_lightstone_green_on.png") -mesecon:lightstone_add("blue", "mesecons_materials:fiber", "jeija_lightstone_blue_off.png", "jeija_lightstone_blue_on.png") -mesecon:lightstone_add("gray", "default:cobble", "jeija_lightstone_gray_off.png", "jeija_lightstone_gray_on.png") -mesecon:lightstone_add("darkgray", "default:gravel", "jeija_lightstone_darkgray_off.png", "jeija_lightstone_darkgray_on.png") -mesecon:lightstone_add("yellow", "default:mese_crystal_fragment", "jeija_lightstone_yellow_off.png", "jeija_lightstone_yellow_on.png") +mesecon.lightstone_add("red", "default:clay_brick", "jeija_lightstone_red_off.png", "jeija_lightstone_red_on.png") +mesecon.lightstone_add("green", "default:cactus", "jeija_lightstone_green_off.png", "jeija_lightstone_green_on.png") +mesecon.lightstone_add("blue", "mesecons_materials:fiber", "jeija_lightstone_blue_off.png", "jeija_lightstone_blue_on.png") +mesecon.lightstone_add("gray", "default:cobble", "jeija_lightstone_gray_off.png", "jeija_lightstone_gray_on.png") +mesecon.lightstone_add("darkgray", "default:gravel", "jeija_lightstone_darkgray_off.png", "jeija_lightstone_darkgray_on.png") +mesecon.lightstone_add("yellow", "default:mese_crystal_fragment", "jeija_lightstone_yellow_off.png", "jeija_lightstone_yellow_on.png") diff --git a/mods/mesecons/mesecons_luacontroller/init.lua b/mods/mesecons/mesecons_luacontroller/init.lua index f4869b51..4af91e7a 100644 --- a/mods/mesecons/mesecons_luacontroller/init.lua +++ b/mods/mesecons/mesecons_luacontroller/init.lua @@ -1,11 +1,21 @@ +-- ______ +-- | +-- | +-- | __ ___ _ __ _ _ +-- | | | | | |\ | | |_| | | | | |_ |_| +-- |___| |______ |__| | \| | | \ |__| |_ |_ |_ |\ +-- | +-- | +-- + -- Reference --- ports = get_real_portstates(pos): gets if inputs are powered from outside --- newport = merge_portstates(state1, state2): just does result = state1 or state2 for every port --- action_setports(pos, rule, state): activates/deactivates the mesecons according to the portstates (helper for action) --- action(pos, ports): Applies new portstates to a luacontroller at pos --- lc_update(pos): updates the controller at pos by executing the code --- reset_meta (pos, code, errmsg): performs a software-reset, installs new code and prints error messages --- reset (pos): performs a hardware reset, turns off all ports +-- ports = get_real_port_states(pos): gets if inputs are powered from outside +-- newport = merge_port_states(state1, state2): just does result = state1 or state2 for every port +-- set_port(pos, rule, state): activates/deactivates the mesecons according to the port states +-- set_port_states(pos, ports): Applies new port states to a LuaController at pos +-- run(pos): runs the code in the controller at pos +-- reset_meta(pos, code, errmsg): performs a software-reset, installs new code and prints error messages +-- resetn(pos): performs a hardware reset, turns off all ports -- -- The Sandbox -- The whole code of the controller runs in a sandbox, @@ -20,70 +30,76 @@ local BASENAME = "mesecons_luacontroller:luacontroller" -local rules = {} -rules.a = {x = -1, y = 0, z = 0, name="A"} -rules.b = {x = 0, y = 0, z = 1, name="B"} -rules.c = {x = 1, y = 0, z = 0, name="C"} -rules.d = {x = 0, y = 0, z = -1, name="D"} +local rules = { + a = {x = -1, y = 0, z = 0, name="A"}, + b = {x = 0, y = 0, z = 1, name="B"}, + c = {x = 1, y = 0, z = 0, name="C"}, + d = {x = 0, y = 0, z = -1, name="D"}, +} + ------------------ -- Action stuff -- ------------------ --- These helpers are required to set the portstates of the luacontroller +-- These helpers are required to set the port states of the luacontroller -function lc_update_real_portstates(pos, rulename, newstate) +local function update_real_port_states(pos, rule_name, new_state) local meta = minetest.get_meta(pos) - if rulename == nil then + if rule_name == nil then meta:set_int("real_portstates", 1) return end local n = meta:get_int("real_portstates") - 1 - if n < 0 then - legacy_update_ports(pos) - n = meta:get_int("real_portstates") - 1 - end local L = {} for i = 1, 4 do - L[i] = n%2 - n = math.floor(n/2) + L[i] = n % 2 + n = math.floor(n / 2) end - if rulename.x == nil then - for _, rname in ipairs(rulename) do - local port = ({4, 1, nil, 3, 2})[rname.x+2*rname.z+3] + -- (0,-1) (-1,0) (1,0) (0,1) + local pos_to_side = { 4, 1, nil, 3, 2 } + if rule_name.x == nil then + for _, rname in ipairs(rule_name) do + local port = pos_to_side[rname.x + (2 * rname.z) + 3] L[port] = (newstate == "on") and 1 or 0 end else - local port = ({4, 1, nil, 3, 2})[rulename.x+2*rulename.z+3] - L[port] = (newstate == "on") and 1 or 0 + local port = pos_to_side[rule_name.x + (2 * rule_name.z) + 3] + L[port] = (new_state == "on") and 1 or 0 end - meta:set_int("real_portstates", 1 + L[1] + 2*L[2] + 4*L[3] + 8*L[4]) + meta:set_int("real_portstates", + 1 + + 1 * L[1] + + 2 * L[2] + + 4 * L[3] + + 8 * L[4]) end -local get_real_portstates = function(pos) -- determine if ports are powered (by itself or from outside) + +local port_names = {"a", "b", "c", "d"} + +local function get_real_port_states(pos) + -- Determine if ports are powered (by itself or from outside) local meta = minetest.get_meta(pos) local L = {} local n = meta:get_int("real_portstates") - 1 - if n < 0 then - return legacy_update_ports(pos) - end - for _, index in ipairs({"a", "b", "c", "d"}) do - L[index] = ((n%2) == 1) - n = math.floor(n/2) + for _, name in ipairs(port_names) do + L[name] = ((n % 2) == 1) + n = math.floor(n / 2) end return L end -local merge_portstates = function (ports, vports) - local npo = {a=false, b=false, c=false, d=false} - npo.a = vports.a or ports.a - npo.b = vports.b or ports.b - npo.c = vports.c or ports.c - npo.d = vports.d or ports.d - return npo + +local function merge_port_states(ports, vports) + return { + a = ports.a or vports.a, + b = ports.b or vports.b, + c = ports.c or vports.c, + d = ports.d or vports.d, + } end -local generate_name = function (ports) - local overwrite = overwrite or {} +local function generate_name(ports) local d = ports.d and 1 or 0 local c = ports.c and 1 or 0 local b = ports.b and 1 or 0 @@ -91,101 +107,136 @@ local generate_name = function (ports) return BASENAME..d..c..b..a end -local setport = function (pos, rule, state) + +local function set_port(pos, rule, state) if state then - mesecon:receptor_on(pos, {rule}) + mesecon.receptor_on(pos, {rule}) else - mesecon:receptor_off(pos, {rule}) + mesecon.receptor_off(pos, {rule}) end end -local action = function (pos, ports) + +local function clean_port_states(ports) + ports.a = ports.a and true or false + ports.b = ports.b and true or false + ports.c = ports.c and true or false + ports.d = ports.d and true or false +end + + +local function set_port_states(pos, ports) local node = minetest.get_node(pos) local name = node.name + clean_port_states(ports) local vports = minetest.registered_nodes[name].virtual_portstates - local newname = generate_name(ports) + local new_name = generate_name(ports) - if name ~= newname and vports then - local rules_on = {} - local rules_off = {} + if name ~= new_name and vports then + -- Problem: + -- We need to place the new node first so that when turning + -- off some port, it won't stay on because the rules indicate + -- there is an onstate output port there. + -- When turning the output off then, it will however cause feedback + -- so that the luacontroller will receive an "off" event by turning + -- its output off. + -- Solution / Workaround: + -- Remember which output was turned off and ignore next "off" event. + local meta = minetest.get_meta(pos) + local ign = minetest.deserialize(meta:get_string("ignore_offevents")) or {} + if ports.a and not vports.a and not mesecon.is_powered(pos, rules.a) then ign.A = true end + if ports.b and not vports.b and not mesecon.is_powered(pos, rules.b) then ign.B = true end + if ports.c and not vports.c and not mesecon.is_powered(pos, rules.c) then ign.C = true end + if ports.d and not vports.d and not mesecon.is_powered(pos, rules.d) then ign.D = true end + meta:set_string("ignore_offevents", minetest.serialize(ign)) - minetest.swap_node(pos, {name = newname, param2 = node.param2}) + minetest.swap_node(pos, {name = new_name, param2 = node.param2}) - if ports.a ~= vports.a then setport(pos, rules.a, ports.a) end - if ports.b ~= vports.b then setport(pos, rules.b, ports.b) end - if ports.c ~= vports.c then setport(pos, rules.c, ports.c) end - if ports.d ~= vports.d then setport(pos, rules.d, ports.d) end + if ports.a ~= vports.a then set_port(pos, rules.a, ports.a) end + if ports.b ~= vports.b then set_port(pos, rules.b, ports.b) end + if ports.c ~= vports.c then set_port(pos, rules.c, ports.c) end + if ports.d ~= vports.d then set_port(pos, rules.d, ports.d) end end end --------------------- --- Overheat stuff -- --------------------- -local overheat_off = function(pos) - mesecon:receptor_off(pos, mesecon.rules.flat) +----------------- +-- Overheating -- +----------------- + +local function overheat_off(pos) + mesecon.receptor_off(pos, mesecon.rules.flat) end -------------------- --- Parsing stuff -- -------------------- -local code_prohibited = function(code) - -- Clean code - local prohibited = {"while", "for", "repeat", "until", "function", "goto"} - for _, p in ipairs(prohibited) do - if string.find(code, p) then - return "Prohibited command: "..p - end +local function overheat(pos, meta) + if mesecon.do_overheat(pos) then -- If too hot + local node = minetest.get_node(pos) + node.name = BASENAME.."_burnt" + minetest.swap_node(pos, node) + -- Wait for pending operations + minetest.after(0.2, overheat_off, pos) + return true end end -local safe_print = function(param) +------------------------ +-- Ignored off events -- +------------------------ + +local function ignore_event(event, meta) + if event.type ~= "off" then return false end + local ignore_offevents = minetest.deserialize(meta:get_string("ignore_offevents")) or {} + if ignore_offevents[event.pin.name] then + ignore_offevents[event.pin.name] = nil + meta:set_string("ignore_offevents", minetest.serialize(ignore_offevents)) + return true + end +end + +------------------------- +-- Parsing and running -- +------------------------- + +local function safe_print(param) print(dump(param)) end -deep_copy = function(original, visited) --deep copy that removes functions - visited = visited or {} - if visited[original] ~= nil then --already visited this node - return visited[original] - end - if type(original) == 'table' then --nested table - local copy = {} - visited[original] = copy - for key, value in next, original, nil do - copy[deep_copy(key, visited)] = deep_copy(value, visited) +local function remove_functions(x) + local tp = type(x) + if tp == "table" then + for key, value in pairs(x) do + local key_t, val_t = type(key), type(value) + if key_t == "function" or val_t == "function" then + x[key] = nil + else + if key_t == "table" then + remove_functions(key) + end + if val_t == "table" then + remove_functions(value) + end + end end - setmetatable(copy, deep_copy(getmetatable(original), visited)) - return copy - elseif type(original) == 'function' then --ignore functions + elseif tp == "function" then return nil - else --by-value type - return original end + return x end -local safe_serialize = function(value) - return minetest.serialize(deep_copy(value)) -end - -mesecon.queue:add_function("lc_interrupt", function (pos, iid, luac_id) - -- There is no luacontroller anymore / it has been reprogrammed / replaced - if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end - lc_update(pos, {type="interrupt", iid = iid}) -end) - -local getinterrupt = function(pos) - local interrupt = function (time, iid) -- iid = interrupt id +local function get_interrupt(pos) + -- iid = interrupt id + local function interrupt(time, iid) if type(time) ~= "number" then return end - luac_id = minetest.get_meta(pos):get_int("luac_id") - mesecon.queue:add_action(pos, "lc_interrupt", {iid, luac_id}, time, iid, 1) + local luac_id = minetest.get_meta(pos):get_int("luac_id") + mesecon.queue:add_action(pos, "lc_interrupt", {luac_id, iid}, time, iid, 1) end return interrupt end -local getdigiline_send = function(pos) + +local function get_digiline_send(pos) if not digiline then return end - -- Send messages on next serverstep return function(channel, msg) minetest.after(0, function() digiline:receptor_send(pos, digiline.rules.default, channel, msg) @@ -193,145 +244,187 @@ local getdigiline_send = function(pos) end end -local create_environment = function(pos, mem, event) + +local safe_globals = { + "assert", "error", "ipairs", "next", "pairs", "pcall", "select", + "tonumber", "tostring", "type", "unpack", "_VERSION", "xpcall", +} +local function create_environment(pos, mem, event) -- Gather variables for the environment local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates - vports = {a = vports.a, b = vports.b, c = vports.c, d = vports.d} - local rports = get_real_portstates(pos) + local vports_copy = {} + for k, v in pairs(vports) do vports_copy[k] = v end + local rports = get_real_port_states(pos) - return { - print = safe_print, - pin = merge_portstates(vports, rports), - port = vports, - interrupt = getinterrupt(pos), - digiline_send = getdigiline_send(pos), - mem = mem, - tostring = tostring, - tonumber = tonumber, - heat = minetest.get_meta(pos):get_int("heat"), - heat_max = OVERHEAT_MAX, - string = { - byte = string.byte, - char = string.char, - find = string.find, - format = string.format, - gmatch = string.gmatch, - gsub = string.gsub, - len = string.len, - lower = string.lower, - upper = string.upper, - match = string.match, - rep = string.rep, - reverse = string.reverse, - sub = string.sub, - }, - math = { - abs = math.abs, - acos = math.acos, - asin = math.asin, - atan = math.atan, - atan2 = math.atan2, - ceil = math.ceil, - cos = math.cos, - cosh = math.cosh, - deg = math.deg, - exp = math.exp, - floor = math.floor, - fmod = math.fmod, - frexp = math.frexp, - huge = math.huge, - ldexp = math.ldexp, - log = math.log, - log10 = math.log10, - max = math.max, - min = math.min, - modf = math.modf, - pi = math.pi, - pow = math.pow, - rad = math.rad, - random = math.random, - sin = math.sin, - sinh = math.sinh, - sqrt = math.sqrt, - tan = math.tan, - tanh = math.tanh, - }, - table = { - insert = table.insert, - maxn = table.maxn, - remove = table.remove, - sort = table.sort - }, - event = event, + -- Create new library tables on each call to prevent one LuaController + -- from breaking a library and messing up other LuaControllers. + local env = { + pin = merge_port_states(vports, rports), + port = vports_copy, + event = event, + mem = mem, + heat = minetest.get_meta(pos):get_int("heat"), + heat_max = mesecon.setting("overheat_max", 20), + print = safe_print, + interrupt = get_interrupt(pos), + digiline_send = get_digiline_send(pos), + string = { + byte = string.byte, + char = string.char, + format = string.format, + gsub = string.gsub, + len = string.len, + lower = string.lower, + upper = string.upper, + rep = string.rep, + reverse = string.reverse, + sub = string.sub, + }, + math = { + abs = math.abs, + acos = math.acos, + asin = math.asin, + atan = math.atan, + atan2 = math.atan2, + ceil = math.ceil, + cos = math.cos, + cosh = math.cosh, + deg = math.deg, + exp = math.exp, + floor = math.floor, + fmod = math.fmod, + frexp = math.frexp, + huge = math.huge, + ldexp = math.ldexp, + log = math.log, + log10 = math.log10, + max = math.max, + min = math.min, + modf = math.modf, + pi = math.pi, + pow = math.pow, + rad = math.rad, + random = math.random, + sin = math.sin, + sinh = math.sinh, + sqrt = math.sqrt, + tan = math.tan, + tanh = math.tanh, + }, + table = { + concat = table.concat, + insert = table.insert, + maxn = table.maxn, + remove = table.remove, + sort = table.sort, + }, + os = { + clock = os.clock, + difftime = os.difftime, + time = os.time, + }, } + env._G = env + + for _, name in pairs(safe_globals) do + env[name] = _G[name] + end + + return env end -local create_sandbox = function (code, env) - -- Create Sandbox + +local function timeout() + debug.sethook() -- Clear hook + error("Code timed out!") +end + + +local function code_prohibited(code) + -- LuaJIT doesn't increment the instruction counter when running + -- loops, so we have to sanitize inputs if we're using LuaJIT. + if not jit then + return false + end + local prohibited = {"while", "for", "do", "repeat", "until", "goto"} + code = " "..code.." " + for _, p in ipairs(prohibited) do + if string.find(code, "[^%w_]"..p.."[^%w_]") then + return "Prohibited command: "..p + end + end +end + + +local function create_sandbox(code, env) if code:byte(1) == 27 then - return _, "You Hacker You! Don't use binary code!" + return nil, "Binary code prohibited." end - f, msg = loadstring(code) - if not f then return _, msg end + local f, msg = loadstring(code) + if not f then return nil, msg end setfenv(f, env) - return f -end -local lc_overheat = function (pos, meta) - if mesecon.do_overheat(pos) then -- if too hot - local node = minetest.get_node(pos) - minetest.swap_node(pos, {name = BASENAME.."_burnt", param2 = node.param2}) - minetest.after(0.2, overheat_off, pos) -- wait for pending operations - return true + return function(...) + debug.sethook(timeout, "", 10000) + local ok, ret = pcall(f, ...) + debug.sethook() -- Clear hook + if not ok then error(ret) end + return ret end end -local load_memory = function(meta) + +local function load_memory(meta) return minetest.deserialize(meta:get_string("lc_memory")) or {} end -local save_memory = function(meta, mem) - meta:set_string("lc_memory", safe_serialize(mem)) + +local function save_memory(meta, mem) + meta:set_string("lc_memory", + minetest.serialize( + remove_functions(mem) + ) + ) end -local ports_invalid = function (var) - if type(var) == "table" then - return false - end - return "The ports you set are invalid" -end ----------------------- --- Parsing function -- ----------------------- - -lc_update = function (pos, event) +local function run(pos, event) local meta = minetest.get_meta(pos) - if lc_overheat(pos) then return end + if overheat(pos) then return end + if ignore_event(event, meta) then return end - -- load code & mem from memory + -- Load code & mem from meta local mem = load_memory(meta) local code = meta:get_string("code") - -- make sure code is ok and create environment - local prohibited = code_prohibited(code) - if prohibited then return prohibited end + local err = code_prohibited(code) + if err then return err end + + -- Create environment local env = create_environment(pos, mem, event) - -- create the sandbox and execute code - local chunk, msg = create_sandbox (code, env) - if not chunk then return msg end + -- Create the sandbox and execute code + local f, msg = create_sandbox(code, env) + if not f then return msg end local success, msg = pcall(f) if not success then return msg end - if ports_invalid(env.port) then return ports_invalid(env.port) end + if type(env.port) ~= "table" then + return "Ports set are invalid." + end - save_memory(meta, mem) + save_memory(meta, env.mem) -- Actually set the ports - action(pos, env.port) + set_port_states(pos, env.port) end -local reset_meta = function(pos, code, errmsg) +mesecon.queue:add_function("lc_interrupt", function (pos, luac_id, iid) + -- There is no luacontroller anymore / it has been reprogrammed / replaced + if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end + run(pos, {type="interrupt", iid = iid}) +end) + +local function reset_meta(pos, code, errmsg) local meta = minetest.get_meta(pos) meta:set_string("code", code) code = minetest.formspec_escape(code or "") @@ -343,172 +436,154 @@ local reset_meta = function(pos, code, errmsg) "image_button_exit[9.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]".. "label[0.1,5;"..errmsg.."]") meta:set_int("heat", 0) - meta:set_int("luac_id", math.random(1, 1000000)) + meta:set_int("luac_id", math.random(1, 65535)) end -local reset = function (pos) - action(pos, {a=false, b=false, c=false, d=false}) +local function reset(pos) + set_port_states(pos, {a=false, b=false, c=false, d=false}) end --- ______ --- | --- | --- | __ ___ _ __ _ _ --- | | | | | |\ | | |_| | | | | |_ |_| --- |___| |______ |__| | \| | | \ |__| |_ |_ |_ |\ --- | --- | --- ----------------------- -- Node Registration -- ----------------------- -local output_rules={} -local input_rules={} +local output_rules = {} +local input_rules = {} -local nodebox = { - type = "fixed", - fixed = { - { -8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }, -- bottom slab - { -5/16, -7/16, -5/16, 5/16, -6/16, 5/16 }, -- circuit board - { -3/16, -6/16, -3/16, 3/16, -5/16, 3/16 }, -- IC - } +local node_box = { + type = "fixed", + fixed = { + {-8/16, -8/16, -8/16, 8/16, -7/16, 8/16}, -- Bottom slab + {-5/16, -7/16, -5/16, 5/16, -6/16, 5/16}, -- Circuit board + {-3/16, -6/16, -3/16, 3/16, -5/16, 3/16}, -- IC } +} -local selectionbox = { - type = "fixed", - fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 }, - } +local selection_box = { + type = "fixed", + fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 }, +} local digiline = { receptor = {}, effector = { - action = function (pos, node, channel, msg) - lc_update (pos, {type = "digiline", channel = channel, msg = msg}) + action = function(pos, node, channel, msg) + run(pos, {type = "digiline", channel = channel, msg = msg}) end } } +local function on_receive_fields(pos, form_name, fields) + if not fields.program then + return + end + reset(pos) + reset_meta(pos, fields.code) + local err = run(pos, {type="program"}) + if err then + print(err) + reset_meta(pos, fields.code, err) + end +end -for a = 0, 1 do -- 0 = off; 1 = on +for a = 0, 1 do -- 0 = off 1 = on for b = 0, 1 do for c = 0, 1 do for d = 0, 1 do + local cid = tostring(d)..tostring(c)..tostring(b)..tostring(a) + local node_name = BASENAME..cid + local top = "jeija_luacontroller_top.png" + if a == 1 then + top = top.."^jeija_luacontroller_LED_A.png" + end + if b == 1 then + top = top.."^jeija_luacontroller_LED_B.png" + end + if c == 1 then + top = top.."^jeija_luacontroller_LED_C.png" + end + if d == 1 then + top = top.."^jeija_luacontroller_LED_D.png" + end -local cid = tostring(d)..tostring(c)..tostring(b)..tostring(a) -local nodename = BASENAME..cid -local top = "jeija_luacontroller_top.png" -if a == 1 then - top = top.."^jeija_luacontroller_LED_A.png" -end -if b == 1 then - top = top.."^jeija_luacontroller_LED_B.png" -end -if c == 1 then - top = top.."^jeija_luacontroller_LED_C.png" -end -if d == 1 then - top = top.."^jeija_luacontroller_LED_D.png" -end + local groups + if a + b + c + d ~= 0 then + groups = {dig_immediate=2, not_in_creative_inventory=1, overheat = 1} + else + groups = {dig_immediate=2, overheat = 1} + end -if a + b + c + d ~= 0 then - groups = {dig_immediate=2, not_in_creative_inventory=1, overheat = 1} -else - groups = {dig_immediate=2, overheat = 1} -end + output_rules[cid] = {} + input_rules[cid] = {} + if a == 1 then table.insert(output_rules[cid], rules.a) end + if b == 1 then table.insert(output_rules[cid], rules.b) end + if c == 1 then table.insert(output_rules[cid], rules.c) end + if d == 1 then table.insert(output_rules[cid], rules.d) end -output_rules[cid] = {} -input_rules[cid] = {} -if (a == 1) then table.insert(output_rules[cid], rules.a) end -if (b == 1) then table.insert(output_rules[cid], rules.b) end -if (c == 1) then table.insert(output_rules[cid], rules.c) end -if (d == 1) then table.insert(output_rules[cid], rules.d) end + if a == 0 then table.insert( input_rules[cid], rules.a) end + if b == 0 then table.insert( input_rules[cid], rules.b) end + if c == 0 then table.insert( input_rules[cid], rules.c) end + if d == 0 then table.insert( input_rules[cid], rules.d) end -if (a == 0) then table.insert(input_rules[cid], rules.a) end -if (b == 0) then table.insert(input_rules[cid], rules.b) end -if (c == 0) then table.insert(input_rules[cid], rules.c) end -if (d == 0) then table.insert(input_rules[cid], rules.d) end - -local mesecons = { - effector = - { - rules = input_rules[cid], - action_change = function (pos, _, rulename, newstate) - lc_update_real_portstates(pos, rulename, newstate) - lc_update(pos, {type=newstate, pin=rulename}) - end, - }, - receptor = - { - state = mesecon.state.on, - rules = output_rules[cid] - } -} - -minetest.register_node(nodename, { - description = "Luacontroller", - drawtype = "nodebox", - tiles = { - top, - "jeija_microcontroller_bottom.png", - "jeija_microcontroller_sides.png", - "jeija_microcontroller_sides.png", - "jeija_microcontroller_sides.png", - "jeija_microcontroller_sides.png" + local mesecons = { + effector = { + rules = input_rules[cid], + action_change = function (pos, _, rule_name, new_state) + update_real_port_states(pos, rule_name, new_state) + run(pos, {type=new_state, pin=rule_name}) + end, }, - - inventory_image = top, - paramtype = "light", - groups = groups, - drop = BASENAME.."0000", - sunlight_propagates = true, - selection_box = selectionbox, - node_box = nodebox, - on_construct = reset_meta, - on_receive_fields = function(pos, formname, fields) - if not fields.program then - return - end - reset(pos) - reset_meta(pos, fields.code) - local err = lc_update(pos, {type="program"}) - if err then - print(err) - reset_meta(pos, fields.code, err) - end - end, - on_timer = handle_timer, - sounds = default.node_sound_stone_defaults(), - mesecons = mesecons, - digiline = digiline, - virtual_portstates = { a = a == 1, -- virtual portstates are - b = b == 1, -- the ports the the - c = c == 1, -- controller powers itself - d = d == 1},-- so those that light up - after_dig_node = function (pos, node) - mesecon:receptor_off(pos, output_rules) - end, - is_luacontroller = true, -}) -end -end -end -end - ------------------------------- --- overheated luacontroller -- ------------------------------- - -local mesecons_burnt = { - effector = - { - rules = mesecon.rules.flat, - action_change = function (pos, _, rulename, newstate) - -- only update portstates when changes are triggered - lc_update_real_portstates(pos, rulename, newstate) - end + receptor = { + state = mesecon.state.on, + rules = output_rules[cid] + } } -} + + minetest.register_node(node_name, { + description = "LuaController", + drawtype = "nodebox", + tiles = { + top, + "jeija_microcontroller_bottom.png", + "jeija_microcontroller_sides.png", + "jeija_microcontroller_sides.png", + "jeija_microcontroller_sides.png", + "jeija_microcontroller_sides.png" + }, + inventory_image = top, + paramtype = "light", + groups = groups, + drop = BASENAME.."0000", + sunlight_propagates = true, + selection_box = selection_box, + node_box = node_box, + on_construct = reset_meta, + on_receive_fields = on_receive_fields, + on_timer = handle_timer, + sounds = default.node_sound_stone_defaults(), + mesecons = mesecons, + digiline = digiline, + -- Virtual portstates are the ports that + -- the node shows as powered up (light up). + virtual_portstates = { + a = a == 1, + b = b == 1, + c = c == 1, + d = d == 1, + }, + after_dig_node = function (pos, node) + mesecon.receptor_off(pos, output_rules) + end, + is_luacontroller = true, + }) +end +end +end +end + +------------------------------ +-- Overheated LuaController -- +------------------------------ minetest.register_node(BASENAME .. "_burnt", { drawtype = "nodebox", @@ -526,23 +601,19 @@ minetest.register_node(BASENAME .. "_burnt", { drop = BASENAME.."0000", sunlight_propagates = true, selection_box = selectionbox, - node_box = nodebox, + node_box = node_box, on_construct = reset_meta, - on_receive_fields = function(pos, formname, fields) - if fields.quit then - return - end - reset(pos) - reset_meta(pos, fields.code) - local err = lc_update(pos, {type="program"}) - if err then - print(err) - reset_meta(pos, fields.code, err) - end - end, + on_receive_fields = on_receive_fields, sounds = default.node_sound_stone_defaults(), virtual_portstates = {a = false, b = false, c = false, d = false}, - mesecons = mesecons_burnt, + mesecons = { + effector = { + rules = mesecon.rules.flat, + action_change = function(pos, _, rule_name, new_state) + update_real_port_states(pos, rule_name, new_state) + end, + }, + }, }) ------------------------ diff --git a/mods/mesecons/mesecons_microcontroller/init.lua b/mods/mesecons/mesecons_microcontroller/init.lua index 8c9f3b8c..7e290a36 100644 --- a/mods/mesecons/mesecons_microcontroller/init.lua +++ b/mods/mesecons/mesecons_microcontroller/init.lua @@ -1,5 +1,7 @@ EEPROM_SIZE = 255 +local microc_rules = {} + for a = 0, 1 do for b = 0, 1 do for c = 0, 1 do @@ -34,7 +36,7 @@ if (a == 0) then table.insert(input_rules, {x = -1, y = 0, z = 0, name = "A"}) if (b == 0) then table.insert(input_rules, {x = 0, y = 0, z = 1, name = "B"}) end if (c == 0) then table.insert(input_rules, {x = 1, y = 0, z = 0, name = "C"}) end if (d == 0) then table.insert(input_rules, {x = 0, y = 0, z = -1, name = "D"}) end -mesecon:add_rules(nodename, rules) +microc_rules[nodename] = rules local mesecons = {effector = { @@ -131,8 +133,8 @@ minetest.register_node(nodename, { sounds = default.node_sound_stone_defaults(), mesecons = mesecons, after_dig_node = function (pos, node) - rules = mesecon:get_rules(node.name) - mesecon:receptor_off(pos, rules) + rules = microc_rules[node.name] + mesecon.receptor_off(pos, rules) end, }) end @@ -164,7 +166,7 @@ function update_yc(pos) if (mesecon.do_overheat(pos)) then minetest.remove_node(pos) minetest.after(0.2, function (pos) - mesecon:receptor_off(pos, mesecon.rules.flat) + mesecon.receptor_off(pos, mesecon.rules.flat) end , pos) -- wait for pending parsings minetest.add_item(pos, "mesecons_microcontroller:microcontroller0000") end @@ -183,7 +185,7 @@ end --Code Parsing function yc_code_remove_commentary(code) - is_string = false + local is_string = false for i = 1, #code do if code:sub(i, i) == '"' then is_string = not is_string --toggle is_string @@ -203,15 +205,17 @@ function yc_parsecode(code, pos) local c local eeprom = meta:get_string("eeprom") while true do + local command, params command, endi = parse_get_command(code, endi) if command == nil then return nil end if command == true then break end --end of code if command == "if" then + local r r, endi = yc_command_if(code, endi, yc_merge_portstates(Lreal, Lvirtual), eeprom) if r == nil then return nil end if r == true then -- nothing elseif r == false then - endi_new = yc_skip_to_else (code, endi) + local endi_new = yc_skip_to_else (code, endi) if endi_new == nil then --else > not found endi = yc_skip_to_endif(code, endi) else @@ -221,7 +225,7 @@ function yc_parsecode(code, pos) end else params, endi = parse_get_params(code, endi) - if params == nil then return nil end + if not params then return nil end end if command == "on" then L = yc_command_on (params, Lvirtual) @@ -234,6 +238,7 @@ function yc_parsecode(code, pos) local su = yc_command_after(params, pos) if su == nil then return nil end elseif command == "sbi" then + local new_eeprom new_eeprom, Lvirtual = yc_command_sbi (params, eeprom, yc_merge_portstates(Lreal, Lvirtual), Lvirtual) if new_eeprom == nil then return nil else eeprom = new_eeprom end @@ -251,7 +256,7 @@ end function parse_get_command(code, starti) i = starti - s = nil + local s while s ~= "" do s = string.sub(code, i, i) if s == "(" then @@ -277,7 +282,7 @@ end function parse_get_params(code, starti) i = starti - s = nil + local s local params = {} local is_string = false while s ~= "" do @@ -300,7 +305,7 @@ end function yc_parse_get_eeprom_param(cond, starti) i = starti - s = nil + local s local addr while s ~= "" do s = string.sub(cond, i, i) @@ -403,7 +408,7 @@ function yc_command_sbi(params, eeprom, L, Lv) end --is an eeprom address - new_eeprom = ""; + local new_eeprom = ""; for i=1, #eeprom do if tonumber(params[1])==i then new_eeprom = new_eeprom..status @@ -457,17 +462,17 @@ function yc_command_if(code, starti, L, eeprom) cond = yc_command_parsecondition(cond, L, eeprom) + local result if cond == "0" then result = false - elseif cond == "1" then result = true - else result = nil end - if result == nil then end + elseif cond == "1" then result = true end + if not result then end return result, endi --endi from local cond, endi = yc_command_if_getcondition(code, starti) end --Condition parsing function yc_command_if_getcondition(code, starti) i = starti - s = nil + local s local brackets = 1 --1 Bracket to close while s ~= "" do s = string.sub(code, i, i) @@ -501,8 +506,8 @@ function yc_command_parsecondition(cond, L, eeprom) while i<=l do local s = cond:sub(i,i) if s == "#" then - addr, endi = yc_parse_get_eeprom_param(cond, i+1) - buf = yc_eeprom_read(tonumber(addr), eeprom) + local addr, endi = yc_parse_get_eeprom_param(cond, i+1) + local buf = yc_eeprom_read(tonumber(addr), eeprom) if buf == nil then return nil end local call = cond:sub(i, endi-1) cond = string.gsub(cond, call, buf) @@ -576,10 +581,8 @@ end --Virtual-Hardware functions function yc_eeprom_read(number, eeprom) - if number == nil then return nil, nil end - value = eeprom:sub(number, number) - if value == nil then return nil, nil end - return value, endi + if not number then return end + return eeprom:sub(number, number) end --Real I/O functions @@ -600,24 +603,24 @@ function yc_action_setports(pos, L, Lv) local name = "mesecons_microcontroller:microcontroller" local rules if Lv.a ~= L.a then - rules = mesecon:get_rules(name.."0001") - if L.a == true then mesecon:receptor_on(pos, rules) - else mesecon:receptor_off(pos, rules) end + rules = microc_rules[name.."0001"] + if L.a == true then mesecon.receptor_on(pos, rules) + else mesecon.receptor_off(pos, rules) end end if Lv.b ~= L.b then - rules = mesecon:get_rules(name.."0010") - if L.b == true then mesecon:receptor_on(pos, rules) - else mesecon:receptor_off(pos, rules) end + rules = microc_rules[name.."0010"] + if L.b == true then mesecon.receptor_on(pos, rules) + else mesecon.receptor_off(pos, rules) end end if Lv.c ~= L.c then - rules = mesecon:get_rules(name.."0100") - if L.c == true then mesecon:receptor_on(pos, rules) - else mesecon:receptor_off(pos, rules) end + rules = microc_rules[name.."0100"] + if L.c == true then mesecon.receptor_on(pos, rules) + else mesecon.receptor_off(pos, rules) end end if Lv.d ~= L.d then - rules = mesecon:get_rules(name.."1000") - if L.d == true then mesecon:receptor_on(pos, rules) - else mesecon:receptor_off(pos, rules) end + rules = microc_rules[name.."1000"] + if L.d == true then mesecon.receptor_on(pos, rules) + else mesecon.receptor_off(pos, rules) end end end @@ -637,10 +640,6 @@ function yc_update_real_portstates(pos, node, rulename, newstate) return end local n = meta:get_int("real_portstates") - 1 - if n < 0 then - legacy_update_ports(pos) - n = meta:get_int("real_portstates") - 1 - end local L = {} for i = 1, 4 do L[i] = n%2 @@ -662,9 +661,6 @@ function yc_get_real_portstates(pos) -- determine if ports are powered (by itsel local meta = minetest.get_meta(pos) local L = {} local n = meta:get_int("real_portstates") - 1 - if n < 0 then - return legacy_update_ports(pos) - end for _, index in ipairs({"a", "b", "c", "d"}) do L[index] = ((n%2) == 1) n = math.floor(n/2) @@ -673,12 +669,12 @@ function yc_get_real_portstates(pos) -- determine if ports are powered (by itsel end function yc_get_virtual_portstates(pos) -- portstates according to the name - name = minetest.get_node(pos).name - b, a = string.find(name, ":microcontroller") + local name = minetest.get_node(pos).name + local b, a = string.find(name, ":microcontroller") if a == nil then return nil end a = a + 1 - Lvirtual = {a=false, b=false, c=false, d=false} + local Lvirtual = {a=false, b=false, c=false, d=false} if name:sub(a , a ) == "1" then Lvirtual.d = true end if name:sub(a+1, a+1) == "1" then Lvirtual.c = true end if name:sub(a+2, a+2) == "1" then Lvirtual.b = true end diff --git a/mods/mesecons/mesecons_movestones/init.lua b/mods/mesecons/mesecons_movestones/init.lua index e31f2d27..7790658f 100644 --- a/mods/mesecons/mesecons_movestones/init.lua +++ b/mods/mesecons/mesecons_movestones/init.lua @@ -8,7 +8,7 @@ -- Pushes all block in front of it -- Pull all blocks in its back -function mesecon:get_movestone_direction(pos) +function mesecon.get_movestone_direction(pos) getactivated = 0 local lpos local getactivated = 0 @@ -28,28 +28,28 @@ function mesecon:get_movestone_direction(pos) lpos = {x=pos.x+1, y=pos.y, z=pos.z} for n = 1, 3 do - if mesecon:is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then + if mesecon.is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then return {x=0, y=0, z=-1} end end lpos = {x = pos.x-1, y = pos.y, z = pos.z} for n=4, 6 do - if mesecon:is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then + if mesecon.is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then return {x=0, y=0, z=1} end end lpos = {x = pos.x, y = pos.y, z = pos.z+1} for n=7, 9 do - if mesecon:is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then + if mesecon.is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then return {x=-1, y=0, z=0} end end lpos = {x = pos.x, y = pos.y, z = pos.z-1} for n=10, 12 do - if mesecon:is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then + if mesecon.is_power_on(lpos, rules[n].x, rules[n].y, rules[n].z) then return {x=1, y=0, z=0} end end @@ -64,10 +64,10 @@ minetest.register_node("mesecons_movestones:movestone", { sounds = default.node_sound_stone_defaults(), mesecons = {effector = { action_on = function (pos, node) - local direction=mesecon:get_movestone_direction(pos) + local direction=mesecon.get_movestone_direction(pos) if not direction then return end minetest.remove_node(pos) - mesecon:update_autoconnect(pos) + mesecon.on_dignode(pos, node) minetest.add_entity(pos, "mesecons_movestones:movestone_entity") end }} @@ -89,30 +89,35 @@ minetest.register_entity("mesecons_movestones:movestone_entity", { on_step = function(self, dtime) local pos = self.object:getpos() pos.x, pos.y, pos.z = math.floor(pos.x+0.5), math.floor(pos.y+0.5), math.floor(pos.z+0.5) - local direction = mesecon:get_movestone_direction(pos) + local direction = mesecon.get_movestone_direction(pos) + local maxpush = mesecon.setting("movestone_max_push", 50) if not direction then -- no mesecon power --push only solid nodes local name = minetest.get_node(pos).name if name ~= "air" and name ~= "ignore" and ((not minetest.registered_nodes[name]) or minetest.registered_nodes[name].liquidtype == "none") then - mesecon:mvps_push(pos, self.lastdir, MOVESTONE_MAXIMUM_PUSH) + mesecon.mvps_push(pos, self.lastdir, maxpush) end - minetest.add_node(pos, {name="mesecons_movestones:movestone"}) + local nn = {name="mesecons_movestones:movestone"} + minetest.add_node(pos, nn) self.object:remove() + mesecon.on_placenode(pos, nn) return end local success, stack, oldstack = - mesecon:mvps_push(pos, direction, MOVESTONE_MAXIMUM_PUSH) + mesecon.mvps_push(pos, direction, maxpush) if not success then -- Too large stack/stopper in the way - minetest.add_node(pos, {name="mesecons_movestones:movestone"}) + local nn = {name="mesecons_movestones:movestone"} + minetest.add_node(pos, nn) self.object:remove() + mesecon.on_placenode(pos, nn) return else - mesecon:mvps_process_stack (stack) - mesecon:mvps_move_objects (pos, direction, oldstack) + mesecon.mvps_process_stack (stack) + mesecon.mvps_move_objects (pos, direction, oldstack) self.lastdir = direction end @@ -143,10 +148,10 @@ minetest.register_node("mesecons_movestones:sticky_movestone", { sounds = default.node_sound_stone_defaults(), mesecons = {effector = { action_on = function (pos, node) - local direction=mesecon:get_movestone_direction(pos) + local direction=mesecon.get_movestone_direction(pos) if not direction then return end minetest.remove_node(pos) - mesecon:update_autoconnect(pos) + mesecon.on_dignode(pos, node) minetest.add_entity(pos, "mesecons_movestones:sticky_movestone_entity") end }} @@ -175,7 +180,7 @@ minetest.register_entity("mesecons_movestones:sticky_movestone_entity", { on_step = function(self, dtime) local pos = self.object:getpos() pos.x, pos.y, pos.z = math.floor(pos.x+0.5), math.floor(pos.y+0.5), math.floor(pos.z+0.5) - local direction = mesecon:get_movestone_direction(pos) + local direction = mesecon.get_movestone_direction(pos) if not direction then -- no mesecon power --push only solid nodes @@ -183,34 +188,39 @@ minetest.register_entity("mesecons_movestones:sticky_movestone_entity", { if name ~= "air" and name ~= "ignore" and ((not minetest.registered_nodes[name]) or minetest.registered_nodes[name].liquidtype == "none") then - mesecon:mvps_push(pos, self.lastdir, MOVESTONE_MAXIMUM_PUSH) + mesecon.mvps_push(pos, self.lastdir, + mesecon.setting("movestone_max_push", 50)) --STICKY - mesecon:mvps_pull_all(pos, self.lastdir) + mesecon.mvps_pull_all(pos, self.lastdir) end - minetest.add_node(pos, {name="mesecons_movestones:sticky_movestone"}) + local nn = {name="mesecons_movestones:sticky_movestone"} + minetest.add_node(pos, nn) self.object:remove() + mesecon.on_placenode(pos, nn) return end local success, stack, oldstack = - mesecon:mvps_push(pos, direction, MOVESTONE_MAXIMUM_PUSH) + mesecon.mvps_push(pos, direction, mesecon.setting("movestone_max_push", 50)) if not success then -- Too large stack/stopper in the way - minetest.add_node(pos, {name="mesecons_movestones:sticky_movestone"}) + local nn = {name="mesecons_movestones:sticky_movestone"} + minetest.add_node(pos, nn) self.object:remove() + mesecon.on_placenode(pos, nn) return else - mesecon:mvps_process_stack (stack) - mesecon:mvps_move_objects (pos, direction, oldstack) + mesecon.mvps_process_stack (stack) + mesecon.mvps_move_objects (pos, direction, oldstack) self.lastdir = direction end self.object:setvelocity({x=direction.x*2, y=direction.y*2, z=direction.z*2}) --STICKY - mesecon:mvps_pull_all(pos, direction) + mesecon.mvps_pull_all(pos, direction) end, }) -mesecon:register_mvps_unmov("mesecons_movestones:movestone_entity") -mesecon:register_mvps_unmov("mesecons_movestones:sticky_movestone_entity") +mesecon.register_mvps_unmov("mesecons_movestones:movestone_entity") +mesecon.register_mvps_unmov("mesecons_movestones:sticky_movestone_entity") diff --git a/mods/mesecons/mesecons_mvps/init.lua b/mods/mesecons/mesecons_mvps/init.lua index 0079f1aa..bcbda179 100644 --- a/mods/mesecons/mesecons_mvps/init.lua +++ b/mods/mesecons/mesecons_mvps/init.lua @@ -4,7 +4,7 @@ mesecon.mvps_stoppers = {} mesecon.mvps_unmov = {} mesecon.on_mvps_move = {} -function mesecon:is_mvps_stopper(node, pushdir, stack, stackid) +function mesecon.is_mvps_stopper(node, pushdir, stack, stackid) local get_stopper = mesecon.mvps_stoppers[node.name] if type (get_stopper) == "function" then get_stopper = get_stopper(node, pushdir, stack, stackid) @@ -12,7 +12,7 @@ function mesecon:is_mvps_stopper(node, pushdir, stack, stackid) return get_stopper end -function mesecon:register_mvps_stopper(nodename, get_stopper) +function mesecon.register_mvps_stopper(nodename, get_stopper) if get_stopper == nil then get_stopper = true end @@ -20,16 +20,16 @@ function mesecon:register_mvps_stopper(nodename, get_stopper) end -- Objects that cannot be moved (e.g. movestones) -function mesecon:register_mvps_unmov(objectname) +function mesecon.register_mvps_unmov(objectname) mesecon.mvps_unmov[objectname] = true; end -function mesecon:is_mvps_unmov(objectname) +function mesecon.is_mvps_unmov(objectname) return mesecon.mvps_unmov[objectname] end -- Functions to be called on mvps movement -function mesecon:register_on_mvps_move(callback) +function mesecon.register_on_mvps_move(callback) mesecon.on_mvps_move[#mesecon.on_mvps_move+1] = callback end @@ -39,16 +39,14 @@ local function on_mvps_move(moved_nodes) end end -function mesecon:mvps_process_stack(stack) +function mesecon.mvps_process_stack(stack) -- update mesecons for placed nodes ( has to be done after all nodes have been added ) for _, n in ipairs(stack) do - nodeupdate(n.pos) mesecon.on_placenode(n.pos, minetest.get_node(n.pos)) - mesecon:update_autoconnect(n.pos) end end -function mesecon:mvps_get_stack(pos, dir, maximum) +function mesecon.mvps_get_stack(pos, dir, maximum) -- determine the number of nodes to be pushed local np = {x = pos.x, y = pos.y, z = pos.z} local nodes = {} @@ -67,18 +65,18 @@ function mesecon:mvps_get_stack(pos, dir, maximum) table.insert (nodes, {node = nn, pos = np}) - np = mesecon:addPosRule(np, dir) + np = mesecon.addPosRule(np, dir) end return nodes end -function mesecon:mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: direction of push; maximum: maximum nodes to be pushed - local nodes = mesecon:mvps_get_stack(pos, dir, maximum) +function mesecon.mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: direction of push; maximum: maximum nodes to be pushed + local nodes = mesecon.mvps_get_stack(pos, dir, maximum) if not nodes then return end -- determine if one of the nodes blocks the push for id, n in ipairs(nodes) do - if mesecon:is_mvps_stopper(n.node, dir, nodes, id) then + if mesecon.is_mvps_stopper(n.node, dir, nodes, id) then return end end @@ -92,22 +90,21 @@ function mesecon:mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: directio -- update mesecons for removed nodes ( has to be done after all nodes have been removed ) for _, n in ipairs(nodes) do mesecon.on_dignode(n.pos, n.node) - mesecon:update_autoconnect(n.pos) end -- 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 local moved_nodes = {} - local oldstack = mesecon:tablecopy(nodes) + local oldstack = mesecon.tablecopy(nodes) for i in ipairs(nodes) do moved_nodes[i] = {} moved_nodes[i].oldpos = nodes[i].pos - nodes[i].pos = mesecon:addPosRule(nodes[i].pos, dir) + nodes[i].pos = mesecon.addPosRule(nodes[i].pos, dir) moved_nodes[i].pos = nodes[i].pos moved_nodes[i].node = nodes[i].node moved_nodes[i].meta = nodes[i].meta @@ -118,20 +115,20 @@ function mesecon:mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: directio return true, nodes, oldstack end -mesecon:register_on_mvps_move(function(moved_nodes) +mesecon.register_on_mvps_move(function(moved_nodes) for _, n in ipairs(moved_nodes) do mesecon.on_placenode(n.pos, n.node) - mesecon:update_autoconnect(n.pos) + mesecon.update_autoconnect(n.pos) end 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) +function mesecon.mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons) + 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 - and not mesecon:is_mvps_stopper(nn, {x = -dir.x, y = -dir.y, z = -dir.z}, {{pos = np, node = nn}}, 1) then --non-stopper node + and not mesecon.is_mvps_stopper(nn, {x = -dir.x, y = -dir.y, z = -dir.z}, {{pos = np, node = nn}}, 1) then --non-stopper node local meta = minetest.get_meta(np):to_table() minetest.remove_node(np) minetest.add_node(pos, nn) @@ -140,13 +137,13 @@ function mesecon:mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: dire nodeupdate(np) nodeupdate(pos) mesecon.on_dignode(np, nn) - mesecon:update_autoconnect(np) + mesecon.update_autoconnect(np) on_mvps_move({{pos = pos, oldpos = np, node = nn, meta = meta}}) end return {{pos = np, node = {param2 = 0, name = "air"}}, {pos = pos, node = nn}} end -function mesecon:mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: direction of pull +function mesecon.mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: direction of pull local lpos = {x=pos.x-direction.x, y=pos.y-direction.y, z=pos.z-direction.z} -- 1 away local lnode = minetest.get_node(lpos) local lpos2 = {x=pos.x-direction.x*2, y=pos.y-direction.y*2, z=pos.z-direction.z*2} -- 2 away @@ -188,15 +185,15 @@ function mesecon:mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: d and minetest.registered_nodes[lnode.name].liquidtype ~= "none") minetest.remove_node(oldpos) mesecon.on_dignode(oldpos, lnode2) - mesecon:update_autoconnect(oldpos) + mesecon.update_autoconnect(oldpos) on_mvps_move(moved_nodes) end -function mesecon:mvps_move_objects(pos, dir, nodestack) +function mesecon.mvps_move_objects(pos, dir, nodestack) local objects_to_move = {} -- Move object at tip of stack - local pushpos = mesecon:addPosRule(pos, -- get pos at tip of stack + local pushpos = mesecon.addPosRule(pos, -- get pos at tip of stack {x = dir.x * #nodestack, y = dir.y * #nodestack, z = dir.z * #nodestack}) @@ -211,7 +208,7 @@ function mesecon:mvps_move_objects(pos, dir, nodestack) if tonumber(minetest.setting_get("movement_gravity")) > 0 and dir.y == 0 then -- If gravity positive and dir horizontal, push players standing on the stack for _, n in ipairs(nodestack) do - local p_above = mesecon:addPosRule(n.pos, {x=0, y=1, z=0}) + local p_above = mesecon.addPosRule(n.pos, {x=0, y=1, z=0}) local objects = minetest.get_objects_inside_radius(p_above, 1) for _, obj in ipairs(objects) do table.insert(objects_to_move, obj) @@ -221,8 +218,8 @@ function mesecon:mvps_move_objects(pos, dir, nodestack) for _, obj in ipairs(objects_to_move) do local entity = obj:get_luaentity() - if not entity or not mesecon:is_mvps_unmov(entity.name) then - local np = mesecon:addPosRule(obj:getpos(), dir) + if not entity or not mesecon.is_mvps_unmov(entity.name) then + local np = mesecon.addPosRule(obj:getpos(), dir) --move only if destination is not solid local nn = minetest.get_node(np) @@ -234,5 +231,5 @@ function mesecon:mvps_move_objects(pos, dir, nodestack) end end -mesecon:register_mvps_stopper("default:chest_locked") -mesecon:register_mvps_stopper("default:furnace") +mesecon.register_mvps_stopper("default:chest_locked") +mesecon.register_mvps_stopper("default:furnace") diff --git a/mods/mesecons/mesecons_noteblock/init.lua b/mods/mesecons/mesecons_noteblock/init.lua index 39710760..d63b93ea 100644 --- a/mods/mesecons/mesecons_noteblock/init.lua +++ b/mods/mesecons/mesecons_noteblock/init.lua @@ -2,7 +2,6 @@ minetest.register_node("mesecons_noteblock:noteblock", { description = "Noteblock", tiles = {"mesecons_noteblock.png"}, groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, - drawtype = "allfaces_optional", visual_scale = 1.3, paramtype="light", after_place_node = function(pos) diff --git a/mods/mesecons/mesecons_pistons/init.lua b/mods/mesecons/mesecons_pistons/init.lua index 7780fc97..71e63e7d 100644 --- a/mods/mesecons/mesecons_pistons/init.lua +++ b/mods/mesecons/mesecons_pistons/init.lua @@ -33,7 +33,7 @@ local piston_down_rules = local piston_get_rules = function (node) local rules = piston_rules for i = 1, node.param2 do - rules = mesecon:rotate_rules_left(rules) + rules = mesecon.rotate_rules_left(rules) end return rules end @@ -41,7 +41,7 @@ end piston_facedir_direction = function (node) local rules = {{x = 0, y = 0, z = -1}} for i = 1, node.param2 do - rules = mesecon:rotate_rules_left(rules) + rules = mesecon.rotate_rules_left(rules) end return rules[1] end @@ -55,15 +55,16 @@ piston_get_direction = function(dir, node) end local piston_remove_pusher = function(pos, node) - pistonspec = minetest.registered_nodes[node.name].mesecons_piston - if pushername == pistonspec.pusher then --make sure there actually is a pusher (for compatibility reasons mainly) + 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 + + -- make sure there actually is a pusher (for compatibility reasons mainly) + if pushername ~= pistonspec.pusher then return end - dir = piston_get_direction(pistonspec.dir, node) - local pusherpos = mesecon:addPosRule(pos, dir) - local pushername = minetest.get_node(pusherpos).name - minetest.remove_node(pusherpos) minetest.sound_play("piston_retract", { pos = pos, @@ -77,8 +78,9 @@ local piston_on = function(pos, node) local pistonspec = minetest.registered_nodes[node.name].mesecons_piston local dir = piston_get_direction(pistonspec.dir, node) - local np = mesecon:addPosRule(pos, dir) - local success, stack, oldstack = mesecon:mvps_push(np, dir, PISTON_MAXIMUM_PUSH) + local np = mesecon.addPosRule(pos, dir) + local maxpush = mesecon.setting("piston_max_push", 15) + local success, stack, oldstack = mesecon.mvps_push(np, dir, maxpush) if success then minetest.add_node(pos, {param2 = node.param2, name = pistonspec.onname}) minetest.add_node(np, {param2 = node.param2, name = pistonspec.pusher}) @@ -87,8 +89,8 @@ local piston_on = function(pos, node) max_hear_distance = 20, gain = 0.3, }) - mesecon:mvps_process_stack (stack) - mesecon:mvps_move_objects (np, dir, oldstack) + mesecon.mvps_process_stack (stack) + mesecon.mvps_move_objects (np, dir, oldstack) end end @@ -98,10 +100,10 @@ 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) - mesecon:mvps_process_stack(pos, dir, stack) + 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 @@ -692,14 +694,14 @@ local piston_pusher_up_down_get_stopper = function (node, dir, stack, stackid) return true end -mesecon:register_mvps_stopper("mesecons_pistons:piston_pusher_normal", piston_pusher_get_stopper) -mesecon:register_mvps_stopper("mesecons_pistons:piston_pusher_sticky", piston_pusher_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_normal", piston_pusher_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_sticky", piston_pusher_get_stopper) -mesecon:register_mvps_stopper("mesecons_pistons:piston_up_pusher_normal", piston_pusher_up_down_get_stopper) -mesecon:register_mvps_stopper("mesecons_pistons:piston_up_pusher_sticky", piston_pusher_up_down_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_normal", piston_pusher_up_down_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_sticky", piston_pusher_up_down_get_stopper) -mesecon:register_mvps_stopper("mesecons_pistons:piston_down_pusher_normal", piston_pusher_up_down_get_stopper) -mesecon:register_mvps_stopper("mesecons_pistons:piston_down_pusher_sticky", piston_pusher_up_down_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_normal", piston_pusher_up_down_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_sticky", piston_pusher_up_down_get_stopper) -- Register pistons as stoppers if they would be seperated from the stopper @@ -716,12 +718,12 @@ end local piston_get_stopper = function (node, dir, stack, stackid) pistonspec = minetest.registered_nodes[node.name].mesecons_piston dir = piston_get_direction(pistonspec.dir, node) - local pusherpos = mesecon:addPosRule(stack[stackid].pos, dir) + local pusherpos = mesecon.addPosRule(stack[stackid].pos, dir) local pushernode = minetest.get_node(pusherpos) if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then for _, s in ipairs(stack) do - if mesecon:cmpPos(s.pos, pusherpos) -- pusher is also to be pushed + if mesecon.cmpPos(s.pos, pusherpos) -- pusher is also to be pushed and s.node.param2 == node.param2 then return false end @@ -730,14 +732,14 @@ local piston_get_stopper = function (node, dir, stack, stackid) return true end -mesecon:register_mvps_stopper("mesecons_pistons:piston_normal_on", piston_get_stopper) -mesecon:register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_normal_on", piston_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_get_stopper) -mesecon:register_mvps_stopper("mesecons_pistons:piston_up_normal_on", piston_up_down_get_stopper) -mesecon:register_mvps_stopper("mesecons_pistons:piston_up_sticky_on", piston_up_down_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_up_normal_on", piston_up_down_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_up_sticky_on", piston_up_down_get_stopper) -mesecon:register_mvps_stopper("mesecons_pistons:piston_down_normal_on", piston_up_down_get_stopper) -mesecon:register_mvps_stopper("mesecons_pistons:piston_down_sticky_on", piston_up_down_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_down_normal_on", piston_up_down_get_stopper) +mesecon.register_mvps_stopper("mesecons_pistons:piston_down_sticky_on", piston_up_down_get_stopper) --craft recipes minetest.register_craft({ diff --git a/mods/mesecons/mesecons_pressureplates/init.lua b/mods/mesecons/mesecons_pressureplates/init.lua index ec8d7893..d01e6e5a 100644 --- a/mods/mesecons/mesecons_pressureplates/init.lua +++ b/mods/mesecons/mesecons_pressureplates/init.lua @@ -9,31 +9,31 @@ local pp_box_on = { } pp_on_timer = function (pos, elapsed) - local node = minetest.get_node(pos) - local ppspec = minetest.registered_nodes[node.name].pressureplate + local node = minetest.get_node(pos) + local basename = minetest.registered_nodes[node.name].pressureplate_basename -- This is a workaround for a strange bug that occurs when the server is started -- For some reason the first time on_timer is called, the pos is wrong - if not ppspec then return end + if not basename then return end local objs = minetest.get_objects_inside_radius(pos, 1) - local two_below = mesecon:addPosRule(pos, {x = 0, y = -2, z = 0}) + local two_below = mesecon.addPosRule(pos, {x = 0, y = -2, z = 0}) - if objs[1] == nil and node.name == ppspec.onstate then - minetest.add_node(pos, {name = ppspec.offstate}) - mesecon:receptor_off(pos) + if objs[1] == nil and node.name == basename .. "_on" then + minetest.add_node(pos, {name = basename .. "_off"}) + mesecon.receptor_off(pos, mesecon.rules.pplate) -- force deactivation of mesecon two blocks below (hacky) - if not mesecon:connected_to_receptor(two_below) then - mesecon:turnoff(two_below) + if not mesecon.connected_to_receptor(two_below) then + mesecon.turnoff(two_below) end else for k, obj in pairs(objs) do local objpos = obj:getpos() if objpos.y > pos.y-1 and objpos.y < pos.y then - minetest.add_node(pos, {name=ppspec.onstate}) - mesecon:receptor_on(pos) + minetest.add_node(pos, {name = basename .. "_on"}) + mesecon.receptor_on(pos, mesecon.rules.pplate ) -- force activation of mesecon two blocks below (hacky) - mesecon:turnon(two_below) + mesecon.turnon(two_below) end end end @@ -49,66 +49,40 @@ end -- image: inventory and wield image of the pressure plate -- recipe: crafting recipe of the pressure plate -function mesecon:register_pressure_plate(offstate, onstate, description, textures_off, textures_on, image_w, image_i, recipe) - local ppspec = { - offstate = offstate, - onstate = onstate - } - - minetest.register_node(offstate, { +function mesecon.register_pressure_plate(basename, description, textures_off, textures_on, image_w, image_i, recipe) + mesecon.register_node(basename, { drawtype = "nodebox", - tiles = textures_off, inventory_image = image_i, wield_image = image_w, paramtype = "light", - selection_box = pp_box_off, - node_box = pp_box_off, - groups = {snappy = 2, oddly_breakable_by_hand = 3}, description = description, - pressureplate = ppspec, + pressureplate_basename = basename, on_timer = pp_on_timer, - mesecons = {receptor = { - state = mesecon.state.off - }}, on_construct = function(pos) - minetest.get_node_timer(pos):start(PRESSURE_PLATE_INTERVAL) + minetest.get_node_timer(pos):start(mesecon.setting("pplate_interval", 0.1)) end, - }) - - minetest.register_node(onstate, { - drawtype = "nodebox", - tiles = textures_on, - paramtype = "light", - selection_box = pp_box_on, + },{ + mesecons = {receptor = { state = mesecon.state.off, rules = mesecon.rules.pplate }}, + node_box = pp_box_off, + selection_box = pp_box_off, + groups = {snappy = 2, oddly_breakable_by_hand = 3}, + tiles = textures_off + },{ + mesecons = {receptor = { state = mesecon.state.on, rules = mesecon.rules.pplate }}, node_box = pp_box_on, + selection_box = pp_box_on, groups = {snappy = 2, oddly_breakable_by_hand = 3, not_in_creative_inventory = 1}, - drop = offstate, - pressureplate = ppspec, - on_timer = pp_on_timer, - sounds = default.node_sound_wood_defaults(), - mesecons = {receptor = { - state = mesecon.state.on - }}, - on_construct = function(pos) - minetest.get_node_timer(pos):start(PRESSURE_PLATE_INTERVAL) - end, - after_dig_node = function(pos) - local two_below = mesecon:addPosRule(pos, {x = 0, y = -2, z = 0}) - if not mesecon:connected_to_receptor(two_below) then - mesecon:turnoff(two_below) - end - end + tiles = textures_on }) minetest.register_craft({ - output = offstate, + output = basename .. "_off", recipe = recipe, }) end -mesecon:register_pressure_plate( - "mesecons_pressureplates:pressure_plate_wood_off", - "mesecons_pressureplates:pressure_plate_wood_on", +mesecon.register_pressure_plate( + "mesecons_pressureplates:pressure_plate_wood", "Wooden Pressure Plate", {"jeija_pressure_plate_wood_off.png","jeija_pressure_plate_wood_off.png","jeija_pressure_plate_wood_off_edges.png"}, {"jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on_edges.png"}, @@ -116,9 +90,8 @@ mesecon:register_pressure_plate( "jeija_pressure_plate_wood_inv.png", {{"group:wood", "group:wood"}}) -mesecon:register_pressure_plate( - "mesecons_pressureplates:pressure_plate_stone_off", - "mesecons_pressureplates:pressure_plate_stone_on", +mesecon.register_pressure_plate( + "mesecons_pressureplates:pressure_plate_stone", "Stone Pressure Plate", {"jeija_pressure_plate_stone_off.png","jeija_pressure_plate_stone_off.png","jeija_pressure_plate_stone_off_edges.png"}, {"jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on_edges.png"}, diff --git a/mods/mesecons/mesecons_random/init.lua b/mods/mesecons/mesecons_random/init.lua index 670bea40..01363092 100644 --- a/mods/mesecons/mesecons_random/init.lua +++ b/mods/mesecons/mesecons_random/init.lua @@ -9,7 +9,7 @@ minetest.register_node("mesecons_random:removestone", { mesecons = {effector = { action_on = function (pos, node) minetest.remove_node(pos) - mesecon:update_autoconnect(pos) + mesecon.update_autoconnect(pos) end }} }) diff --git a/mods/mesecons/mesecons_receiver/init.lua b/mods/mesecons/mesecons_receiver/init.lua index 3b1108ef..b06baa5d 100644 --- a/mods/mesecons/mesecons_receiver/init.lua +++ b/mods/mesecons/mesecons_receiver/init.lua @@ -9,11 +9,11 @@ local receiver_get_rules = function (node) local rules = { {x = 1, y = 0, z = 0}, {x = -2, y = 0, z = 0}} if node.param2 == 2 then - rules = mesecon:rotate_rules_left(rules) + rules = mesecon.rotate_rules_left(rules) elseif node.param2 == 3 then - rules = mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules)) + rules = mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules)) elseif node.param2 == 0 then - rules = mesecon:rotate_rules_right(rules) + rules = mesecon.rotate_rules_right(rules) end return rules end @@ -81,83 +81,76 @@ minetest.register_node("mesecons_receiver:receiver_off", { }} }) -mesecon:add_rules("receiver_pos", {{x = 2, y = 0, z = 0}}) - -mesecon:add_rules("receiver_pos_all", { -{x = 2, y = 0, z = 0}, -{x =-2, y = 0, z = 0}, -{x = 0, y = 0, z = 2}, -{x = 0, y = 0, z =-2}}) - -function mesecon:receiver_get_pos_from_rcpt(pos, param2) - local rules = mesecon:get_rules("receiver_pos") +function mesecon.receiver_get_pos_from_rcpt(pos, param2) + local rules = {{x = 2, y = 0, z = 0}} if param2 == nil then param2 = minetest.get_node(pos).param2 end if param2 == 2 then - rules = mesecon:rotate_rules_left(rules) + rules = mesecon.rotate_rules_left(rules) elseif param2 == 3 then - rules = mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules)) + rules = mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules)) elseif param2 == 0 then - rules = mesecon:rotate_rules_right(rules) + rules = mesecon.rotate_rules_right(rules) end - np = { - x = pos.x + rules[1].x, - y = pos.y + rules[1].y, - z = pos.z + rules[1].z} + local np = { x = pos.x + rules[1].x, + y = pos.y + rules[1].y, + z = pos.z + rules[1].z} return np end -function mesecon:receiver_place(rcpt_pos) +function mesecon.receiver_place(rcpt_pos) local node = minetest.get_node(rcpt_pos) - local pos = mesecon:receiver_get_pos_from_rcpt(rcpt_pos, node.param2) + local pos = mesecon.receiver_get_pos_from_rcpt(rcpt_pos, node.param2) local nn = minetest.get_node(pos) if string.find(nn.name, "mesecons:wire_") ~= nil then minetest.dig_node(pos) - if mesecon:is_power_on(rcpt_pos) then + if mesecon.is_power_on(rcpt_pos) then minetest.add_node(pos, {name = "mesecons_receiver:receiver_on", param2 = node.param2}) - mesecon:receptor_on(pos, receiver_get_rules(node)) + mesecon.receptor_on(pos, receiver_get_rules(node)) else minetest.add_node(pos, {name = "mesecons_receiver:receiver_off", param2 = node.param2}) end - mesecon:update_autoconnect(pos) + mesecon.update_autoconnect(pos) end end -function mesecon:receiver_remove(rcpt_pos, dugnode) - local pos = mesecon:receiver_get_pos_from_rcpt(rcpt_pos, dugnode.param2) +function mesecon.receiver_remove(rcpt_pos, dugnode) + local pos = mesecon.receiver_get_pos_from_rcpt(rcpt_pos, dugnode.param2) local nn = minetest.get_node(pos) if string.find(nn.name, "mesecons_receiver:receiver_") ~=nil then minetest.dig_node(pos) local node = {name = "mesecons:wire_00000000_off"} minetest.add_node(pos, node) - mesecon:update_autoconnect(pos) + mesecon.update_autoconnect(pos) mesecon.on_placenode(pos, node) end end minetest.register_on_placenode(function (pos, node) if minetest.get_item_group(node.name, "mesecon_needs_receiver") == 1 then - mesecon:receiver_place(pos) + mesecon.receiver_place(pos) end end) minetest.register_on_dignode(function(pos, node) if minetest.get_item_group(node.name, "mesecon_needs_receiver") == 1 then - mesecon:receiver_remove(pos, node) + mesecon.receiver_remove(pos, node) end end) minetest.register_on_placenode(function (pos, node) if string.find(node.name, "mesecons:wire_") ~=nil then - rules = mesecon:get_rules("receiver_pos_all") + local rules = { {x = 2, y = 0, z = 0}, + {x =-2, y = 0, z = 0}, + {x = 0, y = 0, z = 2}, + {x = 0, y = 0, z =-2}} local i = 1 while rules[i] ~= nil do - np = { - x = pos.x + rules[i].x, - y = pos.y + rules[i].y, - z = pos.z + rules[i].z} + local np = { x = pos.x + rules[i].x, + y = pos.y + rules[i].y, + z = pos.z + rules[i].z} if minetest.get_item_group(minetest.get_node(np).name, "mesecon_needs_receiver") == 1 then - mesecon:receiver_place(np) + mesecon.receiver_place(np) end i = i + 1 end diff --git a/mods/mesecons/mesecons_solarpanel/init.lua b/mods/mesecons/mesecons_solarpanel/init.lua index c30fe12c..bc5a408e 100644 --- a/mods/mesecons/mesecons_solarpanel/init.lua +++ b/mods/mesecons/mesecons_solarpanel/init.lua @@ -75,7 +75,7 @@ minetest.register_abm( if light >= 12 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2}) - mesecon:receptor_on(pos) + mesecon.receptor_on(pos) end end, }) @@ -89,7 +89,7 @@ minetest.register_abm( if light < 12 then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2}) - mesecon:receptor_off(pos) + mesecon.receptor_off(pos) end end, }) diff --git a/mods/mesecons/mesecons_switch/init.lua b/mods/mesecons/mesecons_switch/init.lua index 1b7f4788..2b3c3ee1 100644 --- a/mods/mesecons/mesecons_switch/init.lua +++ b/mods/mesecons/mesecons_switch/init.lua @@ -1,35 +1,29 @@ -- MESECON_SWITCH -minetest.register_node("mesecons_switch:mesecon_switch_off", { - tiles = {"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_off.png"}, +mesecon.register_node("mesecons_switch:mesecon_switch", { paramtype2="facedir", - groups = {dig_immediate=2}, description="Switch", sounds = default.node_sound_stone_defaults(), - mesecons = {receptor = { - state = mesecon.state.off - }}, - on_punch = function(pos, node) - minetest.swap_node(pos, {name = "mesecons_switch:mesecon_switch_on", param2 = node.param2}) - mesecon:receptor_on(pos) - minetest.sound_play("mesecons_switch", {pos=pos}) - end -}) - -minetest.register_node("mesecons_switch:mesecon_switch_on", { - tiles = {"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_on.png"}, - paramtype2="facedir", - groups = {dig_immediate=2,not_in_creative_inventory=1}, - drop="mesecons_switch:mesecon_switch_off 1", - sounds = default.node_sound_stone_defaults(), - mesecons = {receptor = { - state = mesecon.state.on - }}, - on_punch = function(pos, node) - minetest.swap_node(pos, {name = "mesecons_switch:mesecon_switch_off", param2 = node.param2}) - mesecon:receptor_off(pos) + on_punch = function (pos, node) + if(mesecon.flipstate(pos, node) == "on") then + mesecon.receptor_on(pos) + else + mesecon.receptor_off(pos) + end minetest.sound_play("mesecons_switch", {pos=pos}) end +},{ + groups = {dig_immediate=2}, + tiles = { "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", + "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", + "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_off.png"}, + mesecons = {receptor = { state = mesecon.state.off }} +},{ + groups = {dig_immediate=2, not_in_creative_inventory=1}, + tiles = { "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", + "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", + "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_on.png"}, + mesecons = {receptor = { state = mesecon.state.on }} }) minetest.register_craft({ diff --git a/mods/mesecons/mesecons_torch/init.lua b/mods/mesecons/mesecons_torch/init.lua index 97a29910..91f8e65b 100644 --- a/mods/mesecons/mesecons_torch/init.lua +++ b/mods/mesecons/mesecons_torch/init.lua @@ -2,15 +2,15 @@ local rotate_torch_rules = function (rules, param2) if param2 == 5 then - return mesecon:rotate_rules_right(rules) + return mesecon.rotate_rules_right(rules) elseif param2 == 2 then - return mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules)) --180 degrees + return mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules)) --180 degrees elseif param2 == 4 then - return mesecon:rotate_rules_left(rules) + return mesecon.rotate_rules_left(rules) elseif param2 == 1 then - return mesecon:rotate_rules_down(rules) + return mesecon.rotate_rules_down(rules) elseif param2 == 0 then - return mesecon:rotate_rules_up(rules) + return mesecon.rotate_rules_up(rules) else return rules end @@ -91,8 +91,8 @@ minetest.register_abm({ action = function(pos, node) local is_powered = false for _, rule in ipairs(torch_get_input_rules(node)) do - local src = mesecon:addPosRule(pos, rule) - if mesecon:is_power_on(src) then + local src = mesecon.addPosRule(pos, rule) + if mesecon.is_power_on(src) then is_powered = true end end @@ -100,11 +100,11 @@ minetest.register_abm({ if is_powered then if node.name == "mesecons_torch:mesecon_torch_on" then minetest.swap_node(pos, {name = "mesecons_torch:mesecon_torch_off", param2 = node.param2}) - mesecon:receptor_off(pos, torch_get_output_rules(node)) + mesecon.receptor_off(pos, torch_get_output_rules(node)) end elseif node.name == "mesecons_torch:mesecon_torch_off" then minetest.swap_node(pos, {name = "mesecons_torch:mesecon_torch_on", param2 = node.param2}) - mesecon:receptor_on(pos, torch_get_output_rules(node)) + mesecon.receptor_on(pos, torch_get_output_rules(node)) end end }) diff --git a/mods/mesecons/mesecons_walllever/init.lua b/mods/mesecons/mesecons_walllever/init.lua index a35d9f17..bd71871b 100644 --- a/mods/mesecons/mesecons_walllever/init.lua +++ b/mods/mesecons/mesecons_walllever/init.lua @@ -1,16 +1,9 @@ -- WALL LEVER -- Basically a switch that can be attached to a wall -- Powers the block 2 nodes behind (using a receiver) -minetest.register_node("mesecons_walllever:wall_lever_off", { +mesecon.register_node("mesecons_walllever:wall_lever", { + description="Lever", drawtype = "nodebox", - tiles = { - "jeija_wall_lever_tb.png", - "jeija_wall_lever_bottom.png", - "jeija_wall_lever_sides.png", - "jeija_wall_lever_sides.png", - "jeija_wall_lever_back.png", - "jeija_wall_lever_off.png", - }, inventory_image = "jeija_wall_lever_off.png", wield_image = "jeija_wall_lever_off.png", paramtype = "light", @@ -21,29 +14,34 @@ minetest.register_node("mesecons_walllever:wall_lever_off", { type = "fixed", fixed = { -8/16, -8/16, 3/16, 8/16, 8/16, 8/16 }, }, + sounds = default.node_sound_wood_defaults(), + on_punch = function (pos, node) + if(mesecon.flipstate(pos, node) == "on") then + mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node)) + else + mesecon.receptor_off(pos, mesecon.rules.buttonlike_get(node)) + end + minetest.sound_play("mesecons_lever", {pos=pos}) + end +},{ + tiles = { "jeija_wall_lever_tb.png", "jeija_wall_lever_bottom.png", + "jeija_wall_lever_sides.png", "jeija_wall_lever_sides.png", + "jeija_wall_lever_back.png", "jeija_wall_lever_off.png", + }, node_box = { type = "fixed", fixed = {{ -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, -- the base "slab" { -5/16, -3/16, 5/16, 5/16, 3/16, 6/16 }, -- the lighted ring area - { -4/16, -2/16, 4/16, 4/16, 2/16, 5/16 }, -- the raised bit that the lever "sits" on + { -4/16, -2/16, 4/16, 4/16, 2/16, 5/16 }, -- the raised bit { -2/16, -1/16, 3/16, 2/16, 1/16, 4/16 }, -- the lever "hinge" { -1/16, -8/16, 4/16, 1/16, 0, 6/16 }} -- the lever itself. }, - groups = {dig_immediate=2, mesecon_needs_receiver = 1}, - description="Lever", - on_punch = function (pos, node) - minetest.swap_node(pos, {name = "mesecons_walllever:wall_lever_on", param2 = node.param2}) - mesecon:receptor_on(pos, mesecon.rules.buttonlike_get(node)) - minetest.sound_play("mesecons_lever", {pos=pos}) - end, - sounds = default.node_sound_wood_defaults(), mesecons = {receptor = { rules = mesecon.rules.buttonlike_get, state = mesecon.state.off - }} -}) -minetest.register_node("mesecons_walllever:wall_lever_on", { - drawtype = "nodebox", + }}, + groups = {dig_immediate = 2, mesecon_needs_receiver = 1} +},{ tiles = { "jeija_wall_lever_top.png", "jeija_wall_lever_tb.png", @@ -52,37 +50,19 @@ minetest.register_node("mesecons_walllever:wall_lever_on", { "jeija_wall_lever_back.png", "jeija_wall_lever_on.png", }, - inventory_image = "jeija_wall_lever_on.png", - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - walkable = false, - light_source = LIGHT_MAX-7, - selection_box = { - type = "fixed", - fixed = { -8/16, -8/16, 3/16, 8/16, 8/16, 8/16 }, - }, node_box = { type = "fixed", fixed = {{ -6/16, -6/16, 6/16, 6/16, 6/16, 8/16 }, -- the base "slab" { -5/16, -3/16, 5/16, 5/16, 3/16, 6/16 }, -- the lighted ring area - { -4/16, -2/16, 4/16, 4/16, 2/16, 5/16 }, -- the raised bit that the lever "sits" on + { -4/16, -2/16, 4/16, 4/16, 2/16, 5/16 }, -- the raised bit { -2/16, -1/16, 3/16, 2/16, 1/16, 4/16 }, -- the lever "hinge" { -1/16, 0, 4/16, 1/16, 8/16, 6/16 }} -- the lever itself. }, - groups = {dig_immediate = 2, not_in_creative_inventory = 1, mesecon_needs_receiver = 1}, - drop = "mesecons_walllever:wall_lever_off 1", - description="Lever", - on_punch = function (pos, node) - minetest.swap_node(pos, {name = "mesecons_walllever:wall_lever_off", param2 = node.param2}) - mesecon:receptor_off(pos, mesecon.rules.buttonlike_get(node)) - minetest.sound_play("mesecons_lever", {pos=pos}) - end, - sounds = default.node_sound_wood_defaults(), mesecons = {receptor = { rules = mesecon.rules.buttonlike_get, state = mesecon.state.on - }} + }}, + groups = {dig_immediate = 2, mesecon_needs_receiver = 1, not_in_creative_inventory = 1} }) minetest.register_craft({