diff options
-rw-r--r-- | crawl-ref/source/effects.cc | 32 | ||||
-rw-r--r-- | crawl-ref/source/effects.h | 2 | ||||
-rw-r--r-- | crawl-ref/source/invent.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/invent.h | 4 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 239 | ||||
-rw-r--r-- | crawl-ref/source/item_use.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/itemprop.cc | 41 | ||||
-rw-r--r-- | crawl-ref/source/itemprop.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/spells1.cc | 11 | ||||
-rw-r--r-- | crawl-ref/source/spells1.h | 2 |
10 files changed, 220 insertions, 121 deletions
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index ee8c14b65c..00e0b348af 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -27,6 +27,7 @@ #include "dgnevent.h" #include "food.h" #include "hiscores.h" +#include "invent.h" #include "it_use2.h" #include "item_use.h" #include "itemname.h" @@ -1697,12 +1698,37 @@ bool acquirement(object_class_type class_wanted, int agent, return (true); } // end acquirement() -bool recharge_wand(void) +bool recharge_wand(int item_slot) { - if (you.equip[EQ_WEAPON] == -1) + if (item_slot == -1) + item_slot = prompt_invent_item( "Charge which item?", MT_INVLIST, + OSEL_RECHARGE, true, true, false ); + + if (item_slot == PROMPT_ABORT) + { + canned_msg( MSG_OK ); return (false); + } + + item_def &wand = you.inv[ item_slot ]; + + if (wand.base_type == OBJ_WEAPONS + && !is_random_artefact( wand ) + && !is_fixed_artefact( wand ) + && get_weapon_brand( wand ) == SPWPN_ELECTROCUTION) + { + // might fail because of already high enchantment + if (enchant_weapon( ENCHANT_TO_DAM, false, item_slot )) + { + you.wield_change = true; - item_def &wand = you.inv[ you.equip[EQ_WEAPON] ]; + if (!item_ident(wand, ISFLAG_KNOW_TYPE)) + set_ident_flags(wand, ISFLAG_KNOW_TYPE); + + return (true); + } + return (false); + } if (wand.base_type != OBJ_WANDS && !item_is_rod(wand)) return (false); diff --git a/crawl-ref/source/effects.h b/crawl-ref/source/effects.h index 115af95922..eb8661c0c7 100644 --- a/crawl-ref/source/effects.h +++ b/crawl-ref/source/effects.h @@ -72,7 +72,7 @@ bool acquirement(object_class_type force_class, int agent, /* *********************************************************************** * called from: item_use * *********************************************************************** */ -bool recharge_wand(void); +bool recharge_wand(const int item_slot = -1); // last updated 12may2000 {dlb} diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc index 53289b4036..68340be502 100644 --- a/crawl-ref/source/invent.cc +++ b/crawl-ref/source/invent.cc @@ -759,6 +759,10 @@ static bool item_class_selected(const item_def &i, int selector) && (i.sub_type != BOOK_DESTRUCTION || !item_type_known(i))); case OBJ_SCROLLS: return (itype == OBJ_SCROLLS || itype == OBJ_BOOKS); + case OSEL_RECHARGE: + return (item_is_rechargable(i), true); + case OSEL_ENCH_ARM: + return (is_enchantable_armour(i, true)); case OSEL_EQUIP: for (int eq = 0; eq < NUM_EQUIP; eq++) { diff --git a/crawl-ref/source/invent.h b/crawl-ref/source/invent.h index f3473810fd..df77475a8b 100644 --- a/crawl-ref/source/invent.h +++ b/crawl-ref/source/invent.h @@ -26,7 +26,9 @@ enum object_selector OSEL_WIELD = -2, OSEL_UNIDENT = -3, OSEL_EQUIP = -4, - OSEL_MEMORISE = -5 + OSEL_MEMORISE = -5, + OSEL_RECHARGE = -6, + OSEL_ENCH_ARM = -7 }; #define PROMPT_ABORT -1 diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 2e2628a836..0cc7a3f3cc 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -81,7 +81,7 @@ #include "xom.h" static bool drink_fountain(); -static bool enchant_armour(); +static bool enchant_armour(int item_slot = -1); static int _fire_prompt_for_item(std::string& err); static bool _fire_validate_item(int selected, std::string& err); @@ -3788,9 +3788,11 @@ static bool affix_weapon_enchantment() return (success); } -bool enchant_weapon( enchant_stat_type which_stat, bool quiet ) +bool enchant_weapon( enchant_stat_type which_stat, bool quiet, int wpn ) { - const int wpn = you.equip[ EQ_WEAPON ]; + if (wpn == -1) + wpn = you.equip[ EQ_WEAPON ]; + bool affected = true; int enchant_level; @@ -3889,76 +3891,65 @@ bool enchant_weapon( enchant_stat_type which_stat, bool quiet ) return (true); } -static bool enchant_armour( void ) +static bool enchant_armour( int item_slot ) { - // NOTE: It is assumed that armour which changes in this way does - // not change into a form of armour with a different evasion modifier. - int nthing = you.equip[EQ_BODY_ARMOUR]; - - if (nthing != -1 - && (you.inv[nthing].sub_type == ARM_DRAGON_HIDE - || you.inv[nthing].sub_type == ARM_ICE_DRAGON_HIDE - || you.inv[nthing].sub_type == ARM_STEAM_DRAGON_HIDE - || you.inv[nthing].sub_type == ARM_MOTTLED_DRAGON_HIDE - || you.inv[nthing].sub_type == ARM_STORM_DRAGON_HIDE - || you.inv[nthing].sub_type == ARM_GOLD_DRAGON_HIDE - || you.inv[nthing].sub_type == ARM_SWAMP_DRAGON_HIDE - || you.inv[nthing].sub_type == ARM_TROLL_HIDE)) - { - mprf("%s glows purple and changes!", - you.inv[you.equip[EQ_BODY_ARMOUR]].name(DESC_CAP_YOUR).c_str()); + if (item_slot == -1) + item_slot = prompt_invent_item( "Enchant which item?", MT_INVLIST, + OSEL_ENCH_ARM, true, true, false ); - you.redraw_armour_class = 1; - - hide2armour(you.inv[nthing]); - return (true); + if (item_slot == PROMPT_ABORT) + { + canned_msg( MSG_OK ); + return (false); } - // pick random piece of armour - int count = 0; - int affected_slot = EQ_WEAPON; - - for (int i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++) - { - if (you.equip[i] != -1) - { - count++; - if (one_chance_in( count )) - affected_slot = i; - } - } + item_def& arm(you.inv[item_slot]); - // no armour == no enchantment - if (affected_slot == EQ_WEAPON) + // cannot be enchanted nor uncursed + if (!is_enchantable_armour(arm, true)) { - canned_msg(MSG_NOTHING_HAPPENS); + canned_msg( MSG_NOTHING_HAPPENS ); return (false); } - bool affected = true; - item_def &item = you.inv[you.equip[ affected_slot ]]; - - if (is_random_artefact( item ) - || ((item.sub_type >= ARM_CLOAK && item.sub_type <= ARM_BOOTS) - && item.plus >= 2) - || ((item.sub_type == ARM_SHIELD - || item.sub_type == ARM_BUCKLER - || item.sub_type == ARM_LARGE_SHIELD) - && item.plus >= 2) - || (item.plus >= 3 && random2(8) < item.plus)) + bool is_cursed = item_cursed(arm); + + // Turn hides into mails where applicable. + // NOTE: It is assumed that armour which changes in this way does + // not change into a form of armour with a different evasion modifier. + if (arm.sub_type == ARM_DRAGON_HIDE + || arm.sub_type == ARM_ICE_DRAGON_HIDE + || arm.sub_type == ARM_STEAM_DRAGON_HIDE + || arm.sub_type == ARM_MOTTLED_DRAGON_HIDE + || arm.sub_type == ARM_STORM_DRAGON_HIDE + || arm.sub_type == ARM_GOLD_DRAGON_HIDE + || arm.sub_type == ARM_SWAMP_DRAGON_HIDE + || arm.sub_type == ARM_TROLL_HIDE) { - affected = false; + mprf("%s glows purple and changes!", + arm.name(DESC_CAP_YOUR).c_str()); + + hide2armour(arm); + + if (is_cursed) + do_uncurse_item( arm ); + + you.redraw_armour_class = 1; + + // no additional enchantment + return (true); } // even if not affected, it may be uncursed. - if (!affected) + if (!is_enchantable_armour(arm, false) + || arm.plus >= 3 && random2(8) < arm.plus) { - if (item_cursed( item )) + if (is_cursed) { mprf("%s glows silver for a moment.", - item.name(DESC_CAP_YOUR).c_str()); - - do_uncurse_item( item ); + arm.name(DESC_CAP_YOUR).c_str()); + + do_uncurse_item( arm ); return (true); } else @@ -3968,13 +3959,15 @@ static bool enchant_armour( void ) } } - // vVvVv This is *here* for a reason! + // output message before changing enchantment and curse status mprf("%s glows green for a moment.", - item.name(DESC_CAP_YOUR).c_str()); + arm.name(DESC_CAP_YOUR).c_str()); - item.plus++; + arm.plus++; - do_uncurse_item( item ); + if (is_cursed) + do_uncurse_item( arm ); + you.redraw_armour_class = 1; xom_is_stimulated(16); return (true); @@ -4021,6 +4014,54 @@ static void handle_read_book( int item_slot ) } } +// returns true if the scroll had an obvious effect and should be identified +static bool scroll_modify_item(const scroll_type scroll) +{ + int item_slot = prompt_invent_item( "Modify which item?", MT_INVLIST, + OSEL_ANY, true, true, false ); + + if (item_slot == PROMPT_ABORT) + { + canned_msg( MSG_OK ); + return (false); + } + + item_def &item = you.inv[item_slot]; + + switch (scroll) + { + case SCR_IDENTIFY: + if ( !fully_identified(item) ) + { + mpr("This is a scroll of identify!"); + identify(-1, item_slot); + return (true); + } + break; + case SCR_RECHARGING: + if (item_is_rechargable(item)) + { + mpr("This is a scroll of recharging!"); + recharge_wand(item_slot); + return (true); + } + case SCR_ENCHANT_ARMOUR: + if (is_enchantable_armour(item, true)) + { + // might still fail because of already high enchantment + if (enchant_armour(item_slot)) + return (true); + return (false); + } + default: + break; + } + + // Oops, wrong item... + canned_msg(MSG_NOTHING_HAPPENS); + return (false); +} + void read_scroll( int slot ) { int affected = 0; @@ -4096,19 +4137,19 @@ void read_scroll( int slot ) } // decrement and handle inventory if any scroll other than paper {dlb}: - const int scroll_type = scroll.sub_type; - if (scroll_type != SCR_PAPER && - (scroll_type != SCR_IMMOLATION || you.duration[DUR_CONF])) + const scroll_type which_scroll = static_cast<scroll_type>(scroll.sub_type); + if (which_scroll != SCR_PAPER && + (which_scroll != SCR_IMMOLATION || you.duration[DUR_CONF])) { mpr("As you read the scroll, it crumbles to dust."); // Actual removal of scroll done afterwards. -- bwr } const bool alreadyknown = item_type_known(scroll); - const bool dangerous = player_in_a_dangerous_place(); + const bool dangerous = player_in_a_dangerous_place(); // scrolls of paper are also exempted from this handling {dlb}: - if (scroll_type != SCR_PAPER) + if (which_scroll != SCR_PAPER) { if (you.duration[DUR_CONF]) { @@ -4125,7 +4166,7 @@ void read_scroll( int slot ) // it is the exception, not the rule, that // the scroll will not be identified {dlb}: - switch (scroll_type) + switch (which_scroll) { case SCR_PAPER: // remember paper scrolls handled as special case above, too: @@ -4239,22 +4280,6 @@ void read_scroll( int slot ) explosion(beam); break; - case SCR_IDENTIFY: - if ( !item_type_known(scroll) ) - { - mpr("This is a scroll of identify!"); - more(); - } - - set_ident_flags( you.inv[item_slot], ISFLAG_IDENT_MASK ); - - // important {dlb} - set_ident_type( OBJ_SCROLLS, SCR_IDENTIFY, ID_KNOWN_TYPE ); - - identify(-1); - you.wield_change = true; - break; - case SCR_CURSE_WEAPON: nthing = you.equip[EQ_WEAPON]; @@ -4344,35 +4369,25 @@ void read_scroll( int slot ) set_item_ego_type( you.inv[nthing], OBJ_WEAPONS, SPWPN_VORPAL ); break; - case SCR_RECHARGING: - nthing = you.equip[EQ_WEAPON]; - - if (nthing != -1 - && !is_random_artefact( you.inv[nthing] ) - && !is_fixed_artefact( you.inv[nthing] ) - && get_weapon_brand( you.inv[nthing] ) == SPWPN_ELECTROCUTION) - { - id_the_scroll = enchant_weapon( ENCHANT_TO_DAM ); - - if (!item_ident(you.inv[nthing], ISFLAG_KNOW_TYPE)) - { - if (item_type_known(scroll)) - set_ident_flags(you.inv[nthing], ISFLAG_KNOW_TYPE); - else - id_the_scroll = false; - } - break; - } + case SCR_IDENTIFY: + if ( !item_type_known(scroll) ) + id_the_scroll = scroll_modify_item(which_scroll); + else + identify(-1); + break; - if (!recharge_wand()) - { - canned_msg(MSG_NOTHING_HAPPENS); - id_the_scroll = false; - } + case SCR_RECHARGING: + if ( !item_type_known(scroll) ) + id_the_scroll = scroll_modify_item(which_scroll); + else + recharge_wand(-1); break; case SCR_ENCHANT_ARMOUR: - id_the_scroll = enchant_armour(); + if ( !item_type_known(scroll) ) + id_the_scroll = scroll_modify_item(which_scroll); + else + enchant_armour(-1); break; case SCR_CURSE_ARMOUR: @@ -4429,11 +4444,15 @@ void read_scroll( int slot ) you.duration[DUR_PIETY_POOL] = 500; } } + break; + default: + mpr("Read a buggy scroll, please report this."); + break; } // end switch // finally, destroy and identify the scroll // scrolls of immolation were already destroyed earlier - if (scroll_type != SCR_PAPER && scroll_type != SCR_IMMOLATION) + if (which_scroll != SCR_PAPER && which_scroll != SCR_IMMOLATION) { if ( id_the_scroll ) set_ident_flags( scroll, ISFLAG_KNOW_TYPE ); // for notes @@ -4441,7 +4460,7 @@ void read_scroll( int slot ) dec_inv_item_quantity( item_slot, 1 ); } - set_ident_type( OBJ_SCROLLS, scroll_type, + set_ident_type( OBJ_SCROLLS, which_scroll, (id_the_scroll) ? ID_KNOWN_TYPE : ID_TRIED_TYPE ); if (!alreadyknown && dangerous) diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h index 0efea498a3..07de89103d 100644 --- a/crawl-ref/source/item_use.h +++ b/crawl-ref/source/item_use.h @@ -160,7 +160,8 @@ void use_randart(item_def &item); bool puton_item(int slot, bool prompt_finger = true); -bool enchant_weapon( enchant_stat_type which_stat, bool quiet = false ); +bool enchant_weapon( enchant_stat_type which_stat, bool quiet = false, + int wpn = -1 ); bool throw_it(bolt &pbolt, int throw_2, bool teleport=false, int acc_bonus=0, dist *target = NULL); diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc index 86e20cd1d2..73e90c32dd 100644 --- a/crawl-ref/source/itemprop.cc +++ b/crawl-ref/source/itemprop.cc @@ -1284,6 +1284,47 @@ bool check_armour_shape( const item_def &item, bool quiet ) return (true); } +bool item_is_rechargable(const item_def &it, bool known) +{ + // These are obvious + if (it.base_type == OBJ_WANDS || item_is_rod(it)) + return (true); + + // ... but electro-weapons can also be charged + return ( it.base_type == OBJ_WEAPONS + && !is_random_artefact( it ) + && !is_fixed_artefact( it ) + && get_weapon_brand( it ) == SPWPN_ELECTROCUTION + && (!known || item_type_known(it)) ); +} + +bool is_enchantable_armour(const item_def &arm, bool uncurse) +{ + if (arm.base_type != OBJ_ARMOUR) + return (false); + + // only equipped items should be affected +// if (!item_is_equipped(arm)) +// return (false); + + // artefacts cannot be enchanted + if (is_fixed_artefact( arm ) + || is_random_artefact( arm )) + { + return (uncurse && item_cursed( arm )); // ?EA may uncurse artefacts + } + + // Nor can highly enchanted items + if ( arm.plus >= 2 + && (arm.sub_type >= ARM_CLOAK && arm.sub_type <= ARM_BOOTS + || is_shield(arm)) ) + { + return (uncurse && item_cursed( arm )); // ?EA may uncurse item + } + + return (true); +} + // // Weapon information and checking functions: // diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h index 34c0f747d9..38f6b169e8 100644 --- a/crawl-ref/source/itemprop.h +++ b/crawl-ref/source/itemprop.h @@ -629,6 +629,9 @@ int fit_armour_size( const item_def &item, size_type size ); bool check_armour_size( const item_def &item, size_type size ); bool check_armour_shape( const item_def &item, bool quiet ); +bool item_is_rechargable(const item_def &it, bool known = false); +bool is_enchantable_armour(const item_def &arm, bool uncurse); + // weapon functions: int weapon_rarity( int w_type ); diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc index 0ca5d6284b..9a4af6bf8e 100644 --- a/crawl-ref/source/spells1.cc +++ b/crawl-ref/source/spells1.cc @@ -420,10 +420,9 @@ void cast_chain_lightning( int powc ) more(); } -void identify(int power) +void identify(int power, int item_slot) { int id_used = 1; - int item_slot; // scrolls of identify *may* produce "extra" identifications {dlb}: if (power == -1 && one_chance_in(5)) @@ -431,8 +430,9 @@ void identify(int power) do { - item_slot = prompt_invent_item( "Identify which item?", MT_INVLIST, - OSEL_UNIDENT, true, true, false ); + if (item_slot == -1) + item_slot = prompt_invent_item( "Identify which item?", MT_INVLIST, + OSEL_UNIDENT, true, true, false ); if (item_slot == PROMPT_ABORT) { canned_msg( MSG_OK ); @@ -463,6 +463,9 @@ void identify(int power) if (Options.auto_list && id_used > 0) more(); + + // in case we get to try again + item_slot = -1; } while (id_used > 0); } // end identify() diff --git a/crawl-ref/source/spells1.h b/crawl-ref/source/spells1.h index 00881795be..ac1eb282ed 100644 --- a/crawl-ref/source/spells1.h +++ b/crawl-ref/source/spells1.h @@ -119,7 +119,7 @@ void antimagic(); /* *********************************************************************** * called from: acr (WIZARD only) - item_use - spell * *********************************************************************** */ -void identify(int power); +void identify(int power, int item_slot = -1); // last updated 24may2000 {dlb} |