5 Commits

72 changed files with 700 additions and 1453 deletions

View File

@ -22,7 +22,7 @@ OK, I want in.
-------------- --------------
Go get it! Go get it!
[DOWNLOAD IT NOW](https://github.com/minetest-mods/mesecons/archive/master.zip) [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:
@ -45,7 +45,7 @@ An overview for the very newest of new beginners? How does [this one](http://ube
Want to get more into building? Why not check out the [Mesecons Laboratory](http://uberi.mesecons.net/), a website dedicated to advanced Mesecons builders? Want to get more into building? Why not check out the [Mesecons Laboratory](http://uberi.mesecons.net/), a website dedicated to advanced Mesecons builders?
Want to contribute to Mesecons itself? Check out the [source code](https://github.com/minetest-mods/mesecons)! Want to contribute to Mesecons itself? Check out the [source code](https://github.com/Jeija/minetest-mod-mesecons)!
Who wrote it anyways? Who wrote it anyways?
--------------------- ---------------------

View File

@ -1,12 +0,0 @@
{
"name": "mesecons",
"description": "Mesecons is a mod for Minetest that implements items related to digital circuitry: wires, buttons, lights, and programmable controllers.",
"homepage": "http://mesecons.net",
"authors": "Jeija",
"license": "LGPL-3.0+",
"keywords": [
"mesecons",
"minetest",
"mod"
]
}

View File

@ -1 +1,2 @@
default default
screwdriver?

View File

@ -548,3 +548,52 @@ function mesecon.is_powered(pos, rule)
if (#sourcepos == 0) then return false if (#sourcepos == 0) then return false
else return sourcepos end else return sourcepos end
end end
--Rules rotation Functions:
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,
name = rule.name})
end
return nr
end
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,
name = rule.name})
end
return nr
end
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,
name = rule.name})
end
return nr
end
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,
name = rule.name})
end
return nr
end

View File

@ -12,3 +12,86 @@ for hash, _ in pairs(old_forceloaded_blocks) do
minetest.forceload_free_block(unhash_blockpos(hash)) minetest.forceload_free_block(unhash_blockpos(hash))
end end
os.remove(minetest.get_worldpath()..DIR_DELIM.."mesecon_forceloaded") os.remove(minetest.get_worldpath()..DIR_DELIM.."mesecon_forceloaded")
-- LBMs to convert old pistons to use facedir instead of separate up/down nodes
minetest.register_lbm({
label = "Convert up pistons to use facedir",
name = ":mesecons_pistons:update_up_pistons",
nodenames = {"mesecons_pistons:piston_up_normal_on","mesecons_pistons:piston_up_normal_off",
"mesecons_pistons:piston_up_sticky_on","mesecons_pistons:piston_up_sticky_off"},
action = function(pos, node)
if string.find(node.name, "sticky") then
if string.sub(node.name, -3, -1) == "_on" then
node.name = "mesecons_pistons:piston_sticky_on"
else
node.name = "mesecons_pistons:piston_sticky_off"
end
else
if string.sub(node.name, -3, -1) == "_on" then
node.name = "mesecons_pistons:piston_normal_on"
else
node.name = "mesecons_pistons:piston_normal_off"
end
end
local dir = {x=0, y=-1, z=0}
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.swap_node(pos, node)
end
})
minetest.register_lbm({
label = "Convert down pistons to use facedir",
name = ":mesecons_pistons:update_down_pistons",
nodenames = {"mesecons_pistons:piston_down_normal_on","mesecons_pistons:piston_down_normal_off",
"mesecons_pistons:piston_down_sticky_on","mesecons_pistons:piston_down_sticky_off"},
action = function(pos, node)
if string.find(node.name, "sticky") then
if string.sub(node.name, -3, -1) == "_on" then
node.name = "mesecons_pistons:piston_sticky_on"
else
node.name = "mesecons_pistons:piston_sticky_off"
end
else
if string.sub(node.name, -3, -1) == "_on" then
node.name = "mesecons_pistons:piston_normal_on"
else
node.name = "mesecons_pistons:piston_normal_off"
end
end
local dir = {x=0, y=1, z=0}
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.swap_node(pos, node)
end
})
minetest.register_lbm({
label = "Convert up piston pushers to use facedir",
name = ":mesecons_pistons:update_up_pushers",
nodenames = {"mesecons_pistons:piston_up_pusher_normal", "mesecons_pistons:piston_up_pusher_sticky"},
action = function(pos, node)
if string.find(node.name, "sticky") then
node.name = "mesecons_pistons:piston_pusher_sticky"
else
node.name = "mesecons_pistons:piston_pusher_normal"
end
local dir = {x=0, y=-1, z=0}
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.swap_node(pos, node)
end
})
minetest.register_lbm({
label = "Convert down piston pushers to use facedir",
name = ":mesecons_pistons:update_down_pushers",
nodenames = {"mesecons_pistons:piston_down_pusher_normal", "mesecons_pistons:piston_down_pusher_sticky"},
action = function(pos, node)
if string.find(node.name, "sticky") then
node.name = "mesecons_pistons:piston_pusher_sticky"
else
node.name = "mesecons_pistons:piston_pusher_normal"
end
local dir = {x=0, y=1, z=0}
node.param2 = minetest.dir_to_facedir(dir, true)
minetest.swap_node(pos, node)
end
})

View File

@ -4,7 +4,7 @@ minetest.register_node("mesecons:mesecon_off", {
inventory_image = "jeija_mesecon_off.png", inventory_image = "jeija_mesecon_off.png",
wield_image = "jeija_mesecon_off.png", wield_image = "jeija_mesecon_off.png",
paramtype = "light", paramtype = "light",
is_ground_content = false, is_ground_content = true,
walkable = false, walkable = false,
selection_box = { selection_box = {
type = "fixed", type = "fixed",
@ -22,7 +22,7 @@ minetest.register_node("mesecons:mesecon_on", {
drawtype = "raillike", drawtype = "raillike",
tiles = {"jeija_mesecon_on.png", "jeija_mesecon_curved_on.png", "jeija_mesecon_t_junction_on.png", "jeija_mesecon_crossing_on.png"}, tiles = {"jeija_mesecon_on.png", "jeija_mesecon_curved_on.png", "jeija_mesecon_t_junction_on.png", "jeija_mesecon_crossing_on.png"},
paramtype = "light", paramtype = "light",
is_ground_content = false, is_ground_content = true,
walkable = false, walkable = false,
selection_box = { selection_box = {
type = "fixed", type = "fixed",

View File

@ -1,85 +1,61 @@
mesecon.rules = {} mesecon.rules = {}
mesecon.state = {} mesecon.state = {}
mesecon.rules.default = { mesecon.rules.default =
{x = 0, y = 0, z = -1}, {{x=0, y=0, z=-1},
{x = 1, y = 0, z = 0}, {x=1, y=0, z=0},
{x = -1, y = 0, z = 0}, {x=-1, y=0, z=0},
{x = 0, y = 0, z = 1}, {x=0, y=0, z=1},
{x = 1, y = 1, z = 0}, {x=1, y=1, z=0},
{x = 1, y = -1, z = 0}, {x=1, y=-1, z=0},
{x = -1, y = 1, z = 0}, {x=-1, y=1, z=0},
{x = -1, y = -1, z = 0}, {x=-1, y=-1, z=0},
{x = 0, y = 1, z = 1}, {x=0, y=1, z=1},
{x = 0, y = -1, z = 1}, {x=0, y=-1, z=1},
{x = 0, y = 1, z = -1}, {x=0, y=1, z=-1},
{x = 0, y = -1, z = -1}, {x=0, y=-1, z=-1}}
}
mesecon.rules.floor = mesecon.mergetable(mesecon.rules.default, {{x = 0, y = -1, z = 0}}) mesecon.rules.pplate = mesecon.mergetable(mesecon.rules.default, {{x=0, y=-2, z=0}})
mesecon.rules.pplate = mesecon.mergetable(mesecon.rules.floor, {{x = 0, y = -2, z = 0}}) mesecon.rules.buttonlike =
{{x = 1, y = 0, z = 0},
{x = 1, y = 1, z = 0},
{x = 1, y =-1, z = 0},
{x = 1, y =-1, z = 1},
{x = 1, y =-1, z =-1},
{x = 2, y = 0, z = 0}}
mesecon.rules.buttonlike = { mesecon.rules.flat =
{x = 1, y = 0, z = 0}, {{x = 1, y = 0, z = 0},
{x = 1, y = 1, z = 0}, {x =-1, y = 0, z = 0},
{x = 1, y = -1, z = 0}, {x = 0, y = 0, z = 1},
{x = 1, y = -1, z = 1}, {x = 0, y = 0, z =-1}}
{x = 1, y = -1, z = -1},
{x = 2, y = 0, z = 0},
}
mesecon.rules.flat = { mesecon.rules.alldirs =
{x = 1, y = 0, z = 0}, {{x= 1, y= 0, z= 0},
{x = -1, y = 0, z = 0}, {x=-1, y= 0, z= 0},
{x = 0, y = 0, z = 1}, {x= 0, y= 1, z= 0},
{x = 0, y = 0, z = -1}, {x= 0, y=-1, z= 0},
} {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},
}
local rules_wallmounted = {
xp = mesecon.rotate_rules_down(mesecon.rules.floor),
xn = mesecon.rotate_rules_up(mesecon.rules.floor),
yp = mesecon.rotate_rules_up(mesecon.rotate_rules_up(mesecon.rules.floor)),
yn = mesecon.rules.floor,
zp = mesecon.rotate_rules_left(mesecon.rotate_rules_up(mesecon.rules.floor)),
zn = mesecon.rotate_rules_right(mesecon.rotate_rules_up(mesecon.rules.floor)),
}
local rules_buttonlike = {
xp = mesecon.rules.buttonlike,
xn = mesecon.rotate_rules_right(mesecon.rotate_rules_right(mesecon.rules.buttonlike)),
yp = mesecon.rotate_rules_down(mesecon.rules.buttonlike),
yn = mesecon.rotate_rules_up(mesecon.rules.buttonlike),
zp = mesecon.rotate_rules_right(mesecon.rules.buttonlike),
zn = mesecon.rotate_rules_left(mesecon.rules.buttonlike),
}
local function rules_from_dir(ruleset, dir)
if dir.x == 1 then return ruleset.xp end
if dir.y == 1 then return ruleset.yp end
if dir.z == 1 then return ruleset.zp end
if dir.x == -1 then return ruleset.xn end
if dir.y == -1 then return ruleset.yn end
if dir.z == -1 then return ruleset.zn end
end
mesecon.rules.wallmounted_get = function(node)
local dir = minetest.wallmounted_to_dir(node.param2)
return rules_from_dir(rules_wallmounted, dir)
end
mesecon.rules.buttonlike_get = function(node) mesecon.rules.buttonlike_get = function(node)
local rules = mesecon.rules.buttonlike
local dir = minetest.facedir_to_dir(node.param2) local dir = minetest.facedir_to_dir(node.param2)
return rules_from_dir(rules_buttonlike, dir) if dir.x == 1 then
-- No action needed
elseif dir.z == -1 then
rules=mesecon.rotate_rules_left(rules)
elseif dir.x == -1 then
rules=mesecon.rotate_rules_right(mesecon.rotate_rules_right(rules))
elseif dir.z == 1 then
rules=mesecon.rotate_rules_right(rules)
elseif dir.y == -1 then
rules=mesecon.rotate_rules_up(rules)
elseif dir.y == 1 then
rules=mesecon.rotate_rules_down(rules)
end
return rules
end end
mesecon.state.on = "on" mesecon.state.on = "on"

View File

@ -21,8 +21,7 @@ mesecon.on_placenode = function(pos, node)
end end
--mesecon.receptor_on (pos, mesecon.conductor_get_rules(node)) --mesecon.receptor_on (pos, mesecon.conductor_get_rules(node))
elseif mesecon.is_conductor_on(node) then elseif mesecon.is_conductor_on(node) then
node.name = mesecon.get_conductor_off(node) minetest.swap_node(pos, {name = mesecon.get_conductor_off(node)})
minetest.swap_node(pos, node)
end end
end end
@ -63,74 +62,42 @@ mesecon.on_dignode = function(pos, node)
mesecon.execute_autoconnect_hooks_queue(pos, node) mesecon.execute_autoconnect_hooks_queue(pos, node)
end end
function mesecon.on_blastnode(pos, intensity)
local node = minetest.get_node(pos)
minetest.remove_node(pos)
mesecon.on_dignode(pos, node)
return minetest.get_node_drops(node.name, "")
end
minetest.register_on_placenode(mesecon.on_placenode) minetest.register_on_placenode(mesecon.on_placenode)
minetest.register_on_dignode(mesecon.on_dignode) minetest.register_on_dignode(mesecon.on_dignode)
-- Overheating service for fast circuits -- Overheating service for fast circuits
local OVERHEAT_MAX = mesecon.setting("overheat_max", 20)
local COOLDOWN_TIME = mesecon.setting("cooldown_time", 2.0)
local COOLDOWN_STEP = mesecon.setting("cooldown_granularity", 0.5)
local COOLDOWN_MULTIPLIER = OVERHEAT_MAX / COOLDOWN_TIME
local cooldown_timer = 0.0
local object_heat = {}
-- returns true if heat is too high -- returns true if heat is too high
function mesecon.do_overheat(pos) mesecon.do_overheat = function(pos)
local id = minetest.hash_node_position(pos) local meta = minetest.get_meta(pos)
local heat = (object_heat[id] or 0) + 1 local heat = meta:get_int("heat") or 0
object_heat[id] = heat
if heat >= OVERHEAT_MAX then heat = heat + 1
minetest.log("action", "Node overheats at " .. minetest.pos_to_string(pos)) meta:set_int("heat", heat)
object_heat[id] = nil
if heat < mesecon.setting("overheat_max", 20) then
mesecon.queue:add_action(pos, "cooldown", {}, 1, nil, 0)
else
return true return true
end end
return false return false
end end
function mesecon.do_cooldown(pos)
local id = minetest.hash_node_position(pos)
object_heat[id] = nil
end
function mesecon.get_heat(pos) mesecon.queue:add_function("cooldown", function (pos)
local id = minetest.hash_node_position(pos) local meta = minetest.get_meta(pos)
return object_heat[id] or 0 local heat = meta:get_int("heat")
end
function mesecon.move_hot_nodes(moved_nodes) if (heat > 0) then
local new_heat = {} meta:set_int("heat", heat - 1)
for _, n in ipairs(moved_nodes) do
local old_id = minetest.hash_node_position(n.oldpos)
local new_id = minetest.hash_node_position(n.pos)
new_heat[new_id] = object_heat[old_id]
object_heat[old_id] = nil
end end
for id, heat in pairs(new_heat) do end)
object_heat[id] = heat
end
end
local function global_cooldown(dtime) -- "Shim" for simple rotation, will result in the following item in nodedefs using it:
cooldown_timer = cooldown_timer + dtime -- "on_rotate = screwdriver.rotate_simple" if screwdriver mod is installed
if cooldown_timer < COOLDOWN_STEP then -- "on_rotate = nil" (essentially not present) if screwdriver mod is missing
return -- don't overload the CPU
end if screwdriver then
local cooldown = COOLDOWN_MULTIPLIER * cooldown_timer mesecon.rotate_simple = screwdriver.rotate_simple
cooldown_timer = 0
for id, heat in pairs(object_heat) do
heat = heat - cooldown
if heat <= 0 then
object_heat[id] = nil -- free some RAM
else
object_heat[id] = heat
end
end
end end
minetest.register_globalstep(global_cooldown)

View File

@ -1,15 +1,15 @@
-- SETTINGS -- SETTINGS
function mesecon.setting(setting, default) function mesecon.setting(setting, default)
if type(default) == "boolean" then if type(default) == "boolean" then
local read = minetest.settings:get_bool("mesecon."..setting) local read = minetest.setting_getbool("mesecon."..setting)
if read == nil then if read == nil then
return default return default
else else
return read return read
end end
elseif type(default) == "string" then elseif type(default) == "string" then
return minetest.settings:get("mesecon."..setting) or default return minetest.setting_get("mesecon."..setting) or default
elseif type(default) == "number" then elseif type(default) == "number" then
return tonumber(minetest.settings:get("mesecon."..setting) or default) return tonumber(minetest.setting_get("mesecon."..setting) or default)
end end
end end

View File

@ -6,56 +6,6 @@ function mesecon.move_node(pos, newpos)
minetest.get_meta(pos):from_table(meta) minetest.get_meta(pos):from_table(meta)
end end
-- Rules rotation Functions:
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,
name = rule.name})
end
return nr
end
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,
name = rule.name})
end
return nr
end
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,
name = rule.name})
end
return nr
end
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,
name = rule.name})
end
return nr
end
--
function mesecon.flattenrules(allrules) function mesecon.flattenrules(allrules)
--[[ --[[
{ {
@ -228,7 +178,6 @@ end
function mesecon.register_node(name, spec_common, spec_off, spec_on) function mesecon.register_node(name, spec_common, spec_off, spec_on)
spec_common.drop = spec_common.drop or name .. "_off" spec_common.drop = spec_common.drop or name .. "_off"
spec_common.on_blast = spec_common.on_blast or mesecon.on_blastnode
spec_common.__mesecon_basename = name spec_common.__mesecon_basename = name
spec_on.__mesecon_state = "on" spec_on.__mesecon_state = "on"
spec_off.__mesecon_state = "off" spec_off.__mesecon_state = "off"

View File

@ -24,7 +24,6 @@ mesecon.register_node("mesecons_blinkyplant:blinky_plant", {
drawtype = "plantlike", drawtype = "plantlike",
inventory_image = "jeija_blinky_plant_off.png", inventory_image = "jeija_blinky_plant_off.png",
paramtype = "light", paramtype = "light",
is_ground_content = false,
walkable = false, walkable = false,
sounds = default.node_sound_leaves_defaults(), sounds = default.node_sound_leaves_defaults(),
selection_box = { selection_box = {

View File

@ -4,13 +4,12 @@
mesecon.button_turnoff = function (pos) mesecon.button_turnoff = function (pos)
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if node.name ~= "mesecons_button:button_on" then -- has been dug if node.name=="mesecons_button:button_on" then --has not been dug
return minetest.swap_node(pos, {name = "mesecons_button:button_off", param2=node.param2})
minetest.sound_play("mesecons_button_pop", {pos=pos})
local rules = mesecon.rules.buttonlike_get(node)
mesecon.receptor_off(pos, rules)
end end
minetest.swap_node(pos, {name = "mesecons_button:button_off", param2 = node.param2})
minetest.sound_play("mesecons_button_pop", {pos = pos})
local rules = mesecon.rules.buttonlike_get(node)
mesecon.receptor_off(pos, rules)
end end
minetest.register_node("mesecons_button:button_off", { minetest.register_node("mesecons_button:button_off", {
@ -25,7 +24,6 @@ minetest.register_node("mesecons_button:button_off", {
}, },
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
legacy_wallmounted = true, legacy_wallmounted = true,
walkable = false, walkable = false,
on_rotate = mesecon.buttonlike_onrotate, on_rotate = mesecon.buttonlike_onrotate,
@ -47,14 +45,13 @@ minetest.register_node("mesecons_button:button_off", {
minetest.swap_node(pos, {name = "mesecons_button:button_on", param2=node.param2}) minetest.swap_node(pos, {name = "mesecons_button:button_on", param2=node.param2})
mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node)) mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node))
minetest.sound_play("mesecons_button_push", {pos=pos}) minetest.sound_play("mesecons_button_push", {pos=pos})
minetest.get_node_timer(pos):start(1) minetest.after(1, mesecon.button_turnoff, pos)
end, end,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.off, state = mesecon.state.off,
rules = mesecon.rules.buttonlike_get rules = mesecon.rules.buttonlike_get
}}, }}
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_button:button_on", { minetest.register_node("mesecons_button:button_on", {
@ -69,7 +66,6 @@ minetest.register_node("mesecons_button:button_on", {
}, },
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
legacy_wallmounted = true, legacy_wallmounted = true,
walkable = false, walkable = false,
on_rotate = false, on_rotate = false,
@ -93,9 +89,7 @@ minetest.register_node("mesecons_button:button_on", {
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.on, state = mesecon.state.on,
rules = mesecon.rules.buttonlike_get rules = mesecon.rules.buttonlike_get
}}, }}
on_timer = mesecon.button_turnoff,
on_blast = mesecon.on_blastnode,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -181,7 +181,6 @@ minetest.register_node("mesecons_commandblock:commandblock_off", {
description = "Command Block", description = "Command Block",
tiles = {"jeija_commandblock_off.png"}, tiles = {"jeija_commandblock_off.png"},
inventory_image = minetest.inventorycube("jeija_commandblock_off.png"), inventory_image = minetest.inventorycube("jeija_commandblock_off.png"),
is_ground_content = false,
groups = {cracky=2, mesecon_effector_off=1}, groups = {cracky=2, mesecon_effector_off=1},
on_construct = construct, on_construct = construct,
after_place_node = after_place, after_place_node = after_place,
@ -190,13 +189,11 @@ minetest.register_node("mesecons_commandblock:commandblock_off", {
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_on = commandblock_action_on action_on = commandblock_action_on
}}, }}
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_commandblock:commandblock_on", { minetest.register_node("mesecons_commandblock:commandblock_on", {
tiles = {"jeija_commandblock_on.png"}, tiles = {"jeija_commandblock_on.png"},
is_ground_content = false,
groups = {cracky=2, mesecon_effector_on=1, not_in_creative_inventory=1}, groups = {cracky=2, mesecon_effector_on=1, not_in_creative_inventory=1},
light_source = 10, light_source = 10,
drop = "mesecons_commandblock:commandblock_off", drop = "mesecons_commandblock:commandblock_off",
@ -207,6 +204,5 @@ minetest.register_node("mesecons_commandblock:commandblock_on", {
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_off = commandblock_action_off action_off = commandblock_action_off
}}, }}
on_blast = mesecon.on_blastnode,
}) })

