Noise: Prevent unittest crash caused by division by zero
[oweals/minetest.git] / src / serverenvironment.cpp
index cbdc747d1f9e8cd375a59bbcf79d425a65c7dcea..19dff956eb9dd748c413159d6f8c73de4447cd26 100644 (file)
@@ -30,7 +30,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "remoteplayer.h"
 #include "scripting_server.h"
 #include "server.h"
-#include "voxelalgorithms.h"
 #include "util/serialize.h"
 #include "util/basic_macros.h"
 #include "util/pointedthing.h"
@@ -54,8 +53,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 ABMWithState::ABMWithState(ActiveBlockModifier *abm_):
-       abm(abm_),
-       timer(0)
+       abm(abm_)
 {
        // Initialize timer to random value to spread processing
        float itv = abm->getTriggerInterval();
@@ -71,9 +69,8 @@ ABMWithState::ABMWithState(ActiveBlockModifier *abm_):
 
 void LBMContentMapping::deleteContents()
 {
-       for (std::vector<LoadingBlockModifierDef *>::iterator it = lbm_list.begin();
-               it != lbm_list.end(); ++it) {
-               delete *it;
+       for (auto &it : lbm_list) {
+               delete it;
        }
 }
 
@@ -85,24 +82,21 @@ void LBMContentMapping::addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamed
 
        lbm_list.push_back(lbm_def);
 
-       for (std::set<std::string>::const_iterator it = lbm_def->trigger_contents.begin();
-               it != lbm_def->trigger_contents.end(); ++it) {
+       for (const std::string &nodeTrigger: lbm_def->trigger_contents) {
                std::set<content_t> c_ids;
-               bool found = nodedef->getIds(*it, c_ids);
+               bool found = nodedef->getIds(nodeTrigger, c_ids);
                if (!found) {
-                       content_t c_id = gamedef->allocateUnknownNodeId(*it);
+                       content_t c_id = gamedef->allocateUnknownNodeId(nodeTrigger);
                        if (c_id == CONTENT_IGNORE) {
                                // Seems it can't be allocated.
-                               warningstream << "Could not internalize node name \"" << *it
+                               warningstream << "Could not internalize node name \"" << nodeTrigger
                                        << "\" while loading LBM \"" << lbm_def->name << "\"." << std::endl;
                                continue;
                        }
                        c_ids.insert(c_id);
                }
 
-               for (std::set<content_t>::const_iterator iit =
-                       c_ids.begin(); iit != c_ids.end(); ++iit) {
-                       content_t c_id = *iit;
+               for (content_t c_id : c_ids) {
                        map[c_id].push_back(lbm_def);
                }
        }
@@ -111,7 +105,7 @@ void LBMContentMapping::addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamed
 const std::vector<LoadingBlockModifierDef *> *
 LBMContentMapping::lookup(content_t c) const
 {
-       container_map::const_iterator it = map.find(c);
+       lbm_map::const_iterator it = map.find(c);
        if (it == map.end())
                return NULL;
        // This first dereferences the iterator, returning
@@ -122,13 +116,12 @@ LBMContentMapping::lookup(content_t c) const
 
 LBMManager::~LBMManager()
 {
-       for (std::map<std::string, LoadingBlockModifierDef *>::iterator it =
-               m_lbm_defs.begin(); it != m_lbm_defs.end(); ++it) {
-               delete it->second;
+       for (auto &m_lbm_def : m_lbm_defs) {
+               delete m_lbm_def.second;
        }
-       for (lbm_lookup_map::iterator it = m_lbm_lookup.begin();
-               it != m_lbm_lookup.end(); ++it) {
-               (it->second).deleteContents();
+
+       for (auto &it : m_lbm_lookup) {
+               (it.second).deleteContents();
        }
 }
 
@@ -214,12 +207,11 @@ void LBMManager::loadIntroductionTimes(const std::string &times,
        LBMContentMapping &lbms_we_introduce_now = m_lbm_lookup[now];
        LBMContentMapping &lbms_running_always = m_lbm_lookup[U32_MAX];
 
-       for (std::map<std::string, LoadingBlockModifierDef *>::iterator it =
-               m_lbm_defs.begin(); it != m_lbm_defs.end(); ++it) {
-               if (it->second->run_at_every_load) {
-                       lbms_running_always.addLBM(it->second, gamedef);
+       for (auto &m_lbm_def : m_lbm_defs) {
+               if (m_lbm_def.second->run_at_every_load) {
+                       lbms_running_always.addLBM(m_lbm_def.second, gamedef);
                } else {
-                       lbms_we_introduce_now.addLBM(it->second, gamedef);
+                       lbms_we_introduce_now.addLBM(m_lbm_def.second, gamedef);
                }
        }
 
@@ -235,18 +227,16 @@ std::string LBMManager::createIntroductionTimesString()
                "attempted to query on non fully set up LBMManager");
 
        std::ostringstream oss;
-       for (lbm_lookup_map::iterator it = m_lbm_lookup.begin();
-               it != m_lbm_lookup.end(); ++it) {
-               u32 time = it->first;
-               std::vector<LoadingBlockModifierDef *> &lbm_list = it->second.lbm_list;
-               for (std::vector<LoadingBlockModifierDef *>::iterator iit = lbm_list.begin();
-                       iit != lbm_list.end(); ++iit) {
+       for (const auto &it : m_lbm_lookup) {
+               u32 time = it.first;
+               const std::vector<LoadingBlockModifierDef *> &lbm_list = it.second.lbm_list;
+               for (const auto &lbm_def : lbm_list) {
                        // Don't add if the LBM runs at every load,
                        // then introducement time is hardcoded
                        // and doesn't need to be stored
-                       if ((*iit)->run_at_every_load)
+                       if (lbm_def->run_at_every_load)
                                continue;
-                       oss << (*iit)->name << "~" << time << ";";
+                       oss << lbm_def->name << "~" << time << ";";
                }
        }
        return oss.str();
@@ -274,9 +264,8 @@ void LBMManager::applyLBMs(ServerEnvironment *env, MapBlock *block, u32 stamp)
                                                iit->second.lookup(c);
                                        if (!lbm_list)
                                                continue;
-                                       for (std::vector<LoadingBlockModifierDef *>::const_iterator iit =
-                                               lbm_list->begin(); iit != lbm_list->end(); ++iit) {
-                                               (*iit)->trigger(env, pos + pos_of_block, n);
+                                       for (auto lbmdef : *lbm_list) {
+                                               lbmdef->trigger(env, pos + pos_of_block, n);
                                        }
                                }
                        }
@@ -365,15 +354,7 @@ ServerEnvironment::ServerEnvironment(ServerMap *map,
        m_map(map),
        m_script(scriptIface),
        m_server(server),
-       m_path_world(path_world),
-       m_send_recommended_timer(0),
-       m_active_block_interval_overload_skip(0),
-       m_game_time(0),
-       m_game_time_fraction_counter(0),
-       m_last_clear_objects_time(0),
-       m_recommended_send_interval(0.1),
-       m_max_lag_estimate(0.1),
-       m_player_database(NULL)
+       m_path_world(path_world)
 {
        // Determine which database backend to use
        std::string conf_path = path_world + DIR_DELIM + "world.mt";
@@ -579,7 +560,8 @@ 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
-               if (objectpos_over_limit(playersao->getBasePosition())) {
+               ServerMap &map = getServerMap();
+               if (map.getMapgenParams()->saoPosOverLimit(playersao->getBasePosition())) {
                        actionstream << "Respawn position for player \""
                                << player->getName() << "\" outside limits, resetting" << std::endl;
                        playersao->setBasePosition(m_server->findSpawnPos());
@@ -999,9 +981,10 @@ bool ServerEnvironment::swapNode(v3s16 p, const MapNode &n)
        return true;
 }
 
-void ServerEnvironment::getObjectsInsideRadius(std::vector<u16> &objects, v3f pos, float radius)
+void ServerEnvironment::getObjectsInsideRadius(std::vector<u16> &objects, v3f pos,
+       float radius)
 {
-       for (ActiveObjectMap::iterator i = m_active_objects.begin();
+       for (ServerActiveObjectMap::iterator i = m_active_objects.begin();
                i != m_active_objects.end(); ++i) {
                ServerActiveObject* obj = i->second;
                u16 id = i->first;
@@ -1017,7 +1000,7 @@ void ServerEnvironment::clearObjects(ClearObjectsMode mode)
        infostream << "ServerEnvironment::clearObjects(): "
                << "Removing all active objects" << std::endl;
        std::vector<u16> objects_to_remove;
-       for (ActiveObjectMap::iterator i = m_active_objects.begin();
+       for (ServerActiveObjectMap::iterator i = m_active_objects.begin();
                i != m_active_objects.end(); ++i) {
                ServerActiveObject* obj = i->second;
                if (obj->getType() == ACTIVEOBJECT_TYPE_PLAYER)
@@ -1167,7 +1150,8 @@ void ServerEnvironment::step(float dtime)
        // Update this one
        // NOTE: This is kind of funny on a singleplayer game, but doesn't
        // really matter that much.
-       static const float server_step = g_settings->getFloat("dedicated_server_step");
+       static thread_local const float server_step =
+                       g_settings->getFloat("dedicated_server_step");
        m_recommended_send_interval = server_step;
 
        /*
@@ -1228,7 +1212,8 @@ void ServerEnvironment::step(float dtime)
                /*
                        Update list of active blocks, collecting changes
                */
-               static const s16 active_block_range = g_settings->getS16("active_block_range");
+               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,
@@ -1395,7 +1380,7 @@ void ServerEnvironment::step(float dtime)
                        send_recommended = true;
                }
 
-               for(ActiveObjectMap::iterator i = m_active_objects.begin();
+               for (ServerActiveObjectMap::iterator i = m_active_objects.begin();
                        i != m_active_objects.end(); ++i) {
                        ServerActiveObject* obj = i->second;
                        // Don't step if is to be removed or stored statically
@@ -1429,7 +1414,7 @@ void ServerEnvironment::step(float dtime)
                Manage particle spawner expiration
        */
        if (m_particle_management_interval.step(dtime, 1.0)) {
-               for (UNORDERED_MAP<u32, float>::iterator i = m_particle_spawners.begin();
+               for (std::unordered_map<u32, float>::iterator i = m_particle_spawners.begin();
                        i != m_particle_spawners.end(); ) {
                        //non expiring spawners
                        if (i->second == PARTICLE_SPAWNER_NO_EXPIRY) {
@@ -1454,7 +1439,7 @@ u32 ServerEnvironment::addParticleSpawner(float exptime)
        u32 id = 0;
        for (;;) { // look for unused particlespawner id
                id++;
-               UNORDERED_MAP<u32, float>::iterator f = m_particle_spawners.find(id);
+               std::unordered_map<u32, float>::iterator f = m_particle_spawners.find(id);
                if (f == m_particle_spawners.end()) {
                        m_particle_spawners[id] = time;
                        break;
@@ -1476,7 +1461,7 @@ u32 ServerEnvironment::addParticleSpawner(float exptime, u16 attached_id)
 void ServerEnvironment::deleteParticleSpawner(u32 id, bool remove_from_object)
 {
        m_particle_spawners.erase(id);
-       UNORDERED_MAP<u32, u16>::iterator it = m_particle_spawner_attachments.find(id);
+       std::unordered_map<u32, u16>::iterator it = m_particle_spawner_attachments.find(id);
        if (it != m_particle_spawner_attachments.end()) {
                u16 obj_id = (*it).second;
                ServerActiveObject *sao = getActiveObject(obj_id);
@@ -1489,11 +1474,11 @@ void ServerEnvironment::deleteParticleSpawner(u32 id, bool remove_from_object)
 
 ServerActiveObject* ServerEnvironment::getActiveObject(u16 id)
 {
-       ActiveObjectMap::iterator n = m_active_objects.find(id);
+       ServerActiveObjectMap::const_iterator n = m_active_objects.find(id);
        return (n != m_active_objects.end() ? n->second : NULL);
 }
 
-bool isFreeServerActiveObjectId(u16 id, ActiveObjectMap &objects)
+bool isFreeServerActiveObjectId(u16 id, ServerActiveObjectMap &objects)
 {
        if (id == 0)
                return false;
@@ -1501,7 +1486,7 @@ bool isFreeServerActiveObjectId(u16 id, ActiveObjectMap &objects)
        return objects.find(id) == objects.end();
 }
 
-u16 getFreeServerActiveObjectId(ActiveObjectMap &objects)
+u16 getFreeServerActiveObjectId(ServerActiveObjectMap &objects)
 {
        //try to reuse id's as late as possible
        static u16 last_used_id = 0;
@@ -1546,7 +1531,7 @@ void ServerEnvironment::getAddedActiveObjects(PlayerSAO *playersao, s16 radius,
                - discard objects that are found in current_objects.
                - add remaining objects to added_objects
        */
-       for (ActiveObjectMap::iterator i = m_active_objects.begin();
+       for (ServerActiveObjectMap::iterator i = m_active_objects.begin();
                i != m_active_objects.end(); ++i) {
                u16 id = i->first;
 
@@ -1642,7 +1627,7 @@ void ServerEnvironment::setStaticForActiveObjectsInBlock(
                so_it = block->m_static_objects.m_active.begin();
                so_it != block->m_static_objects.m_active.end(); ++so_it) {
                // Get the ServerActiveObject counterpart to this StaticObject
-               ActiveObjectMap::iterator ao_it = m_active_objects.find(so_it->first);
+               ServerActiveObjectMap::const_iterator ao_it = m_active_objects.find(so_it->first);
                if (ao_it == m_active_objects.end()) {
                        // If this ever happens, there must be some kind of nasty bug.
                        errorstream << "ServerEnvironment::setStaticForObjectsInBlock(): "
@@ -1667,6 +1652,38 @@ ActiveObjectMessage ServerEnvironment::getActiveObjectMessage()
        return message;
 }
 
+void ServerEnvironment::getSelectedActiveObjects(
+       const core::line3d<f32> &shootline_on_map,
+       std::vector<PointedThing> &objects)
+{
+       std::vector<u16> objectIds;
+       getObjectsInsideRadius(objectIds, shootline_on_map.start,
+               shootline_on_map.getLength() + 10.0f);
+       const v3f line_vector = shootline_on_map.getVector();
+
+       for (u32 i = 0; i < objectIds.size(); i++) {
+               ServerActiveObject* obj = getActiveObject(objectIds[i]);
+
+               aabb3f selection_box;
+               if (!obj->getSelectionBox(&selection_box))
+                       continue;
+
+               v3f pos = obj->getBasePosition();
+
+               aabb3f offsetted_box(selection_box.MinEdge + pos,
+                       selection_box.MaxEdge + pos);
+
+               v3f current_intersection;
+               v3s16 current_normal;
+               if (boxLineCollision(offsetted_box, shootline_on_map.start, line_vector,
+                               &current_intersection, &current_normal)) {
+                       objects.push_back(PointedThing(
+                               (s16) objectIds[i], current_intersection, current_normal,
+                               (current_intersection - shootline_on_map.start).getLengthSQ()));
+               }
+       }
+}
+
 /*
        ************ Private methods *************
 */
@@ -1761,7 +1778,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
 void ServerEnvironment::removeRemovedObjects()
 {
        std::vector<u16> objects_to_remove;
-       for(ActiveObjectMap::iterator i = m_active_objects.begin();
+       for(ServerActiveObjectMap::iterator i = m_active_objects.begin();
                i != m_active_objects.end(); ++i) {
                u16 id = i->first;
                ServerActiveObject* obj = i->second;
@@ -1979,7 +1996,7 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
 void ServerEnvironment::deactivateFarObjects(bool _force_delete)
 {
        std::vector<u16> objects_to_remove;
-       for(ActiveObjectMap::iterator i = m_active_objects.begin();
+       for (ServerActiveObjectMap::iterator i = m_active_objects.begin();
                i != m_active_objects.end(); ++i) {
                // force_delete might be overriden per object
                bool force_delete = _force_delete;