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