mirror of
https://github.com/luanti-org/luanti.git
synced 2025-09-15 18:57:08 +00:00
Prevent MapBlocks in generation from being unloaded (#16339)
This change prevents issues arising from partial generation of MapChunks, which are liable to be regenerated completely when ungenerated MapBlocks within are encountered. Co-authored-by: Po Lu <luangruo@yahoo.com> Co-authored-by: sfan5 <sfan5@live.de>
This commit is contained in:
parent
2ef085967d
commit
e86d2fea8d
3 changed files with 52 additions and 18 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<v3s16, MapBlock*> *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);
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
/// @param now current game time
|
||||
void finishBlockMake(BlockMakeData *data,
|
||||
std::map<v3s16, MapBlock*> *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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue