1 Commits

Author SHA1 Message Date
7d8fd7a8df Fix issue #135 2014-01-05 19:55:45 +01:00
215 changed files with 2319 additions and 3219 deletions

View File

@ -1,118 +0,0 @@
mesecon.queue.actions={} -- contains all ActionQueue actions
function mesecon.queue:add_function(name, func)
mesecon.queue.funcs[name] = func
end
-- If add_action with twice the same overwritecheck and same position are called, the first one is overwritten
-- use overwritecheck nil to never overwrite, but just add the event to the queue
-- priority specifies the order actions are executed within one globalstep, highest first
-- should be between 0 and 1
function mesecon.queue:add_action(pos, func, params, time, overwritecheck, priority)
-- Create Action Table:
time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution
priority = priority or 1
local action = { pos=mesecon.tablecopy(pos),
func=func,
params=mesecon.tablecopy(params or {}),
time=time,
owcheck=(overwritecheck and mesecon.tablecopy(overwritecheck)) or nil,
priority=priority}
local toremove = nil
-- Otherwise, add the action to the queue
if overwritecheck then -- check if old action has to be overwritten / removed:
for i, ac in ipairs(mesecon.queue.actions) do
if(mesecon.cmpPos(pos, ac.pos)
and mesecon.cmpAny(overwritecheck, ac.owcheck)) then
toremove = i
break
end
end
end
if (toremove ~= nil) then
table.remove(mesecon.queue.actions, toremove)
end
table.insert(mesecon.queue.actions, action)
end
-- execute the stored functions on a globalstep
-- if however, the pos of a function is not loaded (get_node_or_nil == nil), do NOT execute the function
-- this makes sure that resuming mesecons circuits when restarting minetest works fine
-- However, even that does not work in some cases, that's why we delay the time the globalsteps
-- start to be execute by 5 seconds
local get_highest_priority = function (actions)
local highestp = -1
local highesti
for i, ac in ipairs(actions) do
if ac.priority > highestp then
highestp = ac.priority
highesti = i
end
end
return highesti
end
local m_time = 0
local resumetime = mesecon.setting("resumetime", 4)
minetest.register_globalstep(function (dtime)
m_time = m_time + dtime
-- don't even try if server has not been running for XY seconds; resumetime = time to wait
-- after starting the server before processing the ActionQueue, don't set this too low
if (m_time < resumetime) then return end
local actions = mesecon.tablecopy(mesecon.queue.actions)
local actions_now={}
mesecon.queue.actions = {}
-- sort actions into two categories:
-- those toexecute now (actions_now) and those to execute later (mesecon.queue.actions)
for i, ac in ipairs(actions) do
if ac.time > 0 then
ac.time = ac.time - dtime -- executed later
table.insert(mesecon.queue.actions, ac)
else
table.insert(actions_now, ac)
end
end
while(#actions_now > 0) do -- execute highest priorities first, until all are executed
local hp = get_highest_priority(actions_now)
mesecon.queue:execute(actions_now[hp])
table.remove(actions_now, hp)
end
end)
function mesecon.queue:execute(action)
mesecon.queue.funcs[action.func](action.pos, unpack(action.params))
end
-- Store and read the ActionQueue to / from a file
-- so that upcoming actions are remembered when the game
-- is restarted
local wpath = minetest.get_worldpath()
local function file2table(filename)
local f = io.open(filename, "r")
if f==nil then return {} end
local t = f:read("*all")
f:close()
if t=="" or t==nil then return {} end
return minetest.deserialize(t)
end
local function table2file(filename, table)
local f = io.open(filename, "w")
f:write(minetest.serialize(table))
f:close()
end
mesecon.queue.actions = file2table(wpath.."/mesecon_actionqueue")
minetest.register_on_shutdown(function()
mesecon.queue.actions = table2file(wpath.."/mesecon_actionqueue", mesecon.queue.actions)
end)

View File

@ -39,26 +39,53 @@
-- } -- }
--} --}
-- PUBLIC VARIABLES -- PUBLIC VARIABLES
mesecon={} -- contains all functions and all global variables mesecon={} -- contains all functions and all global variables
mesecon.queue={} -- contains the ActionQueue mesecon.actions_on={} -- Saves registered function callbacks for mesecon on | DEPRECATED
mesecon.queue.funcs={} -- contains all ActionQueue functions mesecon.actions_off={} -- Saves registered function callbacks for mesecon off | DEPRECATED
mesecon.actions_change={} -- Saves registered function callbacks for mesecon change | DEPRECATED
mesecon.receptors={} -- saves all information about receptors | DEPRECATED
mesecon.effectors={} -- saves all information about effectors | DEPRECATED
mesecon.conductors={} -- saves all information about conductors | DEPRECATED
local wpath = minetest.get_worldpath()
local function read_file(fn)
local f = io.open(fn, "r")
if f==nil then return {} end
local t = f:read("*all")
f:close()
if t=="" or t==nil then return {} end
return minetest.deserialize(t)
end
local function write_file(fn, tbl)
local f = io.open(fn, "w")
f:write(minetest.serialize(tbl))
f:close()
end
mesecon.to_update = read_file(wpath.."/mesecon_to_update")
mesecon.r_to_update = read_file(wpath.."/mesecon_r_to_update")
minetest.register_on_shutdown(function()
write_file(wpath.."/mesecon_to_update",mesecon.to_update)
write_file(wpath.."/mesecon_r_to_update",mesecon.r_to_update)
end)
-- 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
-- Saves all the actions that have to be execute in the future
dofile(minetest.get_modpath("mesecons").."/actionqueue.lua");
-- Internal stuff -- Internal stuff
-- This is the most important file -- This is the most important file
-- it handles signal transmission and basically everything else -- it handles signal transmission and basically everything else
@ -66,72 +93,62 @@ 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
mesecon.queue:add_function("receptor_on", function (pos, rules) function mesecon:receptor_on_i(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 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)
-- if area is not loaded, keep trying
if minetest.get_node_or_nil(np) == nil then
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
return
end
end
-- execute action
for _, rule in ipairs(mesecon.flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule)
local rulenames = mesecon.rules_link_rule_all(pos, rule)
for _, rulename in ipairs(rulenames) do for _, rulename in ipairs(rulenames) do
mesecon.turnon(np, rulename) mesecon:turnon(np, rulename)
end end
end end
end)
function mesecon.receptor_on(pos, rules)
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
end end
mesecon.queue:add_function("receptor_off", function (pos, rules) function mesecon:receptor_on(pos, rules)
if MESECONS_GLOBALSTEP then
rules = rules or mesecon.rules.default rules = rules or mesecon.rules.default
mesecon.r_to_update[#mesecon.r_to_update+1]={pos=pos, rules=rules, action="on"}
-- if area (any of the rule targets) is not loaded, keep trying and call this again later
for _, rule in ipairs(mesecon.flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule)
if minetest.get_node_or_nil(np) == nil then
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
return
end
end
for _, rule in ipairs(mesecon.flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule)
local rulenames = mesecon.rules_link_rule_all(pos, rule)
for _, rulename in ipairs(rulenames) do
if not mesecon.connected_to_receptor(np, mesecon.invertRule(rule)) then
mesecon.turnoff(np, rulename)
else else
mesecon.changesignal(np, minetest.get_node(np), rulename, mesecon.state.off, 2) mesecon:receptor_on_i(pos, rules)
end end
end end
end
end)
function mesecon.receptor_off(pos, rules) function mesecon:receptor_off_i(pos, rules)
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) rules = rules or mesecon.rules.default
for _, rule in ipairs(mesecon:flattenrules(rules)) do
local np = mesecon:addPosRule(pos, rule)
local rulenames = mesecon:rules_link_rule_all(pos, rule)
for _, rulename in ipairs(rulenames) do
if not mesecon:connected_to_receptor(np, mesecon:invertRule(rule)) then
mesecon:turnoff(np, rulename)
else
mesecon:changesignal(np, minetest.get_node(np), rulename, mesecon.state.off)
end
end
end
end
function mesecon:receptor_off(pos, rules)
if MESECONS_GLOBALSTEP then
rules = rules or mesecon.rules.default
mesecon.r_to_update[#mesecon.r_to_update+1]={pos=pos, rules=rules, action="off"}
else
mesecon:receptor_off_i(pos, rules)
end
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) --> Activates the effector node at the specific pos (calls nodedef.mesecons.effector.action_on)
-- 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) --> 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
-- 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
-- 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
@ -176,156 +177,205 @@ function mesecon.effector_get_rules(node)
return mesecon.rules.default return mesecon.rules.default
end end
-- ####################### --Signals
-- # Signals (effectors) #
-- #######################
-- Activation:
mesecon.queue:add_function("activate", function (pos, rulename)
local node = minetest.get_node(pos)
local effector = mesecon.get_effector(node.name)
function mesecon:activate(pos, node, rulename)
if MESECONS_GLOBALSTEP then
if rulename == nil then
for _,rule in ipairs(mesecon:effector_get_rules(node)) do
mesecon:activate(pos, node, rule)
end
return
end
add_action(pos, "on", rulename)
else
local 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
end
function mesecon.activate(pos, node, rulename, depth) function mesecon:deactivate(pos, node, rulename)
if MESECONS_GLOBALSTEP then
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:deactivate(pos, node, rule)
end end
return return
end end
mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / depth) add_action(pos, "off", rulename)
end else
local effector = mesecon:get_effector(node.name)
-- Deactivation
mesecon.queue:add_function("deactivate", function (pos, rulename)
local node = minetest.get_node(pos)
local 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
end
function mesecon.deactivate(pos, node, rulename, depth) function mesecon:changesignal(pos, node, rulename, newstate)
newstate = newstate or "on"
--rulename = rulename or mesecon.rules.default
if MESECONS_GLOBALSTEP then
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:changesignal(pos, node, rule, newstate)
end end
return return
end end
mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / depth) add_action(pos, "c"..newstate, rulename)
end else
local effector = mesecon:get_effector(node.name)
-- Change
mesecon.queue:add_function("change", function (pos, rulename, changetype)
local node = minetest.get_node(pos)
local 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, newstate)
end end
end)
function mesecon.changesignal(pos, node, rulename, newstate, depth)
if rulename == nil then
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
mesecon.changesignal(pos, node, rule, newstate, depth + 1)
end end
return
end end
-- Include "change" in overwritecheck so that it cannot be overwritten function execute_actions(dtime)
-- by "active" / "deactivate" that will be called upon the node at the same time. local nactions = mesecon.to_update
local overwritecheck = {"change", rulename} mesecon.to_update = {}
mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, overwritecheck, 1 / depth) for _,i in ipairs(nactions) do
node = minetest.get_node(i.pos)
if node.name=="ignore" then
add_action(i.pos, i.action, i.rname)
else
effector = mesecon:get_effector(node.name)
if i.action == "on" then
if effector and effector.action_on then
effector.action_on(i.pos, node, i.rname)
end
elseif i.action == "off" then
if effector and effector.action_off then
effector.action_off(i.pos, node, i.rname)
end
elseif i.action == "con" then
if effector and effector.action_change then
effector.action_change(i.pos, node, i.rname, "on")
end
elseif i.action == "coff" then
if effector and effector.action_change then
effector.action_change(i.pos, node, i.rname, "off")
end
end
end
end
local nactions = mesecon.r_to_update
mesecon.r_to_update = {}
for _,i in ipairs(nactions) do
if i.action == "on" then
mesecon:receptor_on_i(i.pos, i.rules)
else
mesecon:receptor_off_i(i.pos,i.rules)
end
end
end
minetest.register_globalstep(execute_actions)
function add_action(pos, action, rname)
for i, update in ipairs(mesecon.to_update) do
-- check if action for this node already exist, if so correct it:
if mesecon:cmpPos(pos, update.pos) and mesecon:cmpPos(update.rname, rname) then
mesecon.to_update[i].action = action
return -- action added (as correction), so return now
end
end
table.insert(mesecon.to_update, {pos = pos, action = action, rname = rname})
end
--Rules
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 +389,101 @@ 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)
local frontiers = {{pos = pos, link = link}} local node = minetest.get_node(pos)
local depth = 1 if mesecon:is_conductor_off(node, rulename) then
while frontiers[depth] do local rules = mesecon:conductor_get_rules(node)
local f = frontiers[depth]
local node = minetest.get_node_or_nil(f.pos)
-- area not loaded, postpone action if not rulename then
if not node then for _, rule in ipairs(mesecon:flattenrules(rules)) do
mesecon.queue:add_action(f.pos, "turnon", {link}, nil, true) if mesecon:connected_to_receptor(pos, rule) then
elseif mesecon.is_conductor_off(node, f.link) then mesecon:turnon(pos, rule)
local rules = mesecon.conductor_get_rules(node) end
end
return
end
minetest.swap_node(f.pos, {name = mesecon.get_conductor_on(node, f.link), minetest.swap_node(pos, {name = mesecon:get_conductor_on(node, rulename), param2 = node.param2})
param2 = node.param2})
-- call turnon on neighbors: normal rules for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do local np = mesecon:addPosRule(pos, rule)
local np = mesecon.addPosRule(f.pos, r) local rulenames = mesecon:rules_link_rule_all(pos, rule)
-- area not loaded, postpone action for _, rulename in ipairs(rulenames) do
if not minetest.get_node_or_nil(np) then mesecon:turnon(np, rulename)
mesecon.queue:add_action(np, "turnon", {rulename}, end
nil, true) end
else elseif mesecon:is_effector(node.name) then
local links = mesecon.rules_link_rule_all(f.pos, r) mesecon:changesignal(pos, node, rulename, mesecon.state.on)
for _, l in ipairs(links) do if mesecon:is_effector_off(node.name) then
table.insert(frontiers, {pos = np, link = l}) mesecon:activate(pos, node, rulename)
end end
end end
end end
elseif mesecon.is_effector(node.name) then
mesecon.changesignal(f.pos, node, f.link, mesecon.state.on, depth) function mesecon:turnoff(pos, rulename)
if mesecon.is_effector_off(node.name) then local node = minetest.get_node(pos)
mesecon.activate(f.pos, node, f.link, depth)
if mesecon:is_conductor_on(node, rulename) then
local rules = mesecon:conductor_get_rules(node)
--[[
if not rulename then
for _, rule in ipairs(mesecon:flattenrules(rules)) do
if mesecon:is_powered(pos, rule) then
mesecon:turnoff(pos, rule)
end end
end end
depth = depth + 1 return
end
--]]
minetest.swap_node(pos, {name = mesecon:get_conductor_off(node, rulename), param2 = node.param2})
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
local np = mesecon:addPosRule(pos, rule)
local rulenames = mesecon:rules_link_rule_all(pos, rule)
for _, rulename in ipairs(rulenames) do
mesecon:turnoff(np, rulename)
end
end
elseif mesecon:is_effector(node.name) then
mesecon:changesignal(pos, node, rulename, mesecon.state.off)
if mesecon:is_effector_on(node.name)
and not mesecon:is_powered(pos) then
mesecon:deactivate(pos, node, rulename)
end
end end
end end
mesecon.queue:add_function("turnon", function (pos, rulename, recdepth)
mesecon.turnon(pos, rulename, recdepth)
end)
function mesecon.turnoff(pos, link) function mesecon:connected_to_receptor(pos, rulename)
local frontiers = {{pos = pos, link = link}}
local depth = 1
while frontiers[depth] do
local f = frontiers[depth]
local node = minetest.get_node_or_nil(f.pos)
-- area not loaded, postpone action
if not node then
mesecon.queue:add_action(f.pos, "turnoff", {link}, nil, true)
elseif mesecon.is_conductor_on(node, f.link) then
local rules = mesecon.conductor_get_rules(node)
minetest.swap_node(f.pos, {name = mesecon.get_conductor_off(node, f.link),
param2 = node.param2})
-- call turnoff on neighbors: normal rules
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
local np = mesecon.addPosRule(f.pos, r)
-- area not loaded, postpone action
if not minetest.get_node_or_nil(np) then
mesecon.queue:add_action(np, "turnoff", {rulename},
nil, true)
else
local links = mesecon.rules_link_rule_all(f.pos, r)
for _, l in ipairs(links) do
table.insert(frontiers, {pos = np, link = l})
end
end
end
elseif mesecon.is_effector(node.name) then
mesecon.changesignal(f.pos, node, f.link, mesecon.state.off, depth)
if mesecon.is_effector_on(node.name) and not mesecon.is_powered(f.pos) then
mesecon.deactivate(f.pos, node, f.link, depth)
end
end
depth = depth + 1
end
end
mesecon.queue:add_function("turnoff", function (pos, rulename, recdepth)
mesecon.turnoff(pos, rulename, recdepth)
end)
function mesecon.connected_to_receptor(pos, link)
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 np = mesecon:addPosRule(pos, rule)
for _, l in ipairs(links) do if mesecon:rules_link(np, pos) then
local np = mesecon.addPosRule(pos, l) if mesecon:find_receptor_on(np, {}, mesecon:invertRule(rule)) then
if mesecon.find_receptor_on(np, mesecon.invertRule(l)) then
return true return true
end end
end end
@ -468,185 +492,205 @@ 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 np = mesecon:addPosRule(pos, rule)
table.insert(frontiers, {pos = np, link = l}) if mesecon:rules_link(np, pos) then
checked[checkedstring] = true if mesecon:find_receptor_on(np, checked, mesecon:invertRule(rule)) 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
depth = depth + 1
end end
table.insert(checked, {x=pos.x, y=pos.y, z=pos.z})
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 return false
end
function mesecon:rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule
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_anydir(pos1, pos2)
--local irule = mesecon.invertRule(rule) return mesecon:rules_link(pos1, pos2) or mesecon:rules_link(pos2, pos1)
local output = mesecon.addPosRule(input, rule)
local outputnode = minetest.get_node(output)
local outputrules = mesecon.get_any_outputrules (outputnode)
if not outputrules then
return {}
end
local rules = {}
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then
table.insert(rules, mesecon.invertRule(outputrule))
end
end
return rules
end end
function mesecon.rules_link_anydir(pos1, pos2) function mesecon:is_powered(pos, rule)
return mesecon.rules_link(pos1, pos2) or mesecon.rules_link(pos2, pos1)
end
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 np = mesecon:addPosRule(pos, rule)
for _, rname in ipairs(rulenames) do
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))
or mesecon.is_receptor_on (nn.name)) then if (mesecon:is_conductor_on (nn, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name))
table.insert(sourcepos, np) and mesecon:rules_link(np, pos) then
end return true
end end
end end
else else
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) local np = mesecon:addPosRule(pos, rule)
for _, rname in ipairs(rulenames) do
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))
or mesecon.is_receptor_on (nn.name)) then if (mesecon:is_conductor_on (nn, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name))
table.insert(sourcepos, np) and mesecon:rules_link(np, pos) then
end return true
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,5 @@
-- 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 end
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
end
function mesecon.receptor_off(self, pos, rules)
if (self.receptor_off) then
print("[Mesecons] Warning: A mod with mesecon support called mesecon:receptor_off.")
print("[Mesecons] If you are the programmer of this mod, please update it ")
print("[Mesecons] to use mesecon.receptor_off instead. mesecon:* is deprecated")
print("[Mesecons] Otherwise, please make sure you're running the latest version")
print("[Mesecons] of that mod and inform the mod creator.")
else
rules = pos
pos = self
end
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
end

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,94 +1,38 @@
-- Dig and place services
mesecon.on_placenode = function (pos, node) mesecon.on_placenode = function (pos, node)
mesecon.update_autoconnect(pos, node) if mesecon:is_receptor_on(node.name) then
mesecon:receptor_on(pos, mesecon:receptor_get_rules(node))
-- Receptors: Send on signal when active elseif mesecon:is_powered(pos) then
if mesecon.is_receptor_on(node.name) then if mesecon:is_conductor(node.name) then
mesecon.receptor_on(pos, mesecon.receptor_get_rules(node)) mesecon:turnon (pos)
end --mesecon:receptor_on (pos, mesecon:conductor_get_rules(node))
else
-- Conductors: Send turnon signal when powered or replace by respective offstate conductor mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on")
-- if placed conductor is an onstate one mesecon:activate(pos, node)
if mesecon.is_conductor(node.name) then
local sources = mesecon.is_powered(pos)
if sources then
-- also call receptor_on if itself is powered already, so that neighboring
-- conductors will be activated (when pushing an on-conductor with a piston)
for _, s in ipairs(sources) do
local rule = {x = pos.x - s.x, y = pos.y - s.y, z = pos.z - s.z}
mesecon.turnon(pos, rule)
end
--mesecon.receptor_on (pos, mesecon.conductor_get_rules(node))
elseif mesecon.is_conductor_on(node) then
minetest.swap_node(pos, {name = mesecon.get_conductor_off(node)})
end
end
-- Effectors: Send changesignal and activate or deactivate
if mesecon.is_effector(node.name) then
local powered_rules = {}
-- for each input rule, check if powered
for _, r in ipairs(mesecon.effector_get_rules(node)) do
local powered = mesecon.is_powered(pos, r)
if powered then table.insert(powered_rules, r) end
local state = powered and mesecon.state.on or mesecon.state.off
mesecon.changesignal(pos, node, r, state, 1)
end
if (#powered_rules > 0) then
for _, r in ipairs(powered_rules) do
mesecon.activate(pos, node, r, 1)
end
end end
elseif mesecon:is_conductor_on(node) then
minetest.swap_node(pos, {name = mesecon:get_conductor_off(node)})
elseif mesecon:is_effector_on (node.name) then
mesecon:deactivate(pos, node)
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_i(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_abm({
nodenames = {"group:overheat"},
interval = 1.0,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
meta:set_int("heat",0)
end,
})
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)
-- Overheating service for fast circuits
-- returns true if heat is too high
mesecon.do_overheat = function(pos)
local meta = minetest.get_meta(pos)
local heat = meta:get_int("heat") or 0
heat = heat + 1
meta:set_int("heat", heat)
if heat < mesecon.setting("overheat_max", 20) then
mesecon.queue:add_action(pos, "cooldown", {}, 1, nil, 0)
else
return true
end
return false
end
mesecon.queue:add_function("cooldown", function (pos)
if minetest.get_item_group(minetest.get_node(pos).name, "overheat") == 0 then
return -- node has been moved, this one does not use overheating - ignore
end
local meta = minetest.get_meta(pos)
local heat = meta:get_int("heat")
if (heat > 0) then
meta:set_int("heat", heat - 1)
end
end)

View File

@ -1,10 +1,9 @@
-- 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_GLOBALSTEP = true -- true = receptors/effectors won't be updated
end -- until next globalstep, decreases server load
end

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,52 @@ 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)
if type(table) ~= "table" then return table end -- no need to copy return (r1.sx == r2.sx and r1.sy == r2.sy and r1.sz == r2.sz)
end
function mesecon:tablecopy(table) -- deep table 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
@ -158,54 +181,3 @@ function mesecon.tablecopy(table) -- deep table copy
return newtable return newtable
end end
function mesecon.cmpAny(t1, t2)
if type(t1) ~= type(t2) then return false end
if type(t1) ~= "table" and type(t2) ~= "table" then return t1 == t2 end
for i, e in pairs(t1) do
if not mesecon.cmpAny(e, t2[i]) then return false end
end
return true
end
-- does not overwrite values; number keys (ipairs) are appended, not overwritten
function mesecon.mergetable(source, dest)
local rval = mesecon.tablecopy(dest)
for k, v in pairs(source) do
rval[k] = dest[k] or mesecon.tablecopy(v)
end
for i, v in ipairs(source) do
table.insert(rval, mesecon.tablecopy(v))
end
return rval
end
function mesecon.register_node(name, spec_common, spec_off, spec_on)
spec_common.drop = spec_common.drop or name .. "_off"
spec_common.__mesecon_basename = name
spec_on.__mesecon_state = "on"
spec_off.__mesecon_state = "off"
spec_on = mesecon.mergetable(spec_common, spec_on);
spec_off = mesecon.mergetable(spec_common, spec_off);
minetest.register_node(name .. "_on", spec_on)
minetest.register_node(name .. "_off", spec_off)
end
-- swap onstate and offstate nodes, returns new state
function mesecon.flipstate(pos, node)
local nodedef = minetest.registered_nodes[node.name]
local newstate
if (nodedef.__mesecon_state == "on") then newstate = "off" end
if (nodedef.__mesecon_state == "off") then newstate = "on" end
minetest.swap_node(pos, {name = nodedef.__mesecon_basename .. "_" .. newstate,
param2 = node.param2})
return newstate
end

