]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/mapblock.cpp
added sand to map generator
[dragonfireclient.git] / src / mapblock.cpp
index a7bc730ce076723ce69062fa39c7a6f0ef0210b5..da7d22ac56f4679a43f42cf8ba3b8513b6beed01 100644 (file)
@@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "mapblock.h"
 #include "map.h"
-// For g_materials
+// For g_settings and g_irrlicht
 #include "main.h"
 #include "light.h"
 #include <sstream>
@@ -600,7 +600,6 @@ void MapBlock::updateMesh(u32 daynight_ratio)
        v3f posRelative_f(getPosRelative().X, getPosRelative().Y,
                        getPosRelative().Z); // floating point conversion
        
-       
        /*
                Avoid interlocks by copying m_temp_mods
        */
@@ -610,6 +609,11 @@ void MapBlock::updateMesh(u32 daynight_ratio)
                m_temp_mods.copy(temp_mods);
        }
 
+       bool new_style_water = g_settings.getBool("new_style_water");
+       float node_water_level = 1.0;
+       if(new_style_water)
+               node_water_level = 0.8;
+       
        /*
                We are including the faces of the trailing edges of the block.
                This means that when something changes, the caller must
@@ -700,6 +704,9 @@ void MapBlock::updateMesh(u32 daynight_ratio)
                        const u16 indices[] = {0,1,2,2,3,0};
 
                        video::ITexture *texture = g_irrlicht->getTexture(f.tile.spec);
+                       if(texture == NULL)
+                               continue;
+
                        material.setTexture(0, texture);
                        if(f.tile.alpha != 255)
                                material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
@@ -817,6 +824,8 @@ void MapBlock::updateMesh(u32 daynight_ratio)
                        // Includes current node
                        core::map<v3s16, f32> neighbor_levels;
                        core::map<v3s16, u8> neighbor_contents;
+                       core::map<v3s16, u8> neighbor_flags;
+                       const u8 neighborflag_top_is_water = 0x01;
                        v3s16 neighbor_dirs[9] = {
                                v3s16(0,0,0),
                                v3s16(0,0,1),
@@ -832,21 +841,33 @@ void MapBlock::updateMesh(u32 daynight_ratio)
                        {
                                u8 content = CONTENT_AIR;
                                float level = -0.5 * BS;
+                               u8 flags = 0;
                                try{
+                                       // Check neighbor
                                        v3s16 p2 = p + neighbor_dirs[i];
                                        MapNode n2 = getNodeParent(p2);
 
                                        content = n2.d;
 
                                        if(n2.d == CONTENT_WATERSOURCE)
-                                               level = 0.5 * BS;
+                                               level = (-0.5+node_water_level) * BS;
                                        else if(n2.d == CONTENT_WATER)
-                                               level = (-0.5 + ((float)n2.param2 + 0.5) / 8.0) * BS;
+                                               level = (-0.5 + ((float)n2.param2 + 0.5) / 8.0
+                                                               * node_water_level) * BS;
+
+                                       // Check node above neighbor.
+                                       // NOTE: This doesn't get executed if neighbor
+                                       //       doesn't exist
+                                       p2.Y += 1;
+                                       n2 = getNodeParent(p2);
+                                       if(n2.d == CONTENT_WATERSOURCE || n2.d == CONTENT_WATER)
+                                               flags |= neighborflag_top_is_water;
                                }
                                catch(InvalidPositionException &e){}
                                
                                neighbor_levels.insert(neighbor_dirs[i], level);
                                neighbor_contents.insert(neighbor_dirs[i], content);
+                               neighbor_flags.insert(neighbor_dirs[i], flags);
                        }
 
                        //float water_level = (-0.5 + ((float)n.param2 + 0.5) / 8.0) * BS;
@@ -873,7 +894,7 @@ void MapBlock::updateMesh(u32 daynight_ratio)
                                        // Special case for source nodes
                                        if(content == CONTENT_WATERSOURCE)
                                        {
-                                               cornerlevel = 0.5*BS;
+                                               cornerlevel = (-0.5+node_water_level)*BS;
                                                valid_count = 1;
                                                break;
                                        }
@@ -913,20 +934,24 @@ void MapBlock::updateMesh(u32 daynight_ratio)
                        {
                                v3s16 dir = side_dirs[i];
 
-                               //float neighbor_level = neighbor_levels[dir];
-                               /*if(neighbor_level > -0.5*BS + 0.001)
-                                       continue;*/
-                               /*if(neighbor_level > water_level - 0.1*BS)
-                                       continue;*/
+                               /*
+                                       If our topside is water and neighbor's topside
+                                       is water, don't draw side face
+                               */
+                               if(top_is_water &&
+                                               neighbor_flags[dir] & neighborflag_top_is_water)
+                                       continue;
 
                                u8 neighbor_content = neighbor_contents[dir];
