Manual update due to conflict
This adds part of PR #4 and they came from inpos/areas repo, author for the changes is ElementW.
							
								
								
									
										108
									
								
								api.lua
									
									
									
									
									
								
							
							
						
						| @@ -14,6 +14,13 @@ function areas:getExternalHudEntries(pos) | |||||||
| 	return areas | 	return areas | ||||||
| end | end | ||||||
|  |  | ||||||
|  | --plants to place in openfarming | ||||||
|  | local plants = { ["farming:blueberries"]="air", ["farming:carrot"]="air", ["farming:coffee_beans"]="air", ["farming:corn"]="air", ["farming:cucumber"]="air", | ||||||
|  | 				["farming:melon_slice"]="air", ["farming:potato"]="air", ["farming:pumpkin_slice"]="air", ["farming:raspberries"]="air", ["farming:rhubarb"]="air", | ||||||
|  | 				 ["farming:tomato"]="air", ["farming:seed_cotton"]="air", ["farming:seed_wheat"]="air",["default:papyrus"]="air", ["farming:trellis"]="air", | ||||||
|  | 				 ["farming:grapes"]="farming:trellis", ["farming:beanpole"]="air", ["farming:beans"]="farming:beanpole", | ||||||
|  | 				} | ||||||
|  |  | ||||||
| --- Returns a list of areas that include the provided position. | --- Returns a list of areas that include the provided position. | ||||||
| function areas:getAreasAtPos(pos) | function areas:getAreasAtPos(pos) | ||||||
| 	local res = {} | 	local res = {} | ||||||
| @@ -73,9 +80,42 @@ function areas:canInteract(pos, name) | |||||||
| 		return true | 		return true | ||||||
| 	end | 	end | ||||||
| 	local owned = false | 	local owned = false | ||||||
|  | 	 | ||||||
|  | 	-- to avoid crash with water lily | ||||||
|  | 	if pos == nil  then | ||||||
|  | 		return not owned | ||||||
|  | 	end | ||||||
|  | 	 | ||||||
| 	for _, area in pairs(self:getAreasAtPos(pos)) do | 	for _, area in pairs(self:getAreasAtPos(pos)) do | ||||||
| 		if area.owner == name or area.open then | 		if area.owner == name or area.open then | ||||||
| 			return true | 			return true | ||||||
|  | 		 | ||||||
|  | 		elseif area.openfarming then | ||||||
|  | 			-- if area is openfarming | ||||||
|  | 			local node = minetest.get_node(pos).name | ||||||
|  | 			if not minetest.registered_nodes[node] then | ||||||
|  | 				return false | ||||||
|  | 			end | ||||||
|  | 			local player = minetest.get_player_by_name(name) | ||||||
|  | 			if not player then | ||||||
|  | 				return false | ||||||
|  | 			end | ||||||
|  | 			local wstack = player:get_wielded_item():get_name() | ||||||
|  | 			if wstack == "" then | ||||||
|  | 				wstack = "hand" | ||||||
|  | 			end | ||||||
|  |  | ||||||
|  | 			--on_dig | ||||||
|  | 			if minetest.get_item_group(node, "plant") == 1 and (wstack == "hand" or minetest.registered_tools[wstack]) then | ||||||
|  | 				return true | ||||||
|  | 			end | ||||||
|  |  | ||||||
|  | 			--on_place | ||||||
|  | 			if plants[wstack] ~= nil and plants[wstack] == node then | ||||||
|  | 				return true | ||||||
|  | 			end | ||||||
|  |  | ||||||
|  | 			owned = true | ||||||
| 		else | 		else | ||||||
| 			owned = true | 			owned = true | ||||||
| 		end | 		end | ||||||
| @@ -83,6 +123,74 @@ function areas:canInteract(pos, name) | |||||||
| 	return not owned | 	return not owned | ||||||
| end | end | ||||||
|  |  | ||||||
|  | function areas:canMakeArea(pos1, pos2, name) --MFF crabman(25/02/2016) fix areas in areas | ||||||
|  | 	if name and minetest.check_player_privs(name, self.adminPrivs) then | ||||||
|  | 		return true | ||||||
|  | 	end | ||||||
|  | 	areas:sortPos(pos1, pos2) | ||||||
|  |  | ||||||
|  | 	local id_areas_intersect = {} | ||||||
|  | 	local areas = self:getAreasIntersectingArea(pos1, pos2) | ||||||
|  |  | ||||||
|  | 	if not areas then return true end | ||||||
|  |  | ||||||
|  | 	for id, area in pairs(areas) do | ||||||
|  | 		if area.owner == name and self:isSubarea(pos1, pos2, id) then | ||||||
|  | 			return true | ||||||
|  | 		end | ||||||
|  | 		if not area.open and not self:isAreaOwner(id, name) then | ||||||
|  | 			table.insert(id_areas_intersect, id) | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	if #id_areas_intersect > 0 then | ||||||
|  | 		return false, id_areas_intersect[1] | ||||||
|  | 	end | ||||||
|  |  | ||||||
|  | 	return true | ||||||
|  | end | ||||||
|  |  | ||||||
|  |  | ||||||
|  | --MFF crabman(5/03/2016 ) return special area pos if a spawn is set. | ||||||
|  | --1 party (2 party in beds mod) | ||||||
|  | function areas:getSpawn(pos) | ||||||
|  | 	for _, area in pairs(areas:getAreasAtPos(pos)) do | ||||||
|  | 		if area.spawn and area.spawn.x then | ||||||
|  | 			return area.spawn | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	return nil | ||||||
|  | end | ||||||
|  |  | ||||||
|  | --MFF DEBUT crabman(17/09/2015 ) respawn player in special area(event) if a spawn is set. | ||||||
|  | --1 party (2 party in beds mod) | ||||||
|  | local dead_players = {} | ||||||
|  | minetest.register_on_dieplayer(function(player) | ||||||
|  | 	local player_name = player:get_player_name() | ||||||
|  | 	if not player_name then return end | ||||||
|  | 	local pos = player:getpos() | ||||||
|  | 	if pos then | ||||||
|  | 		dead_players[player_name] = pos | ||||||
|  | 	end | ||||||
|  | end) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function areas:onRespawn(player) | ||||||
|  | 	local player_name = player:get_player_name() | ||||||
|  | 	if not player_name or not dead_players[player_name] then return false end | ||||||
|  | 	local pos = dead_players[player_name] | ||||||
|  | 	dead_players[player_name] = nil | ||||||
|  | 	if pos then | ||||||
|  | 		for _, area in pairs(areas:getAreasAtPos(pos)) do | ||||||
|  | 			if area.spawn then | ||||||
|  | 				player:setpos(area.spawn) | ||||||
|  | 				return true | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 	return false | ||||||
|  | end | ||||||
|  |  | ||||||
| -- Returns a table (list) of all players that own an area | -- Returns a table (list) of all players that own an area | ||||||
| function areas:getNodeOwners(pos) | function areas:getNodeOwners(pos) | ||||||
| 	local owners = {} | 	local owners = {} | ||||||
|   | |||||||
| @@ -285,6 +285,26 @@ minetest.register_chatcommand("area_open", { | |||||||
| 	end | 	end | ||||||
| }) | }) | ||||||
|  |  | ||||||
|  | minetest.register_chatcommand("area_openfarming", { | ||||||
|  | 	params = "<ID>", | ||||||
|  | 	description = "Toggle an area open (anyone can interact farming) or closed", | ||||||
|  | 	func = function(name, param) | ||||||
|  | 		local id = tonumber(param) | ||||||
|  | 		if not id then | ||||||
|  | 			return false, "Invalid usage, see /help area_openfarming." | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		if not areas:isAreaOwner(id, name) then | ||||||
|  | 			return false, "Area "..id.." does not exist" | ||||||
|  | 					.." or is not owned by you." | ||||||
|  | 		end | ||||||
|  | 		local openfarming = not areas.areas[id].openfarming | ||||||
|  | 		-- Save false as nil to avoid inflating the DB. | ||||||
|  | 		areas.areas[id].openfarming = openfarming or nil | ||||||
|  | 		areas:save() | ||||||
|  | 		return true, ("Area %s to farming."):format(openfarming and "opened" or "closed") | ||||||
|  | 	end | ||||||
|  | }) | ||||||
|  |  | ||||||
| minetest.register_chatcommand("move_area", { | minetest.register_chatcommand("move_area", { | ||||||
| 	params = "<ID>", | 	params = "<ID>", | ||||||
| @@ -403,3 +423,60 @@ minetest.register_chatcommand("area_info", { | |||||||
| 	end, | 	end, | ||||||
| }) | }) | ||||||
|  |  | ||||||
|  | --MFF DEBUT crabman(17/09/2015 ) respawn player at in special area(event) if a spawn is set. | ||||||
|  | +minetest.register_chatcommand("area_addspawn", { | ||||||
|  | 	params = "<ID>", | ||||||
|  | 		privs = areas.adminPrivs, | ||||||
|  | 	description = "Define special spawn for area", | ||||||
|  | 	func = function(name, param) | ||||||
|  | 		local id = param:match("^(%d+)") | ||||||
|  | 		if not id then | ||||||
|  | 			return false, "Invalid usage, see /help area_addspawn." | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		id = tonumber(id) | ||||||
|  | 		if not id then | ||||||
|  | 			return false, "Error, Param id must be int." | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		local player = minetest.get_player_by_name(name) | ||||||
|  | 		if not player then | ||||||
|  | 			return false, "Error, there is not player" | ||||||
|  | 		end | ||||||
|  | 		local pos = player:getpos() | ||||||
|  | 		if not pos then | ||||||
|  | 			return false, "Error, there is not pos." | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		if not areas.areas[id] then | ||||||
|  | 			return false, "Area ".. id .." does not exist." | ||||||
|  | 		end | ||||||
|  | 		areas.areas[id].spawn = pos | ||||||
|  | 		areas:save() | ||||||
|  | 		return true, "spawn of area ".. id .." defined." | ||||||
|  | 	end | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | minetest.register_chatcommand("area_delspawn", { | ||||||
|  | 	params = "<ID>", | ||||||
|  | 		privs = areas.adminPrivs, | ||||||
|  | 	description = "Delete special spawn of area", | ||||||
|  | 	func = function(name, param) | ||||||
|  | 		local id = param:match("^(%d+)") | ||||||
|  | 		if not id then | ||||||
|  | 			return false, "Invalid usage, see /help area_delspawn." | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		id = tonumber(id) | ||||||
|  | 		if not id then | ||||||
|  | 			return false, "Error, Param id must be int." | ||||||
|  | 		end | ||||||
|  |  | ||||||
|  | 		if not areas.areas[id] then | ||||||
|  | 			return false, "Area ".. id .." does not exist." | ||||||
|  | 		end | ||||||
|  | 		areas.areas[id].spawn = nil | ||||||
|  | 		areas:save() | ||||||
|  | 		return true, "spawn of area ".. id .." deleted." | ||||||
|  | 	end | ||||||
|  | }) | ||||||
|   | |||||||
							
								
								
									
										84
									
								
								hud.lua
									
									
									
									
									
								
							
							
						
						| @@ -2,16 +2,35 @@ | |||||||
|  |  | ||||||
| areas.hud = {} | areas.hud = {} | ||||||
|  |  | ||||||
| minetest.register_globalstep(function(dtime) | local function tick() | ||||||
| 	for _, player in pairs(minetest.get_connected_players()) do | 	for _, player in pairs(minetest.get_connected_players()) do | ||||||
| 		local name = player:get_player_name() | 		local name = player:get_player_name() | ||||||
| 		local pos = vector.round(player:getpos()) | 		local pos = vector.round(player:getpos()) | ||||||
| 		local areaStrings = {} | 		local area_text = "No area(s)\n\n" | ||||||
|  | 		local area_owner_name = "" | ||||||
|  | 		local mod_owner = 0 | ||||||
|  | 		local mod_open = 0 | ||||||
|  | 		local mod_farming = 0 | ||||||
|  | 		local area_name = "" | ||||||
|  | 		local nb_areas = 0 | ||||||
|  |  | ||||||
| 		for id, area in pairs(areas:getAreasAtPos(pos)) do | 		for id, area in pairs(areas:getAreasAtPos(pos)) do | ||||||
| 			table.insert(areaStrings, ("%s [%u] (%s%s)") | 			nb_areas = nb_areas+1 | ||||||
| 					:format(area.name, id, area.owner, | 			if areas:isAreaOwner(id, name) then | ||||||
| 					area.open and ":open" or "")) | 				mod_owner = 1 | ||||||
|  | 			end | ||||||
|  |  | ||||||
|  | 			if area.open then | ||||||
|  | 				mod_open = 1 | ||||||
|  | 			end | ||||||
|  | 			if area.openfarming then | ||||||
|  | 				mod_farming = 1 | ||||||
|  | 			end | ||||||
|  |  | ||||||
|  | 			if not area.parent then | ||||||
|  | 				area_owner_name = area.owner | ||||||
|  | 				area_name = area.name | ||||||
|  | 			end | ||||||
| 		end | 		end | ||||||
|  |  | ||||||
| 		for i, area in pairs(areas:getExternalHudEntries(pos)) do | 		for i, area in pairs(areas:getExternalHudEntries(pos)) do | ||||||
| @@ -22,33 +41,52 @@ minetest.register_globalstep(function(dtime) | |||||||
| 			table.insert(areaStrings, str) | 			table.insert(areaStrings, str) | ||||||
| 		end | 		end | ||||||
|  |  | ||||||
| 		local areaString = "Areas:" | 		local icon = "areas_not_area.png" | ||||||
| 		if #areaStrings > 0 then | 		if nb_areas > 0 then | ||||||
| 			areaString = areaString.."\n".. | 			local plural = "" | ||||||
| 				table.concat(areaStrings, "\n") | 			if nb_areas > 1 then | ||||||
|  | 				plural = "s" | ||||||
|  | 			end | ||||||
|  | 			area_text = ("%s\nOwner: %s\n%u area" .. plural):format(area_name, area_owner_name, nb_areas) | ||||||
|  | 			icon = ("areas_%u_%u_%u.png"):format(mod_owner, mod_open, mod_farming) | ||||||
| 		end | 		end | ||||||
| 		local hud = areas.hud[name] | 		if not areas.hud[name] then | ||||||
| 		if not hud then | 			areas.hud[name] = {} | ||||||
| 			hud = {} | 			areas.hud[name].icon = player:hud_add({ | ||||||
| 			areas.hud[name] = hud | 				hud_elem_type = "image", | ||||||
| 			hud.areasId = player:hud_add({ | 				position = {x=0,y=1}, | ||||||
|  | 				scale = {x=1,y=1}, | ||||||
|  | 				offset = {x=26,y=-60}, | ||||||
|  | 				text = icon, | ||||||
|  | 			}) | ||||||
|  |  | ||||||
|  | 			areas.hud[name].areas_id = player:hud_add({ | ||||||
| 				hud_elem_type = "text", | 				hud_elem_type = "text", | ||||||
| 				name = "Areas", | 				name = "Areas", | ||||||
| 				number = 0xFFFFFF, | 				number = 0xFFFFFF, | ||||||
| 				position = {x=0, y=1}, | 				position = {x=0, y=1}, | ||||||
| 				offset = {x=8, y=-8}, | 				offset = {x=48, y=-40}, | ||||||
| 				text = areaString, | 				text = area_text, | ||||||
| 				scale = {x=200, y=60}, | 				scale = {x=1, y=1}, | ||||||
| 				alignment = {x=1, y=-1}, | 				alignment = {x=1, y=-1}, | ||||||
| 			}) | 			}) | ||||||
| 			hud.oldAreas = areaString | 			areas.hud[name].old_area_text = area_text | ||||||
| 			return | 			areas.hud[name].old_icon = icon | ||||||
| 		elseif hud.oldAreas ~= areaString then | 		else | ||||||
| 			player:hud_change(hud.areasId, "text", areaString) | 			if areas.hud[name].old_area_text ~= area_text then | ||||||
| 			hud.oldAreas = areaString | 				player:hud_change(areas.hud[name].areas_id, "text", area_text) | ||||||
|  | 				areas.hud[name].old_area_text = area_text | ||||||
|  | 			end | ||||||
|  | 			if areas.hud[name].old_icon ~= icon then | ||||||
|  | 				player:hud_change(areas.hud[name].icon, "text", icon) | ||||||
|  | 				areas.hud[name].old_icon = icon | ||||||
|  | 			end | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| end) | 	minetest.after(1.5, tick) | ||||||
|  | end | ||||||
|  |  | ||||||
|  | tick() | ||||||
|  |  | ||||||
| minetest.register_on_leaveplayer(function(player) | minetest.register_on_leaveplayer(function(player) | ||||||
| 	areas.hud[player:get_player_name()] = nil | 	areas.hud[player:get_player_name()] = nil | ||||||
|   | |||||||
							
								
								
									
										53
									
								
								internal.lua
									
									
									
									
									
								
							
							
						
						| @@ -1,3 +1,5 @@ | |||||||
|  | -- Mega_builder privilege | ||||||
|  | minetest.register_privilege("megabuilder","Can protect an infinite amount of areas.") | ||||||
|  |  | ||||||
| function areas:player_exists(name) | function areas:player_exists(name) | ||||||
| 	return minetest.get_auth_handler().get_auth(name) ~= nil | 	return minetest.get_auth_handler().get_auth(name) ~= nil | ||||||
| @@ -202,33 +204,38 @@ function areas:canPlayerAddArea(pos1, pos2, name) | |||||||
| 				.." the necessary privilege." | 				.." the necessary privilege." | ||||||
| 	end | 	end | ||||||
|  |  | ||||||
| 	local max_size = privs.areas_high_limit and | 	-- MFF: megabuilders skip checks on size and number of areas. | ||||||
| 			self.config.self_protection_max_size_high or | 	if not privs["megabuilder"] then | ||||||
| 			self.config.self_protection_max_size | 		-- Check size | ||||||
| 	if | 		local max_size = privs.areas_high_limit and | ||||||
| 			(pos2.x - pos1.x) > max_size.x or | 				self.config.self_protection_max_size_high or | ||||||
| 			(pos2.y - pos1.y) > max_size.y or | 				self.config.self_protection_max_size | ||||||
| 			(pos2.z - pos1.z) > max_size.z then | 		if | ||||||
| 		return false, "Area is too big." | 				(pos2.x - pos1.x) > max_size.x or | ||||||
| 	end | 				(pos2.y - pos1.y) > max_size.y or | ||||||
|  | 				(pos2.z - pos1.z) > max_size.z then | ||||||
| 	-- Check number of areas the user has and make sure it not above the max | 			return false, "Area is too big." | ||||||
| 	local count = 0 | 		end | ||||||
| 	for _, area in pairs(self.areas) do | 		 | ||||||
| 		if area.owner == name then | 		-- Check number of areas the user has and make sure it not above the max | ||||||
| 			count = count + 1 | 		local count = 0 | ||||||
|  | 		for _, area in pairs(self.areas) do | ||||||
|  | 			if area.owner == name then | ||||||
|  | 				count = count + 1 | ||||||
|  | 			end | ||||||
|  | 		end | ||||||
|  | 		local max_areas = privs.areas_high_limit and | ||||||
|  | 				self.config.self_protection_max_areas_high or | ||||||
|  | 				self.config.self_protection_max_areas | ||||||
|  | 		if count >= max_areas then | ||||||
|  | 			return false, "You have reached the maximum amount of" | ||||||
|  | 					.." areas that you are allowed to  protect." | ||||||
| 		end | 		end | ||||||
| 	end | 	end | ||||||
| 	local max_areas = privs.areas_high_limit and | end | ||||||
| 			self.config.self_protection_max_areas_high or |  | ||||||
| 			self.config.self_protection_max_areas |  | ||||||
| 	if count >= max_areas then |  | ||||||
| 		return false, "You have reached the maximum amount of" |  | ||||||
| 				.." areas that you are allowed to  protect." |  | ||||||
| 	end |  | ||||||
|  |  | ||||||
| 	-- Check intersecting areas | 	-- Check intersecting areas | ||||||
| 	local can, id = self:canInteractInArea(pos1, pos2, name) | 	local can, id = self:canMakeArea(pos1, pos2, name)  --MFF crabman(25/02/2016) fix areas in areas | ||||||
| 	if not can then | 	if not can then | ||||||
| 		local area = self.areas[id] | 		local area = self.areas[id] | ||||||
| 		return false, ("The area intersects with %s [%u] (%s).") | 		return false, ("The area intersects with %s [%u] (%s).") | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								textures/areas_0_0_0.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 275 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/areas_0_0_1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 440 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/areas_0_1_0.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 437 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/areas_0_1_1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 437 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/areas_1_0_0.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 341 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/areas_1_0_1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 491 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/areas_1_1_0.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 278 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/areas_1_1_1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 495 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/areas_not_area.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 288 B |