diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/map.cpp | 70 | ||||
-rw-r--r-- | src/nodedef.cpp | 4 | ||||
-rw-r--r-- | src/nodedef.h | 2 | ||||
-rw-r--r-- | src/script/common/c_content.cpp | 2 |
4 files changed, 46 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; } diff --git a/src/nodedef.cpp b/src/nodedef.cpp index b5ccc3b94..2ebe1c131 100644 --- a/src/nodedef.cpp +++ b/src/nodedef.cpp @@ -233,6 +233,7 @@ void ContentFeatures::reset() diggable = true; climbable = false; buildable_to = false; + floodable = false; rightclickable = true; leveled = 0; liquid_type = LIQUID_NONE; @@ -318,6 +319,7 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const // the protocol version os<<serializeString(mesh); collision_box.serialize(os, protocol_version); + writeU8(os, floodable); } void ContentFeatures::deSerialize(std::istream &is) @@ -388,6 +390,7 @@ void ContentFeatures::deSerialize(std::istream &is) // otherwise changes the protocol version mesh = deSerializeString(is); collision_box.deSerialize(is); + floodable = readU8(is); }catch(SerializationError &e) {}; } @@ -520,6 +523,7 @@ void CNodeDefManager::clear() f.pointable = false; f.diggable = false; f.buildable_to = true; + f.floodable = true; f.is_ground_content = true; // Insert directly into containers content_t c = CONTENT_AIR; diff --git a/src/nodedef.h b/src/nodedef.h index 7a84b0316..8f4942c04 100644 --- a/src/nodedef.h +++ b/src/nodedef.h @@ -229,6 +229,8 @@ struct ContentFeatures bool climbable; // Player can build on these bool buildable_to; + // Liquids flow into and replace node + bool floodable; // Player cannot build to these (placement prediction disabled) bool rightclickable; // Flowing liquid or snow, value = default level diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 36a5c2ddd..62de2c968 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -481,6 +481,8 @@ ContentFeatures read_content_features(lua_State *L, int index) getboolfield(L, index, "climbable", f.climbable); // Player can build on these getboolfield(L, index, "buildable_to", f.buildable_to); + // Liquids flow into and replace node + getboolfield(L, index, "floodable", f.floodable); // Whether the node is non-liquid, source liquid or flowing liquid f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype", ScriptApiNode::es_LiquidType, LIQUID_NONE); |