Branch data Line data Source code
1 : : /* omega copyright (C) by Laurence Raphael Brothers, 1987,1988,1989 */
2 : : /* spell.c */
3 : : /* functions having to do with spellcasting */
4 : :
5 : : #include "glob.h"
6 : :
7 : :
8 : 0 : void s_nutrition(void)
9 : : {
10 : : #ifdef TRADEMARK_VIOLATION
11 : 0 : mprint("Magically Delicious!");
12 : : #else
13 : : mprint("Scrumptious!");
14 : : #endif
15 : 0 : Player.food = 44;
16 : 0 : foodcheck();
17 : 0 : }
18 : :
19 : 0 : void s_wish(void)
20 : : {
21 [ # # ]: 0 : if (random_range(100) > Player.iq+Player.pow+Player.level) {
22 : 0 : mprint("Your concentration is flawed!");
23 : 0 : mprint("The spell energy backfires!");
24 : 0 : p_damage(random_range(Spells[S_WISH].powerdrain),
25 : : UNSTOPPABLE,
26 : : "a backfired wish spell");
27 : : }
28 : : else {
29 : 0 : wish(0);
30 [ # # ]: 0 : if (Spells[S_WISH].known) {
31 : 0 : mprint("The power of the spell is too much for you to withstand!");
32 : 0 : mprint("All memory of the spell is expunged from your brain.");
33 : 0 : Spells[S_WISH].known = FALSE;
34 : : }
35 : : }
36 : 0 : }
37 : :
38 : 0 : void s_firebolt(void)
39 : : {
40 : 0 : int x=Player.x,y=Player.y;
41 : 0 : setspot(&x,&y);
42 : 0 : fbolt(Player.x,Player.y,x,y,Player.dex*2+Player.level,Player.level*10+10);
43 : 0 : }
44 : :
45 : 0 : void s_missile(void)
46 : : {
47 : 0 : int x=Player.x,y=Player.y;
48 : 0 : setspot(&x,&y);
49 : 0 : nbolt(Player.x,Player.y,x,y,Player.dex*2+Player.level,Player.level*3+3);
50 : 0 : }
51 : :
52 : 0 : void s_teleport(void)
53 : : {
54 : 0 : p_teleport(0);
55 : 0 : }
56 : :
57 : 0 : void s_disrupt(void)
58 : : {
59 : 0 : int x=Player.x,y=Player.y;
60 : 0 : setspot(&x,&y);
61 : 0 : disrupt(x,y,Player.level*10+25);
62 : 0 : }
63 : :
64 : :
65 : 0 : void s_disintegrate(void)
66 : : {
67 : 0 : int x=Player.x,y=Player.y;
68 : 0 : setspot(&x,&y);
69 : 0 : disintegrate(x,y);
70 : 0 : }
71 : :
72 : :
73 : 0 : void s_sleep(void)
74 : : {
75 : 0 : sleep_monster(0);
76 : 0 : }
77 : :
78 : 0 : void s_heal(void)
79 : : {
80 : 0 : heal(3);
81 : 0 : }
82 : :
83 : 0 : void s_dispel(void)
84 : : {
85 : 0 : dispel((Player.level+Player.maxpow)/10);
86 : 0 : }
87 : :
88 : 0 : void s_breathe(void)
89 : : {
90 : 0 : breathe(0);
91 : 0 : }
92 : :
93 : 0 : void s_invisible(void)
94 : : {
95 : 0 : invisible(0);
96 : 0 : }
97 : :
98 : :
99 : 0 : void s_warp(void)
100 : : {
101 : 0 : warp(1);
102 : 0 : }
103 : :
104 : 0 : void s_enchant(void)
105 : : {
106 : 0 : enchant(1);
107 : 0 : }
108 : :
109 : :
110 : 0 : void s_bless(void)
111 : : {
112 : 0 : bless(0);
113 : 0 : }
114 : :
115 : :
116 : 0 : void s_restore(void)
117 : : {
118 : 0 : recover_stat(0);
119 : 0 : }
120 : :
121 : :
122 : 0 : void s_cure(void)
123 : : {
124 : 0 : cure(0);
125 : 0 : }
126 : :
127 : :
128 : 0 : void s_truesight(void)
129 : : {
130 : 0 : truesight(0);
131 : 0 : }
132 : :
133 : :
134 : 0 : void s_hellfire(void)
135 : : {
136 : 0 : int x=Player.x,y=Player.y;
137 : 0 : setspot(&x,&y);
138 : 0 : hellfire(x,y,0);
139 : 0 : Spells[S_HELLFIRE].powerdrain *= 2;
140 [ # # ]: 0 : if (Spells[S_HELLFIRE].powerdrain > 90) /* 90 is original casting cost */
141 : : {
142 : 0 : mprint("The power of the spell is too much for you to withstand!");
143 : 0 : mprint("All memory of the spell is expunged from your brain.");
144 : 0 : Spells[S_HELLFIRE].powerdrain = 90;
145 : 0 : Spells[S_HELLFIRE].known = FALSE;
146 : : }
147 : 0 : }
148 : :
149 : :
150 : 0 : void s_knowledge(void)
151 : : {
152 : 0 : knowledge(0);
153 : 0 : }
154 : :
155 : :
156 : 0 : void s_hero(void)
157 : : {
158 : 0 : hero(0);
159 : 0 : }
160 : :
161 : : /* spell takes longer and longer to work deeper into dungeon */
162 : 0 : void s_return(void)
163 : : {
164 : 0 : mprint("You hear a whine as your spell begins to charge up.");
165 : 0 : Player.status[RETURNING] =
166 [ # # ]: 0 : ((Current_Environment == Current_Dungeon) ? difficulty() : 1);
167 : 0 : }
168 : :
169 : 0 : void s_desecrate(void)
170 : : {
171 : 0 : sanctify(-1);
172 : 0 : }
173 : :
174 : :
175 : 0 : void s_haste(void)
176 : : {
177 : 0 : haste(0);
178 : 0 : }
179 : :
180 : :
181 : 0 : void s_summon(void)
182 : : {
183 : 0 : summon(0,-1);
184 : 0 : }
185 : :
186 : :
187 : 0 : void s_sanctuary(void)
188 : : {
189 : 0 : sanctuary();
190 : 0 : }
191 : :
192 : 0 : void s_sanctify(void)
193 : : {
194 : 0 : sanctify(1);
195 : 0 : }
196 : :
197 : :
198 : 0 : void s_accuracy(void)
199 : : {
200 : 0 : accuracy(0);
201 : 0 : }
202 : :
203 : 0 : void s_fear(void)
204 : : {
205 : 0 : int x = Player.x,y=Player.y;
206 : 0 : setspot(&x,&y);
207 : 0 : inflict_fear(x,y);
208 : 0 : }
209 : :
210 : :
211 : : /* Has all kinds of effects in different circumstances.
212 : : Eventually will be more interesting */
213 : 0 : void s_ritual(void)
214 : : {
215 : : pob symbol;
216 : : int i,roomno;
217 : : int x,y;
218 : :
219 : 0 : mprint("You begin your ritual....");
220 : 0 : mprint("You enter a deep trance. Time Passes...");
221 : 0 : setgamestatus(SKIP_PLAYER);
222 : 0 : time_clock(FALSE);
223 : 0 : setgamestatus(SKIP_PLAYER);
224 : 0 : time_clock(FALSE);
225 : 0 : setgamestatus(SKIP_PLAYER);
226 : 0 : time_clock(FALSE);
227 : 0 : setgamestatus(SKIP_PLAYER);
228 : 0 : time_clock(FALSE);
229 : 0 : setgamestatus(SKIP_PLAYER);
230 : 0 : time_clock(FALSE);
231 [ # # ]: 0 : if (RitualHour == hour())
232 : 0 : mprint("Your mental fatigue prevents from completing the ritual!");
233 [ # # ]: 0 : else if (random_range(100) > Player.iq+Player.pow+Player.level)
234 : 0 : mprint("Your concentration was broken -- the ritual fails!");
235 : : else {
236 : 0 : mprint("You charge the ritual with magical energy and focus your will.");
237 : 0 : mprint("Time Passes...");
238 : 0 : setgamestatus(SKIP_PLAYER);
239 : 0 : time_clock(FALSE);
240 : 0 : setgamestatus(SKIP_PLAYER);
241 : 0 : time_clock(FALSE);
242 : 0 : setgamestatus(SKIP_PLAYER);
243 : 0 : time_clock(FALSE);
244 : 0 : setgamestatus(SKIP_PLAYER);
245 : 0 : time_clock(FALSE);
246 : 0 : setgamestatus(SKIP_PLAYER);
247 : 0 : time_clock(FALSE);
248 : 0 : RitualHour = hour();
249 : : /* set of random conditions for different ritual effects */
250 [ # # ]: 0 : if (Current_Environment == E_CITY) {
251 : 0 : mprint("Flowing waves of mystical light congeal all around you.");
252 : 0 : mprint("'Like wow, man! Colors!'");
253 : 0 : mprint("Appreciative citizens throw you spare change.");
254 : 0 : Player.cash +=random_range(50);
255 : : }
256 [ # # ]: 0 : else if ( (roomno=Level->site[Player.x][Player.y].roomnumber) >= ROOMBASE )
257 : : {
258 [ # # ]: 0 : if (RitualRoom == roomno)
259 : 0 : mprint("For some reason the ritual doesn't work this time...");
260 : : else {
261 : 0 : RitualRoom = roomno;
262 [ # # # # : 0 : switch (RitualRoom) {
# # # ]
263 : : case RS_TREASURE: /* ransacked treasure chamber */
264 : 0 : mprint("Your spell sets off frenetic growth all around you!");
265 [ # # ]: 0 : for(i=0;i<8;i++){
266 : 0 : Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].locchar =
267 : : HEDGE;
268 : 0 : Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].p_locf =
269 : : L_TRIFID;
270 : 0 : lset(Player.x+Dirs[0][i], Player.y+Dirs[1][i], CHANGED);
271 : : }
272 : 0 : break;
273 : : case RS_HAREM: /* harem */
274 : : case RS_BOUDOIR: /* boudoir */
275 : 0 : mprint("A secret panel opens next to the bed....");
276 [ # # ]: 0 : if (random_range(2))
277 : 0 : summon(0,INCUBUS); /* succubus/incubus */
278 : 0 : else summon(0,SATYR); /* satyr/nymph */
279 : 0 : break;
280 : : case RS_SHRINE: /*shrine to high magic */
281 : 0 : mprint("A storm of mana coaelesces around you.");
282 : 0 : mprint("You are buffeted by bursts of random magic.");
283 : 0 : p_damage(random_range(Player.pow),UNSTOPPABLE,"high magic");
284 : 0 : mprint("Continue ritual? Could be dangerous.... [yn] ");
285 [ # # ]: 0 : if (ynq()=='y') s_wish();
286 : 0 : else mprint("The mana fades away to nothingness.");
287 : 0 : x = Player.x;
288 : 0 : y = Player.y;
289 [ # # ][ # # ]: 0 : while (x >= 0 && Level->site[x - 1][y].roomnumber == RS_SHRINE)
290 : 0 : x--;
291 [ # # ][ # # ]: 0 : while (y >= 0 && Level->site[x][y - 1].roomnumber == RS_SHRINE)
292 : 0 : y--;
293 [ # # ]: 0 : for (i = 0; Level->site[x][y].roomnumber == RS_SHRINE;) {
294 : 0 : Level->site[x][y].roomnumber = RS_ZORCH;
295 : 0 : lset(x, y, CHANGED);
296 : 0 : x++;
297 : 0 : i++;
298 [ # # ]: 0 : if (Level->site[x][y].roomnumber != RS_SHRINE) {
299 : 0 : x -= i;
300 : 0 : i = 0;
301 : 0 : y++;
302 : : }
303 : : }
304 : 0 : break;
305 : : case RS_MAGIC_LAB: /* magician's lab */
306 : 0 : mprint("Your magical activity sets off a latent spell in the lab!");
307 : 0 : cast_spell(random_range(NUMSPELLS));
308 : 0 : break;
309 : : case RS_PENTAGRAM: /* pentagram room */
310 : 0 : mprint("A smoky form begins to coalesce....");
311 : 0 : summon(-1,-1);
312 : 0 : mprint("Fortunately, it seems confined to the pentagram.");
313 : 0 : m_status_reset(Level->mlist->m,MOBILE);
314 : 0 : break;
315 : : case RS_OMEGA_DAIS: /* blue omega room */
316 : 0 : mprint("The Lords of Destiny look upon you....");
317 [ # # ]: 0 : if (Player.level > 10) {
318 : 0 : mprint("A curtain of blue flames leaps up from the omega.");
319 : 0 : morewait();
320 : 0 : l_adept();
321 : : }
322 : : else {
323 [ # # ]: 0 : if (Player.patron == DESTINY) {
324 : 0 : mprint("Your patrons take pity on you.");
325 [ # # # # ]: 0 : if ((Player.rank[PRIESTHOOD]<SPRIEST) &&
326 : 0 : (! find_item(&symbol,OB_SYMBOL_DESTINY,-1))) {
327 : 0 : symbol = ((pob) checkmalloc(sizeof(objtype)));
328 : 0 : *symbol = Objects[OB_SYMBOL_DESTINY];
329 : 0 : symbol->known = 2;
330 : 0 : symbol->charge = 17;
331 : 0 : gain_item(symbol);
332 : 0 : mprint("You feel uplifted.");
333 : : }
334 : 0 : else gain_experience(min(1000,Player.xp));
335 : : }
336 [ # # ]: 0 : else if (random_range(3)==1) {
337 : 0 : mprint("You feel Fated.");
338 : 0 : gain_experience(Player.level*Player.level*10);
339 : 0 : Player.hp = max(Player.hp, Player.maxhp);
340 : : }
341 [ # # ]: 0 : else if (random_range(2)) {
342 : 0 : mprint("You feel Doomed.");
343 : 0 : Player.hp = 1;
344 : 0 : Player.mana = 0;
345 : 0 : Player.xp = 0;
346 : : }
347 : 0 : else mprint("The Lords of Destiny laugh at you!");
348 : : }
349 : 0 : break;
350 : : default:
351 : 0 : mprint("Well, not much effect. Chalk it up to experience.");
352 : 0 : gain_experience(Player.level*5);
353 : 0 : break;
354 : : }
355 : : }
356 : : }
357 : : else {
358 [ # # ]: 0 : if (RitualRoom == Level->site[Player.x][Player.y].roomnumber)
359 : 0 : mprint("The ritual fails for some unexplainable reason.");
360 : : else {
361 : 0 : mprint("The ritual seems to be generating some spell effect.");
362 : 0 : RitualRoom = Level->site[Player.x][Player.y].roomnumber;
363 [ # # # # : 0 : switch (RitualRoom) {
# ]
364 : : case RS_WALLSPACE:
365 : 0 : shadowform();
366 : 0 : break;
367 : : case RS_CORRIDOR:
368 : 0 : haste(0);
369 : 0 : break;
370 : : case RS_PONDS:
371 : 0 : breathe(0);
372 : 0 : break;
373 : : case RS_ADEPT:
374 : 0 : hero(1);
375 : 0 : break;
376 : : default:
377 : 0 : mprint("The ritual doesn't seem to produce any tangible results...");
378 : 0 : gain_experience(Player.level*6);
379 : : }
380 : : }
381 : : }
382 : : }
383 : 0 : }
384 : :
385 : :
386 : :
387 : 0 : void s_apport(void)
388 : : {
389 : 0 : apport(0);
390 : 0 : }
391 : :
392 : 0 : void s_shadowform(void)
393 : : {
394 : 0 : shadowform();
395 : 0 : }
396 : :
397 : 0 : void s_alert(void)
398 : : {
399 : 0 : alert(0);
400 : 0 : }
401 : :
402 : 0 : void s_regenerate(void)
403 : : {
404 : 0 : regenerate(0);
405 : 0 : }
406 : :
407 : 0 : void s_clairvoyance(void)
408 : : {
409 : 0 : clairvoyance(10);
410 : 0 : }
411 : :
412 : 0 : void s_drain(void)
413 : : {
414 : 0 : drain(0);
415 : 0 : }
416 : :
417 : 0 : void s_levitate(void)
418 : : {
419 : 0 : levitate(0);
420 : 0 : }
421 : :
422 : 0 : void s_polymorph(void)
423 : : {
424 : 0 : polymorph(0);
425 : 0 : }
426 : :
427 : :
428 : : /* lball spell */
429 : 0 : void s_lball(void)
430 : : {
431 : 0 : int x=Player.x,y=Player.y;
432 : 0 : setspot(&x,&y);
433 : 0 : lball(Player.x,Player.y,x,y,Player.level*10+10);
434 : 0 : }
435 : :
436 : 0 : void s_identify(void)
437 : : {
438 : 0 : identify(0);
439 : 0 : }
440 : :
441 : 0 : void s_objdet(void)
442 : : {
443 : 0 : objdet(1);
444 : 0 : }
445 : :
446 : 0 : void s_mondet(void)
447 : : {
448 : 0 : mondet(1);
449 : 0 : }
450 : :
451 : :
452 : : /* select a spell to cast */
453 : 0 : int getspell(void)
454 : : {
455 : 0 : int spell= ABORT - 1;
456 : :
457 : : do {
458 : 0 : mprint("Cast Spell: [type spell abbrev, ?, or ESCAPE]: ");
459 : 0 : spell = spellparse();
460 [ # # ]: 0 : } while (spell < ABORT);
461 : 0 : return(spell);
462 : : }
463 : :
464 : :
465 : 0 : char *spellid(int id)
466 : : {
467 [ # # # # : 0 : switch(id) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
468 : 0 : case S_MON_DET:return("monster detection");
469 : 0 : case S_OBJ_DET:return("object detection");
470 : 0 : case S_IDENTIFY:return("identification");
471 : 0 : case S_FIREBOLT:return("firebolt");
472 : 0 : case S_LBALL:return("ball lightning");
473 : 0 : case S_SLEEP:return("sleep");
474 : 0 : case S_DISRUPT:return("disrupt");
475 : 0 : case S_DISINTEGRATE:return("disintegrate");
476 : 0 : case S_TELEPORT:return("teleport");
477 : 0 : case S_MISSILE:return("magic missile");
478 : 0 : case S_HEAL:return("healing");
479 : 0 : case S_DISPEL:return("dispelling");
480 : 0 : case S_BREATHE:return("breathing");
481 : 0 : case S_INVISIBLE:return("invisibility");
482 : 0 : case S_WARP:return("the warp");
483 : 0 : case S_ENCHANT:return("enchantment");
484 : 0 : case S_BLESS:return("blessing");
485 : 0 : case S_RESTORE:return("restoration");
486 : 0 : case S_CURE:return("curing");
487 : 0 : case S_TRUESIGHT:return("true sight");
488 : 0 : case S_HELLFIRE:return("hellfire");
489 : 0 : case S_KNOWLEDGE:return("self knowledge");
490 : 0 : case S_HERO:return("heroism");
491 : 0 : case S_RETURN:return("return");
492 : 0 : case S_DESECRATE:return("desecration");
493 : 0 : case S_HASTE:return("haste");
494 : 0 : case S_SUMMON:return("summoning");
495 : 0 : case S_SANCTUARY:return("sanctuary");
496 : 0 : case S_ACCURACY:return("accuracy");
497 : 0 : case S_RITUAL:return("ritual magic");
498 : 0 : case S_APPORT:return("apportation");
499 : 0 : case S_SHADOWFORM:return("shadow form");
500 : 0 : case S_ALERT:return("alertness");
501 : 0 : case S_REGENERATE:return("regeneration");
502 : 0 : case S_SANCTIFY:return("sanctification");
503 : 0 : case S_CLAIRVOYANCE:return("clairvoyance");
504 : 0 : case S_DRAIN:return("energy drain");
505 : 0 : case S_LEVITATE:return("levitate");
506 : 0 : case S_POLYMORPH:return("polymorph");
507 : 0 : case S_FEAR:return("fear");
508 : 0 : case S_WISH:return("wishing");
509 : 0 : case S_NUTRITION:return("nutrition");
510 : 0 : default:return("???");
511 : : }
512 : : }
513 : :
514 : :
515 : :
516 : 1 : void initspells(void)
517 : : {
518 : : int i;
519 : :
520 [ + + ]: 43 : for (i=0; i<NUMSPELLS; i++)
521 : 42 : Spells[i].known = FALSE;
522 : :
523 : 1 : Spells[S_MON_DET].powerdrain = 3;
524 : 1 : Spells[S_MON_DET].id = S_MON_DET;
525 : :
526 : 1 : Spells[S_OBJ_DET].powerdrain = 3;
527 : 1 : Spells[S_OBJ_DET].id = S_OBJ_DET;
528 : :
529 : 1 : Spells[S_IDENTIFY].powerdrain = 10;
530 : 1 : Spells[S_IDENTIFY].id = S_IDENTIFY;
531 : :
532 : 1 : Spells[S_FIREBOLT].powerdrain = 20;
533 : 1 : Spells[S_FIREBOLT].id = S_FIREBOLT;
534 : :
535 : 1 : Spells[S_SLEEP].powerdrain = 15;
536 : 1 : Spells[S_SLEEP].id = S_SLEEP;
537 : :
538 : 1 : Spells[S_LBALL].powerdrain = 25;
539 : 1 : Spells[S_LBALL].id = S_LBALL;
540 : :
541 : 1 : Spells[S_TELEPORT].powerdrain = 20;
542 : 1 : Spells[S_TELEPORT].id = S_TELEPORT;
543 : :
544 : 1 : Spells[S_DISRUPT].powerdrain = 30;
545 : 1 : Spells[S_DISRUPT].id = S_DISRUPT;
546 : :
547 : 1 : Spells[S_DISINTEGRATE].powerdrain = 40;
548 : 1 : Spells[S_DISINTEGRATE].id = S_DISINTEGRATE;
549 : :
550 : 1 : Spells[S_MISSILE].powerdrain = 10;
551 : 1 : Spells[S_MISSILE].id = S_MISSILE;
552 : :
553 : 1 : Spells[S_HEAL].powerdrain = 15;
554 : 1 : Spells[S_HEAL].id = S_HEAL;
555 : :
556 : 1 : Spells[S_DISPEL].powerdrain = 40;
557 : 1 : Spells[S_DISPEL].id = S_DISPEL;
558 : :
559 : 1 : Spells[S_BREATHE].powerdrain = 20;
560 : 1 : Spells[S_BREATHE].id = S_BREATHE;
561 : :
562 : 1 : Spells[S_INVISIBLE].powerdrain = 15;
563 : 1 : Spells[S_INVISIBLE].id = S_INVISIBLE;
564 : :
565 : 1 : Spells[S_WARP].powerdrain = 50;
566 : 1 : Spells[S_WARP].id = S_WARP;
567 : :
568 : 1 : Spells[S_ENCHANT].powerdrain = 30;
569 : 1 : Spells[S_ENCHANT].id = S_ENCHANT;
570 : :
571 : 1 : Spells[S_BLESS].powerdrain = 30;
572 : 1 : Spells[S_BLESS].id = S_BLESS;
573 : :
574 : 1 : Spells[S_RESTORE].powerdrain = 20;
575 : 1 : Spells[S_RESTORE].id = S_RESTORE;
576 : :
577 : 1 : Spells[S_CURE].powerdrain = 20;
578 : 1 : Spells[S_CURE].id = S_CURE;
579 : :
580 : 1 : Spells[S_TRUESIGHT].powerdrain = 20;
581 : 1 : Spells[S_TRUESIGHT].id = S_TRUESIGHT;
582 : :
583 : 1 : Spells[S_HELLFIRE].powerdrain = 90;
584 : 1 : Spells[S_HELLFIRE].id = S_HELLFIRE;
585 : :
586 : 1 : Spells[S_KNOWLEDGE].powerdrain = 10;
587 : 1 : Spells[S_KNOWLEDGE].id = S_KNOWLEDGE;
588 : :
589 : 1 : Spells[S_HERO].powerdrain = 20;
590 : 1 : Spells[S_HERO].id = S_HERO;
591 : :
592 : 1 : Spells[S_RETURN].powerdrain = 10;
593 : 1 : Spells[S_RETURN].id = S_RETURN;
594 : :
595 : 1 : Spells[S_DESECRATE].powerdrain = 50;
596 : 1 : Spells[S_DESECRATE].id = S_DESECRATE;
597 : :
598 : 1 : Spells[S_HASTE].powerdrain = 15;
599 : 1 : Spells[S_HASTE].id = S_HASTE;
600 : :
601 : 1 : Spells[S_SUMMON].powerdrain = 20;
602 : 1 : Spells[S_SUMMON].id = S_SUMMON;
603 : :
604 : 1 : Spells[S_SANCTUARY].powerdrain = 75;
605 : 1 : Spells[S_SANCTUARY].id = S_SANCTUARY;
606 : :
607 : 1 : Spells[S_ACCURACY].powerdrain = 20;
608 : 1 : Spells[S_ACCURACY].id = S_ACCURACY;
609 : :
610 : 1 : Spells[S_RITUAL].powerdrain = 50;
611 : 1 : Spells[S_RITUAL].id = S_RITUAL;
612 : :
613 : 1 : Spells[S_APPORT].powerdrain = 15;
614 : 1 : Spells[S_APPORT].id = S_APPORT;
615 : :
616 : 1 : Spells[S_SHADOWFORM].powerdrain = 50;
617 : 1 : Spells[S_SHADOWFORM].id = S_SHADOWFORM;
618 : :
619 : 1 : Spells[S_ALERT].powerdrain = 15;
620 : 1 : Spells[S_ALERT].id = S_ALERT;
621 : :
622 : 1 : Spells[S_REGENERATE].powerdrain = 20;
623 : 1 : Spells[S_REGENERATE].id = S_REGENERATE;
624 : :
625 : 1 : Spells[S_SANCTIFY].powerdrain = 75;
626 : 1 : Spells[S_SANCTIFY].id = S_SANCTIFY;
627 : :
628 : 1 : Spells[S_CLAIRVOYANCE].powerdrain = 10;
629 : 1 : Spells[S_CLAIRVOYANCE].id = S_CLAIRVOYANCE;
630 : :
631 : 1 : Spells[S_DRAIN].powerdrain = 40;
632 : 1 : Spells[S_DRAIN].id = S_DRAIN;
633 : :
634 : 1 : Spells[S_LEVITATE].powerdrain = 25;
635 : 1 : Spells[S_LEVITATE].id = S_LEVITATE;
636 : :
637 : 1 : Spells[S_POLYMORPH].powerdrain = 30;
638 : 1 : Spells[S_POLYMORPH].id = S_POLYMORPH;
639 : :
640 : 1 : Spells[S_FEAR].powerdrain = 10;
641 : 1 : Spells[S_FEAR].id = S_FEAR;
642 : :
643 : 1 : Spells[S_WISH].powerdrain = 100;
644 : 1 : Spells[S_WISH].id = S_WISH;
645 : :
646 : 1 : Spells[S_NUTRITION].powerdrain = 25;
647 : 1 : Spells[S_NUTRITION].id = S_NUTRITION;
648 : :
649 : 1 : }
650 : :
651 : :
652 : :
653 : :
654 : :
655 : :
656 : 0 : void cast_spell(int spell)
657 : : {
658 [ # # # # : 0 : switch(spell) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
659 : 0 : case S_MON_DET:s_mondet();
660 : 0 : break;
661 : 0 : case S_OBJ_DET:s_objdet();
662 : 0 : break;
663 : 0 : case S_IDENTIFY:s_identify();
664 : 0 : break;
665 : 0 : case S_FIREBOLT:s_firebolt();
666 : 0 : break;
667 : 0 : case S_SLEEP:s_sleep();
668 : 0 : break;
669 : 0 : case S_LBALL:s_lball();
670 : 0 : break;
671 : 0 : case S_TELEPORT:s_teleport();
672 : 0 : break;
673 : 0 : case S_DISRUPT:s_disrupt();
674 : 0 : break;
675 : 0 : case S_DISINTEGRATE:s_disintegrate();
676 : 0 : break;
677 : 0 : case S_MISSILE:s_missile();
678 : 0 : break;
679 : 0 : case S_HEAL:s_heal();
680 : 0 : break;
681 : 0 : case S_DISPEL:s_dispel();
682 : 0 : break;
683 : 0 : case S_BREATHE:s_breathe();
684 : 0 : break;
685 : 0 : case S_INVISIBLE:s_invisible();
686 : 0 : break;
687 : 0 : case S_WARP:s_warp();
688 : 0 : break;
689 : 0 : case S_ENCHANT:s_enchant();
690 : 0 : break;
691 : 0 : case S_BLESS:s_bless();
692 : 0 : break;
693 : 0 : case S_RESTORE:s_restore();
694 : 0 : break;
695 : 0 : case S_CURE:s_cure();
696 : 0 : break;
697 : 0 : case S_TRUESIGHT:s_truesight();
698 : 0 : break;
699 : 0 : case S_HELLFIRE:s_hellfire();
700 : 0 : break;
701 : 0 : case S_KNOWLEDGE:s_knowledge();
702 : 0 : break;
703 : 0 : case S_HERO:s_hero();
704 : 0 : break;
705 : 0 : case S_RETURN:s_return();
706 : 0 : break;
707 : 0 : case S_DESECRATE:s_desecrate();
708 : 0 : break;
709 : 0 : case S_HASTE:s_haste();
710 : 0 : break;
711 : 0 : case S_SUMMON:s_summon();
712 : 0 : break;
713 : 0 : case S_SANCTUARY:s_sanctuary();
714 : 0 : break;
715 : 0 : case S_ACCURACY:s_accuracy();
716 : 0 : break;
717 : 0 : case S_RITUAL:s_ritual();
718 : 0 : break;
719 : 0 : case S_APPORT:s_apport();
720 : 0 : break;
721 : 0 : case S_SHADOWFORM:s_shadowform();
722 : 0 : break;
723 : 0 : case S_ALERT:s_alert();
724 : 0 : break;
725 : 0 : case S_REGENERATE:s_regenerate();
726 : 0 : break;
727 : 0 : case S_SANCTIFY:s_sanctify();
728 : 0 : break;
729 : 0 : case S_CLAIRVOYANCE:s_clairvoyance();
730 : 0 : break;
731 : 0 : case S_DRAIN:s_drain();
732 : 0 : break;
733 : 0 : case S_LEVITATE:s_levitate();
734 : 0 : break;
735 : 0 : case S_FEAR:s_fear();
736 : 0 : break;
737 : 0 : case S_POLYMORPH:s_polymorph();
738 : 0 : break;
739 : 0 : case S_WISH:s_wish();
740 : 0 : break;
741 : 0 : case S_NUTRITION:s_nutrition();
742 : 0 : break;
743 : 0 : default: mprint("Your odd spell fizzles with a small 'sput'.");
744 : 0 : break;
745 : : }
746 : 0 : }
747 : :
748 : :
749 : :
750 : : static char *spell_names[] = { /* alphabetical listing */
751 : : "accuracy", "alertness", "apportation", "ball lightning", "blessing",
752 : : "breathing", "clairvoyance", "curing", "desecration", "disintegrate",
753 : : "dispelling", "disrupt", "enchantment", "energy drain", "fear", "firebolt",
754 : : "haste", "healing", "hellfire", "heroism", "identification", "invisibility",
755 : : "levitate", "magic missile", "monster detection", "nutrition", "object detection",
756 : : "polymorph", "regeneration", "restoration", "return", "ritual magic",
757 : : "sanctification", "sanctuary", "self knowledge", "shadow form", "sleep",
758 : : "summoning", "teleport", "the warp", "true sight", "wishing" };
759 : :
760 : : static int spell_ids[] = { /* in the same order as spell_names[] */
761 : : S_ACCURACY, S_ALERT, S_APPORT, S_LBALL, S_BLESS, S_BREATHE, S_CLAIRVOYANCE,
762 : : S_CURE, S_DESECRATE, S_DISINTEGRATE, S_DISPEL, S_DISRUPT, S_ENCHANT, S_DRAIN,
763 : : S_FEAR, S_FIREBOLT, S_HASTE, S_HEAL, S_HELLFIRE, S_HERO, S_IDENTIFY,
764 : : S_INVISIBLE, S_LEVITATE, S_MISSILE, S_MON_DET, S_NUTRITION, S_OBJ_DET, S_POLYMORPH,
765 : : S_REGENERATE, S_RESTORE, S_RETURN, S_RITUAL, S_SANCTIFY, S_SANCTUARY,
766 : : S_KNOWLEDGE, S_SHADOWFORM, S_SLEEP, S_SUMMON, S_TELEPORT, S_WARP, S_TRUESIGHT,
767 : : S_WISH };
768 : :
769 : 0 : void showknownspells(int first, int last)
770 : : {
771 : 0 : int i,printed=FALSE;
772 : :
773 : 0 : menuclear();
774 : 0 : menuprint("\nPossible Spells:\n");
775 [ # # ]: 0 : for (i = first; i <= last; i++)
776 [ # # ]: 0 : if (Spells[spell_ids[i]].known) {
777 : 0 : printed = TRUE;
778 : 0 : menuprint(spell_names[i]);
779 : 0 : menuprint(" (");
780 : 0 : menunumprint(Spells[spell_ids[i]].powerdrain);
781 : 0 : menuprint(" mana)");
782 : 0 : menuprint("\n");
783 : : }
784 [ # # ]: 0 : if (! printed)
785 : 0 : menuprint("\nNo spells match that prefix!");
786 : 0 : showmenu();
787 : 0 : }
788 : :
789 : 0 : int spellparse(void)
790 : : {
791 : : int first, last, pos;
792 : : char byte, prefix[80];
793 : 0 : int found = 0;
794 : : int f, l;
795 : :
796 : 0 : first = 0;
797 [ # # ][ # # ]: 0 : while (first < NUMSPELLS && !Spells[spell_ids[first]].known)
798 : 0 : first++;
799 [ # # ]: 0 : if (first == NUMSPELLS) {
800 : 0 : print1("You don't know any spells!");
801 : 0 : return ABORT;
802 : : }
803 : 0 : last = NUMSPELLS - 1;
804 : 0 : pos = 0;
805 : 0 : print2("");
806 : : do {
807 : 0 : byte = mgetc();
808 [ # # ][ # # ]: 0 : if (byte == BACKSPACE || byte == DELETE) {
809 [ # # ]: 0 : if (pos > 0) {
810 : 0 : prefix[--pos] = '\0';
811 : 0 : byte = prefix[pos - 1];
812 : 0 : f = first;
813 [ # # ][ # # ]: 0 : while (f >= 0 && !strncmp(prefix, spell_names[f], pos)) {
814 [ # # ]: 0 : if (Spells[spell_ids[f]].known)
815 : 0 : first = f;
816 : 0 : f--;
817 : : }
818 : 0 : l = last;
819 [ # # ][ # # ]: 0 : while (l < NUMSPELLS && !strncmp(prefix, spell_names[l], pos)) {
820 [ # # ]: 0 : if (Spells[spell_ids[l]].known)
821 : 0 : last = l;
822 : 0 : l++;
823 : : }
824 [ # # ]: 0 : if (found)
825 : 0 : found = 0;
826 : 0 : print2(prefix);
827 : : }
828 [ # # ]: 0 : if (pos == 0) {
829 : 0 : first = 0;
830 : 0 : last = NUMSPELLS - 1;
831 : 0 : found = 0;
832 : 0 : print2("");
833 : : }
834 : : }
835 [ # # ]: 0 : else if (byte == ESCAPE) {
836 : 0 : xredraw();
837 : 0 : return ABORT;
838 : : }
839 [ # # ]: 0 : else if (byte == '?')
840 : 0 : showknownspells(first, last);
841 [ # # ]: 0 : else if (byte != '\n') {
842 [ # # ][ # # ]: 0 : if (byte >= 'A' && byte <= 'Z')
843 : 0 : byte += 'a' - 'A';
844 [ # # ]: 0 : if (found)
845 : 0 : continue;
846 : 0 : f = first;
847 : 0 : l = last;
848 [ # # ][ # # ]: 0 : while (f < NUMSPELLS &&
849 [ # # ]: 0 : (!Spells[spell_ids[f]].known ||
850 [ # # ]: 0 : strlen(spell_names[f]) < pos || spell_names[f][pos] < byte))
851 : 0 : f++;
852 [ # # ][ # # ]: 0 : while (l >= 0 && (!Spells[spell_ids[l]].known ||
[ # # ]
853 [ # # ]: 0 : strlen(spell_names[l]) < pos || spell_names[l][pos] > byte))
854 : 0 : l--;
855 [ # # ]: 0 : if (l < f)
856 : 0 : continue;
857 : 0 : prefix[pos++] = byte;
858 : 0 : prefix[pos] = '\0';
859 : 0 : nprint2(prefix + pos - 1);
860 : 0 : first = f;
861 : 0 : last = l;
862 [ # # ][ # # ]: 0 : if (first == last && !found) { /* unique name */
863 : 0 : found = 1;
864 : 0 : nprint2(spell_names[first] + pos);
865 : : }
866 : : }
867 [ # # ]: 0 : } while (byte != '\n');
868 : 0 : xredraw();
869 [ # # ]: 0 : if (found)
870 : 0 : return spell_ids[first];
871 : : else {
872 : 0 : print3("That is an ambiguous abbreviation!");
873 : 0 : return ABORT;
874 : : }
875 : : }
|