abstract
| - Below is the full text to mthrowu.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/mthrowu.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)mthrowu.c 3.3 1999/08/16 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. STATIC_DCL int FDECL(drop_throw,(struct obj *,BOOLEAN_P,int,int)); 8. 9. #define URETREATING(x,y) (distmin(u.ux,u.uy,x,y) > distmin(u.ux0,u.uy0,x,y)) 10. 11. #define POLE_LIM 5 /* How far monsters can use pole-weapons */ 12. 13. #ifndef OVLB 14. 15. STATIC_DCL const char *breathwep[]; 16. 17. #else /* OVLB */ 18. 19. /* 20. * Keep consistent with breath weapons in zap.c, and AD_* in monattk.h. 21. */ 22. STATIC_OVL NEARDATA const char *breathwep[] = { 23. "fragments", 24. "fire", 25. "frost", 26. "sleep gas", 27. "a disintegration blast", 28. "lightning", 29. "poison gas", 30. "acid", 31. "strange breath #8", 32. "strange breath #9" 33. }; 34. 35. 36. int 37. thitu(tlev, dam, obj, name) /* u is hit by sth, but not a monster */ 38. register int tlev, dam; 39. struct obj *obj; 40. register const char *name; 41. { 42. const char *onm = (obj && obj_is_pname(obj)) ? the(name) : 43. (obj && obj->quan > 1) ? name : an(name); 44. boolean is_acid = (obj && obj->otyp == ACID_VENOM); 45. 46. if(u.uac + tlev <= rnd(20)) { 47. if(Blind || !flags.verbose) pline("It misses."); 48. else You("are almost hit by %s!", onm); 49. return(0); 50. } else { 51. if(Blind || !flags.verbose) You("are hit!"); 52. else You("are hit by %s!", onm); 53. 54. if (obj && objects[obj->otyp].oc_material == SILVER 55. && hates_silver(youmonst.data)) { 56. dam += rnd(20); 57. pline_The("silver sears your flesh!"); 58. exercise(A_CON, FALSE); 59. } 60. if (is_acid && Acid_resistance) 61. pline("It doesn't seem to hurt you."); 62. else { 63. if (is_acid) pline("It burns!"); 64. if (Half_physical_damage) dam = (dam+1) / 2; 65. losehp(dam, name, (obj && obj_is_pname(obj)) ? 66. KILLED_BY : KILLED_BY_AN); 67. exercise(A_STR, FALSE); 68. } 69. return(1); 70. } 71. } 72. 73. /* Be sure this corresponds with what happens to player-thrown objects in 74. * dothrow.c (for consistency). --KAA 75. * Returns 0 if object still exists (not destroyed). 76. */ 77. 78. STATIC_OVL int 79. drop_throw(obj, ohit, x, y) 80. register struct obj *obj; 81. boolean ohit; 82. int x,y; 83. { 84. int retvalu = 1; 85. int create; 86. struct monst *mtmp; 87. struct trap *t; 88. 89. if (obj->otyp == CREAM_PIE || obj->oclass == VENOM_CLASS || 90. (ohit && obj->otyp == EGG)) 91. create = 0; 92. else if (ohit && (is_multigen(obj) || obj->otyp == ROCK)) 93. create = !rn2(3); 94. else create = 1; 95. 96. if (create && !((mtmp = m_at(x, y)) && (mtmp->mtrapped) && 97. (t = t_at(x, y)) && ((t->ttyp == PIT) || 98. (t->ttyp == SPIKED_PIT)))) { 99. int objgone = 0; 100. 101. if (down_gate(x, y) != -1) 102. objgone = ship_object(obj, x, y, FALSE); 103. if (!objgone) { 104. if (!flooreffects(obj,x,y,"fall")) { /* don't double-dip on damage */ 105. place_object(obj, x, y); 106. stackobj(obj); 107. retvalu = 0; 108. } 109. } 110. } else obfree(obj, (struct obj*) 0); 111. return retvalu; 112. } 113. 114. #endif /* OVLB */ 115. #ifdef OVL1 116. 117. /* an object launched by someone/thing other than player attacks a monster; 118. return 1 if the object has stopped moving (hit or its range used up) */ 119. int 120. ohitmon(mtmp, otmp, range, verbose) 121. struct monst *mtmp; /* accidental target */ 122. struct obj *otmp; /* missile; might be destroyed by drop_throw */ 123. int range; /* how much farther will object travel if it misses */ 124. /* Use -1 to signify to keep going even after hit, */ 125. /* unless its gone (used for rolling_boulder_traps) */ 126. boolean verbose; /* give message(s) even when you can't see what happened */ 127. { 128. int damage, tmp; 129. boolean vis, ismimic; 130. int objgone = 1; 131. 132. ismimic = mtmp->m_ap_type && mtmp->m_ap_type != M_AP_MONSTER; 133. vis = cansee(bhitpos.x, bhitpos.y); 134. 135. tmp = 5 + find_mac(mtmp) + omon_adj(mtmp, otmp, FALSE); 136. if (tmp < rnd(20)) { 137. if (!ismimic) { 138. if (vis) miss(distant_name(otmp, xname), mtmp); 139. else if (verbose) pline("It is missed."); 140. } 141. if (!range) { /* Last position; object drops */ 142. (void) drop_throw(otmp, 0, mtmp->mx, mtmp->my); 143. return 1; 144. } 145. } else if (otmp->oclass == POTION_CLASS) { 146. if (ismimic) seemimic(mtmp); 147. mtmp->msleeping = 0; 148. if (vis) otmp->dknown = 1; 149. potionhit(mtmp, otmp, FALSE); 150. return 1; 151. } else { 152. damage = dmgval(otmp, mtmp); 153. if (otmp->otyp == ACID_VENOM && resists_acid(mtmp)) 154. damage = 0; 155. if (ismimic) seemimic(mtmp); 156. mtmp->msleeping = 0; 157. if (vis) hit(distant_name(otmp,xname), mtmp, exclam(damage)); 158. else if (verbose) pline("It is hit%s", exclam(damage)); 159. 160. if (otmp->opoisoned) { 161. if (resists_poison(mtmp)) { 162. if (vis) pline_The("poison doesn't seem to affect %s.", 163. mon_nam(mtmp)); 164. } else { 165. if (rn2(30)) { 166. damage += rnd(6); 167. } else { 168. if (vis) pline_The("poison was deadly..."); 169. damage = mtmp->mhp; 170. } 171. } 172. } 173. if (objects[otmp->otyp].oc_material == SILVER && 174. hates_silver(mtmp->data)) { 175. if (vis) pline_The("silver sears %s flesh!", 176. s_suffix(mon_nam(mtmp))); 177. else if (verbose) pline("Its flesh is seared!"); 178. } 179. if (otmp->otyp == ACID_VENOM && cansee(mtmp->mx,mtmp->my)) { 180. if (resists_acid(mtmp)) { 181. if (vis || verbose) 182. pline("%s is unaffected.", Monnam(mtmp)); 183. damage = 0; 184. } else { 185. if (vis) pline_The("acid burns %s!", mon_nam(mtmp)); 186. else if (verbose) pline("It is burned!"); 187. } 188. } 189. mtmp->mhp -= damage; 190. if (mtmp->mhp < 1) { 191. if (vis || verbose) 192. pline("%s is %s!", Monnam(mtmp), 193. (nonliving(mtmp->data) || !vis) 194. ? "destroyed" : "killed"); 195. mondied(mtmp); 196. } 197. 198. if ((otmp->otyp == CREAM_PIE || otmp->otyp == BLINDING_VENOM) && 199. haseyes(mtmp->data)) { 200. /* note: resists_blnd() doesn't apply here */ 201. if (vis) pline("%s is blinded by %s.", 202. Monnam(mtmp), the(xname(otmp))); 203. mtmp->mcansee = 0; 204. tmp = (int)mtmp->mblinded + rnd(25) + 20; 205. if (tmp > 127) tmp = 127; 206. mtmp->mblinded = tmp; 207. } 208. 209. objgone = drop_throw(otmp, 1, bhitpos.x, bhitpos.y); 210. if (!objgone && range == -1) { /* special case */ 211. obj_extract_self(otmp); /* free it for motion again */ 212. return 0; 213. } 214. return 1; 215. } 216. return 0; 217. } 218. 219. void 220. m_throw(mon, x, y, dx, dy, range, obj) 221. register struct monst *mon; 222. register int x,y,dx,dy,range; /* direction and range */ 223. register struct obj *obj; 224. { 225. register struct monst *mtmp; 226. struct obj *singleobj; 227. char sym = obj->oclass; 228. int hitu, blindinc = 0; 229. 230. bhitpos.x = x; 231. bhitpos.y = y; 232. 233. if (obj->quan == 1L) { 234. /* 235. * Remove object from minvent. This cannot be done later on; 236. * what if the player dies before then, leaving the monster 237. * with 0 daggers? (This caused the infamous 2^32-1 orcish 238. * dagger bug). 239. * 240. * VENOM is not in minvent - it should already be OBJ_FREE. 241. * The extract below does nothing. 242. */ 243. 244. /* not possibly_unwield, which checks the object's */ 245. /* location, not its existence */ 246. if (MON_WEP(mon) == obj) { 247. obj->owornmask &= ~W_WEP; 248. MON_NOWEP(mon); 249. } 250. obj_extract_self(obj); 251. singleobj = obj; 252. obj = (struct obj *) 0; 253. } else { 254. singleobj = splitobj(obj, obj->quan - 1L); 255. obj_extract_self(singleobj); 256. } 257. 258. singleobj->owornmask = 0; /* threw one of multiple weapons in hand? */ 259. 260. if (singleobj->cursed && (dx || dy) && !rn2(7)) { 261. if(canseemon(mon) && flags.verbose) { 262. if(is_ammo(singleobj)) 263. pline("%s misfires!", Monnam(mon)); 264. else 265. pline("%s slips as %s throws it!", 266. The(xname(singleobj)), mon_nam(mon)); 267. } 268. dx = rn2(3)-1; 269. dy = rn2(3)-1; 270. /* pre-check validity of new direction */ 271. if((!dx && !dy) 272. || !isok(bhitpos.x+dx,bhitpos.y+dy) 273. /* missile hits the wall */ 274. || IS_ROCK(levl[bhitpos.x+dx][bhitpos.y+dy].typ)) { 275. (void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y); 276. return; 277. } 278. } 279. 280. /* Note: drop_throw may destroy singleobj. Since obj must be destroyed 281. * early to avoid the dagger bug, anyone who modifies this code should 282. * be careful not to use either one after it's been freed. 283. */ 284. if (sym) tmp_at(DISP_FLASH, obj_to_glyph(singleobj)); 285. while(range-- > 0) { /* Actually the loop is always exited by break */ 286. bhitpos.x += dx; 287. bhitpos.y += dy; 288. if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) { 289. if (ohitmon(mtmp, singleobj, range, TRUE)) 290. break; 291. } else if (bhitpos.x == u.ux && bhitpos.y == u.uy) { 292. if (multi) nomul(0); 293. 294. if (singleobj->oclass == GEM_CLASS && 295. singleobj->otyp <= LAST_GEM+9 /* 9 glass colors */ 296. && is_unicorn(youmonst.data)) { 297. if (singleobj->otyp > LAST_GEM) { 298. You("catch the %s.", xname(singleobj)); 299. You("are not interested in %s junk.", 300. s_suffix(mon_nam(mon))); 301. makeknown(singleobj->otyp); 302. dropy(singleobj); 303. } else { 304. You("accept %s gift in the spirit in which it was intended.", 305. s_suffix(mon_nam(mon))); 306. (void)hold_another_object(singleobj, 307. "You catch, but drop, %s.", xname(singleobj), 308. "You catch:"); 309. } 310. break; 311. } 312. if (singleobj->oclass == POTION_CLASS) { 313. if (!Blind) singleobj->dknown = 1; 314. potionhit(&youmonst, singleobj, FALSE); 315. break; 316. } 317. switch(singleobj->otyp) { 318. int dam, hitv; 319. case EGG: 320. if (!touch_petrifies(&mons[singleobj->corpsenm])) { 321. impossible("monster throwing egg type %d", 322. singleobj->corpsenm); 323. hitu = 0; 324. break; 325. } 326. /* fall through */ 327. case CREAM_PIE: 328. case BLINDING_VENOM: 329. hitu = thitu(8, 0, singleobj, xname(singleobj)); 330. break; 331. default: 332. dam = dmgval(singleobj, &youmonst); 333. hitv = 3 - distmin(u.ux,u.uy, mon->mx,mon->my); 334. if (hitv < -4) hitv = -4; 335. if (is_elf(mon->data) && 336. objects[singleobj->otyp].oc_skill == P_BOW) { 337. hitv++; 338. if (MON_WEP(mon) && 339. MON_WEP(mon)->otyp == ELVEN_BOW) 340. hitv++; 341. if(singleobj->otyp == ELVEN_ARROW) dam++; 342. } 343. if (bigmonst(youmonst.data)) hitv++; 344. hitv += 8+singleobj->spe; 345. 346. if (dam < 1) dam = 1; 347. hitu = thitu(hitv, dam, 348. singleobj, xname(singleobj)); 349. } 350. if (hitu && singleobj->opoisoned) { 351. char *singlename = xname(singleobj); 352. poisoned(singlename, A_STR, singlename, 10); 353. } 354. if(hitu && (singleobj->otyp == CREAM_PIE || 355. singleobj->otyp == BLINDING_VENOM)) { 356. blindinc = rnd(25); 357. if(singleobj->otyp == CREAM_PIE) { 358. if(!Blind) pline("Yecch! You've been creamed."); 359. else pline("There's %s sticky all over your %s.", 360. something, 361. body_part(FACE)); 362. } else { /* venom in the eyes */ 363. if(ublindf) /* nothing */ ; 364. else if(!Blind) pline_The("venom blinds you."); 365. else Your("%s sting.", makeplural(body_part(EYE))); 366. } 367. } 368. if (hitu && singleobj->otyp == EGG) { 369. if (!Stone_resistance 370. && !(poly_when_stoned(youmonst.data) && 371. polymon(PM_STONE_GOLEM))) 372. Stoned = 5; 373. } 374. stop_occupation(); 375. if (hitu || !range) { 376. (void) drop_throw(singleobj, hitu, u.ux, u.uy); 377. break; 378. } 379. } else if (!range /* reached end of path */ 380. /* missile hits edge of screen */ 381. || !isok(bhitpos.x+dx,bhitpos.y+dy) 382. /* missile hits the wall */ 383. || IS_ROCK(levl[bhitpos.x+dx][bhitpos.y+dy].typ) 384. #ifdef SINKS 385. /* Thrown objects "sink" */ 386. || IS_SINK(levl[bhitpos.x][bhitpos.y].typ) 387. #endif 388. ) { 389. (void) drop_throw(singleobj, 0, bhitpos.x, bhitpos.y); 390. break; 391. } 392. tmp_at(bhitpos.x, bhitpos.y); 393. delay_output(); 394. } 395. tmp_at(bhitpos.x, bhitpos.y); 396. delay_output(); 397. tmp_at(DISP_END, 0); 398. /* blindfolds, towels, & lenses keep substances out of your eyes */ 399. if (blindinc && !ublindf) { 400. u.ucreamed += blindinc; 401. make_blinded(Blinded + blindinc,FALSE); 402. } 403. } 404. 405. #endif /* OVL1 */ 406. #ifdef OVLB 407. 408. /* Remove an item from the monster's inventory and destroy it. */ 409. void 410. m_useup(mon, obj) 411. struct monst *mon; 412. struct obj *obj; 413. { 414. if (obj->quan > 1L) { 415. obj->quan--; 416. } else { 417. obj_extract_self(obj); 418. possibly_unwield(mon); 419. if (obj->owornmask) { 420. mon->misc_worn_check &= ~obj->owornmask; 421. update_mon_intrinsics(mon, obj, FALSE); 422. } 423. dealloc_obj(obj); 424. } 425. } 426. 427. #endif /* OVLB */ 428. #ifdef OVL1 429. 430. void 431. thrwmu(mtmp) /* monster throws item at you */ 432. register struct monst *mtmp; 433. { 434. struct obj *otmp; 435. register xchar x, y; 436. boolean ispole; 437. schar skill; 438. int multishot = 1; 439. 440. 441. /* Rearranged beginning so monsters can use polearms not in a line */ 442. if (mtmp->weapon_check == NEED_WEAPON || !MON_WEP(mtmp)) { 443. mtmp->weapon_check = NEED_RANGED_WEAPON; 444. /* mon_wield_item resets weapon_check as appropriate */ 445. if(mon_wield_item(mtmp) != 0) return; 446. } 447. 448. /* Pick a weapon */ 449. otmp = select_rwep(mtmp); 450. if (!otmp) return; 451. ispole = is_pole(otmp); 452. skill = objects[otmp->otyp].oc_skill; 453. 454. if(ispole || lined_up(mtmp)) { 455. /* If you are coming toward the monster, the monster 456. * should try to soften you up with missiles. If you are 457. * going away, you are probably hurt or running. Give 458. * chase, but if you are getting too far away, throw. 459. */ 460. x = mtmp->mx; 461. y = mtmp->my; 462. if(ispole || !URETREATING(x,y) || 463. !rn2(BOLT_LIM-distmin(x,y,mtmp->mux,mtmp->muy))) 464. { 465. const char *verb = "throws"; 466. 467. if (otmp->otyp == ARROW 468. || otmp->otyp == ELVEN_ARROW 469. || otmp->otyp == ORCISH_ARROW 470. || otmp->otyp == YA 471. || otmp->otyp == CROSSBOW_BOLT) verb = "shoots"; 472. if (ispole) { 473. if (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 474. POLE_LIM && couldsee(mtmp->mx, mtmp->my)) 475. verb = "thrusts"; 476. else return; /* Out of range, or intervening wall */ 477. } 478. 479. if (canseemon(mtmp)) { 480. pline("%s %s %s!", Monnam(mtmp), verb, 481. obj_is_pname(otmp) ? 482. the(singular(otmp, xname)) : 483. an(singular(otmp, xname))); 484. } 485. 486. /* Use a pole */ 487. if (ispole) { 488. int dam = dmgval(otmp, &youmonst); 489. int hitv = 3 - distmin(u.ux,u.uy, mtmp->mx,mtmp->my); 490. 491. if (hitv < -4) hitv = -4; 492. if (bigmonst(youmonst.data)) hitv++; 493. hitv += 8 + otmp->spe; 494. if (dam < 1) dam = 1; 495. (void) thitu(hitv, dam, otmp, xname(otmp)); 496. 497. return; 498. } 499. 500. /* Multishot calculations */ 501. if (((ammo_and_launcher(otmp, MON_WEP(mtmp)) && skill != -P_SLING) || 502. skill == P_DAGGER || skill == P_DART || 503. skill == P_SHURIKEN) && !mtmp->mconf) { 504. /* Assumes lords are skilled, princes are expert */ 505. if (is_lord(mtmp->data)) multishot++; 506. if (is_prince(mtmp->data)) multishot += 2; 507. 508. switch (monsndx(mtmp->data)) { 509. case PM_RANGER: 510. multishot++; 511. break; 512. case PM_ROGUE: 513. if (skill == P_DAGGER) multishot++; 514. break; 515. case PM_SAMURAI: 516. if (otmp->otyp == YA && MON_WEP(mtmp) && 517. MON_WEP(mtmp)->otyp == YUMI) multishot++; 518. break; 519. default: 520. if (is_elf(mtmp->data) && otmp->otyp == ELVEN_ARROW && 521. MON_WEP(mtmp) && MON_WEP(mtmp)->otyp == ELVEN_BOW) 522. multishot++; 523. break; 524. } 525. } 526. if (otmp->quan < multishot) multishot = (int)otmp->quan; 527. if (multishot < 1) multishot = 1; 528. else multishot = rnd(multishot); 529. while (multishot-- > 0) 530. m_throw(mtmp, mtmp->mx, mtmp->my, sgn(tbx), sgn(tby), 531. distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp); 532. nomul(0); 533. return; 534. } 535. } 536. } 537. 538. #endif /* OVL1 */ 539. #ifdef OVLB 540. 541. int 542. spitmu(mtmp, mattk) /* monster spits substance at you */ 543. register struct monst *mtmp; 544. register struct attack *mattk; 545. { 546. register struct obj *otmp; 547. 548. if(mtmp->mcan) { 549. 550. if(flags.soundok) 551. pline("A dry rattle comes from %s throat.", 552. s_suffix(mon_nam(mtmp))); 553. return 0; 554. } 555. if(lined_up(mtmp)) { 556. switch (mattk->adtyp) { 557. case AD_BLND: 558. case AD_DRST: 559. otmp = mksobj(BLINDING_VENOM, TRUE, FALSE); 560. break; 561. default: 562. impossible("bad attack type in spitmu"); 563. /* fall through */ 564. case AD_ACID: 565. otmp = mksobj(ACID_VENOM, TRUE, FALSE); 566. break; 567. } 568. if(!rn2(BOLT_LIM-distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy))) { 569. if (canseemon(mtmp)) 570. pline("%s spits venom!", Monnam(mtmp)); 571. m_throw(mtmp, mtmp->mx, mtmp->my, sgn(tbx), sgn(tby), 572. distmin(mtmp->mx,mtmp->my,mtmp->mux,mtmp->muy), otmp); 573. nomul(0); 574. return 0; 575. } 576. } 577. return 0; 578. } 579. 580. #endif /* OVLB */ 581. #ifdef OVL1 582. 583. int 584. breamu(mtmp, mattk) /* monster breathes at you (ranged) */ 585. register struct monst *mtmp; 586. register struct attack *mattk; 587. { 588. /* if new breath types are added, change AD_ACID to max type */ 589. int typ = (mattk->adtyp == AD_RBRE) ? rnd(AD_ACID) : mattk->adtyp ; 590. 591. if(lined_up(mtmp)) { 592. 593. if(mtmp->mcan) { 594. if(flags.soundok) { 595. if(canseemon(mtmp)) 596. pline("%s coughs.", Monnam(mtmp)); 597. else 598. You_hear("a cough."); 599. } 600. return(0); 601. } 602. if(!mtmp->mspec_used && rn2(3)) { 603. 604. if((typ >= AD_MAGM) && (typ <= AD_ACID)) { 605. 606. if(canseemon(mtmp)) 607. pline("%s breathes %s!", Monnam(mtmp), 608. breathwep[typ-1]); 609. buzz((int) (-20 - (typ-1)), (int)mattk->damn, 610. mtmp->mx, mtmp->my, sgn(tbx), sgn(tby)); 611. nomul(0); 612. /* breath runs out sometimes. Also, give monster some 613. * cunning; don't breath if the player fell asleep. 614. */ 615. if(!rn2(3)) 616. mtmp->mspec_used = 10+rn2(20); 617. if(typ == AD_SLEE && !Sleep_resistance) 618. mtmp->mspec_used += rnd(20); 619. } else impossible("Breath weapon %d used", typ-1); 620. } 621. } 622. return(1); 623. } 624. 625. boolean 626. linedup(ax, ay, bx, by) 627. register xchar ax, ay, bx, by; 628. { 629. tbx = ax - bx; /* These two values are set for use */ 630. tby = ay - by; /* after successful return. */ 631. 632. /* sometimes displacement makes a monster think that you're at its 633. own location; prevent it from throwing and zapping in that case */ 634. if (!tbx && !tby) return FALSE; 635. 636. if((!tbx || !tby || abs(tbx) == abs(tby)) /* straight line or diagonal */ 637. && distmin(tbx, tby, 0, 0) < BOLT_LIM) { 638. if(ax == u.ux && ay == u.uy) return((boolean)(couldsee(bx,by))); 639. else if(clear_path(ax,ay,bx,by)) return TRUE; 640. } 641. return FALSE; 642. } 643. 644. boolean 645. lined_up(mtmp) /* is mtmp in position to use ranged attack? */ 646. register struct monst *mtmp; 647. { 648. return(linedup(mtmp->mux,mtmp->muy,mtmp->mx,mtmp->my)); 649. } 650. 651. #endif /* OVL1 */ 652. #ifdef OVL0 653. 654. /* Check if a monster is carrying a particular item. 655. */ 656. struct obj * 657. m_carrying(mtmp, type) 658. struct monst *mtmp; 659. int type; 660. { 661. register struct obj *otmp; 662. 663. for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj) 664. if(otmp->otyp == type) 665. return(otmp); 666. return((struct obj *) 0); 667. } 668. 669. #endif /* OVL0 */ 670. 671. /*mthrowu.c*/
|