moved example trees into this seperate mod

This commit is contained in:
Sokomine 2017-04-11 22:27:46 +02:00
commit 92d6f6201f
6 changed files with 930 additions and 0 deletions

29
README.md Normal file
View File

@ -0,0 +1,29 @@
These are examples as to how trees_lib for Minetest can be used.
Files:
init.lua Just does dofile(..)
example_tree.lua A complex tree example.
trees_lib_growing_functions.lua Some adjusted growth functions
taken from other mods.
trees.lua Taken from and for minetest_game.
The example tree will look blueish and carry fruits that look like
copper lumps. It exists only to demonstrate what can be done. Depending
on the ground on which the sapling is placed, diffrent methods of
growing are used, and the tree will display diffrent forms of growth.
trees.lua is not executed. If you want to use it, copy it to
minetest_game/mods/default/trees.lua Create a backup of the existing file
there first. Then comment out all definitions of tree trunks, wood,
leaves and fruit nodes (=apple) in minetest_game/mods/default/nodes.lua
as those will be created by trees.lua. All calls to leafdecay in nodes.lua
have to be removed as well. Also remove the function leafdecay_after_destruct
in minetest_game/mods/default/functions.lua
trees.lua and trees_lib have not yet been adjusted to the most recent
changes in minetest_game (i.e. using of LBMs and timers instead of
ABMs).
trees.lua is taken from minetest_game and modified so that trees_lib can be
used by minetest_game.

2
depends.txt Normal file
View File

@ -0,0 +1,2 @@
trees_lib
default

209
example_tree.lua Normal file
View File

