diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/environment.cpp | 376 | ||||
-rw-r--r-- | src/environment.h | 2 |
2 files changed, 192 insertions, 186 deletions
diff --git a/src/environment.cpp b/src/environment.cpp index efcdbbd15..bed47fd40 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<u16> objects_to_remove; - for(core::map<u16, ServerActiveObject*>::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<u16> objects_to_remove; + for(core::map<u16, ServerActiveObject*>::Iterator + i = m_active_objects.getIterator(); + i.atEnd()==false; i++) { - dstream<<"WARNING: NULL object found in ServerEnvironment" - <<" while finding removed objects. id="<<id<<std::endl; + u16 id = i.getNode()->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="<<id<<std::endl; + // 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) + { + 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<u16>::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<u16>::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<Player*>::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<Player*>::Iterator i = m_players.begin(); + i != m_players.end(); i++) { - v3s16 blockpos(x,y,z); - MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos); - if(block==NULL) - continue; - // Ignore if no stored objects (to not set changed flag) - if(block->m_static_objects.m_stored.size() == 0) + Player *player = *i; + + // Ignore disconnected players + if(player->peer_id == 0) continue; - // This will contain the leftovers of the stored list - core::list<StaticObject> new_stored; - // Loop through stored static objects - for(core::list<StaticObject>::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"<<std::endl;*/ - StaticObject &s_obj = *i; - // Create an active object from the data - ServerActiveObject *obj = ServerActiveObject::create - (s_obj.type, this, 0, s_obj.pos, s_obj.data); - if(obj==NULL) - { - // This is necessary to preserve stuff during bugs - // and errors - new_stored.push_back(s_obj); + v3s16 blockpos(x,y,z); + MapBlock *block = m_map->getBlockNoCreateNoEx(blockpos); + if(block==NULL) 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<StaticObject> new_stored; + // Loop through stored static objects + for(core::list<StaticObject>::Iterator + i = block->m_static_objects.m_stored.begin(); + i != block->m_static_objects.m_stored.end(); i++) + { + /*dstream<<"INFO: Server: Creating an active object from " + <<"static data"<<std::endl;*/ + StaticObject &s_obj = *i; + // Create an active object from the data + ServerActiveObject *obj = ServerActiveObject::create + (s_obj.type, this, 0, s_obj.pos, s_obj.data); + if(obj==NULL) + { + // This is necessary to preserve stuff during bugs + // and errors + new_stored.push_back(s_obj); + continue; + } + // This will also add the object to the active static list + addActiveObject(obj); + //u16 id = addActiveObject(obj); } - // 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<StaticObject>::Iterator - i = new_stored.begin(); - i != new_stored.end(); i++) - { - StaticObject &s_obj = *i; - block->m_static_objects.m_stored.push_back(s_obj); + // Clear stored list + block->m_static_objects.m_stored.clear(); + // Add leftover stuff to stored list + for(core::list<StaticObject>::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(); } - block->setChangedFlag(); } - } - /* - Convert objects that are far away from all the players to static. - */ - { - core::list<u16> objects_to_remove; - for(core::map<u16, ServerActiveObject*>::Iterator - i = m_active_objects.getIterator(); - i.atEnd()==false; i++) + /* + Convert objects that are far away from all the players to static. + */ { - ServerActiveObject* obj = i.getNode()->getValue(); - u16 id = i.getNode()->getKey(); - v3f objectpos = obj->getBasePosition(); - - // This shouldn't happen but check it - if(obj == NULL) + core::list<u16> objects_to_remove; + for(core::map<u16, ServerActiveObject*>::Iterator + i = m_active_objects.getIterator(); + i.atEnd()==false; i++) { - dstream<<"WARNING: NULL object found in ServerEnvironment" - <<std::endl; - continue; - } - // If known by some client, don't convert to static. - if(obj->m_known_by_count > 0) - continue; + ServerActiveObject* obj = i.getNode()->getValue(); + u16 id = i.getNode()->getKey(); + v3f objectpos = obj->getBasePosition(); - // If close to some player, don't convert to static. - bool close_to_player = false; - for(core::list<Player*>::Iterator i = m_players.begin(); - i != m_players.end(); i++) - { - Player *player = *i; - - // Ignore disconnected players - if(player->peer_id == 0) + // This shouldn't happen but check it + if(obj == NULL) + { + dstream<<"WARNING: NULL object found in ServerEnvironment" + <<std::endl; + continue; + } + // If known by some client, don't convert to static. + if(obj->m_known_by_count > 0) continue; - v3f playerpos = player->getPosition(); - f32 d = playerpos.getDistanceFrom(objectpos); - if(d < to_static_max_f) + // If close to some player, don't convert to static. + bool close_to_player = false; + for(core::list<Player*>::Iterator i = m_players.begin(); + i != m_players.end(); i++) { - close_to_player = true; - break; + 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; + if(close_to_player) + continue; - /* - Update the static data and remove the active object. - */ + /* + 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); + // 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.remove(id); - oldblock = 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"<<std::endl; + obj->m_static_exists = false; + continue; + } + /*dstream<<"INFO: Server: Stored static data. Deleting object." + <<std::endl;*/ + // Delete active object + delete obj; + // Id to be removed from m_active_objects + objects_to_remove.push_back(id); } - // 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) + // Remove references from m_active_objects + for(core::list<u16>::Iterator i = objects_to_remove.begin(); + i != objects_to_remove.end(); i++) { - 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"<<std::endl; - obj->m_static_exists = false; - continue; + m_active_objects.remove(*i); } - /*dstream<<"INFO: Server: Stored static data. Deleting object." - <<std::endl;*/ - // Delete active object - 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<u16>::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 85d2f668f..e82cea6ae 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 <ostream> +#include "utility.h" class Environment { @@ -154,6 +155,7 @@ private: Queue<ActiveObjectMessage> m_active_object_messages; float m_random_spawn_timer; float m_send_recommended_timer; + IntervalLimiter m_object_management_interval; }; #ifndef SERVER |