From 8993d9dd8321aad1243f4fb7fc55259c3747224f Mon Sep 17 00:00:00 2001
From: Perttu Ahola <celeron55@gmail.com>
Date: Sat, 23 Jul 2011 02:04:24 +0300
Subject: [PATCH] Jungle biome/whatever thing

---
 data/junglegrass.png     | Bin 0 -> 672 bytes
 data/jungletree.png      | Bin 0 -> 502 bytes
 data/jungletree_top.png  | Bin 0 -> 507 bytes
 src/content_mapblock.cpp |  62 +++++++++++++++
 src/content_mapnode.cpp  |  24 +++++-
 src/content_mapnode.h    |   2 +
 src/mapgen.cpp           | 168 ++++++++++++++++++++++++++++++++++++++-
 src/mapnode.h            |   3 +-
 8 files changed, 253 insertions(+), 6 deletions(-)
 create mode 100644 data/junglegrass.png
 create mode 100644 data/jungletree.png
 create mode 100644 data/jungletree_top.png

diff --git a/data/junglegrass.png b/data/junglegrass.png
new file mode 100644
index 0000000000000000000000000000000000000000..eea87c07c55ea290e364c45f0dbad538c19468c7
GIT binary patch
literal 672
zcmV;R0$=@!P)<h;3K|Lk000e1NJLTq000mG000;W1^@s6^PqhU00004b3#c}2nYxW
zd<bNS00009a7bBm000XU000XU0RWnu7ytkO8FWQhbVF}#ZDnqB07G(RVRU6=Aa`kW
zXdp*PO;A^X4i^9b0v$<2K~y-6ty8^<t56XBjtXf43&MgLEQAo;E{&~l8_6r!+%7M$
z58?}?+a|9NY!=emq%#D;BA5t)fM64doLgLGax|M;-Dy0G^YhL3%>e()ri+n`6JN%O
zFJHyPi7zRRd<H!n*F=>!n0&mwOwQ60#pWi8&7S=l{oJn30syMK!7CKS<|c+d4FIyV
z{AUsM9WHGdF74+A>TJWHIPv9AiE-jfV^|0PPRA=8*W}Js-hj|Op;F;lbAwS#7bEUE
zU5t8Y)ErH%I<|Cvw{-^q*sjhZh`e4i;wVmhDO4xf<l_xlTEcNnY**)A%ptpA7QFMQ
z#`<$FR0XWL!SD{*1w>qxH#i-ysCRcU3&8Oj08o+P7{7i`d*rrthj3|2b=fo`Y)B|=
z=5}=!)SYboxo1UK#w;xnL>_|3!}@bCthpiU-MuH>EO_s6!U&4ZO|*4~@2`T{CZY&3
zsWM%RWR*8eI#;8vV@pR6d3;y|-*HWxj#spGhq0yeU1(Wa@-5W6yJ+hUSz11kcgQXv
zl7q-&zBH=z{Z$}b+H!2^y#)H!ySoS?4~}axiE-jfEnM2taZLb^8yH(U#+HsMZ+fzl
zD(cwGa=5gm3X`OyqQr-~16f)=ZehDR3u3;lJ2<Y%@Q0SAB`apoEJGz|ZLK-vBzknG
zeW7@b2vn7zy-?4X;#3rjfI88lsAEi`$7TNA%sYYzT=);+Q-SS8mTnOM0000<MNUMn
GLSTYZt08&-

literal 0
HcmV?d00001

diff --git a/data/jungletree.png b/data/jungletree.png
new file mode 100644
index 0000000000000000000000000000000000000000..ccd20ac7403a35d9d288524afaf94e6e50939d26
GIT binary patch
literal 502
zcmV<S0SW$zP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000ie000i_0f#p>b^rhYm`OxIR5*=&ld(&~Kp4e;h7Mgy>0$zQ
z5R%CvLPaPPlnyQ`LcyiDS@bUuih^swt)n2gl`euH>Y!k8C={eZ5uFlnu#mWv(xsaY
z`du%L`lj!4-@W&~m%FL`^73ag5eML?cFTg3qFO0p*(Nua9R|Y@g1d)jx^AD&{Q*0B
zCsZp%4B0%Y-2%{c`&hO~quwH$NmIx<h=7i*jU@n#Le60@9I@b}0O;Hw(5SZnXtv$R
zq5bkQ0E6L(X50OCpj*??>wPGaWFk&Bla9EFS+=Q^eJ?=Pz21jv%4X8P*1$Lefc4$8
z(B|t~U)4`9@2d8_fYNq;Oi-;9@x6fmu(r7v$t0PG6Pr|@B$AnLE<3<D*ph9M&7?7W
zFW~U_;!owlaD?^K4BvqRH0muZ+YDzgiMiR7s+(<Bxe*coL!V3Tf{sGY3Avesp|k0S
zW@e@VuxwN1BE4O=uiO~&L7@LGA<<n*uVfO*;QZ<_;^;Ssvj~Aa5<#QhqO_e41$TYA
sqv{BO1eHw0)ttT;u(~oIQkQ%21znz`cM;!Vl>h($07*qoM6N<$f?HDLB>(^b

literal 0
HcmV?d00001

diff --git a/data/jungletree_top.png b/data/jungletree_top.png
new file mode 100644
index 0000000000000000000000000000000000000000..2a9b51373d939d19e3486f735761bf57c88614a9
GIT binary patch
literal 507
zcmV<X0R;YuP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00004b3#c}2nYxW
zd<bNS00009a7bBm000ie000i_0f#p>b^rhYok>JNR5*=wld(%eQ5431@8wWIge|(%
z;+q1KaLCDcK@ACo|H6}&rXWEQf*>%0f~J;7ZqXPBuc1IO2wEJZDSFM-Bw|6E4RWsc
zJ?)$BJ?Gr>efPWP8lLO)%jX`|ONYB!i^Ge11Su;@rIaV0h@nI3JlDa@?Nq5=I{b(7
z=`Ek{UuysP{zbR<ORIiB`P^dyIGT@6^Y;1?U<ZiLO|ib3#Jz5^vN+Fo=ZD6#4?uEh
zf$iKfkzyfBxA!}ieSI|vK&6ydYTAAWfZ3Tz4lnL8TJ?iIz|Hj&56u_aeutD5RShI2
zo=6O!?RPMR&CXb=NM{c#vNKj77m-Ed*$*V_jHSf}D$cGR0RpNF&vp9c)7udiy>a-E
zs01)lR<!@0)Nm7NB&d|~7{EvafMOx5t}zaF#v-1G4L#7Mg$>kMg;}Q4Bm{YLVb`Bb
zJkVhR9Pe!em>-%i0qNm`dQJ_}U9F`iQop<IzMxphs&&NK9eyS;2Eb-8x?vpeZLqnO
x1|Yq5f?3(mkzP9)DU2s#%8zkycB^=<!yk`y!N0*pn{ogE002ovPDHLkV1k;$-#h>S

literal 0
HcmV?d00001

diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp
index d8bf71dc0..730907222 100644
--- a/src/content_mapblock.cpp
+++ b/src/content_mapblock.cpp
@@ -198,6 +198,17 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
 	AtlasPointer pa_papyrus = g_texturesource->getTexture(
 			g_texturesource->getTextureId("papyrus.png"));
 	material_papyrus.setTexture(0, pa_papyrus.atlas);
+
+	// junglegrass material
+	video::SMaterial material_junglegrass;
+	material_junglegrass.setFlag(video::EMF_LIGHTING, false);
+	material_junglegrass.setFlag(video::EMF_BILINEAR_FILTER, false);
+	material_junglegrass.setFlag(video::EMF_FOG_ENABLE, true);
+	material_junglegrass.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+	AtlasPointer pa_junglegrass = g_texturesource->getTexture(
+			g_texturesource->getTextureId("junglegrass.png"));
+	material_junglegrass.setTexture(0, pa_junglegrass.atlas);
+
 	for(s16 z=0; z<MAP_BLOCKSIZE; z++)
 	for(s16 y=0; y<MAP_BLOCKSIZE; y++)
 	for(s16 x=0; x<MAP_BLOCKSIZE; x++)
@@ -966,6 +977,57 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
 				collector.append(material_papyrus, vertices, 4, indices, 6);
 			}
 		}
+		else if(n.d == CONTENT_JUNGLEGRASS)
+		{
+			u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+			video::SColor c(255,l,l,l);
+
+			for(u32 j=0; j<4; j++)
+			{
+				video::S3DVertex vertices[4] =
+				{
+					video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c,
+						pa_papyrus.x0(), pa_papyrus.y1()),
+					video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c,
+						pa_papyrus.x1(), pa_papyrus.y1()),
+					video::S3DVertex(BS/2,BS/1,0, 0,0,0, c,
+						pa_papyrus.x1(), pa_papyrus.y0()),
+					video::S3DVertex(-BS/2,BS/1,0, 0,0,0, c,
+						pa_papyrus.x0(), pa_papyrus.y0()),
+				};
+
+				if(j == 0)
+				{
+					for(u16 i=0; i<4; i++)
+						vertices[i].Pos.rotateXZBy(45);
+				}
+				else if(j == 1)
+				{
+					for(u16 i=0; i<4; i++)
+						vertices[i].Pos.rotateXZBy(-45);
+				}
+				else if(j == 2)
+				{
+					for(u16 i=0; i<4; i++)
+						vertices[i].Pos.rotateXZBy(135);
+				}
+				else if(j == 3)
+				{
+					for(u16 i=0; i<4; i++)
+						vertices[i].Pos.rotateXZBy(-135);
+				}
+
+				for(u16 i=0; i<4; i++)
+				{
+					vertices[i].Pos *= 1.3;
+					vertices[i].Pos += intToFloat(p + blockpos_nodes, BS);
+				}
+
+				u16 indices[] = {0,1,2,2,3,0};
+				// Add to mesh collector
+				collector.append(material_junglegrass, vertices, 4, indices, 6);
+			}
+		}
 		else if(n.d == CONTENT_RAIL)
 		{
 			u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio));
diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp
index 79e10fd61..be7f95adc 100644
--- a/src/content_mapnode.cpp
+++ b/src/content_mapnode.cpp
@@ -136,12 +136,34 @@ void content_mapnode_init()
 	f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
 	setWoodLikeDiggingProperties(f->digging_properties, 1.0);
 	
+	i = CONTENT_JUNGLETREE;
+	f = &content_features(i);
+	f->setAllTextures("jungletree.png");
+	f->setTexture(0, "jungletree_top.png");
+	f->setTexture(1, "jungletree_top.png");
+	f->param_type = CPT_MINERAL;
+	//f->is_ground_content = true;
+	f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
+	setWoodLikeDiggingProperties(f->digging_properties, 1.0);
+	
+	i = CONTENT_JUNGLEGRASS;
+	f = &content_features(i);
+	f->setInventoryTexture("junglegrass.png");
+	f->light_propagates = true;
+	f->param_type = CPT_LIGHT;
+	//f->is_ground_content = true;
+	f->air_equivalent = false; // grass grows underneath
+	f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
+	f->solidness = 0; // drawn separately, makes no faces
+	f->walkable = false;
+	setWoodLikeDiggingProperties(f->digging_properties, 0.10);
+
 	i = CONTENT_LEAVES;
 	f = &content_features(i);
 	f->light_propagates = true;
 	//f->param_type = CPT_MINERAL;
 	f->param_type = CPT_LIGHT;