@ -0,0 +1,209 @@
--
-- This is an actual example of how trees_lib can be used
--
local modname = minetest.get_current_modname();
-- this is taken as an example from https://github.com/duane-r/valleys_c/blob/master/*
-- Create and initialize a table for a schematic.
local function vmg_schematic_array(width, height, depth)
-- Dimensions of data array.
local s = {size={x=width, y=height, z=depth}}
s.data = {}
for x = 0,width-1 do
for y = 0,height-1 do
for z = 0,depth-1 do
local i = x*width*height + y*width + z + 1
s.data[i] = {}
s.data[i].name = "air"
s.data[i].param1 = 000
end
end
end
s.yslice_prob = {}
return s
end
-- this is taken as an example from https://github.com/duane-r/valleys_c/blob/master/deco_banana.lua
-- A shock of leaves at the top and some fruit.
local function vmg_generate_banana_schematic(trunk_height)
local height = trunk_height + 3
local radius = 1
local width = 3
local s = vmg_schematic_array(width, height, width)
-- the main trunk
for y = 0,trunk_height do
local i = (0+radius)*width*height + y*width + (0+radius) + 1
s.data[i].name = modname..":example_tree"
s.data[i].param1 = 255
end
-- leaves at the top
for x = -1,1 do
for y = trunk_height+1, height-1 do
for z = -1,1 do
local i = (x+radius)*width*height + y*width + (z+radius) + 1
if y > height - 2 then
s.data[i].name = modname..":example_leaves"
if x == 0 and z == 0 then
s.data[i].param1 = 255
else
s.data[i].param1 = 127
end
elseif x == 0 and z == 0 then
s.data[i].name = modname..":example_leaves"
s.data[i].param1 = 255
elseif x ~= 0 or z ~= 0 then
s.data[i].name = modname..":cfruit"
s.data[i].param1 = 75
end
end
end
end
return s
end
-- this function allows the tree to chose between diffrent growth functions (or provide its own)
local example_tree_select_how_to_grow = function( pos, node, sapling_data_how_to_grow, ground_found )
-- grow into a normal fruit tree on dirt or grass
if( ground_found == "default:dirt"
or ground_found == "default:dirt_with_grass" ) then
return 1;
-- if growing on desert sand, then grow like an acacia
elseif( ground_found == "default:desert_sand" ) then
return 2;
-- on normal sand, grow like the banana tree from valleys_c
elseif( ground_found == "default:sand" ) then
return 3;
-- on soil, grow like one of the birches from moretrees
elseif( ground_found == "group:soil" ) then
return math.random(4,5);
-- stone is not the ideal ground to grow on...
elseif( ground_found == "group:stone" ) then
-- this shows that we can also return new tree types
return {
use_function = trees_lib.generate_unhappy_tree,
xoff = 1, zoff = 1, yoff = 0, height = 3,
};
end
end
--- the actual example tree; it will grow in very diffrent ways depending on where it is placed;
-- most of the node names and descriptions can be created automaticly;
-- all we have to supply in such cases are the texture names
trees_lib.register_tree( "example",
{ tree = {
--node_name = modname..":example_tree",
--description = "example Tree",
tiles = {"default_tree_top.png^[colorize:#015dbb70", "default_tree_top.png^[colorize:#015dbb70", "default_tree.png^[colorize:#015dbb70"},
}, wood = {
--node_name = modname..":example_wood",
--description = "example Wooden Planks",
tiles = {"default_wood.png^[colorize:#015dbb70"},
}, leaves = {
--node_name = modname..":example_leaves",
--description = "example Leaves",
tiles = {"default_leaves.png^[colorize:#01ffd870"},
special_tiles= {"default_leaves_simple.png^[colorize:#01ffd870"},
}, sapling = {
--node_name = modname..":example_sapling",
--description = "example Tree Sapling",
tiles = {"default_sapling.png^[colorize:#ff840170"},
--rarity = 20,
}, fruit = {
-- the fruit diverges in name and description from what would automaticly be created
node_name = modname..":cfruit",
description = "Yellow Copper Fruit",
tiles = {"default_copper_lump.png^[colorize:#e3ff0070"},
-- the fruit can be eaten
on_use = minetest.item_eat(2),
}},
-- the diffrent ways of how a tree can be grown
{
-- version 1
-- one of these methods will be choosen randomly
{
-- a function - like that used to create the trees/apple trees in mapgen v6
use_function = trees_lib.generate_fruit_tree,
-- How far will the tree reach in each direction? We need to load a
-- sufficiently large voxelmanip area.
xoff = 2, zoff = 2, yoff = 0, height = 12,
}, { -- version 2
-- schematics can be used as well
use_schematic = minetest.get_modpath("default").."/schematics/acacia_tree_from_sapling.mts",
-- TODO: determine these values automaticly
xoff = 4, zoff = 4, yoff = 0, height = 10,
-- use a schematic with diffrent nodes
use_replacements = {
{"default:acacia_tree", modname..":example_tree"},
{"default:acacia_leaves",modname..":example_leaves"},
}
}, { -- version 3
-- schematics in table form are also acceptable
use_schematic = vmg_generate_banana_schematic(3),
-- TODO: determine these values automaticly
xoff = 1, zoff = 1, yoff = 0, height = 8,
-- TODO: minetest.place_schematic does not apply replacements for tables
-- use a schematic with diffrent nodes
use_replacements = {
{"default:acacia_tree", modname..":example_tree"},
{"default:acacia_leaves",modname..":example_leaves"},
}
}, { -- version 4
-- this is moretrees.birch_model1
use_lsystem = {
axiom="FFFFFdddccA/FFFFFFcA/FFFFFFcB",
rules_a="[&&&dddd^^ddddddd][&&&---dddd^^ddddddd][&&&+++dddd^^ddddddd][&&&++++++dddd^^ddddddd]",
rules_b="[&&&ddd^^ddddd][&&&---ddd^^ddddd][&&&+++ddd^^ddddd][&&&++++++ddd^^ddddd]",
rules_c="/",
rules_d="F",
trunk=modname..":example_tree", --"moretrees:birch_trunk",
leaves=modname..":example_leaves", --"moretrees:birch_leaves",
angle=30,
iterations=2,
random_level=0,
trunk_type="single",
thin_branches=true
}
},{ -- version 5
-- this is moretrees.birch_model2
use_lsystem = {
axiom="FFFdddccA/FFFFFccA/FFFFFccB",
rules_a="[&&&dFFF^^FFFdd][&&&---dFFF^^FFFdd][&&&+++dFFF^^FFFdd][&&&++++++dFFF^^FFFdd]",
rules_b="[&&&dFF^^FFFd][&&&---dFFF^^FFFd][&&&+++dFF^^FFFd][&&&++++++dFF^^FFFd]",
rules_c="/",
rules_d="F",
trunk=modname..":example_tree", --"moretrees:birch_trunk",
leaves=modname..":example_leaves", --"moretrees:birch_leaves",
angle=30,
iterations=2,
random_level=0,
trunk_type="single",
thin_branches=true
}
},
},
-- grows_on_node_type_list - the tree only grows on nodes of this type
{"default:cobble", "group:soil", "default:dirt", "default:dirt_with_grass", "default:desert_sand","default:sand","group:soil","group:stone"},
-- no (additional) limits as to where the tree can grow (no can_grow_function)
nil,
-- the tree will grow in a diffrent way depending on the ground it grows on; see the function below for details
example_tree_select_how_to_grow,
-- the interval for the sapling-growing abm in seconds
10,
-- the chance of the abm actually firing and growing the sapling (the higher the smaller)
1
);