View File

@ -87,7 +87,7 @@ minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
sunlight_propagates = true, sunlight_propagates = true,
is_ground_content = false, is_ground_content = true,
drop = 'mesecons_delayer:delayer_off_1', drop = 'mesecons_delayer:delayer_off_1',
on_punch = function (pos, node) on_punch = function (pos, node)
if node.name=="mesecons_delayer:delayer_off_1" then if node.name=="mesecons_delayer:delayer_off_1" then
@ -114,8 +114,7 @@ minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), {
rules = delayer_get_input_rules, rules = delayer_get_input_rules,
action_on = delayer_activate action_on = delayer_activate
} }
}, }
on_blast = mesecon.on_blastnode,
}) })
@ -143,7 +142,7 @@ minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
sunlight_propagates = true, sunlight_propagates = true,
is_ground_content = false, is_ground_content = true,
drop = 'mesecons_delayer:delayer_off_1', drop = 'mesecons_delayer:delayer_off_1',
on_punch = function (pos, node) on_punch = function (pos, node)
if node.name=="mesecons_delayer:delayer_on_1" then if node.name=="mesecons_delayer:delayer_on_1" then
@ -158,7 +157,6 @@ minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
end, end,
delayer_time = delaytime, delayer_time = delaytime,
delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i), delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i),
sounds = default.node_sound_stone_defaults(),
mesecons = { mesecons = {
receptor = receptor =
{ {
@ -170,8 +168,7 @@ minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
rules = delayer_get_input_rules, rules = delayer_get_input_rules,
action_off = delayer_deactivate action_off = delayer_deactivate
} }
}, }
on_blast = mesecon.on_blastnode,
}) })
end end

View File

@ -4,4 +4,3 @@ It can also receive digiline signals. You can either send "GET" and it will
respond with the detected nodename or you can send any other string and it will respond with the detected nodename or you can send any other string and it will
set this string as the node to scan for. set this string as the node to scan for.
Nodenames must include the mod they reside in, so for instance default:dirt, not just dirt. Nodenames must include the mod they reside in, so for instance default:dirt, not just dirt.
The distance parameter specifies how many blocks are between the node detector and the node to detect.

View File

@ -1,4 +1,3 @@
The object detector is a receptor. It changes its state when a player approaches. The object detector is a receptor. It changes its state when a player approaches.
Right-click it to set a name to scan for. Right-click it to set a name to scan for.
You can also search for comma-separated lists of players where the detector gets activated if any of the names in the list are found.
It can also receive digiline signals which are the name to scan for on the specified channel in the right-click menu. It can also receive digiline signals which are the name to scan for on the specified channel in the right-click menu.

View File

@ -5,18 +5,15 @@ local GET_COMMAND = "GET"
-- The radius can be specified in mesecons/settings.lua -- The radius can be specified in mesecons/settings.lua
local function object_detector_make_formspec(pos) local function object_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 player to scan for (empty for any):;${scanname}]".. "field[0.3, 0;9,2;scanname;Name of player to scan for (empty for any):;${scanname}]"..
"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]".. "field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
"button_exit[7,0.75;2,3;;Save]") "button_exit[7,0.75;2,3;;Save]")
end end
local function object_detector_on_receive_fields(pos, formname, fields, sender) local function object_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
if minetest.is_protected(pos, sender:get_player_name()) then return end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("scanname", fields.scanname) meta:set_string("scanname", fields.scanname)
meta:set_string("digiline_channel", fields.digiline_channel) meta:set_string("digiline_channel", fields.digiline_channel)
@ -31,17 +28,14 @@ local function object_detector_scan(pos)
if next(objs) == nil then return false end if next(objs) == nil then return false end
local scanname = minetest.get_meta(pos):get_string("scanname") local scanname = minetest.get_meta(pos):get_string("scanname")
local scan_for = {}
for _, str in pairs(string.split(scanname:gsub(" ", ""), ",")) do
scan_for[str] = true
end
local every_player = scanname == "" local every_player = scanname == ""
for _, obj in pairs(objs) do for _, obj in pairs(objs) do
-- "" is returned if it is not a player; "" ~= nil; so only handle objects with foundname ~= "" -- "" is returned if it is not a player; "" ~= nil; so only handle objects with foundname ~= ""
local foundname = obj:get_player_name() local foundname = obj:get_player_name()
if foundname ~= "" then if foundname ~= "" then
if every_player or scan_for[foundname] then -- return true if scanning for any player or if specific playername was detected
if scanname == "" or foundname == scanname then
return true return true
end end
end end
@ -66,7 +60,6 @@ local object_detector_digiline = {
minetest.register_node("mesecons_detector:object_detector_off", { minetest.register_node("mesecons_detector:object_detector_off", {
tiles = {"default_steel_block.png", "default_steel_block.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png"}, tiles = {"default_steel_block.png", "default_steel_block.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png", "jeija_object_detector_off.png"},
paramtype = "light", paramtype = "light",
is_ground_content = false,
walkable = true, walkable = true,
groups = {cracky=3}, groups = {cracky=3},
description="Player Detector", description="Player Detector",
@ -77,14 +70,12 @@ minetest.register_node("mesecons_detector:object_detector_off", {
on_construct = object_detector_make_formspec, on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields, on_receive_fields = object_detector_on_receive_fields,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
digiline = object_detector_digiline, digiline = object_detector_digiline
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_detector:object_detector_on", { minetest.register_node("mesecons_detector:object_detector_on", {
tiles = {"default_steel_block.png", "default_steel_block.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png"}, tiles = {"default_steel_block.png", "default_steel_block.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png", "jeija_object_detector_on.png"},
paramtype = "light", paramtype = "light",
is_ground_content = false,
walkable = true, walkable = true,
groups = {cracky=3,not_in_creative_inventory=1}, groups = {cracky=3,not_in_creative_inventory=1},
drop = 'mesecons_detector:object_detector_off', drop = 'mesecons_detector:object_detector_off',
@ -95,8 +86,7 @@ minetest.register_node("mesecons_detector:object_detector_on", {
on_construct = object_detector_make_formspec, on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields, on_receive_fields = object_detector_on_receive_fields,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
digiline = object_detector_digiline, digiline = object_detector_digiline
on_blast = mesecon.on_blastnode,
}) })
minetest.register_craft({ minetest.register_craft({
@ -108,15 +98,6 @@ minetest.register_craft({
} }
}) })
minetest.register_craft({
output = 'mesecons_detector:object_detector_off',
recipe = {
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
{"default:steel_ingot", "mesecons_microcontroller:microcontroller0000", "default:steel_ingot"},
{"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
}
})
minetest.register_abm({ minetest.register_abm({
nodenames = {"mesecons_detector:object_detector_off"}, nodenames = {"mesecons_detector:object_detector_off"},
interval = 1, interval = 1,
@ -147,23 +128,17 @@ minetest.register_abm({
-- Detects the node in front of it -- Detects the node in front of it
local function node_detector_make_formspec(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]" ..
if meta:get_string("distance") == "" then meta:set_string("distance", "0") end
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;2.5,2;distance;Distance (0-"..mesecon.setting("node_detector_distance_max", 10).."):;${distance}]".. "field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
"field[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 function node_detector_on_receive_fields(pos, fieldname, fields, sender) 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
if minetest.is_protected(pos, sender:get_player_name()) then return end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
meta:set_string("scanname", fields.scanname) meta:set_string("scanname", fields.scanname)
meta:set_string("distance", fields.distance or "0")
meta:set_string("digiline_channel", fields.digiline_channel) meta:set_string("digiline_channel", fields.digiline_channel)
node_detector_make_formspec(pos) node_detector_make_formspec(pos)
end end
@ -173,17 +148,10 @@ local function node_detector_scan(pos)
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 meta = minetest.get_meta(pos)
local distance = meta:get_int("distance")
local distance_max = mesecon.setting("node_detector_distance_max", 10)
if distance < 0 then distance = 0 end
if distance > distance_max then distance = distance_max end
local frontname = minetest.get_node( local frontname = minetest.get_node(
vector.subtract(pos, vector.multiply(minetest.facedir_to_dir(node.param2), distance + 1)) vector.subtract(pos, minetest.facedir_to_dir(node.param2))
).name ).name
local scanname = meta:get_string("scanname") local scanname = minetest.get_meta(pos):get_string("scanname")
return (frontname == scanname) or return (frontname == scanname) or
(frontname ~= "air" and frontname ~= "ignore" and scanname == "") (frontname ~= "air" and frontname ~= "ignore" and scanname == "")
@ -194,17 +162,11 @@ 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 distance = meta:get_int("distance")
local distance_max = mesecon.setting("node_detector_distance_max", 10)
if distance < 0 then distance = 0 end
if distance > distance_max then distance = distance_max end
if channel ~= meta:get_string("digiline_channel") then return end if channel ~= meta:get_string("digiline_channel") then return end
if msg == GET_COMMAND then if msg == GET_COMMAND then
local nodename = minetest.get_node( local nodename = minetest.get_node(
vector.subtract(pos, vector.multiply(minetest.facedir_to_dir(node.param2), distance + 1)) vector.subtract(pos, minetest.facedir_to_dir(node.param2))
).name ).name
digiline:receptor_send(pos, digiline.rules.default, channel, nodename) digiline:receptor_send(pos, digiline.rules.default, channel, nodename)
@ -238,7 +200,6 @@ 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",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
walkable = true, walkable = true,
groups = {cracky=3}, groups = {cracky=3},
description="Node Detector", description="Node Detector",
@ -247,16 +208,15 @@ 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 = after_place_node_detector,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
digiline = node_detector_digiline, digiline = node_detector_digiline
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_detector:node_detector_on", { minetest.register_node("mesecons_detector:node_detector_on", {
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_on.png"}, tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_on.png"},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
walkable = true, walkable = true,
groups = {cracky=3,not_in_creative_inventory=1}, groups = {cracky=3,not_in_creative_inventory=1},
drop = 'mesecons_detector:node_detector_off', drop = 'mesecons_detector:node_detector_off',
@ -265,9 +225,9 @@ 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 = after_place_node_detector,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
digiline = node_detector_digiline, digiline = node_detector_digiline
on_blast = mesecon.on_blastnode,
}) })
minetest.register_craft({ minetest.register_craft({
@ -279,15 +239,6 @@ minetest.register_craft({
} }
}) })
minetest.register_craft({
output = 'mesecons_detector:node_detector_off',
recipe = {
{"default:steel_ingot", "group:mesecon_conductor_craftable", "default:steel_ingot"},
{"default:steel_ingot", "mesecons_microcontroller:microcontroller0000", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
}
})
minetest.register_abm({ minetest.register_abm({
nodenames = {"mesecons_detector:node_detector_off"}, nodenames = {"mesecons_detector:node_detector_off"},
interval = 1, interval = 1,

View File

@ -1,5 +1,3 @@
local screwdriver_exists = minetest.global_exists("screwdriver")
local corner_nodebox = { local corner_nodebox = {
type = "fixed", type = "fixed",
fixed = {{ -16/32-0.001, -17/32, -3/32, 0, -13/32, 3/32 }, fixed = {{ -16/32-0.001, -17/32, -3/32, 0, -13/32, 3/32 },
@ -35,22 +33,19 @@ minetest.register_node("mesecons_extrawires:corner_on", {
}, },
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
walkable = false, walkable = false,
sunlight_propagates = true, sunlight_propagates = true,
selection_box = corner_selectionbox, selection_box = corner_selectionbox,
node_box = corner_nodebox, node_box = corner_nodebox,
on_rotate = mesecon.rotate_simple,
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, not_in_creative_inventory = 1},
drop = "mesecons_extrawires:corner_off", drop = "mesecons_extrawires:corner_off",
sounds = default.node_sound_defaults(),
mesecons = {conductor = mesecons = {conductor =
{ {
state = mesecon.state.on, state = mesecon.state.on,
rules = corner_get_rules, rules = corner_get_rules,
offstate = "mesecons_extrawires:corner_off" offstate = "mesecons_extrawires:corner_off"
}}, }}
on_blast = mesecon.on_blastnode,
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
}) })
minetest.register_node("mesecons_extrawires:corner_off", { minetest.register_node("mesecons_extrawires:corner_off", {
@ -66,21 +61,18 @@ minetest.register_node("mesecons_extrawires:corner_off", {
}, },
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
walkable = false, walkable = false,
sunlight_propagates = true, sunlight_propagates = true,
selection_box = corner_selectionbox, selection_box = corner_selectionbox,
node_box = corner_nodebox, node_box = corner_nodebox,
on_rotate = mesecon.rotate_simple,
groups = {dig_immediate = 3}, groups = {dig_immediate = 3},
sounds = default.node_sound_defaults(),
mesecons = {conductor = mesecons = {conductor =
{ {
state = mesecon.state.off, state = mesecon.state.off,
rules = corner_get_rules, rules = corner_get_rules,
onstate = "mesecons_extrawires:corner_on" onstate = "mesecons_extrawires:corner_on"
}}, }}
on_blast = mesecon.on_blastnode,
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -29,19 +29,16 @@ minetest.register_node("mesecons_extrawires:crossover_off", {
"jeija_insulated_wire_ends_off.png" "jeija_insulated_wire_ends_off.png"
}, },
paramtype = "light", paramtype = "light",
is_ground_content = false,
walkable = false, walkable = false,
stack_max = 99, stack_max = 99,
selection_box = {type="fixed", fixed={-16/32-0.0001, -18/32, -16/32-0.001, 16/32+0.001, -5/32, 16/32+0.001}}, selection_box = {type="fixed", fixed={-16/32-0.0001, -18/32, -16/32-0.001, 16/32+0.001, -5/32, 16/32+0.001}},
groups = {dig_immediate=3, mesecon=3}, groups = {dig_immediate=3, mesecon=3},
sounds = default.node_sound_defaults(),
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
rules = crossover_get_rules(), rules = crossover_get_rules(),
} }
}, },
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_extrawires:crossover_01", { minetest.register_node("mesecons_extrawires:crossover_01", {
@ -56,19 +53,16 @@ minetest.register_node("mesecons_extrawires:crossover_01", {
"jeija_insulated_wire_ends_off.png" "jeija_insulated_wire_ends_off.png"
}, },
paramtype = "light", paramtype = "light",
is_ground_content = false,
walkable = false, walkable = false,
stack_max = 99, stack_max = 99,
selection_box = {type="fixed", fixed={-16/32-0.0001, -18/32, -16/32-0.001, 16/32+0.001, -5/32, 16/32+0.001}}, selection_box = {type="fixed", fixed={-16/32-0.0001, -18/32, -16/32-0.001, 16/32+0.001, -5/32, 16/32+0.001}},
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1}, groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1},
sounds = default.node_sound_defaults(),
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
rules = crossover_get_rules(), rules = crossover_get_rules(),
} }
}, },
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_extrawires:crossover_10", { minetest.register_node("mesecons_extrawires:crossover_10", {
@ -83,19 +77,16 @@ minetest.register_node("mesecons_extrawires:crossover_10", {
"jeija_insulated_wire_ends_on.png" "jeija_insulated_wire_ends_on.png"
}, },
paramtype = "light", paramtype = "light",
is_ground_content = false,
walkable = false, walkable = false,
stack_max = 99, stack_max = 99,
selection_box = {type="fixed", fixed={-16/32-0.0001, -18/32, -16/32-0.001, 16/32+0.001, -5/32, 16/32+0.001}}, selection_box = {type="fixed", fixed={-16/32-0.0001, -18/32, -16/32-0.001, 16/32+0.001, -5/32, 16/32+0.001}},
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1}, groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1},
sounds = default.node_sound_defaults(),
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
rules = crossover_get_rules(), rules = crossover_get_rules(),
} }
}, },
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_extrawires:crossover_on", { minetest.register_node("mesecons_extrawires:crossover_on", {
@ -110,19 +101,16 @@ minetest.register_node("mesecons_extrawires:crossover_on", {
"jeija_insulated_wire_ends_on.png" "jeija_insulated_wire_ends_on.png"
}, },
paramtype = "light", paramtype = "light",
is_ground_content = false,
walkable = false, walkable = false,
stack_max = 99, stack_max = 99,
selection_box = {type="fixed", fixed={-16/32-0.0001, -18/32, -16/32-0.001, 16/32+0.001, -5/32, 16/32+0.001}}, selection_box = {type="fixed", fixed={-16/32-0.0001, -18/32, -16/32-0.001, 16/32+0.001, -5/32, 16/32+0.001}},
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1}, groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1},
sounds = default.node_sound_defaults(),
mesecons = { mesecons = {
conductor = { conductor = {
states = crossover_states, states = crossover_states,
rules = crossover_get_rules(), rules = crossover_get_rules(),
} }
}, },
on_blast = mesecon.on_blastnode,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -1,3 +1,2 @@
default default
mesecons mesecons
screwdriver?

