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. */
11 /* this matches the categorizations shown by enlightenment */
12 #define ALGN_SINNED (-4) /* worse than strayed */
16 STATIC_DCL boolean FDECL(histemple_at,(struct monst *,XCHAR_P,XCHAR_P));
17 STATIC_DCL boolean FDECL(has_shrine,(struct monst *));
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.
24 move_special(mtmp,in_his_shop,appr,uondoor,avoid,omx,omy,gx,gy)
25 register struct monst *mtmp;
28 boolean uondoor,avoid;
29 register xchar omx,omy,gx,gy;
31 register xchar nx,ny,nix,niy;
37 struct obj *ib = (struct obj *)0;
39 if(omx == gx && omy == gy)
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;
57 if (is_giant(mtmp->data)) allowflags |= BUSTDOOR;
58 cnt = mfndpos(mtmp, poss, info, allowflags);
60 if(mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */
62 if(!(info[i] & NOTONL)) goto pick_move;
66 #define GDIST(x,y) (dist2(x,y,gx,gy))
69 for(i=0; i<cnt; i++) {
72 if(levl[nx][ny].typ == ROOM ||
74 levl[nx][ny].typ == ALTAR) ||
76 (!in_his_shop || ESHK(mtmp)->following))) {
77 if(avoid && (info[i] & NOTONL))
79 if((!appr && !rn2(++chcnt)) ||
80 (appr && GDIST(nx,ny) < GDIST(nix,niy))) {
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
94 if(nix != omx || niy != omy) {
95 remove_monster(omx, omy);
96 place_monster(mtmp, nix, niy);
98 if (mtmp->isshk && !in_his_shop && inhishop(mtmp))
99 check_special_room(FALSE);
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);
117 temple_occupied(array)
118 register char *array;
122 for (ptr = array; *ptr; ptr++)
123 if (rooms[*ptr - ROOMOFFSET].rtype == TEMPLE)
132 histemple_at(priest, x, y)
133 register struct monst *priest;
136 return((boolean)((EPRI(priest)->shroom == *in_rooms(x, y, TEMPLE)) &&
137 on_level(&(EPRI(priest)->shrlevel), &u.uz)));
141 * pri_move: return 1: moved 0: didn't -1: let m_move do it -2: died
145 register struct monst *priest;
147 register xchar gx,gy,omx,omy;
149 boolean avoid = TRUE;
154 if(!histemple_at(priest, omx, omy)) return(-1);
156 temple = EPRI(priest)->shroom;
158 gx = EPRI(priest)->shrpos.x;
159 gy = EPRI(priest)->shrpos.y;
161 gx += rn1(3,-1); /* mill around the altar */
164 if(!priest->mpeaceful ||
165 (Conflict && !resist(priest, RING_CLASS, 0, 0))) {
166 if(monnear(priest, u.ux, u.uy)) {
168 Your("displaced image doesn't fool %s!",
170 (void) mattacku(priest);
172 } else if(index(u.urooms, temple)) {
173 /* chase player if inside temple & can see him */
174 if(priest->mcansee && m_canseeu(priest)) {
180 } else if(Invis) avoid = FALSE;
182 return(move_special(priest,FALSE,TRUE,FALSE,avoid,omx,omy,gx,gy));
185 /* exclusively for mktemple() */
187 priestini(lvl, sroom, sx, sy, sanctum)
189 struct mkroom *sroom;
191 boolean sanctum; /* is it the seat of the high priest? */
193 struct monst *priest;
198 (void) rloc(m_at(sx+1, sy), FALSE); /* insurance */
200 priest = makemon(&mons[sanctum ? PM_HIGH_PRIEST : PM_ALIGNED_PRIEST],
201 sx + 1, sy, NO_MM_FLAGS);
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 */
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);
219 /* 2 to 4 spellbooks */
220 for (cnt = rn1(3,2); cnt > 0; --cnt) {
221 (void) mpickobj(priest, mkobj(SPBOOK_CLASS, FALSE));
223 /* robe [via makemon()] */
224 if (rn2(2) && (otmp = which_armor(priest, W_ARMC)) != 0) {
225 if (p_coaligned(priest))
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
246 priestname(mon, pname)
247 register struct monst *mon;
248 char *pname; /* caller-supplied output buffer */
250 const char *what = Hallucination ? rndmonnam() : mon->data->mname;
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]) {
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]) {
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 ");
270 Strcat(pname, "poohbah ");
271 else if (mon->female)
272 Strcat(pname, "priestess ");
274 Strcat(pname, "priest ");
276 Strcat(pname, "of ");
277 Strcat(pname, halu_gname((int)EPRI(mon)->shralign));
280 /* use emin instead of epri */
282 Strcat(pname, " of ");
283 Strcat(pname, halu_gname(EMIN(mon)->min_align));
289 struct monst *priest;
291 return((boolean)(u.ualign.type == ((int)EPRI(priest)->shralign)));
302 lev = &levl[EPRI(pri)->shrpos.x][EPRI(pri)->shrpos.y];
303 if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE))
305 return((boolean)(EPRI(pri)->shralign == Amask2align(lev->altarmask & ~AM_SHRINE)));
312 register struct monst *mtmp;
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))
320 return (struct monst *)0;
323 /* called from check_special_room() when the player enters the temple room */
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;
334 if(!temple_occupied(u.urooms0)) {
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 &&
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;
348 canseemon(priest) ? Monnam(priest) : "A nearby voice");
349 priest->ispriest = save_priest;
352 if(sanctum && Is_sanctum(&u.uz)) {
353 if(priest->mpeaceful) {
354 msg1 = "Infidel, you have entered Moloch's Sanctum!";
356 priest->mpeaceful = 0;
359 msg1 = "You desecrate this place by your presence!";
361 Sprintf(buf, "Pilgrim, you enter a %s place!",
362 !shrined ? "desecrated" : "sacred");
367 if (msg2) verbalize(msg2);
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.");
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;
387 if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy,NO_MM_FLAGS)))
389 if (!Blind || sensemon(mtmp))
390 pline("An enormous ghost appears next to you!");
391 else You("sense a presence close by!");
395 You("are frightened to death, and unable to move.");
397 nomovemsg = "You regain your composure.";
405 register struct monst *priest;
407 boolean coaligned = p_coaligned(priest);
408 boolean strayed = (u.ualign.record < 0);
411 u.uconduct.gnostic++;
413 if(priest->mflee || (!priest->ispriest && coaligned && strayed)) {
414 pline("%s doesn't want anything to do with you!",
416 priest->mpeaceful = 0;
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."
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;
435 priest->mpeaceful = 0;
436 verbalize(cranky_msg[rn2(3)]);
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;
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)
458 priest->mgold -= u.ugold;
461 if(!money_cnt(invent)) {
462 if(coaligned && !strayed) {
463 long pmoney = money_cnt(priest->minvent);
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);
471 pline("%s preaches the virtues of poverty.", Monnam(priest));
472 exercise(A_WIS, TRUE);
474 pline("%s is not interested.", Monnam(priest));
479 pline("%s asks you for a contribution for the temple.",
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)) {
486 if(u.ugold > (offer * 2L)) verbalize("Cheapskate.");
488 if(money_cnt(invent) > (offer * 2L)) verbalize("Cheapskate.");
491 verbalize("I thank thee for thy contribution.");
492 /* give player some token */
493 exercise(A_WIS, TRUE);
495 } else if(offer < (u.ulevel * 400)) {
496 verbalize("Thou art indeed a pious individual.");
498 if(u.ugold < (offer * 2L)) {
500 if(money_cnt(invent) < (offer * 2L)) {
502 if (coaligned && u.ualign.record <= ALGN_SINNED)
504 verbalize("I bestow upon thee a blessing.");
505 incr_itimeout(&HClairvoyant, rn1(500,500));
507 } else if(offer < (u.ulevel * 600) &&
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);
516 verbalize("Thy selfless generosity is deeply appreciated.");
518 if(u.ugold < (offer * 2L) && coaligned) {
520 if(money_cnt(invent) < (offer * 2L) && coaligned) {
522 if(strayed && (moves - u.ucleansed) > 5000L) {
523 u.ualign.record = 0; /* cleanse thee */
534 mk_roamer(ptr, alignment, x, y, peaceful)
535 register struct permonst *ptr;
540 register struct monst *roamer;
541 register boolean coaligned = (u.ualign.type == alignment);
543 if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL])
544 return((struct monst *)0);
546 if (MON_AT(x, y)) (void) rloc(m_at(x, y), FALSE); /* insurance */
548 if (!(roamer = makemon(ptr, x, y, NO_MM_FLAGS)))
549 return((struct monst *)0);
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 */
566 reset_hostility(roamer)
567 register struct monst *roamer;
569 if(!(roamer->isminion && (roamer->data == &mons[PM_ALIGNED_PRIEST] ||
570 roamer->data == &mons[PM_ANGEL])))
573 if(EPRI(roamer)->shralign != u.ualign.type) {
574 roamer->mpeaceful = roamer->mtame = 0;
577 newsym(roamer->mx, roamer->my);
581 in_your_sanctuary(mon, x, y)
582 struct monst *mon; /* if non-null, <mx,my> overrides <x,y> */
585 register char roomno;
586 register struct monst *priest;
589 if (is_minion(mon->data) || is_rider(mon->data)) return FALSE;
590 x = mon->mx, y = mon->my;
592 if (u.ualign.record <= ALGN_SINNED) /* sinned or worse */
594 if ((roomno = temple_occupied(u.urooms)) == 0 ||
595 roomno != *in_rooms(x, y, TEMPLE))
597 if ((priest = findpriest(roomno)) == 0)
599 return (boolean)(has_shrine(priest) &&
600 p_coaligned(priest) &&
605 ghod_hitsu(priest) /* when attacking "priest" in his temple */
606 struct monst *priest;
608 int x, y, ax, ay, roomno = (int)temple_occupied(u.urooms);
609 struct mkroom *troom;
611 if (!roomno || !has_shrine(priest))
614 ax = x = EPRI(priest)->shrpos.x;
615 ay = y = EPRI(priest)->shrpos.y;
616 troom = &rooms[roomno - ROOMOFFSET];
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)) {
621 if(u.ux == troom->lx - 1) {
624 } else if(u.ux == troom->hx + 1) {
627 } else if(u.uy == troom->ly - 1) {
630 } else if(u.uy == troom->hy + 1) {
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;
642 if(!linedup(u.ux, u.uy, x, y)) return;
647 pline("%s roars in anger: \"Thou shalt suffer!\"",
651 pline("%s voice booms: \"How darest thou harm my servant!\"",
652 s_suffix(a_gname_at(ax, ay)));
655 pline("%s roars: \"Thou dost profane my shrine!\"",
660 buzz(-10-(AD_ELEC-1), 6, x, y, sgn(tbx), sgn(tby)); /* bolt of lightning */
661 exercise(A_WIS, FALSE);
667 register struct monst *priest;
670 if ((priest = findpriest(temple_occupied(u.urooms))) != 0) {
673 * If the altar has been destroyed or converted, let the
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...)
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;
692 * When saving bones, find priests that aren't on their shrine level,
693 * and remove them. This avoids big problems when restoring bones.
698 register struct monst *mtmp, *mtmp2;
700 for(mtmp = fmon; mtmp; mtmp = mtmp2) {
702 if (!DEADMONSTER(mtmp) && mtmp->ispriest && !on_level(&(EPRI(mtmp)->shrlevel), &u.uz))
707 /* munge priest-specific structure when restoring -dlc */
709 restpriest(mtmp, ghostly)
710 register struct monst *mtmp;
715 assign_level(&(EPRI(mtmp)->shrlevel), &u.uz);