From a48a0e77eb48a0afe8b2d66f3f5ea75e39b9d504 Mon Sep 17 00:00:00 2001
From: Perttu Ahola <celeron55@gmail.com>
Date: Tue, 15 Nov 2011 15:32:09 +0200
Subject: [PATCH] Prepare more for node definition serialization

---
 src/content_mapblock.cpp | 25 +++++++++------
 src/content_mapnode.cpp  | 67 +++++++++++++++-------------------------
 src/nodedef.cpp          | 43 +++++++++++++++++---------
 src/nodedef.h            | 41 +++++++++++++-----------
 4 files changed, 91 insertions(+), 85 deletions(-)

diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp
index 7ce4f2df4..e0a9b60f9 100644
--- a/src/content_mapblock.cpp
+++ b/src/content_mapblock.cpp
@@ -366,15 +366,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
 		*/
 		else if(nodedef->get(n).liquid_type == LIQUID_FLOWING)
 		{
-			assert(nodedef->get(n).special_material);
+			assert(nodedef->get(n).special_materials[0]);
+			assert(nodedef->get(n).special_materials[1]);
+			assert(nodedef->get(n).special_aps[0]);
+
 			video::SMaterial &liquid_material =
-					*nodedef->get(n).special_material;
+					*nodedef->get(n).special_materials[0];
 			video::SMaterial &liquid_material_bfculled =
-					*nodedef->get(n).special_material2;
-
-			assert(nodedef->get(n).special_atlas);
+					*nodedef->get(n).special_materials[1];
 			AtlasPointer &pa_liquid1 =
-					*nodedef->get(n).special_atlas;
+					*nodedef->get(n).special_aps[0];
 
 			bool top_is_same_liquid = false;
 			MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
@@ -661,12 +662,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
 		else if(nodedef->get(n).liquid_type == LIQUID_SOURCE
 				&& new_style_water)
 		{
-			assert(nodedef->get(n).special_material);
+			assert(nodedef->get(n).special_materials[0]);
+			//assert(nodedef->get(n).special_materials[1]);
+			assert(nodedef->get(n).special_aps[0]);
+
 			video::SMaterial &liquid_material =
-					*nodedef->get(n).special_material;
-			assert(nodedef->get(n).special_atlas);
+					*nodedef->get(n).special_materials[0];
+			/*video::SMaterial &liquid_material_bfculled =
+					*nodedef->get(n).special_materials[1];*/
 			AtlasPointer &pa_liquid1 =
-					*nodedef->get(n).special_atlas;
+					*nodedef->get(n).special_aps[0];
 
 			bool top_is_air = false;
 			MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z));
diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp
index 8a521badc..8bcfe933b 100644
--- a/src/content_mapnode.cpp
+++ b/src/content_mapnode.cpp
@@ -467,13 +467,18 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr
 	f->liquid_alternative_flowing = CONTENT_WATER;
 	f->liquid_alternative_source = CONTENT_WATERSOURCE;
 	f->liquid_viscosity = WATER_VISC;
-#ifndef SERVER
 	if(!opaque_water)
 		f->alpha = WATER_ALPHA;
 	f->post_effect_color = video::SColor(64, 100, 100, 200);
+	// Flowing water material
+	f->mspec_special[0].tname = "water.png";
+	f->mspec_special[0].backface_culling = false;
+	f->mspec_special[1].tname = "water.png";
+	f->mspec_special[1].backface_culling = true;
+
+/*#ifndef SERVER
 	if(f->special_material == NULL && tsrc)
 	{
-		// Flowing water material
 		f->special_material = new video::SMaterial;
 		f->special_material->setFlag(video::EMF_LIGHTING, false);
 		f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
@@ -492,7 +497,7 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr
 		
 		f->special_atlas = pa_water1;
 	}
-#endif
+#endif*/
 	
 	i = CONTENT_WATERSOURCE;
 	f = nodemgr->getModifiable(i);
@@ -519,13 +524,15 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr
 	f->liquid_alternative_flowing = CONTENT_WATER;
 	f->liquid_alternative_source = CONTENT_WATERSOURCE;
 	f->liquid_viscosity = WATER_VISC;
-#ifndef SERVER
 	if(!opaque_water)
 		f->alpha = WATER_ALPHA;
 	f->post_effect_color = video::SColor(64, 100, 100, 200);
+	// New-style water source material (mostly unused)
+	f->mspec_special[0].tname = "water.png";
+	f->mspec_special[0].backface_culling = false;
+/*#ifndef SERVER
 	if(f->special_material == NULL && tsrc)
 	{
-		// New-style water source material (mostly unused)
 		f->special_material = new video::SMaterial;
 		f->special_material->setFlag(video::EMF_LIGHTING, false);
 		f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
@@ -537,7 +544,7 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr
 		f->special_material->setTexture(0, pa_water1->atlas);
 		f->special_atlas = pa_water1;
 	}
-#endif
+#endif*/
 	
 	i = CONTENT_LAVA;
 	f = nodemgr->getModifiable(i);
@@ -557,31 +564,17 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr
 	f->liquid_alternative_source = CONTENT_LAVASOURCE;
 	f->liquid_viscosity = LAVA_VISC;
 	f->damage_per_second = 4*2;
-#ifndef SERVER
 	f->post_effect_color = video::SColor(192, 255, 64, 0);
+	// Flowing lava material
+	f->mspec_special[0].tname = "lava.png";
+	f->mspec_special[0].backface_culling = false;
+	f->mspec_special[1].tname = "lava.png";
+	f->mspec_special[1].backface_culling = true;
+/*#ifndef SERVER
 	if(f->special_material == NULL && tsrc)
 	{
-		// Flowing lava material
-		f->special_material = new video::SMaterial;
-		f->special_material->setFlag(video::EMF_LIGHTING, false);
-		f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
-		f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
-		f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
-		f->special_material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
-
-		AtlasPointer *pa_lava1 = new AtlasPointer(
-			tsrc->getTexture(
-				tsrc->getTextureId("lava.png")));
-		f->special_material->setTexture(0, pa_lava1->atlas);
-
-		// Flowing lava material, backface culled
-		f->special_material2 = new video::SMaterial;
-		*f->special_material2 = *f->special_material;
-		f->special_material2->setFlag(video::EMF_BACK_FACE_CULLING, true);
-
-		f->special_atlas = pa_lava1;
 	}
-#endif
+#endif*/
 	
 	i = CONTENT_LAVASOURCE;
 	f = nodemgr->getModifiable(i);
@@ -609,25 +602,15 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr
 	f->liquid_alternative_source = CONTENT_LAVASOURCE;
 	f->liquid_viscosity = LAVA_VISC;
 	f->damage_per_second = 4*2;
-#ifndef SERVER
 	f->post_effect_color = video::SColor(192, 255, 64, 0);
+	// New-style lava source material (mostly unused)
+	f->mspec_special[0].tname = "lava.png";
+	f->mspec_special[0].backface_culling = false;
+/*#ifndef SERVER
 	if(f->special_material == NULL && tsrc)
 	{
-		// New-style lava source material (mostly unused)
-		f->special_material = new video::SMaterial;
-		f->special_material->setFlag(video::EMF_LIGHTING, false);
-		f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false);
-		f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false);
-		f->special_material->setFlag(video::EMF_FOG_ENABLE, true);
-		f->special_material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
-		AtlasPointer *pa_lava1 = new AtlasPointer(
-			tsrc->getTexture(
-				tsrc->getTextureId("lava.png")));
-		f->special_material->setTexture(0, pa_lava1->atlas);
-
-		f->special_atlas = pa_lava1;
 	}
-#endif
+#endif*/
 	
 	i = CONTENT_TORCH;
 	f = nodemgr->getModifiable(i);
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index 84b5f1d3d..6fa410cc2 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -30,8 +30,10 @@ ContentFeatures::~ContentFeatures()
 {
 	delete initial_metadata;
 #ifndef SERVER
-	delete special_material;
-	delete special_atlas;
+	for(u16 j=0; j<CF_SPECIAL_COUNT; j++){
+		delete special_materials[j];
+		delete special_aps[j];
+	}
 #endif
 }
 
@@ -198,19 +200,30 @@ class CNodeDefManager: public IWritableNodeDefManager
 				else
 					f->tiles[j].material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING;
 			}
