forked from Mirrorlandia_minetest/mesecons
Add support for sticky blocks for pistons and a a sample sticky block
This commit is contained in:
parent
aa5538a734
commit
a6d0a523ba
@ -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
|
||||
|
@ -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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
if all_pull_sticky then
|
||||
table.insert(connected, vector.subtract(np, dir))
|
||||
end
|
||||
|
||||
-- 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
|
||||
|
||||
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 (nodes, {node = nn, pos = np})
|
||||
|
||||
np = mesecon.addPosRule(np, dir)
|
||||
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 = {}
|
||||
|
||||
|
@ -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
|
||||
|
2
mesecons_stickyblocks/depends.txt
Normal file
2
mesecons_stickyblocks/depends.txt
Normal file
@ -0,0 +1,2 @@
|
||||
mesecons
|
||||
mesecons_mvps
|
16
mesecons_stickyblocks/init.lua
Normal file
16
mesecons_stickyblocks/init.lua
Normal file
@ -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
|
||||
})
|
Loading…
Reference in New Issue
Block a user