-	f->is_ground_content = true;
+	//f->is_ground_content = true;
 	if(new_style_leaves)
 	{
 		f->solidness = 0; // drawn separately, makes no faces
diff --git a/src/content_mapnode.h b/src/content_mapnode.h
index e53624c21..f7d3269ea 100644
--- a/src/content_mapnode.h
+++ b/src/content_mapnode.h
@@ -57,6 +57,8 @@ void content_mapnode_init();
 #define CONTENT_PAPYRUS 28
 #define CONTENT_BOOKSHELF 29
 #define CONTENT_RAIL 30
+#define CONTENT_JUNGLETREE 31
+#define CONTENT_JUNGLEGRASS 32
 
 #endif
 
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index 8dda93c96..0bb6560a8 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -152,6 +152,92 @@ static void make_tree(VoxelManipulator &vmanip, v3s16 p0)
 	}
 }
 
+static void make_jungletree(VoxelManipulator &vmanip, v3s16 p0)
+{
+	MapNode treenode(CONTENT_JUNGLETREE);
+	MapNode leavesnode(CONTENT_LEAVES);
+
+	for(s16 x=-1; x<=1; x++)
+	for(s16 z=-1; z<=1; z++)
+	{
+		if(myrand_range(0, 2) == 0)
+			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;
+	}
+
+	s16 trunk_h = myrand_range(8, 12);
+	v3s16 p1 = p0;
+	for(s16 ii=0; ii<trunk_h; ii++)
+	{
+		if(vmanip.m_area.contains(p1))
+			vmanip.m_data[vmanip.m_area.index(p1)] = treenode;
+		p1.Y++;
+	}
+
+	// p1 is now the last piece of the trunk
+	p1.Y -= 1;
+
+	VoxelArea leaves_a(v3s16(-3,-2,-3), v3s16(3,2,3));
+	//SharedPtr<u8> leaves_d(new u8[leaves_a.getVolume()]);
+	Buffer<u8> leaves_d(leaves_a.getVolume());
+	for(s32 i=0; i<leaves_a.getVolume(); i++)
+		leaves_d[i] = 0;
+
+	// Force leaves at near the end of the trunk
+	{
+		s16 d = 1;
+		for(s16 z=-d; z<=d; z++)
+		for(s16 y=-d; y<=d; y++)
+		for(s16 x=-d; x<=d; x++)
+		{
+			leaves_d[leaves_a.index(v3s16(x,y,z))] = 1;
+		}
+	}
+
+	// Add leaves randomly
+	for(u32 iii=0; iii<30; iii++)
+	{
+		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)
+		);
+
+		for(s16 z=0; z<=d; z++)
+		for(s16 y=0; y<=d; y++)
+		for(s16 x=0; x<=d; x++)
+		{
+			leaves_d[leaves_a.index(p+v3s16(x,y,z))] = 1;
+		}
+	}
+
+	// Blit leaves to vmanip
+	for(s16 z=leaves_a.MinEdge.Z; z<=leaves_a.MaxEdge.Z; z++)
+	for(s16 y=leaves_a.MinEdge.Y; y<=leaves_a.MaxEdge.Y; y++)
+	for(s16 x=leaves_a.MinEdge.X; x<=leaves_a.MaxEdge.X; x++)
+	{
+		v3s16 p(x,y,z);
+		p += p1;
+		if(vmanip.m_area.contains(p) == false)
+			continue;
+		u32 vi = vmanip.m_area.index(p);
+		if(vmanip.m_data[vi].d != CONTENT_AIR
+				&& vmanip.m_data[vi].d != CONTENT_IGNORE)
+			continue;
+		u32 i = leaves_a.index(x,y,z);
+		if(leaves_d[i] == 1)
+			vmanip.m_data[vi] = leavesnode;
+	}
+}
+
 void make_papyrus(VoxelManipulator &vmanip, v3s16 p0)
 {
 	MapNode papyrusnode(CONTENT_PAPYRUS);
@@ -1004,13 +1090,26 @@ double tree_amount_2d(u64 seed, v2s16 p)
 	double noise = noise2d_perlin(
 			0.5+(float)p.X/125, 0.5+(float)p.Y/125,
 			seed+2, 4, 0.66);
-	double zeroval = -0.35;
+	double zeroval = -0.39;
 	if(noise < zeroval)
 		return 0;
 	else
 		return 0.04 * (noise-zeroval) / (1.0-zeroval);
 }
 
