summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authordolorous <dolorous@c06c8d41-db1a-0410-9941-cceddc491573>2008-03-23 21:46:25 +0000
committerdolorous <dolorous@c06c8d41-db1a-0410-9941-cceddc491573>2008-03-23 21:46:25 +0000
commit4199cb903775df050465148d7ade49daf09fac39 (patch)
tree80945903f518f9711e28c413438e51d9890473d8 /crawl-ref
parent9e511702e814c94093bb77ae460f8be8b7a49b16 (diff)
downloadcrawl-ref-4199cb903775df050465148d7ade49daf09fac39.tar.gz
crawl-ref-4199cb903775df050465148d7ade49daf09fac39.zip
Add a weapon enchantment blessing that will enchant a monster's weapon
by two points (either this or armor enchantment blessing can occur, with 5% rarity). Whether to-hit or to-damage is chosen is random. Split handling of weapon enchantment into enchant_weapon() for the generic item routines, and handle_enchant_weapon() for the player-specific routines. Furthermore, make enchant_weapon() and enchant_armour() more similar in terms of structure. Also, in bless_follower(), store the blessing description and monster name in std::strings instead of const char*'s. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@3839 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/effects.cc6
-rw-r--r--crawl-ref/source/invent.cc2
-rw-r--r--crawl-ref/source/item_use.cc128
-rw-r--r--crawl-ref/source/item_use.h3
-rw-r--r--crawl-ref/source/itemprop.cc29
-rw-r--r--crawl-ref/source/itemprop.h1
-rw-r--r--crawl-ref/source/religion.cc74
7 files changed, 151 insertions, 92 deletions
diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc
index fddc3d2efd..257e58e237 100644
--- a/crawl-ref/source/effects.cc
+++ b/crawl-ref/source/effects.cc
@@ -1715,18 +1715,16 @@ bool recharge_wand(int item_slot)
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 ))
+ if ( enchant_weapon( ENCHANT_TO_DAM, false, wand ))
{
you.wield_change = true;
if (!item_ident(wand, ISFLAG_KNOW_TYPE))
set_ident_flags(wand, ISFLAG_KNOW_TYPE);
-
+
return (true);
}
return (false);
diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc
index bee34b1cb7..cb7d0c78ac 100644
--- a/crawl-ref/source/invent.cc
+++ b/crawl-ref/source/invent.cc
@@ -757,7 +757,7 @@ static bool item_class_selected(const item_def &i, int selector)
return (itype == OBJ_MISSILES || itype == OBJ_WEAPONS);
case OBJ_WEAPONS:
case OSEL_WIELD:
- return (itype == OBJ_WEAPONS || itype == OBJ_STAVES
+ return (itype == OBJ_WEAPONS || itype == OBJ_STAVES
|| itype == OBJ_MISCELLANY);
case OSEL_MEMORISE:
return (itype == OBJ_BOOKS && i.sub_type != BOOK_MANUAL
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index f818edac69..d13c85b591 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -81,6 +81,8 @@
#include "xom.h"
static bool drink_fountain();
+static bool handle_enchant_weapon( enchant_stat_type which_stat,
+ bool quiet = false, int item_slot = -1 );
static bool handle_enchant_armour( int item_slot = -1 );
static int _fire_prompt_for_item(std::string& err);
@@ -3812,64 +3814,39 @@ static bool affix_weapon_enchantment()
return (success);
}
-bool enchant_weapon( enchant_stat_type which_stat, bool quiet, int wpn )
+bool enchant_weapon( enchant_stat_type which_stat, bool quiet, item_def &wpn )
{
- if (wpn == -1)
- wpn = you.equip[ EQ_WEAPON ];
-
- bool affected = true;
- int enchant_level;
-
- if (wpn == -1
- || (you.inv[ wpn ].base_type != OBJ_WEAPONS
- && you.inv[ wpn ].base_type != OBJ_MISSILES))
+ // cannot be enchanted nor uncursed
+ if (!is_enchantable_weapon(wpn, true))
{
if (!quiet)
- canned_msg(MSG_NOTHING_HAPPENS);
+ canned_msg( MSG_NOTHING_HAPPENS );
return (false);
}
- item_def& item = you.inv[wpn];
-
- you.wield_change = true;
+ const bool is_cursed = item_cursed(wpn);
// missiles only have one stat
- if (item.base_type == OBJ_MISSILES)
+ if (wpn.base_type == OBJ_MISSILES)
which_stat = ENCHANT_TO_HIT;
- if (which_stat == ENCHANT_TO_HIT)
- enchant_level = item.plus;
- else
- enchant_level = item.plus2;
-
- // artefacts can't be enchanted, but scrolls still remove curses
- if (item.base_type == OBJ_WEAPONS
- && (is_fixed_artefact( you.inv[wpn] )
- || is_random_artefact( you.inv[wpn] )))
- {
- affected = false;
- }
-
- if (enchant_level >= 4 && random2(9) < enchant_level)
- {
- affected = false;
- }
+ int enchant_level = (which_stat == ENCHANT_TO_HIT) ? wpn.plus
+ : wpn.plus2;
- // if it isn't affected by the enchantment, it will still
- // be uncursed.
- if (!affected)
+ // Even if not affected, it may be uncursed.
+ if (!is_enchantable_weapon(wpn, false)
+ || enchant_level >= 4 && random2(9) < enchant_level)
{
- if (item_cursed(item))
+ if (is_cursed)
{
if (!quiet)
{
mprf("%s glows silver for a moment.",
- item.name(DESC_CAP_YOUR).c_str());
+ wpn.name(DESC_CAP_YOUR).c_str());
}
- do_uncurse_item( you.inv[you.equip[EQ_WEAPON]] );
-
+ do_uncurse_item( wpn );
return (true);
}
else
@@ -3881,43 +3858,62 @@ bool enchant_weapon( enchant_stat_type which_stat, bool quiet, int wpn )
}
}
- // Get the item name now before the enchantment changes it.
- std::string iname = item.name(DESC_CAP_YOUR);
-
- do_uncurse_item( item );
+ // get item name now before changing enchantment
+ std::string iname = wpn.name(DESC_CAP_YOUR);
- if (item.base_type == OBJ_WEAPONS)
+ if (wpn.base_type == OBJ_WEAPONS)
{
- if (which_stat == ENCHANT_TO_DAM)
+ if (which_stat == ENCHANT_TO_HIT)
{
- item.plus2++;
-
if (!quiet)
- mprf("%s glows red for a moment.", iname.c_str());
+ mprf("%s glows green for a moment.", iname.c_str());
+
+ wpn.plus++;
}
- else if (which_stat == ENCHANT_TO_HIT)
+ else
{
- item.plus++;
-
if (!quiet)
- mprf("%s glows green for a moment.", iname.c_str());
+ mprf("%s glows red for a moment.", iname.c_str());
+
+ wpn.plus2++;
}
}
- else if (item.base_type == OBJ_MISSILES)
+ else if (wpn.base_type == OBJ_MISSILES)
{
if (!quiet)
{
mprf("%s %s red for a moment.", iname.c_str(),
- item.quantity > 1 ? "glow" : "glows");
+ wpn.quantity > 1 ? "glow" : "glows");
}
- item.plus++;
+ wpn.plus++;
}
+ if (is_cursed)
+ do_uncurse_item( wpn );
+
xom_is_stimulated(16);
return (true);
}
+static bool handle_enchant_weapon( enchant_stat_type which_stat,
+ bool quiet, int item_slot )
+{
+ if (item_slot == -1)
+ item_slot = you.equip[ EQ_WEAPON ];
+
+ if (item_slot == -1)
+ return (false);
+
+ item_def& wpn(you.inv[item_slot]);
+
+ bool result = enchant_weapon(which_stat, quiet, wpn);
+
+ you.wield_change = true;
+
+ return result;
+}
+
bool enchant_armour( int &ac_change, bool quiet, item_def &arm )
{
ac_change = 0;
@@ -3927,10 +3923,11 @@ bool enchant_armour( int &ac_change, bool quiet, item_def &arm )
{
if (!quiet)
canned_msg( MSG_NOTHING_HAPPENS );
+
return (false);
}
- bool is_cursed = item_cursed(arm);
+ const bool is_cursed = item_cursed(arm);
// Turn hides into mails where applicable.
// NOTE: It is assumed that armour which changes in this way does
@@ -3973,6 +3970,7 @@ bool enchant_armour( int &ac_change, bool quiet, item_def &arm )
{
if (!quiet)
canned_msg( MSG_NOTHING_HAPPENS );
+
return (false);
}
}
@@ -4000,7 +3998,7 @@ static bool handle_enchant_armour( int item_slot )
item_slot = prompt_invent_item( "Enchant which item?", MT_INVLIST,
OSEL_ENCH_ARM, true, true, false );
- if (item_slot == PROMPT_ABORT)
+ if (item_slot == -1)
{
canned_msg( MSG_OK );
return (false);
@@ -4353,11 +4351,11 @@ void read_scroll( int slot )
// everything [in the switch] below this line is a nightmare {dlb}:
case SCR_ENCHANT_WEAPON_I:
- id_the_scroll = enchant_weapon( ENCHANT_TO_HIT );
+ id_the_scroll = handle_enchant_weapon( ENCHANT_TO_HIT );
break;
case SCR_ENCHANT_WEAPON_II:
- id_the_scroll = enchant_weapon( ENCHANT_TO_DAM );
+ id_the_scroll = handle_enchant_weapon( ENCHANT_TO_DAM );
break;
case SCR_ENCHANT_WEAPON_III:
@@ -4372,17 +4370,17 @@ void read_scroll( int slot )
mprf("%s glows bright yellow for a while.", iname.c_str() );
- enchant_weapon( ENCHANT_TO_HIT, true );
+ do_uncurse_item( you.inv[you.equip[EQ_WEAPON]] );
+
+ handle_enchant_weapon( ENCHANT_TO_HIT, true );
if (coinflip())
- enchant_weapon( ENCHANT_TO_HIT, true );
+ handle_enchant_weapon( ENCHANT_TO_HIT, true );
- enchant_weapon( ENCHANT_TO_DAM, true );
+ handle_enchant_weapon( ENCHANT_TO_DAM, true );
if (coinflip())
- enchant_weapon( ENCHANT_TO_DAM, true );
-
- do_uncurse_item( you.inv[you.equip[EQ_WEAPON]] );
+ handle_enchant_weapon( ENCHANT_TO_DAM, true );
}
}
else
diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h
index 1c79a93ecc..997f84b741 100644
--- a/crawl-ref/source/item_use.h
+++ b/crawl-ref/source/item_use.h
@@ -160,8 +160,7 @@ 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,
- int wpn = -1 );
+bool enchant_weapon( enchant_stat_type which_stat, bool quiet, item_def &wpn );
bool enchant_armour( int &ac_change, bool quiet, item_def &arm );
bool throw_it(bolt &pbolt, int throw_2, bool teleport=false, int acc_bonus=0,
diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc
index 9db56d82d7..14851779d4 100644
--- a/crawl-ref/source/itemprop.cc
+++ b/crawl-ref/source/itemprop.cc
@@ -1291,6 +1291,33 @@ bool item_is_rechargable(const item_def &it, bool known)
&& (!known || item_type_known(it)) );
}
+bool is_enchantable_weapon(const item_def &wpn, bool uncurse)
+{
+ if (wpn.base_type != OBJ_WEAPONS && wpn.base_type != OBJ_MISSILES)
+ return (false);
+
+ // only equipped items should be affected
+// if (!item_is_equipped(wpn))
+// return (false);
+
+ // artefacts cannot be enchanted (missiles can't be artefacts)
+ if (wpn.base_type == OBJ_WEAPONS
+ && (is_fixed_artefact( wpn )
+ || is_random_artefact( wpn )))
+ {
+ return (uncurse && item_cursed( wpn )); // ?EW may uncurse artefacts
+ }
+
+ // Nor can highly enchanted items (missiles only have one stat)
+ if ( wpn.plus >= 9 ||
+ (wpn.base_type == OBJ_WEAPONS && wpn.plus2 >= 9) )
+ {
+ return (uncurse && item_cursed( wpn )); // ?EW may uncurse items
+ }
+
+ return (true);
+}
+
bool is_enchantable_armour(const item_def &arm, bool uncurse)
{
if (arm.base_type != OBJ_ARMOUR)
@@ -1312,7 +1339,7 @@ bool is_enchantable_armour(const item_def &arm, bool uncurse)
&& (arm.sub_type >= ARM_CLOAK && arm.sub_type <= ARM_BOOTS
|| is_shield(arm)) )
{
- return (uncurse && item_cursed( arm )); // ?EA may uncurse item
+ return (uncurse && item_cursed( arm )); // ?EA may uncurse items
}
return (true);
diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h
index da16b46a38..8f42cb6a19 100644
--- a/crawl-ref/source/itemprop.h
+++ b/crawl-ref/source/itemprop.h
@@ -632,6 +632,7 @@ 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_weapon(const item_def &wpn, bool uncurse);
bool is_enchantable_armour(const item_def &arm, bool uncurse);
// weapon functions:
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index fd2cf18989..aa44ff1bc2 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -775,6 +775,21 @@ static bool blessing_priesthood(monsters* mon)
return false;
}
+static bool blessing_wpn(monsters *mon)
+{
+ // Pick a monster's weapon.
+ const int weapon = mon->inv[MSLOT_WEAPON];
+
+ if (weapon == NON_ITEM)
+ return false;
+
+ item_def& wpn(mitm[weapon]);
+
+ // And enchant or uncurse it.
+ return enchant_weapon((coinflip()) ? ENCHANT_TO_HIT
+ : ENCHANT_TO_DAM, true, wpn);
+}
+
static bool blessing_ac(monsters* mon)
{
// Pick either a monster's armour or its shield.
@@ -796,7 +811,7 @@ static bool blessing_ac(monsters* mon)
int ac_change;
- // And enchant it.
+ // And enchant or uncurse it.
return enchant_armour(ac_change, true, arm);
}
@@ -852,10 +867,10 @@ void bless_follower(god_type god,
mon = &menv[monster];
}
- const char *blessed = (follower && !mons_near(follower))
- ? "your follower"
- : mon->name(DESC_NOCAP_THE).c_str();
- const char *result;
+ std::string blessed = (follower && !mons_near(follower))
+ ? "your follower"
+ : mon->name(DESC_NOCAP_THE).c_str();
+ std::string result;
int chance = random2(20);
@@ -869,23 +884,43 @@ void bless_follower(god_type god,
}
}
- // Enchant a monster's armour or shield by one or two points, or at
- // least uncurse it, if possible. The message doesn't make a
- // distinction.
+ // Enchant a monster's weapon or armour/shield by one or two points,
+ // or at least uncurse it, if possible.
if (chance <= 1)
{
- bool ac_effect = blessing_ac(mon);
+ bool affected;
- if (!ac_effect || coinflip())
+ if (coinflip())
{
- if (blessing_ac(mon))
- ac_effect = true;
- }
+ affected = blessing_wpn(mon);
+
+ if (!affected || coinflip())
+ {
+ if (blessing_wpn(mon))
+ affected = true;
+ }
- if (ac_effect)
+ if (affected)
+ {
+ result = "extra attack power";
+ goto blessing_done;
+ }
+ }
+ else
{
- result = "extra defence";
- goto blessing_done;
+ affected = blessing_ac(mon);
+
+ if (!affected || coinflip())
+ {
+ if (blessing_ac(mon))
+ affected = true;
+ }
+
+ if (affected)
+ {
+ result = "extra defence";
+ goto blessing_done;
+ }
}
}
@@ -921,7 +956,8 @@ void bless_follower(god_type god,
}
blessing_done:
- snprintf(info, INFO_SIZE, " blesses %s with %s.", blessed, result);
+ snprintf(info, INFO_SIZE, " blesses %s with %s.", blessed.c_str(),
+ result.c_str());
simple_god_message(info);
}
@@ -3761,8 +3797,8 @@ static bool bless_weapon( god_type god, int brand, int colour )
you.inv[wpn].colour = colour;
do_uncurse_item( you.inv[wpn] );
- enchant_weapon( ENCHANT_TO_HIT, true );
- enchant_weapon( ENCHANT_TO_DAM, true );
+ enchant_weapon( ENCHANT_TO_HIT, true, you.inv[wpn] );
+ enchant_weapon( ENCHANT_TO_DAM, true, you.inv[wpn] );
you.wield_change = true;
you.num_gifts[god]++;