1
0
mirror of https://github.com/sys4-fr/server-nalc.git synced 2024-12-25 18:20:36 +01:00

[mesecons] Update

- Update of Mesecons
This commit is contained in:
LeMagnesium 2016-03-03 22:14:11 +01:00
parent f89496571b
commit 7f607115fe
19 changed files with 374 additions and 261 deletions

View File

@ -22,7 +22,7 @@ OK, I want in.
-------------- --------------
Go get it! Go get it!
[DOWNLOADS PAGE](http://mesecons.net/downloads.php) [DOWNLOAD IT NOW](https://github.com/Jeija/minetest-mod-mesecons/archive/master.zip)
Now go ahead and install it like any other Minetest mod. Don't know how? Check out [the wonderful page about it](http://wiki.minetest.com/wiki/Mods) over at the Minetest Wiki. For your convenience, here's a quick summary: Now go ahead and install it like any other Minetest mod. Don't know how? Check out [the wonderful page about it](http://wiki.minetest.com/wiki/Mods) over at the Minetest Wiki. For your convenience, here's a quick summary:
@ -39,7 +39,7 @@ How do I use this thing?
------------------------ ------------------------
How about a [quick overview video](https://www.youtube.com/watch?v=6kmeQj6iW5k)? How about a [quick overview video](https://www.youtube.com/watch?v=6kmeQj6iW5k)?
Or maybe a [comprehensive reference](http://mesecons.net/items.php) is your style? Or maybe a [comprehensive reference](http://mesecons.net/items.html) is your style?
An overview for the very newest of new beginners? How does [this one](http://uberi.mesecons.net/projects/MeseconsBasics/index.html) look? An overview for the very newest of new beginners? How does [this one](http://uberi.mesecons.net/projects/MeseconsBasics/index.html) look?

View File

@ -1 +0,0 @@
0.41 DEV

View File

@ -23,7 +23,7 @@ function mesecon.queue:add_action(pos, func, params, time, overwritecheck, prior
-- Otherwise, add the action to the queue -- Otherwise, add the action to the queue
if overwritecheck then -- check if old action has to be overwritten / removed: if overwritecheck then -- check if old action has to be overwritten / removed:
for i, ac in ipairs(mesecon.queue.actions) do for i, ac in ipairs(mesecon.queue.actions) do
if(mesecon.cmpPos(pos, ac.pos) if(vector.equals(pos, ac.pos)
and mesecon.cmpAny(overwritecheck, ac.owcheck)) then and mesecon.cmpAny(overwritecheck, ac.owcheck)) then
toremove = i toremove = i
break break
@ -94,25 +94,8 @@ end
-- Store and read the ActionQueue to / from a file -- Store and read the ActionQueue to / from a file
-- so that upcoming actions are remembered when the game -- so that upcoming actions are remembered when the game
-- is restarted -- is restarted
mesecon.queue.actions = mesecon.file2table("mesecon_actionqueue")
local wpath = minetest.get_worldpath()
local function file2table(filename)
local f = io.open(filename, "r")
if f==nil then return {} end
local t = f:read("*all")
f:close()
if t=="" or t==nil then return {} end
return minetest.deserialize(t)
end
local function table2file(filename, table)
local f = io.open(filename, "w")
f:write(minetest.serialize(table))
f:close()
end
mesecon.queue.actions = file2table(wpath.."/mesecon_actionqueue")
minetest.register_on_shutdown(function() minetest.register_on_shutdown(function()
mesecon.queue.actions = table2file(wpath.."/mesecon_actionqueue", mesecon.queue.actions) mesecon.table2file("mesecon_actionqueue", mesecon.queue.actions)
end) end)

View File

@ -74,7 +74,7 @@ mesecon.queue:add_function("receptor_on", function (pos, rules)
-- if area (any of the rule targets) is not loaded, keep trying and call this again later -- if area (any of the rule targets) is not loaded, keep trying and call this again later
for _, rule in ipairs(mesecon.flattenrules(rules)) do for _, rule in ipairs(mesecon.flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule) local np = vector.add(pos, rule)
-- if area is not loaded, keep trying -- if area is not loaded, keep trying
if minetest.get_node_or_nil(np) == nil then if minetest.get_node_or_nil(np) == nil then
mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules) mesecon.queue:add_action(pos, "receptor_on", {rules}, nil, rules)
@ -84,7 +84,7 @@ mesecon.queue:add_function("receptor_on", function (pos, rules)
-- execute action -- execute action
for _, rule in ipairs(mesecon.flattenrules(rules)) do for _, rule in ipairs(mesecon.flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule) local np = vector.add(pos, rule)
local rulenames = mesecon.rules_link_rule_all(pos, rule) local rulenames = mesecon.rules_link_rule_all(pos, rule)
for _, rulename in ipairs(rulenames) do for _, rulename in ipairs(rulenames) do
mesecon.turnon(np, rulename) mesecon.turnon(np, rulename)
@ -101,7 +101,7 @@ mesecon.queue:add_function("receptor_off", function (pos, rules)
-- if area (any of the rule targets) is not loaded, keep trying and call this again later -- if area (any of the rule targets) is not loaded, keep trying and call this again later
for _, rule in ipairs(mesecon.flattenrules(rules)) do for _, rule in ipairs(mesecon.flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule) local np = vector.add(pos, rule)
if minetest.get_node_or_nil(np) == nil then if minetest.get_node_or_nil(np) == nil then
mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules) mesecon.queue:add_action(pos, "receptor_off", {rules}, nil, rules)
return return
@ -109,7 +109,7 @@ mesecon.queue:add_function("receptor_off", function (pos, rules)
end end
for _, rule in ipairs(mesecon.flattenrules(rules)) do for _, rule in ipairs(mesecon.flattenrules(rules)) do
local np = mesecon.addPosRule(pos, rule) local np = vector.add(pos, rule)
local rulenames = mesecon.rules_link_rule_all(pos, rule) local rulenames = mesecon.rules_link_rule_all(pos, rule)
for _, rulename in ipairs(rulenames) do for _, rulename in ipairs(rulenames) do
if not mesecon.connected_to_receptor(np, mesecon.invertRule(rule)) then if not mesecon.connected_to_receptor(np, mesecon.invertRule(rule)) then

View File

@ -77,6 +77,8 @@ function mesecon.get_conductor(nodename)
end end
function mesecon.get_any_outputrules (node) function mesecon.get_any_outputrules (node)
if not node then return nil end
if mesecon.is_conductor(node.name) then if mesecon.is_conductor(node.name) then
return mesecon.conductor_get_rules(node) return mesecon.conductor_get_rules(node)
elseif mesecon.is_receptor(node.name) then elseif mesecon.is_receptor(node.name) then
@ -85,6 +87,8 @@ function mesecon.get_any_outputrules (node)
end end
function mesecon.get_any_inputrules (node) function mesecon.get_any_inputrules (node)
if not node then return nil end
if mesecon.is_conductor(node.name) then if mesecon.is_conductor(node.name) then
return mesecon.conductor_get_rules(node) return mesecon.conductor_get_rules(node)
elseif mesecon.is_effector(node.name) then elseif mesecon.is_effector(node.name) then
@ -182,7 +186,9 @@ end
-- Activation: -- Activation:
mesecon.queue:add_function("activate", function (pos, rulename) mesecon.queue:add_function("activate", function (pos, rulename)
local node = minetest.get_node(pos) local node = mesecon.get_node_force(pos)
if not node then return end
local effector = mesecon.get_effector(node.name) local effector = mesecon.get_effector(node.name)
if effector and effector.action_on then if effector and effector.action_on then
@ -203,7 +209,9 @@ end
-- Deactivation -- Deactivation
mesecon.queue:add_function("deactivate", function (pos, rulename) mesecon.queue:add_function("deactivate", function (pos, rulename)
local node = minetest.get_node(pos) local node = mesecon.get_node_force(pos)
if not node then return end
local effector = mesecon.get_effector(node.name) local effector = mesecon.get_effector(node.name)
if effector and effector.action_off then if effector and effector.action_off then
@ -224,7 +232,9 @@ end
-- Change -- Change
mesecon.queue:add_function("change", function (pos, rulename, changetype) mesecon.queue:add_function("change", function (pos, rulename, changetype)
local node = minetest.get_node(pos) local node = mesecon.get_node_force(pos)
if not node then return end
local effector = mesecon.get_effector(node.name) local effector = mesecon.get_effector(node.name)
if effector and effector.action_change then if effector and effector.action_change then
@ -249,6 +259,8 @@ end
-- Conductors -- Conductors
function mesecon.is_conductor_on(node, rulename) function mesecon.is_conductor_on(node, rulename)
if not node then return false end
local conductor = mesecon.get_conductor(node.name) local conductor = mesecon.get_conductor(node.name)
if conductor then if conductor then
if conductor.state then if conductor.state then
@ -263,10 +275,13 @@ function mesecon.is_conductor_on(node, rulename)
return mesecon.get_bit(binstate, bit) return mesecon.get_bit(binstate, bit)
end end
end end
return false return false
end end
function mesecon.is_conductor_off(node, rulename) function mesecon.is_conductor_off(node, rulename)
if not node then return false end
local conductor = mesecon.get_conductor(node.name) local conductor = mesecon.get_conductor(node.name)
if conductor then if conductor then
if conductor.state then if conductor.state then
@ -281,6 +296,7 @@ function mesecon.is_conductor_off(node, rulename)
return not mesecon.get_bit(binstate, bit) return not mesecon.get_bit(binstate, bit)
end end
end end
return false return false
end end
@ -340,16 +356,16 @@ end
-- some more general high-level stuff -- some more general high-level stuff
function mesecon.is_power_on(pos, rulename) function mesecon.is_power_on(pos, rulename)
local node = minetest.get_node(pos) local node = mesecon.get_node_force(pos)
if mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name) then if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then
return true return true
end end
return false return false
end end
function mesecon.is_power_off(pos, rulename) function mesecon.is_power_off(pos, rulename)
local node = minetest.get_node(pos) local node = mesecon.get_node_force(pos)
if mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name) then if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then
return true return true
end end
return false return false
@ -361,7 +377,7 @@ function mesecon.turnon(pos, link)
local depth = 1 local depth = 1
while frontiers[depth] do while frontiers[depth] do
local f = frontiers[depth] local f = frontiers[depth]
local node = minetest.get_node_or_nil(f.pos) local node = mesecon.get_node_force(f.pos)
-- area not loaded, postpone action -- area not loaded, postpone action
if not node then if not node then
@ -374,10 +390,10 @@ function mesecon.turnon(pos, link)
-- call turnon on neighbors: normal rules -- call turnon on neighbors: normal rules
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
local np = mesecon.addPosRule(f.pos, r) local np = vector.add(f.pos, r)
-- area not loaded, postpone action -- area not loaded, postpone action
if not minetest.get_node_or_nil(np) then if not mesecon.get_node_force(np) then
mesecon.queue:add_action(np, "turnon", {rulename}, mesecon.queue:add_action(np, "turnon", {rulename},
nil, true) nil, true)
else else
@ -407,7 +423,7 @@ function mesecon.turnoff(pos, link)
local depth = 1 local depth = 1
while frontiers[depth] do while frontiers[depth] do
local f = frontiers[depth] local f = frontiers[depth]
local node = minetest.get_node_or_nil(f.pos) local node = mesecon.get_node_force(f.pos)
-- area not loaded, postpone action -- area not loaded, postpone action
if not node then if not node then
@ -420,10 +436,10 @@ function mesecon.turnoff(pos, link)
-- call turnoff on neighbors: normal rules -- call turnoff on neighbors: normal rules
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
local np = mesecon.addPosRule(f.pos, r) local np = vector.add(f.pos, r)
-- area not loaded, postpone action -- area not loaded, postpone action
if not minetest.get_node_or_nil(np) then if not mesecon.get_node_force(np) then
mesecon.queue:add_action(np, "turnoff", {rulename}, mesecon.queue:add_action(np, "turnoff", {rulename},
nil, true) nil, true)
else else
@ -449,7 +465,8 @@ end)
function mesecon.connected_to_receptor(pos, link) function mesecon.connected_to_receptor(pos, link)
local node = minetest.get_node(pos) local node = mesecon.get_node_force(pos)
if not node then return false end
-- Check if conductors around are connected -- Check if conductors around are connected
local rules = mesecon.get_any_inputrules(node) local rules = mesecon.get_any_inputrules(node)
@ -458,7 +475,7 @@ function mesecon.connected_to_receptor(pos, link)
for _, rule in ipairs(mesecon.rule2meta(link, rules)) do for _, rule in ipairs(mesecon.rule2meta(link, rules)) do
local links = mesecon.rules_link_rule_all_inverted(pos, rule) local links = mesecon.rules_link_rule_all_inverted(pos, rule)
for _, l in ipairs(links) do for _, l in ipairs(links) do
local np = mesecon.addPosRule(pos, l) local np = vector.add(pos, l)
if mesecon.find_receptor_on(np, mesecon.invertRule(l)) then if mesecon.find_receptor_on(np, mesecon.invertRule(l)) then
return true return true
end end
@ -476,7 +493,7 @@ function mesecon.find_receptor_on(pos, link)
local depth = 1 local depth = 1
while frontiers[depth] do while frontiers[depth] do
local f = frontiers[depth] local f = frontiers[depth]
local node = minetest.get_node_or_nil(f.pos) local node = mesecon.get_node_force(f.pos)
if not node then return false end if not node then return false end
if mesecon.is_receptor_on(node.name) then return true end if mesecon.is_receptor_on(node.name) then return true end
@ -485,7 +502,7 @@ function mesecon.find_receptor_on(pos, link)
-- call turnoff on neighbors: normal rules -- call turnoff on neighbors: normal rules
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
local np = mesecon.addPosRule(f.pos, r) local np = vector.add(f.pos, r)
local links = mesecon.rules_link_rule_all_inverted(f.pos, r) local links = mesecon.rules_link_rule_all_inverted(f.pos, r)
for _, l in ipairs(links) do for _, l in ipairs(links) do
@ -503,8 +520,9 @@ function mesecon.find_receptor_on(pos, link)
end end
function mesecon.rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule function mesecon.rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule
local outputnode = minetest.get_node(output) local outputnode = mesecon.get_node_force(output)
local inputnode = minetest.get_node(input) local inputnode = mesecon.get_node_force(input)
local outputrules = dug_outputrules or mesecon.get_any_outputrules (outputnode) local outputrules = dug_outputrules or mesecon.get_any_outputrules (outputnode)
local inputrules = mesecon.get_any_inputrules (inputnode) local inputrules = mesecon.get_any_inputrules (inputnode)
if not outputrules or not inputrules then if not outputrules or not inputrules then
@ -513,21 +531,22 @@ function mesecon.rules_link(output, input, dug_outputrules) --output/input are p
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
-- Check if output sends to input -- Check if output sends to input
if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then if vector.equals(vector.add(output, outputrule), input) then
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
-- Check if input accepts from output -- Check if input accepts from output
if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then if vector.equals(vector.add(input, inputrule), output) then
return true, inputrule return true, inputrule
end end
end end
end end
end end
return false return false
end end
function mesecon.rules_link_rule_all(output, rule) function mesecon.rules_link_rule_all(output, rule)
local input = mesecon.addPosRule(output, rule) local input = vector.add(output, rule)
local inputnode = minetest.get_node(input) local inputnode = mesecon.get_node_force(input)
local inputrules = mesecon.get_any_inputrules (inputnode) local inputrules = mesecon.get_any_inputrules (inputnode)
if not inputrules then if not inputrules then
return {} return {}
@ -536,17 +555,18 @@ function mesecon.rules_link_rule_all(output, rule)
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
-- Check if input accepts from output -- Check if input accepts from output
if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then if vector.equals(vector.add(input, inputrule), output) then
table.insert(rules, inputrule) table.insert(rules, inputrule)
end end
end end
return rules return rules
end end
function mesecon.rules_link_rule_all_inverted(input, rule) function mesecon.rules_link_rule_all_inverted(input, rule)
--local irule = mesecon.invertRule(rule) --local irule = mesecon.invertRule(rule)
local output = mesecon.addPosRule(input, rule) local output = vector.add(input, rule)
local outputnode = minetest.get_node(output) local outputnode = mesecon.get_node_force(output)
local outputrules = mesecon.get_any_outputrules (outputnode) local outputrules = mesecon.get_any_outputrules (outputnode)
if not outputrules then if not outputrules then
return {} return {}
@ -554,7 +574,7 @@ function mesecon.rules_link_rule_all_inverted(input, rule)
local rules = {} local rules = {}
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then if vector.equals(vector.add(output, outputrule), input) then
table.insert(rules, mesecon.invertRule(outputrule)) table.insert(rules, mesecon.invertRule(outputrule))
end end
end end
@ -566,7 +586,7 @@ function mesecon.rules_link_anydir(pos1, pos2)
end end
function mesecon.is_powered(pos, rule) function mesecon.is_powered(pos, rule)
local node = minetest.get_node(pos) local node = mesecon.get_node_force(pos)
local rules = mesecon.get_any_inputrules(node) local rules = mesecon.get_any_inputrules(node)
if not rules then return false end if not rules then return false end
@ -577,10 +597,11 @@ function mesecon.is_powered(pos, rule)
for _, rule in ipairs(mesecon.flattenrules(rules)) do for _, rule in ipairs(mesecon.flattenrules(rules)) do
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
for _, rname in ipairs(rulenames) do for _, rname in ipairs(rulenames) do
local np = mesecon.addPosRule(pos, rname) local np = vector.add(pos, rname)
local nn = minetest.get_node(np) local nn = mesecon.get_node_force(np)
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
or mesecon.is_receptor_on (nn.name)) then if (mesecon.is_conductor_on(nn, mesecon.invertRule(rname))
or mesecon.is_receptor_on(nn.name)) then
table.insert(sourcepos, np) table.insert(sourcepos, np)
end end
end end
@ -588,8 +609,8 @@ function mesecon.is_powered(pos, rule)
else else
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
for _, rname in ipairs(rulenames) do for _, rname in ipairs(rulenames) do
local np = mesecon.addPosRule(pos, rname) local np = vector.add(pos, rname)
local nn = minetest.get_node(np) local nn = mesecon.get_node_force(np)
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
or mesecon.is_receptor_on (nn.name)) then or mesecon.is_receptor_on (nn.name)) then
table.insert(sourcepos, np) table.insert(sourcepos, np)

View File

@ -16,7 +16,7 @@ mesecon.on_placenode = function (pos, node)
-- also call receptor_on if itself is powered already, so that neighboring -- also call receptor_on if itself is powered already, so that neighboring
-- conductors will be activated (when pushing an on-conductor with a piston) -- conductors will be activated (when pushing an on-conductor with a piston)
for _, s in ipairs(sources) do for _, s in ipairs(sources) do
local rule = {x = pos.x - s.x, y = pos.y - s.y, z = pos.z - s.z} local rule = vector.subtract(pos, s)
mesecon.turnon(pos, rule) mesecon.turnon(pos, rule)
end end
--mesecon.receptor_on (pos, mesecon.conductor_get_rules(node)) --mesecon.receptor_on (pos, mesecon.conductor_get_rules(node))

View File

@ -2,7 +2,7 @@ function mesecon.move_node(pos, newpos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos):to_table() local meta = minetest.get_meta(pos):to_table()
minetest.remove_node(pos) minetest.remove_node(pos)
minetest.add_node(newpos, node) minetest.set_node(newpos, node)
minetest.get_meta(pos):from_table(meta) minetest.get_meta(pos):from_table(meta)
end end
@ -50,7 +50,7 @@ function mesecon.rule2bit(findrule, allrules)
end end
for m,metarule in ipairs( allrules) do for m,metarule in ipairs( allrules) do
for _, rule in ipairs(metarule ) do for _, rule in ipairs(metarule ) do
if mesecon.cmpPos(findrule, rule) then if vector.equals(findrule, rule) then
return m return m
end end
end end
@ -69,7 +69,7 @@ function mesecon.rule2metaindex(findrule, allrules)
for m, metarule in ipairs( allrules) do for m, metarule in ipairs( allrules) do
for _, rule in ipairs(metarule ) do for _, rule in ipairs(metarule ) do
if mesecon.cmpPos(findrule, rule) then if vector.equals(findrule, rule) then
return m return m
end end
end end
@ -133,15 +133,7 @@ function mesecon.set_bit(binary,bit,value)
end end
function mesecon.invertRule(r) function mesecon.invertRule(r)
return {x = -r.x, y = -r.y, z = -r.z} 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 end
function mesecon.tablecopy(table) -- deep table copy function mesecon.tablecopy(table) -- deep table copy
@ -209,3 +201,75 @@ function mesecon.flipstate(pos, node)
return newstate return newstate
end 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

@ -22,7 +22,7 @@ local wire_getconnect = function (from_pos, self_pos)
end end
for _, r in ipairs(mesecon.flattenrules(rules)) do for _, r in ipairs(mesecon.flattenrules(rules)) do
if (mesecon.cmpPos(mesecon.addPosRule(self_pos, r), from_pos)) then if (vector.equals(vector.add(self_pos, r), from_pos)) then
return true return true
end end
end end
@ -35,7 +35,7 @@ local wire_updateconnect = function (pos)
local connections = {} local connections = {}
for _, r in ipairs(mesecon.rules.default) do for _, r in ipairs(mesecon.rules.default) do
if wire_getconnect(pos, mesecon.addPosRule(pos, r)) then if wire_getconnect(pos, vector.add(pos, r)) then
table.insert(connections, r) table.insert(connections, r)
end end
end end
@ -83,7 +83,7 @@ local update_on_place_dig = function (pos, node)
if (not rules) then return end if (not rules) then return end
for _, r in ipairs(mesecon.flattenrules(rules)) do for _, r in ipairs(mesecon.flattenrules(rules)) do
local np = mesecon.addPosRule(pos, r) local np = vector.add(pos, r)
if minetest.registered_nodes[minetest.get_node(np).name] if minetest.registered_nodes[minetest.get_node(np).name]
and minetest.registered_nodes[minetest.get_node(np).name].mesecon_wire then and minetest.registered_nodes[minetest.get_node(np).name].mesecon_wire then
wire_updateconnect(np) wire_updateconnect(np)

View File

@ -4,6 +4,7 @@ local GET_COMMAND = "GET"
-- Detects players in a certain radius -- Detects players in a certain radius
-- The radius can be specified in mesecons/settings.lua -- The radius can be specified in mesecons/settings.lua
-- The following file was modified to detect multiple players
local object_detector_make_formspec = function (pos) local object_detector_make_formspec = function (pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("formspec", "size[9,2.5]" .. meta:set_string("formspec", "size[9,2.5]" ..
@ -101,43 +102,44 @@ minetest.register_craft({
} }
}) })
minetest.register_abm( minetest.register_abm({
{nodenames = {"mesecons_detector:object_detector_off"}, nodenames = {"mesecons_detector:object_detector_off"},
interval = 1.0, interval = 1,
chance = 1, chance = 1,
action = function(pos) action = function(pos, node)
if object_detector_scan(pos) then if not object_detector_scan(pos) then return end
minetest.swap_node(pos, {name = "mesecons_detector:object_detector_on"})
mesecon.receptor_on(pos, mesecon.rules.pplate) node.name = "mesecons_detector:object_detector_on"
end minetest.swap_node(pos, node)
mesecon.receptor_on(pos, mesecon.rules.pplate)
end, end,
}) })
minetest.register_abm( minetest.register_abm({
{nodenames = {"mesecons_detector:object_detector_on"}, nodenames = {"mesecons_detector:object_detector_on"},
interval = 1.0, interval = 1,
chance = 1, chance = 1,
action = function(pos) action = function(pos, node)
if not object_detector_scan(pos) then if object_detector_scan(pos) then return end
minetest.swap_node(pos, {name = "mesecons_detector:object_detector_off"})
mesecon.receptor_off(pos, mesecon.rules.pplate) node.name = "mesecons_detector:object_detector_off"
end minetest.swap_node(pos, node)
mesecon.receptor_off(pos, mesecon.rules.pplate)
end, end,
}) })
-- Node detector -- Node detector
-- Detects the node in front of it -- Detects the node in front of it
local node_detector_make_formspec = function (pos) local function node_detector_make_formspec(pos)
local meta = minetest.get_meta(pos) minetest.get_meta(pos):set_string("formspec", "size[9,2.5]" ..
meta:set_string("formspec", "size[9,2.5]" ..
"field[0.3, 0;9,2;scanname;Name of node to scan for (empty for any):;${scanname}]".. "field[0.3, 0;9,2;scanname;Name of node to scan for (empty for any):;${scanname}]"..
"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]".. "field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
"button_exit[7,0.75;2,3;;Save]") "button_exit[7,0.75;2,3;;Save]")
end end
local node_detector_on_receive_fields = function(pos, formname, fields) local function node_detector_on_receive_fields(pos, _, fields)
if not fields.scanname or not fields.digiline_channel then return end; if not fields.scanname or not fields.digiline_channel then return end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("scanname", fields.scanname) meta:set_string("scanname", fields.scanname)
@ -145,41 +147,59 @@ local node_detector_on_receive_fields = function(pos, formname, fields)
node_detector_make_formspec(pos) node_detector_make_formspec(pos)
end end
-- returns true if player was found, false if not -- returns true if node was found, false if not
local node_detector_scan = function (pos) local function node_detector_scan(pos)
if not pos then return end
local node = minetest.get_node_or_nil(pos) local node = minetest.get_node_or_nil(pos)
if not node then return end if not node then return end
local scandir = minetest.facedir_to_dir(node.param2)
if not scandir then return end local frontname = minetest.get_node(
local frontpos = vector.subtract(pos, scandir) vector.subtract(pos, minetest.facedir_to_dir(node.param2))
local frontnode = minetest.get_node(frontpos) ).name
local meta = minetest.get_meta(pos) local scanname = minetest.get_meta(pos):get_string("scanname")
return (frontnode.name == meta:get_string("scanname")) or
(frontnode.name ~= "air" and frontnode.name ~= "ignore" and meta:get_string("scanname") == "") return (frontname == scanname) or
(frontname ~= "air" and frontname ~= "ignore" and scanname == "")
end end
-- set player name when receiving a digiline signal on a specific channel -- set player name when receiving a digiline signal on a specific channel
local node_detector_digiline = { local node_detector_digiline = {
effector = { effector = {
action = function (pos, node, channel, msg) action = function(pos, node, channel, msg)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local active_channel = meta:get_string("digiline_channel") if channel ~= meta:get_string("digiline_channel") then return end
if channel == active_channel then
if msg == GET_COMMAND then if msg == GET_COMMAND then
local frontpos = vector.subtract(pos, minetest.facedir_to_dir(node.param2)) local nodename = minetest.get_node(
local name = minetest.get_node(frontpos).name vector.subtract(pos, minetest.facedir_to_dir(node.param2))
digiline:receptor_send(pos, digiline.rules.default, channel, name) ).name
else
meta:set_string("scanname", msg) digiline:receptor_send(pos, digiline.rules.default, channel, nodename)
node_detector_make_formspec(pos) else
end meta:set_string("scanname", msg)
node_detector_make_formspec(pos)
end end
end, end,
}, },
receptor = {} receptor = {}
} }
local function after_place_node_detector(pos, placer)
local placer_pos = placer:getpos()
if not placer_pos then
return
end
--correct for the player's height
if placer:is_player() then
placer_pos.y = placer_pos.y + 1.625
end
--correct for 6d facedir
local node = minetest.get_node(pos)
node.param2 = minetest.dir_to_facedir(vector.subtract(pos, placer_pos), true)
minetest.set_node(pos, node)
end
minetest.register_node("mesecons_detector:node_detector_off", { minetest.register_node("mesecons_detector:node_detector_off", {
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_off.png"}, tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_off.png"},
paramtype = "light", paramtype = "light",
@ -192,25 +212,7 @@ minetest.register_node("mesecons_detector:node_detector_off", {
}}, }},
on_construct = node_detector_make_formspec, on_construct = node_detector_make_formspec,
on_receive_fields = node_detector_on_receive_fields, on_receive_fields = node_detector_on_receive_fields,
after_place_node = function (pos, placer) after_place_node = after_place_node_detector,
local placer_pos = placer:getpos()
--correct for the player's height
if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
--correct for 6d facedir
if placer_pos then
local dir = {
x = pos.x - placer_pos.x,
y = pos.y - placer_pos.y,
z = pos.z - placer_pos.z
}
local node = minetest.get_node(pos)
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.set_node(pos, node)
minetest.log("action", "real (6d) facedir: " .. node.param2)
end
end,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
digiline = node_detector_digiline digiline = node_detector_digiline
}) })
@ -227,25 +229,7 @@ minetest.register_node("mesecons_detector:node_detector_on", {
}}, }},
on_construct = node_detector_make_formspec, on_construct = node_detector_make_formspec,
on_receive_fields = node_detector_on_receive_fields, on_receive_fields = node_detector_on_receive_fields,
after_place_node = function (pos, placer) after_place_node = after_place_node_detector,
local placer_pos = placer:getpos()
--correct for the player's height
if placer:is_player() then placer_pos.y = placer_pos.y + 1.5 end
--correct for 6d facedir
if placer_pos then
local dir = {
x = pos.x - placer_pos.x,
y = pos.y - placer_pos.y,
z = pos.z - placer_pos.z
}
local node = minetest.get_node(pos)
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.set_node(pos, node)
minetest.log("action", "real (6d) facedir: " .. node.param2)
end
end,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
digiline = node_detector_digiline digiline = node_detector_digiline
}) })
@ -259,26 +243,28 @@ minetest.register_craft({
} }
}) })
minetest.register_abm( minetest.register_abm({
{nodenames = {"mesecons_detector:node_detector_off"}, nodenames = {"mesecons_detector:node_detector_off"},
interval = 1.0, interval = 1,
chance = 1, chance = 1,
action = function(pos, node) action = function(pos, node)
if node_detector_scan(pos) then if not node_detector_scan(pos) then return end
minetest.swap_node(pos, {name = "mesecons_detector:node_detector_on", param2 = node.param2})
mesecon.receptor_on(pos) node.name = "mesecons_detector:node_detector_on"
end minetest.swap_node(pos, node)
mesecon.receptor_on(pos)
end, end,
}) })
minetest.register_abm( minetest.register_abm({
{nodenames = {"mesecons_detector:node_detector_on"}, nodenames = {"mesecons_detector:node_detector_on"},
interval = 1.0, interval = 1,
chance = 1, chance = 1,
action = function(pos, node) action = function(pos, node)
if not node_detector_scan(pos) then if node_detector_scan(pos) then return end
minetest.swap_node(pos, {name = "mesecons_detector:node_detector_off", param2 = node.param2})
mesecon.receptor_off(pos) node.name = "mesecons_detector:node_detector_off"
end minetest.swap_node(pos, node)
mesecon.receptor_off(pos)
end, end,
}) })

