From 143401451c457da5079b2970fe260acea45bd85a Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Sat, 14 May 2016 12:23:15 +0200 Subject: DB::loadBlock copy removal & DB backend cleanup * Remove the copy from db::loadBlock by using a pointer to the destination * cleanup db backend, the child backend doesn't have to set their functions as virtual --- src/map.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 66fabaf87..848d2ef13 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -3442,8 +3442,7 @@ MapBlock* ServerMap::loadBlock(v3s16 blockpos) v2s16 p2d(blockpos.X, blockpos.Z); std::string ret; - - ret = dbase->loadBlock(blockpos); + dbase->loadBlock(blockpos, &ret); if (ret != "") { loadBlock(&ret, blockpos, createSector(p2d), false); return getBlockNoCreateNoEx(blockpos); -- cgit v1.2.3 From ce42ff9cf74ebb8d4b68bc78c95e90ea3db02b78 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Sat, 14 May 2016 11:00:42 +0200 Subject: Implement a PostgreSQL backend --- src/map.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 848d2ef13..03daf4fa8 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -50,6 +50,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #if USE_REDIS #include "database-redis.h" #endif +#if USE_POSTGRESQL +#include "database-postgresql.h" +#endif #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" @@ -3240,6 +3243,10 @@ Database *ServerMap::createDatabase( else if (name == "redis") return new Database_Redis(conf); #endif + #if USE_POSTGRESQL + else if (name == "postgresql") + return new Database_PostgreSQL(conf); + #endif else throw BaseException(std::string("Database backend ") + name + " not supported."); } -- cgit v1.2.3 From 559dd9946988cd35a7c26bcafe7d0f8c42dc547a Mon Sep 17 00:00:00 2001 From: Ekdohibs Date: Mon, 21 Mar 2016 12:58:52 +0100 Subject: Make node timers more efficient --- src/map.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 03daf4fa8..a1f2086ce 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2087,11 +2087,13 @@ NodeTimer Map::getNodeTimer(v3s16 p) return NodeTimer(); } NodeTimer t = block->m_node_timers.get(p_rel); - return t; + NodeTimer nt(t.timeout, t.elapsed, p); + return nt; } -void Map::setNodeTimer(v3s16 p, NodeTimer t) +void Map::setNodeTimer(const NodeTimer &t) { + v3s16 p = t.position; v3s16 blockpos = getNodeBlockPos(p); v3s16 p_rel = p - blockpos*MAP_BLOCKSIZE; MapBlock *block = getBlockNoCreateNoEx(blockpos); @@ -2105,7 +2107,8 @@ void Map::setNodeTimer(v3s16 p, NodeTimer t) <m_node_timers.set(p_rel, t); + NodeTimer nt(t.timeout, t.elapsed, p_rel); + block->m_node_timers.set(nt); } void Map::removeNodeTimer(v3s16 p) -- cgit v1.2.3 From 3c63c3044d5e4ca36c2649c530f31622581d90fd Mon Sep 17 00:00:00 2001 From: kwolekr Date: Fri, 24 Jun 2016 18:15:56 -0400 Subject: Add MapSettingsManager and new mapgen setting script API functions This commit refactors the majority of the Mapgen settings system. - MapgenParams is now owned by MapSettingsManager, itself a part of ServerMap, instead of the EmergeManager. - New Script API functions added: core.get_mapgen_setting core.get_mapgen_setting_noiseparams, core.set_mapgen_setting, and core.set_mapgen_setting_noiseparams. - minetest.get/set_mapgen_params are deprecated by the above new functions. - It is now possible to view and modify any arbitrary mapgen setting from a mod, rather than the base MapgenParams structure. - MapgenSpecificParams has been removed. --- src/map.cpp | 100 ++++++++++++++++-------------------------------------------- 1 file changed, 26 insertions(+), 74 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index a1f2086ce..38f0fa37c 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -2130,11 +2130,15 @@ void Map::removeNodeTimer(v3s16 p) */ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emerge): Map(dout_server, gamedef), + settings_mgr(g_settings, savedir + DIR_DELIM + "map_meta.txt"), m_emerge(emerge), m_map_metadata_changed(true) { verbosestream<map_settings_mgr = &settings_mgr; + /* Try to load map; if not found, create a new one. */ @@ -2170,26 +2174,15 @@ ServerMap::ServerMap(std::string savedir, IGameDef *gamedef, EmergeManager *emer } else { - try{ - // Load map metadata (seed, chunksize) - loadMapMeta(); - } - catch(SettingNotFoundException &e){ - infostream<<"ServerMap: Some metadata not found." - <<" Using default settings."<params.seed; + return getMapgenParams()->seed; } s16 ServerMap::getWaterLevel() { - return m_emerge->params.water_level; + return getMapgenParams()->water_level; } bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data) { - s16 csize = m_emerge->params.chunksize; + s16 csize = getMapgenParams()->chunksize; v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize); v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1); @@ -2287,7 +2287,7 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data) blockpos_over_limit(full_bpmax)) return false; - data->seed = m_emerge->params.seed; + data->seed = getSeed(); data->blockpos_min = bpmin; data->blockpos_max = bpmax; data->blockpos_requested = blockpos; @@ -2905,8 +2905,9 @@ void ServerMap::save(ModifiedState save_level) infostream<<"ServerMap: Saving whole map, this can take time." < &dst) } } -void ServerMap::saveMapMeta() -{ - DSTACK(FUNCTION_NAME); - - createDirs(m_savedir); - - std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt"; - std::ostringstream oss(std::ios_base::binary); - Settings conf; - - m_emerge->params.save(conf); - conf.writeLines(oss); - - oss << "[end_of_params]\n"; - - if(!fs::safeWriteToFile(fullpath, oss.str())) { - errorstream << "ServerMap::saveMapMeta(): " - << "could not write " << fullpath << std::endl; - throw FileNotGoodException("Cannot save chunk metadata"); - } - - m_map_metadata_changed = false; -} - -void ServerMap::loadMapMeta() -{ - DSTACK(FUNCTION_NAME); - - Settings conf; - std::string fullpath = m_savedir + DIR_DELIM + "map_meta.txt"; - - std::ifstream is(fullpath.c_str(), std::ios_base::binary); - if (!is.good()) { - errorstream << "ServerMap::loadMapMeta(): " - "could not open " << fullpath << std::endl; - throw FileNotGoodException("Cannot open map metadata"); - } - - if (!conf.parseConfigLines(is, "[end_of_params]")) { - throw SerializationError("ServerMap::loadMapMeta(): " - "[end_of_params] not found!"); - } - - m_emerge->params.load(conf); - - verbosestream << "ServerMap::loadMapMeta(): seed=" - << m_emerge->params.seed << std::endl; -} - void ServerMap::saveSectorMeta(ServerMapSector *sector) { DSTACK(FUNCTION_NAME); -- cgit v1.2.3 From c071efaa43ad3dcba7d60a7a67e942aae2a7dc83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Juh=C3=A1sz?= Date: Thu, 20 Oct 2016 21:41:38 +0200 Subject: Improved lighting This commit rewrites the procedure that is responsible for light updating. this commit -provides iterative solutions for unlighting and light spreading -introduces a new priority queue-like container for the iteration -creates per-node MapBlock caching to reduce retrieving MapBlocks from the map -calculates with map block positions and in-block relative node coordinates -skips light updating if it is not necessary since the node's new light will be the same as its old light was --- src/map.cpp | 441 +++--------------------------------------------------------- 1 file changed, 15 insertions(+), 426 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 38f0fa37c..1694582db 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mapblock.h" #include "filesys.h" #include "voxel.h" +#include "voxelalgorithms.h" #include "porting.h" #include "serialization.h" #include "nodemetadata.h" @@ -234,7 +235,6 @@ void Map::setNode(v3s16 p, MapNode & n) block->setNodeNoCheck(relpos, n); } - /* Goes recursively through the neighbours of the node. @@ -413,20 +413,6 @@ void Map::unspreadLight(enum LightBank bank, unspreadLight(bank, unlighted_nodes, light_sources, modified_blocks); } -/* - A single-node wrapper of the above -*/ -void Map::unLightNeighbors(enum LightBank bank, - v3s16 pos, u8 lightwas, - std::set & light_sources, - std::map & modified_blocks) -{ - std::map from_nodes; - from_nodes[pos] = lightwas; - - unspreadLight(bank, from_nodes, light_sources, modified_blocks); -} - /* Lights neighbors of from_nodes, collects all them and then goes on recursively. @@ -568,108 +554,6 @@ void Map::spreadLight(enum LightBank bank, spreadLight(bank, lighted_nodes, modified_blocks); } -/* - A single-node source variation of the above. -*/ -void Map::lightNeighbors(enum LightBank bank, - v3s16 pos, - std::map & modified_blocks) -{ - std::set from_nodes; - from_nodes.insert(pos); - spreadLight(bank, from_nodes, modified_blocks); -} - -v3s16 Map::getBrightestNeighbour(enum LightBank bank, v3s16 p) -{ - INodeDefManager *nodemgr = m_gamedef->ndef(); - - v3s16 dirs[6] = { - 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 - }; - - u8 brightest_light = 0; - v3s16 brightest_pos(0,0,0); - bool found_something = false; - - // Loop through 6 neighbors - for(u16 i=0; i<6; i++){ - // Get the position of the neighbor node - v3s16 n2pos = p + dirs[i]; - MapNode n2; - bool is_valid_position; - n2 = getNodeNoEx(n2pos, &is_valid_position); - if (!is_valid_position) - continue; - - if(n2.getLight(bank, nodemgr) > brightest_light || found_something == false){ - brightest_light = n2.getLight(bank, nodemgr); - brightest_pos = n2pos; - found_something = true; - } - } - - if(found_something == false) - throw InvalidPositionException(); - - return brightest_pos; -} - -/* - Propagates sunlight down from a node. - Starting point gets sunlight. - - Returns the lowest y value of where the sunlight went. - - Mud is turned into grass in where the sunlight stops. -*/ -s16 Map::propagateSunlight(v3s16 start, - std::map & modified_blocks) -{ - INodeDefManager *nodemgr = m_gamedef->ndef(); - - s16 y = start.Y; - for(; ; y--) - { - v3s16 pos(start.X, y, start.Z); - - v3s16 blockpos = getNodeBlockPos(pos); - MapBlock *block; - try{ - block = getBlockNoCreate(blockpos); - } - catch(InvalidPositionException &e) - { - break; - } - - v3s16 relpos = pos - blockpos*MAP_BLOCKSIZE; - bool is_valid_position; - MapNode n = block->getNode(relpos, &is_valid_position); - if (!is_valid_position) - break; - - if(nodemgr->get(n).sunlight_propagates) - { - n.setLight(LIGHTBANK_DAY, LIGHT_SUN, nodemgr); - block->setNode(relpos, n); - - modified_blocks[blockpos] = block; - } - else - { - // Sunlight goes no further - break; - } - } - return y + 1; -} - void Map::updateLighting(enum LightBank bank, std::map & a_blocks, std::map & modified_blocks) @@ -922,150 +806,29 @@ void Map::updateLighting(std::map & a_blocks, } } -/* -*/ void Map::addNodeAndUpdate(v3s16 p, MapNode n, std::map &modified_blocks, bool remove_metadata) { INodeDefManager *ndef = m_gamedef->ndef(); - /*PrintInfo(m_dout); - m_dout<<"Map::addNodeAndUpdate(): p=(" - < light_sources; - - /* - Collect old node for rollback - */ + // Collect old node for rollback RollbackNode rollback_oldnode(this, p, m_gamedef); - /* - If there is a node at top and it doesn't have sunlight, - there has not been any sunlight going down. - - Otherwise there probably is. - */ - - bool is_valid_position; - MapNode topnode = getNodeNoEx(toppos, &is_valid_position); - - if(is_valid_position && topnode.getLight(LIGHTBANK_DAY, ndef) != LIGHT_SUN) - node_under_sunlight = false; - - /* - Remove all light that has come out of this node - */ - - enum LightBank banks[] = - { - LIGHTBANK_DAY, - LIGHTBANK_NIGHT - }; - for(s32 i=0; i<2; i++) - { - enum LightBank bank = banks[i]; + // This is needed for updating the lighting + MapNode oldnode = getNodeNoEx(p); - u8 lightwas = getNodeNoEx(p).getLight(bank, ndef); - - // Add the block of the added node to modified_blocks - v3s16 blockpos = getNodeBlockPos(p); - MapBlock * block = getBlockNoCreate(blockpos); - assert(block != NULL); - modified_blocks[blockpos] = block; - - assert(isValidPosition(p)); - - // Unlight neighbours of node. - // This means setting light of all consequent dimmer nodes - // to 0. - // This also collects the nodes at the border which will spread - // light again into this. - unLightNeighbors(bank, p, lightwas, light_sources, modified_blocks); - - n.setLight(bank, 0, ndef); - } - - /* - If node lets sunlight through and is under sunlight, it has - sunlight too. - */ - if(node_under_sunlight && ndef->get(n).sunlight_propagates) - { - n.setLight(LIGHTBANK_DAY, LIGHT_SUN, ndef); - } - - /* - Remove node metadata - */ + // Remove node metadata if (remove_metadata) { removeNodeMetadata(p); } - /* - Set the node on the map - */ - + // Set the node on the map setNode(p, n); - /* - If node is under sunlight and doesn't let sunlight through, - take all sunlighted nodes under it and clear light from them - and from where the light has been spread. - TODO: This could be optimized by mass-unlighting instead - of looping - */ - if(node_under_sunlight && !ndef->get(n).sunlight_propagates) - { - s16 y = p.Y - 1; - for(;; y--){ - //m_dout<<"y="<::iterator i = modified_blocks.begin(); i != modified_blocks.end(); ++i) @@ -1073,9 +836,7 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n, i->second->expireDayNightDiff(); } - /* - Report for rollback - */ + // Report for rollback if(m_gamedef->rollback()) { RollbackNode rollback_newnode(this, p, m_gamedef); @@ -1085,22 +846,23 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n, } /* - Add neighboring liquid nodes and the node itself if it is - liquid (=water node was added) to transform queue. - */ + Add neighboring liquid nodes and this node to transform queue. + (it's vital for the node itself to get updated last, if it was removed.) + */ v3s16 dirs[7] = { - v3s16(0,0,0), // self 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<7; i++) { v3s16 p2 = p + dirs[i]; + bool is_valid_position; MapNode n2 = getNodeNoEx(p2, &is_valid_position); if(is_valid_position && (ndef->get(n2).isLiquid() || n2.getContent() == CONTENT_AIR)) @@ -1110,183 +872,10 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n, } } -/* -*/ void Map::removeNodeAndUpdate(v3s16 p, std::map &modified_blocks) { - INodeDefManager *ndef = m_gamedef->ndef(); - - /*PrintInfo(m_dout); - m_dout<<"Map::removeNodeAndUpdate(): p=(" - < light_sources; - - enum LightBank banks[] = - { - LIGHTBANK_DAY, - LIGHTBANK_NIGHT - }; - for(s32 i=0; i<2; i++) - { - enum LightBank bank = banks[i]; - - /* - Unlight neighbors (in case the node is a light source) - */ - unLightNeighbors(bank, p, - getNodeNoEx(p).getLight(bank, ndef), - light_sources, modified_blocks); - } - - /* - Remove node metadata - */ - - removeNodeMetadata(p); - - /* - Remove the node. - This also clears the lighting. - */ - - MapNode n(replace_material); - setNode(p, n); - - for(s32 i=0; i<2; i++) - { - enum LightBank bank = banks[i]; - - /* - Recalculate lighting - */ - spreadLight(bank, light_sources, modified_blocks); - } - - // Add the block of the removed node to modified_blocks - v3s16 blockpos = getNodeBlockPos(p); - MapBlock * block = getBlockNoCreate(blockpos); - assert(block != NULL); - modified_blocks[blockpos] = block; - - /* - If the removed node was under sunlight, propagate the - sunlight down from it and then light all neighbors - of the propagated blocks. - */ - if(node_under_sunlight) - { - s16 ybottom = propagateSunlight(p, modified_blocks); - /*m_dout<<"Node was under sunlight. " - "Propagating sunlight"; - m_dout<<" -> ybottom="<= ybottom; y--) - { - v3s16 p2(p.X, y, p.Z); - /*m_dout<<"lighting neighbors of node (" - <::iterator - i = modified_blocks.begin(); - i != modified_blocks.end(); ++i) - { - i->second->expireDayNightDiff(); - } - - /* - Report for rollback - */ - if(m_gamedef->rollback()) - { - RollbackNode rollback_newnode(this, p, m_gamedef); - RollbackAction action; - action.setSetNode(p, rollback_oldnode, rollback_newnode); - m_gamedef->rollback()->reportAction(action); - } - - /* - Add neighboring liquid nodes and this node to transform queue. - (it's vital for the node itself to get updated last.) - */ - 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<7; i++) - { - v3s16 p2 = p + dirs[i]; - - bool is_position_valid; - MapNode n2 = getNodeNoEx(p2, &is_position_valid); - if (is_position_valid - && (ndef->get(n2).isLiquid() || n2.getContent() == CONTENT_AIR)) - { - m_transforming_liquid.push_back(p2); - } - } + addNodeAndUpdate(p, MapNode(CONTENT_AIR), modified_blocks, true); } bool Map::addNodeWithEvent(v3s16 p, MapNode n, bool remove_metadata) -- cgit v1.2.3 From be39f61359ad63f2c6d4aea14c1dfd8357eee03f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Juh=C3=A1sz?= Date: Sun, 23 Oct 2016 17:51:13 +0200 Subject: Use node lighting for liquid spreading This commit modifies the liquid transforming procedure to light and unlight nodes instead of whole map blocks. --- src/map.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 1694582db..5a1611c89 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -824,10 +824,15 @@ void Map::addNodeAndUpdate(v3s16 p, MapNode n, } // Set the node on the map + // Ignore light (because calling voxalgo::update_lighting_nodes) + n.setLight(LIGHTBANK_DAY, 0, ndef); + n.setLight(LIGHTBANK_NIGHT, 0, ndef); setNode(p, n); // Update lighting - voxalgo::update_lighting_node(this, ndef, p, oldnode, modified_blocks); + std::vector > oldnodes; + oldnodes.push_back(std::pair(p, oldnode)); + voxalgo::update_lighting_nodes(this, ndef, oldnodes, modified_blocks); for(std::map::iterator i = modified_blocks.begin(); @@ -1224,7 +1229,9 @@ void Map::transformLiquids(std::map &modified_blocks) std::deque must_reflow; // List of MapBlocks that will require a lighting update (due to lava) - std::map lighting_modified_blocks; + std::map lighting_modified_blocks2; + + std::vector > changed_nodes; u32 liquid_loop_max = g_settings->getS32("liquid_loop_max"); u32 loop_max = liquid_loop_max; @@ -1457,6 +1464,10 @@ void Map::transformLiquids(std::map &modified_blocks) } n0.setContent(new_node_content); + // Ignore light (because calling voxalgo::update_lighting_nodes) + n0.setLight(LIGHTBANK_DAY, 0, nodemgr); + n0.setLight(LIGHTBANK_NIGHT, 0, nodemgr); + // Find out whether there is a suspect for this action std::string suspect; if (m_gamedef->rollback()) @@ -1484,9 +1495,10 @@ void Map::transformLiquids(std::map &modified_blocks) 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; + lighting_modified_blocks[block->getPos()] = block;*/ + changed_nodes.push_back(std::pair(p0, n00)); } /* @@ -1515,7 +1527,8 @@ void Map::transformLiquids(std::map &modified_blocks) for (std::deque::iterator iter = must_reflow.begin(); iter != must_reflow.end(); ++iter) m_transforming_liquid.push_back(*iter); - updateLighting(lighting_modified_blocks, modified_blocks); + //updateLighting(lighting_modified_blocks, modified_blocks); + voxalgo::update_lighting_nodes(this, nodemgr, changed_nodes, modified_blocks); /* ---------------------------------------------------------------------- -- cgit v1.2.3 From bcb06aeb8559a295ae4df2ca71b80c74338fb9f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Juh=C3=A1sz?= Date: Tue, 25 Oct 2016 23:04:10 +0200 Subject: Cleanup --- src/map.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 5a1611c89..d03943a16 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1228,9 +1228,6 @@ void Map::transformLiquids(std::map &modified_blocks) // list of nodes that due to viscosity have not reached their max level height std::deque must_reflow; - // List of MapBlocks that will require a lighting update (due to lava) - std::map lighting_modified_blocks2; - std::vector > changed_nodes; u32 liquid_loop_max = g_settings->getS32("liquid_loop_max"); @@ -1272,7 +1269,11 @@ void Map::transformLiquids(std::map &modified_blocks) Collect information about current node */ s8 liquid_level = -1; + // The liquid node which will be placed there if + // the liquid flows into this node. content_t liquid_kind = CONTENT_IGNORE; + // The node which will be placed there if liquid + // can't flow into this node. content_t floodable_node = CONTENT_AIR; const ContentFeatures &cf = nodemgr->get(n0); LiquidType liquid_type = cf.liquid_type; @@ -1494,10 +1495,6 @@ void Map::transformLiquids(std::map &modified_blocks) MapBlock *block = getBlockNoCreateNoEx(blockpos); 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 || - nodemgr->get(n00).light_source != 0) - lighting_modified_blocks[block->getPos()] = block;*/ changed_nodes.push_back(std::pair(p0, n00)); } @@ -1527,7 +1524,6 @@ void Map::transformLiquids(std::map &modified_blocks) for (std::deque::iterator iter = must_reflow.begin(); iter != must_reflow.end(); ++iter) m_transforming_liquid.push_back(*iter); - //updateLighting(lighting_modified_blocks, modified_blocks); voxalgo::update_lighting_nodes(this, nodemgr, changed_nodes, modified_blocks); -- cgit v1.2.3 From 2829742ae8869276f000bdb64a9f14977e70038b Mon Sep 17 00:00:00 2001 From: MillersMan Date: Sun, 27 Nov 2016 21:34:16 +0100 Subject: Map::isValidPosition: Return false instead of throwing exception --- src/map.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index d03943a16..3c135cd48 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -174,7 +174,7 @@ bool Map::isNodeUnderground(v3s16 p) bool Map::isValidPosition(v3s16 p) { v3s16 blockpos = getNodeBlockPos(p); - MapBlock *block = getBlockNoCreate(blockpos); + MapBlock *block = getBlockNoCreateNoEx(blockpos); return (block != NULL); } -- cgit v1.2.3 From cc36f5e99ae46cf2fd370dde8311f139169a4c43 Mon Sep 17 00:00:00 2001 From: MillersMan Date: Sun, 27 Nov 2016 21:46:14 +0100 Subject: Liquids: Preserve flow state if 'ignore' is a neighbour Prevent waterfalls from falling down or streams from flowing away when the source node is in an unloaded block - Nodes near a CONTENT_IGNORE node will be interpreted as if the ignored node is a liquid node that just supports the current state of the nodes in question. --- src/map.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 3c135cd48..28d650276 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -1309,6 +1309,7 @@ void Map::transformLiquids(std::map &modified_blocks) NodeNeighbor neutrals[6]; // nodes that are solid or another kind of liquid int num_neutrals = 0; bool flowing_down = false; + bool ignored_sources = false; for (u16 i = 0; i < 6; i++) { NeighborType nt = NEIGHBOR_SAME_LEVEL; switch (i) { @@ -1336,10 +1337,15 @@ void Map::transformLiquids(std::map &modified_blocks) flowing_down = true; } else { neutrals[num_neutrals++] = nb; - // If neutral below is ignore prevent water spreading outwards - if (nb.t == NEIGHBOR_LOWER && - nb.n.getContent() == CONTENT_IGNORE) - flowing_down = true; + if (nb.n.getContent() == CONTENT_IGNORE) { + // If node below is ignore prevent water from + // spreading outwards and otherwise prevent from + // flowing away as ignore node might be the source + if (nb.t == NEIGHBOR_LOWER) + flowing_down = true; + else + ignored_sources = true; + } } break; case LIQUID_SOURCE: @@ -1392,6 +1398,11 @@ void Map::transformLiquids(std::map &modified_blocks) new_node_content = liquid_kind; else new_node_content = floodable_node; + } else if (ignored_sources && liquid_level >= 0) { + // Maybe there are neighbouring sources that aren't loaded yet + // so prevent flowing away. + new_node_level = liquid_level; + new_node_content = liquid_kind; } else { // no surrounding sources, so get the maximum level that can flow into this node for (u16 i = 0; i < num_flows; i++) { -- cgit v1.2.3 From 9714cdcf4ba51b44cca72e133ec5ef2a3c9f50f6 Mon Sep 17 00:00:00 2001 From: MillersMan Date: Sun, 27 Nov 2016 21:51:40 +0100 Subject: Liquids: Update flow on block load When loading a block add liquid-nodes that might flow away or spread to neighbours to the transforming_liquid queue. --- src/map.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/map.cpp') diff --git a/src/map.cpp b/src/map.cpp index 28d650276..7bb8c4a13 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/mathconstants.h" #include "rollback_interface.h" #include "environment.h" +#include "reflowscan.h" #include "emerge.h" #include "mapgen_v6.h" #include "mg_biome.h" @@ -2905,8 +2906,11 @@ void ServerMap::loadBlock(std::string sectordir, std::string blockfile, block->deSerialize(is, version, true); // If it's a new block, insert it to the map - if(created_new) + if (created_new) { sector->insertBlock(block); + ReflowScan scanner(this, m_emerge->ndef); + scanner.scan(block, &m_transforming_liquid); + } /* Save blocks loaded in old format in new format @@ -2972,8 +2976,11 @@ void ServerMap::loadBlock(std::string *blob, v3s16 p3d, MapSector *sector, bool block->deSerialize(is, version, true); // If it's a new block, insert it to the map - if(created_new) + if (created_new) { sector->insertBlock(block); + ReflowScan scanner(this, m_emerge->ndef); + scanner.scan(block, &m_transforming_liquid); + } /* Save blocks loaded in old format in new format -- cgit v1.2.3