Do not emerge blocks in the active_object_send_range_blocks range (#14152)

The active object range is about active objects (not blocks). Activate blocks (and hence any object "in" them) in the cone define by the active object range (and fov) when they are loaded (i.e. visible), otherwise ignore them.
This commit is contained in:
lhofhansl 2023-12-29 14:18:06 -08:00 committed by GitHub
parent 22a1653702
commit c99196d363
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 53 additions and 15 deletions

@ -335,12 +335,14 @@ void ActiveBlockList::update(std::vector<PlayerSAO*> &active_players,
s16 active_block_range, s16 active_block_range,
s16 active_object_range, s16 active_object_range,
std::set<v3s16> &blocks_removed, std::set<v3s16> &blocks_removed,
std::set<v3s16> &blocks_added) std::set<v3s16> &blocks_added,
std::set<v3s16> &extra_blocks_added)
{ {
/* /*
Create the new list Create the new list
*/ */
std::set<v3s16> newlist = m_forceloaded_list; std::set<v3s16> newlist = m_forceloaded_list;
std::set<v3s16> extralist;
m_abm_list = m_forceloaded_list; m_abm_list = m_forceloaded_list;
for (const PlayerSAO *playersao : active_players) { for (const PlayerSAO *playersao : active_players) {
v3s16 pos = getNodeBlockPos(floatToInt(playersao->getBasePosition(), BS)); v3s16 pos = getNodeBlockPos(floatToInt(playersao->getBasePosition(), BS));
@ -360,29 +362,52 @@ void ActiveBlockList::update(std::vector<PlayerSAO*> &active_players,
playersao->getEyePosition(), playersao->getEyePosition(),
camera_dir, camera_dir,
playersao->getFov(), playersao->getFov(),
newlist); extralist);
} }
} }
/*
Find out which blocks on the old list are not on the new list
*/
// Go through old list
for (v3s16 p : m_list) {
// If not on new list, it's been removed
if (newlist.find(p) == newlist.end())
blocks_removed.insert(p);
}
/* /*
Find out which blocks on the new list are not on the old list Find out which blocks on the new list are not on the old list
*/ */
// Go through new list
for (v3s16 p : newlist) { for (v3s16 p : newlist) {
// also remove duplicate blocks from the extra list
extralist.erase(p);
// If not on old list, it's been added // If not on old list, it's been added
if (m_list.find(p) == m_list.end()) if (m_list.find(p) == m_list.end())
blocks_added.insert(p); blocks_added.insert(p);
} }
/*
Find out which blocks on the extra list are not on the old list
*/
for (v3s16 p : extralist) {
// also make sure newlist has all blocks
newlist.insert(p);
// If not on old list, it's been added
if (m_list.find(p) == m_list.end())
extra_blocks_added.insert(p);
}
/*
Find out which blocks on the old list are not on the new + extra list
*/
std::set_difference(m_list.begin(), m_list.end(), newlist.begin(), newlist.end(),
std::inserter(blocks_removed, blocks_removed.end()));
/*
Some sanity checks
*/
assert(newlist.size() >= extralist.size());
assert(blocks_removed.size() <= m_list.size());
if (!blocks_added.empty())
assert(newlist.count(*blocks_added.begin()) > 0);
if (!extra_blocks_added.empty()) {
assert(newlist.count(*extra_blocks_added.begin()) > 0);
assert(blocks_added.count(*extra_blocks_added.begin()) == 0);
}
if (!blocks_removed.empty()) {
assert(newlist.count(*blocks_removed.begin()) == 0);
assert(m_list.count(*blocks_removed.begin()) > 0);
}
/* /*
Update m_list Update m_list
@ -1403,8 +1428,9 @@ void ServerEnvironment::step(float dtime)
g_settings->getS16("active_block_range"); g_settings->getS16("active_block_range");
std::set<v3s16> blocks_removed; std::set<v3s16> blocks_removed;
std::set<v3s16> blocks_added; std::set<v3s16> blocks_added;
std::set<v3s16> extra_blocks_added;
m_active_blocks.update(players, active_block_range, active_object_range, m_active_blocks.update(players, active_block_range, active_object_range,
blocks_removed, blocks_added); blocks_removed, blocks_added, extra_blocks_added);
/* /*
Handle removed blocks Handle removed blocks
@ -1440,6 +1466,17 @@ void ServerEnvironment::step(float dtime)
activateBlock(block); activateBlock(block);
} }
for (const v3s16 &p: extra_blocks_added) {
// only activate if the block is already loaded
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
if (!block) {
m_active_blocks.remove(p);
continue;
}
activateBlock(block);
}
// Some blocks may be removed again by the code above so do this here // Some blocks may be removed again by the code above so do this here
m_active_block_gauge->set(m_active_blocks.size()); m_active_block_gauge->set(m_active_blocks.size());

@ -168,7 +168,8 @@ public:
s16 active_block_range, s16 active_block_range,
s16 active_object_range, s16 active_object_range,
std::set<v3s16> &blocks_removed, std::set<v3s16> &blocks_removed,
std::set<v3s16> &blocks_added); std::set<v3s16> &blocks_added,
std::set<v3s16> &extra_blocks_added);
bool contains(v3s16 p) const { bool contains(v3s16 p) const {
return (m_list.find(p) != m_list.end()); return (m_list.find(p) != m_list.end());