Optionally extend the active object in a players camera direction.
authorLars Hofhansl <larsh@apache.org>
Mon, 4 Dec 2017 01:51:58 +0000 (17:51 -0800)
committerLars Hofhansl <larsh@apache.org>
Mon, 4 Dec 2017 01:52:05 +0000 (17:52 -0800)
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
src/serverenvironment.h

index 1ac1ac1ba9738f2d5d3d541466a1c7c957667725..92159a469b11dd1c066c8358b205c223ae17f516 100644 (file)
@@ -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;
index b8a35f7fdadd75c878c5ebeec2f63904a502975e..cb813155de159697a3865b540299880941b7e435 100644 (file)
@@ -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: