diff options
| author | ShadowNinja <shadowninja@minetest.net> | 2014-07-12 16:37:54 -0400 | 
|---|---|---|
| committer | ShadowNinja <shadowninja@minetest.net> | 2014-07-12 16:37:54 -0400 | 
| commit | e17cda925b7ab7d3d586ed1c40c591854704d770 (patch) | |
| tree | 09fb9de01e475713eb9332e0d338e3a161d730be | |
| parent | ee212466bfb6f19bc30a1c9f0b591f733ee30450 (diff) | |
Add canInteractInArea
| -rw-r--r-- | api.lua | 31 | ||||
| -rw-r--r-- | internal.lua | 18 | ||||
| -rw-r--r-- | legacy.lua | 5 | ||||
| -rw-r--r-- | pos.lua | 2 | 
4 files changed, 41 insertions, 15 deletions
| @@ -39,3 +39,34 @@ function areas:getNodeOwners(pos)  	return owners  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 miltiple protection zones, none of which +-- cover the entire checked area. +-- @return Boolean indicating whether the player can interact in that area. +-- @return Un-owned intersecting area id, if found. +function areas:canInteractInArea(pos1, pos2, name) +	areas:sortPos(pos1, pos2) +	-- First check for a fully enclosing owned area +	for id, area in pairs(self.areas) do +		-- A little optimization: isAreaOwner isn't necessary here +		-- since we're iterating through all areas. +		if area.owner == name and self:isSubarea(pos1, pos2, id) then +			return true +		end +	end +	-- Then check for intersecting non-owned areas +	for id, area in pairs(self.areas) do +		local p1, p2 = area.pos1, area.pos2 +		if (p1.x <= pos2.x and p2.x >= pos1.x) and +		   (p1.y <= pos2.y and p2.y >= pos1.y) and +		   (p1.z <= pos2.z and p2.z >= pos1.z) then +			-- Found an intersecting area +			if not areas:isAreaOwner(id, name) then +				return false, id +			end +		end +	end +	return true +end + diff --git a/internal.lua b/internal.lua index 93b873f..f032b1b 100644 --- a/internal.lua +++ b/internal.lua @@ -81,7 +81,7 @@ function areas:isSubarea(pos1, pos2, id)  	if not area then  		return false  	end -	p1, p2 = area.pos1, area.pos2 +	local p1, p2 = area.pos1, area.pos2  	if (pos1.x >= p1.x and pos1.x <= p2.x) and  	   (pos2.x >= p1.x and pos2.x <= p2.x) and  	   (pos1.y >= p1.y and pos1.y <= p2.y) and @@ -141,17 +141,11 @@ function areas:canPlayerAddArea(pos1, pos2, name)  	end  	-- Check intersecting areas -	for id, area in pairs(self.areas) do -		if (area.pos1.x <= pos2.x and area.pos2.x >= pos1.x) and -		   (area.pos1.y <= pos2.y and area.pos2.y >= pos1.y) and -		   (area.pos1.z <= pos2.z and area.pos2.z >= pos1.z) then -			-- Found an area intersecting with the suplied area -			if not areas:isAreaOwner(id, name) then -				return false, ("The area intersects with" -					.." %s [%u] owned by %s.") -					:format(area.name, id, area.owner) -			end -		end +	local can, id = self:canInteractInArea(pos1, pos2, name) +	if not can then +		local area = self.areas[id] +		return false, ("The area intersects with %s [%u] owned by %s.") +				:format(area.name, id, area.owner)  	end  	return true @@ -31,7 +31,7 @@ minetest.register_chatcommand("legacy_load_areas", {  				nil, nil, nil, nil, nil, nil  			-- Area positions sorting -			area.pos1, area.pos2 = areas:sortPos(area.pos1, area.pos2) +			areas:sortPos(area.pos1, area.pos2)  			-- Add name  			area.name = "unnamed" @@ -43,7 +43,8 @@ minetest.register_chatcommand("legacy_load_areas", {  		areas:save()  		minetest.chat_send_player(name, "Converted areas saved. Done.") -end}) +	end +})  function areas:node_ownership_load()  	local filename = minetest.get_worldpath().."/owners.tbl" @@ -168,7 +168,7 @@ end)  -- Modifies positions `pos1` and `pos2` so that each component of `pos1`  -- is less than or equal to its corresponding component of `pos2`, --- returning two new positions +-- returning the two positions.  function areas:sortPos(pos1, pos2)  	if pos1.x > pos2.x then  		pos2.x, pos1.x = pos1.x, pos2.x | 
