abstract
| - 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 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 Harlow distribution gives tt = 1L <<" ttmp->typ;" but the double quotes in that statement are an obvious corruption; it does not compile when written thus, the UUNet distribution does not have the quotes, and neither does the corresponding line in 1.3d. 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< 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
|