コード例 #1
0
ファイル: main_menu.cpp プロジェクト: D33pfield/Cataclysm-DDA
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;
}
コード例 #2
0
ファイル: main_menu.cpp プロジェクト: Nukesor/Cataclysm-DDA
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;
}