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, 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 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 information, and a string, function, or table describing what to do if the
suitable node (see below). engine finds a suitable surface node (see below).
The biome table contains quite a number of options, though there are fewer 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 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. random_facedir = {table}, -- same as with the ABM spawner.
} }
Regarding node_or_function_or_treedef, this must either be table with an Regarding nodes_or_function_or_treedef, this must either be a string naming
L-Systems tree definition, or a string with a node or function name. 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 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 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 top of the target position directly (unless one of the other mapgen options
directs the code to do otherwise). directs the code to do otherwise).
If you specified a table, the code assumes this table contains an L-Systems If you specified a table and there is no "axiom" field, the code assumes that
tree definition, then that definition will be passed directly to the it is a list of nodes. Simply name one node per entry in the list, e.g.
spawn_tree() function along with the position to spawn the tree on. {"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 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 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. -- 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 -- 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 -- if calling code passes an undefined node for a surface or
-- as a node to be spawned, don't register an action for it. -- as a node to be spawned, don't register an action for it.
if type(node_or_function_or_model) == "string" if type(nodes_or_function_or_model) == "string"
and string.find(node_or_function_or_model, ":") and string.find(nodes_or_function_or_model, ":")
and not minetest.registered_nodes[node_or_function_or_model] then and not minetest.registered_nodes[nodes_or_function_or_model] then
plantslib:dbg("Warning: Ignored registration for undefined spawn node: "..dump(node_or_function_or_model)) plantslib:dbg("Warning: Ignored registration for undefined spawn node: "..dump(nodes_or_function_or_model))
return return
end end
if type(node_or_function_or_model) == "string" if type(nodes_or_function_or_model) == "string"
and not string.find(node_or_function_or_model, ":") then and not string.find(nodes_or_function_or_model, ":") then
plantslib:dbg("Warning: Registered function call using deprecated string method: "..dump(node_or_function_or_model)) plantslib:dbg("Warning: Registered function call using deprecated string method: "..dump(nodes_or_function_or_model))
end end
if biomedef.check_air == false then if biomedef.check_air == false then
plantslib:dbg("Register no-air-check mapgen hook: "..dump(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, node_or_function_or_model } plantslib.actions_list_noaircheck[#plantslib.actions_list_noaircheck + 1] = { biomedef, nodes_or_function_or_model }
local s = biomedef.surface local s = biomedef.surface
if type(s) == "string" then if type(s) == "string" then
if s and minetest.registered_nodes[s] 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
end end
else else
plantslib:dbg("Register with-air-checking mapgen hook: "..dump(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, node_or_function_or_model } plantslib.actions_list[#plantslib.actions_list + 1] = { biomedef, nodes_or_function_or_model }
local s = biomedef.surface local s = biomedef.surface
if type(s) == "string" then if type(s) == "string" then
if s and minetest.registered_nodes[s] 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 for action = 1, #plantslib.actions_list do
local biome = plantslib.actions_list[action][1] 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) plantslib:set_defaults(biome)
@ -280,27 +280,36 @@ function plantslib:generate_block_with_air_checking(minp, maxp, blockseed)
minetest.remove_node(pos) minetest.remove_node(pos)
end end
local objtype = type(node_or_function_or_model) local objtype = type(nodes_or_function_or_model)
if objtype == "table" then 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 spawned = true
elseif objtype == "string" and else
minetest.registered_nodes[node_or_function_or_model] then
local fdir = nil local fdir = nil
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])
end 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 spawned = true
elseif objtype == "function" then elseif objtype == "function" then
node_or_function_or_model(pos) nodes_or_function_or_model(pos)
spawned = true spawned = true
elseif objtype == "string" and pcall(loadstring(("return %s(...)"): 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 spawned = true
else 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 end
else else
tries = tries + 1 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 for action = 1, #plantslib.actions_list_noaircheck do
local biome = plantslib.actions_list_noaircheck[action][1] 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) plantslib:set_defaults(biome)
@ -400,27 +409,36 @@ function plantslib:generate_block_no_air_check(minp, maxp, blockseed)
minetest.remove_node(pos) minetest.remove_node(pos)
end end
local objtype = type(node_or_function_or_model) local objtype = type(nodes_or_function_or_model)
if objtype == "table" then 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 spawned = true
elseif objtype == "string" and else
minetest.registered_nodes[node_or_function_or_model] then
local fdir = nil local fdir = nil
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])
end 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 spawned = true
elseif objtype == "function" then elseif objtype == "function" then
node_or_function_or_model(pos) nodes_or_function_or_model(pos)
spawned = true spawned = true
elseif objtype == "string" and pcall(loadstring(("return %s(...)"): 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 spawned = true
else 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 end
else else
tries = tries + 1 tries = tries + 1
@ -666,14 +684,14 @@ end
-- spawn_tree() on generate is routed through here so that other mods can hook -- spawn_tree() on generate is routed through here so that other mods can hook
-- into it. -- into it.
function plantslib:generate_tree(pos, node_or_function_or_model) function plantslib:generate_tree(pos, nodes_or_function_or_model)
minetest.spawn_tree(pos, node_or_function_or_model) minetest.spawn_tree(pos, nodes_or_function_or_model)
end end
-- and this one's for the call used in the growing code -- and this one's for the call used in the growing code
function plantslib:grow_tree(pos, node_or_function_or_model) function plantslib:grow_tree(pos, nodes_or_function_or_model)
minetest.spawn_tree(pos, node_or_function_or_model) minetest.spawn_tree(pos, nodes_or_function_or_model)
end end
-- Check for infinite stacks -- Check for infinite stacks