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