View File

@ -26,8 +26,7 @@ local powered_def = mesecon.mergetable(minetest.registered_nodes["default:mese"]
offstate = "default:mese", offstate = "default:mese",
rules = mesewire_rules rules = mesewire_rules
}}, }},
groups = {cracky = 1, not_in_creative_inventory = 1}, groups = {cracky = 1, not_in_creative_inventory = 1}
on_blast = mesecon.on_blastnode,
}) })
for i, v in pairs(powered_def.tiles) do for i, v in pairs(powered_def.tiles) do

View File

@ -1,5 +1,3 @@
local screwdriver_exists = minetest.global_exists("screwdriver")
local tjunction_nodebox = { local tjunction_nodebox = {
type = "fixed", type = "fixed",
fixed = {{ -16/32-0.001, -17/32, -3/32, 16/32+0.001, -13/32, 3/32 }, fixed = {{ -16/32-0.001, -17/32, -3/32, 16/32+0.001, -13/32, 3/32 },
@ -36,22 +34,19 @@ minetest.register_node("mesecons_extrawires:tjunction_on", {
}, },
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
walkable = false, walkable = false,
sunlight_propagates = true, sunlight_propagates = true,
selection_box = tjunction_selectionbox, selection_box = tjunction_selectionbox,
node_box = tjunction_nodebox, node_box = tjunction_nodebox,
on_rotate = mesecon.rotate_simple,
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, not_in_creative_inventory = 1},
drop = "mesecons_extrawires:tjunction_off", drop = "mesecons_extrawires:tjunction_off",
sounds = default.node_sound_defaults(),
mesecons = {conductor = mesecons = {conductor =
{ {
state = mesecon.state.on, state = mesecon.state.on,
rules = tjunction_get_rules, rules = tjunction_get_rules,
offstate = "mesecons_extrawires:tjunction_off" offstate = "mesecons_extrawires:tjunction_off"
}}, }}
on_blast = mesecon.on_blastnode,
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
}) })
minetest.register_node("mesecons_extrawires:tjunction_off", { minetest.register_node("mesecons_extrawires:tjunction_off", {
@ -67,21 +62,18 @@ minetest.register_node("mesecons_extrawires:tjunction_off", {
}, },
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
walkable = false, walkable = false,
sunlight_propagates = true, sunlight_propagates = true,
selection_box = tjunction_selectionbox, selection_box = tjunction_selectionbox,
node_box = tjunction_nodebox, node_box = tjunction_nodebox,
on_rotate = mesecon.rotate_simple,
groups = {dig_immediate = 3}, groups = {dig_immediate = 3},
sounds = default.node_sound_defaults(),
mesecons = {conductor = mesecons = {conductor =
{ {
state = mesecon.state.off, state = mesecon.state.off,
rules = tjunction_get_rules, rules = tjunction_get_rules,
onstate = "mesecons_extrawires:tjunction_on" onstate = "mesecons_extrawires:tjunction_on"
}}, }}
on_blast = mesecon.on_blastnode,
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -77,19 +77,18 @@ end
-- Vertical wire -- Vertical wire
mesecon.register_node("mesecons_extrawires:vertical", { mesecon.register_node("mesecons_extrawires:vertical", {
description = "Vertical Mesecon", description = "Vertical mesecon",
drawtype = "nodebox", drawtype = "nodebox",
walkable = false, walkable = false,
paramtype = "light", paramtype = "light",
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
selection_box = vertical_box, selection_box = vertical_box,
node_box = vertical_box, node_box = vertical_box,
on_rotate = false,
is_vertical_conductor = true, is_vertical_conductor = true,
drop = "mesecons_extrawires:vertical_off", drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update, after_place_node = vertical_update,
after_dig_node = vertical_update, after_dig_node = vertical_update
sounds = default.node_sound_defaults(),
},{ },{
tiles = {"mesecons_wire_off.png"}, tiles = {"mesecons_wire_off.png"},
groups = {dig_immediate=3}, groups = {dig_immediate=3},
@ -114,16 +113,15 @@ mesecon.register_node("mesecons_extrawires:vertical_top", {
drawtype = "nodebox", drawtype = "nodebox",
walkable = false, walkable = false,
paramtype = "light", paramtype = "light",
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
groups = {dig_immediate=3, not_in_creative_inventory=1}, groups = {dig_immediate=3, not_in_creative_inventory=1},
selection_box = top_box, selection_box = top_box,
node_box = top_box, node_box = top_box,
on_rotate = false,
is_vertical_conductor = true, is_vertical_conductor = true,
drop = "mesecons_extrawires:vertical_off", drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update, after_place_node = vertical_update,
after_dig_node = vertical_update, after_dig_node = vertical_update
sounds = default.node_sound_defaults(),
},{ },{
tiles = {"mesecons_wire_off.png"}, tiles = {"mesecons_wire_off.png"},
mesecons = {conductor = { mesecons = {conductor = {
@ -146,16 +144,15 @@ mesecon.register_node("mesecons_extrawires:vertical_bottom", {
drawtype = "nodebox", drawtype = "nodebox",
walkable = false, walkable = false,
paramtype = "light", paramtype = "light",
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, not_in_creative_inventory = 1},
selection_box = bottom_box, selection_box = bottom_box,
node_box = bottom_box, node_box = bottom_box,
on_rotate = false,
is_vertical_conductor = true, is_vertical_conductor = true,
drop = "mesecons_extrawires:vertical_off", drop = "mesecons_extrawires:vertical_off",
after_place_node = vertical_update, after_place_node = vertical_update,
after_dig_node = vertical_update, after_dig_node = vertical_update
sounds = default.node_sound_defaults(),
},{ },{
tiles = {"mesecons_wire_off.png"}, tiles = {"mesecons_wire_off.png"},
mesecons = {conductor = { mesecons = {conductor = {

View File

@ -1,2 +1 @@
mesecons mesecons
screwdriver?

View File

@ -69,11 +69,10 @@ plg.register_nodes({
"jeija_fpga_sides.png" "jeija_fpga_sides.png"
}, },
inventory_image = "", -- replaced later inventory_image = "", -- replaced later
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
walkable = true, walkable = true,
groups = {dig_immediate = 2, mesecon = 3, overheat = 1}, groups = {dig_immediate = 2, mesecon = 3},
drop = "mesecons_fpga:fpga0000", drop = "mesecons_fpga:fpga0000",
selection_box = { selection_box = {
type = "fixed", type = "fixed",
@ -117,45 +116,6 @@ plg.register_nodes({
after_dig_node = function(pos, node) after_dig_node = function(pos, node)
mesecon.receptor_off(pos, plg.rules[node.name]) mesecon.receptor_off(pos, plg.rules[node.name])
end, end,
on_blast = mesecon.on_blastnode,
on_rotate = function(pos, node, user, mode)
local abcd1 = {"A", "B", "C", "D"}
local abcd2 = {A = 1, B = 2, C = 3, D = 4}
local ops = {"op1", "op2", "dst"}
local dir = 0
if mode == screwdriver.ROTATE_FACE then -- clock-wise
dir = 1
if user and user:is_player() then
minetest.chat_send_player(user:get_player_name(),
"FPGA ports have been rotated clockwise.")
end
elseif mode == screwdriver.ROTATE_AXIS then -- counter-clockwise
dir = -1
if user and user:is_player() then
minetest.chat_send_player(user:get_player_name(),
"FPGA ports have been rotated counter-clockwise.")
end
end
local meta = minetest.get_meta(pos)
local instr = lcore.deserialize(meta:get_string("instr"))
for i = 1, #instr do
for _, op in ipairs(ops) do
local o = instr[i][op]
if o and o.type == "io" then
local num = abcd2[o.port]
num = num + dir
if num > 4 then num = 1
elseif num < 1 then num = 4 end
instr[i][op].port = abcd1[num]
end
end
end
meta:set_string("instr", lcore.serialize(instr))
plg.update_formspec(pos, instr)
return true
end,
}) })
@ -310,11 +270,6 @@ plg.update = function(pos)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if meta:get_int("valid") ~= 1 then if meta:get_int("valid") ~= 1 then
return return
elseif mesecon.do_overheat(pos) then
plg.setports(pos, false, false, false, false)
meta:set_int("valid", 0)
meta:set_string("infotext", "FPGA (overheated)")
return
end end
local is = lcore.deserialize(meta:get_string("instr")) local is = lcore.deserialize(meta:get_string("instr"))

View File

@ -1 +1 @@
AND gates power their output if both inputs (from left and right) are powered. And gates power their output if both inputs (from left and right) are powered.

View File

@ -1 +1 @@
Diodes conduct signals in one direction only. Mesecon diodes, just like real ones, only transfer power (signals) in one direction only.

View File

@ -1 +1 @@
NAND gates do not power their output if both inputs (from left and right) are powered, but power it in every other case. Nand gates do not power their output if both inputs (from left and right) are powered, but power it in every other case.

View File

@ -1 +1 @@
NOR gates only power their output if none of their two inputs is powered. They are basically OR gates with a NOT gate at their output. Nor gates only power their output if none of their two inputs is powered. They are basically or gates with a not gate at their output.

View File

@ -1 +1 @@
NOT gates invert signals, just like a mesecon torch does, but faster. The input is at the opposite side of the output. Not gates invert signals, just like a mesecon torch does, but faster. The input is at the opposite side of the output.

View File

@ -1 +1 @@
OR gates power their output if either of their inputs (or both) are powered. You could basically get the same behaviour with two diodes, but OR gates save some space. Or gates power their output if either of their inputs (or both) are powered. You could basically get the same behaviour with two diodes, but or gates save some space.

View File

@ -54,10 +54,10 @@ local function update_gate(pos, node, link, newstate)
end end
end end
local function register_gate(name, inputnumber, assess, recipe, description) local function register_gate(name, inputnumber, assess, recipe)
local get_inputrules = inputnumber == 2 and gate_get_input_rules_twoinputs or local get_inputrules = inputnumber == 2 and gate_get_input_rules_twoinputs or
gate_get_input_rules_oneinput gate_get_input_rules_oneinput
description = "Logic Gate: "..name local description = "Mesecons Logic Gate: "..name
local basename = "mesecons_gates:"..name local basename = "mesecons_gates:"..name
mesecon.register_node(basename, { mesecon.register_node(basename, {
@ -65,7 +65,6 @@ local function register_gate(name, inputnumber, assess, recipe, description)
inventory_image = "jeija_gate_off.png^jeija_gate_"..name..".png", inventory_image = "jeija_gate_off.png^jeija_gate_"..name..".png",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
drawtype = "nodebox", drawtype = "nodebox",
drop = basename.."_off", drop = basename.."_off",
selection_box = nodebox, selection_box = nodebox,
@ -75,8 +74,7 @@ local function register_gate(name, inputnumber, assess, recipe, description)
assess = assess, assess = assess,
onstate = basename.."_on", onstate = basename.."_on",
offstate = basename.."_off", offstate = basename.."_off",
inputnumber = inputnumber, inputnumber = inputnumber
after_dig_node = mesecon.do_cooldown,
},{ },{
tiles = {"jeija_microcontroller_bottom.png^".."jeija_gate_off.png^".. tiles = {"jeija_microcontroller_bottom.png^".."jeija_gate_off.png^"..
"jeija_gate_"..name..".png"}, "jeija_gate_"..name..".png"},
@ -105,39 +103,32 @@ local function register_gate(name, inputnumber, assess, recipe, description)
end end
register_gate("diode", 1, function (input) return input end, register_gate("diode", 1, function (input) return input end,
{{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons_torch:mesecon_torch_on"}}, {{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons_torch:mesecon_torch_on"}})
"Diode")
register_gate("not", 1, function (input) return not input end, register_gate("not", 1, function (input) return not input end,
{{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons:mesecon"}}, {{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons:mesecon"}})
"NOT Gate")
register_gate("and", 2, function (val1, val2) return val1 and val2 end, register_gate("and", 2, function (val1, val2) return val1 and val2 end,
{{"mesecons:mesecon", "", ""}, {{"mesecons:mesecon", "", ""},
{"", "mesecons_materials:silicon", "mesecons:mesecon"}, {"", "mesecons_materials:silicon", "mesecons:mesecon"},
{"mesecons:mesecon", "", ""}}, {"mesecons:mesecon", "", ""}})
"AND Gate")
register_gate("nand", 2, function (val1, val2) return not (val1 and val2) end, register_gate("nand", 2, function (val1, val2) return not (val1 and val2) end,
{{"mesecons:mesecon", "", ""}, {{"mesecons:mesecon", "", ""},
{"", "mesecons_materials:silicon", "mesecons_torch:mesecon_torch_on"}, {"", "mesecons_materials:silicon", "mesecons_torch:mesecon_torch_on"},
{"mesecons:mesecon", "", ""}}, {"mesecons:mesecon", "", ""}})
"NAND Gate")
register_gate("xor", 2, function (val1, val2) return (val1 or val2) and not (val1 and val2) end, register_gate("xor", 2, function (val1, val2) return (val1 or val2) and not (val1 and val2) end,
{{"mesecons:mesecon", "", ""}, {{"mesecons:mesecon", "", ""},
{"", "mesecons_materials:silicon", "mesecons_materials:silicon"}, {"", "mesecons_materials:silicon", "mesecons_materials:silicon"},
{"mesecons:mesecon", "", ""}}, {"mesecons:mesecon", "", ""}})
"XOR Gate")
register_gate("nor", 2, function (val1, val2) return not (val1 or val2) end, register_gate("nor", 2, function (val1, val2) return not (val1 or val2) end,
{{"mesecons:mesecon", "", ""}, {{"mesecons:mesecon", "", ""},
{"", "mesecons:mesecon", "mesecons_torch:mesecon_torch_on"}, {"", "mesecons:mesecon", "mesecons_torch:mesecon_torch_on"},
{"mesecons:mesecon", "", ""}}, {"mesecons:mesecon", "", ""}})
"NOR Gate")
register_gate("or", 2, function (val1, val2) return (val1 or val2) end, register_gate("or", 2, function (val1, val2) return (val1 or val2) end,
{{"mesecons:mesecon", "", ""}, {{"mesecons:mesecon", "", ""},
{"", "mesecons:mesecon", "mesecons:mesecon"}, {"", "mesecons:mesecon", "mesecons:mesecon"},
{"mesecons:mesecon", "", ""}}, {"mesecons:mesecon", "", ""}})
"OR Gate")

View File

@ -13,7 +13,6 @@ minetest.register_node("mesecons_hydroturbine:hydro_turbine_off", {
"jeija_hydro_turbine_turbine_misc_off.png" "jeija_hydro_turbine_turbine_misc_off.png"
}, },
inventory_image = "jeija_hydro_turbine_inv.png", inventory_image = "jeija_hydro_turbine_inv.png",
is_ground_content = false,
wield_scale = {x=0.75, y=0.75, z=0.75}, wield_scale = {x=0.75, y=0.75, z=0.75},
groups = {dig_immediate=2}, groups = {dig_immediate=2},
description="Water Turbine", description="Water Turbine",
@ -22,16 +21,14 @@ minetest.register_node("mesecons_hydroturbine:hydro_turbine_off", {
type = "fixed", type = "fixed",
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 }, fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 },
}, },
sounds = default.node_sound_metal_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.off state = mesecon.state.off
}}, }}
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_hydroturbine:hydro_turbine_on", { minetest.register_node("mesecons_hydroturbine:hydro_turbine_on", {
drawtype = "mesh", drawtype = "mesh",
is_ground_content = false,
mesh = "jeija_hydro_turbine_on.obj", mesh = "jeija_hydro_turbine_on.obj",
wield_scale = {x=0.75, y=0.75, z=0.75}, wield_scale = {x=0.75, y=0.75, z=0.75},
tiles = { tiles = {
@ -51,11 +48,10 @@ minetest.register_node("mesecons_hydroturbine:hydro_turbine_on", {
type = "fixed", type = "fixed",
fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 }, fixed = { -0.5, -0.5, -0.5, 0.5, 1.5, 0.5 },
}, },
sounds = default.node_sound_metal_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.on state = mesecon.state.on
}}, }}
on_blast = mesecon.on_blastnode,
}) })
@ -74,6 +70,7 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_off"},
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 is_flowing_water(waterpos) then if is_flowing_water(waterpos) then
minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"}) minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"})
nodeupdate(pos)
mesecon.receptor_on(pos) mesecon.receptor_on(pos)
end end
end, end,
@ -87,6 +84,7 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_on"},
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 not is_flowing_water(waterpos) then if not is_flowing_water(waterpos) then
minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"}) minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"})
nodeupdate(pos)
mesecon.receptor_off(pos) mesecon.receptor_off(pos)
end end
end, end,

View File

@ -1,2 +1 @@
mesecons mesecons
screwdriver?

View File

@ -1,5 +1,3 @@
local screwdriver_exists = minetest.global_exists("screwdriver")
local function insulated_wire_get_rules(node) local function insulated_wire_get_rules(node)
local rules = {{x = 1, y = 0, z = 0}, local rules = {{x = 1, y = 0, z = 0},
{x =-1, y = 0, z = 0}} {x =-1, y = 0, z = 0}}
@ -11,7 +9,7 @@ end
minetest.register_node("mesecons_insulated:insulated_on", { minetest.register_node("mesecons_insulated:insulated_on", {
drawtype = "nodebox", drawtype = "nodebox",
description = "Straight Insulated Mesecon", description = "Insulated Mesecon",
tiles = { tiles = {
"jeija_insulated_wire_sides_on.png", "jeija_insulated_wire_sides_on.png",
"jeija_insulated_wire_sides_on.png", "jeija_insulated_wire_sides_on.png",
@ -22,7 +20,6 @@ minetest.register_node("mesecons_insulated:insulated_on", {
}, },
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
walkable = false, walkable = false,
sunlight_propagates = true, sunlight_propagates = true,
selection_box = { selection_box = {
@ -33,21 +30,19 @@ minetest.register_node("mesecons_insulated:insulated_on", {
type = "fixed", type = "fixed",
fixed = { -16/32-0.001, -17/32, -3/32, 16/32+0.001, -13/32, 3/32 } fixed = { -16/32-0.001, -17/32, -3/32, 16/32+0.001, -13/32, 3/32 }
}, },
on_rotate = mesecon.rotate_simple,
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, not_in_creative_inventory = 1},
drop = "mesecons_insulated:insulated_off", drop = "mesecons_insulated:insulated_off",
sounds = default.node_sound_defaults(),
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.on, state = mesecon.state.on,
offstate = "mesecons_insulated:insulated_off", offstate = "mesecons_insulated:insulated_off",
rules = insulated_wire_get_rules rules = insulated_wire_get_rules
}}, }}
on_blast = mesecon.on_blastnode,
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
}) })
minetest.register_node("mesecons_insulated:insulated_off", { minetest.register_node("mesecons_insulated:insulated_off", {
drawtype = "nodebox", drawtype = "nodebox",
description = "Straight Insulated Mesecon", description = "Insulated Mesecon",
tiles = { tiles = {
"jeija_insulated_wire_sides_off.png", "jeija_insulated_wire_sides_off.png",
"jeija_insulated_wire_sides_off.png", "jeija_insulated_wire_sides_off.png",
@ -58,7 +53,6 @@ minetest.register_node("mesecons_insulated:insulated_off", {
}, },
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
walkable = false, walkable = false,
sunlight_propagates = true, sunlight_propagates = true,
selection_box = { selection_box = {
@ -69,15 +63,13 @@ minetest.register_node("mesecons_insulated:insulated_off", {
type = "fixed", type = "fixed",
fixed = { -16/32-0.001, -17/32, -3/32, 16/32+0.001, -13/32, 3/32 } fixed = { -16/32-0.001, -17/32, -3/32, 16/32+0.001, -13/32, 3/32 }
}, },
on_rotate = screwdriver.rotate_simple,
groups = {dig_immediate = 3}, groups = {dig_immediate = 3},
sounds = default.node_sound_defaults(),
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.off, state = mesecon.state.off,
onstate = "mesecons_insulated:insulated_on", onstate = "mesecons_insulated:insulated_on",
rules = insulated_wire_get_rules rules = insulated_wire_get_rules
}}, }}
on_blast = mesecon.on_blastnode,
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -1 +1 @@
Mesecon lamps are effectors that if powered emit light. Lamps are effectors that if powered emit light.

View File

@ -14,23 +14,20 @@ minetest.register_node("mesecons_lamp:lamp_on", {
tiles = {"jeija_meselamp_on.png"}, tiles = {"jeija_meselamp_on.png"},
paramtype = "light", paramtype = "light",
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
is_ground_content = false,
legacy_wallmounted = true, legacy_wallmounted = true,
sunlight_propagates = true, sunlight_propagates = true,
walkable = true, walkable = true,
light_source = minetest.LIGHT_MAX, light_source = default.LIGHT_MAX,
node_box = mesecon_lamp_box, node_box = mesecon_lamp_box,
selection_box = mesecon_lamp_box, selection_box = mesecon_lamp_box,
groups = {dig_immediate = 3,not_in_creative_inventory = 1, mesecon_effector_on = 1}, groups = {dig_immediate=3,not_in_creative_inventory=1, mesecon_effector_on = 1},
drop = "mesecons_lamp:lamp_off 1", drop="mesecons_lamp:lamp_off 1",
sounds = default.node_sound_glass_defaults(), sounds = default.node_sound_glass_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_off = function (pos, node) action_off = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_lamp:lamp_off", param2 = node.param2}) minetest.swap_node(pos, {name = "mesecons_lamp:lamp_off", param2 = node.param2})
end, end
rules = mesecon.rules.wallmounted_get, }}
}},
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_lamp:lamp_off", { minetest.register_node("mesecons_lamp:lamp_off", {
@ -40,21 +37,18 @@ minetest.register_node("mesecons_lamp:lamp_off", {
wield_image = "jeija_meselamp.png", wield_image = "jeija_meselamp.png",
paramtype = "light", paramtype = "light",
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
walkable = true, walkable = true,
node_box = mesecon_lamp_box, node_box = mesecon_lamp_box,
selection_box = mesecon_lamp_box, selection_box = mesecon_lamp_box,
groups = {dig_immediate=3, mesecon_receptor_off = 1, mesecon_effector_off = 1}, groups = {dig_immediate=3, mesecon_receptor_off = 1, mesecon_effector_off = 1},
description = "Mesecon Lamp", description="Meselamp",
sounds = default.node_sound_glass_defaults(), sounds = default.node_sound_glass_defaults(),
mesecons = {effector = { mesecons = {effector = {
action_on = function (pos, node) action_on = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_lamp:lamp_on", param2 = node.param2}) minetest.swap_node(pos, {name = "mesecons_lamp:lamp_on", param2 = node.param2})
end, end
rules = mesecon.rules.wallmounted_get, }}
}},
on_blast = mesecon.on_blastnode,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -14,38 +14,31 @@ local lightstone_rules = {
{x=0, y=-1, z=0}, {x=0, y=-1, z=0},
} }
function mesecon.lightstone_add(name, base_item, texture_off, texture_on, desc) function mesecon.lightstone_add(name, base_item, texture_off, texture_on)
if not desc then
desc = name .. " Lightstone"
end
minetest.register_node("mesecons_lightstone:lightstone_" .. name .. "_off", { minetest.register_node("mesecons_lightstone:lightstone_" .. name .. "_off", {
tiles = {texture_off}, tiles = {texture_off},
is_ground_content = false, groups = {cracky=2, mesecon_effector_off = 1, mesecon = 2},
groups = {cracky = 2, mesecon_effector_off = 1, mesecon = 2}, description=name.." Lightstone",
description = desc,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {effector = { mesecons = {effector = {
rules = lightstone_rules, rules = lightstone_rules,
action_on = function (pos, node) action_on = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_lightstone:lightstone_" .. name .. "_on", param2 = node.param2}) minetest.swap_node(pos, {name = "mesecons_lightstone:lightstone_" .. name .. "_on", param2 = node.param2})
end, end,
}}, }}
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_lightstone:lightstone_" .. name .. "_on", { minetest.register_node("mesecons_lightstone:lightstone_" .. name .. "_on", {
tiles = {texture_on}, tiles = {texture_on},
is_ground_content = false, groups = {cracky=2,not_in_creative_inventory=1, mesecon = 2},
groups = {cracky = 2, not_in_creative_inventory = 1, mesecon = 2}, drop = "mesecons_lightstone:lightstone_" .. name .. "_off",
drop = "mesecons_lightstone:lightstone_" .. name .. "_off", light_source = default.LIGHT_MAX-2,
light_source = minetest.LIGHT_MAX - 2, sounds = default.node_sound_stone_defaults(),
sounds = default.node_sound_stone_defaults(), mesecons = {effector = {
mesecons = {effector = { rules = lightstone_rules,
rules = lightstone_rules, action_off = function (pos, node)
action_off = function (pos, node) minetest.swap_node(pos, {name = "mesecons_lightstone:lightstone_" .. name .. "_off", param2 = node.param2})
minetest.swap_node(pos, {name = "mesecons_lightstone:lightstone_" .. name .. "_off", param2 = node.param2}) end,
end, }}
}},
on_blast = mesecon.on_blastnode,
}) })
minetest.register_craft({ minetest.register_craft({
@ -59,15 +52,9 @@ function mesecon.lightstone_add(name, base_item, texture_off, texture_on, desc)
end end
mesecon.lightstone_add("red", "dye:red", "jeija_lightstone_red_off.png", "jeija_lightstone_red_on.png", "Red Lightstone") mesecon.lightstone_add("red", "dye:red", "jeija_lightstone_red_off.png", "jeija_lightstone_red_on.png")
mesecon.lightstone_add("green", "dye:green", "jeija_lightstone_green_off.png", "jeija_lightstone_green_on.png", "Green Lightstone") mesecon.lightstone_add("green", "dye:green", "jeija_lightstone_green_off.png", "jeija_lightstone_green_on.png")
mesecon.lightstone_add("blue", "dye:blue", "jeija_lightstone_blue_off.png", "jeija_lightstone_blue_on.png", "Blue Lightstone") mesecon.lightstone_add("blue", "dye:blue", "jeija_lightstone_blue_off.png", "jeija_lightstone_blue_on.png")
mesecon.lightstone_add("gray", "dye:grey", "jeija_lightstone_gray_off.png", "jeija_lightstone_gray_on.png", "Grey Lightstone") mesecon.lightstone_add("gray", "dye:grey", "jeija_lightstone_gray_off.png", "jeija_lightstone_gray_on.png")
mesecon.lightstone_add("darkgray", "dye:dark_grey", "jeija_lightstone_darkgray_off.png", "jeija_lightstone_darkgray_on.png", "Dark Grey Lightstone") mesecon.lightstone_add("darkgray", "dye:dark_grey", "jeija_lightstone_darkgray_off.png", "jeija_lightstone_darkgray_on.png")
mesecon.lightstone_add("yellow", "dye:yellow", "jeija_lightstone_yellow_off.png", "jeija_lightstone_yellow_on.png", "Yellow Lightstone") mesecon.lightstone_add("yellow", "dye:yellow", "jeija_lightstone_yellow_off.png", "jeija_lightstone_yellow_on.png")
mesecon.lightstone_add("orange", "dye:orange", "jeija_lightstone_orange_off.png", "jeija_lightstone_orange_on.png", "Orange Lightstone")
mesecon.lightstone_add("white", "dye:white", "jeija_lightstone_white_off.png", "jeija_lightstone_white_on.png", "White Lightstone")
mesecon.lightstone_add("pink", "dye:pink", "jeija_lightstone_pink_off.png", "jeija_lightstone_pink_on.png", "Pink Lightstone")
mesecon.lightstone_add("magenta", "dye:magenta", "jeija_lightstone_magenta_off.png", "jeija_lightstone_magenta_on.png", "Magenta Lightstone")
mesecon.lightstone_add("cyan", "dye:cyan", "jeija_lightstone_cyan_off.png", "jeija_lightstone_cyan_on.png", "Cyan Lightstone")
mesecon.lightstone_add("violet", "dye:violet", "jeija_lightstone_violet_off.png", "jeija_lightstone_violet_on.png", "Violet Lightstone")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 357 B

View File

@ -1,5 +1,5 @@
The Luacontroller is an advanced programmable component. The luacontroller is an advanced programmable component.
You can simply code it in the language Mesecons uses itself: Lua! You can simply code it in the language mesecons uses itself: Lua!
All the code runs in a sandbox, so it's completely safe (but I won't guarantee that for absolute certainty!). All the code runs in a sandbox, so it's completely safe (but I won't guarantee that for absolute certainty!).
<a href="http://mesecons.net/luacontroller/">Documentation is available here!</a> <a href="http://mesecons.net/luacontroller/">Documentation is available here!</a>

View File

@ -12,11 +12,9 @@
-- ports = get_real_port_states(pos): gets if inputs are powered from outside -- ports = get_real_port_states(pos): gets if inputs are powered from outside
-- newport = merge_port_states(state1, state2): just does result = state1 or state2 for every port -- newport = merge_port_states(state1, state2): just does result = state1 or state2 for every port
-- set_port(pos, rule, state): activates/deactivates the mesecons according to the port states -- set_port(pos, rule, state): activates/deactivates the mesecons according to the port states
-- set_port_states(pos, ports): Applies new port states to a Luacontroller at pos -- set_port_states(pos, ports): Applies new port states to a LuaController at pos
-- run_inner(pos, code, event): runs code on the controller at pos and event -- run(pos): runs the code in the controller at pos
-- reset_formspec(pos, code, errmsg): installs new code and prints error messages, without resetting LCID -- reset_meta(pos, code, errmsg): performs a software-reset, installs new code and prints error messages
-- reset_meta(pos, code, errmsg): performs a software-reset, installs new code and prints error message
-- run(pos, event): a wrapper for run_inner which gets code & handles errors via reset_meta
-- resetn(pos): performs a hardware reset, turns off all ports -- resetn(pos): performs a hardware reset, turns off all ports
-- --
-- The Sandbox -- The Sandbox
@ -143,7 +141,7 @@ local function set_port_states(pos, ports)
-- Solution / Workaround: -- Solution / Workaround:
-- Remember which output was turned off and ignore next "off" event. -- Remember which output was turned off and ignore next "off" event.
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
local ign = minetest.deserialize(meta:get_string("ignore_offevents"), true) or {} local ign = minetest.deserialize(meta:get_string("ignore_offevents")) or {}
if ports.a and not vports.a and not mesecon.is_powered(pos, rules.a) then ign.A = true end if ports.a and not vports.a and not mesecon.is_powered(pos, rules.a) then ign.A = true end
if ports.b and not vports.b and not mesecon.is_powered(pos, rules.b) then ign.B = true end if ports.b and not vports.b and not mesecon.is_powered(pos, rules.b) then ign.B = true end
if ports.c and not vports.c and not mesecon.is_powered(pos, rules.c) then ign.C = true end if ports.c and not vports.c and not mesecon.is_powered(pos, rules.c) then ign.C = true end
@ -185,7 +183,7 @@ end
local function ignore_event(event, meta) local function ignore_event(event, meta)
if event.type ~= "off" then return false end if event.type ~= "off" then return false end
local ignore_offevents = minetest.deserialize(meta:get_string("ignore_offevents"), true) or {} local ignore_offevents = minetest.deserialize(meta:get_string("ignore_offevents")) or {}
if ignore_offevents[event.pin.name] then if ignore_offevents[event.pin.name] then
ignore_offevents[event.pin.name] = nil ignore_offevents[event.pin.name] = nil
meta:set_string("ignore_offevents", minetest.serialize(ignore_offevents)) meta:set_string("ignore_offevents", minetest.serialize(ignore_offevents))
@ -198,11 +196,7 @@ end
------------------------- -------------------------
local function safe_print(param) local function safe_print(param)
local string_meta = getmetatable("")
local sandbox = string_meta.__index
string_meta.__index = string -- Leave string sandbox temporarily
print(dump(param)) print(dump(param))
string_meta.__index = sandbox -- Restore string sandbox
end end
local function safe_date() local function safe_date()
@ -225,7 +219,7 @@ end
local function safe_string_find(...) local function safe_string_find(...)
if (select(4, ...)) ~= true then if (select(4, ...)) ~= true then
debug.sethook() -- Clear hook debug.sethook() -- Clear hook
error("string.find: 'plain' (fourth parameter) must always be true in a Luacontroller") error("string.find: 'plain' (fourth parameter) must always be true in a LuaController")
end end
return string.find(...) return string.find(...)
@ -238,11 +232,10 @@ local function remove_functions(x)
end end
-- Make sure to not serialize the same table multiple times, otherwise -- Make sure to not serialize the same table multiple times, otherwise
-- writing mem.test = mem in the Luacontroller will lead to infinite recursion -- writing mem.test = mem in the LuaController will lead to infinite recursion
local seen = {} local seen = {}
local function rfuncs(x) local function rfuncs(x)
if x == nil then return end
if seen[x] then return end if seen[x] then return end
seen[x] = true seen[x] = true
if type(x) ~= "table" then return end if type(x) ~= "table" then return end
@ -266,149 +259,37 @@ local function remove_functions(x)
return x return x
end end
-- itbl: Flat table of functions to run after sandbox cleanup, used to prevent various security hazards local function get_interrupt(pos)
local function get_interrupt(pos, itbl, send_warning)
-- iid = interrupt id -- iid = interrupt id
local function interrupt(time, iid) local function interrupt(time, iid)
-- NOTE: This runs within string metatable sandbox, so don't *rely* on anything of the form (""):y
-- Hence the values get moved out. Should take less time than original, so totally compatible
if type(time) ~= "number" then return end if type(time) ~= "number" then return end
table.insert(itbl, function () local luac_id = minetest.get_meta(pos):get_int("luac_id")
-- Outside string metatable sandbox, can safely run this now mesecon.queue:add_action(pos, "lc_interrupt", {luac_id, iid}, time, iid, 1)
local luac_id = minetest.get_meta(pos):get_int("luac_id")
-- Check if IID is dodgy, so you can't use interrupts to store an infinite amount of data.
-- Note that this is safe from alter-after-free because this code gets run after the sandbox has ended.
-- This runs outside of the timer and *shouldn't* harm perf. unless dodgy data is being sent in the first place
iid = remove_functions(iid)
local msg_ser = minetest.serialize(iid)
if #msg_ser <= mesecon.setting("luacontroller_interruptid_maxlen", 256) then
mesecon.queue:add_action(pos, "lc_interrupt", {luac_id, iid}, time, iid, 1)
else
send_warning("An interrupt ID was too large!")
end
end)
end end
return interrupt return interrupt
end end
-- Given a message object passed to digiline_send, clean it up into a form local function get_digiline_send(pos)
-- which is safe to transmit over the network and compute its "cost" (a very if not digiline then return end
-- rough estimate of its memory usage).
--
-- The cleaning comprises the following:
-- 1. Functions (and userdata, though user scripts ought not to get hold of
-- those in the first place) are removed, because they break the model of
-- Digilines as a network that carries basic data, and they could exfiltrate
-- references to mutable objects from one Luacontroller to another, allowing
-- inappropriate high-bandwidth, no-wires communication.
-- 2. Tables are duplicated because, being mutable, they could otherwise be
-- modified after the send is complete in order to change what data arrives
-- at the recipient, perhaps in violation of the previous cleaning rule or
-- in violation of the message size limit.
--
-- The cost indication is only approximate; its not a perfect measurement of
-- the number of bytes of memory used by the message object.
--
-- Parameters:
-- msg -- the message to clean
-- back_references -- for internal use only; do not provide
--
-- Returns:
-- 1. The cleaned object.
-- 2. The approximate cost of the object.
local function clean_and_weigh_digiline_message(msg, back_references)
local t = type(msg)
if t == "string" then
-- Strings are immutable so can be passed by reference, and cost their
-- length plus the size of the Lua object header (24 bytes on a 64-bit
-- platform) plus one byte for the NUL terminator.
return msg, #msg + 25
elseif t == "number" then
-- Numbers are passed by value so need not be touched, and cost 8 bytes
-- as all numbers in Lua are doubles.
return msg, 8
elseif t == "boolean" then
-- Booleans are passed by value so need not be touched, and cost 1
-- byte.
return msg, 1
elseif t == "table" then
-- Tables are duplicated. Check if this table has been seen before
-- (self-referential or shared table); if so, reuse the cleaned value
-- of the previous occurrence, maintaining table topology and avoiding
-- infinite recursion, and charge zero bytes for this as the object has
-- already been counted.
back_references = back_references or {}
local bref = back_references[msg]
if bref then
return bref, 0
end
-- Construct a new table by cleaning all the keys and values and adding
-- up their costs, plus 8 bytes as a rough estimate of table overhead.
local cost = 8
local ret = {}
back_references[msg] = ret
for k, v in pairs(msg) do
local k_cost, v_cost
k, k_cost = clean_and_weigh_digiline_message(k, back_references)
v, v_cost = clean_and_weigh_digiline_message(v, back_references)
if k ~= nil and v ~= nil then
-- Only include an element if its key and value are of legal
-- types.
ret[k] = v
end
-- If we only counted the cost of a table element when we actually
-- used it, we would be vulnerable to the following attack:
-- 1. Construct a huge table (too large to pass the cost limit).
-- 2. Insert it somewhere in a table, with a function as a key.
-- 3. Insert it somewhere in another table, with a number as a key.
-- 4. The first occurrence doesnt pay the cost because functions
-- are stripped and therefore the element is dropped.
-- 5. The second occurrence doesnt pay the cost because its in
-- back_references.
-- By counting the costs regardless of whether the objects will be
-- included, we avoid this attack; it may overestimate the cost of
-- some messages, but only those that wont be delivered intact
-- anyway because they contain illegal object types.
cost = cost + k_cost + v_cost
end
return ret, cost
else
return nil, 0
end
end
-- itbl: Flat table of functions to run after sandbox cleanup, used to prevent various security hazards
local function get_digiline_send(pos, itbl, send_warning)
if not minetest.global_exists("digilines") then return end
local chan_maxlen = mesecon.setting("luacontroller_digiline_channel_maxlen", 256)
local maxlen = mesecon.setting("luacontroller_digiline_maxlen", 50000)
return function(channel, msg) return function(channel, msg)
-- NOTE: This runs within string metatable sandbox, so don't *rely* on anything of the form (""):y
-- or via anything that could.
-- Make sure channel is string, number or boolean -- Make sure channel is string, number or boolean
if type(channel) == "string" then if (type(channel) ~= "string" and type(channel) ~= "number" and type(channel) ~= "boolean") then
if #channel > chan_maxlen then
send_warning("Channel string too long.")
return false
end
elseif (type(channel) ~= "string" and type(channel) ~= "number" and type(channel) ~= "boolean") then
send_warning("Channel must be string, number or boolean.")
return false return false
end end
local msg_cost -- It is technically possible to send functions over the wire since
msg, msg_cost = clean_and_weigh_digiline_message(msg) -- the high performance impact of stripping those from the data has
if msg == nil or msg_cost > maxlen then -- been decided to not be worth the added realism.
send_warning("Message was too complex, or contained invalid data.") -- Make sure serialized version of the data is not insanely long to
-- prevent DoS-like attacks
local msg_ser = minetest.serialize(msg)
if #msg_ser > mesecon.setting("luacontroller_digiline_maxlen", 50000) then
return false return false
end end
table.insert(itbl, function () minetest.after(0, function()
-- Runs outside of string metatable sandbox digiline:receptor_send(pos, digiline.rules.default, channel, msg)
local luac_id = minetest.get_meta(pos):get_int("luac_id")
mesecon.queue:add_action(pos, "lc_digiline_relay", {channel, luac_id, msg})
end) end)
return true return true
end end
@ -416,30 +297,29 @@ end
local safe_globals = { local safe_globals = {
-- Don't add pcall/xpcall unless willing to deal with the consequences (unless very careful, incredibly likely to allow killing server indirectly)
"assert", "error", "ipairs", "next", "pairs", "select", "assert", "error", "ipairs", "next", "pairs", "select",
"tonumber", "tostring", "type", "unpack", "_VERSION" "tonumber", "tostring", "type", "unpack", "_VERSION"
} }
local function create_environment(pos, mem, event, itbl, send_warning) local function create_environment(pos, mem, event)
-- Gather variables for the environment -- Gather variables for the environment
local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates
local vports_copy = {} local vports_copy = {}
for k, v in pairs(vports) do vports_copy[k] = v end for k, v in pairs(vports) do vports_copy[k] = v end
local rports = get_real_port_states(pos) local rports = get_real_port_states(pos)
-- Create new library tables on each call to prevent one Luacontroller -- Create new library tables on each call to prevent one LuaController
-- from breaking a library and messing up other Luacontrollers. -- from breaking a library and messing up other LuaControllers.
local env = { local env = {
pin = merge_port_states(vports, rports), pin = merge_port_states(vports, rports),
port = vports_copy, port = vports_copy,
event = event, event = event,
mem = mem, mem = mem,
heat = mesecon.get_heat(pos), heat = minetest.get_meta(pos):get_int("heat"),
heat_max = mesecon.setting("overheat_max", 20), heat_max = mesecon.setting("overheat_max", 20),
print = safe_print, print = safe_print,
interrupt = get_interrupt(pos, itbl, send_warning), interrupt = get_interrupt(pos),
digiline_send = get_digiline_send(pos, itbl, send_warning), digiline_send = get_digiline_send(pos),
string = { string = {
byte = string.byte, byte = string.byte,
char = string.char, char = string.char,
@ -527,11 +407,10 @@ local function create_sandbox(code, env)
jit.off(f, true) jit.off(f, true)
end end
local maxevents = mesecon.setting("luacontroller_maxevents", 10000)
return function(...) return function(...)
-- NOTE: This runs within string metatable sandbox, so the setting's been moved out for safety
-- Use instruction counter to stop execution -- Use instruction counter to stop execution
-- after luacontroller_maxevents -- after luacontroller_maxevents
local maxevents = mesecon.setting("luacontroller_maxevents", 10000)
debug.sethook(timeout, "", maxevents) debug.sethook(timeout, "", maxevents)
local ok, ret = pcall(f, ...) local ok, ret = pcall(f, ...)
debug.sethook() -- Clear hook debug.sethook() -- Clear hook
@ -542,7 +421,7 @@ end
local function load_memory(meta) local function load_memory(meta)
return minetest.deserialize(meta:get_string("lc_memory"), true) or {} return minetest.deserialize(meta:get_string("lc_memory")) or {}
end end
@ -559,42 +438,26 @@ local function save_memory(pos, meta, mem)
end end
end end
-- Returns success (boolean), errmsg (string)
-- run (as opposed to run_inner) is responsible for setting up meta according to this output local function run(pos, event)
local function run_inner(pos, code, event)
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
-- Note: These return success, presumably to avoid changing LC ID. if overheat(pos) then return end
if overheat(pos) then return true, "" end if ignore_event(event, meta) then return end
if ignore_event(event, meta) then return true, "" end
-- Load code & mem from meta -- Load code & mem from meta
local mem = load_memory(meta) local mem = load_memory(meta)
local code = meta:get_string("code") local code = meta:get_string("code")
-- 'Last warning' label.
local warning = ""
local function send_warning(str)
warning = "Warning: " .. str
end
-- Create environment -- Create environment
local itbl = {} local env = create_environment(pos, mem, event)
local env = create_environment(pos, mem, event, itbl, send_warning)
-- Create the sandbox and execute code -- Create the sandbox and execute code
local f, msg = create_sandbox(code, env) local f, msg = create_sandbox(code, env)
if not f then return false, msg end if not f then return msg end
-- Start string true sandboxing
local onetruestring = getmetatable("")
-- If a string sandbox is already up yet inconsistent, something is very wrong
assert(onetruestring.__index == string)
onetruestring.__index = env.string
local success, msg = pcall(f) local success, msg = pcall(f)
onetruestring.__index = string if not success then return msg end
-- End string true sandboxing
if not success then return false, msg end
if type(env.port) ~= "table" then if type(env.port) ~= "table" then
return false, "Ports set are invalid." return "Ports set are invalid."
end end
-- Actually set the ports -- Actually set the ports
@ -602,56 +465,8 @@ local function run_inner(pos, code, event)
-- Save memory. This may burn the luacontroller if a memory overflow occurs. -- Save memory. This may burn the luacontroller if a memory overflow occurs.
save_memory(pos, meta, env.mem) save_memory(pos, meta, env.mem)
-- Execute deferred tasks
for _, v in ipairs(itbl) do
local failure = v()
if failure then
return false, failure
end
end
return true, warning
end end
local function reset_formspec(meta, code, errmsg)
meta:set_string("code", code)
code = minetest.formspec_escape(code or "")
errmsg = minetest.formspec_escape(tostring(errmsg or ""))
meta:set_string("formspec", "size[12,10]"..
"background[-0.2,-0.25;12.4,10.75;jeija_luac_background.png]"..
"textarea[0.2,0.2;12.2,9.5;code;;"..code.."]"..
"image_button[4.75,8.75;2.5,1;jeija_luac_runbutton.png;program;]"..
"image_button_exit[11.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]"..
"label[0.1,9;"..errmsg.."]")
end
local function reset_meta(pos, code, errmsg)
local meta = minetest.get_meta(pos)
reset_formspec(meta, code, errmsg)
meta:set_int("luac_id", math.random(1, 65535))
end
-- Wraps run_inner with LC-reset-on-error
local function run(pos, event)
local meta = minetest.get_meta(pos)
local code = meta:get_string("code")
local ok, errmsg = run_inner(pos, code, event)
if not ok then
reset_meta(pos, code, errmsg)
else
reset_formspec(meta, code, errmsg)
end
return ok, errmsg
end
local function reset(pos)
set_port_states(pos, {a=false, b=false, c=false, d=false})
end
-----------------------
-- A.Queue callbacks --
-----------------------
mesecon.queue:add_function("lc_interrupt", function (pos, luac_id, iid) mesecon.queue:add_function("lc_interrupt", function (pos, luac_id, iid)
-- There is no luacontroller anymore / it has been reprogrammed / replaced / burnt -- There is no luacontroller anymore / it has been reprogrammed / replaced / burnt
if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end
@ -659,14 +474,25 @@ mesecon.queue:add_function("lc_interrupt", function (pos, luac_id, iid)
run(pos, {type="interrupt", iid = iid}) run(pos, {type="interrupt", iid = iid})
end) end)
mesecon.queue:add_function("lc_digiline_relay", function (pos, channel, luac_id, msg) local function reset_meta(pos, code, errmsg)
if not digiline then return end local meta = minetest.get_meta(pos)
-- This check is only really necessary because in case of server crash, old actions can be thrown into the future meta:set_string("code", code)
if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end code = minetest.formspec_escape(code or "")
if (minetest.registered_nodes[minetest.get_node(pos).name].is_burnt) then return end errmsg = minetest.formspec_escape(errmsg or "")
-- The actual work meta:set_string("formspec", "size[10,8]"..
digiline:receptor_send(pos, digiline.rules.default, channel, msg) "background[-0.2,-0.25;10.4,8.75;jeija_luac_background.png]"..
end) "textarea[0.2,0.6;10.2,5;code;;"..code.."]"..
"image_button[3.75,6;2.5,1;jeija_luac_runbutton.png;program;]"..
"image_button_exit[9.72,-0.25;0.425,0.4;jeija_close_window.png;exit;]"..
"label[0.1,5;"..errmsg.."]")
meta:set_int("heat", 0)
meta:set_int("luac_id", math.random(1, 65535))
end
local function reset(pos)
set_port_states(pos, {a=false, b=false, c=false, d=false})
end
----------------------- -----------------------
-- Node Registration -- -- Node Registration --
@ -693,23 +519,10 @@ local digiline = {
receptor = {}, receptor = {},
effector = { effector = {
action = function(pos, node, channel, msg) action = function(pos, node, channel, msg)
msg = clean_and_weigh_digiline_message(msg)
run(pos, {type = "digiline", channel = channel, msg = msg}) run(pos, {type = "digiline", channel = channel, msg = msg})
end end
} }
} }
local function get_program(pos)
local meta = minetest.get_meta(pos)
return meta:get_string("code")
end
local function set_program(pos, code)
reset(pos)
reset_meta(pos, code)
return run(pos, {type="program"})
end
local function on_receive_fields(pos, form_name, fields, sender) local function on_receive_fields(pos, form_name, fields, sender)
if not fields.program then if not fields.program then
return return
@ -719,10 +532,12 @@ local function on_receive_fields(pos, form_name, fields, sender)
minetest.record_protection_violation(pos, name) minetest.record_protection_violation(pos, name)
return return
end end
local ok, err = set_program(pos, fields.code) reset(pos)
if not ok then reset_meta(pos, fields.code)
-- it's not an error from the server perspective local err = run(pos, {type="program"})
minetest.log("action", "Lua controller programming error: " .. tostring(err)) if err then
print(err)
reset_meta(pos, fields.code, err)
end end
end end
@ -776,15 +591,11 @@ for d = 0, 1 do
receptor = { receptor = {
state = mesecon.state.on, state = mesecon.state.on,
rules = output_rules[cid] rules = output_rules[cid]
}, }
luacontroller = {
get_program = get_program,
set_program = set_program,
},
} }
minetest.register_node(node_name, { minetest.register_node(node_name, {
description = "Luacontroller", description = "LuaController",
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
top, top,
@ -796,7 +607,6 @@ for d = 0, 1 do
}, },
inventory_image = top, inventory_image = top,
paramtype = "light", paramtype = "light",
is_ground_content = false,
groups = groups, groups = groups,
drop = BASENAME.."0000", drop = BASENAME.."0000",
sunlight_propagates = true, sunlight_propagates = true,
@ -816,11 +626,9 @@ for d = 0, 1 do
d = d == 1, d = d == 1,
}, },
after_dig_node = function (pos, node) after_dig_node = function (pos, node)
mesecon.do_cooldown(pos)
mesecon.receptor_off(pos, output_rules) mesecon.receptor_off(pos, output_rules)
end, end,
is_luacontroller = true, is_luacontroller = true,
on_blast = mesecon.on_blastnode,
}) })
end end
end end
@ -828,7 +636,7 @@ end
end end
------------------------------ ------------------------------
-- Overheated Luacontroller -- -- Overheated LuaController --
------------------------------ ------------------------------
minetest.register_node(BASENAME .. "_burnt", { minetest.register_node(BASENAME .. "_burnt", {
@ -844,7 +652,6 @@ minetest.register_node(BASENAME .. "_burnt", {
inventory_image = "jeija_luacontroller_burnt_top.png", inventory_image = "jeija_luacontroller_burnt_top.png",
is_burnt = true, is_burnt = true,
paramtype = "light", paramtype = "light",
is_ground_content = false,
groups = {dig_immediate=2, not_in_creative_inventory=1}, groups = {dig_immediate=2, not_in_creative_inventory=1},
drop = BASENAME.."0000", drop = BASENAME.."0000",
sunlight_propagates = true, sunlight_propagates = true,
@ -862,7 +669,6 @@ minetest.register_node(BASENAME .. "_burnt", {
end, end,
}, },
}, },
on_blast = mesecon.on_blastnode,
}) })
------------------------ ------------------------

Binary file not shown.

Before

Width:  |  Height:  |  Size: 718 B

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -69,7 +69,6 @@ minetest.register_node(nodename, {
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
is_ground_content = false,
walkable = true, walkable = true,
groups = groups, groups = groups,
drop = "mesecons_microcontroller:microcontroller0000 1", drop = "mesecons_microcontroller:microcontroller0000 1",
@ -103,12 +102,6 @@ minetest.register_node(nodename, {
meta:set_string("eeprom", r) meta:set_string("eeprom", r)
end, end,
on_receive_fields = function(pos, formanme, fields, sender) on_receive_fields = function(pos, formanme, fields, sender)
local player_name = sender:get_player_name()
if minetest.is_protected(pos, player_name) and
not minetest.check_player_privs(player_name, {protection_bypass=true}) then
minetest.record_protection_violation(pos, player_name)
return
end
local meta = minetest.get_meta(pos) local meta = minetest.get_meta(pos)
if fields.band then if fields.band then
fields.code = "sbi(C, A&B) :A and B are inputs, C is output" fields.code = "sbi(C, A&B) :A and B are inputs, C is output"
@ -145,34 +138,20 @@ minetest.register_node(nodename, {
rules = microc_rules[node.name] rules = microc_rules[node.name]
mesecon.receptor_off(pos, rules) mesecon.receptor_off(pos, rules)
end, end,
on_blast = mesecon.on_blastnode,
}) })
end end
end end
end end
end end
if minetest.get_modpath("mesecons_luacontroller") then minetest.register_craft({
minetest.register_craft({ output = 'craft "mesecons_microcontroller:microcontroller0000" 2',
type = "shapeless", recipe = {
output = "mesecons_microcontroller:microcontroller0000", {'mesecons_materials:silicon', 'mesecons_materials:silicon', 'group:mesecon_conductor_craftable'},
recipe = {"mesecons_luacontroller:luacontroller0000"}, {'mesecons_materials:silicon', 'mesecons_materials:silicon', 'group:mesecon_conductor_craftable'},
}) {'group:mesecon_conductor_craftable', 'group:mesecon_conductor_craftable', ''},
minetest.register_craft({ }
type = "shapeless", })
output = "mesecons_luacontroller:luacontroller0000",
recipe = {"mesecons_microcontroller:microcontroller0000"},
})
else
minetest.register_craft({
output = 'craft "mesecons_microcontroller:microcontroller0000" 2',
recipe = {
{'mesecons_materials:silicon', 'mesecons_materials:silicon', 'group:mesecon_conductor_craftable'},
{'mesecons_materials:silicon', 'mesecons_materials:silicon', 'group:mesecon_conductor_craftable'},
{'group:mesecon_conductor_craftable', 'group:mesecon_conductor_craftable', ''},
}
})
end
yc.reset = function(pos) yc.reset = function(pos)
yc.action(pos, {a=false, b=false, c=false, d=false}) yc.action(pos, {a=false, b=false, c=false, d=false})
@ -278,7 +257,7 @@ yc.parsecode = function(code, pos)
end end
yc.parse_get_command = function(code, starti) yc.parse_get_command = function(code, starti)
local i = starti i = starti
local s local s
while s ~= "" do while s ~= "" do
s = string.sub(code, i, i) s = string.sub(code, i, i)
@ -304,7 +283,7 @@ yc.parse_get_command = function(code, starti)
end end
yc.parse_get_params = function(code, starti) yc.parse_get_params = function(code, starti)
local i = starti i = starti
local s local s
local params = {} local params = {}
local is_string = false local is_string = false
@ -327,7 +306,7 @@ yc.parse_get_params = function(code, starti)
end end
yc.parse_get_eeprom_param = function(cond, starti) yc.parse_get_eeprom_param = function(cond, starti)
local i = starti i = starti
local s local s
local addr local addr
while s ~= "" do while s ~= "" do
@ -494,7 +473,7 @@ end
--Condition parsing --Condition parsing
yc.command_if_getcondition = function(code, starti) yc.command_if_getcondition = function(code, starti)
local i = starti i = starti
local s local s
local brackets = 1 --1 Bracket to close local brackets = 1 --1 Bracket to close
while s ~= "" do while s ~= "" do

View File

@ -8,156 +8,124 @@
-- Pushes all block in front of it -- Pushes all block in front of it
-- Pull all blocks in its back -- Pull all blocks in its back
-- settings: function mesecon.get_movestone_direction(pos)
local timer_interval = 1 / mesecon.setting("movestone_speed", 3) local lpos
local max_push = mesecon.setting("movestone_max_push", 50) local rules = {
local max_pull = mesecon.setting("movestone_max_pull", 50) {x=0, y=1, z=-1},
{x=0, y=0, z=-1},
{x=0, y=-1, z=-1},
{x=0, y=1, z=1},
{x=0, y=-1, z=1},
{x=0, y=0, z=1},
{x=1, y=0, z=0},
{x=1, y=1, z=0},
{x=1, y=-1, z=0},
{x=-1, y=1, z=0},
{x=-1, y=-1, z=0},
{x=-1, y=0, z=0}}
-- helper functions: lpos = {x=pos.x+1, y=pos.y, z=pos.z}
local function get_movestone_direction(rulename, is_vertical) for n = 1, 3 do
if is_vertical then if mesecon.is_power_on(lpos, rules[n]) then
if rulename.z > 0 then return {x=0, y=0, z=-1}
return {x = 0, y = -1, z = 0}
elseif rulename.z < 0 then
return {x = 0, y = 1, z = 0}
elseif rulename.x > 0 then
return {x = 0, y = -1, z = 0}
elseif rulename.x < 0 then
return {x = 0, y = 1, z = 0}
end end
else end
if rulename.z > 0 then
return {x = -1, y = 0, z = 0} lpos = {x = pos.x-1, y = pos.y, z = pos.z}
elseif rulename.z < 0 then for n=4, 6 do
return {x = 1, y = 0, z = 0} if mesecon.is_power_on(lpos, rules[n]) then
elseif rulename.x > 0 then return {x=0, y=0, z=1}
return {x = 0, y = 0, z = -1} end
elseif rulename.x < 0 then end
return {x = 0, y = 0, z = 1}
lpos = {x = pos.x, y = pos.y, z = pos.z+1}
for n=7, 9 do
if mesecon.is_power_on(lpos, rules[n]) then
return {x=-1, y=0, z=0}
end
end
lpos = {x = pos.x, y = pos.y, z = pos.z-1}
for n=10, 12 do
if mesecon.is_power_on(lpos, rules[n]) then
return {x=1, y=0, z=0}
end end
end end
end end
-- registration functions: function mesecon.register_movestone(name, def, is_sticky)
function mesecon.register_movestone(name, def, is_sticky, is_vertical) local timer_interval = 1 / mesecon.setting("movestone_speed", 3)
local function movestone_move(pos, node, rulename) local name_active = name.."_active"
local direction = get_movestone_direction(rulename, is_vertical)
local frontpos = vector.add(pos, direction)
-- ### Step 1: Push nodes in front ### local function movestone_move (pos)
local success, stack, oldstack = mesecon.mvps_push(frontpos, direction, max_push) if minetest.get_node(pos).name ~= name_active then
if not success then return
minetest.get_node_timer(pos):start(timer_interval) end
local direction = mesecon.get_movestone_direction(pos)
if not direction then
minetest.set_node(pos, {name = name})
return
end
local frontpos = vector.add(pos, direction)
local backpos = vector.subtract(pos, direction)
-- ### Step 1: Push nodes in front ###
local maxpush = mesecon.setting("movestone_max_push", 50)
local maxpull = mesecon.setting("movestone_max_pull", 50)
local success, stack, oldstack = mesecon.mvps_push(frontpos, direction, maxpush)
if success then
mesecon.mvps_process_stack(stack)
mesecon.mvps_move_objects(frontpos, direction, oldstack)
-- Too large stack/stopper in the way: try again very soon
else
minetest.after(0.05, movestone_move, pos)
return return
end end
mesecon.mvps_move_objects(frontpos, direction, oldstack)
-- ### Step 2: Move the movestone ### -- ### Step 2: Move the movestone ###
local node = minetest.get_node(pos)
minetest.set_node(frontpos, node) minetest.set_node(frontpos, node)
minetest.remove_node(pos) minetest.remove_node(pos)
mesecon.on_dignode(pos, node) mesecon.on_dignode(pos, node)
mesecon.on_placenode(frontpos, node) mesecon.on_placenode(frontpos, node)
minetest.get_node_timer(frontpos):start(timer_interval) minetest.after(timer_interval, movestone_move, frontpos)
-- ### Step 3: If sticky, pull stack behind ### -- ### Step 3: If sticky, pull stack behind ###
if is_sticky then if is_sticky then
local backpos = vector.subtract(pos, direction) mesecon.mvps_pull_all(backpos, direction, maxpull)
success, stack, oldstack = mesecon.mvps_pull_all(backpos, direction, max_pull)
if success then
mesecon.mvps_move_objects(backpos, vector.multiply(direction, -1), oldstack, -1)
end
end end
-- ### Step 4: Let things fall ###
minetest.check_for_falling(vector.add(pos, {x=0, y=1, z=0}))
end end
def.is_ground_content = false
def.mesecons = {effector = { def.mesecons = {effector = {
action_on = function(pos, node, rulename) action_on = function (pos)
if rulename and not minetest.get_node_timer(pos):is_started() then if minetest.get_node(pos).name ~= name_active then
movestone_move(pos, node, rulename) minetest.set_node(pos, {name = name_active})
movestone_move(pos)
end end
end, end,
rules = mesecon.rules.default, action_off = function (pos)
minetest.set_node(pos, {name = name})
end
}} }}
def.on_timer = function(pos, elapsed) def.drop = name
local sourcepos = mesecon.is_powered(pos)
if not sourcepos then
return
end
local rulename = vector.subtract(sourcepos[1], pos)
mesecon.activate(pos, minetest.get_node(pos), rulename, 0)
end
def.on_blast = mesecon.on_blastnode
minetest.register_node(name, def) minetest.register_node(name, def)
-- active node only
local def_active = table.copy(def)
def_active.groups.not_in_creative_inventory = 1
minetest.register_node(name_active, def_active)
end end
-- registration:
mesecon.register_movestone("mesecons_movestones:movestone", { mesecon.register_movestone("mesecons_movestones:movestone", {
tiles = { tiles = {"jeija_movestone_side.png", "jeija_movestone_side.png", "jeija_movestone_side.png", "jeija_movestone_side.png", "jeija_movestone_arrows.png", "jeija_movestone_arrows.png"},
"jeija_movestone_side.png", groups = {cracky=3},
"jeija_movestone_side.png", description="Movestone",
"jeija_movestone_arrows.png^[transformFX",
"jeija_movestone_arrows.png^[transformFX",
"jeija_movestone_arrows.png",
"jeija_movestone_arrows.png",
},
groups = {cracky = 3},
description = "Movestone",
sounds = default.node_sound_stone_defaults() sounds = default.node_sound_stone_defaults()
}, false, false) }, false)
mesecon.register_movestone("mesecons_movestones:sticky_movestone", {
tiles = {
"jeija_movestone_side.png",
"jeija_movestone_side.png",
"jeija_sticky_movestone.png^[transformFX",
"jeija_sticky_movestone.png^[transformFX",
"jeija_sticky_movestone.png",
"jeija_sticky_movestone.png",
},
groups = {cracky = 3},
description = "Sticky Movestone",
sounds = default.node_sound_stone_defaults(),
}, true, false)
mesecon.register_movestone("mesecons_movestones:movestone_vertical", {
tiles = {
"jeija_movestone_side.png",
"jeija_movestone_side.png",
"jeija_movestone_arrows.png^[transformFXR90",
"jeija_movestone_arrows.png^[transformR90",
"jeija_movestone_arrows.png^[transformFXR90",
"jeija_movestone_arrows.png^[transformR90",
},
groups = {cracky = 3},
description = "Vertical Movestone",
sounds = default.node_sound_stone_defaults()
}, false, true)
mesecon.register_movestone("mesecons_movestones:sticky_movestone_vertical", {
tiles = {
"jeija_movestone_side.png",
"jeija_movestone_side.png",
"jeija_sticky_movestone.png^[transformFXR90",
"jeija_sticky_movestone.png^[transformR90",
"jeija_sticky_movestone.png^[transformFXR90",
"jeija_sticky_movestone.png^[transformR90",
},
groups = {cracky = 3},
description = "Vertical Sticky Movestone",
sounds = default.node_sound_stone_defaults(),
}, true, true)
-- crafting:
-- base recipe:
minetest.register_craft({ minetest.register_craft({
output = "mesecons_movestones:movestone 2", output = "mesecons_movestones:movestone 2",
recipe = { recipe = {
@ -167,32 +135,15 @@ minetest.register_craft({
} }
}) })
-- conversation: -- STICKY_MOVESTONE
minetest.register_craft({ mesecon.register_movestone("mesecons_movestones:sticky_movestone", {
type = "shapeless", tiles = {"jeija_movestone_side.png", "jeija_movestone_side.png", "jeija_movestone_side.png", "jeija_movestone_side.png", "jeija_sticky_movestone.png", "jeija_sticky_movestone.png"},
output = "mesecons_movestones:movestone", inventory_image = minetest.inventorycube("jeija_sticky_movestone.png", "jeija_movestone_side.png", "jeija_movestone_side.png"),
recipe = {"mesecons_movestones:movestone_vertical"}, groups = {cracky=3},
}) description="Sticky Movestone",
sounds = default.node_sound_stone_defaults(),
}, true)
minetest.register_craft({
type = "shapeless",
output = "mesecons_movestones:movestone_vertical",
recipe = {"mesecons_movestones:movestone"},
})
minetest.register_craft({
type = "shapeless",
output = "mesecons_movestones:sticky_movestone",
recipe = {"mesecons_movestones:sticky_movestone_vertical"},
})
minetest.register_craft({
type = "shapeless",
output = "mesecons_movestones:sticky_movestone_vertical",
recipe = {"mesecons_movestones:sticky_movestone"},
})
-- make sticky:
minetest.register_craft({ minetest.register_craft({
output = "mesecons_movestones:sticky_movestone", output = "mesecons_movestones:sticky_movestone",
recipe = { recipe = {
@ -200,18 +151,6 @@ minetest.register_craft({
} }
}) })
minetest.register_craft({ -- Don't allow pushing movestones while they're active
output = "mesecons_movestones:sticky_movestone_vertical", mesecon.register_mvps_stopper("mesecons_movestones:movestone_active")
recipe = { mesecon.register_mvps_stopper("mesecons_movestones:sticky_movestone_active")
{"mesecons_materials:glue"},
{"mesecons_movestones:movestone_vertical"},
{"mesecons_materials:glue"},
}
})
-- legacy code:
minetest.register_alias("mesecons_movestones:movestone_active",
"mesecons_movestones:movestone")
minetest.register_alias("mesecons_movestones:sticky_movestone_active",
"mesecons_movestones:sticky_movestone")

View File

@ -165,10 +165,6 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
-- remove all nodes -- remove all nodes
for _, n in ipairs(nodes) do for _, n in ipairs(nodes) do
n.meta = minetest.get_meta(n.pos):to_table() n.meta = minetest.get_meta(n.pos):to_table()
local node_timer = minetest.get_node_timer(n.pos)
if node_timer:is_started() then
n.node_timer = {node_timer:get_timeout(), node_timer:get_elapsed()}
end
minetest.remove_node(n.pos) minetest.remove_node(n.pos)
end end
@ -183,9 +179,6 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
minetest.set_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)
if n.node_timer then
minetest.get_node_timer(np):set(unpack(n.node_timer))
end
end end
local moved_nodes = {} local moved_nodes = {}
@ -197,7 +190,6 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
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
moved_nodes[i].node_timer = nodes[i].node_timer
end end
on_mvps_move(moved_nodes) on_mvps_move(moved_nodes)
@ -205,56 +197,45 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
return true, nodes, oldstack return true, nodes, oldstack
end end
function mesecon.mvps_move_objects(pos, dir, nodestack, movefactor) mesecon.register_on_mvps_move(function(moved_nodes)
for _, n in ipairs(moved_nodes) do
mesecon.on_placenode(n.pos, n.node)
end
end)
function mesecon.mvps_move_objects(pos, dir, nodestack)
local objects_to_move = {} local objects_to_move = {}
local dir_k
local dir_l -- Move object at tip of stack, pushpos is position at tip of stack
for k, v in pairs(dir) do local pushpos = vector.add(pos, vector.multiply(dir, #nodestack))
if v ~= 0 then
dir_k = k local objects = minetest.get_objects_inside_radius(pushpos, 1)
dir_l = v for _, obj in ipairs(objects) do
break table.insert(objects_to_move, obj)
end
-- Move objects lying/standing on the stack (before it was pushed - oldstack)
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 = 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)
end
end end
end end
movefactor = movefactor or 1
dir = vector.multiply(dir, movefactor) for _, obj in ipairs(objects_to_move) do
for id, obj in pairs(minetest.object_refs) do local entity = obj:get_luaentity()
local obj_pos = obj:getpos() if not entity or not mesecon.is_mvps_unmov(entity.name) then
local cbox = obj:get_properties().collisionbox local np = vector.add(obj:getpos(), dir)
local min_pos = vector.add(obj_pos, vector.new(cbox[1], cbox[2], cbox[3]))
local max_pos = vector.add(obj_pos, vector.new(cbox[4], cbox[5], cbox[6])) --move only if destination is not solid
local ok = true local nn = minetest.get_node(np)
for k, v in pairs(pos) do if not ((not minetest.registered_nodes[nn.name])
local edge1, edge2 or minetest.registered_nodes[nn.name].walkable) then
if k ~= dir_k then obj:setpos(np)
edge1 = v - 0.51 -- More than 0.5 to move objects near to the stack.
edge2 = v + 0.51
else
edge1 = v - 0.5 * dir_l
edge2 = v + (#nodestack + 0.5 * movefactor) * dir_l
-- Make sure, edge1 is bigger than edge2:
if edge1 > edge2 then
edge1, edge2 = edge2, edge1
end
end
if min_pos[k] > edge2 or max_pos[k] < edge1 then
ok = false
break
end
end
if ok then
local ent = obj:get_luaentity()
if obj:is_player() or (ent and not mesecon.is_mvps_unmov(ent.name)) then
local np = vector.add(obj_pos, dir)
-- Move only if destination is not solid or object is inside stack:
local nn = minetest.get_node(np)
local node_def = minetest.registered_nodes[nn.name]
local obj_offset = dir_l * (obj_pos[dir_k] - pos[dir_k])
if (node_def and not node_def.walkable) or
(obj_offset >= 0 and
obj_offset <= #nodestack - 0.5) then
obj:move_to(np)
end
end end
end end
end end
@ -265,19 +246,3 @@ 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_b_2")
mesecon.register_mvps_stopper("doors:door_steel_t_2") mesecon.register_mvps_stopper("doors:door_steel_t_2")
mesecon.register_mvps_stopper("default:chest_locked") mesecon.register_mvps_stopper("default:chest_locked")
mesecon.register_on_mvps_move(mesecon.move_hot_nodes)
mesecon.register_on_mvps_move(function(moved_nodes)
for i = 1, #moved_nodes do
local moved_node = moved_nodes[i]
mesecon.on_placenode(moved_node.pos, moved_node.node)
minetest.after(0, function()
minetest.check_for_falling(moved_node.oldpos)
minetest.check_for_falling(moved_node.pos)
end)
local node_def = minetest.registered_nodes[moved_node.node.name]
if node_def and node_def.mesecon and node_def.mesecon.on_mvps_move then
node_def.mesecon.on_mvps_move(moved_node.pos, moved_node.node,
moved_node.oldpos, moved_node.meta)
end
end
end)

View File

@ -1,7 +1,6 @@
minetest.register_node("mesecons_noteblock:noteblock", { minetest.register_node("mesecons_noteblock:noteblock", {
description = "Noteblock", description = "Noteblock",
tiles = {"mesecons_noteblock.png"}, tiles = {"mesecons_noteblock.png"},
is_ground_content = false,
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}, groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2},
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
@ -13,8 +12,7 @@ minetest.register_node("mesecons_noteblock:noteblock", {
action_on = function(pos, node) action_on = function(pos, node)
mesecon.noteblock_play(pos, node.param2) mesecon.noteblock_play(pos, node.param2)
end end
}}, }}
on_blast = mesecon.on_blastnode,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -1,62 +1,36 @@
local specs = { local piston_get_rules = function (node)
normal = { local all_rules ={
offname = "mesecons_pistons:piston_normal_off", {x=0, y=0, z=1},
onname = "mesecons_pistons:piston_normal_on", {x=0, y=0, z=-1},
pusher = "mesecons_pistons:piston_pusher_normal", {x=1, y=0, z=0},
}, {x=-1, y=0, z=0},
sticky = { {x=1, y=1, z=0},
offname = "mesecons_pistons:piston_sticky_off", {x=1, y=-1, z=0},
onname = "mesecons_pistons:piston_sticky_on", {x=-1, y=1, z=0},
pusher = "mesecons_pistons:piston_pusher_sticky", {x=-1, y=-1, z=0},
sticky = true, {x=0, y=1, z=1},
}, {x=0, y=-1, z=1},
} {x=0, y=1, z=-1},
{x=0, y=-1, z=-1}}
local function get_pistonspec_name(name, part) local pusher_dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
if part then for k,v in ipairs(all_rules) do
for spec_name, spec in pairs(specs) do if vector.equals(v, pusher_dir) then
if name == spec[part] then table.remove(all_rules, k)
return spec_name, part
end
end
return
end
for spec_name, spec in pairs(specs) do
for part, value in pairs(spec) do
if name == value then
return spec_name, part
end
end end
end end
return all_rules
end end
local function get_pistonspec(name, part) local function piston_facedir_direction(node)
return specs[get_pistonspec_name(name, part)] local rules = {{x = 0, y = 0, z = -1}}
for i = 1, node.param2 do
rules = mesecon.rotate_rules_left(rules)
end
return rules[1]
end end
local max_push = mesecon.setting("piston_max_push", 15) local piston_remove_pusher = function(pos, node)
local max_pull = mesecon.setting("piston_max_pull", 15) local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
-- Get mesecon rules of pistons
local function piston_get_rules(node)
local dir = minetest.facedir_to_dir(node.param2)
for k, v in pairs(dir) do
if v ~= 0 then
dir = {k, -v}
break
end
end
local rules = table.copy(mesecon.rules.default)
for i, rule in ipairs(rules) do
if rule[dir[1]] == dir[2] then
table.remove(rules, i)
end
end
return rules
end
local function piston_remove_pusher(pos, node)
local pistonspec = get_pistonspec(node.name, "onname")
local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1) local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
local pusherpos = vector.add(pos, dir) local pusherpos = vector.add(pos, dir)
local pushername = minetest.get_node(pusherpos).name local pushername = minetest.get_node(pusherpos).name
@ -72,167 +46,48 @@ local function piston_remove_pusher(pos, node)
max_hear_distance = 20, max_hear_distance = 20,
gain = 0.3, gain = 0.3,
}) })
minetest.check_for_falling(pusherpos) nodeupdate(pusherpos)
end end
local piston_on = function(pos, node) local piston_on = function(pos, node)
local pistonspec = get_pistonspec(node.name, "offname") local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1) local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
local pusher_pos = vector.add(pos, dir) local np = vector.add(pos, dir)
local success, stack, oldstack = mesecon.mvps_push(pusher_pos, dir, max_push) local maxpush = mesecon.setting("piston_max_push", 15)
if not success then local success, stack, oldstack = mesecon.mvps_push(np, dir, maxpush)
return if success then
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)
end end
minetest.set_node(pos, {param2 = node.param2, name = pistonspec.onname})
minetest.set_node(pusher_pos, {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(pusher_pos, dir, oldstack)
end end
local function piston_off(pos, node) local piston_off = function(pos, node)
local pistonspec = get_pistonspec(node.name, "onname") local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
minetest.set_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 not pistonspec.sticky then local maxpull = mesecon.setting("piston_max_pull", 15)
return local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
end local pullpos = vector.add(pos, vector.multiply(dir, 2))
local dir = minetest.facedir_to_dir(node.param2) local stack = mesecon.mvps_pull_single(pullpos, vector.multiply(dir, -1), maxpull)
local pullpos = vector.add(pos, vector.multiply(dir, -2)) mesecon.mvps_process_stack(pos, dir, stack)
local success, stack, oldstack = mesecon.mvps_pull_single(pullpos, dir, max_pull)
if success then
mesecon.mvps_move_objects(pullpos, vector.multiply(dir, -1), oldstack, -1)
end end
end end
local orientations = { local piston_onrotate = function(pos, node, _, _, newparam2)
[0] = { 4, 8}, local node_copy = minetest.get_node(pos)
{13, 17}, minetest.after(0, mesecon.on_dignode, pos, node)
{10, 6}, node_copy.param2 = newparam2
{20, 15}, minetest.after(0, mesecon.on_placenode, pos, node_copy)
}
local function piston_orientate(pos, placer)
if not placer then
return
end
local pitch = math.deg(placer:get_look_vertical())
local node = minetest.get_node(pos)
if pitch > 55 then
node.param2 = orientations[node.param2][1]
elseif pitch < -55 then
node.param2 = orientations[node.param2][2]
else
return
end
minetest.swap_node(pos, node)
-- minetest.after, because on_placenode for unoriented piston must be processed first
minetest.after(0, mesecon.on_placenode, pos, node)
end end
local rotations = {
{0, 16, 20, 12},
{2, 14, 22, 18},
{1, 5, 23, 9},
{3, 11, 21, 7},
{4, 13, 10, 19},
{6, 15, 8, 17},
}
local function get_rotation(param2)
for a = 1, #rotations do
for f = 1, #rotations[a] do
if rotations[a][f] == param2 then
return a, f
end
end
end
end
local function rotate(param2, mode)
local axis, face = get_rotation(param2)
if mode == screwdriver.ROTATE_FACE then
face = face + 1
if face > 4 then
face = 1
end
elseif mode == screwdriver.ROTATE_AXIS then
axis = axis + 1
if axis > 6 then
axis = 1
end
face = 1
else
return param2
end
return rotations[axis][face]
end
local function piston_rotate(pos, node, _, mode)
node.param2 = rotate(node.param2, mode)
minetest.swap_node(pos, node)
mesecon.execute_autoconnect_hooks_now(pos, node)
return true
end
local function piston_rotate_on(pos, node, player, mode)
local pistonspec = get_pistonspec(node.name, "onname")
local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
local pusher_pos = vector.add(dir, pos)
local pusher_node = minetest.get_node(pusher_pos)
if pusher_node.name ~= pistonspec.pusher then
return piston_rotate(pos, node, nil, mode)
end
if mode == screwdriver.ROTATE_FACE then
piston_rotate(pusher_pos, pusher_node, nil, mode)
return piston_rotate(pos, node, nil, mode)
elseif mode ~= screwdriver.ROTATE_AXIS then
return false
end
local player_name = player and player:is_player() and player:get_player_name() or ""
local ok, dir_after, pusher_pos_after
for i = 1, 5 do
node.param2 = rotate(node.param2, mode)
dir_after = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
pusher_pos_after = vector.add(dir_after, pos)
local pusher_pos_after_node_name = minetest.get_node(pusher_pos_after).name
local pusher_pos_after_node_def = minetest.registered_nodes[pusher_pos_after_node_name]
if pusher_pos_after_node_def and pusher_pos_after_node_def.buildable_to and
not minetest.is_protected(pusher_pos_after, player_name) then
ok = true
break
end
end
if not ok then
return false
end
pusher_node.param2 = node.param2
minetest.remove_node(pusher_pos)
minetest.set_node(pusher_pos_after, pusher_node)
minetest.swap_node(pos, node)
mesecon.execute_autoconnect_hooks_now(pos, node)
return true
end
local function piston_rotate_pusher(pos, node, player, mode)
local pistonspec = get_pistonspec(node.name, "pusher")
local piston_pos = vector.add(pos, minetest.facedir_to_dir(node.param2))
local piston_node = minetest.get_node(piston_pos)
if piston_node.name ~= pistonspec.onname then
minetest.remove_node(pos) -- Make it possible to remove alone pushers.
return false
end
return piston_rotate_on(piston_pos, piston_node, player, mode)
end
-- Boxes:
local pt = 3/16 -- pusher thickness local pt = 3/16 -- pusher thickness
local piston_pusher_box = { local piston_pusher_box = {
@ -240,18 +95,26 @@ local piston_pusher_box = {
fixed = { fixed = {
{-2/16, -2/16, -.5 + pt, 2/16, 2/16, .5 + pt}, {-2/16, -2/16, -.5 + pt, 2/16, 2/16, .5 + pt},
{-.5 , -.5 , -.5 , .5 , .5 , -.5 + pt}, {-.5 , -.5 , -.5 , .5 , .5 , -.5 + pt},
}, }
} }
local piston_on_box = { local piston_on_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-.5, -.5, -.5 + pt, .5, .5, .5} {-.5, -.5, -.5 + pt, .5, .5, .5}
}, }
} }
-- Normal (non-sticky) Pistons: -- Normal (non-sticky) ones:
local pistonspec_normal = {
offname = "mesecons_pistons:piston_normal_off",
onname = "mesecons_pistons:piston_normal_on",
dir = piston_facedir_direction,
pusher = "mesecons_pistons:piston_pusher_normal",
}
-- offstate -- offstate
minetest.register_node("mesecons_pistons:piston_normal_off", { minetest.register_node("mesecons_pistons:piston_normal_off", {
description = "Piston", description = "Piston",
@ -262,23 +125,20 @@ minetest.register_node("mesecons_pistons:piston_normal_off", {
"mesecons_piston_right.png", "mesecons_piston_right.png",
"mesecons_piston_back.png", "mesecons_piston_back.png",
"mesecons_piston_pusher_front.png" "mesecons_piston_pusher_front.png"
}, },
groups = {cracky = 3}, groups = {cracky = 3},
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false, mesecons_piston = pistonspec_normal,
after_place_node = piston_orientate, on_rotate = piston_onrotate,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
mesecons = {effector={ mesecons = {effector={
action_on = piston_on, action_on = piston_on,
rules = piston_get_rules, rules = piston_get_rules
}}, }}
on_rotate = piston_rotate,
on_blast = mesecon.on_blastnode,
}) })
-- onstate -- onstate
minetest.register_node("mesecons_pistons:piston_normal_on", { minetest.register_node("mesecons_pistons:piston_normal_on", {
description = "Activated Piston Base",
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
"mesecons_piston_top.png", "mesecons_piston_top.png",
@ -287,27 +147,27 @@ minetest.register_node("mesecons_pistons:piston_normal_on", {
"mesecons_piston_right.png", "mesecons_piston_right.png",
"mesecons_piston_back.png", "mesecons_piston_back.png",
"mesecons_piston_on_front.png" "mesecons_piston_on_front.png"
}, },
inventory_image = "mesecons_piston_top.png",
wield_image = "mesecons_piston_top.png",
groups = {cracky = 3, not_in_creative_inventory = 1}, groups = {cracky = 3, not_in_creative_inventory = 1},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
drop = "mesecons_pistons:piston_normal_off", drop = "mesecons_pistons:piston_normal_off",
after_dig_node = piston_remove_pusher, after_dig_node = piston_remove_pusher,
node_box = piston_on_box, node_box = piston_on_box,
selection_box = piston_on_box, selection_box = piston_on_box,
mesecons_piston = pistonspec_normal,
on_rotate = false,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
mesecons = {effector={ mesecons = {effector={
action_off = piston_off, action_off = piston_off,
rules = piston_get_rules, rules = piston_get_rules
}}, }}
on_rotate = piston_rotate_on,
on_blast = mesecon.on_blastnode,
}) })
-- pusher -- pusher
minetest.register_node("mesecons_pistons:piston_pusher_normal", { minetest.register_node("mesecons_pistons:piston_pusher_normal", {
description = "Piston Pusher",
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
"mesecons_piston_pusher_top.png", "mesecons_piston_pusher_top.png",
@ -316,20 +176,26 @@ minetest.register_node("mesecons_pistons:piston_pusher_normal", {
"mesecons_piston_pusher_right.png", "mesecons_piston_pusher_right.png",
"mesecons_piston_pusher_back.png", "mesecons_piston_pusher_back.png",
"mesecons_piston_pusher_front.png" "mesecons_piston_pusher_front.png"
}, },
groups = {not_in_creative_inventory = 1},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
diggable = false, diggable = false,
on_rotate = false,
corresponding_piston = "mesecons_pistons:piston_normal_on",
selection_box = piston_pusher_box, selection_box = piston_pusher_box,
node_box = piston_pusher_box, node_box = piston_pusher_box,
on_rotate = piston_rotate_pusher,
drop = "",
sounds = default.node_sound_wood_defaults(),
}) })
-- Sticky ones -- Sticky ones
local pistonspec_sticky = {
offname = "mesecons_pistons:piston_sticky_off",
onname = "mesecons_pistons:piston_sticky_on",
dir = piston_facedir_direction,
pusher = "mesecons_pistons:piston_pusher_sticky",
sticky = true,
}
-- offstate -- offstate
minetest.register_node("mesecons_pistons:piston_sticky_off", { minetest.register_node("mesecons_pistons:piston_sticky_off", {
description = "Sticky Piston", description = "Sticky Piston",
@ -340,23 +206,20 @@ minetest.register_node("mesecons_pistons:piston_sticky_off", {
"mesecons_piston_right.png", "mesecons_piston_right.png",
"mesecons_piston_back.png", "mesecons_piston_back.png",
"mesecons_piston_pusher_front_sticky.png" "mesecons_piston_pusher_front_sticky.png"
}, },
groups = {cracky = 3}, groups = {cracky = 3},
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false, on_rotate = piston_onrotate,
after_place_node = piston_orientate, mesecons_piston = pistonspec_sticky,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
mesecons = {effector={ mesecons = {effector={
action_on = piston_on, action_on = piston_on,
rules = piston_get_rules, rules = piston_get_rules
}}, }}
on_rotate = piston_rotate,
on_blast = mesecon.on_blastnode,
}) })
-- onstate -- onstate
minetest.register_node("mesecons_pistons:piston_sticky_on", { minetest.register_node("mesecons_pistons:piston_sticky_on", {
description = "Activated Sticky Piston Base",
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
"mesecons_piston_top.png", "mesecons_piston_top.png",
@ -365,27 +228,27 @@ minetest.register_node("mesecons_pistons:piston_sticky_on", {
"mesecons_piston_right.png", "mesecons_piston_right.png",
"mesecons_piston_back.png", "mesecons_piston_back.png",
"mesecons_piston_on_front.png" "mesecons_piston_on_front.png"
}, },
inventory_image = "mesecons_piston_top.png",
wield_image = "mesecons_piston_top.png",
groups = {cracky = 3, not_in_creative_inventory = 1}, groups = {cracky = 3, not_in_creative_inventory = 1},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
drop = "mesecons_pistons:piston_sticky_off", drop = "mesecons_pistons:piston_sticky_off",
after_dig_node = piston_remove_pusher, after_dig_node = piston_remove_pusher,
node_box = piston_on_box, node_box = piston_on_box,
selection_box = piston_on_box, selection_box = piston_on_box,
mesecons_piston = pistonspec_sticky,
on_rotate = false,
sounds = default.node_sound_wood_defaults(), sounds = default.node_sound_wood_defaults(),
mesecons = {effector={ mesecons = {effector={
action_off = piston_off, action_off = piston_off,
rules = piston_get_rules, rules = piston_get_rules
}}, }}
on_rotate = piston_rotate_on,
on_blast = mesecon.on_blastnode,
}) })
-- pusher -- pusher
minetest.register_node("mesecons_pistons:piston_pusher_sticky", { minetest.register_node("mesecons_pistons:piston_pusher_sticky", {
description = "Sticky Piston Pusher",
drawtype = "nodebox", drawtype = "nodebox",
tiles = { tiles = {
"mesecons_piston_pusher_top.png", "mesecons_piston_pusher_top.png",
@ -394,38 +257,34 @@ minetest.register_node("mesecons_pistons:piston_pusher_sticky", {
"mesecons_piston_pusher_right.png", "mesecons_piston_pusher_right.png",
"mesecons_piston_pusher_back.png", "mesecons_piston_pusher_back.png",
"mesecons_piston_pusher_front_sticky.png" "mesecons_piston_pusher_front_sticky.png"
}, },
groups = {not_in_creative_inventory = 1},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
diggable = false, diggable = false,
on_rotate = false,
corresponding_piston = "mesecons_pistons:piston_sticky_on",
selection_box = piston_pusher_box, selection_box = piston_pusher_box,
node_box = piston_pusher_box, node_box = piston_pusher_box,
on_rotate = piston_rotate_pusher,
drop = "",
sounds = default.node_sound_wood_defaults(),
}) })
-- Register pushers as stoppers if they would be seperated from the piston -- Register pushers as stoppers if they would be seperated from the piston
local function piston_pusher_get_stopper(node, dir, stack, stackid) local piston_pusher_get_stopper = function (node, dir, stack, stackid)
if (stack[stackid + 1] if (stack[stackid + 1]
and stack[stackid + 1].node.name == get_pistonspec(node.name, "pusher").onname and stack[stackid + 1].node.name == minetest.registered_nodes[node.name].corresponding_piston
and stack[stackid + 1].node.param2 == node.param2) and stack[stackid + 1].node.param2 == node.param2)
or (stack[stackid - 1] or (stack[stackid - 1]
and stack[stackid - 1].node.name == get_pistonspec(node.name, "pusher").onname and stack[stackid - 1].node.name == minetest.registered_nodes[node.name].corresponding_piston
and stack[stackid - 1].node.param2 == node.param2) then and stack[stackid - 1].node.param2 == node.param2) then
return false return false
end end
return true return true
end end
local function piston_pusher_up_down_get_stopper(node, dir, stack, stackid) local piston_pusher_up_down_get_stopper = function (node, dir, stack, stackid)
if (stack[stackid + 1] if (stack[stackid + 1]
and stack[stackid + 1].node.name == get_pistonspec(node.name, "pusher").onname) and stack[stackid + 1].node.name == minetest.registered_nodes[node.name].corresponding_piston)
or (stack[stackid - 1] or (stack[stackid - 1]
and stack[stackid - 1].node.name == get_pistonspec(node.name, "pusher").onname) then and stack[stackid - 1].node.name == minetest.registered_nodes[node.name].corresponding_piston) then
return false return false
end end
return true return true
@ -434,24 +293,24 @@ end
mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_normal", piston_pusher_get_stopper) mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_normal", piston_pusher_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_sticky", piston_pusher_get_stopper) mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_sticky", piston_pusher_get_stopper)
-- Register pistons as stoppers if they would be seperated from the stopper -- Register pistons as stoppers if they would be seperated from the stopper
local piston_up_down_get_stopper = function (node, dir, stack, stackid) local piston_up_down_get_stopper = function (node, dir, stack, stackid)
if (stack[stackid + 1] if (stack[stackid + 1]
and stack[stackid + 1].node.name == get_pistonspec(node.name, "onname").pusher) and stack[stackid + 1].node.name == minetest.registered_nodes[node.name].mesecons_piston.pusher)
or (stack[stackid - 1] or (stack[stackid - 1]
and stack[stackid - 1].node.name == get_pistonspec(node.name, "onname").pusher) then and stack[stackid - 1].node.name == minetest.registered_nodes[node.name].mesecons_piston.pusher) then
return false return false
end end
return true return true
end end
local function piston_get_stopper(node, dir, stack, stackid) local piston_get_stopper = function (node, dir, stack, stackid)
local pistonspec = get_pistonspec(node.name, "onname") local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1) local dir = pistonspec.dir(node)
local pusherpos = vector.add(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 pistonspec.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 vector.equals(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
@ -465,13 +324,12 @@ end
mesecon.register_mvps_stopper("mesecons_pistons:piston_normal_on", piston_get_stopper) mesecon.register_mvps_stopper("mesecons_pistons:piston_normal_on", piston_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_get_stopper) mesecon.register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_get_stopper)
--craft recipes --craft recipes
minetest.register_craft({ minetest.register_craft({
output = "mesecons_pistons:piston_normal_off 2", output = "mesecons_pistons:piston_normal_off 2",
recipe = { recipe = {
{"group:wood", "group:wood", "group:wood"}, {"group:wood", "group:wood", "group:wood"},
{"default:cobble", "default:steel_ingot", "default:cobble"}, {"default:cobble", "default:steel_ingot", "default:cobble"},
{"default:cobble", "group:mesecon_conductor_craftable", "default:cobble"}, {"default:cobble", "group:mesecon_conductor_craftable", "default:cobble"},
} }
}) })
@ -484,6 +342,3 @@ minetest.register_craft({
} }
}) })
-- load legacy code
dofile(minetest.get_modpath("mesecons_pistons")..DIR_DELIM.."legacy.lua")

View File

@ -1,48 +0,0 @@
local ground_dir = {
[0] = {x = 0, y = -1, z = 0},
{x = 0, y = 0, z = -1},
{x = 0, y = 0, z = 1},
{x = -1, y = 0, z = 0},
{x = 1, y = 0, z = 0},
{x = 0, y = 1, z = 0},
}
minetest.register_lbm({
label = "Upgrade legacy pistons pointing up",
name = "mesecons_pistons:replace_legacy_piston_up",
nodenames = {
"mesecons_pistons:piston_up_normal_off",
"mesecons_pistons:piston_up_normal_on",
"mesecons_pistons:piston_up_pusher_normal",
"mesecons_pistons:piston_up_sticky_off",
"mesecons_pistons:piston_up_sticky_on",
"mesecons_pistons:piston_up_pusher_sticky",
},
run_at_every_load = false,
action = function(pos, node)
local dir = ground_dir[math.floor(node.param2/4)]
node.param2 = minetest.dir_to_facedir(dir, true)
node.name = node.name:sub(1, 24)..node.name:sub(28)
minetest.swap_node(pos, node)
end,
})
minetest.register_lbm({
label = "Upgrade legacy pistons pointing down",
name = "mesecons_pistons:replace_legacy_piston_down",
nodenames = {
"mesecons_pistons:piston_down_normal_off",
"mesecons_pistons:piston_down_normal_on",
"mesecons_pistons:piston_down_pusher_normal",
"mesecons_pistons:piston_down_sticky_off",
"mesecons_pistons:piston_down_sticky_on",
"mesecons_pistons:piston_down_pusher_sticky",
},
run_at_every_load = false,
action = function(pos, node)
local dir = vector.multiply(ground_dir[math.floor(node.param2/4)], -1)
node.param2 = minetest.dir_to_facedir(dir, true)
node.name = node.name:sub(1, 24)..node.name:sub(30)
minetest.swap_node(pos, node)
end,
})

View File

@ -7,7 +7,6 @@ minetest.register_node("mesecons_powerplant:power_plant", {
tiles = {"jeija_power_plant.png"}, tiles = {"jeija_power_plant.png"},
inventory_image = "jeija_power_plant.png", inventory_image = "jeija_power_plant.png",
paramtype = "light", paramtype = "light",
is_ground_content = false,
walkable = false, walkable = false,
groups = {dig_immediate=3, mesecon = 2}, groups = {dig_immediate=3, mesecon = 2},
light_source = default.LIGHT_MAX-9, light_source = default.LIGHT_MAX-9,
@ -19,8 +18,7 @@ minetest.register_node("mesecons_powerplant:power_plant", {
sounds = default.node_sound_leaves_defaults(), sounds = default.node_sound_leaves_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.on state = mesecon.state.on
}}, }}
on_blast = mesecon.on_blastnode,
}) })
minetest.register_craft({ minetest.register_craft({

View File

@ -42,42 +42,30 @@ end
-- tiles_on: textures of the pressure plate when active -- tiles_on: textures of the pressure plate when active
-- image: inventory and wield image of the pressure plate -- image: inventory and wield image of the pressure plate
-- recipe: crafting recipe of the pressure plate -- recipe: crafting recipe of the pressure plate
-- groups: groups
-- sounds: sound table
function mesecon.register_pressure_plate(basename, description, textures_off, textures_on, image_w, image_i, recipe, groups, sounds)
local groups_off, groups_on
if not groups then
groups = {}
end
local groups_off = table.copy(groups)
local groups_on = table.copy(groups)
groups_on.not_in_creative_inventory = 1
function mesecon.register_pressure_plate(basename, description, textures_off, textures_on, image_w, image_i, recipe)
mesecon.register_node(basename, { mesecon.register_node(basename, {
drawtype = "nodebox", drawtype = "nodebox",
inventory_image = image_i, inventory_image = image_i,
wield_image = image_w, wield_image = image_w,
paramtype = "light", paramtype = "light",
is_ground_content = false, description = description,
description = description,
pressureplate_basename = basename, pressureplate_basename = basename,
on_timer = pp_on_timer, on_timer = pp_on_timer,
on_construct = function(pos) on_construct = function(pos)
minetest.get_node_timer(pos):start(mesecon.setting("pplate_interval", 0.1)) minetest.get_node_timer(pos):start(mesecon.setting("pplate_interval", 0.1))
end, end,
sounds = sounds,
},{ },{
mesecons = {receptor = { state = mesecon.state.off, rules = mesecon.rules.pplate }}, mesecons = {receptor = { state = mesecon.state.off, rules = mesecon.rules.pplate }},
node_box = pp_box_off, node_box = pp_box_off,
selection_box = pp_box_off, selection_box = pp_box_off,
groups = groups_off, groups = {snappy = 2, oddly_breakable_by_hand = 3},
tiles = textures_off tiles = textures_off
},{ },{
mesecons = {receptor = { state = mesecon.state.on, rules = mesecon.rules.pplate }}, mesecons = {receptor = { state = mesecon.state.on, rules = mesecon.rules.pplate }},
node_box = pp_box_on, node_box = pp_box_on,
selection_box = pp_box_on, selection_box = pp_box_on,
groups = groups_on, groups = {snappy = 2, oddly_breakable_by_hand = 3, not_in_creative_inventory = 1},
tiles = textures_on tiles = textures_on
}) })
@ -94,9 +82,7 @@ mesecon.register_pressure_plate(
{"jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on_edges.png"}, {"jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on.png","jeija_pressure_plate_wood_on_edges.png"},
"jeija_pressure_plate_wood_wield.png", "jeija_pressure_plate_wood_wield.png",
"jeija_pressure_plate_wood_inv.png", "jeija_pressure_plate_wood_inv.png",
{{"group:wood", "group:wood"}}, {{"group:wood", "group:wood"}})
{ choppy = 3, oddly_breakable_by_hand = 3 },
default.node_sound_wood_defaults())
mesecon.register_pressure_plate( mesecon.register_pressure_plate(
"mesecons_pressureplates:pressure_plate_stone", "mesecons_pressureplates:pressure_plate_stone",
@ -105,6 +91,4 @@ mesecon.register_pressure_plate(
{"jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on_edges.png"}, {"jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on.png","jeija_pressure_plate_stone_on_edges.png"},
"jeija_pressure_plate_stone_wield.png", "jeija_pressure_plate_stone_wield.png",
"jeija_pressure_plate_stone_inv.png", "jeija_pressure_plate_stone_inv.png",
{{"default:cobble", "default:cobble"}}, {{"default:cobble", "default:cobble"}})
{ cracky = 3, oddly_breakable_by_hand = 3 },
default.node_sound_stone_defaults())

View File

@ -2,7 +2,6 @@
minetest.register_node("mesecons_random:removestone", { minetest.register_node("mesecons_random:removestone", {
tiles = {"jeija_removestone.png"}, tiles = {"jeija_removestone.png"},
is_ground_content = false,
inventory_image = minetest.inventorycube("jeija_removestone_inv.png"), inventory_image = minetest.inventorycube("jeija_removestone_inv.png"),
groups = {cracky=3}, groups = {cracky=3},
description="Removestone", description="Removestone",
@ -11,10 +10,8 @@ minetest.register_node("mesecons_random:removestone", {
action_on = function (pos, node) action_on = function (pos, node)
minetest.remove_node(pos) minetest.remove_node(pos)
mesecon.on_dignode(pos, node) mesecon.on_dignode(pos, node)
minetest.check_for_falling(vector.add(pos, vector.new(0, 1, 0)))
end end
}}, }}
on_blast = mesecon.on_blastnode,
}) })
minetest.register_craft({ minetest.register_craft({
@ -31,16 +28,22 @@ minetest.register_craft({
minetest.register_node("mesecons_random:ghoststone", { minetest.register_node("mesecons_random:ghoststone", {
description="Ghoststone", description="Ghoststone",
tiles = {"jeija_ghoststone.png"}, tiles = {"jeija_ghoststone.png"},
is_ground_content = false, is_ground_content = true,
inventory_image = minetest.inventorycube("jeija_ghoststone_inv.png"), inventory_image = minetest.inventorycube("jeija_ghoststone_inv.png"),
groups = {cracky=3}, groups = {cracky=3},
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.off, state = mesecon.state.off,
rules = mesecon.rules.alldirs, rules = { --axes
{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},
},
onstate = "mesecons_random:ghoststone_active" onstate = "mesecons_random:ghoststone_active"
}}, }}
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_random:ghoststone_active", { minetest.register_node("mesecons_random:ghoststone_active", {
@ -48,13 +51,19 @@ minetest.register_node("mesecons_random:ghoststone_active", {
pointable = false, pointable = false,
walkable = false, walkable = false,
diggable = false, diggable = false,
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
paramtype = "light", paramtype = "light",
drop = "mesecons_random:ghoststone", drop = "mesecons_random:ghoststone",
mesecons = {conductor = { mesecons = {conductor = {
state = mesecon.state.on, state = mesecon.state.on,
rules = mesecon.rules.alldirs, 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},
},
offstate = "mesecons_random:ghoststone" offstate = "mesecons_random:ghoststone"
}}, }},
on_construct = function(pos) on_construct = function(pos)
@ -63,8 +72,7 @@ minetest.register_node("mesecons_random:ghoststone_active", {
if (minetest.get_node(shadowpos).name == "air") then if (minetest.get_node(shadowpos).name == "air") then
minetest.dig_node(shadowpos) minetest.dig_node(shadowpos)
end end
end, end
on_blast = mesecon.on_blastnode,
}) })

View File

@ -42,7 +42,6 @@ mesecon.register_node("mesecons_receiver:receiver", {
drawtype = "nodebox", drawtype = "nodebox",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
walkable = false, walkable = false,
on_rotate = false, on_rotate = false,
@ -56,7 +55,6 @@ mesecon.register_node("mesecons_receiver:receiver", {
}, },
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, not_in_creative_inventory = 1},
drop = "mesecons:wire_00000000_off", drop = "mesecons:wire_00000000_off",
sounds = default.node_sound_defaults(),
}, { }, {
tiles = { tiles = {
"receiver_top_off.png", "receiver_top_off.png",
@ -91,7 +89,6 @@ mesecon.register_node("mesecons_receiver:receiver_up", {
drawtype = "nodebox", drawtype = "nodebox",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
walkable = false, walkable = false,
on_rotate = false, on_rotate = false,
@ -105,7 +102,6 @@ mesecon.register_node("mesecons_receiver:receiver_up", {
}, },
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, not_in_creative_inventory = 1},
drop = "mesecons:wire_00000000_off", drop = "mesecons:wire_00000000_off",
sounds = default.node_sound_defaults(),
}, { }, {
tiles = {"mesecons_wire_off.png"}, tiles = {"mesecons_wire_off.png"},
mesecons = {conductor = { mesecons = {conductor = {
@ -136,7 +132,6 @@ mesecon.register_node("mesecons_receiver:receiver_down", {
drawtype = "nodebox", drawtype = "nodebox",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
walkable = false, walkable = false,
on_rotate = false, on_rotate = false,
@ -150,7 +145,6 @@ mesecon.register_node("mesecons_receiver:receiver_down", {
}, },
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, not_in_creative_inventory = 1},
drop = "mesecons:wire_00000000_off", drop = "mesecons:wire_00000000_off",
sounds = default.node_sound_defaults(),
}, { }, {
tiles = {"mesecons_wire_off.png"}, tiles = {"mesecons_wire_off.png"},
mesecons = {conductor = { mesecons = {conductor = {
@ -209,6 +203,7 @@ function mesecon.receiver_place(rcpt_pos)
local param2 = minetest.dir_to_facedir(minetest.facedir_to_dir(node.param2)) local param2 = minetest.dir_to_facedir(minetest.facedir_to_dir(node.param2))
if string.find(nn.name, "mesecons:wire_") ~= nil then if string.find(nn.name, "mesecons:wire_") ~= nil then
minetest.dig_node(pos)
minetest.set_node(pos, {name = rcvtype, param2 = param2}) minetest.set_node(pos, {name = rcvtype, param2 = param2})
mesecon.on_placenode(pos, nn) mesecon.on_placenode(pos, nn)
end end
@ -217,7 +212,8 @@ end
function mesecon.receiver_remove(rcpt_pos, dugnode) function mesecon.receiver_remove(rcpt_pos, dugnode)
local pos = mesecon.receiver_get_pos_from_rcpt(rcpt_pos, dugnode.param2) local pos = mesecon.receiver_get_pos_from_rcpt(rcpt_pos, dugnode.param2)
local nn = minetest.get_node(pos) local nn = minetest.get_node(pos)
if string.find(nn.name, "mesecons_receiver:receiver_") ~= nil then if string.find(nn.name, "mesecons_receiver:receiver_") ~=nil then
minetest.dig_node(pos)
local node = {name = "mesecons:wire_00000000_off"} local node = {name = "mesecons:wire_00000000_off"}
minetest.set_node(pos, node) minetest.set_node(pos, node)
mesecon.on_placenode(pos, node) mesecon.on_placenode(pos, node)

View File

@ -7,7 +7,7 @@ minetest.register_node("mesecons_solarpanel:solar_panel_on", {
paramtype = "light", paramtype = "light",
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
walkable = false, walkable = false,
is_ground_content = false, is_ground_content = true,
node_box = { node_box = {
type = "wallmounted", type = "wallmounted",
wall_bottom = { -7/16, -8/16, -7/16, 7/16, -7/16, 7/16 }, wall_bottom = { -7/16, -8/16, -7/16, 7/16, -7/16, 7/16 },
@ -24,10 +24,8 @@ minetest.register_node("mesecons_solarpanel:solar_panel_on", {
groups = {dig_immediate=3, not_in_creative_inventory = 1}, groups = {dig_immediate=3, not_in_creative_inventory = 1},
sounds = default.node_sound_glass_defaults(), sounds = default.node_sound_glass_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.on, state = mesecon.state.on
rules = mesecon.rules.wallmounted_get, }}
}},
on_blast = mesecon.on_blastnode,
}) })
-- Solar Panel -- Solar Panel
@ -39,7 +37,7 @@ minetest.register_node("mesecons_solarpanel:solar_panel_off", {
paramtype = "light", paramtype = "light",
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
walkable = false, walkable = false,
is_ground_content = false, is_ground_content = true,
node_box = { node_box = {
type = "wallmounted", type = "wallmounted",
wall_bottom = { -7/16, -8/16, -7/16, 7/16, -7/16, 7/16 }, wall_bottom = { -7/16, -8/16, -7/16, 7/16, -7/16, 7/16 },
@ -53,13 +51,11 @@ minetest.register_node("mesecons_solarpanel:solar_panel_off", {
wall_side = { -8/16, -7/16, -7/16, -7/16, 7/16, 7/16 }, wall_side = { -8/16, -7/16, -7/16, -7/16, 7/16, 7/16 },
}, },
groups = {dig_immediate=3}, groups = {dig_immediate=3},
description = "Solar Panel", description="Solar Panel",
sounds = default.node_sound_glass_defaults(), sounds = default.node_sound_glass_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.off, state = mesecon.state.off
rules = mesecon.rules.wallmounted_get, }}
}},
on_blast = mesecon.on_blastnode,
}) })
minetest.register_craft({ minetest.register_craft({
@ -78,9 +74,8 @@ minetest.register_abm(
local light = minetest.get_node_light(pos, nil) local light = minetest.get_node_light(pos, nil)
if light >= 12 then if light >= 12 then
node.name = "mesecons_solarpanel:solar_panel_on" minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2})
minetest.swap_node(pos, node) mesecon.receptor_on(pos)
mesecon.receptor_on(pos, mesecon.rules.wallmounted_get(node))
end end
end, end,
}) })
@ -93,9 +88,8 @@ minetest.register_abm(
local light = minetest.get_node_light(pos, nil) local light = minetest.get_node_light(pos, nil)
if light < 12 then if light < 12 then
node.name = "mesecons_solarpanel:solar_panel_off" minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2})
minetest.swap_node(pos, node) mesecon.receptor_off(pos)
mesecon.receptor_off(pos, mesecon.rules.wallmounted_get(node))
end end
end, end,
}) })

View File

@ -3,17 +3,14 @@
-- All sides sticky block -- All sides sticky block
minetest.register_node("mesecons_stickyblocks:sticky_block_all", { minetest.register_node("mesecons_stickyblocks:sticky_block_all", {
-- TODO: Rename to “All-Faces Sticky Block” when other sticky blocks become available description = "All-sides sticky block",
description = "Sticky Block", tiles = {"default_grass.png^default_footprint.png"},
tiles = {"mesecons_stickyblocks_sticky.png"}, groups = {dig_immediate=2},
is_ground_content = false,
groups = {choppy=3, oddly_breakable_by_hand=2},
mvps_sticky = function (pos, node) mvps_sticky = function (pos, node)
local connected = {} local connected = {}
for _, r in ipairs(mesecon.rules.alldirs) do for _, r in ipairs(mesecon.rules.alldirs) do
table.insert(connected, vector.add(pos, r)) table.insert(connected, vector.add(pos, r))
end end
return connected return connected
end, end
sounds = default.node_sound_wood_defaults(),
}) })

Binary file not shown.

Before

Width:  |  Height:  |  Size: 661 B

View File

@ -3,7 +3,6 @@
mesecon.register_node("mesecons_switch:mesecon_switch", { mesecon.register_node("mesecons_switch:mesecon_switch", {
paramtype2="facedir", paramtype2="facedir",
description="Switch", description="Switch",
is_ground_content = false,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
on_rightclick = function (pos, node) on_rightclick = function (pos, node)
if(mesecon.flipstate(pos, node) == "on") then if(mesecon.flipstate(pos, node) == "on") then

View File

@ -54,18 +54,15 @@ minetest.register_node("mesecons_torch:mesecon_torch_off", {
tiles = {"jeija_torches_off.png", "jeija_torches_off_ceiling.png", "jeija_torches_off_side.png"}, tiles = {"jeija_torches_off.png", "jeija_torches_off_ceiling.png", "jeija_torches_off_side.png"},
inventory_image = "jeija_torches_off.png", inventory_image = "jeija_torches_off.png",
paramtype = "light", paramtype = "light",
is_ground_content = false,
walkable = false, walkable = false,
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
selection_box = torch_selectionbox, selection_box = torch_selectionbox,
groups = {dig_immediate = 3, not_in_creative_inventory = 1}, groups = {dig_immediate = 3, not_in_creative_inventory = 1},
drop = "mesecons_torch:mesecon_torch_on", drop = "mesecons_torch:mesecon_torch_on",
sounds = default.node_sound_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.off, state = mesecon.state.off,
rules = torch_get_output_rules rules = torch_get_output_rules
}}, }}
on_blast = mesecon.on_blastnode,
}) })
minetest.register_node("mesecons_torch:mesecon_torch_on", { minetest.register_node("mesecons_torch:mesecon_torch_on", {
@ -74,7 +71,6 @@ minetest.register_node("mesecons_torch:mesecon_torch_on", {
inventory_image = "jeija_torches_on.png", inventory_image = "jeija_torches_on.png",
wield_image = "jeija_torches_on.png", wield_image = "jeija_torches_on.png",
paramtype = "light", paramtype = "light",
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
walkable = false, walkable = false,
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
@ -82,12 +78,10 @@ minetest.register_node("mesecons_torch:mesecon_torch_on", {
groups = {dig_immediate=3}, groups = {dig_immediate=3},
light_source = default.LIGHT_MAX-5, light_source = default.LIGHT_MAX-5,
description="Mesecon Torch", description="Mesecon Torch",
sounds = default.node_sound_defaults(),
mesecons = {receptor = { mesecons = {receptor = {
state = mesecon.state.on, state = mesecon.state.on,
rules = torch_get_output_rules rules = torch_get_output_rules
}}, }},
on_blast = mesecon.on_blastnode,
}) })
minetest.register_abm({ minetest.register_abm({

View File

@ -8,7 +8,6 @@ mesecon.register_node("mesecons_walllever:wall_lever", {
wield_image = "jeija_wall_lever_inv.png", wield_image = "jeija_wall_lever_inv.png",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
walkable = false, walkable = false,
selection_box = { selection_box = {

View File

@ -200,7 +200,6 @@ local function register_wires()
if nodeid ~= "00000000" then if nodeid ~= "00000000" then
groups_off["not_in_creative_inventory"] = 1 groups_off["not_in_creative_inventory"] = 1
end end
mesecon.register_node(":mesecons:wire_"..nodeid, { mesecon.register_node(":mesecons:wire_"..nodeid, {
description = "Mesecon", description = "Mesecon",
drawtype = "nodebox", drawtype = "nodebox",
@ -208,15 +207,13 @@ local function register_wires()
wield_image = "mesecons_wire_inv.png", wield_image = "mesecons_wire_inv.png",
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true, sunlight_propagates = true,
selection_box = selectionbox, selection_box = selectionbox,
node_box = nodebox, node_box = nodebox,
walkable = false, walkable = false,
drop = "mesecons:wire_00000000_off",
mesecon_wire = true,
sounds = default.node_sound_defaults(),
on_rotate = false, on_rotate = false,
drop = "mesecons:wire_00000000_off",
mesecon_wire = true
}, {tiles = tiles_off, mesecons = meseconspec_off, groups = groups_off}, }, {tiles = tiles_off, mesecons = meseconspec_off, groups = groups_off},
{tiles = tiles_on, mesecons = meseconspec_on, groups = groups_on}) {tiles = tiles_on, mesecons = meseconspec_on, groups = groups_on})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 180 KiB

View File

@ -1,43 +0,0 @@
[mesecons]
mesecon.resumetime (Startup delay) int 4 1 10
mesecon.overheat_max (Device heat limit) int 20 1 100
mesecon.cooldown_time (Device cooldown time) float 2.0 0.1 10.0
mesecon.cooldown_granularity (Cooldown step length) float 0.5 0.0 1.0
[mesecons_blinkyplant]
mesecon.blinky_plant_interval (Plant blinking interval) int 3 1 5
[mesecons_detector]
mesecon.detector_radius (Player detector scanning radius) int 6 3 16
mesecon.node_detector_distance_max (Node detector distance limit) int 10 1 16
[mesecons_luacontroller]
mesecon.luacontroller_string_rep_max (string:rep result length limit) int 64000 1000 1000000
mesecon.luacontroller_digiline_maxlen (Digiline message size limit) int 50000 1000 1000000
mesecon.luacontroller_maxevents (Controller execution time limit) int 10000 1000 100000
mesecon.luacontroller_memsize (Controller memory limit) int 100000 10000 1000000
[mesecons_movestones]
mesecon.movestone_speed (Speed) int 3 1 10
mesecon.movestone_max_push (Max push) int 50 1 100
mesecon.movestone_max_pull (Max pull) int 50 1 100
[mesecons_pistons]
mesecon.piston_max_push (Max push) int 15 1 100
mesecon.piston_max_pull (Max pull) int 15 1 100
[mesecons_pressureplates]
mesecon.pplate_interval (Check interval) float 0.1 0.1 1.0