diff options
author | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-08-02 12:54:15 +0000 |
---|---|---|
committer | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-08-02 12:54:15 +0000 |
commit | d5e5340c3926d1cf97f6cba151ffaecb20bfb35f (patch) | |
tree | d1faf7d5b27df8f3c523a8dd33357804118e62b1 /trunk/source/invent.cc | |
parent | 7b2204d69f21d7075e4666ee032d7a129081bc4b (diff) | |
download | crawl-ref-d5e5340c3926d1cf97f6cba151ffaecb20bfb35f.tar.gz crawl-ref-d5e5340c3926d1cf97f6cba151ffaecb20bfb35f.zip |
Integrated travel patch as of 20060727
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'trunk/source/invent.cc')
-rw-r--r-- | trunk/source/invent.cc | 802 |
1 files changed, 599 insertions, 203 deletions
diff --git a/trunk/source/invent.cc b/trunk/source/invent.cc index 1a6db7d1bc..2145f80f72 100644 --- a/trunk/source/invent.cc +++ b/trunk/source/invent.cc @@ -25,6 +25,7 @@ #include "externs.h" +#include "clua.h" #include "itemname.h" #include "items.h" #include "macro.h" @@ -32,237 +33,467 @@ #include "shopping.h" #include "stuff.h" #include "view.h" - +#include "menu.h" const char *command_string( int i ); const char *wizard_string( int i ); -unsigned char get_invent( int invent_type ) +struct InvTitle : public MenuEntry { - unsigned char nothing = invent( invent_type, false ); - - redraw_screen(); + Menu *m; + std::string (*titlefn)( int menuflags, const std::string &oldt ); + + InvTitle( Menu *mn, const char *title, + std::string (*tfn)( int menuflags, const std::string &oldt ) ) + : MenuEntry( title ) + { + m = mn; + titlefn = tfn; + } - return (nothing); -} // end get_invent() + std::string get_text() const + { + return titlefn? titlefn( m->get_flags(), MenuEntry::get_text() ) : + MenuEntry::get_text(); + } +}; -unsigned char invent( int item_class_inv, bool show_price ) +class InvShowPrices; +class InvEntry : public MenuEntry { - char st_pass[ ITEMNAME_SIZE ] = ""; +private: + static bool show_prices; + static char temp_id[4][50]; + static void set_show_prices(bool doshow); - int i, j; - char lines = 0; - unsigned char anything = 0; - char tmp_quant[20] = ""; - char yps = 0; - char temp_id[4][50]; + friend class InvShowPrices; +public: + const item_def *item; - const int num_lines = get_number_of_lines(); + InvEntry( const item_def &i ) : MenuEntry( "", MEL_ITEM ), item( &i ) + { + data = const_cast<item_def *>( item ); + + char buf[ITEMNAME_SIZE]; + if (i.base_type == OBJ_GOLD) + snprintf(buf, sizeof buf, "%d gold piece%s", i.quantity, + (i.quantity > 1? "s" : "")); + else + item_name(i, + in_inventory(i)? + DESC_INVENTORY_EQUIP : DESC_NOCAP_A, buf, false); + text = buf; - FixedVector< int, NUM_OBJECT_CLASSES > inv_class2; - int inv_count = 0; - unsigned char ki = 0; + if (i.base_type != OBJ_GOLD) + { + if (in_inventory(i)) + { + text = text.substr( 4 ); // Skip the inventory letter. + add_hotkey(index_to_letter( i.link )); + } + else + add_hotkey(' '); // Dummy hotkey + } + else + { + // Dummy hotkey for gold. + add_hotkey(' '); + } + add_class_hotkeys(i); -#ifdef DOS_TERM - char buffer[4600]; + quantity = i.quantity; + } - gettext(1, 1, 80, 25, buffer); - window(1, 1, 80, 25); -#endif + std::string get_text() const + { + char buf[ITEMNAME_SIZE]; + char suffix[ITEMNAME_SIZE] = ""; - for (i = 0; i < 4; i++) + if (InvEntry::show_prices) + { + int value = item_value(*item, temp_id, true); + if (value > 0) + snprintf(suffix, sizeof suffix, + " (%d gold)", value); + } + snprintf( buf, sizeof buf, + "%c %c %s%s", + hotkeys[0], + (!selected_qty? '-' : selected_qty < quantity? '#' : '+'), + text.c_str(), + suffix ); + return (buf); + } +private: + void add_class_hotkeys(const item_def &i) { - for (j = 0; j < 50; j++) + switch (i.base_type) { - temp_id[i][j] = 1; + case OBJ_GOLD: + add_hotkey('$'); + break; + case OBJ_MISSILES: + add_hotkey('('); + break; + case OBJ_WEAPONS: + add_hotkey(')'); + break; + case OBJ_ARMOUR: + add_hotkey('['); + break; + case OBJ_WANDS: + add_hotkey('/'); + break; + case OBJ_FOOD: + add_hotkey('%'); + break; + case OBJ_BOOKS: + add_hotkey('+'); + add_hotkey(':'); + break; + case OBJ_SCROLLS: + add_hotkey('?'); + break; + case OBJ_JEWELLERY: + add_hotkey(i.sub_type >= AMU_RAGE? '"' : '='); + break; + case OBJ_POTIONS: + add_hotkey('!'); + break; + case OBJ_STAVES: + add_hotkey('\\'); + add_hotkey('|'); + break; + case OBJ_MISCELLANY: + add_hotkey('}'); + break; + case OBJ_CORPSES: + add_hotkey('&'); + break; + default: + break; } } +}; - clrscr(); - - for (i = 0; i < NUM_OBJECT_CLASSES; i++) - inv_class2[i] = 0; +bool InvEntry::show_prices = false; +char InvEntry::temp_id[4][50]; - for (i = 0; i < ENDOFPACK; i++) +void InvEntry::set_show_prices(bool doshow) +{ + if ((show_prices = doshow)) { - if (you.inv[i].quantity) - { - inv_class2[ you.inv[i].base_type ]++; - inv_count++; - } + memset(temp_id, 1, sizeof temp_id); } +} - if (!inv_count) +class InvShowPrices { +public: + InvShowPrices(bool doshow = true) { - cprintf("You aren't carrying anything."); + InvEntry::set_show_prices(doshow); + } + ~InvShowPrices() + { + InvEntry::set_show_prices(false); + } +}; - if (getch() == 0) - getch(); +class InvMenu : public Menu +{ +public: + InvMenu(int flags = MF_MULTISELECT) : Menu(flags) { } +protected: + bool process_key(int key); +}; - goto putty; +bool InvMenu::process_key( int key ) +{ + if (items.size() && (key == CONTROL('D') || key == '@')) + { + int newflag = + is_set(MF_MULTISELECT)? + MF_SINGLESELECT | MF_EASY_EXIT | MF_ANYPRINTABLE + : MF_MULTISELECT; + + flags &= ~(MF_SINGLESELECT | MF_MULTISELECT | + MF_EASY_EXIT | MF_ANYPRINTABLE); + flags |= newflag; + + deselect_all(); + sel->clear(); + draw_select_count(0); + return true; } + return Menu::process_key( key ); +} - if (item_class_inv != -1) - { - for (i = 0; i < NUM_OBJECT_CLASSES; i++) - { - if (item_class_inv == OBJ_MISSILES && i == OBJ_WEAPONS) - i++; +bool in_inventory( const item_def &i ) +{ + return i.x == -1 && i.y == -1; +} - if (item_class_inv == OBJ_WEAPONS - && (i == OBJ_STAVES || i == OBJ_MISCELLANY)) - { - i++; - } +unsigned char get_invent( int invent_type ) +{ + unsigned char nothing = invent_select( invent_type ); + + redraw_screen(); - if (item_class_inv == OBJ_SCROLLS && i == OBJ_BOOKS) - i++; + return (nothing); +} // end get_invent() - if (i < NUM_OBJECT_CLASSES && item_class_inv != i) - inv_class2[i] = 0; +std::string item_class_name( int type, bool terse ) +{ + if (terse) + { + switch (type) + { + case OBJ_GOLD: return ("gold"); + case OBJ_WEAPONS: return ("weapon"); + case OBJ_MISSILES: return ("missile"); + case OBJ_ARMOUR: return ("armour"); + case OBJ_WANDS: return ("wand"); + case OBJ_FOOD: return ("food"); + case OBJ_UNKNOWN_I: return ("book"); + case OBJ_SCROLLS: return ("scroll"); + case OBJ_JEWELLERY: return ("jewelry"); + case OBJ_POTIONS: return ("potion"); + case OBJ_UNKNOWN_II: return ("gem"); + case OBJ_BOOKS: return ("book"); + case OBJ_STAVES: return ("stave"); + case OBJ_ORBS: return ("orb"); + case OBJ_MISCELLANY: return ("misc"); + case OBJ_CORPSES: return ("carrion"); + } + } + else + { + switch (type) + { + case OBJ_GOLD: return ("Gold"); + case OBJ_WEAPONS: return ("Hand Weapons"); + case OBJ_MISSILES: return ("Missiles"); + case OBJ_ARMOUR: return ("Armour"); + case OBJ_WANDS: return ("Magical Devices"); + case OBJ_FOOD: return ("Comestibles"); + case OBJ_UNKNOWN_I: return ("Books"); + case OBJ_SCROLLS: return ("Scrolls"); + case OBJ_JEWELLERY: return ("Jewellery"); + case OBJ_POTIONS: return ("Potions"); + case OBJ_UNKNOWN_II: return ("Gems"); + case OBJ_BOOKS: return ("Books"); + case OBJ_STAVES: return ("Magical Staves and Rods"); + case OBJ_ORBS: return ("Orbs of Power"); + case OBJ_MISCELLANY: return ("Miscellaneous"); + case OBJ_CORPSES: return ("Carrion"); } } + return (""); +} - if ((item_class_inv == -1 && inv_count > 0) - || (item_class_inv != -1 && inv_class2[item_class_inv] > 0) - || (item_class_inv == OBJ_MISSILES && inv_class2[OBJ_WEAPONS] > 0) - || (item_class_inv == OBJ_WEAPONS - && (inv_class2[OBJ_STAVES] > 0 || inv_class2[OBJ_MISCELLANY] > 0)) - || (item_class_inv == OBJ_SCROLLS && inv_class2[OBJ_BOOKS] > 0)) +void populate_item_menu( Menu *menu, const std::vector<item_def> &items, + void (*callback)(MenuEntry *me) ) +{ + FixedVector< int, NUM_OBJECT_CLASSES > inv_class; + for (int i = 0; i < NUM_OBJECT_CLASSES; ++i) + inv_class[i] = 0; + for (int i = 0, count = items.size(); i < count; ++i) + inv_class[ items[i].base_type ]++; + + menu_letter ckey; + for (int i = 0; i < NUM_OBJECT_CLASSES; ++i) { - const int cap = carrying_capacity(); + if (!inv_class[i]) continue; - cprintf( " Inventory: %d.%d aum (%d%% of %d.%d aum maximum)", - you.burden / 10, you.burden % 10, - (you.burden * 100) / cap, cap / 10, cap % 10 ); - lines++; + menu->add_entry( new MenuEntry( item_class_name(i), MEL_SUBTITLE ) ); - for (i = 0; i < 15; i++) + for (int j = 0, count = items.size(); j < count; ++j) { - if (inv_class2[i] != 0) - { - if (lines > num_lines - 3) - { - gotoxy(1, num_lines); - cprintf("-more-"); + if (items[j].base_type != i) continue; - ki = getch(); + InvEntry *ie = new InvEntry( items[j] ); + ie->hotkeys[0] = ckey++; + callback(ie); - if (ki == ESCAPE) - { -#ifdef DOS_TERM - puttext(1, 1, 80, 25, buffer); -#endif - return (ESCAPE); - } - else if (isalpha(ki) || ki == '?' || ki == '*') - { -#ifdef DOS_TERM - puttext(1, 1, 80, 25, buffer); -#endif - return (ki); - } + menu->add_entry( ie ); + } + } +} - if (ki == 0) - ki = getch(); +std::vector<SelItem> select_items( std::vector<item_def*> &items, + const char *title ) +{ + std::vector<SelItem> selected; - lines = 0; - clrscr(); - gotoxy(1, 1); - anything = 0; + if (items.empty()) + return selected; - } + FixedVector< int, NUM_OBJECT_CLASSES > inv_class; + for (int i = 0; i < NUM_OBJECT_CLASSES; ++i) + inv_class[i] = 0; + for (int i = 0, count = items.size(); i < count; ++i) + inv_class[ items[i]->base_type ]++; - if (lines > 0) - cprintf(EOL " "); + Menu menu; + menu.set_title( new MenuEntry(title) ); - textcolor(BLUE); + char ckey = 'a'; + for (int i = 0; i < NUM_OBJECT_CLASSES; ++i) + { + if (!inv_class[i]) continue; - switch (i) - { - case OBJ_WEAPONS: cprintf("Hand Weapons"); break; - case OBJ_MISSILES: cprintf("Missiles"); break; - case OBJ_ARMOUR: cprintf("Armour"); break; - case OBJ_WANDS: cprintf("Magical Devices"); break; - case OBJ_FOOD: cprintf("Comestibles"); break; - case OBJ_UNKNOWN_I: cprintf("Books"); break; - case OBJ_SCROLLS: cprintf("Scrolls"); break; - case OBJ_JEWELLERY: cprintf("Jewellery"); break; - case OBJ_POTIONS: cprintf("Potions"); break; - case OBJ_UNKNOWN_II: cprintf("Gems"); break; - case OBJ_BOOKS: cprintf("Books"); break; - case OBJ_STAVES: cprintf("Magical Staves and Rods"); break; - case OBJ_ORBS: cprintf("Orbs of Power"); break; - case OBJ_MISCELLANY: cprintf("Miscellaneous"); break; - case OBJ_CORPSES: cprintf("Carrion"); break; - //case OBJ_GEMSTONES: cprintf("Miscellaneous"); break; - } - - textcolor(LIGHTGREY); - lines++; - - for (j = 0; j < ENDOFPACK; j++) - { - if (lines > num_lines - 2 && inv_count > 0) - { - gotoxy(1, num_lines); - cprintf("-more-"); - ki = getch(); + menu.add_entry( new MenuEntry( item_class_name(i), MEL_SUBTITLE ) ); - if (ki == ESCAPE) - { -#ifdef DOS_TERM - puttext(1, 1, 80, 25, buffer); -#endif - return (ESCAPE); - } - else if (isalpha(ki) || ki == '?' || ki == '*') - { -#ifdef DOS_TERM - puttext(1, 1, 80, 25, buffer); + for (int j = 0, count = items.size(); j < count; ++j) + { + if (items[j]->base_type != i) continue; + + InvEntry *ie = new InvEntry( *items[j] ); + ie->hotkeys[0] = ckey; + + menu.add_entry( ie ); + + ckey = ckey == 'z'? 'A' : + ckey == 'Z'? 'a' : + ckey + 1; + } + } + menu.set_flags( MF_MULTISELECT | MF_SELECT_ANY_PAGE ); + std::vector< MenuEntry * > sel = menu.show(); + for (int i = 0, count = sel.size(); i < count; ++i) + { + InvEntry *inv = (InvEntry *) sel[i]; + selected.push_back( SelItem( inv->hotkeys[0], + inv->selected_qty, + inv->item ) ); + } + + return selected; +} + +static bool item_class_selected(const item_def &i, int selector) +{ + const int itype = i.base_type; + if (selector == OSEL_ANY || selector == itype) + return (true); + + switch (selector) + { + case OBJ_MISSILES: + return (itype == OBJ_MISSILES || itype == OBJ_WEAPONS); + case OBJ_WEAPONS: + case OSEL_WIELD: + return (itype == OBJ_WEAPONS || itype == OBJ_STAVES + || itype == OBJ_MISCELLANY); + case OBJ_SCROLLS: + return (itype == OBJ_SCROLLS || itype == OBJ_BOOKS); + default: + return (false); + } +} + +static bool userdef_item_selected(const item_def &i, int selector) +{ +#if defined(CLUA_BINDINGS) + const char *luafn = selector == OSEL_WIELD? "ch_item_wieldable" : + NULL; + return (luafn && clua.callbooleanfn(false, luafn, "u", &i)); +#else + return (false); #endif - return (ki); - } +} - if (ki == 0) - ki = getch(); +static bool is_item_selected(const item_def &i, int selector) +{ + return item_class_selected(i, selector) + || userdef_item_selected(i, selector); +} - lines = 0; - clrscr(); - gotoxy(1, 1); - anything = 0; - } +static void get_inv_items_to_show(std::vector<item_def*> &v, int selector) +{ + for (int i = 0; i < ENDOFPACK; i++) + { + if (is_valid_item(you.inv[i]) && is_item_selected(you.inv[i], selector)) + v.push_back( &you.inv[i] ); + } +} - if (is_valid_item(you.inv[j]) && you.inv[j].base_type==i) - { - anything++; +static void set_vectitem_classes(const std::vector<item_def*> &v, + FixedVector<int, NUM_OBJECT_CLASSES> &fv) +{ + for (int i = 0; i < NUM_OBJECT_CLASSES; i++) + fv[i] = 0; + + for (int i = 0, size = v.size(); i < size; i++) + fv[ v[i]->base_type ]++; +} - if (lines > 0) - cprintf(EOL); +unsigned char invent_select( + int item_selector, + int flags, + std::string (*titlefn)( int menuflags, + const std::string &oldt ), + std::vector<SelItem> *items, + std::vector<text_pattern> *filter, + Menu::selitem_tfn selitemfn ) +{ + InvMenu menu; + + menu.selitem_text = selitemfn; + if (filter) + menu.set_select_filter( *filter ); - lines++; + FixedVector< int, NUM_OBJECT_CLASSES > inv_class2; + for (int i = 0; i < NUM_OBJECT_CLASSES; i++) + inv_class2[i] = 0; - yps = wherey(); + int inv_count = 0; - in_name( j, DESC_INVENTORY_EQUIP, st_pass ); - cprintf( st_pass ); + for (int i = 0; i < ENDOFPACK; i++) + { + if (you.inv[i].quantity) + { + inv_class2[ you.inv[i].base_type ]++; + inv_count++; + } + } - inv_count--; + if (!inv_count) + { + menu.set_title( new MenuEntry( "You aren't carrying anything." ) ); + menu.show(); + return 0; + } + std::vector<item_def*> tobeshown; + get_inv_items_to_show( tobeshown, item_selector ); + set_vectitem_classes( tobeshown, inv_class2 ); - if (show_price) - { - cprintf(" ("); + if (tobeshown.size()) + { + const int cap = carrying_capacity(); - itoa( item_value( you.inv[j], temp_id, true ), - tmp_quant, 10 ); + char title_buf[200]; + snprintf( title_buf, sizeof title_buf, + "Inventory: %d.%d/%d.%d aum (%d%%, %d/52 slots)", + you.burden / 10, you.burden % 10, + cap / 10, cap % 10, + (you.burden * 100) / cap, + inv_count ); + menu.set_title( new InvTitle( &menu, title_buf, titlefn ) ); - cprintf( tmp_quant ); - cprintf( " gold)" ); - } + for (int i = 0; i < 15; i++) + { + if (inv_class2[i] != 0) + { + std::string s = item_class_name(i); + menu.add_entry( new MenuEntry( s, MEL_SUBTITLE ) ); - if (wherey() != yps) - lines++; + for (int j = 0, size = tobeshown.size(); j < size; ++j) + { + if (tobeshown[j]->base_type == i) + { + menu.add_entry( new InvEntry( *tobeshown[j] ) ); } } // end of j loop } // end of if inv_class2 @@ -270,43 +501,41 @@ unsigned char invent( int item_class_inv, bool show_price ) } else { - if (item_class_inv == -1) - cprintf("You aren't carrying anything."); + std::string s; + if (item_selector == -1) + s = "You aren't carrying anything."; else { - if (item_class_inv == OBJ_WEAPONS) - cprintf("You aren't carrying any weapons."); - else if (item_class_inv == OBJ_MISSILES) - cprintf("You aren't carrying any ammunition."); + if (item_selector == OBJ_WEAPONS || item_selector == OSEL_WIELD) + s = "You aren't carrying any weapons."; + else if (item_selector == OBJ_MISSILES) + s = "You aren't carrying any ammunition."; else - cprintf("You aren't carrying any such object."); - - anything++; + s = "You aren't carrying any such object."; } + menu.set_title( new MenuEntry( s ) ); } - if (anything > 0) + menu.set_flags( flags ); + std::vector< MenuEntry * > sel = menu.show(); + if (items) { - ki = getch(); - - if (isalpha(ki) || ki == '?' || ki == '*') - { -#ifdef DOS_TERM - puttext(1, 1, 80, 25, buffer); -#endif - return (ki); - } - - if (ki == 0) - ki = getch(); + for (int i = 0, count = sel.size(); i < count; ++i) + items->push_back( SelItem( sel[i]->hotkeys[0], + sel[i]->selected_qty ) ); } - putty: -#ifdef DOS_TERM - puttext(1, 1, 80, 25, buffer); -#endif + unsigned char mkey = menu.getkey(); + if (!isalnum(mkey) && mkey != '$' && mkey != '-' && mkey != '?' + && mkey != '*') + mkey = ' '; + return mkey; +} - return (ki); +unsigned char invent( int item_class_inv, bool show_price ) +{ + InvShowPrices show_item_prices(show_price); + return (invent_select(item_class_inv)); } // end invent() @@ -337,6 +566,140 @@ static unsigned char get_invent_quant( unsigned char keyin, int &quant ) return (keyin); } +// This function prompts the user for an item, handles the '?' and '*' +// listings, and returns the inventory slot to the caller (which if +// must_exist is true (the default) will be an assigned item, with +// a positive quantity. +// +// It returns PROMPT_ABORT if the player hits escape. +// It returns PROMPT_GOT_SPECIAL if the player hits the "other_valid_char". +// +// Note: This function never checks if the item is appropriate. +std::vector<SelItem> prompt_invent_items( + const char *prompt, + int type_expect, + std::string (*titlefn)( int menuflags, + const std::string &oldt ), + bool allow_auto_list, + bool allow_easy_quit, + const char other_valid_char, + std::vector<text_pattern> *select_filter, + Menu::selitem_tfn fn ) +{ + unsigned char keyin = 0; + int ret = -1; + + bool need_redraw = false; + bool need_prompt = true; + bool need_getch = true; + + if (Options.auto_list && allow_auto_list) + { + need_getch = false; + need_redraw = false; + need_prompt = false; + keyin = '?'; + } + + std::vector< SelItem > items; + int count = -1; + for (;;) + { + if (need_redraw) + { + redraw_screen(); + mesclr( true ); + } + + if (need_prompt) + mpr( prompt, MSGCH_PROMPT ); + + if (need_getch) + keyin = get_ch(); + + need_redraw = false; + need_prompt = true; + need_getch = true; + + // Note: We handle any "special" character first, so that + // it can be used to override the others. + if (other_valid_char != '\0' && keyin == other_valid_char) + { + ret = PROMPT_GOT_SPECIAL; + break; + } + else if (keyin == '?' || keyin == '*' || keyin == ',') + { + int selmode = Options.drop_mode == DM_SINGLE? + MF_SINGLESELECT | MF_EASY_EXIT | MF_ANYPRINTABLE : + MF_MULTISELECT; + // The "view inventory listing" mode. + int ch = invent_select( + keyin == '*'? -1 : type_expect, + selmode | MF_SELECT_ANY_PAGE, + titlefn, &items, select_filter, fn ); + + if (selmode & MF_SINGLESELECT) + { + keyin = ch; + need_getch = false; + } + else + { + keyin = 0; + need_getch = true; + } + + if (items.size()) + { + redraw_screen(); + mesclr( true ); + + for (int i = 0, count = items.size(); i < count; ++i) + items[i].slot = letter_to_index( items[i].slot ); + return items; + } + + need_redraw = !(keyin == '?' || keyin == '*' + || keyin == ',' || keyin == '+'); + need_prompt = need_redraw; + } + else if (isdigit( keyin )) + { + // The "read in quantity" mode + keyin = get_invent_quant( keyin, count ); + + need_prompt = false; + need_getch = false; + } + else if (keyin == ESCAPE + || (Options.easy_quit_item_prompts + && allow_easy_quit + && keyin == ' ')) + { + ret = PROMPT_ABORT; + break; + } + else if (isalpha( keyin )) + { + ret = letter_to_index( keyin ); + + if (!is_valid_item( you.inv[ret] )) + mpr( "You do not have any such object." ); + else + break; + } + else if (!isspace( keyin )) + { + // we've got a character we don't understand... + canned_msg( MSG_HUH ); + } + } + + if (ret != PROMPT_ABORT) + items.push_back( SelItem( ret, count ) ); + return items; +} // This function prompts the user for an item, handles the '?' and '*' // listings, and returns the inventory slot to the caller (which if @@ -362,8 +725,22 @@ int prompt_invent_item( const char *prompt, int type_expect, if (Options.auto_list && allow_auto_list) { + std::vector< SelItem > items; + // pretend the player has hit '?' and setup state. - keyin = invent( type_expect, false ); + keyin = invent_select( type_expect, + MF_SINGLESELECT | MF_ANYPRINTABLE + | MF_EASY_EXIT, + NULL, &items ); + + if (items.size()) + { + if (count) + *count = items[0].quantity; + redraw_screen(); + mesclr( true ); + return letter_to_index( keyin ); + } need_getch = false; @@ -402,10 +779,21 @@ int prompt_invent_item( const char *prompt, int type_expect, else if (keyin == '?' || keyin == '*') { // The "view inventory listing" mode. - if (keyin == '*') - keyin = invent( -1, false ); - else - keyin = invent( type_expect, false ); + std::vector< SelItem > items; + keyin = invent_select( keyin == '*'? OSEL_ANY : type_expect, + MF_SINGLESELECT | MF_ANYPRINTABLE + | MF_EASY_EXIT, + NULL, + &items ); + + if (items.size()) + { + if (count) + *count = items[0].quantity; + redraw_screen(); + mesclr( true ); + return letter_to_index( keyin ); + } need_getch = false; @@ -619,7 +1007,15 @@ const char *command_string( int i ) (i == 450) ? "Ctrl-X : Save game without query" : #ifdef ALLOW_DESTROY_ITEM_COMMAND - (i == 455) ? "Ctrl-D : Destroy inventory item" : + (i == 451) ? "Ctrl-D : Destroy inventory item" : +#endif + (i == 453) ? "Ctrl-G : interlevel travel" : + (i == 455) ? "Ctrl-O : explore" : + +#ifdef STASH_TRACKING + (i == 456) ? "Ctrl-S : mark stash" : + (i == 457) ? "Ctrl-E : forget stash" : + (i == 458) ? "Ctrl-F : search stashes" : #endif (i == 460) ? "Shift & DIR : long walk" : |