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