]> git.lizzy.rs Git - minetest.git/blobdiff - src/content_mapblock.cpp
Workaround for blocks having a huge amount of active objects; add log messages relate...
[minetest.git] / src / content_mapblock.cpp
index ab5cc1b54975f6d180d36a5d145505506a99e507..0c96c568f7b5d2cf1c84935efb798a3f1a37bec4 100644 (file)
@@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "main.h" // For g_settings and g_texturesource
 #include "mineral.h"
 #include "mapblock_mesh.h" // For MapBlock_LightColor()
+#include "settings.h"
 
 #ifndef SERVER
 // Create a cuboid.
@@ -128,10 +129,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
        /*
                Some settings
        */
-       bool new_style_water = g_settings.getBool("new_style_water");
-       bool new_style_leaves = g_settings.getBool("new_style_leaves");
-       //bool smooth_lighting = g_settings.getBool("smooth_lighting");
-       bool invisible_stone = g_settings.getBool("invisible_stone");
+       bool new_style_water = g_settings->getBool("new_style_water");
+       bool new_style_leaves = g_settings->getBool("new_style_leaves");
+       //bool smooth_lighting = g_settings->getBool("smooth_lighting");
+       bool invisible_stone = g_settings->getBool("invisible_stone");
        
        float node_liquid_level = 1.0;
        if(new_style_water)
@@ -188,6 +189,28 @@ 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);
+       
+       // Apple material
+       video::SMaterial material_apple;
+       material_apple.setFlag(video::EMF_LIGHTING, false);
+       material_apple.setFlag(video::EMF_BILINEAR_FILTER, false);
+       material_apple.setFlag(video::EMF_FOG_ENABLE, true);
+       material_apple.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+       AtlasPointer pa_apple = g_texturesource->getTexture(
+                       g_texturesource->getTextureId("apple.png"));
+       material_apple.setTexture(0, pa_apple.atlas);
+
+
+       // Sapling material
+       video::SMaterial material_sapling;
+       material_sapling.setFlag(video::EMF_LIGHTING, false);
+       material_sapling.setFlag(video::EMF_BILINEAR_FILTER, false);
+       material_sapling.setFlag(video::EMF_FOG_ENABLE, true);
+       material_sapling.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
+       AtlasPointer pa_sapling = g_texturesource->getTexture(
+                       g_texturesource->getTextureId("sapling.png"));
+       material_sapling.setTexture(0, pa_sapling.atlas);
+
 
        // junglegrass material
        video::SMaterial material_junglegrass;
@@ -373,7 +396,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        };
                        for(u32 i=0; i<9; i++)
                        {
-                               u8 content = CONTENT_AIR;
+                               content_t content = CONTENT_AIR;
                                float level = -0.5 * BS;
                                u8 flags = 0;
                                // Check neighbor
@@ -386,8 +409,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                        if(n2.getContent() == c_source)
                                                level = (-0.5+node_liquid_level) * BS;
                                        else if(n2.getContent() == c_flowing)
-                                               level = (-0.5 + ((float)n2.param2 + 0.5) / 8.0
-                                                               * node_liquid_level) * BS;
+                                               level = (-0.5 + ((float)(n2.param2&LIQUID_LEVEL_MASK)
+                                                               + 0.5) / 8.0 * node_liquid_level) * BS;
 
                                        // Check node above neighbor.
                                        // NOTE: This doesn't get executed if neighbor
@@ -404,9 +427,6 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                neighbor_flags.insert(neighbor_dirs[i], flags);
                        }
 
-                       //float liquid_level = (-0.5 + ((float)n.param2 + 0.5) / 8.0) * BS;
-                       //float liquid_level = neighbor_levels[v3s16(0,0,0)];
-
                        // Corner heights (average between four liquids)
                        f32 corner_levels[4];
                        
@@ -421,17 +441,27 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                v3s16 cornerdir = halfdirs[i];
                                float cornerlevel = 0;
                                u32 valid_count = 0;
+                               u32 air_count = 0;
                                for(u32 j=0; j<4; j++)
                                {
                                        v3s16 neighbordir = cornerdir - halfdirs[j];
-                                       u8 content = neighbor_contents[neighbordir];
-                                       // Special case for source nodes
-                                       if(content == c_source)
+                                       content_t content = neighbor_contents[neighbordir];
+                                       // If top is liquid, draw starting from top of node
+                                       if(neighbor_flags[neighbordir] &
+                                                       neighborflag_top_is_same_liquid)
+                                       {
+                                               cornerlevel = 0.5*BS;
+                                               valid_count = 1;
+                                               break;
+                                       }
+                                       // Source is always the same height
+                                       else if(content == c_source)
                                        {
                                                cornerlevel = (-0.5+node_liquid_level)*BS;
                                                valid_count = 1;
                                                break;
                                        }
+                                       // Flowing liquid has level information
                                        else if(content == c_flowing)
                                        {
                                                cornerlevel += neighbor_levels[neighbordir];
@@ -439,11 +469,12 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                        }
                                        else if(content == CONTENT_AIR)
                                        {
-                                               cornerlevel += -0.5*BS;
-                                               valid_count++;
+                                               air_count++;
                                        }
                                }
