commit 05e5deaa20f93559de9286e5914f82b3f602c440 Author: ferrumcccp Date: Wed Jul 6 22:14:58 2022 +0800 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.txt b/README.txt new file mode 100755 index 0000000..fc16c2a --- /dev/null +++ b/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/init.lua b/init.lua new file mode 100755 index 0000000..f1e4f91 --- /dev/null +++ b/init.lua @@ -0,0 +1,179 @@ +-- spawn/init.lua + +-- Disable by mapgen, setting or if 'static_spawnpoint' is set +-------------------------------------------------------------- + +spawn = {} + +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"), +--} + +-- I know comparing names can be slow but we should ensure extensibility +local biome_names = { + -- Default + "taiga","coniferous_forest","deciduous_forest","grassland","savanna", + -- Ethereal + "clearing","bamboo","sakura","mesa","frost","grassy","grassytwo", + "grayness","prairie","jumble","grove", + -- Australia + "arnhem_land","eastern_coasts","flinders_lofty","great_dividing_range", + "golf_of_carpentaria","jarrah_karri_forests","mulga_lands", + "murray_darling_basin","tasmania","victorian_forests" +} + +function spawn.register_habitable_biome(name) + table.insert(biome_names, name) +end + +-- 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 = {} + + +-- Get world 'mapgen_limit' and 'chunksize' to calculate 'spawn_limit'. +-- This accounts for how mapchunks are not generated if they or their shell exceed +-- 'mapgen_limit'. + +local mapgen_limit = tonumber(minetest.get_mapgen_setting("mapgen_limit")) +local chunksize = tonumber(minetest.get_mapgen_setting("chunksize")) +local spawn_limit = math.max(mapgen_limit - (chunksize + 1) * 16, 0) + + +--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_names do + local biome_id = minetest.get_biome_id(biome_names[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() + -- Check for position being outside world edge + if math.abs(pos.x) > spawn_limit or math.abs(pos.z) > spawn_limit then + return false + end + end + + return false +end + + +-- On new player spawn and player respawn + +-- Search for spawn position once per server session. If successful, store +-- position and reposition players, otherwise leave them at engine spawn +-- position. + +local function on_spawn(player) + if not searched then + --if true then + success = search() + searched = true + end + if success then + player:set_pos(spawn_pos) + end + return success +end + +minetest.register_on_newplayer(function(player) + on_spawn(player) +end) + +local enable_bed_respawn = minetest.settings:get_bool("enable_bed_respawn") +if enable_bed_respawn == nil then + enable_bed_respawn = true +end + +minetest.register_on_respawnplayer(function(player) + -- Avoid respawn conflict with beds mod + if beds and enable_bed_respawn and + beds.spawn[player:get_player_name()] then + return + end + + return on_spawn(player) +end) diff --git a/license.txt b/license.txt new file mode 100755 index 0000000..f923bdd --- /dev/null +++ b/license.txt @@ -0,0 +1,26 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2018 paramat + +Modified by cathaya7d4 + +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/mod.conf b/mod.conf new file mode 100755 index 0000000..ec3d564 --- /dev/null +++ b/mod.conf @@ -0,0 +1,4 @@ +name = spawn +description = Minetest Game mod: spawn +depends = default +optional_depends = beds