mp.mesecons: Update to Git commit 7013f2e & patch 96784e2

Upstream: https://github.com/minetest-mods/mesecons/tree/7013f2e
Patch: https://github.com/AntumMT/mp-mesecons/tree/96784e2
This commit is contained in:
Jordan Irwin 2018-07-04 11:48:11 -07:00
parent 65f6ca5708
commit 53adf260f0
59 changed files with 1222 additions and 968 deletions

View File

@ -136,7 +136,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
* [3d_armor][] ([LGPL / CC BY-SA][lic.3d_armor]) - version: [cc26d04 Git][ver.3d_armor] *2017-07-09* ([patched][patch.3d_armor]) ***UPDATES***
* [deploy_nodes][] ([BSD 3-Clause][lic.deploy_nodes]) -- version [b67e162 Git][ver.deploy_nodes] *2017-06-08*
* [homedecor][] ([LGPL / WTFPL / CC BY-SA / CC0][lic.homedecor]) -- version: [a6c17d6 Git][ver.homedecor] *2017-06-16* ([patched][patch.homedecor]) ***UPDATES***
* [mesecons][] ([LGPL / CC BY-SA][lic.mesecons]) -- version: [564bdc2 Git][ver.mesecons] *2017-05-08* ([patched][patch.mesecons]) ***UPDATES***
* [mesecons][] ([LGPL / CC BY-SA][lic.mesecons]) -- version [7013f2e Git][ver.mesecons] *2018-05-15* ([patched][patch.mesecons])
* [minetest_game][] ([LGPL][lic.lgpl2.1] / [CC BY-SA][lic.ccbysa3.0]) -- version: [0.4.17][ver.minetest_game] *2018-05-18* ***UNSTABLE UPDATES***
* [moremesecons][] ([MPL][lic.mpl2.0]) -- version: [aa2ae82 Git][ver.moremesecons] *2017-06-04* ***UPDATES***
* [technic][] ([LGPL][lic.lgpl2.0]) -- version: [6664714 Git][ver.technic] *2018-06-28* ([patched][patch.technic])
@ -431,7 +431,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
[ver.invisibility]: https://github.com/tenplus1/invisibility/tree/bf4156b
[ver.jukebox]: https://github.com/minetest-mods/jukebox/tree/21fdffa
[ver.lightning]: https://github.com/minetest-mods/lightning/tree/39bd36c
[ver.mesecons]: https://github.com/minetest-mods/mesecons/tree/564bdc2
[ver.mesecons]: https://github.com/minetest-mods/mesecons/tree/7013f2e
[ver.minetest_game]: https://github.com/minetest/minetest_game/tree/f855bee
[ver.mob-engine]: https://github.com/minetest-mods/mob-engine/tree/138f655
[ver.mobs_animal]: https://github.com/tenplus1/mobs_animal/tree/52889c7
@ -505,7 +505,7 @@ The game includes the mods from the default [minetest_game](https://github.com/m
[patch.hovercraft]: https://github.com/AntumMT/mod-hovercraft/tree/73a6223
[patch.hud]: https://github.com/AntumMT/mod-hud/tree/6846e20
[patch.invisibility]: https://github.com/AntumMT/mod-invisibility/tree/f045c7c
[patch.mesecons]: https://github.com/AntumMT/mp-mesecons/tree/830823a
[patch.mesecons]: https://github.com/AntumMT/mp-mesecons/tree/96784e2
[patch.minetest_game]: https://github.com/AntumMT/mtgame-minetest/tree/c2f3b95
[patch.mob-engine]: https://github.com/AntumMT/mp-mob-engine/tree/0b3706f
[patch.mobs_animal]: https://github.com/AntumMT/mod-mobs_animal/tree/e275046

View File

@ -2666,27 +2666,22 @@ animalmaterials.override_lasso = true
# ## mesecons
# ???
# type: int
# default: 600
#mesecon.foreceload_timeout = 600
# The value at which circuits will overheat.
# type: int
# default: 20
#mesecon.overheat_max = 20
# Resume time.
## Resume time.
# type: int
# default: 4
#mesecon.resumetime = 4
## Cooldown time.
## The value at which circuits will overheat.
# type: int
# default: 20
#mesecon.overheat_max = 20
## Device cooldown time.
# type: float
# default: 2.0
#mesecon.cooldown_time = 2.0
## Cooldown granularity.
## Cooldown step length.
# type: float
# default: 0.5
#mesecon.cooldown_granularity = 0.5
@ -2694,7 +2689,7 @@ animalmaterials.override_lasso = true
# ## mesecons_blinkyplant
## Plant interval.
## Plant blinking interval.
# type: int
# default: 3
#mesecon.blinky_plant_interval = 3
@ -2702,12 +2697,12 @@ animalmaterials.override_lasso = true
# ## mesecons_detector
## Detector radius.
## Player detector radius.
# type: int
# default: 6
#mesecon.detector_radius = 6
## Detector max distance.
## Node detector radius.
# type: int
# default: 10
#mesecon.node_detector_distance_max = 10
@ -2715,22 +2710,22 @@ animalmaterials.override_lasso = true
# ## mesecons_luacontroller
## Max.
## string:rep result length limit.
# type: int
# default: 64000
#mesecon.luacontroller_string_rep_max = 64000
## Digiline max length.
## Digiline message size limit.
# type: int
# default: 50000
#mesecon.luacontroller_digiline_maxlen = 50000
## Max events.
## Controller execution time limit.
# type: int
# default: 10000
#mesecon.luacontroller_maxevents = 10000
## Memory size.
## Controller memory limit.
# type: int
# default: 100000
#mesecon.luacontroller_memsize = 100000
@ -2743,12 +2738,12 @@ animalmaterials.override_lasso = true
# default: 3
#mesecon.movestone_speed = 3
## Max push
## Max push.
# type: int
# default: 50
#mesecon.movestone_max_push = 50
## Max pull
## Max pull.
# type: int
# default: 50
#mesecon.movestone_max_pull = 50
@ -2769,7 +2764,7 @@ animalmaterials.override_lasso = true
# ## mesecons_pressureplates
## Interval.
## Check interval.
# type: float
# default: 0.1
#mesecon.pplate_interval = 0.1

View File

@ -548,52 +548,3 @@ function mesecon.is_powered(pos, rule)
if (#sourcepos == 0) then return false
else return sourcepos 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

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

View File

@ -1,61 +1,85 @@
mesecon.rules = {}
mesecon.state = {}
mesecon.rules.default =
{{x=0, y=0, z=-1},
{x=1, y=0, z=0},
{x=-1, y=0, z=0},
{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=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.default = {
{x = 0, y = 0, z = -1},
{x = 1, y = 0, z = 0},
{x = -1, y = 0, z = 0},
{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 = 0, y = 1, z = 1},
{x = 0, y = -1, z = 1},
{x = 0, y = 1, z = -1},
{x = 0, y = -1, z = -1},
}
mesecon.rules.pplate = mesecon.mergetable(mesecon.rules.default, {{x=0, y=-2, z=0}})
mesecon.rules.floor = mesecon.mergetable(mesecon.rules.default, {{x = 0, y = -1, 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.pplate = mesecon.mergetable(mesecon.rules.floor, {{x = 0, y = -2, z = 0}})
mesecon.rules.flat =
{{x = 1, y = 0, z = 0},
{x =-1, y = 0, z = 0},
{x = 0, y = 0, z = 1},
{x = 0, y = 0, z =-1}}
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.alldirs =
{{x= 1, y= 0, z= 0},
{x=-1, y= 0, z= 0},
{x= 0, y= 1, z= 0},
{x= 0, y=-1, z= 0},
{x= 0, y= 0, z= 1},
{x= 0, y= 0, z=-1}}
mesecon.rules.flat = {
{x = 1, y = 0, z = 0},
{x = -1, y = 0, 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)
local rules = mesecon.rules.buttonlike
local dir = minetest.facedir_to_dir(node.param2)
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
return rules_from_dir(rules_buttonlike, dir)
end
mesecon.state.on = "on"

View File

@ -21,7 +21,8 @@ mesecon.on_placenode = function(pos, node)
end
--mesecon.receptor_on (pos, mesecon.conductor_get_rules(node))
elseif mesecon.is_conductor_on(node) then
minetest.swap_node(pos, {name = mesecon.get_conductor_off(node)})
node.name = mesecon.get_conductor_off(node)
minetest.swap_node(pos, node)
end
end
@ -62,6 +63,13 @@ mesecon.on_dignode = function(pos, node)
mesecon.execute_autoconnect_hooks_queue(pos, node)
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_dignode(mesecon.on_dignode)

View File

@ -6,6 +6,56 @@ function mesecon.move_node(pos, newpos)
minetest.get_meta(pos):from_table(meta)
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)
--[[
{
@ -178,6 +228,7 @@ end
function mesecon.register_node(name, spec_common, spec_off, spec_on)
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_on.__mesecon_state = "on"
spec_off.__mesecon_state = "off"

View File

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

View File

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

View File

@ -181,6 +181,7 @@ minetest.register_node("mesecons_commandblock:commandblock_off", {
description = "Command Block",
tiles = {"jeija_commandblock_off.png"},
inventory_image = minetest.inventorycube("jeija_commandblock_off.png"),
is_ground_content = false,
groups = {cracky=2, mesecon_effector_off=1},
on_construct = construct,
after_place_node = after_place,
@ -189,11 +190,13 @@ minetest.register_node("mesecons_commandblock:commandblock_off", {
sounds = default.node_sound_stone_defaults(),
mesecons = {effector = {
action_on = commandblock_action_on
}}
}},
on_blast = mesecon.on_blastnode,
})
minetest.register_node("mesecons_commandblock:commandblock_on", {
tiles = {"jeija_commandblock_on.png"},
is_ground_content = false,
groups = {cracky=2, mesecon_effector_on=1, not_in_creative_inventory=1},
light_source = 10,
drop = "mesecons_commandblock:commandblock_off",
@ -204,5 +207,6 @@ minetest.register_node("mesecons_commandblock:commandblock_on", {
sounds = default.node_sound_stone_defaults(),
mesecons = {effector = {
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",
paramtype2 = "facedir",
sunlight_propagates = true,
is_ground_content = true,
is_ground_content = false,
drop = 'mesecons_delayer:delayer_off_1',
on_punch = function (pos, node)
if node.name=="mesecons_delayer:delayer_off_1" then
@ -114,7 +114,8 @@ minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), {
rules = delayer_get_input_rules,
action_on = delayer_activate
}
}
},
on_blast = mesecon.on_blastnode,
})
@ -142,7 +143,7 @@ minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
is_ground_content = true,
is_ground_content = false,
drop = 'mesecons_delayer:delayer_off_1',
on_punch = function (pos, node)
if node.name=="mesecons_delayer:delayer_on_1" then
@ -168,7 +169,8 @@ minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
rules = delayer_get_input_rules,
action_off = delayer_deactivate
}
}
},
on_blast = mesecon.on_blastnode,
})
end

View File

@ -35,7 +35,7 @@ local function object_detector_scan(pos)
for _, str in pairs(string.split(scanname:gsub(" ", ""), ",")) do
scan_for[str] = true
end
local every_player = scanname == ""
for _, obj in pairs(objs) do
-- "" is returned if it is not a player; "" ~= nil; so only handle objects with foundname ~= ""
@ -66,6 +66,7 @@ local object_detector_digiline = {
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"},
paramtype = "light",
is_ground_content = false,
walkable = true,
groups = {cracky=3},
description="Player Detector",
@ -76,12 +77,14 @@ minetest.register_node("mesecons_detector:object_detector_off", {
on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields,
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", {
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",
is_ground_content = false,
walkable = true,
groups = {cracky=3,not_in_creative_inventory=1},
drop = 'mesecons_detector:object_detector_off',
@ -92,7 +95,8 @@ minetest.register_node("mesecons_detector:object_detector_on", {
on_construct = object_detector_make_formspec,
on_receive_fields = object_detector_on_receive_fields,
sounds = default.node_sound_stone_defaults(),
digiline = object_detector_digiline
digiline = object_detector_digiline,
on_blast = mesecon.on_blastnode,
})
minetest.register_craft({
@ -104,6 +108,15 @@ 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({
nodenames = {"mesecons_detector:object_detector_off"},
interval = 1,
@ -181,12 +194,12 @@ local node_detector_digiline = {
effector = {
action = function(pos, node, channel, msg)
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 msg == GET_COMMAND then
@ -225,6 +238,7 @@ minetest.register_node("mesecons_detector:node_detector_off", {
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_off.png"},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
walkable = true,
groups = {cracky=3},
description="Node Detector",
@ -234,13 +248,15 @@ minetest.register_node("mesecons_detector:node_detector_off", {
on_construct = node_detector_make_formspec,
on_receive_fields = node_detector_on_receive_fields,
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", {
tiles = {"default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "default_steel_block.png", "jeija_node_detector_on.png"},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
walkable = true,
groups = {cracky=3,not_in_creative_inventory=1},
drop = 'mesecons_detector:node_detector_off',
@ -250,7 +266,8 @@ minetest.register_node("mesecons_detector:node_detector_on", {
on_construct = node_detector_make_formspec,
on_receive_fields = node_detector_on_receive_fields,
sounds = default.node_sound_stone_defaults(),
digiline = node_detector_digiline
digiline = node_detector_digiline,
on_blast = mesecon.on_blastnode,
})
minetest.register_craft({
@ -262,6 +279,15 @@ 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({
nodenames = {"mesecons_detector:node_detector_off"},
interval = 1,

View File

@ -1,3 +1,5 @@
local screwdriver_exists = minetest.global_exists("screwdriver")
local corner_nodebox = {
type = "fixed",
fixed = {{ -16/32-0.001, -17/32, -3/32, 0, -13/32, 3/32 },
@ -33,6 +35,7 @@ minetest.register_node("mesecons_extrawires:corner_on", {
},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
walkable = false,
sunlight_propagates = true,
selection_box = corner_selectionbox,
@ -44,7 +47,9 @@ minetest.register_node("mesecons_extrawires:corner_on", {
state = mesecon.state.on,
rules = corner_get_rules,
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", {
@ -60,6 +65,7 @@ minetest.register_node("mesecons_extrawires:corner_off", {
},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
walkable = false,
sunlight_propagates = true,
selection_box = corner_selectionbox,
@ -70,7 +76,9 @@ minetest.register_node("mesecons_extrawires:corner_off", {
state = mesecon.state.off,
rules = corner_get_rules,
onstate = "mesecons_extrawires:corner_on"
}}
}},
on_blast = mesecon.on_blastnode,
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
})
minetest.register_craft({

View File

@ -29,6 +29,7 @@ minetest.register_node("mesecons_extrawires:crossover_off", {
"jeija_insulated_wire_ends_off.png"
},
paramtype = "light",
is_ground_content = false,
walkable = false,
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}},
@ -39,6 +40,7 @@ minetest.register_node("mesecons_extrawires:crossover_off", {
rules = crossover_get_rules(),
}
},
on_blast = mesecon.on_blastnode,
})
minetest.register_node("mesecons_extrawires:crossover_01", {
@ -53,6 +55,7 @@ minetest.register_node("mesecons_extrawires:crossover_01", {
"jeija_insulated_wire_ends_off.png"
},
paramtype = "light",
is_ground_content = false,
walkable = false,
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}},
@ -63,6 +66,7 @@ minetest.register_node("mesecons_extrawires:crossover_01", {
rules = crossover_get_rules(),
}
},
on_blast = mesecon.on_blastnode,
})
minetest.register_node("mesecons_extrawires:crossover_10", {
@ -77,6 +81,7 @@ minetest.register_node("mesecons_extrawires:crossover_10", {
"jeija_insulated_wire_ends_on.png"
},
paramtype = "light",
is_ground_content = false,
walkable = false,
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}},
@ -87,6 +92,7 @@ minetest.register_node("mesecons_extrawires:crossover_10", {
rules = crossover_get_rules(),
}
},
on_blast = mesecon.on_blastnode,
})
minetest.register_node("mesecons_extrawires:crossover_on", {
@ -101,6 +107,7 @@ minetest.register_node("mesecons_extrawires:crossover_on", {
"jeija_insulated_wire_ends_on.png"
},
paramtype = "light",
is_ground_content = false,
walkable = false,
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}},
@ -111,6 +118,7 @@ minetest.register_node("mesecons_extrawires:crossover_on", {
rules = crossover_get_rules(),
}
},
on_blast = mesecon.on_blastnode,
})
minetest.register_craft({

View File

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

View File

@ -26,7 +26,8 @@ local powered_def = mesecon.mergetable(minetest.registered_nodes["default:mese"]
offstate = "default:mese",
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

View File

@ -1,3 +1,5 @@
local screwdriver_exists = minetest.global_exists("screwdriver")
local tjunction_nodebox = {
type = "fixed",
fixed = {{ -16/32-0.001, -17/32, -3/32, 16/32+0.001, -13/32, 3/32 },
@ -34,6 +36,7 @@ minetest.register_node("mesecons_extrawires:tjunction_on", {
},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
walkable = false,
sunlight_propagates = true,
selection_box = tjunction_selectionbox,
@ -45,7 +48,9 @@ minetest.register_node("mesecons_extrawires:tjunction_on", {
state = mesecon.state.on,
rules = tjunction_get_rules,
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", {
@ -61,6 +66,7 @@ minetest.register_node("mesecons_extrawires:tjunction_off", {
},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
walkable = false,
sunlight_propagates = true,
selection_box = tjunction_selectionbox,
@ -71,7 +77,9 @@ minetest.register_node("mesecons_extrawires:tjunction_off", {
state = mesecon.state.off,
rules = tjunction_get_rules,
onstate = "mesecons_extrawires:tjunction_on"
}}
}},
on_blast = mesecon.on_blastnode,
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
})
minetest.register_craft({

View File

@ -81,6 +81,7 @@ mesecon.register_node("mesecons_extrawires:vertical", {
drawtype = "nodebox",
walkable = false,
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
selection_box = vertical_box,
node_box = vertical_box,
@ -112,6 +113,7 @@ mesecon.register_node("mesecons_extrawires:vertical_top", {
drawtype = "nodebox",
walkable = false,
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
groups = {dig_immediate=3, not_in_creative_inventory=1},
selection_box = top_box,
@ -142,6 +144,7 @@ mesecon.register_node("mesecons_extrawires:vertical_bottom", {
drawtype = "nodebox",
walkable = false,
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
selection_box = bottom_box,

View File

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

View File

@ -69,10 +69,11 @@ plg.register_nodes({
"jeija_fpga_sides.png"
},
inventory_image = "", -- replaced later
is_ground_content = false,
sunlight_propagates = true,
paramtype = "light",
walkable = true,
groups = {dig_immediate = 2, mesecon = 3},
groups = {dig_immediate = 2, mesecon = 3, overheat = 1},
drop = "mesecons_fpga:fpga0000",
selection_box = {
type = "fixed",
@ -116,6 +117,45 @@ plg.register_nodes({
after_dig_node = function(pos, node)
mesecon.receptor_off(pos, plg.rules[node.name])
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,
})
@ -270,6 +310,11 @@ plg.update = function(pos)
local meta = minetest.get_meta(pos)
if meta:get_int("valid") ~= 1 then
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
local is = lcore.deserialize(meta:get_string("instr"))

View File

@ -65,6 +65,7 @@ local function register_gate(name, inputnumber, assess, recipe, description)
inventory_image = "jeija_gate_off.png^jeija_gate_"..name..".png",
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
drawtype = "nodebox",
drop = basename.."_off",
selection_box = nodebox,

View File

@ -13,6 +13,7 @@ minetest.register_node("mesecons_hydroturbine:hydro_turbine_off", {
"jeija_hydro_turbine_turbine_misc_off.png"
},
inventory_image = "jeija_hydro_turbine_inv.png",
is_ground_content = false,
wield_scale = {x=0.75, y=0.75, z=0.75},
groups = {dig_immediate=2},
description="Water Turbine",
@ -24,11 +25,13 @@ minetest.register_node("mesecons_hydroturbine:hydro_turbine_off", {
sounds = default.node_sound_stone_defaults(),
mesecons = {receptor = {
state = mesecon.state.off
}}
}},
on_blast = mesecon.on_blastnode,
})
minetest.register_node("mesecons_hydroturbine:hydro_turbine_on", {
drawtype = "mesh",
is_ground_content = false,
mesh = "jeija_hydro_turbine_on.obj",
wield_scale = {x=0.75, y=0.75, z=0.75},
tiles = {
@ -51,7 +54,8 @@ minetest.register_node("mesecons_hydroturbine:hydro_turbine_on", {
sounds = default.node_sound_stone_defaults(),
mesecons = {receptor = {
state = mesecon.state.on
}}
}},
on_blast = mesecon.on_blastnode,
})
@ -70,7 +74,6 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_off"},
local waterpos={x=pos.x, y=pos.y+1, z=pos.z}
if is_flowing_water(waterpos) then
minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_on"})
nodeupdate(pos)
mesecon.receptor_on(pos)
end
end,
@ -84,7 +87,6 @@ nodenames = {"mesecons_hydroturbine:hydro_turbine_on"},
local waterpos={x=pos.x, y=pos.y+1, z=pos.z}
if not is_flowing_water(waterpos) then
minetest.set_node(pos, {name="mesecons_hydroturbine:hydro_turbine_off"})
nodeupdate(pos)
mesecon.receptor_off(pos)
end
end,

View File

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

View File

@ -1,3 +1,5 @@
local screwdriver_exists = minetest.global_exists("screwdriver")
local function insulated_wire_get_rules(node)
local rules = {{x = 1, y = 0, z = 0},
{x =-1, y = 0, z = 0}}
@ -20,6 +22,7 @@ minetest.register_node("mesecons_insulated:insulated_on", {
},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
walkable = false,
sunlight_propagates = true,
selection_box = {
@ -36,7 +39,9 @@ minetest.register_node("mesecons_insulated:insulated_on", {
state = mesecon.state.on,
offstate = "mesecons_insulated:insulated_off",
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", {
@ -52,6 +57,7 @@ minetest.register_node("mesecons_insulated:insulated_off", {
},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
walkable = false,
sunlight_propagates = true,
selection_box = {
@ -67,7 +73,9 @@ minetest.register_node("mesecons_insulated:insulated_off", {
state = mesecon.state.off,
onstate = "mesecons_insulated:insulated_on",
rules = insulated_wire_get_rules
}}
}},
on_blast = mesecon.on_blastnode,
on_rotate = screwdriver_exists and screwdriver.rotate_simple,
})
minetest.register_craft({

View File

@ -14,20 +14,23 @@ minetest.register_node("mesecons_lamp:lamp_on", {
tiles = {"jeija_meselamp_on.png"},
paramtype = "light",
paramtype2 = "wallmounted",
is_ground_content = false,
legacy_wallmounted = true,
sunlight_propagates = true,
walkable = true,
light_source = default.LIGHT_MAX,
light_source = minetest.LIGHT_MAX,
node_box = mesecon_lamp_box,
selection_box = mesecon_lamp_box,
groups = {dig_immediate=3,not_in_creative_inventory=1, mesecon_effector_on = 1},
drop="mesecons_lamp:lamp_off 1",
groups = {dig_immediate = 3,not_in_creative_inventory = 1, mesecon_effector_on = 1},
drop = "mesecons_lamp:lamp_off 1",
sounds = default.node_sound_glass_defaults(),
mesecons = {effector = {
action_off = function (pos, node)
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", {
@ -37,18 +40,21 @@ minetest.register_node("mesecons_lamp:lamp_off", {
wield_image = "jeija_meselamp.png",
paramtype = "light",
paramtype2 = "wallmounted",
is_ground_content = false,
sunlight_propagates = true,
walkable = true,
node_box = mesecon_lamp_box,
selection_box = mesecon_lamp_box,
groups = {dig_immediate=3, mesecon_receptor_off = 1, mesecon_effector_off = 1},
description="Mesecon Lamp",
description = "Mesecon Lamp",
sounds = default.node_sound_glass_defaults(),
mesecons = {effector = {
action_on = function (pos, node)
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({

View File

@ -20,7 +20,8 @@ function mesecon.lightstone_add(name, base_item, texture_off, texture_on, desc)
end
minetest.register_node("mesecons_lightstone:lightstone_" .. name .. "_off", {
tiles = {texture_off},
groups = {cracky=2, mesecon_effector_off = 1, mesecon = 2},
is_ground_content = false,
groups = {cracky = 2, mesecon_effector_off = 1, mesecon = 2},
description = desc,
sounds = default.node_sound_stone_defaults(),
mesecons = {effector = {
@ -28,20 +29,23 @@ function mesecon.lightstone_add(name, base_item, texture_off, texture_on, desc)
action_on = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_lightstone:lightstone_" .. name .. "_on", param2 = node.param2})
end,
}}
}},
on_blast = mesecon.on_blastnode,
})
minetest.register_node("mesecons_lightstone:lightstone_" .. name .. "_on", {
tiles = {texture_on},
groups = {cracky=2,not_in_creative_inventory=1, mesecon = 2},
drop = "mesecons_lightstone:lightstone_" .. name .. "_off",
light_source = default.LIGHT_MAX-2,
sounds = default.node_sound_stone_defaults(),
mesecons = {effector = {
rules = lightstone_rules,
action_off = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_lightstone:lightstone_" .. name .. "_off", param2 = node.param2})
end,
}}
tiles = {texture_on},
is_ground_content = false,
groups = {cracky = 2, not_in_creative_inventory = 1, mesecon = 2},
drop = "mesecons_lightstone:lightstone_" .. name .. "_off",
light_source = minetest.LIGHT_MAX - 2,
sounds = default.node_sound_stone_defaults(),
mesecons = {effector = {
rules = lightstone_rules,
action_off = function (pos, node)
minetest.swap_node(pos, {name = "mesecons_lightstone:lightstone_" .. name .. "_off", param2 = node.param2})
end,
}},
on_blast = mesecon.on_blastnode,
})
minetest.register_craft({
@ -61,3 +65,9 @@ mesecon.lightstone_add("blue", "dye:blue", "jeija_lightstone_blue_off.png", "jei
mesecon.lightstone_add("gray", "dye:grey", "jeija_lightstone_gray_off.png", "jeija_lightstone_gray_on.png", "Grey Lightstone")
mesecon.lightstone_add("darkgray", "dye:dark_grey", "jeija_lightstone_darkgray_off.png", "jeija_lightstone_darkgray_on.png", "Dark Grey Lightstone")
mesecon.lightstone_add("yellow", "dye:yellow", "jeija_lightstone_yellow_off.png", "jeija_lightstone_yellow_on.png", "Yellow Lightstone")
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.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 546 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 387 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 633 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 357 B

View File

@ -13,8 +13,10 @@
-- 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_states(pos, ports): Applies new port states to a Luacontroller at pos
-- run(pos): runs the code in the controller at pos
-- reset_meta(pos, code, errmsg): performs a software-reset, installs new code and prints error messages
-- run_inner(pos, code, event): runs code on the controller at pos and event
-- 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 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
--
-- The Sandbox
@ -141,7 +143,7 @@ local function set_port_states(pos, ports)
-- Solution / Workaround:
-- Remember which output was turned off and ignore next "off" event.
local meta = minetest.get_meta(pos)
local ign = minetest.deserialize(meta:get_string("ignore_offevents")) or {}
local ign = minetest.deserialize(meta:get_string("ignore_offevents"), true) or {}
if ports.a and not vports.a and not mesecon.is_powered(pos, rules.a) then ign.A = true end
if ports.b and not vports.b and not mesecon.is_powered(pos, rules.b) then ign.B = true end
if ports.c and not vports.c and not mesecon.is_powered(pos, rules.c) then ign.C = true end
@ -183,7 +185,7 @@ end
local function ignore_event(event, meta)
if event.type ~= "off" then return false end
local ignore_offevents = minetest.deserialize(meta:get_string("ignore_offevents")) or {}
local ignore_offevents = minetest.deserialize(meta:get_string("ignore_offevents"), true) or {}
if ignore_offevents[event.pin.name] then
ignore_offevents[event.pin.name] = nil
meta:set_string("ignore_offevents", minetest.serialize(ignore_offevents))
@ -236,6 +238,7 @@ local function remove_functions(x)
local seen = {}
local function rfuncs(x)
if x == nil then return end
if seen[x] then return end
seen[x] = true
if type(x) ~= "table" then return end
@ -259,37 +262,149 @@ local function remove_functions(x)
return x
end
local function get_interrupt(pos)
-- itbl: Flat table of functions to run after sandbox cleanup, used to prevent various security hazards
local function get_interrupt(pos, itbl, send_warning)
-- iid = interrupt id
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
local luac_id = minetest.get_meta(pos):get_int("luac_id")
mesecon.queue:add_action(pos, "lc_interrupt", {luac_id, iid}, time, iid, 1)
table.insert(itbl, function ()
-- Outside string metatable sandbox, can safely run this now
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
return interrupt
end
local function get_digiline_send(pos)
if not digiline then return end
-- Given a message object passed to digiline_send, clean it up into a form
-- which is safe to transmit over the network and compute its "cost" (a very
-- 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)
-- 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
if (type(channel) ~= "string" and type(channel) ~= "number" and type(channel) ~= "boolean") then
if type(channel) == "string" 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
end
-- It is technically possible to send functions over the wire since
-- the high performance impact of stripping those from the data has
-- been decided to not be worth the added realism.
-- 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
local msg_cost
msg, msg_cost = clean_and_weigh_digiline_message(msg)
if msg == nil or msg_cost > maxlen then
send_warning("Message was too complex, or contained invalid data.")
return false
end
minetest.after(0, function()
digiline:receptor_send(pos, digiline.rules.default, channel, msg)
table.insert(itbl, function ()
-- Runs outside of string metatable sandbox
local luac_id = minetest.get_meta(pos):get_int("luac_id")
mesecon.queue:add_action(pos, "lc_digiline_relay", {channel, luac_id, msg})
end)
return true
end
@ -297,11 +412,12 @@ end
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",
"tonumber", "tostring", "type", "unpack", "_VERSION"
}
local function create_environment(pos, mem, event)
local function create_environment(pos, mem, event, itbl, send_warning)
-- Gather variables for the environment
local vports = minetest.registered_nodes[minetest.get_node(pos).name].virtual_portstates
local vports_copy = {}
@ -318,8 +434,8 @@ local function create_environment(pos, mem, event)
heat = mesecon.get_heat(pos),
heat_max = mesecon.setting("overheat_max", 20),
print = safe_print,
interrupt = get_interrupt(pos),
digiline_send = get_digiline_send(pos),
interrupt = get_interrupt(pos, itbl, send_warning),
digiline_send = get_digiline_send(pos, itbl, send_warning),
string = {
byte = string.byte,
char = string.char,
@ -407,10 +523,11 @@ local function create_sandbox(code, env)
jit.off(f, true)
end
local maxevents = mesecon.setting("luacontroller_maxevents", 10000)
return function(...)
-- NOTE: This runs within string metatable sandbox, so the setting's been moved out for safety
-- Use instruction counter to stop execution
-- after luacontroller_maxevents
local maxevents = mesecon.setting("luacontroller_maxevents", 10000)
debug.sethook(timeout, "", maxevents)
local ok, ret = pcall(f, ...)
debug.sethook() -- Clear hook
@ -421,7 +538,7 @@ end
local function load_memory(meta)
return minetest.deserialize(meta:get_string("lc_memory")) or {}
return minetest.deserialize(meta:get_string("lc_memory"), true) or {}
end
@ -438,26 +555,42 @@ local function save_memory(pos, meta, mem)
end
end
local function run(pos, event)
-- Returns success (boolean), errmsg (string)
-- run (as opposed to run_inner) is responsible for setting up meta according to this output
local function run_inner(pos, code, event)
local meta = minetest.get_meta(pos)
if overheat(pos) then return end
if ignore_event(event, meta) then return end
-- Note: These return success, presumably to avoid changing LC ID.
if overheat(pos) then return true, "" end
if ignore_event(event, meta) then return true, "" end
-- Load code & mem from meta
local mem = load_memory(meta)
local code = meta:get_string("code")
-- 'Last warning' label.
local warning = ""
local function send_warning(str)
warning = "Warning: " .. str
end
-- Create environment
local env = create_environment(pos, mem, event)
local itbl = {}
local env = create_environment(pos, mem, event, itbl, send_warning)
-- Create the sandbox and execute code
local f, msg = create_sandbox(code, env)
if not f then return msg end
if not f then return false, 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)
if not success then return msg end
onetruestring.__index = string
-- End string true sandboxing
if not success then return false, msg end
if type(env.port) ~= "table" then
return "Ports set are invalid."
return false, "Ports set are invalid."
end
-- Actually set the ports
@ -465,17 +598,18 @@ local function run(pos, event)
-- Save memory. This may burn the luacontroller if a memory overflow occurs.
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
mesecon.queue:add_function("lc_interrupt", function (pos, luac_id, iid)
-- 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.registered_nodes[minetest.get_node(pos).name].is_burnt) then return end
run(pos, {type="interrupt", iid = iid})
end)
local function reset_meta(pos, code, errmsg)
local meta = minetest.get_meta(pos)
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 ""))
@ -485,13 +619,50 @@ local function reset_meta(pos, code, errmsg)
"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)
-- 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.registered_nodes[minetest.get_node(pos).name].is_burnt) then return end
run(pos, {type="interrupt", iid = iid})
end)
mesecon.queue:add_function("lc_digiline_relay", function (pos, channel, luac_id, msg)
if not digiline then return end
-- This check is only really necessary because in case of server crash, old actions can be thrown into the future
if (minetest.get_meta(pos):get_int("luac_id") ~= luac_id) then return end
if (minetest.registered_nodes[minetest.get_node(pos).name].is_burnt) then return end
-- The actual work
digiline:receptor_send(pos, digiline.rules.default, channel, msg)
end)
-----------------------
-- Node Registration --
@ -518,10 +689,23 @@ local digiline = {
receptor = {},
effector = {
action = function(pos, node, channel, msg)
msg = clean_and_weigh_digiline_message(msg)
run(pos, {type = "digiline", channel = channel, msg = msg})
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)
if not fields.program then
return
@ -531,12 +715,10 @@ local function on_receive_fields(pos, form_name, fields, sender)
minetest.record_protection_violation(pos, name)
return
end
reset(pos)
reset_meta(pos, fields.code)
local err = run(pos, {type="program"})
if err then
print(err)
reset_meta(pos, fields.code, err)
local ok, err = set_program(pos, fields.code)
if not ok then
-- it's not an error from the server perspective
minetest.log("action", "Lua controller programming error: " .. err)
end
end
@ -590,7 +772,11 @@ for d = 0, 1 do
receptor = {
state = mesecon.state.on,
rules = output_rules[cid]
}
},
luacontroller = {
get_program = get_program,
set_program = set_program,
},
}
minetest.register_node(node_name, {
@ -606,6 +792,7 @@ for d = 0, 1 do
},
inventory_image = top,
paramtype = "light",
is_ground_content = false,
groups = groups,
drop = BASENAME.."0000",
sunlight_propagates = true,
@ -629,6 +816,7 @@ for d = 0, 1 do
mesecon.receptor_off(pos, output_rules)
end,
is_luacontroller = true,
on_blast = mesecon.on_blastnode,
})
end
end
@ -652,6 +840,7 @@ minetest.register_node(BASENAME .. "_burnt", {
inventory_image = "jeija_luacontroller_burnt_top.png",
is_burnt = true,
paramtype = "light",
is_ground_content = false,
groups = {dig_immediate=2, not_in_creative_inventory=1},
drop = BASENAME.."0000",
sunlight_propagates = true,
@ -669,6 +858,7 @@ minetest.register_node(BASENAME .. "_burnt", {
end,
},
},
on_blast = mesecon.on_blastnode,
})
------------------------

View File

@ -69,6 +69,7 @@ minetest.register_node(nodename, {
sunlight_propagates = true,
paramtype = "light",
is_ground_content = false,
walkable = true,
groups = groups,
drop = "mesecons_microcontroller:microcontroller0000 1",
@ -138,20 +139,34 @@ minetest.register_node(nodename, {
rules = microc_rules[node.name]
mesecon.receptor_off(pos, rules)
end,
on_blast = mesecon.on_blastnode,
})
end
end
end
end
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', ''},
}
})
if minetest.get_modpath("mesecons_luacontroller") then
minetest.register_craft({
type = "shapeless",
output = "mesecons_microcontroller:microcontroller0000",
recipe = {"mesecons_luacontroller:luacontroller0000"},
})
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.action(pos, {a=false, b=false, c=false, d=false})

View File

@ -8,124 +8,154 @@
-- Pushes all block in front of it
-- Pull all blocks in its back
function mesecon.get_movestone_direction(pos)
local lpos
local rules = {
{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}}
-- settings:
local timer_interval = 1 / mesecon.setting("movestone_speed", 3)
local max_push = mesecon.setting("movestone_max_push", 50)
local max_pull = mesecon.setting("movestone_max_pull", 50)
lpos = {x=pos.x+1, y=pos.y, z=pos.z}
for n = 1, 3 do
if mesecon.is_power_on(lpos, rules[n]) then
return {x=0, y=0, z=-1}
-- helper functions:
local function get_movestone_direction(rulename, is_vertical)
if is_vertical then
if rulename.z > 0 then
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
lpos = {x = pos.x-1, y = pos.y, z = pos.z}
for n=4, 6 do
if mesecon.is_power_on(lpos, rules[n]) then
return {x=0, y=0, z=1}
end
end
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}
else
if rulename.z > 0 then
return {x = -1, y = 0, z = 0}
elseif rulename.z < 0 then
return {x = 1, y = 0, z = 0}
elseif rulename.x > 0 then
return {x = 0, y = 0, z = -1}
elseif rulename.x < 0 then
return {x = 0, y = 0, z = 1}
end
end
end
function mesecon.register_movestone(name, def, is_sticky)
local timer_interval = 1 / mesecon.setting("movestone_speed", 3)
local name_active = name.."_active"
local function movestone_move (pos)
if minetest.get_node(pos).name ~= name_active then
return
end
local direction = mesecon.get_movestone_direction(pos)
if not direction then
minetest.set_node(pos, {name = name})
return
end
-- registration functions:
function mesecon.register_movestone(name, def, is_sticky, is_vertical)
local function movestone_move(pos, node, rulename)
local direction = get_movestone_direction(rulename, is_vertical)
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)
local success, stack, oldstack = mesecon.mvps_push(frontpos, direction, max_push)
if not success then
minetest.get_node_timer(pos):start(timer_interval)
return
end
mesecon.mvps_move_objects(frontpos, direction, oldstack)
-- ### Step 2: Move the movestone ###
local node = minetest.get_node(pos)
minetest.set_node(frontpos, node)
minetest.remove_node(pos)
mesecon.on_dignode(pos, node)
mesecon.on_placenode(frontpos, node)
minetest.after(timer_interval, movestone_move, frontpos)
minetest.get_node_timer(frontpos):start(timer_interval)
-- ### Step 3: If sticky, pull stack behind ###
if is_sticky then
mesecon.mvps_pull_all(backpos, direction, maxpull)
if not is_sticky then
return
end
local backpos = vector.subtract(pos, direction)
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
def.is_ground_content = false
def.mesecons = {effector = {
action_on = function (pos)
if minetest.get_node(pos).name ~= name_active then
minetest.set_node(pos, {name = name_active})
movestone_move(pos)
action_on = function(pos, node, rulename)
if rulename and not minetest.get_node_timer(pos):is_started() then
movestone_move(pos, node, rulename)
end
end,
action_off = function (pos)
minetest.set_node(pos, {name = name})
end
rules = mesecon.rules.default,
}}
def.drop = name
def.on_timer = function(pos, elapsed)
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)
-- 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
mesecon.register_movestone("mesecons_movestones:movestone", {
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"},
groups = {cracky=3},
description="Movestone",
sounds = default.node_sound_stone_defaults()
}, false)
-- registration:
mesecon.register_movestone("mesecons_movestones:movestone", {
tiles = {
"jeija_movestone_side.png",
"jeija_movestone_side.png",
"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()
}, 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({
output = "mesecons_movestones:movestone 2",
recipe = {
@ -135,15 +165,32 @@ minetest.register_craft({
}
})
-- STICKY_MOVESTONE
mesecon.register_movestone("mesecons_movestones:sticky_movestone", {
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"},
inventory_image = minetest.inventorycube("jeija_sticky_movestone.png", "jeija_movestone_side.png", "jeija_movestone_side.png"),
groups = {cracky=3},
description="Sticky Movestone",
sounds = default.node_sound_stone_defaults(),
}, true)
-- conversation:
minetest.register_craft({
type = "shapeless",
output = "mesecons_movestones:movestone",
recipe = {"mesecons_movestones:movestone_vertical"},
})
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({
output = "mesecons_movestones:sticky_movestone",
recipe = {
@ -151,6 +198,18 @@ minetest.register_craft({
}
})
-- Don't allow pushing movestones while they're active
mesecon.register_mvps_stopper("mesecons_movestones:movestone_active")
mesecon.register_mvps_stopper("mesecons_movestones:sticky_movestone_active")
minetest.register_craft({
output = "mesecons_movestones:sticky_movestone_vertical",
recipe = {
{"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,6 +165,10 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
-- remove all nodes
for _, n in ipairs(nodes) do
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)
end
@ -179,6 +183,9 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
minetest.set_node(np, n.node)
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
local moved_nodes = {}
@ -190,6 +197,7 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
moved_nodes[i].pos = nodes[i].pos
moved_nodes[i].node = nodes[i].node
moved_nodes[i].meta = nodes[i].meta
moved_nodes[i].node_timer = nodes[i].node_timer
end
on_mvps_move(moved_nodes)
@ -197,45 +205,56 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti
return true, nodes, oldstack
end
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)
function mesecon.mvps_move_objects(pos, dir, nodestack, movefactor)
local objects_to_move = {}
-- Move object at tip of stack, pushpos is position at tip of stack
local pushpos = vector.add(pos, vector.multiply(dir, #nodestack))
local objects = minetest.get_objects_inside_radius(pushpos, 1)
for _, obj in ipairs(objects) do
table.insert(objects_to_move, obj)
end
-- Move objects lying/standing on the stack (before it was pushed - oldstack)
if tonumber(minetest.settings: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
local dir_k
local dir_l
for k, v in pairs(dir) do
if v ~= 0 then
dir_k = k
dir_l = v
break
end
end
for _, obj in ipairs(objects_to_move) do
local entity = obj:get_luaentity()
if not entity or not mesecon.is_mvps_unmov(entity.name) then
local np = vector.add(obj:getpos(), dir)
--move only if destination is not solid
local nn = minetest.get_node(np)
if not ((not minetest.registered_nodes[nn.name])
or minetest.registered_nodes[nn.name].walkable) then
obj:setpos(np)
movefactor = movefactor or 1
dir = vector.multiply(dir, movefactor)
for id, obj in pairs(minetest.object_refs) do
local obj_pos = obj:getpos()
local cbox = obj:get_properties().collisionbox
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]))
local ok = true
for k, v in pairs(pos) do
local edge1, edge2
if k ~= dir_k then
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
@ -247,3 +266,18 @@ mesecon.register_mvps_stopper("doors:door_steel_b_2")
mesecon.register_mvps_stopper("doors:door_steel_t_2")
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,6 +1,7 @@
minetest.register_node("mesecons_noteblock:noteblock", {
description = "Noteblock",
tiles = {"mesecons_noteblock.png"},
is_ground_content = false,
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2},
on_punch = function(pos, node) -- change sound when punched
node.param2 = (node.param2+1)%12
@ -12,7 +13,8 @@ minetest.register_node("mesecons_noteblock:noteblock", {
action_on = function(pos, node)
mesecon.noteblock_play(pos, node.param2)
end
}}
}},
on_blast = mesecon.on_blastnode,
})
minetest.register_craft({

View File

@ -1,65 +1,63 @@
local specs = {
normal = {
offname = "mesecons_pistons:piston_normal_off",
onname = "mesecons_pistons:piston_normal_on",
pusher = "mesecons_pistons:piston_pusher_normal",
},
sticky = {
offname = "mesecons_pistons:piston_sticky_off",
onname = "mesecons_pistons:piston_sticky_on",
pusher = "mesecons_pistons:piston_pusher_sticky",
sticky = true,
},
}
local function get_pistonspec_name(name, part)
if part then
for spec_name, spec in pairs(specs) do
if name == spec[part] then
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
local function get_pistonspec(name, part)
return specs[get_pistonspec_name(name, part)]
end
local max_push = mesecon.setting("piston_max_push", 15)
local max_pull = mesecon.setting("piston_max_pull", 15)
-- Get mesecon rules of pistons
local piston_rules = {
{x=0, y=0, z=1}, --everything apart from z- (pusher side)
{x=1, y=0, z=0},
{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=0, y=1, z=1},
{x=0, y=-1, z=1}
}
local piston_up_rules = {
{x=0, y=0, z=-1}, --everything apart from y+ (pusher side)
{x=1, y=0, z=0},
{x=-1, y=0, z=0},
{x=0, y=0, z=1},
{x=1, y=-1, z=0},
{x=-1, y=-1, z=0},
{x=0, y=-1, z=1},
{x=0, y=-1, z=-1}
}
local piston_down_rules = {
{x=0, y=0, z=-1}, --everything apart from y- (pusher side)
{x=1, y=0, z=0},
{x=-1, y=0, z=0},
{x=0, y=0, z=1},
{x=1, y=1, z=0},
{x=-1, y=1, z=0},
{x=0, y=1, z=1},
{x=0, y=1, z=-1}
}
local function piston_get_rules(node)
local rules = piston_rules
for i = 1, node.param2 do
rules = mesecon.rotate_rules_left(rules)
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_facedir_direction(node)
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
local function piston_get_direction(dir, node)
if type(dir) == "function" then
return dir(node)
else
return dir
end
end
local piston_remove_pusher = function(pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local dir = piston_get_direction(pistonspec.dir, node)
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 pusherpos = vector.add(pos, dir)
local pushername = minetest.get_node(pusherpos).name
@ -74,67 +72,166 @@ local piston_remove_pusher = function(pos, node)
max_hear_distance = 20,
gain = 0.3,
})
nodeupdate(pusherpos)
minetest.check_for_falling(pusherpos)
end
local piston_on = function(pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local dir = piston_get_direction(pistonspec.dir, node)
local np = vector.add(pos, dir)
local maxpush = mesecon.setting("piston_max_push", 15)
local success, stack, oldstack = mesecon.mvps_push(np, dir, maxpush)
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)
local pistonspec = get_pistonspec(node.name, "offname")
local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
local pusher_pos = vector.add(pos, dir)
local success, stack, oldstack = mesecon.mvps_push(pusher_pos, dir, max_push)
if not success then
return
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
local piston_off = function(pos, node)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
local function piston_off(pos, node)
local pistonspec = get_pistonspec(node.name, "onname")
minetest.set_node(pos, {param2 = node.param2, name = pistonspec.offname})
piston_remove_pusher(pos, node)
if pistonspec.sticky then
local maxpull = mesecon.setting("piston_max_pull", 15)
local dir = piston_get_direction(pistonspec.dir, node)
local pullpos = vector.add(pos, vector.multiply(dir, 2))
local stack = mesecon.mvps_pull_single(pullpos, vector.multiply(dir, -1), maxpull)
mesecon.mvps_process_stack(pos, dir, stack)
if not pistonspec.sticky then
return
end
local dir = minetest.facedir_to_dir(node.param2)
local pullpos = vector.add(pos, vector.multiply(dir, -2))
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
local piston_orientate = function(pos, placer)
-- not placed by player
if not placer then return end
-- placer pitch in degrees
local pitch = placer:get_look_pitch() * (180 / math.pi)
local orientations = {
[0] = { 4, 8},
{13, 17},
{10, 6},
{20, 15},
}
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)
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
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
-- looking upwards (pitch > 55) / looking downwards (pitch < -55)
local nn = nil
if pitch > 55 then nn = {name = pistonspec.piston_down} end
if pitch < -55 then nn = {name = pistonspec.piston_up} end
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},
}
if nn then
minetest.set_node(pos, nn)
-- minetest.after, because on_placenode for unoriented piston must be processed first
minetest.after(0, mesecon.on_placenode, pos, nn)
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
-- Horizontal pistons
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
@ -143,28 +240,18 @@ local piston_pusher_box = {
fixed = {
{-2/16, -2/16, -.5 + pt, 2/16, 2/16, .5 + pt},
{-.5 , -.5 , -.5 , .5 , .5 , -.5 + pt},
}
},
}
local piston_on_box = {
type = "fixed",
fixed = {
{-.5, -.5, -.5 + pt, .5, .5, .5}
}
},
}
-- 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",
piston_down = "mesecons_pistons:piston_down_normal_off",
piston_up = "mesecons_pistons:piston_up_normal_off",
}
-- Normal (non-sticky) Pistons:
-- offstate
minetest.register_node("mesecons_pistons:piston_normal_off", {
description = "Piston",
@ -175,20 +262,23 @@ minetest.register_node("mesecons_pistons:piston_normal_off", {
"mesecons_piston_right.png",
"mesecons_piston_back.png",
"mesecons_piston_pusher_front.png"
},
},
groups = {cracky = 3},
paramtype2 = "facedir",
is_ground_content = false,
after_place_node = piston_orientate,
mesecons_piston = pistonspec_normal,
sounds = default.node_sound_wood_defaults(),
mesecons = {effector={
action_on = piston_on,
rules = piston_get_rules
}}
rules = piston_get_rules,
}},
on_rotate = piston_rotate,
on_blast = mesecon.on_blastnode,
})
-- onstate
minetest.register_node("mesecons_pistons:piston_normal_on", {
description = "Activated Piston Base",
drawtype = "nodebox",
tiles = {
"mesecons_piston_top.png",
@ -197,26 +287,27 @@ minetest.register_node("mesecons_pistons:piston_normal_on", {
"mesecons_piston_right.png",
"mesecons_piston_back.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},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
drop = "mesecons_pistons:piston_normal_off",
after_dig_node = piston_remove_pusher,
node_box = piston_on_box,
selection_box = piston_on_box,
mesecons_piston = pistonspec_normal,
sounds = default.node_sound_wood_defaults(),
mesecons = {effector={
action_off = piston_off,
rules = piston_get_rules
}}
rules = piston_get_rules,
}},
on_rotate = piston_rotate_on,
on_blast = mesecon.on_blastnode,
})
-- pusher
minetest.register_node("mesecons_pistons:piston_pusher_normal", {
description = "Piston Pusher",
drawtype = "nodebox",
tiles = {
"mesecons_piston_pusher_top.png",
@ -225,27 +316,19 @@ minetest.register_node("mesecons_pistons:piston_pusher_normal", {
"mesecons_piston_pusher_right.png",
"mesecons_piston_pusher_back.png",
"mesecons_piston_pusher_front.png"
},
},
groups = {not_in_creative_inventory = 1},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
diggable = false,
corresponding_piston = "mesecons_pistons:piston_normal_on",
selection_box = piston_pusher_box,
node_box = piston_pusher_box,
on_rotate = piston_rotate_pusher,
drop = "",
})
-- 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,
piston_down = "mesecons_pistons:piston_down_sticky_off",
piston_up = "mesecons_pistons:piston_up_sticky_off",
}
-- offstate
minetest.register_node("mesecons_pistons:piston_sticky_off", {
description = "Sticky Piston",
@ -256,20 +339,23 @@ minetest.register_node("mesecons_pistons:piston_sticky_off", {
"mesecons_piston_right.png",
"mesecons_piston_back.png",
"mesecons_piston_pusher_front_sticky.png"
},
},
groups = {cracky = 3},
paramtype2 = "facedir",
is_ground_content = false,
after_place_node = piston_orientate,
mesecons_piston = pistonspec_sticky,
sounds = default.node_sound_wood_defaults(),
mesecons = {effector={
action_on = piston_on,
rules = piston_get_rules
}}
rules = piston_get_rules,
}},
on_rotate = piston_rotate,
on_blast = mesecon.on_blastnode,
})
-- onstate
minetest.register_node("mesecons_pistons:piston_sticky_on", {
description = "Activated Sticky Piston Base",
drawtype = "nodebox",
tiles = {
"mesecons_piston_top.png",
@ -278,26 +364,27 @@ minetest.register_node("mesecons_pistons:piston_sticky_on", {
"mesecons_piston_right.png",
"mesecons_piston_back.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},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
drop = "mesecons_pistons:piston_sticky_off",
after_dig_node = piston_remove_pusher,
node_box = piston_on_box,
selection_box = piston_on_box,
mesecons_piston = pistonspec_sticky,
sounds = default.node_sound_wood_defaults(),
mesecons = {effector={
action_off = piston_off,
rules = piston_get_rules
}}
rules = piston_get_rules,
}},
on_rotate = piston_rotate_on,
on_blast = mesecon.on_blastnode,
})
-- pusher
minetest.register_node("mesecons_pistons:piston_pusher_sticky", {
description = "Sticky Piston Pusher",
drawtype = "nodebox",
tiles = {
"mesecons_piston_pusher_top.png",
@ -306,399 +393,37 @@ minetest.register_node("mesecons_pistons:piston_pusher_sticky", {
"mesecons_piston_pusher_right.png",
"mesecons_piston_pusher_back.png",
"mesecons_piston_pusher_front_sticky.png"
},
},
groups = {not_in_creative_inventory = 1},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
diggable = false,
corresponding_piston = "mesecons_pistons:piston_sticky_on",
selection_box = piston_pusher_box,
node_box = piston_pusher_box,
})
--
--
-- UP
--
--
local piston_up_pusher_box = {
type = "fixed",
fixed = {
{-2/16, -.5 - pt, -2/16, 2/16, .5 - pt, 2/16},
{-.5 , .5 - pt, -.5 , .5 , .5 , .5},
}
}
local piston_up_on_box = {
type = "fixed",
fixed = {
{-.5, -.5, -.5 , .5, .5-pt, .5}
}
}
-- Normal
local pistonspec_normal_up = {
offname = "mesecons_pistons:piston_up_normal_off",
onname = "mesecons_pistons:piston_up_normal_on",
dir = {x = 0, y = 1, z = 0},
pusher = "mesecons_pistons:piston_up_pusher_normal"
}
-- offstate
minetest.register_node("mesecons_pistons:piston_up_normal_off", {
tiles = {
"mesecons_piston_pusher_front.png",
"mesecons_piston_back.png",
"mesecons_piston_left.png^[transformR270",
"mesecons_piston_right.png^[transformR90",
"mesecons_piston_bottom.png",
"mesecons_piston_top.png^[transformR180",
},
inventory_image = "mesecons_piston_top.png",
wield_image = "mesecons_piston_top.png",
groups = {cracky = 3, not_in_creative_inventory = 1},
paramtype2 = "facedir",
drop = "mesecons_pistons:piston_normal_off",
mesecons_piston = pistonspec_normal_up,
mesecons = {effector={
action_on = piston_on,
rules = piston_up_rules,
}}
})
-- onstate
minetest.register_node("mesecons_pistons:piston_up_normal_on", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_on_front.png",
"mesecons_piston_back.png",
"mesecons_piston_left.png^[transformR270",
"mesecons_piston_right.png^[transformR90",
"mesecons_piston_bottom.png",
"mesecons_piston_top.png^[transformR180",
},
inventory_image = "mesecons_piston_top.png",
wield_image = "mesecons_piston_top.png",
groups = {cracky = 3, not_in_creative_inventory = 1},
paramtype = "light",
paramtype2 = "facedir",
drop = "mesecons_pistons:piston_normal_off",
after_dig_node = piston_remove_pusher,
node_box = piston_up_on_box,
selection_box = piston_up_on_box,
mesecons_piston = pistonspec_normal_up,
sounds = default.node_sound_wood_defaults(),
mesecons = {effector={
action_off = piston_off,
rules = piston_up_rules,
}}
})
-- pusher
minetest.register_node("mesecons_pistons:piston_up_pusher_normal", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_pusher_front.png",
"mesecons_piston_pusher_back.png",
"mesecons_piston_pusher_left.png^[transformR270",
"mesecons_piston_pusher_right.png^[transformR90",
"mesecons_piston_pusher_bottom.png",
"mesecons_piston_pusher_top.png^[transformR180",
},
paramtype = "light",
paramtype2 = "facedir",
diggable = false,
corresponding_piston = "mesecons_pistons:piston_up_normal_on",
selection_box = piston_up_pusher_box,
node_box = piston_up_pusher_box,
})
-- Sticky
local pistonspec_sticky_up = {
offname = "mesecons_pistons:piston_up_sticky_off",
onname = "mesecons_pistons:piston_up_sticky_on",
dir = {x = 0, y = 1, z = 0},
pusher = "mesecons_pistons:piston_up_pusher_sticky",
sticky = true
}
-- offstate
minetest.register_node("mesecons_pistons:piston_up_sticky_off", {
tiles = {
"mesecons_piston_pusher_front_sticky.png",
"mesecons_piston_back.png",
"mesecons_piston_left.png^[transformR270",
"mesecons_piston_right.png^[transformR90",
"mesecons_piston_bottom.png",
"mesecons_piston_top.png^[transformR180",
"mesecons_piston_tb.png"
},
inventory_image = "mesecons_piston_top.png",
wield_image = "mesecons_piston_top.png",
groups = {cracky = 3, not_in_creative_inventory = 1},
paramtype2 = "facedir",
drop = "mesecons_pistons:piston_sticky_off",
mesecons_piston = pistonspec_sticky_up,
sounds = default.node_sound_wood_defaults(),
mesecons = {effector={
action_on = piston_on,
rules = piston_up_rules,
}}
})
-- onstate
minetest.register_node("mesecons_pistons:piston_up_sticky_on", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_on_front.png",
"mesecons_piston_back.png",
"mesecons_piston_left.png^[transformR270",
"mesecons_piston_right.png^[transformR90",
"mesecons_piston_bottom.png",
"mesecons_piston_top.png^[transformR180",
},
inventory_image = "mesecons_piston_top.png",
wield_image = "mesecons_piston_top.png",
groups = {cracky = 3, not_in_creative_inventory = 1},
paramtype = "light",
paramtype2 = "facedir",
drop = "mesecons_pistons:piston_normal_off",
after_dig_node = piston_remove_pusher,
node_box = piston_up_on_box,
selection_box = piston_up_on_box,
mesecons_piston = pistonspec_sticky_up,
sounds = default.node_sound_wood_defaults(),
mesecons = {effector={
action_off = piston_off,
rules = piston_up_rules,
}}
})
-- pusher
minetest.register_node("mesecons_pistons:piston_up_pusher_sticky", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_pusher_front_sticky.png",
"mesecons_piston_pusher_back.png",
"mesecons_piston_pusher_left.png^[transformR270",
"mesecons_piston_pusher_right.png^[transformR90",
"mesecons_piston_pusher_bottom.png",
"mesecons_piston_pusher_top.png^[transformR180",
},
paramtype = "light",
paramtype2 = "facedir",
diggable = false,
corresponding_piston = "mesecons_pistons:piston_up_sticky_on",
selection_box = piston_up_pusher_box,
node_box = piston_up_pusher_box,
})
--
--
-- DOWN
--
--
local piston_down_pusher_box = {
type = "fixed",
fixed = {
{-2/16, -.5 + pt, -2/16, 2/16, .5 + pt, 2/16},
{-.5 , -.5 , -.5 , .5 , -.5 + pt, .5},
}
}
local piston_down_on_box = {
type = "fixed",
fixed = {
{-.5, -.5+pt, -.5 , .5, .5, .5}
}
}
-- Normal
local pistonspec_normal_down = {
offname = "mesecons_pistons:piston_down_normal_off",
onname = "mesecons_pistons:piston_down_normal_on",
dir = {x = 0, y = -1, z = 0},
pusher = "mesecons_pistons:piston_down_pusher_normal",
}
-- offstate
minetest.register_node("mesecons_pistons:piston_down_normal_off", {
tiles = {
"mesecons_piston_back.png",
"mesecons_piston_pusher_front.png",
"mesecons_piston_left.png^[transformR90",
"mesecons_piston_right.png^[transformR270",
"mesecons_piston_bottom.png^[transformR180",
"mesecons_piston_top.png",
},
inventory_image = "mesecons_piston_top.png",
wield_image = "mesecons_piston_top.png",
groups = {cracky = 3, not_in_creative_inventory = 1},
paramtype2 = "facedir",
drop = "mesecons_pistons:piston_normal_off",
mesecons_piston = pistonspec_normal_down,
sounds = default.node_sound_wood_defaults(),
mesecons = {effector={
action_on = piston_on,
rules = piston_down_rules,
}}
})
-- onstate
minetest.register_node("mesecons_pistons:piston_down_normal_on", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_back.png",
"mesecons_piston_on_front.png",
"mesecons_piston_left.png^[transformR90",
"mesecons_piston_right.png^[transformR270",
"mesecons_piston_bottom.png^[transformR180",
"mesecons_piston_top.png",
},
inventory_image = "mesecons_piston_top.png",
wield_image = "mesecons_piston_top.png",
groups = {cracky = 3, not_in_creative_inventory = 1},
paramtype = "light",
paramtype2 = "facedir",
drop = "mesecons_pistons:piston_normal_off",
after_dig_node = piston_remove_pusher,
node_box = piston_down_on_box,
selection_box = piston_down_on_box,
mesecons_piston = pistonspec_normal_down,
sounds = default.node_sound_wood_defaults(),
mesecons = {effector={
action_off = piston_off,
rules = piston_down_rules,
}}
})
-- pusher
minetest.register_node("mesecons_pistons:piston_down_pusher_normal", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_pusher_back.png",
"mesecons_piston_pusher_front.png",
"mesecons_piston_pusher_left.png^[transformR90",
"mesecons_piston_pusher_right.png^[transformR270",
"mesecons_piston_pusher_bottom.png^[transformR180",
"mesecons_piston_pusher_top.png",
},
paramtype = "light",
paramtype2 = "facedir",
diggable = false,
corresponding_piston = "mesecons_pistons:piston_down_normal_on",
selection_box = piston_down_pusher_box,
node_box = piston_down_pusher_box,
})
-- Sticky
local pistonspec_sticky_down = {
onname = "mesecons_pistons:piston_down_sticky_on",
offname = "mesecons_pistons:piston_down_sticky_off",
dir = {x = 0, y = -1, z = 0},
pusher = "mesecons_pistons:piston_down_pusher_sticky",
sticky = true
}
-- offstate
minetest.register_node("mesecons_pistons:piston_down_sticky_off", {
tiles = {
"mesecons_piston_back.png",
"mesecons_piston_pusher_front_sticky.png",
"mesecons_piston_left.png^[transformR90",
"mesecons_piston_right.png^[transformR270",
"mesecons_piston_bottom.png^[transformR180",
"mesecons_piston_top.png",
},
inventory_image = "mesecons_piston_top.png",
wield_image = "mesecons_piston_top.png",
groups = {cracky = 3, not_in_creative_inventory = 1},
paramtype2 = "facedir",
drop = "mesecons_pistons:piston_sticky_off",
mesecons_piston = pistonspec_sticky_down,
sounds = default.node_sound_wood_defaults(),
mesecons = {effector={
action_on = piston_on,
rules = piston_down_rules,
}}
})
-- onstate
minetest.register_node("mesecons_pistons:piston_down_sticky_on", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_back.png",
"mesecons_piston_on_front.png",
"mesecons_piston_left.png^[transformR90",
"mesecons_piston_right.png^[transformR270",
"mesecons_piston_bottom.png^[transformR180",
"mesecons_piston_top.png",
},
inventory_image = "mesecons_piston_top.png",
wield_image = "mesecons_piston_top.png",
groups = {cracky = 3, not_in_creative_inventory = 1},
paramtype = "light",
paramtype2 = "facedir",
drop = "mesecons_pistons:piston_sticky_off",
after_dig_node = piston_remove_pusher,
node_box = piston_down_on_box,
selection_box = piston_down_on_box,
mesecons_piston = pistonspec_sticky_down,
sounds = default.node_sound_wood_defaults(),
mesecons = {effector={
action_off = piston_off,
rules = piston_down_rules,
}}
})
-- pusher
minetest.register_node("mesecons_pistons:piston_down_pusher_sticky", {
drawtype = "nodebox",
tiles = {
"mesecons_piston_pusher_back.png",
"mesecons_piston_pusher_front_sticky.png",
"mesecons_piston_pusher_left.png^[transformR90",
"mesecons_piston_pusher_right.png^[transformR270",
"mesecons_piston_pusher_bottom.png^[transformR180",
"mesecons_piston_pusher_top.png",
},
paramtype = "light",
paramtype2 = "facedir",
diggable = false,
corresponding_piston = "mesecons_pistons:piston_down_sticky_on",
selection_box = piston_down_pusher_box,
node_box = piston_down_pusher_box,
on_rotate = piston_rotate_pusher,
drop = "",
})
-- Register pushers as stoppers if they would be seperated from the piston
local piston_pusher_get_stopper = function (node, dir, stack, stackid)
local function piston_pusher_get_stopper(node, dir, stack, stackid)
if (stack[stackid + 1]
and stack[stackid + 1].node.name == minetest.registered_nodes[node.name].corresponding_piston
and stack[stackid + 1].node.name == get_pistonspec(node.name, "pusher").onname
and stack[stackid + 1].node.param2 == node.param2)
or (stack[stackid - 1]
and stack[stackid - 1].node.name == minetest.registered_nodes[node.name].corresponding_piston
and stack[stackid - 1].node.name == get_pistonspec(node.name, "pusher").onname
and stack[stackid - 1].node.param2 == node.param2) then
return false
end
return true
end
local piston_pusher_up_down_get_stopper = function (node, dir, stack, stackid)
local function piston_pusher_up_down_get_stopper(node, dir, stack, stackid)
if (stack[stackid + 1]
and stack[stackid + 1].node.name == minetest.registered_nodes[node.name].corresponding_piston)
and stack[stackid + 1].node.name == get_pistonspec(node.name, "pusher").onname)
or (stack[stackid - 1]
and stack[stackid - 1].node.name == minetest.registered_nodes[node.name].corresponding_piston) then
and stack[stackid - 1].node.name == get_pistonspec(node.name, "pusher").onname) then
return false
end
return true
@ -707,31 +432,24 @@ end
mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_normal", piston_pusher_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_sticky", piston_pusher_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_normal", piston_pusher_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_sticky", piston_pusher_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_normal", piston_pusher_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_sticky", piston_pusher_up_down_get_stopper)
-- Register pistons as stoppers if they would be seperated from the stopper
local piston_up_down_get_stopper = function (node, dir, stack, stackid)
if (stack[stackid + 1]
and stack[stackid + 1].node.name == minetest.registered_nodes[node.name].mesecons_piston.pusher)
and stack[stackid + 1].node.name == get_pistonspec(node.name, "onname").pusher)
or (stack[stackid - 1]
and stack[stackid - 1].node.name == minetest.registered_nodes[node.name].mesecons_piston.pusher) then
and stack[stackid - 1].node.name == get_pistonspec(node.name, "onname").pusher) then
return false
end
return true
end
local piston_get_stopper = function (node, dir, stack, stackid)
pistonspec = minetest.registered_nodes[node.name].mesecons_piston
dir = piston_get_direction(pistonspec.dir, node)
local pusherpos = vector.add(stack[stackid].pos, dir)
local function piston_get_stopper(node, dir, stack, stackid)
local pistonspec = get_pistonspec(node.name, "onname")
local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
local pusherpos = vector.add(stack[stackid].pos, dir)
local pushernode = minetest.get_node(pusherpos)
if minetest.registered_nodes[node.name].mesecons_piston.pusher == pushernode.name then
if pistonspec.pusher == pushernode.name then
for _, s in ipairs(stack) do
if vector.equals(s.pos, pusherpos) -- pusher is also to be pushed
and s.node.param2 == node.param2 then
@ -745,18 +463,13 @@ end
mesecon.register_mvps_stopper("mesecons_pistons:piston_normal_on", piston_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_sticky_on", piston_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_normal_on", piston_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_sticky_on", piston_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_normal_on", piston_up_down_get_stopper)
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_sticky_on", piston_up_down_get_stopper)
--craft recipes
minetest.register_craft({
output = "mesecons_pistons:piston_normal_off 2",
recipe = {
{"group:wood", "group:wood", "group:wood"},
{"default:cobble", "default:steel_ingot", "default:cobble"},
{"group:wood", "group:wood", "group:wood"},
{"default:cobble", "default:steel_ingot", "default:cobble"},
{"default:cobble", "group:mesecon_conductor_craftable", "default:cobble"},
}
})
@ -768,3 +481,7 @@ minetest.register_craft({
{"mesecons_pistons:piston_normal_off"},
}
})
-- load legacy code
dofile(minetest.get_modpath("mesecons_pistons")..DIR_DELIM.."legacy.lua")

View File

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

View File

@ -49,7 +49,8 @@ function mesecon.register_pressure_plate(basename, description, textures_off, te
inventory_image = image_i,
wield_image = image_w,
paramtype = "light",
description = description,
is_ground_content = false,
description = description,
pressureplate_basename = basename,
on_timer = pp_on_timer,
on_construct = function(pos)

View File

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

View File

@ -42,6 +42,7 @@ mesecon.register_node("mesecons_receiver:receiver", {
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
on_rotate = false,
@ -89,6 +90,7 @@ mesecon.register_node("mesecons_receiver:receiver_up", {
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
on_rotate = false,
@ -132,6 +134,7 @@ mesecon.register_node("mesecons_receiver:receiver_down", {
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
on_rotate = false,

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 661 B

View File

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

View File

@ -54,6 +54,7 @@ minetest.register_node("mesecons_torch:mesecon_torch_off", {
tiles = {"jeija_torches_off.png", "jeija_torches_off_ceiling.png", "jeija_torches_off_side.png"},
inventory_image = "jeija_torches_off.png",
paramtype = "light",
is_ground_content = false,
walkable = false,
paramtype2 = "wallmounted",
selection_box = torch_selectionbox,
@ -62,7 +63,8 @@ minetest.register_node("mesecons_torch:mesecon_torch_off", {
mesecons = {receptor = {
state = mesecon.state.off,
rules = torch_get_output_rules
}}
}},
on_blast = mesecon.on_blastnode,
})
minetest.register_node("mesecons_torch:mesecon_torch_on", {
@ -71,6 +73,7 @@ minetest.register_node("mesecons_torch:mesecon_torch_on", {
inventory_image = "jeija_torches_on.png",
wield_image = "jeija_torches_on.png",
paramtype = "light",
is_ground_content = false,
sunlight_propagates = true,
walkable = false,
paramtype2 = "wallmounted",
@ -82,6 +85,7 @@ minetest.register_node("mesecons_torch:mesecon_torch_on", {
state = mesecon.state.on,
rules = torch_get_output_rules
}},
on_blast = mesecon.on_blastnode,
})
minetest.register_abm({

View File

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

View File

@ -208,12 +208,14 @@ local function register_wires()
wield_image = "mesecons_wire_inv.png",
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
sunlight_propagates = true,
selection_box = selectionbox,
node_box = nodebox,
walkable = false,
drop = "mesecons:wire_00000000_off",
mesecon_wire = true
mesecon_wire = true,
on_rotate = false,
}, {tiles = tiles_off, mesecons = meseconspec_off, groups = groups_off},
{tiles = tiles_on, mesecons = meseconspec_on, groups = groups_on})

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

View File

@ -1,28 +1,28 @@
[mesecons]
mesecon.resumetime (Resume time) int 4
mesecon.overheat_max (Overheat max) int 20
mesecon.cooldown_time (Cooldown time) float 2.0
mesecon.cooldown_granularity (Cooldown granularity) float 0.5
mesecon.overheat_max (Device heat limit) int 20
mesecon.cooldown_time (Device cooldown time) float 2.0
mesecon.cooldown_granularity (Cooldown step length) float 0.5
[mesecons_blinkyplant]
mesecon.blinky_plant_interval (Plant interval) int 3
mesecon.blinky_plant_interval (Plant blinking interval) int 3
[mesecons_detector]
mesecon.detector_radius (Detector radius) int 6
mesecon.node_detector_distance_max (Detector max distance) int 10
mesecon.detector_radius (Player detector radius) int 6
mesecon.node_detector_distance_max (Node detector radius) int 10
[mesecons_luacontroller]
mesecon.luacontroller_string_rep_max (Max) int 64000
mesecon.luacontroller_digiline_maxlen (Digiline max length) int 50000
mesecon.luacontroller_maxevents (Max events) int 10000
mesecon.luacontroller_memsize (Memory size) int 100000
mesecon.luacontroller_string_rep_max (string:rep result length limit) int 64000
mesecon.luacontroller_digiline_maxlen (Digiline message size limit) int 50000
mesecon.luacontroller_maxevents (Controller execution time limit) int 10000
mesecon.luacontroller_memsize (Controller memory limit) int 100000
[mesecons_movestones]
@ -40,4 +40,4 @@ mesecon.piston_max_pull (Max pull) int 15
[mesecons_pressureplates]
mesecon.pplate_interval (Interval) float 0.1
mesecon.pplate_interval (Check interval) float 0.1

View File

@ -618,28 +618,31 @@ mobs.velociraptor_spawn_time (Velociraptor spawn time) enum any day,night,any
[**mesecons]
mesecon.resumetime (Resume time) int 4
mesecon.overheat_max (Overheat max) int 20
mesecon.cooldown_time (Cooldown time) float 2.0
mesecon.cooldown_granularity (Cooldown granularity) float 0.5
# The value at which circuits will overheat.
mesecon.overheat_max (Device heat limit) int 20
mesecon.cooldown_time (Device cooldown time) float 2.0
mesecon.cooldown_granularity (Cooldown step length) float 0.5
[**mesecons_blinkyplant]
mesecon.blinky_plant_interval (Plant interval) int 3
mesecon.blinky_plant_interval (Plant blinking interval) int 3
[**mesecons_detector]
mesecon.detector_radius (Detector radius) int 6
mesecon.node_detector_distance_max (Detector max distance) int 10
mesecon.detector_radius (Player detector radius) int 6
mesecon.node_detector_distance_max (Node detector radius) int 10
[**mesecons_luacontroller]
mesecon.luacontroller_string_rep_max (Max) int 64000
mesecon.luacontroller_digiline_maxlen (Digiline max length) int 50000
mesecon.luacontroller_maxevents (Max events) int 10000
mesecon.luacontroller_memsize (Memory size) int 100000
mesecon.luacontroller_string_rep_max (string:rep result length limit) int 64000
mesecon.luacontroller_digiline_maxlen (Digiline message size limit) int 50000
mesecon.luacontroller_maxevents (Controller execution time limit) int 10000
mesecon.luacontroller_memsize (Controller memory limit) int 100000
[**mesecons_movestones]
@ -657,7 +660,7 @@ mesecon.piston_max_pull (Max pull) int 15
[**mesecons_pressureplates]
mesecon.pplate_interval (Interval) float 0.1
mesecon.pplate_interval (Check interval) float 0.1
[*Minetest Game]