diff --git a/mesecons_mvps/init.lua b/mesecons_mvps/init.lua index 10cae42..c3003ce 100644 --- a/mesecons_mvps/init.lua +++ b/mesecons_mvps/init.lua @@ -145,29 +145,36 @@ function mesecon.mvps_mark_owner(pos, placer) end end -local function prot_deny() return true end -local function prot_allow() return false end +local function add_pos(positions, pos) + local hash = minetest.hash_node_position(pos) + positions[hash] = pos +end -local function make_is_protected(player_name) +local function are_protected(positions, player_name) local mode = mesecon.setting("mvps_protection_mode", "normal") if mode == "ignore" then - return prot_allow + return false end + local name = player_name if player_name == "" or not player_name then -- legacy MVPS if mode == "normal" then - player_name = "$unknown" -- sentinel, for checking for *any* protection + name = "$unknown" -- sentinel, for checking for *any* protection elseif mode == "compat" then - return prot_allow + return false elseif mode == "restrict" then - return prot_deny + return true else error("Invalid protection mode") end end local is_protected = minetest.is_protected - return function(pos) - return is_protected(pos, player_name) + for _, pos in pairs(positions) do + if is_protected(pos, name) then + minetest.record_protection_violation(pos, player_name) + return true + end end + return false end function mesecon.mvps_push(pos, dir, maximum, player_name) @@ -194,16 +201,21 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, all_pull_sti local nodes = mesecon.mvps_get_stack(pos, movedir, maximum, all_pull_sticky) 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 - local is_protected = make_is_protected(player_name) for id, n in ipairs(nodes) do if mesecon.is_mvps_stopper(n.node, movedir, nodes, id) then return end - if is_protected(n.pos) then - minetest.record_protection_violation(n.pos, player_name) - return - 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 end -- remove all nodes