abstract
| - Below is the full text to mhitu.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/mhitu.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: \@(#)mhitu.c 3.0 88/10/28 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #ifdef NAMED_ITEMS 7. # include "artifact.h" 8. #endif 9. 10. static struct obj *otmp; 11. #ifdef POLYSELF 12. static void urustm P((struct monst *, struct obj *)); 13. static int passiveum P((struct permonst *, struct monst *)); 14. #endif 15. #ifdef SEDUCE 16. static void mayberem P((struct obj *, char *)); 17. #endif 18. static int hitmu P((struct monst *,struct attack *)); 19. static int gulpmu P((struct monst *,struct attack *)); 20. static int explmu P((struct monst *,struct attack *)); 21. static int gazemu P((struct monst *,struct attack *)); 22. 23. #ifdef POLYSELF 24. boolean 25. /* also needed in uhitm.c */ 26. #else 27. static boolean 28. #endif 29. incompatible(mon) 30. register struct monst *mon; 31. { 32. return(poly_gender() != 1-gender(mon)); 33. } 34. 35. boolean 36. is_nymph(mon) 37. register struct monst *mon; 38. { 39. return( mon->data->mlet == S_NYMPH ); 40. } 41. 42. boolean 43. sp_melee(mon) 44. register struct monst *mon; 45. { 46. return( 47. #ifdef SEDUCE 48. (mon->data == &mons[PM_SUCCUBUS] && !mon->minvis) || 49. (mon->data == &mons[PM_INCUBUS] && !mon->minvis) || 50. #endif 51. is_nymph(mon)); 52. } 53. 54. static void 55. hitmsg(mtmp, attyp) 56. register struct monst *mtmp; 57. register uchar attyp; 58. { 59. /* Note: if opposite gender, "seductively" */ 60. /* If same gender, "engagingly" for nymph, normal msg for others */ 61. if(sp_melee(mtmp) && !mtmp->mcan) { 62. if(!is_nymph(mtmp) && incompatible(mtmp)) goto strike; 63. kludge("%s %s you %s.", Monnam(mtmp), 64. Blind ? "talks to" : "smiles at", 65. incompatible(mtmp) ? "engagingly" : "seductively"); 66. } else 67. strike: 68. switch (attyp) { 69. case AT_BITE: 70. kludge("%s bites!", Monnam(mtmp)); 71. break; 72. case AT_KICK: 73. #ifdef POLYSELF 74. kludge("%s kicks%c", Monnam(mtmp), thick_skinned(uasmon) ? '.' : '!'); 75. #else 76. kludge("%s kicks!", Monnam(mtmp)); 77. #endif 78. break; 79. case AT_STNG: 80. kludge("%s stings!", Monnam(mtmp)); 81. break; 82. case AT_BUTT: 83. kludge("%s butts!", Monnam(mtmp)); 84. break; 85. case AT_TUCH: 86. kludge("%s touches you!", Monnam(mtmp)); 87. break; 88. default: 89. kludge("%s hits!", Monnam(mtmp)); 90. } 91. } 92. 93. static void 94. missmu(mtmp, nearmiss) /* monster missed you */ 95. register struct monst *mtmp; 96. register boolean nearmiss; 97. { 98. if(sp_melee(mtmp) && !mtmp->mcan) { 99. if(!is_nymph(mtmp) && incompatible(mtmp)) goto strike; 100. kludge("%s pretends to be friendly.", Monnam(mtmp)); 101. } else { 102. strike: 103. if (!flags.verbose || !nearmiss) 104. kludge("%s misses.", Monnam(mtmp)); 105. else 106. kludge("%s just misses!", Monnam(mtmp)); 107. } 108. } 109. 110. static void 111. mswings(mtmp, otemp) /* monster swings obj */ 112. register struct monst *mtmp; 113. register struct obj *otemp; 114. { 115. if (!flags.verbose || Blind || otemp->olet != WEAPON_SYM) return; 116. pline("%s %s %s %s.", Monnam(mtmp), 117. (otemp->otyp == SPEAR || 118. otemp->otyp == LANCE || 119. otemp->otyp == GLAIVE || 120. otemp->otyp == TRIDENT) ? "thrusts" : "swings", 121. is_female(mtmp) ? "her" : 122. is_human(mtmp->data) ? "his" : "its", 123. xname(otemp)); 124. } 125. 126. static void 127. wildmiss(mtmp) /* monster attacked your displaced image */ 128. register struct monst *mtmp; 129. { 130. if (!flags.verbose) return; 131. if (!cansee(mtmp->mx, mtmp->my)) return; 132. /* maybe it's attacking an image around the corner? */ 133. if(Invis && !perceives(mtmp->data)) { 134. if(sp_melee(mtmp) && !mtmp->mcan) { 135. if(!is_nymph(mtmp) && incompatible(mtmp)) goto strike; 136. kludge("%s tries to touch you and misses!", Monnam(mtmp)); 137. } else 138. strike: 139. switch(rn2(3)) { 140. case 0: kludge("%s swings wildly and misses!", Monnam(mtmp)); 141. break; 142. case 1: kludge("%s attacks a spot beside you.", Monnam(mtmp)); 143. break; 144. case 2: kludge("%s strikes at thin air!", Monnam(mtmp)); 145. break; 146. default:kludge("%s swings wildly!", Monnam(mtmp)); 147. break; 148. } 149. } 150. else if(Displaced) { 151. if(sp_melee(mtmp) && !mtmp->mcan) { 152. if(!is_nymph(mtmp) && incompatible(mtmp)) goto strikem; 153. kludge("%s smiles %s at your %sdisplaced image...", 154. Monnam(mtmp), 155. incompatible(mtmp) ? "engagingly" : "seductively", 156. Invis ? "invisible " : ""); 157. } else 158. strikem: 159. kludge("%s strikes at your %sdisplaced image and misses you!", 160. /* Note: if you're both invisible and displaced, 161. * only monsters which see invisible will attack your 162. * displaced image, since the displaced image is also 163. * invisible. 164. */ 165. Monnam(mtmp), 166. Invis ? "invisible " : ""); 167. } 168. else impossible("%s attacks you without knowing your location?", 169. Monnam(mtmp)); 170. } 171. 172. static void 173. regurgitates(mtmp) 174. register struct monst *mtmp; 175. { 176. u.ux = mtmp->mx; 177. u.uy = mtmp->my; 178. u.uswallow = 0; 179. u.ustuck = 0; 180. mnexto(mtmp); 181. setsee(); 182. docrt(); 183. spoteffects(); 184. /* to cover for a case where mtmp is not in a next square */ 185. if(um_dist(mtmp->mx,mtmp->my,1)) 186. pline("Brrooaa... You land hard at some distance."); 187. } 188. 189. /* 190. * mattacku: monster attacks you 191. * returns 1 if monster dies (e.g. "yellow light"), 0 otherwise 192. * Note: if you're displaced or invisible the monster might attack the 193. * wrong position... 194. * Assumption: it's attacking you or an empty square; if there's another 195. * monster which it attacks by mistake, the caller had better 196. * take care of it... 197. */ 198. int 199. mattacku(mtmp) 200. register struct monst *mtmp; 201. { 202. struct attack *mattk; 203. int i, j, tmp, sum[NATTK]; 204. struct permonst *mdat = mtmp->data; 205. boolean ranged = (dist(mtmp->mx, mtmp->my) > 3); 206. /* Is it near you? Affects your actions */ 207. boolean range2 = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) > 3); 208. /* Does it think it's near you? Affects its actions */ 209. boolean foundyou = (mtmp->mux==u.ux && mtmp->muy==u.uy); 210. /* Is it attacking you or your image? */ 211. boolean youseeit = (cansee(mtmp->mx, mtmp->my)); 212. /* Necessary since if it's attacking your image around a 213. * corner, you might not see it 214. */ 215. 216. if(!ranged) nomul(0); 217. if(mtmp->mhp <= 0) return(0); 218. 219. /* If swallowed, can only be affected by u.ustuck */ 220. if(u.uswallow) { 221. if(mtmp != u.ustuck) 222. return(0); 223. u.ustuck->mux = u.ux; 224. u.ustuck->muy = u.uy; 225. range2 = 0; 226. foundyou = 1; 227. /* This is not impossible! */ 228. /* If the swallowing monster changes into a monster 229. * that is not capable of swallowing you, you get 230. * regurgitated - dgk 231. */ 232. for(i = 0; i < NATTK; i++) 233. if(mdat->mattk[i].aatyp == AT_ENGL) goto doattack; 234. 235. You("get regurgitated!"); 236. regurgitates(mtmp); 237. return(0); 238. } 239. doattack: 240. #ifdef POLYSELF 241. if (u.uundetected && !range2 && foundyou) { 242. u.uundetected = 0; 243. if (u.usym == S_PIERCER) { 244. coord cc; /* maybe we need a unexto() function? */ 245. 246. unpmon(mtmp); 247. levl[mtmp->mx][mtmp->my].mmask = 0; 248. mtmp->mx = u.ux; mtmp->my = u.uy; 249. levl[mtmp->mx][mtmp->my].mmask = 1; 250. pmon(mtmp); 251. enexto(&cc, u.ux, u.uy); 252. /* Luckily piercers cannot walk through walls, so this 253. * will work. If they can (i.e., if someone adds a potion 254. * of phasing), we gotta change this... 255. */ 256. teleds(cc.x, cc.y); 257. You("fall from the ceiling!"); 258. if (is_mercenary(mtmp->data) && m_carrying(mtmp,HELMET)) { 259. kludge("Your blow glances off %s's helmet.", 260. mon_nam(mtmp)); 261. } else { 262. if (3 + mtmp->data->ac <= rnd(20)) { 263. kludge("%s is hit by a falling piercer (you)!", 264. Monnam(mtmp)); 265. if ((mtmp->mhp -= d(3,6)) < 1) 266. killed(mtmp); 267. } else 268. kludge("%s is almost hit by a falling piercer (you)!", 269. Monnam(mtmp)); 270. } 271. } else { 272. if (Blind) pline("It tries to move where you are hiding."); 273. else 274. pline("Wait, %s! There's a %s named %s hiding under %s!", 275. mtmp->mnamelth ? NAME(mtmp) : mtmp->data->mname, 276. uasmon->mname, plname, 277. levl[u.ux][u.uy].omask ? doname(o_at(u.ux,u.uy)) : 278. "some gold"); 279. prme(); 280. } 281. return(0); 282. } 283. if (u.usym == S_MIMIC_DEF && !range2 && foundyou) { 284. if (Blind) pline("It gets stuck on you."); 285. else pline("Wait, %s! That's a %s named %s!", 286. mtmp->mnamelth ? NAME(mtmp) : mtmp->data->mname, 287. uasmon->mname, plname); 288. u.ustuck = mtmp; 289. u.usym = S_MIMIC; 290. prme(); 291. return(0); 292. } 293. #endif 294. /* Work out the armor class differential */ 295. tmp = u.uac + 10; /* tmp ~= 0 - 20 */ 296. /* give people with Ac < -9 at least some vulnerability */ 297. /* negative AC gives an actual AC of somewhere from -1 to the AC */ 298. if (tmp < 10) tmp = 10 - rnd(10-tmp); 299. tmp += mtmp->m_lev; 300. if(multi < 0) tmp += 4; 301. if((Invis && !perceives(mdat)) || !mtmp->mcansee) 302. tmp -= 2; 303. if(mtmp->mtrapped) tmp -= 2; 304. if(tmp <= 0) tmp = 1; 305. 306. /* make eels visible the moment they hit/miss us */ 307. if(mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx,mtmp->my)) { 308. mtmp->minvis = 0; 309. pmon(mtmp); 310. } 311. 312. /* Special demon handling code */ 313. if(!mtmp->cham && is_demon(mdat) && !range2 314. #ifdef HARD 315. && mtmp->data != &mons[PM_BALROG] 316. && mtmp->data != &mons[PM_SUCCUBUS] 317. && mtmp->data != &mons[PM_INCUBUS] 318. #endif 319. ) 320. if(!mtmp->mcan && !rn2(13)) dsummon(mdat); 321. 322. /* Special lycanthrope handling code */ 323. if(!mtmp->cham && is_were(mdat) && !range2) { 324. 325. if(is_human(mdat)) { 326. if(!rn2(5 - (night() * 2)) && !mtmp->mcan) new_were(mtmp); 327. } else if(!rn2(30) && !mtmp->mcan) new_were(mtmp); 328. 329. if(!rn2(10) && !mtmp->mcan) { 330. if(!Blind) { 331. pline("%s summons help!",youseeit ? 332. Monnam(mtmp) : "It"); 333. } else 334. You("feel hemmed in."); 335. /* Technically wrong; we really should check if you can see the 336. * help, but close enough... 337. */ 338. if (!were_summon(mdat,FALSE) && !Blind) 339. pline("But none comes."); 340. } 341. } 342. 343. for(i = 0; i < NATTK; i++) { 344. 345. mattk = &(mdat->mattk[i]); 346. switch(mattk->aatyp) { 347. case AT_CLAW: /* "hand to hand" attacks */ 348. case AT_KICK: 349. case AT_BITE: 350. case AT_STNG: 351. case AT_TUCH: 352. case AT_BUTT: 353. if(!range2) { 354. if (!foundyou) { 355. wildmiss(mtmp); 356. sum[i] = 0; 357. } else if(tmp > (j = rnd(20+i))) 358. #ifdef POLYSELF 359. if (mattk->aatyp == AT_KICK && 360. thick_skinned(uasmon)) sum[i] = 0; 361. else 362. #endif 363. sum[i] = hitmu(mtmp, mattk); 364. else { 365. missmu(mtmp, (tmp == j)); 366. sum[i] = 0; 367. } 368. } else sum[i] = 0; 369. break; 370. 371. case AT_HUGS: /* automatic if prev two attacks succeed */ 372. /* Note: if displaced, prev attacks never succeeded */ 373. if(!range2) { 374. if(sum[i-1] && sum[i-2]) 375. sum[i]= hitmu(mtmp, mattk); 376. else sum[i] = 0; 377. } else sum[i] = 0; 378. break; 379. 380. case AT_GAZE: /* can affect you either ranged or not */ 381. if (!youseeit) sum[i] = 0; 382. /* Displaced and around a corner so not visible */ 383. else sum[i] = gazemu(mtmp, mattk); 384. break; 385. 386. case AT_EXPL: /* automatic hit if next to, and aimed at you */ 387. if(!range2) { 388. if (!foundyou) { 389. if (!mtmp->mcan) { 390. pline("%s explodes at a spot in thin air!", 391. youseeit ? Monnam(mtmp) : "It"); 392. mondead(mtmp); 393. sum[i] = 2; 394. } else sum[i] = 0; 395. } else sum[i] = explmu(mtmp, mattk); 396. } else sum[i] = 0; 397. break; 398. 399. case AT_ENGL: 400. if (!range2) { 401. if(foundyou) { 402. if(u.uswallow || tmp > (j = rnd(20+i))) { 403. /* Force swallowing monster to be 404. * displayed even when player is 405. * moving away */ 406. nscr(); 407. sum[i] = gulpmu(mtmp, mattk); 408. } else { 409. missmu(mtmp, (tmp == j)); 410. sum[i] = 0; 411. } 412. } else pline("%s gulps some air!", youseeit ? 413. Monnam(mtmp) : "It"); 414. } else sum[i] = 0; 415. break; 416. case AT_BREA: 417. if(range2) sum[i] = breamu(mtmp, mattk); 418. /* Note: breamu takes care of displacement */ 419. else sum[i] = 0; 420. break; 421. case AT_SPIT: 422. if(range2) sum[i] = spitmu(mtmp); 423. /* Note: spitmu takes care of displacement */ 424. else sum[i] = 0; 425. break; 426. case AT_WEAP: 427. if(range2) { 428. #ifdef REINCARNATION 429. if (dlevel != rogue_level) 430. #endif 431. sum[i] = thrwmu(mtmp); 432. } else { 433. if (!foundyou) { 434. wildmiss(mtmp); 435. sum[i] = 0; 436. } else { 437. set_uasmon(); 438. otmp = select_hwep(mtmp); 439. if(otmp) { 440. tmp += hitval(otmp, uasmon); 441. mswings(mtmp, otmp); 442. } 443. if(tmp > (j = rnd(20+i))) 444. sum[i] = hitmu(mtmp, mattk); 445. else { 446. missmu(mtmp, (tmp == j)); 447. sum[i] = 0; 448. } 449. } 450. } 451. break; 452. case AT_MAGC: 453. if(!range2) { 454. if (!foundyou) { 455. pline("%s casts a spell at thin air!", 456. youseeit ? Monnam(mtmp) : "It"); 457. sum[i] = 0; 458. /* Not totally right since castmu allows other 459. * spells, such as the monster healing itself, 460. * that should work even when not next to you-- 461. * but the previous code was just as wrong. 462. * --KAA 463. */ 464. } else sum[i] = castmu(mtmp, mattk); 465. } else sum[i] = buzzmu(mtmp, mattk); 466. break; 467. 468. default: /* no attack */ 469. sum[i] = 0; 470. break; 471. } 472. if(flags.botl) bot(); 473. if(sum[i] == 2) return(1); /* attacker dead */ 474. } 475. return(0); 476. } 477. 478. /* 479. * hitmu: monster hits you 480. * returns 2 if monster dies (e.g. "yellow light"), 0 otherwise 481. */ 482. static 483. int 484. hitmu(mtmp, mattk) 485. register struct monst *mtmp; 486. register struct attack *mattk; 487. { 488. register struct permonst *mdat = mtmp->data; 489. register int dmg, ctmp, ptmp; 490. register boolean getbronze; 491. char buf[BUFSZ]; 492. #ifdef POLYSELF 493. struct permonst *olduasmon = uasmon; 494. int res; 495. #endif 496. 497. /* If the monster is undetected & hits you. You should know where 498. * the attack came from. 499. */ 500. if(mtmp->mhide && mtmp->mundetected) { 501. mtmp->mundetected = 0; 502. if(!(Blind ? Telepat : (HTelepat & WORN_HELMET))) { 503. register struct obj *obj; 504. 505. if(levl[mtmp->mx][mtmp->my].omask == 1) { 506. if(obj = o_at(mtmp->mx,mtmp->my)) 507. pline("%s was hidden under %s!", 508. Xmonnam(mtmp), doname(obj)); 509. } else if (levl[mtmp->mx][mtmp->my].gmask == 1) 510. pline("%s was hidden under some gold!", 511. Xmonnam(mtmp)); 512. } 513. } 514. 515. /* First determine the base damage done */ 516. dmg = d((int)mattk->damn, (int)mattk->damd); 517. if(is_undead(mdat) && midnight()) 518. dmg += d((int)mattk->damn, (int)mattk->damd); /* extra damage */ 519. 520. /* Next a cancellation factor */ 521. /* Use ctmp when the cancellation factor takes into account certain 522. * armor's special magic protection. Otherwise just use !mtmp->mcan. 523. */ 524. ctmp = !mtmp->mcan && 525. (!uarm || (rn2(3) >= objects[uarm->otyp].a_can) || !rn2(50)) 526. && (!uarmc || (rn2(3) >= objects[uarmc->otyp].a_can) || !rn2(50)); 527. 528. /* Now, adjust damages via resistances or specific attacks */ 529. switch(mattk->adtyp) { 530. case AD_PHYS: 531. if(mattk->aatyp == AT_HUGS 532. #ifdef POLYSELF 533. && !sticks(uasmon) 534. #endif 535. ) { 536. if(!u.ustuck && rn2(2)) { 537. u.ustuck = mtmp; 538. kludge("%s grabs you!", Monnam(mtmp)); 539. } else if(u.ustuck == mtmp) 540. You("are being %s.", 541. #ifdef GOLEMS 542. (mtmp->data == &mons[PM_ROPE_GOLEM]) 543. ? "choked" : 544. #endif /* GOLEMS */ 545. "crushed"); 546. 547. } else { /* hand to hand weapon */ 548. hitmsg(mtmp,mattk->aatyp); 549. if(mattk->aatyp == AT_WEAP && otmp) { 550. dmg += dmgval(otmp, uasmon); 551. if (dmg <= 0) dmg = 1; 552. #ifdef NAMED_ITEMS 553. if (spec_ability(otmp, SPFX_DRLI) 554. # ifdef POLYSELF 555. && !resists_drli(uasmon) 556. # endif 557. ) { 558. pline("The %s blade drains your life!", 559. Hallucination ? hcolor() : black); 560. losexp(); 561. } 562. #endif 563. #ifdef POLYSELF 564. if (u.mh > 1 && u.mh > ((u.uac>0) ? dmg : dmg+u.uac) && 565. (u.umonnum==PM_BLACK_PUDDING 566. || u.umonnum==PM_BROWN_PUDDING)) { 567. /* This redundancy necessary because you have to 568. * take the damage _before_ being cloned. 569. */ 570. if (u.uac < 0) dmg += u.uac; 571. if (dmg < 1) dmg = 1; 572. u.mh -= dmg; 573. flags.botl = 1; 574. dmg = 0; 575. if(cloneu()) 576. kludge("You divide as %s hits you!",mon_nam(mtmp)); 577. } 578. urustm(mtmp, otmp); 579. #endif 580. } 581. } 582. break; 583. case AD_DISE: 584. hitmsg(mtmp, mattk->aatyp); 585. You("feel very sick."); 586. make_sick((long)rn1(25-ACURR(A_CON),15),FALSE); 587. u.usick_cause = mdat->mname; 588. break; 589. case AD_FIRE: 590. hitmsg(mtmp,mattk->aatyp); 591. if(ctmp && rn2(2)) { 592. pline("You're on fire!"); 593. if (Fire_resistance) { 594. pline("The fire doesn't feel hot!"); 595. dmg = 0; 596. } 597. if(mtmp->m_lev > rn2(20)) 598. destroy_item(SCROLL_SYM, AD_FIRE); 599. if(mtmp->m_lev > rn2(20)) 600. destroy_item(POTION_SYM, AD_FIRE); 601. #ifdef SPELLS 602. if(mtmp->m_lev > rn2(25)) 603. destroy_item(SPBOOK_SYM, AD_FIRE); 604. #endif 605. } 606. break; 607. case AD_COLD: 608. hitmsg(mtmp,mattk->aatyp); 609. if(ctmp && rn2(2)) { 610. pline("You're covered in frost!"); 611. if (Cold_resistance) { 612. pline("The frost doesn't seem cold!"); 613. dmg = 0; 614. } 615. if(mtmp->m_lev > rn2(20)) 616. destroy_item(POTION_SYM, AD_COLD); 617. } 618. break; 619. case AD_ELEC: 620. hitmsg(mtmp,mattk->aatyp); 621. if(ctmp && rn2(2)) { 622. You("get zapped!"); 623. if (Shock_resistance) { 624. pline("The zap doesn't shock you!"); 625. dmg = 0; 626. } 627. if(mtmp->m_lev > rn2(20)) 628. destroy_item(WAND_SYM, AD_ELEC); 629. if(mtmp->m_lev > rn2(20)) 630. destroy_item(RING_SYM, AD_ELEC); 631. } 632. break; 633. case AD_SLEE: 634. hitmsg(mtmp,mattk->aatyp); 635. if(ctmp && multi >= 0 && !rn2(5)) { 636. if (Sleep_resistance) break; 637. nomul(-rnd(10)); 638. if (Blind) You("are put to sleep!"); 639. else You("are put to sleep by %s!",mon_nam(mtmp)); 640. } 641. break; 642. case AD_DRST: 643. ptmp = A_STR; 644. goto dopois; 645. case AD_DRDX: 646. ptmp = A_DEX; 647. goto dopois; 648. case AD_DRCO: 649. ptmp = A_CON; 650. dopois: 651. hitmsg(mtmp,mattk->aatyp); 652. if(ctmp && !rn2(8)) { 653. Sprintf(buf, "%s's %s", 654. Hallucination ? rndmonnam() : mdat->mname, 655. (mattk->aatyp == AT_BITE) ? "bite" : "sting"); 656. poisoned(buf, ptmp, mdat->mname); 657. } 658. break; 659. case AD_PLYS: 660. hitmsg(mtmp, mattk->aatyp); 661. if(ctmp && multi >= 0 && !rn2(3)) { 662. if (Blind) You("are frozen!"); 663. else You("are frozen by %s!", mon_nam(mtmp)); 664. nomul(-rnd(10)); 665. } 666. break; 667. case AD_DRLI: 668. hitmsg(mtmp, mattk->aatyp); 669. if (ctmp && !rn2(3) 670. #ifdef POLYSELF 671. && !resists_drli(uasmon) 672. #endif 673. #ifdef NAMED_ITEMS 674. && !defends(AD_DRLI, uwep) 675. #endif 676. ) losexp(); 677. break; 678. case AD_LEGS: 679. { register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; 680. if (mtmp->mcan) { 681. pline("%s nuzzles against your %s %s!", Monnam(mtmp), 682. (side == RIGHT_SIDE) ? "right" : "left", 683. body_part(LEG)); 684. } else { 685. if (uarmf) { 686. pline("%s scratches your %s boot!", Monnam(mtmp), 687. (side == RIGHT_SIDE) ? "right" : "left"); 688. break; 689. } 690. pline("%s pricks your %s %s!", Monnam(mtmp), 691. (side == RIGHT_SIDE) ? "right" : "left", 692. body_part(LEG)); 693. set_wounded_legs(side, rnd(60-ACURR(A_DEX))); 694. } 695. break; 696. } 697. case AD_STON: /* at present only a cockatrice */ 698. hitmsg(mtmp,mattk->aatyp); 699. if(!rn2(3) && !Stoned) { 700. if (mtmp->mcan) { 701. if (flags.soundok) 702. You("hear a cough from %s!", mon_nam(mtmp)); 703. } else { 704. if (flags.soundok) 705. You("hear %s's hissing!", mon_nam(mtmp)); 706. if((!rn2(10) || 707. (flags.moonphase == NEW_MOON && 708. !carrying(DEAD_LIZARD))) 709. #ifdef POLYSELF 710. && !resists_ston(uasmon) 711. #endif 712. ) { 713. Stoned = 5; 714. return(1); 715. /* You("turn to stone..."); */ 716. /* done_in_by(mtmp); */ 717. } 718. } 719. } 720. break; 721. case AD_STCK: 722. hitmsg(mtmp,mattk->aatyp); 723. if(ctmp && !u.ustuck 724. #ifdef POLYSELF 725. && !sticks(uasmon) 726. #endif 727. ) u.ustuck = mtmp; 728. break; 729. case AD_WRAP: 730. if(ctmp 731. #ifdef POLYSELF 732. && !sticks(uasmon) 733. #endif 734. ) { 735. if(!u.ustuck && !rn2(10)) { 736. pline("%s swings itself around you!", 737. Monnam(mtmp)); 738. u.ustuck = mtmp; 739. } else if(u.ustuck == mtmp) { 740. if (is_pool(mtmp->mx,mtmp->my) 741. #ifdef POLYSELF 742. && !is_swimmer(uasmon) 743. #endif 744. ) { 745. pline("%s drowns you...", Monnam(mtmp)); 746. done("drowned"); 747. } else if(mattk->aatyp == AT_HUGS) 748. You("are being crushed."); 749. } else dmg = 0; 750. } else dmg = 0; 751. break; 752. case AD_WERE: 753. hitmsg(mtmp,mattk->aatyp); 754. #ifdef POLYSELF 755. if (ctmp && !rn2(4) && u.ulycn == -1 756. # ifdef NAMED_ITEMS 757. && !defends(AD_WERE,uwep) 758. # endif 759. ) { 760. You("feel feverish."); 761. u.ulycn = monsndx(mdat); 762. } 763. #endif 764. break; 765. case AD_SGLD: 766. hitmsg(mtmp,mattk->aatyp); 767. #ifdef POLYSELF 768. if (u.usym == mdat->mlet) break; 769. #endif 770. if(!mtmp->mcan) stealgold(mtmp); 771. break; 772. 773. case AD_SITM: /* for now these are the same */ 774. case AD_SEDU: 775. #ifdef POLYSELF 776. if (dmgtype(uasmon, AD_SEDU) 777. # ifdef SEDUCE 778. || dmgtype(uasmon, AD_SSEX) 779. # endif 780. ) { 781. if (mtmp->minvent) 782. pline("%s brags about the goods some dungeon explorer provided.", 783. Monnam(mtmp)); 784. else 785. pline("%s makes some remarks about how difficult theft is lately.", 786. Monnam(mtmp)); 787. rloc(mtmp); 788. } else 789. #endif 790. if(mtmp->mcan) { 791. if (!Blind) { 792. pline("%s tries to %s you, but you seem %s.", 793. Amonnam(mtmp, "plain"), 794. flags.female ? "charm" : "seduce", 795. flags.female ? "unaffected" : "uninterested"); 796. } 797. if(rn2(3)) rloc(mtmp); 798. } else if(steal(mtmp)) { 799. rloc(mtmp); 800. mtmp->mflee = 1; 801. } 802. break; 803. #ifdef SEDUCE 804. case AD_SSEX: 805. if(!mtmp->mcan && !mtmp->minvis) doseduce(mtmp); 806. break; 807. #endif 808. case AD_SAMU: 809. hitmsg(mtmp,mattk->aatyp); 810. /* when the Wiz hits, 1/20 steals the amulet */ 811. if (!carrying(AMULET_OF_YENDOR)) break; 812. if (!rn2(20)) stealamulet(mtmp); 813. break; 814. 815. case AD_TLPT: 816. hitmsg(mtmp,mattk->aatyp); 817. if(ctmp) { 818. if(flags.verbose) 819. Your("position suddenly seems very uncertain!"); 820. tele(); 821. } 822. break; 823. case AD_RUST: 824. hitmsg(mtmp,mattk->aatyp); 825. if (mtmp->mcan) break; 826. #ifdef POLYSELF 827. #ifdef GOLEMS 828. if (u.umonnum == PM_IRON_GOLEM) { 829. You("rust!"); 830. rehumanize(); 831. break; 832. } 833. #endif /* GOLEMS */ 834. #endif 835. /* What the following code does: it keeps looping until it 836. * finds a target for the rust monster. 837. * Head, feet, etc... not covered by metal, or covered by 838. * rusty metal, are not targets. However, your body always 839. * is, no matter what covers it. 840. */ 841. getbronze = (mdat == &mons[PM_BLACK_PUDDING] && 842. uarm->otyp == BRONZE_PLATE_MAIL); 843. while (1) { 844. switch(rn2(5)) { 845. case 0: 846. if (!rust_dmg(uarmh, "helmet", 1, FALSE)) continue; 847. break; 848. case 1: 849. if (uarmc) break; 850. /* Note the difference between break and continue; 851. * break means it was hit and didn't rust; continue 852. * means it wasn't a target and though it didn't rust 853. * something else did. 854. */ 855. if (getbronze) 856. (void)rust_dmg(uarm, "bronze armor", 3, TRUE); 857. else 858. (void)rust_dmg(uarm, "armor", 1, TRUE); 859. break; 860. case 2: 861. if (!rust_dmg(uarms, "shield", 1, FALSE)) continue; 862. break; 863. case 3: 864. if (!rust_dmg(uarmg, "metal gauntlets", 1, FALSE)) 865. continue; 866. break; 867. case 4: 868. if (!rust_dmg(uarmf, "metal boots", 1, FALSE)) continue; 869. break; 870. } 871. break; /* Out of while loop */ 872. } 873. break; 874. case AD_DCAY: 875. hitmsg(mtmp,mattk->aatyp); 876. if (mtmp->mcan) break; 877. #ifdef POLYSELF 878. #ifdef GOLEMS 879. if (u.umonnum == PM_WOOD_GOLEM || 880. u.umonnum == PM_LEATHER_GOLEM) { 881. You("rot!"); 882. rehumanize(); 883. break; 884. } 885. #endif /* GOLEMS */ 886. #endif 887. while (1) { 888. switch(rn2(5)) { 889. case 0: 890. if (!rust_dmg(uarmh, "leather helmet", 2, FALSE)) 891. continue; 892. break; 893. case 1: 894. if (uarmc) break; 895. (void)rust_dmg(uarm, "leather armor", 2, TRUE); 896. break; 897. case 2: 898. if (!rust_dmg(uarms, "wooden shield", 2, FALSE)) 899. continue; 900. break; 901. case 3: 902. if (!rust_dmg(uarmg, "gloves", 2, FALSE)) continue; 903. break; 904. case 4: 905. if (!rust_dmg(uarmf, "boots", 2, FALSE)) continue; 906. break; 907. } 908. break; /* Out of while loop */ 909. } 910. break; 911. case AD_HEAL: 912. if(!uwep 913. #ifdef SHIRT 914. && !uarmu 915. #endif 916. && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) { 917. kludge("%s hits! (I hope you don't mind.)", Monnam(mtmp)); 918. #ifdef POLYSELF 919. if (u.mtimedone) { 920. u.mh += rnd(7); 921. if(!rn2(7)) u.mhmax++; 922. if(u.mh > u.mhmax) u.mh = u.mhmax; 923. if(u.mh == u.mhmax && !rn2(50)) mongone(mtmp); 924. } else { 925. #endif 926. u.uhp += rnd(7); 927. if(!rn2(7)) u.uhpmax++; 928. if(u.uhp > u.uhpmax) u.uhp = u.uhpmax; 929. if(u.uhp == u.uhpmax && !rn2(50)) mongone(mtmp); 930. #ifdef POLYSELF 931. } 932. #endif 933. flags.botl = 1; 934. if(!rn2(50)) rloc(mtmp); 935. dmg = 0; 936. } else 937. if(pl_character[0] == 'H') { 938. if (flags.soundok && !(moves % 5)) 939. pline("'Doc, I can't help you unless you cooperate.'"); 940. dmg = 0; 941. } else hitmsg(mtmp,mattk->aatyp); 942. break; 943. case AD_CURS: 944. hitmsg(mtmp,mattk->aatyp); 945. if(!night() && mdat == &mons[PM_GREMLIN]) break; 946. if(!mtmp->mcan && !rn2(10)) { 947. if (flags.soundok) 948. if (Blind) You("hear laughter."); 949. else pline("%s chuckles.", Monnam(mtmp)); 950. #ifdef POLYSELF 951. #ifdef GOLEMS 952. if (u.umonnum == PM_CLAY_GOLEM) { 953. pline("Some writing vanishes from your head!"); 954. rehumanize(); 955. break; 956. } 957. #endif /* GOLEMS */ 958. #endif 959. attrcurse(); 960. } 961. break; 962. case AD_STUN: 963. hitmsg(mtmp,mattk->aatyp); 964. if(!mtmp->mcan && !rn2(4)) { 965. make_stunned(HStun + dmg, TRUE); 966. dmg /= 2; 967. } 968. break; 969. case AD_ACID: 970. hitmsg(mtmp,mattk->aatyp); 971. if(!mtmp->mcan && !rn2(3)) 972. #ifdef POLYSELF 973. if (resists_acid(uasmon)) { 974. pline("You're covered in acid, but it seems harmless."); 975. dmg = 0; 976. } else 977. #endif 978. pline("You're covered in acid! It burns!"); 979. else dmg = 0; 980. break; 981. case AD_SLOW: 982. hitmsg(mtmp,mattk->aatyp); 983. if(!ctmp && (Fast & (INTRINSIC|TIMEOUT)) && !rn2(4)) { 984. Fast &= ~(INTRINSIC|TIMEOUT); 985. You("feel yourself slowing down."); 986. } 987. break; 988. case AD_DREN: 989. hitmsg(mtmp,mattk->aatyp); 990. #ifdef SPELLS 991. if(!ctmp && !rn2(4)) drain_en(dmg); 992. #endif 993. dmg = 0; 994. break; 995. case AD_CUSS: 996. if(flags.soundok && !rn2(3)) cuss(mtmp); 997. dmg = 0; 998. break; 999. #ifdef HARD /* a non-gaze AD_CONF exists only for one of the demons */ 1000. case AD_CONF: 1001. hitmsg(mtmp,mattk->aatyp); 1002. if(!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) { 1003. mtmp->mspec_used += (dmg + rn2(6)); 1004. if(Confusion) 1005. You("are getting even more confused."); 1006. else You("are getting confused."); 1007. make_confused(HConfusion + dmg, FALSE); 1008. } 1009. #endif 1010. /* fall through to next case */ 1011. default: dmg = 0; 1012. break; 1013. } 1014. if(u.uhp < 1) done_in_by(mtmp); 1015. 1016. /* Negative armor class reduces damage done instead of fully protecting 1017. * against hits. 1018. */ 1019. if (dmg && u.uac < 0) { 1020. dmg -= rnd(-u.uac); 1021. if (dmg < 1) dmg = 1; 1022. } 1023. 1024. if(dmg) mdamageu(mtmp, dmg); 1025. 1026. #ifdef POLYSELF 1027. res = passiveum(olduasmon, mtmp); 1028. stop_occupation(); 1029. return res; 1030. #else 1031. stop_occupation(); 1032. return 1; 1033. #endif 1034. } 1035. 1036. static 1037. int 1038. gulpmu(mtmp, mattk) /* monster swallows you, or damage if u.uswallow */ 1039. register struct monst *mtmp; 1040. register struct attack *mattk; 1041. { 1042. int tmp = d((int)mattk->damn, (int)mattk->damd); 1043. int tim_tmp; 1044. #ifdef WALKIES 1045. int i; 1046. #endif 1047. 1048. if(!u.uswallow) { /* swallow him */ 1049. levl[mtmp->mx][mtmp->my].mmask = 0; 1050. mtmp->mx = u.ux; 1051. mtmp->my = u.uy; 1052. levl[mtmp->mx][mtmp->my].mmask = 1; 1053. u.ustuck = mtmp; 1054. pmon(mtmp); 1055. kludge("%s engulfs you!", Monnam(mtmp)); 1056. #ifdef WALKIES 1057. if((i = number_leashed()) > 0) { 1058. pline("The leash%s snap%s loose...", 1059. (i > 1) ? "es" : "", 1060. (i > 1) ? "" : "s"); 1061. unleash_all(); 1062. } 1063. #endif 1064. #ifdef POLYSELF 1065. if (u.umonnum==PM_COCKATRICE) { 1066. kludge("%s turns to stone!", Monnam(mtmp)); 1067. stoned = 1; 1068. xkilled(mtmp, 0); 1069. return 2; 1070. } 1071. #endif 1072. more(); 1073. seeoff(1); 1074. u.uswallow = 1; 1075. /*assume that u.uswldtim always set >=0*/ 1076. u.uswldtim = (tim_tmp = 1077. (-u.uac + 10 + rnd(25 - (int)mtmp->m_lev)) >> 1) > 0 ? 1078. tim_tmp : 0; 1079. swallowed(1); 1080. } else { 1081. 1082. if(mtmp != u.ustuck) return(0); 1083. switch(mattk->adtyp) { 1084. 1085. case AD_DGST: 1086. if(!u.uswldtim) { /* a3 *//*no cf unsigned <=0*/ 1087. kludge("%s totally digests you!", Monnam(mtmp)); 1088. tmp = u.uhp; 1089. } else { 1090. kludge("%s digests you!", Monnam(mtmp)); 1091. } 1092. break; 1093. case AD_PHYS: 1094. You("are pummeled with debris!"); 1095. break; 1096. case AD_ACID: 1097. #ifdef POLYSELF 1098. if (resists_acid(uasmon)) { 1099. You("are covered with a seemingly harmless goo."); 1100. tmp = 0; 1101. } else 1102. #endif 1103. if (Hallucination) pline("Ouch! You've been slimed!"); 1104. else You("are covered in slime! It burns!!!"); 1105. break; 1106. case AD_BLND: 1107. if(!Blind) { 1108. You("can't see in here!"); 1109. make_blinded((long)tmp,FALSE); 1110. } else make_blinded(Blinded+1,FALSE); /* keep him blind until disgorged */ 1111. tmp = 0; 1112. break; 1113. case AD_ELEC: 1114. if(!mtmp->mcan && rn2(2)) { 1115. pline("The air around you crackles with electricity."); 1116. if (Shock_resistance) { 1117. shieldeff(u.ux, u.uy); 1118. You("seem unhurt."); 1119. #if defined(POLYSELF) && defined(GOLEMS) 1120. ugolemeffects(AD_ELEC,tmp); 1121. #endif 1122. tmp = 0; 1123. } 1124. } else tmp = 0; 1125. break; 1126. case AD_COLD: 1127. if(!mtmp->mcan && rn2(2)) { 1128. if (Cold_resistance) { 1129. shieldeff(u.ux, u.uy); 1130. You("feel mildly chilly."); 1131. #if defined(POLYSELF) && defined(GOLEMS) 1132. ugolemeffects(AD_COLD,tmp); 1133. #endif 1134. tmp = 0; 1135. } else You("are freezing to death!"); 1136. } else tmp = 0; 1137. break; 1138. case AD_FIRE: 1139. if(!mtmp->mcan && rn2(2)) { 1140. if (Fire_resistance) { 1141. shieldeff(u.ux, u.uy); 1142. You("feel mildly hot."); 1143. #if defined(POLYSELF) && defined(GOLEMS) 1144. ugolemeffects(AD_FIRE,tmp); 1145. #endif 1146. tmp = 0; 1147. } else You("are burning to a crisp!"); 1148. } else tmp = 0; 1149. break; 1150. #ifdef HARD 1151. case AD_DISE: 1152. if (!Sick) You("feel very sick."); 1153. make_sick(Sick + (long)rn1(25-ACURR(A_CON),15),FALSE); 1154. u.usick_cause = mtmp->data->mname; 1155. break; 1156. #endif 1157. default: tmp = 0; 1158. break; 1159. } 1160. } 1161. 1162. mdamageu(mtmp, tmp); 1163. if(u.uswldtim) --u.uswldtim; 1164. if(!u.uswldtim 1165. #ifdef POLYSELF 1166. || u.umonnum==PM_COCKATRICE 1167. #endif 1168. ) { 1169. #ifdef POLYSELF 1170. if (u.umonnum == PM_COCKATRICE) { 1171. kludge("%s very hurriedly regurgitates you!", 1172. Monnam(mtmp)); 1173. u.uswldtim = 0; 1174. } else { 1175. #endif 1176. You("get regurgitated!"); 1177. if(flags.verbose) 1178. kludge("Obviously %s doesn't like your taste.", 1179. mon_nam(mtmp)); 1180. #ifdef POLYSELF 1181. } 1182. #endif 1183. regurgitates(mtmp); 1184. } 1185. return(1); 1186. } 1187. 1188. static 1189. int 1190. explmu(mtmp, mattk) /* monster explodes in your face */ 1191. register struct monst *mtmp; 1192. register struct attack *mattk; 1193. { 1194. register int tmp = d((int)mattk->damn, (int)mattk->damd); 1195. 1196. if(mtmp->mcan) return(0); 1197. if(!Blind) kludge("%s explodes!", Monnam(mtmp)); 1198. else pline("It explodes!"); 1199. 1200. switch(mattk->adtyp) { 1201. case AD_COLD: 1202. if(Cold_resistance) { 1203. You("seem unaffected by it."); 1204. #if defined(POLYSELF) && defined(GOLEMS) 1205. ugolemeffects(AD_COLD,tmp); 1206. #endif 1207. tmp = 0; 1208. } else { 1209. if(ACURR(A_DEX) > rnd(20)) { 1210. if (!flags.verbose) 1211. You("are caught in the blast!"); 1212. } else { 1213. You("duck the blast..."); 1214. tmp /= 2; 1215. } 1216. } 1217. break; 1218. case AD_BLND: 1219. if(!Blind 1220. #ifdef POLYSELF 1221. && u.usym != S_YLIGHT 1222. #endif 1223. ) { 1224. You("are blinded by a blast of light!"); 1225. make_blinded((long)tmp,FALSE); 1226. } 1227. tmp = 0; 1228. break; 1229. default: break; 1230. } 1231. mdamageu(mtmp, tmp); 1232. mondead(mtmp); 1233. return(2); /* it dies */ 1234. } 1235. 1236. static 1237. int 1238. gazemu(mtmp, mattk) /* monster gazes at you */ 1239. register struct monst *mtmp; 1240. register struct attack *mattk; 1241. { 1242. switch(mattk->adtyp) { 1243. case AD_STON: 1244. if (mtmp->mcan) { 1245. You("notice that %s isn't all that ugly.",mon_nam(mtmp)); 1246. break; 1247. } 1248. if (canseemon(mtmp)) { 1249. You("look upon %s.", mon_nam(mtmp)); 1250. #ifdef POLYSELF 1251. if (resists_ston(uasmon)) { 1252. pline("So what?"); 1253. break; 1254. } 1255. #endif 1256. You("turn to stone..."); 1257. killer = mons[PM_MEDUSA].mname; 1258. done("stoned"); 1259. } 1260. break; 1261. case AD_CONF: 1262. if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && 1263. !mtmp->mspec_used && rn2(5)) { 1264. int conf = d(3,4); 1265. 1266. mtmp->mspec_used += (conf + rn2(6)); 1267. if(!Confusion) 1268. pline("%s's gaze confuses you!", Monnam(mtmp)); 1269. else 1270. You("are getting more and more confused."); 1271. make_confused(HConfusion + conf, FALSE); 1272. } 1273. break; 1274. default: impossible("Gaze attack %d?", mattk->adtyp); 1275. break; 1276. } 1277. return(1); 1278. } 1279. 1280. void 1281. mdamageu(mtmp, n) /* mtmp hits you for n points damage */ 1282. register struct monst *mtmp; 1283. register int n; 1284. { 1285. #ifdef POLYSELF 1286. if (u.mtimedone) { 1287. u.mh -= n; 1288. flags.botl = 1; 1289. if (u.mh < 1) rehumanize(); 1290. return; 1291. } 1292. #endif 1293. u.uhp -= n; 1294. flags.botl = 1; 1295. if(u.uhp < 1) 1296. done_in_by(mtmp); 1297. } 1298. 1299. #ifdef POLYSELF 1300. static void 1301. urustm(mon, obj) 1302. register struct monst *mon; 1303. register struct obj *obj; 1304. { 1305. boolean vis = cansee(mon->mx, mon->my); 1306. 1307. if (!mon || !obj) return; /* just in case */ 1308. if (u.umonnum == PM_RUST_MONSTER && 1309. objects[obj->otyp].oc_material == METAL && 1310. obj->spe > -2) { 1311. if(obj->rustfree) { 1312. if (vis) 1313. pline("The rust vanishes from %s's weapon!", 1314. mon_nam(mon)); 1315. } else if(obj->blessed && rn2(3)) { 1316. if (vis) 1317. pline("Somehow, %s's weapon is not affected!", 1318. mon_nam(mon)); 1319. } else { 1320. if (vis) 1321. pline("%s's %s!", Monnam(mon), aobjnam(obj,"corrode")); 1322. obj->spe--; 1323. } 1324. } 1325. } 1326. #endif 1327. 1328. #ifdef SEDUCE 1329. void 1330. doseduce(mon) 1331. register struct monst *mon; 1332. { 1333. register struct obj *ring; 1334. boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */ 1335. 1336. if (fem == poly_gender() || poly_gender()==2) return; 1337. 1338. if (mon->mcan || mon->mspec_used) { 1339. pline("%s acts as though %s has got a %sheadache.", 1340. Blind ? "It" : Monnam(mon), Blind ? "it" : 1341. fem ? "she" : "he", 1342. mon->mcan ? "severe " : ""); 1343. return; 1344. } 1345. 1346. if (unconscious()) { 1347. kludge("%s seems dismayed at your lack of response.", 1348. Monnam(mon)); 1349. return; 1350. } 1351. 1352. if (Blind) pline("It caresses you..."); 1353. else You("feel very attracted to %s.", mon_nam(mon)); 1354. 1355. for(ring = invent; ring; ring = ring->nobj) { 1356. if (ring->otyp != RIN_ADORNMENT) continue; 1357. if (fem) { 1358. if (rn2(20) < ACURR(A_CHA)) { 1359. pline("\"That %s looks pretty. May I have it?\" ", 1360. xname(ring)); 1361. makeknown(RIN_ADORNMENT); 1362. if (yn() == 'n') continue; 1363. } else pline("%s decides she'd like your %s, and takes it.", 1364. Blind ? "She" : Monnam(mon), xname(ring)); 1365. if (ring->known) makeknown(RIN_ADORNMENT); 1366. if (ring==uleft || ring==uright) Ring_gone(ring); 1367. if (ring==uwep) setuwep((struct obj *)0); 1368. freeinv(ring); 1369. mpickobj(mon,ring); 1370. } else { 1371. char buf[BUFSZ]; 1372. 1373. if (uleft && uright && uleft->otyp == RIN_ADORNMENT 1374. && uright->otyp==RIN_ADORNMENT) 1375. break; 1376. if (ring==uleft || ring==uright) continue; 1377. if (rn2(20) < ACURR(A_CHA)) { 1378. pline("\"That %s looks pretty. Would you wear it for me?\" ", 1379. xname(ring)); 1380. makeknown(RIN_ADORNMENT); 1381. if (yn() == 'n') continue; 1382. } else { 1383. pline("%s decides you'd look prettier wearing your %s,", 1384. Blind ? "He" : Monnam(mon), xname(ring)); 1385. pline("and puts it on your finger."); 1386. } 1387. makeknown(RIN_ADORNMENT); 1388. if (!uright) { 1389. pline("%s puts the %s on your right hand.", 1390. Blind ? "He" : Monnam(mon), xname(ring)); 1391. setworn(ring, RIGHT_RING); 1392. } else if (!uleft) { 1393. pline("%s puts the %s on your left hand.", 1394. Blind ? "He" : Monnam(mon), xname(ring)); 1395. setworn(ring, LEFT_RING); 1396. } else if (uright && uright->otyp != RIN_ADORNMENT) { 1397. Strcpy(buf, xname(uright)); 1398. pline("%s replaces your %s with your %s.", 1399. Blind ? "He" : Monnam(mon), buf, xname(ring)); 1400. Ring_gone(uright); 1401. setworn(ring, RIGHT_RING); 1402. } else if (uleft && uleft->otyp != RIN_ADORNMENT) { 1403. Strcpy(buf, xname(uleft)); 1404. pline("%s replaces your %s with your %s.", 1405. Blind ? "He" : Monnam(mon), buf, xname(ring)); 1406. Ring_gone(uleft); 1407. setworn(ring, LEFT_RING); 1408. } else impossible("ring replacement"); 1409. Ring_on(ring); 1410. prinv(ring); 1411. } 1412. } 1413. 1414. pline("%s murmurs in your ear, while helping you undress.", 1415. Blind ? (fem ? "She" : "He") : Monnam(mon)); 1416. mayberem(uarmc, "cloak"); 1417. if(!uarmc) 1418. mayberem(uarm, "suit"); 1419. mayberem(uarmf, "boots"); 1420. mayberem(uarmg, "gloves"); 1421. mayberem(uarms, "shield"); 1422. #ifdef SHIRT 1423. if(!uarmc && !uarm) 1424. mayberem(uarmu, "shirt"); 1425. #endif 1426. 1427. if (uarm || uarmc) { 1428. pline("\"You're such a %s; I wish...\"", 1429. flags.female ? "sweet lady" : "nice guy"); 1430. rloc(mon); 1431. return; 1432. } 1433. #define ALIGNLIM (5L + (moves/200L)) /* from pray.c */ 1434. if (u.ualigntyp == U_CHAOTIC && u.ualign < ALIGNLIM) u.ualign++; 1435. 1436. /* by this point you have discovered mon's identity, blind or not... */ 1437. pline("Time stands still while you and %s lie in each other's arms...", 1438. mon_nam(mon)); 1439. if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) { 1440. /* Don't bother with mspec_used here... it didn't get tired! */ 1441. pline("%s seems to have enjoyed it more than you...", 1442. Monnam(mon)); 1443. #ifdef SPELLS 1444. switch (rn2(5)) { 1445. case 0: You("feel drained of energy."); 1446. u.uen = 0; 1447. u.uenmax -= rnd(10); 1448. if (u.uenmax < 0) u.uenmax = 0; 1449. break; 1450. #else 1451. switch (rnd(4)) { 1452. #endif 1453. case 1: You("are down in the dumps."); 1454. adjattrib(A_CON, -1, TRUE); 1455. flags.botl = 1; 1456. break; 1457. case 2: Your("senses are dulled."); 1458. adjattrib(A_WIS, -1, TRUE); 1459. flags.botl = 1; 1460. break; 1461. case 3: 1462. #ifdef POLYSELF 1463. if (resists_drli(uasmon)) 1464. You("have a curious feeling..."); 1465. else { 1466. #endif 1467. You("feel out of shape."); 1468. losexp(); 1469. #ifdef POLYSELF 1470. } 1471. #endif 1472. break; 1473. case 4: You("feel exhausted."); 1474. losehp(5+rnd(10), "bout of exhaustion"); 1475. break; 1476. } 1477. } else { 1478. mon->mspec_used = rnd(100); /* monster is worn out */ 1479. You("seem to have enjoyed it more than %s...", mon_nam(mon)); 1480. #ifdef SPELLS 1481. switch (rn2(5)) { 1482. case 0: You("feel raised to your full potential."); 1483. u.uen = (u.uenmax += rnd(5)); 1484. break; 1485. #else 1486. switch (rnd(4)) { 1487. #endif 1488. case 1: You("feel good enough to do it again."); 1489. adjattrib(A_CON, 1, TRUE); 1490. flags.botl = 1; 1491. break; 1492. case 2: You("will always remember %s...", mon_nam(mon)); 1493. adjattrib(A_WIS, 1, TRUE); 1494. flags.botl = 1; 1495. break; 1496. case 3: pline("That was a very educational experience."); 1497. pluslvl(); 1498. break; 1499. case 4: You("feel restored to health!"); 1500. u.uhp = u.uhpmax; 1501. #ifdef POLYSELF 1502. if (u.mtimedone) u.mh = u.mhmax; 1503. #endif 1504. flags.botl = 1; 1505. break; 1506. } 1507. } 1508. 1509. if (mon->mtame) /* don't charge */ ; 1510. else if (rn2(20) < ACURR(A_CHA)) { 1511. pline("%s demands that you pay %s, but you refuse...", 1512. Monnam(mon), (fem ? "her" : "him")); 1513. } 1514. #ifdef POLYSELF 1515. else if (u.umonnum == PM_LEPRECHAUN) 1516. pline("%s tries to take your money, but fails...", 1517. Monnam(mon)); 1518. #endif 1519. else { 1520. long cost = (long)rnd( 1521. (int)(u.ugold > 32767L ? 32767 : u.ugold) +10) + 500; 1522. 1523. if (mon->mpeaceful) { 1524. cost /= 5; 1525. if (!cost) cost=1; 1526. } 1527. if (cost > u.ugold) cost = u.ugold; 1528. if (!cost) pline("%s says: \"It's on the house!\"", Monnam(mon)); 1529. else { 1530. pline("%s takes %ld Zorkmid%s for services rendered!", 1531. Monnam(mon), cost, (cost==1) ? "" : "s"); 1532. u.ugold -= cost; 1533. mon->mgold += cost; 1534. flags.botl = 1; 1535. } 1536. } 1537. if (!rn2(25)) mon->mcan = 1; /* monster is worn out */ 1538. rloc(mon); 1539. } 1540. 1541. static void 1542. mayberem(obj, str) 1543. register struct obj *obj; 1544. char *str; 1545. { 1546. if (!obj || !obj->owornmask) return; 1547. 1548. if (rn2(20) < ACURR(A_CHA)) { 1549. pline("\"Shall I remove your %s, %s?\" ", 1550. str, 1551. (!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart")); 1552. if (yn() == 'n') return; 1553. } else pline("\"Take off your %s; %s.\"", str, 1554. (obj == uarm) ? "let's get a little closer" : 1555. (obj == uarmc) ? "it's in the way" : 1556. (obj == uarmf) ? "let me rub your feet" : 1557. (obj == uarmg) ? "they're too clumsy" : 1558. #ifdef SHIRT 1559. (obj == uarmu) ? "let me massage you" : 1560. #endif 1561. /* obj == uarmh */ 1562. "so I can run my fingers through your hair"); 1563. 1564. if (obj == uarm) (void) Armor_off(); 1565. else if (obj == uarmc) (void) Cloak_off(); 1566. else if (obj == uarmf) (void) Boots_off(); 1567. else if (obj == uarmg) (void) Gloves_off(); 1568. else if (obj == uarmh) (void) Helmet_off(); 1569. else setworn((struct obj *)0, obj->owornmask & W_ARMOR); 1570. } 1571. #endif /* SEDUCE */ 1572. 1573. #ifdef POLYSELF 1574. static int 1575. passiveum(olduasmon,mtmp) 1576. struct permonst *olduasmon; 1577. register struct monst *mtmp; 1578. { 1579. register struct permonst *mdat = mtmp->data; 1580. int dam = 0; 1581. 1582. if (olduasmon->mattk[0].aatyp != AT_NONE) return 1; 1583. 1584. /* These affect the enemy even if you were "killed" (rehumanized) */ 1585. switch(olduasmon->mattk[0].adtyp) { 1586. case AD_ACID: 1587. if (!rn2(2)) { 1588. kludge("%s is splashed by your acid!", Monnam(mtmp)); 1589. if(!resists_acid(mdat)) 1590. dam = d((int)olduasmon->mlevel+1, 1591. (int)olduasmon->mattk[0].damd); 1592. else pline("%s is not affected.", Monnam(mtmp)); 1593. } 1594. break; 1595. default: 1596. break; 1597. } 1598. if (!u.mtimedone) return 1; 1599. 1600. /* These affect the enemy only if you are still a monster */ 1601. if (rn2(3)) switch(uasmon->mattk[0].adtyp) { 1602. case AD_PLYS: /* Floating eye */ 1603. if (!mtmp->mblinded && rn2(3)) { 1604. if (Blind) 1605. pline("As a blind %s, you cannot defend yourself.", 1606. uasmon->mname); 1607. else { 1608. pline("%s is frozen by your gaze!", Monnam(mtmp)); 1609. mtmp->mfroz = 1; 1610. } 1611. } 1612. break; 1613. case AD_COLD: /* Brown mold or blue jelly */ 1614. dam = d((int)uasmon->mlevel+1, (int)uasmon->mattk[0].damd); 1615. if(resists_cold(mdat)) { 1616. shieldeff(mtmp->mx, mtmp->my); 1617. kludge("%s is mildly chilly.", Monnam(mtmp)); 1618. #ifdef GOLEMS 1619. golemeffects(mtmp, AD_COLD, dam); 1620. #endif /* GOLEMS */ 1621. dam = 0; 1622. break; 1623. } 1624. kludge("%s is suddenly very cold!", Monnam(mtmp)); 1625. u.mh += dam / 2; 1626. if (u.mhmax < u.mh) u.mhmax = u.mh; 1627. if (u.mhmax > ((uasmon->mlevel+1) * 8)) { 1628. register struct monst *mon; 1629. 1630. if (mon = cloneu()) { 1631. mon->mhpmax = u.mhmax /= 2; 1632. if (Blind) 1633. You("multiply from its heat!"); 1634. else 1635. You("multiply from %s's heat!", mon_nam(mtmp)); 1636. } 1637. } 1638. break; 1639. case AD_STUN: /* Yellow mold */ 1640. if (!mtmp->mstun) { 1641. mtmp->mstun = 1; 1642. kludge("%s staggers...", Monnam(mtmp)); 1643. } 1644. break; 1645. case AD_FIRE: /* Red mold */ 1646. dam = d((int)uasmon->mlevel+1, (int)uasmon->mattk[0].damd); 1647. if(resists_fire(mdat)) { 1648. shieldeff(mtmp->mx, mtmp->my); 1649. kludge("%s is mildly warm.", Monnam(mtmp)); 1650. #ifdef GOLEMS 1651. golemeffects(mtmp, AD_FIRE, dam); 1652. #endif /* GOLEMS */ 1653. dam = 0; 1654. break; 1655. } 1656. kludge("%s is suddenly very hot!", Monnam(mtmp)); 1657. } 1658. 1659. if((mtmp->mhp -= dam) <= 0) { 1660. kludge("%s dies!", Monnam(mtmp)); 1661. xkilled(mtmp,0); 1662. return(2); 1663. } 1664. return 1; 1665. } 1666. 1667. #include "edog.h" 1668. struct monst * 1669. cloneu() 1670. { 1671. register struct monst *mon; 1672. register int nmlth = strlen(plname) + 1; 1673. 1674. if (u.mh <= 1) return(struct monst *)0; 1675. uasmon->pxlth += sizeof(struct edog) + nmlth; 1676. mon = makemon(uasmon, u.ux, u.uy); 1677. uasmon->pxlth -= sizeof(struct edog) + nmlth; 1678. mon->mxlth = sizeof(struct edog); 1679. Strcpy(NAME(mon), plname); 1680. mon->mnamelth = nmlth; 1681. initedog(mon); 1682. mon->m_lev = uasmon->mlevel; 1683. mon->mhp = u.mh /= 2; 1684. mon->mhpmax = u.mhmax; 1685. return(mon); 1686. } 1687. #endif /* POLYSELF */
|