]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/game.cpp
Put ChatEvent handler into own function
[dragonfireclient.git] / src / game.cpp
index 09b8aab42182adc7c0514a1050e4e82787c61487..1738517b57022d2d3705d2a77f8d77e154eea1dc 100644 (file)
@@ -40,7 +40,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "guiPasswordChange.h"
 #include "guiVolumeChange.h"
 #include "hud.h"
-#include "logoutputbuffer.h"
 #include "mainmenumanager.h"
 #include "mapblock.h"
 #include "nodedef.h"         // Needed for determining pointing to nodes
@@ -375,7 +374,7 @@ PointedThing getPointedThing(Client *client, v3f player_position,
 
                                for (std::vector<aabb3f>::const_iterator
                                                i = boxes.begin();
-                                               i != boxes.end(); i++) {
+                                               i != boxes.end(); ++i) {
                                        aabb3f box = *i;
                                        box.MinEdge += npf;
                                        box.MaxEdge += npf;
@@ -420,7 +419,7 @@ PointedThing getPointedThing(Client *client, v3f player_position,
                                                if (!g_settings->getBool("enable_node_highlighting")) {
                                                        for (std::vector<aabb3f>::const_iterator
                                                                        i2 = boxes.begin();
-                                                                       i2 != boxes.end(); i2++) {
+                                                                       i2 != boxes.end(); ++i2) {
                                                                aabb3f box = *i2;
                                                                box.MinEdge += npf + v3f(-d, -d, -d) - intToFloat(camera_offset, BS);
                                                                box.MaxEdge += npf + v3f(d, d, d) - intToFloat(camera_offset, BS);
@@ -490,7 +489,7 @@ class ProfilerGraph
                        color(color)
                {}
        };
-       std::vector<Piece> m_log;
+       std::deque<Piece> m_log;
 public:
        u32 m_log_max_size;
 
@@ -513,12 +512,12 @@ class ProfilerGraph
        {
                std::map<std::string, Meta> m_meta;
 
-               for (std::vector<Piece>::const_iterator k = m_log.begin();
-                               k != m_log.end(); k++) {
+               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++) {
+                                       i != piece.values.end(); ++i) {
                                const std::string &id = i->first;
                                const float &value = i->second;
                                std::map<std::string, Meta>::iterator j =
@@ -550,7 +549,7 @@ class ProfilerGraph
                u32 next_color_i = 0;
 
                for (std::map<std::string, Meta>::iterator i = m_meta.begin();
-                               i != m_meta.end(); i++) {
+                               i != m_meta.end(); ++i) {
                        Meta &meta = i->second;
                        video::SColor color(255, 200, 200, 200);
 
@@ -566,7 +565,7 @@ class ProfilerGraph
                s32 meta_i = 0;
 
                for (std::map<std::string, Meta>::const_iterator i = m_meta.begin();
-                               i != m_meta.end(); i++) {
+                               i != m_meta.end(); ++i) {
                        const std::string &id = i->first;
                        const Meta &meta = i->second;
                        s32 x = x_left;
@@ -601,8 +600,8 @@ class ProfilerGraph
                        float lastscaledvalue = 0.0;
                        bool lastscaledvalue_exists = false;
 
-                       for (std::vector<Piece>::const_iterator j = m_log.begin();
-                                       j != m_log.end(); j++) {
+                       for (std::deque<Piece>::const_iterator j = m_log.begin();
+                                       j != m_log.end(); ++j) {
                                const Piece &piece = *j;
                                float value = 0;
                                bool value_exists = false;
@@ -1049,7 +1048,7 @@ static void show_chat_menu(GUIFormSpecMenu **cur_formspec,
                FORMSPEC_VERSION_STRING
                SIZE_TAG
                "field[3,2.35;6,0.5;f_text;;" + text + "]"
-               "button_exit[4,3;3,0.5;btn_send;" + wide_to_utf8(wstrgettext("Proceed")) + "]"
+               "button_exit[4,3;3,0.5;btn_send;" + strgettext("Proceed") + "]"
                ;
 
        /* Create menu */
@@ -1089,32 +1088,32 @@ static void show_pause_menu(GUIFormSpecMenu **cur_formspec,
                bool singleplayermode)
 {
 #ifdef __ANDROID__
-       std::string control_text = wide_to_utf8(wstrgettext("Default Controls:\n"
-                                  "No menu visible:\n"
-                                  "- single tap: button activate\n"
-                                  "- double tap: place/use\n"
-                                  "- slide finger: look around\n"
-                                  "Menu/Inventory visible:\n"
-                                  "- double tap (outside):\n"
-                                  " -->close\n"
-                                  "- touch stack, touch slot:\n"
-                                  " --> move stack\n"
-                                  "- touch&drag, tap 2nd finger\n"
-                                  " --> place single item to slot\n"
-                                                            ));
+       std::string control_text = strgettext("Default Controls:\n"
+               "No menu visible:\n"
+               "- single tap: button activate\n"
+               "- double tap: place/use\n"
+               "- slide finger: look around\n"
+               "Menu/Inventory visible:\n"
+               "- double tap (outside):\n"
+               " -->close\n"
+               "- touch stack, touch slot:\n"
+               " --> move stack\n"
+               "- touch&drag, tap 2nd finger\n"
+               " --> place single item to slot\n"
+               );
 #else
-       std::string control_text = wide_to_utf8(wstrgettext("Default Controls:\n"
-                                  "- WASD: move\n"
-                                  "- Space: jump/climb\n"
-                                  "- Shift: sneak/go down\n"
-                                  "- Q: drop item\n"
-                                  "- I: inventory\n"
-                                  "- Mouse: turn/look\n"
-                                  "- Mouse left: dig/punch\n"
-                                  "- Mouse right: place/use\n"
-                                  "- Mouse wheel: select item\n"
-                                  "- T: chat\n"
-                                                            ));
+       std::string control_text = strgettext("Default Controls:\n"
+               "- WASD: move\n"
+               "- Space: jump/climb\n"
+               "- Shift: sneak/go down\n"
+               "- Q: drop item\n"
+               "- I: inventory\n"
+               "- Mouse: turn/look\n"
+               "- Mouse left: dig/punch\n"
+               "- Mouse right: place/use\n"
+               "- Mouse wheel: select item\n"
+               "- T: chat\n"
+               );
 #endif
 
        float ypos = singleplayermode ? 0.5 : 0.1;
@@ -1122,23 +1121,23 @@ static void show_pause_menu(GUIFormSpecMenu **cur_formspec,
 
        os << FORMSPEC_VERSION_STRING  << SIZE_TAG
           << "button_exit[4," << (ypos++) << ";3,0.5;btn_continue;"
-          << wide_to_utf8(wstrgettext("Continue"))     << "]";
+          << strgettext("Continue") << "]";
 
        if (!singleplayermode) {
                os << "button_exit[4," << (ypos++) << ";3,0.5;btn_change_password;"
-                  << wide_to_utf8(wstrgettext("Change Password")) << "]";
+                  << strgettext("Change Password") << "]";
        }
 
 #ifndef __ANDROID__
        os              << "button_exit[4," << (ypos++) << ";3,0.5;btn_sound;"
-                       << wide_to_utf8(wstrgettext("Sound Volume")) << "]";
+                       << strgettext("Sound Volume") << "]";
        os              << "button_exit[4," << (ypos++) << ";3,0.5;btn_key_config;"
-                       << wide_to_utf8(wstrgettext("Change Keys"))  << "]";
+                       << strgettext("Change Keys")  << "]";
 #endif
        os              << "button_exit[4," << (ypos++) << ";3,0.5;btn_exit_menu;"
-                       << wide_to_utf8(wstrgettext("Exit to Menu")) << "]";
+                       << strgettext("Exit to Menu") << "]";
        os              << "button_exit[4," << (ypos++) << ";3,0.5;btn_exit_os;"
-                       << wide_to_utf8(wstrgettext("Exit to OS"))   << "]"
+                       << strgettext("Exit to OS")   << "]"
                        << "textarea[7.5,0.25;3.9,6.25;;" << control_text << ";]"
                        << "textarea[0.4,0.25;3.5,6;;" << PROJECT_NAME_C "\n"
                        << g_build_info << "\n"
@@ -1163,7 +1162,7 @@ static void updateChat(Client &client, f32 dtime, bool show_debug,
                ChatBackend &chat_backend, gui::IGUIStaticText *guitext_chat)
 {
        // Add chat log output for errors to be shown in chat
-       static LogOutputBuffer chat_log_error_buf(LMT_ERROR);
+       static LogOutputBuffer chat_log_error_buf(g_logger, LL_ERROR);
 
        // Get new messages from error log buffer
        while (!chat_log_error_buf.empty()) {
@@ -1235,6 +1234,7 @@ struct KeyCache {
                KEYMAP_ID_JUMP,
                KEYMAP_ID_SPECIAL1,
                KEYMAP_ID_SNEAK,
+               KEYMAP_ID_AUTORUN,
 
                // Other
                KEYMAP_ID_DROP,
@@ -1287,6 +1287,8 @@ void KeyCache::populate()
        key[KEYMAP_ID_SPECIAL1]     = getKeySetting("keymap_special1");
        key[KEYMAP_ID_SNEAK]        = getKeySetting("keymap_sneak");
 
+       key[KEYMAP_ID_AUTORUN]      = getKeySetting("keymap_autorun");
+
        key[KEYMAP_ID_DROP]         = getKeySetting("keymap_drop");
        key[KEYMAP_ID_INVENTORY]    = getKeySetting("keymap_inventory");
        key[KEYMAP_ID_CHAT]         = getKeySetting("keymap_chat");
@@ -1497,7 +1499,7 @@ class Game {
 
        void toggleChat(float *statustext_time, bool *flag);
        void toggleHud(float *statustext_time, bool *flag);
-       void toggleMinimap(float *statustext_time, bool *flag1, bool *flag2,
+       void toggleMinimap(float *statustext_time, bool *flag, bool show_hud,
                        bool shift_pressed);
        void toggleFog(float *statustext_time, bool *flag);
        void toggleDebug(float *statustext_time, bool *show_debug,
@@ -1545,6 +1547,9 @@ class Game {
        void showOverlayMessage(const wchar_t *msg, float dtime, int percent,
                        bool draw_clouds = true);
 
+       static void settingChangedCallback(const std::string &setting_name, void *data);
+       void readSettings();
+
 private:
        InputHandler *input;
 
@@ -1616,10 +1621,7 @@ class Game {
 
        IntervalLimiter profiler_interval;
 
-       /* TODO: Add a callback function so these can be updated when a setting
-        *       changes.  At this point in time it doesn't matter (e.g. /set
-        *       is documented to change server settings only)
-        *
+       /*
         * TODO: Local caching of settings is not optimal and should at some stage
         *       be updated to use a global settings object for getting thse values
         *       (as opposed to the this local caching). This can be addressed in
@@ -1662,15 +1664,22 @@ Game::Game() :
        hud(NULL),
        mapper(NULL)
 {
-       m_cache_doubletap_jump            = g_settings->getBool("doubletap_jump");
-       m_cache_enable_node_highlighting  = g_settings->getBool("enable_node_highlighting");
-       m_cache_enable_clouds             = g_settings->getBool("enable_clouds");
-       m_cache_enable_particles          = g_settings->getBool("enable_particles");
-       m_cache_enable_fog                = g_settings->getBool("enable_fog");
-       m_cache_mouse_sensitivity         = g_settings->getFloat("mouse_sensitivity");
-       m_repeat_right_click_time         = g_settings->getFloat("repeat_rightclick_time");
-
-       m_cache_mouse_sensitivity = rangelim(m_cache_mouse_sensitivity, 0.001, 100.0);
+       g_settings->registerChangedCallback("doubletap_jump",
+               &settingChangedCallback, this);
+       g_settings->registerChangedCallback("enable_node_highlighting",
+               &settingChangedCallback, this);
+       g_settings->registerChangedCallback("enable_clouds",
+               &settingChangedCallback, this);
+       g_settings->registerChangedCallback("enable_particles",
+               &settingChangedCallback, this);
+       g_settings->registerChangedCallback("enable_fog",
+               &settingChangedCallback, this);
+       g_settings->registerChangedCallback("mouse_sensitivity",
+               &settingChangedCallback, this);
+       g_settings->registerChangedCallback("repeat_rightclick_time",
+               &settingChangedCallback, this);
+
+       readSettings();
 
 #ifdef __ANDROID__
        m_cache_hold_aux1 = false;      // This is initialised properly later
@@ -1705,6 +1714,21 @@ Game::~Game()
        delete draw_control;
 
        extendedResourceCleanup();
+
+       g_settings->deregisterChangedCallback("doubletap_jump",
+               &settingChangedCallback, this);
+       g_settings->deregisterChangedCallback("enable_node_highlighting",
+               &settingChangedCallback, this);
+       g_settings->deregisterChangedCallback("enable_clouds",
+               &settingChangedCallback, this);
+       g_settings->deregisterChangedCallback("enable_particles",
+               &settingChangedCallback, this);
+       g_settings->deregisterChangedCallback("enable_fog",
+               &settingChangedCallback, this);
+       g_settings->deregisterChangedCallback("mouse_sensitivity",
+               &settingChangedCallback, this);
+       g_settings->deregisterChangedCallback("repeat_rightclick_time",
+               &settingChangedCallback, this);
 }
 
 bool Game::startup(bool *kill,
@@ -1835,6 +1859,9 @@ void Game::run()
                updateFrame(highlight_boxes, &graph, &stats, &runData, dtime,
                                flags, cam_view);
                updateProfilerGraphs(&graph);
+
+               // Update if minimap has been disabled by the server
+               flags.show_minimap &= !client->isMinimapDisabledByServer();
        }
 }
 
@@ -2591,6 +2618,10 @@ void Game::processKeyboardInput(VolatileRunFlags *flags,
 
        if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_DROP])) {
                dropSelectedItem();
+       // Add WoW-style autorun by toggling continuous forward.
+       } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_AUTORUN])) {
+               bool autorun_setting = g_settings->getBool("continuous_forward");
+               g_settings->setBool("continuous_forward", !autorun_setting);
        } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_INVENTORY])) {
                openInventory();
        } else if (input->wasKeyDown(EscapeKey) || input->wasKeyDown(CancelKey)) {
@@ -2620,7 +2651,7 @@ void Game::processKeyboardInput(VolatileRunFlags *flags,
        } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_HUD])) {
                toggleHud(statustext_time, &flags->show_hud);
        } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_MINIMAP])) {
-               toggleMinimap(statustext_time, &flags->show_minimap, &flags->show_hud,
+               toggleMinimap(statustext_time, &flags->show_minimap, flags->show_hud,
                        input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_SNEAK]));
        } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_CHAT])) {
                toggleChat(statustext_time, &flags->show_chat);
@@ -2650,7 +2681,7 @@ void Game::processKeyboardInput(VolatileRunFlags *flags,
                // Print debug stacks
                dstream << "-----------------------------------------"
                        << std::endl;
-               dstream << DTIME << "Printing debug stacks:" << std::endl;
+               dstream << "Printing debug stacks:" << std::endl;
                dstream << "-----------------------------------------"
                        << std::endl;
                debug_stacks_print();
@@ -2842,43 +2873,54 @@ void Game::toggleHud(float *statustext_time, bool *flag)
                client->setHighlighted(client->getHighlighted(), *flag);
 }
 
-void Game::toggleMinimap(float *statustext_time, bool *flag, bool *show_hud, bool shift_pressed)
+void Game::toggleMinimap(float *statustext_time, bool *flag,
+       bool show_hud, bool shift_pressed)
 {
-       if (*show_hud && g_settings->getBool("enable_minimap")) {
-               if (shift_pressed) {
-                       mapper->toggleMinimapShape();
-                       return;
-               }
-               MinimapMode mode = mapper->getMinimapMode();
-               mode = (MinimapMode)((int)(mode) + 1);
-               *flag = true;
-               switch (mode) {
-                       case MINIMAP_MODE_SURFACEx1:
-                               statustext = L"Minimap in surface mode, Zoom x1";
-                               break;
-                       case MINIMAP_MODE_SURFACEx2:
-                               statustext = L"Minimap in surface mode, Zoom x2";
-                               break;
-                       case MINIMAP_MODE_SURFACEx4:
-                               statustext = L"Minimap in surface mode, Zoom x4";
-                               break;
-                       case MINIMAP_MODE_RADARx1:
-                               statustext = L"Minimap in radar mode, Zoom x1";
-                               break;
-                       case MINIMAP_MODE_RADARx2:
-                               statustext = L"Minimap in radar mode, Zoom x2";
-                               break;
-                       case MINIMAP_MODE_RADARx4:
-                               statustext = L"Minimap in radar mode, Zoom x4";
-                               break;
-                       default:
-                               mode = MINIMAP_MODE_OFF;
-                               *flag = false;
-                               statustext = L"Minimap hidden";
-               }
-               *statustext_time = 0;
-               mapper->setMinimapMode(mode);
+       if (!show_hud || !g_settings->getBool("enable_minimap"))
+               return;
+
+       if (shift_pressed) {
+               mapper->toggleMinimapShape();
+               return;
        }
+
+       u32 hud_flags = client->getEnv().getLocalPlayer()->hud_flags;
+
+       MinimapMode mode = MINIMAP_MODE_OFF;
+       if (hud_flags & HUD_FLAG_MINIMAP_VISIBLE) {
+               mode = mapper->getMinimapMode();
+               mode = (MinimapMode)((int)mode + 1);
+       }
+
+       *flag = true;
+       switch (mode) {
+               case MINIMAP_MODE_SURFACEx1:
+                       statustext = L"Minimap in surface mode, Zoom x1";
+                       break;
+               case MINIMAP_MODE_SURFACEx2:
+                       statustext = L"Minimap in surface mode, Zoom x2";
+                       break;
+               case MINIMAP_MODE_SURFACEx4:
+                       statustext = L"Minimap in surface mode, Zoom x4";
+                       break;
+               case MINIMAP_MODE_RADARx1:
+                       statustext = L"Minimap in radar mode, Zoom x1";
+                       break;
+               case MINIMAP_MODE_RADARx2:
+                       statustext = L"Minimap in radar mode, Zoom x2";
+                       break;
+               case MINIMAP_MODE_RADARx4:
+                       statustext = L"Minimap in radar mode, Zoom x4";
+                       break;
+               default:
+                       mode = MINIMAP_MODE_OFF;
+                       *flag = false;
+                       statustext = (hud_flags & HUD_FLAG_MINIMAP_VISIBLE) ?
+                               L"Minimap hidden" : L"Minimap disabled by server";
+       }
+
+       *statustext_time = 0;
+       mapper->setMinimapMode(mode);
 }
 
 void Game::toggleFog(float *statustext_time, bool *flag)
@@ -3638,11 +3680,15 @@ void Game::handlePointingAtNode(GameRunData *runData,
                        } else {
                                soundmaker->m_player_rightpunch_sound =
                                                SimpleSoundSpec();
-                       }
 
-                       if (playeritem_def.node_placement_prediction == "" ||
-                                       nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable)
-                               client->interact(3, pointed); // Report to server
+                               if (playeritem_def.node_placement_prediction == "" ||
+                                               nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
+                                       client->interact(3, pointed); // Report to server
+                               } else {
+                                       soundmaker->m_player_rightpunch_sound =
+                                               playeritem_def.sound_place_failed;
+                               }
+                       }
                }
        }
 }
@@ -4287,6 +4333,23 @@ void Game::showOverlayMessage(const wchar_t *msg, float dtime,
        delete[] msg;
 }
 
+void Game::settingChangedCallback(const std::string &setting_name, void *data)
+{
+       ((Game *)data)->readSettings();
+}
+
+void Game::readSettings()
+{
+       m_cache_doubletap_jump            = g_settings->getBool("doubletap_jump");
+       m_cache_enable_node_highlighting  = g_settings->getBool("enable_node_highlighting");
+       m_cache_enable_clouds             = g_settings->getBool("enable_clouds");
+       m_cache_enable_particles          = g_settings->getBool("enable_particles");
+       m_cache_enable_fog                = g_settings->getBool("enable_fog");
+       m_cache_mouse_sensitivity         = g_settings->getFloat("mouse_sensitivity");
+       m_repeat_right_click_time         = g_settings->getFloat("repeat_rightclick_time");
+
+       m_cache_mouse_sensitivity = rangelim(m_cache_mouse_sensitivity, 0.001, 100.0);
+}
 
 /****************************************************************************/
 /****************************************************************************
@@ -4370,4 +4433,3 @@ void the_game(bool *kill,
                errorstream << "ModError: " << error_message << std::endl;
        }
 }
-