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