aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaliy <numzer0@yandex.ru>2020-05-21 00:52:10 +0300
committerGitHub <noreply@github.com>2020-05-20 22:52:10 +0100
commit82e41378937378667cdbdda3ea9e8c1acb5822ea (patch)
tree07a5e04b6979b42e763640b8dccec6e7c8855854
parent42fcfb75e85523a2fa5d99a453c2fabc2c04c0f6 (diff)
downloadminetest-82e41378937378667cdbdda3ea9e8c1acb5822ea.tar.gz
minetest-82e41378937378667cdbdda3ea9e8c1acb5822ea.tar.bz2
minetest-82e41378937378667cdbdda3ea9e8c1acb5822ea.zip
Cache liquid alternative IDs (#8053)
-rw-r--r--src/client/content_mapblock.cpp4
-rw-r--r--src/map.cpp12
-rw-r--r--src/mapnode.cpp4
-rw-r--r--src/nodedef.cpp21
-rw-r--r--src/nodedef.h9
-rw-r--r--src/server.cpp4
6 files changed, 38 insertions, 16 deletions
diff --git a/src/client/content_mapblock.cpp b/src/client/content_mapblock.cpp
index bf1b4c7d6..50efd2e40 100644
--- a/src/client/content_mapblock.cpp
+++ b/src/client/content_mapblock.cpp
@@ -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) {
diff --git a/src/map.cpp b/src/map.cpp
index 5f1b984a4..677cbc869 100644
--- a/src/map.cpp
+++ b/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;
diff --git a/src/mapnode.cpp b/src/mapnode.cpp
index 24d62b504..dcf1f6d6e 100644
--- a/src/mapnode.cpp
+++ b/src/mapnode.cpp
@@ -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) {
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index b8211fceb..cb841e544 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -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);
}
}
diff --git a/src/nodedef.h b/src/nodedef.h
index 497e7ee0e..0992001e1 100644
--- a/src/nodedef.h
+++ b/src/nodedef.h
@@ -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:
/*!
diff --git a/src/server.cpp b/src/server.cpp
index b28c30e1e..92870f972 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -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);