mirror of
				https://github.com/luanti-org/luanti.git
				synced 2025-11-04 01:05:48 +01:00 
			
		
		
		
	Cache liquid alternative IDs (#8053)
This commit is contained in:
		@@ -405,8 +405,8 @@ void MapblockMeshGenerator::prepareLiquidNodeDrawing()
 | 
			
		||||
 | 
			
		||||
	MapNode ntop = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(p.X, p.Y + 1, p.Z));
 | 
			
		||||
	MapNode nbottom = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(p.X, p.Y - 1, p.Z));
 | 
			
		||||
	c_flowing = nodedef->getId(f->liquid_alternative_flowing);
 | 
			
		||||
	c_source = nodedef->getId(f->liquid_alternative_source);
 | 
			
		||||
	c_flowing = f->liquid_alternative_flowing_id;
 | 
			
		||||
	c_source = f->liquid_alternative_source_id;
 | 
			
		||||
	top_is_same_liquid = (ntop.getContent() == c_flowing) || (ntop.getContent() == c_source);
 | 
			
		||||
	draw_liquid_bottom = (nbottom.getContent() != c_flowing) && (nbottom.getContent() != c_source);
 | 
			
		||||
	if (draw_liquid_bottom) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								src/map.cpp
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/map.cpp
									
									
									
									
									
								
							@@ -568,7 +568,7 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
 | 
			
		||||
		switch (liquid_type) {
 | 
			
		||||
			case LIQUID_SOURCE:
 | 
			
		||||
				liquid_level = LIQUID_LEVEL_SOURCE;
 | 
			
		||||
				liquid_kind = m_nodedef->getId(cf.liquid_alternative_flowing);
 | 
			
		||||
				liquid_kind = cf.liquid_alternative_flowing_id;
 | 
			
		||||
				break;
 | 
			
		||||
			case LIQUID_FLOWING:
 | 
			
		||||
				liquid_level = (n0.param2 & LIQUID_LEVEL_MASK);
 | 
			
		||||
@@ -641,8 +641,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 = m_nodedef->getId(cfnb.liquid_alternative_flowing);
 | 
			
		||||
					if (m_nodedef->getId(cfnb.liquid_alternative_flowing) != liquid_kind) {
 | 
			
		||||
						liquid_kind = cfnb.liquid_alternative_flowing_id;
 | 
			
		||||
					if (cfnb.liquid_alternative_flowing_id != liquid_kind) {
 | 
			
		||||
						neutrals[num_neutrals++] = nb;
 | 
			
		||||
					} else {
 | 
			
		||||
						// Do not count bottom source, it will screw things up
 | 
			
		||||
@@ -653,8 +653,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 = m_nodedef->getId(cfnb.liquid_alternative_flowing);
 | 
			
		||||
					if (m_nodedef->getId(cfnb.liquid_alternative_flowing) != liquid_kind) {
 | 
			
		||||
						liquid_kind = cfnb.liquid_alternative_flowing_id;
 | 
			
		||||
					if (cfnb.liquid_alternative_flowing_id != liquid_kind) {
 | 
			
		||||
						neutrals[num_neutrals++] = nb;
 | 
			
		||||
					} else {
 | 
			
		||||
						flows[num_flows++] = nb;
 | 
			
		||||
@@ -680,7 +680,7 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> &modified_blocks,
 | 
			
		||||
			// liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
 | 
			
		||||
			// or the flowing alternative of the first of the surrounding sources (if it's air), so
 | 
			
		||||
			// it's perfectly safe to use liquid_kind here to determine the new node content.
 | 
			
		||||
			new_node_content = m_nodedef->getId(m_nodedef->get(liquid_kind).liquid_alternative_source);
 | 
			
		||||
			new_node_content = m_nodedef->get(liquid_kind).liquid_alternative_source_id;
 | 
			
		||||
		} else if (num_sources >= 1 && sources[0].t != NEIGHBOR_LOWER) {
 | 
			
		||||
			// liquid_kind is set properly, see above
 | 
			
		||||
			max_node_level = new_node_level = LIQUID_LEVEL_MAX;
 | 
			
		||||
 
 | 
			
		||||
@@ -622,10 +622,10 @@ s8 MapNode::setLevel(const NodeDefManager *nodemgr, s16 level)
 | 
			
		||||
		}
 | 
			
		||||
		if (level >= LIQUID_LEVEL_SOURCE) {
 | 
			
		||||
			rest = level - LIQUID_LEVEL_SOURCE;
 | 
			
		||||
			setContent(nodemgr->getId(f.liquid_alternative_source));
 | 
			
		||||
			setContent(f.liquid_alternative_source_id);
 | 
			
		||||
			setParam2(0);
 | 
			
		||||
		} else {
 | 
			
		||||
			setContent(nodemgr->getId(f.liquid_alternative_flowing));
 | 
			
		||||
			setContent(f.liquid_alternative_flowing_id);
 | 
			
		||||
			setParam2((level & LIQUID_LEVEL_MASK) | (getParam2() & ~LIQUID_LEVEL_MASK));
 | 
			
		||||
		}
 | 
			
		||||
	} else if (f.param_type_2 == CPT2_LEVELED) {
 | 
			
		||||
 
 | 
			
		||||
@@ -371,7 +371,9 @@ void ContentFeatures::reset()
 | 
			
		||||
	leveled_max = LEVELED_MAX;
 | 
			
		||||
	liquid_type = LIQUID_NONE;
 | 
			
		||||
	liquid_alternative_flowing = "";
 | 
			
		||||
	liquid_alternative_flowing_id = CONTENT_IGNORE;
 | 
			
		||||
	liquid_alternative_source = "";
 | 
			
		||||
	liquid_alternative_source_id = CONTENT_IGNORE;
 | 
			
		||||
	liquid_viscosity = 0;
 | 
			
		||||
	liquid_renewable = true;
 | 
			
		||||
	liquid_range = LIQUID_LEVEL_MAX+1;
 | 
			
		||||
@@ -1444,6 +1446,10 @@ void NodeDefManager::deSerialize(std::istream &is)
 | 
			
		||||
		getNodeBoxUnion(f.selection_box, f, &m_selection_box_union);
 | 
			
		||||
		fixSelectionBoxIntUnion();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Since liquid_alternative_flowing_id and liquid_alternative_source_id
 | 
			
		||||
	// are not sent, resolve them client-side too.
 | 
			
		||||
	resolveCrossrefs();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1504,15 +1510,28 @@ void NodeDefManager::resetNodeResolveState()
 | 
			
		||||
	m_pending_resolve_callbacks.clear();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NodeDefManager::mapNodeboxConnections()
 | 
			
		||||
static void removeDupes(std::vector<content_t> &list)
 | 
			
		||||
{
 | 
			
		||||
	std::sort(list.begin(), list.end());
 | 
			
		||||
	auto new_end = std::unique(list.begin(), list.end());
 | 
			
		||||
	list.erase(new_end, list.end());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void NodeDefManager::resolveCrossrefs()
 | 
			
		||||
{
 | 
			
		||||
	for (ContentFeatures &f : m_content_features) {
 | 
			
		||||
		if (f.liquid_type != LIQUID_NONE) {
 | 
			
		||||
			f.liquid_alternative_flowing_id = getId(f.liquid_alternative_flowing);
 | 
			
		||||
			f.liquid_alternative_source_id = getId(f.liquid_alternative_source);
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		if (f.drawtype != NDT_NODEBOX || f.node_box.type != NODEBOX_CONNECTED)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		for (const std::string &name : f.connects_to) {
 | 
			
		||||
			getIds(name, f.connects_to_ids);
 | 
			
		||||
		}
 | 
			
		||||
		removeDupes(f.connects_to_ids);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -368,8 +368,10 @@ struct ContentFeatures
 | 
			
		||||
	enum LiquidType liquid_type;
 | 
			
		||||
	// If the content is liquid, this is the flowing version of the liquid.
 | 
			
		||||
	std::string liquid_alternative_flowing;
 | 
			
		||||
	content_t liquid_alternative_flowing_id;
 | 
			
		||||
	// If the content is liquid, this is the source version of the liquid.
 | 
			
		||||
	std::string liquid_alternative_source;
 | 
			
		||||
	content_t liquid_alternative_source_id;
 | 
			
		||||
	// Viscosity for fluid flow, ranging from 1 to 7, with
 | 
			
		||||
	// 1 giving almost instantaneous propagation and 7 being
 | 
			
		||||
	// the slowest possible
 | 
			
		||||
@@ -428,7 +430,7 @@ struct ContentFeatures
 | 
			
		||||
	}
 | 
			
		||||
	bool sameLiquid(const ContentFeatures &f) const{
 | 
			
		||||
		if(!isLiquid() || !f.isLiquid()) return false;
 | 
			
		||||
		return (liquid_alternative_flowing == f.liquid_alternative_flowing);
 | 
			
		||||
		return (liquid_alternative_flowing_id == f.liquid_alternative_flowing_id);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int getGroup(const std::string &group) const
 | 
			
		||||
@@ -641,10 +643,11 @@ public:
 | 
			
		||||
	void resetNodeResolveState();
 | 
			
		||||
 | 
			
		||||
	/*!
 | 
			
		||||
	 * Resolves the IDs to which connecting nodes connect from names.
 | 
			
		||||
	 * Resolves (caches the IDs) cross-references between nodes,
 | 
			
		||||
	 * like liquid alternatives.
 | 
			
		||||
	 * Must be called after node registration has finished!
 | 
			
		||||
	 */
 | 
			
		||||
	void mapNodeboxConnections();
 | 
			
		||||
	void resolveCrossrefs();
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	/*!
 | 
			
		||||
 
 | 
			
		||||
@@ -412,8 +412,8 @@ void Server::init()
 | 
			
		||||
	// Perform pending node name resolutions
 | 
			
		||||
	m_nodedef->runNodeResolveCallbacks();
 | 
			
		||||
 | 
			
		||||
	// unmap node names for connected nodeboxes
 | 
			
		||||
	m_nodedef->mapNodeboxConnections();
 | 
			
		||||
	// unmap node names in cross-references
 | 
			
		||||
	m_nodedef->resolveCrossrefs();
 | 
			
		||||
 | 
			
		||||
	// init the recipe hashes to speed up crafting
 | 
			
		||||
	m_craftdef->initHashes(this);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user