abstract
| - Below is the full text to mon.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/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 3.1 93/01/19 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* If you're using precompiled headers, you don't want this either */ 6. #ifdef MICROPORT_BUG 7. #define MKROOM_H 8. #endif 9. 10. #include "hack.h" 11. #include "mfndpos.h" 12. #include "edog.h" 13. #include 14. 15. STATIC_DCL boolean FDECL(restrap,(struct monst *)); 16. STATIC_DCL void NDECL(dmonsfree); 17. 18. #ifdef OVL1 19. #define warnDelay 10 20. long lastwarntime; 21. int lastwarnlev; 22. const char *warnings[] = { 23. "white", "pink", "red", "ruby", "purple", "black" }; 24. 25. static void NDECL(warn_effects); 26. 27. #endif /* OVL1 */ 28. 29. #ifdef OVLB 30. static struct obj *FDECL(make_corpse,(struct monst *)); 31. static void FDECL(m_detach,(struct monst *)); 32. 33. struct monst *fdmon; /* chain of dead monsters, need not be saved */ 34. /* otherwise used only in priest.c */ 35. 36. /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't 37. * leave corpses. Monsters which leave "special" corpses should have 38. * G_NOCORPSE set in order to prevent wishing for one, finding tins of one, 39. * etc.... 40. */ 41. static struct obj * 42. make_corpse(mtmp) 43. register struct monst *mtmp; 44. { 45. register struct permonst *mdat = mtmp->data; 46. int num; 47. struct obj *obj = (struct obj *)0; 48. int x = mtmp->mx, y = mtmp->my; 49. int mndx = monsndx(mdat); 50. 51. switch(mndx) { 52. case PM_GRAY_DRAGON: 53. case PM_RED_DRAGON: 54. case PM_ORANGE_DRAGON: 55. case PM_WHITE_DRAGON: 56. case PM_BLACK_DRAGON: 57. case PM_BLUE_DRAGON: 58. case PM_GREEN_DRAGON: 59. case PM_YELLOW_DRAGON: 60. /* Make dragon scales. This assumes that the order of the */ 61. /* dragons is the same as the order of the scales. */ 62. if (!rn2(3)) { 63. obj = mksobj_at(GRAY_DRAGON_SCALES + 64. monsndx(mdat)-PM_GRAY_DRAGON, x, y, FALSE); 65. obj->spe = 0; 66. obj->cursed = obj->blessed = FALSE; 67. } 68. goto default_1; 69. 70. case PM_WHITE_UNICORN: 71. case PM_GRAY_UNICORN: 72. case PM_BLACK_UNICORN: 73. (void) mksobj_at(UNICORN_HORN, x, y, TRUE); 74. goto default_1; 75. case PM_LONG_WORM: 76. (void) mksobj_at(WORM_TOOTH, x, y, TRUE); 77. goto default_1; 78. case PM_KOBOLD_MUMMY: 79. case PM_GNOME_MUMMY: 80. case PM_ORC_MUMMY: 81. case PM_ELF_MUMMY: 82. case PM_HUMAN_MUMMY: 83. case PM_GIANT_MUMMY: 84. case PM_ETTIN_MUMMY: 85. (void) mksobj_at(MUMMY_WRAPPING, x, y, TRUE); /* and fall through */ 86. case PM_KOBOLD_ZOMBIE: 87. case PM_GNOME_ZOMBIE: 88. case PM_ORC_ZOMBIE: 89. case PM_ELF_ZOMBIE: 90. case PM_HUMAN_ZOMBIE: 91. case PM_GIANT_ZOMBIE: 92. case PM_ETTIN_ZOMBIE: 93. switch (mndx) { 94. case PM_KOBOLD_ZOMBIE: 95. case PM_KOBOLD_MUMMY: 96. num = PM_KOBOLD; break; 97. case PM_GNOME_MUMMY: 98. case PM_GNOME_ZOMBIE: 99. num = PM_GNOME; break; 100. case PM_ORC_MUMMY: 101. case PM_ORC_ZOMBIE: 102. num = PM_ORC; break; 103. case PM_ELF_MUMMY: 104. case PM_ELF_ZOMBIE: 105. num = PM_ELF; break; 106. case PM_HUMAN_MUMMY: 107. case PM_HUMAN_ZOMBIE: 108. num = PM_HUMAN; break; 109. case PM_GIANT_MUMMY: 110. case PM_GIANT_ZOMBIE: 111. num = PM_GIANT; break; 112. case PM_ETTIN_MUMMY: 113. case PM_ETTIN_ZOMBIE: 114. #ifdef GCC_WARN 115. default: 116. #endif 117. num = PM_ETTIN; break; 118. } 119. obj = mkcorpstat(CORPSE, &mons[num], x, y, TRUE); 120. obj->age -= 100; /* this is an *OLD* corpse */ 121. break; 122. case PM_IRON_GOLEM: 123. num = d(2,6); 124. while (num--) 125. obj = mksobj_at(IRON_CHAIN, x, y, TRUE); 126. mtmp->mnamelth = 0; 127. break; 128. case PM_CLAY_GOLEM: 129. obj = mksobj_at(ROCK, x, y, FALSE); 130. obj->quan = (long)(rn2(20) + 50); 131. obj->owt = weight(obj); 132. mtmp->mnamelth = 0; 133. break; 134. case PM_STONE_GOLEM: 135. obj = mkcorpstat(STATUE, mdat, x, y, FALSE); 136. break; 137. case PM_WOOD_GOLEM: 138. num = d(2,4); 139. while(num--) { 140. obj = mksobj_at(QUARTERSTAFF, x, y, TRUE); 141. if (obj && obj->oartifact) { /* don't allow this */ 142. artifact_exists(obj, ONAME(obj), FALSE); 143. Strcpy(ONAME(obj), ""); obj->onamelth = 0; 144. } 145. } 146. mtmp->mnamelth = 0; 147. break; 148. case PM_LEATHER_GOLEM: 149. num = d(2,4); 150. while(num--) 151. obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE); 152. mtmp->mnamelth = 0; 153. break; 154. default_1: 155. default: 156. if (mdat->geno & G_NOCORPSE) 157. return (struct obj *)0; 158. else obj = mkcorpstat(CORPSE, mdat, x, y, TRUE); 159. break; 160. } 161. /* All special cases should precede the G_NOCORPSE check */ 162. 163. /* Note: oname() cannot be used generically for non-inventory objects 164. * unless you fix the link from the previous object in the chains. 165. * (Here we know it's the first one, so there was no link.) 166. */ 167. if (mtmp->mnamelth) { 168. obj = oname(obj, NAME(mtmp), 0); 169. fobj = obj; 170. level.objects[x][y] = obj; 171. } 172. stackobj(fobj); 173. newsym(x, y); 174. return obj; 175. } 176. 177. #endif /* OVLB */ 178. #ifdef OVL1 179. 180. static void 181. warn_effects() 182. { 183. if (warnlevel == 100) { 184. if(!Blind && 185. (warnlevel > lastwarnlev || moves > lastwarntime + warnDelay)) { 186. Your("%s %s!", aobjnam(uwep, "glow"), 187. Hallucination ? hcolor() : light_blue); 188. lastwarnlev = warnlevel; 189. lastwarntime = moves; 190. } 191. warnlevel = 0; 192. return; 193. } 194. 195. if(warnlevel >= SIZE(warnings)) 196. warnlevel = SIZE(warnings)-1; 197. if(!Blind && warnlevel >= 0) 198. if(warnlevel > lastwarnlev || moves > lastwarntime + warnDelay) { 199. register const char *rr; 200. 201. lastwarntime = moves; 202. lastwarnlev = warnlevel; 203. switch((int) (Warning & (LEFT_RING | RIGHT_RING))) { 204. case LEFT_RING: 205. rr = Hallucination ? "left mood ring glows" : "left ring glows"; 206. break; 207. case RIGHT_RING: 208. rr = Hallucination ? "right mood ring glows" 209. : "right ring glows"; 210. break; 211. case LEFT_RING | RIGHT_RING: 212. rr = Hallucination ? "mood rings glow" : "rings both glow"; 213. break; 214. default: 215. if (Hallucination) 216. Your("spider-sense is tingling...."); 217. else 218. You("feel apprehensive as you sense a %s flash.", 219. warnings[warnlevel]); 220. return; 221. } 222. Your("%s %s!", rr, Hallucination ? hcolor() : warnings[warnlevel]); 223. } 224. } 225. 226. /* check mtmp and water for compatibility, 0 (survived), 1 (drowned) */ 227. int 228. minwater(mtmp) 229. register struct monst *mtmp; 230. { 231. boolean inpool, infountain; 232. 233. inpool = is_pool(mtmp->mx,mtmp->my); 234. infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ); 235. 236. /* Gremlin multiplying won't go on forever since the hit points 237. * keep going down, and when it gets to 1 hit point the clone 238. * function will fail. 239. */ 240. if(mtmp->data->mlet == S_GREMLIN && (inpool || infountain) && rn2(3)) { 241. struct monst *mtmp2 = clone_mon(mtmp); 242. 243. if (mtmp2) { 244. mtmp2->mhpmax = (mtmp->mhpmax /= 2); 245. if(cansee(mtmp->mx,mtmp->my)) 246. pline("%s multiplies.", Monnam(mtmp)); 247. dryup(mtmp->mx,mtmp->my); 248. } 249. return (0); 250. } 251. if (inpool) { 252. /* most monsters drown in pools */ 253. if (!is_flyer(mtmp->data) && !is_clinger(mtmp->data) 254. && !is_swimmer(mtmp->data) && !magic_breathing(mtmp->data)) { 255. if (cansee(mtmp->mx,mtmp->my)) 256. pline("%s drowns.", Monnam(mtmp)); 257. mondead(mtmp); 258. return (1); 259. } 260. } else { 261. /* but eels have a difficult time outside */ 262. if (mtmp->data->mlet == S_EEL) { 263. if(mtmp->mhp > 1) mtmp->mhp--; 264. mtmp->mflee = 1; 265. mtmp->mfleetim += 2; 266. } 267. } 268. return (0); 269. } 270. 271. void 272. movemon() 273. { 274. register struct monst *mtmp; 275. register boolean tametype = TRUE; 276. 277. warnlevel = 0; 278. 279. while(1) { 280. /* Find a monster that we have not treated yet. 281. * Note that mtmp or mtmp->nmon might get killed 282. * while mtmp moves, so we cannot just walk down the 283. * chain (even new monsters might get created!) 284. * 285. * Do tame monsters first. Necessary so that when the tame 286. * monster attacks something, the something gets a chance to 287. * attack the tame monster back (which it's permitted to do 288. * only if it hasn't made its move yet). 289. */ 290. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 291. if(mtmp->mlstmv < monstermoves && 292. ((mtmp->mtame>0) == tametype)) goto next_mon; 293. if(tametype) { 294. /* checked all tame monsters, now do other ones */ 295. tametype = FALSE; 296. continue; 297. } 298. /* treated all monsters */ 299. break; 300. 301. next_mon: 302. mtmp->mlstmv = monstermoves; 303. 304. if(mtmp->mhp <= 0) { 305. impossible("Monster with zero hp?"); 306. mtmp->mhp = mtmp->mhpmax = 1; /* repair */ 307. } 308. if (minwater(mtmp)) continue; 309. 310. if(mtmp->mblinded && !--mtmp->mblinded) 311. mtmp->mcansee = 1; 312. if(mtmp->mfrozen && !--mtmp->mfrozen) 313. mtmp->mcanmove = 1; 314. if(mtmp->mfleetim && !--mtmp->mfleetim) 315. mtmp->mflee = 0; 316. if (is_hider(mtmp->data)) { 317. /* unwatched mimics and piercers may hide again [MRS] */ 318. if(restrap(mtmp)) continue; 319. if(mtmp->m_ap_type == M_AP_FURNITURE || 320. mtmp->m_ap_type == M_AP_OBJECT) 321. continue; 322. if(mtmp->mundetected) continue; 323. } 324. if(mtmp->mspeed != MSLOW || !(moves%2)) { 325. /* continue if the monster died fighting */ 326. if (Conflict && !mtmp->iswiz && mtmp->mcansee) { 327. /* Note: 328. * Conflict does not take effect in the first round. 329. * Therefore, A monster when stepping into the area will 330. * get to swing at you. 331. * 332. * The call to fightm() must be _last_. The monster might 333. * have died if it returns 1. 334. */ 335. if (couldsee(mtmp->mx,mtmp->my) && 336. (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) && 337. fightm(mtmp)) 338. continue; /* mon might have died */ 339. } 340. if(dochugw(mtmp)) 341. /* otherwise just move the monster */ 342. continue; 343. } 344. if(mtmp->mspeed == MFAST && dochugw(mtmp)) 345. continue; 346. } 347. if(warnlevel > 0) 348. warn_effects(); 349. 350. dmonsfree(); /* remove all dead monsters */ 351. } 352. 353. #endif /* OVL1 */ 354. #ifdef OVLB 355. 356. void 357. meatgold(mtmp) 358. register struct monst *mtmp; 359. { 360. register struct obj *otmp; 361. 362. /* If a pet, eating is handled separately, in dog.c */ 363. if (mtmp->mtame) return; 364. 365. /* Eats topmost metal object if it is there */ 366. for (otmp = level.objects[mtmp->mx][mtmp->my]; 367. otmp; otmp = otmp->nexthere) 368. if (is_metallic(otmp) && touch_artifact(otmp,mtmp)) { 369. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 370. pline("%s eats %s!", Monnam(mtmp), 371. distant_name(otmp,doname)); 372. else if (flags.soundok && flags.verbose) 373. You("hear a crunching sound."); 374. mtmp->meating = otmp->owt/2 + 1; 375. /* Heal up to the object's weight in hp */ 376. if (mtmp->mhp < mtmp->mhpmax) { 377. mtmp->mhp += objects[otmp->otyp].oc_weight; 378. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; 379. } 380. if(otmp == uball) { 381. unpunish(); 382. delobj(otmp); 383. } else if(otmp == uchain) 384. unpunish(); /* frees uchain */ 385. else 386. delobj(otmp); 387. /* Left behind a pile? */ 388. if(rnd(25) < 3) (void) mksobj_at(ROCK, mtmp->mx, mtmp->my, TRUE); 389. newsym(mtmp->mx, mtmp->my); 390. break; 391. } 392. } 393. 394. void 395. meatobj(mtmp) /* for gelatinous cubes */ 396. register struct monst *mtmp; 397. { 398. register struct obj *otmp, *otmp2; 399. 400. /* If a pet, eating is handled separately, in dog.c */ 401. if (mtmp->mtame) return; 402. 403. /* Eats organic objects, including cloth and wood, if there */ 404. /* Engulfs others, except huge rocks and metal attached to player */ 405. for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) { 406. otmp2 = otmp->nexthere; 407. if(is_organic(otmp) && touch_artifact(otmp,mtmp)) { 408. if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE 409. && !resists_ston(mtmp->data)) 410. continue; 411. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 412. pline("%s eats %s!", Monnam(mtmp), 413. distant_name(otmp, doname)); 414. else if (flags.soundok && flags.verbose) 415. You("hear a slurping sound."); 416. /* Heal up to the object's weight in hp */ 417. if (mtmp->mhp < mtmp->mhpmax) { 418. mtmp->mhp += objects[otmp->otyp].oc_weight; 419. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; 420. } 421. delobj(otmp); /* munch */ 422. } else if (otmp->oclass != ROCK_CLASS && 423. otmp != uball && otmp != uchain) { 424. if (cansee(mtmp->mx, mtmp->my) && flags.verbose) 425. pline("%s engulfs %s.", Monnam(mtmp), 426. distant_name(otmp,doname)); 427. freeobj(otmp); 428. mpickobj(mtmp, otmp); /* slurp */ 429. } 430. /* Engulf & devour is instant, so don't set meating */ 431. newsym(mtmp->mx, mtmp->my); 432. } 433. } 434. 435. void 436. mpickgold(mtmp) 437. register struct monst *mtmp; 438. { 439. register struct obj *gold; 440. 441. if ((gold = g_at(mtmp->mx, mtmp->my)) != 0) { 442. mtmp->mgold += gold->quan; 443. delobj(gold); 444. if (cansee(mtmp->mx, mtmp->my) ) { 445. if (flags.verbose && !mtmp->isgd) 446. pline("%s picks up some gold.", Monnam(mtmp)); 447. newsym(mtmp->mx, mtmp->my); 448. } 449. } 450. } 451. 452. /* Now includes giants which pick up enormous rocks. KAA */ 453. void 454. mpickgems(mtmp) 455. register struct monst *mtmp; 456. { 457. register struct obj *otmp; 458. 459. for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp=otmp->nexthere) 460. if(throws_rocks(mtmp->data) ? otmp->otyp == BOULDER : 461. (otmp->oclass == GEM_CLASS && 462. objects[otmp->otyp].oc_material != MINERAL)) 463. if (touch_artifact(otmp,mtmp)) 464. if(mtmp->data->mlet != S_UNICORN 465. || objects[otmp->otyp].oc_material == GEMSTONE){ 466. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 467. pline("%s picks up %s.", Monnam(mtmp), 468. distant_name(otmp, doname)); 469. freeobj(otmp); 470. mpickobj(mtmp, otmp); 471. if (otmp->otyp == BOULDER) 472. unblock_point(otmp->ox,otmp->oy); /* vision */ 473. newsym(mtmp->mx, mtmp->my); 474. return; /* pick only one object */ 475. } 476. } 477. 478. #endif /* OVLB */ 479. #ifdef OVL2 480. 481. void 482. mpickstuff(mtmp, str) 483. register struct monst *mtmp; 484. register const char *str; 485. { 486. register struct obj *otmp; 487. 488. /* prevent shopkeepers from leaving the door of their shop */ 489. if(mtmp->isshk && inhishop(mtmp)) return; 490. 491. for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp=otmp->nexthere) 492. /* Nymphs take everything. Most monsters don't pick up corpses. */ 493. if ( 494. #ifdef MUSE 495. !str ? searches_for_item(mtmp,otmp) : 496. #endif 497. (index(str, otmp->oclass) 498. && (otmp->otyp != CORPSE || mtmp->data->mlet == S_NYMPH))) { 499. if (!touch_artifact(otmp,mtmp)) return; 500. if (!can_carry(mtmp,otmp)) return; 501. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 502. pline("%s picks up %s.", Monnam(mtmp), doname(otmp)); 503. freeobj(otmp); 504. mpickobj(mtmp, otmp); 505. #ifdef MUSE 506. m_dowear(mtmp, FALSE); 507. #endif 508. newsym(mtmp->mx, mtmp->my); 509. return; /* pick only one object */ 510. } 511. } 512. 513. #endif /* OVL2 */ 514. #ifdef OVL0 515. 516. int 517. curr_mon_load(mtmp) 518. register struct monst *mtmp; 519. { 520. register int curload = 0; 521. register struct obj *obj; 522. 523. for(obj = mtmp->minvent; obj; obj = obj->nobj) { 524. if(obj->otyp != BOULDER || !throws_rocks(mtmp->data)) 525. curload += obj->owt; 526. } 527. 528. return curload; 529. } 530. 531. int 532. max_mon_load(mtmp) 533. register struct monst *mtmp; 534. { 535. register long maxload; 536. 537. /* Base monster carrying capacity is equal to human maximum 538. * carrying capacity, or half human maximum if not strong. 539. * (for a polymorphed player, the value used would be the 540. * non-polymorphed carrying capacity instead of max/half max). 541. * This is then modified by the ratio between the monster weights 542. * and human weights. Corpseless monsters are given a capacity 543. * proportional to their size instead of weight. 544. */ 545. if (!mtmp->data->cwt) 546. maxload = (MAX_CARR_CAP * (long)mtmp->data->msize) / MZ_HUMAN; 547. else if (!strongmonst(mtmp->data) 548. || (strongmonst(mtmp->data) && (mtmp->data->cwt > WT_HUMAN))) 549. maxload = (MAX_CARR_CAP * (long)mtmp->data->cwt) / WT_HUMAN; 550. else maxload = MAX_CARR_CAP; /*strong monsters w/cwt <= WT_HUMAN*/ 551. 552. if (!strongmonst(mtmp->data)) maxload /= 2; 553. 554. if (maxload < 1) maxload = 1; 555. 556. return (int) maxload; 557. } 558. 559. /* for restricting monsters' object-pickup */ 560. boolean 561. can_carry(mtmp,otmp) 562. struct monst *mtmp; 563. struct obj *otmp; 564. { 565. register int newload = otmp->owt; 566. 567. if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE 568. && !resists_ston(mtmp->data)) 569. return(FALSE); 570. if (mtmp->isshk) return(TRUE); /* no limit */ 571. if (mtmp->mpeaceful && !mtmp->mtame) return(FALSE); 572. /* otherwise players might find themselves obligated to violate 573. * their alignment if the monster takes something they need 574. */ 575. 576. /* special--boulder throwers carry unlimited amounts of boulders */ 577. if (throws_rocks(mtmp->data) && otmp->otyp == BOULDER) 578. return(TRUE); 579. 580. /* nymphs deal in stolen merchandise, but not boulders or statues */ 581. if (mtmp->data->mlet == S_NYMPH) 582. return !(otmp->oclass == ROCK_CLASS); 583. 584. if(curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return(FALSE); 585. 586. return(TRUE); 587. } 588. 589. /* return number of acceptable neighbour positions */ 590. int 591. mfndpos(mon, poss, info, flag) 592. register struct monst *mon; 593. coord *poss; /* coord poss[9] */ 594. long *info; /* long info[9] */ 595. long flag; 596. { 597. register xchar x,y,nx,ny; 598. register int cnt = 0; 599. register uchar ntyp; 600. uchar nowtyp; 601. boolean wantpool,poolok,lavaok,nodiag; 602. int maxx, maxy; 603. 604. x = mon->mx; 605. y = mon->my; 606. nowtyp = levl[x][y].typ; 607. 608. nodiag = (mon->data == &mons[PM_GRID_BUG]); 609. wantpool = mon->data->mlet == S_EEL; 610. poolok = is_flyer(mon->data) || is_clinger(mon->data) || 611. (is_swimmer(mon->data) && !wantpool); 612. lavaok = is_flyer(mon->data) || is_clinger(mon->data) || 613. (mon->data == &mons[PM_FIRE_ELEMENTAL]); 614. nexttry: /* eels prefer the water, but if there is no water nearby, 615. they will crawl over land */ 616. if(mon->mconf) { 617. flag |= ALLOW_ALL; 618. flag &= ~NOTONL; 619. } 620. if(!mon->mcansee) 621. flag |= ALLOW_SSM; 622. maxx = min(x+1,COLNO-1); 623. maxy = min(y+1,ROWNO-1); 624. for(nx = max(1,x-1); nx <= maxx; nx++) 625. for(ny = max(0,y-1); ny <= maxy; ny++) { 626. if(nx == x && ny == y) continue; 627. if(IS_ROCK(ntyp = levl[nx][ny].typ) && !(flag & ALLOW_WALL) && 628. !((flag & ALLOW_DIG) && may_dig(nx,ny))) continue; 629. if(IS_DOOR(ntyp) && !amorphous(mon->data) && 630. ((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) || 631. (levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR)) 632. ) && !(flag & (ALLOW_WALL|ALLOW_DIG|BUSTDOOR))) continue; 633. if(nx != x && ny != y && (nodiag || 634. #ifdef REINCARNATION 635. ((IS_DOOR(nowtyp) && 636. ((levl[x][y].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))) || 637. (IS_DOOR(ntyp) && 638. ((levl[nx][ny].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz)))) 639. #else 640. ((IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN)) || 641. (IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN))) 642. #endif 643. )) 644. continue; 645. if((is_pool(nx,ny) == wantpool || poolok) && 646. (lavaok || !is_lava(nx,ny))) { 647. int dispx, dispy; 648. boolean monseeu = (!Invis || perceives(mon->data)); 649. boolean checkobj = OBJ_AT(nx,ny); 650. 651. /* Displacement also displaces the Elbereth/scare monster, 652. * as long as you are visible. 653. */ 654. if(Displaced && monseeu && (mon->mux==nx) && (mon->muy==ny)) { 655. dispx = u.ux; 656. dispy = u.uy; 657. } else { 658. dispx = nx; 659. dispy = ny; 660. } 661. 662. info[cnt] = 0; 663. if(((checkobj || Displaced) && 664. sobj_at(SCR_SCARE_MONSTER, dispx, dispy)) 665. #ifdef ELBERETH 666. || sengr_at("Elbereth", dispx, dispy) 667. #endif 668. ) { 669. if(!(flag & ALLOW_SSM)) continue; 670. info[cnt] |= ALLOW_SSM; 671. } 672. if((nx == u.ux && ny == u.uy) || 673. (nx == mon->mux && ny == mon->muy)) { 674. if (nx == u.ux && ny == u.uy) { 675. /* If it's right next to you, it found you, 676. * displaced or no. We must set mux and muy 677. * right now, so when we return we can tell 678. * that the ALLOW_U means to attack _you_ and 679. * not the image. 680. */ 681. mon->mux = u.ux; 682. mon->muy = u.uy; 683. } 684. if(!(flag & ALLOW_U)) continue; 685. info[cnt] |= ALLOW_U; 686. } else { 687. if(MON_AT(nx, ny)) { 688. if(!(flag & ALLOW_M)) continue; 689. info[cnt] |= ALLOW_M; 690. if((m_at(nx,ny))->mtame) { 691. if(!(flag & ALLOW_TM)) continue; 692. info[cnt] |= ALLOW_TM; 693. } 694. } 695. /* Note: ALLOW_SANCT only prevents movement, not */ 696. /* attack, into a temple. */ 697. if(level.flags.has_temple && 698. *in_rooms(nx, ny, TEMPLE) && 699. !*in_rooms(x, y, TEMPLE) && 700. in_your_sanctuary(nx, ny)){ 701. if(!(flag & ALLOW_SANCT)) continue; 702. info[cnt] |= ALLOW_SANCT; 703. } 704. } 705. if(checkobj && sobj_at(CLOVE_OF_GARLIC, nx, ny)) { 706. if(flag & NOGARLIC) continue; 707. info[cnt] |= NOGARLIC; 708. } 709. if(checkobj && sobj_at(BOULDER, nx, ny)) { 710. if(!(flag & ALLOW_ROCK)) continue; 711. info[cnt] |= ALLOW_ROCK; 712. } 713. if (monseeu && onlineu(nx,ny)) { 714. if(flag & NOTONL) continue; 715. info[cnt] |= NOTONL; 716. } 717. /* we cannot avoid traps of an unknown kind */ 718. { register struct trap *ttmp = t_at(nx, ny); 719. register long tt; 720. if(ttmp) { 721. if(ttmp->ttyp >= TRAPNUM || ttmp->ttyp == 0) { 722. impossible("A monster looked at a very strange trap of type %d.", ttmp->ttyp); 723. continue; 724. } 725. tt = 1L << ttmp->ttyp; 726. if(mon->mtrapseen & tt) { 727. 728. if(!(flag & tt)) continue; 729. info[cnt] |= tt; 730. } 731. } 732. } 733. poss[cnt].x = nx; 734. poss[cnt].y = ny; 735. cnt++; 736. } 737. } 738. if(!cnt && wantpool && !is_pool(x,y)) { 739. wantpool = FALSE; 740. goto nexttry; 741. } 742. return(cnt); 743. } 744. 745. #endif /* OVL0 */ 746. #ifdef OVL1 747. 748. boolean 749. monnear(mon, x, y) 750. register struct monst *mon; 751. register int x,y; 752. /* Is the square close enough for the monster to move or attack into? */ 753. { 754. register int distance = dist2(mon->mx, mon->my, x, y); 755. if (distance==2 && mon->data==&mons[PM_GRID_BUG]) return 0; 756. return (distance < 3); 757. } 758. 759. #endif /* OVL1 */ 760. #ifdef OVL2 761. 762. STATIC_OVL void 763. dmonsfree() 764. { 765. register struct monst *mtmp; 766. while ((mtmp = fdmon) != 0) { 767. fdmon = mtmp->nmon; 768. dealloc_monst(mtmp); 769. } 770. } 771. 772. #endif /* OVL2 */ 773. #ifdef OVLB 774. /* we do not free monsters immediately, in order to have their name 775. available shortly after their demise */ 776. void 777. monfree(mtmp) 778. register struct monst *mtmp; 779. { 780. mtmp->nmon = fdmon; 781. fdmon = mtmp; 782. } 783. 784. /* called when monster is moved to larger structure */ 785. void 786. replmon(mtmp, mtmp2) 787. register struct monst *mtmp, *mtmp2; 788. { 789. relmon(mtmp); 790. monfree(mtmp); 791. place_monster(mtmp2, mtmp2->mx, mtmp2->my); 792. if (mtmp2->wormno) /* update level.monsters[wseg->wx][wseg->wy] */ 793. place_wsegs(mtmp2); /* locations to mtmp2 not mtmp. */ 794. mtmp2->nmon = fmon; 795. fmon = mtmp2; 796. if (u.ustuck == mtmp) u.ustuck = mtmp2; 797. if (mtmp2->isshk) replshk(mtmp,mtmp2); 798. } 799. 800. /* release mon from display and monster list */ 801. void 802. relmon(mon) 803. register struct monst *mon; 804. { 805. register struct monst *mtmp; 806. 807. if (fmon == (struct monst *)0) panic ("relmon: no fmon available."); 808. 809. remove_monster(mon->mx, mon->my); 810. 811. if(mon == fmon) fmon = fmon->nmon; 812. else { 813. for(mtmp = fmon; mtmp && mtmp->nmon != mon; mtmp = mtmp->nmon) ; 814. if(mtmp) mtmp->nmon = mon->nmon; 815. else panic("relmon: mon not in list."); 816. } 817. } 818. 819. /* remove effects of mtmp from other data structures */ 820. static void 821. m_detach(mtmp) 822. register struct monst *mtmp; 823. { 824. #ifdef WALKIES 825. if(mtmp->mleashed) m_unleash(mtmp); 826. #endif 827. /* to prevent an infinite relobj-flooreffects-hmon-killed loop */ 828. mtmp->mtrapped = 0; 829. mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */ 830. relobj(mtmp, 0, FALSE); 831. relmon(mtmp); 832. newsym(mtmp->mx,mtmp->my); 833. unstuck(mtmp); 834. fill_pit(mtmp->mx, mtmp->my); 835. 836. if(mtmp->isshk) shkgone(mtmp); 837. if(mtmp->wormno) wormgone(mtmp); 838. } 839. 840. void 841. mondead(mtmp) 842. register struct monst *mtmp; 843. { 844. int tmp, nk; 845. 846. if(mtmp->isgd) { 847. /* if we're going to abort the death, it *must* be before 848. * the m_detach or there will be relmon problems later */ 849. if(!grddead(mtmp)) return; 850. } 851. 852. /* restore chameleon, lycanthropes to true form at death */ 853. if(mtmp->cham) mtmp->data = &mons[PM_CHAMELEON]; 854. if(mtmp->data == &mons[PM_WEREJACKAL]) 855. mtmp->data = &mons[PM_HUMAN_WEREJACKAL]; 856. if(mtmp->data == &mons[PM_WEREWOLF]) 857. mtmp->data = &mons[PM_HUMAN_WEREWOLF]; 858. if(mtmp->data == &mons[PM_WERERAT]) 859. mtmp->data = &mons[PM_HUMAN_WERERAT]; 860. 861. /* if MAXMONNO monsters of a given type have died, and it 862. * can be done, extinguish that monster. 863. * 864. * u.nr_killed does double duty as total number of dead monsters 865. * and as experience factor for the player killing more monsters. 866. * this means that a dragon dying by other means reduces the 867. * experience the player gets for killing a dragon directly; this 868. * is probably not too bad, since the player likely finagled the 869. * first dead dragon via ring of conflict or pets, and extinguishing 870. * based on only player kills probably opens more avenues of abuse 871. * for rings of conflict and such. 872. */ 873. tmp = monsndx(mtmp->data); 874. u.nr_killed[tmp]++; 875. nk = u.nr_killed[tmp]; 876. if(nk > (tmp == PM_NAZGUL ? 9 : tmp == PM_ERINYES ? 3 : MAXMONNO) && 877. !(mons[tmp].geno & (G_NOGEN | G_EXTINCT))) { 878. #ifdef DEBUG 879. pline("Automatically extinguished %s.", makeplural(mons[tmp].mname)); 880. #endif 881. mons[tmp].geno |= G_EXTINCT; 882. } 883. #ifdef MAIL 884. /* if the mail daemon dies, no more mail delivery. -3. */ 885. else if(tmp==PM_MAIL_DAEMON) mons[tmp].geno |= G_GENOD; 886. #endif 887. 888. #ifdef KOPS 889. if(mtmp->data->mlet == S_KOP && allow_kops) { 890. /* Dead Kops may come back. */ 891. switch(rnd(5)) { 892. case 1: /* returns near the stairs */ 893. (void) makemon(mtmp->data,xdnstair,ydnstair); 894. break; 895. case 2: /* randomly */ 896. (void) makemon(mtmp->data,0,0); 897. break; 898. default: 899. break; 900. } 901. } 902. #endif 903. if(mtmp->iswiz) wizdead(mtmp); 904. #ifdef MULDGN 905. if(mtmp->data->msound == MS_NEMESIS) nemdead(); 906. #endif 907. m_detach(mtmp); 908. monfree(mtmp); 909. } 910. 911. /* drop (perhaps) a cadaver and remove monster */ 912. void 913. mondied(mdef) 914. register struct monst *mdef; 915. { 916. mondead(mdef); 917. if(rn2(3) 918. #ifdef REINCARNATION 919. && !Is_rogue_level(&u.uz) 920. #endif 921. ) 922. (void) make_corpse(mdef); 923. } 924. 925. /* monster disappears, not dies */ 926. void 927. mongone(mdef) 928. register struct monst *mdef; 929. { 930. register struct obj *otmp, *otmp2; 931. 932. /* release monster's inventory */ 933. for (otmp = mdef->minvent; otmp; otmp = otmp2) { 934. otmp2 = otmp->nobj; 935. obfree(otmp, (struct obj *)0); 936. } 937. mdef->minvent = 0; 938. mdef->mgold = 0; 939. m_detach(mdef); 940. monfree(mdef); 941. } 942. 943. /* drop a statue or rock and remove monster */ 944. void 945. monstone(mdef) 946. register struct monst *mdef; 947. { 948. struct obj *otmp, *contents; 949. xchar x = mdef->mx, y = mdef->my; 950. 951. if((int)mdef->data->msize > MZ_TINY || 952. !rn2(2 + ((mdef->data->geno & G_FREQ) > 2))) { 953. otmp = mk_named_object(STATUE, mdef->data, x, y, 954. NAME(mdef), (int)mdef->mnamelth); 955. contents = otmp->cobj = mdef->minvent; 956. while(contents) { 957. contents->owornmask = 0L; 958. contents = contents->nobj; 959. } 960. mdef->minvent = (struct obj *)0; 961. if (mdef->mgold) { 962. struct obj *au; 963. au = mksobj(GOLD_PIECE, FALSE, FALSE); 964. au->quan = mdef->mgold; 965. au->owt = weight(au); 966. mdef->mgold = 0; 967. au->nobj = otmp->cobj; 968. otmp->cobj = au; 969. } 970. otmp->owt = weight(otmp); 971. } else 972. otmp = mksobj_at(ROCK, x, y, TRUE); 973. 974. mondead(mdef); 975. 976. stackobj(otmp); 977. if (cansee(x, y)) newsym(x,y); 978. } 979. 980. /* another monster has killed the monster mdef */ 981. void 982. monkilled(mdef, fltxt, how) 983. register struct monst *mdef; 984. const char *fltxt; 985. uchar how; 986. { 987. if (cansee(mdef->mx, mdef->my) && fltxt) 988. pline("%s is %s%s%s!", Monnam(mdef), 989. (is_demon(mdef->data) || is_undead(mdef->data)) ? 990. "destroyed" : "killed", 991. *fltxt ? " by the " : "", 992. fltxt 993. ); 994. else if(mdef->mtame) 995. You("have a sad feeling for a moment, then it passes."); 996. 997. /* no corpses if digested */ 998. if(how == AD_DGST) 999. mondead(mdef); 1000. else 1001. mondied(mdef); 1002. } 1003. 1004. void 1005. unstuck(mtmp) 1006. register struct monst *mtmp; 1007. { 1008. if(u.ustuck == mtmp) { 1009. if(u.uswallow){ 1010. u.ux = mtmp->mx; 1011. u.uy = mtmp->my; 1012. u.uswallow = 0; 1013. u.uswldtim = 0; 1014. if (Punished) placebc(); 1015. vision_full_recalc = 1; 1016. docrt(); 1017. } 1018. u.ustuck = 0; 1019. } 1020. } 1021. 1022. void 1023. killed(mtmp) 1024. register struct monst *mtmp; 1025. { 1026. xkilled(mtmp, 1); 1027. } 1028. 1029. /* the player has killed the monster mtmp */ 1030. void 1031. xkilled(mtmp, dest) 1032. register struct monst *mtmp; 1033. /* 1034. * Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse 1035. * either; dest=3, message but no corpse 1036. */ 1037. int dest; 1038. { 1039. register int tmp, x = mtmp->mx, y = mtmp->my; 1040. register struct permonst *mdat; 1041. register struct obj *otmp; 1042. register struct trap *t; 1043. boolean chance, redisp = FALSE; 1044. boolean wasinside = u.uswallow && (u.ustuck == mtmp); 1045. 1046. if (dest & 1) { 1047. if(!canseemon(mtmp) && !sensemon(mtmp)) You("destroy it!"); 1048. else { 1049. You("destroy %s!", 1050. mtmp->mtame ? x_monnam(mtmp, 0, "poor", 0) 1051. : mon_nam(mtmp)); 1052. } 1053. } 1054. 1055. if (mtmp->mtrapped && 1056. ((t = t_at(x, y)) && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) && 1057. sobj_at(BOULDER, x, y)) 1058. dest ^= 2; /* 1059. * Prevent corpses/treasure being created "on top" 1060. * of the boulder that is about to fall in. This is 1061. * out of order, but cannot be helped unless this 1062. * whole routine is rearranged. 1063. */ 1064. 1065. /* dispose of monster and make cadaver */ 1066. if(stoned) monstone(mtmp); 1067. else mondead(mtmp); 1068. 1069. mdat = mtmp->data; /* note: mondead can change mtmp->data */ 1070. 1071. if (stoned) { 1072. stoned = FALSE; 1073. goto cleanup; 1074. } 1075. 1076. if((dest & 2) 1077. #ifdef REINCARNATION 1078. || Is_rogue_level(&u.uz) 1079. #endif 1080. || (mdat == &mons[PM_WRAITH] && Is_valley(&u.uz) && rn2(5))) 1081. goto cleanup; 1082. 1083. #ifdef MAIL 1084. if(mdat == &mons[PM_MAIL_DAEMON]) { 1085. (void) mksobj_at(SCR_MAIL, x, y, FALSE); 1086. stackobj(fobj); 1087. redisp = TRUE; 1088. } 1089. #endif 1090. if(!accessible(x, y)) { 1091. /* might be mimic in wall or dead eel or in a pool or lava */ 1092. redisp = TRUE; 1093. if(wasinside) spoteffects(); 1094. } else if(x != u.ux || y != u.uy) { 1095. /* might be here after swallowed */ 1096. if (!rn2(6) && !(mdat->geno & G_NOCORPSE) 1097. #ifdef KOPS 1098. && mdat->mlet != S_KOP 1099. #endif 1100. ) { 1101. int typ; 1102. 1103. otmp = mkobj_at(RANDOM_CLASS, x, y, TRUE); 1104. /* Don't create large objects from small monsters */ 1105. typ = otmp->otyp; 1106. if (mdat->msize < MZ_HUMAN && typ != FOOD_RATION 1107. #ifdef WALKIES 1108. && typ != LEASH 1109. #endif 1110. && typ != FIGURINE 1111. && (otmp->owt > 3 || 1112. (typ >= SPEAR && typ <= LANCE) || 1113. (typ >= SCIMITAR && typ <= KATANA) || 1114. (typ == MORNING_STAR || typ == QUARTERSTAFF) || 1115. (typ >= BARDICHE && typ <= VOULGE) || 1116. (typ >= PLATE_MAIL && 1117. typ <= YELLOW_DRAGON_SCALE_MAIL) || 1118. (typ == LARGE_SHIELD))) { 1119. delobj(otmp); 1120. } else redisp = TRUE; 1121. } 1122. /* Whether or not it always makes a corpse is, in theory, 1123. * different from whether or not the corpse is "special"; 1124. * if we want both, we have to specify it explicitly. 1125. */ 1126. if (bigmonst(mdat) || mdat == &mons[PM_LIZARD] 1127. || is_golem(mdat) 1128. || is_mplayer(mdat) 1129. || is_rider(mdat)) 1130. chance = 1; 1131. else chance = !rn2((int) 1132. (2 + ((mdat->geno & G_FREQ)<2) + verysmall(mdat))); 1133. if (chance) 1134. (void) make_corpse(mtmp); 1135. } 1136. if(redisp) newsym(x,y); 1137. cleanup: 1138. /* punish bad behaviour */ 1139. if(is_human(mdat) && !always_hostile(mdat) && 1140. (monsndx(mdat) < PM_ARCHEOLOGIST || monsndx(mdat) > PM_WIZARD) && 1141. u.ualign.type != A_CHAOTIC) { 1142. HTelepat &= ~INTRINSIC; 1143. change_luck(-2); 1144. if (Blind && !Telepat) 1145. see_monsters(); /* Can't sense monsters any more. */ 1146. } 1147. if((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame) change_luck(-1); 1148. if (mdat->mlet == S_UNICORN && 1149. sgn(u.ualign.type) == sgn(mdat->maligntyp)) 1150. change_luck(-5); 1151. 1152. /* give experience points */ 1153. tmp = experience(mtmp, u.nr_killed[monsndx(mdat)] + 1); 1154. more_experienced(tmp, 0); 1155. newexplevel(); /* will decide if you go up */ 1156. 1157. /* adjust alignment points */ 1158. #ifdef MULDGN 1159. if(mdat->msound == MS_LEADER) /* REAL BAD! */ 1160. adjalign(-(u.ualign.record+(int)ALIGNLIM/2)); 1161. else if(mdat->msound == MS_NEMESIS) /* Real good! */ 1162. adjalign((int)(ALIGNLIM/4)); 1163. else if(mdat->msound == MS_GUARDIAN) /* Bad */ 1164. adjalign(-(int)(ALIGNLIM/8)); 1165. else 1166. #endif 1167. if (mtmp->ispriest) { 1168. adjalign((p_coaligned(mtmp)) ? -2 : 2); 1169. if(mdat->maligntyp == A_NONE) 1170. adjalign((int)(ALIGNLIM / 4)); /* BIG bonus */ 1171. } else if(mtmp->mtame) 1172. adjalign(-15); /* bad!! */ 1173. else if (mtmp->mpeaceful) 1174. adjalign(-5); 1175. 1176. /* malign was already adjusted for u.ualign.type and randomization */ 1177. adjalign(mtmp->malign); 1178. } 1179. 1180. /* changes the monster into a stone monster of the same type */ 1181. /* this should only be called when poly_when_stoned() is true */ 1182. void 1183. mon_to_stone(mtmp) 1184. register struct monst *mtmp; 1185. { 1186. if(mtmp->data->mlet == S_GOLEM) { 1187. /* it's a golem, and not a stone golem */ 1188. if(canseemon(mtmp)) 1189. pline("%s solidifies...", Monnam(mtmp)); 1190. (void) newcham(mtmp, &mons[PM_STONE_GOLEM]); 1191. if(canseemon(mtmp)) 1192. pline("Now it's %s", a_monnam(mtmp)); 1193. } else 1194. impossible("Can't polystone %s", a_monnam(mtmp)); 1195. } 1196. 1197. void 1198. mnexto(mtmp) /* Make monster mtmp next to you (if possible) */ 1199. struct monst *mtmp; 1200. { 1201. coord mm; 1202. 1203. if(!enexto(&mm, u.ux, u.uy, mtmp->data)) return; 1204. 1205. rloc_to(mtmp, mm.x, mm.y); 1206. } 1207. 1208. /* mnearto() 1209. * Put monster near (or at) location if possible. 1210. * Returns: 1211. * 1 - if a monster was moved from x, y to put mtmp at x, y. 1212. * 0 - in most cases. 1213. */ 1214. boolean 1215. mnearto(mtmp,x,y,move_other) 1216. register struct monst *mtmp; 1217. xchar x, y; 1218. boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */ 1219. { 1220. struct monst *othermon = (struct monst *)0; 1221. xchar newx, newy; 1222. coord mm; 1223. 1224. if ((mtmp->mx == x) && (mtmp->my == y)) return(FALSE); 1225. 1226. if (move_other && (othermon = m_at(x, y))) { 1227. if (othermon->wormno) 1228. remove_worm(othermon); 1229. else 1230. remove_monster(x, y); 1231. } 1232. 1233. newx = x; 1234. newy = y; 1235. 1236. if (!goodpos(newx, newy, mtmp, mtmp->data)) { 1237. /* actually we have real problems if enexto ever fails. 1238. * migrating_mons that need to be placed will cause 1239. * no end of trouble. 1240. */ 1241. if (!enexto(&mm, newx, newy, mtmp->data)) return(FALSE); 1242. newx = mm.x; newy = mm.y; 1243. } 1244. 1245. rloc_to(mtmp, newx, newy); 1246. 1247. if (move_other && othermon) { 1248. othermon->mx = othermon->my = 0; 1249. (void) mnearto(othermon, x, y, FALSE); 1250. if ((othermon->mx != x) || (othermon->my != y)) 1251. return(TRUE); 1252. } 1253. 1254. return(FALSE); 1255. } 1256. 1257. 1258. static const char *poiseff[] = { 1259. 1260. " feel very weak", "r brain is on fire", 1261. "r judgement is impaired", "r muscles won't obey you", 1262. " feel very sick", " break out in hives" 1263. }; 1264. 1265. void 1266. poisontell(typ) 1267. 1268. int typ; 1269. { 1270. pline("You%s.", poiseff[typ]); 1271. } 1272. 1273. void 1274. poisoned(string, typ, pname, fatal) 1275. register const char *string, *pname; 1276. register int typ, fatal; 1277. { 1278. register int i, plural; 1279. boolean thrown_weapon = !strncmp(string, "poison", 6); 1280. /* admittedly a kludge... */ 1281. 1282. if(strcmp(string, "blast") && !thrown_weapon) { 1283. /* 'blast' has already given a 'poison gas' message */ 1284. /* so have "poison arrow", "poison dart", etc... */ 1285. plural = (string[strlen(string) - 1] == 's')? 1 : 0; 1286. /* avoid "The" Orcus's sting was poisoned... */ 1287. pline("%s%s %s poisoned!", isupper(*string) ? "" : "The ", 1288. string, plural ? "were" : "was"); 1289. } 1290. 1291. if(Poison_resistance) { 1292. if(!strcmp(string, "blast")) shieldeff(u.ux, u.uy); 1293. pline("The poison doesn't seem to affect you."); 1294. return; 1295. } 1296. i = rn2(fatal + 20*thrown_weapon); 1297. if(i == 0 && typ != A_CHA) { 1298. u.uhp = -1; 1299. pline("The poison was deadly..."); 1300. } else if(i <= 5) { 1301. pline("You%s!", poiseff[typ]); 1302. (void) adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), TRUE); 1303. } else { 1304. i = thrown_weapon ? rnd(6) : rn1(10,6); 1305. if(Half_physical_damage) i = (i+1) / 2; 1306. losehp(i, pname, KILLED_BY_AN); 1307. } 1308. if(u.uhp < 1) { 1309. killer_format = KILLED_BY_AN; 1310. killer = pname; 1311. done(POISONING); 1312. } 1313. } 1314. 1315. /* monster responds to player action; not the same as a passive attack */ 1316. /* assumes reason for response has been tested, and response _must_ be made */ 1317. void 1318. m_respond(mtmp) 1319. register struct monst *mtmp; 1320. { 1321. if(mtmp->data->msound == MS_SHRIEK) { 1322. if(flags.soundok) 1323. pline("%s shrieks.", Monnam(mtmp)); 1324. aggravate(); 1325. } 1326. } 1327. 1328. #endif /* OVLB */ 1329. #ifdef OVL2 1330. 1331. void 1332. setmangry(mtmp) 1333. register struct monst *mtmp; 1334. { 1335. mtmp->data->mflags3 &= ~M3_WAITMASK; 1336. if(!mtmp->mpeaceful) return; 1337. if(mtmp->mtame) return; 1338. mtmp->mpeaceful = 0; 1339. if(mtmp->ispriest) { 1340. if(p_coaligned(mtmp)) adjalign(-5); /* very bad */ 1341. else adjalign(2); 1342. } else 1343. adjalign(-1); /* attacking peaceful monsters is bad */ 1344. if(humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd) 1345. pline("%s gets angry!", Monnam(mtmp)); 1346. #ifdef SOUNDS 1347. else if (flags.verbose && flags.soundok) growl(mtmp); 1348. #endif 1349. } 1350. 1351. void 1352. wakeup(mtmp) 1353. register struct monst *mtmp; 1354. { 1355. mtmp->msleep = 0; 1356. mtmp->meating = 0; /* assume there's no salvagable food left */ 1357. setmangry(mtmp); 1358. if(mtmp->m_ap_type) seemimic(mtmp); 1359. } 1360. 1361. /* Wake up nearby monsters. */ 1362. void 1363. wake_nearby() 1364. { 1365. register struct monst *mtmp; 1366. 1367. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1368. if (distu(mtmp->mx,mtmp->my) < u.ulevel*20) { 1369. if(mtmp->msleep) mtmp->msleep = 0; 1370. if(mtmp->mtame) EDOG(mtmp)->whistletime = moves; 1371. } 1372. } 1373. } 1374. 1375. /* NOTE: we must check for mimicry before calling this routine */ 1376. void 1377. seemimic(mtmp) 1378. register struct monst *mtmp; 1379. { 1380. /* 1381. * Discovered mimics don't block light. 1382. */ 1383. if ((mtmp->m_ap_type == M_AP_FURNITURE && 1384. (mtmp->mappearance==S_hcdoor || mtmp->mappearance==S_vcdoor))|| 1385. (mtmp->m_ap_type == M_AP_OBJECT && mtmp->mappearance == BOULDER)) 1386. unblock_point(mtmp->mx,mtmp->my); 1387. 1388. mtmp->m_ap_type = M_AP_NOTHING; 1389. mtmp->mappearance = 0; 1390. newsym(mtmp->mx,mtmp->my); 1391. } 1392. 1393. /* force all chameleons to become normal */ 1394. void 1395. rescham() 1396. { 1397. register struct monst *mtmp; 1398. 1399. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1400. if(mtmp->cham) { 1401. mtmp->cham = 0; 1402. (void) newcham(mtmp, &mons[PM_CHAMELEON]); 1403. } 1404. if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN) 1405. new_were(mtmp); 1406. if(mtmp->m_ap_type && cansee(mtmp->mx, mtmp->my)) { 1407. seemimic(mtmp); 1408. /* we pretend that the mimic doesn't */ 1409. /* know that it has been unmasked. */ 1410. mtmp->msleep = 1; 1411. } 1412. } 1413. } 1414. 1415. /* Let the chameleons change again -dgk */ 1416. void 1417. restartcham() 1418. { 1419. register struct monst *mtmp; 1420. 1421. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1422. if (mtmp->data == &mons[PM_CHAMELEON]) 1423. mtmp->cham = 1; 1424. if(mtmp->data->mlet == S_MIMIC && mtmp->msleep && 1425. cansee(mtmp->mx, mtmp->my)) { 1426. set_mimic_sym(mtmp); 1427. newsym(mtmp->mx,mtmp->my); 1428. } 1429. } 1430. } 1431. 1432. /* unwatched hiders may hide again; if so, a 1 is returned. */ 1433. STATIC_OVL boolean 1434. restrap(mtmp) 1435. register struct monst *mtmp; 1436. { 1437. if(mtmp->cham || mtmp->mcan || mtmp->m_ap_type || 1438. cansee(mtmp->mx, mtmp->my) || rn2(3) || (mtmp == u.ustuck)) 1439. return(FALSE); 1440. 1441. if(mtmp->data->mlet == S_MIMIC) { 1442. set_mimic_sym(mtmp); 1443. return(TRUE); 1444. } else 1445. if(levl[mtmp->mx][mtmp->my].typ == ROOM) { 1446. mtmp->mundetected = 1; 1447. return(TRUE); 1448. } 1449. 1450. return(FALSE); 1451. } 1452. 1453. /* make a chameleon look like a new monster; returns 1 if it actually changed */ 1454. int 1455. newcham(mtmp, mdat) 1456. register struct monst *mtmp; 1457. register struct permonst *mdat; 1458. { 1459. register int mhp, hpn, hpd; 1460. int tryct; 1461. struct permonst *olddata = mtmp->data; 1462. 1463. /* mdat = 0 -> caller wants a random monster shape */ 1464. tryct = 0; 1465. if(mdat == 0) { 1466. while (++tryct < 100) { 1467. mdat = &mons[rn2(NUMMONS)]; 1468. /* polyok rules out all M2_PNAME and M2_WERE's */ 1469. if (!is_human(mdat) && polyok(mdat) 1470. && !(mdat->geno & G_GENOD)) 1471. break; 1472. } 1473. if (tryct >= 100) return(0); /* Should never happen */ 1474. } 1475. 1476. if(is_male(mdat)) { 1477. if(mtmp->female) mtmp->female = FALSE; 1478. } else if (is_female(mdat)) { 1479. if(!mtmp->female) mtmp->female = TRUE; 1480. } else if (!is_neuter(mdat)) { 1481. if(!rn2(10)) mtmp->female = !mtmp->female; 1482. } 1483. 1484. if(mdat == mtmp->data) return(0); /* still the same monster */ 1485. 1486. if(mtmp->wormno) { /* throw tail away */ 1487. wormgone(mtmp); 1488. place_monster(mtmp, mtmp->mx, mtmp->my); 1489. } 1490. 1491. hpn = mtmp->mhp; 1492. hpd = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel; 1493. if(!hpd) hpd = 4; 1494. 1495. mtmp->m_lev = adj_lev(mdat); /* new monster level */ 1496. 1497. mhp = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel; 1498. if(!mhp) mhp = 4; 1499. 1500. /* new hp: same fraction of max as before */ 1501. #ifndef LINT 1502. mtmp->mhp = (int)(((long)hpn*(long)mhp)/(long)hpd); 1503. #endif 1504. if(mtmp->mhp < 0) mtmp->mhp = hpn; /* overflow */ 1505. /* Unlikely but not impossible; a 1HD creature with 1HP that changes into a 1506. 0HD creature will require this statement */ 1507. if (!mtmp->mhp) mtmp->mhp = 1; 1508. 1509. /* and the same for maximum hit points */ 1510. hpn = mtmp->mhpmax; 1511. #ifndef LINT 1512. mtmp->mhpmax = (int)(((long)hpn*(long)mhp)/(long)hpd); 1513. #endif 1514. if(mtmp->mhpmax < 0) mtmp->mhpmax = hpn; /* overflow */ 1515. if (!mtmp->mhpmax) mtmp->mhpmax = 1; 1516. 1517. mtmp->data = mdat; 1518. mtmp->minvis = !!(mdat->mlet == S_STALKER); 1519. if (!hides_under(mdat) || !OBJ_AT(mtmp->mx, mtmp->my)) 1520. mtmp->mundetected = 0; 1521. if (u.ustuck == mtmp) { 1522. if(u.uswallow) { 1523. if(!attacktype(mdat,AT_ENGL)) { 1524. /* Does mdat care? */ 1525. if (!noncorporeal(mdat) && !amorphous(mdat) && 1526. !is_whirly(mdat) && 1527. (mdat != &mons[PM_YELLOW_LIGHT])) { 1528. You("break out of %s%s!", mon_nam(mtmp), 1529. (is_animal(mdat)? 1530. "'s stomach" : "")); 1531. mtmp->mhp = 1; /* almost dead */ 1532. } 1533. expels(mtmp, olddata, FALSE); 1534. } 1535. } else { 1536. if(!sticks(mdat) 1537. #ifdef POLYSELF 1538. && !sticks(uasmon) 1539. #endif 1540. ) 1541. unstuck(mtmp); 1542. } 1543. } 1544. 1545. if ( (mdat == &mons[PM_LONG_WORM]) && (mtmp->wormno = get_wormno()) ) { 1546. /* we can now create worms with tails - 11/91 */ 1547. initworm(mtmp, rn2(5)); 1548. if (count_wsegs(mtmp)) 1549. place_worm_tail_randomly(mtmp, mtmp->mx, mtmp->my); 1550. } 1551. 1552. newsym(mtmp->mx,mtmp->my); 1553. #ifdef MUSE 1554. mon_break_armor(mtmp); 1555. possibly_unwield(mtmp); 1556. #endif 1557. return(1); 1558. } 1559. 1560. #endif /* OVL2 */ 1561. #ifdef OVLB 1562. 1563. void 1564. golemeffects(mon, damtype, dam) 1565. register struct monst *mon; 1566. int damtype, dam; 1567. { 1568. int heal=0, slow=0; 1569. 1570. if (mon->data != &mons[PM_FLESH_GOLEM] 1571. && mon->data != &mons[PM_IRON_GOLEM]) 1572. return; 1573. 1574. if (mon->data == &mons[PM_FLESH_GOLEM]) { 1575. if (damtype == AD_ELEC) heal = dam / 6; 1576. else if (damtype == AD_FIRE || damtype == AD_COLD) slow = 1; 1577. } else { 1578. if (damtype == AD_ELEC) slow = 1; 1579. else if (damtype == AD_FIRE) heal = dam; 1580. } 1581. if (slow) { 1582. if (mon->mspeed != MSLOW) { 1583. if (mon->mspeed == MFAST) mon->mspeed = 0; 1584. else mon->mspeed = MSLOW; 1585. if (cansee(mon->mx, mon->my)) 1586. pline("%s seems to be moving slower.", 1587. Monnam(mon)); 1588. } 1589. } 1590. if (heal) { 1591. if (mon->mhp < mon->mhpmax) { 1592. mon->mhp += dam; 1593. if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 1594. if (cansee(mon->mx, mon->my)) 1595. pline("%s seems healthier.", Monnam(mon)); 1596. } 1597. } 1598. } 1599. 1600. boolean 1601. angry_guards(silent) 1602. register boolean silent; 1603. { 1604. register struct monst *mtmp; 1605. register int ct = 0, nct = 0, sct = 0, slct = 0; 1606. 1607. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1608. if((mtmp->data == &mons[PM_WATCHMAN] || 1609. mtmp->data == &mons[PM_WATCH_CAPTAIN]) 1610. && mtmp->mpeaceful) { 1611. ct++; 1612. if(cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) { 1613. if (distu(mtmp->mx, mtmp->my) == 2) nct++; 1614. else sct++; 1615. } 1616. if(mtmp->msleep || mtmp->mfrozen) { 1617. slct++; 1618. mtmp->msleep = mtmp->mfrozen = 0; 1619. } 1620. mtmp->mpeaceful = 0; 1621. } 1622. } 1623. if(ct) { 1624. if(!silent) { /* do we want pline msgs? */ 1625. if(slct) pline("The guard%s wake%s up!", 1626. slct > 1 ? "s" : "", slct == 1 ? "s" : ""); 1627. if(nct || sct) { 1628. if(nct) pline("The guard%s get%s angry!", 1629. nct == 1 ? "" : "s", nct == 1 ? "s" : ""); 1630. else if(!Blind) 1631. You("see %sangry guard%s approaching!", 1632. sct == 1 ? "an " : "", sct > 1 ? "s" : ""); 1633. } else if(flags.soundok) 1634. You("hear the shrill sound of a guard's whistle."); 1635. } 1636. return(TRUE); 1637. } 1638. return(FALSE); 1639. } 1640. 1641. void 1642. pacify_guards() 1643. { 1644. register struct monst *mtmp; 1645. 1646. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1647. if (mtmp->data == &mons[PM_WATCHMAN] || 1648. mtmp->data == &mons[PM_WATCH_CAPTAIN]) 1649. mtmp->mpeaceful = 1; 1650. } 1651. } 1652. #endif /* OVLB */ 1653. 1654. /*mon.c*/
|