From 758b3d0dd0caf8d7c59e3c8ecbdfe5e2595102b9 Mon Sep 17 00:00:00 2001 From: MoNTE48 Date: Wed, 19 May 2021 10:42:16 +0200 Subject: [PATCH] Add the best PvP solution you've seen --- chatcommands.lua | 62 +++++++++++++++++++++++++++++++++++++++++++--- hud.lua | 6 +++-- interact.lua | 52 +++++++++++++++++++++++++++++++++++--- internal.lua | 14 ++++++++++- locale/areas.ru.tr | 10 +++++++- 5 files changed, 133 insertions(+), 11 deletions(-) diff --git a/chatcommands.lua b/chatcommands.lua index 3107fab..189b498 100644 --- a/chatcommands.lua +++ b/chatcommands.lua @@ -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 = "", + 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 }) diff --git a/hud.lua b/hud.lua index 3b28ed5..dc47e52 100644 --- a/hud.lua +++ b/hud.lua @@ -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 = "" diff --git a/interact.lua b/interact.lua index ce06560..a5a736e 100644 --- a/interact.lua +++ b/interact.lua @@ -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) diff --git a/internal.lua b/internal.lua index 37516e0..cbaf4d5 100644 --- a/internal.lua +++ b/internal.lua @@ -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) diff --git a/locale/areas.ru.tr b/locale/areas.ru.tr index 1aa19e0..eead0a1 100644 --- a/locale/areas.ru.tr +++ b/locale/areas.ru.tr @@ -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 ###