mirror of
				https://github.com/sys4-fr/server-nalc.git
				synced 2025-10-30 20:15:33 +01:00 
			
		
		
		
	Added worldedge mod (with little tweak)
- Added worldedge mod by @DonBatman - Solves #50
This commit is contained in:
		
							
								
								
									
										13
									
								
								mods/worldedge/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								mods/worldedge/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| worldedge | ||||
| ========= | ||||
|  | ||||
| A Minetest Mod that teleports you to the other side of the map when you reach its edge. | ||||
| This gives the illusion that that world is round and you can walk all the way around. | ||||
|  | ||||
| You can change the worlds edge by changing the first variable in init.lua | ||||
| 	local edge = 30000 | ||||
|  | ||||
| License of code: WTFPL | ||||
|  | ||||
| Written by Amaz | ||||
| Modified by Don | ||||
							
								
								
									
										0
									
								
								mods/worldedge/depends.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								mods/worldedge/depends.txt
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										145
									
								
								mods/worldedge/init.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								mods/worldedge/init.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| -------------- | ||||
| -- TODO: Check for terrain height | ||||
|  | ||||
| -- Defines the edge of a world | ||||
| local edge = 30000 | ||||
| -- Radius which should be checked for a good teleportation place | ||||
| local radius = 2 | ||||
| -------------- | ||||
|  | ||||
| local count = 0 | ||||
| local waiting_list = {} | ||||
| --[[ Explanation of waiting_list table | ||||
| 	Index = Player name | ||||
| 	Value = { | ||||
| 		player = Player to teleport | ||||
| 		pos = Destination | ||||
| 		obj = Attacked entity | ||||
| 		notified = When the player must wait longer... | ||||
| 	} | ||||
| ]] | ||||
|  | ||||
| minetest.register_globalstep(function(dtime) | ||||
| 	count = count + dtime | ||||
| 	if count < 3 then | ||||
| 		return | ||||
| 	end | ||||
| 	count = 0 | ||||
|  | ||||
| 	for k, v in pairs(waiting_list) do | ||||
| 		if v.player and v.player:is_player() then | ||||
| 			local pos = get_surface_pos(v.pos) | ||||
| 			if pos then | ||||
| 				v.obj:setpos(pos) | ||||
| 				minetest.after(0.2, function(p, o) | ||||
| 					p:set_detach() | ||||
| 					o:remove() | ||||
| 				end, v.player, v.obj) | ||||
| 				waiting_list[k] = nil | ||||
| 			elseif not v.notified then | ||||
| 				v.notified = true | ||||
| 				minetest.chat_send_player(k, "Sorry, we have not found a free place yet. Please be patient.") | ||||
| 			end | ||||
| 		else | ||||
| 			v.obj:remove() | ||||
| 			waiting_list[k] = nil | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	local newedge = edge - 5 | ||||
| 	-- Check if the players are near the edge and teleport them | ||||
| 	local players = minetest.get_connected_players() | ||||
| 	for i, player in ipairs(players) do | ||||
| 		local name = player:get_player_name() | ||||
| 		if not waiting_list[name] then | ||||
| 			local pos = vector.round(player:getpos()) | ||||
| 			local newpos = nil | ||||
| 			if pos.x >= edge then | ||||
| 				newpos = {x = -newedge, y = 10, z = pos.z} | ||||
| 			elseif pos.x <= -edge then | ||||
| 				newpos = {x = newedge, y = 10, z = pos.z} | ||||
| 			end | ||||
|  | ||||
| 			if pos.z >= edge then | ||||
| 				newpos = {x = pos.x, y = 10, z = -newedge} | ||||
| 				newpos.y = get_surface_pos(newpos).y | ||||
| 			elseif pos.z <= -edge then | ||||
| 				newpos = {x = pos.x, y = 10, z = newedge} | ||||
| 				newpos.y = get_surface_pos(newpos).y | ||||
| 			end | ||||
|  | ||||
| 			-- Teleport the player | ||||
| 			if newpos then | ||||
| 				minetest.chat_send_player(name, "Please wait a few seconds. We will teleport you soon.") | ||||
| 				local obj = minetest.add_entity(newpos, "worldedge:lock") | ||||
| 				player:set_attach(obj, "", {x=0, y=0, z=0}, {x=0, y=0, z=0}) | ||||
| 				waiting_list[name] = { | ||||
| 					player = player, | ||||
| 					pos = newpos, | ||||
| 					obj = obj | ||||
| 				} | ||||
| 				obj:setpos(newpos) | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| end) | ||||
|  | ||||
| function get_surface_pos(pos) | ||||
| 	local minp = { | ||||
| 		x = pos.x - radius - 1, | ||||
| 		y = -10, | ||||
| 		z = pos.z - radius - 1 | ||||
| 	} | ||||
| 	local maxp = { | ||||
| 		x = pos.x + radius - 1, | ||||
| 		y = 50, | ||||
| 		z = pos.z + radius - 1 | ||||
| 	} | ||||
|  | ||||
| 	local c_air = minetest.get_content_id("air") | ||||
| 	local c_ignore = minetest.get_content_id("ignore") | ||||
|  | ||||
| 	local vm = minetest.get_voxel_manip() | ||||
| 	local emin, emax = vm:read_from_map(minp, maxp) | ||||
| 	local area = VoxelArea:new{MinEdge = emin, MaxEdge = emax} | ||||
| 	local data = vm:get_data() | ||||
|  | ||||
| 	local seen_air = false | ||||
| 	local deepest_place = vector.new(pos) | ||||
| 	deepest_place.y = 50 | ||||
|  | ||||
| 	for x = minp.x, maxp.x do | ||||
| 	for z = minp.z, maxp.z do | ||||
| 		local solid = 0 | ||||
| 		for y = deepest_place.y, -10, -1 do | ||||
| 			local node = data[area:index(x, y, z)] | ||||
| 			if y < deepest_place.y and node == c_air then | ||||
| 				deepest_place = vector.new(x, y, z) | ||||
| 				seen_air = true | ||||
| 			end | ||||
| 			if solid > 5 then | ||||
| 				-- Do not find caves! | ||||
| 				break | ||||
| 			end | ||||
| 			if node ~= c_air and node ~= c_ignore then | ||||
| 				solid = solid + 1 | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| 	end | ||||
|  | ||||
| 	if seen_air then | ||||
| 		return deepest_place | ||||
| 	else | ||||
| 		return false | ||||
| 	end | ||||
| end | ||||
|  | ||||
| minetest.register_entity("worldedge:lock", { | ||||
| 	initial_properties = { | ||||
| 		is_visible = false | ||||
| 	}, | ||||
| 	on_activate = function(staticdata, dtime_s) | ||||
| 		--self.object:set_armor_groups({immortal = 1}) | ||||
| 	end | ||||
| }) | ||||
		Reference in New Issue
	
	Block a user