Update Bluestone

This commit is contained in:
MoNTE48 2019-06-22 12:22:18 +02:00
parent a51369d706
commit a1ba95d0a2
42 changed files with 2473 additions and 2746 deletions

View File

@ -1 +0,0 @@
0.41 DEV

View File

@ -0,0 +1,101 @@
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(vector.equals(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
mesecon.queue.actions = mesecon.file2table("mesecon_actionqueue")
minetest.register_on_shutdown(function()
mesecon.table2file("mesecon_actionqueue", mesecon.queue.actions)
end)

View File

@ -39,53 +39,26 @@
-- }
--}
-- PUBLIC VARIABLES
mesecon={} -- contains all functions and all global variables
mesecon.actions_on={} -- Saves registered function callbacks for mesecon on | DEPRECATED
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)
mesecon.queue={} -- contains the ActionQueue
mesecon.queue.funcs={} -- contains all ActionQueue functions
-- Settings
dofile(minetest.get_modpath("mesecons").."/settings.lua")
-- Presets (eg default rules)
dofile(minetest.get_modpath("mesecons").."/presets.lua");
-- Utilities like comparing positions,
-- adding positions and rules,
-- mostly things that make the source look cleaner
dofile(minetest.get_modpath("mesecons").."/util.lua");
-- Presets (eg default rules)
dofile(minetest.get_modpath("mesecons").."/presets.lua");
-- The ActionQueue
-- Saves all the actions that have to be execute in the future
dofile(minetest.get_modpath("mesecons").."/actionqueue.lua");
-- Internal stuff
-- This is the most important file
-- it handles signal transmission and basically everything else
@ -96,50 +69,60 @@ dofile(minetest.get_modpath("mesecons").."/internal.lua");
-- API
-- these are the only functions you need to remember
function mesecon:receptor_on_i(pos, rules)
mesecon.queue:add_function("receptor_on", function (pos, rules)
rules = rules or mesecon.rules.default
for _, rule in ipairs(mesecon:flattenrules(rules)) do
local np = mesecon:addPosRule(pos, rule)
local link, rulename = mesecon:rules_link(pos, np, rules)
if link then
mesecon:turnon(np, rulename)
end
-- 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 = vector.add(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
function mesecon:receptor_on(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="on"}
else
mesecon:receptor_on_i(pos, rules)
-- execute action
for _, rule in ipairs(mesecon.flattenrules(rules)) do
local np = vector.add(pos, rule)
local rulenames = mesecon.rules_link_rule_all(pos, rule)
for _, rulename in ipairs(rulenames) do
mesecon.turnon(np, rulename)
end
end
end)
function mesecon.receptor_on(pos, rules)
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
end
function mesecon:receptor_off_i(pos, rules)
mesecon.queue:add_function("receptor_off", function (pos, rules)
rules = rules or mesecon.rules.default
for _, rule in ipairs(mesecon:flattenrules(rules)) do
local np = mesecon:addPosRule(pos, rule)
local link, rulename = mesecon:rules_link(pos, np, rules)
if link then
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
-- 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 = vector.add(pos, rule)
if minetest.get_node_or_nil(np) == nil then
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
return
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"}
for _, rule in ipairs(mesecon.flattenrules(rules)) do
local np = vector.add(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:receptor_off_i(pos, rules)
mesecon.changesignal(np, minetest.get_node(np), rulename, mesecon.state.off, 2)
end
end
end
end)
function mesecon.receptor_off(pos, rules)
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
end
--The actual wires

View File

@ -1,62 +1,58 @@
-- Internal.lua - The core of mesecons
--
-- For more practical developer resources see mesecons.tk
-- For more practical developer resources see http://mesecons.net/developers.php
--
-- Function overview
-- mesecon:get_effector(nodename) --> Returns the mesecons.effector -specifictation in the nodedef by the nodename
-- mesecon:get_receptor(nodename) --> Returns the mesecons.receptor -specifictation in the nodedef by the nodename
-- mesecon:get_conductor(nodename) --> Returns the mesecons.conductor-specifictation in the nodedef by the nodename
-- mesecon:get_any_inputrules (node) --> Returns the rules of a node if it is a conductor or an effector
-- mesecon:get_any_outputrules (node) --> Returns the rules of a node if it is a conductor or a receptor
-- mesecon.get_effector(nodename) --> Returns the mesecons.effector -specifictation in the nodedef by the nodename
-- mesecon.get_receptor(nodename) --> Returns the mesecons.receptor -specifictation in the nodedef by the nodename
-- mesecon.get_conductor(nodename) --> Returns the mesecons.conductor-specifictation in the nodedef by the nodename
-- mesecon.get_any_inputrules (node) --> Returns the rules of a node if it is a conductor or an effector
-- mesecon.get_any_outputrules (node) --> Returns the rules of a node if it is a conductor or a receptor
-- RECEPTORS
-- mesecon:is_receptor(nodename) --> Returns true if nodename is a receptor
-- mesecon:is_receptor_on(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.on
-- mesecon:is_receptor_off(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.off
-- mesecon:receptor_get_rules(node) --> Returns the rules of the receptor (mesecon.rules.default if none specified)
-- mesecon.is_receptor(nodename) --> Returns true if nodename is a receptor
-- mesecon.is_receptor_on(nodename --> Returns true if nodename is an receptor with state = mesecon.state.on
-- mesecon.is_receptor_off(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.off
-- mesecon.receptor_get_rules(node) --> Returns the rules of the receptor (mesecon.rules.default if none specified)
-- EFFECTORS
-- mesecon:is_effector(nodename) --> Returns true if nodename is an effector
-- mesecon:is_effector_on(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_off
-- mesecon:is_effector_off(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_on
-- mesecon:effector_get_rules(node) --> Returns the input rules of the effector (mesecon.rules.default if none specified)
-- mesecon.is_effector(nodename) --> Returns true if nodename is an effector
-- mesecon.is_effector_on(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_off
-- mesecon.is_effector_off(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_on
-- mesecon.effector_get_rules(node) --> Returns the input rules of the effector (mesecon.rules.default if none specified)
-- SIGNALS
-- mesecon:activate(pos, node) --> Activates the effector node at the specific pos (calls nodedef.mesecons.effector.action_on)
-- mesecon:deactivate(pos, node) --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off)
-- mesecon:changesignal(pos, node, rulename, newstate) --> Changes the effector node at the specific pos (calls nodedef.mesecons.effector.action_change)
-- RULES
-- mesecon:add_rules(name, rules) | deprecated? --> Saves rules table by name
-- mesecon:get_rules(name, rules) | deprecated? --> Loads rules table with name
-- mesecon.activate(pos, node, depth) --> Activates the effector node at the specific pos (calls nodedef.mesecons.effector.action_on), higher depths are executed later
-- mesecon.deactivate(pos, node, depth) --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off), higher depths are executed later
-- mesecon.changesignal(pos, node, rulename, newstate, depth) --> Changes the effector node at the specific pos (calls nodedef.mesecons.effector.action_change), higher depths are executed later
-- CONDUCTORS
-- mesecon:is_conductor(nodename) --> Returns true if nodename is a conductor
-- mesecon:is_conductor_on(nodename) --> Returns true if nodename is a conductor with state = mesecon.state.on
-- mesecon:is_conductor_off(nodename) --> Returns true if nodename is a conductor with state = mesecon.state.off
-- mesecon:get_conductor_on(offstate) --> Returns the onstate nodename of the conductor with the name offstate
-- mesecon:get_conductor_off(onstate) --> Returns the offstate nodename of the conductor with the name onstate
-- mesecon:conductor_get_rules(node) --> Returns the input+output rules of a conductor (mesecon.rules.default if none specified)
-- mesecon.is_conductor(nodename) --> Returns true if nodename is a conductor
-- mesecon.is_conductor_on(node --> Returns true if node is a conductor with state = mesecon.state.on
-- mesecon.is_conductor_off(node) --> Returns true if node is a conductor with state = mesecon.state.off
-- mesecon.get_conductor_on(node_off) --> Returns the onstate nodename of the conductor
-- mesecon.get_conductor_off(node_on) --> Returns the offstate nodename of the conductor
-- mesecon.conductor_get_rules(node) --> Returns the input+output rules of a conductor (mesecon.rules.default if none specified)
-- HIGH-LEVEL Internals
-- mesecon:is_power_on(pos) --> Returns true if pos emits power in any way
-- mesecon:is_power_off(pos) --> Returns true if pos does not emit power in any way
-- mesecon:turnon(pos, rulename) --> Returns true whatever there is at pos. Calls itself for connected nodes (if pos is a conductor) --> recursive, the rulename is the name of the input rule that caused calling turnon
-- 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) --> Returns true if pos is connected to a receptor directly or via conductors; calls itself if pos is a conductor --> recursive
-- mesecon:rules_link(output, input, dug_outputrules) --> Returns true if outputposition + outputrules = inputposition and inputposition + inputrules = outputposition (if the two positions connect)
-- mesecon:rules_link_anydir(outp., inp., d_outpr.) --> Same as rules mesecon:rules_link but also returns true if output and input are swapped
-- mesecon:is_powered(pos) --> Returns true if pos is powered by a receptor or a conductor
-- mesecon.is_power_on(pos) --> Returns true if pos emits power in any way
-- mesecon.is_power_off(pos) --> Returns true if pos does not emit power in any way
-- mesecon.turnon(pos, link) --> link is the input rule that caused calling turnon, turns on every connected node, iterative
-- mesecon.turnoff(pos, link) --> link is the input rule that caused calling turnoff, turns off every connected node, iterative
-- mesecon.connected_to_receptor(pos, link) --> Returns true if pos is connected to a receptor directly or via conductors, iterative
-- mesecon.rules_link(output, input, dug_outputrules) --> Returns true if outputposition + outputrules = inputposition and inputposition + inputrules = outputposition (if the two positions connect)
-- mesecon.rules_link_anydir(outp., inp., d_outpr.) --> Same as rules mesecon.rules_link but also returns true if output and input are swapped
-- mesecon.is_powered(pos) --> Returns true if pos is powered by a receptor or a conductor
-- RULES ROTATION helpsers
-- mesecon:rotate_rules_right(rules)
-- mesecon:rotate_rules_left(rules)
-- mesecon:rotate_rules_up(rules)
-- mesecon:rotate_rules_down(rules)
-- RULES ROTATION helpers
-- mesecon.rotate_rules_right(rules)
-- mesecon.rotate_rules_left(rules)
-- mesecon.rotate_rules_up(rules)
-- mesecon.rotate_rules_down(rules)
-- These functions return rules that have been rotated in the specific direction
-- General
function mesecon:get_effector(nodename)
function mesecon.get_effector(nodename)
if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.effector then
@ -64,7 +60,7 @@ function mesecon:get_effector(nodename)
end
end
function mesecon:get_receptor(nodename)
function mesecon.get_receptor(nodename)
if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.receptor then
@ -72,7 +68,7 @@ function mesecon:get_receptor(nodename)
end
end
function mesecon:get_conductor(nodename)
function mesecon.get_conductor(nodename)
if minetest.registered_nodes[nodename]
and minetest.registered_nodes[nodename].mesecons
and minetest.registered_nodes[nodename].mesecons.conductor then
@ -80,52 +76,59 @@ function mesecon:get_conductor(nodename)
end
end
function mesecon:get_any_outputrules (node)
if mesecon:is_conductor(node.name) then
return mesecon:conductor_get_rules(node)
elseif mesecon:is_receptor(node.name) then
return mesecon:receptor_get_rules(node)
function mesecon.get_any_outputrules (node)
if not node then return nil end
if mesecon.is_conductor(node.name) then
return mesecon.conductor_get_rules(node)
elseif mesecon.is_receptor(node.name) then
return mesecon.receptor_get_rules(node)
end
return false
end
function mesecon:get_any_inputrules (node)
if mesecon:is_conductor(node.name) then
return mesecon:conductor_get_rules(node)
elseif mesecon:is_effector(node.name) then
return mesecon:effector_get_rules(node)
function mesecon.get_any_inputrules (node)
if not node then return nil end
if mesecon.is_conductor(node.name) then
return mesecon.conductor_get_rules(node)
elseif mesecon.is_effector(node.name) then
return mesecon.effector_get_rules(node)
end
return false
end
function mesecon.get_any_rules (node)
return mesecon.mergetable(mesecon.get_any_inputrules(node) or {},
mesecon.get_any_outputrules(node) or {})
end
-- Receptors
-- Nodes that can power mesecons
function mesecon:is_receptor_on(nodename)
local receptor = mesecon:get_receptor(nodename)
function mesecon.is_receptor_on(nodename)
local receptor = mesecon.get_receptor(nodename)
if receptor and receptor.state == mesecon.state.on then
return true
end
return false
end
function mesecon:is_receptor_off(nodename)
local receptor = mesecon:get_receptor(nodename)
function mesecon.is_receptor_off(nodename)
local receptor = mesecon.get_receptor(nodename)
if receptor and receptor.state == mesecon.state.off then
return true
end
return false
end
function mesecon:is_receptor(nodename)
local receptor = mesecon:get_receptor(nodename)
function mesecon.is_receptor(nodename)
local receptor = mesecon.get_receptor(nodename)
if receptor then
return true
end
return false
end
function mesecon:receptor_get_rules(node)
local receptor = mesecon:get_receptor(node.name)
function mesecon.receptor_get_rules(node)
local receptor = mesecon.get_receptor(node.name)
if receptor then
local rules = receptor.rules
if type(rules) == 'function' then
@ -140,32 +143,32 @@ end
-- Effectors
-- Nodes that can be powered by mesecons
function mesecon:is_effector_on(nodename)
local effector = mesecon:get_effector(nodename)
function mesecon.is_effector_on(nodename)
local effector = mesecon.get_effector(nodename)
if effector and effector.action_off then
return true
end
return false
end
function mesecon:is_effector_off(nodename)
local effector = mesecon:get_effector(nodename)
function mesecon.is_effector_off(nodename)
local effector = mesecon.get_effector(nodename)
if effector and effector.action_on then
return true
end
return false
end
function mesecon:is_effector(nodename)
local effector = mesecon:get_effector(nodename)
function mesecon.is_effector(nodename)
local effector = mesecon.get_effector(nodename)
if effector then
return true
end
return false
end
function mesecon:effector_get_rules(node)
local effector = mesecon:get_effector(node.name)
function mesecon.effector_get_rules(node)
local effector = mesecon.get_effector(node.name)
if effector then
local rules = effector.rules
if type(rules) == 'function' then
@ -177,210 +180,168 @@ function mesecon:effector_get_rules(node)
return mesecon.rules.default
end
--Signals
-- #######################
-- # Signals (effectors) #
-- #######################
-- Activation:
mesecon.queue:add_function("activate", function (pos, rulename)
local node = mesecon.get_node_force(pos)
if not node then return end
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
effector.action_on (pos, node, rulename)
end
end
end
end)
function mesecon:deactivate(pos, node, rulename)
if MESECONS_GLOBALSTEP then
function mesecon.activate(pos, node, rulename, depth)
if rulename == nil then
for _,rule in ipairs(mesecon:effector_get_rules(node)) do
mesecon:deactivate(pos, node, rule)
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
mesecon.activate(pos, node, rule, depth + 1)
end
return
end
add_action(pos, "off", rulename)
else
local effector = mesecon:get_effector(node.name)
mesecon.queue:add_action(pos, "activate", {rulename}, nil, rulename, 1 / depth)
end
-- Deactivation
mesecon.queue:add_function("deactivate", function (pos, rulename)
local node = mesecon.get_node_force(pos)
if not node then return end
local effector = mesecon.get_effector(node.name)
if effector and effector.action_off then
effector.action_off (pos, node, rulename)
end
end
end
end)
function mesecon:changesignal(pos, node, rulename, newstate)
newstate = newstate or "on"
--rulename = rulename or mesecon.rules.default
if MESECONS_GLOBALSTEP then
function mesecon.deactivate(pos, node, rulename, depth)
if rulename == nil then
for _,rule in ipairs(mesecon:effector_get_rules(node)) do
mesecon:changesignal(pos, node, rule, newstate)
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
mesecon.deactivate(pos, node, rule, depth + 1)
end
return
end
add_action(pos, "c"..newstate, rulename)
else
local effector = mesecon:get_effector(node.name)
mesecon.queue:add_action(pos, "deactivate", {rulename}, nil, rulename, 1 / depth)
end
-- Change
mesecon.queue:add_function("change", function (pos, rulename, changetype)
local node = mesecon.get_node_force(pos)
if not node then return end
local effector = mesecon.get_effector(node.name)
if effector and effector.action_change then
effector.action_change (pos, node, rulename, newstate)
effector.action_change(pos, node, rulename, changetype)
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
return
end
function execute_actions(dtime)
local nactions = mesecon.to_update
mesecon.to_update = {}
for _,i in ipairs(nactions) do
local node = minetest.get_node(i.pos)
if node.name=="ignore" then
add_action(i.pos, i.action, i.rname)
else
local 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 in ipairs(mesecon.to_update) do
if i.pos.x == pos.x and i.pos.y == pos.y and i.pos.z == pos.z and i.rname.x == rname.x and i.rname.y == rname.y and i.rname.z == rname.z then
if (i.action == "on" and action == "on") or (i.action == "off" and action == "off") then
--nothing
elseif i.action == "coff" and action == "on" then i.action = "on"
elseif i.action == "con" and action == "off" then i.action = "off"
else
if action == "on" or action == "con" then i.action = "con" end
if action == "off" or action == "coff" then i.action = "coff" end
end
break
end
end
mesecon.to_update[#mesecon.to_update+1] = {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]
-- Include "change" in overwritecheck so that it cannot be overwritten
-- by "active" / "deactivate" that will be called upon the node at the same time.
local overwritecheck = {"change", rulename}
mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, overwritecheck, 1 / depth)
end
-- Conductors
function mesecon:is_conductor_on(nodename, rulename)
local conductor = mesecon:get_conductor(nodename)
function mesecon.is_conductor_on(node, rulename)
if not node then return false end
local conductor = mesecon.get_conductor(node.name)
if conductor then
if conductor.state then
return conductor.state == mesecon.state.on
end
if conductor.states then
if not rulename then
return mesecon:getstate(nodename, conductor.states) ~= 1
return mesecon.getstate(node.name, conductor.states) ~= 1
end
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[nodename]))
local binstate = mesecon:getbinstate(nodename, conductor.states)
return mesecon:get_bit(binstate, bit)
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node))
local binstate = mesecon.getbinstate(node.name, conductor.states)
return mesecon.get_bit(binstate, bit)
end
end
return false
end
function mesecon:is_conductor_off(nodename, rulename)
local conductor = mesecon:get_conductor(nodename)
function mesecon.is_conductor_off(node, rulename)
if not node then return false end
local conductor = mesecon.get_conductor(node.name)
if conductor then
if conductor.state then
return conductor.state == mesecon.state.off
end
if conductor.states then
if not rulename then
return mesecon:getstate(nodename, conductor.states) == 1
return mesecon.getstate(node.name, conductor.states) == 1
end
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[nodename]))
local binstate = mesecon:getbinstate(nodename, conductor.states)
return not mesecon:get_bit(binstate, bit)
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node))
local binstate = mesecon.getbinstate(node.name, conductor.states)
return not mesecon.get_bit(binstate, bit)
end
end
return false
end
function mesecon:is_conductor(nodename)
local conductor = mesecon:get_conductor(nodename)
function mesecon.is_conductor(nodename)
local conductor = mesecon.get_conductor(nodename)
if conductor then
return true
end
return false
end
function mesecon:get_conductor_on(offstate, rulename)
local conductor = mesecon:get_conductor(offstate)
function mesecon.get_conductor_on(node_off, rulename)
local conductor = mesecon.get_conductor(node_off.name)
if conductor then
if conductor.onstate then
return conductor.onstate
end
if conductor.states then
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[offstate]))
local binstate = mesecon:getbinstate(offstate, conductor.states)
binstate = mesecon:set_bit(binstate, bit, "1")
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_off))
local binstate = mesecon.getbinstate(node_off.name, conductor.states)
binstate = mesecon.set_bit(binstate, bit, "1")
return conductor.states[tonumber(binstate,2)+1]
end
end
return offstate
end
function mesecon:get_conductor_off(onstate, rulename)
local conductor = mesecon:get_conductor(onstate)
function mesecon.get_conductor_off(node_on, rulename)
local conductor = mesecon.get_conductor(node_on.name)
if conductor then
if conductor.offstate then
return conductor.offstate
end
if conductor.states then
local bit = mesecon:rule2bit(rulename, mesecon:conductor_get_rules(minetest.registered_nodes[onstate]))
local binstate = mesecon:getbinstate(onstate, conductor.states)
binstate = mesecon:set_bit(binstate, bit, "0")
local bit = mesecon.rule2bit(rulename, mesecon.conductor_get_rules(node_on))
local binstate = mesecon.getbinstate(node_on.name, conductor.states)
binstate = mesecon.set_bit(binstate, bit, "0")
return conductor.states[tonumber(binstate,2)+1]
end
end
return onstate
end
function mesecon:conductor_get_rules(node)
local conductor = mesecon:get_conductor(node.name)
function mesecon.conductor_get_rules(node)
local conductor = mesecon.get_conductor(node.name)
if conductor then
local rules = conductor.rules
if type(rules) == 'function' then
@ -394,101 +355,128 @@ end
-- some more general high-level stuff
function mesecon:is_power_on(pos, rulename)
local node = minetest.get_node(pos)
if mesecon:is_conductor_on(node.name, rulename) or mesecon:is_receptor_on(node.name) then
function mesecon.is_power_on(pos, rulename)
local node = mesecon.get_node_force(pos)
if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then
return true
end
return false
end
function mesecon:is_power_off(pos, rulename)
local node = minetest.get_node(pos)
if mesecon:is_conductor_off(node.name, rulename) or mesecon:is_receptor_off(node.name) then
function mesecon.is_power_off(pos, rulename)
local node = mesecon.get_node_force(pos)
if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then
return true
end
return false
end
function mesecon:turnon(pos, rulename)
local node = minetest.get_node(pos)
function mesecon.turnon(pos, link)
local frontiers = {{pos = pos, link = link}}
if mesecon:is_conductor_off(node.name, rulename) then
local rules = mesecon:conductor_get_rules(node)
local depth = 1
while frontiers[depth] do
local f = frontiers[depth]
local node = mesecon.get_node_force(f.pos)
if not rulename then
for _, rule in ipairs(mesecon:flattenrules(rules)) do
if mesecon:connected_to_receptor(pos, rule) then
mesecon:turnon(pos, rule)
-- area not loaded, postpone action
if not node then
mesecon.queue:add_action(f.pos, "turnon", {link}, nil, true)
elseif mesecon.is_conductor_off(node, f.link) then
local rules = mesecon.conductor_get_rules(node)
minetest.swap_node(f.pos, {name = mesecon.get_conductor_on(node, f.link),
param2 = node.param2})
-- call turnon on neighbors: normal rules
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
local np = vector.add(f.pos, r)
-- area not loaded, postpone action
if not mesecon.get_node_force(np) then
mesecon.queue:add_action(np, "turnon", {rulename},
nil, true)
else
local links = mesecon.rules_link_rule_all(f.pos, r)
for _, l in ipairs(links) do
table.insert(frontiers, {pos = np, link = l})
end
end
return
end
elseif mesecon.is_effector(node.name) then
mesecon.changesignal(f.pos, node, f.link, mesecon.state.on, depth)
if mesecon.is_effector_off(node.name) then
mesecon.activate(f.pos, node, f.link, depth)
end
end
depth = depth + 1
end
end
minetest.add_node(pos, {name = mesecon:get_conductor_on(node.name, rulename), param2 = node.param2})
mesecon.queue:add_function("turnon", function (pos, rulename, recdepth)
mesecon.turnon(pos, rulename, recdepth)
end)
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
local np = mesecon:addPosRule(pos, rule)
local link, rulename = mesecon:rules_link(pos, np)
function mesecon.turnoff(pos, link)
local frontiers = {{pos = pos, link = link}}
if link then
mesecon:turnon(np, rulename)
local depth = 1
while frontiers[depth] do
local f = frontiers[depth]
local node = mesecon.get_node_force(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 = vector.add(f.pos, r)
-- area not loaded, postpone action
if not mesecon.get_node_force(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
elseif mesecon:is_effector(node.name) then
mesecon:changesignal(pos, node, rulename, mesecon.state.on)
if mesecon:is_effector_off(node.name) then
mesecon:activate(pos, node, rulename)
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
function mesecon:turnoff(pos, rulename)
local node = minetest.get_node(pos)
if mesecon:is_conductor_on(node.name, 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
return
end
--]]
minetest.add_node(pos, {name = mesecon:get_conductor_off(node.name, rulename), param2 = node.param2})
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
local np = mesecon:addPosRule(pos, rule)
local link, rulename = mesecon:rules_link(pos, np)
if link then
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
mesecon.queue:add_function("turnoff", function (pos, rulename, recdepth)
mesecon.turnoff(pos, rulename, recdepth)
end)
function mesecon:connected_to_receptor(pos, rulename)
local node = minetest.get_node(pos)
function mesecon.connected_to_receptor(pos, link)
local node = mesecon.get_node_force(pos)
if not node then return false end
-- Check if conductors around are connected
local rules = mesecon:get_any_inputrules(node)
local rules = mesecon.get_any_inputrules(node)
if not rules then return false end
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
local np = mesecon:addPosRule(pos, rule)
if mesecon:rules_link(np, pos) then
if mesecon:find_receptor_on(np, {}, mesecon:invertRule(rule)) then
for _, rule in ipairs(mesecon.rule2meta(link, rules)) do
local links = mesecon.rules_link_rule_all_inverted(pos, rule)
for _, l in ipairs(links) do
local np = vector.add(pos, l)
if mesecon.find_receptor_on(np, mesecon.invertRule(l)) then
return true
end
end
@ -497,133 +485,189 @@ function mesecon:connected_to_receptor(pos, rulename)
return false
end
function mesecon:find_receptor_on(pos, checked, rulename)
-- 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
function mesecon.find_receptor_on(pos, link)
local frontiers = {{pos = pos, link = link}}
local checked = {}
-- add current position to checked
table.insert(checked, {x=pos.x, y=pos.y, z=pos.z})
local node = minetest.get_node(pos)
-- List of positions that have been searched for onstate receptors
local depth = 1
while frontiers[depth] do
local f = frontiers[depth]
local node = mesecon.get_node_force(f.pos)
if mesecon:is_receptor_on(node.name) then
return true
end
if not node then return false end
if mesecon.is_receptor_on(node.name) then return true end
if mesecon.is_conductor_on(node, f.link) then
local rules = mesecon.conductor_get_rules(node)
if mesecon:is_conductor(node.name) then
local rules = mesecon:conductor_get_rules(node)
for _, rule in ipairs(mesecon:rule2meta(rulename, rules)) do
local np = mesecon:addPosRule(pos, rule)
if mesecon:rules_link(np, pos) then
if mesecon:find_receptor_on(np, checked, mesecon:invertRule(rule)) then
return true
end
-- call turnoff on neighbors: normal rules
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
local np = vector.add(f.pos, r)
local links = mesecon.rules_link_rule_all_inverted(f.pos, r)
for _, l in ipairs(links) do
local checkedstring = np.x..np.y..np.z..l.x..l.y..l.z
if not checked[checkedstring] then
table.insert(frontiers, {pos = np, link = l})
checked[checkedstring] = true
end
end
end
return false
end
depth = depth + 1
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
local outputnode = minetest.get_node(output)
local inputnode = minetest.get_node(input)
local outputrules = dug_outputrules or mesecon:get_any_outputrules (outputnode)
local inputrules = mesecon:get_any_inputrules (inputnode)
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 = mesecon.get_node_force(output)
local inputnode = mesecon.get_node_force(input)
local outputrules = dug_outputrules or mesecon.get_any_outputrules (outputnode)
local inputrules = mesecon.get_any_inputrules (inputnode)
if not outputrules or not inputrules then
return
end
for _, outputrule in ipairs(mesecon:flattenrules(outputrules)) do
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
-- Check if output sends to input
if mesecon:cmpPos(mesecon:addPosRule(output, outputrule), input) then
for _, inputrule in ipairs(mesecon:flattenrules(inputrules)) do
if vector.equals(vector.add(output, outputrule), input) then
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
-- Check if input accepts from output
if mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then
if vector.equals(vector.add(input, inputrule), output) then
return true, inputrule
end
end
end
end
return false
end
function mesecon:rules_link_anydir(pos1, pos2)
return mesecon:rules_link(pos1, pos2) or mesecon:rules_link(pos2, pos1)
function mesecon.rules_link_rule_all(output, rule)
local input = vector.add(output, rule)
local inputnode = mesecon.get_node_force(input)
local inputrules = mesecon.get_any_inputrules (inputnode)
if not inputrules then
return {}
end
local rules = {}
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
-- Check if input accepts from output
if vector.equals(vector.add(input, inputrule), output) then
table.insert(rules, inputrule)
end
end
return rules
end
function mesecon:is_powered(pos, rule)
local node = minetest.get_node(pos)
local rules = mesecon:get_any_inputrules(node)
function mesecon.rules_link_rule_all_inverted(input, rule)
--local irule = mesecon.invertRule(rule)
local output = vector.add(input, rule)
local outputnode = mesecon.get_node_force(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 vector.equals(vector.add(output, outputrule), input) then
table.insert(rules, mesecon.invertRule(outputrule))
end
end
return rules
end
function mesecon.rules_link_anydir(pos1, pos2)
return mesecon.rules_link(pos1, pos2) or mesecon.rules_link(pos2, pos1)
end
function mesecon.is_powered(pos, rule)
local node = mesecon.get_node_force(pos)
local rules = mesecon.get_any_inputrules(node)
if not rules then return false end
if not rule then
for _, rule in ipairs(mesecon:flattenrules(rules)) do
local np = mesecon:addPosRule(pos, rule)
local nn = minetest.get_node(np)
-- List of nodes that send out power to pos
local sourcepos = {}
if (mesecon:is_conductor_on (nn.name, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name))
and mesecon:rules_link(np, pos) then
return true
if not rule then
for _, rule in ipairs(mesecon.flattenrules(rules)) do
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
for _, rname in ipairs(rulenames) do
local np = vector.add(pos, rname)
local nn = mesecon.get_node_force(np)
if (mesecon.is_conductor_on(nn, mesecon.invertRule(rname))
or mesecon.is_receptor_on(nn.name)) then
table.insert(sourcepos, np)
end
end
end
else
local np = mesecon:addPosRule(pos, rule)
local nn = minetest.get_node(np)
if (mesecon:is_conductor_on (nn.name, mesecon:invertRule(rule)) or mesecon:is_receptor_on (nn.name))
and mesecon:rules_link(np, pos) then
return true
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
for _, rname in ipairs(rulenames) do
local np = vector.add(pos, rname)
local nn = mesecon.get_node_force(np)
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
or mesecon.is_receptor_on (nn.name)) then
table.insert(sourcepos, np)
end
end
end
return false
-- Return FALSE if not powered, return list of sources if is powered
if (#sourcepos == 0) then return false
else return sourcepos end
end
--Rules rotation Functions:
function mesecon:rotate_rules_right(rules)
function mesecon.rotate_rules_right(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = -rule.z,
y = rule.y,
z = rule.x})
z = rule.x,
name = rule.name})
end
return nr
end
function mesecon:rotate_rules_left(rules)
function mesecon.rotate_rules_left(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = rule.z,
y = rule.y,
z = -rule.x})
z = -rule.x,
name = rule.name})
end
return nr
end
function mesecon:rotate_rules_down(rules)
function mesecon.rotate_rules_down(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = -rule.y,
y = rule.x,
z = rule.z})
z = rule.z,
name = rule.name})
end
return nr
end
function mesecon:rotate_rules_up(rules)
function mesecon.rotate_rules_up(rules)
local nr = {}
for i, rule in ipairs(rules) do
table.insert(nr, {
x = rule.y,
y = -rule.x,
z = rule.z})
z = rule.z,
name = rule.name})
end
return nr
end

