@@ -29,16 +29,24 @@ minetest.register_on_protection_violation(function(pos, name)
29
29
end
30
30
local player_pos = player :get_pos ()
31
31
if pos .y < player_pos .y then
32
- player :set_pos ({
33
- x = player_pos .x ,
34
- y = player_pos .y + 1 ,
35
- z = player_pos .z
36
- })
32
+ player_pos .y = player_pos .y + 1
33
+ player :set_pos (player_pos )
37
34
end
38
35
end
39
36
end
40
37
end )
41
38
39
+ local function can_pvp_at (pos )
40
+ for id in pairs (areas :getAreasAtPos (pos )) do
41
+ -- This uses areas:canPvP instead of area.canPvP in case areas:canPvP
42
+ -- is overridden
43
+ if areas :canPvP (id ) then
44
+ return true
45
+ end
46
+ end
47
+ return false
48
+ end
49
+
42
50
minetest .register_on_punchplayer (function (player , hitter , time_from_last_punch )
43
51
if not enable_damage then
44
52
return true
@@ -57,37 +65,22 @@ minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch)
57
65
return true
58
66
end
59
67
60
- local hitterInPvP
61
- -- Check if the hitter is in an area with allowed PvP
62
- local hitterAreas = areas :getAreasAtPos (hitter :get_pos ())
63
- -- If the table is empty, PvP is not allowed
64
- if not next (hitterAreas ) then
65
- return true
66
- end
67
- -- Do any of the areas have allowed PvP?
68
- for _ , area in pairs (hitterAreas ) do
69
- if area .canPvP then
70
- hitterInPvP = true
71
- break
72
- end
73
- end
74
-
75
- if hitterInPvP then
76
- -- Check if the victim is in an area with allowed PvP
77
- local victimAreas = areas :getAreasAtPos (player :get_pos ())
78
- -- If the table is empty, PvP is not allowed
79
- if not next (victimAreas ) then
80
- return true
81
- end
82
- -- Do any of the areas have allowed PvP?
83
- for _ , area in pairs (victimAreas ) do
84
- if area .canPvP then
85
- return false
86
- end
87
- end
68
+ -- Allow PvP if both players are in a PvP area
69
+ if can_pvp_at (hitter :get_pos ()) and can_pvp_at (player :get_pos ()) then
70
+ return false
88
71
end
89
72
90
73
-- Otherwise, it doesn't do damage
91
74
minetest .chat_send_player (player_name , S (" PvP is not allowed in this area!" ))
92
75
return true
93
76
end )
77
+
78
+ local old_calculate_knockback = minetest .calculate_knockback
79
+ function minetest .calculate_knockback (player , hitter , time_from_last_punch , ...)
80
+ if player :is_player () and hitter and hitter :is_player () and
81
+ (time_from_last_punch < 0.25 or not can_pvp_at (player :get_pos ()) or
82
+ not can_pvp_at (hitter :get_pos ())) then
83
+ return 0
84
+ end
85
+ return old_calculate_knockback (player , hitter , time_from_last_punch , ... )
86
+ end
0 commit comments