]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/game.cpp
Cleanup various headers to reduce compilation times (#6255)
[dragonfireclient.git] / src / game.cpp
index 4c903cc700e8ddce326a36108fa4f93c935191f0..cdbd9230106ccfaf2bb8afaa200a469ad9015cda 100644 (file)
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "game.h"
 
 #include <iomanip>
+#include <cmath>
 #include "client/renderingengine.h"
 #include "camera.h"
 #include "client.h"
@@ -50,6 +51,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "particles.h"
 #include "profiler.h"
 #include "quicktune_shortcutter.h"
+#include "raycast.h"
 #include "server.h"
 #include "settings.h"
 #include "sky.h"
@@ -121,8 +123,7 @@ struct TextDestPlayerInventory : public TextDest
 
 struct LocalFormspecHandler : public TextDest
 {
-       LocalFormspecHandler(const std::string &formname):
-               m_client(NULL)
+       LocalFormspecHandler(const std::string &formname)
        {
                m_formname = formname;
        }
@@ -174,10 +175,11 @@ struct LocalFormspecHandler : public TextDest
                }
 
                // Don't disable this part when modding is disabled, it's used in builtin
-               m_client->getScript()->on_formspec_input(m_formname, fields);
+               if (m_client && m_client->getScript())
+                       m_client->getScript()->on_formspec_input(m_formname, fields);
        }
 
-       Client *m_client;
+       Client *m_client = nullptr;
 };
 
 /* Form update callback */
@@ -975,8 +977,7 @@ static void updateChat(Client &client, f32 dtime, bool show_debug,
        }
 
        // Get new messages from client
-       std::wstring message;
-
+       std::wstring message = L"";
        while (client.getChatMessage(message)) {
                chat_backend.addUnparsedMessage(message);
        }
@@ -995,7 +996,7 @@ static void updateChat(Client &client, f32 dtime, bool show_debug,
        s32 chat_y = 5;
 
        if (show_debug)
-               chat_y += 2 * line_height;
+               chat_y += 3 * line_height;
 
        // first pass to calculate height of text to be set
        const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
@@ -1106,6 +1107,11 @@ void KeyCache::populate()
 
        key[KeyType::DEBUG_STACKS]   = getKeySetting("keymap_print_debug_stacks");
 
+       for (int i = 0; i < 23; i++) {
+               std::string slot_key_name = "keymap_slot" + std::to_string(i + 1);
+               key[KeyType::SLOT_1 + i] = getKeySetting(slot_key_name.c_str());
+       }
+
        if (handler) {
                // First clear all keys, then re-add the ones we listen for
                handler->dontListenForKeys();
@@ -1114,9 +1120,6 @@ void KeyCache::populate()
                }
                handler->listenForKey(EscapeKey);
                handler->listenForKey(CancelKey);
-               for (size_t i = 0; i < 10; i++) {
-                       handler->listenForKey(NumberKey[i]);
-               }
        }
 }
 
