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
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.
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
) || (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 */
64 if(!(info
[i
] & NOTONL
)) goto pick_move
;
68 #define GDIST(x,y) (dist2(x,y,gx,gy))
71 for(i
=0; i
<cnt
; i
++) {
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
)) ||
77 levl
[nx
][ny
].typ
== ALTAR
) ||
79 (!in_his_shop
|| ESHK(mtmp
)->following
))) {
80 if(avoid
&& (info
[i
] & NOTONL
))
82 if((!appr
&& !rn2(++chcnt
)) ||
83 (appr
&& GDIST(nx
,ny
) < GDIST(nix
,niy
))) {
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
97 if(nix
!= omx
|| niy
!= omy
) {
98 remove_monster(omx
, omy
);
99 place_monster(mtmp
, nix
, niy
);
101 if (mtmp
->isshk
&& !in_his_shop
&& inhishop(mtmp
))
102 check_special_room(FALSE
);
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
);
120 temple_occupied(array
)
121 register char *array
;
125 for (ptr
= array
; *ptr
; ptr
++)
126 if (rooms
[*ptr
- ROOMOFFSET
].rtype
== TEMPLE
)
135 histemple_at(priest
, x
, y
)
136 register struct monst
*priest
;
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
148 register struct monst
*priest
;
150 register xchar gx
,gy
,omx
,omy
;
152 boolean avoid
= TRUE
;
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 */
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
)) {
177 Your("displaced image doesn't fool %s!",
179 (void) mattacku(priest
);
181 } else if(index(u
.urooms
, temple
)) {
182 /* chase player if inside temple & can see him */
183 if(priest
->mcansee
&& m_canseeu(priest
)) {
189 } else if(Invis
) avoid
= FALSE
;
191 return(move_special(priest
,FALSE
,TRUE
,FALSE
,avoid
,omx
,omy
,gx
,gy
));
194 /* exclusively for mktemple() */
196 priestini(lvl
, sroom
, sx
, sy
, sanctum
)
198 struct mkroom
*sroom
;
200 boolean sanctum
; /* is it the seat of the high priest? */
202 struct monst
*priest
;
203 struct obj
*otmp
= NULL
;
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
);
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));
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) {
241 obj
= mksobj(ROBE
, TRUE
, FALSE
, FALSE
);
243 obj
= oname(obj
, artiname(ART_MOTHERFUCKER_TROPHY
));
246 (void) mpickobj(priest
, obj
, TRUE
);
248 m_dowear(priest
, TRUE
);
251 } else if (rn2(2) || (otmp
= which_armor(priest
, W_ARM
)) == 0) {
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
))
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
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
]) {
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
]) {
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 ");
316 strcat(pname
, "poohbah ");
317 else if (mon
->female
)
318 strcat(pname
, "priestess ");
320 strcat(pname
, "priest ");
322 strcat(pname
, "of ");
323 strcat(pname
, halu_gname((int)EPRI(mon
)->shralign
));
326 /* use emin instead of epri */
328 strcat(pname
, " of ");
329 strcat(pname
, halu_gname(EMIN(mon
)->min_align
));
335 struct monst
*priest
;
337 return((boolean
)(u
.ualign
.type
== ((int)EPRI(priest
)->shralign
)));
348 lev
= &levl
[EPRI(pri
)->shrpos
.x
][EPRI(pri
)->shrpos
.y
];
349 if (!IS_ALTAR(lev
->typ
) || !(lev
->altarmask
& AM_SHRINE
))
351 return((boolean
)(EPRI(pri
)->shralign
== Amask2align(lev
->altarmask
& ~AM_SHRINE
)));
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
))
366 return (struct monst
*)0;
369 /* called from check_special_room() when the player enters the temple room */
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
;
380 if(!temple_occupied(u
.urooms0
)) {
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
&&
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;
394 canseemon(priest
) ? Monnam(priest
) : "A nearby voice");
395 priest
->ispriest
= save_priest
;
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!";
404 priest
->mpeaceful
= 0;
407 if (rn2(2)) msg1
= "You desecrate this place by your presence!";
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!";
417 sprintf(buf
, "Pilgrim, you enter a %s place!",
418 !shrined
? "desecrated" : "sacred");
422 verbalize("%s", msg1
);
423 if (msg2
) verbalize("%s", msg2
);
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.");
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;
445 if(!(mtmp
= makemon(&mons
[PM_GHOST
],u
.ux
,u
.uy
,NO_MM_FLAGS
)))
447 if (!Blind
|| sensemon(mtmp
))
448 pline("An enormous ghost appears next to you!");
449 else You("sense a presence close by!");
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.";
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!");
475 u
.uconduct
.gnostic
++;
476 if (Race_if(PM_MAGYAR
)) {
477 You_feel("bad about breaking the atheist conduct.");
481 if(priest
->mflee
|| (!priest
->ispriest
&& coaligned
&& strayed
)) {
482 pline("%s doesn't want anything to do with you!",
484 priest
->mpeaceful
= 0;
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;
502 priest
->mcanmove
= 1;
504 priest
->mpeaceful
= 0;
505 verbalize("%s", cranky_msg
[rn2(3)]);
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;
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)
528 priest
->mgold
-= u
.ugold
;
531 if(!money_cnt(invent
)) {
532 if(coaligned
&& !strayed
) {
533 long pmoney
= money_cnt(priest
->minvent
);
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);
541 pline("%s preaches the virtues of poverty.", Monnam(priest
));
542 exercise(A_WIS
, TRUE
);
544 pline("%s is not interested.", Monnam(priest
));
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.",
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) ) {
558 if(u
.ugold
> (offer
* 2L)) verbalize(issoviet
? "lol u sposobstvovali slishkom malo govorit sovetskiy mat' iz ada." : "Cheapskate.");
560 if(money_cnt(invent
) > (offer
* 2L)) verbalize(issoviet
? "lol u sposobstvovali slishkom malo govorit sovetskiy mat' iz ada." : "Cheapskate.");
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.");
570 if(u
.ugold
< (offer
* 2L)) {
572 if(money_cnt(invent
) < (offer
* 2L)) {
574 if (coaligned
&& u
.ualign
.record
<= ALGN_SINNED
)
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) &&
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);
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
);
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 */
612 if(u
.ugold
< (offer
* 2L) && coaligned
) {
614 if(money_cnt(invent
) < (offer
* 2L) && coaligned
) {
616 /* don't immediately lose all negative alignment --Amy */
617 if(strayed
&& (moves
- u
.ucleansed
) > 5000L) {
618 u
.ualign
.record
/= 2; /* cleanse thee */
621 verbalize("Thou hast been cleansed.");
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)) {
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.");
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);
650 if(u
.ugold
< (offer
* 2L) && coaligned
) {
652 if(money_cnt(invent
) < (offer
* 2L) && coaligned
) {
654 /* don't immediately lose all negative alignment --Amy */
655 if(strayed
&& (moves
- u
.ucleansed
) > 5000L) {
656 u
.ualign
.record
/= 2; /* cleanse thee */
659 verbalize("Thou hast been cleansed.");
665 if (u
.ualign
.sins
> 0) {
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
);
673 otmp
->owt
= weight(otmp
);
674 verbalize("Thou shall have a large supply of sacred water.");
685 mk_roamer(ptr
, alignment
, x
, y
, peaceful
)
686 register struct permonst
*ptr
;
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 */
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
])))
724 if(EPRI(roamer
)->shralign
!= u
.ualign
.type
) {
725 roamer
->mpeaceful
= roamer
->mtame
= 0;
728 newsym(roamer
->mx
, roamer
->my
);
732 in_your_sanctuary(mon
, x
, y
)
733 struct monst
*mon
; /* if non-null, <mx,my> overrides <x,y> */
736 register char roomno
;
737 register struct monst
*priest
;
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 */
745 if ((roomno
= temple_occupied(u
.urooms
)) == 0 ||
746 roomno
!= *in_rooms(x
, y
, TEMPLE
))
748 if ((priest
= findpriest(roomno
)) == 0)
750 return (boolean
)(has_shrine(priest
) &&
751 p_coaligned(priest
) &&
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
;
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
))
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
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) {
794 /* Diagonal required */
795 x1
= u
.ux
+ u
.uy
- troom
->ly
;
797 x2
= u
.ux
+ troom
->hy
- u
.uy
;
799 if (x1
> troom
->hx
&& x2
> troom
->hx
)
801 else if (x2
> troom
->hx
|| x1
<= troom
->hx
&& !rn2(2)) {
809 } else if(u
.ux
== troom
->hx
+ 1) {
810 if (stpx
!= sgn(u
.ux
- troom
->lx
) || stpy
!= 0) {
814 /* Diagonal required */
815 x1
= u
.ux
- (u
.uy
- troom
->ly
);
817 x2
= u
.ux
- (troom
->hy
- u
.uy
);
819 if (x1
< troom
->lx
&& x2
< troom
->lx
)
821 else if (x2
< troom
->lx
|| x1
>= troom
->lx
&& !rn2(2)) {
829 } else if(u
.uy
== troom
->ly
- 1) {
830 if (stpx
!= 0 || stpy
!= sgn(u
.uy
- troom
->hy
)) {
834 /* Diagonal required */
836 y1
= u
.uy
+ u
.ux
- troom
->lx
;
838 y2
= u
.uy
+ troom
->hx
- u
.ux
;
839 if (y1
> troom
->hy
&& y2
> troom
->hy
)
841 else if (y2
> troom
->hy
|| y1
<= troom
->hy
&& !rn2(2)) {
849 } else if(u
.uy
== troom
->hy
+ 1) {
850 if (stpx
!= 0 || stpy
!= sgn(u
.uy
- troom
->ly
)) {
854 /* Diagonal required */
856 y1
= u
.uy
- (u
.ux
- troom
->lx
);
858 y2
= u
.uy
- (troom
->hx
- u
.ux
);
859 if (y1
< troom
->ly
&& y2
< troom
->ly
)
861 else if (y2
< troom
->ly
|| y1
>= troom
->ly
&& !rn2(2)) {
871 /* Calculate the possible orthogonal paths */
873 if (stpx
!= 0 || stpy
!= sgn(u
.uy
- troom
->ly
)) {
875 poss
[n
++].y
= troom
->ly
;
877 if (stpx
!= 0 || stpy
!= sgn(u
.uy
- troom
->hy
)) {
879 poss
[n
++].y
= troom
->hy
;
881 if (stpx
!= sgn(u
.ux
- troom
->lx
) || stpy
!= 0) {
882 poss
[n
].x
= troom
->lx
;
885 if (stpx
!= sgn(u
.ux
- troom
->hx
) || stpy
!= 0) {
886 poss
[n
].x
= troom
->hx
;
894 impossible("Omnipresent priest?");
898 if(!linedup(u
.ux
, u
.uy
, x
, y
, FALSE
))
904 pline("%s roars in anger: \"Thou shalt suffer!\"",
908 pline("%s voice booms: \"How darest thou harm my servant!\"",
909 s_suffix(a_gname_at(ax
, ay
)));
912 pline("%s roars: \"Thou dost profane my shrine!\"",
917 buzz(-10-(AD_ELEC
-1), 6, x
, y
, sgn(tbx
), sgn(tby
)); /* bolt of lightning */
918 exercise(A_WIS
, FALSE
);
924 register struct monst
*priest
;
927 if ((priest
= findpriest(temple_occupied(u
.urooms
))) != 0) {
930 * If the altar has been destroyed or converted, let the
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.
955 register struct monst
*mtmp
, *mtmp2
;
957 for(mtmp
= fmon
; mtmp
; mtmp
= mtmp2
) {
959 if (!DEADMONSTER(mtmp
) && mtmp
->ispriest
&& !on_level(&(EPRI(mtmp
)->shrlevel
), &u
.uz
))
964 /* munge priest-specific structure when restoring -dlc */
966 restpriest(mtmp
, ghostly
)
967 register struct monst
*mtmp
;
972 assign_level(&(EPRI(mtmp
)->shrlevel
), &u
.uz
);