Beispiel #1
0
int fold_and_print_from(WINDOW *w, int begin_y, int begin_x, int width, int begin_line,
                        nc_color base_color, const std::string &text)
{
    nc_color color = base_color;
    std::vector<std::string> textformatted;
    textformatted = foldstring(text, width);
    for (int line_num = 0; line_num < textformatted.size(); line_num++) {
        if (line_num >= begin_line) {
            wmove(w, line_num + begin_y - begin_line, begin_x);
        }
        // split into colourable sections
        std::vector<std::string> color_segments = split_by_color(textformatted[line_num]);
        // for each section, get the colour, and print it
        std::vector<std::string>::iterator it;
        for (it = color_segments.begin(); it != color_segments.end(); ++it) {
            if (!it->empty() && it->at(0) == '<') {
                color = get_color_from_tag(*it, base_color);
            }
            if (line_num >= begin_line) {
                std::string l = rm_prefix(*it);
                if(l != "--") { // -- is a newline!
                    wprintz(w, color, "%s", rm_prefix(*it).c_str());
                }
            }
        }
    }
    return textformatted.size();
};
Beispiel #2
0
// returns number of printed lines
int fold_and_print(WINDOW* w, int begin_y, int begin_x, int width, nc_color base_color, const char *mes, ...)
{
    va_list ap;
    va_start(ap,mes);
    char buff[6000];    //TODO replace Magic Number
    vsprintf(buff, mes, ap);
    va_end(ap);

    nc_color color = base_color;
    std::vector<std::string> textformatted;
    textformatted = foldstring(buff, width);
    for (int line_num=0; line_num<textformatted.size(); line_num++)
    {
        wmove(w, line_num+begin_y, begin_x);
        // split into colourable sections
        std::vector<std::string> color_segments = split_by_color(textformatted[line_num]);
        // for each section, get the colour, and print it
        std::vector<std::string>::iterator it;
        for (it = color_segments.begin(); it != color_segments.end(); ++it) {
            if (!it->empty() && it->at(0) == '<') {
                color = get_color_from_tag(*it, base_color);
            }
            wprintz(w, color, "%s", rm_prefix(*it).c_str());
        }
    }
    return textformatted.size();
};
Beispiel #3
0
std::string invent_name()
{
 std::string ret = "";
 std::string tmp;
 int syllables = rng(2, 3);
 for (int i = 0; i < syllables; i++) {
  switch (rng(0, 25)) {
   case  0: tmp = _("<fac_name>ab");  break;
   case  1: tmp = _("<fac_name>bon"); break;
   case  2: tmp = _("<fac_name>cor"); break;
   case  3: tmp = _("<fac_name>den"); break;
   case  4: tmp = _("<fac_name>el");  break;
   case  5: tmp = _("<fac_name>fes"); break;
   case  6: tmp = _("<fac_name>gun"); break;
   case  7: tmp = _("<fac_name>hit"); break;
   case  8: tmp = _("<fac_name>id");  break;
   case  9: tmp = _("<fac_name>jan"); break;
   case 10: tmp = _("<fac_name>kal"); break;
   case 11: tmp = _("<fac_name>ler"); break;
   case 12: tmp = _("<fac_name>mal"); break;
   case 13: tmp = _("<fac_name>nor"); break;
   case 14: tmp = _("<fac_name>or");  break;
   case 15: tmp = _("<fac_name>pan"); break;
   case 16: tmp = _("<fac_name>qua"); break;
   case 17: tmp = _("<fac_name>ros"); break;
   case 18: tmp = _("<fac_name>sin"); break;
   case 19: tmp = _("<fac_name>tor"); break;
   case 20: tmp = _("<fac_name>urr"); break;
   case 21: tmp = _("<fac_name>ven"); break;
   case 22: tmp = _("<fac_name>wel"); break;
   case 23: tmp = _("<fac_name>oxo");  break;
   case 24: tmp = _("<fac_name>yen"); break;
   case 25: tmp = _("<fac_name>zu");  break;
  }
  ret += rm_prefix(tmp);
 }

 return capitalize_letter(ret);
}
void show_auto_pickup()
{
    save_reset_changes(false);

    const int iHeaderHeight = 4;
    const int iContentHeight = FULL_SCREEN_HEIGHT-2-iHeaderHeight;

    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;
    mapLines[50] = true;
    mapLines[54] = true;

    const int iTotalCols = mapLines.size()-1;

    WINDOW* w_auto_pickup_options = newwin(FULL_SCREEN_HEIGHT/2, FULL_SCREEN_WIDTH/2, iOffsetY + (FULL_SCREEN_HEIGHT/2)/2, iOffsetX + (FULL_SCREEN_WIDTH/2)/2);
    WINDOW* w_auto_pickup_help = newwin((FULL_SCREEN_HEIGHT/2)-2, FULL_SCREEN_WIDTH * 3/4, 8 + iOffsetY + (FULL_SCREEN_HEIGHT/2)/2, iOffsetX + 19/2);

    WINDOW* w_auto_pickup_border = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);
    WINDOW* w_auto_pickup_header = newwin(iHeaderHeight, FULL_SCREEN_WIDTH - 2, 1 + iOffsetY, 1 + iOffsetX);
    WINDOW* w_auto_pickup = newwin(iContentHeight, FULL_SCREEN_WIDTH - 2, iHeaderHeight + 1 + iOffsetY, 1 + iOffsetX);

    wborder(w_auto_pickup_border, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX);
    mvwputch(w_auto_pickup_border, 3,  0, c_ltgray, LINE_XXXO); // |-
    mvwputch(w_auto_pickup_border, 3, 79, c_ltgray, LINE_XOXX); // -|

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

    mvwprintz(w_auto_pickup_border, 0, 29, c_ltred, _(" AUTO PICKUP MANAGER "));
    wrefresh(w_auto_pickup_border);

    int tmpx = 0;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<A>dd"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<R>emove"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<C>opy"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<M>ove"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<E>nable"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<D>isable"))+2;
    shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<T>est"));
    tmpx = 0;
    tmpx += shortcut_print(w_auto_pickup_header, 1, tmpx, c_white, c_ltgreen, _("<+-> Move up/down"))+2;
    tmpx += shortcut_print(w_auto_pickup_header, 1, tmpx, c_white, c_ltgreen, _("<Enter>-Edit"))+2;
    shortcut_print(w_auto_pickup_header, 1, tmpx, c_white, c_ltgreen, _("<Tab>-Switch Page"));

    for (int i = 0; i < 78; i++) {
        if (mapLines[i]) {
            mvwputch(w_auto_pickup_header, 2, i, c_ltgray, LINE_OXXX);
            mvwputch(w_auto_pickup_header, 3, i, c_ltgray, LINE_XOXO);
        } else {
            mvwputch(w_auto_pickup_header, 2, i, c_ltgray, LINE_OXOX); // Draw line under header
        }
    }

    mvwprintz(w_auto_pickup_header, 3, 0, c_white, "#");
    mvwprintz(w_auto_pickup_header, 3, 7, c_white, _("Rules"));
    mvwprintz(w_auto_pickup_header, 3, 51, c_white, _("I/E"));

    wrefresh(w_auto_pickup_header);

    int iCurrentPage = 1;
    int iCurrentLine = 0;
    int iCurrentCol = 1;
    int iStartPos = 0;
    bool bStuffChanged = false;
    char ch = ' ';

    std::stringstream sTemp;

    do {
        int locx = 17;
        locx += shortcut_print(w_auto_pickup_header, 2, locx, c_white, (iCurrentPage == 1) ? hilite(c_white) : c_white, _("[<Global>]"))+1;
        shortcut_print(w_auto_pickup_header, 2, locx, c_white, (iCurrentPage == 2) ? hilite(c_white) : c_white, _("[<Character>]"));

        wrefresh(w_auto_pickup_header);

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

        if (iCurrentPage == 1 || iCurrentPage == 2) {
            if (iCurrentPage == 2 && g->u.name == "") {
                vAutoPickupRules[2].clear();
                mvwprintz(w_auto_pickup, 8, 15, c_white, _("Please load a character first to use this page!"));
            }

            //Draw Scrollbar
            draw_scrollbar(w_auto_pickup_border, iCurrentLine, iContentHeight, vAutoPickupRules[iCurrentPage].size(), 5);

            calcStartPos(iStartPos, iCurrentLine, iContentHeight, vAutoPickupRules[iCurrentPage].size());

            // display auto pickup
            for (int i = iStartPos; i < vAutoPickupRules[iCurrentPage].size(); i++) {
                if (i >= iStartPos && i < iStartPos + ((iContentHeight > vAutoPickupRules[iCurrentPage].size()) ? vAutoPickupRules[iCurrentPage].size() : iContentHeight)) {
                    nc_color cLineColor = (vAutoPickupRules[iCurrentPage][i].bActive) ? c_white : c_ltgray;

                    sTemp.str("");
                    sTemp << i + 1;
                    mvwprintz(w_auto_pickup, i - iStartPos, 0, cLineColor, sTemp.str().c_str());
                    mvwprintz(w_auto_pickup, i - iStartPos, 4, cLineColor, "");

                    if (iCurrentLine == i) {
                        wprintz(w_auto_pickup, c_yellow, ">> ");
                    } else {
                        wprintz(w_auto_pickup, c_yellow, "   ");
                    }

                    wprintz(w_auto_pickup, (iCurrentLine == i && iCurrentCol == 1) ? hilite(cLineColor) : cLineColor, "%s", ((vAutoPickupRules[iCurrentPage][i].sRule == "") ? _("<empty rule>") : vAutoPickupRules[iCurrentPage][i].sRule).c_str());

                    mvwprintz(w_auto_pickup, i - iStartPos, 52, (iCurrentLine == i && iCurrentCol == 2) ? hilite(cLineColor) : cLineColor, "%s", ((vAutoPickupRules[iCurrentPage][i].bExclude) ? rm_prefix(_("<Exclude>E")).c_str() : rm_prefix(_("<Include>I")).c_str()));
                }
            }

            wrefresh(w_auto_pickup);

        } else if (iCurrentPage == 3) {
            wborder(w_auto_pickup_options, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX);

            mvwprintz(w_auto_pickup_options, 5, 10, c_white, _("Under construction!"));

            wrefresh(w_auto_pickup);
            wrefresh(w_auto_pickup_options);
        }

        ch = (char)input();

        if (iCurrentPage == 3) {
            switch(ch) {
                case '\t': //Switch to next Page
                    iCurrentPage++;
                    if (iCurrentPage > 3) {
                        iCurrentPage = 1;
                        iCurrentLine = 0;
                    }
                    break;
            }
        } else if (iCurrentPage == 1 || iCurrentPage == 2) {
            if (iCurrentPage == 2 && g->u.name == "" && ch != '\t') {
                //Only allow loaded games to use the char sheet
            } else if (vAutoPickupRules[iCurrentPage].size() > 0 || ch == 'a' || ch == '\t') {
                switch(ch) {
                    case 'j': //move down
                        iCurrentLine++;
                        iCurrentCol = 1;
                        if (iCurrentLine >= vAutoPickupRules[iCurrentPage].size()) {
                            iCurrentLine = 0;
                        }
                        break;
                    case 'k': //move up
                        iCurrentLine--;
                        iCurrentCol = 1;
                        if (iCurrentLine < 0) {
                            iCurrentLine = vAutoPickupRules[iCurrentPage].size()-1;
                        }
                        break;
                    case 'a': //add new rule
                    case 'A':
                        bStuffChanged = true;
                        vAutoPickupRules[iCurrentPage].push_back(cPickupRules("", true, false));
                        iCurrentLine = vAutoPickupRules[iCurrentPage].size()-1;
                        break;
                    case 'r': //remove rule
                    case 'R':
                        bStuffChanged = true;
                        vAutoPickupRules[iCurrentPage].erase(vAutoPickupRules[iCurrentPage].begin() + iCurrentLine);
                        if (iCurrentLine > vAutoPickupRules[iCurrentPage].size()-1) {
                            iCurrentLine--;
                        }
                        break;
                    case 'c': //copy rule
                    case 'C':
                        bStuffChanged = true;
                        vAutoPickupRules[iCurrentPage].push_back(cPickupRules(vAutoPickupRules[iCurrentPage][iCurrentLine].sRule, vAutoPickupRules[iCurrentPage][iCurrentLine].bActive, vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude));
                        iCurrentLine = vAutoPickupRules[iCurrentPage].size()-1;
                        break;
                    case 'm': //move rule global <-> character
                    case 'M':
                        if ((iCurrentPage == 1 && g->u.name != "") || iCurrentPage == 2) {
                            bStuffChanged = true;
                            //copy over
                            vAutoPickupRules[(iCurrentPage == 1) ? 2 : 1].push_back(cPickupRules(vAutoPickupRules[iCurrentPage][iCurrentLine].sRule, vAutoPickupRules[iCurrentPage][iCurrentLine].bActive, vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude));

                            //remove old
                            vAutoPickupRules[iCurrentPage].erase(vAutoPickupRules[iCurrentPage].begin() + iCurrentLine);
                            iCurrentLine = vAutoPickupRules[(iCurrentPage == 1) ? 2 : 1].size()-1;
                            iCurrentPage = (iCurrentPage == 1) ? 2 : 1;
                        }
                        break;
                    case '\t': //Switch to next Page
                        iCurrentPage++;
                        if (iCurrentPage > 2) {
                            iCurrentPage = 1;
                            iCurrentLine = 0;
                        }
                        break;
                    case '\n': //Edit Col in current line
                        bStuffChanged = true;
                        if (iCurrentCol == 1) {
                            fold_and_print(w_auto_pickup_help, 1, 1, 999, c_white,
                                _(
                                "* is used as a Wildcard. A few Examples:\n"
                                "\n"
                                "wood arrow    matches the itemname exactly\n"
                                "wood ar*      matches items beginning with wood ar\n"
                                "*rrow         matches items ending with rrow\n"
                                "*avy fle*fi*arrow     multible * are allowed\n"
                                "heAVY*woOD*arrOW      case insesitive search\n"
                                "")
                            );

                            wborder(w_auto_pickup_help, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX, LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX);
                            wrefresh(w_auto_pickup_help);
                            vAutoPickupRules[iCurrentPage][iCurrentLine].sRule = trim_rule(string_input_popup(_("Pickup Rule:"), 30, vAutoPickupRules[iCurrentPage][iCurrentLine].sRule));
                        } else if (iCurrentCol == 2) {
                            vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude = !vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude;
                        }
                        break;
                    case 'e': //enable rule
                    case 'E':
                        bStuffChanged = true;
                        vAutoPickupRules[iCurrentPage][iCurrentLine].bActive = true;
                        break;
                    case 'd': //disable rule
                    case 'D':
                        bStuffChanged = true;
                        vAutoPickupRules[iCurrentPage][iCurrentLine].bActive = false;
                        break;
                    case 'h': //move left
                        iCurrentCol--;
                        if (iCurrentCol < 1) {
                            iCurrentCol = iTotalCols;
                        }
                        break;
                    case 'l': //move right
                        iCurrentCol++;
                        if (iCurrentCol > iTotalCols) {
                            iCurrentCol = 1;
                        }
                        break;
                    case '+': //move rule up
                        bStuffChanged = true;
                        if (iCurrentLine < vAutoPickupRules[iCurrentPage].size()-1) {
                            std::swap(vAutoPickupRules[iCurrentPage][iCurrentLine], vAutoPickupRules[iCurrentPage][iCurrentLine+1]);
                            iCurrentLine++;
                            iCurrentCol = 1;
                        }
                        break;
                    case '-': //move rule down
                        bStuffChanged = true;
                        if (iCurrentLine > 0) {
                            std::swap(vAutoPickupRules[iCurrentPage][iCurrentLine], vAutoPickupRules[iCurrentPage][iCurrentLine-1]);
                            iCurrentLine--;
                            iCurrentCol = 1;
                        }
                        break;
                    case 't': //test rule
                    case 'T':
                        test_pattern(iCurrentPage, iCurrentLine);
                        break;
                }
            }
        }
    } while(ch != 'q' && ch != 'Q' && ch != KEY_ESCAPE);

    if (bStuffChanged) {
        if(query_yn(_("Save changes?"))) {
            save_auto_pickup(false);

            if (g->u.name != "") {
                save_auto_pickup(true);
            }
        } else {
            save_reset_changes(true);
        }
    }

    werase(w_auto_pickup);
    werase(w_auto_pickup_border);
    werase(w_auto_pickup_header);
    werase(w_auto_pickup_options);
    werase(w_auto_pickup_help);
}
std::string invent_adj()
{
    int syllables = dice(2, 2) - 1;
    std::string ret,  tmp;
    switch (rng(0, 25)) {
    case  0:
        ret = _("<fac_adj>Ald");
        break;
    case  1:
        ret = _("<fac_adj>Brogg");
        break;
    case  2:
        ret = _("<fac_adj>Cald");
        break;
    case  3:
        ret = _("<fac_adj>Dredd");
        break;
    case  4:
        ret = _("<fac_adj>Eld");
        break;
    case  5:
        ret = _("<fac_adj>Forr");
        break;
    case  6:
        ret = _("<fac_adj>Gugg");
        break;
    case  7:
        ret = _("<fac_adj>Horr");
        break;
    case  8:
        ret = _("<fac_adj>Ill");
        break;
    case  9:
        ret = _("<fac_adj>Jov");
        break;
    case 10:
        ret = _("<fac_adj>Kok");
        break;
    case 11:
        ret = _("<fac_adj>Lill");
        break;
    case 12:
        ret = _("<fac_adj>Moom");
        break;
    case 13:
        ret = _("<fac_adj>Nov");
        break;
    case 14:
        ret = _("<fac_adj>Orb");
        break;
    case 15:
        ret = _("<fac_adj>Perv");
        break;
    case 16:
        ret = _("<fac_adj>Quot");
        break;
    case 17:
        ret = _("<fac_adj>Rar");
        break;
    case 18:
        ret = _("<fac_adj>Suss");
        break;
    case 19:
        ret = _("<fac_adj>Torr");
        break;
    case 20:
        ret = _("<fac_adj>Umbr");
        break;
    case 21:
        ret = _("<fac_adj>Viv");
        break;
    case 22:
        ret = _("<fac_adj>Warr");
        break;
    case 23:
        ret = _("<fac_adj>Xen");
        break;
    case 24:
        ret = _("<fac_adj>Yend");
        break;
    case 25:
        ret = _("<fac_adj>Zor");
        break;
    }
    ret = rm_prefix(ret);
    for (int i = 0; i < syllables - 2; i++) {
        switch (rng(0, 17)) {
        case  0:
            tmp = _("<fac_adj>al");
            break;
        case  1:
            tmp = _("<fac_adj>arn");
            break;
        case  2:
            tmp = _("<fac_adj>astr");
            break;
        case  3:
            tmp = _("<fac_adj>antr");
            break;
        case  4:
            tmp = _("<fac_adj>ent");
            break;
        case  5:
            tmp = _("<fac_adj>ell");
            break;
        case  6:
            tmp = _("<fac_adj>ev");
            break;
        case  7:
            tmp = _("<fac_adj>emm");
            break;
        case  8:
            tmp = _("<fac_adj>empr");
            break;
        case  9:
            tmp = _("<fac_adj>ill");
            break;
        case 10:
            tmp = _("<fac_adj>ial");
            break;
        case 11:
            tmp = _("<fac_adj>ior");
            break;
        case 12:
            tmp = _("<fac_adj>ordr");
            break;
        case 13:
            tmp = _("<fac_adj>oth");
            break;
        case 14:
            tmp = _("<fac_adj>omn");
            break;
        case 15:
            tmp = _("<fac_adj>uv");
            break;
        case 16:
            tmp = _("<fac_adj>ulv");
            break;
        case 17:
            tmp = _("<fac_adj>urn");
            break;
        }
        ret += rm_prefix(tmp);
    }
    switch (rng(0, 24)) {
    case  0:
        tmp = "";
        break;
    case  1:
        tmp = _("<fac_adj>al");
        break;
    case  2:
        tmp = _("<fac_adj>an");
        break;
    case  3:
        tmp = _("<fac_adj>ard");
        break;
    case  4:
        tmp = _("<fac_adj>ate");
        break;
    case  5:
        tmp = _("<fac_adj>e");
        break;
    case  6:
        tmp = _("<fac_adj>ed");
        break;
    case  7:
        tmp = _("<fac_adj>en");
        break;
    case  8:
        tmp = _("<fac_adj>er");
        break;
    case  9:
        tmp = _("<fac_adj>ial");
        break;
    case 10:
        tmp = _("<fac_adj>ian");
        break;
    case 11:
        tmp = _("<fac_adj>iated");
        break;
    case 12:
        tmp = _("<fac_adj>ier");
        break;
    case 13:
        tmp = _("<fac_adj>ious");
        break;
    case 14:
        tmp = _("<fac_adj>ish");
        break;
    case 15:
        tmp = _("<fac_adj>ive");
        break;
    case 16:
        tmp = _("<fac_adj>oo");
        break;
    case 17:
        tmp = _("<fac_adj>or");
        break;
    case 18:
        tmp = _("<fac_adj>oth");
        break;
    case 19:
        tmp = _("<fac_adj>old");
        break;
    case 20:
        tmp = _("<fac_adj>ous");
        break;
    case 21:
        tmp = _("<fac_adj>ul");
        break;
    case 22:
        tmp = _("<fac_adj>un");
        break;
    case 23:
        tmp = _("<fac_adj>ule");
        break;
    case 24:
        tmp = _("<fac_adj>y");
        break;
    }
    ret += rm_prefix(tmp);
    return ret;
}
void show_auto_pickup()
{
    save_reset_changes(false);

    const int iHeaderHeight = 4;
    const int iContentHeight = FULL_SCREEN_HEIGHT - 2 - iHeaderHeight;

    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[4] = true;
    mapLines[50] = true;
    mapLines[54] = true;

    const int iTotalCols = mapLines.size() - 1;

    WINDOW *w_auto_pickup_help = newwin((FULL_SCREEN_HEIGHT / 2) - 2, FULL_SCREEN_WIDTH * 3 / 4,
                                        7 + iOffsetY + (FULL_SCREEN_HEIGHT / 2) / 2, iOffsetX + 19 / 2);
    WINDOW_PTR w_auto_pickup_helpptr( w_auto_pickup_help );

    WINDOW *w_auto_pickup_border = newwin(FULL_SCREEN_HEIGHT, FULL_SCREEN_WIDTH, iOffsetY, iOffsetX);
    WINDOW_PTR w_auto_pickup_borderptr( w_auto_pickup_border );
    WINDOW *w_auto_pickup_header = newwin(iHeaderHeight, FULL_SCREEN_WIDTH - 2, 1 + iOffsetY,
                                          1 + iOffsetX);
    WINDOW_PTR w_auto_pickup_headerptr( w_auto_pickup_header );
    WINDOW *w_auto_pickup = newwin(iContentHeight, FULL_SCREEN_WIDTH - 2, iHeaderHeight + 1 + iOffsetY,
                                   1 + iOffsetX);
    WINDOW_PTR w_auto_pickupptr( w_auto_pickup );

    draw_border(w_auto_pickup_border);
    mvwputch(w_auto_pickup_border, 3,  0, c_ltgray, LINE_XXXO); // |-
    mvwputch(w_auto_pickup_border, 3, 79, c_ltgray, LINE_XOXX); // -|

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

    mvwprintz(w_auto_pickup_border, 0, 29, c_ltred, _(" AUTO PICKUP MANAGER "));
    wrefresh(w_auto_pickup_border);

    int tmpx = 0;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<A>dd")) + 2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<R>emove")) + 2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<C>opy")) + 2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<M>ove")) + 2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<E>nable")) + 2;
    tmpx += shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<D>isable")) + 2;
    shortcut_print(w_auto_pickup_header, 0, tmpx, c_white, c_ltgreen, _("<T>est"));
    tmpx = 0;
    tmpx += shortcut_print(w_auto_pickup_header, 1, tmpx, c_white, c_ltgreen,
                           _("<+-> Move up/down")) + 2;
    tmpx += shortcut_print(w_auto_pickup_header, 1, tmpx, c_white, c_ltgreen, _("<Enter>-Edit")) + 2;
    shortcut_print(w_auto_pickup_header, 1, tmpx, c_white, c_ltgreen, _("<Tab>-Switch Page"));

    for (int i = 0; i < 78; i++) {
        if (mapLines[i]) {
            mvwputch(w_auto_pickup_header, 2, i, c_ltgray, LINE_OXXX);
            mvwputch(w_auto_pickup_header, 3, i, c_ltgray, LINE_XOXO);
        } else {
            mvwputch(w_auto_pickup_header, 2, i, c_ltgray, LINE_OXOX); // Draw line under header
        }
    }

    mvwprintz(w_auto_pickup_header, 3, 1, c_white, "#");
    mvwprintz(w_auto_pickup_header, 3, 8, c_white, _("Rules"));
    mvwprintz(w_auto_pickup_header, 3, 51, c_white, _("I/E"));

    wrefresh(w_auto_pickup_header);

    int iCurrentPage = 1;
    int iCurrentLine = 0;
    int iCurrentCol = 1;
    int iStartPos = 0;
    bool bStuffChanged = false;
    input_context ctxt("AUTO_PICKUP");
    ctxt.register_cardinal();
    ctxt.register_action("CONFIRM");
    ctxt.register_action("QUIT");
    ctxt.register_action("NEXT_TAB");
    ctxt.register_action("PREV_TAB");
    ctxt.register_action("ADD_RULE");
    ctxt.register_action("REMOVE_RULE");
    ctxt.register_action("COPY_RULE");
    ctxt.register_action("SWAP_RULE_GLOBAL_CHAR");
    ctxt.register_action("ENABLE_RULE");
    ctxt.register_action("DISABLE_RULE");
    ctxt.register_action("MOVE_RULE_UP");
    ctxt.register_action("MOVE_RULE_DOWN");
    ctxt.register_action("TEST_RULE");
    ctxt.register_action("SWITCH_AUTO_PICKUP_OPTION");
    ctxt.register_action("HELP_KEYBINDINGS");

    std::stringstream sTemp;

    while(true) {
        int locx = 17;
        locx += shortcut_print(w_auto_pickup_header, 2, locx, c_white,
                               (iCurrentPage == 1) ? hilite(c_white) : c_white, _("[<Global>]")) + 1;
        shortcut_print(w_auto_pickup_header, 2, locx, c_white,
                       (iCurrentPage == 2) ? hilite(c_white) : c_white, _("[<Character>]"));

        locx = 55;
        mvwprintz(w_auto_pickup_header, 0, locx, c_white, _("Auto pickup enabled:"));
        locx += shortcut_print(w_auto_pickup_header, 1, locx,
                               ((OPTIONS["AUTO_PICKUP"]) ? c_ltgreen : c_ltred), c_white,
                               ((OPTIONS["AUTO_PICKUP"]) ? _("True") : _("False")));
        locx += shortcut_print(w_auto_pickup_header, 1, locx, c_white, c_ltgreen, "  ");
        locx += shortcut_print(w_auto_pickup_header, 1, locx, c_white, c_ltgreen, _("<S>witch"));
        shortcut_print(w_auto_pickup_header, 1, locx, c_white, c_ltgreen, "  ");

        wrefresh(w_auto_pickup_header);

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

        const bool currentPageNonEmpty = !vAutoPickupRules[iCurrentPage].empty();

        if (iCurrentPage == 2 && g->u.name == "") {
            vAutoPickupRules[2].clear();
            mvwprintz(w_auto_pickup, 8, 15, c_white,
                      _("Please load a character first to use this page!"));
        }

        //Draw Scrollbar
        draw_scrollbar(w_auto_pickup_border, iCurrentLine, iContentHeight,
                       vAutoPickupRules[iCurrentPage].size(), 5);

        calcStartPos(iStartPos, iCurrentLine, iContentHeight,
                     vAutoPickupRules[iCurrentPage].size());

        // display auto pickup
        for (int i = iStartPos; i < (int)vAutoPickupRules[iCurrentPage].size(); i++) {
            if (i >= iStartPos &&
                i < iStartPos + ((iContentHeight > (int)vAutoPickupRules[iCurrentPage].size()) ?
                                 (int)vAutoPickupRules[iCurrentPage].size() : iContentHeight)) {
                nc_color cLineColor = (vAutoPickupRules[iCurrentPage][i].bActive) ?
                                      c_white : c_ltgray;

                sTemp.str("");
                sTemp << i + 1;
                mvwprintz(w_auto_pickup, i - iStartPos, 1, cLineColor, "%s", sTemp.str().c_str());
                mvwprintz(w_auto_pickup, i - iStartPos, 5, cLineColor, "");

                if (iCurrentLine == i) {
                    wprintz(w_auto_pickup, c_yellow, ">> ");
                } else {
                    wprintz(w_auto_pickup, c_yellow, "   ");
                }

                wprintz(w_auto_pickup, (iCurrentLine == i &&
                                        iCurrentCol == 1) ? hilite(cLineColor) : cLineColor, "%s",
                        ((vAutoPickupRules[iCurrentPage][i].sRule == "") ? _("<empty rule>") :
                         vAutoPickupRules[iCurrentPage][i].sRule).c_str());

                mvwprintz(w_auto_pickup, i - iStartPos, 52, (iCurrentLine == i &&
                          iCurrentCol == 2) ? hilite(cLineColor) : cLineColor, "%s",
                          ((vAutoPickupRules[iCurrentPage][i].bExclude) ? rm_prefix(_("<Exclude>E")).c_str() : rm_prefix(
                               _("<Include>I")).c_str()));
            }
        }

        wrefresh(w_auto_pickup);

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

        if (action == "NEXT_TAB") {
            iCurrentPage++;
            if (iCurrentPage > 2) {
                iCurrentPage = 1;
                iCurrentLine = 0;
            }
        } else if (action == "PREV_TAB") {
            iCurrentPage--;
            if (iCurrentPage < 1) {
                iCurrentPage = 2;
                iCurrentLine = 0;
            }
        } else if (action == "QUIT") {
            break;
        } else if (iCurrentPage == 2 && g->u.name.empty()) {
            //Only allow loaded games to use the char sheet
        } else if (action == "DOWN") {
            iCurrentLine++;
            iCurrentCol = 1;
            if (iCurrentLine >= (int)vAutoPickupRules[iCurrentPage].size()) {
                iCurrentLine = 0;
            }
        } else if (action == "UP") {
            iCurrentLine--;
            iCurrentCol = 1;
            if (iCurrentLine < 0) {
                iCurrentLine = vAutoPickupRules[iCurrentPage].size() - 1;
            }
        } else if (action == "ADD_RULE") {
            bStuffChanged = true;
            vAutoPickupRules[iCurrentPage].push_back(cPickupRules("", true, false));
            iCurrentLine = vAutoPickupRules[iCurrentPage].size() - 1;
        } else if (action == "REMOVE_RULE" && currentPageNonEmpty) {
            bStuffChanged = true;
            vAutoPickupRules[iCurrentPage].erase(vAutoPickupRules[iCurrentPage].begin() + iCurrentLine);
            if (iCurrentLine > (int)vAutoPickupRules[iCurrentPage].size() - 1) {
                iCurrentLine--;
            }
            if(iCurrentLine < 0){
                iCurrentLine = 0;
            }
        } else if (action == "COPY_RULE" && currentPageNonEmpty) {
            bStuffChanged = true;
            vAutoPickupRules[iCurrentPage].push_back(cPickupRules(
                        vAutoPickupRules[iCurrentPage][iCurrentLine].sRule,
                        vAutoPickupRules[iCurrentPage][iCurrentLine].bActive,
                        vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude));
            iCurrentLine = vAutoPickupRules[iCurrentPage].size() - 1;
        } else if (action == "SWAP_RULE_GLOBAL_CHAR" && currentPageNonEmpty) {
            if ((iCurrentPage == 1 && g->u.name != "") || iCurrentPage == 2) {
                bStuffChanged = true;
                //copy over
                vAutoPickupRules[(iCurrentPage == 1) ? 2 : 1].push_back(cPickupRules(
                            vAutoPickupRules[iCurrentPage][iCurrentLine].sRule,
                            vAutoPickupRules[iCurrentPage][iCurrentLine].bActive,
                            vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude));

                //remove old
                vAutoPickupRules[iCurrentPage].erase(vAutoPickupRules[iCurrentPage].begin() + iCurrentLine);
                iCurrentLine = vAutoPickupRules[(iCurrentPage == 1) ? 2 : 1].size() - 1;
                iCurrentPage = (iCurrentPage == 1) ? 2 : 1;
            }
        } else if (action == "CONFIRM" && currentPageNonEmpty) {
            bStuffChanged = true;
            if (iCurrentCol == 1) {
                fold_and_print(w_auto_pickup_help, 1, 1, 999, c_white,
                               _(
                                   "* is used as a Wildcard. A few Examples:\n"
                                   "\n"
                                   "wooden arrow    matches the itemname exactly\n"
                                   "wooden ar*      matches items beginning with wood ar\n"
                                   "*rrow           matches items ending with rrow\n"
                                   "*avy fle*fi*arrow     multiple * are allowed\n"
                                   "heAVY*woOD*arrOW      case insensitive search\n"
                                   "")
                              );

                draw_border(w_auto_pickup_help);
                wrefresh(w_auto_pickup_help);
                vAutoPickupRules[iCurrentPage][iCurrentLine].sRule = trim_rule(string_input_popup(_("Pickup Rule:"),
                        30, vAutoPickupRules[iCurrentPage][iCurrentLine].sRule));
            } else if (iCurrentCol == 2) {
                vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude =
                    !vAutoPickupRules[iCurrentPage][iCurrentLine].bExclude;
            }
        } else if (action == "ENABLE_RULE" && currentPageNonEmpty) {
            bStuffChanged = true;
            vAutoPickupRules[iCurrentPage][iCurrentLine].bActive = true;
        } else if (action == "DISABLE_RULE" && currentPageNonEmpty) {
            bStuffChanged = true;
            vAutoPickupRules[iCurrentPage][iCurrentLine].bActive = false;
        } else if (action == "LEFT") {
            iCurrentCol--;
            if (iCurrentCol < 1) {
                iCurrentCol = iTotalCols;
            }
        } else if (action == "RIGHT") {
            iCurrentCol++;
            if (iCurrentCol > iTotalCols) {
                iCurrentCol = 1;
            }
        } else if (action == "MOVE_RULE_UP" && currentPageNonEmpty) {
            bStuffChanged = true;
            if (iCurrentLine < (int)vAutoPickupRules[iCurrentPage].size() - 1) {
                std::swap(vAutoPickupRules[iCurrentPage][iCurrentLine],
                          vAutoPickupRules[iCurrentPage][iCurrentLine + 1]);
                iCurrentLine++;
                iCurrentCol = 1;
            }
        } else if (action == "MOVE_RULE_DOWN" && currentPageNonEmpty) {
            bStuffChanged = true;
            if (iCurrentLine > 0) {
                std::swap(vAutoPickupRules[iCurrentPage][iCurrentLine],
                          vAutoPickupRules[iCurrentPage][iCurrentLine - 1]);
                iCurrentLine--;
                iCurrentCol = 1;
            }
        } else if (action == "TEST_RULE" && currentPageNonEmpty) {
            test_pattern(iCurrentPage, iCurrentLine);
        } else if (action == "SWITCH_AUTO_PICKUP_OPTION") {
            OPTIONS["AUTO_PICKUP"].setNext();
            save_options((g->u.name != ""));
        }
    }

    if (bStuffChanged) {
        if(query_yn(_("Save changes?"))) {
            save_auto_pickup(false);

            if (g->u.name != "") {
                save_auto_pickup(true);
            }
        } else {
            save_reset_changes(true);
        }
    }
}
void complete_vehicle (game *g)
{
    if (g->u.activity.values.size() < 7)
    {
        debugmsg ("Invalid activity ACT_VEHICLE values:%d", g->u.activity.values.size());
        return;
    }
    vehicle *veh = g->m.veh_at (g->u.activity.values[0], g->u.activity.values[1]);
    if (!veh)
    {
        debugmsg ("Activity ACT_VEHICLE: vehicle not found");
        return;
    }
    char cmd = (char) g->u.activity.index;
    int dx = g->u.activity.values[4];
    int dy = g->u.activity.values[5];
    int part = g->u.activity.values[6];
    int type = g->u.activity.values[7];
    std::vector<component> tools;
    int welder_charges = ((it_tool *) g->itypes["welder"])->charges_per_use;
    int welder_crude_charges = ((it_tool *) g->itypes["welder_crude"])->charges_per_use;
    itype_id itm;
    int partnum;
    item used_item;
    bool broken;
    int replaced_wheel;
    std::vector<int> parts;
    int dd = 2;
    switch (cmd)
    {
    case 'i':
        partnum = veh->install_part (dx, dy, (vpart_id) part);
        if(partnum < 0)
            debugmsg ("complete_vehicle install part fails dx=%d dy=%d id=%d", dx, dy, part);
        used_item = consume_vpart_item (g, (vpart_id) part);
        veh->get_part_properties_from_item(g, partnum, used_item); //transfer damage, etc.
        tools.push_back(component("welder", welder_charges));
        tools.push_back(component("welder_crude", welder_crude_charges));
        tools.push_back(component("toolset", welder_charges/20));
        g->consume_tools(&g->u, tools, true);

        if ( part == vp_head_light ) {
            // Need map-relative coordinates to compare to output of look_around.
            int gx, gy;
            // Need to call coord_translate() directly since it's a new part.
            veh->coord_translate(dx, dy, gx, gy);
            // Stash offset and set it to the location of the part so look_around will start there.
            int px = g->u.view_offset_x;
            int py = g->u.view_offset_y;
            g->u.view_offset_x = veh->global_x() + gx - g->u.posx;
            g->u.view_offset_y = veh->global_y() + gy - g->u.posy;
            popup("Choose a facing direction for the new headlight.");
            point headlight_target = g->look_around();
            // Restore previous view offsets.
            g->u.view_offset_x = px;
            g->u.view_offset_y = py;

            int delta_x = headlight_target.x - (veh->global_x() + gx);
            int delta_y = headlight_target.y - (veh->global_y() + gy);

            const double PI = 3.14159265358979f;
            int dir = (atan2(delta_y, delta_x) * 180.0 / PI);
            dir -= veh->face.dir();
            while(dir < 0) dir += 360;
            while(dir > 360) dir -= 360;

            veh->parts[partnum].direction = dir;
        }

        g->add_msg (_("You install a %s into the %s."),
                    vpart_list[part].name.c_str(), veh->name.c_str());
        g->u.practice (g->turn, "mechanics", vpart_list[part].difficulty * 5 + 20);
        break;
    case 'r':
        if (veh->parts[part].hp <= 0)
        {
            used_item = consume_vpart_item (g, veh->parts[part].id);
            tools.push_back(component("wrench", -1));
            g->consume_tools(&g->u, tools, true);
            tools.clear();
            dd = 0;
            veh->insides_dirty = true;
        }
        tools.push_back(component("welder", welder_charges));
        tools.push_back(component("welder_crude", welder_crude_charges));
        tools.push_back(component("toolset", welder_charges/20));
        g->consume_tools(&g->u, tools, true);
        veh->parts[part].hp = veh->part_info(part).durability;
        g->add_msg (_("You repair the %s's %s."),
                    veh->name.c_str(), veh->part_info(part).name.c_str());
        g->u.practice (g->turn, "mechanics", (vpart_list[part].difficulty + dd) * 5 + 20);
        break;
    case 'f':
        if (!g->pl_refill_vehicle(*veh, part, true))
            debugmsg ("complete_vehicle refill broken");
        g->pl_refill_vehicle(*veh, part);
        break;
    case 'o':
        // Dump contents of part at player's feet, if any.
        for (int i = 0; i < veh->parts[part].items.size(); i++)
            g->m.add_item_or_charges (g->u.posx, g->u.posy, veh->parts[part].items[i]);
        veh->parts[part].items.clear();

        broken = veh->parts[part].hp <= 0;
        if (!broken) {
            used_item = veh->item_from_part( part );
            g->m.add_item_or_charges(g->u.posx, g->u.posy, used_item);
            if(type!=SEL_JACK) // Changing tires won't make you a car mechanic
                g->u.practice (g->turn, "mechanics", 2 * 5 + 20);
        }
        if (veh->parts.size() < 2)
        {
            g->add_msg (_("You completely dismantle %s."), veh->name.c_str());
            g->u.activity.type = ACT_NULL;
            g->m.destroy_vehicle (veh);
        }
        else
        {
            g->add_msg (_("You remove %s%s from %s."), broken? rm_prefix(_("<veh>broken ")).c_str() : "",
                        veh->part_info(part).name.c_str(), veh->name.c_str());
            veh->remove_part (part);
        }
        break;
    case 's':
        g->u.siphon( g, veh, "gasoline" );
        break;
    case 'c':
        parts = veh->parts_at_relative( dx, dy );
        if( parts.size() ) {
            item removed_wheel;
            replaced_wheel = veh->part_with_feature( parts[0], "WHEEL", false );
            broken = veh->parts[replaced_wheel].hp <= 0;
            if( replaced_wheel != -1 ) {
                removed_wheel = veh->item_from_part( replaced_wheel );
                veh->remove_part( replaced_wheel );
                g->add_msg( _("You replace one of the %s's tires with %s."),
                            veh->name.c_str(), vpart_list[part].name.c_str() );
            } else {
                debugmsg( "no wheel to remove when changing wheels." );
                return;
            }
            partnum = veh->install_part( dx, dy, (vpart_id) part );
            if( partnum < 0 )
                debugmsg ("complete_vehicle tire change fails dx=%d dy=%d id=%d", dx, dy, part);
            used_item = consume_vpart_item( g, (vpart_id) part );
            veh->get_part_properties_from_item( g, partnum, used_item ); //transfer damage, etc.
            // Place the removed wheel on the map last so consume_vpart_item() doesn't pick it.
            if ( !broken ) {
                g->m.add_item_or_charges( g->u.posx, g->u.posy, removed_wheel );
            }
        }
        break;
    case 'd':
        g->u.siphon( g, veh, "water" );
        break;
    default:;
    }
}
void veh_interact::do_tirechange(int reason)
{
    werase( w_msg );
    switch( reason ) {
    case 1:
        mvwprintz(w_msg, 0, 1, c_ltred, _("There is no wheel to change here."));
        wrefresh (w_msg);
        return;
    case 2:
        mvwprintz(w_msg, 1, 1, c_ltgray, rm_prefix(_("<veh>To change a wheel you need a ")).c_str());
        wprintz(w_msg, has_wrench? c_ltgreen : c_red, _("wrench"));
        wprintz(w_msg, c_ltgray, rm_prefix(_("<veh> and a ")).c_str());
        wprintz(w_msg, has_jack? c_ltgreen : c_red, _("jack"));
        return;
    default:;
    }
    mvwprintz(w_mode, 0, 1, c_ltgray, _("Choose wheel to use as replacement:      "));
    wrefresh (w_mode);
    int pos = 0;
    while (true)
    {
        bool is_wheel = false;
        sel_part = can_mount[pos];
        switch(sel_part) {
        case vp_wheel:
        case vp_wheel_wide:
        case vp_wheel_bicycle:
        case vp_wheel_motorbike:
        case vp_wheel_small:
            is_wheel = true;
            break;
        default:
            break;
        }
        display_list (pos);
        itype_id itm = vpart_list[sel_part].item;
        bool has_comps = crafting_inv.has_amount(itm, 1);
        bool has_tools = has_jack && has_wrench;
        werase (w_msg);
        wrefresh (w_msg);
        char ch = input(); // See keypress.h
        int dx, dy;
        get_direction (g, dx, dy, ch);
        if ((ch == '\n' || ch == ' ') && has_comps && has_tools && is_wheel)
        {
            sel_cmd = 'c';
            return;
        }
        else
        {
            if (ch == KEY_ESCAPE || ch == 'q' )
            {
                werase (w_list);
                wrefresh (w_list);
                werase (w_msg);
                break;
            }
        }
        if (dy == -1 || dy == 1)
        {
            pos += dy;
            if (pos < 0)
            {
                pos = can_mount.size()-1;
            }
            else if (pos >= can_mount.size())
            {
                pos = 0;
            }
        }
    }
}
void veh_interact::do_remove(int reason)
{
    werase (w_msg);
    if (g->u.morale_level() < MIN_MORALE_CRAFT)
    { // See morale.h
        mvwprintz(w_msg, 0, 1, c_ltred, _("Your morale is too low to construct..."));
        wrefresh (w_msg);
        return;
    }
    switch (reason)
    {
    case 1:
        mvwprintz(w_msg, 0, 1, c_ltred, _("No parts here."));
        wrefresh (w_msg);
        return;
    case 2:
        mvwprintz(w_msg, 0, 1, c_ltgray, rm_prefix(_("<veh>You need a ")).c_str());
        wprintz(w_msg, has_wrench? c_ltgreen : c_red, _("wrench"));
        wprintz(w_msg, c_ltgray, rm_prefix(_("<veh> and a ")).c_str());
        wprintz(w_msg, has_hacksaw? c_ltgreen : c_red, _("hacksaw"));
        wprintz(w_msg, c_ltgray, rm_prefix(_("<veh> to remove parts.")).c_str());
        if(wheel) {
            mvwprintz(w_msg, 1, 1, c_ltgray, rm_prefix(_("<veh>To change a wheel you need a ")).c_str());
            wprintz(w_msg, has_wrench? c_ltgreen : c_red, _("wrench"));
            wprintz(w_msg, c_ltgray, rm_prefix(_("<veh> and a ")).c_str());
            wprintz(w_msg, has_jack? c_ltgreen : c_red, _("jack"));
        }
        wrefresh (w_msg);
        return;
    case 3:
        mvwprintz(w_msg, 0, 1, c_ltred,
                  _("You cannot remove mount point while something is attached to it."));
        wrefresh (w_msg);
        return;
    case 4:
        mvwprintz(w_msg, 0, 1, c_ltred, _("You need level 2 mechanics skill to remove parts."));
        wrefresh (w_msg);
        return;
    default:;
    }
    mvwprintz(w_mode, 0, 1, c_ltgray, _("Choose a part here to remove:"));
    wrefresh (w_mode);
    int first = parts_here.size() > 1? 1 : 0;
    int pos = first;
    while (true)
    {
        sel_part = parts_here[pos];
        werase (w_parts);
        veh->print_part_desc (w_parts, 0, winw2, cpart, pos);
        wrefresh (w_parts);
        char ch = input(); // See keypress.h
        int dx, dy;
        get_direction (g, dx, dy, ch);
        if (ch == '\n' || ch == ' ')
        {
            sel_cmd = 'o';
            return;
        }
        else
            if (ch == KEY_ESCAPE || ch == 'q' )
            {
                werase (w_parts);
                veh->print_part_desc (w_parts, 0, winw2, cpart, -1);
                wrefresh (w_parts);
                werase (w_msg);
                break;
            }
        if (dy == -1 || dy == 1)
        {
            pos += dy;
            if (pos < first)
                pos = parts_here.size()-1;
            else
                if (pos >= parts_here.size())
                    pos = first;
        }
    }
}
void veh_interact::do_install(int reason)
{
    werase (w_msg);
    if (g->u.morale_level() < MIN_MORALE_CRAFT)
    { // See morale.h
        mvwprintz(w_msg, 0, 1, c_ltred, _("Your morale is too low to construct..."));
        wrefresh (w_msg);
        return;
    }
    switch (reason)
    {
    case 1:
        mvwprintz(w_msg, 0, 1, c_ltred, _("Cannot install any part here."));
        wrefresh (w_msg);
        return;
    case 2:
        mvwprintz(w_msg, 0, 1, c_ltgray, rm_prefix(_("<veh>You need a ")).c_str());
        wprintz(w_msg, has_wrench? c_ltgreen : c_red, _("wrench"));
        wprintz(w_msg, c_ltgray, rm_prefix(_("<veh> and a ")).c_str());
        wprintz(w_msg, has_welder? c_ltgreen : c_red, _("powered welder"));
        wprintz(w_msg, c_ltgray, rm_prefix(_("<veh> to install parts.")).c_str());
        wrefresh (w_msg);
        return;
    default:;
    }
    mvwprintz(w_mode, 0, 1, c_ltgray, _("Choose new part to install here:      "));
    wrefresh (w_mode);
    int pos = 0;
    int engines = 0;
    int dif_eng = 0;
    for (int p = 0; p < veh->parts.size(); p++)
    {
        if (veh->part_flag (p, "ENGINE"))
        {
            engines++;
            dif_eng = dif_eng / 2 + 12;
        }
    }
    while (true)
    {
        sel_part = can_mount[pos];
        display_list (pos);
        itype_id itm = vpart_list[sel_part].item;
        bool has_comps = crafting_inv.has_amount(itm, 1);
        bool has_skill = g->u.skillLevel("mechanics") >= vpart_list[sel_part].difficulty;
        bool has_tools = has_welder && has_wrench;
        werase (w_msg);
        mvwprintz(w_msg, 0, 1, c_ltgray, rm_prefix(_("<veh>Needs ")).c_str());
        wprintz(w_msg, has_comps? c_ltgreen : c_red, g->itypes[itm]->name.c_str());
        wprintz(w_msg, c_ltgray, rm_prefix(_("<veh>, a ")).c_str());
        wprintz(w_msg, has_wrench? c_ltgreen : c_red, _("wrench"));
        wprintz(w_msg, c_ltgray, rm_prefix(_("<veh>, a ")).c_str());
        wprintz(w_msg, has_welder? c_ltgreen : c_red, _("powered welder"));
        wprintz(w_msg, c_ltgray, rm_prefix(_("<veh>, and level ")).c_str());
        wprintz(w_msg, has_skill? c_ltgreen : c_red, "%d", vpart_list[sel_part].difficulty);
        wprintz(w_msg, c_ltgray, rm_prefix(_("<veh> skill in mechanics.")).c_str());
        bool eng = vpart_list[sel_part].has_flag("ENGINE");
        bool has_skill2 = !eng || (g->u.skillLevel("mechanics") >= dif_eng);
        if (engines && eng) // already has engine
        {
            wprintz(w_msg, c_ltgray, rm_prefix(_("<veh> You also need level ")).c_str());
            wprintz(w_msg, has_skill2? c_ltgreen : c_red, "%d", dif_eng);
            wprintz(w_msg, c_ltgray, rm_prefix(_("<veh> skill in mechanics to install additional engine.")).c_str());
        }
        wrefresh (w_msg);
        char ch = input(); // See keypress.h
        int dx, dy;
        get_direction (g, dx, dy, ch);
        if ((ch == '\n' || ch == ' ') && has_comps && has_tools && has_skill && has_skill2)
        {
            //if(itm.is_var_veh_part() && crafting_inv.has_amount(itm, 2);
            sel_cmd = 'i';
            return;
        }
        else
        {
            if (ch == KEY_ESCAPE || ch == 'q' )
            {
                werase (w_list);
                wrefresh (w_list);
                werase (w_msg);
                break;
            }
        }
        if (dy == -1 || dy == 1)
        {
            pos += dy;
            if (pos < 0)
            {
                pos = can_mount.size()-1;
            }
            else if (pos >= can_mount.size())
            {
                pos = 0;
            }
        }
    }
}
Beispiel #11
0
// Why put this in a Big Switch?  Why not let bionics have pointers to
// functions, much like monsters and items?
//
// Well, because like diseases, which are also in a Big Switch, bionics don't
// share functions....
void player::activate_bionic(int b)
{
    bionic bio = my_bionics[b];
    int power_cost = bionics[bio.id]->power_cost;
    if ((weapon.type->id == "bio_claws_weapon" && bio.id == "bio_claws_weapon") ||
        (weapon.type->id == "bio_blade_weapon" && bio.id == "bio_blade_weapon")) {
        power_cost = 0;
    }
    if (power_level < power_cost) {
        if (my_bionics[b].powered) {
            add_msg(m_neutral, _("Your %s powers down."), bionics[bio.id]->name.c_str());
            my_bionics[b].powered = false;
        } else {
            add_msg(m_info, _("You cannot power your %s"), bionics[bio.id]->name.c_str());
        }
        return;
    }

    if (my_bionics[b].powered && my_bionics[b].charge > 0) {
        // Already-on units just lose a bit of charge
        my_bionics[b].charge--;
    } else {
        // Not-on units, or those with zero charge, have to pay the power cost
        if (bionics[bio.id]->charge_time > 0) {
            my_bionics[b].powered = true;
            my_bionics[b].charge = bionics[bio.id]->charge_time - 1;
        }
        power_level -= power_cost;
    }

    std::vector<point> traj;
    std::vector<std::string> good;
    std::vector<std::string> bad;
    int dirx, diry;
    item tmp_item;

    if(bio.id == "bio_painkiller") {
        pkill += 6;
        pain -= 2;
        if (pkill > pain) {
            pkill = pain;
        }
    } else if (bio.id == "bio_nanobots") {
        rem_disease("bleed");
        healall(4);
    } else if (bio.id == "bio_night") {
        if (calendar::turn % 5) {
            add_msg(m_neutral, _("Artificial night generator active!"));
        }
    } else if (bio.id == "bio_resonator") {
        g->sound(posx, posy, 30, _("VRRRRMP!"));
        for (int i = posx - 1; i <= posx + 1; i++) {
            for (int j = posy - 1; j <= posy + 1; j++) {
                g->m.bash( i, j, 40 );
                g->m.bash( i, j, 40 ); // Multibash effect, so that doors &c will fall
                g->m.bash( i, j, 40 );
                if (g->m.is_destructable(i, j) && rng(1, 10) >= 4) {
                    g->m.ter_set(i, j, t_rubble);
                }
            }
        }
    } else if (bio.id == "bio_time_freeze") {
        moves += power_level;
        power_level = 0;
        add_msg(m_good, _("Your speed suddenly increases!"));
        if (one_in(3)) {
            add_msg(m_bad, _("Your muscles tear with the strain."));
            apply_damage( nullptr, bp_arm_l, rng( 5, 10 ) );
            apply_damage( nullptr, bp_arm_r, rng( 5, 10 ) );
            apply_damage( nullptr, bp_leg_l, rng( 7, 12 ) );
            apply_damage( nullptr, bp_leg_r, rng( 7, 12 ) );
            apply_damage( nullptr, bp_torso, rng( 5, 15 ) );
        }
        if (one_in(5)) {
            add_disease("teleglow", rng(50, 400));
        }
    } else if (bio.id == "bio_teleport") {
        g->teleport();
        add_disease("teleglow", 300);
    }
    // TODO: More stuff here (and bio_blood_filter)
    else if(bio.id == "bio_blood_anal") {
        WINDOW *w = newwin(20, 40, 3 + ((TERMY > 25) ? (TERMY - 25) / 2 : 0),
                           10 + ((TERMX > 80) ? (TERMX - 80) / 2 : 0));
        draw_border(w);
        if (has_disease("fungus")) {
            bad.push_back(_("Fungal Parasite"));
        }
        if (has_disease("dermatik")) {
            bad.push_back(_("Insect Parasite"));
        }
        if (has_effect("stung")) {
            bad.push_back(_("Stung"));
        }
        if (has_effect("poison")) {
            bad.push_back(_("Poison"));
        }
        if (radiation > 0) {
            bad.push_back(_("Irradiated"));
        }
        if (has_disease("pkill1")) {
            good.push_back(_("Minor Painkiller"));
        }
        if (has_disease("pkill2")) {
            good.push_back(_("Moderate Painkiller"));
        }
        if (has_disease("pkill3")) {
            good.push_back(_("Heavy Painkiller"));
        }
        if (has_disease("pkill_l")) {
            good.push_back(_("Slow-Release Painkiller"));
        }
        if (has_disease("drunk")) {
            good.push_back(_("Alcohol"));
        }
        if (has_disease("cig")) {
            good.push_back(_("Nicotine"));
        }
        if (has_disease("meth")) {
            good.push_back(_("Methamphetamines"));
        }
        if (has_disease("high")) {
            good.push_back(_("Intoxicant: Other"));
        }
        if (has_disease("weed_high")) {
            good.push_back(_("THC Intoxication"));
        }
        if (has_disease("hallu") || has_disease("visuals")) {
            bad.push_back(_("Magic Mushroom"));
        }
        if (has_disease("iodine")) {
            good.push_back(_("Iodine"));
        }
        if (has_disease("datura")) {
            good.push_back(_("Anticholinergic Tropane Alkaloids"));
        }
        if (has_disease("took_xanax")) {
            good.push_back(_("Xanax"));
        }
        if (has_disease("took_prozac")) {
            good.push_back(_("Prozac"));
        }
        if (has_disease("took_flumed")) {
            good.push_back(_("Antihistamines"));
        }
        if (has_disease("adrenaline")) {
            good.push_back(_("Adrenaline Spike"));
        }
        if (has_disease("tapeworm")) {  // This little guy is immune to the blood filter though, as he lives in your bowels.
            good.push_back(_("Intestinal Parasite"));
        }
        if (has_disease("bloodworms")) {
            good.push_back(_("Hemolytic Parasites"));
        }
        if (has_disease("brainworm")) {  // This little guy is immune to the blood filter too, as he lives in your brain.
            good.push_back(_("Intracranial Parasite"));
        }
        if (has_disease("paincysts")) {  // These little guys are immune to the blood filter too, as they live in your muscles.
            good.push_back(_("Intramuscular Parasites"));
        }
        if (has_disease("tetanus")) {  // Tetanus infection.
            good.push_back(_("Clostridium Tetani Infection"));
        }
        if (good.empty() && bad.empty()) {
            mvwprintz(w, 1, 1, c_white, _("No effects."));
        } else {
            for (unsigned line = 1; line < 39 && line <= good.size() + bad.size(); line++) {
                if (line <= bad.size()) {
                    mvwprintz(w, line, 1, c_red, "%s", bad[line - 1].c_str());
                } else {
                    mvwprintz(w, line, 1, c_green, "%s", good[line - 1 - bad.size()].c_str());
                }
            }
        }
        wrefresh(w);
        refresh();
        getch();
        delwin(w);
    } else if(bio.id == "bio_blood_filter") {
        add_msg(m_neutral, _("You activate your blood filtration system."));
        rem_disease("fungus");
        rem_disease("dermatik");
        rem_disease("bloodworms");
        rem_disease("tetanus");
        remove_effect("poison");
        remove_effect("stung");
        rem_disease("pkill1");
        rem_disease("pkill2");
        rem_disease("pkill3");
        rem_disease("pkill_l");
        rem_disease("drunk");
        rem_disease("cig");
        rem_disease("high");
        rem_disease("hallu");
        rem_disease("visuals");
        rem_disease("iodine");
        rem_disease("datura");
        rem_disease("took_xanax");
        rem_disease("took_prozac");
        rem_disease("took_flumed");
        rem_disease("adrenaline");
        rem_disease("meth");
        pkill = 0;
        stim = 0;
    } else if(bio.id == "bio_evap") {
        item water = item("water_clean", 0);
        int humidity = g->weatherGen.get_weather(pos(), calendar::turn).humidity;
        int water_charges = (humidity * 3.0) / 100.0 + 0.5;
        // At 50% relative humidity or more, the player will draw 2 units of water
        // At 16% relative humidity or less, the player will draw 0 units of water
        water.charges = water_charges;
        if (water_charges == 0) {
            add_msg_if_player(m_bad, _("There was not enough moisture in the air from which to draw water!"));
        }
        if (g->handle_liquid(water, true, false)) {
            moves -= 100;
        } else if (query_yn(_("Drink from your hands?"))) {
            inv.push_back(water);
            consume(inv.position_by_type(water.typeId()));
            moves -= 350;
        } else if (water.charges == water_charges && water_charges != 0) {
            power_level += bionics["bio_evap"]->power_cost;
        }
    } else if(bio.id == "bio_lighter") {
        if(!choose_adjacent(_("Start a fire where?"), dirx, diry) ||
           (!g->m.add_field(dirx, diry, fd_fire, 1))) {
            add_msg_if_player(m_info, _("You can't light a fire there."));
            power_level += bionics["bio_lighter"]->power_cost;
        }

    }
    if(bio.id == "bio_leukocyte") {
        add_msg(m_neutral, _("You activate your leukocyte breeder system."));
        g->u.set_healthy(std::min(100, g->u.get_healthy() + 2));
        g->u.mod_healthy_mod(20);
    }
    if(bio.id == "bio_geiger") {
        add_msg(m_info, _("Your radiation level: %d"), radiation);
    }
    if(bio.id == "bio_radscrubber") {
        add_msg(m_neutral, _("You activate your radiation scrubber system."));
        if (radiation > 4) {
            radiation -= 5;
        } else {
            radiation = 0;
        }
    }
    if(bio.id == "bio_adrenaline") {
        add_msg(m_neutral, _("You activate your adrenaline pump."));
        if (has_disease("adrenaline")) {
            add_disease("adrenaline", 50);
        } else {
            add_disease("adrenaline", 200);
        }
    } else if(bio.id == "bio_claws") {
        if (weapon.type->id == "bio_claws_weapon") {
            add_msg(m_neutral, _("You withdraw your claws."));
            weapon = ret_null;
        } else if (weapon.has_flag ("NO_UNWIELD")) {
            add_msg(m_info, _("Deactivate your %s first!"),
                    weapon.tname().c_str());
            power_level += bionics[bio.id]->power_cost;
            return;
        } else if(weapon.type->id != "null") {
            add_msg(m_warning, _("Your claws extend, forcing you to drop your %s."),
                    weapon.tname().c_str());
            g->m.add_item_or_charges(posx, posy, weapon);
            weapon = item("bio_claws_weapon", 0);
            weapon.invlet = '#';
        } else {
            add_msg(m_neutral, _("Your claws extend!"));
            weapon = item("bio_claws_weapon", 0);
            weapon.invlet = '#';
        }
    } else if(bio.id == "bio_blade") {
        if (weapon.type->id == "bio_blade_weapon") {
            add_msg(m_neutral, _("You retract your blade."));
            weapon = ret_null;
        } else if (weapon.has_flag ("NO_UNWIELD")) {
            add_msg(m_info, _("Deactivate your %s first!"),
                    weapon.tname().c_str());
            power_level += bionics[bio.id]->power_cost;
            return;
        } else if(weapon.type->id != "null") {
            add_msg(m_warning, _("Your blade extends, forcing you to drop your %s."),
                    weapon.tname().c_str());
            g->m.add_item_or_charges(posx, posy, weapon);
            weapon = item("bio_blade_weapon", 0);
            weapon.invlet = '#';
        } else {
            add_msg(m_neutral, _("You extend your blade!"));
            weapon = item("bio_blade_weapon", 0);
            weapon.invlet = '#';
        }
    } else if(bio.id == "bio_blaster") {
        tmp_item = weapon;
        weapon = item("bio_blaster_gun", 0);
        g->refresh_all();
        g->plfire(false);
        if(weapon.charges == 1) { // not fired
            power_level += bionics[bio.id]->power_cost;
        }
        weapon = tmp_item;
    } else if (bio.id == "bio_laser") {
        tmp_item = weapon;
        weapon = item("bio_laser_gun", 0);
        g->refresh_all();
        g->plfire(false);
        if(weapon.charges == 1) { // not fired
            power_level += bionics[bio.id]->power_cost;
        }
        weapon = tmp_item;
    } else if(bio.id == "bio_chain_lightning") {
        tmp_item = weapon;
        weapon = item("bio_lightning", 0);
        g->refresh_all();
        g->plfire(false);
        if(weapon.charges == 1) { // not fired
            power_level += bionics[bio.id]->power_cost;
        }
        weapon = tmp_item;
    } else if (bio.id == "bio_emp") {
        if(choose_adjacent(_("Create an EMP where?"), dirx, diry)) {
            g->emp_blast(dirx, diry);
        } else {
            power_level += bionics["bio_emp"]->power_cost;
        }
    } else if (bio.id == "bio_hydraulics") {
        add_msg(m_good, _("Your muscles hiss as hydraulic strength fills them!"));
        // Sound of hissing hydraulic muscle! (not quite as loud as a car horn)
        g->sound(posx, posy, 19, _("HISISSS!"));
    } else if (bio.id == "bio_water_extractor") {
        bool extracted = false;
        for (std::vector<item>::iterator it = g->m.i_at(posx, posy).begin();
             it != g->m.i_at(posx, posy).end(); ++it) {
            if (it->type->id == "corpse" ) {
                int avail = 0;
                if ( it->item_vars.find("remaining_water") != it->item_vars.end() ) {
                    avail = atoi ( it->item_vars["remaining_water"].c_str() );
                } else {
                    avail = it->volume() / 2;
                }
                if(avail > 0 && query_yn(_("Extract water from the %s"), it->tname().c_str())) {
                    item water = item("water_clean", 0);
                    if (g->handle_liquid(water, true, true)) {
                        moves -= 100;
                    } else if (query_yn(_("Drink directly from the condenser?"))) {
                        inv.push_back(water);
                        consume(inv.position_by_type(water.typeId()));
                        moves -= 350;
                    }
                    extracted = true;
                    avail--;
                    it->item_vars["remaining_water"] = string_format("%d", avail);
                    break;
                }
            }
        }
        if (!extracted) {
            power_level += bionics["bio_water_extractor"]->power_cost;
        }
    } else if(bio.id == "bio_magnet") {
        for (int i = posx - 10; i <= posx + 10; i++) {
            for (int j = posy - 10; j <= posy + 10; j++) {
                if (g->m.i_at(i, j).size() > 0) {
                    int t; //not sure why map:sees really needs this, but w/e
                    if (g->m.sees(i, j, posx, posy, -1, t)) {
                        traj = line_to(i, j, posx, posy, t);
                    } else {
                        traj = line_to(i, j, posx, posy, 0);
                    }
                }
                traj.insert(traj.begin(), point(i, j));
                for (unsigned k = 0; k < g->m.i_at(i, j).size(); k++) {
                    if (g->m.i_at(i, j)[k].made_of("iron") || g->m.i_at(i, j)[k].made_of("steel")) {
                        tmp_item = g->m.i_at(i, j)[k];
                        g->m.i_rem(i, j, k);
                        std::vector<point>::iterator it;
                        for (it = traj.begin(); it != traj.end(); ++it) {
                            int index = g->mon_at(it->x, it->y);
                            if (index != -1) {
                                g->zombie(index).apply_damage( this, bp_torso, tmp_item.weight() / 225 );
                                g->m.add_item_or_charges(it->x, it->y, tmp_item);
                                break;
                            } else if (it != traj.begin() && g->m.move_cost(it->x, it->y) == 0) {
                                g->m.bash( it->x, it->y, tmp_item.weight() / 225 );
                                if (g->m.move_cost(it->x, it->y) == 0) {
                                    g->m.add_item_or_charges((it - 1)->x, (it - 1)->y, tmp_item);
                                    break;
                                }
                            }
                        }
                        if (it == traj.end()) {
                            g->m.add_item_or_charges(posx, posy, tmp_item);
                        }
                    }
                }
            }
        }
    } else if(bio.id == "bio_lockpick") {
        if(!choose_adjacent(_("Activate your bio lockpick where?"), dirx, diry)) {
            power_level += bionics["bio_lockpick"]->power_cost;
            return;
        }
        ter_id type = g->m.ter(dirx, diry);
        if (type  == t_door_locked || type == t_door_locked_alarm || type == t_door_locked_interior ) {
            moves -= 40;
            std::string door_name = rm_prefix(_("<door_name>door"));
            add_msg_if_player(m_neutral, _("With a satisfying click, the lock on the %s opens."),
                              door_name.c_str());
            g->m.ter_set(dirx, diry, t_door_c);
            // Locked metal doors are the Lab and Bunker entries.  Those need to stay locked.
        } else if(type == t_door_bar_locked) {
            moves -= 40;
            std::string door_name = rm_prefix(_("<door_name>door"));
            add_msg_if_player(m_neutral, _("The %s swings open..."),
                              door_name.c_str()); //Could better copy the messages from lockpick....
            g->m.ter_set(dirx, diry, t_door_bar_o);
        } else if(type == t_chaingate_l) {
            moves -= 40;
            std::string gate_name = rm_prefix (_("<door_name>gate"));
            add_msg_if_player(m_neutral, _("With a satisfying click, the lock on the %s opens."),
                              gate_name.c_str());
            g->m.ter_set(dirx, diry, t_chaingate_c);
        } else if(type == t_door_c) {
            add_msg(m_info, _("That door isn't locked."));
        } else {
            add_msg_if_player(m_neutral, _("You can't unlock that %s."),
                              g->m.tername(dirx, diry).c_str());
        }
    } else if(bio.id == "bio_flashbang") {
        add_msg_if_player(m_neutral, _("You activate your integrated flashbang generator!"));
        g->flashbang(posx, posy, true);
    } else if(bio.id == "bio_shockwave") {
        g->shockwave(posx, posy, 3, 4, 2, 8, true);
        add_msg_if_player(m_neutral, _("You unleash a powerful shockwave!"));
    }
}