Source:NetHack 2.3e/mhitu.c
Jump to navigation
Jump to search
Below is the full text to mhitu.c from the source code of NetHack 2.3e.
Warning! This is the source code from an old release. For newer releases, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* SCCS Id: @(#)mhitu.c 2.3 88/01/21 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include "hack.h" 5. extern struct monst *makemon(); 6. extern struct obj *carrying(); 7. #ifdef KAA 8. extern char pl_character[]; 9. #endif 10. 11. char *breathe[]= { "fragments", 12. "fire", 13. "sleep gas", 14. "frost", 15. "death", 16. "lightening", 17. "poison gas", 18. "acid" }; 19. 20. /* 21. * mhitu: monster hits you 22. * returns 1 if monster dies (e.g. 'y', 'F'), 0 otherwise 23. */ 24. mhitu(mtmp) 25. register struct monst *mtmp; 26. { 27. register struct permonst *mdat = mtmp->data; 28. register int tmp, ctmp; 29. 30. nomul(0); 31. 32. /* If swallowed, can only be affected by hissers and by u.ustuck */ 33. if(u.uswallow) { 34. if(mtmp != u.ustuck) { 35. if(mdat->mlet == 'c' && !rn2(13)) { 36. pline("Outside, you hear %s's hissing!", 37. monnam(mtmp)); 38. pline("%s gets turned to stone!", 39. Monnam(u.ustuck)); 40. pline("And the same fate befalls you."); 41. done_in_by(mtmp); 42. /* "notreached": not return(1); */ 43. } 44. return(0); 45. } 46. switch(mdat->mlet) { /* now mtmp == u.ustuck */ 47. case ',': 48. youswld(mtmp, (u.uac > 0) ? u.uac+4 : 4, 49. 5, Monnam(mtmp)); 50. break; 51. case '\: 52. youswld(mtmp,rnd(6),7,Monnam(mtmp)); 53. break; 54. case 'P': 55. youswld(mtmp,d(2,4),12,Monnam(mtmp)); 56. break; 57. default: 58. /* This is not impossible! */ 59. #ifdef DGKMOD 60. /* If the swallowing monster changes into a monster 61. * that is not capable of swallowing you, you get 62. * regurgitated - dgk 63. */ 64. pline("You get regurgitated!"); 65. u.ux = mtmp->mx; 66. u.uy = mtmp->my; 67. u.uswallow = 0; 68. u.ustuck = 0; 69. mnexto(mtmp); 70. setsee(); 71. docrt(); 72. break; 73. #else 74. pline("The mysterious monster totally digests you."); 75. u.uhp = 0; 76. #endif /* DGKMOD /**/ 77. } 78. if(u.uhp < 1) done_in_by(mtmp); 79. return(0); 80. } 81. 82. if(mdat->mlet == 'c' && Stoned) 83. return(0); 84. 85. /* make eels visible the moment they hit/miss us */ 86. if(mdat->mlet == ';' && mtmp->minvis && cansee(mtmp->mx,mtmp->my)){ 87. mtmp->minvis = 0; 88. pmon(mtmp); 89. } 90. if(!index("1&DuxynNF",mdat->mlet)) 91. tmp = hitu(mtmp,d(mdat->damn,mdat->damd)); 92. else 93. tmp = 0; 94. if(index(UNDEAD, mdat->mlet) && midnight()) 95. tmp += hitu(mtmp,d(mdat->damn,mdat->damd)); 96. 97. ctmp = tmp && !mtmp->mcan && 98. (!uarm || objects[uarm->otyp].a_can < rnz(3)); 99. switch(mdat->mlet) { 100. case '1': 101. if(wiz_hit(mtmp)) return(1); /* he disappeared */ 102. break; 103. case '&': 104. if(mtmp->isdjinni) { 105. (void) hitu(mtmp,d(mdat->damn, mdat->damd)); 106. (void) hitu(mtmp,d(mdat->damn, mdat->damd)); 107. } else demon_hit(mtmp); 108. break; 109. case ',': 110. if(tmp) justswld(mtmp,Monnam(mtmp)); 111. break; 112. case '\: 113. if (tmp) justswld(mtmp,Monnam(mtmp)); 114. break; 115. case ';': 116. if(ctmp) { 117. if (!rn2(6)) { 118. if (!Blind) 119. pline("%s shocks you!", Monnam(mtmp)); 120. else pline("It shocks you!"); 121. if (Shock_resistance) 122. pline("You aren't affected!"); 123. else losehp_m(d(4,6),mtmp); 124. } else 125. if(!u.ustuck && !rn2(10)) { 126. pline("%s swings itself around you!", 127. Monnam(mtmp)); 128. u.ustuck = mtmp; 129. } else if(u.ustuck == mtmp && 130. levl[mtmp->mx][mtmp->my].typ == POOL) { 131. pline("%s drowns you ...", Monnam(mtmp)); 132. done("drowned"); 133. } 134. } 135. break; 136. case 'A': 137. if(ctmp && rn2(2)) { 138. if(Poison_resistance) 139. pline("The sting doesn't seem to affect you."); 140. else { 141. pline("You feel weaker!"); 142. losestr(1); 143. } 144. } 145. break; 146. case 'C': 147. (void) hitu(mtmp,rnd(6)); 148. break; 149. case 'c': 150. if(!rn2(5)) { 151. if (mtmp->mcan) 152. pline("You hear a cough from %s!", monnam(mtmp)); 153. else { 154. pline("You hear %s's hissing!", monnam(mtmp)); 155. if(!rn2(20) || (flags.moonphase == NEW_MOON 156. && !carrying(DEAD_LIZARD) && u.usym != 'c')) { 157. Stoned = 5; 158. /* pline("You get turned to stone!"); */ 159. /* done_in_by(mtmp); */ 160. } 161. } 162. } 163. break; 164. case 'D': 165. if(rn2(6) || mtmp->mcan) { 166. (void) hitu(mtmp,d(3,10)); 167. (void) hitu(mtmp,rnd(8)); 168. (void) hitu(mtmp,rnd(8)); 169. break; 170. } 171. kludge("%s breathes %s!",Monnam(mtmp), breathe[mtmp->dragon]); 172. buzz((int) -10 - (mtmp->dragon), 173. mtmp->mx,mtmp->my,u.ux-mtmp->mx,u.uy-mtmp->my); 174. break; 175. case 'd': 176. (void) hitu(mtmp,d(2, (flags.moonphase == FULL_MOON) ? 3 : 4)); 177. break; 178. case 'e': 179. (void) hitu(mtmp,d(3,6)); 180. break; 181. case 'F': 182. if(mtmp->mcan) break; 183. kludge("%s explodes!", Monnam(mtmp)); 184. if(Cold_resistance) pline("You don't seem affected by it."); 185. else { 186. xchar dn; 187. if(17-(u.ulevel/2) > rnd(20)) { 188. pline("You get blasted!"); 189. dn = 6; 190. } else { 191. pline("You duck the blast..."); 192. dn = 3; 193. } 194. losehp_m(d(dn,6), mtmp); 195. } 196. mondead(mtmp); 197. return(1); 198. case 'G': 199. if(!mtmp->isgremlin || mtmp->mcan) break; 200. if(!rn2(10)) { 201. if (Blind) 202. pline("You hear laughter."); 203. else 204. pline("%s chuckles.", Monnam(mtmp)); 205. attrcurse(); 206. } 207. break; 208. case 'g': 209. if(ctmp && multi >= 0 && !rn2(3)) { 210. /* fix so we do not know what hit us when blind KAA */ 211. if (Blind) 212. pline("You are frozen by its juices!"); 213. else 214. pline("You are frozen by %s's juices!",monnam(mtmp)); 215. nomul(-rnd(10)); 216. } 217. break; 218. case 'h': 219. if(ctmp && multi >= 0 && !rn2(5)) { 220. nomul(-rnd(10)); 221. if (Blind) 222. pline("You are put to sleep by its bite!"); 223. else 224. pline("You are put to sleep by %s's bite!",monnam(mtmp)); 225. } 226. break; 227. case 'j': 228. tmp = hitu(mtmp,rnd(3)); 229. tmp &= hitu(mtmp,rnd(3)); 230. if(tmp){ 231. (void) hitu(mtmp,rnd(4)); 232. (void) hitu(mtmp,rnd(4)); 233. } 234. break; 235. case 'k': 236. if((hitu(mtmp,rnd(4)) || !rn2(3)) && ctmp){ 237. poisoned("bee's sting",mdat->mname); 238. } 239. break; 240. case 'L': 241. #ifdef KAA 242. if (u.usym=='L') break; 243. #endif 244. if(!mtmp->mcan && tmp) stealgold(mtmp); 245. break; 246. case 'N': 247. #ifdef KAA 248. if (u.usym=='N') { 249. if (mtmp->minvent) 250. pline("%s brags about the goods some dungeon explorer provided.", 251. Monnam(mtmp)); 252. else 253. pline("%s makes some remarks about how difficult theft is lately.", 254. Monnam(mtmp)); 255. rloc(mtmp); 256. } else 257. #endif 258. if(mtmp->mcan && !Blind) { 259. pline("%s tries to seduce you, but you seem not interested.", 260. Amonnam(mtmp, "plain")); 261. if(rn2(3)) rloc(mtmp); 262. } else if(steal(mtmp)) { 263. rloc(mtmp); 264. mtmp->mflee = 1; 265. } 266. break; 267. case 'n': 268. if(!uwep 269. #ifdef KAA 270. && u.usym == '@' 271. #endif 272. #ifdef SHIRT 273. && !uarmu 274. #endif 275. && !uarm && !uarmh && !uarms && !uarmg) { 276. pline("%s hits! (I hope you don't mind)", 277. Monnam(mtmp)); 278. u.uhp += rnd(7); 279. if(!rn2(7)) u.uhpmax++; 280. if(u.uhp > u.uhpmax) u.uhp = u.uhpmax; 281. flags.botl = 1; 282. if(!rn2(50)) rloc(mtmp); 283. } else { 284. #ifdef KAA 285. if (pl_character[0] == 'H' && u.usym == '@') { 286. if (!(moves % 5)) 287. pline("Doc, I can't help you unless you cooperate."); 288. } else { 289. #endif 290. (void) hitu(mtmp,d(2,6)); 291. (void) hitu(mtmp,d(2,6)); 292. #ifdef KAA 293. } 294. #endif 295. } 296. break; 297. case 'o': 298. tmp = hitu(mtmp,rnd(6)); 299. if(hitu(mtmp,rnd(6)) && tmp && /* hits with both paws */ 300. !u.ustuck && rn2(2)) { 301. u.ustuck = mtmp; 302. kludge("%s has grabbed you!", Monnam(mtmp)); 303. losehp_m(d(2,8), mtmp); 304. } else if(u.ustuck == mtmp) { 305. losehp_m(d(2,8), mtmp); 306. pline("You are being crushed."); 307. } 308. break; 309. case 'P': 310. if(ctmp && !rn2(4)) 311. justswld(mtmp,Monnam(mtmp)); 312. else 313. (void) hitu(mtmp,d(2,4)); 314. break; 315. case 'Q': 316. #ifdef KAA 317. if(ctmp) { 318. pline("Your position suddenly seems very uncertain!"); 319. tele(); 320. } 321. #else 322. (void) hitu(mtmp,rnd(2)); 323. (void) hitu(mtmp,rnd(2)); 324. #endif 325. break; 326. case 'R': 327. if(ctmp && uarmh && !uarmh->rustfree && 328. (int) uarmh->spe >= -1) { 329. pline("Your helmet rusts!"); 330. uarmh->spe--; 331. } else 332. if(ctmp && uarm && !uarm->rustfree && /* Mike Newton */ 333. uarm->otyp < STUDDED_LEATHER_ARMOR && 334. (int) uarm->spe >= -1) { 335. pline("Your armor rusts!"); 336. uarm->spe--; 337. } 338. break; 339. case 'S': 340. if(ctmp && !rn2(8)) { 341. poisoned("snake's bite",mdat->mname); 342. } 343. break; 344. case 's': 345. if(ctmp && !rn2(8)) { 346. #ifdef SPIDERS 347. poisoned("giant spider's bite",mdat->mname); 348. #else 349. poisoned("scorpion's sting",mdat->mname); 350. #endif 351. } 352. (void) hitu(mtmp,rnd(8)); 353. (void) hitu(mtmp,rnd(8)); 354. break; 355. case 'T': 356. (void) hitu(mtmp,rnd(6)); 357. (void) hitu(mtmp,rnd(6)); 358. break; 359. case 't': 360. if(!rn2(5)) rloc(mtmp); 361. break; 362. case 'u': 363. mtmp->mflee = 1; 364. break; 365. case 'U': 366. (void) hitu(mtmp,d(3,4)); 367. (void) hitu(mtmp,d(3,4)); 368. break; 369. case 'v': 370. if(ctmp && !u.ustuck) u.ustuck = mtmp; 371. break; 372. case 'V': 373. if(tmp) losehp_m(4, mtmp); 374. if(ctmp) losexp(); 375. break; 376. case 'W': 377. if(ctmp) losexp(); 378. break; 379. #ifndef NOWORM 380. case 'w': 381. if(tmp) wormhit(mtmp); 382. #endif 383. break; 384. case 'X': 385. (void) hitu(mtmp,rnd(5)); 386. (void) hitu(mtmp,rnd(5)); 387. (void) hitu(mtmp,rnd(5)); 388. break; 389. case 'x': 390. { register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; 391. #ifdef KAA 392. if (mtmp->mcan) 393. pline("%s nuzzles against your %s leg!", 394. Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left"); 395. else { 396. #endif 397. pline("%s pricks your %s leg!", 398. Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left"); 399. set_wounded_legs(side, rnd(50)); 400. losehp_m(2, mtmp); 401. #ifdef KAA 402. } 403. #endif 404. break; 405. } 406. case 'y': 407. if(mtmp->mcan) break; 408. mondead(mtmp); 409. if(!Blind && (u.usym != 'y')) { 410. pline("You are blinded by a blast of light!"); 411. Blinded = d(4,12); 412. seeoff(0); 413. } 414. return(1); 415. case 'Y': 416. (void) hitu(mtmp,rnd(6)); 417. break; 418. #ifdef RPH 419. case '8': 420. if (canseemon(mtmp) && !mtmp->mcan) { 421. 422. pline ("You look upon %s.", monnam(mtmp)); 423. pline ("You turn to stone."); 424. done_in_by(mtmp); 425. } 426. (void) hitu(mtmp,d(2,6)); 427. (void) hitu(mtmp,d(2,6)); 428. break; 429. #endif 430. #ifdef STOOGES 431. case '@': 432. if(!mtmp->isstooge) break; 433. if(!tmp) break; 434. if(!rn2(6) && !Blind) { 435. pline ("%s poked you in the eye.", Monnam(mtmp)); 436. pline ("You are blinded!"); 437. Blinded += rnd(10); 438. seeoff(0); 439. } 440. break; 441. #endif 442. } 443. if(u.uhp < 1) done_in_by(mtmp); 444. return(0); 445. } 446. 447. hitu(mtmp,dam) 448. register struct monst *mtmp; 449. register dam; 450. { 451. register tmp, res; 452. 453. nomul(0); 454. if (mtmp->mfroz || mtmp->mhp <= 0) return(0); 455. /* If you are a 'a' or 'E' the monster might not get a second hit */ 456. if(u.uswallow) return(0); 457. 458. if(mtmp->mhide && mtmp->mundetected) { 459. mtmp->mundetected = 0; 460. if(!Blind) { 461. register struct obj *obj; 462. extern char *Xmonnam(); 463. if(obj = o_at(mtmp->mx,mtmp->my)) 464. pline("%s was hidden under %s!", 465. Xmonnam(mtmp), doname(obj)); 466. } 467. } 468. 469. tmp = u.uac; 470. /* give people with Ac = -10 at least some vulnerability */ 471. if(tmp < 0) { 472. dam += tmp; /* decrease damage */ 473. if(dam <= 0) dam = 1; 474. tmp = -rn2(-tmp); 475. } 476. tmp += mtmp->data->mlevel; 477. if(multi < 0) tmp += 4; 478. if((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee) tmp -= 2; 479. if(mtmp->mtrapped) tmp -= 2; 480. if(tmp <= rnd(20)) { 481. if(Blind) pline("It misses."); 482. else pline("%s misses.",Monnam(mtmp)); 483. res = 0; 484. } else { 485. if(Blind) pline("It hits!"); 486. else pline("%s hits!",Monnam(mtmp)); 487. if (u.usym == 'a' && !rn2(4)) { 488. pline("%s is splashed by your acid!",Monnam(mtmp)); 489. mtmp->mhp -= rnd(10); 490. if(mtmp->mhp <= 0) { 491. pline("%s dies!",Monnam(mtmp)); 492. xkilled(mtmp,0); 493. } 494. } 495. losehp_m(dam, mtmp); 496. res = 1; 497. } 498. stop_occupation(); 499. if(u.usym=='E' && mtmp->mcansee && rn2(2)) { 500. pline("%s is frozen by your gaze!",Monnam(mtmp)); 501. mtmp->mfroz = 1; 502. } 503. return(res); 504. } 505. 506. #define Athome (Inhell && !mtmp->cham) 507. 508. #ifdef HARD 509. demon_talk(mtmp) /* returns 1 if we pay him off. */ 510. register struct monst *mtmp; 511. { 512. char *xmonnam(), *Xmonnam(); 513. int demand, offer; 514. 515. if(uwep && !strcmp(ONAME(uwep), "Excalibur")) { 516. 517. pline("%s looks very angry.", Xmonnam(mtmp)); 518. mtmp->mpeaceful = mtmp->mtame = 0; 519. return(0); 520. } 521. if(!strcmp(mtmp->data->mname, "demon")) { /* not for regular '&'s */ 522. 523. pline("%s mutters something about awful working conditions.", 524. Xmonnam(mtmp)); 525. return(0); 526. } 527. 528. /* Slight advantage given. */ 529. if(!strcmp(mtmp->data->mname, "demon prince") && mtmp->minvis) { 530. 531. if (!Blind) pline("%s appears before you.", Xmonnam(mtmp)); 532. mtmp->minvis = 0; 533. pmon(mtmp); 534. } 535. if(u.usym == '&') { /* Won't blackmail their own. */ 536. 537. pline("%s says, 'Good hunting %s.' and vanishes", 538. Xmonnam(mtmp), flags.female ? "Sister" : "Brother"); 539. rloc(mtmp); 540. return(1); 541. } 542. demand = (u.ugold * (rnd(80) + 20 * Athome)) / 100; 543. if(!demand) { /* you have no gold */ 544. mtmp->mpeaceful = 0; 545. return(0); 546. } else { 547. char buf[80]; 548. 549. pline("%s demands %d Zorkmids for safe passage.", 550. Xmonnam(mtmp), demand); 551. pline("how many will you offer him?"); 552. getlin(buf); 553. sscanf(buf, "%d", &offer); 554. 555. if(offer >= u.ugold) { 556. pline("You give %s all your gold.", xmonnam(mtmp, 0)); 557. offer = u.ugold; 558. } else pline("You give %s %d Zorkmids.", xmonnam(mtmp, 0), offer); 559. u.ugold -= offer; 560. 561. if(offer >= demand) { 562. pline("%s vanishes laughing about cowardly mortals.", 563. Xmonnam(mtmp)); 564. } else { 565. if(rnd(40) > (demand - offer)) { 566. pline("%s scowls at you menacingly, then vanishes.", 567. Xmonnam(mtmp)); 568. } else { 569. pline("%s gets angry...", Xmonnam(mtmp)); 570. mtmp->mpeaceful = 0; 571. return(0); 572. } 573. } 574. } 575. mondead(mtmp); 576. return(1); 577. } 578. #endif 579. 580. demon_hit(mtmp) 581. register struct monst *mtmp; 582. { 583. register struct obj *otmp; 584. int onum, nobj = 0, 585. ml = mtmp->data->mlevel; 586. 587. if(!mtmp->cham && !mtmp->mcan && !rn2(13)) { 588. (void) makemon(PM_DEMON,u.ux,u.uy); 589. } else { 590. switch((!mtmp->mcan) ? rn2(ml - 5 - !Athome) : 0) { 591. #ifdef HARD 592. case 12: 593. case 11: 594. case 10: 595. case 9: /* the wiz */ 596. (void) hitu(mtmp, 1); 597. pline("Oh no, he's using the touch of death!"); 598. if (rn2(ml) > 12) { 599. 600. if(Confusion) 601. pline("You have an out of body experience."); 602. else { 603. killer = "touch of death"; 604. done("died"); 605. } 606. } else pline("Lucky for you, it didn't work!"); 607. break; 608. case 8: /* demon princes */ 609. (void) hitu(mtmp, 1); 610. if(!destroy_arm()) pline("Your skin itches."); 611. break; 612. case 7: 613. (void) hitu(mtmp, 1); 614. for (otmp = invent; otmp; otmp = otmp->nobj) nobj++; 615. onum = rn2(nobj); 616. for(otmp = invent; onum != 0; onum--) otmp = otmp->nobj; 617. otmp->cursed++; 618. break; 619. case 6: /* demon lords */ 620. (void) hitu(mtmp, 1); 621. pline("You suddenly feel weaker!"); 622. losestr(rnd(ml - 6)); 623. break; 624. case 5: 625. (void) hitu(mtmp, 1); 626. if (Confusion) pline("Hey, that tickles!"); 627. else pline("Huh, What? Where am I?"); 628. HConfusion += rn1(7, 16); 629. break; 630. #endif /* HARD /**/ 631. default: /* demons and chamelons as demons */ 632. (void) hitu(mtmp,d(2,5 + Athome)); 633. (void) hitu(mtmp,d(2,5 + Athome)); 634. (void) hitu(mtmp,rnd(2 + Athome)); 635. (void) hitu(mtmp,rnd(2 + Athome)); 636. (void) hitu(mtmp,rn1(4,1 + Athome)); 637. break; 638. } 639. } 640. return(0); 641. }