From 5a03b1f5f928e30cb650f9d16bc4fbb866275405 Mon Sep 17 00:00:00 2001 From: Lars Hofhansl Date: Sun, 3 Dec 2017 17:51:58 -0800 Subject: [PATCH] Optionally extend the active object in a players camera direction. See #6667 By setting active_object_send_range_blocks > active_block_range a server admin can allow clients to retrieve active objects futher out from the player at relatively low cost to the server (only objects in the players' view cone are considered). --- src/serverenvironment.cpp | 62 +++++++++++++++++++++++++++++++-------- src/serverenvironment.h | 6 ++-- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index 1ac1ac1ba..92159a469 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -292,8 +292,27 @@ void fillRadiusBlock(v3s16 p0, s16 r, std::set &list) } } -void ActiveBlockList::update(std::vector &active_positions, - s16 radius, +void fillViewConeBlock(v3s16 p0, + const s16 r, + const v3f camera_pos, + const v3f camera_dir, + const float camera_fov, + std::set &list) +{ + v3s16 p; + const s16 r_nodes = r * BS * MAP_BLOCKSIZE; + for (p.X = p0.X - r; p.X <= p0.X+r; p.X++) + for (p.Y = p0.Y - r; p.Y <= p0.Y+r; p.Y++) + for (p.Z = p0.Z - r; p.Z <= p0.Z+r; p.Z++) { + if (isBlockInSight(p, camera_pos, camera_dir, camera_fov, r_nodes)) { + list.insert(p); + } + } +} + +void ActiveBlockList::update(std::vector &active_players, + s16 active_block_range, + s16 active_object_range, std::set &blocks_removed, std::set &blocks_added) { @@ -301,8 +320,25 @@ void ActiveBlockList::update(std::vector &active_positions, Create the new list */ std::set newlist = m_forceloaded_list; - for (const v3s16 &active_position : active_positions) { - fillRadiusBlock(active_position, radius, newlist); + m_abm_list = m_forceloaded_list; + for (const PlayerSAO *playersao : active_players) { + v3s16 pos = getNodeBlockPos(floatToInt(playersao->getBasePosition(), BS)); + fillRadiusBlock(pos, active_block_range, m_abm_list); + fillRadiusBlock(pos, active_block_range, newlist); + + s16 player_ao_range = std::min(active_object_range, playersao->getWantedRange()); + // only do this if this would add blocks + if (player_ao_range > active_block_range) { + v3f camera_dir = v3f(0,0,1); + camera_dir.rotateYZBy(playersao->getPitch()); + camera_dir.rotateXZBy(playersao->getYaw()); + fillViewConeBlock(pos, + player_ao_range, + playersao->getEyePosition(), + camera_dir, + playersao->getFov(), + newlist); + } } /* @@ -873,10 +909,6 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime) elapsed_timer.position)); } } - - /* Handle ActiveBlockModifiers */ - ABMHandler abmhandler(m_abms, dtime_s, this, false); - abmhandler.apply(block); } void ServerEnvironment::addActiveBlockModifier(ActiveBlockModifier *abm) @@ -1140,7 +1172,7 @@ void ServerEnvironment::step(float dtime) /* Get player block positions */ - std::vector players_blockpos; + std::vector players; for (RemotePlayer *player: m_players) { // Ignore disconnected players if (player->getPeerId() == PEER_ID_INEXISTENT) @@ -1149,18 +1181,21 @@ void ServerEnvironment::step(float dtime) PlayerSAO *playersao = player->getPlayerSAO(); assert(playersao); - players_blockpos.push_back( - getNodeBlockPos(floatToInt(playersao->getBasePosition(), BS))); + players.push_back(playersao); } /* Update list of active blocks, collecting changes */ + // use active_object_send_range_blocks since that is max distance + // for active objects sent the client anyway + static thread_local const s16 active_object_range = + g_settings->getS16("active_object_send_range_blocks"); static thread_local const s16 active_block_range = g_settings->getS16("active_block_range"); std::set blocks_removed; std::set blocks_added; - m_active_blocks.update(players_blockpos, active_block_range, + m_active_blocks.update(players, active_block_range, active_object_range, blocks_removed, blocks_added); /* @@ -1187,6 +1222,7 @@ void ServerEnvironment::step(float dtime) MapBlock *block = m_map->getBlockOrEmerge(p); if (!block) { m_active_blocks.m_list.erase(p); + m_active_blocks.m_abm_list.erase(p); continue; } @@ -1248,7 +1284,7 @@ void ServerEnvironment::step(float dtime) // Initialize handling of ActiveBlockModifiers ABMHandler abmhandler(m_abms, m_cache_abm_interval, this, true); - for (const v3s16 &p : m_active_blocks.m_list) { + for (const v3s16 &p : m_active_blocks.m_abm_list) { MapBlock *block = m_map->getBlockNoCreateNoEx(p); if (!block) continue; diff --git a/src/serverenvironment.h b/src/serverenvironment.h index b8a35f7fd..cb813155d 100644 --- a/src/serverenvironment.h +++ b/src/serverenvironment.h @@ -154,8 +154,9 @@ private: class ActiveBlockList { public: - void update(std::vector &active_positions, - s16 radius, + void update(std::vector &active_players, + s16 active_block_range, + s16 active_object_range, std::set &blocks_removed, std::set &blocks_added); @@ -168,6 +169,7 @@ public: } std::set m_list; + std::set m_abm_list; std::set m_forceloaded_list; private: