now works like the drop or pickup menu (or like a cart in any shop in RL, if you will) in that you can add or remove stuff, and the game will even tell you how much you have left and what else you can afford. Very cool stuff!
Known bugs:
Since you now buy a lot of stuff at the same time and there's a shortage of space in the shopping interface I've merged all bought items into one line (using comma_separated_line). This has the unintended side effect that you can no longer note which items you bought because this message can be longer than a single line. Rather than printing each bought item on a single line, I'd rather add a NOTE_BOUGHT case that is optional and also tracks what you paid for said item.
If you buy several packages of the same item type, the output doesn't yet merge them, so you'll get "You bought 1 potion of heal wounds, 1 potion of healing, and 1 potion of heal wounds."
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@6545 c06c8d41-db1a-0410-9941-cceddc491573
25EF5X4H3LURXFZ35ZGYGUB6ND7NFQVH4M2XX2SI33I4XRGYG5HAC
IGBJ3ZY5G73GTHPRNWKC6XMQDINRGCTIXKBHTEZ7JLUJS6H4JRBAC
4ZAYR6K7SNJ45QYS5KLZOJ2T7OKYL4M2RY5UIIMOWRQGZLTME6UQC
TDAVD56MGLFSMJLPLSYLEVW7MBRMT7V5BNII4TRWVDIHH47CD2OAC
QKBKV43FJRXHZ7IOHWNNFXYT7G7NGVDBNO7Z7ZJBDU3SFP4DZIHAC
GYRKOLZFYXWJTPEV35USSHCJNA6Y4XMDHSTEZWEBM57WQP2PT6UQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
4DEFHDNO2GUBYL4EGYEAR2IP3KBDXRU7UL7L4P7HEZY2UNR6IYJAC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
74LQ7JXVLAFSHLI7LCBKFX47CNTYSKGUQSXNX5FCIUIGCC2JTR3QC
3ZWALZFSTSIVYXY4BAY6ANGINTDACZC6RSSJTEMQSTSUIE66YOBQC
OQ4KB7QCJSK7GSW3DYBARH4DCB75HFKLUSOSOZZZ4IUFKNGFRUDQC
2KTJHQUX2LTU2BCLS5YXVRRKMOYKKIZAPF2LBKORFGSHEN5IO3IAC
CIPVRZGLOZHCERK6YPOBV3P2E4IAB4H6D5EHLRQE2O5E4P4VCBUAC
3JOOHBLF6D4362LD2TQGKYB5JVTNX34DD7DPXVJL5E2K2QN2EFLQC
5HPIIGNWB3UXJ5APQLAGFOV2CA7J2GB7AWAVVZDBB2YZS4TNCMAQC
textcolor( can_afford ? LIGHTGREEN : LIGHTRED );
cprintf("%c - ", c);
// Colour stock as follows:
// * lightred, if you can't buy all you selected.
// * lightgreen, if this item is purchasable along with your selections
// * red, if this item is not purchasable even by itself.
// * yellow, if this item would be purchasable if you deselected
// something else.
// Is this too complicated?
textcolor((i % 2) ? LIGHTGREY : WHITE);
if (total_cost > you.gold && selected[i])
textcolor(LIGHTRED);
else if (gp_value <= you.gold - total_cost || selected[i] && can_afford)
textcolor(LIGHTGREEN);
else if (!can_afford)
textcolor(RED);
else
textcolor(YELLOW);
if (selected[i])
cprintf("%c + ", c);
else
cprintf("%c - ", c);
textcolor(i % 2 ? LIGHTGREY : WHITE);
/*
Rather than prompting for each individual item, I think it should be
like multi-pickup, in that pressing a letter only "selects" an item
(changing the '-' next to its name to a '+').
New, suggested shopping keys:
* letter keys [a-t] (de)select item
* Enter buys (with prompt)
* ? toggles examination mode (where letter keys view items)
* \ shows discovered items
* * lists inventory
* x exits (also Esc)
For the ? key, the text should read:
[?] switch to examination mode
[?] switch to selection mode
Display selected items in yellow.
Use red/green letters to indicated availability as now. Update these as
items are (de)selected.
List funds: "You now have 119 gold pieces. After the purchase, you will
have 24 gold pieces."
*/
snprintf( info, INFO_SIZE, "You have %d gold piece%s.", you.gold,
(you.gold == 1) ? "" : "s" );
textcolor(YELLOW);
textcolor(YELLOW);
}
else if (total_cost > you.gold)
{
snprintf( info, INFO_SIZE, "You now have %d gold piece%s. "
"You are short %d gold piece%s for the purchase.",
you.gold,
(you.gold == 1) ? "" : "s",
total_cost - you.gold,
(total_cost - you.gold == 1) ? "" : "s" );
textcolor(LIGHTRED);
}
else
{
snprintf( info, INFO_SIZE, "You now have %d gold piece%s. "
"After the purchase, you will have %d gold piece%s.",
you.gold,
(you.gold == 1) ? "" : "s",
you.gold - total_cost,
(you.gold - total_cost == 1) ? "" : "s" );
textcolor(YELLOW);
}
else if (ft == '\r')
{
// Do purchase.
if (total_cost > you.gold)
{
_shop_print("I'm sorry, you don't seem to have enough money.", 1);
_shop_more();
}
else if (!total_cost)
continue;
else
{
textcolor(channel_to_colour(MSGCH_PROMPT));
snprintf(info, INFO_SIZE, "Purchase for %d gold? (y/n) ",
total_cost);
_shop_print(info, 1);
if ( yesno(NULL, true, 'n', false, false, true) )
{
std::vector<std::string> purchases;
int num_items = 0, outside_items = 0, quant;
for (int i = selected.size() - 1; i >= 0; --i)
{
if (selected[i])
{
item_def& item = mitm[stock[i]];
purchases.push_back(item.name(DESC_NOCAP_A));
quant = item.quantity;
num_items += quant;
const int gp_value = _shop_get_item_value(item,
shop.greed, id_stock);
if (!_purchase(shopidx, stock[i], gp_value,
id_stock))
{
// The purchased item didn't fit into your
// knapsack.
outside_items += quant;
}
}
}
// Hack to make sure the lines are empty for the mpr().
for (int i = 0; i < 5; i++)
_shop_print("\n", i);
// This is so that note_messages can be used to note items
// being bought, and also so you can use message history
// to review what you bought.
// FIXME: If you buy several items of the same type
// they are not merged in the listing.
mprf("You bought %s for a total of %d gold piece%s.",
comma_separated_line(purchases.begin(),
purchases.end(),
", and ", ", ").c_str(),
total_cost,
total_cost > 1 ? "s" : "");
if (outside_items)
{
mprf( "I'll put %s outside for you.",
num_items == 1 ? "it" :
num_items == outside_items ? "them"
: "part of them" );
}
}
}
_shop_more();
continue;
}
const int gp_value = _shop_get_item_value(item, shop.greed, id_stock);
if (gp_value > you.gold)
{
_shop_print("I'm sorry, you don't seem to have enough money.", 1);
_shop_more();
}
selected[ft] = !selected[ft];
if (selected[ft])
total_cost += gp_value;
{
textcolor(channel_to_colour(MSGCH_PROMPT));
snprintf(info, INFO_SIZE, "Purchase %s (%d gold)? (y/n) ",
item.name(DESC_NOCAP_A).c_str(), gp_value);
_shop_print(info, 1);
if ( yesno(NULL, true, 'n', false, false, true) )
_purchase( shopidx, stock[ft], gp_value, id_stock );
}
total_cost -= gp_value;
// This is so that note_messages can be used to note items being
// bought, and also so you can use message history to review
// what you bought.
mprf("You bought %s.", item.name(DESC_NOCAP_A, false, id).c_str());
mesclr();
if ( id )
if (id)
snprintf( info, INFO_SIZE, "I'll put %s outside for you.",
(quant == 1) ? "it" :
(num > 0) ? "the rest"
: "these" );
_shop_print(info, 1);
_shop_more();