Add seed parameter for default and L-system trees
authorRealBadAngel <mk@realbadangel.pl>
Sun, 24 Feb 2013 01:26:25 +0000 (02:26 +0100)
committerRealBadAngel <mk@realbadangel.pl>
Sun, 24 Feb 2013 01:26:25 +0000 (02:26 +0100)
doc/lua_api.txt
src/content_abm.cpp
src/mapgen.cpp
src/scriptapi.cpp
src/treegen.cpp
src/treegen.h

index af70a1047672ffbb098ce4ac93f9a6a784f78818..005d7c010af462ac90a9dae5dd5af8a0e53f5ed7 100644 (file)
@@ -1093,6 +1093,7 @@ treedef={
   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
+  seed,          - num     random seed
   }
 
 Key for Special L-System Symbols used in Axioms
index ce1751117630d7b84488dde3dc93d84595fe17a2..0dcf862fc0d1c891fad909c1df5be008b7467cf5 100644 (file)
@@ -119,7 +119,7 @@ public:
                v3s16 tree_blockp = getNodeBlockPos(tree_p);
                vmanip.initialEmerge(tree_blockp - v3s16(1,1,1), tree_blockp + v3s16(1,1,1));
                bool is_apple_tree = myrand()%4 == 0;
-               treegen::make_tree(vmanip, tree_p, is_apple_tree, ndef);
+               treegen::make_tree(vmanip, tree_p, is_apple_tree, ndef, myrand());
                vmanip.blitBackAll(&modified_blocks);
 
                // update lighting
index b19073e9017d8c703a8f1780ce55db9245d57bb5..a2d920bbc0ebd5a5600a5a532a766bba180c34fe 100644 (file)
@@ -2251,6 +2251,7 @@ void make_block(BlockMakeData *data)
        */
        assert(central_area_size.X == central_area_size.Z);
        {
+               PseudoRandom ps (blockseed);
                // Divide area into parts
                s16 div = 8;
                s16 sidelen = central_area_size.X / div;
@@ -2278,8 +2279,8 @@ void make_block(BlockMakeData *data)
                        // Put trees in random places on part of division
                        for(u32 i=0; i<tree_count; i++)
                        {
-                               s16 x = myrand_range(p2d_min.X, p2d_max.X);
-                               s16 z = myrand_range(p2d_min.Y, p2d_max.Y);
+                               s16 x = ps.range(p2d_min.X, p2d_max.X);
+                               s16 z = ps.range(p2d_min.Y, p2d_max.Y);
                                s16 y = find_ground_level(vmanip, v2s16(x,z), ndef);
                                // Don't make a tree under water level
                                if(y < WATER_LEVEL)
@@ -2300,7 +2301,7 @@ void make_block(BlockMakeData *data)
                                }
                                p.Y++;
                                // Make a tree
-                               treegen::make_tree(vmanip, p, false, ndef);
+                               treegen::make_tree(vmanip, p, false, ndef, ps.next());
                        }
                }
        }
index 66654813e3c905642747d946c0fbc65fa8a3c08f..b7a7f6e4294aa4e2bef7ed6407083f34affd1ea9 100644 (file)
@@ -4254,6 +4254,7 @@ private:
                                tree_def.fruitnode=ndef->getId(fruit);
                                getintfield(L, 3, "fruit_chance",tree_def.fruit_chance);
                        }
+                       getintfield(L, 3, "seed", tree_def.seed);
                }
                else
                        return 0;
index 7530843d377f3e6ca40f57503768a4c318b56a7e..948716dcf21f9fa8932b2d8781e9d040ff98fc18 100644 (file)
@@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <stack>
 #include "util/numeric.h"
 #include "util/mathconstants.h"
-#include "noise.h"
 #include "map.h"
 #include "environment.h"
 #include "nodedef.h"
