diff options
-rw-r--r-- | crawl-ref/source/it_use3.cc | 599 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/tilereg.cc | 14 |
3 files changed, 311 insertions, 306 deletions
diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc index cde6d53c8f..b1723620c9 100644 --- a/crawl-ref/source/it_use3.cc +++ b/crawl-ref/source/it_use3.cc @@ -54,13 +54,6 @@ REVISION("$Rev$"); #include "view.h" #include "xom.h" -static bool _ball_of_energy(); -static bool _ball_of_fixation(); -static bool _ball_of_seeing(); -static bool _box_of_beasts(); -static bool _disc_of_storms(); -static bool _efreet_flask(); - void special_wielded() { item_def& weapon = *you.weapon(); @@ -433,7 +426,7 @@ static bool evoke_sceptre_of_asmodeus() return (rc); } -static bool _efreet_flask() +static bool _efreet_flask(int slot) { bool friendly = x_chance_in_y(10 + you.skills[SK_EVOCATIONS] / 3, 20); @@ -467,302 +460,11 @@ static bool _efreet_flask() else canned_msg(MSG_NOTHING_HAPPENS); - dec_inv_item_quantity(you.equip[EQ_WEAPON], 1); + dec_inv_item_quantity(slot, 1); return (true); } -bool evoke_item(int slot) -{ - if (you.duration[DUR_BERSERKER]) - { - canned_msg( MSG_TOO_BERSERK ); - return (false); - } - - if (player_in_bat_form()) - { - canned_msg(MSG_PRESENT_FORM); - return (false); - } - - if (slot == -1) - { - 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); - - 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(item, OPER_EVOKE)) - return (false); - - 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: - ASSERT(wielded); - - if (get_weapon_brand(item) == SPWPN_REACHING) - { - if (_reaching_weapon_attack(item)) - { - pract = 0; - did_work = true; - } - else - return (false); - } - else if (is_fixed_artefact(item)) - { - switch (item.special) - { - case SPWPN_STAFF_OF_DISPATER: - if (you.duration[DUR_DEATHS_DOOR] || !enough_hp(11, true) - || !enough_mp(5, true)) - { - break; - } - - mpr("You feel the staff feeding on your energy!"); - - dec_hp( 5 + random2avg(19, 2), false, "Staff of Dispater" ); - dec_mp( 2 + random2avg(5, 2) ); - make_hungry(100, false, true); - - power = you.skills[SK_EVOCATIONS] * 8; - your_spells( SPELL_HELLFIRE, power, false ); - pract = (coinflip() ? 2 : 1); - did_work = true; - break; - - case SPWPN_SCEPTRE_OF_ASMODEUS: - if (evoke_sceptre_of_asmodeus()) - { - make_hungry(200, false, true); - did_work = true; - pract = 1; - } - break; - - case SPWPN_STAFF_OF_OLGREB: - if (!enough_mp( 4, true ) - || you.skills[SK_EVOCATIONS] < random2(6)) - { - break; - } - - dec_mp(4); - make_hungry(50, false, true); - pract = 1; - did_work = true; - - power = 10 + you.skills[SK_EVOCATIONS] * 8; - - your_spells( SPELL_OLGREBS_TOXIC_RADIANCE, power, false ); - - if (x_chance_in_y(you.skills[SK_EVOCATIONS] + 1, 10)) - your_spells( SPELL_VENOM_BOLT, power, false ); - break; - - case SPWPN_STAFF_OF_WUCAD_MU: - if (you.magic_points == you.max_magic_points - || you.skills[SK_EVOCATIONS] < random2(25)) - { - break; - } - - mpr("Magical energy flows into your mind!"); - - inc_mp( 3 + random2(5) + you.skills[SK_EVOCATIONS] / 3, false ); - make_hungry(50, false, true); - pract = 1; - did_work = true; - - if (one_chance_in(3)) - { - // NH_NEVER prevents "nothing happens" messages. - MiscastEffect( &you, NON_MONSTER, SPTYP_DIVINATION, - random2(9), random2(70), - "the Staff of Wucad Mu", NH_NEVER ); - } - break; - - default: - unevokable = true; - break; - } - } - else - unevokable = true; - break; - - case OBJ_STAVES: - ASSERT(wielded); - - if (item_is_rod( item )) - { - 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 (item.sub_type == STAFF_CHANNELING) - { - if (you.magic_points < you.max_magic_points - && x_chance_in_y(you.skills[SK_EVOCATIONS] + 11, 40)) - { - mpr("You channel some magical energy."); - inc_mp( 1 + random2(3), false ); - make_hungry(50, false, true); - pract = 1; - did_work = true; - - if (!item_type_known(item)) - { - set_ident_type( OBJ_STAVES, item.sub_type, ID_KNOWN_TYPE ); - set_ident_flags( item, ISFLAG_KNOW_TYPE ); - - mprf("You are wielding %s.", - item.name(DESC_NOCAP_A).c_str()); - - more(); - - you.wield_change = true; - } - } - } - else - { - unevokable = true; - } - break; - - case OBJ_MISCELLANY: - did_work = true; // easier to do it this way for misc items - - if (is_deck(item)) - { - ASSERT(wielded); - evoke_deck(item); - pract = 1; - break; - } - - switch (item.sub_type) - { - case MISC_BOTTLED_EFREET: - if (_efreet_flask()) - pract = 2; - break; - - case MISC_CRYSTAL_BALL_OF_SEEING: - if (_ball_of_seeing()) - pract = 1; - break; - - case MISC_AIR_ELEMENTAL_FAN: - if (you.skills[SK_EVOCATIONS] <= random2(30)) - canned_msg(MSG_NOTHING_HAPPENS); - else - { - cast_summon_elemental(100, GOD_NO_GOD, MONS_AIR_ELEMENTAL, 4); - pract = (one_chance_in(5) ? 1 : 0); - } - break; - - case MISC_LAMP_OF_FIRE: - if (you.skills[SK_EVOCATIONS] <= random2(30)) - canned_msg(MSG_NOTHING_HAPPENS); - else - { - cast_summon_elemental(100, GOD_NO_GOD, MONS_FIRE_ELEMENTAL, 4); - pract = (one_chance_in(5) ? 1 : 0); - } - break; - - case MISC_STONE_OF_EARTH_ELEMENTALS: - if (you.skills[SK_EVOCATIONS] <= random2(30)) - canned_msg(MSG_NOTHING_HAPPENS); - else - { - cast_summon_elemental(100, GOD_NO_GOD, MONS_EARTH_ELEMENTAL, 4); - pract = (one_chance_in(5) ? 1 : 0); - } - break; - - case MISC_HORN_OF_GERYON: - if (evoke_horn_of_geryon()) - pract = 1; - break; - - case MISC_BOX_OF_BEASTS: - if (_box_of_beasts()) - pract = 1; - break; - - case MISC_CRYSTAL_BALL_OF_ENERGY: - if (_ball_of_energy()) - pract = 1; - break; - - case MISC_CRYSTAL_BALL_OF_FIXATION: - if (_ball_of_fixation()) - pract = 1; - break; - - case MISC_DISC_OF_STORMS: - if (_disc_of_storms()) - pract = (coinflip() ? 2 : 1); - break; - - default: - did_work = false; - unevokable = true; - break; - } - break; - - default: - unevokable = true; - break; - } - - if (!did_work) - canned_msg(MSG_NOTHING_HAPPENS); - else if (pract > 0) - exercise( SK_EVOCATIONS, pract ); - - if (!unevokable) - you.turn_is_over = true; - else - crawl_state.zero_turns_taken(); - - return (did_work); -} - static bool _ball_of_seeing(void) { bool ret = false; @@ -966,7 +668,7 @@ void skill_manual(int slot) xom_is_stimulated(known ? 14 : 64); } -static bool _box_of_beasts() +static bool _box_of_beasts(item_def &box) { bool success = false; @@ -1018,7 +720,7 @@ static bool _box_of_beasts() else { mpr("...but the box appears empty."); - you.weapon()->sub_type = MISC_EMPTY_EBONY_CASKET; + box.sub_type = MISC_EMPTY_EBONY_CASKET; } } @@ -1077,7 +779,298 @@ static bool _ball_of_fixation(void) const int duration = random_range(15, 40); you.duration[DUR_PARALYSIS] = duration; - you.duration[DUR_SLOW] = duration; + you.duration[DUR_SLOW] = duration; return (true); } + +bool evoke_item(int slot) +{ + if (you.duration[DUR_BERSERKER]) + { + canned_msg( MSG_TOO_BERSERK ); + return (false); + } + + if (player_in_bat_form()) + { + canned_msg(MSG_PRESENT_FORM); + return (false); + } + + if (slot == -1) + { + 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); + + 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(item, OPER_EVOKE)) + return (false); + + 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: + ASSERT(wielded); + + if (get_weapon_brand(item) == SPWPN_REACHING) + { + if (_reaching_weapon_attack(item)) + { + pract = 0; + did_work = true; + } + else + return (false); + } + else if (is_fixed_artefact(item)) + { + switch (item.special) + { + case SPWPN_STAFF_OF_DISPATER: + if (you.duration[DUR_DEATHS_DOOR] || !enough_hp(11, true) + || !enough_mp(5, true)) + { + break; + } + + mpr("You feel the staff feeding on your energy!"); + + dec_hp( 5 + random2avg(19, 2), false, "Staff of Dispater" ); + dec_mp( 2 + random2avg(5, 2) ); + make_hungry(100, false, true); + + power = you.skills[SK_EVOCATIONS] * 8; + your_spells( SPELL_HELLFIRE, power, false ); + pract = (coinflip() ? 2 : 1); + did_work = true; + break; + + case SPWPN_SCEPTRE_OF_ASMODEUS: + if (evoke_sceptre_of_asmodeus()) + { + make_hungry(200, false, true); + did_work = true; + pract = 1; + } + break; + + case SPWPN_STAFF_OF_OLGREB: + if (!enough_mp( 4, true ) + || you.skills[SK_EVOCATIONS] < random2(6)) + { + break; + } + + dec_mp(4); + make_hungry(50, false, true); + pract = 1; + did_work = true; + + power = 10 + you.skills[SK_EVOCATIONS] * 8; + + your_spells( SPELL_OLGREBS_TOXIC_RADIANCE, power, false ); + + if (x_chance_in_y(you.skills[SK_EVOCATIONS] + 1, 10)) + your_spells( SPELL_VENOM_BOLT, power, false ); + break; + + case SPWPN_STAFF_OF_WUCAD_MU: + if (you.magic_points == you.max_magic_points + || you.skills[SK_EVOCATIONS] < random2(25)) + { + break; + } + + mpr("Magical energy flows into your mind!"); + + inc_mp( 3 + random2(5) + you.skills[SK_EVOCATIONS] / 3, false ); + make_hungry(50, false, true); + pract = 1; + did_work = true; + + if (one_chance_in(3)) + { + // NH_NEVER prevents "nothing happens" messages. + MiscastEffect( &you, NON_MONSTER, SPTYP_DIVINATION, + random2(9), random2(70), + "the Staff of Wucad Mu", NH_NEVER ); + } + break; + + default: + unevokable = true; + break; + } + } + else + unevokable = true; + break; + + case OBJ_STAVES: + ASSERT(wielded); + + if (item_is_rod( item )) + { + 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 (item.sub_type == STAFF_CHANNELING) + { + if (you.magic_points < you.max_magic_points + && x_chance_in_y(you.skills[SK_EVOCATIONS] + 11, 40)) + { + mpr("You channel some magical energy."); + inc_mp( 1 + random2(3), false ); + make_hungry(50, false, true); + pract = 1; + did_work = true; + + if (!item_type_known(item)) + { + set_ident_type( OBJ_STAVES, item.sub_type, ID_KNOWN_TYPE ); + set_ident_flags( item, ISFLAG_KNOW_TYPE ); + + mprf("You are wielding %s.", + item.name(DESC_NOCAP_A).c_str()); + + more(); + + you.wield_change = true; + } + } + } + else + { + unevokable = true; + } + break; + + case OBJ_MISCELLANY: + did_work = true; // easier to do it this way for misc items + + if (is_deck(item)) + { + ASSERT(wielded); + evoke_deck(item); + pract = 1; + break; + } + + switch (item.sub_type) + { + case MISC_BOTTLED_EFREET: + if (_efreet_flask(slot)) + pract = 2; + break; + + case MISC_CRYSTAL_BALL_OF_SEEING: + if (_ball_of_seeing()) + pract = 1; + break; + + case MISC_AIR_ELEMENTAL_FAN: + if (you.skills[SK_EVOCATIONS] <= random2(30)) + canned_msg(MSG_NOTHING_HAPPENS); + else + { + cast_summon_elemental(100, GOD_NO_GOD, MONS_AIR_ELEMENTAL, 4); + pract = (one_chance_in(5) ? 1 : 0); + } + break; + + case MISC_LAMP_OF_FIRE: + if (you.skills[SK_EVOCATIONS] <= random2(30)) + canned_msg(MSG_NOTHING_HAPPENS); + else + { + cast_summon_elemental(100, GOD_NO_GOD, MONS_FIRE_ELEMENTAL, 4); + pract = (one_chance_in(5) ? 1 : 0); + } + break; + + case MISC_STONE_OF_EARTH_ELEMENTALS: + if (you.skills[SK_EVOCATIONS] <= random2(30)) + canned_msg(MSG_NOTHING_HAPPENS); + else + { + cast_summon_elemental(100, GOD_NO_GOD, MONS_EARTH_ELEMENTAL, 4); + pract = (one_chance_in(5) ? 1 : 0); + } + break; + + case MISC_HORN_OF_GERYON: + if (evoke_horn_of_geryon()) + pract = 1; + break; + + case MISC_BOX_OF_BEASTS: + if (_box_of_beasts(item)) + pract = 1; + break; + + case MISC_CRYSTAL_BALL_OF_ENERGY: + if (_ball_of_energy()) + pract = 1; + break; + + case MISC_CRYSTAL_BALL_OF_FIXATION: + if (_ball_of_fixation()) + pract = 1; + break; + + case MISC_DISC_OF_STORMS: + if (_disc_of_storms()) + pract = (coinflip() ? 2 : 1); + break; + + default: + did_work = false; + unevokable = true; + break; + } + break; + + default: + unevokable = true; + break; + } + + if (!did_work) + canned_msg(MSG_NOTHING_HAPPENS); + else if (pract > 0) + exercise( SK_EVOCATIONS, pract ); + + if (!unevokable) + you.turn_is_over = true; + else + crawl_state.zero_turns_taken(); + + return (did_work); +} diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 961dd0842b..60547947e4 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -5491,8 +5491,8 @@ void tile_item_use(int idx) evoke_item(idx); return; } - // Unwield staves or weapons. - if (check_warning_inscriptions(item, OPER_WIELD)) + // Unwield wielded items. + if (equipped && check_warning_inscriptions(item, OPER_WIELD)) wield_weapon(true, PROMPT_GOT_SPECIAL); // unwield return; diff --git a/crawl-ref/source/tilereg.cc b/crawl-ref/source/tilereg.cc index 4e5a2e06bb..11bc7df8da 100644 --- a/crawl-ref/source/tilereg.cc +++ b/crawl-ref/source/tilereg.cc @@ -1571,6 +1571,10 @@ static bool _is_true_equipped_item(item_def item) // apart from dropping it. static bool _can_use_item(const item_def &item, bool equipped) { + // There's nothing you can do with an empty box if you can't unwield it. + if (!equipped && item.sub_type == MISC_EMPTY_EBONY_CASKET) + return (false); + // Vampires can drain corpses. if (item.base_type == OBJ_CORPSES) { @@ -1691,7 +1695,6 @@ bool InventoryRegion::update_tip_text(std::string& tip) // first equipable categories case OBJ_WEAPONS: case OBJ_STAVES: - case OBJ_MISCELLANY: tip += "Wield (w)"; if (is_throwable(&you, item)) tip += "\n[Ctrl-L-Click] Fire (f)"; @@ -1701,6 +1704,15 @@ bool InventoryRegion::update_tip_text(std::string& tip) if (is_throwable(&you, item)) tip += "\n[Ctrl-L-Click] Fire (f)"; break; + case OBJ_MISCELLANY: + if (item.sub_type >= MISC_DECK_OF_ESCAPE + && item.sub_type <= MISC_DECK_OF_DEFENCE) + { + tip += "Wield (w)"; + break; + } + tip += "Evoke (V)"; + break; case OBJ_MISCELLANY + EQUIP_OFFSET: if (item.sub_type >= MISC_DECK_OF_ESCAPE && item.sub_type <= MISC_DECK_OF_DEFENCE) |