+double surface_humidity_2d(u64 seed, v2s16 p)
+{
+	double noise = noise2d_perlin(
+			0.5+(float)p.X/500, 0.5+(float)p.Y/500,
+			seed+72384, 4, 0.66);
+	noise = (noise + 1.0)/2.0;
+	if(noise < 0.0)
+		noise = 0.0;
+	if(noise > 1.0)
+		noise = 1.0;
+	return noise;
+}
+
 #if 0
 double randomstone_amount_2d(u64 seed, v2s16 p)
 {
@@ -1909,11 +2008,19 @@ void make_block(BlockMakeData *data)
 		}
 
 		/*
-			Add trees
+			Calculate some stuff
 		*/
 		
+		float surface_humidity = surface_humidity_2d(data->seed, p2d_center);
+		bool is_jungle = surface_humidity > 0.75;
 		// Amount of trees
 		u32 tree_count = block_area_nodes * tree_amount_2d(data->seed, p2d_center);
+		if(is_jungle)
+			tree_count *= 5;
+
+		/*
+			Add trees
+		*/
 		PseudoRandom treerandom(blockseed);
 		// Put trees in random places on part of division
 		for(u32 i=0; i<tree_count; i++)
@@ -1938,7 +2045,8 @@ void make_block(BlockMakeData *data)
 			{
 				u32 i = data->vmanip->m_area.index(p);
 				MapNode *n = &data->vmanip->m_data[i];
-				if(n->d != CONTENT_AIR && n->d != CONTENT_WATERSOURCE && n->d != CONTENT_IGNORE)
+				//if(n->d != CONTENT_AIR && n->d != CONTENT_WATERSOURCE && n->d != CONTENT_IGNORE)
+				if(content_features(n->d).is_ground_content)
 				{
 					found = true;
 					break;
@@ -1965,7 +2073,11 @@ void make_block(BlockMakeData *data)
 				else if((n->d == CONTENT_MUD || n->d == CONTENT_GRASS) && y > WATER_LEVEL + 2)
 				{
 					p.Y++;
-					make_tree(vmanip, p);
+					//if(surface_humidity_2d(data->seed, v2s16(x, y)) < 0.5)
+					if(is_jungle == false)
+						make_tree(vmanip, p);
+					else
+						make_jungletree(vmanip, p);
 				}
 				// Cactii grow only on sand, on land
 				else if(n->d == CONTENT_SAND && y > WATER_LEVEL + 2)
@@ -1976,6 +2088,54 @@ void make_block(BlockMakeData *data)
 			}
 		}
 
