From 11b18b03decd3e02766b75237d145599130f015c Mon Sep 17 00:00:00 2001 From: 1F616EMO Date: Sun, 18 May 2025 09:03:00 +0800 Subject: [PATCH] Embed co-owner data into the area itself --- api.lua | 6 ++-- chatcommands.lua | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ hud.lua | 10 ++++-- internal.lua | 24 ++++++++++++++ 4 files changed, 121 insertions(+), 4 deletions(-) diff --git a/api.lua b/api.lua index 8042785..3eaaabe 100644 --- a/api.lua +++ b/api.lua @@ -128,8 +128,10 @@ function areas:canInteract(pos, name) end local owned = false for _, area in pairs(areas_list) do - -- Player owns the area or area is open - if area.owner == name or area.open then + -- Player owns the area, area is open, or player is a co-owner + if area.owner == name + or area.open + or (area.co_owners and area.co_owners[name]) then return true elseif areas.factions_available and area.faction_open then if (factions.version or 0) < 2 then diff --git a/chatcommands.lua b/chatcommands.lua index f1f058a..53215e6 100644 --- a/chatcommands.lua +++ b/chatcommands.lua @@ -286,6 +286,7 @@ minetest.register_chatcommand("change_owner", { .." or is not owned by you.", id) end areas.areas[id].owner = newOwner + areas:removeCoOwner(id, newOwner) areas:save() minetest.chat_send_player(newOwner, S("@1 has given you control over the area \"@2\" (ID @3).", @@ -294,6 +295,90 @@ minetest.register_chatcommand("change_owner", { end }) +minetest.register_chatcommand("add_co_owner", { + params = S("").." "..S(""), + description = S("Add a co-owner to an area"), + func = function(name, param) + local id, coOwner = param:match("^(%d+)%s(%S+)$") + if not id then + return false, S("Invalid usage, see" + .." /help @1.", "add_co_owner") + end + + if not areas:player_exists(coOwner) then + return false, S("The player \"@1\" does not exist.", coOwner) + end + + id = tonumber(id) + if not areas:isAreaOwner(id, name) then + return false, S("Area @1 does not exist" + .." or is not owned by you.", id) + end + areas:addCoOwner(id, coOwner) + areas:save() + minetest.chat_send_player(coOwner, + S("@1 has added you as a co-owner of the area \"@2\" (ID @3).", + name, areas.areas[id].name, id)) + return true, S("Co-owner added.") + end +}) + +minetest.register_chatcommand("remove_co_owner", { + params = S("").." "..S(""), + description = S("Remove a co-owner from an area"), + func = function(name, param) + local id, coOwner = param:match("^(%d+)%s(%S+)$") + if not id then + return false, S("Invalid usage, see" + .." /help @1.", "remove_co_owner") + end + + if not areas:player_exists(coOwner) then + return false, S("The player \"@1\" does not exist.", coOwner) + end + + id = tonumber(id) + if not areas:isAreaOwner(id, name) then + return false, S("Area @1 does not exist" + .." or is not owned by you.", id) + end + areas:removeCoOwner(id, coOwner) + areas:save() + minetest.chat_send_player(coOwner, + S("@1 has removed you from the list of co-owners of the area \"@2\" (ID @3).", + name, areas.areas[id].name, id)) + return true, S("Co-owner removed.") + end +}) + +minetest.register_chatcommand("list_co_owners", { + params = S(""), + description = S("List co-owners of an area"), + func = function(name, param) + local id = tonumber(param) + if not id then + return false, S("Invalid usage, see /help @1.", "area_open") + end + + local entry = areas.areas[id] + if not entry then + return false, S("The area @1 does not exist.", id) + end + + local coOwners = {} + for coOwner in pairs(areas:listCoOwners(id)) do + coOwners[#coOwners+1] = coOwner + end + + if #coOwners == 0 then + return true, S("The area \"@1\" (ID @2) have no co-owners.", entry.name, id) + end + + return true, S("Co-owners of area \"@1\" (ID @2): @3", + entry.name, id, table.concat(coOwners, ", ")) + end +}) + minetest.register_chatcommand("area_open", { params = S(""), diff --git a/hud.lua b/hud.lua index 2c4f6ba..8973259 100644 --- a/hud.lua +++ b/hud.lua @@ -42,10 +42,16 @@ minetest.register_globalstep(function(dtime) end end - table.insert(areaStrings, ("%s [%u] (%s%s%s)") + local coOwnersCount = 0 + for _ in pairs(areas:listCoOwners(id)) do + coOwnersCount = coOwnersCount + 1 + end + + table.insert(areaStrings, ("%s [%u] (%s%s%s)%s") :format(area.name, id, area.owner, area.open and S(":open") or "", - faction_info and ": "..faction_info or "")) + faction_info and ": "..faction_info or "", + coOwnersCount ~= 0 and " +" .. coOwnersCount or "")) end for i, area in pairs(areas:getExternalHudEntries(pos)) do diff --git a/internal.lua b/internal.lua index 700af0f..d1b9f51 100644 --- a/internal.lua +++ b/internal.lua @@ -217,6 +217,30 @@ function areas:getChildren(id) return children end +-- Add a co-owner to an area +function areas:addCoOwner(id, name) + local entry = self.areas[id] + entry.co_owners = entry.co_owners or {} + entry.co_owners[name] = true +end + +-- Remove a co-owner from an area +function areas:removeCoOwner(id, name) + local entry = self.areas[id] + if entry.co_owners then + entry.co_owners[name] = nil + if next(entry.co_owners) == nil then + entry.co_owners = nil + end + end +end + +-- Return the list of co-owners +function areas:listCoOwners(id) + local entry = self.areas[id] + return entry.co_owners and table.copy(entry.co_owners) or {} +end + -- checks all possible restrictions registered with -- areas:registerProtectionCondition -- builtin callbacks below