summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/effects.cc32
-rw-r--r--crawl-ref/source/effects.h2
-rw-r--r--crawl-ref/source/invent.cc4
-rw-r--r--crawl-ref/source/invent.h4
-rw-r--r--crawl-ref/source/item_use.cc239
-rw-r--r--crawl-ref/source/item_use.h3
-rw-r--r--crawl-ref/source/itemprop.cc41
-rw-r--r--crawl-ref/source/itemprop.h3
-rw-r--r--crawl-ref/source/spells1.cc11
-rw-r--r--crawl-ref/source/spells1.h2
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}