From c99196d363d3337b7b7c6392cd6bfb8846a7ed2b Mon Sep 17 00:00:00 2001 From: lhofhansl Date: Fri, 29 Dec 2023 14:18:06 -0800 Subject: [PATCH] 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. --- src/serverenvironment.cpp | 65 ++++++++++++++++++++++++++++++--------- src/serverenvironment.h | 3 +- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index 810456b0d..26b0dd1fa 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -335,12 +335,14 @@ void ActiveBlockList::update(std::vector &active_players, s16 active_block_range, s16 active_object_range, std::set &blocks_removed, - std::set &blocks_added) + std::set &blocks_added, + std::set &extra_blocks_added) { /* Create the new list */ std::set newlist = m_forceloaded_list; + std::set extralist; m_abm_list = m_forceloaded_list; for (const PlayerSAO *playersao : active_players) { v3s16 pos = getNodeBlockPos(floatToInt(playersao->getBasePosition(), BS)); @@ -360,29 +362,52 @@ void ActiveBlockList::update(std::vector &active_players, playersao->getEyePosition(), camera_dir, 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 */ - // Go through new list 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 (m_list.find(p) == m_list.end()) 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 @@ -1403,8 +1428,9 @@ void ServerEnvironment::step(float dtime) g_settings->getS16("active_block_range"); std::set blocks_removed; std::set blocks_added; + std::set extra_blocks_added; 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 @@ -1440,6 +1466,17 @@ void ServerEnvironment::step(float dtime) 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 m_active_block_gauge->set(m_active_blocks.size()); diff --git a/src/serverenvironment.h b/src/serverenvironment.h index 215fd37ee..bb689ea2c 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -168,7 +168,8 @@ public: s16 active_block_range, s16 active_object_range, std::set &blocks_removed, - std::set &blocks_added); + std::set &blocks_added, + std::set &extra_blocks_added); bool contains(v3s16 p) const { return (m_list.find(p) != m_list.end());