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