write something there

This commit is contained in:
N-Nachtigal 2025-05-04 16:01:41 +02:00
commit b4b6c08f4f
8546 changed files with 309825 additions and 0 deletions

1
mods/findbiome/.mailmap Normal file
View file

@ -0,0 +1 @@
Wuzzy <Wuzzy@disroot.org> <Wuzzy2@mail.ru>

64
mods/findbiome/API.md Normal file
View file

@ -0,0 +1,64 @@
# Find Biome API
This mod has two public functions:
## `findbiome.find_biome(pos, biomes, res, checks)`
Attempts to find a position of any biome listed in `biomes`, starting the search from `pos`.
The algorithm will start check positions around `pos`, starting at `pos` and extend its
search outwards. As soon as any of the listed biomes is found, the algorithm terminates
and the biome position is returned.
### Parameters
* `pos`: Position at where to start the search
* `biomes`: List of the technical names of the biomes to search for
* `res`: (optional): Size of search grid resolution (smaller = more precise, but also smaller area) (default: 64)
* `checks`: (optional): Number of points checked in total (default: 16384)
### Return value
Returns `<biome position>, <success>`.
* `<biome position>` is the position of a found biome or `nil` if none was found
* `<success>` is `true` on success and `false` on failure.
### Additional notes
* This function checks nodes on a square spiral going outwards from `pos`
* Although unlikely, there is *no 100% guarantee* that the biome will always be found if
it exists in the world. Very small and/or rare biomes tend to get “overlooked”.
* The search might include different Y levels than provided in `pos.y` in order
to find biomes that are restricted by Y coordinates
* If the mapgen `v6` is used, this function only works if the mod `biomeinfo` is
active, too. See the `biomeinfo` mod for more information
* Be careful not to check too many points, as this can lead to potentially longer
searches which may freeze the server for a while
## `findbiome.list_biomes()`
Lists all registered biomes in the world.
### Parameters
None.
### Return value
Returns `<success>, <biomes>`.
* `<success>` is `true` on success and `false` on failure.
* `<biomes>` is a table.
* If there are no errors, it will be a list of all registered biomes, in alphabetical order.
* If there is an error, it will be a table with the first element being an error message.
* Possible errors:
* `v6` mapgen is used and `biomeinfo` mod is not enabled.
* Not all mods have loaded into the world yet.
### Additional notes
* If no biomes have been registered, `<biomes>` will be an empty table, but it still counts as success if there was no error.
* If the mapgen `v6` is used, this function only works if the mod `biomeinfo` is
active, too. See the `biomeinfo` mod for more information.
* The error messages are always sent in English so the API user can check for them. It is possible to then use a translator on the returned value before showing it to the player, if that is what is wanted. See how errors are handled by the chat command.
* It is better to just check the success value, unless the error message may interfere with other functions.

30
mods/findbiome/README.md Normal file
View file

@ -0,0 +1,30 @@
# Minetest mod: findbiome
## Description
This is a mod to help with mod/game development for Minetest.
It adds a command (“findbiome”) to find a biome nearby and teleport you to it,
and another command (“listbiomes”) to list all biomes.
Version: 1.2.0
## Known limitations
There's no guarantee you will always find the biome, even if it exists in the world.
This can happen if the biome is very obscure or small, but usually you should be
able to find the biome.
If the biome could not be found, just move to somewhere else and try again.
## Modding info
For modders, this mod offers two functions to search or list biomes via code, similar to the chat commands.
See `API.md` for details.
## Authors
- paramat (MIT License)
- Wuzzy (MIT License)
- Skivling (MIT License, `list_biomes()` function)
- rstcxk (MIT License, Polish translation, general cleanups)
This mod is free software. See `license.txt` for license information.
This mod is based on the algorithm of the "spawn" mod from Minetest Game 5.0.0.

357
mods/findbiome/init.lua Normal file
View file