View File

@ -1,233 +1,255 @@
-- 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
end end
register_wires()
-- ############## -- Updating the wires:
-- ## Crafting ## -- 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
minetest.register_on_placenode(update_on_place_dig)
minetest.register_on_dignode(update_on_place_dig)
function mesecon:update_autoconnect(pos, secondcall, replace_old)
local xppos = {x=pos.x+1, y=pos.y, z=pos.z}
local zppos = {x=pos.x, y=pos.y, z=pos.z+1}
local xmpos = {x=pos.x-1, y=pos.y, z=pos.z}
local zmpos = {x=pos.x, y=pos.y, z=pos.z-1}
local xpympos = {x=pos.x+1, y=pos.y-1, z=pos.z}
local zpympos = {x=pos.x, y=pos.y-1, z=pos.z+1}
local xmympos = {x=pos.x-1, y=pos.y-1, z=pos.z}
local zmympos = {x=pos.x, y=pos.y-1, z=pos.z-1}
local xpypos = {x=pos.x+1, y=pos.y+1, z=pos.z}
local zpypos = {x=pos.x, y=pos.y+1, z=pos.z+1}
local xmypos = {x=pos.x-1, y=pos.y+1, z=pos.z}
local zmypos = {x=pos.x, y=pos.y+1, z=pos.z-1}
if secondcall == nil then
mesecon:update_autoconnect(xppos, true)
mesecon:update_autoconnect(zppos, true)
mesecon:update_autoconnect(xmpos, true)
mesecon:update_autoconnect(zmpos, true)
mesecon:update_autoconnect(xpypos, true)
mesecon:update_autoconnect(zpypos, true)
mesecon:update_autoconnect(xmypos, true)
mesecon:update_autoconnect(zmypos, true)
mesecon:update_autoconnect(xpympos, true)
mesecon:update_autoconnect(zpympos, true)
mesecon:update_autoconnect(xmympos, true)
mesecon:update_autoconnect(zmympos, true)
end
nodename = minetest.get_node(pos).name
if string.find(nodename, "mesecons:wire_") == nil and not replace_old then return nil end
if mesecon:rules_link_anydir(pos, xppos) then xp = 1 else xp = 0 end
if mesecon:rules_link_anydir(pos, xmpos) then xm = 1 else xm = 0 end
if mesecon:rules_link_anydir(pos, zppos) then zp = 1 else zp = 0 end
if mesecon:rules_link_anydir(pos, zmpos) then zm = 1 else zm = 0 end
if mesecon:rules_link_anydir(pos, xpympos) then xp = 1 end
if mesecon:rules_link_anydir(pos, xmympos) then xm = 1 end
if mesecon:rules_link_anydir(pos, zpympos) then zp = 1 end
if mesecon:rules_link_anydir(pos, zmympos) then zm = 1 end
if mesecon:rules_link_anydir(pos, xpypos) then xpy = 1 else xpy = 0 end
if mesecon:rules_link_anydir(pos, zpypos) then zpy = 1 else zpy = 0 end
if mesecon:rules_link_anydir(pos, xmypos) then xmy = 1 else xmy = 0 end
if mesecon:rules_link_anydir(pos, zmypos) then zmy = 1 else zmy = 0 end
if xpy == 1 then xp = 1 end
if zpy == 1 then zp = 1 end
if xmy == 1 then xm = 1 end
if zmy == 1 then zm = 1 end
local nodeid = tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm )..
tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy)
if string.find(nodename, "_off") ~= nil then
minetest.set_node(pos, {name = "mesecons:wire_"..nodeid.."_off"})
else
minetest.set_node(pos, {name = "mesecons:wire_"..nodeid.."_on" })
end
end
if not minetest.registered_nodes["default:stone_with_mese"] then --before MESE update, use old recipes
minetest.register_craft({
output = "mesecons:wire_00000000_off 18",
recipe = {
{"default:mese"},
}
})
else
minetest.register_craft({ minetest.register_craft({
type = "cooking", type = "cooking",
output = "mesecons:wire_00000000_off 2", output = "mesecons:wire_00000000_off 2",
@ -248,3 +270,11 @@ minetest.register_craft({
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

@ -23,6 +23,14 @@ minetest.register_chatcommand("tell", {
end end
}) })
minetest.register_chatcommand("tellme", {
params = "<text>",
description = "Say <text> to yourself",
func = function(name, param)
minetest.chat_send_player(name, param, false)
end
})
minetest.register_chatcommand("hp", { minetest.register_chatcommand("hp", {
params = "<name> <value>", params = "<name> <value>",
description = "Set health of <name> to <value> hitpoints", description = "Set health of <name> to <value> hitpoints",
@ -42,13 +50,16 @@ minetest.register_chatcommand("hp", {
end end
}) })
local function initialize_data(meta) local initialize_data = function(meta, player, command, param)
local commands = meta:get_string("commands")
meta:set_string("formspec", meta:set_string("formspec",
"invsize[9,5;]" .. "invsize[9,6;]" ..
"textarea[0.5,0.5;8.5,4;commands;Commands;"..commands.."]" .. "field[1,1;7.5,1;player;Player;" .. player .. "]" ..
"label[1,3.8;@nearest, @farthest, and @random are replaced by the respective player names]" .. "button[1.3,2;2,1;nearest;Nearest]" ..
"button_exit[3.3,4.5;2,1;submit;Submit]") "button[3.3,2;2,1;farthest;Farthest]" ..
"button[5.3,2;2,1;random;Random]" ..
"field[1,4;2,1;command;Command;" .. command .. "]" ..
"field[3,4;5.5,1;param;Parameter;" .. param .. "]" ..
"button_exit[3.3,5;2,1;submit;Submit]")
local owner = meta:get_string("owner") local owner = meta:get_string("owner")
if owner == "" then if owner == "" then
owner = "not owned" owner = "not owned"
@ -57,64 +68,81 @@ local function initialize_data(meta)
end end
meta:set_string("infotext", "Command Block\n" .. meta:set_string("infotext", "Command Block\n" ..
"(" .. owner .. ")\n" .. "(" .. owner .. ")\n" ..
"Commands: "..commands) "Command: /" .. command .. " " .. param)
end end
local function construct(pos) local construct = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("commands", "tell @nearest Commandblock unconfigured") meta:set_string("player", "@nearest")
meta:set_string("command", "time")
meta:set_string("param", "7000")
meta:set_string("owner", "") meta:set_string("owner", "")
initialize_data(meta) initialize_data(meta, "@nearest", "time", "7000")
end end
local function after_place(pos, placer) local after_place = function(pos, placer)
if placer then if placer then
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name()) meta:set_string("owner", placer:get_player_name())
initialize_data(meta) initialize_data(meta, "@nearest", "time", "7000")
end end
end end
local function receive_fields(pos, formname, fields, sender) local receive_fields = function(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)
local owner = meta:get_string("owner") if fields.nearest then
if owner ~= "" and sender:get_player_name() ~= owner then initialize_data(meta, "@nearest", fields.command, fields.param)
return elseif fields.farthest then
end initialize_data(meta, "@farthest", fields.command, fields.param)
meta:set_string("commands", fields.commands) elseif fields.random then
initialize_data(meta, "@random", fields.command, fields.param)
else --fields.submit or pressed enter
meta:set_string("player", fields.player)
meta:set_string("command", fields.command)
meta:set_string("param", fields.param)
initialize_data(meta) initialize_data(meta, fields.player, fields.command, fields.param)
end
end end
local function resolve_commands(commands, pos) local resolve_player = function(name, pos)
local nearest, farthest = nil, nil local get_distance = function(pos1, pos2)
local min_distance, max_distance = math.huge, -1 return math.sqrt((pos1.x - pos2.x) ^ 2 + (pos1.y - pos2.y) ^ 2 + (pos1.z - pos2.z) ^ 2)
local players = minetest.get_connected_players() end
for index, player in pairs(players) do
local distance = vector.distance(pos, player:getpos()) if name == "@nearest" then
local min_distance = math.huge
for index, player in ipairs(minetest.get_connected_players()) do
local distance = get_distance(pos, player:getpos())
if distance < min_distance then if distance < min_distance then
min_distance = distance min_distance = distance
nearest = player:get_player_name() name = player:get_player_name()
end end
end
elseif name == "@farthest" then
local max_distance = -1
for index, player in ipairs(minetest.get_connected_players()) do
local distance = get_distance(pos, player:getpos())
if distance > max_distance then if distance > max_distance then
max_distance = distance max_distance = distance
farthest = player:get_player_name() name = player:get_player_name()
end end
end end
local random = players[math.random(#players)]:get_player_name() elseif name == "@random" then
commands = commands:gsub("@nearest", nearest) local players = minetest.get_connected_players()
commands = commands:gsub("@farthest", farthest) local player = players[math.random(#players)]
commands = commands:gsub("@random", random) name = player:get_player_name()
return commands end
return name
end end
local function commandblock_action_on(pos, node) local commandblock_action_on = function(pos, node)
if node.name ~= "mesecons_commandblock:commandblock_off" then if node.name ~= "mesecons_commandblock:commandblock_off" then
return return
end end
@ -122,48 +150,29 @@ local function commandblock_action_on(pos, node)
minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_on"}) minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_on"})
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local command = minetest.chatcommands[meta:get_string("command")]
if command == nil then
return
end
local owner = meta:get_string("owner") local owner = meta:get_string("owner")
if owner == "" then if owner == "" then
return return
end end
local has_privs, missing_privs = minetest.check_player_privs(owner, command.privs)
local commands = resolve_commands(meta:get_string("commands"), pos)
for _, command in pairs(commands:split("\n")) do
local pos = command:find(" ")
local cmd, param = command, ""
if pos then
cmd = command:sub(1, pos - 1)
param = command:sub(pos + 1)
end
local cmddef = minetest.chatcommands[cmd]
if not cmddef then
minetest.chat_send_player(owner, "The command "..cmd.." does not exist")
return
end
local has_privs, missing_privs = minetest.check_player_privs(owner, cmddef.privs)
if not has_privs then if not has_privs then
minetest.chat_send_player(owner, "You don't have permission " minetest.chat_send_player(owner, "You don't have permission to run this command (missing privileges: "..table.concat(missing_privs, ", ")..")")
.."to run "..cmd
.." (missing privileges: "
..table.concat(missing_privs, ", ")..")")
return return
end end
cmddef.func(owner, param) local player = resolve_player(meta:get_string("player"), pos)
end command.func(player, meta:get_string("param"))
end end
local function commandblock_action_off(pos, node) local commandblock_action_off = function(pos, node)
if node.name == "mesecons_commandblock:commandblock_on" then if node.name == "mesecons_commandblock:commandblock_on" then
minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_off"}) minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_off"})
end end
end end
local function can_dig(pos, player)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
return owner == "" or owner == player:get_player_name()
end
minetest.register_node("mesecons_commandblock:commandblock_off", { minetest.register_node("mesecons_commandblock:commandblock_off", {
description = "Command Block", description = "Command Block",
tiles = {"jeija_commandblock_off.png"}, tiles = {"jeija_commandblock_off.png"},
@ -172,7 +181,10 @@ minetest.register_node("mesecons_commandblock:commandblock_off", {
on_construct = construct, on_construct = construct,
after_place_node = after_place, after_place_node = after_place,
on_receive_fields = receive_fields, on_receive_fields = receive_fields,
can_dig = can_dig, can_dig = function(pos,player)
local owner = minetest.get_meta(pos):get_string("owner")
return owner == "" or owner == player:get_player_name()
end,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_on = commandblock_action_on action_on = commandblock_action_on
@ -187,7 +199,10 @@ minetest.register_node("mesecons_commandblock:commandblock_on", {
on_construct = construct, on_construct = construct,
after_place_node = after_place, after_place_node = after_place,
on_receive_fields = receive_fields, on_receive_fields = receive_fields,
can_dig = can_dig, can_dig = function(pos,player)
local owner = minetest.get_meta(pos):get_string("owner")
return owner == "" or owner == player:get_player_name()
end,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_off = commandblock_action_off action_off = commandblock_action_off

View File

@ -0,0 +1,167 @@
doors = {}
-- Registers a door - REDEFINITION ONLY | DOORS MOD MUST HAVE BEEN LOADED BEFORE
-- name: The name of the door
-- def: a table with the folowing fields:
-- description
-- inventory_image
-- groups
-- tiles_bottom: the tiles of the bottom part of the door {front, side}
-- tiles_top: the tiles of the bottom part of the door {front, side}
-- If the following fields are not defined the default values are used
-- node_box_bottom
-- node_box_top
-- selection_box_bottom
-- selection_box_top
-- only_placer_can_open: if true only the player who placed the door can
-- open it
function doors:register_door(name, def)
def.groups.not_in_creative_inventory = 1
local box = {{-0.5, -0.5, -0.5, 0.5, 0.5, -0.5+1.5/16}}
if not def.node_box_bottom then
def.node_box_bottom = box
end
if not def.node_box_top then
def.node_box_top = box
end
if not def.selection_box_bottom then
def.selection_box_bottom= box
end
if not def.selection_box_top then
def.selection_box_top = box
end
local tt = def.tiles_top
local tb = def.tiles_bottom
local function after_dig_node(pos, name)
if minetest.get_node(pos).name == name then
minetest.remove_node(pos)
end
end
local function on_rightclick(pos, dir, check_name, replace, replace_dir, params)
pos.y = pos.y+dir
if not minetest.get_node(pos).name == check_name then
return
end
local p2 = minetest.get_node(pos).param2
p2 = params[p2+1]
local meta = minetest.get_meta(pos):to_table()
minetest.set_node(pos, {name=replace_dir, param2=p2})
minetest.get_meta(pos):from_table(meta)
pos.y = pos.y-dir
meta = minetest.get_meta(pos):to_table()
minetest.set_node(pos, {name=replace, param2=p2})
minetest.get_meta(pos):from_table(meta)
end
local function on_mesecons_signal_open (pos, node)
on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0})
end
local function on_mesecons_signal_close (pos, node)
on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2})
end
local function check_player_priv(pos, player)
if not def.only_placer_can_open then
return true
end
local meta = minetest.get_meta(pos)
local pn = player:get_player_name()
return meta:get_string("doors_owner") == pn
end
minetest.register_node(":"..name.."_b_1", {
tiles = {tb[2], tb[2], tb[2], tb[2], tb[1], tb[1].."^[transformfx"},
paramtype = "light",
paramtype2 = "facedir",
drop = name,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = def.node_box_bottom
},
selection_box = {
type = "fixed",
fixed = def.selection_box_bottom
},
groups = def.groups,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
pos.y = pos.y+1
after_dig_node(pos, name.."_t_1")
end,
on_rightclick = function(pos, node, puncher)
if check_player_priv(pos, puncher) then
on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0})
end
end,
mesecons = {effector = {
action_on = on_mesecons_signal_open
}},
can_dig = check_player_priv,
})
minetest.register_node(":"..name.."_b_2", {
tiles = {tb[2], tb[2], tb[2], tb[2], tb[1].."^[transformfx", tb[1]},
paramtype = "light",
paramtype2 = "facedir",
drop = name,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = def.node_box_bottom
},
selection_box = {
type = "fixed",
fixed = def.selection_box_bottom
},
groups = def.groups,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
pos.y = pos.y+1
after_dig_node(pos, name.."_t_2")
end,
on_rightclick = function(pos, node, puncher)
if check_player_priv(pos, puncher) then
on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2})
end
end,
mesecons = {effector = {
action_off = on_mesecons_signal_close
}},
can_dig = check_player_priv,
})
end
doors:register_door("doors:door_wood", {
description = "Wooden Door",
inventory_image = "door_wood.png",
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=2,door=1},
tiles_bottom = {"door_wood_b.png", "door_brown.png"},
tiles_top = {"door_wood_a.png", "door_brown.png"},
sounds = default.node_sound_wood_defaults(),
})
doors:register_door("doors:door_steel", {
description = "Steel Door",
inventory_image = "door_steel.png",
groups = {snappy=1,bendy=2,cracky=1,melty=2,level=2,door=1},
tiles_bottom = {"door_steel_b.png", "door_grey.png"},
tiles_top = {"door_steel_a.png", "door_grey.png"},
only_placer_can_open = true,
sounds = default.node_sound_stone_defaults(),
})

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,25 +10,35 @@ 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
-- Functions that are called after the delay time -- Functions that are called after the delay time
local delayer_turnon = function(params)
local rules = delayer_get_output_rules(params.node)
mesecon:receptor_on(params.pos, rules)
end
local delayer_turnoff = function(params)
local rules = delayer_get_output_rules(params.node)
mesecon:receptor_off(params.pos, rules)
end
local delayer_activate = function(pos, node) local delayer_activate = function(pos, node)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
local time = def.delayer_time local time = def.delayer_time
minetest.swap_node(pos, {name = def.delayer_onstate, param2=node.param2}) minetest.swap_node(pos, {name = def.delayer_onstate, param2=node.param2})
mesecon.queue:add_action(pos, "receptor_on", {delayer_get_output_rules(node)}, time, nil) minetest.after(time, delayer_turnon , {pos = pos, node = node})
end end
local delayer_deactivate = function(pos, node) local delayer_deactivate = function(pos, node)
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
local time = def.delayer_time local time = def.delayer_time
minetest.swap_node(pos, {name = def.delayer_offstate, param2=node.param2}) minetest.swap_node(pos, {name = def.delayer_offstate, param2=node.param2})
mesecon.queue:add_action(pos, "receptor_off", {delayer_get_output_rules(node)}, time, nil) minetest.after(time, delayer_turnoff, {pos = pos, node = node})
end end
-- Register the 2 (states) x 4 (delay times) delayers -- Register the 2 (states) x 4 (delay times) delayers

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
@ -8,13 +6,13 @@ local object_detector_make_formspec = function (pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("formspec", "size[9,2.5]" .. meta:set_string("formspec", "size[9,2.5]" ..
"field[0.3, 0;9,2;scanname;Name of player to scan for (empty for any):;${scanname}]".. "field[0.3, 0;9,2;scanname;Name of player to scan for (empty for any):;${scanname}]"..
"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]".. "field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]")
"button_exit[7,0.75;2,3;;Save]")
end end
local object_detector_on_receive_fields = function(pos, formname, fields) local object_detector_on_receive_fields = function(pos, formname, fields)
if not fields.scanname or not fields.digiline_channel then return end; if fields.quit then
return
end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("scanname", fields.scanname) meta:set_string("scanname", fields.scanname)
meta:set_string("digiline_channel", fields.digiline_channel) meta:set_string("digiline_channel", fields.digiline_channel)
@ -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,80 +0,0 @@
-- Modified, from minetest_game/mods/doors/init.lua
local function on_rightclick(pos, dir, check_name, replace, replace_dir, params)
pos.y = pos.y + dir
if not minetest.get_node(pos).name == check_name then
return
end
local p2 = minetest.get_node(pos).param2
p2 = params[p2 + 1]
minetest.swap_node(pos, {name = replace_dir, param2 = p2})
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
}},
})
minetest.override_item(name.."_b_2", {
mesecons = {effector = {
action_on = toggle_state2,
action_off = toggle_state2,
rules = mesecon.rules.pplate
}},
})
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

