Blindfold removal fix
[slashemextended.git] / src / priest.c
blobb16854a4023b44387c33e60d1d693ea1c3639f7d
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. */
5 #include "hack.h"
6 #include "mfndpos.h"
7 #include "eshk.h"
8 #include "epri.h"
9 #include "emin.h"
11 /* this matches the categorizations shown by enlightenment */
12 #define ALGN_SINNED (-4) /* worse than strayed */
14 #ifdef OVLB
16 STATIC_DCL boolean histemple_at(struct monst *,XCHAR_P,XCHAR_P);
17 STATIC_DCL boolean 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.
23 int
24 move_special(mtmp,in_his_shop,appr,uondoor,avoid,omx,omy,gx,gy)
25 register struct monst *mtmp;
26 boolean in_his_shop;
27 schar appr;
28 boolean uondoor,avoid;
29 register xchar omx,omy,gx,gy;
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;
39 if(omx == gx && omy == gy)
40 return(0);
41 if(mtmp->mconf) {
42 avoid = FALSE;
43 appr = 0;
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) || (mtmp->egotype_wallwalk) ) 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 if (m_carrying(mtmp, CONTROVERSY_CODE)) allowflags |= BUSTDOOR;
57 if (m_carrying(mtmp, SECRET_KEY)) allowflags |= BUSTDOOR;
59 if (is_giant(mtmp->data)) allowflags |= BUSTDOOR;
60 cnt = mfndpos(mtmp, poss, info, allowflags);
62 if(mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */
63 for(i=0; i<cnt; i++)
64 if(!(info[i] & NOTONL)) goto pick_move;
65 avoid = FALSE;
68 #define GDIST(x,y) (dist2(x,y,gx,gy))
69 pick_move:
70 chcnt = 0;
71 for(i=0; i<cnt; i++) {
72 nx = poss[i].x;
73 ny = poss[i].y;
74 if(levl[nx][ny].typ == ROOM || (ACCESSIBLE(levl[nx][ny].typ) && levl[nx][ny].typ != DOOR) ||
75 (levl[nx][ny].typ >= POOL && levl[nx][ny].typ <= STYXRIVER && is_flyer(mtmp->data)) ||
76 (mtmp->ispriest &&
77 levl[nx][ny].typ == ALTAR) ||
78 (mtmp->isshk &&
79 (!in_his_shop || ESHK(mtmp)->following))) {
80 if(avoid && (info[i] & NOTONL))
81 continue;
82 if((!appr && !rn2(++chcnt)) ||
83 (appr && GDIST(nx,ny) < GDIST(nix,niy))) {
84 nix = nx;
85 niy = ny;
89 if(mtmp->ispriest && avoid &&
90 nix == omx && niy == omy && onlineu(omx,omy)) {
91 /* might as well move closer as long it's going to stay
92 * lined up */
93 avoid = FALSE;
94 goto pick_move;
97 if(nix != omx || niy != omy) {
98 remove_monster(omx, omy);
99 place_monster(mtmp, nix, niy);
100 newsym(nix,niy);
101 if (mtmp->isshk && !in_his_shop && inhishop(mtmp))
102 check_special_room(FALSE);
103 if(ib) {
104 if (cansee(mtmp->mx,mtmp->my))
105 pline("%s picks up %s.", Monnam(mtmp),
106 distant_name(ib,doname));
107 obj_extract_self(ib);
108 (void) mpickobj(mtmp, ib, FALSE);
110 return(1);
112 return(0);
115 #endif /* OVLB */
117 #ifdef OVL0
119 char
120 temple_occupied(array)
121 register char *array;
123 register char *ptr;
125 for (ptr = array; *ptr; ptr++)
126 if (rooms[*ptr - ROOMOFFSET].rtype == TEMPLE)
127 return(*ptr);
128 return('\0');
131 #endif /* OVL0 */
132 #ifdef OVLB
134 STATIC_OVL boolean
135 histemple_at(priest, x, y)
136 register struct monst *priest;
137 register xchar x, y;
139 return((boolean)((EPRI(priest)->shroom == *in_rooms(x, y, TEMPLE)) &&
140 on_level(&(EPRI(priest)->shrlevel), &u.uz)));
144 * pri_move: return 1: moved 0: didn't -1: let m_move do it -2: died
147 pri_move(priest)
148 register struct monst *priest;
150 register xchar gx,gy,omx,omy;
151 schar temple;
152 boolean avoid = TRUE;
154 omx = priest->mx;
155 omy = priest->my;
157 if(!histemple_at(priest, omx, omy)) return(-1);
159 temple = EPRI(priest)->shroom;
161 gx = EPRI(priest)->shrpos.x;
162 gy = EPRI(priest)->shrpos.y;
164 gx += rn1(3,-1); /* mill around the altar */
165 gy += rn1(3,-1);
167 if (evilfriday && monnear(priest, u.ux, u.uy) && (uwep && (uwep->otyp == CIGARETTE || uwep->otyp == ELECTRIC_CIGARETTE || uwep->otyp == CIGAR)) && priest->mpeaceful) {
168 priest->mpeaceful = 0;
169 verbalize("Begone! Thou desecratest this holy place with thy presence.");
172 if(!priest->mpeaceful ||
173 (Conflict && !resist(priest, RING_CLASS, 0, 0)) ||
174 (StrongConflict && !resist(priest, RING_CLASS, 0, 0))) {
175 if(monnear(priest, u.ux, u.uy)) {
176 if(Displaced)
177 Your("displaced image doesn't fool %s!",
178 mon_nam(priest));
179 (void) mattacku(priest);
180 return(0);
181 } else if(index(u.urooms, temple)) {
182 /* chase player if inside temple & can see him */
183 if(priest->mcansee && m_canseeu(priest)) {
184 gx = u.ux;
185 gy = u.uy;
187 avoid = FALSE;
189 } else if(Invis) avoid = FALSE;
191 return(move_special(priest,FALSE,TRUE,FALSE,avoid,omx,omy,gx,gy));
194 /* exclusively for mktemple() */
195 void
196 priestini(lvl, sroom, sx, sy, sanctum)
197 d_level *lvl;
198 struct mkroom *sroom;
199 int sx, sy;
200 boolean sanctum; /* is it the seat of the high priest? */
202 struct monst *priest;
203 struct obj *otmp = NULL;
204 int cnt;
206 if(MON_AT(sx+1, sy))
207 (void) rloc(m_at(sx+1, sy), FALSE); /* insurance */
209 priest = makemon(&mons[(In_yendorian(&u.uz) && depth(&u.uz) == 1) ? PM_DNETHACK_ELDER_PRIEST_TM_ : isevilvariant ? PM_DNETHACK_ELDER_PRIEST_TM_ : sanctum ? PM_HIGH_PRIEST : ((level_difficulty() + u.pompejipermanentrecord) > 79 && Amask2align(levl[sx][sy].altarmask) != A_NONE) ? PM_ELITE_PRIEST : ((level_difficulty() + u.pompejipermanentrecord) > 59 && Amask2align(levl[sx][sy].altarmask) != A_NONE) ? PM_EXCEPTIONAL_PRIEST : ((level_difficulty() + u.pompejipermanentrecord) > 39 && Amask2align(levl[sx][sy].altarmask) != A_NONE) ? PM_MASTER_PRIEST : ((level_difficulty() + u.pompejipermanentrecord) > 19 && Amask2align(levl[sx][sy].altarmask) != A_NONE) ? PM_EXPERIENCED_PRIEST : PM_ALIGNED_PRIEST],
210 sx + 1, sy, NO_MM_FLAGS);
212 if (priest) {
213 EPRI(priest)->shroom = (sroom - rooms) + ROOMOFFSET;
214 EPRI(priest)->shralign = Amask2align(levl[sx][sy].altarmask);
215 EPRI(priest)->shrpos.x = sx;
216 EPRI(priest)->shrpos.y = sy;
217 assign_level(&(EPRI(priest)->shrlevel), lvl);
218 /*priest->mtrapseen = ~0;*/ /* traps are known */
219 priest->mpeaceful = 1;
220 priest->ispriest = 1;
221 priest->msleeping = 0;
222 set_malign(priest); /* mpeaceful may have changed */
224 /* now his/her goodies... */
225 if(sanctum && EPRI(priest)->shralign == A_NONE &&
226 on_level(&sanctum_level, &u.uz)) {
227 (void) mongets(priest, AMULET_OF_YENDOR);
229 /* 2 to 4 spellbooks - but less later on
230 * Amy edit: 50% chance of having just one, har-har :P
231 * they're just free loot anyway, the priest doesn't benefit from having them! */
232 cnt = (rn2(2) ? 1 : rn1(3,2));
233 while (cnt > 0) {
234 cnt--;
235 if (timebasedlowerchance()) (void) mpickobj(priest, mkobj(SPBOOK_CLASS, FALSE, FALSE), TRUE);
237 /* [ALI] Upgrade existing robe or aquire new */
239 if (In_yendorian(&u.uz) && depth(&u.uz) == 1) {
240 struct obj *obj;
241 obj = mksobj(ROBE, TRUE, FALSE, FALSE);
242 if (obj) {
243 obj = oname(obj, artiname(ART_MOTHERFUCKER_TROPHY));
244 if (obj) {
245 curse(obj);
246 (void) mpickobj(priest, obj, TRUE);
248 m_dowear(priest, TRUE);
251 } else if (rn2(2) || (otmp = which_armor(priest, W_ARM)) == 0) {
252 struct obj *obj;
253 obj = mksobj(rn2(p_coaligned(priest) ? 2 : 5) ?
254 ROBE_OF_PROTECTION : ROBE_OF_POWER, TRUE, FALSE, FALSE);
255 if (obj) { /* this should fix a STUPID segfault for minimalist characters --Amy */
256 if (p_coaligned(priest))
257 uncurse(obj, TRUE);
258 else
259 curse(obj);
260 if (obj) {
261 (void) mpickobj(priest, obj, TRUE);
263 m_dowear(priest, TRUE);
264 /* somehow the bug was still happening... this gold piece check seems to really fix it --Amy */
265 if (obj && !(obj->otyp == GOLD_PIECE) && !(obj->owornmask & W_ARM)) {
266 obj_extract_self(obj);
267 obfree(obj, (struct obj *)0);
268 } else if (otmp && !(otmp->otyp == GOLD_PIECE)) {
269 obj_extract_self(otmp);
270 obfree(otmp, (struct obj *)0);
278 * Specially aligned monsters are named specially.
279 * - aligned priests with ispriest and high priests have shrines
280 * they retain ispriest and epri when polymorphed
281 * - aligned priests without ispriest and Angels are roamers
282 * they retain isminion and access epri as emin when polymorphed
283 * (coaligned Angels are also created as minions, but they
284 * use the same naming convention)
285 * - minions do not have ispriest but have isminion and emin
286 * - caller needs to inhibit Hallucination if it wants to force
287 * the true name even when under that influence
289 char *
290 priestname(mon, pname)
291 register struct monst *mon;
292 char *pname; /* caller-supplied output buffer */
294 const char *what = Hallucination ? rndmonnam() : (u.usanity > 900 && (u.usanity > rn2(10000)) && rn2(10) ) ? rndmonnam() : mon->data->mname;
296 strcpy(pname, "the ");
297 if (mon->minvis) strcat(pname, "invisible ");
298 if (mon->ispriest || mon->data == &mons[PM_ALIGNED_PRIEST] || mon->data == &mons[PM_MASTER_PRIEST] || mon->data == &mons[PM_EXPERIENCED_PRIEST] || mon->data == &mons[PM_EXCEPTIONAL_PRIEST] || mon->data == &mons[PM_ELITE_PRIEST] ||
299 mon->data == &mons[PM_ANGEL]) {
300 /* use epri */
301 if (mon->mtame && mon->data == &mons[PM_ANGEL])
302 strcat(pname, "guardian ");
303 if (mon->data != &mons[PM_ALIGNED_PRIEST] && mon->data != &mons[PM_EXPERIENCED_PRIEST] && mon->data != &mons[PM_MASTER_PRIEST] && mon->data != &mons[PM_EXCEPTIONAL_PRIEST] && mon->data != &mons[PM_ELITE_PRIEST] && mon->data != &mons[PM_DNETHACK_ELDER_PRIEST_TM_] &&
304 mon->data != &mons[PM_HIGH_PRIEST]) {
305 strcat(pname, what);
306 strcat(pname, " ");
308 if (mon->data != &mons[PM_ANGEL]) {
309 if (!mon->ispriest && EPRI(mon)->renegade)
310 strcat(pname, "renegade ");
311 if (mon->data == &mons[PM_HIGH_PRIEST])
312 strcat(pname, "high ");
313 if (mon->data == &mons[PM_DNETHACK_ELDER_PRIEST_TM_])
314 strcat(pname, "elder ");
315 if (FunnyHallu)
316 strcat(pname, "poohbah ");
317 else if (mon->female)
318 strcat(pname, "priestess ");
319 else
320 strcat(pname, "priest ");
322 strcat(pname, "of ");
323 strcat(pname, halu_gname((int)EPRI(mon)->shralign));
324 return(pname);
326 /* use emin instead of epri */
327 strcat(pname, what);
328 strcat(pname, " of ");
329 strcat(pname, halu_gname(EMIN(mon)->min_align));
330 return(pname);
333 boolean
334 p_coaligned(priest)
335 struct monst *priest;
337 return((boolean)(u.ualign.type == ((int)EPRI(priest)->shralign)));
340 STATIC_OVL boolean
341 has_shrine(pri)
342 struct monst *pri;
344 struct rm *lev;
346 if(!pri)
347 return(FALSE);
348 lev = &levl[EPRI(pri)->shrpos.x][EPRI(pri)->shrpos.y];
349 if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE))
350 return(FALSE);
351 return((boolean)(EPRI(pri)->shralign == Amask2align(lev->altarmask & ~AM_SHRINE)));
354 struct monst *
355 findpriest(roomno)
356 char roomno;
358 register struct monst *mtmp;
360 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
361 if (DEADMONSTER(mtmp)) continue;
362 if(mtmp->ispriest && (EPRI(mtmp)->shroom == roomno) &&
363 histemple_at(mtmp,mtmp->mx,mtmp->my))
364 return(mtmp);
366 return (struct monst *)0;
369 /* called from check_special_room() when the player enters the temple room */
370 void
371 intemple(roomno)
372 register int roomno;
374 register struct monst *priest = findpriest((char)roomno);
375 boolean tended = (priest != (struct monst *)0);
376 boolean shrined, sanctum, can_speak;
377 const char *msg1, *msg2;
378 char buf[BUFSZ];
380 if(!temple_occupied(u.urooms0)) {
381 if(tended) {
382 shrined = has_shrine(priest);
383 sanctum = ( (priest->data == &mons[PM_HIGH_PRIEST] || priest->data == &mons[PM_DNETHACK_ELDER_PRIEST_TM_]) &&
384 (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
385 can_speak = (priest->mcanmove && !priest->msleeping &&
386 flags.soundok);
387 if (can_speak) {
388 unsigned save_priest = priest->ispriest;
389 /* don't reveal the altar's owner upon temple entry in
390 the endgame; for the Sanctum, the next message names
391 Moloch so suppress the "of Moloch" for him here too */
392 if (sanctum && !Hallucination) priest->ispriest = 0;
393 pline("%s intones:",
394 canseemon(priest) ? Monnam(priest) : "A nearby voice");
395 priest->ispriest = save_priest;
397 msg2 = 0;
398 if(sanctum && Is_sanctum(&u.uz)) {
399 if(priest->mpeaceful) { /* never the case in this game --Amy */
400 msg1 = "Infidel, you have entered Moloch's Sanctum!";
401 if (Role_if(PM_GANG_SCHOLAR)) msg1 = "Infidel, you have entered Anna's Sanctum!";
402 if (Role_if(PM_WALSCHOLAR)) msg1 = "Infidel, you have entered Anna's Sanctum!";
403 msg2 = "Be gone!";
404 priest->mpeaceful = 0;
405 set_malign(priest);
406 } else {
407 if (rn2(2)) msg1 = "You desecrate this place by your presence!";
408 else {
409 msg1 = "Infidel, you have entered Moloch's Sanctum!";
410 if (Role_if(PM_GANG_SCHOLAR)) msg1 = "Infidel, you have entered Anna's Sanctum!";
411 if (Role_if(PM_WALSCHOLAR)) msg1 = "Infidel, you have entered Anna's Sanctum!";
412 msg2 = "Be gone!";
416 } else {
417 sprintf(buf, "Pilgrim, you enter a %s place!",
418 !shrined ? "desecrated" : "sacred");
419 msg1 = buf;
421 if (can_speak) {
422 verbalize("%s", msg1);
423 if (msg2) verbalize("%s", msg2);
425 if(!sanctum) {
426 /* !tended -> !shrined */
427 if (!shrined || !p_coaligned(priest) ||
428 u.ualign.record <= ALGN_SINNED)
429 You("have a%s forbidding feeling...",
430 (!shrined) ? "" : " strange");
431 else You("experience a strange sense of peace.");
434 if (can_speak && evilfriday) verbalize("Please be aware that smoking is strictly prohibited in this temple.");
435 } else {
436 switch(rn2(3)) {
437 case 0: You("have an eerie feeling..."); break;
438 case 1: You_feel("like you are being watched."); break;
439 default: pline("A shiver runs down your %s.",
440 body_part(SPINE)); break;
442 if(!rn2(5)) {
443 struct monst *mtmp;
445 if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy,NO_MM_FLAGS)))
446 return;
447 if (!Blind || sensemon(mtmp))
448 pline("An enormous ghost appears next to you!");
449 else You("sense a presence close by!");
450 mtmp->mpeaceful = 0;
451 set_malign(mtmp);
452 if(flags.verbose)
453 You("are frightened to death, and unable to move.");
454 nomul(-3, "frightened to death", TRUE);
455 make_feared(HFeared + rnd(30 + (monster_difficulty() * 3) ),TRUE);
456 nomovemsg = "You regain your composure.";
462 void
463 priest_talk(priest)
464 register struct monst *priest;
466 boolean coaligned = p_coaligned(priest);
467 boolean strayed = (u.ualign.record < 0);
469 if (Race_if(PM_MACTHEIST)) {
470 pline("Did you forget by any chance that you're an atheist? You cannot talk to priests!");
471 return;
474 /* KMH, conduct */
475 u.uconduct.gnostic++;
476 if (Race_if(PM_MAGYAR)) {
477 You_feel("bad about breaking the atheist conduct.");
478 badeffect();
481 if(priest->mflee || (!priest->ispriest && coaligned && strayed)) {
482 pline("%s doesn't want anything to do with you!",
483 Monnam(priest));
484 priest->mpeaceful = 0;
485 return;
488 /* priests don't chat unless peaceful and in their own temple */
489 if(!histemple_at(priest,priest->mx,priest->my) ||
490 !priest->mpeaceful || !priest->mcanmove || priest->msleeping) {
491 static const char *cranky_msg[3] = {
492 "Thou wouldst have words, eh? I'll give thee a word or two!",
493 "Talk? Here is what I have to say!",
494 "Pilgrim, I would speak no longer with thee."
497 if(!priest->mcanmove || priest->msleeping) {
498 pline("%s breaks out of %s reverie!",
499 Monnam(priest), mhis(priest));
500 priest->mfrozen = priest->msleeping = 0;
501 priest->masleep = 0;
502 priest->mcanmove = 1;
504 priest->mpeaceful = 0;
505 verbalize("%s", cranky_msg[rn2(3)]);
506 return;
509 /* you desecrated the temple and now you want to chat? */
510 if(priest->mpeaceful && *in_rooms(priest->mx, priest->my, TEMPLE) &&
511 !has_shrine(priest)) {
512 verbalize("Begone! Thou desecratest this holy place with thy presence.");
513 priest->mpeaceful = 0;
514 return;
516 #ifndef GOLDOBJ
517 if(!u.ugold) {
518 if(coaligned && !strayed) {
519 if (priest->mgold > 0L) {
520 /* Note: two bits is actually 25 cents. Hmm. */
521 pline("%s gives you %s for an ale.", Monnam(priest),
522 FunnyHallu ? ((priest->mgold == 1L) ? "one bitcoin" : "two bitcoins") :
523 (priest->mgold == 1L) ? "one bit" : "two bits");
524 if (priest->mgold > 1L)
525 u.ugold = 2L;
526 else
527 u.ugold = 1L;
528 priest->mgold -= u.ugold;
529 flags.botl = 1;
530 #else
531 if(!money_cnt(invent)) {
532 if(coaligned && !strayed) {
533 long pmoney = money_cnt(priest->minvent);
534 if (pmoney > 0L) {
535 /* Note: two bits is actually 25 cents. Hmm. */
536 pline("%s gives you %s for an ale.", Monnam(priest),
537 (pmoney == 1L) ? "one bit" : "two bits");
538 money2u(priest, pmoney > 1L ? 2 : 1);
539 #endif
540 } else
541 pline("%s preaches the virtues of poverty.", Monnam(priest));
542 exercise(A_WIS, TRUE);
543 } else
544 pline("%s is not interested.", Monnam(priest));
545 return;
546 } else {
547 long offer;
549 /* "Revert temple/priest prices to vanilla values." In Soviet Russia, the protection racket is a legal thing to do, just like ransom extortion, russian roulette and jaywalking. And so, tons of promising level 1 characters will die trying to get to the Minetown priest again. All the other races got enough of that bullshit mechanism and will enjoy fixed prices instead, which makes much more sense and gives players an incentive to actually level up. --Amy */
551 pline("%s asks you for a contribution for the temple.",
552 Monnam(priest));
553 if((offer = bribe(priest)) == 0) {
554 verbalize("Thou shalt regret thine action!");
555 if(coaligned) adjalign(-1);
556 } else if(offer < (issoviet ? (u.ulevel * 200) : 2000) ) {
557 #ifndef GOLDOBJ
558 if(u.ugold > (offer * 2L)) verbalize(issoviet ? "lol u sposobstvovali slishkom malo govorit sovetskiy mat' iz ada." : "Cheapskate.");
559 #else
560 if(money_cnt(invent) > (offer * 2L)) verbalize(issoviet ? "lol u sposobstvovali slishkom malo govorit sovetskiy mat' iz ada." : "Cheapskate.");
561 #endif
562 else {
563 verbalize("I thank thee for thy contribution.");
564 /* give player some token */
565 exercise(A_WIS, TRUE);
567 } else if(offer < (issoviet ? (u.ulevel * 400) : 4000) ) {
568 verbalize("Thou art indeed a pious individual.");
569 #ifndef GOLDOBJ
570 if(u.ugold < (offer * 2L)) {
571 #else
572 if(money_cnt(invent) < (offer * 2L)) {
573 #endif
574 if (coaligned && u.ualign.record <= ALGN_SINNED)
575 adjalign(1);
576 verbalize("I bestow upon thee a blessing.");
577 /* KMH, intrinsic patch */
578 incr_itimeout(&HClairvoyant, rn1(500,500));
580 /* Amy edit: it's way too easy to get lots of protection. Fixing that. */
581 } else if(offer < (issoviet ? (u.ulevel * 600) : 6000) &&
582 u.ublessed < 20 &&
583 (u.ublessed < 1 || !rn2(u.ublessed))) {
584 verbalize("Thy devotion has been rewarded.");
585 if (Role_if(PM_PRIEST) || Role_if(PM_NECROMANCER) || Role_if(PM_CHEVALIER) || Race_if(PM_VEELA)) {
586 use_skill(P_SPIRITUALITY, Role_if(PM_PRIEST) ? 3 : 1);
588 if (!(HProtection & INTRINSIC)) {
589 HProtection |= FROMOUTSIDE;
590 if (!u.ublessed) u.ublessed = rno(Race_if(PM_MAYMES) ? 8 : 4);
591 } else {
592 u.ublessed++;
593 if (Race_if(PM_MAYMES) && u.ublessed < 20) u.ublessed++;
596 register struct obj *otmp;
597 otmp = mksobj_at(POT_WATER, u.ux, u.uy, FALSE, FALSE, FALSE);
598 if (otmp) {
599 bless(otmp);
600 verbalize("Thou shall have some sacred water.");
603 } else if(offer < (issoviet ? (u.ulevel * 2000) : 20000) ) {
604 verbalize("Thy selfless generosity is deeply appreciated.");
605 if (Role_if(PM_PRIEST) || Role_if(PM_NECROMANCER) || Role_if(PM_CHEVALIER) || Race_if(PM_VEELA)) {
606 use_skill(P_SPIRITUALITY, Role_if(PM_PRIEST) ? 3 : 1);
608 u.alignlim++; /* give some boost even if it doesn't cleanse you --Amy */
609 adjalign(10);
611 #ifndef GOLDOBJ
612 if(u.ugold < (offer * 2L) && coaligned) {
613 #else
614 if(money_cnt(invent) < (offer * 2L) && coaligned) {
615 #endif
616 /* don't immediately lose all negative alignment --Amy */
617 if(strayed && (moves - u.ucleansed) > 5000L) {
618 u.ualign.record /= 2; /* cleanse thee */
619 adjalign(2);
620 u.ucleansed = moves;
621 verbalize("Thou hast been cleansed.");
622 } else {
623 adjalign(2);
627 register struct obj *otmp;
628 otmp = mksobj_at(POT_WATER, u.ux, u.uy, FALSE, FALSE, FALSE);
629 if (!rn2(2) && offer >= (issoviet ? (u.ulevel * 600) : 6000)) {
630 otmp->quan++;
631 otmp->owt = weight(otmp);
632 verbalize("To the thirsty I will give water without cost from the spring of the water of life.");
633 } else verbalize("Thou shall have some sacred water.");
634 if (otmp) {
635 bless(otmp);
638 } else {
640 verbalize("Thy are indeed most pious.");
642 if (Role_if(PM_PRIEST) || Role_if(PM_NECROMANCER) || Role_if(PM_CHEVALIER) || Race_if(PM_VEELA)) {
643 use_skill(P_SPIRITUALITY, Role_if(PM_PRIEST) ? 15 : 5);
646 u.alignlim += 5;
647 adjalign(50);
649 #ifndef GOLDOBJ
650 if(u.ugold < (offer * 2L) && coaligned) {
651 #else
652 if(money_cnt(invent) < (offer * 2L) && coaligned) {
653 #endif
654 /* don't immediately lose all negative alignment --Amy */
655 if(strayed && (moves - u.ucleansed) > 5000L) {
656 u.ualign.record /= 2; /* cleanse thee */
657 adjalign(2);
658 u.ucleansed = moves;
659 verbalize("Thou hast been cleansed.");
660 } else {
661 adjalign(2);
665 if (u.ualign.sins > 0) {
666 u.ualign.sins--;
667 verbalize("I shall absolve thee of thine most recent sin.");
670 register struct obj *otmp;
671 otmp = mksobj_at(POT_WATER, u.ux, u.uy, FALSE, FALSE, FALSE);
672 otmp->quan = 5;
673 otmp->owt = weight(otmp);
674 verbalize("Thou shall have a large supply of sacred water.");
675 if (otmp) {
676 bless(otmp);
684 struct monst *
685 mk_roamer(ptr, alignment, x, y, peaceful)
686 register struct permonst *ptr;
687 aligntyp alignment;
688 xchar x, y;
689 boolean peaceful;
691 register struct monst *roamer;
692 register boolean coaligned = (u.ualign.type == alignment);
694 if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_MASTER_PRIEST] && ptr != &mons[PM_EXPERIENCED_PRIEST] && ptr != &mons[PM_EXCEPTIONAL_PRIEST] && ptr != &mons[PM_ELITE_PRIEST] && ptr != &mons[PM_ANGEL])
695 return((struct monst *)0);
697 if (MON_AT(x, y)) (void) rloc(m_at(x, y), FALSE); /* insurance */
699 if (!(roamer = makemon(ptr, x, y, NO_MM_FLAGS)))
700 return((struct monst *)0);
702 EPRI(roamer)->shralign = alignment;
703 if (coaligned && !peaceful)
704 EPRI(roamer)->renegade = TRUE;
705 /* roamer->ispriest == FALSE naturally */
706 roamer->isminion = TRUE; /* borrowing this bit */
707 /*roamer->mtrapseen = ~0;*/ /* traps are known */
708 roamer->mpeaceful = peaceful;
709 roamer->msleeping = 0;
710 set_malign(roamer); /* peaceful may have changed */
712 /* MORE TO COME */
713 return(roamer);
716 void
717 reset_hostility(roamer)
718 register struct monst *roamer;
720 if(!(roamer->isminion && (roamer->data == &mons[PM_ALIGNED_PRIEST] || roamer->data == &mons[PM_MASTER_PRIEST] || roamer->data == &mons[PM_EXPERIENCED_PRIEST] || roamer->data == &mons[PM_EXCEPTIONAL_PRIEST] || roamer->data == &mons[PM_ELITE_PRIEST] ||
721 roamer->data == &mons[PM_ANGEL])))
722 return;
724 if(EPRI(roamer)->shralign != u.ualign.type) {
725 roamer->mpeaceful = roamer->mtame = 0;
726 set_malign(roamer);
728 newsym(roamer->mx, roamer->my);
731 boolean
732 in_your_sanctuary(mon, x, y)
733 struct monst *mon; /* if non-null, <mx,my> overrides <x,y> */
734 xchar x, y;
736 register char roomno;
737 register struct monst *priest;
739 if (mon) {
740 if (is_minion(mon->data) || is_rider(mon->data) || is_deadlysin(mon->data)) return FALSE;
741 x = mon->mx, y = mon->my;
743 if (u.ualign.record <= ALGN_SINNED) /* sinned or worse */
744 return FALSE;
745 if ((roomno = temple_occupied(u.urooms)) == 0 ||
746 roomno != *in_rooms(x, y, TEMPLE))
747 return FALSE;
748 if ((priest = findpriest(roomno)) == 0)
749 return FALSE;
750 return (boolean)(has_shrine(priest) &&
751 p_coaligned(priest) &&
752 priest->mpeaceful);
755 void
756 ghod_hitsu(priest) /* when attacking "priest" in his temple */
757 struct monst *priest;
759 int x, y, ax, ay, roomno = (int)temple_occupied(u.urooms);
760 int x1, y1, x2, y2, n;
761 coord poss[4];
762 int stpx = sgn(u.ux - priest->mx), stpy = sgn(u.uy - priest->my);
763 /* gods avoid hitting the temple priest */
764 struct mkroom *troom;
766 if (!roomno || !has_shrine(priest))
767 return;
769 ax = x = EPRI(priest)->shrpos.x;
770 ay = y = EPRI(priest)->shrpos.y;
771 troom = &rooms[roomno - ROOMOFFSET];
774 * Determine the source of the lightning bolt according to the
775 * following rules:
776 * 1. The source cannot be directly under the player
777 * 2. Don't zap through the temple priest
778 * 3. First choice of source is the altar itself
779 * 4. Otherwise use a wall, prefering orthogonal to diagonal paths
780 * 5. Choose randomly from equally preferred sources
781 * Note that if the hero is not standing on either the altar or
782 * a door then (u.ux, u.uy) may be counted as a possible source which
783 * is later rejected by linedup() letting the hero off the hook.
785 if((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y, FALSE) ||
786 stpx == sgn(tbx) && stpy == sgn(tby)) {
787 if(IS_DOOR(levl[u.ux][u.uy].typ)) {
789 if(u.ux == troom->lx - 1) {
790 if (stpx != sgn(u.ux - troom->hx) || stpy != 0) {
791 x = troom->hx;
792 y = u.uy;
793 } else {
794 /* Diagonal required */
795 x1 = u.ux + u.uy - troom->ly;
796 y1 = troom->ly;
797 x2 = u.ux + troom->hy - u.uy;
798 y2 = troom->hy;
799 if (x1 > troom->hx && x2 > troom->hx)
800 return;
801 else if (x2 > troom->hx || x1 <= troom->hx && !rn2(2)) {
802 x = x1;
803 y = y1;
804 } else {
805 x = x2;
806 y = y2;
809 } else if(u.ux == troom->hx + 1) {
810 if (stpx != sgn(u.ux - troom->lx) || stpy != 0) {
811 x = troom->lx;
812 y = u.uy;
813 } else {
814 /* Diagonal required */
815 x1 = u.ux - (u.uy - troom->ly);
816 y1 = troom->ly;
817 x2 = u.ux - (troom->hy - u.uy);
818 y2 = troom->hy;
819 if (x1 < troom->lx && x2 < troom->lx)
820 return;
821 else if (x2 < troom->lx || x1 >= troom->lx && !rn2(2)) {
822 x = x1;
823 y = y1;
824 } else {
825 x = x2;
826 y = y2;
829 } else if(u.uy == troom->ly - 1) {
830 if (stpx != 0 || stpy != sgn(u.uy - troom->hy)) {
831 x = u.ux;
832 y = troom->hy;
833 } else {
834 /* Diagonal required */
835 x1 = troom->lx;
836 y1 = u.uy + u.ux - troom->lx;
837 x2 = troom->hx;
838 y2 = u.uy + troom->hx - u.ux;
839 if (y1 > troom->hy && y2 > troom->hy)
840 return;
841 else if (y2 > troom->hy || y1 <= troom->hy && !rn2(2)) {
842 x = x1;
843 y = y1;
844 } else {
845 x = x2;
846 y = y2;
849 } else if(u.uy == troom->hy + 1) {
850 if (stpx != 0 || stpy != sgn(u.uy - troom->ly)) {
851 x = u.ux;
852 y = troom->ly;
853 } else {
854 /* Diagonal required */
855 x1 = troom->lx;
856 y1 = u.uy - (u.ux - troom->lx);
857 x2 = troom->hx;
858 y2 = u.uy - (troom->hx - u.ux);
859 if (y1 < troom->ly && y2 < troom->ly)
860 return;
861 else if (y2 < troom->ly || y1 >= troom->ly && !rn2(2)) {
862 x = x1;
863 y = y1;
864 } else {
865 x = x2;
866 y = y2;
870 } else {
871 /* Calculate the possible orthogonal paths */
872 n = 0;
873 if (stpx != 0 || stpy != sgn(u.uy - troom->ly)) {
874 poss[n].x = u.ux;
875 poss[n++].y = troom->ly;
877 if (stpx != 0 || stpy != sgn(u.uy - troom->hy)) {
878 poss[n].x = u.ux;
879 poss[n++].y = troom->hy;
881 if (stpx != sgn(u.ux - troom->lx) || stpy != 0) {
882 poss[n].x = troom->lx;
883 poss[n++].y = u.uy;
885 if (stpx != sgn(u.ux - troom->hx) || stpy != 0) {
886 poss[n].x = troom->hx;
887 poss[n++].y = u.uy;
889 if (n) {
890 n = rn2(n);
891 x = poss[n].x;
892 y = poss[n].y;
893 } else {
894 impossible("Omnipresent priest?");
895 return;
898 if(!linedup(u.ux, u.uy, x, y, FALSE))
899 return;
902 switch(rn2(3)) {
903 case 0:
904 pline("%s roars in anger: \"Thou shalt suffer!\"",
905 a_gname_at(ax, ay));
906 break;
907 case 1:
908 pline("%s voice booms: \"How darest thou harm my servant!\"",
909 s_suffix(a_gname_at(ax, ay)));
910 break;
911 default:
912 pline("%s roars: \"Thou dost profane my shrine!\"",
913 a_gname_at(ax, ay));
914 break;
917 buzz(-10-(AD_ELEC-1), 6, x, y, sgn(tbx), sgn(tby)); /* bolt of lightning */
918 exercise(A_WIS, FALSE);
921 void
922 angry_priest()
924 register struct monst *priest;
925 struct rm *lev;
927 if ((priest = findpriest(temple_occupied(u.urooms))) != 0) {
928 wakeup(priest);
930 * If the altar has been destroyed or converted, let the
931 * priest run loose.
932 * (When it's just a conversion and there happens to be
933 * a fresh corpse nearby, the priest ought to have an
934 * opportunity to try converting it back; maybe someday...)
936 lev = &levl[EPRI(priest)->shrpos.x][EPRI(priest)->shrpos.y];
937 if (!IS_ALTAR(lev->typ) ||
938 ((aligntyp)Amask2align(lev->altarmask & AM_MASK) !=
939 EPRI(priest)->shralign)) {
940 priest->ispriest = 0; /* now a roamer */
941 priest->isminion = 1; /* but still aligned */
942 /* this overloads the `shroom' field, which is now clobbered */
943 EPRI(priest)->renegade = 0;
949 * When saving bones, find priests that aren't on their shrine level,
950 * and remove them. This avoids big problems when restoring bones.
952 void
953 clearpriests()
955 register struct monst *mtmp, *mtmp2;
957 for(mtmp = fmon; mtmp; mtmp = mtmp2) {
958 mtmp2 = mtmp->nmon;
959 if (!DEADMONSTER(mtmp) && mtmp->ispriest && !on_level(&(EPRI(mtmp)->shrlevel), &u.uz))
960 mongone(mtmp);
964 /* munge priest-specific structure when restoring -dlc */
965 void
966 restpriest(mtmp, ghostly)
967 register struct monst *mtmp;
968 boolean ghostly;
970 if(u.uz.dlevel) {
971 if (ghostly)
972 assign_level(&(EPRI(mtmp)->shrlevel), &u.uz);
976 #endif /* OVLB */
978 /*priest.c*/