diff options
author | Lars Hofhansl <larsh@apache.org> | 2017-12-03 17:51:58 -0800 |
---|---|---|
committer | Lars Hofhansl <larsh@apache.org> | 2017-12-03 17:52:05 -0800 |
commit | 5a03b1f5f928e30cb650f9d16bc4fbb866275405 (patch) | |
tree | 250d3259956e2efa04ad1e0b887364d5c8a95d8f /src | |
parent | 83b12ed481fdb1f0c86a97de8a2887acaa32079e (diff) | |
download | minetest-5a03b1f5f928e30cb650f9d16bc4fbb866275405.tar.gz minetest-5a03b1f5f928e30cb650f9d16bc4fbb866275405.tar.bz2 minetest-5a03b1f5f928e30cb650f9d16bc4fbb866275405.zip |
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).
Diffstat (limited to 'src')
-rw-r--r-- | src/serverenvironment.cpp | 62 | ||||
-rw-r--r-- | 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<v3s16> &list) } } -void ActiveBlockList::update(std::vector<v3s16> &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<v3s16> &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<PlayerSAO*> &active_players, + s16 active_block_range, + s16 active_object_range, std::set<v3s16> &blocks_removed, std::set<v3s16> &blocks_added) { @@ -301,8 +320,25 @@ void ActiveBlockList::update(std::vector<v3s16> &active_positions, Create the new list */ std::set<v3s16> 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<v3s16> players_blockpos; + std::vector<PlayerSAO*> 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<v3s16> blocks_removed; std::set<v3s16> 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<v3s16> &active_positions, - s16 radius, + void update(std::vector<PlayerSAO*> &active_players, + s16 active_block_range, + s16 active_object_range, std::set<v3s16> &blocks_removed, std::set<v3s16> &blocks_added); @@ -168,6 +169,7 @@ public: } std::set<v3s16> m_list; + std::set<v3s16> m_abm_list; std::set<v3s16> m_forceloaded_list; private: |