X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fgame.cpp;h=d7efbeae9fbaf616d19113ee48820f5463cd79bd;hb=64996422c00ddb70cfc8aee7da7b62485b8b0416;hp=a996626515d677a70772553a373ede615053ca5b;hpb=36af9bb027ed6846227282587e3414ea3d30f6c5;p=dragonfireclient.git diff --git a/src/game.cpp b/src/game.cpp index a99662651..d7efbeae9 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -17,27 +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 "guiDeathScreen.h" #include "materials.h" #include "config.h" #include "clouds.h" #include "camera.h" #include "farmesh.h" #include "mapblock.h" - -/* - TODO: Move content-aware stuff to separate file by adding properties - and virtual interfaces -*/ +#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 @@ -81,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) @@ -133,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); } @@ -142,6 +134,26 @@ struct TextDestSignNode : public TextDest Client *m_client; }; +/* Respawn menu callback */ + +class MainRespawnInitiator: public IRespawnInitiator +{ +public: + MainRespawnInitiator(bool *active, Client *client): + m_active(active), m_client(client) + { + *m_active = true; + } + void respawn() + { + *m_active = false; + m_client->sendRespawn(); + } +private: + bool *m_active; + Client *m_client; +}; + /* Hotbar draw routine */ @@ -152,7 +164,7 @@ void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font, InventoryList *mainlist = inventory->getList("main"); if(mainlist == NULL) { - dstream<<"WARNING: draw_hotbar(): mainlist == NULL"<getBool("enable_farmesh")) return;*/ if(brightness >= 0.5) @@ -697,7 +709,7 @@ void the_game( SharedPtr server; if(address == ""){ draw_load_screen(L"Creating server...", driver, font); - std::cout<start(port); } @@ -707,7 +719,7 @@ void the_game( */ draw_load_screen(L"Creating client...", driver, font); - std::cout<remove(); @@ -733,9 +745,9 @@ void the_game( Attempt to connect to the server */ - dstream<remove(); return; @@ -825,7 +837,7 @@ void the_game( float cloud_height = BS*100; Clouds *clouds = NULL; - if(g_settings.getBool("enable_clouds")) + if(g_settings->getBool("enable_clouds")) { clouds = new Clouds(smgr->getRootSceneNode(), smgr, -1, cloud_height, time(0)); @@ -836,7 +848,7 @@ void the_game( */ FarMesh *farmesh = NULL; - if(g_settings.getBool("enable_farmesh")) + if(g_settings->getBool("enable_farmesh")) { farmesh = new FarMesh(smgr->getRootSceneNode(), smgr, -1, client.getMapSeed(), &client); } @@ -861,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( @@ -878,6 +889,15 @@ void the_game( //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 @@ -916,10 +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 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 @@ -944,7 +978,7 @@ void the_game( { error_message = L"Access denied. Reason: " +client.accessDeniedReason(); - std::cout<getFloat("fps_max"); u32 frametime_min = 1000./fps_max; if(busytime_u32 < frametime_min) @@ -1045,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 */ @@ -1059,8 +1100,8 @@ 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(m_profiler_interval.step(0.030, profiler_print_interval)) - { - dstream<<"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); } /* @@ -1162,7 +1221,7 @@ void the_game( */ if(input->wasKeyDown(getKeySetting("keymap_inventory"))) { - dstream<wasKeyDown(EscapeKey)) { - dstream<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")) + if(g_settings->getBool("frametime_graph")) { - g_settings.set("frametime_graph","false"); + g_settings->set("frametime_graph","false"); chat_lines.push_back(ChatLine(L"frametime_graph disabled")); } else { - g_settings.set("frametime_graph","true"); + g_settings->set("frametime_graph","true"); chat_lines.push_back(ChatLine(L"frametime_graph enabled")); } } @@ -1257,20 +1316,45 @@ void the_game( 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(), + 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 { @@ -1304,7 +1388,7 @@ void the_game( { 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, @@ -1385,78 +1535,60 @@ void the_game( //client.step(dtime_avg1); } - // Read client events - for(;;) { - ClientEvent event = client.getClientEvent(); - if(event.type == CE_NONE) - { - break; - } - else if(event.type == CE_PLAYER_DAMAGE) + // Read client events + for(;;) { - //u16 damage = event.player_damage.amount; - //dstream<<"Player damage: "<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); - } + ClientEvent event = client.getClientEvent(); + if(event.type == CE_NONE) + { + break; + } + else if(event.type == CE_PLAYER_DAMAGE) + { + //u16 damage = event.player_damage.amount; + //infostream<<"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 */ - if(first_loop_after_window_activation){ - //std::cout<<"window active, first loop"<getMousePos().X - displaycenter.X; - s32 dy = input->getMousePos().Y - displaycenter.Y; - if(invert_mouse) - dy = -dy; - //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;*/ + damage_flash_timer = 0; - 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{ - // Mac OSX gets upset if this is set every frame - if(device->getCursorControl()->isVisible() == false) - device->getCursorControl()->setVisible(true); - - //std::cout<<"window inactive"< 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(); @@ -1570,21 +1649,38 @@ 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); } @@ -1607,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 */ @@ -1652,20 +1747,21 @@ void the_game( { if(nodepos != nodepos_old) { - std::cout<getLeftClicked() || (input->getLeftState() && nodepos != nodepos_old)) { - dstream<getLeftClicked()) @@ -1698,7 +1794,7 @@ void the_game( if(prop.diggable == false) { - /*dstream<<"Material "<<(int)material + /*infostream<<"Material "<<(int)material <<" not diggable with \"" <getRightClicked()) { - std::cout<getInventoryDrawSpecString() != "" && !random_input) { - dstream<typeId() == CONTENT_SIGN_WALL && !random_input) { - dstream<<"Sign node right-clicked"<getLeftClicked()) + if(left_punch || (input->getLeftClicked() && !left_punch_muted)) { camera.setDigging(0); // left click animation } @@ -1837,13 +1933,13 @@ void the_game( if(input->getLeftReleased()) { - std::cout<getRightReleased()) { - //std::cout<getBool("enable_fog") == true && !force_fog_off) { f32 range; if(farmesh) @@ -1916,10 +2012,11 @@ void the_game( 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; + /*if(range < 50*BS) + range = range * 0.5 + 25*BS;*/ } driver->setFog( @@ -1984,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()); @@ -2072,7 +2170,8 @@ void the_game( 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); @@ -2088,7 +2187,7 @@ void the_game( { client.selectPlayerItem(g_selected_item); old_selected_item = g_selected_item; - //std::cout<<"Updating local inventory"<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<<")" @@ -2179,7 +2278,7 @@ void the_game( /* Frametime log */ - if(g_settings.getBool("frametime_graph") == true) + if(g_settings->getBool("frametime_graph") == true) { s32 x = 10; for(core::list::Iterator