1 #include <stdio.h>
2 #include <strings.h>
3
4 #include "handwave.h"
5 #include "internal.h"
6
7 char exbuf[2048], exbuf2[2048], exbuf3[2048];
8 static char smallbuf[512];
9 static int summonelq;
10
11 static void exec_counters(), exec_summons(), check_elements(), exec_cancels(), exec_protects();
12 extern void exec_enchants(), exec_attacks(), exec_heals();
13
clear_round(fred)14 void clear_round(fred)
15 union being *fred;
16 {
17 int ix;
18
19 fred->both.enchant_caster = (-1);
20 fred->both.enchant_ppend = 0;
21 fred->both.raisedead_caster = (-1);
22 fred->both.fl_resist_heat = 0;
23 fred->both.fl_resist_cold = 0;
24 fred->both.fl_resist_icestorm = 0;
25
26 for (ix=0; ix<NUMSPELLS; ix++)
27 fred->both.zaplist[ix] = 0;
28 }
29
30 /* add a zaplist entry. If the spell is a control spell, set the enchant_caster also; this can only store one value, but that's ok, since if there's more than one control spell they all fail. If the spell is raise dead, set raisedead_caster (only used when raising dead monsters) */
set_zap_flag(self,spel,spelnum)31 static void set_zap_flag(self, spel, spelnum)
32 struct realgame *self;
33 struct castspell *spel;
34 int spelnum;
35 {
36 int set_enchanter=0, set_ppend=0;
37 struct permstats *perm = NULL;
38 int *ppend = NULL;
39
40 if (spelnum==(-1))
41 spelnum = spel->spellnum;
42
43 if (spelnum==SP__PARALYSIS || spelnum==SP__CHARM_PERSON || spelnum==SP__CHARM_MONSTER) {
44 set_enchanter=1;
45 }
46
47 if (spelnum==SP__PARALYSIS || spelnum==SP__CHARM_PERSON || spelnum==SP__CHARM_MONSTER || spelnum==SP__FEAR || spelnum==SP__AMNESIA || spelnum==SP__CONFUSION) {
48 set_ppend=1;
49 }
50
51 switch (spel->targettype) {
52 case QuVal_Target_Wizard:
53 perm = &(self->wiz[spel->target]->perm);
54 ppend = &(self->wiz[spel->target]->enchant_ppend);
55 self->wiz[spel->target]->zaplist[spelnum]++;
56 if (set_enchanter)
57 self->wiz[spel->target]->enchant_caster = spel->caster;
58 if (set_ppend)
59 *ppend = spel->permanent;
60 if (spelnum==SP__RAISE_DEAD)
61 self->wiz[spel->target]->raisedead_caster = spel->caster;
62 break;
63 case QuVal_Target_Creature:
64 perm = &(self->cre[spel->target].perm);
65 ppend = &(self->cre[spel->target].enchant_ppend);
66 self->cre[spel->target].zaplist[spelnum]++;
67 if (set_enchanter)
68 self->cre[spel->target].enchant_caster = spel->caster;
69 if (set_ppend)
70 *ppend = spel->permanent;
71 if (spelnum==SP__RAISE_DEAD)
72 self->cre[spel->target].raisedead_caster = spel->caster;
73 break;
74 default: /* up-in-air or area-effect */
75 break;
76 }
77
78 if (spel->permanent && perm) {
79 struct wizard *wiz = self->wiz[spel->target];
80 switch (spelnum) {
81 case SP__AMNESIA:
82 case SP__FEAR:
83 case SP__CHARM_PERSON:
84 case SP__CHARM_MONSTER:
85 case SP__PARALYSIS:
86 case SP__CONFUSION:
87 break;
88 case SP__HASTE:
89 perm->fl_haste = 1;
90 break;
91 case SP__PROTECTION_FROM_EVIL:
92 perm->fl_prot_evil = 1;
93 break;
94 case SP__RESIST_HEAT:
95 perm->fl_resist_heat = 1;
96 break;
97 case SP__RESIST_COLD:
98 perm->fl_resist_cold = 1;
99 break;
100 case SP__INVISIBILITY:
101 perm->fl_invisibility = 1;
102 break;
103 case SP__BLINDNESS:
104 perm->fl_blindness = 1;
105 break;
106 default:
107 printf("ERROR: do not know how to permanent %d.\n", spelnum);
108 break;
109 }
110 }
111 }
112
pro_himself(gender)113 char *pro_himself(gender)
114 int gender;
115 {
116 switch (gender) {
117 case Gender_NONE:
118 return "itself";
119 case Gender_MALE:
120 return "himself";
121 case Gender_FEMALE:
122 return "herself";
123 case Gender_NEUTER:
124 return "hirself";
125 default:
126 return "ERROR-himself";
127 }
128 }
129
pro_him(gender)130 char *pro_him(gender)
131 int gender;
132 {
133 switch (gender) {
134 case Gender_NONE:
135 return "it";
136 case Gender_MALE:
137 return "him";
138 case Gender_FEMALE:
139 return "her";
140 case Gender_NEUTER:
141 return "hir";
142 default:
143 return "ERROR-him";
144 }
145 }
146
pro_he(gender)147 char *pro_he(gender)
148 int gender;
149 {
150 switch (gender) {
151 case Gender_NONE:
152 return "it";
153 case Gender_MALE:
154 return "he";
155 case Gender_FEMALE:
156 return "she";
157 case Gender_NEUTER:
158 return "ke";
159 default:
160 return "ERROR-he";
161 }
162 }
163
pro_his(gender)164 char *pro_his(gender) /* his head, not the head of his */
165 int gender;
166 {
167 switch (gender) {
168 case Gender_NONE:
169 return "its";
170 case Gender_MALE:
171 return "his";
172 case Gender_FEMALE:
173 return "her";
174 case Gender_NEUTER:
175 return "hir";
176 default:
177 return "ERROR-his";
178 }
179 }
180
number_name(num)181 char *number_name(num)
182 int num;
183 {
184 static char buf[16];
185
186 switch (num) {
187 case 0:
188 return "zero";
189 case 1:
190 return "one";
191 case 2:
192 return "two";
193 case 3:
194 return "three";
195 case 4:
196 return "four";
197 case 5:
198 return "five";
199 case 6:
200 return "six";
201 case 7:
202 return "seven";
203 case 8:
204 return "eight";
205 case 9:
206 return "nine";
207 case 10:
208 return "ten";
209 default:
210 sprintf(buf, "%d", num);
211 return buf;
212 }
213 }
214
list_mind_spells(buf,zapl)215 static void list_mind_spells(buf, zapl)
216 char *buf;
217 int *zapl;
218 {
219 int any = 0;
220 int ix, spel;
221 static int spelist[6] = {SP__AMNESIA, SP__CONFUSION, SP__CHARM_PERSON, SP__CHARM_MONSTER, SP__PARALYSIS, SP__FEAR};
222 strcpy(buf, "");
223
224 for (ix=0; ix<6; ix++) {
225 spel = spelist[ix];
226 if (zapl[spel]) {
227 if (any)
228 strcat(buf, ", ");
229 any = 1;
230 if (zapl[spel]==1) {
231 strcat(buf, spelllist[spel].name);
232 }
233 else {
234 sprintf(smallbuf, "%s %s", number_name(zapl[spel]), spelllist[spel].name);
235 strcat(buf, smallbuf);
236 }
237 }
238 }
239 }
240
check_visibility(self,mcaster,mtarget,ctmp)241 static int check_visibility(self, mcaster, mtarget, ctmp)
242 struct realgame *self;
243 struct wizard *mcaster;
244 union being *mtarget;
245 struct castspell *ctmp;
246 {
247 if (!mtarget)
248 return 1; /* you can always see up-in-the-air */
249
250 if ((union being *)mcaster != mtarget
251 && (mtarget->both.invisibility || mcaster->blindness)) {
252 sprintf(exbuf, "You are unable to see %s; your %s goes wild.\n", mtarget->both.name, spelllist[ctmp->spellnum].name);
253 sprintf(exbuf2, "%s is unable to see you; %s %s goes wild.\n", mcaster->name, pro_his(mcaster->gender), spelllist[ctmp->spellnum].name);
254 sprintf(exbuf3, "%s is unable to see %s; %s %s goes wild.\n", mcaster->name, mtarget->both.name, pro_his(mcaster->gender), spelllist[ctmp->spellnum].name);
255 if (ctmp->targettype==QuVal_Target_Wizard)
256 PrintMsg3(ctmp->caster, ctmp->target, exbuf, exbuf2, exbuf3);
257 else
258 PrintMsg2(ctmp->caster, exbuf, exbuf3);
259 return 0;
260 }
261 return 1;
262 }
263
execute_spells(self)264 void execute_spells(self)
265 struct realgame *self;
266 {
267 struct castspell *ctmp, **pt;
268 int ix, jx, wiznum;
269 int *zapl;
270 union being *mtarget;
271 struct wizard *mcaster;
272
273 for (ctmp = self->castlist; ctmp; ctmp = ctmp->next) {
274 char *handage;
275 switch (ctmp->handage) {
276 case MASK_LEFT:
277 handage = "with the left hand";
278 break;
279 case MASK_RIGHT:
280 handage = "with the right hand";
281 break;
282 case MASK_TWOHAND:
283 handage = "with both hands";
284 break;
285 case 0:
286 handage = "from a Delayed Effect";
287 break;
288 case MASK_LEFT|MASK_RIGHT:
289 handage = "ERROR:BOTH??? hands";
290 break;
291 default:
292 handage = "ERROR:NEITHER??? hand";
293 break;
294 }
295 switch (ctmp->targettype) {
296 case -1:
297 strcpy(smallbuf, "over the arena");
298 break;
299 case 0:
300 strcpy(smallbuf, "up into the air");
301 break;
302 default:
303 if (ctmp->targettype==QuVal_Target_Wizard && ctmp->target==ctmp->caster) {
304 strcpy(smallbuf, "at ");
305 strcat(smallbuf, pro_himself(self->wiz[ctmp->caster]->gender));
306 }
307 else {
308 switch (ctmp->targettype) {
309 case QuVal_Target_Wizard:
310 mtarget = (union being *)self->wiz[ctmp->target];
311 break;
312 case QuVal_Target_Creature:
313 mtarget = (union being *)&(self->cre[ctmp->target]);
314 break;
315 default:
316 mtarget = NULL;
317 break;
318 }
319 sprintf(smallbuf, "at %s", mtarget->both.name);
320 }
321 break;
322 }
323 if (ctmp->spellnum == SP__STAB)
324 sprintf(exbuf, "%s stabs (%s) %s.\n", self->wiz[ctmp->caster]->name, handage, smallbuf);
325 else
326 sprintf(exbuf, "%s casts %s%s (%s) %s.\n", self->wiz[ctmp->caster]->name, ((ctmp->permanent)?"Permanent ":""), spelllist[ctmp->spellnum].name, handage, smallbuf);
327 PrintMsg(exbuf);
328 }
329
330 /* CLEAR ROUND DATA */
331 self->fl_icestorm = 0;
332 self->fl_firestorm = 0;
333 self->fl_dispelmagic = 0;
334 for (ix=0; ix<self->numplayers; ix++)
335 clear_round(self->wiz[ix]);
336 for (ix=0; ix<self->numcres; ix++)
337 clear_round(&self->cre[ix]);
338
339 /* check DISPEL MAGIC, MAGIC MIRROR, COUNTER_SPELL */
340 for (ctmp = self->castlist; ctmp; ctmp = ctmp->next) {
341
342 switch (ctmp->targettype) {
343 case QuVal_Target_Wizard:
344 mtarget = (union being *)self->wiz[ctmp->target];
345 break;
346 case QuVal_Target_Creature:
347 mtarget = (union being *)&(self->cre[ctmp->target]);
348 break;
349 default:
350 mtarget = NULL;
351 break;
352 }
353 mcaster = self->wiz[ctmp->caster];
354
355 /* convert counter_spell2 to counter_spell */
356 if (ctmp->spellnum==SP__COUNTER_SPELL2)
357 ctmp->spellnum = SP__COUNTER_SPELL;
358
359 if (ctmp->spellnum==SP__DISPEL_MAGIC) {
360 if (check_visibility(self, mcaster, mtarget, ctmp)) {
361 self->fl_dispelmagic = 1;
362 set_zap_flag(self, ctmp, SP__SHIELD); /* auto-shield */
363 }
364 }
365 else if (ctmp->spellnum==SP__COUNTER_SPELL) {
366 if (check_visibility(self, mcaster, mtarget, ctmp)) {
367 set_zap_flag(self, ctmp, SP__COUNTER_SPELL);
368 }
369 }
370 else if (ctmp->spellnum==SP__MAGIC_MIRROR) {
371 if (check_visibility(self, mcaster, mtarget, ctmp)) {
372 set_zap_flag(self, ctmp, SP__MAGIC_MIRROR);
373 }
374 }
375 }
376
377 if (self->fl_dispelmagic)
378 PrintMsg("The magical energies in the arena fade away.\n");
379
380 /* EXECUTE DISPEL MAGIC, MAGIC MIRROR, COUNTER_SPELL : all beings and corpses. This sets the zapl[] for those spells. */
381 for (ix=0; ix<self->numplayers; ix++) {
382 exec_counters(self, self->wiz[ix], ix, 1);
383 }
384 for (ix=0; ix<self->numcres; ix++) {
385 exec_counters(self, &self->cre[ix], ix, 0);
386 }
387
388 /* set up spell tables */
389 for (ctmp = self->castlist; ctmp; ctmp = ctmp->next) {
390
391 switch (ctmp->targettype) {
392 case QuVal_Target_Wizard:
393 mtarget = (union being *)self->wiz[ctmp->target];
394 break;
395 case QuVal_Target_Creature:
396 mtarget = (union being *)&(self->cre[ctmp->target]);
397 break;
398 default:
399 mtarget = NULL;
400 break;
401 }
402 mcaster = self->wiz[ctmp->caster];
403
404 switch (ctmp->spellnum) {
405 case SP__SHIELD:
406 case SP__REMOVE_ENCHANTMENT:
407 case SP__RAISE_DEAD:
408 case SP__CURE_LIGHT_WOUNDS:
409 case SP__CURE_HEAVY_WOUNDS:
410 case SP__SUMMON_GOBLIN:
411 case SP__SUMMON_OGRE:
412 case SP__SUMMON_TROLL:
413 case SP__SUMMON_GIANT:
414 case SP__SUMMON_ELEMENTAL:
415 case SP__PROTECTION_FROM_EVIL:
416 case SP__RESIST_HEAT:
417 case SP__RESIST_COLD:
418 case SP__INVISIBILITY:
419 case SP__HASTE:
420 case SP__TIME_STOP:
421 case SP__DELAYED_EFFECT:
422 case SP__PERMANENCY:
423 /* spells not affected by magic mirror */
424
425 /* check for dispel magic */
426 if (self->fl_dispelmagic) {
427 sprintf(exbuf, "The %s is dispelled.\n", spelllist[ctmp->spellnum].name);
428 PrintMsg(exbuf);
429 break;
430 }
431
432 if (!mtarget) {
433 /* up in air, or (shouldn't happen) area-effect */
434 break;
435 }
436
437 /* sight check */
438 if (!check_visibility(self, mcaster, mtarget, ctmp)) {
439 break;
440 }
441
442 /* check for counterspell */
443 if (mtarget->both.zaplist[SP__COUNTER_SPELL]) {
444 sprintf(exbuf, "The %s is destroyed by your Counter-Spell.\n", spelllist[ctmp->spellnum].name);
445 sprintf(exbuf2, "The %s is destroyed by the Counter-Spell around %s.\n", spelllist[ctmp->spellnum].name, mtarget->both.name);
446 if (ctmp->targettype==QuVal_Target_Wizard)
447 PrintMsg2(ctmp->target, exbuf, exbuf2);
448 else
449 PrintMsg(exbuf2);
450 break;
451 }
452 set_zap_flag(self, ctmp, -1);
453 break;
454
455 case SP__STAB:
456 /* not affected by magic mirror or dispel magic */
457 if (!mtarget) {
458 /* up in air, or (shouldn't happen) area-effect */
459 break;
460 }
461 /* sight check */
462 if (!check_visibility(self, mcaster, mtarget, ctmp)) {
463 break;
464 }
465
466 set_zap_flag(self, ctmp, -1);
467 break;
468
469 case SP__MISSILE:
470 case SP__FINGER_OF_DEATH:
471 case SP__LIGHTNING_BOLT:
472 case SP__LIGHTNING_BOLT2:
473 case SP__CAUSE_LIGHT_WOUNDS:
474 case SP__CAUSE_HEAVY_WOUNDS:
475 case SP__FIREBALL:
476 case SP__AMNESIA:
477 case SP__CONFUSION:
478 case SP__CHARM_PERSON:
479 case SP__CHARM_MONSTER:
480 case SP__PARALYSIS:
481 case SP__FEAR:
482 case SP__ANTI_SPELL:
483 case SP__DISEASE:
484 case SP__POISON:
485 case SP__BLINDNESS:
486 /* spells affected by magic mirror */
487
488 /* check for repeat of short lightning bolt */
489 if (ctmp->spellnum==SP__LIGHTNING_BOLT2) {
490 if (!mcaster->fl_cast_lightning) {
491 mcaster->fl_cast_lightning = 1;
492 ctmp->spellnum = SP__LIGHTNING_BOLT;
493 }
494 else {
495 sprintf(exbuf2, "%s's Lightning Bolt fizzles.\n", mcaster->name);
496 PrintMsg2(ctmp->caster, "Since you have already cast Lightning Bolt with that formulation, the spell fizzles.\n", exbuf2);
497 break;
498 }
499 }
500
501 /* check for dispel magic */
502 if (self->fl_dispelmagic) {
503 sprintf(exbuf, "The %s is dispelled.\n", spelllist[ctmp->spellnum].name);
504 PrintMsg(exbuf);
505 break;
506 }
507
508 if (!mtarget) {
509 /* up in air, or (shouldn't happen) area-effect */
510 break;
511 }
512
513 /* sight check */
514 if (!check_visibility(self, mcaster, mtarget, ctmp)) {
515 break;
516 }
517
518 /* check for counterspell */
519 if (ctmp->spellnum != SP__FINGER_OF_DEATH) {
520 if (mtarget->both.zaplist[SP__COUNTER_SPELL]) {
521 sprintf(exbuf, "The %s is destroyed by your Counter-Spell.\n", spelllist[ctmp->spellnum].name);
522 sprintf(exbuf2, "The %s is destroyed by the Counter-Spell around %s.\n", spelllist[ctmp->spellnum].name, mtarget->both.name);
523 if (ctmp->targettype==QuVal_Target_Wizard)
524 PrintMsg2(ctmp->target, exbuf, exbuf2);
525 else
526 PrintMsg(exbuf2);
527 break;
528 }
529 }
530
531 ix = mtarget->both.zaplist[SP__MAGIC_MIRROR];
532 /* if the caster is the target, ignore magic mirror. */
533 if (ix && ((union being *)mcaster!=mtarget)) {
534 /* magic mirror -- terrific */
535 /* we assume that the caster is a wizard. */
536
537 /* check to see if caster has mirror too */
538 if (mcaster->zaplist[SP__MAGIC_MIRROR]) {
539 sprintf(exbuf, "Your %s is reflected back and forth between %s's Magic Mirror and your own! It rapidly decays and dissipates.\n", spelllist[ctmp->spellnum].name, mtarget->both.name);
540 sprintf(exbuf2, "%s's %s is reflected back and forth between your Magic Mirror and %s own! It rapidly decays and dissipates.\n", mcaster->name, spelllist[ctmp->spellnum].name, pro_his(mcaster->gender));
541 sprintf(exbuf3, "%s's %s is reflected back and forth between %s's Magic Mirror and %s own! It rapidly decays and dissipates.\n", mcaster->name, spelllist[ctmp->spellnum].name, mtarget->both.name, pro_his(mcaster->gender));
542 if (ctmp->targettype==QuVal_Target_Wizard)
543 PrintMsg3(ctmp->caster, ctmp->target, exbuf, exbuf2, exbuf3);
544 else
545 PrintMsg2(ctmp->caster, exbuf, exbuf3);
546 break; /* spell is lost */
547 }
548
549 sprintf(exbuf, "Your %s is reflected from %s's Magic Mirror back at you.\n", spelllist[ctmp->spellnum].name, mtarget->both.name);
550 sprintf(exbuf2, "%s's %s reflects from your Magic Mirror back at %s.\n", mcaster->name, spelllist[ctmp->spellnum].name, pro_him(mcaster->gender));
551 sprintf(exbuf3, "%s's %s reflects from %s's Magic Mirror back at %s.\n", mcaster->name, spelllist[ctmp->spellnum].name, mtarget->both.name, pro_him(mcaster->gender));
552 if (ctmp->targettype==QuVal_Target_Wizard)
553 PrintMsg3(ctmp->caster, ctmp->target, exbuf, exbuf2, exbuf3);
554 else
555 PrintMsg2(ctmp->caster, exbuf, exbuf3);
556 /* reverse spell */
557 ix = ctmp->caster;
558 if (ctmp->targettype==QuVal_Target_Wizard)
559 ctmp->caster = ctmp->target;
560 else
561 ctmp->caster = (-1);
562 ctmp->targettype = QuVal_Target_Wizard;
563 ctmp->target = ix;
564 /* now, check AGAIN for counterspell */
565 if (ctmp->spellnum != SP__FINGER_OF_DEATH) {
566 if (mcaster->zaplist[SP__COUNTER_SPELL]) {
567 sprintf(exbuf, "The reflected %s is destroyed by your Counter-Spell.\n", spelllist[ctmp->spellnum].name);
568 sprintf(exbuf2, "The reflected %s is destroyed by the Counter-Spell around %s.\n", spelllist[ctmp->spellnum].name, mcaster->name);
569 if (ctmp->targettype==QuVal_Target_Wizard)
570 PrintMsg2(ctmp->target, exbuf, exbuf2);
571 else
572 PrintMsg(exbuf2);
573 break;
574 }
575 }
576 set_zap_flag(self, ctmp, -1);
577 }
578 else {
579 set_zap_flag(self, ctmp, -1);
580 }
581 break;
582
583 case SP__ICE_STORM:
584 /* area-effect spell; mtarget is NULL */
585 /* check for dispel magic */
586 if (self->fl_dispelmagic) {
587 sprintf(exbuf, "The %s is dispelled.\n", spelllist[ctmp->spellnum].name);
588 PrintMsg(exbuf);
589 break;
590 }
591 self->fl_icestorm++;
592 break;
593 case SP__FIRE_STORM:
594 /* area-effect spell; mtarget is NULL */
595 /* check for dispel magic */
596 if (self->fl_dispelmagic) {
597 sprintf(exbuf, "The %s is dispelled.\n", spelllist[ctmp->spellnum].name);
598 PrintMsg(exbuf);
599 break;
600 }
601 self->fl_firestorm++;
602 break;
603
604 case SP__SURRENDER:
605 PrintMsg("ERROR: Surrender got through to spell table setup\n");
606 break;
607
608 case SP__COUNTER_SPELL:
609 case SP__COUNTER_SPELL2:
610 case SP__DISPEL_MAGIC:
611 case SP__MAGIC_MIRROR:
612 /* already taken care of */
613 break;
614
615 default:
616 PrintMsg("ERROR: Unknown spell in spell table setup\n");
617 break;
618 }
619 }
620
621 /* before summoning, do any queries for elemental type. */
622 erase_queries(self);
623 for (ix=0; ix<self->numplayers; ix++)
624 if (self->wiz[ix]->alive) {
625 for (jx=0; jx<self->wiz[ix]->zaplist[SP__SUMMON_ELEMENTAL]; jx++) {
626 add_query(self, ix, Qu_ElementalType, 0);
627 }
628 }
629 if (self->numqueries)
630 Queries(self->numqueries, self->querylist);
631
632 /* SUMMON SPELLS : live wizards */
633 summonelq = 0; /* counter for queries */
634 for (ix=0; ix<self->numplayers; ix++) {
635 if (self->wiz[ix]->alive)
636 exec_summons(self, self->wiz[ix], ix, 1);
637 }
638
639 /* CHECK FOR ELEMENTAL / STORM CANCELS */
640 check_elements(self);
641
642 /* CHECK FOR CANCELS : live beings */
643 for (ix=0; ix<self->numplayers; ix++) {
644 if (self->wiz[ix]->alive)
645 exec_cancels(self, self->wiz[ix], ix, 1);
646 }
647 for (ix=0; ix<self->numcres; ix++) {
648 if (self->cre[ix].alive)
649 exec_cancels(self, &self->cre[ix], ix, 0);
650 }
651
652 /* CHECK FOR PROTECTS : live beings */
653 for (ix=0; ix<self->numplayers; ix++) {
654 if (self->wiz[ix]->alive)
655 exec_protects(self, self->wiz[ix], ix, 1);
656 }
657 for (ix=0; ix<self->numcres; ix++) {
658 if (self->cre[ix].alive)
659 exec_protects(self, &self->cre[ix], ix, 0);
660 }
661
662 /* CHECK FOR ENCHANTMENTS : live beings */
663 for (ix=0; ix<self->numplayers; ix++) {
664 if (self->wiz[ix]->alive)
665 exec_enchants(self, self->wiz[ix], ix, 1);
666 }
667 for (ix=0; ix<self->numcres; ix++) {
668 if (self->cre[ix].alive)
669 exec_enchants(self, &self->cre[ix], ix, 0);
670 }
671
672 /* DAMAGE SPELLS : live beings */
673 for (ix=0; ix<self->numplayers; ix++) {
674 if (self->wiz[ix]->alive)
675 exec_attacks(self, self->wiz[ix], ix, 1);
676 }
677 for (ix=0; ix<self->numcres; ix++) {
678 if (self->cre[ix].alive)
679 exec_attacks(self, &self->cre[ix], ix, 0);
680 }
681
682 /* HEALING SPELLS : all beings */
683 for (ix=0; ix<self->numplayers; ix++) {
684 exec_heals(self, self->wiz[ix], ix, 1);
685 }
686 for (ix=0; ix<self->numcres; ix++) {
687 exec_heals(self, &self->cre[ix], ix, 0);
688 }
689
690 }
691
exec_counters(self,fred,cnum,wizflag)692 static void exec_counters(self, fred, cnum, wizflag) /* dead allowed */
693 struct realgame *self;
694 union being *fred;
695 int cnum;
696 int wizflag;
697 {
698 struct castspell *ctmp, **pt;
699 int ix, jx, wiznum;
700 int *zapl;
701
702 zapl = fred->both.zaplist;
703
704 /*{
705 for (jx=0; jx<NUMSPELLS; jx++)
706 putchar('0'+zapl[jx]);
707 printf(" : %s\n", fred->both.name);
708 }*/
709
710 if (self->fl_dispelmagic) {
711 /* dispel magic in effect: neutralize counter_spells and magic mirrors */
712 if (zapl[SP__COUNTER_SPELL]) {
713 zapl[SP__COUNTER_SPELL] = 0;
714 sprintf(exbuf, "The Counter-Spell on %s is dispelled.\n", fred->both.name);
715 if (wizflag)
716 PrintMsg2(cnum, "The Counter-Spell on you is dispelled.\n", exbuf);
717 else
718 PrintMsg(exbuf);
719 }
720 if (zapl[SP__MAGIC_MIRROR]) {
721 zapl[SP__MAGIC_MIRROR] = 0;
722 sprintf(exbuf, "The Magic Mirror on %s is dispelled.\n", fred->both.name);
723 if (wizflag)
724 PrintMsg2(cnum, "The Magic Mirror on you is dispelled.\n", exbuf);
725 else
726 PrintMsg(exbuf);
727 }
728
729 if (!wizflag) {
730 struct creature *cre = (struct creature *)fred;
731 if (cre->alive) {
732 sprintf(exbuf, "The Dispel Magic starts to tear %s apart.\n", cre->name);
733 PrintMsg(exbuf);
734 cre->hitpoints = (-100);
735 cre->nocorpse = 1;
736 }
737 else if (!cre->nocorpse) {
738 sprintf(exbuf, "The corpse of %s disintegrates, destroyed by the Dispel Magic.\n", cre->name);
739 PrintMsg(exbuf);
740 cre->nocorpse = 1;
741 }
742 }
743 }
744 else {
745 /* no dispel magic */
746 if (zapl[SP__COUNTER_SPELL]) {
747 zapl[SP__SHIELD]++; /* auto-shield */
748
749 sprintf(exbuf, "A Counter-Spell flares around %s.\n", fred->both.name);
750 if (wizflag)
751 PrintMsg2(cnum, "Your magical senses go numb as a Counter-Spell surrounds you.\n", exbuf);
752 else
753 PrintMsg(exbuf);
754
755 if (zapl[SP__MAGIC_MIRROR]) {
756 /* counterspell beats mirror */
757 zapl[SP__MAGIC_MIRROR] = 0;
758 sprintf(exbuf, "The Magic Mirror on %s is destroyed by the Counter-Spell.\n", fred->both.name);
759 if (wizflag)
760 PrintMsg2(cnum, "The Magic Mirror on you is destroyed by the Counter-Spell.\n", exbuf);
761 else
762 PrintMsg(exbuf);
763 }
764
765 }
766
767 if (zapl[SP__MAGIC_MIRROR]) {
768
769 sprintf(exbuf, "A Magic Mirror swirls around %s.\n", fred->both.name);
770 if (wizflag)
771 PrintMsg2(cnum, "The bright haze of a Magic Mirror surrounds you.\n", exbuf);
772 else
773 PrintMsg(exbuf);
774
775 }
776 }
777 }
778
exec_summons(self,fred,cnum,wizflag)779 static void exec_summons(self, fred, cnum, wizflag) /* no deaders or monsters */
780 struct realgame *self;
781 union being *fred;
782 int cnum;
783 int wizflag;
784 {
785 int ix, jx, spelnum;
786 int *zapl = fred->both.zaplist;
787 char *elm;
788 /* counterspell, dispel magic, magic mirror have already been taken care of. */
789 static int summonspells[4] = {SP__SUMMON_GOBLIN, SP__SUMMON_OGRE, SP__SUMMON_TROLL, SP__SUMMON_GIANT};
790 static char *summonnames[4] = {"Goblin", "Ogre", "Troll", "Giant"};
791
792 for (ix=0; ix<4; ix++) {
793 spelnum = summonspells[ix];
794 if (zapl[spelnum]) {
795 if (zapl[spelnum]==1) {
796 sprintf(exbuf, "Your %s materializes by your side.\n", summonnames[ix]);
797 sprintf(exbuf2, "%s's %s appears by %s side.\n", fred->both.name, summonnames[ix], pro_his(fred->both.gender));
798 if (wizflag)
799 PrintMsg2(cnum, exbuf, exbuf2);
800 else
801 PrintMsg(exbuf2);
802 }
803 else {
804 sprintf(exbuf, "Your %s %ss materialize by your side.\n", number_name(zapl[spelnum]), summonnames[ix]);
805 sprintf(exbuf2, "%s's %s %ss appear by %s side.\n", fred->both.name, number_name(zapl[spelnum]), summonnames[ix], pro_his(fred->both.gender));
806 if (wizflag)
807 PrintMsg2(cnum, exbuf, exbuf2);
808 else
809 PrintMsg(exbuf2);
810 }
811 for (jx=0; jx<zapl[spelnum]; jx++)
812 create_creature(self, ix+1, cnum);
813 }
814 }
815
816 for (jx=0; jx<self->wiz[cnum]->zaplist[SP__SUMMON_ELEMENTAL]; jx++) {
817 ix = self->querylist[summonelq].answer; /* 0 fire, 1 ice */
818 summonelq++;
819 if (!ix) {
820 sprintf(exbuf, "A blazing Fire Elemental materializes above you.\n");
821 sprintf(exbuf2, "A blazing Fire Elemental materializes above %s.\n", fred->both.name);
822 }
823 else {
824 sprintf(exbuf, "A glittering Ice Elemental materializes above you.\n");
825 sprintf(exbuf2, "A glittering Ice Elemental materializes above %s.\n", fred->both.name);
826 }
827 if (wizflag)
828 PrintMsg2(cnum, exbuf, exbuf2);
829 else
830 PrintMsg(exbuf2);
831 create_creature(self, 6-ix, cnum);
832 }
833
834 }
835
836 /* actually, check for cancellation of creatures for any cause. */
check_elements(self)837 static void check_elements(self)
838 struct realgame *self;
839 {
840 int num_fire, num_ice, firel, icel;
841 int ix, nukit;
842 int *zapl;
843
844 num_fire = 0;
845 num_ice = 0;
846 for (ix=0; ix<self->numcres; ix++)
847 if (self->cre[ix].alive) {
848 if (self->cre[ix].type==Creature_FIREL) {
849 num_fire++;
850 if (num_fire == 1) {
851 firel = ix;
852 }
853 else {
854 self->cre[firel].hitpoints = 3; /* max strength */
855 self->cre[ix].nocorpse = 1;
856 self->cre[ix].alive = 0;
857 }
858 }
859 if (self->cre[ix].type==Creature_ICEL) {
860 num_ice++;
861 if (num_ice == 1) {
862 icel = ix;
863 }
864 else {
865 self->cre[icel].hitpoints = 3; /* max strength */
866 self->cre[ix].nocorpse = 1;
867 self->cre[ix].alive = 0;
868 }
869 }
870 }
871 if (num_fire>1) {
872 sprintf(exbuf, "The %s Fire Elementals merge into single raging form.\n", number_name(num_fire));
873 PrintMsg(exbuf);
874 }
875 if (num_ice>1) {
876 sprintf(exbuf, "The %s Ice Elementals merge into single whirling form.\n", number_name(num_ice));
877 PrintMsg(exbuf);
878 }
879
880 ix = (num_fire ? 1 : 0)
881 | (num_ice ? 2 : 0)
882 | (self->fl_firestorm ? 4 : 0)
883 | (self->fl_icestorm ? 8 : 0);
884
885 switch (ix) {
886 case 5: /* 0101 */
887 PrintMsg("The Fire Elemental is dispersed into the Fire Storm.\n");
888 self->cre[firel].nocorpse = 1;
889 self->cre[firel].alive = 0;
890 break;
891 case 10: /* 1010 */
892 PrintMsg("The Ice Elemental is dispersed into the Ice Storm.\n");
893 self->cre[icel].nocorpse = 1;
894 self->cre[icel].alive = 0;
895 break;
896 case 12: /* 1100 */
897 PrintMsg("The Fire and Ice Storms tear each other into shreds of vapor.\n");
898 self->fl_firestorm = 0;
899 self->fl_icestorm = 0;
900 break;
901 case 3: /* 0011 */
902 PrintMsg("The Fire and Ice Elementals tear into each other, and whirl into a column of steam that dissipates in moments.\n");
903 self->cre[firel].nocorpse = 1;
904 self->cre[firel].alive = 0;
905 self->cre[icel].nocorpse = 1;
906 self->cre[icel].alive = 0;
907 break;
908 case 6: /* 0110 */
909 PrintMsg("The Ice Elemental is dispersed into the Fire Storm, destroying both.\n");
910 self->cre[icel].nocorpse = 1;
911 self->cre[icel].alive = 0;
912 self->fl_firestorm = 0;
913 break;
914 case 9: /* 1001 */
915 PrintMsg("The Fire Elemental is dispersed into the Ice Storm, destroying both.\n");
916 self->cre[firel].nocorpse = 1;
917 self->cre[firel].alive = 0;
918 self->fl_icestorm = 0;
919 break;
920 case 13: /* 1101 */
921 PrintMsg("The Fire and Ice Storms tear each other into shreds of vapor, destroying the Fire Elemental as well.\n");
922 self->cre[firel].nocorpse = 1;
923 self->cre[firel].alive = 0;
924 self->fl_firestorm = 0;
925 self->fl_icestorm = 0;
926 break;
927 case 14: /* 1110 */
928 PrintMsg("The Fire and Ice Storms tear each other into shreds of vapor, destroying the Ice Elemental as well.\n");
929 self->cre[icel].nocorpse = 1;
930 self->cre[icel].alive = 0;
931 self->fl_firestorm = 0;
932 self->fl_icestorm = 0;
933 break;
934 case 11: /* 1011 */
935 PrintMsg("The Fire and Ice Elementals tear into each other, and whirl into a column of steam that dissipates in moments. The Ice Storm is absorbed as well.\n");
936 self->cre[firel].nocorpse = 1;
937 self->cre[firel].alive = 0;
938 self->cre[icel].nocorpse = 1;
939 self->cre[icel].alive = 0;
940 self->fl_icestorm = 0;
941 break;
942 case 7: /* 0111 */
943 PrintMsg("The Fire and Ice Elementals tear into each other, and whirl into a column of steam that dissipates in moments. The Fire Storm is absorbed as well.\n");
944 self->cre[firel].nocorpse = 1;
945 self->cre[firel].alive = 0;
946 self->cre[icel].nocorpse = 1;
947 self->cre[icel].alive = 0;
948 self->fl_firestorm = 0;
949 break;
950 case 15: /* 1111 */
951 PrintMsg("The Fire and Ice Elementals whirl into each other, screaming in fury, and the Fire and Ice storms shriek in response. The column of Elemental energy rises to meet the cloud of vapor that descends over the arena. You are buffeted by the conflicting energies; but within moments, nothing remains.\n");
952 self->cre[firel].nocorpse = 1;
953 self->cre[firel].alive = 0;
954 self->cre[icel].nocorpse = 1;
955 self->cre[icel].alive = 0;
956 self->fl_icestorm = 0;
957 self->fl_firestorm = 0;
958 break;
959 }
960
961 for (ix=0; ix<self->numcres; ix++)
962 if (self->cre[ix].alive) {
963 zapl = self->cre[ix].zaplist;
964 nukit = 0;
965
966 if (self->cre[ix].type==Creature_FIREL) {
967 if (!nukit && zapl[SP__RESIST_HEAT]) {
968 sprintf(exbuf, "%s gutters and flickers out under the influence of the Resist Heat.\n", self->cre[ix].name);
969 PrintMsg(exbuf);
970 nukit = 1;
971 }
972 }
973 if (self->cre[ix].type==Creature_ICEL) {
974 if (!nukit && zapl[SP__RESIST_COLD]) {
975 sprintf(exbuf, "%s melts away under the influence of the Resist Cold.\n", self->cre[ix].name);
976 PrintMsg(exbuf);
977 nukit = 1;
978 }
979 if (!nukit && zapl[SP__FIREBALL]) {
980 sprintf(exbuf, "%s is vaporized by the Fireball.\n", self->cre[ix].name);
981 PrintMsg(exbuf);
982 nukit = 1;
983 }
984 }
985 if (!nukit && zapl[SP__BLINDNESS]) {
986 sprintf(exbuf, "Under the stress of the Blindness, %s shivers and disintegrates into random energies.\n", self->cre[ix].name);
987 PrintMsg(exbuf);
988 nukit = 1;
989 }
990 if (!nukit && zapl[SP__INVISIBILITY]) {
991 sprintf(exbuf, "Under the stress of the Invisibility, %s shivers and disintegrates into random energies.\n", self->cre[ix].name);
992 PrintMsg(exbuf);
993 nukit = 1;
994 }
995
996 if (nukit) {
997 self->cre[ix].alive = 0;
998 self->cre[ix].nocorpse = 1;
999 }
1000
1001 /* dispel magic was taken care of earlier */
1002 if (self->cre[ix].alive && zapl[SP__REMOVE_ENCHANTMENT]) {
1003 sprintf(exbuf, "The Remove Enchantment starts to tear %s apart.\n", self->cre[ix].name);
1004 PrintMsg(exbuf);
1005 self->cre[ix].hitpoints = (-100);
1006 self->cre[ix].nocorpse = 1;
1007 }
1008 }
1009 }
1010
exec_cancels(self,fred,cnum,wizflag)1011 static void exec_cancels(self, fred, cnum, wizflag) /* no deaders */
1012 struct realgame *self;
1013 union being *fred;
1014 int cnum;
1015 int wizflag;
1016 {
1017 int ix;
1018 int *zapl = fred->both.zaplist;
1019 struct permstats *perm = &(fred->both.perm);
1020 /* counterspell, dispel magic, magic mirror have already been taken care of. */
1021
1022 if (zapl[SP__RAISE_DEAD] && zapl[SP__FINGER_OF_DEATH]) {
1023 sprintf(exbuf2, "The Finger of Death and Raise Dead spells aimed at %s cancel each other.\n", fred->both.name);
1024 if (wizflag)
1025 PrintMsg2(cnum, "For a moment, you feel a sudden pressure in your chest, as if an iron band was squeezing your heart. Then it fades, as the Raise Dead spell burns through you.\n", exbuf2);
1026 else
1027 PrintMsg(exbuf2);
1028 zapl[SP__RAISE_DEAD]=0;
1029 zapl[SP__FINGER_OF_DEATH]=0;
1030 }
1031
1032 if (zapl[SP__FIREBALL] && self->fl_icestorm) {
1033 sprintf(exbuf2, "The Fireball hurtling towards %s is snuffed by the Ice Storm, leaving %s enveloped in a cloud of steam.\n", fred->both.name, pro_him(fred->both.gender));
1034 if (wizflag)
1035 PrintMsg2(cnum, "The Fireball hurtling towards you is snuffed by the Ice Storm, leaving you enveloped in warm steam.\n", exbuf2);
1036 else
1037 PrintMsg(exbuf2);
1038 zapl[SP__FIREBALL]=0;
1039 fred->both.fl_resist_icestorm = 1;
1040 }
1041
1042 ix = (zapl[SP__AMNESIA] ? 1 : 0)
1043 + (zapl[SP__CONFUSION] ? 1 : 0)
1044 + (zapl[SP__CHARM_PERSON] ? 1 : 0)
1045 + (zapl[SP__CHARM_MONSTER] ? 1 : 0)
1046 + (zapl[SP__PARALYSIS] ? 1 : 0)
1047 + (zapl[SP__FEAR] ? 1 : 0);
1048
1049 if (ix>1
1050 || (zapl[SP__PARALYSIS]>1 && (wizflag && fred->wiz.hand_paralyzed==(-1)))
1051 || zapl[SP__CHARM_PERSON]>1
1052 || zapl[SP__CHARM_MONSTER]>1) {
1053 /* all mind spells cancel. */
1054 list_mind_spells(exbuf3, zapl);
1055
1056 sprintf(exbuf, "The mind-control spells (%s) aimed at you interfere with each other and fizzle, leaving you with a pounding headache.\n", exbuf3);
1057 sprintf(exbuf2, "The mind-control spells (%s) aimed at %s interfere with each other and fizzle.\n", exbuf3, fred->both.name);
1058 if (wizflag)
1059 PrintMsg2(cnum, exbuf, exbuf2);
1060 else
1061 PrintMsg(exbuf2);
1062
1063 zapl[SP__AMNESIA] = 0;
1064 zapl[SP__CONFUSION] = 0;
1065 zapl[SP__CHARM_PERSON] = 0;
1066 zapl[SP__CHARM_MONSTER] = 0;
1067 zapl[SP__PARALYSIS] = 0;
1068 zapl[SP__FEAR] = 0;
1069 fred->both.enchant_ppend = 0;
1070 }
1071 /* now only a legal set of mind spells remain, and at most one control spell, whose caster is in enchant_caster. (Which may be -1, if the spell mirrored off a creature.) */
1072
1073 }
1074
exec_protects(self,fred,cnum,wizflag)1075 static void exec_protects(self, fred, cnum, wizflag) /* no deaders */
1076 struct realgame *self;
1077 union being *fred;
1078 int cnum;
1079 int wizflag;
1080 {
1081 int *zapl = fred->both.zaplist;
1082 struct permstats *perm = &(fred->both.perm);
1083 /* counterspell, dispel magic, magic mirror have already been taken care of. */
1084
1085 /* don't bother checking permanency -- it doesn't change anything */
1086 if (zapl[SP__RESIST_HEAT]) {
1087 if (!fred->both.resistant_heat) {
1088 sprintf(exbuf2, "The Resist Heat shrouds %s in a cool blue veil.\n", fred->both.name);
1089 if (wizflag)
1090 PrintMsg2(cnum, "The Resist Heat wraps you in a pleasant blue coolness.\n", exbuf2);
1091 else
1092 PrintMsg(exbuf2);
1093 fred->both.resistant_heat = 1;
1094 }
1095 else {
1096 sprintf(exbuf2, "%s's veil of Resist Heat continues to glow coolly.\n", fred->both.name);
1097 if (wizflag)
1098 PrintMsg2(cnum, "Your veil of Resist Heat continues to glow coolly.\n", exbuf2);
1099 else
1100 PrintMsg(exbuf2);
1101 }
1102 }
1103
1104 /* don't bother checking permanency -- it doesn't change anything */
1105 if (zapl[SP__RESIST_COLD]) {
1106 if (!fred->both.resistant_cold) {
1107 sprintf(exbuf2, "The Resist Cold shrouds %s in a warm pink veil.\n", fred->both.name);
1108 if (wizflag)
1109 PrintMsg2(cnum, "The Resist Cold wraps you in a pleasant pink warmth.\n", exbuf2);
1110 else
1111 PrintMsg(exbuf2);
1112 fred->both.resistant_cold = 1;
1113 }
1114 else {
1115 sprintf(exbuf2, "%s's veil of Resist Cold continues to glow warmly.\n", fred->both.name);
1116 if (wizflag)
1117 PrintMsg2(cnum, "Your veil of Resist Cold continues to glow warmly.\n", exbuf2);
1118 else
1119 PrintMsg(exbuf2);
1120 }
1121 }
1122
1123 if (zapl[SP__PROTECTION_FROM_EVIL] || perm->fl_prot_evil) {
1124 if (!fred->both.prot_from_evil) {
1125 sprintf(exbuf, "A white circle of Protection from Evil springs up around you. You feel the Shield aura cloaking your skin.\n");
1126 sprintf(exbuf2, "A white circle of Protection from Evil springs up around %s.\n", fred->both.name);
1127 if (wizflag)
1128 PrintMsg2(cnum, exbuf, exbuf2);
1129 else
1130 PrintMsg(exbuf2);
1131 }
1132 else {
1133 sprintf(exbuf, "Your circle of Protection from Evil flares back to full strength.\n");
1134 sprintf(exbuf2, "%s's circle of Protection from Evil flares back to full strength.\n", fred->both.name);
1135 if (wizflag)
1136 PrintMsg2(cnum, exbuf, exbuf2);
1137 else
1138 PrintMsg(exbuf2);
1139 }
1140 fred->both.prot_from_evil = 4;
1141 }
1142
1143 if (!(self->turntype==Turn_TIMESTOP && fred->both.timestop!=1)) {
1144 fred->both.fl_resist_heat = (fred->both.resistant_heat);
1145 fred->both.fl_resist_cold = (fred->both.resistant_cold);
1146
1147 if (fred->both.prot_from_evil>0) {
1148 int doit = 1;
1149 switch (fred->both.prot_from_evil) {
1150 case 4:
1151 default:
1152 doit = 0;
1153 /*sprintf(exbuf, "Your circle of Protection from Evil is still glowing strongly.\n");
1154 sprintf(exbuf2, "%s's circle of Protection from Evil is still glowing strongly.\n", fred->both.name);*/
1155 break;
1156 case 3:
1157 sprintf(exbuf, "Your circle of Protection from Evil is beginning to fade.\n");
1158 sprintf(exbuf2, "%s's circle of Protection from Evil is beginning to fade.\n", fred->both.name);
1159 break;
1160 case 2:
1161 sprintf(exbuf, "Your circle of Protection from Evil is dimmer now.\n");
1162 sprintf(exbuf2, "%s's circle of Protection from Evil is dimmer now.\n", fred->both.name);
1163 break;
1164 case 1:
1165 sprintf(exbuf, "Your circle of Protection from Evil is nearly gone.\n");
1166 sprintf(exbuf2, "%s's circle of Protection from Evil is nearly gone.\n", fred->both.name);
1167 break;
1168 }
1169 if (doit)
1170 if (wizflag)
1171 PrintMsg2(cnum, exbuf, exbuf2);
1172 else
1173 PrintMsg(exbuf2);
1174
1175 fred->both.prot_from_evil--;
1176 zapl[SP__SHIELD] += 64; /* auto-shield, special mark */
1177 }
1178 }
1179 else {
1180 /* the protections are timestopped and have no effect. */
1181 }
1182 }
1183
1184