Difference between revisions of "Source:SLASH'EM 0.0.7E7F2/mon.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (SLASH'EM 0.0.7E7F2/mon.c moved to Source:SLASH'EM 0.0.7E7F2/mon.c: Robot: moved page) |
(No difference)
|
Latest revision as of 19:21, 7 March 2008
Below is the full text to mon.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/mon.c#line123]], for example.
The latest source code for vanilla NetHack is at 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.4 2003/12/04 */ 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 "artifact.h" 14. #include "display.h" 15. #include "global.h" 16. 17. #include <ctype.h> 18. 19. void FDECL(display_monster,(XCHAR_P,XCHAR_P,struct monst *,int,XCHAR_P)); 20. 21. STATIC_DCL boolean FDECL(restrap,(struct monst *)); 22. STATIC_DCL long FDECL(mm_aggression, (struct monst *,struct monst *)); 23. #ifdef OVL2 24. STATIC_DCL int NDECL(pick_animal); 25. STATIC_DCL int FDECL(select_newcham_form, (struct monst *)); 26. STATIC_DCL void FDECL(kill_eggs, (struct obj *)); 27. #endif 28. 29. #ifdef REINCARNATION 30. #define LEVEL_SPECIFIC_NOCORPSE(mdat) \ 31. (Is_rogue_level(&u.uz) || \ 32. (level.flags.graveyard && is_undead(mdat) && \ 33. mdat != &mons[PM_VECNA] && rn2(3))) 34. #else 35. #define LEVEL_SPECIFIC_NOCORPSE(mdat) \ 36. (level.flags.graveyard && is_undead(mdat) && \ 37. mdat != &mons[PM_VECNA] && rn2(3)) 38. #endif 39. 40. 41. #if 0 42. /* part of the original warning code which was replaced in 3.3.1 */ 43. #ifdef OVL1 44. #define warnDelay 10 45. long lastwarntime; 46. int lastwarnlev; 47. 48. 49. STATIC_DCL void NDECL(warn_effects); 50. #endif /* OVL1 */ 51. #endif /* 0 */ 52. 53. #ifndef OVLB 54. STATIC_VAR short cham_to_pm[]; 55. #else 56. STATIC_DCL struct obj *FDECL(make_corpse,(struct monst *)); 57. STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *)); 58. STATIC_DCL void FDECL(lifesaved_monster, (struct monst *)); 59. static void FDECL(unpoly_monster, (struct monst *)); 60. 61. /* convert the monster index of an undead to its living counterpart */ 62. int 63. undead_to_corpse(mndx) 64. int mndx; 65. { 66. switch (mndx) { 67. case PM_KOBOLD_ZOMBIE: 68. case PM_KOBOLD_MUMMY: mndx = PM_KOBOLD; break; 69. case PM_DWARF_ZOMBIE: 70. case PM_DWARF_MUMMY: mndx = PM_DWARF; break; 71. case PM_GNOME_ZOMBIE: 72. case PM_GNOME_MUMMY: mndx = PM_GNOME; break; 73. case PM_ORC_ZOMBIE: 74. case PM_ORC_MUMMY: mndx = PM_ORC; break; 75. case PM_ELF_ZOMBIE: 76. case PM_ELF_MUMMY: mndx = PM_ELF; break; 77. case PM_VAMPIRE: 78. case PM_VAMPIRE_LORD: 79. case PM_VAMPIRE_MAGE: 80. case PM_HUMAN_ZOMBIE: 81. case PM_HUMAN_MUMMY: mndx = PM_HUMAN; break; 82. case PM_GIANT_ZOMBIE: 83. case PM_GIANT_MUMMY: mndx = PM_GIANT; break; 84. case PM_ETTIN_ZOMBIE: 85. case PM_ETTIN_MUMMY: mndx = PM_ETTIN; break; 86. case PM_TROLL_MUMMY: mndx = PM_TROLL; break; 87. default: break; 88. } 89. return mndx; 90. } 91. 92. /* Convert the monster index of some monsters (such as quest guardians) 93. * to their generic species type. 94. * 95. * Return associated character class monster, rather than species 96. * if mode is 1. 97. */ 98. int 99. genus(mndx, mode) 100. int mndx, mode; 101. { 102. switch (mndx) { 103. /* Quest guardians */ 104. case PM_STUDENT: mndx = mode ? PM_ARCHEOLOGIST : PM_HUMAN; break; 105. case PM_CHIEFTAIN: mndx = mode ? PM_BARBARIAN : PM_HUMAN; break; 106. case PM_NEANDERTHAL: mndx = mode ? PM_CAVEMAN : PM_HUMAN; break; 107. case PM_ATTENDANT: mndx = mode ? PM_HEALER : PM_HUMAN; break; 108. case PM_PAGE: mndx = mode ? PM_KNIGHT : PM_HUMAN; break; 109. case PM_ABBOT: mndx = mode ? PM_MONK : PM_HUMAN; break; 110. case PM_ACOLYTE: mndx = mode ? PM_PRIEST : PM_HUMAN; break; 111. case PM_HUNTER: mndx = mode ? PM_RANGER : PM_HUMAN; break; 112. case PM_THUG: mndx = mode ? PM_ROGUE : PM_HUMAN; break; 113. case PM_ROSHI: mndx = mode ? PM_SAMURAI : PM_HUMAN; break; 114. #ifdef TOURIST 115. case PM_GUIDE: mndx = mode ? PM_TOURIST : PM_HUMAN; break; 116. #endif 117. case PM_APPRENTICE: mndx = mode ? PM_WIZARD : PM_HUMAN; break; 118. case PM_WARRIOR: mndx = mode ? PM_VALKYRIE : PM_HUMAN; break; 119. default: 120. if (mndx >= LOW_PM && mndx < NUMMONS) { 121. struct permonst *ptr = &mons[mndx]; 122. if (is_human(ptr)) mndx = PM_HUMAN; 123. else if (is_elf(ptr)) mndx = PM_ELF; 124. else if (is_dwarf(ptr)) mndx = PM_DWARF; 125. else if (is_gnome(ptr)) mndx = PM_GNOME; 126. else if (is_orc(ptr)) mndx = PM_ORC; 127. } 128. break; 129. } 130. return mndx; 131. } 132. 133. /* convert monster index to chameleon index */ 134. int 135. pm_to_cham(mndx) 136. int mndx; 137. { 138. int mcham; 139. 140. switch (mndx) { 141. case PM_CHAMELEON: mcham = CHAM_CHAMELEON; break; 142. case PM_DOPPELGANGER: mcham = CHAM_DOPPELGANGER; break; 143. case PM_SANDESTIN: mcham = CHAM_SANDESTIN; break; 144. default: mcham = CHAM_ORDINARY; break; 145. } 146. return mcham; 147. } 148. 149. /* convert chameleon index to monster index */ 150. STATIC_VAR short cham_to_pm[] = { 151. NON_PM, /* placeholder for CHAM_ORDINARY */ 152. PM_CHAMELEON, 153. PM_DOPPELGANGER, 154. PM_SANDESTIN, 155. }; 156. 157. /* for deciding whether corpse or statue will carry along full monster data */ 158. #define KEEPTRAITS(mon) ((mon)->isshk || (mon)->isgyp || (mon)->mtame ||\ 159. ((mon)->data->geno & G_UNIQ) || \ 160. is_reviver((mon)->data) || \ 161. /* normally leader the will be unique, */ \ 162. /* but he might have been polymorphed */ \ 163. (mon)->m_id == quest_status.leader_m_id || \ 164. /* special cancellation handling for these */ \ 165. (dmgtype((mon)->data, AD_SEDU) || \ 166. dmgtype((mon)->data, AD_SSEX))) 167. 168. /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't 169. * leave corpses. Monsters which leave "special" corpses should have 170. * G_NOCORPSE set in order to prevent wishing for one, finding tins of one, 171. * etc.... 172. */ 173. STATIC_OVL struct obj * 174. make_corpse(mtmp) 175. register struct monst *mtmp; 176. { 177. register struct permonst *mdat = mtmp->data; 178. int num; 179. struct obj *obj = (struct obj *)0; 180. int x = mtmp->mx, y = mtmp->my; 181. int mndx = monsndx(mdat); 182. 183. switch(mndx) { 184. case PM_GRAY_DRAGON: 185. case PM_SILVER_DRAGON: 186. case PM_SHIMMERING_DRAGON: 187. case PM_DEEP_DRAGON: 188. case PM_RED_DRAGON: 189. case PM_ORANGE_DRAGON: 190. case PM_WHITE_DRAGON: 191. case PM_BLACK_DRAGON: 192. case PM_BLUE_DRAGON: 193. case PM_GREEN_DRAGON: 194. case PM_YELLOW_DRAGON: 195. /* Make dragon scales. This assumes that the order of the */ 196. /* dragons is the same as the order of the scales. */ 197. if (!rn2(mtmp->mrevived ? 20 : 3)) { 198. num = GRAY_DRAGON_SCALES + monsndx(mdat) - PM_GRAY_DRAGON; 199. obj = mksobj_at(num, x, y, FALSE, FALSE); 200. obj->spe = 0; 201. obj->cursed = obj->blessed = FALSE; 202. } 203. goto default_1; 204. 205. case PM_WHITE_UNICORN: 206. case PM_GRAY_UNICORN: 207. case PM_BLACK_UNICORN: 208. if (mtmp->mrevived && rn2(20)) { 209. if (canseemon(mtmp)) 210. pline("%s recently regrown horn crumbles to dust.", 211. s_suffix(Monnam(mtmp))); 212. } else 213. (void) mksobj_at(UNICORN_HORN, x, y, TRUE, FALSE); 214. goto default_1; 215. case PM_LONG_WORM: 216. (void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE); 217. goto default_1; 218. case PM_KILLER_TRIPE_RATION: 219. (void) mksobj_at(TRIPE_RATION, x, y, TRUE, FALSE); 220. newsym(x, y); 221. return (struct obj *)0; 222. case PM_KILLER_FOOD_RATION: 223. (void) mksobj_at(FOOD_RATION, x, y, TRUE, FALSE); 224. newsym(x, y); 225. return (struct obj *)0; 226. case PM_VAMPIRE: 227. case PM_VAMPIRE_LORD: 228. case PM_VAMPIRE_MAGE: 229. /* include mtmp in the mkcorpstat() call */ 230. num = undead_to_corpse(mndx); 231. obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, TRUE); 232. obj->age -= 100; /* this is an *OLD* corpse */ 233. break; 234. case PM_KOBOLD_MUMMY: 235. case PM_DWARF_MUMMY: 236. case PM_GNOME_MUMMY: 237. case PM_ORC_MUMMY: 238. case PM_ELF_MUMMY: 239. case PM_HUMAN_MUMMY: 240. case PM_GIANT_MUMMY: 241. case PM_ETTIN_MUMMY: 242. case PM_TROLL_MUMMY: 243. case PM_KOBOLD_ZOMBIE: 244. case PM_DWARF_ZOMBIE: 245. case PM_GNOME_ZOMBIE: 246. case PM_ORC_ZOMBIE: 247. case PM_ELF_ZOMBIE: 248. case PM_HUMAN_ZOMBIE: 249. case PM_GIANT_ZOMBIE: 250. case PM_ETTIN_ZOMBIE: 251. num = undead_to_corpse(mndx); 252. obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, TRUE); 253. obj->age -= 100; /* this is an *OLD* corpse */ 254. break; 255. case PM_WIGHT: 256. case PM_GHOUL: 257. case PM_GHAST: 258. case PM_FRANKENSTEIN_S_MONSTER: 259. obj = mkcorpstat(CORPSE, (struct monst *)0, &mons[mndx], x, y, TRUE); 260. obj->age -= 100; /* this is an *OLD* corpse */ 261. break; 262. case PM_MEDUSA: { 263. struct monst *mtmp2; 264. 265. 266. /* KMH -- the legend of Medusa and Pegasus */ 267. /* Only when Medusa leaves a corpse */ 268. mtmp2 = makemon(&mons[PM_PEGASUS], x, y, 0); 269. if (mtmp2) { 270. You("%s something spring forth from the corpse of %s.", 271. Blind ? "sense" : "see", mon_nam(mtmp)); 272. mtmp2->mpeaceful = 1; 273. mtmp2->mtame = 0; 274. } 275. goto default_1; 276. } 277. case PM_NIGHTMARE: 278. pline("All that remains is her horn..."); 279. obj = oname(mksobj(UNICORN_HORN, TRUE, FALSE), 280. artiname(ART_NIGHTHORN)); 281. goto initspecial; 282. case PM_BEHOLDER: 283. pline("All that remains is a single eye..."); 284. obj = oname(mksobj(EYEBALL, TRUE, FALSE), 285. artiname(ART_EYE_OF_THE_BEHOLDER)); 286. goto initspecial; 287. case PM_VECNA: 288. pline("All that remains is a hand..."); 289. obj = oname(mksobj(SEVERED_HAND, TRUE, FALSE), 290. artiname(ART_HAND_OF_VECNA)); 291. initspecial: 292. obj->quan = 1; 293. curse(obj); 294. place_object(obj, x, y); 295. stackobj(obj); 296. newsym(x, y); 297. return obj; 298. break; 299. case PM_IRON_GOLEM: 300. num = d(2,6); 301. while (num--) 302. obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE); 303. mtmp->mnamelth = 0; 304. break; 305. case PM_GLASS_GOLEM: 306. num = d(2,4); /* very low chance of creating all glass gems */ 307. while (num--) 308. obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE); 309. mtmp->mnamelth = 0; 310. break; 311. case PM_RUBY_GOLEM: 312. /* [DS] Mik's original Lethe fobbed off the player with coloured 313. * glass even for the higher golems. We'll play fair here - if 314. * you can kill one of these guys, you deserve the gems. */ 315. num = d(2,4); 316. while (num--) 317. obj = mksobj_at(RUBY, x, y, TRUE, FALSE); 318. mtmp->mnamelth = 0; 319. break; 320. case PM_DIAMOND_GOLEM: 321. num = d(2,4); 322. while (num--) 323. obj = mksobj_at(DIAMOND, x, y, TRUE, FALSE); 324. mtmp->mnamelth = 0; 325. break; 326. case PM_SAPPHIRE_GOLEM: 327. num = d(2,4); 328. while (num--) 329. obj = mksobj_at(SAPPHIRE, x, y, TRUE, FALSE); 330. mtmp->mnamelth = 0; 331. break; 332. case PM_STEEL_GOLEM: 333. num = d(2,6); 334. /* [DS] Add steel chains (or handcuffs!) for steel golems? */ 335. while (num--) 336. obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE); 337. mtmp->mnamelth = 0; 338. break; 339. case PM_CRYSTAL_GOLEM: 340. /* [DS] Generate gemstones of various hues */ 341. num = d(2,4); 342. { 343. int gemspan = LAST_GEM - bases[GEM_CLASS] + 1; 344. while (num--) 345. obj = mksobj_at(bases[GEM_CLASS] + rn2(gemspan), x, y, 346. TRUE, FALSE); 347. mtmp->mnamelth = 0; 348. } 349. break; 350. case PM_CLAY_GOLEM: 351. obj = mksobj_at(ROCK, x, y, FALSE, FALSE); 352. obj->quan = (long)(rn2(20) + 50); 353. obj->owt = weight(obj); 354. mtmp->mnamelth = 0; 355. break; 356. case PM_STONE_GOLEM: 357. obj = mkcorpstat(STATUE, (struct monst *)0, 358. mdat, x, y, FALSE); 359. break; 360. case PM_WOOD_GOLEM: 361. num = d(2,4); 362. while(num--) 363. obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE); 364. mtmp->mnamelth = 0; 365. break; 366. case PM_LEATHER_GOLEM: 367. num = d(2,4); 368. while(num--) 369. obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE); 370. mtmp->mnamelth = 0; 371. break; 372. case PM_WAX_GOLEM: 373. num = d(2,4); 374. while (num--) 375. obj = mksobj_at(WAX_CANDLE, x, y, TRUE, FALSE); 376. mtmp->mnamelth = 0; 377. break; 378. case PM_PLASTIC_GOLEM: 379. /* KMH -- Credit cards are #ifdef TOURIST */ 380. num = d(2,2); 381. while (num--) 382. obj = mksobj_at( 383. #ifdef TOURIST 384. CREDIT_CARD, 385. #else 386. FAKE_AMULET_OF_YENDOR, 387. #endif 388. x, y, TRUE, FALSE); 389. mtmp->mnamelth = 0; 390. break; 391. case PM_GOLD_GOLEM: 392. /* Good luck gives more coins */ 393. obj = mkgold((long)(200 - rnl(101)), x, y); 394. mtmp->mnamelth = 0; 395. break; 396. case PM_PAPER_GOLEM: 397. num = rnd(4); 398. while (num--) 399. obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE); 400. mtmp->mnamelth = 0; 401. break; 402. default_1: 403. default: 404. if (mvitals[mndx].mvflags & G_NOCORPSE) 405. return (struct obj *)0; 406. else /* preserve the unique traits of some creatures */ 407. obj = mkcorpstat(CORPSE, KEEPTRAITS(mtmp) ? mtmp : 0, 408. mdat, x, y, TRUE); 409. break; 410. } 411. /* All special cases should precede the G_NOCORPSE check */ 412. 413. /* if polymorph or undead turning has killed this monster, 414. prevent the same attack beam from hitting its corpse */ 415. if (flags.bypasses) bypass_obj(obj); 416. 417. if (mtmp->mnamelth) 418. obj = oname(obj, NAME(mtmp)); 419. 420. /* Avoid "It was hidden under a green mold corpse!" 421. * during Blind combat. An unseen monster referred to as "it" 422. * could be killed and leave a corpse. If a hider then hid 423. * underneath it, you could be told the corpse type of a 424. * monster that you never knew was there without this. 425. * The code in hitmu() substitutes the word "something" 426. * if the corpses obj->dknown is 0. 427. */ 428. if (Blind && !sensemon(mtmp)) obj->dknown = 0; 429. 430. #ifdef INVISIBLE_OBJECTS 431. /* Invisible monster ==> invisible corpse */ 432. obj->oinvis = mtmp->perminvis; 433. #endif 434. 435. stackobj(obj); 436. newsym(x, y); 437. return obj; 438. } 439. 440. #endif /* OVLB */ 441. #ifdef OVL1 442. 443. #if 0 444. /* part of the original warning code which was replaced in 3.3.1 */ 445. STATIC_OVL void 446. warn_effects() 447. { 448. register struct monst *mtmp; 449. int num_mon; 450. int warned_of; 451. 452. num_mon = 0; 453. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 454. if (!canseemon(mtmp) && !(mtmp->mpeaceful) && !(mtmp->mtame)) { 455. if (Warning && (!spec_ability(uwep,SPFX_WARN) || !spec_dbon(uwep,mtmp,1))) num_mon++; 456. else if (Undead_warning && is_undead(mtmp->data)) num_mon++; 457. else if (spec_ability(uwep,SPFX_WARN) && spec_dbon(uwep,mtmp,1)) num_mon++; 458. } 459. } 460. if (num_mon == 0) return; 461. /* num_mon is the # of monsters which could be warned against... 462. pick one at random... */ 463. warned_of = rn2(num_mon)+1; 464. mtmp = fmon; 465. num_mon = warned_of; 466. do { 467. if (!canseemon(mtmp) && !(mtmp->mpeaceful) && !(mtmp->mtame)) { 468. if (Warning && (!spec_ability(uwep,SPFX_WARN) || !spec_dbon(uwep,mtmp,1))) num_mon--; 469. else if (Undead_warning && is_undead(mtmp->data)) num_mon--; 470. else if (spec_ability(uwep,SPFX_WARN) && spec_dbon(uwep,mtmp,1)) num_mon--; 471. } 472. if (num_mon > 0) mtmp = mtmp->nmon; 473. } while (num_mon > 0); 474. display_monster(mtmp->mx,mtmp->my,mtmp,1,0); 475. lastwarnlev = warnlevel; 476. lastwarntime = moves; 477. /* warnlevel = 0;*/ 478. return; 479. } 480. #endif /* 0 */ 481. 482. /* check mtmp and water/lava for compatibility, 0 (survived), 1 (died) */ 483. int 484. minliquid(mtmp) 485. register struct monst *mtmp; 486. { 487. boolean inpool, inlava, infountain; 488. 489. inpool = is_pool(mtmp->mx,mtmp->my) && 490. !is_flyer(mtmp->data) && !is_floater(mtmp->data); 491. inlava = is_lava(mtmp->mx,mtmp->my) && 492. !is_flyer(mtmp->data) && !is_floater(mtmp->data); 493. infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ); 494. 495. #ifdef STEED 496. /* Flying and levitation keeps our steed out of the liquid */ 497. /* (but not water-walking or swimming) */ 498. if (mtmp == u.usteed && (Flying || Levitation)) 499. return (0); 500. #endif 501. 502. /* Gremlin multiplying won't go on forever since the hit points 503. * keep going down, and when it gets to 1 hit point the clone 504. * function will fail. 505. */ 506. if (mtmp->data == &mons[PM_GREMLIN] && (inpool || infountain) && rn2(3)) { 507. if (split_mon(mtmp, (struct monst *)0)) 508. dryup(mtmp->mx, mtmp->my, FALSE); 509. if (inpool) water_damage(mtmp->minvent, FALSE, FALSE); 510. return (0); 511. } else if (mtmp->data == &mons[PM_IRON_GOLEM] && inpool && !rn2(5)) { 512. int dam = d(2,6); 513. if (cansee(mtmp->mx,mtmp->my)) 514. pline("%s rusts.", Monnam(mtmp)); 515. mtmp->mhp -= dam; 516. if (mtmp->mhpmax > dam) mtmp->mhpmax -= dam; 517. if (mtmp->mhp < 1) { 518. mondead(mtmp); 519. if (mtmp->mhp < 1) return (1); 520. } 521. water_damage(mtmp->minvent, FALSE, FALSE); 522. return (0); 523. } 524. 525. if (inlava) { 526. /* 527. * Lava effects much as water effects. Lava likers are able to 528. * protect their stuff. Fire resistant monsters can only protect 529. * themselves --ALI 530. */ 531. if (!is_clinger(mtmp->data) && !likes_lava(mtmp->data)) { 532. if (!resists_fire(mtmp)) { 533. if (cansee(mtmp->mx,mtmp->my)) 534. pline("%s %s.", Monnam(mtmp), 535. mtmp->data == &mons[PM_WATER_ELEMENTAL] ? 536. "boils away" : "burns to a crisp"); 537. mondead(mtmp); 538. } 539. else { 540. if (--mtmp->mhp < 1) { 541. if (cansee(mtmp->mx,mtmp->my)) 542. pline("%s surrenders to the fire.", Monnam(mtmp)); 543. mondead(mtmp); 544. } 545. else if (cansee(mtmp->mx,mtmp->my)) 546. pline("%s burns slightly.", Monnam(mtmp)); 547. } 548. if (mtmp->mhp > 0) { 549. (void) fire_damage(mtmp->minvent, FALSE, FALSE, 550. mtmp->mx, mtmp->my); 551. (void) rloc(mtmp, FALSE); 552. return 0; 553. } 554. return (1); 555. } 556. } else if (inpool) { 557. /* Most monsters drown in pools. flooreffects() will take care of 558. * water damage to dead monsters' inventory, but survivors need to 559. * be handled here. Swimmers are able to protect their stuff... 560. */ 561. if (!is_clinger(mtmp->data) 562. && !is_swimmer(mtmp->data) && !amphibious(mtmp->data)) { 563. if (cansee(mtmp->mx,mtmp->my)) { 564. pline("%s drowns.", Monnam(mtmp)); 565. } 566. if (u.ustuck && u.uswallow && u.ustuck == mtmp) { 567. /* This can happen after a purple worm plucks you off a 568. flying steed while you are over water. */ 569. pline("%s sinks as water rushes in and flushes you out.", 570. Monnam(mtmp)); 571. } 572. mondead(mtmp); 573. if (mtmp->mhp > 0) { 574. (void) rloc(mtmp, FALSE); 575. water_damage(mtmp->minvent, FALSE, FALSE); 576. return 0; 577. } 578. return (1); 579. } 580. } else { 581. /* but eels have a difficult time outside */ 582. if (mtmp->data->mlet == S_EEL && !Is_waterlevel(&u.uz)) { 583. if(mtmp->mhp > 1) mtmp->mhp--; 584. monflee(mtmp, 2, FALSE, FALSE); 585. } 586. } 587. return (0); 588. } 589. 590. int 591. mcalcmove(mon) 592. struct monst *mon; 593. { 594. int mmove = mon->data->mmove; 595. 596. /* Note: MSLOW's `+ 1' prevents slowed speed 1 getting reduced to 0; 597. * MFAST's `+ 2' prevents hasted speed 1 from becoming a no-op; 598. * both adjustments have negligible effect on higher speeds. 599. */ 600. if (mon->mspeed == MSLOW) 601. mmove = (2 * mmove + 1) / 3; 602. else if (mon->mspeed == MFAST) 603. mmove = (4 * mmove + 2) / 3; 604. 605. #ifdef STEED 606. if (mon == u.usteed) { 607. if (u.ugallop && flags.mv) { 608. /* average movement is 1.50 times normal */ 609. mmove = ((rn2(2) ? 4 : 5) * mmove) / 3; 610. } 611. } 612. #endif 613. 614. return mmove; 615. } 616. 617. /* actions that happen once per ``turn, regardless of each 618. individual monster's metabolism; some of these might need to 619. be reclassified to occur more in proportion with movement rate */ 620. void 621. mcalcdistress() 622. { 623. struct monst *mtmp; 624. 625. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 626. if (DEADMONSTER(mtmp)) continue; 627. 628. /* must check non-moving monsters once/turn in case 629. * they managed to end up in liquid */ 630. if (mtmp->data->mmove == 0) { 631. if (vision_full_recalc) vision_recalc(0); 632. if (minliquid(mtmp)) continue; 633. } 634. 635. /* regenerate hit points */ 636. mon_regen(mtmp, FALSE); 637. 638. /* possibly polymorph shapechangers and lycanthropes */ 639. if (mtmp->cham && !rn2(6)) 640. (void) mon_spec_poly(mtmp, (struct permonst *)0, 0L, FALSE, 641. cansee(mtmp->mx,mtmp->my) && flags.verbose, FALSE, FALSE); 642. were_change(mtmp); 643. 644. /* gradually time out temporary problems */ 645. if (mtmp->mblinded && !--mtmp->mblinded) 646. mtmp->mcansee = 1; 647. if (mtmp->mfrozen && !--mtmp->mfrozen) 648. mtmp->mcanmove = 1; 649. if (mtmp->mfleetim && !--mtmp->mfleetim) 650. mtmp->mflee = 0; 651. 652. /* FIXME: mtmp->mlstmv ought to be updated here */ 653. } 654. } 655. 656. int 657. movemon() 658. { 659. register struct monst *mtmp, *nmtmp; 660. register boolean somebody_can_move = FALSE; 661. 662. #if 0 663. /* part of the original warning code which was replaced in 3.3.1 */ 664. warnlevel = 0; 665. #endif 666. 667. /* 668. Some of you may remember the former assertion here that 669. because of deaths and other actions, a simple one-pass 670. algorithm wasn't possible for movemon. Deaths are no longer 671. removed to the separate list fdmon; they are simply left in 672. the chain with hit points <= 0, to be cleaned up at the end 673. of the pass. 674. 675. The only other actions which cause monsters to be removed from 676. the chain are level migrations and losedogs(). I believe losedogs() 677. is a cleanup routine not associated with monster movements, and 678. monsters can only affect level migrations on themselves, not others 679. (hence the fetching of nmon before moving the monster). Currently, 680. monsters can jump into traps, read cursed scrolls of teleportation, 681. and drink cursed potions of raise level to change levels. These are 682. all reflexive at this point. Should one monster be able to level 683. teleport another, this scheme would have problems. 684. */ 685. 686. for(mtmp = fmon; mtmp; mtmp = nmtmp) { 687. nmtmp = mtmp->nmon; 688. 689. /* Find a monster that we have not treated yet. */ 690. if(DEADMONSTER(mtmp)) 691. continue; 692. if(mtmp->movement < NORMAL_SPEED) 693. continue; 694. 695. mtmp->movement -= NORMAL_SPEED; 696. if (mtmp->movement >= NORMAL_SPEED) 697. somebody_can_move = TRUE; 698. 699. if (vision_full_recalc) vision_recalc(0); /* vision! */ 700. 701. if (minliquid(mtmp)) continue; 702. 703. if (is_hider(mtmp->data)) { 704. /* unwatched mimics and piercers may hide again [MRS] */ 705. if(restrap(mtmp)) continue; 706. if(mtmp->m_ap_type == M_AP_FURNITURE || 707. mtmp->m_ap_type == M_AP_OBJECT) 708. continue; 709. if(mtmp->mundetected) continue; 710. } 711. 712. /* continue if the monster died fighting */ 713. if (Conflict && !mtmp->iswiz && mtmp->mcansee) { 714. /* Note: 715. * Conflict does not take effect in the first round. 716. * Therefore, A monster when stepping into the area will 717. * get to swing at you. 718. * 719. * The call to fightm() must be _last_. The monster might 720. * have died if it returns 1. 721. */ 722. if (couldsee(mtmp->mx,mtmp->my) && 723. (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) && 724. fightm(mtmp)) 725. continue; /* mon might have died */ 726. } 727. if(dochugw(mtmp)) /* otherwise just move the monster */ 728. continue; 729. } 730. #if 0 731. /* part of the original warning code which was replaced in 3.3.1 */ 732. if(warnlevel > 0) 733. warn_effects(); 734. #endif 735. if (any_light_source()) 736. vision_full_recalc = 1; /* in case a mon moved with a light source */ 737. dmonsfree(); /* remove all dead monsters */ 738. 739. /* a monster may have levteleported player -dlc */ 740. if (u.utotype) { 741. deferred_goto(); 742. /* changed levels, so these monsters are dormant */ 743. somebody_can_move = FALSE; 744. } 745. 746. return somebody_can_move; 747. } 748. 749. #endif /* OVL1 */ 750. #ifdef OVLB 751. 752. #define mstoning(obj) (ofood(obj) && \ 753. (touch_petrifies(&mons[(obj)->corpsenm]) || \ 754. (obj)->corpsenm == PM_MEDUSA)) 755. 756. /* 757. * Maybe eat a metallic object (not just gold). 758. * Return value: 0 => nothing happened, 1 => monster ate something, 759. * 2 => monster died (it must have grown into a genocided form, but 760. * that can't happen at present because nothing which eats objects 761. * has young and old forms). 762. */ 763. int 764. meatmetal(mtmp) 765. register struct monst *mtmp; 766. { 767. register struct obj *otmp; 768. struct permonst *ptr; 769. int poly, grow, heal, mstone; 770. 771. /* If a pet, eating is handled separately, in dog.c */ 772. if (mtmp->mtame) return 0; 773. 774. /* Eats topmost metal object if it is there */ 775. for (otmp = level.objects[mtmp->mx][mtmp->my]; 776. otmp; otmp = otmp->nexthere) { 777. if (mtmp->data == &mons[PM_RUST_MONSTER] && !is_rustprone(otmp)) 778. continue; 779. if (is_metallic(otmp) && !obj_resists(otmp, 5, 95) && 780. touch_artifact(otmp,mtmp)) { 781. if (mtmp->data == &mons[PM_RUST_MONSTER] && otmp->oerodeproof) { 782. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) { 783. pline("%s eats %s!", 784. Monnam(mtmp), 785. distant_name(otmp,doname)); 786. } 787. /* The object's rustproofing is gone now */ 788. otmp->oerodeproof = 0; 789. mtmp->mstun = 1; 790. if (canseemon(mtmp) && flags.verbose) { 791. pline("%s spits %s out in disgust!", 792. Monnam(mtmp), distant_name(otmp,doname)); 793. } 794. /* KMH -- Don't eat indigestible/choking objects */ 795. } else if (otmp->otyp != AMULET_OF_STRANGULATION && 796. otmp->otyp != RIN_SLOW_DIGESTION) { 797. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 798. pline("%s eats %s!", Monnam(mtmp), 799. distant_name(otmp,doname)); 800. else if (flags.soundok && flags.verbose) 801. You_hear("a crunching sound."); 802. mtmp->meating = otmp->owt/2 + 1; 803. /* Heal up to the object's weight in hp */ 804. if (mtmp->mhp < mtmp->mhpmax) { 805. mtmp->mhp += objects[otmp->otyp].oc_weight; 806. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; 807. } 808. if(otmp == uball) { 809. unpunish(); 810. delobj(otmp); 811. } else if (otmp == uchain) { 812. unpunish(); /* frees uchain */ 813. } else { 814. poly = polyfodder(otmp); 815. grow = mlevelgain(otmp); 816. heal = mhealup(otmp); 817. mstone = mstoning(otmp); 818. delobj(otmp); 819. ptr = mtmp->data; 820. if (poly) { 821. if (mon_spec_poly(mtmp, 822. (struct permonst *)0, 0L, FALSE, 823. cansee(mtmp->mx,mtmp->my) && flags.verbose, 824. FALSE, FALSE)) 825. ptr = mtmp->data; 826. } else if (grow) { 827. ptr = grow_up(mtmp, (struct monst *)0); 828. } else if (mstone) { 829. if (poly_when_stoned(ptr)) { 830. mon_to_stone(mtmp); 831. ptr = mtmp->data; 832. } else if (!resists_ston(mtmp)) { 833. if (canseemon(mtmp)) 834. pline("%s turns to stone!", Monnam(mtmp)); 835. monstone(mtmp); 836. ptr = (struct permonst *)0; 837. } 838. } else if (heal) { 839. mtmp->mhp = mtmp->mhpmax; 840. } 841. if (!ptr) return 2; /* it died */ 842. } 843. /* Left behind a pile? */ 844. if (rnd(25) < 3) 845. (void) mksobj_at(ROCK, mtmp->mx, mtmp->my, TRUE, FALSE); 846. newsym(mtmp->mx, mtmp->my); 847. return 1; 848. } 849. } 850. } 851. return 0; 852. } 853. 854. void 855. meatcorpse(mtmp) 856. register struct monst *mtmp; 857. { 858. register struct obj *otmp; 859. 860. /* If a pet, eating is handled separately, in dog.c */ 861. if (mtmp->mtame) return; 862. 863. /* Eats topmost corpse if it is there */ 864. for (otmp = level.objects[mtmp->mx][mtmp->my]; 865. otmp; otmp = otmp->nexthere) 866. if (otmp->otyp == CORPSE && 867. otmp->age+50 <= monstermoves) { 868. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 869. pline("%s eats %s!", Monnam(mtmp), 870. distant_name(otmp,doname)); 871. else if (flags.soundok && flags.verbose) 872. You("hear an awful gobbling noise!"); 873. mtmp->meating = 2; 874. delobj(otmp); 875. break; /* only eat one at a time... */ 876. } 877. newsym(mtmp->mx, mtmp->my); 878. } 879. 880. int 881. meatobj(mtmp) /* for gelatinous cubes */ 882. register struct monst *mtmp; 883. { 884. register struct obj *otmp, *otmp2; 885. struct permonst *ptr; 886. int poly, grow, heal, count = 0, ecount = 0; 887. char buf[BUFSZ]; 888. 889. buf[0] = '\0'; 890. /* If a pet, eating is handled separately, in dog.c */ 891. if (mtmp->mtame) return 0; 892. 893. /* Eats organic objects, including cloth and wood, if there */ 894. /* Engulfs others, except huge rocks and metal attached to player */ 895. for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) { 896. otmp2 = otmp->nexthere; 897. if (is_organic(otmp) && !obj_resists(otmp, 5, 95) && 898. touch_artifact(otmp,mtmp)) { 899. if (otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) && 900. !resists_ston(mtmp)) 901. continue; 902. if (otmp->otyp == AMULET_OF_STRANGULATION || 903. otmp->otyp == RIN_SLOW_DIGESTION) 904. continue; 905. ++count; 906. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 907. pline("%s eats %s!", Monnam(mtmp), 908. distant_name(otmp, doname)); 909. else if (flags.soundok && flags.verbose) 910. You_hear("a slurping sound."); 911. /* Heal up to the object's weight in hp */ 912. if (mtmp->mhp < mtmp->mhpmax) { 913. mtmp->mhp += objects[otmp->otyp].oc_weight; 914. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; 915. } 916. if (Has_contents(otmp)) { 917. register struct obj *otmp3; 918. /* contents of eaten containers become engulfed; this 919. is arbitrary, but otherwise g.cubes are too powerful */ 920. while ((otmp3 = otmp->cobj) != 0) { 921. obj_extract_self(otmp3); 922. if (otmp->otyp == ICE_BOX && otmp3->otyp == CORPSE) { 923. otmp3->age = monstermoves - otmp3->age; 924. start_corpse_timeout(otmp3); 925. } 926. (void) mpickobj(mtmp, otmp3); 927. } 928. } 929. poly = polyfodder(otmp); 930. grow = mlevelgain(otmp); 931. heal = mhealup(otmp); 932. delobj(otmp); /* munch */ 933. ptr = mtmp->data; 934. if (poly) { 935. if (mon_spec_poly(mtmp, (struct permonst *)0, 0L, FALSE, 936. cansee(mtmp->mx,mtmp->my) && flags.verbose, 937. FALSE, FALSE)) 938. ptr = mtmp->data; 939. } else if (grow) { 940. ptr = grow_up(mtmp, (struct monst *)0); 941. } else if (heal) { 942. mtmp->mhp = mtmp->mhpmax; 943. } 944. /* in case it polymorphed or died */ 945. if (ptr != &mons[PM_GELATINOUS_CUBE]) 946. return !ptr ? 2 : 1; 947. } else if (otmp->oclass != ROCK_CLASS && 948. otmp != uball && otmp != uchain) { 949. ++ecount; 950. if (ecount == 1) { 951. Sprintf(buf, "%s engulfs %s.", Monnam(mtmp), 952. distant_name(otmp,doname)); 953. } else if (ecount == 2) 954. Sprintf(buf, "%s engulfs several objects.", Monnam(mtmp)); 955. obj_extract_self(otmp); 956. (void) mpickobj(mtmp, otmp); /* slurp */ 957. } 958. /* Engulf & devour is instant, so don't set meating */ 959. if (mtmp->minvis) newsym(mtmp->mx, mtmp->my); 960. } 961. if (ecount > 0) { 962. if (cansee(mtmp->mx, mtmp->my) && flags.verbose && buf[0]) 963. pline("%s", buf); 964. else if (flags.soundok && flags.verbose) 965. You_hear("%s slurping sound%s.", 966. ecount == 1 ? "a" : "several", 967. ecount == 1 ? "" : "s"); 968. } 969. return ((count > 0) || (ecount > 0)) ? 1 : 0; 970. } 971. 972. void 973. mpickgold(mtmp) 974. register struct monst *mtmp; 975. { 976. register struct obj *gold; 977. int mat_idx; 978. 979. if ((gold = g_at(mtmp->mx, mtmp->my)) != 0) { 980. mat_idx = objects[gold->otyp].oc_material; 981. #ifndef GOLDOBJ 982. mtmp->mgold += gold->quan; 983. delobj(gold); 984. #else 985. obj_extract_self(gold); 986. add_to_minv(mtmp, gold); 987. #endif 988. if (cansee(mtmp->mx, mtmp->my) ) { 989. if (flags.verbose && !mtmp->isgd) 990. pline("%s picks up some %s.", Monnam(mtmp), 991. mat_idx == GOLD ? "gold" : "money"); 992. newsym(mtmp->mx, mtmp->my); 993. } 994. } 995. } 996. #endif /* OVLB */ 997. #ifdef OVL2 998. 999. boolean 1000. mpickstuff(mtmp, str) 1001. register struct monst *mtmp; 1002. register const char *str; 1003. { 1004. register struct obj *otmp, *otmp2; 1005. 1006. /* prevent shopkeepers from leaving the door of their shop */ 1007. if(mtmp->isshk && inhishop(mtmp)) return FALSE; 1008. 1009. for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) { 1010. otmp2 = otmp->nexthere; 1011. /* Nymphs take everything. Most monsters don't pick up corpses. */ 1012. if (!str ? searches_for_item(mtmp,otmp) : 1013. !!(index(str, otmp->oclass))) { 1014. if (otmp->otyp == CORPSE && mtmp->data->mlet != S_NYMPH && 1015. /* let a handful of corpse types thru to can_carry() */ 1016. !touch_petrifies(&mons[otmp->corpsenm]) && 1017. otmp->corpsenm != PM_LIZARD && 1018. !acidic(&mons[otmp->corpsenm])) continue; 1019. if (!touch_artifact(otmp,mtmp)) continue; 1020. if (!can_carry(mtmp,otmp)) continue; 1021. if (is_pool(mtmp->mx,mtmp->my)) continue; 1022. #ifdef INVISIBLE_OBJECTS 1023. if (otmp->oinvis && !perceives(mtmp->data)) continue; 1024. #endif 1025. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 1026. pline("%s picks up %s.", Monnam(mtmp), 1027. (distu(mtmp->mx, mtmp->my) <= 5) ? 1028. doname(otmp) : distant_name(otmp, doname)); 1029. obj_extract_self(otmp); 1030. /* unblock point after extract, before pickup */ 1031. if (otmp->otyp == BOULDER) 1032. unblock_point(otmp->ox,otmp->oy); /* vision */ 1033. (void) mpickobj(mtmp, otmp); /* may merge and free otmp */ 1034. m_dowear(mtmp, FALSE); 1035. newsym(mtmp->mx, mtmp->my); 1036. return TRUE; /* pick only one object */ 1037. } 1038. } 1039. return FALSE; 1040. } 1041. 1042. #endif /* OVL2 */ 1043. #ifdef OVL0 1044. 1045. int 1046. curr_mon_load(mtmp) 1047. register struct monst *mtmp; 1048. { 1049. register int curload = 0; 1050. register struct obj *obj; 1051. 1052. for(obj = mtmp->minvent; obj; obj = obj->nobj) { 1053. if(obj->otyp != BOULDER || !throws_rocks(mtmp->data)) 1054. curload += obj->owt; 1055. } 1056. 1057. return curload; 1058. } 1059. 1060. int 1061. max_mon_load(mtmp) 1062. register struct monst *mtmp; 1063. { 1064. register long maxload; 1065. 1066. /* Base monster carrying capacity is equal to human maximum 1067. * carrying capacity, or half human maximum if not strong. 1068. * (for a polymorphed player, the value used would be the 1069. * non-polymorphed carrying capacity instead of max/half max). 1070. * This is then modified by the ratio between the monster weights 1071. * and human weights. Corpseless monsters are given a capacity 1072. * proportional to their size instead of weight. 1073. */ 1074. if (!mtmp->data->cwt) 1075. maxload = (MAX_CARR_CAP * (long)mtmp->data->msize) / MZ_HUMAN; 1076. else if (!strongmonst(mtmp->data) 1077. || (strongmonst(mtmp->data) && (mtmp->data->cwt > WT_HUMAN))) 1078. maxload = (MAX_CARR_CAP * (long)mtmp->data->cwt) / WT_HUMAN; 1079. else maxload = MAX_CARR_CAP; /*strong monsters w/cwt <= WT_HUMAN*/ 1080. 1081. if (!strongmonst(mtmp->data)) maxload /= 2; 1082. 1083. if (maxload < 1) maxload = 1; 1084. 1085. return (int) maxload; 1086. } 1087. 1088. /* for restricting monsters' object-pickup */ 1089. boolean 1090. can_carry(mtmp,otmp) 1091. struct monst *mtmp; 1092. struct obj *otmp; 1093. { 1094. int otyp = otmp->otyp, newload = otmp->owt; 1095. struct permonst *mdat = mtmp->data; 1096. 1097. if (notake(mdat)) return FALSE; /* can't carry anything */ 1098. 1099. if (otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) && 1100. !(mtmp->misc_worn_check & W_ARMG) && !resists_ston(mtmp)) 1101. return FALSE; 1102. if (otyp == CORPSE && is_rider(&mons[otmp->corpsenm])) 1103. return FALSE; 1104. if (objects[otyp].oc_material == SILVER && hates_silver(mdat) && 1105. (otyp != BELL_OF_OPENING || !is_covetous(mdat))) 1106. return FALSE; 1107. 1108. #ifdef STEED 1109. /* Steeds don't pick up stuff (to avoid shop abuse) */ 1110. if (mtmp == u.usteed) return (FALSE); 1111. #endif 1112. if (mtmp->isshk) return(TRUE); /* no limit */ 1113. if (mtmp->mpeaceful && !mtmp->mtame) return(FALSE); 1114. /* otherwise players might find themselves obligated to violate 1115. * their alignment if the monster takes something they need 1116. */ 1117. 1118. /* special--boulder throwers carry unlimited amounts of boulders */ 1119. if (throws_rocks(mdat) && otyp == BOULDER) 1120. return(TRUE); 1121. 1122. /* nymphs deal in stolen merchandise, but not boulders or statues */ 1123. if (mdat->mlet == S_NYMPH) 1124. return (boolean)(otmp->oclass != ROCK_CLASS); 1125. 1126. if (curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return FALSE; 1127. 1128. /* if the monster hates silver, don't pick it up */ 1129. if (objects[otmp->otyp].oc_material == SILVER && hates_silver(mtmp->data)) 1130. return(FALSE); 1131. 1132. if(curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return(FALSE); 1133. 1134. return(TRUE); 1135. } 1136. 1137. /* return number of acceptable neighbour positions */ 1138. int 1139. mfndpos(mon, poss, info, flag) 1140. register struct monst *mon; 1141. coord *poss; /* coord poss[9] */ 1142. long *info; /* long info[9] */ 1143. long flag; 1144. { 1145. struct permonst *mdat = mon->data; 1146. register xchar x,y,nx,ny; 1147. register int cnt = 0; 1148. register uchar ntyp; 1149. uchar nowtyp; 1150. boolean wantpool,poolok,lavaok,nodiag; 1151. boolean rockok = FALSE, treeok = FALSE, thrudoor; 1152. int maxx, maxy; 1153. 1154. x = mon->mx; 1155. y = mon->my; 1156. nowtyp = levl[x][y].typ; 1157. 1158. nodiag = (mdat == &mons[PM_GRID_BUG]); 1159. wantpool = mdat->mlet == S_EEL; 1160. poolok = is_flyer(mdat) || is_clinger(mdat) || 1161. (is_swimmer(mdat) && !wantpool); 1162. lavaok = is_flyer(mdat) || is_clinger(mdat) || likes_lava(mdat); 1163. thrudoor = ((flag & (ALLOW_WALL|BUSTDOOR)) != 0L); 1164. if (flag & ALLOW_DIG) { 1165. struct obj *mw_tmp; 1166. 1167. /* need to be specific about what can currently be dug */ 1168. if (!needspick(mdat)) { 1169. rockok = treeok = TRUE; 1170. } else if ((mw_tmp = MON_WEP(mon)) && mw_tmp->cursed && 1171. mon->weapon_check == NO_WEAPON_WANTED) { 1172. rockok = is_pick(mw_tmp); 1173. treeok = is_axe(mw_tmp); 1174. } else { 1175. rockok = (m_carrying(mon, PICK_AXE) || 1176. (m_carrying(mon, DWARVISH_MATTOCK) && 1177. !which_armor(mon, W_ARMS))); 1178. treeok = (m_carrying(mon, AXE) || 1179. (m_carrying(mon, BATTLE_AXE) && 1180. !which_armor(mon, W_ARMS))); 1181. } 1182. thrudoor |= rockok || treeok; 1183. } 1184. 1185. nexttry: /* eels prefer the water, but if there is no water nearby, 1186. they will crawl over land */ 1187. if(mon->mconf) { 1188. flag |= ALLOW_ALL; 1189. flag &= ~NOTONL; 1190. } 1191. if(!mon->mcansee) 1192. flag |= ALLOW_SSM; 1193. maxx = min(x+1,COLNO-1); 1194. maxy = min(y+1,ROWNO-1); 1195. for(nx = max(1,x-1); nx <= maxx; nx++) 1196. for(ny = max(0,y-1); ny <= maxy; ny++) { 1197. if(nx == x && ny == y) continue; 1198. if(IS_ROCK(ntyp = levl[nx][ny].typ) && 1199. !((flag & ALLOW_WALL) && may_passwall(nx,ny)) && 1200. !((IS_TREE(ntyp) ? treeok : rockok) && may_dig(nx,ny))) continue; 1201. /* KMH -- Added iron bars */ 1202. if (ntyp == IRONBARS && !(flag & ALLOW_BARS)) continue; 1203. /* ALI -- Artifact doors (no passage unless open/openable) */ 1204. if (IS_DOOR(ntyp)) 1205. if (artifact_door(nx, ny) ? 1206. levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR) 1207. || levl[nx][ny].doormask & D_LOCKED : 1208. !amorphous(mdat) && 1209. ((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) || 1210. (levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))) && 1211. !thrudoor) continue; 1212. if(nx != x && ny != y && (nodiag || 1213. #ifdef REINCARNATION 1214. ((IS_DOOR(nowtyp) && 1215. ((levl[x][y].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))) || 1216. (IS_DOOR(ntyp) && 1217. ((levl[nx][ny].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz)))) 1218. #else 1219. ((IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN)) || 1220. (IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN))) 1221. #endif 1222. )) 1223. continue; 1224. if((is_pool(nx,ny) == wantpool || poolok) && 1225. (lavaok || !is_lava(nx,ny))) { 1226. int dispx, dispy; 1227. boolean monseeu = (mon->mcansee && (!Invis || perceives(mdat))); 1228. boolean checkobj = OBJ_AT(nx,ny); 1229. 1230. /* Displacement also displaces the Elbereth/scare monster, 1231. * as long as you are visible. 1232. */ 1233. if(Displaced && monseeu && (mon->mux==nx) && (mon->muy==ny)) { 1234. dispx = u.ux; 1235. dispy = u.uy; 1236. } else { 1237. dispx = nx; 1238. dispy = ny; 1239. } 1240. 1241. info[cnt] = 0; 1242. if ((checkobj || Displaced) && onscary(dispx, dispy, mon)) { 1243. if(!(flag & ALLOW_SSM)) continue; 1244. info[cnt] |= ALLOW_SSM; 1245. } 1246. if((nx == u.ux && ny == u.uy) || 1247. (nx == mon->mux && ny == mon->muy)) { 1248. if (nx == u.ux && ny == u.uy) { 1249. /* If it's right next to you, it found you, 1250. * displaced or no. We must set mux and muy 1251. * right now, so when we return we can tell 1252. * that the ALLOW_U means to attack _you_ and 1253. * not the image. 1254. */ 1255. mon->mux = u.ux; 1256. mon->muy = u.uy; 1257. } 1258. if(!(flag & ALLOW_U)) continue; 1259. info[cnt] |= ALLOW_U; 1260. } else { 1261. if(MON_AT(nx, ny)) { 1262. struct monst *mtmp2 = m_at(nx, ny); 1263. long mmflag = flag | mm_aggression(mon, mtmp2); 1264. 1265. if (!(mmflag & ALLOW_M)) continue; 1266. info[cnt] |= ALLOW_M; 1267. if (mtmp2->mtame) { 1268. if (!(mmflag & ALLOW_TM)) continue; 1269. info[cnt] |= ALLOW_TM; 1270. } 1271. } 1272. /* Note: ALLOW_SANCT only prevents movement, not */ 1273. /* attack, into a temple. */ 1274. if(level.flags.has_temple && 1275. *in_rooms(nx, ny, TEMPLE) && 1276. !*in_rooms(x, y, TEMPLE) && 1277. in_your_sanctuary((struct monst *)0, nx, ny)) { 1278. if(!(flag & ALLOW_SANCT)) continue; 1279. info[cnt] |= ALLOW_SANCT; 1280. } 1281. } 1282. if(checkobj && sobj_at(CLOVE_OF_GARLIC, nx, ny)) { 1283. if(flag & NOGARLIC) continue; 1284. info[cnt] |= NOGARLIC; 1285. } 1286. if(checkobj && sobj_at(BOULDER, nx, ny)) { 1287. if(!(flag & ALLOW_ROCK)) continue; 1288. info[cnt] |= ALLOW_ROCK; 1289. } 1290. if (monseeu && onlineu(nx,ny)) { 1291. if(flag & NOTONL) continue; 1292. info[cnt] |= NOTONL; 1293. } 1294. if (nx != x && ny != y && bad_rock(mon, x, ny) 1295. && bad_rock(mon, nx, y) 1296. && (bigmonst(mdat) || (curr_mon_load(mon) > 600))) 1297. continue; 1298. /* The monster avoids a particular type of trap if it's familiar 1299. * with the trap type. Pets get ALLOW_TRAPS and checking is 1300. * done in dogmove.c. In either case, "harmless" traps are 1301. * neither avoided nor marked in info[]. 1302. */ 1303. { register struct trap *ttmp = t_at(nx, ny); 1304. if(ttmp) { 1305. if(ttmp->ttyp >= TRAPNUM || ttmp->ttyp == 0) { 1306. impossible("A monster looked at a very strange trap of type %d.", ttmp->ttyp); 1307. continue; 1308. } 1309. if ((ttmp->ttyp != RUST_TRAP 1310. || mdat == &mons[PM_FLAMING_SPHERE] 1311. || mdat == &mons[PM_IRON_GOLEM]) 1312. && ttmp->ttyp != STATUE_TRAP 1313. && ((ttmp->ttyp != PIT 1314. && ttmp->ttyp != SPIKED_PIT 1315. && ttmp->ttyp != TRAPDOOR 1316. && ttmp->ttyp != HOLE) 1317. || (!is_flyer(mdat) 1318. && !is_floater(mdat) 1319. && !is_clinger(mdat)) 1320. || In_sokoban(&u.uz)) 1321. && (ttmp->ttyp != SLP_GAS_TRAP || 1322. !resists_sleep(mon)) 1323. && (ttmp->ttyp != BEAR_TRAP || 1324. (mdat->msize > MZ_SMALL && 1325. !amorphous(mdat) && !is_flyer(mdat))) 1326. && (ttmp->ttyp != FIRE_TRAP || 1327. !resists_fire(mon)) 1328. && (ttmp->ttyp != SQKY_BOARD || !is_flyer(mdat)) 1329. && (ttmp->ttyp != WEB || (!amorphous(mdat) && 1330. !webmaker(mdat))) 1331. ) { 1332. if (!(flag & ALLOW_TRAPS)) { 1333. if (mon->mtrapseen & (1L << (ttmp->ttyp - 1))) 1334. continue; 1335. } 1336. info[cnt] |= ALLOW_TRAPS; 1337. } 1338. } 1339. } 1340. poss[cnt].x = nx; 1341. poss[cnt].y = ny; 1342. cnt++; 1343. } 1344. } 1345. if(!cnt && wantpool && !is_pool(x,y)) { 1346. wantpool = FALSE; 1347. goto nexttry; 1348. } 1349. return(cnt); 1350. } 1351. 1352. #endif /* OVL0 */ 1353. #ifdef OVL1 1354. 1355. /* Monster against monster special attacks; for the specified monster 1356. combinations, this allows one monster to attack another adjacent one 1357. in the absence of Conflict. There is no provision for targetting 1358. other monsters; just hand to hand fighting when they happen to be 1359. next to each other. */ 1360. STATIC_OVL long 1361. mm_aggression(magr, mdef) 1362. struct monst *magr, /* monster that is currently deciding where to move */ 1363. *mdef; /* another monster which is next to it */ 1364. { 1365. /* supposedly purple worms are attracted to shrieking because they 1366. like to eat shriekers, so attack the latter when feasible */ 1367. if (magr->data == &mons[PM_PURPLE_WORM] && 1368. mdef->data == &mons[PM_SHRIEKER]) 1369. return ALLOW_M|ALLOW_TM; 1370. 1371. /* elves vs. orcs */ 1372. if(magr->data->mflags2 & M2_ELF && mdef->data->mflags2 & M2_ORC) 1373. return ALLOW_M|ALLOW_TM; 1374. /* and vice versa */ 1375. if(mdef->data->mflags2 & M2_ELF && magr->data->mflags2 & M2_ORC) 1376. return ALLOW_M|ALLOW_TM; 1377. 1378. /* angels vs. demons */ 1379. if(magr->data->mlet==S_ANGEL && mdef->data->mflags2 & M2_DEMON) 1380. return ALLOW_M|ALLOW_TM; 1381. /* and vice versa */ 1382. if(mdef->data->mlet==S_ANGEL && magr->data->mflags2 & M2_DEMON) 1383. return ALLOW_M|ALLOW_TM; 1384. 1385. /* woodchucks vs. The Oracle */ 1386. if(magr->data == &mons[PM_WOODCHUCK] && mdef->data == &mons[PM_ORACLE]) 1387. return ALLOW_M|ALLOW_TM; 1388. 1389. return 0L; 1390. } 1391. 1392. boolean 1393. monnear(mon, x, y) 1394. register struct monst *mon; 1395. register int x,y; 1396. /* Is the square close enough for the monster to move or attack into? */ 1397. { 1398. register int distance = dist2(mon->mx, mon->my, x, y); 1399. if (distance==2 && mon->data==&mons[PM_GRID_BUG]) return 0; 1400. return((boolean)(distance < 3)); 1401. } 1402. 1403. /* really free dead monsters */ 1404. void 1405. dmonsfree() 1406. { 1407. struct monst **mtmp; 1408. int count = 0; 1409. 1410. for (mtmp = &fmon; *mtmp;) { 1411. if ((*mtmp)->mhp <= 0) { 1412. struct monst *freetmp = *mtmp; 1413. *mtmp = (*mtmp)->nmon; 1414. dealloc_monst(freetmp); 1415. count++; 1416. } else 1417. mtmp = &(*mtmp)->nmon; 1418. } 1419. 1420. if (count != iflags.purge_monsters) 1421. impossible("dmonsfree: %d removed doesn't match %d pending", 1422. count, iflags.purge_monsters); 1423. iflags.purge_monsters = 0; 1424. } 1425. 1426. #endif /* OVL1 */ 1427. #ifdef OVLB 1428. 1429. /* called when monster is moved to larger structure */ 1430. void 1431. replmon(mtmp, mtmp2) 1432. register struct monst *mtmp, *mtmp2; 1433. { 1434. struct obj *otmp; 1435. long unpolytime; /* WAC */ 1436. 1437. /* transfer the monster's inventory */ 1438. for (otmp = mtmp2->minvent; otmp; otmp = otmp->nobj) { 1439. #ifdef DEBUG 1440. if (otmp->where != OBJ_MINVENT || otmp->ocarry != mtmp) 1441. panic("replmon: minvent inconsistency"); 1442. #endif 1443. otmp->ocarry = mtmp2; 1444. } 1445. mtmp->minvent = 0; 1446. 1447. /* remove the old monster from the map and from `fmon' list */ 1448. relmon(mtmp); 1449. 1450. /* finish adding its replacement */ 1451. #ifdef STEED 1452. if (mtmp == u.usteed) ; else /* don't place steed onto the map */ 1453. #endif 1454. place_monster(mtmp2, mtmp2->mx, mtmp2->my); 1455. if (mtmp2->wormno) /* update level.monsters[wseg->wx][wseg->wy] */ 1456. place_wsegs(mtmp2); /* locations to mtmp2 not mtmp. */ 1457. if (emits_light(mtmp2->data)) { 1458. /* since this is so rare, we don't have any `mon_move_light_source' */ 1459. new_light_source(mtmp2->mx, mtmp2->my, 1460. emits_light(mtmp2->data), 1461. LS_MONSTER, (genericptr_t)mtmp2); 1462. /* here we rely on the fact that `mtmp' hasn't actually been deleted */ 1463. del_light_source(LS_MONSTER, (genericptr_t)mtmp); 1464. } 1465. /* If poly'ed, move polytimer along */ 1466. if (unpolytime = stop_timer(UNPOLY_MON, (genericptr_t) mtmp)) { 1467. (void) start_timer(unpolytime, TIMER_MONSTER, UNPOLY_MON, 1468. (genericptr_t) mtmp2); 1469. } 1470. mtmp2->nmon = fmon; 1471. fmon = mtmp2; 1472. if (u.ustuck == mtmp) setustuck(mtmp2); 1473. #ifdef STEED 1474. if (u.usteed == mtmp) u.usteed = mtmp2; 1475. #endif 1476. if (mtmp2->isshk) replshk(mtmp,mtmp2); 1477. 1478. /* discard the old monster */ 1479. dealloc_monst(mtmp); 1480. } 1481. 1482. /* release mon from display and monster list */ 1483. void 1484. relmon(mon) 1485. register struct monst *mon; 1486. { 1487. register struct monst *mtmp; 1488. 1489. if (fmon == (struct monst *)0) panic ("relmon: no fmon available."); 1490. 1491. remove_monster(mon->mx, mon->my); 1492. 1493. if(mon == fmon) fmon = fmon->nmon; 1494. else { 1495. for(mtmp = fmon; mtmp && mtmp->nmon != mon; mtmp = mtmp->nmon) ; 1496. if(mtmp) mtmp->nmon = mon->nmon; 1497. else panic("relmon: mon not in list."); 1498. } 1499. } 1500. 1501. /* remove effects of mtmp from other data structures */ 1502. STATIC_OVL void 1503. m_detach(mtmp, mptr) 1504. struct monst *mtmp; 1505. struct permonst *mptr; /* reflects mtmp->data _prior_ to mtmp's death */ 1506. { 1507. if (mtmp->mleashed) m_unleash(mtmp, FALSE); 1508. /* to prevent an infinite relobj-flooreffects-hmon-killed loop */ 1509. mtmp->mtrapped = 0; 1510. mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */ 1511. relobj(mtmp, 0, FALSE); 1512. remove_monster(mtmp->mx, mtmp->my); 1513. if (emits_light(mptr)) 1514. del_light_source(LS_MONSTER, (genericptr_t)mtmp); 1515. newsym(mtmp->mx,mtmp->my); 1516. unstuck(mtmp); 1517. fill_pit(mtmp->mx, mtmp->my); 1518. 1519. if(mtmp->isshk) shkgone(mtmp); 1520. if(mtmp->wormno) wormgone(mtmp); 1521. iflags.purge_monsters++; 1522. } 1523. 1524. /* find the worn amulet of life saving which will save a monster */ 1525. struct obj * 1526. mlifesaver(mon) 1527. struct monst *mon; 1528. { 1529. if (!nonliving(mon->data)) { 1530. struct obj *otmp = which_armor(mon, W_AMUL); 1531. 1532. if (otmp && otmp->otyp == AMULET_OF_LIFE_SAVING) 1533. return otmp; 1534. } 1535. return (struct obj *)0; 1536. } 1537. 1538. STATIC_OVL void 1539. lifesaved_monster(mtmp) 1540. struct monst *mtmp; 1541. { 1542. int visible; 1543. struct obj *lifesave = mlifesaver(mtmp); 1544. 1545. if (lifesave) { 1546. /* not canseemon; amulets are on the head, so you don't want */ 1547. /* to show this for a long worm with only a tail visible. */ 1548. /* Nor do you check invisibility, because glowing and disinte- */ 1549. /* grating amulets are always visible. */ 1550. /* [ALI] Always treat swallower as visible for consistency */ 1551. /* with unpoly_monster(). */ 1552. visible = u.uswallow && u.ustuck == mtmp || 1553. cansee(mtmp->mx, mtmp->my); 1554. if (visible) { 1555. pline("But wait..."); 1556. pline("%s medallion begins to glow!", 1557. s_suffix(Monnam(mtmp))); 1558. makeknown(AMULET_OF_LIFE_SAVING); 1559. if (attacktype(mtmp->data, AT_EXPL) 1560. || attacktype(mtmp->data, AT_BOOM)) 1561. pline("%s reconstitutes!", Monnam(mtmp)); 1562. else 1563. pline("%s looks much better!", Monnam(mtmp)); 1564. pline_The("medallion crumbles to dust!"); 1565. } 1566. m_useup(mtmp, lifesave); 1567. mtmp->mcanmove = 1; 1568. mtmp->mfrozen = 0; 1569. if (mtmp->mtame && !mtmp->isminion) { 1570. wary_dog(mtmp, FALSE); 1571. } 1572. if (mtmp->mhpmax <= 0) mtmp->mhpmax = 10; 1573. mtmp->mhp = mtmp->mhpmax; 1574. if (mvitals[monsndx(mtmp->data)].mvflags & G_GENOD) { 1575. if (visible) 1576. pline("Unfortunately %s is still genocided...", 1577. mon_nam(mtmp)); 1578. } else 1579. return; 1580. } 1581. mtmp->mhp = 0; 1582. } 1583. 1584. /* WAC -- undo polymorph */ 1585. static void 1586. unpoly_monster(mtmp) 1587. struct monst *mtmp; 1588. { 1589. int visible; 1590. char buf[BUFSZ]; 1591. 1592. sprintf(buf, Monnam(mtmp)); 1593. 1594. /* If there is a timer == monster was poly'ed */ 1595. if (stop_timer(UNPOLY_MON, (genericptr_t) mtmp)) { 1596. /* [ALI] Always treat swallower as visible so that the message 1597. * indicating that the monster hasn't died comes _before_ any 1598. * message about breaking out of the "new" monster. 1599. */ 1600. visible = u.uswallow && u.ustuck == mtmp || cansee(mtmp->mx,mtmp->my); 1601. mtmp->mhp = mtmp->mhpmax; 1602. if (visible) 1603. pline("But wait..."); 1604. if (newcham(mtmp, &mons[mtmp->oldmonnm], FALSE, visible)) 1605. mtmp->mhp = mtmp->mhpmax/2; 1606. else { 1607. if (visible) 1608. pline("%s shudders!", Monnam(mtmp)); 1609. mtmp->mhp = 0; 1610. } 1611. } 1612. } 1613. 1614. 1615. void 1616. mondead(mtmp) 1617. register struct monst *mtmp; 1618. { 1619. struct permonst *mptr; 1620. int tmp; 1621. 1622. /* WAC just in case caller forgot to...*/ 1623. if (mtmp->mhp) mtmp->mhp = -1; 1624. 1625. if(mtmp->isgd) { 1626. /* if we're going to abort the death, it *must* be before 1627. * the m_detach or there will be relmon problems later */ 1628. if(!grddead(mtmp)) return; 1629. } 1630. 1631. mptr = mtmp->data; 1632. 1633. /* WAC First check that monster can unpoly */ 1634. unpoly_monster(mtmp); 1635. if (mtmp->mhp > 0) return; 1636. 1637. lifesaved_monster(mtmp); 1638. if (mtmp->mhp > 0) return; 1639. 1640. #ifdef STEED 1641. /* Player is thrown from his steed when it dies */ 1642. if (mtmp == u.usteed) 1643. dismount_steed(DISMOUNT_GENERIC); 1644. #endif 1645. 1646. mptr = mtmp->data; /* save this for m_detach() */ 1647. /* restore chameleon, lycanthropes to true form at death */ 1648. if (mtmp->cham) 1649. set_mon_data(mtmp, &mons[cham_to_pm[mtmp->cham]], -1); 1650. else if (mtmp->data == &mons[PM_WEREJACKAL]) 1651. set_mon_data(mtmp, &mons[PM_HUMAN_WEREJACKAL], -1); 1652. else if (mtmp->data == &mons[PM_WEREWOLF]) 1653. set_mon_data(mtmp, &mons[PM_HUMAN_WEREWOLF], -1); 1654. else if (mtmp->data == &mons[PM_WERERAT]) 1655. set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT], -1); 1656. else if (mtmp->data == &mons[PM_WEREPANTHER]) 1657. set_mon_data(mtmp, &mons[PM_HUMAN_WEREPANTHER], -1); 1658. else if (mtmp->data == &mons[PM_WERETIGER]) 1659. set_mon_data(mtmp, &mons[PM_HUMAN_WERETIGER], -1); 1660. else if (mtmp->data == &mons[PM_WERESNAKE]) 1661. set_mon_data(mtmp, &mons[PM_HUMAN_WERESNAKE], -1); 1662. else if (mtmp->data == &mons[PM_WERESPIDER]) 1663. set_mon_data(mtmp, &mons[PM_HUMAN_WERESPIDER], -1); 1664. 1665. /* if MAXMONNO monsters of a given type have died, and it 1666. * can be done, extinguish that monster. 1667. * 1668. * mvitals[].died does double duty as total number of dead monsters 1669. * and as experience factor for the player killing more monsters. 1670. * this means that a dragon dying by other means reduces the 1671. * experience the player gets for killing a dragon directly; this 1672. * is probably not too bad, since the player likely finagled the 1673. * first dead dragon via ring of conflict or pets, and extinguishing 1674. * based on only player kills probably opens more avenues of abuse 1675. * for rings of conflict and such. 1676. */ 1677. /* KMH -- Yes, keep spell monsters in the count */ 1678. tmp = monsndx(mtmp->data); 1679. if (mvitals[tmp].died < 255) mvitals[tmp].died++; 1680. 1681. /* if it's a (possibly polymorphed) quest leader, mark him as dead */ 1682. if (mtmp->m_id == quest_status.leader_m_id) 1683. quest_status.leader_is_dead = TRUE; 1684. #ifdef MAIL 1685. /* if the mail daemon dies, no more mail delivery. -3. */ 1686. if (tmp == PM_MAIL_DAEMON) mvitals[tmp].mvflags |= G_GENOD; 1687. #endif 1688. 1689. #ifdef KOPS 1690. if (mtmp->data->mlet == S_KOP) { 1691. /* Dead Kops may come back. */ 1692. switch(rnd(5)) { 1693. case 1: /* returns near the stairs */ 1694. (void) makemon(mtmp->data,xdnstair,ydnstair,NO_MM_FLAGS); 1695. break; 1696. case 2: /* randomly */ 1697. (void) makemon(mtmp->data,0,0,NO_MM_FLAGS); 1698. break; 1699. default: 1700. break; 1701. } 1702. } 1703. #endif 1704. if(mtmp->iswiz) wizdead(); 1705. if(mtmp->data->msound == MS_NEMESIS) nemdead(); 1706. if(memory_is_invisible(mtmp->mx, mtmp->my)) 1707. unmap_object(mtmp->mx, mtmp->my); 1708. m_detach(mtmp, mptr); 1709. } 1710. 1711. /* TRUE if corpse might be dropped, magr may die if mon was swallowed */ 1712. boolean 1713. corpse_chance(mon, magr, was_swallowed) 1714. struct monst *mon; 1715. struct monst *magr; /* killer, if swallowed */ 1716. boolean was_swallowed; /* digestion */ 1717. { 1718. struct permonst *mdat = mon->data; 1719. int i, tmp; 1720. 1721. if (mdat == &mons[PM_VLAD_THE_IMPALER] || mdat->mlet == S_LICH) { 1722. if (cansee(mon->mx, mon->my) && !was_swallowed) 1723. pline("%s body crumbles into dust.", s_suffix(Monnam(mon))); 1724. /* KMH -- make_corpse() handles Vecna */ 1725. return (mdat == &mons[PM_VECNA]); 1726. } 1727. 1728. /* Gas spores always explode upon death */ 1729. for(i = 0; i < NATTK; i++) { 1730. if (mdat->mattk[i].aatyp == AT_BOOM) { 1731. char buf[BUFSZ]; 1732. 1733. if (mdat->mattk[i].damn) 1734. tmp = d((int)mdat->mattk[i].damn, 1735. (int)mdat->mattk[i].damd); 1736. else if(mdat->mattk[i].damd) 1737. tmp = d((int)mdat->mlevel+1, (int)mdat->mattk[i].damd); 1738. else tmp = 0; 1739. if (was_swallowed && magr) { 1740. if (magr == &youmonst) { 1741. There("is an explosion in your %s!", 1742. body_part(STOMACH)); 1743. Sprintf(killer_buf, "%s explosion", 1744. s_suffix(mdat->mname)); 1745. if (Half_physical_damage) tmp = (tmp+1) / 2; 1746. losehp(tmp, killer_buf, KILLED_BY_AN); 1747. } else { 1748. if (flags.soundok) You_hear("an explosion."); 1749. magr->mhp -= tmp; 1750. if (magr->mhp < 1) mondied(magr); 1751. if (magr->mhp < 1) { /* maybe lifesaved */ 1752. if (canspotmon(magr)) 1753. pline("%s rips open!", Monnam(magr)); 1754. } else if (canseemon(magr)) 1755. pline("%s seems to have indigestion.", 1756. Monnam(magr)); 1757. } 1758. 1759. return FALSE; 1760. } 1761. 1762. Sprintf(buf, "%s explosion", s_suffix(mdat->mname)); 1763. killer = buf; 1764. killer_format = KILLED_BY_AN; 1765. explode(mon->mx, mon->my, -1, tmp, MON_EXPLODE, EXPL_NOXIOUS); 1766. return (FALSE); 1767. } 1768. } 1769. 1770. /* Cthulhu Deliquesces... */ 1771. if (mdat == &mons[PM_CTHULHU]) { 1772. if (cansee(mon->mx, mon->my)) 1773. pline("%s body deliquesces into a cloud of noxious gas!", 1774. s_suffix(Monnam(mon))); 1775. else 1776. You_hear("hissing and bubbling!"); 1777. /* ...into a stinking cloud... */ 1778. (void) create_cthulhu_death_cloud(mon->mx, mon->my, 3, 8); 1779. return (FALSE); 1780. } 1781. 1782. /* must duplicate this below check in xkilled() since it results in 1783. * creating no objects as well as no corpse 1784. */ 1785. if (LEVEL_SPECIFIC_NOCORPSE(mdat)) 1786. return FALSE; 1787. 1788. if (bigmonst(mdat) || mdat == &mons[PM_LIZARD] 1789. || is_golem(mdat) 1790. || is_mplayer(mdat) 1791. || is_rider(mdat)) 1792. return TRUE; 1793. return (boolean) (!rn2((int) 1794. (2 + ((int)(mdat->geno & G_FREQ)<2) + verysmall(mdat)))); 1795. } 1796. 1797. /* drop (perhaps) a cadaver and remove monster */ 1798. void 1799. mondied(mdef) 1800. register struct monst *mdef; 1801. { 1802. mondead(mdef); 1803. if (mdef->mhp > 0) return; /* lifesaved */ 1804. 1805. if (corpse_chance(mdef, (struct monst *)0, FALSE) && 1806. (accessible(mdef->mx, mdef->my) || is_pool(mdef->mx, mdef->my))) 1807. (void) make_corpse(mdef); 1808. } 1809. 1810. /* monster disappears, not dies */ 1811. void 1812. mongone(mdef) 1813. register struct monst *mdef; 1814. { 1815. mdef->mhp = 0; /* can skip some inventory bookkeeping */ 1816. #ifdef STEED 1817. /* Player is thrown from his steed when it disappears */ 1818. if (mdef == u.usteed) 1819. dismount_steed(DISMOUNT_GENERIC); 1820. #endif 1821. 1822. /* drop special items like the Amulet so that a dismissed Kop or nurse 1823. can't remove them from the game */ 1824. mdrop_special_objs(mdef); 1825. /* release rest of monster's inventory--it is removed from game */ 1826. discard_minvent(mdef); 1827. #ifndef GOLDOBJ 1828. mdef->mgold = 0L; 1829. #endif 1830. m_detach(mdef, mdef->data); 1831. } 1832. 1833. /* drop a statue or rock and remove monster */ 1834. void 1835. monstone(mdef) 1836. register struct monst *mdef; 1837. { 1838. struct obj *otmp, *obj, *oldminvent; 1839. xchar x = mdef->mx, y = mdef->my; 1840. boolean wasinside = FALSE; 1841. 1842. /* we have to make the statue before calling mondead, to be able to 1843. * put inventory in it, and we have to check for lifesaving before 1844. * making the statue.... 1845. */ 1846. lifesaved_monster(mdef); 1847. if (mdef->mhp > 0) return; 1848. 1849. mdef->mtrapped = 0; /* (see m_detach) */ 1850. 1851. if ((int)mdef->data->msize > MZ_TINY || 1852. !rn2(2 + ((int) (mdef->data->geno & G_FREQ) > 2))) { 1853. oldminvent = 0; 1854. /* some objects may end up outside the statue */ 1855. while ((obj = mdef->minvent) != 0) { 1856. obj_extract_self(obj); 1857. if (obj->owornmask) 1858. update_mon_intrinsics(mdef, obj, FALSE, TRUE); 1859. obj_no_longer_held(obj); 1860. if (obj->owornmask & W_WEP) 1861. setmnotwielded(mdef,obj); 1862. obj->owornmask = 0L; 1863. if (obj->otyp == BOULDER || 1864. #if 0 /* monsters don't carry statues */ 1865. (obj->otyp == STATUE && mons[obj->corpsenm].msize >= mdef->data->msize) || 1866. #endif 1867. obj_resists(obj, 0, 0)) { 1868. if (flooreffects(obj, x, y, "fall")) continue; 1869. place_object(obj, x, y); 1870. } else { 1871. if (obj->lamplit) end_burn(obj, TRUE); 1872. obj->nobj = oldminvent; 1873. oldminvent = obj; 1874. } 1875. } 1876. /* defer statue creation until after inventory removal 1877. so that saved monster traits won't retain any stale 1878. item-conferred attributes */ 1879. otmp = mkcorpstat(STATUE, KEEPTRAITS(mdef) ? mdef : 0, 1880. mdef->data, x, y, FALSE); 1881. if (mdef->mnamelth) otmp = oname(otmp, NAME(mdef)); 1882. while ((obj = oldminvent) != 0) { 1883. oldminvent = obj->nobj; 1884. (void) add_to_container(otmp, obj); 1885. } 1886. #ifndef GOLDOBJ 1887. if (mdef->mgold) { 1888. struct obj *au; 1889. au = mksobj(GOLD_PIECE, FALSE, FALSE); 1890. au->quan = mdef->mgold; 1891. au->owt = weight(au); 1892. (void) add_to_container(otmp, au); 1893. mdef->mgold = 0; 1894. } 1895. #endif 1896. /* Archeologists should not break unique statues */ 1897. if (mdef->data->geno & G_UNIQ) 1898. otmp->spe = 1; 1899. otmp->owt = weight(otmp); 1900. } else 1901. otmp = mksobj_at(ROCK, x, y, TRUE, FALSE); 1902. 1903. stackobj(otmp); 1904. /* mondead() already does this, but we must do it before the newsym */ 1905. if(memory_is_invisible(x, y)) 1906. unmap_object(x, y); 1907. if (cansee(x, y)) newsym(x,y); 1908. /* We don't currently trap the hero in the statue in this case but we could */ 1909. if (u.uswallow && u.ustuck == mdef) wasinside = TRUE; 1910. (void) stop_timer(UNPOLY_MON, (genericptr_t) mdef); 1911. mondead(mdef); 1912. if (wasinside) { 1913. if (is_animal(mdef->data)) 1914. You("%s through an opening in the new %s.", 1915. locomotion(youmonst.data, "jump"), 1916. xname(otmp)); 1917. } 1918. } 1919. 1920. /* another monster has killed the monster mdef */ 1921. void 1922. monkilled(mdef, fltxt, how) 1923. register struct monst *mdef; 1924. const char *fltxt; 1925. int how; 1926. { 1927. boolean be_sad = FALSE; /* true if unseen pet is killed */ 1928. 1929. if ((mdef->wormno ? worm_known(mdef) : cansee(mdef->mx, mdef->my)) 1930. && fltxt) 1931. pline("%s is %s%s%s!", Monnam(mdef), 1932. nonliving(mdef->data) ? "destroyed" : "killed", 1933. *fltxt ? " by the " : "", 1934. fltxt 1935. ); 1936. else 1937. be_sad = (mdef->mtame != 0 && !mdef->isspell); 1938. 1939. /* no corpses if digested or disintegrated */ 1940. if(how == AD_DGST || how == -AD_RBRE) 1941. mondead(mdef); 1942. else 1943. mondied(mdef); 1944. 1945. if (be_sad && mdef->mhp <= 0) 1946. You("have a sad feeling for a moment, then it passes."); 1947. } 1948. 1949. 1950. /* WAC -- another monster has killed the monster mdef and you get exp. */ 1951. void 1952. mon_xkilled(mdef, fltxt, how) 1953. register struct monst *mdef; 1954. const char *fltxt; 1955. int how; 1956. { 1957. boolean be_sad = FALSE; /* true if unseen pet is killed */ 1958. 1959. if ((mdef->wormno ? worm_known(mdef) : cansee(mdef->mx, mdef->my)) 1960. && fltxt) 1961. pline("%s is %s%s%s!", Monnam(mdef), 1962. nonliving(mdef->data) ? "destroyed" : "killed", 1963. *fltxt ? " by the " : "", 1964. fltxt); 1965. else 1966. be_sad = (mdef->mtame != 0 && !mdef->isspell); 1967. 1968. /* no corpses if digested or disintegrated */ 1969. if(how == AD_DGST || how == -AD_RBRE) 1970. xkilled(mdef,2); 1971. else 1972. xkilled(mdef,0); 1973. 1974. if (be_sad && mdef->mhp <= 0) 1975. You("have a sad feeling for a moment, then it passes."); 1976. } 1977. 1978. 1979. void 1980. unstuck(mtmp) 1981. register struct monst *mtmp; 1982. { 1983. if(u.ustuck == mtmp) { 1984. if(u.uswallow){ 1985. u.ux = mtmp->mx; 1986. u.uy = mtmp->my; 1987. u.uswallow = 0; 1988. u.uswldtim = 0; 1989. if (Punished) placebc(); 1990. vision_full_recalc = 1; 1991. docrt(); 1992. } 1993. setustuck(0); 1994. } 1995. } 1996. 1997. void 1998. killed(mtmp) 1999. register struct monst *mtmp; 2000. { 2001. xkilled(mtmp, 1); 2002. } 2003. 2004. /* the player has killed the monster mtmp */ 2005. void 2006. xkilled(mtmp, dest) 2007. register struct monst *mtmp; 2008. /* 2009. * Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse 2010. * either; dest=3, message but no corpse 2011. */ 2012. int dest; 2013. { 2014. register int tmp, x = mtmp->mx, y = mtmp->my; 2015. register struct permonst *mdat; 2016. int mndx; 2017. register struct obj *otmp; 2018. register struct trap *t; 2019. boolean redisp = FALSE; 2020. boolean wasinside = u.uswallow && (u.ustuck == mtmp); 2021. 2022. 2023. /* KMH, conduct */ 2024. u.uconduct.killer++; 2025. 2026. if (dest & 1) { 2027. const char *verb = nonliving(mtmp->data) ? "destroy" : "kill"; 2028. 2029. if (!wasinside && !canspotmon(mtmp)) 2030. You("%s it!", verb); 2031. else { 2032. You("%s %s!", verb, 2033. !mtmp->mtame ? mon_nam(mtmp) : 2034. x_monnam(mtmp, 2035. mtmp->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 2036. "poor", 2037. mtmp->mnamelth ? SUPPRESS_SADDLE : 0, 2038. FALSE)); 2039. } 2040. } 2041. 2042. if (mtmp->mtrapped && (t = t_at(x, y)) != 0 && 2043. (t->ttyp == PIT || t->ttyp == SPIKED_PIT) && 2044. sobj_at(BOULDER, x, y)) 2045. dest |= 2; /* 2046. * Prevent corpses/treasure being created "on top" 2047. * of the boulder that is about to fall in. This is 2048. * out of order, but cannot be helped unless this 2049. * whole routine is rearranged. 2050. */ 2051. 2052. /* your pet knows who just killed it...watch out */ 2053. if (mtmp->mtame && !mtmp->isminion) EDOG(mtmp)->killed_by_u = 1; 2054. 2055. /* dispose of monster and make cadaver */ 2056. if(stoned) monstone(mtmp); 2057. else mondead(mtmp); 2058. 2059. if (mtmp->mhp > 0) { /* monster cheated death */ 2060. /* Cannot put the non-visible lifesaving message in 2061. * lifesaved_monster()/unpoly_monster() since the message 2062. * appears only when you kill it (as opposed to visible 2063. * lifesaving which always appears). 2064. */ 2065. stoned = FALSE; 2066. if ((!u.uswallow || u.ustuck != mtmp) && !cansee(x, y)) 2067. pline("Maybe not..."); 2068. return; 2069. } 2070. 2071. mdat = mtmp->data; /* note: mondead can change mtmp->data */ 2072. mndx = monsndx(mdat); 2073. 2074. if (stoned) { 2075. stoned = FALSE; 2076. goto cleanup; 2077. } 2078. 2079. if((dest & 2) || LEVEL_SPECIFIC_NOCORPSE(mdat)) 2080. goto cleanup; 2081. 2082. #ifdef MAIL 2083. if(mdat == &mons[PM_MAIL_DAEMON]) { 2084. stackobj(mksobj_at(SCR_MAIL, x, y, FALSE, FALSE)); 2085. redisp = TRUE; 2086. } 2087. #endif 2088. if((!accessible(x, y) && !is_pool(x, y)) || 2089. (x == u.ux && y == u.uy)) { 2090. /* might be mimic in wall or corpse in lava or on player's spot */ 2091. redisp = TRUE; 2092. if(wasinside) spoteffects(TRUE); 2093. } else if(x != u.ux || y != u.uy) { 2094. /* might be here after swallowed */ 2095. if (!rn2(6) && !(mvitals[mndx].mvflags & G_NOCORPSE) && !(nohands(mdat)) 2096. #ifdef KOPS 2097. && mdat->mlet != S_KOP 2098. #endif 2099. ) { 2100. int typ; 2101. 2102. otmp = mkobj_at(RANDOM_CLASS, x, y, TRUE); 2103. /* Don't create large objects from small monsters */ 2104. typ = otmp->otyp; 2105. if (mdat->msize < MZ_HUMAN && typ != FOOD_RATION 2106. && typ != LEASH 2107. && typ != FIGURINE 2108. && (otmp->owt > 3 || 2109. objects[typ].oc_big /*oc_bimanual/oc_bulky*/ || 2110. is_spear(otmp) || is_pole(otmp) || 2111. typ == MORNING_STAR)) { 2112. delobj(otmp); 2113. } else redisp = TRUE; 2114. } 2115. /* Whether or not it always makes a corpse is, in theory, 2116. * different from whether or not the corpse is "special"; 2117. * if we want both, we have to specify it explicitly. 2118. */ 2119. if (corpse_chance(mtmp, (struct monst *)0, FALSE)) 2120. (void) make_corpse(mtmp); 2121. } 2122. if(redisp) newsym(x,y); 2123. cleanup: 2124. /* punish bad behaviour */ 2125. if(is_human(mdat) && (!always_hostile(mdat) && mtmp->malign <= 0) && 2126. (mndx < PM_ARCHEOLOGIST || mndx > PM_WIZARD) && 2127. u.ualign.type != A_CHAOTIC) { 2128. HTelepat &= ~INTRINSIC; 2129. change_luck(-2); 2130. You("murderer!"); 2131. if (Blind && !Blind_telepat) 2132. see_monsters(); /* Can't sense monsters any more. */ 2133. } 2134. if((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame) change_luck(-1); 2135. if (is_unicorn(mdat) && 2136. sgn(u.ualign.type) == sgn(mdat->maligntyp)) { 2137. change_luck(-5); 2138. You_feel("guilty..."); 2139. } 2140. /* give experience points */ 2141. tmp = experience(mtmp, (int)mvitals[mndx].died + 1); 2142. more_experienced(tmp, 0); 2143. newexplevel(); /* will decide if you go up */ 2144. 2145. /* adjust alignment points */ 2146. if (mtmp->m_id == quest_status.leader_m_id) { /* REAL BAD! */ 2147. adjalign(-(u.ualign.record+(int)ALIGNLIM/2)); 2148. pline("That was %sa bad idea...", 2149. u.uevent.qcompleted ? "probably " : ""); 2150. } else if (mdat->msound == MS_NEMESIS) /* Real good! */ 2151. adjalign((int)(ALIGNLIM/4)); 2152. else if (mdat->msound == MS_GUARDIAN) { /* Bad */ 2153. adjalign(-(int)(ALIGNLIM/8)); 2154. if (!Hallucination) pline("That was probably a bad idea..."); 2155. else pline("Whoopsie-daisy!"); 2156. } else if (mtmp->ispriest) { 2157. adjalign((p_coaligned(mtmp)) ? -2 : 2); 2158. /* cancel divine protection for killing your priest */ 2159. if (p_coaligned(mtmp)) u.ublessed = 0; 2160. if (mdat->maligntyp == A_NONE) 2161. adjalign((int)(ALIGNLIM / 4)); /* BIG bonus */ 2162. } else if (mtmp->mtame) { 2163. adjalign(-15); /* bad!! */ 2164. /* your god is mighty displeased... */ 2165. if (!Hallucination) You_hear("the rumble of distant thunder..."); 2166. else You_hear("the studio audience applaud!"); 2167. } else if (mtmp->mpeaceful) { 2168. adjalign(-5); 2169. if (!Hallucination) pline("The gods will probably not appreciate this..."); 2170. else pline("Whoopsie-daisy!"); 2171. } 2172. 2173. /* malign was already adjusted for u.ualign.type and randomization */ 2174. adjalign(mtmp->malign); 2175. } 2176. 2177. /* changes the monster into a stone monster of the same type */ 2178. /* this should only be called when poly_when_stoned() is true */ 2179. void 2180. mon_to_stone(mtmp) 2181. register struct monst *mtmp; 2182. { 2183. boolean polymorphed = mtmp->oldmonnm != monsndx(mtmp->data); 2184. 2185. if(mtmp->data->mlet == S_GOLEM) { 2186. /* it's a golem, and not a stone golem */ 2187. if(canseemon(mtmp)) 2188. pline("%s solidifies...", Monnam(mtmp)); 2189. if (newcham(mtmp, &mons[PM_STONE_GOLEM], FALSE, FALSE)) { 2190. if (!polymorphed) 2191. mtmp->oldmonnm = PM_STONE_GOLEM; /* Change is permanent */ 2192. if(canseemon(mtmp)) 2193. pline("Now it's %s.", an(mtmp->data->mname)); 2194. } else { 2195. if(canseemon(mtmp)) 2196. pline("... and returns to normal."); 2197. } 2198. } else 2199. impossible("Can't polystone %s!", a_monnam(mtmp)); 2200. } 2201. 2202. void 2203. mnexto(mtmp) /* Make monster mtmp next to you (if possible) */ 2204. struct monst *mtmp; 2205. { 2206. coord mm; 2207. 2208. #ifdef STEED 2209. if (mtmp == u.usteed) { 2210. /* Keep your steed in sync with you instead */ 2211. mtmp->mx = u.ux; 2212. mtmp->my = u.uy; 2213. return; 2214. } 2215. #endif 2216. 2217. if(!enexto(&mm, u.ux, u.uy, mtmp->data)) return; 2218. rloc_to(mtmp, mm.x, mm.y); 2219. return; 2220. } 2221. 2222. /* mnearto() 2223. * Put monster near (or at) location if possible. 2224. * Returns: 2225. * 1 - if a monster was moved from x, y to put mtmp at x, y. 2226. * 0 - in most cases. 2227. */ 2228. boolean 2229. mnearto(mtmp,x,y,move_other) 2230. register struct monst *mtmp; 2231. xchar x, y; 2232. boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */ 2233. { 2234. struct monst *othermon = (struct monst *)0; 2235. xchar newx, newy; 2236. coord mm; 2237. 2238. if ((mtmp->mx == x) && (mtmp->my == y)) return(FALSE); 2239. 2240. if (move_other && (othermon = m_at(x, y))) { 2241. if (othermon->wormno) 2242. remove_worm(othermon); 2243. else 2244. remove_monster(x, y); 2245. } 2246. 2247. newx = x; 2248. newy = y; 2249. 2250. if (!goodpos(newx, newy, mtmp, 0)) { 2251. /* actually we have real problems if enexto ever fails. 2252. * migrating_mons that need to be placed will cause 2253. * no end of trouble. 2254. */ 2255. if (!enexto(&mm, newx, newy, mtmp->data)) return(FALSE); 2256. newx = mm.x; newy = mm.y; 2257. } 2258. 2259. rloc_to(mtmp, newx, newy); 2260. 2261. if (move_other && othermon) { 2262. othermon->mx = othermon->my = 0; 2263. (void) mnearto(othermon, x, y, FALSE); 2264. if ((othermon->mx != x) || (othermon->my != y)) 2265. return(TRUE); 2266. } 2267. 2268. return(FALSE); 2269. } 2270. 2271. 2272. static const char *poiseff[] = { 2273. 2274. " feel weaker", "r brain is on fire", 2275. "r judgement is impaired", "r muscles won't obey you", 2276. " feel very sick", " break out in hives" 2277. }; 2278. 2279. void 2280. poisontell(typ) 2281. 2282. int typ; 2283. { 2284. pline("You%s.", poiseff[typ]); 2285. } 2286. 2287. void 2288. poisoned(string, typ, pname, fatal) 2289. const char *string, *pname; 2290. int typ, fatal; 2291. { 2292. int i, plural, kprefix = KILLED_BY_AN; 2293. boolean thrown_weapon = (fatal < 0); 2294. 2295. if (thrown_weapon) fatal = -fatal; 2296. if(strcmp(string, "blast") && !thrown_weapon) { 2297. /* 'blast' has already given a 'poison gas' message */ 2298. /* so have "poison arrow", "poison dart", etc... */ 2299. plural = (string[strlen(string) - 1] == 's')? 1 : 0; 2300. /* avoid "The" Orcus's sting was poisoned... */ 2301. pline("%s%s %s poisoned!", isupper((int)*string) ? "" : "The ", 2302. string, plural ? "were" : "was"); 2303. } 2304. 2305. if(Poison_resistance) { 2306. if(!strcmp(string, "blast")) shieldeff(u.ux, u.uy); 2307. pline_The("poison doesn't seem to affect you."); 2308. return; 2309. } 2310. /* suppress killer prefix if it already has one */ 2311. if ((i = name_to_mon(pname)) >= LOW_PM && mons[i].geno & G_UNIQ) { 2312. kprefix = KILLED_BY; 2313. if (!type_is_pname(&mons[i])) pname = the(pname); 2314. } else if (!strncmpi(pname, "the ", 4) || 2315. !strncmpi(pname, "an ", 3) || 2316. !strncmpi(pname, "a ", 2)) { 2317. /*[ does this need a plural check too? ]*/ 2318. kprefix = KILLED_BY; 2319. } 2320. i = rn2(fatal + 20*thrown_weapon); 2321. if(i == 0 && typ != A_CHA) { 2322. if (Invulnerable) 2323. pline("You are unharmed!"); 2324. else { 2325. u.uhp = -1; 2326. pline_The("poison was deadly..."); 2327. } 2328. } else if(i <= 5) { 2329. /* Check that a stat change was made */ 2330. if (adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), 1)) 2331. pline("You%s!", poiseff[typ]); 2332. } else { 2333. i = thrown_weapon ? rnd(6) : rn1(10,6); 2334. if(Half_physical_damage) i = (i+1) / 2; 2335. losehp(i, pname, kprefix); 2336. } 2337. if(u.uhp < 1) { 2338. killer_format = kprefix; 2339. killer = pname; 2340. /* "Poisoned by a poisoned ___" is redundant */ 2341. done(strstri(pname, "poison") ? DIED : POISONING); 2342. } 2343. (void) encumber_msg(); 2344. } 2345. 2346. /* monster responds to player action; not the same as a passive attack */ 2347. /* assumes reason for response has been tested, and response _must_ be made */ 2348. void 2349. m_respond(mtmp) 2350. register struct monst *mtmp; 2351. { 2352. if(mtmp->data->msound == MS_SHRIEK) { 2353. if(flags.soundok) { 2354. pline("%s shrieks.", Monnam(mtmp)); 2355. stop_occupation(); 2356. } 2357. /* [Tom] took out the weird purple worm thing and lowered prob from 10 */ 2358. if (!rn2(8)) { 2359. /* if (!rn2(13)) 2360. (void) makemon(&mons[PM_PURPLE_WORM], 0, 0, NO_MM_FLAGS); 2361. else */ 2362. (void) makemon((struct permonst *)0, 0, 0, NO_MM_FLAGS); 2363. 2364. } 2365. aggravate(); 2366. } 2367. if(mtmp->data == &mons[PM_MEDUSA]) { 2368. register int i; 2369. for(i = 0; i < NATTK; i++) 2370. if(mtmp->data->mattk[i].aatyp == AT_GAZE) { 2371. (void) gazemu(mtmp, &mtmp->data->mattk[i]); 2372. break; 2373. } 2374. } 2375. } 2376. 2377. #endif /* OVLB */ 2378. #ifdef OVL2 2379. 2380. void 2381. setmangry(mtmp) 2382. register struct monst *mtmp; 2383. { 2384. mtmp->mstrategy &= ~STRAT_WAITMASK; 2385. #ifdef BLACKMARKET 2386. /* Even if the black marketeer is already angry he may not have called 2387. * for his assistants if he or his staff have not been assaulted yet. 2388. */ 2389. if (Is_blackmarket(&u.uz) && !mtmp->mpeaceful && mtmp->isshk) 2390. blkmar_guards(mtmp); 2391. #endif /* BLACKMARKET */ 2392. if(!mtmp->mpeaceful) return; 2393. if(mtmp->mtame) return; 2394. mtmp->mpeaceful = 0; 2395. if(mtmp->ispriest) { 2396. if(p_coaligned(mtmp)) adjalign(-5); /* very bad */ 2397. else adjalign(2); 2398. } else { 2399. adjalign(-1); /* attacking peaceful monsters is bad */ 2400. } 2401. 2402. if (couldsee(mtmp->mx, mtmp->my)) { 2403. if (humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd) 2404. pline("%s gets angry!", Monnam(mtmp)); 2405. else if (flags.verbose && flags.soundok) growl(mtmp); 2406. } 2407. 2408. #ifdef BLACKMARKET 2409. /* Don't misbehave in the Black Market or else... */ 2410. if (Is_blackmarket(&u.uz)) { 2411. if (mtmp->isshk) 2412. blkmar_guards(mtmp); 2413. else if (NAME(mtmp) && *NAME(mtmp)) { 2414. /* non-tame named monsters are presumably 2415. * black marketeer's assistants */ 2416. struct monst *shkp; 2417. shkp = shop_keeper(inside_shop(mtmp->mx, mtmp->my)); 2418. if (shkp) wakeup(shkp); 2419. } 2420. } 2421. #endif /* BLACKMARKET */ 2422. 2423. /* attacking your own quest leader will anger his or her guardians */ 2424. if (!flags.mon_moving && /* should always be the case here */ 2425. mtmp->data == &mons[quest_info(MS_LEADER)]) { 2426. struct monst *mon; 2427. struct permonst *q_guardian = &mons[quest_info(MS_GUARDIAN)]; 2428. int got_mad = 0; 2429. 2430. /* guardians will sense this attack even if they can't see it */ 2431. for (mon = fmon; mon; mon = mon->nmon) 2432. if (!DEADMONSTER(mon) && mon->data == q_guardian && mon->mpeaceful) { 2433. mon->mpeaceful = 0; 2434. if (canseemon(mon)) ++got_mad; 2435. } 2436. if (got_mad && !Hallucination) 2437. pline_The("%s appear%s to be angry too...", 2438. got_mad == 1 ? q_guardian->mname : 2439. makeplural(q_guardian->mname), 2440. got_mad == 1 ? "s" : ""); 2441. } 2442. } 2443. 2444. void 2445. wakeup(mtmp) 2446. register struct monst *mtmp; 2447. { 2448. mtmp->msleeping = 0; 2449. mtmp->meating = 0; /* assume there's no salvagable food left */ 2450. setmangry(mtmp); 2451. if(mtmp->m_ap_type) seemimic(mtmp); 2452. else if (flags.forcefight && !flags.mon_moving && mtmp->mundetected) { 2453. mtmp->mundetected = 0; 2454. newsym(mtmp->mx, mtmp->my); 2455. } 2456. } 2457. 2458. /* Wake up nearby monsters. */ 2459. void 2460. wake_nearby() 2461. { 2462. register struct monst *mtmp; 2463. 2464. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 2465. if (!DEADMONSTER(mtmp) && distu(mtmp->mx,mtmp->my) < u.ulevel*20) { 2466. mtmp->msleeping = 0; 2467. if (mtmp->mtame && !mtmp->isminion) 2468. EDOG(mtmp)->whistletime = moves; 2469. } 2470. } 2471. } 2472. 2473. /* Wake up monsters near some particular location. */ 2474. void 2475. wake_nearto(x, y, distance) 2476. register int x, y, distance; 2477. { 2478. register struct monst *mtmp; 2479. 2480. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 2481. if (!DEADMONSTER(mtmp) && mtmp->msleeping && (distance == 0 || 2482. dist2(mtmp->mx, mtmp->my, x, y) < distance)) 2483. mtmp->msleeping = 0; 2484. } 2485. } 2486. 2487. /* NOTE: we must check for mimicry before calling this routine */ 2488. void 2489. seemimic(mtmp) 2490. register struct monst *mtmp; 2491. { 2492. unsigned old_app = mtmp->mappearance; 2493. uchar old_ap_type = mtmp->m_ap_type; 2494. 2495. mtmp->m_ap_type = M_AP_NOTHING; 2496. mtmp->mappearance = 0; 2497. 2498. /* 2499. * Discovered mimics don't block light. 2500. */ 2501. if (((old_ap_type == M_AP_FURNITURE && 2502. (old_app == S_hcdoor || old_app == S_vcdoor)) || 2503. (old_ap_type == M_AP_OBJECT && old_app == BOULDER)) && 2504. !does_block(mtmp->mx, mtmp->my, &levl[mtmp->mx][mtmp->my])) 2505. unblock_point(mtmp->mx, mtmp->my); 2506. 2507. newsym(mtmp->mx,mtmp->my); 2508. } 2509. 2510. /* force all chameleons to become normal */ 2511. void 2512. rescham() 2513. { 2514. register struct monst *mtmp; 2515. int mcham; 2516. 2517. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 2518. if (DEADMONSTER(mtmp)) continue; 2519. mcham = (int) mtmp->cham; 2520. if (mcham) { 2521. mtmp->cham = CHAM_ORDINARY; 2522. (void) newcham(mtmp, &mons[cham_to_pm[mcham]], FALSE, 2523. canseemon(mtmp)); 2524. } 2525. if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN) 2526. new_were(mtmp); 2527. if(mtmp->m_ap_type && cansee(mtmp->mx, mtmp->my)) { 2528. seemimic(mtmp); 2529. /* we pretend that the mimic doesn't */ 2530. /* know that it has been unmasked. */ 2531. mtmp->msleeping = 1; 2532. } 2533. } 2534. } 2535. 2536. /* Let the chameleons change again -dgk */ 2537. void 2538. restartcham() 2539. { 2540. register struct monst *mtmp; 2541. 2542. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 2543. if (DEADMONSTER(mtmp)) continue; 2544. mtmp->cham = pm_to_cham(monsndx(mtmp->data)); 2545. if (mtmp->data->mlet == S_MIMIC && mtmp->msleeping && 2546. cansee(mtmp->mx, mtmp->my)) { 2547. set_mimic_sym(mtmp); 2548. newsym(mtmp->mx,mtmp->my); 2549. } 2550. } 2551. } 2552. 2553. /* called when restoring a monster from a saved level; protection 2554. against shape-changing might be different now than it was at the 2555. time the level was saved. */ 2556. void 2557. restore_cham(mon) 2558. struct monst *mon; 2559. { 2560. int mcham; 2561. 2562. if (Protection_from_shape_changers) { 2563. mcham = (int) mon->cham; 2564. if (mcham) { 2565. mon->cham = CHAM_ORDINARY; 2566. (void) newcham(mon, &mons[cham_to_pm[mcham]], FALSE, FALSE); 2567. } else if (is_were(mon->data) && !is_human(mon->data)) { 2568. new_were(mon); 2569. } 2570. } else if (mon->cham == CHAM_ORDINARY) { 2571. mon->cham = pm_to_cham(monsndx(mon->data)); 2572. } 2573. } 2574. 2575. /* unwatched hiders may hide again; if so, a 1 is returned. */ 2576. STATIC_OVL boolean 2577. restrap(mtmp) 2578. register struct monst *mtmp; 2579. { 2580. if(mtmp->cham || mtmp->mcan || mtmp->m_ap_type || 2581. cansee(mtmp->mx, mtmp->my) || rn2(3) || (mtmp == u.ustuck) || 2582. (sensemon(mtmp) && distu(mtmp->mx, mtmp->my) <= 2)) 2583. return(FALSE); 2584. 2585. if(mtmp->data->mlet == S_MIMIC) { 2586. set_mimic_sym(mtmp); 2587. return(TRUE); 2588. } else 2589. if(levl[mtmp->mx][mtmp->my].typ == ROOM) { 2590. mtmp->mundetected = 1; 2591. return(TRUE); 2592. } 2593. 2594. return(FALSE); 2595. } 2596. 2597. short *animal_list = 0; /* list of PM values for animal monsters */ 2598. int animal_list_count; 2599. 2600. void 2601. mon_animal_list(construct) 2602. boolean construct; 2603. { 2604. if (construct) { 2605. short animal_temp[SPECIAL_PM]; 2606. int i, n; 2607. 2608. /* if (animal_list) impossible("animal_list already exists"); */ 2609. 2610. for (n = 0, i = LOW_PM; i < SPECIAL_PM; i++) 2611. if (is_animal(&mons[i])) animal_temp[n++] = i; 2612. /* if (n == 0) animal_temp[n++] = NON_PM; */ 2613. 2614. animal_list = (short *)alloc(n * sizeof *animal_list); 2615. (void) memcpy((genericptr_t)animal_list, 2616. (genericptr_t)animal_temp, 2617. n * sizeof *animal_list); 2618. animal_list_count = n; 2619. } else { /* release */ 2620. if (animal_list) free((genericptr_t)animal_list), animal_list = 0; 2621. animal_list_count = 0; 2622. } 2623. } 2624. 2625. STATIC_OVL int 2626. pick_animal() 2627. { 2628. if (!animal_list) mon_animal_list(TRUE); 2629. 2630. return animal_list[rn2(animal_list_count)]; 2631. } 2632. 2633. STATIC_OVL int 2634. select_newcham_form(mon) 2635. struct monst *mon; 2636. { 2637. int mndx = NON_PM; 2638. 2639. switch (mon->cham) { 2640. case CHAM_SANDESTIN: 2641. if (rn2(7)) mndx = pick_nasty(); 2642. break; 2643. case CHAM_DOPPELGANGER: 2644. if (!rn2(7)) mndx = pick_nasty(); 2645. else if (rn2(3)) mndx = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1, 2646. PM_ARCHEOLOGIST); 2647. break; 2648. case CHAM_CHAMELEON: 2649. if (!rn2(3)) mndx = pick_animal(); 2650. break; 2651. case CHAM_ORDINARY: 2652. { 2653. struct obj *m_armr = which_armor(mon, W_ARM); 2654. 2655. if (m_armr && Is_dragon_scales(m_armr)) 2656. mndx = Dragon_scales_to_pm(m_armr) - mons; 2657. else if (m_armr && Is_dragon_mail(m_armr)) 2658. mndx = Dragon_mail_to_pm(m_armr) - mons; 2659. } 2660. break; 2661. } 2662. #ifdef WIZARD 2663. /* For debugging only: allow control of polymorphed monster; not saved */ 2664. if (wizard && iflags.mon_polycontrol) { 2665. char pprompt[BUFSZ], buf[BUFSZ]; 2666. int tries = 0; 2667. do { 2668. Sprintf(pprompt, 2669. "Change %s into what kind of monster? [type the name]", 2670. mon_nam(mon)); 2671. getlin(pprompt,buf); 2672. mndx = name_to_mon(buf); 2673. if (mndx < LOW_PM) 2674. You("cannot polymorph %s into that.", mon_nam(mon)); 2675. else break; 2676. } while(++tries < 5); 2677. if (tries==5) pline(thats_enough_tries); 2678. } 2679. #endif /*WIZARD*/ 2680. if (mndx == NON_PM) mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM); 2681. return mndx; 2682. } 2683. 2684. 2685. /* make a chameleon look like a new monster; returns 1 if it actually changed */ 2686. /* [ALI] Special case: Don't print a message if hero can neither spot the 2687. * original _or_ the new monster (avoids "It turns into it!"). 2688. */ 2689. int 2690. newcham(mtmp, mdat, polyspot, msg) 2691. struct monst *mtmp; 2692. struct permonst *mdat; 2693. boolean polyspot; /* change is the result of wand or spell of polymorph */ 2694. boolean msg; 2695. { 2696. int mhp, hpn, hpd; 2697. int mndx, tryct; 2698. int couldsee = canseemon(mtmp); 2699. struct permonst *olddata = mtmp->data; 2700. char oldname[BUFSZ]; 2701. boolean alt_mesg = FALSE; /* Avoid "<rank> turns into a <rank>" */ 2702. 2703. if (msg) { 2704. /* like Monnam() but never mention saddle */ 2705. Strcpy(oldname, x_monnam(mtmp, ARTICLE_THE, (char *)0, 2706. SUPPRESS_SADDLE, FALSE)); 2707. oldname[0] = highc(oldname[0]); 2708. } 2709. 2710. /* mdat = 0 -> caller wants a random monster shape */ 2711. tryct = 0; 2712. if(mdat == 0) { 2713. while (++tryct <= 100) { 2714. mndx = select_newcham_form(mtmp); 2715. mdat = &mons[mndx]; 2716. if ((mvitals[mndx].mvflags & G_GENOD) != 0 || 2717. is_placeholder(mdat)) continue; 2718. /* polyok rules out all M2_PNAME and M2_WERE's; 2719. select_newcham_form might deliberately pick a player 2720. character type, so we can't arbitrarily rule out all 2721. human forms any more */ 2722. if (is_mplayer(mdat) || (!is_human(mdat) && polyok(mdat))) 2723. break; 2724. } 2725. if (tryct > 100) return 0; /* Should never happen */ 2726. } else if (mvitals[monsndx(mdat)].mvflags & G_GENOD) 2727. return(0); /* passed in mdat is genocided */ 2728. 2729. if(is_male(mdat)) { 2730. if(mtmp->female) mtmp->female = FALSE; 2731. } else if (is_female(mdat)) { 2732. if(!mtmp->female) mtmp->female = TRUE; 2733. } else if (!is_neuter(mdat)) { 2734. if(!rn2(10)) mtmp->female = !mtmp->female; 2735. } 2736. 2737. if (In_endgame(&u.uz) && is_mplayer(olddata)) { 2738. /* mplayers start out as "Foo the Bar", but some of the 2739. * titles are inappropriate when polymorphed, particularly 2740. * into the opposite sex. players don't use ranks when 2741. * polymorphed, so dropping the rank for mplayers seems 2742. * reasonable. 2743. */ 2744. char *p = index(NAME(mtmp), ' '); 2745. if (p) { 2746. *p = '\0'; 2747. mtmp->mnamelth = p - NAME(mtmp) + 1; 2748. } 2749. } 2750. 2751. if(mdat == mtmp->data) return(0); /* still the same monster */ 2752. 2753. /* [ALI] Detect transforming between player monsters with the 2754. * same rank title to avoid badly formed messages. 2755. * Similarly for were creatures transforming to their alt. form. 2756. */ 2757. if (msg && is_mplayer(olddata) && is_mplayer(mdat)) { 2758. const struct Role *role; 2759. int i, oldmndx; 2760. 2761. mndx = monsndx(mdat); 2762. oldmndx = monsndx(olddata); 2763. for (role = roles; role->name.m; role++) { 2764. if (role->femalenum == NON_PM) 2765. continue; 2766. if ((mndx == role->femalenum && oldmndx == role->malenum) || 2767. (mndx == role->malenum && oldmndx == role->femalenum)) { 2768. /* Find the rank */ 2769. for (i = xlev_to_rank(mtmp->m_lev); i >= 0; i--) 2770. if (role->rank[i].m) { 2771. /* Only need alternate message if no female form */ 2772. alt_mesg = !role->rank[i].f; 2773. break; 2774. } 2775. } 2776. } 2777. } else if (msg && is_were(olddata) && 2778. monsndx(mdat) == counter_were(monsndx(olddata))) 2779. alt_mesg = TRUE; 2780. 2781. /* WAC - At this point, the transformation is going to happen */ 2782. /* Reset values, remove worm tails, change levels...etc. */ 2783. 2784. if(mtmp->wormno) { /* throw tail away */ 2785. wormgone(mtmp); 2786. place_monster(mtmp, mtmp->mx, mtmp->my); 2787. } 2788. 2789. hpn = mtmp->mhp; 2790. hpd = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel; 2791. if(!hpd) hpd = 4; 2792. 2793. mtmp->m_lev = adj_lev(mdat); /* new monster level */ 2794. 2795. mhp = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel; 2796. if(!mhp) mhp = 4; 2797. 2798. /* new hp: same fraction of max as before */ 2799. #ifndef LINT 2800. mtmp->mhp = (int)(((long)hpn*(long)mhp)/(long)hpd); 2801. #endif 2802. if(mtmp->mhp < 0) mtmp->mhp = hpn; /* overflow */ 2803. /* Unlikely but not impossible; a 1HD creature with 1HP that changes into a 2804. 0HD creature will require this statement */ 2805. if (!mtmp->mhp) mtmp->mhp = 1; 2806. 2807. /* and the same for maximum hit points */ 2808. hpn = mtmp->mhpmax; 2809. #ifndef LINT 2810. mtmp->mhpmax = (int)(((long)hpn*(long)mhp)/(long)hpd); 2811. #endif 2812. if(mtmp->mhpmax < 0) mtmp->mhpmax = hpn; /* overflow */ 2813. if (!mtmp->mhpmax) mtmp->mhpmax = 1; 2814. 2815. /* take on the new form... */ 2816. set_mon_data(mtmp, mdat, 0); 2817. 2818. if (emits_light(olddata) != emits_light(mtmp->data)) { 2819. /* used to give light, now doesn't, or vice versa, 2820. or light's range has changed */ 2821. if (emits_light(olddata)) 2822. del_light_source(LS_MONSTER, (genericptr_t)mtmp); 2823. if (emits_light(mtmp->data)) 2824. new_light_source(mtmp->mx, mtmp->my, emits_light(mtmp->data), 2825. LS_MONSTER, (genericptr_t)mtmp); 2826. } 2827. if (!mtmp->perminvis || pm_invisible(olddata)) 2828. mtmp->perminvis = pm_invisible(mdat); 2829. mtmp->minvis = mtmp->invis_blkd ? 0 : mtmp->perminvis; 2830. if (!(hides_under(mdat) && OBJ_AT(mtmp->mx, mtmp->my)) && 2831. !(mdat->mlet == S_EEL && is_pool(mtmp->mx, mtmp->my))) 2832. mtmp->mundetected = 0; 2833. #ifdef STEED 2834. if (u.usteed) { 2835. if (touch_petrifies(u.usteed->data) && 2836. !Stone_resistance && rnl(3)) { 2837. char buf[BUFSZ]; 2838. 2839. pline("You touch %s.", mon_nam(u.usteed)); 2840. Sprintf(buf, "riding %s", an(u.usteed->data->mname)); 2841. instapetrify(buf); 2842. } 2843. if (!can_ride(u.usteed)) dismount_steed(DISMOUNT_POLY); 2844. } 2845. #endif 2846. 2847. #ifndef DCC30_BUG 2848. if (mdat == &mons[PM_LONG_WORM] && (mtmp->wormno = get_wormno()) != 0) { 2849. #else 2850. /* DICE 3.0 doesn't like assigning and comparing mtmp->wormno in the 2851. * same expression. 2852. */ 2853. if (mdat == &mons[PM_LONG_WORM] && 2854. (mtmp->wormno = get_wormno(), mtmp->wormno != 0)) { 2855. #endif 2856. /* we can now create worms with tails - 11/91 */ 2857. initworm(mtmp, rn2(5)); 2858. if (count_wsegs(mtmp)) 2859. place_worm_tail_randomly(mtmp, mtmp->mx, mtmp->my); 2860. } 2861. 2862. newsym(mtmp->mx,mtmp->my); 2863. 2864. if (msg && (u.uswallow && mtmp == u.ustuck || canspotmon(mtmp))) { 2865. if (alt_mesg && is_mplayer(mdat)) 2866. pline("%s is suddenly very %s!", oldname, 2867. mtmp->female ? "feminine" : "masculine"); 2868. else if (alt_mesg) 2869. pline("%s changes into a %s!", oldname, 2870. is_human(mdat) ? "human" : mdat->mname + 4); 2871. else { 2872. uchar save_mnamelth = mtmp->mnamelth; 2873. mtmp->mnamelth = 0; 2874. pline("%s turns into %s!", oldname, 2875. mdat == &mons[PM_GREEN_SLIME] ? "slime" : 2876. x_monnam(mtmp, ARTICLE_A, (char*)0, SUPPRESS_SADDLE, FALSE)); 2877. mtmp->mnamelth = save_mnamelth; 2878. } 2879. } else if (msg && couldsee) 2880. /* No message if we only sensed the monster previously */ 2881. pline("%s suddenly disappears!", oldname); 2882. 2883. /* [ALI] In Slash'EM, this must come _after_ "<mon> turns into <mon>" 2884. * since it's possible to get both messages. 2885. */ 2886. if (u.ustuck == mtmp) { 2887. if(u.uswallow) { 2888. if(!attacktype(mdat,AT_ENGL)) { 2889. /* Does mdat care? */ 2890. if (!noncorporeal(mdat) && !amorphous(mdat) && 2891. !is_whirly(mdat) && 2892. (mdat != &mons[PM_YELLOW_LIGHT])) { 2893. You("break out of %s%s!", mon_nam(mtmp), 2894. (is_animal(mdat)? 2895. "'s stomach" : "")); 2896. mtmp->mhp = 1; /* almost dead */ 2897. } 2898. expels(mtmp, olddata, FALSE); 2899. } else { 2900. /* update swallow glyphs for new monster */ 2901. swallowed(0); 2902. } 2903. } else if (!sticks(mdat) && !sticks(youmonst.data)) 2904. unstuck(mtmp); 2905. } 2906. 2907. possibly_unwield(mtmp, polyspot); /* might lose use of weapon */ 2908. mon_break_armor(mtmp, polyspot); 2909. if (!(mtmp->misc_worn_check & W_ARMG)) 2910. mselftouch(mtmp, "No longer petrify-resistant, ", 2911. !flags.mon_moving); 2912. m_dowear(mtmp, FALSE); 2913. 2914. /* This ought to re-test can_carry() on each item in the inventory 2915. * rather than just checking ex-giants & boulders, but that'd be 2916. * pretty expensive to perform. If implemented, then perhaps 2917. * minvent should be sorted in order to drop heaviest items first. 2918. */ 2919. /* former giants can't continue carrying boulders */ 2920. if (mtmp->minvent && !throws_rocks(mdat)) { 2921. register struct obj *otmp, *otmp2; 2922. 2923. for (otmp = mtmp->minvent; otmp; otmp = otmp2) { 2924. otmp2 = otmp->nobj; 2925. if (otmp->otyp == BOULDER) { 2926. /* this keeps otmp from being polymorphed in the 2927. same zap that the monster that held it is polymorphed */ 2928. if (polyspot) bypass_obj(otmp); 2929. obj_extract_self(otmp); 2930. /* probably ought to give some "drop" message here */ 2931. if (flooreffects(otmp, mtmp->mx, mtmp->my, "")) continue; 2932. place_object(otmp, mtmp->mx, mtmp->my); 2933. } 2934. } 2935. } 2936. 2937. return(1); 2938. } 2939. 2940. /* sometimes an egg will be special */ 2941. #define BREEDER_EGG (!rn2(77)) 2942. 2943. /* 2944. * Determine if the given monster number can be hatched from an egg. 2945. * Return the monster number to use as the egg's corpsenm. Return 2946. * NON_PM if the given monster can't be hatched. 2947. */ 2948. int 2949. can_be_hatched(mnum) 2950. int mnum; 2951. { 2952. /* ranger quest nemesis has the oviparous bit set, making it 2953. be possible to wish for eggs of that unique monster; turn 2954. such into ordinary eggs rather than forbidding them outright */ 2955. if (mnum == PM_SCORPIUS) mnum = PM_SCORPION; 2956. 2957. mnum = little_to_big(mnum); 2958. /* 2959. * Queen bees lay killer bee eggs (usually), but killer bees don't 2960. * grow into queen bees. Ditto for [winged-]gargoyles. 2961. */ 2962. if (mnum == PM_KILLER_BEE || mnum == PM_GARGOYLE || 2963. (lays_eggs(&mons[mnum]) && (BREEDER_EGG || 2964. (mnum != PM_QUEEN_BEE && mnum != PM_WINGED_GARGOYLE)))) 2965. return mnum; 2966. return NON_PM; 2967. } 2968. 2969. /* type of egg laid by #sit; usually matches parent */ 2970. int 2971. egg_type_from_parent(mnum, force_ordinary) 2972. int mnum; /* parent monster; caller must handle lays_eggs() check */ 2973. boolean force_ordinary; 2974. { 2975. if (force_ordinary || !BREEDER_EGG) { 2976. if (mnum == PM_QUEEN_BEE) mnum = PM_KILLER_BEE; 2977. else if (mnum == PM_WINGED_GARGOYLE) mnum = PM_GARGOYLE; 2978. } 2979. return mnum; 2980. } 2981. 2982. /* decide whether an egg of the indicated monster type is viable; */ 2983. /* also used to determine whether an egg or tin can be created... */ 2984. boolean 2985. dead_species(m_idx, egg) 2986. int m_idx; 2987. boolean egg; 2988. { 2989. /* 2990. * For monsters with both baby and adult forms, genociding either 2991. * form kills all eggs of that monster. Monsters with more than 2992. * two forms (small->large->giant mimics) are more or less ignored; 2993. * fortunately, none of them have eggs. Species extinction due to 2994. * overpopulation does not kill eggs. 2995. */ 2996. return (boolean) 2997. (m_idx >= LOW_PM && 2998. ((mvitals[m_idx].mvflags & G_GENOD) != 0 || 2999. (egg && 3000. (mvitals[big_to_little(m_idx)].mvflags & G_GENOD) != 0))); 3001. } 3002. 3003. /* kill off any eggs of genocided monsters */ 3004. STATIC_OVL void 3005. kill_eggs(obj_list) 3006. struct obj *obj_list; 3007. { 3008. struct obj *otmp; 3009. 3010. for (otmp = obj_list; otmp; otmp = otmp->nobj) 3011. if (otmp->otyp == EGG) { 3012. if (dead_species(otmp->corpsenm, TRUE)) { 3013. /* 3014. * It seems we could also just catch this when 3015. * it attempted to hatch, so we wouldn't have to 3016. * search all of the objlists.. or stop all 3017. * hatch timers based on a corpsenm. 3018. */ 3019. kill_egg(otmp); 3020. } 3021. #if 0 /* not used */ 3022. } else if (otmp->otyp == TIN) { 3023. if (dead_species(otmp->corpsenm, FALSE)) 3024. otmp->corpsenm = NON_PM; /* empty tin */ 3025. } else if (otmp->otyp == CORPSE) { 3026. if (dead_species(otmp->corpsenm, FALSE)) 3027. ; /* not yet implemented... */ 3028. #endif 3029. } else if (Has_contents(otmp)) { 3030. kill_eggs(otmp->cobj); 3031. } 3032. } 3033. 3034. /* kill all members of genocided species */ 3035. void 3036. kill_genocided_monsters() 3037. { 3038. struct monst *mtmp, *mtmp2; 3039. boolean kill_cham[CHAM_MAX_INDX+1]; 3040. int mndx; 3041. 3042. kill_cham[CHAM_ORDINARY] = FALSE; /* (this is mndx==0) */ 3043. for (mndx = 1; mndx <= CHAM_MAX_INDX; mndx++) 3044. kill_cham[mndx] = (mvitals[cham_to_pm[mndx]].mvflags & G_GENOD) != 0; 3045. /* 3046. * Called during genocide, and again upon level change. The latter 3047. * catches up with any migrating monsters as they finally arrive at 3048. * their intended destinations, so possessions get deposited there. 3049. * 3050. * Chameleon handling: 3051. * 1) if chameleons have been genocided, destroy them 3052. * regardless of current form; 3053. * 2) otherwise, force every chameleon which is imitating 3054. * any genocided species to take on a new form. 3055. */ 3056. for (mtmp = fmon; mtmp; mtmp = mtmp2) { 3057. mtmp2 = mtmp->nmon; 3058. if (DEADMONSTER(mtmp)) continue; 3059. mndx = monsndx(mtmp->data); 3060. if ((mvitals[mndx].mvflags & G_GENOD) || kill_cham[mtmp->cham]) { 3061. if (mtmp->cham && !kill_cham[mtmp->cham]) 3062. /* [ALI] Chameleons are not normally subject to 3063. * system shock, but genocide is a special case. 3064. */ 3065. (void) mon_spec_poly(mtmp, (struct permonst *)0, 0L, 3066. FALSE, FALSE, TRUE, TRUE); 3067. else 3068. mondead(mtmp); 3069. } 3070. if (mtmp->minvent) kill_eggs(mtmp->minvent); 3071. } 3072. 3073. kill_eggs(invent); 3074. kill_eggs(fobj); 3075. kill_eggs(level.buriedobjlist); 3076. } 3077. 3078. #endif /* OVL2 */ 3079. #ifdef OVLB 3080. 3081. void 3082. golemeffects(mon, damtype, dam) 3083. register struct monst *mon; 3084. int damtype, dam; 3085. { 3086. int heal=0, slow=0; 3087. 3088. if (mon->data == &mons[PM_FLESH_GOLEM]) { 3089. if (damtype == AD_ELEC) heal = dam / 6; 3090. else if (damtype == AD_FIRE || damtype == AD_COLD) slow = 1; 3091. } else if (mon->data == &mons[PM_IRON_GOLEM]) { 3092. if (damtype == AD_ELEC) slow = 1; 3093. else if (damtype == AD_FIRE) heal = dam; 3094. } else { 3095. return; 3096. } 3097. if (slow) { 3098. if (mon->mspeed != MSLOW) 3099. mon_adjust_speed(mon, -1, (struct obj *)0); 3100. } 3101. if (heal) { 3102. if (mon->mhp < mon->mhpmax) { 3103. mon->mhp += dam; 3104. if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 3105. if (cansee(mon->mx, mon->my)) 3106. pline("%s seems healthier.", Monnam(mon)); 3107. } 3108. } 3109. } 3110. 3111. boolean 3112. angry_guards(silent) 3113. register boolean silent; 3114. { 3115. register struct monst *mtmp; 3116. register int ct = 0, nct = 0, sct = 0, slct = 0; 3117. 3118. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 3119. if (DEADMONSTER(mtmp)) continue; 3120. if((mtmp->data == &mons[PM_WATCHMAN] || 3121. mtmp->data == &mons[PM_WATCH_CAPTAIN]) 3122. && mtmp->mpeaceful) { 3123. ct++; 3124. if(cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) { 3125. if (distu(mtmp->mx, mtmp->my) == 2) nct++; 3126. else sct++; 3127. } 3128. if (mtmp->msleeping || mtmp->mfrozen) { 3129. slct++; 3130. mtmp->msleeping = mtmp->mfrozen = 0; 3131. } 3132. mtmp->mpeaceful = 0; 3133. } 3134. } 3135. if(ct) { 3136. if(!silent) { /* do we want pline msgs? */ 3137. if(slct) pline_The("guard%s wake%s up!", 3138. slct > 1 ? "s" : "", slct == 1 ? "s" : ""); 3139. if(nct || sct) { 3140. if(nct) pline_The("guard%s get%s angry!", 3141. nct == 1 ? "" : "s", nct == 1 ? "s" : ""); 3142. else if(!Blind) 3143. You("see %sangry guard%s approaching!", 3144. sct == 1 ? "an " : "", sct > 1 ? "s" : ""); 3145. } else if(flags.soundok) 3146. You_hear("the shrill sound of a guard's whistle."); 3147. } 3148. return(TRUE); 3149. } 3150. return(FALSE); 3151. } 3152. 3153. void 3154. pacify_guards() 3155. { 3156. register struct monst *mtmp; 3157. 3158. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 3159. if (DEADMONSTER(mtmp)) continue; 3160. if (mtmp->data == &mons[PM_WATCHMAN] || 3161. mtmp->data == &mons[PM_WATCH_CAPTAIN]) 3162. mtmp->mpeaceful = 1; 3163. } 3164. } 3165. 3166. void 3167. mimic_hit_msg(mtmp, otyp) 3168. struct monst *mtmp; 3169. short otyp; 3170. { 3171. short ap = mtmp->mappearance; 3172. 3173. switch(mtmp->m_ap_type) { 3174. case M_AP_NOTHING: 3175. case M_AP_FURNITURE: 3176. case M_AP_MONSTER: 3177. break; 3178. case M_AP_OBJECT: 3179. if (otyp == SPE_HEALING || otyp == SPE_EXTRA_HEALING) { 3180. pline("%s seems a more vivid %s than before.", 3181. The(simple_typename(ap)), 3182. c_obj_colors[objects[ap].oc_color]); 3183. } 3184. break; 3185. } 3186. } 3187. #endif /* OVLB */ 3188. 3189. /*mon.c*/