summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Dagsson Moskopp <nils@dieweltistgarnichtso.net>2011-07-14 16:17:50 +0200
committerNils Dagsson Moskopp <nils@dieweltistgarnichtso.net>2011-07-14 16:17:53 +0200
commit4415d95c503f083d871abaf84516f2b6487ecb60 (patch)
treedcbf0e5418e95415a6851dab6350a9449ae1b44c
parent1cdf210e4f01b7221a241cbb911f08bc6ffa75bd (diff)
downloadminetest-4415d95c503f083d871abaf84516f2b6487ecb60.tar.gz
minetest-4415d95c503f083d871abaf84516f2b6487ecb60.tar.bz2
minetest-4415d95c503f083d871abaf84516f2b6487ecb60.zip
* possibly improved water flow, by flyx86
- When flowing liquid starts to flow down, it stops contributing to its neighboring nodes' liquid level (possibly transforming it back to air) - Flowing liquid turns into a source if there are at least 2 adjacent liquid source nodes - If a new liquid flow reaches existing flowing liquid, the existing liquid is now updated properly.
-rw-r--r--src/content_mapnode.cpp2
-rw-r--r--src/map.cpp46
-rw-r--r--src/mapnode.h4
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;