1 /**
2 * @file
3 * @brief Self-enchantment spells.
4 **/
5
6 #include "AppHdr.h"
7
8 #include "spl-selfench.h"
9
10 #include <cmath>
11
12 #include "areas.h"
13 #include "coordit.h" // radius_iterator
14 #include "env.h"
15 #include "god-passive.h"
16 #include "hints.h"
17 #include "items.h" // stack_iterator
18 #include "libutil.h"
19 #include "message.h"
20 #include "output.h"
21 #include "prompt.h"
22 #include "religion.h"
23 #include "spl-util.h"
24 #include "stringutil.h"
25 #include "terrain.h"
26 #include "transform.h"
27 #include "tilepick.h"
28 #include "view.h"
29
cast_deaths_door(int pow,bool fail)30 spret cast_deaths_door(int pow, bool fail)
31 {
32 fail_check();
33 mpr("You stand defiantly in death's doorway!");
34 mprf(MSGCH_SOUND, "You seem to hear sand running through an hourglass...");
35
36 you.set_duration(DUR_DEATHS_DOOR, 10 + random2avg(13, 3)
37 + (random2(pow) / 10));
38
39 const int hp = max(calc_spell_power(SPELL_DEATHS_DOOR, true) / 10, 1);
40 you.attribute[ATTR_DEATHS_DOOR_HP] = hp;
41 set_hp(hp);
42
43 if (you.duration[DUR_DEATHS_DOOR] > 25 * BASELINE_DELAY)
44 you.duration[DUR_DEATHS_DOOR] = (23 + random2(5)) * BASELINE_DELAY;
45 return spret::success;
46 }
47
remove_ice_armour()48 void remove_ice_armour()
49 {
50 mprf(MSGCH_DURATION, "Your icy armour melts away.");
51 you.redraw_armour_class = true;
52 you.duration[DUR_ICY_ARMOUR] = 0;
53 }
54
ice_armour(int pow,bool fail)55 spret ice_armour(int pow, bool fail)
56 {
57 fail_check();
58
59 if (you.duration[DUR_ICY_ARMOUR])
60 mpr("Your icy armour thickens.");
61 else if (you.form == transformation::ice_beast)
62 mpr("Your icy body feels more resilient.");
63 else
64 mpr("A film of ice covers your body!");
65
66 you.increase_duration(DUR_ICY_ARMOUR, random_range(40, 50), 50);
67 you.props[ICY_ARMOUR_KEY] = pow;
68 you.redraw_armour_class = true;
69
70 return spret::success;
71 }
72
cast_revivification(int pow,bool fail)73 spret cast_revivification(int pow, bool fail)
74 {
75 fail_check();
76 mpr("Your body is healed in an amazingly painful way.");
77
78 const int loss = 6 + binomial(9, 8, pow);
79 dec_max_hp(loss * you.hp_max / 100);
80 set_hp(you.hp_max);
81
82 if (you.duration[DUR_DEATHS_DOOR])
83 {
84 mprf(MSGCH_DURATION, "Your life is in your own hands once again.");
85 // XXX: better cause name?
86 paralyse_player("Death's Door abortion");
87 you.duration[DUR_DEATHS_DOOR] = 0;
88 }
89 return spret::success;
90 }
91
cast_swiftness(int power,bool fail)92 spret cast_swiftness(int power, bool fail)
93 {
94 fail_check();
95
96 if (you.in_liquid())
97 {
98 // Hint that the player won't be faster until they leave the liquid.
99 mprf("The %s foams!", you.in_water() ? "water"
100 : "liquid ground");
101 }
102
103 you.set_duration(DUR_SWIFTNESS, 12 + random2(power)/2, 30,
104 "You feel quick.");
105 you.attribute[ATTR_SWIFTNESS] = you.duration[DUR_SWIFTNESS];
106
107 return spret::success;
108 }
109
cast_selective_amnesia(const string & pre_msg)110 int cast_selective_amnesia(const string &pre_msg)
111 {
112 if (you.spell_no == 0)
113 {
114 canned_msg(MSG_NO_SPELLS);
115 return 0;
116 }
117
118 int keyin = 0;
119 spell_type spell;
120 int slot;
121
122 // Pick a spell to forget.
123 keyin = list_spells(false, false, false, "Forget which spell?");
124 redraw_screen();
125 update_screen();
126
127 if (isaalpha(keyin))
128 {
129 spell = get_spell_by_letter(keyin);
130 slot = get_spell_slot_by_letter(keyin);
131
132 const bool in_library = you.spell_library[spell];
133 if (spell != SPELL_NO_SPELL)
134 {
135 const string prompt = make_stringf(
136 "Forget %s, freeing %d spell level%s for a total of %d?%s",
137 spell_title(spell), spell_levels_required(spell),
138 spell_levels_required(spell) != 1 ? "s" : "",
139 player_spell_levels() + spell_levels_required(spell),
140 in_library ? "" : " This spell is not in your library!");
141
142 if (yesno(prompt.c_str(), in_library, 'n', false))
143 {
144 if (!pre_msg.empty())
145 mpr(pre_msg);
146 del_spell_from_memory_by_slot(slot);
147 return 1;
148 }
149 }
150 }
151
152 return -1;
153 }
154
cast_wereblood(int pow,bool fail)155 spret cast_wereblood(int pow, bool fail)
156 {
157 fail_check();
158
159 if (you.duration[DUR_WEREBLOOD])
160 mpr("Your blood is freshly infused with primal strength!");
161 else
162 mpr("Your blood is infused with primal strength.");
163
164 you.set_duration(DUR_WEREBLOOD, 20 + random2avg(pow, 2));
165
166 you.props[WEREBLOOD_KEY] = 0;
167 return spret::success;
168 }
169
cast_silence(int pow,bool fail)170 spret cast_silence(int pow, bool fail)
171 {
172 fail_check();
173 mpr("A profound silence engulfs you.");
174
175 you.increase_duration(DUR_SILENCE, 10 + pow/4 + random2avg(pow/2, 2), 100);
176 invalidate_agrid(true);
177
178 if (you.beheld())
179 you.update_beholders();
180
181 learned_something_new(HINT_YOU_SILENCE);
182 return spret::success;
183 }
184
cast_liquefaction(int pow,bool fail)185 spret cast_liquefaction(int pow, bool fail)
186 {
187 fail_check();
188 flash_view_delay(UA_PLAYER, BROWN, 80);
189 flash_view_delay(UA_PLAYER, YELLOW, 80);
190 flash_view_delay(UA_PLAYER, BROWN, 140);
191
192 mpr("The ground around you becomes liquefied!");
193
194 you.increase_duration(DUR_LIQUEFYING, 10 + random2avg(pow, 2), 100);
195 invalidate_agrid(true);
196 return spret::success;
197 }
198
cast_transform(int pow,transformation which_trans,bool fail)199 spret cast_transform(int pow, transformation which_trans, bool fail)
200 {
201 if (!transform(pow, which_trans, false, true)
202 || !check_form_stat_safety(which_trans))
203 {
204 return spret::abort;
205 }
206
207 fail_check();
208 transform(pow, which_trans);
209 return spret::success;
210 }
211