6
init.lua Normal file
View File

@ -0,0 +1,6 @@
local modpath = minetest.get_modpath( minetest.get_current_modname());
-- some examples as to how tree growing functions can be implemented
dofile( modpath.."/trees_lib_growing_functions.lua")
-- as the name says: an example tree; just for documentation
dofile( modpath.."/example_tree.lua")

545
trees.lua Normal file
View File

@ -0,0 +1,545 @@
--
-- Grow trees from saplings
--
-- Leafdecay
local function leafdecay_after_destruct(pos, oldnode, def)
for _, v in pairs(minetest.find_nodes_in_area(vector.subtract(pos, def.radius),
vector.add(pos, def.radius), def.leaves)) do
local node = minetest.get_node(v)
local timer = minetest.get_node_timer(v)
if node.param2 == 0 and not timer:is_started() then
timer:start(math.random(20, 120) / 10)
end
end
end
local function leafdecay_on_timer(pos, def)
if minetest.find_node_near(pos, def.radius, def.trunks) then
return false
end
local node = minetest.get_node(pos)
local drops = minetest.get_node_drops(node.name)
for _, item in ipairs(drops) do
local is_leaf
for _, v in pairs(def.leaves) do
if v == item then
is_leaf = true
end
end
if minetest.get_item_group(item, "leafdecay_drop") ~= 0 or
not is_leaf then
minetest.add_item({
x = pos.x - 0.5 + math.random(),
y = pos.y - 0.5 + math.random(),
z = pos.z - 0.5 + math.random(),
}, item)
end
end
minetest.remove_node(pos)
minetest.check_for_falling(pos)
end
function default_register_leafdecay( tree_name, mod_prefix, nodes)
-- TODO: how to handle radius? might be stored inside the leaf node definition as additional data
local def = { leaves = {}, trunks = {nodes.tree.node_name}, radius = 2 };
-- there can be up to 5 diffrent types of leaves; they all need to decay
local leaves_id = {'leaves','leaves2','leaves3','leaves4','leaves5'};
for _,k in ipairs( leaves_id ) do
if( nodes[ k ] and nodes[ k ].node_name ) then
table.insert( def.leaves, nodes[ k ].node_name );
end
end
assert(def.leaves)
assert(def.trunks)
assert(def.radius)
for _, v in pairs(def.trunks) do
minetest.override_item(v, {
after_destruct = function(pos, oldnode)
leafdecay_after_destruct(pos, oldnode, def)
end,
})
end
for _, v in pairs(def.leaves) do
minetest.override_item(v, {
on_timer = function(pos)
leafdecay_on_timer(pos, def)
end,
})
end
end
-- enable leafdecay for all registered trees
trees_lib.register_on_new_tree_type( default_register_leafdecay );
-- add craft receipes for turning 1 tree into 4 corresponding wood;
-- this function will be called for each registered tree
local default_craft_wood_from_tree = function( tree_name, mod_prefix, nodes )
if( not( nodes )
or not( nodes.tree ) or not( nodes.tree.node_name )
or not( nodes.wood ) or not( nodes.wood.node_name )) then
return;
end
minetest.register_craft({
-- the amount of wood given might be a global config variable
output = nodes.wood.node_name..' 4',
recipe = {
{ nodes.tree.node_name },
}
});
end
-- allow to craft wooden planks from all trees
trees_lib.register_on_new_tree_type( default_craft_wood_from_tree );
-- 'Can grow' function
local random = math.random
local function can_grow(pos)
local ll = minetest.get_node_light(pos)
-- return -1 - no final abort, just don't grow yet
if not ll or ll < 13 then -- Minimum light level for growth
return -1 -- matches grass, wheat and cotton
end
return 1; -- the tree can grow
end
-- default trees grow using a function if they detect mapgen v6 - and a schematic otherwise
local default_select_how_to_grow = function( pos, node, how_to_grow, ground_found )
local mapgen = minetest.get_mapgen_params().mgname
if mapgen == "v6" then
-- select growing method 1 (previously set to a function)
return 1;
else
-- select growing method 2 (previously set to a schematic)
return 2;
end
end
-- log successful growth; for that, we override the a_tree_has_grown function
local old_a_tree_has_grown = trees_lib.a_tree_has_grown;
trees_lib.a_tree_has_grown = function( pos, node, how_to_grow )
minetest.log("action", "A "..tostring( node.name ).." grows into a tree at "..
minetest.pos_to_string(pos))
old_a_tree_has_grown( pos, node, how_to_grow );
end
--
-- Tree generation
--
-- Apple tree and jungle tree trunk and leaves function
local function add_trunk_and_leaves(data, a, pos, tree_cid, leaves_cid,
height, size, iters, is_apple_tree)
local x, y, z = pos.x, pos.y, pos.z
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
local c_apple = minetest.get_content_id("default:apple")
-- Trunk
data[a:index(x, y, z)] = tree_cid -- Force-place lowest trunk node to replace sapling
for yy = y + 1, y + height - 1 do
local vi = a:index(x, yy, z)
local node_id = data[vi]
if node_id == c_air or node_id == c_ignore or node_id == leaves_cid then
data[vi] = tree_cid
end
end
-- Force leaves near the trunk
for z_dist = -1, 1 do
for y_dist = -size, 1 do
local vi = a:index(x - 1, y + height + y_dist, z + z_dist)
for x_dist = -1, 1 do
if data[vi] == c_air or data[vi] == c_ignore then
if is_apple_tree and random(1, 8) == 1 then
data[vi] = c_apple
else
data[vi] = leaves_cid
end
end
vi = vi + 1
end
end
end
-- Randomly add leaves in 2x2x2 clusters.
for i = 1, iters do
local clust_x = x + random(-size, size - 1)
local clust_y = y + height + random(-size, 0)
local clust_z = z + random(-size, size - 1)
for xi = 0, 1 do
for yi = 0, 1 do
for zi = 0, 1 do
local vi = a:index(clust_x + xi, clust_y + yi, clust_z + zi)
if data[vi] == c_air or data[vi] == c_ignore then
if is_apple_tree and random(1, 8) == 1 then
data[vi] = c_apple
else
data[vi] = leaves_cid
end
end
end
end
end
end
end
-- Apple tree
function default.grow_apple_tree( data, a, pos, sapling_data, extra_params )
-- translate parameter names
local c_tree = sapling_data.cid.tree;
local c_leaves = sapling_data.cid.leaves;
-- about every 4th tree is an apple tree
local is_apple_tree = (random(1, 4) == 1);
local height = random(4, 5)
-- call the actual tree generation function
add_trunk_and_leaves(data, a, pos, c_tree, c_leaves, height, 2, 8, is_apple_tree)
end
-- Jungle tree
function default.grow_jungle_tree(data, a, pos, sapling_data, extra_params )
--[[
NOTE: Jungletree-placing code is currently duplicated in the engine
and in games that have saplings; both are deprecated but not
replaced yet
--]]
-- translate parameter names
local c_jungletree = sapling_data.cid.tree;
local c_jungleleaves = sapling_data.cid.leaves;
local height = random(8, 12)
add_trunk_and_leaves(data, a, pos, c_jungletree, c_jungleleaves, height, 3, 30, false)
-- further parameters for the roots
local x, y, z = pos.x, pos.y, pos.z
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
-- Roots
for z_dist = -1, 1 do
local vi_1 = a:index(x - 1, y - 1, z + z_dist)
local vi_2 = a:index(x - 1, y, z + z_dist)
for x_dist = -1, 1 do
if random(1, 3) >= 2 then
if data[vi_1] == c_air or data[vi_1] == c_ignore then
data[vi_1] = c_jungletree
elseif data[vi_2] == c_air or data[vi_2] == c_ignore then
data[vi_2] = c_jungletree
end
end
vi_1 = vi_1 + 1
vi_2 = vi_2 + 1
end
end
end
-- Pine tree from mg mapgen mod, design by sfan5, pointy top added by paramat
local function add_pine_needles(data, vi, c_air, c_ignore, c_snow, c_pine_needles)
local node_id = data[vi]
if node_id == c_air or node_id == c_ignore or node_id == c_snow then
data[vi] = c_pine_needles
end
end
local function add_snow(data, vi, c_air, c_ignore, c_snow)
local node_id = data[vi]
if node_id == c_air or node_id == c_ignore then
data[vi] = c_snow
end
end
function default.grow_pine_tree(data, a, pos, sapling_data, extra_params )
-- translate parameter names
local c_pine_tree = sapling_data.cid.tree;
local c_pine_needles = sapling_data.cid.leaves;
-- other internal parameters
local x, y, z = pos.x, pos.y, pos.z
local maxy = y + random(9, 13) -- Trunk top
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
local c_snow = minetest.get_content_id("default:snow")
local c_snowblock = minetest.get_content_id("default:snowblock")
local c_dirtsnow = minetest.get_content_id("default:dirt_with_snow")
-- Scan for snow nodes near sapling to enable snow on branches
local snow = false
for yy = y - 1, y + 1 do
for zz = z - 1, z + 1 do
local vi = a:index(x - 1, yy, zz)
for xx = x - 1, x + 1 do
local nodid = data[vi]
if nodid == c_snow or nodid == c_snowblock or nodid == c_dirtsnow then
snow = true
end
vi = vi + 1
end
end
end
-- Upper branches layer
local dev = 3
for yy = maxy - 1, maxy + 1 do
for zz = z - dev, z + dev do
local vi = a:index(x - dev, yy, zz)
local via = a:index(x - dev, yy + 1, zz)
for xx = x - dev, x + dev do
if random() < 0.95 - dev * 0.05 then
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
c_pine_needles)
if snow then
add_snow(data, via, c_air, c_ignore, c_snow)
end
end
vi = vi + 1
via = via + 1
end
end
dev = dev - 1
end
-- Centre top nodes
add_pine_needles(data, a:index(x, maxy + 1, z), c_air, c_ignore, c_snow,
c_pine_needles)
add_pine_needles(data, a:index(x, maxy + 2, z), c_air, c_ignore, c_snow,
c_pine_needles) -- Paramat added a pointy top node
if snow then
add_snow(data, a:index(x, maxy + 3, z), c_air, c_ignore, c_snow)
end
-- Lower branches layer
local my = 0
for i = 1, 20 do -- Random 2x2 squares of needles
local xi = x + random(-3, 2)
local yy = maxy + random(-6, -5)
local zi = z + random(-3, 2)
if yy > my then
my = yy
end
for zz = zi, zi+1 do
local vi = a:index(xi, yy, zz)
local via = a:index(xi, yy + 1, zz)
for xx = xi, xi + 1 do
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
c_pine_needles)
if snow then
add_snow(data, via, c_air, c_ignore, c_snow)
end
vi = vi + 1
via = via + 1
end
end
end
local dev = 2
for yy = my + 1, my + 2 do
for zz = z - dev, z + dev do
local vi = a:index(x - dev, yy, zz)
local via = a:index(x - dev, yy + 1, zz)
for xx = x - dev, x + dev do
if random() < 0.95 - dev * 0.05 then
add_pine_needles(data, vi, c_air, c_ignore, c_snow,
c_pine_needles)
if snow then
add_snow(data, via, c_air, c_ignore, c_snow)
end
end
vi = vi + 1
via = via + 1
end
end
dev = dev - 1
end
-- Trunk
data[a:index(x, y, z)] = c_pine_tree -- Force-place lowest trunk node to replace sapling
for yy = y + 1, maxy do
local vi = a:index(x, yy, z)
local node_id = data[vi]
if node_id == c_air or node_id == c_ignore or
node_id == c_pine_needles or node_id == c_snow then
data[vi] = c_pine_tree
end
end
end
--
-- Trees
--
-- the normal tree does not have a special name and no space after it
trees_lib.register_tree( "normal",
{ tree = {
node_name = "default:tree",
tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png"},
paramtype2 = "facedir",
}, wood = {
node_name = "default:wood",
description = "Wooden Planks",
tiles = {"default_wood.png"},
}, sapling = {
node_name = "default:sapling",
description = "Sapling",
tiles = {"default_sapling.png"},
}, leaves = {
node_name = "default:leaves",
description = "Leaves",
tiles = {"default_leaves.png"},
special_tiles = {"default_leaves_simple.png"},
}, fruit = {
node_name = "default:apple",
description = "Apple",
tiles = {"default_apple.png"},
on_use = minetest.item_eat(2),
}},
-- growing methods:
{
{ -- the first growing method uses a function
use_function = default.grow_apple_tree,
xoff = 2, zoff = 2, yoff = 8, height = 15,
}, { -- the second growing method (when mapgen is not v6) uses a schematic
use_schematic = minetest.get_modpath("default") .. "/schematics/apple_tree_from_sapling.mts",
xoff = 2, zoff = 2, yoff = 1, height = 10,
}
},
-- grows on nodes of this type:
{"group:soil"},
-- can_grow_function: (in this case, checks if there is enough light)
can_grow,
-- select_how_to_grow_function:
default_select_how_to_grow,
-- interval (for the abm)
10,
-- chance (for the abm)
50
);
-- the jungletree has no space between tree name and fruther parts of the name
trees_lib.register_tree( "jungle",
{ tree = {
node_name = "default:jungletree",
description = "Jungle Tree",
tiles = {"default_jungletree_top.png", "default_jungletree_top.png",
"default_jungletree.png"},
}, wood = {
node_name = "default:junglewood",
description = "Junglewood Planks",
tiles = {"default_junglewood.png"},
}, sapling = {
node_name = "default:junglesapling",
description = "Jungle Sapling",
tiles = {"default_junglesapling.png"},
}, leaves = {
node_name = "default:jungleleaves",
description = "Jungle Leaves",
tiles = {"default_jungleleaves.png"},
special_tiles = {"default_jungleleaves_simple.png"},
-- the jungletree has no fruit
}, fruit = {
node_name = "air",
}},
{ { -- the first growing method uses a function
use_function = default.grow_jungle_tree,
xoff = 3, zoff = 3, yoff = 1, height = 15,
},{ -- new jungle tree (grown from schematic)
use_schematic = minetest.get_modpath("default") .. "/schematics/jungle_tree_from_sapling.mts",
xoff = 2, zoff = 2, yoff = 1, height = 10,
}
},
{"group:soil"},
can_grow,
default_select_how_to_grow,
10, 50);
-- the pine tree mostly follows naming conventions
trees_lib.register_tree( "pine",
-- ...except for the leaves, which are needles
{ leaves = {
node_name = "default:pine_needles",
description = "Pine Needles",
tiles = {"default_pine_needles.png"},
-- the pine tree also has no fruit
}, fruit = {
node_name = "air",
}},
{
{ -- the old pine tree (in mapgen v6) grows using a function
use_function = default.grow_pine_tree,
-- we need to know how much space will have to be loaded into voxelmanip
xoff = 3, zoff = 3, yoff = 1, height = 18,
}, { -- new pine tree (grown from schematic)
use_schematic = minetest.get_modpath("default") .. "/schematics/pine_tree_from_sapling.mts",
xoff = 2, zoff = 2, yoff = 1, height = 10,
}
},
{"group:soil"},
can_grow,
default_select_how_to_grow,
10, 50);
-- the acacia tree follows naming conventions
trees_lib.register_tree( "acacia",
-- the acacia tree has no fruit
{ fruit = {
node_name = "air",
}},
-- the acacia only knows to grow from a schematic
{
{ -- new acacia tree (grown from schematic)
use_schematic = minetest.get_modpath("default") .. "/schematics/acacia_tree_from_sapling.mts",
xoff = 4, zoff = 4, yoff = 1, height = 10,
}
},
{"group:soil","group:sand"},
can_grow,
-- the acacia only has the schematic version - there is no other growing method to select
nil,
10, 50);
-- aspen tree - follows naming conventions as well
trees_lib.register_tree( "aspen",
{ fruit = {
node_name = "air",
}},
{
{
use_schematic = minetest.get_modpath("default") .. "/schematics/aspen_tree_from_sapling.mts",
xoff = 2, zoff = 2, yoff = 1, height = 16,
}
},
{"group:soil"},
can_grow,
nil,
10, 50);

