Attached Files |
use_from_floor_v6.patch [^] (19,490 bytes) 2016-05-26 04:49 [Show Content] [Hide Content]From c7d9921757a95c4936ab0acb24311ae963b8b98b Mon Sep 17 00:00:00 2001
From: Naruni <kram321@gmail.com>
Date: Wed, 25 May 2016 16:16:04 -0700
Subject: [PATCH 1/2] Drink and read items on the floor.
New class UseItemMenu displays a menu with items of requested type (via
object_selector), inventory items first then floor items.
---
crawl-ref/source/delay.cc | 25 ++++-
crawl-ref/source/describe.cc | 4 +-
crawl-ref/source/item_use.cc | 245 +++++++++++++++++++++++++++++++++----------
crawl-ref/source/item_use.h | 8 +-
4 files changed, 218 insertions(+), 64 deletions(-)
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index 4e88b0a..7eb1f13 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -506,13 +506,13 @@ bool already_learning_spell(int spell)
* @return false if the player is confused, berserk, silenced,
* has no scroll in the given slot, etc; true otherwise.
*/
-static bool _can_read_scroll(int inv_slot)
+static bool _can_read_scroll(item_def* scroll)
{
// prints its own messages
if (!player_can_read())
return false;
- const string illiteracy_reason = cannot_read_item_reason(you.inv[inv_slot]);
+ const string illiteracy_reason = cannot_read_item_reason(*scroll);
if (illiteracy_reason.empty())
return true;
@@ -681,7 +681,13 @@ void handle_delay()
}
else if (delay.type == DELAY_BLURRY_SCROLL)
{
- if (!_can_read_scroll(delay.parm1))
+ if (delay.parm2 == 0 && !_can_read_scroll(&you.inv[delay.parm1]))
+ {
+ _pop_delay();
+ you.time_taken = 0;
+ return;
+ }
+ else if (delay.parm2 == 1 && !_can_read_scroll(&mitm[delay.parm1]))
{
_pop_delay();
you.time_taken = 0;
@@ -949,8 +955,17 @@ static void _finish_delay(const delay_queue_item &delay)
case DELAY_BLURRY_SCROLL:
// Make sure the scroll still exists, the player isn't confused, etc
- if (_can_read_scroll(delay.parm1))
- read_scroll(delay.parm1);
+ if (delay.parm2 == 0 && _can_read_scroll(&you.inv[delay.parm1]))
+ {
+ item_def* scroll = &you.inv[delay.parm1];
+ read_scroll(scroll);
+ }
+ else if (delay.parm2 == 1 && _can_read_scroll(&mitm[delay.parm1]))
+ {
+ item_def* scroll = &mitm[delay.parm1];
+ read_scroll(scroll);
+ }
+
break;
case DELAY_BUTCHER:
diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc
index 58d4fd3..2e439de 100644
--- a/crawl-ref/source/describe.cc
+++ b/crawl-ref/source/describe.cc
@@ -2335,10 +2335,10 @@ static bool _do_action(item_def &item, const vector<command_type>& actions, int
case CMD_REMOVE_ARMOUR: takeoff_armour(slot); break;
case CMD_EVOKE: evoke_item(slot); break;
case CMD_EAT: eat_food(slot); break;
- case CMD_READ: read(slot); break;
+ case CMD_READ: read(&item); break;
case CMD_WEAR_JEWELLERY: puton_ring(slot); break;
case CMD_REMOVE_JEWELLERY: remove_ring(slot, true); break;
- case CMD_QUAFF: drink(slot); break;
+ case CMD_QUAFF: drink(&item); break;
case CMD_DROP: drop_item(slot, item.quantity); break;
case CMD_INSCRIBE_ITEM: inscribe_item(item); break;
case CMD_ADJUST_INVENTORY: adjust_item(slot); break;
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 81f4d8c..ef89ba6 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -68,6 +68,132 @@
#include "view.h"
#include "xom.h"
+// The menu class for using items from either inv or floor.
+// Derivative of InvMenu
+
+class UseItemMenu : public InvMenu
+{
+public:
+ vector<const item_def*> item_inv;
+ vector<const item_def*> item_floor;
+
+ void populate_list(int item_type);
+ void populate_menu();
+
+ // Constructor
+ // Requires int for item filter.
+ // Accepts:
+ // OBJ_POTIONS
+ // OBJ_SCROLLS
+ UseItemMenu (int);
+};
+
+UseItemMenu::UseItemMenu(int item_type) {
+ set_flags( MF_SINGLESELECT );
+ set_type( MT_INVLIST );
+ populate_list(item_type);
+ populate_menu();
+}
+
+void UseItemMenu::populate_list(int item_type)
+{
+ // Load inv items first
+ for (const auto &item : you.inv)
+ {
+ // Populate the vector with filter
+ if (item.defined() && item_is_selected(item, item_type))
+ item_inv.push_back(&item);
+ }
+ // Load floor items
+ item_list_on_square(item_floor, you.visible_igrd(you.pos()));
+ // Filter
+ erase_if(item_floor, [=](const item_def* item)
+ {
+ return !item_is_selected(*item,item_type);
+ });
+}
+
+void UseItemMenu::populate_menu()
+{
+ // Load the inv items first, they have a hotkey
+ MenuEntry *me = new MenuEntry("Inv Items", MEL_TITLE, 0, 0, false);
+ add_entry(me);
+ load_items(item_inv, 0, 0, false);
+
+ // Need a tracker for inv item hotkeys and floor item hotkeys
+ set<char> keys_unused;
+ for (int i = 0; i < 52; ++i)
+ keys_unused.insert(index_to_letter(i));
+
+ // Remove inventory item hotkeys from the tracker
+ for (MenuEntry *entry : items)
+ {
+ if (!entry->hotkeys.empty())
+ keys_unused.erase(char(entry->hotkeys[0]));
+ }
+
+ // Load floor items to menu
+ me = new MenuEntry("Floor Items", MEL_TITLE, 0, 0, false);
+ add_entry(me);
+
+ load_items(item_floor, 0, 0, false);
+
+ // Go through each menu item
+ for (MenuEntry* entry : items)
+ {
+ // Make an InvEntry out of it
+ auto ie = dynamic_cast<InvEntry *>(entry);
+ // If this is an inventory item, leave its hotkeys alone
+ if (!entry->hotkeys.empty() && ie && !in_inventory(*(ie->item)))
+ {
+ if (keys_unused.empty())
+ entry->hotkeys[0] = (' ');
+ else
+ {
+ // Give it the next unused hotkey
+ auto it = keys_unused.begin();
+ auto hotkey = *it;
+ entry->hotkeys[0] = hotkey;
+ keys_unused.erase(it);
+ }
+ }
+ }
+ return;
+}
+
+/*
+ * Prompt use of a consumable from either player inventory or the floor.
+ *
+ * This function generates a menu containing type_expect items based on the
+ * object_class_type to be acted on by another function. First it will list
+ * items in inventory, then items on the floor. If player cancels out of menu,
+ * nullptr is returned.
+ *
+ * @param object_class_type The desired command which will decide item types.
+ * OBJ_POTIONS and OBJ_SCROLLS are valid.
+ *
+ * @return A chosen item_def*, or nullptr.
+ */
+
+item_def* _use_an_item(int item_type)
+{
+ // Init the menu
+ UseItemMenu menu (item_type);
+
+ vector<MenuEntry*> sel = menu.show(true);
+
+ if (sel.empty())
+ return nullptr;
+
+ ASSERT(sel.size() == 1);
+
+ auto ie = dynamic_cast<InvEntry *>(sel[0]);
+ item_def* target = const_cast<item_def*>(ie->item);
+
+ redraw_screen();
+ return target;
+}
+
static bool _safe_to_remove_or_wear(const item_def &item, bool remove,
bool quiet = false);
@@ -1652,7 +1778,7 @@ static void _vampire_corpse_help()
mpr("Use <w>e</w> to drain blood from corpses.");
}
-void drink(int slot)
+void drink(item_def* potion)
{
if (you_foodless(true))
{
@@ -1686,33 +1812,30 @@ void drink(int slot)
return;
}
- if (slot == -1)
+ if (!potion)
{
- slot = prompt_invent_item("Drink which item?",
- MT_INVLIST, OBJ_POTIONS,
- true, true, true, 0, -1, nullptr,
- OPER_QUAFF);
- if (prompt_failed(slot))
+ potion = _use_an_item(OBJ_POTIONS);
+
+ if (!potion)
{
- _vampire_corpse_help();
- return;
+ int slot = PROMPT_ABORT;
+ if (prompt_failed(slot))
+ {
+ _vampire_corpse_help();
+ return;
+ }
}
}
- item_def& potion = you.inv[slot];
-
- if (potion.base_type != OBJ_POTIONS)
+ if (potion->base_type != OBJ_POTIONS)
{
- if (you.species == SP_VAMPIRE && potion.base_type == OBJ_CORPSES)
- eat_food(slot);
- else
- mpr("You can't drink that!");
+ mpr("You can't drink that!");
return;
}
- const bool alreadyknown = item_type_known(potion);
+ const bool alreadyknown = item_type_known(*potion);
- if (alreadyknown && is_bad_item(potion, true))
+ if (alreadyknown && is_bad_item(*potion, true))
{
canned_msg(MSG_UNTHINKING_ACT);
return;
@@ -1723,7 +1846,6 @@ void drink(int slot)
// potions on monsters.
const bool dangerous = (player_in_a_dangerous_place()
&& you.experience_level > 1);
- potion_type pot_type = (potion_type)potion.sub_type;
if (player_under_penance(GOD_GOZAG) && one_chance_in(3))
{
@@ -1732,7 +1854,7 @@ void drink(int slot)
return;
}
- if (!quaff_potion(potion))
+ if (!quaff_potion(*potion))
return;
if (!alreadyknown && dangerous)
@@ -1741,17 +1863,22 @@ void drink(int slot)
// a dangerous monster nearby...
xom_is_stimulated(200);
}
- if (is_blood_potion(potion))
+ if (is_blood_potion(*potion))
{
// Always drink oldest potion.
- remove_oldest_perishable_item(potion);
+ remove_oldest_perishable_item(*potion);
}
- dec_inv_item_quantity(slot, 1);
+ if (in_inventory(*potion))
+ {
+ dec_inv_item_quantity(potion->link, 1);
+ auto_assign_item_slot(*potion);
+ }
+ else
+ dec_mitm_item_quantity(potion->index(), 1);
count_action(CACT_USE, OBJ_POTIONS);
- auto_assign_item_slot(potion);
you.turn_is_over = true;
// This got deferred from PotionExperience::effect to prevent SIGHUP abuse.
- if (pot_type == POT_EXPERIENCE)
+ if (potion->sub_type == POT_EXPERIENCE)
level_change();
}
@@ -2252,7 +2379,7 @@ void random_uselessness()
}
}
-static void _handle_read_book(int item_slot)
+static void _handle_read_book(item_def* book)
{
if (you.berserk())
{
@@ -2266,18 +2393,18 @@ static void _handle_read_book(int item_slot)
return;
}
- item_def& book(you.inv[item_slot]);
- ASSERT(book.sub_type != BOOK_MANUAL);
+ //item_def& book = item;
+ ASSERT(book->sub_type != BOOK_MANUAL);
#if TAG_MAJOR_VERSION == 34
- if (book.sub_type == BOOK_BUGGY_DESTRUCTION)
+ if (book->sub_type == BOOK_BUGGY_DESTRUCTION)
{
mpr("This item has been removed, sorry!");
return;
}
#endif
- read_book(book);
+ read_book(*book);
}
static void _vulnerability_scroll()
@@ -2467,37 +2594,37 @@ string cannot_read_item_reason(const item_def &item)
* @param slot The slot of the item in the player's inventory. If -1, the
* player is prompted to choose a slot.
*/
-void read(int slot)
+void read(item_def* scroll)
{
if (!player_can_read())
return;
- int item_slot = (slot != -1) ? slot
- : prompt_invent_item("Read which item?",
- MT_INVLIST,
- OBJ_SCROLLS,
- true, true, true, 0, -1,
- nullptr, OPER_READ);
-
- if (prompt_failed(item_slot))
- return;
+ if (!scroll)
+ {
+ scroll = _use_an_item(OBJ_SCROLLS);
+ if (!scroll)
+ {
+ int slot = PROMPT_ABORT;
+ if (prompt_failed(slot))
+ return;
+ }
+ }
- const item_def& scroll = you.inv[item_slot];
- const string failure_reason = cannot_read_item_reason(scroll);
+ const string failure_reason = cannot_read_item_reason(*scroll);
if (!failure_reason.empty())
{
mprf(MSGCH_PROMPT, "%s", failure_reason.c_str());
return;
}
- if (scroll.base_type == OBJ_BOOKS)
+ if (scroll->base_type == OBJ_BOOKS)
{
- _handle_read_book(item_slot);
+ _handle_read_book(scroll);
return;
}
// need to handle this before we waste time (with e.g. blurryvis)
- if (scroll.sub_type == SCR_BLINKING && item_type_known(scroll)
+ if (scroll->sub_type == SCR_BLINKING && item_type_known(*scroll)
&& player_has_orb()
&& !yesno("Your blink will be uncontrolled - continue anyway?",
false, 'n'))
@@ -2531,12 +2658,19 @@ void read(int slot)
{
// takes 0.5, 1, 2 extra turns
const int turns = max(1, player_mutation_level(MUT_BLURRY_VISION) - 1);
- start_delay(DELAY_BLURRY_SCROLL, turns, item_slot);
+ if (in_inventory(*scroll))
+ {
+ start_delay(DELAY_BLURRY_SCROLL, turns,
+ letter_to_index(scroll->slot), 0);
+ }
+ else
+ start_delay(DELAY_BLURRY_SCROLL, turns,
+ scroll->index(), 1);
if (player_mutation_level(MUT_BLURRY_VISION) == 1)
you.time_taken /= 2;
}
else
- read_scroll(item_slot);
+ read_scroll(scroll);
}
/**
@@ -2549,9 +2683,9 @@ void read(int slot)
*
* @param slot The slot of the item in the player's inventory.
*/
-void read_scroll(int item_slot)
+void read_scroll(item_def* item)
{
- item_def& scroll = you.inv[item_slot];
+ item_def& scroll = *item;
const scroll_type which_scroll = static_cast<scroll_type>(scroll.sub_type);
const int prev_quantity = scroll.quantity;
const bool alreadyknown = item_type_known(scroll);
@@ -2830,7 +2964,10 @@ void read_scroll(int item_slot)
if (!cancel_scroll)
{
- dec_inv_item_quantity(item_slot, 1);
+ if (in_inventory(scroll))
+ dec_inv_item_quantity(scroll.link, 1);
+ else
+ dec_mitm_item_quantity(scroll.index(), 1);
count_action(CACT_USE, OBJ_SCROLLS);
}
@@ -2844,7 +2981,7 @@ void read_scroll(int item_slot)
&& which_scroll != SCR_AMNESIA)
{
mprf("It %s a %s.",
- you.inv[item_slot].quantity < prev_quantity ? "was" : "is",
+ scroll.quantity < prev_quantity ? "was" : "is",
scroll_name.c_str());
}
@@ -3037,7 +3174,7 @@ void tile_item_use(int idx)
if (!item_is_spellbook(item) || !you.skill(SK_SPELLCASTING))
{
if (check_warning_inscriptions(item, OPER_READ))
- _handle_read_book(idx);
+ _handle_read_book(&you.inv[idx]);
} // else it's a spellbook
else if (check_warning_inscriptions(item, OPER_MEMORISE))
learn_spell(); // offers all spells, might not be what we want
@@ -3045,7 +3182,7 @@ void tile_item_use(int idx)
case OBJ_SCROLLS:
if (check_warning_inscriptions(item, OPER_READ))
- read(idx);
+ read(&you.inv[idx]);
return;
case OBJ_JEWELLERY:
@@ -3057,7 +3194,7 @@ void tile_item_use(int idx)
case OBJ_POTIONS:
if (check_warning_inscriptions(item, OPER_QUAFF))
- drink(idx);
+ drink(&you.inv[idx]);
return;
default:
diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h
index 5b2fd86..f21a957 100644
--- a/crawl-ref/source/item_use.h
+++ b/crawl-ref/source/item_use.h
@@ -14,7 +14,7 @@ bool armour_prompt(const string & mesg, int *index, operation_types oper);
bool takeoff_armour(int index);
-void drink(int slot = -1);
+void drink(item_def* potion = nullptr);
bool god_hates_brand(const int brand);
@@ -22,8 +22,8 @@ bool safe_to_remove(const item_def &item, bool quiet = false);
bool puton_ring(int slot = -1, bool allow_prompt = true);
-void read(int slot = -1);
-void read_scroll(int slot);
+void read(item_def* scroll = nullptr);
+void read_scroll(item_def* item = nullptr);
bool player_can_read();
string cannot_read_item_reason(const item_def &item);
@@ -53,6 +53,8 @@ void random_uselessness();
void prompt_inscribe_item();
+item_def* _use_an_item(int);
+
#define STASIS_STABILITY_MSG "Your stasis keeps you stable."
#define NO_HASTE_MSG "You cannot haste."
--
2.8.2
From 1f40d2a99f5651f874aa657ad4fb66a2b4198ed2 Mon Sep 17 00:00:00 2001
From: Naruni <kram321@gmail.com>
Date: Wed, 25 May 2016 19:50:40 -0700
Subject: [PATCH 2/2] Item lookup and return functions
Functions that require (int slot) for doing things to items need to change
to item_def. These functions will help with that conversion.
---
crawl-ref/source/items.cc | 37 +++++++++++++++++++++++++++++++++++++
crawl-ref/source/items.h | 3 +++
2 files changed, 40 insertions(+)
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index 546fcee..d4e327e 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -83,6 +83,43 @@
#include "view.h"
#include "xom.h"
+/**
+ * Return an item's location (floor or inventory) and the corresponding mitm
+ * int or inv slot referring to it.
+ *
+ * @param item_def The item_def. item_int(item) or item_int(*item).
+ *
+ * @return A pair containing bool and int. Bool will be true for
+ * items in inventory, false if not. The int will be
+ * either index into either you.inv or mitm.
+ */
+
+pair<bool, int> item_int(item_def &item)
+{
+ if (in_inventory(item))
+ return make_pair (true, item.slot);
+ return make_pair (false, item.index());
+}
+
+
+/**
+ * Return an item_def& requested by an item's inv slot or mitm index.
+ * If you want an item_def* then call via &item_from_int(inv, number).
+ *
+ * @param bool inv Is the item in inventory (true)?
+ * @param int number The number associated with the item. Either
+ * inv.slot or mitm[index()].
+ *
+ * @return item_def*
+ */
+
+item_def& item_from_int(bool inv, int number)
+{
+ if (inv)
+ return you.inv[number];
+ return mitm[number];
+}
+
static void _autoinscribe_item(item_def& item);
static void _autoinscribe_floor_items();
static void _autoinscribe_inventory();
diff --git a/crawl-ref/source/items.h b/crawl-ref/source/items.h
index f235d7d..694fe33 100644
--- a/crawl-ref/source/items.h
+++ b/crawl-ref/source/items.h
@@ -29,6 +29,9 @@ enum item_source_type
/// top-priority item override colour
#define FORCED_ITEM_COLOUR_KEY "forced_item_colour"
+pair<bool, int> item_int(item_def &item);
+item_def& item_from_int(bool, int);
+
int get_max_subtype(object_class_type base_type);
bool item_type_has_unidentified(object_class_type base_type);
--
2.8.2
item_int_fix.patch [^] (711 bytes) 2016-05-30 03:34 [Show Content] [Hide Content]From 64ca64a7d980adb09c810991a7659c8782cd61b6 Mon Sep 17 00:00:00 2001
From: Naruni <kram321@gmail.com>
Date: Sun, 29 May 2016 18:34:54 -0700
Subject: [PATCH] Fix item_int.
Needs to return item.link instead of item.slot
---
crawl-ref/source/items.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc
index 08b0200..0710cda 100644
--- a/crawl-ref/source/items.cc
+++ b/crawl-ref/source/items.cc
@@ -97,7 +97,7 @@
pair<bool, int> item_int(item_def &item)
{
if (in_inventory(item))
- return make_pair (true, item.slot);
+ return make_pair (true, item.link);
return make_pair (false, item.index());
}
--
2.8.2
use_from_floor_upgrade.patch [^] (6,416 bytes) 2016-05-30 07:33 [Show Content] [Hide Content]From 8a1e4b6bbadff7a6e1c8d2de97d9ecf12777b09e Mon Sep 17 00:00:00 2001
From: Naruni <kram321@gmail.com>
Date: Sun, 29 May 2016 21:09:57 -0700
Subject: [PATCH 1/3] Add option to any_items_of_type
Add argument bool inspect_floor (default false). If true, will look at the
items on the player's tile.
---
crawl-ref/source/invent.cc | 16 ++++++++++++++--
crawl-ref/source/invent.h | 2 +-
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc
index b3bc64a..61f6cac 100644
--- a/crawl-ref/source/invent.cc
+++ b/crawl-ref/source/invent.cc
@@ -1105,14 +1105,26 @@ static void _get_inv_items_to_show(vector<const item_def*> &v,
* @return Whether there are any items matching the given
* selector in the player's inventory.
*/
-bool any_items_of_type(int selector, int excluded_slot)
+bool any_items_of_type(int selector, int excluded_slot, bool inspect_floor)
{
- return any_of(begin(you.inv), end(you.inv),
+ bool ret = any_of(begin(you.inv), end(you.inv),
[=] (const item_def &item) -> bool
{
return item.defined() && item.link != excluded_slot
&& item_is_selected(item, selector);
});
+ if (!ret && inspect_floor)
+ {
+ vector<const item_def*> item_floor;
+ item_list_on_square(item_floor, you.visible_igrd(you.pos()));
+ ret = any_of(begin(item_floor), end(item_floor),
+ [=] (const item_def* item) -> bool
+ {
+ return item->defined()
+ && item_is_selected(*item, selector);
+ });
+ }
+ return ret;
}
// Use title = nullptr for stock Inventory title
diff --git a/crawl-ref/source/invent.h b/crawl-ref/source/invent.h
index ff379c2..9e39a0d 100644
--- a/crawl-ref/source/invent.h
+++ b/crawl-ref/source/invent.h
@@ -186,7 +186,7 @@ protected:
void get_class_hotkeys(const int type, vector<char> &glyphs);
bool item_is_selected(const item_def &item, int selector);
-bool any_items_of_type(int type_expect, int excluded_slot = -1);
+bool any_items_of_type(int type_expect, int excluded_slot = -1, bool inspect_floor = false);
string no_selectables_message(int item_selector);
string slot_description();
--
2.8.2
From d6af1092b95a56185eb5c86dad73376ae5c6980d Mon Sep 17 00:00:00 2001
From: Naruni <kram321@gmail.com>
Date: Sun, 29 May 2016 21:17:08 -0700
Subject: [PATCH 2/3] Item check in _use_an_item
If there are no scrolls, books, or potions on tile or in inv, _use_an_item
will message the player and return nullptr.
---
crawl-ref/source/invent.cc | 4 ++--
crawl-ref/source/item_use.cc | 10 ++++++++--
2 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc
index 61f6cac..42158a1 100644
--- a/crawl-ref/source/invent.cc
+++ b/crawl-ref/source/invent.cc
@@ -424,10 +424,10 @@ string no_selectables_message(int item_selector)
case OBJ_FOOD:
return "You aren't carrying any food.";
case OBJ_POTIONS:
- return "You aren't carrying any potions.";
+ return "You aren't carrying or standing over any potions.";
case OBJ_SCROLLS:
case OBJ_BOOKS:
- return "You aren't carrying any spellbooks or scrolls.";
+ return "You aren't carrying or standing over any spellbooks or scrolls.";
case OBJ_WANDS:
return "You aren't carrying any wands.";
case OBJ_JEWELLERY:
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index b26abc7..e05e4ec 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -181,6 +181,12 @@ void UseItemMenu::populate_menu()
item_def* _use_an_item(int item_type)
{
+ if (!any_items_of_type(item_type, 0, true))
+ {
+ mprf(MSGCH_PROMPT, "%s",
+ no_selectables_message(item_type).c_str());
+ return nullptr;
+ }
// Init the menu
UseItemMenu menu (item_type);
@@ -1828,7 +1834,7 @@ void drink(item_def* potion)
if (!potion)
{
- int slot = PROMPT_ABORT;
+ int slot = PROMPT_NOTHING;
if (prompt_failed(slot))
{
_vampire_corpse_help();
@@ -2613,7 +2619,7 @@ void read(item_def* scroll)
scroll = _use_an_item(OBJ_SCROLLS);
if (!scroll)
{
- int slot = PROMPT_ABORT;
+ int slot = PROMPT_NOTHING;
if (prompt_failed(slot))
return;
}
--
2.8.2
From f752a1532eab9be205e68672d01db509ef6ec840 Mon Sep 17 00:00:00 2001
From: Naruni <kram321@gmail.com>
Date: Sun, 29 May 2016 22:33:52 -0700
Subject: [PATCH 3/3] Make _use_an_item more robust
_use_an_item is a dumpster fire. This makes it handle situations a little
better.
---
crawl-ref/source/item_use.cc | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index e05e4ec..00e5597 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -181,12 +181,25 @@ void UseItemMenu::populate_menu()
item_def* _use_an_item(int item_type)
{
+ item_def* target = nullptr;
+ // What is player trying to do? Assign oper based on item_type.
+ operation_types oper;
+ switch (item_type)
+ {
+ case OBJ_POTIONS: oper = OPER_QUAFF;
+ case OBJ_SCROLLS: oper = OPER_READ;
+ }
+
+ // First handle things that will return nullptr
+
+ // No selectable items in inv or floor
if (!any_items_of_type(item_type, 0, true))
{
mprf(MSGCH_PROMPT, "%s",
no_selectables_message(item_type).c_str());
return nullptr;
}
+
// Init the menu
UseItemMenu menu (item_type);
@@ -199,7 +212,14 @@ item_def* _use_an_item(int item_type)
ASSERT(sel.size() == 1);
auto ie = dynamic_cast<InvEntry *>(sel[0]);
- item_def* target = const_cast<item_def*>(ie->item);
+ target = const_cast<item_def*>(ie->item);
+
+ // Check for a warning. If player says no, return nullptr with a message.
+ if (!check_warning_inscriptions(*target, oper))
+ {
+ prompt_failed(PROMPT_ABORT);
+ return nullptr;
+ }
return target;
}
--
2.8.2
|