1 Commits

Author SHA1 Message Date
77b8f6514a Better mesecon-enabled doors
The mesecons_compatibility doors erred in making steel doors, which
are meant to be locked, openable by anyone using a mesecon signal.
They also didn't handle mirror-paired doors, and nastily duplicated
lots of the standard door code rather than using it and adding to it.
Replace mesecons_compatibility with a new system, in which standard
doors are left alone and new types of door are added that have mesecon
behaviour.  The new door types are each available in both wood and steel,
using the standard door textures.

The mesecon-operated doors open and close according to the mesecon
signal they receive: open when the signal is on and closed when off.
Unlike the old mesecons_compatibility doors, which only accepted the
signal to the bottom half, these accept the signal to either half of
the door.  A convenient kind of control therefore is a wall-mounted
button just above the doorway: the signal flows diagonally down to the
top half of the door.  The door cannot be operated manually.

The mesecon-signalling doors are opened and closed manually, and generate
a mesecon signal indicating whether they're open, on when open and off
when closed.  Thus opening the door can trigger automatic activity.
Pairing a mesecon-signalling door with a mesecon-operated door results
in a door pair where right-clicking on one door operates both.

By making use of the pairing behaviour built into the standard doors mod,
which is inherited by the mesecon doors, and placing doors from sideways
angles, it is possible to effectively get mesecon doors with the opposite
signal sense.  For example, a mesecon-signalling door that sends an on
signal when closed, turning the signal off when opened.
2014-05-04 16:47:47 +02:00
90 changed files with 2014 additions and 2808 deletions

View File

@ -12,19 +12,19 @@ function mesecon.queue:add_action(pos, func, params, time, overwritecheck, prior
-- Create Action Table: -- Create Action Table:
time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution
priority = priority or 1 priority = priority or 1
local action = { pos=mesecon.tablecopy(pos), local action = { pos=mesecon:tablecopy(pos),
func=func, func=func,
params=mesecon.tablecopy(params or {}), params=mesecon:tablecopy(params),
time=time, time=time,
owcheck=(overwritecheck and mesecon.tablecopy(overwritecheck)) or nil, owcheck=(overwritecheck and mesecon:tablecopy(overwritecheck)) or nil,
priority=priority} priority=priority}
local toremove = nil local toremove = nil
-- Otherwise, add the action to the queue -- Otherwise, add the action to the queue
if overwritecheck then -- check if old action has to be overwritten / removed: if overwritecheck then -- check if old action has to be overwritten / removed:
for i, ac in ipairs(mesecon.queue.actions) do for i, ac in ipairs(mesecon.queue.actions) do
if(mesecon.cmpPos(pos, ac.pos) if(mesecon:cmpPos(pos, ac.pos)
and mesecon.cmpAny(overwritecheck, ac.owcheck)) then and mesecon:cmpAny(overwritecheck, ac.owcheck)) then
toremove = i toremove = i
break break
end end
@ -44,8 +44,7 @@ end
-- However, even that does not work in some cases, that's why we delay the time the globalsteps -- 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 -- start to be execute by 5 seconds
local get_highest_priority = function (actions) local get_highest_priority = function (actions)
local highestp = -1 local highestp = -1, highesti
local highesti
for i, ac in ipairs(actions) do for i, ac in ipairs(actions) do
if ac.priority > highestp then if ac.priority > highestp then
highestp = ac.priority highestp = ac.priority
@ -57,13 +56,10 @@ local get_highest_priority = function (actions)
end end
local m_time = 0 local m_time = 0
local resumetime = mesecon.setting("resumetime", 4)
minetest.register_globalstep(function (dtime) minetest.register_globalstep(function (dtime)
m_time = m_time + dtime m_time = m_time + dtime
-- don't even try if server has not been running for XY seconds; resumetime = time to wait if (m_time < MESECONS_RESUMETIME) then return end -- don't even try if server has not been running for XY seconds
-- after starting the server before processing the ActionQueue, don't set this too low local actions = mesecon:tablecopy(mesecon.queue.actions)
if (m_time < resumetime) then return end
local actions = mesecon.tablecopy(mesecon.queue.actions)
local actions_now={} local actions_now={}
mesecon.queue.actions = {} mesecon.queue.actions = {}

View File

@ -47,14 +47,15 @@ mesecon.queue.funcs={} -- contains all ActionQueue functions
-- Settings -- Settings
dofile(minetest.get_modpath("mesecons").."/settings.lua") dofile(minetest.get_modpath("mesecons").."/settings.lua")
-- Presets (eg default rules)
dofile(minetest.get_modpath("mesecons").."/presets.lua");
-- Utilities like comparing positions, -- Utilities like comparing positions,
-- adding positions and rules, -- adding positions and rules,
-- mostly things that make the source look cleaner -- mostly things that make the source look cleaner
dofile(minetest.get_modpath("mesecons").."/util.lua"); dofile(minetest.get_modpath("mesecons").."/util.lua");
-- Presets (eg default rules)
dofile(minetest.get_modpath("mesecons").."/presets.lua");
-- The ActionQueue -- The ActionQueue
-- Saves all the actions that have to be execute in the future -- Saves all the actions that have to be execute in the future
dofile(minetest.get_modpath("mesecons").."/actionqueue.lua"); dofile(minetest.get_modpath("mesecons").."/actionqueue.lua");
@ -66,6 +67,11 @@ dofile(minetest.get_modpath("mesecons").."/actionqueue.lua");
-- like calling action_on/off/change -- like calling action_on/off/change
dofile(minetest.get_modpath("mesecons").."/internal.lua"); 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 -- API
-- these are the only functions you need to remember -- these are the only functions you need to remember
@ -73,8 +79,8 @@ mesecon.queue:add_function("receptor_on", function (pos, rules)
rules = rules or mesecon.rules.default rules = rules or mesecon.rules.default
-- if area (any of the rule targets) is not loaded, keep trying and call this again later -- 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 for _, rule in ipairs(mesecon:flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule) local np = mesecon:addPosRule(pos, rule)
-- if area is not loaded, keep trying -- if area is not loaded, keep trying
if minetest.get_node_or_nil(np) == nil then if minetest.get_node_or_nil(np) == nil then
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
@ -83,16 +89,16 @@ mesecon.queue:add_function("receptor_on", function (pos, rules)
end end
-- execute action -- execute action
for _, rule in ipairs(mesecon.flattenrules(rules)) do for _, rule in ipairs(mesecon:flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule) local np = mesecon:addPosRule(pos, rule)
local rulenames = mesecon.rules_link_rule_all(pos, rule) local rulenames = mesecon:rules_link_rule_all(pos, rule)
for _, rulename in ipairs(rulenames) do for _, rulename in ipairs(rulenames) do
mesecon.turnon(np, rulename) mesecon:turnon(np, rulename)
end end
end 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) mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
end end
@ -100,38 +106,34 @@ mesecon.queue:add_function("receptor_off", function (pos, rules)
rules = rules or mesecon.rules.default rules = rules or mesecon.rules.default
-- if area (any of the rule targets) is not loaded, keep trying and call this again later -- 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 for _, rule in ipairs(mesecon:flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule) local np = mesecon:addPosRule(pos, rule)
if minetest.get_node_or_nil(np) == nil then if minetest.get_node_or_nil(np) == nil then
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
return return
end end
end end
for _, rule in ipairs(mesecon.flattenrules(rules)) do for _, rule in ipairs(mesecon:flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule) local np = mesecon:addPosRule(pos, rule)
local rulenames = mesecon.rules_link_rule_all(pos, rule) local rulenames = mesecon:rules_link_rule_all(pos, rule)
for _, rulename in ipairs(rulenames) do for _, rulename in ipairs(rulenames) do
if not mesecon.connected_to_receptor(np, mesecon.invertRule(rule)) then if not mesecon:connected_to_receptor(np, mesecon:invertRule(rule)) then
mesecon.turnoff(np, rulename) mesecon:turnoff(np, rulename)
else 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
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) mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
end end
print("[OK] Mesecons") print("[OK] Mesecons")
-- Deprecated stuff
-- To be removed in future releases
dofile(minetest.get_modpath("mesecons").."/legacy.lua");
--The actual wires --The actual wires
dofile(minetest.get_modpath("mesecons").."/wires.lua"); dofile(minetest.get_modpath("mesecons").."/wires.lua");

View File

@ -1,58 +1,62 @@
-- Internal.lua - The core of mesecons -- Internal.lua - The core of mesecons
-- --
-- For more practical developer resources see http://mesecons.net/developers.php -- For more practical developer resources see mesecons.tk
-- --
-- Function overview -- Function overview
-- mesecon.get_effector(nodename) --> Returns the mesecons.effector -specifictation in the nodedef by the nodename -- 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_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_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_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_any_outputrules (node) --> Returns the rules of a node if it is a conductor or a receptor
-- RECEPTORS -- RECEPTORS
-- mesecon.is_receptor(nodename) --> Returns true if nodename is a receptor -- 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_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: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:receptor_get_rules(node) --> Returns the rules of the receptor (mesecon.rules.default if none specified)
-- EFFECTORS -- EFFECTORS
-- mesecon.is_effector(nodename) --> Returns true if nodename is an effector -- 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_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: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:effector_get_rules(node) --> Returns the input rules of the effector (mesecon.rules.default if none specified)
-- SIGNALS -- SIGNALS
-- 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: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, depth) --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off), higher depths 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, depth) --> Changes the effector node at the specific pos (calls nodedef.mesecons.effector.action_change), higher depths are executed later -- 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
-- CONDUCTORS -- CONDUCTORS
-- mesecon.is_conductor(nodename) --> Returns true if nodename is a conductor -- 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_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: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_on(node_off) --> Returns the onstate nodename of the conductor
-- mesecon.get_conductor_off(node_on) --> Returns the offstate 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:conductor_get_rules(node) --> Returns the input+output rules of a conductor (mesecon.rules.default if none specified)
-- HIGH-LEVEL Internals -- HIGH-LEVEL Internals
-- mesecon.is_power_on(pos) --> Returns true if pos emits power in any way -- 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: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: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, link) --> link is the input rule that caused calling turnoff, turns off every connected node, iterative -- 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, link) --> Returns true if pos is connected to a receptor directly or via conductors, iterative -- 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(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: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_powered(pos) --> Returns true if pos is powered by a receptor or a conductor
-- RULES ROTATION helpers -- RULES ROTATION helpsers
-- mesecon.rotate_rules_right(rules) -- mesecon:rotate_rules_right(rules)
-- mesecon.rotate_rules_left(rules) -- mesecon:rotate_rules_left(rules)
-- mesecon.rotate_rules_up(rules) -- mesecon:rotate_rules_up(rules)
-- mesecon.rotate_rules_down(rules) -- mesecon:rotate_rules_down(rules)
-- These functions return rules that have been rotated in the specific direction -- These functions return rules that have been rotated in the specific direction
-- General -- General
function mesecon.get_effector(nodename) function mesecon:get_effector(nodename)
if minetest.registered_nodes[nodename] if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.effector then and minetest.registered_nodes[nodename].mesecons.effector then
@ -60,7 +64,7 @@ function mesecon.get_effector(nodename)
end end
end end
function mesecon.get_receptor(nodename) function mesecon:get_receptor(nodename)
if minetest.registered_nodes[nodename] if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.receptor then and minetest.registered_nodes[nodename].mesecons.receptor then
@ -68,7 +72,7 @@ function mesecon.get_receptor(nodename)
end end
end end
function mesecon.get_conductor(nodename) function mesecon:get_conductor(nodename)
if minetest.registered_nodes[nodename] if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.conductor then and minetest.registered_nodes[nodename].mesecons.conductor then
@ -76,55 +80,52 @@ function mesecon.get_conductor(nodename)
end end
end end
function mesecon.get_any_outputrules (node) function mesecon:get_any_outputrules (node)
if mesecon.is_conductor(node.name) then if mesecon:is_conductor(node.name) then
return mesecon.conductor_get_rules(node) return mesecon:conductor_get_rules(node)
elseif mesecon.is_receptor(node.name) then elseif mesecon:is_receptor(node.name) then
return mesecon.receptor_get_rules(node) return mesecon:receptor_get_rules(node)
end end
return false
end end
function mesecon.get_any_inputrules (node) function mesecon:get_any_inputrules (node)
if mesecon.is_conductor(node.name) then if mesecon:is_conductor(node.name) then
return mesecon.conductor_get_rules(node) return mesecon:conductor_get_rules(node)
elseif mesecon.is_effector(node.name) then elseif mesecon:is_effector(node.name) then
return mesecon.effector_get_rules(node) return mesecon:effector_get_rules(node)
end end
end return false
function mesecon.get_any_rules (node)
return mesecon.mergetable(mesecon.get_any_inputrules(node) or {},
mesecon.get_any_outputrules(node) or {})
end end
-- Receptors -- Receptors
-- Nodes that can power mesecons -- Nodes that can power mesecons
function mesecon.is_receptor_on(nodename) function mesecon:is_receptor_on(nodename)
local receptor = mesecon.get_receptor(nodename) local receptor = mesecon:get_receptor(nodename)
if receptor and receptor.state == mesecon.state.on then if receptor and receptor.state == mesecon.state.on then
return true return true
end end
return false return false
end end
function mesecon.is_receptor_off(nodename) function mesecon:is_receptor_off(nodename)
local receptor = mesecon.get_receptor(nodename) local receptor = mesecon:get_receptor(nodename)
if receptor and receptor.state == mesecon.state.off then if receptor and receptor.state == mesecon.state.off then
return true return true
end end
return false return false
end end
function mesecon.is_receptor(nodename) function mesecon:is_receptor(nodename)
local receptor = mesecon.get_receptor(nodename) local receptor = mesecon:get_receptor(nodename)
if receptor then if receptor then
return true return true
end end
return false return false
end end
function mesecon.receptor_get_rules(node) function mesecon:receptor_get_rules(node)
local receptor = mesecon.get_receptor(node.name) local receptor = mesecon:get_receptor(node.name)
if receptor then if receptor then
local rules = receptor.rules local rules = receptor.rules
if type(rules) == 'function' then if type(rules) == 'function' then
@ -139,32 +140,32 @@ end
-- Effectors -- Effectors
-- Nodes that can be powered by mesecons -- Nodes that can be powered by mesecons
function mesecon.is_effector_on(nodename) function mesecon:is_effector_on(nodename)
local effector = mesecon.get_effector(nodename) local effector = mesecon:get_effector(nodename)
if effector and effector.action_off then if effector and effector.action_off then
return true return true
end end
return false return false
end end
function mesecon.is_effector_off(nodename) function mesecon:is_effector_off(nodename)
local effector = mesecon.get_effector(nodename) local effector = mesecon:get_effector(nodename)
if effector and effector.action_on then if effector and effector.action_on then
return true return true
end end
return false return false
end end
function mesecon.is_effector(nodename) function mesecon:is_effector(nodename)
local effector = mesecon.get_effector(nodename) local effector = mesecon:get_effector(nodename)
if effector then if effector then
return true return true
end end
return false return false
end end
function mesecon.effector_get_rules(node) function mesecon:effector_get_rules(node)
local effector = mesecon.get_effector(node.name) local effector = mesecon:get_effector(node.name)
if effector then if effector then
local rules = effector.rules local rules = effector.rules
if type(rules) == 'function' then if type(rules) == 'function' then
@ -182,150 +183,159 @@ end
-- Activation: -- Activation:
mesecon.queue:add_function("activate", function (pos, rulename) mesecon.queue:add_function("activate", function (pos, rulename)
local node = minetest.get_node(pos) node = minetest.get_node(pos)
local effector = mesecon.get_effector(node.name) effector = mesecon:get_effector(node.name)
if effector and effector.action_on then if effector and effector.action_on then
effector.action_on(pos, node, rulename) effector.action_on(pos, node, rulename)
end end
end) end)
function mesecon.activate(pos, node, rulename, depth) function mesecon:activate(pos, node, rulename, recdepth)
if rulename == nil then if rulename == nil then
for _,rule in ipairs(mesecon.effector_get_rules(node)) do for _,rule in ipairs(mesecon:effector_get_rules(node)) do
mesecon.activate(pos, node, rule, depth + 1) mesecon:activate(pos, node, rule, recdepth + 1)
end end
return return
end end
mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / depth) mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / recdepth)
end end
-- Deactivation -- Deactivation
mesecon.queue:add_function("deactivate", function (pos, rulename) mesecon.queue:add_function("deactivate", function (pos, rulename)
local node = minetest.get_node(pos) node = minetest.get_node(pos)
local effector = mesecon.get_effector(node.name) effector = mesecon:get_effector(node.name)
if effector and effector.action_off then if effector and effector.action_off then
effector.action_off(pos, node, rulename) effector.action_off(pos, node, rulename)
end end
end) end)
function mesecon.deactivate(pos, node, rulename, depth) function mesecon:deactivate(pos, node, rulename, recdepth)
if rulename == nil then if rulename == nil then
for _,rule in ipairs(mesecon.effector_get_rules(node)) do for _,rule in ipairs(mesecon:effector_get_rules(node)) do
mesecon.deactivate(pos, node, rule, depth + 1) mesecon:deactivate(pos, node, rule, recdepth + 1)
end end
return return
end end
mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / depth) mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / recdepth)
end end
-- Change -- Change
mesecon.queue:add_function("change", function (pos, rulename, changetype) mesecon.queue:add_function("change", function (pos, rulename, changetype)
local node = minetest.get_node(pos) node = minetest.get_node(pos)
local effector = mesecon.get_effector(node.name) effector = mesecon:get_effector(node.name)
if effector and effector.action_change then if effector and effector.action_change then
effector.action_change(pos, node, rulename, changetype) effector.action_change(pos, node, rulename, changetype)
end end
end) end)
function mesecon.changesignal(pos, node, rulename, newstate, depth) function mesecon:changesignal(pos, node, rulename, newstate, recdepth)
if rulename == nil then if rulename == nil then
for _,rule in ipairs(mesecon.effector_get_rules(node)) do for _,rule in ipairs(mesecon:effector_get_rules(node)) do
mesecon.changesignal(pos, node, rule, newstate, depth + 1) mesecon:changesignal(pos, node, rule, newstate, recdepth + 1)
end end
return return
end end
-- Include "change" in overwritecheck so that it cannot be overwritten mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, rulename, 1 / recdepth)
-- by "active" / "deactivate" that will be called upon the node at the same time. end
local overwritecheck = {"change", rulename}
mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, overwritecheck, 1 / depth) -- #########
-- # Rules # "Database" for rulenames
-- #########
function mesecon:add_rules(name, rules)
mesecon.rules[name] = rules
end
function mesecon:get_rules(name)
return mesecon.rules[name]
end end
-- Conductors -- Conductors
function mesecon.is_conductor_on(node, rulename) function mesecon:is_conductor_on(node, rulename)
local conductor = mesecon.get_conductor(node.name) local conductor = mesecon:get_conductor(node.name)
if conductor then if conductor then
if conductor.state then if conductor.state then
return conductor.state == mesecon.state.on return conductor.state == mesecon.state.on
end end
if conductor.states then if conductor.states then
if not rulename then if not rulename then
return mesecon.getstate(node.name, conductor.states) ~= 1 return mesecon:getstate(node.name, conductor.states) ~= 1
end end
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node)) local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node))
local binstate = mesecon.getbinstate(node.name, conductor.states) local binstate = mesecon:getbinstate(node.name, conductor.states)
return mesecon.get_bit(binstate, bit) return mesecon:get_bit(binstate, bit)
end end
end end
return false return false
end end
function mesecon.is_conductor_off(node, rulename) function mesecon:is_conductor_off(node, rulename)
local conductor = mesecon.get_conductor(node.name) local conductor = mesecon:get_conductor(node.name)
if conductor then if conductor then
if conductor.state then if conductor.state then
return conductor.state == mesecon.state.off return conductor.state == mesecon.state.off
end end
if conductor.states then if conductor.states then
if not rulename then if not rulename then
return mesecon.getstate(node.name, conductor.states) == 1 return mesecon:getstate(node.name, conductor.states) == 1
end end
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node)) local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node))
local binstate = mesecon.getbinstate(node.name, conductor.states) local binstate = mesecon:getbinstate(node.name, conductor.states)
return not mesecon.get_bit(binstate, bit) return not mesecon:get_bit(binstate, bit)
end end
end end
return false return false
end end
function mesecon.is_conductor(nodename) function mesecon:is_conductor(nodename)
local conductor = mesecon.get_conductor(nodename) local conductor = mesecon:get_conductor(nodename)
if conductor then if conductor then
return true return true
end end
return false return false
end end
function mesecon.get_conductor_on(node_off, rulename) function mesecon:get_conductor_on(node_off, rulename)
local conductor = mesecon.get_conductor(node_off.name) local conductor = mesecon:get_conductor(node_off.name)
if conductor then if conductor then
if conductor.onstate then if conductor.onstate then
return conductor.onstate return conductor.onstate
end end
if conductor.states then if conductor.states then
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_off)) local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node_off))
local binstate = mesecon.getbinstate(node_off.name, conductor.states) local binstate = mesecon:getbinstate(node_off.name, conductor.states)
binstate = mesecon.set_bit(binstate, bit, "1") binstate = mesecon:set_bit(binstate, bit, "1")
return conductor.states[tonumber(binstate,2)+1] return conductor.states[tonumber(binstate,2)+1]
end end
end end
return offstate return offstate
end end
function mesecon.get_conductor_off(node_on, rulename) function mesecon:get_conductor_off(node_on, rulename)
local conductor = mesecon.get_conductor(node_on.name) local conductor = mesecon:get_conductor(node_on.name)
if conductor then if conductor then
if conductor.offstate then if conductor.offstate then
return conductor.offstate return conductor.offstate
end end
if conductor.states then if conductor.states then
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_on)) local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(node_on))
local binstate = mesecon.getbinstate(node_on.name, conductor.states) local binstate = mesecon:getbinstate(node_on.name, conductor.states)
binstate = mesecon.set_bit(binstate, bit, "0") binstate = mesecon:set_bit(binstate, bit, "0")
return conductor.states[tonumber(binstate,2)+1] return conductor.states[tonumber(binstate,2)+1]
end end
end end
return onstate return onstate
end end
function mesecon.conductor_get_rules(node) function mesecon:conductor_get_rules(node)
local conductor = mesecon.get_conductor(node.name) local conductor = mesecon:get_conductor(node.name)
if conductor then if conductor then
local rules = conductor.rules local rules = conductor.rules
if type(rules) == 'function' then if type(rules) == 'function' then
@ -339,127 +349,126 @@ end
-- some more general high-level stuff -- 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) 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 return true
end end
return false return false
end end
function mesecon.is_power_off(pos, rulename) function mesecon:is_power_off(pos, rulename)
local node = minetest.get_node(pos) 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 return true
end end
return false return false
end end
function mesecon.turnon(pos, link) function mesecon:turnon(pos, rulename, recdepth)
local frontiers = {{pos = pos, link = link}} recdepth = recdepth or 2
local node = minetest.get_node(pos)
local depth = 1 if(node.name == "ignore") then
while frontiers[depth] do -- try turning on later again
local f = frontiers[depth] mesecon.queue:add_action(
local node = minetest.get_node_or_nil(f.pos) pos, "turnon", {rulename, recdepth + 1}, nil, true)
end
-- area not loaded, postpone action if mesecon:is_conductor_off(node, rulename) then
if not node then local rules = mesecon:conductor_get_rules(node)
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), if not rulename then
param2 = node.param2}) for _, rule in ipairs(mesecon:flattenrules(rules)) do
if mesecon:connected_to_receptor(pos, rule) then
mesecon:turnon(pos, rule, recdepth + 1)
end
end
return
end
-- call turnon on neighbors: normal rules minetest.swap_node(pos, {name = mesecon:get_conductor_on(node, rulename), param2 = node.param2})
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
local np = mesecon.addPosRule(f.pos, r)
-- area not loaded, postpone action for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
if not minetest.get_node_or_nil(np) then local np = mesecon:addPosRule(pos, rule)
mesecon.queue:add_action(np, "turnon", {rulename}, if(minetest.get_node(np).name == "ignore") then
nil, true) -- try turning on later again
mesecon.queue:add_action(
np, "turnon", {rulename, recdepth + 1}, nil, true)
else else
local links = mesecon.rules_link_rule_all(f.pos, r) local rulenames = mesecon:rules_link_rule_all(pos, rule)
for _, l in ipairs(links) do
table.insert(frontiers, {pos = np, link = l}) for _, rulename in ipairs(rulenames) do
mesecon:turnon(np, rulename, recdepth + 1)
end end
end end
end end
elseif mesecon.is_effector(node.name) then elseif mesecon:is_effector(node.name) then
mesecon.changesignal(f.pos, node, f.link, mesecon.state.on, depth) mesecon:changesignal(pos, node, rulename, mesecon.state.on, recdepth)
if mesecon.is_effector_off(node.name) then if mesecon:is_effector_off(node.name) then
mesecon.activate(f.pos, node, f.link, depth) mesecon:activate(pos, node, rulename, recdepth)
end end
end end
depth = depth + 1
end
end end
mesecon.queue:add_function("turnon", function (pos, rulename, recdepth) mesecon.queue:add_function("turnon", function (pos, rulename, recdepth)
mesecon.turnon(pos, rulename, recdepth) mesecon:turnon(pos, rulename, recdepth)
end) end)
function mesecon.turnoff(pos, link) function mesecon:turnoff(pos, rulename, recdepth)
local frontiers = {{pos = pos, link = link}} recdepth = recdepth or 2
local node = minetest.get_node(pos)
local depth = 1 if(node.name == "ignore") then
while frontiers[depth] do -- try turning on later again
local f = frontiers[depth] mesecon.queue:add_action(
local node = minetest.get_node_or_nil(f.pos) pos, "turnoff", {rulename, recdepth + 1}, nil, true)
end
-- area not loaded, postpone action if mesecon:is_conductor_on(node, rulename) then
if not node then local rules = mesecon:conductor_get_rules(node)
mesecon.queue:add_action(f.pos, "turnoff", {link}, nil, true) minetest.swap_node(pos, {name = mesecon:get_conductor_off(node, rulename), param2 = node.param2})
elseif mesecon.is_conductor_on(node, f.link) then
local rules = mesecon.conductor_get_rules(node)
minetest.swap_node(f.pos, {name = mesecon.get_conductor_off(node, f.link), for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
param2 = node.param2}) local np = mesecon:addPosRule(pos, rule)
if(minetest.get_node(np).name == "ignore") then
-- call turnoff on neighbors: normal rules -- try turning on later again
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do mesecon.queue:add_action(
local np = mesecon.addPosRule(f.pos, r) np, "turnoff", {rulename, recdepth + 1}, nil, true)
-- area not loaded, postpone action
if not minetest.get_node_or_nil(np) then
mesecon.queue:add_action(np, "turnoff", {rulename},
nil, true)
else else
local links = mesecon.rules_link_rule_all(f.pos, r) local rulenames = mesecon:rules_link_rule_all(pos, rule)
for _, l in ipairs(links) do
table.insert(frontiers, {pos = np, link = l}) for _, rulename in ipairs(rulenames) do
mesecon:turnoff(np, rulename, recdepth + 1)
end end
end end
end end
elseif mesecon.is_effector(node.name) then elseif mesecon:is_effector(node.name) then
mesecon.changesignal(f.pos, node, f.link, mesecon.state.off, depth) mesecon:changesignal(pos, node, rulename, mesecon.state.off, recdepth)
if mesecon.is_effector_on(node.name) and not mesecon.is_powered(f.pos) then if mesecon:is_effector_on(node.name)
mesecon.deactivate(f.pos, node, f.link, depth) and not mesecon:is_powered(pos) then
mesecon:deactivate(pos, node, rulename, recdepth + 1)
end end
end end
depth = depth + 1
end
end end
mesecon.queue:add_function("turnoff", function (pos, rulename, recdepth) mesecon.queue:add_function("turnoff", function (pos, rulename, recdepth)
mesecon.turnoff(pos, rulename, recdepth) mesecon:turnoff(pos, rulename, recdepth)
end) end)
function mesecon.connected_to_receptor(pos, link) function mesecon:connected_to_receptor(pos, rulename)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
-- Check if conductors around are connected -- 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 if not rules then return false end
for _, rule in ipairs(mesecon.rule2meta(link, rules)) do for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
local links = mesecon.rules_link_rule_all_inverted(pos, rule) local rulenames = mesecon:rules_link_rule_all_inverted(pos, rule)
for _, l in ipairs(links) do for _, rname in ipairs(rulenames) do
local np = mesecon.addPosRule(pos, l) local np = mesecon:addPosRule(pos, rname)
if mesecon.find_receptor_on(np, mesecon.invertRule(l)) then if mesecon:find_receptor_on(np, {}, mesecon:invertRule(rname)) then
return true return true
end end
end end
@ -468,185 +477,228 @@ function mesecon.connected_to_receptor(pos, link)
return false return false
end end
function mesecon.find_receptor_on(pos, link) function mesecon:find_receptor_on(pos, checked, rulename)
local frontiers = {{pos = pos, link = link}} local node = minetest.get_node(pos)
local checked = {}
-- List of positions that have been searched for onstate receptors if mesecon:is_receptor_on(node.name) then
local depth = 1 -- add current position to checked
while frontiers[depth] do table.insert(checked, {x=pos.x, y=pos.y, z=pos.z})
local f = frontiers[depth] return true
local node = minetest.get_node_or_nil(f.pos) end
if not node then return false end if mesecon:is_conductor(node.name) then
if mesecon.is_receptor_on(node.name) then return true end local rules = mesecon:conductor_get_rules(node)
if mesecon.is_conductor_on(node, f.link) then local metaindex = mesecon:rule2metaindex(rulename, rules)
local rules = mesecon.conductor_get_rules(node) -- find out if node has already been checked (to prevent from endless loop)
for _, cp in ipairs(checked) do
-- call turnoff on neighbors: normal rules if mesecon:cmpPos(cp, pos) and cp.metaindex == metaindex then
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do return false, checked
local np = mesecon.addPosRule(f.pos, r) end
end
local links = mesecon.rules_link_rule_all_inverted(f.pos, r) -- add current position to checked
for _, l in ipairs(links) do table.insert(checked, {x=pos.x, y=pos.y, z=pos.z, metaindex = metaindex})
local checkedstring = np.x..np.y..np.z..l.x..l.y..l.z for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
if not checked[checkedstring] then local rulenames = mesecon:rules_link_rule_all_inverted(pos, rule)
table.insert(frontiers, {pos = np, link = l}) for _, rname in ipairs(rulenames) do
checked[checkedstring] = true local np = mesecon:addPosRule(pos, rname)
if mesecon:find_receptor_on(np, checked, mesecon:invertRule(rname)) then
return true
end end
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})
end
end return false
depth = depth + 1
end
end 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 outputnode = minetest.get_node(output)
local inputnode = minetest.get_node(input) local inputnode = minetest.get_node(input)
local outputrules = dug_outputrules or mesecon.get_any_outputrules (outputnode) local outputrules = dug_outputrules or mesecon:get_any_outputrules (outputnode)
local inputrules = mesecon.get_any_inputrules (inputnode) local inputrules = mesecon:get_any_inputrules (inputnode)
if not outputrules or not inputrules then if not outputrules or not inputrules then
return return
end end
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do for _, outputrule in ipairs(mesecon:flattenrules(outputrules)) do
-- Check if output sends to input -- Check if output sends to input
if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then if mesecon:cmpPos(mesecon:addPosRule(output, outputrule), input) then
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do
-- Check if input accepts from output -- Check if input accepts from output
if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then 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 return true, inputrule
end end
end end
end end
end end
end
return false return false
end end
function mesecon.rules_link_rule_all(output, rule) 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) local input = mesecon:addPosRule(output, rule)
local inputnode = minetest.get_node(input) local inputnode = minetest.get_node(input)
local inputrules = mesecon.get_any_inputrules (inputnode) local inputrules = mesecon:get_any_inputrules (inputnode)
if not inputrules then if not inputrules then
return {} return {}
end end
local rules = {} local rules = {}
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do
-- Check if input accepts from output -- Check if input accepts from output
if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then if mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then
table.insert(rules, inputrule) if inputrule.sx == nil or rule.sx == nil or mesecon:cmpSpecial(inputrule, rule) then
rules[#rules+1] = inputrule
end
end end
end end
return rules return rules
end end
function mesecon.rules_link_rule_all_inverted(input, rule) function mesecon:rules_link_rule_all_inverted(input, rule)
--local irule = mesecon.invertRule(rule) --local irule = mesecon:invertRule(rule)
local output = mesecon.addPosRule(input, rule) local output = mesecon:addPosRule(input, rule)
local outputnode = minetest.get_node(output) local outputnode = minetest.get_node(output)
local outputrules = mesecon.get_any_outputrules (outputnode) local outputrules = mesecon:get_any_outputrules (outputnode)
if not outputrules then if not outputrules then
return {} return {}
end end
local rules = {} local rules = {}
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do for _, outputrule in ipairs(mesecon:flattenrules(outputrules)) do
if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then if mesecon:cmpPos(mesecon:addPosRule(output, outputrule), input) then
table.insert(rules, mesecon.invertRule(outputrule)) if outputrule.sx == nil or rule.sx == nil or mesecon:cmpSpecial(outputrule, rule) then
rules[#rules+1] = mesecon:invertRule(outputrule)
end
end end
end end
return rules return rules
end end
function mesecon.rules_link_anydir(pos1, pos2) function mesecon:rules_link_anydir(pos1, pos2)
return mesecon.rules_link(pos1, pos2) or mesecon.rules_link(pos2, pos1) return mesecon:rules_link(pos1, pos2) or mesecon:rules_link(pos2, pos1)
end end
function mesecon.is_powered(pos, rule) function mesecon:is_powered(pos, rule)
local node = minetest.get_node(pos) 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 if not rules then return false end
-- List of nodes that send out power to pos
local sourcepos = {}
if not rule then if not rule then
for _, rule in ipairs(mesecon.flattenrules(rules)) do for _, rule in ipairs(mesecon:flattenrules(rules)) do
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 for _, rname in ipairs(rulenames) do
local np = mesecon.addPosRule(pos, rname) local np = mesecon:addPosRule(pos, rname)
local nn = minetest.get_node(np) local nn = minetest.get_node(np)
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) if (mesecon:is_conductor_on (nn, mesecon:invertRule(rname)) or mesecon:is_receptor_on (nn.name)) then
or mesecon.is_receptor_on (nn.name)) then return true
table.insert(sourcepos, np)
end end
end end
end end
else 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 for _, rname in ipairs(rulenames) do
local np = mesecon.addPosRule(pos, rname) local np = mesecon:addPosRule(pos, rname)
local nn = minetest.get_node(np) local nn = minetest.get_node(np)
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) if (mesecon:is_conductor_on (nn, mesecon:invertRule(rname)) or mesecon:is_receptor_on (nn.name)) then
or mesecon.is_receptor_on (nn.name)) then return true
table.insert(sourcepos, np)
end end
end end
end end
-- Return FALSE if not powered, return list of sources if is powered return false
if (#sourcepos == 0) then return false
else return sourcepos end
end end
--Rules rotation Functions: --Rules rotation Functions:
function mesecon.rotate_rules_right(rules) function mesecon:rotate_rules_right(rules)
local nr = {} local nr = {}
for i, rule in ipairs(rules) do for i, rule in ipairs(rules) do
if rule.sx then
table.insert(nr, { table.insert(nr, {
x = -rule.z, x = -rule.z,
y = rule.y, y = rule.y,
z = rule.x, z = rule.x,
name = rule.name}) sx = -rule.sz,
sy = rule.sy,
sz = rule.sx})
else
table.insert(nr, {
x = -rule.z,
y = rule.y,
z = rule.x})
end
end end
return nr return nr
end end
function mesecon.rotate_rules_left(rules) function mesecon:rotate_rules_left(rules)
local nr = {} local nr = {}
for i, rule in ipairs(rules) do for i, rule in ipairs(rules) do
if rule.sx then
table.insert(nr, { table.insert(nr, {
x = rule.z, x = rule.z,
y = rule.y, y = rule.y,
z = -rule.x, z = -rule.x,
name = rule.name}) sx = rule.sz,
sy = rule.sy,
sz = -rule.sx})
else
table.insert(nr, {
x = rule.z,
y = rule.y,
z = -rule.x})
end
end end
return nr return nr
end end
function mesecon.rotate_rules_down(rules) function mesecon:rotate_rules_down(rules)
local nr = {} local nr = {}
for i, rule in ipairs(rules) do for i, rule in ipairs(rules) do
if rule.sx then
table.insert(nr, { table.insert(nr, {
x = -rule.y, x = -rule.y,
y = rule.x, y = rule.x,
z = rule.z, z = rule.z,
name = rule.name}) sx = -rule.sy,
sy = rule.sx,
sz = rule.sz})
else
table.insert(nr, {
x = -rule.y,
y = rule.x,
z = rule.z})
end
end end
return nr return nr
end end
function mesecon.rotate_rules_up(rules) function mesecon:rotate_rules_up(rules)
local nr = {} local nr = {}
for i, rule in ipairs(rules) do for i, rule in ipairs(rules) do
if rule.sx then
table.insert(nr, { table.insert(nr, {
x = rule.y, x = rule.y,
y = -rule.x, y = -rule.x,
z = rule.z, z = rule.z,
name = rule.name}) sx = rule.sy,
sy = -rule.sx,
sz = rule.sz})
else
table.insert(nr, {
x = rule.y,
y = -rule.x,
z = rule.z})
end
end end
return nr return nr
end end

View File

@ -1,30 +1,32 @@
-- Ugly hack to prevent breaking compatibility with other mods minetest.swap_node = minetest.swap_node or function(pos, node)
-- Just remove the following two functions to delete the hack, to be done when other mods have updated local data = minetest.get_meta(pos):to_table()
function mesecon.receptor_on(self, pos, rules) minetest.add_node(pos, node)
if (self.receptor_on) then minetest.get_meta(pos):from_table(data)
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 end
function mesecon.receptor_off(self, pos, rules) local rules = {}
if (self.receptor_off) then rules.a = {x = -1, y = 0, z = 0, name="A"}
print("[Mesecons] Warning: A mod with mesecon support called mesecon:receptor_off.") rules.b = {x = 0, y = 0, z = 1, name="B"}
print("[Mesecons] If you are the programmer of this mod, please update it ") rules.c = {x = 1, y = 0, z = 0, name="C"}
print("[Mesecons] to use mesecon.receptor_off instead. mesecon:* is deprecated") rules.d = {x = 0, y = 0, z = -1, name="D"}
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
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
end

View File

@ -15,8 +15,6 @@ mesecon.rules.default =
{x=0, y=1, z=-1}, {x=0, y=1, z=-1},
{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 = mesecon.rules.buttonlike =
{{x = 1, y = 0, z = 0}, {{x = 1, y = 0, z = 0},
{x = 1, y = 1, z = 0}, {x = 1, y = 1, z = 0},
@ -34,11 +32,11 @@ mesecon.rules.flat =
mesecon.rules.buttonlike_get = function(node) mesecon.rules.buttonlike_get = function(node)
local rules = mesecon.rules.buttonlike local rules = mesecon.rules.buttonlike
if node.param2 == 2 then if node.param2 == 2 then
rules=mesecon.rotate_rules_left(rules) rules=mesecon:rotate_rules_left(rules)
elseif node.param2 == 3 then 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 elseif node.param2 == 0 then
rules=mesecon.rotate_rules_right(rules) rules=mesecon:rotate_rules_right(rules)
end end
return rules return rules
end end

View File

@ -1,62 +1,44 @@
-- Dig and place services -- Dig and place services
mesecon.on_placenode = function (pos, node) mesecon.on_placenode = function (pos, node)
mesecon.update_autoconnect(pos, node)
-- Receptors: Send on signal when active -- Receptors: Send on signal when active
if mesecon.is_receptor_on(node.name) then if mesecon:is_receptor_on(node.name) then
mesecon.receptor_on(pos, mesecon.receptor_get_rules(node)) mesecon:receptor_on(pos, mesecon:receptor_get_rules(node))
end end
-- Conductors: Send turnon signal when powered or replace by respective offstate conductor -- Conductors: Send turnon signal when powered or replace by respective offstate conductor
-- if placed conductor is an onstate one -- if placed conductor is an onstate one
if mesecon.is_conductor(node.name) then if mesecon:is_conductor(node.name) then
local sources = mesecon.is_powered(pos) if mesecon:is_powered(pos) then
if sources then
-- also call receptor_on if itself is powered already, so that neighboring -- also call receptor_on if itself is powered already, so that neighboring
-- conductors will be activated (when pushing an on-conductor with a piston) -- conductors will be activated (when pushing an on-conductor with a piston)
for _, s in ipairs(sources) do mesecon:turnon (pos)
local rule = {x = pos.x - s.x, y = pos.y - s.y, z = pos.z - s.z} mesecon:receptor_on (pos, mesecon:conductor_get_rules(node))
mesecon.turnon(pos, rule) elseif mesecon:is_conductor_off(node.name) then
end minetest.swap_node(pos, {name = mesecon:get_conductor_off(node)})
--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
end end
-- Effectors: Send changesignal and activate or deactivate -- Effectors: Send changesignal and activate or deactivate
if mesecon.is_effector(node.name) then if mesecon:is_effector(node.name) then
local powered_rules = {} if mesecon:is_powered(pos) then
mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on", 1)
-- for each input rule, check if powered mesecon:activate(pos, node, nil, 1)
for _, r in ipairs(mesecon.effector_get_rules(node)) do else
local powered = mesecon.is_powered(pos, r) mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "off", 1)
if powered then table.insert(powered_rules, r) end mesecon:deactivate(pos, node, nil, 1)
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
end end
end end
end end
mesecon.on_dignode = function (pos, node) mesecon.on_dignode = function (pos, node)
if mesecon.is_conductor_on(node) then if mesecon:is_conductor_on(node) then
mesecon.receptor_off(pos, mesecon.conductor_get_rules(node)) mesecon:receptor_off(pos, mesecon:conductor_get_rules(node))
elseif mesecon.is_receptor_on(node.name) then elseif mesecon:is_receptor_on(node.name) then
mesecon.receptor_off(pos, mesecon.receptor_get_rules(node)) mesecon:receptor_off(pos, mesecon:receptor_get_rules(node))
end end
mesecon.queue:add_action(pos, "update_autoconnect", {node})
end end
mesecon.queue:add_function("update_autoconnect", mesecon.update_autoconnect)
minetest.register_on_placenode(mesecon.on_placenode) minetest.register_on_placenode(mesecon.on_placenode)
minetest.register_on_dignode(mesecon.on_dignode) minetest.register_on_dignode(mesecon.on_dignode)
@ -70,7 +52,7 @@ mesecon.do_overheat = function(pos)
heat = heat + 1 heat = heat + 1
meta:set_int("heat", heat) meta:set_int("heat", heat)
if heat < mesecon.setting("overheat_max", 20) then if heat < OVERHEAT_MAX then
mesecon.queue:add_action(pos, "cooldown", {}, 1, nil, 0) mesecon.queue:add_action(pos, "cooldown", {}, 1, nil, 0)
else else
return true return true

View File

@ -1,10 +1,12 @@
-- SETTINGS -- SETTINGS
function mesecon.setting(setting, default) BLINKY_PLANT_INTERVAL = 3
if type(default) == "bool" then NEW_STYLE_WIRES = true -- true = new nodebox wires, false = old raillike wires
return minetest.setting_getbool("mesecon."..setting) or default PRESSURE_PLATE_INTERVAL = 0.1
elseif type(default) == "string" then OBJECT_DETECTOR_RADIUS = 6
return minetest.setting_get("mesecon."..setting) or default PISTON_MAXIMUM_PUSH = 15
elseif type(default) == "number" then MOVESTONE_MAXIMUM_PUSH = 100
return tonumber(minetest.setting_get("mesecon."..setting) or default) MESECONS_RESUMETIME = 4 -- time to wait when starting the server before
end -- processing the ActionQueue, don't set this too low
end 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

View File

Before

Width:  |  Height:  |  Size: 204 B

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

View File

Before

Width:  |  Height:  |  Size: 465 B

After

Width:  |  Height:  |  Size: 465 B

View File

Before

Width:  |  Height:  |  Size: 464 B

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

View File

@ -1,4 +1,4 @@
function mesecon.move_node(pos, newpos) function mesecon:move_node(pos, newpos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos):to_table() local meta = minetest.get_meta(pos):to_table()
minetest.remove_node(pos) minetest.remove_node(pos)
@ -6,7 +6,19 @@ function mesecon.move_node(pos, newpos)
minetest.get_meta(pos):from_table(meta) minetest.get_meta(pos):from_table(meta)
end end
function mesecon.flattenrules(allrules) --[[ new functions:
mesecon:flattenrules(allrules)
mesecon:rule2bit(findrule, allrules)
mesecon:rule2meta(findrule, allrules)
dec2bin(n)
mesecon:getstate(nodename, states)
mesecon:getbinstate(nodename, states)
mesecon:get_bit(binary, bit)
mesecon:set_bit(binary, bit, value)
mesecon:invertRule(r)
--]]
function mesecon:flattenrules(allrules)
--[[ --[[
{ {
{ {
@ -41,7 +53,7 @@ function mesecon.flattenrules(allrules)
--]] --]]
end end
function mesecon.rule2bit(findrule, allrules) function mesecon:rule2bit(findrule, allrules)
--get the bit of the metarule the rule is in, or bit 1 --get the bit of the metarule the rule is in, or bit 1
if (allrules[1] and if (allrules[1] and
allrules[1].x) or allrules[1].x) or
@ -50,36 +62,35 @@ function mesecon.rule2bit(findrule, allrules)
end end
for m,metarule in ipairs( allrules) do for m,metarule in ipairs( allrules) do
for _, rule in ipairs(metarule ) do for _, rule in ipairs(metarule ) do
if mesecon.cmpPos(findrule, rule) then if mesecon:cmpPos(findrule, rule) and mesecon:cmpSpecial(findrule, rule) then
return m return m
end end
end end
end end
end end
function mesecon.rule2metaindex(findrule, allrules) function mesecon:rule2metaindex(findrule, allrules)
--get the metarule the rule is in, or allrules --get the metarule the rule is in, or allrules
if allrules[1].x then if allrules[1].x then
return nil return nil
end end
if not(findrule) then if not(findrule) then
return mesecon.flattenrules(allrules) return mesecon:flattenrules(allrules)
end end
for m, metarule in ipairs( allrules) do for m, metarule in ipairs( allrules) do
for _, rule in ipairs(metarule ) do for _, rule in ipairs(metarule ) do
if mesecon.cmpPos(findrule, rule) then if mesecon:cmpPos(findrule, rule) and mesecon:cmpSpecial(findrule, rule) then
return m return m
end end
end end
end end
end end
function mesecon.rule2meta(findrule, allrules) function mesecon:rule2meta(findrule, allrules)
if #allrules == 0 then return {} end local index = mesecon:rule2metaindex(findrule, allrules)
local index = mesecon.rule2metaindex(findrule, allrules)
if index == nil then if index == nil then
if allrules[1].x then if allrules[1].x then
return allrules return allrules
@ -90,16 +101,25 @@ function mesecon.rule2meta(findrule, allrules)
return allrules[index] return allrules[index]
end end
function mesecon.dec2bin(n) if convert_base then
print(
"base2dec is tonumber(num,base1)\n"..
"commonlib needs dec2base(num,base2)\n"..
"and it needs base2base(num,base1,base2),\n"..
"which is dec2base(tonumber(num,base1),base2)"
)
else
function dec2bin(n)
local x, y = math.floor(n / 2), n % 2 local x, y = math.floor(n / 2), n % 2
if (n > 1) then if (n > 1) then
return mesecon.dec2bin(x)..y return dec2bin(x)..y
else else
return ""..y return ""..y
end end
end
end end
function mesecon.getstate(nodename, states) function mesecon:getstate(nodename, states)
for state, name in ipairs(states) do for state, name in ipairs(states) do
if name == nodename then if name == nodename then
return state return state
@ -108,49 +128,53 @@ function mesecon.getstate(nodename, states)
error(nodename.." doesn't mention itself in "..dump(states)) error(nodename.." doesn't mention itself in "..dump(states))
end end
function mesecon.getbinstate(nodename, states) function mesecon:getbinstate(nodename, states)
return mesecon.dec2bin(mesecon.getstate(nodename, states)-1) return dec2bin(mesecon:getstate(nodename, states)-1)
end end
function mesecon.get_bit(binary,bit) function mesecon:get_bit(binary,bit)
bit = bit or 1 bit = bit or 1
local c = binary:len()-(bit-1) local c = binary:len()-(bit-1)
return binary:sub(c,c) == "1" return binary:sub(c,c) == "1"
end end
function mesecon.set_bit(binary,bit,value) function mesecon:set_bit(binary,bit,value)
if value == "1" then if value == "1" then
if not mesecon.get_bit(binary,bit) then if not mesecon:get_bit(binary,bit) then
return mesecon.dec2bin(tonumber(binary,2)+math.pow(2,bit-1)) return dec2bin(tonumber(binary,2)+math.pow(2,bit-1))
end end
elseif value == "0" then elseif value == "0" then
if mesecon.get_bit(binary,bit) then if mesecon:get_bit(binary,bit) then
return mesecon.dec2bin(tonumber(binary,2)-math.pow(2,bit-1)) return dec2bin(tonumber(binary,2)-math.pow(2,bit-1))
end end
end end
return binary return binary
end end
function mesecon.invertRule(r) function mesecon:invertRule(r)
return {x = -r.x, y = -r.y, z = -r.z} return {x = -r.x, y = -r.y, z = -r.z, sx = r.sx, sy = r.sy, sz = r.sz}
end 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} return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z}
end 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) return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z)
end end
function mesecon.tablecopy(table) -- deep table copy function mesecon:cmpSpecial(r1, r2)
return (r1.sx == r2.sx and r1.sy == r2.sy and r1.sz == r2.sz)
end
function mesecon:tablecopy(table) -- deep table copy
if type(table) ~= "table" then return table end -- no need to copy if type(table) ~= "table" then return table end -- no need to copy
local newtable = {} local newtable = {}
for idx, item in pairs(table) do for idx, item in pairs(table) do
if type(item) == "table" then if type(item) == "table" then
newtable[idx] = mesecon.tablecopy(item) newtable[idx] = mesecon:tablecopy(item)
else else
newtable[idx] = item newtable[idx] = item
end end
@ -159,53 +183,13 @@ function mesecon.tablecopy(table) -- deep table copy
return newtable return newtable
end end
function mesecon.cmpAny(t1, t2) function mesecon:cmpAny(t1, t2)
if type(t1) ~= type(t2) then return false end if type(t1) ~= type(t2) then return false end
if type(t1) ~= "table" and type(t2) ~= "table" then return t1 == t2 end if type(t1) ~= "table" and type(t2) ~= "table" then return t1 == t2 end
for i, e in pairs(t1) do 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 end
return true return true
end 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

View File

@ -1,250 +1,280 @@
-- naming scheme: wire:(xp)(zp)(xm)(zm)(xpyp)(zpyp)(xmyp)(zmyp)_on/off -- naming scheme: wire:(xp)(zp)(xm)(zm)_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 conditions in brackets define whether there is a mesecon at that place or not
-- The (xp)/(zpyp)/.. statements shall be replaced by either 0 or 1 -- 1 = there is one; 0 = there is none
-- Where 0 means the wire has no visual connection to that direction and -- y always means y+
-- 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}
-- ## Update wire looks ## box_bump1 = { -2/16, -8/16, -2/16, 2/16, -13/32, 2/16 }
-- #######################
-- self_pos = pos of any mesecon node, from_pos = pos of conductor to getconnect for box_xp = {1/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
local wire_getconnect = function (from_pos, self_pos) box_zp = {-1/16, -.5, 1/16, 1/16, -.5+1/16, 8/16}
local node = minetest.get_node(self_pos) box_xm = {-8/16, -.5, -1/16, -1/16, -.5+1/16, 1/16}
if minetest.registered_nodes[node.name] box_zm = {-1/16, -.5, -8/16, 1/16, -.5+1/16, -1/16}
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
for _, r in ipairs(mesecon.flattenrules(rules)) do box_xpy = {.5-1/16, -.5+1/16, -1/16, .5, .4999+1/16, 1/16}
if (mesecon.cmpPos(mesecon.addPosRule(self_pos, r), from_pos)) then box_zpy = {-1/16, -.5+1/16, .5-1/16, 1/16, .4999+1/16, .5}
return true box_xmy = {-.5, -.5+1/16, -1/16, -.5+1/16, .4999+1/16, 1/16}
end box_zmy = {-1/16, -.5+1/16, -.5, 1/16, .4999+1/16, -.5+1/16}
end
end
return false
end
-- Update this node -- Registering the wires
local wire_updateconnect = function (pos)
local connections = {}
for _, r in ipairs(mesecon.rules.default) do for xp=0, 1 do
if wire_getconnect(pos, mesecon.addPosRule(pos, r)) then for zp=0, 1 do
table.insert(connections, r) for xm=0, 1 do
end for zm=0, 1 do
end 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
local nid = {} local groups
for _, vec in ipairs(connections) do local nodeid = tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm )..
-- flat component tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy)
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
-- 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
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
-- 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
return i <= 8
end
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 if nodeid == "00000000" then
nodebox.fixed = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16} groups = {dig_immediate = 3, mesecon_conductor_craftable=1}
wiredesc = "Mesecon"
else
groups = {dig_immediate = 3, not_in_creative_inventory = 1}
wiredesc = "Mesecons Wire (ID: "..nodeid..")"
end end
local rules = {} local nodebox = {}
if (nid[0] == 1) then table.insert(rules, vector.new( 1, 0, 0)) end local adjx = false
if (nid[1] == 1) then table.insert(rules, vector.new( 0, 0, 1)) end local adjz = false
if (nid[2] == 1) then table.insert(rules, vector.new(-1, 0, 0)) end if xp == 1 then table.insert(nodebox, box_xp) adjx = true end
if (nid[3] == 1) then table.insert(rules, vector.new( 0, 0, -1)) 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 (nid[0] == 1) then table.insert(rules, vector.new( 1, -1, 0)) end if adjx and adjz and (xp + zp + xm + zm > 2) then
if (nid[1] == 1) then table.insert(rules, vector.new( 0, -1, 1)) end table.insert(nodebox, box_bump1)
if (nid[2] == 1) then table.insert(rules, vector.new(-1, -1, 0)) end tiles_off = {
if (nid[3] == 1) then table.insert(rules, vector.new( 0, -1, -1)) end "wires_bump_off.png",
"wires_bump_off.png",
if (nid[4] == 1) then table.insert(rules, vector.new( 1, 1, 0)) end "wires_vertical_off.png",
if (nid[5] == 1) then table.insert(rules, vector.new( 0, 1, 1)) end "wires_vertical_off.png",
if (nid[6] == 1) then table.insert(rules, vector.new(-1, 1, 0)) end "wires_vertical_off.png",
if (nid[7] == 1) then table.insert(rules, vector.new( 0, 1, -1)) end "wires_vertical_off.png"
}
local meseconspec_off = { conductor = { tiles_on = {
rules = rules, "wires_bump_on.png",
state = mesecon.state.off, "wires_bump_on.png",
onstate = "mesecons:wire_"..nodeid.."_on" "wires_vertical_on.png",
}} "wires_vertical_on.png",
"wires_vertical_on.png",
local meseconspec_on = { conductor = { "wires_vertical_on.png"
rules = rules, }
state = mesecon.state.on, else
offstate = "mesecons:wire_"..nodeid.."_off" table.insert(nodebox, box_center)
}} tiles_off = {
"wires_off.png",
local groups_on = {dig_immediate = 3, mesecon_conductor_craftable = 1, "wires_off.png",
not_in_creative_inventory = 1} "wires_vertical_off.png",
local groups_off = {dig_immediate = 3, mesecon_conductor_craftable = 1} "wires_vertical_off.png",
if nodeid ~= "00000000" then "wires_vertical_off.png",
groups_off["not_in_creative_inventory"] = 1 "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"
}
end end
mesecon.register_node("mesecons:wire_"..nodeid, { if nodeid == "00000000" then
description = "Mesecon", nodebox = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
end
minetest.register_node("mesecons:wire_"..nodeid.."_off", {
description = wiredesc,
drawtype = "nodebox", drawtype = "nodebox",
inventory_image = "mesecons_wire_inv.png", tiles = tiles_off,
wield_image = "mesecons_wire_inv.png", -- inventory_image = "wires_inv.png",
-- wield_image = "wires_inv.png",
inventory_image = "jeija_mesecon_off.png",
wield_image = "jeija_mesecon_off.png",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
sunlight_propagates = true, sunlight_propagates = true,
selection_box = selectionbox, selection_box = {
node_box = nodebox, type = "fixed",
fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5}
},
node_box = {
type = "fixed",
fixed = nodebox
},
groups = groups,
walkable = false, walkable = false,
stack_max = 99,
drop = "mesecons:wire_00000000_off", drop = "mesecons:wire_00000000_off",
mesecon_wire = true mesecons = {conductor={
}, {tiles = tiles_off, mesecons = meseconspec_off, groups = groups_off}, state = mesecon.state.off,
{tiles = tiles_on, mesecons = meseconspec_on, groups = groups_on}) onstate = "mesecons:wire_"..nodeid.."_on"
}}
})
if (nid_inc(nid) == false) then return end 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={
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 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)
end end
end end
register_wires()
-- ############## minetest.register_on_placenode(update_on_place_dig)
-- ## Crafting ## minetest.register_on_dignode(update_on_place_dig)
-- ##############
minetest.register_craft({ 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", type = "cooking",
output = "mesecons:wire_00000000_off 2", output = "mesecons:wire_00000000_off 2",
recipe = "default:mese_crystal_fragment", recipe = "default:mese_crystal_fragment",
cooktime = 3, cooktime = 3,
}) })
minetest.register_craft({ minetest.register_craft({
type = "cooking", type = "cooking",
output = "mesecons:wire_00000000_off 18", output = "mesecons:wire_00000000_off 18",
recipe = "default:mese_crystal", recipe = "default:mese_crystal",
cooktime = 15, cooktime = 15,
}) })
minetest.register_craft({ minetest.register_craft({
type = "cooking", type = "cooking",
output = "mesecons:wire_00000000_off 162", output = "mesecons:wire_00000000_off 162",
recipe = "default:mese", recipe = "default:mese",
cooktime = 30, cooktime = 30,
})
end
minetest.register_craft({
type = "cooking",
output = "mesecons:wire_00000000_off 16",
recipe = "default:mese_crystal",
}) })

View File

@ -1,51 +1,102 @@
-- The BLINKY_PLANT -- The BLINKY_PLANT
minetest.register_node("mesecons_blinkyplant:blinky_plant", {
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", drawtype = "plantlike",
visual_scale = 1,
tiles = {"jeija_blinky_plant_off.png"},
inventory_image = "jeija_blinky_plant_off.png", inventory_image = "jeija_blinky_plant_off.png",
paramtype = "light",
walkable = false, 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(), sounds = default.node_sound_leaves_defaults(),
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3}, fixed = {-0.3, -0.5, -0.3, 0.3, -0.5+0.7, 0.3},
}, },
on_timer = on_timer, mesecons = {receptor = {
on_rightclick = toggle_timer, state = mesecon.state.off
on_construct = toggle_timer }},
},{ 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"}, tiles = {"jeija_blinky_plant_off.png"},
groups = {dig_immediate=3}, inventory_image = "jeija_blinky_plant_off.png",
mesecons = {receptor = { state = mesecon.state.off }} 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"}, tiles = {"jeija_blinky_plant_on.png"},
groups = {dig_immediate=3, not_in_creative_inventory=1}, inventory_image = "jeija_blinky_plant_off.png",
mesecons = {receptor = { state = mesecon.state.on }} 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)
end
}) })
minetest.register_craft({ minetest.register_craft({
output = "mesecons_blinkyplant:blinky_plant_off 1", output = "mesecons_blinkyplant:blinky_plant_off 1",
recipe = { {"","group:mesecon_conductor_craftable",""}, recipe = {
{"","group:mesecon_conductor_craftable",""}, {"","group:mesecon_conductor_craftable",""},
{"group:sapling","group:sapling","group:sapling"}} {"","group:mesecon_conductor_craftable",""},
{"default:sapling","default:sapling","default:sapling"},
}
})
minetest.register_abm(
{nodenames = {"mesecons_blinkyplant:blinky_plant_off"},
interval = BLINKY_PLANT_INTERVAL,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
--minetest.remove_node(pos)
minetest.add_node(pos, {name="mesecons_blinkyplant:blinky_plant_on"})
nodeupdate(pos)
mesecon:receptor_on(pos)
end,
})
minetest.register_abm({
nodenames = {"mesecons_blinkyplant:blinky_plant_on"},
interval = BLINKY_PLANT_INTERVAL,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
--minetest.remove_node(pos)
minetest.add_node(pos, {name="mesecons_blinkyplant:blinky_plant_off"})
nodeupdate(pos)
mesecon:receptor_off(pos)
end,
}) })

View File

@ -8,7 +8,7 @@ mesecon.button_turnoff = function (pos)
minetest.swap_node(pos, {name = "mesecons_button:button_off", param2=node.param2}) minetest.swap_node(pos, {name = "mesecons_button:button_off", param2=node.param2})
minetest.sound_play("mesecons_button_pop", {pos=pos}) minetest.sound_play("mesecons_button_pop", {pos=pos})
local rules = mesecon.rules.buttonlike_get(node) local rules = mesecon.rules.buttonlike_get(node)
mesecon.receptor_off(pos, rules) mesecon:receptor_off(pos, rules)
end end
end end
@ -42,7 +42,7 @@ minetest.register_node("mesecons_button:button_off", {
description = "Button", description = "Button",
on_punch = function (pos, node) on_punch = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_button:button_on", param2=node.param2}) 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.sound_play("mesecons_button_push", {pos=pos})
minetest.after(1, mesecon.button_turnoff, pos) minetest.after(1, mesecon.button_turnoff, pos)
end, end,

View File

@ -79,7 +79,7 @@ local function after_place(pos, placer)
end end
local function receive_fields(pos, formname, fields, sender) local function receive_fields(pos, formname, fields, sender)
if not fields.submit then if fields.quit then
return return
end end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)

View File

@ -2,7 +2,7 @@
local delayer_get_output_rules = function(node) local delayer_get_output_rules = function(node)
local rules = {{x = 0, y = 0, z = 1}} local rules = {{x = 0, y = 0, z = 1}}
for i = 0, node.param2 do for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules) rules = mesecon:rotate_rules_left(rules)
end end
return rules return rules
end end
@ -10,7 +10,7 @@ end
local delayer_get_input_rules = function(node) local delayer_get_input_rules = function(node)
local rules = {{x = 0, y = 0, z = -1}} local rules = {{x = 0, y = 0, z = -1}}
for i = 0, node.param2 do for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules) rules = mesecon:rotate_rules_left(rules)
end end
return rules return rules
end end

View File

@ -1,5 +1,3 @@
local GET_COMMAND = "GET"
-- Object detector -- Object detector
-- Detects players in a certain radius -- Detects players in a certain radius
-- The radius can be specified in mesecons/settings.lua -- The radius can be specified in mesecons/settings.lua
@ -23,7 +21,7 @@ end
-- returns true if player was found, false if not -- returns true if player was found, false if not
local object_detector_scan = function (pos) local object_detector_scan = function (pos)
local objs = minetest.get_objects_inside_radius(pos, mesecon.setting("detector_radius", 6)) local objs = minetest.get_objects_inside_radius(pos, OBJECT_DETECTOR_RADIUS)
for k, obj in pairs(objs) do for k, obj in pairs(objs) do
local isname = obj:get_player_name() -- "" is returned if it is not a player; "" ~= nil! local isname = obj:get_player_name() -- "" is returned if it is not a player; "" ~= nil!
local scanname = minetest.get_meta(pos):get_string("scanname") local scanname = minetest.get_meta(pos):get_string("scanname")
@ -35,7 +33,7 @@ local object_detector_scan = function (pos)
end end
-- set player name when receiving a digiline signal on a specific channel -- set player name when receiving a digiline signal on a specific channel
local object_detector_digiline = { object_detector_digiline = {
effector = { effector = {
action = function (pos, node, channel, msg) action = function (pos, node, channel, msg)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
@ -55,8 +53,7 @@ minetest.register_node("mesecons_detector:object_detector_off", {
groups = {cracky=3}, groups = {cracky=3},
description="Player Detector", description="Player Detector",
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.off, state = mesecon.state.off
rules = mesecon.rules.pplate
}}, }},
on_construct = object_detector_make_formspec, on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields, on_receive_fields = object_detector_on_receive_fields,
@ -71,8 +68,7 @@ minetest.register_node("mesecons_detector:object_detector_on", {
groups = {cracky=3,not_in_creative_inventory=1}, groups = {cracky=3,not_in_creative_inventory=1},
drop = 'mesecons_detector:object_detector_off', drop = 'mesecons_detector:object_detector_off',
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.on, state = mesecon.state.on
rules = mesecon.rules.pplate
}}, }},
on_construct = object_detector_make_formspec, on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields, on_receive_fields = object_detector_on_receive_fields,
@ -96,7 +92,7 @@ minetest.register_abm(
action = function(pos) action = function(pos)
if object_detector_scan(pos) then if object_detector_scan(pos) then
minetest.swap_node(pos, {name = "mesecons_detector:object_detector_on"}) minetest.swap_node(pos, {name = "mesecons_detector:object_detector_on"})
mesecon.receptor_on(pos, mesecon.rules.pplate) mesecon:receptor_on(pos)
end end
end, end,
}) })
@ -108,161 +104,7 @@ minetest.register_abm(
action = function(pos) action = function(pos)
if not object_detector_scan(pos) then if not object_detector_scan(pos) then
minetest.swap_node(pos, {name = "mesecons_detector:object_detector_off"}) minetest.swap_node(pos, {name = "mesecons_detector:object_detector_off"})
mesecon.receptor_off(pos, mesecon.rules.pplate) mesecon:receptor_off(pos)
end
end,
})
-- Node detector
-- Detects the node in front of it
local node_detector_make_formspec = function (pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", "size[9,2.5]" ..
"field[0.3, 0;9,2;scanname;Name of node to scan for (empty for any):;${scanname}]"..
"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
"button_exit[7,0.75;2,3;;Save]")
end
local node_detector_on_receive_fields = function(pos, formname, fields)
if not fields.scanname or not fields.digiline_channel then return end;
local meta = minetest.get_meta(pos)
meta:set_string("scanname", fields.scanname)
meta:set_string("digiline_channel", fields.digiline_channel)
node_detector_make_formspec(pos)
end
-- returns true if player was found, false if not
local node_detector_scan = function (pos)
local node = minetest.get_node(pos)
local frontpos = vector.subtract(pos, minetest.facedir_to_dir(node.param2))
local frontnode = minetest.get_node(frontpos)
local meta = minetest.get_meta(pos)
return (frontnode.name == meta:get_string("scanname")) or
(frontnode.name ~= "air" and frontnode.name ~= "ignore" and meta:get_string("scanname") == "")
end
-- set player name when receiving a digiline signal on a specific channel
local node_detector_digiline = {
effector = {
action = function (pos, node, channel, msg)
local meta = minetest.get_meta(pos)
local active_channel = meta:get_string("digiline_channel")
if channel == active_channel then
if msg == GET_COMMAND then
local frontpos = vector.subtract(pos, minetest.facedir_to_dir(node.param2))
local name = minetest.get_node(frontpos).name
digiline:receptor_send(pos, digiline.rules.default, channel, name)
else
meta:set_string("scanname", msg)
node_detector_make_formspec(pos)
end
end
end,
},
receptor = {}
}
minetest.register_node("mesecons_detector:node_detector_off", {
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_off.png"},
paramtype = "light",
paramtype2 = "facedir",
walkable = true,
groups = {cracky=3},
description="Node Detector",
mesecons = {receptor = {
state = mesecon.state.off
}},
on_construct = node_detector_make_formspec,
on_receive_fields = node_detector_on_receive_fields,
after_place_node = function (pos, placer)
local placer_pos = placer:getpos()
--correct for the player's height
if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
--correct for 6d facedir
if placer_pos then
local dir = {
x = pos.x - placer_pos.x,
y = pos.y - placer_pos.y,
z = pos.z - placer_pos.z
}
local node = minetest.get_node(pos)
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.set_node(pos, node)
minetest.log("action", "real (6d) facedir: " .. node.param2)
end
end,
sounds = default.node_sound_stone_defaults(),
digiline = node_detector_digiline
})
minetest.register_node("mesecons_detector:node_detector_on", {
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_on.png"},
paramtype = "light",
paramtype2 = "facedir",
walkable = true,
groups = {cracky=3,not_in_creative_inventory=1},
drop = 'mesecons_detector:node_detector_off',
mesecons = {receptor = {
state = mesecon.state.on
}},
on_construct = node_detector_make_formspec,
on_receive_fields = node_detector_on_receive_fields,
after_place_node = function (pos, placer)
local placer_pos = placer:getpos()
--correct for the player's height
if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
--correct for 6d facedir
if placer_pos then
local dir = {
x = pos.x - placer_pos.x,
y = pos.y - placer_pos.y,
z = pos.z - placer_pos.z
}
local node = minetest.get_node(pos)
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.set_node(pos, node)
minetest.log("action", "real (6d) facedir: " .. node.param2)
end
end,
sounds = default.node_sound_stone_defaults(),
digiline = node_detector_digiline
})
minetest.register_craft({
output = 'mesecons_detector:node_detector_off',
recipe = {
{"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
{"default:steel_ingot", "mesecons_luacontroller:luacontroller0000", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
}
})
minetest.register_abm(
{nodenames = {"mesecons_detector:node_detector_off"},
interval = 1.0,
chance = 1,
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)
end
end,
})
minetest.register_abm(
{nodenames = {"mesecons_detector:node_detector_on"},
interval = 1.0,
chance = 1,
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)
end end
end, end,
}) })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 727 B

View File

@ -1,2 +1,2 @@
mesecons
doors doors
mesecons

View File

@ -1,80 +1,130 @@
-- Modified, from minetest_game/mods/doors/init.lua local other_state_node = {}
local function on_rightclick(pos, dir, check_name, replace, replace_dir, params) for _, material in ipairs({
pos.y = pos.y + dir { id = "wood", desc = "Wooden", color = "brown" },
if not minetest.get_node(pos).name == check_name then { id = "steel", desc = "Steel", color = "grey" },
return }) do
end doors:register_door("mesecons_doors:op_door_"..material.id, {
local p2 = minetest.get_node(pos).param2 description = "Mesecon-operated "..material.desc.." Door",
p2 = params[p2 + 1] inventory_image = minetest.registered_items["doors:door_"..material.id].inventory_image,
groups = minetest.registered_nodes["doors:door_"..material.id.."_b_1"].groups,
minetest.swap_node(pos, {name = replace_dir, param2 = p2}) tiles_bottom = {"door_"..material.id.."_b.png", "door_"..material.color..".png"},
tiles_top = {"door_"..material.id.."_a.png", "door_"..material.color..".png"},
pos.y = pos.y - dir
minetest.swap_node(pos, {name = replace, param2 = p2})
if (minetest.get_meta(pos):get_int("right") ~= 0) == (params[1] ~= 3) then
minetest.sound_play("door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
else
minetest.sound_play("door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
end
end
local function meseconify_door(name)
local function toggle_state1 (pos, node)
on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0})
end
local function toggle_state2 (pos, node)
on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2})
end
minetest.override_item(name.."_b_1", {
mesecons = {effector = {
action_on = toggle_state1,
action_off = toggle_state1,
rules = mesecon.rules.pplate
}},
}) })
local groups_plus_mesecon = { mesecon = 2 }
minetest.override_item(name.."_b_2", { for k, v in pairs(minetest.registered_nodes["doors:door_"..material.id.."_b_1"].groups) do
mesecons = {effector = { groups_plus_mesecon[k] = v
action_on = toggle_state2, end
action_off = toggle_state2, doors:register_door("mesecons_doors:sig_door_"..material.id, {
rules = mesecon.rules.pplate description = "Mesecon-signalling "..material.desc.." Door",
}}, inventory_image = minetest.registered_items["doors:door_"..material.id].inventory_image,
groups = groups_plus_mesecon,
tiles_bottom = {"door_"..material.id.."_b.png", "door_"..material.color..".png"},
tiles_top = {"door_"..material.id.."_a.png", "door_"..material.color..".png"},
})
for _, thishalf in ipairs({ "t", "b" }) do
local otherhalf = thishalf == "t" and "b" or "t"
local otherdir = thishalf == "t" and -1 or 1
for orientation = 1, 2 do
local thissuffix = material.id.."_"..thishalf.."_"..orientation
local othersuffix = material.id.."_"..otherhalf.."_"..orientation
local thisopname = "mesecons_doors:op_door_"..thissuffix
local otheropname = "mesecons_doors:op_door_"..othersuffix
local oponr = minetest.registered_nodes[thisopname].on_rightclick
local function handle_mesecon_signal (thispos, thisnode, signal)
local thismeta = minetest.get_meta(thispos)
if signal == thismeta:get_int("sigstate") then return end
thismeta:set_int("sigstate", signal)
local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z }
if minetest.get_node(otherpos).name ~= otheropname then return end
local othermeta = minetest.get_meta(otherpos)
local newdoorstate = math.max(thismeta:get_int("sigstate"), othermeta:get_int("sigstate"))
if newdoorstate == thismeta:get_int("doorstate") then return end
oponr(thispos, thisnode, nil)
thismeta:set_int("doorstate", newdoorstate)
othermeta:set_int("doorstate", newdoorstate)
end
minetest.override_item(thisopname, {
on_construct = function (pos)
if mesecon:is_powered(pos) then
local node = minetest.get_node(pos)
mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on", 1)
mesecon:activate(pos, node, nil, 1)
end
end,
on_rightclick = function (pos, node, clicker) end,
mesecons = {
effector = {
action_on = function (pos, node)
handle_mesecon_signal(pos, node, 1)
end,
action_off = function (pos, node)
handle_mesecon_signal(pos, node, 0)
end,
},
},
})
local thissigname = "mesecons_doors:sig_door_"..thissuffix
local othersigname = "mesecons_doors:sig_door_"..othersuffix
local sigonr = minetest.registered_nodes[thissigname].on_rightclick
minetest.override_item(thissigname, {
on_rightclick = function (thispos, thisnode, clicker)
local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z }
print("open: otherpos.name="..minetest.get_node(otherpos).name..", othersigname="..othersigname)
if minetest.get_node(otherpos).name ~= othersigname then return end
sigonr(thispos, thisnode, clicker)
for _, pos in ipairs({ thispos, otherpos }) do
local node = minetest.get_node(pos)
node.name = other_state_node[node.name]
minetest.swap_node(pos, node)
mesecon:receptor_on(pos)
end
end,
mesecons = { receptor = { state = mesecon.state.off } },
})
other_state_node[thissigname] = thissigname.."_on"
local ondef = {}
for k, v in pairs(minetest.registered_nodes[thissigname]) do
ondef[k] = v
end
ondef.on_rightclick = function (thispos, thisnode, clicker)
local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z }
print("close: otherpos.name="..minetest.get_node(otherpos).name..", othersigname="..othersigname)
if minetest.get_node(otherpos).name ~= othersigname.."_on" then return end
for _, pos in ipairs({ thispos, otherpos }) do
local node = minetest.get_node(pos)
node.name = other_state_node[node.name]
minetest.swap_node(pos, node)
mesecon:receptor_off(pos)
end
sigonr(thispos, thisnode, clicker)
end
ondef.mesecons = { receptor = { state = mesecon.state.on } }
ondef.after_destruct = function (thispos, thisnode)
local otherpos = { x = thispos.x, y = thispos.y + otherdir, z = thispos.z }
if minetest.get_node(otherpos).name == othersigname.."_on" then
minetest.remove_node(otherpos)
mesecon:receptor_off(otherpos)
end
end
other_state_node[thissigname.."_on"] = thissigname
ondef.mesecon_other_state_node = thissigname
minetest.register_node(thissigname.."_on", ondef)
end
end
minetest.register_craft({
output = "mesecons_doors:op_door_"..material.id,
recipe = {
{ "group:mesecon_conductor_craftable", "", "" },
{ "", "doors:door_"..material.id, "group:mesecon_conductor_craftable" },
{ "group:mesecon_conductor_craftable", "", "" },
},
})
minetest.register_craft({
output = "mesecons_doors:sig_door_"..material.id,
recipe = {
{ "", "", "group:mesecon_conductor_craftable" },
{ "group:mesecon_conductor_craftable", "doors:door_"..material.id, "" },
{ "", "", "group:mesecon_conductor_craftable" },
},
}) })
end end
meseconify_door("doors:door_wood")
meseconify_door("doors:door_steel")
meseconify_door("doors:door_glass")
meseconify_door("doors:door_obsidian_glass")
-- Trapdoor
local function trapdoor_switch(pos, node)
local state = minetest.get_meta(pos):get_int("state")
if state == 1 then
minetest.sound_play("doors_door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
minetest.set_node(pos, {name="doors:trapdoor", param2 = node.param2})
else
minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
minetest.set_node(pos, {name="doors:trapdoor_open", param2 = node.param2})
end
minetest.get_meta(pos):set_int("state", state == 1 and 0 or 1)
end
minetest.override_item("doors:trapdoor", {
mesecons = {effector = {
action_on = trapdoor_switch,
action_off = trapdoor_switch
}},
})
minetest.override_item("doors:trapdoor_open", {
mesecons = {effector = {
action_on = trapdoor_switch,
action_off = trapdoor_switch
}},
})

View File

@ -15,7 +15,7 @@ local corner_get_rules = function (node)
{x = 0, y = 0, z = -1}} {x = 0, y = 0, z = -1}}
for i = 0, node.param2 do for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules) rules = mesecon:rotate_rules_left(rules)
end end
return rules return rules

View File

