1 /*	SCCS Id: @(#)priest.c	3.3	2000/02/19	*/
2 /* Copyright (c) Izchak Miller, Steve Linhart, 1989.		  */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 #include "hack.h"
6 #include "mfndpos.h"
7 #include "eshk.h"
8 #include "epri.h"
9 #include "emin.h"
10 
11 #ifdef OVLB
12 
13 STATIC_DCL boolean FDECL(histemple_at,(struct monst *,XCHAR_P,XCHAR_P));
14 STATIC_DCL boolean FDECL(has_shrine,(struct monst *));
15 
16 /*
17  * Move for priests and shopkeepers.  Called from shk_move() and pri_move().
18  * Valid returns are  1: moved  0: didn't  -1: let m_move do it  -2: died.
19  */
20 int
move_special(mtmp,in_his_shop,appr,uondoor,avoid,omx,omy,gx,gy)21 move_special(mtmp,in_his_shop,appr,uondoor,avoid,omx,omy,gx,gy)
22 register struct monst *mtmp;
23 boolean in_his_shop;
24 schar appr;
25 boolean uondoor,avoid;
26 register xchar omx,omy,gx,gy;
27 {
28 	register xchar nx,ny,nix,niy;
29 	register schar i;
30 	schar chcnt,cnt;
31 	coord poss[9];
32 	long info[9];
33 	long allowflags;
34 	struct obj *ib = (struct obj *)0;
35 
36 	if(omx == gx && omy == gy)
37 		return(0);
38 	if(mtmp->mconf) {
39 		avoid = FALSE;
40 		appr = 0;
41 	}
42 
43 	nix = omx;
44 	niy = omy;
45 	if (mtmp->isshk) allowflags = ALLOW_SSM;
46 	else allowflags = ALLOW_SSM | ALLOW_SANCT;
47 	if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK|ALLOW_WALL);
48 	if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
49 	if (tunnels(mtmp->data) &&
50 		    (!needspick(mtmp->data) || m_carrying(mtmp, PICK_AXE) ||
51 		     m_carrying(mtmp, DWARVISH_MATTOCK)))
52 		allowflags |= ALLOW_DIG;
53 	if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
54 		allowflags |= OPENDOOR;
55 		if (m_carrying(mtmp, SKELETON_KEY)) allowflags |= BUSTDOOR;
56 	}
57 	if (is_giant(mtmp->data)) allowflags |= BUSTDOOR;
58 	cnt = mfndpos(mtmp, poss, info, allowflags);
59 
60 	if(mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */
61 		for(i=0; i<cnt; i++)
62 		    if(!(info[i] & NOTONL)) goto pick_move;
63 		avoid = FALSE;
64 	}
65 
66 #define GDIST(x,y)	(dist2(x,y,gx,gy))
67 pick_move:
68 	chcnt = 0;
69 	for(i=0; i<cnt; i++) {
70 		nx = poss[i].x;
71 		ny = poss[i].y;
72 		if(levl[nx][ny].typ == ROOM ||
73 			(mtmp->ispriest &&
74 			    levl[nx][ny].typ == ALTAR) ||
75 			(mtmp->isshk &&
76 			    (!in_his_shop || ESHK(mtmp)->following))) {
77 		    if(avoid && (info[i] & NOTONL))
78 			continue;
79 		    if((!appr && !rn2(++chcnt)) ||
80 			(appr && GDIST(nx,ny) < GDIST(nix,niy))) {
81 			    nix = nx;
82 			    niy = ny;
83 		    }
84 		}
85 	}
86 	if(mtmp->ispriest && avoid &&
87 			nix == omx && niy == omy && onlineu(omx,omy)) {
88 		/* might as well move closer as long it's going to stay
89 		 * lined up */
90 		avoid = FALSE;
91 		goto pick_move;
92 	}
93 
94 	if(nix != omx || niy != omy) {
95 		remove_monster(omx, omy);
96 		place_monster(mtmp, nix, niy);
97 		newsym(nix,niy);
98 		if (mtmp->isshk && !in_his_shop && inhishop(mtmp))
99 		    check_special_room(FALSE);
100 		if(ib) {
101 			if (cansee(mtmp->mx,mtmp->my))
102 			    pline("%s picks up %s.", Monnam(mtmp),
103 				distant_name(ib,doname));
104 			obj_extract_self(ib);
105 			(void) mpickobj(mtmp, ib);
106 		}
107 		return(1);
108 	}
109 	return(0);
110 }
111 
112 #endif /* OVLB */
113 
114 #ifdef OVL0
115 
116 char
temple_occupied(array)117 temple_occupied(array)
118 register char *array;
119 {
120 	register char *ptr;
121 
122 	for (ptr = array; *ptr; ptr++)
123 		if (rooms[*ptr - ROOMOFFSET].rtype == TEMPLE)
124 			return(*ptr);
125 	return('\0');
126 }
127 
128 #endif /* OVL0 */
129 #ifdef OVLB
130 
131 STATIC_OVL boolean
histemple_at(priest,x,y)132 histemple_at(priest, x, y)
133 register struct monst *priest;
134 register xchar x, y;
135 {
136 	return((boolean)((EPRI(priest)->shroom == *in_rooms(x, y, TEMPLE)) &&
137 	       on_level(&(EPRI(priest)->shrlevel), &u.uz)));
138 }
139 
140 /*
141  * pri_move: return 1: moved  0: didn't  -1: let m_move do it  -2: died
142  */
143 int
pri_move(priest)144 pri_move(priest)
145 register struct monst *priest;
146 {
147 	register xchar gx,gy,omx,omy;
148 	schar temple;
149 	boolean avoid = TRUE;
150 
151 	omx = priest->mx;
152 	omy = priest->my;
153 
154 	if(!histemple_at(priest, omx, omy)) return(-1);
155 
156 	temple = EPRI(priest)->shroom;
157 
158 	gx = EPRI(priest)->shrpos.x;
159 	gy = EPRI(priest)->shrpos.y;
160 
161 	gx += rn1(3,-1);	/* mill around the altar */
162 	gy += rn1(3,-1);
163 
164 	if(!priest->mpeaceful ||
165 	   (Conflict && !resist(priest, RING_CLASS, 0, 0))) {
166 		if(monnear(priest, u.ux, u.uy)) {
167 			if(Displaced)
168 				Your("displaced image doesn't fool %s!",
169 					mon_nam(priest));
170 			(void) mattacku(priest);
171 			return(0);
172 		} else if(index(u.urooms, temple)) {
173 			/* chase player if inside temple & can see him */
174 			if(priest->mcansee && m_canseeu(priest)) {
175 				gx = u.ux;
176 				gy = u.uy;
177 			}
178 			avoid = FALSE;
179 		}
180 	} else if(Invis) avoid = FALSE;
181 
182 	return(move_special(priest,FALSE,TRUE,FALSE,avoid,omx,omy,gx,gy));
183 }
184 
185 /* exclusively for mktemple() */
186 void
priestini(lvl,sroom,sx,sy,sanctum)187 priestini(lvl, sroom, sx, sy, sanctum)
188 d_level	*lvl;
189 struct mkroom *sroom;
190 int sx, sy;
191 boolean sanctum;   /* is it the seat of the high priest? */
192 {
193 	register struct monst *priest;
194 	register struct obj *otmp;
195 	register int cnt;
196 
197 	if(MON_AT(sx+1, sy))
198 		rloc(m_at(sx+1, sy)); /* insurance */
199 
200 	priest = makemon(&mons[sanctum ? PM_HIGH_PRIEST : PM_ALIGNED_PRIEST],
201 			 sx + 1, sy, NO_MM_FLAGS);
202 	if (priest) {
203 		EPRI(priest)->shroom = (sroom - rooms) + ROOMOFFSET;
204 		EPRI(priest)->shralign = Amask2align(levl[sx][sy].altarmask);
205 		EPRI(priest)->shrpos.x = sx;
206 		EPRI(priest)->shrpos.y = sy;
207 		assign_level(&(EPRI(priest)->shrlevel), lvl);
208 		priest->mtrapseen = ~0;	/* traps are known */
209 		priest->mpeaceful = 1;
210 		priest->ispriest = 1;
211 		priest->msleeping = 0;
212 		set_malign(priest); /* mpeaceful may have changed */
213 
214 		/* now his/her goodies... */
215 		if(sanctum && EPRI(priest)->shralign == A_NONE &&
216 		     on_level(&sanctum_level, &u.uz)) {
217 			(void) mongets(priest, AMULET_OF_YENDOR);
218 		}
219 		/* Do NOT put the rest in m_initinv.    */
220 		/* Priests created elsewhere than in a  */
221 		/* temple should not carry these items, */
222 		cnt = rn1(2,3);
223 		while(cnt) {
224 		    otmp = mkobj(SPBOOK_CLASS, FALSE);
225 		    if(otmp) (void) mpickobj(priest, otmp);
226 		    cnt--;
227 		}
228 		if(p_coaligned(priest))
229 		    (void) mongets(priest, ROBE);
230 		else {
231 		    otmp = mksobj(ROBE, TRUE, FALSE);
232 		    if(otmp) {
233 			if(!rn2(2)) curse(otmp);
234 			(void) mpickobj(priest, otmp);
235 		    }
236 		}
237 		m_dowear(priest, TRUE);
238 	}
239 }
240 
241 /*
242  * Specially aligned monsters are named specially.
243  *	- aligned priests with ispriest and high priests have shrines
244  *		they retain ispriest and epri when polymorphed
245  *	- aligned priests without ispriest and Angels are roamers
246  *		they retain isminion and access epri as emin when polymorphed
247  *		(coaligned Angels are also created as minions, but they
248  *		use the same naming convention)
249  *	- minions do not have ispriest but have isminion and emin
250  *	- caller needs to inhibit Hallucination if it wants to force
251  *		the true name even when under that influence
252  */
253 char *
priestname(mon,pname)254 priestname(mon, pname)
255 register struct monst *mon;
256 char *pname;		/* caller-supplied output buffer */
257 {
258 	const char *what = Hallucination ? rndmonnam() : mon->data->mname;
259 
260 	Strcpy(pname, "the ");
261 	if (mon->minvis) Strcat(pname, "invisible ");
262 	if (mon->ispriest || mon->data == &mons[PM_ALIGNED_PRIEST] ||
263 					mon->data == &mons[PM_ANGEL]) {
264 		/* use epri */
265 		if (mon->mtame && mon->data == &mons[PM_ANGEL])
266 			Strcat(pname, "guardian ");
267 		if (mon->data != &mons[PM_ALIGNED_PRIEST] &&
268 				mon->data != &mons[PM_HIGH_PRIEST]) {
269 			Strcat(pname, what);
270 			Strcat(pname, " ");
271 		}
272 		if (mon->data != &mons[PM_ANGEL]) {
273 			if (!mon->ispriest && EPRI(mon)->renegade)
274 				Strcat(pname, "renegade ");
275 			if (mon->data == &mons[PM_HIGH_PRIEST])
276 				Strcat(pname, "high ");
277 			if (Hallucination)
278 				Strcat(pname, "poohbah ");
279 			else if (mon->female)
280 				Strcat(pname, "priestess ");
281 			else
282 				Strcat(pname, "priest ");
283 		}
284 		Strcat(pname, "of ");
285 		Strcat(pname, halu_gname((int)EPRI(mon)->shralign));
286 		return(pname);
287 	}
288 	/* use emin instead of epri */
289 	Strcat(pname, what);
290 	Strcat(pname, " of ");
291 	Strcat(pname, halu_gname(EMIN(mon)->min_align));
292 	return(pname);
293 }
294 
295 boolean
p_coaligned(priest)296 p_coaligned(priest)
297 struct monst *priest;
298 {
299 	return((boolean)(u.ualign.type == ((int)EPRI(priest)->shralign)));
300 }
301 
302 STATIC_OVL boolean
has_shrine(pri)303 has_shrine(pri)
304 struct monst *pri;
305 {
306 	struct rm *lev;
307 
308 	if(!pri)
309 		return(FALSE);
310 	lev = &levl[EPRI(pri)->shrpos.x][EPRI(pri)->shrpos.y];
311 	if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE))
312 		return(FALSE);
313 	return((boolean)(EPRI(pri)->shralign == Amask2align(lev->altarmask & ~AM_SHRINE)));
314 }
315 
316 struct monst *
findpriest(roomno)317 findpriest(roomno)
318 char roomno;
319 {
320 	register struct monst *mtmp;
321 
322 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
323 	    if (DEADMONSTER(mtmp)) continue;
324 	    if(mtmp->ispriest && (EPRI(mtmp)->shroom == roomno) &&
325 	       histemple_at(mtmp,mtmp->mx,mtmp->my))
326 		return(mtmp);
327 	}
328 	return (struct monst *)0;
329 }
330 
331 /* called from check_special_room() when the player enters the temple room */
332 void
intemple(roomno)333 intemple(roomno)
334 register int roomno;
335 {
336 	register struct monst *priest = findpriest((char)roomno);
337 	boolean tended = (priest != (struct monst *)0);
338 	boolean shrined, sanctum, can_speak;
339 	const char *msg1, *msg2;
340 	char buf[BUFSZ];
341 
342 	if(!temple_occupied(u.urooms0)) {
343 	    if(tended) {
344 		shrined = has_shrine(priest);
345 		sanctum = (priest->data == &mons[PM_HIGH_PRIEST] &&
346 			   (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
347 		can_speak = (priest->mcanmove && !priest->msleeping);
348 		if (can_speak)
349 		    pline("%s intones:",
350 			  (!Blind ? Monnam(priest) : "A nearby voice"));
351 		msg2 = 0;
352 		if(sanctum && Is_sanctum(&u.uz)) {
353 		    if(priest->mpeaceful) {
354 			msg1 = "Infidel, you entered Moloch's Sanctum!";
355 			msg2 = "Be gone!";
356 			priest->mpeaceful = 0;
357 			set_malign(priest);
358 		    } else
359 			msg1 = "You desecrate this place by your presence!";
360 		} else {
361 		    Sprintf(buf, "Pilgrim, you enter a %s place!",
362 			    !shrined ? "desecrated" : "sacred");
363 		    msg1 = buf;
364 		}
365 		if (can_speak) {
366 		    verbalize(msg1);
367 		    if (msg2) verbalize(msg2);
368 		}
369 		if(!sanctum) {
370 		    /* !tended -> !shrined */
371 		    if(!shrined || !p_coaligned(priest) ||
372 						   u.ualign.record < -5)
373 			You("have a%s forbidding feeling...",
374 				(!shrined) ? "" : " strange");
375 		    else You("experience a strange sense of peace.");
376 		}
377 	    } else {
378 		switch(rn2(3)) {
379 		  case 0: You("have an eerie feeling..."); break;
380 		  case 1: You_feel("like you are being watched."); break;
381 		  default: pline("A shiver runs down your %s.",
382 			body_part(SPINE)); break;
383 		}
384 		if(!rn2(5)) {
385 		    struct monst *mtmp;
386 
387 		    if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy,NO_MM_FLAGS)))
388 			return;
389 		    pline("An enormous ghost appears next to you!");
390 		    mtmp->mpeaceful = 0;
391 		    set_malign(mtmp);
392 		    if(flags.verbose)
393 			You("are frightened to death, and unable to move.");
394 		    nomul(-3);
395 		    nomovemsg = "You regain your composure.";
396 	       }
397 	   }
398        }
399 }
400 
401 void
priest_talk(priest)402 priest_talk(priest)
403 register struct monst *priest;
404 {
405 	boolean coaligned = p_coaligned(priest);
406 	boolean strayed = (u.ualign.record < 0);
407 
408 
409 	/* KMH, conduct */
410 	u.uconduct.gnostic++;
411 
412 	if(priest->mflee || (!priest->ispriest && coaligned && strayed)) {
413 	    pline("%s doesn't want anything to do with you!",
414 				Monnam(priest));
415 	    priest->mpeaceful = 0;
416 	    return;
417 	}
418 
419 	/* priests don't chat unless peaceful and in their own temple */
420 	if(!histemple_at(priest,priest->mx,priest->my) ||
421 		 !priest->mpeaceful || !priest->mcanmove || priest->msleeping) {
422 	    static const char *cranky_msg[3] = {
423 		"Thou wouldst have words, eh?  I'll give thee a word or two!",
424 		"Talk?  Here is what I have to say!",
425 		"Pilgrim, I would speak no longer with thee."
426 	    };
427 
428 	    if(!priest->mcanmove || priest->msleeping) {
429 		pline("%s breaks out of %s reverie!",
430 		      Monnam(priest), his[pronoun_gender(priest)]);
431 		priest->mfrozen = priest->msleeping = 0;
432 		priest->mcanmove = 1;
433 	    }
434 	    priest->mpeaceful = 0;
435 	    verbalize(cranky_msg[rn2(3)]);
436 	    return;
437 	}
438 
439 	/* you desecrated the temple and now you want to chat? */
440 	if(priest->mpeaceful && *in_rooms(priest->mx, priest->my, TEMPLE) &&
441 		  !has_shrine(priest)) {
442 	    verbalize("Begone!  Thou desecratest this holy place with thy presence.");
443 	    priest->mpeaceful = 0;
444 	    return;
445 	}
446 
447 	if(!u.ugold) {
448 	    if(coaligned && !strayed) {
449 		if (priest->mgold > 0L) {
450 		    /* Note: two bits is actually 25 cents.  Hmm. */
451 		    pline("%s gives you %s for an ale.", Monnam(priest),
452 			(priest->mgold == 1L) ? "one bit" : "two bits");
453 		    if (priest->mgold > 1L)
454 			u.ugold = 2L;
455 		    else
456 			u.ugold = 1L;
457 		    priest->mgold -= u.ugold;
458 		    flags.botl = 1;
459 		} else
460 		    pline("%s preaches the virtues of poverty.", Monnam(priest));
461 		exercise(A_WIS, TRUE);
462 	    } else
463 		pline("%s is not interested.", Monnam(priest));
464 	    return;
465 	} else {
466 	    long offer;
467 
468 	    pline("%s asks you for a contribution for the temple.",
469 			Monnam(priest));
470 	    if((offer = bribe(priest)) == 0) {
471 		verbalize("Thou shalt regret thine action!");
472 		if(coaligned) adjalign(-1);
473 	    } else if(offer < (u.ulevel * 200)) {
474 		if(u.ugold > (offer * 2L)) verbalize("Cheapskate.");
475 		else {
476 		    verbalize("I thank thee for thy contribution.");
477 		    /*  give player some token  */
478 		    exercise(A_WIS, TRUE);
479 		}
480 	    } else if(offer < (u.ulevel * 400)) {
481 		verbalize("Thou art indeed a pious individual.");
482 		if(u.ugold < (offer * 2L)) {
483 		    if(coaligned && u.ualign.record < -5) adjalign(1);
484 		    verbalize("I bestow upon thee a blessing.");
485 		    incr_itimeout(&HClairvoyant, rn1(500,500));
486 		}
487 	    } else if(offer < (u.ulevel * 600) &&
488 		      u.ublessed < 20 &&
489 		      (u.ublessed < 9 || !rn2(u.ublessed))) {
490 		verbalize("Thy devotion has been rewarded.");
491 		if (!(HProtection & INTRINSIC))  {
492 			HProtection |= FROMOUTSIDE;
493 			if (!u.ublessed)  u.ublessed = rn1(3, 2);
494 		} else u.ublessed++;
495 	    } else {
496 		verbalize("Thy selfless generosity is deeply appreciated.");
497 		if(u.ugold < (offer * 2L) && coaligned) {
498 		    if(strayed && (moves - u.ucleansed) > 5000L) {
499 			u.ualign.record = 0; /* cleanse thee */
500 			u.ucleansed = moves;
501 		    } else {
502 			adjalign(2);
503 		    }
504 		}
505 	    }
506 	}
507 }
508 
509 struct monst *
mk_roamer(ptr,alignment,x,y,peaceful)510 mk_roamer(ptr, alignment, x, y, peaceful)
511 register struct permonst *ptr;
512 aligntyp alignment;
513 xchar x, y;
514 boolean peaceful;
515 {
516 	register struct monst *roamer;
517 	register boolean coaligned = (u.ualign.type == alignment);
518 
519 	if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL])
520 		return((struct monst *)0);
521 
522 	if (MON_AT(x, y)) rloc(m_at(x, y));	/* insurance */
523 
524 	if (!(roamer = makemon(ptr, x, y, NO_MM_FLAGS)))
525 		return((struct monst *)0);
526 
527 	EPRI(roamer)->shralign = alignment;
528 	if (coaligned && !peaceful)
529 		EPRI(roamer)->renegade = TRUE;
530 	/* roamer->ispriest == FALSE naturally */
531 	roamer->isminion = TRUE;	/* borrowing this bit */
532 	roamer->mtrapseen = ~0;		/* traps are known */
533 	roamer->mpeaceful = peaceful;
534 	roamer->msleeping = 0;
535 	set_malign(roamer); /* peaceful may have changed */
536 
537 	/* MORE TO COME */
538 	return(roamer);
539 }
540 
541 void
reset_hostility(roamer)542 reset_hostility(roamer)
543 register struct monst *roamer;
544 {
545 	if(!(roamer->isminion && (roamer->data == &mons[PM_ALIGNED_PRIEST] ||
546 				  roamer->data == &mons[PM_ANGEL])))
547 	        return;
548 
549 	if(EPRI(roamer)->shralign != u.ualign.type) {
550 	    roamer->mpeaceful = roamer->mtame = 0;
551 	    set_malign(roamer);
552 	}
553 	newsym(roamer->mx, roamer->my);
554 }
555 
556 boolean
in_your_sanctuary(mon,x,y)557 in_your_sanctuary(mon, x, y)
558 struct monst *mon;	/* if non-null, <mx,my> overrides <x,y> */
559 xchar x, y;
560 {
561 	register char roomno;
562 	register struct monst *priest;
563 
564 	if (mon) {
565 	    if (is_minion(mon->data) || is_rider(mon->data)) return FALSE;
566 	    x = mon->mx, y = mon->my;
567 	}
568 	if (u.ualign.record < -3)		/* sinned or worse */
569 	    return FALSE;
570 	if ((roomno = temple_occupied(u.urooms)) == 0 ||
571 		roomno != *in_rooms(x, y, TEMPLE))
572 	    return FALSE;
573 	if ((priest = findpriest(roomno)) == 0)
574 	    return FALSE;
575 	return (boolean)(has_shrine(priest) &&
576 			 p_coaligned(priest) &&
577 			 priest->mpeaceful);
578 }
579 
580 void
ghod_hitsu(priest)581 ghod_hitsu(priest)	/* when attacking "priest" in his temple */
582 struct monst *priest;
583 {
584 	int x, y, ax, ay, roomno = (int)temple_occupied(u.urooms);
585 	struct mkroom *troom;
586 
587 	if (!roomno || !has_shrine(priest))
588 		return;
589 
590 	ax = x = EPRI(priest)->shrpos.x;
591 	ay = y = EPRI(priest)->shrpos.y;
592 	troom = &rooms[roomno - ROOMOFFSET];
593 
594 	if((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y)) {
595 	    if(IS_DOOR(levl[u.ux][u.uy].typ)) {
596 
597 		if(u.ux == troom->lx - 1) {
598 		    x = troom->hx;
599 		    y = u.uy;
600 		} else if(u.ux == troom->hx + 1) {
601 		    x = troom->lx;
602 		    y = u.uy;
603 		} else if(u.uy == troom->ly - 1) {
604 		    x = u.ux;
605 		    y = troom->hy;
606 		} else if(u.uy == troom->hy + 1) {
607 		    x = u.ux;
608 		    y = troom->ly;
609 		}
610 	    } else {
611 		switch(rn2(4)) {
612 		case 0:  x = u.ux; y = troom->ly; break;
613 		case 1:  x = u.ux; y = troom->hy; break;
614 		case 2:  x = troom->lx; y = u.uy; break;
615 		default: x = troom->hx; y = u.uy; break;
616 		}
617 	    }
618 	    if(!linedup(u.ux, u.uy, x, y)) return;
619 	}
620 
621 	switch(rn2(3)) {
622 	case 0:
623 	    pline("%s roars in anger:  \"Thou shalt suffer!\"",
624 			a_gname_at(ax, ay));
625 	    break;
626 	case 1:
627 	    pline("%s voice booms:  \"How darest thou harm my servant!\"",
628 			s_suffix(a_gname_at(ax, ay)));
629 	    break;
630 	default:
631 	    pline("%s roars:  \"Thou dost profane my shrine!\"",
632 			a_gname_at(ax, ay));
633 	    break;
634 	}
635 
636 	buzz(-10-(AD_ELEC-1), 6, x, y, sgn(tbx), sgn(tby)); /* bolt of lightning */
637 	exercise(A_WIS, FALSE);
638 }
639 
640 void
angry_priest()641 angry_priest()
642 {
643 	register struct monst *priest;
644 	struct rm *lev;
645 
646 	if ((priest = findpriest(temple_occupied(u.urooms))) != 0) {
647 	    wakeup(priest);
648 	    /*
649 	     * If the altar has been destroyed or converted, let the
650 	     * priest run loose.
651 	     * (When it's just a conversion and there happens to be
652 	     *	a fresh corpse nearby, the priest ought to have an
653 	     *	opportunity to try converting it back; maybe someday...)
654 	     */
655 	    lev = &levl[EPRI(priest)->shrpos.x][EPRI(priest)->shrpos.y];
656 	    if (!IS_ALTAR(lev->typ) ||
657 		((aligntyp)Amask2align(lev->altarmask & AM_MASK) !=
658 			EPRI(priest)->shralign)) {
659 		priest->ispriest = 0;		/* now a roamer */
660 		priest->isminion = 1;		/* but still aligned */
661 		/* this overloads the `shroom' field, which is now clobbered */
662 		EPRI(priest)->renegade = 0;
663 	    }
664 	}
665 }
666 
667 /*
668  * When saving bones, find priests that aren't on their shrine level,
669  * and remove them.   This avoids big problems when restoring bones.
670  */
671 void
clearpriests()672 clearpriests()
673 {
674     register struct monst *mtmp, *mtmp2;
675 
676     for(mtmp = fmon; mtmp; mtmp = mtmp2) {
677 	mtmp2 = mtmp->nmon;
678 	if (!DEADMONSTER(mtmp) && mtmp->ispriest && !on_level(&(EPRI(mtmp)->shrlevel), &u.uz))
679 	    mongone(mtmp);
680     }
681 }
682 
683 /* munge priest-specific structure when restoring -dlc */
684 void
restpriest(mtmp,ghostly)685 restpriest(mtmp, ghostly)
686 register struct monst *mtmp;
687 boolean ghostly;
688 {
689     if(u.uz.dlevel) {
690 	if (ghostly)
691 	    assign_level(&(EPRI(mtmp)->shrlevel), &u.uz);
692     }
693 }
694 
695 #endif /* OVLB */
696 
697 /*priest.c*/
698