View File

@ -15,6 +15,8 @@ mesecon.rules.default =
{x=0, y=1, z=-1},
{x=0, y=-1, z=-1}}
mesecon.rules.pplate = mesecon.mergetable(mesecon.rules.default, {{x=0, y=-2, z=0}})
mesecon.rules.buttonlike =
{{x = 1, y = 0, z = 0},
{x = 1, y = 1, z = 0},
@ -29,14 +31,22 @@ mesecon.rules.flat =
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1}}
mesecon.rules.alldirs =
{{x= 1, y= 0, z= 0},
{x=-1, y= 0, z= 0},
{x= 0, y= 1, z= 0},
{x= 0, y=-1, z= 0},
{x= 0, y= 0, z= 1},
{x= 0, y= 0, z=-1}}
mesecon.rules.buttonlike_get = function(node)
local rules = mesecon.rules.buttonlike
if node.param2 == 2 then
rules=mesecon:rotate_rules_left(rules)
rules=mesecon.rotate_rules_left(rules)
elseif node.param2 == 3 then
rules=mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules))
rules=mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules))
elseif node.param2 == 0 then
rules=mesecon:rotate_rules_right(rules)
rules=mesecon.rotate_rules_right(rules)
end
return rules
end

View File

@ -1,38 +1,100 @@
-- Dig and place services
mesecon.on_placenode = function (pos, node)
if mesecon:is_receptor_on(node.name) then
mesecon:receptor_on(pos, mesecon:receptor_get_rules(node))
elseif mesecon:is_powered(pos) then
if mesecon:is_conductor(node.name) then
mesecon:turnon (pos)
--mesecon:receptor_on (pos, mesecon:conductor_get_rules(node))
else
mesecon:changesignal(pos, node, mesecon:effector_get_rules(node), "on")
mesecon:activate(pos, node)
mesecon.update_autoconnect(pos, node)
-- Receptors: Send on signal when active
if mesecon.is_receptor_on(node.name) then
mesecon.receptor_on(pos, mesecon.receptor_get_rules(node))
end
-- Conductors: Send turnon signal when powered or replace by respective offstate conductor
-- if placed conductor is an onstate one
if mesecon.is_conductor(node.name) then
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 = vector.subtract(pos, s)
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 = {}
local unpowered_rules = {}
-- for each input rule, check if powered
for _, r in ipairs(mesecon.effector_get_rules(node)) do
local powered = mesecon.is_powered(pos, r)
if powered then table.insert(powered_rules, r)
else table.insert(unpowered_rules, r) end
local state = powered and mesecon.state.on or mesecon.state.off
mesecon.changesignal(pos, node, r, state, 1)
end
if (#powered_rules > 0) then
for _, r in ipairs(powered_rules) do
mesecon.activate(pos, node, r, 1)
end
else
for _, r in ipairs(unpowered_rules) do
mesecon.deactivate(pos, node, r, 1)
end
end
elseif mesecon:is_conductor_on(node.name) then
minetest.swap_node(pos, {name = mesecon:get_conductor_off(node.name)})
elseif mesecon:is_effector_on (node.name) then
mesecon:deactivate(pos, node)
end
end
mesecon.on_dignode = function (pos, node)
if mesecon:is_conductor_on(node.name) then
mesecon:receptor_off(pos, mesecon:conductor_get_rules(node))
elseif mesecon:is_receptor_on(node.name) then
mesecon:receptor_off(pos, mesecon:receptor_get_rules(node))
if mesecon.is_conductor_on(node) then
mesecon.receptor_off(pos, mesecon.conductor_get_rules(node))
elseif mesecon.is_receptor_on(node.name) then
mesecon.receptor_off(pos, mesecon.receptor_get_rules(node))
end
mesecon.queue:add_action(pos, "update_autoconnect", {node})
end
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,
})
mesecon.queue:add_function("update_autoconnect", mesecon.update_autoconnect)
minetest.register_on_placenode(mesecon.on_placenode)
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,9 +1,15 @@
-- SETTINGS
BLINKY_PLANT_INTERVAL = 3
NEW_STYLE_WIRES = true -- true = new nodebox wires, false = old raillike wires
PRESSURE_PLATE_INTERVAL = 0.1
OBJECT_DETECTOR_RADIUS = 6
PISTON_MAXIMUM_PUSH = 15
MOVESTONE_MAXIMUM_PUSH = 100
MESECONS_GLOBALSTEP = true -- true = receptors/effectors won't be updated
-- until next globalstep, decreases server load
function mesecon.setting(setting, default)
if type(default) == "boolean" then
local read = minetest.setting_getbool("mesecon."..setting)
if read == nil then
return default
else
return read
end
elseif type(default) == "string" then
return minetest.setting_get("mesecon."..setting) or default
elseif type(default) == "number" then
return tonumber(minetest.setting_get("mesecon."..setting) or default)
end
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 290 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 294 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