@@ -29,15 +28,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 namespace treegen
 {
-
 void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0,
-               bool is_apple_tree, INodeDefManager *ndef)
+               bool is_apple_tree, INodeDefManager *ndef,int seed)
 {
        MapNode treenode(ndef->getId("mapgen_tree"));
        MapNode leavesnode(ndef->getId("mapgen_leaves"));
        MapNode applenode(ndef->getId("mapgen_apple"));
 
-       s16 trunk_h = myrand_range(4, 5);
+       PseudoRandom ps(seed);
+       s16 trunk_h = ps.range(4, 5);
        v3s16 p1 = p0;
        for(s16 ii=0; ii<trunk_h; ii++)
        {
@@ -73,9 +72,9 @@ void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0,
                s16 d = 1;
 
                v3s16 p(
-                       myrand_range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X-d),
-                       myrand_range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y-d),
-                       myrand_range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z-d)
+                       ps.range(leaves_a.MinEdge.X, leaves_a.MaxEdge.X-d),
+                       ps.range(leaves_a.MinEdge.Y, leaves_a.MaxEdge.Y-d),
+                       ps.range(leaves_a.MinEdge.Z, leaves_a.MaxEdge.Z-d)
                );
 
                for(s16 z=0; z<=d; z++)
@@ -101,7 +100,7 @@ void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0,
                        continue;
                u32 i = leaves_a.index(x,y,z);
                if(leaves_d[i] == 1) {
-                       bool is_apple = myrand_range(0,99) < 10;
+                       bool is_apple = ps.range(0,99) < 10;
                        if(is_apple_tree && is_apple) {
                                vmanip.m_data[vi] = applenode;
                        } else {
@@ -150,6 +149,7 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd
 {
        MapNode dirtnode(ndef->getId("mapgen_dirt"));
 
+       PseudoRandom ps(tree_definition.seed+14002);
        // chance of inserting abcd rules
        double prop_a = 9;
        double prop_b = 8;
@@ -159,13 +159,13 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd
        //randomize tree growth level, minimum=2
        s16 iterations = tree_definition.iterations;
        if (tree_definition.iterations_random_level>0)
-               iterations -= myrand_range(0,tree_definition.iterations_random_level);
+               iterations -= ps.range(0,tree_definition.iterations_random_level);
        if (iterations<2)
                iterations=2;
 
        s16 MAX_ANGLE_OFFSET = 5;
        double angle_in_radians = (double)tree_definition.angle*M_PI/180;
-       double angleOffset_in_radians = (s16)(myrand_range(0,1)%MAX_ANGLE_OFFSET)*M_PI/180;
+       double angleOffset_in_radians = (s16)(ps.range(0,1)%MAX_ANGLE_OFFSET)*M_PI/180;
 
        //initialize rotation matrix, position and stacks for branches
        core::matrix4 rotation;
@@ -200,19 +200,19 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd
                                temp+=tree_definition.rules_d;
                                break;
                        case 'a':
-                               if (prop_a >= myrand_range(1,10))
+                               if (prop_a >= ps.range(1,10))
                                        temp+=tree_definition.rules_a;
                                break;
                        case 'b':
-                               if (prop_b >= myrand_range(1,10))
+                               if (prop_b >= ps.range(1,10))
                                        temp+=tree_definition.rules_b;
                                break;
                        case 'c':
-                               if (prop_c >= myrand_range(1,10))
+                               if (prop_c >= ps.range(1,10))
                                        temp+=tree_definition.rules_c;
                                break;
                        case 'd':
-                               if (prop_d >= myrand_range(1,10))
+                               if (prop_d >= ps.range(1,10))
                                        temp+=tree_definition.rules_d;
                                break;
                        default:
@@ -324,10 +324,10 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd
                                                for(z=-size; z<=size; z++)
                                                        if (abs(x) == size && abs(y) == size && abs(z) == size)
                                                        {
-                                                               tree_leaves_placement(vmanip,v3f(position.X+x+1,position.Y+y,position.Z+z),tree_definition);
-                                                               tree_leaves_placement(vmanip,v3f(position.X+x-1,position.Y+y,position.Z+z),tree_definition);
-                                                               tree_leaves_placement(vmanip,v3f(position.X+x,position.Y+y,position.Z+z+1),tree_definition);
-                                                               tree_leaves_placement(vmanip,v3f(position.X+x,position.Y+y,position.Z+z-1),tree_definition);
+                                                               tree_leaves_placement(vmanip,v3f(position.X+x+1,position.Y+y,position.Z+z),ps.next(), tree_definition);
+                                                               tree_leaves_placement(vmanip,v3f(position.X+x-1,position.Y+y,position.Z+z),ps.next(), tree_definition);
+                                                               tree_leaves_placement(vmanip,v3f(position.X+x,position.Y+y,position.Z+z+1),ps.next(), tree_definition);
+                                                               tree_leaves_placement(vmanip,v3f(position.X+x,position.Y+y,position.Z+z-1),ps.next(), tree_definition);
                                                        }
                        }
                        dir = v3f(1,0,0);
@@ -335,7 +335,7 @@ void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *nd
                        position+=dir;
                        break;
                case 'f':
-                       tree_single_leaves_placement(vmanip,v3f(position.X,position.Y,position.Z),tree_definition);
+                       tree_single_leaves_placement(vmanip,v3f(position.X,position.Y,position.Z),ps.next() ,tree_definition);
                        dir = v3f(1,0,0);
                        dir = transposeMatrix(rotation,dir);
                        position+=dir;
@@ -421,10 +421,10 @@ void tree_trunk_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
 }
 
 void tree_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
-               TreeDef &tree_definition)
+               PseudoRandom ps ,TreeDef &tree_definition)
 {
        MapNode leavesnode=tree_definition.leavesnode;
-       if (myrand_range(1,100) > 100-tree_definition.leaves2_chance)
+       if (ps.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)
@@ -435,20 +435,20 @@ void tree_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
                return; 
        if (tree_definition.fruit_chance>0)
        {
-               if (myrand_range(1,100) > 100-tree_definition.fruit_chance)
+               if (ps.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)] = leavesnode;
        }
