X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fgame.cpp;h=d7efbeae9fbaf616d19113ee48820f5463cd79bd;hb=64996422c00ddb70cfc8aee7da7b62485b8b0416;hp=bbd0a22ef06fb3ccb970e852234226a5c46a8dbd;hpb=e261cc9e8fa67c9020fa0a82bd1a7041ecd351a0;p=dragonfireclient.git diff --git a/src/game.cpp b/src/game.cpp index bbd0a22ef..d7efbeae9 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -17,19 +17,40 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "common_irrlicht.h" #include "game.h" +#include "common_irrlicht.h" +#include +#include +#include +#include +#include #include "client.h" #include "server.h" #include "guiPauseMenu.h" #include "guiPasswordChange.h" #include "guiInventoryMenu.h" #include "guiTextInputMenu.h" -#include "guiFurnaceMenu.h" +#include "guiDeathScreen.h" #include "materials.h" #include "config.h" #include "clouds.h" -#include "keycode.h" +#include "camera.h" +#include "farmesh.h" +#include "mapblock.h" +#include "settings.h" +#include "profiler.h" +#include "mainmenumanager.h" +#include "gettext.h" +#include "log.h" +#include "filesys.h" +// Needed for some special cases for CONTENT_TORCH and CONTENT_SIGN_WALL +// TODO: A generic way for handling such should be created +#include "content_mapnode.h" +// Needed for sign text input +// TODO: A generic way for handling such should be created +#include "content_nodemeta.h" +// Needed for determining pointing to nodes +#include "mapnode_contentfeatures.h" /* Setting this to 1 enables a special camera mode that forces @@ -42,8 +63,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 { @@ -75,27 +94,6 @@ u16 g_selected_item = 0; Text input system */ -struct TextDestSign : public TextDest -{ - TextDestSign(v3s16 blockpos, s16 id, Client *client) - { - m_blockpos = blockpos; - m_id = id; - m_client = client; - } - void gotText(std::wstring text) - { - std::string ntext = wide_to_narrow(text); - dstream<<"Changing text of a sign object: " - <sendSignText(m_blockpos, m_id, ntext); - } - - v3s16 m_blockpos; - s16 m_id; - Client *m_client; -}; - struct TextDestChat : public TextDest { TextDestChat(Client *client) @@ -107,18 +105,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); @@ -139,7 +125,7 @@ struct TextDestSignNode : public TextDest void gotText(std::wstring text) { std::string ntext = wide_to_narrow(text); - dstream<<"Changing text of a sign node: " + infostream<<"Changing text of a sign node: " <sendSignNodeText(m_p, ntext); } @@ -148,143 +134,25 @@ 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; +/* Respawn menu callback */ - // 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 "<sendRespawn(); } - - 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="<getList("main"); if(mainlist == NULL) { - dstream<<"WARNING: draw_hotbar(): mainlist == NULL"<draw2DRectangle(video::SColor(255,255,0,0), - core::rect(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( + v2s32(x1 - padding, y1 - padding), + v2s32(x2 + padding, y1) + ), NULL); + driver->draw2DRectangle(c_outside, + core::rect( + v2s32(x1 - padding, y2), + v2s32(x2 + padding, y2 + padding) + ), NULL); + driver->draw2DRectangle(c_outside, + core::rect( + v2s32(x1 - padding, y1), + v2s32(x1, y2) + ), NULL); + driver->draw2DRectangle(c_outside, + core::rect( + v2s32(x2, y1), + v2s32(x2 + padding, y2) + ), NULL); + /*// Light inside borders + driver->draw2DRectangle(c_inside, + core::rect( + v2s32(x1 - padding/2, y1 - padding/2), + v2s32(x2 + padding/2, y1) + ), NULL); + driver->draw2DRectangle(c_inside, + core::rect( + v2s32(x1 - padding/2, y2), + v2s32(x2 + padding/2, y2 + padding/2) + ), NULL); + driver->draw2DRectangle(c_inside, + core::rect( + v2s32(x1 - padding/2, y1), + v2s32(x1, y2) + ), NULL); + driver->draw2DRectangle(c_inside, + core::rect( + 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); @@ -358,7 +270,7 @@ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font, core::rect(core::position2d(0,0), core::dimension2di(heart_texture->getOriginalSize())), NULL, colors, true); - p += v2s32(20,0); + p += v2s32(16,0); } if(halfheartcount % 2 == 1) { @@ -371,7 +283,7 @@ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font, driver->draw2DImage(heart_texture, rect, core::rect(core::position2d(0,0), srcd), NULL, colors, true); - p += v2s32(20,0); + p += v2s32(16,0); } } } @@ -390,7 +302,7 @@ void getPointedNode(Client *client, v3f player_position, v3s16 pos_i = floatToInt(player_position, BS); - /*std::cout<<"pos_i=("<getNode(v3s16(x,y,z)); - if(content_pointable(n.d) == false) + if(content_pointable(n.getContent()) == false) continue; } catch(InvalidPositionException &e) @@ -434,9 +346,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; @@ -481,9 +393,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; @@ -530,9 +442,59 @@ void getPointedNode(Client *client, v3f player_position, } } } - else if(n.d == CONTENT_RAIL) + + else if(n.getContent() == CONTENT_LADDER) { - 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; + 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 box; + + box = core::aabbox3d(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; @@ -632,6 +594,10 @@ void update_skybox(video::IVideoDriver* driver, skybox->remove(); } + /*// Disable skybox if FarMesh is enabled + if(g_settings->getBool("enable_farmesh")) + return;*/ + if(brightness >= 0.5) { skybox = smgr->addSkyBoxSceneNode( @@ -664,6 +630,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 textsize_u = font->getDimension(loadingtext); + core::vector2d textsize(textsize_u.X,textsize_u.Y); + core::vector2d center(screensize.X/2, screensize.Y/2); + core::rect 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, @@ -675,18 +669,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 @@ -697,20 +697,10 @@ void the_game( /* Draw "Loading" screen */ - const wchar_t *loadingtext = L"Loading and connecting..."; - u32 text_height = font->getDimension(loadingtext).Height; - core::vector2d center(screensize.X/2, screensize.Y/2); - core::vector2d textsize(300, text_height); - core::rect 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. @@ -718,8 +708,9 @@ void the_game( */ SharedPtr server; if(address == ""){ - std::cout<start(port); } @@ -727,9 +718,12 @@ void the_game( Create client */ - std::cout<remove(); + //gui_loadingtext->remove(); return; } @@ -751,9 +745,9 @@ void the_game( Attempt to connect to the server */ - dstream<beginScene(true, true, video::SColor(255,0,0,0)); guienv->drawAll(); - driver->endScene(); + driver->endScene();*/ // Update client and server @@ -801,15 +801,16 @@ void the_game( { if(client.accessDenied()) { - error_message = L"Access denied. Check your password and try again."; - std::cout<remove(); + //gui_loadingtext->remove(); return; } @@ -823,25 +824,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" @@ -851,14 +837,27 @@ void the_game( float cloud_height = BS*100; Clouds *clouds = NULL; - clouds = new Clouds(smgr->getRootSceneNode(), smgr, -1, - cloud_height, time(0)); + if(g_settings->getBool("enable_clouds")) + { + clouds = new Clouds(smgr->getRootSceneNode(), smgr, -1, + cloud_height, time(0)); + } + + /* + FarMesh + */ + + FarMesh *farmesh = NULL; + if(g_settings->getBool("enable_farmesh")) + { + farmesh = new FarMesh(smgr->getRootSceneNode(), smgr, -1, client.getMapSeed(), &client); + } /* Move into game */ - gui_loadingtext->remove(); + //gui_loadingtext->remove(); /* Add some gui stuff @@ -874,7 +873,6 @@ void the_game( L"", core::rect(5, 5+(text_height+5)*1, 795, (5+text_height)*2), false, false); - // At the middle of the screen // Object infos are shown in this gui::IGUIStaticText *guitext_info = guienv->addStaticText( @@ -886,11 +884,20 @@ void the_game( gui::IGUIStaticText *guitext_chat = guienv->addStaticText( L"", core::rect(0,0,0,0), - false, false); // Disable word wrap as of now - //false, true); + //false, false); // Disable word wrap as of now + false, true); //guitext_chat->setBackgroundColor(video::SColor(96,0,0,0)); core::list chat_lines; + // Profiler text (size is updated when text is updated) + gui::IGUIStaticText *guitext_profiler = guienv->addStaticText( + L"", + core::rect(6, 4+(text_height+5)*2, 400, + (text_height+5)*2 + text_height*35), + false, false); + guitext_profiler->setBackgroundColor(video::SColor(80,0,0,0)); + guitext_profiler->setVisible(false); + /*GUIQuickInventory *quick_inventory = new GUIQuickInventory (guienv, NULL, v2s32(10, 70), 5, &local_inventory);*/ /*GUIQuickInventory *quick_inventory = new GUIQuickInventory @@ -929,7 +936,24 @@ void the_game( core::list frametime_log; + float nodig_delay_counter = 0.0; + float dig_time = 0.0; + u16 dig_index = 0; + v3s16 nodepos_old(-32768,-32768,-32768); + float damage_flash_timer = 0; + s16 farmesh_range = 20*MAP_BLOCKSIZE; + + const float object_hit_delay = 0.5; + float object_hit_delay_timer = 0.0; + + bool invert_mouse = g_settings->getBool("invert_mouse"); + + bool respawn_menu_active = false; + + bool show_profiler = false; + bool force_fog_off = false; + bool disable_camera_update = false; /* Main loop @@ -937,6 +961,10 @@ void the_game( bool first_loop_after_window_activation = true; + // TODO: Convert the static interval timers to these + // Interval limiter for profiler + IntervalLimiter m_profiler_interval; + // Time is in milliseconds // NOTE: getRealTime() causes strange problems in wine (imprecision?) // NOTE: So we have to use getTime() and call run()s between them @@ -944,6 +972,16 @@ void the_game( while(device->run() && kill == false) { + //std::cerr<<"frame"<disconnect_requested) { g_gamecallback->disconnect_requested = false; @@ -969,6 +1007,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 > hilightboxes; @@ -998,23 +1044,17 @@ void the_game( busytime = busytime_u32 / 1000.0; } - //std::cout<<"busytime_u32="<getFloat("fps_max"); u32 frametime_min = 1000./fps_max; if(busytime_u32 < frametime_min) @@ -1039,6 +1079,13 @@ void the_game( dtime = 0; lasttime = time; + /* Run timers */ + + object_hit_delay_timer -= dtime; + + g_profiler->add("Elapsed time", dtime); + g_profiler->avg("FPS", 1./dtime); + /* Log frametime for visualization */ @@ -1053,15 +1100,15 @@ void the_game( Visualize frametime in terminal */ /*for(u32 i=0; igetFloat("profiler_print_interval"); + bool print_to_log = true; + if(profiler_print_interval == 0){ + print_to_log = false; + profiler_print_interval = 5; + } + if(m_profiler_interval.step(dtime, profiler_print_interval)) + { + if(print_to_log){ + infostream<<"Profiler:"<print(infostream); + } + + std::ostringstream os(std::ios_base::binary); + g_profiler->print(os); + std::wstring text = narrow_to_wide(os.str()); + guitext_profiler->setText(text.c_str()); + + g_profiler->clear(); + + s32 w = font->getDimension(text.c_str()).Width; + if(w < 400) + w = 400; + core::rect rect(6, 4+(text_height+5)*2, 12+w, + 8+(text_height+5)*2 + + font->getDimension(text.c_str()).Height); + guitext_profiler->setRelativePosition(rect); + } + /* Direct handling of user input */ @@ -1141,7 +1221,7 @@ void the_game( */ if(input->wasKeyDown(getKeySetting("keymap_inventory"))) { - dstream<drop(); } - else if(input->wasKeyDown(KEY_ESCAPE)) + else if(input->wasKeyDown(EscapeKey)) { - dstream<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")) + if(g_settings->getBool("free_move")) { - g_settings.set("free_move","false"); + g_settings->set("free_move","false"); + chat_lines.push_back(ChatLine(L"free_move disabled")); } else { - g_settings.set("free_move","true"); + g_settings->set("free_move","true"); + chat_lines.push_back(ChatLine(L"free_move enabled")); } } else if(input->wasKeyDown(getKeySetting("keymap_fastmove"))) { - if(g_settings.getBool("fast_move")) + if(g_settings->getBool("fast_move")) { - g_settings.set("fast_move","false"); + g_settings->set("fast_move","false"); + chat_lines.push_back(ChatLine(L"fast_move disabled")); } else { - g_settings.set("fast_move","true"); + g_settings->set("fast_move","true"); + chat_lines.push_back(ChatLine(L"fast_move enabled")); } } + else if(input->wasKeyDown(getKeySetting("keymap_frametime_graph"))) + { + if(g_settings->getBool("frametime_graph")) + { + g_settings->set("frametime_graph","false"); + chat_lines.push_back(ChatLine(L"frametime_graph disabled")); + } + else + { + g_settings->set("frametime_graph","true"); + 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" DIR_DELIM "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 '"<drop(); + } + } + else if(input->wasKeyDown(getKeySetting("keymap_toggle_profiler"))) + { + show_profiler = !show_profiler; + guitext_profiler->setVisible(show_profiler); + if(show_profiler) + chat_lines.push_back(ChatLine(L"Profiler disabled")); + else + chat_lines.push_back(ChatLine(L"Profiler enabled")); + } + else if(input->wasKeyDown(getKeySetting("keymap_toggle_force_fog_off"))) + { + force_fog_off = !force_fog_off; + if(force_fog_off) + chat_lines.push_back(ChatLine(L"Fog disabled")); + else + chat_lines.push_back(ChatLine(L"Fog enabled")); + } + else if(input->wasKeyDown(getKeySetting("keymap_toggle_update_camera"))) + { + disable_camera_update = !disable_camera_update; + if(disable_camera_update) + chat_lines.push_back(ChatLine(L"Camera update disabled")); + else + chat_lines.push_back(ChatLine(L"Camera update enabled")); + } // Item selection with mouse wheel { @@ -1232,16 +1381,14 @@ 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) { g_selected_item = i; - dstream<isWindowActive() && noMenuActive()) || random_input) + { + if(!random_input) + { + // Mac OSX gets upset if this is set every frame + if(device->getCursorControl()->isVisible()) + device->getCursorControl()->setVisible(false); + } + + if(first_loop_after_window_activation){ + //infostream<<"window active, first loop"<getMousePos().X - displaycenter.X; + s32 dy = input->getMousePos().Y - displaycenter.Y; + if(invert_mouse) + dy = -dy; + //infostream<<"window active, pos difference "<isKeyDown(irr::KEY_UP)) + dy -= dtime * keyspeed; + if(input->isKeyDown(irr::KEY_DOWN)) + dy += dtime * keyspeed; + if(input->isKeyDown(irr::KEY_LEFT)) + dx -= dtime * keyspeed; + if(input->isKeyDown(irr::KEY_RIGHT)) + dx += dtime * keyspeed;*/ + + camera_yaw -= dx*0.2; + camera_pitch += dy*0.2; + if(camera_pitch < -89.5) camera_pitch = -89.5; + if(camera_pitch > 89.5) camera_pitch = 89.5; + } + input->setMousePos(displaycenter.X, displaycenter.Y); + } + else{ + // Mac OSX gets upset if this is set every frame + if(device->getCursorControl()->isVisible() == false) + device->getCursorControl()->setVisible(true); + + //infostream<<"window inactive"<isWindowActive()) + { + PlayerControl control( + false, + false, + false, + false, + false, + false, + false, + camera_pitch, + camera_yaw + ); + client.setPlayerControl(control); + } + else { /*bool a_up, bool a_down, @@ -1322,98 +1535,75 @@ void the_game( //client.step(dtime_avg1); } - // Read client events - for(;;) { - ClientEvent event = client.getClientEvent(); - if(event.type == CE_NONE) + // Read client events + for(;;) { - break; - } - else if(event.type == CE_PLAYER_DAMAGE) - { - //u16 damage = event.player_damage.amount; - //dstream<<"Player damage: "<= 2){ + damage_flash_timer += 0.05 * event.player_damage.amount; + } + } + else if(event.type == CE_PLAYER_FORCE_MOVE) + { + camera_yaw = event.player_force_move.yaw; + camera_pitch = event.player_force_move.pitch; + } + else if(event.type == CE_DEATHSCREEN) + { + if(respawn_menu_active) + continue; + + /*bool set_camera_point_target = + event.deathscreen.set_camera_point_target; + v3f camera_point_target; + camera_point_target.X = event.deathscreen.camera_point_target_x; + camera_point_target.Y = event.deathscreen.camera_point_target_y; + camera_point_target.Z = event.deathscreen.camera_point_target_z;*/ + MainRespawnInitiator *respawner = + new MainRespawnInitiator( + &respawn_menu_active, &client); + GUIDeathScreen *menu = + new GUIDeathScreen(guienv, guiroot, -1, + &g_menumgr, respawner); + menu->drop(); + + /* Handle visualization */ - /* - Mouse and camera control - */ - - if((device->isWindowActive() && noMenuActive()) || random_input) - { - if(!random_input) - device->getCursorControl()->setVisible(false); + damage_flash_timer = 0; - if(first_loop_after_window_activation){ - //std::cout<<"window active, first loop"<getMousePos().X - displaycenter.X; - s32 dy = input->getMousePos().Y - displaycenter.Y; - //std::cout<<"window active, pos difference "<isKeyDown(irr::KEY_UP)) - dy -= dtime * keyspeed; - if(input->isKeyDown(irr::KEY_DOWN)) - dy += dtime * keyspeed; - if(input->isKeyDown(irr::KEY_LEFT)) - dx -= dtime * keyspeed; - if(input->isKeyDown(irr::KEY_RIGHT)) - dx += dtime * keyspeed;*/ - - camera_yaw -= dx*0.2; - camera_pitch += dy*0.2; - if(camera_pitch < -89.5) camera_pitch = -89.5; - if(camera_pitch > 89.5) camera_pitch = 89.5; + /*LocalPlayer* player = client.getLocalPlayer(); + player->setPosition(player->getPosition() + v3f(0,-BS,0)); + camera.update(player, busytime, screensize);*/ + } } - input->setMousePos(displaycenter.X, displaycenter.Y); } - else{ - device->getCursorControl()->setVisible(true); - - //std::cout<<"window inactive"<setPosition(camera_position); - // *100.0 helps in large map coordinates - camera->setTarget(camera_position + camera_direction * 100.0); + LocalPlayer* player = client.getLocalPlayer(); + camera.update(player, busytime, screensize); + camera.step(dtime); - if(FIELD_OF_VIEW_TEST){ - client.updateCamera(v3f(0,0,0), v3f(0,0,1)); - } - else{ - //TimeTaker timer("client.updateCamera"); - client.updateCamera(camera_position, camera_direction); - } + v3f player_position = player->getPosition(); + v3f camera_position = camera.getPosition(); + v3f camera_direction = camera.getDirection(); + f32 camera_fov = camera.getFovMax(); + if(!disable_camera_update){ + client.updateCamera(camera_position, + camera_direction, camera_fov); + } + //timer2.stop(); //TimeTaker //timer3("//timer3"); @@ -1428,72 +1618,24 @@ void the_game( core::line3d shootline(camera_position, camera_position + camera_direction * BS * (d+1)); - MapBlockObject *selected_object = client.getSelectedObject - (d*BS, camera_position, shootline); - ClientActiveObject *selected_active_object = client.getSelectedActiveObject (d*BS, camera_position, shootline); + + bool left_punch = false; + bool left_punch_muted = false; - if(selected_object != NULL) + if(selected_active_object != NULL) { - //dstream<<"Client returned selected_object != NULL"< box_on_map - = selected_object->getSelectionBoxOnMap(); - - hilightboxes.push_back(box_on_map); - - infotext = narrow_to_wide(selected_object->infoText()); - - if(input->getLeftClicked()) + /* Clear possible cracking animation */ + if(nodepos_old != v3s16(-32768,-32768,-32768)) { - std::cout<getBlock()->getPos(), - selected_object->getId(), g_selected_item); + client.clearTempMod(nodepos_old); + dig_time = 0.0; + nodepos_old = v3s16(-32768,-32768,-32768); } - else if(input->getRightClicked()) - { - std::cout<getTypeId() == MAPBLOCKOBJECT_TYPE_SIGN) - { - dstream<<"Sign object right-clicked"<getBlock()->getPos(), - selected_object->getId(), - &client); - - SignObject *sign_object = (SignObject*)selected_object; - - std::wstring wtext = - narrow_to_wide(sign_object->getText()); - - (new GUITextInputMenu(guienv, guiroot, -1, - &g_menumgr, dest, - wtext))->drop(); - } - } - /* - Otherwise pass the event to the server as-is - */ - else - { - client.clickObject(1, selected_object->getBlock()->getPos(), - selected_object->getId(), g_selected_item); - } - } - } - else if(selected_active_object != NULL) - { - //dstream<<"Client returned selected_active_object != NULL"< *selection_box = selected_active_object->getSelectionBox(); @@ -1507,21 +1649,40 @@ void the_game( selection_box->MinEdge + pos, selection_box->MaxEdge + pos ); - - hilightboxes.push_back(box_on_map); + + if(selected_active_object->doShowSelectionBox()) + hilightboxes.push_back(box_on_map); //infotext = narrow_to_wide("A ClientActiveObject"); infotext = narrow_to_wide(selected_active_object->infoText()); - if(input->getLeftClicked()) + //if(input->getLeftClicked()) + if(input->getLeftState()) { - std::cout<getId(), g_selected_item); + bool do_punch = false; + bool do_punch_damage = false; + if(object_hit_delay_timer <= 0.0){ + do_punch = true; + do_punch_damage = true; + object_hit_delay_timer = object_hit_delay; + } + if(input->getLeftClicked()){ + do_punch = true; + } + if(do_punch){ + infostream<<"Left-clicked object"<getId(), g_selected_item); + } } else if(input->getRightClicked()) { - std::cout<getId(), g_selected_item); } } else // selected_object == NULL @@ -1542,15 +1703,14 @@ void the_game( nodepos, neighbourpos, nodehilightbox, d); - static float nodig_delay_counter = 0.0; - - if(nodefound) - { - static v3s16 nodepos_old(-32768,-32768,-32768); - - static float dig_time = 0.0; - static u16 dig_index = 0; - + if(!nodefound){ + if(nodepos_old != v3s16(-32768,-32768,-32768)) + { + client.clearTempMod(nodepos_old); + dig_time = 0.0; + nodepos_old = v3s16(-32768,-32768,-32768); + } + } else { /* Visualize selection */ @@ -1587,20 +1747,21 @@ void the_game( { if(nodepos != nodepos_old) { - std::cout<getLeftClicked() || (input->getLeftState() && nodepos != nodepos_old)) { - dstream<getLeftClicked()) @@ -1625,7 +1786,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); @@ -1633,7 +1794,7 @@ void the_game( if(prop.diggable == false) { - /*dstream<<"Material "<<(int)material + /*infostream<<"Material "<<(int)material <<" not diggable with \"" <getRightClicked()) { - std::cout<typeId() == CONTENT_SIGN_WALL && !random_input) + // If metadata provides an inventory view, activate it + if(meta && meta->getInventoryDrawSpecString() != "" && !random_input) { - dstream<<"Sign node right-clicked"<getText()); + core::array draw_spec; + v2s16 invsize = + GUIInventoryMenu::makeDrawSpecArrayFromString( + draw_spec, + meta->getInventoryDrawSpecString(), + current_name); - (new GUITextInputMenu(guienv, guiroot, -1, - &g_menumgr, dest, - wtext))->drop(); - } - else if(meta && meta->typeId() == CONTENT_CHEST && !random_input) - { - dstream<<"Chest node right-clicked"< draw_spec; - - draw_spec.push_back(GUIInventoryMenu::DrawSpec( - "list", chest_inv_id, "0", - v2s32(0, 0), v2s32(8, 4))); - draw_spec.push_back(GUIInventoryMenu::DrawSpec( - "list", "current_player", "main", - v2s32(0, 5), v2s32(8, 4))); - menu->setDrawSpec(draw_spec); - menu->drop(); - } - else if(meta && meta->typeId() == CONTENT_FURNACE && !random_input) + else if(meta && meta->typeId() == CONTENT_SIGN_WALL && !random_input) { - dstream<<"Furnace node right-clicked"<drop(); + TextDest *dest = new TextDestSignNode(nodepos, &client); + + std::wstring wtext = + narrow_to_wide(signmeta->getText()); + (new GUITextInputMenu(guienv, guiroot, -1, + &g_menumgr, dest, + wtext))->drop(); } else { client.groundAction(1, nodepos, neighbourpos, g_selected_item); + camera.setDigging(1); // right click animation } } nodepos_old = nodepos; } - else{ - } } // selected_object == NULL + if(left_punch || (input->getLeftClicked() && !left_punch_muted)) + { + camera.setDigging(0); // left click animation + } + input->resetLeftClicked(); input->resetRightClicked(); if(input->getLeftReleased()) { - std::cout<getRightReleased()) { - //std::cout<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( @@ -1815,7 +1970,7 @@ void the_game( update_skybox(driver, smgr, skybox, brightness); /* - Update coulds + Update clouds */ if(clouds) { @@ -1824,6 +1979,22 @@ void the_game( 0.05+brightness*0.95); } + /* + Update farmesh + */ + if(farmesh) + { + farmesh_range = draw_control.wanted_range * 10; + if(draw_control.range_all && farmesh_range < 500) + farmesh_range = 500; + if(farmesh_range > 1000) + farmesh_range = 1000; + + farmesh->step(dtime); + farmesh->update(v2f(player_position.X, player_position.Z), + 0.05+brightness*0.95, farmesh_range); + } + // Store brightness value old_brightness = brightness; @@ -1831,13 +2002,22 @@ void the_game( Fog */ - if(g_settings.getBool("enable_fog") == true) + if(g_settings->getBool("enable_fog") == true && !force_fog_off) { - f32 range = draw_control.wanted_range*BS + MAP_BLOCKSIZE*BS*1.5; - if(draw_control.range_all) - range = 100000*BS; - if(range < 50*BS) - range = range * 0.5 + 25*BS; + f32 range; + if(farmesh) + { + range = BS*farmesh_range; + } + else + { + range = draw_control.wanted_range*BS + MAP_BLOCKSIZE*BS*1.5; + range *= 0.9; + if(draw_control.range_all) + range = 100000*BS; + /*if(range < 50*BS) + range = range * 0.5 + 25*BS;*/ + } driver->setFog( bgcolor, @@ -1862,7 +2042,6 @@ void the_game( ); } - /* Update gui stuff (0ms) */ @@ -1902,14 +2081,15 @@ void the_game( "(% .1f, % .1f, % .1f)" " (% .3f < btime_jitter < % .3f" ", dtime_jitter = % .1f %%" - ", v_range = %.1f)", + ", v_range = %.1f, RTT = %.3f)", player_position.X/BS, player_position.Y/BS, player_position.Z/BS, busytime_jitter1_min_sample, busytime_jitter1_max_sample, dtime_jitter1_max_fraction * 100.0, - draw_control.wanted_range + draw_control.wanted_range, + client.getRTT() ); guitext2->setText(narrow_to_wide(temptext).c_str()); @@ -1985,12 +2165,13 @@ void the_game( 10, 50, screensize.X - 10, - 50 + text_height*chat_lines.size() + 50 + guitext_chat->getTextHeight() ); guitext_chat->setRelativePosition(rect); - if(chat_lines.size() == 0) + // Don't show chat if empty or profiler is enabled + if(chat_lines.size() == 0 || show_profiler) guitext_chat->setVisible(false); else guitext_chat->setVisible(true); @@ -2004,9 +2185,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"<getItem(g_selected_item); + camera.wield(item); } /* @@ -2034,10 +2223,10 @@ void the_game( //driver->beginScene(false, true, bgcolor); beginscenetime = timer.stop(true); } - + //timer3.stop(); - //std::cout<drawAll()"<drawAll()"< >::Iterator i=hilightboxes.begin(); i != hilightboxes.end(); i++) { - /*std::cout<<"hilightbox min=" + /*infostream<<"hilightbox min=" <<"("<MinEdge.X<<","<MinEdge.Y<<","<MinEdge.Z<<")" <<" max=" <<"("<MaxEdge.X<<","<MaxEdge.Y<<","<MaxEdge.Z<<")" @@ -2071,10 +2260,25 @@ void the_game( driver->draw3DBox(*i, video::SColor(255,0,0,0)); } + /* + Wielded tool + */ + { + // Warning: This clears the Z buffer. + camera.drawWieldedTool(); + } + + /* + Post effects + */ + { + client.renderPostFx(); + } + /* Frametime log */ - if(g_settings.getBool("frametime_graph") == true) + if(g_settings->getBool("frametime_graph") == true) { s32 x = 10; for(core::list::Iterator @@ -2131,7 +2335,7 @@ void the_game( core::rect(0,0,screensize.X,screensize.Y), NULL); } - + /* End scene */ @@ -2166,22 +2370,20 @@ void the_game( /* Drop stuff */ - clouds->drop(); + if(clouds) + clouds->drop(); /* Draw a "shutting down" screen, which will be shown while the map 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();*/ } }