View File

@ -1,24 +1,12 @@
function mesecon:move_node(pos, newpos)
function mesecon.move_node(pos, newpos)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos):to_table()
minetest.remove_node(pos)
minetest.add_node(newpos, node)
minetest.set_node(newpos, node)
minetest.get_meta(pos):from_table(meta)
end
--[[ 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)
function mesecon.flattenrules(allrules)
--[[
{
{
@ -53,7 +41,7 @@ function mesecon:flattenrules(allrules)
--]]
end
function mesecon:rule2bit(findrule, allrules)
function mesecon.rule2bit(findrule, allrules)
--get the bit of the metarule the rule is in, or bit 1
if (allrules[1] and
allrules[1].x) or
@ -62,53 +50,56 @@ function mesecon:rule2bit(findrule, allrules)
end
for m,metarule in ipairs( allrules) do
for _, rule in ipairs(metarule ) do
if mesecon:cmpPos(findrule, rule) then
if vector.equals(findrule, rule) then
return m
end
end
end
end
function mesecon:rule2meta(findrule, allrules)
function mesecon.rule2metaindex(findrule, allrules)
--get the metarule the rule is in, or allrules
if allrules[1].x then
return allrules
return nil
end
if not(findrule) then
return mesecon:flattenrules(allrules)
return mesecon.flattenrules(allrules)
end
for m, metarule in ipairs( allrules) do
for _, rule in ipairs(metarule ) do
if mesecon:cmpPos(findrule, rule) then
return metarule
if vector.equals(findrule, rule) then
return m
end
end
end
end
local convert_base
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)"
)
function mesecon.rule2meta(findrule, allrules)
if #allrules == 0 then return {} end
local index = mesecon.rule2metaindex(findrule, allrules)
if index == nil then
if allrules[1].x then
return allrules
else
function dec2bin(n)
return {}
end
end
return allrules[index]
end
function mesecon.dec2bin(n)
local x, y = math.floor(n / 2), n % 2
if (n > 1) then
return dec2bin(x)..y
return mesecon.dec2bin(x)..y
else
return ""..y
end
end
end
function mesecon:getstate(nodename, states)
function mesecon.getstate(nodename, states)
for state, name in ipairs(states) do
if name == nodename then
return state
@ -117,48 +108,41 @@ function mesecon:getstate(nodename, states)
error(nodename.." doesn't mention itself in "..dump(states))
end
function mesecon:getbinstate(nodename, states)
return dec2bin(mesecon:getstate(nodename, states)-1)
function mesecon.getbinstate(nodename, states)
return mesecon.dec2bin(mesecon.getstate(nodename, states)-1)
end
function mesecon:get_bit(binary,bit)
function mesecon.get_bit(binary,bit)
bit = bit or 1
local c = binary:len()-(bit-1)
return binary:sub(c,c) == "1"
end
function mesecon:set_bit(binary,bit,value)
function mesecon.set_bit(binary,bit,value)
if value == "1" then
if not mesecon:get_bit(binary,bit) then
return dec2bin(tonumber(binary,2)+math.pow(2,bit-1))
if not mesecon.get_bit(binary,bit) then
return mesecon.dec2bin(tonumber(binary,2)+math.pow(2,bit-1))
end
elseif value == "0" then
if mesecon:get_bit(binary,bit) then
return dec2bin(tonumber(binary,2)-math.pow(2,bit-1))
if mesecon.get_bit(binary,bit) then
return mesecon.dec2bin(tonumber(binary,2)-math.pow(2,bit-1))
end
end
return binary
end
function mesecon:invertRule(r)
return {x = -r.x, y = -r.y, z = -r.z}
function mesecon.invertRule(r)
return vector.multiply(r, -1)
end
function mesecon:addPosRule(p, r)
return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z}
end
function mesecon:cmpPos(p1, p2)
return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z)
end
function mesecon:tablecopy(table) -- deep table copy
function mesecon.tablecopy(table) -- deep table copy
if type(table) ~= "table" then return table end -- no need to copy
local newtable = {}
for idx, item in pairs(table) do
if type(item) == "table" then
newtable[idx] = mesecon:tablecopy(item)
newtable[idx] = mesecon.tablecopy(item)
else
newtable[idx] = item
end
@ -166,3 +150,126 @@ function mesecon:tablecopy(table) -- deep table copy
return newtable
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
-- File writing / reading utilities
local wpath = minetest.get_worldpath()
function mesecon.file2table(filename)
local f = io.open(wpath..DIR_DELIM..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
function mesecon.table2file(filename, table)
local f = io.open(wpath..DIR_DELIM..filename, "w")
f:write(minetest.serialize(table))
f:close()
end
-- Forceloading: Force server to load area if node is nil
local BLOCKSIZE = 16
-- convert node position --> block hash
local function hash_blockpos(pos)
return minetest.hash_node_position({
x = math.floor(pos.x/BLOCKSIZE),
y = math.floor(pos.y/BLOCKSIZE),
z = math.floor(pos.z/BLOCKSIZE)
})
end
-- convert block hash --> node position
local function unhash_blockpos(hash)
return vector.multiply(minetest.get_position_from_hash(hash), BLOCKSIZE)
end
mesecon.forceloaded_blocks = {}
-- get node and force-load area
function mesecon.get_node_force(pos)
local hash = hash_blockpos(pos)
if mesecon.forceloaded_blocks[hash] == nil then
-- if no more forceload spaces are available, try again next time
if minetest.forceload_block(pos) then
mesecon.forceloaded_blocks[hash] = 0
end
else
mesecon.forceloaded_blocks[hash] = 0
end
return minetest.get_node_or_nil(pos)
end
minetest.register_globalstep(function (dtime)
for hash, time in pairs(mesecon.forceloaded_blocks) do
-- unload forceloaded blocks after 10 minutes without usage
if (time > mesecon.setting("forceload_timeout", 600)) then
minetest.forceload_free_block(unhash_blockpos(hash))
mesecon.forceloaded_blocks[hash] = nil
else
mesecon.forceloaded_blocks[hash] = time + dtime
end
end
end)
-- Store and read the forceloaded blocks to / from a file
-- so that those blocks are remembered when the game
-- is restarted
mesecon.forceloaded_blocks = mesecon.file2table("mesecon_forceloaded")
minetest.register_on_shutdown(function()
mesecon.table2file("mesecon_forceloaded", mesecon.forceloaded_blocks)
end)

View File

@ -1,238 +1,236 @@
-- naming scheme: wire:(xp)(zp)(xm)(zm)_on/off
-- The conditions in brackets define whether there is a mesecon at that place or not
-- 1 = there is one; 0 = there is none
-- y always means y+
-- naming scheme: wire:(xp)(zp)(xm)(zm)(xpyp)(zpyp)(xmyp)(zmyp)_on/off
-- where x= x direction, z= z direction, y= y direction, p = +1, m = -1, e.g. xpym = {x=1, y=-1, z=0}
-- The (xp)/(zpyp)/.. statements shall be replaced by either 0 or 1
-- Where 0 means the wire has no visual connection to that direction and
-- 1 means that the wire visually connects to that other node.
box_center = {-1/16, -.5, -1/16, 1/16, -.5+1/64, 1/16}
box_bump1 = { -2/16, -.5, -2/16, 2/16, -.5+1/64, 2/16 }
-- #######################
-- ## Update wire looks ##
-- #######################
box_xp = {1/16, -.5, -1/16, 8/16, -.5+1/64, 1/16}
box_zp = {-1/16, -.5, 1/16, 1/16, -.5+1/64, 8/16}
box_xm = {-8/16, -.5, -1/16, -1/16, -.5+1/64, 1/16}
box_zm = {-1/16, -.5, -8/16, 1/16, -.5+1/64, -1/16}
box_xpy = {.5-1/16, -.5+1/64, -1/16, .5, .4999+1/64, 1/16}
box_zpy = {-1/16, -.5+1/64, .5-1/16, 1/16, .4999+1/64, .5}
box_xmy = {-.5, -.5+1/64, -1/16, -.5+1/16, .4999+1/64, 1/16}
box_zmy = {-1/16, -.5+1/64, -.5, 1/16, .4999+1/64, -.5+1/16}
-- Registering the wires
for xp=0, 1 do
for zp=0, 1 do
for xm=0, 1 do
for zm=0, 1 do
for xpy=0, 1 do
for zpy=0, 1 do
for xmy=0, 1 do
for zmy=0, 1 do
if (xpy == 1 and xp == 0) or (zpy == 1 and zp == 0)
or (xmy == 1 and xm == 0) or (zmy == 1 and zm == 0) then break end
local groups
local nodeid = tostring(xp )..tostring(zp )..tostring(xm )..tostring(zm )..
tostring(xpy)..tostring(zpy)..tostring(xmy)..tostring(zmy)
if nodeid == "00000000" then
groups = {dig_immediate = 3, mesecon_conductor_craftable=1}
wiredesc = "Mesecon"
-- self_pos = pos of any mesecon node, from_pos = pos of conductor to getconnect for
local wire_getconnect = function (from_pos, self_pos)
local node = minetest.get_node(self_pos)
if minetest.registered_nodes[node.name]
and minetest.registered_nodes[node.name].mesecons then
-- rules of node to possibly connect to
local rules = {}
if (minetest.registered_nodes[node.name].mesecon_wire) then
rules = mesecon.rules.default
else
groups = {dig_immediate = 3, not_in_creative_inventory = 1}
wiredesc = "Mesecons Wire (ID: "..nodeid..")"
rules = mesecon.get_any_rules(node)
end
local nodebox = {}
local adjx = false
local adjz = false
if xp == 1 then table.insert(nodebox, box_xp) adjx = true end
if zp == 1 then table.insert(nodebox, box_zp) adjz = true end
if xm == 1 then table.insert(nodebox, box_xm) adjx = true end
if zm == 1 then table.insert(nodebox, box_zm) adjz = true end
if xpy == 1 then table.insert(nodebox, box_xpy) end
if zpy == 1 then table.insert(nodebox, box_zpy) end
if xmy == 1 then table.insert(nodebox, box_xmy) end
if zmy == 1 then table.insert(nodebox, box_zmy) end
for _, r in ipairs(mesecon.flattenrules(rules)) do
if (vector.equals(vector.add(self_pos, r), from_pos)) then
return true
end
end
end
return false
end
if adjx and adjz and (xp + zp + xm + zm > 2) then
table.insert(nodebox, box_bump1)
tiles_off = {
"jeija_mesecon_crossing_off.png",
"jeija_mesecon_crossing_off.png",
"jeija_mesecon_off.png",
"jeija_mesecon_off.png",
"jeija_mesecon_off.png",
"jeija_mesecon_off.png"
}
tiles_on = {
"jeija_mesecon_crossing_on.png",
"jeija_mesecon_crossing_on.png",
"jeija_mesecon_on.png",
"jeija_mesecon_on.png",
"jeija_mesecon_on.png",
"jeija_mesecon_on.png"
}
-- Update this node
local wire_updateconnect = function (pos)
local connections = {}
for _, r in ipairs(mesecon.rules.default) do
if wire_getconnect(pos, vector.add(pos, r)) then
table.insert(connections, r)
end
end
local nid = {}
for _, vec in ipairs(connections) do
-- flat component
if vec.x == 1 then nid[0] = "1" end
if vec.z == 1 then nid[1] = "1" end
if vec.x == -1 then nid[2] = "1" end
if vec.z == -1 then nid[3] = "1" end
-- 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
table.insert(nodebox, box_center)
tiles_off = {
"jeija_mesecon_crossing_off.png",
"jeija_mesecon_crossing_off.png",
"jeija_mesecon_off.png",
"jeija_mesecon_off.png",
"jeija_mesecon_off.png",
"jeija_mesecon_off.png"
}
tiles_on = {
"jeija_mesecon_crossing_on.png",
"jeija_mesecon_crossing_on.png",
"jeija_mesecon_on.png",
"jeija_mesecon_on.png",
"jeija_mesecon_on.png",
"jeija_mesecon_on.png"
}
rules = mesecon.get_any_rules(node)
end
if (not rules) then return end
for _, r in ipairs(mesecon.flattenrules(rules)) do
local np = vector.add(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
nodebox = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
nodebox.fixed = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
end
minetest.register_node("mesecons:wire_"..nodeid.."_off", {
description = "Bluestone Dust",
drawtype = "nodebox",
tiles = tiles_off,
inventory_image = "default_bluestone_dust.png",
wield_image = "default_bluestone_dust.png",
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
selection_box = {
type = "fixed",
fixed = {-.5, -.5, -.5, .5, -.5+1/16, .5}
},
node_box = {
type = "fixed",
fixed = nodebox
},
groups = groups,
walkable = false,
drop = "mesecons:wire_00000000_off",
mesecons = {conductor={
local rules = {}
if (nid[0] == 1) then table.insert(rules, vector.new( 1, 0, 0)) end
if (nid[1] == 1) then table.insert(rules, vector.new( 0, 0, 1)) end
if (nid[2] == 1) then table.insert(rules, vector.new(-1, 0, 0)) end
if (nid[3] == 1) then table.insert(rules, vector.new( 0, 0, -1)) end
if (nid[0] == 1) then table.insert(rules, vector.new( 1, -1, 0)) end
if (nid[1] == 1) then table.insert(rules, vector.new( 0, -1, 1)) end
if (nid[2] == 1) then table.insert(rules, vector.new(-1, -1, 0)) end
if (nid[3] == 1) then table.insert(rules, vector.new( 0, -1, -1)) end
if (nid[4] == 1) then table.insert(rules, vector.new( 1, 1, 0)) end
if (nid[5] == 1) then table.insert(rules, vector.new( 0, 1, 1)) end
if (nid[6] == 1) then table.insert(rules, vector.new(-1, 1, 0)) end
if (nid[7] == 1) then table.insert(rules, vector.new( 0, 1, -1)) end
local meseconspec_off = { conductor = {
rules = rules,
state = mesecon.state.off,
onstate = "mesecons:wire_"..nodeid.."_on"
}}
})
minetest.register_node("mesecons:wire_"..nodeid.."_on", {
description = "Bluestone Dust",
drawtype = "nodebox",
tiles = tiles_on,
inventory_image = "default_bluestone_dust.png",
wield_image = "default_bluestone_dust.png",
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
selection_box = {
type = "fixed",
fixed = {-.5, -.5, -.5, .5, -.5+1/16, .5}
},
node_box = {
type = "fixed",
fixed = nodebox
},
groups = {dig_immediate = 3, mesecon = 2, not_in_creative_inventory = 1},
walkable = false,
drop = "mesecons:wire_00000000_off",
mesecons = {conductor={
local meseconspec_on = { conductor = {
rules = rules,
state = mesecon.state.on,
offstate = "mesecons:wire_"..nodeid.."_off"
}}
})
end
end
end
end
end
end
end
local groups_on = {dig_immediate = 3, mesecon_conductor_craftable = 1,
not_in_creative_inventory = 1}
local groups_off = {dig_immediate = 3, mesecon_conductor_craftable = 1}
if nodeid ~= "00000000" then
groups_off["not_in_creative_inventory"] = 1
end
-- Updating the wires:
-- Place the right connection wire
mesecon.register_node("mesecons:wire_"..nodeid, {
description = "Mesecon",
drawtype = "nodebox",
inventory_image = "bluestone_dust.png",
wield_image = "bluestone_dust.png",
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
selection_box = selectionbox,
node_box = nodebox,
walkable = false,
drop = "mesecons:wire_00000000_off",
mesecon_wire = true
}, {tiles = tiles_off, mesecons = meseconspec_off, groups = groups_off},
{tiles = tiles_on, mesecons = meseconspec_on, groups = groups_on})
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)
if (nid_inc(nid) == false) then return end
end
end
register_wires()
minetest.register_on_placenode(update_on_place_dig)
minetest.register_on_dignode(update_on_place_dig)
-- ##############
-- ## Crafting ##
-- ##############
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
local nodename = minetest.get_node(pos).name
if string.find(nodename, "mesecons:wire_") == nil and not replace_old then return nil end
local xp, xm, zp, zm, xpy, zpy, xmy, zmy
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
minetest.register_craft({
type = "cooking",
output = "mesecons:wire_00000000_off 8",
recipe = "default:stone_with_bluestone",
})

View File

@ -8,12 +8,12 @@ mesecon.button_turnoff = function (pos)
minetest.swap_node(pos, {name = "mesecons_button:button_stone_off", param2=node.param2})
minetest.sound_play("mesecons_button_pop", {pos=pos})
local rules = mesecon.rules.buttonlike_get(node)
mesecon:receptor_off(pos, rules)
mesecon.receptor_off(pos, rules)
elseif node.name=="mesecons_button:button_wood_on" then --has not been dug
minetest.swap_node(pos, {name = "mesecons_button:button_wood_off", param2=node.param2})
minetest.sound_play("mesecons_button_pop", {pos=pos})
local rules = mesecon.rules.buttonlike_get(node)
mesecon:receptor_off(pos, rules)
mesecon.receptor_off(pos, rules)
end
end
@ -40,7 +40,7 @@ minetest.register_node("mesecons_button:button_stone_off", {
description = "Stone Button",
on_punch = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_button:button_stone_on", param2=node.param2})
mesecon:receptor_on(pos, mesecon.rules.buttonlike_get(node))
mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node))
minetest.sound_play("mesecons_button_push", {pos=pos})
minetest.after(1, mesecon.button_turnoff, pos)
end,
@ -97,7 +97,7 @@ minetest.register_node("mesecons_button:button_wood_off", {
description = "Wood Button",
on_punch = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_button:button_wood_on", param2=node.param2})
mesecon:receptor_on(pos, mesecon.rules.buttonlike_get(node))
mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node))
minetest.sound_play("mesecons_button_push", {pos=pos})
minetest.after(1, mesecon.button_turnoff, pos)
end,

View File

@ -1,148 +0,0 @@
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

View File

@ -2,7 +2,7 @@
local delayer_get_output_rules = function(node)
local rules = {{x = 0, y = 0, z = 1}}
for i = 0, node.param2 do
rules = mesecon:rotate_rules_left(rules)
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
@ -10,35 +10,25 @@ end
local delayer_get_input_rules = function(node)
local rules = {{x = 0, y = 0, z = -1}}
for i = 0, node.param2 do
rules = mesecon:rotate_rules_left(rules)
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
-- 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 def = minetest.registered_nodes[node.name]
local time = def.delayer_time
minetest.swap_node(pos, {name = def.delayer_onstate, param2=node.param2})
minetest.after(time, delayer_turnon , {pos = pos, node = node})
mesecon.queue:add_action(pos, "receptor_on", {delayer_get_output_rules(node)}, time, nil)
end
local delayer_deactivate = function(pos, node)
local def = minetest.registered_nodes[node.name]
local time = def.delayer_time
minetest.swap_node(pos, {name = def.delayer_offstate, param2=node.param2})
minetest.after(time, delayer_turnoff, {pos = pos, node = node})
mesecon.queue:add_action(pos, "receptor_off", {delayer_get_output_rules(node)}, time, nil)
end
-- Register the 2 (states) x 4 (delay times) delayers

View File

@ -0,0 +1,98 @@
-- 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("doors_door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
else
minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
end
end
local function meseconify_door(name)
if minetest.registered_items[name .. "_b_1"] then
-- old style double-node doors
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
}}
})
elseif minetest.registered_items[name .. "_a"] then
-- new style mesh node based doors
local override = {
mesecons = {effector = {
action_on = function(pos, node)
local door = doors.get(pos)
if door then
door:open()
end
end,
action_off = function(pos, node)
local door = doors.get(pos)
if door then
door:close()
end
end,
rules = mesecon.rules.pplate
}}
}
minetest.override_item(name .. "_a", override)
minetest.override_item(name .. "_b", override)
end
end
meseconify_door("doors:door_wood")
meseconify_door("doors:door_steel")
meseconify_door("doors:door_glass")
meseconify_door("doors:door_obsidian_glass")
if doors and doors.get then
local override = {
mesecons = {effector = {
action_on = function(pos, node)
local door = doors.get(pos)
if door then
door:open()
end
end,
action_off = function(pos, node)
local door = doors.get(pos)
if door then
door:close()
end
end,
}},
}
minetest.override_item("doors:trapdoor", override)
minetest.override_item("doors:trapdoor_open", override)
minetest.override_item("doors:trapdoor_steel", override)
minetest.override_item("doors:trapdoor_steel_open", override)
end

View File

@ -1,3 +0,0 @@
mesecons
default

View File

@ -1,5 +0,0 @@
-- dofile(minetest.get_modpath("mesecons_extrawires").."/crossing.lua");
-- The crossing code is not active right now because it is hard to maintain
dofile(minetest.get_modpath("mesecons_extrawires").."/mesewire.lua");

View File

@ -1,9 +0,0 @@
local mesewire_rules =
{
{x = 1, y = 0, z = 0},
{x =-1, y = 0, z = 0},
{x = 0, y = 1, z = 0},
{x = 0, y =-1, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1},
}

View File

@ -1,6 +1,6 @@
--GLUE
-- Glue
minetest.register_craftitem("mesecons_materials:glue", {
image = "jeija_glue.png",
image = "mesecons_glue.png",
on_place_on_ground = minetest.craftitem_place_item,
description="Glue",
})
@ -8,7 +8,7 @@ minetest.register_craftitem("mesecons_materials:glue", {
minetest.register_craft({
output = "mesecons_materials:glue 2",
type = "cooking",
recipe = "default:sapling",
recipe = "group:sapling",
cooktime = 2
})

View File

@ -1,72 +1,163 @@
--register stoppers for movestones/pistons
mesecon.mvps_stoppers={}
mesecon.on_mvps_move = {}
mesecon.mvps_unmov = {}
function mesecon:is_mvps_stopper(node, pushdir, stack, stackid)
--- Objects (entities) that cannot be moved
function mesecon.register_mvps_unmov(objectname)
mesecon.mvps_unmov[objectname] = true;
end
function mesecon.is_mvps_unmov(objectname)
return mesecon.mvps_unmov[objectname]
end
-- Nodes that cannot be pushed / pulled by movestones, pistons
function mesecon.is_mvps_stopper(node, pushdir, stack, stackid)
-- unknown nodes are always stoppers
if not minetest.registered_nodes[node.name] then
return true
end
local get_stopper = mesecon.mvps_stoppers[node.name]
if type (get_stopper) == "function" then
get_stopper = get_stopper(node, pushdir, stack, stackid)
end
return get_stopper
end
function mesecon:register_mvps_stopper(nodename, get_stopper)
function mesecon.register_mvps_stopper(nodename, get_stopper)
if get_stopper == nil then
get_stopper = true
end
mesecon.mvps_stoppers[nodename] = get_stopper
end
-- Objects that cannot be moved (e.g. movestones)
function mesecon:register_mvps_unmov(objectname)
mesecon.mvps_unmov[objectname] = true;
-- Functions to be called on mvps movement
function mesecon.register_on_mvps_move(callback)
mesecon.on_mvps_move[#mesecon.on_mvps_move+1] = callback
end
function mesecon:is_mvps_unmov(objectname)
return mesecon.mvps_unmov[objectname]
local function on_mvps_move(moved_nodes)
for _, callback in ipairs(mesecon.on_mvps_move) do
callback(moved_nodes)
end
end
function mesecon:mvps_process_stack(stack)
function mesecon.mvps_process_stack(stack)
-- update mesecons for placed nodes ( has to be done after all nodes have been added )
for _, n in ipairs(stack) do
nodeupdate(n.pos)
mesecon.on_placenode(n.pos, minetest.get_node(n.pos))
mesecon:update_autoconnect(n.pos)
end
end
function mesecon:mvps_get_stack(pos, dir, maximum)
-- tests if the node can be pushed into, e.g. air, water, grass
local function node_replaceable(name)
if name == "ignore" then return true end
if minetest.registered_nodes[name] then
return minetest.registered_nodes[name].buildable_to or false
end
return false
end
function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
-- determine the number of nodes to be pushed
local np = {x = pos.x, y = pos.y, z = pos.z}
local nodes = {}
while true do
local nn = minetest.get_node_or_nil(np)
if not nn or #nodes > maximum then
-- don't push at all, something is in the way (unloaded map or too many nodes)
return nil
local frontiers = {pos}
while #frontiers > 0 do
local np = frontiers[1]
local nn = minetest.get_node(np)
if not node_replaceable(nn.name) then
table.insert(nodes, {node = nn, pos = np})
if #nodes > maximum then return nil end
-- add connected nodes to frontiers, connected is a vector list
-- the vectors must be absolute positions
local connected = {}
if minetest.registered_nodes[nn.name]
and minetest.registered_nodes[nn.name].mvps_sticky then
connected = minetest.registered_nodes[nn.name].mvps_sticky(np, nn)
end
if nn.name == "air"
or (minetest.registered_nodes[nn.name]
and minetest.registered_nodes[nn.name].liquidtype ~= "none") then --is liquid
break
table.insert(connected, vector.add(np, dir))
-- If adjacent node is sticky block and connects add that
-- position to the connected table
for _, r in ipairs(mesecon.rules.alldirs) do
local adjpos = vector.add(np, r)
local adjnode = minetest.get_node(adjpos)
if minetest.registered_nodes[adjnode.name]
and minetest.registered_nodes[adjnode.name].mvps_sticky then
local sticksto = minetest.registered_nodes[adjnode.name]
.mvps_sticky(adjpos, adjnode)
-- connects to this position?
for _, link in ipairs(sticksto) do
if vector.equals(link, np) then
table.insert(connected, adjpos)
end
end
end
end
table.insert (nodes, {node = nn, pos = np})
np = mesecon:addPosRule(np, dir)
if all_pull_sticky then
table.insert(connected, vector.subtract(np, dir))
end
-- Make sure there are no duplicates in frontiers / nodes before
-- adding nodes in "connected" to frontiers
for _, cp in ipairs(connected) do
local duplicate = false
for _, rp in ipairs(nodes) do
if vector.equals(cp, rp.pos) then
duplicate = true
end
end
for _, fp in ipairs(frontiers) do
if vector.equals(cp, fp) then
duplicate = true
end
end
if not duplicate then
table.insert(frontiers, cp)
end
end
end
table.remove(frontiers, 1)
end
return nodes
end
function mesecon:mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: direction of push; maximum: maximum nodes to be pushed
local nodes = mesecon:mvps_get_stack(pos, dir, maximum)
function mesecon.mvps_push(pos, dir, maximum)
return mesecon.mvps_push_or_pull(pos, dir, dir, maximum)
end
function mesecon.mvps_pull_all(pos, dir, maximum)
return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, true)
end
function mesecon.mvps_pull_single(pos, dir, maximum)
return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum)
end
-- pos: pos of mvps; stackdir: direction of building the stack
-- movedir: direction of actual movement
-- maximum: maximum nodes to be pushed
-- all_pull_sticky: All nodes are sticky in the direction that they are pulled from
function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sticky)
local nodes = mesecon.mvps_get_stack(pos, movedir, maximum, all_pull_sticky)
if not nodes then return end
-- determine if one of the nodes blocks the push
-- determine if one of the nodes blocks the push / pull
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, movedir, nodes, id) then
return
end
end
@ -80,99 +171,44 @@ function mesecon:mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: directio
-- update mesecons for removed nodes ( has to be done after all nodes have been removed )
for _, n in ipairs(nodes) do
mesecon.on_dignode(n.pos, n.node)
mesecon:update_autoconnect(n.pos)
end
-- add nodes
for _, n in ipairs(nodes) do
local np = mesecon:addPosRule(n.pos, dir)
minetest.add_node(np, n.node)
local np = vector.add(n.pos, movedir)
minetest.set_node(np, n.node)
minetest.get_meta(np):from_table(n.meta)
end
local oldstack = mesecon:tablecopy(nodes)
local moved_nodes = {}
local oldstack = mesecon.tablecopy(nodes)
for i in ipairs(nodes) do
nodes[i].pos = mesecon:addPosRule(nodes[i].pos, dir)
moved_nodes[i] = {}
moved_nodes[i].oldpos = nodes[i].pos
nodes[i].pos = vector.add(nodes[i].pos, movedir)
moved_nodes[i].pos = nodes[i].pos
moved_nodes[i].node = nodes[i].node
moved_nodes[i].meta = nodes[i].meta
end
for _, n in ipairs(nodes) do
mesecon.on_placenode(n.pos, n.node)
mesecon:update_autoconnect(n.pos)
end
on_mvps_move(moved_nodes)
return true, nodes, oldstack
end
function mesecon:mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons)
local np = mesecon:addPosRule(pos, dir)
local nn = minetest.get_node(np)
if ((not minetest.registered_nodes[nn.name]) --unregistered node
or minetest.registered_nodes[nn.name].liquidtype == "none") --non-liquid node
and not mesecon:is_mvps_stopper(nn, {x = -dir.x, y = -dir.y, z = -dir.z}, {{pos = np, node = nn}}, 1) then --non-stopper node
local meta = minetest.get_meta(np):to_table()
minetest.remove_node(np)
minetest.add_node(pos, nn)
minetest.get_meta(pos):from_table(meta)
nodeupdate(np)
nodeupdate(pos)
mesecon.on_dignode(np, nn)
mesecon:update_autoconnect(np)
mesecon:update_autoconnect(pos)
mesecon.on_placenode(pos, nn)
end
return {{pos = np, node = {param2 = 0, name = "air"}}, {pos = pos, node = nn}}
mesecon.register_on_mvps_move(function(moved_nodes)
for _, n in ipairs(moved_nodes) do
mesecon.on_placenode(n.pos, n.node)
mesecon.update_autoconnect(n.pos)
end
end)
function mesecon:mvps_pull_all(pos, direction) -- pos: pos of mvps; direction: direction of pull
local lpos = {x=pos.x-direction.x, y=pos.y-direction.y, z=pos.z-direction.z} -- 1 away
local lnode = minetest.get_node(lpos)
local lpos2 = {x=pos.x-direction.x*2, y=pos.y-direction.y*2, z=pos.z-direction.z*2} -- 2 away
local lnode2 = minetest.get_node(lpos2)
--avoid pulling solid nodes
if lnode.name ~= "ignore"
and lnode.name ~= "air"
and ((not minetest.registered_nodes[lnode.name])
or minetest.registered_nodes[lnode.name].liquidtype == "none") then
return
end
--avoid pulling empty or liquid nodes
if lnode2.name == "ignore"
or lnode2.name == "air"
or (minetest.registered_nodes[lnode2.name]
and minetest.registered_nodes[lnode2.name].liquidtype ~= "none") then
return
end
local oldpos = {x=lpos2.x+direction.x, y=lpos2.y+direction.y, z=lpos2.z+direction.z}
repeat
lnode2 = minetest.get_node(lpos2)
minetest.add_node(oldpos, {name=lnode2.name})
nodeupdate(oldpos)
oldpos = {x=lpos2.x, y=lpos2.y, z=lpos2.z}
lpos2.x = lpos2.x-direction.x
lpos2.y = lpos2.y-direction.y
lpos2.z = lpos2.z-direction.z
lnode = minetest.get_node(lpos2)
until lnode.name == "air"
or lnode.name == "ignore"
or (minetest.registered_nodes[lnode2.name]
and minetest.registered_nodes[lnode2.name].liquidtype ~= "none")
minetest.remove_node(oldpos)
end
function mesecon:mvps_move_objects(pos, dir, nodestack)
function mesecon.mvps_move_objects(pos, dir, nodestack)
local objects_to_move = {}
-- Move object at tip of stack
local pushpos = mesecon:addPosRule(pos, -- get pos at tip of stack
{x = dir.x * #nodestack,
y = dir.y * #nodestack,
z = dir.z * #nodestack})
-- Move object at tip of stack, pushpos is position at tip of stack
local pushpos = vector.add(pos, vector.multiply(dir, #nodestack))
local objects = minetest.get_objects_inside_radius(pushpos, 1)
for _, obj in ipairs(objects) do
@ -183,7 +219,7 @@ function mesecon:mvps_move_objects(pos, dir, nodestack)
if tonumber(minetest.setting_get("movement_gravity")) > 0 and dir.y == 0 then
-- If gravity positive and dir horizontal, push players standing on the stack
for _, n in ipairs(nodestack) do
local p_above = mesecon:addPosRule(n.pos, {x=0, y=1, z=0})
local p_above = vector.add(n.pos, {x=0, y=1, z=0})
local objects = minetest.get_objects_inside_radius(p_above, 1)
for _, obj in ipairs(objects) do
table.insert(objects_to_move, obj)
@ -193,8 +229,8 @@ function mesecon:mvps_move_objects(pos, dir, nodestack)
for _, obj in ipairs(objects_to_move) do
local entity = obj:get_luaentity()
if not entity or not mesecon:is_mvps_unmov(entity.name) then
local np = mesecon:addPosRule(obj:getpos(), dir)
if not entity or not mesecon.is_mvps_unmov(entity.name) then
local np = vector.add(obj:getpos(), dir)
--move only if destination is not solid
local nn = minetest.get_node(np)
@ -206,5 +242,8 @@ function mesecon:mvps_move_objects(pos, dir, nodestack)
end
end
mesecon:register_mvps_stopper("default:chest_locked")
mesecon:register_mvps_stopper("default:furnace")
mesecon.register_mvps_stopper("doors:door_steel_b_1")
mesecon.register_mvps_stopper("doors:door_steel_t_1")
mesecon.register_mvps_stopper("doors:door_steel_b_2")
mesecon.register_mvps_stopper("doors:door_steel_t_2")
mesecon.register_mvps_stopper("default:furnace")

View File

@ -33,7 +33,7 @@ local piston_down_rules =
local piston_get_rules = function (node)
local rules = piston_rules
for i = 1, node.param2 do
rules = mesecon:rotate_rules_left(rules)
rules = mesecon.rotate_rules_left(rules)
end
return rules
end
@ -41,7 +41,7 @@ end
piston_facedir_direction = function (node)
local rules = {{x = 0, y = 0, z = -1}}
for i = 1, node.param2 do
rules = mesecon:rotate_rules_left(rules)
rules = mesecon.rotate_rules_left(rules)
end
return rules[1]
end
@ -56,15 +56,15 @@ end
local piston_remove_pusher = function (pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local pushername
if pushername == pistonspec.pusher then --make sure there actually is a pusher (for compatibility reasons mainly)
local dir = piston_get_direction(pistonspec.dir, node)
local pusherpos = vector.add(pos, dir)
local pushername = minetest.get_node(pusherpos).name
-- make sure there actually is a pusher (for compatibility reasons mainly)
if pushername ~= pistonspec.pusher then
return
end
local dir = piston_get_direction(pistonspec.dir, node)
local pusherpos = mesecon:addPosRule(pos, dir)
local pushername = minetest.get_node(pusherpos).name
minetest.remove_node(pusherpos)
minetest.sound_play("piston_retract", {
pos = pos,
@ -78,31 +78,33 @@ local piston_on = function (pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local dir = piston_get_direction(pistonspec.dir, node)
local np = mesecon:addPosRule(pos, dir)
local success, stack, oldstack = mesecon:mvps_push(np, dir, PISTON_MAXIMUM_PUSH)
local np = vector.add(pos, dir)
local maxpush = mesecon.setting("piston_max_push", 10)
local success, stack, oldstack = mesecon.mvps_push(np, dir, maxpush)
if success then
minetest.add_node(pos, {param2 = node.param2, name = pistonspec.onname})
minetest.add_node(np, {param2 = node.param2, name = pistonspec.pusher})
minetest.set_node(pos, {param2 = node.param2, name = pistonspec.onname})
minetest.set_node(np, {param2 = node.param2, name = pistonspec.pusher})
minetest.sound_play("piston_extend", {
pos = pos,
max_hear_distance = 20,
gain = 0.3,
})
mesecon:mvps_process_stack(stack)
mesecon:mvps_move_objects (np, dir, oldstack)
mesecon.mvps_process_stack(stack)
mesecon.mvps_move_objects(np, dir, oldstack)
end
end
local piston_off = function (pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
minetest.add_node(pos, {param2 = node.param2, name = pistonspec.offname})
minetest.set_node(pos, {param2 = node.param2, name = pistonspec.offname})
piston_remove_pusher (pos, node)
if pistonspec.sticky then
local maxpull = mesecon.setting("piston_max_pull", 10)
local dir = piston_get_direction(pistonspec.dir, node)
local pullpos = mesecon:addPosRule(pos, dir)
local stack = mesecon:mvps_pull_single(pullpos, dir)
mesecon:mvps_process_stack(pos, dir, stack)
local pullpos = vector.add(pos, vector.multiply(dir, 2))
local stack = mesecon.mvps_pull_single(pullpos, vector.multiply(dir, -1), maxpull)
mesecon.mvps_process_stack(pos, dir, stack)
end
end
@ -115,10 +117,16 @@ local piston_orientate = function (pos, placer)
local node = minetest.get_node(pos)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
if pitch > 55 then --looking upwards
minetest.add_node(pos, {name=pistonspec.piston_down})
elseif pitch < -55 then --looking downwards
minetest.add_node(pos, {name=pistonspec.piston_up})
-- looking upwards (pitch > 55) / looking downwards (pitch < -55)
local nn = nil
if pitch > 55 then nn = {name = pistonspec.piston_down} end
if pitch < -55 then nn = {name = pistonspec.piston_up} end
if nn then
minetest.set_node(pos, nn)
-- minetest.after, because on_placenode for unoriented piston must be processed first
minetest.after(0, mesecon.on_placenode, pos, nn)
end
end
@ -693,14 +701,14 @@ local piston_pusher_up_down_get_stopper = function (node, dir, stack, stackid)
return true
end
mesecon:register_mvps_stopper("mesecons_pistons:piston_pusher_normal", piston_pusher_get_stopper)
mesecon:register_mvps_stopper("mesecons_pistons:piston_pusher_sticky", piston_pusher_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_normal", piston_pusher_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_sticky", piston_pusher_get_stopper)
mesecon:register_mvps_stopper("mesecons_pistons:piston_up_pusher_normal", piston_pusher_up_down_get_stopper)
mesecon:register_mvps_stopper("mesecons_pistons:piston_up_pusher_sticky", piston_pusher_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_normal", piston_pusher_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_sticky", piston_pusher_up_down_get_stopper)
mesecon:register_mvps_stopper("mesecons_pistons:piston_down_pusher_normal", piston_pusher_up_down_get_stopper)
mesecon:register_mvps_stopper("mesecons_pistons:piston_down_pusher_sticky", piston_pusher_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_normal", piston_pusher_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_sticky", piston_pusher_up_down_get_stopper)
-- Register pistons as stoppers if they would be seperated from the stopper
@ -717,12 +725,12 @@ end
local piston_get_stopper = function (node, dir, stack, stackid)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local dir = piston_get_direction(pistonspec.dir, node)
local pusherpos = mesecon:addPosRule(stack[stackid].pos, dir)
local pusherpos = vector.add(stack[stackid].pos, dir)
local pushernode = minetest.get_node(pusherpos)
if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then
for _, s in ipairs(stack) do
if mesecon:cmpPos(s.pos, pusherpos) -- pusher is also to be pushed
if vector.equals(s.pos, pusherpos) -- pusher is also to be pushed
and s.node.param2 == node.param2 then
return false
end
@ -731,14 +739,14 @@ local piston_get_stopper = function (node, dir, stack, stackid)
return true
end
mesecon:register_mvps_stopper("mesecons_pistons:piston_normal_on", piston_get_stopper)
mesecon:register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_normal_on", piston_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_get_stopper)
mesecon:register_mvps_stopper("mesecons_pistons:piston_up_normal_on", piston_up_down_get_stopper)
mesecon:register_mvps_stopper("mesecons_pistons:piston_up_sticky_on", piston_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_normal_on", piston_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_sticky_on", piston_up_down_get_stopper)
mesecon:register_mvps_stopper("mesecons_pistons:piston_down_normal_on", piston_up_down_get_stopper)
mesecon:register_mvps_stopper("mesecons_pistons:piston_down_sticky_on", piston_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_normal_on", piston_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_sticky_on", piston_up_down_get_stopper)
--craft recipes
minetest.register_craft({

View File

@ -8,32 +8,26 @@ local pp_box_on = {
fixed = { -7/16, -8/16, -7/16, 7/16, -7.5/16, 7/16 },
}
local function pp_on_timer(pos, elapsed)
pp_on_timer = function (pos, elapsed)
local node = minetest.get_node(pos)
local ppspec = minetest.registered_nodes[node.name].pressureplate
local basename = minetest.registered_nodes[node.name].pressureplate_basename
-- This is a workaround for a strange bug that occurs when the server is started
-- For some reason the first time on_timer is called, the pos is wrong
if not ppspec then return end
if not basename then return end
local objs = minetest.get_objects_inside_radius(pos, 1)
local two_below = mesecon:addPosRule(pos, {x = 0, y = -2, z = 0})
local two_below = vector.add(pos, vector.new(0, -2, 0))
if objs[1] == nil and node.name == ppspec.onstate then
minetest.add_node(pos, {name = ppspec.offstate})
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
if objs[1] == nil and node.name == basename .. "_on" then
minetest.set_node(pos, {name = basename .. "_off"})
mesecon.receptor_off(pos, mesecon.rules.pplate)
elseif node.name == basename .. "_off" then
for k, obj in pairs(objs) do
local objpos = obj:getpos()
if objpos.y > pos.y-1 and objpos.y < pos.y then
minetest.add_node(pos, {name=ppspec.onstate})
mesecon:receptor_on(pos)
-- force activation of mesecon two blocks below (hacky)
mesecon:turnon(two_below)
minetest.set_node(pos, {name = basename .. "_on"})
mesecon.receptor_on(pos, mesecon.rules.pplate )
end
end
end
@ -49,73 +43,47 @@ end
-- image: inventory and wield image of the pressure plate
-- recipe: crafting recipe of the pressure plate
function mesecon:register_pressure_plate(offstate, onstate, description, texture_off, texture_on, recipe)
local ppspec = {
offstate = offstate,
onstate = onstate
}
minetest.register_node(offstate, {
function mesecon.register_pressure_plate(basename, description, textures_off, textures_on, --[[image_w, image_i,]] recipe)
mesecon.register_node(basename, {
drawtype = "nodebox",
tiles = texture_off,
wield_image = texture_off,
-- inventory_image = image_i,
-- wield_image = image_w,
paramtype = "light",
selection_box = pp_box_off,
node_box = pp_box_off,
groups = {snappy = 2, oddly_breakable_by_hand = 3},
description = description,
pressureplate = ppspec,
pressureplate_basename = basename,
on_timer = pp_on_timer,
mesecons = {receptor = {
state = mesecon.state.off
}},
on_construct = function(pos)
minetest.get_node_timer(pos):start(PRESSURE_PLATE_INTERVAL)
minetest.get_node_timer(pos):start(mesecon.setting("pplate_interval", 0.1))
end,
})
minetest.register_node(onstate, {
drawtype = "nodebox",
tiles = texture_on,
paramtype = "light",
selection_box = pp_box_on,
},{
mesecons = {receptor = { state = mesecon.state.off, rules = mesecon.rules.pplate }},
node_box = pp_box_off,
selection_box = pp_box_off,
groups = {snappy = 2, oddly_breakable_by_hand = 3},
tiles = textures_off
},{
mesecons = {receptor = { state = mesecon.state.on, rules = mesecon.rules.pplate }},
node_box = pp_box_on,
selection_box = pp_box_on,
groups = {snappy = 2, oddly_breakable_by_hand = 3, not_in_creative_inventory = 1},
drop = offstate,
pressureplate = ppspec,
on_timer = pp_on_timer,
sounds = default.node_sound_wood_defaults(),
mesecons = {receptor = {
state = mesecon.state.on
}},
on_construct = function(pos)
minetest.get_node_timer(pos):start(PRESSURE_PLATE_INTERVAL)
end,
after_dig_node = function(pos)
local two_below = mesecon:addPosRule(pos, {x = 0, y = -2, z = 0})
if not mesecon:connected_to_receptor(two_below) then
mesecon:turnoff(two_below)
end
end
tiles = textures_on
})
minetest.register_craft({
output = offstate,
output = basename .. "_off",
recipe = recipe,
})
end
mesecon:register_pressure_plate(
"mesecons_pressureplates:pressure_plate_wood_off",
"mesecons_pressureplates:pressure_plate_wood_on",
mesecon.register_pressure_plate(
"mesecons_pressureplates:pressure_plate_wood",
"Wooden Pressure Plate",
{"default_wood.png"},
{"default_wood.png"},
{{"default:wood", "default:wood"}})
mesecon:register_pressure_plate(
"mesecons_pressureplates:pressure_plate_stone_off",
"mesecons_pressureplates:pressure_plate_stone_on",
mesecon.register_pressure_plate(
"mesecons_pressureplates:pressure_plate_stone",
"Stone Pressure Plate",
{"default_stone.png"},
{"default_stone.png"},

View File

@ -2,7 +2,8 @@
minetest.register_node("mesecons_solarpanel:solar_panel_on", {
drawtype = "nodebox",
tiles = { "jeija_solar_panel.png" },
inventor = { "jeija_solar_panel.png" },
inventory_image = "jeija_solar_panel.png",
wield_image = "jeija_solar_panel.png",
paramtype = "light",
paramtype2 = "wallmounted",
is_ground_content = true,
@ -61,7 +62,7 @@ minetest.register_abm(
if light >= 10 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2})
mesecon:receptor_on(pos)
mesecon.receptor_on(pos)
end
end,
})
@ -75,7 +76,7 @@ minetest.register_abm(
if light < 10 then
minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2})
mesecon:receptor_off(pos)
mesecon.receptor_off(pos)
end
end,
})

View File

@ -2,15 +2,15 @@
local rotate_torch_rules = function (rules, param2)
if param2 == 5 then
return mesecon:rotate_rules_right(rules)
return mesecon.rotate_rules_right(rules)
elseif param2 == 2 then
return mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules)) --180 degrees
return mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules)) --180 degrees
elseif param2 == 4 then
return mesecon:rotate_rules_left(rules)
return mesecon.rotate_rules_left(rules)
elseif param2 == 1 then
return mesecon:rotate_rules_down(rules)
return mesecon.rotate_rules_down(rules)
elseif param2 == 0 then
return mesecon:rotate_rules_up(rules)
return mesecon.rotate_rules_up(rules)
else
return rules
end
@ -124,8 +124,8 @@ minetest.register_craft({
action = function(pos, node)
local is_powered = false
for _, rule in ipairs(torch_get_input_rules(node)) do
local src = mesecon:addPosRule(pos, rule)
if mesecon:is_power_on(src) then
local src = vector.add(pos, rule)
if mesecon.is_power_on(src) then
is_powered = true
end
end
@ -133,11 +133,11 @@ minetest.register_craft({
if is_powered then
if node.name == "mesecons_torch:mesecon_torch_on" then
minetest.swap_node(pos, {name = "mesecons_torch:mesecon_torch_off", param2 = node.param2})
mesecon:receptor_off(pos, torch_get_output_rules(node))
mesecon.receptor_off(pos, torch_get_output_rules(node))
end
elseif node.name == "mesecons_torch:mesecon_torch_off" then
minetest.swap_node(pos, {name = "mesecons_torch:mesecon_torch_on", param2 = node.param2})
mesecon:receptor_on(pos, torch_get_output_rules(node))
mesecon.receptor_on(pos, torch_get_output_rules(node))
end
end
})]]

View File

@ -31,7 +31,7 @@ minetest.register_node("mesecons_walllever:wall_lever_off", {
description="Lever",
on_punch = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_walllever:wall_lever_on", param2 = node.param2})
mesecon:receptor_on(pos, mesecon.rules.buttonlike_get(node))
mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node))
minetest.sound_play("mesecons_lever", {pos=pos})
end,
sounds = default.node_sound_wood_defaults(),
@ -40,6 +40,7 @@ minetest.register_node("mesecons_walllever:wall_lever_off", {
state = mesecon.state.off
}}
})
minetest.register_node("mesecons_walllever:wall_lever_on", {
drawtype = "nodebox",
tiles = {
@ -70,7 +71,7 @@ minetest.register_node("mesecons_walllever:wall_lever_on", {
description="Lever",
on_punch = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_walllever:wall_lever_off", param2 = node.param2})
mesecon:receptor_off(pos, mesecon.rules.buttonlike_get(node))
mesecon.receptor_off(pos, mesecon.rules.buttonlike_get(node))
minetest.sound_play("mesecons_lever", {pos=pos})
end,
sounds = default.node_sound_wood_defaults(),

View File

@ -1,244 +0,0 @@
xof 0302txt 0064
// File created by CINEMA 4D
template Header {
<3D82AB43-62DA-11cf-AB39-0020AF71E433>
SWORD major;
SWORD minor;
DWORD flags;
}
template Vector {
<3D82AB5E-62DA-11cf-AB39-0020AF71E433>
FLOAT x;
FLOAT y;
FLOAT z;
}
template Coords2d {
<F6F23F44-7686-11cf-8F52-0040333594A3>
FLOAT u;
FLOAT v;
}
template Matrix4x4 {
<F6F23F45-7686-11cf-8F52-0040333594A3>
array FLOAT matrix[16];
}
template ColorRGBA {
<35FF44E0-6C7C-11cf-8F52-0040333594A3>
FLOAT red;
FLOAT green;
FLOAT blue;
FLOAT alpha;
}
template ColorRGB {
<D3E16E81-7835-11cf-8F52-0040333594A3>
FLOAT red;
FLOAT green;
FLOAT blue;
}
template IndexedColor {
<1630B820-7842-11cf-8F52-0040333594A3>
DWORD index;
ColorRGBA indexColor;
}
template Boolean {
<4885AE61-78E8-11cf-8F52-0040333594A3>
SWORD truefalse;
}
template Boolean2d {
<4885AE63-78E8-11cf-8F52-0040333594A3>
Boolean u;
Boolean v;
}
template MaterialWrap {
<4885AE60-78E8-11cf-8F52-0040333594A3>
Boolean u;
Boolean v;
}
template TextureFilename {
<A42790E1-7810-11cf-8F52-0040333594A3>
STRING filename;
}
template Material {
<3D82AB4D-62DA-11cf-AB39-0020AF71E433>
ColorRGBA faceColor;
FLOAT power;
ColorRGB specularColor;
ColorRGB emissiveColor;
[...]
}
template MeshFace {
<3D82AB5F-62DA-11cf-AB39-0020AF71E433>
DWORD nFaceVertexIndices;
array DWORD faceVertexIndices[nFaceVertexIndices];
}
template MeshFaceWraps {
<4885AE62-78E8-11cf-8F52-0040333594A3>
DWORD nFaceWrapValues;
Boolean2d faceWrapValues;
}
template MeshTextureCoords {
<F6F23F40-7686-11cf-8F52-0040333594A3>
DWORD nTextureCoords;
array Coords2d textureCoords[nTextureCoords];
}
template MeshMaterialList {
<F6F23F42-7686-11cf-8F52-0040333594A3>
DWORD nMaterials;
DWORD nFaceIndexes;
array DWORD faceIndexes[nFaceIndexes];
[Material]
}
template MeshNormals {
<F6F23F43-7686-11cf-8F52-0040333594A3>
DWORD nNormals;
array Vector normals[nNormals];
DWORD nFaceNormals;
array MeshFace faceNormals[nFaceNormals];
}
template MeshVertexColors {
<1630B821-7842-11cf-8F52-0040333594A3>
DWORD nVertexColors;
array IndexedColor vertexColors[nVertexColors];
}
template Mesh {
<3D82AB44-62DA-11cf-AB39-0020AF71E433>
DWORD nVertices;
array Vector vertices[nVertices];
DWORD nFaces;
array MeshFace faces[nFaces];
[...]
}
template FrameTransformMatrix {
<F6F23F41-7686-11cf-8F52-0040333594A3>
Matrix4x4 frameMatrix;
}
template Frame {
<3D82AB46-62DA-11cf-AB39-0020AF71E433>
[...]
}
Header {
1;
0;
1;
}
Mesh CINEMA4D_Mesh {
16;
// Lever1
-4.481;-4.311;-6.25;,
-44.655;43.567;-6.25;,
5.095;3.724;-6.25;,
-35.079;51.602;-6.25;,
5.095;3.724;6.25;,
-35.079;51.602;6.25;,
-4.481;-4.311;6.25;,
-44.655;43.567;6.25;,
// Lever_Hold
-25.0;-9.375;-18.75;,
-25.0;9.375;-18.75;,
25.0;-9.375;-18.75;,
25.0;9.375;-18.75;,
25.0;-9.375;18.75;,
25.0;9.375;18.75;,
-25.0;-9.375;18.75;,
-25.0;9.375;18.75;;
12;
// Lever1
4;0,1,3,2;,
4;2,3,5,4;,
4;4,5,7,6;,
4;6,7,1,0;,
4;1,7,5,3;,
4;6,0,2,4;,
// Lever_Hold
4;8,9,11,10;,
4;10,11,13,12;,
4;12,13,15,14;,
4;14,15,9,8;,
4;9,15,13,11;,
4;14,8,10,12;;
MeshNormals {
16;
// Lever1
0.088;-0.161;-0.036;,
-0.144;0.115;-0.036;,
0.144;-0.115;-0.036;,
-0.088;0.161;-0.036;,
0.144;-0.115;0.036;,
-0.088;0.161;0.036;,
0.088;-0.161;0.036;,
-0.144;0.115;0.036;,
// Lever_Hold
-0.144;-0.054;-0.108;,
-0.144;0.054;-0.108;,
0.144;-0.054;-0.108;,
0.144;0.054;-0.108;,
0.144;-0.054;0.108;,
0.144;0.054;0.108;,
-0.144;-0.054;0.108;,
-0.144;0.054;0.108;;
12;
// Lever1
4;0,1,3,2;,
4;2,3,5,4;,
4;4,5,7,6;,
4;6,7,1,0;,
4;1,7,5,3;,
4;6,0,2,4;,
// Lever_Hold
4;8,9,11,10;,
4;10,11,13,12;,
4;12,13,15,14;,
4;14,15,9,8;,
4;9,15,13,11;,
4;14,8,10,12;;
}
MeshTextureCoords {
16;
// Lever1
0.027;0.399;,
0.027;0.437;,
0.035;0.399;,
0.035;0.437;,
0.035;0.437;,
0.035;0.399;,
0.027;0.437;,
0.027;0.399;,
// Lever_Hold
0.0;0.063;,
0.0;0.086;,
0.031;0.063;,
0.031;0.086;,
0.031;0.086;,
0.031;0.063;,
0.0;0.086;,
0.0;0.063;;
}
}

View File

@ -1,274 +0,0 @@
xof 0302txt 0064
// File created by CINEMA 4D
template Header {
<3D82AB43-62DA-11cf-AB39-0020AF71E433>
SWORD major;
SWORD minor;
DWORD flags;
}
template Vector {
<3D82AB5E-62DA-11cf-AB39-0020AF71E433>
FLOAT x;
FLOAT y;
FLOAT z;
}
template Coords2d {
<F6F23F44-7686-11cf-8F52-0040333594A3>
FLOAT u;
FLOAT v;
}
template Matrix4x4 {
<F6F23F45-7686-11cf-8F52-0040333594A3>
array FLOAT matrix[16];
}
template ColorRGBA {
<35FF44E0-6C7C-11cf-8F52-0040333594A3>
FLOAT red;
FLOAT green;
FLOAT blue;
FLOAT alpha;
}
template ColorRGB {
<D3E16E81-7835-11cf-8F52-0040333594A3>
FLOAT red;
FLOAT green;
FLOAT blue;
}
template IndexedColor {
<1630B820-7842-11cf-8F52-0040333594A3>
DWORD index;
ColorRGBA indexColor;
}
template Boolean {
<4885AE61-78E8-11cf-8F52-0040333594A3>
SWORD truefalse;
}
template Boolean2d {
<4885AE63-78E8-11cf-8F52-0040333594A3>
Boolean u;
Boolean v;
}
template MaterialWrap {
<4885AE60-78E8-11cf-8F52-0040333594A3>
Boolean u;
Boolean v;
}
template TextureFilename {
<A42790E1-7810-11cf-8F52-0040333594A3>
STRING filename;
}
template Material {
<3D82AB4D-62DA-11cf-AB39-0020AF71E433>
ColorRGBA faceColor;
FLOAT power;
ColorRGB specularColor;
ColorRGB emissiveColor;
[...]
}
template MeshFace {
<3D82AB5F-62DA-11cf-AB39-0020AF71E433>
DWORD nFaceVertexIndices;
array DWORD faceVertexIndices[nFaceVertexIndices];
}
template MeshFaceWraps {
<4885AE62-78E8-11cf-8F52-0040333594A3>
DWORD nFaceWrapValues;
Boolean2d faceWrapValues;
}
template MeshTextureCoords {
<F6F23F40-7686-11cf-8F52-0040333594A3>
DWORD nTextureCoords;
array Coords2d textureCoords[nTextureCoords];
}
template MeshMaterialList {
<F6F23F42-7686-11cf-8F52-0040333594A3>
DWORD nMaterials;
DWORD nFaceIndexes;
array DWORD faceIndexes[nFaceIndexes];
[Material]
}
template MeshNormals {
<F6F23F43-7686-11cf-8F52-0040333594A3>
DWORD nNormals;
array Vector normals[nNormals];
DWORD nFaceNormals;
array MeshFace faceNormals[nFaceNormals];
}
template MeshVertexColors {
<1630B821-7842-11cf-8F52-0040333594A3>
DWORD nVertexColors;
array IndexedColor vertexColors[nVertexColors];
}
template Mesh {
<3D82AB44-62DA-11cf-AB39-0020AF71E433>
DWORD nVertices;
array Vector vertices[nVertices];
DWORD nFaces;
array MeshFace faces[nFaces];
[...]
}
template FrameTransformMatrix {
<F6F23F41-7686-11cf-8F52-0040333594A3>
Matrix4x4 frameMatrix;
}
template Frame {
<3D82AB46-62DA-11cf-AB39-0020AF71E433>
[...]
}
Header {
1;
0;
1;
}
Mesh CINEMA4D_Mesh {
16;
// Lever1
4.968;-3.861;6.175;,
44.767;43.898;-0.249;,
-4.623;4.154;6.346;,
35.177;51.913;-0.078;,
-5.577;3.277;-6.087;,
34.222;51.036;-12.511;,
4.014;-4.738;-6.258;,
43.813;43.021;-12.682;,
// Lever_Hold
-25.0;-9.375;-18.75;,
-25.0;9.375;-18.75;,
25.0;-9.375;-18.75;,
25.0;9.375;-18.75;,
25.0;-9.375;18.75;,
25.0;9.375;18.75;,
-25.0;-9.375;18.75;,
-25.0;9.375;18.75;;
12;
// Lever1
4;0,1,3,2;,
4;2,3,5,4;,
4;4,5,7,6;,
4;6,7,1,0;,
4;1,7,5,3;,
4;6,0,2,4;,
// Lever_Hold
4;8,9,11,10;,
4;10,11,13,12;,
4;12,13,15,14;,
4;14,15,9,8;,
4;9,15,13,11;,
4;14,8,10,12;;
MeshNormals {
16;
// Lever1
-0.084;-0.158;0.054;,
0.145;0.117;0.017;,
-0.14;-0.112;0.055;,
0.09;0.164;0.018;,
-0.145;-0.117;-0.017;,
0.084;0.158;-0.054;,
-0.09;-0.164;-0.018;,
0.14;0.112;-0.055;,
// Lever_Hold
-0.144;-0.054;-0.108;,
-0.144;0.054;-0.108;,
0.144;-0.054;-0.108;,
0.144;0.054;-0.108;,
0.144;-0.054;0.108;,
0.144;0.054;0.108;,
-0.144;-0.054;0.108;,
-0.144;0.054;0.108;;
12;
// Lever1
4;0,1,3,2;,
4;2,3,5,4;,
4;4,5,7,6;,
4;6,7,1,0;,
4;1,7,5,3;,
4;6,0,2,4;,
// Lever_Hold
4;8,9,11,10;,
4;10,11,13,12;,
4;12,13,15,14;,
4;14,15,9,8;,
4;9,15,13,11;,
4;14,8,10,12;;
}
MeshTextureCoords {
16;
// Lever1
0.027;0.399;,
0.027;0.437;,
0.035;0.399;,
0.035;0.437;,
0.035;0.437;,
0.035;0.399;,
0.027;0.437;,
0.027;0.399;,
// Lever_Hold
0.0;0.063;,
0.0;0.086;,
0.031;0.063;,
0.031;0.086;,
0.031;0.086;,
0.031;0.063;,
0.0;0.086;,
0.0;0.063;;
}
MeshMaterialList {
2;
12;
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1;
Material C4DMAT_NONE {
1.0;1.0;1.0;1.0;;
1.0;
0.0;0.0;0.0;;
0.0;0.0;0.0;;
}
Material C4DMAT_Terrain {
1.0;1.0;1.0;1.0;;
1.0;
0.0;0.0;0.0;;
0.0;0.0;0.0;;
}
}
}

View File

@ -604,12 +604,6 @@ minetest.register_craft({
recipe = "default:stone_with_coal",
})
minetest.register_craft({
type = "cooking",
output = "mesecons:wire_00000000_off 5",
recipe = "default:stone_with_bluestone",
})
minetest.register_craft({
type = "cooking",
output = "default:diamond",

View File

@ -773,7 +773,7 @@ minetest.register_node("default:stone_with_bluestone", {
description = "Bluestone Ore",
tiles = {"default_stone.png^default_mineral_bluestone.png"},
groups = {cracky = 2},
drop = "mesecons:wire_00000000_off 5",
drop = "mesecons:wire_00000000_off 8",
sounds = default.node_sound_stone_defaults(),
})

View File

@ -424,7 +424,7 @@ local function punch(pos)
else
state = 1
minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
tmp_node = {name="doors:trapdoors_door_open", param1=me.param1, param2=me.param2}
tmp_node = {name="doors:trapdoor_open", param1=me.param1, param2=me.param2}
end
update_door(pos, tmp_node)
meta:set_int("state", state)
@ -477,7 +477,7 @@ minetest.register_node("doors:trapdoor", {
})
minetest.register_node("doors:trapdoors_door_open", {
minetest.register_node("doors:trapdoor_open", {
drawtype = "nodebox",
tiles = {"default_wood.png", "default_wood.png", "default_wood.png", "default_wood.png", "door_trapdoor.png", "door_trapdoor.png"},
paramtype = "light",
@ -506,8 +506,7 @@ minetest.register_node("doors:trapdoors_door_open", {
})
minetest.register_alias("doors:trapdoors_door_open", "doors:trapdoor_open")
minetest.register_craft({
output = 'doors:trapdoor 2',
@ -518,7 +517,7 @@ minetest.register_craft({
}
})
--- Iron Trapdoor ----
--- Steel Trapdoor ----
local me
local meta
local state = 0
@ -537,19 +536,19 @@ local function punch(pos)
if state == 1 then
state = 0
minetest.sound_play("doors_door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
tmp_node = {name="doors:iron_trapdoor", param1=me.param1, param2=me.param2}
tmp_node = {name="doors:trapdoor_steel", param1=me.param1, param2=me.param2}
else
state = 1
minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
tmp_node = {name="doors:iron_trapdoors_door_open", param1=me.param1, param2=me.param2}
tmp_node = {name="doors:trapdoor_steel_open", param1=me.param1, param2=me.param2}
end
update_door(pos, tmp_node)
meta:set_int("state", state)
end
minetest.register_node("doors:iron_trapdoor", {
description = "Trapdoor",
minetest.register_node("doors:trapdoor_steel", {
description = "Steel Trapdoor",
drawtype = "nodebox",
tiles = {"iron_trapdoor.png", "iron_trapdoor.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png"},
paramtype = "light",
@ -557,7 +556,7 @@ minetest.register_node("doors:iron_trapdoor", {
paramtype2 = "facedir",
groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2,mesecon_effector_on=1, flammable = 0, door=1},
sounds = default.node_sound_wood_defaults(),
drop = "doors:iron_trapdoor",
drop = "doors:trapdoor_steel",
node_box = {
type = "fixed",
fixed = {
@ -590,8 +589,7 @@ minetest.register_node("doors:iron_trapdoor", {
end,
})
minetest.register_node("doors:iron_trapdoors_door_open", {
minetest.register_node("doors:trapdoor_steel_open", {
drawtype = "nodebox",
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "iron_trapdoor.png", "iron_trapdoor.png"},
paramtype = "light",
@ -600,7 +598,7 @@ minetest.register_node("doors:iron_trapdoors_door_open", {
stack_max = 0,
groups = {snappy = 1, choppy = 2, oddly_breakable_by_hand = 2, flammable = 0,door=1,mesecon_effector_on=1},
sounds = default.node_sound_wood_defaults(),
drop = "doors:iron_trapdoor",
drop = "doors:trapdoor_steel",
node_box = {
type = "fixed",
fixed = {-0.5, -0.5, 0.4, 0.5, 0.5, 0.5}
@ -616,6 +614,9 @@ minetest.register_node("doors:iron_trapdoors_door_open", {
}},
})
minetest.register_alias("doors:iron_trapdoors_door_open", "doors:trapdoor_steel_open")
minetest.register_alias("doors:iron_trapdoor", "doors:trapdoor_steel")
minetest.register_craft({
output = 'doors:iron_trapdoor 2',
recipe = {