Source:NetHack 3.3.0/mthrowu.c

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*/