@ -0,0 +1,357 @@
local S = minetest.get_translator("findbiome")
local NS = function(s) return s end
findbiome = {}
local mod_biomeinfo = minetest.get_modpath("biomeinfo") ~= nil
local mg_name = minetest.get_mapgen_setting("mg_name")
local water_level = tonumber(minetest.get_mapgen_setting("water_level"))
-- Calculate the playable area of the world
local playable_limit_min, playable_limit_max
if minetest.get_mapgen_edges then
-- Modern method by just asking Minetest
playable_limit_min, playable_limit_max = minetest.get_mapgen_edges()
else
-- Legacy method for older Minetest versions
-- by calculating an estimate ourself
-- (it's not perfect but close enough)
local BLOCKSIZE = 16
local mapgen_limit = tonumber(minetest.get_mapgen_setting("mapgen_limit"))
local chunksize = tonumber(minetest.get_mapgen_setting("chunksize"))
local limit_estimate = math.max(mapgen_limit - (chunksize + 1) * BLOCKSIZE, 0)
playable_limit_min = vector.new(-limit_estimate, -limit_estimate, -limit_estimate)
playable_limit_max = vector.new(limit_estimate, limit_estimate, limit_estimate)
end
-- Default parameters
---------------------
-- Resolution of search grid in nodes.
local DEFAULT_SEARCH_GRID_RESOLUTION = 64
-- Number of points checked in the square search grid (edge * edge).
local DEFAULT_CHECKED_POINTS = 128 * 128
-- 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},
}
-- Returns true if pos is within the world boundaries
local function is_in_world(pos)
return not (pos.x < playable_limit_min.x or pos.y < playable_limit_min.y or pos.z < playable_limit_min.z or
pos.x > playable_limit_max.x or pos.y > playable_limit_max.y or pos.z > playable_limit_max.z)
end
-- Checks if pos is within the biome's boundaries. If it isn't, places pos inside the boundaries.
local function adjust_pos_to_biome_limits(pos, biome_id)
local bpos = table.copy(pos)
local biome_name = minetest.get_biome_name(biome_id)
local biome = minetest.registered_biomes[biome_name]
if not biome then
minetest.log("error", "[findbiome] adjust_pos_to_biome_limits non-existing biome!")
return bpos, true
end
local axes = {"y", "x", "z"}
local out_of_bounds = false
for a=1, #axes do
local ax = axes[a]
local min, max
if biome[ax.."_min"] then
min = biome[ax.."_min"]
else
min = playable_limit_min[ax]
end
if biome[ax.."_max"] then
max = biome[ax.."_max"]
else
max = playable_limit_max[ax]
end
min = tonumber(min)
max = tonumber(max)
if bpos[ax] < min then
out_of_bounds = true
bpos[ax] = min
if max-min > 16 then
bpos[ax] = math.max(bpos[ax] + 8, playable_limit_min[ax])
end
end
if bpos[ax] > max then
out_of_bounds = true
bpos[ax] = max
if max-min > 16 then
bpos[ax] = math.min(bpos[ax] - 8, playable_limit_max[ax])
end
end
end
return bpos, out_of_bounds
end
-- Find the special default biome
local function find_default_biome()
local all_biomes = minetest.registered_biomes
local biome_count = 0
for _, _ in pairs(all_biomes) do
biome_count = biome_count + 1
end
-- Trivial case: No biomes registered, default biome is everywhere.
if biome_count == 0 then
local y = minetest.get_spawn_level(0, 0)
if not y then
y = 0
end
return vector.new(0, y, 0)
end
local pos = vector.new()
-- Just check a lot of random positions
-- It's a crappy algorithm but better than nothing.
for _=1, 100 do
pos.x = math.random(playable_limit_min.x, playable_limit_max.x)
pos.y = math.random(playable_limit_min.y, playable_limit_max.y)
pos.z = math.random(playable_limit_min.z, playable_limit_max.z)
local biome_data = minetest.get_biome_data(pos)
if biome_data and minetest.get_biome_name(biome_data.biome) == "default" then
return pos
end
end
return nil
end
function findbiome.find_biome(pos, biomes, res, checks)
if not res then
res = DEFAULT_SEARCH_GRID_RESOLUTION
end
if not checks then
checks = DEFAULT_CHECKED_POINTS
end
pos = vector.round(pos)
-- Pos: 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.
-- Initial variables
local edge_len = 1
local edge_dist = 0
local dir_step = 0
local dir_ind = 1
local success
local spawn_pos
local biome_ids
-- 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
-- Position search
local function search()
local attempt = 1
while attempt < 3 do
for _ = 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]
pos = adjust_pos_to_biome_limits(pos, biome_id)
local spos = table.copy(pos)
if biome == biome_id then
local good_spawn_height = pos.y <= water_level + 16 and pos.y >= water_level
local spawn_y = minetest.get_spawn_level(spos.x, spos.z)
if spawn_y then
spawn_pos = vector.new(spos.x, spawn_y, spos.z)
elseif not good_spawn_height then
spawn_pos = vector.new(spos.x, spos.y, spos.z)
elseif attempt >= 2 then
spawn_pos = vector.new(spos.x, spos.y, spos.z)
end
if spawn_pos then
local _, outside = adjust_pos_to_biome_limits(spawn_pos, biome_id)
if is_in_world(spawn_pos) and not outside then
return true
end
end
end
end
pos = next_pos()
end
attempt = attempt + 1
end
return false
end
local function search_v6()
if not mod_biomeinfo then return
false
end
for _ = 1, checks do
local found_biome = biomeinfo.get_v6_biome(pos)
for i = 1, #biomes do
local searched_biome = biomes[i]
if found_biome == searched_biome then
local spawn_y = minetest.get_spawn_level(pos.x, pos.z)
if spawn_y then
spawn_pos = vector.new(pos.x, spawn_y, pos.z)
if is_in_world(spawn_pos) then
return true
end
end
end
end
pos = next_pos()
end
return false
end
if mg_name == "v6" then
success = search_v6()
else
-- Table of suitable biomes
biome_ids = {}
for i=1, #biomes do
local id = minetest.get_biome_id(biomes[i])
if not id then
return nil, false
end
table.insert(biome_ids, id)
end
success = search()
end
return spawn_pos, success
end
local mods_loaded = false
minetest.register_on_mods_loaded(function()
mods_loaded = true
end)
function findbiome.list_biomes()
local biomes = {}
local b = 0
if not mods_loaded then
table.insert(biomes, NS("Wait until all mods have loaded!"))
return false, biomes
end
if mg_name == "v6" then
if not mod_biomeinfo then
table.insert(biomes, NS("Not supported. The “biomeinfo” mod is required for v6 mapgen support!"))
return false, biomes
end
biomes = biomeinfo.get_active_v6_biomes()
b = #biomes
else
biomes = {}
for k, _ in pairs(minetest.registered_biomes) do
table.insert(biomes, k)
b = b + 1
end
end
if b == 0 then
return true, biomes
else
table.sort(biomes)
return true, biomes
end
end
-- Register chat commands
do
minetest.register_chatcommand("findbiome", {
description = S("Find and teleport to biome"),
params = S("<biome>"),
privs = { debug = true, teleport = true },
func = function(name, param)
if not mods_loaded then
return false
end
local player = minetest.get_player_by_name(name)
if not player then
return false, S("No player.")
end
local pos = player:get_pos()
local invalid_biome = true
if mg_name == "v6" then
if not mod_biomeinfo then
return false, S("Not supported. The “biomeinfo” mod is required for v6 mapgen support!")
end
local biomes = biomeinfo.get_active_v6_biomes()
for b=1, #biomes do
if param == biomes[b] then
invalid_biome = false
break
end
end
else
if param == "default" then
local biome_pos = find_default_biome()
if biome_pos then
player:set_pos(biome_pos)
return true, S("Biome found at @1.", minetest.pos_to_string(biome_pos))
else
return false, S("No biome found!")
end
end
local id = minetest.get_biome_id(param)
if id then
invalid_biome = false
end
end
if invalid_biome then
return false, S("Biome does not exist!")
end
local biome_pos, success = findbiome.find_biome(pos, {param})
if success then
player:set_pos(biome_pos)
return true, S("Biome found at @1.", minetest.pos_to_string(biome_pos))
else
return false, S("No biome found!")
end
end,
})
minetest.register_chatcommand("listbiomes", {
description = S("List all biomes"),
params = "",
privs = { debug = true },
func = function(name, param)
local success, biomes = findbiome.list_biomes()
-- Error checking before sending them in chat
if success == false then -- send error message
return false, S(biomes[1])
else -- it worked, send all biomes
if #biomes == 0 then
return true, S("No biomes.")
else
table.sort(biomes)
return true, table.concat(biomes, "\n")
end
end
end,
})
end

