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)
|
if (!error)
|
||||||
block = finishGen(pos, &bmdata, &modified_blocks);
|
block = finishGen(pos, &bmdata, &modified_blocks);
|
||||||
|
else
|
||||||
|
m_map->cancelBlockMake(&bmdata);
|
||||||
if (!block || error)
|
if (!block || error)
|
||||||
action = EMERGE_ERRORED;
|
action = EMERGE_ERRORED;
|
||||||
|
|
||||||
|
|
|
@ -201,8 +201,8 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data)
|
||||||
{
|
{
|
||||||
assert(data);
|
assert(data);
|
||||||
s16 csize = getMapgenParams()->chunksize;
|
s16 csize = getMapgenParams()->chunksize;
|
||||||
v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize);
|
const v3s16 bpmin = EmergeManager::getContainingChunk(blockpos, csize);
|
||||||
v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1);
|
const v3s16 bpmax = bpmin + v3s16(1, 1, 1) * (csize - 1);
|
||||||
|
|
||||||
if (!m_chunks_in_progress.insert(bpmin).second)
|
if (!m_chunks_in_progress.insert(bpmin).second)
|
||||||
return false;
|
return false;
|
||||||
|
@ -210,11 +210,10 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data)
|
||||||
bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
|
bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
|
||||||
EMERGE_DBG_OUT("initBlockMake(): " << bpmin << " - " << bpmax);
|
EMERGE_DBG_OUT("initBlockMake(): " << bpmin << " - " << bpmax);
|
||||||
|
|
||||||
v3s16 extra_borders(1, 1, 1);
|
const v3s16 full_bpmin = bpmin - EMERGE_EXTRA_BORDER;
|
||||||
v3s16 full_bpmin = bpmin - extra_borders;
|
const v3s16 full_bpmax = bpmax + EMERGE_EXTRA_BORDER;
|
||||||
v3s16 full_bpmax = bpmax + extra_borders;
|
|
||||||
|
|
||||||
// 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) ||
|
if (blockpos_over_mapgen_limit(full_bpmin) ||
|
||||||
blockpos_over_mapgen_limit(full_bpmax))
|
blockpos_over_mapgen_limit(full_bpmax))
|
||||||
return false;
|
return false;
|
||||||
|
@ -246,6 +245,7 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data)
|
||||||
bool ug = m_emerge->isBlockUnderground(p);
|
bool ug = m_emerge->isBlockUnderground(p);
|
||||||
block->setIsUnderground(ug);
|
block->setIsUnderground(ug);
|
||||||
}
|
}
|
||||||
|
block->refGrab();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,13 +263,28 @@ bool ServerMap::initBlockMake(v3s16 blockpos, BlockMakeData *data)
|
||||||
return true;
|
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,
|
void ServerMap::finishBlockMake(BlockMakeData *data,
|
||||||
std::map<v3s16, MapBlock*> *changed_blocks, u32 now)
|
std::map<v3s16, MapBlock*> *changed_blocks, u32 now)
|
||||||
{
|
{
|
||||||
assert(data);
|
assert(data);
|
||||||
assert(changed_blocks);
|
assert(changed_blocks);
|
||||||
v3s16 bpmin = data->blockpos_min;
|
const v3s16 bpmin = data->blockpos_min;
|
||||||
v3s16 bpmax = data->blockpos_max;
|
const v3s16 bpmax = data->blockpos_max;
|
||||||
|
|
||||||
bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
|
bool enable_mapgen_debug_info = m_emerge->enable_mapgen_debug_info;
|
||||||
EMERGE_DBG_OUT("finishBlockMake(): " << bpmin << " - " << bpmax);
|
EMERGE_DBG_OUT("finishBlockMake(): " << bpmin << " - " << bpmax);
|
||||||
|
@ -306,17 +321,30 @@ void ServerMap::finishBlockMake(BlockMakeData *data,
|
||||||
MOD_REASON_EXPIRE_IS_AIR);
|
MOD_REASON_EXPIRE_IS_AIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: this does not apply to the extra border area
|
const v3s16 full_bpmin = bpmin - EMERGE_EXTRA_BORDER;
|
||||||
for (s16 x = bpmin.X; x <= bpmax.X; x++)
|
const v3s16 full_bpmax = bpmax + EMERGE_EXTRA_BORDER;
|
||||||
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;
|
|
||||||
|
|
||||||
block->setGenerated(true);
|
v3s16 bp;
|
||||||
// Set timestamp to ensure correct application of LBMs and other stuff
|
for (bp.X = full_bpmin.X; bp.X <= full_bpmax.X; bp.X++)
|
||||||
block->setTimestampNoChangedFlag(now);
|
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);
|
m_chunks_in_progress.erase(bpmin);
|
||||||
|
|
|
@ -67,6 +67,7 @@ public:
|
||||||
/// @param now current game time
|
/// @param now current game time
|
||||||
void finishBlockMake(BlockMakeData *data,
|
void finishBlockMake(BlockMakeData *data,
|
||||||
std::map<v3s16, MapBlock*> *changed_blocks, u32 now);
|
std::map<v3s16, MapBlock*> *changed_blocks, u32 now);
|
||||||
|
void cancelBlockMake(BlockMakeData *data);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get a block from somewhere.
|
Get a block from somewhere.
|
||||||
|
@ -169,6 +170,9 @@ protected:
|
||||||
private:
|
private:
|
||||||
friend class ModApiMapgen; // for m_transforming_liquid
|
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
|
// Emerge manager
|
||||||
EmergeManager *m_emerge;
|
EmergeManager *m_emerge;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue