diff --git a/mods/mesecons/mesecons/presets.lua b/mods/mesecons/mesecons/presets.lua index ea4bd65a..e5ca1ca6 100644 --- a/mods/mesecons/mesecons/presets.lua +++ b/mods/mesecons/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/mods/mesecons/mesecons_detector/init.lua b/mods/mesecons/mesecons_detector/init.lua index 1a8595d4..e5896764 100644 --- a/mods/mesecons/mesecons_detector/init.lua +++ b/mods/mesecons/mesecons_detector/init.lua @@ -135,8 +135,12 @@ end -- returns true if player was found, false if not local node_detector_scan = function (pos) - local node = minetest.get_node(pos) - local frontpos = vector.subtract(pos, minetest.facedir_to_dir(node.param2)) + if not pos then return end + local node = minetest.get_node_or_nil(pos) + if not node then return end + local scandir = minetest.facedir_to_dir(node.param2) + if not scandir then return end + local frontpos = vector.subtract(pos, scandir) local frontnode = minetest.get_node(frontpos) local meta = minetest.get_meta(pos) return (frontnode.name == meta:get_string("scanname")) or diff --git a/mods/mesecons/mesecons_mvps/init.lua b/mods/mesecons/mesecons_mvps/init.lua index e7c9d5a1..beec94bd 100644 --- a/mods/mesecons/mesecons_mvps/init.lua +++ b/mods/mesecons/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 + 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 = {} diff --git a/mods/mesecons/mesecons_pistons/init.lua b/mods/mesecons/mesecons_pistons/init.lua index 7db10732..678adca8 100644 --- a/mods/mesecons/mesecons_pistons/init.lua +++ b/mods/mesecons/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/mods/mesecons/mesecons_stickyblocks/depends.txt b/mods/mesecons/mesecons_stickyblocks/depends.txt new file mode 100644 index 00000000..01f085ba --- /dev/null +++ b/mods/mesecons/mesecons_stickyblocks/depends.txt @@ -0,0 +1,2 @@ +mesecons +mesecons_mvps diff --git a/mods/mesecons/mesecons_stickyblocks/init.lua b/mods/mesecons/mesecons_stickyblocks/init.lua new file mode 100644 index 00000000..c1eb1217 --- /dev/null +++ b/mods/mesecons/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 +}) diff --git a/mods/pipeworks/devices.lua b/mods/pipeworks/devices.lua index 6f408175..52f3002f 100644 --- a/mods/pipeworks/devices.lua +++ b/mods/pipeworks/devices.lua @@ -283,8 +283,9 @@ minetest.register_node("pipeworks:entry_panel_empty", { selection_box = panel_cbox, collision_box = panel_cbox, on_place = function(itemstack, placer, pointed_thing) - if not pipeworks.node_is_owned(pointed_thing.under, placer) - and not pipeworks.node_is_owned(pointed_thing.above, placer) then + local playername = placer:get_player_name() + if not minetest.is_protected(pointed_thing.under, playername) + and not minetest.is_protected(pointed_thing.above, playername) then local node = minetest.get_node(pointed_thing.under) if not minetest.registered_nodes[node.name] diff --git a/mods/pipeworks/init.lua b/mods/pipeworks/init.lua index 9c2ebc82..92ce02c6 100755 --- a/mods/pipeworks/init.lua +++ b/mods/pipeworks/init.lua @@ -68,39 +68,6 @@ function pipeworks.may_configure(pos, player) return not minetest.is_protected(pos, name) end -function pipeworks.node_is_owned(pos, placer) - local ownername = false - if type(IsPlayerNodeOwner) == "function" then -- node_ownership mod - if HasOwner(pos, placer) then -- returns true if the node is owned - if not IsPlayerNodeOwner(pos, placer:get_player_name()) then - if type(getLastOwner) == "function" then -- ...is an old version - ownername = getLastOwner(pos) - elseif type(GetNodeOwnerName) == "function" then -- ...is a recent version - ownername = GetNodeOwnerName(pos) - else - ownername = S("someone") - end - end - end - - elseif type(isprotect)=="function" then -- glomie's protection mod - if not isprotect(5, pos, placer) then - ownername = S("someone") - end - elseif type(protector)=="table" and type(protector.can_dig)=="function" then -- Zeg9's protection mod - if not protector.can_dig(5, pos, placer) then - ownername = S("someone") - end - end - - if ownername ~= false then - minetest.chat_send_player( placer:get_player_name(), S("Sorry, %s owns that spot."):format(ownername) ) - return true - else - return false - end -end - function pipeworks.replace_name(tbl,tr,name) local ntbl={} for key,i in pairs(tbl) do