1 /**
2 * @file
3 * @brief Weapon enchantment spells.
4 **/
5
6 #include "AppHdr.h"
7
8 #include "spl-wpnench.h"
9
10 #include "areas.h"
11 #include "god-item.h"
12 #include "god-passive.h"
13 #include "item-prop.h"
14 #include "message.h"
15 #include "player-equip.h"
16 #include "prompt.h"
17 #include "religion.h"
18 #include "shout.h"
19 #include "spl-miscast.h"
20 #include "spl-summoning.h"
21
22 /** End your weapon branding spell.
23 *
24 * Returns the weapon to the previous brand, and ends DUR_EXCRUCIATING_WOUNDS.
25 * @param weapon The item in question (which may have just been unwielded).
26 * @param verbose whether to print a message about expiration.
27 */
end_weapon_brand(item_def & weapon,bool verbose)28 void end_weapon_brand(item_def &weapon, bool verbose)
29 {
30 ASSERT(you.duration[DUR_EXCRUCIATING_WOUNDS]);
31
32 set_item_ego_type(weapon, OBJ_WEAPONS, you.props[ORIGINAL_BRAND_KEY]);
33 you.props.erase(ORIGINAL_BRAND_KEY);
34 you.duration[DUR_EXCRUCIATING_WOUNDS] = 0;
35
36 if (verbose)
37 {
38 mprf(MSGCH_DURATION, "%s seems less pained.",
39 weapon.name(DESC_YOUR).c_str());
40 }
41
42 you.wield_change = true;
43 const brand_type real_brand = get_weapon_brand(weapon);
44 if (real_brand == SPWPN_ANTIMAGIC)
45 calc_mp();
46 if (you.weapon() && is_holy_item(weapon) && you.form == transformation::lich)
47 {
48 mprf(MSGCH_DURATION, "%s falls away!", weapon.name(DESC_YOUR).c_str());
49 unequip_item(EQ_WEAPON);
50 }
51 }
52
53 /**
54 * Temporarily brand a weapon with pain.
55 *
56 * @param[in] power Spellpower.
57 * @param[in] fail Whether you've already failed to cast.
58 * @return Success, fail, or abort.
59 */
cast_excruciating_wounds(int power,bool fail)60 spret cast_excruciating_wounds(int power, bool fail)
61 {
62 item_def& weapon = *you.weapon();
63 const brand_type which_brand = SPWPN_PAIN;
64 const brand_type orig_brand = get_weapon_brand(weapon);
65
66 // Can only brand melee weapons.
67 if (is_range_weapon(weapon))
68 {
69 mpr("You cannot brand ranged weapons with this spell.");
70 return spret::abort;
71 }
72
73 bool has_temp_brand = you.duration[DUR_EXCRUCIATING_WOUNDS];
74 if (!has_temp_brand && get_weapon_brand(weapon) == which_brand)
75 {
76 mpr("This weapon is already branded with pain.");
77 return spret::abort;
78 }
79
80 const bool dangerous_disto = orig_brand == SPWPN_DISTORTION
81 && !have_passive(passive_t::safe_distortion);
82 if (dangerous_disto)
83 {
84 const string prompt =
85 "Really brand " + weapon.name(DESC_INVENTORY) + "?";
86 if (!yesno(prompt.c_str(), false, 'n'))
87 {
88 canned_msg(MSG_OK);
89 return spret::abort;
90 }
91 }
92
93 fail_check();
94
95 if (dangerous_disto)
96 unwield_distortion(true);
97
98 noisy(spell_effect_noise(SPELL_EXCRUCIATING_WOUNDS), you.pos());
99 mprf("%s %s in agony.", weapon.name(DESC_YOUR).c_str(),
100 silenced(you.pos()) ? "writhes" : "shrieks");
101
102 if (!has_temp_brand)
103 {
104 you.props[ORIGINAL_BRAND_KEY] = get_weapon_brand(weapon);
105 set_item_ego_type(weapon, OBJ_WEAPONS, which_brand);
106 you.wield_change = true;
107 if (you.duration[DUR_SPWPN_PROTECTION])
108 {
109 you.duration[DUR_SPWPN_PROTECTION] = 0;
110 you.redraw_armour_class = true;
111 }
112 if (orig_brand == SPWPN_ANTIMAGIC)
113 calc_mp();
114 monster * spectral = find_spectral_weapon(&you);
115 if (orig_brand == SPWPN_SPECTRAL && spectral)
116 end_spectral_weapon(spectral, false);
117 }
118
119 you.increase_duration(DUR_EXCRUCIATING_WOUNDS, 8 + roll_dice(2, power), 50);
120
121 return spret::success;
122 }
123
cast_confusing_touch(int power,bool fail)124 spret cast_confusing_touch(int power, bool fail)
125 {
126 fail_check();
127 msg::stream << you.hands_act("begin", "to glow ")
128 << (you.duration[DUR_CONFUSING_TOUCH] ? "brighter" : "red")
129 << "." << endl;
130
131 you.set_duration(DUR_CONFUSING_TOUCH,
132 max(10 + random2(power) / 5,
133 you.duration[DUR_CONFUSING_TOUCH]),
134 20, nullptr);
135 you.props["confusing touch power"] = power;
136
137 return spret::success;
138 }
139