-       else if (myrand_range(1,100) > 20)
+       else if (ps.range(1,100) > 20)
                vmanip.m_data[vmanip.m_area.index(p1)] = leavesnode;
 }
 
 void tree_single_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
-               TreeDef &tree_definition)
+               PseudoRandom ps, TreeDef &tree_definition)
 {
        MapNode leavesnode=tree_definition.leavesnode;
-       if (myrand_range(1,100) > 100-tree_definition.leaves2_chance)
+       if (ps.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)
index cb365f4bea5a9a6806b2147dbdd51c0ff5c47d9c..0068219dd763a63bb0054984ba1862a1357d00d0 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define TREEGEN_HEADER
 
 #include <matrix4.h>
+#include "noise.h"
 
 class ManualMapVoxelManipulator;
 class INodeDefManager;
@@ -47,11 +48,12 @@ std::string trunk_type;
 bool thin_branches;
 MapNode fruitnode;
 int fruit_chance;
+int seed;
 };
 
        // Add default tree
        void make_tree(ManualMapVoxelManipulator &vmanip, v3s16 p0,
-               bool is_apple_tree, INodeDefManager *ndef);
+               bool is_apple_tree, INodeDefManager *ndef,int seed);
 
        // Add L-Systems tree (used by engine)
        void make_ltree(ManualMapVoxelManipulator &vmanip, v3s16 p0, INodeDefManager *ndef,
@@ -66,9 +68,9 @@ int fruit_chance;
        void tree_trunk_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
                TreeDef &tree_definition);
        void tree_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
-               TreeDef &tree_definition);
+               PseudoRandom ps, TreeDef &tree_definition);
        void tree_single_leaves_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
-               TreeDef &tree_definition);
+               PseudoRandom ps, TreeDef &tree_definition);
        void tree_fruit_placement(ManualMapVoxelManipulator &vmanip, v3f p0,
                TreeDef &tree_definition);
        irr::core::matrix4 setRotationAxisRadians(irr::core::matrix4 M, double angle,v3f axis);