Source:NetHack 3.1.0/mhitm.c
Jump to navigation
Jump to search
Below is the full text to mhitm.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/mhitm.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)mhitm.c 3.1 92/12/10 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "artifact.h" 7. #include "edog.h" 8. 9. #ifdef OVLB 10. 11. static boolean NEARDATA vis, NEARDATA far_noise; 12. static long NEARDATA noisetime; 13. static struct obj NEARDATA *otmp; 14. 15. static void FDECL(mrustm, (struct monst *, struct monst *, struct obj *)); 16. static int FDECL(hitmm, (struct monst *,struct monst *,struct attack *)); 17. static int FDECL(gazemm, (struct monst *,struct monst *,struct attack *)); 18. static int FDECL(gulpmm, (struct monst *,struct monst *,struct attack *)); 19. static int FDECL(explmm, (struct monst *,struct monst *,struct attack *)); 20. static int FDECL(mdamagem, (struct monst *,struct monst *,struct attack *)); 21. static void FDECL(mswingsm, (struct monst *, struct monst *, struct obj *)); 22. static void FDECL(noises,(struct monst *,struct attack *)); 23. static void FDECL(missmm,(struct monst *,struct monst *,struct attack *)); 24. static int FDECL(passivemm, (struct monst *, struct monst *, BOOLEAN_P, int)); 25. 26. /* Needed for the special case of monsters wielding vorpal blades (rare). 27. * If we use this a lot it should probably be a parameter to mdamagem() 28. * instead of a global variable. 29. */ 30. static int dieroll; 31. 32. static void 33. noises(magr, mattk) 34. register struct monst *magr; 35. register struct attack *mattk; 36. { 37. boolean farq = (distu(magr->mx, magr->my) > 15); 38. 39. if(flags.soundok && (farq != far_noise || moves-noisetime > 10)) { 40. far_noise = farq; 41. noisetime = moves; 42. You("hear %s%s.", 43. (mattk->aatyp == AT_EXPL) ? "an explosion" : "some noises", 44. farq ? " in the distance" : ""); 45. } 46. } 47. 48. static 49. void 50. missmm(magr, mdef, mattk) 51. register struct monst *magr, *mdef; 52. struct attack *mattk; 53. { 54. const char *fmt; 55. char buf[BUFSZ]; 56. 57. if (vis) { 58. if (mdef->m_ap_type) seemimic(mdef); 59. if (magr->m_ap_type) seemimic(magr); 60. fmt = (could_seduce(magr,mdef,mattk) && !magr->mcan) ? 61. "%s pretends to be friendly to" : "%s misses"; 62. Sprintf(buf, fmt, Monnam(magr)); 63. pline("%s %s.", buf, mon_nam(mdef)); 64. } else noises(magr, mattk); 65. } 66. 67. /* 68. * fightm() -- fight some other monster 69. * 70. * Returns: 71. * 0 - Monster did nothing. 72. * 1 - If the monster made an attack. The monster might have died. 73. * 74. * There is an exception to the above. If mtmp has the hero swallowed, 75. * then we report that the monster did nothing so it will continue to 76. * digest the hero. 77. */ 78. int 79. fightm(mtmp) /* have monsters fight each other */ 80. register struct monst *mtmp; 81. { 82. register struct monst *mon, *nmon; 83. int result, has_u_swallowed; 84. #ifdef LINT 85. nmon = 0; 86. #endif 87. /* perhaps the monster will resist Conflict */ 88. if(resist(mtmp, RING_CLASS, 0, 0)) 89. return(0); 90. #ifdef POLYSELF 91. if(u.ustuck == mtmp) { 92. /* perhaps we're holding it... */ 93. if(itsstuck(mtmp)) 94. return(0); 95. } 96. #endif 97. has_u_swallowed = (u.uswallow && (mtmp == u.ustuck)); 98. 99. for(mon = fmon; mon; mon = nmon) { 100. nmon = mon->nmon; 101. if(nmon == mtmp) nmon = mtmp->nmon; 102. if(mon != mtmp) { 103. if(monnear(mtmp,mon->mx,mon->my)) { 104. if(!u.uswallow && (mtmp == u.ustuck)) { 105. if(!rn2(4)) { 106. pline("%s releases you!", Monnam(mtmp)); 107. u.ustuck = 0; 108. } else 109. break; 110. } 111. 112. /* mtmp can be killed */ 113. bhitpos.x = mon->mx; 114. bhitpos.y = mon->my; 115. result = mattackm(mtmp,mon); 116. 117. if (result & MM_AGR_DIED) return 1; /* mtmp died */ 118. /* 119. * If mtmp has the hero swallowed, lie and say there 120. * was no attack (this allows mtmp to digest the hero). 121. */ 122. if (has_u_swallowed) return 0; 123. 124. return ((result & MM_HIT) ? 1 : 0); 125. } 126. } 127. } 128. return 0; 129. } 130. 131. /* 132. * mattackm() -- a monster attacks another monster. 133. * 134. * This function returns a result bitfield: 135. * 136. * --------- agressor died 137. * / ------- defender died 138. * / / ----- defender was hit 139. * / / / 140. * x x x 141. * 142. * 0x4 MM_AGR_DIED 143. * 0x2 MM_DEF_DIED 144. * 0x1 MM_HIT 145. * 0x0 MM_MISS 146. * 147. * Each successive attack has a lower probability of hitting. Some rely on the 148. * success of previous attacks. ** this doen't seem to be implemented -dl ** 149. * 150. * In the case of exploding monsters, the monster dies as well. 151. */ 152. int 153. mattackm(magr, mdef) 154. register struct monst *magr,*mdef; 155. { 156. int i, /* loop counter */ 157. tmp, /* amour class difference */ 158. strike, /* hit this attack */ 159. attk, /* attack attempted this time */ 160. struck = 0, /* hit at least once */ 161. res[NATTK]; /* results of all attacks */ 162. struct attack *mattk; 163. struct permonst *pa, *pd; 164. 165. if (!magr || !mdef) return(MM_MISS); /* mike@genat */ 166. pa = magr->data; pd = mdef->data; 167. if (!magr->mcanmove) return(MM_MISS); /* riv05!a3 */ 168. 169. /* Grid bugs cannot attack at an angle. */ 170. if (pa == &mons[PM_GRID_BUG] && magr->mx != mdef->mx 171. && magr->my != mdef->my) 172. return(MM_MISS); 173. 174. /* Calculate the armour class differential. */ 175. tmp = find_mac(mdef) + magr->m_lev; 176. if (mdef->mconf || !mdef->mcanmove || mdef->msleep){ 177. tmp += 4; 178. if (mdef->msleep) mdef->msleep = 0; 179. } 180. 181. /* undetect monsters become un-hidden if they are attacked */ 182. if (mdef->mundetected) { 183. mdef->mundetected = 0; 184. newsym(mdef->mx, mdef->my); 185. if(canseemon(mdef)) 186. pline("Suddenly, you notice %s.", a_monnam(mdef)); 187. } 188. 189. /* Elves hate orcs. */ 190. if (is_elf(pa) && is_orc(pd)) tmp++; 191. 192. 193. /* Set up the visibility of action */ 194. vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my)); 195. 196. /* Set flag indicating monster has moved this turn. Necessary since a 197. * monster might get an attack out of sequence (i.e. before its move) in 198. * some cases, in which case this still counts as its move for the round 199. * and it shouldn't move again. 200. */ 201. magr->mlstmv = monstermoves; 202. 203. /* Now perform all attacks for the monster. */ 204. for (i = 0; i < NATTK; i++) { 205. res[i] = MM_MISS; 206. mattk = &(pa->mattk[i]); 207. otmp = (struct obj *)0; 208. attk = 1; 209. switch (mattk->aatyp) { 210. case AT_WEAP: /* "hand to hand" attacks */ 211. #ifdef MUSE 212. if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) { 213. magr->weapon_check = NEED_HTH_WEAPON; 214. if (mon_wield_item(magr) != 0) return 0; 215. } 216. otmp = MON_WEP(magr); 217. #else 218. otmp = select_hwep(magr); 219. #endif 220. if (otmp) { 221. if (vis) mswingsm(magr, mdef, otmp); 222. tmp += hitval(otmp, pd); 223. } 224. /* fall through */ 225. case AT_CLAW: 226. case AT_KICK: 227. case AT_BITE: 228. case AT_STNG: 229. case AT_TUCH: 230. case AT_BUTT: 231. case AT_TENT: 232. dieroll = rnd(20 + i); 233. strike = (tmp > dieroll); 234. if (strike) 235. res[i] = hitmm(magr, mdef, mattk); 236. else 237. missmm(magr, mdef, mattk); 238. break; 239. 240. case AT_HUGS: /* automatic if prev two attacks succeed */ 241. strike = (i >= 2 && res[i-1] == MM_HIT && res[i-2] == MM_HIT); 242. if (strike) 243. res[i] = hitmm(magr, mdef, mattk); 244. 245. break; 246. 247. case AT_GAZE: 248. strike = 0; /* will not wake up a sleeper */ 249. res[i] = gazemm(magr, mdef, mattk); 250. break; 251. 252. case AT_EXPL: 253. strike = 1; /* automatic hit */ 254. res[i] = explmm(magr, mdef, mattk); 255. break; 256. 257. case AT_ENGL: 258. /* Engulfing attacks are directed at the hero if 259. * possible. -dlc 260. */ 261. if (u.uswallow && magr == u.ustuck) 262. strike = 0; 263. else { 264. if ((strike = (tmp > rnd(20+i)))) 265. res[i] = gulpmm(magr, mdef, mattk); 266. else 267. missmm(magr, mdef, mattk); 268. } 269. break; 270. 271. default: /* no attack */ 272. strike = 0; 273. attk = 0; 274. break; 275. } 276. 277. if (attk && !(res[i] & MM_AGR_DIED)) 278. res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED); 279. 280. if (res[i] & MM_DEF_DIED) return res[i]; 281. 282. /* 283. * Wake up the defender. NOTE: this must follow the check 284. * to see if the defender died. We don't want to modify 285. * unallocated monsters! 286. */ 287. if (strike) mdef->msleep = 0; 288. 289. if (res[i] & MM_AGR_DIED) return res[i]; 290. /* return if aggressor can no longer attack */ 291. if (!magr->mcanmove || magr->msleep) return res[i]; 292. if (res[i] & MM_HIT) struck = 1; /* at least one hit */ 293. } 294. 295. return(struck ? MM_HIT : MM_MISS); 296. } 297. 298. /* Returns the result of mdamagem(). */ 299. static int 300. hitmm(magr, mdef, mattk) 301. register struct monst *magr,*mdef; 302. struct attack *mattk; 303. { 304. if(vis){ 305. int compat; 306. char buf[BUFSZ]; 307. 308. if(mdef->m_ap_type) seemimic(mdef); 309. if(magr->m_ap_type) seemimic(magr); 310. if((compat = could_seduce(magr,mdef,mattk)) && !magr->mcan) { 311. Sprintf(buf, "%s %s", Monnam(magr), 312. mdef->mcansee ? "smiles at" : "talks to"); 313. pline("%s %s %s.", buf, mon_nam(mdef), 314. compat == 2 ? 315. "engagingly" : "seductively"); 316. } else { 317. char magr_name[BUFSZ]; 318. 319. Strcpy(magr_name, Monnam(magr)); 320. switch (mattk->aatyp) { 321. case AT_BITE: 322. Sprintf(buf,"%s bites", magr_name); 323. break; 324. case AT_STNG: 325. Sprintf(buf,"%s stings", magr_name); 326. break; 327. case AT_BUTT: 328. Sprintf(buf,"%s butts", magr_name); 329. break; 330. case AT_TUCH: 331. Sprintf(buf,"%s touches", magr_name); 332. break; 333. case AT_TENT: 334. Sprintf(buf, "%s tentacles suck", 335. s_suffix(magr_name)); 336. break; 337. case AT_HUGS: 338. if (magr != u.ustuck) { 339. Sprintf(buf,"%s squeezes", magr_name); 340. break; 341. } 342. default: 343. Sprintf(buf,"%s hits", magr_name); 344. } 345. } 346. pline("%s %s.", buf, mon_nam(mdef)); 347. } else noises(magr, mattk); 348. return(mdamagem(magr, mdef, mattk)); 349. } 350. 351. /* Returns the same values as mdamagem(). */ 352. static int 353. gazemm(magr, mdef, mattk) 354. register struct monst *magr, *mdef; 355. struct attack *mattk; 356. { 357. char buf[BUFSZ]; 358. 359. if(vis) { 360. Sprintf(buf,"%s gazes at", Monnam(magr)); 361. pline("%s %s.", buf, mon_nam(mdef)); 362. } 363. 364. if (!mdef->mcansee || mdef->msleep) { 365. if(vis) pline("but nothing happens."); 366. return(MM_MISS); 367. } 368. 369. return(mdamagem(magr, mdef, mattk)); 370. } 371. 372. /* Returns the same values as mattackm(). */ 373. static int 374. gulpmm(magr, mdef, mattk) 375. register struct monst *magr, *mdef; 376. register struct attack *mattk; 377. { 378. xchar ax, ay, dx, dy; 379. int status; 380. char buf[BUFSZ]; 381. 382. if (mdef->data->msize >= MZ_HUGE) return MM_MISS; 383. 384. if (vis) { 385. Sprintf(buf,"%s swallows", Monnam(magr)); 386. pline("%s %s.", buf, mon_nam(mdef)); 387. } 388. 389. /* 390. * All of this maniuplation is needed to keep the display correct. 391. * There is a flush at the next pline(). 392. */ 393. ax = magr->mx; 394. ay = magr->my; 395. dx = mdef->mx; 396. dy = mdef->my; 397. /* 398. * Leave the defender in the monster chain at it's current position, 399. * but don't leave it on the screen. Move the agressor to the def- 400. * ender's position. 401. */ 402. remove_monster(ax, ay); 403. place_monster(magr, dx, dy); 404. newsym(ax,ay); /* erase old position */ 405. newsym(dx,dy); /* update new position */ 406. 407. status = mdamagem(magr, mdef, mattk); 408. 409. if ((status & MM_AGR_DIED) && (status & MM_DEF_DIED)) { 410. ; /* both died -- do nothing */ 411. } 412. else if (status & MM_DEF_DIED) { /* defender died */ 413. /* 414. * Note: remove_monster() was called in relmon(), wiping out 415. * magr from level.monsters[mdef->mx][mdef->my]. We need to 416. * put it back and display it. -kd 417. */ 418. place_monster(magr, dx, dy); 419. newsym(dx, dy); 420. } 421. else if (status & MM_AGR_DIED) { /* agressor died */ 422. place_monster(mdef, dx, dy); 423. newsym(dx, dy); 424. } 425. else { /* both alive, put them back */ 426. if (cansee(dx, dy)) 427. pline("%s is regurgitated!", Monnam(mdef)); 428. 429. place_monster(magr, ax, ay); 430. place_monster(mdef, dx, dy); 431. newsym(ax, ay); 432. newsym(dx, dy); 433. } 434. 435. return status; 436. } 437. 438. static int 439. explmm(magr, mdef, mattk) 440. register struct monst *magr, *mdef; 441. register struct attack *mattk; 442. { 443. int result, was_tame; 444. 445. if(cansee(magr->mx, magr->my)) 446. pline("%s explodes!", Monnam(magr)); 447. else noises(magr, mattk); 448. 449. was_tame = magr->mtame; 450. result = mdamagem(magr, mdef, mattk); 451. 452. /* The attacker could have died . . */ 453. if (was_tame) 454. You("have a sad feeling for a moment, then it passes."); 455. 456. /* Kill off agressor if it didn't die. */ 457. if (!(result & MM_AGR_DIED)) { 458. mondead(magr); 459. result |= MM_AGR_DIED; 460. } 461. 462. return result; 463. } 464. 465. static const char psf[] = 466. "have a peculiarly sad feeling for a moment, then it passes."; 467. 468. /* 469. * See comment at top of mattackm(), for return values. 470. */ 471. static int 472. mdamagem(magr, mdef, mattk) 473. register struct monst *magr, *mdef; 474. register struct attack *mattk; 475. { 476. struct permonst *pa = magr->data, *pd = mdef->data; 477. int tmp = d((int)mattk->damn,(int)mattk->damd); 478. char buf[BUFSZ]; 479. 480. if (pd == &mons[PM_COCKATRICE] && !resists_ston(pa) && 481. (mattk->aatyp != AT_WEAP || !otmp) && 482. (mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL) && 483. #ifdef MUSE 484. (!which_armor(magr, W_ARMG))) { 485. #else 486. (!is_mercenary(pa) || !m_carrying(magr, LEATHER_GLOVES))) { 487. /* Note: other monsters may carry gloves, only soldiers have them */ 488. /* as their "armor" and can be said to wear them */ 489. #endif 490. if (poly_when_stoned(pa)) { 491. mon_to_stone(magr); 492. return MM_HIT; /* no damage during the polymorph */ 493. } 494. if (vis) pline("%s turns to stone!", Monnam(magr)); 495. else if (magr->mtame) You(psf); 496. monstone(magr); 497. return MM_AGR_DIED; 498. } 499. 500. switch(mattk->adtyp) { 501. case AD_DGST: 502. if(flags.verbose && flags.soundok) verbalize("Burrrrp!"); 503. tmp = mdef->mhp; 504. break; 505. case AD_STUN: 506. if (magr->mcan) break; 507. if(vis) pline("%s staggers for a moment.", Monnam(mdef)); 508. mdef->mstun = 1; 509. /* fall through */ 510. case AD_WERE: 511. case AD_HEAL: 512. case AD_LEGS: 513. case AD_PHYS: 514. if (mattk->aatyp == AT_KICK && thick_skinned(pd)) 515. tmp = 0; 516. else if(mattk->aatyp == AT_WEAP) { 517. if(otmp) { 518. tmp += dmgval(otmp, pd); 519. if (otmp->oartifact) { 520. (void)artifact_hit(magr,mdef, otmp, &tmp, dieroll); 521. if (mdef->mhp <= 0) 522. return (MM_DEF_DIED | 523. (grow_up(magr,mdef) ? 0 : MM_AGR_DIED)); 524. } 525. if (tmp) 526. mrustm(magr, mdef, otmp); 527. } 528. } 529. break; 530. case AD_FIRE: 531. if (magr->mcan) { 532. tmp = 0; 533. break; 534. } 535. if(vis) pline("%s is on fire!", Monnam(mdef)); 536. tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); 537. tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); 538. if(resists_fire(pd)) { 539. if (vis) 540. pline("The fire doesn't seem to burn %s!", 541. mon_nam(mdef)); 542. shieldeff(mdef->mx, mdef->my); 543. golemeffects(mdef, AD_FIRE, tmp); 544. tmp = 0; 545. } 546. /* only potions damage resistant players in destroy_item */ 547. tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); 548. break; 549. case AD_COLD: 550. if (magr->mcan) { 551. tmp = 0; 552. break; 553. } 554. if(vis) pline("%s is covered in frost!", Monnam(mdef)); 555. if(resists_cold(pd)) { 556. if (vis) 557. pline("The frost doesn't seem to chill %s!", 558. mon_nam(mdef)); 559. shieldeff(mdef->mx, mdef->my); 560. golemeffects(mdef, AD_COLD, tmp); 561. tmp = 0; 562. } 563. tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD); 564. break; 565. case AD_ELEC: 566. if (magr->mcan) { 567. tmp = 0; 568. break; 569. } 570. if(vis) pline("%s gets zapped!", Monnam(mdef)); 571. tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); 572. if(resists_elec(pd)) { 573. if (vis) pline("The zap doesn't shock %s!", mon_nam(mdef)); 574. shieldeff(mdef->mx, mdef->my); 575. golemeffects(mdef, AD_ELEC, tmp); 576. tmp = 0; 577. } 578. /* only rings damage resistant players in destroy_item */ 579. tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC); 580. break; 581. case AD_ACID: 582. if (magr->mcan) { 583. tmp = 0; 584. break; 585. } 586. if(resists_acid(pd)) { 587. if (vis) 588. pline("%s is covered in acid, but it seems harmless.", 589. Monnam(mdef)); 590. tmp = 0; 591. } else if (vis) { 592. pline("%s is covered in acid!", Monnam(mdef)); 593. pline("It burns %s!", mon_nam(mdef)); 594. } 595. break; 596. case AD_RUST: 597. if (!magr->mcan && pd == &mons[PM_IRON_GOLEM]) { 598. if (vis) pline("%s falls to pieces!", Monnam(mdef)); 599. else if(mdef->mtame) 600. pline("May %s rust in peace.", mon_nam(mdef)); 601. mondied(mdef); 602. return (MM_DEF_DIED | (grow_up(magr,mdef) ? 603. 0 : MM_AGR_DIED)); 604. } 605. tmp = 0; 606. break; 607. case AD_DCAY: 608. if (!magr->mcan && (pd == &mons[PM_WOOD_GOLEM] || 609. pd == &mons[PM_LEATHER_GOLEM])) { 610. if (vis) pline("%s falls to pieces!", Monnam(mdef)); 611. else if(mdef->mtame) 612. pline("May %s rot in peace.", mon_nam(mdef)); 613. mondied(mdef); 614. return (MM_DEF_DIED | (grow_up(magr,mdef) ? 615. 0 : MM_AGR_DIED)); 616. } 617. tmp = 0; 618. break; 619. case AD_STON: 620. if(poly_when_stoned(pd)) { 621. mon_to_stone(mdef); 622. tmp = 0; 623. break; 624. } 625. if(!resists_ston(pd)) { 626. if(vis) pline("%s turns to stone!", Monnam(mdef)); 627. else if(mdef->mtame) You(psf); 628. monstone(mdef); 629. return (MM_DEF_DIED | (grow_up(magr,mdef) ? 630. 0 : MM_AGR_DIED)); 631. } 632. tmp = 0; /* no damage if this fails */ 633. break; 634. case AD_TLPT: 635. if(!magr->mcan && tmp < mdef->mhp) { 636. rloc(mdef); 637. if(vis && !cansee(mdef->mx, mdef->my)) 638. pline("%s suddenly disappears!", Monnam(mdef)); 639. } 640. break; 641. case AD_SLEE: 642. if(!resists_sleep(pd) && !magr->mcan && !mdef->msleep 643. && mdef->mcanmove) { 644. if (vis) { 645. Strcpy(buf, Monnam(mdef)); 646. pline("%s is put to sleep by %s.", buf, mon_nam(magr)); 647. } 648. mdef->mcanmove = 0; 649. mdef->mfrozen = rnd(10); 650. } 651. break; 652. case AD_PLYS: 653. if(!magr->mcan && mdef->mcanmove) { 654. if (vis) { 655. Strcpy(buf, Monnam(mdef)); 656. pline("%s is frozen by %s.", buf, mon_nam(magr)); 657. } 658. mdef->mcanmove = 0; 659. mdef->mfrozen = rnd(10); 660. } 661. break; 662. case AD_SLOW: 663. if(!magr->mcan && vis && mdef->mspeed != MSLOW) { 664. if (vis) pline("%s slows down.", Monnam(mdef)); 665. if (mdef->mspeed == MFAST) mdef->mspeed = 0; 666. else mdef->mspeed = MSLOW; 667. } 668. break; 669. case AD_CONF: 670. /* Since confusing another monster doesn't have a real time 671. * limit, setting spec_used would not really be right (though 672. * we still should check for it). 673. */ 674. if (!magr->mcan && vis && !mdef->mconf && !magr->mspec_used) { 675. pline("%s looks confused.", Monnam(mdef)); 676. mdef->mconf = 1; 677. } 678. break; 679. case AD_BLND: 680. if (!magr->mcan && haseyes(pd)) { 681. register unsigned rnd_tmp; 682. 683. if (vis && mdef->mcansee) 684. pline("%s is blinded.", Monnam(mdef)); 685. rnd_tmp = d((int)mattk->damn, (int)mattk->damd); 686. if ((rnd_tmp += mdef->mblinded) > 127) rnd_tmp = 127; 687. mdef->mblinded = rnd_tmp; 688. mdef->mcansee = 0; 689. } 690. tmp = 0; 691. break; 692. case AD_CURS: 693. if (!night() && (pa == &mons[PM_GREMLIN])) break; 694. if (!magr->mcan && !rn2(10)) { 695. if (is_were(pd) && pd->mlet != S_HUMAN) 696. were_change(mdef); 697. if (pd == &mons[PM_CLAY_GOLEM]) { 698. if (vis) { 699. pline("Some writing vanishes from %s head!", 700. s_suffix(mon_nam(mdef))); 701. pline("%s dies!", Monnam(mdef)); 702. } 703. else if (mdef->mtame) 704. You("have a strangely sad feeling for a moment, then it passes."); 705. mondied(mdef); 706. return (MM_DEF_DIED | (grow_up(magr,mdef) ? 707. 0 : MM_AGR_DIED)); 708. } 709. mdef->mcan = 1; 710. if (flags.soundok) { 711. if (!vis) You("hear laughter."); 712. else pline("%s chuckles.", Monnam(magr)); 713. } 714. } 715. break; 716. case AD_SGLD: 717. tmp = 0; 718. if (magr->mcan || !mdef->mgold) break; 719. /* technically incorrect; no check for stealing gold from 720. * between mdef's feet... 721. */ 722. magr->mgold += mdef->mgold; 723. mdef->mgold = 0; 724. if (vis) { 725. Strcpy(buf, Monnam(magr)); 726. pline("%s steals some gold from %s.", buf, 727. mon_nam(mdef)); 728. } 729. break; 730. case AD_DRLI: 731. if(rn2(2) && !resists_drli(pd)) { 732. tmp = d(2,6); 733. if (vis) 734. pline("%s suddenly seems weaker!", Monnam(mdef)); 735. mdef->mhpmax -= tmp; 736. if (mdef->m_lev == 0) 737. tmp = mdef->mhp; 738. else mdef->m_lev--; 739. /* Automatic kill if drained past level 0 */ 740. } 741. break; 742. #ifdef SEDUCE 743. case AD_SSEX: 744. #endif 745. case AD_SITM: /* for now these are the same */ 746. case AD_SEDU: 747. if (!magr->mcan && mdef->minvent) { 748. otmp = mdef->minvent; 749. mdef->minvent = otmp->nobj; 750. otmp->nobj = magr->minvent; 751. magr->minvent = otmp; 752. if (vis) { 753. Strcpy(buf, Monnam(magr)); 754. pline("%s steals %s from %s!", buf, 755. doname(otmp), mon_nam(mdef)); 756. } 757. #ifdef MUSE 758. possibly_unwield(mdef); 759. if (otmp->owornmask) { 760. mdef->misc_worn_check &= ~otmp->owornmask; 761. otmp->owornmask = 0; 762. } 763. #endif 764. } 765. tmp = 0; 766. break; 767. case AD_DRST: 768. case AD_DRDX: 769. case AD_DRCO: 770. if (!magr->mcan && !rn2(8)) { 771. if (vis) 772. pline("%s %s was poisoned!", s_suffix(Monnam(magr)), 773. mattk->aatyp==AT_BITE ? "bite" : "sting"); 774. if (resists_poison(pd)) { 775. if (vis) 776. pline("The poison doesn't seem to affect %s.", 777. mon_nam(mdef)); 778. } else { 779. if (rn2(10)) tmp += rn1(10,6); 780. else { 781. if (vis) pline("The poison was deadly..."); 782. tmp = mdef->mhp; 783. } 784. } 785. } 786. break; 787. case AD_DRIN: 788. if (!has_head(pd)) { 789. if (vis) pline("%s doesn't seem harmed.", Monnam(mdef)); 790. tmp = 0; 791. break; 792. } 793. #ifdef MUSE 794. if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { 795. if (vis) { 796. Strcpy(buf, s_suffix(Monnam(mdef))); 797. pline("%s helmet blocks %s attack to his head.", 798. buf, s_suffix(mon_nam(magr))); 799. } 800. break; 801. } 802. #endif 803. if (vis) pline("%s brain is eaten!", s_suffix(Monnam(mdef))); 804. if (mindless(pd)) { 805. if (vis) pline("%s doesn't notice.", Monnam(mdef)); 806. break; 807. } 808. tmp += rnd(10); /* fakery, since monsters lack INT scores */ 809. if (magr->mtame && !magr->isminion) { 810. EDOG(magr)->hungrytime += rnd(60); 811. magr->mconf = 0; 812. } 813. if (tmp >= mdef->mhp && vis) 814. pline("%s last thought fades away...", 815. s_suffix(Monnam(mdef))); 816. break; 817. case AD_STCK: 818. case AD_WRAP: /* monsters cannot grab one another, it's too hard */ 819. break; 820. default: tmp = 0; 821. break; 822. } 823. if(!tmp) return(MM_MISS); 824. 825. if((mdef->mhp -= tmp) < 1) { 826. if (m_at(mdef->mx, mdef->my) == magr) { /* see gulpmm() */ 827. remove_monster(mdef->mx, mdef->my); 828. place_monster(mdef, mdef->mx, mdef->my); 829. } 830. monkilled(mdef, "", mattk->adtyp); 831. return (MM_DEF_DIED | (grow_up(magr,mdef) ? 0 : MM_AGR_DIED)); 832. } 833. return(MM_HIT); 834. } 835. 836. #endif /* OVLB */ 837. 838. 839. #ifdef OVL0 840. 841. int 842. noattacks(ptr) /* returns 1 if monster doesn't attack */ 843. struct permonst *ptr; 844. { 845. int i; 846. 847. for(i = 0; i < NATTK; i++) 848. if(ptr->mattk[i].aatyp) return(0); 849. 850. return(1); 851. } 852. 853. #endif /* OVL0 */ 854. #ifdef OVLB 855. 856. static void 857. mrustm(magr, mdef, obj) 858. register struct monst *magr, *mdef; 859. register struct obj *obj; 860. { 861. if (!magr || !mdef || !obj) return; /* just in case */ 862. if (mdef->data == &mons[PM_RUST_MONSTER] && !mdef->mcan && 863. is_rustprone(obj) && obj->oeroded < MAX_ERODE) { 864. if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) { 865. if (cansee(mdef->mx, mdef->my) && flags.verbose) 866. pline("%s weapon is not affected.", 867. s_suffix(Monnam(magr))); 868. if (obj->greased && !rn2(2)) obj->greased = 0; 869. } else { 870. if (cansee(mdef->mx, mdef->my)) { 871. pline("%s %s%s!", s_suffix(Monnam(magr)), 872. aobjnam(obj, "rust"), 873. obj->oeroded ? " further" : ""); 874. } 875. obj->oeroded++; 876. } 877. } 878. } 879. 880. static void 881. mswingsm(magr, mdef, otemp) 882. register struct monst *magr, *mdef; 883. register struct obj *otemp; 884. { 885. char buf[BUFSZ]; 886. Strcpy(buf, mon_nam(mdef)); 887. if (!flags.verbose || Blind || otemp->oclass != WEAPON_CLASS) return; 888. pline("%s %s %s %s at %s.", Monnam(magr), 889. ((otemp->otyp >= SPEAR && 890. otemp->otyp <= LANCE) || 891. (otemp->otyp >= PARTISAN && 892. otemp->otyp <= SPETUM) || 893. otemp->otyp == TRIDENT) ? "thrusts" : "swings", 894. humanoid(magr->data) ? (magr->female ? "her" : "his") : "its", 895. xname(otemp), buf); 896. } 897. 898. /* 899. * Passive responses by defenders. Does not replicate responses already 900. * handled above. Returns same values as mattackm. 901. */ 902. static int 903. passivemm(magr,mdef,mhit,mdead) 904. register struct monst *magr, *mdef; 905. boolean mhit; 906. int mdead; 907. { 908. register struct permonst *mddat = mdef->data; 909. register struct permonst *madat = magr->data; 910. char buf[BUFSZ]; 911. int i, tmp; 912. 913. for(i = 0; ; i++) { 914. if(i >= NATTK) return (mdead | mhit); /* no passive attacks */ 915. if(mddat->mattk[i].aatyp == AT_NONE) break; 916. } 917. if (mddat->mattk[i].damn) 918. tmp = d((int)mddat->mattk[i].damn, 919. (int)mddat->mattk[i].damd); 920. else if(mddat->mattk[i].damd) 921. tmp = d((int)mddat->mlevel+1, (int)mddat->mattk[i].damd); 922. else 923. tmp = 0; 924. 925. /* These affect the enemy even if defender killed */ 926. switch(mddat->mattk[i].adtyp) { 927. case AD_ACID: 928. if (mhit && !rn2(2)) { 929. Strcpy(buf, Monnam(magr)); 930. if(canseemon(magr)) 931. pline("%s is splashed by %s acid!", 932. buf, s_suffix(mon_nam(mdef))); 933. if(resists_acid(madat)) { 934. if(canseemon(magr)) 935. pline("%s is not affected.", Monnam(magr)); 936. tmp = 0; 937. } 938. } else tmp = 0; 939. goto assess_dmg; 940. default: 941. break; 942. } 943. if (mdead || mdef->mcan) return (mdead|mhit); 944. 945. /* These affect the enemy only if defender is still alive */ 946. if (rn2(3)) switch(mddat->mattk[i].adtyp) { 947. case AD_PLYS: /* Floating eye */ 948. if (mddat == &mons[PM_FLOATING_EYE]) { 949. if (magr->mcansee && haseyes(madat) && mdef->mcansee && 950. (perceives(madat) || !mdef->minvis)) { 951. Strcpy(buf, Monnam(magr)); 952. if(canseemon(magr)) 953. pline("%s is frozen by %s gaze!", 954. buf, s_suffix(mon_nam(mdef))); 955. magr->mcanmove = 0; 956. magr->mfrozen = tmp; 957. return (mdead|mhit); 958. } 959. } else { /* gelatinous cube */ 960. Strcpy(buf, Monnam(magr)); 961. if(canseemon(magr)) 962. pline("%s is frozen by %s.", buf, mon_nam(mdef)); 963. magr->mcanmove = 0; 964. magr->mfrozen = tmp; 965. return (mdead|mhit); 966. } 967. return 1; 968. case AD_COLD: 969. if (resists_cold(madat)) { 970. if (canseemon(magr)) { 971. pline("%s is mildly chilly.", Monnam(magr)); 972. golemeffects(magr, AD_COLD, tmp); 973. tmp = 0; 974. break; 975. } 976. } 977. if(canseemon(magr)) 978. pline("%s is suddenly very cold!", Monnam(magr)); 979. mdef->mhp += tmp / 2; 980. if (mdef->mhpmax < mdef->mhp) mdef->mhpmax = mdef->mhp; 981. if (mdef->mhpmax > ((int) (mdef->m_lev+1) * 8)) { 982. register struct monst *mtmp; 983. 984. if ((mtmp = clone_mon(mdef)) != 0) { 985. mtmp->mhpmax = mdef->mhpmax /= 2; 986. if(canseemon(magr)) { 987. Strcpy(buf, Monnam(mdef)); 988. pline("%s multiplies from %s heat!", 989. buf, s_suffix(mon_nam(magr))); 990. } 991. } 992. } 993. break; 994. case AD_STUN: 995. if (!magr->mstun) { 996. magr->mstun = 1; 997. if (canseemon(magr)) 998. pline("%s staggers....", Monnam(magr)); 999. } 1000. tmp = 0; 1001. break; 1002. case AD_FIRE: 1003. if (resists_fire(madat)) { 1004. if (canseemon(magr)) { 1005. pline("%s is mildly warmed.", Monnam(magr)); 1006. golemeffects(magr, AD_FIRE, tmp); 1007. tmp = 0; 1008. break; 1009. } 1010. } 1011. if(canseemon(magr)) 1012. pline("%s is suddenly very hot!", Monnam(magr)); 1013. break; 1014. case AD_ELEC: 1015. if (resists_elec(madat)) { 1016. if (canseemon(magr)) { 1017. pline("%s is mildly tingled.", Monnam(magr)); 1018. golemeffects(magr, AD_ELEC, tmp); 1019. tmp = 0; 1020. break; 1021. } 1022. } 1023. if(canseemon(magr)) 1024. pline("%s is jolted with electricity!", Monnam(magr)); 1025. break; 1026. default: tmp = 0; 1027. break; 1028. } 1029. else tmp = 0; 1030. 1031. assess_dmg: 1032. if((magr->mhp -= tmp) <= 0) { 1033. monkilled(magr,"",mddat->mattk[i].adtyp); 1034. return (mdead | mhit | MM_AGR_DIED); 1035. } 1036. return (mdead | mhit); 1037. } 1038. 1039. #endif /* OVLB */ 1040. 1041. /*mhitm.c*/