1 /*
2  *  File:       abl-show.cc
3  *  Summary:    Functions related to special abilities.
4  *  Written by: Linley Henzell
5  *
6  *  Change History (most recent first):
7  *
8  *  <6>    19mar2000     jmf    added elvish Glamour
9  *  <5>     11/06/99     cdl    reduced power of minor destruction
10  *
11  *  <4>      9/25/99     cdl    linuxlib -> liblinux
12  *
13  *  <3>      5/20/99     BWR    Now use scan_randarts to
14  *                              check for flags, rather than
15  *                              only checking the weapon.
16  *
17  *  <2>      5/20/99     BWR    Extended screen line support
18  *
19  *  <1>      -/--/--     LRH             Created
20  */
21 
22 #include "AppHdr.h"
23 #include "abl-show.h"
24 
25 #include <string.h>
26 #include <stdio.h>
27 #include <ctype.h>
28 
29 #ifdef DOS
30 #include <conio.h>
31 #endif
32 
33 #include "externs.h"
34 
35 #include "beam.h"
36 #include "effects.h"
37 #include "food.h"
38 #include "it_use2.h"
39 #include "macro.h"
40 #include "message.h"
41 #include "misc.h"
42 #include "monplace.h"
43 #include "player.h"
44 #include "religion.h"
45 #include "skills.h"
46 #include "skills2.h"
47 #include "spl-cast.h"
48 #include "spl-util.h"
49 #include "spells1.h"
50 #include "spells2.h"
51 #include "spells3.h"
52 #include "spells4.h"
53 #include "stuff.h"
54 #include "transfor.h"
55 #include "view.h"
56 
57 
58 #ifdef LINUX
59 #include "liblinux.h"
60 #endif
61 
62 // this all needs to be split into data/util/show files
63 // and the struct mechanism here needs to be rewritten (again)
64 // along with the display routine to piece the strings
65 // together dynamically ... I'm getting to it now {dlb}
66 
67 // it makes more sense to think of them as an array
68 // of structs than two arrays that share common index
69 // values -- well, doesn't it? {dlb}
70 struct talent
71 {
72     int which;
73     int fail;
74     bool is_invocation;
75 };
76 
77 static FixedVector< talent, 52 >  Curr_abil;
78 
79 static bool insert_ability( int which_ability );
80 
81 // The description screen was way out of date with the actual costs.
82 // This table puts all the information in one place... -- bwr
83 //
84 // The four numerical fields are: MP, HP, food, and piety.
85 // Note:  food_cost  = val + random2avg( val, 2 )
86 //        piety_cost = val + random2( (val + 1) / 2 + 1 );
87 static const struct ability_def Ability_List[] =
88 {
89     // NON_ABILITY should always come first
90     { ABIL_NON_ABILITY, "No ability", 0, 0, 0, 0, ABFLAG_NONE },
91     { ABIL_SPIT_POISON, "Spit Poison", 0, 0, 40, 0, ABFLAG_BREATH },
92     { ABIL_GLAMOUR, "Glamour", 5, 0, 40, 0, ABFLAG_DELAY },
93 
94     { ABIL_MAPPING, "Sense Surroundings", 0, 0, 30, 0, ABFLAG_NONE },
95     { ABIL_TELEPORTATION, "Teleportation", 3, 0, 200, 0, ABFLAG_NONE },
96     { ABIL_BLINK, "Blink", 1, 0, 50, 0, ABFLAG_NONE },
97 
98     { ABIL_BREATHE_FIRE, "Breathe Fire", 0, 0, 125, 0, ABFLAG_BREATH },
99     { ABIL_BREATHE_FROST, "Breathe Frost", 0, 0, 125, 0, ABFLAG_BREATH },
100     { ABIL_BREATHE_POISON, "Breathe Poison Gas", 0, 0, 125, 0, ABFLAG_BREATH },
101     { ABIL_BREATHE_LIGHTNING, "Breathe Lightning", 0, 0, 125, 0, ABFLAG_BREATH },
102     { ABIL_BREATHE_POWER, "Breathe Power", 0, 0, 125, 0, ABFLAG_BREATH },
103     { ABIL_BREATHE_STICKY_FLAME, "Breathe Sticky Flame", 0, 0, 125, 0, ABFLAG_BREATH },
104     { ABIL_BREATHE_STEAM, "Breathe Steam", 0, 0, 75, 0, ABFLAG_BREATH },
105 
106     // Handled with breath weapons, but doesn't cause a breathing delay
107     { ABIL_SPIT_ACID, "Spit Acid", 0, 0, 125, 0, ABFLAG_NONE },
108 
109     { ABIL_FLY, "Fly", 3, 0, 100, 0, ABFLAG_NONE },
110     { ABIL_SUMMON_MINOR_DEMON, "Summon Minor Demon", 3, 3, 75, 0, ABFLAG_NONE },
111     { ABIL_SUMMON_DEMON, "Summon Demon", 5, 5, 150, 0, ABFLAG_NONE },
112     { ABIL_HELLFIRE, "Hellfire", 8, 8, 200, 0, ABFLAG_NONE },
113     { ABIL_TORMENT, "Torment", 9, 0, 250, 0, ABFLAG_PAIN },
114     { ABIL_RAISE_DEAD, "Raise Dead", 5, 5, 150, 0, ABFLAG_NONE },
115     { ABIL_CONTROL_DEMON, "Control Demon", 4, 4, 100, 0, ABFLAG_NONE },
116     { ABIL_TO_PANDEMONIUM, "Gate Yourself to Pandemonium", 7, 0, 200, 0, ABFLAG_NONE },
117     { ABIL_CHANNELING, "Channeling", 1, 0, 30, 0, ABFLAG_NONE },
118     { ABIL_THROW_FLAME, "Throw Flame", 1, 1, 50, 0, ABFLAG_NONE },
119     { ABIL_THROW_FROST, "Throw Frost", 1, 1, 50, 0, ABFLAG_NONE },
120     { ABIL_BOLT_OF_DRAINING, "Bolt of Draining", 4, 4, 100, 0, ABFLAG_NONE },
121 
122     // FLY_II used to have ABFLAG_EXHAUSTION, but that's somewhat meaningless
123     // as exhaustion's only (and designed) effect is preventing Berserk. -- bwr
124     { ABIL_FLY_II, "Fly", 0, 0, 25, 0, ABFLAG_NONE },
125     { ABIL_DELAYED_FIREBALL, "Release Delayed Fireball", 0, 0, 0, 0, ABFLAG_INSTANT },
126     { ABIL_MUMMY_RESTORATION, "Restoration", 1, 0, 0, 0, ABFLAG_PERMANENT_MP },
127 
128     // EVOKE abilities use Evocations and come from items:
129     // Mapping, Teleportation, and Blink can also come from mutations
130     // so we have to distinguish them (see above).  The off items
131     // below are labeled EVOKE because they only work now if the
132     // player has an item with the evocable power (not just because
133     // you used a wand, potion, or miscast effect).  I didn't see
134     // any reason to label them as "Evoke" in the text, they don't
135     // use or train Evocations (the others do).  -- bwr
136     { ABIL_EVOKE_MAPPING, "Evoke Sense Surroundings", 0, 0, 30, 0, ABFLAG_NONE },
137     { ABIL_EVOKE_TELEPORTATION, "Evoke Teleportation", 3, 0, 200, 0, ABFLAG_NONE },
138     { ABIL_EVOKE_BLINK, "Evoke Blink", 1, 0, 50, 0, ABFLAG_NONE },
139 
140     { ABIL_EVOKE_BERSERK, "Evoke Berserk Rage", 0, 0, 0, 0, ABFLAG_NONE },
141 
142     { ABIL_EVOKE_TURN_INVISIBLE, "Evoke Invisibility", 2, 0, 250, 0, ABFLAG_NONE },
143     { ABIL_EVOKE_TURN_VISIBLE, "Turn Visible", 0, 0, 0, 0, ABFLAG_NONE },
144     { ABIL_EVOKE_LEVITATE, "Evoke Levitation", 1, 0, 100, 0, ABFLAG_NONE },
145     { ABIL_EVOKE_STOP_LEVITATING, "Stop Levitating", 0, 0, 0, 0, ABFLAG_NONE },
146 
147     { ABIL_END_TRANSFORMATION, "End Transformation", 0, 0, 0, 0, ABFLAG_NONE },
148 
149     // INVOCATIONS:
150     // Zin
151     { ABIL_ZIN_REPEL_UNDEAD, "Repel Undead", 1, 0, 100, 0, ABFLAG_NONE },
152     { ABIL_ZIN_HEALING, "Minor Healing", 2, 0, 50, 1, ABFLAG_NONE },
153     { ABIL_ZIN_PESTILENCE, "Pestilence", 3, 0, 100, 2, ABFLAG_NONE },
154     { ABIL_ZIN_HOLY_WORD, "Holy Word", 6, 0, 150, 3, ABFLAG_NONE },
155     { ABIL_ZIN_SUMMON_GUARDIAN, "Summon Guardian", 7, 0, 150, 4, ABFLAG_NONE },
156 
157     // The Shining One
158     { ABIL_TSO_REPEL_UNDEAD, "Repel Undead", 1, 0, 100, 0, ABFLAG_NONE },
159     { ABIL_TSO_SMITING, "Smiting", 3, 0, 50, 2, ABFLAG_NONE },
160     { ABIL_TSO_ANNIHILATE_UNDEAD, "Annihilate Undead", 3, 0, 50, 2, ABFLAG_NONE },
161     { ABIL_TSO_THUNDERBOLT, "Thunderbolt", 5, 0, 100, 2, ABFLAG_NONE },
162     { ABIL_TSO_SUMMON_DAEVA, "Summon Daeva", 8, 0, 150, 4, ABFLAG_NONE },
163 
164     // Kikubaaqudgha
165     { ABIL_KIKU_RECALL_UNDEAD_SLAVES, "Recall Undead Slaves", 2, 0, 50, 0, ABFLAG_NONE },
166     { ABIL_KIKU_ENSLAVE_UNDEAD, "Enslave Undead", 4, 0, 150, 3, ABFLAG_NONE },
167     { ABIL_KIKU_INVOKE_DEATH, "Invoke Death", 4, 0, 250, 3, ABFLAG_NONE },
168 
169     // Yredelemnul
170     { ABIL_YRED_ANIMATE_CORPSE, "Animate Corpse", 1, 0, 50, 0, ABFLAG_NONE },
171     { ABIL_YRED_RECALL_UNDEAD, "Recall Undead Slaves", 2, 0, 50, 0, ABFLAG_NONE },
172     { ABIL_YRED_ANIMATE_DEAD, "Animate Dead", 3, 0, 100, 1, ABFLAG_NONE },
173     { ABIL_YRED_DRAIN_LIFE, "Drain Life", 6, 0, 200, 2, ABFLAG_NONE },
174     { ABIL_YRED_CONTROL_UNDEAD, "Control Undead", 5, 0, 150, 2, ABFLAG_NONE },
175 
176     // Vehumet
177     { ABIL_VEHUMET_CHANNEL_ENERGY, "Channel Energy", 0, 0, 50, 0, ABFLAG_NONE },
178 
179     // Okawaru
180     { ABIL_OKAWARU_MIGHT, "Might", 2, 0, 50, 1, ABFLAG_NONE },
181     { ABIL_OKAWARU_HEALING, "Healing", 2, 0, 75, 1, ABFLAG_NONE },
182     { ABIL_OKAWARU_HASTE, "Haste", 5, 0, 100, 3, ABFLAG_NONE },
183 
184     // Makhleb
185     { ABIL_MAKHLEB_MINOR_DESTRUCTION, "Minor Destruction", 1, 0, 20, 0, ABFLAG_NONE },
186     { ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB, "Lesser Servant of Makhleb", 2, 0, 50, 1, ABFLAG_NONE },
187     { ABIL_MAKHLEB_MAJOR_DESTRUCTION, "Major Destruction", 4, 0, 100, 2, ABFLAG_NONE },
188     { ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB, "Greater Servant of Makhleb", 6, 0, 100, 3, ABFLAG_NONE },
189 
190     // Sif Muna
191     { ABIL_SIF_MUNA_FORGET_SPELL, "Forget Spell", 5, 0, 0, 8, ABFLAG_NONE },
192 
193     // Trog
194     { ABIL_TROG_BERSERK, "Berserk", 0, 0, 200, 0, ABFLAG_NONE },
195     { ABIL_TROG_MIGHT, "Might", 0, 0, 200, 1, ABFLAG_NONE },
196     { ABIL_TROG_HASTE_SELF, "Haste Self", 0, 0, 250, 3, ABFLAG_NONE },
197 
198     // Elyvilon
199     { ABIL_ELYVILON_LESSER_HEALING, "Lesser Healing", 1, 0, 100, 0, ABFLAG_NONE },
200     { ABIL_ELYVILON_PURIFICATION, "Purification", 2, 0, 150, 1, ABFLAG_NONE },
201     { ABIL_ELYVILON_HEALING, "Healing", 2, 0, 250, 2, ABFLAG_NONE },
202     { ABIL_ELYVILON_RESTORATION, "Restoration", 3, 0, 400, 3, ABFLAG_NONE },
203     { ABIL_ELYVILON_GREATER_HEALING, "Greater Healing", 6, 0, 600, 4, ABFLAG_NONE },
204 
205     // These six are unused "evil" god abilities:
206     { ABIL_CHARM_SNAKE, "Charm Snake", 6, 0, 200, 5, ABFLAG_NONE },
207     { ABIL_TRAN_SERPENT_OF_HELL, "Turn into Demonic Serpent", 16, 0, 600, 8, ABFLAG_NONE },
208     { ABIL_BREATHE_HELLFIRE, "Breathe Hellfire", 0, 8, 200, 0, ABFLAG_BREATH },
209 
210     { ABIL_ROTTING, "Rotting", 4, 4, 0, 2, ABFLAG_NONE },
211     { ABIL_TORMENT_II, "Call Torment", 9, 0, 0, 3, ABFLAG_PAIN },
212     { ABIL_SHUGGOTH_SEED, "Sow Shuggoth Seed", 12, 8, 0, 6, ABFLAG_NONE },
213 
214     { ABIL_RENOUNCE_RELIGION, "Renounce Religion", 0, 0, 0, 0, ABFLAG_NONE },
215 };
216 
217 
get_ability_def(int abil)218 const struct ability_def & get_ability_def( int abil )
219 /****************************************************/
220 {
221     for (unsigned int i = 0; i < sizeof( Ability_List ); i++)
222     {
223         if (Ability_List[i].ability == abil)
224             return (Ability_List[i]);
225     }
226 
227     return (Ability_List[0]);
228 }
229 
230 
get_ability_name_by_index(char index)231 const char * get_ability_name_by_index( char index )
232 /**************************************************/
233 {
234     const struct ability_def &abil = get_ability_def( Curr_abil[index].which );
235 
236     return (abil.name);
237 }
238 
239 
make_cost_description(const struct ability_def & abil)240 const std::string make_cost_description( const struct ability_def &abil )
241 /***********************************************************************/
242 {
243     char         tmp_buff[80];  // avoiding string steams for portability
244     std::string  ret = "";
245 
246     if (abil.mp_cost)
247     {
248         snprintf( tmp_buff, sizeof(tmp_buff), "%d%s MP",
249                   abil.mp_cost,
250                   (abil.flags & ABFLAG_PERMANENT_MP) ? " Permanent" : "" );
251 
252         ret += tmp_buff;
253     }
254 
255     if (abil.hp_cost)
256     {
257         if (ret.length())
258             ret += ", ";
259 
260         snprintf( tmp_buff, sizeof(tmp_buff), "%d%s HP",
261                   abil.hp_cost,
262                   (abil.flags & ABFLAG_PERMANENT_HP) ? " Permanent" : "" );
263 
264         ret += tmp_buff;
265     }
266 
267     if (abil.food_cost)
268     {
269         if (ret.length())
270             ret += ", ";
271 
272         ret += "Food";   // randomized and amount hidden from player
273     }
274 
275     if (abil.piety_cost)
276     {
277         if (ret.length())
278             ret += ", ";
279 
280         ret += "Piety";  // randomized and amount hidden from player
281     }
282 
283     if (abil.flags & ABFLAG_BREATH)
284     {
285         if (ret.length())
286             ret += ", ";
287 
288         ret += "Breath";
289     }
290 
291     if (abil.flags & ABFLAG_DELAY)
292     {
293         if (ret.length())
294             ret += ", ";
295 
296         ret += "Delay";
297     }
298 
299     if (abil.flags & ABFLAG_PAIN)
300     {
301         if (ret.length())
302             ret += ", ";
303 
304         ret += "Pain";
305     }
306 
307     if (abil.flags & ABFLAG_EXHAUSTION)
308     {
309         if (ret.length())
310             ret += ", ";
311 
312         ret += "Exhaustion";
313     }
314 
315     if (abil.flags & ABFLAG_INSTANT)
316     {
317         if (ret.length())
318             ret += ", ";
319 
320         ret += "Instant"; // not really a cost, more of a bonus -bwr
321     }
322 
323     // If we haven't output anything so far, then the effect has no cost
324     if (!ret.length())
325         ret += "None";
326 
327     return (ret);
328 }
329 
330 
331 /*
332    Activates a menu which gives player access to all of their non-spell
333    special abilities - Eg naga's spit poison, or the Invocations you get
334    from worshipping. Generated dynamically - the function checks to see which
335    abilities you have every time.
336  */
activate_ability(void)337 bool activate_ability(void)
338 /*************************/
339 {
340     unsigned char keyin = 0;
341     unsigned char spc, spc2;
342 
343     int power;
344     struct dist abild;
345     struct bolt beam;
346     struct dist spd;
347 
348     unsigned char abil_used;
349 
350     // early returns prior to generation of ability list {dlb}:
351     if (you.conf)
352     {
353         mpr("You're too confused!");
354         return (false);
355     }
356 
357     if (you.berserker)
358     {
359         canned_msg(MSG_TOO_BERSERK);
360         return (false);
361     }
362 
363     // populate the array of structs {dlb}:
364     if (!generate_abilities())
365     {
366         mpr("Sorry, you're not good enough to have a special ability.");
367         return (false);
368     }
369 
370     bool  need_redraw = false;
371     bool  need_prompt = true;
372     bool  need_getch  = true;
373 
374     for (;;)
375     {
376         if (need_redraw)
377         {
378             mesclr( true );
379             redraw_screen();
380         }
381 
382         if (need_prompt)
383             mpr( "Use which ability? (? or * to list)", MSGCH_PROMPT );
384 
385         if (need_getch)
386             keyin = get_ch();
387 
388         need_redraw = false;
389         need_prompt = true;
390         need_getch  = true;
391 
392         if (isalpha( keyin ))
393         {
394             break;
395         }
396         else if (keyin == '?' || keyin == '*')
397         {
398             keyin = show_abilities();
399 
400             need_getch  = false;
401             need_redraw = true;
402             need_prompt = true;
403         }
404         else if (keyin == ESCAPE || keyin == ' '
405                 || keyin == '\r' || keyin == '\n')
406         {
407             canned_msg( MSG_OK );
408             return (false);
409         }
410     }
411 
412     spc = (int) keyin;
413 
414     if (!isalpha( spc ))
415     {
416         mpr("You can't do that.");
417         return (false);
418     }
419 
420     spc2 = letter_to_index(spc);
421 
422     if (Curr_abil[spc2].which == -1)
423     {
424         mpr("You can't do that.");
425         return (false);
426     }
427 
428     abil_used = spc2;
429 
430     // some abilities don't need a hunger check
431     bool hungerCheck = true;
432     switch (Curr_abil[abil_used].which)
433     {
434         case ABIL_RENOUNCE_RELIGION:
435         case ABIL_EVOKE_STOP_LEVITATING:
436         case ABIL_EVOKE_TURN_VISIBLE:
437         case ABIL_END_TRANSFORMATION:
438         case ABIL_DELAYED_FIREBALL:
439         case ABIL_MUMMY_RESTORATION:
440             hungerCheck = false;
441             break;
442         default:
443             break;
444     }
445 
446     if (hungerCheck && you.hunger_state < HS_HUNGRY)
447     {
448         mpr("You're too hungry.");
449         return (false);
450     }
451 
452     // no turning back now... {dlb}
453     const struct ability_def abil = get_ability_def(Curr_abil[abil_used].which);
454 
455     // currently only delayed fireball is instantaneous -- bwr
456     you.turn_is_over = ((abil.flags & ABFLAG_INSTANT) ? 0 : 1);
457 
458     if (random2avg(100, 3) < Curr_abil[abil_used].fail)
459     {
460         mpr("You fail to use your ability.");
461         return (false);
462     }
463 
464     if (!enough_mp( abil.mp_cost, false ))
465         return (false);
466 
467     if (!enough_hp( abil.hp_cost, false ))
468         return (false);
469 
470     // Note: the costs will not be applied until after this switch
471     // statement... it's assumed that only failures have returned! -- bwr
472     switch (abil.ability)
473     {
474     case ABIL_MUMMY_RESTORATION:
475         mpr( "You infuse your body with magical energy." );
476         restore_stat( STAT_ALL, false );
477         unrot_hp( 100 );
478         break;
479 
480     case ABIL_DELAYED_FIREBALL:
481         // Note: power level of ball calculated at release -- bwr
482         fireball( calc_spell_power( SPELL_DELAYED_FIREBALL, true ) );
483 
484         // only one allowed since this is instantaneous -- bwr
485         you.attribute[ ATTR_DELAYED_FIREBALL ] = 0;
486         break;
487 
488     case ABIL_GLAMOUR:
489         if (you.duration[DUR_GLAMOUR])
490         {
491             canned_msg(MSG_CANNOT_DO_YET);
492             return (false);
493         }
494 
495         mpr("You use your Elvish wiles.");
496 
497         cast_glamour( 10 + random2(you.experience_level)
498                          + random2(you.experience_level) );
499 
500         you.duration[DUR_GLAMOUR] = 20 + random2avg(13, 3);
501         break;
502 
503     case ABIL_SPIT_POISON:      // Naga + spit poison mutation
504         if (you.duration[DUR_BREATH_WEAPON])
505         {
506             canned_msg(MSG_CANNOT_DO_YET);
507             return (false);
508         }
509         else if (spell_direction(abild, beam) == -1)
510         {
511             canned_msg(MSG_OK);
512             return (false);
513         }
514         else
515         {
516             mpr("You spit poison.");
517 
518             zapping( ZAP_SPIT_POISON,
519                      you.experience_level
520                         + you.mutation[MUT_SPIT_POISON] * 5
521                         + (you.species == SP_NAGA) * 10,
522                      beam );
523 
524             you.duration[DUR_BREATH_WEAPON] = 3 + random2(5);
525         }
526         break;
527 
528     case ABIL_EVOKE_MAPPING:    // randarts
529         mpr("You sense your surroundings.");
530 
531         magic_mapping(  3 + roll_dice( 2, you.skills[SK_EVOCATIONS] ),
532                        40 + roll_dice( 2, you.skills[SK_EVOCATIONS] ) );
533 
534         exercise( SK_EVOCATIONS, 1 );
535         break;
536 
537     case ABIL_MAPPING:          // Gnome + sense surrounds mut
538         mpr("You sense your surroundings.");
539 
540         magic_mapping(  3 + roll_dice( 2, you.experience_level )
541                             + you.mutation[MUT_MAPPING] * 10,
542                        40 + roll_dice( 2, you.experience_level ) );
543         break;
544 
545     case ABIL_EVOKE_TELEPORTATION:    // ring of teleportation
546     case ABIL_TELEPORTATION:          // teleport mut
547         if (you.mutation[MUT_TELEPORT_AT_WILL] == 3)
548             you_teleport2( true, true ); // instant and to new area of Abyss
549         else
550             you_teleport();
551 
552         if (abil.ability == ABIL_EVOKE_TELEPORTATION)
553             exercise( SK_EVOCATIONS, 1 );
554         break;
555 
556     case ABIL_BREATHE_FIRE:
557     case ABIL_BREATHE_FROST:
558     case ABIL_BREATHE_POISON:
559     case ABIL_BREATHE_LIGHTNING:
560     case ABIL_SPIT_ACID:
561     case ABIL_BREATHE_POWER:
562     case ABIL_BREATHE_STICKY_FLAME:
563     case ABIL_BREATHE_STEAM:
564         if (you.duration[DUR_BREATH_WEAPON]
565             && Curr_abil[abil_used].which != ABIL_SPIT_ACID)
566         {
567             canned_msg(MSG_CANNOT_DO_YET);
568             return (false);
569         }
570         else if (spell_direction( abild, beam ) == -1)
571         {
572             canned_msg(MSG_OK);
573             return (false);
574         }
575 
576         switch (Curr_abil[abil_used].which)
577         {
578         case ABIL_BREATHE_FIRE:
579             power = you.experience_level;
580             power += you.mutation[MUT_BREATHE_FLAMES] * 4;
581 
582             if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
583                 power += 12;
584 
585             // don't check for hell serpents - they get hell fire,
586             // never regular fire (GDL)
587 
588             snprintf( info, INFO_SIZE, "You breathe fire%c", (power < 15)?'.':'!');
589             mpr(info);
590 
591             zapping( ZAP_BREATHE_FIRE, power, beam);
592             break;
593 
594         case ABIL_BREATHE_FROST:
595             mpr("You exhale a wave of freezing cold.");
596             zapping(ZAP_BREATHE_FROST, you.experience_level, beam);
597             break;
598 
599         case ABIL_BREATHE_POISON:
600             mpr("You exhale a blast of poison gas.");
601             zapping(ZAP_BREATHE_POISON, you.experience_level, beam);
602             break;
603 
604         case ABIL_BREATHE_LIGHTNING:
605             mpr("You spit a bolt of lightning.");
606             zapping(ZAP_LIGHTNING, (you.experience_level * 2), beam);
607             break;
608 
609         case ABIL_SPIT_ACID:
610             mpr("You spit acid.");
611             zapping(ZAP_BREATHE_ACID, you.experience_level, beam);
612             break;
613 
614         case ABIL_BREATHE_POWER:
615             mpr("You spit a bolt of incandescent energy.");
616             zapping(ZAP_BREATHE_POWER, you.experience_level, beam);
617             break;
618 
619         case ABIL_BREATHE_STICKY_FLAME:
620             mpr("You spit a glob of burning liquid.");
621             zapping(ZAP_STICKY_FLAME, you.experience_level, beam);
622             break;
623 
624         case ABIL_BREATHE_STEAM:
625             mpr("You exhale a blast of scalding steam.");
626             zapping(ZAP_BREATHE_STEAM, you.experience_level, beam);
627             break;
628 
629         }
630 
631         if (Curr_abil[abil_used].which != ABIL_SPIT_ACID)
632         {
633             you.duration[DUR_BREATH_WEAPON] = 3 + random2(5)
634                                                 + random2(30 - you.experience_level);
635         }
636 
637         if (Curr_abil[abil_used].which == ABIL_BREATHE_STEAM)
638         {
639             you.duration[DUR_BREATH_WEAPON] /= 2;
640         }
641         break;
642 
643     case ABIL_EVOKE_BLINK:      // randarts
644     case ABIL_BLINK:            // mutation
645         random_blink(true);
646 
647         if (abil.ability == ABIL_EVOKE_BLINK)
648             exercise( SK_EVOCATIONS, 1 );
649         break;
650 
651     case ABIL_EVOKE_BERSERK:    // amulet of rage, randarts
652         if (you.hunger_state < HS_SATIATED)
653         {
654             mpr("You're too hungry to berserk.");
655             return (false);
656         }
657 
658         go_berserk(true);
659         exercise( SK_EVOCATIONS, 1 );
660         break;
661 
662     // fly (kenku) -- eventually becomes permanent (see acr.cc)
663     case ABIL_FLY:
664         cast_fly( you.experience_level * 4 );
665 
666         if (you.experience_level > 14)
667         {
668             mpr("You feel very comfortable in the air.");
669             you.levitation = 100;
670             you.duration[DUR_CONTROLLED_FLIGHT] = 100;
671         }
672         break;
673 
674     case ABIL_FLY_II:           // Fly (Draconians, or anything else with wings)
675         if (you.exhausted)
676         {
677             mpr("You're too exhausted to fly.");
678             return (false);
679         }
680         else if (you.burden_state != BS_UNENCUMBERED)
681         {
682             mpr("You're carrying too much weight to fly.");
683             return (false);
684         }
685         else
686         {
687             cast_fly( you.experience_level * 2 );
688             // you.attribute[ATTR_EXPENSIVE_FLIGHT] = 1;  // unused
689         }
690         break;
691 
692     // DEMONIC POWERS:
693     case ABIL_SUMMON_MINOR_DEMON:
694         summon_ice_beast_etc( you.experience_level * 4,
695                                      summon_any_demon(DEMON_LESSER) );
696         break;
697 
698     case ABIL_SUMMON_DEMON:
699         summon_ice_beast_etc( you.experience_level * 4,
700                                      summon_any_demon(DEMON_COMMON) );
701         break;
702 
703     case ABIL_HELLFIRE:
704         your_spells(SPELL_HELLFIRE, 20 + you.experience_level, false);
705         break;
706 
707     case ABIL_TORMENT:
708         if (you.is_undead)
709         {
710             mpr("The unliving cannot use this ability.");
711             return (false);
712         }
713 
714         torment(you.x_pos, you.y_pos);
715         break;
716 
717     case ABIL_RAISE_DEAD:
718         your_spells(SPELL_ANIMATE_DEAD, you.experience_level * 5, false);
719         break;
720 
721     case ABIL_CONTROL_DEMON:
722         if (spell_direction(abild, beam) == -1)
723         {
724             canned_msg(MSG_OK);
725             return (false);
726         }
727 
728         zapping(ZAP_CONTROL_DEMON, you.experience_level * 5, beam);
729         break;
730 
731     case ABIL_TO_PANDEMONIUM:
732         if (you.level_type == LEVEL_PANDEMONIUM)
733         {
734             mpr("You're already here.");
735             return (false);
736         }
737 
738         banished(DNGN_ENTER_PANDEMONIUM);
739         break;
740 
741     case ABIL_CHANNELING:
742         mpr("You channel some magical energy.");
743         inc_mp(1 + random2(5), false);
744         break;
745 
746     case ABIL_THROW_FLAME:
747     case ABIL_THROW_FROST:
748         if (spell_direction(abild, beam) == -1)
749         {
750             canned_msg(MSG_OK);
751             return (false);
752         }
753 
754         zapping( (Curr_abil[abil_used].which == ABIL_THROW_FLAME ? ZAP_FLAME
755                                                                  : ZAP_FROST),
756                     you.experience_level * 3,
757                     beam );
758         break;
759 
760     case ABIL_BOLT_OF_DRAINING:
761         if (spell_direction(abild, beam) == -1)
762         {
763             canned_msg(MSG_OK);
764             return (false);
765         }
766 
767         zapping(ZAP_NEGATIVE_ENERGY, you.experience_level * 6, beam);
768         break;
769 
770     case ABIL_EVOKE_TURN_INVISIBLE:     // ring, randarts, darkness items
771         if (you.hunger_state < HS_SATIATED)
772         {
773             mpr("You're too hungry to turn invisible.");
774             return (false);
775         }
776 
777         potion_effect( POT_INVISIBILITY, 2 * you.skills[SK_EVOCATIONS] + 5 );
778         contaminate_player( 1 + random2(3) );
779         exercise( SK_EVOCATIONS, 1 );
780         break;
781 
782     case ABIL_EVOKE_TURN_VISIBLE:
783         mpr("You feel less transparent.");
784         you.invis = 1;
785         break;
786 
787     case ABIL_EVOKE_LEVITATE:           // ring, boots, randarts
788         potion_effect( POT_LEVITATION, 2 * you.skills[SK_EVOCATIONS] + 30 );
789         exercise( SK_EVOCATIONS, 1 );
790         break;
791 
792     case ABIL_EVOKE_STOP_LEVITATING:
793         mpr("You feel heavy.");
794         you.levitation = 1;
795         break;
796 
797     case ABIL_END_TRANSFORMATION:
798         mpr("You feel almost normal.");
799         you.duration[DUR_TRANSFORMATION] = 2;
800         break;
801 
802     // INVOCATIONS:
803     case ABIL_ZIN_REPEL_UNDEAD:
804     case ABIL_TSO_REPEL_UNDEAD:
805         turn_undead(you.piety);
806 
807         if (!you.duration[DUR_REPEL_UNDEAD])
808             mpr( "You feel a holy aura protecting you." );
809 
810         you.duration[DUR_REPEL_UNDEAD] += 8
811                                 + roll_dice(2, 2 * you.skills[SK_INVOCATIONS]);
812 
813         if (you.duration[ DUR_REPEL_UNDEAD ] > 50)
814             you.duration[ DUR_REPEL_UNDEAD ] = 50;
815 
816         exercise(SK_INVOCATIONS, 1);
817         break;
818 
819     case ABIL_ZIN_HEALING:
820         if (!cast_healing( 3 + (you.skills[SK_INVOCATIONS] / 6) ))
821             break;
822 
823         exercise(SK_INVOCATIONS, 1 + random2(3));
824         break;
825 
826     case ABIL_ZIN_PESTILENCE:
827         mpr( "You call forth a swarm of pestilential beasts!" );
828 
829         if (!summon_swarm( you.skills[SK_INVOCATIONS] * 8, false, true ))
830             mpr( "Nothing seems to have answered your call." );
831 
832         exercise( SK_INVOCATIONS, 2 + random2(4) );
833         break;
834 
835     case ABIL_ZIN_HOLY_WORD:
836         holy_word( you.skills[SK_INVOCATIONS] * 8 );
837         exercise(SK_INVOCATIONS, 3 + random2(5));
838         break;
839 
840     case ABIL_ZIN_SUMMON_GUARDIAN:
841         summon_ice_beast_etc(you.skills[SK_INVOCATIONS] * 4, MONS_ANGEL);
842         exercise(SK_INVOCATIONS, 8 + random2(10));
843         break;
844 
845     case ABIL_TSO_SMITING:
846         cast_smiting( you.skills[SK_INVOCATIONS] * 6 );
847         exercise( SK_INVOCATIONS, (coinflip()? 3 : 2) );
848         break;
849 
850     case ABIL_TSO_ANNIHILATE_UNDEAD:
851         if (spell_direction(spd, beam) == -1)
852         {
853             canned_msg(MSG_OK);
854             return (false);
855         }
856 
857         zapping(ZAP_DISPEL_UNDEAD, you.skills[SK_INVOCATIONS] * 6, beam);
858         exercise(SK_INVOCATIONS, 2 + random2(4));
859         break;
860 
861     case ABIL_TSO_THUNDERBOLT:
862         if (spell_direction(spd, beam) == -1)
863         {
864             canned_msg(MSG_OK);
865             return (false);
866         }
867 
868         zapping(ZAP_LIGHTNING, you.skills[SK_INVOCATIONS] * 6, beam);
869         exercise(SK_INVOCATIONS, 3 + random2(6));
870         break;
871 
872     case ABIL_TSO_SUMMON_DAEVA:
873         summon_ice_beast_etc(you.skills[SK_INVOCATIONS] * 4, MONS_DAEVA);
874         exercise(SK_INVOCATIONS, 8 + random2(10));
875         break;
876 
877     case ABIL_KIKU_RECALL_UNDEAD_SLAVES:
878         recall(1);
879         exercise(SK_INVOCATIONS, 1);
880         break;
881 
882     case ABIL_KIKU_ENSLAVE_UNDEAD:
883         if (spell_direction(spd, beam) == -1)
884         {
885             canned_msg(MSG_OK);
886             return (false);
887         }
888 
889         zapping( ZAP_ENSLAVE_UNDEAD, you.skills[SK_INVOCATIONS] * 8, beam );
890         exercise(SK_INVOCATIONS, 5 + random2(5));
891         break;
892 
893     case ABIL_KIKU_INVOKE_DEATH:
894         summon_ice_beast_etc(20 + you.skills[SK_INVOCATIONS] * 3, MONS_REAPER);
895         exercise(SK_INVOCATIONS, 10 + random2(14));
896         break;
897 
898     case ABIL_YRED_ANIMATE_CORPSE:
899         mpr("You call on the dead to walk for you...");
900 
901         animate_a_corpse( you.x_pos, you.y_pos, BEH_FRIENDLY,
902                           you.pet_target, CORPSE_BODY );
903 
904         exercise(SK_INVOCATIONS, 2 + random2(4));
905         break;
906 
907     case ABIL_YRED_RECALL_UNDEAD:
908         recall(1);
909         exercise(SK_INVOCATIONS, 2 + random2(4));
910         break;
911 
912     case ABIL_YRED_ANIMATE_DEAD:
913         mpr("You call on the dead to walk for you...");
914 
915         animate_dead( 1 + you.skills[SK_INVOCATIONS], BEH_FRIENDLY,
916                       you.pet_target, 1 );
917 
918         exercise(SK_INVOCATIONS, 2 + random2(4));
919         break;
920 
921     case ABIL_YRED_DRAIN_LIFE:
922         drain_life( you.skills[SK_INVOCATIONS] );
923         exercise(SK_INVOCATIONS, 2 + random2(4));
924         break;
925 
926     case ABIL_YRED_CONTROL_UNDEAD:
927         mass_enchantment( ENCH_CHARM, you.skills[SK_INVOCATIONS] * 8, MHITYOU );
928         exercise(SK_INVOCATIONS, 3 + random2(4));
929         break;
930 
931     case ABIL_VEHUMET_CHANNEL_ENERGY:
932         mpr("You channel some magical energy.");
933 
934         inc_mp(1 + random2(you.skills[SK_INVOCATIONS] / 4 + 2), false);
935         exercise(SK_INVOCATIONS, 1 + random2(3));
936         break;
937 
938     case ABIL_OKAWARU_MIGHT:
939         potion_effect( POT_MIGHT, you.skills[SK_INVOCATIONS] * 8 );
940         exercise(SK_INVOCATIONS, 1 + random2(3));
941         break;
942 
943     case ABIL_OKAWARU_HEALING:
944         if (!cast_healing( 3 + (you.skills[SK_INVOCATIONS] / 6) ))
945             break;
946 
947         exercise(SK_INVOCATIONS, 2 + random2(5));
948         break;
949 
950     case ABIL_OKAWARU_HASTE:
951         potion_effect( POT_SPEED, you.skills[SK_INVOCATIONS] * 8 );
952         exercise(SK_INVOCATIONS, 3 + random2(7));
953         break;
954 
955     case ABIL_MAKHLEB_MINOR_DESTRUCTION:
956         if (spell_direction(spd, beam) == -1)
957         {
958             canned_msg(MSG_OK);
959             return (false);
960         }
961 
962         power = you.skills[SK_INVOCATIONS]
963                     + random2( 1 + you.skills[SK_INVOCATIONS] )
964                     + random2( 1 + you.skills[SK_INVOCATIONS] );
965 
966         switch (random2(5))
967         {
968         case 0: zapping( ZAP_FLAME,        power,     beam ); break;
969         case 1: zapping( ZAP_PAIN,         power,     beam ); break;
970         case 2: zapping( ZAP_STONE_ARROW,  power,     beam ); break;
971         case 3: zapping( ZAP_ELECTRICITY,  power,     beam ); break;
972         case 4: zapping( ZAP_BREATHE_ACID, power / 2, beam ); break;
973         }
974 
975         exercise(SK_INVOCATIONS, 1);
976         break;
977 
978     case ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB:
979         summon_ice_beast_etc( 20 + you.skills[SK_INVOCATIONS] * 3,
980                               MONS_NEQOXEC + random2(5) );
981 
982         exercise(SK_INVOCATIONS, 2 + random2(3));
983         break;
984 
985     case ABIL_MAKHLEB_MAJOR_DESTRUCTION:
986         if (spell_direction(spd, beam) == -1)
987         {
988             canned_msg(MSG_OK);
989             return (false);
990         }
991 
992         power = you.skills[SK_INVOCATIONS] * 3
993                     + random2( 1 + you.skills[SK_INVOCATIONS] )
994                     + random2( 1 + you.skills[SK_INVOCATIONS] );
995 
996         switch (random2(8))
997         {
998         case 0: zapping( ZAP_FIRE,               power, beam ); break;
999         case 1: zapping( ZAP_FIREBALL,           power, beam ); break;
1000         case 2: zapping( ZAP_LIGHTNING,          power, beam ); break;
1001         case 3: zapping( ZAP_NEGATIVE_ENERGY,    power, beam ); break;
1002         case 4: zapping( ZAP_STICKY_FLAME,       power, beam ); break;
1003         case 5: zapping( ZAP_IRON_BOLT,          power, beam ); break;
1004         case 6: zapping( ZAP_ORB_OF_ELECTRICITY, power, beam ); break;
1005 
1006         case 7:
1007             you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 1;
1008             mpr("Makhleb hurls a blast of lightning!");
1009 
1010             // make a divine lightning bolt...
1011             beam.beam_source = NON_MONSTER;
1012             beam.type = SYM_BURST;
1013             beam.damage = dice_def( 3, 30 );
1014             beam.flavour = BEAM_ELECTRICITY;
1015             beam.target_x = you.x_pos;
1016             beam.target_y = you.y_pos;
1017             strcpy(beam.beam_name, "blast of lightning");
1018             beam.colour = LIGHTCYAN;
1019             beam.thrower = KILL_YOU;
1020             beam.aux_source = "Makhleb's lightning strike";
1021             beam.ex_size = 1 + you.skills[SK_INVOCATIONS] / 8;
1022             beam.isTracer = false;
1023 
1024             // ... and fire!
1025             explosion(beam);
1026 
1027             // protection down
1028             mpr("Your divine protection wanes.");
1029             you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 0;
1030             break;
1031         }
1032 
1033         exercise(SK_INVOCATIONS, 3 + random2(5));
1034         break;
1035 
1036     case ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB:
1037         summon_ice_beast_etc( 20 + you.skills[SK_INVOCATIONS] * 3,
1038                               MONS_EXECUTIONER + random2(5) );
1039 
1040         exercise(SK_INVOCATIONS, 6 + random2(6));
1041         break;
1042 
1043     case ABIL_TROG_BERSERK:
1044         // Trog abilities don't use or train invocations.
1045         if (you.hunger_state < HS_SATIATED)
1046         {
1047             mpr("You're too hungry to berserk.");
1048             return (false);
1049         }
1050 
1051         go_berserk(true);
1052         break;
1053 
1054     case ABIL_TROG_MIGHT:
1055         // Trog abilities don't use or train invocations.
1056         potion_effect( POT_MIGHT, 150 );
1057         break;
1058 
1059     case ABIL_TROG_HASTE_SELF:
1060         // Trog abilities don't use or train invocations.
1061         potion_effect( POT_SPEED, 150 );
1062         break;
1063 
1064     case ABIL_SIF_MUNA_FORGET_SPELL:
1065         cast_selective_amnesia(true);
1066         break;
1067 
1068     case ABIL_ELYVILON_LESSER_HEALING:
1069         if (!cast_healing( 3 + (you.skills[SK_INVOCATIONS] / 6) ))
1070             break;
1071 
1072         exercise( SK_INVOCATIONS, 1 );
1073         break;
1074 
1075     case ABIL_ELYVILON_PURIFICATION:
1076         purification();
1077         exercise( SK_INVOCATIONS, 2 + random2(3) );
1078         break;
1079 
1080     case ABIL_ELYVILON_HEALING:
1081         if (!cast_healing( 10 + (you.skills[SK_INVOCATIONS] / 3) ))
1082             break;
1083 
1084         exercise( SK_INVOCATIONS, 3 + random2(5) );
1085         break;
1086 
1087     case ABIL_ELYVILON_RESTORATION:
1088         restore_stat( STAT_ALL, false );
1089         unrot_hp( 100 );
1090 
1091         exercise( SK_INVOCATIONS, 4 + random2(6) );
1092         break;
1093 
1094     case ABIL_ELYVILON_GREATER_HEALING:
1095         if (!cast_healing( 20 + you.skills[SK_INVOCATIONS] * 2 ))
1096             break;
1097 
1098         exercise( SK_INVOCATIONS, 6 + random2(10) );
1099         break;
1100 
1101     //jmf: intended as invocations from evil god(s):
1102     case ABIL_CHARM_SNAKE:
1103         cast_snake_charm( you.experience_level * 2
1104                             + you.skills[SK_INVOCATIONS] * 3 );
1105 
1106         exercise(SK_INVOCATIONS, 2 + random2(4));
1107         break;
1108 
1109     case ABIL_TRAN_SERPENT_OF_HELL:
1110         transform(10 + (you.experience_level * 2) +
1111                   (you.skills[SK_INVOCATIONS] * 3), TRAN_SERPENT_OF_HELL);
1112 
1113         exercise(SK_INVOCATIONS, 6 + random2(9));
1114         break;
1115 
1116     case ABIL_BREATHE_HELLFIRE:
1117         if (you.duration[DUR_BREATH_WEAPON])
1118         {
1119             canned_msg(MSG_CANNOT_DO_YET);
1120             return (false);
1121         }
1122 
1123         your_spells( SPELL_HELLFIRE, 20 + you.experience_level, false );
1124 
1125         you.duration[DUR_BREATH_WEAPON] +=
1126                         3 + random2(5) + random2(30 - you.experience_level);
1127         break;
1128 
1129     case ABIL_ROTTING:
1130         cast_rotting(you.experience_level * 2 + you.skills[SK_INVOCATIONS] * 3);
1131         exercise(SK_INVOCATIONS, 2 + random2(4));
1132         break;
1133 
1134     case ABIL_TORMENT_II:
1135         if (you.is_undead)
1136         {
1137             mpr("The unliving cannot use this ability.");
1138             return (false);
1139         }
1140 
1141         torment(you.x_pos, you.y_pos);
1142         exercise(SK_INVOCATIONS, 2 + random2(4));
1143         break;
1144 
1145     case ABIL_SHUGGOTH_SEED:
1146         if (you.duration[DUR_SHUGGOTH_SEED_RELOAD])
1147         {
1148             canned_msg(MSG_CANNOT_DO_YET);
1149             return (false);
1150         }
1151 
1152         cast_shuggoth_seed( you.experience_level * 2
1153                                 + you.skills[SK_INVOCATIONS] * 3 );
1154 
1155         you.duration[DUR_SHUGGOTH_SEED_RELOAD] = 10 + random2avg(39, 2);
1156         exercise(SK_INVOCATIONS, 2 + random2(4));
1157         break;
1158 
1159     case ABIL_RENOUNCE_RELIGION:
1160         if (yesno("Really renounce your faith, foregoing its fabulous benefits?")
1161             && yesno( "Are you sure you won't change your mind later?" ))
1162         {
1163             excommunication();
1164         }
1165         else
1166         {
1167             canned_msg(MSG_OK);
1168         }
1169         break;
1170 
1171     default:
1172         mpr("Sorry, you can't do that.");
1173         break;
1174     }
1175 
1176     // All failures should have returned by this point, so we'll
1177     // apply the costs -- its not too neat, but it works for now. -- bwr
1178     const int food_cost = abil.food_cost + random2avg(abil.food_cost, 2);
1179     const int piety_cost = abil.piety_cost + random2((abil.piety_cost + 1) / 2 + 1);
1180 
1181 #if DEBUG_DIAGNOSTICS
1182     snprintf( info, INFO_SIZE, "Cost: mp=%d; hp=%d; food=%d; piety=%d",
1183               abil.mp_cost, abil.hp_cost, food_cost, piety_cost );
1184 
1185     mpr( info, MSGCH_DIAGNOSTICS );
1186 #endif
1187 
1188     if (abil.mp_cost)
1189     {
1190         dec_mp( abil.mp_cost );
1191         if (abil.flags & ABFLAG_PERMANENT_MP)
1192             rot_mp(1);
1193     }
1194 
1195     if (abil.hp_cost)
1196     {
1197         dec_hp( abil.hp_cost, false );
1198         if (abil.flags & ABFLAG_PERMANENT_HP)
1199             rot_hp(1);
1200     }
1201 
1202     if (food_cost)
1203         make_hungry( food_cost, false );
1204 
1205     if (piety_cost)
1206         lose_piety( piety_cost );
1207 
1208     return (true);
1209 }  // end activate_ability()
1210 
1211 
1212 // Lists any abilities the player may possess
show_abilities(void)1213 char show_abilities( void )
1214 /*************************/
1215 {
1216     int loopy = 0;
1217     char lines = 0;
1218     unsigned char anything = 0;
1219     char ki;
1220     bool can_invoke = false;
1221 
1222     const int num_lines = get_number_of_lines();
1223 
1224     for (loopy = 0; loopy < 52; loopy++)
1225     {
1226         if (Curr_abil[loopy].is_invocation)
1227         {
1228             can_invoke = true;
1229             break;
1230         }
1231     }
1232 
1233 
1234 #ifdef DOS_TERM
1235     char buffer[4800];
1236 
1237     gettext(1, 1, 80, 25, buffer);
1238     window(1, 1, 80, 25);
1239 #endif
1240 
1241     clrscr();
1242     cprintf("  Ability                           Cost                    Success");
1243     lines++;
1244 
1245     for (int do_invoke = 0; do_invoke < (can_invoke ? 2 : 1); do_invoke++)
1246     {
1247         if (do_invoke)
1248         {
1249             anything++;
1250             textcolor(BLUE);
1251             cprintf(EOL "    Invocations - ");
1252             textcolor(LIGHTGREY);
1253             lines++;
1254         }
1255 
1256         for (loopy = 0; loopy < 52; loopy++)
1257         {
1258             if (lines > num_lines - 2)
1259             {
1260                 gotoxy(1, num_lines);
1261                 cprintf("-more-");
1262 
1263                 ki = getch();
1264 
1265                 if (ki == ESCAPE)
1266                 {
1267 #ifdef DOS_TERM
1268                     puttext(1, 1, 80, 25, buffer);
1269 #endif
1270                     return (ESCAPE);
1271                 }
1272 
1273                 if (ki >= 'A' && ki <= 'z')
1274                 {
1275 #ifdef DOS_TERM
1276                     puttext(1, 1, 80, 25, buffer);
1277 #endif
1278                     return (ki);
1279                 }
1280 
1281                 if (ki == 0)
1282                     ki = getch();
1283 
1284                 lines = 0;
1285                 clrscr();
1286                 gotoxy(1, 1);
1287                 anything = 0;
1288             }
1289 
1290             if (Curr_abil[loopy].which != ABIL_NON_ABILITY
1291                 && (do_invoke == Curr_abil[loopy].is_invocation))
1292             {
1293                 anything++;
1294 
1295                 if (lines > 0)
1296                     cprintf(EOL);
1297 
1298                 lines++;
1299 
1300                 const struct ability_def abil = get_ability_def( Curr_abil[loopy].which );
1301 
1302                 cprintf( " %c - %s", index_to_letter(loopy), abil.name );
1303 
1304                 // Output costs:
1305                 gotoxy( 35, wherey() );
1306 
1307                 std::string cost_str = make_cost_description( abil );
1308 
1309                 if (cost_str.length() > 24)
1310                     cost_str = cost_str.substr( 0, 24 );
1311 
1312                 cprintf( cost_str.c_str() );
1313 
1314                 gotoxy(60, wherey());
1315 
1316                 int spell_f = Curr_abil[loopy].fail;
1317 
1318                 cprintf( (spell_f >= 100) ? "Useless"   :
1319                          (spell_f >   90) ? "Terrible"  :
1320                          (spell_f >   80) ? "Cruddy"    :
1321                          (spell_f >   70) ? "Bad"       :
1322                          (spell_f >   60) ? "Very Poor" :
1323                          (spell_f >   50) ? "Poor"      :
1324                          (spell_f >   40) ? "Fair"      :
1325                          (spell_f >   30) ? "Good"      :
1326                          (spell_f >   20) ? "Very Good" :
1327                          (spell_f >   10) ? "Great"     :
1328                          (spell_f >    0) ? "Excellent" :
1329                                             "Perfect" );
1330 
1331                 gotoxy(70, wherey());
1332             }                              // end if conditional
1333         }                                  // end "for loopy"
1334     }
1335 
1336     if (anything > 0)
1337     {
1338         ki = getch();
1339 
1340         if (ki >= 'A' && ki <= 'z')
1341         {
1342 #ifdef DOS_TERM
1343             puttext(1, 1, 80, 25, buffer);
1344 #endif
1345             return (ki);
1346         }
1347 
1348         if (ki == 0)
1349             ki = getch();
1350 
1351 #ifdef DOS_TERM
1352         puttext(1, 1, 80, 25, buffer);
1353 #endif
1354 
1355         return (ki);
1356     }
1357 
1358 #ifdef DOS_TERM
1359     puttext(1, 1, 80, 25, buffer);
1360 #endif
1361 
1362     ki = getch();
1363 
1364     return (ki);
1365 }                               // end show_abilities()
1366 
1367 
generate_abilities(void)1368 bool generate_abilities( void )
1369 /*****************************/
1370 {
1371     int loopy;
1372     int ability = -1;                   // used with draconian checks {dlb}
1373 
1374     // fill array of structs with "empty" values {dlb}:
1375     for (loopy = 0; loopy < 52; loopy++)
1376     {
1377         Curr_abil[loopy].which = ABIL_NON_ABILITY;
1378         Curr_abil[loopy].fail = 100;
1379         Curr_abil[loopy].is_invocation = false;
1380     }
1381 
1382     // first we do the racial abilities:
1383 
1384     // Mummies get the ability to restore HPs and stats, but it
1385     // costs permanent MP (and those can never be recovered).  -- bwr
1386     if (you.species == SP_MUMMY && you.experience_level >= 13)
1387     {
1388         insert_ability( ABIL_MUMMY_RESTORATION );
1389     }
1390 
1391     // checking for species-related abilities and mutagenic counterparts {dlb}:
1392     if (you.attribute[ATTR_TRANSFORMATION] == TRAN_NONE
1393         && ((you.species == SP_GREY_ELF && you.experience_level >= 5)
1394             || (you.species == SP_HIGH_ELF && you.experience_level >= 15)))
1395     {
1396         insert_ability( ABIL_GLAMOUR );
1397     }
1398 
1399     if (you.species == SP_NAGA)
1400     {
1401         if (you.mutation[MUT_BREATHE_POISON])
1402             insert_ability( ABIL_BREATHE_POISON );
1403         else
1404             insert_ability( ABIL_SPIT_POISON );
1405     }
1406     else if (you.mutation[MUT_SPIT_POISON])
1407     {
1408         insert_ability( ABIL_SPIT_POISON );
1409     }
1410 
1411     if (player_genus(GENPC_DRACONIAN))
1412     {
1413         if (you.experience_level >= 7)
1414         {
1415             ability = (
1416                 (you.species == SP_GREEN_DRACONIAN)  ? ABIL_BREATHE_POISON :
1417                 (you.species == SP_RED_DRACONIAN)    ? ABIL_BREATHE_FIRE :
1418                 (you.species == SP_WHITE_DRACONIAN)  ? ABIL_BREATHE_FROST :
1419                 (you.species == SP_GOLDEN_DRACONIAN) ? ABIL_SPIT_ACID :
1420                 (you.species == SP_BLACK_DRACONIAN)  ? ABIL_BREATHE_LIGHTNING :
1421                 (you.species == SP_PURPLE_DRACONIAN) ? ABIL_BREATHE_POWER :
1422                 (you.species == SP_PALE_DRACONIAN)   ? ABIL_BREATHE_STEAM :
1423                 (you.species == SP_MOTTLED_DRACONIAN)? ABIL_BREATHE_STICKY_FLAME:
1424                                                      -1);
1425 
1426             if (ability != -1)
1427                 insert_ability( ability );
1428         }
1429     }
1430 
1431     //jmf: alternately put check elsewhere
1432     if ((you.level_type == LEVEL_DUNGEON
1433             && (you.species == SP_GNOME || you.mutation[MUT_MAPPING]))
1434         || (you.level_type == LEVEL_PANDEMONIUM
1435             && you.mutation[MUT_MAPPING] == 3))
1436     {
1437         insert_ability( ABIL_MAPPING );
1438     }
1439 
1440     if (!you.duration[DUR_CONTROLLED_FLIGHT] && !player_is_levitating())
1441     {
1442         // kenku can fly, but only from the ground
1443         // (until levitation 15, when it becomes permanent until revoked)
1444         //jmf: "upgrade" for draconians -- expensive flight
1445         if (you.species == SP_KENKU && you.experience_level >= 5)
1446             insert_ability( ABIL_FLY );
1447         else if (player_genus(GENPC_DRACONIAN) && you.mutation[MUT_BIG_WINGS])
1448             insert_ability( ABIL_FLY_II );
1449     }
1450 
1451     // demonic powers {dlb}:
1452     if (you.mutation[MUT_SUMMON_MINOR_DEMONS])
1453         insert_ability( ABIL_SUMMON_MINOR_DEMON );
1454 
1455     if (you.mutation[MUT_SUMMON_DEMONS])
1456         insert_ability( ABIL_SUMMON_DEMON );
1457 
1458     if (you.mutation[MUT_HURL_HELLFIRE])
1459         insert_ability( ABIL_HELLFIRE );
1460 
1461     if (you.mutation[MUT_CALL_TORMENT])
1462         insert_ability( ABIL_TORMENT );
1463 
1464     if (you.mutation[MUT_RAISE_DEAD])
1465         insert_ability( ABIL_RAISE_DEAD );
1466 
1467     if (you.mutation[MUT_CONTROL_DEMONS])
1468         insert_ability( ABIL_CONTROL_DEMON );
1469 
1470     if (you.mutation[MUT_PANDEMONIUM])
1471         insert_ability( ABIL_TO_PANDEMONIUM );
1472 
1473     if (you.mutation[MUT_CHANNEL_HELL])
1474         insert_ability( ABIL_CHANNELING );
1475 
1476     if (you.mutation[MUT_THROW_FLAMES])
1477         insert_ability( ABIL_THROW_FLAME );
1478 
1479     if (you.mutation[MUT_THROW_FROST])
1480         insert_ability( ABIL_THROW_FROST );
1481 
1482     if (you.mutation[MUT_SMITE])
1483         insert_ability( ABIL_BOLT_OF_DRAINING );
1484 
1485     if (you.duration[DUR_TRANSFORMATION])
1486         insert_ability( ABIL_END_TRANSFORMATION );
1487 
1488     if (you.mutation[MUT_BLINK])
1489         insert_ability( ABIL_BLINK );
1490 
1491     if (you.mutation[MUT_TELEPORT_AT_WILL])
1492         insert_ability( ABIL_TELEPORTATION );
1493 
1494     // gods take abilities away until penance completed -- bwr
1495     if (!player_under_penance() && !silenced( you.x_pos, you.y_pos ))
1496     {
1497         switch (you.religion)
1498         {
1499         case GOD_ZIN:
1500             if (you.piety >= 30)
1501                 insert_ability( ABIL_ZIN_REPEL_UNDEAD );
1502             if (you.piety >= 50)
1503                 insert_ability( ABIL_ZIN_HEALING );
1504             if (you.piety >= 75)
1505                 insert_ability( ABIL_ZIN_PESTILENCE );
1506             if (you.piety >= 100)
1507                 insert_ability( ABIL_ZIN_HOLY_WORD );
1508             if (you.piety >= 120)
1509                 insert_ability( ABIL_ZIN_SUMMON_GUARDIAN );
1510             break;
1511 
1512         case GOD_SHINING_ONE:
1513             if (you.piety >= 30)
1514                 insert_ability( ABIL_TSO_REPEL_UNDEAD );
1515             if (you.piety >= 50)
1516                 insert_ability( ABIL_TSO_SMITING );
1517             if (you.piety >= 75)
1518                 insert_ability( ABIL_TSO_ANNIHILATE_UNDEAD );
1519             if (you.piety >= 100)
1520                 insert_ability( ABIL_TSO_THUNDERBOLT );
1521             if (you.piety >= 120)
1522                 insert_ability( ABIL_TSO_SUMMON_DAEVA );
1523             break;
1524 
1525         case GOD_YREDELEMNUL:
1526             if (you.piety >= 30)
1527                 insert_ability( ABIL_YRED_ANIMATE_CORPSE );
1528             if (you.piety >= 50)
1529                 insert_ability( ABIL_YRED_RECALL_UNDEAD );
1530             if (you.piety >= 75)
1531                 insert_ability( ABIL_YRED_ANIMATE_DEAD );
1532             if (you.piety >= 100)
1533                 insert_ability( ABIL_YRED_DRAIN_LIFE );
1534             if (you.piety >= 120)
1535                 insert_ability( ABIL_YRED_CONTROL_UNDEAD );
1536             break;
1537 
1538         case GOD_ELYVILON:
1539             if (you.piety >= 30)
1540                 insert_ability( ABIL_ELYVILON_LESSER_HEALING );
1541             if (you.piety >= 50)
1542                 insert_ability( ABIL_ELYVILON_PURIFICATION );
1543             if (you.piety >= 75)
1544                 insert_ability( ABIL_ELYVILON_HEALING );
1545             if (you.piety >= 100)
1546                 insert_ability( ABIL_ELYVILON_RESTORATION );
1547             if (you.piety >= 120)
1548                 insert_ability( ABIL_ELYVILON_GREATER_HEALING );
1549             break;
1550 
1551         case GOD_MAKHLEB:
1552             if (you.piety >= 50)
1553                 insert_ability( ABIL_MAKHLEB_MINOR_DESTRUCTION );
1554             if (you.piety >= 75)
1555                 insert_ability( ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB );
1556             if (you.piety >= 100)
1557                 insert_ability( ABIL_MAKHLEB_MAJOR_DESTRUCTION );
1558             if (you.piety >= 120)
1559                 insert_ability( ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB );
1560             break;
1561 
1562         case GOD_KIKUBAAQUDGHA:
1563             if (you.piety >= 30)
1564                 insert_ability( ABIL_KIKU_RECALL_UNDEAD_SLAVES );
1565             if (you.piety >= 75)
1566                 insert_ability( ABIL_KIKU_ENSLAVE_UNDEAD );
1567             if (you.piety >= 120)
1568                 insert_ability( ABIL_KIKU_INVOKE_DEATH );
1569             break;
1570 
1571         case GOD_OKAWARU:
1572             if (you.piety >= 30)
1573                 insert_ability( ABIL_OKAWARU_MIGHT );
1574             if (you.piety >= 50)
1575                 insert_ability( ABIL_OKAWARU_HEALING );
1576             if (you.piety >= 120)
1577                 insert_ability( ABIL_OKAWARU_HASTE );
1578             break;
1579 
1580         case GOD_TROG:
1581             if (you.piety >= 30)
1582                 insert_ability( ABIL_TROG_BERSERK );
1583             if (you.piety >= 50)
1584                 insert_ability( ABIL_TROG_MIGHT );
1585             if (you.piety >= 100)
1586                 insert_ability( ABIL_TROG_HASTE_SELF );
1587             break;
1588 
1589         case GOD_SIF_MUNA:
1590             if (you.piety >= 50)
1591                 insert_ability( ABIL_SIF_MUNA_FORGET_SPELL );
1592             break;
1593 
1594         case GOD_VEHUMET:
1595             if (you.piety >= 100)
1596                 insert_ability( ABIL_VEHUMET_CHANNEL_ENERGY );
1597             break;
1598 
1599         default:
1600             break;
1601         }
1602     }
1603 
1604     // and finally, the ability to opt-out of your faith {dlb}:
1605     if (you.religion != GOD_NO_GOD && !silenced( you.x_pos, you.y_pos ))
1606         insert_ability( ABIL_RENOUNCE_RELIGION );
1607 
1608     //jmf: check for breath weapons -- they're exclusive of each other I hope!
1609     //     better make better ones first.
1610     if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SERPENT_OF_HELL)
1611     {
1612         insert_ability( ABIL_BREATHE_HELLFIRE );
1613     }
1614     else if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON
1615                                         || you.mutation[MUT_BREATHE_FLAMES])
1616     {
1617         insert_ability( ABIL_BREATHE_FIRE );
1618     }
1619 
1620     // checking for unreleased delayed fireball
1621     if (you.attribute[ ATTR_DELAYED_FIREBALL ])
1622     {
1623         insert_ability( ABIL_DELAYED_FIREBALL );
1624     }
1625 
1626     // evocations from items:
1627     if (scan_randarts(RAP_BLINK))
1628         insert_ability( ABIL_EVOKE_BLINK );
1629 
1630     if (wearing_amulet(AMU_RAGE) || scan_randarts(RAP_BERSERK))
1631         insert_ability( ABIL_EVOKE_BERSERK );
1632 
1633     if (scan_randarts( RAP_MAPPING ))
1634         insert_ability( ABIL_EVOKE_MAPPING );
1635 
1636     if (player_equip( EQ_RINGS, RING_INVISIBILITY )
1637         || player_equip_ego_type( EQ_ALL_ARMOUR, SPARM_DARKNESS )
1638         || scan_randarts( RAP_INVISIBLE ))
1639     {
1640         // Now you can only turn invisibility off if you have an
1641         // activatable item.  Wands and potions allow will have
1642         // to time out. -- bwr
1643         if (you.invis)
1644             insert_ability( ABIL_EVOKE_TURN_VISIBLE );
1645         else
1646             insert_ability( ABIL_EVOKE_TURN_INVISIBLE );
1647     }
1648 
1649     //jmf: "upgrade" for draconians -- expensive flight
1650     // note: this ability only applies to this counter
1651     if (player_equip( EQ_RINGS, RING_LEVITATION )
1652         || player_equip_ego_type( EQ_BOOTS, SPARM_LEVITATION )
1653         || scan_randarts( RAP_LEVITATE ))
1654     {
1655         // Now you can only turn levitation off if you have an
1656         // activatable item.  Potions and miscast effects will
1657         // have to time out (this makes the miscast effect actually
1658         // a bit annoying). -- bwr
1659         if (you.levitation)
1660             insert_ability( ABIL_EVOKE_STOP_LEVITATING );
1661         else
1662             insert_ability( ABIL_EVOKE_LEVITATE );
1663     }
1664 
1665     if (player_equip( EQ_RINGS, RING_TELEPORTATION )
1666         || scan_randarts( RAP_CAN_TELEPORT ))
1667     {
1668         insert_ability( ABIL_EVOKE_TELEPORTATION );
1669     }
1670 
1671     // this is a shameless kludge for the time being {dlb}:
1672     // still shameless. -- bwr
1673     for (loopy = 0; loopy < 52; loopy++)
1674     {
1675         if (Curr_abil[loopy].which != ABIL_NON_ABILITY)
1676             return (true);
1677     }
1678 
1679     return (false);
1680 }                               // end generate_abilities()
1681 
1682 // Note: we're trying for a behaviour where the player gets
1683 // to keep their assigned invocation slots if they get excommunicated
1684 // and then rejoin (but if they spend time with another god we consider
1685 // the old invocation slots void and erase them).  We also try to
1686 // protect any bindings the character might have made into the
1687 // traditional invocation slots (A-E and X). -- bwr
set_god_ability_helper(int abil,char letter)1688 void set_god_ability_helper( int abil, char letter )
1689 /**************************************************/
1690 {
1691     int i;
1692     const int index = letter_to_index( letter );
1693 
1694     for (i = 0; i < 52; i++)
1695     {
1696         if (you.ability_letter_table[i] == abil)
1697             break;
1698     }
1699 
1700     if (i == 52)        // ability is not already assigned
1701     {
1702         // if slot is unoccupied, move in
1703         if (you.ability_letter_table[index] == ABIL_NON_ABILITY)
1704             you.ability_letter_table[index] = abil;
1705     }
1706 }
1707 
set_god_ability_slots(void)1708 void set_god_ability_slots( void )
1709 /********************************/
1710 {
1711     ASSERT( you.religion != GOD_NO_GOD );
1712 
1713     int i;
1714 
1715     set_god_ability_helper( ABIL_RENOUNCE_RELIGION, 'X' );
1716 
1717     int num_abil = 0;
1718     int abil_start = ABIL_NON_ABILITY;
1719 
1720     switch (you.religion)
1721     {
1722     case GOD_ZIN:
1723         abil_start = ABIL_ZIN_REPEL_UNDEAD;
1724         num_abil = 5;
1725         break;
1726 
1727     case GOD_SHINING_ONE:
1728         abil_start = ABIL_TSO_REPEL_UNDEAD;
1729         num_abil = 5;
1730         break;
1731 
1732     case GOD_KIKUBAAQUDGHA:
1733         abil_start = ABIL_KIKU_RECALL_UNDEAD_SLAVES;
1734         num_abil = 3;
1735         break;
1736 
1737     case GOD_YREDELEMNUL:
1738         abil_start = ABIL_YRED_ANIMATE_CORPSE;
1739         num_abil = 5;
1740         break;
1741 
1742     case GOD_VEHUMET:
1743         abil_start = ABIL_VEHUMET_CHANNEL_ENERGY;
1744         num_abil = 1;
1745         break;
1746 
1747     case GOD_OKAWARU:
1748         abil_start = ABIL_OKAWARU_MIGHT;
1749         num_abil = 3;
1750         break;
1751 
1752     case GOD_MAKHLEB:
1753         abil_start = ABIL_MAKHLEB_MINOR_DESTRUCTION;
1754         num_abil = 4;
1755         break;
1756 
1757     case GOD_SIF_MUNA:
1758         abil_start = ABIL_SIF_MUNA_FORGET_SPELL;
1759         num_abil = 1;
1760         break;
1761 
1762     case GOD_TROG:
1763         abil_start = ABIL_TROG_BERSERK;
1764         num_abil = 3;
1765         break;
1766 
1767     case GOD_ELYVILON:
1768         abil_start = ABIL_ELYVILON_LESSER_HEALING;
1769         num_abil = 5;
1770         break;
1771 
1772     case GOD_NEMELEX_XOBEH:
1773     case GOD_XOM:
1774     default:
1775         break;
1776     }
1777 
1778     // clear out other god invocations:
1779     for (i = 0; i < 52; i++)
1780     {
1781         const int abil = you.ability_letter_table[i];
1782 
1783         if ((abil >= ABIL_ZIN_REPEL_UNDEAD      // is a god ability
1784                     && abil <= ABIL_ELYVILON_GREATER_HEALING)
1785             && (num_abil == 0           // current god does have abilities
1786                 || abil < abil_start    // not one of current god's abilities
1787                 || abil >= abil_start + num_abil))
1788         {
1789             you.ability_letter_table[i] = ABIL_NON_ABILITY;
1790         }
1791     }
1792 
1793     // finally, add in current god's invocaions in traditional slots:
1794     if (num_abil)
1795     {
1796         for (i = 0; i < num_abil; i++)
1797         {
1798             set_god_ability_helper( abil_start + i,
1799                     (Options.lowercase_invocations ? 'a' : 'A') + i );
1800         }
1801     }
1802 }
1803 
1804 
1805 // returns index to Curr_abil, -1 on failure
find_ability_slot(int which_ability)1806 static int find_ability_slot( int which_ability )
1807 /***********************************************/
1808 {
1809     int  slot;
1810     for (slot = 0; slot < 52; slot++)
1811     {
1812         if (you.ability_letter_table[slot] == which_ability)
1813             break;
1814     }
1815 
1816     // no requested slot, find new one and make it prefered.
1817     if (slot == 52)
1818     {
1819         // skip over a-e if player prefers them for invocations
1820         for (slot = (Options.lowercase_invocations ? 5 : 0); slot < 52; slot++)
1821         {
1822             if (you.ability_letter_table[slot] == ABIL_NON_ABILITY)
1823                 break;
1824         }
1825 
1826         // if we skipped over a-e to reserve them, try them now
1827         if (Options.lowercase_invocations && slot == 52)
1828         {
1829             for (slot = 5; slot >= 0; slot--)
1830             {
1831                 if (you.ability_letter_table[slot] == ABIL_NON_ABILITY)
1832                     break;
1833             }
1834         }
1835 
1836         // All letters are assigned, check Curr_abil and try to steal a letter
1837         if (slot == 52)
1838         {
1839             // backwards, to protect the low lettered slots from replacement
1840             for (slot = 51; slot >= 0; slot--)
1841             {
1842                 if (Curr_abil[slot].which == ABIL_NON_ABILITY)
1843                     break;
1844             }
1845 
1846             // no slots at all == no hope of adding
1847             if (slot < 0)
1848                 return (-1);
1849         }
1850 
1851         // this ability now takes over this slot
1852         you.ability_letter_table[slot] = which_ability;
1853     }
1854 
1855     return (slot);
1856 }
1857 
insert_ability(int which_ability)1858 static bool insert_ability( int which_ability )
1859 /**********************************************/
1860 {
1861     ASSERT( which_ability != ABIL_NON_ABILITY );
1862 
1863     int failure = 0;
1864     bool perfect = false;  // is perfect
1865     bool invoc = false;
1866 
1867     // Look through the table to see if there's a preference, else
1868     // find a new empty slot for this ability. -- bwr
1869     const int slot = find_ability_slot( which_ability );
1870     if (slot == -1)
1871         return (false);
1872 
1873     Curr_abil[slot].which = which_ability;
1874 
1875     switch (which_ability)
1876     {
1877     // begin spell abilities
1878     case ABIL_DELAYED_FIREBALL:
1879     case ABIL_MUMMY_RESTORATION:
1880         perfect = true;
1881         failure = 0;
1882         break;
1883 
1884     // begin species abilities - some are mutagenic, too {dlb}
1885     case ABIL_GLAMOUR:
1886         failure = 50 - (you.experience_level * 2);
1887         break;
1888 
1889     case ABIL_SPIT_POISON:
1890         failure = ((you.species == SP_NAGA) ? 20 : 40)
1891                         - 10 * you.mutation[MUT_SPIT_POISON]
1892                         - you.experience_level;
1893         break;
1894 
1895     case ABIL_EVOKE_MAPPING:
1896         failure = 30 - you.skills[SK_EVOCATIONS];
1897         break;
1898 
1899     case ABIL_MAPPING:
1900         failure = ((you.species == SP_GNOME) ? 20 : 40)
1901                         - 10 * you.mutation[MUT_MAPPING]
1902                         - you.experience_level;
1903         break;
1904 
1905     case ABIL_BREATHE_FIRE:
1906         failure = ((you.species == SP_RED_DRACONIAN) ? 30 : 50)
1907                         - 10 * you.mutation[MUT_BREATHE_FLAMES]
1908                         - you.experience_level;
1909 
1910         if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
1911             failure -= 20;
1912         break;
1913 
1914     case ABIL_BREATHE_FROST:
1915     case ABIL_BREATHE_POISON:
1916     case ABIL_SPIT_ACID:
1917     case ABIL_BREATHE_LIGHTNING:
1918     case ABIL_BREATHE_POWER:
1919     case ABIL_BREATHE_STICKY_FLAME:
1920         failure = 30 - you.experience_level;
1921 
1922         if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
1923             failure -= 20;
1924         break;
1925 
1926     case ABIL_BREATHE_STEAM:
1927         failure = 20 - you.experience_level;
1928 
1929         if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
1930             failure -= 20;
1931         break;
1932 
1933     case ABIL_FLY:              // this is for kenku {dlb}
1934         failure = 45 - (3 * you.experience_level);
1935         break;
1936 
1937     case ABIL_FLY_II:           // this is for draconians {dlb}
1938         failure = 45 - (you.experience_level + you.strength);
1939         break;
1940         // end species abilties (some mutagenic)
1941 
1942         // begin demonic powers {dlb}
1943     case ABIL_THROW_FLAME:
1944     case ABIL_THROW_FROST:
1945         failure = 10 - you.experience_level;
1946         break;
1947 
1948     case ABIL_SUMMON_MINOR_DEMON:
1949         failure = 27 - you.experience_level;
1950         break;
1951 
1952     case ABIL_CHANNELING:
1953     case ABIL_BOLT_OF_DRAINING:
1954         failure = 30 - you.experience_level;
1955         break;
1956 
1957     case ABIL_CONTROL_DEMON:
1958         failure = 35 - you.experience_level;
1959         break;
1960 
1961     case ABIL_SUMMON_DEMON:
1962         failure = 40 - you.experience_level;
1963         break;
1964 
1965     case ABIL_TO_PANDEMONIUM:
1966         failure = 57 - (you.experience_level * 2);
1967         break;
1968 
1969     case ABIL_HELLFIRE:
1970     case ABIL_RAISE_DEAD:
1971         failure = 50 - you.experience_level;
1972         break;
1973 
1974     case ABIL_TORMENT:
1975         failure = 60 - you.experience_level;
1976         break;
1977 
1978     case ABIL_BLINK:
1979         failure = 30 - (10 * you.mutation[MUT_BLINK]) - you.experience_level;
1980         break;
1981 
1982     case ABIL_TELEPORTATION:
1983         failure = ((you.mutation[MUT_TELEPORT_AT_WILL] > 1) ? 30 : 50)
1984                     - you.experience_level;
1985         break;
1986         // end demonic powers {dlb}
1987 
1988         // begin transformation abilities {dlb}
1989     case ABIL_END_TRANSFORMATION:
1990         perfect = true;
1991         failure = 0;
1992         break;
1993 
1994     case ABIL_BREATHE_HELLFIRE:
1995         failure = 32 - you.experience_level;
1996         break;
1997         // end transformation abilities {dlb}
1998         //
1999         // begin item abilities - some possibly mutagenic {dlb}
2000     case ABIL_EVOKE_TURN_INVISIBLE:
2001     case ABIL_EVOKE_TELEPORTATION:
2002         failure = 60 - 2 * you.skills[SK_EVOCATIONS];
2003         break;
2004 
2005     case ABIL_EVOKE_TURN_VISIBLE:
2006     case ABIL_EVOKE_STOP_LEVITATING:
2007         perfect = true;
2008         failure = 0;
2009         break;
2010 
2011     case ABIL_EVOKE_LEVITATE:
2012     case ABIL_EVOKE_BLINK:
2013         failure = 40 - 2 * you.skills[SK_EVOCATIONS];
2014         break;
2015 
2016     case ABIL_EVOKE_BERSERK:
2017         failure = 50 - 2 * you.skills[SK_EVOCATIONS];
2018 
2019         if (you.species == SP_TROLL)
2020             failure -= 30;
2021         else if (player_genus(GENPC_DWARVEN) || you.species == SP_HILL_ORC
2022                 || you.species == SP_OGRE)
2023         {
2024             failure -= 10;
2025         }
2026         break;
2027         // end item abilities - some possibly mutagenic {dlb}
2028 
2029         // begin invocations {dlb}
2030     case ABIL_ELYVILON_PURIFICATION:
2031         invoc = true;
2032         failure = 20 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
2033         break;
2034 
2035     case ABIL_ZIN_REPEL_UNDEAD:
2036     case ABIL_TSO_REPEL_UNDEAD:
2037     case ABIL_KIKU_RECALL_UNDEAD_SLAVES:
2038     case ABIL_OKAWARU_MIGHT:
2039     case ABIL_ELYVILON_LESSER_HEALING:
2040         invoc = true;
2041         failure = 30 - (you.piety / 20) - (6 * you.skills[SK_INVOCATIONS]);
2042         break;
2043 
2044     // These three are Trog abilities... Invocations means nothing -- bwr
2045     case ABIL_TROG_BERSERK:    // piety >= 30
2046         invoc = true;
2047         failure = 30 - you.piety;       // starts at 0%
2048         break;
2049 
2050     case ABIL_TROG_MIGHT:         // piety >= 50
2051         invoc = true;
2052         failure = 80 - you.piety;       // starts at 30%
2053         break;
2054 
2055     case ABIL_TROG_HASTE_SELF:       // piety >= 100
2056         invoc = true;
2057         failure = 160 - you.piety;      // starts at 60%
2058         break;
2059 
2060     case ABIL_YRED_ANIMATE_CORPSE:
2061         invoc = true;
2062         failure = 40 - (you.piety / 20) - (3 * you.skills[SK_INVOCATIONS]);
2063         break;
2064 
2065     case ABIL_ZIN_HEALING:
2066     case ABIL_TSO_SMITING:
2067     case ABIL_OKAWARU_HEALING:
2068     case ABIL_MAKHLEB_MINOR_DESTRUCTION:
2069     case ABIL_SIF_MUNA_FORGET_SPELL:
2070     case ABIL_KIKU_ENSLAVE_UNDEAD:
2071     case ABIL_YRED_ANIMATE_DEAD:
2072     case ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB:
2073     case ABIL_ELYVILON_HEALING:
2074         invoc = true;
2075         failure = 40 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
2076         break;
2077 
2078     case ABIL_VEHUMET_CHANNEL_ENERGY:
2079         invoc = true;
2080         failure = 40 - you.intel - you.skills[SK_INVOCATIONS];
2081         break;
2082 
2083     case ABIL_YRED_RECALL_UNDEAD:
2084         invoc = true;
2085         failure = 50 - (you.piety / 20) - (you.skills[SK_INVOCATIONS] * 4);
2086         break;
2087 
2088     case ABIL_ZIN_PESTILENCE:
2089     case ABIL_TSO_ANNIHILATE_UNDEAD:
2090         invoc = true;
2091         failure = 60 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
2092         break;
2093 
2094     case ABIL_MAKHLEB_MAJOR_DESTRUCTION:
2095     case ABIL_YRED_DRAIN_LIFE:
2096         invoc = true;
2097         failure = 60 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
2098         break;
2099 
2100     case ABIL_ZIN_HOLY_WORD:
2101     case ABIL_TSO_THUNDERBOLT:
2102     case ABIL_ELYVILON_RESTORATION:
2103     case ABIL_YRED_CONTROL_UNDEAD:
2104     case ABIL_OKAWARU_HASTE:
2105     case ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB:
2106         invoc = true;
2107         failure = 70 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
2108         break;
2109 
2110     case ABIL_ZIN_SUMMON_GUARDIAN:
2111     case ABIL_TSO_SUMMON_DAEVA:
2112     case ABIL_KIKU_INVOKE_DEATH:
2113     case ABIL_ELYVILON_GREATER_HEALING:
2114         invoc = true;
2115         failure = 80 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
2116         break;
2117 
2118         //jmf: following for to-be-created gods
2119     case ABIL_CHARM_SNAKE:
2120         invoc = true;
2121         failure = 40 - (you.piety / 20) - (3 * you.skills[SK_INVOCATIONS]);
2122         break;
2123 
2124     case ABIL_TRAN_SERPENT_OF_HELL:
2125         invoc = true;
2126         failure = 80 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
2127         break;
2128 
2129     case ABIL_ROTTING:
2130         invoc = true;
2131         failure = 60 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
2132         break;
2133 
2134     case ABIL_TORMENT_II:
2135         invoc = true;
2136         failure = 70 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
2137         break;
2138 
2139     case ABIL_SHUGGOTH_SEED:
2140         invoc = true;
2141         failure = 85 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 3);
2142         break;
2143 
2144     case ABIL_RENOUNCE_RELIGION:
2145         invoc = true;
2146         perfect = true;
2147         failure = 0;
2148         break;
2149 
2150         // end invocations {dlb}
2151     default:
2152         failure = -1;
2153         break;
2154     }
2155 
2156     // Perfect abilities are things like "renounce religion", which
2157     // shouldn't have a failure rate ever. -- bwr
2158     if (failure <= 0 && !perfect)
2159         failure = 1;
2160 
2161     if (failure > 100)
2162         failure = 100;
2163 
2164     Curr_abil[slot].fail = failure;
2165     Curr_abil[slot].is_invocation = invoc;
2166 
2167     return (true);
2168 }                               // end insert_ability()
2169