From 7dd3ec252519a5d209a520c192360b7a5dc64b36 Mon Sep 17 00:00:00 2001 From: Vanessa Ezekowitz Date: Sat, 19 Jan 2013 00:45:46 -0500 Subject: [PATCH] Added a function to let one spawn plants at mapgen time, but it's slow as molasses in January. Not recommended for general use yet. --- API.txt | 289 +++++++++++++++++++++++-------------------- flowers/init.lua | 14 +-- junglegrass/init.lua | 12 +- plants_lib/init.lua | 176 ++++++++++++++++---------- poinsonivy/init.lua | 9 +- 5 files changed, 286 insertions(+), 214 deletions(-) diff --git a/API.txt b/API.txt index 6af91f3..4c89a0e 100644 --- a/API.txt +++ b/API.txt @@ -1,178 +1,201 @@ This document briefly describes the Plantlife API. +Last revision: 2013-01-18 + ========= Functions ========= -There are five main functions defined by the main "plants_lib" mod: +All functions in plants lib are declared locally to avoid namespace collisions +with other mods. They are accessible via the "plantslib" method, e.g. +plantslib:spawn_on_surfaces() and so forth. + +There are three main functions defined by the main "plants_lib" mod: spawn_on_surfaces() +generate_on_surfaces() grow_plants() -plant_valid_wall() -is_node_loaded() -dbg() + +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. See init.lua for more. ----- + The first of these, spawn_on_surfaces() is defined with quite a large number of variables. All of the variables below, if specified at all, must be specified exactly in the order given here. This function has no return value. spawn_on_surfaces = function(sdelay, splant, sradius, schance, ssurface, - savoid, seed_diff, lightmin, lightmax, nneighbors, ocount, - facedir, depthmax, altitudemin, altitudemax, tempmin, tempmax) + savoid, seed_diff, lightmin, lightmax, nneighbors, ocount, facedir, + depthmax, altitudemin, altitudemax, sbiome, sbiomesize, sbiomecount, + airsize, aircount, tempmin, tempmax) The first several of these are all required, and are from the last version of the flowers mod, so this part of the API should be the same as before. -sdelay: The value passed to the ABM's interval parameter, usually - in the 1000-3000 range. -splant: The node name of the item to spawn (e.g. - "flowers:flower_rose"). Note that if the plant is - "poisonivy:seedling", and it's next to a wall at spawn - time, it automatically becomes the wall-climbing variety. - A plant will of course only be spawned if the node about - to be replaced is air. -sradius: Don't spawn within this many nodes of the avoid items - mentioned below. -schance: The value passed to the ABM's chance parameter, normally - in the 10-100 range. -ssurface: Table with the names of the nodes on which to spawn the - plant in question, such as {"default:sand", - "default:dirt_with_grass"}. It is not recommended to put - "default:dirt" or "default:stone" into this table if you - can do without it, as this will cause the engine to - process potentially large numbers of such nodes when - deciding when to execute the ABM and where it should - operate. -savoid: Table with a list of groups and/or node names to avoid - when spawning the plant, such as {"group:flowers", - "default:tree"}. +sdelay: The value passed to the ABM's interval parameter, in seconds. +splant: The node name of the item to spawn (e.g. + "flowers:flower_rose"). Note that if the plant is + "poisonivy:seedling", and it's next to a wall at spawn + time, it automatically becomes the wall-climbing variety. + A plant will of course only be spawned if the node about + to be replaced is air. +sradius: Don't spawn within this many nodes of the avoid items + mentioned below. +schance: The value passed to the ABM's chance parameter, normally + in the 10-100 range (1-in-X chance of operating on a given + node, e.g. 1-in-10). +ssurface: Table with the names of the nodes on which to spawn the + plant in question, such as {"default:sand", + "default:dirt_with_grass"}. It is not recommended to put + "default:dirt" or "default:stone" into this table if you + can do without it, as this will cause the engine to + process potentially large numbers of such nodes when + deciding when to execute the ABM and where it should + operate. +savoid: Table with a list of groups and/or node names to avoid + when spawning the plant, such as {"group:flowers", + "default:tree"}. From here down are several optional parameters. You can use as many as you -need, but you must specify them in order (so if you want lightmax, you need -lightmin and seed_diff also, but not the rest). +need, but you must specify them in order. To keep the default values for +those parameters you don't wish to alter, set them to nil in your function +call. -seed_diff: The Perlin seed difference value passed to the - minetest.env:get_perlin() function. Used along with the - global Perlin controls below to create the "biome" in - which the plants will spawn. Usually a value of somewhere - in the 10 to 100 range is good. Defaults to 0 if not - provided. -lightmin: Minimum amount of light necessary to make a plant spawn. - Defaults to 0. -lightmax: Maximum amount of light present to allow a plant to spawn. - Defaults to the engine's MAX_LIGHT value of 14. -nneighbors: Table with a list of neighboring nodes, passed to the ABM - as the "neighbors" parameter, indicating what needs to be - next to the node the plant is about to spawn on, such as - {"default:stone","default:water_source"}. Defaults to the - value of ssurface if not provided. -ocount: There must be at least this many of the above neighbors in - the eight spaces immediately surrounding the node the - plant is about to spawn on for it to happen. Defaults to - 0. -facedir: The value passed to the param2 variable when adding the - plant node to the map. Defaults to 0. -depthmax: If a node spawns on top of a water source, the water must - be at most this deep. Defaults to 1 node. -altitudemin: Items must be at this altitude or higher to spawn at all. - Defaults to -31000. -altitudemax: But no higher than this altitude. Defaults to +31000. -sbiome: List of nodes that must be somewhere in the vicinity in - order for the plant to spawn. Typically this would be - something like "default:water_source" or "default:sand". - Defaults to the value of ssurface if not provided. -sbiomesize: How large of an area to check for the above node. - Specifically, this checks a cuboid area centered on the - node to be spawned on, 3 tall and this wide/long. - Defaults to 0. -sbiomecount: How many of the above nodes must be within that radius. - Defaults to 1. -airradius: How large of an area to check for air around the target. - Defaults to 0 (only check the target). -aircount: How many of the surrounding nodes need to be air for the - above check to return true. Defaults to 1. -tempmin: Minimum 2d Perlin value (which has a floating point range of - -1 to +1) needed in the temperature map for the desired - plant to spawn. Defaults to -1 if not supplied. -tempmax: Maximum temperature. Defaults to +1. +seed_diff: The Perlin seed difference value passed to the + minetest.env:get_perlin() function. Used along with the + global Perlin controls below to create the "biome" in + which the plants will spawn. Usually a value of somewhere + in the 10 to 100 range is good. Defaults to 0 if not + provided. +lightmin: Minimum amount of light necessary to make a plant spawn. + Defaults to 0. +lightmax: Maximum amount of light present to allow a plant to spawn. + Defaults to the engine's MAX_LIGHT value of 14. +nneighbors: Table with a list of neighboring nodes, passed to the ABM + as the "neighbors" parameter, indicating what needs to be + next to the node the plant is about to spawn on, such as + {"default:stone","default:water_source"}. Defaults to the + value of ssurface if not provided. +ocount: There must be at least this many of the above neighbors in + the eight spaces immediately surrounding the node the + plant is about to spawn on for it to happen. Defaults to + 0. +facedir: The value passed to the param2 variable when adding the + plant node to the map. Defaults to 0. +depthmax: If a node spawns on top of a water source, the water must + be at most this deep. Defaults to 1 node. +altitudemin: Items must be at this altitude or higher to spawn at all. + Defaults to -31000. +altitudemax: But no higher than this altitude. Defaults to +31000. +sbiome: List of nodes that must be somewhere in the vicinity in + order for the plant to spawn. Typically this would be + something like "default:water_source" or "default:sand". + Defaults to the value of ssurface if not provided. +sbiomesize: How large of an area to check for the above node. + Specifically, this checks a cuboid area centered on the + node to be spawned on, 3 tall and this wide/long. + Defaults to 0. +sbiomecount: How many of the above nodes must be within that radius. + Defaults to 1. +airradius: How large of an area to check for air around the target. + Defaults to 0 (only check the target). +aircount: How many of the surrounding nodes need to be air for the + above check to return true. Defaults to 1. +tempmin: Minimum 2d Perlin value (which has a floating point range of + -1 to +1) needed in the temperature map for the desired + plant to spawn. Defaults to -1 if not supplied. +tempmax: Maximum temperature. Defaults to +1. By default, if a biome node, size, and count are not defined, the biome checking is disabled. Same holds true for the nneighbors bit above that. ----- -The second function, grow_plants() is used to turn the spawned nodes above + +XXXXXXXXXX FIX ME FIX ME FIX ME +XXXXXXXXXX +XXXXXXXXXX Document the mapgen-based spawning function +XXXXXXXXXX +XXXXXXXXXX FIX ME FIX ME FIX ME + +----- + +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 is defined like so: grow_plants = function(gdelay, gchance, gplant, gresult, dry_early_node, - grow_nodes, facedir, need_wall, grow_vertically, height_limit, - ground_nodes, grow_function) + grow_nodes, facedir, need_wall, grow_vertically, height_limit, + ground_nodes, grow_function) -gdelay: Passed as the ABM "interval" parameter, as with spawning. -gchance: Passed as the ABM "chance" parameter. -gplant: Name of the node being grown. This value is passed as the - only item in the table given to the ABM as the nodenames - parameter, so it is the plants themselves that are the ABM - trigger, rather than the ground they spawned on. A plant - will only grow if the node above it is air. -gresult: Name of the node into which the above should transform - when the ABM executes. -dry_early_node: This value is ignored except for jungle grass, where it - indicates which node the grass must be on in order for it - to turn from "short" to default:dry_shrub. -grow_nodes: This node must be under the plant in order for it to grow - at all. Normally this should be the same as the list of - surfaces passed to the spawning ABM as the "nodenames" - parameter, such as {"default:dirt_with_grass", - "default:sand"}. This is so that the plant can be - manually placed on something like a flower pot or - something without it growing and eventually dieing. -facedir: Same as with spawning a plant. If supplied, this value is - passed to the param2 variable when changing the plant. If - nil or left out, no new param2 value is applied. -need_wall: Set this to true if you the plant needs to grow against a - wall. Defaults to false. -grow_vertically: Set this to true if the plant needs to grow vertically, as - in climbing poison ivy. Defaults to false. -height_limit: Just how tall can a vertically-growing plant go? Set this - accordingly. The mod will search straight down from the - position being spawned at to find a ground node, below. - Defaults to 62000 (unlimited). -ground_nodes: What nodes should be treated as "the ground" below a - vertically-growing plant. Usually this will be the same - as the grow_nodes table, but might also include, for - example, water or some other surrounding material. - Defaults to "default:dirt_with_grass". -grow_function: Execute the named function (which must be supplied as just - the name of the function as a string) when growing this - node, rather than using the method provided by the default - growing code. Note that if this is specified, only the - gdelay, gchance, and gplant variables will be used, the - rest will be ignored by the growing ABM. You can still - read them from within the function if you need to. The - function will be passed two parameters in order: The - position of the node to be "grown" (in the usual table - format), and the Perlin noise value at the location in - question. -seed_diff: The Perlin seed diff to be use to calculate the noise - value given to the above grow_function. Should be the - same as the seed diff used when first spawning the plant - that's being grown. +gdelay: Passed as the ABM "interval" parameter, as with spawning. +gchance: Passed as the ABM "chance" parameter. +gplant: Name of the node being grown. This value is passed as the + only item in the table given to the ABM as the nodenames + parameter, so it is the plants themselves that are the ABM + trigger, rather than the ground they spawned on. A plant + will only grow if the node above it is air. +gresult: Name of the node into which the above should transform + when the ABM executes. +dry_early_node: This value is ignored except for jungle grass, where it + indicates which node the grass must be on in order for it + to turn from "short" to default:dry_shrub. +grow_nodes: This node must be under the plant in order for it to grow + at all. Normally this should be the same as the list of + surfaces passed to the spawning ABM as the "nodenames" + parameter, such as {"default:dirt_with_grass", + "default:sand"}. This is so that the plant can be + manually placed on something like a flower pot or + something without it growing and eventually dieing. +facedir: Same as with spawning a plant. If supplied, this value is + passed to the param2 variable when changing the plant. If + nil or left out, no new param2 value is applied. +need_wall: Set this to true if you the plant needs to grow against a + wall. Defaults to false. +grow_vertically: Set this to true if the plant needs to grow vertically, as + in climbing poison ivy. Defaults to false. +height_limit: Just how tall can a vertically-growing plant go? Set this + accordingly. The mod will search straight down from the + position being spawned at to find a ground node, set via the + parameter below. Defaults to 62000 (unlimited). +ground_nodes: What nodes should be treated as "the ground" below a + vertically-growing plant. Usually this will be the same + as the grow_nodes table, but might also include, for + example, water or some other surrounding material. + Defaults to "default:dirt_with_grass". +grow_function: Execute the named function (which must be supplied as just + the name of the function as a string) when growing this + node, rather than using the method provided by the default + growing code. Note that if this is specified, only the + gdelay, gchance, and gplant variables will be used, the + rest will be ignored by the growing ABM. You can still + read them from within the function if you need to. The + function will be passed two parameters in order: The + position of the node to be "grown" (in the usual table + format), and the Perlin noise value at the location in + question. +seed_diff: The Perlin seed diff to be use to calculate the noise + value given to the above grow_function. Should be the + same as the seed diff used when first spawning the plant + that's being grown. ----- -plant_valid_wall() expects only a single parameter, "pos", which is the usual -table indicating the coordinates around which to search for adjacent walls. -This function returns the location of the first wall found as a facedir value, -or nil if there are no adjacent walls. + +Of the few helper functions, plant_valid_wall() expects only a single +parameter, "pos", which is the usual table indicating the coordinates around +which to search for adjacent walls. This function returns the location of the +first wall found as a facedir value, or nil if there are no adjacent walls. ----- + is_node_loaded() is defined in exactly the same manner (that is, "node_pos" is a set of coordinates), and acts as a wrapper for the minetest.env:get_node_or_nil(node_pos) function. Returns true if the node in question is already loaded, or false if not. ----- + dbg() is a simple debug output function which takes one string parameter. It just checks if plantlife_debug is true and outputs the phrase "[Plantlife] " followed by the supplied string, via the print() function. @@ -252,7 +275,7 @@ Perlin Approx. Temperature -0.5 55 °C ( 131 °F) -0.25 41 °C ( 107 °F) -0.18 38 °C ( 100 °F) - 0 28 °C ( 83 °F) + 0 28 °C ( 83 °F) 0.13 21 °C ( 70 °F) 0.25 15 °C ( 59 °F) 0.5 2 °C ( 35 °F) diff --git a/flowers/init.lua b/flowers/init.lua index 0ce9560..d97f72c 100644 --- a/flowers/init.lua +++ b/flowers/init.lua @@ -2,9 +2,7 @@ local spawn_delay = 2000 -- 2000 local spawn_chance = 100 -- 100 -local grow_delay = 1000 -- 1000 -local grow_chance = 10 -- 10 -local flowers_seed_diff = plantlife_seed_diff+20 +local flowers_seed_diff = plantslib.plantlife_seed_diff+20 local flowers_list = { { "Rose", "rose", spawn_delay, 10, spawn_chance , 10}, @@ -66,7 +64,7 @@ for i in ipairs(flowers_list) do } }) - spawn_on_surfaces(delay, "flowers:flower_"..flower, radius, chance, "default:dirt_with_grass", {"group:flower", "group:poisonivy"}, flowers_seed_diff) + plantslib:spawn_on_surfaces(delay, "flowers:flower_"..flower, radius, chance, "default:dirt_with_grass", {"group:flower", "group:poisonivy"}, flowers_seed_diff) end minetest.register_node(":flowers:flower_waterlily", { @@ -105,11 +103,11 @@ minetest.register_node(":flowers:flower_seaweed", { }, }) -spawn_on_surfaces(spawn_delay/2, "flowers:flower_waterlily", 3, spawn_chance*2, "default:water_source" , {"group:flower"}, flowers_seed_diff, 10, nil, nil, nil, nil, 4) +plantslib:spawn_on_surfaces(spawn_delay/2, "flowers:flower_waterlily", 3, spawn_chance*2, "default:water_source" , {"group:flower"}, flowers_seed_diff, 10, nil, nil, nil, nil, 4) -spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:water_source" , {"group:flower"}, flowers_seed_diff, 4, 10, {"default:dirt_with_grass"}, 0, 1) -spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:dirt_with_grass", {"group:flower"}, flowers_seed_diff, 4, 10, {"default:water_source"} , 1, 1) -spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:stone" , {"group:flower"}, flowers_seed_diff, 4, 10, {"default:water_source"} , 6, 1) +plantslib:spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:water_source" , {"group:flower"}, flowers_seed_diff, 4, 10, {"default:dirt_with_grass"}, 0, 1) +plantslib:spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:dirt_with_grass", {"group:flower"}, flowers_seed_diff, 4, 10, {"default:water_source"} , 1, 1) +plantslib:spawn_on_surfaces(spawn_delay*2, "flowers:flower_seaweed" , 0.1, spawn_chance*2, "default:stone" , {"group:flower"}, flowers_seed_diff, 4, 10, {"default:water_source"} , 6, 1) minetest.register_craftitem(":flowers:flower_pot", { diff --git a/junglegrass/init.lua b/junglegrass/init.lua index 5a18eed..7dfde15 100644 --- a/junglegrass/init.lua +++ b/junglegrass/init.lua @@ -4,7 +4,7 @@ local spawn_delay = 2000 -- 2000 local spawn_chance = 100 -- 100 local grow_delay = 1000 -- 1000 local grow_chance = 10 -- 10 -local junglegrass_seed_diff = plantlife_seed_diff +local junglegrass_seed_diff = plantslib.plantlife_seed_diff local grasses_list = { {"junglegrass:shortest","junglegrass:short" }, @@ -68,12 +68,12 @@ minetest.register_node(':junglegrass:shortest', { }, }) -spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance, "default:dirt_with_grass", {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) -spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance*2, "default:sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) -spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance*3, "default:desert_sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) -spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance*3, "default:desert_sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) +plantslib:spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance, "default:dirt_with_grass", {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) +plantslib:spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance*2, "default:sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) +plantslib:spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance*3, "default:desert_sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) +plantslib:spawn_on_surfaces(spawn_delay*2, "junglegrass:shortest", 4, spawn_chance*3, "default:desert_sand" , {"group:junglegrass", "default:junglegrass", "default:dry_shrub"}, junglegrass_seed_diff, 5) for i in ipairs(grasses_list) do - grow_plants(grow_delay, grow_chance/2, grasses_list[i][1], grasses_list[i][2], "default:desert_sand", {"default:dirt_with_grass", "default:sand", "default:desert_sand"}) + plantslib:grow_plants(grow_delay, grow_chance/2, grasses_list[i][1], grasses_list[i][2], "default:desert_sand", {"default:dirt_with_grass", "default:sand", "default:desert_sand"}) end diff --git a/plants_lib/init.lua b/plants_lib/init.lua index 84ae8a1..8e16a53 100644 --- a/plants_lib/init.lua +++ b/plants_lib/init.lua @@ -1,17 +1,17 @@ -- Plantlife library mod by Vanessa Ezekowitz --- 2013-01-00 +-- 2013-01-18 -- -- License: WTFPL -- -- I got the temperature map idea from "hmmmm", values used for it came from +-- Splizard's snow mod. -- - -- Various settings - most of these probably won't need to be changed -plantlife_seed_diff = 329 -- needs to be global so other mods can see it +plantslib = {} -local plantlife_debug = true -- ...unless you want the modpack to spam the console ;-) +plantslib.plantlife_seed_diff = 329 -- needs to be global so other mods can see it local perlin_octaves = 3 local perlin_persistence = 0.6 @@ -28,13 +28,7 @@ local plantlife_limit = 0.1 -- compared against perlin noise. lower = more abun math.randomseed(os.time()) -local dbg = function(s) - if plantlife_debug then - print("[Plantlife] " .. s) - end -end - -local is_node_loaded = function(node_pos) +function plantslib:is_node_loaded(node_pos) n = minetest.env:get_node_or_nil(node_pos) if (n == nil) or (n.name == "ignore") then return false @@ -42,31 +36,89 @@ local is_node_loaded = function(node_pos) return true end +-- Spawn plants using the map generator + +function plantslib:register_generate_plant(biome) + minetest.register_on_generated(plantslib:search_for_surfaces(minp, maxp, biome)) +end + +function plantslib:search_for_surfaces(minp, maxp, biome) + return function(minp, maxp, blockseed) + print("Started checking generated mapblock...") + local searchnodes = minetest.env:find_nodes_in_area(minp, maxp, biome.surface) + local surfacenodes = {} + local numsurfacenodes = 0 + for i in ipairs(searchnodes) do + local pos = searchnodes[i] + local p_top = { x = pos.x, y = pos.y + 1, z = pos.z } + if minetest.env:get_node(p_top).name == "air" then + table.insert(surfacenodes, pos) + numsurfacenodes = numsurfacenodes + 1 + end + end + + print("Found "..numsurfacenodes.." surface nodes in map block {"..dump(minp)..":"..dump(maxp).."} to check.") + + if biome.seed_diff == nil then biome.seed_diff = 0 end + if biome.neighbors == nil then biome.neighbors = biome.surface end + if biome.ncount == nil then biome.ncount = -1 end + if biome.min_elevation == nil then biome.min_elevation = -31000 end + if biome.max_elevation == nil then biome.max_elevation = 31000 end + if biome.near_nodes_size == nil then biome.near_nodes_size = 0 end + if biome.near_nodes_count == nil then biome.near_nodes_count = 1 end + if biome.temp_min == nil then biome.temp_min = -1 end + if biome.temp_max == nil then biome.temp_max = 1 end + + for i in ipairs(surfacenodes) do + local pos = surfacenodes[i] + local p_top = {x = pos.x, y = pos.y + 1, z = pos.z} + local perlin1 = minetest.env:get_perlin(biome.seed_diff, perlin_octaves, perlin_persistence, perlin_scale) + local perlin2 = minetest.env:get_perlin(temperature_seeddiff, temperature_octaves, temperature_persistence, temperature_scale) + local noise1 = perlin1:get2d({x=p_top.x, y=p_top.z}) + local noise2 = perlin2:get2d({x=p_top.x, y=p_top.z}) + if minetest.env:find_node_near(p_top, biome.radius + math.random(-1.5,1.5), biome.avoid) == nil + and noise1 > plantlife_limit + and noise2 >= biome.temp_min + and noise2 <= biome.temp_max + and (biome.ncount == -1 or table.getn(minetest.env:find_nodes_in_area({x=pos.x-1, y=pos.y, z=pos.z-1}, {x=pos.x+1, y=pos.y, z=pos.z+1}, biome.neighbors)) > biome.ncount) + and (biome.near_nodes == nil or table.getn(minetest.env:find_nodes_in_area({x=pos.x-biome.near_nodes_size, y=pos.y-1, z=pos.z-biome.near_nodes_size}, {x=pos.x+biome.near_nodes_size, y=pos.y+1, z=pos.z+biome.near_nodes_size}, biome.near_nodes)) >= biome.near_nodes_count) + and pos.y >= biome.min_elevation + and pos.y <= biome.max_elevation + and (biome.water_depth == nil or minetest.env:get_node({ x = pos.x, y = pos.y-biome.water_depth-1, z = pos.z }).name ~= "default:water_source") + then + minetest.log("verbose", "Call function: "..biome.exec_funct.."("..dump(pos)..")") + assert(loadstring(biome.exec_funct.."("..dump(pos)..")"))() + end + end + print("Finished checking generated mapblock.") + end +end + -- The spawning ABM -spawn_on_surfaces = function( - sdelay, - splant, - sradius, - schance, - ssurface, - savoid, - seed_diff, - lightmin, - lightmax, - nneighbors, - ocount, - facedir, - depthmax, - altmin, - altmax, - sbiome, - sbiomesize, - sbiomecount, - airsize, - aircount, - tempmin, - tempmax) +function plantslib:spawn_on_surfaces( + sdelay, + splant, + sradius, + schance, + ssurface, + savoid, + seed_diff, + lightmin, + lightmax, + nneighbors, + ocount, + facedir, + depthmax, + altmin, + altmax, + sbiome, + sbiomesize, + sbiomecount, + airsize, + aircount, + tempmin, + tempmax) if seed_diff == nil then seed_diff = 0 end if lightmin == nil then lightmin = 0 end if lightmax == nil then lightmax = LIGHT_MAX end @@ -97,7 +149,7 @@ spawn_on_surfaces = function( if noise1 > plantlife_limit and noise2 >= tempmin and noise2 <= tempmax - and is_node_loaded(p_top) then + and plantslib:is_node_loaded(p_top) then local n_light = minetest.env:get_node_light(p_top, nil) if minetest.env:find_node_near(p_top, sradius + math.random(-1.5,2), savoid) == nil and n_light >= lightmin @@ -110,16 +162,16 @@ spawn_on_surfaces = function( and pos.y >= altmin and pos.y <= altmax then - local walldir = plant_valid_wall(p_top) + local walldir = plantslib:plant_valid_wall(p_top) if splant == "poisonivy:seedling" and walldir ~= nil then - dbg("Spawn: poisonivy:climbing at "..dump(p_top).." on "..ssurface) + minetest.log("verbose", "Spawn: poisonivy:climbing at "..dump(p_top).." on "..ssurface) minetest.env:add_node(p_top, { name = "poisonivy:climbing", param2 = walldir }) else local deepnode = minetest.env:get_node({ x = pos.x, y = pos.y-depthmax-1, z = pos.z }).name if (ssurface ~= "default:water_source") or (ssurface == "default:water_source" and deepnode ~= "default:water_source") then - dbg("Spawn: "..splant.." at "..dump(p_top).." on "..ssurface) + minetest.log("verbose", "Spawn: "..splant.." at "..dump(p_top).." on "..ssurface) minetest.env:add_node(p_top, { name = splant, param2 = facedir }) end end @@ -131,20 +183,20 @@ end -- The growing ABM -grow_plants = function( - gdelay, - gchance, - gplant, - gresult, - dry_early_node, - grow_nodes, - facedir, - need_wall, - grow_vertically, - height_limit, - ground_nodes, - grow_function, - seed_diff) +function plantslib:grow_plants( + gdelay, + gchance, + gplant, + gresult, + dry_early_node, + grow_nodes, + facedir, + need_wall, + grow_vertically, + height_limit, + ground_nodes, + grow_function, + seed_diff) if need_wall ~= true then need_wall = false end if grow_vertically ~= true then grow_vertically = false end if height_limit == nil then height_limit = 62000 end @@ -162,30 +214,30 @@ grow_plants = function( if grow_function == nil then if string.find(dump(grow_nodes), n_bot.name) ~= nil and n_top.name == "air" then if grow_vertically then - if find_first_node(pos, height_limit, ground_nodes) ~= nil then + if plantslib:find_first_node(pos, height_limit, ground_nodes) ~= nil then if need_wall then - local walldir=plant_valid_wall(p_top) + local walldir=plantslib:plant_valid_wall(p_top) if walldir ~= nil then - dbg("Grow: "..gplant.." upwards to ("..dump(p_top)..") on wall "..walldir) + minetest.log("verbose", "Grow: "..gplant.." upwards to ("..dump(p_top)..") on wall "..walldir) minetest.env:add_node(p_top, { name = gplant, param2 = walldir }) end else - dbg("Grow: "..gplant.." upwards to ("..dump(p_top)..")") + minetest.log("verbose", "Grow: "..gplant.." upwards to ("..dump(p_top)..")") minetest.env:add_node(p_top, { name = gplant }) end end -- corner case for changing short junglegrass to dry shrub in desert elseif n_bot.name == dry_early_node and gplant == "junglegrass:short" then - dbg("Die: "..gplant.." becomes default:dry_shrub at ("..dump(pos)..")") + minetest.log("verbose", "Die: "..gplant.." becomes default:dry_shrub at ("..dump(pos)..")") minetest.env:add_node(pos, { name = "default:dry_shrub" }) elseif gresult == nil then - dbg("Die: "..gplant.." at ("..dump(pos)..")") + minetest.log("verbose", "Die: "..gplant.." at ("..dump(pos)..")") minetest.env:remove_node(pos) elseif gresult ~= nil then - dbg("Grow: "..gplant.." becomes "..gresult.." at ("..dump(pos)..")") + minetest.log("verbose", "Grow: "..gplant.." becomes "..gresult.." at ("..dump(pos)..")") if facedir == nil then minetest.env:add_node(pos, { name = gresult }) else @@ -199,7 +251,7 @@ grow_plants = function( local perlin2 = minetest.env:get_perlin(temperature_seeddiff, temperature_octaves, temperature_persistence, temperature_scale) local noise1 = perlin1:get2d({x=p_top.x, y=p_top.z}) local noise2 = perlin2:get2d({x=p_top.x, y=p_top.z}) - dbg("Call function: "..grow_function.."("..dump(pos)..","..noise1..","..noise2..")") + minetest.log("verbose", "Call function: "..grow_function.."("..dump(pos)..","..noise1..","..noise2..")") assert(loadstring(grow_function.."("..dump(pos)..","..noise1..","..noise2..")"))() end end @@ -209,7 +261,7 @@ end -- function to decide if a node has a wall that's in verticals_list{} -- returns wall direction of valid node, or nil if invalid. -plant_valid_wall = function(wallpos) +function plantslib:plant_valid_wall(wallpos) local walldir = nil local verts = dump(verticals_list) @@ -230,7 +282,7 @@ end -- Function to search straight down from (pos) to find first node in match list. -find_first_node = function(pos, height_limit, nodelist) +function plantslib:find_first_node(pos, height_limit, nodelist) for i = 1, height_limit do n = minetest.env:get_node({x=pos.x, y=pos.y-i, z=pos.z}) if string.find(dump(nodelist),n.name) ~= nil then diff --git a/poinsonivy/init.lua b/poinsonivy/init.lua index 316a3ae..4a68e90 100644 --- a/poinsonivy/init.lua +++ b/poinsonivy/init.lua @@ -4,7 +4,7 @@ local spawn_delay = 2000 -- 2000 local spawn_chance = 100 -- 100 local grow_delay = 1000 -- 1000 local grow_chance = 10 -- 10 -local poisonivy_seed_diff = plantlife_seed_diff + 10 +local poisonivy_seed_diff = plantslib.plantlife_seed_diff + 10 local verticals_list = { "default:dirt", @@ -63,9 +63,8 @@ minetest.register_node(':poisonivy:climbing', { }, }) -spawn_on_surfaces(spawn_delay, "poisonivy:seedling", 10 , spawn_chance/10, "default:dirt_with_grass", {"group:poisonivy","group:flower"}, poisonivy_seed_diff, 7) +plantslib:spawn_on_surfaces(spawn_delay, "poisonivy:seedling", 10 , spawn_chance/10, "default:dirt_with_grass", {"group:poisonivy","group:flower"}, poisonivy_seed_diff, 7) -grow_plants(spawn_delay, grow_chance, "poisonivy:seedling", "poisonivy:sproutling", nil, {"default:dirt_with_grass"}) - -grow_plants(spawn_delay, grow_chance*2, "poisonivy:climbing", nil, nil, nil ,nil,true,true,nil,{"default:dirt_with_grass"}) +plantslib:grow_plants(spawn_delay, grow_chance, "poisonivy:seedling", "poisonivy:sproutling", nil, {"default:dirt_with_grass"}) +plantslib:grow_plants(spawn_delay, grow_chance*2, "poisonivy:climbing", nil, nil, nil ,nil,true,true,nil,{"default:dirt_with_grass"})