]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/game.cpp
Added sprite extruder
[dragonfireclient.git] / src / game.cpp
index aa1cf4a70a657d192905c9c885862cbb66462e84..5e8db9b1d1d0b1b6e75ca6c2a2f9d83cad6cccd6 100644 (file)
@@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "materials.h"
 #include "config.h"
 #include "clouds.h"
-#include "keycode.h"
+#include "camera.h"
 #include "farmesh.h"
 #include "mapblock.h"
 
@@ -50,8 +50,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define FIELD_OF_VIEW_TEST 0
 
 
-MapDrawControl draw_control;
-
 // Chat data
 struct ChatLine
 {
@@ -115,18 +113,6 @@ struct TextDestChat : public TextDest
                // Discard empty line
                if(text == L"")
                        return;
-               
-               // Parse command (server command starts with "/#")
-               if(text[0] == L'/' && text[1] != L'#')
-               {
-                       std::wstring reply = L"Local: ";
-
-                       reply += L"Local commands not yet supported. "
-                                       L"Server prefix is \"/#\".";
-                       
-                       m_client->addChatMessage(reply);
-                       return;
-               }
 
                // Send to others
                m_client->sendChatMessage(text);
@@ -156,144 +142,6 @@ struct TextDestSignNode : public TextDest
        Client *m_client;
 };
 
-/*
-       Render distance feedback loop
-*/
-void updateViewingRange(f32 frametime_in, Client *client)
-{
-       if(draw_control.range_all == true)
-               return;
-       
-       static f32 added_frametime = 0;
-       static s16 added_frames = 0;
-
-       added_frametime += frametime_in;
-       added_frames += 1;
-
-       // Actually this counter kind of sucks because frametime is busytime
-       static f32 counter = 0;
-       counter -= frametime_in;
-       if(counter > 0)
-               return;
-       //counter = 0.1;
-       counter = 0.2;
-
-       /*dstream<<__FUNCTION_NAME
-                       <<": Collected "<<added_frames<<" frames, total of "
-                       <<added_frametime<<"s."<<std::endl;*/
-       
-       /*dstream<<"draw_control.blocks_drawn="
-                       <<draw_control.blocks_drawn
-                       <<", draw_control.blocks_would_have_drawn="
-                       <<draw_control.blocks_would_have_drawn
-                       <<std::endl;*/
-       
-       float range_min = g_settings.getS16("viewing_range_nodes_min");
-       float range_max = g_settings.getS16("viewing_range_nodes_max");
-       
-       // Limit minimum to keep the feedback loop stable
-       if(range_min < 5)
-               range_min = 5;
-       
-       draw_control.wanted_min_range = range_min;
-       //draw_control.wanted_max_blocks = (1.5*draw_control.blocks_drawn)+1;
-       draw_control.wanted_max_blocks = (1.5*draw_control.blocks_would_have_drawn)+1;
-       if(draw_control.wanted_max_blocks < 10)
-               draw_control.wanted_max_blocks = 10;
-       
-       float block_draw_ratio = 1.0;
-       if(draw_control.blocks_would_have_drawn != 0)
-       {
-               block_draw_ratio = (float)draw_control.blocks_drawn
-                       / (float)draw_control.blocks_would_have_drawn;
-       }
-
-       // Calculate the average frametime in the case that all wanted
-       // blocks had been drawn
-       f32 frametime = added_frametime / added_frames / block_draw_ratio;
-       
-       added_frametime = 0.0;
-       added_frames = 0;
-       
-       float wanted_fps = g_settings.getFloat("wanted_fps");
-       float wanted_frametime = 1.0 / wanted_fps;
-       
-       f32 wanted_frametime_change = wanted_frametime - frametime;
-       //dstream<<"wanted_frametime_change="<<wanted_frametime_change<<std::endl;
-       
-       // If needed frametime change is small, just return
-       if(fabs(wanted_frametime_change) < wanted_frametime*0.4)
-       {
-               //dstream<<"ignoring small wanted_frametime_change"<<std::endl;
-               return;
-       }
-
-       float range = draw_control.wanted_range;
-       float new_range = range;
-
-       static s16 range_old = 0;
-       static f32 frametime_old = 0;
-       
-       float d_range = range - range_old;
-       f32 d_frametime = frametime - frametime_old;
-       // A sane default of 30ms per 50 nodes of range
-       static f32 time_per_range = 30. / 50;
-       if(d_range != 0)
-       {
-               time_per_range = d_frametime / d_range;
-       }
-       
-       // The minimum allowed calculated frametime-range derivative:
-       // Practically this sets the maximum speed of changing the range.
-       // The lower this value, the higher the maximum changing speed.
-       // A low value here results in wobbly range (0.001)
-       // A high value here results in slow changing range (0.0025)
-       // SUGG: This could be dynamically adjusted so that when
-       //       the camera is turning, this is lower
-       //float min_time_per_range = 0.0015;
-       float min_time_per_range = 0.0010;
-       //float min_time_per_range = 0.05 / range;
-       if(time_per_range < min_time_per_range)
-       {
-               time_per_range = min_time_per_range;
-               //dstream<<"time_per_range="<<time_per_range<<" (min)"<<std::endl;
-       }
-       else
-       {
-               //dstream<<"time_per_range="<<time_per_range<<std::endl;
-       }
-
-       f32 wanted_range_change = wanted_frametime_change / time_per_range;
-       // Dampen the change a bit to kill oscillations
-       //wanted_range_change *= 0.9;
-       //wanted_range_change *= 0.75;
-       wanted_range_change *= 0.5;
-       //dstream<<"wanted_range_change="<<wanted_range_change<<std::endl;
-
-       // If needed range change is very small, just return
-       if(fabs(wanted_range_change) < 0.001)
-       {
-               //dstream<<"ignoring small wanted_range_change"<<std::endl;
-               return;
-       }
-
-       new_range += wanted_range_change;
-       
-       //float new_range_unclamped = new_range;
-       if(new_range < range_min)
-               new_range = range_min;
-       if(new_range > range_max)
-               new_range = range_max;
-       
-       /*dstream<<"new_range="<<new_range_unclamped
-                       <<", clamped to "<<new_range<<std::endl;*/
-
-       draw_control.wanted_range = new_range;
-
-       range_old = new_range;
-       frametime_old = frametime;
-}
-
 /*
        Hotbar draw routine
 */
