diff options
author | Perttu Ahola <celeron55@gmail.com> | 2011-11-15 19:58:36 +0200 |
---|---|---|
committer | Perttu Ahola <celeron55@gmail.com> | 2011-11-29 19:13:44 +0200 |
commit | eed727c61b51f46f6d172c56ecd26a3b1752d449 (patch) | |
tree | 0c6efe4379ace6c20f76267cc40ba01a69ef9ecc | |
parent | 89e7bacd991060fe6cdada6bf8112f9f20c3e310 (diff) | |
download | minetest-eed727c61b51f46f6d172c56ecd26a3b1752d449.tar.gz minetest-eed727c61b51f46f6d172c56ecd26a3b1752d449.tar.bz2 minetest-eed727c61b51f46f6d172c56ecd26a3b1752d449.zip |
Completely generalized mesh generation; ContentFeatures serialization
-rw-r--r-- | minetest.conf.example | 2 | ||||
-rw-r--r-- | src/common_irrlicht.h | 1 | ||||
-rw-r--r-- | src/content_mapblock.cpp | 890 | ||||
-rw-r--r-- | src/content_mapnode.cpp | 135 | ||||
-rw-r--r-- | src/content_mapnode.h | 3 | ||||
-rw-r--r-- | src/defaultsettings.cpp | 1 | ||||
-rw-r--r-- | src/game.cpp | 2 | ||||
-rw-r--r-- | src/irrlichttypes.h | 1 | ||||
-rw-r--r-- | src/mapnode.cpp | 2 | ||||
-rw-r--r-- | src/mapnode.h | 2 | ||||
-rw-r--r-- | src/materials.cpp | 42 | ||||
-rw-r--r-- | src/materials.h | 6 | ||||
-rw-r--r-- | src/nodedef.cpp | 315 | ||||
-rw-r--r-- | src/nodedef.h | 134 | ||||
-rw-r--r-- | src/server.cpp | 2 | ||||
-rw-r--r-- | src/test.cpp | 2 | ||||
-rw-r--r-- | src/tile.cpp | 7 | ||||
-rw-r--r-- | src/utility.h | 13 |
18 files changed, 767 insertions, 793 deletions
diff --git a/minetest.conf.example b/minetest.conf.example index 30adc5e60..e0c43d728 100644 --- a/minetest.conf.example +++ b/minetest.conf.example @@ -100,8 +100,6 @@ #farmesh_distance = 40 # Enable/disable clouds #enable_clouds = true -# Don't draw stone (for testing) -#invisible_stone = false # Path for screenshots #screenshot_path = . # Amount of view bobbing (0 = no view bobbing, 1.0 = normal, 2.0 = double) diff --git a/src/common_irrlicht.h b/src/common_irrlicht.h index 379c2d15a..0a2ed0be1 100644 --- a/src/common_irrlicht.h +++ b/src/common_irrlicht.h @@ -26,7 +26,6 @@ video::SColor(255,30,30,30));d->endScene();} #include "irrlichttypes.h" #ifndef SERVER -#include <SColor.h> #include <IMesh.h> #include <IImage.h> #include <IrrlichtDevice.h> diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index 368e6c611..3950c83c3 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -18,7 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "content_mapblock.h" -#include "content_mapnode.h" + #include "main.h" // For g_settings #include "mineral.h" #include "mapblock_mesh.h" // For MapBlock_LightColor() @@ -125,7 +125,6 @@ void makeCuboid(video::SMaterial &material, MeshCollector *collector, void mapblock_mesh_generate_special(MeshMakeData *data, MeshCollector &collector, IGameDef *gamedef) { - ITextureSource *tsrc = gamedef->tsrc(); INodeDefManager *nodedef = gamedef->ndef(); // 0ms @@ -135,9 +134,6 @@ 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"); float node_liquid_level = 1.0; if(new_style_water) @@ -145,86 +141,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data, v3s16 blockpos_nodes = data->m_blockpos*MAP_BLOCKSIZE; - // New-style leaves material - video::SMaterial material_leaves1; - material_leaves1.setFlag(video::EMF_LIGHTING, false); - material_leaves1.setFlag(video::EMF_BILINEAR_FILTER, false); - material_leaves1.setFlag(video::EMF_FOG_ENABLE, true); - material_leaves1.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - AtlasPointer pa_leaves1 = tsrc->getTexture( - tsrc->getTextureId("leaves.png")); - material_leaves1.setTexture(0, pa_leaves1.atlas); - - // Glass material - video::SMaterial material_glass; - material_glass.setFlag(video::EMF_LIGHTING, false); - material_glass.setFlag(video::EMF_BILINEAR_FILTER, false); - material_glass.setFlag(video::EMF_FOG_ENABLE, true); - material_glass.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - AtlasPointer pa_glass = tsrc->getTexture( - tsrc->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 = tsrc->getTexture( - tsrc->getTextureId("wood.png")); - material_wood.setTexture(0, pa_wood.atlas); - - // General ground material for special output + /*// General ground material for special output // Texture is modified just before usage video::SMaterial material_general; material_general.setFlag(video::EMF_LIGHTING, false); material_general.setFlag(video::EMF_BILINEAR_FILTER, false); material_general.setFlag(video::EMF_FOG_ENABLE, true); - material_general.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - - - // Papyrus material - video::SMaterial material_papyrus; - material_papyrus.setFlag(video::EMF_LIGHTING, false); - material_papyrus.setFlag(video::EMF_BILINEAR_FILTER, false); - material_papyrus.setFlag(video::EMF_FOG_ENABLE, true); - material_papyrus.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - AtlasPointer pa_papyrus = tsrc->getTexture( - tsrc->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 = tsrc->getTexture( - tsrc->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 = tsrc->getTexture( - tsrc->getTextureId("sapling.png")); - material_sapling.setTexture(0, pa_sapling.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 = tsrc->getTexture( - tsrc->getTextureId("junglegrass.png")); - material_junglegrass.setTexture(0, pa_junglegrass.atlas); + material_general.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;*/ for(s16 z=0; z<MAP_BLOCKSIZE; z++) for(s16 y=0; y<MAP_BLOCKSIZE; y++) @@ -233,143 +156,74 @@ void mapblock_mesh_generate_special(MeshMakeData *data, v3s16 p(x,y,z); MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes+p); + const ContentFeatures &f = nodedef->get(n); // Only solidness=0 stuff is drawn here - if(nodedef->get(n).solidness != 0) + if(f.solidness != 0) continue; - - /* - Add torches to mesh - */ - if(n.getContent() == CONTENT_TORCH) + + switch(f.drawtype){ + default: + infostream<<"Got "<<f.drawtype<<std::endl; + assert(0); + break; + case NDT_AIRLIKE: + break; + case NDT_LIQUID: { - v3s16 dir = unpackDir(n.param2); - - const char *texturename = "torch.png"; - if(dir == v3s16(0,-1,0)){ - texturename = "torch_on_floor.png"; - } else if(dir == v3s16(0,1,0)){ - texturename = "torch_on_ceiling.png"; - // For backwards compatibility - } else if(dir == v3s16(0,0,0)){ - texturename = "torch_on_floor.png"; - } else { - texturename = "torch.png"; - } - - AtlasPointer ap = tsrc->getTexture(texturename); - - // Set material - video::SMaterial material; - material.setFlag(video::EMF_LIGHTING, false); - material.setFlag(video::EMF_BACK_FACE_CULLING, false); - material.setFlag(video::EMF_BILINEAR_FILTER, false); - material.setFlag(video::EMF_FOG_ENABLE, true); - //material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; - material.MaterialType - = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - material.setTexture(0, ap.atlas); - - video::SColor c(255,255,255,255); - - // Wall at X+ of node - video::S3DVertex vertices[4] = - { - video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, - ap.x0(), ap.y1()), - video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, - ap.x1(), ap.y1()), - video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, - ap.x1(), ap.y0()), - video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, - ap.x0(), ap.y0()), - }; - - for(s32 i=0; i<4; i++) - { - if(dir == v3s16(1,0,0)) - vertices[i].Pos.rotateXZBy(0); - if(dir == v3s16(-1,0,0)) - vertices[i].Pos.rotateXZBy(180); - if(dir == v3s16(0,0,1)) - vertices[i].Pos.rotateXZBy(90); - if(dir == v3s16(0,0,-1)) - vertices[i].Pos.rotateXZBy(-90); - if(dir == v3s16(0,-1,0)) - vertices[i].Pos.rotateXZBy(45); - if(dir == v3s16(0,1,0)) - vertices[i].Pos.rotateXZBy(-45); - - vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); - } + /* + Add water sources to mesh if using new style + */ + assert(nodedef->get(n).special_materials[0]); + //assert(nodedef->get(n).special_materials[1]); + assert(nodedef->get(n).special_aps[0]); - u16 indices[] = {0,1,2,2,3,0}; - // Add to mesh collector - collector.append(material, vertices, 4, indices, 6); - } - /* - Signs on walls - */ - else if(n.getContent() == CONTENT_SIGN_WALL) - { - AtlasPointer ap = tsrc->getTexture("sign_wall.png"); + video::SMaterial &liquid_material = + *nodedef->get(n).special_materials[0]; + /*video::SMaterial &liquid_material_bfculled = + *nodedef->get(n).special_materials[1];*/ + AtlasPointer &pa_liquid1 = + *nodedef->get(n).special_aps[0]; - // Set material - video::SMaterial material; - material.setFlag(video::EMF_LIGHTING, false); - material.setFlag(video::EMF_BACK_FACE_CULLING, false); - material.setFlag(video::EMF_BILINEAR_FILTER, false); - material.setFlag(video::EMF_FOG_ENABLE, true); - material.MaterialType - = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - material.setTexture(0, ap.atlas); + bool top_is_air = false; + MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); + if(n.getContent() == CONTENT_AIR) + top_is_air = true; + + if(top_is_air == false) + continue; u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef)); - video::SColor c = MapBlock_LightColor(255, l); - - float d = (float)BS/16; - // Wall at X+ of node + video::SColor c = MapBlock_LightColor( + nodedef->get(n).alpha, l); + video::S3DVertex vertices[4] = { - video::S3DVertex(BS/2-d,-BS/2,-BS/2, 0,0,0, c, - ap.x0(), ap.y1()), - video::S3DVertex(BS/2-d,-BS/2,BS/2, 0,0,0, c, - ap.x1(), ap.y1()), - video::S3DVertex(BS/2-d,BS/2,BS/2, 0,0,0, c, - ap.x1(), ap.y0()), - video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c, - ap.x0(), ap.y0()), + video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, + pa_liquid1.x0(), pa_liquid1.y1()), + video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, + pa_liquid1.x1(), pa_liquid1.y1()), + video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, + pa_liquid1.x1(), pa_liquid1.y0()), + video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, + pa_liquid1.x0(), pa_liquid1.y0()), }; - v3s16 dir = unpackDir(n.param2); - for(s32 i=0; i<4; i++) { - if(dir == v3s16(1,0,0)) - vertices[i].Pos.rotateXZBy(0); - if(dir == v3s16(-1,0,0)) - vertices[i].Pos.rotateXZBy(180); - if(dir == v3s16(0,0,1)) - vertices[i].Pos.rotateXZBy(90); - if(dir == v3s16(0,0,-1)) - vertices[i].Pos.rotateXZBy(-90); - if(dir == v3s16(0,-1,0)) - vertices[i].Pos.rotateXYBy(-90); - if(dir == v3s16(0,1,0)) - vertices[i].Pos.rotateXYBy(90); - + vertices[i].Pos.Y += (-0.5+node_liquid_level)*BS; vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); } u16 indices[] = {0,1,2,2,3,0}; // Add to mesh collector - collector.append(material, vertices, 4, indices, 6); - } - /* - Add flowing liquid to mesh - */ - else if(nodedef->get(n).liquid_type == LIQUID_FLOWING) + collector.append(liquid_material, vertices, 4, indices, 6); + break;} + case NDT_FLOWINGLIQUID: { + /* + Add flowing liquid to mesh + */ assert(nodedef->get(n).special_materials[0]); assert(nodedef->get(n).special_materials[1]); assert(nodedef->get(n).special_aps[0]); @@ -659,64 +513,17 @@ void mapblock_mesh_generate_special(MeshMakeData *data, // Add to mesh collector collector.append(liquid_material, vertices, 4, indices, 6); } - } - /* - Add water sources to mesh if using new style - */ - else if(nodedef->get(n).liquid_type == LIQUID_SOURCE - && new_style_water) + break;} + case NDT_GLASSLIKE: { - assert(nodedef->get(n).special_materials[0]); - //assert(nodedef->get(n).special_materials[1]); - assert(nodedef->get(n).special_aps[0]); + video::SMaterial material_glass; + material_glass.setFlag(video::EMF_LIGHTING, false); + material_glass.setFlag(video::EMF_BILINEAR_FILTER, false); + material_glass.setFlag(video::EMF_FOG_ENABLE, true); + material_glass.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + AtlasPointer pa_glass = f.tiles[0].texture; + material_glass.setTexture(0, pa_glass.atlas); - video::SMaterial &liquid_material = - *nodedef->get(n).special_materials[0]; - /*video::SMaterial &liquid_material_bfculled = - *nodedef->get(n).special_materials[1];*/ - AtlasPointer &pa_liquid1 = - *nodedef->get(n).special_aps[0]; - - bool top_is_air = false; - MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); - if(n.getContent() == CONTENT_AIR) - top_is_air = true; - - if(top_is_air == false) - continue; - - u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef)); - video::SColor c = MapBlock_LightColor( - nodedef->get(n).alpha, l); - - video::S3DVertex vertices[4] = - { - video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, - pa_liquid1.x0(), pa_liquid1.y1()), - video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, - pa_liquid1.x1(), pa_liquid1.y1()), - video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, - pa_liquid1.x1(), pa_liquid1.y0()), - video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, - pa_liquid1.x0(), pa_liquid1.y0()), - }; - - for(s32 i=0; i<4; i++) - { - vertices[i].Pos.Y += (-0.5+node_liquid_level)*BS; - vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); - } - - u16 indices[] = {0,1,2,2,3,0}; - // Add to mesh collector - collector.append(liquid_material, vertices, 4, indices, 6); - } - /* - Add leaves if using new style - */ - else if(n.getContent() == CONTENT_LEAVES && new_style_leaves) - { - /*u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef));*/ u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef))); video::SColor c = MapBlock_LightColor(255, l); @@ -725,13 +532,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data, video::S3DVertex vertices[4] = { video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c, - pa_leaves1.x0(), pa_leaves1.y1()), + pa_glass.x0(), pa_glass.y1()), video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c, - pa_leaves1.x1(), pa_leaves1.y1()), + pa_glass.x1(), pa_glass.y1()), video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c, - pa_leaves1.x1(), pa_leaves1.y0()), + pa_glass.x1(), pa_glass.y0()), video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c, - pa_leaves1.x0(), pa_leaves1.y0()), + pa_glass.x0(), pa_glass.y0()), }; if(j == 0) @@ -772,14 +579,19 @@ void mapblock_mesh_generate_special(MeshMakeData *data, u16 indices[] = {0,1,2,2,3,0}; // Add to mesh collector - collector.append(material_leaves1, vertices, 4, indices, 6); + collector.append(material_glass, vertices, 4, indices, 6); } - } - /* - Add glass - */ - else if(n.getContent() == CONTENT_GLASS) + break;} + case NDT_ALLFACES: { + video::SMaterial material_leaves1; + material_leaves1.setFlag(video::EMF_LIGHTING, false); + material_leaves1.setFlag(video::EMF_BILINEAR_FILTER, false); + material_leaves1.setFlag(video::EMF_FOG_ENABLE, true); + material_leaves1.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + AtlasPointer pa_leaves1 = f.tiles[0].texture; + material_leaves1.setTexture(0, pa_leaves1.atlas); + u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef))); video::SColor c = MapBlock_LightColor(255, l); @@ -788,13 +600,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data, video::S3DVertex vertices[4] = { video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c, - pa_glass.x0(), pa_glass.y1()), + pa_leaves1.x0(), pa_leaves1.y1()), video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c, - pa_glass.x1(), pa_glass.y1()), + pa_leaves1.x1(), pa_leaves1.y1()), video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c, - pa_glass.x1(), pa_glass.y0()), + pa_leaves1.x1(), pa_leaves1.y0()), video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c, - pa_glass.x0(), pa_glass.y0()), + pa_leaves1.x0(), pa_leaves1.y0()), }; if(j == 0) @@ -835,158 +647,141 @@ void mapblock_mesh_generate_special(MeshMakeData *data, u16 indices[] = {0,1,2,2,3,0}; // Add to mesh collector - collector.append(material_glass, vertices, 4, indices, 6); + collector.append(material_leaves1, vertices, 4, indices, 6); } - } - /* - Add fence - */ - else if(n.getContent() == CONTENT_FENCE) + break;} + case NDT_ALLFACES_OPTIONAL: + // This is always pre-converted to something else + assert(0); + break; + case NDT_TORCHLIKE: { - u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef))); - video::SColor c = MapBlock_LightColor(255, l); + v3s16 dir = unpackDir(n.param2); + + AtlasPointer ap(0); + if(dir == v3s16(0,-1,0)){ + ap = f.tiles[0].texture; // floor + } else if(dir == v3s16(0,1,0)){ + ap = f.tiles[1].texture; // ceiling + // For backwards compatibility + } else if(dir == v3s16(0,0,0)){ + ap = f.tiles[0].texture; // floor + } else { + ap = f.tiles[2].texture; // side + } - const f32 post_rad=(f32)BS/10; - const f32 bar_rad=(f32)BS/20; - const f32 bar_len=(f32)(BS/2)-post_rad; + // Set material + video::SMaterial material; + material.setFlag(video::EMF_LIGHTING, false); + material.setFlag(video::EMF_BACK_FACE_CULLING, false); + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setFlag(video::EMF_FOG_ENABLE, true); + //material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; + material.MaterialType + = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + material.setTexture(0, ap.atlas); - // The post - always present - v3f pos = intToFloat(p+blockpos_nodes, BS); - f32 postuv[24]={ - 0.4,0.4,0.6,0.6, - 0.35,0,0.65,1, - 0.35,0,0.65,1, - 0.35,0,0.65,1, - 0.35,0,0.65,1, - 0.4,0.4,0.6,0.6}; - makeCuboid(material_wood, &collector, - &pa_wood, c, pos, - post_rad,BS/2,post_rad, postuv); + video::SColor c(255,255,255,255); - // 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.getContent() == CONTENT_FENCE) + // Wall at X+ of node + video::S3DVertex vertices[4] = { - pos = intToFloat(p+blockpos_nodes, BS); - pos.X += BS/2; - pos.Y += BS/4; - f32 xrailuv[24]={ - 0,0.4,1,0.6, - 0,0.4,1,0.6, - 0,0.4,1,0.6, - 0,0.4,1,0.6, - 0,0.4,1,0.6, - 0,0.4,1,0.6}; - makeCuboid(material_wood, &collector, - &pa_wood, c, pos, - bar_len,bar_rad,bar_rad, xrailuv); - - pos.Y -= BS/2; - makeCuboid(material_wood, &collector, - &pa_wood, c, pos, - bar_len,bar_rad,bar_rad, xrailuv); - } + video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, + ap.x0(), ap.y1()), + video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, + ap.x1(), ap.y1()), + video::S3DVertex(BS/2,BS/2,0, 0,0,0, c, + ap.x1(), ap.y0()), + video::S3DVertex(-BS/2,BS/2,0, 0,0,0, c, + ap.x0(), ap.y0()), + }; - // 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.getContent() == CONTENT_FENCE) + for(s32 i=0; i<4; i++) { - pos = intToFloat(p+blockpos_nodes, BS); - pos.Z += BS/2; - pos.Y += BS/4; - f32 zrailuv[24]={ - 0,0.4,1,0.6, - 0,0.4,1,0.6, - 0,0.4,1,0.6, - 0,0.4,1,0.6, - 0,0.4,1,0.6, - 0,0.4,1,0.6}; - makeCuboid(material_wood, &collector, - &pa_wood, c, pos, - bar_rad,bar_rad,bar_len, zrailuv); - pos.Y -= BS/2; - makeCuboid(material_wood, &collector, - &pa_wood, c, pos, - bar_rad,bar_rad,bar_len, zrailuv); + if(dir == v3s16(1,0,0)) + vertices[i].Pos.rotateXZBy(0); + if(dir == v3s16(-1,0,0)) + vertices[i].Pos.rotateXZBy(180); + if(dir == v3s16(0,0,1)) + vertices[i].Pos.rotateXZBy(90); + if(dir == v3s16(0,0,-1)) + vertices[i].Pos.rotateXZBy(-90); + if(dir == v3s16(0,-1,0)) + vertices[i].Pos.rotateXZBy(45); + if(dir == v3s16(0,1,0)) + vertices[i].Pos.rotateXZBy(-45); + vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); } - } -#if 1 - /* - Add stones with minerals if stone is invisible - */ - else if(n.getContent() == CONTENT_STONE && invisible_stone && n.getMineral(nodedef) != MINERAL_NONE) + u16 indices[] = {0,1,2,2,3,0}; + // Add to mesh collector + collector.append(material, vertices, 4, indices, 6); + break;} + case NDT_SIGNLIKE: { - for(u32 j=0; j<6; j++) - { - // NOTE: Hopefully g_6dirs[j] is the right direction... - v3s16 dir = g_6dirs[j]; - /*u8 l = 0; - MapNode n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + dir); - if(nodedef->get(n2).param_type == CPT_LIGHT) - l = decode_light(n2.getLightBlend(data->m_daynight_ratio, nodedef)); - else - l = 255;*/ - u8 l = 255; - video::SColor c = MapBlock_LightColor(255, l); - - // Get the right texture - TileSpec ts = n.getTile(dir, tsrc, nodedef); - AtlasPointer ap = ts.texture; - material_general.setTexture(0, ap.atlas); + // Set material + video::SMaterial material; + material.setFlag(video::EMF_LIGHTING, false); + material.setFlag(video::EMF_BACK_FACE_CULLING, false); + material.setFlag(video::EMF_BILINEAR_FILTER, false); + material.setFlag(video::EMF_FOG_ENABLE, true); + material.MaterialType + = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + AtlasPointer ap = f.tiles[0].texture; + material.setTexture(0, ap.atlas); - video::S3DVertex vertices[4] = - { - video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c, + u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef)); + video::SColor c = MapBlock_LightColor(255, l); + + float d = (float)BS/16; + // Wall at X+ of node + video::S3DVertex vertices[4] = + { + video::S3DVertex(BS/2-d,-BS/2,-BS/2, 0,0,0, c, ap.x0(), ap.y1()), - video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c, + video::S3DVertex(BS/2-d,-BS/2,BS/2, 0,0,0, c, ap.x1(), ap.y1()), - video::S3DVertex(BS/2,BS/2,BS/2, 0,0,0, c, + video::S3DVertex(BS/2-d,BS/2,BS/2, 0,0,0, c, ap.x1(), ap.y0()), - video::S3DVertex(-BS/2,BS/2,BS/2, 0,0,0, c, + video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c, ap.x0(), ap.y0()), - }; + }; - if(j == 0) - { - for(u16 i=0; i<4; i++) - vertices[i].Pos.rotateXZBy(0); - } - else if(j == 1) - { - for(u16 i=0; i<4; i++) - vertices[i].Pos.rotateXZBy(180); - } - else if(j == 2) - { - for(u16 i=0; i<4; i++) - vertices[i].Pos.rotateXZBy(-90); - } - else if(j == 3) - { - for(u16 i=0; i<4; i++) - vertices[i].Pos.rotateXZBy(90); - } - else if(j == 4) + v3s16 dir = unpackDir(n.param2); - for(u16 i=0; i<4; i++) - { - vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); - } + for(s32 i=0; i<4; i++) + { + if(dir == v3s16(1,0,0)) + vertices[i].Pos.rotateXZBy(0); + if(dir == v3s16(-1,0,0)) + vertices[i].Pos.rotateXZBy(180); + if(dir == v3s16(0,0,1)) + vertices[i].Pos.rotateXZBy(90); + if(dir == v3s16(0,0,-1)) + vertices[i].Pos.rotateXZBy(-90); + if(dir == v3s16(0,-1,0)) + vertices[i].Pos.rotateXYBy(-90); + if(dir == v3s16(0,1,0)) + vertices[i].Pos.rotateXYBy(90); - u16 indices[] = {0,1,2,2,3,0}; - // Add to mesh collector - collector.append(material_general, vertices, 4, indices, 6); + vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); } - } -#endif - else if(n.getContent() == CONTENT_PAPYRUS) + + u16 indices[] = {0,1,2,2,3,0}; + // Add to mesh collector + collector.append(material, vertices, 4, indices, 6); + break;} + case NDT_PLANTLIKE: { + video::SMaterial material_papyrus; + material_papyrus.setFlag(video::EMF_LIGHTING, false); + material_papyrus.setFlag(video::EMF_BILINEAR_FILTER, false); + material_papyrus.setFlag(video::EMF_FOG_ENABLE, true); + material_papyrus.MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; + AtlasPointer pa_papyrus = f.tiles[0].texture; + material_papyrus.setTexture(0, pa_papyrus.atlas); + u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef))); video::SColor c = MapBlock_LightColor(255, l); @@ -1027,6 +822,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, for(u16 i=0; i<4; i++) { + vertices[i].Pos *= f.visual_scale; vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); } @@ -1034,59 +830,92 @@ void mapblock_mesh_generate_special(MeshMakeData *data, // Add to mesh collector collector.append(material_papyrus, vertices, 4, indices, 6); } - } - else if(n.getContent() == CONTENT_JUNGLEGRASS) + break;} + case NDT_FENCELIKE: { + 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 = f.tiles[0].texture; + material_wood.setTexture(0, pa_wood.atlas); + u8 l = decode_light(undiminish_light(n.getLightBlend(data->m_daynight_ratio, nodedef))); video::SColor c = MapBlock_LightColor(255, l); - for(u32 j=0; j<4; j++) + 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); + f32 postuv[24]={ + 0.4,0.4,0.6,0.6, + 0.35,0,0.65,1, + 0.35,0,0.65,1, + 0.35,0,0.65,1, + 0.35,0,0.65,1, + 0.4,0.4,0.6,0.6}; + makeCuboid(material_wood, &collector, + &pa_wood, c, pos, + post_rad,BS/2,post_rad, postuv); + + // 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); + const ContentFeatures *f2 = &nodedef->get(n2); + if(f2->drawtype == NDT_FENCELIKE) { - video::S3DVertex vertices[4] = - { - video::S3DVertex(-BS/2,-BS/2,0, 0,0,0, c, - pa_junglegrass.x0(), pa_junglegrass.y1()), - video::S3DVertex(BS/2,-BS/2,0, 0,0,0, c, - pa_junglegrass.x1(), pa_junglegrass.y1()), - video::S3DVertex(BS/2,BS/1,0, 0,0,0, c, - pa_junglegrass.x1(), pa_junglegrass.y0()), - video::S3DVertex(-BS/2,BS/1,0, 0,0,0, c, - pa_junglegrass.x0(), pa_junglegrass.y0()), - }; + pos = intToFloat(p+blockpos_nodes, BS); + pos.X += BS/2; + pos.Y += BS/4; + f32 xrailuv[24]={ + 0,0.4,1,0.6, + 0,0.4,1,0.6, + 0,0.4,1,0.6, + 0,0.4,1,0.6, + 0,0.4,1,0.6, + 0,0.4,1,0.6}; + makeCuboid(material_wood, &collector, + &pa_wood, c, pos, + bar_len,bar_rad,bar_rad, xrailuv); - 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); - } + pos.Y -= BS/2; + makeCuboid(material_wood, &collector, + &pa_wood, c, pos, + bar_len,bar_rad,bar_rad, xrailuv); + } - for(u16 i=0; i<4; i++) - { - vertices[i].Pos *= 1.3; - vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); - } + // Now a section of fence, +Z, if there's a post there + p2 = p; + p2.Z++; + n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); + f2 = &nodedef->get(n2); + if(f2->drawtype == NDT_FENCELIKE) + { + pos = intToFloat(p+blockpos_nodes, BS); + pos.Z += BS/2; + pos.Y += BS/4; + f32 zrailuv[24]={ + 0,0.4,1,0.6, + 0,0.4,1,0.6, + 0,0.4,1,0.6, + 0,0.4,1,0.6, + 0,0.4,1,0.6, + 0,0.4,1,0.6}; + makeCuboid(material_wood, &collector, + &pa_wood, c, pos, + bar_rad,bar_rad,bar_len, zrailuv); + pos.Y -= BS/2; + makeCuboid(material_wood, &collector, + &pa_wood, c, pos, + bar_rad,bar_rad,bar_len, zrailuv); - u16 indices[] = {0,1,2,2,3,0}; - // Add to mesh collector - collector.append(material_junglegrass, vertices, 4, indices, 6); } - } - else if(n.getContent() == CONTENT_RAIL) + break;} + case NDT_RAILLIKE: { bool is_rail_x [] = { false, false }; /* x-1, x+1 */ bool is_rail_z [] = { false, false }; /* z-1, z+1 */ @@ -1095,36 +924,35 @@ void mapblock_mesh_generate_special(MeshMakeData *data, MapNode n_plus_x = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x+1,y,z)); MapNode n_minus_z = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y,z-1)); MapNode n_plus_z = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y,z+1)); - - if(n_minus_x.getContent() == CONTENT_RAIL) + + content_t thiscontent = n.getContent(); + if(n_minus_x.getContent() == thiscontent) is_rail_x[0] = true; - if(n_plus_x.getContent() == CONTENT_RAIL) + if(n_plus_x.getContent() == thiscontent) is_rail_x[1] = true; - if(n_minus_z.getContent() == CONTENT_RAIL) + if(n_minus_z.getContent() == thiscontent) is_rail_z[0] = true; - if(n_plus_z.getContent() == CONTENT_RAIL) + if(n_plus_z.getContent() == thiscontent) is_rail_z[1] = true; int adjacencies = is_rail_x[0] + is_rail_x[1] + is_rail_z[0] + is_rail_z[1]; // Assign textures - const char *texturename = "rail.png"; + AtlasPointer ap = f.tiles[0].texture; // straight if(adjacencies < 2) - texturename = "rail.png"; + ap = f.tiles[0].texture; // straight else if(adjacencies == 2) { if((is_rail_x[0] && is_rail_x[1]) || (is_rail_z[0] && is_rail_z[1])) - texturename = "rail.png"; + ap = f.tiles[0].texture; // straight else - texturename = "rail_curved.png"; + ap = f.tiles[1].texture; // curved } else if(adjacencies == 3) - texturename = "rail_t_junction.png"; + ap = f.tiles[2].texture; // t-junction else if(adjacencies == 4) - texturename = "rail_crossing.png"; + ap = f.tiles[3].texture; // crossing - AtlasPointer ap = tsrc->getTexture(texturename); - video::SMaterial material_rail; material_rail.setFlag(video::EMF_LIGHTING, false); material_rail.setFlag(video::EMF_BACK_FACE_CULLING, false); @@ -1193,159 +1021,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, u16 indices[] = {0,1,2,2,3,0}; collector.append(material_rail, vertices, 4, indices, 6); - } - else if (n.getContent() == CONTENT_LADDER) { - AtlasPointer ap = tsrc->getTexture("ladder.png"); - - // Set material - video::SMaterial material_ladder; - material_ladder.setFlag(video::EMF_LIGHTING, false); - material_ladder.setFlag(video::EMF_BACK_FACE_CULLING, false); - material_ladder.setFlag(video::EMF_BILINEAR_FILTER, false); - material_ladder.setFlag(video::EMF_FOG_ENABLE, true); - material_ladder.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; - material_ladder.setTexture(0, ap.atlas); - - u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio, nodedef)); - video::SColor c(255,l,l,l); - - float d = (float)BS/16; - - // Assume wall is at X+ - video::S3DVertex vertices[4] = - { - video::S3DVertex(BS/2-d,-BS/2,-BS/2, 0,0,0, c, - ap.x0(), ap.y1()), - video::S3DVertex(BS/2-d,-BS/2,BS/2, 0,0,0, c, - ap.x1(), ap.y1()), - video::S3DVertex(BS/2-d,BS/2,BS/2, 0,0,0, c, - ap.x1(), ap.y0()), - video::S3DVertex(BS/2-d,BS/2,-BS/2, 0,0,0, c, - ap.x0(), ap.y0()), - }; - - v3s16 dir = unpackDir(n.param2); - - for(s32 i=0; i<4; i++) - { - if(dir == v3s16(1,0,0)) - vertices[i].Pos.rotateXZBy(0); - if(dir == v3s16(-1,0,0)) - vertices[i].Pos.rotateXZBy(180); - if(dir == v3s16(0,0,1)) - vertices[i].Pos.rotateXZBy(90); - if(dir == v3s16(0,0,-1)) - vertices[i].Pos.rotateXZBy(-90); - if(dir == v3s16(0,-1,0)) - vertices[i].Pos.rotateXYBy(-90); - if(dir == v3s16(0,1,0)) - vertices[i].Pos.rotateXYBy(90); - - vertices[i].Pos += intToFloat(p + blockpos_nodes, BS); - } - - u16 indices[] = {0,1,2,2,3,0}; - // 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, nodedef))); - 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, nodedef))); - 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); - } + break;} } } } diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index 0f1ae4a6e..58eaff108 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -17,13 +17,11 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -// For g_settings -#include "main.h" - #include "content_mapnode.h" + +#include "irrlichttypes.h" #include "mapnode.h" #include "content_nodemeta.h" -#include "settings.h" #include "nodedef.h" #define WATER_ALPHA 160 @@ -156,23 +154,8 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version) } // See header for description -void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr) +void content_mapnode_init(IWritableNodeDefManager *nodemgr) { - if(tsrc == NULL) - dstream<<"INFO: Initial run of content_mapnode_init with " - "tsrc=NULL. If this segfaults, " - "there is a bug with something not checking for " - "the NULL value."<<std::endl; - else - dstream<<"INFO: Full run of content_mapnode_init with " - "tsrc!=NULL"<<std::endl; - - // Read some settings - bool new_style_water = g_settings->getBool("new_style_water"); - bool new_style_leaves = g_settings->getBool("new_style_leaves"); - bool invisible_stone = g_settings->getBool("invisible_stone"); - bool opaque_water = g_settings->getBool("opaque_water"); - content_t i; ContentFeatures *f = NULL; @@ -185,8 +168,6 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr f->often_contains_mineral = true; f->dug_item = std::string("MaterialItem2 ")+itos(CONTENT_COBBLE)+" 1"; setStoneLikeMaterialProperties(f->material, 1.0); - if(invisible_stone) - f->solidness = 0; // For debugging, hides regular stone i = CONTENT_GRASS; f = nodemgr->getModifiable(i); @@ -278,40 +259,29 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr 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("MaterialItem2 ")+itos(i)+" 1"; setWoodLikeMaterialProperties(f->material, 1.0); i = CONTENT_JUNGLEGRASS; f = nodemgr->getModifiable(i); + f->drawtype = NDT_PLANTLIKE; + f->visual_scale = 1.6; + f->setAllTextures("junglegrass.png"); f->setInventoryTexture("junglegrass.png"); - f->used_texturenames.insert("junglegrass.png"); // Add to atlas 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("MaterialItem2 ")+itos(i)+" 1"; - f->solidness = 0; // drawn separately, makes no faces f->walkable = false; setLeavesLikeMaterialProperties(f->material, 1.0); i = CONTENT_LEAVES; f = nodemgr->getModifiable(i); + f->drawtype = NDT_ALLFACES_OPTIONAL; + f->setAllTextures("leaves.png"); + //f->setAllTextures("[noalpha:leaves.png"); f->light_propagates = true; - //f->param_type = CPT_MINERAL; f->param_type = CPT_LIGHT; - //f->is_ground_content = true; - if(new_style_leaves) - { - f->solidness = 0; // drawn separately, makes no faces - f->visual_solidness = 1; - f->setAllTextures("leaves.png"); - f->setInventoryTextureCube("leaves.png", "leaves.png", "leaves.png"); - } - else - { - f->setAllTextures("[noalpha:leaves.png"); - } f->extra_dug_item = std::string("MaterialItem2 ")+itos(CONTENT_SAPLING)+" 1"; f->extra_dug_item_rarity = 20; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; @@ -330,13 +300,13 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr i = CONTENT_PAPYRUS; f = nodemgr->getModifiable(i); + f->drawtype = NDT_PLANTLIKE; + f->setAllTextures("papyrus.png"); f->setInventoryTexture("papyrus.png"); - f->used_texturenames.insert("papyrus.png"); // Add to atlas f->light_propagates = true; f->param_type = CPT_LIGHT; f->is_ground_content = true; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; - f->solidness = 0; // drawn separately, makes no faces f->walkable = false; setLeavesLikeMaterialProperties(f->material, 0.5); @@ -354,27 +324,26 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr i = CONTENT_GLASS; f = nodemgr->getModifiable(i); + f->drawtype = NDT_GLASSLIKE; + f->setAllTextures("glass.png"); f->light_propagates = true; f->sunlight_propagates = true; f->param_type = CPT_LIGHT; f->is_ground_content = true; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; - f->solidness = 0; // drawn separately, makes no faces - f->visual_solidness = 1; - f->setAllTextures("glass.png"); f->setInventoryTextureCube("glass.png", "glass.png", "glass.png"); setGlassLikeMaterialProperties(f->material, 1.0); i = CONTENT_FENCE; f = nodemgr->getModifiable(i); + f->drawtype = NDT_FENCELIKE; + f->setInventoryTexture("fence.png"); + f->setTexture(0, "wood.png"); f->light_propagates = true; f->param_type = CPT_LIGHT; f->is_ground_content = true; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; - f->solidness = 0; // drawn separately, makes no faces f->air_equivalent = true; // grass grows underneath - f->setInventoryTexture("fence.png"); - f->used_texturenames.insert("fence.png"); // Add to atlas f->selection_box.type = NODEBOX_FIXED; f->selection_box.fixed = core::aabbox3d<f32>( -BS/7, -BS/2, -BS/7, BS/7, BS/2, BS/7); @@ -382,13 +351,16 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr i = CONTENT_RAIL; f = nodemgr->getModifiable(i); + f->drawtype = NDT_RAILLIKE; f->setInventoryTexture("rail.png"); - f->used_texturenames.insert("rail.png"); // Add to atlas + f->setTexture(0, "rail.png"); + f->setTexture(1, "rail_curved.png"); + f->setTexture(2, "rail_t_junction.png"); + f->setTexture(3, "rail_crossing.png"); f->light_propagates = true; f->param_type = CPT_LIGHT; f->is_ground_content = true; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; - f->solidness = 0; // drawn separately, makes no faces f->air_equivalent = true; // grass grows underneath f->walkable = false; f->selection_box.type = NODEBOX_FIXED; @@ -396,14 +368,14 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr i = CONTENT_LADDER; f = nodemgr->getModifiable(i); + f->drawtype = NDT_SIGNLIKE; + f->setAllTextures("ladder.png"); f->setInventoryTexture("ladder.png"); - f->used_texturenames.insert("ladder.png"); // Add to atlas f->light_propagates = true; f->param_type = CPT_LIGHT; f->is_ground_content = true; f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; f->wall_mounted = true; - f->solidness = 0; f->air_equivalent = true; f->walkable = false; f->climbable = true; @@ -445,7 +417,6 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr f->param_type = CPT_LIGHT; f->light_propagates = true; f->sunlight_propagates = true; - f->solidness = 0; f->walkable = false; f->pointable = false; f->diggable = false; @@ -454,11 +425,11 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr i = CONTENT_WATER; f = nodemgr->getModifiable(i); + f->drawtype = NDT_FLOWINGLIQUID; + f->setAllTextures("water.png", WATER_ALPHA); f->setInventoryTextureCube("water.png", "water.png", "water.png"); f->param_type = CPT_LIGHT; f->light_propagates = true; - f->solidness = 0; // Drawn separately, makes no faces - f->visual_solidness = 1; f->walkable = false; f->pointable = false; f->diggable = false; @@ -467,8 +438,6 @@ 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; - 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"; @@ -478,16 +447,8 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr i = CONTENT_WATERSOURCE; f = nodemgr->getModifiable(i); - if(new_style_water) - { - f->solidness = 0; // drawn separately, makes no faces - } - else // old style - { - f->solidness = 1; - f->setAllTextures("water.png", WATER_ALPHA); - f->backface_culling = false; - } + f->drawtype = NDT_LIQUID; + f->setAllTextures("water.png", WATER_ALPHA); //f->setInventoryTexture("water.png"); f->setInventoryTextureCube("water.png", "water.png", "water.png"); f->param_type = CPT_LIGHT; @@ -501,8 +462,6 @@ 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; - 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"; @@ -510,13 +469,12 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr i = CONTENT_LAVA; f = nodemgr->getModifiable(i); + f->drawtype = NDT_FLOWINGLIQUID; + f->setAllTextures("lava.png"); f->setInventoryTextureCube("lava.png", "lava.png", "lava.png"); - f->used_texturenames.insert("lava.png"); // Add to atlas f->param_type = CPT_LIGHT; f->light_propagates = false; f->light_source = LIGHT_MAX-1; - f->solidness = 0; // Drawn separately, makes no faces - f->visual_solidness = 1; // Does not completely cover block boundaries f->walkable = false; f->pointable = false; f->diggable = false; @@ -535,16 +493,8 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr i = CONTENT_LAVASOURCE; f = nodemgr->getModifiable(i); - f->used_texturenames.insert("ladder.png"); // Add to atlas - if(new_style_water) - { - f->solidness = 0; // drawn separately, makes no faces - } - else // old style - { - f->solidness = 2; - f->setAllTextures("lava.png"); - } + f->drawtype = NDT_LIQUID; + f->setAllTextures("lava.png"); f->setInventoryTextureCube("lava.png", "lava.png", "lava.png"); f->param_type = CPT_LIGHT; f->light_propagates = false; @@ -566,14 +516,14 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr i = CONTENT_TORCH; f = nodemgr->getModifiable(i); + f->drawtype = NDT_TORCHLIKE; + f->setTexture(0, "torch_on_floor.png"); + f->setTexture(1, "torch_on_ceiling.png"); + f->setTexture(2, "torch.png"); f->setInventoryTexture("torch_on_floor.png"); - f->used_texturenames.insert("torch_on_floor.png"); // Add to atlas - f->used_texturenames.insert("torch_on_ceiling.png"); // Add to atlas - f->used_texturenames.insert("torch.png"); // Add to atlas f->param_type = CPT_LIGHT; f->light_propagates = true; f->sunlight_propagates = true; - f->solidness = 0; // drawn separately, makes no faces f->walkable = false; f->wall_mounted = true; f->air_equivalent = true; @@ -590,12 +540,12 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr i = CONTENT_SIGN_WALL; f = nodemgr->getModifiable(i); + f->drawtype = NDT_SIGNLIKE; + f->setAllTextures("sign_wall.png"); f->setInventoryTexture("sign_wall.png"); - f->used_texturenames.insert("sign_wall.png"); // Add to atlas f->param_type = CPT_LIGHT; f->light_propagates = true; f->sunlight_propagates = true; - f->solidness = 0; // drawn separately, makes no faces f->walkable = false; f->wall_mounted = true; f->air_equivalent = true; @@ -692,25 +642,26 @@ void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr i = CONTENT_SAPLING; f = nodemgr->getModifiable(i); - f->param_type = CPT_LIGHT; + f->drawtype = NDT_PLANTLIKE; + f->visual_scale = 1.5; f->setAllTextures("sapling.png"); f->setInventoryTexture("sapling.png"); - f->used_texturenames.insert("sapling.png"); // Add to atlas + f->param_type = CPT_LIGHT; f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; f->light_propagates = true; f->air_equivalent = false; - f->solidness = 0; // drawn separately, makes no faces f->walkable = false; setConstantMaterialProperties(f->material, 0.0); i = CONTENT_APPLE; f = nodemgr->getModifiable(i); + f->drawtype = NDT_PLANTLIKE; + f->visual_scale = 1.0; + f->setAllTextures("apple.png"); f->setInventoryTexture("apple.png"); - f->used_texturenames.insert("apple.png"); // Add to atlas f->param_type = CPT_LIGHT; f->light_propagates = true; f->sunlight_propagates = true; - f->solidness = 0; // drawn separately, makes no faces f->walkable = false; f->air_equivalent = true; f->dug_item = std::string("CraftItem apple 1"); diff --git a/src/content_mapnode.h b/src/content_mapnode.h index ace30be7b..3140f2179 100644 --- a/src/content_mapnode.h +++ b/src/content_mapnode.h @@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #define CONTENT_MAPNODE_HEADER #include "mapnode.h" -class ITextureSource; class IWritableNodeDefManager; /* @@ -36,7 +35,7 @@ class IWritableNodeDefManager; Server only calls this once with tsrc=NULL. */ -void content_mapnode_init(ITextureSource *tsrc, IWritableNodeDefManager *nodemgr); +void content_mapnode_init(IWritableNodeDefManager *nodemgr); // Backwards compatibility for non-extended content types in v19 extern content_t trans_table_19[21][2]; diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index fbc22867d..2cb69b116 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -75,7 +75,6 @@ void set_default_settings(Settings *settings) settings->setDefault("invert_mouse", "false"); settings->setDefault("enable_farmesh", "false"); settings->setDefault("enable_clouds", "true"); - settings->setDefault("invisible_stone", "false"); settings->setDefault("screenshot_path", "."); settings->setDefault("view_bobbing_amount", "1.0"); settings->setDefault("enable_3d_clouds", "false"); diff --git a/src/game.cpp b/src/game.cpp index 4fd6eebb0..7efce23a4 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -645,7 +645,7 @@ void the_game( IWritableNodeDefManager *nodedef = createNodeDefManager(); // Fill node feature table with default definitions - content_mapnode_init(tsrc, nodedef); + content_mapnode_init(nodedef); /* Create server. diff --git a/src/irrlichttypes.h b/src/irrlichttypes.h index 7ab83bb7d..bc17694fc 100644 --- a/src/irrlichttypes.h +++ b/src/irrlichttypes.h @@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <irrList.h> #include <irrArray.h> #include <aabbox3d.h> +#include <SColor.h> using namespace irr; typedef core::vector3df v3f; typedef core::vector3d<s16> v3s16; diff --git a/src/mapnode.cpp b/src/mapnode.cpp index 9aceab17e..1e8915b03 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "nodedef.h" #include "content_mapnode.h" // For mapnode_translate_*_internal +#ifndef SERVER /* Nodes make a face if contents differ and solidness differs. Return value: @@ -81,6 +82,7 @@ u8 face_contents(content_t m1, content_t m2, bool *equivalent, else return 2; } +#endif v3s16 facedir_rotate(u8 facedir, v3s16 dir) { diff --git a/src/mapnode.h b/src/mapnode.h index 70a7638d2..7fe205463 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -62,6 +62,7 @@ typedef u16 content_t; */ #define CONTENT_AIR 126 +#ifndef SERVER /* Nodes make a face if contents differ and solidness differs. Return value: @@ -72,6 +73,7 @@ typedef u16 content_t; */ u8 face_contents(content_t m1, content_t m2, bool *equivalent, INodeDefManager *nodemgr); +#endif /* Packs directions like (1,0,0), (1,-1,0) in six bits. diff --git a/src/materials.cpp b/src/materials.cpp index d89b1e079..72547face 100644 --- a/src/materials.cpp +++ b/src/materials.cpp @@ -1,7 +1,49 @@ +/* +Minetest-c55 +Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com> + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + #include "materials.h" #include "mapnode.h" #include "nodedef.h" #include "tooldef.h" +#include "utility.h" + +void MaterialProperties::serialize(std::ostream &os) +{ + writeU8(os, 0); // version + writeU8(os, diggability); + writeF1000(os, weight); + writeF1000(os, crackiness); + writeF1000(os, crumbliness); + writeF1000(os, cuttability); +} + +void MaterialProperties::deSerialize(std::istream &is) +{ + int version = readU8(is); + if(version != 0) + throw SerializationError("unsupported MaterialProperties version"); + diggability = (enum Diggability)readU8(is); + weight = readF1000(is); + crackiness = readF1000(is); + crumbliness = readF1000(is); + cuttability = readF1000(is); +} DiggingProperties getDiggingProperties(u16 content, ToolDiggingProperties *tp, INodeDefManager *nodemgr) diff --git a/src/materials.h b/src/materials.h index 62bce1669..4e067fd66 100644 --- a/src/materials.h +++ b/src/materials.h @@ -1,6 +1,6 @@ /* Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com> +Copyright (C) 2010-2011 celeron55, Perttu Ahola <celeron55@gmail.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common_irrlicht.h" #include <string> +#include <iostream> enum Diggability { @@ -65,6 +66,9 @@ struct MaterialProperties crumbliness(1), cuttability(1) {} + + void serialize(std::ostream &os); + void deSerialize(std::istream &is); }; struct DiggingProperties diff --git a/src/nodedef.cpp b/src/nodedef.cpp index 045615fbb..996b20781 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -25,6 +25,54 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "tile.h" #endif #include "log.h" +#include "settings.h" + +void NodeBox::serialize(std::ostream &os) +{ + writeU8(os, 0); // version + writeU8(os, type); + writeV3F1000(os, fixed.MinEdge); + writeV3F1000(os, fixed.MaxEdge); + writeV3F1000(os, wall_top.MinEdge); + writeV3F1000(os, wall_top.MaxEdge); + writeV3F1000(os, wall_bottom.MinEdge); + writeV3F1000(os, wall_bottom.MaxEdge); + writeV3F1000(os, wall_side.MinEdge); + writeV3F1000(os, wall_side.MaxEdge); +} + +void NodeBox::deSerialize(std::istream &is) +{ + int version = readU8(is); + if(version != 0) + throw SerializationError("unsupported NodeBox version"); + type = (enum NodeBoxType)readU8(is); + fixed.MinEdge = readV3F1000(is); + fixed.MaxEdge = readV3F1000(is); + wall_top.MinEdge = readV3F1000(is); + wall_top.MaxEdge = readV3F1000(is); + wall_bottom.MinEdge = readV3F1000(is); + wall_bottom.MaxEdge = readV3F1000(is); + wall_side.MinEdge = readV3F1000(is); + wall_side.MaxEdge = readV3F1000(is); +} + +void MaterialSpec::serialize(std::ostream &os) +{ + os<<serializeString(tname); + writeU8(os, backface_culling); +} + +void MaterialSpec::deSerialize(std::istream &is) +{ + tname = deSerializeString(is); + backface_culling = readU8(is); +} + +ContentFeatures::ContentFeatures() +{ + reset(); +} ContentFeatures::~ContentFeatures() { @@ -37,6 +85,161 @@ ContentFeatures::~ContentFeatures() #endif } +void ContentFeatures::reset() +{ + /* + Cached stuff + */ +#ifndef SERVER + inventory_texture = NULL; + + for(u16 j=0; j<CF_SPECIAL_COUNT; j++){ + special_materials[j] = NULL; + special_aps[j] = NULL; + } + solidness = 2; + visual_solidness = 0; + backface_culling = true; +#endif + used_texturenames.clear(); + modified = true; // NodeDefManager explicitly sets to false + /* + Actual data + */ + drawtype = NDT_NORMAL; + visual_scale = 1.0; + 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 = ""; + alpha = 255; + post_effect_color = video::SColor(0, 0, 0, 0); + param_type = CPT_NONE; + is_ground_content = false; + light_propagates = false; + sunlight_propagates = false; + walkable = true; + pointable = true; + diggable = true; + climbable = false; + buildable_to = false; + wall_mounted = false; + air_equivalent = false; + often_contains_mineral = false; + dug_item = ""; + initial_metadata = NULL; + liquid_type = LIQUID_NONE; + liquid_alternative_flowing = CONTENT_IGNORE; + liquid_alternative_source = CONTENT_IGNORE; + liquid_viscosity = 0; + light_source = 0; + damage_per_second = 0; + selection_box = NodeBox(); + material = MaterialProperties(); +} + +void ContentFeatures::serialize(std::ostream &os) +{ + writeU8(os, 0); // version + writeU8(os, drawtype); + writeF1000(os, visual_scale); + writeU8(os, 6); + for(u32 i=0; i<6; i++) + os<<serializeString(tname_tiles[i]); + os<<serializeString(tname_inventory); + writeU8(os, CF_SPECIAL_COUNT); + for(u32 i=0; i<CF_SPECIAL_COUNT; i++){ + mspec_special[i].serialize(os); + } + writeU8(os, alpha); + writeU8(os, post_effect_color.getAlpha()); + writeU8(os, post_effect_color.getRed()); + writeU8(os, post_effect_color.getGreen()); + writeU8(os, post_effect_color.getBlue()); + writeU8(os, param_type); + writeU8(os, is_ground_content); + writeU8(os, light_propagates); + writeU8(os, sunlight_propagates); + writeU8(os, walkable); + writeU8(os, pointable); + writeU8(os, diggable); + writeU8(os, climbable); + writeU8(os, buildable_to); + writeU8(os, wall_mounted); + writeU8(os, air_equivalent); + writeU8(os, often_contains_mineral); + os<<serializeString(dug_item); + os<<serializeString(extra_dug_item); + writeS32(os, extra_dug_item_rarity); + if(initial_metadata){ + writeU8(os, true); + initial_metadata->serialize(os); + } else { + writeU8(os, false); + } + writeU8(os, liquid_type); + writeU16(os, liquid_alternative_flowing); + writeU16(os, liquid_alternative_source); + writeU8(os, liquid_viscosity); + writeU8(os, light_source); + writeU32(os, damage_per_second); + selection_box.serialize(os); + material.serialize(os); +} + +void ContentFeatures::deSerialize(std::istream &is, IGameDef *gamedef) +{ + int version = readU8(is); + if(version != 0) + throw SerializationError("unsupported ContentFeatures version"); + drawtype = (enum NodeDrawType)readU8(is); + visual_scale = readF1000(is); + if(readU8(is) != 6) + throw SerializationError("unsupported tile count"); + for(u32 i=0; i<6; i++) + tname_tiles[i] = deSerializeString(is); + tname_inventory = deSerializeString(is); + if(readU8(is) != CF_SPECIAL_COUNT) + throw SerializationError("unsupported CF_SPECIAL_COUNT"); + for(u32 i=0; i<CF_SPECIAL_COUNT; i++){ + mspec_special[i].deSerialize(is); + } + alpha = readU8(is); + post_effect_color.setAlpha(readU8(is)); + post_effect_color.setRed(readU8(is)); + post_effect_color.setGreen(readU8(is)); + post_effect_color.setBlue(readU8(is)); + param_type = (enum ContentParamType)readU8(is); + is_ground_content = readU8(is); + light_propagates = readU8(is); + sunlight_propagates = readU8(is); + walkable = readU8(is); + pointable = readU8(is); + diggable = readU8(is); + climbable = readU8(is); + buildable_to = readU8(is); + wall_mounted = readU8(is); + air_equivalent = readU8(is); + often_contains_mineral = readU8(is); + dug_item = deSerializeString(is); + extra_dug_item = deSerializeString(is); + extra_dug_item_rarity = readS32(is); + if(readU8(is)){ + initial_metadata = NodeMetadata::deSerialize(is, gamedef); + } else { + initial_metadata = NULL; + } + liquid_type = (enum LiquidType)readU8(is); + liquid_alternative_flowing = readU16(is); + liquid_alternative_source = readU16(is); + liquid_viscosity = readU8(is); + light_source = readU8(is); + damage_per_second = readU32(is); + selection_box.deSerialize(is); + material.deSerialize(is); +} + void ContentFeatures::setTexture(u16 i, std::string name) { used_texturenames.insert(name); @@ -70,20 +273,28 @@ void ContentFeatures::setInventoryTextureCube(std::string top, class CNodeDefManager: public IWritableNodeDefManager { public: - CNodeDefManager() + void clear() { for(u16 i=0; i<=MAX_CONTENT; i++) { ContentFeatures *f = &m_content_features[i]; - // Reset to defaults - f->reset(); - if(i == CONTENT_IGNORE || i == CONTENT_AIR) + f->reset(); // Reset to defaults + f->modified = false; // Not changed from default + if(i == CONTENT_IGNORE || i == CONTENT_AIR){ + f->drawtype = NDT_AIRLIKE; continue; + } f->setAllTextures("unknown_block.png"); - f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + //f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; } +#ifndef SERVER // Make CONTENT_IGNORE to not block the view when occlusion culling m_content_features[CONTENT_IGNORE].solidness = 0; +#endif + } + CNodeDefManager() + { + clear(); } virtual ~CNodeDefManager() { @@ -116,6 +327,7 @@ public: virtual ContentFeatures* getModifiable(content_t c) { assert(c <= MAX_CONTENT); + m_content_features[c].modified = true; // Assume it is modified return &m_content_features[c]; } virtual void updateTextures(ITextureSource *tsrc) @@ -123,10 +335,72 @@ public: #ifndef SERVER infostream<<"CNodeDefManager::updateTextures(): Updating " <<"textures in node definitions"<<std::endl; + + bool new_style_water = g_settings->getBool("new_style_water"); + bool new_style_leaves = g_settings->getBool("new_style_leaves"); + bool opaque_water = g_settings->getBool("opaque_water"); + for(u16 i=0; i<=MAX_CONTENT; i++) { - infostream<<"Updating content "<<i<<std::endl; ContentFeatures *f = &m_content_features[i]; + + switch(f->drawtype){ + default: + case NDT_NORMAL: + f->solidness = 2; + break; + case NDT_AIRLIKE: + f->solidness = 0; + break; + case NDT_LIQUID: + assert(f->liquid_type == LIQUID_SOURCE); + if(opaque_water) + f->alpha = 255; + if(new_style_water){ + f->solidness = 0; + } else { + f->solidness = 1; + if(f->alpha == 255) + f->solidness = 2; + } + break; + case NDT_FLOWINGLIQUID: + assert(f->liquid_type == LIQUID_FLOWING); + f->solidness = 0; + if(opaque_water) + f->alpha = 255; + break; + case NDT_GLASSLIKE: + f->solidness = 0; + f->visual_solidness = 1; + break; + case NDT_ALLFACES: + f->solidness = 0; + f->visual_solidness = 1; + break; + case NDT_ALLFACES_OPTIONAL: + if(new_style_leaves){ + f->drawtype = NDT_ALLFACES; + f->solidness = 0; + f->visual_solidness = 1; + } else { + f->drawtype = NDT_NORMAL; + f->solidness = 1; + for(u32 i=0; i<6; i++){ + f->tname_tiles[i] = std::string("[noalpha:") + + f->tname_tiles[i]; + } + } + break; + case NDT_TORCHLIKE: + case NDT_SIGNLIKE: + case NDT_PLANTLIKE: + case NDT_FENCELIKE: + case NDT_RAILLIKE: + f->solidness = 0; + break; + } + // Inventory texture if(f->tname_inventory != "") f->inventory_texture = tsrc->getTextureRaw(f->tname_inventory); @@ -175,6 +449,35 @@ public: } #endif } + void serialize(std::ostream &os) + { + std::ostringstream tmp_os(std::ios::binary); + for(u16 i=0; i<=MAX_CONTENT; i++) + { + ContentFeatures *f = &m_content_features[i]; + if(!f->modified) + continue; + writeU16(tmp_os, i); + f->serialize(tmp_os); + } + os<<serializeLongString(tmp_os.str()); + } + void deSerialize(std::istream &is, IGameDef *gamedef) + { + clear(); + std::istringstream tmp_is(deSerializeLongString(is), std::ios::binary); + while(!tmp_is.eof()){ + u16 i = readU16(tmp_is); + if(i > MAX_CONTENT){ + errorstream<<"ContentFeatures::deSerialize(): " + <<"Too large content id: "<<i<<std::endl; + continue; + } + ContentFeatures *f = &m_content_features[i]; + f->deSerialize(tmp_is, gamedef); + f->modified = true; + } + } private: ContentFeatures m_content_features[MAX_CONTENT+1]; }; diff --git a/src/nodedef.h b/src/nodedef.h index e70295616..43bd1966d 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common_irrlicht.h" #include <string> +#include <iostream> #include <set> #include "mapnode.h" #ifndef SERVER @@ -29,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #endif #include "materials.h" // MaterialProperties class ITextureSource; +class IGameDef; /* TODO: Rename to nodedef.h @@ -95,6 +97,9 @@ struct NodeBox wall_bottom(-BS/2, -BS/2, -BS/2, BS/2, -BS/2+BS/16., BS/2), wall_side(-BS/2, -BS/2, -BS/2, -BS/2+BS/16., BS/2, BS/2) {} + + void serialize(std::ostream &os); + void deSerialize(std::istream &is); }; struct MapNode; @@ -109,42 +114,70 @@ struct MaterialSpec tname(tname_), backface_culling(backface_culling_) {} + + void serialize(std::ostream &os); + void deSerialize(std::istream &is); +}; + +enum NodeDrawType +{ + NDT_NORMAL, // A basic solid block + NDT_AIRLIKE, // Nothing is drawn + NDT_LIQUID, // Do not draw face towards same kind of flowing/source liquid + NDT_FLOWINGLIQUID, // A very special kind of thing + NDT_GLASSLIKE, // Glass-like, don't draw faces towards other glass + NDT_ALLFACES, // Leaves-like, draw all faces no matter what + NDT_ALLFACES_OPTIONAL, // Fancy -> allfaces, fast -> normal + NDT_TORCHLIKE, + NDT_SIGNLIKE, + NDT_PLANTLIKE, + NDT_FENCELIKE, + NDT_RAILLIKE, }; #define CF_SPECIAL_COUNT 2 struct ContentFeatures { + /* + Cached stuff + */ #ifndef SERVER // 0 1 2 3 4 5 // up down right left back front TileSpec tiles[6]; - video::ITexture *inventory_texture; - - // Post effect color, drawn when the camera is inside the node. - video::SColor post_effect_color; - // Special material/texture // - Currently used for flowing liquids video::SMaterial *special_materials[CF_SPECIAL_COUNT]; AtlasPointer *special_aps[CF_SPECIAL_COUNT]; + u8 solidness; // Used when choosing which face is drawn + u8 visual_solidness; // When solidness=0, this tells how it looks like + bool backface_culling; #endif + // List of all block textures that have been used (value is dummy) + // Used for texture atlas making. + // Exists on server too for cleaner code in content_mapnode.cpp. + std::set<std::string> used_texturenames; + + // True if this actually contains non-default data + bool modified; + + /* + Actual data + */ + // Visual definition + enum NodeDrawType drawtype; + float visual_scale; // Misc. scale parameter std::string tname_tiles[6]; std::string tname_inventory; MaterialSpec mspec_special[CF_SPECIAL_COUNT]; u8 alpha; - bool backface_culling; - u8 solidness; // Used when choosing which face is drawn - u8 visual_solidness; // When solidness=0, this tells how it looks like - // List of all block textures that have been used (value is dummy) - // Used for texture atlas making. - // Exists on server too for cleaner code in content_mapnode.cpp. - std::set<std::string> used_texturenames; - + // Post effect color, drawn when the camera is inside the node. + video::SColor post_effect_color; // Type of MapNode::param1 ContentParamType param_type; // True for all ground-like things like stone and mud, false for eg. trees @@ -172,18 +205,14 @@ struct ContentFeatures // Used for texture atlas creation. // Currently only enabled for CONTENT_STONE. bool often_contains_mineral; - // Inventory item string as which the node appears in inventory when dug. // Mineral overrides this. std::string dug_item; - // Extra dug item and its rarity std::string extra_dug_item; s32 extra_dug_item_rarity; - // Initial metadata is cloned from this NodeMetadata *initial_metadata; - // Whether the node is non-liquid, source liquid or flowing liquid enum LiquidType liquid_type; // If the content is liquid, this is the flowing version of the liquid. @@ -194,72 +223,22 @@ struct ContentFeatures // 1 giving almost instantaneous propagation and 7 being // the slowest possible u8 liquid_viscosity; - // Amount of light the node emits u8 light_source; - u32 damage_per_second; - NodeBox selection_box; - MaterialProperties material; - - // NOTE: Move relevant properties to here from elsewhere - void reset() - { - // This isn't exactly complete due to lazyness - // TODO: Make it completely reset everything -#ifndef SERVER - inventory_texture = NULL; - - post_effect_color = video::SColor(0, 0, 0, 0); - 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 = ""; - alpha = 255; - backface_culling = true; - solidness = 2; - visual_solidness = 0; - used_texturenames.clear(); - param_type = CPT_NONE; - is_ground_content = false; - light_propagates = false; - sunlight_propagates = false; - walkable = true; - pointable = true; - diggable = true; - climbable = false; - buildable_to = false; - wall_mounted = false; - air_equivalent = false; - often_contains_mineral = false; - dug_item = ""; - initial_metadata = NULL; - liquid_type = LIQUID_NONE; - liquid_alternative_flowing = CONTENT_IGNORE; - liquid_alternative_source = CONTENT_IGNORE; - liquid_viscosity = 0; - light_source = 0; - damage_per_second = 0; - selection_box = NodeBox(); - material = MaterialProperties(); - } - - ContentFeatures() - { - reset(); - } - - ~ContentFeatures(); + /* + Methods + */ + ContentFeatures(); + ~ContentFeatures(); + void reset(); + void serialize(std::ostream &os); + void deSerialize(std::istream &is, IGameDef *gamedef); + /* Quickhands for simple materials */ @@ -320,6 +299,9 @@ public: Call after updating the texture atlas of a TextureSource. */ virtual void updateTextures(ITextureSource *tsrc)=0; + + virtual void serialize(std::ostream &os)=0; + virtual void deSerialize(std::istream &is, IGameDef *gamedef)=0; }; IWritableNodeDefManager* createNodeDefManager(); diff --git a/src/server.cpp b/src/server.cpp index 54c19be50..698174e0a 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -1016,7 +1016,7 @@ Server::Server( infostream<<"m_nodemgr="<<m_nodemgr<<std::endl; // Initialize default node definitions - content_mapnode_init(NULL, m_nodemgr); + content_mapnode_init(m_nodemgr); // Add default global mod path m_modspaths.push_back(porting::path_data + DIR_DELIM + "mods"); diff --git a/src/test.cpp b/src/test.cpp index 7c9fa9408..c998a97ab 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -1088,7 +1088,7 @@ void run_tests() // Create node definitions IWritableNodeDefManager *nodedef = createNodeDefManager(); - content_mapnode_init(NULL, nodedef); + content_mapnode_init(nodedef); infostream<<"run_tests() started"<<std::endl; TEST(TestUtilities); diff --git a/src/tile.cpp b/src/tile.cpp index b0e1fbf5a..f57abfbb8 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -182,12 +182,15 @@ struct SourceAtlasPointer class SourceImageCache { public: - void insert(const std::string &name, video::IImage *img) + void insert(const std::string &name, video::IImage *img, + bool do_overwrite) { assert(img); core::map<std::string, video::IImage*>::Node *n; n = m_images.find(name); if(n){ + if(!do_overwrite) + return; video::IImage *oldimg = n->getValue(); if(oldimg) oldimg->drop(); @@ -720,7 +723,7 @@ void TextureSource::insertSourceImage(const std::string &name, video::IImage *im assert(get_current_thread_id() == m_main_thread); - m_sourcecache.insert(name, img); + m_sourcecache.insert(name, img, false); #if 0 JMutexAutoLock lock(m_atlaspointer_cache_mutex); diff --git a/src/utility.h b/src/utility.h index ed368b208..7c1fde6f0 100644 --- a/src/utility.h +++ b/src/utility.h @@ -235,6 +235,19 @@ inline u32 readU32(std::istream &is) return readU32((u8*)buf); } +inline void writeS32(std::ostream &os, u32 p) +{ + char buf[4]; + writeS32((u8*)buf, p); + os.write(buf, 4); +} +inline u32 readS32(std::istream &is) +{ + char buf[4]; + is.read(buf, 4); + return readS32((u8*)buf); +} + inline void writeF1000(std::ostream &os, f32 p) { char buf[4]; |