diff --git a/src/environment.cpp b/src/environment.cpp index efcdbbd1..bed47fd4 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -449,227 +449,231 @@ void ServerEnvironment::step(float dtime) obj->step(dtime, m_active_object_messages, send_recommended); } - /* - Remove objects that satisfy (m_removed && m_known_by_count==0) - */ + if(m_object_management_interval.step(dtime, 0.5)) { - core::list objects_to_remove; - for(core::map::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) + /* + Remove objects that satisfy (m_removed && m_known_by_count==0) + */ { - u16 id = i.getNode()->getKey(); - ServerActiveObject* obj = i.getNode()->getValue(); - // This shouldn't happen but check it - if(obj == NULL) + core::list objects_to_remove; + for(core::map::Iterator + i = m_active_objects.getIterator(); + i.atEnd()==false; i++) { - dstream<<"WARNING: NULL object found in ServerEnvironment" - <<" while finding removed objects. id="<getKey(); + ServerActiveObject* obj = i.getNode()->getValue(); + // This shouldn't happen but check it + if(obj == NULL) + { + dstream<<"WARNING: NULL object found in ServerEnvironment" + <<" while finding removed objects. id="<m_removed == false) + continue; + // Delete static data from block + if(obj->m_static_exists) + { + MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block); + if(block) + { + block->m_static_objects.remove(id); + block->setChangedFlag(); + } + } + // If m_known_by_count > 0, don't actually remove. + if(obj->m_known_by_count > 0) + continue; + // Delete + delete obj; // Id to be removed from m_active_objects objects_to_remove.push_back(id); - continue; } - // If not m_removed, don't remove. - if(obj->m_removed == false) - continue; - // Delete static data from block - if(obj->m_static_exists) + // Remove references from m_active_objects + for(core::list::Iterator i = objects_to_remove.begin(); + i != objects_to_remove.end(); i++) { - MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block); - if(block) - { - block->m_static_objects.remove(id); - block->setChangedFlag(); - } + m_active_objects.remove(*i); } - // If m_known_by_count > 0, don't actually remove. - if(obj->m_known_by_count > 0) - continue; - // Delete - delete obj; - // Id to be removed from m_active_objects - objects_to_remove.push_back(id); } - // Remove references from m_active_objects - for(core::list::Iterator i = objects_to_remove.begin(); - i != objects_to_remove.end(); i++) - { - m_active_objects.remove(*i); - } - } - - - const s16 to_active_max_blocks = 3; - const f32 to_static_max_f = (to_active_max_blocks+1)*MAP_BLOCKSIZE*BS; - - /* - Convert stored objects from blocks near the players to active. - */ - for(core::list::Iterator i = m_players.begin(); - i != m_players.end(); i++) - { - Player *player = *i; - // Ignore disconnected players - if(player->peer_id == 0) - continue; - v3f playerpos = player->getPosition(); - - v3s16 blockpos0 = getNodeBlockPos(floatToInt(playerpos, BS)); - v3s16 bpmin = blockpos0 - v3s16(1,1,1)*to_active_max_blocks; - v3s16 bpmax = blockpos0 + v3s16(1,1,1)*to_active_max_blocks; - // Loop through all nearby blocks - for(s16 x=bpmin.X; x<=bpmax.X; x++) - for(s16 y=bpmin.Y; y<=bpmax.Y; y++) - for(s16 z=bpmin.Z; z<=bpmax.Z; z++) + const s16 to_active_max_blocks = 3; + const f32 to_static_max_f = (to_active_max_blocks+1)*MAP_BLOCKSIZE*BS; + + /* + Convert stored objects from blocks near the players to active. + */ + for(core::list::Iterator i = m_players.begin(); + i != m_players.end(); i++) { - v3s16 blockpos(x,y,z); - MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos); - if(block==NULL) + Player *player = *i; + + // Ignore disconnected players + if(player->peer_id == 0) continue; - // Ignore if no stored objects (to not set changed flag) - if(block->m_static_objects.m_stored.size() == 0) - continue; - // This will contain the leftovers of the stored list - core::list new_stored; - // Loop through stored static objects - for(core::list::Iterator - i = block->m_static_objects.m_stored.begin(); - i != block->m_static_objects.m_stored.end(); i++) + + v3f playerpos = player->getPosition(); + + v3s16 blockpos0 = getNodeBlockPos(floatToInt(playerpos, BS)); + v3s16 bpmin = blockpos0 - v3s16(1,1,1)*to_active_max_blocks; + v3s16 bpmax = blockpos0 + v3s16(1,1,1)*to_active_max_blocks; + // Loop through all nearby blocks + for(s16 x=bpmin.X; x<=bpmax.X; x++) + for(s16 y=bpmin.Y; y<=bpmax.Y; y++) + for(s16 z=bpmin.Z; z<=bpmax.Z; z++) { - /*dstream<<"INFO: Server: Creating an active object from " - <<"static data"<getBlockNoCreateNoEx(blockpos); + if(block==NULL) continue; - } - // This will also add the object to the active static list - addActiveObject(obj); - //u16 id = addActiveObject(obj); - } - // Clear stored list - block->m_static_objects.m_stored.clear(); - // Add leftover stuff to stored list - for(core::list::Iterator - i = new_stored.begin(); - i != new_stored.end(); i++) - { - StaticObject &s_obj = *i; - block->m_static_objects.m_stored.push_back(s_obj); - } - block->setChangedFlag(); - } - } - - /* - Convert objects that are far away from all the players to static. - */ - { - core::list objects_to_remove; - for(core::map::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) - { - ServerActiveObject* obj = i.getNode()->getValue(); - u16 id = i.getNode()->getKey(); - v3f objectpos = obj->getBasePosition(); - - // This shouldn't happen but check it - if(obj == NULL) - { - dstream<<"WARNING: NULL object found in ServerEnvironment" - <m_known_by_count > 0) - continue; - - // If close to some player, don't convert to static. - bool close_to_player = false; - for(core::list::Iterator i = m_players.begin(); - i != m_players.end(); i++) - { - Player *player = *i; - - // Ignore disconnected players - if(player->peer_id == 0) + // Ignore if no stored objects (to not set changed flag) + if(block->m_static_objects.m_stored.size() == 0) continue; - - v3f playerpos = player->getPosition(); - f32 d = playerpos.getDistanceFrom(objectpos); - if(d < to_static_max_f) + // This will contain the leftovers of the stored list + core::list new_stored; + // Loop through stored static objects + for(core::list::Iterator + i = block->m_static_objects.m_stored.begin(); + i != block->m_static_objects.m_stored.end(); i++) { - close_to_player = true; - break; + /*dstream<<"INFO: Server: Creating an active object from " + <<"static data"<m_static_exists) - { - MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block); - if(block) + // Clear stored list + block->m_static_objects.m_stored.clear(); + // Add leftover stuff to stored list + for(core::list::Iterator + i = new_stored.begin(); + i != new_stored.end(); i++) { - block->m_static_objects.remove(id); - oldblock = block; + StaticObject &s_obj = *i; + block->m_static_objects.m_stored.push_back(s_obj); } - } - // Add new static object - std::string staticdata = obj->getStaticData(); - StaticObject s_obj(obj->getType(), objectpos, staticdata); - // Add to the block where the object is located in - v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS)); - MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos); - if(block) - { - block->m_static_objects.insert(0, s_obj); block->setChangedFlag(); - obj->m_static_exists = true; - obj->m_static_block = block->getPos(); } - // If not possible, add back to previous block - else if(oldblock) - { - oldblock->m_static_objects.insert(0, s_obj); - oldblock->setChangedFlag(); - obj->m_static_exists = true; - obj->m_static_block = oldblock->getPos(); - } - else{ - dstream<<"WARNING: Server: Could not find a block for " - <<"storing static object"<m_static_exists = false; - continue; - } - /*dstream<<"INFO: Server: Stored static data. Deleting object." - <::Iterator i = objects_to_remove.begin(); - i != objects_to_remove.end(); i++) + + /* + Convert objects that are far away from all the players to static. + */ { - m_active_objects.remove(*i); + core::list objects_to_remove; + for(core::map::Iterator + i = m_active_objects.getIterator(); + i.atEnd()==false; i++) + { + ServerActiveObject* obj = i.getNode()->getValue(); + u16 id = i.getNode()->getKey(); + v3f objectpos = obj->getBasePosition(); + + // This shouldn't happen but check it + if(obj == NULL) + { + dstream<<"WARNING: NULL object found in ServerEnvironment" + <m_known_by_count > 0) + continue; + + // If close to some player, don't convert to static. + bool close_to_player = false; + for(core::list::Iterator i = m_players.begin(); + i != m_players.end(); i++) + { + Player *player = *i; + + // Ignore disconnected players + if(player->peer_id == 0) + continue; + + v3f playerpos = player->getPosition(); + f32 d = playerpos.getDistanceFrom(objectpos); + if(d < to_static_max_f) + { + close_to_player = true; + break; + } + } + + if(close_to_player) + continue; + + /* + Update the static data and remove the active object. + */ + + // Delete old static object + MapBlock *oldblock = NULL; + if(obj->m_static_exists) + { + MapBlock *block = m_map->getBlockNoCreateNoEx + (obj->m_static_block); + if(block) + { + block->m_static_objects.remove(id); + oldblock = block; + } + } + // Add new static object + std::string staticdata = obj->getStaticData(); + StaticObject s_obj(obj->getType(), objectpos, staticdata); + // Add to the block where the object is located in + v3s16 blockpos = getNodeBlockPos(floatToInt(objectpos, BS)); + MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos); + if(block) + { + block->m_static_objects.insert(0, s_obj); + block->setChangedFlag(); + obj->m_static_exists = true; + obj->m_static_block = block->getPos(); + } + // If not possible, add back to previous block + else if(oldblock) + { + oldblock->m_static_objects.insert(0, s_obj); + oldblock->setChangedFlag(); + obj->m_static_exists = true; + obj->m_static_block = oldblock->getPos(); + } + else{ + dstream<<"WARNING: Server: Could not find a block for " + <<"storing static object"<m_static_exists = false; + continue; + } + /*dstream<<"INFO: Server: Stored static data. Deleting object." + <::Iterator i = objects_to_remove.begin(); + i != objects_to_remove.end(); i++) + { + m_active_objects.remove(*i); + } } } diff --git a/src/environment.h b/src/environment.h index 85d2f668..e82cea6a 100644 --- a/src/environment.h +++ b/src/environment.h @@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "player.h" #include "map.h" #include +#include "utility.h" class Environment { @@ -154,6 +155,7 @@ private: Queue m_active_object_messages; float m_random_spawn_timer; float m_send_recommended_timer; + IntervalLimiter m_object_management_interval; }; #ifndef SERVER