}
}
-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)
{
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);
+ }
}
/*
elapsed_timer.position));
}
}
-
- /* Handle ActiveBlockModifiers */
- ABMHandler abmhandler(m_abms, dtime_s, this, false);
- abmhandler.apply(block);
}
void ServerEnvironment::addActiveBlockModifier(ActiveBlockModifier *abm)
/*
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)
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);
/*
MapBlock *block = m_map->getBlockOrEmerge(p);
if (!block) {
m_active_blocks.m_list.erase(p);
+ m_active_blocks.m_abm_list.erase(p);
continue;
}
// 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;