@ -8,7 +8,12 @@ local mesewire_rules =
{x = 0, y = 0, z =-1}, {x = 0, y = 0, z =-1},
} }
minetest.override_item("default:mese", { 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(),
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.off, state = mesecon.state.off,
onstate = "mesecons_extrawires:mese_powered", onstate = "mesecons_extrawires:mese_powered",

View File

@ -16,7 +16,7 @@ local tjunction_get_rules = function (node)
{x = 0, y = 0, z = -1}} {x = 0, y = 0, z = -1}}
for i = 0, node.param2 do for i = 0, node.param2 do
rules = mesecon.rotate_rules_left(rules) rules = mesecon:rotate_rules_left(rules)
end end
return rules return rules

View File

@ -18,7 +18,7 @@ local bottom_box = {
local vertical_rules = { local vertical_rules = {
{x=0, y=1, z=0}, {x=0, y=1, z=0},
{x=0, y=-1, z=0} {x=0, y=-1, z=0},
} }
local top_rules = { local top_rules = {
@ -26,7 +26,7 @@ local top_rules = {
{x=-1,y=0, z=0}, {x=-1,y=0, z=0},
{x=0,y=0, z=1}, {x=0,y=0, z=1},
{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 = { local bottom_rules = {
@ -35,79 +35,85 @@ local bottom_rules = {
{x=0, y=0, z=1}, {x=0, y=0, z=1},
{x=0, y=0, z=-1}, {x=0, y=0, z=-1},
{x=0, y=1, z=0}, {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 vertical_updatepos = function (pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if minetest.registered_nodes[node.name] if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].is_vertical_conductor then
and minetest.registered_nodes[node.name].is_vertical_conductor then local node_above = minetest.get_node(mesecon:addPosRule(pos, vertical_rules[1]))
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 node_below = minetest.get_node(mesecon.addPosRule(pos, vertical_rules[2]))
local namestate = minetest.registered_nodes[node.name].vertical_conductor_state local namestate = minetest.registered_nodes[node.name].vertical_conductor_state
local above = minetest.registered_nodes[node_above.name] local above = minetest.registered_nodes[node_above.name] and minetest.registered_nodes[node_above.name].is_vertical_conductor
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 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 if above and below then -- above and below: vertical mesecon
minetest.add_node(pos, {name = basename .. namestate}) minetest.add_node(pos, {name = "mesecons_extrawires:vertical_" .. namestate})
elseif above and not below then -- above only: bottom elseif above and not below then -- above only: bottom
minetest.add_node(pos, {name = basename .. "bottom_" .. namestate}) minetest.add_node(pos, {name = "mesecons_extrawires:vertical_bottom_" .. namestate})
elseif not above and below then -- below only: top elseif not above and below then -- below only: top
minetest.add_node(pos, {name = basename .. "top_" .. namestate}) minetest.add_node(pos, {name = "mesecons_extrawires:vertical_top_" .. namestate})
else -- no vertical wire above, no vertical wire below: use bottom else -- no vertical wire above, no vertical wire below: use default wire
minetest.add_node(pos, {name = basename .. "bottom_" .. namestate}) minetest.add_node(pos, {name = "mesecons_extrawires:vertical_" .. namestate})
end end
mesecon.update_autoconnect(pos)
end end
end end
local vertical_update = function (pos, node) local vertical_update = function (pos, node)
vertical_updatepos(pos) -- this one vertical_updatepos(pos) -- this one
vertical_updatepos(mesecon.addPosRule(pos, vertical_rules[1])) -- above 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[2])) -- below
end end
-- Vertical wire -- Vertical wire
mesecon.register_node("mesecons_extrawires:vertical", { minetest.register_node("mesecons_extrawires:vertical_on", {
description = "Vertical mesecon", description = "Vertical mesecon",
drawtype = "nodebox", drawtype = "nodebox",
tiles = {"wires_vertical_on.png"},
walkable = false, walkable = false,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
groups = {dig_immediate=3, not_in_creative_inventory=1},
selection_box = vertical_box, selection_box = vertical_box,
node_box = vertical_box, node_box = vertical_box,
is_vertical_conductor = true, is_vertical_conductor = true,
drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update,
after_dig_node = vertical_update
},{
tiles = {"mesecons_wire_off.png"},
groups = {dig_immediate=3},
vertical_conductor_state = "off",
mesecons = {conductor = {
state = mesecon.state.off,
onstate = "mesecons_extrawires:vertical_on",
rules = vertical_rules,
}}
},{
tiles = {"mesecons_wire_on.png"},
groups = {dig_immediate=3, not_in_creative_inventory=1},
vertical_conductor_state = "on", vertical_conductor_state = "on",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.on, state = mesecon.state.on,
offstate = "mesecons_extrawires:vertical_off", offstate = "mesecons_extrawires:vertical_off",
rules = vertical_rules, 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,
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 -- Vertical wire top
mesecon.register_node("mesecons_extrawires:vertical_top", { minetest.register_node("mesecons_extrawires:vertical_top_on", {
description = "Vertical mesecon", description = "Vertical mesecon",
drawtype = "nodebox", drawtype = "nodebox",
tiles = {"wires_full_on.png","wires_full_on.png","wires_vertical_on.png"},
walkable = false, walkable = false,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
@ -115,31 +121,65 @@ mesecon.register_node("mesecons_extrawires:vertical_top", {
selection_box = top_box, selection_box = top_box,
node_box = top_box, node_box = top_box,
is_vertical_conductor = true, 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,
}}
},{
tiles = {"mesecons_wire_on.png"},
vertical_conductor_state = "on", vertical_conductor_state = "on",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.on, state = mesecon.state.on,
offstate = "mesecons_extrawires:vertical_top_off", offstate = "mesecons_extrawires:vertical_top_off",
rules = top_rules, rules = top_rules,
}} }},
drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update,
after_dig_node = vertical_update,
})
minetest.register_node("mesecons_extrawires:vertical_top_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,
groups = {dig_immediate=3, not_in_creative_inventory=1},
selection_box = top_box,
node_box = top_box,
is_vertical_conductor = true,
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,
}) })
-- Vertical wire bottom -- Vertical wire bottom
mesecon.register_node("mesecons_extrawires:vertical_bottom", { minetest.register_node("mesecons_extrawires:vertical_bottom_on", {
description = "Vertical mesecon", description = "Vertical mesecon",
drawtype = "nodebox", 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, walkable = false,
paramtype = "light", paramtype = "light",
sunlight_propagates = true, sunlight_propagates = true,
@ -147,25 +187,15 @@ mesecon.register_node("mesecons_extrawires:vertical_bottom", {
selection_box = bottom_box, selection_box = bottom_box,
node_box = bottom_box, node_box = bottom_box,
is_vertical_conductor = true, 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", vertical_conductor_state = "off",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.off, state = mesecon.state.off,
onstate = "mesecons_extrawires:vertical_bottom_on", onstate = "mesecons_extrawires:vertical_bottom_on",
rules = bottom_rules, rules = bottom_rules,
}} }},
},{ drop = "mesecons_extrawires:vertical_off",
tiles = {"mesecons_wire_on.png"}, after_place_node = vertical_update,
vertical_conductor_state = "on", after_dig_node = vertical_update,
mesecons = {conductor = {
state = mesecon.state.on,
offstate = "mesecons_extrawires:vertical_bottom_off",
rules = bottom_rules,
}}
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -1,124 +1,222 @@
local nodebox = { function gate_rotate_rules(node)
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 for rotations = 0, node.param2 - 1 do
rules = mesecon.rotate_rules_left(rules) rules = mesecon:rotate_rules_left(rules)
end end
return rules return rules
end end
local function gate_get_output_rules(node) function gate_get_output_rules(node)
return gate_rotate_rules(node, {{x=1, y=0, z=0}}) rules = {{x=1, y=0, z=0}}
return gate_rotate_rules(node)
end end
local function gate_get_input_rules_oneinput(node) function gate_get_input_rules_oneinput(node)
return gate_rotate_rules(node, {{x=-1, y=0, z=0}}) rules = {{x=-1, y=0, z=0}, {x=1, y=0, z=0}}
return gate_rotate_rules(node)
end end
local function gate_get_input_rules_twoinputs(node) function gate_get_input_rules_twoinputs(node)
return gate_rotate_rules(node, {{x=0, y=0, z=1, name="input1"}, rules = {
{x=0, y=0, z=-1, name="input2"}}) {x=0, y=0, z=1},
{x=0, y=0, z=-1},
{x=1, y=0, z=0}}
return gate_rotate_rules(node)
end end
local function set_gate(pos, node, state) function update_gate(pos, node, rulename, newstate)
local gate = minetest.registered_nodes[node.name] yc_update_real_portstates(pos, node, rulename, newstate)
gate = get_gate(pos)
if mesecon.do_overheat(pos) then L = rotate_ports(
minetest.remove_node(pos) yc_get_real_portstates(pos),
mesecon.receptor_off(pos, gate_get_output_rules(node)) minetest.get_node(pos).param2
minetest.add_item(pos, gate.drop) )
elseif state then if gate == "diode" then
minetest.swap_node(pos, {name = gate.onstate, param2=node.param2}) set_gate(pos, L.a)
mesecon.receptor_on(pos, gate_get_output_rules(node)) elseif gate == "not" then
else set_gate(pos, not L.a)
minetest.swap_node(pos, {name = gate.offstate, param2=node.param2}) elseif gate == "nand" then
mesecon.receptor_off(pos, gate_get_output_rules(node)) set_gate(pos, not(L.b and L.d))
elseif gate == "and" then
set_gate(pos, L.b and L.d)
elseif gate == "xor" then
set_gate(pos, (L.b and not L.d) or (not L.b and L.d))
end end
end end
local function update_gate(pos, node, link, newstate) function set_gate(pos, on)
local gate = minetest.registered_nodes[node.name] gate = get_gate(pos)
if gate.inputnumber == 1 then
set_gate(pos, node, gate.assess(newstate == "on"))
elseif gate.inputnumber == 2 then
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_int(link.name, newstate == "on" and 1 or 0) if on ~= gate_state(pos) then
if mesecon.do_overheat(pos) then
local val1 = meta:get_int("input1") == 1 pop_gate(pos)
local val2 = meta:get_int("input2") == 1 else
set_gate(pos, node, gate.assess(val1, val2)) 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
end end
function register_gate(name, inputnumber, assess, recipe) function get_gate(pos)
local get_inputrules = inputnumber == 2 and gate_get_input_rules_twoinputs or return minetest.registered_nodes[minetest.get_node(pos).name].mesecons_gate
gate_get_input_rules_oneinput end
local description = "Mesecons Logic Gate: "..name
local basename = "mesecons_gates:"..name function gate_state(pos)
mesecon.register_node(basename, { 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
elseif gate.inputnumber == 2 then
get_rules = gate_get_input_rules_twoinputs
end
for on = 0, 1 do
nodename = "mesecons_gates:"..gate.name
if on == 1 then
onoff = "on"
drop = nodename.."_off"
nodename = nodename.."_"..onoff
description = "You hacker you!"
groups = {dig_immediate=2, not_in_creative_inventory=1, overheat = 1}
else
onoff = "off"
drop = nil
nodename = nodename.."_"..onoff
description = gate.name.." Gate"
groups = {dig_immediate=2, overheat = 1}
end
tiles = "jeija_microcontroller_bottom.png^"..
"jeija_gate_"..onoff..".png^"..
"jeija_gate_"..gate.name..".png"
node_box = {
type = "fixed",
fixed = {
{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 },
},
}
local mesecon_state
if on == 1 then
mesecon_state = mesecon.state.on
else
mesecon_state = mesecon.state.off
end
minetest.register_node(nodename, {
description = description, description = description,
inventory_image = "jeija_gate_off.png^jeija_gate_"..name..".png",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
drawtype = "nodebox", drawtype = "nodebox",
drop = basename.."_off", tiles = {tiles},
selection_box = nodebox, inventory_image = tiles,
node_box = nodebox, selection_box = node_box,
node_box = node_box,
walkable = true, 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(), sounds = default.node_sound_stone_defaults(),
assess = assess, mesecons_gate = gate.name,
onstate = basename.."_on", mesecons =
offstate = basename.."_off", {
inputnumber = inputnumber receptor =
},{ {
tiles = {"jeija_microcontroller_bottom.png^".."jeija_gate_off.png^".. state = mesecon_state,
"jeija_gate_"..name..".png"},
groups = {dig_immediate = 2, overheat = 1},
mesecons = { receptor = {
state = "off",
rules = gate_get_output_rules rules = gate_get_output_rules
}, effector = { },
rules = get_inputrules, effector =
{
rules = get_rules,
action_change = update_gate 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, overheat = 1},
mesecons = { receptor = {
state = "on",
rules = gate_get_output_rules
}, effector = {
rules = get_inputrules,
action_change = update_gate
}}
}) })
end
minetest.register_craft({output = basename.."_off", recipe = recipe})
end end
register_gate("diode", 1, function (input) return input end, minetest.register_craft({
{{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons_torch:mesecon_torch_on"}}) output = 'mesecons_gates:diode_off',
recipe = {
{'', '', ''},
{'mesecons:mesecon', 'mesecons_torch:mesecon_torch_on', 'mesecons_torch:mesecon_torch_on'},
{'', '', ''},
},
})
register_gate("not", 1, function (input) return not input end, minetest.register_craft({
{{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons:mesecon"}}) output = 'mesecons_gates:not_off',
recipe = {
{'', '', ''},
{'mesecons:mesecon', 'mesecons_torch:mesecon_torch_on', 'mesecons:mesecon'},
{'', '', ''},
},
})
register_gate("and", 2, function (val1, val2) return val1 and val2 end, minetest.register_craft({
{{"mesecons:mesecon", "", ""}, output = 'mesecons_gates:and_off',
{"", "mesecons_materials:silicon", "mesecons:mesecon"}, recipe = {
{"mesecons:mesecon", "", ""}}) {'mesecons:mesecon', '', ''},
{'', 'mesecons_materials:silicon', 'mesecons:mesecon'},
{'mesecons:mesecon', '', ''},
},
})
register_gate("nand", 2, function (val1, val2) return not (val1 and val2) end, minetest.register_craft({
{{"mesecons:mesecon", "", ""}, output = 'mesecons_gates:nand_off',
{"", "mesecons_materials:silicon", "mesecons_torch:mesecon_torch_on"}, recipe = {
{"mesecons:mesecon", "", ""}}) {'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, minetest.register_craft({
{{"mesecons:mesecon", "", ""}, output = 'mesecons_gates:xor_off',
{"", "mesecons_materials:silicon", "mesecons_materials:silicon"}, recipe = {
{"mesecons:mesecon", "", ""}}) {'mesecons:mesecon', '', ''},
{'', 'mesecons_materials:silicon', 'mesecons_materials:silicon'},
{'mesecons:mesecon', '', ''},
},
})

View File

@ -4,17 +4,24 @@
-- (does not work with other liquids) -- (does not work with other liquids)
minetest.register_node("mesecons_hydroturbine:hydro_turbine_off", { minetest.register_node("mesecons_hydroturbine:hydro_turbine_off", {
drawtype = "mesh", drawtype = "nodebox",
mesh = "jeija_hydro_turbine.obj",
tiles = {"jeija_hydro_turbine_off.png"}, tiles = {"jeija_hydro_turbine_off.png"},
inventory_image = "jeija_hydro_turbine_inv.png",
wield_scale = {x=0.75, y=0.75, z=0.75},
groups = {dig_immediate=2}, groups = {dig_immediate=2},
description="Water Turbine", description="Water Turbine",
paramtype = "light", paramtype = "light",
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 }, fixed = {{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
{-0.15, 0.5, -0.15, 0.15, 1.45, 0.15},
{-0.45, 1.15, -0.1, 0.45, 1.45, 0.1},
{-0.1, 1.15, -0.45, 0.1, 1.45, 0.45}},
},
node_box = {
type = "fixed",
fixed = {{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
{-0.15, 0.5, -0.15, 0.15, 1.45, 0.15},
{-0.45, 1.15, -0.1, 0.45, 1.45, 0.1},
{-0.1, 1.15, -0.45, 0.1, 1.45, 0.45}},
}, },
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
@ -23,18 +30,25 @@ minetest.register_node("mesecons_hydroturbine:hydro_turbine_off", {
}) })
minetest.register_node("mesecons_hydroturbine:hydro_turbine_on", { minetest.register_node("mesecons_hydroturbine:hydro_turbine_on", {
drawtype = "mesh", drawtype = "nodebox",
mesh = "jeija_hydro_turbine.obj",
wield_scale = {x=0.75, y=0.75, z=0.75},
tiles = {"jeija_hydro_turbine_on.png"}, tiles = {"jeija_hydro_turbine_on.png"},
inventory_image = "jeija_hydro_turbine_inv.png",
drop = "mesecons_hydroturbine:hydro_turbine_off 1", drop = "mesecons_hydroturbine:hydro_turbine_off 1",
groups = {dig_immediate=2,not_in_creative_inventory=1}, groups = {dig_immediate=2,not_in_creative_inventory=1},
description="Water Turbine", description="Water Turbine",
paramtype = "light", paramtype = "light",
selection_box = { selection_box = {
type = "fixed", type = "fixed",
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 }, fixed = {{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
{-0.15, 0.5, -0.15, 0.15, 1.45, 0.15},
{-0.5, 1.15, -0.1, 0.5, 1.45, 0.1},
{-0.1, 1.15, -0.5, 0.1, 1.45, 0.5}},
},
node_box = {
type = "fixed",
fixed = {{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
{-0.15, 0.5, -0.15, 0.15, 1.45, 0.15},
{-0.5, 1.15, -0.1, 0.5, 1.45, 0.1},
{-0.1, 1.15, -0.5, 0.1, 1.45, 0.5}},
}, },
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
@ -52,7 +66,7 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_off"},
if minetest.get_node(waterpos).name=="default:water_flowing" then if minetest.get_node(waterpos).name=="default:water_flowing" then
minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"}) minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"})
nodeupdate(pos) nodeupdate(pos)
mesecon.receptor_on(pos) mesecon:receptor_on(pos)
end end
end, end,
}) })
@ -66,7 +80,7 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_on"},
if minetest.get_node(waterpos).name~="default:water_flowing" then if minetest.get_node(waterpos).name~="default:water_flowing" then
minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"}) minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"})
nodeupdate(pos) nodeupdate(pos)
mesecon.receptor_off(pos) mesecon:receptor_off(pos)
end end
end, end,
}) })

View File

@ -1,416 +0,0 @@
# Blender v2.69 (sub 0) OBJ File: 'mesecons-water-turbine.blend'
# www.blender.org
o Cylinder.002_Cylinder.003
v 0.000000 0.500000 -0.150000
v 0.000000 0.562500 -0.150000
v 0.106066 0.500000 -0.106066
v 0.106066 0.562500 -0.106066
v 0.150000 0.500000 0.000000
v 0.150000 0.562500 0.000000
v 0.106066 0.500000 0.106066
v 0.106066 0.562500 0.106066
v -0.000000 0.500000 0.150000
v -0.000000 0.562500 0.150000
v -0.106066 0.500000 0.106066
v -0.106066 0.562500 0.106066
v -0.150000 0.500000 -0.000000
v -0.150000 0.562500 -0.000000
v -0.106066 0.500000 -0.106066
v -0.106066 0.562500 -0.106066
v 0.097545 0.625000 -0.490393
v -0.097545 0.625000 -0.490393
v -0.277785 0.625000 -0.415735
v -0.415735 0.625000 -0.277785
v -0.490393 0.625000 -0.097545
v -0.490393 0.625000 0.097545
v -0.415735 0.625000 0.277785
v -0.277785 0.625000 0.415735
v -0.097545 0.625000 0.490393
v 0.097545 0.625000 0.490393
v 0.277785 0.625000 0.415735
v 0.415735 0.625000 0.277785
v 0.490393 0.625000 0.097545
v 0.490393 0.625000 -0.097545
v 0.415735 0.625000 -0.277785
v 0.277785 0.625000 -0.415735
v 0.097545 0.656250 -0.490393
v -0.097545 0.656250 -0.490393
v -0.277785 0.656250 -0.415735
v -0.415735 0.656250 -0.277785
v -0.490393 0.656250 -0.097545
v -0.490393 0.656250 0.097545
v -0.415735 0.656250 0.277785
v -0.277785 0.656250 0.415735
v -0.097545 0.656250 0.490393
v 0.097545 0.656250 0.490393
v 0.277785 0.656250 0.415735
v 0.415735 0.656250 0.277785
v 0.490393 0.656250 0.097545
v 0.490393 0.656250 -0.097545
v 0.415735 0.656250 -0.277785
v 0.277785 0.656250 -0.415735
v 0.116233 0.634645 -0.436100
v 0.116233 1.482640 -0.436100
v 0.299524 0.634645 -0.186124
v 0.299524 1.482640 -0.186124
v 0.343405 0.634645 0.080186
v 0.343405 1.482640 0.080186
v 0.186124 0.634645 0.299524
v 0.186124 1.482640 0.299524
v -0.080186 0.634645 0.343405
v -0.080186 1.482640 0.343405
v -0.299524 0.634645 0.186124
v -0.299524 1.482640 0.186124
v -0.343405 0.634645 -0.080186
v -0.343405 1.482640 -0.080186
v -0.186124 0.634645 -0.299524
v -0.186124 1.482640 -0.299524
v 0.080186 0.634645 -0.343405
v 0.080186 1.482640 -0.343405
v 0.390559 1.482640 -0.226180
v 0.390559 0.634645 -0.226180
v 0.436100 1.482640 0.116233
v 0.436100 0.634645 0.116233
v 0.226180 1.482640 0.390559
v 0.226180 0.634645 0.390559
v -0.116233 1.482640 0.436100
v -0.116233 0.634645 0.436100
v -0.390559 1.482640 0.226180
v -0.390559 0.634645 0.226180
v -0.436100 1.482640 -0.116233
v -0.436100 0.634645 -0.116233
v -0.226180 1.482640 -0.390559
v -0.226180 0.634645 -0.390559
v 0.108975 0.634645 -0.430778
v 0.292266 0.634645 -0.180802
v 0.292266 1.482640 -0.180802
v 0.108975 1.482640 -0.430778
v 0.381664 0.634645 -0.227549
v 0.334509 0.634645 0.078817
v 0.334509 1.482640 0.078817
v 0.381664 1.482640 -0.227549
v 0.430778 0.634645 0.108975
v 0.180802 0.634645 0.292266
v 0.180802 1.482640 0.292266
v 0.430778 1.482640 0.108975
v 0.227549 0.634645 0.381664
v -0.078817 0.634645 0.334509
v -0.078817 1.482640 0.334509
v 0.227549 1.482640 0.381664
v -0.108975 0.634645 0.430778
v -0.292266 0.634645 0.180802
v -0.292266 1.482640 0.180802
v -0.108975 1.482640 0.430778
v -0.381664 0.634645 0.227549
v -0.334509 0.634645 -0.078817
v -0.334509 1.482640 -0.078817
v -0.381664 1.482640 0.227549
v -0.227549 0.634645 -0.381663
v 0.078817 0.634645 -0.334509
v 0.078817 1.482640 -0.334509
v -0.227549 1.482640 -0.381663
v -0.430779 0.634645 -0.108975
v -0.180802 0.634645 -0.292266
v -0.180802 1.482640 -0.292266
v -0.430779 1.482640 -0.108975
v 0.097545 1.500000 -0.490393
v -0.097545 1.500000 -0.490393
v -0.277785 1.500000 -0.415735
v -0.415735 1.500000 -0.277785
v -0.490393 1.500000 -0.097545
v -0.490393 1.500000 0.097545
v -0.415735 1.500000 0.277785
v -0.277785 1.500000 0.415735
v -0.097545 1.500000 0.490393
v 0.097545 1.500000 0.490393
v 0.277785 1.500000 0.415735
v 0.415735 1.500000 0.277785
v 0.490393 1.500000 0.097545
v 0.490393 1.500000 -0.097545
v 0.415735 1.500000 -0.277785
v 0.277785 1.500000 -0.415735
v 0.097545 1.468750 -0.490393
v -0.097545 1.468750 -0.490393
v -0.277785 1.468750 -0.415735
v -0.415735 1.468750 -0.277785
v -0.490393 1.468750 -0.097545
v -0.490393 1.468750 0.097545
v -0.415735 1.468750 0.277785
v -0.277785 1.468750 0.415735
v -0.097545 1.468750 0.490393
v 0.097545 1.468750 0.490393
v 0.277785 1.468750 0.415735
v 0.415735 1.468750 0.277785
v 0.490393 1.468750 0.097545
v 0.490393 1.468750 -0.097545
v 0.415735 1.468750 -0.277785
v 0.277785 1.468750 -0.415735
v 0.025624 0.559630 -0.061863
v 0.025624 1.481372 -0.061863
v 0.061863 0.559630 -0.025624
v 0.061863 1.481372 -0.025624
v 0.061863 0.559630 0.025624
v 0.061863 1.481372 0.025624
v 0.025624 0.559630 0.061863
v 0.025624 1.481372 0.061863
v -0.025624 0.559630 0.061863
v -0.025624 1.481372 0.061863
v -0.061863 0.559630 0.025624
v -0.061863 1.481372 0.025624
v -0.061863 0.559630 -0.025624
v -0.061863 1.481372 -0.025624
v -0.025624 0.559630 -0.061863
v -0.025624 1.481372 -0.061863
v 0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 -0.500000 0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
vt 0.416667 0.625000
vt 0.416667 0.645833
vt 0.395833 0.645833
vt 0.395833 0.625000
vt 0.375000 0.645833
vt 0.375000 0.625000
vt 0.291667 0.625000
vt 0.291667 0.645833
vt 0.312500 0.645833
vt 0.312500 0.625000
vt 0.333333 0.645833
vt 0.333333 0.625000
vt 0.354167 0.645833
vt 0.354167 0.625000
vt 0.708333 0.645833
vt 0.729167 0.625000
vt 0.750000 0.625000
vt 0.770833 0.645833
vt 0.770833 0.666667
vt 0.750000 0.687500
vt 0.729167 0.687500
vt 0.708333 0.666667
vt 0.437500 0.625000
vt 0.437500 0.645833
vt 0.458333 0.625000
vt 0.458333 0.645833
vt 0.656250 0.953125
vt 0.593750 0.980469
vt 0.531250 0.980469
vt 0.468750 0.953125
vt 0.421875 0.906250
vt 0.394531 0.843750
vt 0.394531 0.781250
vt 0.421875 0.718750
vt 0.468750 0.671875
vt 0.531250 0.644531
vt 0.593750 0.644531
vt 0.656250 0.671875
vt 0.703125 0.718750
vt 0.730469 0.781250
vt 0.730469 0.843750
vt 0.703125 0.906250
vt 0.019531 0.843750
vt 0.019531 0.781250
vt 0.046875 0.718750
vt 0.093750 0.671875
vt 0.156250 0.644531
vt 0.218750 0.644531
vt 0.281250 0.671875
vt 0.328125 0.718750
vt 0.355469 0.781250
vt 0.355469 0.843750
vt 0.328125 0.906250
vt 0.281250 0.953125
vt 0.218750 0.980469
vt 0.156250 0.980469
vt 0.093750 0.953125
vt 0.046875 0.906250
vt 0.187500 0.041667
vt 0.104167 0.041667
vt 0.104167 0.020833
vt 0.187500 0.020833
vt 0.270833 0.041667
vt 0.270833 0.020833
vt 0.354167 0.041667
vt 0.354167 0.020833
vt 0.437500 0.041667
vt 0.437500 0.020833
vt 0.520833 0.041667
vt 0.520833 0.020833
vt 0.354167 0.104167
vt 0.270833 0.104167
vt 0.270833 0.083333
vt 0.354167 0.083333
vt 0.604167 0.041667
vt 0.604167 0.020833
vt 0.687500 0.041667
vt 0.687500 0.020833
vt 0.437500 0.104167
vt 0.437500 0.083333
vt 0.104167 0.104167
vt 0.020833 0.104167
vt 0.020833 0.083333
vt 0.104167 0.083333
vt 0.520833 0.104167
vt 0.520833 0.083333
vt 0.187500 0.104167
vt 0.187500 0.083333
vt 0.604167 0.104167
vt 0.604167 0.083333
vt 0.687500 0.104167
vt 0.687500 0.083333
vt 0.020833 0.041667
vt 0.020833 0.020833
vt 0.979167 0.020833
vt 0.979167 0.270833
vt 0.895833 0.270833
vt 0.895833 0.020833
vt 0.875000 0.020833
vt 0.875000 0.270833
vt 0.791667 0.270833
vt 0.791667 0.020833
vt 0.687500 0.208333
vt 0.687500 0.229167
vt 0.604167 0.229167
vt 0.604167 0.208333
vt 0.104167 0.145833
vt 0.104167 0.166667
vt 0.020833 0.166667
vt 0.020833 0.145833
vt 0.187500 0.145833
vt 0.187500 0.166667
vt 0.270833 0.145833
vt 0.270833 0.166667
vt 0.354167 0.145833
vt 0.354167 0.166667
vt 0.187500 0.208333
vt 0.187500 0.229167
vt 0.104167 0.229167
vt 0.104167 0.208333
vt 0.437500 0.145833
vt 0.437500 0.166667
vt 0.520833 0.145833
vt 0.520833 0.166667
vt 0.270833 0.208333
vt 0.270833 0.229167
vt 0.604167 0.145833
vt 0.604167 0.166667
vt 0.354167 0.208333
vt 0.354167 0.229167
vt 0.687500 0.145833
vt 0.687500 0.166667
vt 0.437500 0.208333
vt 0.437500 0.229167
vt 0.020833 0.229167
vt 0.020833 0.208333
vt 0.520833 0.208333
vt 0.520833 0.229167
vt 0.854167 0.645833
vt 0.854167 0.979167
vt 0.812500 0.979167
vt 0.812500 0.645833
vt 0.979167 0.312500
vt 0.979167 0.645833
vt 0.937500 0.645833
vt 0.937500 0.312500
vt 0.895833 0.645833
vt 0.895833 0.312500
vt 0.854167 0.312500
vt 0.812500 0.312500
vt 0.979167 0.979167
vt 0.937500 0.979167
vt 0.895833 0.979167
vt 0.020833 0.604167
vt 0.020833 0.270833
vt 0.354167 0.270833
vt 0.354167 0.604167
vt 0.729167 0.270833
vt 0.729167 0.604167
vt 0.395833 0.604167
vt 0.395833 0.270833
s off
f 1/1 2/2 4/3 3/4
f 3/4 4/3 6/5 5/6
f 5/7 6/8 8/9 7/10
f 7/10 8/9 10/11 9/12
f 9/12 10/11 12/13 11/14
f 11/14 12/13 14/5 13/6
f 4/15 2/16 16/17 14/18 12/19 10/20 8/21 6/22
f 15/23 16/24 2/2 1/1
f 13/25 14/26 16/24 15/23
f 130/27 129/28 144/29 143/30 142/31 141/32 140/33 139/34 138/35 137/36 136/37 135/38 134/39 133/40 132/41 131/42
f 18/43 17/44 32/45 31/46 30/47 29/48 28/49 27/50 26/51 25/52 24/53 23/54 22/55 21/56 20/57 19/58
f 27/59 28/60 44/61 43/62
f 26/63 27/59 43/62 42/64
f 25/65 26/63 42/64 41/66
f 24/67 25/65 41/66 40/68
f 23/69 24/67 40/68 39/70
f 17/71 18/72 34/73 33/74
f 22/75 23/69 39/70 38/76
f 21/77 22/75 38/76 37/78
f 32/79 17/71 33/74 48/80
f 20/81 21/82 37/83 36/84
f 31/85 32/79 48/80 47/86
f 19/87 20/81 36/84 35/88
f 30/89 31/85 47/86 46/90
f 18/72 19/87 35/88 34/73
f 29/91 30/89 46/90 45/92
f 28/60 29/93 45/94 44/61
f 49/95 50/96 52/97 51/98
f 68/98 67/95 54/96 53/97
f 70/95 69/96 56/97 55/98
f 72/96 71/97 58/98 57/95
f 74/95 73/96 60/97 59/98
f 76/95 75/96 62/97 61/98
f 80/96 79/97 66/98 65/95
f 78/95 77/96 64/97 63/98
f 81/99 82/100 83/101 84/102
f 85/100 86/101 87/102 88/99
f 89/101 90/102 91/99 92/100
f 93/102 94/99 95/100 96/101
f 97/102 98/99 99/100 100/101
f 101/99 102/100 103/101 104/102
f 105/102 106/99 107/100 108/101
f 109/101 110/102 111/99 112/100
f 75/100 76/99 101/98 104/97
f 71/100 72/99 93/98 96/97
f 67/98 68/97 85/100 88/99
f 79/98 80/97 105/100 108/99
f 77/100 78/99 109/98 112/97
f 73/100 74/99 97/98 100/97
f 69/98 70/97 89/100 92/99
f 50/98 49/97 81/100 84/99
f 33/51 34/52 35/53 36/54 37/55 38/56 39/57 40/58 41/43 42/44 43/45 44/46 45/47 46/48 47/49 48/50
f 123/103 139/104 140/105 124/106
f 122/107 138/108 139/109 123/110
f 121/111 137/112 138/108 122/107
f 120/113 136/114 137/112 121/111
f 119/115 135/116 136/114 120/113
f 113/117 129/118 130/119 114/120
f 118/121 134/122 135/116 119/115
f 117/123 133/124 134/122 118/121
f 128/125 144/126 129/118 113/117
f 116/127 132/128 133/124 117/123
f 127/129 143/130 144/126 128/125
f 115/131 131/132 132/128 116/127
f 126/133 142/134 143/130 127/129
f 114/120 130/119 131/135 115/136
f 125/137 141/138 142/134 126/133
f 124/106 140/105 141/138 125/137
f 145/139 146/140 148/141 147/142
f 147/143 148/144 150/145 149/146
f 149/146 150/145 152/147 151/148
f 151/148 152/147 154/139 153/149
f 153/149 154/139 156/142 155/150
f 155/144 156/151 158/152 157/145
f 159/147 160/153 146/140 145/139
f 157/145 158/152 160/153 159/147
f 161/154 162/155 163/156 164/157
f 165/155 168/156 167/157 166/154
f 161/158 165/159 166/160 162/161
f 162/158 166/159 167/160 163/161
f 163/158 167/159 168/160 164/161
f 165/160 161/161 164/158 168/159
f 113/40 114/41 115/42 116/27 117/28 118/29 119/30 120/31 121/32 122/33 123/34 124/35 125/36 126/37 127/38 128/39

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 817 B

View File

@ -2,7 +2,7 @@ function insulated_wire_get_rules(node)
local rules = {{x = 1, y = 0, z = 0}, local rules = {{x = 1, y = 0, z = 0},
{x =-1, y = 0, z = 0}} {x =-1, y = 0, z = 0}}
if node.param2 == 1 or node.param2 == 3 then if node.param2 == 1 or node.param2 == 3 then
return mesecon.rotate_rules_right(rules) return mesecon:rotate_rules_right(rules)
end end
return rules return rules
end end
@ -41,7 +41,7 @@ minetest.register_node("mesecons_insulated:insulated_on", {
minetest.register_node("mesecons_insulated:insulated_off", { minetest.register_node("mesecons_insulated:insulated_off", {
drawtype = "nodebox", drawtype = "nodebox",
description = "Insulated Mesecon", description = "insulated mesecons",
tiles = { tiles = {
"jeija_insulated_wire_sides_off.png", "jeija_insulated_wire_sides_off.png",
"jeija_insulated_wire_sides_off.png", "jeija_insulated_wire_sides_off.png",
@ -78,3 +78,7 @@ minetest.register_craft({
{"mesecons_materials:fiber", "mesecons_materials:fiber", "mesecons_materials:fiber"}, {"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}})

View File

@ -1,2 +1 @@
mesecons mesecons
dye

View File

@ -14,7 +14,7 @@ local lightstone_rules = {
{x=0, y=-1, z=0}, {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", { minetest.register_node("mesecons_lightstone:lightstone_" .. name .. "_off", {
tiles = {texture_off}, tiles = {texture_off},
groups = {cracky=2, mesecon_effector_off = 1, mesecon = 2}, 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 end
mesecon.lightstone_add("red", "dye:red", "jeija_lightstone_red_off.png", "jeija_lightstone_red_on.png") mesecon:lightstone_add("red", "default:clay_brick", "jeija_lightstone_red_off.png", "jeija_lightstone_red_on.png")
mesecon.lightstone_add("green", "dye:green", "jeija_lightstone_green_off.png", "jeija_lightstone_green_on.png") mesecon:lightstone_add("green", "default:cactus", "jeija_lightstone_green_off.png", "jeija_lightstone_green_on.png")
mesecon.lightstone_add("blue", "dye:blue", "jeija_lightstone_blue_off.png", "jeija_lightstone_blue_on.png") mesecon:lightstone_add("blue", "mesecons_materials:fiber", "jeija_lightstone_blue_off.png", "jeija_lightstone_blue_on.png")
mesecon.lightstone_add("gray", "dye:grey", "jeija_lightstone_gray_off.png", "jeija_lightstone_gray_on.png") mesecon:lightstone_add("gray", "default:cobble", "jeija_lightstone_gray_off.png", "jeija_lightstone_gray_on.png")
mesecon.lightstone_add("darkgray", "dye:dark_grey", "jeija_lightstone_darkgray_off.png", "jeija_lightstone_darkgray_on.png") mesecon:lightstone_add("darkgray", "default:gravel", "jeija_lightstone_darkgray_off.png", "jeija_lightstone_darkgray_on.png")
mesecon.lightstone_add("yellow", "dye:yellow", "jeija_lightstone_yellow_off.png", "jeija_lightstone_yellow_on.png") mesecon:lightstone_add("yellow", "default:mese_crystal_fragment", "jeija_lightstone_yellow_off.png", "jeija_lightstone_yellow_on.png")

View File

@ -1,21 +1,11 @@
-- ______
-- |
-- |
-- | __ ___ _ __ _ _
-- | | | | | |\ | | |_| | | | | |_ |_|
-- |___| |______ |__| | \| | | \ |__| |_ |_ |_ |\
-- |
-- |
--
-- Reference -- Reference
-- ports = get_real_port_states(pos): gets if inputs are powered from outside -- ports = get_real_portstates(pos): gets if inputs are powered from outside
-- newport = merge_port_states(state1, state2): just does result = state1 or state2 for every port -- newport = merge_portstates(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 -- action_setports(pos, rule, state): activates/deactivates the mesecons according to the portstates (helper for action)
-- set_port_states(pos, ports): Applies new port states to a LuaController at pos -- action(pos, ports): Applies new portstates to a luacontroller at pos
-- run(pos): runs the code in the controller 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_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 -- reset (pos): performs a hardware reset, turns off all ports
-- --
-- The Sandbox -- The Sandbox
-- The whole code of the controller runs in a sandbox, -- The whole code of the controller runs in a sandbox,
@ -30,76 +20,70 @@
local BASENAME = "mesecons_luacontroller:luacontroller" local BASENAME = "mesecons_luacontroller:luacontroller"
local rules = { local rules = {}
a = {x = -1, y = 0, z = 0, name="A"}, rules.a = {x = -1, y = 0, z = 0, name="A"}
b = {x = 0, y = 0, z = 1, name="B"}, rules.b = {x = 0, y = 0, z = 1, name="B"}
c = {x = 1, y = 0, z = 0, name="C"}, rules.c = {x = 1, y = 0, z = 0, name="C"}
d = {x = 0, y = 0, z = -1, name="D"}, rules.d = {x = 0, y = 0, z = -1, name="D"}
}
------------------ ------------------
-- Action stuff -- -- Action stuff --
------------------ ------------------
-- These helpers are required to set the port states of the luacontroller -- These helpers are required to set the portstates of the luacontroller
local function update_real_port_states(pos, rule_name, new_state) function lc_update_real_portstates(pos, rulename, newstate)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if rule_name == nil then if rulename == nil then
meta:set_int("real_portstates", 1) meta:set_int("real_portstates", 1)
return return
end end
local n = meta:get_int("real_portstates") - 1 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 = {} local L = {}
for i = 1, 4 do for i = 1, 4 do
L[i] = n % 2 L[i] = n%2
n = math.floor(n / 2) n = math.floor(n/2)
end end
-- (0,-1) (-1,0) (1,0) (0,1) if rulename.x == nil then
local pos_to_side = { 4, 1, nil, 3, 2 } for _, rname in ipairs(rulename) do
if rule_name.x == nil then local port = ({4, 1, nil, 3, 2})[rname.x+2*rname.z+3]
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 L[port] = (newstate == "on") and 1 or 0
end end
else else
local port = pos_to_side[rule_name.x + (2 * rule_name.z) + 3] local port = ({4, 1, nil, 3, 2})[rulename.x+2*rulename.z+3]
L[port] = (new_state == "on") and 1 or 0 L[port] = (newstate == "on") and 1 or 0
end end
meta:set_int("real_portstates", meta:set_int("real_portstates", 1 + L[1] + 2*L[2] + 4*L[3] + 8*L[4])
1 +
1 * L[1] +
2 * L[2] +
4 * L[3] +
8 * L[4])
end 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 meta = minetest.get_meta(pos)
local L = {} local L = {}
local n = meta:get_int("real_portstates") - 1 local n = meta:get_int("real_portstates") - 1
for _, name in ipairs(port_names) do if n < 0 then
L[name] = ((n % 2) == 1) return legacy_update_ports(pos)
n = math.floor(n / 2) end
for _, index in ipairs({"a", "b", "c", "d"}) do
L[index] = ((n%2) == 1)
n = math.floor(n/2)
end end
return L return L
end end
local merge_portstates = function (ports, vports)
local function merge_port_states(ports, vports) local npo = {a=false, b=false, c=false, d=false}
return { npo.a = vports.a or ports.a
a = ports.a or vports.a, npo.b = vports.b or ports.b
b = ports.b or vports.b, npo.c = vports.c or ports.c
c = ports.c or vports.c, npo.d = vports.d or ports.d
d = ports.d or vports.d, return npo
}
end end
local function generate_name(ports) local generate_name = function (ports)
local overwrite = overwrite or {}
local d = ports.d and 1 or 0 local d = ports.d and 1 or 0
local c = ports.c and 1 or 0 local c = ports.c and 1 or 0
local b = ports.b and 1 or 0 local b = ports.b and 1 or 0
@ -107,136 +91,101 @@ local function generate_name(ports)
return BASENAME..d..c..b..a return BASENAME..d..c..b..a
end end
local setport = function (pos, rule, state)
local function set_port(pos, rule, state)
if state then if state then
mesecon.receptor_on(pos, {rule}) mesecon:receptor_on(pos, {rule})
else else
mesecon.receptor_off(pos, {rule}) mesecon:receptor_off(pos, {rule})
end end
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 node = minetest.get_node(pos)
local name = node.name local name = node.name
clean_port_states(ports)
local vports = minetest.registered_nodes[name].virtual_portstates local vports = minetest.registered_nodes[name].virtual_portstates
local new_name = generate_name(ports) local newname = generate_name(ports)
if name ~= new_name and vports then if name ~= newname and vports then
-- Problem: local rules_on = {}
-- We need to place the new node first so that when turning local rules_off = {}
-- 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 = new_name, param2 = node.param2}) minetest.swap_node(pos, {name = newname, param2 = node.param2})
if ports.a ~= vports.a then set_port(pos, rules.a, ports.a) end if ports.a ~= vports.a then setport(pos, rules.a, ports.a) end
if ports.b ~= vports.b then set_port(pos, rules.b, ports.b) end if ports.b ~= vports.b then setport(pos, rules.b, ports.b) end
if ports.c ~= vports.c then set_port(pos, rules.c, ports.c) end if ports.c ~= vports.c then setport(pos, rules.c, ports.c) end
if ports.d ~= vports.d then set_port(pos, rules.d, ports.d) end if ports.d ~= vports.d then setport(pos, rules.d, ports.d) end
end end
end end
--------------------
-- Overheat stuff --
--------------------
----------------- local overheat_off = function(pos)
-- Overheating -- mesecon:receptor_off(pos, mesecon.rules.flat)
-----------------
local function overheat_off(pos)
mesecon.receptor_off(pos, mesecon.rules.flat)
end end
-------------------
-- Parsing stuff --
-------------------
local function overheat(pos, meta) local code_prohibited = function(code)
if mesecon.do_overheat(pos) then -- If too hot -- Clean code
local node = minetest.get_node(pos) local prohibited = {"while", "for", "repeat", "until", "function", "goto"}
node.name = BASENAME.."_burnt" for _, p in ipairs(prohibited) do
minetest.swap_node(pos, node) if string.find(code, p) then
-- Wait for pending operations return "Prohibited command: "..p
minetest.after(0.2, overheat_off, pos) end
return true
end end
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)) print(dump(param))
end end
local function remove_functions(x) deep_copy = function(original, visited) --deep copy that removes functions
local tp = type(x) visited = visited or {}
if tp == "table" then if visited[original] ~= nil then --already visited this node
for key, value in pairs(x) do return visited[original]
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 end
if val_t == "table" then if type(original) == 'table' then --nested table
remove_functions(value) local copy = {}
visited[original] = copy
for key, value in next, original, nil do
copy[deep_copy(key, visited)] = deep_copy(value, visited)
end end
end setmetatable(copy, deep_copy(getmetatable(original), visited))
end return copy
elseif tp == "function" then elseif type(original) == 'function' then --ignore functions
return nil return nil
else --by-value type
return original
end end
return x
end end
local function get_interrupt(pos) local safe_serialize = function(value)
-- iid = interrupt id return minetest.serialize(deep_copy(value))
local function interrupt(time, iid) 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
if type(time) ~= "number" then return end if type(time) ~= "number" then return end
local luac_id = minetest.get_meta(pos):get_int("luac_id") luac_id = minetest.get_meta(pos):get_int("luac_id")
mesecon.queue:add_action(pos, "lc_interrupt", {luac_id, iid}, time, iid, 1) mesecon.queue:add_action(pos, "lc_interrupt", {iid, luac_id}, time, iid, 1)
end end
return interrupt return interrupt
end end
local getdigiline_send = function(pos)
local function get_digiline_send(pos)
if not digiline then return end if not digiline then return end
-- Send messages on next serverstep
return function(channel, msg) return function(channel, msg)
minetest.after(0, function() minetest.after(0, function()
digiline:receptor_send(pos, digiline.rules.default, channel, msg) digiline:receptor_send(pos, digiline.rules.default, channel, msg)
@ -244,38 +193,34 @@ local function get_digiline_send(pos)
end end
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 -- Gather variables for the environment
local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates
local vports_copy = {} vports = {a = vports.a, b = vports.b, c = vports.c, d = vports.d}
for k, v in pairs(vports) do vports_copy[k] = v end local rports = get_real_portstates(pos)
local rports = get_real_port_states(pos)
-- Create new library tables on each call to prevent one LuaController return {
-- 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, print = safe_print,
interrupt = get_interrupt(pos), pin = merge_portstates(vports, rports),
digiline_send = get_digiline_send(pos), 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 = { string = {
byte = string.byte, byte = string.byte,
char = string.char, char = string.char,
find = string.find,
format = string.format, format = string.format,
gmatch = string.gmatch,
gsub = string.gsub, gsub = string.gsub,
len = string.len, len = string.len,
lower = string.lower, lower = string.lower,
upper = string.upper, upper = string.upper,
match = string.match,
rep = string.rep, rep = string.rep,
reverse = string.reverse, reverse = string.reverse,
sub = string.sub, sub = string.sub,
@ -312,119 +257,81 @@ local function create_environment(pos, mem, event)
tanh = math.tanh, tanh = math.tanh,
}, },
table = { table = {
concat = table.concat,
insert = table.insert, insert = table.insert,
maxn = table.maxn, maxn = table.maxn,
remove = table.remove, remove = table.remove,
sort = table.sort, sort = table.sort
},
os = {
clock = os.clock,
difftime = os.difftime,
time = os.time,
}, },
event = event,
} }
env._G = env
for _, name in pairs(safe_globals) do
env[name] = _G[name]
end
return env
end end
local create_sandbox = function (code, env)
local function timeout() -- Create Sandbox
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 if code:byte(1) == 27 then
return nil, "Binary code prohibited." return _, "You Hacker You! Don't use binary code!"
end end
local f, msg = loadstring(code) f, msg = loadstring(code)
if not f then return nil, msg end if not f then return _, msg end
setfenv(f, env) setfenv(f, env)
return f
end
return function(...) local lc_overheat = function (pos, meta)
debug.sethook(timeout, "", 10000) if mesecon.do_overheat(pos) then -- if too hot
local ok, ret = pcall(f, ...) local node = minetest.get_node(pos)
debug.sethook() -- Clear hook minetest.swap_node(pos, {name = BASENAME.."_burnt", param2 = node.param2})
if not ok then error(ret) end minetest.after(0.2, overheat_off, pos) -- wait for pending operations
return ret return true
end end
end end
local load_memory = function(meta)
local function load_memory(meta)
return minetest.deserialize(meta:get_string("lc_memory")) or {} return minetest.deserialize(meta:get_string("lc_memory")) or {}
end end
local save_memory = function(meta, mem)
local function save_memory(meta, mem) meta:set_string("lc_memory", safe_serialize(mem))
meta:set_string("lc_memory",
minetest.serialize(
remove_functions(mem)
)
)
end end
local ports_invalid = function (var)
if type(var) == "table" then
return false
end
return "The ports you set are invalid"
end
local function run(pos, event) ----------------------
-- Parsing function --
----------------------
lc_update = function (pos, event)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if overheat(pos) then return end if lc_overheat(pos) then return end
if ignore_event(event, meta) then return end
-- Load code & mem from meta -- load code & mem from memory
local mem = load_memory(meta) local mem = load_memory(meta)
local code = meta:get_string("code") local code = meta:get_string("code")
local err = code_prohibited(code) -- make sure code is ok and create environment
if err then return err end local prohibited = code_prohibited(code)
if prohibited then return prohibited end
-- Create environment
local env = create_environment(pos, mem, event) local env = create_environment(pos, mem, event)
-- Create the sandbox and execute code -- create the sandbox and execute code
local f, msg = create_sandbox(code, env) local chunk, msg = create_sandbox (code, env)
if not f then return msg end if not chunk then return msg end
local success, msg = pcall(f) local success, msg = pcall(f)
if not success then return msg end if not success then return msg end
if type(env.port) ~= "table" then if ports_invalid(env.port) then return ports_invalid(env.port) end
return "Ports set are invalid."
end
save_memory(meta, env.mem) save_memory(meta, mem)
-- Actually set the ports -- Actually set the ports
set_port_states(pos, env.port) action(pos, env.port)
end end
mesecon.queue:add_function("lc_interrupt", function (pos, luac_id, iid) local reset_meta = function(pos, code, errmsg)
-- 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) local meta = minetest.get_meta(pos)
meta:set_string("code", code) meta:set_string("code", code)
code = minetest.formspec_escape(code or "") code = minetest.formspec_escape(code or "")
@ -436,111 +343,110 @@ local function reset_meta(pos, code, errmsg)
"image_button_exit[9.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]".. "image_button_exit[9.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]"..
"label[0.1,5;"..errmsg.."]") "label[0.1,5;"..errmsg.."]")
meta:set_int("heat", 0) meta:set_int("heat", 0)
meta:set_int("luac_id", math.random(1, 65535)) meta:set_int("luac_id", math.random(1, 1000000))
end end
local function reset(pos) local reset = function (pos)
set_port_states(pos, {a=false, b=false, c=false, d=false}) action(pos, {a=false, b=false, c=false, d=false})
end end
-- ______
-- |
-- |
-- | __ ___ _ __ _ _
-- | | | | | |\ | | |_| | | | | |_ |_|
-- |___| |______ |__| | \| | | \ |__| |_ |_ |_ |\
-- |
-- |
--
----------------------- -----------------------
-- Node Registration -- -- Node Registration --
----------------------- -----------------------
local output_rules = {} local output_rules={}
local input_rules = {} local input_rules={}
local node_box = { local nodebox = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16}, -- Bottom slab { -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 { -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 { -3/16, -6/16, -3/16, 3/16, -5/16, 3/16 }, -- IC
}
} }
}
local selection_box = { local selectionbox = {
type = "fixed", type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 }, fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 },
} }
local digiline = { local digiline = {
receptor = {}, receptor = {},
effector = { effector = {
action = function(pos, node, channel, msg) action = function (pos, node, channel, msg)
run(pos, {type = "digiline", channel = channel, msg = msg}) lc_update (pos, {type = "digiline", channel = channel, msg = msg})
end 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 b = 0, 1 do
for c = 0, 1 do for c = 0, 1 do
for d = 0, 1 do for d = 0, 1 do
local cid = tostring(d)..tostring(c)..tostring(b)..tostring(a)
local node_name = BASENAME..cid local cid = tostring(d)..tostring(c)..tostring(b)..tostring(a)
local top = "jeija_luacontroller_top.png" local nodename = BASENAME..cid
if a == 1 then local top = "jeija_luacontroller_top.png"
if a == 1 then
top = top.."^jeija_luacontroller_LED_A.png" top = top.."^jeija_luacontroller_LED_A.png"
end end
if b == 1 then if b == 1 then
top = top.."^jeija_luacontroller_LED_B.png" top = top.."^jeija_luacontroller_LED_B.png"
end end
if c == 1 then if c == 1 then
top = top.."^jeija_luacontroller_LED_C.png" top = top.."^jeija_luacontroller_LED_C.png"
end end
if d == 1 then if d == 1 then
top = top.."^jeija_luacontroller_LED_D.png" top = top.."^jeija_luacontroller_LED_D.png"
end end
local groups if a + b + c + d ~= 0 then
if a + b + c + d ~= 0 then
groups = {dig_immediate=2, not_in_creative_inventory=1, overheat = 1} groups = {dig_immediate=2, not_in_creative_inventory=1, overheat = 1}
else else
groups = {dig_immediate=2, overheat = 1} groups = {dig_immediate=2, overheat = 1}
end end
output_rules[cid] = {} output_rules[cid] = {}
input_rules[cid] = {} input_rules[cid] = {}
if a == 1 then table.insert(output_rules[cid], rules.a) end 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 (b == 1) then table.insert(output_rules[cid], rules.b) end
if c == 1 then table.insert(output_rules[cid], rules.c) 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 (d == 1) then table.insert(output_rules[cid], rules.d) end
if a == 0 then table.insert( input_rules[cid], rules.a) 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 (b == 0) then table.insert(input_rules[cid], rules.b) end
if c == 0 then table.insert( input_rules[cid], rules.c) 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 (d == 0) then table.insert(input_rules[cid], rules.d) end
local mesecons = { local mesecons = {
effector = { effector =
{
rules = input_rules[cid], rules = input_rules[cid],
action_change = function (pos, _, rule_name, new_state) action_change = function (pos, _, rulename, newstate)
update_real_port_states(pos, rule_name, new_state) lc_update_real_portstates(pos, rulename, newstate)
run(pos, {type=new_state, pin=rule_name}) lc_update(pos, {type=newstate, pin=rulename})
end, end,
}, },
receptor = { receptor =
{
state = mesecon.state.on, state = mesecon.state.on,
rules = output_rules[cid] rules = output_rules[cid]
} }
} }
minetest.register_node(node_name, { minetest.register_node(nodename, {
description = "LuaController", description = "Luacontroller",
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
top, top,
@ -550,40 +456,60 @@ for d = 0, 1 do
"jeija_microcontroller_sides.png", "jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png" "jeija_microcontroller_sides.png"
}, },
inventory_image = top, inventory_image = top,
paramtype = "light", paramtype = "light",
groups = groups, groups = groups,
drop = BASENAME.."0000", drop = BASENAME.."0000",
sunlight_propagates = true, sunlight_propagates = true,
selection_box = selection_box, selection_box = selectionbox,
node_box = node_box, node_box = nodebox,
on_construct = reset_meta, on_construct = reset_meta,
on_receive_fields = on_receive_fields, 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(), sounds = default.node_sound_stone_defaults(),
mesecons = mesecons, mesecons = mesecons,
digiline = digiline, digiline = digiline,
-- Virtual portstates are the ports that virtual_portstates = { a = a == 1, -- virtual portstates are
-- the node shows as powered up (light up). b = b == 1, -- the ports the the
virtual_portstates = { c = c == 1, -- controller powers itself
a = a == 1, d = d == 1},-- so those that light up
b = b == 1,
c = c == 1,
d = d == 1,
},
after_dig_node = function (pos, node) after_dig_node = function (pos, node)
mesecon.receptor_off(pos, output_rules) mesecon:receptor_off(pos, output_rules)
end, end,
is_luacontroller = true, is_luacontroller = true,
}) })
end end
end end
end end
end end
------------------------------ ------------------------------
-- Overheated LuaController -- -- 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
}
}
minetest.register_node(BASENAME .. "_burnt", { minetest.register_node(BASENAME .. "_burnt", {
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
@ -599,20 +525,24 @@ minetest.register_node(BASENAME .. "_burnt", {
groups = {dig_immediate=2, not_in_creative_inventory=1}, groups = {dig_immediate=2, not_in_creative_inventory=1},
drop = BASENAME.."0000", drop = BASENAME.."0000",
sunlight_propagates = true, sunlight_propagates = true,
selection_box = selection_box, selection_box = selectionbox,
node_box = node_box, node_box = nodebox,
on_construct = reset_meta, on_construct = reset_meta,
on_receive_fields = on_receive_fields, 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,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
virtual_portstates = {a = false, b = false, c = false, d = false}, virtual_portstates = {a = false, b = false, c = false, d = false},
mesecons = { mesecons = mesecons_burnt,
effector = {
rules = mesecon.rules.flat,
action_change = function(pos, _, rule_name, new_state)
update_real_port_states(pos, rule_name, new_state)
end,
},
},
}) })
------------------------ ------------------------

View File

@ -14,7 +14,7 @@ minetest.register_craftitem("mesecons_materials:fiber", {
minetest.register_craft({ minetest.register_craft({
output = "mesecons_materials:glue 2", output = "mesecons_materials:glue 2",
type = "cooking", type = "cooking",
recipe = "group:sapling", recipe = "default:sapling",
cooktime = 2 cooktime = 2
}) })
@ -35,7 +35,7 @@ minetest.register_craftitem("mesecons_materials:silicon", {
minetest.register_craft({ minetest.register_craft({
output = "mesecons_materials:silicon 4", output = "mesecons_materials:silicon 4",
recipe = { recipe = {
{"group:sand", "group:sand"}, {"default:sand", "default:sand"},
{"group:sand", "default:steel_ingot"}, {"default:sand", "default:steel_ingot"},
} }
}) })

View File

@ -1,7 +1,5 @@
EEPROM_SIZE = 255 EEPROM_SIZE = 255
local microc_rules = {}
for a = 0, 1 do for a = 0, 1 do
for b = 0, 1 do for b = 0, 1 do
for c = 0, 1 do for c = 0, 1 do
@ -36,7 +34,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 (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 (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 if (d == 0) then table.insert(input_rules, {x = 0, y = 0, z = -1, name = "D"}) end
microc_rules[nodename] = rules mesecon:add_rules(nodename, rules)
local mesecons = {effector = local mesecons = {effector =
{ {
@ -133,8 +131,8 @@ minetest.register_node(nodename, {
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = mesecons, mesecons = mesecons,
after_dig_node = function (pos, node) after_dig_node = function (pos, node)
rules = microc_rules[node.name] rules = mesecon:get_rules(node.name)
mesecon.receptor_off(pos, rules) mesecon:receptor_off(pos, rules)
end, end,
}) })
end end
@ -166,7 +164,7 @@ function update_yc(pos)
if (mesecon.do_overheat(pos)) then if (mesecon.do_overheat(pos)) then
minetest.remove_node(pos) minetest.remove_node(pos)
minetest.after(0.2, function (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 end , pos) -- wait for pending parsings
minetest.add_item(pos, "mesecons_microcontroller:microcontroller0000") minetest.add_item(pos, "mesecons_microcontroller:microcontroller0000")
end end
@ -185,7 +183,7 @@ end
--Code Parsing --Code Parsing
function yc_code_remove_commentary(code) function yc_code_remove_commentary(code)
local is_string = false is_string = false
for i = 1, #code do for i = 1, #code do
if code:sub(i, i) == '"' then if code:sub(i, i) == '"' then
is_string = not is_string --toggle is_string is_string = not is_string --toggle is_string
@ -205,17 +203,15 @@ function yc_parsecode(code, pos)
local c local c
local eeprom = meta:get_string("eeprom") local eeprom = meta:get_string("eeprom")
while true do while true do
local command, params
command, endi = parse_get_command(code, endi) command, endi = parse_get_command(code, endi)
if command == nil then return nil end if command == nil then return nil end
if command == true then break end --end of code if command == true then break end --end of code
if command == "if" then if command == "if" then
local r
r, endi = yc_command_if(code, endi, yc_merge_portstates(Lreal, Lvirtual), eeprom) r, endi = yc_command_if(code, endi, yc_merge_portstates(Lreal, Lvirtual), eeprom)
if r == nil then return nil end if r == nil then return nil end
if r == true then -- nothing if r == true then -- nothing
elseif r == false then elseif r == false then
local endi_new = yc_skip_to_else (code, endi) endi_new = yc_skip_to_else (code, endi)
if endi_new == nil then --else > not found if endi_new == nil then --else > not found
endi = yc_skip_to_endif(code, endi) endi = yc_skip_to_endif(code, endi)
else else
@ -225,7 +221,7 @@ function yc_parsecode(code, pos)
end end
else else
params, endi = parse_get_params(code, endi) params, endi = parse_get_params(code, endi)
if not params then return nil end if params == nil then return nil end
end end
if command == "on" then if command == "on" then
L = yc_command_on (params, Lvirtual) L = yc_command_on (params, Lvirtual)
@ -238,7 +234,6 @@ function yc_parsecode(code, pos)
local su = yc_command_after(params, pos) local su = yc_command_after(params, pos)
if su == nil then return nil end if su == nil then return nil end
elseif command == "sbi" then elseif command == "sbi" then
local new_eeprom
new_eeprom, Lvirtual = yc_command_sbi (params, eeprom, yc_merge_portstates(Lreal, Lvirtual), Lvirtual) new_eeprom, Lvirtual = yc_command_sbi (params, eeprom, yc_merge_portstates(Lreal, Lvirtual), Lvirtual)
if new_eeprom == nil then return nil if new_eeprom == nil then return nil
else eeprom = new_eeprom end else eeprom = new_eeprom end
@ -256,7 +251,7 @@ end
function parse_get_command(code, starti) function parse_get_command(code, starti)
i = starti i = starti
local s s = nil
while s ~= "" do while s ~= "" do
s = string.sub(code, i, i) s = string.sub(code, i, i)
if s == "(" then if s == "(" then
@ -282,7 +277,7 @@ end
function parse_get_params(code, starti) function parse_get_params(code, starti)
i = starti i = starti
local s s = nil
local params = {} local params = {}
local is_string = false local is_string = false
while s ~= "" do while s ~= "" do
@ -305,7 +300,7 @@ end
function yc_parse_get_eeprom_param(cond, starti) function yc_parse_get_eeprom_param(cond, starti)
i = starti i = starti
local s s = nil
local addr local addr
while s ~= "" do while s ~= "" do
s = string.sub(cond, i, i) s = string.sub(cond, i, i)
@ -408,7 +403,7 @@ function yc_command_sbi(params, eeprom, L, Lv)
end end
--is an eeprom address --is an eeprom address
local new_eeprom = ""; new_eeprom = "";
for i=1, #eeprom do for i=1, #eeprom do
if tonumber(params[1])==i then if tonumber(params[1])==i then
new_eeprom = new_eeprom..status new_eeprom = new_eeprom..status
@ -462,17 +457,17 @@ function yc_command_if(code, starti, L, eeprom)
cond = yc_command_parsecondition(cond, L, eeprom) cond = yc_command_parsecondition(cond, L, eeprom)
local result
if cond == "0" then result = false if cond == "0" then result = false
elseif cond == "1" then result = true end elseif cond == "1" then result = true
if not result then end else result = nil end
if result == nil then end
return result, endi --endi from local cond, endi = yc_command_if_getcondition(code, starti) return result, endi --endi from local cond, endi = yc_command_if_getcondition(code, starti)
end end
--Condition parsing --Condition parsing
function yc_command_if_getcondition(code, starti) function yc_command_if_getcondition(code, starti)
i = starti i = starti
local s s = nil
local brackets = 1 --1 Bracket to close local brackets = 1 --1 Bracket to close
while s ~= "" do while s ~= "" do
s = string.sub(code, i, i) s = string.sub(code, i, i)
@ -506,8 +501,8 @@ function yc_command_parsecondition(cond, L, eeprom)
while i<=l do while i<=l do
local s = cond:sub(i,i) local s = cond:sub(i,i)
if s == "#" then if s == "#" then
local addr, endi = yc_parse_get_eeprom_param(cond, i+1) addr, endi = yc_parse_get_eeprom_param(cond, i+1)
local buf = yc_eeprom_read(tonumber(addr), eeprom) buf = yc_eeprom_read(tonumber(addr), eeprom)
if buf == nil then return nil end if buf == nil then return nil end
local call = cond:sub(i, endi-1) local call = cond:sub(i, endi-1)
cond = string.gsub(cond, call, buf) cond = string.gsub(cond, call, buf)
@ -581,8 +576,10 @@ end
--Virtual-Hardware functions --Virtual-Hardware functions
function yc_eeprom_read(number, eeprom) function yc_eeprom_read(number, eeprom)
if not number then return end if number == nil then return nil, nil end
return eeprom:sub(number, number) value = eeprom:sub(number, number)
if value == nil then return nil, nil end
return value, endi
end end
--Real I/O functions --Real I/O functions
@ -603,24 +600,24 @@ function yc_action_setports(pos, L, Lv)
local name = "mesecons_microcontroller:microcontroller" local name = "mesecons_microcontroller:microcontroller"
local rules local rules
if Lv.a ~= L.a then if Lv.a ~= L.a then
rules = microc_rules[name.."0001"] rules = mesecon:get_rules(name.."0001")
if L.a == true then mesecon.receptor_on(pos, rules) if L.a == true then mesecon:receptor_on(pos, rules)
else mesecon.receptor_off(pos, rules) end else mesecon:receptor_off(pos, rules) end
end end
if Lv.b ~= L.b then if Lv.b ~= L.b then
rules = microc_rules[name.."0010"] rules = mesecon:get_rules(name.."0010")
if L.b == true then mesecon.receptor_on(pos, rules) if L.b == true then mesecon:receptor_on(pos, rules)
else mesecon.receptor_off(pos, rules) end else mesecon:receptor_off(pos, rules) end
end end
if Lv.c ~= L.c then if Lv.c ~= L.c then
rules = microc_rules[name.."0100"] rules = mesecon:get_rules(name.."0100")
if L.c == true then mesecon.receptor_on(pos, rules) if L.c == true then mesecon:receptor_on(pos, rules)
else mesecon.receptor_off(pos, rules) end else mesecon:receptor_off(pos, rules) end
end end
if Lv.d ~= L.d then if Lv.d ~= L.d then
rules = microc_rules[name.."1000"] rules = mesecon:get_rules(name.."1000")
if L.d == true then mesecon.receptor_on(pos, rules) if L.d == true then mesecon:receptor_on(pos, rules)
else mesecon.receptor_off(pos, rules) end else mesecon:receptor_off(pos, rules) end
end end
end end
@ -640,6 +637,10 @@ function yc_update_real_portstates(pos, node, rulename, newstate)
return return
end end
local n = meta:get_int("real_portstates") - 1 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 = {} local L = {}
for i = 1, 4 do for i = 1, 4 do
L[i] = n%2 L[i] = n%2
@ -661,6 +662,9 @@ function yc_get_real_portstates(pos) -- determine if ports are powered (by itsel
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local L = {} local L = {}
local n = meta:get_int("real_portstates") - 1 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 for _, index in ipairs({"a", "b", "c", "d"}) do
L[index] = ((n%2) == 1) L[index] = ((n%2) == 1)
n = math.floor(n/2) n = math.floor(n/2)
@ -669,12 +673,12 @@ function yc_get_real_portstates(pos) -- determine if ports are powered (by itsel
end end
function yc_get_virtual_portstates(pos) -- portstates according to the name function yc_get_virtual_portstates(pos) -- portstates according to the name
local name = minetest.get_node(pos).name name = minetest.get_node(pos).name
local b, a = string.find(name, ":microcontroller") b, a = string.find(name, ":microcontroller")
if a == nil then return nil end if a == nil then return nil end
a = a + 1 a = a + 1
local Lvirtual = {a=false, b=false, c=false, d=false} Lvirtual = {a=false, b=false, c=false, d=false}
if name:sub(a , a ) == "1" then Lvirtual.d = true end 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+1, a+1) == "1" then Lvirtual.c = true end
if name:sub(a+2, a+2) == "1" then Lvirtual.b = true end if name:sub(a+2, a+2) == "1" then Lvirtual.b = true end

View File

@ -8,7 +8,7 @@
-- Pushes all block in front of it -- Pushes all block in front of it
-- Pull all blocks in its back -- Pull all blocks in its back
function mesecon.get_movestone_direction(pos) function mesecon:get_movestone_direction(pos)
getactivated = 0 getactivated = 0
local lpos local lpos
local getactivated = 0 local getactivated = 0
@ -28,28 +28,28 @@ function mesecon.get_movestone_direction(pos)
lpos = {x=pos.x+1, y=pos.y, z=pos.z} lpos = {x=pos.x+1, y=pos.y, z=pos.z}
for n = 1, 3 do 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} return {x=0, y=0, z=-1}
end end
end end
lpos = {x = pos.x-1, y = pos.y, z = pos.z} lpos = {x = pos.x-1, y = pos.y, z = pos.z}
for n=4, 6 do 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} return {x=0, y=0, z=1}
end end
end end
lpos = {x = pos.x, y = pos.y, z = pos.z+1} lpos = {x = pos.x, y = pos.y, z = pos.z+1}
for n=7, 9 do 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} return {x=-1, y=0, z=0}
end end
end end
lpos = {x = pos.x, y = pos.y, z = pos.z-1} lpos = {x = pos.x, y = pos.y, z = pos.z-1}
for n=10, 12 do 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} return {x=1, y=0, z=0}
end end
end end
@ -64,10 +64,10 @@ minetest.register_node("mesecons_movestones:movestone", {
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_on = function (pos, node) 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 if not direction then return end
minetest.remove_node(pos) minetest.remove_node(pos)
mesecon.on_dignode(pos, node) mesecon:update_autoconnect(pos)
minetest.add_entity(pos, "mesecons_movestones:movestone_entity") minetest.add_entity(pos, "mesecons_movestones:movestone_entity")
end end
}} }}
@ -89,35 +89,30 @@ minetest.register_entity("mesecons_movestones:movestone_entity", {
on_step = function(self, dtime) on_step = function(self, dtime)
local pos = self.object:getpos() 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) 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 if not direction then -- no mesecon power
--push only solid nodes --push only solid nodes
local name = minetest.get_node(pos).name local name = minetest.get_node(pos).name
if name ~= "air" and name ~= "ignore" if name ~= "air" and name ~= "ignore"
and ((not minetest.registered_nodes[name]) and ((not minetest.registered_nodes[name])
or minetest.registered_nodes[name].liquidtype == "none") then or minetest.registered_nodes[name].liquidtype == "none") then
mesecon.mvps_push(pos, self.lastdir, maxpush) mesecon:mvps_push(pos, self.lastdir, MOVESTONE_MAXIMUM_PUSH)
end end
local nn = {name="mesecons_movestones:movestone"} minetest.add_node(pos, {name="mesecons_movestones:movestone"})
minetest.add_node(pos, nn)
self.object:remove() self.object:remove()
mesecon.on_placenode(pos, nn)
return return
end end
local success, stack, oldstack = local success, stack, oldstack =
mesecon.mvps_push(pos, direction, maxpush) mesecon:mvps_push(pos, direction, MOVESTONE_MAXIMUM_PUSH)
if not success then -- Too large stack/stopper in the way if not success then -- Too large stack/stopper in the way
local nn = {name="mesecons_movestones:movestone"} minetest.add_node(pos, {name="mesecons_movestones:movestone"})
minetest.add_node(pos, nn)
self.object:remove() self.object:remove()
mesecon.on_placenode(pos, nn)
return return
else else
mesecon.mvps_process_stack (stack) mesecon:mvps_process_stack (stack)
mesecon.mvps_move_objects (pos, direction, oldstack) mesecon:mvps_move_objects (pos, direction, oldstack)
self.lastdir = direction self.lastdir = direction
end end
@ -148,10 +143,10 @@ minetest.register_node("mesecons_movestones:sticky_movestone", {
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_on = function (pos, node) 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 if not direction then return end
minetest.remove_node(pos) minetest.remove_node(pos)
mesecon.on_dignode(pos, node) mesecon:update_autoconnect(pos)
minetest.add_entity(pos, "mesecons_movestones:sticky_movestone_entity") minetest.add_entity(pos, "mesecons_movestones:sticky_movestone_entity")
end end
}} }}
@ -180,7 +175,7 @@ minetest.register_entity("mesecons_movestones:sticky_movestone_entity", {
on_step = function(self, dtime) on_step = function(self, dtime)
local pos = self.object:getpos() 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) 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 if not direction then -- no mesecon power
--push only solid nodes --push only solid nodes
@ -188,39 +183,34 @@ minetest.register_entity("mesecons_movestones:sticky_movestone_entity", {
if name ~= "air" and name ~= "ignore" if name ~= "air" and name ~= "ignore"
and ((not minetest.registered_nodes[name]) and ((not minetest.registered_nodes[name])
or minetest.registered_nodes[name].liquidtype == "none") then or minetest.registered_nodes[name].liquidtype == "none") then
mesecon.mvps_push(pos, self.lastdir, mesecon:mvps_push(pos, self.lastdir, MOVESTONE_MAXIMUM_PUSH)
mesecon.setting("movestone_max_push", 50))
--STICKY --STICKY
mesecon.mvps_pull_all(pos, self.lastdir) mesecon:mvps_pull_all(pos, self.lastdir)
end end
local nn = {name="mesecons_movestones:sticky_movestone"} minetest.add_node(pos, {name="mesecons_movestones:sticky_movestone"})
minetest.add_node(pos, nn)
self.object:remove() self.object:remove()
mesecon.on_placenode(pos, nn)
return return
end end
local success, stack, oldstack = local success, stack, oldstack =
mesecon.mvps_push(pos, direction, mesecon.setting("movestone_max_push", 50)) mesecon:mvps_push(pos, direction, MOVESTONE_MAXIMUM_PUSH)
if not success then -- Too large stack/stopper in the way if not success then -- Too large stack/stopper in the way
local nn = {name="mesecons_movestones:sticky_movestone"} minetest.add_node(pos, {name="mesecons_movestones:sticky_movestone"})
minetest.add_node(pos, nn)
self.object:remove() self.object:remove()
mesecon.on_placenode(pos, nn)
return return
else else
mesecon.mvps_process_stack (stack) mesecon:mvps_process_stack (stack)
mesecon.mvps_move_objects (pos, direction, oldstack) mesecon:mvps_move_objects (pos, direction, oldstack)
self.lastdir = direction self.lastdir = direction
end end
self.object:setvelocity({x=direction.x*2, y=direction.y*2, z=direction.z*2}) self.object:setvelocity({x=direction.x*2, y=direction.y*2, z=direction.z*2})
--STICKY --STICKY
mesecon.mvps_pull_all(pos, direction) mesecon:mvps_pull_all(pos, direction)
end, end,
}) })
mesecon.register_mvps_unmov("mesecons_movestones:movestone_entity") mesecon:register_mvps_unmov("mesecons_movestones:movestone_entity")
mesecon.register_mvps_unmov("mesecons_movestones:sticky_movestone_entity") mesecon:register_mvps_unmov("mesecons_movestones:sticky_movestone_entity")

View File

@ -4,7 +4,7 @@ mesecon.mvps_stoppers = {}
mesecon.mvps_unmov = {} mesecon.mvps_unmov = {}
mesecon.on_mvps_move = {} 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] local get_stopper = mesecon.mvps_stoppers[node.name]
if type (get_stopper) == "function" then if type (get_stopper) == "function" then
get_stopper = get_stopper(node, pushdir, stack, stackid) get_stopper = get_stopper(node, pushdir, stack, stackid)
@ -12,7 +12,7 @@ function mesecon.is_mvps_stopper(node, pushdir, stack, stackid)
return get_stopper return get_stopper
end end
function mesecon.register_mvps_stopper(nodename, get_stopper) function mesecon:register_mvps_stopper(nodename, get_stopper)
if get_stopper == nil then if get_stopper == nil then
get_stopper = true get_stopper = true
end end
@ -20,16 +20,16 @@ function mesecon.register_mvps_stopper(nodename, get_stopper)
end end
-- Objects that cannot be moved (e.g. movestones) -- 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; mesecon.mvps_unmov[objectname] = true;
end end
function mesecon.is_mvps_unmov(objectname) function mesecon:is_mvps_unmov(objectname)
return mesecon.mvps_unmov[objectname] return mesecon.mvps_unmov[objectname]
end end
-- Functions to be called on mvps movement -- 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 mesecon.on_mvps_move[#mesecon.on_mvps_move+1] = callback
end end
@ -39,14 +39,16 @@ local function on_mvps_move(moved_nodes)
end end
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 ) -- update mesecons for placed nodes ( has to be done after all nodes have been added )
for _, n in ipairs(stack) do for _, n in ipairs(stack) do
nodeupdate(n.pos)
mesecon.on_placenode(n.pos, minetest.get_node(n.pos)) mesecon.on_placenode(n.pos, minetest.get_node(n.pos))
mesecon:update_autoconnect(n.pos)
end end
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 -- determine the number of nodes to be pushed
local np = {x = pos.x, y = pos.y, z = pos.z} local np = {x = pos.x, y = pos.y, z = pos.z}
local nodes = {} local nodes = {}
@ -65,18 +67,18 @@ function mesecon.mvps_get_stack(pos, dir, maximum)
table.insert (nodes, {node = nn, pos = np}) table.insert (nodes, {node = nn, pos = np})
np = mesecon.addPosRule(np, dir) np = mesecon:addPosRule(np, dir)
end end
return nodes return nodes
end end
function mesecon.mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: direction of push; maximum: maximum nodes to be pushed 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) local nodes = mesecon:mvps_get_stack(pos, dir, maximum)
if not nodes then return end if not nodes then return end
-- determine if one of the nodes blocks the push -- determine if one of the nodes blocks the push
for id, n in ipairs(nodes) do 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 return
end end
end end
@ -90,21 +92,22 @@ 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 ) -- update mesecons for removed nodes ( has to be done after all nodes have been removed )
for _, n in ipairs(nodes) do for _, n in ipairs(nodes) do
mesecon.on_dignode(n.pos, n.node) mesecon.on_dignode(n.pos, n.node)
mesecon:update_autoconnect(n.pos)
end end
-- add nodes -- add nodes
for _, n in ipairs(nodes) do for _, n in ipairs(nodes) do
local np = mesecon.addPosRule(n.pos, dir) np = mesecon:addPosRule(n.pos, dir)
minetest.add_node(np, n.node) minetest.add_node(np, n.node)
minetest.get_meta(np):from_table(n.meta) minetest.get_meta(np):from_table(n.meta)
end end
local moved_nodes = {} local moved_nodes = {}
local oldstack = mesecon.tablecopy(nodes) local oldstack = mesecon:tablecopy(nodes)
for i in ipairs(nodes) do for i in ipairs(nodes) do
moved_nodes[i] = {} moved_nodes[i] = {}
moved_nodes[i].oldpos = nodes[i].pos 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].pos = nodes[i].pos
moved_nodes[i].node = nodes[i].node moved_nodes[i].node = nodes[i].node
moved_nodes[i].meta = nodes[i].meta moved_nodes[i].meta = nodes[i].meta
@ -115,20 +118,20 @@ function mesecon.mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: directio
return true, nodes, oldstack return true, nodes, oldstack
end end
mesecon.register_on_mvps_move(function(moved_nodes) mesecon:register_on_mvps_move(function(moved_nodes)
for _, n in ipairs(moved_nodes) do for _, n in ipairs(moved_nodes) do
mesecon.on_placenode(n.pos, n.node) mesecon.on_placenode(n.pos, n.node)
mesecon.update_autoconnect(n.pos) mesecon:update_autoconnect(n.pos)
end end
end) end)
function mesecon.mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons) 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) np = mesecon:addPosRule(pos, dir)
local nn = minetest.get_node(np) nn = minetest.get_node(np)
if ((not minetest.registered_nodes[nn.name]) --unregistered node if ((not minetest.registered_nodes[nn.name]) --unregistered node
or minetest.registered_nodes[nn.name].liquidtype == "none") --non-liquid 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() local meta = minetest.get_meta(np):to_table()
minetest.remove_node(np) minetest.remove_node(np)
minetest.add_node(pos, nn) minetest.add_node(pos, nn)
@ -137,13 +140,13 @@ function mesecon.mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: dire
nodeupdate(np) nodeupdate(np)
nodeupdate(pos) nodeupdate(pos)
mesecon.on_dignode(np, nn) mesecon.on_dignode(np, nn)
mesecon.update_autoconnect(np) mesecon:update_autoconnect(np)
on_mvps_move({{pos = pos, oldpos = np, node = nn, meta = meta}}) on_mvps_move({{pos = pos, oldpos = np, node = nn, meta = meta}})
end end
return {{pos = np, node = {param2 = 0, name = "air"}}, {pos = pos, node = nn}} return {{pos = np, node = {param2 = 0, name = "air"}}, {pos = pos, node = nn}}
end 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 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 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 local lpos2 = {x=pos.x-direction.x*2, y=pos.y-direction.y*2, z=pos.z-direction.z*2} -- 2 away
@ -172,7 +175,7 @@ function mesecon.mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: d
local meta = minetest.get_meta(lnode2):to_table() local meta = minetest.get_meta(lnode2):to_table()
minetest.add_node(oldpos, lnode2) minetest.add_node(oldpos, lnode2)
minetest.get_meta(oldpos):from_table(meta) minetest.get_meta(oldpos):from_table(meta)
moved_nodes[#moved_nodes+1] = {pos = oldpos, oldpos = lpos2, node = lnode2, meta = meta} moved_nodes[#moved_nodes+1] = {pos = oldpos, oldpos = lnode2, node = lnode2, meta = meta}
nodeupdate(oldpos) nodeupdate(oldpos)
oldpos = {x=lpos2.x, y=lpos2.y, z=lpos2.z} oldpos = {x=lpos2.x, y=lpos2.y, z=lpos2.z}
lpos2.x = lpos2.x-direction.x lpos2.x = lpos2.x-direction.x
@ -185,15 +188,15 @@ function mesecon.mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: d
and minetest.registered_nodes[lnode.name].liquidtype ~= "none") and minetest.registered_nodes[lnode.name].liquidtype ~= "none")
minetest.remove_node(oldpos) minetest.remove_node(oldpos)
mesecon.on_dignode(oldpos, lnode2) mesecon.on_dignode(oldpos, lnode2)
mesecon.update_autoconnect(oldpos) mesecon:update_autoconnect(oldpos)
on_mvps_move(moved_nodes) on_mvps_move(moved_nodes)
end end
function mesecon.mvps_move_objects(pos, dir, nodestack) function mesecon:mvps_move_objects(pos, dir, nodestack)
local objects_to_move = {} local objects_to_move = {}
-- Move object at tip of stack -- 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, {x = dir.x * #nodestack,
y = dir.y * #nodestack, y = dir.y * #nodestack,
z = dir.z * #nodestack}) z = dir.z * #nodestack})
@ -208,7 +211,7 @@ function mesecon.mvps_move_objects(pos, dir, nodestack)
if tonumber(minetest.setting_get("movement_gravity")) > 0 and dir.y == 0 then 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 -- If gravity positive and dir horizontal, push players standing on the stack
for _, n in ipairs(nodestack) do 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) local objects = minetest.get_objects_inside_radius(p_above, 1)
for _, obj in ipairs(objects) do for _, obj in ipairs(objects) do
table.insert(objects_to_move, obj) table.insert(objects_to_move, obj)
@ -218,8 +221,8 @@ function mesecon.mvps_move_objects(pos, dir, nodestack)
for _, obj in ipairs(objects_to_move) do for _, obj in ipairs(objects_to_move) do
local entity = obj:get_luaentity() local entity = obj:get_luaentity()
if not entity or not mesecon.is_mvps_unmov(entity.name) then if not entity or not mesecon:is_mvps_unmov(entity.name) then
local np = mesecon.addPosRule(obj:getpos(), dir) local np = mesecon:addPosRule(obj:getpos(), dir)
--move only if destination is not solid --move only if destination is not solid
local nn = minetest.get_node(np) local nn = minetest.get_node(np)
@ -231,5 +234,5 @@ function mesecon.mvps_move_objects(pos, dir, nodestack)
end end
end end
mesecon.register_mvps_stopper("default:chest_locked") mesecon:register_mvps_stopper("default:chest_locked")
mesecon.register_mvps_stopper("default:furnace") mesecon:register_mvps_stopper("default:furnace")

View File

@ -2,6 +2,7 @@ minetest.register_node("mesecons_noteblock:noteblock", {
description = "Noteblock", description = "Noteblock",
tiles = {"mesecons_noteblock.png"}, tiles = {"mesecons_noteblock.png"},
groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2}, groups = {snappy=2,choppy=2,oddly_breakable_by_hand=2},
drawtype = "allfaces_optional",
visual_scale = 1.3, visual_scale = 1.3,
paramtype="light", paramtype="light",
after_place_node = function(pos) after_place_node = function(pos)
@ -61,15 +62,9 @@ mesecon.noteblock_play = function (pos, param2)
if block_below_name == "default:glass" then if block_below_name == "default:glass" then
soundname="mesecons_noteblock_hihat" soundname="mesecons_noteblock_hihat"
end end
if block_below_name == "default:steelblock" then
soundname=soundname.."2" -- Go up an octave.
end
if block_below_name == "default:stone" then if block_below_name == "default:stone" then
soundname="mesecons_noteblock_kick" soundname="mesecons_noteblock_kick"
end end
if block_below_name == "default:lava_source" then
soundname="fire_large"
end
if block_below_name == "default:chest" then if block_below_name == "default:chest" then
soundname="mesecons_noteblock_snare" soundname="mesecons_noteblock_snare"
end end
@ -79,9 +74,6 @@ mesecon.noteblock_play = function (pos, param2)
if block_below_name == "default:wood" then if block_below_name == "default:wood" then
soundname="mesecons_noteblock_litecrash" soundname="mesecons_noteblock_litecrash"
end end
if block_below_name == "default:coalblock" then
soundname="tnt_explode"
end
minetest.sound_play(soundname, minetest.sound_play(soundname,
{pos = pos, gain = 1.0, max_hear_distance = 32,}) {pos = pos, gain = 1.0, max_hear_distance = 32,})
end end

View File

@ -33,7 +33,7 @@ local piston_down_rules =
local piston_get_rules = function (node) local piston_get_rules = function (node)
local rules = piston_rules local rules = piston_rules
for i = 1, node.param2 do for i = 1, node.param2 do
rules = mesecon.rotate_rules_left(rules) rules = mesecon:rotate_rules_left(rules)
end end
return rules return rules
end end
@ -41,7 +41,7 @@ end
piston_facedir_direction = function (node) piston_facedir_direction = function (node)
local rules = {{x = 0, y = 0, z = -1}} local rules = {{x = 0, y = 0, z = -1}}
for i = 1, node.param2 do for i = 1, node.param2 do
rules = mesecon.rotate_rules_left(rules) rules = mesecon:rotate_rules_left(rules)
end end
return rules[1] return rules[1]
end end
@ -55,16 +55,15 @@ piston_get_direction = function(dir, node)
end end
local piston_remove_pusher = function(pos, node) local piston_remove_pusher = function(pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local dir = piston_get_direction(pistonspec.dir, node) if pushername == pistonspec.pusher then --make sure there actually is a pusher (for compatibility reasons mainly)
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 return
end 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.remove_node(pusherpos)
minetest.sound_play("piston_retract", { minetest.sound_play("piston_retract", {
pos = pos, pos = pos,
@ -78,9 +77,8 @@ local piston_on = function(pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local dir = piston_get_direction(pistonspec.dir, node) local dir = piston_get_direction(pistonspec.dir, node)
local np = mesecon.addPosRule(pos, dir) local np = mesecon:addPosRule(pos, dir)
local maxpush = mesecon.setting("piston_max_push", 15) local success, stack, oldstack = mesecon:mvps_push(np, dir, PISTON_MAXIMUM_PUSH)
local success, stack, oldstack = mesecon.mvps_push(np, dir, maxpush)
if success then if success then
minetest.add_node(pos, {param2 = node.param2, name = pistonspec.onname}) minetest.add_node(pos, {param2 = node.param2, name = pistonspec.onname})
minetest.add_node(np, {param2 = node.param2, name = pistonspec.pusher}) minetest.add_node(np, {param2 = node.param2, name = pistonspec.pusher})
@ -89,8 +87,8 @@ local piston_on = function(pos, node)
max_hear_distance = 20, max_hear_distance = 20,
gain = 0.3, gain = 0.3,
}) })
mesecon.mvps_process_stack (stack) mesecon:mvps_process_stack (stack)
mesecon.mvps_move_objects (np, dir, oldstack) mesecon:mvps_move_objects (np, dir, oldstack)
end end
end end
@ -100,10 +98,10 @@ local piston_off = function(pos, node)
piston_remove_pusher(pos, node) piston_remove_pusher(pos, node)
if pistonspec.sticky then if pistonspec.sticky then
local dir = piston_get_direction(pistonspec.dir, node) dir = piston_get_direction(pistonspec.dir, node)
local pullpos = mesecon.addPosRule(pos, dir) pullpos = mesecon:addPosRule(pos, dir)
local stack = mesecon.mvps_pull_single(pullpos, dir) stack = mesecon:mvps_pull_single(pullpos, dir)
mesecon.mvps_process_stack(pos, dir, stack) mesecon:mvps_process_stack(pos, dir, stack)
end end
end end
@ -694,14 +692,14 @@ local piston_pusher_up_down_get_stopper = function (node, dir, stack, stackid)
return true return true
end end
mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_normal", 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_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_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_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_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_sticky", piston_pusher_up_down_get_stopper)
-- Register pistons as stoppers if they would be seperated from the stopper -- Register pistons as stoppers if they would be seperated from the stopper
@ -718,12 +716,12 @@ end
local piston_get_stopper = function (node, dir, stack, stackid) local piston_get_stopper = function (node, dir, stack, stackid)
pistonspec = minetest.registered_nodes[node.name].mesecons_piston pistonspec = minetest.registered_nodes[node.name].mesecons_piston
dir = piston_get_direction(pistonspec.dir, node) 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) local pushernode = minetest.get_node(pusherpos)
if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then
for _, s in ipairs(stack) do 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 and s.node.param2 == node.param2 then
return false return false
end end
@ -732,14 +730,14 @@ local piston_get_stopper = function (node, dir, stack, stackid)
return true return true
end end
mesecon.register_mvps_stopper("mesecons_pistons:piston_normal_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_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_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_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_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_sticky_on", piston_up_down_get_stopper)
--craft recipes --craft recipes
minetest.register_craft({ minetest.register_craft({

View File

@ -26,6 +26,6 @@ minetest.register_craft({
recipe = { recipe = {
{"group:mesecon_conductor_craftable"}, {"group:mesecon_conductor_craftable"},
{"group:mesecon_conductor_craftable"}, {"group:mesecon_conductor_craftable"},
{"group:sapling"}, {"default:sapling"},
} }
}) })

View File

@ -10,24 +10,30 @@ local pp_box_on = {
pp_on_timer = function (pos, elapsed) pp_on_timer = function (pos, elapsed)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local basename = minetest.registered_nodes[node.name].pressureplate_basename local ppspec = minetest.registered_nodes[node.name].pressureplate
-- This is a workaround for a strange bug that occurs when the server is started -- 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 -- For some reason the first time on_timer is called, the pos is wrong
if not basename then return end if not ppspec then return end
local objs = minetest.get_objects_inside_radius(pos, 1) 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 == basename .. "_on" then if objs[1] == nil and node.name == ppspec.onstate then
minetest.add_node(pos, {name = basename .. "_off"}) minetest.add_node(pos, {name = ppspec.offstate})
mesecon.receptor_off(pos, mesecon.rules.pplate) mesecon:receptor_off(pos)
-- force deactivation of mesecon two blocks below (hacky)
if not mesecon:connected_to_receptor(two_below) then
mesecon:turnoff(two_below)
end
else else
for k, obj in pairs(objs) do for k, obj in pairs(objs) do
local objpos = obj:getpos() local objpos = obj:getpos()
if objpos.y > pos.y-1 and objpos.y < pos.y then if objpos.y > pos.y-1 and objpos.y < pos.y then
minetest.add_node(pos, {name = basename .. "_on"}) minetest.add_node(pos, {name=ppspec.onstate})
mesecon.receptor_on(pos, mesecon.rules.pplate ) mesecon:receptor_on(pos)
-- force activation of mesecon two blocks below (hacky)
mesecon:turnon(two_below)
end end
end end
end end
@ -43,40 +49,66 @@ end
-- image: inventory and wield image of the pressure plate -- image: inventory and wield image of the pressure plate
-- recipe: crafting recipe of the pressure plate -- recipe: crafting recipe of the pressure plate
function mesecon.register_pressure_plate(basename, description, textures_off, textures_on, image_w, image_i, recipe) function mesecon:register_pressure_plate(offstate, onstate, description, textures_off, textures_on, image_w, image_i, recipe)
mesecon.register_node(basename, { local ppspec = {
offstate = offstate,
onstate = onstate
}
minetest.register_node(offstate, {
drawtype = "nodebox", drawtype = "nodebox",
tiles = textures_off,
inventory_image = image_i, inventory_image = image_i,
wield_image = image_w, wield_image = image_w,
paramtype = "light", paramtype = "light",
description = description,
pressureplate_basename = basename,
on_timer = pp_on_timer,
on_construct = function(pos)
minetest.get_node_timer(pos):start(mesecon.setting("pplate_interval", 0.1))
end,
},{
mesecons = {receptor = { state = mesecon.state.off, rules = mesecon.rules.pplate }},
node_box = pp_box_off,
selection_box = pp_box_off, selection_box = pp_box_off,
node_box = pp_box_off,
groups = {snappy = 2, oddly_breakable_by_hand = 3}, groups = {snappy = 2, oddly_breakable_by_hand = 3},
tiles = textures_off description = description,
},{ pressureplate = ppspec,
mesecons = {receptor = { state = mesecon.state.on, rules = mesecon.rules.pplate }}, on_timer = pp_on_timer,
node_box = pp_box_on, mesecons = {receptor = {
state = mesecon.state.off
}},
on_construct = function(pos)
minetest.get_node_timer(pos):start(PRESSURE_PLATE_INTERVAL)
end,
})
minetest.register_node(onstate, {
drawtype = "nodebox",
tiles = textures_on,
paramtype = "light",
selection_box = pp_box_on, selection_box = pp_box_on,
node_box = pp_box_on,
groups = {snappy = 2, oddly_breakable_by_hand = 3, not_in_creative_inventory = 1}, groups = {snappy = 2, oddly_breakable_by_hand = 3, not_in_creative_inventory = 1},
tiles = textures_on 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
}) })
minetest.register_craft({ minetest.register_craft({
output = basename .. "_off", output = offstate,
recipe = recipe, recipe = recipe,
}) })
end end
mesecon.register_pressure_plate( mesecon:register_pressure_plate(
"mesecons_pressureplates:pressure_plate_wood", "mesecons_pressureplates:pressure_plate_wood_off",
"mesecons_pressureplates:pressure_plate_wood_on",
"Wooden Pressure Plate", "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_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"}, {"jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on_edges.png"},
@ -84,8 +116,9 @@ mesecon.register_pressure_plate(
"jeija_pressure_plate_wood_inv.png", "jeija_pressure_plate_wood_inv.png",
{{"group:wood", "group:wood"}}) {{"group:wood", "group:wood"}})
mesecon.register_pressure_plate( mesecon:register_pressure_plate(
"mesecons_pressureplates:pressure_plate_stone", "mesecons_pressureplates:pressure_plate_stone_off",
"mesecons_pressureplates:pressure_plate_stone_on",
"Stone Pressure Plate", "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_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"}, {"jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on_edges.png"},

View File

@ -9,7 +9,7 @@ minetest.register_node("mesecons_random:removestone", {
mesecons = {effector = { mesecons = {effector = {
action_on = function (pos, node) action_on = function (pos, node)
minetest.remove_node(pos) minetest.remove_node(pos)
mesecon.update_autoconnect(pos) mesecon:update_autoconnect(pos)
end end
}} }}
}) })

View File

@ -1,19 +1,19 @@
rcvboxes = { rcvboxes = {
{ -3/16, -3/16, -8/16 , 3/16, 3/16 , -13/32 }, -- the smaller bump { -3/16, -3/16 , -8/16 , 3/16, 3/16, -13/32 }, -- the smaller bump
{ -1/32, -1/32, -3/2 , 1/32, 1/32 , -1/2 }, -- the wire through the block { -1/32, -1/32 , -3/2 , 1/32, 1/32, -1/2 }, -- the wire through the block
{ -2/32, -1/2 , -.5 , 2/32, 0 , -.5002+3/32 }, -- the vertical wire bit { -2/32, -.5-1/32, -.5 , 2/32, 0 , -.5002+3/32 }, -- the vertical wire bit
{ -2/32, -1/2 , -7/16+0.002 , 2/32, -14/32, 16/32+0.001 } -- the horizontal wire { -2/32, -17/32 , -7/16+0.002 , 2/32, -14/32, 16/32+0.001 } -- the horizontal wire
} }
local receiver_get_rules = function (node) local receiver_get_rules = function (node)
local rules = { {x = 1, y = 0, z = 0}, local rules = { {x = 1, y = 0, z = 0},
{x = -2, y = 0, z = 0}} {x = -2, y = 0, z = 0}}
if node.param2 == 2 then if node.param2 == 2 then
rules = mesecon.rotate_rules_left(rules) rules = mesecon:rotate_rules_left(rules)
elseif node.param2 == 3 then 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 elseif node.param2 == 0 then
rules = mesecon.rotate_rules_right(rules) rules = mesecon:rotate_rules_right(rules)
end end
return rules return rules
end end
@ -81,76 +81,83 @@ minetest.register_node("mesecons_receiver:receiver_off", {
}} }}
}) })
function mesecon.receiver_get_pos_from_rcpt(pos, param2) mesecon:add_rules("receiver_pos", {{x = 2, y = 0, z = 0}})
local rules = {{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")
if param2 == nil then param2 = minetest.get_node(pos).param2 end if param2 == nil then param2 = minetest.get_node(pos).param2 end
if param2 == 2 then if param2 == 2 then
rules = mesecon.rotate_rules_left(rules) rules = mesecon:rotate_rules_left(rules)
elseif param2 == 3 then 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 elseif param2 == 0 then
rules = mesecon.rotate_rules_right(rules) rules = mesecon:rotate_rules_right(rules)
end end
local np = { x = pos.x + rules[1].x, np = {
x = pos.x + rules[1].x,
y = pos.y + rules[1].y, y = pos.y + rules[1].y,
z = pos.z + rules[1].z} z = pos.z + rules[1].z}
return np return np
end end
function mesecon.receiver_place(rcpt_pos) function mesecon:receiver_place(rcpt_pos)
local node = minetest.get_node(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) local nn = minetest.get_node(pos)
if string.find(nn.name, "mesecons:wire_") ~= nil then if string.find(nn.name, "mesecons:wire_") ~= nil then
minetest.dig_node(pos) 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}) 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 else
minetest.add_node(pos, {name = "mesecons_receiver:receiver_off", param2 = node.param2}) minetest.add_node(pos, {name = "mesecons_receiver:receiver_off", param2 = node.param2})
end end
mesecon.update_autoconnect(pos) mesecon:update_autoconnect(pos)
end end
end end
function mesecon.receiver_remove(rcpt_pos, dugnode) function mesecon:receiver_remove(rcpt_pos, dugnode)
local pos = mesecon.receiver_get_pos_from_rcpt(rcpt_pos, dugnode.param2) local pos = mesecon:receiver_get_pos_from_rcpt(rcpt_pos, dugnode.param2)
local nn = minetest.get_node(pos) local nn = minetest.get_node(pos)
if string.find(nn.name, "mesecons_receiver:receiver_") ~=nil then if string.find(nn.name, "mesecons_receiver:receiver_") ~=nil then
minetest.dig_node(pos) minetest.dig_node(pos)
local node = {name = "mesecons:wire_00000000_off"} local node = {name = "mesecons:wire_00000000_off"}
minetest.add_node(pos, node) minetest.add_node(pos, node)
mesecon.update_autoconnect(pos) mesecon:update_autoconnect(pos)
mesecon.on_placenode(pos, node) mesecon.on_placenode(pos, node)
end end
end end
minetest.register_on_placenode(function (pos, node) minetest.register_on_placenode(function (pos, node)
if minetest.get_item_group(node.name, "mesecon_needs_receiver") == 1 then if minetest.get_item_group(node.name, "mesecon_needs_receiver") == 1 then
mesecon.receiver_place(pos) mesecon:receiver_place(pos)
end end
end) end)
minetest.register_on_dignode(function(pos, node) minetest.register_on_dignode(function(pos, node)
if minetest.get_item_group(node.name, "mesecon_needs_receiver") == 1 then if minetest.get_item_group(node.name, "mesecon_needs_receiver") == 1 then
mesecon.receiver_remove(pos, node) mesecon:receiver_remove(pos, node)
end end
end) end)
minetest.register_on_placenode(function (pos, node) minetest.register_on_placenode(function (pos, node)
if string.find(node.name, "mesecons:wire_") ~=nil then if string.find(node.name, "mesecons:wire_") ~=nil then
local rules = { {x = 2, y = 0, z = 0}, rules = mesecon:get_rules("receiver_pos_all")
{x =-2, y = 0, z = 0},
{x = 0, y = 0, z = 2},
{x = 0, y = 0, z =-2}}
local i = 1 local i = 1
while rules[i] ~= nil do while rules[i] ~= nil do
local np = { x = pos.x + rules[i].x, np = {
x = pos.x + rules[i].x,
y = pos.y + rules[i].y, y = pos.y + rules[i].y,
z = pos.z + rules[i].z} z = pos.z + rules[i].z}
if minetest.get_item_group(minetest.get_node(np).name, "mesecon_needs_receiver") == 1 then if minetest.get_item_group(minetest.get_node(np).name, "mesecon_needs_receiver") == 1 then
mesecon.receiver_place(np) mesecon:receiver_place(np)
end end
i = i + 1 i = i + 1
end end

View File

@ -75,7 +75,7 @@ minetest.register_abm(
if light >= 12 then if light >= 12 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2}) minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2})
mesecon.receptor_on(pos) mesecon:receptor_on(pos)
end end
end, end,
}) })
@ -89,7 +89,7 @@ minetest.register_abm(
if light < 12 then if light < 12 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2}) minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2})
mesecon.receptor_off(pos) mesecon:receptor_off(pos)
end end
end, end,
}) })

View File

@ -1,29 +1,35 @@
-- MESECON_SWITCH -- MESECON_SWITCH
mesecon.register_node("mesecons_switch: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"},
paramtype2="facedir", paramtype2="facedir",
groups = {dig_immediate=2},
description="Switch", description="Switch",
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
on_punch = function (pos, node) mesecons = {receptor = {
if(mesecon.flipstate(pos, node) == "on") then state = mesecon.state.off
mesecon.receptor_on(pos) }},
else on_punch = function(pos, node)
mesecon.receptor_off(pos) minetest.swap_node(pos, {name = "mesecons_switch:mesecon_switch_on", param2 = node.param2})
end 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)
minetest.sound_play("mesecons_switch", {pos=pos}) minetest.sound_play("mesecons_switch", {pos=pos})
end 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({ minetest.register_craft({

View File

@ -2,15 +2,15 @@
local rotate_torch_rules = function (rules, param2) local rotate_torch_rules = function (rules, param2)
if param2 == 5 then if param2 == 5 then
return mesecon.rotate_rules_right(rules) return mesecon:rotate_rules_right(rules)
elseif param2 == 2 then 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 elseif param2 == 4 then
return mesecon.rotate_rules_left(rules) return mesecon:rotate_rules_left(rules)
elseif param2 == 1 then elseif param2 == 1 then
return mesecon.rotate_rules_down(rules) return mesecon:rotate_rules_down(rules)
elseif param2 == 0 then elseif param2 == 0 then
return mesecon.rotate_rules_up(rules) return mesecon:rotate_rules_up(rules)
else else
return rules return rules
end end
@ -91,8 +91,8 @@ minetest.register_abm({
action = function(pos, node) action = function(pos, node)
local is_powered = false local is_powered = false
for _, rule in ipairs(torch_get_input_rules(node)) do for _, rule in ipairs(torch_get_input_rules(node)) do
local src = mesecon.addPosRule(pos, rule) local src = mesecon:addPosRule(pos, rule)
if mesecon.is_power_on(src) then if mesecon:is_power_on(src) then
is_powered = true is_powered = true
end end
end end
@ -100,11 +100,11 @@ minetest.register_abm({
if is_powered then if is_powered then
if node.name == "mesecons_torch:mesecon_torch_on" then if node.name == "mesecons_torch:mesecon_torch_on" then
minetest.swap_node(pos, {name = "mesecons_torch:mesecon_torch_off", param2 = node.param2}) 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 end
elseif node.name == "mesecons_torch:mesecon_torch_off" then elseif node.name == "mesecons_torch:mesecon_torch_off" then
minetest.swap_node(pos, {name = "mesecons_torch:mesecon_torch_on", param2 = node.param2}) 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
end end
}) })

View File

@ -1,11 +1,18 @@
-- WALL LEVER -- WALL LEVER
-- Basically a switch that can be attached to a wall -- Basically a switch that can be attached to a wall
-- Powers the block 2 nodes behind (using a receiver) -- Powers the block 2 nodes behind (using a receiver)
mesecon.register_node("mesecons_walllever:wall_lever", { minetest.register_node("mesecons_walllever:wall_lever_off", {
description="Lever", drawtype = "nodebox",
drawtype = "mesh", tiles = {
inventory_image = "jeija_wall_lever_inv.png", "jeija_wall_lever_tb.png",
wield_image = "jeija_wall_lever_inv.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", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
sunlight_propagates = true, sunlight_propagates = true,
@ -14,31 +21,68 @@ mesecon.register_node("mesecons_walllever:wall_lever", {
type = "fixed", type = "fixed",
fixed = { -8/16, -8/16, 3/16, 8/16, 8/16, 8/16 }, fixed = { -8/16, -8/16, 3/16, 8/16, 8/16, 8/16 },
}, },
sounds = default.node_sound_wood_defaults(), 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
{ -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) on_punch = function (pos, node)
if(mesecon.flipstate(pos, node) == "on") then minetest.swap_node(pos, {name = "mesecons_walllever:wall_lever_on", param2 = node.param2})
mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node)) 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}) minetest.sound_play("mesecons_lever", {pos=pos})
end end,
},{ sounds = default.node_sound_wood_defaults(),
tiles = { "jeija_wall_lever_off.png" },
mesh="jeija_wall_lever_off.obj",
mesecons = {receptor = { mesecons = {receptor = {
rules = mesecon.rules.buttonlike_get, rules = mesecon.rules.buttonlike_get,
state = mesecon.state.off state = mesecon.state.off
}}, }}
groups = {dig_immediate = 2, mesecon_needs_receiver = 1} })
},{ minetest.register_node("mesecons_walllever:wall_lever_on", {
tiles = { "jeija_wall_lever_on.png" }, drawtype = "nodebox",
mesh="jeija_wall_lever_on.obj", tiles = {
"jeija_wall_lever_top.png",
"jeija_wall_lever_tb.png",
"jeija_wall_lever_sides.png",
"jeija_wall_lever_sides.png",
"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
{ -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 = { mesecons = {receptor = {
rules = mesecon.rules.buttonlike_get, rules = mesecon.rules.buttonlike_get,
state = mesecon.state.on state = mesecon.state.on
}}, }}
groups = {dig_immediate = 2, mesecon_needs_receiver = 1, not_in_creative_inventory = 1}
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -1,263 +0,0 @@
# Blender v2.73 (sub 0) OBJ File: 'mesecons-wall-lever-off.blend'
# www.blender.org
o nodebox-5
v 0.289062 0.156250 0.312500
v -0.375000 0.375000 0.375000
v -0.375000 -0.375000 0.375000
v 0.332500 0.207500 0.375000
v 0.332500 -0.207500 0.375000
v 0.375000 0.375000 0.375000
v 0.375000 -0.375000 0.375000
v 0.289062 -0.156250 0.312500
v -0.062500 -0.036146 0.200392
v -0.062500 -0.068498 0.321133
v -0.062500 -0.394498 0.233782
v -0.062500 -0.362146 0.113041
v -0.332500 0.207500 0.375000
v 0.062500 -0.036146 0.200392
v 0.062500 -0.068498 0.321133
v -0.332500 -0.207500 0.375000
v 0.332500 0.207500 0.375000
v 0.062500 -0.394498 0.233782
v 0.062500 -0.362146 0.113041
v 0.332500 -0.207500 0.375000
v 0.375000 -0.375000 0.375000
v 0.375000 -0.375000 0.500000
v 0.375000 0.375000 0.500000
v 0.375000 0.375000 0.375000
v -0.375000 -0.375000 0.375000
v -0.375000 -0.375000 0.500000
v -0.375000 0.375000 0.500000
v -0.375000 0.375000 0.375000
v -0.289062 0.156250 0.312500
v -0.332500 0.207500 0.375000
v -0.332500 -0.207500 0.375000
v -0.289062 -0.156250 0.312500
v -0.250000 0.125000 0.312500
v -0.250000 -0.125000 0.312500
v 0.250000 0.125000 0.312500
v 0.250000 -0.125000 0.312500
v -0.250000 -0.000000 0.250000
v -0.000000 -0.125000 0.250000
v 0.250000 -0.000000 0.250000
v 0.000000 0.125000 0.250000
v -0.250000 0.125000 0.250000
v -0.250000 0.125000 0.312500
v -0.250000 -0.125000 0.312500
v -0.250000 -0.125000 0.250000
v 0.250000 0.125000 0.250000
v 0.250000 0.125000 0.312500
v 0.250000 -0.125000 0.312500
v 0.250000 -0.125000 0.250000
v 0.250000 -0.125000 0.250000
v 0.250000 0.125000 0.250000
v -0.250000 -0.125000 0.250000
v -0.250000 0.125000 0.250000
v 0.125000 -0.062500 0.187500
v 0.125000 0.062500 0.187500
v -0.125000 -0.062500 0.187500
v -0.125000 0.062500 0.187500
v 0.065000 -0.032500 0.176992
v 0.065000 0.032500 0.176992
v -0.065000 -0.032500 0.176992
v -0.065000 0.032500 0.176992
v 0.000000 0.125000 0.250000
v 0.250000 -0.000000 0.250000
v -0.000000 -0.125000 0.250000
v -0.250000 -0.000000 0.250000
v 0.000000 0.062500 0.187500
v -0.187500 -0.093750 0.208750
v 0.125000 -0.000000 0.187500
v 0.000000 -0.062500 0.187500
v -0.125000 -0.000000 0.187500
v 0.187500 0.093750 0.208750
v 0.187500 -0.093750 0.208750
v -0.187500 0.093750 0.208750
v 0.000000 0.093750 0.208750
v 0.000000 -0.093750 0.208750
v 0.187500 -0.000000 0.208750
v -0.187500 -0.000000 0.208750
vt 0.416667 0.416667
vt 0.083333 0.416667
vt 0.055556 0.472222
vt 0.444444 0.472222
vt 0.083333 0.083333
vt 0.055556 0.027778
vt 0.444444 0.027778
vt 0.416667 0.083333
vt 0.472222 0.055556
vt 0.472222 0.444444
vt 0.027778 0.055556
vt 0.027778 0.444444
vt 0.250000 0.833333
vt 0.250000 0.638889
vt 0.305556 0.638889
vt 0.305556 0.833333
vt 0.388889 0.777778
vt 0.333333 0.777778
vt 0.333333 0.722222
vt 0.388889 0.722222
vt 0.944444 0.527778
vt 0.944444 0.916667
vt 1.000000 0.916667
vt 1.000000 0.527778
vt 0.500000 0.527778
vt 0.555556 0.527778
vt 0.555556 0.916667
vt 0.500000 0.916667
vt 0.138889 0.833333
vt 0.194444 0.833333
vt 0.194444 0.638889
vt 0.138889 0.638889
vt 0.944444 0.472222
vt 0.555556 0.472222
vt 0.555556 0.972222
vt 0.944444 0.972222
vt 0.888802 0.166753
vt 0.555642 0.166753
vt 0.527778 0.138889
vt 0.916667 0.138889
vt 0.888802 0.388802
vt 0.916667 0.416667
vt 0.527778 0.416667
vt 0.555642 0.388802
vt 0.361111 0.361111
vt 0.250000 0.361111
vt 0.138889 0.361111
vt 0.138889 0.416667
vt 0.361111 0.416667
vt 0.361111 0.083333
vt 0.361111 0.138889
vt 0.138889 0.138889
vt 0.138889 0.083333
vt 0.250000 0.083333
vt 0.416667 0.361111
vt 0.416667 0.138889
vt 0.416667 0.250000
vt 0.138889 0.250000
vt 0.083333 0.138889
vt 0.083333 0.361111
vt 0.083333 0.638889
vt 0.083333 0.833333
vt 0.444444 0.611111
vt 0.055556 0.611111
vt 0.027778 0.527778
vt 0.472222 0.527778
vt 0.444444 0.888889
vt 0.472222 0.972222
vt 0.055556 0.888889
vt 0.027778 0.972222
vt 0.722222 0.361111
vt 0.583333 0.361111
vt 0.722222 0.388802
vt 0.833333 0.333333
vt 0.777778 0.305556
vt 0.777778 0.250000
vt 0.833333 0.222222
vt 0.833333 0.277778
vt 0.722222 0.194444
vt 0.722222 0.166753
vt 0.861111 0.194444
vt 0.583333 0.277778
vt 0.583333 0.194444
vt 0.555642 0.277778
vt 0.861111 0.277778
vt 0.888802 0.277778
vt 0.861111 0.361111
vt 0.666667 0.250000
vt 0.666667 0.305556
vt 0.611111 0.222222
vt 0.722222 0.222222
vt 0.611111 0.333333
vt 0.611111 0.277778
vt 0.722222 0.333333
vn 0.000000 0.773300 -0.634100
vn 0.000000 -0.773300 -0.634100
vn -0.821200 0.000000 -0.570700
vn 0.821200 0.000000 -0.570700
vn 0.000000 -0.258800 0.965900
vn 0.000000 -0.965900 -0.258800
vn 1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn 0.000000 0.258800 -0.965900
vn 0.000000 -0.000000 1.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.688800 -0.724900
vn -0.269900 0.421500 -0.865700
vn -0.395600 0.336800 -0.854500
vn 0.000000 0.797100 -0.603900
vn -0.142400 0.274900 -0.950900
vn -0.056900 0.142700 -0.988100
vn -0.056900 -0.142700 -0.988100
vn -0.142400 -0.274900 -0.950900
vn -0.247900 0.000000 -0.968700
vn 0.000000 -0.688800 -0.724900
vn 0.000000 -0.797100 -0.603900
vn -0.395600 -0.336800 -0.854500
vn -0.269900 -0.421500 -0.865700
vn 0.440000 0.000000 -0.898000
vn 0.269900 0.421500 -0.865700
vn 0.395600 0.336800 -0.854500
vn 0.550800 0.000000 -0.834600
vn -0.440000 0.000000 -0.898000
vn -0.550800 0.000000 -0.834600
vn 0.056900 -0.142700 -0.988100
vn 0.056900 0.142700 -0.988100
vn 0.142400 -0.274900 -0.950900
vn 0.000000 -0.450200 -0.892900
vn 0.142400 0.274900 -0.950900
vn 0.247900 0.000000 -0.968700
vn 0.000000 0.450200 -0.892900
vn 0.269900 -0.421500 -0.865700
vn 0.395600 -0.336800 -0.854500
s off
f 1/1/1 29/2/1 30/3/1 4/4/1
f 8/5/2 5/6/2 31/7/2 32/8/2
f 32/8/3 31/9/3 30/10/3 29/1/3
f 8/2/4 1/5/4 4/11/4 5/12/4
f 18/13/5 15/14/5 10/15/5 11/16/5
f 19/17/6 18/18/6 11/19/6 12/20/6
f 21/21/7 24/22/7 23/23/7 22/24/7
f 25/25/8 26/26/8 27/27/8 28/28/8
f 19/29/9 12/30/9 9/31/9 14/32/9
f 22/26/10 23/21/10 27/22/10 26/27/10
f 21/33/11 22/21/11 26/26/11 25/34/11
f 24/22/12 28/27/12 27/35/12 23/36/12
f 34/37/13 36/38/13 8/39/13 32/40/13
f 33/41/13 34/37/13 32/40/13 29/42/13
f 33/41/13 29/42/13 1/43/13 35/44/13
f 35/44/13 1/43/13 8/39/13 36/38/13
f 45/45/12 40/46/12 41/47/12 42/48/12 46/49/12
f 48/50/11 47/51/11 43/52/11 44/53/11 38/54/11
f 44/55/8 43/45/8 42/51/8 41/56/8 37/57/8
f 48/47/7 39/58/7 45/52/7 46/59/7 47/60/7
f 12/13/8 11/30/8 10/31/8 9/14/8
f 19/29/7 14/32/7 15/61/7 18/62/7
f 16/63/13 20/64/13 7/65/13 3/66/13
f 13/67/13 16/63/13 3/66/13 2/68/13
f 17/69/13 6/70/13 7/65/13 20/64/13
f 13/67/13 2/68/13 6/70/13 17/69/13
s 1
f 73/71/14 72/72/15 52/44/16 61/73/17
f 56/74/18 60/75/19 59/76/20 55/77/21 69/78/22
f 74/79/23 63/80/24 51/37/25 66/81/26
f 75/82/27 70/83/28 50/38/29 62/84/30
f 76/85/31 64/86/32 52/41/16 72/87/15
f 57/88/33 59/76/20 60/75/19 58/89/34
f 55/77/21 59/76/20 57/88/33 53/90/35 68/91/36
f 53/90/35 57/88/33 58/89/34 54/92/37 67/93/38
f 54/92/37 58/89/34 60/75/19 56/74/18 65/94/39
f 65/94/39 56/92/18 72/72/15 73/71/14
f 54/74/37 65/94/39 73/71/14 70/87/28
f 70/87/28 73/71/14 61/73/17 50/41/29
f 68/91/36 74/79/23 66/81/26 55/77/21
f 53/90/35 71/83/40 74/79/23 68/91/36
f 71/83/40 49/38/41 63/80/24 74/79/23
f 67/93/38 54/90/37 70/83/28 75/82/27
f 53/92/35 67/93/38 75/82/27 71/72/40
f 71/72/40 75/82/27 62/84/30 49/44/41
f 69/78/22 76/85/31 72/87/15 56/74/18
f 55/77/21 66/81/26 76/85/31 69/78/22
f 66/81/26 51/37/25 64/86/32 76/85/31

View File

@ -1,263 +0,0 @@
# Blender v2.73 (sub 0) OBJ File: 'mesecons-wall-lever.blend'
# www.blender.org
o nodebox-5
v 0.289062 0.156250 0.312500
v -0.375000 0.375000 0.375000
v -0.375000 -0.375000 0.375000
v 0.332500 0.207500 0.375000
v 0.332500 -0.207500 0.375000
v 0.375000 0.375000 0.375000
v 0.375000 -0.375000 0.375000
v 0.289062 -0.156250 0.312500
v -0.062500 0.075354 0.315617
v -0.062500 0.043002 0.194876
v -0.062500 0.369002 0.107525
v -0.062500 0.401354 0.228266
v -0.332500 0.207500 0.375000
v 0.062500 0.075354 0.315617
v 0.062500 0.043002 0.194876
v -0.332500 -0.207500 0.375000
v 0.332500 0.207500 0.375000
v 0.062500 0.369002 0.107525
v 0.062500 0.401354 0.228266
v 0.332500 -0.207500 0.375000
v 0.375000 -0.375000 0.375000
v 0.375000 -0.375000 0.500000
v 0.375000 0.375000 0.500000
v 0.375000 0.375000 0.375000
v -0.375000 -0.375000 0.375000
v -0.375000 -0.375000 0.500000
v -0.375000 0.375000 0.500000
v -0.375000 0.375000 0.375000
v -0.289062 0.156250 0.312500
v -0.332500 0.207500 0.375000
v -0.332500 -0.207500 0.375000
v -0.289062 -0.156250 0.312500
v -0.250000 0.125000 0.312500
v -0.250000 -0.125000 0.312500
v 0.250000 0.125000 0.312500
v 0.250000 -0.125000 0.312500
v -0.250000 -0.000000 0.250000
v -0.000000 -0.125000 0.250000
v 0.250000 -0.000000 0.250000
v 0.000000 0.125000 0.250000
v -0.250000 0.125000 0.250000
v -0.250000 0.125000 0.312500
v -0.250000 -0.125000 0.312500
v -0.250000 -0.125000 0.250000
v 0.250000 0.125000 0.250000
v 0.250000 0.125000 0.312500
v 0.250000 -0.125000 0.312500
v 0.250000 -0.125000 0.250000
v 0.250000 -0.125000 0.250000
v 0.250000 0.125000 0.250000
v -0.250000 -0.125000 0.250000
v -0.250000 0.125000 0.250000
v 0.125000 -0.062500 0.187500
v 0.125000 0.062500 0.187500
v -0.125000 -0.062500 0.187500
v -0.125000 0.062500 0.187500
v 0.065000 -0.032500 0.176992
v 0.065000 0.032500 0.176992
v -0.065000 -0.032500 0.176992
v -0.065000 0.032500 0.176992
v 0.000000 0.125000 0.250000
v 0.250000 -0.000000 0.250000
v -0.000000 -0.125000 0.250000
v -0.250000 -0.000000 0.250000
v 0.000000 0.062500 0.187500
v -0.187500 -0.093750 0.208750
v 0.125000 -0.000000 0.187500
v 0.000000 -0.062500 0.187500
v -0.125000 -0.000000 0.187500
v 0.187500 0.093750 0.208750
v 0.187500 -0.093750 0.208750
v -0.187500 0.093750 0.208750
v 0.000000 0.093750 0.208750
v 0.000000 -0.093750 0.208750
v 0.187500 -0.000000 0.208750
v -0.187500 -0.000000 0.208750
vt 0.416667 0.416667
vt 0.083333 0.416667
vt 0.055556 0.472222
vt 0.444444 0.472222
vt 0.083333 0.083333
vt 0.055556 0.027778
vt 0.444444 0.027778
vt 0.416667 0.083333
vt 0.472222 0.055556
vt 0.472222 0.444444
vt 0.027778 0.055556
vt 0.027778 0.444444
vt 0.250000 0.833333
vt 0.250000 0.638889
vt 0.305556 0.638889
vt 0.305556 0.833333
vt 0.388889 0.777778
vt 0.333333 0.777778
vt 0.333333 0.722222
vt 0.388889 0.722222
vt 0.944444 0.527778
vt 0.944444 0.916667
vt 1.000000 0.916667
vt 1.000000 0.527778
vt 0.500000 0.527778
vt 0.555556 0.527778
vt 0.555556 0.916667
vt 0.500000 0.916667
vt 0.138889 0.833333
vt 0.194444 0.833333
vt 0.194444 0.638889
vt 0.138889 0.638889
vt 0.944444 0.472222
vt 0.555556 0.472222
vt 0.555556 0.972222
vt 0.944444 0.972222
vt 0.888802 0.166753
vt 0.555642 0.166753
vt 0.527778 0.138889
vt 0.916667 0.138889
vt 0.888802 0.388802
vt 0.916667 0.416667
vt 0.527778 0.416667
vt 0.555642 0.388802
vt 0.361111 0.361111
vt 0.250000 0.361111
vt 0.138889 0.361111
vt 0.138889 0.416667
vt 0.361111 0.416667
vt 0.361111 0.083333
vt 0.361111 0.138889
vt 0.138889 0.138889
vt 0.138889 0.083333
vt 0.250000 0.083333
vt 0.416667 0.361111
vt 0.416667 0.138889
vt 0.416667 0.250000
vt 0.138889 0.250000
vt 0.083333 0.138889
vt 0.083333 0.361111
vt 0.083333 0.638889
vt 0.083333 0.833333
vt 0.444444 0.611111
vt 0.055556 0.611111
vt 0.027778 0.527778
vt 0.472222 0.527778
vt 0.444444 0.888889
vt 0.472222 0.972222
vt 0.055556 0.888889
vt 0.027778 0.972222
vt 0.722222 0.361111
vt 0.583333 0.361111
vt 0.722222 0.388802
vt 0.833333 0.333333
vt 0.777778 0.305556
vt 0.777778 0.250000
vt 0.833333 0.222222
vt 0.833333 0.277778
vt 0.722222 0.194444
vt 0.722222 0.166753
vt 0.861111 0.194444
vt 0.583333 0.277778
vt 0.583333 0.194444
vt 0.555642 0.277778
vt 0.861111 0.277778
vt 0.888802 0.277778
vt 0.861111 0.361111
vt 0.666667 0.250000
vt 0.666667 0.305556
vt 0.611111 0.222222
vt 0.722222 0.222222
vt 0.611111 0.333333
vt 0.611111 0.277778
vt 0.722222 0.333333
vn 0.000000 0.773300 -0.634100
vn 0.000000 -0.773300 -0.634100
vn -0.821200 0.000000 -0.570700
vn 0.821200 0.000000 -0.570700
vn 0.000000 -0.258800 -0.965900
vn 0.000000 0.965900 -0.258800
vn 1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn 0.000000 0.258800 0.965900
vn 0.000000 -0.000000 1.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.688800 -0.724900
vn -0.269900 0.421500 -0.865700
vn -0.395600 0.336800 -0.854500
vn 0.000000 0.797100 -0.603900
vn -0.142400 0.274900 -0.950900
vn -0.056900 0.142700 -0.988100
vn -0.056900 -0.142700 -0.988100
vn -0.142400 -0.274900 -0.950900
vn -0.247900 0.000000 -0.968700
vn 0.000000 -0.688800 -0.724900
vn 0.000000 -0.797100 -0.603900
vn -0.395600 -0.336800 -0.854500
vn -0.269900 -0.421500 -0.865700
vn 0.440000 0.000000 -0.898000
vn 0.269900 0.421500 -0.865700
vn 0.395600 0.336800 -0.854500
vn 0.550800 0.000000 -0.834600
vn -0.440000 0.000000 -0.898000
vn -0.550800 0.000000 -0.834600
vn 0.056900 -0.142700 -0.988100
vn 0.056900 0.142700 -0.988100
vn 0.142400 -0.274900 -0.950900
vn 0.000000 -0.450200 -0.892900
vn 0.142400 0.274900 -0.950900
vn 0.247900 0.000000 -0.968700
vn 0.000000 0.450200 -0.892900
vn 0.269900 -0.421500 -0.865700
vn 0.395600 -0.336800 -0.854500
s off
f 1/1/1 29/2/1 30/3/1 4/4/1
f 8/5/2 5/6/2 31/7/2 32/8/2
f 32/8/3 31/9/3 30/10/3 29/1/3
f 8/2/4 1/5/4 4/11/4 5/12/4
f 18/13/5 15/14/5 10/15/5 11/16/5
f 19/17/6 18/18/6 11/19/6 12/20/6
f 21/21/7 24/22/7 23/23/7 22/24/7
f 25/25/8 26/26/8 27/27/8 28/28/8
f 19/29/9 12/30/9 9/31/9 14/32/9
f 22/26/10 23/21/10 27/22/10 26/27/10
f 21/33/11 22/21/11 26/26/11 25/34/11
f 24/22/12 28/27/12 27/35/12 23/36/12
f 34/37/13 36/38/13 8/39/13 32/40/13
f 33/41/13 34/37/13 32/40/13 29/42/13
f 33/41/13 29/42/13 1/43/13 35/44/13
f 35/44/13 1/43/13 8/39/13 36/38/13
f 45/45/12 40/46/12 41/47/12 42/48/12 46/49/12
f 48/50/11 47/51/11 43/52/11 44/53/11 38/54/11
f 44/55/8 43/45/8 42/51/8 41/56/8 37/57/8
f 48/47/7 39/58/7 45/52/7 46/59/7 47/60/7
f 12/13/8 11/30/8 10/31/8 9/14/8
f 19/29/7 14/32/7 15/61/7 18/62/7
f 16/63/13 20/64/13 7/65/13 3/66/13
f 13/67/13 16/63/13 3/66/13 2/68/13
f 17/69/13 6/70/13 7/65/13 20/64/13
f 13/67/13 2/68/13 6/70/13 17/69/13
s 1
f 73/71/14 72/72/15 52/44/16 61/73/17
f 56/74/18 60/75/19 59/76/20 55/77/21 69/78/22
f 74/79/23 63/80/24 51/37/25 66/81/26
f 75/82/27 70/83/28 50/38/29 62/84/30
f 76/85/31 64/86/32 52/41/16 72/87/15
f 57/88/33 59/76/20 60/75/19 58/89/34
f 55/77/21 59/76/20 57/88/33 53/90/35 68/91/36
f 53/90/35 57/88/33 58/89/34 54/92/37 67/93/38
f 54/92/37 58/89/34 60/75/19 56/74/18 65/94/39
f 65/94/39 56/92/18 72/72/15 73/71/14
f 54/74/37 65/94/39 73/71/14 70/87/28
f 70/87/28 73/71/14 61/73/17 50/41/29
f 68/91/36 74/79/23 66/81/26 55/77/21
f 53/90/35 71/83/40 74/79/23 68/91/36
f 71/83/40 49/38/41 63/80/24 74/79/23
f 67/93/38 54/90/37 70/83/28 75/82/27
f 53/92/35 67/93/38 75/82/27 71/72/40
f 71/72/40 75/82/27 62/84/30 49/44/41
f 69/78/22 76/85/31 72/87/15 56/74/18
f 55/77/21 66/81/26 76/85/31 69/78/22
f 66/81/26 51/37/25 64/86/32 76/85/31

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 500 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 B