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