Make saplings only grow on dirt or grass, make jungle tree trunks only replace air
authorkwolekr <kwolekr@minetest.net>
Sat, 16 Mar 2013 23:37:27 +0000 (19:37 -0400)
committerkwolekr <kwolekr@minetest.net>
Sat, 16 Mar 2013 23:55:29 +0000 (19:55 -0400)
src/content_abm.cpp
src/treegen.cpp

index e50edddd7def9aaa8b86f48e8fc6272ff7840bf9..ccd9ca19ce326884d10f46b4ac45d4fd39ba514c 100644 (file)
@@ -94,7 +94,17 @@ public:
 class MakeTreesFromSaplingsABM : public ActiveBlockModifier
 {
 private:
+       content_t c_junglesapling;
+       content_t c_dirt;
+       content_t c_dirt_with_grass;
+       
 public:
+       MakeTreesFromSaplingsABM(ServerEnvironment *env, INodeDefManager *nodemgr) {
+               c_junglesapling   = nodemgr->getId("junglesapling");
+               c_dirt            = nodemgr->getId("mapgen_dirt");
+               c_dirt_with_grass = nodemgr->getId("mapgen_dirt_with_grass");
+       }
+
        virtual std::set<std::string> getTriggerContents()
        {
                std::set<std::string> s;
@@ -112,7 +122,12 @@ public:
                INodeDefManager *ndef = env->getGameDef()->ndef();
                ServerMap *map = &env->getServerMap();
                
-               bool is_jungle_tree = n.getContent() == ndef->getId("junglesapling");
+               MapNode n_below = map->getNodeNoEx(p - v3s16(0, 1, 0));
+               if (n_below.getContent() != c_dirt &&
+                       n_below.getContent() != c_dirt_with_grass)
+                       return;
+                       
+               bool is_jungle_tree = n.getContent() == c_junglesapling;
                
                actionstream <<"A " << (is_jungle_tree ? "jungle " : "")
                                << "sapling grows into a tree at "
@@ -187,7 +202,7 @@ void add_legacy_abms(ServerEnvironment *env, INodeDefManager *nodedef)
 {
        env->addActiveBlockModifier(new GrowGrassABM());
        env->addActiveBlockModifier(new RemoveGrassABM());
-       env->addActiveBlockModifier(new MakeTreesFromSaplingsABM());
+       env->addActiveBlockModifier(new MakeTreesFromSaplingsABM(env, nodedef));
        if (g_settings->getBool("liquid_finite"))
                env->addActiveBlockModifier(new LiquidFlowABM(env, nodedef));
 }
index 9df528a21fd01191017f8a09a93b4536d76d355c..808cf916a386ada660edd03dff69297445cea4a2 100644 (file)
@@ -528,19 +528,27 @@ void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
                        continue;
                v3s16 p1 = p0 + v3s16(x,0,z);
                v3s16 p2 = p0 + v3s16(x,-1,z);
-               if(vmanip.m_area.contains(p2)
-                               && vmanip.m_data[vmanip.m_area.index(p2)] == CONTENT_AIR)
-                       vmanip.m_data[vmanip.m_area.index(p2)] = treenode;
-               else if(vmanip.m_area.contains(p1))
-                       vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
+               u32 vi1 = vmanip.m_area.index(p1);
+               u32 vi2 = vmanip.m_area.index(p2);
+               
+               if (vmanip.m_area.contains(p2) &&
+                       vmanip.m_data[vi2].getContent() == CONTENT_AIR)
+                       vmanip.m_data[vi2] = treenode;
+               else if (vmanip.m_area.contains(p1) &&
+                               vmanip.m_data[vi1].getContent() == CONTENT_AIR)
+                       vmanip.m_data[vi1] = treenode;
        }
+       vmanip.m_data[vmanip.m_area.index(p0)] = treenode;
 
        s16 trunk_h = pr.range(8, 12);
        v3s16 p1 = p0;
-       for(s16 ii=0; ii<trunk_h; ii++)
+       for (s16 ii=0; ii<trunk_h; ii++)
        {
-               if(vmanip.m_area.contains(p1))
-                       vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
+               if (vmanip.m_area.contains(p1)) {
+                       u32 vi = vmanip.m_area.index(p1);
+                       if (vmanip.m_data[vi].getContent() == CONTENT_AIR)
+                               vmanip.m_data[vi] = treenode;
+               }
                p1.Y++;
        }
 
@@ -593,8 +601,8 @@ void make_jungletree(VoxelManipulator &vmanip, v3s16 p0,
                if(vmanip.m_area.contains(p) == false)
                        continue;
                u32 vi = vmanip.m_area.index(p);
-               if(vmanip.m_data[vi].getContent() != CONTENT_AIR
-                               && vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
+               if (vmanip.m_data[vi].getContent() != CONTENT_AIR &&
+                       vmanip.m_data[vi].getContent() != CONTENT_IGNORE)
                        continue;
                u32 i = leaves_a.index(x,y,z);
                if(leaves_d[i] == 1)