Move getpos return values to header
[aNetHack.git] / src / priest.c
blobec76c91bbe42d043a184ab158a62f11e537a4374
1 /* NetHack 3.6 priest.c $NHDT-Date: 1446892452 2015/11/07 10:34:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.41 $ */
2 /* Copyright (c) Izchak Miller, Steve Linhart, 1989. */
3 /* NetHack may be freely redistributed. See license for details. */
5 #include "hack.h"
6 #include "mfndpos.h"
8 /* these match the categorizations shown by enlightenment */
9 #define ALGN_SINNED (-4) /* worse than strayed (-1..-3) */
10 #define ALGN_PIOUS 14 /* better than fervent (9..13) */
12 STATIC_DCL boolean FDECL(histemple_at, (struct monst *, XCHAR_P, XCHAR_P));
13 STATIC_DCL boolean FDECL(has_shrine, (struct monst *));
15 void
16 newepri(mtmp)
17 struct monst *mtmp;
19 if (!mtmp->mextra)
20 mtmp->mextra = newmextra();
21 if (!EPRI(mtmp)) {
22 EPRI(mtmp) = (struct epri *) alloc(sizeof(struct epri));
23 (void) memset((genericptr_t) EPRI(mtmp), 0, sizeof(struct epri));
27 void
28 free_epri(mtmp)
29 struct monst *mtmp;
31 if (mtmp->mextra && EPRI(mtmp)) {
32 free((genericptr_t) EPRI(mtmp));
33 EPRI(mtmp) = (struct epri *) 0;
35 mtmp->ispriest = 0;
39 * Move for priests and shopkeepers. Called from shk_move() and pri_move().
40 * Valid returns are 1: moved 0: didn't -1: let m_move do it -2: died.
42 int
43 move_special(mtmp, in_his_shop, appr, uondoor, avoid, omx, omy, gx, gy)
44 register struct monst *mtmp;
45 boolean in_his_shop;
46 schar appr;
47 boolean uondoor, avoid;
48 register xchar omx, omy, gx, gy;
50 register xchar nx, ny, nix, niy;
51 register schar i;
52 schar chcnt, cnt;
53 coord poss[9];
54 long info[9];
55 long allowflags;
56 struct obj *ib = (struct obj *) 0;
58 if (omx == gx && omy == gy)
59 return 0;
60 if (mtmp->mconf) {
61 avoid = FALSE;
62 appr = 0;
65 nix = omx;
66 niy = omy;
67 if (mtmp->isshk)
68 allowflags = ALLOW_SSM;
69 else
70 allowflags = ALLOW_SSM | ALLOW_SANCT;
71 if (passes_walls(mtmp->data))
72 allowflags |= (ALLOW_ROCK | ALLOW_WALL);
73 if (throws_rocks(mtmp->data))
74 allowflags |= ALLOW_ROCK;
75 if (tunnels(mtmp->data))
76 allowflags |= ALLOW_DIG;
77 if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
78 allowflags |= OPENDOOR;
79 if (monhaskey(mtmp, TRUE))
80 allowflags |= UNLOCKDOOR;
82 if (is_giant(mtmp->data))
83 allowflags |= BUSTDOOR;
84 cnt = mfndpos(mtmp, poss, info, allowflags);
86 if (mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */
87 for (i = 0; i < cnt; i++)
88 if (!(info[i] & NOTONL))
89 goto pick_move;
90 avoid = FALSE;
93 #define GDIST(x, y) (dist2(x, y, gx, gy))
94 pick_move:
95 chcnt = 0;
96 for (i = 0; i < cnt; i++) {
97 nx = poss[i].x;
98 ny = poss[i].y;
99 if (IS_ROOM(levl[nx][ny].typ)
100 || (mtmp->isshk && (!in_his_shop || ESHK(mtmp)->following))) {
101 if (avoid && (info[i] & NOTONL))
102 continue;
103 if ((!appr && !rn2(++chcnt))
104 || (appr && GDIST(nx, ny) < GDIST(nix, niy))) {
105 nix = nx;
106 niy = ny;
110 if (mtmp->ispriest && avoid && nix == omx && niy == omy
111 && onlineu(omx, omy)) {
112 /* might as well move closer as long it's going to stay
113 * lined up */
114 avoid = FALSE;
115 goto pick_move;
118 if (nix != omx || niy != omy) {
119 remove_monster(omx, omy);
120 place_monster(mtmp, nix, niy);
121 newsym(nix, niy);
122 if (mtmp->isshk && !in_his_shop && inhishop(mtmp))
123 check_special_room(FALSE);
124 if (ib) {
125 if (cansee(mtmp->mx, mtmp->my))
126 pline("%s picks up %s.", Monnam(mtmp),
127 distant_name(ib, doname));
128 obj_extract_self(ib);
129 (void) mpickobj(mtmp, ib);
131 return 1;
133 return 0;
136 char
137 temple_occupied(array)
138 register char *array;
140 register char *ptr;
142 for (ptr = array; *ptr; ptr++)
143 if (rooms[*ptr - ROOMOFFSET].rtype == TEMPLE)
144 return *ptr;
145 return '\0';
148 STATIC_OVL boolean
149 histemple_at(priest, x, y)
150 register struct monst *priest;
151 register xchar x, y;
153 return (boolean) (priest && priest->ispriest
154 && (EPRI(priest)->shroom == *in_rooms(x, y, TEMPLE))
155 && on_level(&(EPRI(priest)->shrlevel), &u.uz));
158 boolean
159 inhistemple(priest)
160 struct monst *priest;
162 /* make sure we have a priest */
163 if (!priest || !priest->ispriest)
164 return FALSE;
165 /* priest must be on right level and in right room */
166 if (!histemple_at(priest, priest->mx, priest->my))
167 return FALSE;
168 /* temple room must still contain properly aligned altar */
169 return has_shrine(priest);
173 * pri_move: return 1: moved 0: didn't -1: let m_move do it -2: died
176 pri_move(priest)
177 register struct monst *priest;
179 register xchar gx, gy, omx, omy;
180 schar temple;
181 boolean avoid = TRUE;
183 omx = priest->mx;
184 omy = priest->my;
186 if (!histemple_at(priest, omx, omy))
187 return -1;
189 temple = EPRI(priest)->shroom;
191 gx = EPRI(priest)->shrpos.x;
192 gy = EPRI(priest)->shrpos.y;
194 gx += rn1(3, -1); /* mill around the altar */
195 gy += rn1(3, -1);
197 if (!priest->mpeaceful
198 || (Conflict && !resist(priest, RING_CLASS, 0, 0))) {
199 if (monnear(priest, u.ux, u.uy)) {
200 if (Displaced)
201 Your("displaced image doesn't fool %s!", mon_nam(priest));
202 (void) mattacku(priest);
203 return 0;
204 } else if (index(u.urooms, temple)) {
205 /* chase player if inside temple & can see him */
206 if (priest->mcansee && m_canseeu(priest)) {
207 gx = u.ux;
208 gy = u.uy;
210 avoid = FALSE;
212 } else if (Invis)
213 avoid = FALSE;
215 return move_special(priest, FALSE, TRUE, FALSE, avoid, omx, omy, gx, gy);
218 /* exclusively for mktemple() */
219 void
220 priestini(lvl, sroom, sx, sy, sanctum)
221 d_level *lvl;
222 struct mkroom *sroom;
223 int sx, sy;
224 boolean sanctum; /* is it the seat of the high priest? */
226 struct monst *priest;
227 struct obj *otmp;
228 int cnt;
230 if (MON_AT(sx + 1, sy))
231 (void) rloc(m_at(sx + 1, sy), FALSE); /* insurance */
233 priest = makemon(&mons[sanctum ? PM_HIGH_PRIEST : PM_ALIGNED_PRIEST],
234 sx + 1, sy, MM_EPRI);
235 if (priest) {
236 EPRI(priest)->shroom = (schar) ((sroom - rooms) + ROOMOFFSET);
237 EPRI(priest)->shralign = Amask2align(levl[sx][sy].altarmask);
238 EPRI(priest)->shrpos.x = sx;
239 EPRI(priest)->shrpos.y = sy;
240 assign_level(&(EPRI(priest)->shrlevel), lvl);
241 priest->mtrapseen = ~0; /* traps are known */
242 priest->mpeaceful = 1;
243 priest->ispriest = 1;
244 priest->isminion = 0;
245 priest->msleeping = 0;
246 set_malign(priest); /* mpeaceful may have changed */
248 /* now his/her goodies... */
249 if (sanctum && EPRI(priest)->shralign == A_NONE
250 && on_level(&sanctum_level, &u.uz)) {
251 (void) mongets(priest, AMULET_OF_YENDOR);
253 /* 2 to 4 spellbooks */
254 for (cnt = rn1(3, 2); cnt > 0; --cnt) {
255 (void) mpickobj(priest, mkobj(SPBOOK_CLASS, FALSE));
257 /* robe [via makemon()] */
258 if (rn2(2) && (otmp = which_armor(priest, W_ARMC)) != 0) {
259 if (p_coaligned(priest))
260 uncurse(otmp);
261 else
262 curse(otmp);
267 /* get a monster's alignment type without caller needing EPRI & EMIN */
268 aligntyp
269 mon_aligntyp(mon)
270 struct monst *mon;
272 aligntyp algn = mon->ispriest ? EPRI(mon)->shralign
273 : mon->isminion ? EMIN(mon)->min_align
274 : mon->data->maligntyp;
276 if (algn == A_NONE)
277 return A_NONE; /* negative but differs from chaotic */
278 return (algn > 0) ? A_LAWFUL : (algn < 0) ? A_CHAOTIC : A_NEUTRAL;
282 * Specially aligned monsters are named specially.
283 * - aligned priests with ispriest and high priests have shrines
284 * they retain ispriest and epri when polymorphed
285 * - aligned priests without ispriest are roamers
286 * they have isminion set and use emin rather than epri
287 * - minions do not have ispriest but have isminion and emin
288 * - caller needs to inhibit Hallucination if it wants to force
289 * the true name even when under that influence
291 char *
292 priestname(mon, pname)
293 register struct monst *mon;
294 char *pname; /* caller-supplied output buffer */
296 boolean do_hallu = Hallucination,
297 aligned_priest = mon->data == &mons[PM_ALIGNED_PRIEST],
298 high_priest = mon->data == &mons[PM_HIGH_PRIEST];
299 char whatcode = '\0';
300 const char *what = do_hallu ? rndmonnam(&whatcode) : mon->data->mname;
302 if (!mon->ispriest && !mon->isminion) /* should never happen... */
303 return strcpy(pname, what); /* caller must be confused */
305 *pname = '\0';
306 if (!do_hallu || !bogon_is_pname(whatcode))
307 Strcat(pname, "the ");
308 if (mon->minvis)
309 Strcat(pname, "invisible ");
310 if (mon->isminion && EMIN(mon)->renegade)
311 Strcat(pname, "renegade ");
313 if (mon->ispriest || aligned_priest) { /* high_priest implies ispriest */
314 if (!aligned_priest && !high_priest) {
315 ; /* polymorphed priest; use ``what'' as is */
316 } else {
317 if (high_priest)
318 Strcat(pname, "high ");
319 if (Hallucination)
320 what = "poohbah";
321 else if (mon->female)
322 what = "priestess";
323 else
324 what = "priest";
326 } else {
327 if (mon->mtame && !strcmpi(what, "Angel"))
328 Strcat(pname, "guardian ");
331 Strcat(pname, what);
332 /* same as distant_monnam(), more or less... */
333 if (do_hallu || !high_priest || !Is_astralevel(&u.uz)
334 || distu(mon->mx, mon->my) <= 2 || program_state.gameover) {
335 Strcat(pname, " of ");
336 Strcat(pname, halu_gname(mon_aligntyp(mon)));
338 return pname;
341 boolean
342 p_coaligned(priest)
343 struct monst *priest;
345 return (boolean) (u.ualign.type == mon_aligntyp(priest));
348 STATIC_OVL boolean
349 has_shrine(pri)
350 struct monst *pri;
352 struct rm *lev;
353 struct epri *epri_p;
355 if (!pri || !pri->ispriest)
356 return FALSE;
357 epri_p = EPRI(pri);
358 lev = &levl[epri_p->shrpos.x][epri_p->shrpos.y];
359 if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE))
360 return FALSE;
361 return (boolean) (epri_p->shralign
362 == (Amask2align(lev->altarmask & ~AM_SHRINE)));
365 struct monst *
366 findpriest(roomno)
367 char roomno;
369 register struct monst *mtmp;
371 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
372 if (DEADMONSTER(mtmp))
373 continue;
374 if (mtmp->ispriest && (EPRI(mtmp)->shroom == roomno)
375 && histemple_at(mtmp, mtmp->mx, mtmp->my))
376 return mtmp;
378 return (struct monst *) 0;
381 /* called from check_special_room() when the player enters the temple room */
382 void
383 intemple(roomno)
384 int roomno;
386 struct monst *priest, *mtmp;
387 struct epri *epri_p;
388 boolean shrined, sanctum, can_speak;
389 long *this_time, *other_time;
390 const char *msg1, *msg2;
391 char buf[BUFSZ];
393 /* don't do anything if hero is already in the room */
394 if (temple_occupied(u.urooms0))
395 return;
397 if ((priest = findpriest((char) roomno)) != 0) {
398 /* tended */
400 epri_p = EPRI(priest);
401 shrined = has_shrine(priest);
402 sanctum = (priest->data == &mons[PM_HIGH_PRIEST]
403 && (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
404 can_speak = (priest->mcanmove && !priest->msleeping);
405 if (can_speak && !Deaf && moves >= epri_p->intone_time) {
406 unsigned save_priest = priest->ispriest;
408 /* don't reveal the altar's owner upon temple entry in
409 the endgame; for the Sanctum, the next message names
410 Moloch so suppress the "of Moloch" for him here too */
411 if (sanctum && !Hallucination)
412 priest->ispriest = 0;
413 pline("%s intones:",
414 canseemon(priest) ? Monnam(priest) : "A nearby voice");
415 priest->ispriest = save_priest;
416 epri_p->intone_time = moves + (long) d(10, 500); /* ~2505 */
417 /* make sure that we don't suppress entry message when
418 we've just given its "priest intones" introduction */
419 epri_p->enter_time = 0L;
421 msg1 = msg2 = 0;
422 if (sanctum && Is_sanctum(&u.uz)) {
423 if (priest->mpeaceful) {
424 /* first time inside */
425 msg1 = "Infidel, you have entered Moloch's Sanctum!";
426 msg2 = "Be gone!";
427 priest->mpeaceful = 0;
428 /* became angry voluntarily; no penalty for attacking him */
429 set_malign(priest);
430 } else {
431 /* repeat visit, or attacked priest before entering */
432 msg1 = "You desecrate this place by your presence!";
434 } else if (moves >= epri_p->enter_time) {
435 Sprintf(buf, "Pilgrim, you enter a %s place!",
436 !shrined ? "desecrated" : "sacred");
437 msg1 = buf;
439 if (msg1 && can_speak && !Deaf) {
440 verbalize1(msg1);
441 if (msg2)
442 verbalize1(msg2);
443 epri_p->enter_time = moves + (long) d(10, 100); /* ~505 */
445 if (!sanctum) {
446 if (!shrined || !p_coaligned(priest)
447 || u.ualign.record <= ALGN_SINNED) {
448 msg1 = "have a%s forbidding feeling...";
449 msg2 = (!shrined || !p_coaligned(priest)) ? "" : " strange";
450 this_time = &epri_p->hostile_time;
451 other_time = &epri_p->peaceful_time;
452 } else {
453 msg1 = "experience %s sense of peace.";
454 msg2 = (u.ualign.record >= ALGN_PIOUS) ? "a" : "an unusual";
455 this_time = &epri_p->peaceful_time;
456 other_time = &epri_p->hostile_time;
458 /* give message if we haven't seen it recently or
459 if alignment update has caused it to switch from
460 forbidding to sense-of-peace or vice versa */
461 if (moves >= *this_time || *other_time >= *this_time) {
462 You(msg1, msg2);
463 *this_time = moves + (long) d(10, 20); /* ~55 */
464 /* avoid being tricked by the RNG: switch might have just
465 happened and previous random threshold could be larger */
466 if (*this_time <= *other_time)
467 *other_time = *this_time - 1L;
470 /* recognize the Valley of the Dead and Moloch's Sanctum
471 once hero has encountered the temple priest on those levels */
472 mapseen_temple(priest);
473 } else {
474 /* untended */
476 switch (rn2(4)) {
477 case 0:
478 You("have an eerie feeling...");
479 break;
480 case 1:
481 You_feel("like you are being watched.");
482 break;
483 case 2:
484 pline("A shiver runs down your %s.", body_part(SPINE));
485 break;
486 default:
487 break; /* no message; unfortunately there's no
488 EPRI(priest)->eerie_time available to
489 make sure we give one the first time */
491 if (!rn2(5)
492 && (mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, NO_MM_FLAGS))
493 != 0) {
494 int ngen = mvitals[PM_GHOST].born;
495 if (canspotmon(mtmp))
496 pline("A%s ghost appears next to you%c",
497 ngen < 5 ? "n enormous" : "",
498 ngen < 10 ? '!' : '.');
499 else
500 You("sense a presence close by!");
501 mtmp->mpeaceful = 0;
502 set_malign(mtmp);
503 if (flags.verbose)
504 You("are frightened to death, and unable to move.");
505 nomul(-3);
506 multi_reason = "being terrified of a ghost";
507 nomovemsg = "You regain your composure.";
512 /* reset the move counters used to limit temple entry feedback;
513 leaving the level and then returning yields a fresh start */
514 void
515 forget_temple_entry(priest)
516 struct monst *priest;
518 struct epri *epri_p = priest->ispriest ? EPRI(priest) : 0;
520 if (!epri_p) {
521 impossible("attempting to manipulate shrine data for non-priest?");
522 return;
524 epri_p->intone_time = epri_p->enter_time = epri_p->peaceful_time =
525 epri_p->hostile_time = 0L;
528 void
529 priest_talk(priest)
530 register struct monst *priest;
532 boolean coaligned = p_coaligned(priest);
533 boolean strayed = (u.ualign.record < 0);
535 /* KMH, conduct */
536 u.uconduct.gnostic++;
538 if (priest->mflee || (!priest->ispriest && coaligned && strayed)) {
539 pline("%s doesn't want anything to do with you!", Monnam(priest));
540 priest->mpeaceful = 0;
541 return;
544 /* priests don't chat unless peaceful and in their own temple */
545 if (!inhistemple(priest) || !priest->mpeaceful
546 || !priest->mcanmove || priest->msleeping) {
547 static const char *cranky_msg[3] = {
548 "Thou wouldst have words, eh? I'll give thee a word or two!",
549 "Talk? Here is what I have to say!",
550 "Pilgrim, I would speak no longer with thee."
553 if (!priest->mcanmove || priest->msleeping) {
554 pline("%s breaks out of %s reverie!", Monnam(priest),
555 mhis(priest));
556 priest->mfrozen = priest->msleeping = 0;
557 priest->mcanmove = 1;
559 priest->mpeaceful = 0;
560 verbalize1(cranky_msg[rn2(3)]);
561 return;
564 /* you desecrated the temple and now you want to chat? */
565 if (priest->mpeaceful && *in_rooms(priest->mx, priest->my, TEMPLE)
566 && !has_shrine(priest)) {
567 verbalize(
568 "Begone! Thou desecratest this holy place with thy presence.");
569 priest->mpeaceful = 0;
570 return;
572 if (!money_cnt(invent)) {
573 if (coaligned && !strayed) {
574 long pmoney = money_cnt(priest->minvent);
575 if (pmoney > 0L) {
576 /* Note: two bits is actually 25 cents. Hmm. */
577 pline("%s gives you %s for an ale.", Monnam(priest),
578 (pmoney == 1L) ? "one bit" : "two bits");
579 money2u(priest, pmoney > 1L ? 2 : 1);
580 } else
581 pline("%s preaches the virtues of poverty.", Monnam(priest));
582 exercise(A_WIS, TRUE);
583 } else
584 pline("%s is not interested.", Monnam(priest));
585 return;
586 } else {
587 long offer;
589 pline("%s asks you for a contribution for the temple.",
590 Monnam(priest));
591 if ((offer = bribe(priest)) == 0) {
592 verbalize("Thou shalt regret thine action!");
593 if (coaligned)
594 adjalign(-1);
595 } else if (offer < (u.ulevel * 200)) {
596 if (money_cnt(invent) > (offer * 2L)) {
597 verbalize("Cheapskate.");
598 } else {
599 verbalize("I thank thee for thy contribution.");
600 /* give player some token */
601 exercise(A_WIS, TRUE);
603 } else if (offer < (u.ulevel * 400)) {
604 verbalize("Thou art indeed a pious individual.");
605 if (money_cnt(invent) < (offer * 2L)) {
606 if (coaligned && u.ualign.record <= ALGN_SINNED)
607 adjalign(1);
608 verbalize("I bestow upon thee a blessing.");
609 incr_itimeout(&HClairvoyant, rn1(500, 500));
611 } else if (offer < (u.ulevel * 600)
612 /* u.ublessed is only active when Protection is
613 enabled via something other than worn gear
614 (theft by gremlin clears the intrinsic but not
615 its former magnitude, making it recoverable) */
616 && (!(HProtection & INTRINSIC)
617 || (u.ublessed < 20
618 && (u.ublessed < 9 || !rn2(u.ublessed))))) {
619 verbalize("Thy devotion has been rewarded.");
620 if (!(HProtection & INTRINSIC)) {
621 HProtection |= FROMOUTSIDE;
622 if (!u.ublessed)
623 u.ublessed = rn1(3, 2);
624 } else
625 u.ublessed++;
626 } else {
627 verbalize("Thy selfless generosity is deeply appreciated.");
628 if (money_cnt(invent) < (offer * 2L) && coaligned) {
629 if (strayed && (moves - u.ucleansed) > 5000L) {
630 u.ualign.record = 0; /* cleanse thee */
631 u.ucleansed = moves;
632 } else {
633 adjalign(2);
640 struct monst *
641 mk_roamer(ptr, alignment, x, y, peaceful)
642 register struct permonst *ptr;
643 aligntyp alignment;
644 xchar x, y;
645 boolean peaceful;
647 register struct monst *roamer;
648 register boolean coaligned = (u.ualign.type == alignment);
650 #if 0 /* this was due to permonst's pxlth field which is now gone */
651 if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL])
652 return (struct monst *) 0;
653 #endif
655 if (MON_AT(x, y))
656 (void) rloc(m_at(x, y), FALSE); /* insurance */
658 if (!(roamer = makemon(ptr, x, y, MM_ADJACENTOK | MM_EMIN)))
659 return (struct monst *) 0;
661 EMIN(roamer)->min_align = alignment;
662 EMIN(roamer)->renegade = (coaligned && !peaceful);
663 roamer->ispriest = 0;
664 roamer->isminion = 1;
665 roamer->mtrapseen = ~0; /* traps are known */
666 roamer->mpeaceful = peaceful;
667 roamer->msleeping = 0;
668 set_malign(roamer); /* peaceful may have changed */
670 /* MORE TO COME */
671 return roamer;
674 void
675 reset_hostility(roamer)
676 register struct monst *roamer;
678 if (!roamer->isminion)
679 return;
680 if (roamer->data != &mons[PM_ALIGNED_PRIEST]
681 && roamer->data != &mons[PM_ANGEL])
682 return;
684 if (EMIN(roamer)->min_align != u.ualign.type) {
685 roamer->mpeaceful = roamer->mtame = 0;
686 set_malign(roamer);
688 newsym(roamer->mx, roamer->my);
691 boolean
692 in_your_sanctuary(mon, x, y)
693 struct monst *mon; /* if non-null, <mx,my> overrides <x,y> */
694 xchar x, y;
696 register char roomno;
697 register struct monst *priest;
699 if (mon) {
700 if (is_minion(mon->data) || is_rider(mon->data))
701 return FALSE;
702 x = mon->mx, y = mon->my;
704 if (u.ualign.record <= ALGN_SINNED) /* sinned or worse */
705 return FALSE;
706 if ((roomno = temple_occupied(u.urooms)) == 0
707 || roomno != *in_rooms(x, y, TEMPLE))
708 return FALSE;
709 if ((priest = findpriest(roomno)) == 0)
710 return FALSE;
711 return (boolean) (has_shrine(priest) && p_coaligned(priest)
712 && priest->mpeaceful);
715 /* when attacking "priest" in his temple */
716 void
717 ghod_hitsu(priest)
718 struct monst *priest;
720 int x, y, ax, ay, roomno = (int) temple_occupied(u.urooms);
721 struct mkroom *troom;
723 if (!roomno || !has_shrine(priest))
724 return;
726 ax = x = EPRI(priest)->shrpos.x;
727 ay = y = EPRI(priest)->shrpos.y;
728 troom = &rooms[roomno - ROOMOFFSET];
730 if ((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y, 1)) {
731 if (IS_DOOR(levl[u.ux][u.uy].typ)) {
732 if (u.ux == troom->lx - 1) {
733 x = troom->hx;
734 y = u.uy;
735 } else if (u.ux == troom->hx + 1) {
736 x = troom->lx;
737 y = u.uy;
738 } else if (u.uy == troom->ly - 1) {
739 x = u.ux;
740 y = troom->hy;
741 } else if (u.uy == troom->hy + 1) {
742 x = u.ux;
743 y = troom->ly;
745 } else {
746 switch (rn2(4)) {
747 case 0:
748 x = u.ux;
749 y = troom->ly;
750 break;
751 case 1:
752 x = u.ux;
753 y = troom->hy;
754 break;
755 case 2:
756 x = troom->lx;
757 y = u.uy;
758 break;
759 default:
760 x = troom->hx;
761 y = u.uy;
762 break;
765 if (!linedup(u.ux, u.uy, x, y, 1))
766 return;
769 switch (rn2(3)) {
770 case 0:
771 pline("%s roars in anger: \"Thou shalt suffer!\"",
772 a_gname_at(ax, ay));
773 break;
774 case 1:
775 pline("%s voice booms: \"How darest thou harm my servant!\"",
776 s_suffix(a_gname_at(ax, ay)));
777 break;
778 default:
779 pline("%s roars: \"Thou dost profane my shrine!\"",
780 a_gname_at(ax, ay));
781 break;
784 buzz(-10 - (AD_ELEC - 1), 6, x, y, sgn(tbx),
785 sgn(tby)); /* bolt of lightning */
786 exercise(A_WIS, FALSE);
789 void
790 angry_priest()
792 register struct monst *priest;
793 struct rm *lev;
795 if ((priest = findpriest(temple_occupied(u.urooms))) != 0) {
796 struct epri *eprip = EPRI(priest);
798 wakeup(priest);
800 * If the altar has been destroyed or converted, let the
801 * priest run loose.
802 * (When it's just a conversion and there happens to be
803 * a fresh corpse nearby, the priest ought to have an
804 * opportunity to try converting it back; maybe someday...)
806 lev = &levl[eprip->shrpos.x][eprip->shrpos.y];
807 if (!IS_ALTAR(lev->typ)
808 || ((aligntyp) Amask2align(lev->altarmask & AM_MASK)
809 != eprip->shralign)) {
810 if (!EMIN(priest))
811 newemin(priest);
812 priest->ispriest = 0; /* now a roaming minion */
813 priest->isminion = 1;
814 EMIN(priest)->min_align = eprip->shralign;
815 EMIN(priest)->renegade = FALSE;
816 /* discard priest's memory of his former shrine;
817 if we ever implement the re-conversion mentioned
818 above, this will need to be removed */
819 free_epri(priest);
825 * When saving bones, find priests that aren't on their shrine level,
826 * and remove them. This avoids big problems when restoring bones.
827 * [Perhaps we should convert them into roamers instead?]
829 void
830 clearpriests()
832 struct monst *mtmp;
834 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
835 if (DEADMONSTER(mtmp))
836 continue;
837 if (mtmp->ispriest && !on_level(&(EPRI(mtmp)->shrlevel), &u.uz))
838 mongone(mtmp);
842 /* munge priest-specific structure when restoring -dlc */
843 void
844 restpriest(mtmp, ghostly)
845 register struct monst *mtmp;
846 boolean ghostly;
848 if (u.uz.dlevel) {
849 if (ghostly)
850 assign_level(&(EPRI(mtmp)->shrlevel), &u.uz);
854 /*priest.c*/