summaryrefslogtreecommitdiff
path: root/src/serverenvironment.cpp
diff options
context:
space:
mode:
authorLars Hofhansl <larsh@apache.org>2017-12-03 17:51:58 -0800
committerLars Hofhansl <larsh@apache.org>2017-12-03 17:52:05 -0800
commit5a03b1f5f928e30cb650f9d16bc4fbb866275405 (patch)
tree250d3259956e2efa04ad1e0b887364d5c8a95d8f /src/serverenvironment.cpp
parent83b12ed481fdb1f0c86a97de8a2887acaa32079e (diff)
downloadminetest-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/serverenvironment.cpp')
-rw-r--r--src/serverenvironment.cpp62
1 files changed, 49 insertions, 13 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;