add experimental support for calling an arbitrary function

in the spawning ABM after all other biome tests and general checks (aside from
spawning at the sides/bottom/top of a node) are done.
This commit is contained in:
Vanessa Ezekowitz 2013-01-29 16:22:33 -05:00
parent 320154a3a8
commit 8df8e44a0c
2 changed files with 22 additions and 9 deletions

20
API.txt
View File

@ -68,13 +68,7 @@ you must pass at least four arguments as regular keyed entries in the table,
in any order: in any order:
plants_lib: spawn_on_surfaces({ plants_lib: spawn_on_surfaces({
spawn_plants = {table}, -- List of plants to spawn with this ABM call. spawn_plants = something, -- [*] String or table; see below.
-- The program will choose one of these at
-- random each time the ABM executes. 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.
spawn_delay = number, -- same as sdelay spawn_delay = number, -- same as sdelay
spawn_chance = number, -- same as schance spawn_chance = number, -- same as schance
spawn_surfaces = {table} -- List of node names on which the plants spawn_surfaces = {table} -- List of node names on which the plants
@ -234,6 +228,18 @@ plants_lib: spawn_on_surfaces({
-- settings. -- settings.
}) })
[*] 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
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.
You can also specify a string containing the name of a function to execute.
In this case, the function will be passed a single position parameter
indicating where the function should place the desired object, and the checks
for spawning on top vs. sides vs. bottom vs. replacing the target node will be
skipped.
By default, if a biome node, size, and count are not defined, the biome 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. checking is disabled. Same holds true for the nneighbors bit above that.

View File

@ -11,7 +11,7 @@
plantslib = {} plantslib = {}
local DEBUG = true --... except if you want to spam the console with debugging info :-) local DEBUG = false --... except if you want to spam the console with debugging info :-)
plantslib.plantlife_seed_diff = 329 -- needs to be global so other mods can see it plantslib.plantlife_seed_diff = 329 -- needs to be global so other mods can see it
@ -240,7 +240,11 @@ function plantslib:spawn_on_surfaces(sd,sp,sr,sc,ss,sa)
local plant_to_spawn = biome.spawn_plants[rnd] local plant_to_spawn = biome.spawn_plants[rnd]
plantslib:dbg("Chose entry number "..rnd.." of "..biome.spawn_plants_count) plantslib:dbg("Chose entry number "..rnd.." of "..biome.spawn_plants_count)
if not biome.spawn_on_side and not biome.spawn_on_bottom and not biome.spawn_replace_node then if type(spawn_plants) == "string" then
plantslib:dbg("Call function: "..spawn_plants.."("..dump(pos)..")")
assert(loadstring(spawn_plants.."("..dump(pos)..")"))()
elseif not biome.spawn_on_side and not biome.spawn_on_bottom and not biome.spawn_replace_node then
local fdir = biome.facedir local fdir = biome.facedir
if biome.random_facedir then if biome.random_facedir then
fdir = math.random(biome.random_facedir[1],biome.random_facedir[2]) fdir = math.random(biome.random_facedir[1],biome.random_facedir[2])
@ -250,6 +254,7 @@ function plantslib:spawn_on_surfaces(sd,sp,sr,sc,ss,sa)
plantslib:dbg("Spawn: "..plant_to_spawn.." on top of ("..dump(pos)..")") plantslib:dbg("Spawn: "..plant_to_spawn.." on top of ("..dump(pos)..")")
minetest.env:add_node(p_top, { name = plant_to_spawn, param2 = fdir }) minetest.env:add_node(p_top, { name = plant_to_spawn, param2 = fdir })
end end
elseif biome.spawn_replace_node then elseif biome.spawn_replace_node then
local fdir = biome.facedir local fdir = biome.facedir
if biome.random_facedir then if biome.random_facedir then
@ -258,12 +263,14 @@ function plantslib:spawn_on_surfaces(sd,sp,sr,sc,ss,sa)
end end
plantslib:dbg("Spawn: "..plant_to_spawn.." to replace "..minetest.env:get_node(pos).name.." at ("..dump(pos)..")") plantslib:dbg("Spawn: "..plant_to_spawn.." to replace "..minetest.env:get_node(pos).name.." at ("..dump(pos)..")")
minetest.env:add_node(pos, { name = plant_to_spawn, param2 = fdir }) minetest.env:add_node(pos, { name = plant_to_spawn, param2 = fdir })
elseif biome.spawn_on_side then elseif biome.spawn_on_side then
local onside = plantslib:find_open_side(pos) local onside = plantslib:find_open_side(pos)
if onside then if onside then
plantslib:dbg("Spawn: "..plant_to_spawn.." at side of ("..dump(pos).."), facedir "..onside.facedir.."") plantslib:dbg("Spawn: "..plant_to_spawn.." at side of ("..dump(pos).."), facedir "..onside.facedir.."")
minetest.env:add_node(onside.newpos, { name = plant_to_spawn, param2 = onside.facedir }) minetest.env:add_node(onside.newpos, { name = plant_to_spawn, param2 = onside.facedir })
end end
elseif biome.spawn_on_bottom then elseif biome.spawn_on_bottom then
if minetest.env:get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then if minetest.env:get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then
local fdir = biome.facedir local fdir = biome.facedir