abstract
| - Below is the full text to mhitu.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/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 1.3 87/07/14 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* mhitu.c - version 1.0.3 */ 4. 5. #include "hack.h" 6. extern struct monst *makemon(); 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] == 'P' && 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. poisoned("scorpion's sting",mdat->mname); 313. } 314. (void) hitu(mtmp,rnd(8)); 315. (void) hitu(mtmp,rnd(8)); 316. break; 317. case 'T': 318. (void) hitu(mtmp,rnd(6)); 319. (void) hitu(mtmp,rnd(6)); 320. break; 321. case 't': 322. if(!rn2(5)) rloc(mtmp); 323. break; 324. case 'u': 325. mtmp->mflee = 1; 326. break; 327. case 'U': 328. (void) hitu(mtmp,d(3,4)); 329. (void) hitu(mtmp,d(3,4)); 330. break; 331. case 'v': 332. if(ctmp && !u.ustuck) u.ustuck = mtmp; 333. break; 334. case 'V': 335. if(tmp) losehp_m(4, mtmp); 336. if(ctmp) losexp(); 337. break; 338. case 'W': 339. if(ctmp) losexp(); 340. break; 341. #ifndef NOWORM 342. case 'w': 343. if(tmp) wormhit(mtmp); 344. #endif 345. break; 346. case 'X': 347. (void) hitu(mtmp,rnd(5)); 348. (void) hitu(mtmp,rnd(5)); 349. (void) hitu(mtmp,rnd(5)); 350. break; 351. case 'x': 352. { register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; 353. #ifdef KAA 354. if (mtmp->mcan) 355. pline("%s nuzzles against your %s leg!", 356. Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left"); 357. else { 358. #endif 359. pline("%s pricks your %s leg!", 360. Monnam(mtmp), (side==RIGHT_SIDE)?"right":"left"); 361. set_wounded_legs(side, rnd(50)); 362. losehp_m(2, mtmp); 363. #ifdef KAA 364. } 365. #endif 366. break; 367. } 368. case 'y': 369. if(mtmp->mcan) break; 370. mondead(mtmp); 371. if(!Blind && (u.usym != 'y')) { 372. pline("You are blinded by a blast of light!"); 373. Blind = d(4,12); 374. seeoff(0); 375. } 376. return(1); 377. case 'Y': 378. (void) hitu(mtmp,rnd(6)); 379. break; 380. } 381. if(u.uhp < 1) done_in_by(mtmp); 382. return(0); 383. } 384. 385. hitu(mtmp,dam) 386. register struct monst *mtmp; 387. register dam; 388. { 389. register tmp, res; 390. 391. nomul(0); 392. if (mtmp->mfroz || mtmp->mhp <= 0) return(0); 393. /* If you are a 'a' or 'E' the monster might not get a second hit */ 394. if(u.uswallow) return(0); 395. 396. if(mtmp->mhide && mtmp->mundetected) { 397. mtmp->mundetected = 0; 398. if(!Blind) { 399. register struct obj *obj; 400. extern char * Xmonnam(); 401. if(obj = o_at(mtmp->mx,mtmp->my)) 402. pline("%s was hidden under %s!", 403. Xmonnam(mtmp), doname(obj)); 404. } 405. } 406. 407. tmp = u.uac; 408. /* give people with Ac = -10 at least some vulnerability */ 409. if(tmp < 0) { 410. dam += tmp; /* decrease damage */ 411. if(dam <= 0) dam = 1; 412. tmp = -rn2(-tmp); 413. } 414. tmp += mtmp->data->mlevel; 415. if(multi < 0) tmp += 4; 416. if((Invis && mtmp->data->mlet != 'I') || !mtmp->mcansee) tmp -= 2; 417. if(mtmp->mtrapped) tmp -= 2; 418. if(tmp <= rnd(20)) { 419. if(Blind) pline("It misses."); 420. else pline("%s misses.",Monnam(mtmp)); 421. res = 0; 422. } else { 423. if(Blind) pline("It hits!"); 424. else pline("%s hits!",Monnam(mtmp)); 425. if (u.usym == 'a' && !rn2(4)) { 426. pline("%s is splashed by your acid!",Monnam(mtmp)); 427. mtmp->mhp -= rnd(10); 428. if(mtmp->mhp <= 0) { 429. pline("%s dies!",Monnam(mtmp)); 430. xkilled(mtmp,0); 431. } 432. } 433. losehp_m(dam, mtmp); 434. res = 1; 435. } 436. stop_occupation(); 437. if(u.usym=='E' && mtmp->mcansee && rn2(2)) { 438. pline("%s is frozen by your gaze!",Monnam(mtmp)); 439. mtmp->mfroz = 1; 440. } 441. return(res); 442. } 443. 444. #define Athome (Inhell && !mtmp->cham) 445. 446. #ifdef HARD 447. demon_talk(mtmp) /* returns 1 if we pay him off. */ 448. register struct monst *mtmp; 449. { 450. char *xmonnam(), *Xmonnam(); 451. int demand, offer; 452. 453. if(!strcmp(mtmp->data->mname, "demon")) { /* not for regular '&'s */ 454. 455. pline("%s mutters something about awful working conditions.", 456. Xmonnam(mtmp)); 457. return(0); 458. } 459. 460. if(u.usym == '&') { /* Won't blackmail their own. */ 461. 462. pline("%s says, 'Good hunting %s.' and vanishes", 463. Xmonnam(mtmp), flags.female ? "Sister" : "Brother"); 464. mondead(mtmp); 465. return(1); 466. } 467. 468. demand = (u.ugold * (rnd(80) + 20 * Athome)) / 100; 469. if(!demand) { /* you have no gold */ 470. mtmp->mpeaceful = 0; 471. return(0); 472. } else { 473. char buf[80]; 474. 475. pline("%s demands %d Zorkmids for safe passage.", 476. Xmonnam(mtmp), demand); 477. pline("how many will you offer him?"); 478. getlin(buf); 479. sscanf(buf, "%d", &offer); 480. 481. if(offer >= u.ugold) { 482. pline("You give %s all your gold.", xmonnam(mtmp)); 483. offer = u.ugold; 484. } else pline("You give %s %d Zorkmids.", xmonnam(mtmp), offer); 485. u.ugold -= offer; 486. 487. if(offer >= demand) { 488. pline("%s vanishes laughing about cowardly mortals.", 489. Xmonnam(mtmp)); 490. } else { 491. if(rnd(40) > (demand - offer)) { 492. pline("%s scowls at you menacingly, then vanishes.", 493. Xmonnam(mtmp)); 494. } else { 495. pline("%s gets angry...", Xmonnam(mtmp)); 496. mtmp->mpeaceful = 0; 497. return(0); 498. } 499. } 500. } 501. mondead(mtmp); 502. return(1); 503. } 504. #endif 505. 506. demon_hit(mtmp) 507. register struct monst *mtmp; 508. { 509. register struct obj *otmp; 510. int onum, nobj = 0, 511. ml = mtmp->data->mlevel; 512. 513. if(!mtmp->cham && !mtmp->mcan && !rn2(13)) { 514. (void) makemon(PM_DEMON,u.ux,u.uy); 515. } else { 516. switch((!mtmp->mcan) ? rn2(ml - 5 - !Athome) : 0) { 517. #ifdef HARD 518. case 12: 519. case 11: 520. case 10: 521. case 9: /* the wiz */ 522. (void) hitu(mtmp, 1); 523. pline("Oh no, he's using the touch of death!"); 524. if (rn2(ml) > 12) { 525. 526. if(Confusion) 527. pline("You have an out of body experience."); 528. else { 529. killer = "touch of death"; 530. done("died"); 531. } 532. } else pline("Lucky for you, it didn't work!"); 533. break; 534. case 8: /* demon princes */ 535. (void) hitu(mtmp, 1); 536. if(!destroy_arm()) pline("Your skin itches."); 537. break; 538. case 7: 539. (void) hitu(mtmp, 1); 540. for (otmp = invent; otmp; otmp = otmp->nobj) nobj++; 541. onum = rn2(nobj); 542. for(otmp = invent; onum != 0; onum--) otmp = otmp->nobj; 543. otmp->cursed++; 544. break; 545. case 6: /* demon lords */ 546. (void) hitu(mtmp, 1); 547. pline("You suddenly feel weaker!"); 548. losestr(rnd(ml - 6)); 549. break; 550. case 5: 551. (void) hitu(mtmp, 1); 552. if (Confusion) pline("Hey, that tickles!"); 553. else pline("Huh, What? Where am I?"); 554. HConfusion += rn1(7, 16); 555. break; 556. #endif /* HARD /**/ 557. default: /* demons and chamelons as demons */ 558. (void) hitu(mtmp,d(2,5 + Athome)); 559. (void) hitu(mtmp,d(2,5 + Athome)); 560. (void) hitu(mtmp,rnd(2 + Athome)); 561. (void) hitu(mtmp,rnd(2 + Athome)); 562. (void) hitu(mtmp,rn1(4,1 + Athome)); 563. break; 564. } 565. } 566. return(0); 567. }
|