| abstract
| - Below is the full text to priest.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/priest.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)priest.c 3.1 92/01/05 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. #ifdef OVLB 12. 13. static boolean FDECL(histemple_at,(struct monst *,XCHAR_P,XCHAR_P)); 14. static boolean FDECL(has_shrine,(struct monst *)); 15. 16. /* 17. * Move for priests and shopkeepers. Called from shk_move() and pri_move(). 18. * Valid returns are 1: moved 0: didn't -1: let m_move do it -2: died. 19. */ 20. int 21. move_special(mtmp,in_his_shop,appr,uondoor,avoid,omx,omy,gx,gy) 22. register struct monst *mtmp; 23. boolean in_his_shop; 24. schar appr; 25. boolean uondoor,avoid; 26. register xchar omx,omy,gx,gy; 27. { 28. register xchar nx,ny,nix,niy; 29. register schar i; 30. schar chcnt,cnt; 31. coord poss[9]; 32. long info[9]; 33. long allowflags; 34. struct obj *ib = (struct obj *)0; 35. 36. if(omx == gx && omy == gy) 37. return(0); 38. if(mtmp->mconf) { 39. avoid = FALSE; 40. appr = 0; 41. } 42. 43. nix = omx; 44. niy = omy; 45. if (mtmp->isshk) allowflags = ALLOW_SSM; 46. else allowflags = ALLOW_SSM | ALLOW_SANCT; 47. if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK|ALLOW_WALL); 48. if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK; 49. if (tunnels(mtmp->data) && 50. (!needspick(mtmp->data) || m_carrying(mtmp, PICK_AXE))) 51. allowflags |= ALLOW_DIG; 52. if (!nohands(mtmp->data) && !verysmall(mtmp->data)) { 53. allowflags |= OPENDOOR; 54. if (m_carrying(mtmp, SKELETON_KEY)) allowflags |= BUSTDOOR; 55. } 56. if (is_giant(mtmp->data)) allowflags |= BUSTDOOR; 57. cnt = mfndpos(mtmp, poss, info, allowflags); 58. 59. if(mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */ 60. for(i=0; i 61. if(!(info[i] & NOTONL)) goto pick_move; 62. avoid = FALSE; 63. } 64. 65. #define GDIST(x,y) (dist2(x,y,gx,gy)) 66. pick_move: 67. chcnt = 0; 68. for(i=0; i 69. nx = poss[i].x; 70. ny = poss[i].y; 71. if(levl[nx][ny].typ == ROOM || 72. (mtmp->ispriest && 73. levl[nx][ny].typ == ALTAR) || 74. (mtmp->isshk && 75. (!in_his_shop || ESHK(mtmp)->following))) { 76. if(avoid && (info[i] & NOTONL)) 77. continue; 78. if((!appr && !rn2(++chcnt)) || 79. (appr && GDIST(nx,ny) < GDIST(nix,niy))) { 80. nix = nx; 81. niy = ny; 82. } 83. } 84. } 85. if(mtmp->ispriest && avoid && 86. nix == omx && niy == omy && onlineu(omx,omy)) { 87. /* might as well move closer as long it's going to stay 88. * lined up */ 89. avoid = FALSE; 90. goto pick_move; 91. } 92. 93. if(nix != omx || niy != omy) { 94. remove_monster(omx, omy); 95. place_monster(mtmp, nix, niy); 96. newsym(nix,niy); 97. if (mtmp->isshk && !in_his_shop && inhishop(mtmp)) 98. check_special_room(FALSE); 99. if(ib) { 100. if (cansee(mtmp->mx,mtmp->my)) 101. pline("%s picks up %s.", Monnam(mtmp), 102. distant_name(ib,doname)); 103. freeobj(ib); 104. mpickobj(mtmp, ib); 105. } 106. return(1); 107. } 108. return(0); 109. } 110. 111. #endif /* OVLB */ 112. 113. #ifdef OVL0 114. 115. char 116. temple_occupied(array) 117. register char *array; 118. { 119. register char *ptr; 120. 121. for (ptr = array; *ptr; ptr++) 122. if (rooms[*ptr - ROOMOFFSET].rtype == TEMPLE) 123. return(*ptr); 124. return('\0'); 125. } 126. 127. #endif /* OVL0 */ 128. #ifdef OVLB 129. 130. static boolean 131. histemple_at(priest, x, y) 132. register struct monst *priest; 133. register xchar x, y; 134. { 135. return((EPRI(priest)->shroom == *in_rooms(x, y, TEMPLE)) && 136. on_level(&(EPRI(priest)->shrlevel), &u.uz)); 137. } 138. 139. /* 140. * pri_move: return 1: moved 0: didn't -1: let m_move do it -2: died 141. */ 142. int 143. pri_move(priest) 144. register struct monst *priest; 145. { 146. register xchar gx,gy,omx,omy; 147. schar temple; 148. boolean avoid = TRUE; 149. 150. omx = priest->mx; 151. omy = priest->my; 152. 153. if(!histemple_at(priest, omx, omy)) return(-1); 154. 155. temple = EPRI(priest)->shroom; 156. 157. gx = EPRI(priest)->shrpos.x; 158. gy = EPRI(priest)->shrpos.y; 159. 160. gx += rn1(3,-1); /* mill around the altar */ 161. gy += rn1(3,-1); 162. 163. if(!priest->mpeaceful || 164. (Conflict && !resist(priest, RING_CLASS, 0, 0))) { 165. if(monnear(priest, u.ux, u.uy)) { 166. if(Displaced) 167. Your("displaced image doesn't fool %s!", 168. mon_nam(priest)); 169. (void) mattacku(priest); 170. return(0); 171. } else if(index(u.urooms, temple)) { 172. /* chase player if inside temple & can see him */ 173. if(priest->mcansee && m_canseeu(priest)) { 174. gx = u.ux; 175. gy = u.uy; 176. } 177. avoid = FALSE; 178. } 179. } else if(Invis) avoid = FALSE; 180. 181. return(move_special(priest,FALSE,TRUE,FALSE,avoid,omx,omy,gx,gy)); 182. } 183. 184. /* exclusively for mktemple() */ 185. void 186. priestini(lvl, sroom, sx, sy, sanctum) 187. d_level *lvl; 188. struct mkroom *sroom; 189. int sx, sy; 190. boolean sanctum; /* is it the seat of the high priest? */ 191. { 192. register struct monst *priest; 193. register struct obj *otmp; 194. register int cnt; 195. 196. if(MON_AT(sx+1, sy)) 197. rloc(m_at(sx+1, sy)); /* insurance */ 198. 199. if(priest = (sanctum ? makemon(&mons[PM_HIGH_PRIEST], sx+1, sy) 200. : makemon(&mons[PM_ALIGNED_PRIEST], sx+1, sy))) { 201. EPRI(priest)->shroom = (sroom - rooms) + ROOMOFFSET; 202. EPRI(priest)->shralign = Amask2align(levl[sx][sy].altarmask); 203. EPRI(priest)->shrpos.x = sx; 204. EPRI(priest)->shrpos.y = sy; 205. assign_level(&(EPRI(priest)->shrlevel), lvl); 206. priest->mtrapseen = ~0; /* traps are known */ 207. priest->mpeaceful = 1; 208. priest->ispriest = 1; 209. priest->msleep = 0; 210. set_malign(priest); /* mpeaceful may have changed */ 211. 212. /* now his/her goodies... */ 213. (void) mongets(priest, CHAIN_MAIL); 214. (void) mongets(priest, SMALL_SHIELD); 215. #ifdef MUSE 216. m_dowear(priest, TRUE); 217. #endif 218. priest->mgold = (long)rn1(10,20); 219. if(sanctum && EPRI(priest)->shralign == A_NONE && 220. on_level(&sanctum_level, &u.uz)) 221. (void) mongets(priest, AMULET_OF_YENDOR); 222. /* Do NOT put the rest in m_initinv. */ 223. /* Priests created elsewhere than in a */ 224. /* temple should not carry these items, */ 225. /* except for the mace. */ 226. cnt = rn1(2,3); 227. while(cnt) { 228. otmp = mkobj(SPBOOK_CLASS, FALSE); 229. if(otmp) mpickobj(priest, otmp); 230. cnt--; 231. } 232. if(p_coaligned(priest)) 233. (void) mongets(priest, rn2(2) ? CLOAK_OF_PROTECTION 234. : CLOAK_OF_MAGIC_RESISTANCE); 235. else { 236. if(!rn2(5)) 237. otmp = mksobj(CLOAK_OF_MAGIC_RESISTANCE, TRUE, FALSE); 238. else otmp = mksobj(CLOAK_OF_PROTECTION, TRUE, FALSE); 239. if(otmp) { 240. if(!rn2(2)) curse(otmp); 241. mpickobj(priest, otmp); 242. } 243. } 244. 245. otmp = mksobj(MACE, FALSE, FALSE); 246. if(otmp) { 247. otmp->spe = rnd(3); 248. if(!rn2(2)) curse(otmp); 249. mpickobj(priest, otmp); 250. } 251. } 252. } 253. 254. /* 255. * Specially aligned monsters are named specially. 256. * - aligned priests with ispriest and high priests have shrines 257. * they retain ispriest and epri when polymorphed 258. * - aligned priests without ispriest and Angels are roamers 259. * they retain isminion and access epri as emin when polymorphed 260. * (coaligned Angels are also created as minions, but they 261. * use the same naming convention) 262. * - minions do not have ispriest but have isminion and emin 263. */ 264. char * 265. priestname(mon) 266. register struct monst *mon; 267. { 268. static char NEARDATA pname[PL_NSIZ]; 269. 270. Strcpy(pname, "the "); 271. if (mon->minvis) Strcat(pname, "invisible "); 272. if (mon->ispriest || mon->data == &mons[PM_ALIGNED_PRIEST] || 273. mon->data == &mons[PM_ANGEL]) { 274. /* use epri */ 275. if (mon->mtame && mon->data == &mons[PM_ANGEL]) 276. Strcat(pname, "guardian "); 277. if (mon->data != &mons[PM_ALIGNED_PRIEST] && 278. mon->data != &mons[PM_HIGH_PRIEST]) { 279. Strcat(pname, mon->data->mname); 280. Strcat(pname, " "); 281. } 282. if (mon->data != &mons[PM_ANGEL]) { 283. if (!mon->ispriest && EPRI(mon)->renegade) 284. Strcat(pname, "renegade "); 285. if (mon->data == &mons[PM_HIGH_PRIEST]) 286. Strcat(pname, "high "); 287. if (mon->female) 288. Strcat(pname, "priestess "); 289. else 290. Strcat(pname, "priest "); 291. } 292. Strcat(pname, "of "); 293. Strcat(pname, align_gname((int)EPRI(mon)->shralign)); 294. return(pname); 295. } 296. /* use emin instead of epri */ 297. Strcat(pname, mon->data->mname); 298. Strcat(pname, " of "); 299. Strcat(pname, align_gname(EMIN(mon)->min_align)); 300. return(pname); 301. } 302. 303. boolean 304. p_coaligned(priest) 305. struct monst *priest; 306. { 307. return(u.ualign.type == ((int)EPRI(priest)->shralign)); 308. } 309. 310. static boolean 311. has_shrine(pri) 312. struct monst *pri; 313. { 314. struct rm *lev; 315. 316. if(!pri) 317. return(FALSE); 318. lev = &levl[EPRI(pri)->shrpos.x][EPRI(pri)->shrpos.y]; 319. if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE)) 320. return(FALSE); 321. return(EPRI(pri)->shralign == Amask2align(lev->altarmask & ~AM_SHRINE)); 322. } 323. 324. struct monst * 325. findpriest(roomno) 326. char roomno; 327. { 328. register struct monst *mtmp; 329. extern struct monst *fdmon; /* from mon.c */ 330. 331. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 332. if(mtmp->ispriest && (EPRI(mtmp)->shroom == roomno) && 333. histemple_at(mtmp,mtmp->mx,mtmp->my)) 334. return(mtmp); 335. for(mtmp = fdmon; mtmp; mtmp = mtmp->nmon) 336. if(mtmp->ispriest && (EPRI(mtmp)->shroom == roomno) && 337. histemple_at(mtmp,mtmp->mx,mtmp->my)) 338. return(mtmp); 339. return (struct monst *)0; 340. } 341. 342. /* called from check_special_room() when the player enters the temple room */ 343. void 344. intemple(roomno) 345. register int roomno; 346. { 347. register struct monst *priest = findpriest((char)roomno); 348. boolean tended = (priest != (struct monst *)0); 349. boolean shrined = (tended && has_shrine(priest)); 350. boolean sanctum = (tended && priest->data == &mons[PM_HIGH_PRIEST] && 351. (Is_sanctum(&u.uz) || In_endgame(&u.uz))); 352. 353. if(!temple_occupied(u.urooms0)) { 354. if(tended) { 355. pline("%s intones:", 356. (!Blind ? Monnam(priest) : "A nearby voice")); 357. if(sanctum && Is_sanctum(&u.uz)) { 358. if(priest->mpeaceful) { 359. verbalize("Infidel, you entered Moloch's Sanctum!"); 360. verbalize("Be gone!"); 361. priest->mpeaceful = 0; 362. set_malign(priest); 363. } else 364. verbalize("You desecrate this place by your presence!"); 365. } else verbalize("Pilgrim, you enter a%s place!", 366. !shrined ? " desecrated" : 367. " sacred"); 368. if(!sanctum) { 369. /* !tended -> !shrined */ 370. if(!shrined || !p_coaligned(priest) || 371. u.ualign.record < -5) 372. You("have a%s forbidding feeling...", 373. (!shrined) ? "" : " strange"); 374. else You("experience a strange sense of peace."); 375. } 376. } else { 377. switch(rn2(3)) { 378. case 0: You("have an eerie feeling..."); break; 379. case 1: You("feel like you are being watched."); break; 380. default: pline("A shiver runs down your spine."); break; 381. } 382. if(!rn2(5)) { 383. struct monst *mtmp; 384. 385. if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy))) return; 386. pline("An enormous ghost appears next to you!"); 387. mtmp->mpeaceful = 0; 388. set_malign(mtmp); 389. if(flags.verbose) 390. You("are frightened to death, and unable to move."); 391. nomul(-3); 392. nomovemsg = "You regain your composure."; 393. } 394. } 395. } 396. } 397. 398. void 399. priest_talk(priest) 400. register struct monst *priest; 401. { 402. boolean coaligned = p_coaligned(priest); 403. boolean strayed = (u.ualign.record < 0); 404. 405. if(priest->mflee || (!priest->ispriest && coaligned && strayed)) { 406. pline("%s doesn't want anything to do with you!", 407. Monnam(priest)); 408. priest->mpeaceful = 0; 409. return; 410. } 411. 412. /* priests don't chat unless peaceful and in their own temple */ 413. if(!histemple_at(priest,priest->mx,priest->my) || 414. !priest->mpeaceful || !priest->mcanmove || priest->msleep) { 415. if(!priest->mcanmove || priest->msleep) { 416. pline("%s breaks out of %s reverie!", 417. humanoid(priest->data) 418. ? (priest->female ? "her" : "his") 419. : "its", 420. Monnam(priest)); 421. priest->mfrozen = priest->msleep = 0; 422. priest->mcanmove = 1; 423. } 424. priest->mpeaceful = 0; 425. switch(rn2(3)) { 426. case 0: 427. verbalize("Thou wouldst have words, eh? I'll give thee a word or two!"); 428. break; 429. case 1: 430. verbalize("Talk? Here is what I have to say!"); 431. break; 432. default: 433. verbalize("Pilgrim, I have lost mine desire to talk."); 434. break; 435. } 436. return; 437. } 438. 439. /* you desecrated the temple and now you want to chat? */ 440. if(priest->mpeaceful && *in_rooms(priest->mx, priest->my, TEMPLE) && 441. !has_shrine(priest)) { 442. verbalize("Begone! Thou desecratest this holy place with thy presence."); 443. priest->mpeaceful = 0; 444. return; 445. } 446. 447. if(!u.ugold) { 448. if(coaligned && !strayed) { 449. if (priest->mgold > 0L) { 450. /* Note: two bits is actually 25 cents. Hmm. */ 451. pline("%s gives you %s for an ale.", Monnam(priest), 452. (priest->mgold == 1L) ? "one bit" : "two bits"); 453. if (priest->mgold > 1L) 454. u.ugold = 2L; 455. else 456. u.ugold = 1L; 457. priest->mgold -= u.ugold; 458. flags.botl = 1; 459. } else 460. pline("%s preaches the virtues of poverty.", Monnam(priest)); 461. exercise(A_WIS, TRUE); 462. } else 463. pline("%s is not interested.", Monnam(priest)); 464. return; 465. } else { 466. long offer; 467. 468. pline("%s asks you for a contribution for the temple.", 469. Monnam(priest)); 470. if((offer = bribe(priest)) == 0) { 471. verbalize("Thou shalt regret thine action!"); 472. if(coaligned) u.ualign.record--; 473. } else if(offer < (u.ulevel * 200)) { 474. if(u.ugold > (offer * 2L)) verbalize("Cheapskate."); 475. else { 476. verbalize("I thank thee for thy contribution."); 477. /* give player some token */ 478. exercise(A_WIS, TRUE); 479. } 480. } else if(offer < (u.ulevel * 400)) { 481. verbalize("Thou art indeed a pious individual."); 482. if(u.ugold < (offer * 2L)) { 483. if(coaligned && u.ualign.record < -5) u.ualign.record++; 484. verbalize("I bestow upon thee a blessing."); 485. Clairvoyant += rn1(500,500); 486. } 487. } else if(offer < (u.ulevel * 600)) { 488. verbalize("Thy devotion has been rewarded."); 489. if (!(Protection & INTRINSIC)) { 490. Protection |= FROMOUTSIDE; 491. if (!u.ublessed) u.ublessed = rn1(3, 2); 492. } else u.ublessed++; 493. } else { 494. verbalize("Thy selfless generosity is deeply appreciated."); 495. if(u.ugold < (offer * 2L) && coaligned) { 496. if(strayed && (moves - u.ucleansed) > 5000L) { 497. u.ualign.record = 0; /* cleanse him */ 498. u.ucleansed = moves; 499. } else { 500. u.ualign.record += 2; 501. } 502. } 503. } 504. } 505. } 506. 507. struct monst * 508. mk_roamer(ptr, alignment, x, y, peaceful) 509. register struct permonst *ptr; 510. aligntyp alignment; 511. xchar x, y; 512. boolean peaceful; 513. { 514. register struct monst *roamer; 515. register boolean coaligned = (u.ualign.type == alignment); 516. 517. if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL]) 518. return((struct monst *)0); 519. 520. if (MON_AT(x, y)) rloc(m_at(x, y)); /* insurance */ 521. 522. if (!(roamer = makemon(ptr, x, y))) 523. return((struct monst *)0); 524. 525. EPRI(roamer)->shralign = alignment; 526. if (coaligned && !peaceful) 527. EPRI(roamer)->renegade = TRUE; 528. /* roamer->ispriest == FALSE naturally */ 529. roamer->isminion = TRUE; /* borrowing this bit */ 530. roamer->mtrapseen = ~0; /* traps are known */ 531. roamer->mpeaceful = peaceful; 532. roamer->msleep = 0; 533. set_malign(roamer); /* peaceful may have changed */ 534. 535. /* MORE TO COME */ 536. return(roamer); 537. } 538. 539. void 540. reset_hostility(roamer) 541. register struct monst *roamer; 542. { 543. if(!(roamer->isminion && (roamer->data == &mons[PM_ALIGNED_PRIEST] || 544. roamer->data == &mons[PM_ANGEL]))) 545. return; 546. 547. if(EPRI(roamer)->shralign != u.ualign.type) { 548. roamer->mpeaceful = roamer->mtame = 0; 549. set_malign(roamer); 550. } 551. newsym(roamer->mx, roamer->my); 552. } 553. 554. boolean 555. in_your_sanctuary(x, y) 556. xchar x, y; 557. { 558. register char roomno; 559. register struct monst *priest; 560. 561. if ((u.ualign.record < -5) || !(roomno = temple_occupied(u.urooms)) || 562. (roomno != *in_rooms(x, y, TEMPLE)) || 563. !(priest = findpriest(roomno))) 564. return(FALSE); 565. return(has_shrine(priest) && p_coaligned(priest) && priest->mpeaceful); 566. } 567. 568. void 569. ghod_hitsu(priest) /* when attacking "priest" in his temple */ 570. struct monst *priest; 571. { 572. int x, y, ax, ay, roomno = (int)temple_occupied(u.urooms); 573. struct mkroom *troom; 574. 575. if (!roomno || !has_shrine(priest)) 576. return; 577. 578. ax = x = EPRI(priest)->shrpos.x; 579. ay = y = EPRI(priest)->shrpos.y; 580. troom = &rooms[roomno - ROOMOFFSET]; 581. 582. if((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y)) { 583. if(IS_DOOR(levl[u.ux][u.uy].typ)) { 584. 585. if(u.ux == troom->lx - 1) { 586. x = troom->hx; 587. y = u.uy; 588. } else if(u.ux == troom->hx + 1) { 589. x = troom->lx; 590. y = u.uy; 591. } else if(u.uy == troom->ly - 1) { 592. x = u.ux; 593. y = troom->hy; 594. } else if(u.uy == troom->hy + 1) { 595. x = u.ux; 596. y = troom->ly; 597. } 598. } else { 599. switch(rn2(4)) { 600. case 0: x = u.ux; y = troom->ly; break; 601. case 1: x = u.ux; y = troom->hy; break; 602. case 2: x = troom->lx; y = u.uy; break; 603. default: x = troom->hx; y = u.uy; break; 604. } 605. } 606. if(!linedup(u.ux, u.uy, x, y)) return; 607. } 608. 609. switch(rn2(3)) { 610. case 0: 611. pline("%s roars in anger: \"Thou shalt suffer!\"", 612. a_gname_at(ax, ay)); 613. break; 614. case 1: 615. pline("%s voice booms: \"How darest thou harm my servant!\"", 616. s_suffix(a_gname_at(ax, ay))); 617. break; 618. default: 619. pline("%s roars: \"Thou dost profane my shrine!\"", 620. a_gname_at(ax, ay)); 621. break; 622. } 623. 624. buzz(-10-(AD_ELEC-1), 6, x, y, sgn(tbx), sgn(tby)); /* bolt of lightning */ 625. exercise(A_WIS, FALSE); 626. } 627. 628. void 629. angry_priest() 630. { 631. register struct monst *priest; 632. 633. if(priest = findpriest(temple_occupied(u.urooms))) 634. wakeup(priest); 635. } 636. 637. #endif /* OVLB */ 638. 639. /*priest.c*/
|