1/*	SCCS Id: @(#)priest.c	3.4	2002/11/06	*/
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/* this matches the categorizations shown by enlightenment */
12#define ALGN_SINNED	(-4)	/* worse than strayed */
13
14#ifdef OVLB
15
16STATIC_DCL boolean FDECL(histemple_at,(struct monst *,XCHAR_P,XCHAR_P));
17STATIC_DCL boolean FDECL(has_shrine,(struct monst *));
18
19/*
20 * Move for priests and shopkeepers.  Called from shk_move() and pri_move().
21 * Valid returns are  1: moved  0: didn't  -1: let m_move do it  -2: died.
22 */
23int
24move_special(mtmp,in_his_shop,appr,uondoor,avoid,omx,omy,gx,gy)
25register struct monst *mtmp;
26boolean in_his_shop;
27schar appr;
28boolean uondoor,avoid;
29register xchar omx,omy,gx,gy;
30{
31	register xchar nx,ny,nix,niy;
32	register schar i;
33	schar chcnt,cnt;
34	coord poss[9];
35	long info[9];
36	long allowflags;
37	struct obj *ib = (struct obj *)0;
38
39	if(omx == gx && omy == gy)
40		return(0);
41	if(mtmp->mconf) {
42		avoid = FALSE;
43		appr = 0;
44	}
45
46	nix = omx;
47	niy = omy;
48	if (mtmp->isshk) allowflags = ALLOW_SSM;
49	else allowflags = ALLOW_SSM | ALLOW_SANCT;
50	if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK|ALLOW_WALL);
51	if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
52	if (tunnels(mtmp->data)) 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))
67pick_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
116char
117temple_occupied(array)
118register 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
131STATIC_OVL boolean
132histemple_at(priest, x, y)
133register struct monst *priest;
134register 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 */
143int
144pri_move(priest)
145register 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() */
186void
187priestini(lvl, sroom, sx, sy, sanctum)
188d_level	*lvl;
189struct mkroom *sroom;
190int sx, sy;
191boolean sanctum;   /* is it the seat of the high priest? */
192{
193	struct monst *priest;
194	struct obj *otmp;
195	int cnt;
196
197	if(MON_AT(sx+1, sy))
198		(void) rloc(m_at(sx+1, sy), FALSE); /* 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		/* 2 to 4 spellbooks */
220		for (cnt = rn1(3,2); cnt > 0; --cnt) {
221		    (void) mpickobj(priest, mkobj(SPBOOK_CLASS, FALSE));
222		}
223		/* robe [via makemon()] */
224		if (rn2(2) && (otmp = which_armor(priest, W_ARMC)) != 0) {
225		    if (p_coaligned(priest))
226			uncurse(otmp);
227		    else
228			curse(otmp);
229		}
230	}
231}
232
233/*
234 * Specially aligned monsters are named specially.
235 *	- aligned priests with ispriest and high priests have shrines
236 *		they retain ispriest and epri when polymorphed
237 *	- aligned priests without ispriest and Angels are roamers
238 *		they retain isminion and access epri as emin when polymorphed
239 *		(coaligned Angels are also created as minions, but they
240 *		use the same naming convention)
241 *	- minions do not have ispriest but have isminion and emin
242 *	- caller needs to inhibit Hallucination if it wants to force
243 *		the true name even when under that influence
244 */
245char *
246priestname(mon, pname)
247register struct monst *mon;
248char *pname;		/* caller-supplied output buffer */
249{
250	const char *what = Hallucination ? rndmonnam() : mon->data->mname;
251
252	Strcpy(pname, "the ");
253	if (mon->minvis) Strcat(pname, "invisible ");
254	if (mon->ispriest || mon->data == &mons[PM_ALIGNED_PRIEST] ||
255					mon->data == &mons[PM_ANGEL]) {
256		/* use epri */
257		if (mon->mtame && mon->data == &mons[PM_ANGEL])
258			Strcat(pname, "guardian ");
259		if (mon->data != &mons[PM_ALIGNED_PRIEST] &&
260				mon->data != &mons[PM_HIGH_PRIEST]) {
261			Strcat(pname, what);
262			Strcat(pname, " ");
263		}
264		if (mon->data != &mons[PM_ANGEL]) {
265			if (!mon->ispriest && EPRI(mon)->renegade)
266				Strcat(pname, "renegade ");
267			if (mon->data == &mons[PM_HIGH_PRIEST])
268				Strcat(pname, "high ");
269			if (Hallucination)
270				Strcat(pname, "poohbah ");
271			else if (mon->female)
272				Strcat(pname, "priestess ");
273			else
274				Strcat(pname, "priest ");
275		}
276		Strcat(pname, "of ");
277		Strcat(pname, halu_gname((int)EPRI(mon)->shralign));
278		return(pname);
279	}
280	/* use emin instead of epri */
281	Strcat(pname, what);
282	Strcat(pname, " of ");
283	Strcat(pname, halu_gname(EMIN(mon)->min_align));
284	return(pname);
285}
286
287boolean
288p_coaligned(priest)
289struct monst *priest;
290{
291	return((boolean)(u.ualign.type == ((int)EPRI(priest)->shralign)));
292}
293
294STATIC_OVL boolean
295has_shrine(pri)
296struct monst *pri;
297{
298	struct rm *lev;
299
300	if(!pri)
301		return(FALSE);
302	lev = &levl[EPRI(pri)->shrpos.x][EPRI(pri)->shrpos.y];
303	if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE))
304		return(FALSE);
305	return((boolean)(EPRI(pri)->shralign == Amask2align(lev->altarmask & ~AM_SHRINE)));
306}
307
308struct monst *
309findpriest(roomno)
310char roomno;
311{
312	register struct monst *mtmp;
313
314	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
315	    if (DEADMONSTER(mtmp)) continue;
316	    if(mtmp->ispriest && (EPRI(mtmp)->shroom == roomno) &&
317	       histemple_at(mtmp,mtmp->mx,mtmp->my))
318		return(mtmp);
319	}
320	return (struct monst *)0;
321}
322
323/* called from check_special_room() when the player enters the temple room */
324void
325intemple(roomno)
326register int roomno;
327{
328	register struct monst *priest = findpriest((char)roomno);
329	boolean tended = (priest != (struct monst *)0);
330	boolean shrined, sanctum, can_speak;
331	const char *msg1, *msg2;
332	char buf[BUFSZ];
333
334	if(!temple_occupied(u.urooms0)) {
335	    if(tended) {
336		shrined = has_shrine(priest);
337		sanctum = (priest->data == &mons[PM_HIGH_PRIEST] &&
338			   (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
339		can_speak = (priest->mcanmove && !priest->msleeping &&
340			     flags.soundok);
341		if (can_speak) {
342		    unsigned save_priest = priest->ispriest;
343		    /* don't reveal the altar's owner upon temple entry in
344		       the endgame; for the Sanctum, the next message names
345		       Moloch so suppress the "of Moloch" for him here too */
346		    if (sanctum && !Hallucination) priest->ispriest = 0;
347		    pline("%s intones:",
348			canseemon(priest) ? Monnam(priest) : "A nearby voice");
349		    priest->ispriest = save_priest;
350		}
351		msg2 = 0;
352		if(sanctum && Is_sanctum(&u.uz)) {
353		    if(priest->mpeaceful) {
354			msg1 = "Infidel, you have 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 <= ALGN_SINNED)
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		    if (!Blind || sensemon(mtmp))
390			pline("An enormous ghost appears next to you!");
391		    else You("sense a presence close by!");
392		    mtmp->mpeaceful = 0;
393		    set_malign(mtmp);
394		    if(flags.verbose)
395			You("are frightened to death, and unable to move.");
396		    nomul(-3);
397		    nomovemsg = "You regain your composure.";
398	       }
399	   }
400       }
401}
402
403void
404priest_talk(priest)
405register struct monst *priest;
406{
407	boolean coaligned = p_coaligned(priest);
408	boolean strayed = (u.ualign.record < 0);
409
410	/* KMH, conduct */
411	u.uconduct.gnostic++;
412
413	if(priest->mflee || (!priest->ispriest && coaligned && strayed)) {
414	    pline("%s doesn't want anything to do with you!",
415				Monnam(priest));
416	    priest->mpeaceful = 0;
417	    return;
418	}
419
420	/* priests don't chat unless peaceful and in their own temple */
421	if(!histemple_at(priest,priest->mx,priest->my) ||
422		 !priest->mpeaceful || !priest->mcanmove || priest->msleeping) {
423	    static const char *cranky_msg[3] = {
424		"Thou wouldst have words, eh?  I'll give thee a word or two!",
425		"Talk?  Here is what I have to say!",
426		"Pilgrim, I would speak no longer with thee."
427	    };
428
429	    if(!priest->mcanmove || priest->msleeping) {
430		pline("%s breaks out of %s reverie!",
431		      Monnam(priest), mhis(priest));
432		priest->mfrozen = priest->msleeping = 0;
433		priest->mcanmove = 1;
434	    }
435	    priest->mpeaceful = 0;
436	    verbalize(cranky_msg[rn2(3)]);
437	    return;
438	}
439
440	/* you desecrated the temple and now you want to chat? */
441	if(priest->mpeaceful && *in_rooms(priest->mx, priest->my, TEMPLE) &&
442		  !has_shrine(priest)) {
443	    verbalize("Begone!  Thou desecratest this holy place with thy presence.");
444	    priest->mpeaceful = 0;
445	    return;
446	}
447#ifndef GOLDOBJ
448	if(!u.ugold) {
449	    if(coaligned && !strayed) {
450		if (priest->mgold > 0L) {
451		    /* Note: two bits is actually 25 cents.  Hmm. */
452		    pline("%s gives you %s for an ale.", Monnam(priest),
453			(priest->mgold == 1L) ? "one bit" : "two bits");
454		    if (priest->mgold > 1L)
455			u.ugold = 2L;
456		    else
457			u.ugold = 1L;
458		    priest->mgold -= u.ugold;
459		    flags.botl = 1;
460#else
461	if(!money_cnt(invent)) {
462	    if(coaligned && !strayed) {
463                long pmoney = money_cnt(priest->minvent);
464		if (pmoney > 0L) {
465		    /* Note: two bits is actually 25 cents.  Hmm. */
466		    pline("%s gives you %s for an ale.", Monnam(priest),
467			(pmoney == 1L) ? "one bit" : "two bits");
468		     money2u(priest, pmoney > 1L ? 2 : 1);
469#endif
470		} else
471		    pline("%s preaches the virtues of poverty.", Monnam(priest));
472		exercise(A_WIS, TRUE);
473	    } else
474		pline("%s is not interested.", Monnam(priest));
475	    return;
476	} else {
477	    long offer;
478
479	    pline("%s asks you for a contribution for the temple.",
480			Monnam(priest));
481	    if((offer = bribe(priest)) == 0) {
482		verbalize("Thou shalt regret thine action!");
483		if(coaligned) adjalign(-1);
484	    } else if(offer < (u.ulevel * 200)) {
485#ifndef GOLDOBJ
486		if(u.ugold > (offer * 2L)) verbalize("Cheapskate.");
487#else
488		if(money_cnt(invent) > (offer * 2L)) verbalize("Cheapskate.");
489#endif
490		else {
491		    verbalize("I thank thee for thy contribution.");
492		    /*  give player some token  */
493		    exercise(A_WIS, TRUE);
494		}
495	    } else if(offer < (u.ulevel * 400)) {
496		verbalize("Thou art indeed a pious individual.");
497#ifndef GOLDOBJ
498		if(u.ugold < (offer * 2L)) {
499#else
500		if(money_cnt(invent) < (offer * 2L)) {
501#endif
502		    if (coaligned && u.ualign.record <= ALGN_SINNED)
503			adjalign(1);
504		    verbalize("I bestow upon thee a blessing.");
505		    incr_itimeout(&HClairvoyant, rn1(500,500));
506		}
507	    } else if(offer < (u.ulevel * 600) &&
508		      u.ublessed < 20 &&
509		      (u.ublessed < 9 || !rn2(u.ublessed))) {
510		verbalize("Thy devotion has been rewarded.");
511		if (!(HProtection & INTRINSIC))  {
512			HProtection |= FROMOUTSIDE;
513			if (!u.ublessed)  u.ublessed = rn1(3, 2);
514		} else u.ublessed++;
515	    } else {
516		verbalize("Thy selfless generosity is deeply appreciated.");
517#ifndef GOLDOBJ
518		if(u.ugold < (offer * 2L) && coaligned) {
519#else
520		if(money_cnt(invent) < (offer * 2L) && coaligned) {
521#endif
522		    if(strayed && (moves - u.ucleansed) > 5000L) {
523			u.ualign.record = 0; /* cleanse thee */
524			u.ucleansed = moves;
525		    } else {
526			adjalign(2);
527		    }
528		}
529	    }
530	}
531}
532
533struct monst *
534mk_roamer(ptr, alignment, x, y, peaceful)
535register struct permonst *ptr;
536aligntyp alignment;
537xchar x, y;
538boolean peaceful;
539{
540	register struct monst *roamer;
541	register boolean coaligned = (u.ualign.type == alignment);
542
543	if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL])
544		return((struct monst *)0);
545
546	if (MON_AT(x, y)) (void) rloc(m_at(x, y), FALSE);	/* insurance */
547
548	if (!(roamer = makemon(ptr, x, y, NO_MM_FLAGS)))
549		return((struct monst *)0);
550
551	EPRI(roamer)->shralign = alignment;
552	if (coaligned && !peaceful)
553		EPRI(roamer)->renegade = TRUE;
554	/* roamer->ispriest == FALSE naturally */
555	roamer->isminion = TRUE;	/* borrowing this bit */
556	roamer->mtrapseen = ~0;		/* traps are known */
557	roamer->mpeaceful = peaceful;
558	roamer->msleeping = 0;
559	set_malign(roamer); /* peaceful may have changed */
560
561	/* MORE TO COME */
562	return(roamer);
563}
564
565void
566reset_hostility(roamer)
567register struct monst *roamer;
568{
569	if(!(roamer->isminion && (roamer->data == &mons[PM_ALIGNED_PRIEST] ||
570				  roamer->data == &mons[PM_ANGEL])))
571	        return;
572
573	if(EPRI(roamer)->shralign != u.ualign.type) {
574	    roamer->mpeaceful = roamer->mtame = 0;
575	    set_malign(roamer);
576	}
577	newsym(roamer->mx, roamer->my);
578}
579
580boolean
581in_your_sanctuary(mon, x, y)
582struct monst *mon;	/* if non-null, <mx,my> overrides <x,y> */
583xchar x, y;
584{
585	register char roomno;
586	register struct monst *priest;
587
588	if (mon) {
589	    if (is_minion(mon->data) || is_rider(mon->data)) return FALSE;
590	    x = mon->mx, y = mon->my;
591	}
592	if (u.ualign.record <= ALGN_SINNED)	/* sinned or worse */
593	    return FALSE;
594	if ((roomno = temple_occupied(u.urooms)) == 0 ||
595		roomno != *in_rooms(x, y, TEMPLE))
596	    return FALSE;
597	if ((priest = findpriest(roomno)) == 0)
598	    return FALSE;
599	return (boolean)(has_shrine(priest) &&
600			 p_coaligned(priest) &&
601			 priest->mpeaceful);
602}
603
604void
605ghod_hitsu(priest)	/* when attacking "priest" in his temple */
606struct monst *priest;
607{
608	int x, y, ax, ay, roomno = (int)temple_occupied(u.urooms);
609	struct mkroom *troom;
610
611	if (!roomno || !has_shrine(priest))
612		return;
613
614	ax = x = EPRI(priest)->shrpos.x;
615	ay = y = EPRI(priest)->shrpos.y;
616	troom = &rooms[roomno - ROOMOFFSET];
617
618	if((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y)) {
619	    if(IS_DOOR(levl[u.ux][u.uy].typ)) {
620
621		if(u.ux == troom->lx - 1) {
622		    x = troom->hx;
623		    y = u.uy;
624		} else if(u.ux == troom->hx + 1) {
625		    x = troom->lx;
626		    y = u.uy;
627		} else if(u.uy == troom->ly - 1) {
628		    x = u.ux;
629		    y = troom->hy;
630		} else if(u.uy == troom->hy + 1) {
631		    x = u.ux;
632		    y = troom->ly;
633		}
634	    } else {
635		switch(rn2(4)) {
636		case 0:  x = u.ux; y = troom->ly; break;
637		case 1:  x = u.ux; y = troom->hy; break;
638		case 2:  x = troom->lx; y = u.uy; break;
639		default: x = troom->hx; y = u.uy; break;
640		}
641	    }
642	    if(!linedup(u.ux, u.uy, x, y)) return;
643	}
644
645	switch(rn2(3)) {
646	case 0:
647	    pline("%s roars in anger:  \"Thou shalt suffer!\"",
648			a_gname_at(ax, ay));
649	    break;
650	case 1:
651	    pline("%s voice booms:  \"How darest thou harm my servant!\"",
652			s_suffix(a_gname_at(ax, ay)));
653	    break;
654	default:
655	    pline("%s roars:  \"Thou dost profane my shrine!\"",
656			a_gname_at(ax, ay));
657	    break;
658	}
659
660	buzz(-10-(AD_ELEC-1), 6, x, y, sgn(tbx), sgn(tby)); /* bolt of lightning */
661	exercise(A_WIS, FALSE);
662}
663
664void
665angry_priest()
666{
667	register struct monst *priest;
668	struct rm *lev;
669
670	if ((priest = findpriest(temple_occupied(u.urooms))) != 0) {
671	    wakeup(priest);
672	    /*
673	     * If the altar has been destroyed or converted, let the
674	     * priest run loose.
675	     * (When it's just a conversion and there happens to be
676	     *	a fresh corpse nearby, the priest ought to have an
677	     *	opportunity to try converting it back; maybe someday...)
678	     */
679	    lev = &levl[EPRI(priest)->shrpos.x][EPRI(priest)->shrpos.y];
680	    if (!IS_ALTAR(lev->typ) ||
681		((aligntyp)Amask2align(lev->altarmask & AM_MASK) !=
682			EPRI(priest)->shralign)) {
683		priest->ispriest = 0;		/* now a roamer */
684		priest->isminion = 1;		/* but still aligned */
685		/* this overloads the `shroom' field, which is now clobbered */
686		EPRI(priest)->renegade = 0;
687	    }
688	}
689}
690
691/*
692 * When saving bones, find priests that aren't on their shrine level,
693 * and remove them.   This avoids big problems when restoring bones.
694 */
695void
696clearpriests()
697{
698    register struct monst *mtmp, *mtmp2;
699
700    for(mtmp = fmon; mtmp; mtmp = mtmp2) {
701	mtmp2 = mtmp->nmon;
702	if (!DEADMONSTER(mtmp) && mtmp->ispriest && !on_level(&(EPRI(mtmp)->shrlevel), &u.uz))
703	    mongone(mtmp);
704    }
705}
706
707/* munge priest-specific structure when restoring -dlc */
708void
709restpriest(mtmp, ghostly)
710register struct monst *mtmp;
711boolean ghostly;
712{
713    if(u.uz.dlevel) {
714	if (ghostly)
715	    assign_level(&(EPRI(mtmp)->shrlevel), &u.uz);
716    }
717}
718
719#endif /* OVLB */
720
721/*priest.c*/
722