summaryrefslogtreecommitdiff
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
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).
-rw-r--r--src/serverenvironment.cpp62
-rw-r--r--src/serverenvironment.h6
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: