Add the best PvP solution you've seen

master
MoNTE48 2021-05-19 10:42:16 +02:00
parent 96ca31dd7d
commit 758b3d0dd0
5 changed files with 133 additions and 11 deletions

View File

@ -5,7 +5,6 @@ minetest.register_chatcommand("protect", {
description = S("Protect your own area"),
privs = {[areas.config.self_protection_privilege]=true},
func = function(name, param)
minetest.log("warning", "/protect invoked, owner = " .. name ..
" AreaName = " .. param)
@ -184,7 +183,6 @@ minetest.register_chatcommand("find_areas", {
minetest.register_chatcommand("list_areas", {
description = S("List your areas, or all areas if you are an admin."),
func = function(name, param)
minetest.log("warning", "/list_areas invoked, owner = " .. name ..
" AreaName = " .. param)
@ -433,7 +431,63 @@ minetest.register_chatcommand("areas_cleanup", {
end
areas:save()
return true, "Total areas: " .. total .. ", Removed: " ..
count .. " areas. New count: " .. (total - count)
return true, S("Total areas: @1, Removed: @1 areas. New count: @3.",
total, count, (total - count))
end
})
-- Get a table with all connected players with a position
local function player_list()
local list = {}
for _, player in pairs(minetest.get_connected_players()) do
local pos = player:get_pos()
if minetest.is_valid_pos(pos) then
local name = player:get_player_name()
list[#list + 1] = {name = name, pos = pos}
end
end
return list
end
minetest.register_chatcommand("area_pvp", {
description = "Toggle PvP in an area",
params = "<ID>",
func = function(name, param)
local id = tonumber(param)
if not id then
return false, S("Invalid usage, see /help @1.", "area_pvp")
end
if not areas:isAreaOwner(id, name) then
return false,
S("Area @1 does not exist or is not owned by you.", id)
end
local canPvP = areas.areas[id].canPvP
if not canPvP then
local players = {}
for _, info in pairs(player_list()) do
local inAreas = areas:getAreasAtPos(info.pos)
for areaid, area in pairs(inAreas) do
if name ~= info.name and id == areaid then
players[#players + 1] = info.name
end
end
end
if next(players) then
return false,
S("You cannot enable PvP, there are other players in the area: @1.",
table.concat(players, ", "))
end
end
-- Save false as nil to avoid inflating the DB.
areas.areas[id].canPvP = not canPvP or nil
areas:save()
return true, S("PvP is @1 in area @2.",
not canPvP and S("enabled") or S("disabled"), id)
end
})

View File

@ -26,9 +26,11 @@ minetest.register_playerstep(function(_, playernames)
local areaStrings = {}
for id, area in pairs(areas:getAreasAtPos(pos)) do
areaStrings[#areaStrings+1] = ("%s [%u] (%s%s)")
areaStrings[#areaStrings+1] = ("%s [%u] (%s)%s%s%s")
:format(area.name, id, area.owner,
area.open and ":open" or "")
area.open and (" " .. S("Open")) or "",
(area.open and area.canPvP and " | " or ""), -- shitcode detected XD
area.canPvP and (" " .. S("PvP enabled")) or "")
end
local str = ""

View File

@ -1,5 +1,7 @@
local S = areas.S
local enable_damage = minetest.settings:get_bool("enable_damage")
local old_is_protected = minetest.is_protected
local disallowed = {
@ -51,10 +53,54 @@ minetest.register_on_protection_violation(function(pos, name)
-- Little damage player
local player = minetest.get_player_by_name(name)
if player and player:is_player() then
local hp = player:get_hp()
if hp and hp > 2 then
player:set_hp(hp - 1)
if enable_damage then
local hp = player:get_hp()
if hp and hp > 2 then
player:set_hp(hp - 1)
end
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
})
end
end
end
end)
minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, _, _, damage)
if not enable_damage then
return false
end
-- If it's a mob, deal damage as usual
if not hitter or not hitter:is_player() then
return false
end
-- It is possible to use cheats
if time_from_last_punch < 0.25 then
minetest.chat_send_player(hitter:get_player_name(), S("Wow, wow, take it easy!"))
return true
end
-- Check if the victim is in an area with allowed PvP or in an unprotected area
local inAreas = areas:getAreasAtPos(player:get_pos())
-- If the table is empty, PvP is not allowed
if not next(inAreas) then
return true
end
-- Do any of the areas have allowed PvP?
for id, area in pairs(inAreas) do
if area.canPvP then
return false
end
end
-- Otherwise, it doesn't do damage
minetest.chat_send_player(hitter:get_player_name(), S("PvP is not allowed in this area!"))
return true
end)

View File

@ -101,7 +101,8 @@ function areas:add(owner, name, pos1, pos2, parent)
pos1 = pos1,
pos2 = pos2,
owner = owner,
parent = parent
parent = parent,
canPvP = nil
}
for i=1, #areas.registered_on_adds do
@ -172,6 +173,17 @@ function areas:move(id, area, pos1, pos2)
end
end
-- Check if PvP is enabled in an area
-- @returns true or false (enabled or disabled)
function areas:canPvP(id)
local area = self.areas[id]
if not area then
return true
end
-- canPvP is nil when false
return area.canPvP or false
end
-- Checks if a area between two points is entirely contained by another area.
-- Positions must be sorted.
function areas:isSubarea(pos1, pos2, id)

View File

@ -66,6 +66,11 @@ You have extended area protection limits ("areas_high_limit" privilege).=У ва
You have the necessary privilege ("@1").=У вас есть необходимая привилегия ("@1").
You need to select an area first.=Вам нужно выбрать зону вначале.
You cannot enable PvP, there are other players in the area: @1.=Вы не можете включить PvP, в зоне есть другие игроки: @1.
PvP is @1 in area @2.=PvP @1 в зоне @2.
enabled=включен
disabled=выключен
### chatcommands.lua ###
### pos.lua ###
@ -74,12 +79,15 @@ Invalid usage, see /help @1.=Неправильное использование
### hud.lua ###
:open=:открыта
Areas:=Зоны:
Open=Открыта
PvP enabled=PvP включен
### interact.lua ###
@1 is protected by @2.=@1 защищено @2.
Wow, wow, take it easy!=Вау-вау, полегче!
PvP is not allowed in this area!=PvP отключено в этой в этой зоне!
### internal.lua ###