1 /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
2 /* mspec.c */
3 /* monster special functions */
4 
5 #include "glob.h"
6 
7 
m_sp_mp(m)8 void m_sp_mp(m)
9 struct monster *m;
10 {
11   if (m->attacked && (random_range(3) == 1)) {
12     mprint("You feel cursed!");
13     p_damage(10,UNSTOPPABLE,"a mendicant priest's curse");
14     m_vanish(m);
15   }
16   else if (! m_statusp(m,NEEDY)) {
17     mprint("The mendicant priest makes a mystical gesture....");
18     mprint("You feel impressed...");
19     Player.alignment += 5;
20     if (Player.alignment > 20)
21       Player.hp = max(Player.hp,Player.maxhp);
22     m_vanish(m);
23   }
24 }
25 
26 
27 
m_sp_ng(m)28 void m_sp_ng(m)
29 struct monster *m;
30 {
31   if (distance(m->x,m->y,Player.x,Player.y) < 2)
32     if ((random_range(5) == 1) || (Player.status[VULNERABLE]>0)) {
33       mprint("The night gaunt grabs you and carries you off!");
34       mprint("Its leathery wings flap and flap, and it giggles insanely.");
35       mprint("It tickles you cunningly to render you incapable of escape.");
36       mprint("Finally, it deposits you in a strange place.");
37       p_teleport(0);
38     }
39 }
40 
41 
42 
43 
44 
m_sp_poison_cloud(m)45 void m_sp_poison_cloud(m)
46 struct monster *m;
47 {
48   if (distance(m->x,m->y,Player.x,Player.y) < 3) {
49     mprint("A cloud of poison gas surrounds you!");
50     if (Player.status[BREATHING] > 0)
51       mprint("You can breathe freely, however.");
52     else p_poison(7);
53   }
54 }
55 
56 
m_sp_explode(m)57 void m_sp_explode(m)
58 struct monster *m;
59 {
60   if ((distance(Player.x,Player.y,m->x,m->y)<2) &&
61       (m-> hp > 0) &&
62       (m->hp < Monsters[m->id].hp))
63     fball(m->x,m->y,m->x,m->y,m->hp);
64 }
65 
66 
67 
m_sp_demon(m)68 void m_sp_demon(m)
69 struct monster *m;
70 {
71   int mid;
72 
73   if (random_range(2)) {
74     if ((m->id != INCUBUS) && /*succubi don't give fear */
75 	los_p(m->x,m->y,Player.x,Player.y) &&
76 	(random_range(30) > Player.level+10) &&
77 	(Player.status[AFRAID] == 0)) {
78       mprint("You are stricken with fear!");
79       if (! p_immune(FEAR)) Player.status[AFRAID] += m->level;
80       else mprint("You master your reptile brain and stand fast.");
81     }
82     else m_sp_spell(m);
83   }
84   if ((m->hp < (m->level * 5)) && (m->hp > 1)) {
85     mprint("The demon uses its waning lifeforce to summon help!");
86     m->hp = 1;
87     switch(m->level) {
88     case 3: mid = NIGHT_GAUNT; break;
89     case 4:
90     case 5: mid = L_FDEMON; break; /* lesser frost demon */
91     case 6: mid = FROST_DEMON; break;
92     case 7: mid = OUTER_DEMON; break; /* outer circle demon */
93     case 8: mid = DEMON_SERP; break; /* demon serpent */
94     case 9: mid = INNER_DEMON; break; /* inner circle demon */
95     }
96     summon(-1,mid);
97     summon(-1,mid);
98   }
99 }
100 
101 
m_sp_acid_cloud(m)102 void m_sp_acid_cloud(m)
103 struct monster *m;
104 {
105   if (m_statusp(m,HOSTILE) &&
106       (distance(m->x,m->y,Player.x,Player.y) < 3))
107     acid_cloud();
108 }
109 
110 
m_sp_escape(m)111 void m_sp_escape(m)
112 struct monster *m;
113 {
114   if (m_statusp(m,HOSTILE))
115     m_vanish(m);
116 }
117 
118 
m_sp_ghost(m)119 void m_sp_ghost(m)
120 struct monster *m;
121 {
122   if (m_statusp(m,HOSTILE)) {
123     mprint("The ghost moans horribly....");
124     p_damage(1,FEAR,"a ghost-inspired heart attack");
125     mprint("You've been terrorized!");
126     if (! p_immune(FEAR)) Player.status[AFRAID] += m->level;
127     else mprint("You master your reptile brain and stand fast.");
128   }
129 }
130 
131 
132 
133 
134 /* random spell cast by monster */
m_sp_spell(m)135 void m_sp_spell(m)
136 struct monster *m;
137 {
138   char action[80];
139   if (m_statusp(m,HOSTILE) && los_p(Player.x,Player.y,m->x,m->y)) {
140     if (m->uniqueness == COMMON) strcpy(action,"The ");
141     else strcpy(action,"");
142     strcat(action,m->monstring);
143     strcat(action," casts a spell...");
144     mprint(action);
145     if (! magic_resist(m->level)) switch (random_range(m->level+7)) {
146     case 0:
147       nbolt(m->x,m->y,Player.x,Player.y,m->hit,10);
148       break;
149     case 1:
150       mprint("It seems stronger...");
151       m->hp += random_range(m->level*m->level);
152       break;
153     case 2:
154       haste(-1);
155       break;
156     case 3:
157       cure(-1);
158       break;
159     case 4:
160       /* WDT: I'd like to make this (and "case 5" below) dependant on
161        * the monster's IQ in some way -- dumb but powerful monsters
162        * deserve what they get :).  No rush. */
163       if (m_immunityp(m, ELECTRICITY) ||
164 	  distance(m->x,m->y,Player.x,Player.y) > 2)
165 	lball(m->x,m->y,Player.x,Player.y,20);
166       else
167         lbolt(m->x,m->y,Player.x,Player.y,m->hit,20);
168       break;
169     case 5:
170       if (m_immunityp(m, COLD) ||
171 	  distance(m->x,m->y,Player.x,Player.y) > 2)
172 	snowball(m->x,m->y,Player.x,Player.y,30);
173       else
174         icebolt(m->x,m->y,Player.x,Player.y,m->hit,30);
175       break;
176     case 6:
177       enchant(-1);
178       break;
179     case 7:
180       bless(0-m->level);
181       break;
182     case 8:
183       p_poison(m->level);
184       break;
185     case 9:
186       sleep_player(m->level/2);
187       break;
188     case 10:
189       fbolt(m->x,m->y,Player.x,Player.y,m->hit*3,50);
190       break;
191     case 11:
192       acquire(0-m->level);
193       break;
194     case 12:
195       dispel(-1);
196       break;
197     case 13:
198       disrupt(Player.x,Player.y,50);
199       break;
200     case 14:
201       if (m->uniqueness == COMMON) {
202 	strcpy(Str2,"a ");
203 	strcat(Str2,m->monstring);
204       }
205       else strcpy(Str2,m->monstring);
206       level_drain(m->level,Str2);
207       break;
208     case 15:
209     case 16:
210       disintegrate(Player.x,Player.y);
211       break;
212     }
213   }
214 }
215 
216 
217 
218 /* monsters with this have some way to hide, camouflage, etc until they
219    attack */
m_sp_surprise(m)220 void m_sp_surprise(m)
221 struct monster *m;
222 {
223   if (m->attacked) {
224     if (m_statusp(m,HOSTILE) &&
225 	(! Player.status[TRUESIGHT]) &&
226 	m_statusp(m,M_INVISIBLE)) {
227       m->monchar = Monsters[m->id].monchar;
228       if (! Player.status[ALERT]) {
229 	switch(random_range(4)) {
230 	case 0:
231 	  mprint("You are surprised by a sudden treacherous attack!");
232 	  break;
233 	case 1:
234 	  mprint("You are shocked out of your reverie by the scream of battle!");
235 	  break;
236 	case 2:
237 	  mprint("Suddenly, from out of the shadows, a surprise attack!");
238 	  break;
239 	case 3:
240 	  mprint("A shriek of hatred causes you to momentarily freeze up!");
241 	  break;
242 	}
243 	morewait();
244 	setgamestatus(SKIP_PLAYER);
245 	m_status_reset(m,M_INVISIBLE);
246       }
247       else {
248 	mprint("You alertly sense the presence of an attacker!");
249 	m_status_reset(m,M_INVISIBLE);
250       }
251     }
252   }
253 }
254 
m_sp_whistleblower(m)255 void m_sp_whistleblower(m)
256 struct monster *m;
257 {
258   if (m_statusp(m,HOSTILE)) {
259     alert_guards();
260     m->specialf = M_MELEE_NORMAL;
261   }
262 }
263 
264 
m_sp_seductor(m)265 void m_sp_seductor(m)
266 struct monster *m;
267 {
268   if (m_statusp(m,HOSTILE)) {
269     if (m->uniqueness == COMMON) {
270       strcpy(Str2,"The ");
271       strcat(Str2,m->monstring);
272     }
273     else strcpy(Str2,m->monstring);
274     strcat(Str2," runs away screaming for help....");
275     mprint(Str2);
276     m_vanish(m);
277     summon(-1,-1);
278     summon(-1,-1);
279     summon(-1,-1);
280   }
281   else if (distance(Player.x,Player.y,m->x,m->y) < 2)
282     m_talk_seductor(m);
283 
284 }
285 
286 
m_sp_demonlover(m)287 void m_sp_demonlover(m)
288 struct monster *m;
289 {
290   if (distance(Player.x,Player.y,m->x,m->y) < 2)
291     m_talk_demonlover(m);
292 }
293 
m_sp_eater(m)294 void m_sp_eater(m)
295 struct monster *m;
296 {
297   int i;
298   if (Player.rank[COLLEGE]) m_status_set(m,HOSTILE);
299   if (m_statusp(m,HOSTILE))
300     if (los_p(m->x,m->y,Player.x,Player.y)) {
301       mprint("A strange numbing sensation comes over you...");
302       morewait();
303       Player.mana = Player.mana / 2;
304       if (random_range(4)) enchant(-1);
305       else dispel(-1);
306       Player.pow--;
307       if (--Player.pow < 1) p_death("the Eater of Magic");
308     }
309   if (m->hp < 10) {
310     mprint("The Eater explodes in a burst of mana!");
311     manastorm(m->x,m->y,1000);
312   }
313 }
314 
315 
m_sp_dragonlord(m)316 void m_sp_dragonlord(m)
317 struct monster *m;
318 {
319   if (m_statusp(m,HOSTILE)) {
320     if (distance(m->x,m->y,Player.x,Player.y)<2) {
321       if (! Player.status[IMMOBILE]) {
322 	mprint("A gust of wind from the Dragonlord's wings knocks you down!");
323 	p_damage(25,NORMAL_DAMAGE,"a gust of wind");
324 	setgamestatus(SKIP_PLAYER);
325 	Player.status[IMMOBILE]+=2;
326       }
327       else if (! Constriction) {
328 	mprint("The Dragonlord grabs you with his tail!");
329 	Constriction = 25;
330 	Player.status[IMMOBILE]+=1;
331       }
332       else if (random_range(2)) {
333 	mprint("The coils squeeze tighter and tighter...");
334 	p_damage(Constriction,NORMAL_DAMAGE,"the Dragonlord");
335 	Player.status[IMMOBILE]+=1;
336 	Constriction *=2;
337       }
338       else {
339 	mprint("The Dragonlord hurls you to the ground!");
340 	p_damage(2*Constriction,NORMAL_DAMAGE,"the Dragonlord");
341 	Constriction = 0;
342       }
343       m_sp_spell(m);
344     }
345     else {
346       Constriction = 0;
347       if (view_los_p(m->x,m->y,Player.x,Player.y)) {
348 	if ((! Player.immunity[FEAR]) && (! Player.status[AFRAID])) {
349 	  mprint("You are awestruck at the sight of the Dragonlord.");
350 	  Player.status[AFRAID]+=5;
351 	}
352 	if (random_range(3)) {
353 	  m_sp_spell(m);
354 	  m_sp_spell(m);
355 	}
356       }
357     }
358   }
359   else if (distance(m->x,m->y,Player.x,Player.y)<2)
360     mprint("You are extremely impressed at the sight of the Dragonlord.");
361 }
362 
363 
m_sp_blackout(m)364 void m_sp_blackout(m)
365 struct monster *m;
366 {
367   if ((distance(m->x,m->y,Player.x,Player.y) < 4) &&
368       (Player.status[BLINDED] == 0)) {
369     mprint("The fungus emits a burst of black spores. You've been blinded!");
370     if (Player.status[TRUESIGHT] > 0) mprint("The blindness quickly passes.");
371     else Player.status[BLINDED]+=4;
372   }
373   if (loc_statusp(m->x,m->y,LIT)) {
374     mprint("The fungus chirps.... ");
375     mprint("The area is plunged into darkness.");
376     torch_check();torch_check();torch_check();
377     torch_check();torch_check();torch_check();
378     spreadroomdark(m->x,m->y,Level->site[m->x][m->y].roomnumber);
379     levelrefresh();
380   }
381 }
382 
383 
m_sp_bogthing(m)384 void m_sp_bogthing(m)
385 struct monster *m;
386 {
387   if (Player.status[IMMOBILE] &&
388       (distance(Player.x,Player.y,m->x,m->y) < 2)) {
389     if (! Player.status[AFRAID]) {
390       mprint("As the bogthing touches you, you feel a frisson of terror....");
391       if (Player.immunity[FEAR]) mprint("which you shake off.");
392       else Player.status[AFRAID]+=2;
393     }
394     else {
395       mprint("The bogthing's touch causes you scream in agony!");
396       p_damage(50,UNSTOPPABLE,"fright");
397       mprint("Your struggles grow steadily weaker....");
398       Player.con--;
399       Player.str--;
400       if ((Player.con < 3) || (Player.str < 3))
401 	p_death("congestive heart failure");
402     }
403   }
404 }
405 
406 
m_sp_were(m)407 void m_sp_were(m)
408 struct monster *m;
409 {
410   int mid;
411   if (m_statusp(m,HOSTILE) || (Phase == 6)) {
412     do mid = random_range(ML9-NML_0)+ML1;
413     /* log npc, 0th level npc, high score npc or were-creature */
414     while (mid == NPC || mid == ZERO_NPC ||
415 	   mid == HISCORE_NPC || mid == WEREHUMAN ||
416 	   (Monsters[mid].uniqueness != COMMON) ||
417 	   (! m_statusp(&(Monsters[mid]),MOBILE)) ||
418 	   (! m_statusp(&(Monsters[mid]),HOSTILE))
419 	   );
420     m->id = Monsters[mid].id;
421     m->hp += Monsters[mid].hp;
422     m->status |= Monsters[mid].status;
423     m->ac = Monsters[mid].ac;
424     m->dmg = Monsters[mid].dmg;
425     m->speed = Monsters[mid].speed;
426     m->immunity |= Monsters[mid].immunity;
427     m->xpv += Monsters[mid].xpv;
428     m->corpseweight = Monsters[mid].corpseweight;
429     m->monchar = Monsters[mid].monchar;
430     m->talkf = Monsters[mid].talkf;
431     m->meleef = Monsters[mid].meleef;
432     m->strikef = Monsters[mid].strikef;
433     m->specialf = Monsters[mid].specialf;
434     strcpy(Str1,"were-");
435     strcat(Str1,Monsters[mid].monstring);
436     strcpy(Str2,"dead were-");
437     strcat(Str2,Monsters[mid].monstring);
438     m->monstring = salloc(Str1);
439     m->corpsestr = salloc(Str2);
440     m->immunity += pow2(NORMAL_DAMAGE);
441     if (los_p(m->x,m->y,Player.x,Player.y))
442       mprint("You witness a hideous transformation!");
443     else mprint("You hear a distant howl.");
444   }
445 }
446 
447 
m_sp_servant(m)448 void m_sp_servant(m)
449 struct monster *m;
450 {
451   if ((m->id == SERV_LAW) && (Player.alignment < 0))
452     m_status_set(m,HOSTILE);
453   else if ((m->id == SERV_CHAOS) && (Player.alignment > 0))
454     m_status_set(m,HOSTILE);
455 }
456 
457 
m_sp_av(m)458 void m_sp_av(m)
459 struct monster *m;
460 {
461   if (Player.mana > 0) {
462     mprint("You feel a sudden loss of mana!");
463     Player.mana -= (max(0,10-distance(m->x,m->y,Player.x,Player.y)));
464     dataprint();
465   }
466 }
467 
m_sp_lw(m)468 void m_sp_lw(m)
469 struct monster *m;
470 {
471   if (random_range(2)) {
472     if (Level->site[m->x][m->y].locchar == FLOOR) {
473       Level->site[m->x][m->y].locchar = LAVA;
474       Level->site[m->x][m->y].p_locf = L_LAVA;
475       lset(m->x, m->y, CHANGED);
476     }
477     else if (Level->site[m->x][m->y].locchar == WATER) {
478       Level->site[m->x][m->y].locchar = FLOOR;
479       Level->site[m->x][m->y].p_locf = L_NO_OP;
480       lset(m->x, m->y, CHANGED);
481     }
482   }
483 }
484 
485 
m_sp_angel(m)486 void m_sp_angel(m)
487 struct monster *m;
488 {
489   int mid,hostile = FALSE;
490   switch(m->aux1) {
491   case ATHENA:
492   case ODIN:
493     hostile = ((Player.patron == HECATE) || (Player.patron == SET));
494     break;
495   case SET:
496   case HECATE:
497     hostile = ((Player.patron == ODIN) || (Player.patron == ATHENA));
498     break;
499   case DESTINY:
500     hostile = (Player.patron != DESTINY);
501     break;
502   }
503   if (hostile)
504     m_status_set(m,HOSTILE);
505   if (m_statusp(m,HOSTILE)) {
506     mprint("The angel summons a heavenly host!");
507     switch(m->level) {
508     case 9: mid = HIGH_ANGEL; break;
509     case 8: mid = ANGEL; break;
510     default:
511     case 6: mid = PHANTOM; break;
512     }
513     summon(-1,mid);
514     summon(-1,mid);
515     summon(-1,mid);
516     /* prevent angel from summoning infinitely */
517     m->specialf = M_NO_OP;
518   }
519 }
520 
521 
522 /* Could completely fill up level */
m_sp_swarm(m)523 void m_sp_swarm(m)
524 struct monster *m;
525 {
526   if (random_range(5)==1) {
527     if (view_los_p(m->x,m->y,Player.x,Player.y))
528       mprint("The swarm expands!");
529     else mprint("You hear an aggravating humming noise.");
530     summon(-1,SWARM);
531   }
532 }
533 
534 
535 
536 
537 /* raise nearby corpses from the dead.... */
m_sp_raise(m)538 void m_sp_raise(m)
539 struct monster *m;
540 {
541   int x,y;
542   pol t;
543   for(x=m->x-2;x<=m->x+2;x++)
544     for(y=m->y-2;y<=m->y+2;y++)
545       if (inbounds(x,y))
546 	if (Level->site[x][y].things != NULL)
547 	  if (Level->site[x][y].things->thing->id == CORPSEID) {
548 	    mprint("The Zombie Overlord makes a mystical gesture...");
549 	    summon(-1,Level->site[x][y].things->thing->charge);
550 	    t = Level->site[x][y].things;
551 	    Level->site[x][y].things = Level->site[x][y].things->next;
552 	    free((char *) t);
553 	  }
554 }
555 
556 
557 
558 
m_sp_mb(m)559 void m_sp_mb(m)
560 struct monster *m;
561 {
562   if (distance(m->x,m->y,Player.x,Player.y)==1) {
563     mprint("The manaburst explodes!");
564     if (m_statusp(m,HOSTILE)) {
565       mprint("You get blasted!");
566       p_damage(random_range(100),UNSTOPPABLE,"a manaburst");
567       mprint("You feel cold all over!");
568       Player.pow-=3;
569       Player.iq--;
570       Player.con--;
571       Player.str-=2;
572       Player.dex--;
573       Player.agi--;
574       dispel(-1);
575     }
576     else {
577       mprint("You feel toasty warm inside!");
578       Player.pow++;
579       Player.mana = max(Player.mana,calcmana());
580       Player.hp = max(Player.hp,++Player.maxhp);
581     }
582     m->hp = 0;
583   }
584 }
585 
586 
m_sp_mirror(m)587 void m_sp_mirror(m)
588 struct monster *m;
589 {
590   int i,x,y;
591   if (view_los_p(m->x,m->y,Player.x,Player.y)) {
592     if (random_range(20)+6 < m->level) {
593       summon(-1,m->id);
594       mprint("You hear the sound of a mirror shattering!");
595     }
596     else for(i=0;i<5;i++) {
597       x = m->x + random_range(13)-6;
598       y = m->y + random_range(13)-6;
599       if (inbounds(x,y)) {
600 	Level->site[x][y].showchar = m->monchar;
601 	putspot(x,y,m->monchar);
602       }
603     }
604   }
605 }
606 
607 
608 
m_illusion(m)609 void m_illusion(m)
610 struct monster *m;
611 {
612   int i = random_range(NUMMONSTERS);
613   if (i==NPC || i==HISCORE_NPC || i==ZERO_NPC) i = m->id; /* can't imitate NPC */
614   if (Player.status[TRUESIGHT]) {
615     m->monchar = Monsters[m->id].monchar;
616     m->monstring = Monsters[m->id].monstring;
617   }
618   else  if (random_range(5) == 1) {
619     m->monchar = Monsters[i].monchar;
620     m->monstring = Monsters[i].monstring;
621   }
622 }
623 
624 
625 
626 
m_huge_sounds(m)627 void m_huge_sounds(m)
628 struct monster *m;
629 {
630   if (m_statusp(m,AWAKE) &&
631       (! los_p(m->x,m->y,Player.x,Player.y)) &&
632       (random_range(10) == 1))
633     mprint("The dungeon shakes!");
634 }
635 
636 
637 
m_thief_f(m)638 void m_thief_f(m)
639 struct monster *m;
640 {
641   int i = random_item();
642   if (random_range(3) == 1) {
643     if (distance(Player.x,Player.y,m->x,m->y) < 2) {
644       if (p_immune(THEFT) || (Player.level > (m->level*2)+random_range(20)))
645 	mprint("You feel secure.");
646       else {
647 	if (i == ABORT)
648 	  mprint("You feel fortunate.");
649 	else if ((Player.possessions[i]->used) ||
650 		 (Player.dex < m->level*random_range(10))) {
651 	  mprint("You feel a sharp tug.... You hold on!");
652 	}
653 	else {
654 	  mprint("You feel uneasy for a moment.");
655 	  if (m->uniqueness == COMMON) {
656 	    strcpy(Str2,"The ");
657 	    strcat(Str2,m->monstring);
658 	  }
659 	  else strcpy(Str2,m->monstring);
660 	  strcat(Str2," suddenly runs away for some reason.");
661 	  mprint(Str2);
662 	  m_teleport(m);
663 	  m->movef = M_MOVE_SCAREDY;
664 	  m->specialf = M_MOVE_SCAREDY;
665 	  m_pickup(m,Player.possessions[i]);
666 	  conform_unused_object(Player.possessions[i]);
667 	  Player.possessions[i] = NULL;
668 	}
669       }
670     }
671   }
672 }
673 
674 
m_summon(m)675 void m_summon(m)
676 struct monster *m;
677 {
678   if ((distance(Player.x,Player.y,m->x,m->y) < 2) &&
679       (random_range(3) == 1)) {
680 	summon(0,-1);
681 	summon(0,-1);
682       }
683 }
684 
685 
m_aggravate(m)686 void m_aggravate(m)
687 struct monster *m;
688 {
689 
690   if (m_statusp(m,HOSTILE)) {
691     if (m->uniqueness == COMMON) {
692       strcpy(Str2,"The ");
693       strcat(Str2,m->monstring);
694     }
695     else strcpy(Str2,m->monstring);
696     strcat(Str2," emits an irritating humming sound.");
697     mprint(Str2);
698     aggravate();
699     m_status_reset(m,HOSTILE);
700   }
701 }
702 
703 
704 
m_sp_merchant(m)705 void m_sp_merchant(m)
706 struct monster *m;
707 {
708   pml ml;
709   if (m_statusp(m,HOSTILE))
710     if (Current_Environment == E_VILLAGE) {
711       mprint("The merchant screams: 'Help! Murder! Guards! Help!'");
712       mprint("You hear the sound of police whistles and running feet.");
713       for (ml=Level->mlist;ml!=NULL;ml=ml->next) {
714 	m_status_set(ml->m,AWAKE);
715 	m_status_set(ml->m,HOSTILE);
716       }
717       m->specialf = M_NO_OP;
718     }
719 }
720 
721 /* The special function of the various people in the court of the archmage */
722 /* and the sorcerors' circle */
m_sp_court(m)723 void m_sp_court(m)
724 struct monster *m;
725 {
726   pml ml;
727   if (m_statusp(m,HOSTILE)) {
728     mprint("A storm of spells hits you!");
729     for(ml=Level->mlist;ml!=NULL;ml=ml->next) {
730       m_status_set(ml->m,HOSTILE);
731       m_sp_spell(ml->m);
732       if (ml->m->specialf == M_SP_COURT)
733 	ml->m->specialf = M_SP_SPELL;
734     }
735   }
736 }
737 
738 
739 /* The special function of the dragons in the dragons' lair */
m_sp_lair(m)740 void m_sp_lair(m)
741 struct monster *m;
742 {
743   pml ml;
744   if (m_statusp(m,HOSTILE)) {
745     mprint("You notice a number of dragons waking up....");
746     mprint("You are struck by a quantity of firebolts.");
747     morewait();
748     for(ml=Level->mlist;ml!=NULL;ml=ml->next)
749       if (ml->m->hp > 0 && ml->m->specialf == M_SP_LAIR) {
750 	m_status_set(ml->m,HOSTILE);
751 	fbolt(ml->m->x,ml->m->y,Player.x,Player.y,100,100);
752 	if (ml->m->id == DRAGON_LORD)
753 	  ml->m->specialf = M_SP_DRAGONLORD;
754 	else
755 	  ml->m->specialf = M_STRIKE_FBOLT;
756       }
757   }
758 }
759 
760 
m_sp_prime(m)761 void m_sp_prime(m)
762 struct monster *m;
763 {
764   if (m_statusp(m,HOSTILE)) {
765     mprint("The prime sorceror gestures and a pentacular gate opens!");
766     mprint("You are surrounded by demons!");
767     summon(-1,DEMON_PRINCE);
768     summon(-1,DEMON_PRINCE);
769     summon(-1,DEMON_PRINCE);
770     summon(-1,DEMON_PRINCE);
771   }
772   m->specialf = M_SP_SPELL;
773 }
774