summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-03-03 23:09:10 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-03-03 23:09:10 +0000
commit30e4163e934e8f9dcd201e1cfba1a13a7f3b79c3 (patch)
treec10066a70df3e56145fc9d36cfc8986415b8d3d1
parent610652dba6b72b800879510c3e715c1aeb4e5747 (diff)
downloadcrawl-ref-30e4163e934e8f9dcd201e1cfba1a13a7f3b79c3.tar.gz
crawl-ref-30e4163e934e8f9dcd201e1cfba1a13a7f3b79c3.zip
[FR 1903593] Change identification process of
?recharging, ?enchant armour and ?identify. If you read one of these scrolls and the type isn't known yet you are prompted with "Modify which item?" (better message needed!) and get to choose from the entire inventory. If the chosen item can be usefully "modified" by the scroll (unID'd item for identify, wand for recharging, enchantable armour for EA) the usual effect takes place and the scroll is identified. (Reading other scrolls of the same type will then only offer a more sensible selection of items.) Otherwise, nothing happens. Further, recharging and enchant armour now allow direct choice of the item in question, and it doesn't even have to be wielded or worn. I think this change actually makes the id game more interesting and also improves the interface. Gameplay might dictate that we reintroduce the "armour needs to be worn" rule, but that remains to be seen until after some more playtesting. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3514 c06c8d41-db1a-0410-9941-cceddc491573
-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}