diff options
-rw-r--r-- | crawl-ref/source/acr.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/cmd-keys.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/cmd-name.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/command.cc | 1 | ||||
-rw-r--r-- | crawl-ref/source/enum.h | 1 | ||||
-rw-r--r-- | crawl-ref/source/invent.cc | 103 | ||||
-rw-r--r-- | crawl-ref/source/invent.h | 6 | ||||
-rw-r--r-- | crawl-ref/source/it_use3.cc | 151 | ||||
-rw-r--r-- | crawl-ref/source/it_use3.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 11 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 4 |
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) |