diff options
-rw-r--r-- | src/content_mapnode.cpp | 2 | ||||
-rw-r--r-- | src/map.cpp | 46 | ||||
-rw-r--r-- | src/mapnode.h | 4 |
3 files changed, 44 insertions, 8 deletions
diff --git a/src/content_mapnode.cpp b/src/content_mapnode.cpp index 2e7a240f3..38356599f 100644 --- a/src/content_mapnode.cpp +++ b/src/content_mapnode.cpp @@ -276,6 +276,7 @@ void content_mapnode_init() f->buildable_to = true; f->liquid_type = LIQUID_FLOWING; f->liquid_alternative_flowing = CONTENT_WATER; + f->liquid_alternative_source = CONTENT_WATERSOURCE; i = CONTENT_WATERSOURCE; f = &content_features(i); @@ -307,6 +308,7 @@ void content_mapnode_init() f->liquid_type = LIQUID_SOURCE; f->dug_item = std::string("MaterialItem ")+itos(i)+" 1"; f->liquid_alternative_flowing = CONTENT_WATER; + f->liquid_alternative_source = CONTENT_WATERSOURCE; i = CONTENT_TORCH; f = &content_features(i); diff --git a/src/map.cpp b/src/map.cpp index 0de9cf18e..d3e898357 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1204,16 +1204,24 @@ void Map::removeNodeAndUpdate(v3s16 p, /* Add neighboring liquid nodes to transform queue. + + Also add horizontal neighbors of node on top of removed node + because they could be affected of the water on top flowing + down instead of into them. */ - v3s16 dirs[6] = { + v3s16 dirs[10] = { v3s16(0,0,1), // back v3s16(0,1,0), // top + v3s16(1,1,0), // topright + v3s16(-1,1,0), // topleft + v3s16(0,1,1), // topback + v3s16(0,1,-1), // topfront v3s16(1,0,0), // right v3s16(0,0,-1), // front v3s16(0,-1,0), // bottom v3s16(-1,0,0), // left }; - for(u16 i=0; i<6; i++) + for(u16 i=0; i<10; i++) { try { @@ -1510,6 +1518,9 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks) // Turn possible source into non-source u8 nonsource_c = make_liquid_flowing(n0.d); + // Counts surrounding liquid source blocks + u8 surrounding_sources = 0; + /* If not source, check that some node flows into this one and what is the level of liquid in this one @@ -1547,7 +1558,9 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks) } bool n2_is_source = !content_flowing_liquid(n2.d); s8 n2_liquid_level = 8; - if(n2_is_source == false) + if(n2_is_source) + surrounding_sources++; + else n2_liquid_level = n2.param2 & 0x07; s8 new_liquid_level = -1; @@ -1561,7 +1574,20 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks) } else if(n2_liquid_level > 0) { - new_liquid_level = n2_liquid_level - 1; + // If the neighbor node isn't a source and flows downwards, + // it doesn't flow into this node + if (n2_is_source) + { + new_liquid_level = n2_liquid_level - 1; + } + else + { + // Node below n2 + MapNode n3 = getNodeNoEx(p2 + v3s16(0,-1,0)); + // NOTE: collision of different liquids not yet handled here. + if (content_features(n3.d).liquid_type != LIQUID_FLOWING) + new_liquid_level = n2_liquid_level - 1; + } } if(new_liquid_level > new_liquid_level_max) @@ -1577,9 +1603,14 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks) If liquid level should be something else, update it and add all the neighboring water nodes to the transform queue. */ - if(new_liquid_level_max != liquid_level) + if(new_liquid_level_max != liquid_level || (!is_source && surrounding_sources >= 2)) { - if(new_liquid_level_max == -1) + if (surrounding_sources >= 2) + { + n0.d = content_features(n0.d).liquid_alternative_source; + setNode(p0,n0); + } + else if(new_liquid_level_max == -1) { // Remove water alltoghether n0.d = CONTENT_AIR; @@ -1589,6 +1620,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks) else { n0.param2 = new_liquid_level_max; + liquid_level = new_liquid_level_max; setNode(p0, n0); } @@ -1706,7 +1738,7 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks) } else { - if(liquid_next_level > liquid_level) + if(liquid_next_level > n2_liquid_level) { n2.param2 = liquid_next_level; setNode(p2, n2); diff --git a/src/mapnode.h b/src/mapnode.h index d975a50c4..d4ba0fed5 100644 --- a/src/mapnode.h +++ b/src/mapnode.h @@ -141,8 +141,10 @@ struct ContentFeatures NodeMetadata *initial_metadata; // If the content is liquid, this is the flowing version of the liquid. - // If content is liquid, this is the same content. + // If content is flowing liquid, this is the same content. u8 liquid_alternative_flowing; + // If the content is liquid, this is the source version of the liquid. + u8 liquid_alternative_source; // Amount of light the node emits u8 light_source; |