1
0
mirror of https://github.com/mt-mods/biome_lib.git synced 2025-06-29 23:00:57 +02:00

11 Commits

7 changed files with 139 additions and 41 deletions

40
API.txt
View File

@ -588,3 +588,43 @@ And this particular one is mapped slightly differently from the others:
(Note the +150 and +50 offsets) (Note the +150 and +50 offsets)
==================
Default game nodes
==================
Although this project was intended to be used with minetest_game, it can be
configured to work with something else instead. All you need to do is provide
the names of the nodes in your game you want biome_lib's internals to use.
Put these settings in your game's minetest.conf (or your client's own config,
if desired). You'll need to set all of them.
biome_lib_default_grow_through_nodes
Comma-separated list of things that a spawned node is allowed to grow
through. Air is always added to whatever you specify.
Default: air, default:snow
biome_lib_default_water_nodes
Comma-separated list of nodes that should be treated as water for the sake
of looking for neighboring "wet" ground.
Default: default:water_source, default:water_flowing,
default:river_water_source, default:river_water_flowing
biome_lib_default_wet_surfaces
Comma-separated list of nodes that should be considered "wet" if one of
the aforementioned water nodes is nearby.
Default: default:dirt, default:dirt_with_grass, default:sand
biome_lib_default_grow_nodes
Comma-separated list of nodes that something must be sitting on to be
able to actively change from one thing to another (such as a sapling
growing into a tree), to be used for ALL growable nodes, if the calling
mod doesn't provide its own lists.
Default: "default:dirt_with_grass"
biome_lib_default_ground_nodes
Comma-separated list of nodes to use as the "root" of something that can
gradually climb up a wall, to be used for ALL such nodes, if the calling
mod doesn't provide its own lists.
Default: "default:dirt_with_grass"

View File

