allow multiple nodes to be specified as a table in the

nodes_or_function_or_model field of the mapgen register call
This commit is contained in:
Vanessa Ezekowitz 2014-08-22 22:44:33 -04:00
parent a60f89a8a2
commit 27430814a0
2 changed files with 68 additions and 42 deletions

24
API.txt
View File

@ -238,12 +238,12 @@ checking is disabled. Same holds true for the nneighbors bit above that.
=====
plantslib:register_generate_plant(biome, node_or_function_or_treedef)
plantslib:register_generate_plant(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
information, and a string or table describing what to do if the engine finds a
suitable node (see below).
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
here than are available in the ABM-based spawner, as some stuff doesn't make
@ -335,17 +335,25 @@ biome = {
random_facedir = {table}, -- same as with the ABM spawner.
}
Regarding node_or_function_or_treedef, this must either be table with an
L-Systems tree definition, or a string with a node or function name.
Regarding nodes_or_function_or_treedef, this must either be a string naming
a node to spawn, a table with a list of nodes to choose from, a table with an
L-Systems tree definition, or a function.
If you specified a string, the code will attempt to determine whether that
string specifies a valid node name. If it does, that node will be placed on
top of the target position directly (unless one of the other mapgen options
directs the code to do otherwise).
If you specified a table, the code assumes this table contains an L-Systems
tree definition, then that definition will be passed directly to the
spawn_tree() function along with the position to spawn the tree on.
If you specified a table and there is no "axiom" field, the code assumes that
it is a list of nodes. Simply name one node per entry in the list, e.g.
{"default:junglegrass", "default:dry_shrub"} and so on, for as many nodes as
you want to list. A random node from the list will be chosen each time the
code goes to place a node.
If you specified a table, and there *is* an "axiom" field, the code assumes
that this table contains an L-Systems tree definition, which will be passed
directly to the engine's spawn_tree() function along with the position on
which to spawn the tree.
You can also supply a function to be directly executed, which is given the
current node position (the usual "pos" table format) as its sole argument. It

View File

@ -114,26 +114,26 @@ 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 plantslib:register_generate_plant(biomedef, node_or_function_or_model)
function plantslib:register_generate_plant(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.
if type(node_or_function_or_model) == "string"
and string.find(node_or_function_or_model, ":")
and not minetest.registered_nodes[node_or_function_or_model] then
plantslib:dbg("Warning: Ignored registration for undefined spawn node: "..dump(node_or_function_or_model))
if type(nodes_or_function_or_model) == "string"
and string.find(nodes_or_function_or_model, ":")
and not minetest.registered_nodes[nodes_or_function_or_model] then
plantslib:dbg("Warning: Ignored registration for undefined spawn node: "..dump(nodes_or_function_or_model))
return
end
if type(node_or_function_or_model) == "string"
and not string.find(node_or_function_or_model, ":") then
plantslib:dbg("Warning: Registered function call using deprecated string method: "..dump(node_or_function_or_model))
if type(nodes_or_function_or_model) == "string"
and not string.find(nodes_or_function_or_model, ":") then
plantslib:dbg("Warning: Registered function call using deprecated string method: "..dump(nodes_or_function_or_model))
end
if biomedef.check_air == false then
plantslib:dbg("Register no-air-check mapgen hook: "..dump(node_or_function_or_model))
plantslib.actions_list_noaircheck[#plantslib.actions_list_noaircheck + 1] = { biomedef, node_or_function_or_model }
plantslib:dbg("Register no-air-check mapgen hook: "..dump(nodes_or_function_or_model))
plantslib.actions_list_noaircheck[#plantslib.actions_list_noaircheck + 1] = { biomedef, nodes_or_function_or_model }
local s = biomedef.surface
if type(s) == "string" then
if s and minetest.registered_nodes[s] then
@ -156,8 +156,8 @@ function plantslib:register_generate_plant(biomedef, node_or_function_or_model)
end
end
else
plantslib:dbg("Register with-air-checking mapgen hook: "..dump(node_or_function_or_model))
plantslib.actions_list[#plantslib.actions_list + 1] = { biomedef, node_or_function_or_model }
plantslib:dbg("Register with-air-checking mapgen hook: "..dump(nodes_or_function_or_model))
plantslib.actions_list[#plantslib.actions_list + 1] = { biomedef, nodes_or_function_or_model }
local s = biomedef.surface
if type(s) == "string" then
if s and minetest.registered_nodes[s] then
@ -209,7 +209,7 @@ function plantslib:generate_block_with_air_checking(minp, maxp, blockseed)
for action = 1, #plantslib.actions_list do
local biome = plantslib.actions_list[action][1]
local node_or_function_or_model = plantslib.actions_list[action][2]
local nodes_or_function_or_model = plantslib.actions_list[action][2]
plantslib:set_defaults(biome)
@ -280,27 +280,36 @@ function plantslib:generate_block_with_air_checking(minp, maxp, blockseed)
minetest.remove_node(pos)
end
local objtype = type(node_or_function_or_model)
local objtype = type(nodes_or_function_or_model)
if objtype == "table" then
plantslib:generate_tree(pos, node_or_function_or_model)
if nodes_or_function_or_model.axiom then
plantslib:generate_tree(pos, nodes_or_function_or_model)
spawned = true
elseif objtype == "string" and
minetest.registered_nodes[node_or_function_or_model] then
else
local fdir = nil
if biome.random_facedir then
fdir = math.random(biome.random_facedir[1], biome.random_facedir[2])
end
minetest.set_node(p_top, { name = node_or_function_or_model, param2 = fdir })
minetest.set_node(p_top, { name = nodes_or_function_or_model[math.random(#nodes_or_function_or_model)], param2 = fdir })
spawned = true
end
elseif objtype == "string" and
minetest.registered_nodes[nodes_or_function_or_model] then
local fdir = nil
if biome.random_facedir then
fdir = math.random(biome.random_facedir[1], biome.random_facedir[2])
end
minetest.set_node(p_top, { name = nodes_or_function_or_model, param2 = fdir })
spawned = true
elseif objtype == "function" then
node_or_function_or_model(pos)
nodes_or_function_or_model(pos)
spawned = true
elseif objtype == "string" and pcall(loadstring(("return %s(...)"):
format(node_or_function_or_model)),pos) then
format(nodes_or_function_or_model)),pos) then
spawned = true
else
plantslib:dbg("Warning: Ignored invalid definition for object "..dump(node_or_function_or_model).." that was pointed at {"..dump(pos).."}")
plantslib:dbg("Warning: Ignored invalid definition for object "..dump(nodes_or_function_or_model).." that was pointed at {"..dump(pos).."}")
end
else
tries = tries + 1
@ -330,7 +339,7 @@ function plantslib:generate_block_no_air_check(minp, maxp, blockseed)
for action = 1, #plantslib.actions_list_noaircheck do
local biome = plantslib.actions_list_noaircheck[action][1]
local node_or_function_or_model = plantslib.actions_list_noaircheck[action][2]
local nodes_or_function_or_model = plantslib.actions_list_noaircheck[action][2]
plantslib:set_defaults(biome)
@ -400,27 +409,36 @@ function plantslib:generate_block_no_air_check(minp, maxp, blockseed)
minetest.remove_node(pos)
end
local objtype = type(node_or_function_or_model)
local objtype = type(nodes_or_function_or_model)
if objtype == "table" then
plantslib:generate_tree(pos, node_or_function_or_model)
if nodes_or_function_or_model.axiom then
plantslib:generate_tree(pos, nodes_or_function_or_model)
spawned = true
elseif objtype == "string" and
minetest.registered_nodes[node_or_function_or_model] then
else
local fdir = nil
if biome.random_facedir then
fdir = math.random(biome.random_facedir[1], biome.random_facedir[2])
end
minetest.set_node(p_top, { name = node_or_function_or_model, param2 = fdir })
minetest.set_node(p_top, { name = nodes_or_function_or_model[math.random(#nodes_or_function_or_model)], param2 = fdir })
spawned = true
end
elseif objtype == "string" and
minetest.registered_nodes[nodes_or_function_or_model] then
local fdir = nil
if biome.random_facedir then
fdir = math.random(biome.random_facedir[1], biome.random_facedir[2])
end
minetest.set_node(p_top, { name = nodes_or_function_or_model, param2 = fdir })
spawned = true
elseif objtype == "function" then
node_or_function_or_model(pos)
nodes_or_function_or_model(pos)
spawned = true
elseif objtype == "string" and pcall(loadstring(("return %s(...)"):
format(node_or_function_or_model)),pos) then
format(nodes_or_function_or_model)),pos) then
spawned = true
else
plantslib:dbg("Warning: Ignored invalid definition for object "..dump(node_or_function_or_model).." that was pointed at {"..dump(pos).."}")
plantslib:dbg("Warning: Ignored invalid definition for object "..dump(nodes_or_function_or_model).." that was pointed at {"..dump(pos).."}")
end
else
tries = tries + 1
@ -666,14 +684,14 @@ end
-- spawn_tree() on generate is routed through here so that other mods can hook
-- into it.
function plantslib:generate_tree(pos, node_or_function_or_model)
minetest.spawn_tree(pos, node_or_function_or_model)
function plantslib: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 plantslib:grow_tree(pos, node_or_function_or_model)
minetest.spawn_tree(pos, node_or_function_or_model)
function plantslib:grow_tree(pos, nodes_or_function_or_model)
minetest.spawn_tree(pos, nodes_or_function_or_model)
end
-- Check for infinite stacks