From e8ee792fc655d84e6ba8a1ddde19c5954f64350f Mon Sep 17 00:00:00 2001 From: luk3yx Date: Mon, 22 Aug 2022 08:33:22 +1200 Subject: [PATCH] Don't do knockback in non-PvP areas (#2) --- interact.lua | 59 +++++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/interact.lua b/interact.lua index ef14976..43eb1ac 100644 --- a/interact.lua +++ b/interact.lua @@ -29,16 +29,24 @@ minetest.register_on_protection_violation(function(pos, name) end local player_pos = player:get_pos() if pos.y < player_pos.y then - player:set_pos({ - x = player_pos.x, - y = player_pos.y + 1, - z = player_pos.z - }) + player_pos.y = player_pos.y + 1 + player:set_pos(player_pos) end end end end) +local function can_pvp_at(pos) + for id in pairs(areas:getAreasAtPos(pos)) do + -- This uses areas:canPvP instead of area.canPvP in case areas:canPvP + -- is overridden + if areas:canPvP(id) then + return true + end + end + return false +end + minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch) if not enable_damage then return true @@ -57,37 +65,22 @@ minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch) return true end - local hitterInPvP - -- Check if the hitter is in an area with allowed PvP - local hitterAreas = areas:getAreasAtPos(hitter:get_pos()) - -- If the table is empty, PvP is not allowed - if not next(hitterAreas) then - return true - end - -- Do any of the areas have allowed PvP? - for _, area in pairs(hitterAreas) do - if area.canPvP then - hitterInPvP = true - break - end - end - - if hitterInPvP then - -- Check if the victim is in an area with allowed PvP - local victimAreas = areas:getAreasAtPos(player:get_pos()) - -- If the table is empty, PvP is not allowed - if not next(victimAreas) then - return true - end - -- Do any of the areas have allowed PvP? - for _, area in pairs(victimAreas) do - if area.canPvP then - return false - end - end + -- Allow PvP if both players are in a PvP area + if can_pvp_at(hitter:get_pos()) and can_pvp_at(player:get_pos()) then + return false end -- Otherwise, it doesn't do damage minetest.chat_send_player(player_name, S("PvP is not allowed in this area!")) return true end) + +local old_calculate_knockback = minetest.calculate_knockback +function minetest.calculate_knockback(player, hitter, time_from_last_punch, ...) + if player:is_player() and hitter and hitter:is_player() and + (time_from_last_punch < 0.25 or not can_pvp_at(player:get_pos()) or + not can_pvp_at(hitter:get_pos())) then + return 0 + end + return old_calculate_knockback(player, hitter, time_from_last_punch, ...) +end