@ -77,7 +77,7 @@ minetest.register_node("mesecons_extrawires:crossover_01", {
{ -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 }, { -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 },
}, },
}, },
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1}, groups = {dig_immediate=3, mesecon=3, mesecon_conductor_craftable=1, not_in_creative_inventory=1},
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
@ -113,7 +113,7 @@ minetest.register_node("mesecons_extrawires:crossover_10", {
{ -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 }, { -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 },
}, },
}, },
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1}, groups = {dig_immediate=3, mesecon=3, mesecon_conductor_craftable=1, not_in_creative_inventory=1},
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
@ -149,7 +149,7 @@ minetest.register_node("mesecons_extrawires:crossover_on", {
{ -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 }, { -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 },
}, },
}, },
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1}, groups = {dig_immediate=3, mesecon=3, mesecon_conductor_craftable=1, not_in_creative_inventory=1},
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,

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
@ -38,7 +38,7 @@ minetest.register_node("mesecons_extrawires:tjunction_on", {
sunlight_propagates = true, sunlight_propagates = true,
selection_box = tjunction_selectionbox, selection_box = tjunction_selectionbox,
node_box = tjunction_nodebox, node_box = tjunction_nodebox,
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, mesecon_conductor_craftable=1, not_in_creative_inventory = 1},
drop = "mesecons_extrawires:tjunction_off", drop = "mesecons_extrawires:tjunction_off",
mesecons = {conductor = mesecons = {conductor =
{ {

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,223 @@
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)
local gate = minetest.registered_nodes[node.name] gate = get_gate(pos)
L = rotate_ports(
if mesecon.do_overheat(pos) then yc_get_real_portstates(pos),
minetest.remove_node(pos) minetest.get_node(pos).param2
mesecon.receptor_off(pos, gate_get_output_rules(node)) )
minetest.add_item(pos, gate.drop) if gate == "diode" then
elseif state then set_gate(pos, L.a)
minetest.swap_node(pos, {name = gate.onstate, param2=node.param2}) elseif gate == "not" then
mesecon.receptor_on(pos, gate_get_output_rules(node)) set_gate(pos, not L.a)
else elseif gate == "nand" then
minetest.swap_node(pos, {name = gate.offstate, param2=node.param2}) set_gate(pos, not(L.b and L.d))
mesecon.receptor_off(pos, gate_get_output_rules(node)) 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
yc_heat(meta)
local val1 = meta:get_int("input1") == 1 --minetest.after(0.5, yc_cool, meta)
local val2 = meta:get_int("input2") == 1 if yc_overheat(meta) then
set_gate(pos, node, gate.assess(val1, val2)) pop_gate(pos)
else
local node = minetest.get_node(pos)
if on then
minetest.swap_node(pos, {name = "mesecons_gates:"..gate.."_on", param2=node.param2})
mesecon:receptor_on(pos,
gate_get_output_rules(node))
else
minetest.swap_node(pos, {name = "mesecons_gates:"..gate.."_off", param2=node.param2})
mesecon:receptor_off(pos,
gate_get_output_rules(node))
end
end
end end
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, yc_overheat_off, pos)
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)
meta:set_int("heat", 0)
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', '', ''},
},
})
minetest.register_craft({
output = 'mesecons_gates:xor_off',
recipe = {
{'mesecons:mesecon', '', ''},
{'', 'mesecons_materials:silicon', 'mesecons_materials:silicon'},
{'mesecons:mesecon', '', ''},
},
})
register_gate("xor", 2, function (val1, val2) return (val1 or val2) and not (val1 and val2) end,
{{"mesecons:mesecon", "", ""},
{"", "mesecons_materials:silicon", "mesecons_materials:silicon"},
{"mesecons:mesecon", "", ""}})

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

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,42 @@
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 portstates 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) local get_real_portstates = function(pos) -- determine if ports are powered (by itself or from outside)
local meta = minetest.get_meta(pos) ports = {
if rule_name == nil then a = mesecon:is_power_on(mesecon:addPosRule(pos, rules.a), mesecon:invertRule(rules.a))
meta:set_int("real_portstates", 1) and mesecon:rules_link(mesecon:addPosRule(pos, rules.a), pos),
return b = mesecon:is_power_on(mesecon:addPosRule(pos, rules.b), mesecon:invertRule(rules.b))
end and mesecon:rules_link(mesecon:addPosRule(pos, rules.b), pos),
local n = meta:get_int("real_portstates") - 1 c = mesecon:is_power_on(mesecon:addPosRule(pos, rules.c), mesecon:invertRule(rules.c))
local L = {} and mesecon:rules_link(mesecon:addPosRule(pos, rules.c), pos),
for i = 1, 4 do d = mesecon:is_power_on(mesecon:addPosRule(pos, rules.d), mesecon:invertRule(rules.d))
L[i] = n % 2 and mesecon:rules_link(mesecon:addPosRule(pos, rules.d), pos),
n = math.floor(n / 2)
end
-- (0,-1) (-1,0) (1,0) (0,1)
local pos_to_side = { 4, 1, nil, 3, 2 }
if rule_name.x == nil then
for _, rname in ipairs(rule_name) do
local port = pos_to_side[rname.x + (2 * rname.z) + 3]
L[port] = (newstate == "on") and 1 or 0
end
else
local port = pos_to_side[rule_name.x + (2 * rule_name.z) + 3]
L[port] = (new_state == "on") and 1 or 0
end
meta:set_int("real_portstates",
1 +
1 * L[1] +
2 * L[2] +
4 * L[3] +
8 * L[4])
end
local port_names = {"a", "b", "c", "d"}
local function get_real_port_states(pos)
-- Determine if ports are powered (by itself or from outside)
local meta = minetest.get_meta(pos)
local L = {}
local n = meta:get_int("real_portstates") - 1
for _, name in ipairs(port_names) do
L[name] = ((n % 2) == 1)
n = math.floor(n / 2)
end
return L
end
local function merge_port_states(ports, vports)
return {
a = ports.a or vports.a,
b = ports.b or vports.b,
c = ports.c or vports.c,
d = ports.d or vports.d,
} }
return ports
end end
local function generate_name(ports) local merge_portstates = function (ports, vports)
local npo = {a=false, b=false, c=false, d=false}
npo.a = vports.a or ports.a
npo.b = vports.b or ports.b
npo.c = vports.c or ports.c
npo.d = vports.d or ports.d
return npo
end
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,175 +63,168 @@ 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 heat = function (meta) -- warm up
-- Overheating -- h = meta:get_int("heat")
----------------- if h ~= nil then
meta:set_int("heat", h + 1)
local function overheat_off(pos) end
mesecon.receptor_off(pos, mesecon.rules.flat)
end end
--local cool = function (meta) -- cool down after a while
-- h = meta:get_int("heat")
-- if h ~= nil then
-- meta:set_int("heat", h - 1)
-- end
--end
local function overheat(pos, meta) local overheat = function (meta) -- determine if too hot
if mesecon.do_overheat(pos) then -- If too hot h = meta:get_int("heat")
local node = minetest.get_node(pos) if h == nil then return true end -- if nil then overheat
node.name = BASENAME.."_burnt" if h > 40 then
minetest.swap_node(pos, node)
-- Wait for pending operations
minetest.after(0.2, overheat_off, pos)
return true return true
else
return false
end end
end end
------------------------ local overheat_off = function(pos)
-- Ignored off events -- mesecon:receptor_off(pos, mesecon.rules.flat)
------------------------ end
local function ignore_event(event, meta) -------------------
if event.type ~= "off" then return false end -- Parsing stuff --
local ignore_offevents = minetest.deserialize(meta:get_string("ignore_offevents")) or {} -------------------
if ignore_offevents[event.pin.name] then
ignore_offevents[event.pin.name] = nil local code_prohibited = function(code)
meta:set_string("ignore_offevents", minetest.serialize(ignore_offevents)) -- Clean code
return true local prohibited = {"while", "for", "repeat", "until", "function", "goto"}
for _, p in ipairs(prohibited) do
if string.find(code, p) then
return "Prohibited command: "..p
end
end end
end end
------------------------- local safe_print = function(param)
-- 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
local interrupt = function(params)
lc_update(params.pos, {type="interrupt", iid = params.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") local iid = iid or math.random()
mesecon.queue:add_action(pos, "lc_interrupt", {luac_id, iid}, time, iid, 1) local meta = minetest.get_meta(pos)
local interrupts = minetest.deserialize(meta:get_string("lc_interrupts")) or {}
local found = false
local search = safe_serialize(iid)
for _, i in ipairs(interrupts) do
if safe_serialize(i) == search then
found = true
break
end
end
if not found then
table.insert(interrupts, iid)
meta:set_string("lc_interrupts", safe_serialize(interrupts))
end
minetest.after(time, interrupt, {pos=pos, iid = iid})
end end
return interrupt return interrupt
end end
local getdigiline_send = function (pos)
local function get_digiline_send(pos) local digiline_send = function (channel, msg)
if not digiline then return end if digiline then
return function(channel, msg)
minetest.after(0, function()
digiline:receptor_send(pos, digiline.rules.default, channel, msg) digiline:receptor_send(pos, digiline.rules.default, channel, msg)
end)
end end
end end
return digiline_send
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,
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, match = string.match,
rep = string.rep, rep = string.rep,
reverse = string.reverse, reverse = string.reverse,
sub = string.sub, sub = string.sub,
@ -312,119 +261,100 @@ 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 end
return env local create_sandbox = function (code, env)
end -- Create Sandbox
local function timeout()
debug.sethook() -- Clear hook
error("Code timed out!")
end
local function code_prohibited(code)
-- LuaJIT doesn't increment the instruction counter when running
-- loops, so we have to sanitize inputs if we're using LuaJIT.
if not jit then
return false
end
local prohibited = {"while", "for", "do", "repeat", "until", "goto"}
code = " "..code.." "
for _, p in ipairs(prohibited) do
if string.find(code, "[^%w_]"..p.."[^%w_]") then
return "Prohibited command: "..p
end
end
end
local function create_sandbox(code, env)
if code:byte(1) == 27 then 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 do_overheat = function (pos, meta)
debug.sethook(timeout, "", 10000) -- Overheat protection
local ok, ret = pcall(f, ...) heat(meta)
debug.sethook() -- Clear hook --minetest.after(0.5, cool, meta)
if not ok then error(ret) end if overheat(meta) then
return ret local node = minetest.get_node(pos)
minetest.swap_node(pos, {name = BASENAME.."_burnt", param2 = node.param2})
minetest.get_meta(pos):set_string("lc_interrupts", "")
minetest.after(0.2, overheat_off, pos) -- wait for pending operations
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 interrupt_allow = function (meta, event)
if event.type ~= "interrupt" then return true end
local function run(pos, event) local interrupts = minetest.deserialize(meta:get_string("lc_interrupts")) or {}
local search = safe_serialize(event.iid)
for _, i in ipairs(interrupts) do
if safe_serialize(i) == search then
return true
end
end
return false
end
local ports_invalid = function (var)
if type(var) == "table" then
return false
end
return "The ports you set are invalid"
end
----------------------
-- Parsing function --
----------------------
lc_update = function (pos, event)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if overheat(pos) then return end if not interrupt_allow(meta, event) then return end
if ignore_event(event, meta) then return end if do_overheat(pos, 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) minetest.after(0, 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,13 +366,22 @@ 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))
end end
local function reset(pos) local reset = function (pos)
set_port_states(pos, {a=false, b=false, c=false, d=false}) minetest.get_meta(pos):set_string("lc_interrupts", "")
action(pos, {a=false, b=false, c=false, d=false}, true)
end end
-- ______
-- |
-- |
-- | __ ___ _ __ _ _
-- | | | | | |\ | | |_| | | | | |_ |_|
-- |___| |______ |__| | \| | | \ |__| |_ |_ |_ |\
-- |
-- |
--
----------------------- -----------------------
-- Node Registration -- -- Node Registration --
@ -451,16 +390,16 @@ end
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 },
} }
@ -469,29 +408,18 @@ 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 cid = tostring(d)..tostring(c)..tostring(b)..tostring(a)
local node_name = BASENAME..cid local nodename = BASENAME..cid
local top = "jeija_luacontroller_top.png" local top = "jeija_luacontroller_top.png"
if a == 1 then if a == 1 then
top = top.."^jeija_luacontroller_LED_A.png" top = top.."^jeija_luacontroller_LED_A.png"
@ -506,7 +434,6 @@ for d = 0, 1 do
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
@ -515,32 +442,33 @@ for d = 0, 1 do
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(pos, {type=newstate, pin=rulename})
run(pos, {type=new_state, pin=rule_name})
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 +478,43 @@ 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 fields.quit then
return
end
reset(pos)
reset_meta(pos, fields.code)
local err = lc_update(pos, {type="program"})
if err then print(err) end
reset_meta(pos, fields.code, err)
end,
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
-- the node shows as powered up (light up).
virtual_portstates = {
a = a == 1,
b = b == 1,
c = c == 1,
d = d == 1,
},
after_dig_node = function (pos, node)
mesecon.receptor_off(pos, output_rules)
end,
is_luacontroller = true, is_luacontroller = true,
virtual_portstates = { a = a == 1, -- virtual portstates are
b = b == 1, -- the ports the the
c = c == 1, -- controller powers itself
d = d == 1},-- so those that light up
after_dig_node = function (pos, node)
mesecon:receptor_off(pos, output_rules)
end,
}) })
end end
end end
end end
end end
------------------------------ --overheated luacontroller
-- Overheated LuaController --
------------------------------
minetest.register_node(BASENAME .. "_burnt", { minetest.register_node(BASENAME .. "_burnt", {
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
@ -599,20 +530,22 @@ 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)
sounds = default.node_sound_stone_defaults(), if fields.quit then
virtual_portstates = {a = false, b = false, c = false, d = false}, return
mesecons = { end
effector = { reset(pos)
rules = mesecon.rules.flat, reset_meta(pos, fields.code)
action_change = function(pos, _, rule_name, new_state) local err = lc_update(pos, {type="program"})
update_real_port_states(pos, rule_name, new_state) if err then print(err) end
reset_meta(pos, fields.code, err)
end, end,
}, sounds = default.node_sound_stone_defaults(),
}, is_luacontroller = true,
virtual_portstates = {a = false, b = false, c = false, d = false},
}) })
------------------------ ------------------------

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,13 +34,12 @@ 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 =
{ {
rules = input_rules, rules = input_rules,
action_change = function (pos, node, rulename, newstate) action_change = function (pos, node, rulename)
yc_update_real_portstates(pos, node, rulename, newstate)
update_yc(pos) update_yc(pos)
end end
}} }}
@ -95,11 +92,15 @@ minetest.register_node(nodename, {
"button[7.5,0.2;1.5,3;brsflop;RS-Flop]".. "button[7.5,0.2;1.5,3;brsflop;RS-Flop]"..
"button_exit[3.5,1;2,3;program;Program]") "button_exit[3.5,1;2,3;program;Program]")
meta:set_string("infotext", "Unprogrammed Microcontroller") meta:set_string("infotext", "Unprogrammed Microcontroller")
meta:set_int("heat", 0)
local r = "" local r = ""
for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0" for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0"
meta:set_string("eeprom", r) meta:set_string("eeprom", r)
end, end,
on_receive_fields = function(pos, formanme, fields, sender) on_receive_fields = function(pos, formanme, fields, sender)
if fields.quit then
return
end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if fields.band then if fields.band then
fields.code = "sbi(C, A&B) :A and B are inputs, C is output" fields.code = "sbi(C, A&B) :A and B are inputs, C is output"
@ -113,8 +114,8 @@ minetest.register_node(nodename, {
fields.code = "if(A)sbi(1,1);if(!A&#1)sbi(B,!B)sbi(1,0); if(C)off(B,1); :A is input, B is output (Q), C is reset, toggles with falling edge" fields.code = "if(A)sbi(1,1);if(!A&#1)sbi(B,!B)sbi(1,0); if(C)off(B,1); :A is input, B is output (Q), C is reset, toggles with falling edge"
elseif fields.brsflop then elseif fields.brsflop then
fields.code = "if(A)on(C);if(B)off(C); :A is S (Set), B is R (Reset), C is output (R dominates)" fields.code = "if(A)on(C);if(B)off(C); :A is S (Set), B is R (Reset), C is output (R dominates)"
end elseif fields.program or fields.code then --nothing
if fields.code == nil then return end else return nil end
meta:set_string("code", fields.code) meta:set_string("code", fields.code)
meta:set_string("formspec", "size[9,2.5]".. meta:set_string("formspec", "size[9,2.5]"..
@ -133,8 +134,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
@ -154,6 +155,7 @@ minetest.register_craft({
function yc_reset(pos) function yc_reset(pos)
yc_action(pos, {a=false, b=false, c=false, d=false}) yc_action(pos, {a=false, b=false, c=false, d=false})
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_int("heat", 0)
meta:set_int("afterid", 0) meta:set_int("afterid", 0)
local r = "" local r = ""
for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0" for i=1, EEPROM_SIZE+1 do r=r.."0" end --Generate a string with EEPROM_SIZE*"0"
@ -162,12 +164,11 @@ end
function update_yc(pos) function update_yc(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
yc_heat(meta)
if (mesecon.do_overheat(pos)) then --minetest.after(0.5, yc_cool, meta)
if (yc_overheat(meta)) then
minetest.remove_node(pos) minetest.remove_node(pos)
minetest.after(0.2, function (pos) minetest.after(0.2, yc_overheat_off, pos) --wait for pending parsings
mesecon.receptor_off(pos, mesecon.rules.flat)
end , pos) -- wait for pending parsings
minetest.add_item(pos, "mesecons_microcontroller:microcontroller0000") minetest.add_item(pos, "mesecons_microcontroller:microcontroller0000")
end end
@ -185,7 +186,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 +206,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 +224,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 +237,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 +254,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 +280,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 +303,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 +406,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 +460,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 +504,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 +579,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 +603,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
@ -633,48 +633,35 @@ function yc_set_portstate(port, state, L)
return L return L
end end
function yc_update_real_portstates(pos, node, rulename, newstate) function yc_get_real_portstates(pos) -- port powered or not (by itself or from outside)?
local meta = minetest.get_meta(pos) rulesA = mesecon:get_rules("mesecons_microcontroller:microcontroller0001")
if rulename == nil then rulesB = mesecon:get_rules("mesecons_microcontroller:microcontroller0010")
meta:set_int("real_portstates", 1) rulesC = mesecon:get_rules("mesecons_microcontroller:microcontroller0100")
return rulesD = mesecon:get_rules("mesecons_microcontroller:microcontroller1000")
end L = {
local n = meta:get_int("real_portstates") - 1 a = mesecon:is_power_on(mesecon:addPosRule(pos, rulesA[1]),
local L = {} mesecon:invertRule(rulesA[1])) and
for i = 1, 4 do mesecon:rules_link(mesecon:addPosRule(pos, rulesA[1]), pos),
L[i] = n%2 b = mesecon:is_power_on(mesecon:addPosRule(pos, rulesB[1]),
n = math.floor(n/2) mesecon:invertRule(rulesB[1])) and
end mesecon:rules_link(mesecon:addPosRule(pos, rulesB[1]), pos),
if rulename.x == nil then c = mesecon:is_power_on(mesecon:addPosRule(pos, rulesC[1]),
for _, rname in ipairs(rulename) do mesecon:invertRule(rulesC[1])) and
local port = ({4, 1, nil, 3, 2})[rname.x+2*rname.z+3] mesecon:rules_link(mesecon:addPosRule(pos, rulesC[1]), pos),
L[port] = (newstate == "on") and 1 or 0 d = mesecon:is_power_on(mesecon:addPosRule(pos, rulesD[1]),
end mesecon:invertRule(rulesD[1])) and
else mesecon:rules_link(mesecon:addPosRule(pos, rulesD[1]), pos),
local port = ({4, 1, nil, 3, 2})[rulename.x+2*rulename.z+3] }
L[port] = (newstate == "on") and 1 or 0
end
meta:set_int("real_portstates", 1 + L[1] + 2*L[2] + 4*L[3] + 8*L[4])
end
function yc_get_real_portstates(pos) -- determine if ports are powered (by itself or from outside)
local meta = minetest.get_meta(pos)
local L = {}
local n = meta:get_int("real_portstates") - 1
for _, index in ipairs({"a", "b", "c", "d"}) do
L[index] = ((n%2) == 1)
n = math.floor(n/2)
end
return L return L
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
@ -690,3 +677,34 @@ function yc_merge_portstates(Lreal, Lvirtual)
if Lvirtual.d or Lreal.d then L.d = true end if Lvirtual.d or Lreal.d then L.d = true end
return L return L
end end
--"Overheat" protection
function yc_heat(meta)
h = meta:get_int("heat")
if h ~= nil then
meta:set_int("heat", h + 1)
end
end
--function yc_cool(meta)
-- h = meta:get_int("heat")
-- if h ~= nil then
-- meta:set_int("heat", h - 1)
-- end
--end
function yc_overheat(meta)
if MESECONS_GLOBALSTEP then return false end
h = meta:get_int("heat")
if h == nil then return true end -- if nil the overheat
if h>60 then
return true
else
return false
end
end
function yc_overheat_off(pos)
rules = mesecon:get_rules("mesecons_microcontroller:microcontroller1111")
mesecon:receptor_off(pos, rules)
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(),
mesecons = {receptor = {
state = mesecon.state.off
}},
on_punch = function(pos, node) on_punch = function(pos, node)
if(mesecon.flipstate(pos, node) == "on") then minetest.swap_node(pos, {name = "mesecons_switch:mesecon_switch_on", param2 = node.param2})
mesecon.receptor_on(pos) mesecon:receptor_on(pos)
else
mesecon.receptor_off(pos)
end
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", minetest.register_node("mesecons_switch:mesecon_switch_on", {
"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", 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"},
"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_off.png"}, paramtype2="facedir",
mesecons = {receptor = { state = mesecon.state.off }}
},{
groups = {dig_immediate=2,not_in_creative_inventory=1}, groups = {dig_immediate=2,not_in_creative_inventory=1},
tiles = { "jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", drop="mesecons_switch:mesecon_switch_off 1",
"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_side.png", sounds = default.node_sound_stone_defaults(),
"jeija_mesecon_switch_side.png", "jeija_mesecon_switch_on.png"}, mesecons = {receptor = {
mesecons = {receptor = { state = mesecon.state.on }} 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})
end
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -0,0 +1 @@
-- place texture packs for mesecons into the textures folder here

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

View File

Before

Width:  |  Height:  |  Size: 454 B

After

Width:  |  Height:  |  Size: 454 B

View File

Before

Width:  |  Height:  |  Size: 463 B

After

Width:  |  Height:  |  Size: 463 B

View File

Before

Width:  |  Height:  |  Size: 323 B

After

Width:  |  Height:  |  Size: 323 B

View File

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 282 B

View File

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 278 B

View File

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 592 B

View File

Before

Width:  |  Height:  |  Size: 233 B

After

Width:  |  Height:  |  Size: 233 B

View File

Before

Width:  |  Height:  |  Size: 231 B

After

Width:  |  Height:  |  Size: 231 B

View File

Before

Width:  |  Height:  |  Size: 251 B

After

Width:  |  Height:  |  Size: 251 B

View File

Before

Width:  |  Height:  |  Size: 241 B

After

Width:  |  Height:  |  Size: 241 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 195 B

After

Width:  |  Height:  |  Size: 195 B

View File

Before

Width:  |  Height:  |  Size: 245 B

After

Width:  |  Height:  |  Size: 245 B

View File

Before

Width:  |  Height:  |  Size: 743 B

After

Width:  |  Height:  |  Size: 743 B

View File

Before

Width:  |  Height:  |  Size: 777 B

After

Width:  |  Height:  |  Size: 777 B

View File

Before

Width:  |  Height:  |  Size: 487 B

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 817 B

View File

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 305 B

View File

Before

Width:  |  Height:  |  Size: 270 B

After

Width:  |  Height:  |  Size: 270 B

View File

Before

Width:  |  Height:  |  Size: 209 B

After

Width:  |  Height:  |  Size: 209 B

View File

Before

Width:  |  Height:  |  Size: 253 B

After

Width:  |  Height:  |  Size: 253 B

View File

Before

Width:  |  Height:  |  Size: 196 B

After

Width:  |  Height:  |  Size: 196 B

View File

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 246 B

View File

Before

Width:  |  Height:  |  Size: 252 B

After

Width:  |  Height:  |  Size: 252 B

View File

Before

Width:  |  Height:  |  Size: 238 B

After

Width:  |  Height:  |  Size: 238 B

View File

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 261 B

View File

Before

Width:  |  Height:  |  Size: 142 B

After

Width:  |  Height:  |  Size: 142 B

View File

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 126 B

View File

Before

Width:  |  Height:  |  Size: 200 B

After

Width:  |  Height:  |  Size: 200 B

View File

Before

Width:  |  Height:  |  Size: 169 B

After

Width:  |  Height:  |  Size: 169 B

View File

Before

Width:  |  Height:  |  Size: 260 B

After

Width:  |  Height:  |  Size: 260 B

View File

Before

Width:  |  Height:  |  Size: 545 B

After

Width:  |  Height:  |  Size: 545 B

View File

Before

Width:  |  Height:  |  Size: 447 B

After

Width:  |  Height:  |  Size: 447 B

View File

Before

Width:  |  Height:  |  Size: 667 B

After

Width:  |  Height:  |  Size: 667 B

View File

Before

Width:  |  Height:  |  Size: 452 B

After

Width:  |  Height:  |  Size: 452 B

Some files were not shown because too many files have changed in this diff Show More