-                               if(valid_count > 0)
+                               if(air_count >= 2)
+                                       cornerlevel = -0.5*BS;
+                               else if(valid_count > 0)
                                        cornerlevel /= valid_count;
                                corner_levels[i] = cornerlevel;
                        }
@@ -476,17 +507,20 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                                neighbor_flags[dir] & neighborflag_top_is_same_liquid)
                                        continue;
 
-                               u8 neighbor_content = neighbor_contents[dir];
+                               content_t neighbor_content = neighbor_contents[dir];
                                
                                // Don't draw face if neighbor is not air or liquid
                                if(neighbor_content != CONTENT_AIR
-                                               && neighbor_content != c_source)
+                                               && content_liquid(neighbor_content) == false)
                                        continue;
                                
-                               bool neighbor_is_liquid = (neighbor_content == c_source);
+                               bool neighbor_is_same_liquid = (neighbor_content == c_source
+                                               || neighbor_content == c_flowing);
                                
-                               // Don't draw any faces if neighbor is liquid and top is liquid
-                               if(neighbor_is_liquid == true && top_is_same_liquid == false)
+                               // Don't draw any faces if neighbor same is liquid and top is
+                               // same liquid
+                               if(neighbor_is_same_liquid == true
+                                               && top_is_same_liquid == false)
                                        continue;
                                
                                video::S3DVertex vertices[4] =
@@ -527,7 +561,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                        If neighbor is liquid, lower border of face is corner
                                        liquid levels
                                */
-                               if(neighbor_is_liquid)
+                               if(neighbor_is_same_liquid)
                                {
                                        vertices[0].Pos.Y = corner_levels[side_corners[i][1]];
                                        vertices[1].Pos.Y = corner_levels[side_corners[i][0]];
@@ -552,6 +586,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                                                vertices[j].Pos.rotateXZBy(90);
                                        if(dir == v3s16(1,0,-0))
                                                vertices[j].Pos.rotateXZBy(-90);
+                                               
+                                       // Do this to not cause glitches when two liquids are
+                                       // side-by-side
+                                       if(neighbor_is_same_liquid == false){
+                                               vertices[j].Pos.X *= 0.98;
+                                               vertices[j].Pos.Z *= 0.98;
+                                       }
 
                                        vertices[j].Pos += intToFloat(p + blockpos_nodes, BS);
                                }
@@ -1185,6 +1226,105 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
                        // Add to mesh collector
                        collector.append(material_ladder, vertices, 4, indices, 6);
                }
+               else if(n.getContent() == CONTENT_APPLE)
+               {
+                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+                       video::SColor c = MapBlock_LightColor(255, l);
+
+                       for(u32 j=0; j<4; j++)
+                       {
+                               video::S3DVertex vertices[4] =
+                               {
+                                       video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c,
+                                               pa_apple.x0(), pa_apple.y1()),
+                                       video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c,
+                                               pa_apple.x1(), pa_apple.y1()),
+                                       video::S3DVertex(BS/2,BS/2,0, 0,0,0, c,
+                                               pa_apple.x1(), pa_apple.y0()),
+                                       video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c,
+                                               pa_apple.x0(), pa_apple.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 += intToFloat(p + blockpos_nodes, BS);
+                               }
+
+                               u16 indices[] = {0,1,2,2,3,0};
+                               // Add to mesh collector
+                               collector.append(material_apple, vertices, 4, indices, 6);
+                       }
+               }
+               else if(n.getContent() == CONTENT_SAPLING) {
+                       u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio)));
+                       video::SColor c = MapBlock_LightColor(255, l);
+
+                       for(u32 j=0; j<4; j++)
+                       {
+                               video::S3DVertex vertices[4] =
+                               {
+                                       video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c,
+                                               pa_sapling.x0(), pa_sapling.y1()),
+                                       video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c,
+                                               pa_sapling.x1(), pa_sapling.y1()),
+                                       video::S3DVertex(BS/2,BS/1,0, 0,0,0, c,
+                                               pa_sapling.x1(), pa_sapling.y0()),
+                                       video::S3DVertex(-BS/2,BS/1,0, 0,0,0, c,
+                                               pa_sapling.x0(), pa_sapling.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 += intToFloat(p + blockpos_nodes, BS);
+                               }
+
+                               u16 indices[] = {0,1,2,2,3,0};
+                               // Add to mesh collector
+                               collector.append(material_sapling, vertices, 4, indices, 6);
+                       }
+               }
        }
 }
 #endif