aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/lua_api.txt101
-rw-r--r--src/scriptapi.cpp21
-rw-r--r--src/treegen.cpp46
-rw-r--r--src/treegen.h7
4 files changed, 108 insertions, 67 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 34738974a..b0c1b41a3 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -1073,57 +1073,62 @@ methods:
^ clear all objects in the environments
- spawn_tree (pos, {treedef})
^ spawns L-System tree at given pos with definition in treedef table
- treedef={
- axiom, - string initial tree axiom
- rules_a, - string rules set A
- rules_b, - string rules set B
- rules_c, - string rules set C
- rules_d, - string rules set D
- trunk, - string trunk node name
- leaves, - string leaves node name
- angle, - num angle in deg
- iterations, - num max # of iterations, usually 2 -5
- random_level, - num factor to lower nr of iterations, usually 0 - 3
- thin_trunks, - boolean true -> use thin trunks
- fruit_tree, - boolean true -> is a fruit tree
- fruit - string fruit node name
+treedef={
+ axiom, - string initial tree axiom
+ rules_a, - string rules set A
+ rules_b, - string rules set B
+ rules_c, - string rules set C
+ rules_d, - string rules set D
+ trunk, - string trunk node name
+ leaves, - string leaves node name
+ leaves2, - string secondary leaves node name
+ leaves2_chance,- num chance (0-100) to replace leaves with leaves2
+ angle, - num angle in deg
+ iterations, - num max # of iterations, usually 2 -5
+ random_level, - num factor to lower nr of iterations, usually 0 - 3
+ trunk_type, - string single/double/crossed) type of trunk: 1 node, 2x2 nodes or 3x3 in cross shape
+ thin_branches, - boolean true -> use thin (1 node) branches
+ fruit, - string fruit node name
+ fruit_chance, - num chance (0-100) to replace leaves with fruit node
}
- Key for Special L-System Symbols used in Axioms
- G - move forward one unit with the pin down
- F - move forward one unit with the pin up
- A - replace with rules set A
- B - replace with rules set B
- C - replace with rules set C
- D - replace with rules set D
- a - replace with rules set A, chance 90%
- b - replace with rules set B, chance 80%
- c - replace with rules set C, chance 70%
- d - replace with rules set D, chance 60%
- + - yaw the turtle right by angle parameter
- - - yaw the turtle left by angle parameter
- & - pitch the turtle down by angle parameter
- ^ - pitch the turtle up by angle parameter
- / - roll the turtle to the right by angle parameter
- * - roll the turtle to the left by angle parameter
- [ - save in stack current state info
- ] - recover from stack state info
-
- Example usage: spawn small apple tree
- apple_tree={
- axiom="FFFFFAFFBF",
- rules_a="[&&&FFFFF&&FFFF][&&&++++FFFFF&&FFFF][&&&----FFFFF&&FFFF]",
- rules_b="[&&&++FFFFF&&FFFF][&&&--FFFFF&&FFFF][&&&------FFFFF&&FFFF]",
- trunk="default:tree",
- leaves="default:leaves",
- angle=30,
- iterations=2,
- random_level=0,
- thin_trunks=true,
- fruit_tree=true,
- fruit="default:apple"
+Key for Special L-System Symbols used in Axioms
+ G - move forward one unit with the pen up
+ F - move forward one unit with the pen down drawing trunks and branches
+ f - move forward one unit with the pen down drawing leaves
+ A - replace with rules set A
+ B - replace with rules set B
+ C - replace with rules set C
+ D - replace with rules set D
+ a - replace with rules set A, chance 90%
+ b - replace with rules set B, chance 80%
+ c - replace with rules set C, chance 70%
+ d - replace with rules set D, chance 60%
+ + - yaw the turtle right by angle parameter
+ - - yaw the turtle left by angle parameter
+ & - pitch the turtle down by angle parameter
+ ^ - pitch the turtle up by angle parameter
+ / - roll the turtle to the right by angle parameter
+ * - roll the turtle to the left by angle parameter
+ [ - save in stack current state info
+ ] - recover from stack state info
+
+Example usage: spawn small apple tree
+apple_tree={
+ axiom="FFFFFAFFBF",
+ rules_a="[&&&FFFFF&&FFFF][&&&++++FFFFF&&FFFF][&&&----FFFFF&&FFFF]",
+ rules_b="[&&&++FFFFF&&FFFF][&&&--FFFFF&&FFFF][&&&------FFFFF&&FFFF]",
+ trunk="default:tree",
+ leaves="default:leaves",
+ angle=30,
+ iterations=2,
+ random_level=0,
+ trunk_type="single",
+ thin_branches=true,
+ fruit_chance=10,
+ fruit="default:apple"
}
- minetest.env:spawn_tree(pos,apple_tree)
+minetest.env:spawn_tree(pos,apple_tree)
Deprecated:
- add_rat(pos): Add C++ rat object (no-op)
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index 04f741ad3..60e5b55f4 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -4034,21 +4034,30 @@ private:
getstringfield(L, 3, "axiom", tree_def.initial_axiom);
getstringfield(L, 3, "rules_a", tree_def.rules_a);
getstringfield(L, 3, "rules_b", tree_def.rules_b);
- getstringfield(L, 3, "rules_c", tree_def.rules_a);
- getstringfield(L, 3, "rules_d", tree_def.rules_b);
+ getstringfield(L, 3, "rules_c", tree_def.rules_c);
+ getstringfield(L, 3, "rules_d", tree_def.rules_d);
getstringfield(L, 3, "trunk", trunk);
tree_def.trunknode=ndef->getId(trunk);
getstringfield(L, 3, "leaves", leaves);
tree_def.leavesnode=ndef->getId(leaves);
+ tree_def.leaves2_chance=0;
+ getstringfield(L, 3, "leaves2", leaves);
+ if (leaves !="")
+ {
+ tree_def.leaves2node=ndef->getId(leaves);
+ getintfield(L, 3, "leaves2_chance", tree_def.leaves2_chance);
+ }
getintfield(L, 3, "angle", tree_def.angle);
getintfield(L, 3, "iterations", tree_def.iterations);
getintfield(L, 3, "random_level", tree_def.iterations_random_level);
- getboolfield(L, 3, "thin_trunks", tree_def.thin_trunks);
- getboolfield(L, 3, "fruit_tree", tree_def.fruit_tree);
- if (tree_def.fruit_tree)
+ getstringfield(L, 3, "trunk_type", tree_def.trunk_type);
+ getboolfield(L, 3, "thin_branches", tree_def.thin_branches);
+ tree_def.fruit_chance=0;
+ getstringfield(L, 3, "fruit", fruit);
+ if (fruit != "")
{
- getstringfield(L, 3, "fruit", fruit);
tree_def.fruitnode=ndef->getId(fruit);
+ getintfield(L, 3, "fruit_chance",tree_def.fruit_chance);
}
}
else
diff --git a/src/treegen.cpp b/src/treegen.cpp
index 54cee0fef..49f0666bc 100644
--- a/src/treegen.cpp
+++ b/src/treegen.cpp
@@ -118,7 +118,7 @@ void spawn_ltree (ServerEnvironment *env, v3s16 p0, INodeDefManager *ndef, TreeD
core::map<v3s16, MapBlock*> modified_blocks;
ManualMapVoxelManipulator vmanip(map);
v3s16 tree_blockp = getNodeBlockPos(p0);
- vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,1,1));
+ vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,2,1));
make_ltree (vmanip, p0, ndef, tree_definition);
vmanip.blitBackAll(&modified_blocks);
@@ -221,7 +221,13 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd
}
//make sure tree is not floating in the air
- if (tree_definition.thin_trunks == false)
+ if (tree_definition.trunk_type == "double")
+ {
+ make_tree_node_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y-1,p0.Z+position.Z),dirtnode);
+ make_tree_node_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y-1,p0.Z+position.Z+1),dirtnode);
+ make_tree_node_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y-1,p0.Z+position.Z+1),dirtnode);
+ }
+ if (tree_definition.trunk_type == "crossed")
{
make_tree_node_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y-1,p0.Z+position.Z),dirtnode);
make_tree_node_placement(vmanip,v3f(p0.X+position.X-1,p0.Y+position.Y-1,p0.Z+position.Z),dirtnode);
@@ -233,8 +239,9 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd
Key for Special L-System Symbols used in Axioms
- G - move forward one unit with the pin down
- F - move forward one unit with the pin up
+ G - move forward one unit with the pen up
+ F - move forward one unit with the pen down drawing trunks and branches
+ f - move forward one unit with the pen down drawing leaves
A - replace with rules set A
B - replace with rules set B
C - replace with rules set C
@@ -264,13 +271,21 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd
switch (axiom_char)
{
case 'G':
- dir = v3f(-1,0,0);
+ dir = v3f(1,0,0);
dir = transposeMatrix(rotation,dir);
position+=dir;
break;
case 'F':
make_tree_trunk_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y,p0.Z+position.Z),tree_definition);
- if (tree_definition.thin_trunks == false)
+ if ((stack_orientation.empty() && tree_definition.trunk_type == "double") ||
+ (!stack_orientation.empty() && tree_definition.trunk_type == "double" && !tree_definition.thin_branches))
+ {
+ make_tree_trunk_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y,p0.Z+position.Z),tree_definition);
+ make_tree_trunk_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y,p0.Z+position.Z+1),tree_definition);
+ make_tree_trunk_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y,p0.Z+position.Z+1),tree_definition);
+ }
+ if ((stack_orientation.empty() && tree_definition.trunk_type == "crossed") ||
+ (!stack_orientation.empty() && tree_definition.trunk_type == "crossed" && !tree_definition.thin_branches))
{
make_tree_trunk_placement(vmanip,v3f(p0.X+position.X+1,p0.Y+position.Y,p0.Z+position.Z),tree_definition);
make_tree_trunk_placement(vmanip,v3f(p0.X+position.X-1,p0.Y+position.Y,p0.Z+position.Z),tree_definition);
@@ -295,6 +310,12 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd
dir = transposeMatrix(rotation,dir);
position+=dir;
break;
+ case 'f':
+ make_tree_leaves_placement(vmanip,v3f(p0.X+position.X,p0.Y+position.Y,p0.Z+position.Z),tree_definition);
+ dir = v3f(1,0,0);
+ dir = transposeMatrix(rotation,dir);
+ position+=dir;
+ break;
// turtle commands
case '[':
stack_orientation.push(rotation);
@@ -371,6 +392,9 @@ void make_tree_trunk_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
void make_tree_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
TreeDef &tree_definition)
{
+ MapNode leavesnode=tree_definition.leavesnode;
+ if (myrand_range(1,100) > 100-tree_definition.leaves2_chance)
+ leavesnode=tree_definition.leaves2node;
v3s16 p1 = v3s16(myround(p0.X),myround(p0.Y),myround(p0.Z));
if(vmanip.m_area.contains(p1) == false)
return;
@@ -378,15 +402,15 @@ void make_tree_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
if(vmanip.m_data[vi].getContent() != CONTENT_AIR
&& vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
return;
- if (tree_definition.fruit_tree)
+ if (tree_definition.fruit_chance>0)
{
- if (myrand_range(1,100) > 90+tree_definition.iterations)
+ if (myrand_range(1,100) > 100-tree_definition.fruit_chance)
vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.fruitnode;
else
- vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.leavesnode;
+ vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode;
}
else if (myrand_range(1,100) > 20)
- vmanip.m_data[vmanip.m_area.index(p1)] = tree_definition.leavesnode;
+ vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode;
}
irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle, v3f axis)
@@ -517,4 +541,4 @@ static void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
}
#endif
-}; // namespace treegen \ No newline at end of file
+}; // namespace treegen
diff --git a/src/treegen.h b/src/treegen.h
index 62a220ee2..1435d6bb2 100644
--- a/src/treegen.h
+++ b/src/treegen.h
@@ -38,12 +38,15 @@ std::string rules_c;
std::string rules_d;
MapNode trunknode;
MapNode leavesnode;
+MapNode leaves2node;
+int leaves2_chance;
int angle;
int iterations;
int iterations_random_level;
-bool thin_trunks;
-bool fruit_tree;
+std::string trunk_type;
+bool thin_branches;
MapNode fruitnode;
+int fruit_chance;
};
// Add default tree