summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/invent.cc
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-22 08:41:20 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2006-11-22 08:41:20 +0000
commit1d0f57cbceb778139ca215cc4fcfd1584951f6dd (patch)
treecafd60c944c51fcce778aa5d6912bc548c518339 /crawl-ref/source/invent.cc
parent6f5e187a9e5cd348296dba2fd89d2e206e775a01 (diff)
downloadcrawl-ref-1d0f57cbceb778139ca215cc4fcfd1584951f6dd.tar.gz
crawl-ref-1d0f57cbceb778139ca215cc4fcfd1584951f6dd.zip
Merged stone_soup r15:451 into trunk.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@452 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/invent.cc')
-rw-r--r--crawl-ref/source/invent.cc995
1 files changed, 430 insertions, 565 deletions
diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc
index 2145f80f72..437b01c4fc 100644
--- a/crawl-ref/source/invent.cc
+++ b/crawl-ref/source/invent.cc
@@ -3,6 +3,8 @@
* Summary: Functions for inventory related commands.
* Written by: Linley Henzell
*
+ * Modified for Crawl Reference by $Author$ on $Date$
+ *
* Change History (most recent first):
*
* <5> 10/9/99 BCR Added wizard help screen
@@ -35,199 +37,341 @@
#include "view.h"
#include "menu.h"
-const char *command_string( int i );
-const char *wizard_string( int i );
+///////////////////////////////////////////////////////////////////////////////
+// Inventory menu shenanigans
+
+static void get_inv_items_to_show(
+ std::vector<const item_def*> &v, int selector);
-struct InvTitle : public MenuEntry
+InvTitle::InvTitle( Menu *mn, const std::string &title,
+ invtitle_annotator tfn )
+ : MenuEntry( title, MEL_TITLE )
{
- 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;
+}
+
+std::string InvTitle::get_text() const
+{
+ return titlefn? titlefn( m, MenuEntry::get_text() ) :
+ MenuEntry::get_text();
+}
+
+InvEntry::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;
+
+ if (i.base_type != OBJ_GOLD && in_inventory(i))
{
- m = mn;
- titlefn = tfn;
+ // FIXME: This is HORRIBLE! We're skipping the inventory letter prefix
+ // which looks like this: "a - ".
+ text = text.substr( 4 );
+ add_hotkey(index_to_letter( i.link ));
}
-
- std::string get_text() const
+ else
{
- return titlefn? titlefn( m->get_flags(), MenuEntry::get_text() ) :
- MenuEntry::get_text();
+ // Dummy hotkey for gold or non-inventory items.
+ add_hotkey(' ');
}
-};
+ add_class_hotkeys(i);
+
+ quantity = i.quantity;
+}
-class InvShowPrices;
-class InvEntry : public MenuEntry
+std::string InvEntry::get_text() const
{
-private:
- static bool show_prices;
- static char temp_id[4][50];
- static void set_show_prices(bool doshow);
+ char buf[ITEMNAME_SIZE];
+ char suffix[ITEMNAME_SIZE] = "";
- friend class InvShowPrices;
-public:
- const item_def *item;
+ 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);
+}
- InvEntry( const item_def &i ) : MenuEntry( "", MEL_ITEM ), item( &i )
+void InvEntry::add_class_hotkeys(const item_def &i)
+{
+ switch (i.base_type)
{
- 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;
+ 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;
+ }
+}
- 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);
+bool InvEntry::show_prices = false;
+char InvEntry::temp_id[4][50];
- quantity = i.quantity;
+void InvEntry::set_show_prices(bool doshow)
+{
+ if ((show_prices = doshow))
+ {
+ memset(temp_id, 1, sizeof temp_id);
}
+}
+
+InvShowPrices::InvShowPrices(bool doshow)
+{
+ InvEntry::set_show_prices(doshow);
+}
+
+InvShowPrices::~InvShowPrices()
+{
+ InvEntry::set_show_prices(false);
+}
+
+// Returns vector of item_def pointers to each item_def in the given
+// vector. Note: make sure the original vector stays around for the lifetime
+// of the use of the item pointers, or mayhem results!
+std::vector<const item_def*>
+InvMenu::xlat_itemvect(const std::vector<item_def> &v)
+{
+ std::vector<const item_def*> xlatitems;
+ for (unsigned i = 0, size = v.size(); i < size; ++i)
+ xlatitems.push_back( &v[i] );
+ return (xlatitems);
+}
+
+void InvMenu::set_type(menu_type t)
+{
+ type = t;
+}
+
+void InvMenu::set_title_annotator(invtitle_annotator afn)
+{
+ title_annotate = afn;
+}
+
+void InvMenu::set_title(MenuEntry *t)
+{
+ Menu::set_title(t);
+}
- std::string get_text() const
+void InvMenu::set_preselect(const std::vector<SelItem> *pre)
+{
+ pre_select = pre;
+}
+
+void InvMenu::set_title(const std::string &s)
+{
+ std::string stitle = s;
+ if (stitle.empty())
{
- char buf[ITEMNAME_SIZE];
- char suffix[ITEMNAME_SIZE] = "";
+ const int cap = carrying_capacity();
- 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);
+ 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() );
+ stitle = title_buf;
}
-private:
- void add_class_hotkeys(const item_def &i)
+
+ set_title(new InvTitle(this, stitle, title_annotate));
+}
+
+void InvMenu::load_inv_items(int item_selector,
+ MenuEntry *(*procfn)(MenuEntry *me))
+{
+ std::vector<const item_def *> tobeshown;
+ get_inv_items_to_show(tobeshown, item_selector);
+
+ load_items(tobeshown, procfn);
+ if (!item_count())
{
- switch (i.base_type)
+ std::string s;
+ switch (item_selector)
{
- case OBJ_GOLD:
- add_hotkey('$');
- break;
- case OBJ_MISSILES:
- add_hotkey('(');
+ case OSEL_ANY:
+ s = "You aren't carrying anything.";
break;
+ case OSEL_WIELD:
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('&');
+ s = "You aren't carrying any weapons.";
break;
default:
+ s = "You aren't carrying any such object.";
break;
}
+ set_title(s);
}
-};
+ else
+ {
+ set_title("");
+ }
+}
-bool InvEntry::show_prices = false;
-char InvEntry::temp_id[4][50];
+static bool compare_menu_entries(const MenuEntry* a, const MenuEntry* b)
+{
+ return (*a < *b);
+}
-void InvEntry::set_show_prices(bool doshow)
+void InvMenu::load_items(const std::vector<const item_def*> &mitems,
+ MenuEntry *(*procfn)(MenuEntry *me))
{
- if ((show_prices = doshow))
+ FixedVector< int, NUM_OBJECT_CLASSES > inv_class(0);
+ for (int i = 0, count = mitems.size(); i < count; ++i)
+ inv_class[ mitems[i]->base_type ]++;
+
+ menu_letter ckey;
+ std::vector<InvEntry*> items_in_class;
+
+ for (int i = 0; i < NUM_OBJECT_CLASSES; ++i)
{
- memset(temp_id, 1, sizeof temp_id);
+ if (!inv_class[i]) continue;
+
+ add_entry( new MenuEntry( item_class_name(i), MEL_SUBTITLE ) );
+ items_in_class.clear();
+
+ for (int j = 0, count = mitems.size(); j < count; ++j)
+ {
+ if (mitems[j]->base_type != i) continue;
+ items_in_class.push_back( new InvEntry(*mitems[j]) );
+ }
+
+ if (Options.sort_menus)
+ std::sort( items_in_class.begin(), items_in_class.end(),
+ compare_menu_entries );
+
+ for (unsigned int j = 0; j < items_in_class.size(); ++j)
+ {
+ InvEntry *ie = items_in_class[j];
+ // If there's no hotkey, provide one.
+ if (ie->hotkeys[0] == ' ')
+ ie->hotkeys[0] = ckey++;
+ do_preselect(ie);
+
+ add_entry( procfn? (*procfn)(ie) : ie );
+ }
}
}
-class InvShowPrices {
-public:
- InvShowPrices(bool doshow = true)
- {
- InvEntry::set_show_prices(doshow);
- }
- ~InvShowPrices()
- {
- InvEntry::set_show_prices(false);
- }
-};
+void InvMenu::do_preselect(InvEntry *ie)
+{
+ if (!pre_select || pre_select->empty())
+ return;
-class InvMenu : public Menu
+ for (int i = 0, size = pre_select->size(); i < size; ++i)
+ if (ie->item && ie->item == (*pre_select)[i].item)
+ {
+ ie->selected_qty = (*pre_select)[i].quantity;
+ break;
+ }
+}
+
+std::vector<SelItem> InvMenu::get_selitems() const
{
-public:
- InvMenu(int flags = MF_MULTISELECT) : Menu(flags) { }
-protected:
- bool process_key(int key);
-};
+ std::vector<SelItem> selected_items;
+ for (int i = 0, count = sel.size(); i < count; ++i)
+ {
+ InvEntry *inv = dynamic_cast<InvEntry*>(sel[i]);
+ selected_items.push_back(
+ SelItem(
+ inv->hotkeys[0],
+ inv->selected_qty,
+ inv->item ) );
+ }
+ return (selected_items);
+}
bool InvMenu::process_key( int key )
{
- if (items.size() && (key == CONTROL('D') || key == '@'))
+ if (items.size()
+ && type == MT_DROP
+ && (key == CONTROL('D') || key == '@'))
{
- int newflag =
+ int newflag =
is_set(MF_MULTISELECT)?
- MF_SINGLESELECT | MF_EASY_EXIT | MF_ANYPRINTABLE
+ MF_SINGLESELECT | MF_ANYPRINTABLE
: MF_MULTISELECT;
- flags &= ~(MF_SINGLESELECT | MF_MULTISELECT |
- MF_EASY_EXIT | MF_ANYPRINTABLE);
+ flags &= ~(MF_SINGLESELECT | MF_MULTISELECT | MF_ANYPRINTABLE);
flags |= newflag;
deselect_all();
- sel->clear();
- draw_select_count(0);
+ sel.clear();
+ draw_select_count(0, true);
return true;
}
return Menu::process_key( key );
}
+unsigned char InvMenu::getkey() const
+{
+ unsigned char mkey = lastch;
+ // Fake an ESCAPE if the menu is empty.
+ if (!item_count())
+ mkey = ESCAPE;
+ if (!isalnum(mkey) && mkey != '$' && mkey != '-' && mkey != '?'
+ && mkey != '*' && mkey != ESCAPE)
+ mkey = ' ';
+ return (mkey);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
bool in_inventory( const item_def &i )
{
return i.x == -1 && i.y == -1;
@@ -235,10 +379,8 @@ bool in_inventory( const item_def &i )
unsigned char get_invent( int invent_type )
{
- unsigned char nothing = invent_select( invent_type );
-
+ unsigned char nothing = invent_select(NULL, MT_INVLIST, invent_type);
redraw_screen();
-
return (nothing);
} // end get_invent()
@@ -291,84 +433,20 @@ std::string item_class_name( int type, bool terse )
return ("");
}
-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)
- {
- if (!inv_class[i]) continue;
-
- menu->add_entry( new MenuEntry( item_class_name(i), MEL_SUBTITLE ) );
-
- 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++;
- callback(ie);
-
- menu->add_entry( ie );
- }
- }
-}
-
-std::vector<SelItem> select_items( std::vector<item_def*> &items,
- const char *title )
+std::vector<SelItem> select_items( const std::vector<const item_def*> &items,
+ const char *title, bool noselect )
{
std::vector<SelItem> selected;
-
- 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 ]++;
-
- Menu menu;
- menu.set_title( new MenuEntry(title) );
-
- char ckey = 'a';
- for (int i = 0; i < NUM_OBJECT_CLASSES; ++i)
+ if (!items.empty())
{
- if (!inv_class[i]) continue;
-
- menu.add_entry( new MenuEntry( item_class_name(i), MEL_SUBTITLE ) );
-
- 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 ) );
+ InvMenu menu;
+ menu.set_title(title);
+ menu.load_items(items);
+ menu.set_flags(noselect ? MF_NOSELECT : MF_MULTISELECT);
+ menu.show();
+ selected = menu.get_selitems();
}
-
- return selected;
+ return (selected);
}
static bool item_class_selected(const item_def &i, int selector)
@@ -409,7 +487,7 @@ static bool is_item_selected(const item_def &i, int selector)
|| userdef_item_selected(i, selector);
}
-static void get_inv_items_to_show(std::vector<item_def*> &v, int selector)
+static void get_inv_items_to_show(std::vector<const item_def*> &v, int selector)
{
for (int i = 0; i < ENDOFPACK; i++)
{
@@ -418,127 +496,45 @@ static void get_inv_items_to_show(std::vector<item_def*> &v, int selector)
}
}
-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 ]++;
-}
-
unsigned char invent_select(
+ const char *title,
+ menu_type type,
int item_selector,
int flags,
- std::string (*titlefn)( int menuflags,
- const std::string &oldt ),
+ invtitle_annotator titlefn,
std::vector<SelItem> *items,
std::vector<text_pattern> *filter,
- Menu::selitem_tfn selitemfn )
+ Menu::selitem_tfn selitemfn,
+ const std::vector<SelItem> *pre_select )
{
- InvMenu menu;
+ InvMenu menu(flags);
- menu.selitem_text = selitemfn;
+ menu.set_preselect(pre_select);
+ menu.set_title_annotator(titlefn);
+ menu.f_selitem = selitemfn;
if (filter)
menu.set_select_filter( *filter );
+ menu.load_inv_items(item_selector);
+ menu.set_type(type);
- FixedVector< int, NUM_OBJECT_CLASSES > inv_class2;
- for (int i = 0; i < NUM_OBJECT_CLASSES; i++)
- inv_class2[i] = 0;
+ // Don't override title if there are no items.
+ if (title && menu.item_count())
+ menu.set_title(title);
- int inv_count = 0;
+ menu.show(true);
- for (int i = 0; i < ENDOFPACK; i++)
- {
- if (you.inv[i].quantity)
- {
- inv_class2[ you.inv[i].base_type ]++;
- 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 (tobeshown.size())
- {
- const int cap = carrying_capacity();
-
- 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 ) );
-
- 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 ) );
-
- 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
- } // end of i loop.
- }
- else
- {
- std::string s;
- if (item_selector == -1)
- s = "You aren't carrying anything.";
- else
- {
- 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
- s = "You aren't carrying any such object.";
- }
- menu.set_title( new MenuEntry( s ) );
- }
-
- menu.set_flags( flags );
- std::vector< MenuEntry * > sel = menu.show();
if (items)
- {
- for (int i = 0, count = sel.size(); i < count; ++i)
- items->push_back( SelItem( sel[i]->hotkeys[0],
- sel[i]->selected_qty ) );
- }
+ *items = menu.get_selitems();
- unsigned char mkey = menu.getkey();
- if (!isalnum(mkey) && mkey != '$' && mkey != '-' && mkey != '?'
- && mkey != '*')
- mkey = ' ';
- return mkey;
+ return (menu.getkey());
}
unsigned char invent( int item_class_inv, bool show_price )
{
InvShowPrices show_item_prices(show_price);
- return (invent_select(item_class_inv));
+ return (invent_select(NULL, MT_INVLIST, item_class_inv));
} // end invent()
-
// Reads in digits for a count and apprends then to val, the
// return value is the character that stopped the reading.
static unsigned char get_invent_quant( unsigned char keyin, int &quant )
@@ -577,31 +573,31 @@ static unsigned char get_invent_quant( unsigned char keyin, int &quant )
// Note: This function never checks if the item is appropriate.
std::vector<SelItem> prompt_invent_items(
const char *prompt,
+ menu_type mtype,
int type_expect,
- std::string (*titlefn)( int menuflags,
- const std::string &oldt ),
+ invtitle_annotator titlefn,
bool allow_auto_list,
bool allow_easy_quit,
const char other_valid_char,
std::vector<text_pattern> *select_filter,
- Menu::selitem_tfn fn )
+ Menu::selitem_tfn fn,
+ const std::vector<SelItem> *pre_select )
{
unsigned char keyin = 0;
- int ret = -1;
+ int ret = PROMPT_ABORT;
bool need_redraw = false;
bool need_prompt = true;
bool need_getch = true;
+ bool auto_list = Options.auto_list && allow_auto_list;
- if (Options.auto_list && allow_auto_list)
+ if (auto_list)
{
- need_getch = false;
- need_redraw = false;
- need_prompt = false;
+ need_prompt = need_getch = false;
keyin = '?';
}
- std::vector< SelItem > items;
+ std::vector<SelItem> items;
int count = -1;
for (;;)
{
@@ -630,16 +626,21 @@ std::vector<SelItem> prompt_invent_items(
}
else if (keyin == '?' || keyin == '*' || keyin == ',')
{
- int selmode = Options.drop_mode == DM_SINGLE?
- MF_SINGLESELECT | MF_EASY_EXIT | MF_ANYPRINTABLE :
- MF_MULTISELECT;
+ int selmode =
+ Options.drop_mode == DM_SINGLE
+ && (!pre_select || pre_select->empty())?
+ 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)
+ prompt,
+ mtype,
+ keyin == '*'? OSEL_ANY : type_expect,
+ selmode,
+ titlefn, &items, select_filter, fn,
+ pre_select );
+
+ if ((selmode & MF_SINGLESELECT) || ch == ESCAPE)
{
keyin = ch;
need_getch = false;
@@ -653,11 +654,11 @@ std::vector<SelItem> prompt_invent_items(
if (items.size())
{
redraw_screen();
- mesclr( true );
+ mesclr(true);
- for (int i = 0, count = items.size(); i < count; ++i)
+ for (unsigned int i = 0; i < items.size(); ++i)
items[i].slot = letter_to_index( items[i].slot );
- return items;
+ return (items);
}
need_redraw = !(keyin == '?' || keyin == '*'
@@ -694,6 +695,11 @@ std::vector<SelItem> prompt_invent_items(
// we've got a character we don't understand...
canned_msg( MSG_HUH );
}
+ else
+ {
+ // We're going to loop back up, so don't draw another prompt.
+ need_prompt = false;
+ }
}
if (ret != PROMPT_ABORT)
@@ -701,6 +707,52 @@ std::vector<SelItem> prompt_invent_items(
return items;
}
+static int digit_to_index( char digit, operation_types oper ) {
+
+ int i;
+ unsigned int j;
+ char iletter = (char)(oper);
+
+ for ( i = 0; i < ENDOFPACK; ++i ) {
+ if (is_valid_item(you.inv[i])) {
+ const std::string& r(you.inv[i].inscription);
+ /* note that r.size() is unsigned */
+ for ( j = 0; j + 2 < r.size(); ++j ) {
+ if ( r[j] == '@' &&
+ (r[j+1] == iletter || r[j+1] == '*') &&
+ r[j+2] == digit ) {
+ return i;
+ }
+ }
+ }
+ }
+ return -1;
+}
+
+/* return true if user OK'd it (or no warning), false otherwise */
+static bool check_warning_inscriptions( const item_def& item,
+ operation_types oper )
+{
+ unsigned int i;
+ char iletter = (char)(oper);
+ char name[ITEMNAME_SIZE];
+ char prompt[ITEMNAME_SIZE + 100];
+ item_name(item, DESC_INVENTORY, name, false);
+ strcpy( prompt, "Really choose ");
+ strncat( prompt, name, ITEMNAME_SIZE );
+ strcat( prompt, "?");
+
+ const std::string& r(item.inscription);
+ for ( i = 0; i + 1 < r.size(); ++i ) {
+ if ( r[i] == '!' &&
+ (r[i+1] == iletter || r[i+1] == '*') ) {
+
+ return yesno(prompt, false, 'n');
+ }
+ }
+ return true;
+}
+
// 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
@@ -710,45 +762,26 @@ std::vector<SelItem> prompt_invent_items(
// It returns PROMPT_GOT_SPECIAL if the player hits the "other_valid_char".
//
// Note: This function never checks if the item is appropriate.
-int prompt_invent_item( const char *prompt, int type_expect,
+int prompt_invent_item( const char *prompt,
+ menu_type mtype, int type_expect,
bool must_exist, bool allow_auto_list,
bool allow_easy_quit,
const char other_valid_char,
- int *const count )
+ int *const count,
+ operation_types oper )
{
unsigned char keyin = 0;
- int ret = -1;
+ int ret = PROMPT_ABORT;
bool need_redraw = false;
bool need_prompt = true;
bool need_getch = true;
+ bool auto_list = Options.auto_list && allow_auto_list;
- if (Options.auto_list && allow_auto_list)
+ if (auto_list)
{
- std::vector< SelItem > items;
-
- // pretend the player has hit '?' and setup state.
- 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;
-
- // Don't redraw if we're just going to display another listing
- need_redraw = (keyin != '?' && keyin != '*');
-
- // A prompt is nice for when we're moving to "count" mode.
- need_prompt = (count != NULL && isdigit( keyin ));
+ need_prompt = need_getch = false;
+ keyin = '?';
}
for (;;)
@@ -780,11 +813,14 @@ int prompt_invent_item( const char *prompt, int type_expect,
{
// The "view inventory listing" mode.
std::vector< SelItem > items;
- keyin = invent_select( keyin == '*'? OSEL_ANY : type_expect,
- MF_SINGLESELECT | MF_ANYPRINTABLE
- | MF_EASY_EXIT,
- NULL,
- &items );
+ keyin = invent_select(
+ prompt,
+ mtype,
+ keyin == '*'? OSEL_ANY : type_expect,
+ MF_SINGLESELECT | MF_ANYPRINTABLE
+ | MF_EASY_EXIT,
+ NULL,
+ &items );
if (items.size())
{
@@ -799,9 +835,7 @@ int prompt_invent_item( const char *prompt, int type_expect,
// Don't redraw if we're just going to display another listing
need_redraw = (keyin != '?' && keyin != '*');
-
- // A prompt is nice for when we're moving to "count" mode.
- need_prompt = (count != NULL && isdigit( keyin ));
+ need_prompt = need_redraw;
}
else if (count != NULL && isdigit( keyin ))
{
@@ -811,6 +845,17 @@ int prompt_invent_item( const char *prompt, int type_expect,
need_prompt = false;
need_getch = false;
}
+ /*** HP CHANGE ***/
+ else if ( count == NULL && isdigit( keyin ) )
+ {
+ /* scan for our item */
+ int res = digit_to_index( keyin, oper );
+ if ( res != -1 ) {
+ ret = res;
+ if ( check_warning_inscriptions( you.inv[ret], oper ) )
+ break;
+ }
+ }
else if (keyin == ESCAPE
|| (Options.easy_quit_item_prompts
&& allow_easy_quit
@@ -825,203 +870,23 @@ int prompt_invent_item( const char *prompt, int type_expect,
if (must_exist && !is_valid_item( you.inv[ret] ))
mpr( "You do not have any such object." );
- else
- break;
+ else {
+ if ( check_warning_inscriptions( you.inv[ret], oper ) ) {
+ break;
+ }
+ }
}
else if (!isspace( keyin ))
{
// we've got a character we don't understand...
canned_msg( MSG_HUH );
}
- }
-
- return (ret);
-}
-
-void list_commands(bool wizard)
-{
- const char *line;
- int j = 0;
-
-#ifdef DOS_TERM
- char buffer[4800];
-
- window(1, 1, 80, 25);
- gettext(1, 1, 80, 25, buffer);
-#endif
-
- clrscr();
-
- // BCR - Set to screen length - 1 to display the "more" string
- int moreLength = (get_number_of_lines() - 1) * 2;
-
- for (int i = 0; i < 500; i++)
- {
- if (wizard)
- line = wizard_string( i );
else
- line = command_string( i );
-
- if (strlen( line ) != 0)
{
- // BCR - If we've reached the end of the screen, clear
- if (j == moreLength)
- {
- gotoxy(2, j / 2 + 1);
- cprintf("More...");
- getch();
- clrscr();
- j = 0;
- }
-
- gotoxy( ((j % 2) ? 40 : 2), ((j / 2) + 1) );
- cprintf( line );
-
- j++;
+ // We're going to loop back up, so don't draw another prompt.
+ need_prompt = false;
}
}
- getch();
-
-#ifdef DOS_TERM
- puttext(1, 1, 80, 25, buffer);
-#endif
-
- return;
-} // end list_commands()
-
-const char *wizard_string( int i )
-{
- UNUSED( i );
-
-#ifdef WIZARD
- return((i == 10) ? "a : acquirement" :
- (i == 13) ? "A : set all skills to level" :
- (i == 15) ? "b : controlled blink" :
- (i == 20) ? "B : banish yourself to the Abyss" :
- (i == 30) ? "g : add a skill" :
- (i == 35) ? "G : remove all monsters" :
- (i == 40) ? "h/H : heal yourself (super-Heal)" :
- (i == 50) ? "i/I : identify/unidentify inventory":
- (i == 70) ? "l : make entrance to labyrinth" :
- (i == 80) ? "m/M : create monster by number/name":
- (i == 90) ? "o/%% : create an object" :
- (i == 100) ? "p : make entrance to pandemonium" :
- (i == 110) ? "x : gain an experience level" :
- (i == 115) ? "r : change character's species" :
- (i == 120) ? "s : gain 20000 skill points" :
- (i == 130) ? "S : set skill to level" :
- (i == 140) ? "t : tweak object properties" :
- (i == 150) ? "X : Receive a gift from Xom" :
- (i == 160) ? "z/Z : cast any spell by number/name":
- (i == 200) ? "$ : get 1000 gold" :
- (i == 210) ? "</> : create up/down staircase" :
- (i == 220) ? "u/d : shift up/down one level" :
- (i == 230) ? "~/\" : goto a level" :
- (i == 240) ? "( : create a feature" :
- (i == 250) ? "] : get a mutation" :
- (i == 260) ? "[ : get a demonspawn mutation" :
- (i == 270) ? ": : find branch" :
- (i == 280) ? "{ : magic mapping" :
- (i == 290) ? "^ : gain piety" :
- (i == 300) ? "_ : gain religion" :
- (i == 310) ? "\' : list items" :
- (i == 320) ? "? : list wizard commands" :
- (i == 330) ? "| : acquire all unrand artefacts" :
- (i == 340) ? "+ : turn item into random artefact" :
- (i == 350) ? "= : sum skill points"
- : "");
-
-#else
- return ("");
-#endif
-} // end wizard_string()
-
-const char *command_string( int i )
-{
- /*
- * BCR - Command printing, case statement
- * Note: The numbers in this case indicate the order in which the
- * commands will be printed out. Make sure none of these
- * numbers is greater than 500, because that is the limit.
- *
- * Arranged alpha lower, alpha upper, punctuation, ctrl.
- *
- */
-
- return((i == 10) ? "a : use special ability" :
- (i == 20) ? "d(#) : drop (exact quantity of) items" :
- (i == 30) ? "e : eat food" :
- (i == 40) ? "f : fire first available missile" :
- (i == 50) ? "i : inventory listing" :
- (i == 55) ? "m : check skills" :
- (i == 60) ? "o/c : open / close a door" :
- (i == 65) ? "p : pray" :
- (i == 70) ? "q : quaff a potion" :
- (i == 80) ? "r : read a scroll or book" :
- (i == 90) ? "s : search adjacent tiles" :
- (i == 100) ? "t : throw/shoot an item" :
- (i == 110) ? "v : view item description" :
- (i == 120) ? "w : wield an item" :
- (i == 130) ? "x : examine visible surroundings" :
- (i == 135) ? "z : zap a wand" :
- (i == 140) ? "A : list abilities/mutations" :
- (i == 141) ? "C : check experience" :
- (i == 142) ? "D : dissect a corpse" :
- (i == 145) ? "E : evoke power of wielded item" :
- (i == 150) ? "M : memorise a spell" :
- (i == 155) ? "O : overview of the dungeon" :
- (i == 160) ? "P/R : put on / remove jewellery" :
- (i == 165) ? "Q : quit without saving" :
- (i == 168) ? "S : save game and exit" :
- (i == 179) ? "V : version information" :
- (i == 200) ? "W/T : wear / take off armour" :
- (i == 210) ? "X : examine level map" :
- (i == 220) ? "Z : cast a spell" :
- (i == 240) ? ",/g : pick up items" :
- (i == 242) ? "./del: rest one turn" :
- (i == 250) ? "</> : ascend / descend a staircase" :
- (i == 270) ? "; : examine occupied tile" :
- (i == 280) ? "\\ : check item knowledge" :
-#ifdef WIZARD
- (i == 290) ? "& : invoke your Wizardly powers" :
-#endif
- (i == 300) ? "+/- : scroll up/down [level map only]" :
- (i == 310) ? "! : shout or command allies" :
- (i == 325) ? "^ : describe religion" :
- (i == 337) ? "@ : status" :
- (i == 340) ? "# : dump character to file" :
- (i == 350) ? "= : reassign inventory/spell letters" :
- (i == 360) ? "\' : wield item a, or switch to b" :
-#ifdef USE_MACROS
- (i == 380) ? "` : add macro" :
- (i == 390) ? "~ : save macros" :
-#endif
- (i == 400) ? "] : display worn armour" :
- (i == 410) ? "\" : display worn jewellery" :
- (i == 420) ? "Ctrl-P : see old messages" :
-#ifdef PLAIN_TERM
- (i == 430) ? "Ctrl-R : Redraw screen" :
-#endif
- (i == 440) ? "Ctrl-A : toggle autopickup" :
- (i == 450) ? "Ctrl-X : Save game without query" :
-
-#ifdef ALLOW_DESTROY_ITEM_COMMAND
- (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" :
- (i == 465) ? "/ DIR : long walk" :
- (i == 470) ? "Ctrl & DIR : door; untrap; attack" :
- (i == 475) ? "* DIR : door; untrap; attack" :
- (i == 478) ? "Shift & 5 on keypad : rest 100 turns"
- : "");
-} // end command_string()
+ return (ret);
+}