summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/acr.cc7
-rw-r--r--crawl-ref/source/cmd-keys.h3
-rw-r--r--crawl-ref/source/cmd-name.h1
-rw-r--r--crawl-ref/source/command.cc1
-rw-r--r--crawl-ref/source/enum.h1
-rw-r--r--crawl-ref/source/invent.cc103
-rw-r--r--crawl-ref/source/invent.h6
-rw-r--r--crawl-ref/source/it_use3.cc151
-rw-r--r--crawl-ref/source/it_use3.h2
-rw-r--r--crawl-ref/source/item_use.cc11
-rw-r--r--crawl-ref/source/mon-util.cc4
11 files changed, 214 insertions, 76 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 11753c6070..32532a4e12 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -1522,7 +1522,12 @@ void process_command( command_type cmd )
break;
case CMD_EVOKE:
- if (!evoke_wielded())
+ if (!evoke_item())
+ flush_input_buffer( FLUSH_ON_FAILURE );
+ break;
+
+ case CMD_EVOKE_WIELDED:
+ if (!evoke_item(you.equip[EQ_WEAPON]))
flush_input_buffer( FLUSH_ON_FAILURE );
break;
diff --git a/crawl-ref/source/cmd-keys.h b/crawl-ref/source/cmd-keys.h
index 0ec95978d7..aa5d660355 100644
--- a/crawl-ref/source/cmd-keys.h
+++ b/crawl-ref/source/cmd-keys.h
@@ -37,7 +37,8 @@
{'r', CMD_READ},
{'s', CMD_SEARCH},
{'t', CMD_SHOUT},
-{'v', CMD_EVOKE},
+{'V', CMD_EVOKE},
+{'v', CMD_EVOKE_WIELDED},
{'w', CMD_WIELD_WEAPON},
{'x', CMD_LOOK_AROUND},
{'z', CMD_CAST_SPELL},
diff --git a/crawl-ref/source/cmd-name.h b/crawl-ref/source/cmd-name.h
index 5f16bd40cf..9b91471cb8 100644
--- a/crawl-ref/source/cmd-name.h
+++ b/crawl-ref/source/cmd-name.h
@@ -39,6 +39,7 @@
{CMD_FULL_VIEW, "CMD_FULL_VIEW"},
{CMD_EXAMINE_OBJECT, "CMD_EXAMINE_OBJECT"},
{CMD_EVOKE, "CMD_EVOKE"},
+{CMD_EVOKE_WIELDED, "CMD_EVOKE_WIELDED"},
{CMD_WIELD_WEAPON, "CMD_WIELD_WEAPON"},
{CMD_WEAPON_SWAP, "CMD_WEAPON_SWAP"},
{CMD_FIRE, "CMD_FIRE"},
diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc
index 99c9fd037c..05f6638b41 100644
--- a/crawl-ref/source/command.cc
+++ b/crawl-ref/source/command.cc
@@ -2227,6 +2227,7 @@ static void _add_formatted_keyhelp(column_composer &cols)
"<w>'</w> : wield item a, or switch to b \n"
" (use <w>=</w> to assign slots)\n"
"<w>v</w> : eVoke power of wielded item\n"
+ "<w>V</w> : eVoke power of an item in inventory\n"
"<w>W</w>/<w>T</w> : Wear or Take off armour\n"
"<w>P</w>/<w>R</w> : Put on or Remove jewellery\n";
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index 2695017c5c..43f52dc1e3 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -465,6 +465,7 @@ enum command_type
CMD_FULL_VIEW,
CMD_EXAMINE_OBJECT,
CMD_EVOKE,
+ CMD_EVOKE_WIELDED,
CMD_WIELD_WEAPON,
CMD_WEAPON_SWAP,
CMD_FIRE,
diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc
index 9208943f4b..21c1390090 100644
--- a/crawl-ref/source/invent.cc
+++ b/crawl-ref/source/invent.cc
@@ -459,6 +459,8 @@ static std::string _no_selectables_message(int item_selector)
return("You aren't carrying any items that might be thrown or fired.");
case OSEL_BUTCHERY:
return("You aren't carrying any sharp implements.");
+ case OSEL_EVOKABLE:
+ return("You aren't carrying any items that can be evoked.");
}
return("You aren't carrying any such object.");
@@ -1017,6 +1019,9 @@ static bool _item_class_selected(const item_def &i, int selector)
case OSEL_RECHARGE:
return (item_is_rechargeable(i, true));
+ case OSEL_EVOKABLE:
+ return (item_is_evokable(i, true));
+
case OSEL_ENCH_ARM:
return (is_enchantable_armour(i, true, true));
@@ -1689,3 +1694,101 @@ bool prompt_failed(int retval, std::string msg)
return (true);
}
+
+bool item_is_evokable(const item_def &item, bool known, bool msg)
+{
+ const bool wielded = (you.equip[EQ_WEAPON] == item.link);
+
+ switch (item.base_type)
+ {
+ case OBJ_WANDS:
+ if (item.plus2 == ZAPCOUNT_EMPTY)
+ {
+ if (msg)
+ mpr("This wand has no charges.");
+ return (false);
+ }
+ return (true);
+
+ case OBJ_WEAPONS:
+ if (!wielded && !msg)
+ return (false);
+
+ if (get_weapon_brand(item) == SPWPN_REACHING
+ && item_type_known(item))
+ {
+ if (!wielded)
+ {
+ if (msg)
+ mpr("That item can only be evoked when wielded.");
+ return (false);
+ }
+ return (true);
+ }
+
+ if (is_fixed_artefact(item))
+ {
+ switch (item.special)
+ {
+ case SPWPN_SCEPTRE_OF_ASMODEUS:
+ case SPWPN_STAFF_OF_WUCAD_MU:
+ case SPWPN_STAFF_OF_DISPATER:
+ case SPWPN_STAFF_OF_OLGREB:
+ if (!wielded)
+ {
+ if (msg)
+ mpr("That item can only be evoked when wielded.");
+ return (false);
+ }
+ return (true);
+
+ default:
+ return (false);
+ }
+ }
+ if (msg)
+ mpr("That item cannot be evoked!");
+ return (false);
+
+ case OBJ_STAVES:
+ if (item_is_rod(item)
+ || !known && !item_type_known(item)
+ || item.sub_type == STAFF_CHANNELING
+ && item_type_known(item))
+ {
+ if (!wielded)
+ {
+ if (msg)
+ mpr("That item can only be evoked when wielded.");
+ return (false);
+ }
+ return (true);
+ }
+ if (msg)
+ mpr("That item cannot be evoked!");
+ return (false);
+
+ case OBJ_MISCELLANY:
+ if (is_deck(item))
+ {
+ if (!wielded)
+ {
+ if (msg)
+ mpr("That item can only be evoked when wielded.");
+ return (false);
+ }
+ return (true);
+ }
+
+ if (item.sub_type != MISC_LANTERN_OF_SHADOWS
+ && item.sub_type != MISC_EMPTY_EBONY_CASKET)
+ {
+ return (true);
+ }
+ // else fall through
+ default:
+ if (msg)
+ mpr("That item cannot be evoked!");
+ return (false);
+ }
+}
diff --git a/crawl-ref/source/invent.h b/crawl-ref/source/invent.h
index c8fac012cf..f82196ca06 100644
--- a/crawl-ref/source/invent.h
+++ b/crawl-ref/source/invent.h
@@ -28,7 +28,8 @@ enum object_selector
OSEL_VAMP_EAT = -8,
OSEL_DRAW_DECK = -9,
OSEL_THROWABLE = -10,
- OSEL_BUTCHERY = -11
+ OSEL_BUTCHERY = -11,
+ OSEL_EVOKABLE = -12
};
#define PROMPT_ABORT -1
@@ -233,4 +234,7 @@ void init_item_sort_comparators(item_sort_comparators &list,
bool prompt_failed(int retval, std::string msg = "");
+bool item_is_evokable(const item_def &item, bool known = false,
+ bool msg = false);
+
#endif
diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc
index 7885b1cab4..d68dee4a05 100644
--- a/crawl-ref/source/it_use3.cc
+++ b/crawl-ref/source/it_use3.cc
@@ -27,6 +27,7 @@ REVISION("$Rev$");
#include "food.h"
#include "invent.h"
#include "items.h"
+#include "item_use.h"
#include "it_use2.h"
#include "itemname.h"
#include "itemprop.h"
@@ -432,41 +433,93 @@ static bool evoke_sceptre_of_asmodeus()
return (rc);
}
-// Returns true if item successfully evoked.
-bool evoke_wielded()
+static bool _efreet_flask()
{
- int power = 0;
+ bool friendly = x_chance_in_y(10 + you.skills[SK_EVOCATIONS] / 3, 20);
- int pract = 0; // By how much Evocations is practised.
- bool did_work = false; // Used for default "nothing happens" message.
+ mpr("You open the flask...");
+
+ const int monster =
+ create_monster(
+ mgen_data(MONS_EFREET,
+ friendly ? BEH_FRIENDLY : BEH_HOSTILE,
+ 0, 0, you.pos(),
+ MHITYOU, MG_FORCE_BEH));
+
+ if (monster != -1)
+ {
+ mpr("...and a huge efreet comes out.");
- const int wield = you.equip[EQ_WEAPON];
+ if (player_angers_monster(&menv[monster]))
+ friendly = false;
+ if (silenced(you.pos()))
+ {
+ mpr(friendly ? "It nods graciously at you."
+ : "It snaps in your direction!", MSGCH_TALK_VISUAL);
+ }
+ else
+ {
+ mpr(friendly ? "\"Thank you for releasing me!\""
+ : "It howls insanely!", MSGCH_TALK);
+ }
+ }
+ else
+ canned_msg(MSG_NOTHING_HAPPENS);
+
+ dec_inv_item_quantity(you.equip[EQ_WEAPON], 1);
+
+ return (true);
+}
+
+bool evoke_item(int slot)
+{
if (you.duration[DUR_BERSERKER])
{
canned_msg( MSG_TOO_BERSERK );
return (false);
}
- else if (!you.weapon())
+
+ if (slot == -1)
{
- mpr("You aren't wielding anything!");
- crawl_state.zero_turns_taken();
- return (false);
+ slot = prompt_invent_item( "Evoke which item? (* to show all)",
+ MT_INVLIST,
+ OSEL_EVOKABLE, true, true, true, 0, -1,
+ NULL, OPER_EVOKE );
+
+ if (prompt_failed(slot))
+ return (false);
}
+ ASSERT (slot >= 0);
- item_def& wpn = *you.weapon();
- bool unevokable = false;
+ const bool wielded = (you.equip[EQ_WEAPON] == slot);
+
+ item_def& item = you.inv[slot];
+ // Also handles messages.
+ if (!item_is_evokable(item, false, true))
+ return (false);
// Check inscriptions.
- if (!check_warning_inscriptions(wpn, OPER_EVOKE))
+ if (!check_warning_inscriptions(item, OPER_EVOKE))
return (false);
- switch (wpn.base_type)
+ int power = 0;
+ int pract = 0; // By how much Evocations is practised.
+ bool did_work = false; // Used for default "nothing happens" message.
+ bool unevokable = false;
+
+ switch (item.base_type)
{
+ case OBJ_WANDS:
+ zap_wand(slot);
+ return (true);
+
case OBJ_WEAPONS:
- if (get_weapon_brand(wpn) == SPWPN_REACHING)
+ ASSERT(wielded);
+
+ if (get_weapon_brand(item) == SPWPN_REACHING)
{
- if (_reaching_weapon_attack(wpn))
+ if (_reaching_weapon_attack(item))
{
pract = 0;
did_work = true;
@@ -474,9 +527,9 @@ bool evoke_wielded()
else
return (false);
}
- else if (is_fixed_artefact(wpn))
+ else if (is_fixed_artefact(item))
{
- switch (wpn.special)
+ switch (item.special)
{
case SPWPN_STAFF_OF_DISPATER:
if (you.duration[DUR_DEATHS_DOOR] || !enough_hp(11, true)
@@ -559,16 +612,18 @@ bool evoke_wielded()
break;
case OBJ_STAVES:
- if (item_is_rod( wpn ))
+ ASSERT(wielded);
+
+ if (item_is_rod( item ))
{
- pract = staff_spell( wield );
+ pract = staff_spell( slot );
// [ds] Early exit, no turns are lost.
if (pract == -1)
return (false);
did_work = true; // staff_spell() will handle messages
}
- else if (wpn.sub_type == STAFF_CHANNELING)
+ else if (item.sub_type == STAFF_CHANNELING)
{
if (you.magic_points < you.max_magic_points
&& x_chance_in_y(you.skills[SK_EVOCATIONS] + 11, 40))
@@ -579,13 +634,13 @@ bool evoke_wielded()
pract = 1;
did_work = true;
- if (!item_type_known(wpn))
+ if (!item_type_known(item))
{
- set_ident_type( OBJ_STAVES, wpn.sub_type, ID_KNOWN_TYPE );
- set_ident_flags( wpn, ISFLAG_KNOW_TYPE );
+ set_ident_type( OBJ_STAVES, item.sub_type, ID_KNOWN_TYPE );
+ set_ident_flags( item, ISFLAG_KNOW_TYPE );
mprf("You are wielding %s.",
- wpn.name(DESC_NOCAP_A).c_str());
+ item.name(DESC_NOCAP_A).c_str());
more();
@@ -602,14 +657,15 @@ bool evoke_wielded()
case OBJ_MISCELLANY:
did_work = true; // easier to do it this way for misc items
- if (is_deck(wpn))
+ if (is_deck(item))
{
- evoke_deck(wpn);
+ ASSERT(wielded);
+ evoke_deck(item);
pract = 1;
break;
}
- switch (wpn.sub_type)
+ switch (item.sub_type)
{
case MISC_BOTTLED_EFREET:
if (_efreet_flask())
@@ -699,45 +755,6 @@ bool evoke_wielded()
crawl_state.zero_turns_taken();
return (did_work);
-} // end evoke_wielded()
-
-static bool _efreet_flask()
-{
- bool friendly = x_chance_in_y(10 + you.skills[SK_EVOCATIONS] / 3, 20);
-
- mpr("You open the flask...");
-
- const int monster =
- create_monster(
- mgen_data(MONS_EFREET,
- friendly ? BEH_FRIENDLY : BEH_HOSTILE,
- 0, 0, you.pos(),
- MHITYOU, MG_FORCE_BEH));
-
- if (monster != -1)
- {
- mpr("...and a huge efreet comes out.");
-
- if (player_angers_monster(&menv[monster]))
- friendly = false;
-
- if (silenced(you.pos()))
- {
- mpr(friendly ? "It nods graciously at you."
- : "It snaps in your direction!", MSGCH_TALK_VISUAL);
- }
- else
- {
- mpr(friendly ? "\"Thank you for releasing me!\""
- : "It howls insanely!", MSGCH_TALK);
- }
- }
- else
- canned_msg(MSG_NOTHING_HAPPENS);
-
- dec_inv_item_quantity(you.equip[EQ_WEAPON], 1);
-
- return (true);
}
static bool _ball_of_seeing(void)
diff --git a/crawl-ref/source/it_use3.h b/crawl-ref/source/it_use3.h
index 2a7bdd6e20..0c492d9a00 100644
--- a/crawl-ref/source/it_use3.h
+++ b/crawl-ref/source/it_use3.h
@@ -29,7 +29,7 @@ void tome_of_power(int slot);
/* ***********************************************************************
* called from: acr
* *********************************************************************** */
-bool evoke_wielded();
+bool evoke_item(int slot = -1);
// last updated 12may2000 {dlb}
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 5a643a6276..b184f89d82 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -23,6 +23,9 @@ REVISION("$Rev$");
#include "cloud.h"
#include "command.h"
#include "debug.h"
+#ifdef USE_TILE
+#include "decks.h"
+#endif
#include "delay.h"
#include "describe.h"
#include "directn.h"
@@ -5435,17 +5438,19 @@ void tile_item_use(int idx)
case OBJ_STAVES:
case OBJ_MISCELLANY:
// Wield any unwielded item of these types.
- if (!equipped)
+ if (!equipped
+ && (item.base_type != OBJ_MISCELLANY || is_deck(item)
+ || item.sub_type == MISC_LANTERN_OF_SHADOWS))
{
if (check_warning_inscriptions(item, OPER_WIELD))
wield_weapon(true, idx);
return;
}
// Evoke misc. items and rods.
- if (item.base_type == OBJ_MISCELLANY || item_is_rod(item))
+ if (item_is_evokable(item))
{
if (check_warning_inscriptions(item, OPER_EVOKE))
- evoke_wielded();
+ evoke_item(idx);
return;
}
// Unwield staves or weapons.
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 34b986e721..4fc0db2260 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -5068,8 +5068,8 @@ bool monsters::pickup_wand(item_def &item, int near)
if ((mons_is_holy(this) || is_good_god(god)) && is_evil_item(item))
return (false);
- // If you already have a charged wand, don't bother. Otherwise,
- // replace with a charged one.
+ // If a monster already has a charged wand, don't bother.
+ // Otherwise, replace with a charged one.
if (item_def *wand = mslot_item(MSLOT_WAND))
{
if (wand->plus > 0)