From c5e583e059bc31c0dc57496b23f5c97db1f5a3e3 Mon Sep 17 00:00:00 2001
From: Ciaran Gultnieks <ciaran@ciarang.com>
Date: Tue, 24 May 2011 17:52:04 +0100
Subject: [PATCH] Added fences (but still needs an icon or something to display
 in inventory)

---
 src/mapblock.cpp  | 132 ++++++++++++++++++++++++++++++++++++++++++++++
 src/mapnode.cpp   |   7 +++
 src/mapnode.h     |   1 +
 src/materials.cpp |   1 +
 src/server.cpp    |  18 +++++++
 5 files changed, 159 insertions(+)

diff --git a/src/mapblock.cpp b/src/mapblock.cpp
index d62928ce2..c448ef236 100644
--- a/src/mapblock.cpp
+++ b/src/mapblock.cpp
@@ -729,6 +729,72 @@ class MeshCollector
 	core::array<PreMeshBuffer> m_prebuffers;
 };
 
+void makeCuboid(video::SMaterial &material, MeshCollector *collector,
+	AtlasPointer* pa, video::SColor &c,
+	v3f &pos, f32 rx, f32 ry, f32 rz)
+{
+	video::S3DVertex v[4] =
+	{
+		video::S3DVertex(0,0,0, 0,0,0, c,
+			pa->x0(), pa->y1()),
+		video::S3DVertex(0,0,0, 0,0,0, c,
+			pa->x1(), pa->y1()),
+		video::S3DVertex(0,0,0, 0,0,0, c,
+			pa->x1(), pa->y0()),
+		video::S3DVertex(0,0,0, 0,0,0, c,
+			pa->x0(), pa->y0())
+	};
+
+	for(int i=0;i<6;i++)
+	{
+		switch(i)
+		{
+			case 0:
+				v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
+				v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
+				v[2].Pos.X= rx; v[2].Pos.Y= ry; v[2].Pos.Z= rz;
+				v[3].Pos.X= rx; v[3].Pos.Y= ry, v[3].Pos.Z=-rz;
+				break;
+			case 1:
+				v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
+				v[1].Pos.X= rx; v[1].Pos.Y= ry; v[1].Pos.Z=-rz;
+				v[2].Pos.X= rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
+				v[3].Pos.X=-rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
+				break;
+			case 2:
+				v[0].Pos.X= rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz;
+				v[1].Pos.X= rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
+				v[2].Pos.X= rx; v[2].Pos.Y=-ry; v[2].Pos.Z= rz;
+				v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
+				break;
+			case 3:
+				v[0].Pos.X= rx; v[0].Pos.Y= ry; v[0].Pos.Z= rz;
+				v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz;
+				v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z= rz;
+				v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z= rz;
+				break;
+			case 4:
+				v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z= rz;
+				v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z=-rz;
+				v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
+				v[3].Pos.X=-rx; v[3].Pos.Y=-ry, v[3].Pos.Z= rz;
+				break;
+			case 5:
+				v[0].Pos.X= rx; v[0].Pos.Y=-ry; v[0].Pos.Z= rz;
+				v[1].Pos.X=-rx; v[1].Pos.Y=-ry; v[1].Pos.Z= rz;
+				v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz;
+				v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz;
+				break;
+		}
+		for(u16 i=0; i<4; i++)
+			v[i].Pos += pos;
+		u16 indices[] = {0,1,2,2,3,0};
+		collector->append(material, v, 4, indices, 6);
+
+	}
+
+}
+
 scene::SMesh* makeMapBlockMesh(MeshMakeData *data)
 {
 	// 4-21ms for MAP_BLOCKSIZE=16
@@ -911,6 +977,15 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data)
 			g_texturesource->getTextureId("glass.png"));
 	material_glass.setTexture(0, pa_glass.atlas);
 
+	// Wood material
+	video::SMaterial material_wood;
+	material_wood.setFlag(video::EMF_LIGHTING, false);
+	material_wood.setFlag(video::EMF_BILINEAR_FILTER, false);
+	material_wood.setFlag(video::EMF_FOG_ENABLE, true);
+	material_wood.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+	AtlasPointer pa_wood = g_texturesource->getTexture(
+			g_texturesource->getTextureId("wood.png"));
+	material_wood.setTexture(0, pa_wood.atlas);
 
 	for(s16 z=0; z<MAP_BLOCKSIZE; z++)
 	for(s16 y=0; y<MAP_BLOCKSIZE; y++)
@@ -1480,6 +1555,63 @@ scene::SMesh* makeMapBlockMesh(MeshMakeData *data)
 				collector.append(material_glass, vertices, 4, indices, 6);
 			}
 		}
