]> git.lizzy.rs Git - minetest.git/blobdiff - src/environment.cpp
dofile error reporting for syntax errors
[minetest.git] / src / environment.cpp
index 166523a4fa8c257276f2d27353b28a7f779f3b0b..dc18fd58f8857a2734be3b78ea6a5cc4af06e3bc 100644 (file)
@@ -17,6 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
+#include <fstream>
 #include "environment.h"
 #include "filesys.h"
 #include "porting.h"
@@ -31,7 +32,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "scripting_game.h"
 #include "nodedef.h"
 #include "nodemetadata.h"
-#include "main.h" // For g_settings, g_profiler
 #include "gamedef.h"
 #ifndef SERVER
 #include "clientmap.h"
@@ -61,9 +61,8 @@ Environment::Environment():
 Environment::~Environment()
 {
        // Deallocate players
-       for(std::list<Player*>::iterator i = m_players.begin();
-                       i != m_players.end(); ++i)
-       {
+       for(std::vector<Player*>::iterator i = m_players.begin();
+                       i != m_players.end(); ++i) {
                delete (*i);
        }
 }
@@ -78,9 +77,9 @@ void Environment::addPlayer(Player *player)
        */
        // If peer id is non-zero, it has to be unique.
        if(player->peer_id != 0)
-               assert(getPlayer(player->peer_id) == NULL);
+               FATAL_ERROR_IF(getPlayer(player->peer_id) != NULL, "Peer id not unique");
        // Name has to be unique.
-       assert(getPlayer(player->getName()) == NULL);
+       FATAL_ERROR_IF(getPlayer(player->getName()) != NULL, "Player name not unique");
        // Add.
        m_players.push_back(player);
 }
