X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fserverenvironment.cpp;h=ae0f397eeedfc2cc12f250f2fcc11e360cb911b4;hb=6c9df2ffa7ee81a05b28fdd6123a926abd284c72;hp=1ac1ac1ba9738f2d5d3d541466a1c7c957667725;hpb=912ba1e47f61be18fa01cc91936929168c883f7b;p=minetest.git diff --git a/src/serverenvironment.cpp b/src/serverenvironment.cpp index 1ac1ac1ba..ae0f397ee 100644 --- a/src/serverenvironment.cpp +++ b/src/serverenvironment.cpp @@ -80,7 +80,7 @@ void LBMContentMapping::addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamed { // Add the lbm_def to the LBMContentMapping. // Unknown names get added to the global NameIdMapping. - INodeDefManager *nodedef = gamedef->ndef(); + const NodeDefManager *nodedef = gamedef->ndef(); lbm_list.push_back(lbm_def); @@ -292,8 +292,27 @@ void fillRadiusBlock(v3s16 p0, s16 r, std::set &list) } } -void ActiveBlockList::update(std::vector &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 &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 &active_players, + s16 active_block_range, + s16 active_object_range, std::set &blocks_removed, std::set &blocks_added) { @@ -301,8 +320,25 @@ void ActiveBlockList::update(std::vector &active_positions, Create the new list */ std::set 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); + } } /* @@ -456,30 +492,21 @@ bool ServerEnvironment::removePlayerFromDatabase(const std::string &name) return m_player_database->removePlayer(name); } -bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16 *p) +bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, v3s16 *p) { - float distance = pos1.getDistanceFrom(pos2); - - //calculate normalized direction vector - v3f normalized_vector = v3f((pos2.X - pos1.X)/distance, - (pos2.Y - pos1.Y)/distance, - (pos2.Z - pos1.Z)/distance); - - //find out if there's a node on path between pos1 and pos2 - for (float i = 1; i < distance; i += stepsize) { - v3s16 pos = floatToInt(v3f(normalized_vector.X * i, - normalized_vector.Y * i, - normalized_vector.Z * i) +pos1,BS); - - MapNode n = getMap().getNodeNoEx(pos); - - if(n.param0 != CONTENT_AIR) { - if (p) { - *p = pos; - } + // Iterate trough nodes on the line + voxalgo::VoxelLineIterator iterator(pos1 / BS, (pos2 - pos1) / BS); + do { + MapNode n = getMap().getNodeNoEx(iterator.m_current_node_pos); + + // Return non-air + if (n.param0 != CONTENT_AIR) { + if (p) + *p = iterator.m_current_node_pos; return false; } - } + iterator.next(); + } while (iterator.m_current_index <= iterator.m_last_index); return true; } @@ -540,8 +567,7 @@ PlayerSAO *ServerEnvironment::loadPlayer(RemotePlayer *player, bool *new_player, // If the player exists, ensure that they respawn inside legal bounds // This fixes an assert crash when the player can't be added // to the environment - ServerMap &map = getServerMap(); - if (map.getMapgenParams()->saoPosOverLimit(playersao->getBasePosition())) { + if (objectpos_over_limit(playersao->getBasePosition())) { actionstream << "Respawn position for player \"" << player->getName() << "\" outside limits, resetting" << std::endl; playersao->setBasePosition(m_server->findSpawnPos()); @@ -664,7 +690,7 @@ class ABMHandler { if(dtime_s < 0.001) return; - INodeDefManager *ndef = env->getGameDef()->ndef(); + const NodeDefManager *ndef = env->getGameDef()->ndef(); for (ABMWithState &abmws : abms) { ActiveBlockModifier *abm = abmws.abm; float trigger_interval = abm->getTriggerInterval(); @@ -873,10 +899,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) @@ -891,11 +913,13 @@ void ServerEnvironment::addLoadingBlockModifierDef(LoadingBlockModifierDef *lbm) bool ServerEnvironment::setNode(v3s16 p, const MapNode &n) { - INodeDefManager *ndef = m_server->ndef(); + const NodeDefManager *ndef = m_server->ndef(); MapNode n_old = m_map->getNodeNoEx(p); + const ContentFeatures &cf_old = ndef->get(n_old); + // Call destructor - if (ndef->get(n_old).has_on_destruct) + if (cf_old.has_on_destruct) m_script->node_on_destruct(p, n_old); // Replace node @@ -906,11 +930,15 @@ bool ServerEnvironment::setNode(v3s16 p, const MapNode &n) m_map->updateVManip(p); // Call post-destructor - if (ndef->get(n_old).has_after_destruct) + if (cf_old.has_after_destruct) m_script->node_after_destruct(p, n_old); + // Retrieve node content features + // if new node is same as old, reuse old definition to prevent a lookup + const ContentFeatures &cf_new = n_old == n ? cf_old : ndef->get(n); + // Call constructor - if (ndef->get(n).has_on_construct) + if (cf_new.has_on_construct) m_script->node_on_construct(p, n); return true; @@ -918,7 +946,7 @@ bool ServerEnvironment::setNode(v3s16 p, const MapNode &n) bool ServerEnvironment::removeNode(v3s16 p) { - INodeDefManager *ndef = m_server->ndef(); + const NodeDefManager *ndef = m_server->ndef(); MapNode n_old = m_map->getNodeNoEx(p); // Call destructor @@ -1140,7 +1168,7 @@ void ServerEnvironment::step(float dtime) /* Get player block positions */ - std::vector players_blockpos; + std::vector players; for (RemotePlayer *player: m_players) { // Ignore disconnected players if (player->getPeerId() == PEER_ID_INEXISTENT) @@ -1149,18 +1177,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 blocks_removed; std::set 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 +1218,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 +1280,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;