abstract
| - Below is the full text to mhitu.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/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 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. }
|