Source:NetHack 3.0.0/mon.c
Jump to navigation
Jump to search
Below is the full text to mon.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/mon.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)mon.c 3.0 88/10/31 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "mfndpos.h" 7. #ifdef NAMED_ITEMS 8. # include "artifact.h" 9. #endif 10. 11. #ifdef HARD 12. static boolean restrap(); 13. #endif 14. 15. long lastwarntime; 16. int lastwarnlev; 17. static const char *warnings[] = { 18. "white", "pink", "red", "ruby", "purple", "black" }; 19. struct monst *fdmon; /* chain of dead monsters, need not to be saved */ 20. 21. /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't 22. * leave corpses. Monsters which leave "special" corpses should have 23. * G_NOCORPSE set in order to prevent wishing for one, finding tins of one, 24. * etc.... 25. */ 26. static struct obj * 27. make_corpse(mtmp) 28. register struct monst *mtmp; 29. { 30. register struct permonst *mdat = mtmp->data; 31. #ifdef GOLEMS 32. int pieces; 33. #endif 34. struct obj *obj = 0; 35. int x = mtmp->mx, y = mtmp->my; 36. 37. switch(monsndx(mdat)) { 38. case PM_KOBOLD_MUMMY: 39. obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 40. case PM_KOBOLD_ZOMBIE: 41. obj = mksobj_at(CORPSE, x, y); 42. obj->corpsenm = PM_KOBOLD; 43. break; 44. case PM_GNOME_MUMMY: 45. obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 46. case PM_GNOME_ZOMBIE: 47. obj = mksobj_at(CORPSE, x, y); 48. obj->corpsenm = PM_GNOME; 49. break; 50. case PM_ORC_MUMMY: 51. obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 52. case PM_ORC_ZOMBIE: 53. obj = mksobj_at(CORPSE, x, y); 54. obj->corpsenm = PM_ORC; 55. break; 56. case PM_ELF_MUMMY: 57. obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 58. case PM_ELF_ZOMBIE: 59. obj = mksobj_at(CORPSE, x, y); 60. obj->corpsenm = PM_ELF; 61. break; 62. case PM_HUMAN_MUMMY: 63. obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 64. case PM_HUMAN_ZOMBIE: 65. obj = mksobj_at(CORPSE, x, y); 66. obj->corpsenm = PM_HUMAN; 67. break; 68. case PM_GIANT_MUMMY: 69. obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 70. case PM_GIANT_ZOMBIE: 71. obj = mksobj_at(CORPSE, x, y); 72. obj->corpsenm = PM_GIANT; 73. break; 74. case PM_ETTIN_MUMMY: 75. obj = mksobj_at(MUMMY_WRAPPING, x, y); /* and fall through */ 76. case PM_ETTIN_ZOMBIE: 77. obj = mksobj_at(CORPSE, x, y); 78. obj->corpsenm = PM_ETTIN; 79. break; 80. #ifdef GOLEMS 81. case PM_IRON_GOLEM: 82. pieces = d(2,6); 83. while (pieces--) 84. obj = mksobj_at(IRON_CHAIN, x, y); 85. break; 86. case PM_CLAY_GOLEM: 87. obj = mksobj_at(ROCK, x, y); 88. obj->quan = rn2(20) + 100; 89. obj->owt = weight(obj); 90. break; 91. case PM_STONE_GOLEM: 92. obj = mkstatue(mdat, x, y); 93. break; 94. case PM_WOOD_GOLEM: 95. pieces = d(2,4); 96. while(pieces--) 97. obj = mksobj_at(QUARTERSTAFF, x, y); 98. break; 99. case PM_LEATHER_GOLEM: 100. pieces = d(2,4); 101. while(pieces--) 102. obj = mksobj_at(LEATHER_ARMOR, x, y); 103. break; 104. #endif 105. default: 106. if (mdat->geno & G_NOCORPSE) 107. return (struct obj *)0; 108. else obj = mkcorpse_at(mdat, x, y); 109. break; 110. } 111. /* All special cases should precede the G_NOCORPSE check */ 112. 113. /* Note: oname() cannot be used generically for non-inventory objects 114. * unless you fix the link from the previous object in the chain. 115. * (Here we know it's the first one, so there was no link.) 116. */ 117. if (mtmp->mnamelth) { 118. obj = oname(obj, NAME(mtmp), 0); 119. fobj = obj; 120. } 121. stackobj(fobj); 122. newsym(x, y); 123. return obj; 124. } 125. 126. 127. static void 128. dmonsfree(){ 129. register struct monst *mtmp; 130. while(mtmp = fdmon){ 131. fdmon = mtmp->nmon; 132. free((genericptr_t) mtmp); 133. } 134. } 135. 136. void 137. movemon() 138. { 139. register struct monst *mtmp; 140. register int fr; 141. 142. warnlevel = 0; 143. 144. while(1) { 145. /* Find a monster that we have not treated yet. 146. * Note that mtmp or mtmp->nmon might get killed 147. * while mtmp moves, so we cannot just walk down the 148. * chain (even new monsters might get created!) 149. */ 150. /* Do tame monsters first. Necessary so that when the tame 151. * monster attacks something, the something gets a chance to 152. * attack the tame monster back (which it's permitted to do 153. * only if it hasn't made its move yet). 154. */ 155. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 156. if(mtmp->mlstmv < moves && mtmp->mtame) goto next_mon; 157. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 158. if(mtmp->mlstmv < moves && !mtmp->mtame) goto next_mon; 159. /* treated all monsters */ 160. break; 161. 162. next_mon: 163. mtmp->mlstmv = moves; 164. 165. /* most monsters drown in pools */ 166. { boolean inpool,infountain,iseel,isgremlin; 167. 168. inpool = is_pool(mtmp->mx,mtmp->my); 169. iseel = mtmp->data->mlet == S_EEL; 170. isgremlin = mtmp->data->mlet == S_GREMLIN; 171. infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ); 172. /* Gremlin multiplying won't go on forever since the hit points 173. * keep going down, and when it gets to 1 hit point the clone 174. * function will fail. 175. */ 176. if((inpool || infountain) && isgremlin && rn2(3)) { 177. struct monst *mtmp2 = clone_mon(mtmp); 178. 179. if (mtmp2) { 180. mtmp2->mhpmax = (mtmp->mhpmax /= 2); 181. if(cansee(mtmp->mx,mtmp->my)) 182. pline("%s multiplies.", Monnam(mtmp)); 183. } 184. #ifdef FOUNTAINS 185. if (infountain) dryup(); 186. #endif 187. } else 188. if(inpool && !is_flyer(mtmp->data) && !is_swimmer(mtmp->data)) { 189. if(cansee(mtmp->mx,mtmp->my)) 190. pline("%s drowns.", Monnam(mtmp)); 191. mondead(mtmp); 192. continue; 193. } else 194. /* but eels have a difficult time outside */ 195. if(iseel && !inpool) { 196. if(mtmp->mhp > 1) mtmp->mhp--; 197. mtmp->mflee = 1; 198. mtmp->mfleetim += 2; 199. } 200. } 201. if(mtmp->mblinded && !--mtmp->mblinded) 202. mtmp->mcansee = 1; 203. if(mtmp->mfleetim && !--mtmp->mfleetim) 204. mtmp->mflee = 0; 205. #ifdef HARD 206. /* unwatched mimics and piercers may hide again [MRS] */ 207. if(is_hider(mtmp->data) && restrap(mtmp)) continue; 208. #endif 209. if(mtmp->mimic) continue; 210. if(mtmp->mspeed != MSLOW || !(moves%2)){ 211. /* continue if the monster died fighting */ 212. fr = -1; 213. /* TODO: Handle the case of the agressor dying? */ 214. if(Conflict && cansee(mtmp->mx,mtmp->my) 215. && !mtmp->iswiz 216. && (fr = fightm(mtmp)) == 2) 217. continue; 218. if(fr<0 && dochugw(mtmp)) 219. continue; 220. } 221. if(mtmp->mspeed == MFAST && dochugw(mtmp)) 222. continue; 223. } 224. #ifdef NAMED_ITEMS 225. if (warnlevel == 100) { 226. Your("%s %s!", aobjnam(uwep, "glow"), 227. Hallucination ? hcolor() : light_blue); 228. warnlevel = 0; 229. } 230. #endif 231. warnlevel -= u.ulevel; 232. if(warnlevel >= SIZE(warnings)) 233. warnlevel = SIZE(warnings)-1; 234. if(!Blind && warnlevel >= 0) 235. if(warnlevel > lastwarnlev || moves > lastwarntime + 5){ 236. register char *rr; 237. 238. switch((int) (Warning & (LEFT_RING | RIGHT_RING))){ 239. case LEFT_RING: 240. rr = "Your left ring glows"; 241. break; 242. case RIGHT_RING: 243. rr = "Your right ring glows"; 244. break; 245. case LEFT_RING | RIGHT_RING: 246. rr = "Both your rings glow"; 247. break; 248. default: 249. { char buf[33]; 250. Sprintf(buf, "Your %s glow", makeplural(body_part(FINGERTIP))); 251. rr = buf; 252. } 253. break; 254. } 255. pline("%s %s!", rr, Hallucination ? hcolor() : warnings[warnlevel]); 256. lastwarntime = moves; 257. lastwarnlev = warnlevel; 258. } 259. 260. dmonsfree(); /* remove all dead monsters */ 261. } 262. 263. void 264. meatgold(mtmp) 265. register struct monst *mtmp; 266. { 267. register struct gold *gold; 268. register struct obj *otmp; 269. 270. /* Eats gold if it is there */ 271. while(gold = g_at(mtmp->mx, mtmp->my)){ 272. if (cansee(mtmp->mx, mtmp->my) && flags.verbose) 273. pline("%s eats some gold!", Monnam(mtmp)); 274. mtmp->meating = (int)((gold->amount + 500L)/1000L); 275. freegold(gold); 276. /* Left behind a pile? */ 277. if(rnd(25) < 3) (void) mksobj_at(ROCK, mtmp->mx, mtmp->my); 278. newsym(mtmp->mx, mtmp->my); 279. } 280. /* Eats topmost metal object if it is there */ 281. for (otmp = fobj; otmp; otmp = otmp->nobj) 282. if (otmp->ox == mtmp->mx && otmp->oy == mtmp->my && 283. objects[otmp->otyp].oc_material == METAL) { 284. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 285. pline("%s eats %s!", Monnam(mtmp), 286. distant_name(otmp,doname)); 287. else if (flags.soundok && flags.verbose) 288. You("hear a crunching sound."); 289. mtmp->meating = otmp->owt/2 - 1; 290. /* Heal up to the object's weight in hp */ 291. if (mtmp->mhp < mtmp->mhpmax) { 292. mtmp->mhp += objects[otmp->otyp].oc_weight; 293. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; 294. } 295. freeobj(otmp); 296. /* Left behind a pile? */ 297. if(rnd(25) < 3) (void) mksobj_at(ROCK, mtmp->mx, mtmp->my); 298. newsym(mtmp->mx, mtmp->my); 299. break; 300. } 301. set_omask(mtmp->mx, mtmp->my); 302. } 303. 304. void 305. meatobj(mtmp) /* for gelatinous cubes */ 306. register struct monst *mtmp; 307. { 308. register struct obj *otmp, *otmp2; 309. 310. /* Eats organic, glass, or wood objects if there */ 311. /* Engulfs anything else, metal and rock */ 312. for (otmp = fobj; otmp; otmp = otmp2) { 313. otmp2 = otmp->nobj; 314. if (otmp->ox == mtmp->mx && otmp->oy == mtmp->my) { 315. if(!objects[otmp->otyp].oc_material <= WOOD) { 316. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 317. pline("%s eats %s!", Monnam(mtmp), 318. distant_name(otmp, doname)); 319. else if (flags.soundok && flags.verbose) 320. You("hear a slurping sound."); 321. /* Heal up to the object's weight in hp */ 322. if (mtmp->mhp < mtmp->mhpmax) { 323. mtmp->mhp += objects[otmp->otyp].oc_weight; 324. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; 325. } 326. delobj(otmp); /* munch */ 327. } else if (otmp->olet != ROCK_SYM && otmp->olet != BALL_SYM) { 328. if (cansee(mtmp->mx, mtmp->my) && flags.verbose) 329. pline("%s engulfs %s.", Monnam(mtmp), 330. distant_name(otmp,doname)); 331. freeobj(otmp); 332. mpickobj(mtmp, otmp); /* slurp */ 333. } 334. } 335. /* Engulf & devour is instant, so don't set meating */ 336. newsym(mtmp->mx, mtmp->my); 337. } 338. set_omask(mtmp->mx, mtmp->my); 339. } 340. 341. void 342. mpickgold(mtmp) 343. register struct monst *mtmp; 344. { 345. register struct gold *gold; 346. 347. while(gold = g_at(mtmp->mx, mtmp->my)){ 348. mtmp->mgold += gold->amount; 349. if (cansee(mtmp->mx, mtmp->my) && flags.verbose) 350. pline("%s picks up some gold.", Monnam(mtmp)); 351. freegold(gold); 352. if(levl[mtmp->mx][mtmp->my].scrsym == GOLD_SYM) 353. newsym(mtmp->mx, mtmp->my); 354. } 355. set_omask(mtmp->mx, mtmp->my); 356. } 357. 358. /* Now includes giants which pick up enormous rocks. KAA */ 359. void 360. mpickgems(mtmp) 361. register struct monst *mtmp; 362. { 363. register struct obj *otmp; 364. 365. for(otmp = fobj; otmp; otmp = otmp->nobj) 366. if(throws_rocks(mtmp->data) ? otmp->otyp == BOULDER : 367. (otmp->olet == GEM_SYM && otmp->otyp < LAST_GEM+5)) 368. if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my) 369. if(mtmp->data->mlet != S_UNICORN 370. || objects[otmp->otyp].g_val != 0){ 371. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 372. pline("%s picks up %s.", Monnam(mtmp), 373. distant_name(otmp, doname)); 374. freeobj(otmp); 375. mpickobj(mtmp, otmp); 376. newsym(mtmp->mx, mtmp->my); 377. return; /* pick only one object */ 378. } 379. set_omask(mtmp->mx, mtmp->my); 380. } 381. 382. int 383. curr_mon_load(mtmp) 384. register struct monst *mtmp; 385. { 386. register int curload = 0; 387. register struct obj *obj; 388. 389. for(obj = mtmp->minvent; obj; obj = obj->nobj) { 390. if(obj->otyp != BOULDER || !throws_rocks(mtmp->data)) 391. curload += weight(obj); 392. } 393. 394. return curload; 395. } 396. 397. int 398. max_mon_load(mtmp) 399. register struct monst *mtmp; 400. { 401. register int maxload; 402. 403. /* Base monster carrying capacity is equal to human maximum 404. * carrying capacity, or half human maximum if not strong. 405. * (for a polymorphed player, the value used would be the 406. * non-polymorphed carrying capacity instead of max/half max). 407. * This is then modified by the ratio between the monster weights 408. * and human weights (weight of a human=45). Limits for corpseless 409. * monsters are arbitrary. 410. */ 411. maxload = (mtmp->data->cwt ? mtmp->data->cwt : mtmp->data->mlevel*6) 412. * MAX_CARR_CAP / 45; 413. if (!strongmonst(mtmp->data)) maxload /= 2; 414. 415. return maxload; 416. } 417. 418. /* for restricting monsters' object-pickup */ 419. boolean 420. can_carry(mtmp,otmp) 421. struct monst *mtmp; 422. struct obj *otmp; 423. { 424. register int newload = weight(otmp); 425. 426. if (mtmp->isshk) return(TRUE); /* no limit */ 427. if (mtmp->mpeaceful && !mtmp->mtame) return(FALSE); 428. /* otherwise players might find themselves obligated to violate 429. * their alignment if the monster takes something they need 430. */ 431. 432. /* special--boulder throwers carry unlimited amounts of boulders */ 433. if (throws_rocks(mtmp->data) && otmp->otyp == BOULDER) 434. return(TRUE); 435. 436. /* nymphs deal in stolen merchandise, but not boulders or statues */ 437. if (mtmp->data->mlet == S_NYMPH) 438. return !(otmp->olet == ROCK_SYM); 439. 440. if(curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return(FALSE); 441. 442. return(TRUE); 443. } 444. 445. void 446. mpickstuff(mtmp, str) 447. register struct monst *mtmp; 448. register char *str; 449. { 450. register struct obj *otmp; 451. 452. /* prevent shopkeepers from leaving the door of their shop */ 453. if(mtmp->isshk && inhishop(mtmp)) return; 454. 455. for(otmp = fobj; otmp; otmp = otmp->nobj) 456. if(index(str, otmp->olet)) 457. if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my) { 458. if(!can_carry(mtmp,otmp)) return; 459. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 460. pline("%s picks up %s.", Monnam(mtmp), doname(otmp)); 461. freeobj(otmp); 462. mpickobj(mtmp, otmp); 463. if(index(str, (char) levl[mtmp->mx][mtmp->my].scrsym)) 464. newsym(mtmp->mx, mtmp->my); 465. set_omask(mtmp->mx, mtmp->my); 466. return; /* pick only one object */ 467. } 468. } 469. 470. /* return number of acceptable neighbour positions */ 471. int 472. mfndpos(mon, poss, info, flag) 473. register struct monst *mon; 474. coord *poss; /* coord poss[9] */ 475. long *info; /* long info[9] */ 476. long flag; 477. { 478. register int x,y,nx,ny,cnt = 0,ntyp; 479. int nowtyp; 480. boolean wantpool,poolok; 481. 482. x = mon->mx; 483. y = mon->my; 484. nowtyp = levl[x][y].typ; 485. 486. wantpool = mon->data->mlet == S_EEL; 487. poolok = is_flyer(mon->data) || (is_swimmer(mon->data) && !wantpool); 488. nexttry: /* eels prefer the water, but if there is no water nearby, 489. they will crawl over land */ 490. if(mon->mconf) { 491. flag |= ALLOW_ALL; 492. flag &= ~NOTONL; 493. } 494. if(!mon->mcansee) 495. flag |= ALLOW_SSM; 496. for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) { 497. if((nx == x && ny == y) || !isok(nx,ny)) continue; 498. if(IS_ROCK(ntyp = levl[nx][ny].typ) && !(flag & ALLOW_WALL) && 499. !((flag & ALLOW_DIG) && may_dig(nx,ny))) continue; 500. if(IS_DOOR(ntyp) && !amorphous(mon->data) && 501. ((levl[nx][ny].doormask & D_LOCKED && 502. !is_giant(mon->data) && !mon->isshk) || 503. (levl[nx][ny].doormask & D_CLOSED && 504. (verysmall(mon->data) || 505. (!is_giant(mon->data) && nohands(mon->data)))) 506. ) && !(flag & (ALLOW_WALL|ALLOW_DIG))) continue; 507. if(nx != x && ny != y && (IS_DOOR(nowtyp) || IS_DOOR(ntyp))) 508. continue; 509. if(is_pool(nx,ny) == wantpool || poolok) { 510. /* Displacement also displaces the Elbereth/scare monster, 511. * as long as you are visible. 512. */ 513. int dispx = (Displaced && (!Invis || perceives(mon->data)) && 514. (mon->mux==nx)) ? u.ux : nx; 515. int dispy = (Displaced && (!Invis || perceives(mon->data)) && 516. (mon->muy==ny)) ? u.uy : ny; 517. 518. info[cnt] = 0; 519. if(sobj_at(SCR_SCARE_MONSTER, dispx, dispy) 520. #ifdef ELBERETH 521. || sengr_at("Elbereth", dispx, dispy) 522. #endif 523. ) { 524. if(!(flag & ALLOW_SSM)) continue; 525. info[cnt] |= ALLOW_SSM; 526. } 527. if((nx == u.ux && ny == u.uy) || 528. (nx == mon->mux && ny == mon->muy)) { 529. if(!(flag & ALLOW_U)) continue; 530. info[cnt] |= ALLOW_U; 531. } else { 532. if(levl[nx][ny].mmask) { 533. if(!(flag & ALLOW_M)) continue; 534. info[cnt] |= ALLOW_M; 535. if((m_at(nx,ny))->mtame) { 536. if(!(flag & ALLOW_TM)) continue; 537. info[cnt] |= ALLOW_TM; 538. } 539. } 540. #if defined(ALTARS) && defined(THEOLOGY) 541. /* Note: ALLOW_SANCT only prevents movement, not */ 542. /* attack, into a temple. */ 543. if(!in_temple(x, y) && in_temple(nx, ny) && 544. u_in_sanctuary(in_temple(nx, ny))) { 545. if(!(flag & ALLOW_SANCT)) continue; 546. info[cnt] |= ALLOW_SANCT; 547. } 548. #endif 549. } 550. if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) { 551. if(flag & NOGARLIC) continue; 552. info[cnt] |= NOGARLIC; 553. } 554. if(sobj_at(BOULDER, nx, ny)) { 555. if(!(flag & ALLOW_ROCK)) continue; 556. info[cnt] |= ALLOW_ROCK; 557. } 558. if((!Invis || perceives(mon->data)) && online(nx,ny)){ 559. if(flag & NOTONL) continue; 560. info[cnt] |= NOTONL; 561. } 562. /* we cannot avoid traps of an unknown kind */ 563. { register struct trap *ttmp = t_at(nx, ny); 564. register long tt; 565. if(ttmp) { 566. /* tt = 1L << ttmp->ttyp;*/ 567. /* why don't we just have code look like what it's supposed to do? then it 568. /* might start working for every case. try this instead: -sac */ 569. tt = (ttmp->ttyp < TRAPNUM && ttmp->ttyp); 570. /* below if added by GAN 02/06/87 to avoid 571. * traps out of range 572. */ 573. if(!(tt & ALLOW_TRAPS)) { 574. impossible("A monster looked at a very strange trap of type %d.", ttmp->ttyp); 575. continue; 576. } 577. if(mon->mtrapseen & tt) { 578. 579. if(!(flag & tt)) continue; 580. info[cnt] |= tt; 581. } 582. } 583. } 584. poss[cnt].x = nx; 585. poss[cnt].y = ny; 586. cnt++; 587. } 588. } 589. if(!cnt && wantpool && !is_pool(x,y)) { 590. wantpool = FALSE; 591. goto nexttry; 592. } 593. return(cnt); 594. } 595. 596. int 597. dist(x, y) 598. register int x,y; 599. { 600. register int dx = x - u.ux, dy = y - u.uy; 601. return dx*dx + dy*dy; 602. } 603. 604. static const char *poiseff[] = { 605. 606. " feel very weak", "r brain is on fire", 607. " can't think straight", "r muscles won't obey you", 608. " feel very sick", " break out in hives" 609. }; 610. 611. void 612. poisontell(typ) 613. 614. int typ; 615. { 616. pline("You%s.", poiseff[typ]); 617. } 618. 619. void 620. poisoned(string, typ, pname) 621. register char *string, *pname; 622. register int typ; 623. { 624. register int i, plural; 625. boolean thrown_weapon = !strncmp(string, "poison", 6); 626. /* admittedly a kludge... */ 627. 628. if(strcmp(string, "blast") && !thrown_weapon) { 629. /* 'blast' has already given a 'poison gas' message */ 630. /* so have "poison arrow", "poison dart", etc... */ 631. plural = (string[strlen(string) - 1] == 's')? 1 : 0; 632. if(Blind) 633. pline("%s poisoned.", (plural) ? "They were" : "It was"); 634. else 635. pline("The %s %s poisoned!", string, (plural) ? "were" : "was"); 636. } 637. 638. if(Poison_resistance) { 639. if(!strcmp(string, "blast")) shieldeff(u.ux, u.uy); 640. pline("The poison doesn't seem to affect you."); 641. return; 642. } 643. i = rn2(10 + 20*thrown_weapon); 644. if(i == 0 && typ != A_CHA) { 645. u.uhp = -1; 646. pline("The poison was deadly..."); 647. } else if(i <= 5) { 648. pline("You%s!", poiseff[typ]); 649. adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), TRUE); 650. } else { 651. losehp(thrown_weapon ? rnd(6) : rn1(10,6), pname); 652. } 653. if(u.uhp < 1) { 654. killer = pname; 655. done("died"); 656. } 657. } 658. 659. static void 660. m_detach(mtmp) 661. register struct monst *mtmp; 662. { 663. #ifdef WALKIES 664. if(mtmp->mleashed) m_unleash(mtmp); 665. #endif 666. relobj(mtmp,1); 667. unpmon(mtmp); 668. relmon(mtmp); 669. unstuck(mtmp); 670. } 671. 672. void 673. mondead(mtmp) 674. register struct monst *mtmp; 675. { 676. m_detach(mtmp); 677. #ifdef KOPS 678. if(mtmp->data->mlet == S_KOP && allow_kops) { 679. /* Dead Kops may come back. */ 680. switch(rnd(5)) { 681. case 1: /* returns near the stairs */ 682. (void) mkmon_at(mtmp->data->mname,xdnstair,ydnstair); 683. break; 684. case 2: /* randomly */ 685. (void) mkmon_at(mtmp->data->mname,0,0); 686. break; 687. default: 688. break; 689. } 690. } 691. #endif 692. if(mtmp->isshk) shkdead(mtmp); 693. if(mtmp->isgd) gddead(); 694. #ifdef WORM 695. if(mtmp->wormno) wormdead(mtmp); 696. #endif 697. #ifdef HARD 698. if(mtmp->iswiz) wizdead(mtmp); 699. #endif 700. #ifdef MEDUSA 701. if(mtmp->data == &mons[PM_MEDUSA]) u.ukilled_medusa = TRUE; 702. #endif 703. monfree(mtmp); 704. } 705. 706. /* called when monster is moved to larger structure */ 707. void 708. replmon(mtmp, mtmp2) 709. register struct monst *mtmp, *mtmp2; 710. { 711. relmon(mtmp); 712. monfree(mtmp); 713. levl[mtmp2->mx][mtmp2->my].mmask = 1; 714. mtmp2->nmon = fmon; 715. fmon = mtmp2; 716. if(u.ustuck == mtmp) u.ustuck = mtmp2; 717. if(mtmp2->isshk) replshk(mtmp,mtmp2); 718. if(mtmp2->isgd) replgd(mtmp,mtmp2); 719. } 720. 721. void 722. relmon(mon) 723. register struct monst *mon; 724. { 725. register struct monst *mtmp; 726. 727. if (fmon == 0) panic ("relmon: no fmon available."); 728. 729. levl[mon->mx][mon->my].mmask = 0; 730. 731. if(mon == fmon) fmon = fmon->nmon; 732. else { 733. for(mtmp = fmon; mtmp && mtmp->nmon != mon; mtmp = mtmp->nmon) ; 734. if(mtmp) mtmp->nmon = mon->nmon; 735. else panic("relmon: mon not in list."); 736. } 737. } 738. 739. /* we do not free monsters immediately, in order to have their name 740. available shortly after their demise */ 741. void 742. monfree(mtmp) register struct monst *mtmp; { 743. mtmp->nmon = fdmon; 744. fdmon = mtmp; 745. levl[mtmp->mx][mtmp->my].mmask = 0; 746. } 747. 748. void 749. unstuck(mtmp) 750. register struct monst *mtmp; 751. { 752. if(u.ustuck == mtmp) { 753. if(u.uswallow){ 754. u.ux = mtmp->mx; 755. u.uy = mtmp->my; 756. u.uswallow = 0; 757. setsee(); 758. docrt(); 759. } 760. u.ustuck = 0; 761. } 762. } 763. 764. void 765. killed(mtmp) 766. register struct monst *mtmp; 767. { 768. xkilled(mtmp, 1); 769. } 770. 771. void 772. xkilled(mtmp, dest) 773. register struct monst *mtmp; 774. /* 775. * Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse 776. * either; dest=3, message but no corpse 777. */ 778. int dest; 779. { 780. register int tmp, nk, x, y; 781. register struct permonst *mdat = mtmp->data; 782. register struct obj *otmp; 783. boolean chance; 784. 785. if (dest & 1) { 786. if(!cansee(mtmp->mx,mtmp->my)) You("destroy it!"); 787. else { 788. You("destroy %s!", 789. mtmp->mtame ? a_monnam(mtmp, "poor") : mon_nam(mtmp)); 790. } 791. } 792. 793. /* restore chameleon, lycanthropes to true form at death */ 794. /* cannot do this in make_corpse() since genociding monsters after 795. * MAXMONNO were killed does the wrong type 796. */ 797. if(mtmp->cham) mtmp->data = mdat = &mons[PM_CHAMELEON]; 798. if(mdat == &mons[PM_JACKALWERE]) 799. mtmp->data = mdat = &mons[PM_WEREJACKAL]; 800. if(mdat == &mons[PM_WOLFWERE]) 801. mtmp->data = mdat = &mons[PM_WEREWOLF]; 802. if(mdat == &mons[PM_RATWERE]) 803. mtmp->data = mdat = &mons[PM_WERERAT]; 804. 805. if(u.umconf) { 806. if(!Blind) { 807. Your("%s stop glowing %s.", 808. makeplural(body_part(HAND)), 809. Hallucination ? hcolor() : red); 810. } 811. u.umconf = 0; 812. } 813. 814. /* if we have killed MAXMONNO monsters of a given type, and it 815. * can be done, genocide that monster. 816. */ 817. tmp = monsndx(mdat); 818. u.nr_killed[tmp]++; 819. nk = u.nr_killed[tmp]; 820. #ifdef TOLKIEN 821. if(nk > (tmp==PM_NAZGUL ? 9 : MAXMONNO) && 822. !(mons[tmp].geno & (G_NOGEN | G_GENOD))) { 823. #else 824. if(nk > MAXMONNO && !(mons[tmp].geno & (G_NOGEN | G_GENOD))) { 825. #endif 826. #ifdef DEBUG 827. pline("Automatically genocided %s.", makeplural(mons[tmp].mname)); 828. #endif 829. mons[tmp].geno |= G_GENOD; 830. } 831. #ifdef MAIL 832. /* If you kill the mail daemon, no more mail delivery. -3. */ 833. else if(tmp==PM_MAIL_DAEMON) mons[tmp].geno |= G_GENOD; 834. #endif 835. 836. /* punish bad behaviour */ 837. if(is_human(mdat) && !always_hostile(mdat) && 838. (monsndx(mdat) < PM_ARCHEOLOGIST || monsndx(mdat) > PM_WIZARD) && 839. u.ualigntyp != U_CHAOTIC) { 840. HTelepat &= ~INTRINSIC; 841. change_luck(-2); 842. } 843. if((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame) change_luck(-1); 844. if ((mdat==&mons[PM_BLACK_UNICORN] && u.ualigntyp == U_CHAOTIC) || 845. (mdat==&mons[PM_GREY_UNICORN] && u.ualigntyp == U_NEUTRAL) || 846. (mdat==&mons[PM_WHITE_UNICORN] && u.ualigntyp == U_LAWFUL)) 847. change_luck(-5); 848. 849. /* give experience points */ 850. tmp = experience(mtmp, nk); 851. more_experienced(tmp, 0); 852. newexplevel(); /* will decide if you go up */ 853. 854. /* adjust alignment points */ 855. if(mtmp->mtame) 856. adjalign(-15); /* bad!! */ 857. #if defined(ALTARS) && defined(THEOLOGY) 858. else if (mtmp->ispriest && !p_coaligned(mtmp)) 859. adjalign(2); 860. #endif 861. else if (mtmp->mpeaceful) 862. adjalign(-5); 863. /* malign was already adjusted for ualigntyp and randomization */ 864. adjalign(mtmp->malign); 865. 866. /* dispose of monster and make cadaver */ 867. if(stoned) { 868. monstone(mtmp); 869. return; 870. } 871. 872. x = mtmp->mx; y = mtmp->my; 873. 874. mondead(mtmp); 875. 876. if((dest & 2) 877. #ifdef REINCARNATION 878. || dlevel == rogue_level 879. #endif 880. ) return; 881. 882. #ifdef WORM 883. if(mdat == &mons[PM_LONG_WORM]) { 884. (void) mksobj_at(WORM_TOOTH, x, y); 885. stackobj(fobj); 886. newsym(x,y); 887. } 888. #endif 889. #ifdef MAIL 890. if(mdat == &mons[PM_MAIL_DAEMON]) { 891. (void) mksobj_at(SCR_MAIL, x, y); 892. stackobj(fobj); 893. newsym(x,y); 894. } 895. #endif 896. if(!ACCESSIBLE(levl[x][y].typ) || 897. (IS_DOOR(levl[x][y].typ) && 898. levl[x][y].doormask & (D_CLOSED | D_LOCKED))) { 899. /* might be mimic in wall or dead eel*/ 900. newsym(x,y); 901. } else if(x != u.ux || y != u.uy) { 902. /* might be here after swallowed */ 903. if (!rn2(6) && !(mdat->geno & G_NOCORPSE) 904. #ifdef KOPS 905. && mdat->mlet != S_KOP 906. #endif 907. ) { 908. int typ; 909. 910. otmp = mkobj_at(RANDOM_SYM, x, y); 911. /* Don't create large objects from small monsters */ 912. typ = otmp->otyp; 913. if (!bigmonst(mdat) && typ != FOOD_RATION 914. #ifdef WALKIES 915. && typ != LEASH 916. #endif 917. && typ != FIGURINE 918. && (otmp->owt > 3 || 919. (typ >= SPEAR && typ <= LANCE) || 920. (typ >= SCIMITAR && typ <= KATANA) || 921. (typ == MORNING_STAR || typ == QUARTERSTAFF) || 922. (typ >= BARDICHE && typ <= VOULGE) || 923. (typ>=PLATE_MAIL && typ<=DRAGON_SCALE_MAIL) || 924. (typ == LARGE_SHIELD))) { 925. delobj(otmp); 926. } else newsym(x,y); 927. } 928. /* Whether or not it always makes a corpse is, in theory, 929. * different from whether or not the corpse is "special"; 930. * if we want both, we have to specify it explicitly. 931. */ 932. if (bigmonst(mdat) 933. #ifdef GOLEMS 934. || is_golem(mdat) 935. #endif 936. ) chance = 1; 937. else chance = !rn2((int) 938. (2 + ((mdat->geno & G_FREQ)<2) + verysmall(mdat))); 939. if (chance) 940. (void) make_corpse(mtmp); 941. } 942. } 943. 944. /*VARARGS2*/ 945. void 946. kludge(str, arg, arg2, arg3) 947. register char *str,*arg,*arg2,*arg3; 948. { 949. if(Blind || !flags.verbose) { 950. if(*str == '%') pline(str,"It",arg2,arg3); 951. else pline(str,"it",arg2,arg3); 952. } else pline(str,arg,arg2,arg3); 953. } 954. 955. void 956. rescham() { /* force all chameleons to become normal */ 957. 958. register struct monst *mtmp; 959. 960. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 961. if(mtmp->cham) { 962. mtmp->cham = 0; 963. (void) newcham(mtmp, &mons[PM_CHAMELEON]); 964. } 965. if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN) 966. (void) new_were(mtmp); 967. } 968. } 969. 970. /* Let the chameleons change again -dgk */ 971. void 972. restartcham() { 973. 974. register struct monst *mtmp; 975. 976. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) 977. if (mtmp->data->mlet == S_CHAMELEON) 978. mtmp->cham = 1; 979. } 980. 981. int 982. newcham(mtmp, mdat) /* make a chameleon look like a new monster */ 983. /* returns 1 if the monster actually changed */ 984. register struct monst *mtmp; 985. register struct permonst *mdat; 986. { 987. register int mhp, hpn, hpd; 988. int tryct; 989. 990. /* mdat = 0 -> caller wants a random monster shape */ 991. tryct = 0; 992. if(mdat == 0) { 993. while (++tryct < 100) { 994. static int num; 995. mdat = &mons[num=rn2(NUMMONS)]; 996. if ((!is_human(mdat) || num == PM_NURSE) 997. && !type_is_pname(mdat) 998. && !is_were(mdat) 999. #ifdef MEDUSA 1000. && num != PM_MEDUSA 1001. #endif 1002. #ifdef MAIL 1003. && num != PM_MAIL_DAEMON 1004. #endif 1005. ) 1006. break; 1007. } 1008. if (tryct >= 100) return(0); /* Should never happen */ 1009. } 1010. if(mdat == mtmp->data) return(0); /* still the same monster */ 1011. 1012. #ifdef WORM 1013. if(mtmp->wormno) wormdead(mtmp); /* throw tail away */ 1014. #endif 1015. mtmp->m_lev = adj_lev(mdat); /* new monster level */ 1016. 1017. hpn = mtmp->mhp; 1018. hpd = (mtmp->m_lev < 50) ? (mtmp->m_lev)*8 : mdat->mlevel; 1019. if(!hpd) hpd = 4; 1020. mhp = (mtmp->m_lev < 50) ? (mtmp->m_lev)*8 : mdat->mlevel; 1021. if(!mhp) mhp = 4; 1022. 1023. /* new hp: same fraction of max as before */ 1024. #ifndef LINT 1025. mtmp->mhp = (int)(((long)hpn*(long)mhp)/(long)hpd); 1026. #endif 1027. if(mtmp->mhp < 0) mtmp->mhp = hpn; /* overflow */ 1028. /* Unlikely but not impossible; a 1HD creature with 1HP that changes into a 1029. 0HD creature will require this statement */ 1030. if (!mtmp->mhp) mtmp->mhp = 1; 1031. 1032. /* and the same for maximum hit points */ 1033. hpn = mtmp->mhpmax; 1034. #ifndef LINT 1035. mtmp->mhpmax = (int)(((long)hpn*(long)mhp)/(long)hpd); 1036. #endif 1037. if(mtmp->mhpmax < 0) mtmp->mhpmax = hpn; /* overflow */ 1038. if (!mtmp->mhpmax) mtmp->mhpmax = 1; 1039. 1040. mtmp->data = mdat; 1041. mtmp->minvis = !!(mdat->mlet == S_STALKER); 1042. mtmp->mhide = !!hides_under(mdat); 1043. if (!mtmp->mhide) mtmp->mundetected = 0; 1044. if (u.ustuck == mtmp 1045. #ifdef POLYSELF 1046. && !sticks(uasmon) 1047. #endif 1048. && !sticks(mdat)) 1049. u.ustuck = 0; 1050. #ifdef WORM 1051. if(mdat == &mons[PM_LONG_WORM] && getwn(mtmp)) initworm(mtmp); 1052. /* perhaps we should clear mtmp->mtame here? */ 1053. #endif 1054. unpmon(mtmp); /* necessary for 'I' and to force pmon */ 1055. pmon(mtmp); 1056. return(1); 1057. } 1058. 1059. void 1060. mnexto(mtmp) /* Make monster mtmp next to you (if possible) */ 1061. struct monst *mtmp; 1062. { 1063. coord mm; 1064. enexto(&mm, u.ux, u.uy); 1065. levl[mtmp->mx][mtmp->my].mmask = 0; 1066. levl[mm.x][mm.y].mmask = 1; 1067. mtmp->mx = mm.x; 1068. mtmp->my = mm.y; 1069. pmon(mtmp); 1070. set_apparxy(mtmp); 1071. } 1072. 1073. void 1074. mnearto(mtmp,x,y,gz) /* Make monster near (or at) location if possible */ 1075. register struct monst *mtmp; 1076. xchar x, y; 1077. boolean gz; 1078. { 1079. coord mm; 1080. if(!gz || !goodpos(x,y)) { 1081. enexto(&mm, x, y); 1082. x = mm.x; y = mm.y; 1083. } 1084. if(x == mtmp->mx && y == mtmp->my) /* that was easy */ 1085. return; 1086. levl[mtmp->mx][mtmp->my].mmask = 0; 1087. levl[x][y].mmask = 1; 1088. mtmp->mx = x; 1089. mtmp->my = y; 1090. pmon(mtmp); 1091. set_apparxy(mtmp); 1092. } 1093. 1094. void 1095. setmangry(mtmp) 1096. register struct monst *mtmp; 1097. { 1098. if(!mtmp->mpeaceful) return; 1099. if(mtmp->mtame) return; 1100. mtmp->mpeaceful = 0; 1101. #if defined(ALTARS) && defined(THEOLOGY) 1102. if(mtmp->ispriest) { 1103. if(p_coaligned(mtmp)) adjalign(-5); /* very bad */ 1104. else adjalign(2); 1105. } else 1106. #endif 1107. adjalign(-1); /* attacking peaceful monsters is bad */ 1108. if(humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd) 1109. pline("%s gets angry!", Monnam(mtmp)); 1110. #ifdef SOUNDS 1111. else if (flags.verbose && flags.soundok) growl(mtmp); 1112. #endif 1113. } 1114. 1115. int 1116. disturb(mtmp) /* awaken monsters while in the same room. 1117. * return a 1 if they have been woken. 1118. */ 1119. register struct monst *mtmp; 1120. { 1121. /* wake up, or get out of here. */ 1122. /* ettins are hard to surprise */ 1123. /* Nymphs and Leprechauns do not easily wake up */ 1124. if(cansee(mtmp->mx,mtmp->my) && 1125. (!Stealth || (mtmp->data == &mons[PM_ETTIN] && rn2(10))) && 1126. (!(mtmp->data->mlet == S_NYMPH 1127. || mtmp->data->mlet == S_LEPRECHAUN) || !rn2(50)) && 1128. (Aggravate_monster || 1129. (mtmp->data->mlet == S_DOG || mtmp->data->mlet == S_HUMAN) || 1130. (!rn2(7) && !mtmp->mimic))) { 1131. mtmp->msleep = 0; 1132. return(1); 1133. } 1134. if(Hallucination) pmon(mtmp); 1135. return(0); 1136. } 1137. 1138. #ifdef HARD 1139. static boolean 1140. restrap(mtmp) 1141. /* unwatched hiders may hide again, 1142. * if so, a 1 is returned. 1143. */ 1144. register struct monst *mtmp; 1145. { 1146. if(mtmp->cham || mtmp->mcan || mtmp->mimic || 1147. cansee(mtmp->mx, mtmp->my) || rn2(3)) 1148. return(FALSE); 1149. 1150. if(mtmp->data->mlet == S_MIMIC) { 1151. set_mimic_sym(mtmp); 1152. return(TRUE); 1153. } else 1154. if(levl[mtmp->mx][mtmp->my].typ == ROOM) { 1155. (void) maketrap(mtmp->mx, mtmp->my, MONST_TRAP); 1156. /* override type selection */ 1157. ftrap->pm = monsndx(mtmp->data); 1158. mondead(mtmp); 1159. return(TRUE); 1160. } 1161. 1162. return(FALSE); 1163. } 1164. #endif 1165. 1166. /* drop (perhaps) a cadaver and remove monster */ 1167. void 1168. mondied(mdef) 1169. register struct monst *mdef; 1170. { 1171. mondead(mdef); 1172. if(rn2(3) 1173. #ifdef REINCARNATION 1174. && dlevel != rogue_level 1175. #endif 1176. ) 1177. (void) make_corpse(mdef); 1178. } 1179. 1180. /* monster disappears, not dies */ 1181. void 1182. mongone(mdef) 1183. register struct monst *mdef; 1184. { 1185. register struct obj *otmp, *otmp2; 1186. 1187. /* release monster's inventory */ 1188. for (otmp = mdef->minvent; otmp; otmp = otmp2) { 1189. otmp2 = otmp->nobj; 1190. obfree(otmp, (struct obj *)0); 1191. } 1192. mdef->minvent = 0; 1193. mdef->mgold = 0; 1194. m_detach(mdef); 1195. monfree(mdef); 1196. } 1197. 1198. /* drop a statue or rock and remove monster */ 1199. void 1200. monstone(mdef) 1201. register struct monst *mdef; 1202. { 1203. struct obj *otmp; 1204. 1205. if(!verysmall(mdef->data) || 1206. !rn2(2 + ((mdef->data->geno & G_FREQ) > 2))) { 1207. otmp = mk_named_object(STATUE, mdef->data, mdef->mx, mdef->my, 1208. NAME(mdef), (int)mdef->mnamelth); 1209. otmp->spe = 0; /* no book inside */ 1210. } else 1211. (void) mksobj_at(ROCK, mdef->mx, mdef->my); 1212. 1213. stackobj(fobj); 1214. 1215. if(cansee(mdef->mx, mdef->my)){ 1216. unpmon(mdef); 1217. atl(mdef->mx,mdef->my,Hallucination ? rndobjsym() : fobj->olet); 1218. } 1219. mondead(mdef); 1220. } 1221. 1222. #ifdef GOLEMS 1223. void 1224. golemeffects(mon, damtype, dam) 1225. register struct monst *mon; 1226. int damtype, dam; 1227. { 1228. int heal=0, slow=0; 1229. 1230. if (mon->data != &mons[PM_FLESH_GOLEM] 1231. && mon->data != &mons[PM_IRON_GOLEM]) 1232. return; 1233. 1234. if (mon->data == &mons[PM_FLESH_GOLEM]) { 1235. if (damtype == AD_ELEC) heal = dam / 6; 1236. else if (damtype == AD_FIRE || damtype == AD_COLD) slow = 1; 1237. } else { 1238. if (damtype == AD_ELEC) slow = 1; 1239. else if (damtype == AD_FIRE) heal = dam; 1240. } 1241. if (slow) { 1242. if (mon->mspeed != MSLOW) { 1243. if (mon->mspeed == MFAST) mon->mspeed = 0; 1244. else mon->mspeed = MSLOW; 1245. if (cansee(mon->mx, mon->my)) 1246. pline("%s seems to be moving slower.", 1247. Monnam(mon)); 1248. } 1249. } 1250. if (heal) { 1251. if (mon->mhp < mon->mhpmax) { 1252. mon->mhp += dam; 1253. if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 1254. if (cansee(mon->mx, mon->my)) 1255. pline("%s seems healthier.", Monnam(mon)); 1256. } 1257. } 1258. } 1259. #endif /* GOLEMS */