View file

@ -0,0 +1,24 @@
License of this mod
-------------------
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

View file

@ -0,0 +1,17 @@
# textdomain: findbiome
# mod title
Find Biome=Biom finden
# mod description
Adds commands to list and find biomes=Fügt Befehle zum Auflisten und Finden von Biomen hinzu
# mod strings
Wait until all mods have loaded!=Bitte warten, bis alle Mods geladen wurden!
Find and teleport to biome=Ein Biom finden und hinteleportieren
<biome>=<Biom>
No player.=Kein Spieler
Biome does not exist!=Biom existiert nicht!
Biome found at @1.=Biom gefunden bei @1.
No biome found!=Kein Biom gefunden!
List all biomes=Alle Biome auflisten
No biomes.=Keine Biome.
Not supported. The “biomeinfo” mod is required for v6 mapgen support!=Nicht unterstützt. Die Mod „biomeinfo“ wird für Unterstützung des v6-Kartengenerators benötigt.

View file

@ -0,0 +1,17 @@
# textdomain: findbiome
# mod title
Find Biome=Znajdź biom
# mod description
Adds commands to list and find biomes=Dodaje komendy do znajdowania i wypisywania biomów
# mod strings
Wait until all mods have loaded!=
Find and teleport to biome=Znajduje i teleportuje do biomu
<biome>=<biom>
No player.=Gracz nie istnieje.
Biome does not exist!=Biom nie istnieje!
Biome found at @1.=Znaleziono biom w pozycji @1
No biome found!=Nie znaleziono biomu!
List all biomes=Wypisuje wszystkie biomy
No biomes.=Brak Biomów
Not supported. The “biomeinfo” mod is required for v6 mapgen support!=Błąd! mod "biomeinfo" jest potrzebny dla wsparcia mapgen'u v6

View file

@ -0,0 +1,17 @@
# textdomain: findbiome
# mod title
Find Biome=
# mod description
Adds commands to list and find biomes=
# mod strings
Wait until all mods have loaded!=
Find and teleport to biome=
<biome>=
No player.=
Biome does not exist!=
Biome found at @1.=
No biome found!=
List all biomes=
No biomes.=
Not supported. The “biomeinfo” mod is required for v6 mapgen support!=

4
mods/findbiome/mod.conf Normal file
View file

@ -0,0 +1,4 @@
name=findbiome
title=Find Biome
description=Adds commands to list and find biomes
optional_depends=biomeinfo