diff options
Diffstat (limited to 'src/map.cpp')
-rw-r--r-- | src/map.cpp | 70 |
1 files changed, 38 insertions, 32 deletions
diff --git a/src/map.cpp b/src/map.cpp index ceebd40a3..ac29cfeee 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1654,10 +1654,10 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) loop_max *= m_transforming_liquid_loop_count_multiplier; #endif - while(m_transforming_liquid.size() != 0) + while (m_transforming_liquid.size() != 0) { // This should be done here so that it is done when continue is used - if(loopcount >= initial_size || loopcount >= loop_max) + if (loopcount >= initial_size || loopcount >= loop_max) break; loopcount++; @@ -1674,21 +1674,24 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) */ s8 liquid_level = -1; content_t liquid_kind = CONTENT_IGNORE; - LiquidType liquid_type = nodemgr->get(n0).liquid_type; + content_t floodable_node = CONTENT_AIR; + ContentFeatures cf = nodemgr->get(n0); + LiquidType liquid_type = cf.liquid_type; switch (liquid_type) { case LIQUID_SOURCE: liquid_level = LIQUID_LEVEL_SOURCE; - liquid_kind = nodemgr->getId(nodemgr->get(n0).liquid_alternative_flowing); + liquid_kind = nodemgr->getId(cf.liquid_alternative_flowing); break; case LIQUID_FLOWING: liquid_level = (n0.param2 & LIQUID_LEVEL_MASK); liquid_kind = n0.getContent(); break; case LIQUID_NONE: - // if this is an air node, it *could* be transformed into a liquid. otherwise, - // continue with the next node. - if (n0.getContent() != CONTENT_AIR) + // if this node is 'floodable', it *could* be transformed + // into a liquid, otherwise, continue with the next node. + if (!cf.floodable) continue; + floodable_node = n0.getContent(); liquid_kind = CONTENT_AIR; break; } @@ -1718,9 +1721,10 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) } v3s16 npos = p0 + dirs[i]; NodeNeighbor nb(getNodeNoEx(npos), nt, npos); + ContentFeatures cfnb = nodemgr->get(nb.n); switch (nodemgr->get(nb.n.getContent()).liquid_type) { case LIQUID_NONE: - if (nb.n.getContent() == CONTENT_AIR) { + if (cfnb.floodable) { airs[num_airs++] = nb; // if the current node is a water source the neighbor // should be enqueded for transformation regardless of whether the @@ -1738,8 +1742,8 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) case LIQUID_SOURCE: // if this node is not (yet) of a liquid type, choose the first liquid type we encounter if (liquid_kind == CONTENT_AIR) - liquid_kind = nodemgr->getId(nodemgr->get(nb.n).liquid_alternative_flowing); - if (nodemgr->getId(nodemgr->get(nb.n).liquid_alternative_flowing) != liquid_kind) { + liquid_kind = nodemgr->getId(cfnb.liquid_alternative_flowing); + if (nodemgr->getId(cfnb.liquid_alternative_flowing) != liquid_kind) { neutrals[num_neutrals++] = nb; } else { // Do not count bottom source, it will screw things up @@ -1750,8 +1754,8 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) case LIQUID_FLOWING: // if this node is not (yet) of a liquid type, choose the first liquid type we encounter if (liquid_kind == CONTENT_AIR) - liquid_kind = nodemgr->getId(nodemgr->get(nb.n).liquid_alternative_flowing); - if (nodemgr->getId(nodemgr->get(nb.n).liquid_alternative_flowing) != liquid_kind) { + liquid_kind = nodemgr->getId(cfnb.liquid_alternative_flowing); + if (nodemgr->getId(cfnb.liquid_alternative_flowing) != liquid_kind) { neutrals[num_neutrals++] = nb; } else { flows[num_flows++] = nb; @@ -1770,8 +1774,8 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) s8 max_node_level = -1; u8 range = nodemgr->get(liquid_kind).liquid_range; - if (range > LIQUID_LEVEL_MAX+1) - range = LIQUID_LEVEL_MAX+1; + if (range > LIQUID_LEVEL_MAX + 1) + range = LIQUID_LEVEL_MAX + 1; if ((num_sources >= 2 && nodemgr->get(liquid_kind).liquid_renewable) || liquid_type == LIQUID_SOURCE) { // liquid_kind will be set to either the flowing alternative of the node (if it's a liquid) @@ -1780,10 +1784,11 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) new_node_content = nodemgr->getId(nodemgr->get(liquid_kind).liquid_alternative_source); } else if (num_sources >= 1 && sources[0].t != NEIGHBOR_LOWER) { // liquid_kind is set properly, see above - new_node_content = liquid_kind; max_node_level = new_node_level = LIQUID_LEVEL_MAX; - if (new_node_level < (LIQUID_LEVEL_MAX+1-range)) - new_node_content = CONTENT_AIR; + if (new_node_level >= (LIQUID_LEVEL_MAX + 1 - range)) + new_node_content = liquid_kind; + else + new_node_content = floodable_node; } else { // no surrounding sources, so get the maximum level that can flow into this node for (u16 i = 0; i < num_flows; i++) { @@ -1794,16 +1799,16 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) max_node_level = LIQUID_LEVEL_MAX; if (nb_liquid_level + WATER_DROP_BOOST < LIQUID_LEVEL_MAX) max_node_level = nb_liquid_level + WATER_DROP_BOOST; - } else if (nb_liquid_level > max_node_level) + } else if (nb_liquid_level > max_node_level) { max_node_level = nb_liquid_level; + } break; case NEIGHBOR_LOWER: break; case NEIGHBOR_SAME_LEVEL: if ((flows[i].n.param2 & LIQUID_FLOW_DOWN_MASK) != LIQUID_FLOW_DOWN_MASK && - nb_liquid_level > 0 && nb_liquid_level - 1 > max_node_level) { + nb_liquid_level > 0 && nb_liquid_level - 1 > max_node_level) max_node_level = nb_liquid_level - 1; - } break; } } @@ -1821,23 +1826,25 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) new_node_level = liquid_level + 1; if (new_node_level != max_node_level) must_reflow.push_back(p0); - } else + } else { new_node_level = max_node_level; + } - if (max_node_level >= (LIQUID_LEVEL_MAX+1-range)) + if (max_node_level >= (LIQUID_LEVEL_MAX + 1 - range)) new_node_content = liquid_kind; else - new_node_content = CONTENT_AIR; + new_node_content = floodable_node; } /* check if anything has changed. if not, just continue with the next node. */ - if (new_node_content == n0.getContent() && (nodemgr->get(n0.getContent()).liquid_type != LIQUID_FLOWING || - ((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level && - ((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK) - == flowing_down))) + if (new_node_content == n0.getContent() && + (nodemgr->get(n0.getContent()).liquid_type != LIQUID_FLOWING || + ((n0.param2 & LIQUID_LEVEL_MASK) == (u8)new_node_level && + ((n0.param2 & LIQUID_FLOW_DOWN_MASK) == LIQUID_FLOW_DOWN_MASK) + == flowing_down))) continue; @@ -1857,11 +1864,10 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) // Find out whether there is a suspect for this action std::string suspect; - if(m_gamedef->rollback()) { + if (m_gamedef->rollback()) suspect = m_gamedef->rollback()->getSuspect(p0, 83, 1); - } - if(m_gamedef->rollback() && !suspect.empty()){ + if (m_gamedef->rollback() && !suspect.empty()) { // Blame suspect RollbackScopeActor rollback_scope(m_gamedef->rollback(), suspect, true); // Get old node for rollback @@ -1880,10 +1886,10 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks) v3s16 blockpos = getNodeBlockPos(p0); MapBlock *block = getBlockNoCreateNoEx(blockpos); - if(block != NULL) { + if (block != NULL) { modified_blocks[blockpos] = block; // If new or old node emits light, MapBlock requires lighting update - if(nodemgr->get(n0).light_source != 0 || + if (nodemgr->get(n0).light_source != 0 || nodemgr->get(n00).light_source != 0) lighting_modified_blocks[block->getPos()] = block; } |