summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesecons/presets.lua8
-rw-r--r--mesecons_mvps/init.lua113
-rw-r--r--mesecons_pistons/init.lua5
-rw-r--r--mesecons_stickyblocks/depends.txt2
-rw-r--r--mesecons_stickyblocks/init.lua16
5 files changed, 103 insertions, 41 deletions
diff --git a/mesecons/presets.lua b/mesecons/presets.lua
index ea4bd65..e5ca1ca 100644
--- a/mesecons/presets.lua
+++ b/mesecons/presets.lua
@@ -30,6 +30,14 @@ mesecon.rules.flat =
{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}}
mesecon.rules.buttonlike_get = function(node)
local rules = mesecon.rules.buttonlike
diff --git a/mesecons_mvps/init.lua b/mesecons_mvps/init.lua
index e7c9d5a..beec94b 100644
--- a/mesecons_mvps/init.lua
+++ b/mesecons_mvps/init.lua
@@ -19,7 +19,6 @@ function mesecon.is_mvps_stopper(node, pushdir, stack, stackid)
if type (get_stopper) == "function" then
get_stopper = get_stopper(node, pushdir, stack, stackid)
end
- if (get_stopper) then print(node.name) end
return get_stopper
end
@@ -48,27 +47,76 @@ function mesecon.mvps_process_stack(stack)
end
end
-function mesecon.mvps_get_stack(pos, dir, maximum)
+function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
-- determine the number of nodes to be pushed
- local np = {x = pos.x, y = pos.y, z = pos.z}
local nodes = {}
- while true do
- local nn = minetest.get_node_or_nil(np)
- if not nn or #nodes > maximum then
- -- don't push at all, something is in the way (unloaded map or too many nodes)
- return nil
- end
+ local frontiers = {pos}
+
+ while #frontiers > 0 do
+ local np = frontiers[1]
+ local nn = minetest.get_node(np)
+
+ if nn.name ~= "air"
+ and minetest.registered_nodes[nn.name]
+ and minetest.registered_nodes[nn.name].liquidtype == "none" then
+ table.insert(nodes, {node = nn, pos = np})
+ if #nodes > maximum then return nil end
+
+ -- add connected nodes to frontiers, connected is a vector list
+ -- the vectors must be absolute positions
+ local connected = {}
+ if minetest.registered_nodes[nn.name]
+ and minetest.registered_nodes[nn.name].mvps_sticky then
+ connected = minetest.registered_nodes[nn.name].mvps_sticky(np, nn)
+ end
- if nn.name == "air"
- or (minetest.registered_nodes[nn.name]
- and minetest.registered_nodes[nn.name].liquidtype ~= "none") then --is liquid
- break
- end
+ table.insert(connected, vector.add(np, dir))
+
+ -- If adjacent node is sticky block and connects add that
+ -- position to the connected table
+ for _, r in ipairs(mesecon.rules.alldirs) do
+ local adjpos = vector.add(np, r)
+ local adjnode = minetest.get_node(adjpos)
+ if minetest.registered_nodes[adjnode.name]
+ and minetest.registered_nodes[adjnode.name].mvps_sticky then
+ local sticksto = minetest.registered_nodes[adjnode.name]
+ .mvps_sticky(adjpos, adjnode)
+
+ -- connects to this position?
+ for _, link in ipairs(sticksto) do
+ if vector.equals(link, np) then
+ table.insert(connected, adjpos)
+ end
+ end
+ end
+ end
- table.insert (nodes, {node = nn, pos = np})
+ if all_pull_sticky then
+ table.insert(connected, vector.subtract(np, dir))
+ end
- np = mesecon.addPosRule(np, dir)
+ -- Make sure there are no duplicates in frontiers / nodes before
+ -- adding nodes in "connected" to frontiers
+ for _, cp in ipairs(connected) do
+ local duplicate = false
+ for _, rp in ipairs(nodes) do
+ if vector.equals(cp, rp.pos) then
+ duplicate = true
+ end
+ end
+ for _, fp in ipairs(frontiers) do
+ if vector.equals(cp, fp) then
+ duplicate = true
+ end
+ end
+ if not duplicate then
+ table.insert(frontiers, cp)
+ end
+ end
+ end
+ table.remove(frontiers, 1)
end
+
return nodes
end
@@ -77,11 +125,19 @@ function mesecon.mvps_push(pos, dir, maximum)
end
function mesecon.mvps_pull_all(pos, dir, maximum)
+ return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, true)
+end
+
+function mesecon.mvps_pull_single(pos, dir, maximum)
return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum)
end
-function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum) -- pos: pos of mvps; stackdir: direction of building the stack; movedir: direction of actual movement; maximum: maximum nodes to be pushed
- local nodes = mesecon.mvps_get_stack(pos, stackdir, maximum)
+-- pos: pos of mvps; stackdir: direction of building the stack
+-- movedir: direction of actual movement
+-- maximum: maximum nodes to be pushed
+-- all_pull_sticky: All nodes are sticky in the direction that they are pulled from
+function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sticky)
+ local nodes = mesecon.mvps_get_stack(pos, movedir, maximum, all_pull_sticky)
if not nodes then return end
-- determine if one of the nodes blocks the push / pull
@@ -133,27 +189,6 @@ mesecon.register_on_mvps_move(function(moved_nodes)
end
end)
-function mesecon.mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons)
- local np = mesecon.addPosRule(pos, dir)
- local nn = minetest.get_node(np)
-
- if ((not minetest.registered_nodes[nn.name]) --unregistered node
- or minetest.registered_nodes[nn.name].liquidtype == "none") --non-liquid node
- and not mesecon.is_mvps_stopper(nn, dir, {{pos = np, node = nn}}, 1) then --non-stopper node
- local meta = minetest.get_meta(np):to_table()
- minetest.remove_node(np)
- minetest.add_node(pos, nn)
- minetest.get_meta(pos):from_table(meta)
-
- nodeupdate(np)
- nodeupdate(pos)
- mesecon.on_dignode(np, nn)
- mesecon.update_autoconnect(np)
- on_mvps_move({{pos = pos, oldpos = np, node = nn, meta = meta}})
- end
- return {{pos = np, node = {param2 = 0, name = "air"}}, {pos = pos, node = nn}}
-end
-
function mesecon.mvps_move_objects(pos, dir, nodestack)
local objects_to_move = {}
diff --git a/mesecons_pistons/init.lua b/mesecons_pistons/init.lua
index 7db1073..678adca 100644
--- a/mesecons_pistons/init.lua
+++ b/mesecons_pistons/init.lua
@@ -100,9 +100,10 @@ local piston_off = function(pos, node)
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 = mesecon.addPosRule(pos, dir)
- local stack = mesecon.mvps_pull_single(pullpos, dir)
+ local pullpos = vector.add(pos, vector.multiply(dir, 2))
+ local stack = mesecon.mvps_pull_single(pullpos, vector.multiply(dir, -1), maxpull)
mesecon.mvps_process_stack(pos, dir, stack)
end
end
diff --git a/mesecons_stickyblocks/depends.txt b/mesecons_stickyblocks/depends.txt
new file mode 100644
index 0000000..01f085b
--- /dev/null
+++ b/mesecons_stickyblocks/depends.txt
@@ -0,0 +1,2 @@
+mesecons
+mesecons_mvps
diff --git a/mesecons_stickyblocks/init.lua b/mesecons_stickyblocks/init.lua
new file mode 100644
index 0000000..c1eb121
--- /dev/null
+++ b/mesecons_stickyblocks/init.lua
@@ -0,0 +1,16 @@
+-- Sticky blocks can be used together with pistons or movestones to push / pull
+-- structures that are "glued" together using sticky blocks
+
+-- All sides sticky block
+minetest.register_node("mesecons_stickyblocks:sticky_block_all", {
+ description = "All-sides sticky block",
+ tiles = {"default_grass_footsteps.png"},
+ groups = {dig_immediate=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
+})