}
/*
- Add neighboring liquid nodes to transform queue.
+ Add neighboring liquid nodes and this node to transform queue.
+ (it's vital for the node itself to get updated last.)
*/
- v3s16 dirs[10] = {
+ v3s16 dirs[7] = {
v3s16(0,0,1), // back
v3s16(0,1,0), // top
v3s16(1,0,0), // right
v3s16(0,0,-1), // front
v3s16(0,-1,0), // bottom
v3s16(-1,0,0), // left
+ v3s16(0,0,0), // self
};
- for(u16 i=0; i<10; i++)
+ for(u16 i=0; i<7; i++)
{
try
{
Collect information about current node
*/
s8 liquid_level = -1;
- u8 liquid_kind;
+ u8 liquid_kind = CONTENT_IGNORE;
LiquidType liquid_type = content_features(n0.d).liquid_type;
switch (liquid_type) {
case LIQUID_SOURCE:
v3s16( 1, 0, 0), // right
v3s16(-1, 0, 0), // left
v3s16( 0, 0, 1), // back
- v3s16( 0, 0,-1) // front
+ v3s16( 0, 0,-1), // front
};
NodeNeighbor sources[6]; // surrounding sources
int num_sources = 0;
int num_flows = 0;
NodeNeighbor airs[6]; // surrounding air
int num_airs = 0;
- NodeNeighbor neutrals[6]; // nodes that are solid, another kind of liquid
+ NodeNeighbor neutrals[6]; // nodes that are solid or another kind of liquid
int num_neutrals = 0;
bool flowing_down = false;
for (u16 i = 0; i < 6; i++) {
case LIQUID_NONE:
if (nb.n.d == CONTENT_AIR) {
airs[num_airs++] = nb;
- // if the current nodes happens to be a flowing node, it will start to flow down here.
+ // if the current node happens to be a flowing node, it will start to flow down here.
if (nb.t == NEIGHBOR_LOWER)
flowing_down = true;
} else {
break;
case LIQUID_FLOWING:
// if this node is not (yet) of a liquid type, choose the first liquid type we encounter
- // (while ignoring flowing liquids at the lowest level, which cannot flow into this node)
- if (liquid_kind == CONTENT_AIR && ((nb.n.param2 & LIQUID_LEVEL_MASK) > 0))
+ if (liquid_kind == CONTENT_AIR)
liquid_kind = content_features(nb.n.d).liquid_alternative_flowing;
if (content_features(nb.n.d).liquid_alternative_flowing != liquid_kind) {
neutrals[num_neutrals++] = nb;
} else {
- // order flowing neighbors by liquid level descending
- int insert_at = 0;
- while (insert_at < num_flows && ((flows[insert_at].n.param2 & LIQUID_LEVEL_MASK) >
- (nb.n.param2 & LIQUID_LEVEL_MASK))) {
- insert_at++;
- }
- flows[insert_at] = nb;
- num_flows++;
+ flows[num_flows++] = nb;
if (nb.t == NEIGHBOR_LOWER)
flowing_down = true;
}
break;
}
}
+ // don't flow as far in open terrain - if there isn't at least one adjacent solid block,
+ // substract another unit from the resulting water level.
+ if (!flowing_down && new_node_level >= 1) {
+ bool at_wall = false;
+ for (u16 i = 0; i < num_neutrals; i++) {
+ if (neutrals[i].t == NEIGHBOR_SAME_LEVEL) {
+ at_wall = true;
+ break;
+ }
+ }
+ if (!at_wall)
+ new_node_level -= 1;
+ }
+
if (new_node_level >= 0)
new_node_content = liquid_kind;
else
check if anything has changed. if not, just continue with the next node.
*/
if (new_node_content == n0.d && (content_features(n0.d).liquid_type != LIQUID_FLOWING ||
- ((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level) &&
+ ((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level &&
((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK)
- == flowing_down))
+ == flowing_down)))
continue;
+
/*
update the current node
*/
n0.d = new_node_content;
if (content_features(n0.d).liquid_type == LIQUID_FLOWING) {
// set level to last 3 bits, flowing down bit to 4th bit
- n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK);
+ n0.param2 = (flowing_down ? LIQUID_FLOW_DOWN_MASK : 0x00) | (new_node_level & LIQUID_LEVEL_MASK);
} else {
n0.param2 = 0;
}
if(block != NULL)
modified_blocks.insert(blockpos, block);
+ /*
+ enqueue neighbors for update if neccessary
+ */
switch (content_features(n0.d).liquid_type) {
case LIQUID_SOURCE:
// make sure source flows into all neighboring nodes
loopcount++;
//if(loopcount >= 100000)
- if(loopcount >= initial_size * 1) {
+ if(loopcount >= initial_size * 10) {
break;
}
}