Esempio n. 1
0
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();
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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 ();
}