View File

@ -0,0 +1,139 @@
--[[ the version from mg_villages
-- this is more or less the code to grow an apple tree with v6
trees_lib.generate_fruit_tree = function(data, a, pos, is_apple_tree, seed, snow)
local leaves_type = c_leaves;
if( snow
or data[ a:index(pos.x, pos.y, pos.z) ] == c_snow
or data[ a:index(pos.x, pos.y+1, pos.z) ] == c_snow ) then
leaves_type = c_msnow_leaves2;
end
local hight = math.random(4, 5)
for x_area = -2, 2 do
for y_area = -1, 2 do
for z_area = -2, 2 do
if math.random(1,30) < 23 then --randomize leaves
local area_l = a:index(pos.x+x_area, pos.y+hight+y_area-1, pos.z+z_area) --sets area for leaves
if data[area_l] == c_air or data[area_l] == c_ignore or data[area_l]== c_snow then --sets if it's air or ignore
if( snow and c_msnow_leaves1 and math.random( 1,5 )==1) then
data[area_l] = c_msnow_leaves1;
else
data[area_l] = leaves_type --add leaves now
end
end
-- put a snow top on some leaves
if ( snow and math.random(1,3)==1 )then
mg_villages.trees_add_snow(data, a:index(pos.x+x_area, pos.y+hight+y_area, pos.z+z_area), c_air, c_ignore, c_snow)
end
end
end
end
end
for tree_h = 0, hight-1 do -- add the trunk
local area_t = a:index(pos.x, pos.y+tree_h, pos.z) --set area for tree
if data[area_t] == c_air or data[area_t] == c_leaves or data[area_t] == c_sapling or data[area_t] == c_snow or data[area_t] == c_msnow_top or data[area_t] == c_msnow_leaves1 or data[area_t] == c_msnow_leaves2 then --sets if air
data[area_t] = c_tree --add tree now
end
end
end
--]]
-- Apple tree and jungle tree trunk and leaves function
trees_lib.generate_fruit_tree = function(data, a, pos, sapling_data, extra_params )
local tree_cid = sapling_data.cid.tree;
local leaves_cid = sapling_data.cid.leaves;
local fruit_cid = sapling_data.cid.fruit;
local height = math.random(3,7);
local size = 2; --math.random(1,3);
local iters = 8;
local x, y, z = pos.x, pos.y, pos.z
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
-- Trunk
data[a:index(x, y, z)] = tree_cid -- Force-place lowest trunk node to replace sapling
for yy = y + 1, y + height - 1 do
local vi = a:index(x, yy, z)
local node_id = data[vi]
if node_id == c_air or node_id == c_ignore or node_id == leaves_cid then
data[vi] = tree_cid
end
end
-- Force leaves near the trunk
for z_dist = -1, 1 do
for y_dist = -size, 1 do
local vi = a:index(x - 1, y + height + y_dist, z + z_dist)
for x_dist = -1, 1 do
if data[vi] == c_air or data[vi] == c_ignore then
if fruit_cid and fruit_cid ~= leaves_cid and math.random(1, 8) == 1 then
data[vi] = fruit_cid
else
data[vi] = leaves_cid
end
end
vi = vi + 1
end
end
end
-- Randomly add leaves in 2x2x2 clusters.
for i = 1, iters do
local clust_x = x + math.random(-size, size - 1)
local clust_y = y + height + math.random(-size, 0)
local clust_z = z + math.random(-size, size - 1)
for xi = 0, 1 do
for yi = 0, 1 do
for zi = 0, 1 do
local vi = a:index(clust_x + xi, clust_y + yi, clust_z + zi)
if data[vi] == c_air or data[vi] == c_ignore then
if fruit_cid and fruit_cid ~= leaves_cid and math.random(1, 8) == 1 then
data[vi] = fruit_cid
else
data[vi] = leaves_cid
end
end
end
end
end
end
end
-- a very small tree
trees_lib.generate_unhappy_tree = function(data, a, pos, sapling_data, extra_params )
local tree_cid = sapling_data.cid.tree;
local leaves_cid = sapling_data.cid.leaves;
local x, y, z = pos.x, pos.y, pos.z
local c_air = minetest.get_content_id("air")
local c_ignore = minetest.get_content_id("ignore")
-- Trunk
data[a:index(x, y, z)] = tree_cid;
local found = data[a:index(x, y+1, z )];
if( found==c_air or found==c_ignore ) then
data[a:index(x, y+1, z)] = tree_cid;
end
for xv=-1,1 do
for zv=-1,1 do
if( math.random(1,2)==1 ) then
local found = data[a:index(x+xv, y+1, z+zv )]
if( found==c_air or found==c_ignore ) then
data[a:index(x+xv, y+1, z+zv )] = leaves_cid;
end
end
end
end
end