register_on_generate: tries and rarity_fertility (#8)

* Can specify the number of tries when generating
* Added rarity_fertility which means rarity can be affected by fertility level.
Rarity can now be a fraction.
A rarity of 100 (with rarity_fertility of 0) means the object will never appear, and a rarity of 0 means it will always appear.
This commit is contained in:
Jordan Leppert 2021-12-24 08:30:36 +00:00 committed by GitHub
parent bd92dc1b0b
commit 932485a6fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 15 deletions

33
API.txt
View File

@ -26,7 +26,7 @@ biome_lib.register_active_spawner(sdelay, splant, sradius, schance, ssurface, sa
This first function is an ABM-based spawner function originally created as
part of Ironzorg's flowers mod. It has since been largely extended and
expanded. There are two ways to call this function: You can either pass it
expanded. There are two ways to call this function: You can either pass it
several individual string and number parameters to use the legacy interface,
or you can pass a single biome definition as a table, with all of your options
spelled out nicely. This is the preferred method.
@ -135,7 +135,7 @@ biome = {
-- radius. Defaults to 1 but is ignored if near_nodes
-- isn't set. Bear in mind that the total area to be
-- checked is equal to:
-- (near_nodes_size^2)*near_nodes_vertical*2
-- (near_nodes_size^2)*near_nodes_vertical*2
-- For example, if size is 10 and vertical is 4, then
-- the area is (10^2)*8 = 800 nodes in size, so you'll
-- want to make sure you specify a value appropriate
@ -202,7 +202,7 @@ biome = {
}
[*] spawn_plants must be either a table or a string. If it's a table, the
values therein are treated as a list of nodenames to pick from randomly on
values therein are treated as a list of nodenames to pick from randomly on
each application of the ABM code. The more nodes you can pack into this
parameter to avoid making too many calls to this function, the lower the CPU
load will likely be.
@ -225,7 +225,7 @@ call this function with two parameters: a table with your object's biome
information, and a string, function, or table describing what to do if the
engine finds a suitable surface node (see below).
The biome table contains quite a number of options, though there are fewer
The biome table contains quite a number of options, though there are fewer
here than are available in the ABM-based spawner, as some stuff doesn't make
sense at map-generation time.
@ -250,12 +250,21 @@ biome = {
-- skipped. Avoid using excessively large radii.
rarity = num, -- How rare should this object be in its biome? Larger
-- values make objects more rare, via:
-- math.random(1,100) > this
-- math.random() * 100 > this
rarity_fertility -- The amount that the rarity is reduced by fertility.
= num, -- This makes the rarity field the upper bound for
-- rarity, and (rarity - rarity_fertility) the lower
-- bound. Defaults to 0.
max_count = num, -- The absolute maximum number of your object that
-- should be allowed to spawn in a 5x5x5 mapblock area
-- (80x80x80 nodes). Defaults to 5, but be sure you
-- set this to some reasonable value depending on your
-- object and its size if 5 is insufficient.
tries = num, -- the number of attempts that will be made to spawn
-- an object, defaults to 2. This means if the first
-- attempt fails due to something blocking the object
-- for example, another attempt will be made in
-- another random location.
seed_diff = num, -- Perlin seed-diff value. Defaults to 0, which
-- causes the function to inherit the global value of
-- 329.
@ -341,7 +350,7 @@ definition table as the only parameter. These are defined like so:
options = {
label = string, -- set this to identify the ABM for Minetest's
-- profiler. If not set, biome_lib will set it to
-- profiler. If not set, biome_lib will set it to
-- "biome_lib.update_plant(): " appended with the node
-- in grow_plant (or the first item if it's a table)
grow_plant = "string" or {table}, -- Name(s) of the node(s) to be grown
@ -406,7 +415,7 @@ If this value is set to a simple string, this is treated as the name of the
function to use to grow the plant. In this case, all of the usual growing
code is executeed, but then instead of a plant being simply added to the
world, grow_result is ignored and the named function is executed and passed a
few parmeters in the following general form:
few parmeters in the following general form:
somefunction(pos, perlin1, perlin2)
@ -431,7 +440,7 @@ search around the given position for a neighboring wall, returning the first
one it finds as a facedir value, or nil if there are no adjacent walls.
If randomflag is set to true, the function will just return the facedir of any
random wall it finds adjacent to the target position. Defaults to false if
random wall it finds adjacent to the target position. Defaults to false if
not specified.
=====
@ -463,7 +472,7 @@ spammy stuff.
biome_lib.generate_ltree(pos, treemodel)
biome_lib.grow_ltree(pos, treemodel)
In the case of the growing code and the mapgen-based tree generator code,
In the case of the growing code and the mapgen-based tree generator code,
generating a tree is done via the above two calls, which in turn immediately
call the usual spawn_tree() functions. This rerouting exists as a way for
other mods to hook into biome_lib's tree-growing functions in general,
@ -475,7 +484,7 @@ is to be placed. 'treemodel' is the standard L-Systems tree definition table
expected by the spawn_tree() function. Refer to the 'trunk' field in that
table to derive the name of the tree being spawned.
biome_lib.grow_ltree(pos, treemodel) does the same sort of thing whenever a
biome_lib.grow_ltree(pos, treemodel) does the same sort of thing whenever a
tree is spawned within the abm-based growing code, for example when growing a
sapling into a tree.
@ -518,7 +527,7 @@ appears to be the standard now. Those values are:
temperature_persistence = 0.5
temperature_scale = 150
The way Perlin values are used by this mod, in keeping with the snow mod's
The way Perlin values are used by this mod, in keeping with the snow mod's
apparent methods, larger values returned by the Perlin function represent
*colder* temperatures. In this mod, the following table gives a rough
approximation of how temperature maps to these values, normalized to
@ -542,7 +551,7 @@ Perlin Approx. Temperature
Included in this table are even 0.25 steps in Perlin values along with some
common temperatures on both the Centigrade and Fahrenheit scales. Note that
unless you're trying to model the Moon or perhaps Mercury in your mods/maps,
unless you're trying to model the Moon or perhaps Mercury in your mods/maps,
you probably won't need to bother with Perlin values of less than -0.56 or so.

12
api.lua
View File

@ -73,7 +73,9 @@ function biome_lib.set_defaults(biome)
biome.near_nodes_size = biome.near_nodes_size or 0
biome.near_nodes_count = biome.near_nodes_count or 1
biome.rarity = biome.rarity or 50
biome.rarity_fertility = biome.rarity_fertility or 0
biome.max_count = biome.max_count or 125
biome.tries = biome.tries or 2
if biome.check_air ~= false then biome.check_air = true end
-- specific to abm spawner
@ -182,14 +184,18 @@ end
local function populate_single_surface(biome, pos, perlin_fertile_area, checkair)
local p_top = { x = pos.x, y = pos.y + 1, z = pos.z }
if math.random(1, 100) <= biome.rarity then
if biome.rarity - biome.rarity_fertility == 100 then
return
end
local fertility, temperature, humidity = get_biome_data(pos, perlin_fertile_area)
if math.random() * 100 <= (biome.rarity - ((fertility + 1) / 2 * biome.rarity_fertility)) then
return
end
local pos_biome_ok = pos.y >= biome.min_elevation and pos.y <= biome.max_elevation
and fertility > biome.plantlife_limit
and fertility >= biome.plantlife_limit
and temperature <= biome.temp_min and temperature >= biome.temp_max
and humidity <= biome.humidity_min and humidity >= biome.humidity_max
@ -286,7 +292,7 @@ function biome_lib.populate_surfaces(b, nodes_or_function_or_model, snodes, chec
for i = 1, math.min(math.ceil(biome.max_count/25), num_in_biome_nodes) do
local tries = 0
local spawned = false
while tries < 2 and not spawned do
while tries < biome.tries and not spawned do
local pos = in_biome_nodes[math.random(1, num_in_biome_nodes)]
local will_place = true