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