void construction_menu() { static bool hide_unconstructable = false; // only display constructions the player can theoretically perform std::vector<std::string> available; load_available_constructions( available, hide_unconstructable ); if(available.empty()) { popup(_("You can not construct anything here.")); return; } int iMaxY = TERMY; if (available.size() + 2 < iMaxY) { iMaxY = available.size() + 2; } if (iMaxY < FULL_SCREEN_HEIGHT) { iMaxY = FULL_SCREEN_HEIGHT; } WINDOW *w_con = newwin( iMaxY, FULL_SCREEN_WIDTH, (TERMY > iMaxY) ? (TERMY - iMaxY) / 2 : 0, (TERMX > FULL_SCREEN_WIDTH) ? (TERMX - FULL_SCREEN_WIDTH) / 2 : 0 ); draw_border(w_con); mvwprintz(w_con, 0, 8, c_ltred, _(" Construction ")); mvwputch(w_con, 0, 30, c_ltgray, LINE_OXXX); mvwputch(w_con, iMaxY - 1, 30, c_ltgray, LINE_XXOX); for( int i = 1; i < iMaxY - 1; ++i ) { mvwputch(w_con, i, 30, c_ltgray, LINE_XOXO); } wrefresh(w_con); bool update_info = true; int select = 0; int chosen = 0; long ch; bool exit = false; inventory total_inv = g->crafting_inventory(&(g->u)); do { // Erase existing list of constructions for( int i = 1; i < iMaxY - 1; i++ ) { for( int j = 1; j < 30; j++ ) { mvwputch(w_con, i, j, c_black, ' '); } } //Draw Scrollbar draw_scrollbar(w_con, select, iMaxY - 2, available.size(), 1); // Determine where in the master list to start printing //int offset = select - 11; int offset = 0; if (select >= iMaxY - 2) { offset = select - iMaxY + 3; } // Print the constructions between offset and max (or how many will fit) for (int i = 0; i < iMaxY - 2 && (i + offset) < available.size(); i++) { int current = i + offset; nc_color col = (player_can_build(g->u, total_inv, available[current]) ? c_white : c_dkgray); // Map menu items to hotkey letters, skipping j, k, l, and q. unsigned char hotkey = 97 + current; if (hotkey > 122) { hotkey = hotkey - 58; } if (current == select) { col = hilite(col); } // print construction name with limited length. // limit(28) = 30(column len) - 2(letter + ' '). mvwprintz(w_con, 1 + i, 1, col, "%c %s", hotkey, utf8_substr(available[current].c_str(), 0, 27).c_str()); } if (update_info) { update_info = false; std::string current_desc = available[select]; // Clear out lines for tools & materials for (int i = 1; i < iMaxY - 1; i++) { for (int j = 31; j < 79; j++) { mvwputch(w_con, i, j, c_black, ' '); } } // Print instructions for toggling recipe hiding. mvwprintz(w_con, 1, 31, c_white, "%s", _("Press ';' to toggle unavailable constructions.")); // Print consruction name mvwprintz(w_con, 2, 31, c_white, "%s", current_desc.c_str()); // Print stages and their requirement int posx = 33, posy = 2; std::vector<construction *> options = constructions_by_desc(current_desc); for( unsigned i = 0; i < options.size(); ++i) { construction *current_con = options[i]; if( hide_unconstructable && !can_construct(current_con) ) { continue; } nc_color color_stage = c_white; // display required skill and difficulty int pskill = g->u.skillLevel(current_con->skill); int diff = (current_con->difficulty > 0) ? current_con->difficulty : 0; posy++; mvwprintz(w_con, posy, 31, c_white, _("Skill: %s"), Skill::skill(current_con->skill)->name().c_str()); posy++; mvwprintz(w_con, posy, 31, (pskill >= diff ? c_white : c_red), _("Difficulty: %d"), diff); // display required terrain if (current_con->pre_terrain != "") { posy++; if (current_con->pre_is_furniture) { mvwprintz(w_con, posy, 31, color_stage, _("Replaces: %s"), furnmap[current_con->pre_terrain].name.c_str()); } else { mvwprintz(w_con, posy, 31, color_stage, _("Replaces: %s"), termap[current_con->pre_terrain].name.c_str()); } } // display result if (current_con->post_terrain != "") { posy++; if (current_con->post_is_furniture) { mvwprintz(w_con, posy, 31, color_stage, _("Result: %s"), furnmap[current_con->post_terrain].name.c_str()); } else { mvwprintz(w_con, posy, 31, color_stage, _("Result: %s"), termap[current_con->post_terrain].name.c_str()); } } // display time needed posy++; mvwprintz(w_con, posy, 31, color_stage, _("Time: %1d minutes"), current_con->time); // Print tools std::vector<bool> has_tool; posy++; posx = 33; for (int i = 0; i < current_con->tools.size(); i++) { has_tool.push_back(false); mvwprintz(w_con, posy, posx - 2, c_white, ">"); for (unsigned j = 0; j < current_con->tools[i].size(); j++) { itype_id tool = current_con->tools[i][j].type; nc_color col = c_red; if (total_inv.has_amount(tool, 1)) { has_tool[i] = true; col = c_green; } int length = utf8_width(item_controller->find_template(tool)->name.c_str()); if( posx + length > FULL_SCREEN_WIDTH - 1 ) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, col, item_controller->find_template(tool)->name.c_str()); posx += length + 1; // + 1 for an empty space if (j < current_con->tools[i].size() - 1) { // "OR" if there's more if (posx > FULL_SCREEN_WIDTH - 3) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, c_white, _("OR")); posx += utf8_width(_("OR")) + 1; } } posy ++; posx = 33; } // Print components posx = 33; std::vector<bool> has_component; for( int i = 0; i < current_con->components.size(); i++ ) { has_component.push_back(false); mvwprintz(w_con, posy, posx - 2, c_white, ">"); for( unsigned j = 0; j < current_con->components[i].size(); j++ ) { nc_color col = c_red; component comp = current_con->components[i][j]; if( ( item_controller->find_template(comp.type)->is_ammo() && total_inv.has_charges(comp.type, comp.count)) || (!item_controller->find_template(comp.type)->is_ammo() && total_inv.has_amount(comp.type, comp.count)) ) { has_component[i] = true; col = c_green; } int length = utf8_width(item_controller->find_template(comp.type)->name.c_str()); if (posx + length > FULL_SCREEN_WIDTH - 1) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, col, "%s x%d", item_controller->find_template(comp.type)->name.c_str(), comp.count); posx += length + 3; // + 2 for " x", + 1 for an empty space // Add more space for the length of the count if (comp.count < 10) { posx++; } else if (comp.count < 100) { posx += 2; } else { posx += 3; } if (j < current_con->components[i].size() - 1) { // "OR" if there's more if (posx > FULL_SCREEN_WIDTH - 3) { posy++; posx = 33; } mvwprintz(w_con, posy, posx, c_white, _("OR")); posx += utf8_width(_("OR")) + 1; } } posy ++; posx = 33; } } wrefresh(w_con); } // Finished updating ch = getch(); switch (ch) { case KEY_DOWN: update_info = true; if (select < available.size() - 1) { select++; } else { select = 0; } break; case KEY_UP: update_info = true; if (select > 0) { select--; } else { select = available.size() - 1; } break; case ' ': case KEY_ESCAPE: case 'q': case 'Q': exit = true; break; case ';': update_info = true; hide_unconstructable = !hide_unconstructable; load_available_constructions( available, hide_unconstructable ); break; case '\n': default: if (ch > 64 && ch < 91) { //A-Z chosen = ch - 65 + 26; } else if (ch > 96 && ch < 123) { //a-z chosen = ch - 97; } else if (ch == '\n') { chosen = select; } if (chosen < available.size()) { if (player_can_build(g->u, total_inv, available[chosen])) { place_construction(available[chosen]); exit = true; } else { popup(_("You can't build that!")); select = chosen; for (int i = 1; i < iMaxY - 1; i++) { mvwputch(w_con, i, 30, c_ltgray, LINE_XOXO); } update_info = true; } } break; } } while (!exit); for (int i = iMaxY - FULL_SCREEN_HEIGHT; i <= iMaxY; ++i) { for (int j = TERRAIN_WINDOW_WIDTH; j <= FULL_SCREEN_WIDTH; ++j) { mvwputch(w_con, i, j, c_black, ' '); } } wrefresh(w_con); g->refresh_all(); }
static package bf_http_request( Var arglist, Byte next, void *vdata, Objid progr) { CURL *curl_handle; CURLcode ok; package result; if (!is_wizard(progr)) { free_var(arglist); return make_error_pack(E_PERM); } int nargs = arglist.v.list[0].v.num; const char *address = arglist.v.list[1].v.str; const char *agent="",*postfields="",*cookies=""; int headers = 0; switch(nargs) { case 5: cookies = arglist.v.list[5].v.str; case 4: postfields = arglist.v.list[4].v.str; case 3: agent = arglist.v.list[3].v.str; case 2: headers = arglist.v.list[2].v.num; } if(!strlen(agent)) agent = "MOO-http/1.0"; const char delimiters[] = "\n"; free_var(arglist); struct MemoryStruct chunk; chunk.memory = malloc(1); chunk.size = 0; curl_global_init(CURL_GLOBAL_ALL); curl_handle = curl_easy_init(); curl_easy_setopt(curl_handle, CURLOPT_URL, address); curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, agent); curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, 5); curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT, 3); curl_easy_setopt(curl_handle, CURLOPT_FTP_RESPONSE_TIMEOUT, 3); curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 5); curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl_handle, CURLOPT_MAXFILESIZE, 1048576); if(strlen(postfields)) curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, postfields); if(strlen(cookies)) curl_easy_setopt(curl_handle, CURLOPT_COOKIE, cookies); if(headers) curl_easy_setopt(curl_handle, CURLOPT_HEADER, 1); ok = curl_easy_perform(curl_handle); curl_easy_cleanup(curl_handle); if(ok == CURLE_OK && strlen(chunk.memory) != chunk.size) ok = CURLE_BAD_CONTENT_ENCODING; // binary !!! if(ok == CURLE_OK) { char *token,*p=chunk.memory; Var r; r.type = TYPE_LIST; r = new_list(0); token = strsep(&p, delimiters); while( token != NULL ) { Var line; line.type = TYPE_STR; if(token[strlen(token)-1] == '\r') token[strlen(token)-1] = '\0'; //run it through utf8_substr to get rid of invalid utf8 line.v.str = (char *)utf8_substr(token,1,utf8_strlen(token)); r = listappend(r, var_dup(line)); token = strsep(&p, delimiters); free_var(line); } result = make_var_pack(r); } else { Var r; r.type = TYPE_INT; r.v.num = ok; result = make_raise_pack(E_INVARG, curl_easy_strerror(ok), r); } if(chunk.memory) free(chunk.memory); curl_global_cleanup(); return result; }
std::string CmdCalendar::renderMonths ( int firstMonth, int firstYear, const Date& today, std::vector <Task>& all, int monthsPerLine) { // What day of the week does the user consider the first? int weekStart = Date::dayOfWeek (context.config.get ("weekstart")); if (weekStart != 0 && weekStart != 1) throw std::string (STRING_CMD_CAL_SUN_MON); // Build table for the number of months to be displayed. Color label (context.config.get ("color.label")); ViewText view; view.colorHeader (label); view.width (context.getWidth ()); for (int i = 0 ; i < (monthsPerLine * 8); i += 8) { if (weekStart == 1) { view.add (Column::factory ("string.right", " ")); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (1), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (2), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (3), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (4), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (5), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (6), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (0), 0, 2))); } else { view.add (Column::factory ("string.right", " ")); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (0), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (1), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (2), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (3), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (4), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (5), 0, 2))); view.add (Column::factory ("string.right", utf8_substr (Date::dayName (6), 0, 2))); } } // At most, we need 6 rows. view.addRow (); view.addRow (); view.addRow (); view.addRow (); view.addRow (); view.addRow (); // Set number of days per month, months to render, and years to render. std::vector<int> years; std::vector<int> months; std::vector<int> daysInMonth; int thisYear = firstYear; int thisMonth = firstMonth; for (int i = 0 ; i < monthsPerLine ; i++) { if (thisMonth < 13) { years.push_back (thisYear); } else { thisMonth -= 12; years.push_back (++thisYear); } months.push_back (thisMonth); daysInMonth.push_back (Date::daysInMonth (thisMonth++, thisYear)); } int row = 0; Color color_today (context.config.get ("color.calendar.today")); Color color_due (context.config.get ("color.calendar.due")); Color color_duetoday (context.config.get ("color.calendar.due.today")); Color color_overdue (context.config.get ("color.calendar.overdue")); Color color_weekend (context.config.get ("color.calendar.weekend")); Color color_holiday (context.config.get ("color.calendar.holiday")); Color color_weeknumber (context.config.get ("color.calendar.weeknumber")); // Loop through months to be added on this line. for (int mpl = 0; mpl < monthsPerLine ; mpl++) { // Reset row counter for subsequent months if (mpl != 0) row = 0; // Loop through days in month and add to table. for (int d = 1; d <= daysInMonth[mpl]; ++d) { Date temp (months[mpl], d, years[mpl]); int dow = temp.dayOfWeek (); int woy = temp.weekOfYear (weekStart); if (context.config.getBoolean ("displayweeknumber")) view.set (row, (8 * mpl), woy, color_weeknumber); // Calculate column id. int thisCol = dow + // 0 = Sunday (weekStart == 1 ? 0 : 1) + // Offset for weekStart (8 * mpl); // Columns in 1 month if (thisCol == (8 * mpl)) thisCol += 7; view.set (row, thisCol, d); if (context.color ()) { Color cellColor; // colorize weekends if (dow == 0 || dow == 6) cellColor.blend (color_weekend); // colorize holidays if (context.config.get ("calendar.holidays") != "none") { Config::const_iterator hol; for (hol = context.config.begin (); hol != context.config.end (); ++hol) if (hol->first.substr (0, 8) == "holiday.") if (hol->first.substr (hol->first.size () - 4) == "date") { std::string value = hol->second; Date holDate (value.c_str (), context.config.get ("dateformat.holiday")); if (holDate.day () == d && holDate.month () == months[mpl] && holDate.year () == years[mpl]) cellColor.blend (color_holiday); } } // colorize today if (today.day () == d && today.month () == months.at (mpl) && today.year () == years.at (mpl)) cellColor.blend (color_today); // colorize due tasks if (context.config.get ("calendar.details") != "none") { context.config.set ("due", 0); std::vector <Task>::iterator task; for (task = all.begin (); task != all.end (); ++task) { if (task->getStatus () == Task::pending && !task->hasTag ("nocal") && task->has ("due")) { std::string due = task->get ("due"); Date duedmy (strtol (due.c_str(), NULL, 10)); if (duedmy.day () == d && duedmy.month () == months[mpl] && duedmy.year () == years[mpl]) { switch (task->getDateState ("due")) { case Task::dateNotDue: break; case Task::dateAfterToday: cellColor.blend (color_due); break; case Task::dateEarlierToday: case Task::dateLaterToday: cellColor.blend (color_duetoday); cellColor.blend (color_duetoday); break; case Task::dateBeforeToday: cellColor.blend (color_overdue); break; } } } } } view.set (row, thisCol, cellColor); } // Check for end of week, and... int eow = 6; if (weekStart == 1) eow = 0; if (dow == eow && d < daysInMonth[mpl]) row++; } } return view.render (); }