1/* SCCS Id: @(#)priest.c 3.4 2002/11/06 */ 2/* Copyright (c) Izchak Miller, Steve Linhart, 1989. */ 3/* NetHack may be freely redistributed. See license for details. */ 4 5#include "hack.h" 6#include "mfndpos.h" 7#include "eshk.h" 8#include "epri.h" 9#include "emin.h" 10 11/* this matches the categorizations shown by enlightenment */ 12#define ALGN_SINNED (-4) /* worse than strayed */ 13 14#ifdef OVLB 15 16STATIC_DCL boolean FDECL(histemple_at,(struct monst *,XCHAR_P,XCHAR_P)); 17STATIC_DCL boolean FDECL(has_shrine,(struct monst *)); 18 19/* 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. 22 */ 23int 24move_special(mtmp,in_his_shop,appr,uondoor,avoid,omx,omy,gx,gy) 25register struct monst *mtmp; 26boolean in_his_shop; 27schar appr; 28boolean uondoor,avoid; 29register xchar omx,omy,gx,gy; 30{ 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; 38 39 if(omx == gx && omy == gy) 40 return(0); 41 if(mtmp->mconf) { 42 avoid = FALSE; 43 appr = 0; 44 } 45 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)) 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 } 57 if (is_giant(mtmp->data)) allowflags |= BUSTDOOR; 58 cnt = mfndpos(mtmp, poss, info, allowflags); 59 60 if(mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */ 61 for(i=0; i<cnt; i++) 62 if(!(info[i] & NOTONL)) goto pick_move; 63 avoid = FALSE; 64 } 65 66#define GDIST(x,y) (dist2(x,y,gx,gy)) 67pick_move: 68 chcnt = 0; 69 for(i=0; i<cnt; i++) { 70 nx = poss[i].x; 71 ny = poss[i].y; 72 if(levl[nx][ny].typ == ROOM || 73 (mtmp->ispriest && 74 levl[nx][ny].typ == ALTAR) || 75 (mtmp->isshk && 76 (!in_his_shop || ESHK(mtmp)->following))) { 77 if(avoid && (info[i] & NOTONL)) 78 continue; 79 if((!appr && !rn2(++chcnt)) || 80 (appr && GDIST(nx,ny) < GDIST(nix,niy))) { 81 nix = nx; 82 niy = ny; 83 } 84 } 85 } 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 89 * lined up */ 90 avoid = FALSE; 91 goto pick_move; 92 } 93 94 if(nix != omx || niy != omy) { 95 remove_monster(omx, omy); 96 place_monster(mtmp, nix, niy); 97 newsym(nix,niy); 98 if (mtmp->isshk && !in_his_shop && inhishop(mtmp)) 99 check_special_room(FALSE); 100 if(ib) { 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); 106 } 107 return(1); 108 } 109 return(0); 110} 111 112#endif /* OVLB */ 113 114#ifdef OVL0 115 116char 117temple_occupied(array) 118register char *array; 119{ 120 register char *ptr; 121 122 for (ptr = array; *ptr; ptr++) 123 if (rooms[*ptr - ROOMOFFSET].rtype == TEMPLE) 124 return(*ptr); 125 return('\0'); 126} 127 128#endif /* OVL0 */ 129#ifdef OVLB 130 131STATIC_OVL boolean 132histemple_at(priest, x, y) 133register struct monst *priest; 134register xchar x, y; 135{ 136 return((boolean)((EPRI(priest)->shroom == *in_rooms(x, y, TEMPLE)) && 137 on_level(&(EPRI(priest)->shrlevel), &u.uz))); 138} 139 140/* 141 * pri_move: return 1: moved 0: didn't -1: let m_move do it -2: died 142 */ 143int 144pri_move(priest) 145register struct monst *priest; 146{ 147 register xchar gx,gy,omx,omy; 148 schar temple; 149 boolean avoid = TRUE; 150 151 omx = priest->mx; 152 omy = priest->my; 153 154 if(!histemple_at(priest, omx, omy)) return(-1); 155 156 temple = EPRI(priest)->shroom; 157 158 gx = EPRI(priest)->shrpos.x; 159 gy = EPRI(priest)->shrpos.y; 160 161 gx += rn1(3,-1); /* mill around the altar */ 162 gy += rn1(3,-1); 163 164 if(!priest->mpeaceful || 165 (Conflict && !resist(priest, RING_CLASS, 0, 0))) { 166 if(monnear(priest, u.ux, u.uy)) { 167 if(Displaced) 168 Your("displaced image doesn't fool %s!", 169 mon_nam(priest)); 170 (void) mattacku(priest); 171 return(0); 172 } else if(index(u.urooms, temple)) { 173 /* chase player if inside temple & can see him */ 174 if(priest->mcansee && m_canseeu(priest)) { 175 gx = u.ux; 176 gy = u.uy; 177 } 178 avoid = FALSE; 179 } 180 } else if(Invis) avoid = FALSE; 181 182 return(move_special(priest,FALSE,TRUE,FALSE,avoid,omx,omy,gx,gy)); 183} 184 185/* exclusively for mktemple() */ 186void 187priestini(lvl, sroom, sx, sy, sanctum) 188d_level *lvl; 189struct mkroom *sroom; 190int sx, sy; 191boolean sanctum; /* is it the seat of the high priest? */ 192{ 193 struct monst *priest; 194 struct obj *otmp; 195 int cnt; 196 197 if(MON_AT(sx+1, sy)) 198 (void) rloc(m_at(sx+1, sy), FALSE); /* insurance */ 199 200 priest = makemon(&mons[sanctum ? PM_HIGH_PRIEST : PM_ALIGNED_PRIEST], 201 sx + 1, sy, NO_MM_FLAGS); 202 if (priest) { 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 */ 213 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); 218 } 219 /* 2 to 4 spellbooks */ 220 for (cnt = rn1(3,2); cnt > 0; --cnt) { 221 (void) mpickobj(priest, mkobj(SPBOOK_CLASS, FALSE)); 222 } 223 /* robe [via makemon()] */ 224 if (rn2(2) && (otmp = which_armor(priest, W_ARMC)) != 0) { 225 if (p_coaligned(priest)) 226 uncurse(otmp); 227 else 228 curse(otmp); 229 } 230 } 231} 232 233/* 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 244 */ 245char * 246priestname(mon, pname) 247register struct monst *mon; 248char *pname; /* caller-supplied output buffer */ 249{ 250 const char *what = Hallucination ? rndmonnam() : mon->data->mname; 251 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]) { 256 /* use epri */ 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]) { 261 Strcat(pname, what); 262 Strcat(pname, " "); 263 } 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 "); 269 if (Hallucination) 270 Strcat(pname, "poohbah "); 271 else if (mon->female) 272 Strcat(pname, "priestess "); 273 else 274 Strcat(pname, "priest "); 275 } 276 Strcat(pname, "of "); 277 Strcat(pname, halu_gname((int)EPRI(mon)->shralign)); 278 return(pname); 279 } 280 /* use emin instead of epri */ 281 Strcat(pname, what); 282 Strcat(pname, " of "); 283 Strcat(pname, halu_gname(EMIN(mon)->min_align)); 284 return(pname); 285} 286 287boolean 288p_coaligned(priest) 289struct monst *priest; 290{ 291 return((boolean)(u.ualign.type == ((int)EPRI(priest)->shralign))); 292} 293 294STATIC_OVL boolean 295has_shrine(pri) 296struct monst *pri; 297{ 298 struct rm *lev; 299 300 if(!pri) 301 return(FALSE); 302 lev = &levl[EPRI(pri)->shrpos.x][EPRI(pri)->shrpos.y]; 303 if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE)) 304 return(FALSE); 305 return((boolean)(EPRI(pri)->shralign == Amask2align(lev->altarmask & ~AM_SHRINE))); 306} 307 308struct monst * 309findpriest(roomno) 310char roomno; 311{ 312 register struct monst *mtmp; 313 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)) 318 return(mtmp); 319 } 320 return (struct monst *)0; 321} 322 323/* called from check_special_room() when the player enters the temple room */ 324void 325intemple(roomno) 326register int roomno; 327{ 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; 332 char buf[BUFSZ]; 333 334 if(!temple_occupied(u.urooms0)) { 335 if(tended) { 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 && 340 flags.soundok); 341 if (can_speak) { 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; 347 pline("%s intones:", 348 canseemon(priest) ? Monnam(priest) : "A nearby voice"); 349 priest->ispriest = save_priest; 350 } 351 msg2 = 0; 352 if(sanctum && Is_sanctum(&u.uz)) { 353 if(priest->mpeaceful) { 354 msg1 = "Infidel, you have entered Moloch's Sanctum!"; 355 msg2 = "Be gone!"; 356 priest->mpeaceful = 0; 357 set_malign(priest); 358 } else 359 msg1 = "You desecrate this place by your presence!"; 360 } else { 361 Sprintf(buf, "Pilgrim, you enter a %s place!", 362 !shrined ? "desecrated" : "sacred"); 363 msg1 = buf; 364 } 365 if (can_speak) { 366 verbalize(msg1); 367 if (msg2) verbalize(msg2); 368 } 369 if(!sanctum) { 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."); 376 } 377 } else { 378 switch(rn2(3)) { 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; 383 } 384 if(!rn2(5)) { 385 struct monst *mtmp; 386 387 if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy,NO_MM_FLAGS))) 388 return; 389 if (!Blind || sensemon(mtmp)) 390 pline("An enormous ghost appears next to you!"); 391 else You("sense a presence close by!"); 392 mtmp->mpeaceful = 0; 393 set_malign(mtmp); 394 if(flags.verbose) 395 You("are frightened to death, and unable to move."); 396 nomul(-3); 397 nomovemsg = "You regain your composure."; 398 } 399 } 400 } 401} 402 403void 404priest_talk(priest) 405register struct monst *priest; 406{ 407 boolean coaligned = p_coaligned(priest); 408 boolean strayed = (u.ualign.record < 0); 409 410 /* KMH, conduct */ 411 u.uconduct.gnostic++; 412 413 if(priest->mflee || (!priest->ispriest && coaligned && strayed)) { 414 pline("%s doesn't want anything to do with you!", 415 Monnam(priest)); 416 priest->mpeaceful = 0; 417 return; 418 } 419 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." 427 }; 428 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; 434 } 435 priest->mpeaceful = 0; 436 verbalize(cranky_msg[rn2(3)]); 437 return; 438 } 439 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; 445 return; 446 } 447#ifndef GOLDOBJ 448 if(!u.ugold) { 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) 455 u.ugold = 2L; 456 else 457 u.ugold = 1L; 458 priest->mgold -= u.ugold; 459 flags.botl = 1; 460#else 461 if(!money_cnt(invent)) { 462 if(coaligned && !strayed) { 463 long pmoney = money_cnt(priest->minvent); 464 if (pmoney > 0L) { 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); 469#endif 470 } else 471 pline("%s preaches the virtues of poverty.", Monnam(priest)); 472 exercise(A_WIS, TRUE); 473 } else 474 pline("%s is not interested.", Monnam(priest)); 475 return; 476 } else { 477 long offer; 478 479 pline("%s asks you for a contribution for the temple.", 480 Monnam(priest)); 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)) { 485#ifndef GOLDOBJ 486 if(u.ugold > (offer * 2L)) verbalize("Cheapskate."); 487#else 488 if(money_cnt(invent) > (offer * 2L)) verbalize("Cheapskate."); 489#endif 490 else { 491 verbalize("I thank thee for thy contribution."); 492 /* give player some token */ 493 exercise(A_WIS, TRUE); 494 } 495 } else if(offer < (u.ulevel * 400)) { 496 verbalize("Thou art indeed a pious individual."); 497#ifndef GOLDOBJ 498 if(u.ugold < (offer * 2L)) { 499#else 500 if(money_cnt(invent) < (offer * 2L)) { 501#endif 502 if (coaligned && u.ualign.record <= ALGN_SINNED) 503 adjalign(1); 504 verbalize("I bestow upon thee a blessing."); 505 incr_itimeout(&HClairvoyant, rn1(500,500)); 506 } 507 } else if(offer < (u.ulevel * 600) && 508 u.ublessed < 20 && 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); 514 } else u.ublessed++; 515 } else { 516 verbalize("Thy selfless generosity is deeply appreciated."); 517#ifndef GOLDOBJ 518 if(u.ugold < (offer * 2L) && coaligned) { 519#else 520 if(money_cnt(invent) < (offer * 2L) && coaligned) { 521#endif 522 if(strayed && (moves - u.ucleansed) > 5000L) { 523 u.ualign.record = 0; /* cleanse thee */ 524 u.ucleansed = moves; 525 } else { 526 adjalign(2); 527 } 528 } 529 } 530 } 531} 532 533struct monst * 534mk_roamer(ptr, alignment, x, y, peaceful) 535register struct permonst *ptr; 536aligntyp alignment; 537xchar x, y; 538boolean peaceful; 539{ 540 register struct monst *roamer; 541 register boolean coaligned = (u.ualign.type == alignment); 542 543 if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL]) 544 return((struct monst *)0); 545 546 if (MON_AT(x, y)) (void) rloc(m_at(x, y), FALSE); /* insurance */ 547 548 if (!(roamer = makemon(ptr, x, y, NO_MM_FLAGS))) 549 return((struct monst *)0); 550 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 */ 560 561 /* MORE TO COME */ 562 return(roamer); 563} 564 565void 566reset_hostility(roamer) 567register struct monst *roamer; 568{ 569 if(!(roamer->isminion && (roamer->data == &mons[PM_ALIGNED_PRIEST] || 570 roamer->data == &mons[PM_ANGEL]))) 571 return; 572 573 if(EPRI(roamer)->shralign != u.ualign.type) { 574 roamer->mpeaceful = roamer->mtame = 0; 575 set_malign(roamer); 576 } 577 newsym(roamer->mx, roamer->my); 578} 579 580boolean 581in_your_sanctuary(mon, x, y) 582struct monst *mon; /* if non-null, <mx,my> overrides <x,y> */ 583xchar x, y; 584{ 585 register char roomno; 586 register struct monst *priest; 587 588 if (mon) { 589 if (is_minion(mon->data) || is_rider(mon->data)) return FALSE; 590 x = mon->mx, y = mon->my; 591 } 592 if (u.ualign.record <= ALGN_SINNED) /* sinned or worse */ 593 return FALSE; 594 if ((roomno = temple_occupied(u.urooms)) == 0 || 595 roomno != *in_rooms(x, y, TEMPLE)) 596 return FALSE; 597 if ((priest = findpriest(roomno)) == 0) 598 return FALSE; 599 return (boolean)(has_shrine(priest) && 600 p_coaligned(priest) && 601 priest->mpeaceful); 602} 603 604void 605ghod_hitsu(priest) /* when attacking "priest" in his temple */ 606struct monst *priest; 607{ 608 int x, y, ax, ay, roomno = (int)temple_occupied(u.urooms); 609 struct mkroom *troom; 610 611 if (!roomno || !has_shrine(priest)) 612 return; 613 614 ax = x = EPRI(priest)->shrpos.x; 615 ay = y = EPRI(priest)->shrpos.y; 616 troom = &rooms[roomno - ROOMOFFSET]; 617 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)) { 620 621 if(u.ux == troom->lx - 1) { 622 x = troom->hx; 623 y = u.uy; 624 } else if(u.ux == troom->hx + 1) { 625 x = troom->lx; 626 y = u.uy; 627 } else if(u.uy == troom->ly - 1) { 628 x = u.ux; 629 y = troom->hy; 630 } else if(u.uy == troom->hy + 1) { 631 x = u.ux; 632 y = troom->ly; 633 } 634 } else { 635 switch(rn2(4)) { 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; 640 } 641 } 642 if(!linedup(u.ux, u.uy, x, y)) return; 643 } 644 645 switch(rn2(3)) { 646 case 0: 647 pline("%s roars in anger: \"Thou shalt suffer!\"", 648 a_gname_at(ax, ay)); 649 break; 650 case 1: 651 pline("%s voice booms: \"How darest thou harm my servant!\"", 652 s_suffix(a_gname_at(ax, ay))); 653 break; 654 default: 655 pline("%s roars: \"Thou dost profane my shrine!\"", 656 a_gname_at(ax, ay)); 657 break; 658 } 659 660 buzz(-10-(AD_ELEC-1), 6, x, y, sgn(tbx), sgn(tby)); /* bolt of lightning */ 661 exercise(A_WIS, FALSE); 662} 663 664void 665angry_priest() 666{ 667 register struct monst *priest; 668 struct rm *lev; 669 670 if ((priest = findpriest(temple_occupied(u.urooms))) != 0) { 671 wakeup(priest); 672 /* 673 * If the altar has been destroyed or converted, let the 674 * priest run loose. 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...) 678 */ 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; 687 } 688 } 689} 690 691/* 692 * When saving bones, find priests that aren't on their shrine level, 693 * and remove them. This avoids big problems when restoring bones. 694 */ 695void 696clearpriests() 697{ 698 register struct monst *mtmp, *mtmp2; 699 700 for(mtmp = fmon; mtmp; mtmp = mtmp2) { 701 mtmp2 = mtmp->nmon; 702 if (!DEADMONSTER(mtmp) && mtmp->ispriest && !on_level(&(EPRI(mtmp)->shrlevel), &u.uz)) 703 mongone(mtmp); 704 } 705} 706 707/* munge priest-specific structure when restoring -dlc */ 708void 709restpriest(mtmp, ghostly) 710register struct monst *mtmp; 711boolean ghostly; 712{ 713 if(u.uz.dlevel) { 714 if (ghostly) 715 assign_level(&(EPRI(mtmp)->shrlevel), &u.uz); 716 } 717} 718 719#endif /* OVLB */ 720 721/*priest.c*/ 722