Source:NetHack 3.2.0/mhitu.c
Jump to navigation
Jump to search
Below is the full text to mhitu.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.0/mhitu.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: @(#)mhitu.c 3.2 96/01/21 */ 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. 8. STATIC_VAR NEARDATA struct obj *otmp; 9. 10. STATIC_DCL void FDECL(urustm, (struct monst *, struct obj *)); 11. # ifdef OVL1 12. static int FDECL(passiveum, (struct permonst *,struct monst *,struct attack *)); 13. # endif /* OVL1 */ 14. 15. #ifdef OVLB 16. # ifdef SEDUCE 17. static void FDECL(mayberem, (struct obj *, const char *)); 18. # endif 19. #endif /* OVLB */ 20. 21. STATIC_DCL boolean FDECL(diseasemu, (struct permonst *)); 22. STATIC_DCL int FDECL(hitmu, (struct monst *,struct attack *)); 23. STATIC_DCL int FDECL(gulpmu, (struct monst *,struct attack *)); 24. STATIC_DCL int FDECL(explmu, (struct monst *,struct attack *,BOOLEAN_P)); 25. STATIC_DCL void FDECL(missmu,(struct monst *,BOOLEAN_P,struct attack *)); 26. STATIC_DCL void FDECL(mswings,(struct monst *,struct obj *)); 27. STATIC_DCL void FDECL(wildmiss, (struct monst *,struct attack *)); 28. 29. STATIC_DCL void FDECL(hurtarmor,(struct permonst *,int)); 30. STATIC_DCL void FDECL(hitmsg,(struct monst *,struct attack *)); 31. 32. /* See comment in mhitm.c. If we use this a lot it probably should be */ 33. /* changed to a parameter to mhitu. */ 34. static int dieroll; 35. 36. #ifdef OVL1 37. 38. 39. STATIC_OVL void 40. hitmsg(mtmp, mattk) 41. register struct monst *mtmp; 42. register struct attack *mattk; 43. { 44. int compat; 45. 46. /* Note: if opposite gender, "seductively" */ 47. /* If same gender, "engagingly" for nymph, normal msg for others */ 48. if((compat = could_seduce(mtmp, &youmonst, mattk)) 49. && !mtmp->mcan && !mtmp->mspec_used) { 50. pline("%s %s you %s.", Monnam(mtmp), 51. Blind ? "talks to" : "smiles at", 52. compat == 2 ? "engagingly" : "seductively"); 53. } else 54. switch (mattk->aatyp) { 55. case AT_BITE: 56. pline("%s bites!", Monnam(mtmp)); 57. break; 58. case AT_KICK: 59. pline("%s kicks%c", Monnam(mtmp), 60. thick_skinned(uasmon) ? '.' : '!'); 61. break; 62. case AT_STNG: 63. pline("%s stings!", Monnam(mtmp)); 64. break; 65. case AT_BUTT: 66. pline("%s butts!", Monnam(mtmp)); 67. break; 68. case AT_TUCH: 69. pline("%s touches you!", Monnam(mtmp)); 70. break; 71. case AT_TENT: 72. pline("%s tentacles suck you!", 73. s_suffix(Monnam(mtmp))); 74. break; 75. case AT_EXPL: 76. pline("%s explodes!", Monnam(mtmp)); 77. break; 78. default: 79. pline("%s hits!", Monnam(mtmp)); 80. } 81. } 82. 83. STATIC_OVL void 84. missmu(mtmp, nearmiss, mattk) /* monster missed you */ 85. register struct monst *mtmp; 86. register boolean nearmiss; 87. register struct attack *mattk; 88. { 89. if(could_seduce(mtmp, &youmonst, mattk) && !mtmp->mcan) 90. pline("%s pretends to be friendly.", Monnam(mtmp)); 91. else { 92. if (!flags.verbose || !nearmiss) 93. pline("%s misses.", Monnam(mtmp)); 94. else 95. pline("%s just misses!", Monnam(mtmp)); 96. } 97. } 98. 99. STATIC_OVL void 100. mswings(mtmp, otemp) /* monster swings obj */ 101. register struct monst *mtmp; 102. register struct obj *otemp; 103. { 104. if (!flags.verbose || Blind || !mon_visible(mtmp)) 105. return; 106. pline("%s %s %s %s.", Monnam(mtmp), 107. (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings", 108. his[pronoun_gender(mtmp)], xname(otemp)); 109. } 110. 111. /* return how a poison attack was delivered */ 112. const char * 113. mpoisons_subj(mtmp, mattk) 114. struct monst *mtmp; 115. struct attack *mattk; 116. { 117. if (mattk->aatyp == AT_WEAP) { 118. struct obj *mwep = (mtmp == &youmonst) ? uwep : MON_WEP(mtmp); 119. /* "Foo's attack was poisoned." is pretty lame, but at least 120. it's better than "sting" when not a stinging attack... */ 121. return (!mwep || !mwep->opoisoned) ? "attack" : "weapon"; 122. } else { 123. return (mattk->aatyp == AT_TUCH) ? "contact" : 124. (mattk->aatyp == AT_BITE) ? "bite" : "sting"; 125. } 126. } 127. 128. /* called when your intrinsic speed is taken away */ 129. void 130. u_slow_down() 131. { 132. Fast &= ~(INTRINSIC|TIMEOUT); 133. if (!Fast) 134. You("slow down."); 135. else /* speed boots */ 136. Your("quickness feels less natural."); 137. exercise(A_DEX, FALSE); 138. } 139. 140. #endif /* OVL1 */ 141. #ifdef OVLB 142. 143. STATIC_OVL void 144. wildmiss(mtmp, mattk) /* monster attacked your displaced image */ 145. register struct monst *mtmp; 146. register struct attack *mattk; 147. { 148. int compat; 149. 150. if (!flags.verbose) return; 151. if (!cansee(mtmp->mx, mtmp->my)) return; 152. /* maybe it's attacking an image around the corner? */ 153. 154. compat = (mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX) && 155. could_seduce(mtmp, &youmonst, (struct attack *)0); 156. 157. if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) { 158. const char *swings = 159. mattk->aatyp == AT_BITE ? "snaps" : 160. mattk->aatyp == AT_KICK ? "kicks" : 161. (mattk->aatyp == AT_STNG || 162. mattk->aatyp == AT_BUTT || 163. nolimbs(mtmp->data)) ? "lunges" : "swings"; 164. 165. if (compat) 166. pline("%s tries to touch you and misses!", Monnam(mtmp)); 167. else 168. switch(rn2(3)) { 169. case 0: pline("%s %s wildly and misses!", Monnam(mtmp), 170. swings); 171. break; 172. case 1: pline("%s attacks a spot beside you.", Monnam(mtmp)); 173. break; 174. case 2: pline("%s strikes at %s!", Monnam(mtmp), 175. Underwater ? "empty water" : "thin air"); 176. break; 177. default:pline("%s %s wildly!", Monnam(mtmp), swings); 178. break; 179. } 180. 181. } else if (Displaced) { 182. if (compat) 183. pline("%s smiles %s at your %sdisplaced image...", 184. Monnam(mtmp), 185. compat == 2 ? "engagingly" : "seductively", 186. Invis ? "invisible " : ""); 187. else 188. pline("%s strikes at your %sdisplaced image and misses you!", 189. /* Note: if you're both invisible and displaced, 190. * only monsters which see invisible will attack your 191. * displaced image, since the displaced image is also 192. * invisible. 193. */ 194. Monnam(mtmp), 195. Invis ? "invisible " : ""); 196. 197. } else if (Underwater) { 198. /* monsters may miss especially on water level where 199. bubbles shake the player here and there */ 200. if (compat) 201. pline("%s reaches towards your distorted image.",Monnam(mtmp)); 202. else 203. pline("%s is fooled by water reflections and misses!",Monnam(mtmp)); 204. 205. } else impossible("%s attacks you without knowing your location?", 206. Monnam(mtmp)); 207. } 208. 209. void 210. expels(mtmp, mdat, message) 211. register struct monst *mtmp; 212. register struct permonst *mdat; /* if mtmp is polymorphed, mdat != mtmp->data */ 213. boolean message; 214. { 215. if (message) { 216. if (is_animal(mdat)) 217. You("get regurgitated!"); 218. else { 219. char blast[40]; 220. register int i; 221. 222. blast[0] = '\0'; 223. for(i = 0; i < NATTK; i++) 224. if(mdat->mattk[i].aatyp == AT_ENGL) 225. break; 226. if (mdat->mattk[i].aatyp != AT_ENGL) 227. impossible("Swallower has no engulfing attack?"); 228. else { 229. if (is_whirly(mdat)) { 230. switch (mdat->mattk[i].adtyp) { 231. case AD_ELEC: 232. Strcpy(blast, 233. " in a shower of sparks"); 234. break; 235. case AD_COLD: 236. Strcpy(blast, 237. " in a blast of frost"); 238. break; 239. } 240. } else 241. Strcpy(blast, " with a squelch"); 242. You("get expelled from %s%s!", 243. mon_nam(mtmp), blast); 244. } 245. } 246. } 247. unstuck(mtmp); /* ball&chain returned in unstuck() */ 248. mnexto(mtmp); 249. newsym(u.ux,u.uy); 250. spoteffects(); 251. /* to cover for a case where mtmp is not in a next square */ 252. if(um_dist(mtmp->mx,mtmp->my,1)) 253. pline("Brrooaa... You land hard at some distance."); 254. } 255. 256. #endif /* OVLB */ 257. #ifdef OVL0 258. 259. /* 260. * mattacku: monster attacks you 261. * returns 1 if monster dies (e.g. "yellow light"), 0 otherwise 262. * Note: if you're displaced or invisible the monster might attack the 263. * wrong position... 264. * Assumption: it's attacking you or an empty square; if there's another 265. * monster which it attacks by mistake, the caller had better 266. * take care of it... 267. */ 268. int 269. mattacku(mtmp) 270. register struct monst *mtmp; 271. { 272. struct attack *mattk; 273. int i, j, tmp, sum[NATTK]; 274. struct permonst *mdat = mtmp->data; 275. boolean ranged = (distu(mtmp->mx, mtmp->my) > 3); 276. /* Is it near you? Affects your actions */ 277. boolean range2 = !monnear(mtmp, mtmp->mux, mtmp->muy); 278. /* Does it think it's near you? Affects its actions */ 279. boolean foundyou = (mtmp->mux==u.ux && mtmp->muy==u.uy); 280. /* Is it attacking you or your image? */ 281. boolean youseeit = canseemon(mtmp); 282. /* Might be attacking your image around the corner, or 283. * invisible, or you might be blind.... 284. */ 285. 286. if(!ranged) nomul(0); 287. if(mtmp->mhp <= 0 || (Underwater && !is_swimmer(mtmp->data))) 288. return(0); 289. 290. /* If swallowed, can only be affected by u.ustuck */ 291. if(u.uswallow) { 292. if(mtmp != u.ustuck) 293. return(0); 294. u.ustuck->mux = u.ux; 295. u.ustuck->muy = u.uy; 296. range2 = 0; 297. foundyou = 1; 298. if(u.uinvulnerable) return (0); /* stomachs can't hurt you! */ 299. } 300. 301. if (u.uundetected && !range2 && foundyou && !u.uswallow) { 302. u.uundetected = 0; 303. if (is_hider(uasmon)) { 304. coord cc; /* maybe we need a unexto() function? */ 305. 306. You("fall from the %s!", ceiling(u.ux,u.uy)); 307. if (enexto(&cc, u.ux, u.uy, &playermon)) { 308. remove_monster(mtmp->mx, mtmp->my); 309. newsym(mtmp->mx,mtmp->my); 310. place_monster(mtmp, u.ux, u.uy); 311. if(mtmp->wormno) worm_move(mtmp); 312. teleds(cc.x, cc.y); 313. set_apparxy(mtmp); 314. newsym(u.ux,u.uy); 315. } else { 316. pline("%s is killed by a falling %s (you)!", 317. Monnam(mtmp), uasmon->mname); 318. killed(mtmp); 319. newsym(u.ux,u.uy); 320. if (mtmp->mhp > 0) return 0; 321. else return 1; 322. } 323. if (u.usym != S_PIERCER) 324. return(0); /* trappers don't attack */ 325. 326. if (which_armor(mtmp, WORN_HELMET)) { 327. Your("blow glances off %s helmet.", 328. s_suffix(mon_nam(mtmp))); 329. } else { 330. if (3 + find_mac(mtmp) <= rnd(20)) { 331. pline("%s is hit by a falling piercer (you)!", 332. Monnam(mtmp)); 333. if ((mtmp->mhp -= d(3,6)) < 1) 334. killed(mtmp); 335. } else 336. pline("%s is almost hit by a falling piercer (you)!", 337. Monnam(mtmp)); 338. } 339. } else { 340. if (!youseeit) 341. pline("It tries to move where you are hiding."); 342. else { 343. /* Ugly kludge for eggs. The message is phrased so as 344. * to be directed at the monster, not the player, 345. * which makes "laid by you" wrong. For the 346. * parallelism to work, we can't rephrase it, so we 347. * zap the "laid by you" momentarily instead. 348. */ 349. struct obj *obj = level.objects[u.ux][u.uy]; 350. 351. if (obj || 352. (uasmon->mlet == S_EEL && is_pool(u.ux, u.uy))) { 353. int save_spe = 0; /* suppress warning */ 354. if (obj) { 355. save_spe = obj->spe; 356. if (obj->otyp == EGG) obj->spe = 0; 357. } 358. if (uasmon->mlet == S_EEL) 359. pline("Wait, %s! There's a hidden %s named %s there!", 360. m_monnam(mtmp), uasmon->mname, plname); 361. else 362. pline("Wait, %s! There's a %s named %s hiding under %s!", 363. m_monnam(mtmp), uasmon->mname, plname, 364. doname(level.objects[u.ux][u.uy])); 365. if (obj) obj->spe = save_spe; 366. } else 367. impossible("hiding under nothing?"); 368. } 369. newsym(u.ux,u.uy); 370. } 371. return(0); 372. } 373. if (u.usym == S_MIMIC_DEF && !range2 && foundyou && !u.uswallow) { 374. if (!youseeit) pline("It gets stuck on you."); 375. else pline("Wait, %s! That's a %s named %s!", 376. m_monnam(mtmp), uasmon->mname, plname); 377. u.ustuck = mtmp; 378. u.usym = S_MIMIC; 379. newsym(u.ux,u.uy); 380. return(0); 381. } 382. 383. /* player might be mimicking gold */ 384. if (u.usym == 0 && !range2 && foundyou && !u.uswallow) { 385. if (!youseeit) 386. pline("%s %s!", Something, likes_gold(mtmp->data) ? 387. "tries to pick you up" : "disturbs you"); 388. else pline("Wait, %s! That gold is really %s named %s!", 389. m_monnam(mtmp), 390. u.mtimedone ? an(uasmon->mname) : 391. an(player_mon()->mname), 392. plname); 393. if (multi < 0) { /* this should always be the case */ 394. char buf[BUFSIZ]; 395. Sprintf(buf, "You appear to be %s again.", 396. u.mtimedone ? (const char *) an(uasmon->mname) : 397. (const char *) "yourself"); 398. unmul(buf); /* immediately stop mimicking gold */ 399. } 400. return 0; 401. } 402. 403. /* Work out the armor class differential */ 404. tmp = AC_VALUE(u.uac) + 10; /* tmp ~= 0 - 20 */ 405. tmp += mtmp->m_lev; 406. if(multi < 0) tmp += 4; 407. if((Invis && !perceives(mdat)) || !mtmp->mcansee) 408. tmp -= 2; 409. if(mtmp->mtrapped) tmp -= 2; 410. if(tmp <= 0) tmp = 1; 411. 412. /* make eels visible the moment they hit/miss us */ 413. if(mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx,mtmp->my)) { 414. mtmp->minvis = 0; 415. newsym(mtmp->mx,mtmp->my); 416. } 417. 418. /* Special demon handling code */ 419. if(!mtmp->cham && is_demon(mdat) && !range2 420. && mtmp->data != &mons[PM_BALROG] 421. && mtmp->data != &mons[PM_SUCCUBUS] 422. && mtmp->data != &mons[PM_INCUBUS]) 423. if(!mtmp->mcan && !rn2(13)) msummon(mdat); 424. 425. /* Special lycanthrope handling code */ 426. if(!mtmp->cham && is_were(mdat) && !range2) { 427. 428. if(is_human(mdat)) { 429. if(!rn2(5 - (night() * 2)) && !mtmp->mcan) new_were(mtmp); 430. } else if(!rn2(30) && !mtmp->mcan) new_were(mtmp); 431. mdat = mtmp->data; 432. 433. if(!rn2(10) && !mtmp->mcan) { 434. if(youseeit) { 435. pline("%s summons help!", Monnam(mtmp)); 436. } else 437. You_feel("hemmed in."); 438. /* Technically wrong; we really should check if you can see the 439. * help, but close enough... 440. */ 441. if (!were_summon(mdat,FALSE) && youseeit) 442. pline("But none comes."); 443. } 444. } 445. 446. if(u.uinvulnerable) { 447. /* monster's won't attack you */ 448. if(mtmp == u.ustuck) 449. pline("%s loosens its grip slightly.", Monnam(mtmp)); 450. else if(!range2) { 451. if(youseeit) 452. pline("%s starts to attack you, but pulls back.", 453. Monnam(mtmp)); 454. else 455. You_feel("%s move nearby.", something); 456. } 457. return (0); 458. } 459. 460. /* Unlike defensive stuff, don't let them use item _and_ attack. */ 461. /* Exception: Medusa; her gaze is automatic. (We actually kludge 462. * by permitting a full attack sequence, not just a gaze attack.) 463. */ 464. if(find_offensive(mtmp)) { 465. int foo = use_offensive(mtmp); 466. 467. if (mtmp->data != &mons[PM_MEDUSA] && foo != 0) return(foo==1); 468. } 469. 470. for(i = 0; i < NATTK; i++) { 471. 472. sum[i] = 0; 473. mattk = &(mdat->mattk[i]); 474. if (u.uswallow && (mattk->aatyp != AT_ENGL)) 475. continue; 476. switch(mattk->aatyp) { 477. case AT_CLAW: /* "hand to hand" attacks */ 478. case AT_KICK: 479. case AT_BITE: 480. case AT_STNG: 481. case AT_TUCH: 482. case AT_BUTT: 483. case AT_TENT: 484. if(!range2) { 485. if (foundyou) { 486. if(tmp > (j = rnd(20+i))) { 487. if (mattk->aatyp != AT_KICK || 488. !thick_skinned(uasmon)) 489. sum[i] = hitmu(mtmp, mattk); 490. } else 491. missmu(mtmp, (tmp == j), mattk); 492. } else 493. wildmiss(mtmp, mattk); 494. } 495. break; 496. 497. case AT_HUGS: /* automatic if prev two attacks succeed */ 498. /* Note: if displaced, prev attacks never succeeded */ 499. if((!range2 && i>=2 && sum[i-1] && sum[i-2]) 500. || mtmp == u.ustuck) 501. sum[i]= hitmu(mtmp, mattk); 502. break; 503. 504. case AT_GAZE: /* can affect you either ranged or not */ 505. sum[i] = gazemu(mtmp, mattk); 506. break; 507. 508. case AT_EXPL: /* automatic hit if next to, and aimed at you */ 509. if(!range2) sum[i] = explmu(mtmp, mattk, foundyou); 510. break; 511. 512. case AT_ENGL: 513. if (!range2) { 514. if(foundyou) { 515. if(u.uswallow || tmp > (j = rnd(20+i))) { 516. /* Force swallowing monster to be 517. * displayed even when player is 518. * moving away */ 519. flush_screen(1); 520. sum[i] = gulpmu(mtmp, mattk); 521. } else { 522. missmu(mtmp, (tmp == j), mattk); 523. } 524. } else if (is_animal(mtmp->data)) 525. pline("%s gulps some air!", youseeit ? 526. Monnam(mtmp) : "It"); 527. else 528. if (youseeit) 529. pline("%s lunges forward and recoils!", 530. Monnam(mtmp)); 531. else 532. You_hear("a %s nearby.", 533. is_whirly(mtmp->data)? 534. "rushing noise" : 535. "splat"); 536. } 537. break; 538. case AT_BREA: 539. if(range2) sum[i] = breamu(mtmp, mattk); 540. /* Note: breamu takes care of displacement */ 541. break; 542. case AT_SPIT: 543. if(range2) sum[i] = spitmu(mtmp, mattk); 544. /* Note: spitmu takes care of displacement */ 545. break; 546. case AT_WEAP: 547. if(range2) { 548. #ifdef REINCARNATION 549. if (!Is_rogue_level(&u.uz)) 550. #endif 551. thrwmu(mtmp); 552. } else { 553. /* Rare but not impossible. Normally the monster 554. * wields when 2 spaces away, but it can be 555. * teleported or whatever.... 556. */ 557. if (mtmp->weapon_check == NEED_WEAPON || 558. !MON_WEP(mtmp)) { 559. mtmp->weapon_check = NEED_HTH_WEAPON; 560. /* mon_wield_item resets weapon_check as 561. * appropriate */ 562. if (mon_wield_item(mtmp) != 0) break; 563. } 564. if (foundyou) { 565. possibly_unwield(mtmp); 566. otmp = MON_WEP(mtmp); 567. if(otmp) { 568. tmp += hitval(otmp, &youmonst); 569. mswings(mtmp, otmp); 570. } 571. if(tmp > (j = dieroll = rnd(20+i))) 572. sum[i] = hitmu(mtmp, mattk); 573. else 574. missmu(mtmp, (tmp == j), mattk); 575. } else 576. wildmiss(mtmp, mattk); 577. } 578. break; 579. case AT_MAGC: 580. if (range2) 581. sum[i] = buzzmu(mtmp, mattk); 582. else 583. if (foundyou) 584. sum[i] = castmu(mtmp, mattk); 585. else 586. pline("%s casts a spell at thin air!", 587. youseeit ? Monnam(mtmp) : "It"); 588. /* Not totally right since castmu allows other 589. * spells, such as the monster healing itself, 590. * that should work even when not next to you-- 591. * but the previous code was just as wrong. 592. * --KAA 593. */ 594. break; 595. 596. default: /* no attack */ 597. break; 598. } 599. if(flags.botl) bot(); 600. /* give player a chance of waking up before dying -kaa */ 601. if(sum[i] == 1) { /* successful attack */ 602. if (u.usleep && u.usleep < monstermoves && !rn2(10)) { 603. multi = -1; 604. nomovemsg = "The combat suddenly awakens you."; 605. } 606. } 607. if(sum[i] == 2) return 1; /* attacker dead */ 608. if(sum[i] == 3) break; /* attacker teleported, no more attacks */ 609. /* sum[i] == 0: unsuccessful attack */ 610. } 611. return(0); 612. } 613. 614. #endif /* OVL0 */ 615. #ifdef OVLB 616. 617. /* 618. * helper function for some compilers that have trouble with hitmu 619. */ 620. 621. STATIC_OVL void 622. hurtarmor(mdat, attk) 623. struct permonst *mdat; 624. int attk; 625. { 626. boolean getbronze, rusting; 627. int hurt; 628. 629. rusting = (attk == AD_RUST); 630. if (rusting) { 631. hurt = 1; 632. getbronze = (mdat == &mons[PM_BLACK_PUDDING] && 633. uarm && is_corrodeable(uarm)); 634. } 635. else { 636. hurt=2; 637. getbronze = FALSE; 638. } 639. /* What the following code does: it keeps looping until it 640. * finds a target for the rust monster. 641. * Head, feet, etc... not covered by metal, or covered by 642. * rusty metal, are not targets. However, your body always 643. * is, no matter what covers it. 644. */ 645. while (1) { 646. switch(rn2(5)) { 647. case 0: 648. if (!rust_dmg(uarmh, rusting ? "helmet" : "leather helmet", 649. hurt, FALSE)) 650. continue; 651. break; 652. case 1: 653. if (uarmc) { 654. if (!rusting) 655. (void)rust_dmg(uarmc, "cloak", hurt, TRUE); 656. break; 657. } 658. /* Note the difference between break and continue; 659. * break means it was hit and didn't rust; continue 660. * means it wasn't a target and though it didn't rust 661. * something else did. 662. */ 663. if (getbronze) 664. (void)rust_dmg(uarm, "bronze armor", 3, TRUE); 665. else if (uarm) 666. (void)rust_dmg(uarm, xname(uarm), hurt, TRUE); 667. #ifdef TOURIST 668. else if (uarmu) 669. (void)rust_dmg(uarmu, "shirt", hurt, TRUE); 670. #endif 671. break; 672. case 2: 673. if (!rust_dmg(uarms, rusting ? "shield" : "wooden shield", 674. hurt, FALSE)) 675. continue; 676. break; 677. case 3: 678. if (!rust_dmg(uarmg, rusting ? "metal gauntlets" : "gloves", 679. hurt, FALSE)) 680. continue; 681. break; 682. case 4: 683. if (!rust_dmg(uarmf, rusting ? "metal boots" : "boots", 684. hurt, FALSE)) 685. continue; 686. break; 687. } 688. break; /* Out of while loop */ 689. } 690. } 691. 692. #endif /* OVLB */ 693. #ifdef OVL1 694. 695. STATIC_OVL boolean 696. diseasemu(mdat) 697. struct permonst *mdat; 698. { 699. if (defends(AD_DISE,uwep) || u.usym == S_FUNGUS) { 700. You_feel("a slight illness."); 701. return FALSE; 702. } else { 703. make_sick(Sick ? Sick/3L + 1L : (long)rn1(ACURR(A_CON), 20), 704. mdat->mname, TRUE, SICK_NONVOMITABLE); 705. return TRUE; 706. } 707. } 708. 709. /* 710. * hitmu: monster hits you 711. * returns 2 if monster dies (e.g. "yellow light"), 1 otherwise 712. * 3 if the monster lives but teleported/paralyzed, so it can't keep 713. * attacking you 714. */ 715. STATIC_OVL int 716. hitmu(mtmp, mattk) 717. register struct monst *mtmp; 718. register struct attack *mattk; 719. { 720. register struct permonst *mdat = mtmp->data; 721. register int uncancelled, ptmp; 722. int dmg, armpro; 723. char buf[BUFSZ]; 724. struct permonst *olduasmon = uasmon; 725. int res; 726. 727. /* If the monster is undetected & hits you, you should know where 728. * the attack came from. 729. */ 730. if(mtmp->mundetected && (hides_under(mdat) || mdat->mlet == S_EEL)) { 731. mtmp->mundetected = 0; 732. if (!(Blind ? Telepat : (HTelepat & ~INTRINSIC))) { 733. struct obj *obj; 734. const char *what; 735. 736. if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) { 737. if (Blind && !obj->dknown) 738. what = something; 739. else if (is_pool(mtmp->mx, mtmp->my) && !Underwater) 740. what = "the water"; 741. else 742. what = doname(obj); 743. 744. pline("%s was hidden under %s!", Amonnam(mtmp), what); 745. } 746. newsym(mtmp->mx, mtmp->my); 747. } 748. } 749. 750. /* First determine the base damage done */ 751. dmg = d((int)mattk->damn, (int)mattk->damd); 752. if(is_undead(mdat) && midnight()) 753. dmg += d((int)mattk->damn, (int)mattk->damd); /* extra damage */ 754. 755. /* Next a cancellation factor */ 756. /* Use uncancelled when the cancellation factor takes into account certain 757. * armor's special magic protection. Otherwise just use !mtmp->mcan. 758. */ 759. armpro = 0; 760. if (uarm && armpro < objects[uarm->otyp].a_can) 761. armpro = objects[uarm->otyp].a_can; 762. if (uarmc && armpro < objects[uarmc->otyp].a_can) 763. armpro = objects[uarmc->otyp].a_can; 764. uncancelled = !mtmp->mcan && ((rn2(3) >= armpro) || !rn2(50)); 765. 766. /* Now, adjust damages via resistances or specific attacks */ 767. switch(mattk->adtyp) { 768. case AD_PHYS: 769. if (mattk->aatyp == AT_HUGS && !sticks(uasmon)) { 770. if(!u.ustuck && rn2(2)) { 771. register struct obj *obj = (uarmc ? uarmc : uarm); 772. 773. /* if your cloak/armor is greased, monster slips off */ 774. if (obj && obj->greased) { 775. dmg = 0; 776. pline("%s grabs you, but cannot hold onto your greased %s!", 777. Monnam(mtmp), xname(obj)); 778. if (!rn2(2)) { 779. pline_The("grease wears off."); 780. obj->greased = 0; 781. } 782. } else { 783. u.ustuck = mtmp; 784. pline("%s grabs you!", Monnam(mtmp)); 785. } 786. } else if(u.ustuck == mtmp) { 787. exercise(A_STR, FALSE); 788. You("are being %s.", 789. (mtmp->data == &mons[PM_ROPE_GOLEM]) 790. ? "choked" : "crushed"); 791. } 792. } else { /* hand to hand weapon */ 793. if(mattk->aatyp == AT_WEAP && otmp) { 794. if (otmp->otyp == CORPSE 795. && otmp->corpsenm == PM_COCKATRICE) { 796. dmg = 1; 797. pline("%s hits you with the cockatrice corpse.", 798. Monnam(mtmp)); 799. if (!Stoned) 800. goto do_stone; 801. } 802. dmg += dmgval(otmp, &youmonst); 803. if (dmg <= 0) dmg = 1; 804. if (!(otmp->oartifact && 805. artifact_hit(mtmp, &youmonst, otmp, &dmg,dieroll))) 806. hitmsg(mtmp, mattk); 807. if (!dmg) break; 808. if (u.mh > 1 && u.mh > ((u.uac>0) ? dmg : dmg+u.uac) && 809. (u.umonnum==PM_BLACK_PUDDING 810. || u.umonnum==PM_BROWN_PUDDING)) { 811. /* This redundancy necessary because you have to 812. * take the damage _before_ being cloned. 813. */ 814. if (u.uac < 0) dmg += u.uac; 815. if (dmg < 1) dmg = 1; 816. if (dmg > 1) exercise(A_STR, FALSE); 817. u.mh -= dmg; 818. flags.botl = 1; 819. dmg = 0; 820. if(cloneu()) 821. You("divide as %s hits you!",mon_nam(mtmp)); 822. } 823. urustm(mtmp, otmp); 824. } else if (mattk->aatyp != AT_TUCH || dmg != 0 || 825. mtmp != u.ustuck) 826. hitmsg(mtmp, mattk); 827. } 828. break; 829. case AD_DISE: 830. hitmsg(mtmp, mattk); 831. if (!diseasemu(mdat)) dmg = 0; 832. break; 833. case AD_FIRE: 834. hitmsg(mtmp, mattk); 835. if (uncancelled) { 836. pline("You're %s!", 837. mattk->aatyp == AT_HUGS ? "being roasted" : 838. "on fire"); 839. if (Fire_resistance) { 840. pline_The("fire doesn't feel hot!"); 841. dmg = 0; 842. } 843. if((int) mtmp->m_lev > rn2(20)) 844. destroy_item(SCROLL_CLASS, AD_FIRE); 845. if((int) mtmp->m_lev > rn2(20)) 846. destroy_item(POTION_CLASS, AD_FIRE); 847. if((int) mtmp->m_lev > rn2(25)) 848. destroy_item(SPBOOK_CLASS, AD_FIRE); 849. } else dmg = 0; 850. break; 851. case AD_COLD: 852. hitmsg(mtmp, mattk); 853. if (uncancelled) { 854. pline("You're covered in frost!"); 855. if (Cold_resistance) { 856. pline_The("frost doesn't seem cold!"); 857. dmg = 0; 858. } 859. if((int) mtmp->m_lev > rn2(20)) 860. destroy_item(POTION_CLASS, AD_COLD); 861. } else dmg = 0; 862. break; 863. case AD_ELEC: 864. hitmsg(mtmp, mattk); 865. if (uncancelled) { 866. You("get zapped!"); 867. if (Shock_resistance) { 868. pline_The("zap doesn't shock you!"); 869. dmg = 0; 870. } 871. if((int) mtmp->m_lev > rn2(20)) 872. destroy_item(WAND_CLASS, AD_ELEC); 873. if((int) mtmp->m_lev > rn2(20)) 874. destroy_item(RING_CLASS, AD_ELEC); 875. } else dmg = 0; 876. break; 877. case AD_SLEE: 878. hitmsg(mtmp, mattk); 879. if (uncancelled && multi >= 0 && !rn2(5)) { 880. if (Sleep_resistance) break; 881. fall_asleep(-rnd(10), TRUE); 882. if (Blind) You("are put to sleep!"); 883. else You("are put to sleep by %s!", mon_nam(mtmp)); 884. } 885. break; 886. case AD_DRST: 887. ptmp = A_STR; 888. goto dopois; 889. case AD_DRDX: 890. ptmp = A_DEX; 891. goto dopois; 892. case AD_DRCO: 893. ptmp = A_CON; 894. dopois: 895. hitmsg(mtmp, mattk); 896. if (uncancelled && !rn2(8)) { 897. Sprintf(buf, "%s %s", 898. !canspotmon(mtmp) ? "Its" : 899. Hallucination ? s_suffix(rndmonnam()) : 900. s_suffix(mdat->mname), 901. mpoisons_subj(mtmp, mattk)); 902. poisoned(buf, ptmp, mdat->mname, 30); 903. } 904. break; 905. case AD_DRIN: 906. hitmsg(mtmp, mattk); 907. if (defends(AD_DRIN, uwep) || !has_head(uasmon)) { 908. You("don't seem harmed."); 909. break; 910. } 911. if (uarmh && rn2(8)) { 912. Your("helmet blocks the attack to your head."); 913. break; 914. } 915. if (Half_physical_damage) dmg = (dmg+1) / 2; 916. losehp(dmg, mon_nam(mtmp), KILLED_BY_AN); 917. 918. if (!uarmh || uarmh->otyp != DUNCE_CAP) { 919. Your("brain is eaten!"); 920. /* No such thing as mindless players... */ 921. if (ABASE(A_INT) <= ATTRMIN(A_INT)) { 922. int lifesaved = 0; 923. struct obj *wore_amulet = uamul; 924. 925. while(1) { 926. /* avoid looping on "die(y/n)?" */ 927. if (lifesaved && (discover || wizard)) { 928. if (wore_amulet && !uamul) { 929. /* used up AMULET_OF_LIFE_SAVING; still 930. subject to dying from brainlessness */ 931. wore_amulet = 0; 932. } else { 933. /* explicitly chose not to die; 934. arbitrarily boost intelligence */ 935. ABASE(A_INT) = ATTRMIN(A_INT) + 2; 936. You_feel("like a scarecrow."); 937. break; 938. } 939. } 940. 941. if (lifesaved) 942. pline("Unfortunately your brain is still gone."); 943. else 944. Your("last thought fades away."); 945. killer = "brainlessness"; 946. killer_format = KILLED_BY; 947. done(DIED); 948. lifesaved++; 949. } 950. } 951. } 952. /* adjattrib gives dunce cap message when appropriate */ 953. (void) adjattrib(A_INT, -rnd(2), FALSE); 954. forget_levels(25); /* lose memory of 25% of levels */ 955. forget_objects(25); /* lose memory of 25% of objects */ 956. exercise(A_WIS, FALSE); 957. break; 958. case AD_PLYS: 959. hitmsg(mtmp, mattk); 960. if (uncancelled && multi >= 0 && !rn2(3)) { 961. if (Blind) You("are frozen!"); 962. else You("are frozen by %s!", mon_nam(mtmp)); 963. nomovemsg = 0; /* default: "you can move again" */ 964. nomul(-rnd(10)); 965. exercise(A_DEX, FALSE); 966. } 967. break; 968. case AD_DRLI: 969. hitmsg(mtmp, mattk); 970. if (uncancelled && !rn2(3) && !resists_drli(&youmonst)) 971. losexp(); 972. break; 973. case AD_LEGS: 974. { register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; 975. const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left"; 976. if (mtmp->mcan) { 977. pline("%s nuzzles against your %s %s!", Monnam(mtmp), 978. sidestr, body_part(LEG)); 979. } else { 980. if (uarmf) { 981. if (rn2(2) && (uarmf->otyp == LOW_BOOTS || 982. uarmf->otyp == IRON_SHOES)) 983. pline("%s pricks the exposed part of your %s %s!", 984. Monnam(mtmp), sidestr, body_part(LEG)); 985. else if (!rn2(5)) 986. pline("%s pricks through your %s boot!", 987. Monnam(mtmp), sidestr); 988. else { 989. pline("%s scratches your %s boot!", Monnam(mtmp), 990. sidestr); 991. break; 992. } 993. } else pline("%s pricks your %s %s!", Monnam(mtmp), 994. sidestr, body_part(LEG)); 995. set_wounded_legs(side, rnd(60-ACURR(A_DEX))); 996. exercise(A_STR, FALSE); 997. exercise(A_DEX, FALSE); 998. } 999. break; 1000. } 1001. case AD_STON: /* at present only a cockatrice */ 1002. hitmsg(mtmp, mattk); 1003. if(!rn2(3) && !Stoned) { 1004. if (mtmp->mcan) { 1005. if (flags.soundok) 1006. You_hear("a cough from %s!", mon_nam(mtmp)); 1007. } else { 1008. if (flags.soundok) 1009. You_hear("%s hissing!", s_suffix(mon_nam(mtmp))); 1010. if(!rn2(10) || 1011. (flags.moonphase == NEW_MOON && !have_lizard())) { 1012. do_stone: 1013. if (!resists_ston(&youmonst) 1014. && !(poly_when_stoned(uasmon) && 1015. polymon(PM_STONE_GOLEM))) { 1016. Stoned = 5; 1017. return(1); 1018. /* You("turn to stone..."); */ 1019. /* done_in_by(mtmp); */ 1020. } 1021. } 1022. } 1023. } 1024. break; 1025. case AD_STCK: 1026. hitmsg(mtmp, mattk); 1027. if (uncancelled && !u.ustuck && !sticks(uasmon)) 1028. u.ustuck = mtmp; 1029. break; 1030. case AD_WRAP: 1031. if ((!mtmp->mcan || u.ustuck == mtmp) && !sticks(uasmon)) { 1032. if (!u.ustuck && !rn2(10)) { 1033. register struct obj *obj = (uarmc ? uarmc : uarm); 1034. #ifdef TOURIST 1035. if (!obj) obj = uarmu; 1036. #endif 1037. /* if your cloak/armor is greased, monster slips off */ 1038. if (obj && obj->greased) { 1039. dmg = 0; 1040. pline("%s slips off of your greased %s!", 1041. Monnam(mtmp), xname(obj)); 1042. if (!rn2(2)) { 1043. pline_The("grease wears off."); 1044. obj->greased = 0; 1045. } 1046. } else { 1047. pline("%s swings itself around you!", 1048. Monnam(mtmp)); 1049. u.ustuck = mtmp; 1050. } 1051. } else if(u.ustuck == mtmp) { 1052. if (is_pool(mtmp->mx,mtmp->my) && !is_swimmer(uasmon) 1053. && !Amphibious) { 1054. boolean moat = (levl[u.ux][u.uy].typ != POOL) && 1055. (levl[u.ux][u.uy].typ != WATER) && 1056. !Is_medusa_level(&u.uz) && 1057. !Is_waterlevel(&u.uz); 1058. 1059. pline("%s drowns you...", Monnam(mtmp)); 1060. killer_format = KILLED_BY_AN; 1061. Sprintf(buf, "%s by %s", 1062. moat ? "moat" : "pool of water", 1063. a_monnam(mtmp)); 1064. killer = buf; 1065. done(DROWNING); 1066. } else if(mattk->aatyp == AT_HUGS) 1067. You("are being crushed."); 1068. } else { 1069. dmg = 0; 1070. if(flags.verbose) 1071. pline("%s brushes against your %s.", Monnam(mtmp), 1072. body_part(LEG)); 1073. } 1074. } else dmg = 0; 1075. break; 1076. case AD_WERE: 1077. hitmsg(mtmp, mattk); 1078. if (uncancelled && !rn2(4) && u.ulycn == PM_PLAYERMON && 1079. !Protection_from_shape_changers && 1080. !defends(AD_WERE,uwep)) { 1081. You_feel("feverish."); 1082. exercise(A_CON, FALSE); 1083. u.ulycn = monsndx(mdat); 1084. } 1085. break; 1086. case AD_SGLD: 1087. hitmsg(mtmp, mattk); 1088. if (u.usym == mdat->mlet) break; 1089. if(!mtmp->mcan) stealgold(mtmp); 1090. break; 1091. 1092. case AD_SITM: /* for now these are the same */ 1093. case AD_SEDU: 1094. if (dmgtype(uasmon, AD_SEDU) 1095. #ifdef SEDUCE 1096. || dmgtype(uasmon, AD_SSEX) 1097. #endif 1098. ) { 1099. if (mtmp->minvent) 1100. pline("%s brags about the goods some dungeon explorer provided.", 1101. Monnam(mtmp)); 1102. else 1103. pline("%s makes some remarks about how difficult theft is lately.", 1104. Monnam(mtmp)); 1105. if (!tele_restrict(mtmp)) rloc(mtmp); 1106. return 3; 1107. } else if (mtmp->mcan) { 1108. if (!Blind) { 1109. pline("%s tries to %s you, but you seem %s.", 1110. Adjmonnam(mtmp, "plain"), 1111. flags.female ? "charm" : "seduce", 1112. flags.female ? "unaffected" : "uninterested"); 1113. } 1114. if(rn2(3)) { 1115. if (!tele_restrict(mtmp)) rloc(mtmp); 1116. return 3; 1117. } 1118. } else { 1119. switch (steal(mtmp)) { 1120. case -1: 1121. return 2; 1122. case 0: 1123. break; 1124. default: 1125. if (!tele_restrict(mtmp)) rloc(mtmp); 1126. mtmp->mflee = 1; 1127. return 3; 1128. } 1129. } 1130. break; 1131. #ifdef SEDUCE 1132. case AD_SSEX: 1133. if(could_seduce(mtmp, &youmonst, mattk) == 1 1134. && !mtmp->mcan) 1135. if (doseduce(mtmp)) 1136. return 3; 1137. break; 1138. #endif 1139. case AD_SAMU: 1140. hitmsg(mtmp, mattk); 1141. /* when the Wiz hits, 1/20 steals the amulet */ 1142. if (u.uhave.amulet || 1143. u.uhave.bell || u.uhave.book || u.uhave.menorah 1144. || u.uhave.questart) /* carrying the Quest Artifact */ 1145. if (!rn2(20)) stealamulet(mtmp); 1146. break; 1147. 1148. case AD_TLPT: 1149. hitmsg(mtmp, mattk); 1150. if (uncancelled) { 1151. if(flags.verbose) 1152. Your("position suddenly seems very uncertain!"); 1153. tele(); 1154. } 1155. break; 1156. case AD_RUST: 1157. hitmsg(mtmp, mattk); 1158. if (mtmp->mcan) break; 1159. if (u.umonnum == PM_IRON_GOLEM) { 1160. You("rust!"); 1161. rehumanize(); 1162. break; 1163. } 1164. hurtarmor(mdat, AD_RUST); 1165. break; 1166. case AD_DCAY: 1167. hitmsg(mtmp, mattk); 1168. if (mtmp->mcan) break; 1169. if (u.umonnum == PM_WOOD_GOLEM || 1170. u.umonnum == PM_LEATHER_GOLEM) { 1171. You("rot!"); 1172. rehumanize(); 1173. break; 1174. } 1175. hurtarmor(mdat, AD_DCAY); 1176. break; 1177. case AD_HEAL: 1178. if(!uwep 1179. #ifdef TOURIST 1180. && !uarmu 1181. #endif 1182. && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) { 1183. boolean goaway = FALSE; 1184. pline("%s hits! (I hope you don't mind.)", Monnam(mtmp)); 1185. if (u.mtimedone) { 1186. u.mh += rnd(7); 1187. if (!rn2(7)) { 1188. /* no upper limit necessary; effect is temporary */ 1189. u.mhmax++; 1190. if (!rn2(13)) goaway = TRUE; 1191. } 1192. if (u.mh > u.mhmax) u.mh = u.mhmax; 1193. } else { 1194. u.uhp += rnd(7); 1195. if (!rn2(7)) { 1196. /* hard upper limit via nurse care: 25 * ulevel */ 1197. if (u.uhpmax < 5 * u.ulevel + d(2 * u.ulevel, 10)) 1198. u.uhpmax++; 1199. if (!rn2(13)) goaway = TRUE; 1200. } 1201. if (u.uhp > u.uhpmax) u.uhp = u.uhpmax; 1202. } 1203. if (!rn2(3)) exercise(A_STR, TRUE); 1204. if (!rn2(3)) exercise(A_CON, TRUE); 1205. if (Sick) make_sick(0L, (char *) 0, FALSE, SICK_ALL); 1206. flags.botl = 1; 1207. if (goaway) { 1208. mongone(mtmp); 1209. return 2; 1210. } else if (!rn2(33)) { 1211. if (!tele_restrict(mtmp)) rloc(mtmp); 1212. if (!mtmp->mflee) { 1213. mtmp->mflee = 1; 1214. mtmp->mfleetim = d(3,6); 1215. } 1216. return 3; 1217. } 1218. dmg = 0; 1219. } else { 1220. if (Role_is('H')) { 1221. if (flags.soundok && !(moves % 5)) 1222. verbalize("Doc, I can't help you unless you cooperate."); 1223. dmg = 0; 1224. } else hitmsg(mtmp, mattk); 1225. } 1226. break; 1227. case AD_CURS: 1228. hitmsg(mtmp, mattk); 1229. if(!night() && mdat == &mons[PM_GREMLIN]) break; 1230. if(!mtmp->mcan && !rn2(10)) { 1231. if (flags.soundok) 1232. if (Blind) You_hear("laughter."); 1233. else pline("%s chuckles.", Monnam(mtmp)); 1234. if (u.umonnum == PM_CLAY_GOLEM) { 1235. pline("Some writing vanishes from your head!"); 1236. rehumanize(); 1237. break; 1238. } 1239. attrcurse(); 1240. } 1241. break; 1242. case AD_STUN: 1243. hitmsg(mtmp, mattk); 1244. if(!mtmp->mcan && !rn2(4)) { 1245. make_stunned(HStun + dmg, TRUE); 1246. dmg /= 2; 1247. } 1248. break; 1249. case AD_ACID: 1250. hitmsg(mtmp, mattk); 1251. if(!mtmp->mcan && !rn2(3)) 1252. if (resists_acid(&youmonst)) { 1253. pline("You're covered in acid, but it seems harmless."); 1254. dmg = 0; 1255. } else { 1256. pline("You're covered in acid! It burns!"); 1257. exercise(A_STR, FALSE); 1258. } 1259. else dmg = 0; 1260. break; 1261. case AD_SLOW: 1262. hitmsg(mtmp, mattk); 1263. if (uncancelled && (Fast & (INTRINSIC|TIMEOUT)) && 1264. !defends(AD_SLOW, uwep) && !rn2(4)) 1265. u_slow_down(); 1266. break; 1267. case AD_DREN: 1268. hitmsg(mtmp, mattk); 1269. if (uncancelled && !rn2(4)) 1270. drain_en(dmg); 1271. dmg = 0; 1272. break; 1273. case AD_CONF: 1274. hitmsg(mtmp, mattk); 1275. if(!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) { 1276. mtmp->mspec_used = mtmp->mspec_used + (dmg + rn2(6)); 1277. if(Confusion) 1278. You("are getting even more confused."); 1279. else You("are getting confused."); 1280. make_confused(HConfusion + dmg, FALSE); 1281. } 1282. /* fall through to next case */ 1283. case AD_DETH: 1284. pline("%s reaches out with its deadly touch.", Monnam(mtmp)); 1285. if (is_undead(uasmon)) { 1286. /* Still does normal damage */ 1287. pline("Was that the touch of death?"); 1288. break; 1289. } 1290. if(!Antimagic && rn2(20) > 16) { 1291. killer_format = KILLED_BY_AN; 1292. killer = "touch of death"; 1293. done(DIED); 1294. } else { 1295. if(!rn2(5)) { 1296. if(Antimagic) shieldeff(u.ux, u.uy); 1297. pline("Lucky for you, it didn't work!"); 1298. dmg = 0; 1299. } else You_feel("your life force draining away..."); 1300. } 1301. break; 1302. case AD_PEST: 1303. pline("%s reaches out, and you feel fever and chills.", 1304. Monnam(mtmp)); 1305. (void) diseasemu(mdat); /* plus the normal damage */ 1306. break; 1307. case AD_FAMN: 1308. pline("%s reaches out, and your body shrivels.", 1309. Monnam(mtmp)); 1310. exercise(A_CON, FALSE); 1311. if (!is_fainted()) morehungry(rn1(40,40)); 1312. /* plus the normal damage */ 1313. break; 1314. default: dmg = 0; 1315. break; 1316. } 1317. if(u.uhp < 1) done_in_by(mtmp); 1318. 1319. /* Negative armor class reduces damage done instead of fully protecting 1320. * against hits. 1321. */ 1322. if (dmg && u.uac < 0) { 1323. dmg -= rnd(-u.uac); 1324. if (dmg < 1) dmg = 1; 1325. } 1326. 1327. if(dmg) { 1328. if (Half_physical_damage 1329. /* Mitre of Holiness */ 1330. || (Role_is('P') && uarmh && is_quest_artifact(uarmh) && 1331. (is_undead(mtmp->data) || is_demon(mtmp->data)))) 1332. dmg = (dmg+1) / 2; 1333. mdamageu(mtmp, dmg); 1334. } 1335. 1336. if (dmg) { 1337. res = passiveum(olduasmon, mtmp, mattk); 1338. stop_occupation(); 1339. return res; 1340. } else 1341. return 1; 1342. } 1343. 1344. #endif /* OVL1 */ 1345. #ifdef OVLB 1346. 1347. STATIC_OVL int 1348. gulpmu(mtmp, mattk) /* monster swallows you, or damage if u.uswallow */ 1349. register struct monst *mtmp; 1350. register struct attack *mattk; 1351. { 1352. struct trap *t = t_at(u.ux, u.uy); 1353. int tmp = d((int)mattk->damn, (int)mattk->damd); 1354. int tim_tmp; 1355. register struct obj *otmp2; 1356. int i; 1357. 1358. if (!u.uswallow) { /* swallows you */ 1359. if (uasmon->msize >= MZ_HUGE) return(0); 1360. if ((t && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))) && 1361. sobj_at(BOULDER, u.ux, u.uy)) 1362. return(0); 1363. 1364. if (Punished) unplacebc(); /* ball&chain go away */ 1365. remove_monster(mtmp->mx, mtmp->my); 1366. place_monster(mtmp, u.ux, u.uy); 1367. u.ustuck = mtmp; 1368. newsym(mtmp->mx,mtmp->my); 1369. pline("%s engulfs you!", Monnam(mtmp)); 1370. stop_occupation(); 1371. 1372. if (u.utrap) { 1373. You("are released from the %s!", 1374. u.utraptype==TT_WEB ? "web" : "trap"); 1375. u.utrap = 0; 1376. } 1377. 1378. i = number_leashed(); 1379. if (i > 0) { 1380. pline_The("leash%s snap%s loose.", 1381. (i > 1) ? "es" : "", 1382. (i > 1) ? "" : "s"); 1383. unleash_all(); 1384. } 1385. 1386. if (u.umonnum==PM_COCKATRICE && !resists_ston(mtmp)) { 1387. minstapetrify(mtmp, TRUE); 1388. if (mtmp->mhp > 0) return 0; 1389. else return 2; 1390. } 1391. 1392. display_nhwindow(WIN_MESSAGE, FALSE); 1393. vision_recalc(2); /* hero can't see anything */ 1394. u.uswallow = 1; 1395. /* assume that u.uswldtim always set >= 0 */ 1396. u.uswldtim = (tim_tmp = 1397. (-u.uac + 10 + rnd(25 - (int)mtmp->m_lev)) >> 1) > 0 ? 1398. tim_tmp : 0; 1399. swallowed(1); 1400. for(otmp2 = invent; otmp2; otmp2 = otmp2->nobj) { 1401. (void) snuff_lit(otmp2); 1402. } 1403. } 1404. 1405. if (mtmp != u.ustuck) return(0); 1406. 1407. switch(mattk->adtyp) { 1408. 1409. case AD_DGST: 1410. if(u.uswldtim <= 1) { /* a3 *//*no cf unsigned <=0*/ 1411. pline("%s totally digests you!", Monnam(mtmp)); 1412. tmp = u.uhp; 1413. if (Half_physical_damage) tmp *= 2; /* sorry */ 1414. } else { 1415. pline("%s digests you!", Monnam(mtmp)); 1416. exercise(A_STR, FALSE); 1417. } 1418. break; 1419. case AD_PHYS: 1420. You("are pummeled with debris!"); 1421. exercise(A_STR, FALSE); 1422. break; 1423. case AD_ACID: 1424. if (resists_acid(&youmonst)) { 1425. You("are covered with a seemingly harmless goo."); 1426. tmp = 0; 1427. } else { 1428. if (Hallucination) pline("Ouch! You've been slimed!"); 1429. else You("are covered in slime! It burns!"); 1430. exercise(A_STR, FALSE); 1431. } 1432. break; 1433. case AD_BLND: 1434. if (!defends(AD_BLND, uwep)) { 1435. if(!Blind) { 1436. You_cant("see in here!"); 1437. make_blinded((long)tmp,FALSE); 1438. } else 1439. /* keep him blind until disgorged */ 1440. make_blinded(Blinded+1,FALSE); 1441. } 1442. tmp = 0; 1443. break; 1444. case AD_ELEC: 1445. if(!mtmp->mcan && rn2(2)) { 1446. pline_The("air around you crackles with electricity."); 1447. if (Shock_resistance) { 1448. shieldeff(u.ux, u.uy); 1449. You("seem unhurt."); 1450. ugolemeffects(AD_ELEC,tmp); 1451. tmp = 0; 1452. } 1453. } else tmp = 0; 1454. break; 1455. case AD_COLD: 1456. if(!mtmp->mcan && rn2(2)) { 1457. if (Cold_resistance) { 1458. shieldeff(u.ux, u.uy); 1459. You_feel("mildly chilly."); 1460. ugolemeffects(AD_COLD,tmp); 1461. tmp = 0; 1462. } else You("are freezing to death!"); 1463. } else tmp = 0; 1464. break; 1465. case AD_FIRE: 1466. if(!mtmp->mcan && rn2(2)) { 1467. if (Fire_resistance) { 1468. shieldeff(u.ux, u.uy); 1469. You_feel("mildly hot."); 1470. ugolemeffects(AD_FIRE,tmp); 1471. tmp = 0; 1472. } else You("are burning to a crisp!"); 1473. } else tmp = 0; 1474. break; 1475. case AD_DISE: 1476. if (!diseasemu(mtmp->data)) tmp = 0; 1477. break; 1478. default: 1479. tmp = 0; 1480. break; 1481. } 1482. 1483. if (Half_physical_damage) tmp = (tmp+1) / 2; 1484. 1485. mdamageu(mtmp, tmp); 1486. if(tmp) stop_occupation(); 1487. if(u.uswldtim) --u.uswldtim; 1488. 1489. if (u.umonnum == PM_COCKATRICE && !resists_ston(mtmp)) { 1490. pline("%s very hurriedly %s you!", Monnam(mtmp), 1491. is_animal(mtmp->data)? "regurgitates" : "expels"); 1492. expels(mtmp, mtmp->data, FALSE); 1493. } else if (!u.uswldtim || uasmon->msize >= MZ_HUGE) { 1494. You("get %s!", is_animal(mtmp->data)? "regurgitated" : "expelled"); 1495. if (flags.verbose && is_animal(mtmp->data)) 1496. pline("Obviously %s doesn't like your taste.", 1497. mon_nam(mtmp)); 1498. expels(mtmp, mtmp->data, FALSE); 1499. } 1500. return(1); 1501. } 1502. 1503. STATIC_OVL int 1504. explmu(mtmp, mattk, ufound) /* monster explodes in your face */ 1505. register struct monst *mtmp; 1506. register struct attack *mattk; 1507. boolean ufound; 1508. { 1509. if (mtmp->mcan) return(0); 1510. 1511. if (!ufound) 1512. pline("%s explodes at a spot in thin air!", 1513. canseemon(mtmp) ? Monnam(mtmp) : "It"); 1514. else { 1515. register int tmp = d((int)mattk->damn, (int)mattk->damd); 1516. register boolean not_affected = defends((int)mattk->adtyp, uwep); 1517. 1518. hitmsg(mtmp, mattk); 1519. 1520. switch (mattk->adtyp) { 1521. case AD_COLD: 1522. not_affected |= Cold_resistance; 1523. 1524. if (!not_affected) { 1525. if (ACURR(A_DEX) > rnd(20)) { 1526. You("duck some of the blast."); 1527. tmp = (tmp+1) / 2; 1528. } else { 1529. if (flags.verbose) You("get blasted!"); 1530. } 1531. if (Half_physical_damage) tmp = (tmp+1) / 2; 1532. mdamageu(mtmp, tmp); 1533. } 1534. break; 1535. 1536. case AD_BLND: 1537. not_affected |= (u.umonnum == PM_YELLOW_LIGHT) || Blind; 1538. if (!not_affected) { 1539. /* sometimes you're affected even if it's invisible */ 1540. if (mon_visible(mtmp) || (rnd(tmp /= 2) > u.ulevel)) { 1541. You("are blinded by a blast of light!"); 1542. make_blinded((long)tmp, FALSE); 1543. } else 1544. if (flags.verbose) 1545. You("get the impression it was not terribly bright."); 1546. } 1547. break; 1548. 1549. case AD_HALU: 1550. not_affected |= Blind || 1551. (u.umonnum == PM_BLACK_LIGHT || 1552. u.umonnum == PM_VIOLET_FUNGUS || 1553. dmgtype(uasmon, AD_STUN)); 1554. if (!not_affected) { 1555. if (!Hallucination) 1556. You("are freaked by a blast of kaleidoscopic light!"); 1557. make_hallucinated(HHallucination + (long)tmp,FALSE,0L); 1558. } 1559. break; 1560. 1561. default: 1562. break; 1563. } 1564. if (not_affected) { 1565. You("seem unaffected by it."); 1566. ugolemeffects((int)mattk->adtyp, tmp); 1567. } 1568. } 1569. mondead(mtmp); 1570. if (mtmp->mhp > 0) return(0); 1571. return(2); /* it dies */ 1572. } 1573. 1574. int 1575. gazemu(mtmp, mattk) /* monster gazes at you */ 1576. register struct monst *mtmp; 1577. register struct attack *mattk; 1578. { 1579. switch(mattk->adtyp) { 1580. case AD_STON: 1581. if (mtmp->mcan) { 1582. if (mtmp->data == &mons[PM_MEDUSA] && canseemon(mtmp)) 1583. pline("%s doesn't look all that ugly.", Monnam(mtmp)); 1584. break; 1585. } 1586. if(Reflecting && m_canseeu(mtmp) && 1587. !mtmp->mcan && mtmp->data == &mons[PM_MEDUSA]) { 1588. if(!Blind) { 1589. if(Reflecting & W_AMUL) 1590. makeknown(AMULET_OF_REFLECTION); 1591. else 1592. makeknown(SHIELD_OF_REFLECTION); 1593. pline("%s gaze is reflected by your %s.", 1594. s_suffix(Monnam(mtmp)), 1595. (Reflecting & W_AMUL) ? 1596. "medallion" : "shield"); 1597. pline("%s is turned to stone!", Monnam(mtmp)); 1598. } 1599. stoned = TRUE; 1600. killed(mtmp); 1601. 1602. if (mtmp->mhp > 0) break; 1603. return 2; 1604. } 1605. if (canseemon(mtmp) && !resists_ston(&youmonst)) { 1606. You("look upon %s.", mon_nam(mtmp)); 1607. if(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)) 1608. break; 1609. You("turn to stone..."); 1610. killer_format = KILLED_BY; 1611. killer = mons[PM_MEDUSA].mname; 1612. done(STONING); 1613. } 1614. break; 1615. case AD_CONF: 1616. if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && 1617. !mtmp->mspec_used && rn2(5)) { 1618. int conf = d(3,4); 1619. 1620. mtmp->mspec_used = mtmp->mspec_used + (conf + rn2(6)); 1621. if(!Confusion) 1622. pline("%s gaze confuses you!", 1623. s_suffix(Monnam(mtmp))); 1624. else 1625. You("are getting more and more confused."); 1626. make_confused(HConfusion + conf, FALSE); 1627. } 1628. break; 1629. case AD_STUN: 1630. if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && 1631. !mtmp->mspec_used && rn2(5)) { 1632. int stun = d(2,6); 1633. 1634. mtmp->mspec_used = mtmp->mspec_used + (stun + rn2(6)); 1635. make_stunned(HStun + stun, TRUE); 1636. pline("%s stares piercingly at you!", Monnam(mtmp)); 1637. } 1638. break; 1639. case AD_BLND: 1640. if(!mtmp->mcan && canseemon(mtmp) && !defends(AD_BLND, uwep) && 1641. distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) { 1642. int blnd = d((int)mattk->damn, (int)mattk->damd); 1643. make_blinded((long)blnd,FALSE); 1644. make_stunned((long)d(1,3),TRUE); 1645. You("are blinded by %s radiance!", 1646. s_suffix(mon_nam(mtmp))); 1647. } 1648. break; 1649. #ifdef PM_BEHOLDER /* work in progress */ 1650. case AD_SLEE: 1651. if(multi >= 0 && !rn2(5) && !Sleep_resistance) { 1652. fall_asleep(-rnd(10), TRUE); 1653. pline("%s gaze makes you very sleepy...", 1654. s_suffix(Monnam(mtmp))); 1655. } 1656. break; 1657. case AD_SLOW: 1658. if((Fast & (INTRINSIC|TIMEOUT)) && 1659. !defends(AD_SLOW, uwep) && !rn2(4)) 1660. u_slow_down(); 1661. break; 1662. #endif 1663. default: impossible("Gaze attack %d?", mattk->adtyp); 1664. break; 1665. } 1666. return(0); 1667. } 1668. 1669. #endif /* OVLB */ 1670. #ifdef OVL1 1671. 1672. void 1673. mdamageu(mtmp, n) /* mtmp hits you for n points damage */ 1674. register struct monst *mtmp; 1675. register int n; 1676. { 1677. flags.botl = 1; 1678. if (u.mtimedone) { 1679. u.mh -= n; 1680. if (u.mh < 1) rehumanize(); 1681. } else { 1682. u.uhp -= n; 1683. if(u.uhp < 1) done_in_by(mtmp); 1684. } 1685. } 1686. 1687. #endif /* OVL1 */ 1688. #ifdef OVLB 1689. 1690. STATIC_OVL void 1691. urustm(mon, obj) 1692. register struct monst *mon; 1693. register struct obj *obj; 1694. { 1695. boolean vis; 1696. 1697. if (!mon || !obj) return; /* just in case */ 1698. vis = cansee(mon->mx, mon->my); 1699. if (u.umonnum == PM_RUST_MONSTER && 1700. is_rustprone(obj) && obj->oeroded < MAX_ERODE) { 1701. if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) { 1702. if (vis) 1703. pline("Somehow, %s weapon is not affected.", 1704. s_suffix(mon_nam(mon))); 1705. if (obj->greased && !rn2(2)) obj->greased = 0; 1706. } else { 1707. if (vis) 1708. pline("%s %s%s!", 1709. s_suffix(Monnam(mon)), aobjnam(obj, "rust"), 1710. obj->oeroded ? " further" : ""); 1711. obj->oeroded++; 1712. } 1713. } 1714. } 1715. 1716. #endif /* OVLB */ 1717. #ifdef OVL1 1718. 1719. int 1720. could_seduce(magr,mdef,mattk) 1721. struct monst *magr, *mdef; 1722. struct attack *mattk; 1723. /* returns 0 if seduction impossible, 1724. * 1 if fine, 1725. * 2 if wrong gender for nymph */ 1726. { 1727. register struct permonst *pagr; 1728. boolean agrinvis, defperc; 1729. xchar genagr, gendef; 1730. 1731. if(magr == &youmonst) { 1732. pagr = uasmon; 1733. agrinvis = (Invis != 0); 1734. genagr = poly_gender(); 1735. } else { 1736. pagr = magr->data; 1737. agrinvis = magr->minvis; 1738. genagr = gender(magr); 1739. } 1740. if(mdef == &youmonst) { 1741. defperc = (See_invisible != 0); 1742. gendef = poly_gender(); 1743. } else { 1744. defperc = perceives(mdef->data); 1745. gendef = gender(mdef); 1746. } 1747. 1748. if(agrinvis && !defperc 1749. #ifdef SEDUCE 1750. && mattk && mattk->adtyp != AD_SSEX 1751. #endif 1752. ) 1753. return 0; 1754. 1755. if(pagr->mlet != S_NYMPH 1756. && ((pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS]) 1757. #ifdef SEDUCE 1758. || (mattk && mattk->adtyp != AD_SSEX) 1759. #endif 1760. )) 1761. return 0; 1762. 1763. if(genagr == 1 - gendef) 1764. return 1; 1765. else 1766. return (pagr->mlet == S_NYMPH) ? 2 : 0; 1767. } 1768. 1769. #endif /* OVL1 */ 1770. #ifdef OVLB 1771. 1772. #ifdef SEDUCE 1773. /* Returns 1 if monster teleported */ 1774. int 1775. doseduce(mon) 1776. register struct monst *mon; 1777. { 1778. register struct obj *ring, *nring; 1779. boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */ 1780. char qbuf[QBUFSZ]; 1781. 1782. if (mon->mcan || mon->mspec_used) { 1783. pline("%s acts as though %s has got a %sheadache.", 1784. Monnam(mon), he[pronoun_gender(mon)], 1785. mon->mcan ? "severe " : ""); 1786. return 0; 1787. } 1788. 1789. if (unconscious()) { 1790. pline("%s seems dismayed at your lack of response.", 1791. Monnam(mon)); 1792. return 0; 1793. } 1794. 1795. if (Blind) pline("It caresses you..."); 1796. else You_feel("very attracted to %s.", mon_nam(mon)); 1797. 1798. for(ring = invent; ring; ring = nring) { 1799. nring = ring->nobj; 1800. if (ring->otyp != RIN_ADORNMENT) continue; 1801. if (fem) { 1802. if (rn2(20) < ACURR(A_CHA)) { 1803. Sprintf(qbuf, "\"That %s looks pretty. May I have it?\"", 1804. xname(ring)); 1805. makeknown(RIN_ADORNMENT); 1806. if (yn(qbuf) == 'n') continue; 1807. } else pline("%s decides she'd like your %s, and takes it.", 1808. Blind ? "She" : Monnam(mon), xname(ring)); 1809. makeknown(RIN_ADORNMENT); 1810. if (ring==uleft || ring==uright) Ring_gone(ring); 1811. if (ring==uwep) setuwep((struct obj *)0); 1812. freeinv(ring); 1813. mpickobj(mon,ring); 1814. } else { 1815. char buf[BUFSZ]; 1816. 1817. if (uleft && uright && uleft->otyp == RIN_ADORNMENT 1818. && uright->otyp==RIN_ADORNMENT) 1819. break; 1820. if (ring==uleft || ring==uright) continue; 1821. if (rn2(20) < ACURR(A_CHA)) { 1822. Sprintf(qbuf,"\"That %s looks pretty. Would you wear it for me?\"", 1823. xname(ring)); 1824. makeknown(RIN_ADORNMENT); 1825. if (yn(qbuf) == 'n') continue; 1826. } else { 1827. pline("%s decides you'd look prettier wearing your %s,", 1828. Blind ? "He" : Monnam(mon), xname(ring)); 1829. pline("and puts it on your finger."); 1830. } 1831. makeknown(RIN_ADORNMENT); 1832. if (!uright) { 1833. pline("%s puts %s on your right hand.", 1834. Blind ? "He" : Monnam(mon), the(xname(ring))); 1835. setworn(ring, RIGHT_RING); 1836. } else if (!uleft) { 1837. pline("%s puts %s on your left hand.", 1838. Blind ? "He" : Monnam(mon), the(xname(ring))); 1839. setworn(ring, LEFT_RING); 1840. } else if (uright && uright->otyp != RIN_ADORNMENT) { 1841. Strcpy(buf, xname(uright)); 1842. pline("%s replaces your %s with your %s.", 1843. Blind ? "He" : Monnam(mon), buf, xname(ring)); 1844. Ring_gone(uright); 1845. setworn(ring, RIGHT_RING); 1846. } else if (uleft && uleft->otyp != RIN_ADORNMENT) { 1847. Strcpy(buf, xname(uleft)); 1848. pline("%s replaces your %s with your %s.", 1849. Blind ? "He" : Monnam(mon), buf, xname(ring)); 1850. Ring_gone(uleft); 1851. setworn(ring, LEFT_RING); 1852. } else impossible("ring replacement"); 1853. Ring_on(ring); 1854. prinv((char *)0, ring, 0L); 1855. } 1856. } 1857. 1858. if (!uarmc && !uarmf && !uarmg && !uarms && !uarmh 1859. #ifdef TOURIST 1860. && !uarmu 1861. #endif 1862. ) 1863. pline("%s murmurs sweet nothings into your ear.", 1864. Blind ? (fem ? "She" : "He") : Monnam(mon)); 1865. else 1866. pline("%s murmurs in your ear, while helping you undress.", 1867. Blind ? (fem ? "She" : "He") : Monnam(mon)); 1868. mayberem(uarmc, "cloak"); 1869. if(!uarmc) 1870. mayberem(uarm, "suit"); 1871. mayberem(uarmf, "boots"); 1872. if(!uwep || !welded(uwep)) 1873. mayberem(uarmg, "gloves"); 1874. mayberem(uarms, "shield"); 1875. mayberem(uarmh, "helmet"); 1876. #ifdef TOURIST 1877. if(!uarmc && !uarm) 1878. mayberem(uarmu, "shirt"); 1879. #endif 1880. 1881. if (uarm || uarmc) { 1882. verbalize("You're such a %s; I wish...", 1883. flags.female ? "sweet lady" : "nice guy"); 1884. if (!tele_restrict(mon)) rloc(mon); 1885. return 1; 1886. } 1887. if (u.ualign.type == A_CHAOTIC) 1888. adjalign(1); 1889. 1890. /* by this point you have discovered mon's identity, blind or not... */ 1891. pline("Time stands still while you and %s lie in each other's arms...", 1892. mon_nam(mon)); 1893. if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) { 1894. /* Don't bother with mspec_used here... it didn't get tired! */ 1895. pline("%s seems to have enjoyed it more than you...", 1896. Monnam(mon)); 1897. switch (rn2(5)) { 1898. case 0: You_feel("drained of energy."); 1899. u.uen = 0; 1900. u.uenmax -= rnd(Half_physical_damage ? 5 : 10); 1901. exercise(A_CON, FALSE); 1902. if (u.uenmax < 0) u.uenmax = 0; 1903. break; 1904. case 1: You("are down in the dumps."); 1905. (void) adjattrib(A_CON, -1, TRUE); 1906. exercise(A_CON, FALSE); 1907. flags.botl = 1; 1908. break; 1909. case 2: Your("senses are dulled."); 1910. (void) adjattrib(A_WIS, -1, TRUE); 1911. exercise(A_WIS, FALSE); 1912. flags.botl = 1; 1913. break; 1914. case 3: 1915. if (!resists_drli(&youmonst)) { 1916. You_feel("out of shape."); 1917. losexp(); 1918. if(u.uhp <= 0) { 1919. killer_format = KILLED_BY; 1920. killer = "overexertion"; 1921. done(DIED); 1922. } 1923. } else { 1924. You("have a curious feeling..."); 1925. } 1926. break; 1927. case 4: { 1928. int tmp; 1929. You_feel("exhausted."); 1930. exercise(A_STR, FALSE); 1931. tmp = rn1(10, 6); 1932. if(Half_physical_damage) tmp = (tmp+1) / 2; 1933. losehp(tmp, "exhaustion", KILLED_BY); 1934. break; 1935. } 1936. } 1937. } else { 1938. mon->mspec_used = rnd(100); /* monster is worn out */ 1939. You("seem to have enjoyed it more than %s...", mon_nam(mon)); 1940. switch (rn2(5)) { 1941. case 0: You_feel("raised to your full potential."); 1942. exercise(A_CON, TRUE); 1943. u.uen = (u.uenmax += rnd(5)); 1944. break; 1945. case 1: You_feel("good enough to do it again."); 1946. (void) adjattrib(A_CON, 1, TRUE); 1947. exercise(A_CON, TRUE); 1948. flags.botl = 1; 1949. break; 1950. case 2: You("will always remember %s...", mon_nam(mon)); 1951. (void) adjattrib(A_WIS, 1, TRUE); 1952. exercise(A_WIS, TRUE); 1953. flags.botl = 1; 1954. break; 1955. case 3: pline("That was a very educational experience."); 1956. pluslvl(); 1957. exercise(A_WIS, TRUE); 1958. break; 1959. case 4: You_feel("restored to health!"); 1960. u.uhp = u.uhpmax; 1961. if (u.mtimedone) u.mh = u.mhmax; 1962. exercise(A_STR, TRUE); 1963. flags.botl = 1; 1964. break; 1965. } 1966. } 1967. 1968. if (mon->mtame) /* don't charge */ ; 1969. else if (rn2(20) < ACURR(A_CHA)) { 1970. pline("%s demands that you pay %s, but you refuse...", 1971. Monnam(mon), him[fem]); 1972. } else if (u.umonnum == PM_LEPRECHAUN) 1973. pline("%s tries to take your money, but fails...", 1974. Monnam(mon)); 1975. else { 1976. long cost; 1977. 1978. if (u.ugold > (long)LARGEST_INT - 10L) 1979. cost = (long) rnd(LARGEST_INT) + 500L; 1980. else 1981. cost = (long) rnd((int)u.ugold + 10) + 500L; 1982. if (mon->mpeaceful) { 1983. cost /= 5L; 1984. if (!cost) cost = 1L; 1985. } 1986. if (cost > u.ugold) cost = u.ugold; 1987. if (!cost) verbalize("It's on the house!"); 1988. else { 1989. pline("%s takes %ld zorkmid%s for services rendered!", 1990. Monnam(mon), cost, plur(cost)); 1991. u.ugold -= cost; 1992. mon->mgold += cost; 1993. flags.botl = 1; 1994. } 1995. } 1996. if (!rn2(25)) mon->mcan = 1; /* monster is worn out */ 1997. if (!tele_restrict(mon)) rloc(mon); 1998. return 1; 1999. } 2000. 2001. static void 2002. mayberem(obj, str) 2003. register struct obj *obj; 2004. const char *str; 2005. { 2006. char qbuf[QBUFSZ]; 2007. 2008. if (!obj || !obj->owornmask) return; 2009. 2010. if (rn2(20) < ACURR(A_CHA)) { 2011. Sprintf(qbuf,"\"Shall I remove your %s, %s?\"", 2012. str, 2013. (!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart")); 2014. if (yn(qbuf) == 'n') return; 2015. } else { 2016. char hairbuf[BUFSZ]; 2017. 2018. Sprintf(hairbuf,"let me run run my fingers through your %s", 2019. body_part(HAIR)); 2020. verbalize("Take off your %s; %s.", str, 2021. (obj == uarm) ? "let's get a little closer" : 2022. (obj == uarmc || obj == uarms) ? "it's in the way" : 2023. (obj == uarmf) ? "let me rub your feet" : 2024. (obj == uarmg) ? "they're too clumsy" : 2025. #ifdef TOURIST 2026. (obj == uarmu) ? "let me massage you" : 2027. #endif 2028. /* obj == uarmh */ 2029. hairbuf); 2030. } 2031. if (donning(obj)) cancel_don(); 2032. if (obj == uarm) (void) Armor_off(); 2033. else if (obj == uarmc) (void) Cloak_off(); 2034. else if (obj == uarmf) (void) Boots_off(); 2035. else if (obj == uarmg) (void) Gloves_off(); 2036. else if (obj == uarmh) (void) Helmet_off(); 2037. else setworn((struct obj *)0, obj->owornmask & W_ARMOR); 2038. } 2039. #endif /* SEDUCE */ 2040. 2041. #endif /* OVLB */ 2042. 2043. #ifdef OVL1 2044. 2045. static int 2046. passiveum(olduasmon,mtmp,mattk) 2047. struct permonst *olduasmon; 2048. register struct monst *mtmp; 2049. register struct attack *mattk; 2050. { 2051. int i, tmp; 2052. 2053. for(i = 0; ; i++) { 2054. if(i >= NATTK) return 1; 2055. if(olduasmon->mattk[i].aatyp == AT_NONE) break; 2056. } 2057. if (olduasmon->mattk[i].damn) 2058. tmp = d((int)olduasmon->mattk[i].damn, 2059. (int)olduasmon->mattk[i].damd); 2060. else if(olduasmon->mattk[i].damd) 2061. tmp = d((int)olduasmon->mlevel+1, (int)olduasmon->mattk[i].damd); 2062. else 2063. tmp = 0; 2064. 2065. /* These affect the enemy even if you were "killed" (rehumanized) */ 2066. switch(olduasmon->mattk[i].adtyp) { 2067. case AD_ACID: 2068. if (!rn2(2)) { 2069. pline("%s is splashed by your acid!", Monnam(mtmp)); 2070. if (resists_acid(mtmp)) { 2071. pline("%s is not affected.", Monnam(mtmp)); 2072. tmp = 0; 2073. } 2074. } else tmp = 0; 2075. goto assess_dmg; 2076. case AD_STON: /* cockatrice */ 2077. if (!resists_ston(mtmp) && 2078. (mattk->aatyp != AT_WEAP || !MON_WEP(mtmp)) && 2079. mattk->aatyp != AT_GAZE && mattk->aatyp != AT_EXPL && 2080. mattk->aatyp != AT_MAGC && 2081. !(mtmp->misc_worn_check & W_ARMG)) { 2082. if(poly_when_stoned(mtmp->data)) { 2083. mon_to_stone(mtmp); 2084. return (1); 2085. } 2086. pline("%s turns to stone!", Monnam(mtmp)); 2087. stoned = 1; 2088. xkilled(mtmp, 0); 2089. if (mtmp->mhp > 0) return 1; 2090. return 2; 2091. } 2092. return 1; 2093. default: 2094. break; 2095. } 2096. if (!u.mtimedone) return 1; 2097. 2098. /* These affect the enemy only if you are still a monster */ 2099. if (rn2(3)) switch(uasmon->mattk[i].adtyp) { 2100. case AD_PLYS: /* Floating eye */ 2101. if (tmp > 127) tmp = 127; 2102. if (u.umonnum == PM_FLOATING_EYE) { 2103. if (!rn2(4)) tmp = 127; 2104. if (mtmp->mcansee && haseyes(mtmp->data) && rn2(3) && 2105. (perceives(mtmp->data) || !Invis)) { 2106. if (Blind) 2107. pline("As a blind %s, you cannot defend yourself.", 2108. uasmon->mname); 2109. else { 2110. if (mon_reflects(mtmp, 2111. "Your gaze is reflected by %s %s.")) 2112. return 1; 2113. pline("%s is frozen by your gaze!", Monnam(mtmp)); 2114. mtmp->mcanmove = 0; 2115. mtmp->mfrozen = tmp; 2116. return 3; 2117. } 2118. } 2119. } else { /* gelatinous cube */ 2120. pline("%s is frozen by you.", Monnam(mtmp)); 2121. mtmp->mcanmove = 0; 2122. mtmp->mfrozen = tmp; 2123. return 3; 2124. } 2125. return 1; 2126. case AD_COLD: /* Brown mold or blue jelly */ 2127. if (resists_cold(mtmp)) { 2128. shieldeff(mtmp->mx, mtmp->my); 2129. pline("%s is mildly chilly.", Monnam(mtmp)); 2130. golemeffects(mtmp, AD_COLD, tmp); 2131. tmp = 0; 2132. break; 2133. } 2134. pline("%s is suddenly very cold!", Monnam(mtmp)); 2135. u.mh += tmp / 2; 2136. if (u.mhmax < u.mh) u.mhmax = u.mh; 2137. if (u.mhmax > ((uasmon->mlevel+1) * 8)) { 2138. register struct monst *mon; 2139. 2140. if ((mon = cloneu()) != 0) { 2141. mon->mhpmax = u.mhmax /= 2; 2142. You("multiply from %s heat!", 2143. s_suffix(mon_nam(mtmp))); 2144. } 2145. } 2146. break; 2147. case AD_STUN: /* Yellow mold */ 2148. if (!mtmp->mstun) { 2149. mtmp->mstun = 1; 2150. pline("%s staggers.", Monnam(mtmp)); 2151. } 2152. tmp = 0; 2153. break; 2154. case AD_FIRE: /* Red mold */ 2155. if (resists_fire(mtmp)) { 2156. shieldeff(mtmp->mx, mtmp->my); 2157. pline("%s is mildly warm.", Monnam(mtmp)); 2158. golemeffects(mtmp, AD_FIRE, tmp); 2159. tmp = 0; 2160. break; 2161. } 2162. pline("%s is suddenly very hot!", Monnam(mtmp)); 2163. break; 2164. case AD_ELEC: 2165. if (resists_elec(mtmp)) { 2166. shieldeff(mtmp->mx, mtmp->my); 2167. pline("%s is slightly tingled.", Monnam(mtmp)); 2168. golemeffects(mtmp, AD_ELEC, tmp); 2169. tmp = 0; 2170. break; 2171. } 2172. pline("%s is jolted with your electricity!", Monnam(mtmp)); 2173. break; 2174. default: tmp = 0; 2175. break; 2176. } 2177. else tmp = 0; 2178. 2179. assess_dmg: 2180. if((mtmp->mhp -= tmp) <= 0) { 2181. pline("%s dies!", Monnam(mtmp)); 2182. xkilled(mtmp,0); 2183. if (mtmp->mhp > 0) return 1; 2184. return 2; 2185. } 2186. return 1; 2187. } 2188. 2189. #endif /* OVL1 */ 2190. #ifdef OVLB 2191. 2192. #include "edog.h" 2193. struct monst * 2194. cloneu() 2195. { 2196. register struct monst *mon; 2197. int mndx = monsndx(uasmon); 2198. 2199. if (u.mh <= 1) return(struct monst *)0; 2200. if (mvitals[mndx].mvflags & G_EXTINCT) return(struct monst *)0; 2201. uasmon->pxlth += sizeof(struct edog); 2202. mon = makemon(uasmon, u.ux, u.uy); 2203. uasmon->pxlth -= sizeof(struct edog); 2204. mon = christen_monst(mon, plname); 2205. initedog(mon); 2206. mon->m_lev = uasmon->mlevel; 2207. mon->mhp = u.mh /= 2; 2208. mon->mhpmax = u.mhmax; 2209. return(mon); 2210. } 2211. 2212. #endif /* OVLB */ 2213. 2214. /*mhitu.c*/