-
+                               
+                               // Don't draw face if neighbor is not air or water
                                if(neighbor_content != CONTENT_AIR
                                                && neighbor_content != CONTENT_WATER)
                                        continue;
                                
                                bool neighbor_is_water = (neighbor_content == CONTENT_WATER);
-
+                               
+                               // Don't draw any faces if neighbor is water and top is water
                                if(neighbor_is_water == true && top_is_water == false)
                                        continue;
                                
@@ -942,22 +967,37 @@ void MapBlock::updateMesh(u32 daynight_ratio)
                                        video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),
                                };
                                
+                               /*
+                                       If our topside is water, set upper border of face
+                                       at upper border of node
+                               */
                                if(top_is_water)
                                {
                                        vertices[2].Pos.Y = 0.5*BS;
                                        vertices[3].Pos.Y = 0.5*BS;
                                }
+                               /*
+                                       Otherwise upper position of face is corner levels
+                               */
                                else
                                {
                                        vertices[2].Pos.Y = corner_levels[side_corners[i][0]];
                                        vertices[3].Pos.Y = corner_levels[side_corners[i][1]];
                                }
-
+                               
+                               /*
+                                       If neighbor is water, lower border of face is corner
+                                       water levels
+                               */
                                if(neighbor_is_water)
                                {
                                        vertices[0].Pos.Y = corner_levels[side_corners[i][1]];
                                        vertices[1].Pos.Y = corner_levels[side_corners[i][0]];
                                }
+                               /*
+                                       If neighbor is not water, lower border of face is
+                                       lower border of node
+                               */
                                else
                                {
                                        vertices[0].Pos.Y = -0.5*BS;
@@ -1010,6 +1050,47 @@ void MapBlock::updateMesh(u32 daynight_ratio)
                                collector.append(material_w1, vertices, 4, indices, 6);
                        }
                }
+               /*
+                       Add water sources to mesh
+               */
+               else if(n.d == CONTENT_WATERSOURCE && new_style_water)
+               {
+                       //bool top_is_water = false;
+                       bool top_is_air = false;
+                       try{
+                               MapNode n = getNodeParent(v3s16(x,y+1,z));
+                               /*if(n.d == CONTENT_WATER || n.d == CONTENT_WATERSOURCE)
+                                       top_is_water = true;*/
+                               if(n.d == CONTENT_AIR)
+                                       top_is_air = true;
+                       }catch(InvalidPositionException &e){}
+                       
+                       /*if(top_is_water == true)
+                               continue;*/
+                       if(top_is_air == false)
+                               continue;
+
+                       u8 l = decode_light(n.getLightBlend(daynight_ratio));
+                       video::SColor c(WATER_ALPHA,l,l,l);
+                       
+                       video::S3DVertex vertices[4] =
+                       {
+                               video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, 0,1),
+                               video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, 1,1),
+                               video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, 1,0),
+                               video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, 0,0),
+                       };
+
+                       for(s32 i=0; i<4; i++)
+                       {
+                               vertices[i].Pos.Y += (-0.5+node_water_level)*BS;
+                               vertices[i].Pos += intToFloat(p + getPosRelative());
+                       }
+
+                       u16 indices[] = {0,1,2,2,3,0};
+                       // Add to mesh collector
+                       collector.append(material_w1, vertices, 4, indices, 6);
+               }
        }
 
        /*
@@ -1309,10 +1390,21 @@ void MapBlock::copyTo(VoxelManipulator &dst)
        v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
        VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
        
+       // Copy from data to VoxelManipulator
        dst.copyFrom(data, data_area, v3s16(0,0,0),
                        getPosRelative(), data_size);
 }
 
+void MapBlock::copyFrom(VoxelManipulator &dst)
+{
+       v3s16 data_size(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE);
+       VoxelArea data_area(v3s16(0,0,0), data_size - v3s16(1,1,1));
+       
+       // Copy from VoxelManipulator to data
+       dst.copyTo(data, data_area, v3s16(0,0,0),
+                       getPosRelative(), data_size);
+}
+
 void MapBlock::stepObjects(float dtime, bool server, u32 daynight_ratio)
 {
        /*
@@ -1662,6 +1754,23 @@ void MapBlock::deSerialize(std::istream &is, u8 version)
                        data[i].param2 = s[i+nodecount*2];
                }
        }
+       
+       /*
+               Translate nodes as specified in the translate_to fields of
+               node features
+       */
+       for(u32 i=0; i<MAP_BLOCKSIZE*MAP_BLOCKSIZE*MAP_BLOCKSIZE; i++)
+       {
+               MapNode &n = data[i];
+
+               MapNode *translate_to = content_features(n.d).translate_to;
+               if(translate_to)
+               {
+                       dstream<<"MapBlock: WARNING: Translating node "<<n.d<<" to "
+                                       <<translate_to->d<<std::endl;
+                       n = *translate_to;
+               }
+       }
 }