@@ -332,17 +180,61 @@ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font,
                
                if(g_selected_item == i)
                {
-                       driver->draw2DRectangle(video::SColor(255,255,0,0),
-                                       core::rect<s32>(rect.UpperLeftCorner - v2s32(1,1)*padding,
-                                                       rect.LowerRightCorner + v2s32(1,1)*padding),
-                                       NULL);
-               }
-               else
-               {
-                       video::SColor bgcolor2(128,0,0,0);
-                       driver->draw2DRectangle(bgcolor2, rect, NULL);
+                       video::SColor c_outside(255,255,0,0);
+                       //video::SColor c_outside(255,0,0,0);
+                       //video::SColor c_inside(255,192,192,192);
+                       s32 x1 = rect.UpperLeftCorner.X;
+                       s32 y1 = rect.UpperLeftCorner.Y;
+                       s32 x2 = rect.LowerRightCorner.X;
+                       s32 y2 = rect.LowerRightCorner.Y;
+                       // Black base borders
+                       driver->draw2DRectangle(c_outside,
+                                       core::rect<s32>(
+                                               v2s32(x1 - padding, y1 - padding),
+                                               v2s32(x2 + padding, y1)
+                                       ), NULL);
+                       driver->draw2DRectangle(c_outside,
+                                       core::rect<s32>(
+                                               v2s32(x1 - padding, y2),
+                                               v2s32(x2 + padding, y2 + padding)
+                                       ), NULL);
+                       driver->draw2DRectangle(c_outside,
+                                       core::rect<s32>(
+                                               v2s32(x1 - padding, y1),
+                                               v2s32(x1, y2)
+                                       ), NULL);
+                       driver->draw2DRectangle(c_outside,
+                                       core::rect<s32>(
+                                               v2s32(x2, y1),
+                                               v2s32(x2 + padding, y2)
+                                       ), NULL);
+                       /*// Light inside borders
+                       driver->draw2DRectangle(c_inside,
+                                       core::rect<s32>(
+                                               v2s32(x1 - padding/2, y1 - padding/2),
+                                               v2s32(x2 + padding/2, y1)
+                                       ), NULL);
+                       driver->draw2DRectangle(c_inside,
+                                       core::rect<s32>(
+                                               v2s32(x1 - padding/2, y2),
+                                               v2s32(x2 + padding/2, y2 + padding/2)
+                                       ), NULL);
+                       driver->draw2DRectangle(c_inside,
+                                       core::rect<s32>(
+                                               v2s32(x1 - padding/2, y1),
+                                               v2s32(x1, y2)
+                                       ), NULL);
+                       driver->draw2DRectangle(c_inside,
+                                       core::rect<s32>(
+                                               v2s32(x2, y1),
+                                               v2s32(x2 + padding/2, y2)
+                                       ), NULL);
+                       */
                }
 
