diff --git a/api.lua b/api.lua index 730e96d..b5cfe3e 100644 --- a/api.lua +++ b/api.lua @@ -74,7 +74,7 @@ function areas:canInteract(pos, name) end local owned = false for _, area in pairs(self:getAreasAtPos(pos)) do - if area.owner == name or area.open then + if area.owner == name or area.open or usergroups:user_is_in_group(name, area.group) then return true else owned = true @@ -87,11 +87,24 @@ end function areas:getNodeOwners(pos) local owners = {} for _, area in pairs(self:getAreasAtPos(pos)) do - table.insert(owners, area.owner) + if area.owner and (area.owner ~= "") then + table.insert(owners, area.owner) + end end return owners end +-- Returns a table (list) of all groups that own an area +function areas:getNodeOwnerGroups(pos) + local ownerGroups = {} + for _, area in pairs(self:getAreasAtPos(pos)) do + if area.group then + table.insert(ownerGroups, area.group) + end + end + return ownerGroups +end + --- Checks if the area intersects with an area that the player can't interact in. -- Note that this fails and returns false when the specified area is fully -- owned by the player, but with multiple protection zones, none of which diff --git a/chatcommands.lua b/chatcommands.lua index 6079e93..9888cb0 100644 --- a/chatcommands.lua +++ b/chatcommands.lua @@ -68,6 +68,41 @@ minetest.register_chatcommand("set_owner", { end }) +minetest.register_chatcommand("set_group_owner", { + params = " ", + description = "Protect an area beetween two positions and give" + .." a group access to it without setting the parent of the" + .." area to any existing area", + privs = areas.adminPrivs, + func = function(name, param) + local groupName, areaName = param:match('^(%S+)%s(.+)$') + + if not groupName then + return false, "Incorrect usage, see /help set_owner." + end + + local pos1, pos2 = areas:getPos(name) + if not (pos1 and pos2) then + return false, "You need to select an area first." + end + + if not usergroups:group_exists(groupName) then + return false, "The group \"" + ..groupName.."\" does not exist." + end + + minetest.log("action", name.." runs /set_owner. Group = "..groupName.. + " AreaName = "..areaName.. + " StartPos = "..minetest.pos_to_string(pos1).. + " EndPos = " ..minetest.pos_to_string(pos2)) + + local id = areas:add_with_group(groupName, areaName, pos1, pos2, nil) + areas:save() + + return true, "Area protected. ID: "..id + end +}) + minetest.register_chatcommand("add_owner", { params = " ", diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..d840536 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +usergroups diff --git a/hud.lua b/hud.lua index 0b7931f..e7c79d3 100644 --- a/hud.lua +++ b/hud.lua @@ -3,6 +3,18 @@ areas.hud = {} minetest.register_globalstep(function(dtime) + function format_owner(area) + if area.owner then + return area.owner + end + + if area.group then + return area.group + end + + return "" + end + for _, player in pairs(minetest.get_connected_players()) do local name = player:get_player_name() local pos = vector.round(player:getpos()) @@ -10,15 +22,16 @@ minetest.register_globalstep(function(dtime) for id, area in pairs(areas:getAreasAtPos(pos)) do table.insert(areaStrings, ("%s [%u] (%s%s)") - :format(area.name, id, area.owner, + :format(area.name, id, format_owner(area), area.open and ":open" or "")) end for i, area in pairs(areas:getExternalHudEntries(pos)) do local str = "" + local formattedOwner = format_owner(area) if area.name then str = area.name .. " " end if area.id then str = str.."["..area.id.."] " end - if area.owner then str = str.."("..area.owner..")" end + if formattedOwner then str = str.."("..formattedOwner..")" end table.insert(areaStrings, str) end diff --git a/interact.lua b/interact.lua index 2e54800..9da2ab7 100644 --- a/interact.lua +++ b/interact.lua @@ -1,4 +1,3 @@ - local old_is_protected = minetest.is_protected function minetest.is_protected(pos, name) if not areas:canInteract(pos, name) then @@ -10,6 +9,11 @@ end minetest.register_on_protection_violation(function(pos, name) if not areas:canInteract(pos, name) then local owners = areas:getNodeOwners(pos) + + if not owners[1] then + owners = areas:getNodeOwnerGroups(pos) + end + minetest.chat_send_player(name, ("%s is protected by %s."):format( minetest.pos_to_string(pos), diff --git a/internal.lua b/internal.lua index bf7e92c..1de6047 100644 --- a/internal.lua +++ b/internal.lua @@ -96,6 +96,27 @@ function areas:add(owner, name, pos1, pos2, parent) return id end +--- Add a area. +-- @return The new area's ID. +function areas:add_with_group(group, name, pos1, pos2, parent) + local id = findFirstUnusedIndex(self.areas) + self.areas[id] = { + name = name, + pos1 = pos1, + pos2 = pos2, + group = group, + parent = parent + } + -- Add to AreaStore + if self.store then + local sid = self.store:insert_area(pos1, pos2, tostring(id)) + if self:checkAreaStoreId(sid) then + self.store_ids[id] = sid + end + end + return id +end + --- Remove a area, and optionally it's children recursively. -- If a area is deleted non-recursively the children will -- have the removed area's parent as their new parent.