forked from Mirrorlandia_minetest/mesecons
Respect protection in MVPS (#466)
This commit is contained in:
parent
1bf862f932
commit
15e743629e
@ -43,10 +43,16 @@ function mesecon.register_movestone(name, def, is_sticky, is_vertical)
|
|||||||
local function movestone_move(pos, node, rulename)
|
local function movestone_move(pos, node, rulename)
|
||||||
local direction = get_movestone_direction(rulename, is_vertical)
|
local direction = get_movestone_direction(rulename, is_vertical)
|
||||||
local frontpos = vector.add(pos, direction)
|
local frontpos = vector.add(pos, direction)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local owner = meta:get_string("owner")
|
||||||
|
|
||||||
-- ### Step 1: Push nodes in front ###
|
-- ### Step 1: Push nodes in front ###
|
||||||
local success, stack, oldstack = mesecon.mvps_push(frontpos, direction, max_push)
|
local success, stack, oldstack = mesecon.mvps_push(frontpos, direction, max_push, owner)
|
||||||
if not success then
|
if not success then
|
||||||
|
if stack == "protected" then
|
||||||
|
meta:set_string("infotext", "Can't move: protected area on the way")
|
||||||
|
return
|
||||||
|
end
|
||||||
minetest.get_node_timer(pos):start(timer_interval)
|
minetest.get_node_timer(pos):start(timer_interval)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -54,6 +60,8 @@ function mesecon.register_movestone(name, def, is_sticky, is_vertical)
|
|||||||
|
|
||||||
-- ### Step 2: Move the movestone ###
|
-- ### Step 2: Move the movestone ###
|
||||||
minetest.set_node(frontpos, node)
|
minetest.set_node(frontpos, node)
|
||||||
|
local meta2 = minetest.get_meta(frontpos)
|
||||||
|
meta2:set_string("owner", owner)
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
mesecon.on_dignode(pos, node)
|
mesecon.on_dignode(pos, node)
|
||||||
mesecon.on_placenode(frontpos, node)
|
mesecon.on_placenode(frontpos, node)
|
||||||
@ -62,7 +70,7 @@ function mesecon.register_movestone(name, def, is_sticky, is_vertical)
|
|||||||
-- ### Step 3: If sticky, pull stack behind ###
|
-- ### Step 3: If sticky, pull stack behind ###
|
||||||
if is_sticky then
|
if is_sticky then
|
||||||
local backpos = vector.subtract(pos, direction)
|
local backpos = vector.subtract(pos, direction)
|
||||||
success, stack, oldstack = mesecon.mvps_pull_all(backpos, direction, max_pull)
|
success, stack, oldstack = mesecon.mvps_pull_all(backpos, direction, max_pull, owner)
|
||||||
if success then
|
if success then
|
||||||
mesecon.mvps_move_objects(backpos, vector.multiply(direction, -1), oldstack, -1)
|
mesecon.mvps_move_objects(backpos, vector.multiply(direction, -1), oldstack, -1)
|
||||||
end
|
end
|
||||||
@ -83,6 +91,16 @@ function mesecon.register_movestone(name, def, is_sticky, is_vertical)
|
|||||||
rules = mesecon.rules.default,
|
rules = mesecon.rules.default,
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
def.after_place_node = mesecon.mvps_set_owner
|
||||||
|
|
||||||
|
def.on_punch = function(pos, node, player)
|
||||||
|
local player_name = player and player.get_player_name and player:get_player_name()
|
||||||
|
if mesecon.mvps_claim(pos, player_name) then
|
||||||
|
minetest.get_node_timer(pos):start(timer_interval)
|
||||||
|
minetest.chat_send_player(player_name, "Reclaimed movestone")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def.on_timer = function(pos, elapsed)
|
def.on_timer = function(pos, elapsed)
|
||||||
local sourcepos = mesecon.is_powered(pos)
|
local sourcepos = mesecon.is_powered(pos)
|
||||||
if not sourcepos then
|
if not sourcepos then
|
||||||
|
@ -133,31 +133,100 @@ function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
|
|||||||
return nodes
|
return nodes
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.mvps_push(pos, dir, maximum)
|
function mesecon.mvps_set_owner(pos, placer)
|
||||||
return mesecon.mvps_push_or_pull(pos, dir, dir, maximum)
|
local meta = minetest.get_meta(pos)
|
||||||
|
local owner = placer and placer.get_player_name and placer:get_player_name()
|
||||||
|
if owner and owner ~= "" then
|
||||||
|
meta:set_string("owner", owner)
|
||||||
|
else
|
||||||
|
meta:set_string("owner", "$unknown") -- to distinguish from older pistons
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.mvps_pull_all(pos, dir, maximum)
|
function mesecon.mvps_claim(pos, player_name)
|
||||||
return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, true)
|
if not player_name or player_name == "" then return end
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if meta:get_string("infotext") == "" then return end
|
||||||
|
if meta:get_string("owner") == player_name then return end -- already owned
|
||||||
|
if minetest.is_protected(pos, player_name) then
|
||||||
|
minetest.chat_send_player(player_name, "Can't reclaim: protected")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
meta:set_string("owner", player_name)
|
||||||
|
meta:set_string("infotext", "")
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.mvps_pull_single(pos, dir, maximum)
|
local function add_pos(positions, pos)
|
||||||
return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum)
|
local hash = minetest.hash_node_position(pos)
|
||||||
|
positions[hash] = pos
|
||||||
end
|
end
|
||||||
|
|
||||||
-- pos: pos of mvps; stackdir: direction of building the stack
|
local function are_protected(positions, player_name)
|
||||||
|
local mode = mesecon.setting("mvps_protection_mode", "normal")
|
||||||
|
if mode == "ignore" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local name = player_name
|
||||||
|
if player_name == "" or not player_name then -- legacy MVPS
|
||||||
|
if mode == "normal" then
|
||||||
|
name = "$unknown" -- sentinel, for checking for *any* protection
|
||||||
|
elseif mode == "compat" then
|
||||||
|
return false
|
||||||
|
elseif mode == "restrict" then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
error("Invalid protection mode")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local is_protected = minetest.is_protected
|
||||||
|
for _, pos in pairs(positions) do
|
||||||
|
if is_protected(pos, name) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function mesecon.mvps_push(pos, dir, maximum, player_name)
|
||||||
|
return mesecon.mvps_push_or_pull(pos, dir, dir, maximum, false, player_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mesecon.mvps_pull_all(pos, dir, maximum, player_name)
|
||||||
|
return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, true, player_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mesecon.mvps_pull_single(pos, dir, maximum, player_name)
|
||||||
|
return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, false, player_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- pos: pos of mvps
|
||||||
|
-- stackdir: direction of building the stack
|
||||||
-- movedir: direction of actual movement
|
-- movedir: direction of actual movement
|
||||||
-- maximum: maximum nodes to be pushed
|
-- maximum: maximum nodes to be pushed
|
||||||
-- all_pull_sticky: All nodes are sticky in the direction that they are pulled from
|
-- 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)
|
-- player_name: Player responsible for the action.
|
||||||
|
-- - empty string means legacy MVPS, actual check depends on configuration
|
||||||
|
-- - "$unknown" is a sentinel for forcing the check
|
||||||
|
function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sticky, player_name)
|
||||||
local nodes = mesecon.mvps_get_stack(pos, movedir, maximum, all_pull_sticky)
|
local nodes = mesecon.mvps_get_stack(pos, movedir, maximum, all_pull_sticky)
|
||||||
|
|
||||||
if not nodes then return end
|
if not nodes then return end
|
||||||
|
|
||||||
|
local protection_check_set = {}
|
||||||
|
if vector.equals(stackdir, movedir) then -- pushing
|
||||||
|
add_pos(protection_check_set, pos)
|
||||||
|
end
|
||||||
-- determine if one of the nodes blocks the push / pull
|
-- determine if one of the nodes blocks the push / pull
|
||||||
for id, n in ipairs(nodes) do
|
for id, n in ipairs(nodes) do
|
||||||
if mesecon.is_mvps_stopper(n.node, movedir, nodes, id) then
|
if mesecon.is_mvps_stopper(n.node, movedir, nodes, id) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
add_pos(protection_check_set, n.pos)
|
||||||
|
add_pos(protection_check_set, vector.add(n.pos, movedir))
|
||||||
|
end
|
||||||
|
if are_protected(protection_check_set, player_name) then
|
||||||
|
return false, "protected"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- remove all nodes
|
-- remove all nodes
|
||||||
|
@ -86,11 +86,15 @@ local piston_on = function(pos, node)
|
|||||||
local pistonspec = get_pistonspec(node.name, "offname")
|
local pistonspec = get_pistonspec(node.name, "offname")
|
||||||
local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
|
local dir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
|
||||||
local pusher_pos = vector.add(pos, dir)
|
local pusher_pos = vector.add(pos, dir)
|
||||||
local success, stack, oldstack = mesecon.mvps_push(pusher_pos, dir, max_push)
|
local meta = minetest.get_meta(pos)
|
||||||
|
local success, stack, oldstack = mesecon.mvps_push(pusher_pos, dir, max_push, meta:get_string("owner"))
|
||||||
if not success then
|
if not success then
|
||||||
|
if stack == "protected" then
|
||||||
|
meta:set_string("infotext", "Can't extend: protected area on the way")
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
minetest.set_node(pos, {param2 = node.param2, name = pistonspec.onname})
|
minetest.swap_node(pos, {param2 = node.param2, name = pistonspec.onname})
|
||||||
minetest.set_node(pusher_pos, {param2 = node.param2, name = pistonspec.pusher})
|
minetest.set_node(pusher_pos, {param2 = node.param2, name = pistonspec.pusher})
|
||||||
minetest.sound_play("piston_extend", {
|
minetest.sound_play("piston_extend", {
|
||||||
pos = pos,
|
pos = pos,
|
||||||
@ -103,15 +107,16 @@ end
|
|||||||
|
|
||||||
local function piston_off(pos, node)
|
local function piston_off(pos, node)
|
||||||
local pistonspec = get_pistonspec(node.name, "onname")
|
local pistonspec = get_pistonspec(node.name, "onname")
|
||||||
minetest.set_node(pos, {param2 = node.param2, name = pistonspec.offname})
|
minetest.swap_node(pos, {param2 = node.param2, name = pistonspec.offname})
|
||||||
piston_remove_pusher(pos, node, not pistonspec.sticky)
|
piston_remove_pusher(pos, node, not pistonspec.sticky) -- allow that even in protected area
|
||||||
|
|
||||||
if not pistonspec.sticky then
|
if not pistonspec.sticky then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local dir = minetest.facedir_to_dir(node.param2)
|
local dir = minetest.facedir_to_dir(node.param2)
|
||||||
local pullpos = vector.add(pos, vector.multiply(dir, -2))
|
local pullpos = vector.add(pos, vector.multiply(dir, -2))
|
||||||
local success, stack, oldstack = mesecon.mvps_pull_single(pullpos, dir, max_pull)
|
local meta = minetest.get_meta(pos)
|
||||||
|
local success, stack, oldstack = mesecon.mvps_pull_single(pullpos, dir, max_pull, meta:get_string("owner"))
|
||||||
if success then
|
if success then
|
||||||
mesecon.mvps_move_objects(pullpos, vector.multiply(dir, -1), oldstack, -1)
|
mesecon.mvps_move_objects(pullpos, vector.multiply(dir, -1), oldstack, -1)
|
||||||
end
|
end
|
||||||
@ -125,6 +130,7 @@ local orientations = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
local function piston_orientate(pos, placer)
|
local function piston_orientate(pos, placer)
|
||||||
|
mesecon.mvps_set_owner(pos, placer)
|
||||||
if not placer then
|
if not placer then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -237,6 +243,13 @@ local function piston_rotate_pusher(pos, node, player, mode)
|
|||||||
return piston_rotate_on(piston_pos, piston_node, player, mode)
|
return piston_rotate_on(piston_pos, piston_node, player, mode)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function piston_punch(pos, node, player)
|
||||||
|
local player_name = player and player.get_player_name and player:get_player_name()
|
||||||
|
if mesecon.mvps_claim(pos, player_name) then
|
||||||
|
minetest.chat_send_player(player_name, "Reclaimed piston")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Boxes:
|
-- Boxes:
|
||||||
|
|
||||||
@ -279,6 +292,7 @@ minetest.register_node("mesecons_pistons:piston_normal_off", {
|
|||||||
action_on = piston_on,
|
action_on = piston_on,
|
||||||
rules = piston_get_rules,
|
rules = piston_get_rules,
|
||||||
}},
|
}},
|
||||||
|
on_punch = piston_punch,
|
||||||
on_rotate = piston_rotate,
|
on_rotate = piston_rotate,
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
})
|
})
|
||||||
@ -357,6 +371,7 @@ minetest.register_node("mesecons_pistons:piston_sticky_off", {
|
|||||||
action_on = piston_on,
|
action_on = piston_on,
|
||||||
rules = piston_get_rules,
|
rules = piston_get_rules,
|
||||||
}},
|
}},
|
||||||
|
on_punch = piston_punch,
|
||||||
on_rotate = piston_rotate,
|
on_rotate = piston_rotate,
|
||||||
on_blast = mesecon.on_blastnode,
|
on_blast = mesecon.on_blastnode,
|
||||||
})
|
})
|
||||||
|
@ -28,6 +28,17 @@ mesecon.luacontroller_memsize (Controller memory limit) int 100000 10000 1000000
|
|||||||
# IID is ignored and at most one interrupt may be queued if this setting is enabled.
|
# IID is ignored and at most one interrupt may be queued if this setting is enabled.
|
||||||
mesecon.luacontroller_lightweight_interrupts (Lightweight interrupts) bool false
|
mesecon.luacontroller_lightweight_interrupts (Lightweight interrupts) bool false
|
||||||
|
|
||||||
|
[mesecons_mvps]
|
||||||
|
|
||||||
|
# In pre-existing world, MVPS may not be labelled with the owner.
|
||||||
|
# Protection handling for them is configurable.
|
||||||
|
# - normal: allow legacy MVPS to work in unprotected areas only
|
||||||
|
# - compat: allow legacy MVPS to work everywhere
|
||||||
|
# - ignore: allow all MVPS to work everywhere
|
||||||
|
# - restrict: disallow legacy MVPS
|
||||||
|
# Note that new unowned (e.g. machine-placed) MVPS are always
|
||||||
|
# handled as in `normal` mode.
|
||||||
|
mesecon.mvps_protection_mode (MVPS [movestones, pistons] protection handling) enum compat normal,compat,ignore,restrict
|
||||||
|
|
||||||
[mesecons_movestones]
|
[mesecons_movestones]
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user