]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/game.cpp
Safe digging and placing (#6127)
[dragonfireclient.git] / src / game.cpp
index cdbd9230106ccfaf2bb8afaa200a469ad9015cda..c3d8446344237ea17ea95d27cc8d5330653bb3e4 100644 (file)
@@ -54,6 +54,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "raycast.h"
 #include "server.h"
 #include "settings.h"
+#include "shader.h"
 #include "sky.h"
 #include "subgame.h"
 #include "tool.h"
@@ -68,8 +69,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        #include "sound_openal.h"
 #endif
 
-extern Settings *g_settings;
-extern Profiler *g_profiler;
 
 /*
        Text input system
@@ -247,7 +246,7 @@ void update_profiler_gui(gui::IGUIStaticText *guitext_profiler, FontEngine *fe,
                setStaticText(guitext_profiler, text.c_str());
                guitext_profiler->setVisible(true);
 
-               s32 w = fe->getTextWidth(text.c_str());
+               s32 w = fe->getTextWidth(text);
 
                if (w < 400)
                        w = 400;
@@ -290,11 +289,9 @@ class ProfilerGraph
        };
        std::deque<Piece> m_log;
 public:
-       u32 m_log_max_size;
+       u32 m_log_max_size = 200;
 
-       ProfilerGraph():
-               m_log_max_size(200)
-       {}
+       ProfilerGraph() = default;
 
        void put(const Profiler::GraphValues &values)
        {
@@ -313,14 +310,10 @@ class ProfilerGraph
                // to be the same for each call to prevent flickering
                std::map<std::string, Meta> m_meta;
 
-               for (std::deque<Piece>::const_iterator k = m_log.begin();
-                               k != m_log.end(); ++k) {
-                       const Piece &piece = *k;
-
-                       for (Profiler::GraphValues::const_iterator i = piece.values.begin();
-                                       i != piece.values.end(); ++i) {
-                               const std::string &id = i->first;
-                               const float &value = i->second;
+               for (const Piece &piece : m_log) {
+                       for (const auto &i : piece.values) {
+                               const std::string &id = i.first;
+                               const float &value = i.second;
                                std::map<std::string, Meta>::iterator j = m_meta.find(id);
 
                                if (j == m_meta.end()) {
@@ -348,9 +341,8 @@ class ProfilerGraph
                        sizeof(usable_colors) / sizeof(*usable_colors);
                u32 next_color_i = 0;
 
-               for (std::map<std::string, Meta>::iterator i = m_meta.begin();
-                               i != m_meta.end(); ++i) {
-                       Meta &meta = i->second;
+               for (auto &i : m_meta) {
+                       Meta &meta = i.second;
                        video::SColor color(255, 200, 200, 200);
 
                        if (next_color_i < usable_colors_count)
@@ -400,9 +392,7 @@ class ProfilerGraph
                        float lastscaledvalue = 0.0;
                        bool lastscaledvalue_exists = false;
 
-                       for (std::deque<Piece>::const_iterator j = m_log.begin();
-                                       j != m_log.end(); ++j) {
-                               const Piece &piece = *j;
+                       for (const Piece &piece : m_log) {
                                float value = 0;
                                bool value_exists = false;
                                Profiler::GraphValues::const_iterator k =
@@ -762,8 +752,8 @@ class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactor
 
        void setSky(Sky *sky) {
                m_sky = sky;
-               for (size_t i = 0; i < created_nosky.size(); ++i) {
-                       created_nosky[i]->setSky(m_sky);
+               for (GameGlobalShaderConstantSetter *ggscs : created_nosky) {
+                       ggscs->setSky(m_sky);
                }
                created_nosky.clear();
        }
@@ -792,7 +782,7 @@ bool nodePlacementPrediction(Client &client, const ItemDefinition &playeritem_de
        if (!is_valid_position)
                return false;
 
-       if (prediction != "" && !nodedef->get(node).rightclickable) {
+       if (!prediction.empty() && !nodedef->get(node).rightclickable) {
                verbosestream << "Node placement prediction for "
                              << playeritem_def.name << " is "
                              << prediction << std::endl;
@@ -977,7 +967,7 @@ static void updateChat(Client &client, f32 dtime, bool show_debug,
        }
 
        // Get new messages from client
-       std::wstring message = L"";
+       std::wstring message;
        while (client.getChatMessage(message)) {
                chat_backend.addUnparsedMessage(message);
        }
@@ -1115,8 +1105,8 @@ void KeyCache::populate()
        if (handler) {
                // First clear all keys, then re-add the ones we listen for
                handler->dontListenForKeys();
-               for (size_t i = 0; i < KeyType::INTERNAL_ENUM_COUNT; i++) {
-                       handler->listenForKey(key[i]);
+               for (const KeyPress &k : key) {
+                       handler->listenForKey(k);
                }
                handler->listenForKey(EscapeKey);
                handler->listenForKey(CancelKey);
@@ -1152,6 +1142,7 @@ struct GameRunData {
        bool digging;
        bool ldown_for_dig;
        bool dig_instantly;
+       bool digging_blocked;
        bool left_punch;
        bool update_wielded_item_trigger;
        bool reset_jump_timer;
@@ -1383,7 +1374,7 @@ class Game {
 
        GameOnDemandSoundFetcher soundfetcher; // useful when testing
        ISoundManager *sound;
-       bool sound_is_dummy;
+       bool sound_is_dummy = false;
        SoundMaker *soundmaker;
 
        ChatBackend *chat_backend;
@@ -1463,9 +1454,9 @@ class Game {
        f32  m_cache_cam_smoothing;
        f32  m_cache_fog_start;
 
-       bool m_invert_mouse;
-       bool m_first_loop_after_window_activation;
-       bool m_camera_offset_changed;
+       bool m_invert_mouse = false;
+       bool m_first_loop_after_window_activation = false;
+       bool m_camera_offset_changed = false;
 
 #ifdef __ANDROID__
        bool m_cache_hold_aux1;
@@ -1481,7 +1472,6 @@ Game::Game() :
        itemdef_manager(NULL),
        nodedef_manager(NULL),
        sound(NULL),
-       sound_is_dummy(false),
        soundmaker(NULL),
        chat_backend(NULL),
        current_formspec(NULL),
@@ -1495,10 +1485,7 @@ Game::Game() :
        sky(NULL),
        local_inventory(NULL),
        hud(NULL),
-       mapper(NULL),
-       m_invert_mouse(false),
-       m_first_loop_after_window_activation(false),
-       m_camera_offset_changed(false)
+       mapper(NULL)
 {
        g_settings->registerChangedCallback("doubletap_jump",
                &settingChangedCallback, this);
@@ -1805,7 +1792,7 @@ bool Game::init(
                return false;
 
        // Create a server if not connecting to an existing one
-       if (*address == "") {
+       if (address->empty()) {
                if (!createSingleplayerServer(map_dir, gamespec, port, address))
                        return false;
        }
@@ -2167,7 +2154,7 @@ bool Game::connectToServer(const std::string &playername,
 
                        wait_time += dtime;
                        // Only time out if we aren't waiting for the server we started
-                       if ((*address != "") && (wait_time > 10)) {
+                       if ((!address->empty()) && (wait_time > 10)) {
                                bool sent_old_init = g_settings->getFlag("send_pre_v25_init");
                                // If no pre v25 init was sent, and no answer was received,
                                // but the low level connection could be established
@@ -2832,6 +2819,9 @@ void Game::toggleMinimap(bool shift_pressed)
        if (hud_flags & HUD_FLAG_MINIMAP_VISIBLE) {
                mode = mapper->getMinimapMode();
                mode = (MinimapMode)((int)mode + 1);
+               // If radar is disabled and in, or switching to, radar mode
+               if (!(hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE) && mode > 3)
+                       mode = MINIMAP_MODE_OFF;
        }
 
        flags.show_minimap = true;
@@ -3174,8 +3164,9 @@ void Game::processClientEvents(CameraOrientation *cam)
                        break;
 
                case CE_SHOW_FORMSPEC:
-                       if (*(event.show_formspec.formspec) == "") {
-                               if (current_formspec && ( *(event.show_formspec.formname) == "" || *(event.show_formspec.formname) == cur_formname) ){
+                       if (event.show_formspec.formspec->empty()) {
+                               if (current_formspec && (event.show_formspec.formname->empty()
+                                               || *(event.show_formspec.formname) == cur_formname)) {
                                        current_formspec->quitMenu();
                                }
                        } else {
@@ -3569,6 +3560,11 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
                hud->updateSelectionMesh(camera_offset);
        }
 
+       if (runData.digging_blocked && !isLeftPressed()) {
+               // allow digging again if button is not pressed
+               runData.digging_blocked = false;
+       }
+
        /*
                Stop digging when
                - releasing left mouse button
@@ -3613,7 +3609,8 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug)
 
        soundmaker->m_player_leftpunch_sound.name = "";
 
-       if (isRightPressed())
+       // Prepare for repeating, unless we're not supposed to
+       if (isRightPressed() && !g_settings->getBool("safe_dig_and_place"))
                runData.repeat_rightclick_timer += dtime;
        else
                runData.repeat_rightclick_timer = 0;
@@ -3712,7 +3709,7 @@ PointedThing Game::updatePointedThing(
        }
 
        // Update selection mesh light level and vertex colors
-       if (selectionboxes->size() > 0) {
+       if (!selectionboxes->empty()) {
                v3f pf = hud->getSelectionPos();
                v3s16 p = floatToInt(pf, BS);
 
@@ -3721,8 +3718,8 @@ PointedThing Game::updatePointedThing(
                u16 node_light = getInteriorLight(n, -1, nodedef);
                u16 light_level = node_light;
 
-               for (u8 i = 0; i < 6; i++) {
-                       n = map.getNodeNoEx(p + g_6dirs[i]);
+               for (const v3s16 &dir : g_6dirs) {
+                       n = map.getNodeNoEx(p + dir);
                        node_light = getInteriorLight(n, -1, nodedef);
                        if (node_light > light_level)
                                light_level = node_light;
@@ -3772,6 +3769,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
        ClientMap &map = client->getEnv().getClientMap();
 
        if (runData.nodig_delay_timer <= 0.0 && isLeftPressed()
+                       && !runData.digging_blocked
                        && client->checkPrivilege("interact")) {
                handleDigging(pointed, nodepos, playeritem_toolcap, dtime);
        }
@@ -3796,7 +3794,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
                runData.repeat_rightclick_timer = 0;
                infostream << "Ground right-clicked" << std::endl;
 
-               if (meta && meta->getString("formspec") != "" && !random_input
+               if (meta && !meta->getString("formspec").empty() && !random_input
                                && !isKeyDown(KeyType::SNEAK)) {
                        // Report right click to server
                        if (nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
@@ -3841,7 +3839,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
                                soundmaker->m_player_rightpunch_sound =
                                                SimpleSoundSpec();
 
-                               if (playeritem_def.node_placement_prediction == "" ||
+                               if (playeritem_def.node_placement_prediction.empty() ||
                                                nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
                                        client->interact(3, pointed); // Report to server
                                } else {
@@ -3861,7 +3859,7 @@ void Game::handlePointingAtObject(const PointedThing &pointed, const ItemStack &
                utf8_to_wide(runData.selected_object->infoText()));
 
        if (show_debug) {
-               if (infotext != L"") {
+               if (!infotext.empty()) {
                        infotext += L"\n";
                }
                infotext += unescape_enriched(utf8_to_wide(
@@ -3972,7 +3970,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
 
        if (sound_dig.exists() && params.diggable) {
                if (sound_dig.name == "__group") {
-                       if (params.main_group != "") {
+                       if (!params.main_group.empty()) {
                                soundmaker->m_player_leftpunch_sound.gain = 0.5;
                                soundmaker->m_player_leftpunch_sound.name =
                                                std::string("default_dig_") +
@@ -3995,6 +3993,9 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos,
 
                runData.dig_time = 0;
                runData.digging = false;
+               // we successfully dug, now block it from repeating if we want to be safe
+               if (g_settings->getBool("safe_dig_and_place"))
+                       runData.digging_blocked = true;
 
                runData.nodig_delay_timer =
                                runData.dig_time_complete / (float)crack_animation_length;
@@ -4217,7 +4218,7 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
                        || runData.update_draw_list_last_cam_dir.getDistanceFrom(camera_direction) > 0.2
                        || m_camera_offset_changed) {
                runData.update_draw_list_timer = 0;
-               client->getEnv().getClientMap().updateDrawList(driver);
+               client->getEnv().getClientMap().updateDrawList();
                runData.update_draw_list_last_cam_dir = camera_direction;
        }
 
@@ -4648,7 +4649,7 @@ void Game::showPauseMenu()
        static const std::string mode = strgettext("- Mode: ");
        if (!simple_singleplayer_mode) {
                Address serverAddress = client->getServerAddress();
-               if (address != "") {
+               if (!address.empty()) {
                        os << mode << strgettext("Remote server") << "\n"
                                        << strgettext("- Address: ") << address;
                } else {
@@ -4658,7 +4659,7 @@ void Game::showPauseMenu()
        } else {
                os << mode << strgettext("Singleplayer") << "\n";
        }
-       if (simple_singleplayer_mode || address == "") {
+       if (simple_singleplayer_mode || address.empty()) {
                static const std::string on = strgettext("On");
                static const std::string off = strgettext("Off");
                const std::string &damage = g_settings->getBool("enable_damage") ? on : off;
@@ -4672,7 +4673,7 @@ void Game::showPauseMenu()
                                        << strgettext("- Public: ") << announced << "\n";
                        std::string server_name = g_settings->get("server_name");
                        str_formspec_escape(server_name);
-                       if (announced == on && server_name != "")
+                       if (announced == on && !server_name.empty())
                                os << strgettext("- Server Name: ") << server_name;
 
                }