@ -12,7 +12,7 @@ Both mapgen-based spawning and ABM-based spawning is supported. Growing code is
It is primarily intended for mapgen v6, but it should work fine when used with mapgen v7. It is primarily intended for mapgen v6, but it should work fine when used with mapgen v7.
**Dependencies**: default from minetest_game **Dependencies:** nothing, but if you don't use `minetest_game`, you'll need to supply some settings (see API.txt).
**Recommends**: [Plantlife Modpack](https://github.com/minetest-mods/plantlife_modpack), **Recommends**: [Plantlife Modpack](https://github.com/minetest-mods/plantlife_modpack),
[More Trees](https://github.com/minetest-mods/moretrees) [More Trees](https://github.com/minetest-mods/moretrees)

View File

@ -1,3 +0,0 @@
default
intllib?

View File

@ -20,8 +20,8 @@ function biome_lib:grow_plants(opts)
local options = opts local options = opts
options.height_limit = options.height_limit or 5 options.height_limit = options.height_limit or 5
options.ground_nodes = options.ground_nodes or { "default:dirt_with_grass" } options.ground_nodes = options.ground_nodes or biome_lib.default_ground_nodes
options.grow_nodes = options.grow_nodes or { "default:dirt_with_grass" } options.grow_nodes = options.grow_nodes or biome_lib.default_grow_nodes
options.seed_diff = options.seed_diff or 0 options.seed_diff = options.seed_diff or 0
local n local n
@ -55,7 +55,7 @@ function biome_lib:grow_plants(opts)
if options.need_wall and options.verticals_list then if options.need_wall and options.verticals_list then
walldir = biome_lib:find_adjacent_wall(p_top, options.verticals_list, options.choose_random_wall) walldir = biome_lib:find_adjacent_wall(p_top, options.verticals_list, options.choose_random_wall)
end end
if (n_top.name == "air" or n_top.name == "default:snow") if biome_lib.default_grow_through_nodes[n_top.name]
and (not options.need_wall or (options.need_wall and walldir)) then and (not options.need_wall or (options.need_wall and walldir)) then
if options.grow_vertically and walldir then if options.grow_vertically and walldir then
if biome_lib:search_downward(pos, options.height_limit, options.ground_nodes) then if biome_lib:search_downward(pos, options.height_limit, options.ground_nodes) then

108
init.lua
View File

@ -1,4 +1,4 @@
-- Biome library mod by Vanessa Ezekowitz -- Biome library mod by VanessaE
-- --
-- I got the temperature map idea from "hmmmm", values used for it came from -- I got the temperature map idea from "hmmmm", values used for it came from
-- Splizard's snow mod. -- Splizard's snow mod.
@ -32,6 +32,41 @@ biome_lib.total_no_aircheck_calls = 0
biome_lib.queue_run_ratio = tonumber(minetest.settings:get("biome_lib_queue_run_ratio")) or 100 biome_lib.queue_run_ratio = tonumber(minetest.settings:get("biome_lib_queue_run_ratio")) or 100
local function tableize(s)
return string.split(string.trim(string.gsub(s, " ", "")))
end
local c1 minetest.settings:get("biome_lib_default_grow_through_nodes")
biome_lib.default_grow_through_nodes = {["air"] = true}
if c1 then
for _, i in ipairs(tableize(c1)) do
biome_lib.default_grow_through_nodes[i] = true
end
else
biome_lib.default_grow_through_nodes["default:snow"] = true
end
local c2 minetest.settings:get("biome_lib_default_water_nodes")
biome_lib.default_water_nodes = {}
if c2 then
for _, i in ipairs(tableize(c2)) do
biome_lib.default_water_nodes[i] = true
end
else
biome_lib.default_water_nodes["default:water_source"] = true
biome_lib.default_water_nodes["default:water_flowing"] = true
biome_lib.default_water_nodes["default:river_water_source"] = true
biome_lib.default_water_nodes["default:river_water_flowing"] = true
end
local c3 = minetest.settings:get("biome_lib_default_wet_surfaces")
local c4 = minetest.settings:get("biome_lib_default_ground_nodes")
local c5 = minetest.settings:get("biome_lib_default_grow_nodes")
biome_lib.default_wet_surfaces = c3 and tableize(c3) or {"default:dirt", "default:dirt_with_grass", "default:sand"}
biome_lib.default_ground_nodes = c4 and tableize(c4) or {"default:dirt_with_grass"}
biome_lib.default_grow_nodes = c5 and tableize(c5) or {"default:dirt_with_grass"}
-- Boilerplate to support localized strings if intllib mod is installed. -- Boilerplate to support localized strings if intllib mod is installed.
local S local S
if minetest.global_exists("intllib") then if minetest.global_exists("intllib") then
@ -45,12 +80,12 @@ else
end end
biome_lib.intllib = S biome_lib.intllib = S
local DEBUG = false --... except if you want to spam the console with debugging info :-) local DEBUG = minetest.settings:get_bool("biome_lib_debug", false)
function biome_lib:dbg(msg) function biome_lib:dbg(msg)
if DEBUG then if DEBUG then
print("[Plantlife] "..msg) print("[Biome Lib] "..msg)
minetest.log("verbose", "[Plantlife] "..msg) minetest.log("verbose", "[Biome Lib] "..msg)
end end
end end
@ -395,7 +430,7 @@ end
-- a surface during the initial map read stage. -- a surface during the initial map read stage.
function biome_lib:generate_block_with_air_checking() function biome_lib:generate_block_with_air_checking()
if #biome_lib.blocklist_aircheck == 0 then if not biome_lib.blocklist_aircheck[1] then
return return
end end
@ -407,13 +442,13 @@ function biome_lib:generate_block_with_air_checking()
local blockhash = minetest.hash_node_position(minp) local blockhash = minetest.hash_node_position(minp)
if not biome_lib.surface_nodes_aircheck.blockhash then if not biome_lib.surface_nodes_aircheck.blockhash then -- read it into the block cache
biome_lib.surface_nodes_aircheck.blockhash = biome_lib.surface_nodes_aircheck.blockhash =
minetest.find_nodes_in_area_under_air(minp, maxp, biome_lib.surfaceslist_aircheck) minetest.find_nodes_in_area_under_air(minp, maxp, biome_lib.surfaceslist_aircheck)
biome_lib.actioncount_aircheck.blockhash = 1 biome_lib.actioncount_aircheck.blockhash = 1
else else
if biome_lib.actioncount_aircheck.blockhash <= #biome_lib.actionslist_aircheck then if biome_lib.actionslist_aircheck[biome_lib.actioncount_aircheck.blockhash] then
-- [1] is biome, [2] is node/function/model -- [1] is biome, [2] is node/function/model
biome_lib:populate_surfaces( biome_lib:populate_surfaces(
biome_lib.actionslist_aircheck[biome_lib.actioncount_aircheck.blockhash][1], biome_lib.actionslist_aircheck[biome_lib.actioncount_aircheck.blockhash][1],
@ -421,10 +456,9 @@ function biome_lib:generate_block_with_air_checking()
biome_lib.surface_nodes_aircheck.blockhash, true) biome_lib.surface_nodes_aircheck.blockhash, true)
biome_lib.actioncount_aircheck.blockhash = biome_lib.actioncount_aircheck.blockhash + 1 biome_lib.actioncount_aircheck.blockhash = biome_lib.actioncount_aircheck.blockhash + 1
else else
if biome_lib.surface_nodes_aircheck.blockhash then table.remove(biome_lib.blocklist_aircheck, 1)
table.remove(biome_lib.blocklist_aircheck, 1) biome_lib.surface_nodes_aircheck.blockhash = nil
biome_lib.surface_nodes_aircheck.blockhash = nil biome_lib.actioncount_aircheck.blockhash = nil
end
end end
end end
end end
@ -433,7 +467,7 @@ end
-- checking for air during the initial map read stage. -- checking for air during the initial map read stage.
function biome_lib:generate_block_no_aircheck() function biome_lib:generate_block_no_aircheck()
if #biome_lib.blocklist_no_aircheck == 0 then if not biome_lib.blocklist_no_aircheck[1] then
return return
end end
@ -443,25 +477,21 @@ function biome_lib:generate_block_no_aircheck()
local blockhash = minetest.hash_node_position(minp) local blockhash = minetest.hash_node_position(minp)
if not biome_lib.surface_nodes_no_aircheck.blockhash then if not biome_lib.surface_nodes_no_aircheck.blockhash then
-- directly read the block to be searched into the chunk cache
biome_lib.surface_nodes_no_aircheck.blockhash = biome_lib.surface_nodes_no_aircheck.blockhash =
minetest.find_nodes_in_area(minp, maxp, biome_lib.surfaceslist_no_aircheck) minetest.find_nodes_in_area(minp, maxp, biome_lib.surfaceslist_no_aircheck)
biome_lib.actioncount_no_aircheck.blockhash = 1 biome_lib.actioncount_no_aircheck.blockhash = 1
else else
if biome_lib.actioncount_no_aircheck.blockhash <= #biome_lib.actionslist_no_aircheck then if biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash] then
biome_lib:populate_surfaces( biome_lib:populate_surfaces(
biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash][1], biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash][1],
biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash][2], biome_lib.actionslist_no_aircheck[biome_lib.actioncount_no_aircheck.blockhash][2],
biome_lib.surface_nodes_no_aircheck.blockhash, false) biome_lib.surface_nodes_no_aircheck.blockhash, false)
biome_lib.actioncount_no_aircheck.blockhash = biome_lib.actioncount_no_aircheck.blockhash + 1 biome_lib.actioncount_no_aircheck.blockhash = biome_lib.actioncount_no_aircheck.blockhash + 1
else else
if biome_lib.surface_nodes_no_aircheck.blockhash then table.remove(biome_lib.blocklist_no_aircheck, 1)
table.remove(biome_lib.blocklist_no_aircheck, 1) biome_lib.surface_nodes_no_aircheck.blockhash = nil
biome_lib.surface_nodes_no_aircheck.blockhash = nil biome_lib.actioncount_no_aircheck.blockhash = nil
end
end end
end end
end end
@ -622,11 +652,11 @@ function biome_lib:spawn_on_surfaces(sd,sp,sr,sc,ss,sa)
local currentsurface = minetest.get_node(pos).name local currentsurface = minetest.get_node(pos).name
if currentsurface == "default:water_source" and if biome_lib.default_water_nodes[currentsurface] and
#minetest.find_nodes_in_area( #minetest.find_nodes_in_area(
{x=pos.x, y=pos.y-biome.depth_max-1, z=pos.z}, {x=pos.x, y=pos.y-biome.depth_max-1, z=pos.z},
vector.new(pos), vector.new(pos),
{"default:dirt", "default:dirt_with_grass", "default:sand"} biome_lib.default_wet_surfaces
) == 0 then ) == 0 then
return -- On water but no ground nearby return -- On water but no ground nearby
end end
@ -687,12 +717,9 @@ function biome_lib:replace_object(pos, replacement, grow_function, walldir, seed
end end
end end
dofile(biome_lib.modpath .. "/search_functions.lua") dofile(biome_lib.modpath .. "/search_functions.lua")
assert(loadfile(biome_lib.modpath .. "/growth.lua"))(time_scale) assert(loadfile(biome_lib.modpath .. "/growth.lua"))(time_scale)
-- Check for infinite stacks -- Check for infinite stacks
if minetest.get_modpath("unified_inventory") or not minetest.settings:get_bool("creative_mode") then if minetest.get_modpath("unified_inventory") or not minetest.settings:get_bool("creative_mode") then
@ -710,10 +737,29 @@ function biome_lib:get_nodedef_field(nodename, fieldname)
return minetest.registered_nodes[nodename][fieldname] return minetest.registered_nodes[nodename][fieldname]
end end
if DEBUG then
biome_lib.last_count_air = 0
biome_lib.last_count_no_air = 0
function biome_lib.show_pending_block_counts()
if biome_lib.last_count_air ~= #biome_lib.blocklist_aircheck
or biome_lib.last_count_no_air ~= #biome_lib.blocklist_no_aircheck then
biome_lib:dbg(string.format("Pending block counts, air: %-7i no-air: %i",
#biome_lib.blocklist_aircheck, #biome_lib.blocklist_no_aircheck))
biome_lib.last_count_air = #biome_lib.blocklist_aircheck
biome_lib.last_count_no_air = #biome_lib.blocklist_no_aircheck
end
minetest.after(1, biome_lib.show_pending_block_counts)
end
biome_lib.show_pending_block_counts()
minetest.after(0, function()
print("Registered a total of "..(#biome_lib.surfaceslist_aircheck)+(#biome_lib.surfaceslist_no_aircheck).." surface types to be evaluated, spread")
print("across "..#biome_lib.actionslist_aircheck.." actions with air-checking and "..#biome_lib.actionslist_no_aircheck.." actions without.")
end)
end
print("[Biome Lib] Loaded") print("[Biome Lib] Loaded")
minetest.after(0, function()
print("[Biome Lib] Registered a total of "..(#biome_lib.surfaceslist_aircheck)+(#biome_lib.surfaceslist_no_aircheck).." surface types to be evaluated, spread")
print("[Biome Lib] across "..#biome_lib.actionslist_aircheck.." actions with air-checking and "..#biome_lib.actionslist_no_aircheck.." actions without.")
end)

View File

@ -1,2 +1,3 @@
name = biome_lib name = biome_lib
min_minetest_version = 5.2.0 min_minetest_version = 5.2.0
optional_depends = default, intllib

View File

@ -52,9 +52,23 @@ function biome_lib:find_open_side(pos)
return nil return nil
end end
-- "Record" the chunks being generated by the core mapgen -- "Record" the map chunks being generated by the core mapgen,
-- split into individual mapblocks to reduce lag
minetest.register_on_generated(function(minp, maxp, blockseed) minetest.register_on_generated(function(minp, maxp, blockseed)
biome_lib.blocklist_aircheck[#biome_lib.blocklist_aircheck + 1] = { minp, maxp } for x = 0, 4 do
biome_lib.blocklist_no_aircheck[#biome_lib.blocklist_no_aircheck + 1] = { minp, maxp } local minx = minp.x + x*16
for y = 0, 4 do
local miny = minp.y + y*16
for z = 0, 4 do
local minz = minp.z + z*16
local bmin = {x=minx, y=miny, z=minz}
local bmax = {x=minx + 15, y=miny + 15, z=minz + 15}
biome_lib.blocklist_aircheck[#biome_lib.blocklist_aircheck + 1] = { bmin, bmax }
biome_lib.blocklist_no_aircheck[#biome_lib.blocklist_no_aircheck + 1] = { bmin, bmax }
end
end
end
end) end)