Below is the full text to mhitu.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/mhitu.c#line123]], for example.
The latest source code for vanilla NetHack is at Source code.
| The NetHack General Public License applies to screenshots, source code and other content from NetHack. |
1. /* SCCS Id: @(#)mhitu.c 3.4 2003/11/26 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "artifact.h" 7. #include "edog.h" 8. 9. STATIC_VAR NEARDATA struct obj *otmp; 10. 11. STATIC_DCL void FDECL(urustm, (struct monst *, struct obj *)); 12. # ifdef OVL1 13. STATIC_DCL boolean FDECL(u_slip_free, (struct monst *,struct attack *)); 14. STATIC_DCL int FDECL(passiveum, (struct permonst *,struct monst *,struct attack *)); 15. # endif /* OVL1 */ 16. 17. #ifdef OVLB 18. # ifdef SEDUCE 19. STATIC_DCL void FDECL(mayberem, (struct obj *, const char *)); 20. # endif 21. #endif /* OVLB */ 22. 23. STATIC_DCL boolean FDECL(diseasemu, (struct permonst *)); 24. STATIC_DCL int FDECL(hitmu, (struct monst *,struct attack *)); 25. STATIC_DCL int FDECL(gulpmu, (struct monst *,struct attack *)); 26. STATIC_DCL int FDECL(explmu, (struct monst *,struct attack *,BOOLEAN_P)); 27. STATIC_DCL void FDECL(missmu,(struct monst *,int,int,struct attack *)); 28. STATIC_DCL void FDECL(mswings,(struct monst *,struct obj *)); 29. STATIC_DCL void FDECL(wildmiss, (struct monst *,struct attack *)); 30. 31. STATIC_DCL void FDECL(hurtarmor,(int)); 32. STATIC_DCL void FDECL(hitmsg,(struct monst *,struct attack *)); 33. 34. /* See comment in mhitm.c. If we use this a lot it probably should be */ 35. /* changed to a parameter to mhitu. */ 36. static int dieroll; 37. 38. #ifdef OVL1 39. 40. STATIC_OVL void 41. hitmsg(mtmp, mattk) 42. register struct monst *mtmp; 43. register struct attack *mattk; 44. { 45. int compat; 46. 47. /* Note: if opposite gender, "seductively" */ 48. /* If same gender, "engagingly" for nymph, normal msg for others */ 49. if((compat = could_seduce(mtmp, &youmonst, mattk)) && !mtmp->mcan && 50. !mtmp->mspec_used) { 51. pline("%s %s you %s.", Monnam(mtmp), Blind ? "talks to" : 52. "smiles at", compat == 2 ? "engagingly" : 53. "seductively"); 54. } else switch (mattk->aatyp) { 55. case AT_CLAW: 56. pline("%s claws you!", Monnam(mtmp)); 57. break; 58. case AT_BITE: 59. pline("%s bites!", Monnam(mtmp)); 60. break; 61. case AT_KICK: 62. pline("%s kicks%c", Monnam(mtmp), 63. thick_skinned(youmonst.data) ? '.' : '!'); 64. break; 65. case AT_STNG: 66. pline("%s stings!", Monnam(mtmp)); 67. break; 68. case AT_BUTT: 69. pline("%s butts!", Monnam(mtmp)); 70. break; 71. case AT_TUCH: 72. pline("%s touches you!", Monnam(mtmp)); 73. break; 74. case AT_TENT: 75. pline("%s tentacles suck you!", 76. s_suffix(Monnam(mtmp))); 77. break; 78. case AT_EXPL: 79. case AT_BOOM: 80. pline("%s explodes!", Monnam(mtmp)); 81. break; 82. case AT_MULTIPLY: 83. /* No message. */ 84. break; 85. default: 86. pline("%s hits!", Monnam(mtmp)); 87. } 88. } 89. 90. 91. STATIC_OVL void 92. missmu(mtmp, target, roll, mattk) /* monster missed you */ 93. register struct monst *mtmp; 94. register int target; 95. register int roll; 96. register struct attack *mattk; 97. { 98. register boolean nearmiss = (target == roll); 99. register struct obj *blocker = (struct obj *)0; 100. /* 3 values for blocker 101. * No blocker: (struct obj *) 0 102. * Piece of armour: object 103. * magical: &zeroobj 104. */ 105. 106. if (target < roll) { 107. /* get object responsible 108. * Work from the closest to the skin outwards 109. */ 110. #ifdef TOURIST 111. /* Try undershirt if tourist */ 112. if (uarmu && target <= roll) { 113. target += ARM_BONUS(uarmu); 114. if (target > roll) blocker = uarmu; 115. } 116. #endif 117. /* Try body armour */ 118. if (uarm && target <= roll) { 119. target += ARM_BONUS(uarm); 120. if (target > roll) blocker = uarm; 121. } 122. 123. if (uarmg && !rn2(10)) { 124. /* Try gloves */ 125. target += ARM_BONUS(uarmg); 126. if (target > roll) blocker = uarmg; 127. } 128. if (uarmf && !rn2(10)) { 129. /* Try boots */ 130. target += ARM_BONUS(uarmf); 131. if (target > roll) blocker = uarmf; 132. } 133. if (uarmh && !rn2(5)) { 134. /* Try helm */ 135. target += ARM_BONUS(uarmh); 136. if (target > roll) blocker = uarmh; 137. } 138. if (uarmc && target <= roll) { 139. /* Try cloak */ 140. target += ARM_BONUS(uarmc); 141. if (target > roll) blocker = uarmc; 142. } 143. if (uarms && target <= roll) { 144. /* Try shield */ 145. target += ARM_BONUS(uarms); 146. if (target > roll) blocker = uarms; 147. } 148. if (target <= roll) { 149. /* Try spell protection */ 150. target += u.uspellprot; 151. if (target > roll) blocker = &zeroobj; 152. } 153. } 154. 155. if (!canspotmon(mtmp)) 156. map_invisible(mtmp->mx, mtmp->my); 157. 158. if(could_seduce(mtmp, &youmonst, mattk) && !mtmp->mcan) 159. pline("%s pretends to be friendly.", Monnam(mtmp)); 160. else { 161. if (!flags.verbose || !nearmiss && !blocker) 162. pline("%s misses.", Monnam(mtmp)); 163. else if (!blocker) 164. pline("%s just misses!", Monnam(mtmp)); 165. else if (blocker == &zeroobj) 166. pline("%s is stopped by the golden haze.", Monnam(mtmp)); 167. else 168. Your("%s %s%s %s attack.", 169. simple_typename(blocker->otyp), 170. rn2(2) ? "block" : "deflect", 171. (blocker == uarmg || blocker == uarmf) ? "" : "s", 172. s_suffix(mon_nam(mtmp))); 173. 174. if (MON_WEP(mtmp)) { 175. struct obj *obj = MON_WEP(mtmp); 176. obj->owornmask &= ~W_WEP; 177. if (rnd(100) < (obj->oeroded * 5 / 2)) { 178. if (obj->spe > -5) { 179. obj->spe--; 180. pline("%s %s is damaged further!", 181. s_suffix(Monnam(mtmp)), xname(obj)); 182. } else 183. pline("%s %s is badly battered!", 184. s_suffix(Monnam(mtmp)), xname(obj)); 185. } 186. } 187. } 188. stop_occupation(); 189. } 190. 191. STATIC_OVL void 192. mswings(mtmp, otemp) /* monster swings obj */ 193. register struct monst *mtmp; 194. register struct obj *otemp; 195. { 196. if (!flags.verbose || Blind || !mon_visible(mtmp)) return; 197. pline("%s %s %s %s.", Monnam(mtmp), 198. (objects[otemp->otyp].oc_dir & PIERCE) ? "thrusts" : "swings", 199. mhis(mtmp), singular(otemp, xname)); 200. } 201. 202. /* return how a poison attack was delivered */ 203. const char * 204. mpoisons_subj(mtmp, mattk) 205. struct monst *mtmp; 206. struct attack *mattk; 207. { 208. if (mattk->aatyp == AT_WEAP) { 209. struct obj *mwep = (mtmp == &youmonst) ? uwep : MON_WEP(mtmp); 210. /* "Foo's attack was poisoned." is pretty lame, but at least 211. it's better than "sting" when not a stinging attack... */ 212. return (!mwep || !mwep->opoisoned) ? "attack" : "weapon"; 213. } else { 214. return (mattk->aatyp == AT_TUCH) ? "contact" : 215. (mattk->aatyp == AT_GAZE) ? "gaze" : 216. (mattk->aatyp == AT_BITE) ? "bite" : "sting"; 217. } 218. } 219. 220. /* called when your intrinsic speed is taken away */ 221. void 222. u_slow_down() 223. { 224. HFast = 0L; 225. if (!Fast) You("slow down."); 226. /* speed boots */ 227. else Your("quickness feels less natural."); 228. exercise(A_DEX, FALSE); 229. } 230. 231. #endif /* OVL1 */ 232. #ifdef OVLB 233. 234. STATIC_OVL void 235. wildmiss(mtmp, mattk) /* monster attacked your displaced image */ 236. register struct monst *mtmp; 237. register struct attack *mattk; 238. { 239. int compat; 240. 241. /* no map_invisible() -- no way to tell where _this_ is coming from */ 242. 243. if (!flags.verbose) return; 244. if (!cansee(mtmp->mx, mtmp->my)) return; 245. /* maybe it's attacking an image around the corner? */ 246. 247. compat = (mattk->adtyp == AD_SEDU || mattk->adtyp == AD_SSEX) && 248. could_seduce(mtmp, &youmonst, (struct attack *)0); 249. 250. if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) { 251. const char *swings = 252. mattk->aatyp == AT_BITE ? "snaps" : 253. mattk->aatyp == AT_KICK ? "kicks" : 254. (mattk->aatyp == AT_STNG || 255. mattk->aatyp == AT_BUTT || 256. nolimbs(mtmp->data)) ? "lunges" : "swings"; 257. 258. if (compat) 259. pline("%s tries to touch you and misses!", Monnam(mtmp)); 260. else 261. switch(rn2(3)) { 262. case 0: pline("%s %s wildly and misses!", Monnam(mtmp), 263. swings); 264. break; 265. case 1: pline("%s attacks a spot beside you.", Monnam(mtmp)); 266. break; 267. case 2: pline("%s strikes at %s!", Monnam(mtmp), 268. levl[mtmp->mux][mtmp->muy].typ == WATER 269. ? "empty water" : "thin air"); 270. break; 271. default:pline("%s %s wildly!", Monnam(mtmp), swings); 272. break; 273. } 274. } else if (Displaced) { 275. if (compat) 276. pline("%s smiles %s at your %sdisplaced image...", 277. Monnam(mtmp), 278. compat == 2 ? "engagingly" : "seductively", 279. Invis ? "invisible " : ""); 280. else 281. pline("%s strikes at your %sdisplaced image and misses you!", 282. /* Note: if you're both invisible and displaced, 283. * only monsters which see invisible will attack your 284. * displaced image, since the displaced image is also 285. * invisible. 286. */ 287. Monnam(mtmp),Invis ? "invisible " : ""); 288. 289. } else if (Underwater) { 290. /* monsters may miss especially on water level where 291. bubbles shake the player here and there */ 292. if (compat) 293. pline("%s reaches towards your distorted image.",Monnam(mtmp)); 294. else 295. pline("%s is fooled by water reflections and misses!",Monnam(mtmp)); 296. 297. } else impossible("%s attacks you without knowing your location?", 298. Monnam(mtmp)); 299. } 300. 301. void 302. expels(mtmp, mdat, message) 303. register struct monst *mtmp; 304. register struct permonst *mdat; /* if mtmp is polymorphed, mdat != mtmp->data */ 305. boolean message; 306. { 307. if (message) { 308. if (is_animal(mdat)) 309. You("get regurgitated!"); 310. else { 311. char blast[40]; 312. register int i; 313. 314. blast[0] = '\0'; 315. for(i = 0; i < NATTK; i++) 316. if(mdat->mattk[i].aatyp == AT_ENGL) 317. break; 318. if (mdat->mattk[i].aatyp != AT_ENGL) 319. impossible("Swallower has no engulfing attack?"); 320. else { 321. if (is_whirly(mdat)) { 322. switch (mdat->mattk[i].adtyp) { 323. case AD_ELEC: 324. Strcpy(blast, 325. " in a shower of sparks"); 326. break; 327. case AD_COLD: 328. Strcpy(blast, 329. " in a blast of frost"); 330. break; 331. } 332. } else 333. Strcpy(blast, " with a squelch"); 334. You("get expelled from %s%s!",mon_nam(mtmp), blast); 335. } 336. } 337. } 338. unstuck(mtmp); /* ball&chain returned in unstuck() */ 339. mnexto(mtmp); 340. newsym(u.ux,u.uy); 341. spoteffects(TRUE); 342. /* to cover for a case where mtmp is not in a next square */ 343. if(um_dist(mtmp->mx,mtmp->my,1)) 344. pline("Brrooaa... You land hard at some distance."); 345. } 346. 347. #endif /* OVLB */ 348. #ifdef OVL0 349. 350. /* select a monster's next attack, possibly substituting for its usual one */ 351. struct attack * 352. getmattk(mptr, indx, prev_result, alt_attk_buf) 353. struct permonst *mptr; 354. int indx, prev_result[]; 355. struct attack *alt_attk_buf; 356. { 357. struct attack *attk = &mptr->mattk[indx]; 358. 359. /* prevent a monster with two consecutive disease or hunger attacks 360. from hitting with both of them on the same turn; if the first has 361. already hit, switch to a stun attack for the second */ 362. if (indx > 0 && prev_result[indx - 1] > 0 && 363. (attk->adtyp == AD_DISE || 364. attk->adtyp == AD_PEST || 365. attk->adtyp == AD_FAMN) && 366. attk->adtyp == mptr->mattk[indx - 1].adtyp) { 367. *alt_attk_buf = *attk; 368. attk = alt_attk_buf; 369. attk->adtyp = AD_STUN; 370. } 371. return attk; 372. } 373. 374. /* Intelligent monsters try and avoid "blue on blue" incidents. 375. */ 376. STATIC_OVL int 377. blue_on_blue(mtmp) 378. struct monst *mtmp; 379. { 380. int x, y; 381. struct monst *mon; 382. if (!mtmp->mconf && !Conflict && !mtmp->mflee && !mindless(mtmp->data)) { 383. if (!lined_up(mtmp)) 384. return FALSE; /* Irrelevant; monster won't attack anyway */ 385. x = mtmp->mx + sgn(tbx); 386. y = mtmp->my + sgn(tby); 387. while(x != mtmp->mux || y != mtmp->muy) { 388. mon = m_at(x, y); 389. if (mon && m_cansee(mtmp, x, y) && !mon->mundetected && 390. (!mon->minvis || perceives(mtmp->data))) 391. return TRUE; 392. x += sgn(tbx); 393. y += sgn(tby); 394. } 395. } 396. return FALSE; 397. } 398. 399. /* 400. * mattacku: monster attacks you 401. * returns 1 if monster dies (e.g. "yellow light"), 0 otherwise 402. * Note: if you're displaced or invisible the monster might attack the 403. * wrong position... 404. * Assumption: it's attacking you or an empty square; if there's another 405. * monster which it attacks by mistake, the caller had better 406. * take care of it... 407. */ 408. int 409. mattacku(mtmp) 410. register struct monst *mtmp; 411. { 412. struct attack *mattk, alt_attk; 413. int i, j, tmp, sum[NATTK]; 414. struct permonst *mdat = mtmp->data; 415. boolean ranged = (distu(mtmp->mx, mtmp->my) > 3); 416. /* Is it near you? Affects your actions */ 417. boolean range2 = !monnear(mtmp, mtmp->mux, mtmp->muy); 418. /* Does it think it's near you? Affects its actions */ 419. boolean foundyou = (mtmp->mux==u.ux && mtmp->muy==u.uy); 420. /* Is it attacking you or your image? */ 421. boolean youseeit = canseemon(mtmp); 422. /* Might be attacking your image around the corner, or 423. * invisible, or you might be blind.... 424. */ 425. 426. if(!ranged) nomul(0); 427. if(mtmp->mhp <= 0 || (Underwater && !is_swimmer(mtmp->data))) 428. return(0); 429. 430. /* If swallowed, can only be affected by u.ustuck */ 431. if(u.uswallow) { 432. if(mtmp != u.ustuck) return(0); 433. u.ustuck->mux = u.ux; 434. u.ustuck->muy = u.uy; 435. range2 = 0; 436. foundyou = 1; 437. if(u.uinvulnerable) return (0); /* stomachs can't hurt you! */ 438. } 439. 440. #ifdef STEED 441. else if (u.usteed) { 442. if (mtmp == u.usteed) 443. /* Your steed won't attack you */ 444. return (0); 445. /* Orcs like to steal and eat horses and the like */ 446. if (!rn2(is_orc(mtmp->data) ? 2 : 4) && 447. distu(mtmp->mx, mtmp->my) <= 2) { 448. /* Attack your steed instead */ 449. i = mattackm(mtmp, u.usteed); 450. if ((i & MM_AGR_DIED)) 451. return (1); 452. if (i & MM_DEF_DIED || u.umoved) 453. return (0); 454. /* Let your steed retaliate */ 455. return (!!(mattackm(u.usteed, mtmp) & MM_DEF_DIED)); 456. } 457. } 458. #endif 459. 460. if (u.uundetected && !range2 && foundyou && !u.uswallow) { 461. u.uundetected = 0; 462. if (is_hider(youmonst.data)) { 463. coord cc; /* maybe we need a unexto() function? */ 464. struct obj *obj; 465. 466. You("fall from the %s!", ceiling(u.ux,u.uy)); 467. if (enexto(&cc, u.ux, u.uy, youmonst.data)) { 468. remove_monster(mtmp->mx, mtmp->my); 469. newsym(mtmp->mx,mtmp->my); 470. place_monster(mtmp, u.ux, u.uy); 471. if(mtmp->wormno) worm_move(mtmp); 472. teleds(cc.x, cc.y, TRUE); 473. set_apparxy(mtmp); 474. newsym(u.ux,u.uy); 475. } else { 476. pline("%s is killed by a falling %s (you)!", 477. Monnam(mtmp), youmonst.data->mname); 478. killed(mtmp); 479. newsym(u.ux,u.uy); 480. if (mtmp->mhp > 0) return 0; 481. else return 1; 482. } 483. if (youmonst.data->mlet != S_PIERCER) 484. return(0); /* trappers don't attack */ 485. 486. obj = which_armor(mtmp, WORN_HELMET); 487. if (obj && is_metallic(obj)) { 488. Your("blow glances off %s helmet.", 489. s_suffix(mon_nam(mtmp))); 490. } else { 491. if (3 + find_mac(mtmp) <= rnd(20)) { 492. pline("%s is hit by a falling piercer (you)!", 493. Monnam(mtmp)); 494. if ((mtmp->mhp -= d(3,6)) < 1) 495. killed(mtmp); 496. } else 497. pline("%s is almost hit by a falling piercer (you)!", 498. Monnam(mtmp)); 499. } 500. } else { 501. if (!youseeit) 502. pline("It tries to move where you are hiding."); 503. else { 504. /* Ugly kludge for eggs. The message is phrased so as 505. * to be directed at the monster, not the player, 506. * which makes "laid by you" wrong. For the 507. * parallelism to work, we can't rephrase it, so we 508. * zap the "laid by you" momentarily instead. 509. */ 510. struct obj *obj = level.objects[u.ux][u.uy]; 511. 512. if (obj || 513. (youmonst.data->mlet == S_EEL && is_pool(u.ux, u.uy))) { 514. int save_spe = 0; /* suppress warning */ 515. if (obj) { 516. save_spe = obj->spe; 517. if (obj->otyp == EGG) obj->spe = 0; 518. } 519. if (youmonst.data->mlet == S_EEL) 520. pline("Wait, %s! There's a hidden %s named %s there!", 521. m_monnam(mtmp), youmonst.data->mname, plname); 522. else 523. pline("Wait, %s! There's a %s named %s hiding under %s!", 524. m_monnam(mtmp), youmonst.data->mname, plname, 525. doname(level.objects[u.ux][u.uy])); 526. if (obj) obj->spe = save_spe; 527. } else 528. impossible("hiding under nothing?"); 529. } 530. newsym(u.ux,u.uy); 531. } 532. return(0); 533. } 534. if (youmonst.data->mlet == S_MIMIC && youmonst.m_ap_type && 535. !range2 && foundyou && !u.uswallow) { 536. if (!youseeit) pline("It gets stuck on you."); 537. else pline("Wait, %s! That's a %s named %s!", 538. m_monnam(mtmp), youmonst.data->mname, plname); 539. setustuck(mtmp); 540. youmonst.m_ap_type = M_AP_NOTHING; 541. youmonst.mappearance = 0; 542. newsym(u.ux,u.uy); 543. return(0); 544. } 545. 546. /* player might be mimicking an object */ 547. if (youmonst.m_ap_type == M_AP_OBJECT && !range2 && foundyou && !u.uswallow) { 548. if (!youseeit) 549. pline("%s %s!", Something, 550. (likes_gold(mtmp->data) && youmonst.mappearance == GOLD_PIECE) ? 551. "tries to pick you up" : "disturbs you"); 552. else pline("Wait, %s! That %s is really %s named %s!", 553. m_monnam(mtmp), 554. mimic_obj_name(&youmonst), 555. an(mons[u.umonnum].mname), 556. plname); 557. if (multi < 0) { /* this should always be the case */ 558. char buf[BUFSZ]; 559. Sprintf(buf, "You appear to be %s again.", 560. Upolyd ? (const char *) an(youmonst.data->mname) : 561. (const char *) "yourself"); 562. unmul(buf); /* immediately stop mimicking */ 563. } 564. return 0; 565. } 566. 567. /* Work out the armor class differential */ 568. tmp = AC_VALUE(u.uac) + 10; /* tmp ~= 0 - 20 */ 569. tmp += mtmp->m_lev; 570. if(multi < 0) tmp += 4; 571. if((Invis && !perceives(mdat)) || !mtmp->mcansee) tmp -= 2; 572. if(mtmp->mtrapped) tmp -= 2; 573. if(tmp <= 0) tmp = 1; 574. 575. /* make eels visible the moment they hit/miss us */ 576. if(mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx,mtmp->my)) { 577. mtmp->minvis = 0; 578. newsym(mtmp->mx,mtmp->my); 579. } 580. 581. /* Make Star Vampires visible the moment they hit/miss us */ 582. if(mtmp->data == &mons[PM_STAR_VAMPIRE] && mtmp->minvis 583. && cansee(mtmp->mx, mtmp->my)) { 584. mtmp->minvis = 0; 585. newsym(mtmp->mx, mtmp->my); 586. } 587. 588. /* Special demon handling code */ 589. if(!mtmp->cham && is_demon(mdat) && !range2 590. && mtmp->data != &mons[PM_BALROG] 591. && mtmp->data != &mons[PM_SUCCUBUS] 592. && mtmp->data != &mons[PM_INCUBUS]) 593. if(!mtmp->mcan && !rn2(13)) msummon(mtmp); 594. 595. /* Special lycanthrope handling code */ 596. if(!mtmp->cham && is_were(mdat) && !range2) { 597. if(is_human(mdat)) { 598. if(!rn2(5 - (night() * 2)) && !mtmp->mcan) new_were(mtmp); 599. } else if(!rn2(30) && !mtmp->mcan) new_were(mtmp); 600. mdat = mtmp->data; 601. 602. if(!rn2(4) && !mtmp->mcan) { 603. int numseen, numhelp; 604. char buf[BUFSZ], genericwere[BUFSZ]; 605. 606. Strcpy(genericwere, "creature"); 607. numhelp = were_summon(mdat, FALSE, &numseen, genericwere); 608. if (youseeit) { 609. pline("%s summons help!", Monnam(mtmp)); 610. if (numhelp > 0) { 611. if (numseen == 0) 612. You_feel("hemmed in."); 613. } else pline("But none comes."); 614. } else { 615. const char *from_nowhere; 616. 617. if (flags.soundok) { 618. pline("%s %s!", Something, 619. makeplural(growl_sound(mtmp))); 620. from_nowhere = ""; 621. } else from_nowhere = " from nowhere"; 622. if (numhelp > 0) { 623. if (numseen < 1) You_feel("hemmed in."); 624. else { 625. if (numseen == 1) 626. Sprintf(buf, "%s appears", 627. an(genericwere)); 628. else 629. Sprintf(buf, "%s appear", 630. makeplural(genericwere)); 631. pline("%s%s!", upstart(buf), from_nowhere); 632. } 633. } /* else no help came; but you didn't know it tried */ 634. } 635. } 636. } 637. 638. if(u.uinvulnerable) { 639. /* monsters won't attack you */ 640. if(mtmp == u.ustuck) 641. pline("%s loosens its grip slightly.", Monnam(mtmp)); 642. else if(!range2) { 643. if (youseeit || sensemon(mtmp)) 644. pline("%s starts to attack you, but pulls back.", 645. Monnam(mtmp)); 646. else 647. You_feel("%s move nearby.", something); 648. } 649. return (0); 650. } 651. 652. /* Unlike defensive stuff, don't let them use item _and_ attack. */ 653. if(!blue_on_blue(mtmp) && find_offensive(mtmp)) { 654. int foo = use_offensive(mtmp); 655. 656. if (foo != 0) return(foo==1); 657. } 658. 659. for(i = 0; i < NATTK; i++) { 660. 661. sum[i] = 0; 662. mattk = getmattk(mdat, i, sum, &alt_attk); 663. if (u.uswallow && (mattk->aatyp != AT_ENGL)) 664. continue; 665. switch(mattk->aatyp) { 666. case AT_CLAW: /* "hand to hand" attacks */ 667. case AT_KICK: 668. case AT_BITE: 669. case AT_STNG: 670. case AT_TUCH: 671. case AT_BUTT: 672. case AT_TENT: 673. if(!range2 && (!MON_WEP(mtmp) || mtmp->mconf || Conflict || 674. !touch_petrifies(youmonst.data))) { 675. if (foundyou) { 676. if(tmp > (j = rnd(20+i))) { 677. if (mattk->aatyp != AT_KICK || 678. !thick_skinned(youmonst.data)) 679. sum[i] = hitmu(mtmp, mattk); 680. } else 681. missmu(mtmp, tmp, j, mattk); 682. } else wildmiss(mtmp, mattk); 683. } 684. break; 685. case AT_HUGS: /* automatic if prev two attacks succeed */ 686. /* Note: if displaced, prev attacks never succeeded */ 687. if((!range2 && i>=2 && sum[i-1] && sum[i-2]) || mtmp == u.ustuck) 688. sum[i]= hitmu(mtmp, mattk); 689. break; 690. case AT_GAZE: /* can affect you either ranged or not */ 691. /* Medusa gaze already operated through m_respond in 692. * dochug(); don't gaze more than once per round. 693. */ 694. if (mdat != &mons[PM_MEDUSA]) 695. sum[i] = gazemu(mtmp, mattk); 696. break; 697. case AT_EXPL: /* automatic hit if next to, and aimed at you */ 698. if(!range2) sum[i] = explmu(mtmp, mattk, foundyou); 699. break; 700. case AT_ENGL: 701. if (!range2) { 702. if(foundyou) { 703. if(u.uswallow || tmp > (j = rnd(20+i))) { 704. /* Force swallowing monster to be 705. * displayed even when player is 706. * moving away */ 707. flush_screen(1); 708. sum[i] = gulpmu(mtmp, mattk); 709. } else { 710. missmu(mtmp, tmp, j, mattk); 711. } 712. } else if (is_animal(mtmp->data)) { 713. pline("%s gulps some air!", Monnam(mtmp)); 714. } else { 715. if (youseeit) 716. pline("%s lunges forward and recoils!", 717. Monnam(mtmp)); 718. else 719. You_hear("a %s nearby.", 720. is_whirly(mtmp->data) ? 721. "rushing noise" : "splat"); 722. } 723. } 724. break; 725. case AT_BREA: 726. if (range2 && !blue_on_blue(mtmp)) 727. sum[i] = breamu(mtmp, mattk); 728. /* Note: breamu takes care of displacement */ 729. break; 730. case AT_SPIT: 731. if (range2 && !blue_on_blue(mtmp)) 732. sum[i] = spitmu(mtmp, mattk); 733. /* Note: spitmu takes care of displacement */ 734. break; 735. case AT_MULTIPLY: 736. /* 737. * Monster multiplying is an AT_ for the following 738. * reasons: 739. * 1. Monsters will only multiply when they're close 740. * to you. The whole level will not become clogged 741. * up with giant lice from monsters multiplying 742. * where you can't see them. 743. * 2. Tame monsters won't multiply. Too bad! (unless 744. * they are conflicted or confused from hunger. 745. * A bit of a "tactic" -- but then you'll have to 746. * let them bite you, and anyway who really wants 747. * a dozen pet fleas to feed?) 748. * 3. Monsters have to be next to you to multiply. 749. * This makes the inevitable altar abuse a little 750. * harder. 751. * 4. Elbereth will stop monsters multiplying. 752. * Otherwise a ring of conflict would crowd out a 753. * whole level in no time. 754. * 5. It is a hack. (Shrug) 755. * 756. * Multiplying monsters must be low-level and 757. * low-frequency, so as to minimise altar/experience 758. * abuse. Any multiplying monsters above about 759. * level 5 should be G_NOCORPSE. 760. * 761. * RJ 762. */ 763. if (!range2) 764. clone_mon(mtmp, 0, 0); 765. break; 766. case AT_WEAP: 767. if(range2) { 768. #ifdef REINCARNATION 769. if (!Is_rogue_level(&u.uz)) 770. #endif 771. if (!blue_on_blue(mtmp)) 772. thrwmu(mtmp); 773. } else { 774. int hittmp = 0; 775. 776. /* Rare but not impossible. Normally the monster 777. * wields when 2 spaces away, but it can be 778. * teleported or whatever.... 779. */ 780. if (mtmp->weapon_check == NEED_WEAPON || !MON_WEP(mtmp)) { 781. mtmp->weapon_check = NEED_HTH_WEAPON; 782. /* mon_wield_item resets weapon_check as 783. * appropriate */ 784. if (mon_wield_item(mtmp) != 0) break; 785. } 786. if (foundyou) { 787. otmp = MON_WEP(mtmp); 788. if (otmp) { 789. hittmp = hitval(otmp, &youmonst); 790. tmp += hittmp; 791. mswings(mtmp, otmp); 792. } 793. if(tmp > (j = dieroll = rnd(20+i))) 794. sum[i] = hitmu(mtmp, mattk); 795. else 796. missmu(mtmp, tmp , j, mattk); 797. /* KMH -- Don't accumulate to-hit bonuses */ 798. if (otmp) 799. tmp -= hittmp; 800. } else wildmiss(mtmp, mattk); 801. } 802. break; 803. case AT_MAGC: 804. if (range2) { 805. if (!blue_on_blue(mtmp)) 806. sum[i] = buzzmu(mtmp, mattk); 807. } else { 808. if (foundyou) 809. sum[i] = castmu(mtmp, mattk, TRUE, TRUE); 810. else 811. sum[i] = castmu(mtmp, mattk, TRUE, FALSE); 812. } 813. break; 814. 815. default: /* no attack */ 816. break; 817. } 818. if(flags.botl) bot(); 819. /* give player a chance of waking up before dying -kaa */ 820. if(sum[i] == 1) { /* successful attack */ 821. if (u.usleep && u.usleep < monstermoves && !rn2(10)) { 822. multi = -1; 823. nomovemsg = "The combat suddenly awakens you."; 824. } 825. } 826. if(sum[i] == 2) return 1; /* attacker dead */ 827. if(sum[i] == 3) break; /* attacker teleported, no more attacks */ 828. /* sum[i] == 0: unsuccessful attack */ 829. } 830. return(0); 831. } 832. 833. #endif /* OVL0 */ 834. #ifdef OVLB 835. 836. /* 837. * helper function for some compilers that have trouble with hitmu 838. */ 839. 840. STATIC_OVL void 841. hurtarmor(attk) 842. int attk; 843. { 844. int hurt; 845. 846. switch(attk) { 847. /* 0 is burning, which we should never be called with */ 848. case AD_RUST: hurt = 1; break; 849. case AD_CORR: hurt = 3; break; 850. default: hurt = 2; break; 851. } 852. 853. /* What the following code does: it keeps looping until it 854. * finds a target for the rust monster. 855. * Head, feet, etc... not covered by metal, or covered by 856. * rusty metal, are not targets. However, your body always 857. * is, no matter what covers it. 858. * 859. * WAC fixed code so that it keeps looping until it either hits 860. * your body or finds a rustable item 861. * changed the last parm of !rust_dmg for non-body targets to FALSE 862. */ 863. while (1) { 864. switch(rn2(5)) { 865. case 0: 866. if (!uarmh || !rust_dmg(uarmh, xname(uarmh), hurt, FALSE, &youmonst)) 867. continue; 868. break; 869. case 1: 870. if (uarmc) { 871. (void)rust_dmg(uarmc, xname(uarmc), hurt, TRUE, &youmonst); 872. break; 873. } 874. /* Note the difference between break and continue; 875. * break means it was hit and didn't rust; continue 876. * means it wasn't a target and though it didn't rust 877. * something else did. 878. */ 879. if (uarm) 880. (void)rust_dmg(uarm, xname(uarm), hurt, TRUE, &youmonst); 881. #ifdef TOURIST 882. else if (uarmu) 883. (void)rust_dmg(uarmu, xname(uarmu), hurt, TRUE, &youmonst); 884. #endif 885. break; 886. case 2: 887. if (!uarms || !rust_dmg(uarms, xname(uarms), hurt, FALSE, &youmonst)) 888. continue; 889. break; 890. case 3: 891. if (!uarmg || !rust_dmg(uarmg, xname(uarmg), hurt, FALSE, &youmonst)) 892. continue; 893. break; 894. case 4: 895. if (!uarmf || !rust_dmg(uarmf, xname(uarmf), hurt, FALSE, &youmonst)) 896. continue; 897. break; 898. } 899. 900. break; /* Out of while loop */ 901. } 902. } 903. 904. #endif /* OVLB */ 905. #ifdef OVL1 906. 907. STATIC_OVL boolean 908. diseasemu(mdat) 909. struct permonst *mdat; 910. { 911. if (Sick_resistance) { 912. You_feel("a slight illness."); 913. return FALSE; 914. } else { 915. make_sick(Sick ? Sick/3L + 1L : (long)rn1(ACURR(A_CON), 20), 916. mdat->mname, TRUE, SICK_NONVOMITABLE); 917. return TRUE; 918. } 919. } 920. 921. /* check whether slippery clothing protects from hug or wrap attack */ 922. STATIC_OVL boolean 923. u_slip_free(mtmp, mattk) 924. struct monst *mtmp; 925. struct attack *mattk; 926. { 927. struct obj *obj = (uarmc ? uarmc : uarm); 928. 929. #ifdef TOURIST 930. if (!obj) obj = uarmu; 931. #endif 932. if (mattk->adtyp == AD_DRIN) obj = uarmh; 933. 934. /* if your cloak/armor is greased, monster slips off; this 935. protection might fail (33% chance) when the armor is cursed */ 936. if (obj && (obj->greased || obj->otyp == OILSKIN_CLOAK) && 937. (!obj->cursed || rn2(3))) { 938. pline("%s %s your %s %s!", 939. Monnam(mtmp), 940. (mattk->adtyp == AD_WRAP) ? 941. "slips off of" : "grabs you, but cannot hold onto", 942. obj->greased ? "greased" : "slippery", 943. /* avoid "slippery slippery cloak" 944. for undiscovered oilskin cloak */ 945. (obj->greased || objects[obj->otyp].oc_name_known) ? 946. xname(obj) : cloak_simple_name(obj)); 947. 948. if (obj->greased && !rn2(2)) { 949. pline_The("grease wears off."); 950. obj->greased = 0; 951. update_inventory(); 952. } 953. return TRUE; 954. /* 50% chance (with a luck bonus) of slipping free with free action */ 955. } else if (Free_action && (rnl(10) < 5)) { 956. pline("%s %s you, but you quickly free yourself!", 957. Monnam(mtmp), 958. (mattk->adtyp == AD_WRAP) ? 959. "swings itself around of" : "grabs"); 960. return TRUE; 961. } 962. return FALSE; 963. } 964. 965. /* armor that sufficiently covers the body might be able to block magic */ 966. int 967. magic_negation(mon) 968. struct monst *mon; 969. { 970. struct obj *armor; 971. int armpro = 0; 972. 973. armor = (mon == &youmonst) ? uarm : which_armor(mon, W_ARM); 974. if (armor && armpro < objects[armor->otyp].a_can) 975. armpro = objects[armor->otyp].a_can; 976. armor = (mon == &youmonst) ? uarmc : which_armor(mon, W_ARMC); 977. if (armor && armpro < objects[armor->otyp].a_can) 978. armpro = objects[armor->otyp].a_can; 979. armor = (mon == &youmonst) ? uarmh : which_armor(mon, W_ARMH); 980. if (armor && armpro < objects[armor->otyp].a_can) 981. armpro = objects[armor->otyp].a_can; 982. 983. /* armor types for shirt, gloves, shoes, and shield don't currently 984. provide any magic cancellation but we might as well be complete */ 985. #ifdef TOURIST 986. armor = (mon == &youmonst) ? uarmu : which_armor(mon, W_ARMU); 987. if (armor && armpro < objects[armor->otyp].a_can) 988. armpro = objects[armor->otyp].a_can; 989. #endif 990. armor = (mon == &youmonst) ? uarmg : which_armor(mon, W_ARMG); 991. if (armor && armpro < objects[armor->otyp].a_can) 992. armpro = objects[armor->otyp].a_can; 993. armor = (mon == &youmonst) ? uarmf : which_armor(mon, W_ARMF); 994. if (armor && armpro < objects[armor->otyp].a_can) 995. armpro = objects[armor->otyp].a_can; 996. armor = (mon == &youmonst) ? uarms : which_armor(mon, W_ARMS); 997. if (armor && armpro < objects[armor->otyp].a_can) 998. armpro = objects[armor->otyp].a_can; 999. 1000. #ifdef STEED 1001. /* this one is really a stretch... */ 1002. armor = (mon == &youmonst) ? 0 : which_armor(mon, W_SADDLE); 1003. if (armor && armpro < objects[armor->otyp].a_can) 1004. armpro = objects[armor->otyp].a_can; 1005. #endif 1006. 1007. return armpro; 1008. } 1009. 1010. /* 1011. * hitmu: monster hits you 1012. * returns 2 if monster dies (e.g. "yellow light"), 1 otherwise 1013. * 3 if the monster lives but teleported/paralyzed, so it can't keep 1014. * attacking you 1015. */ 1016. STATIC_OVL int 1017. hitmu(mtmp, mattk) 1018. register struct monst *mtmp; 1019. register struct attack *mattk; 1020. { 1021. register struct permonst *mdat = mtmp->data; 1022. register int uncancelled, ptmp; 1023. int dmg, armpro, permdmg; 1024. char buf[BUFSZ]; 1025. struct permonst *olduasmon = youmonst.data; 1026. int res; 1027. boolean burnmsg = FALSE; 1028. 1029. if (!canspotmon(mtmp)) 1030. map_invisible(mtmp->mx, mtmp->my); 1031. 1032. /* If the monster is undetected & hits you, you should know where 1033. * the attack came from. 1034. */ 1035. if(mtmp->mundetected && (hides_under(mdat) || mdat->mlet == S_EEL)) { 1036. mtmp->mundetected = 0; 1037. if (!(Blind ? Blind_telepat : Unblind_telepat)) { 1038. struct obj *obj; 1039. const char *what; 1040. 1041. if ((obj = level.objects[mtmp->mx][mtmp->my]) != 0) { 1042. if (Blind && !obj->dknown) 1043. what = something; 1044. else if (is_pool(mtmp->mx, mtmp->my) && !Underwater) 1045. what = "the water"; 1046. else 1047. what = doname(obj); 1048. 1049. pline("%s was hidden under %s!", Amonnam(mtmp), what); 1050. } 1051. newsym(mtmp->mx, mtmp->my); 1052. } 1053. } 1054. 1055. /* First determine the base damage done */ 1056. dmg = d((int)mattk->damn, (int)mattk->damd); 1057. if(is_undead(mdat) && midnight()) 1058. dmg += d((int)mattk->damn, (int)mattk->damd); /* extra damage */ 1059. /* Next a cancellation factor */ 1060. 1061. /* Use uncancelled when the cancellation factor takes into account certain 1062. * armor's special magic protection. Otherwise just use !mtmp->mcan. 1063. */ 1064. armpro = magic_negation(&youmonst); 1065. uncancelled = !mtmp->mcan && ((rn2(3) >= armpro) || !rn2(50)); 1066. 1067. permdmg = 0; 1068. /* Now, adjust damages via resistances or specific attacks */ 1069. switch(mattk->adtyp) { 1070. case AD_PHYS: 1071. if (mattk->aatyp == AT_HUGS && !sticks(youmonst.data)) { 1072. if(!u.ustuck && rn2(2)) { 1073. if (u_slip_free(mtmp, mattk)) { 1074. dmg = 0; 1075. } else { 1076. setustuck(mtmp); 1077. pline("%s grabs you!", Monnam(mtmp)); 1078. } 1079. } else if(u.ustuck == mtmp) { 1080. exercise(A_STR, FALSE); 1081. if (mtmp->data == &mons[PM_ROPE_GOLEM] && Breathless) { 1082. You("are being strangled."); 1083. dmg = (dmg+1) / 2; 1084. } else 1085. You("are being %s.", 1086. (mtmp->data == &mons[PM_ROPE_GOLEM]) 1087. ? "choked" : "crushed"); 1088. } 1089. } else { /* hand to hand weapon */ 1090. if(mattk->aatyp == AT_WEAP && otmp) { 1091. int nopoison = (10 - (otmp->owt/10)); 1092. if (otmp->otyp == CORPSE && 1093. touch_petrifies(&mons[otmp->corpsenm])) { 1094. dmg = 1; 1095. pline("%s hits you with the %s corpse.", 1096. Monnam(mtmp), mons[otmp->corpsenm].mname); 1097. if (!Stoned) goto do_stone; 1098. } 1099. 1100. /* MRKR: If hit with a burning torch, */ 1101. /* then do an extra point of damage */ 1102. /* but save the message till after */ 1103. /* the hitmsg() */ 1104. 1105. if (otmp->otyp == TORCH && otmp->lamplit && 1106. !Fire_resistance) { 1107. burnmsg = TRUE; 1108. dmg++; 1109. } 1110. 1111. /* WAC -- Real weapon? 1112. * Could be stuck with a cursed bow/polearm it wielded 1113. */ 1114. if (/* if you strike with a bow... */ 1115. is_launcher(otmp) || 1116. /* or strike with a missile in your hand... */ 1117. (is_missile(otmp) || is_ammo(otmp)) || 1118. #ifdef LIGHTSABERS 1119. /* lightsaber that isn't lit ;) */ 1120. (is_lightsaber(otmp) && !otmp->lamplit) || 1121. #endif 1122. /* WAC -- or using a pole at short range... */ 1123. (is_pole(otmp))) { 1124. /* then do only 1-2 points of damage */ 1125. if (u.umonnum == PM_SHADE && otmp->otyp != SILVER_ARROW) 1126. dmg = 0; 1127. else 1128. dmg = rnd(2); 1129. 1130. #if 0 /* Monsters don't wield boomerangs */ 1131. if (otmp->otyp == BOOMERANG /* && !rnl(3) */) { 1132. pline("As %s hits you, %s breaks into splinters.", 1133. mon_nam(mtmp), the(xname(otmp))); 1134. useup(otmp); 1135. otmp = (struct obj *) 0; 1136. possibly_unwield(mtmp); 1137. if (u.umonnum != PM_SHADE) 1138. dmg++; 1139. } 1140. #endif 1141. } else dmg += dmgval(otmp, &youmonst); 1142. 1143. if (objects[otmp->otyp].oc_material == SILVER && 1144. hates_silver(youmonst.data)) { 1145. pline("The silver sears your flesh!"); 1146. } 1147. /* Stakes do extra dmg agains vamps */ 1148. if (otmp->otyp == WOODEN_STAKE && 1149. is_vampire(youmonst.data)) { 1150. if (otmp->oartifact == ART_STAKE_OF_VAN_HELSING) { 1151. if (!rn2(10)) { 1152. pline("%s plunges the stake into your heart.", 1153. Monnam(mtmp)); 1154. killer = "a wooden stake in the heart."; 1155. killer_format = KILLED_BY_AN; 1156. u.ugrave_arise = NON_PM; /* No corpse */ 1157. done(DIED); 1158. } else { 1159. pline("%s drives the stake into you.", 1160. Monnam(mtmp)); 1161. dmg += rnd(6) + 2; 1162. } 1163. } else { 1164. pline("%s drives the stake into you.", 1165. Monnam(mtmp)); 1166. dmg += rnd(6); 1167. } 1168. } 1169. 1170. if (otmp->opoisoned) { 1171. poisoned(obj_typename(otmp->otyp), A_STR, 1172. killer_xname(otmp), 10); 1173. if (nopoison < 2) nopoison = 2; 1174. if (!rn2(nopoison)) { 1175. otmp->opoisoned = FALSE; 1176. pline("%s %s no longer poisoned.", 1177. s_suffix(Monnam(mtmp)), 1178. aobjnam(otmp, "are")); 1179. } 1180. } 1181. if (dmg <= 0) dmg = 1; 1182. if (!otmp->oartifact || !artifact_hit(mtmp, &youmonst, 1183. otmp, &dmg, dieroll)) 1184. hitmsg(mtmp, mattk); 1185. 1186. if (burnmsg) { 1187. boolean plural = (Blind ? FALSE : otmp->quan > 1L); 1188. boolean water = (youmonst.data == 1189. &mons[PM_WATER_ELEMENTAL]); 1190. 1191. pline("%s %s%s %syou!", 1192. (Blind ? "It" : Yname2(otmp)), 1193. (water ? "vaporize" : "burn"), 1194. (plural ? "" : "s"), 1195. (water ? "part of " : "")); 1196. 1197. if (!rn2(2) && burnarmor(&youmonst)) { 1198. dmg++; 1199. 1200. /* Torch flame is not hot enough to guarantee */ 1201. /* burning away slime */ 1202. 1203. if (!rn2(4)) burn_away_slime(); 1204. if (!rn2(3)) 1205. (void)destroy_item(POTION_CLASS, AD_FIRE); 1206. if (!rn2(3)) 1207. (void)destroy_item(SCROLL_CLASS, AD_FIRE); 1208. if (!rn2(5)) 1209. (void)destroy_item(SPBOOK_CLASS, AD_FIRE); 1210. } 1211. burn_faster(otmp, 1); 1212. } 1213. 1214. if (!dmg) break; 1215. if (u.mh > 1 && u.mh > ((u.uac>0) ? dmg : dmg+u.uac) && 1216. objects[otmp->otyp].oc_material == IRON && 1217. (u.umonnum==PM_BLACK_PUDDING 1218. || u.umonnum==PM_BROWN_PUDDING)) { 1219. /* This redundancy necessary because you have to 1220. * take the damage _before_ being cloned. 1221. */ 1222. if (u.uac < 0) dmg += u.uac; 1223. if (dmg < 1) dmg = 1; 1224. if (dmg > 1) exercise(A_STR, FALSE); 1225. u.mh -= dmg; 1226. flags.botl = 1; 1227. dmg = 0; 1228. if(cloneu()) 1229. You("divide as %s hits you!",mon_nam(mtmp)); 1230. } 1231. urustm(mtmp, otmp); 1232. } else if (mattk->aatyp != AT_TUCH || dmg != 0 || 1233. mtmp != u.ustuck) 1234. hitmsg(mtmp, mattk); 1235. } 1236. break; 1237. case AD_DISE: 1238. hitmsg(mtmp, mattk); 1239. if (!diseasemu(mdat) || Invulnerable) dmg = 0; 1240. break; 1241. case AD_FIRE: 1242. hitmsg(mtmp, mattk); 1243. if (uncancelled) { 1244. pline("You're %s!", on_fire(youmonst.data, mattk)); 1245. if (youmonst.data == &mons[PM_STRAW_GOLEM] || 1246. youmonst.data == &mons[PM_PAPER_GOLEM]) { 1247. You("roast!"); 1248. /* KMH -- this is okay with unchanging */ 1249. rehumanize(); 1250. break; 1251. } else if (Fire_resistance) { 1252. pline_The("fire doesn't feel hot!"); 1253. dmg = 0; 1254. } else if (u.umonnum == PM_STRAW_GOLEM || 1255. u.umonnum == PM_PAPER_GOLEM || 1256. u.umonnum == PM_WAX_GOLEM) { 1257. /* This code ASSUMES that you are polymorphed 1258. * Code will need to be changed if we ever implement 1259. * Golems as a class. 1260. */ 1261. You("burn up!"); 1262. u.uhp -= mons[u.umonnum].mlevel; 1263. u.uhpmax -= mons[u.umonnum].mlevel; 1264. if (u.uhpmax < 1) u.uhpmax = 1; 1265. /* KMH, balance patch -- this is okay with unchanging */ 1266. u.mh = 0; /* Kill monster form */ 1267. rehumanize(); 1268. break; 1269. } 1270. if((int) mtmp->m_lev > rn2(20)) 1271. destroy_item(SCROLL_CLASS, AD_FIRE); 1272. if((int) mtmp->m_lev > rn2(20)) 1273. destroy_item(POTION_CLASS, AD_FIRE); 1274. if((int) mtmp->m_lev > rn2(25)) 1275. destroy_item(SPBOOK_CLASS, AD_FIRE); 1276. burn_away_slime(); 1277. } else dmg = 0; 1278. break; 1279. case AD_COLD: 1280. hitmsg(mtmp, mattk); 1281. if (uncancelled) { 1282. pline("You're covered in frost!"); 1283. if (Cold_resistance) { 1284. pline_The("frost doesn't seem cold!"); 1285. dmg = 0; 1286. } 1287. if((int) mtmp->m_lev > rn2(20)) 1288. destroy_item(POTION_CLASS, AD_COLD); 1289. } else dmg = 0; 1290. break; 1291. case AD_ELEC: 1292. hitmsg(mtmp, mattk); 1293. if (uncancelled) { 1294. You("get zapped!"); 1295. if (Shock_resistance) { 1296. pline_The("zap doesn't shock you!"); 1297. dmg = 0; 1298. } 1299. if((int) mtmp->m_lev > rn2(20)) 1300. destroy_item(WAND_CLASS, AD_ELEC); 1301. if((int) mtmp->m_lev > rn2(20)) 1302. destroy_item(RING_CLASS, AD_ELEC); 1303. } else dmg = 0; 1304. break; 1305. case AD_SLEE: 1306. hitmsg(mtmp, mattk); 1307. if (uncancelled && multi >= 0 && !rn2(5)) { 1308. if (Sleep_resistance) break; 1309. fall_asleep(-rnd(10), TRUE); 1310. if (Blind) You("are put to sleep!"); 1311. else You("are put to sleep by %s!", mon_nam(mtmp)); 1312. } 1313. break; 1314. case AD_BLND: 1315. if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj*)0)) { 1316. if (!Blind) pline("%s blinds you!", Monnam(mtmp)); 1317. make_blinded(Blinded+(long)dmg,FALSE); 1318. if (!Blind) Your(vision_clears); 1319. } 1320. dmg = 0; 1321. break; 1322. case AD_DRST: 1323. ptmp = A_STR; 1324. goto dopois; 1325. case AD_DRDX: 1326. ptmp = A_DEX; 1327. goto dopois; 1328. case AD_DRCO: 1329. ptmp = A_CON; 1330. dopois: 1331. hitmsg(mtmp, mattk); 1332. if (uncancelled && !rn2(8)) { 1333. Sprintf(buf, "%s %s", 1334. s_suffix(Monnam(mtmp)), mpoisons_subj(mtmp, mattk)); 1335. poisoned(buf, ptmp, mdat->mname, 30); 1336. } 1337. break; 1338. case AD_DRIN: 1339. hitmsg(mtmp, mattk); 1340. if (defends(AD_DRIN, uwep) || !has_head(youmonst.data)) { 1341. You("don't seem harmed."); 1342. /* Not clear what to do for green slimes */ 1343. break; 1344. } 1345. if (u_slip_free(mtmp,mattk)) break; 1346. 1347. if (uarmh && rn2(8)) { 1348. /* not body_part(HEAD) */ 1349. Your("helmet blocks the attack to your head."); 1350. break; 1351. } 1352. 1353. /* conflicted dog, perhaps? */ 1354. if (mtmp->mtame && !mtmp->isminion) { 1355. EDOG(mtmp)->hungrytime += rnd(60); 1356. mtmp->mconf = 0; 1357. } 1358. 1359. if (Half_physical_damage) dmg = (dmg+1) / 2; 1360. mdamageu(mtmp, dmg); 1361. 1362. if (!uarmh || uarmh->otyp != DUNCE_CAP) { 1363. Your("brain is eaten!"); 1364. /* No such thing as mindless players... */ 1365. if (ABASE(A_INT) <= ATTRMIN(A_INT)) { 1366. int lifesaved = 0; 1367. struct obj *wore_amulet = uamul; 1368. 1369. while(1) { 1370. /* avoid looping on "die(y/n)?" */ 1371. if (lifesaved && (discover || wizard)) { 1372. if (wore_amulet && !uamul) { 1373. /* used up AMULET_OF_LIFE_SAVING; still 1374. subject to dying from brainlessness */ 1375. wore_amulet = 0; 1376. } else { 1377. /* explicitly chose not to die; 1378. arbitrarily boost intelligence */ 1379. ABASE(A_INT) = ATTRMIN(A_INT) + 2; 1380. You_feel("like a scarecrow."); 1381. break; 1382. } 1383. } 1384. 1385. if (lifesaved) 1386. pline("Unfortunately your brain is still gone."); 1387. else 1388. Your("last thought fades away."); 1389. killer = "brainlessness"; 1390. killer_format = KILLED_BY; 1391. done(DIED); 1392. lifesaved++; 1393. } 1394. } 1395. } 1396. /* adjattrib gives dunce cap message when appropriate */ 1397. (void) adjattrib(A_INT, -rnd(2), FALSE); 1398. forget_levels(25); /* lose memory of 25% of levels */ 1399. forget_objects(25); /* lose memory of 25% of objects */ 1400. exercise(A_WIS, FALSE); 1401. break; 1402. case AD_PLYS: 1403. hitmsg(mtmp, mattk); 1404. if (uncancelled && multi >= 0 && !rn2(3)) { 1405. if (Free_action) { 1406. You("momentarily stiffen."); 1407. } else { 1408. if (Blind) You("are frozen!"); 1409. else You("are frozen by %s!", mon_nam(mtmp)); 1410. nomovemsg = 0; /* default: "you can move again" */ 1411. nomul(-rnd(10)); 1412. exercise(A_DEX, FALSE); 1413. } 1414. } 1415. break; 1416. case AD_TCKL: 1417. hitmsg(mtmp, mattk); 1418. if (uncancelled && multi >= 0 && !rn2(3)) { 1419. if (Free_action) 1420. You_feel("horrible tentacles probing your flesh!"); 1421. else { 1422. if (Blind) You("are mercilessly tickled!"); 1423. else You("are mercilessly tickled by %s!", mon_nam(mtmp)); 1424. nomovemsg = 0; /* default: "you can move again" */ 1425. nomul(-rnd(10)); 1426. exercise(A_DEX, FALSE); 1427. exercise(A_CON, FALSE); 1428. } 1429. } 1430. break; 1431. case AD_DRLI: 1432. hitmsg(mtmp, mattk); 1433. /* if vampire biting (and also a pet) */ 1434. if (is_vampire(mtmp->data) && mattk->aatyp == AT_BITE && 1435. has_blood(youmonst.data)) { 1436. Your("blood is being drained!"); 1437. /* Get 1/20th of full corpse value 1438. * Therefore 4 bites == 1 drink 1439. */ 1440. if (mtmp->mtame && !mtmp->isminion) 1441. EDOG(mtmp)->hungrytime += ((int)((youmonst.data)->cnutrit / 20) + 1); 1442. } 1443. 1444. if (uncancelled && !rn2(3) && !Drain_resistance) { 1445. losexp("life drainage", FALSE); 1446. } 1447. break; 1448. case AD_LEGS: 1449. { register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; 1450. const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left"; 1451. 1452. /* This case is too obvious to ignore, but Nethack is not in 1453. * general very good at considering height--most short monsters 1454. * still _can_ attack you when you're flying or mounted. 1455. * [FIXME: why can't a flying attacker overcome this?] 1456. */ 1457. if ( 1458. #ifdef STEED 1459. u.usteed || 1460. #endif 1461. Levitation || Flying) { 1462. pline("%s tries to reach your %s %s!", Monnam(mtmp), 1463. sidestr, body_part(LEG)); 1464. dmg = 0; 1465. } else if (mtmp->mcan) { 1466. pline("%s nuzzles against your %s %s!", Monnam(mtmp), 1467. sidestr, body_part(LEG)); 1468. dmg = 0; 1469. } else { 1470. if (uarmf) { 1471. if (rn2(2) && (uarmf->otyp == LOW_BOOTS || 1472. uarmf->otyp == IRON_SHOES)) 1473. pline("%s pricks the exposed part of your %s %s!", 1474. Monnam(mtmp), sidestr, body_part(LEG)); 1475. else if (!rn2(5)) 1476. pline("%s pricks through your %s boot!", 1477. Monnam(mtmp), sidestr); 1478. else { 1479. pline("%s scratches your %s boot!", Monnam(mtmp), 1480. sidestr); 1481. dmg = 0; 1482. break; 1483. } 1484. } else pline("%s pricks your %s %s!", Monnam(mtmp), 1485. sidestr, body_part(LEG)); 1486. set_wounded_legs(side, rnd(60-ACURR(A_DEX))); 1487. exercise(A_STR, FALSE); 1488. exercise(A_DEX, FALSE); 1489. } 1490. break; 1491. } 1492. case AD_STON: /* cockatrice */ 1493. hitmsg(mtmp, mattk); 1494. if(!rn2(3)) { 1495. if (mtmp->mcan) { 1496. if (flags.soundok) 1497. You_hear("a cough from %s!", mon_nam(mtmp)); 1498. } else { 1499. if (flags.soundok) 1500. You_hear("%s hissing!", s_suffix(mon_nam(mtmp))); 1501. if(!rn2(10) || 1502. (flags.moonphase == NEW_MOON && !have_lizard())) { 1503. do_stone: 1504. if (!Stoned && !Stone_resistance 1505. && !(poly_when_stoned(youmonst.data) && 1506. polymon(PM_STONE_GOLEM))) { 1507. Stoned = 5; 1508. delayed_killer = mtmp->data->mname; 1509. if (mtmp->data->geno & G_UNIQ) { 1510. if (!type_is_pname(mtmp->data)) { 1511. static char kbuf[BUFSZ]; 1512. 1513. /* "the" buffer may be reallocated */ 1514. Strcpy(kbuf, the(delayed_killer)); 1515. delayed_killer = kbuf; 1516. } 1517. killer_format = KILLED_BY; 1518. } else killer_format = KILLED_BY_AN; 1519. return(1); 1520. /* You("turn to stone..."); */ 1521. /* done_in_by(mtmp); */ 1522. } 1523. } 1524. } 1525. } 1526. break; 1527. case AD_STCK: 1528. hitmsg(mtmp, mattk); 1529. if (uncancelled && !u.ustuck && !sticks(youmonst.data)) 1530. setustuck(mtmp); 1531. break; 1532. case AD_WRAP: 1533. if ((!mtmp->mcan || u.ustuck == mtmp) && !sticks(youmonst.data)) { 1534. if (!u.ustuck && !rn2(10)) { 1535. if (u_slip_free(mtmp, mattk)) { 1536. dmg = 0; 1537. } else { 1538. pline("%s swings itself around you!", 1539. Monnam(mtmp)); 1540. setustuck(mtmp); 1541. } 1542. } else if(u.ustuck == mtmp) { 1543. if (is_pool(mtmp->mx,mtmp->my) && !Swimming 1544. && !Amphibious) { 1545. boolean moat = 1546. (levl[mtmp->mx][mtmp->my].typ != POOL) && 1547. (levl[mtmp->mx][mtmp->my].typ != WATER) && 1548. !Is_medusa_level(&u.uz) && 1549. !Is_waterlevel(&u.uz); 1550. 1551. pline("%s drowns you...", Monnam(mtmp)); 1552. killer_format = KILLED_BY_AN; 1553. Sprintf(buf, "%s by %s", 1554. moat ? "moat" : "pool of water", 1555. an(mtmp->data->mname)); 1556. killer = buf; 1557. done(DROWNING); 1558. } else if(mattk->aatyp == AT_HUGS) 1559. You("are being crushed."); 1560. } else { 1561. dmg = 0; 1562. if(flags.verbose) 1563. pline("%s brushes against your %s.", Monnam(mtmp), 1564. body_part(LEG)); 1565. } 1566. } else dmg = 0; 1567. break; 1568. case AD_WERE: 1569. hitmsg(mtmp, mattk); 1570. if (uncancelled && !rn2(4) && u.ulycn == NON_PM && 1571. !Protection_from_shape_changers && 1572. !is_were(youmonst.data) && 1573. !defends(AD_WERE,uwep)) { 1574. You_feel("feverish."); 1575. exercise(A_CON, FALSE); 1576. u.ulycn = monsndx(mdat); 1577. upermonst.mflags2 |= (M2_WERE); 1578. } 1579. break; 1580. case AD_SGLD: 1581. hitmsg(mtmp, mattk); 1582. if (youmonst.data->mlet == mdat->mlet) break; 1583. if(!mtmp->mcan) stealgold(mtmp); 1584. break; 1585. 1586. case AD_SITM: /* for now these are the same */ 1587. case AD_SEDU: 1588. if (is_animal(mtmp->data)) { 1589. hitmsg(mtmp, mattk); 1590. if (mtmp->mcan) break; 1591. /* Continue below */ 1592. } else if (dmgtype(youmonst.data, AD_SEDU) 1593. #ifdef SEDUCE 1594. || dmgtype(youmonst.data, AD_SSEX) 1595. #endif 1596. ) { 1597. pline("%s %s.", Monnam(mtmp), mtmp->minvent ? 1598. "brags about the goods some dungeon explorer provided" : 1599. "makes some remarks about how difficult theft is lately"); 1600. if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); 1601. return 3; 1602. } else if (mtmp->mcan) { 1603. if (!Blind) { 1604. /* 1605. * We use flags.female here on the basis that the 1606. * monster chooses whether to charm or to seduce 1607. * based on your visible gender. --ALI 1608. */ 1609. int do_charm = is_neuter(mdat) || \ 1610. flags.female == mtmp->female; 1611. pline("%s tries to %s you, but you seem %s.", 1612. Adjmonnam(mtmp, "plain"), 1613. do_charm ? "charm" : "seduce", 1614. do_charm ? "unaffected" : "uninterested"); 1615. } 1616. if(rn2(3)) { 1617. if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); 1618. return 3; 1619. } 1620. break; 1621. } 1622. buf[0] = '\0'; 1623. switch (steal(mtmp, buf)) { 1624. case -1: 1625. return 2; 1626. case 0: 1627. break; 1628. default: 1629. if (!is_animal(mtmp->data) && !tele_restrict(mtmp)) 1630. (void) rloc(mtmp, FALSE); 1631. if (is_animal(mtmp->data) && *buf) { 1632. if (canseemon(mtmp)) 1633. pline("%s tries to %s away with %s.", 1634. Monnam(mtmp), 1635. locomotion(mtmp->data, "run"), 1636. buf); 1637. } 1638. monflee(mtmp, 0, FALSE, FALSE); 1639. return 3; 1640. } 1641. break; 1642. #ifdef SEDUCE 1643. case AD_SSEX: 1644. if(could_seduce(mtmp, &youmonst, mattk) == 1 1645. && !mtmp->mcan) 1646. if (doseduce(mtmp)) 1647. return 3; 1648. break; 1649. #endif 1650. case AD_SAMU: 1651. hitmsg(mtmp, mattk); 1652. /* when the Wiz hits, 1/20 steals the amulet */ 1653. if (u.uhave.amulet || 1654. u.uhave.bell || u.uhave.book || u.uhave.menorah 1655. || u.uhave.questart) /* carrying the Quest Artifact */ 1656. if (!rn2(20)) stealamulet(mtmp); 1657. break; 1658. 1659. case AD_TLPT: 1660. hitmsg(mtmp, mattk); 1661. if (uncancelled) { 1662. if(flags.verbose) 1663. Your("position suddenly seems very uncertain!"); 1664. tele(); 1665. } 1666. break; 1667. case AD_RUST: 1668. hitmsg(mtmp, mattk); 1669. if (mtmp->mcan) break; 1670. if (u.umonnum == PM_IRON_GOLEM) { 1671. You("rust!"); 1672. u.uhp -= mons[u.umonnum].mlevel; 1673. u.uhpmax -= mons[u.umonnum].mlevel; 1674. if (u.uhpmax < 1) u.uhpmax = 1; 1675. /* KMH, balance patch -- this is okay with unchanging */ 1676. u.mh = 0; 1677. rehumanize(); 1678. break; 1679. } 1680. hurtarmor(AD_RUST); 1681. break; 1682. case AD_CORR: 1683. hitmsg(mtmp, mattk); 1684. if (mtmp->mcan) break; 1685. hurtarmor(AD_CORR); 1686. break; 1687. case AD_DCAY: 1688. hitmsg(mtmp, mattk); 1689. if (mtmp->mcan) break; 1690. if (u.umonnum == PM_WOOD_GOLEM || 1691. u.umonnum == PM_LEATHER_GOLEM) { 1692. You("rot!"); 1693. u.uhp -= mons[u.umonnum].mlevel; 1694. u.uhpmax -= mons[u.umonnum].mlevel; 1695. if (u.uhpmax < 1) u.uhpmax = 1; 1696. u.mh = 0; 1697. /* KMH, balance patch -- this is okay with unchanging */ 1698. rehumanize(); 1699. break; 1700. } 1701. hurtarmor(AD_DCAY); 1702. break; 1703. case AD_HEAL: 1704. /* a cancelled nurse is just an ordinary monster */ 1705. if (mtmp->mcan) { 1706. hitmsg(mtmp, mattk); 1707. break; 1708. } 1709. if(!uwep 1710. #ifdef TOURIST 1711. && !uarmu 1712. #endif 1713. && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) { 1714. boolean goaway = FALSE; 1715. pline("%s hits! (I hope you don't mind.)", Monnam(mtmp)); 1716. if (Upolyd) { 1717. u.mh += rnd(7); 1718. /* STEPHEN WHITE'S NEW CODE */ 1719. if (!rn2(7)) { 1720. /* no upper limit necessary; effect is temporary */ 1721. u.mhmax++; 1722. if (!rn2(13)) goaway = TRUE; 1723. } 1724. if (u.mh > u.mhmax) u.mh = u.mhmax; 1725. } else { 1726. u.uhp += rnd(7); 1727. if (!rn2(7)) { 1728. /* hard upper limit via nurse care: 25 * ulevel */ 1729. if (u.uhpmax < 5 * u.ulevel + d(2 * u.ulevel, 10)) { 1730. u.uhpmax++; 1731. } 1732. if (!rn2(13)) goaway = TRUE; 1733. } 1734. if (u.uhp > u.uhpmax) u.uhp = u.uhpmax; 1735. } 1736. if (!rn2(3)) exercise(A_STR, TRUE); 1737. if (!rn2(3)) exercise(A_CON, TRUE); 1738. if (Sick) make_sick(0L, (char *) 0, FALSE, SICK_ALL); 1739. flags.botl = 1; 1740. if (goaway) { 1741. mongone(mtmp); 1742. return 2; 1743. } else if (!rn2(33)) { 1744. if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE); 1745. monflee(mtmp, d(3, 6), TRUE, FALSE); 1746. return 3; 1747. } 1748. dmg = 0; 1749. } else { 1750. if (Role_if(PM_HEALER)) { 1751. if (flags.soundok && !(moves % 5)) 1752. verbalize("Doc, I can't help you unless you cooperate."); 1753. dmg = 0; 1754. } else hitmsg(mtmp, mattk); 1755. } 1756. break; 1757. case AD_CURS: 1758. hitmsg(mtmp, mattk); 1759. if(!night() && mdat == &mons[PM_GREMLIN]) break; 1760. if(!mtmp->mcan && !rn2(10)) { 1761. if (flags.soundok) { 1762. if (Blind) You_hear("laughter."); 1763. else pline("%s chuckles.", Monnam(mtmp)); 1764. } 1765. if (u.umonnum == PM_CLAY_GOLEM) { 1766. pline("Some writing vanishes from your head!"); 1767. u.uhp -= mons[u.umonnum].mlevel; 1768. u.uhpmax -= mons[u.umonnum].mlevel; 1769. if (u.uhpmax < 1) u.uhpmax = 1; 1770. /* KMH, balance patch -- this is okay with unchanging */ 1771. u.mh = 0; 1772. rehumanize(); 1773. break; 1774. } 1775. attrcurse(); 1776. } 1777. break; 1778. case AD_STUN: 1779. hitmsg(mtmp, mattk); 1780. if(!mtmp->mcan && !rn2(4)) { 1781. make_stunned(HStun + dmg, TRUE); 1782. dmg /= 2; 1783. } 1784. break; 1785. case AD_ACID: 1786. hitmsg(mtmp, mattk); 1787. if(!mtmp->mcan && !rn2(3)) { 1788. if (Acid_resistance) { 1789. pline("You're covered in acid, but it seems harmless."); 1790. dmg = 0; 1791. } else { 1792. pline("You're covered in acid! It burns!"); 1793. exercise(A_STR, FALSE); 1794. } 1795. } else dmg = 0; 1796. break; 1797. case AD_SLOW: 1798. hitmsg(mtmp, mattk); 1799. if (uncancelled && HFast && 1800. !defends(AD_SLOW, uwep) && !rn2(4)) 1801. u_slow_down(); 1802. break; 1803. case AD_DREN: 1804. hitmsg(mtmp, mattk); 1805. if (uncancelled && !rn2(4)) 1806. drain_en(dmg); 1807. dmg = 0; 1808. break; 1809. case AD_CONF: 1810. hitmsg(mtmp, mattk); 1811. if(!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) { 1812. mtmp->mspec_used = mtmp->mspec_used + (dmg + rn2(6)); 1813. if(Confusion) 1814. You("are getting even more confused."); 1815. else You("are getting confused."); 1816. make_confused(HConfusion + dmg, FALSE); 1817. } 1818. dmg = 0; 1819. break; 1820. case AD_DETH: 1821. pline("%s reaches out with its deadly touch.", Monnam(mtmp)); 1822. if (is_undead(youmonst.data)) { 1823. /* Still does normal damage */ 1824. pline("Was that the touch of death?"); 1825. break; 1826. } 1827. switch (rn2(20)) { 1828. case 19: case 18: case 17: 1829. if (!Antimagic) { 1830. killer_format = KILLED_BY_AN; 1831. killer = "touch of death"; 1832. done(DIED); 1833. dmg = 0; 1834. break; 1835. } /* else FALLTHRU */ 1836. default: /* case 16: ... case 5: */ 1837. You_feel("your life force draining away..."); 1838. permdmg = 1; /* actual damage done below */ 1839. break; 1840. case 4: case 3: case 2: case 1: case 0: 1841. if (Antimagic) shieldeff(u.ux, u.uy); 1842. pline("Lucky for you, it didn't work!"); 1843. dmg = 0; 1844. break; 1845. } 1846. break; 1847. case AD_PEST: 1848. pline("%s reaches out, and you feel fever and chills.", 1849. Monnam(mtmp)); 1850. (void) diseasemu(mdat); /* plus the normal damage */ 1851. /* No damage if invulnerable; setting dmg zero prevents 1852. * "You are unharmed!" after a sickness inducing attack */ 1853. if (Invulnerable) dmg = 0; 1854. break; 1855. case AD_FAMN: 1856. pline("%s reaches out, and your body shrivels.", 1857. Monnam(mtmp)); 1858. exercise(A_CON, FALSE); 1859. if (!is_fainted()) morehungry(rn1(40,40)); 1860. /* plus the normal damage */ 1861. break; 1862. case AD_CALM: /* KMH -- koala attack */ 1863. hitmsg(mtmp, mattk); 1864. if (uncancelled) 1865. docalm(); 1866. break; 1867. case AD_POLY: 1868. hitmsg(mtmp, mattk); 1869. if (uncancelled && !Unchanging && !Antimagic) { 1870. if (flags.verbose) 1871. You("undergo a freakish metamorphosis!"); 1872. polyself(FALSE); 1873. } 1874. break; 1875. case AD_SLIM: 1876. hitmsg(mtmp, mattk); 1877. if (!uncancelled) break; 1878. if (flaming(youmonst.data)) { 1879. pline_The("slime burns away!"); 1880. dmg = 0; 1881. } else if (Unchanging || 1882. youmonst.data == &mons[PM_GREEN_SLIME]) { 1883. You("are unaffected."); 1884. dmg = 0; 1885. } else if (!Slimed) { 1886. You("don't feel very well."); 1887. Slimed = 10L; 1888. flags.botl = 1; 1889. killer_format = KILLED_BY_AN; 1890. delayed_killer = mtmp->data->mname; 1891. } else 1892. pline("Yuck!"); 1893. break; 1894. case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ 1895. hitmsg(mtmp, mattk); 1896. /* uncancelled is sufficient enough; please 1897. don't make this attack less frequent */ 1898. if (uncancelled) { 1899. struct obj *obj = some_armor(&youmonst); 1900. 1901. if (drain_item(obj)) { 1902. Your("%s less effective.", aobjnam(obj, "seem")); 1903. } 1904. } 1905. break; 1906. default: dmg = 0; 1907. break; 1908. } 1909. if(u.uhp < 1) done_in_by(mtmp); 1910. 1911. /* Negative armor class reduces damage done instead of fully protecting 1912. * against hits. 1913. */ 1914. if (dmg && u.uac < -10) { 1915. int tempval; 1916. tempval = rnd(-(10 + u.uac)/5+1); 1917. if (tempval < 1) tempval = 1; 1918. if (tempval > 10) tempval = 10; 1919. dmg -= tempval; 1920. if (dmg < 1) dmg = 1; 1921. } 1922. 1923. if(dmg) { 1924. if (Half_physical_damage 1925. /* Mitre of Holiness */ 1926. || (Role_if(PM_PRIEST) && uarmh && is_quest_artifact(uarmh) && 1927. (is_undead(mtmp->data) || is_demon(mtmp->data)))) 1928. dmg = (dmg+1) / 2; 1929. 1930. if (permdmg) { /* Death's life force drain */ 1931. int lowerlimit, *hpmax_p; 1932. /* 1933. * Apply some of the damage to permanent hit points: 1934. * polymorphed 100% against poly'd hpmax 1935. * hpmax > 25*lvl 100% against normal hpmax 1936. * hpmax > 10*lvl 50..100% 1937. * hpmax > 5*lvl 25..75% 1938. * otherwise 0..50% 1939. * Never reduces hpmax below 1 hit point per level. 1940. */ 1941. permdmg = rn2(dmg / 2 + 1); 1942. if (Upolyd || u.uhpmax > 25 * u.ulevel) permdmg = dmg; 1943. else if (u.uhpmax > 10 * u.ulevel) permdmg += dmg / 2; 1944. else if (u.uhpmax > 5 * u.ulevel) permdmg += dmg / 4; 1945. 1946. if (Upolyd) { 1947. hpmax_p = &u.mhmax; 1948. /* [can't use youmonst.m_lev] */ 1949. lowerlimit = min((int)youmonst.data->mlevel, u.ulevel); 1950. } else { 1951. hpmax_p = &u.uhpmax; 1952. lowerlimit = u.ulevel; 1953. } 1954. if (*hpmax_p - permdmg > lowerlimit) 1955. *hpmax_p -= permdmg; 1956. else if (*hpmax_p > lowerlimit) 1957. *hpmax_p = lowerlimit; 1958. else /* unlikely... */ 1959. ; /* already at or below minimum threshold; do nothing */ 1960. flags.botl = 1; 1961. } 1962. 1963. mdamageu(mtmp, dmg); 1964. } 1965. 1966. if (DEADMONSTER(mtmp)) 1967. res = 2; 1968. else if (dmg) 1969. res = passiveum(olduasmon, mtmp, mattk); 1970. else 1971. res = 1; 1972. stop_occupation(); 1973. return res; 1974. } 1975. 1976. #endif /* OVL1 */ 1977. #ifdef OVLB 1978. 1979. STATIC_OVL int 1980. gulpmu(mtmp, mattk) /* monster swallows you, or damage if u.uswallow */ 1981. register struct monst *mtmp; 1982. register struct attack *mattk; 1983. { 1984. struct trap *t = t_at(u.ux, u.uy); 1985. int tmp = d((int)mattk->damn, (int)mattk->damd); 1986. int tim_tmp; 1987. register struct obj *otmp2; 1988. int i; 1989. 1990. if (!u.uswallow) { /* swallows you */ 1991. if (youmonst.data->msize >= MZ_HUGE) return(0); 1992. if ((t && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))) && 1993. sobj_at(BOULDER, u.ux, u.uy)) 1994. return(0); 1995. 1996. if (Punished) unplacebc(); /* ball&chain go away */ 1997. remove_monster(mtmp->mx, mtmp->my); 1998. mtmp->mtrapped = 0; /* no longer on old trap */ 1999. place_monster(mtmp, u.ux, u.uy); 2000. newsym(mtmp->mx,mtmp->my); 2001. #ifdef STEED 2002. if (is_animal(mtmp->data) && u.usteed) { 2003. char buf[BUFSZ]; 2004. /* Too many quirks presently if hero and steed 2005. * are swallowed. Pretend purple worms don't 2006. * like horses for now :-) 2007. */ 2008. Strcpy(buf, mon_nam(u.usteed)); 2009. pline ("%s lunges forward and plucks you off %s!", 2010. Monnam(mtmp), buf); 2011. dismount_steed(DISMOUNT_ENGULFED); 2012. } else 2013. #endif 2014. pline("%s engulfs you!", Monnam(mtmp)); 2015. stop_occupation(); 2016. reset_occupations(); /* behave as if you had moved */ 2017. 2018. if (u.utrap) { 2019. You("are released from the %s!", 2020. u.utraptype==TT_WEB ? "web" : "trap"); 2021. u.utrap = 0; 2022. } 2023. 2024. i = number_leashed(); 2025. if (i > 0) { 2026. const char *s = (i > 1) ? "leashes" : "leash"; 2027. pline_The("%s %s loose.", s, vtense(s, "snap")); 2028. unleash_all(); 2029. } 2030. 2031. if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) { 2032. minstapetrify(mtmp, TRUE); 2033. if (mtmp->mhp > 0) return 0; 2034. else return 2; 2035. } 2036. 2037. display_nhwindow(WIN_MESSAGE, FALSE); 2038. vision_recalc(2); /* hero can't see anything */ 2039. u.uswallow = 1; 2040. setustuck(mtmp); 2041. /* u.uswldtim always set > 1 */ 2042. tim_tmp = 25 - (int)mtmp->m_lev; 2043. if (tim_tmp > 0) tim_tmp = rnd(tim_tmp) / 2; 2044. else if (tim_tmp < 0) tim_tmp = -(rnd(-tim_tmp) / 2); 2045. tim_tmp += -u.uac + 10; 2046. u.uswldtim = (unsigned)((tim_tmp < 2) ? 2 : tim_tmp); 2047. swallowed(1); 2048. for (otmp2 = invent; otmp2; otmp2 = otmp2->nobj) 2049. (void) snuff_lit(otmp2); 2050. } 2051. 2052. if (mtmp != u.ustuck) return(0); 2053. if (u.uswldtim > 0) u.uswldtim -= 1; 2054. 2055. switch(mattk->adtyp) { 2056. 2057. case AD_DGST: 2058. if (Slow_digestion) { 2059. /* Messages are handled below */ 2060. u.uswldtim = 0; 2061. tmp = 0; 2062. } else if (u.uswldtim == 0) { 2063. pline("%s totally digests you!", Monnam(mtmp)); 2064. tmp = u.uhp; 2065. if (Half_physical_damage) tmp *= 2; /* sorry */ 2066. } else { 2067. pline("%s%s digests you!", Monnam(mtmp), 2068. (u.uswldtim == 2) ? " thoroughly" : 2069. (u.uswldtim == 1) ? " utterly" : ""); 2070. exercise(A_STR, FALSE); 2071. } 2072. break; 2073. case AD_PHYS: 2074. if (mtmp->data == &mons[PM_FOG_CLOUD]) { 2075. You("are laden with moisture and %s", 2076. flaming(youmonst.data) ? "are smoldering out!" : 2077. Breathless ? "find it mildly uncomfortable." : 2078. amphibious(youmonst.data) ? "feel comforted." : 2079. "can barely breathe!"); 2080. /* NB: Amphibious includes Breathless */ 2081. if (Amphibious && !flaming(youmonst.data)) tmp = 0; 2082. } else { 2083. You("are pummeled with debris!"); 2084. exercise(A_STR, FALSE); 2085. } 2086. break; 2087. case AD_ACID: 2088. if (Acid_resistance) { 2089. You("are covered with a seemingly harmless goo."); 2090. tmp = 0; 2091. } else { 2092. if (Hallucination) pline("Ouch! You've been slimed!"); 2093. else You("are covered in slime! It burns!"); 2094. exercise(A_STR, FALSE); 2095. } 2096. /* Mik: Go corrode a few things... */ 2097. if (mtmp->data == &mons[PM_SHOGGOTH] 2098. || mtmp->data == &mons[PM_GIANT_SHOGGOTH]) { 2099. for (otmp2 = invent; otmp2; otmp2 = otmp2->nobj) 2100. if (is_corrodeable(otmp2)) 2101. (void) rust_dmg(otmp2, xname(otmp2), 3, FALSE, 2102. &youmonst); 2103. } else { 2104. for (otmp2 = invent; otmp2; otmp2 = otmp2->nobj) 2105. if (is_corrodeable(otmp2) && !rn2(9)) 2106. (void) rust_dmg(otmp2, xname(otmp2), 3, FALSE, 2107. &youmonst); 2108. } 2109. break; 2110. case AD_BLND: 2111. if (can_blnd(mtmp, &youmonst, mattk->aatyp, (struct obj*)0)) { 2112. if(!Blind) { 2113. You_cant("see in here!"); 2114. make_blinded((long)tmp,FALSE); 2115. if (!Blind) Your(vision_clears); 2116. } else 2117. /* keep him blind until disgorged */ 2118. make_blinded(Blinded+1,FALSE); 2119. } 2120. tmp = 0; 2121. break; 2122. case AD_ELEC: 2123. if(!mtmp->mcan && rn2(2)) { 2124. pline_The("air around you crackles with electricity."); 2125. if (Shock_resistance) { 2126. shieldeff(u.ux, u.uy); 2127. You("seem unhurt."); 2128. ugolemeffects(AD_ELEC,tmp); 2129. tmp = 0; 2130. } 2131. } else tmp = 0; 2132. break; 2133. case AD_COLD: 2134. if(!mtmp->mcan && rn2(2)) { 2135. if (Cold_resistance) { 2136. shieldeff(u.ux, u.uy); 2137. You_feel("mildly chilly."); 2138. ugolemeffects(AD_COLD,tmp); 2139. tmp = 0; 2140. } else You("are freezing to death!"); 2141. } else tmp = 0; 2142. break; 2143. case AD_FIRE: 2144. if(!mtmp->mcan && rn2(2)) { 2145. if (Fire_resistance) { 2146. shieldeff(u.ux, u.uy); 2147. You_feel("mildly hot."); 2148. ugolemeffects(AD_FIRE,tmp); 2149. tmp = 0; 2150. } else You("are burning to a crisp!"); 2151. burn_away_slime(); 2152. } else tmp = 0; 2153. break; 2154. case AD_DISE: 2155. if (!diseasemu(mtmp->data)) tmp = 0; 2156. break; 2157. default: 2158. tmp = 0; 2159. break; 2160. } 2161. 2162. if (Half_physical_damage) tmp = (tmp+1) / 2; 2163. 2164. mdamageu(mtmp, tmp); 2165. if (tmp) stop_occupation(); 2166. 2167. if (touch_petrifies(youmonst.data) && !resists_ston(mtmp)) { 2168. pline("%s very hurriedly %s you!", Monnam(mtmp), 2169. is_animal(mtmp->data)? "regurgitates" : "expels"); 2170. expels(mtmp, mtmp->data, FALSE); 2171. } else if (!u.uswldtim || youmonst.data->msize >= MZ_HUGE) { 2172. You("get %s!", is_animal(mtmp->data)? "regurgitated" : "expelled"); 2173. if (flags.verbose && (is_animal(mtmp->data) || 2174. (dmgtype(mtmp->data, AD_DGST) && Slow_digestion))) 2175. pline("Obviously %s doesn't like your taste.", mon_nam(mtmp)); 2176. expels(mtmp, mtmp->data, FALSE); 2177. } 2178. return(1); 2179. } 2180. 2181. STATIC_OVL int 2182. explmu(mtmp, mattk, ufound) /* monster explodes in your face */ 2183. register struct monst *mtmp; 2184. register struct attack *mattk; 2185. boolean ufound; 2186. { 2187. if (mtmp->mcan) return(0); 2188. 2189. if (!ufound) 2190. pline("%s explodes at a spot in %s!", 2191. canseemon(mtmp) ? Monnam(mtmp) : "It", 2192. levl[mtmp->mux][mtmp->muy].typ == WATER 2193. ? "empty water" : "thin air"); 2194. else { 2195. register int tmp = d((int)mattk->damn, (int)mattk->damd); 2196. register boolean not_affected = defends((int)mattk->adtyp, uwep); 2197. 2198. hitmsg(mtmp, mattk); 2199. 2200. switch (mattk->adtyp) { 2201. case AD_COLD: 2202. not_affected |= Cold_resistance; 2203. goto common; 2204. case AD_FIRE: 2205. not_affected |= Fire_resistance; 2206. goto common; 2207. case AD_ELEC: 2208. not_affected |= Shock_resistance; 2209. common: 2210. 2211. if (!not_affected) { 2212. if (ACURR(A_DEX) > rnd(20)) { 2213. You("duck some of the blast."); 2214. tmp = (tmp+1) / 2; 2215. } else { 2216. if (flags.verbose) You("get blasted!"); 2217. } 2218. if (mattk->adtyp == AD_FIRE) burn_away_slime(); 2219. if (Half_physical_damage) tmp = (tmp+1) / 2; 2220. mdamageu(mtmp, tmp); 2221. } 2222. break; 2223. 2224. case AD_BLND: 2225. not_affected = resists_blnd(&youmonst); 2226. if (!not_affected) { 2227. /* sometimes you're affected even if it's invisible */ 2228. if (mon_visible(mtmp) || (rnd(tmp /= 2) > u.ulevel)) { 2229. You("are blinded by a blast of light!"); 2230. make_blinded((long)tmp, FALSE); 2231. if (!Blind) Your(vision_clears); 2232. } else if (flags.verbose) 2233. You("get the impression it was not terribly bright."); 2234. } 2235. break; 2236. 2237. case AD_HALU: 2238. not_affected |= Blind || 2239. (u.umonnum == PM_BLACK_LIGHT || 2240. u.umonnum == PM_VIOLET_FUNGUS || 2241. dmgtype(youmonst.data, AD_STUN)); 2242. if (!not_affected) { 2243. boolean chg; 2244. if (!Hallucination) 2245. You("are caught in a blast of kaleidoscopic light!"); 2246. chg = make_hallucinated(HHallucination + (long)tmp,FALSE,0L); 2247. You("%s.", chg ? "are freaked out" : "seem unaffected"); 2248. } 2249. break; 2250. 2251. default: 2252. break; 2253. } 2254. if (not_affected) { 2255. You("seem unaffected by it."); 2256. ugolemeffects((int)mattk->adtyp, tmp); 2257. } 2258. } 2259. mondead(mtmp); 2260. wake_nearto(mtmp->mx, mtmp->my, 7*7); 2261. if (mtmp->mhp > 0) return(0); 2262. return(2); /* it dies */ 2263. } 2264. 2265. int 2266. gazemu(mtmp, mattk) /* monster gazes at you */ 2267. register struct monst *mtmp; 2268. register struct attack *mattk; 2269. { 2270. switch(mattk->adtyp) { 2271. case AD_STON: 2272. if (mtmp->mcan || !mtmp->mcansee) { 2273. if (!canseemon(mtmp)) break; /* silently */ 2274. pline("%s %s.", Monnam(mtmp), 2275. (mtmp->data == &mons[PM_MEDUSA] && mtmp->mcan) ? 2276. "doesn't look all that ugly" : 2277. "gazes ineffectually"); 2278. break; 2279. } 2280. if (Reflecting && couldsee(mtmp->mx, mtmp->my) && 2281. mtmp->data == &mons[PM_MEDUSA]) { 2282. /* hero has line of sight to Medusa and she's not blind */ 2283. boolean useeit = canseemon(mtmp); 2284. 2285. if (useeit) 2286. (void) ureflects("%s gaze is reflected by your %s.", 2287. s_suffix(Monnam(mtmp))); 2288. if (mon_reflects(mtmp, !useeit ? (char *)0 : 2289. "The gaze is reflected away by %s %s!")) 2290. break; 2291. if (!m_canseeu(mtmp)) { /* probably you're invisible */ 2292. if (useeit) 2293. pline( 2294. "%s doesn't seem to notice that %s gaze was reflected.", 2295. Monnam(mtmp), mhis(mtmp)); 2296. break; 2297. } 2298. if (useeit) 2299. pline("%s is turned to stone!", Monnam(mtmp)); 2300. stoned = TRUE; 2301. killed(mtmp); 2302. 2303. if (mtmp->mhp > 0) break; 2304. return 2; 2305. } 2306. if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) && 2307. !Stone_resistance) { 2308. You("meet %s gaze.", s_suffix(mon_nam(mtmp))); 2309. stop_occupation(); 2310. if(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) 2311. break; 2312. You("turn to stone..."); 2313. killer_format = KILLED_BY; 2314. killer = mtmp->data->mname; 2315. done(STONING); 2316. } 2317. break; 2318. case AD_CONF: 2319. if(!mtmp->mcan && canseemon(mtmp) && 2320. couldsee(mtmp->mx, mtmp->my) && 2321. mtmp->mcansee && !mtmp->mspec_used && rn2(5)) { 2322. int conf = d(3,4); 2323. 2324. mtmp->mspec_used = mtmp->mspec_used + (conf + rn2(6)); 2325. if(!Confusion) 2326. pline("%s gaze confuses you!", 2327. s_suffix(Monnam(mtmp))); 2328. else 2329. You("are getting more and more confused."); 2330. make_confused(HConfusion + conf, FALSE); 2331. stop_occupation(); 2332. } 2333. break; 2334. case AD_STUN: 2335. if(!mtmp->mcan && canseemon(mtmp) && 2336. couldsee(mtmp->mx, mtmp->my) && 2337. mtmp->mcansee && !mtmp->mspec_used && rn2(5)) { 2338. int stun = d(2,6); 2339. 2340. mtmp->mspec_used = mtmp->mspec_used + (stun + rn2(6)); 2341. pline("%s stares piercingly at you!", Monnam(mtmp)); 2342. make_stunned(HStun + stun, TRUE); 2343. stop_occupation(); 2344. } 2345. break; 2346. case AD_BLND: 2347. if (!mtmp->mcan && canseemon(mtmp) && !resists_blnd(&youmonst) 2348. && distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) { 2349. int blnd = d((int)mattk->damn, (int)mattk->damd); 2350. 2351. You("are blinded by %s radiance!", 2352. s_suffix(mon_nam(mtmp))); 2353. make_blinded((long)blnd,FALSE); 2354. stop_occupation(); 2355. /* not blind at this point implies you're wearing 2356. the Eyes of the Overworld; make them block this 2357. particular stun attack too */ 2358. if (!Blind) Your(vision_clears); 2359. else make_stunned((long)d(1,3),TRUE); 2360. } 2361. break; 2362. case AD_FIRE: 2363. if (!mtmp->mcan && canseemon(mtmp) && 2364. couldsee(mtmp->mx, mtmp->my) && 2365. mtmp->mcansee && !mtmp->mspec_used && rn2(5)) { 2366. int dmg = d(2,6); 2367. 2368. pline("%s attacks you with a fiery gaze!", Monnam(mtmp)); 2369. stop_occupation(); 2370. if (Fire_resistance) { 2371. pline_The("fire doesn't feel hot!"); 2372. dmg = 0; 2373. } 2374. burn_away_slime(); 2375. if ((int) mtmp->m_lev > rn2(20)) 2376. destroy_item(SCROLL_CLASS, AD_FIRE); 2377. if ((int) mtmp->m_lev > rn2(20)) 2378. destroy_item(POTION_CLASS, AD_FIRE); 2379. if ((int) mtmp->m_lev > rn2(25)) 2380. destroy_item(SPBOOK_CLASS, AD_FIRE); 2381. if (dmg) mdamageu(mtmp, dmg); 2382. } 2383. break; 2384. #ifdef PM_BEHOLDER /* work in progress */ 2385. #if 0 2386. case AD_SLEE: 2387. if(!mtmp->mcan && canseemon(mtmp) && 2388. couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee && 2389. multi >= 0 && !rn2(5) && !Sleep_resistance) { 2390. 2391. fall_asleep(-rnd(10), TRUE); 2392. pline("%s gaze makes you very sleepy...", 2393. s_suffix(Monnam(mtmp))); 2394. } 2395. break; 2396. #endif 2397. case AD_SLOW: 2398. if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && 2399. (HFast & (INTRINSIC|TIMEOUT)) && 2400. !defends(AD_SLOW, uwep) && !rn2(4)) 2401. 2402. u_slow_down(); 2403. stop_occupation(); 2404. break; 2405. #endif 2406. case AD_SLEE: 2407. if(!mtmp->mcan && canseemon(mtmp) && 2408. mtmp->mcansee && !mtmp->mspec_used && rn2(3)) { 2409. if (Displaced && rn2(3)) { 2410. if (!Blind) pline("%s gazes at your displaced image!",Monnam(mtmp)); 2411. break; 2412. } 2413. if ((Invisible && rn2(3)) || rn2(4)) { 2414. if (!Blind) pline("%s gazes around, but misses you!",Monnam(mtmp)); 2415. break; 2416. } 2417. if (!Blind) pline("%s gazes directly at you!",Monnam(mtmp)); 2418. if(Reflecting && m_canseeu(mtmp) && !mtmp->mcan) { 2419. if(!Blind) { 2420. (void) ureflects("%s gaze is reflected by your %s.", 2421. s_suffix(Monnam(mtmp))); 2422. if (mon_reflects(mtmp, 2423. "The gaze is reflected away by %s %s!")) 2424. break; 2425. } 2426. if (sleep_monst(mtmp, rnd(10), -1) && !Blind) 2427. pline("%s is put to sleep!", Monnam(mtmp)); 2428. break; 2429. } else if (Sleep_resistance) { 2430. pline("You yawn."); 2431. } else { 2432. nomul(-rnd(10)); 2433. u.usleep = 1; 2434. nomovemsg = "You wake up."; 2435. if (Blind) You("are put to sleep!"); 2436. else You("are put to sleep by %s!",mon_nam(mtmp)); 2437. } 2438. } 2439. break; 2440. case AD_DETH: 2441. if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && !mtmp->mspec_used && rn2(4)) { 2442. if (Displaced && rn2(3)) { 2443. if (!Blind) pline("%s gazes at your displaced image!",Monnam(mtmp)); 2444. break; 2445. } 2446. if ((Invisible && rn2(3)) || rn2(4)) { 2447. if (!Blind) pline("%s gazes around, but misses you!",Monnam(mtmp)); 2448. break; 2449. } 2450. if (!Blind) pline("%s gazes directly at you!",Monnam(mtmp)); 2451. if(Reflecting && m_canseeu(mtmp) && !mtmp->mcan) { 2452. if(!Blind) { 2453. (void) ureflects("%s gaze is reflected by your %s.", 2454. s_suffix(Monnam(mtmp))); 2455. if (mon_reflects(mtmp, 2456. "The gaze is reflected away by %s %s!")) 2457. break; 2458. pline("%s is killed by its own gaze of death!", 2459. Monnam(mtmp)); 2460. } 2461. killed(mtmp); 2462. if (mtmp->mhp > 0) break; 2463. return 2; 2464. } else if (is_undead(youmonst.data)) { 2465. /* Still does normal damage */ 2466. pline("Was that the gaze of death?"); 2467. break; 2468. } else if (Antimagic) { 2469. You("shudder momentarily..."); 2470. } else { 2471. You("die..."); 2472. killer_format = KILLED_BY_AN; 2473. killer = "gaze of death"; 2474. done(DIED); 2475. } 2476. } 2477. break; 2478. case AD_PHYS: 2479. if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && !mtmp->mspec_used && rn2(3)) { 2480. if (Displaced && rn2(3)) { 2481. if (!Blind) pline("%s gazes at your displaced image!",Monnam(mtmp)); 2482. break; 2483. } 2484. if ((Invisible && rn2(3)) || rn2(4)) { 2485. if (!Blind) pline("%s gazes around, but misses you!",Monnam(mtmp)); 2486. break; 2487. } 2488. if (!Blind) pline("%s gazes directly at you!",Monnam(mtmp)); 2489. pline("You are wracked with pains!"); 2490. mdamageu(mtmp, d(3,8)); 2491. } 2492. break; 2493. case AD_DRST: 2494. if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && !mtmp->mspec_used && rn2(5)) { 2495. pline("%s stares into your eyes...", Monnam(mtmp)); 2496. poisoned("The gaze", A_STR, mtmp->data->mname, 30); 2497. } 2498. break; 2499. case AD_PLYS: 2500. if(!mtmp->mcan && multi >= 0 && canseemon(mtmp) && mtmp->mcansee && !mtmp->mspec_used && rn2(5)) { 2501. pline("%s stares at you!", Monnam(mtmp)); 2502. if (Free_action) You("stiffen momentarily."); 2503. else { 2504. You("are frozen by %s!", mon_nam(mtmp)); 2505. nomovemsg = 0; 2506. nomul(-rnd(4)); 2507. exercise(A_DEX, FALSE); 2508. } 2509. } 2510. break; 2511. case AD_TLPT: 2512. if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && !mtmp->mspec_used && rn2(5)) { 2513. pline("%s stares blinkingly at you!", Monnam(mtmp)); 2514. if(flags.verbose) 2515. Your("position suddenly seems very uncertain!"); 2516. tele(); 2517. } 2518. break; 2519. default: impossible("Gaze attack %d?", mattk->adtyp); 2520. break; 2521. } 2522. return(0); 2523. } 2524. 2525. #endif /* OVLB */ 2526. #ifdef OVL1 2527. 2528. void 2529. mdamageu(mtmp, n) /* mtmp hits you for n points damage */ 2530. register struct monst *mtmp; 2531. register int n; 2532. { 2533. 2534. if (Invulnerable) n=0; 2535. if (n == 0) { 2536. pline("You are unharmed."); 2537. return; 2538. } 2539. 2540. /* WAC For consistency...DO be careful using techniques ;B */ 2541. if (mtmp->mtame != 0 && tech_inuse(T_PRIMAL_ROAR)) { 2542. n *= 2; /* Double Damage! */ 2543. } 2544. 2545. #ifdef SHOW_DMG 2546. if (flags.showdmg) pline("[%d pts.]", n); 2547. #endif 2548. flags.botl = 1; /* This needs to be AFTER the pline for botl to be 2549. * updated correctly -- Kelly Bailey 2550. */ 2551. 2552. if (Upolyd) { 2553. u.mh -= n; 2554. if (u.mh < 1) { 2555. if (Polymorph_control || !rn2(3)) { 2556. u.uhp -= mons[u.umonnum].mlevel; 2557. u.uhpmax -= mons[u.umonnum].mlevel; 2558. if (u.uhpmax < 1) u.uhpmax = 1; 2559. } 2560. rehumanize(); 2561. } 2562. } else { 2563. u.uhp -= n; 2564. if(u.uhp < 1) done_in_by(mtmp); 2565. } 2566. } 2567. 2568. #endif /* OVL1 */ 2569. #ifdef OVLB 2570. 2571. STATIC_OVL void 2572. urustm(mon, obj) 2573. register struct monst *mon; 2574. register struct obj *obj; 2575. { 2576. boolean vis; 2577. boolean is_acid; 2578. 2579. if (!mon || !obj) return; /* just in case */ 2580. if (dmgtype(youmonst.data, AD_CORR)) 2581. is_acid = TRUE; 2582. else if (dmgtype(youmonst.data, AD_RUST)) 2583. is_acid = FALSE; 2584. else 2585. return; 2586. 2587. vis = cansee(mon->mx, mon->my); 2588. 2589. if ((is_acid ? is_corrodeable(obj) : is_rustprone(obj)) && 2590. (is_acid ? obj->oeroded2 : obj->oeroded) < MAX_ERODE) { 2591. if (obj->greased || obj->oerodeproof || (obj->blessed && rn2(3))) { 2592. if (vis) pline("Somehow, %s weapon is not affected.", 2593. s_suffix(mon_nam(mon))); 2594. if (obj->greased && !rn2(2)) obj->greased = 0; 2595. } else { 2596. if (vis) pline("%s %s%s!", 2597. s_suffix(Monnam(mon)), 2598. aobjnam(obj, (is_acid ? "corrode" : "rust")), 2599. (is_acid ? obj->oeroded2 : obj->oeroded) 2600. ? " further" : ""); 2601. if (is_acid) obj->oeroded2++; 2602. else obj->oeroded++; 2603. } 2604. } 2605. } 2606. 2607. #endif /* OVLB */ 2608. #ifdef OVL1 2609. 2610. int 2611. could_seduce(magr,mdef,mattk) 2612. struct monst *magr, *mdef; 2613. struct attack *mattk; 2614. /* returns 0 if seduction impossible, 2615. * 1 if fine, 2616. * 2 if wrong gender for nymph */ 2617. { 2618. register struct permonst *pagr; 2619. boolean agrinvis, defperc; 2620. xchar genagr, gendef; 2621. 2622. if (is_animal(magr->data)) return (0); 2623. if(magr == &youmonst) { 2624. pagr = youmonst.data; 2625. agrinvis = (Invis != 0); 2626. genagr = poly_gender(); 2627. } else { 2628. pagr = magr->data; 2629. agrinvis = magr->minvis; 2630. genagr = gender(magr); 2631. } 2632. if(mdef == &youmonst) { 2633. defperc = (See_invisible != 0); 2634. gendef = poly_gender(); 2635. } else { 2636. defperc = perceives(mdef->data); 2637. gendef = gender(mdef); 2638. } 2639. 2640. if(agrinvis && !defperc 2641. #ifdef SEDUCE 2642. && mattk && mattk->adtyp != AD_SSEX 2643. #endif 2644. ) 2645. return 0; 2646. 2647. if(pagr->mlet != S_NYMPH 2648. && ((pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS]) 2649. #ifdef SEDUCE 2650. || (mattk && mattk->adtyp != AD_SSEX) 2651. #endif 2652. )) 2653. return 0; 2654. 2655. if(genagr == 1 - gendef) 2656. return 1; 2657. else 2658. return (pagr->mlet == S_NYMPH) ? 2 : 0; 2659. } 2660. 2661. #endif /* OVL1 */ 2662. #ifdef OVLB 2663. 2664. #ifdef SEDUCE 2665. /* Returns 1 if monster teleported */ 2666. int 2667. doseduce(mon) 2668. register struct monst *mon; 2669. { 2670. register struct obj *ring, *nring; 2671. boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */ 2672. char qbuf[QBUFSZ]; 2673. 2674. if (mon->mcan || mon->mspec_used) { 2675. pline("%s acts as though %s has got a %sheadache.", 2676. Monnam(mon), mhe(mon), 2677. mon->mcan ? "severe " : ""); 2678. return 0; 2679. } 2680. 2681. if (unconscious()) { 2682. pline("%s seems dismayed at your lack of response.", 2683. Monnam(mon)); 2684. return 0; 2685. } 2686. 2687. if (Blind) pline("It caresses you..."); 2688. else You_feel("very attracted to %s.", mon_nam(mon)); 2689. 2690. for(ring = invent; ring; ring = nring) { 2691. nring = ring->nobj; 2692. if (ring->otyp != RIN_ADORNMENT) continue; 2693. if (fem) { 2694. if (rn2(20) < ACURR(A_CHA)) { 2695. Sprintf(qbuf, "\"That %s looks pretty. May I have it?\"", 2696. safe_qbuf("",sizeof("\"That looks pretty. May I have it?\""), 2697. xname(ring), simple_typename(ring->otyp), "ring")); 2698. makeknown(RIN_ADORNMENT); 2699. if (yn(qbuf) == 'n') continue; 2700. } else pline("%s decides she'd like your %s, and takes it.", 2701. Blind ? "She" : Monnam(mon), xname(ring)); 2702. makeknown(RIN_ADORNMENT); 2703. if (ring==uleft || ring==uright) Ring_gone(ring); 2704. if (ring==uwep) setuwep((struct obj *)0, FALSE); 2705. if (ring==uswapwep) setuswapwep((struct obj *)0, FALSE); 2706. if (ring==uquiver) setuqwep((struct obj *)0); 2707. freeinv(ring); 2708. (void) mpickobj(mon,ring); 2709. } else { 2710. char buf[BUFSZ]; 2711. 2712. if (uleft && uright && uleft->otyp == RIN_ADORNMENT 2713. && uright->otyp==RIN_ADORNMENT) 2714. break; 2715. if (ring==uleft || ring==uright) continue; 2716. if (rn2(20) < ACURR(A_CHA)) { 2717. Sprintf(qbuf,"\"That %s looks pretty. Would you wear it for me?\"", 2718. safe_qbuf("", 2719. sizeof("\"That looks pretty. Would you wear it for me?\""), 2720. xname(ring), simple_typename(ring->otyp), "ring")); 2721. makeknown(RIN_ADORNMENT); 2722. if (yn(qbuf) == 'n') continue; 2723. } else { 2724. pline("%s decides you'd look prettier wearing your %s,", 2725. Blind ? "He" : Monnam(mon), xname(ring)); 2726. pline("and puts it on your finger."); 2727. } 2728. makeknown(RIN_ADORNMENT); 2729. if (!uright) { 2730. pline("%s puts %s on your right %s.", 2731. Blind ? "He" : Monnam(mon), the(xname(ring)), body_part(HAND)); 2732. setworn(ring, RIGHT_RING); 2733. } else if (!uleft) { 2734. pline("%s puts %s on your left %s.", 2735. Blind ? "He" : Monnam(mon), the(xname(ring)), body_part(HAND)); 2736. setworn(ring, LEFT_RING); 2737. } else if (uright && uright->otyp != RIN_ADORNMENT) { 2738. Strcpy(buf, xname(uright)); 2739. pline("%s replaces your %s with your %s.", 2740. Blind ? "He" : Monnam(mon), buf, xname(ring)); 2741. Ring_gone(uright); 2742. setworn(ring, RIGHT_RING); 2743. } else if (uleft && uleft->otyp != RIN_ADORNMENT) { 2744. Strcpy(buf, xname(uleft)); 2745. pline("%s replaces your %s with your %s.", 2746. Blind ? "He" : Monnam(mon), buf, xname(ring)); 2747. Ring_gone(uleft); 2748. setworn(ring, LEFT_RING); 2749. } else impossible("ring replacement"); 2750. Ring_on(ring); 2751. prinv((char *)0, ring, 0L); 2752. } 2753. } 2754. 2755. if (!uarmc && !uarmf && !uarmg && !uarms && !uarmh 2756. #ifdef TOURIST 2757. && !uarmu 2758. #endif 2759. ) 2760. pline("%s murmurs sweet nothings into your ear.", 2761. Blind ? (fem ? "She" : "He") : Monnam(mon)); 2762. else 2763. pline("%s murmurs in your ear, while helping you undress.", 2764. Blind ? (fem ? "She" : "He") : Monnam(mon)); 2765. mayberem(uarmc, cloak_simple_name(uarmc)); 2766. if(!uarmc) 2767. mayberem(uarm, "suit"); 2768. mayberem(uarmf, "boots"); 2769. if(!uwep || !welded(uwep)) 2770. mayberem(uarmg, "gloves"); 2771. /* 2772. * STEPHEN WHITE'S NEW CODE 2773. * 2774. * This will cause a game crash should the if statment be removed. 2775. * It will try to de-referance a pointer that doesn't exist should 2776. * the player not have a shield 2777. */ 2778. 2779. if (uarms) mayberem(uarms, "shield"); 2780. mayberem(uarmh, "helmet"); 2781. #ifdef TOURIST 2782. if(!uarmc && !uarm) 2783. mayberem(uarmu, "shirt"); 2784. #endif 2785. 2786. if (uarm || uarmc) { 2787. verbalize("You're such a %s; I wish...", 2788. flags.female ? "sweet lady" : "nice guy"); 2789. if (!tele_restrict(mon)) (void) rloc(mon, FALSE); 2790. return 1; 2791. } 2792. if (u.ualign.type == A_CHAOTIC) 2793. adjalign(1); 2794. 2795. /* by this point you have discovered mon's identity, blind or not... */ 2796. pline("Time stands still while you and %s lie in each other's arms...", 2797. noit_mon_nam(mon)); 2798. /* Well, IT happened ... */ 2799. u.uconduct.celibacy++; 2800. 2801. if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) { 2802. /* Don't bother with mspec_used here... it didn't get tired! */ 2803. pline("%s seems to have enjoyed it more than you...", 2804. noit_Monnam(mon)); 2805. switch (rn2(5)) { 2806. case 0: You_feel("drained of energy."); 2807. u.uen = 0; 2808. u.uenmax -= rnd(Half_physical_damage ? 5 : 10); 2809. exercise(A_CON, FALSE); 2810. if (u.uenmax < 0) u.uenmax = 0; 2811. break; 2812. case 1: You("are down in the dumps."); 2813. (void) adjattrib(A_CON, -1, TRUE); 2814. exercise(A_CON, FALSE); 2815. flags.botl = 1; 2816. break; 2817. case 2: Your("senses are dulled."); 2818. (void) adjattrib(A_WIS, -1, TRUE); 2819. exercise(A_WIS, FALSE); 2820. flags.botl = 1; 2821. break; 2822. case 3: 2823. if (!Drain_resistance) { 2824. You_feel("out of shape."); 2825. losexp("overexertion", FALSE); 2826. } else { 2827. You("have a curious feeling..."); 2828. } 2829. break; 2830. case 4: { 2831. int tmp; 2832. You_feel("exhausted."); 2833. exercise(A_STR, FALSE); 2834. tmp = rn1(10, 6); 2835. if(Half_physical_damage) tmp = (tmp+1) / 2; 2836. losehp(tmp, "exhaustion", KILLED_BY); 2837. break; 2838. } 2839. } 2840. } else { 2841. mon->mspec_used = rnd(100); /* monster is worn out */ 2842. You("seem to have enjoyed it more than %s...", 2843. noit_mon_nam(mon)); 2844. switch (rn2(5)) { 2845. case 0: You_feel("raised to your full potential."); 2846. exercise(A_CON, TRUE); 2847. u.uen = (u.uenmax += rnd(5)); 2848. break; 2849. case 1: You_feel("good enough to do it again."); 2850. (void) adjattrib(A_CON, 1, TRUE); 2851. exercise(A_CON, TRUE); 2852. flags.botl = 1; 2853. break; 2854. case 2: You("will always remember %s...", noit_mon_nam(mon)); 2855. (void) adjattrib(A_WIS, 1, TRUE); 2856. exercise(A_WIS, TRUE); 2857. flags.botl = 1; 2858. break; 2859. case 3: pline("That was a very educational experience."); 2860. pluslvl(FALSE); 2861. exercise(A_WIS, TRUE); 2862. break; 2863. case 4: You_feel("restored to health!"); 2864. u.uhp = u.uhpmax; 2865. if (Upolyd) u.mh = u.mhmax; 2866. exercise(A_STR, TRUE); 2867. flags.botl = 1; 2868. break; 2869. } 2870. } 2871. 2872. if (mon->mtame) /* don't charge */ ; 2873. else if (rn2(20) < ACURR(A_CHA)) { 2874. pline("%s demands that you pay %s, but you refuse...", 2875. noit_Monnam(mon), 2876. Blind ? (fem ? "her" : "him") : mhim(mon)); 2877. } else if (u.umonnum == PM_LEPRECHAUN) 2878. pline("%s tries to take your money, but fails...", 2879. noit_Monnam(mon)); 2880. else { 2881. #ifndef GOLDOBJ 2882. long cost; 2883. 2884. if (u.ugold > (long)LARGEST_INT - 10L) 2885. cost = (long) rnd(LARGEST_INT) + 500L; 2886. else 2887. cost = (long) rnd((int)u.ugold + 10) + 500L; 2888. if (mon->mpeaceful) { 2889. cost /= 5L; 2890. if (!cost) cost = 1L; 2891. } 2892. if (cost > u.ugold) cost = u.ugold; 2893. if (!cost) verbalize("It's on the house!"); 2894. else { 2895. pline("%s takes %ld %s for services rendered!", 2896. noit_Monnam(mon), cost, currency(cost)); 2897. u.ugold -= cost; 2898. mon->mgold += cost; 2899. flags.botl = 1; 2900. } 2901. #else 2902. long cost; 2903. long umoney = money_cnt(invent); 2904. 2905. if (umoney > (long)LARGEST_INT - 10L) 2906. cost = (long) rnd(LARGEST_INT) + 500L; 2907. else 2908. cost = (long) rnd((int)umoney + 10) + 500L; 2909. if (mon->mpeaceful) { 2910. cost /= 5L; 2911. if (!cost) cost = 1L; 2912. } 2913. if (cost > umoney) cost = umoney; 2914. if (!cost) verbalize("It's on the house!"); 2915. else { 2916. pline("%s takes %ld %s for services rendered!", 2917. noit_Monnam(mon), cost, currency(cost)); 2918. money2mon(mon, cost); 2919. flags.botl = 1; 2920. } 2921. #endif 2922. } 2923. if (!rn2(25)) mon->mcan = 1; /* monster is worn out */ 2924. if (!tele_restrict(mon)) (void) rloc(mon, FALSE); 2925. return 1; 2926. } 2927. 2928. STATIC_OVL void 2929. mayberem(obj, str) 2930. register struct obj *obj; 2931. const char *str; 2932. { 2933. char qbuf[QBUFSZ]; 2934. 2935. if (!obj || !obj->owornmask) return; 2936. 2937. if (rn2(20) < ACURR(A_CHA)) { 2938. Sprintf(qbuf,"\"Shall I remove your %s, %s?\"", 2939. str, 2940. (!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart")); 2941. if (yn(qbuf) == 'n') return; 2942. } else { 2943. char hairbuf[BUFSZ]; 2944. 2945. Sprintf(hairbuf, "let me run my fingers through your %s", 2946. body_part(HAIR)); 2947. verbalize("Take off your %s; %s.", str, 2948. (obj == uarm) ? "let's get a little closer" : 2949. (obj == uarmc || obj == uarms) ? "it's in the way" : 2950. (obj == uarmf) ? "let me rub your feet" : 2951. (obj == uarmg) ? "they're too clumsy" : 2952. #ifdef TOURIST 2953. (obj == uarmu) ? "let me massage you" : 2954. #endif 2955. /* obj == uarmh */ 2956. hairbuf); 2957. } 2958. remove_worn_item(obj, TRUE); 2959. } 2960. #endif /* SEDUCE */ 2961. 2962. #endif /* OVLB */ 2963. 2964. #ifdef OVL1 2965. 2966. STATIC_OVL int 2967. passiveum(olduasmon,mtmp,mattk) 2968. struct permonst *olduasmon; 2969. register struct monst *mtmp; 2970. register struct attack *mattk; 2971. { 2972. int i, tmp; 2973. 2974. for(i = 0; ; i++) { 2975. if(i >= NATTK) return 1; 2976. if (olduasmon->mattk[i].aatyp == AT_NONE || 2977. olduasmon->mattk[i].aatyp == AT_BOOM) break; 2978. } 2979. if (olduasmon->mattk[i].damn) 2980. tmp = d((int)olduasmon->mattk[i].damn, 2981. (int)olduasmon->mattk[i].damd); 2982. else if(olduasmon->mattk[i].damd) 2983. tmp = d((int)olduasmon->mlevel+1, (int)olduasmon->mattk[i].damd); 2984. else 2985. tmp = 0; 2986. 2987. /* These affect the enemy even if you were "killed" (rehumanized) */ 2988. switch(olduasmon->mattk[i].adtyp) { 2989. case AD_ACID: 2990. if (!rn2(2)) { 2991. pline("%s is splashed by your acid!", Monnam(mtmp)); 2992. if (resists_acid(mtmp)) { 2993. pline("%s is not affected.", Monnam(mtmp)); 2994. tmp = 0; 2995. } 2996. } else tmp = 0; 2997. if (!rn2(30)) erode_armor(mtmp, TRUE); 2998. if (!rn2(6)) erode_obj(MON_WEP(mtmp), TRUE, TRUE); 2999. goto assess_dmg; 3000. case AD_STON: /* cockatrice */ 3001. { 3002. long protector = attk_protection((int)mattk->aatyp), 3003. wornitems = mtmp->misc_worn_check; 3004. 3005. /* wielded weapon gives same protection as gloves here */ 3006. if (MON_WEP(mtmp) != 0) wornitems |= W_ARMG; 3007. 3008. if (!resists_ston(mtmp) && (protector == 0L || 3009. (protector != ~0L && 3010. (wornitems & protector) != protector))) { 3011. if (poly_when_stoned(mtmp->data)) { 3012. mon_to_stone(mtmp); 3013. return (1); 3014. } 3015. pline("%s turns to stone!", Monnam(mtmp)); 3016. stoned = 1; 3017. xkilled(mtmp, 0); 3018. if (mtmp->mhp > 0) return 1; 3019. return 2; 3020. } 3021. return 1; 3022. } 3023. case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ 3024. if (otmp) { 3025. (void) drain_item(otmp); 3026. /* No message */ 3027. } 3028. return (1); 3029. default: 3030. break; 3031. } 3032. if (!Upolyd) return 1; 3033. 3034. /* These affect the enemy only if you are still a monster */ 3035. if (rn2(3)) switch(youmonst.data->mattk[i].adtyp) { 3036. case AD_PHYS: 3037. if (youmonst.data->mattk[i].aatyp == AT_BOOM) { 3038. You("explode!"); 3039. /* KMH, balance patch -- this is okay with unchanging */ 3040. rehumanize(); 3041. goto assess_dmg; 3042. } 3043. break; 3044. case AD_PLYS: /* Floating eye */ 3045. if (tmp > 127) tmp = 127; 3046. if (u.umonnum == PM_FLOATING_EYE) { 3047. if (!rn2(4)) tmp = 127; 3048. if (mtmp->mcansee && haseyes(mtmp->data) && rn2(3) && 3049. (perceives(mtmp->data) || !Invis)) { 3050. if (Blind) 3051. pline("As a blind %s, you cannot defend yourself.", 3052. youmonst.data->mname); 3053. else { 3054. if (mon_reflects(mtmp, 3055. "Your gaze is reflected by %s %s.")) 3056. return 1; 3057. pline("%s is frozen by your gaze!", Monnam(mtmp)); 3058. mtmp->mcanmove = 0; 3059. mtmp->mfrozen = tmp; 3060. return 3; 3061. } 3062. } 3063. } else { /* gelatinous cube */ 3064. pline("%s is frozen by you.", Monnam(mtmp)); 3065. mtmp->mcanmove = 0; 3066. mtmp->mfrozen = tmp; 3067. return 3; 3068. } 3069. return 1; 3070. case AD_COLD: /* Brown mold or blue jelly */ 3071. if (resists_cold(mtmp)) { 3072. shieldeff(mtmp->mx, mtmp->my); 3073. pline("%s is mildly chilly.", Monnam(mtmp)); 3074. golemeffects(mtmp, AD_COLD, tmp); 3075. tmp = 0; 3076. break; 3077. } 3078. pline("%s is suddenly very cold!", Monnam(mtmp)); 3079. u.mh += tmp / 2; 3080. if (u.mhmax < u.mh) u.mhmax = u.mh; 3081. if (u.mhmax > ((youmonst.data->mlevel+1) * 8)) 3082. (void)split_mon(&youmonst, mtmp); 3083. break; 3084. case AD_STUN: /* Yellow mold */ 3085. if (!mtmp->mstun) { 3086. mtmp->mstun = 1; 3087. pline("%s %s.", Monnam(mtmp), 3088. makeplural(stagger(mtmp->data, "stagger"))); 3089. } 3090. tmp = 0; 3091. break; 3092. case AD_FIRE: /* Red mold */ 3093. if (resists_fire(mtmp)) { 3094. shieldeff(mtmp->mx, mtmp->my); 3095. pline("%s is mildly warm.", Monnam(mtmp)); 3096. golemeffects(mtmp, AD_FIRE, tmp); 3097. tmp = 0; 3098. break; 3099. } 3100. pline("%s is suddenly very hot!", Monnam(mtmp)); 3101. break; 3102. case AD_ELEC: 3103. if (resists_elec(mtmp)) { 3104. shieldeff(mtmp->mx, mtmp->my); 3105. pline("%s is slightly tingled.", Monnam(mtmp)); 3106. golemeffects(mtmp, AD_ELEC, tmp); 3107. tmp = 0; 3108. break; 3109. } 3110. pline("%s is jolted with your electricity!", Monnam(mtmp)); 3111. break; 3112. default: tmp = 0; 3113. break; 3114. } 3115. else tmp = 0; 3116. 3117. assess_dmg: 3118. if((mtmp->mhp -= tmp) <= 0) { 3119. pline("%s dies!", Monnam(mtmp)); 3120. xkilled(mtmp,0); 3121. if (mtmp->mhp > 0) return 1; 3122. return 2; 3123. } 3124. return 1; 3125. } 3126. 3127. #endif /* OVL1 */ 3128. #ifdef OVLB 3129. 3130. #include "edog.h" 3131. struct monst * 3132. cloneu() 3133. { 3134. register struct monst *mon; 3135. int mndx = monsndx(youmonst.data); 3136. 3137. if (u.mh <= 1) return(struct monst *)0; 3138. if (mvitals[mndx].mvflags & G_EXTINCT) return(struct monst *)0; 3139. mon = makemon(youmonst.data, u.ux, u.uy, NO_MINVENT|MM_EDOG); 3140. mon = christen_monst(mon, plname); 3141. initedog(mon); 3142. mon->m_lev = youmonst.data->mlevel; 3143. mon->mhpmax = u.mhmax; 3144. mon->mhp = u.mh / 2; 3145. u.mh -= mon->mhp; 3146. flags.botl = 1; 3147. return(mon); 3148. } 3149. 3150. #endif /* OVLB */ 3151. 3152. /*mhitu.c*/