View File

@ -20,31 +20,53 @@ local function on_rightclick(pos, dir, check_name, replace, replace_dir, params)
end end
local function meseconify_door(name) local function meseconify_door(name)
if not minetest.registered_items[name] then return end 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_state1 (pos, node) local function toggle_state2 (pos, node)
on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0}) 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
local function toggle_state2 (pos, node)
on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2})
end
minetest.override_item(name.."_b_1", {
mesecons = {effector = {
action_on = toggle_state1,
action_off = toggle_state1,
rules = mesecon.rules.pplate
}},
})
minetest.override_item(name.."_b_2", {
mesecons = {effector = {
action_on = toggle_state2,
action_off = toggle_state2,
rules = mesecon.rules.pplate
}},
})
end end
meseconify_door("doors:door_wood") meseconify_door("doors:door_wood")
@ -67,18 +89,41 @@ local function trapdoor_switch(pos, node)
minetest.get_meta(pos):set_int("state", state == 1 and 0 or 1) minetest.get_meta(pos):set_int("state", state == 1 and 0 or 1)
end end
if minetest.registered_nodes["doors:trapdoor"] then if doors and doors.get then
minetest.override_item("doors:trapdoor", { local override = {
mesecons = {effector = { mesecons = {effector = {
action_on = trapdoor_switch, action_on = function(pos, node)
action_off = trapdoor_switch 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)
else
if minetest.registered_nodes["doors:trapdoor"] then
minetest.override_item("doors:trapdoor", {
mesecons = {effector = {
action_on = trapdoor_switch,
action_off = trapdoor_switch
}},
})
minetest.override_item("doors:trapdoor_open", { minetest.override_item("doors:trapdoor_open", {
mesecons = {effector = { mesecons = {effector = {
action_on = trapdoor_switch, action_on = trapdoor_switch,
action_off = trapdoor_switch action_off = trapdoor_switch
}}, }},
}) })
end
end end

View File

@ -42,33 +42,37 @@ local vertical_updatepos = function (pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if minetest.registered_nodes[node.name] if minetest.registered_nodes[node.name]
and minetest.registered_nodes[node.name].is_vertical_conductor then and minetest.registered_nodes[node.name].is_vertical_conductor then
local node_above = minetest.get_node(mesecon.addPosRule(pos, vertical_rules[1])) local node_above = minetest.get_node(vector.add(pos, vertical_rules[1]))
local node_below = minetest.get_node(mesecon.addPosRule(pos, vertical_rules[2])) local node_below = minetest.get_node(vector.add(pos, vertical_rules[2]))
local namestate = minetest.registered_nodes[node.name].vertical_conductor_state
local above = minetest.registered_nodes[node_above.name] local above = minetest.registered_nodes[node_above.name]
and minetest.registered_nodes[node_above.name].is_vertical_conductor and minetest.registered_nodes[node_above.name].is_vertical_conductor
local below = minetest.registered_nodes[node_below.name] local below = minetest.registered_nodes[node_below.name]
and minetest.registered_nodes[node_below.name].is_vertical_conductor and minetest.registered_nodes[node_below.name].is_vertical_conductor
local basename = "mesecons_extrawires:vertical_" mesecon.on_dignode(pos, node)
-- Always place offstate conductor and let mesecon.on_placenode take care
local newname = "mesecons_extrawires:vertical_"
if above and below then -- above and below: vertical mesecon if above and below then -- above and below: vertical mesecon
minetest.add_node(pos, {name = basename .. namestate}) newname = newname .. "off"
elseif above and not below then -- above only: bottom elseif above and not below then -- above only: bottom
minetest.add_node(pos, {name = basename .. "bottom_" .. namestate}) newname = newname .. "bottom_off"
elseif not above and below then -- below only: top elseif not above and below then -- below only: top
minetest.add_node(pos, {name = basename .. "top_" .. namestate}) newname = newname .. "top_off"
else -- no vertical wire above, no vertical wire below: use bottom else -- no vertical wire above, no vertical wire below: use bottom
minetest.add_node(pos, {name = basename .. "bottom_" .. namestate}) newname = newname .. "bottom_off"
end end
mesecon.update_autoconnect(pos)
minetest.set_node(pos, {name = newname})
mesecon.on_placenode(pos, {name = newname})
end end
end end
local vertical_update = function (pos, node) local vertical_update = function (pos, node)
vertical_updatepos(pos) -- this one vertical_updatepos(pos) -- this one
vertical_updatepos(mesecon.addPosRule(pos, vertical_rules[1])) -- above vertical_updatepos(vector.add(pos, vertical_rules[1])) -- above
vertical_updatepos(mesecon.addPosRule(pos, vertical_rules[2])) -- below vertical_updatepos(vector.add(pos, vertical_rules[2])) -- below
end end
-- Vertical wire -- Vertical wire
@ -87,7 +91,6 @@ mesecon.register_node("mesecons_extrawires:vertical", {
},{ },{
tiles = {"mesecons_wire_off.png"}, tiles = {"mesecons_wire_off.png"},
groups = {dig_immediate=2}, --MFF groups = {dig_immediate=2}, --MFF
vertical_conductor_state = "off",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.off, state = mesecon.state.off,
onstate = "mesecons_extrawires:vertical_on", onstate = "mesecons_extrawires:vertical_on",
@ -96,7 +99,6 @@ mesecon.register_node("mesecons_extrawires:vertical", {
},{ },{
tiles = {"mesecons_wire_on.png"}, tiles = {"mesecons_wire_on.png"},
groups = {dig_immediate=2, not_in_creative_inventory=1}, --MFF groups = {dig_immediate=2, not_in_creative_inventory=1}, --MFF
vertical_conductor_state = "on",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.on, state = mesecon.state.on,
offstate = "mesecons_extrawires:vertical_off", offstate = "mesecons_extrawires:vertical_off",
@ -120,7 +122,6 @@ mesecon.register_node("mesecons_extrawires:vertical_top", {
after_dig_node = vertical_update after_dig_node = vertical_update
},{ },{
tiles = {"mesecons_wire_off.png"}, tiles = {"mesecons_wire_off.png"},
vertical_conductor_state = "off",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.off, state = mesecon.state.off,
onstate = "mesecons_extrawires:vertical_top_on", onstate = "mesecons_extrawires:vertical_top_on",
@ -128,7 +129,6 @@ mesecon.register_node("mesecons_extrawires:vertical_top", {
}} }}
},{ },{
tiles = {"mesecons_wire_on.png"}, tiles = {"mesecons_wire_on.png"},
vertical_conductor_state = "on",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.on, state = mesecon.state.on,
offstate = "mesecons_extrawires:vertical_top_off", offstate = "mesecons_extrawires:vertical_top_off",
@ -152,7 +152,6 @@ mesecon.register_node("mesecons_extrawires:vertical_bottom", {
after_dig_node = vertical_update after_dig_node = vertical_update
},{ },{
tiles = {"mesecons_wire_off.png"}, tiles = {"mesecons_wire_off.png"},
vertical_conductor_state = "off",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.off, state = mesecon.state.off,
onstate = "mesecons_extrawires:vertical_bottom_on", onstate = "mesecons_extrawires:vertical_bottom_on",
@ -160,7 +159,6 @@ mesecon.register_node("mesecons_extrawires:vertical_bottom", {
}} }}
},{ },{
tiles = {"mesecons_wire_on.png"}, tiles = {"mesecons_wire_on.png"},
vertical_conductor_state = "on",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.on, state = mesecon.state.on,
offstate = "mesecons_extrawires:vertical_bottom_off", offstate = "mesecons_extrawires:vertical_bottom_off",

View File

@ -60,7 +60,7 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_off"},
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
local waterpos={x=pos.x, y=pos.y+1, z=pos.z} local waterpos={x=pos.x, y=pos.y+1, z=pos.z}
if minetest.get_node(waterpos).name=="default:water_flowing" or minetest.get_node(waterpos).name == "default:river_water_flowing" then if minetest.get_node(waterpos).name=="default:water_flowing" or minetest.get_node(waterpos).name == "default:river_water_flowing" then
minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"}) minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"})
nodeupdate(pos) nodeupdate(pos)
mesecon.receptor_on(pos) mesecon.receptor_on(pos)
end end
@ -74,7 +74,7 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_on"},
action = function(pos, node, active_object_count, active_object_count_wider) action = function(pos, node, active_object_count, active_object_count_wider)
local waterpos={x=pos.x, y=pos.y+1, z=pos.z} local waterpos={x=pos.x, y=pos.y+1, z=pos.z}
if minetest.get_node(waterpos).name~="default:water_flowing" or minetest.get_node(waterpos).name ~= "default:river_water_flowing" then if minetest.get_node(waterpos).name~="default:water_flowing" or minetest.get_node(waterpos).name ~= "default:river_water_flowing" then
minetest.add_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"}) minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"})
nodeupdate(pos) nodeupdate(pos)
mesecon.receptor_off(pos) mesecon.receptor_off(pos)
end end

View File

@ -15,10 +15,16 @@ end
-- Nodes that cannot be pushed / pulled by movestones, pistons -- Nodes that cannot be pushed / pulled by movestones, pistons
function mesecon.is_mvps_stopper(node, pushdir, stack, stackid) 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] local get_stopper = mesecon.mvps_stoppers[node.name]
if type (get_stopper) == "function" then if type (get_stopper) == "function" then
get_stopper = get_stopper(node, pushdir, stack, stackid) get_stopper = get_stopper(node, pushdir, stack, stackid)
end end
return get_stopper return get_stopper
end end
@ -47,6 +53,17 @@ function mesecon.mvps_process_stack(stack)
end end
end end
-- 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) function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
-- determine the number of nodes to be pushed -- determine the number of nodes to be pushed
local nodes = {} local nodes = {}
@ -56,9 +73,7 @@ function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
local np = frontiers[1] local np = frontiers[1]
local nn = minetest.get_node(np) local nn = minetest.get_node(np)
if nn.name ~= "air" if not node_replaceable(nn.name) then
and minetest.registered_nodes[nn.name]
and minetest.registered_nodes[nn.name].liquidtype == "none" then
table.insert(nodes, {node = nn, pos = np}) table.insert(nodes, {node = nn, pos = np})
if #nodes > maximum then return nil end if #nodes > maximum then return nil end
@ -160,9 +175,9 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
-- add nodes -- add nodes
for _, n in ipairs(nodes) do for _, n in ipairs(nodes) do
local np = mesecon.addPosRule(n.pos, movedir) local np = vector.add(n.pos, movedir)
minetest.add_node(np, n.node) minetest.set_node(np, n.node)
minetest.get_meta(np):from_table(n.meta) minetest.get_meta(np):from_table(n.meta)
end end
@ -171,7 +186,7 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
for i in ipairs(nodes) do for i in ipairs(nodes) do
moved_nodes[i] = {} moved_nodes[i] = {}
moved_nodes[i].oldpos = nodes[i].pos moved_nodes[i].oldpos = nodes[i].pos
nodes[i].pos = mesecon.addPosRule(nodes[i].pos, movedir) nodes[i].pos = vector.add(nodes[i].pos, movedir)
moved_nodes[i].pos = nodes[i].pos moved_nodes[i].pos = nodes[i].pos
moved_nodes[i].node = nodes[i].node moved_nodes[i].node = nodes[i].node
moved_nodes[i].meta = nodes[i].meta moved_nodes[i].meta = nodes[i].meta
@ -192,12 +207,8 @@ end)
function mesecon.mvps_move_objects(pos, dir, nodestack) function mesecon.mvps_move_objects(pos, dir, nodestack)
local objects_to_move = {} local objects_to_move = {}
-- Move object at tip of stack -- Move object at tip of stack, pushpos is position at tip of stack
local pushpos = mesecon.addPosRule(pos, -- get pos at tip of stack local pushpos = vector.add(pos, vector.multiply(dir, #nodestack))
{x = dir.x * #nodestack,
y = dir.y * #nodestack,
z = dir.z * #nodestack})
local objects = minetest.get_objects_inside_radius(pushpos, 1) local objects = minetest.get_objects_inside_radius(pushpos, 1)
for _, obj in ipairs(objects) do for _, obj in ipairs(objects) do
@ -208,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 tonumber(minetest.setting_get("movement_gravity")) > 0 and dir.y == 0 then
-- If gravity positive and dir horizontal, push players standing on the stack -- If gravity positive and dir horizontal, push players standing on the stack
for _, n in ipairs(nodestack) do for _, n in ipairs(nodestack) do
local p_above = mesecon.addPosRule(n.pos, {x=0, y=1, z=0}) local p_above = vector.add(n.pos, {x=0, y=1, z=0})
local objects = minetest.get_objects_inside_radius(p_above, 1) local objects = minetest.get_objects_inside_radius(p_above, 1)
for _, obj in ipairs(objects) do for _, obj in ipairs(objects) do
table.insert(objects_to_move, obj) table.insert(objects_to_move, obj)
@ -219,7 +230,7 @@ function mesecon.mvps_move_objects(pos, dir, nodestack)
for _, obj in ipairs(objects_to_move) do for _, obj in ipairs(objects_to_move) do
local entity = obj:get_luaentity() local entity = obj:get_luaentity()
if not entity or not mesecon.is_mvps_unmov(entity.name) then if not entity or not mesecon.is_mvps_unmov(entity.name) then
local np = mesecon.addPosRule(obj:getpos(), dir) local np = vector.add(obj:getpos(), dir)
--move only if destination is not solid --move only if destination is not solid
local nn = minetest.get_node(np) local nn = minetest.get_node(np)

View File

@ -5,7 +5,7 @@ minetest.register_node("mesecons_noteblock:noteblock", {
on_punch = function(pos, node) -- change sound when punched on_punch = function(pos, node) -- change sound when punched
node.param2 = (node.param2+1)%12 node.param2 = (node.param2+1)%12
mesecon.noteblock_play(pos, node.param2) mesecon.noteblock_play(pos, node.param2)
minetest.add_node(pos, node) minetest.set_node(pos, node)
end, end,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
mesecons = {effector = { -- play sound when activated mesecons = {effector = { -- play sound when activated

View File

@ -57,7 +57,7 @@ end
local piston_remove_pusher = function(pos, node) local piston_remove_pusher = function(pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local dir = piston_get_direction(pistonspec.dir, node) local dir = piston_get_direction(pistonspec.dir, node)
local pusherpos = mesecon.addPosRule(pos, dir) local pusherpos = vector.add(pos, dir)
local pushername = minetest.get_node(pusherpos).name local pushername = minetest.get_node(pusherpos).name
-- make sure there actually is a pusher (for compatibility reasons mainly) -- make sure there actually is a pusher (for compatibility reasons mainly)
@ -78,12 +78,12 @@ local piston_on = function(pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local dir = piston_get_direction(pistonspec.dir, node) local dir = piston_get_direction(pistonspec.dir, node)
local np = mesecon.addPosRule(pos, dir) local np = vector.add(pos, dir)
local maxpush = mesecon.setting("piston_max_push", 15) local maxpush = mesecon.setting("piston_max_push", 15)
local success, stack, oldstack = mesecon.mvps_push(np, dir, maxpush) local success, stack, oldstack = mesecon.mvps_push(np, dir, maxpush)
if success then if success then
minetest.add_node(pos, {param2 = node.param2, name = pistonspec.onname}) minetest.set_node(pos, {param2 = node.param2, name = pistonspec.onname})
minetest.add_node(np, {param2 = node.param2, name = pistonspec.pusher}) minetest.set_node(np, {param2 = node.param2, name = pistonspec.pusher})
minetest.sound_play("piston_extend", { minetest.sound_play("piston_extend", {
pos = pos, pos = pos,
max_hear_distance = 20, max_hear_distance = 20,
@ -96,7 +96,7 @@ end
local piston_off = function(pos, node) local piston_off = function(pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston 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) piston_remove_pusher(pos, node)
if pistonspec.sticky then if pistonspec.sticky then
@ -117,10 +117,16 @@ local piston_orientate = function(pos, placer)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
if pitch > 55 then --looking upwards
minetest.add_node(pos, {name=pistonspec.piston_down}) -- looking upwards (pitch > 55) / looking downwards (pitch < -55)
elseif pitch < -55 then --looking downwards local nn = nil
minetest.add_node(pos, {name=pistonspec.piston_up}) 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
end end
@ -719,12 +725,12 @@ end
local piston_get_stopper = function (node, dir, stack, stackid) local piston_get_stopper = function (node, dir, stack, stackid)
pistonspec = minetest.registered_nodes[node.name].mesecons_piston pistonspec = minetest.registered_nodes[node.name].mesecons_piston
dir = piston_get_direction(pistonspec.dir, node) dir = piston_get_direction(pistonspec.dir, node)
local pusherpos = mesecon.addPosRule(stack[stackid].pos, dir) local pusherpos = vector.add(stack[stackid].pos, dir)
local pushernode = minetest.get_node(pusherpos) local pushernode = minetest.get_node(pusherpos)
if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then
for _, s in ipairs(stack) do for _, s in ipairs(stack) do
if mesecon.cmpPos(s.pos, pusherpos) -- pusher is also to be pushed if vector.equals(s.pos, pusherpos) -- pusher is also to be pushed
and s.node.param2 == node.param2 then and s.node.param2 == node.param2 then
return false return false
end end

View File

@ -17,16 +17,16 @@ pp_on_timer = function (pos, elapsed)
if not basename then return end if not basename then return end
local objs = minetest.get_objects_inside_radius(pos, 1) local objs = minetest.get_objects_inside_radius(pos, 1)
local two_below = mesecon.addPosRule(pos, {x = 0, y = -2, z = 0}) local two_below = vector.add(pos, vector.new(0, -2, 0))
if objs[1] == nil and node.name == basename .. "_on" then if objs[1] == nil and node.name == basename .. "_on" then
minetest.add_node(pos, {name = basename .. "_off"}) minetest.set_node(pos, {name = basename .. "_off"})
mesecon.receptor_off(pos, mesecon.rules.pplate) mesecon.receptor_off(pos, mesecon.rules.pplate)
elseif node.name == basename .. "_off" then elseif node.name == basename .. "_off" then
for k, obj in pairs(objs) do for k, obj in pairs(objs) do
local objpos = obj:getpos() local objpos = obj:getpos()
if objpos.y > pos.y-1 and objpos.y < pos.y then if objpos.y > pos.y-1 and objpos.y < pos.y then
minetest.add_node(pos, {name = basename .. "_on"}) minetest.set_node(pos, {name = basename .. "_on"})
mesecon.receptor_on(pos, mesecon.rules.pplate ) mesecon.receptor_on(pos, mesecon.rules.pplate )
end end
end end

View File

@ -66,10 +66,10 @@ minetest.register_node("mesecons_random:ghoststone_active", {
offstate = "mesecons_random:ghoststone" offstate = "mesecons_random:ghoststone"
}}, }},
on_construct = function(pos) on_construct = function(pos)
--remove shadow -- remove shadow
pos2 = {x = pos.x, y = pos.y + 1, z = pos.z} shadowpos = vector.add(pos, vector.new(0, 1, 0))
if ( minetest.get_node(pos2).name == "air" ) then if (minetest.get_node(shadowpos).name == "air") then
minetest.dig_node(pos2) minetest.dig_node(shadowpos)
end end
end end
}) })

View File

@ -105,10 +105,10 @@ function mesecon.receiver_place(rcpt_pos)
if string.find(nn.name, "mesecons:wire_") ~= nil then if string.find(nn.name, "mesecons:wire_") ~= nil then
minetest.dig_node(pos) minetest.dig_node(pos)
if mesecon.is_power_on(rcpt_pos) then if mesecon.is_power_on(rcpt_pos) then
minetest.add_node(pos, {name = "mesecons_receiver:receiver_on", param2 = node.param2}) minetest.set_node(pos, {name = "mesecons_receiver:receiver_on", param2 = node.param2})
mesecon.receptor_on(pos, receiver_get_rules(node)) mesecon.receptor_on(pos, receiver_get_rules(node))
else else
minetest.add_node(pos, {name = "mesecons_receiver:receiver_off", param2 = node.param2}) minetest.set_node(pos, {name = "mesecons_receiver:receiver_off", param2 = node.param2})
end end
mesecon.update_autoconnect(pos) mesecon.update_autoconnect(pos)
end end
@ -120,7 +120,7 @@ function mesecon.receiver_remove(rcpt_pos, dugnode)
if string.find(nn.name, "mesecons_receiver:receiver_") ~=nil then if string.find(nn.name, "mesecons_receiver:receiver_") ~=nil then
minetest.dig_node(pos) minetest.dig_node(pos)
local node = {name = "mesecons:wire_00000000_off"} local node = {name = "mesecons:wire_00000000_off"}
minetest.add_node(pos, node) minetest.set_node(pos, node)
mesecon.update_autoconnect(pos) mesecon.update_autoconnect(pos)
mesecon.on_placenode(pos, node) mesecon.on_placenode(pos, node)
end end

View File

@ -91,7 +91,7 @@ minetest.register_abm({
action = function(pos, node) action = function(pos, node)
local is_powered = false local is_powered = false
for _, rule in ipairs(torch_get_input_rules(node)) do for _, rule in ipairs(torch_get_input_rules(node)) do
local src = mesecon.addPosRule(pos, rule) local src = vector.add(pos, rule)
if mesecon.is_power_on(src) then if mesecon.is_power_on(src) then
is_powered = true is_powered = true
end end