From 8f42a8be0c760322207287e50b624bd3d388a2e1 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 15 Aug 2011 02:04:56 +0300 Subject: [PATCH 1/9] lava! --- data/lava.png | Bin 0 -> 357 bytes src/constants.h | 3 - src/content_mapblock.cpp | 152 ++++++++++++++++++++------------------- src/content_mapnode.cpp | 109 +++++++++++++++++++++++++++- src/content_mapnode.h | 8 +++ src/environment.cpp | 29 ++++++++ src/environment.h | 1 + src/game.cpp | 14 ++-- src/mapgen.cpp | 10 +++ src/mapnode.cpp | 5 +- src/mapnode.h | 13 +++- 11 files changed, 255 insertions(+), 89 deletions(-) create mode 100644 data/lava.png diff --git a/data/lava.png b/data/lava.png new file mode 100644 index 0000000000000000000000000000000000000000..cb02ada1318a66f6af28e2095b73d79b103080ed GIT binary patch literal 357 zcmV-r0h<1aP)%zc|Y{#jr1B^>+6sq2y-UJm_blockpos*MAP_BLOCKSIZE; - // Flowing water material - video::SMaterial material_water1; - material_water1.setFlag(video::EMF_LIGHTING, false); - material_water1.setFlag(video::EMF_BACK_FACE_CULLING, false); - material_water1.setFlag(video::EMF_BILINEAR_FILTER, false); - material_water1.setFlag(video::EMF_FOG_ENABLE, true); - material_water1.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; - AtlasPointer pa_water1 = g_texturesource->getTexture( - g_texturesource->getTextureId("water.png")); - material_water1.setTexture(0, pa_water1.atlas); - // New-style leaves material video::SMaterial material_leaves1; material_leaves1.setFlag(video::EMF_LIGHTING, false); @@ -337,30 +326,40 @@ void mapblock_mesh_generate_special(MeshMakeData *data, collector.append(material, vertices, 4, indices, 6); } /* - Add flowing water to mesh + Add flowing liquid to mesh */ - else if(n.getContent() == CONTENT_WATER) + else if(content_features(n).liquid_type == LIQUID_FLOWING) { - bool top_is_water = false; + assert(content_features(n).special_material); + video::SMaterial &liquid_material = + *content_features(n).special_material; + assert(content_features(n).special_atlas); + AtlasPointer &pa_liquid1 = + *content_features(n).special_atlas; + + bool top_is_same_liquid = false; MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); - if(ntop.getContent() == CONTENT_WATER || ntop.getContent() == CONTENT_WATERSOURCE) - top_is_water = true; + content_t c_flowing = content_features(n).liquid_alternative_flowing; + content_t c_source = content_features(n).liquid_alternative_source; + if(ntop.getContent() == c_flowing || ntop.getContent() == c_source) + top_is_same_liquid = true; u8 l = 0; // Use the light of the node on top if possible if(content_features(ntop).param_type == CPT_LIGHT) l = decode_light(ntop.getLightBlend(data->m_daynight_ratio)); - // Otherwise use the light of this node (the water) + // Otherwise use the light of this node (the liquid) else l = decode_light(n.getLightBlend(data->m_daynight_ratio)); - video::SColor c = MapBlock_LightColor(WATER_ALPHA, l); + video::SColor c = MapBlock_LightColor( + content_features(n).vertex_alpha, l); - // Neighbor water levels (key = relative position) + // Neighbor liquid levels (key = relative position) // Includes current node core::map neighbor_levels; core::map neighbor_contents; core::map neighbor_flags; - const u8 neighborflag_top_is_water = 0x01; + const u8 neighborflag_top_is_same_liquid = 0x01; v3s16 neighbor_dirs[9] = { v3s16(0,0,0), v3s16(0,0,1), @@ -384,19 +383,20 @@ void mapblock_mesh_generate_special(MeshMakeData *data, { content = n2.getContent(); - if(n2.getContent() == CONTENT_WATERSOURCE) - level = (-0.5+node_water_level) * BS; - else if(n2.getContent() == CONTENT_WATER) + 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_water_level) * BS; + * node_liquid_level) * BS; // Check node above neighbor. // NOTE: This doesn't get executed if neighbor // doesn't exist p2.Y += 1; n2 = data->m_vmanip.getNodeNoEx(blockpos_nodes + p2); - if(n2.getContent() == CONTENT_WATERSOURCE || n2.getContent() == CONTENT_WATER) - flags |= neighborflag_top_is_water; + if(n2.getContent() == c_source || + n2.getContent() == c_flowing) + flags |= neighborflag_top_is_same_liquid; } neighbor_levels.insert(neighbor_dirs[i], level); @@ -404,10 +404,10 @@ void mapblock_mesh_generate_special(MeshMakeData *data, neighbor_flags.insert(neighbor_dirs[i], flags); } - //float water_level = (-0.5 + ((float)n.param2 + 0.5) / 8.0) * BS; - //float water_level = neighbor_levels[v3s16(0,0,0)]; + //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 waters) + // Corner heights (average between four liquids) f32 corner_levels[4]; v3s16 halfdirs[4] = { @@ -426,13 +426,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data, v3s16 neighbordir = cornerdir - halfdirs[j]; u8 content = neighbor_contents[neighbordir]; // Special case for source nodes - if(content == CONTENT_WATERSOURCE) + if(content == c_source) { - cornerlevel = (-0.5+node_water_level)*BS; + cornerlevel = (-0.5+node_liquid_level)*BS; valid_count = 1; break; } - else if(content == CONTENT_WATER) + else if(content == c_flowing) { cornerlevel += neighbor_levels[neighbordir]; valid_count++; @@ -469,24 +469,24 @@ void mapblock_mesh_generate_special(MeshMakeData *data, v3s16 dir = side_dirs[i]; /* - If our topside is water and neighbor's topside - is water, don't draw side face + If our topside is liquid and neighbor's topside + is liquid, don't draw side face */ - if(top_is_water && - neighbor_flags[dir] & neighborflag_top_is_water) + if(top_is_same_liquid && + neighbor_flags[dir] & neighborflag_top_is_same_liquid) continue; u8 neighbor_content = neighbor_contents[dir]; - // Don't draw face if neighbor is not air or water + // Don't draw face if neighbor is not air or liquid if(neighbor_content != CONTENT_AIR - && neighbor_content != CONTENT_WATER) + && neighbor_content != c_source) continue; - bool neighbor_is_water = (neighbor_content == CONTENT_WATER); + bool neighbor_is_liquid = (neighbor_content == c_source); - // Don't draw any faces if neighbor is water and top is water - if(neighbor_is_water == true && top_is_water == false) + // Don't draw any faces if neighbor is liquid and top is liquid + if(neighbor_is_liquid == true && top_is_same_liquid == false) continue; video::S3DVertex vertices[4] = @@ -496,20 +496,20 @@ void mapblock_mesh_generate_special(MeshMakeData *data, 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),*/ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y1()), + pa_liquid1.x0(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y1()), + pa_liquid1.x1(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y0()), + pa_liquid1.x1(), pa_liquid1.y0()), video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y0()), + pa_liquid1.x0(), pa_liquid1.y0()), }; /* - If our topside is water, set upper border of face + If our topside is liquid, set upper border of face at upper border of node */ - if(top_is_water) + if(top_is_same_liquid) { vertices[2].Pos.Y = 0.5*BS; vertices[3].Pos.Y = 0.5*BS; @@ -524,16 +524,16 @@ void mapblock_mesh_generate_special(MeshMakeData *data, } /* - If neighbor is water, lower border of face is corner - water levels + If neighbor is liquid, lower border of face is corner + liquid levels */ - if(neighbor_is_water) + if(neighbor_is_liquid) { 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 + If neighbor is not liquid, lower border of face is lower border of node */ else @@ -558,14 +558,14 @@ void mapblock_mesh_generate_special(MeshMakeData *data, u16 indices[] = {0,1,2,2,3,0}; // Add to mesh collector - collector.append(material_water1, vertices, 4, indices, 6); + collector.append(liquid_material, vertices, 4, indices, 6); } /* Generate top side, if appropriate */ - if(top_is_water == false) + if(top_is_same_liquid == false) { video::S3DVertex vertices[4] = { @@ -574,13 +574,13 @@ void mapblock_mesh_generate_special(MeshMakeData *data, 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),*/ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y1()), + pa_liquid1.x0(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y1()), + pa_liquid1.x1(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y0()), + pa_liquid1.x1(), pa_liquid1.y0()), video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y0()), + pa_liquid1.x0(), pa_liquid1.y0()), }; // This fixes a strange bug @@ -588,7 +588,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data, for(s32 i=0; i<4; i++) { - //vertices[i].Pos.Y += water_level; + //vertices[i].Pos.Y += liquid_level; //vertices[i].Pos.Y += neighbor_levels[v3s16(0,0,0)]; s32 j = corner_resolve[i]; vertices[i].Pos.Y += corner_levels[j]; @@ -597,29 +597,33 @@ void mapblock_mesh_generate_special(MeshMakeData *data, u16 indices[] = {0,1,2,2,3,0}; // Add to mesh collector - collector.append(material_water1, vertices, 4, indices, 6); + collector.append(liquid_material, vertices, 4, indices, 6); } } /* Add water sources to mesh if using new style */ - else if(n.getContent() == CONTENT_WATERSOURCE && new_style_water) + else if(content_features(n).liquid_type == LIQUID_SOURCE + && new_style_water) { - //bool top_is_water = false; + assert(content_features(n).special_material); + video::SMaterial &liquid_material = + *content_features(n).special_material; + assert(content_features(n).special_atlas); + AtlasPointer &pa_liquid1 = + *content_features(n).special_atlas; + bool top_is_air = false; MapNode n = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x,y+1,z)); - /*if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE) - top_is_water = true;*/ if(n.getContent() == CONTENT_AIR) top_is_air = true; - /*if(top_is_water == true) - continue;*/ if(top_is_air == false) continue; u8 l = decode_light(n.getLightBlend(data->m_daynight_ratio)); - video::SColor c = MapBlock_LightColor(WATER_ALPHA, l); + video::SColor c = MapBlock_LightColor( + content_features(n).vertex_alpha, l); video::S3DVertex vertices[4] = { @@ -628,24 +632,24 @@ void mapblock_mesh_generate_special(MeshMakeData *data, 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),*/ video::S3DVertex(-BS/2,0,BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y1()), + pa_liquid1.x0(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y1()), + pa_liquid1.x1(), pa_liquid1.y1()), video::S3DVertex(BS/2,0,-BS/2, 0,0,0, c, - pa_water1.x1(), pa_water1.y0()), + pa_liquid1.x1(), pa_liquid1.y0()), video::S3DVertex(-BS/2,0,-BS/2, 0,0,0, c, - pa_water1.x0(), pa_water1.y0()), + pa_liquid1.x0(), pa_liquid1.y0()), }; for(s32 i=0; i<4; i++) { - vertices[i].Pos.Y += (-0.5+node_water_level)*BS; + 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_water1, vertices, 4, indices, 6); + collector.append(liquid_material, vertices, 4, indices, 6); } /* Add leaves if using new style diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index b164033db..3c1353467 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -372,6 +372,21 @@ void content_mapnode_init() f->liquid_type = LIQUID_FLOWING; f->liquid_alternative_flowing = CONTENT_WATER; f->liquid_alternative_source = CONTENT_WATERSOURCE; + f->vertex_alpha = 160; + if(f->special_material == NULL && g_texturesource) + { + // Flowing water material + f->special_material = new video::SMaterial; + f->special_material->setFlag(video::EMF_LIGHTING, false); + f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false); + f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false); + f->special_material->setFlag(video::EMF_FOG_ENABLE, true); + f->special_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + AtlasPointer *pa_water1 = new AtlasPointer(g_texturesource->getTexture( + g_texturesource->getTextureId("water.png"))); + f->special_material->setTexture(0, pa_water1->atlas); + f->special_atlas = pa_water1; + } i = CONTENT_WATERSOURCE; f = &content_features(i); @@ -389,7 +404,7 @@ void content_mapnode_init() if(g_texturesource) t.texture = g_texturesource->getTexture("water.png"); - t.alpha = WATER_ALPHA; + t.alpha = 160; t.material_type = MATERIAL_ALPHA_VERTEX; t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING; f->setAllTiles(t); @@ -404,6 +419,98 @@ void content_mapnode_init() f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; f->liquid_alternative_flowing = CONTENT_WATER; f->liquid_alternative_source = CONTENT_WATERSOURCE; + f->vertex_alpha = 160; + if(f->special_material == NULL && g_texturesource) + { + // Flowing water material + f->special_material = new video::SMaterial; + f->special_material->setFlag(video::EMF_LIGHTING, false); + f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false); + f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false); + f->special_material->setFlag(video::EMF_FOG_ENABLE, true); + f->special_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + AtlasPointer *pa_water1 = new AtlasPointer(g_texturesource->getTexture( + g_texturesource->getTextureId("water.png"))); + f->special_material->setTexture(0, pa_water1->atlas); + f->special_atlas = pa_water1; + } + + i = CONTENT_LAVA; + f = &content_features(i); + f->setInventoryTextureCube("lava.png", "lava.png", "lava.png"); + f->param_type = CPT_LIGHT; + f->light_propagates = false; + f->light_source = LIGHT_MAX-1; + f->solidness = 0; // Drawn separately, makes no faces + f->walkable = false; + f->pointable = false; + f->diggable = false; + f->buildable_to = true; + f->liquid_type = LIQUID_FLOWING; + f->liquid_alternative_flowing = CONTENT_LAVA; + f->liquid_alternative_source = CONTENT_LAVASOURCE; + if(f->special_material == NULL && g_texturesource) + { + // Flowing lava material + f->special_material = new video::SMaterial; + f->special_material->setFlag(video::EMF_LIGHTING, false); + f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false); + f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false); + f->special_material->setFlag(video::EMF_FOG_ENABLE, true); + f->special_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + AtlasPointer *pa_lava1 = new AtlasPointer( + g_texturesource->getTexture( + g_texturesource->getTextureId("lava.png"))); + f->special_material->setTexture(0, pa_lava1->atlas); + f->special_atlas = pa_lava1; + } + + i = CONTENT_LAVASOURCE; + f = &content_features(i); + f->setInventoryTextureCube("lava.png", "lava.png", "lava.png"); + if(new_style_water) + { + f->solidness = 0; // drawn separately, makes no faces + } + else // old style + { + f->solidness = 2; + + TileSpec t; + if(g_texturesource) + t.texture = g_texturesource->getTexture("lava.png"); + + //t.alpha = 255; + //t.material_type = MATERIAL_ALPHA_VERTEX; + //t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING; + f->setAllTiles(t); + } + f->param_type = CPT_LIGHT; + f->light_propagates = false; + f->light_source = LIGHT_MAX-1; + f->walkable = false; + f->pointable = false; + f->diggable = false; + f->buildable_to = true; + f->liquid_type = LIQUID_SOURCE; + f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; + f->liquid_alternative_flowing = CONTENT_LAVA; + f->liquid_alternative_source = CONTENT_LAVASOURCE; + if(f->special_material == NULL && g_texturesource) + { + // Flowing lava material + f->special_material = new video::SMaterial; + f->special_material->setFlag(video::EMF_LIGHTING, false); + f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false); + f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false); + f->special_material->setFlag(video::EMF_FOG_ENABLE, true); + f->special_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + AtlasPointer *pa_lava1 = new AtlasPointer( + g_texturesource->getTexture( + g_texturesource->getTextureId("lava.png"))); + f->special_material->setTexture(0, pa_lava1->atlas); + f->special_atlas = pa_lava1; + } i = CONTENT_TORCH; f = &content_features(i); diff --git a/src/content_mapnode.h b/src/content_mapnode.h index 9643db746..1f6292ba4 100644 --- a/src/content_mapnode.h +++ b/src/content_mapnode.h @@ -37,16 +37,24 @@ MapNode mapnode_translate_to_internal(MapNode n_from, u8 version); // 0x000...0x07f (0...127): param2 is fully usable // 126 and 127 are reserved. // Use these sparingly, only when the extra space in param2 might be needed. +// Add a space when there is unused space between numbers. #define CONTENT_STONE 0 + #define CONTENT_WATER 2 #define CONTENT_TORCH 3 + #define CONTENT_WATERSOURCE 9 + #define CONTENT_SIGN_WALL 14 #define CONTENT_CHEST 15 #define CONTENT_FURNACE 16 + #define CONTENT_FENCE 21 + #define CONTENT_RAIL 30 #define CONTENT_LADDER 31 +#define CONTENT_LAVA 32 +#define CONTENT_LAVASOURCE 33 // 0x800...0xfff (2048...4095): higher 4 bytes of param2 are not usable #define CONTENT_GRASS 0x800 //1 diff --git a/src/environment.cpp b/src/environment.cpp index 2349852f2..05efe9eea 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -1632,6 +1632,28 @@ void ClientEnvironment::step(float dtime) } } + /* + A quick draft of lava damage + */ + if(m_lava_hurt_interval.step(dtime, 1.0)) + { + v3f pf = lplayer->getPosition(); + v3s16 p1 = floatToInt(pf + v3f(0, BS*0.0, 0), BS); + MapNode n1 = m_map->getNodeNoEx(p1); + v3s16 p2 = floatToInt(pf + v3f(0, BS*1.5, 0), BS); + MapNode n2 = m_map->getNodeNoEx(p2); + if(n1.getContent() == CONTENT_LAVA || + n1.getContent() == CONTENT_LAVASOURCE || + n2.getContent() == CONTENT_LAVA || + n2.getContent() == CONTENT_LAVASOURCE) + { + ClientEnvEvent event; + event.type = CEE_PLAYER_DAMAGE; + event.player_damage.amount = 4*2; // 4 hearts + m_client_event_queue.push_back(event); + } + } + /* Stuff that can be done in an arbitarily large dtime */ @@ -1917,6 +1939,13 @@ void ClientEnvironment::drawPostFx(video::IVideoDriver* driver, v3f camera_pos) core::rect rect(0,0, ss.X, ss.Y); driver->draw2DRectangle(video::SColor(64, 100, 100, 200), rect); } + else if(content_features(n).solidness == 2 && + g_settings.getBool("free_move") == false) + { + v2u32 ss = driver->getScreenSize(); + core::rect rect(0,0, ss.X, ss.Y); + driver->draw2DRectangle(video::SColor(255, 0, 0, 0), rect); + } } #endif // #ifndef SERVER diff --git a/src/environment.h b/src/environment.h index b6767858a..d9248d2ad 100644 --- a/src/environment.h +++ b/src/environment.h @@ -416,6 +416,7 @@ private: core::map m_active_objects; Queue m_client_event_queue; IntervalLimiter m_active_object_light_update_interval; + IntervalLimiter m_lava_hurt_interval; }; #endif diff --git a/src/game.cpp b/src/game.cpp index a3a5f424a..c740ed252 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -2315,6 +2315,13 @@ void the_game( // 0-1ms guienv->drawAll(); + /* + Environment post fx + */ + { + client.getEnv()->drawPostFx(driver, camera_position); + } + /* Draw hotbar */ @@ -2337,13 +2344,6 @@ void the_game( NULL); } - /* - Environment post fx - */ - { - client.getEnv()->drawPostFx(driver, camera_position); - } - /* End scene */ diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 9effa8ac6..4285378a0 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -1817,6 +1817,16 @@ void make_block(BlockMakeData *data) if(noisebuf_ground_wetness.get(x,y,z) < -0.6) vmanip.m_data[i] = MapNode(CONTENT_GRAVEL); } + else if(noisebuf_ground_crumbleness.get(x,y,z) < + -2.3 + MYMIN(0.1 * sqrt(MYMAX(0, -y)), 1.5)) + { + vmanip.m_data[i] = MapNode(CONTENT_LAVASOURCE); + for(s16 x1=-1; x1<=1; x1++) + for(s16 y1=-1; y1<=1; y1++) + for(s16 z1=-1; z1<=1; z1++) + data->transforming_liquid.push_back( + v3s16(p2d.X+x1, y+y1, p2d.Y+z1)); + } } data->vmanip->m_area.add_y(em, i, -1); diff --git a/src/mapnode.cpp b/src/mapnode.cpp index 9a8a73295..956abe5c7 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -30,8 +30,9 @@ with this program; if not, write to the Free Software Foundation, Inc., ContentFeatures::~ContentFeatures() { - if(initial_metadata) - delete initial_metadata; + delete initial_metadata; + delete special_material; + delete special_atlas; } void ContentFeatures::setTexture(u16 i, std::string name, u8 alpha) diff --git a/src/mapnode.h b/src/mapnode.h index 389fa1c9c..7ac050ef0 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -128,8 +128,8 @@ struct ContentFeatures bool pointable; // Player can dig these bool diggable; - // Player can climb these - bool climbable; + // Player can climb these + bool climbable; // Player can build on these bool buildable_to; // Whether the node has no liquid, source liquid or flowing liquid @@ -153,6 +153,11 @@ struct ContentFeatures content_t liquid_alternative_flowing; // If the content is liquid, this is the source version of the liquid. content_t liquid_alternative_source; + // Used currently for flowing liquids + u8 vertex_alpha; + // Special irrlicht material, used sometimes + video::SMaterial *special_material; + AtlasPointer *special_atlas; // Amount of light the node emits u8 light_source; @@ -181,6 +186,10 @@ struct ContentFeatures dug_item = ""; initial_metadata = NULL; liquid_alternative_flowing = CONTENT_IGNORE; + liquid_alternative_source = CONTENT_IGNORE; + vertex_alpha = 255; + special_material = NULL; + special_atlas = NULL; light_source = 0; digging_properties.clear(); } From 472585a7e8e511e7cc210ad8e2c17cad9dfeb186 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 15 Aug 2011 11:49:39 +0300 Subject: [PATCH 2/9] tuned lava/universal damage code --- src/content_mapnode.cpp | 2 ++ src/environment.cpp | 24 +++++++++++++++++------- src/mapnode.h | 3 +++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index 3c1353467..f3d5b9f59 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -449,6 +449,7 @@ void content_mapnode_init() f->liquid_type = LIQUID_FLOWING; f->liquid_alternative_flowing = CONTENT_LAVA; f->liquid_alternative_source = CONTENT_LAVASOURCE; + f->damage_per_second = 4*2; if(f->special_material == NULL && g_texturesource) { // Flowing lava material @@ -496,6 +497,7 @@ void content_mapnode_init() f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; f->liquid_alternative_flowing = CONTENT_LAVA; f->liquid_alternative_source = CONTENT_LAVASOURCE; + f->damage_per_second = 4*2; if(f->special_material == NULL && g_texturesource) { // Flowing lava material diff --git a/src/environment.cpp b/src/environment.cpp index 05efe9eea..d6ff4d826 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -1638,18 +1638,28 @@ void ClientEnvironment::step(float dtime) if(m_lava_hurt_interval.step(dtime, 1.0)) { v3f pf = lplayer->getPosition(); - v3s16 p1 = floatToInt(pf + v3f(0, BS*0.0, 0), BS); + + // Feet, middle and head + v3s16 p1 = floatToInt(pf + v3f(0, BS*0.1, 0), BS); MapNode n1 = m_map->getNodeNoEx(p1); - v3s16 p2 = floatToInt(pf + v3f(0, BS*1.5, 0), BS); + v3s16 p2 = floatToInt(pf + v3f(0, BS*0.8, 0), BS); MapNode n2 = m_map->getNodeNoEx(p2); - if(n1.getContent() == CONTENT_LAVA || - n1.getContent() == CONTENT_LAVASOURCE || - n2.getContent() == CONTENT_LAVA || - n2.getContent() == CONTENT_LAVASOURCE) + v3s16 p3 = floatToInt(pf + v3f(0, BS*1.6, 0), BS); + MapNode n3 = m_map->getNodeNoEx(p2); + + u32 damage_per_second = 0; + damage_per_second = MYMAX(damage_per_second, + content_features(n1).damage_per_second); + damage_per_second = MYMAX(damage_per_second, + content_features(n2).damage_per_second); + damage_per_second = MYMAX(damage_per_second, + content_features(n3).damage_per_second); + + if(damage_per_second != 0) { ClientEnvEvent event; event.type = CEE_PLAYER_DAMAGE; - event.player_damage.amount = 4*2; // 4 hearts + event.player_damage.amount = damage_per_second; m_client_event_queue.push_back(event); } } diff --git a/src/mapnode.h b/src/mapnode.h index 7ac050ef0..3101a9fc1 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -164,6 +164,8 @@ struct ContentFeatures // Digging properties for different tools DiggingPropertiesList digging_properties; + + u32 damage_per_second; // NOTE: Move relevant properties to here from elsewhere @@ -192,6 +194,7 @@ struct ContentFeatures special_atlas = NULL; light_source = 0; digging_properties.clear(); + damage_per_second = 0; } ContentFeatures() From 8ab77f41531ab325a9dc027070e317d3651888dd Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 15 Aug 2011 11:51:33 +0300 Subject: [PATCH 3/9] Added #define WATER_ALPHA in content_mapnode.cpp --- src/content_mapnode.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index f3d5b9f59..a3c8d4b0a 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapnode.h" #include "content_nodemeta.h" +#define WATER_ALPHA 160 + // TODO: Get rid of these and set up some attributes like toughness, // fluffyness, and a funciton to calculate time and durability loss // (and sound? and whatever else) from them @@ -372,7 +374,7 @@ void content_mapnode_init() f->liquid_type = LIQUID_FLOWING; f->liquid_alternative_flowing = CONTENT_WATER; f->liquid_alternative_source = CONTENT_WATERSOURCE; - f->vertex_alpha = 160; + f->vertex_alpha = WATER_ALPHA; if(f->special_material == NULL && g_texturesource) { // Flowing water material @@ -404,7 +406,7 @@ void content_mapnode_init() if(g_texturesource) t.texture = g_texturesource->getTexture("water.png"); - t.alpha = 160; + t.alpha = WATER_ALPHA; t.material_type = MATERIAL_ALPHA_VERTEX; t.material_flags &= ~MATERIAL_FLAG_BACKFACE_CULLING; f->setAllTiles(t); @@ -419,7 +421,7 @@ void content_mapnode_init() f->dug_item = std::string("MaterialItem2 ")+itos(i)+" 1"; f->liquid_alternative_flowing = CONTENT_WATER; f->liquid_alternative_source = CONTENT_WATERSOURCE; - f->vertex_alpha = 160; + f->vertex_alpha = WATER_ALPHA; if(f->special_material == NULL && g_texturesource) { // Flowing water material From 4b85608e306c4b0bf74f5f132cdd61257eb7e9c1 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 15 Aug 2011 11:56:16 +0300 Subject: [PATCH 4/9] modified mapgen to generate less lava --- src/mapgen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapgen.cpp b/src/mapgen.cpp index 4285378a0..aac2fc228 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -1818,7 +1818,7 @@ void make_block(BlockMakeData *data) vmanip.m_data[i] = MapNode(CONTENT_GRAVEL); } else if(noisebuf_ground_crumbleness.get(x,y,z) < - -2.3 + MYMIN(0.1 * sqrt(MYMAX(0, -y)), 1.5)) + -3.0 + MYMIN(0.1 * sqrt(MYMAX(0, -y)), 1.5)) { vmanip.m_data[i] = MapNode(CONTENT_LAVASOURCE); for(s16 x1=-1; x1<=1; x1++) From 0c7e7f49980851c4290817dae7a9c1cdc4a93b65 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 15 Aug 2011 12:08:41 +0300 Subject: [PATCH 5/9] Non-vertex-alpha texture material for lava --- src/content_mapnode.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index a3c8d4b0a..7174a8a4b 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -460,7 +460,7 @@ void content_mapnode_init() f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false); f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false); f->special_material->setFlag(video::EMF_FOG_ENABLE, true); - f->special_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + f->special_material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; AtlasPointer *pa_lava1 = new AtlasPointer( g_texturesource->getTexture( g_texturesource->getTextureId("lava.png"))); @@ -508,7 +508,7 @@ void content_mapnode_init() f->special_material->setFlag(video::EMF_BACK_FACE_CULLING, false); f->special_material->setFlag(video::EMF_BILINEAR_FILTER, false); f->special_material->setFlag(video::EMF_FOG_ENABLE, true); - f->special_material->MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; + f->special_material->MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; AtlasPointer *pa_lava1 = new AtlasPointer( g_texturesource->getTexture( g_texturesource->getTextureId("lava.png"))); From e57754868f63d5c104a582c1d2c5d1885a87c049 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 15 Aug 2011 15:11:00 +0300 Subject: [PATCH 6/9] Hopefully fixed msvc "'sqrt' : ambiguous call to overloaded function" --- src/mapgen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mapgen.cpp b/src/mapgen.cpp index aac2fc228..0018b9919 100644 --- a/src/mapgen.cpp +++ b/src/mapgen.cpp @@ -1818,7 +1818,7 @@ void make_block(BlockMakeData *data) vmanip.m_data[i] = MapNode(CONTENT_GRAVEL); } else if(noisebuf_ground_crumbleness.get(x,y,z) < - -3.0 + MYMIN(0.1 * sqrt(MYMAX(0, -y)), 1.5)) + -3.0 + MYMIN(0.1 * sqrt((float)MYMAX(0, -y)), 1.5)) { vmanip.m_data[i] = MapNode(CONTENT_LAVASOURCE); for(s16 x1=-1; x1<=1; x1++) From ad408f269c3ce17d3ff188919ecdc600b22caabc Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 15 Aug 2011 16:57:57 +0300 Subject: [PATCH 7/9] Add lava to creative inventory (hmm, we're shortly running out of creative inventory space) --- src/content_craft.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/content_craft.cpp b/src/content_craft.cpp index 481ea1a63..20ab5f069 100644 --- a/src/content_craft.cpp +++ b/src/content_craft.cpp @@ -486,6 +486,7 @@ void craft_set_creative_inventory(Player *player) CONTENT_CHEST, CONTENT_FURNACE, CONTENT_SIGN_WALL, + CONTENT_LAVASOURCE, CONTENT_IGNORE }; From 296748d32e0bc31c1517faf1de59ba734a4909a4 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 15 Aug 2011 17:45:35 +0300 Subject: [PATCH 8/9] Fixed liquid mesh generation --- src/content_mapblock.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp index ab5cc1b54..c0845ec57 100644 --- a/src/content_mapblock.cpp +++ b/src/content_mapblock.cpp @@ -386,8 +386,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 +404,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,29 +418,46 @@ 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) + // 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]; valid_count++; } else if(content == CONTENT_AIR) + { + air_count++; + } + /*// Air is liquid level 0 + else if(content == CONTENT_AIR) { cornerlevel += -0.5*BS; valid_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; } From dc4ac0b96fc11d4620f04d6068e681ab793a5d92 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Mon, 15 Aug 2011 18:49:44 +0300 Subject: [PATCH 9/9] small fix to transformLiquids --- src/map.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/map.cpp b/src/map.cpp index dc4459263..9d67c8282 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1564,6 +1564,11 @@ void Map::transformLiquids(core::map & modified_blocks) while(m_transforming_liquid.size() != 0) { + // This should be done here so that it is done when continue is used + if(loopcount >= initial_size * 3) + break; + loopcount++; + /* Get a queued transforming liquid node */ @@ -1779,12 +1784,6 @@ void Map::transformLiquids(core::map & modified_blocks) } break; } - - loopcount++; - //if(loopcount >= 100000) - if(loopcount >= initial_size * 10) { - break; - } } //dstream<<"Map::transformLiquids(): loopcount="<