+               video::SColor bgcolor2(128,0,0,0);
+               driver->draw2DRectangle(bgcolor2, rect, NULL);
+
                if(item != NULL)
                {
                        drawInventoryItem(driver, font, item, rect, NULL);
@@ -417,7 +309,7 @@ void getPointedNode(Client *client, v3f player_position,
                try
                {
                        n = client->getNode(v3s16(x,y,z));
-                       if(content_pointable(n.d) == false)
+                       if(content_pointable(n.getContent()) == false)
                                continue;
                }
                catch(InvalidPositionException &e)
@@ -442,9 +334,9 @@ void getPointedNode(Client *client, v3f player_position,
                /*
                        Meta-objects
                */
-               if(n.d == CONTENT_TORCH)
+               if(n.getContent() == CONTENT_TORCH)
                {
-                       v3s16 dir = unpackDir(n.dir);
+                       v3s16 dir = unpackDir(n.param2);
                        v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
                        dir_f *= BS/2 - BS/6 - BS/20;
                        v3f cpf = npf + dir_f;
@@ -489,9 +381,9 @@ void getPointedNode(Client *client, v3f player_position,
                                }
                        }
                }
-               else if(n.d == CONTENT_SIGN_WALL)
+               else if(n.getContent() == CONTENT_SIGN_WALL)
                {
-                       v3s16 dir = unpackDir(n.dir);
+                       v3s16 dir = unpackDir(n.param2);
                        v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
                        dir_f *= BS/2 - BS/6 - BS/20;
                        v3f cpf = npf + dir_f;
@@ -538,6 +430,93 @@ void getPointedNode(Client *client, v3f player_position,
                                }
                        }
                }
+
+               else if(n.getContent() == CONTENT_LADDER)
+               {
+                       v3s16 dir = unpackDir(n.param2);
+                       v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
+                       dir_f *= BS/2 - BS/6 - BS/20;
+                       v3f cpf = npf + dir_f;
+                       f32 distance = (cpf - camera_position).getLength();
+
+                       v3f vertices[4] =
+                       {
+                               v3f(BS*0.42,-BS/2,-BS/2),
+                               v3f(BS*0.49, BS/2, BS/2),
+                       };
+
+                       for(s32 i=0; i<2; i++)
+                       {
+                               if(dir == v3s16(1,0,0))
+                                       vertices[i].rotateXZBy(0);
+                               if(dir == v3s16(-1,0,0))
+                                       vertices[i].rotateXZBy(180);
+                               if(dir == v3s16(0,0,1))
+                                       vertices[i].rotateXZBy(90);
+                               if(dir == v3s16(0,0,-1))
+                                       vertices[i].rotateXZBy(-90);
+                               if(dir == v3s16(0,-1,0))
+                                       vertices[i].rotateXYBy(-90);
+                               if(dir == v3s16(0,1,0))
+                                       vertices[i].rotateXYBy(90);
+
+                               vertices[i] += npf;
+                       }
+
+                       core::aabbox3d<f32> box;
+
+                       box = core::aabbox3d<f32>(vertices[0]);
+                       box.addInternalPoint(vertices[1]);
+
+                       if(distance < mindistance)
+                       {
+                               if(box.intersectsWithLine(shootline))
+                               {
+                                       nodefound = true;
+                                       nodepos = np;
+                                       neighbourpos = np;
+                                       mindistance = distance;
+                                       nodehilightbox = box;
+                               }
+                       }
+               }
+               else if(n.getContent() == CONTENT_RAIL)
+               {
+                       v3s16 dir = unpackDir(n.param0);
+                       v3f dir_f = v3f(dir.X, dir.Y, dir.Z);
+                       dir_f *= BS/2 - BS/6 - BS/20;
+                       v3f cpf = npf + dir_f;
+                       f32 distance = (cpf - camera_position).getLength();
+
+                       float d = (float)BS/16;
+                       v3f vertices[4] =
+                       {
+                               v3f(BS/2, -BS/2+d, -BS/2),
+                               v3f(-BS/2, -BS/2, BS/2),
+                       };
+
+                       for(s32 i=0; i<2; i++)
+                       {
+                               vertices[i] += npf;
+                       }
+
+                       core::aabbox3d<f32> box;
+
+                       box = core::aabbox3d<f32>(vertices[0]);
+                       box.addInternalPoint(vertices[1]);
+
+                       if(distance < mindistance)
+                       {
+                               if(box.intersectsWithLine(shootline))
+                               {
+                                       nodefound = true;
+                                       nodepos = np;
+                                       neighbourpos = np;
+                                       mindistance = distance;
+                                       nodehilightbox = box;
+                               }
+                       }
+               }
                /*
                        Regular blocks
                */
@@ -639,6 +618,34 @@ void update_skybox(video::IVideoDriver* driver,
        }
 }
 
