Source:NetHack 3.0.0/mhitu.c
Revision as of 01:13, 5 July 2024 by Furey (talk | contribs) (Delete link-to-particular-source instructions. Source code covers that now. "the latest release" -> "newer releases".)
Below is the full text to mhitu.c from the source code of NetHack 3.0.0.
Warning! This is the source code from an old release. For newer releases, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: \@(#)mhitu.c 3.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 */