Ejemplo n.º 1
0
void npc::init_selling(std::vector<int> &indices, std::vector<int> &prices)
{
 int val, price;
 for (int i = 0; i < inv.size(); i++) {
  val = value(inv[i]) - (inv[i].price() / 50);
  if (val <= NPC_LOW_VALUE || mission == NPC_MISSION_SHOPKEEP) {
   indices.push_back(i);
   price = inv[i].price() / (price_adjustment(sklevel[sk_barter]));
   prices.push_back(price);
  }
 }
}
Ejemplo n.º 2
0
void npc::init_buying(std::vector<item> you, std::vector<int> &indices,
                      std::vector<int> &prices)
{
 int val, price;
 for (int i = 0; i < you.size(); i++) {
  val = value(you[i]);
  if (val >= NPC_HI_VALUE) {
   indices.push_back(i);
   price = you[i].price();
   if (val >= NPC_VERY_HI_VALUE)
    price *= 2;
   price *= price_adjustment(sklevel[sk_barter]);
   prices.push_back(price);
  }
 }
}
Ejemplo n.º 3
0
void npc::init_selling(std::vector<int> &indices, std::vector<int> &prices)
{
 int val, price;
 bool found_lighter = false;
 for (int i = 0; i < inv.size(); i++) {
  if (inv[i].type->id == itm_lighter && !found_lighter)
   found_lighter = true;
  else {
   val = value(inv[i]) - (inv[i].price() / 50);
   if (val <= NPC_LOW_VALUE || mission == NPC_MISSION_SHOPKEEP) {
    indices.push_back(i);
    price = inv[i].price() / (price_adjustment(sklevel[sk_barter]));
    prices.push_back(price);
   }
  }
 }
}
Ejemplo n.º 4
0
bool trade(game *g, npc *p, int cost, std::string deal)
{
    WINDOW* w_head = newwin( 4, 80,  0,  0);
    WINDOW* w_them = newwin(21, 40,  4,  0);
    WINDOW* w_you  = newwin(21, 40,  4, 40);
    WINDOW* w_tmp;
    mvwprintz(w_head, 0, 0, c_white, _("\
Trading with %s\n\
Tab key to switch lists, letters to pick items, Enter to finalize, Esc to quit\n\
? to get information on an item"), p->name.c_str());

// Set up line drawings
    for (int i = 0; i < 80; i++)
        mvwputch(w_head,  3, i, c_white, LINE_OXOX);
    wrefresh(w_head);


// End of line drawings

// Populate the list of what the NPC is willing to buy, and the prices they pay
// Note that the NPC's barter skill is factored into these prices.
    std::vector<int> theirs, their_price, yours, your_price;
    p->init_selling(theirs, their_price);
    p->init_buying(g->u.inv, yours, your_price);
    bool getting_theirs[theirs.size()], getting_yours[yours.size()];

// Adjust the prices based on your barter skill.
    for (int i = 0; i < their_price.size(); i++) {
        their_price[i] *= (price_adjustment(g->u.sklevel[sk_barter]) +
                           (p->int_cur - g->u.int_cur) / 15);
        getting_theirs[i] = false;
    }
    for (int i = 0; i < your_price.size(); i++) {
        your_price[i] /= (price_adjustment(g->u.sklevel[sk_barter]) +
                          (p->int_cur - g->u.int_cur) / 15);
        getting_yours[i] = false;
    }

    int cash = cost;// How much cash you get in the deal (negative = losing money)
    bool focus_them = true;	// Is the focus on them?
    bool update = true;		// Re-draw the screen?
    int them_off = 0, you_off = 0;	// Offset from the start of the list
    char ch, help;

    do {
        if (update) {	// Time to re-draw
            update = false;
// Draw borders, one of which is highlighted
            werase(w_them);
            werase(w_you);
            for (int i = 1; i < 80; i++)
                mvwputch(w_head, 3, i, c_white, LINE_OXOX);
            mvwprintz(w_head, 3, 30, ((cash <  0 && g->u.cash >= cash * -1) ||
                                      (cash >= 0 && p->cash  >= cash) ?
                                      c_green : c_red),
                      "%s $%d", (cash >= 0 ? _("Profit") : _("Cost")), abs(cash));
            if (deal != "")
                mvwprintz(w_head, 3, 45, (cost < 0 ? c_ltred : c_ltgreen), deal.c_str());
            if (focus_them)
                wattron(w_them, c_yellow);
            else
                wattron(w_you,  c_yellow);
            wborder(w_them, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
                    LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX );
            wborder(w_you,  LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
                    LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX );
            wattroff(w_them, c_yellow);
            wattroff(w_you,  c_yellow);
            mvwprintz(w_them, 0, 1, (cash < 0 || p->cash >= cash ? c_green : c_red),
                      "%s: $%d", p->name.c_str(), p->cash);
            mvwprintz(w_you,  0, 2, (cash > 0 || g->u.cash>=cash*-1 ? c_green:c_red),
                      "You: $%d", g->u.cash);
// Draw their list of items, starting from them_off
            for (int i = them_off; i < theirs.size() && i < 17; i++)
                mvwprintz(w_them, i - them_off + 1, 1,
                          (getting_theirs[i] ? c_white : c_ltgray), "%c %c %s - $%d",
                          char(i + 'a'), (getting_theirs[i] ? '+' : '-'),
                          p->inv[theirs[i + them_off]].tname().substr( 0,25).c_str(),
                          their_price[i + them_off]);
            if (them_off > 0)
                mvwprintw(w_them, 19, 1, _("< Back"));
            if (them_off + 17 < theirs.size())
                mvwprintw(w_them, 19, 9, _("More >"));
// Draw your list of items, starting from you_off
            for (int i = you_off; i < yours.size() && i < 17; i++)
                mvwprintz(w_you, i - you_off + 1, 1,
                          (getting_yours[i] ? c_white : c_ltgray), "%c %c %s - $%d",
                          char(i + 'a'), (getting_yours[i] ? '+' : '-'),
                          g->u.inv[yours[i + you_off]].tname().substr( 0,25).c_str(),
                          your_price[i + you_off]);
            if (you_off > 0)
                mvwprintw(w_you, 19, 1, _("< Back"));
            if (you_off + 17 < yours.size())
                mvwprintw(w_you, 19, 9, _("More >"));
            wrefresh(w_head);
            wrefresh(w_them);
            wrefresh(w_you);
        }	// Done updating the screen
        ch = getch();
        switch (ch) {
        case '\t':
            focus_them = !focus_them;
            update = true;
            break;
        case '<':
            if (focus_them) {
                if (them_off > 0) {
                    them_off -= 17;
                    update = true;
                }
            } else {
                if (you_off > 0) {
                    you_off -= 17;
                    update = true;
                }
            }
            break;
        case '>':
            if (focus_them) {
                if (them_off + 17 < theirs.size()) {
                    them_off += 17;
                    update = true;
                }
            } else {
                if (you_off + 17 < yours.size()) {
                    you_off += 17;
                    update = true;
                }
            }
            break;
        case '?':
            update = true;
            w_tmp = newwin(3, 21, 1, 30);
            mvwprintz(w_tmp, 1, 1, c_red, _("Examine which item?"));
            wborder(w_tmp, LINE_XOXO, LINE_XOXO, LINE_OXOX, LINE_OXOX,
                    LINE_OXXO, LINE_OOXX, LINE_XXOO, LINE_XOOX );
            wrefresh(w_tmp);
            help = getch();
            help -= 'a';
            werase(w_tmp);
            delwin(w_tmp);
            wrefresh(w_head);
            if (focus_them) {
                if (help >= 0 && help < theirs.size())
                    popup(p->inv[theirs[help]].info().c_str());
            } else {
                if (help >= 0 && help < yours.size())
                    popup(g->u.inv[theirs[help]].info().c_str());
            }
            break;
        case '\n':	// Check if we have enough cash...
            if (cash < 0 && g->u.cash < cash * -1) {
                popup(_("Not enough cash!  You have $%d, price is $%d."), g->u.cash, cash);
                update = true;
                ch = ' ';
            } else if (cash > 0 && p->cash < cash)
                p->op_of_u.owed += cash;
            break;
        default:	// Letters & such
            if (ch >= 'a' && ch <= 'z') {
                ch -= 'a';
                if (focus_them) {
                    if (ch < theirs.size()) {
                        getting_theirs[ch] = !getting_theirs[ch];
                        if (getting_theirs[ch])
                            cash -= their_price[ch];
                        else
                            cash += their_price[ch];
                        update = true;
                    }
                } else {	// Focus is on the player's inventory
                    if (ch < yours.size()) {
                        getting_yours[ch] = !getting_yours[ch];
                        if (getting_yours[ch])
                            cash += your_price[ch];
                        else
                            cash -= your_price[ch];
                        update = true;
                    }
                }
                ch = 0;
            }
        }
    } while (ch != KEY_ESCAPE && ch != '\n');

    if (ch == '\n') {
        inventory newinv;
        int practice = 0;
        std::vector<char> removing;
        for (int i = 0; i < yours.size(); i++) {
            if (getting_yours[i]) {
                newinv.push_back(g->u.inv[yours[i]]);
                practice++;
                removing.push_back(g->u.inv[yours[i]].invlet);
            }
        }
// Do it in two passes, so removing items doesn't corrupt yours[]
        for (int i = 0; i < removing.size(); i++)
            g->u.i_rem(removing[i]);

        for (int i = 0; i < theirs.size(); i++) {
            item tmp = p->inv[theirs[i]];
            if (getting_theirs[i]) {
                practice += 2;
                tmp.invlet = 'a';
                while (g->u.has_item(tmp.invlet)) {
                    if (tmp.invlet == 'z')
                        tmp.invlet = 'A';
                    else if (tmp.invlet == 'Z')
                        return false;	// TODO: Do something else with these.
                    else
                        tmp.invlet++;
                }
                g->u.inv.push_back(tmp);
            } else
                newinv.push_back(tmp);
        }
        g->u.practice(sk_barter, practice / 2);
        p->inv = newinv;
        g->u.cash += cash;
        p->cash   -= cash;
    }
    werase(w_head);
    werase(w_you);
    werase(w_them);
    wrefresh(w_head);
    wrefresh(w_you);
    wrefresh(w_them);
    delwin(w_head);
    delwin(w_you);
    delwin(w_them);
    if (ch == '\n')
        return true;
    return false;
}