diff --git a/src/emerge.cpp b/src/emerge.cpp index 608bdb9a97..8cacdea0c8 100644 --- a/src/emerge.cpp +++ b/src/emerge.cpp @@ -737,6 +737,8 @@ void *EmergeThread::run() if (!error) block = finishGen(pos, &bmdata, &modified_blocks); + else + m_map->cancelBlockMake(&bmdata); if (!block || error) action = EMERGE_ERRORED; diff --git a/src/servermap.cpp b/src/servermap.cpp index bdd90523f9..912c91a9af 100644 --- a/src/servermap.cpp +++ b/src/servermap.cpp @@ -201,8 +201,8 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data) { assert(data); s16 csize = getMapgenParams()->chunksize; - v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize); - v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1); + const v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize); + const v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1); if (!m_chunks_in_progress.insert(bpmin).second) return false; @@ -210,11 +210,10 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data) bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info; EMERGE_DBG_OUT("initBlockMake(): " << bpmin << " - " << bpmax); - v3s16 extra_borders(1, 1, 1); - v3s16 full_bpmin = bpmin - extra_borders; - v3s16 full_bpmax = bpmax + extra_borders; + const v3s16 full_bpmin = bpmin - EMERGE_EXTRA_BORDER; + const v3s16 full_bpmax = bpmax + EMERGE_EXTRA_BORDER; - // Do nothing if not inside mapgen limits (+-1 because of neighbors) + // Do nothing if not fully inside mapgen limits if (blockpos_over_mapgen_limit(full_bpmin) || blockpos_over_mapgen_limit(full_bpmax)) return false; @@ -246,6 +245,7 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data) bool ug = m_emerge->isBlockUnderground(p); block->setIsUnderground(ug); } + block->refGrab(); } } @@ -263,13 +263,28 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data) return true; } +void ServerMap::cancelBlockMake(BlockMakeData *data) +{ + assert(data->vmanip); // no vmanip = initBlockMake did not complete (caller mistake) + + const v3s16 full_bpmin = data->blockpos_min - EMERGE_EXTRA_BORDER; + const v3s16 full_bpmax = data->blockpos_max + EMERGE_EXTRA_BORDER; + for (s16 x = full_bpmin.X; x <= full_bpmax.X; x++) + for (s16 z = full_bpmin.Z; z <= full_bpmax.Z; z++) + for (s16 y = full_bpmin.Y; y <= full_bpmax.Y; y++) { + MapBlock *block = getBlockNoCreateNoEx(v3s16(x, y, z)); + if (block) + block->refDrop(); + } +} + void ServerMap::finishBlockMake(BlockMakeData *data, std::map *changed_blocks, u32 now) { assert(data); assert(changed_blocks); - v3s16 bpmin = data->blockpos_min; - v3s16 bpmax = data->blockpos_max; + const v3s16 bpmin = data->blockpos_min; + const v3s16 bpmax = data->blockpos_max; bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info; EMERGE_DBG_OUT("finishBlockMake(): " << bpmin << " - " << bpmax); @@ -306,17 +321,30 @@ void ServerMap::finishBlockMake(BlockMakeData *data, MOD_REASON_EXPIRE_IS_AIR); } - // Note: this does not apply to the extra border area - for (s16 x = bpmin.X; x <= bpmax.X; x++) - for (s16 z = bpmin.Z; z <= bpmax.Z; z++) - for (s16 y = bpmin.Y; y <= bpmax.Y; y++) { - MapBlock *block = getBlockNoCreateNoEx(v3s16(x, y, z)); - if (!block) - continue; + const v3s16 full_bpmin = bpmin - EMERGE_EXTRA_BORDER; + const v3s16 full_bpmax = bpmax + EMERGE_EXTRA_BORDER; - block->setGenerated(true); - // Set timestamp to ensure correct application of LBMs and other stuff - block->setTimestampNoChangedFlag(now); + v3s16 bp; + for (bp.X = full_bpmin.X; bp.X <= full_bpmax.X; bp.X++) + for (bp.Z = full_bpmin.Z; bp.Z <= full_bpmax.Z; bp.Z++) + for (bp.Y = full_bpmin.Y; bp.Y <= full_bpmax.Y; bp.Y++) { + MapBlock *block = getBlockNoCreateNoEx(bp); + if (!block) { + warningstream << "ServerMap::finishBlockMake: block " << bp + << " disappeared during generation" << std::endl; + continue; + } + + block->refDrop(); + + /* Border blocks are grabbed during + generation but mustn't be marked generated. */ + if (bp >= bpmin && bp <= bpmax) { + block->setGenerated(true); + // Set timestamp to ensure correct application + // of LBMs and other stuff. + block->setTimestampNoChangedFlag(now); + } } m_chunks_in_progress.erase(bpmin); diff --git a/src/servermap.h b/src/servermap.h index 861d64dbe1..d44823de2a 100644 --- a/src/servermap.h +++ b/src/servermap.h @@ -67,6 +67,7 @@ public: /// @param now current game time void finishBlockMake(BlockMakeData *data, std::map *changed_blocks, u32 now); + void cancelBlockMake(BlockMakeData *data); /* Get a block from somewhere. @@ -169,6 +170,9 @@ protected: private: friend class ModApiMapgen; // for m_transforming_liquid + // extra border area during mapgen (in blocks) + constexpr static v3s16 EMERGE_EXTRA_BORDER{1, 1, 1}; + // Emerge manager EmergeManager *m_emerge;