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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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 = {
|
||||
|
@ -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({
|
||||
|
@ -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,
|
||||
})
|
||||
|
@ -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
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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({
|
||||
|
@ -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({
|
||||
|
@ -1,2 +1,3 @@
|
||||
default
|
||||
mesecons
|
||||
screwdriver?
|
||||
|
@ -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
|
||||
|
@ -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({
|
||||
|
@ -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,
|
||||
|
@ -1 +1,2 @@
|
||||
mesecons
|
||||
screwdriver?
|
||||
|
@ -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"))
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -1 +1,2 @@
|
||||
mesecons
|
||||
screwdriver?
|
||||
|
@ -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({
|
||||
|
@ -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({
|
||||
|
@ -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")
|
||||
|
After Width: | Height: | Size: 443 B |
After Width: | Height: | Size: 663 B |
After Width: | Height: | Size: 387 B |
After Width: | Height: | Size: 633 B |
After Width: | Height: | Size: 407 B |
After Width: | Height: | Size: 641 B |
After Width: | Height: | Size: 349 B |
After Width: | Height: | Size: 546 B |
After Width: | Height: | Size: 387 B |
After Width: | Height: | Size: 633 B |
After Width: | Height: | Size: 429 B |
After Width: | Height: | Size: 357 B |
@ -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; it’s 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 doesn’t pay the cost because functions
|
||||
-- are stripped and therefore the element is dropped.
|
||||
-- 5. The second occurrence doesn’t pay the cost because it’s 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 won’t 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,
|
||||
})
|
||||
|
||||
------------------------
|
||||
|
@ -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})
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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({
|
||||
|
@ -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")
|
||||
|
48
mods/modpacks/mesecons/mesecons_pistons/legacy.lua
Normal 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,
|
||||
})
|
@ -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({
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
})
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
})
|
||||
|
@ -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(),
|
||||
})
|
||||
|
After Width: | Height: | Size: 661 B |
@ -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
|
||||
|
@ -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({
|
||||
|
@ -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 = {
|
||||
|
@ -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})
|
||||
|
||||
|
BIN
mods/modpacks/mesecons/screenshot.png
Normal file
After Width: | Height: | Size: 180 KiB |
@ -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
|
||||
|
@ -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]
|
||||
|