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; }