abstract
| - 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 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 */
|