@@ -1428,6 +1431,7 @@ class Game {
         */
        gui::IGUIStaticText *guitext;          // First line of debug text
        gui::IGUIStaticText *guitext2;         // Second line of debug text
+       gui::IGUIStaticText *guitext3;         // Third line of debug text
        gui::IGUIStaticText *guitext_info;     // At the middle of the screen
        gui::IGUIStaticText *guitext_status;
        gui::IGUIStaticText *guitext_chat;         // Chat text
@@ -1914,7 +1918,7 @@ bool Game::createClient(const std::string &playername,
 
        /* Camera
         */
-       camera = new Camera(smgr, *draw_control, client);
+       camera = new Camera(*draw_control, client);
        if (!camera || !camera->successfullyCreated(*error_message))
                return false;
        client->setCamera(camera);
@@ -1971,7 +1975,7 @@ bool Game::createClient(const std::string &playername,
        player->hurt_tilt_timer = 0;
        player->hurt_tilt_strength = 0;
 
-       hud = new Hud(driver, smgr, guienv, client, player, local_inventory);
+       hud = new Hud(guienv, client, player, local_inventory);
 
        if (!hud) {
                *error_message = "Memory error: could not create HUD";
@@ -2000,6 +2004,12 @@ bool Game::initGui()
                        core::rect<s32>(0, 0, 0, 0),
                        false, false, guiroot);
 
+       // Third line of debug text
+       guitext3 = addStaticText(guienv,
+                       L"",
+                       core::rect<s32>(0, 0, 0, 0),
+                       false, false, guiroot);
+
        // At the middle of the screen
        // Object infos are shown in this
        guitext_info = addStaticText(guienv,
@@ -2121,6 +2131,7 @@ bool Game::connectToServer(const std::string &playername,
 
                fps_control.last_time = RenderingEngine::get_timer_time();
 
+               client->loadMods();
                client->initMods();
 
                while (RenderingEngine::run()) {
@@ -2630,16 +2641,10 @@ void Game::processItemSelection(u16 *new_playeritem)
                *new_playeritem = *new_playeritem > 0 ? *new_playeritem - 1 : max_item;
        // else dir == 0
 
-       /* Item selection using keyboard
+       /* Item selection using hotbar slot keys
         */
-       for (u16 i = 0; i < 10; i++) {
-               static const KeyPress *item_keys[10] = {
-                       NumberKey + 1, NumberKey + 2, NumberKey + 3, NumberKey + 4,
-                       NumberKey + 5, NumberKey + 6, NumberKey + 7, NumberKey + 8,
-                       NumberKey + 9, NumberKey + 0,
-               };
-
-               if (input->wasKeyDown(*item_keys[i])) {
+       for (u16 i = 0; i < 23; i++) {
+               if (wasKeyDown((GameKeyType) (KeyType::SLOT_1 + i))) {
                        if (i < PLAYER_INVENTORY_SIZE && i < player->hud_hotbar_itemcount) {
                                *new_playeritem = i;
                                infostream << "Selected item: " << new_playeritem << std::endl;
@@ -2975,8 +2980,8 @@ void Game::decreaseViewRange()
 void Game::toggleFullViewRange()
 {
        static const wchar_t *msg[] = {
-               L"Disabled full viewing range",
-               L"Enabled full viewing range"
+               L"Normal view range",
+               L"Infinite view range"
        };
 
        draw_control->range_all = !draw_control->range_all;
@@ -3440,8 +3445,7 @@ void Game::updateCamera(u32 busy_time, f32 dtime)
        float tool_reload_ratio = runData.time_from_last_punch / full_punch_interval;
 
        tool_reload_ratio = MYMIN(tool_reload_ratio, 1.0);
-       camera->update(player, dtime, busy_time / 1000.0f, tool_reload_ratio,
-                     client->getEnv());
+       camera->update(player, dtime, busy_time / 1000.0f, tool_reload_ratio);
        camera->step(dtime);
 
        v3f camera_position = camera->getPosition();
@@ -3666,28 +3670,22 @@ PointedThing Game::updatePointedThing(
        static thread_local const bool show_entity_selectionbox = g_settings->getBool(
                "show_entity_selectionbox");
 
-       ClientMap &map = client->getEnv().getClientMap();
-       INodeDefManager *nodedef=client->getNodeDefManager();
+       ClientEnvironment &env = client->getEnv();
+       ClientMap &map = env.getClientMap();
+       INodeDefManager *nodedef = map.getNodeDefManager();
 
        runData.selected_object = NULL;
 
-       PointedThing result=client->getEnv().getPointedThing(
-               shootline, liquids_pointable, look_for_object);
+       RaycastState s(shootline, look_for_object, liquids_pointable);
+       PointedThing result;
+       env.continueRaycast(&s, &result);
        if (result.type == POINTEDTHING_OBJECT) {
                runData.selected_object = client->getEnv().getActiveObject(result.object_id);
-               if (show_entity_selectionbox && runData.selected_object->doShowSelectionBox()) {
-                       aabb3f *selection_box = runData.selected_object->getSelectionBox();
-
-                       // Box should exist because object was
-                       // returned in the first place
-
-                       assert(selection_box);
-
+               aabb3f selection_box;
+               if (show_entity_selectionbox && runData.selected_object->doShowSelectionBox() &&
+                               runData.selected_object->getSelectionBox(&selection_box)) {
                        v3f pos = runData.selected_object->getPosition();
-                       selectionboxes->push_back(aabb3f(
-                               selection_box->MinEdge, selection_box->MaxEdge));
-                       selectionboxes->push_back(
-                               aabb3f(selection_box->MinEdge, selection_box->MaxEdge));
+                       selectionboxes->push_back(aabb3f(selection_box));
                        hud->setSelectionPos(pos, camera_offset);
                }
        } else if (result.type == POINTEDTHING_NODE) {
@@ -3800,6 +3798,11 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
 
                if (meta && meta->getString("formspec") != "" && !random_input
                                && !isKeyDown(KeyType::SNEAK)) {
+                       // Report right click to server
+                       if (nodedef_manager->get(map.getNodeNoEx(nodepos)).rightclickable) {
+                               client->interact(3, pointed);
+                       }
+
                        infostream << "Launching custom inventory view" << std::endl;
 
                        InventoryLocation inventoryloc;
@@ -4103,12 +4106,29 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
                Update clouds
        */
        if (clouds) {
-               v3f player_position = player->getPosition();
                if (sky->getCloudsVisible()) {
                        clouds->setVisible(true);
                        clouds->step(dtime);
-                       clouds->update(v2f(player_position.X, player_position.Z),
-                                      sky->getCloudColor());
+                       // camera->getPosition is not enough for 3rd person views
+                       v3f camera_node_position = camera->getCameraNode()->getPosition();
+                       v3s16 camera_offset      = camera->getOffset();
+                       camera_node_position.X   = camera_node_position.X + camera_offset.X * BS;
+                       camera_node_position.Y   = camera_node_position.Y + camera_offset.Y * BS;
+                       camera_node_position.Z   = camera_node_position.Z + camera_offset.Z * BS;
+                       clouds->update(camera_node_position,
+                                       sky->getCloudColor());
+                       if (clouds->isCameraInsideCloud() && m_cache_enable_fog &&
+                                       !flags.force_fog_off) {
+                               // if inside clouds, and fog enabled, use that as sky
+                               // color(s)
+                               video::SColor clouds_dark = clouds->getColor()
+                                               .getInterpolated(video::SColor(255, 0, 0, 0), 0.9);
+                               sky->overrideColors(clouds_dark, clouds->getColor());
+                               sky->setBodiesVisible(false);
+                               runData.fog_range = std::fmin(runData.fog_range * 0.5f, 32.0f * BS);
+                               // do not draw clouds after all
+                               clouds->setVisible(false);
+                       }
                } else {
                        clouds->setVisible(false);
                }
@@ -4220,7 +4240,6 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
        /*
                Drawing begins
        */
-
        const video::SColor &skycolor = sky->getSkyColor();
 
        TimeTaker tt_draw("mainloop: draw");
@@ -4296,21 +4315,20 @@ void Game::updateGui(const RunStats &stats, f32 dtime, const CameraOrientation &
        if (flags.show_debug) {
                static float drawtime_avg = 0;
                drawtime_avg = drawtime_avg * 0.95 + stats.drawtime * 0.05;
-
                u16 fps = 1.0 / stats.dtime_jitter.avg;
 
                std::ostringstream os(std::ios_base::binary);
                os << std::fixed
                   << PROJECT_NAME_C " " << g_version_hash
-                  << "; " << fps << " FPS"
-                  << ", (R: range_all=" << draw_control->range_all << ")"
+                  << ", FPS = " << fps
+                  << ", range_all = " << draw_control->range_all
                   << std::setprecision(0)
                   << ", drawtime = " << drawtime_avg << " ms"
                   << std::setprecision(1)
                   << ", dtime_jitter = "
                   << (stats.dtime_jitter.max_fraction * 100.0) << " %"
                   << std::setprecision(1)
-                  << ", v_range = " << draw_control->wanted_range
+                  << ", view_range = " << draw_control->wanted_range
                   << std::setprecision(3)
                   << ", RTT = " << client->getRTT() << " s";
                setStaticText(guitext, utf8_to_wide(os.str()).c_str());
@@ -4330,38 +4348,51 @@ void Game::updateGui(const RunStats &stats, f32 dtime, const CameraOrientation &
        if (flags.show_debug) {
                std::ostringstream os(std::ios_base::binary);
                os << std::setprecision(1) << std::fixed
-                  << "(" << (player_position.X / BS)
+                  << "pos = (" << (player_position.X / BS)
                   << ", " << (player_position.Y / BS)
                   << ", " << (player_position.Z / BS)
-                  << ") (yaw=" << (wrapDegrees_0_360(cam.camera_yaw)) << "°"
+                  << "), yaw = " << (wrapDegrees_0_360(cam.camera_yaw)) << "°"
                   << " " << yawToDirectionString(cam.camera_yaw)
-                  << ") (seed = " << ((u64)client->getMapSeed())
-                  << ")";
-
-               if (runData.pointed_old.type == POINTEDTHING_NODE) {
-                       ClientMap &map = client->getEnv().getClientMap();
-                       const INodeDefManager *nodedef = client->getNodeDefManager();
-                       MapNode n = map.getNodeNoEx(runData.pointed_old.node_undersurface);
-                       if (n.getContent() != CONTENT_IGNORE && nodedef->get(n).name != "unknown") {
-                               const ContentFeatures &features = nodedef->get(n);
-                               os << " (pointing_at = \"" << nodedef->get(n).name
-                                  << "\", param1 = " << (u64) n.getParam1()
-                                  << ", param2 = " << (u64) n.getParam2()
-                                  << ", tiledef[0] = \"" << features.tiledef[0].name.c_str()
-                                  << "\")";
-                       }
-               }
-
+                  << ", seed = " << ((u64)client->getMapSeed());
                setStaticText(guitext2, utf8_to_wide(os.str()).c_str());
                guitext2->setVisible(true);
+       } else {
+               guitext2->setVisible(false);
+       }
 
+       if (guitext2->isVisible()) {
                core::rect<s32> rect(
                                5,             5 + g_fontengine->getTextHeight(),
                                screensize.X,  5 + g_fontengine->getTextHeight() * 2
                );
                guitext2->setRelativePosition(rect);
+       }
+
+       if (flags.show_debug && runData.pointed_old.type == POINTEDTHING_NODE) {
+               ClientMap &map = client->getEnv().getClientMap();
+               const INodeDefManager *nodedef = client->getNodeDefManager();
+               MapNode n = map.getNodeNoEx(runData.pointed_old.node_undersurface);
+
+               if (n.getContent() != CONTENT_IGNORE && nodedef->get(n).name != "unknown") {
+                       std::ostringstream os(std::ios_base::binary);
+                       os << "pointing_at = (" << nodedef->get(n).name
+                          << ", param2 = " << (u64) n.getParam2()
+                          << ")";
+                       setStaticText(guitext3, utf8_to_wide(os.str()).c_str());
+                       guitext3->setVisible(true);
+               } else {
+                       guitext3->setVisible(false);
+               }
        } else {
-               guitext2->setVisible(false);
+               guitext3->setVisible(false);
+       }
+
+       if (guitext3->isVisible()) {
+               core::rect<s32> rect(
+                               5,             5 + g_fontengine->getTextHeight() * 2,
+                               screensize.X,  5 + g_fontengine->getTextHeight() * 3
+               );
+               guitext3->setRelativePosition(rect);
        }
 
        setStaticText(guitext_info, infotext.c_str());