Exemple #1
0
WORLDPTR worldfactory::pick_world( bool show_prompt )
{
    std::map<std::string, WORLDPTR> worlds = get_all_worlds();
    std::vector<std::string> world_names = all_worldnames;

    // Filter out special worlds (TUTORIAL | DEFENSE) from world_names.
    for (std::vector<std::string>::iterator it = world_names.begin(); it != world_names.end();) {
        if (*it == "TUTORIAL" || *it == "DEFENSE") {
            it = world_names.erase(it);
        } else if (world_need_lua_build(*it)) {
            it = world_names.erase(it);
        } else {
            ++it;
        }
    }
    // If there is only one world to pick from, autoreturn it.
    if (world_names.size() == 1) {
        return worlds[world_names[0]];
    }
    // If there are no worlds to pick from, immediately try to make one.
    else if (world_names.empty()) {
        return make_new_world( show_prompt );
    }
    // If we're skipping prompts, just return the first one.
    else if( !show_prompt ) {
        return worlds[world_names[0]];
    }

    const int iTooltipHeight = 3;
    const int iContentHeight = FULL_SCREEN_HEIGHT - 3 - iTooltipHeight;
    const unsigned int num_pages = world_names.size() / iContentHeight + 1; // at least 1 page
    const int iOffsetX = (TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0;
    const int iOffsetY = (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY - FULL_SCREEN_HEIGHT) / 2 : 0;

    std::map<int, bool> mapLines;
    mapLines[3] = true;

    std::map<int, std::vector<std::string> > world_pages;
    unsigned int worldnum = 0;
    for (size_t i = 0; i < num_pages; ++i) {
        for (int j = 0; j < iContentHeight && worldnum < world_names.size(); ++j) {
            world_pages[i].push_back(world_names[worldnum++]);
        }
    }
    unsigned int sel = 0, selpage = 0;

    WINDOW *w_worlds_border = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);
    WINDOW *w_worlds_tooltip = newwin(iTooltipHeight, FULL_SCREEN_WIDTH - 2, 1 + iOffsetY,
                                      1 + iOffsetX);
    WINDOW *w_worlds_header = newwin(1, FULL_SCREEN_WIDTH - 2, 1 + iTooltipHeight + iOffsetY,
                                     1 + iOffsetX);
    WINDOW *w_worlds        = newwin(iContentHeight, FULL_SCREEN_WIDTH - 2,
                                     iTooltipHeight + 2 + iOffsetY, 1 + iOffsetX);

    draw_border(w_worlds_border);
    mvwputch(w_worlds_border, 4, 0, BORDER_COLOR, LINE_XXXO); // |-
    mvwputch(w_worlds_border, 4, FULL_SCREEN_WIDTH - 1, BORDER_COLOR, LINE_XOXX); // -|

    for( auto &mapLine : mapLines ) {
        mvwputch( w_worlds_border, FULL_SCREEN_HEIGHT - 1, mapLine.first + 1, BORDER_COLOR,
                  LINE_XXOX ); // _|_
    }

    center_print(w_worlds_border, 0, c_ltred, _(" WORLD SELECTION "));
    wrefresh(w_worlds_border);

    for (int i = 0; i < 78; i++) {
        if (mapLines[i]) {
            mvwputch(w_worlds_header, 0, i, BORDER_COLOR, LINE_OXXX);
        } else {
            mvwputch(w_worlds_header, 0, i, BORDER_COLOR, LINE_OXOX); // Draw header line
        }
    }

    wrefresh(w_worlds_header);

    input_context ctxt("PICK_WORLD_DIALOG");
    ctxt.register_updown();
    ctxt.register_action("HELP_KEYBINDINGS");
    ctxt.register_action("QUIT");
    ctxt.register_action("NEXT_TAB");
    ctxt.register_action("PREV_TAB");
    ctxt.register_action("CONFIRM");

    std::stringstream sTemp;

    while(true) {
        //Clear the lines
        for (int i = 0; i < iContentHeight; i++) {
            for (int j = 0; j < 79; j++) {
                if (mapLines[j]) {
                    mvwputch(w_worlds, i, j, BORDER_COLOR, LINE_XOXO);
                } else {
                    mvwputch(w_worlds, i, j, c_black, ' ');
                }

                if (i < iTooltipHeight) {
                    mvwputch(w_worlds_tooltip, i, j, c_black, ' ');
                }
            }
        }

        //Draw World Names
        for (size_t i = 0; i < world_pages[selpage].size(); ++i) {
            sTemp.str("");
            sTemp << i + 1;
            mvwprintz(w_worlds, i, 0, c_white, "%s", sTemp.str().c_str());
            mvwprintz(w_worlds, i, 4, c_white, "");

            std::string world_name = (world_pages[selpage])[i];
            size_t saves_num = world_generator->all_worlds[world_name]->world_saves.size();

            if (i == sel) {
                wprintz(w_worlds, c_yellow, ">> ");
            } else {
                wprintz(w_worlds, c_yellow, "   ");
            }

            if (world_need_lua_build(world_name)) {
                wprintz(w_worlds, c_dkgray, "%s (%i)", world_name.c_str(), saves_num);
            } else {
                wprintz(w_worlds, c_white, "%s (%i)", world_name.c_str(), saves_num);
            }
        }

        //Draw Tabs
        mvwprintz(w_worlds_header, 0, 7, c_white, "");

        for (size_t i = 0; i < num_pages; ++i) {
            nc_color tabcolor = (selpage == i) ? hilite(c_white) : c_white;
            if (!world_pages[i].empty()) { //skip empty pages
                wprintz(w_worlds_header, c_white, "[");
                wprintz(w_worlds_header, tabcolor, _("Page %d"), i + 1);
                wprintz(w_worlds_header, c_white, "]");
                wputch(w_worlds_header, BORDER_COLOR, LINE_OXOX);
            }
        }

        wrefresh(w_worlds_header);

        fold_and_print(w_worlds_tooltip, 0, 0, 78, c_white, _("Pick a world to enter game"));
        wrefresh(w_worlds_tooltip);

        wrefresh(w_worlds);

        const std::string action = ctxt.handle_input();

        if (action == "QUIT") {
            break;
        } else if (!world_pages[selpage].empty() && action == "DOWN") {
            sel++;
            if (sel >= world_pages[selpage].size()) {
                sel = 0;
            }
        } else if (!world_pages[selpage].empty() && action == "UP") {
            if (sel == 0) {
                sel = world_pages[selpage].size() - 1;
            } else {
                sel--;
            }
        } else if (action == "NEXT_TAB") {
            sel = 0;
            do { //skip empty pages
                selpage++;
                if (selpage >= world_pages.size()) {
                    selpage = 0;
                }
            } while(world_pages[selpage].empty());
        } else if (action == "PREV_TAB") {
            sel = 0;
            do { //skip empty pages
                if (selpage != 0) {
                    selpage--;
                } else {
                    selpage = world_pages.size() - 1;
                }
            } while(world_pages[selpage].empty());
        } else if (action == "CONFIRM") {
            if (world_need_lua_build(world_pages[selpage][sel])) {
                popup(_("Can't start in world [%s]. Some of mods require Lua support."),
                      world_pages[selpage][sel].c_str());
                continue;
            }
            // we are wanting to get out of this by confirmation, so ask if we want to load the level [y/n prompt] and if yes exit
            if (query_yn(_("Do you want to start the game in world [%s]?"),
                         world_pages[selpage][sel].c_str())) {
                werase(w_worlds);
                werase(w_worlds_border);
                werase(w_worlds_header);
                werase(w_worlds_tooltip);
                return all_worlds[world_pages[selpage][sel]];//sel + selpage * iContentHeight;
            }
        }
    }

    werase(w_worlds);
    werase(w_worlds_border);
    werase(w_worlds_header);
    werase(w_worlds_tooltip);

    return NULL;
}
WORLDPTR worldfactory::pick_world()
{
    std::map<std::string, WORLDPTR> worlds = get_all_worlds();
    std::vector<std::string> world_names = all_worldnames;

    // filter out special worlds (TUTORIAL | DEFENSE) from world_names
    for (std::vector<std::string>::iterator it = world_names.begin(); it != world_names.end();) {
        if (*it == "TUTORIAL" || *it == "DEFENSE") {
            it = world_names.erase(it);
        } else {
            ++it;
        }
    }
    // if there is only one world to pick from, autoreturn it
    if (world_names.size() == 1) {
        return worlds[world_names[0]];
    }
    // if there are no worlds to pick from, immediately try to make one
    else if (world_names.empty()) {
        return make_new_world();
    }

    const int iTooltipHeight = 3;
    const int iContentHeight = FULL_SCREEN_HEIGHT - 3 - iTooltipHeight;
    const int num_pages = world_names.size() / iContentHeight + 1; // at least 1 page
    const int iOffsetX = (TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0;
    const int iOffsetY = (TERMY > FULL_SCREEN_HEIGHT) ? (TERMY - FULL_SCREEN_HEIGHT) / 2 : 0;

    std::map<int, bool> mapLines;
    mapLines[3] = true;

    std::map<int, std::vector<std::string> > world_pages;
    int worldnum = 0;
    for (int i = 0; i < num_pages; ++i) {
        world_pages[i] = std::vector<std::string>();
        for (int j = 0; j < iContentHeight; ++j) {
            world_pages[i].push_back(world_names[worldnum++]);
            if (worldnum == world_names.size()) {
                break;
            }
        }
    }
    int sel = 0, selpage = 0;

    WINDOW *w_worlds_border = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);
    WINDOW *w_worlds_tooltip = newwin(iTooltipHeight, FULL_SCREEN_WIDTH - 2, 1 + iOffsetY, 1 + iOffsetX);
    WINDOW *w_worlds_header = newwin(1, FULL_SCREEN_WIDTH - 2, 1 + iTooltipHeight + iOffsetY, 1 + iOffsetX);
    WINDOW *w_worlds        = newwin(iContentHeight, FULL_SCREEN_WIDTH - 2, iTooltipHeight + 2 + iOffsetY, 1 + iOffsetX);

    draw_border(w_worlds_border);
    mvwputch(w_worlds_border, 4, 0, c_dkgray, LINE_XXXO); // |-
    mvwputch(w_worlds_border, 4, 79, c_dkgray, LINE_XOXX); // -|

    for (std::map<int, bool>::iterator iter = mapLines.begin(); iter != mapLines.end(); ++iter) {
        mvwputch(w_worlds_border, FULL_SCREEN_HEIGHT - 1, iter->first + 1, c_dkgray, LINE_XXOX); // _|_
    }

    mvwprintz(w_worlds_border, 0, 31, c_ltred, _(" WORLD SELECTION "));
    wrefresh(w_worlds_border);

    for (int i = 0; i < 78; i++) {
        if (mapLines[i]) {
            mvwputch(w_worlds_header, 0, i, c_dkgray, LINE_OXXX);
        } else {
            mvwputch(w_worlds_header, 0, i, c_dkgray, LINE_OXOX); // Draw header line
        }
    }

    wrefresh(w_worlds_header);

    char ch = ' ';

    std::stringstream sTemp;

    do {
        //Clear the lines
        for (int i = 0; i < iContentHeight; i++) {
            for (int j = 0; j < 79; j++) {
                if (mapLines[j]) {
                    mvwputch(w_worlds, i, j, c_dkgray, LINE_XOXO);
                } else {
                    mvwputch(w_worlds, i, j, c_black, ' ');
                }

                if (i < iTooltipHeight) {
                    mvwputch(w_worlds_tooltip, i, j, c_black, ' ');
                }
            }
        }

        //Draw World Names
        for (unsigned i = 0; i < world_pages[selpage].size(); ++i) {
            sTemp.str("");
            sTemp << i + 1;
            mvwprintz(w_worlds, i, 0, c_white, sTemp.str().c_str());
            mvwprintz(w_worlds, i, 4, c_white, "");


            if (i == sel) {
                wprintz(w_worlds, c_yellow, ">> ");
            } else {
                wprintz(w_worlds, c_yellow, " ");
            }

            wprintz(w_worlds, c_white, "%s", (world_pages[selpage])[i].c_str());
        }

        //Draw Tabs
        mvwprintz(w_worlds_header, 0, 7, c_white, "");

        for (int i = 0; i < num_pages; ++i) {
            nc_color tabcolor = (selpage == i) ? hilite(c_white):c_white;
            if (world_pages[i].size() > 0) { //skip empty pages
                wprintz(w_worlds_header, c_white, "[");
                wprintz(w_worlds_header, tabcolor, _("Page %d"), i + 1);
                wprintz(w_worlds_header, c_white, "]");
                wputch(w_worlds_header, c_dkgray, LINE_OXOX);
            }
        }

        wrefresh(w_worlds_header);

        fold_and_print(w_worlds_tooltip, 0, 0, 78, c_white, _("Pick a world to enter game"));
        wrefresh(w_worlds_tooltip);

        wrefresh(w_worlds);

        ch = input();

        if (world_pages[selpage].size() > 0 || ch == '\t') {
            switch(ch) {
            case 'j': //move down
                sel++;
                if (sel >= world_pages[selpage].size()) {
                    sel = 0;
                }
                break;
            case 'k': //move up
                sel--;
                if (sel < 0) {
                    sel = world_pages[selpage].size() - 1;
                }
                break;
            case '>':
            case '\t': //Switch to next Page
                sel = 0;
                do { //skip empty pages
                    selpage++;
                    if (selpage >= world_pages.size()) {
                        selpage = 0;
                    }
                } while(world_pages[selpage].size() == 0);

                break;
            case '<':
                sel = 0;
                do { //skip empty pages
                    selpage--;
                    if (selpage < 0) {
                        selpage = world_pages.size() - 1;
                    }
                } while(world_pages[selpage].size() == 0);
                break;
            case '\n':
                // we are wanting to get out of this by confirmation, so ask if we want to load the level [y/n prompt] and if yes exit
                std::string querystring = string_format(_("Do you want to start the game in world [%s]?"), world_pages[selpage][sel].c_str());
                if (query_yn(querystring.c_str())) {
                    werase(w_worlds);
                    werase(w_worlds_border);
                    werase(w_worlds_header);
                    werase(w_worlds_tooltip);
                    return all_worlds[world_pages[selpage][sel]];//sel + selpage * iContentHeight;
                }
                break;
            }
        }
    } while(ch != 'q' && ch != 'Q' && ch != KEY_ESCAPE);

    werase(w_worlds);
    werase(w_worlds_border);
    werase(w_worlds_header);
    werase(w_worlds_tooltip);

    return NULL;
}