+		/*
+			Add fence
+		*/
+		else if(n.d == CONTENT_FENCE)
+		{
+			u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+			video::SColor c(255,l,l,l);
+
+			const f32 post_rad=(f32)BS/10;
+			const f32 bar_rad=(f32)BS/20;
+			const f32 bar_len=(f32)(BS/2)-post_rad;
+
+			// The post - always present
+			v3f pos = intToFloat(p+blockpos_nodes, BS);
+			makeCuboid(material_wood, &collector,
+				&pa_wood, c, pos,
+				post_rad,BS/2,post_rad);
+
+			// Now a section of fence, +X, if there's a post there
+			v3s16 p2 = p;
+			p2.X++;
+			MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2);
+			if(n2.d == CONTENT_FENCE)
+			{
+				pos = intToFloat(p+blockpos_nodes, BS);
+				pos.X += BS/2;
+				pos.Y += BS/4;
+				makeCuboid(material_wood, &collector,
+					&pa_wood, c, pos,
+					bar_len,bar_rad,bar_rad);
+
+				pos.Y -= BS/2;
+				makeCuboid(material_wood, &collector,
+					&pa_wood, c, pos,
+					bar_len,bar_rad,bar_rad);
+			}
+
+			// Now a section of fence, +Z, if there's a post there
+			p2 = p;
+			p2.Z++;
+			n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2);
+			if(n2.d == CONTENT_FENCE)
+			{
+				pos = intToFloat(p+blockpos_nodes, BS);
+				pos.Z += BS/2;
+				pos.Y += BS/4;
+				makeCuboid(material_wood, &collector,
+					&pa_wood, c, pos,
+					bar_rad,bar_rad,bar_len);
+				pos.Y -= BS/2;
+				makeCuboid(material_wood, &collector,
+					&pa_wood, c, pos,
+					bar_rad,bar_rad,bar_len);
+
+			}
+
+		}
 
 
 
diff --git a/src/mapnode.cpp b/src/mapnode.cpp
index 00ebef840..199a5c656 100644
--- a/src/mapnode.cpp
+++ b/src/mapnode.cpp
@@ -216,6 +216,13 @@ void init_mapnode()
 	f->solidness = 0; // drawn separately, makes no faces
 	f->setInventoryTextureCube("glass.png", "glass.png", "glass.png");
 
+	i = CONTENT_FENCE;
+	f = &g_content_features[i];
+	f->light_propagates = true;
+	f->param_type = CPT_LIGHT;
+	f->is_ground_content = true;
+	f->dug_item = std::string("MaterialItem ")+itos(i)+" 1";
+	f->solidness = 0; // drawn separately, makes no faces
 
 	// Deprecated
 	i = CONTENT_COALSTONE;
diff --git a/src/mapnode.h b/src/mapnode.h
index 5a1770230..50b257ba2 100644
--- a/src/mapnode.h
+++ b/src/mapnode.h
@@ -100,6 +100,7 @@ void init_content_inventory_texture_paths();
 #define CONTENT_COBBLE 18
 #define CONTENT_STEEL 19
 #define CONTENT_GLASS 20
+#define CONTENT_FENCE 21
 
 /*
 	Content feature list
diff --git a/src/materials.cpp b/src/materials.cpp
index e5f0c3b9e..841f1d655 100644
--- a/src/materials.cpp
+++ b/src/materials.cpp
@@ -73,6 +73,7 @@ void initializeMaterialProperties()
 	setWoodLikeDiggingProperties(CONTENT_TREE, 1.0);
 	setWoodLikeDiggingProperties(CONTENT_LEAVES, 0.15);
 	setWoodLikeDiggingProperties(CONTENT_GLASS, 0.15);
+	setWoodLikeDiggingProperties(CONTENT_FENCE, 0.75);
 	setWoodLikeDiggingProperties(CONTENT_WOOD, 0.75);
 	setWoodLikeDiggingProperties(CONTENT_CHEST, 1.0);
 
diff --git a/src/server.cpp b/src/server.cpp
index 6a4fe3c02..75b47e498 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -3670,6 +3670,23 @@ void Server::UpdateCrafting(u16 peer_id)
 				}
 			}
 
+			// Fence
+			if(!found)
+			{
+				ItemSpec specs[9];
+				specs[4] = ItemSpec(ITEM_CRAFT, "Stick");
+				specs[5] = ItemSpec(ITEM_CRAFT, "Stick");
+				specs[6] = ItemSpec(ITEM_CRAFT, "Stick");
+				specs[7] = ItemSpec(ITEM_CRAFT, "Stick");
+				specs[8] = ItemSpec(ITEM_CRAFT, "Stick");
+				specs[9] = ItemSpec(ITEM_CRAFT, "Stick");
+				if(checkItemCombination(items, specs))
+				{
+					rlist->addItem(new MaterialItem(CONTENT_FENCE, 2));
+					found = true;
+				}
+			}
+
 			// Sign
 			if(!found)
 			{
@@ -4046,6 +4063,7 @@ void setCreativeInventory(Player *player)
 		CONTENT_TREE,
 		CONTENT_LEAVES,
 		CONTENT_GLASS,
+		CONTENT_FENCE,
 		CONTENT_MESE,
 		CONTENT_WATERSOURCE,
 		CONTENT_CLOUD,
-- 
GitLab