+/*
+       Draws a screen with a single text on it.
+       Text will be removed when the screen is drawn the next time.
+*/
+/*gui::IGUIStaticText **/
+void draw_load_screen(const std::wstring &text,
+               video::IVideoDriver* driver, gui::IGUIFont* font)
+{
+       v2u32 screensize = driver->getScreenSize();
+       const wchar_t *loadingtext = text.c_str();
+       core::vector2d<u32> textsize_u = font->getDimension(loadingtext);
+       core::vector2d<s32> textsize(textsize_u.X,textsize_u.Y);
+       core::vector2d<s32> center(screensize.X/2, screensize.Y/2);
+       core::rect<s32> textrect(center - textsize/2, center + textsize/2);
+
+       gui::IGUIStaticText *guitext = guienv->addStaticText(
+                       loadingtext, textrect, false, false);
+       guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
+
+       driver->beginScene(true, true, video::SColor(255,0,0,0));
+       guienv->drawAll();
+       driver->endScene();
+       
+       guitext->remove();
+       
+       //return guitext;
+}
+
 void the_game(
        bool &kill,
        bool random_input,
@@ -650,18 +657,24 @@ void the_game(
        std::string password,
        std::string address,
        u16 port,
-       std::wstring &error_message
+       std::wstring &error_message,
+    std::string configpath
 )
 {
        video::IVideoDriver* driver = device->getVideoDriver();
        scene::ISceneManager* smgr = device->getSceneManager();
+       
+       // Calculate text height using the font
+       u32 text_height = font->getDimension(L"Random test string").Height;
 
        v2u32 screensize(0,0);
        v2u32 last_screensize(0,0);
        screensize = driver->getScreenSize();
 
        const s32 hotbar_itemcount = 8;
-       const s32 hotbar_imagesize = 36;
+       //const s32 hotbar_imagesize = 36;
+       //const s32 hotbar_imagesize = 64;
+       s32 hotbar_imagesize = 48;
        
        // The color of the sky
 
@@ -672,20 +685,10 @@ void the_game(
        /*
                Draw "Loading" screen
        */
-       const wchar_t *loadingtext = L"Loading and connecting...";
-       u32 text_height = font->getDimension(loadingtext).Height;
-       core::vector2d<s32> center(screensize.X/2, screensize.Y/2);
-       core::vector2d<s32> textsize(300, text_height);
-       core::rect<s32> textrect(center - textsize/2, center + textsize/2);
-
-       gui::IGUIStaticText *gui_loadingtext = guienv->addStaticText(
-                       loadingtext, textrect, false, false);
-       gui_loadingtext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
-
-       driver->beginScene(true, true, video::SColor(255,0,0,0));
-       guienv->drawAll();
-       driver->endScene();
+       /*gui::IGUIStaticText *gui_loadingtext = */
+       //draw_load_screen(L"Loading and connecting...", driver, font);
 
+       draw_load_screen(L"Loading...", driver, font);
        
        /*
                Create server.
@@ -693,8 +696,9 @@ void the_game(
        */
        SharedPtr<Server> server;
        if(address == ""){
+               draw_load_screen(L"Creating server...", driver, font);
                std::cout<<DTIME<<"Creating server"<<std::endl;
-               server = new Server(map_dir);
+               server = new Server(map_dir, configpath);
                server->start(port);
        }
        
@@ -702,9 +706,12 @@ void the_game(
                Create client
        */
 
+       draw_load_screen(L"Creating client...", driver, font);
        std::cout<<DTIME<<"Creating client"<<std::endl;
+       MapDrawControl draw_control;
        Client client(device, playername.c_str(), password, draw_control);
                        
+       draw_load_screen(L"Resolving address...", driver, font);
        Address connect_address(0,0,0,0, port);
        try{
                if(address == "")
@@ -718,7 +725,7 @@ void the_game(
                std::cout<<DTIME<<"Couldn't resolve address"<<std::endl;
                //return 0;
                error_message = L"Couldn't resolve address";
-               gui_loadingtext->remove();
+               //gui_loadingtext->remove();
                return;
        }
 
@@ -751,11 +758,17 @@ void the_game(
                        {
                                break;
                        }
+                       
+                       std::wostringstream ss;
+                       ss<<L"Connecting to server... (timeout in ";
+                       ss<<(int)(10.0 - time_counter + 1.0);
+                       ss<<L" seconds)";
+                       draw_load_screen(ss.str(), driver, font);
 
-                       // Update screen
+                       /*// Update screen
                        driver->beginScene(true, true, video::SColor(255,0,0,0));
                        guienv->drawAll();
-                       driver->endScene();
+                       driver->endScene();*/
 
                        // Update client and server
 
@@ -785,7 +798,7 @@ void the_game(
                        error_message = L"Connection timed out.";
                        std::cout<<DTIME<<"Timed out."<<std::endl;
                }
-               gui_loadingtext->remove();
+               //gui_loadingtext->remove();
                return;
        }
 
@@ -799,25 +812,10 @@ void the_game(
        /*
                Create the camera node
        */
-
-       scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(
-               0, // Camera parent
-               v3f(BS*100, BS*2, BS*100), // Look from
-               v3f(BS*100+1, BS*2, BS*100), // Look to
-               -1 // Camera ID
-       );
-
-       if(camera == NULL)
-       {
-               error_message = L"Failed to create the camera node";
+       Camera camera(smgr, draw_control);
+       if (!camera.successfullyCreated(error_message))
                return;
-       }
-
-       camera->setFOV(FOV_ANGLE);
 
-       // Just so big a value that everything rendered is visible
-       camera->setFarValue(100000*BS);
-       
        f32 camera_yaw = 0; // "right/left"
        f32 camera_pitch = 0; // "up/down"
 
@@ -847,7 +845,7 @@ void the_game(
                Move into game
        */
        
-       gui_loadingtext->remove();
+       //gui_loadingtext->remove();
 
        /*
                Add some gui stuff
@@ -942,6 +940,14 @@ void the_game(
        {
                //std::cerr<<"frame"<<std::endl;
 
+               if(client.accessDenied())
+               {
+                       error_message = L"Access denied. Reason: "
+                                       +client.accessDeniedReason();
+                       std::cout<<DTIME<<wide_to_narrow(error_message)<<std::endl;
+                       break;
+               }
+
                if(g_gamecallback->disconnect_requested)
                {
                        g_gamecallback->disconnect_requested = false;
@@ -967,6 +973,14 @@ void the_game(
                screensize = driver->getScreenSize();
                v2s32 displaycenter(screensize.X/2,screensize.Y/2);
                //bool screensize_changed = screensize != last_screensize;
+
+               // Resize hotbar
+               if(screensize.Y <= 800)
+                       hotbar_imagesize = 32;
+               else if(screensize.Y <= 1280)
+                       hotbar_imagesize = 48;
+               else
+                       hotbar_imagesize = 64;
                
                // Hilight boxes collected during the loop and displayed
                core::list< core::aabbox3d<f32> > hilightboxes;
@@ -1001,12 +1015,6 @@ void the_game(
                // Necessary for device->getTimer()->getTime()
                device->run();
 
-               /*
-                       Viewing range
-               */
-               
-               updateViewingRange(busytime, &client);
-               
                /*
                        FPS limiter
                */
@@ -1059,7 +1067,7 @@ void the_game(
                */
 
                static f32 dtime_avg1 = 0.0;
-               dtime_avg1 = dtime_avg1 * 0.98 + dtime * 0.02;
+               dtime_avg1 = dtime_avg1 * 0.96 + dtime * 0.04;
                f32 dtime_jitter1 = dtime - dtime_avg1;
 
                static f32 dtime_jitter1_max_sample = 0.0;
@@ -1178,7 +1186,7 @@ void the_game(
 
                        menu->drop();
                }
-               else if(input->wasKeyDown(KEY_ESCAPE))
+               else if(input->wasKeyDown(EscapeKey))
                {
                        dstream<<DTIME<<"the_game: "
                                        <<"Launching pause menu"<<std::endl;
@@ -1197,6 +1205,14 @@ void the_game(
                                        &g_menumgr, dest,
                                        L""))->drop();
                }
+               else if(input->wasKeyDown(getKeySetting("keymap_cmd")))
+               {
+                       TextDest *dest = new TextDestChat(&client);
+
+                       (new GUITextInputMenu(guienv, guiroot, -1,
+                                       &g_menumgr, dest,
+                                       L"/"))->drop();
+               }
                else if(input->wasKeyDown(getKeySetting("keymap_freemove")))
                {
                        if(g_settings.getBool("free_move"))
@@ -1236,6 +1252,25 @@ void the_game(
                                chat_lines.push_back(ChatLine(L"frametime_graph enabled"));
                        }
                }
+               else if(input->wasKeyDown(getKeySetting("keymap_screenshot")))
+               {
+                       irr::video::IImage* const image = driver->createScreenShot(); 
+                       if (image) { 
+                               irr::c8 filename[256]; 
+                               snprintf(filename, 256, "%s/screenshot_%u.png", 
+                                                g_settings.get("screenshot_path").c_str(),
+                                                device->getTimer()->getRealTime()); 
+                               if (driver->writeImageToFile(image, filename)) {
+                                       std::wstringstream sstr;
+                                       sstr<<"Saved screenshot to '"<<filename<<"'";
+                                       dstream<<"Saved screenshot to '"<<filename<<"'"<<std::endl;
+                                       chat_lines.push_back(ChatLine(sstr.str()));
+                               } else{
+                                       dstream<<"Failed to save screenshot '"<<filename<<"'"<<std::endl;
+                               }
+                               image->drop(); 
+                       }                        
+               }
 
                // Item selection with mouse wheel
                {
@@ -1262,10 +1297,8 @@ void the_game(
                // Item selection
                for(u16 i=0; i<10; i++)
                {
-                       s32 keycode = irr::KEY_KEY_1 + i;
-                       if(i == 9)
-                               keycode = irr::KEY_KEY_0;
-                       if(input->wasKeyDown((irr::EKEY_CODE)keycode))
+                       const KeyPress *kp = NumberKey + (i + 1) % 10;
+                       if(input->wasKeyDown(*kp))
                        {
                                if(i < PLAYER_INVENTORY_SIZE && i < hotbar_itemcount)
                                {
@@ -1373,9 +1406,6 @@ void the_game(
                        }
                }
                
-               // Get player position
-               v3f player_position = client.getPlayerPosition();
-
                //TimeTaker //timer2("//timer2");
 
                /*
@@ -1428,30 +1458,25 @@ void the_game(
                        first_loop_after_window_activation = true;
                }
 
-               camera_yaw = wrapDegrees(camera_yaw);
-               camera_pitch = wrapDegrees(camera_pitch);
-               
-               v3f camera_direction = v3f(0,0,1);
-               camera_direction.rotateYZBy(camera_pitch);
-               camera_direction.rotateXZBy(camera_yaw);
-               
-               // This is at the height of the eyes of the current figure
-               //v3f camera_position = player_position + v3f(0, BS+BS/2, 0);
-               // This is more like in minecraft
-               v3f camera_position = player_position + v3f(0, BS+BS*0.625, 0);
+               LocalPlayer* player = client.getLocalPlayer();
+               camera.update(player, busytime, screensize);
+               camera.step(dtime);
 
-               camera->setPosition(camera_position);
-               // *100.0 helps in large map coordinates
-               camera->setTarget(camera_position + camera_direction * 100.0);
+               v3f player_position = player->getPosition();
+               v3f camera_position = camera.getPosition();
+               v3f camera_direction = camera.getDirection();
+               f32 camera_fov = camera.getFovMax();
 
-               if(FIELD_OF_VIEW_TEST){
-                       client.updateCamera(v3f(0,0,0), v3f(0,0,1));
+               if(FIELD_OF_VIEW_TEST)
+               {
+                       client.updateCamera(v3f(0,0,0), v3f(0,0,1), camera_fov);
                }
-               else{
-                       //TimeTaker timer("client.updateCamera");
-                       client.updateCamera(camera_position, camera_direction);
+               else
+               {
+                       client.updateCamera(camera_position,
+                               camera_direction, camera_fov);
                }
-               
+
                //timer2.stop();
                //TimeTaker //timer3("//timer3");
 
@@ -1489,6 +1514,7 @@ void the_game(
                                std::cout<<DTIME<<"Left-clicked object"<<std::endl;
                                client.clickObject(0, selected_object->getBlock()->getPos(),
                                                selected_object->getId(), g_selected_item);
+                               camera.setDigging(true);
                        }
                        else if(input->getRightClicked())
                        {
@@ -1556,10 +1582,13 @@ void the_game(
                                std::cout<<DTIME<<"Left-clicked object"<<std::endl;
                                client.clickActiveObject(0,
                                                selected_active_object->getId(), g_selected_item);
+                               camera.setDigging(true);
                        }
                        else if(input->getRightClicked())
                        {
                                std::cout<<DTIME<<"Right-clicked object"<<std::endl;
+                               client.clickActiveObject(1,
+                                               selected_active_object->getId(), g_selected_item);
                        }
                }
                else // selected_object == NULL
@@ -1663,7 +1692,7 @@ void the_game(
                                        }
 
                                        // Get digging properties for material and tool
-                                       u8 material = n.d;
+                                       content_t material = n.getContent();
                                        DiggingProperties prop =
                                                        getDiggingProperties(material, toolname);
                                        
@@ -1727,9 +1756,12 @@ void the_game(
                                        }
 
                                        dig_time += dtime;
+
+                                       camera.setDigging(true);
                                }
                        }
                        
+                       
                        if(input->getRightClicked())
                        {
                                std::cout<<DTIME<<"Ground right-clicked"<<std::endl;
@@ -1793,8 +1825,6 @@ void the_game(
                        
                        nodepos_old = nodepos;
                }
-               else{
-               }
 
                } // selected_object == NULL
                
@@ -1806,6 +1836,7 @@ void the_game(
                        std::cout<<DTIME<<"Left button released (stopped digging)"
                                        <<std::endl;
                        client.groundAction(2, v3s16(0,0,0), v3s16(0,0,0), 0);
+                       camera.setDigging(false);
                }
                if(input->getRightReleased())
                {
@@ -1820,8 +1851,6 @@ void the_game(
                        Calculate stuff for drawing
                */
 
-               camera->setAspectRatio((f32)screensize.X / (f32)screensize.Y);
-               
                u32 daynight_ratio = client.getDayNightRatio();
                u8 l = decode_light((daynight_ratio * LIGHT_SUN) / 1000);
                video::SColor bgcolor = video::SColor(
@@ -1842,7 +1871,7 @@ void the_game(
                        update_skybox(driver, smgr, skybox, brightness);
 
                /*
-                       Update coulds
+                       Update clouds
                */
                if(clouds)
                {
@@ -1913,7 +1942,6 @@ void the_game(
                        );
                }
 
-
                /*
                        Update gui stuff (0ms)
                */
@@ -2055,9 +2083,17 @@ void the_game(
                if(client.getLocalInventoryUpdated()
                                || g_selected_item != old_selected_item)
                {
+                       client.selectPlayerItem(g_selected_item);
                        old_selected_item = g_selected_item;
                        //std::cout<<"Updating local inventory"<<std::endl;
                        client.getLocalInventory(local_inventory);
+
+                       // Update wielded tool
+                       InventoryList *mlist = local_inventory.getList("main");
+                       InventoryItem *item = NULL;
+                       if(mlist != NULL)
+                               item = mlist->getItem(g_selected_item);
+                       camera.wield(item);
                }
                
                /*
@@ -2122,6 +2158,13 @@ void the_game(
                        driver->draw3DBox(*i, video::SColor(255,0,0,0));
                }
 
+               /*
+                       Post effects
+               */
+               {
+                       client.renderPostFx();
+               }
+
                /*
                        Frametime log
                */
@@ -2182,7 +2225,7 @@ void the_game(
                                        core::rect<s32>(0,0,screensize.X,screensize.Y),
                                        NULL);
                }
-               
+
                /*
                        End scene
                */
@@ -2225,15 +2268,12 @@ void the_game(
                generator and other stuff quits
        */
        {
-               const wchar_t *shuttingdowntext = L"Shutting down stuff...";
-               gui::IGUIStaticText *gui_shuttingdowntext = guienv->addStaticText(
-                               shuttingdowntext, textrect, false, false);
-               gui_shuttingdowntext->setTextAlignment(gui::EGUIA_CENTER,
-                               gui::EGUIA_UPPERLEFT);
-               driver->beginScene(true, true, video::SColor(255,0,0,0));
+               /*gui::IGUIStaticText *gui_shuttingdowntext = */
+               draw_load_screen(L"Shutting down stuff...", driver, font);
+               /*driver->beginScene(true, true, video::SColor(255,0,0,0));
                guienv->drawAll();
                driver->endScene();
-               gui_shuttingdowntext->remove();
+               gui_shuttingdowntext->remove();*/
        }
 }