+		/*
+			Add jungle grass
+		*/
+		if(is_jungle)
+		{
+			PseudoRandom grassrandom(blockseed);
+			for(u32 i=0; i<surface_humidity*5*tree_count; i++)
+			{
+				s16 x = grassrandom.range(node_min.X, node_max.X);
+				s16 z = grassrandom.range(node_min.Z, node_max.Z);
+				s16 y = find_ground_level_from_noise(data->seed, v2s16(x,z), 4);
+				if(y < WATER_LEVEL)
+					continue;
+				if(y < node_min.Y || y > node_max.Y)
+					continue;
+				/*
+					Find exact ground level
+				*/
+				v3s16 p(x,y+6,z);
+				bool found = false;
+				for(; p.Y >= y-6; p.Y--)
+				{
+					u32 i = data->vmanip->m_area.index(p);
+					MapNode *n = &data->vmanip->m_data[i];
+					if(content_features(n->d).is_ground_content
+							|| n->d == CONTENT_JUNGLETREE)
+					{
+						found = true;
+						break;
+					}
+				}
+				// If not found, handle next one
+				if(found == false)
+					continue;
+				p.Y++;
+				if(vmanip.m_area.contains(p) == false)
+					continue;
+				if(vmanip.m_data[vmanip.m_area.index(p)].d != CONTENT_AIR)
+					continue;
+				/*p.Y--;
+				if(vmanip.m_area.contains(p))
+					vmanip.m_data[vmanip.m_area.index(p)] = CONTENT_MUD;
+				p.Y++;*/
+				if(vmanip.m_area.contains(p))
+					vmanip.m_data[vmanip.m_area.index(p)] = CONTENT_JUNGLEGRASS;
+			}
+		}
+
 #if 0
 		/*
 			Add some kind of random stones
diff --git a/src/mapnode.h b/src/mapnode.h
index 33128049a..ebca3755a 100644
--- a/src/mapnode.h
+++ b/src/mapnode.h
@@ -119,7 +119,8 @@ struct ContentFeatures
 	TileSpec tiles[6];
 	
 	video::ITexture *inventory_texture;
-
+	
+	// True for all ground-like things like stone and mud, false for eg. trees
 	bool is_ground_content;
 	bool light_propagates;
 	bool sunlight_propagates;
-- 
GitLab