From 0b025e63928913b8b9406c311bcee9c988508c75 Mon Sep 17 00:00:00 2001 From: Paramat Date: Fri, 13 Apr 2018 02:21:43 +0100 Subject: [PATCH] Add 'spawn' mod to spawn new players in suitable starting biomes (#2091) Disabled in mgv6 and singlenode mapgens, by setting, or if 'static_spawnpoint' is set. Cleanup format of minetest.conf.example. --- minetest.conf.example | 44 +++++++++------ mods/spawn/README.txt | 7 +++ mods/spawn/depends.txt | 1 + mods/spawn/init.lua | 124 +++++++++++++++++++++++++++++++++++++++++ mods/spawn/license.txt | 24 ++++++++ settingtypes.txt | 4 ++ 6 files changed, 187 insertions(+), 17 deletions(-) create mode 100644 mods/spawn/README.txt create mode 100644 mods/spawn/depends.txt create mode 100644 mods/spawn/init.lua create mode 100644 mods/spawn/license.txt diff --git a/minetest.conf.example b/minetest.conf.example index 9393b1a5..672709d3 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -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. @@ -30,24 +34,30 @@ # 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 = -# 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 index 00000000..fc16c2a6 --- /dev/null +++ b/mods/spawn/README.txt @@ -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 index 00000000..4ad96d51 --- /dev/null +++ b/mods/spawn/depends.txt @@ -0,0 +1 @@ +default diff --git a/mods/spawn/init.lua b/mods/spawn/init.lua new file mode 100644 index 00000000..ae8287f2 --- /dev/null +++ b/mods/spawn/init.lua @@ -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 index 00000000..a466aabd --- /dev/null +++ b/mods/spawn/license.txt @@ -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 diff --git a/settingtypes.txt b/settingtypes.txt index 855235c2..343d041d 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -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