Source:NetHack 3.0.0/uhitm.c
Jump to navigation
Jump to search
Below is the full text to uhitm.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/uhitm.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: @(#)uhitm.c 3.0 88/04/11 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #ifdef NAMED_ITEMS 7. # include "artifact.h" 8. #endif 9. 10. static boolean hitum(); 11. #ifdef POLYSELF 12. static boolean hmonas(); 13. #endif 14. static int passive(); 15. 16. #ifdef WORM 17. extern boolean notonhead; 18. #endif 19. 20. struct monst * 21. clone_mon(mon) 22. struct monst *mon; 23. { 24. coord mm; 25. struct monst *m2; 26. 27. mm.x = mon->mx; 28. mm.y = mon->my; 29. enexto(&mm, mm.x, mm.y); 30. if (levl[mm.x][mm.y].mmask || mon->mhp <= 1) return (struct monst *)0; 31. m2 = newmonst(0); 32. *m2 = *mon; /* copy condition of old monster */ 33. m2->nmon = fmon; 34. fmon = m2; 35. m2->m_id = flags.ident++; 36. m2->mx = mm.x; 37. m2->my = mm.y; 38. 39. m2->minvent = (struct obj *) 0; /* objects don't clone */ 40. m2->mleashed = FALSE; 41. m2->mgold = 0L; 42. /* Max HP the same, but current HP halved for both. The caller 43. * might want to override this by halving the max HP also. 44. */ 45. m2->mhpmax = mon->mhpmax; 46. m2->mhp = mon->mhp /= 2; 47. 48. /* since shopkeepers and guards will only be cloned if they've been 49. * polymorphed away from their original forms, the clone doesn't have 50. * room for the extra information. we also don't want two shopkeepers 51. * around for the same shop. 52. * similarly, clones of named monsters don't have room for the name, 53. * so we just make the clone unnamed instead of bothering to create 54. * a clone with room and copying over the name from the right place 55. * (which changes if the original was a shopkeeper or guard). 56. */ 57. if (mon->isshk) m2->isshk = FALSE; 58. if (mon->isgd) m2->isgd = FALSE; 59. #if defined(ALTARS) && defined(THEOLOGY) 60. if (mon->ispriest) m2->ispriest = FALSE; 61. #endif 62. m2->mxlth = 0; 63. m2->mnamelth = 0; 64. m2->mdispl = 0; 65. pmon(m2); /* display the new monster */ 66. levl[m2->mx][m2->my].mmask = 1; 67. if (mon->mtame) (void) tamedog(m2, (struct obj *)0); 68. return m2; 69. } 70. 71. boolean 72. special_case(mtmp) 73. /* Moved this code from attack() in order to */ 74. /* avoid having to duplicate it in dokick. */ 75. register struct monst *mtmp; 76. { 77. if (flags.confirm && (mtmp->mpeaceful || mtmp->mtame) && !Confusion 78. && !Hallucination && (!mtmp->mhide || !mtmp->mundetected) 79. && (!mtmp->mimic || Protection_from_shape_changers)) { 80. if (Blind ? Telepat : (!mtmp->minvis || See_invisible)) { 81. pline("Really attack %s? ", mon_nam(mtmp)); 82. (void) fflush(stdout); 83. if (yn() != 'y') { 84. flags.move = 0; 85. return(TRUE); 86. } 87. } 88. } 89. 90. if(mtmp->mimic && !Protection_from_shape_changers) { 91. if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK)) 92. u.ustuck = mtmp; 93. if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == DOOR_SYM) 94. #ifdef SPELLS 95. { 96. if (okdoor(u.ux+u.dx, u.uy+u.dy)) 97. #endif 98. pline("The door actually was %s.", defmonnam(mtmp)); 99. #ifdef SPELLS 100. else 101. pline("That spellbook was %s.", defmonnam(mtmp)); 102. } 103. #endif 104. else if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == GOLD_SYM) 105. pline("That gold was %s!", defmonnam(mtmp)); 106. else 107. pline("Wait! That's %s!", defmonnam(mtmp)); 108. wakeup(mtmp); /* clears mtmp->mimic */ 109. return(TRUE); 110. } 111. 112. if(mtmp->mhide && mtmp->mundetected && !canseemon(mtmp)) { 113. mtmp->mundetected = 0; 114. if (!(Blind ? Telepat : (HTelepat & WORN_HELMET))) { 115. register struct obj *obj; 116. 117. if(levl[mtmp->mx][mtmp->my].omask == 1) { 118. if(obj = o_at(mtmp->mx,mtmp->my)) 119. pline("Wait! There's %s hiding under %s!", 120. defmonnam(mtmp), doname(obj)); 121. } else if (levl[mtmp->mx][mtmp->my].gmask == 1) 122. pline("Wait! There's %s hiding under some gold!", 123. defmonnam(mtmp)); 124. wakeup(mtmp); 125. return(TRUE); 126. } 127. } 128. return(FALSE); 129. } 130. 131. 132. /* try to attack; return FALSE if monster evaded */ 133. /* u.dx and u.dy must be set */ 134. boolean 135. attack(mtmp) 136. register struct monst *mtmp; 137. { 138. schar tmp = 0; 139. register struct permonst *mdat = mtmp->data; 140. 141. if(unweapon) { 142. unweapon=FALSE; 143. if(flags.verbose) 144. if(uwep) 145. You("begin bashing monsters with your %s.", 146. aobjnam(uwep, NULL)); 147. else 148. #ifdef POLYSELF 149. if (!cantwield(uasmon)) 150. #endif 151. You("begin bashing monsters with your %s hands.", 152. uarmg ? "gloved" : "bare"); /* Del Lamb */ 153. } 154. /* andrew@orca: prevent unlimited pick-axe attacks */ 155. u_wipe_engr(3); 156. 157. if(mdat->mlet == S_LEPRECHAUN && !mtmp->mfroz && !mtmp->msleep && 158. !mtmp->mconf && mtmp->mcansee && !rn2(7) && 159. (m_move(mtmp, 0) == 2 || /* he died */ 160. mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) /* he moved */ 161. return(FALSE); 162. 163. /* This section of code provides protection against accidentally 164. * hitting peaceful (like '@') and tame (like 'd') monsters. 165. * There is protection only if you're not blind, confused, or hallu- 166. * cinating. 167. */ 168. /* changes by wwp 5/16/85 */ 169. if (!Blind && !Confusion && !Hallucination && flags.safe_dog && 170. (mdat->mlet == S_DOG || mdat->mlet == S_FELINE) && mtmp->mtame) { 171. mtmp->mflee = 1; 172. mtmp->mfleetim = rnd(6); 173. if (mtmp->mnamelth) 174. You("stop to avoid hitting %s.", NAME(mtmp)); 175. else 176. You("stop to avoid hitting your %s.", 177. mdat->mname); 178. return(TRUE); 179. } 180. 181. /* moved code to a separate function to share with dokick */ 182. if(special_case(mtmp)) return(TRUE); 183. 184. #ifdef POLYSELF 185. if(u.umonnum >= 0) { /* certain "pacifist" monsters don't attack */ 186. set_uasmon(); 187. if(noattacks(uasmon)) { 188. You("have no way to attack monsters physically."); 189. return(TRUE); 190. } 191. } 192. tmp = Luck + mdat->ac + abon() + 193. ((u.umonnum >= 0) ? uasmon->mlevel : u.ulevel); 194. #else 195. tmp = Luck + u.ulevel + mdat->ac + abon(); 196. #endif 197. 198. /* it is unchivalrous to attack the defenseless or from behind */ 199. if (pl_character[0] == 'K' && u.ualigntyp == U_LAWFUL && 200. (mtmp->mfroz || mtmp->msleep || mtmp->mflee) && 201. u.ualign > -10) adjalign(-1); 202. 203. /* Adjust vs. (and possibly modify) monster state. */ 204. 205. if(mtmp->mstun) tmp += 2; 206. if(mtmp->mflee) tmp += 2; 207. 208. if(mtmp->msleep) { 209. mtmp->msleep = 0; 210. tmp += 2; 211. } 212. if(mtmp->mfroz) { 213. tmp += 4; 214. if(!rn2(10)) mtmp->mfroz = 0; 215. } 216. if (is_orc(mtmp->data) && pl_character[0]=='E') tmp++; 217. 218. /* with a lot of luggage, your agility diminishes */ 219. tmp -= (inv_weight() + 40)/20; 220. if(u.utrap) tmp -= 3; 221. 222. #ifdef POLYSELF 223. if(u.umonnum >= 0) (void) hmonas(mtmp, tmp); 224. else { 225. #endif 226. if(uwep) tmp += hitval(uwep, mdat); 227. (void) hitum(mtmp, tmp); 228. #ifdef POLYSELF 229. } 230. #endif 231. 232. return(TRUE); 233. } 234. 235. static boolean 236. known_hitum(mon, mhit) /* returns TRUE if monster still lives */ 237. /* Made into a separate function because in some cases we want to know 238. * in the calling function whether we hit. 239. */ 240. register struct monst *mon; 241. register int mhit; 242. { 243. register boolean malive = TRUE; 244. 245. stoned = FALSE; /* this refers to the thing hit, not you */ 246. 247. if(!mhit) { 248. if(!Blind && flags.verbose) You("miss %s.", mon_nam(mon)); 249. else You("miss it."); 250. if(is_human(mon->data) && !(mon->msleep || mon->mfroz)) 251. wakeup(mon); 252. } else { 253. /* we hit the monster; be careful: it might die! */ 254. 255. #ifdef WORM 256. if (mon->mx != u.ux+u.dx || mon->my != u.uy+u.dy) 257. notonhead = TRUE; 258. #endif 259. if((malive = hmon(mon, uwep, 0)) == TRUE) { 260. /* monster still alive */ 261. if(!rn2(25) && mon->mhp < mon->mhpmax/2) { 262. mon->mflee = 1; 263. if(!rn2(3)) mon->mfleetim = rnd(100); 264. if(u.ustuck == mon && !u.uswallow 265. #ifdef POLYSELF 266. && !sticks(uasmon) 267. #endif 268. ) 269. u.ustuck = 0; 270. } 271. #ifdef WORM 272. if(mon->wormno) 273. cutworm(mon, u.ux+u.dx, u.uy+u.dy, 274. uwep ? uwep->otyp : 0); 275. #endif 276. } 277. #if defined(ALTARS) && defined(THEOLOGY) 278. if(mon->ispriest && !rn2(2)) ghod_hitsu(); 279. #endif 280. } 281. return(malive); 282. } 283. 284. static boolean 285. hitum(mon, tmp) /* returns TRUE if monster still lives */ 286. struct monst *mon; 287. int tmp; 288. { 289. static int malive; 290. boolean mhit = !((tmp <= rnd(20)) && !u.uswallow); 291. 292. malive = known_hitum(mon, mhit); 293. (void) passive(mon, mhit, malive); 294. return(malive); 295. } 296. 297. boolean /* general "damage monster" routine */ 298. hmon(mon, obj, thrown) /* return TRUE if mon still alive */ 299. register struct monst *mon; 300. register struct obj *obj; 301. register int thrown; 302. { 303. register int tmp; 304. boolean hittxt = FALSE; 305. boolean get_dmg_bonus = TRUE; 306. boolean ispoisoned = FALSE; 307. 308. wakeup(mon); 309. if(!obj) { 310. tmp = rnd(2); /* attack with bare hands */ 311. if(mon->data == &mons[PM_COCKATRICE] && !uarmg 312. #ifdef POLYSELF 313. && !resists_ston(uasmon) 314. #endif 315. ) { 316. 317. kludge("You hit %s with your bare %s.", 318. mon_nam(mon), makeplural(body_part(HAND))); 319. You("turn to stone..."); 320. done_in_by(mon); 321. } 322. } else { 323. if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE || 324. obj->olet == ROCK_SYM) { 325. 326. if(mon->data == &mons[PM_RUST_MONSTER] && obj == uwep && 327. objects[obj->otyp].oc_material == METAL && 328. obj->spe > -2) { 329. if(obj->rustfree) { 330. pline("The rust on your %s vanishes instantly!", 331. is_sword(obj) ? "sword" : "weapon"); 332. } else if(obj->blessed && rnl(4)) 333. pline("Somehow your %s is not affected!", 334. is_sword(obj) ? "sword" : "weapon"); 335. else { 336. Your("%s!", aobjnam(uwep, "corrode")); 337. uwep->spe--; 338. } 339. } 340. 341. if(obj == uwep && (obj->otyp > VOULGE || obj->otyp < BOOMERANG) 342. && obj->otyp != PICK_AXE) 343. tmp = rnd(2); 344. else { 345. tmp = dmgval(obj, mon->data); 346. #ifdef NAMED_ITEMS 347. if(spec_ability(obj, SPFX_DRLI) && 348. !resists_drli(mon->data)) { 349. if (!Blind) { 350. pline("The %s blade draws the life from %s!", 351. Hallucination ? hcolor() : black, 352. mon_nam(mon)); 353. hittxt = TRUE; 354. } 355. if (mon->m_lev == 0) tmp = mon->mhp; 356. else { 357. int drain = rnd(8); 358. tmp += drain; 359. mon->mhpmax -= drain; 360. mon->m_lev--; 361. } 362. } 363. #endif 364. if(!thrown && obj == uwep && obj->otyp == BOOMERANG && 365. !rnl(3)) { 366. kludge("As you hit %s, the boomerang breaks into splinters.", 367. mon_nam(mon)); 368. useup(obj); 369. hittxt = TRUE; 370. tmp++; 371. } 372. if(thrown && (obj->otyp >= ARROW && obj->otyp <= SHURIKEN)){ 373. if(((uwep && objects[obj->otyp].w_propellor == 374. -objects[uwep->otyp].w_propellor) 375. || obj->otyp==DART || obj->otyp==SHURIKEN) && 376. obj->opoisoned) 377. ispoisoned = TRUE; 378. } 379. } 380. } else if(obj->olet == POTION_SYM) { 381. if (obj->quan > 1) setuwep(splitobj(obj, 1)); 382. else setuwep((struct obj *)0); 383. freeinv(obj); 384. potionhit(mon,obj); 385. hittxt = TRUE; 386. tmp = 1; 387. } else switch(obj->otyp) { 388. case HEAVY_IRON_BALL: 389. tmp = rnd(25); break; 390. case BOULDER: 391. tmp = rnd(20); break; 392. #ifdef MEDUSA 393. case MIRROR: 394. You("break your mirror. That's bad luck!"); 395. change_luck(-2); 396. useup(obj); 397. return(TRUE); 398. #endif 399. case EXPENSIVE_CAMERA: 400. You("succeed in destroying your camera. Congratulations!"); 401. useup(obj); 402. return(TRUE); 403. case CORPSE: /* fixed by polder@cs.vu.nl */ 404. if(obj->corpsenm == PM_COCKATRICE) { 405. kludge("You hit %s with the cockatrice corpse.", 406. mon_nam(mon)); 407. if(resists_ston(mon->data)) { 408. tmp = 1; 409. hittxt = TRUE; 410. break; 411. } 412. kludge("%s turns to stone.", Monnam(mon)); 413. stoned = TRUE; 414. xkilled(mon,0); 415. return(FALSE); 416. } 417. tmp = bigmonst(&mons[obj->corpsenm]) ? 5 : 2 ; 418. break; 419. case EGG: /* only possible if hand-to-hand */ 420. if(obj->corpsenm > -1 421. && obj->corpsenm != PM_COCKATRICE 422. && mon->data==&mons[PM_COCKATRICE]) { 423. kludge("You hit %s with the %s egg%s.", 424. mon_nam(mon), 425. mons[obj->corpsenm].mname, 426. (obj->quan==1) ? "" : "s"); 427. hittxt = TRUE; 428. pline("The egg%sn't live any more...", 429. (obj->quan==1) ? " is" : "s are"); 430. obj->otyp = ROCK; 431. obj->olet = GEM_SYM; 432. obj->known = obj->dknown = 0; 433. obj->owt = weight(obj); 434. } 435. tmp = 1; 436. break; 437. case CLOVE_OF_GARLIC: /* no effect against demons */ 438. if(is_undead(mon->data)) mon->mflee = 1; 439. tmp = 1; 440. break; 441. case CREAM_PIE: 442. #ifdef POLYSELF 443. case BLINDING_VENOM: 444. if(Blind) 445. pline(obj->otyp==CREAM_PIE ? "Splat!" : "Splash!"); 446. else if (obj->otyp == BLINDING_VENOM) 447. pline("The venom blinds %s%s!", mon_nam(mon), 448. mon->mcansee ? "" : " further"); 449. #else 450. if(Blind) pline("Splat!"); 451. #endif 452. else 453. pline("The cream pie splashes over %s%s!", 454. mon_nam(mon), 455. (haseyes(mon->data) && 456. mon->data != &mons[PM_FLOATING_EYE]) 457. ? "'s face" : ""); 458. if(mon->msleep) mon->msleep = 0; 459. setmangry(mon); 460. mon->mcansee = 0; 461. if((mon->mblinded + tmp) > 127) mon->mblinded = 127; 462. else mon->mblinded += tmp; 463. hittxt = TRUE; 464. get_dmg_bonus = FALSE; 465. tmp = 0; 466. break; 467. #ifdef POLYSELF 468. case ACID_VENOM: /* only possible if thrown */ 469. if(resists_acid(mon->data)) { 470. kludge("Your venom hits %s harmlessly.", 471. mon_nam(mon)); 472. tmp = 0; 473. } else { 474. kludge("Your venom burns %s!", mon_nam(mon)); 475. tmp = dmgval(obj, mon->data); 476. } 477. hittxt = TRUE; 478. get_dmg_bonus = FALSE; 479. break; 480. #endif 481. default: 482. /* non-weapons can damage because of their weight */ 483. /* (but not too much) */ 484. tmp = obj->owt/10; 485. if(tmp < 1) tmp = 1; 486. else tmp = rnd(tmp); 487. if(tmp > 6) tmp = 6; 488. } 489. } 490. 491. /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) 492. * *OR* if attacking bare-handed!! */ 493. 494. if (get_dmg_bonus) { 495. tmp += u.udaminc; 496. /* If you throw using a propellor, you don't get a strength 497. * bonus but you do get an increase-damage bonus. 498. */ 499. if(!obj || !uwep || 500. (obj->olet != GEM_SYM && obj->olet != WEAPON_SYM) || 501. objects[obj->otyp].w_propellor != 502. -objects[uwep->otyp].w_propellor) 503. tmp += dbon(); 504. } 505. 506. /* TODO: Fix this up. multiple engulf attacks now exist. 507. if(u.uswallow) { 508. if((tmp -= u.uswldtim) <= 0) { 509. Your("%s are no longer able to hit.", 510. makeplural(body_part(ARM))); 511. return(TRUE); 512. } 513. } 514. */ 515. if (ispoisoned) { 516. /* OK to reference obj because ispoisoned can only be set 517. * when obj is a throwing weapon */ 518. hit(xname(obj), mon, exclam(tmp)); 519. hittxt = TRUE; 520. if(resists_poison(mon->data)) 521. kludge("The poison doesn't seem to affect %s.", mon_nam(mon)); 522. else if (rn2(10)) 523. tmp += rnd(6); 524. else { 525. pline("The poison was deadly..."); 526. xkilled(mon,0); 527. return FALSE; 528. } 529. } 530. if(tmp < 1) tmp = 1; 531. 532. mon->mhp -= tmp; 533. if(mon->mhp < 1) { 534. killed(mon); 535. return(FALSE); 536. } 537. if(mon->mtame && (!mon->mflee || mon->mfleetim)) { 538. #ifdef SOUNDS 539. if (rn2(8)) yelp(mon); 540. else growl(mon); /* give them a moment's worry */ 541. #endif 542. mon->mtame--; 543. mon->mflee = 1; /* Rick Richardson */ 544. mon->mfleetim += 10*rnd(tmp); 545. } 546. if((mon->data == &mons[PM_BLACK_PUDDING] || 547. mon->data == &mons[PM_BROWN_PUDDING]) && uwep && 548. uwep == obj && objects[obj->otyp].oc_material == METAL 549. && mon->mhp > 1 && !thrown && !mon->mcan) { 550. 551. if (clone_mon(mon)) { 552. pline("%s divides as you hit it!", Monnam(mon)); 553. hittxt = TRUE; 554. } 555. } 556. 557. if(!hittxt) { 558. if(thrown) 559. /* thrown => obj exists */ 560. hit(xname(obj), mon, exclam(tmp) ); 561. else if(Blind || !flags.verbose) You("hit it."); 562. else You("hit %s%s", mon_nam(mon), exclam(tmp)); 563. } 564. 565. if(u.umconf && !thrown) { 566. if(!Blind) { 567. Your("%s stop glowing %s.", 568. makeplural(body_part(HAND)), 569. Hallucination ? hcolor() : red); 570. } 571. if(!resist(mon, '+', 0, NOTELL)) mon->mconf = 1; 572. if(!mon->mstun && !mon->mfroz && !mon->msleep && 573. !Blind && mon->mconf) 574. pline("%s appears confused.", Monnam(mon)); 575. u.umconf = 0; 576. } 577. return(TRUE); /* mon still alive */ 578. } 579. 580. #ifdef POLYSELF 581. static int 582. damageum(mdef, mattk) 583. register struct monst *mdef; 584. register struct attack *mattk; 585. { 586. register struct permonst *pd = mdef->data; 587. register int tmp = d((int)mattk->damn, (int)mattk->damd); 588. 589. stoned = FALSE; 590. if (is_demon(uasmon) && !rn2(13) && !uwep 591. #ifdef HARD 592. && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS 593. && u.umonnum != PM_BALROG 594. #endif 595. ) { 596. struct monst *dtmp; 597. pline("Some hell-p has arrived!"); 598. /* if((dtmp = mkmon_at(uasmon, u.ux, u.uy)))*/ 599. /* if((dtmp = makemon(uasmon, u.ux, u.uy)))*/ 600. if((dtmp = makemon(&mons[ndemon()], u.ux, u.uy))) 601. (void)tamedog(dtmp, (struct obj *)0); 602. return(0); 603. } 604. 605. switch(mattk->adtyp) { 606. case AD_STUN: 607. if(!Blind) 608. pline("%s staggers for a moment.", Monnam(mdef)); 609. mdef->mstun = 1; 610. /* fall through to next case */ 611. case AD_WERE: /* no effect on monsters */ 612. case AD_PHYS: 613. if(mattk->aatyp == AT_WEAP) { 614. if(uwep) tmp = 0; 615. } else if(mattk->aatyp == AT_KICK) 616. if(thick_skinned(mdef->data)) tmp = 0; 617. break; 618. case AD_FIRE: 619. #ifdef GOLEMS 620. golemeffects(mdef, AD_FIRE, tmp); 621. #endif /* GOLEMS */ 622. if(resists_fire(pd)) { 623. shieldeff(mdef->mx, mdef->my); 624. tmp = 0; 625. } else { 626. if(!Blind) pline("%s is on fire!", Monnam(mdef)); 627. tmp += destroy_mitem(mdef, SCROLL_SYM, AD_FIRE); 628. tmp += destroy_mitem(mdef, POTION_SYM, AD_FIRE); 629. #ifdef SPELLS 630. tmp += destroy_mitem(mdef, SPBOOK_SYM, AD_FIRE); 631. #endif 632. } 633. break; 634. case AD_COLD: 635. #ifdef GOLEMS 636. golemeffects(mdef, AD_COLD, tmp); 637. #endif /* GOLEMS */ 638. if(resists_cold(pd)) { 639. shieldeff(mdef->mx, mdef->my); 640. tmp = 0; 641. } else { 642. if(!Blind) pline("%s is covered in frost.", Monnam(mdef)); 643. tmp += destroy_mitem(mdef, POTION_SYM, AD_COLD); 644. } 645. break; 646. case AD_ELEC: 647. #ifdef GOLEMS 648. golemeffects(mdef, AD_ELEC, tmp); 649. #endif /* GOLEMS */ 650. if(resists_elec(pd)) { 651. shieldeff(mdef->mx, mdef->my); 652. tmp = 0; 653. } 654. break; 655. case AD_ACID: 656. if(resists_acid(pd)) tmp = 0; 657. break; 658. case AD_STON: 659. if(!resists_ston(pd)) { 660. stoned = TRUE; 661. if(!Blind) pline("%s turns to stone.", Monnam(mdef)); 662. xkilled(mdef, 0); 663. return(2); 664. } 665. tmp = 0; /* no damage if this fails */ 666. break; 667. #ifdef SEDUCE 668. case AD_SSEX: 669. #endif 670. case AD_SEDU: 671. case AD_SITM: 672. if(mdef->minvent) { 673. struct obj *otmp, *addinv(), *stealoid; 674. int isize = inv_cnt(); 675. 676. stealoid = (struct obj *)0; 677. if (is_mercenary(pd)) { 678. for(otmp = mdef->minvent; otmp; otmp=otmp->nobj) 679. if (otmp->otyp >= PLATE_MAIL && otmp->otyp 680. <= ELVEN_CLOAK) stealoid = otmp; 681. } 682. if (stealoid) { 683. boolean stolen = FALSE; 684. /* Is "he"/"his" always correct? */ 685. kludge("You seduce %s and he starts to take off his clothes.", 686. mon_nam(mdef)); 687. while(mdef->minvent) { 688. otmp = mdef->minvent; 689. mdef->minvent = otmp->nobj; 690. if (!stolen && otmp==stealoid) { 691. if(isize < 52) { 692. otmp = addinv(otmp); 693. isize++; 694. } else dropy(otmp); 695. stealoid = otmp; 696. stolen = TRUE; 697. } else { 698. if(isize < 52) { 699. otmp = addinv(otmp); 700. isize++; 701. } else dropy(otmp); 702. You("steal: "); 703. prinv(otmp); 704. } 705. } 706. if (!stolen) 707. impossible("Player steal fails!"); 708. else { 709. kludge("%s finishes taking off his suit.", 710. Monnam(mdef)); 711. You("steal a %s.", xname(stealoid)); 712. #ifdef ARMY 713. mdef->data = &mons[PM_UNARMORED_SOLDIER]; 714. #endif 715. } 716. } else { 717. otmp = mdef->minvent; 718. mdef->minvent = otmp->nobj; 719. if(isize < 52) otmp = addinv(otmp); 720. else dropy(otmp); 721. You("steal: "); 722. prinv(otmp); 723. } 724. } 725. tmp = 0; 726. break; 727. case AD_SGLD: 728. if (mdef->mgold) { 729. u.ugold += mdef->mgold; 730. mdef->mgold = 0; 731. Your("purse feels heavier."); 732. } 733. tmp = 0; 734. break; 735. case AD_TLPT: 736. if(tmp <= 0) tmp = 1; 737. if(tmp < mdef->mhp) { 738. rloc(mdef); 739. if(!Blind) pline("%s suddenly disappears!", Monnam(mdef)); 740. } 741. break; 742. case AD_BLND: 743. if(haseyes(pd)) { 744. 745. if(!Blind) pline("%s is blinded.", Monnam(mdef)); 746. mdef->mcansee = 0; 747. mdef->mblinded += tmp; 748. } 749. tmp = 0; 750. break; 751. case AD_CURS: 752. if (night() && !rn2(10) && !mdef->mcan) { 753. #ifdef GOLEMS 754. if (mdef->data == &mons[PM_CLAY_GOLEM]) { 755. if (!Blind) 756. pline("Some writing vanishes from %s's head!", 757. mon_nam(mdef)); 758. xkilled(mdef, 0); 759. return 2; 760. } 761. #endif /* GOLEMS */ 762. mdef->mcan = 1; 763. You("chuckle."); 764. } 765. tmp = 0; 766. break; 767. case AD_DRLI: 768. if(rn2(2) && !resists_drli(pd)) { 769. int xtmp = d(2,6); 770. kludge("%s suddenly seems weaker!", Monnam(mdef)); 771. mdef->mhpmax -= xtmp; 772. if ((mdef->mhp -= xtmp) <= 0 || !mdef->m_lev--) { 773. kludge("%s dies.", Monnam(mdef)); 774. xkilled(mdef,0); 775. return(2); 776. } 777. } 778. tmp = 0; 779. break; 780. case AD_RUST: 781. #ifdef GOLEMS 782. if (pd == &mons[PM_IRON_GOLEM]) { 783. kludge("%s falls to pieces!", Monnam(mdef)); 784. xkilled(mdef,0); 785. return(2); 786. } 787. #endif /* GOLEMS */ 788. tmp = 0; 789. break; 790. case AD_DCAY: 791. #ifdef GOLEMS 792. if (pd == &mons[PM_WOOD_GOLEM] || 793. pd == &mons[PM_LEATHER_GOLEM]) { 794. kludge("%s falls to pieces!", Monnam(mdef)); 795. xkilled(mdef,0); 796. return(2); 797. } 798. #endif /* GOLEMS */ 799. case AD_DRST: 800. case AD_DRDX: 801. case AD_DRCO: 802. if (!rn2(8)) { 803. Your("%s was poisoned!", mattk->aatyp==AT_BITE ? 804. "bite" : "sting"); 805. if (resists_poison(mdef->data)) 806. kludge("The poison doesn't seem to affect %s.", 807. mon_nam(mdef)); 808. else { 809. if (!rn2(10)) { 810. Your("poison was deadly..."); 811. tmp = mdef->mhp; 812. } else tmp += rn1(10,6); 813. } 814. } 815. break; 816. case AD_WRAP: 817. case AD_STCK: 818. if (!sticks(mdef->data)) 819. u.ustuck = mdef; /* it's now stuck to you */ 820. break; 821. default: tmp = 0; 822. break; 823. } 824. if(!tmp) return(1); 825. 826. if((mdef->mhp -= tmp) < 1) { 827. 828. if(mdef->mtame) { 829. if(!Blind) You("killed your %s!", mon_nam(mdef)); 830. else You("feel embarrassed for a moment."); 831. } else { 832. if(!Blind && flags.verbose) pline("%s is killed!", Monnam(mdef)); 833. else You("kill it!"); 834. } 835. xkilled(mdef, 0); 836. return(2); 837. } 838. return(1); 839. } 840. 841. static int 842. explum(mdef, mattk) 843. register struct monst *mdef; 844. register struct attack *mattk; 845. { 846. switch(mattk->adtyp) { 847. case AD_BLND: 848. if(mdef->data->mlet != S_YLIGHT) { 849. kludge("%s is blinded by your flash of light!", Monnam(mdef)); 850. if (!mdef->mblinded) { 851. mdef->mblinded += rn2(25); 852. mdef->mcansee = 0; 853. } 854. } 855. break; 856. case AD_COLD: 857. You("explode!"); 858. if (!resists_cold(mdef->data)) { 859. kludge("%s gets blasted!", Monnam(mdef)); 860. mdef->mhp -= d(6,6); 861. if (mdef->mhp <= 0) { 862. killed(mdef); 863. return(2); 864. } 865. #ifdef GOLEMS 866. } else if (is_golem(mdef->data)) { 867. golemeffects(mdef, AD_COLD, d(6,6)); 868. shieldeff(mdef->mx, mdef->my); 869. #endif /* GOLEMS */ 870. } else { 871. shieldeff(mdef->mx, mdef->my); 872. kludge("The blast doesn't seem to affect %s.", 873. mon_nam(mdef)); 874. } 875. break; 876. default: break; 877. } 878. return(1); 879. } 880. 881. static int 882. gulpum(mdef,mattk) 883. register struct monst *mdef; 884. register struct attack *mattk; 885. { 886. register int tmp; 887. register int dam = d((int)mattk->damn, (int)mattk->damd); 888. /* Not totally the same as for real monsters. Specifically, these 889. * don't take multiple moves. (It's just too hard, for too little 890. * result, to program monsters which attack from inside you, which 891. * would be necessary if done accurately.) Instead, we arbitrarily 892. * kill the monster immediately for AD_DGST and we regurgitate them 893. * after exactly 1 round of attack otherwise. -KAA 894. */ 895. 896. #ifdef WORM 897. if(mdef->wormno) return 0; 898. #endif 899. if(u.uhunger < 1500 && !u.uswallow) { 900. 901. if(mdef->data->mlet != S_COCKATRICE) { 902. #ifdef LINT /* static char msgbuf[BUFSZ]; */ 903. char msgbuf[BUFSZ]; 904. #else 905. static char msgbuf[BUFSZ]; 906. #endif 907. /* TODO: get the symbol display also to work (monster symbol is removed from 908. * the screen and you moved onto it, then you get moved back and it gets 909. * moved back if the monster survives--just like when monsters swallow you. 910. */ 911. kludge("You engulf %s!", mon_nam(mdef)); 912. switch(mattk->adtyp) { 913. case AD_DGST: 914. u.uhunger += 20*mdef->mhpmax; 915. newuhs(FALSE); 916. xkilled(mdef,2); 917. Sprintf(msgbuf, "You totally digest %s.", 918. Blind ? "it" : mon_nam(mdef)); 919. if ((tmp = mdef->mhpmax/5)) { 920. kludge("You digest %s.", mon_nam(mdef)); 921. nomul(-tmp); 922. nomovemsg = msgbuf; 923. } else pline(msgbuf); 924. return(2); 925. case AD_PHYS: 926. kludge("%s is pummeled with your debris!",Monnam(mdef)); 927. break; 928. case AD_ACID: 929. kludge("%s is covered with your goo!", Monnam(mdef)); 930. if (resists_acid(mdef->data)) { 931. kludge("It seems harmless to %s.", mon_nam(mdef)); 932. dam = 0; 933. } 934. break; 935. case AD_BLND: 936. if (mdef->mcansee) 937. kludge("%s can't see in there!", Monnam(mdef)); 938. mdef->mcansee = 0; 939. dam += mdef->mblinded; 940. if (dam > 127) dam = 127; 941. mdef->mblinded = dam; 942. dam = 0; 943. break; 944. case AD_ELEC: 945. if (rn2(2)) { 946. kludge("The air around %s crackles with electricity.", mon_nam(mdef)); 947. if (resists_elec(mdef->data)) { 948. kludge("%s seems unhurt.", Monnam(mdef)); 949. dam = 0; 950. } 951. #ifdef GOLEMS 952. golemeffects(mdef,(int)mattk->adtyp,dam); 953. #endif 954. } else dam = 0; 955. break; 956. case AD_COLD: 957. if (rn2(2)) { 958. if (resists_cold(mdef->data)) { 959. kludge("%s seems mildly chilly.", Monnam(mdef)); 960. dam = 0; 961. } else 962. kludge("%s is freezing to death!",Monnam(mdef)); 963. #ifdef GOLEMS 964. golemeffects(mdef,(int)mattk->adtyp,dam); 965. #endif 966. } else dam = 0; 967. break; 968. case AD_FIRE: 969. if (rn2(2)) { 970. if (resists_fire(mdef->data)) { 971. kludge("%s seems mildly hot.", Monnam(mdef)); 972. dam = 0; 973. } else 974. kludge("%s is burning to a crisp!",Monnam(mdef)); 975. #ifdef GOLEMS 976. golemeffects(mdef,(int)mattk->adtyp,dam); 977. #endif 978. } else dam = 0; 979. break; 980. } 981. if ((mdef->mhp -= dam) <= 0) { 982. kludge("%s is killed!", Monnam(mdef)); 983. xkilled(mdef,0); 984. return(2); 985. } 986. kludge("You regurgitate %s!", mon_nam(mdef)); 987. if (Blind) 988. pline("Obviously, you didn't like its taste."); 989. else 990. pline("Obviously, you didn't like %s's taste.", 991. mon_nam(mdef)); 992. } else { 993. kludge("You bite into %s", mon_nam(mdef)); 994. You("turn to stone..."); 995. killer = "poor choice of food"; 996. done("stoned"); 997. } 998. } 999. return(0); 1000. } 1001. 1002. static void 1003. missum(mdef) 1004. register struct monst *mdef; 1005. { 1006. #ifdef POLYSELF 1007. if (u.usym==S_NYMPH 1008. # ifdef SEDUCE 1009. || ((u.umonnum==PM_INCUBUS || u.umonnum==PM_SUCCUBUS) && !incompatible(mdef)) 1010. # endif 1011. ) 1012. kludge("You pretend to be friendly to %s.", mon_nam(mdef)); 1013. else 1014. #endif 1015. if(!Blind && flags.verbose) You("miss %s.", mon_nam(mdef)); 1016. else You("miss it."); 1017. if(is_human(mdef->data) && !(mdef->msleep || mdef->mfroz)) 1018. wakeup(mdef); 1019. } 1020. 1021. static boolean 1022. hmonas(mon, tmp) /* attack monster as a monster. */ 1023. register struct monst *mon; 1024. register int tmp; 1025. { 1026. register struct attack *mattk; 1027. int i, sum[NATTK]; 1028. int nsum = 0; 1029. schar dhit; 1030. 1031. for(i = 0; i < NATTK; i++) { 1032. 1033. mattk = &(uasmon->mattk[i]); 1034. switch(mattk->aatyp) { 1035. case AT_WEAP: 1036. use_weapon: 1037. /* Certain monsters don't use weapons when encountered as enemies, 1038. * but players who polymorph into them have hands or claws and thus 1039. * should be able to use weapons. This shouldn't prohibit the use 1040. * of most special abilities, either. 1041. */ 1042. /* Potential problem: if the monster gets multiple weapon attacks, 1043. * we currently allow the player to get each of these as a weapon 1044. * attack. Is this really desirable? 1045. */ 1046. if(uwep) tmp += hitval(uwep, mon->data); 1047. dhit = !((tmp <= rnd(20)) && !u.uswallow); 1048. /* Enemy dead, before any special abilities used */ 1049. if (!known_hitum(mon,dhit)) return 0; 1050. /* Do not print "You hit" message, since known_hitum 1051. * already did it. 1052. */ 1053. if (dhit && mattk->adtyp != AD_SPEL 1054. && mattk->adtyp != AD_PHYS) 1055. sum[i] = damageum(mon,mattk); 1056. else sum[i] = 0; 1057. break; 1058. case AT_CLAW: 1059. if (i==0 && uwep && humanoid(uasmon)) goto use_weapon; 1060. case AT_KICK: 1061. case AT_BITE: 1062. case AT_STNG: 1063. case AT_TUCH: 1064. case AT_BUTT: 1065. if (i==0 && uwep && (u.usym==S_LICH 1066. )) goto use_weapon; 1067. if(dhit = (tmp > rnd(20) || u.uswallow)) { 1068. /* <----- <----- <----- <----- <----- <----- <----- <----- <----- */ 1069. if (!u.uswallow && (u.usym==S_NYMPH 1070. #ifdef SEDUCE 1071. || ((u.umonnum==PM_INCUBUS || u.umonnum==PM_SUCCUBUS) && !incompatible(mon)) 1072. #endif 1073. )) { 1074. kludge("You %s %s %s.", mon->mblinded ? "talk to" : "smile at", 1075. mon_nam(mon), 1076. incompatible(mon) ? "engagingly" : "seductively"); 1077. } 1078. /* <----- <----- <----- <----- <----- <----- <----- <----- <----- */ 1079. else if (mattk->aatyp == AT_KICK) 1080. kludge("You kick %s.", mon_nam(mon)); 1081. else if (mattk->aatyp == AT_BITE) 1082. kludge("You bite %s.", mon_nam(mon)); 1083. else if (mattk->aatyp == AT_STNG) 1084. kludge("You sting %s.", mon_nam(mon)); 1085. else if (mattk->aatyp == AT_BUTT) 1086. kludge("You butt %s.", mon_nam(mon)); 1087. else if (mattk->aatyp == AT_TUCH) 1088. kludge("You touch %s.", mon_nam(mon)); 1089. else kludge("You hit %s.", mon_nam(mon)); 1090. sum[i] = damageum(mon, mattk); 1091. } else { 1092. missum(mon); 1093. sum[i] = 0; 1094. } 1095. break; 1096. 1097. case AT_HUGS: 1098. /* automatic if prev two attacks succeed, or if 1099. * already grabbed in a previous attack 1100. */ 1101. dhit = 1; 1102. if (sticks(mon->data)) sum[i] = 0; 1103. else if (mon==u.ustuck) { 1104. kludge("%s is being %s.", Monnam(mon), 1105. #ifdef GOLEMS 1106. u.umonnum==PM_ROPE_GOLEM ? "choked": 1107. #endif 1108. "crushed"); 1109. sum[i] = damageum(mon, mattk); 1110. } else if(sum[i-1] && sum[i-2]) { 1111. kludge("You grab %s!", mon_nam(mon)); 1112. u.ustuck = mon; 1113. sum[i] = damageum(mon, mattk); 1114. } else sum[i] = 0; 1115. break; 1116. 1117. case AT_EXPL: /* automatic hit if next to */ 1118. dhit = -1; 1119. sum[i] = explum(mon, mattk); 1120. break; 1121. 1122. case AT_ENGL: 1123. if((dhit = (tmp > rnd(20+i)))) 1124. sum[i]= gulpum(mon,mattk); 1125. else { 1126. missum(mon); 1127. sum[i] = 0; 1128. } 1129. break; 1130. 1131. case AT_MAGC: 1132. /* No check for uwep; if wielding nothing we want to 1133. * do the normal 1-2 points bare hand damage... 1134. */ 1135. if (i==0 && (u.usym==S_KOBOLD 1136. || u.usym==S_ORC 1137. || u.usym==S_GNOME 1138. )) goto use_weapon; 1139. 1140. case AT_NONE: 1141. sum[i] = 0; 1142. continue; 1143. /* Not break--avoid passive attacks from enemy */ 1144. 1145. default: /* Strange... */ 1146. impossible("strange attack of yours (%d)", 1147. mattk->aatyp); 1148. case AT_BREA: 1149. case AT_SPIT: 1150. case AT_GAZE: /* all done using #monster command */ 1151. sum[i] = dhit = 0; 1152. break; 1153. } 1154. if (dhit == -1) 1155. rehumanize(); 1156. if(sum[i] == 2) return(passive(mon, 1, 0)); /* defender dead */ 1157. else { 1158. (void) passive(mon, sum[i], 1); 1159. nsum |= sum[i]; 1160. } 1161. if (uasmon == &playermon) 1162. break; /* No extra attacks if no longer a monster */ 1163. if (multi < 0) 1164. break; /* If paralyzed while attacking, i.e. floating eye */ 1165. } 1166. return(nsum); 1167. } 1168. 1169. #endif 1170. 1171. /* Special (passive) attacks on you by monsters done here. */ 1172. 1173. static int 1174. passive(mon, mhit, malive) 1175. register struct monst *mon; 1176. register boolean mhit; 1177. register int malive; 1178. { 1179. register struct permonst *ptr = mon->data; 1180. register int i, tmp; 1181. 1182. for(i = 0; ; i++) { 1183. if(i >= NATTK) return(malive | mhit); /* no passive attacks */ 1184. if(ptr->mattk[i].aatyp == AT_NONE) break; /* try this one */ 1185. } 1186. 1187. /* These affect you even if they just died */ 1188. 1189. switch(ptr->mattk[i].adtyp) { 1190. 1191. case AD_ACID: 1192. if(mhit && rn2(2)) { 1193. if (Blind || !flags.verbose) You("are splashed!"); 1194. else You("are splashed by %s's acid!", mon_nam(mon)); 1195. 1196. tmp = d((int)mon->m_lev, (int)ptr->mattk[i].damd); 1197. #ifdef POLYSELF 1198. if(!resists_acid(uasmon)) 1199. #endif 1200. mdamageu(mon, tmp); 1201. if(!rn2(30)) corrode_armor(); 1202. } 1203. if(mhit && !rn2(6)) corrode_weapon(); 1204. break; 1205. case AD_MAGM: 1206. /* wrath of gods for attacking Oracle */ 1207. if(Antimagic) { 1208. shieldeff(u.ux, u.uy); 1209. pline("A hail of magic missiles narrowly misses you!"); 1210. } else { 1211. tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 1212. You("are hit by magic missiles appearing from thin air!"); 1213. mdamageu(mon, tmp); 1214. } 1215. break; 1216. default: 1217. break; 1218. } 1219. 1220. /* These only affect you if they still live */ 1221. 1222. if(malive && !mon->mcan && rn2(3)) { 1223. 1224. switch(ptr->mattk[i].adtyp) { 1225. 1226. case AD_PLYS: /* specifically floating eye */ 1227. if(canseemon(mon)) { 1228. 1229. tmp = -d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 1230. if(mon->mcansee) { 1231. if(Reflecting & W_AMUL) { 1232. makeknown(AMULET_OF_REFLECTION); 1233. pline("%s's gaze is reflected by your medallion.", 1234. Monnam(mon)); 1235. } else if(Reflecting & W_ARMS) { 1236. makeknown(SHIELD_OF_REFLECTION); 1237. pline("%s's gaze is reflected by your shield.", 1238. Monnam(mon)); 1239. } else { 1240. You("are frozen by %s's gaze!", mon_nam(mon)); 1241. nomul((ACURR(A_WIS) > 12 || rn2(4)) ? tmp : -120); 1242. } 1243. } else { 1244. pline("%s cannot defend itself.", Amonnam(mon,"blind")); 1245. if(!rn2(500)) change_luck(-1); 1246. } 1247. } 1248. break; 1249. case AD_COLD: /* brown mold or blue jelly */ 1250. if(dist(mon->mx, mon->my) <= 3) { 1251. tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 1252. if(Cold_resistance) { 1253. shieldeff(u.ux, u.uy); 1254. You("feel a mild chill."); 1255. #ifdef POLYSELF 1256. #ifdef GOLEMS 1257. ugolemeffects(AD_COLD, tmp); 1258. #endif /* GOLEMS */ 1259. #endif 1260. tmp = 0; 1261. break; 1262. } 1263. You("are suddenly very cold!"); 1264. mdamageu(mon, tmp); 1265. /* monster gets stronger with your heat! */ 1266. mon->mhp += tmp / 2; 1267. if (mon->mhpmax < mon->mhp) mon->mhpmax = mon->mhp; 1268. /* at a certain point, the monster will reproduce! */ 1269. if(mon->mhpmax > ((mon->m_lev+1) * 8)) { 1270. register struct monst *mtmp; 1271. 1272. if(mtmp = clone_mon(mon)) { 1273. mtmp->mhpmax = mon->mhpmax /= 2; 1274. if(!Blind) 1275. pline("%s multiplies from your heat!", 1276. Monnam(mon)); 1277. } 1278. } 1279. } 1280. break; 1281. case AD_STUN: /* specifically yellow mold */ 1282. if(!Stunned) 1283. make_stunned((long)d((int)mon->m_lev+1, (int)ptr->mattk[i].damd), TRUE); 1284. break; 1285. case AD_FIRE: 1286. if(dist(mon->mx, mon->my) <= 3) { 1287. tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 1288. if(Fire_resistance) { 1289. shieldeff(u.ux, u.uy); 1290. You("feel mildly warm."); 1291. #ifdef POLYSELF 1292. #ifdef GOLEMS 1293. ugolemeffects(AD_FIRE, tmp); 1294. #endif /* GOLEMS */ 1295. #endif 1296. tmp = 0; 1297. break; 1298. } 1299. You("are suddenly very hot!"); 1300. mdamageu(mon, tmp); 1301. } 1302. break; 1303. default: 1304. break; 1305. } 1306. } 1307. return(malive | mhit); 1308. }