-			// Special texture
-			if(f->tname_special != ""){
-				if(!f->special_atlas)
-					f->special_atlas = new AtlasPointer(
-							tsrc->getTexture(f->tname_special));
-				else
-					*(f->special_atlas) =
-							tsrc->getTexture(f->tname_special);
-				// Special material textures
-				if(f->special_material)
-					f->special_material->setTexture(0, f->special_atlas->atlas);
-				if(f->special_material2)
-					f->special_material2->setTexture(0, f->special_atlas->atlas);
+			// Special textures
+			for(u16 j=0; j<CF_SPECIAL_COUNT; j++){
+				// Remove all stuff
+				if(f->special_aps[j]){
+					delete f->special_aps[j];
+					f->special_aps[j] = NULL;
+				}
+				if(f->special_materials[j]){
+					delete f->special_materials[j];
+					f->special_materials[j] = NULL;
+				}
+				// Skip if should not exist
+				if(f->mspec_special[j].tname == "")
+					continue;
+				// Create all stuff
+				f->special_aps[j] = new AtlasPointer(
+						tsrc->getTexture(f->mspec_special[j].tname));
+				f->special_materials[j] = new video::SMaterial;
+				f->special_materials[j]->setFlag(video::EMF_LIGHTING, false);
+				f->special_materials[j]->setFlag(video::EMF_BACK_FACE_CULLING,
+						f->mspec_special[j].backface_culling);
+				f->special_materials[j]->setFlag(video::EMF_BILINEAR_FILTER, false);
+				f->special_materials[j]->setFlag(video::EMF_FOG_ENABLE, true);
+				f->special_materials[j]->setTexture(0, f->special_aps[j]->atlas);
 			}
 		}
 #endif
diff --git a/src/nodedef.h b/src/nodedef.h
index 5e4e3378c..f5662967b 100644
--- a/src/nodedef.h
+++ b/src/nodedef.h
@@ -100,6 +100,19 @@ struct NodeBox
 struct MapNode;
 class NodeMetadata;
 
+struct MaterialSpec
+{
+	std::string tname;
+	bool backface_culling;
+	
+	MaterialSpec(const std::string &tname_="", bool backface_culling_=true):
+		tname(tname_),
+		backface_culling(backface_culling_)
+	{}
+};
+
+#define CF_SPECIAL_COUNT 2
+
 struct ContentFeatures
 {
 #ifndef SERVER
@@ -114,15 +127,14 @@ struct ContentFeatures
 
 	// Special material/texture
 	// - Currently used for flowing liquids
-	video::SMaterial *special_material;
-	video::SMaterial *special_material2;
-	AtlasPointer *special_atlas;
+	video::SMaterial *special_materials[CF_SPECIAL_COUNT];
+	AtlasPointer *special_aps[CF_SPECIAL_COUNT];
 #endif
 	
-	// Texture names
+	// Visual definition
 	std::string tname_tiles[6];
 	std::string tname_inventory;
-	std::string tname_special;
+	MaterialSpec mspec_special[CF_SPECIAL_COUNT];
 	u8 alpha;
 	bool backface_culling;
 
@@ -202,14 +214,16 @@ struct ContentFeatures
 		inventory_texture = NULL;
 		
 		post_effect_color = video::SColor(0, 0, 0, 0);
-		special_material = NULL;
-		special_material2 = NULL;
-		special_atlas = NULL;
+		for(u16 j=0; j<CF_SPECIAL_COUNT; j++){
+			special_materials[j] = NULL;
+			special_aps[j] = NULL;
+		}
 #endif
 		for(u32 i=0; i<6; i++)
 			tname_tiles[i] = "";
+		for(u16 j=0; j<CF_SPECIAL_COUNT; j++)
+			mspec_special[j] = MaterialSpec();
 		tname_inventory = "";
-		tname_special = "";
 		alpha = 255;
 		backface_culling = true;
 		used_texturenames.clear();
@@ -265,15 +279,6 @@ struct ContentFeatures
 	void setInventoryTextureCube(std::string top,
 			std::string left, std::string right);
 
-#if 0
-#ifndef SERVER
-	void setTile(u16 i, const TileSpec &tile)
-	{ tiles[i] = tile; }
-	void setAllTiles(const TileSpec &tile)
-	{ for(u16 i=0; i<6; i++) setTile(i, tile); }
-#endif
-#endif
-
 	/*
 		Some handy methods
 	*/
-- 
GitLab