abstract
| - Below is the full text to mon.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/mon.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)mon.c 1.3 87/07/14 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* mon.c - version 1.0.3 */ 4. 5. #include "hack.h" 6. #include "mfndpos.h" 7. extern struct obj *mkobj_at(); 8. extern char *hcolor(); 9. #ifdef KAA 10. extern boolean stoned; 11. extern char mlarge[]; 12. #endif 13. 14. int warnlevel; /* used by movemon and dochugw */ 15. long lastwarntime; 16. int lastwarnlev; 17. char *warnings[] = { "white", "pink", "red", "ruby", "purple", "black" }; 18. 19. movemon() 20. { 21. register struct monst *mtmp; 22. register int fr; 23. 24. warnlevel = 0; 25. 26. while(1) { 27. /* find a monster that we haven't treated yet */ 28. /* note that mtmp or mtmp->nmon might get killed 29. while mtmp moves, so we cannot just walk down the 30. chain (even new monsters might get created!) */ 31. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 32. if(mtmp->mlstmv < moves) goto next_mon; 33. /* treated all monsters */ 34. break; 35. 36. next_mon: 37. mtmp->mlstmv = moves; 38. 39. /* most monsters drown in pools */ 40. { boolean inpool, iseel; 41. 42. inpool = (levl[mtmp->mx][mtmp->my].typ == POOL); 43. iseel = (mtmp->data->mlet == ';'); 44. if(inpool && !iseel) { 45. if(cansee(mtmp->mx,mtmp->my)) 46. pline("%s drowns.", Monnam(mtmp)); 47. mondead(mtmp); 48. continue; 49. } 50. /* but eels have a difficult time outside */ 51. if(iseel && !inpool) { 52. if(mtmp->mhp > 1) mtmp->mhp--; 53. mtmp->mflee = 1; 54. mtmp->mfleetim += 2; 55. } 56. } 57. if(mtmp->mblinded && !--mtmp->mblinded) 58. mtmp->mcansee = 1; 59. if(mtmp->mfleetim && !--mtmp->mfleetim) 60. mtmp->mflee = 0; 61. /* unwatched mimics and piercers may hide again [MRS] */ 62. if(restrap(mtmp)) continue; 63. if(mtmp->mimic) continue; 64. if(mtmp->mspeed != MSLOW || !(moves%2)){ 65. /* continue if the monster died fighting */ 66. fr = -1; 67. if(Conflict && cansee(mtmp->mx,mtmp->my) 68. && (fr = fightm(mtmp)) == 2) 69. continue; 70. if(fr<0 && dochugw(mtmp)) 71. continue; 72. } 73. if(mtmp->mspeed == MFAST && dochugw(mtmp)) 74. continue; 75. } 76. 77. warnlevel -= u.ulevel; 78. if(warnlevel >= SIZE(warnings)) 79. warnlevel = SIZE(warnings)-1; 80. if(warnlevel >= 0) 81. if(warnlevel > lastwarnlev || moves > lastwarntime + 5){ 82. register char *rr; 83. switch(Warning & (LEFT_RING | RIGHT_RING)){ 84. case LEFT_RING: 85. rr = "Your left ring glows"; 86. break; 87. case RIGHT_RING: 88. rr = "Your right ring glows"; 89. break; 90. case LEFT_RING | RIGHT_RING: 91. rr = "Both your rings glow"; 92. break; 93. default: 94. rr = "Your fingertips glow"; 95. break; 96. } 97. pline("%s %s!", rr, Hallucination ? hcolor() : warnings[warnlevel]); 98. lastwarntime = moves; 99. lastwarnlev = warnlevel; 100. } 101. 102. dmonsfree(); /* remove all dead monsters */ 103. } 104. 105. justswld(mtmp,name) 106. register struct monst *mtmp; 107. char *name; 108. { 109. 110. mtmp->mx = u.ux; 111. mtmp->my = u.uy; 112. u.ustuck = mtmp; 113. pmon(mtmp); 114. kludge("%s swallows you!",name); 115. more(); 116. seeoff(1); 117. u.uswallow = 1; 118. u.uswldtim = 0; 119. swallowed(); 120. } 121. 122. youswld(mtmp,dam,die,name) 123. register struct monst *mtmp; 124. register dam,die; 125. char *name; 126. { 127. if(mtmp != u.ustuck) return; 128. kludge("%s digests you!",name); 129. u.uhp -= dam; 130. if(u.uswldtim++ >= die){ /* a3 */ 131. pline("It totally digests you!"); 132. u.uhp = -1; 133. } 134. if(u.uhp < 1) done_in_by(mtmp); 135. /* flags.botlx = 1; /* should we show status line ? */ 136. } 137. 138. #ifdef ROCKMOLE 139. meatgold(mtmp) register struct monst *mtmp; { 140. register struct gold *gold; 141. register int pile; 142. register struct obj *otmp; 143. /* Eats gold if it is there */ 144. while(gold = g_at(mtmp->mx, mtmp->my)){ 145. freegold(gold); 146. /* Left behind a pile? */ 147. pile = rnd(25); 148. if(pile < 3) 149. mksobj_at(ROCK, mtmp->mx, mtmp->my); 150. newsym(mtmp->mx, mtmp->my); 151. } 152. /* Eats armor if it is there */ 153. otmp = o_at(mtmp->mx,mtmp->my); 154. if((otmp) && (otmp->otyp >= PLATE_MAIL) && (otmp->otyp <= RING_MAIL)){ 155. freeobj(otmp); 156. /* Left behind a pile? */ 157. pile = rnd(25); 158. if(pile < 3) 159. mksobj_at(ROCK, mtmp->mx, mtmp->my); 160. newsym(mtmp->mx, mtmp->my); 161. } 162. } 163. #endif /* ROCKMOLE /**/ 164. 165. mpickgold(mtmp) register struct monst *mtmp; { 166. register struct gold *gold; 167. register struct obj *otmp; 168. while(gold = g_at(mtmp->mx, mtmp->my)){ 169. mtmp->mgold += gold->amount; 170. freegold(gold); 171. if(levl[mtmp->mx][mtmp->my].scrsym == '$') 172. newsym(mtmp->mx, mtmp->my); 173. } 174. } 175. 176. /* Now includes giants which pick up enormous rocks. KAA */ 177. mpickgems(mtmp) register struct monst *mtmp; { 178. register struct obj *otmp; 179. for(otmp = fobj; otmp; otmp = otmp->nobj) 180. if(otmp->olet == 181. #ifdef KAA 182. (mtmp->data->mlet=='9' ? ROCK_SYM : GEM_SYM)) 183. #else 184. GEM_SYM) 185. #endif 186. if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my) 187. if(mtmp->data->mlet != 'u' || objects[otmp->otyp].g_val != 0){ 188. freeobj(otmp); 189. mpickobj(mtmp, otmp); 190. #ifndef KAA 191. if(levl[mtmp->mx][mtmp->my].scrsym == GEM_SYM) 192. #endif 193. newsym(mtmp->mx, mtmp->my); /* %% */ 194. return; /* pick only one object */ 195. } 196. } 197. 198. /* return number of acceptable neighbour positions */ 199. mfndpos(mon,poss,info,flag) 200. register struct monst *mon; 201. coord poss[9]; 202. long info[9], flag; 203. { 204. register int x,y,nx,ny,cnt = 0,ntyp; 205. register struct monst *mtmp; 206. int nowtyp; 207. boolean pool; 208. 209. x = mon->mx; 210. y = mon->my; 211. nowtyp = levl[x][y].typ; 212. 213. pool = (mon->data->mlet == ';'); 214. nexttry: /* eels prefer the water, but if there is no water nearby, 215. they will crawl over land */ 216. if(mon->mconf) { 217. flag |= ALLOW_ALL; 218. flag &= ~NOTONL; 219. } 220. for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) 221. if(nx != x || ny != y) if(isok(nx,ny)) 222. #ifdef ROCKMOLE 223. if(!IS_ROCK(ntyp = levl[nx][ny].typ) || (flag & ALLOW_WALL)) 224. #else 225. if(!IS_ROCK(ntyp = levl[nx][ny].typ)) 226. #endif 227. if(!(nx != x && ny != y && (nowtyp == DOOR || ntyp == DOOR))) 228. if((ntyp == POOL) == pool) { 229. info[cnt] = 0; 230. if(nx == u.ux && ny == u.uy){ 231. if(!(flag & ALLOW_U)) continue; 232. info[cnt] = ALLOW_U; 233. } else if(mtmp = m_at(nx,ny)){ 234. if(!(flag & ALLOW_M)) continue; 235. info[cnt] = ALLOW_M; 236. if(mtmp->mtame){ 237. if(!(flag & ALLOW_TM)) continue; 238. info[cnt] |= ALLOW_TM; 239. } 240. } 241. if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) { 242. if(flag & NOGARLIC) continue; 243. info[cnt] |= NOGARLIC; 244. } 245. if(sobj_at(SCR_SCARE_MONSTER, nx, ny) || 246. (!mon->mpeaceful && sengr_at("Elbereth", nx, ny))) { 247. if(!(flag & ALLOW_SSM)) continue; 248. info[cnt] |= ALLOW_SSM; 249. } 250. if(sobj_at(ENORMOUS_ROCK, nx, ny)) { 251. if(!(flag & ALLOW_ROCK)) continue; 252. info[cnt] |= ALLOW_ROCK; 253. } 254. if(!Invis && online(nx,ny)){ 255. if(flag & NOTONL) continue; 256. info[cnt] |= NOTONL; 257. } 258. /* we cannot avoid traps of an unknown kind */ 259. { register struct trap *ttmp = t_at(nx, ny); 260. register int tt; 261. if(ttmp) { 262. tt = 1 << ttmp->ttyp; 263. /* below if added by GAN 02/06/87 to avoid 264. * traps out of range 265. */ 266. if(!(tt & ALLOW_TRAPS)) { 267. impossible("A monster looked at a very strange trap"); 268. continue; 269. } 270. if(mon->mtrapseen & tt){ 271. if(!(flag & tt)) continue; 272. info[cnt] |= tt; 273. } 274. } 275. } 276. poss[cnt].x = nx; 277. poss[cnt].y = ny; 278. cnt++; 279. } 280. if(!cnt && pool && nowtyp != POOL) { 281. pool = FALSE; 282. goto nexttry; 283. } 284. return(cnt); 285. } 286. 287. dist(x,y) int x,y; { 288. return((x-u.ux)*(x-u.ux) + (y-u.uy)*(y-u.uy)); 289. } 290. 291. poisoned(string, pname) 292. register char *string, *pname; 293. { 294. register i, plural; 295. 296. plural = (string[strlen(string) - 1] == 's')? 1 : 0; 297. if(Blind) { 298. if (plural) pline("They were poisoned."); 299. else pline("It was poisoned."); 300. } else { 301. if (plural) pline("The %s were poisoned!", string); 302. else pline("The %s was poisoned!", string); 303. } 304. 305. if(Poison_resistance) { 306. pline("The poison doesn't seem to affect you."); 307. return; 308. } 309. i = rn2(10); 310. if(i == 0) { 311. u.uhp = -1; 312. pline("I am afraid the poison was deadly ..."); 313. } else if(i <= 5) { 314. losestr(rn1(3,3)); 315. } else { 316. losehp(rn1(10,6), pname); 317. } 318. if(u.uhp < 1) { 319. killer = pname; 320. done("died"); 321. } 322. } 323. 324. mondead(mtmp) 325. register struct monst *mtmp; 326. { 327. relobj(mtmp,1); 328. unpmon(mtmp); 329. relmon(mtmp); 330. unstuck(mtmp); 331. #ifdef KOPS 332. if(mtmp->data->mlet == 'K') { 333. /* When a Kop dies, he probably comes back. */ 334. register int fate = rnd(3); 335. if(fate == 1) { 336. /* returns near the stairs */ 337. mkmon_at('K',xdnstair,ydnstair); 338. } else if(fate == 2) { 339. /* randomly */ 340. mkmon_at('K',0,0); 341. } 342. } 343. #endif 344. if(mtmp->isshk) shkdead(mtmp); 345. if(mtmp->isgd) gddead(); 346. #ifndef NOWORM 347. if(mtmp->wormno) wormdead(mtmp); 348. #endif 349. #ifdef HARD 350. if(mtmp->data->mlet == '1') wizdead(mtmp); 351. #endif 352. monfree(mtmp); 353. } 354. 355. /* called when monster is moved to larger structure */ 356. replmon(mtmp,mtmp2) 357. register struct monst *mtmp, *mtmp2; 358. { 359. relmon(mtmp); 360. monfree(mtmp); 361. mtmp2->nmon = fmon; 362. fmon = mtmp2; 363. if(u.ustuck == mtmp) u.ustuck = mtmp2; 364. if(mtmp2->isshk) replshk(mtmp,mtmp2); 365. if(mtmp2->isgd) replgd(mtmp,mtmp2); 366. } 367. 368. relmon(mon) 369. register struct monst *mon; 370. { 371. register struct monst *mtmp; 372. 373. if (fmon == 0) panic ("relmon: no fmon available."); 374. 375. if(mon == fmon) fmon = fmon->nmon; 376. else { 377. for(mtmp = fmon; mtmp->nmon != mon; mtmp = mtmp->nmon) ; 378. mtmp->nmon = mon->nmon; 379. } 380. } 381. 382. /* we do not free monsters immediately, in order to have their name 383. available shortly after their demise */ 384. struct monst *fdmon; /* chain of dead monsters, need not to be saved */ 385. 386. monfree(mtmp) register struct monst *mtmp; { 387. mtmp->nmon = fdmon; 388. fdmon = mtmp; 389. } 390. 391. dmonsfree(){ 392. register struct monst *mtmp; 393. while(mtmp = fdmon){ 394. fdmon = mtmp->nmon; 395. free((char *) mtmp); 396. } 397. } 398. 399. unstuck(mtmp) 400. register struct monst *mtmp; 401. { 402. if(u.ustuck == mtmp) { 403. if(u.uswallow){ 404. u.ux = mtmp->mx; 405. u.uy = mtmp->my; 406. u.uswallow = 0; 407. setsee(); 408. docrt(); 409. } 410. u.ustuck = 0; 411. } 412. } 413. 414. killed(mtmp) 415. register struct monst *mtmp; 416. { 417. xkilled(mtmp, 1); 418. } 419. 420. xkilled(mtmp, dest) 421. register struct monst *mtmp; 422. int dest; 423. /* Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse 424. either; dest=3, message but no corpse */ 425. { 426. #ifdef lint 427. #define NEW_SCORING 428. #endif 429. register int tmp,tmp2,nk,x,y; 430. register struct permonst *mdat = mtmp->data; 431. extern long newuexp(); 432. 433. if(mtmp->cham) mdat = PM_CHAMELEON; 434. if (dest & 1) { 435. if(Blind) pline("You destroy it!"); 436. else { 437. pline("You destroy %s!", 438. mtmp->mtame ? amonnam(mtmp, "poor") : monnam(mtmp)); 439. } 440. } 441. if(u.umconf) { 442. if(!Blind) 443. { 444. pline("Your hands stop glowing %s.", 445. Hallucination ? hcolor() : "blue"); 446. } 447. u.umconf = 0; 448. } 449. 450. /* count killed monsters */ 451. #define MAXMONNO 100 452. nk = 1; /* in case we cannot find it in mons */ 453. tmp = mdat - mons; /* index in mons array (if not 'd', '@', ...) */ 454. if(tmp >= 0 && tmp < CMNUM+2) { 455. extern char fut_geno[]; 456. u.nr_killed[tmp]++; 457. if((nk = u.nr_killed[tmp]) > MAXMONNO && 458. !index(fut_geno, mdat->mlet)) 459. charcat(fut_geno, mdat->mlet); 460. } 461. 462. /* punish bad behaviour */ 463. if(mdat->mlet == '@') { 464. HTelepat = 0; 465. u.uluck -= 2; 466. } 467. if(mtmp->mpeaceful || mtmp->mtame) u.uluck--; 468. if(mdat->mlet == 'u') u.uluck -= 5; 469. if((int)u.uluck < LUCKMIN) u.uluck = LUCKMIN; 470. 471. /* give experience points */ 472. tmp = 1 + mdat->mlevel * mdat->mlevel; 473. if(mdat->ac < 3) tmp += 2*(7 - mdat->ac); 474. #ifdef KAA 475. if(index("AcsSDXaeRTVWU&In:P9", mdat->mlet)) 476. #else 477. if(index("AcsSDXaeRTVWU&In:P", mdat->mlet)) 478. #endif 479. tmp += 2*mdat->mlevel; 480. if(index("DeV&P",mdat->mlet)) tmp += (7*mdat->mlevel); 481. if(mdat->mlevel > 6) tmp += 50; 482. if(mdat->mlet == ';') tmp += 1000; 483. 484. #ifdef NEW_SCORING 485. /* ------- recent addition: make nr of points decrease 486. when this is not the first of this kind */ 487. { int ul = u.ulevel; 488. int ml = mdat->mlevel; 489. 490. if(ul < 14) /* points are given based on present and future level */ 491. for(tmp2 = 0; !tmp2 || ul + tmp2 <= ml; tmp2++) 492. if(u.uexp + 1 + (tmp + ((tmp2 <= 0) ? 0 : 4<<(tmp2-1)))/nk 493. >= 10*pow((unsigned)(ul-1))) 494. if(++ul == 14) break; 495. 496. tmp2 = ml - ul -1; 497. tmp = (tmp + ((tmp2 < 0) ? 0 : 4< 498. if(!tmp) tmp = 1; 499. } 500. /* note: ul is not necessarily the future value of u.ulevel */ 501. /* ------- end of recent valuation change ------- */ 502. #endif /* NEW_SCORING /**/ 503. 504. more_experienced(tmp,0); 505. flags.botl = 1; 506. while(u.ulevel < 14 && u.uexp >= newuexp()){ 507. pline("Welcome to experience level %u.", ++u.ulevel); 508. tmp = rnd(10); 509. if(tmp < 3) tmp = rnd(10); 510. u.uhpmax += tmp; 511. u.uhp += tmp; 512. #ifdef SPELLS 513. tmp = rnd(u.ulevel/2+1) + 1; /* M. Stephenson */ 514. u.uenmax += tmp; 515. u.uen += tmp; 516. #endif 517. flags.botl = 1; 518. } 519. 520. /* dispose of monster and make cadaver */ 521. x = mtmp->mx; y = mtmp->my; 522. mondead(mtmp); 523. tmp = mdat->mlet; 524. if(tmp == 'm') { /* he killed a minotaur, give him a wand of digging */ 525. /* note: the dead minotaur will be on top of it! */ 526. mksobj_at(WAN_DIGGING, x, y); 527. /* if(cansee(x,y)) atl(x,y,fobj->olet); */ 528. stackobj(fobj); 529. } else 530. #ifndef NOWORM 531. if(tmp == 'w') { 532. mksobj_at(WORM_TOOTH, x, y); 533. stackobj(fobj); 534. } else 535. #endif 536. #ifdef KAA 537. if(tmp == '&') (void) mkobj_at(0, x, y); 538. else 539. if(stoned == FALSE && (!letter(tmp) || (!index("9&1", tmp) && !rn2(3)))) tmp = 0; 540. if(dest & 2) { 541. newsym(x,y); 542. return; 543. } 544. #else 545. if(!letter(tmp) || (!index("mw", tmp) && !rn2(3))) tmp = 0; 546. #endif 547. 548. if(ACCESSIBLE(levl[x][y].typ)) /* might be mimic in wall or dead eel*/ 549. if(x != u.ux || y != u.uy) { /* might be here after swallowed */ 550. #ifdef KAA 551. if(stoned) { 552. register char typetmp; 553. if(index(mlarge, tmp)) typetmp = ENORMOUS_ROCK; 554. else typetmp = ROCK; 555. mksobj_at(typetmp, x, y); 556. if(cansee(x,y)) 557. atl(x,y,Hallucination ? rndobjsym() : 558. objects[typetmp].oc_olet); 559. } else if(index("NTVm&w",mdat->mlet) || rn2(5)) { 560. #else 561. if(index("NTVm&w",mdat->mlet) || rn2(5)) { 562. #endif 563. register struct obj *obj2 = mkobj_at(tmp,x,y); 564. if(cansee(x,y)) 565. atl(x, y, Hallucination ? rndobjsym() : obj2->olet); 566. stackobj(obj2); 567. } 568. } 569. } 570. 571. kludge(str,arg) 572. register char *str,*arg; 573. { 574. if(Blind) { 575. if(*str == '%') pline(str,"It"); 576. else pline(str,"it"); 577. } else pline(str,arg); 578. } 579. 580. rescham() /* force all chameleons to become normal */ 581. { 582. register struct monst *mtmp; 583. 584. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 585. if(mtmp->cham) { 586. mtmp->cham = 0; 587. (void) newcham(mtmp, PM_CHAMELEON); 588. } 589. } 590. 591. #ifdef DGKMOD 592. /* Let the chameleons change again -dgk */ 593. restartcham() 594. { 595. register struct monst *mtmp; 596. 597. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) 598. if (mtmp->data->mlet == ':') 599. mtmp->cham = 1; 600. } 601. #endif 602. 603. newcham(mtmp,mdat) /* make a chameleon look like a new monster */ 604. /* returns 1 if the monster actually changed */ 605. register struct monst *mtmp; 606. register struct permonst *mdat; 607. { 608. register mhp, hpn, hpd; 609. 610. if(mdat == mtmp->data) return(0); /* still the same monster */ 611. #ifndef NOWORM 612. if(mtmp->wormno) wormdead(mtmp); /* throw tail away */ 613. #endif 614. hpn = mtmp->mhp; 615. hpd = (mtmp->data->mlevel)*8; if(!hpd) hpd = 4; 616. mhp = (mdat->mlevel)*8; if(!mhp) mhp = 4; 617. 618. /* new hp: same fraction of max as before */ 619. mtmp->mhp = (hpn*mhp)/hpd; 620. if (mhp > hpd && mtmp->mhp < hpn) mtmp->mhp = 127; 621. /* Not totally foolproof. A 2HD monster with 80 HP that changes into a 6HD 622. monster that really should have 240 and actually should have 127, the 623. maximum possible, will wind up having 113. */ 624. if (!mtmp->mhp) mtmp->mhp = 1; 625. /* Unlikely but not impossible; a 1HD creature with 1HP that changes into a 626. 0HD creature will require this statement */ 627. mtmp->data = mdat; 628. /* and the same for maximum hit points */ 629. hpn = mtmp->mhpmax; 630. mtmp->mhpmax = (hpn*mhp)/hpd; 631. if (mhp > hpd && mtmp->mhpmax < hpn) mtmp->mhp = 127; 632. if (!mtmp->mhp) mtmp->mhp = 1; 633. 634. mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0; 635. /* only snakes and scorpions can hide under things -dgk */ 636. /* also generated by GAN */ 637. mtmp->mhide = (mdat->mlet == 'S' || mdat->mlet == 's') ? 1 : 0; 638. if (!mtmp->mhide) mtmp->mundetected = 0; 639. #ifndef NOWORM 640. if(mdat->mlet == 'w' && getwn(mtmp)) initworm(mtmp); 641. /* perhaps we should clear mtmp->mtame here? */ 642. #endif 643. unpmon(mtmp); /* necessary for 'I' and to force pmon */ 644. pmon(mtmp); 645. return(1); 646. } 647. 648. mnexto(mtmp) /* Make monster mtmp next to you (if possible) */ 649. struct monst *mtmp; 650. { 651. extern coord enexto(); 652. coord mm; 653. mm = enexto(u.ux, u.uy); 654. mtmp->mx = mm.x; 655. mtmp->my = mm.y; 656. pmon(mtmp); 657. } 658. 659. ishuman(mtmp) register struct monst *mtmp; { 660. return(mtmp->data->mlet == '@'); 661. } 662. 663. setmangry(mtmp) register struct monst *mtmp; { 664. if(!mtmp->mpeaceful) return; 665. if(mtmp->mtame) return; 666. mtmp->mpeaceful = 0; 667. if(ishuman(mtmp)) pline("%s gets angry!", Monnam(mtmp)); 668. } 669. 670. /* not one hundred procent correct: now a snake may hide under an 671. invisible object */ 672. canseemon(mtmp) 673. register struct monst *mtmp; 674. { 675. return((!mtmp->minvis || See_invisible) 676. && (!mtmp->mhide || !o_at(mtmp->mx,mtmp->my)) 677. && cansee(mtmp->mx, mtmp->my)); 678. } 679. 680. disturb(mtmp) /* awaken monsters while in the same room. 681. * return a 1 if they have been woken. 682. */ 683. register struct monst *mtmp; 684. { 685. /* wake up, or get out of here. */ 686. /* ettins are hard to surprise */ 687. /* Nymphs and Leprechauns do not easily wake up */ 688. if(cansee(mtmp->mx,mtmp->my) && 689. (!Stealth || (mtmp->data->mlet == 'e' && rn2(10))) && 690. (!index("NL",mtmp->data->mlet) || !rn2(50)) && 691. (Aggravate_monster || index("d1", mtmp->data->mlet) 692. || (!rn2(7) && !mtmp->mimic))) { 693. mtmp->msleep = 0; 694. return(1); 695. } 696. if(Hallucination) pmon(mtmp); 697. return(0); 698. } 699. 700. #ifdef HARD 701. restrap(mtmp) /* unwatched mimics and piercers may hide again, 702. * if so, a 1 is returned. 703. */ 704. register struct monst *mtmp; 705. { 706. if(mtmp->data->mlet == 'M' && !mtmp->mimic && !mtmp->cham 707. && !mtmp->mcan && !cansee(mtmp->mx, mtmp->my) 708. && !rn2(3)) { 709. mtmp->mimic = 1; 710. mtmp->mappearance = (levl[mtmp->mx][mtmp->my].typ == DOOR) ? DOOR_SYM : '$'; 711. return(1); 712. } 713. 714. if(mtmp->data->mlet == 'p' && !mtmp->cham 715. && !mtmp->mcan && !cansee(mtmp->mx, mtmp->my) 716. && !rn2(3)) { 717. 718. if(levl[mtmp->mx][mtmp->my].typ == ROOM) { 719. 720. maketrap(mtmp->mx, mtmp->my, PIERC); 721. mondead(mtmp); 722. return(1); 723. } 724. } 725. return(0); 726. } 727. #endif
|