Add 'spawn' mod to spawn new players in suitable starting biomes (#2091)
authorParamat <paramat@users.noreply.github.com>
Fri, 13 Apr 2018 01:21:43 +0000 (02:21 +0100)
committerGitHub <noreply@github.com>
Fri, 13 Apr 2018 01:21:43 +0000 (02:21 +0100)
Disabled in mgv6 and singlenode mapgens, by setting, or if
'static_spawnpoint' is set.

Cleanup format of minetest.conf.example.

minetest.conf.example
mods/spawn/README.txt [new file with mode: 0644]
mods/spawn/depends.txt [new file with mode: 0644]
mods/spawn/init.lua [new file with mode: 0644]
mods/spawn/license.txt [new file with mode: 0644]
settingtypes.txt

index 9393b1a52a0ddb0531605768e7880a630ac15a4b..672709d3ef2871913850af4b8295d6a5c6b9a496 100644 (file)
@@ -1,18 +1,21 @@
-# This file contains settings of Minetest Game that can be changed in minetest.conf
+# This file contains settings of Minetest Game that can be changed in
+# minetest.conf.
 # By default, all the settings are commented and not functional.
 # Uncomment settings by removing the preceding #.
 
-# Whether creative mode (fast digging of all blocks, unlimited resources) should be enabled
+# Whether creative mode (fast digging of all blocks, unlimited resources) should
+# be enabled.
 #creative_mode = false
 
 # Sets the behaviour of the inventory items when a player dies.
-#  "bones": Store all items inside a bone node but drop items if inside protected area
-#  "drop": Drop all items on the ground
-#  "keep": Player keeps all items
+#  "bones": Store items in a bone node but drop items if inside protected area.
+#  "drop": Drop items on the ground.
+#  "keep": Player keeps items.
 #bones_mode = "bones"
 
-# The time in seconds after which the bones of a dead player can be looted by everyone
-# 0 to disable
+# The time in seconds after which the bones of a dead player can be looted by
+# everyone.
+# 0 to disable.
 #share_bones_time = 1200
 
 # How much earlier the bones of a dead player can be looted by
@@ -20,8 +23,9 @@
 # 0 to disable. By default it is "share_bones_time" divide by four.
 #share_bones_time_early = 300
 
-# Whether fire should be enabled. If disabled, 'basic flame' nodes will disappear.
-# 'permanent flame' nodes will remain with either setting.
+# Whether fire should be enabled. If disabled, 'basic_flame' nodes will
+# disappear.
+# 'permanent_flame' nodes will remain with either setting.
 #enable_fire = true
 
 # Enable flame sound.
 # Whether lavacooling should be enabled.
 #enable_lavacooling = true
 
-# Whether the stuff in initial_stuff should be given to new players
+# Whether the stuff in initial_stuff should be given to new players.
 #give_initial_stuff = false
-#initial_stuff = default:pick_steel,default:axe_steel,default:shovel_steel,default:torch 99,default:cobble 99
+#initial_stuff = default:pick_steel,default:axe_steel,default:shovel_steel,
+default:torch 99,default:cobble 99
 
-# Whether the TNT mod should be enabled
+# Whether the TNT mod should be enabled.
 #enable_tnt = <true in singleplayer, false in multiplayer>
 
-# The radius of a TNT explosion
+# The radius of a TNT explosion.
 #tnt_radius = 3
 
 # Enable the stairs mod ABM that replaces the old 'upside down'
 # stair and slab nodes in old maps with the new param2 versions.
 #enable_stairs_replace_abm = false
 
-# Whether you allow respawning in beds
-# Default value is true
+# Whether to allow respawning in beds.
+# Default value is true.
 #enable_bed_respawn = true
 
-# Whether players can skip night by sleeping
-# Default value is true
+# Whether players can skip night by sleeping.
+# Default value is true.
 #enable_bed_night_skip = true
+
+# Whether the engine's spawn search, which does not check for a suitable
+# starting biome, is used.
+# Default value is false.
+#engine_spawn = false
diff --git a/mods/spawn/README.txt b/mods/spawn/README.txt
new file mode 100644 (file)
index 0000000..fc16c2a
--- /dev/null
@@ -0,0 +1,7 @@
+Minetest Game mod: spawn
+========================
+See license.txt for license information.
+
+Authors of source code
+----------------------
+paramat (MIT)
diff --git a/mods/spawn/depends.txt b/mods/spawn/depends.txt
new file mode 100644 (file)
index 0000000..4ad96d5
--- /dev/null
@@ -0,0 +1 @@
+default
diff --git a/mods/spawn/init.lua b/mods/spawn/init.lua
new file mode 100644 (file)
index 0000000..ae8287f
--- /dev/null
@@ -0,0 +1,124 @@
+-- Disable by mapgen, setting or if 'static_spawnpoint' is set
+--------------------------------------------------------------
+
+local mg_name = minetest.get_mapgen_setting("mg_name")
+if mg_name == "v6" or mg_name == "singlenode" or
+               minetest.settings:get("static_spawnpoint") or
+               minetest.settings:get_bool("engine_spawn") then
+       return
+end
+
+
+-- Parameters
+-------------
+
+-- Resolution of search grid in nodes.
+local res = 64
+-- Number of points checked in the square search grid (edge * edge).
+local checks = 128 * 128
+-- Starting point for biome checks. This also sets the y co-ordinate for all
+-- points checked, so the suitable biomes must be active at this y.
+local pos = {x = 0, y = 8, z = 0}
+
+
+-- Table of suitable biomes
+
+local biome_ids = {
+       minetest.get_biome_id("taiga"),
+       minetest.get_biome_id("coniferous_forest"),
+       minetest.get_biome_id("deciduous_forest"),
+       minetest.get_biome_id("grassland"),
+       minetest.get_biome_id("savanna"),
+}
+
+-- End of parameters
+--------------------
+
+
+-- Direction table
+
+local dirs = {
+       {x = 0, y = 0, z = 1},
+       {x = -1, y = 0, z = 0},
+       {x = 0, y = 0, z = -1},
+       {x = 1, y = 0, z = 0},
+}
+
+
+-- Initial variables
+
+local edge_len = 1
+local edge_dist = 0
+local dir_step = 0
+local dir_ind = 1
+local searched = false
+local success = false
+local spawn_pos = {}
+
+
+--Functions
+-----------
+
+-- Get next position on square search spiral
+
+local function next_pos()
+       if edge_dist == edge_len then
+               edge_dist = 0
+               dir_ind = dir_ind + 1
+               if dir_ind == 5 then
+                       dir_ind = 1
+               end
+               dir_step = dir_step + 1
+               edge_len = math.floor(dir_step / 2) + 1
+       end
+
+       local dir = dirs[dir_ind]
+       local move = vector.multiply(dir, res)
+
+       edge_dist = edge_dist + 1
+
+       return vector.add(pos, move)
+end
+
+
+-- Spawn position search
+
+local function search()
+       for iter = 1, checks do
+               local biome_data = minetest.get_biome_data(pos)
+               -- Sometimes biome_data is nil
+               local biome = biome_data and biome_data.biome
+               for id_ind = 1, #biome_ids do
+                       local biome_id = biome_ids[id_ind]
+                       if biome == biome_id then
+                               local spawn_y = minetest.get_spawn_level(pos.x, pos.z)
+                               if spawn_y then
+                                       spawn_pos = {x = pos.x, y = spawn_y, z = pos.z}
+                                       return true
+                               end
+                       end
+               end
+
+               pos = next_pos()
+       end
+
+       return false
+end
+
+
+-- On new player spawn
+
+-- Search for new player spawn once per server session. If successful, store
+-- position and reposition new players, otherwise leave them at engine spawn
+-- position.
+
+minetest.register_on_newplayer(function(player)
+       if not searched then
+               success = search()
+               searched = true
+       end
+
+       if success then
+               player:setpos(spawn_pos)
+       end
+end)
diff --git a/mods/spawn/license.txt b/mods/spawn/license.txt
new file mode 100644 (file)
index 0000000..a466aab
--- /dev/null
@@ -0,0 +1,24 @@
+License of source code
+----------------------
+
+The MIT License (MIT)
+Copyright (C) 2018 paramat
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this
+software and associated documentation files (the "Software"), to deal in the Software
+without restriction, including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+
+For more details:
+https://opensource.org/licenses/MIT
index 855235c2551735c09efdcbae94c1f2f1e79cbd34..343d041d4804396f84d63394061ba33861ef0668 100644 (file)
@@ -46,3 +46,7 @@ share_bones_time (Bone share time) int 1200 0
 
 #    Replaces old stairs with new ones. Only required for older worlds.
 enable_stairs_replace_abm (Replace old stairs) bool false
+
+#    If enabled, use the engine's spawn search which does not check for a
+#    suitable starting biome.
+engine_spawn (Use engine spawn search) bool false