add a spawn_anywhere setting

master
Tai @ Flex 2017-01-31 18:08:53 +00:00
parent 076c91d5de
commit c525d87d7c
2 changed files with 66 additions and 13 deletions

View File

@ -13,13 +13,18 @@ Players are each given their own randomized spawn point near the spawn origin on
* Players will not spawn in spaces that are protected by any other player than the Server Admin.
* Additional commands
* Players can request a new spawn point by typing `/newspawn` if they have the `newspawn` privilege.
* Players can set their spawn point by typeing `/setspawn` if they have the `setspawn` privelege.
* Players can set their spawn point by typing `/setspawn` if they have the `setspawn` privelege.
* Secondary mode: `spawn_anywhere`
### Spawn Anywhere
If `spawn_anywhere` is set in minetest.conf, any new player can spawn anywhere in the world. In the case of a server, players can spawn very far from eachother, and maybe not meet anybody for a long time ...!
## Considerations for a server
If running on a server consider the following
* make sure the space around the origin is clear of ownership, or owned by teh server admin
* make sure the space around the origin is clear of ownership, or is owned by the server admin
* make sure there is sufficient space (try for 32 nodes radius around and above origin) and walkable nodes in the area
Failure to take these into consideration will often mean that the calculation of a new spawn point will take longer and be more processor-intense.

View File

@ -1,6 +1,8 @@
local origin = minetest.setting_get_pos("static_spawnpoint") or {x=0, y=0, z=0}
local origin = minetest.setting_get_pos("static_spawnpoint") or {x=0, y=50, z=0}
local adminname = minetest.setting_get("name") or "singleplayer"
local spawnanywhere = minetest.setting_get("spawn_anywhere") or false
local playerspawns = {}
local spawnsfile = minetest.get_worldpath().."/dynamicspawns.lua.ser"
@ -24,21 +26,34 @@ minetest.register_chatcommand("spawn", {
end
})
local function newspawn(radius)
local function newspawn(pos, radius)
if not radius then
radius = 32
end
if radius > 256 then
minetest.log("error", "No valid spawnable location")
return origin -- always return a position of sorts
return
end
local pos1 = {x=origin.x-radius, y=origin.y, z=origin.z-radius}
local pos2 = {x=origin.x+radius, y=origin.y+(radius/2), z=origin.z+radius}
minetest.debug("Trying somewhere around "..minetest.pos_to_string(pos))
local breadth = radius
local altitude = radius/2
if spawnanywhere then
breadth = radius
altitude = radius
end
local pos1 = {x=pos.x-breadth, y=pos.y-altitude/2, z=pos.z-breadth}
local pos2 = {x=pos.x+breadth, y=pos.y+altitude, z=pos.z+breadth}
--minetest.emerge_area(pos1, pos2)
local airnodes = minetest.find_nodes_in_area(pos1, pos2, {"air"})
local validnodes = {}
minetest.debug("Found "..tostring(#airnodes).." air nodes within "..tostring(radius))
for _,anode in pairs(airnodes) do
local under = minetest.get_node( {x=anode.x, y=anode.y-1, z=anode.z} ).name
local over = minetest.get_node( {x=anode.x, y=anode.y+1, z=anode.z} ).name
@ -56,7 +71,40 @@ local function newspawn(radius)
return validnodes[math.random(1,#validnodes)]
end
return newspawn(radius+32)
return newspawn(pos, radius+32)
end
local function genpos(name, args)
local pos = origin
local player = minetest.get_player_by_name(name)
local curpos = player:getpos()
if spawnanywhere then
pos = {
x = math.random(-30000,30000),
y = math.random(0, 10),
z = math.random(-30000,30000),
}
end
if args == "here" then
pos = curpos
end
player:setpos(pos)
minetest.after(1,function()
local newpos = newspawn(pos)
if newpos then
playerspawns[name] = newpos
player:setpos(playerspawns[name])
spawnsave()
minetest.chat_send_player(name, "New spawn set !")
else
player:setpos(curpos)
end
end)
end
minetest.register_privilege("newspawn", "Can get a new randomized spawn position.")
@ -65,11 +113,8 @@ minetest.register_chatcommand("newspawn", {
description = "Randomly select a new spawn position.",
params = "",
privs = "newspawn",
func = function(name)
playerspawns[name] = newspawn()
minetest.get_player_by_name(name):setpos(playerspawns[name])
spawnsave()
minetest.chat_send_player(name, "New spawn set !")
func = function(name, args)
genpos(name, args)
end
})
@ -116,6 +161,9 @@ minetest.register_on_newplayer(function(player)
local name = player:get_player_name()
playerspawns[name] = player:getpos()
spawnsave()
if spawnanywhere then
genpos(player:get_player_name() )
end
return
end)