add two new Ru sacrifices
[crawl.git] / crawl-ref / source / ability.cc
1 /**
2  * @file
3  * @brief Functions related to special abilities.
4 **/
5
6 #include "AppHdr.h"
7
8 #include "ability.h"
9
10 #include <cctype>
11 #include <cmath>
12 #include <cstdio>
13 #include <cstring>
14 #include <iomanip>
15 #include <sstream>
16
17 #include "abyss.h"
18 #include "acquire.h"
19 #include "areas.h"
20 #include "branch.h"
21 #include "butcher.h"
22 #include "cloud.h"
23 #include "coordit.h"
24 #include "database.h"
25 #include "decks.h"
26 #include "delay.h"
27 #include "describe.h"
28 #include "directn.h"
29 #include "dungeon.h"
30 #include "evoke.h"
31 #include "exercise.h"
32 #include "food.h"
33 #include "godabil.h"
34 #include "godconduct.h"
35 #include "godprayer.h"
36 #include "hints.h"
37 #include "items.h"
38 #include "item_use.h"
39 #include "libutil.h"
40 #include "macro.h"
41 #include "maps.h"
42 #include "menu.h"
43 #include "message.h"
44 #include "misc.h"
45 #include "mon-place.h"
46 #include "mutation.h"
47 #include "notes.h"
48 #include "output.h"
49 #include "player-stats.h"
50 #include "potion.h"
51 #include "prompt.h"
52 #include "religion.h"
53 #include "skills.h"
54 #include "spl-cast.h"
55 #include "spl-clouds.h"
56 #include "spl-damage.h"
57 #include "spl-goditem.h"
58 #include "spl-miscast.h"
59 #include "spl-other.h"
60 #include "spl-selfench.h"
61 #include "spl-summoning.h"
62 #include "spl-transloc.h"
63 #include "stairs.h"
64 #include "state.h"
65 #include "stringutil.h"
66 #include "target.h"
67 #include "terrain.h"
68 #include "tilepick.h"
69 #include "transform.h"
70 #include "traps.h"
71 #include "uncancel.h"
72 #include "unicode.h"
73 #include "zotdef.h"
74
75 enum ability_flag_type
76 {
77     ABFLAG_NONE           = 0x00000000,
78     ABFLAG_BREATH         = 0x00000001, // ability uses DUR_BREATH_WEAPON
79     ABFLAG_DELAY          = 0x00000002, // ability has its own delay
80     ABFLAG_PAIN           = 0x00000004, // ability must hurt player (ie torment)
81     ABFLAG_PIETY          = 0x00000008, // ability has its own piety cost
82     ABFLAG_EXHAUSTION     = 0x00000010, // fails if you.exhausted
83     ABFLAG_INSTANT        = 0x00000020, // doesn't take time to use
84     ABFLAG_PERMANENT_HP   = 0x00000040, // costs permanent HPs
85     ABFLAG_PERMANENT_MP   = 0x00000080, // costs permanent MPs
86     ABFLAG_CONF_OK        = 0x00000100, // can use even if confused
87     ABFLAG_FRUIT          = 0x00000200, // ability requires fruit
88     ABFLAG_VARIABLE_FRUIT = 0x00000400, // ability requires fruit or piety
89                           //0x00000800,
90                           //0x00001000,
91     ABFLAG_NECRO_MISCAST_MINOR = 0x00002000, // severity 2 necro miscast
92                           //0x00004000,
93                           //0x00008000,
94     ABFLAG_LEVEL_DRAIN    = 0x00010000, // drains 2 levels
95     ABFLAG_STAT_DRAIN     = 0x00020000, // stat drain
96     ABFLAG_ZOTDEF         = 0x00040000, // ZotDef ability, w/ appropriate hotkey
97     ABFLAG_SKILL_DRAIN    = 0x00080000, // drains skill levels
98     ABFLAG_GOLD           = 0x00100000, // costs gold
99     ABFLAG_SACRIFICE      = 0x00200000, // sacrifice (Ru)
100 };
101
102 static int  _find_ability_slot(const ability_def& abil);
103 static spret_type _do_ability(const ability_def& abil, bool fail);
104 static void _pay_ability_costs(const ability_def& abil, int zpcost);
105 static int _scale_piety_cost(ability_type abil, int original_cost);
106 static string _zd_mons_description_for_ability(const ability_def &abil);
107 static monster_type _monster_for_ability(const ability_def& abil);
108
109 /**
110  * This all needs to be split into data/util/show files
111  * and the struct mechanism here needs to be rewritten (again)
112  * along with the display routine to piece the strings
113  * together dynamically ... I'm getting to it now {dlb}
114  *
115  * This array corresponds with ::god_gain_power_messages and
116  * ::god_lose_power_messages, which have the same shape.
117  *
118  * It makes more sense to think of them as an array
119  * of structs than two arrays that share common index
120  * values -- well, doesn't it? {dlb}
121  *
122  * @note Declaring this const messes up externs later, so don't do it!
123  */
124 ability_type god_abilities[NUM_GODS][MAX_GOD_ABILITIES] =
125 {
126     // no god
127     { ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_NON_ABILITY,
128       ABIL_NON_ABILITY },
129     // Zin
130     { ABIL_ZIN_RECITE, ABIL_ZIN_VITALISATION, ABIL_ZIN_IMPRISON,
131       ABIL_NON_ABILITY, ABIL_ZIN_SANCTUARY },
132     // TSO
133     { ABIL_NON_ABILITY, ABIL_TSO_DIVINE_SHIELD, ABIL_NON_ABILITY,
134       ABIL_TSO_CLEANSING_FLAME, ABIL_TSO_SUMMON_DIVINE_WARRIOR },
135     // Kikubaaqudgha
136     { ABIL_KIKU_RECEIVE_CORPSES, ABIL_NON_ABILITY, ABIL_NON_ABILITY,
137       ABIL_NON_ABILITY, ABIL_KIKU_TORMENT },
138     // Yredelemnul
139     { ABIL_YRED_ANIMATE_REMAINS_OR_DEAD, ABIL_YRED_RECALL_UNDEAD_SLAVES,
140       ABIL_NON_ABILITY, ABIL_YRED_DRAIN_LIFE, ABIL_YRED_ENSLAVE_SOUL },
141     // Xom
142     { ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_NON_ABILITY,
143       ABIL_NON_ABILITY },
144     // Vehumet
145     { ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_NON_ABILITY,
146       ABIL_NON_ABILITY },
147     // Okawaru
148     { ABIL_OKAWARU_HEROISM, ABIL_NON_ABILITY, ABIL_NON_ABILITY,
149       ABIL_NON_ABILITY, ABIL_OKAWARU_FINESSE },
150     // Makhleb
151     { ABIL_NON_ABILITY, ABIL_MAKHLEB_MINOR_DESTRUCTION,
152       ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB, ABIL_MAKHLEB_MAJOR_DESTRUCTION,
153       ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB },
154     // Sif Muna
155     { ABIL_SIF_MUNA_CHANNEL_ENERGY, ABIL_SIF_MUNA_FORGET_SPELL,
156       ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_NON_ABILITY },
157     // Trog
158     { ABIL_TROG_BERSERK, ABIL_TROG_REGEN_MR, ABIL_NON_ABILITY,
159       ABIL_TROG_BROTHERS_IN_ARMS, ABIL_NON_ABILITY },
160     // Nemelex
161     { ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_NEMELEX_TRIPLE_DRAW,
162       ABIL_NEMELEX_DEAL_FOUR, ABIL_NEMELEX_STACK_FIVE },
163     // Elyvilon
164     { ABIL_ELYVILON_LESSER_HEALING_SELF, ABIL_ELYVILON_PURIFICATION,
165       ABIL_ELYVILON_GREATER_HEALING_OTHERS, ABIL_NON_ABILITY,
166       ABIL_ELYVILON_DIVINE_VIGOUR },
167     // Lugonu
168     { ABIL_LUGONU_ABYSS_EXIT, ABIL_LUGONU_BEND_SPACE, ABIL_LUGONU_BANISH,
169       ABIL_LUGONU_CORRUPT, ABIL_LUGONU_ABYSS_ENTER },
170     // Beogh
171     { ABIL_NON_ABILITY, ABIL_BEOGH_SMITING, ABIL_NON_ABILITY,
172       ABIL_BEOGH_RECALL_ORCISH_FOLLOWERS, ABIL_BEOGH_GIFT_ITEM },
173     // Jiyva
174     { ABIL_JIYVA_CALL_JELLY, ABIL_JIYVA_JELLY_PARALYSE, ABIL_NON_ABILITY,
175       ABIL_JIYVA_SLIMIFY, ABIL_JIYVA_CURE_BAD_MUTATION },
176     // Fedhas
177     { ABIL_FEDHAS_EVOLUTION, ABIL_FEDHAS_SUNLIGHT, ABIL_FEDHAS_PLANT_RING,
178       ABIL_FEDHAS_SPAWN_SPORES, ABIL_FEDHAS_RAIN},
179     // Cheibriados
180     { ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_CHEIBRIADOS_DISTORTION,
181       ABIL_CHEIBRIADOS_SLOUCH, ABIL_CHEIBRIADOS_TIME_STEP },
182     // Ashenzari
183     { ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_NON_ABILITY,
184       ABIL_ASHENZARI_SCRYING, ABIL_ASHENZARI_TRANSFER_KNOWLEDGE },
185     // Dithmenos
186     { ABIL_NON_ABILITY, ABIL_DITHMENOS_SHADOW_STEP, ABIL_NON_ABILITY,
187       ABIL_NON_ABILITY, ABIL_DITHMENOS_SHADOW_FORM },
188     // Gozag
189     { ABIL_GOZAG_POTION_PETITION, ABIL_GOZAG_CALL_MERCHANT,
190       ABIL_GOZAG_BRIBE_BRANCH, ABIL_NON_ABILITY, ABIL_NON_ABILITY },
191     // Qazlal
192     { ABIL_NON_ABILITY, ABIL_QAZLAL_UPHEAVAL, ABIL_QAZLAL_ELEMENTAL_FORCE,
193       ABIL_NON_ABILITY, ABIL_QAZLAL_DISASTER_AREA },
194     // Ru
195     { ABIL_NON_ABILITY, ABIL_NON_ABILITY, ABIL_RU_DRAW_OUT_POWER,
196       ABIL_RU_POWER_LEAP, ABIL_RU_APOCALYPSE }
197 };
198
199 // The description screen was way out of date with the actual costs.
200 // This table puts all the information in one place... -- bwr
201 //
202 // The five numerical fields are: MP, HP, food, piety and ZP.
203 // Note:  food_cost  = val + random2avg(val, 2)
204 //        piety_cost = val + random2((val + 1) / 2 + 1);
205 //        hp cost is in per-mil of maxhp (i.e. 20 = 2% of hp, rounded up)
206 static const ability_def Ability_List[] =
207 {
208     // NON_ABILITY should always come first
209     { ABIL_NON_ABILITY, "No ability", 0, 0, 0, 0, 0, ABFLAG_NONE},
210     { ABIL_SPIT_POISON, "Spit Poison", 0, 0, 40, 0, 0, ABFLAG_BREATH},
211
212     { ABIL_BLINK, "Blink", 0, 50, 50, 0, 0, ABFLAG_NONE},
213
214     { ABIL_BREATHE_FIRE, "Breathe Fire", 0, 0, 125, 0, 0, ABFLAG_BREATH},
215     { ABIL_BREATHE_FROST, "Breathe Frost", 0, 0, 125, 0, 0, ABFLAG_BREATH},
216     { ABIL_BREATHE_POISON, "Breathe Poison Gas",
217       0, 0, 125, 0, 0, ABFLAG_BREATH},
218     { ABIL_BREATHE_MEPHITIC, "Breathe Noxious Fumes",
219       0, 0, 125, 0, 0, ABFLAG_BREATH},
220     { ABIL_BREATHE_LIGHTNING, "Breathe Lightning",
221       0, 0, 125, 0, 0, ABFLAG_BREATH},
222     { ABIL_BREATHE_POWER, "Breathe Dispelling Energy", 0, 0, 125, 0, 0, ABFLAG_BREATH},
223     { ABIL_BREATHE_STICKY_FLAME, "Breathe Sticky Flame",
224       0, 0, 125, 0, 0, ABFLAG_BREATH},
225     { ABIL_BREATHE_STEAM, "Breathe Steam", 0, 0, 75, 0, 0, ABFLAG_BREATH},
226     { ABIL_TRAN_BAT, "Bat Form", 2, 0, 0, 0, 0, ABFLAG_NONE},
227
228     { ABIL_SPIT_ACID, "Spit Acid", 0, 0, 125, 0, 0, ABFLAG_BREATH},
229
230     { ABIL_FLY, "Fly", 3, 0, 100, 0, 0, ABFLAG_NONE},
231     { ABIL_STOP_FLYING, "Stop Flying", 0, 0, 0, 0, 0, ABFLAG_NONE},
232     { ABIL_HELLFIRE, "Hellfire", 0, 150, 200, 0, 0, ABFLAG_NONE},
233
234     { ABIL_DELAYED_FIREBALL, "Release Delayed Fireball",
235       0, 0, 0, 0, 0, ABFLAG_INSTANT},
236     { ABIL_STOP_SINGING, "Stop Singing",
237       0, 0, 0, 0, 0, ABFLAG_NONE},
238     { ABIL_MUMMY_RESTORATION, "Self-Restoration",
239       1, 0, 0, 0, 0, ABFLAG_PERMANENT_MP},
240
241     { ABIL_DIG, "Dig", 0, 0, 0, 0, 0, ABFLAG_INSTANT},
242     { ABIL_SHAFT_SELF, "Shaft Self", 0, 0, 250, 0, 0, ABFLAG_DELAY},
243
244     // EVOKE abilities use Evocations and come from items.
245     // Teleportation and Blink can also come from mutations
246     // so we have to distinguish them (see above).  The off items
247     // below are labeled EVOKE because they only work now if the
248     // player has an item with the evocable power (not just because
249     // you used a wand, potion, or miscast effect).  I didn't see
250     // any reason to label them as "Evoke" in the text, they don't
251     // use or train Evocations (the others do).  -- bwr
252     { ABIL_EVOKE_TELEPORTATION, "Evoke Teleportation",
253       3, 0, 200, 0, 0, ABFLAG_NONE},
254     { ABIL_EVOKE_BLINK, "Evoke Blink", 1, 0, 50, 0, 0, ABFLAG_NONE},
255     { ABIL_RECHARGING, "Device Recharging", 1, 0, 0, 0, 0, ABFLAG_PERMANENT_MP},
256
257     { ABIL_EVOKE_BERSERK, "Evoke Berserk Rage", 0, 0, 0, 0, 0, ABFLAG_NONE},
258
259     { ABIL_EVOKE_TURN_INVISIBLE, "Evoke Invisibility",
260       2, 0, 250, 0, 0, ABFLAG_NONE},
261     { ABIL_EVOKE_TURN_VISIBLE, "Turn Visible", 0, 0, 0, 0, 0, ABFLAG_NONE},
262     { ABIL_EVOKE_FLIGHT, "Evoke Flight", 1, 0, 100, 0, 0, ABFLAG_NONE},
263     { ABIL_EVOKE_FOG, "Evoke Fog", 2, 0, 250, 0, 0, ABFLAG_NONE},
264     { ABIL_EVOKE_TELEPORT_CONTROL, "Evoke Teleport Control", 4, 0, 200, 0, 0, ABFLAG_NONE},
265     { ABIL_EVOKE_TWISTER, "Evoke Twister", 10, 0, 200, 0, 0, ABFLAG_NONE},
266
267     { ABIL_END_TRANSFORMATION, "End Transformation", 0, 0, 0, 0, 0, ABFLAG_NONE},
268
269     // INVOCATIONS:
270     // Zin
271     { ABIL_ZIN_RECITE, "Recite", 0, 0, 0, 0, 0, ABFLAG_BREATH},
272     { ABIL_ZIN_VITALISATION, "Vitalisation", 0, 0, 0, 1, 0, ABFLAG_NONE},
273     { ABIL_ZIN_IMPRISON, "Imprison", 5, 0, 125, 4, 0, ABFLAG_NONE},
274     { ABIL_ZIN_SANCTUARY, "Sanctuary", 7, 0, 150, 15, 0, ABFLAG_NONE},
275     { ABIL_ZIN_CURE_ALL_MUTATIONS, "Cure All Mutations",
276       0, 0, 0, 0, 0, ABFLAG_NONE},
277
278     // The Shining One
279     { ABIL_TSO_DIVINE_SHIELD, "Divine Shield", 3, 0, 50, 2, 0, ABFLAG_NONE},
280     { ABIL_TSO_CLEANSING_FLAME, "Cleansing Flame",
281       5, 0, 100, 2, 0, ABFLAG_NONE},
282     { ABIL_TSO_SUMMON_DIVINE_WARRIOR, "Summon Divine Warrior",
283       8, 0, 150, 6, 0, ABFLAG_NONE},
284
285     // Kikubaaqudgha
286     { ABIL_KIKU_RECEIVE_CORPSES, "Receive Corpses",
287       3, 0, 50, 2, 0, ABFLAG_NONE},
288     { ABIL_KIKU_TORMENT, "Torment", 4, 0, 0, 8, 0, ABFLAG_NONE},
289
290     // Yredelemnul
291     { ABIL_YRED_INJURY_MIRROR, "Injury Mirror", 0, 0, 0, 0, 0, ABFLAG_PIETY},
292     { ABIL_YRED_ANIMATE_REMAINS, "Animate Remains",
293       2, 0, 50, 0, 0, ABFLAG_NONE},
294     { ABIL_YRED_RECALL_UNDEAD_SLAVES, "Recall Undead Slaves",
295       2, 0, 50, 0, 0, ABFLAG_NONE},
296     { ABIL_YRED_ANIMATE_DEAD, "Animate Dead", 2, 0, 50, 0, 0, ABFLAG_NONE},
297     { ABIL_YRED_DRAIN_LIFE, "Drain Life", 6, 0, 200, 2, 0, ABFLAG_NONE},
298     { ABIL_YRED_ENSLAVE_SOUL, "Enslave Soul", 8, 0, 150, 4, 0, ABFLAG_NONE},
299     // Placeholder for Animate Remains or Animate Dead.
300     { ABIL_YRED_ANIMATE_REMAINS_OR_DEAD, "Animate Remains or Dead",
301       2, 0, 100, 0, 0, ABFLAG_NONE},
302
303     // Okawaru
304     { ABIL_OKAWARU_HEROISM, "Heroism", 2, 0, 50, 2, 0, ABFLAG_NONE},
305     { ABIL_OKAWARU_FINESSE, "Finesse", 5, 0, 100, 4, 0, ABFLAG_NONE},
306
307     // Makhleb
308     { ABIL_MAKHLEB_MINOR_DESTRUCTION, "Minor Destruction",
309       0, scaling_cost::fixed(1), 20, 0, 0, ABFLAG_NONE},
310     { ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB, "Lesser Servant of Makhleb",
311       0, scaling_cost::fixed(4), 50, 2, 0, ABFLAG_NONE},
312     { ABIL_MAKHLEB_MAJOR_DESTRUCTION, "Major Destruction",
313       0, scaling_cost::fixed(6), 100, generic_cost::range(0, 1), 0, ABFLAG_NONE},
314     { ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB, "Greater Servant of Makhleb",
315       0, scaling_cost::fixed(10), 100, 5, 0, ABFLAG_NONE},
316
317     // Sif Muna
318     { ABIL_SIF_MUNA_CHANNEL_ENERGY, "Channel Energy",
319       0, 0, 100, 0, 0, ABFLAG_NONE},
320     { ABIL_SIF_MUNA_FORGET_SPELL, "Forget Spell", 5, 0, 0, 8, 0, ABFLAG_NONE},
321
322     // Trog
323     { ABIL_TROG_BURN_SPELLBOOKS, "Burn Spellbooks",
324       0, 0, 10, 0, 0, ABFLAG_NONE},
325     { ABIL_TROG_BERSERK, "Berserk", 0, 0, 200, 0, 0, ABFLAG_NONE},
326     { ABIL_TROG_REGEN_MR, "Trog's Hand",
327       0, 0, 50, generic_cost::range(2, 3), 0, ABFLAG_NONE},
328     { ABIL_TROG_BROTHERS_IN_ARMS, "Brothers in Arms",
329       0, 0, 100, generic_cost::range(5, 6), 0, ABFLAG_NONE},
330
331     // Elyvilon
332     { ABIL_ELYVILON_LIFESAVING, "Divine Protection",
333       0, 0, 0, 0, 0, ABFLAG_NONE},
334     { ABIL_ELYVILON_LESSER_HEALING_SELF, "Lesser Self-Healing",
335       1, 0, 100, generic_cost::range(0, 1), 0, ABFLAG_CONF_OK},
336     { ABIL_ELYVILON_LESSER_HEALING_OTHERS, "Lesser Healing",
337       1, 0, 100, 0, 0, ABFLAG_NONE},
338     { ABIL_ELYVILON_PURIFICATION, "Purification", 3, 0, 300, 3, 0,
339       ABFLAG_CONF_OK},
340     { ABIL_ELYVILON_GREATER_HEALING_SELF, "Greater Self-Healing",
341       2, 0, 250, 3, 0, ABFLAG_CONF_OK},
342     { ABIL_ELYVILON_GREATER_HEALING_OTHERS, "Greater Healing",
343       2, 0, 250, 2, 0, ABFLAG_NONE},
344     { ABIL_ELYVILON_DIVINE_VIGOUR, "Divine Vigour", 0, 0, 600, 6, 0,
345       ABFLAG_CONF_OK},
346
347     // Lugonu
348     { ABIL_LUGONU_ABYSS_EXIT, "Depart the Abyss",
349       1, 0, 150, 10, 0, ABFLAG_NONE},
350     { ABIL_LUGONU_BEND_SPACE, "Bend Space", 1, 0, 50, 0, 0, ABFLAG_PAIN},
351     { ABIL_LUGONU_BANISH, "Banish",
352       4, 0, 200, generic_cost::range(3, 4), 0, ABFLAG_NONE},
353     { ABIL_LUGONU_CORRUPT, "Corrupt",
354       7, scaling_cost::fixed(5), 500, generic_cost::range(10, 14), 0, ABFLAG_NONE},
355     { ABIL_LUGONU_ABYSS_ENTER, "Enter the Abyss",
356       9, 0, 500, generic_cost::fixed(35), 0, ABFLAG_PAIN},
357
358     // Nemelex
359     { ABIL_NEMELEX_TRIPLE_DRAW, "Triple Draw", 2, 0, 100, 2, 0, ABFLAG_NONE},
360     { ABIL_NEMELEX_DEAL_FOUR, "Deal Four", 8, 0, 200, 8, 0, ABFLAG_NONE},
361     { ABIL_NEMELEX_STACK_FIVE, "Stack Five", 5, 0, 250, 10, 0, ABFLAG_NONE},
362
363     // Beogh
364     { ABIL_BEOGH_SMITING, "Smiting",
365       3, 0, 80, generic_cost::fixed(3), 0, ABFLAG_NONE},
366     { ABIL_BEOGH_RECALL_ORCISH_FOLLOWERS, "Recall Orcish Followers",
367       2, 0, 50, 0, 0, ABFLAG_NONE},
368     { ABIL_BEOGH_GIFT_ITEM, "Give Item to Named Follower",
369       0, 0, 0, 0, 0, ABFLAG_NONE},
370
371     // Jiyva
372     { ABIL_JIYVA_CALL_JELLY, "Request Jelly", 2, 0, 20, 1, 0, ABFLAG_NONE},
373     { ABIL_JIYVA_JELLY_PARALYSE, "Jelly Paralyse", 0, 0, 0, 0, 0, ABFLAG_PIETY},
374     { ABIL_JIYVA_SLIMIFY, "Slimify", 4, 0, 100, 8, 0, ABFLAG_NONE},
375     { ABIL_JIYVA_CURE_BAD_MUTATION, "Cure Bad Mutation",
376       8, 0, 200, 15, 0, ABFLAG_NONE},
377
378     // Fedhas
379     { ABIL_FEDHAS_EVOLUTION, "Evolution", 2, 0, 0, 0, 0, ABFLAG_VARIABLE_FRUIT},
380     { ABIL_FEDHAS_SUNLIGHT, "Sunlight", 2, 0, 50, 0, 0, ABFLAG_NONE},
381     { ABIL_FEDHAS_PLANT_RING, "Growth", 2, 0, 0, 0, 0, ABFLAG_FRUIT},
382     { ABIL_FEDHAS_SPAWN_SPORES, "Reproduction", 4, 0, 100, 1, 0, ABFLAG_NONE},
383     { ABIL_FEDHAS_RAIN, "Rain", 4, 0, 150, 4, 0, ABFLAG_NONE},
384
385     // Cheibriados
386     { ABIL_CHEIBRIADOS_TIME_BEND, "Bend Time", 3, 0, 50, 1, 0, ABFLAG_NONE},
387     { ABIL_CHEIBRIADOS_DISTORTION, "Temporal Distortion",
388       4, 0, 200, 3, 0, ABFLAG_INSTANT},
389     { ABIL_CHEIBRIADOS_SLOUCH, "Slouch", 5, 0, 100, 8, 0, ABFLAG_NONE},
390     { ABIL_CHEIBRIADOS_TIME_STEP, "Step From Time",
391       10, 0, 200, 10, 0, ABFLAG_NONE},
392
393     // Ashenzari
394     { ABIL_ASHENZARI_SCRYING, "Scrying",
395       4, 0, 50, generic_cost::range(2, 3), 0, ABFLAG_INSTANT},
396     { ABIL_ASHENZARI_TRANSFER_KNOWLEDGE, "Transfer Knowledge",
397       0, 0, 0, 20, 0, ABFLAG_NONE},
398     { ABIL_ASHENZARI_END_TRANSFER, "End Transfer Knowledge",
399       0, 0, 0, 0, 0, ABFLAG_NONE},
400
401     // Dithmenos
402     { ABIL_DITHMENOS_SHADOW_STEP, "Shadow Step",
403       4, 0, 0, 4, 0, ABFLAG_NONE },
404     { ABIL_DITHMENOS_SHADOW_FORM, "Shadow Form",
405       9, 0, 0, 10, 0, ABFLAG_SKILL_DRAIN },
406
407     // Ru
408     { ABIL_RU_DRAW_OUT_POWER, "Draw Out Power",
409       0, 0, 0, 0, 0, ABFLAG_EXHAUSTION|ABFLAG_SKILL_DRAIN|ABFLAG_CONF_OK },
410     { ABIL_RU_POWER_LEAP, "Power Leap",
411       5, 0, 0, 0, 0, ABFLAG_EXHAUSTION },
412     { ABIL_RU_APOCALYPSE, "Apocalypse",
413       8, 0, 0, 0, 0, ABFLAG_EXHAUSTION|ABFLAG_SKILL_DRAIN },
414
415     { ABIL_RU_SACRIFICE_PURITY, "Sacrifice Purity",
416       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
417     { ABIL_RU_SACRIFICE_WORDS, "Sacrifice Words",
418       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
419     { ABIL_RU_SACRIFICE_DRINK, "Sacrifice Drink",
420       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
421     { ABIL_RU_SACRIFICE_ESSENCE, "Sacrifice Essence",
422       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
423     { ABIL_RU_SACRIFICE_HEALTH, "Sacrifice Health",
424       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
425     { ABIL_RU_SACRIFICE_STEALTH, "Sacrifice Stealth",
426       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
427     { ABIL_RU_SACRIFICE_ARTIFICE, "Sacrifice Artifice",
428       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
429     { ABIL_RU_SACRIFICE_LOVE, "Sacrifice Love",
430       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
431     { ABIL_RU_SACRIFICE_COURAGE, "Sacrifice Courage",
432       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
433     { ABIL_RU_SACRIFICE_ARCANA, "Sacrifice Arcana",
434       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
435     { ABIL_RU_SACRIFICE_NIMBLENESS, "Sacrifice Nimbleness",
436       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
437     { ABIL_RU_SACRIFICE_DURABILITY, "Sacrifice Durability",
438       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
439     { ABIL_RU_SACRIFICE_HAND, "Sacrifice a Hand",
440       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
441     { ABIL_RU_SACRIFICE_EXPERIENCE, "Sacrifice Experience",
442       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
443     { ABIL_RU_SACRIFICE_SKILL, "Sacrifice Skill",
444       0, 0, 0, 0, 0, ABFLAG_SACRIFICE },
445     { ABIL_RU_REJECT_SACRIFICES, "Reject Sacrifices",
446       0, 0, 0, 0, 0, ABFLAG_NONE },
447
448     // Gozag
449     { ABIL_GOZAG_POTION_PETITION, "Potion Petition",
450       0, 0, 0, 0, 0, ABFLAG_GOLD },
451     { ABIL_GOZAG_CALL_MERCHANT, "Call Merchant",
452       0, 0, 0, 0, 0, ABFLAG_GOLD },
453     { ABIL_GOZAG_BRIBE_BRANCH, "Bribe Branch",
454       0, 0, 0, 0, 0, ABFLAG_GOLD },
455
456     // Qazlal
457     { ABIL_QAZLAL_UPHEAVAL, "Upheaval", 4, 0, 0, 3, 0, ABFLAG_NONE },
458     { ABIL_QAZLAL_ELEMENTAL_FORCE, "Elemental Force",
459       6, 0, 0, 6, 0, ABFLAG_NONE },
460     { ABIL_QAZLAL_DISASTER_AREA, "Disaster Area", 7, 0, 0,
461       generic_cost::range(10, 14), 0, ABFLAG_NONE },
462
463     { ABIL_STOP_RECALL, "Stop Recall", 0, 0, 0, 0, 0, ABFLAG_NONE},
464
465     // zot defence abilities
466     { ABIL_MAKE_FUNGUS, "Make mushroom circle", 0, 0, 0, 0, 10, ABFLAG_ZOTDEF},
467     { ABIL_MAKE_PLANT, "Make plant", 0, 0, 0, 0, 2, ABFLAG_ZOTDEF},
468     { ABIL_MAKE_OKLOB_SAPLING, "Make oklob sapling", 0, 0, 0, 0, 60, ABFLAG_ZOTDEF},
469     { ABIL_MAKE_BURNING_BUSH, "Make burning bush", 0, 0, 0, 0, 200, ABFLAG_ZOTDEF},
470     { ABIL_MAKE_OKLOB_PLANT, "Make oklob plant", 0, 0, 0, 0, 250, ABFLAG_ZOTDEF},
471     { ABIL_MAKE_ICE_STATUE, "Make ice statue", 0, 0, 0, 0, 2000, ABFLAG_ZOTDEF},
472     { ABIL_MAKE_OCS, "Make crystal statue", 0, 0, 0, 0, 2000, ABFLAG_ZOTDEF},
473     { ABIL_MAKE_OBSIDIAN_STATUE, "Make obsidian statue", 0, 0, 0, 0, 3000, ABFLAG_ZOTDEF},
474     { ABIL_MAKE_CURSE_SKULL, "Make curse skull",
475       0, 0, 600, 0, 10000, ABFLAG_ZOTDEF|ABFLAG_NECRO_MISCAST_MINOR},
476     { ABIL_MAKE_TELEPORT, "Zot-teleport", 0, 0, 0, 0, 2, ABFLAG_ZOTDEF},
477     { ABIL_MAKE_ARROW_TRAP, "Make arrow trap", 0, 0, 0, 0, 30, ABFLAG_ZOTDEF},
478     { ABIL_MAKE_BOLT_TRAP, "Make bolt trap", 0, 0, 0, 0, 300, ABFLAG_ZOTDEF},
479     { ABIL_MAKE_SPEAR_TRAP, "Make spear trap", 0, 0, 0, 0, 50, ABFLAG_ZOTDEF},
480     { ABIL_MAKE_NEEDLE_TRAP, "Make needle trap", 0, 0, 0, 0, 30, ABFLAG_ZOTDEF},
481     { ABIL_MAKE_NET_TRAP, "Make net trap", 0, 0, 0, 0, 2, ABFLAG_ZOTDEF},
482     { ABIL_MAKE_ALARM_TRAP, "Make alarm trap", 0, 0, 0, 0, 2, ABFLAG_ZOTDEF},
483     { ABIL_MAKE_BLADE_TRAP, "Make blade trap", 0, 0, 0, 0, 3000, ABFLAG_ZOTDEF},
484     { ABIL_MAKE_OKLOB_CIRCLE, "Make oklob circle", 0, 0, 0, 0, 1000, ABFLAG_ZOTDEF},
485     { ABIL_MAKE_ACQUIRE_GOLD, "Acquire gold",
486       0, 0, 0, 0, 0, ABFLAG_ZOTDEF|ABFLAG_LEVEL_DRAIN},
487     { ABIL_MAKE_ACQUIREMENT, "Acquirement",
488       0, 0, 0, 0, 0, ABFLAG_ZOTDEF|ABFLAG_LEVEL_DRAIN},
489     { ABIL_MAKE_WATER, "Make water", 0, 0, 0, 0, 10, ABFLAG_ZOTDEF},
490     { ABIL_MAKE_LIGHTNING_SPIRE, "Make lightning spire", 0, 0, 0, 0, 100, ABFLAG_ZOTDEF},
491     { ABIL_MAKE_BAZAAR, "Make bazaar",
492       0, 30, 0, 0, 100, ABFLAG_ZOTDEF|ABFLAG_PERMANENT_HP},
493     { ABIL_MAKE_ALTAR, "Make altar", 0, 0, 0, 0, 50, ABFLAG_ZOTDEF},
494     { ABIL_MAKE_GRENADES, "Make grenades", 0, 0, 0, 0, 2, ABFLAG_ZOTDEF},
495     { ABIL_REMOVE_CURSE, "Remove Curse",
496       0, 0, 0, 0, 0, ABFLAG_ZOTDEF|ABFLAG_STAT_DRAIN},
497
498     { ABIL_RENOUNCE_RELIGION, "Renounce Religion", 0, 0, 0, 0, 0, ABFLAG_NONE},
499     { ABIL_CONVERT_TO_BEOGH, "Convert to Beogh", 0, 0, 0, 0, 0, ABFLAG_NONE},
500 };
501
502 const ability_def& get_ability_def(ability_type abil)
503 {
504     for (const ability_def &ab_def : Ability_List)
505         if (ab_def.ability == abil)
506             return ab_def;
507
508     return Ability_List[0];
509 }
510
511 /**
512  * Is there a valid ability with a name matching that given?
513  *
514  * @param key   The name in question. (Not case sensitive.)
515  * @return      true if such an ability exists; false if not.
516  */
517 bool string_matches_ability_name(const string& key)
518 {
519     return ability_by_name(key) != ABIL_NON_ABILITY;
520 }
521
522 /**
523  * Find an ability whose name matches the given key.
524  *
525  * @param name      The name in question. (Not case sensitive.)
526  * @return          The enum of the relevant ability, if there was one; else
527  *                  ABIL_NON_ABILITY.
528  */
529 ability_type ability_by_name(const string &key)
530 {
531     for (const auto &abil : Ability_List)
532     {
533         if (abil.ability == ABIL_NON_ABILITY)
534             continue;
535
536         // don't display zot abilties outside zotdef
537         if ((abil.flags & ABFLAG_ZOTDEF) && !crawl_state.game_is_zotdef())
538             continue;
539
540         const string name = lowercase_string(ability_name(abil.ability));
541         if (name == lowercase_string(key))
542             return abil.ability;
543     }
544
545     return ABIL_NON_ABILITY;
546 }
547
548 string print_abilities()
549 {
550     string text = "\n<w>a:</w> ";
551
552     const vector<talent> talents = your_talents(false);
553
554     if (talents.empty())
555         text += "no special abilities";
556     else
557     {
558         for (unsigned int i = 0; i < talents.size(); ++i)
559         {
560             if (i)
561                 text += ", ";
562             text += ability_name(talents[i].which);
563         }
564     }
565
566     return text;
567 }
568
569 static monster_type _monster_for_ability(const ability_def& abil)
570 {
571     monster_type mtyp = MONS_PROGRAM_BUG;
572     switch (abil.ability)
573     {
574         case ABIL_MAKE_PLANT:         mtyp = MONS_PLANT;         break;
575         case ABIL_MAKE_FUNGUS:        mtyp = MONS_FUNGUS;        break;
576         case ABIL_MAKE_OKLOB_SAPLING: mtyp = MONS_OKLOB_SAPLING; break;
577         case ABIL_MAKE_OKLOB_CIRCLE:
578         case ABIL_MAKE_OKLOB_PLANT:   mtyp = MONS_OKLOB_PLANT;   break;
579         case ABIL_MAKE_BURNING_BUSH:  mtyp = MONS_BURNING_BUSH;  break;
580         case ABIL_MAKE_LIGHTNING_SPIRE:  mtyp = MONS_LIGHTNING_SPIRE;  break;
581         case ABIL_MAKE_ICE_STATUE:    mtyp = MONS_ICE_STATUE;    break;
582         case ABIL_MAKE_OCS:           mtyp = MONS_ORANGE_STATUE; break;
583         case ABIL_MAKE_OBSIDIAN_STATUE: mtyp = MONS_OBSIDIAN_STATUE; break;
584         case ABIL_MAKE_CURSE_SKULL:   mtyp = MONS_CURSE_SKULL;   break;
585         default:
586             mprf("DEBUG: NO RELEVANT MONSTER FOR %d", abil.ability);
587             break;
588     }
589     return mtyp;
590 }
591
592 static string _zd_mons_description_for_ability(const ability_def &abil)
593 {
594     switch (abil.ability)
595     {
596     case ABIL_MAKE_PLANT:
597         return "Tendrils and shoots erupt from the earth and gnarl into the form of a plant.";
598     case ABIL_MAKE_OKLOB_SAPLING:
599         return "A rhizome shoots up through the ground and merges with vitriolic spirits in the atmosphere.";
600     case ABIL_MAKE_OKLOB_PLANT:
601         return "A rhizome shoots up through the ground and merges with vitriolic spirits in the atmosphere.";
602     case ABIL_MAKE_BURNING_BUSH:
603         return "Blackened shoots writhe from the ground and burst into flame!";
604     case ABIL_MAKE_ICE_STATUE:
605         return "Water vapor collects and crystallises into an icy humanoid shape.";
606     case ABIL_MAKE_OCS:
607         return "Quartz juts from the ground and forms a humanoid shape. You smell citrus.";
608     case ABIL_MAKE_OBSIDIAN_STATUE:
609         return "Molten obsidian falls from the ceiling and solidifies into a vaguely humanoid shape.";
610     case ABIL_MAKE_CURSE_SKULL:
611         return "You sculpt a terrible being from the primitive principle of evil.";
612     case ABIL_MAKE_LIGHTNING_SPIRE:
613         return "You mount a charged rod inside a coil.";
614     default:
615         return "";
616     }
617 }
618
619 static int _count_relevant_monsters(const ability_def& abil)
620 {
621     monster_type mtyp = _monster_for_ability(abil);
622     if (mtyp == MONS_PROGRAM_BUG)
623         return 0;
624     return count_monsters(mtyp, true);        // Friendly ones only
625 }
626
627 static trap_type _trap_for_ability(const ability_def& abil)
628 {
629     switch (abil.ability)
630     {
631         case ABIL_MAKE_ARROW_TRAP: return TRAP_ARROW;
632         case ABIL_MAKE_BOLT_TRAP: return TRAP_BOLT;
633         case ABIL_MAKE_SPEAR_TRAP: return TRAP_SPEAR;
634         case ABIL_MAKE_NEEDLE_TRAP: return TRAP_NEEDLE;
635         case ABIL_MAKE_NET_TRAP: return TRAP_NET;
636         case ABIL_MAKE_ALARM_TRAP: return TRAP_ALARM;
637         case ABIL_MAKE_BLADE_TRAP: return TRAP_BLADE;
638         default: return TRAP_UNASSIGNED;
639     }
640 }
641
642 // Scale the zp cost by the number of friendly monsters
643 // of that type. Each successive critter costs 20% more
644 // than the last one, after the first two.
645 static int _zp_cost(const ability_def& abil)
646 {
647     int cost = abil.zp_cost;
648     int scale10 = 0;        // number of times to scale up by 10%
649     int scale20 = 0;        // number of times to scale up by 20%
650     int num;
651     switch (abil.ability)
652     {
653         default:
654             return abil.zp_cost;
655
656         // Monster type 1: reasonably generous
657         case ABIL_MAKE_PLANT:
658         case ABIL_MAKE_FUNGUS:
659         case ABIL_MAKE_OKLOB_SAPLING:
660         case ABIL_MAKE_OKLOB_PLANT:
661         case ABIL_MAKE_OKLOB_CIRCLE:
662         case ABIL_MAKE_BURNING_BUSH:
663         case ABIL_MAKE_LIGHTNING_SPIRE:
664             num = _count_relevant_monsters(abil);
665             // special case for oklob circles
666             if (abil.ability == ABIL_MAKE_OKLOB_CIRCLE)
667                 num /= 3;
668             // ... and for harmless stuff
669             else if (abil.ability == ABIL_MAKE_PLANT
670                      || abil.ability == ABIL_MAKE_FUNGUS)
671             {
672                 num /= 5;
673             }
674             num -= 2;        // first two are base cost
675             num = max(num, 0);
676             scale10 = min(num, 10);       // next 10 at 10% increment
677             scale20 = num - scale10;      // after that at 20% increment
678             break;
679
680         // Monster type 2: less generous
681         case ABIL_MAKE_ICE_STATUE:
682         case ABIL_MAKE_OCS:
683             num = _count_relevant_monsters(abil);
684             num -= 2; // first two are base cost
685             scale20 = max(num, 0);        // after first two, 20% increment
686             break;
687
688         // Monster type 3: least generous
689         case ABIL_MAKE_OBSIDIAN_STATUE:
690         case ABIL_MAKE_CURSE_SKULL:
691             scale20 = _count_relevant_monsters(abil); // scale immediately
692             break;
693
694         // Simple Traps
695         case ABIL_MAKE_ARROW_TRAP:
696         case ABIL_MAKE_BOLT_TRAP:
697         case ABIL_MAKE_SPEAR_TRAP:
698         case ABIL_MAKE_NEEDLE_TRAP:
699         case ABIL_MAKE_NET_TRAP:
700         case ABIL_MAKE_ALARM_TRAP:
701             num = count_traps(_trap_for_ability(abil));
702             scale10 = max(num-5, 0);   // First 5 at base cost
703             break;
704
705         case ABIL_MAKE_BLADE_TRAP:
706             scale10 = count_traps(TRAP_BLADE); // Max of 18-ish at base cost 3000
707             break;
708     }
709
710     float c = cost; // stave off round-off errors
711     for (; scale10 > 0; scale10--)
712         c = c * 1.1;        // +10%
713     for (; scale20 > 0; scale20--)
714         c = c * 1.2;        // +20%
715
716     return c;
717 }
718
719 int get_gold_cost(ability_type ability)
720 {
721     switch (ability)
722     {
723     case ABIL_GOZAG_CALL_MERCHANT:
724         return gozag_price_for_shop(true);
725     case ABIL_GOZAG_POTION_PETITION:
726         return gozag_potion_price();
727     case ABIL_GOZAG_BRIBE_BRANCH:
728         return GOZAG_BRIBE_AMOUNT;
729     default:
730         return 0;
731     }
732 }
733
734 const string make_cost_description(ability_type ability)
735 {
736     const ability_def& abil = get_ability_def(ability);
737     string ret;
738     if (abil.mp_cost)
739     {
740         ret += make_stringf(", %d %sMP", abil.mp_cost,
741             abil.flags & ABFLAG_PERMANENT_MP ? "Permanent " : "");
742     }
743
744     if (abil.hp_cost)
745     {
746         ret += make_stringf(", %d %sHP", abil.hp_cost.cost(you.hp_max),
747             abil.flags & ABFLAG_PERMANENT_HP ? "Permanent " : "");
748     }
749
750     if (abil.zp_cost)
751         ret += make_stringf(", %d ZP", (int)_zp_cost(abil));
752
753     if (abil.food_cost && !you_foodless(true)
754         && (you.undead_state() != US_SEMI_UNDEAD
755             || you.hunger_state > HS_STARVING))
756     {
757         ret += ", Hunger"; // randomised and exact amount hidden from player
758     }
759
760     if (abil.piety_cost || abil.flags & ABFLAG_PIETY)
761         ret += ", Piety"; // randomised and exact amount hidden from player
762
763     if (abil.flags & ABFLAG_BREATH)
764         ret += ", Breath";
765
766     if (abil.flags & ABFLAG_DELAY)
767         ret += ", Delay";
768
769     if (abil.flags & ABFLAG_PAIN)
770         ret += ", Pain";
771
772     if (abil.flags & ABFLAG_EXHAUSTION)
773         ret += ", Exhaustion";
774
775     if (abil.flags & ABFLAG_INSTANT)
776         ret += ", Instant"; // not really a cost, more of a bonus - bwr
777
778     if (abil.flags & ABFLAG_FRUIT)
779         ret += ", Fruit";
780
781     if (abil.flags & ABFLAG_VARIABLE_FRUIT)
782         ret += ", Fruit or Piety";
783
784     if (abil.flags & ABFLAG_LEVEL_DRAIN)
785         ret += ", Level drain";
786
787     if (abil.flags & ABFLAG_STAT_DRAIN)
788         ret += ", Stat drain";
789
790     if (abil.flags & ABFLAG_SKILL_DRAIN)
791         ret += ", Skill drain";
792
793     if (abil.flags & ABFLAG_GOLD)
794     {
795         const int amount = get_gold_cost(ability);
796         if (amount)
797             ret += make_stringf(", %d Gold", amount);
798         else
799             ret += ", Gold";
800     }
801
802     if (abil.flags & ABFLAG_SACRIFICE)
803     {
804         ret += ", ";
805         const string prefix = "Sacrifice ";
806         ret += string(ability_name(ability)).substr(prefix.size());
807         ret += ru_sac_text(ability);
808     }
809
810     // If we haven't output anything so far, then the effect has no cost
811     if (ret.empty())
812         return "None";
813
814     ret.erase(0, 2);
815     return ret;
816 }
817
818 static string _get_piety_amount_str(int value)
819 {
820     return value > 15 ? "extremely large" :
821            value > 10 ? "large" :
822            value > 5  ? "moderate" :
823                         "small";
824 }
825
826 static const string _detailed_cost_description(ability_type ability)
827 {
828     const ability_def& abil = get_ability_def(ability);
829     ostringstream ret;
830     vector<string> values;
831     string str;
832
833     bool have_cost = false;
834     ret << "This ability costs: ";
835
836     if (abil.mp_cost > 0)
837     {
838         have_cost = true;
839         if (abil.flags & ABFLAG_PERMANENT_MP)
840             ret << "\nMax MP : ";
841         else
842             ret << "\nMP     : ";
843         ret << abil.mp_cost;
844     }
845     if (abil.hp_cost)
846     {
847         have_cost = true;
848         if (abil.flags & ABFLAG_PERMANENT_HP)
849             ret << "\nMax HP : ";
850         else
851             ret << "\nHP     : ";
852         ret << abil.hp_cost.cost(you.hp_max);
853     }
854     if (abil.zp_cost)
855     {
856         have_cost = true;
857         ret << "\nZP     : ";
858         ret << abil.zp_cost;
859     }
860
861     if (abil.food_cost && !you_foodless(true)
862         && (you.undead_state() != US_SEMI_UNDEAD
863             || you.hunger_state > HS_STARVING))
864     {
865         have_cost = true;
866         ret << "\nHunger : ";
867         ret << hunger_cost_string(abil.food_cost + abil.food_cost / 2);
868     }
869
870     if (abil.piety_cost || abil.flags & ABFLAG_PIETY)
871     {
872         have_cost = true;
873         ret << "\nPiety  : ";
874         if (abil.flags & ABFLAG_PIETY)
875             ret << "variable";
876         else
877         {
878             int avgcost = abil.piety_cost.base + abil.piety_cost.add / 2;
879             ret << _get_piety_amount_str(avgcost);
880         }
881     }
882
883     if (abil.flags & ABFLAG_GOLD)
884     {
885         have_cost = true;
886         ret << "\nGold   : ";
887         int gold_amount = get_gold_cost(ability);
888         if (gold_amount)
889             ret << gold_amount;
890         else
891             ret << "variable";
892     }
893
894     if (!have_cost)
895         ret << "nothing.";
896
897     if (abil.flags & ABFLAG_BREATH)
898         ret << "\nYou must catch your breath between uses of this ability.";
899
900     if (abil.flags & ABFLAG_DELAY)
901         ret << "\nIt takes some time before being effective.";
902
903     if (abil.flags & ABFLAG_PAIN)
904         ret << "\nUsing this ability will hurt you.";
905
906     if (abil.flags & ABFLAG_EXHAUSTION)
907         ret << "\nIt cannot be used when exhausted.";
908
909     if (abil.flags & ABFLAG_INSTANT)
910         ret << "\nIt is instantaneous.";
911
912     if (abil.flags & ABFLAG_CONF_OK)
913         ret << "\nYou can use it even if confused.";
914
915     if (abil.flags & ABFLAG_LEVEL_DRAIN)
916         ret << "\nIt will lower your experience level by one when used.";
917
918     if (abil.flags & ABFLAG_STAT_DRAIN)
919         ret << "\nIt will temporarily drain your strength, intelligence or dexterity when used.";
920
921     if (abil.flags & ABFLAG_SKILL_DRAIN)
922         ret << "\nIt will temporarily drain your skills when used.";
923
924     return ret.str();
925 }
926
927 static ability_type _fixup_ability(ability_type ability)
928 {
929     switch (ability)
930     {
931     case ABIL_YRED_ANIMATE_REMAINS_OR_DEAD:
932         // Placeholder for Animate Remains or Animate Dead.
933         if (yred_can_animate_dead())
934             return ABIL_YRED_ANIMATE_DEAD;
935         else
936             return ABIL_YRED_ANIMATE_REMAINS;
937
938     case ABIL_YRED_RECALL_UNDEAD_SLAVES:
939     case ABIL_BEOGH_RECALL_ORCISH_FOLLOWERS:
940         if (!you.recall_list.empty())
941             return ABIL_STOP_RECALL;
942         return ability;
943
944     case ABIL_EVOKE_BERSERK:
945     case ABIL_TROG_BERSERK:
946         switch (you.species)
947         {
948 #if TAG_MAJOR_VERSION == 34
949         case SP_DJINNI:
950 #endif
951         case SP_GHOUL:
952         case SP_MUMMY:
953         case SP_FORMICID:
954             return ABIL_NON_ABILITY;
955         default:
956             return ability;
957         }
958
959     case ABIL_OKAWARU_FINESSE:
960     case ABIL_BLINK:
961     case ABIL_EVOKE_BLINK:
962         if (you.species == SP_FORMICID)
963             return ABIL_NON_ABILITY;
964         else
965             return ability;
966
967     default:
968         return ability;
969     }
970 }
971
972 talent get_talent(ability_type ability, bool check_confused)
973 {
974     ASSERT(ability != ABIL_NON_ABILITY);
975
976     talent result;
977     // Placeholder handling, part 1: The ability we have might be a
978     // placeholder, so convert it into its corresponding ability before
979     // doing anything else, so that we'll handle its flags properly.
980     result.which = _fixup_ability(ability);
981
982     const ability_def &abil = get_ability_def(result.which);
983
984     int failure = 0;
985     bool invoc = false;
986
987     if (check_confused)
988     {
989         if (you.confused() && !testbits(abil.flags, ABFLAG_CONF_OK))
990         {
991             // Initialize these so compilers don't complain.
992             result.is_invocation = 0;
993             result.is_zotdef = 0;
994             result.hotkey = 0;
995             result.fail = 0;
996
997             result.which = ABIL_NON_ABILITY;
998             return result;
999         }
1000     }
1001
1002     // Look through the table to see if there's a preference, else find
1003     // a new empty slot for this ability. - bwr
1004     const int index = _find_ability_slot(abil);
1005     if (index != -1)
1006         result.hotkey = index_to_letter(index);
1007     else
1008         result.hotkey = 0;      // means 'find later on'
1009
1010     switch (ability)
1011     {
1012     // begin spell abilities
1013     case ABIL_DELAYED_FIREBALL:
1014     case ABIL_MUMMY_RESTORATION:
1015     case ABIL_STOP_SINGING:
1016         failure = 0;
1017         break;
1018
1019     // begin zot defence abilities
1020     case ABIL_MAKE_FUNGUS:
1021     case ABIL_MAKE_PLANT:
1022     case ABIL_MAKE_OKLOB_PLANT:
1023     case ABIL_MAKE_OKLOB_SAPLING:
1024     case ABIL_MAKE_BURNING_BUSH:
1025     case ABIL_MAKE_ICE_STATUE:
1026     case ABIL_MAKE_OCS:
1027     case ABIL_MAKE_OBSIDIAN_STATUE:
1028     case ABIL_MAKE_CURSE_SKULL:
1029     case ABIL_MAKE_TELEPORT:
1030     case ABIL_MAKE_ARROW_TRAP:
1031     case ABIL_MAKE_BOLT_TRAP:
1032     case ABIL_MAKE_SPEAR_TRAP:
1033     case ABIL_MAKE_NEEDLE_TRAP:
1034     case ABIL_MAKE_NET_TRAP:
1035     case ABIL_MAKE_ALARM_TRAP:
1036     case ABIL_MAKE_BLADE_TRAP:
1037     case ABIL_MAKE_OKLOB_CIRCLE:
1038     case ABIL_MAKE_ACQUIRE_GOLD:
1039     case ABIL_MAKE_ACQUIREMENT:
1040     case ABIL_MAKE_WATER:
1041     case ABIL_MAKE_LIGHTNING_SPIRE:
1042     case ABIL_MAKE_BAZAAR:
1043     case ABIL_MAKE_ALTAR:
1044     case ABIL_MAKE_GRENADES:
1045     case ABIL_REMOVE_CURSE:
1046         failure = 0;
1047         break;
1048
1049     // begin species abilities - some are mutagenic, too {dlb}
1050     case ABIL_SPIT_POISON:
1051         failure = ((you.species == SP_NAGA) ? 20 : 40)
1052                         - 10 * player_mutation_level(MUT_SPIT_POISON)
1053                         - you.experience_level;
1054         break;
1055
1056     case ABIL_BREATHE_FIRE:
1057         failure = ((you.species == SP_RED_DRACONIAN) ? 30 : 50)
1058                         - 10 * player_mutation_level(MUT_BREATHE_FLAMES)
1059                         - you.experience_level;
1060
1061         if (you.form == TRAN_DRAGON)
1062             failure -= 20;
1063         break;
1064     case ABIL_BREATHE_FROST:
1065     case ABIL_BREATHE_POISON:
1066     case ABIL_SPIT_ACID:
1067     case ABIL_BREATHE_LIGHTNING:
1068     case ABIL_BREATHE_POWER:
1069     case ABIL_BREATHE_STICKY_FLAME:
1070     case ABIL_BREATHE_MEPHITIC:
1071         failure = 30 - you.experience_level;
1072
1073         if (you.form == TRAN_DRAGON)
1074             failure -= 20;
1075         break;
1076
1077     case ABIL_BREATHE_STEAM:
1078         failure = 20 - you.experience_level;
1079
1080         if (you.form == TRAN_DRAGON)
1081             failure -= 20;
1082         break;
1083
1084     case ABIL_FLY:
1085         failure = 42 - (3 * you.experience_level);
1086         break;
1087
1088     case ABIL_TRAN_BAT:
1089         failure = 45 - (2 * you.experience_level);
1090         break;
1091
1092     case ABIL_RECHARGING:       // this is for deep dwarves {1KB}
1093         failure = 45 - (2 * you.experience_level);
1094         break;
1095
1096     case ABIL_DIG:
1097     case ABIL_SHAFT_SELF:
1098         failure = 0;
1099         break;
1100         // end species abilities (some mutagenic)
1101
1102         // begin demonic powers {dlb}
1103     case ABIL_HELLFIRE:
1104         failure = 50 - you.experience_level;
1105         break;
1106         // end demonic powers {dlb}
1107
1108     case ABIL_BLINK:
1109         failure = 48 - (12 * player_mutation_level(MUT_BLINK))
1110                   - you.experience_level / 2;
1111         break;
1112
1113         // begin transformation abilities {dlb}
1114     case ABIL_END_TRANSFORMATION:
1115         failure = 0;
1116         break;
1117         // end transformation abilities {dlb}
1118
1119         // begin item abilities - some possibly mutagenic {dlb}
1120     case ABIL_EVOKE_TURN_INVISIBLE:
1121     case ABIL_EVOKE_TELEPORTATION:
1122         failure = 60 - you.skill(SK_EVOCATIONS, 2);
1123         break;
1124
1125     case ABIL_EVOKE_TURN_VISIBLE:
1126     case ABIL_STOP_FLYING:
1127         failure = 0;
1128         break;
1129
1130     case ABIL_EVOKE_FLIGHT:
1131     case ABIL_EVOKE_BLINK:
1132         failure = 40 - you.skill(SK_EVOCATIONS, 2);
1133         break;
1134     case ABIL_EVOKE_BERSERK:
1135     case ABIL_EVOKE_FOG:
1136     case ABIL_EVOKE_TELEPORT_CONTROL:
1137         failure = 50 - you.skill(SK_EVOCATIONS, 2);
1138         break;
1139     case ABIL_EVOKE_TWISTER:
1140         failure = 100 - you.skill(SK_EVOCATIONS, 4);
1141         break;
1142         // end item abilities - some possibly mutagenic {dlb}
1143
1144         // begin invocations {dlb}
1145     // Abilities with no fail rate.
1146     case ABIL_ZIN_CURE_ALL_MUTATIONS:
1147     case ABIL_ELYVILON_LIFESAVING:
1148     case ABIL_TROG_BURN_SPELLBOOKS:
1149     case ABIL_ASHENZARI_TRANSFER_KNOWLEDGE:
1150     case ABIL_ASHENZARI_END_TRANSFER:
1151     case ABIL_ASHENZARI_SCRYING:
1152     case ABIL_BEOGH_GIFT_ITEM:
1153     case ABIL_JIYVA_CALL_JELLY:
1154     case ABIL_JIYVA_CURE_BAD_MUTATION:
1155     case ABIL_JIYVA_JELLY_PARALYSE:
1156     case ABIL_GOZAG_POTION_PETITION:
1157     case ABIL_GOZAG_CALL_MERCHANT:
1158     case ABIL_GOZAG_BRIBE_BRANCH:
1159     case ABIL_RU_DRAW_OUT_POWER:
1160     case ABIL_RU_POWER_LEAP:
1161     case ABIL_RU_APOCALYPSE:
1162     case ABIL_RU_SACRIFICE_PURITY:
1163     case ABIL_RU_SACRIFICE_WORDS:
1164     case ABIL_RU_SACRIFICE_DRINK:
1165     case ABIL_RU_SACRIFICE_ESSENCE:
1166     case ABIL_RU_SACRIFICE_HEALTH:
1167     case ABIL_RU_SACRIFICE_STEALTH:
1168     case ABIL_RU_SACRIFICE_ARTIFICE:
1169     case ABIL_RU_SACRIFICE_LOVE:
1170     case ABIL_RU_SACRIFICE_COURAGE:
1171     case ABIL_RU_SACRIFICE_ARCANA:
1172     case ABIL_RU_SACRIFICE_NIMBLENESS:
1173     case ABIL_RU_SACRIFICE_DURABILITY:
1174     case ABIL_RU_SACRIFICE_HAND:
1175     case ABIL_RU_SACRIFICE_EXPERIENCE:
1176     case ABIL_RU_SACRIFICE_SKILL:
1177     case ABIL_RU_REJECT_SACRIFICES:
1178     case ABIL_STOP_RECALL:
1179         invoc = true;
1180         failure = 0;
1181         break;
1182
1183     case ABIL_YRED_ANIMATE_REMAINS_OR_DEAD: // Placeholder.
1184         invoc = true;
1185         break;
1186
1187     // Trog and Jiyva abilities, only based on piety.
1188     case ABIL_TROG_BERSERK:    // piety >= 30
1189         invoc = true;
1190         failure = 0;
1191         break;
1192
1193     case ABIL_TROG_REGEN_MR:            // piety >= 50
1194         invoc = true;
1195         failure = piety_breakpoint(2) - you.piety; // starts at 25%
1196         break;
1197
1198     case ABIL_TROG_BROTHERS_IN_ARMS:    // piety >= 100
1199         invoc = true;
1200         failure = piety_breakpoint(5) - you.piety; // starts at 60%
1201         break;
1202
1203     case ABIL_JIYVA_SLIMIFY:
1204         invoc = true;
1205         failure = 90 - you.piety / 2;
1206         break;
1207
1208     // Other invocations, based on piety and Invocations skill.
1209     case ABIL_ELYVILON_PURIFICATION:
1210         invoc = true;
1211         failure = 20 - (you.piety / 20) - you.skill(SK_INVOCATIONS, 5);
1212         break;
1213
1214     case ABIL_ZIN_RECITE:
1215     case ABIL_BEOGH_RECALL_ORCISH_FOLLOWERS:
1216     case ABIL_OKAWARU_HEROISM:
1217     case ABIL_ELYVILON_LESSER_HEALING_SELF:
1218     case ABIL_ELYVILON_LESSER_HEALING_OTHERS:
1219     case ABIL_LUGONU_ABYSS_EXIT:
1220     case ABIL_FEDHAS_SUNLIGHT:
1221     case ABIL_FEDHAS_EVOLUTION:
1222     case ABIL_DITHMENOS_SHADOW_STEP:
1223         invoc = true;
1224         failure = 30 - (you.piety / 20) - you.skill(SK_INVOCATIONS, 6);
1225         break;
1226
1227     case ABIL_YRED_ANIMATE_REMAINS:
1228     case ABIL_YRED_ANIMATE_DEAD:
1229     case ABIL_YRED_INJURY_MIRROR:
1230     case ABIL_CHEIBRIADOS_TIME_BEND:
1231         invoc = true;
1232         failure = 40 - (you.piety / 20) - you.skill(SK_INVOCATIONS, 4);
1233         break;
1234
1235     case ABIL_ZIN_VITALISATION:
1236     case ABIL_TSO_DIVINE_SHIELD:
1237     case ABIL_BEOGH_SMITING:
1238     case ABIL_SIF_MUNA_FORGET_SPELL:
1239     case ABIL_MAKHLEB_MINOR_DESTRUCTION:
1240     case ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB:
1241     case ABIL_ELYVILON_GREATER_HEALING_SELF:
1242     case ABIL_ELYVILON_GREATER_HEALING_OTHERS:
1243     case ABIL_LUGONU_BEND_SPACE:
1244     case ABIL_FEDHAS_PLANT_RING:
1245     case ABIL_QAZLAL_UPHEAVAL:
1246         invoc = true;
1247         failure = 40 - (you.piety / 20) - you.skill(SK_INVOCATIONS, 5);
1248         break;
1249
1250     case ABIL_KIKU_RECEIVE_CORPSES:
1251         invoc = true;
1252         failure = 40 - (you.piety / 20) - you.skill(SK_NECROMANCY, 5);
1253         break;
1254
1255     case ABIL_SIF_MUNA_CHANNEL_ENERGY:
1256         invoc = true;
1257         failure = 40 - you.intel() - you.skill(SK_INVOCATIONS, 1);
1258         break;
1259
1260     case ABIL_YRED_RECALL_UNDEAD_SLAVES:
1261         invoc = true;
1262         failure = 50 - (you.piety / 20) - you.skill(SK_INVOCATIONS, 4);
1263         break;
1264
1265     case ABIL_ZIN_IMPRISON:
1266     case ABIL_LUGONU_BANISH:
1267     case ABIL_CHEIBRIADOS_DISTORTION:
1268     case ABIL_QAZLAL_ELEMENTAL_FORCE:
1269         invoc = true;
1270         failure = 60 - (you.piety / 20) - you.skill(SK_INVOCATIONS, 5);
1271         break;
1272
1273     case ABIL_KIKU_TORMENT:
1274         invoc = true;
1275         failure = 60 - (you.piety / 20) - you.skill(SK_NECROMANCY, 5);
1276         break;
1277
1278     case ABIL_MAKHLEB_MAJOR_DESTRUCTION:
1279     case ABIL_FEDHAS_SPAWN_SPORES:
1280     case ABIL_YRED_DRAIN_LIFE:
1281     case ABIL_CHEIBRIADOS_SLOUCH:
1282     case ABIL_OKAWARU_FINESSE:
1283         invoc = true;
1284         failure = 60 - (you.piety / 25) - you.skill(SK_INVOCATIONS, 4);
1285         break;
1286
1287     case ABIL_TSO_CLEANSING_FLAME:
1288     case ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB:
1289     case ABIL_LUGONU_CORRUPT:
1290     case ABIL_FEDHAS_RAIN:
1291     case ABIL_QAZLAL_DISASTER_AREA:
1292         invoc = true;
1293         failure = 70 - (you.piety / 25) - you.skill(SK_INVOCATIONS, 4);
1294         break;
1295
1296     case ABIL_ZIN_SANCTUARY:
1297     case ABIL_TSO_SUMMON_DIVINE_WARRIOR:
1298     case ABIL_YRED_ENSLAVE_SOUL:
1299     case ABIL_ELYVILON_DIVINE_VIGOUR:
1300     case ABIL_LUGONU_ABYSS_ENTER:
1301     case ABIL_CHEIBRIADOS_TIME_STEP:
1302     case ABIL_DITHMENOS_SHADOW_FORM:
1303         invoc = true;
1304         failure = 80 - (you.piety / 25) - you.skill(SK_INVOCATIONS, 4);
1305         break;
1306
1307     case ABIL_NEMELEX_STACK_FIVE:
1308         invoc = true;
1309         failure = 80 - (you.piety / 25) - you.skill(SK_EVOCATIONS, 4);
1310         break;
1311
1312     case ABIL_NEMELEX_DEAL_FOUR:
1313         invoc = true;
1314         failure = 70 - (you.piety * 2 / 45) - you.skill(SK_EVOCATIONS, 9) / 2;
1315         break;
1316
1317     case ABIL_NEMELEX_TRIPLE_DRAW:
1318         invoc = true;
1319         failure = 60 - (you.piety / 20) - you.skill(SK_EVOCATIONS, 5);
1320         break;
1321
1322     case ABIL_RENOUNCE_RELIGION:
1323     case ABIL_CONVERT_TO_BEOGH:
1324         invoc = true;
1325         failure = 0;
1326         break;
1327
1328         // end invocations {dlb}
1329     default:
1330         failure = -1;
1331         break;
1332     }
1333
1334     if (failure < 0)
1335         failure = 0;
1336
1337     if (failure > 100)
1338         failure = 100;
1339
1340     result.fail = failure;
1341     result.is_invocation = invoc;
1342     result.is_zotdef = abil.flags & ABFLAG_ZOTDEF;
1343
1344     return result;
1345 }
1346
1347 const char* ability_name(ability_type ability)
1348 {
1349     return get_ability_def(ability).name;
1350 }
1351
1352 vector<const char*> get_ability_names()
1353 {
1354     vector<const char*> result;
1355     for (const talent &tal : your_talents(false))
1356         result.push_back(ability_name(tal.which));
1357     return result;
1358 }
1359
1360 // XXX: should this be in describe.cc?
1361 string get_ability_desc(const ability_type ability)
1362 {
1363     const string& name = ability_name(ability);
1364
1365     string lookup = getLongDescription(name + " ability");
1366
1367     if (lookup.empty()) // Nothing found?
1368         lookup = "No description found.\n";
1369
1370     if (god_hates_ability(ability, you.religion))
1371     {
1372         lookup += uppercase_first(god_name(you.religion))
1373                   + " frowns upon the use of this ability.\n";
1374     }
1375
1376     ostringstream res;
1377     res << name << "\n\n" << lookup << "\n"
1378         << _detailed_cost_description(ability);
1379
1380     const string quote = getQuoteString(name + " ability");
1381     if (!quote.empty())
1382         res << "\n\n" << quote;
1383
1384     return res.str();
1385 }
1386
1387 static void _print_talent_description(const talent& tal)
1388 {
1389     clrscr();
1390
1391     print_description(get_ability_desc(tal.which));
1392
1393     getchm();
1394     clrscr();
1395 }
1396
1397 void no_ability_msg()
1398 {
1399     // Give messages if the character cannot use innate talents right now.
1400     // * Vampires can't turn into bats when full of blood.
1401     // * Tengu can't start to fly if already flying.
1402     if (you.species == SP_VAMPIRE && you.experience_level >= 3)
1403         mpr("Sorry, you're too full to transform right now.");
1404     else if (you.species == SP_TENGU && you.experience_level >= 5
1405              || player_mutation_level(MUT_BIG_WINGS))
1406     {
1407         if (you.flight_mode())
1408             mpr("You're already flying!");
1409     }
1410     else
1411         mpr("Sorry, you're not good enough to have a special ability.");
1412 }
1413
1414 bool activate_ability()
1415 {
1416     if (you.berserk())
1417     {
1418         canned_msg(MSG_TOO_BERSERK);
1419         crawl_state.zero_turns_taken();
1420         return false;
1421     }
1422
1423     vector<talent> talents = your_talents(false);
1424     if (talents.empty())
1425     {
1426         no_ability_msg();
1427         crawl_state.zero_turns_taken();
1428         return false;
1429     }
1430
1431     if (you.confused())
1432     {
1433         talents = your_talents(true);
1434         if (talents.empty())
1435         {
1436             canned_msg(MSG_TOO_CONFUSED);
1437             crawl_state.zero_turns_taken();
1438             return false;
1439         }
1440     }
1441 #ifdef TOUCH_UI
1442     int selected = choose_ability_menu(talents);
1443     if (selected == -1)
1444     {
1445         canned_msg(MSG_OK);
1446         crawl_state.zero_turns_taken();
1447         return false;
1448     }
1449 #else
1450     int selected = -1;
1451     while (selected < 0)
1452     {
1453         msg::streams(MSGCH_PROMPT) << "Use which ability? (? or * to list) "
1454                                    << endl;
1455
1456         const int keyin = get_ch();
1457
1458         if (keyin == '?' || keyin == '*')
1459         {
1460             selected = choose_ability_menu(talents);
1461             if (selected == -1)
1462             {
1463                 canned_msg(MSG_OK);
1464                 crawl_state.zero_turns_taken();
1465                 return false;
1466             }
1467         }
1468         else if (key_is_escape(keyin) || keyin == ' ' || keyin == '\r'
1469                  || keyin == '\n')
1470         {
1471             canned_msg(MSG_OK);
1472             crawl_state.zero_turns_taken();
1473             return false;
1474         }
1475         else if (isaalpha(keyin))
1476         {
1477             // Try to find the hotkey.
1478             for (unsigned int i = 0; i < talents.size(); ++i)
1479             {
1480                 if (talents[i].hotkey == keyin)
1481                 {
1482                     selected = static_cast<int>(i);
1483                     break;
1484                 }
1485             }
1486
1487             // If we can't, cancel out.
1488             if (selected < 0)
1489             {
1490                 mpr("You can't do that.");
1491                 crawl_state.zero_turns_taken();
1492                 return false;
1493             }
1494         }
1495     }
1496 #endif
1497     return activate_talent(talents[selected]);
1498 }
1499
1500 // Check prerequisites for a number of abilities.
1501 // Abort any attempt if these cannot be met, without losing the turn.
1502 // TODO: Many more cases need to be added!
1503 static bool _check_ability_possible(const ability_def& abil,
1504                                     bool hungerCheck = true,
1505                                     bool quiet = false)
1506 {
1507     if (you.berserk())
1508     {
1509         if (!quiet)
1510             canned_msg(MSG_TOO_BERSERK);
1511         return false;
1512     }
1513
1514     if (you.confused() && !testbits(abil.flags, ABFLAG_CONF_OK))
1515     {
1516         if (!quiet)
1517             canned_msg(MSG_TOO_CONFUSED);
1518         return false;
1519     }
1520
1521     if (silenced(you.pos()) && !you_worship(GOD_NEMELEX_XOBEH)
1522           && !you_worship(GOD_RU))
1523     {
1524         talent tal = get_talent(abil.ability, false);
1525         if (tal.is_invocation)
1526         {
1527             if (!quiet)
1528             {
1529                 mprf("You cannot call out to %s while silenced.",
1530                      god_name(you.religion).c_str());
1531             }
1532             return false;
1533         }
1534     }
1535     // Don't insta-starve the player.
1536     // (Losing consciousness possible from 400 downward.)
1537     if (hungerCheck && !you.undead_state())
1538     {
1539         const int expected_hunger = you.hunger - abil.food_cost * 2;
1540         if (!quiet)
1541         {
1542             dprf("hunger: %d, max. food_cost: %d, expected hunger: %d",
1543                  you.hunger, abil.food_cost * 2, expected_hunger);
1544         }
1545         // Safety margin for natural hunger, mutations etc.
1546         if (expected_hunger <= 50)
1547         {
1548             if (!quiet)
1549                 canned_msg(MSG_TOO_HUNGRY);
1550             return false;
1551         }
1552     }
1553
1554     // in case of mp rot ability, check is the player have enough natural MP
1555     // (avoid use of ring/staf of magical power)
1556     if ((abil.flags & ABFLAG_PERMANENT_MP)
1557         && get_real_mp(false) < (int)abil.mp_cost)
1558     {
1559         if (!quiet)
1560             mpr("You don't have enough innate magic capacity to sacrifice.");
1561         return false;
1562     }
1563
1564     switch (abil.ability)
1565     {
1566     case ABIL_ZIN_RECITE:
1567     {
1568         if (!zin_check_able_to_recite(quiet))
1569             return false;
1570
1571         if (zin_check_recite_to_monsters(quiet) != 1)
1572         {
1573             if (!quiet)
1574                 mpr("There's no appreciative audience!");
1575             return false;
1576         }
1577         return true;
1578     }
1579
1580     case ABIL_ZIN_CURE_ALL_MUTATIONS:
1581         return how_mutated();
1582
1583     case ABIL_ZIN_SANCTUARY:
1584         if (env.sanctuary_time)
1585         {
1586             if (!quiet)
1587                 mpr("There's already a sanctuary in place on this level.");
1588             return false;
1589         }
1590         return true;
1591
1592     case ABIL_ELYVILON_PURIFICATION:
1593         if (!you.disease && !you.rotting && !you.duration[DUR_POISONING]
1594             && !you.duration[DUR_CONF] && !you.duration[DUR_SLOW]
1595             && !you.petrifying()
1596             && you.strength(false) == you.max_strength()
1597             && you.intel(false) == you.max_intel()
1598             && you.dex(false) == you.max_dex()
1599             && !player_rotted()
1600             && !you.duration[DUR_WEAK])
1601         {
1602             if (!quiet)
1603                 mpr("Nothing ails you!");
1604             return false;
1605         }
1606         return true;
1607
1608     case ABIL_MUMMY_RESTORATION:
1609         if (you.strength(false) == you.max_strength()
1610             && you.intel(false) == you.max_intel()
1611             && you.dex(false) == you.max_dex()
1612             && !player_rotted())
1613         {
1614             if (!quiet)
1615                 mpr("You don't need to restore your stats or health!");
1616             return false;
1617         }
1618         return true;
1619
1620     case ABIL_LUGONU_ABYSS_EXIT:
1621         if (!player_in_branch(BRANCH_ABYSS))
1622         {
1623             if (!quiet)
1624                 mpr("You aren't in the Abyss!");
1625             return false;
1626         }
1627         return true;
1628
1629     case ABIL_LUGONU_CORRUPT:
1630         return !is_level_incorruptible(quiet);
1631
1632     case ABIL_LUGONU_ABYSS_ENTER:
1633         if (player_in_branch(BRANCH_ABYSS) || brdepth[BRANCH_ABYSS] == -1)
1634         {
1635             if (!quiet)
1636                 mpr("You're already here!");
1637             return false;
1638         }
1639         return true;
1640
1641     case ABIL_SIF_MUNA_FORGET_SPELL:
1642         if (you.spell_no == 0)
1643         {
1644             if (!quiet)
1645                 canned_msg(MSG_NO_SPELLS);
1646             return false;
1647         }
1648         return true;
1649
1650     case ABIL_ASHENZARI_TRANSFER_KNOWLEDGE:
1651         if (all_skills_maxed(true))
1652         {
1653             if (!quiet)
1654                 mpr("You have nothing more to learn.");
1655             return false;
1656         }
1657         return true;
1658
1659     case ABIL_OKAWARU_FINESSE:
1660         if (stasis_blocks_effect(false,
1661                                  quiet ? nullptr
1662                                        : "%s makes your neck tingle."))
1663         {
1664             return false;
1665         }
1666         return true;
1667
1668     case ABIL_FEDHAS_EVOLUTION:
1669         return fedhas_check_evolve_flora(quiet);
1670
1671     case ABIL_FEDHAS_SPAWN_SPORES:
1672     {
1673         const int retval = fedhas_check_corpse_spores(quiet);
1674         if (retval <= 0)
1675         {
1676             if (!quiet)
1677             {
1678                 if (retval == 0)
1679                     mpr("No corpses are in range.");
1680                 else
1681                     canned_msg(MSG_OK);
1682             }
1683             return false;
1684         }
1685         return true;
1686     }
1687
1688     case ABIL_SPIT_POISON:
1689     case ABIL_BREATHE_FIRE:
1690     case ABIL_BREATHE_FROST:
1691     case ABIL_BREATHE_POISON:
1692     case ABIL_BREATHE_LIGHTNING:
1693     case ABIL_SPIT_ACID:
1694     case ABIL_BREATHE_POWER:
1695     case ABIL_BREATHE_STICKY_FLAME:
1696     case ABIL_BREATHE_STEAM:
1697     case ABIL_BREATHE_MEPHITIC:
1698         if (you.duration[DUR_BREATH_WEAPON])
1699         {
1700             if (!quiet)
1701                 canned_msg(MSG_CANNOT_DO_YET);
1702             return false;
1703         }
1704         return true;
1705
1706     case ABIL_BLINK:
1707     case ABIL_EVOKE_BLINK:
1708     {
1709         const string no_tele_reason = you.no_tele_reason(false, true);
1710         if (no_tele_reason.empty())
1711             return true;
1712
1713         if (!quiet)
1714              mpr(no_tele_reason);
1715         return false;
1716     }
1717
1718     case ABIL_EVOKE_BERSERK:
1719     case ABIL_TROG_BERSERK:
1720         return you.can_go_berserk(true, false, true)
1721                && (quiet || berserk_check_wielded_weapon());
1722
1723     case ABIL_EVOKE_FOG:
1724         if (env.cgrid(you.pos()) != EMPTY_CLOUD)
1725         {
1726             if (!quiet)
1727                 mpr("It's too cloudy to do that here.");
1728             return false;
1729         }
1730         return true;
1731
1732     case ABIL_GOZAG_POTION_PETITION:
1733         return gozag_setup_potion_petition(quiet);
1734
1735     case ABIL_GOZAG_CALL_MERCHANT:
1736         return gozag_setup_call_merchant(quiet);
1737
1738     case ABIL_GOZAG_BRIBE_BRANCH:
1739         return gozag_check_bribe_branch(quiet);
1740
1741     default:
1742         return true;
1743     }
1744 }
1745
1746 bool check_ability_possible(const ability_type ability, bool hungerCheck,
1747                             bool quiet)
1748 {
1749     return _check_ability_possible(get_ability_def(ability), hungerCheck,
1750                                    quiet);
1751 }
1752
1753 bool activate_talent(const talent& tal)
1754 {
1755     if (you.berserk())
1756     {
1757         canned_msg(MSG_TOO_BERSERK);
1758         crawl_state.zero_turns_taken();
1759         return false;
1760     }
1761
1762     // Doing these would outright kill the player.
1763     // (or, in the case of the stat-zeros, they'd at least be extremely
1764     // dangerous.)
1765     if (tal.which == ABIL_STOP_FLYING)
1766     {
1767         if (is_feat_dangerous(grd(you.pos()), false, true))
1768         {
1769             mpr("Stopping flight right now would be fatal!");
1770             crawl_state.zero_turns_taken();
1771             return false;
1772         }
1773     }
1774     else if (tal.which == ABIL_TRAN_BAT)
1775     {
1776         if (!check_form_stat_safety(TRAN_BAT))
1777         {
1778             crawl_state.zero_turns_taken();
1779             return false;
1780         }
1781     }
1782     else if (tal.which == ABIL_END_TRANSFORMATION)
1783     {
1784         if (feat_dangerous_for_form(TRAN_NONE, env.grid(you.pos())))
1785         {
1786             mprf("Turning back right now would cause you to %s!",
1787                  env.grid(you.pos()) == DNGN_LAVA ? "burn" : "drown");
1788
1789             crawl_state.zero_turns_taken();
1790             return false;
1791         }
1792
1793         if (!check_form_stat_safety(TRAN_NONE))
1794         {
1795             crawl_state.zero_turns_taken();
1796             return false;
1797         }
1798     }
1799
1800     if ((tal.which == ABIL_EVOKE_BERSERK || tal.which == ABIL_TROG_BERSERK)
1801         && !you.can_go_berserk(true))
1802     {
1803         crawl_state.zero_turns_taken();
1804         return false;
1805     }
1806
1807     if ((tal.which == ABIL_EVOKE_FLIGHT || tal.which == ABIL_TRAN_BAT || tal.which == ABIL_FLY)
1808         && !flight_allowed())
1809     {
1810         crawl_state.zero_turns_taken();
1811         return false;
1812     }
1813
1814     // Some abilities don't need a hunger check.
1815     bool hungerCheck = true;
1816     switch (tal.which)
1817     {
1818         case ABIL_RENOUNCE_RELIGION:
1819         case ABIL_CONVERT_TO_BEOGH:
1820         case ABIL_STOP_FLYING:
1821         case ABIL_EVOKE_TURN_VISIBLE:
1822         case ABIL_END_TRANSFORMATION:
1823         case ABIL_DELAYED_FIREBALL:
1824         case ABIL_STOP_SINGING:
1825         case ABIL_MUMMY_RESTORATION:
1826         case ABIL_TRAN_BAT:
1827         case ABIL_ASHENZARI_END_TRANSFER:
1828         case ABIL_ZIN_VITALISATION:
1829         case ABIL_GOZAG_POTION_PETITION:
1830             hungerCheck = false;
1831             break;
1832         default:
1833             break;
1834     }
1835
1836     if (hungerCheck && !you.undead_state() && !you_foodless()
1837         && you.hunger_state == HS_STARVING)
1838     {
1839         canned_msg(MSG_TOO_HUNGRY);
1840         crawl_state.zero_turns_taken();
1841         return false;
1842     }
1843
1844     const ability_def& abil = get_ability_def(tal.which);
1845
1846     // Check that we can afford to pay the costs.
1847     // Note that mutation shenanigans might leave us with negative MP,
1848     // so don't fail in that case if there's no MP cost.
1849     if (abil.mp_cost > 0 && !enough_mp(abil.mp_cost, false, true))
1850     {
1851         crawl_state.zero_turns_taken();
1852         return false;
1853     }
1854
1855     const int hpcost = abil.hp_cost.cost(you.hp_max);
1856     if (hpcost > 0 && !enough_hp(hpcost, false))
1857     {
1858         crawl_state.zero_turns_taken();
1859         return false;
1860     }
1861
1862     const int zpcost = _zp_cost(abil);
1863     if (zpcost)
1864     {
1865         if (!enough_zp(zpcost, false))
1866         {
1867             crawl_state.zero_turns_taken();
1868             return false;
1869         }
1870     }
1871
1872     if (!_check_ability_possible(abil, hungerCheck))
1873     {
1874         crawl_state.zero_turns_taken();
1875         return false;
1876     }
1877
1878     bool fail = random2avg(100, 3) < tal.fail;
1879
1880     const spret_type ability_result = _do_ability(abil, fail);
1881     switch (ability_result)
1882     {
1883         case SPRET_SUCCESS:
1884             ASSERT(!fail);
1885             practise(EX_USED_ABIL, abil.ability);
1886             _pay_ability_costs(abil, zpcost);
1887             count_action(tal.is_invocation ? CACT_INVOKE : CACT_ABIL, abil.ability);
1888             return true;
1889         case SPRET_FAIL:
1890             mpr("You fail to use your ability.");
1891             you.turn_is_over = true;
1892             return false;
1893         case SPRET_ABORT:
1894             crawl_state.zero_turns_taken();
1895             return false;
1896         case SPRET_NONE:
1897         default:
1898             die("Weird ability return type");
1899             return false;
1900     }
1901 }
1902
1903 static int _calc_breath_ability_range(ability_type ability)
1904 {
1905     // Following monster draconian abilities.
1906     switch (ability)
1907     {
1908     case ABIL_BREATHE_FIRE:         return 6;
1909     case ABIL_BREATHE_FROST:        return 6;
1910     case ABIL_BREATHE_MEPHITIC:     return 7;
1911     case ABIL_BREATHE_LIGHTNING:    return 8;
1912     case ABIL_SPIT_ACID:            return 8;
1913     case ABIL_BREATHE_POWER:        return 8;
1914     case ABIL_BREATHE_STICKY_FLAME: return 1;
1915     case ABIL_BREATHE_STEAM:        return 7;
1916     case ABIL_BREATHE_POISON:       return 7;
1917     default:
1918         die("Bad breath type!");
1919         break;
1920     }
1921     return -2;
1922 }
1923
1924 static bool _sticky_flame_can_hit(const actor *act)
1925 {
1926     if (act->is_monster())
1927     {
1928         const monster* mons = act->as_monster();
1929         bolt testbeam;
1930         testbeam.thrower = KILL_YOU;
1931         zappy(ZAP_BREATHE_STICKY_FLAME, 100, testbeam);
1932
1933         return !testbeam.ignores_monster(mons);
1934     }
1935     else
1936         return false;
1937 }
1938
1939 /*
1940  * Use an ability.
1941  *
1942  * @param abil The actual ability used.
1943  * @param fail If true, the ability is doomed to fail, and SPRET_FAIL will
1944  * be returned if the ability is not SPRET_ABORTed.
1945  * @returns Whether the spell succeeded (SPRET_SUCCESS), failed (SPRET_FAIL),
1946  *  or was canceled (SPRET_ABORT). Never returns SPRET_NONE.
1947  */
1948 static spret_type _do_ability(const ability_def& abil, bool fail)
1949 {
1950     int power;
1951     dist abild;
1952     bolt beam;
1953     dist spd;
1954
1955     direction_chooser_args args;
1956     args.restricts = DIR_TARGET;
1957     args.needs_path = false;
1958     args.may_target_monster = false;
1959
1960     // Note: the costs will not be applied until after this switch
1961     // statement... it's assumed that only failures have returned! - bwr
1962     switch (abil.ability)
1963     {
1964     case ABIL_MAKE_FUNGUS:
1965         fail_check();
1966         if (count_allies() > MAX_MONSTERS / 2)
1967         {
1968             mpr("Mushrooms don't grow well in such thickets.");
1969             return SPRET_ABORT;
1970         }
1971         args.top_prompt="Center fungus circle where?";
1972         direction(abild, args);
1973         if (!abild.isValid)
1974         {
1975             if (abild.isCancel)
1976             canned_msg(MSG_OK);
1977             return SPRET_ABORT;
1978         }
1979         for (adjacent_iterator ai(abild.target); ai; ++ai)
1980         {
1981             place_monster(mgen_data(MONS_FUNGUS, BEH_FRIENDLY, &you, 0, 0, *ai,
1982                           you.pet_target), true);
1983         }
1984         break;
1985
1986     // Begin ZotDef allies
1987     case ABIL_MAKE_PLANT:
1988     case ABIL_MAKE_OKLOB_SAPLING:
1989     case ABIL_MAKE_OKLOB_PLANT:
1990     case ABIL_MAKE_BURNING_BUSH:
1991     case ABIL_MAKE_ICE_STATUE:
1992     case ABIL_MAKE_OCS:
1993     case ABIL_MAKE_OBSIDIAN_STATUE:
1994     case ABIL_MAKE_CURSE_SKULL:
1995     case ABIL_MAKE_LIGHTNING_SPIRE:
1996         fail_check();
1997         if (!create_zotdef_ally(_monster_for_ability(abil),
1998             _zd_mons_description_for_ability(abil).c_str()))
1999         {
2000             return SPRET_ABORT;
2001         }
2002         break;
2003     // End ZotDef Allies
2004
2005     case ABIL_MAKE_TELEPORT:
2006         fail_check();
2007         you_teleport_now(true);
2008         break;
2009
2010     // ZotDef traps
2011     case ABIL_MAKE_ARROW_TRAP:
2012     case ABIL_MAKE_BOLT_TRAP:
2013     case ABIL_MAKE_SPEAR_TRAP:
2014     case ABIL_MAKE_NEEDLE_TRAP:
2015     case ABIL_MAKE_NET_TRAP:
2016     case ABIL_MAKE_ALARM_TRAP:
2017     case ABIL_MAKE_BLADE_TRAP:
2018         fail_check();
2019         if (!create_trap(_trap_for_ability(abil)))
2020             return SPRET_ABORT;
2021         break;
2022     // End ZotDef traps
2023
2024     case ABIL_MAKE_OKLOB_CIRCLE:
2025         fail_check();
2026         args.top_prompt = "Center oklob circle where?";
2027         direction(abild, args);
2028         if (!abild.isValid)
2029         {
2030             if (abild.isCancel)
2031             canned_msg(MSG_OK);
2032             return SPRET_ABORT;
2033         }
2034         for (adjacent_iterator ai(abild.target); ai; ++ai)
2035         {
2036             place_monster(mgen_data(MONS_OKLOB_PLANT, BEH_FRIENDLY, &you, 0, 0,
2037                           *ai, you.pet_target), true);
2038         }
2039         break;
2040
2041     case ABIL_MAKE_ACQUIRE_GOLD:
2042         fail_check();
2043         acquirement(OBJ_GOLD, AQ_SCROLL);
2044         break;
2045
2046     case ABIL_MAKE_ACQUIREMENT:
2047         fail_check();
2048         acquirement(OBJ_RANDOM, AQ_SCROLL);
2049         break;
2050
2051     case ABIL_MAKE_WATER:
2052         fail_check();
2053         zotdef_create_pond(you.pos(), 3);
2054         break;
2055
2056     case ABIL_MAKE_BAZAAR:
2057     {
2058         fail_check();
2059         // Early exit: don't clobber important features.
2060         if (feat_is_critical(grd(you.pos())))
2061         {
2062             mpr("The dungeon trembles momentarily.");
2063             return SPRET_ABORT;
2064         }
2065
2066         // Generate a portal to something.
2067         const map_def *mapidx = random_map_for_tag("zotdef_bazaar", false);
2068         if (mapidx && dgn_safe_place_map(mapidx, false, true, you.pos()))
2069             mpr("A mystic portal forms.");
2070         else
2071         {
2072             mpr("A buggy portal flickers into view, then vanishes.");
2073             return SPRET_ABORT;
2074         }
2075
2076         break;
2077     }
2078
2079     case ABIL_MAKE_ALTAR:
2080         fail_check();
2081         if (!zotdef_create_altar())
2082         {
2083             mpr("The dungeon dims for a moment.");
2084             return SPRET_ABORT;
2085         }
2086         break;
2087
2088     case ABIL_MAKE_GRENADES:
2089         fail_check();
2090         if (create_monster(
2091                mgen_data(MONS_GIANT_SPORE, BEH_FRIENDLY, &you, 6, 0,
2092                          you.pos(), you.pet_target,
2093                          0)))
2094         {
2095             mpr("You create a living grenade.");
2096         }
2097         if (create_monster(
2098                mgen_data(MONS_GIANT_SPORE, BEH_FRIENDLY, &you, 6, 0,
2099                          you.pos(), you.pet_target,
2100                          0)))
2101         {
2102             mpr("You create a living grenade.");
2103         }
2104         break;
2105
2106     case ABIL_REMOVE_CURSE:
2107         fail_check();
2108         remove_curse();
2109         lose_stat(STAT_RANDOM, 1, true, "zot ability");
2110         break;
2111
2112     case ABIL_MUMMY_RESTORATION:
2113     {
2114         fail_check();
2115         mpr("You infuse your body with magical energy.");
2116         bool did_restore = restore_stat(STAT_ALL, 0, false);
2117
2118         const int oldhpmax = you.hp_max;
2119         unrot_hp(9999);
2120         if (you.hp_max > oldhpmax)
2121             did_restore = true;
2122
2123         // If nothing happened, don't take one max MP, don't use a turn.
2124         if (!did_restore)
2125         {
2126             canned_msg(MSG_NOTHING_HAPPENS);
2127             return SPRET_ABORT;
2128         }
2129
2130         break;
2131     }
2132
2133     case ABIL_RECHARGING:
2134         fail_check();
2135         if (recharge_wand() <= 0)
2136             return SPRET_ABORT; // fail message is already given
2137         break;
2138
2139     case ABIL_DIG:
2140         fail_check();
2141         if (!you.digging)
2142         {
2143             you.digging = true;
2144             mpr("You extend your mandibles.");
2145         }
2146         else
2147         {
2148             mpr("You are already prepared to dig.");
2149             return SPRET_ABORT;
2150         }
2151         break;
2152
2153     case ABIL_SHAFT_SELF:
2154         fail_check();
2155         if (you.can_do_shaft_ability(false))
2156         {
2157             if (yesno("Are you sure you want to shaft yourself?", true, 'n'))
2158                 start_delay(DELAY_SHAFT_SELF, 1);
2159             else
2160                 return SPRET_ABORT;
2161         }
2162         else
2163             return SPRET_ABORT;
2164         break;
2165
2166     case ABIL_DELAYED_FIREBALL:
2167     {
2168         fail_check();
2169         // Note: Power level of ball calculated at release. - bwr
2170         power = calc_spell_power(SPELL_DELAYED_FIREBALL, true);
2171         beam.range = spell_range(SPELL_FIREBALL, power);
2172
2173         targetter_beam tgt(&you, beam.range, ZAP_FIREBALL, power, 1, 1);
2174
2175         if (!spell_direction(spd, beam, DIR_NONE, TARG_HOSTILE, beam.range,
2176                              true, true, false, nullptr,
2177                              "Aiming: <white>Delayed Fireball</white>",
2178                              false, &tgt))
2179         {
2180             return SPRET_ABORT;
2181         }
2182
2183         if (!zapping(ZAP_FIREBALL, power, beam, true, nullptr, false))
2184             return SPRET_ABORT;
2185
2186         // Only one allowed, since this is instantaneous. - bwr
2187         you.attribute[ATTR_DELAYED_FIREBALL] = 0;
2188         break;
2189     }
2190
2191     case ABIL_SPIT_POISON:      // Naga + spit poison mutation
2192         power = you.experience_level
2193                 + player_mutation_level(MUT_SPIT_POISON) * 5
2194                 + (you.species == SP_NAGA) * 10;
2195         beam.range = 6;         // following Venom Bolt
2196
2197         if (!spell_direction(abild, beam)
2198             || !player_tracer(ZAP_SPIT_POISON, power, beam))
2199         {
2200             return SPRET_ABORT;
2201         }
2202         else
2203         {
2204             fail_check();
2205             zapping(ZAP_SPIT_POISON, power, beam);
2206             zin_recite_interrupt();
2207             you.set_duration(DUR_BREATH_WEAPON, 3 + random2(5));
2208         }
2209         break;
2210
2211     case ABIL_EVOKE_TELEPORTATION:    // ring of teleportation
2212         fail_check();
2213         you_teleport();
2214         break;
2215
2216     case ABIL_BREATHE_STICKY_FLAME:
2217     {
2218         targetter_splash hitfunc(&you);
2219         beam.range = 1;
2220         if (!spell_direction(abild, beam,
2221                              DIR_NONE, TARG_HOSTILE, 0, true, true, false,
2222                              nullptr, nullptr, false,
2223                              &hitfunc))
2224         {
2225             return SPRET_ABORT;
2226         }
2227
2228         if (stop_attack_prompt(hitfunc, "spit at", _sticky_flame_can_hit))
2229             return SPRET_ABORT;
2230
2231         fail_check();
2232         zapping(ZAP_BREATHE_STICKY_FLAME, (you.form == TRAN_DRAGON) ?
2233                 2 * you.experience_level : you.experience_level,
2234             beam, false, "You spit a glob of burning liquid.");
2235
2236         zin_recite_interrupt();
2237         you.increase_duration(DUR_BREATH_WEAPON,
2238                       3 + random2(10) + random2(30 - you.experience_level));
2239         break;
2240     }
2241
2242     case ABIL_BREATHE_FIRE:
2243     case ABIL_BREATHE_FROST:
2244     case ABIL_BREATHE_POISON:
2245     case ABIL_SPIT_ACID:
2246     case ABIL_BREATHE_POWER:
2247     case ABIL_BREATHE_STEAM:
2248     case ABIL_BREATHE_MEPHITIC:
2249         beam.range = _calc_breath_ability_range(abil.ability);
2250         if (!spell_direction(abild, beam))
2251             return SPRET_ABORT;
2252
2253         // fallthrough to ABIL_BREATHE_LIGHTNING
2254
2255     case ABIL_BREATHE_LIGHTNING: // not targeted
2256         fail_check();
2257
2258         // TODO: refactor this to use only one call to zapping(), don't
2259         // duplicate its fail_check(), split out breathe_lightning, etc
2260
2261         switch (abil.ability)
2262         {
2263         case ABIL_BREATHE_FIRE:
2264             power = you.experience_level
2265                     + player_mutation_level(MUT_BREATHE_FLAMES) * 4;
2266
2267             if (you.form == TRAN_DRAGON)
2268                 power += 12;
2269
2270             snprintf(info, INFO_SIZE, "You breathe a blast of fire%c",
2271                      (power < 15) ? '.':'!');
2272
2273             if (!zapping(ZAP_BREATHE_FIRE, power, beam, true, info))
2274                 return SPRET_ABORT;
2275             break;
2276
2277         case ABIL_BREATHE_FROST:
2278             if (!zapping(ZAP_BREATHE_FROST,
2279                  (you.form == TRAN_DRAGON) ?
2280                      2 * you.experience_level : you.experience_level,
2281                  beam, true,
2282                          "You exhale a wave of freezing cold."))
2283             {
2284                 return SPRET_ABORT;
2285             }
2286             break;
2287
2288         case ABIL_BREATHE_POISON:
2289             if (!zapping(ZAP_BREATHE_POISON, you.experience_level, beam, true,
2290                          "You exhale a blast of poison gas."))
2291             {
2292                 return SPRET_ABORT;
2293             }
2294             break;
2295
2296         case ABIL_BREATHE_LIGHTNING:
2297             mpr("You breathe a wild blast of lightning!");
2298             black_drac_breath();
2299             break;
2300
2301         case ABIL_SPIT_ACID:
2302             if (!zapping(ZAP_BREATHE_ACID,
2303                 (you.form == TRAN_DRAGON) ?
2304                     2 * you.experience_level : you.experience_level,
2305                 beam, true, "You spit a glob of acid."))
2306             {
2307                 return SPRET_ABORT;
2308             }
2309             break;
2310
2311         case ABIL_BREATHE_POWER:
2312             if (!zapping(ZAP_BREATHE_POWER,
2313                 (you.form == TRAN_DRAGON) ?
2314                     2 * you.experience_level : you.experience_level,
2315                 beam, true,
2316                          "You spit a bolt of dispelling energy."))
2317             {
2318                 return SPRET_ABORT;
2319             }
2320             break;
2321
2322         case ABIL_BREATHE_STICKY_FLAME:
2323             if (!zapping(ZAP_BREATHE_STICKY_FLAME,
2324                 (you.form == TRAN_DRAGON) ?
2325                     2 * you.experience_level : you.experience_level,
2326                 beam, true,
2327                          "You spit a glob of burning liquid."))
2328             {
2329                 return SPRET_ABORT;
2330             }
2331             break;
2332
2333         case ABIL_BREATHE_STEAM:
2334             if (!zapping(ZAP_BREATHE_STEAM,
2335                 (you.form == TRAN_DRAGON) ?
2336                     2 * you.experience_level : you.experience_level,
2337                 beam, true,
2338                          "You exhale a blast of scalding steam."))
2339             {
2340                 return SPRET_ABORT;
2341             }
2342             break;
2343
2344         case ABIL_BREATHE_MEPHITIC:
2345             if (!zapping(ZAP_BREATHE_MEPHITIC,
2346                 (you.form == TRAN_DRAGON) ?
2347                     2 * you.experience_level : you.experience_level,
2348                 beam, true,
2349                          "You exhale a blast of noxious fumes."))
2350             {
2351                 return SPRET_ABORT;
2352             }
2353             break;
2354
2355         default:
2356             break;
2357         }
2358
2359         zin_recite_interrupt();
2360         you.increase_duration(DUR_BREATH_WEAPON,
2361                       3 + random2(10) + random2(30 - you.experience_level));
2362
2363         if (abil.ability == ABIL_BREATHE_STEAM
2364             || abil.ability == ABIL_SPIT_ACID)
2365         {
2366             you.duration[DUR_BREATH_WEAPON] /= 2;
2367         }
2368
2369         break;
2370
2371     case ABIL_EVOKE_BLINK:      // randarts
2372     case ABIL_BLINK:            // mutation
2373         return cast_blink(true, fail);
2374         break;
2375
2376     case ABIL_EVOKE_BERSERK:    // amulet of rage, randarts
2377         fail_check();
2378         you.go_berserk(true);
2379         break;
2380
2381     // Fly (tengu/drac) - permanent at high XL
2382     case ABIL_FLY:
2383         fail_check();
2384         if (you.racial_permanent_flight())
2385         {
2386             you.attribute[ATTR_PERM_FLIGHT] = 1;
2387             float_player();
2388             if (you.species == SP_TENGU)
2389                 mpr("You feel very comfortable in the air.");
2390         }
2391         else
2392             cast_fly(you.experience_level * 4);
2393         break;
2394
2395     // DEMONIC POWERS:
2396     case ABIL_HELLFIRE:
2397         fail_check();
2398         if (your_spells(SPELL_HELLFIRE,
2399                         you.experience_level * 10, false) == SPRET_ABORT)
2400         {
2401             return SPRET_ABORT;
2402         }
2403         break;
2404
2405     case ABIL_EVOKE_TURN_INVISIBLE:     // ring, cloaks, randarts
2406         fail_check();
2407         potionlike_effect(POT_INVISIBILITY, you.skill(SK_EVOCATIONS, 2) + 5);
2408         contaminate_player(1000 + random2(2000), true);
2409         break;
2410
2411     case ABIL_EVOKE_TURN_VISIBLE:
2412         fail_check();
2413         ASSERT(!you.attribute[ATTR_INVIS_UNCANCELLABLE]);
2414         mpr("You feel less transparent.");
2415         you.duration[DUR_INVIS] = 1;
2416         break;
2417
2418     case ABIL_EVOKE_FLIGHT:             // ring, boots, randarts
2419         fail_check();
2420         ASSERT(!get_form()->forbids_flight());
2421         if (you.wearing_ego(EQ_ALL_ARMOUR, SPARM_FLYING))
2422         {
2423             bool standing = !you.airborne();
2424             you.attribute[ATTR_PERM_FLIGHT] = 1;
2425             if (standing)
2426                 float_player();
2427             else
2428                 mpr("You feel more buoyant.");
2429         }
2430         else
2431             fly_player(you.skill(SK_EVOCATIONS, 2) + 30);
2432         break;
2433     case ABIL_EVOKE_FOG:     // cloak of the Thief
2434         fail_check();
2435         mpr("With a swish of your cloak, you release a cloud of fog.");
2436         big_cloud(random_smoke_type(), &you, you.pos(), 50, 8 + random2(8));
2437         break;
2438
2439     case ABIL_EVOKE_TELEPORT_CONTROL:
2440         fail_check();
2441         cast_teleport_control(30 + you.skill(SK_EVOCATIONS, 2), false);
2442         break;
2443
2444     case ABIL_EVOKE_TWISTER:
2445         fail_check();
2446         summon_twister(2);
2447         break;
2448
2449     case ABIL_STOP_SINGING:
2450         fail_check();
2451         you.duration[DUR_SONG_OF_SLAYING] = 0;
2452         mpr("You stop singing.");
2453         break;
2454
2455     case ABIL_STOP_FLYING:
2456         fail_check();
2457         you.duration[DUR_FLIGHT] = 0;
2458         you.attribute[ATTR_PERM_FLIGHT] = 0;
2459         land_player();
2460         break;
2461
2462     case ABIL_END_TRANSFORMATION:
2463         fail_check();
2464         you.time_taken = div_rand_round(you.time_taken * 3, 2);
2465         untransform();
2466         break;
2467
2468     // INVOCATIONS:
2469     case ABIL_ZIN_RECITE:
2470     {
2471         fail_check();
2472         if (zin_check_recite_to_monsters() == 1)
2473         {
2474             you.attribute[ATTR_RECITE_TYPE] = (recite_type) random2(NUM_RECITE_TYPES); // This is just flavor
2475             you.attribute[ATTR_RECITE_SEED] = random2(2187); // 3^7
2476             you.attribute[ATTR_RECITE_HP]   = you.hp;
2477             you.duration[DUR_RECITE] = 3 * BASELINE_DELAY;
2478             mprf("You clear your throat and prepare to recite.");
2479         }
2480         else
2481         {
2482             canned_msg(MSG_OK);
2483             return SPRET_ABORT;
2484         }
2485         break;
2486     }
2487     case ABIL_ZIN_VITALISATION:
2488         fail_check();
2489         zin_recite_interrupt();
2490         zin_vitalisation();
2491         break;
2492
2493     case ABIL_ZIN_IMPRISON:
2494     {
2495         beam.range = LOS_RADIUS;
2496         if (!spell_direction(spd, beam, DIR_TARGET, TARG_HOSTILE, 0, false))
2497             return SPRET_ABORT;
2498
2499         if (beam.target == you.pos())
2500         {
2501             mpr("You cannot imprison yourself!");
2502             return SPRET_ABORT;
2503         }
2504
2505         monster* mons = monster_at(beam.target);
2506
2507         if (mons == nullptr || !you.can_see(mons))
2508         {
2509             mpr("There is no monster there to imprison!");
2510             return SPRET_ABORT;
2511         }
2512
2513         if (mons_is_firewood(mons) || mons_is_conjured(mons->type))
2514         {
2515             mpr("You cannot imprison that!");
2516             return SPRET_ABORT;
2517         }
2518
2519         if (mons->friendly() || mons->good_neutral())
2520         {
2521             mpr("You cannot imprison a law-abiding creature!");
2522             return SPRET_ABORT;
2523         }
2524
2525         fail_check();
2526
2527         zin_recite_interrupt();
2528         power = 3 + (roll_dice(5, you.skill(SK_INVOCATIONS, 5) + 12) / 26);
2529
2530         if (!cast_imprison(power, mons, -GOD_ZIN))
2531             return SPRET_ABORT;
2532         break;
2533     }
2534
2535     case ABIL_ZIN_SANCTUARY:
2536         fail_check();
2537         zin_recite_interrupt();
2538         if (!zin_sanctuary())
2539             return SPRET_ABORT;
2540         break;
2541
2542     case ABIL_ZIN_CURE_ALL_MUTATIONS:
2543         fail_check();
2544         zin_recite_interrupt();
2545         zin_remove_all_mutations();
2546         break;
2547
2548     case ABIL_TSO_DIVINE_SHIELD:
2549         fail_check();
2550         tso_divine_shield();
2551         break;
2552
2553     case ABIL_TSO_CLEANSING_FLAME:
2554         fail_check();
2555         cleansing_flame(10 + you.skill_rdiv(SK_INVOCATIONS, 7, 6),
2556                         CLEANSING_FLAME_INVOCATION, you.pos(), &you);
2557         break;
2558
2559     case ABIL_TSO_SUMMON_DIVINE_WARRIOR:
2560         fail_check();
2561         summon_holy_warrior(you.skill(SK_INVOCATIONS, 4), false);
2562         break;
2563
2564     case ABIL_KIKU_RECEIVE_CORPSES:
2565         fail_check();
2566         kiku_receive_corpses(you.skill(SK_NECROMANCY, 4));
2567         break;
2568
2569     case ABIL_KIKU_TORMENT:
2570         fail_check();
2571         if (!kiku_take_corpse())
2572         {
2573             mpr("There are no corpses to sacrifice!");
2574             return SPRET_ABORT;
2575         }
2576         simple_god_message(" torments the living!");
2577         torment(&you, TORMENT_KIKUBAAQUDGHA, you.pos());
2578         break;
2579
2580     case ABIL_YRED_INJURY_MIRROR:
2581         fail_check();
2582         if (yred_injury_mirror())
2583             mpr("Another wave of unholy energy enters you.");
2584         else
2585         {
2586             mprf("You offer yourself to %s, and fill with unholy energy.",
2587                  god_name(you.religion).c_str());
2588         }
2589         you.duration[DUR_MIRROR_DAMAGE] = 9 * BASELINE_DELAY
2590                      + random2avg(you.piety * BASELINE_DELAY, 2) / 10;
2591         break;
2592
2593     case ABIL_YRED_ANIMATE_REMAINS:
2594     case ABIL_YRED_ANIMATE_DEAD:
2595         fail_check();
2596         if (!yred_animate_remains_or_dead())
2597             return SPRET_ABORT;
2598         break;
2599
2600     case ABIL_YRED_RECALL_UNDEAD_SLAVES:
2601         fail_check();
2602         start_recall(RECALL_YRED);
2603         break;
2604
2605     case ABIL_YRED_DRAIN_LIFE:
2606         fail_check();
2607         cast_los_attack_spell(SPELL_DRAIN_LIFE, you.skill_rdiv(SK_INVOCATIONS),
2608                               &you, true);
2609         break;
2610
2611     case ABIL_YRED_ENSLAVE_SOUL:
2612     {
2613         god_acting gdact;
2614         power = you.skill(SK_INVOCATIONS, 4);
2615         beam.range = LOS_RADIUS;
2616
2617         if (!spell_direction(spd, beam))
2618             return SPRET_ABORT;
2619
2620         if (beam.target == you.pos())
2621         {
2622             mpr("Your soul already belongs to Yredelemnul.");
2623             return SPRET_ABORT;
2624         }
2625
2626         monster* mons = monster_at(beam.target);
2627         if (mons == nullptr || !you.can_see(mons)
2628             || !ench_flavour_affects_monster(BEAM_ENSLAVE_SOUL, mons))
2629         {
2630             mpr("You see nothing there to enslave the soul of!");
2631             return SPRET_ABORT;
2632         }
2633
2634         // The monster can be no more than lightly wounded/damaged.
2635         if (mons_get_damage_level(mons) > MDAM_LIGHTLY_DAMAGED)
2636         {
2637             simple_monster_message(mons, "'s soul is too badly injured.");
2638             return SPRET_ABORT;
2639         }
2640         fail_check();
2641
2642         return zapping(ZAP_ENSLAVE_SOUL, power, beam, false, nullptr, fail);
2643     }
2644
2645     case ABIL_SIF_MUNA_CHANNEL_ENERGY:
2646         fail_check();
2647         mpr("You channel some magical energy.");
2648
2649         inc_mp(1 + random2(you.skill_rdiv(SK_INVOCATIONS, 1, 4) + 2));
2650         break;
2651
2652     case ABIL_OKAWARU_HEROISM:
2653         fail_check();
2654         mprf(MSGCH_DURATION, you.duration[DUR_HEROISM]
2655              ? "You feel more confident with your borrowed prowess."
2656              : "You gain the combat prowess of a mighty hero.");
2657
2658         you.increase_duration(DUR_HEROISM,
2659             35 + random2(you.skill(SK_INVOCATIONS, 8)), 80);
2660         you.redraw_evasion      = true;
2661         you.redraw_armour_class = true;
2662         break;
2663
2664     case ABIL_OKAWARU_FINESSE:
2665         fail_check();
2666         if (stasis_blocks_effect(true, "%s emits a piercing whistle.",
2667                                  20, "%s makes your neck tingle."))
2668         {
2669             // Identify the amulet and spend costs - finesse will be aborted
2670             // for free with an identified amulet.
2671             break;
2672         }
2673
2674         if (you.duration[DUR_FINESSE])
2675         {
2676             // "Your [hand(s)] get{s} new energy."
2677             mprf(MSGCH_DURATION, "%s",
2678                  you.hands_act("get", "new energy.").c_str());
2679         }
2680         else
2681             mprf(MSGCH_DURATION, "You can now deal lightning-fast blows.");
2682
2683         you.increase_duration(DUR_FINESSE,
2684             40 + random2(you.skill(SK_INVOCATIONS, 8)), 80);
2685
2686         did_god_conduct(DID_HASTY, 8); // Currently irrelevant.
2687         break;
2688
2689     case ABIL_MAKHLEB_MINOR_DESTRUCTION:
2690         beam.range = 8;
2691
2692         if (!spell_direction(spd, beam))
2693             return SPRET_ABORT;
2694
2695         power = you.skill(SK_INVOCATIONS, 1)
2696                 + random2(1 + you.skill(SK_INVOCATIONS, 1))
2697                 + random2(1 + you.skill(SK_INVOCATIONS, 1));
2698
2699         // Since the actual beam is random, check with BEAM_MMISSILE and the
2700         // highest range possible.
2701         if (!player_tracer(ZAP_DEBUGGING_RAY, power, beam, 8))
2702             return SPRET_ABORT;
2703
2704         fail_check();
2705
2706         switch (random2(5))
2707         {
2708         case 0: zapping(ZAP_THROW_FLAME, power, beam); break;
2709         case 1: zapping(ZAP_PAIN,  power, beam); break;
2710         case 2: zapping(ZAP_STONE_ARROW, power, beam); break;
2711         case 3: zapping(ZAP_SHOCK, power, beam); break;
2712         case 4: zapping(ZAP_BREATHE_ACID, power/2, beam); break;
2713         }
2714         break;
2715
2716     case ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB:
2717         fail_check();
2718         summon_demon_type(random_choose(MONS_HELLWING, MONS_NEQOXEC,
2719                           MONS_ORANGE_DEMON, MONS_SMOKE_DEMON, MONS_YNOXINUL),
2720                           20 + you.skill(SK_INVOCATIONS, 3), GOD_MAKHLEB);
2721         break;
2722
2723     case ABIL_MAKHLEB_MAJOR_DESTRUCTION:
2724         beam.range = 6;
2725
2726         if (!spell_direction(spd, beam))
2727             return SPRET_ABORT;
2728
2729         power = you.skill(SK_INVOCATIONS, 3)
2730                 + random2(1 + you.skill(SK_INVOCATIONS, 1))
2731                 + random2(1 + you.skill(SK_INVOCATIONS, 1));
2732
2733         // Since the actual beam is random, check with BEAM_MMISSILE and the
2734         // highest range possible.
2735         if (!player_tracer(ZAP_DEBUGGING_RAY, power, beam, 8))
2736             return SPRET_ABORT;
2737
2738         fail_check();
2739
2740         {
2741             zap_type ztype =
2742                 random_choose(ZAP_BOLT_OF_FIRE,
2743                               ZAP_FIREBALL,
2744                               ZAP_LIGHTNING_BOLT,
2745                               ZAP_STICKY_FLAME,
2746                               ZAP_IRON_SHOT,
2747                               ZAP_BOLT_OF_DRAINING,
2748                               ZAP_ORB_OF_ELECTRICITY);
2749             zapping(ztype, power, beam);
2750         }
2751         break;
2752
2753     case ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB:
2754         fail_check();
2755         summon_demon_type(random_choose(MONS_EXECUTIONER, MONS_GREEN_DEATH,
2756                           MONS_BLIZZARD_DEMON, MONS_BALRUG, MONS_CACODEMON),
2757                           20 + you.skill(SK_INVOCATIONS, 3), GOD_MAKHLEB);
2758         break;
2759
2760     case ABIL_TROG_BURN_SPELLBOOKS:
2761         fail_check();
2762         if (!trog_burn_spellbooks())
2763             return SPRET_ABORT;
2764         break;
2765
2766     case ABIL_TROG_BERSERK:
2767         fail_check();
2768         // Trog abilities don't use or train invocations.
2769         you.go_berserk(true);
2770         break;
2771
2772     case ABIL_TROG_REGEN_MR:
2773         fail_check();
2774         // Trog abilities don't use or train invocations.
2775         trog_do_trogs_hand(you.piety / 2);
2776         break;
2777
2778     case ABIL_TROG_BROTHERS_IN_ARMS:
2779         fail_check();
2780         // Trog abilities don't use or train invocations.
2781         summon_berserker(you.piety +
2782                          random2(you.piety/4) - random2(you.piety/4),
2783                          &you);
2784         break;
2785
2786     case ABIL_SIF_MUNA_FORGET_SPELL:
2787         fail_check();
2788         if (cast_selective_amnesia() <= 0)
2789             return SPRET_ABORT;
2790         break;
2791
2792     case ABIL_ELYVILON_LIFESAVING:
2793         fail_check();
2794         if (you.duration[DUR_LIFESAVING])
2795             mpr("You renew your call for help.");
2796         else
2797         {
2798             mprf("You beseech %s to protect your life.",
2799                  god_name(you.religion).c_str());
2800         }
2801         // Might be a decrease, this is intentional (like Yred).
2802         you.duration[DUR_LIFESAVING] = 9 * BASELINE_DELAY
2803                      + random2avg(you.piety * BASELINE_DELAY, 2) / 10;
2804         break;
2805
2806     case ABIL_ELYVILON_LESSER_HEALING_SELF:
2807     case ABIL_ELYVILON_LESSER_HEALING_OTHERS:
2808     {
2809         fail_check();
2810         const bool self = (abil.ability == ABIL_ELYVILON_LESSER_HEALING_SELF);
2811         int pow = 3 + (you.skill_rdiv(SK_INVOCATIONS, 1, 6));
2812 #if TAG_MAJOR_VERSION == 34
2813         if (self && you.species == SP_DJINNI)
2814             pow /= 2;
2815 #endif
2816         if (cast_healing(pow,
2817                          3 + (int) ceil(you.skill(SK_INVOCATIONS, 1) / 6.0),
2818                          true, self ? you.pos() : coord_def(0, 0), !self,
2819                          self ? TARG_NUM_MODES : TARG_INJURED_FRIEND)
2820                          == SPRET_ABORT)
2821         {
2822             return SPRET_ABORT;
2823         }
2824         break;
2825     }
2826
2827     case ABIL_ELYVILON_PURIFICATION:
2828         fail_check();
2829         elyvilon_purification();
2830         break;
2831
2832     case ABIL_ELYVILON_GREATER_HEALING_SELF:
2833     case ABIL_ELYVILON_GREATER_HEALING_OTHERS:
2834     {
2835         fail_check();
2836         const bool self = (abil.ability == ABIL_ELYVILON_GREATER_HEALING_SELF);
2837
2838         int pow = 10 + (you.skill_rdiv(SK_INVOCATIONS, 1, 3));
2839 #if TAG_MAJOR_VERSION == 34
2840         if (self && you.species == SP_DJINNI)
2841             pow /= 2;
2842 #endif
2843         if (cast_healing(pow,
2844                          10 + (int) ceil(you.skill(SK_INVOCATIONS, 1) / 3.0),
2845                          true, self ? you.pos() : coord_def(0, 0), !self,
2846                          self ? TARG_NUM_MODES : TARG_INJURED_FRIEND)
2847                          == SPRET_ABORT)
2848         {
2849             return SPRET_ABORT;
2850         }
2851         break;
2852     }
2853
2854     case ABIL_ELYVILON_DIVINE_VIGOUR:
2855         fail_check();
2856         if (!elyvilon_divine_vigour())
2857             return SPRET_ABORT;
2858         break;
2859
2860     case ABIL_LUGONU_ABYSS_EXIT:
2861         fail_check();
2862         down_stairs(DNGN_EXIT_ABYSS);
2863         break;
2864
2865     case ABIL_LUGONU_BEND_SPACE:
2866         fail_check();
2867         lugonu_bend_space();
2868         break;
2869
2870     case ABIL_LUGONU_BANISH:
2871     {
2872         beam.range = LOS_RADIUS;
2873         const int pow = 16 + you.skill(SK_INVOCATIONS, 8);
2874
2875         if (!spell_direction(spd, beam, DIR_NONE, TARG_HOSTILE, 0,
2876                              true, true, false, nullptr, nullptr, false, nullptr,
2877                              bind(desc_success_chance, placeholders::_1, pow)))
2878         {
2879             return SPRET_ABORT;
2880         }
2881
2882         if (beam.target == you.pos())
2883         {
2884             mpr("You cannot banish yourself!");
2885             return SPRET_ABORT;
2886         }
2887
2888         return zapping(ZAP_BANISHMENT, pow, beam, true, nullptr, fail);
2889     }
2890
2891     case ABIL_LUGONU_CORRUPT:
2892         fail_check();
2893         if (!lugonu_corrupt_level(300 + you.skill(SK_INVOCATIONS, 15)))
2894             return SPRET_ABORT;
2895         break;
2896
2897     case ABIL_LUGONU_ABYSS_ENTER:
2898     {
2899         fail_check();
2900         // Deflate HP.
2901         dec_hp(random2avg(you.hp, 2), false);
2902
2903         // Deflate MP.
2904         if (you.magic_points)
2905             dec_mp(random2avg(you.magic_points, 2));
2906
2907         bool note_status = notes_are_active();
2908         activate_notes(false);  // This banishment shouldn't be noted.
2909         banished();
2910         activate_notes(note_status);
2911         break;
2912     }
2913
2914     case ABIL_NEMELEX_TRIPLE_DRAW:
2915         fail_check();
2916         if (!deck_triple_draw())
2917             return SPRET_ABORT;
2918         break;
2919
2920     case ABIL_NEMELEX_DEAL_FOUR:
2921         fail_check();
2922         if (!deck_deal())
2923             return SPRET_ABORT;
2924         break;
2925
2926     case ABIL_NEMELEX_STACK_FIVE:
2927         fail_check();
2928         if (!deck_stack())
2929             return SPRET_ABORT;
2930         break;
2931
2932     case ABIL_BEOGH_SMITING:
2933         fail_check();
2934         if (your_spells(SPELL_SMITING, 12 + skill_bump(SK_INVOCATIONS, 6),
2935                         false) == SPRET_ABORT)
2936         {
2937             return SPRET_ABORT;
2938         }
2939         break;
2940
2941     case ABIL_BEOGH_GIFT_ITEM:
2942         if (!beogh_gift_item())
2943             return SPRET_ABORT;
2944         break;
2945
2946     case ABIL_BEOGH_RECALL_ORCISH_FOLLOWERS:
2947         fail_check();
2948         start_recall(RECALL_BEOGH);
2949         break;
2950
2951     case ABIL_STOP_RECALL:
2952         fail_check();
2953         mpr("You stop recalling your allies.");
2954         end_recall();
2955         break;
2956
2957     case ABIL_FEDHAS_SUNLIGHT:
2958         return fedhas_sunlight(fail);
2959
2960     case ABIL_FEDHAS_PLANT_RING:
2961         fail_check();
2962         if (!fedhas_plant_ring_from_fruit())
2963             return SPRET_ABORT;
2964         break;
2965
2966     case ABIL_FEDHAS_RAIN:
2967         fail_check();
2968         if (!fedhas_rain(you.pos()))
2969         {
2970             canned_msg(MSG_NOTHING_HAPPENS);
2971             return SPRET_ABORT;
2972         }
2973         break;
2974
2975     case ABIL_FEDHAS_SPAWN_SPORES:
2976         fail_check();
2977         ASSERT(fedhas_corpse_spores() > 0);
2978         break;
2979
2980     case ABIL_FEDHAS_EVOLUTION:
2981         fail_check();
2982         fedhas_evolve_flora();
2983         break;
2984
2985     case ABIL_TRAN_BAT:
2986         fail_check();
2987         if (!transform(100, TRAN_BAT))
2988         {
2989             crawl_state.zero_turns_taken();
2990             return SPRET_ABORT;
2991         }
2992         break;
2993
2994     case ABIL_JIYVA_CALL_JELLY:
2995     {
2996         fail_check();
2997         mgen_data mg(MONS_JELLY, BEH_STRICT_NEUTRAL, 0, 0, 0, you.pos(),
2998                      MHITNOT, 0, GOD_JIYVA);
2999
3000         mg.non_actor_summoner = "Jiyva";
3001
3002         if (!create_monster(mg))
3003             return SPRET_ABORT;
3004         break;
3005     }
3006
3007     case ABIL_JIYVA_JELLY_PARALYSE:
3008         fail_check();
3009         jiyva_paralyse_jellies();
3010         break;
3011
3012     case ABIL_JIYVA_SLIMIFY:
3013     {
3014         fail_check();
3015         const item_def* const weapon = you.weapon();
3016         const string msg = (weapon) ? weapon->name(DESC_YOUR)
3017                                     : ("your " + you.hand_name(true));
3018         mprf(MSGCH_DURATION, "A thick mucus forms on %s.", msg.c_str());
3019         you.increase_duration(DUR_SLIMIFY,
3020                               random2avg(you.piety / 4, 2) + 3, 100);
3021         break;
3022     }
3023
3024     case ABIL_JIYVA_CURE_BAD_MUTATION:
3025         fail_check();
3026         jiyva_remove_bad_mutation();
3027         break;
3028
3029     case ABIL_CHEIBRIADOS_TIME_STEP:
3030         fail_check();
3031         cheibriados_time_step(you.skill(SK_INVOCATIONS, 10) * you.piety / 100);
3032         break;
3033
3034     case ABIL_CHEIBRIADOS_TIME_BEND:
3035         fail_check();
3036         cheibriados_time_bend(16 + you.skill(SK_INVOCATIONS, 8));
3037         break;
3038
3039     case ABIL_CHEIBRIADOS_DISTORTION:
3040         fail_check();
3041         cheibriados_temporal_distortion();
3042         break;
3043
3044     case ABIL_CHEIBRIADOS_SLOUCH:
3045         fail_check();
3046         if (!cheibriados_slouch(0))
3047         {
3048             canned_msg(MSG_OK);
3049             return SPRET_ABORT;
3050         }
3051         break;
3052
3053     case ABIL_ASHENZARI_SCRYING:
3054         fail_check();
3055         if (you.duration[DUR_SCRYING])
3056             mpr("You extend your astral sight.");
3057         else
3058             mpr("You gain astral sight.");
3059         you.duration[DUR_SCRYING] = 100 + random2avg(you.piety * 2, 2);
3060         you.xray_vision = true;
3061         break;
3062
3063     case ABIL_ASHENZARI_TRANSFER_KNOWLEDGE:
3064         fail_check();
3065         if (!ashenzari_transfer_knowledge())
3066         {
3067             canned_msg(MSG_OK);
3068             return SPRET_ABORT;
3069         }
3070         break;
3071
3072     case ABIL_ASHENZARI_END_TRANSFER:
3073         fail_check();
3074         ashenzari_end_transfer();
3075         break;
3076
3077     case ABIL_DITHMENOS_SHADOW_STEP:
3078         fail_check();
3079         if (!dithmenos_shadow_step())
3080         {
3081             canned_msg(MSG_OK);
3082             return SPRET_ABORT;
3083         }
3084         break;
3085
3086     case ABIL_DITHMENOS_SHADOW_FORM:
3087         fail_check();
3088         if (!transform(you.skill(SK_INVOCATIONS, 2), TRAN_SHADOW))
3089         {
3090             crawl_state.zero_turns_taken();
3091             return SPRET_ABORT;
3092         }
3093         break;
3094
3095     case ABIL_GOZAG_POTION_PETITION:
3096         fail_check();
3097         run_uncancel(UNC_POTION_PETITION, 0);
3098         break;
3099
3100     case ABIL_GOZAG_CALL_MERCHANT:
3101         fail_check();
3102         run_uncancel(UNC_CALL_MERCHANT, 0);
3103         break;
3104
3105     case ABIL_GOZAG_BRIBE_BRANCH:
3106         fail_check();
3107         if (!gozag_bribe_branch())
3108             return SPRET_ABORT;
3109         break;
3110
3111     case ABIL_QAZLAL_UPHEAVAL:
3112         return qazlal_upheaval(coord_def(), false, fail);
3113
3114     case ABIL_QAZLAL_ELEMENTAL_FORCE:
3115         fail_check();
3116         qazlal_elemental_force();
3117         break;
3118
3119     case ABIL_QAZLAL_DISASTER_AREA:
3120         fail_check();
3121         if (!qazlal_disaster_area())
3122             return SPRET_ABORT;
3123         break;
3124
3125     case ABIL_RU_SACRIFICE_PURITY:
3126     case ABIL_RU_SACRIFICE_WORDS:
3127     case ABIL_RU_SACRIFICE_DRINK:
3128     case ABIL_RU_SACRIFICE_ESSENCE:
3129     case ABIL_RU_SACRIFICE_HEALTH:
3130     case ABIL_RU_SACRIFICE_STEALTH:
3131     case ABIL_RU_SACRIFICE_ARTIFICE:
3132     case ABIL_RU_SACRIFICE_LOVE:
3133     case ABIL_RU_SACRIFICE_COURAGE:
3134     case ABIL_RU_SACRIFICE_ARCANA:
3135     case ABIL_RU_SACRIFICE_NIMBLENESS:
3136     case ABIL_RU_SACRIFICE_DURABILITY:
3137     case ABIL_RU_SACRIFICE_HAND:
3138     case ABIL_RU_SACRIFICE_EXPERIENCE:
3139     case ABIL_RU_SACRIFICE_SKILL:
3140         fail_check();
3141         if (!ru_do_sacrifice(abil.ability))
3142             return SPRET_ABORT;
3143         break;
3144
3145     case ABIL_RU_REJECT_SACRIFICES:
3146         fail_check();
3147         if (!ru_reject_sacrifices())
3148             return SPRET_ABORT;
3149         break;
3150
3151     case ABIL_RU_DRAW_OUT_POWER:
3152         fail_check();
3153         if (you.duration[DUR_EXHAUSTED])
3154         {
3155             mpr("You're too exhausted to draw out your power.");
3156             return SPRET_ABORT;
3157         }
3158         if (you.hp == you.hp_max && you.magic_points == you.max_magic_points
3159             && !you.duration[DUR_CONF]
3160             && !you.duration[DUR_SLOW]
3161             && !you.attribute[ATTR_HELD]
3162             && !you.petrifying()
3163             && !you.is_constricted())
3164         {
3165             mpr("You have no need to draw out power.");
3166             return SPRET_ABORT;
3167         }
3168         ru_draw_out_power();
3169         you.increase_duration(DUR_EXHAUSTED, 12 + random2(5));
3170         break;
3171
3172     case ABIL_RU_POWER_LEAP:
3173         fail_check();
3174         if (you.duration[DUR_EXHAUSTED])
3175         {
3176             mpr("You're too exhausted to power leap.");
3177             return SPRET_ABORT;
3178         }
3179         if (!ru_power_leap())
3180         {
3181             canned_msg(MSG_OK);
3182             return SPRET_ABORT;
3183         }
3184         you.increase_duration(DUR_EXHAUSTED, 18 + random2(8));
3185         break;
3186
3187     case ABIL_RU_APOCALYPSE:
3188         fail_check();
3189         if (you.duration[DUR_EXHAUSTED])
3190         {
3191             mpr("You're too exhausted to unleash your apocalyptic power.");
3192             return SPRET_ABORT;
3193         }
3194         if (!ru_apocalypse())
3195             return SPRET_ABORT;
3196         you.increase_duration(DUR_EXHAUSTED, 30 + random2(20));
3197         break;
3198
3199     case ABIL_RENOUNCE_RELIGION:
3200         fail_check();
3201         if (yesno("Really renounce your faith, foregoing its fabulous benefits?",
3202                   false, 'n')
3203             && yesno("Are you sure you won't change your mind later?",
3204                      false, 'n'))
3205         {
3206             excommunication();
3207         }
3208         else
3209         {
3210             canned_msg(MSG_OK);
3211             return SPRET_ABORT;
3212         }
3213         break;
3214
3215     case ABIL_CONVERT_TO_BEOGH:
3216         fail_check();
3217         god_pitch(GOD_BEOGH);
3218         if (you_worship(GOD_BEOGH))
3219         {
3220             spare_beogh_convert();
3221             break;
3222         }
3223         return SPRET_ABORT;
3224
3225     case ABIL_NON_ABILITY:
3226         fail_check();
3227         mpr("Sorry, you can't do that.");
3228         break;
3229
3230     default:
3231         die("invalid ability");
3232     }
3233
3234     return SPRET_SUCCESS;
3235 }
3236
3237 // [ds] Increase piety cost for god abilities that are particularly
3238 // overpowered in Sprint. Yes, this is a hack. No, I don't care.
3239 static int _scale_piety_cost(ability_type abil, int original_cost)
3240 {
3241     // Abilities that have aroused our ire earn 2.5x their classic
3242     // Crawl piety cost.
3243     return (crawl_state.game_is_sprint()
3244             && (abil == ABIL_TROG_BROTHERS_IN_ARMS
3245                 || abil == ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB))
3246            ? div_rand_round(original_cost * 5, 2)
3247            : original_cost;
3248 }
3249
3250 // We pass in ability ZP cost as it may have changed during the exercise
3251 // of the ability (if the cost is scaled, for example)
3252 static void _pay_ability_costs(const ability_def& abil, int zpcost)
3253 {
3254     if (abil.flags & ABFLAG_INSTANT)
3255     {
3256         you.turn_is_over = false;
3257         you.elapsed_time_at_last_input = you.elapsed_time;
3258         update_turn_count();
3259     }
3260     else
3261         you.turn_is_over = true;
3262
3263     const int food_cost  = abil.food_cost + random2avg(abil.food_cost, 2);
3264     const int piety_cost =
3265         _scale_piety_cost(abil.ability, abil.piety_cost.cost());
3266     const int hp_cost    = abil.hp_cost.cost(you.hp_max);
3267
3268     dprf("Cost: mp=%d; hp=%d; food=%d; piety=%d",
3269          abil.mp_cost, hp_cost, food_cost, piety_cost);
3270
3271     if (abil.mp_cost)
3272     {
3273         dec_mp(abil.mp_cost);
3274         if (abil.flags & ABFLAG_PERMANENT_MP)
3275             rot_mp(1);
3276     }
3277
3278     if (abil.hp_cost)
3279     {
3280         dec_hp(hp_cost, false);
3281         if (abil.flags & ABFLAG_PERMANENT_HP)
3282             rot_hp(hp_cost);
3283     }
3284
3285     if (zpcost)
3286     {
3287         you.zot_points -= zpcost;
3288         you.redraw_experience = true;
3289     }
3290
3291     if (abil.flags & ABFLAG_NECRO_MISCAST_MINOR)
3292     {
3293         MiscastEffect(&you, nullptr, ABIL_MISCAST, SPTYP_NECROMANCY, 5, 90,
3294                       "power out of control");
3295     }
3296     if (abil.flags & ABFLAG_LEVEL_DRAIN)
3297         adjust_level(-1);
3298
3299     if (food_cost)
3300         make_hungry(food_cost, false, true);
3301
3302     if (piety_cost)
3303         lose_piety(piety_cost);
3304 }
3305
3306 int choose_ability_menu(const vector<talent>& talents)
3307 {
3308 #ifdef USE_TILE_LOCAL
3309     const bool text_only = false;
3310 #else
3311     const bool text_only = true;
3312 #endif
3313
3314     ToggleableMenu abil_menu(MF_SINGLESELECT | MF_ANYPRINTABLE
3315                              | MF_TOGGLE_ACTION | MF_ALWAYS_SHOW_MORE,
3316                              text_only);
3317
3318     abil_menu.set_highlighter(nullptr);
3319 #ifdef USE_TILE_LOCAL
3320     {
3321         // Hack like the one in spl-cast.cc:list_spells() to align the title.
3322         ToggleableMenuEntry* me =
3323             new ToggleableMenuEntry("  Ability - do what?                 "
3324                                     "Cost                          Failure",
3325                                     "  Ability - describe what?           "
3326                                     "Cost                          Failure",
3327                                     MEL_ITEM);
3328         me->colour = BLUE;
3329         abil_menu.add_entry(me);
3330     }
3331 #else
3332     abil_menu.set_title(
3333         new ToggleableMenuEntry("  Ability - do what?                 "
3334                                 "Cost                          Failure",
3335                                 "  Ability - describe what?           "
3336                                 "Cost                          Failure",
3337                                 MEL_TITLE));
3338 #endif
3339     abil_menu.set_tag("ability");
3340     abil_menu.add_toggle_key('!');
3341     abil_menu.add_toggle_key('?');
3342     abil_menu.menu_action = Menu::ACT_EXECUTE;
3343
3344     if (crawl_state.game_is_hints())
3345     {
3346         // XXX: This could be buggy if you manage to pick up lots and
3347         // lots of abilities during hints mode.
3348         abil_menu.set_more(hints_abilities_info());
3349     }
3350     else
3351     {
3352         abil_menu.set_more(formatted_string::parse_string(
3353                            "Press '<w>!</w>' or '<w>?</w>' to toggle "
3354                            "between ability selection and description."));
3355     }
3356
3357     int numbers[52];
3358     for (int i = 0; i < 52; ++i)
3359         numbers[i] = i;
3360
3361     bool found_invocations = false;
3362     bool found_zotdef = false;
3363
3364     // First add all non-invocation, non-zotdef abilities.
3365     for (unsigned int i = 0; i < talents.size(); ++i)
3366     {
3367         if (talents[i].is_invocation)
3368             found_invocations = true;
3369         else if (talents[i].is_zotdef)
3370             found_zotdef = true;
3371         else
3372         {
3373             ToggleableMenuEntry* me =
3374                 new ToggleableMenuEntry(describe_talent(talents[i]),
3375                                         describe_talent(talents[i]),
3376                                         MEL_ITEM, 1, talents[i].hotkey);
3377             me->data = &numbers[i];
3378 #ifdef USE_TILE
3379             me->add_tile(tile_def(tileidx_ability(talents[i].which), TEX_GUI));
3380 #endif
3381             // Only check this here, since your god can't hate its own abilities
3382             if (god_hates_ability(talents[i].which, you.religion))
3383                 me->colour = COL_FORBIDDEN;
3384             abil_menu.add_entry(me);
3385         }
3386     }
3387
3388     if (found_zotdef)
3389     {
3390 #ifdef USE_TILE_LOCAL
3391         ToggleableMenuEntry* subtitle =
3392             new ToggleableMenuEntry("    Zot Defence -",
3393                                     "    Zot Defence -", MEL_ITEM);
3394         subtitle->colour = BLUE;
3395         abil_menu.add_entry(subtitle);
3396 #else
3397         abil_menu.add_entry(
3398             new ToggleableMenuEntry("    Zot Defence - ",
3399                                     "    Zot Defence - ", MEL_SUBTITLE));
3400 #endif
3401         for (unsigned int i = 0; i < talents.size(); ++i)
3402         {
3403             if (talents[i].is_zotdef)
3404             {
3405                 ToggleableMenuEntry* me =
3406                     new ToggleableMenuEntry(describe_talent(talents[i]),
3407                                             describe_talent(talents[i]),
3408                                             MEL_ITEM, 1, talents[i].hotkey);
3409                 me->data = &numbers[i];
3410 #ifdef USE_TILE
3411                 me->add_tile(tile_def(tileidx_ability(talents[i].which),
3412                                       TEX_GUI));
3413 #endif
3414                 abil_menu.add_entry(me);
3415             }
3416         }
3417     }
3418
3419     if (found_invocations)
3420     {
3421 #ifdef USE_TILE_LOCAL
3422         ToggleableMenuEntry* subtitle =
3423             new ToggleableMenuEntry("    Invocations - ",
3424                                     "    Invocations - ", MEL_ITEM);
3425         subtitle->colour = BLUE;
3426         abil_menu.add_entry(subtitle);
3427 #else
3428         abil_menu.add_entry(
3429             new ToggleableMenuEntry("    Invocations - ",
3430                                     "    Invocations - ", MEL_SUBTITLE));
3431 #endif
3432         for (unsigned int i = 0; i < talents.size(); ++i)
3433         {
3434             if (talents[i].is_invocation)
3435             {
3436                 ToggleableMenuEntry* me =
3437                     new ToggleableMenuEntry(describe_talent(talents[i]),
3438                                             describe_talent(talents[i]),
3439                                             MEL_ITEM, 1, talents[i].hotkey);
3440                 me->data = &numbers[i];
3441 #ifdef USE_TILE
3442                 me->add_tile(tile_def(tileidx_ability(talents[i].which),
3443                                       TEX_GUI));
3444 #endif
3445                 abil_menu.add_entry(me);
3446             }
3447         }
3448     }
3449
3450     while (true)
3451     {
3452         vector<MenuEntry*> sel = abil_menu.show(false);
3453         if (!crawl_state.doing_prev_cmd_again)
3454             redraw_screen();
3455         if (sel.empty())
3456             return -1;
3457
3458         ASSERT(sel.size() == 1);
3459         ASSERT(sel[0]->hotkeys.size() == 1);
3460         int selected = *(static_cast<int*>(sel[0]->data));
3461
3462         if (abil_menu.menu_action == Menu::ACT_EXAMINE)
3463             _print_talent_description(talents[selected]);
3464         else
3465             return *(static_cast<int*>(sel[0]->data));
3466     }
3467 }
3468
3469 string describe_talent(const talent& tal)
3470 {
3471     ASSERT(tal.which != ABIL_NON_ABILITY);
3472
3473     const string failure = failure_rate_to_string(tal.fail);
3474
3475     ostringstream desc;
3476     desc << left
3477          << chop_string(ability_name(tal.which), 32)
3478          << chop_string(make_cost_description(tal.which), 30)
3479          << chop_string(failure, 7);
3480     return desc.str();
3481 }
3482
3483 static void _add_talent(vector<talent>& vec, const ability_type ability,
3484                         bool check_confused)
3485 {
3486     const talent t = get_talent(ability, check_confused);
3487     if (t.which != ABIL_NON_ABILITY)
3488         vec.push_back(t);
3489 }
3490
3491 /**
3492  * Return all relevant talents that the player has.
3493  *
3494  * Currently the only abilities that are affected by include_unusable are god
3495  * abilities (affect by e.g. penance or silence).
3496  * @param check_confused If true, abilities that don't work when confused will
3497  *                       be excluded.
3498  * @param include_unusable If true, abilities that are currently unusable will
3499  *                         be excluded.
3500  * @return  A vector of talent structs.
3501  */
3502 vector<talent> your_talents(bool check_confused, bool include_unusable)
3503 {
3504     vector<talent> talents;
3505
3506     // zot defence abilities; must also be updated in player.cc when these levels are changed
3507     if (crawl_state.game_is_zotdef())
3508     {
3509         if (you.experience_level >= 2)
3510             _add_talent(talents, ABIL_MAKE_OKLOB_SAPLING, check_confused);
3511         if (you.experience_level >= 3)
3512             _add_talent(talents, ABIL_MAKE_ARROW_TRAP, check_confused);
3513         if (you.experience_level >= 4)
3514             _add_talent(talents, ABIL_MAKE_PLANT, check_confused);
3515         if (you.experience_level >= 4)
3516             _add_talent(talents, ABIL_REMOVE_CURSE, check_confused);
3517         if (you.experience_level >= 5)
3518             _add_talent(talents, ABIL_MAKE_BURNING_BUSH, check_confused);
3519         if (you.experience_level >= 6)
3520             _add_talent(talents, ABIL_MAKE_ALTAR, check_confused);
3521         if (you.experience_level >= 6)
3522             _add_talent(talents, ABIL_MAKE_GRENADES, check_confused);
3523         if (you.experience_level >= 7)
3524             _add_talent(talents, ABIL_MAKE_OKLOB_PLANT, check_confused);
3525         if (you.experience_level >= 8)