Difference between revisions of "Source:NetHack 1.3d/fight.c"
Jump to navigation
Jump to search
m (Automated source code upload) |
Kernigh bot (talk | contribs) m (NetHack 1.3d/fight.c moved to Source:NetHack 1.3d/fight.c: Robot: moved page) |
(No difference)
|
Latest revision as of 23:50, 3 March 2008
Below is the full text to fight.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/fight.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* SCCS Id: @(#)fight.c 1.3 87/07/14 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* fight.c - version 1.0.3 */ 4. 5. #include <stdio.h> 6. #include "hack.h" 7. 8. extern struct permonst li_dog, dog, la_dog; 9. extern char *exclam(), *hcolor(), *xname(); 10. extern struct obj *mkobj_at(); 11. #ifdef KAA 12. extern boolean stoned; 13. extern boolean unweapon; 14. extern char *nomovemsg, *defmonnam(); 15. extern struct monst *mkmon_at(); 16. #endif 17. 18. static boolean far_noise; 19. static long noisetime; 20. 21. /* hitmm returns 0 (miss), 1 (hit), or 2 (kill) */ 22. hitmm(magr,mdef) register struct monst *magr,*mdef; { 23. register struct permonst *pa = magr->data, *pd = mdef->data; 24. int hit; 25. schar tmp; 26. boolean vis; 27. if(index("Eauy", pa->mlet)) return(0); 28. if(magr->mfroz) return(0); /* riv05!a3 */ 29. tmp = pd->ac + pa->mlevel; 30. if(mdef->mconf || mdef->mfroz || mdef->msleep){ 31. tmp += 4; 32. if(mdef->msleep) mdef->msleep = 0; 33. } 34. hit = (tmp > rnd(20)); 35. if(hit) mdef->msleep = 0; 36. vis = (cansee(magr->mx,magr->my) && cansee(mdef->mx,mdef->my)); 37. if(vis){ 38. char buf[BUFSZ]; 39. if(mdef->mimic) seemimic(mdef); 40. if(magr->mimic) seemimic(magr); 41. (void) sprintf(buf,"%s %s", Monnam(magr), 42. hit ? "hits" : "misses"); 43. pline("%s %s.", buf, monnam(mdef)); 44. } else { 45. boolean farq = (dist(magr->mx, magr->my) > 15); 46. if(farq != far_noise || moves-noisetime > 10) { 47. far_noise = farq; 48. noisetime = moves; 49. pline("You hear some noises%s.", 50. farq ? " in the distance" : ""); 51. } 52. } 53. if(hit){ 54. if(magr->data->mlet == 'c' && !magr->cham) { 55. magr->mhpmax += 3; 56. if(vis) pline("%s is turned to stone!", Monnam(mdef)); 57. else if(mdef->mtame) 58. pline("You have a peculiarly sad feeling for a moment, then it passes."); 59. monstone(mdef); 60. hit = 2; 61. } else 62. if((mdef->mhp -= d(pa->damn,pa->damd)) < 1) { 63. magr->mhpmax += 1 + rn2(pd->mlevel+1); 64. if(magr->mtame && magr->mhpmax > 8*pa->mlevel){ 65. if(pa == &li_dog) magr->data = pa = &dog; 66. else if(pa == &dog) magr->data = pa = &la_dog; 67. } 68. if(vis) pline("%s is killed!", Monnam(mdef)); 69. else if(mdef->mtame) 70. pline("You have a sad feeling for a moment, then it passes."); 71. mondied(mdef); 72. hit = 2; 73. } 74. /* fixes a bug where max monster hp could overflow. */ 75. if(magr->mhpmax <= 0) magr->mhpmax = 127; 76. } 77. #ifdef KAA 78. if(hit == 1 && magr->data->mlet == 'Q') { 79. rloc(mdef); 80. if(vis && !cansee(mdef->mx,mdef->my)) 81. pline("%s suddenly disappears!",Monnam(mdef)); 82. } 83. #endif 84. return(hit); 85. } 86. 87. /* drop (perhaps) a cadaver and remove monster */ 88. mondied(mdef) register struct monst *mdef; { 89. register struct permonst *pd = mdef->data; 90. #ifdef KOPS 91. if(letter(pd->mlet) && rn2(3) && pd->mlet != 'K'){ 92. #else 93. if(letter(pd->mlet) && rn2(3)){ 94. #endif 95. if (pd->mlet == '1') panic("mondied: making obj '1'"); 96. (void) mkobj_at(pd->mlet,mdef->mx,mdef->my); 97. if(cansee(mdef->mx,mdef->my)){ 98. unpmon(mdef); 99. atl(mdef->mx,mdef->my,fobj->olet); 100. } 101. stackobj(fobj); 102. } 103. mondead(mdef); 104. } 105. 106. /* drop a rock and remove monster */ 107. monstone(mdef) register struct monst *mdef; { 108. extern char mlarge[]; 109. if(index(mlarge, mdef->data->mlet)) 110. mksobj_at(ENORMOUS_ROCK, mdef->mx, mdef->my); 111. else 112. mksobj_at(ROCK, mdef->mx, mdef->my); 113. if(cansee(mdef->mx, mdef->my)){ 114. unpmon(mdef); 115. atl(mdef->mx,mdef->my,fobj->olet); 116. } 117. mondead(mdef); 118. } 119. 120. 121. fightm(mtmp) register struct monst *mtmp; { 122. register struct monst *mon; 123. for(mon = fmon; mon; mon = mon->nmon) if(mon != mtmp) { 124. if(DIST(mon->mx,mon->my,mtmp->mx,mtmp->my) < 3) 125. if(rn2(4)) 126. return(hitmm(mtmp,mon)); 127. } 128. return(-1); 129. } 130. 131. /* u is hit by sth, but not a monster */ 132. thitu(tlev,dam,name) 133. register tlev,dam; 134. register char *name; 135. { 136. char buf[BUFSZ]; 137. setan(name,buf); 138. if(u.uac + tlev <= rnd(20)) { 139. if(Blind) pline("It misses."); 140. else pline("You are almost hit by %s!", buf); 141. return(0); 142. } else { 143. if(Blind) pline("You are hit!"); 144. else pline("You are hit by %s!", buf); 145. losehp(dam,name); 146. return(1); 147. } 148. } 149. 150. #ifdef KAA 151. char mlarge[] = "bCDdegIlmnoPSsTUwY',&9"; 152. #else 153. char mlarge[] = "bCDdegIlmnoPSsTUwY',&"; 154. #endif 155. 156. boolean 157. hmon(mon,obj,thrown) /* return TRUE if mon still alive */ 158. register struct monst *mon; 159. register struct obj *obj; 160. register thrown; 161. { 162. register tmp; 163. boolean hittxt = FALSE; 164. 165. #ifdef KAA 166. stoned = FALSE; /* this refers to the thing hit, not you */ 167. #endif 168. if(!obj){ 169. #ifdef KAA 170. /* Note that c, y, and F can never wield weapons anyway */ 171. if (u.usym == 'c' && mon->data->mlet != 'c') { 172. pline("You turn %s to stone!", monnam(mon)); 173. stoned = TRUE; 174. xkilled(mon,0); 175. return(FALSE); 176. } else if (u.usym == 'y' && mon->data->mlet != 'y') { 177. pline("%s is blinded by your flash of light!",Monnam(mon)); 178. if (!mon->mblinded) { 179. mon->mblinded += rn2(25); 180. mon->mcansee = 0; 181. } 182. rehumanize(); 183. return(TRUE); 184. } else if (u.usym == 'F') { 185. pline("You explode!"); 186. if (!index("gFY",mon->data->mlet)) { 187. pline("%s gets blasted!", Monnam(mon)); 188. mon->mhp -= d(6,6); 189. rehumanize(); 190. if (mon->mhp <= 0) { 191. killed(mon); 192. return(FALSE); 193. } else return(TRUE); 194. } else { 195. pline("The blast doesn't seem to affect %s.", monnam(mon)); 196. rehumanize(); 197. return(TRUE); 198. } 199. } else if (index("P,'", u.usym) && u.uhunger < 1500 200. && !u.uswallow && mon->data->mlet != 'c') { 201. static char msgbuf[BUFSZ]; 202. pline("You swallow %s whole!", monnam(mon)); 203. u.uhunger += 20*mon->mhpmax; 204. newuhs(FALSE); 205. xkilled(mon,2); 206. if (tmp = mon->mhpmax/5) { 207. nomul(-tmp); 208. (void)sprintf(msgbuf, "You finished digesting %s.", 209. monnam(mon)); 210. nomovemsg = msgbuf; 211. } 212. return(FALSE); 213. } else if (u.usym != '@') { 214. if (u.usym == '&' && !rn2(5)) { 215. struct monst *dtmp; 216. pline("Some hell-p has arrived!"); 217. dtmp = mkmon_at('&',u.ux,u.uy); 218. (void)tamedog(dtmp,(struct obj *)0); 219. } 220. tmp = d(mons[u.umonnum].damn, mons[u.umonnum].damd); 221. } else 222. #endif 223. tmp = rnd(2); /* attack with bare hands */ 224. #ifdef KAA 225. if (mon->data->mlet == 'c' && !uarmg && u.usym != 'c'){ 226. #else 227. if(mon->data->mlet == 'c' && !uarmg){ 228. #endif 229. pline("You hit the cockatrice with your bare hands."); 230. pline("You turn to stone ..."); 231. done_in_by(mon); 232. } 233. } else if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE) { 234. if(obj == uwep && (obj->otyp > SPEAR || obj->otyp < BOOMERANG)) 235. tmp = rnd(2); 236. else { 237. if(index(mlarge, mon->data->mlet)) { 238. tmp = rnd(objects[obj->otyp].wldam); 239. switch (obj->otyp) { 240. case SLING_BULLET: 241. case CROSSBOW_BOLT: 242. case MORNING_STAR: 243. case PARTISAN: 244. case BROAD_SWORD: tmp += 1; break; 245. 246. case FLAIL: 247. case RANSEUR: 248. case VOULGE: tmp += rnd(4); break; 249. 250. case HALBERD: 251. case SPETUM: tmp += rnd(6); break; 252. 253. case BARDICHE: 254. case TRIDENT: tmp += d(2,4); break; 255. 256. case TWO_HANDED_SWORD: 257. case KATANA: tmp += d(2,6); break; 258. } 259. } else { 260. tmp = rnd(objects[obj->otyp].wsdam); 261. switch (obj->otyp) { 262. case SLING_BULLET: 263. case CROSSBOW_BOLT: 264. case MACE: 265. case FLAIL: 266. case SPETUM: 267. case TRIDENT: tmp += 1; break; 268. 269. case BARDICHE: 270. case BILL_GUISARME: 271. case GUISARME: 272. case LUCERN_HAMMER: 273. case MORNING_STAR: 274. case RANSEUR: 275. case BROAD_SWORD: 276. case VOULGE: tmp += rnd(4); break; 277. } 278. } 279. tmp += obj->spe; 280. #ifdef KAA 281. if(obj->olet == WEAPON_SYM && obj->dknown && index("VWZ &", 282. mon->data->mlet)) tmp += rn2(4); 283. #endif 284. if(!thrown && obj == uwep && obj->otyp == BOOMERANG 285. && !rn2(3)){ 286. pline("As you hit %s, the boomerang breaks into splinters.", 287. monnam(mon)); 288. freeinv(obj); 289. setworn((struct obj *) 0, obj->owornmask); 290. obfree(obj, (struct obj *) 0); 291. tmp++; 292. } 293. } 294. if(mon->data->mlet == 'O' && obj->otyp == TWO_HANDED_SWORD && 295. !strcmp(ONAME(obj), "Orcrist")) 296. tmp += rnd(10); 297. } else switch(obj->otyp) { 298. case HEAVY_IRON_BALL: 299. tmp = rnd(25); break; 300. case ENORMOUS_ROCK: 301. tmp = rnd(20); break; 302. case EXPENSIVE_CAMERA: 303. pline("You succeed in destroying your camera. Congratulations!"); 304. freeinv(obj); 305. if(obj->owornmask) 306. setworn((struct obj *) 0, obj->owornmask); 307. obfree(obj, (struct obj *) 0); 308. return(TRUE); 309. case DEAD_COCKATRICE: 310. pline("You hit %s with the cockatrice corpse.", 311. monnam(mon)); 312. if(mon->data->mlet == 'c') { 313. tmp = 1; 314. hittxt = TRUE; 315. #ifdef KAA 316. stoned = TRUE; 317. xkilled(mon,0); 318. #endif 319. break; 320. } 321. pline("%s is turned to stone!", Monnam(mon)); 322. killed(mon); 323. return(FALSE); 324. case CLOVE_OF_GARLIC: /* no effect against demons */ 325. if(index(UNDEAD, mon->data->mlet)) 326. mon->mflee = 1; 327. tmp = 1; 328. break; 329. default: 330. /* non-weapons can damage because of their weight */ 331. /* (but not too much) */ 332. tmp = obj->owt/10; 333. if(tmp < 1) tmp = 1; 334. else tmp = rnd(tmp); 335. if(tmp > 6) tmp = 6; 336. } 337. 338. /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) */ 339. 340. tmp += u.udaminc + dbon(); 341. if(u.uswallow) { 342. if((tmp -= u.uswldtim) <= 0) { 343. pline("Your arms are no longer able to hit."); 344. return(TRUE); 345. } 346. } 347. if(tmp < 1) tmp = 1; 348. mon->mhp -= tmp; 349. if(mon->mhp < 1) { 350. killed(mon); 351. return(FALSE); 352. } 353. if(mon->mtame && (!mon->mflee || mon->mfleetim)) { 354. mon->mflee = 1; /* Rick Richardson */ 355. mon->mfleetim += 10*rnd(tmp); 356. } 357. 358. if(!hittxt) { 359. if(thrown) 360. /* this assumes that we cannot throw plural things */ 361. hit( xname(obj) /* or: objects[obj->otyp].oc_name */, 362. mon, exclam(tmp) ); 363. else if(Blind) 364. pline("You hit it."); 365. else 366. pline("You hit %s%s", monnam(mon), exclam(tmp)); 367. } 368. 369. if(u.umconf && !thrown) { 370. if(!Blind) { 371. pline("Your hands stop glowing %s.", 372. Hallucination ? hcolor() : "blue"); 373. } 374. if (!resist(mon, '+', 0, NOTELL)) mon->mconf = 1; 375. if(!mon->mfroz && !mon->msleep && !Blind && mon->mconf) 376. pline("%s appears confused.",Monnam(mon)); 377. u.umconf = 0; 378. } 379. if(!thrown && rn2(2) && index("VW",u.usym) && 380. !index("VW",mon->data->mlet)){ 381. int tmp=d(2,6); 382. pline("%s suddenly seems weaker!",Monnam(mon)); 383. mon->mhpmax -= tmp; 384. if ((mon->mhp -= tmp) <= 0) { 385. pline("%s dies!",Monnam(mon)); 386. xkilled(mon,0); 387. return(FALSE); 388. } 389. } 390. return(TRUE); /* mon still alive */ 391. } 392. 393. /* try to attack; return FALSE if monster evaded */ 394. /* u.dx and u.dy must be set */ 395. attack(mtmp) 396. register struct monst *mtmp; 397. { 398. schar tmp; 399. boolean malive = TRUE; 400. register struct permonst *mdat; 401. mdat = mtmp->data; 402. 403. #ifdef KAA 404. if(unweapon) { 405. unweapon=FALSE; 406. if(uwep) 407. pline("You begin bashing monsters with your %s.", 408. aobjnam(uwep,(char *)0)); 409. } 410. #endif 411. u_wipe_engr(3); /* andrew@orca: prevent unlimited pick-axe attacks */ 412. 413. if(mdat->mlet == 'L' && !mtmp->mfroz && !mtmp->msleep && 414. !mtmp->mconf && mtmp->mcansee && !rn2(7) && 415. (m_move(mtmp, 0) == 2 /* he died */ || /* he moved: */ 416. mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) 417. return(FALSE); 418. #ifdef SAFE_ATTACK 419. /* This section of code provides protection against accidentally 420. * hitting peaceful (like '@') and tame (like 'd') monsters. 421. * There is protection only if you're not blind, confused or 422. * invisible. 423. */ 424. /* changes by wwp 5/16/85 */ 425. if (!Blind && !Confusion && !Hallucination 426. && mdat->mlet == 'd' && mtmp->mtame) { 427. mtmp->mflee = 1; 428. mtmp->mfleetim = rnd(6); 429. pline("You stop to avoid hitting your dog"); 430. return(TRUE); 431. } 432. if (flags.confirm && (mtmp->mpeaceful || mtmp->mtame) && ! Confusion 433. && !Hallucination && !Invisible) 434. 435. if (Blind ? Telepat : (!mtmp->minvis || See_invisible)) { 436. pline("Really attack?"); 437. (void) fflush(stdout); 438. if (readchar() != 'y') { 439. flags.move = 0; 440. return(TRUE); 441. } 442. } 443. #endif /* SAFE_ATTACK /**/ 444. 445. if(mtmp->mimic){ 446. if(!u.ustuck && !mtmp->mflee) u.ustuck = mtmp; 447. #ifdef DGK 448. if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == symbol.door) 449. if (okdoor(u.ux+u.dx, u.uy+u.dy)) 450. pline("The door actually was %s.", defmonnam(mtmp)); 451. else pline("That spellbook was %s.", defmonnam(mtmp)); 452. else if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == '$') 453. pline("The chest was %s!", defmonnam(mtmp)); 454. else 455. pline("Wait! That's %s!",defmonnam(mtmp)); 456. #else 457. switch(levl[u.ux+u.dx][u.uy+u.dy].scrsym){ 458. case '+': 459. if (okdoor(u.ux+u.dx, u.uy+u.dy)) 460. pline("The door actually was %s.", defmonnam(mtmp)); 461. else pline("That spellbook was %s.", defmonnam(mtmp)); 462. break; 463. case '$': 464. pline("The chest was %s!", defmonnam(mtmp)); 465. break; 466. default: 467. pline("Wait! That's %s!",defmonnam(mtmp)); 468. } 469. #endif 470. wakeup(mtmp); /* clears mtmp->mimic */ 471. return(TRUE); 472. } 473. 474. wakeup(mtmp); 475. 476. if(mtmp->mhide && mtmp->mundetected){ 477. register struct obj *obj; 478. 479. mtmp->mundetected = 0; 480. if((obj = o_at(mtmp->mx,mtmp->my)) && !Blind) 481. pline("Wait! There's %s hiding under %s!", 482. defmonnam(mtmp), doname(obj)); 483. return(TRUE); 484. } 485. #ifdef KAA 486. tmp = u.uluck + (u.mtimedone ? mons[u.umonnum].mlevel : u.ulevel) + 487. mdat->ac + abon(); 488. if (u.usym=='y' || u.usym=='F') tmp=100; 489. if (index("uEa",u.usym)) return(TRUE); 490. #endif 491. if(uwep) { 492. #ifdef KAA /* Blessed weapons used against undead or demons */ 493. if(uwep->olet == WEAPON_SYM && uwep->dknown && index("VWZ &", 494. mtmp->data->mlet)) tmp += 2; 495. #endif 496. if(uwep->olet == WEAPON_SYM || uwep->otyp == PICK_AXE) 497. tmp += uwep->spe; 498. if(uwep->otyp == TWO_HANDED_SWORD) tmp -= 1; 499. else if(uwep->otyp == KATANA) tmp += 1; 500. else if(uwep->otyp == DAGGER || 501. uwep->otyp == SHURIKEN) tmp += 2; 502. else if(uwep->otyp == CRYSKNIFE) tmp += 3; 503. else if(uwep->otyp == SPEAR && 504. index("XDne", mdat->mlet)) tmp += 2; 505. } 506. if(mtmp->msleep) { 507. mtmp->msleep = 0; 508. tmp += 2; 509. } 510. if(mtmp->mfroz) { 511. tmp += 4; 512. if(!rn2(10)) mtmp->mfroz = 0; 513. } 514. if(mtmp->mflee) tmp += 2; 515. if(u.utrap) tmp -= 3; 516. 517. /* with a lot of luggage, your agility diminishes */ 518. tmp -= (inv_weight() + 40)/20; 519. 520. if(tmp <= rnd(20) && !u.uswallow){ 521. if(Blind) pline("You miss it."); 522. else pline("You miss %s.",monnam(mtmp)); 523. } else { 524. /* we hit the monster; be careful: it might die! */ 525. 526. if((malive = hmon(mtmp,uwep,0)) == TRUE) { 527. /* monster still alive */ 528. if(!rn2(25) && mtmp->mhp < mtmp->mhpmax/2) { 529. mtmp->mflee = 1; 530. if(!rn2(3)) mtmp->mfleetim = rnd(100); 531. if(u.ustuck == mtmp && !u.uswallow) 532. u.ustuck = 0; 533. } 534. #ifndef NOWORM 535. if(mtmp->wormno) 536. cutworm(mtmp, u.ux+u.dx, u.uy+u.dy, 537. uwep ? uwep->otyp : 0); 538. #endif 539. } 540. if(mdat->mlet == 'a') { 541. if(rn2(2)) { 542. if (Blind) pline("You are splashed!"); 543. else pline("You are splashed by %s's acid!",monnam(mtmp)); 544. if (u.usym != 'a') { 545. losehp_m(rnd(6), mtmp); 546. if(!rn2(30)) corrode_armor(); 547. } 548. } 549. if(!rn2(6)) corrode_weapon(); 550. } 551. } 552. #ifdef KAA 553. if (malive) if (u.usym=='N' && mtmp->minvent) { 554. struct obj *otmp, *addinv(); 555. otmp = mtmp->minvent; 556. mtmp->minvent = otmp->nobj; 557. otmp = addinv(otmp); 558. pline("You steal:"); 559. prinv(otmp); 560. } else if (u.usym=='L' && mtmp->mgold) { 561. u.ugold += mtmp->mgold; 562. mtmp->mgold = 0; 563. pline("Your purse feels heavier."); 564. } else if (u.usym=='Q') rloc(mtmp); 565. #endif 566. if(malive && mdat->mlet == 'E' && canseemon(mtmp) 567. && !mtmp->mcan && rn2(3)) { 568. if(mtmp->mcansee) { 569. pline("You are frozen by %s's gaze!",monnam(mtmp)); 570. nomul((u.ulevel > 6 || rn2(4)) ? rn1(20,-21) : -200); 571. } else { 572. pline("%s cannot defend itself.", Amonnam(mtmp,"blinded")); 573. if(!rn2(500)) if((int)u.uluck > LUCKMIN) u.uluck--; 574. } 575. } 576. return(TRUE); 577. }