@@ -89,7 +88,7 @@ void Environment::removePlayer(u16 peer_id)
 {
        DSTACK(__FUNCTION_NAME);
 
-       for(std::list<Player*>::iterator i = m_players.begin();
+       for(std::vector<Player*>::iterator i = m_players.begin();
                        i != m_players.end();)
        {
                Player *player = *i;
@@ -104,7 +103,7 @@ void Environment::removePlayer(u16 peer_id)
 
 void Environment::removePlayer(const char *name)
 {
-       for (std::list<Player*>::iterator it = m_players.begin();
+       for (std::vector<Player*>::iterator it = m_players.begin();
                        it != m_players.end(); ++it) {
                if (strcmp((*it)->getName(), name) == 0) {
                        delete *it;
@@ -116,9 +115,8 @@ void Environment::removePlayer(const char *name)
 
 Player * Environment::getPlayer(u16 peer_id)
 {
-       for(std::list<Player*>::iterator i = m_players.begin();
-                       i != m_players.end(); ++i)
-       {
+       for(std::vector<Player*>::iterator i = m_players.begin();
+                       i != m_players.end(); ++i) {
                Player *player = *i;
                if(player->peer_id == peer_id)
                        return player;
@@ -128,9 +126,8 @@ Player * Environment::getPlayer(u16 peer_id)
 
 Player * Environment::getPlayer(const char *name)
 {
-       for(std::list<Player*>::iterator i = m_players.begin();
-                       i != m_players.end(); ++i)
-       {
+       for(std::vector<Player*>::iterator i = m_players.begin();
+                       i != m_players.end(); ++i) {
                Player *player = *i;
                if(strcmp(player->getName(), name) == 0)
                        return player;
@@ -140,15 +137,13 @@ Player * Environment::getPlayer(const char *name)
 
 Player * Environment::getRandomConnectedPlayer()
 {
-       std::list<Player*> connected_players = getPlayers(true);
+       std::vector<Player*> connected_players = getPlayers(true);
        u32 chosen_one = myrand() % connected_players.size();
        u32 j = 0;
-       for(std::list<Player*>::iterator
+       for(std::vector<Player*>::iterator
                        i = connected_players.begin();
-                       i != connected_players.end(); ++i)
-       {
-               if(j == chosen_one)
-               {
+                       i != connected_players.end(); ++i) {
+               if(j == chosen_one) {
                        Player *player = *i;
                        return player;
                }
@@ -159,17 +154,15 @@ Player * Environment::getRandomConnectedPlayer()
 
 Player * Environment::getNearestConnectedPlayer(v3f pos)
 {
-       std::list<Player*> connected_players = getPlayers(true);
+       std::vector<Player*> connected_players = getPlayers(true);
        f32 nearest_d = 0;
        Player *nearest_player = NULL;
-       for(std::list<Player*>::iterator
+       for(std::vector<Player*>::iterator
                        i = connected_players.begin();
-                       i != connected_players.end(); ++i)
-       {
+                       i != connected_players.end(); ++i) {
                Player *player = *i;
                f32 d = player->getPosition().getDistanceFrom(pos);
-               if(d < nearest_d || nearest_player == NULL)
-               {
+               if(d < nearest_d || nearest_player == NULL) {
                        nearest_d = d;
                        nearest_player = player;
                }
@@ -177,22 +170,20 @@ Player * Environment::getNearestConnectedPlayer(v3f pos)
        return nearest_player;
 }
 
-std::list<Player*> Environment::getPlayers()
+std::vector<Player*> Environment::getPlayers()
 {
        return m_players;
 }
 
-std::list<Player*> Environment::getPlayers(bool ignore_disconnected)
+std::vector<Player*> Environment::getPlayers(bool ignore_disconnected)
 {
-       std::list<Player*> newlist;
-       for(std::list<Player*>::iterator
+       std::vector<Player*> newlist;
+       for(std::vector<Player*>::iterator
                        i = m_players.begin();
-                       i != m_players.end(); ++i)
-       {
+                       i != m_players.end(); ++i) {
                Player *player = *i;
-               
-               if(ignore_disconnected)
-               {
+
+               if(ignore_disconnected) {
                        // Ignore disconnected players
                        if(player->peer_id == 0)
                                continue;
@@ -212,25 +203,43 @@ u32 Environment::getDayNightRatio()
 
 void Environment::setTimeOfDaySpeed(float speed)
 {
-       JMutexAutoLock(this->m_lock);
+       JMutexAutoLock(this->m_timeofday_lock);
        m_time_of_day_speed = speed;
 }
 
 float Environment::getTimeOfDaySpeed()
 {
-       JMutexAutoLock(this->m_lock);
+       JMutexAutoLock(this->m_timeofday_lock);
        float retval = m_time_of_day_speed;
        return retval;
 }
 
+void Environment::setTimeOfDay(u32 time)
+{
+       JMutexAutoLock(this->m_time_lock);
+       m_time_of_day = time;
+       m_time_of_day_f = (float)time / 24000.0;
+}
+
+u32 Environment::getTimeOfDay()
+{
+       JMutexAutoLock(this->m_time_lock);
+       u32 retval = m_time_of_day;
+       return retval;
+}
+
+float Environment::getTimeOfDayF()
+{
+       JMutexAutoLock(this->m_time_lock);
+       float retval = m_time_of_day_f;
+       return retval;
+}
+
 void Environment::stepTimeOfDay(float dtime)
 {
-       float day_speed = 0;
-       {
-               JMutexAutoLock(this->m_lock);
-               day_speed = m_time_of_day_speed;
-       }
-       
+       // getTimeOfDaySpeed lock the value we need to prevent MT problems
+       float day_speed = getTimeOfDaySpeed();
+
        m_time_counter += dtime;
        f32 speed = day_speed * 24000./(24.*3600);
        u32 units = (u32)(m_time_counter*speed);
@@ -287,7 +296,7 @@ void fillRadiusBlock(v3s16 p0, s16 r, std::set<v3s16> &list)
        }
 }
 
-void ActiveBlockList::update(std::list<v3s16> &active_positions,
+void ActiveBlockList::update(std::vector<v3s16> &active_positions,
                s16 radius,
                std::set<v3s16> &blocks_removed,
                std::set<v3s16> &blocks_added)
@@ -296,7 +305,7 @@ void ActiveBlockList::update(std::list<v3s16> &active_positions,
                Create the new list
        */
        std::set<v3s16> newlist = m_forceloaded_list;
-       for(std::list<v3s16>::iterator i = active_positions.begin();
+       for(std::vector<v3s16>::iterator i = active_positions.begin();
                        i != active_positions.end(); ++i)
        {
                fillRadiusBlock(*i, radius, newlist);
@@ -373,7 +382,7 @@ ServerEnvironment::~ServerEnvironment()
        m_map->drop();
 
        // Delete ActiveBlockModifiers
-       for(std::list<ABMWithState>::iterator
+       for(std::vector<ABMWithState>::iterator
                        i = m_abms.begin(); i != m_abms.end(); ++i){
                delete i->abm;
        }
@@ -395,8 +404,8 @@ bool ServerEnvironment::line_of_sight(v3f pos1, v3f pos2, float stepsize, v3s16
 
        //calculate normalized direction vector
        v3f normalized_vector = v3f((pos2.X - pos1.X)/distance,
-                                                               (pos2.Y - pos1.Y)/distance,
-                                                               (pos2.Z - pos1.Z)/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) {
@@ -421,7 +430,7 @@ void ServerEnvironment::saveLoadedPlayers()
        std::string players_path = m_path_world + DIR_DELIM "players";
        fs::CreateDir(players_path);
 
-       for (std::list<Player*>::iterator it = m_players.begin();
+       for (std::vector<Player*>::iterator it = m_players.begin();
                        it != m_players.end();
                        ++it) {
                RemotePlayer *player = static_cast<RemotePlayer*>(*it);
@@ -444,41 +453,43 @@ void ServerEnvironment::savePlayer(const std::string &playername)
 
 Player *ServerEnvironment::loadPlayer(const std::string &playername)
 {
-       std::string players_path = m_path_world + DIR_DELIM "players" DIR_DELIM;
-
-       RemotePlayer *player = static_cast<RemotePlayer*>(getPlayer(playername.c_str()));
        bool newplayer = false;
        bool found = false;
+       std::string players_path = m_path_world + DIR_DELIM "players" DIR_DELIM;
+       std::string path = players_path + playername;
+
+       RemotePlayer *player = static_cast<RemotePlayer *>(getPlayer(playername.c_str()));
        if (!player) {
-               player = new RemotePlayer(m_gamedef, playername.c_str());
+               player = new RemotePlayer(m_gamedef, "");
                newplayer = true;
        }
 
-       RemotePlayer testplayer(m_gamedef, "");
-       std::string path = players_path + playername;
        for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES; i++) {
-               // Open file and deserialize
+               //// Open file and deserialize
                std::ifstream is(path.c_str(), std::ios_base::binary);
-               if (!is.good()) {
-                       return NULL;
-               }
-               testplayer.deSerialize(is, path);
+               if (!is.good())
+                       continue;
+               player->deSerialize(is, path);
                is.close();
-               if (testplayer.getName() == playername) {
-                       *player = testplayer;
+
+               if (player->getName() == playername) {
                        found = true;
                        break;
                }
+
                path = players_path + playername + itos(i);
        }
+
        if (!found) {
                infostream << "Player file for player " << playername
                                << " not found" << std::endl;
+               if (newplayer)
+                       delete player;
                return NULL;
        }
-       if (newplayer) {
+
+       if (newplayer)
                addPlayer(player);
-       }
        player->setModified(false);
        return player;
 }
@@ -549,9 +560,9 @@ class ABMHandler
 {
 private:
        ServerEnvironment *m_env;
-       std::map<content_t, std::list<ActiveABM> > m_aabms;
+       std::map<content_t, std::vector<ActiveABM> > m_aabms;
 public:
-       ABMHandler(std::list<ABMWithState> &abms,
+       ABMHandler(std::vector<ABMWithState> &abms,
                        float dtime_s, ServerEnvironment *env,
                        bool use_timers):
                m_env(env)
@@ -559,8 +570,8 @@ class ABMHandler
                if(dtime_s < 0.001)
                        return;
                INodeDefManager *ndef = env->getGameDef()->ndef();
-               for(std::list<ABMWithState>::iterator
-                               i = abms.begin(); i != abms.end(); ++i){
+               for(std::vector<ABMWithState>::iterator
+                               i = abms.begin(); i != abms.end(); ++i) {
                        ActiveBlockModifier *abm = i->abm;
                        float trigger_interval = abm->getTriggerInterval();
                        if(trigger_interval < 0.001)
@@ -604,10 +615,10 @@ class ABMHandler
                                                k != ids.end(); k++)
                                {
                                        content_t c = *k;
-                                       std::map<content_t, std::list<ActiveABM> >::iterator j;
+                                       std::map<content_t, std::vector<ActiveABM> >::iterator j;
                                        j = m_aabms.find(c);
                                        if(j == m_aabms.end()){
-                                               std::list<ActiveABM> aabmlist;
+                                               std::vector<ActiveABM> aabmlist;
                                                m_aabms[c] = aabmlist;
                                                j = m_aabms.find(c);
                                        }
@@ -664,14 +675,13 @@ class ABMHandler
                        content_t c = n.getContent();
                        v3s16 p = p0 + block->getPosRelative();
 
-                       std::map<content_t, std::list<ActiveABM> >::iterator j;
+                       std::map<content_t, std::vector<ActiveABM> >::iterator j;
                        j = m_aabms.find(c);
                        if(j == m_aabms.end())
                                continue;
 
-                       for(std::list<ActiveABM>::iterator
-                                       i = j->second.begin(); i != j->second.end(); i++)
-                       {
+                       for(std::vector<ActiveABM>::iterator
+                                       i = j->second.begin(); i != j->second.end(); i++) {
                                if(myrand() % i->chance != 0)
                                        continue;
 
@@ -738,7 +748,7 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
 
        /*infostream<<"ServerEnvironment::activateBlock(): block is "
                        <<dtime_s<<" seconds old."<<std::endl;*/
-       
+
        // Activate stored objects
        activateObjects(block, dtime_s);
 
@@ -830,9 +840,8 @@ bool ServerEnvironment::swapNode(v3s16 p, const MapNode &n)
        return true;
 }
 
-std::set<u16> ServerEnvironment::getObjectsInsideRadius(v3f pos, float radius)
+void ServerEnvironment::getObjectsInsideRadius(std::vector<u16> &objects, v3f pos, float radius)
 {
-       std::set<u16> objects;
        for(std::map<u16, ServerActiveObject*>::iterator
                        i = m_active_objects.begin();
                        i != m_active_objects.end(); ++i)
@@ -842,20 +851,18 @@ std::set<u16> ServerEnvironment::getObjectsInsideRadius(v3f pos, float radius)
                v3f objectpos = obj->getBasePosition();
                if(objectpos.getDistanceFrom(pos) > radius)
                        continue;
-               objects.insert(id);
+               objects.push_back(id);
        }
-       return objects;
 }
 
 void ServerEnvironment::clearAllObjects()
 {
        infostream<<"ServerEnvironment::clearAllObjects(): "
                        <<"Removing all active objects"<<std::endl;
-       std::list<u16> objects_to_remove;
+       std::vector<u16> objects_to_remove;
        for(std::map<u16, ServerActiveObject*>::iterator
                        i = m_active_objects.begin();
-                       i != m_active_objects.end(); ++i)
-       {
+                       i != m_active_objects.end(); ++i) {
                ServerActiveObject* obj = i->second;
                if(obj->getType() == ACTIVEOBJECT_TYPE_PLAYER)
                        continue;
@@ -866,7 +873,7 @@ void ServerEnvironment::clearAllObjects()
                        if(block){
                                block->m_static_objects.remove(id);
                                block->raiseModified(MOD_STATE_WRITE_NEEDED,
-                                               "clearAllObjects");
+                                               MOD_REASON_CLEAR_ALL_OBJECTS);
                                obj->m_static_exists = false;
                        }
                }
@@ -888,15 +895,15 @@ void ServerEnvironment::clearAllObjects()
                // Id to be removed from m_active_objects
                objects_to_remove.push_back(id);
        }
+
        // Remove references from m_active_objects
-       for(std::list<u16>::iterator i = objects_to_remove.begin();
-                       i != objects_to_remove.end(); ++i)
-       {
+       for(std::vector<u16>::iterator i = objects_to_remove.begin();
+                       i != objects_to_remove.end(); ++i) {
                m_active_objects.erase(*i);
        }
 
        // Get list of loaded blocks
-       std::list<v3s16> loaded_blocks;
+       std::vector<v3s16> loaded_blocks;
        infostream<<"ServerEnvironment::clearAllObjects(): "
                        <<"Listing all loaded blocks"<<std::endl;
        m_map->listAllLoadedBlocks(loaded_blocks);
@@ -905,7 +912,7 @@ void ServerEnvironment::clearAllObjects()
                        <<loaded_blocks.size()<<std::endl;
 
        // Get list of loadable blocks
-       std::list<v3s16> loadable_blocks;
+       std::vector<v3s16> loadable_blocks;
        infostream<<"ServerEnvironment::clearAllObjects(): "
                        <<"Listing all loadable blocks"<<std::endl;
        m_map->listAllLoadableBlocks(loadable_blocks);
@@ -915,12 +922,11 @@ void ServerEnvironment::clearAllObjects()
                        <<", now clearing"<<std::endl;
 
        // Grab a reference on each loaded block to avoid unloading it
-       for(std::list<v3s16>::iterator i = loaded_blocks.begin();
-                       i != loaded_blocks.end(); ++i)
-       {
+       for(std::vector<v3s16>::iterator i = loaded_blocks.begin();
+                       i != loaded_blocks.end(); ++i) {
                v3s16 p = *i;
                MapBlock *block = m_map->getBlockNoCreateNoEx(p);
-               assert(block);
+               assert(block != NULL);
                block->refGrab();
        }
 
@@ -931,9 +937,8 @@ void ServerEnvironment::clearAllObjects()
        u32 num_blocks_checked = 0;
        u32 num_blocks_cleared = 0;
        u32 num_objs_cleared = 0;
-       for(std::list<v3s16>::iterator i = loadable_blocks.begin();
-                       i != loadable_blocks.end(); ++i)
-       {
+       for(std::vector<v3s16>::iterator i = loadable_blocks.begin();
+                       i != loadable_blocks.end(); ++i) {
                v3s16 p = *i;
                MapBlock *block = m_map->emergeBlock(p, false);
                if(!block){
@@ -947,7 +952,7 @@ void ServerEnvironment::clearAllObjects()
                        block->m_static_objects.m_stored.clear();
                        block->m_static_objects.m_active.clear();
                        block->raiseModified(MOD_STATE_WRITE_NEEDED,
-                                       "clearAllObjects");
+                               MOD_REASON_CLEAR_ALL_OBJECTS);
                        num_objs_cleared += num_stored + num_active;
                        num_blocks_cleared++;
                }
@@ -969,9 +974,8 @@ void ServerEnvironment::clearAllObjects()
        m_map->unloadUnreferencedBlocks();
 
        // Drop references that were added above
-       for(std::list<v3s16>::iterator i = loaded_blocks.begin();
-                       i != loaded_blocks.end(); ++i)
-       {
+       for(std::vector<v3s16>::iterator i = loaded_blocks.begin();
+                       i != loaded_blocks.end(); ++i) {
                v3s16 p = *i;
                MapBlock *block = m_map->getBlockNoCreateNoEx(p);
                assert(block);
@@ -986,7 +990,7 @@ void ServerEnvironment::clearAllObjects()
 void ServerEnvironment::step(float dtime)
 {
        DSTACK(__FUNCTION_NAME);
-       
+
        //TimeTaker timer("ServerEnv step");
 
        /* Step time of day */
@@ -1006,21 +1010,21 @@ void ServerEnvironment::step(float dtime)
                m_game_time += inc_i;
                m_game_time_fraction_counter -= (float)inc_i;
        }
-       
+
        /*
                Handle players
        */
        {
                ScopeProfiler sp(g_profiler, "SEnv: handle players avg", SPT_AVG);
-               for(std::list<Player*>::iterator i = m_players.begin();
+               for(std::vector<Player*>::iterator i = m_players.begin();
                                i != m_players.end(); ++i)
                {
                        Player *player = *i;
-                       
+
                        // Ignore disconnected players
                        if(player->peer_id == 0)
                                continue;
-                       
+
                        // Move
                        player->move(dtime, this, 100*BS);
                }
@@ -1035,20 +1039,20 @@ void ServerEnvironment::step(float dtime)
                /*
                        Get player block positions
                */
-               std::list<v3s16> players_blockpos;
-               for(std::list<Player*>::iterator
+               std::vector<v3s16> players_blockpos;
+               for(std::vector<Player*>::iterator
                                i = m_players.begin();
-                               i != m_players.end(); ++i)
-               {
+                               i != m_players.end(); ++i) {
                        Player *player = *i;
                        // Ignore disconnected players
                        if(player->peer_id == 0)
                                continue;
+
                        v3s16 blockpos = getNodeBlockPos(
                                        floatToInt(player->getPosition(), BS));
                        players_blockpos.push_back(blockpos);
                }
-               
+
                /*
                        Update list of active blocks, collecting changes
                */
@@ -1064,7 +1068,7 @@ void ServerEnvironment::step(float dtime)
 
                // Convert active objects that are no more in active blocks to static
                deactivateFarObjects(false);
-               
+
                for(std::set<v3s16>::iterator
                                i = blocks_removed.begin();
                                i != blocks_removed.end(); ++i)
@@ -1073,11 +1077,11 @@ void ServerEnvironment::step(float dtime)
 
                        /* infostream<<"Server: Block " << PP(p)
                                << " became inactive"<<std::endl; */
-                       
+
                        MapBlock *block = m_map->getBlockNoCreateNoEx(p);
                        if(block==NULL)
                                continue;
-                       
+
                        // Set current time as timestamp (and let it set ChangedFlag)
                        block->setTimestamp(m_game_time);
                }
@@ -1110,7 +1114,7 @@ void ServerEnvironment::step(float dtime)
        if(m_active_blocks_nodemetadata_interval.step(dtime, 1.0))
        {
                ScopeProfiler sp(g_profiler, "SEnv: mess in act. blocks avg /1s", SPT_AVG);
-               
+
                float dtime = 1.0;
 
                for(std::set<v3s16>::iterator
@@ -1118,7 +1122,7 @@ void ServerEnvironment::step(float dtime)
                                i != m_active_blocks.m_list.end(); ++i)
                {
                        v3s16 p = *i;
-                       
+
                        /*infostream<<"Server: Block ("<<p.X<<","<<p.Y<<","<<p.Z
                                        <<") being handled"<<std::endl;*/
 
@@ -1128,14 +1132,14 @@ void ServerEnvironment::step(float dtime)
 
                        // Reset block usage timer
                        block->resetUsageTimer();
-                       
+
                        // Set current time as timestamp
                        block->setTimestampNoChangedFlag(m_game_time);
                        // If time has changed much from the one on disk,
                        // set block to be saved when it is unloaded
                        if(block->getTimestamp() > block->getDiskTimestamp() + 60)
                                block->raiseModified(MOD_STATE_WRITE_AT_UNLOAD,
-                                               "Timestamp older than 60s (step)");
+                                       MOD_REASON_BLOCK_EXPIRED);
 
                        // Run node timers
                        std::map<v3s16, NodeTimer> elapsed_timers =
@@ -1153,7 +1157,7 @@ void ServerEnvironment::step(float dtime)
                        }
                }
        }
-       
+
        const float abm_interval = 1.0;
        if(m_active_block_modifier_interval.step(dtime, abm_interval))
        do{ // breakable
@@ -1164,7 +1168,7 @@ void ServerEnvironment::step(float dtime)
                }
                ScopeProfiler sp(g_profiler, "SEnv: modify in blocks avg /1s", SPT_AVG);
                TimeTaker timer("modify in active blocks");
-               
+
                // Initialize handling of ActiveBlockModifiers
                ABMHandler abmhandler(m_abms, abm_interval, this, true);
 
@@ -1173,14 +1177,14 @@ void ServerEnvironment::step(float dtime)
                                i != m_active_blocks.m_list.end(); ++i)
                {
                        v3s16 p = *i;
-                       
+
                        /*infostream<<"Server: Block ("<<p.X<<","<<p.Y<<","<<p.Z
                                        <<") being handled"<<std::endl;*/
 
                        MapBlock *block = m_map->getBlockNoCreateNoEx(p);
-                       if(block==NULL)
+                       if(block == NULL)
                                continue;
-                       
+
                        // Set current time as timestamp
                        block->setTimestampNoChangedFlag(m_game_time);
 
@@ -1197,7 +1201,7 @@ void ServerEnvironment::step(float dtime)
                        m_active_block_interval_overload_skip = (time_ms / max_time_ms) + 1;
                }
        }while(0);
-       
+
        /*
                Step script environment (run global on_step())
        */
@@ -1211,7 +1215,7 @@ void ServerEnvironment::step(float dtime)
                //TimeTaker timer("Step active objects");
 
                g_profiler->avg("SEnv: num of objects", m_active_objects.size());
-               
+
                // This helps the objects to send data at the same time
                bool send_recommended = false;
                m_send_recommended_timer += dtime;
@@ -1234,12 +1238,13 @@ void ServerEnvironment::step(float dtime)
                        // Read messages from object
                        while(!obj->m_messages_out.empty())
                        {
-                               m_active_object_messages.push_back(
-                                               obj->m_messages_out.pop_front());
+                               m_active_object_messages.push(
+                                               obj->m_messages_out.front());
+                               obj->m_messages_out.pop();
                        }
                }
        }
-       
+
        /*
                Manage active objects
        */
@@ -1282,7 +1287,7 @@ u16 getFreeServerActiveObjectId(
                last_used_id ++;
                if(isFreeServerActiveObjectId(last_used_id, objects))
                        return last_used_id;
-               
+
                if(last_used_id == startid)
                        return 0;
        }
@@ -1290,7 +1295,7 @@ u16 getFreeServerActiveObjectId(
 
 u16 ServerEnvironment::addActiveObject(ServerActiveObject *object)
 {
-       assert(object);
+       assert(object); // Pre-condition
        m_added_objects++;
        u16 id = addActiveObjectRaw(object, true, 0);
        return id;
@@ -1438,7 +1443,7 @@ void ServerEnvironment::getRemovedActiveObjects(v3s16 pos, s16 radius,
                        removed_objects.insert(id);
                        continue;
                }
-               
+
                f32 distance_f = object->getBasePosition().getDistanceFrom(pos_f);
                if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
                        if (distance_f <= player_radius_f || player_radius_f == 0)
@@ -1455,9 +1460,9 @@ ActiveObjectMessage ServerEnvironment::getActiveObjectMessage()
 {
        if(m_active_object_messages.empty())
                return ActiveObjectMessage(0);
-       
+
        ActiveObjectMessage message = m_active_object_messages.front();
-       m_active_object_messages.pop_front();
+       m_active_object_messages.pop();
        return message;
 }
 
@@ -1468,7 +1473,7 @@ ActiveObjectMessage ServerEnvironment::getActiveObjectMessage()
 u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
                bool set_changed, u32 dtime_s)
 {
-       assert(object);
+       assert(object); // Pre-condition
        if(object->getId() == 0){
                u16 new_id = getFreeServerActiveObjectId(m_active_objects);
                if(new_id == 0)
@@ -1495,19 +1500,19 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
        }
        /*infostream<<"ServerEnvironment::addActiveObjectRaw(): "
                        <<"added (id="<<object->getId()<<")"<<std::endl;*/
-                       
+
        m_active_objects[object->getId()] = object;
-  
+
        verbosestream<<"ServerEnvironment::addActiveObjectRaw(): "
                        <<"Added id="<<object->getId()<<"; there are now "
                        <<m_active_objects.size()<<" active objects."
                        <<std::endl;
-       
+
        // Register reference in scripting api (must be done before post-init)
        m_script->addObjectReference(object);
        // Post-initialize object
        object->addedToEnvironment(dtime_s);
-       
+
        // Add static data to block
        if(object->isStaticAllowed())
        {
@@ -1525,7 +1530,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
 
                        if(set_changed)
                                block->raiseModified(MOD_STATE_WRITE_NEEDED,
-                                               "addActiveObjectRaw");
+                                       MOD_REASON_ADD_ACTIVE_OBJECT_RAW);
                } else {
                        v3s16 p = floatToInt(objectpos, BS);
                        errorstream<<"ServerEnvironment::addActiveObjectRaw(): "
@@ -1533,7 +1538,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
                                        <<" statically (pos="<<PP(p)<<")"<<std::endl;
                }
        }
-       
+
        return object->getId();
 }
 
@@ -1542,11 +1547,10 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
 */
 void ServerEnvironment::removeRemovedObjects()
 {
-       std::list<u16> objects_to_remove;
+       std::vector<u16> objects_to_remove;
        for(std::map<u16, ServerActiveObject*>::iterator
                        i = m_active_objects.begin();
-                       i != m_active_objects.end(); ++i)
-       {
+                       i != m_active_objects.end(); ++i) {
                u16 id = i->first;
                ServerActiveObject* obj = i->second;
                // This shouldn't happen but check it
@@ -1575,7 +1579,7 @@ void ServerEnvironment::removeRemovedObjects()
                        if (block) {
                                block->m_static_objects.remove(id);
                                block->raiseModified(MOD_STATE_WRITE_NEEDED,
-                                               "removeRemovedObjects/remove");
+                                       MOD_REASON_REMOVE_OBJECTS_REMOVE);
                                obj->m_static_exists = false;
                        } else {
                                infostream<<"Failed to emerge block from which an object to "
@@ -1600,7 +1604,7 @@ void ServerEnvironment::removeRemovedObjects()
                                        block->m_static_objects.m_stored.push_back(i->second);
                                        block->m_static_objects.m_active.erase(id);
                                        block->raiseModified(MOD_STATE_WRITE_NEEDED,
-                                                       "removeRemovedObjects/deactivate");
+                                               MOD_REASON_REMOVE_OBJECTS_DEACTIVATE);
                                }
                        } else {
                                infostream<<"Failed to emerge block from which an object to "
@@ -1616,13 +1620,13 @@ void ServerEnvironment::removeRemovedObjects()
                // Delete
                if(obj->environmentDeletes())
                        delete obj;
+
                // Id to be removed from m_active_objects
                objects_to_remove.push_back(id);
        }
        // Remove references from m_active_objects
-       for(std::list<u16>::iterator i = objects_to_remove.begin();
-                       i != objects_to_remove.end(); ++i)
-       {
+       for(std::vector<u16>::iterator i = objects_to_remove.begin();
+                       i != objects_to_remove.end(); ++i) {
                m_active_objects.erase(*i);
        }
 }
@@ -1666,17 +1670,19 @@ static void print_hexdump(std::ostream &o, const std::string &data)
 */
 void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
 {
-       if(block==NULL)
+       if(block == NULL)
                return;
+
        // Ignore if no stored objects (to not set changed flag)
        if(block->m_static_objects.m_stored.empty())
                return;
+
        verbosestream<<"ServerEnvironment::activateObjects(): "
                        <<"activating objects of block "<<PP(block->getPos())
                        <<" ("<<block->m_static_objects.m_stored.size()
                        <<" objects)"<<std::endl;
        bool large_amount = (block->m_static_objects.m_stored.size() > g_settings->getU16("max_objects_per_block"));
-       if(large_amount){
+       if (large_amount) {
                errorstream<<"suspiciously large amount of objects detected: "
                                <<block->m_static_objects.m_stored.size()<<" in "
                                <<PP(block->getPos())
@@ -1684,32 +1690,28 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
                // Clear stored list
                block->m_static_objects.m_stored.clear();
                block->raiseModified(MOD_STATE_WRITE_NEEDED,
-                               "stored list cleared in activateObjects due to "
-                               "large amount of objects");
+                       MOD_REASON_TOO_MANY_OBJECTS);
                return;
        }
 
        // Activate stored objects
-       std::list<StaticObject> new_stored;
-       for(std::list<StaticObject>::iterator
+       std::vector<StaticObject> new_stored;
+       for (std::vector<StaticObject>::iterator
                        i = block->m_static_objects.m_stored.begin();
-                       i != block->m_static_objects.m_stored.end(); ++i)
-       {
-               /*infostream<<"Server: Creating an active object from "
-                               <<"static data"<<std::endl;*/
+                       i != block->m_static_objects.m_stored.end(); ++i) {
                StaticObject &s_obj = *i;
+
                // Create an active object from the data
                ServerActiveObject *obj = ServerActiveObject::create
                                ((ActiveObjectType) s_obj.type, this, 0, s_obj.pos, s_obj.data);
                // If couldn't create object, store static data back.
-               if(obj==NULL)
-               {
+               if(obj == NULL) {
                        errorstream<<"ServerEnvironment::activateObjects(): "
                                        <<"failed to create active object from static object "
                                        <<"in block "<<PP(s_obj.pos/BS)
                                        <<" type="<<(int)s_obj.type<<" data:"<<std::endl;
                        print_hexdump(verbosestream, s_obj.data);
-                       
+
                        new_stored.push_back(s_obj);
                        continue;
                }
@@ -1722,10 +1724,9 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
        // Clear stored list
        block->m_static_objects.m_stored.clear();
        // Add leftover failed stuff to stored list
-       for(std::list<StaticObject>::iterator
+       for(std::vector<StaticObject>::iterator
                        i = new_stored.begin();
-                       i != new_stored.end(); ++i)
-       {
+                       i != new_stored.end(); ++i) {
                StaticObject &s_obj = *i;
                block->m_static_objects.m_stored.push_back(s_obj);
        }
@@ -1765,14 +1766,13 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
 */
 void ServerEnvironment::deactivateFarObjects(bool force_delete)
 {
-       std::list<u16> objects_to_remove;
+       std::vector<u16> objects_to_remove;
        for(std::map<u16, ServerActiveObject*>::iterator
                        i = m_active_objects.begin();
-                       i != m_active_objects.end(); ++i)
-       {
+                       i != m_active_objects.end(); ++i) {
                ServerActiveObject* obj = i->second;
                assert(obj);
-               
+
                // Do not deactivate if static data creation not allowed
                if(!force_delete && !obj->isStaticAllowed())
                        continue;
@@ -1811,7 +1811,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                        block->m_static_objects.insert(id, s_obj);
                        obj->m_static_block = blockpos_o;
                        block->raiseModified(MOD_STATE_WRITE_NEEDED,
-                                       "deactivateFarObjects: Static data moved in");
+                               MOD_REASON_STATIC_DATA_ADDED);
 
                        // Delete from block where object was located
                        block = m_map->emergeBlock(old_static_block, false);
@@ -1824,7 +1824,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                        }
                        block->m_static_objects.remove(id);
                        block->raiseModified(MOD_STATE_WRITE_NEEDED,
-                                       "deactivateFarObjects: Static data moved out");
+                               MOD_REASON_STATIC_DATA_REMOVED);
                        continue;
                }
 
@@ -1848,7 +1848,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                        // Create new static object
                        std::string staticdata_new = obj->getStaticData();
                        StaticObject s_obj(obj->getType(), objectpos, staticdata_new);
-                       
+
                        bool stays_in_same_block = false;
                        bool data_changed = true;
 
@@ -1857,7 +1857,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                                        stays_in_same_block = true;
 
                                MapBlock *block = m_map->emergeBlock(obj->m_static_block, false);
-                               
+
                                std::map<u16, StaticObject>::iterator n =
                                                block->m_static_objects.m_active.find(id);
                                if(n != block->m_static_objects.m_active.end()){
@@ -1877,7 +1877,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                        }
 
                        bool shall_be_written = (!stays_in_same_block || data_changed);
-                       
+
                        // Delete old static object
                        if(obj->m_static_exists)
                        {
@@ -1889,8 +1889,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                                        // Only mark block as modified if data changed considerably
                                        if(shall_be_written)
                                                block->raiseModified(MOD_STATE_WRITE_NEEDED,
-                                                               "deactivateFarObjects: Static data "
-                                                               "changed considerably");
+                                                       MOD_REASON_STATIC_DATA_CHANGED);
                                }
                        }
 
@@ -1932,13 +1931,12 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                                        // Store static data
                                        u16 store_id = pending_delete ? id : 0;
                                        block->m_static_objects.insert(store_id, s_obj);
-                                       
+
                                        // Only mark block as modified if data changed considerably
                                        if(shall_be_written)
                                                block->raiseModified(MOD_STATE_WRITE_NEEDED,
-                                                               "deactivateFarObjects: Static data "
-                                                               "changed considerably");
-                                       
+                                                       MOD_REASON_STATIC_DATA_CHANGED);
+
                                        obj->m_static_exists = true;
                                        obj->m_static_block = block->getPos();
                                }
@@ -1968,7 +1966,7 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
                        obj->m_pending_deactivation = true;
                        continue;
                }
-               
+
                verbosestream<<"ServerEnvironment::deactivateFarObjects(): "
                                <<"object id="<<id<<" is not known by clients"
                                <<"; deleting"<<std::endl;
@@ -1986,9 +1984,8 @@ void ServerEnvironment::deactivateFarObjects(bool force_delete)
        }
 
        // Remove references from m_active_objects
-       for(std::list<u16>::iterator i = objects_to_remove.begin();
-                       i != objects_to_remove.end(); ++i)
-       {
+       for(std::vector<u16>::iterator i = objects_to_remove.begin();
+                       i != objects_to_remove.end(); ++i) {
                m_active_objects.erase(*i);
        }
 }
@@ -2025,9 +2022,8 @@ ClientEnvironment::~ClientEnvironment()
                delete i->second;
        }
 
-       for(std::list<ClientSimpleObject*>::iterator
-                       i = m_simple_objects.begin(); i != m_simple_objects.end(); ++i)
-       {
+       for(std::vector<ClientSimpleObject*>::iterator
+                       i = m_simple_objects.begin(); i != m_simple_objects.end(); ++i) {
                delete *i;
        }
 
@@ -2052,16 +2048,16 @@ void ClientEnvironment::addPlayer(Player *player)
                It is a failure if player is local and there already is a local
                player
        */
-       assert(!(player->isLocal() == true && getLocalPlayer() != NULL));
+       FATAL_ERROR_IF(player->isLocal() == true && getLocalPlayer() != NULL,
+               "Player is local but there is already a local player");
 
        Environment::addPlayer(player);
 }
 
 LocalPlayer * ClientEnvironment::getLocalPlayer()
 {
-       for(std::list<Player*>::iterator i = m_players.begin();
-                       i != m_players.end(); ++i)
-       {
+       for(std::vector<Player*>::iterator i = m_players.begin();
+                       i != m_players.end(); ++i) {
                Player *player = *i;
                if(player->isLocal())
                        return (LocalPlayer*)player;
@@ -2084,15 +2080,15 @@ void ClientEnvironment::step(float dtime)
        LocalPlayer *lplayer = getLocalPlayer();
        assert(lplayer);
        // collision info queue
-       std::list<CollisionInfo> player_collisions;
-       
+       std::vector<CollisionInfo> player_collisions;
+
        /*
                Get the speed the player is going
        */
        bool is_climbing = lplayer->is_climbing;
-       
+
        f32 player_speed = lplayer->getSpeed().getLength();
-       
+
        /*
                Maximum position increment
        */
@@ -2104,15 +2100,15 @@ void ClientEnvironment::step(float dtime)
        f32 dtime_max_increment = 1;
        if(player_speed > 0.001)
                dtime_max_increment = position_max_increment / player_speed;
-       
+
        // Maximum time increment is 10ms or lower
        if(dtime_max_increment > 0.01)
                dtime_max_increment = 0.01;
-       
+
        // Don't allow overly huge dtime
        if(dtime > 0.5)
                dtime = 0.5;
-       
+
        f32 dtime_downcount = dtime;
 
        /*
@@ -2140,11 +2136,11 @@ void ClientEnvironment::step(float dtime)
                        */
                        dtime_downcount = 0;
                }
-               
+
                /*
                        Handle local player
                */
-               
+
                {
                        // Apply physics
                        if(free_move == false && is_climbing == false)
@@ -2170,10 +2166,10 @@ void ClientEnvironment::step(float dtime)
                                        if(dl > lplayer->movement_liquid_fluidity_smooth)
                                                dl = lplayer->movement_liquid_fluidity_smooth;
                                        dl *= (lplayer->liquid_viscosity * viscosity_factor) + (1 - viscosity_factor);
-                                       
+
                                        v3f d = d_wanted.normalize() * dl;
                                        speed += d;
-                                       
+
 #if 0 // old code
                                        if(speed.X > lplayer->movement_liquid_fluidity + lplayer->movement_liquid_fluidity_smooth)      speed.X -= lplayer->movement_liquid_fluidity_smooth;
                                        if(speed.X < -lplayer->movement_liquid_fluidity - lplayer->movement_liquid_fluidity_smooth)     speed.X += lplayer->movement_liquid_fluidity_smooth;
@@ -2196,13 +2192,11 @@ void ClientEnvironment::step(float dtime)
                }
        }
        while(dtime_downcount > 0.001);
-               
+
        //std::cout<<"Looped "<<loopcount<<" times."<<std::endl;
-       
-       for(std::list<CollisionInfo>::iterator
-                       i = player_collisions.begin();
-                       i != player_collisions.end(); ++i)
-       {
+
+       for(std::vector<CollisionInfo>::iterator i = player_collisions.begin();
+                       i != player_collisions.end(); ++i) {
                CollisionInfo &info = *i;
                v3f speed_diff = info.new_speed - info.old_speed;;
                // Handle only fall damage
@@ -2235,14 +2229,14 @@ void ClientEnvironment::step(float dtime)
                        }
                }
        }
-       
+
        /*
                A quick draft of lava damage
        */
        if(m_lava_hurt_interval.step(dtime, 1.0))
        {
                v3f pf = lplayer->getPosition();
-               
+
                // Feet, middle and head
                v3s16 p1 = floatToInt(pf + v3f(0, BS*0.1, 0), BS);
                MapNode n1 = m_map->getNodeNoEx(p1);
@@ -2258,7 +2252,7 @@ void ClientEnvironment::step(float dtime)
                                m_gamedef->ndef()->get(n2).damage_per_second);
                damage_per_second = MYMAX(damage_per_second,
                                m_gamedef->ndef()->get(n3).damage_per_second);
-               
+
                if(damage_per_second != 0)
                {
                        damageLocalPlayer(damage_per_second, true);
@@ -2317,16 +2311,14 @@ void ClientEnvironment::step(float dtime)
        /*
                Stuff that can be done in an arbitarily large dtime
        */
-       for(std::list<Player*>::iterator i = m_players.begin();
-                       i != m_players.end(); ++i)
-       {
+       for(std::vector<Player*>::iterator i = m_players.begin();
+                       i != m_players.end(); ++i) {
                Player *player = *i;
-               
+
                /*
                        Handle non-local players
                */
-               if(player->isLocal() == false)
-               {
+               if(player->isLocal() == false) {
                        // Move
                        player->move(dtime, this, 100*BS);
 
@@ -2354,7 +2346,7 @@ void ClientEnvironment::step(float dtime)
        /*
                Step active objects and update lighting of them
        */
-       
+
        g_profiler->avg("CEnv: num of objects", m_active_objects.size());
        bool update_lighting = m_active_object_light_update_interval.step(dtime, 0.21);
        for(std::map<u16, ClientActiveObject*>::iterator
@@ -2387,20 +2379,22 @@ void ClientEnvironment::step(float dtime)
                Step and handle simple objects
        */
        g_profiler->avg("CEnv: num of simple objects", m_simple_objects.size());
-       for(std::list<ClientSimpleObject*>::iterator
-                       i = m_simple_objects.begin(); i != m_simple_objects.end();)
-       {
-               ClientSimpleObject *simple = *i;
-               std::list<ClientSimpleObject*>::iterator cur = i;
-               ++i;
+       for(std::vector<ClientSimpleObject*>::iterator
+                       i = m_simple_objects.begin(); i != m_simple_objects.end();) {
+               std::vector<ClientSimpleObject*>::iterator cur = i;
+               ClientSimpleObject *simple = *cur;
+
                simple->step(dtime);
-               if(simple->m_to_be_removed){
+               if(simple->m_to_be_removed) {
                        delete simple;
-                       m_simple_objects.erase(cur);
+                       i = m_simple_objects.erase(cur);
+               }
+               else {
+                       ++i;
                }
        }
 }
-       
+
 void ClientEnvironment::addSimpleObject(ClientSimpleObject *simple)
 {
        m_simple_objects.push_back(simple);
@@ -2435,7 +2429,7 @@ u16 getFreeClientActiveObjectId(
                last_used_id ++;
                if(isFreeClientActiveObjectId(last_used_id, objects))
                        return last_used_id;
-               
+
                if(last_used_id == startid)
                        return 0;
        }
@@ -2443,7 +2437,7 @@ u16 getFreeClientActiveObjectId(
 
 u16 ClientEnvironment::addActiveObject(ClientActiveObject *object)
 {
-       assert(object);
+       assert(object); // Pre-condition
        if(object->getId() == 0)
        {
                u16 new_id = getFreeClientActiveObjectId(m_active_objects);
@@ -2496,7 +2490,7 @@ void ClientEnvironment::addActiveObject(u16 id, u8 type,
                                <<std::endl;
                return;
        }
-       
+
        obj->setId(id);
 
        try
@@ -2565,11 +2559,9 @@ void ClientEnvironment::damageLocalPlayer(u8 damage, bool handle_hp)
 {
        LocalPlayer *lplayer = getLocalPlayer();
        assert(lplayer);
-       
-       if(handle_hp){
-               if (lplayer->hp == 0) // Don't damage a dead player
-                       return;
-               if(lplayer->hp > damage)
+
+       if (handle_hp) {
+               if (lplayer->hp > damage)
                        lplayer->hp -= damage;
                else
                        lplayer->hp = 0;
@@ -2593,7 +2585,7 @@ void ClientEnvironment::updateLocalPlayerBreath(u16 breath)
 /*
        Client likes to call these
 */
-       
+
 void ClientEnvironment::getActiveObjects(v3f origin, f32 max_d,
                std::vector<DistanceSortedActiveObject> &dest)
 {