bool game::opening_screen() { // Play title music, whoo! play_music( "title" ); world_generator->set_active_world( NULL ); // This actually _loads_ what worlds exist. world_generator->get_all_worlds(); WINDOW *w_background = newwin( TERMY, TERMX, 0, 0 ); WINDOW_PTR w_backgroundptr( w_background ); werase( w_background ); wrefresh( w_background ); // main window should also expand to use available display space. // expanding to evenly use up half of extra space, for now. int extra_w = ( ( TERMX - FULL_SCREEN_WIDTH ) / 2 ) - 1; int extra_h = ( ( TERMY - FULL_SCREEN_HEIGHT ) / 2 ) - 1; extra_w = ( extra_w > 0 ? extra_w : 0 ); extra_h = ( extra_h > 0 ? extra_h : 0 ); const int total_w = FULL_SCREEN_WIDTH + extra_w; const int total_h = FULL_SCREEN_HEIGHT + extra_h; // position of window within main display const int x0 = ( TERMX - total_w ) / 2; const int y0 = ( TERMY - total_h ) / 2; WINDOW *w_open = newwin( total_h, total_w, y0, x0 ); WINDOW_PTR w_openptr( w_open ); const int iMenuOffsetX = 0; int iMenuOffsetY = total_h - 3; // note: if iMenuOffset is changed, // please update MOTD and credits to indicate how long they can be. // fill menu with translated menu items vMenuItems.clear(); vMenuItems.push_back( pgettext( "Main Menu", "<M|m>OTD" ) ); vMenuItems.push_back( pgettext( "Main Menu", "<N|n>ew Game" ) ); vMenuItems.push_back( pgettext( "Main Menu", "Lo<a|A>d" ) ); vMenuItems.push_back( pgettext( "Main Menu", "<W|w>orld" ) ); vMenuItems.push_back( pgettext( "Main Menu", "<S|s>pecial" ) ); vMenuItems.push_back( pgettext( "Main Menu", "<O|o>ptions" ) ); vMenuItems.push_back( pgettext( "Main Menu", "H<e|E|?>lp" ) ); vMenuItems.push_back( pgettext( "Main Menu", "<C|c>redits" ) ); vMenuItems.push_back( pgettext( "Main Menu", "<Q|q>uit" ) ); // determine hotkeys from (possibly translated) menu item text vMenuHotkeys.clear(); for( auto item : vMenuItems ) { vMenuHotkeys.push_back( get_hotkeys( item ) ); } std::vector<std::string> vSubItems; vSubItems.push_back( pgettext( "Main Menu|New Game", "<C|c>ustom Character" ) ); vSubItems.push_back( pgettext( "Main Menu|New Game", "<P|p>reset Character" ) ); vSubItems.push_back( pgettext( "Main Menu|New Game", "<R|r>andom Character" ) ); if( !MAP_SHARING::isSharing() ) { // "Play Now" function doesn't play well together with shared maps vSubItems.push_back( pgettext( "Main Menu|New Game", "Play <N|n>ow!" ) ); } std::vector<std::vector<std::string>> vNewGameHotkeys; for( auto item : vSubItems ) { vNewGameHotkeys.push_back( get_hotkeys( item ) ); } std::vector<std::string> vWorldSubItems; vWorldSubItems.push_back( pgettext( "Main Menu|World", "<C|c>reate World" ) ); vWorldSubItems.push_back( pgettext( "Main Menu|World", "<D|d>elete World" ) ); vWorldSubItems.push_back( pgettext( "Main Menu|World", "<R|r>eset World" ) ); std::vector<std::vector<std::string>> vWorldHotkeys; for( auto item : vWorldSubItems ) { vWorldHotkeys.push_back( get_hotkeys( item ) ); } mmenu_refresh_title(); print_menu( w_open, 0, iMenuOffsetX, iMenuOffsetY ); std::vector<std::string> savegames, templates; dirent *dp; DIR *dir; if( !assure_dir_exist( FILENAMES["config_dir"] ) ) { popup( _( "Unable to make config directory. Check permissions." ) ); return false; } if( !assure_dir_exist( FILENAMES["savedir"] ) ) { popup( _( "Unable to make save directory. Check permissions." ) ); return false; } if( !assure_dir_exist( FILENAMES["templatedir"] ) ) { popup( _( "Unable to make templates directory. Check permissions." ) ); return false; } dir = opendir( FILENAMES["templatedir"].c_str() ); while( ( dp = readdir( dir ) ) ) { std::string tmp = dp->d_name; if( tmp.find( ".template" ) != std::string::npos ) { templates.push_back( tmp.substr( 0, tmp.find( ".template" ) ) ); } } closedir( dir ); int sel1 = 1, sel2 = 1, sel3 = 1, layer = 1; input_context ctxt( "MAIN_MENU" ); ctxt.register_cardinal(); ctxt.register_action( "QUIT" ); ctxt.register_action( "CONFIRM" ); ctxt.register_action( "DELETE_TEMPLATE" ); // for the menu shortcuts ctxt.register_action( "ANY_INPUT" ); bool start = false; // Load MOTD and Credits, load it once as it shouldn't change for the duration of the application being open mmenu_refresh_motd(); mmenu_refresh_credits(); u = player(); while( !start ) { print_menu( w_open, sel1, iMenuOffsetX, iMenuOffsetY, ( sel1 == 0 || sel1 == 7 ) ? false : true ); if( layer == 1 ) { if( sel1 == 0 ) { // Print the MOTD. const int motdy = ( iMenuOffsetY - mmenu_motd.size() ) * 2 / 3; const int motdx = 8 + extra_w / 2; for( size_t i = 0; i < mmenu_motd.size(); i++ ) { mvwprintz( w_open, motdy + i, motdx, c_ltred, mmenu_motd[i].c_str() ); } wrefresh( w_open ); refresh(); } else if( sel1 == 7 ) { // Print the Credits. const int credy = ( iMenuOffsetY - mmenu_credits.size() ) * 2 / 3; const int credx = 8 + extra_w / 2; for( size_t i = 0; i < mmenu_credits.size(); i++ ) { mvwprintz( w_open, credy + i, credx, c_ltred, mmenu_credits[i].c_str() ); } wrefresh( w_open ); refresh(); } std::string action = ctxt.handle_input(); std::string sInput = ctxt.get_raw_input().text; // check automatic menu shortcuts for( size_t i = 0; i < vMenuHotkeys.size(); ++i ) { for( auto hotkey : vMenuHotkeys[i] ) { if( sInput == hotkey ) { sel1 = i; action = "CONFIRM"; } } } // also check special keys if( action == "QUIT" ) { // Quit sel1 = 8; action = "CONFIRM"; } else if( action == "LEFT" ) { if( sel1 > 0 ) { sel1--; } else { sel1 = 8; } sfx::play_variant_sound( "menu_move", "default", 100 ); } else if( action == "RIGHT" ) { if( sel1 < 8 ) { sel1++; } else { sel1 = 0; } sfx::play_variant_sound( "menu_move", "default", 100 ); } if( ( action == "UP" || action == "CONFIRM" ) && sel1 > 0 && sel1 != 7 ) { if( sel1 == 5 ) { get_options().show(); } else if( sel1 == 6 ) { display_help(); } else if( sel1 == 8 ) { uquit = QUIT_MENU; return false; } else { sel2 = 0; layer = 2; print_menu( w_open, sel1, iMenuOffsetX, iMenuOffsetY, ( sel1 == 0 || sel1 == 7 ) ? false : true ); } } } else if( layer == 2 ) { if( sel1 == 1 ) { // New Character if( MAP_SHARING::isSharing() && world_generator->all_worlds.empty() ) { //don't show anything when there are no worlds (will not work if there are special maps) layer = 1; sel1 = 1; continue; } print_menu_items( w_open, vSubItems, sel2, iMenuOffsetY - 2, iMenuOffsetX ); wrefresh( w_open ); refresh(); std::string action = ctxt.handle_input(); std::string sInput = ctxt.get_raw_input().text; for( size_t i = 0; i < vNewGameHotkeys.size(); ++i ) { for( auto hotkey : vNewGameHotkeys[i] ) { if( sInput == hotkey ) { sel2 = i; action = "CONFIRM"; } } } if( action == "LEFT" ) { sel2--; if( sel2 < 0 ) { sel2 = vSubItems.size() - 1; } } else if( action == "RIGHT" ) { sel2++; if( sel2 >= ( int )vSubItems.size() ) { sel2 = 0; } } else if( action == "DOWN" || action == "QUIT" ) { layer = 1; sel1 = 1; } if( action == "UP" || action == "CONFIRM" ) { if( sel2 == 0 || sel2 == 2 || sel2 == 3 ) { // First load the mods, this is done by // loading the world. // Pick a world, suppressing prompts if it's "play now" mode. WORLDPTR world = world_generator->pick_world( sel2 != 3 ); if( world == NULL ) { continue; } world_generator->set_active_world( world ); setup(); if( !u.create( sel2 == 0 ? PLTYPE_CUSTOM : ( sel2 == 2 ? PLTYPE_RANDOM : PLTYPE_NOW ) ) ) { u = player(); continue; } werase( w_background ); wrefresh( w_background ); if( !start_game( world->world_name ) ) { u = player(); continue; } start = true; } else if( sel2 == 1 ) { layer = 3; sel3 = 0; } } } else if( sel1 == 2 ) { // Load Character if( world_generator->all_worldnames.empty() ) { mvwprintz( w_open, iMenuOffsetY - 2, 15 + iMenuOffsetX + extra_w / 2, c_red, _( "No Worlds found!" ) ); } else { for( int i = 0; i < ( int )world_generator->all_worldnames.size(); ++i ) { int line = iMenuOffsetY - 2 - i; std::string world_name = world_generator->all_worldnames[i]; int savegames_count = world_generator->all_worlds[world_name]->world_saves.size(); nc_color color1, color2; if( world_name == "TUTORIAL" || world_name == "DEFENSE" ) { color1 = c_ltcyan; color2 = h_ltcyan; } else { if( world_generator->world_need_lua_build( world_name ) ) { color1 = c_dkgray; color2 = h_dkgray; } else { color1 = c_white; color2 = h_white; } } mvwprintz( w_open, line, 15 + iMenuOffsetX + extra_w / 2, ( sel2 == i ? color2 : color1 ), "%s (%d)", world_name.c_str(), savegames_count ); } } wrefresh( w_open ); refresh(); const std::string action = ctxt.handle_input(); if( world_generator->all_worldnames.empty() && ( action == "DOWN" || action == "CONFIRM" ) ) { layer = 1; } else if( action == "DOWN" ) { if( sel2 > 0 ) { sel2--; } else { sel2 = world_generator->all_worldnames.size() - 1; } } else if( action == "UP" ) { if( sel2 < ( int )world_generator->all_worldnames.size() - 1 ) { sel2++; } else { sel2 = 0; } } else if( action == "LEFT" || action == "QUIT" ) { layer = 1; } else if( action == "RIGHT" || action == "CONFIRM" ) { if( sel2 >= 0 && sel2 < ( int )world_generator->all_worldnames.size() ) { layer = 3; sel3 = 0; } } } else if( sel1 == 3 ) { // World Menu // Show options for Create, Destroy, Reset worlds. // Create world goes directly to Make World screen. // Reset and Destroy ask for world to modify. // Reset empties world of everything but options, then makes new world within it. // Destroy asks for confirmation, then destroys everything in world and then removes world folder. // only show reset / destroy world if there is at least one valid world existing! if( MAP_SHARING::isSharing() && !MAP_SHARING::isWorldmenu() && !MAP_SHARING::isAdmin() ) { layer = 1; popup( _( "Only the admin can change worlds." ) ); continue; } int world_subs_to_display = ( !world_generator->all_worldnames.empty() ) ? vWorldSubItems.size() : 1; std::vector<std::string> world_subs; int xoffset = 25 + iMenuOffsetX + extra_w / 2; int yoffset = iMenuOffsetY - 2; int xlen = 0; for( int i = 0; i < world_subs_to_display; ++i ) { world_subs.push_back( vWorldSubItems[i] ); xlen += vWorldSubItems[i].size() + 2; // Open and close brackets added } xlen += world_subs.size() - 1; if( world_subs.size() > 1 ) { xoffset -= 6; } print_menu_items( w_open, world_subs, sel2, yoffset, xoffset - ( xlen / 4 ) ); wrefresh( w_open ); refresh(); std::string action = ctxt.handle_input(); std::string sInput = ctxt.get_raw_input().text; for( int i = 0; i < world_subs_to_display; ++i ) { for( auto hotkey : vWorldHotkeys[i] ) { if( sInput == hotkey ) { sel2 = i; action = "CONFIRM"; } } } if( action == "LEFT" ) { if( sel2 > 0 ) { --sel2; } else { sel2 = world_subs_to_display - 1; } } else if( action == "RIGHT" ) { if( sel2 < world_subs_to_display - 1 ) { ++sel2; } else { sel2 = 0; } } else if( action == "DOWN" || action == "QUIT" ) { layer = 1; } if( action == "UP" || action == "CONFIRM" ) { if( sel2 == 0 ) { // Create world // Open up world creation screen! if( world_generator->make_new_world() ) { return opening_screen(); } else { layer = 1; } } else if( sel2 == 1 || sel2 == 2 ) { // Delete World | Reset World layer = 3; sel3 = 0; } } } else if( sel1 == 4 ) { // Special game if( MAP_SHARING::isSharing() ) { // Thee can't save special games, therefore thee can't share them layer = 1; popup( _( "Special games don't work with shared maps." ) ); continue; } std::vector<std::string> special_names; int xoffset = 32 + iMenuOffsetX + extra_w / 2; int yoffset = iMenuOffsetY - 2; int xlen = 0; for( int i = 1; i < NUM_SPECIAL_GAMES; i++ ) { std::string spec_name = special_game_name( special_game_id( i ) ); special_names.push_back( spec_name ); xlen += spec_name.size() + 2; } xlen += special_names.size() - 1; print_menu_items( w_open, special_names, sel2, yoffset, xoffset - ( xlen / 4 ) ); wrefresh( w_open ); refresh(); std::string action = ctxt.handle_input(); if( action == "LEFT" ) { if( sel2 > 0 ) { sel2--; } else { sel2 = NUM_SPECIAL_GAMES - 2; } } else if( action == "RIGHT" ) { if( sel2 < NUM_SPECIAL_GAMES - 2 ) { sel2++; } else { sel2 = 0; } } else if( action == "DOWN" || action == "QUIT" ) { layer = 1; } if( action == "UP" || action == "CONFIRM" ) { if( sel2 >= 0 && sel2 < NUM_SPECIAL_GAMES - 1 ) { gamemode = get_special_game( special_game_id( sel2 + 1 ) ); // check world WORLDPTR world = world_generator->make_new_world( special_game_id( sel2 + 1 ) ); if( world == NULL ) { continue; } world_generator->set_active_world( world ); setup(); if( !gamemode->init() ) { gamemode.reset(); u = player(); continue; } start = true; } } } } else if( layer == 3 ) { bool available = false; if( sel1 == 2 ) { // Load Game savegames = world_generator->all_worlds[world_generator->all_worldnames[sel2]]->world_saves; std::string wn = world_generator->all_worldnames[sel2]; //hide savegames if lua is not available for a lua-built world if( ( wn != "TUTORIAL" && wn != "DEFENSE" ) && world_generator->world_need_lua_build( wn ) ) { savegames.clear(); mvwprintz( w_open, iMenuOffsetY - 2, 15 + iMenuOffsetX + extra_w / 2, c_red, _( "This world requires the game to be compiled with Lua." ) ); } else if( savegames.empty() ) { mvwprintz( w_open, iMenuOffsetY - 2, 19 + 19 + iMenuOffsetX + extra_w / 2, c_red, _( "No save games found!" ) ); } else { for( std::vector<std::string>::iterator it = savegames.begin(); it != savegames.end(); ) { std::string savename = base64_decode( *it ); if( MAP_SHARING::isSharing() && savename != MAP_SHARING::getUsername() ) { it = savegames.erase( it ); } else { // calculates the index from distance between it and savegames.begin() int i = it - savegames.begin(); available = true; int line = iMenuOffsetY - 2 - i; mvwprintz( w_open, line, 19 + 19 + iMenuOffsetX + extra_w / 2, ( sel3 == i ? h_white : c_white ), base64_decode( *it ).c_str() ); ++it; } } if( !available ) { mvwprintz( w_open, iMenuOffsetY - 2, 19 + 19 + iMenuOffsetX + extra_w / 2, c_red, _( "No save games found!" ) ); } } wrefresh( w_open ); refresh(); std::string action = ctxt.handle_input(); if( savegames.empty() && ( action == "DOWN" || action == "CONFIRM" ) ) { layer = 2; } else if( action == "DOWN" ) { if( sel3 > 0 ) { sel3--; } else { sel3 = savegames.size() - 1; } } else if( action == "UP" ) { if( sel3 < ( int )savegames.size() - 1 ) { sel3++; } else { sel3 = 0; } } else if( action == "LEFT" || action == "QUIT" ) { layer = 2; sel3 = 0; print_menu( w_open, sel1, iMenuOffsetX, iMenuOffsetY ); } if( action == "RIGHT" || action == "CONFIRM" ) { if( sel3 >= 0 && sel3 < ( int )savegames.size() ) { werase( w_background ); wrefresh( w_background ); WORLDPTR world = world_generator->all_worlds[world_generator->all_worldnames[sel2]]; world_generator->set_active_world( world ); setup(); load( world->world_name, savegames[sel3] ); start = true; } } } else if( sel1 == 3 ) { // Show world names int i = 0; for( std::vector<std::string>::iterator it = world_generator->all_worldnames.begin(); it != world_generator->all_worldnames.end(); ++it ) { int savegames_count = world_generator->all_worlds[*it]->world_saves.size(); int line = iMenuOffsetY - 4 - i; nc_color color1, color2; if( *it == "TUTORIAL" || *it == "DEFENSE" ) { color1 = c_ltcyan; color2 = h_ltcyan; } else { color1 = c_white; color2 = h_white; } mvwprintz( w_open, line, 26 + iMenuOffsetX + extra_w / 2, ( sel3 == i ? color2 : color1 ), "%s (%d)", ( *it ).c_str(), savegames_count ); ++i; } wrefresh( w_open ); refresh(); std::string action = ctxt.handle_input(); if( action == "DOWN" ) { if( sel3 > 0 ) { --sel3; } else { sel3 = world_generator->all_worldnames.size() - 1; } } else if( action == "UP" ) { if( sel3 < ( int )world_generator->all_worldnames.size() - 1 ) { ++sel3; } else { sel3 = 0; } } else if( action == "LEFT" || action == "QUIT" ) { layer = 2; print_menu( w_open, sel1, iMenuOffsetX, iMenuOffsetY ); } if( action == "RIGHT" || action == "CONFIRM" ) { if( sel3 >= 0 && sel3 < ( int )world_generator->all_worldnames.size() ) { bool query_yes = false; bool do_delete = false; if( sel2 == 1 ) { // Delete World if( query_yn( _( "Delete the world and all saves?" ) ) ) { query_yes = true; do_delete = true; } } else if( sel2 == 2 ) { // Reset World if( query_yn( _( "Remove all saves and regenerate world?" ) ) ) { query_yes = true; do_delete = false; } } if( query_yes ) { delete_world( world_generator->all_worldnames[sel3], do_delete ); savegames.clear(); MAPBUFFER.reset(); overmap_buffer.clear(); layer = 2; if( do_delete ) { // delete world and all contents world_generator->remove_world( world_generator->all_worldnames[sel3] ); } else { // clear out everything but worldoptions from this world world_generator->all_worlds[world_generator->all_worldnames[sel3]]->world_saves.clear(); } if( world_generator->all_worldnames.empty() ) { sel2 = 0; // reset to create world selection } } else { // hacky resolution to the issue of persisting world names on the screen return opening_screen(); } } print_menu( w_open, sel1, iMenuOffsetX, iMenuOffsetY ); } } else { // Character Templates if( templates.empty() ) { mvwprintz( w_open, iMenuOffsetY - 4, iMenuOffsetX + 20 + extra_w / 2, c_red, _( "No templates found!" ) ); } else { mvwprintz( w_open, iMenuOffsetY - 2, iMenuOffsetX + 20 + extra_w / 2, c_white, _( "Press 'd' to delete a preset." ) ); for( int i = 0; i < ( int )templates.size(); i++ ) { int line = iMenuOffsetY - 4 - i; mvwprintz( w_open, line, 20 + iMenuOffsetX + extra_w / 2, ( sel3 == i ? h_white : c_white ), templates[i].c_str() ); } } wrefresh( w_open ); refresh(); std::string action = ctxt.handle_input(); if( action == "DOWN" ) { if( sel3 > 0 ) { sel3--; } else { sel3 = templates.size() - 1; } } else if( templates.empty() && ( action == "UP" || action == "CONFIRM" ) ) { sel1 = 1; layer = 2; print_menu( w_open, sel1, iMenuOffsetX, iMenuOffsetY ); } else if( action == "UP" ) { if( sel3 < ( int )templates.size() - 1 ) { sel3++; } else { sel3 = 0; } } else if( action == "LEFT" || action == "QUIT" || templates.empty() ) { sel1 = 1; layer = 2; print_menu( w_open, sel1, iMenuOffsetX, iMenuOffsetY ); } else if( !templates.empty() && action == "DELETE_TEMPLATE" ) { if( query_yn( _( "Are you sure you want to delete %s?" ), templates[sel3].c_str() ) ) { const auto path = FILENAMES["templatedir"] + templates[sel3] + ".template"; if( std::remove( path.c_str() ) != 0 ) { popup( _( "Sorry, something went wrong." ) ); } else { templates.erase( templates.begin() + sel3 ); if( ( size_t )sel3 > templates.size() - 1 ) { sel3--; } } } } else if( action == "RIGHT" || action == "CONFIRM" ) { WORLDPTR world = world_generator->pick_world(); if( world == NULL ) { u = player(); continue; } world_generator->set_active_world( world ); setup(); if( !u.create( PLTYPE_TEMPLATE, templates[sel3] ) ) { u = player(); continue; } werase( w_background ); wrefresh( w_background ); if( !start_game( world_generator->active_world->world_name ) ) { u = player(); continue; } start = true; } } } } w_openptr.reset(); w_backgroundptr.reset(); if( start == false ) { uquit = QUIT_MENU; } else { refresh_all(); draw(); } return start; }
bool main_menu::opening_screen() { // Play title music, whoo! play_music( "title" ); world_generator->set_active_world( NULL ); world_generator->init(); w_background = newwin( TERMY, TERMX, 0, 0 ); WINDOW_PTR w_backgroundptr( w_background ); werase( w_background ); wrefresh( w_background ); // main window should also expand to use available display space. // expanding to evenly use up half of extra space, for now. extra_w = ( ( TERMX - FULL_SCREEN_WIDTH ) / 2 ) - 1; int extra_h = ( ( TERMY - FULL_SCREEN_HEIGHT ) / 2 ) - 1; extra_w = ( extra_w > 0 ? extra_w : 0 ); extra_h = ( extra_h > 0 ? extra_h : 0 ); const int total_w = FULL_SCREEN_WIDTH + extra_w; const int total_h = FULL_SCREEN_HEIGHT + extra_h; // position of window within main display const int x0 = ( TERMX - total_w ) / 2; const int y0 = ( TERMY - total_h ) / 2; w_open = newwin( total_h, total_w, y0, x0 ); WINDOW_PTR w_openptr( w_open ); iMenuOffsetY = total_h - 3; // note: if iMenuOffset is changed, // please update MOTD and credits to indicate how long they can be. init_strings(); print_menu( w_open, 0, iMenuOffsetX, iMenuOffsetY ); if( !assure_dir_exist( FILENAMES["config_dir"] ) ) { popup( _( "Unable to make config directory. Check permissions." ) ); return false; } if( !assure_dir_exist( FILENAMES["savedir"] ) ) { popup( _( "Unable to make save directory. Check permissions." ) ); return false; } if( !assure_dir_exist( FILENAMES["templatedir"] ) ) { popup( _( "Unable to make templates directory. Check permissions." ) ); return false; } for( std::string path : get_files_from_path( ".template", FILENAMES["templatedir"], false, true ) ) { path = native_to_utf8( path ); path.erase( path.find( ".template" ), std::string::npos ); path.erase( 0, path.find_last_of( "\\//" ) + 1 ); templates.push_back( path ); } std::sort( templates.begin(), templates.end(), std::greater<std::string>() ); ctxt.register_cardinal(); ctxt.register_action( "QUIT" ); ctxt.register_action( "CONFIRM" ); ctxt.register_action( "DELETE_TEMPLATE" ); // for the menu shortcuts ctxt.register_action( "ANY_INPUT" ); bool start = false; g->u = player(); // Make [Load Game] the default cursor position if there's game save available if( !world_generator->all_worldnames().empty() ) { sel1 = 2; } while( !start ) { print_menu( w_open, sel1, iMenuOffsetX, iMenuOffsetY, ( sel1 != 0 ) ); if( layer == 1 ) { if( sel1 == 0 ) { // Print the MOTD. const int motdy = ( iMenuOffsetY - mmenu_motd.size() ) * 2 / 3; const int motdx = 8 + extra_w / 2; for( size_t i = 0; i < mmenu_motd.size(); i++ ) { mvwprintz( w_open, motdy + i, motdx, c_ltred, mmenu_motd[i].c_str() ); } wrefresh( w_open ); refresh(); } std::string action = ctxt.handle_input(); std::string sInput = ctxt.get_raw_input().text; // check automatic menu shortcuts for( size_t i = 0; i < vMenuHotkeys.size(); ++i ) { for( auto hotkey : vMenuHotkeys[i] ) { if( sInput == hotkey ) { sel1 = i; action = "CONFIRM"; } } } // also check special keys if( action == "QUIT" ) { if( query_yn( _( "Really quit?" ) ) ) { sel1 = 8; action = "CONFIRM"; } } else if( action == "LEFT" ) { if( sel1 > 0 ) { sel1--; } else { sel1 = 8; } on_move(); } else if( action == "RIGHT" ) { if( sel1 < 8 ) { sel1++; } else { sel1 = 0; } on_move(); } if( ( action == "UP" || action == "CONFIRM" ) && sel1 > 0 ) { if( sel1 == 6 ) { display_help(); } else if( sel1 == 7 ) { display_credits(); } else if( sel1 == 8 ) { return false; } else { sel2 = 0; layer = 2; print_menu( w_open, sel1, iMenuOffsetX, iMenuOffsetY, ( sel1 != 0 ) ); switch( sel1 ) { case 1: start = new_character_tab(); break; case 2: start = load_character_tab(); break; case 3: world_tab(); break; default: break; } } } } else if( layer == 2 ) { if( sel1 == 4 ) { // Special game if( MAP_SHARING::isSharing() ) { // Thee can't save special games, therefore thee can't share them layer = 1; popup( _( "Special games don't work with shared maps." ) ); continue; } std::vector<std::string> special_names; int xoffset = 32 + iMenuOffsetX + extra_w / 2; int yoffset = iMenuOffsetY - 2; int xlen = 0; for( int i = 1; i < NUM_SPECIAL_GAMES; i++ ) { std::string spec_name = special_game_name( special_game_id( i ) ); special_names.push_back( spec_name ); xlen += spec_name.size() + 2; } xlen += special_names.size() - 1; print_menu_items( w_open, special_names, sel2, yoffset, xoffset - ( xlen / 4 ) ); wrefresh( w_open ); refresh(); std::string action = ctxt.handle_input(); if( action == "LEFT" ) { if( sel2 > 0 ) { sel2--; } else { sel2 = NUM_SPECIAL_GAMES - 2; } on_move(); } else if( action == "RIGHT" ) { if( sel2 < NUM_SPECIAL_GAMES - 2 ) { sel2++; } else { sel2 = 0; } on_move(); } else if( action == "DOWN" || action == "QUIT" ) { layer = 1; } if( action == "UP" || action == "CONFIRM" ) { if( sel2 >= 0 && sel2 < NUM_SPECIAL_GAMES - 1 ) { g->gamemode = get_special_game( special_game_id( sel2 + 1 ) ); // check world WORLDPTR world = world_generator->make_new_world( special_game_id( sel2 + 1 ) ); if( world == NULL ) { continue; } world_generator->set_active_world( world ); try { g->setup(); } catch( const std::exception &err ) { debugmsg( "Error: %s", err.what() ); g->gamemode.reset(); g->u = player(); continue; } if( !g->gamemode->init() ) { g->gamemode.reset(); g->u = player(); continue; } start = true; } } } else if( sel1 == 5 ) { // Settings Menu int settings_subs_to_display = vSettingsSubItems.size(); std::vector<std::string> settings_subs; int xoffset = 46 + iMenuOffsetX + extra_w / 2; int yoffset = iMenuOffsetY - 2; int xlen = 0; for( int i = 0; i < settings_subs_to_display; ++i ) { settings_subs.push_back( vSettingsSubItems[i] ); xlen += vSettingsSubItems[i].size() + 2; // Open and close brackets added } xlen += settings_subs.size() - 1; if( settings_subs.size() > 1 ) { xoffset -= 6; } print_menu_items( w_open, settings_subs, sel2, yoffset, xoffset - ( xlen / 4 ) ); wrefresh( w_open ); refresh(); std::string action = ctxt.handle_input(); std::string sInput = ctxt.get_raw_input().text; for( int i = 0; i < settings_subs_to_display; ++i ) { for( auto hotkey : vSettingsHotkeys[i] ) { if( sInput == hotkey ) { sel2 = i; action = "CONFIRM"; } } } if( action == "LEFT" ) { if( sel2 > 0 ) { --sel2; } else { sel2 = settings_subs_to_display - 1; } on_move(); } else if( action == "RIGHT" ) { if( sel2 < settings_subs_to_display - 1 ) { ++sel2; } else { sel2 = 0; } on_move(); } else if( action == "DOWN" || action == "QUIT" ) { layer = 1; } if( action == "UP" || action == "CONFIRM" ) { if( sel2 == 0 ) { get_options().show( true ); // The language may have changed- gracefully handle this. init_strings(); print_menu( w_open, sel1, iMenuOffsetX, iMenuOffsetY, ( sel1 != 0 ) ); } else if( sel2 == 1 ) { input_context ctxt_default = get_default_mode_input_context(); ctxt_default.display_help(); } else if( sel2 == 2 ) { get_auto_pickup().show(); } else if( sel2 == 3 ) { get_safemode().show(); } else if( sel2 == 4 ) { all_colors.show_gui(); } } } } } w_openptr.reset(); w_backgroundptr.reset(); if( start ) { g->refresh_all(); g->draw(); } return start; }