diff --git a/API.txt b/API.txt index fd234ed..53ab9ec 100644 --- a/API.txt +++ b/API.txt @@ -1,30 +1,28 @@ This document describes the Plantlife mod API. -Last revision: 2015-02-16 +Last revision: 2021-04-20 ========= Functions ========= -There are three main functions defined by the main "biome_lib" mod: +There are two main functions defined by this mod: -spawn_on_surfaces() -register_generate_plant() -grow_plants() +biome_lib.register_active_spawner() +biome_lib.register_on_generate() There are also several internal, helper functions that can be called if so desired, but they are not really intended for use by other mods and may change at any time. They are briefly described below these main functions, but see init.lua for details. -Most functions in plants lib are declared locally to avoid namespace -collisions with other mods. They are accessible via the "biome_lib" method, -e.g. biome_lib:spawn_on_surfaces() and so forth. +Most functions in biome_lib are either declared locally or kept within its +own namespace to avoid collisions/conflicts with other mods. ===== -spawn_on_surfaces(biome) -spawn_on_surfaces(sdelay, splant, sradius, schance, ssurface, savoid) +biome_lib.register_active_spawner(biome) +biome_lib.register_active_spawner(sdelay, splant, sradius, schance, ssurface, savoid) 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 @@ -220,7 +218,7 @@ checking is disabled. Same holds true for the nneighbors bit above that. ===== -biome_lib:register_generate_plant(biome, nodes_or_function_or_treedef) +biome_lib.register_on_generate(biome, nodes_or_function_or_treedef) To register an object to be spawned at mapgen time rather than via an ABM, call this function with two parameters: a table with your object's biome @@ -336,16 +334,16 @@ will be called in the form: ===== -biome_lib:grow_plants(options) +biome_lib.update_plant(options) -The third function, grow_plants() is used to turn the spawned nodes above -into something else over time. This function has no return value, and accepts -a biome definition table as the only parameter. These are defined like so: +This third function is used to turn the spawned nodes above into something +else over time. This function has no return value, and accepts a biome +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 - -- "biome_lib grow_plants(): " appended with the node + -- "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 -- into something else. This value is passed to the @@ -426,7 +424,7 @@ and grow_result is ignored. ===== -find_adjacent_wall(pos, verticals, randomflag) +biome_lib.find_adjacent_wall(pos, verticals, randomflag) Of the few helper functions, this one expects a position parameter and a table with the list of nodes that should be considered as walls. The code will @@ -438,7 +436,7 @@ random wall it finds adjacent to the target position. Defaults to false if not specified. ===== -is_node_loaded(pos) +biome_lib.is_node_loaded(pos) This acts as a wrapper for the minetest.get_node_or_nil(node_pos) function and accepts a single position parameter. Returns true if the node in @@ -446,7 +444,7 @@ question is already loaded, or false if not. ===== -dbg(string, level) +biome_lib.dbg(string, level) This is a simple debug output function which takes one string parameter. It just checks if DEBUG is true and outputs the phrase "[Plantlife] " followed by @@ -463,8 +461,8 @@ ought always be shown, 1 for errors, 2 for warnings, 3 for info, 4 for verbose spammy stuff. ===== -biome_lib:generate_tree(pos, treemodel) -biome_lib:grow_tree(pos, treemodel) +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, generating a tree is done via the above two calls, which in turn immediately @@ -472,13 +470,13 @@ 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, perhaps to execute something extra whenever a tree is spawned. -biome_lib:generate_tree(pos, treemodel) is called any time a tree is spawned +biome_lib.generate_ltree(pos, treemodel) is called any time a tree is spawned at map generation time. 'pos' is the position of the block on which the tree 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_tree(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. @@ -487,22 +485,6 @@ sapling into a tree. There are other, internal helper functions that are not meant for use by other mods. Don't rely on them, as they are subject to change without notice. - -=============== -Global Settings -=============== - -Set this to true if you want the mod to spam your console with debug info :-) - - plantlife_debug = false - -To slow down the playback of the queue (e.g. for really slow machines where -the 0.2 second max limiter isn't enough), set: - - biome_lib_queue_run_ratio = - -Default is 100 (basically percent of maximum runtime) - ====================== Fertile Ground Mapping ====================== diff --git a/compat.lua b/compat.lua new file mode 100644 index 0000000..05c3897 --- /dev/null +++ b/compat.lua @@ -0,0 +1,51 @@ +-- compatibility shims for old mods + +function biome_lib:register_generate_plant(b, n) + biome_lib.dbg("Warning: biome_lib:register_generate_plant() is deprecated!", 2) + biome_lib.dbg("Use biome_lib.register_on_generate() instead", 2) + biome_lib.dbg("Item: "..dump(n), 2) + biome_lib.register_on_generate(b, n) +end + +function biome_lib:spawn_on_surfaces(sd, sp, sr, sc, ss, sa) + biome_lib.dbg("Warning: biome_lib:spawn_on_surfaces() is deprecated!", 2) + biome_lib.dbg("Use biome_lib.register_active_spawner() instead.", 2) + biome_lib.dbg("Item: "..dump(sd.spawn_plants or sp[1] or sp), 2) + biome_lib.register_active_spawner(sd, sp, sr, sc, ss, sa) +end + +function biome_lib:replace_object(p, r, f, w, d) + biome_lib.dbg("Warning: biome_lib:replace_object() is deprecated!", 2) + biome_lib.dbg("Use biome_lib.replace_plant() instead.", 2) + biome_lib.dbg("Item: "..dump(r), 2) + biome_lib.replace_plant(p, r, f, w, d) +end + +function biome_lib:grow_plants(o) + biome_lib.dbg("Warning: biome_lib:grow_plants() is deprecated!", 2) + biome_lib.dbg("Use biome_lib.update_plant() instead.", 2) + biome_lib.dbg("Item: "..dump(o.grow_nodes), 2) + biome_lib.update_plant(o) +end + +function biome_lib.generate_ltree(p, n) + minetest.spawn_tree(p, n) +end + +function biome_lib.grow_ltree(p, n) + minetest.spawn_tree(p, n) +end + +function biome_lib:generate_tree(p, n) + biome_lib.dbg("Warning: biome_lib:generate_tree() is deprecated!", 2) + biome_lib.dbg("Use biome_lib.generate_ltree() instead.", 2) + biome_lib.dbg("Item: "..dump(n), 2) + biome_lib.generate_ltree(p, n) +end + +function biome_lib:grow_tree(p, n) + biome_lib.dbg("Warning: biome_lib:grow_tree() is deprecated!", 2) + biome_lib.dbg("Use biome_lib.grow_ltree() instead.", 2) + biome_lib.dbg("Item: "..dump(n), 2) + biome_lib.grow_ltree(p, n) +end diff --git a/growth.lua b/growth.lua index ba5285c..dd4d11b 100644 --- a/growth.lua +++ b/growth.lua @@ -15,7 +15,7 @@ function biome_lib.check_surface(name, nodes) return false end -function biome_lib:grow_plants(opts) +function biome_lib.update_plant(opts) local options = opts @@ -32,7 +32,7 @@ function biome_lib:grow_plants(opts) n = options.grow_plant end - options.label = options.label or "biome_lib grow_plants(): "..n + options.label = options.label or "biome_lib.update_plant(): "..n if options.grow_delay*time_scale >= 1 then options.interval = options.grow_delay*time_scale @@ -53,12 +53,12 @@ function biome_lib:grow_plants(opts) local root_node = minetest.get_node({x=pos.x, y=pos.y-options.height_limit, z=pos.z}) local walldir = nil 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 if biome_lib.default_grow_through_nodes[n_top.name] and (not options.need_wall or (options.need_wall 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 minetest.swap_node(p_top, { name = options.grow_plant, param2 = walldir}) end @@ -67,24 +67,10 @@ function biome_lib:grow_plants(opts) minetest.swap_node(pos, biome_lib.air) else - biome_lib:replace_object(pos, options.grow_result, options.grow_function, options.facedir, options.seed_diff) + biome_lib.replace_plant(pos, options.grow_result, options.grow_function, options.facedir, options.seed_diff) end end end end }) end - - --- spawn_tree() on generate is routed through here so that other mods can hook --- into it. - -function biome_lib:generate_tree(pos, nodes_or_function_or_model) - minetest.spawn_tree(pos, nodes_or_function_or_model) -end - --- and this one's for the call used in the growing code - -function biome_lib:grow_tree(pos, nodes_or_function_or_model) - minetest.spawn_tree(pos, nodes_or_function_or_model) -end diff --git a/init.lua b/init.lua index f5a0d31..184e30d 100644 --- a/init.lua +++ b/init.lua @@ -147,7 +147,7 @@ local function get_biome_data(pos, perlin_fertile) return fertility, temperature, humidity end -function biome_lib:is_node_loaded(node_pos) +function biome_lib.is_node_loaded(node_pos) local n = minetest.get_node_or_nil(node_pos) if (not n) or (n.name == "ignore") then return false @@ -155,7 +155,7 @@ function biome_lib:is_node_loaded(node_pos) return true end -function biome_lib:set_defaults(biome) +function biome_lib.set_defaults(biome) biome.seed_diff = biome.seed_diff or 0 biome.min_elevation = biome.min_elevation or biome_lib.mapgen_elevation_limit.min biome.max_elevation = biome.max_elevation or biome_lib.mapgen_elevation_limit.max @@ -193,7 +193,7 @@ end -- register the list of surfaces to spawn stuff on, filtering out all duplicates. -- separate the items by air-checking or non-air-checking map eval methods -function biome_lib:register_generate_plant(biomedef, nodes_or_function_or_model) +function biome_lib.register_on_generate(biomedef, nodes_or_function_or_model) -- if calling code passes an undefined node for a surface or -- as a node to be spawned, don't register an action for it. @@ -348,7 +348,7 @@ end function biome_lib.populate_surfaces(biome, nodes_or_function_or_model, snodes, checkair) local items_added = 0 - biome_lib:set_defaults(biome) + biome_lib.set_defaults(biome) -- filter stage 1 - find nodes from the supplied surfaces that are within the current biome. @@ -408,7 +408,7 @@ function biome_lib.populate_surfaces(biome, nodes_or_function_or_model, snodes, if objtype == "table" then if nodes_or_function_or_model.axiom then - biome_lib:generate_tree(p_top, nodes_or_function_or_model) + biome_lib.generate_ltree(p_top, nodes_or_function_or_model) biome_lib.dbg("An L-tree was spawned at "..minetest.pos_to_string(p_top), 4) spawned = true else @@ -650,7 +650,7 @@ end) -- The spawning ABM -function biome_lib:spawn_on_surfaces(sd,sp,sr,sc,ss,sa) +function biome_lib.register_active_spawner(sd,sp,sr,sc,ss,sa) local biome = {} @@ -671,7 +671,7 @@ function biome_lib:spawn_on_surfaces(sd,sp,sr,sc,ss,sa) biome.interval = 1 end - biome_lib:set_defaults(biome) + biome_lib.set_defaults(biome) biome.spawn_plants_count = #(biome.spawn_plants) local n @@ -699,7 +699,7 @@ function biome_lib:spawn_on_surfaces(sd,sp,sr,sc,ss,sa) 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 - and biome_lib:is_node_loaded(p_top) + and biome_lib.is_node_loaded(p_top) if not pos_biome_ok then return -- Outside of biome @@ -743,7 +743,7 @@ function biome_lib:spawn_on_surfaces(sd,sp,sr,sc,ss,sa) return -- Not enough air end - local walldir = biome_lib:find_adjacent_wall(p_top, biome.verticals_list, biome.choose_random_wall) + local walldir = biome_lib.find_adjacent_wall(p_top, biome.verticals_list, biome.choose_random_wall) if biome.alt_wallnode and walldir then if n_top.name == "air" then minetest.swap_node(p_top, { name = biome.alt_wallnode, param2 = walldir }) @@ -778,7 +778,7 @@ function biome_lib:spawn_on_surfaces(sd,sp,sr,sc,ss,sa) minetest.swap_node(pos, { name = plant_to_spawn, param2 = fdir }) elseif biome.spawn_on_side then - local onside = biome_lib:find_open_side(pos) + local onside = biome_lib.find_open_side(pos) if onside then minetest.swap_node(onside.newpos, { name = plant_to_spawn, param2 = onside.facedir }) end @@ -794,11 +794,11 @@ end -- Function to decide how to replace a plant - either grow it, replace it with -- a tree, run a function, or die with an error. -function biome_lib:replace_object(pos, replacement, grow_function, walldir, seeddiff) +function biome_lib.replace_plant(pos, replacement, grow_function, walldir, seeddiff) local growtype = type(grow_function) if growtype == "table" then minetest.swap_node(pos, biome_lib.air) - biome_lib:grow_tree(pos, grow_function) + biome_lib.grow_ltree(pos, grow_function) return elseif growtype == "function" then local perlin_fertile_area = minetest.get_perlin(seeddiff, perlin_octaves, perlin_persistence, perlin_scale) @@ -831,7 +831,7 @@ end -- read a field from a node's definition -function biome_lib:get_nodedef_field(nodename, fieldname) +function biome_lib.get_nodedef_field(nodename, fieldname) if not minetest.registered_nodes[nodename] then return nil end @@ -863,6 +863,11 @@ if biome_lib.debug_log_level >= 3 then biome_lib.show_pending_block_count() end +-- backward compat +dofile(biome_lib.modpath .. "/compat.lua") + +-- and report the final registration results: + minetest.after(0, function() biome_lib.dbg("Registered a total of "..(#biome_lib.surfaceslist_aircheck)+(#biome_lib.surfaceslist_no_aircheck).." surface types to be evaluated, spread", 0) biome_lib.dbg("across "..#biome_lib.actionslist_aircheck.." actions with air-checking and "..#biome_lib.actionslist_no_aircheck.." actions without.", 0) diff --git a/search_functions.lua b/search_functions.lua index 85772fc..0b0158f 100644 --- a/search_functions.lua +++ b/search_functions.lua @@ -2,7 +2,7 @@ -- function to decide if a node has a wall that's in verticals_list{} -- returns wall direction of valid node, or nil if invalid. -function biome_lib:find_adjacent_wall(pos, verticals, randomflag) +function biome_lib.find_adjacent_wall(pos, verticals, randomflag) local verts = dump(verticals) if randomflag then local walltab = {} @@ -27,7 +27,7 @@ end -- node that matches the ground table. Returns the new position, or nil if -- height limit is exceeded before finding it. -function biome_lib:search_downward(pos, heightlimit, ground) +function biome_lib.search_downward(pos, heightlimit, ground) for i = 0, heightlimit do if string.find(dump(ground), minetest.get_node({x=pos.x, y=pos.y-i, z = pos.z}).name) then return {x=pos.x, y=pos.y-i, z = pos.z} @@ -36,7 +36,7 @@ function biome_lib:search_downward(pos, heightlimit, ground) return false end -function biome_lib:find_open_side(pos) +function biome_lib.find_open_side(pos) if minetest.get_node({ x=pos.x-1, y=pos.y, z=pos.z }).name == "air" then return {newpos = { x=pos.x-1, y=pos.y, z=pos.z }, facedir = 2} end