Source:NetHack 3.4.0/apply.c

Below is the full text to apply.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/apply.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)apply.c	3.4	2002/03/09	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6.    #include "edog.h"  7. 8.   #ifdef OVLB 9.    10.   static const char tools[] = { TOOL_CLASS, WEAPON_CLASS, WAND_CLASS, 0 }; 11.  static const char tools_too[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS, 12.  				  WEAPON_CLASS, WAND_CLASS, GEM_CLASS, 0 }; 13.   14.   #ifdef TOURIST 15.  STATIC_DCL int FDECL(use_camera, (struct obj *)); 16.  #endif 17.  STATIC_DCL int FDECL(use_towel, (struct obj *)); 18.  STATIC_DCL boolean FDECL(its_dead, (int,int,int *)); 19.  STATIC_DCL int FDECL(use_stethoscope, (struct obj *)); 20.  STATIC_DCL void FDECL(use_whistle, (struct obj *)); 21.  STATIC_DCL void FDECL(use_magic_whistle, (struct obj *)); 22.  STATIC_DCL void FDECL(use_leash, (struct obj *)); 23.  STATIC_DCL int FDECL(use_mirror, (struct obj *)); 24.  STATIC_DCL void FDECL(use_bell, (struct obj *)); 25.  STATIC_DCL void FDECL(use_candelabrum, (struct obj *)); 26.  STATIC_DCL void FDECL(use_candle, (struct obj *)); 27.  STATIC_DCL void FDECL(use_lamp, (struct obj *)); 28.  STATIC_DCL void FDECL(light_cocktail, (struct obj *)); 29.  STATIC_DCL void FDECL(use_tinning_kit, (struct obj *)); 30.  STATIC_DCL void FDECL(use_figurine, (struct obj *)); 31.  STATIC_DCL void FDECL(use_grease, (struct obj *)); 32.  STATIC_DCL void FDECL(use_trap, (struct obj *)); 33.  STATIC_DCL void FDECL(use_stone, (struct obj *)); 34.  STATIC_PTR int NDECL(set_trap);		/* occupation callback */ 35.  STATIC_DCL int FDECL(use_whip, (struct obj *)); 36.  STATIC_DCL int FDECL(use_pole, (struct obj *)); 37.  STATIC_DCL int FDECL(use_grapple, (struct obj *)); 38.  STATIC_DCL int FDECL(do_break_wand, (struct obj *)); 39.  STATIC_DCL boolean FDECL(figurine_location_checks,  40.   				(struct obj *, coord *, BOOLEAN_P)); 41.  STATIC_DCL boolean NDECL(uhave_graystone); 42.   43.   #ifdef	AMIGA 44.  void FDECL( amii_speaker, ( struct obj *, char *, int ) ); 45.  #endif 46.   47.   static char no_elbow_room[] = "don't have enough elbow-room to maneuver."; 48.   49.   #ifdef TOURIST 50.  STATIC_OVL int 51.  use_camera(obj) 52.  	struct obj *obj; 53.  {  54.   	register struct monst *mtmp; 55.   56.   	if(Underwater) { 57.  		pline("Using your camera underwater would void the warranty."); 58.  		return(0); 59.  	}  60.   	if(!getdir((char *)0)) return(0); 61.   62.   	if (obj->spe <= 0) { 63.  		pline(nothing_happens); 64.  		return (1); 65.  	}  66.   	check_unpaid(obj); 67.  	obj->spe--; 68.  	if (obj->cursed && !rn2(2)) { 69.  		(void) zapyourself(obj, TRUE); 70.  	} else if (u.uswallow) { 71.  		You("take a picture of %s %s.", s_suffix(mon_nam(u.ustuck)),  72.   		    mbodypart(u.ustuck, STOMACH)); 73.  	} else if (u.dz) { 74.  		You("take a picture of the %s.",  75.   			(u.dz > 0) ? surface(u.ux,u.uy) : ceiling(u.ux,u.uy)); 76.  	} else if (!u.dx && !u.dy) { 77.  		(void) zapyourself(obj, TRUE); 78.  	} else if ((mtmp = bhit(u.dx, u.dy, COLNO, FLASHED_LIGHT,  79.   				(int FDECL((*),(MONST_P,OBJ_P)))0,  80.   				(int FDECL((*),(OBJ_P,OBJ_P)))0,  81.   				obj)) != 0) { 82.  		obj->ox = u.ux,  obj->oy = u.uy; 83.  		(void) flash_hits_mon(mtmp, obj); 84.  	}  85.   	return 1; 86.  }  87.   #endif 88.   89.   STATIC_OVL int 90.  use_towel(obj) 91.  	struct obj *obj; 92.  {  93.   	if(!freehand) { 94.  		You("have no free %s!", body_part(HAND)); 95.  		return 0; 96.  	} else if (obj->owornmask) { 97.  		You("cannot use it while you're wearing it!"); 98.  		return 0; 99.  	} else if (obj->cursed) { 100. 		long old; 101. 		switch (rn2(3)) { 102. 		case 2: 103. 		    old = Glib; 104. 		    Glib += rn1(10, 3); 105. 		    Your("%s %s!", makeplural(body_part(HAND)),  106.  			(old ? "are filthier than ever" : "get slimy")); 107. 		    return 1; 108. 		case 1: 109. 		    if (!ublindf) { 110. 			old = u.ucreamed; 111. 			u.ucreamed += rn1(10, 3); 112. 			pline("Yecch! Your %s %s gunk on it!", body_part(FACE),  113.  			      (old ? "has more" : "now has")); 114. 			make_blinded(Blinded + (long)u.ucreamed - old, TRUE); 115. 		    } else { 116. 			const char *what = (ublindf->otyp == LENSES) ? 117. 					    "lenses" : "blindfold"; 118. 			if (ublindf->cursed) { 119. 			    You("push your %s %s.", what,  120.  				rn2(2) ? "cock-eyed" : "crooked"); 121. 			} else { 122. 			    struct obj *saved_ublindf = ublindf; 123. 			    You("push your %s off.", what); 124. 			    Blindf_off(ublindf); 125. 			    dropx(saved_ublindf); 126. 			}  127.  		    }  128.  		    return 1; 129. 		case 0: 130. 		    break; 131. 		}  132.  	}  133.   134.  	if (Glib) { 135. 		Glib = 0; 136. 		You("wipe off your %s.", makeplural(body_part(HAND))); 137. 		return 1; 138. 	} else if(u.ucreamed) { 139. 		Blinded -= u.ucreamed; 140. 		u.ucreamed = 0; 141.  142.  		if (!Blinded) { 143. 			pline("You've got the glop off."); 144. 			Blinded = 1; 145. 			make_blinded(0L,TRUE); 146. 		} else { 147. 			Your("%s feels clean now.", body_part(FACE)); 148. 		}  149.  		return 1; 150. 	}  151.   152.  	Your("%s and %s are already clean.",  153.  		body_part(FACE), makeplural(body_part(HAND))); 154.  155.  	return 0; 156. }  157.   158.  /* maybe give a stethoscope message based on floor objects */ 159. STATIC_OVL boolean 160. its_dead(rx, ry, resp) 161. int rx, ry, *resp; 162. {  163.  	struct obj *otmp; 164. 	struct trap *ttmp; 165.  166.  	/* additional stethoscope messages from jyoung@apanix.apana.org.au */ 167. 	if (Hallucination && sobj_at(CORPSE, rx, ry)) { 168. 	    /* (a corpse doesn't retain the monster's sex,  169.  	       so we're forced to use generic pronoun here) */ 170. 	    You_hear("a voice say, \"It's dead, Jim.\""); 171. 	    *resp = 1; 172. 	    return TRUE; 173. 	} else if (Role_if(PM_HEALER) && ((otmp = sobj_at(CORPSE, rx, ry)) != 0 || 174. 				    (otmp = sobj_at(STATUE, rx, ry)) != 0)) { 175. 	    /* possibly should check uppermost {corpse,statue} in the pile 176. 	       if both types are present, but it's not worth the effort */ 177. 	    if (vobj_at(rx, ry)->otyp == STATUE) otmp = vobj_at(rx, ry); 178. 	    if (otmp->otyp == CORPSE) { 179. 		You("determine that %s unfortunate being is dead.",  180.  		    (rx == u.ux && ry == u.uy) ? "this" : "that"); 181. 	    } else { 182. 		ttmp = t_at(rx, ry); 183. 		pline("%s appears to be in %s health for a statue.",  184.  		      The(mons[otmp->corpsenm].mname),  185.  		      (ttmp && ttmp->ttyp == STATUE_TRAP) ?  186.  			"extraordinary" : "excellent"); 187. 	    }  188.  	    return TRUE; 189. 	}  190.  	return FALSE; 191. }  192.   193.  static char hollow_str[] = "a hollow sound.  This must be a secret %s!"; 194.  195.  /* Strictly speaking it makes no sense for usage of a stethoscope to  196. not take any time; however, unless it did, the stethoscope would be 197. almost useless. As a compromise, one use per turn is free, another 198.    uses up the turn; this makes curse status have a tangible effect. */ 199.  STATIC_OVL int 200. use_stethoscope(obj) 201. 	register struct obj *obj; 202. {  203.  	static long last_used = 0; 204. 	struct monst *mtmp; 205. 	struct rm *lev; 206. 	int rx, ry, res; 207.  208.  	if (nohands(youmonst.data)) {	/* should also check for no ears and/or deaf */ 209. 		You("have no hands!");	/* not `body_part(HAND)' */ 210. 		return 0; 211. 	} else if (!freehand) { 212. 		You("have no free %s.", body_part(HAND)); 213. 		return 0; 214. 	}  215.  	if (!getdir((char *)0)) return 0; 216.  217.  	res = (moves + monstermoves == last_used); 218. 	last_used = moves + monstermoves; 219.  220.  	if (u.uswallow && (u.dx || u.dy || u.dz)) { 221. 		mstatusline(u.ustuck); 222. 		return res; 223. #ifdef STEED 224. 	} else if (u.usteed && u.dz > 0) { 225. 		mstatusline(u.usteed); 226. 		return res; 227. #endif 228. 	} else if (u.dz) { 229. 		if (Underwater) 230. 		    You_hear("faint splashing."); 231. 		else if (u.dz < 0 || !can_reach_floor) 232. 		    You_cant("reach the %s.",  233.  			(u.dz > 0) ? surface(u.ux,u.uy) : ceiling(u.ux,u.uy)); 234. 		else if (its_dead(u.ux, u.uy, &res)) 235. 		    ;	/* message already given */ 236. 		else if (Is_stronghold(&u.uz)) 237. 		    You_hear("the crackling of hellfire."); 238. 		else 239. 		    pline_The("%s seems healthy enough.", surface(u.ux,u.uy)); 240. 		return res; 241. 	} else if (obj->cursed && !rn2(2)) { 242. 		You_hear("your heart beat."); 243. 		return res; 244. 	}  245.  	if (Stunned || (Confusion && !rn2(5))) confdir; 246. 	if (!u.dx && !u.dy) { 247. 		ustatusline; 248. 		return res; 249. 	}  250.  	rx = u.ux + u.dx; ry = u.uy + u.dy; 251. 	if (!isok(rx,ry)) { 252. 		You_hear("a faint typing noise."); 253. 		return 0; 254. 	}  255.  	if ((mtmp = m_at(rx,ry)) != 0) { 256. 		mstatusline(mtmp); 257. 		if (mtmp->mundetected) { 258. 			mtmp->mundetected = 0; 259. 			if (cansee(rx,ry)) newsym(mtmp->my,mtmp->my); 260. 		}  261.  		if (!canspotmon(mtmp)) 262. 			map_invisible(rx,ry); 263. 		return res; 264. 	}  265.  	if (glyph_is_invisible(levl[rx][ry].glyph)) { 266. 		unmap_object(rx, ry); 267. 		newsym(rx, ry); 268. 		pline_The("invisible monster must have moved."); 269. 	}  270.  	lev = &levl[rx][ry]; 271. 	switch(lev->typ) { 272. 	case SDOOR: 273. 		You_hear(hollow_str, "door"); 274. 		cvt_sdoor_to_door(lev);		/* ->typ = DOOR */ 275. 		if (Blind) feel_location(rx,ry); 276. 		else newsym(rx,ry); 277. 		return res; 278. 	case SCORR: 279. 		You_hear(hollow_str, "passage"); 280. 		lev->typ = CORR; 281. 		unblock_point(rx,ry); 282. 		if (Blind) feel_location(rx,ry); 283. 		else newsym(rx,ry); 284. 		return res; 285. 	}  286.   287.  	if (!its_dead(rx, ry, &res)) 288. 	    You("hear nothing special.");	/* not You_hear  */ 289. 	return res; 290. }  291.   292.  static char whistle_str[] = "produce a %s whistling sound."; 293.  294.  STATIC_OVL void 295. use_whistle(obj) 296. struct obj *obj; 297. {  298.  	You(whistle_str, obj->cursed ? "shrill" : "high"); 299. 	wake_nearby; 300. }  301.   302.  STATIC_OVL void 303. use_magic_whistle(obj) 304. struct obj *obj; 305. {  306.  	register struct monst *mtmp, *nextmon; 307.  308.  	if(obj->cursed && !rn2(2)) { 309. 		You("produce a high-pitched humming noise."); 310. 		wake_nearby; 311. 	} else { 312. 		int pet_cnt = 0; 313. 		You(whistle_str, Hallucination ? "normal" : "strange"); 314. 		for(mtmp = fmon; mtmp; mtmp = nextmon) { 315. 		    nextmon = mtmp->nmon; /* trap might kill mon */ 316. 		    if (DEADMONSTER(mtmp)) continue; 317. 		    if (mtmp->mtame) { 318. 			if (mtmp->mtrapped) { 319. 			    /* no longer in previous trap (affects mintrap) */ 320. 			    mtmp->mtrapped = 0; 321. 			    fill_pit(mtmp->mx, mtmp->my); 322. 			}  323.  			mnexto(mtmp); 324. 			if (canspotmon(mtmp)) ++pet_cnt; 325. 			if (mintrap(mtmp) == 2) change_luck(-1); 326. 		    }  327.  		}  328.  		if (pet_cnt > 0) makeknown(MAGIC_WHISTLE); 329. 	}  330.  }  331.   332.  boolean 333. um_dist(x,y,n) 334. register xchar x, y, n;  335. { 336.  	return((boolean)(abs(u.ux - x) > n  || abs(u.uy - y) > n)); 337. }  338.   339.  int 340. number_leashed 341. {  342.  	register int i = 0; 343. 	register struct obj *obj; 344.  345.  	for(obj = invent; obj; obj = obj->nobj) 346. 		if(obj->otyp == LEASH && obj->leashmon != 0) i++; 347. 	return(i); 348. }  349.   350.  void 351. o_unleash(otmp)		/* otmp is about to be destroyed or stolen */ 352. register struct obj *otmp; 353. {  354.  	register struct monst *mtmp; 355.  356.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 357. 		if(mtmp->m_id == (unsigned)otmp->leashmon) 358. 			mtmp->mleashed = 0; 359. 	otmp->leashmon = 0; 360. }  361.   362.  void 363. m_unleash(mtmp, feedback)	/* mtmp is about to die, or become untame */ 364. register struct monst *mtmp; 365. boolean feedback; 366. {  367.  	register struct obj *otmp; 368.  369.  	if (feedback) { 370. 	    if (canseemon(mtmp)) 371. 		pline("%s pulls free of %s leash!", Monnam(mtmp), mhis(mtmp)); 372. 	    else 373. 		Your("leash falls slack."); 374. 	}  375.  	for(otmp = invent; otmp; otmp = otmp->nobj) 376. 		if(otmp->otyp == LEASH &&  377.  				otmp->leashmon == (int)mtmp->m_id) 378. 			otmp->leashmon = 0; 379. 	mtmp->mleashed = 0; 380. }  381.   382.  void 383. unleash_all		/* player is about to die (for bones) */ 384. {  385.  	register struct obj *otmp; 386. 	register struct monst *mtmp; 387.  388.  	for(otmp = invent; otmp; otmp = otmp->nobj) 389. 		if(otmp->otyp == LEASH) otmp->leashmon = 0; 390. 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 391. 		mtmp->mleashed = 0; 392. }  393.   394.  #define MAXLEASHED	2 395.  396.  /* ARGSUSED */ 397. STATIC_OVL void 398. use_leash(obj) 399. struct obj *obj; 400. {  401.  	register int x, y;  402. register struct monst *mtmp; 403. 	int spotmon; 404.  405.  	if(!obj->leashmon && number_leashed >= MAXLEASHED) { 406. 		You("cannot leash any more pets."); 407. 		return; 408. 	}  409.   410.  	if(!getdir((char *)0)) return; 411.  412.  	x = u.ux + u.dx; 413. 	y = u.uy + u.dy; 414.  415.  	if((x == u.ux) && (y == u.uy)) { 416. #ifdef STEED 417. 		if (u.usteed && u.dz > 0) { 418. 		    mtmp = u.usteed; 419. 		    spotmon = 1; 420. 		    goto got_target; 421. 		}  422.  #endif 423. 		pline("Leash yourself?  Very funny..."); 424. 		return; 425. 	}  426.   427.  	if(!(mtmp = m_at(x, y))) { 428. 		There("is no creature there."); 429. 		return; 430. 	}  431.   432.  	spotmon = canspotmon(mtmp); 433. #ifdef STEED 434.  got_target: 435. #endif 436.  437.  	if(!mtmp->mtame) { 438. 	    if(!spotmon) 439. 		There("is no creature there."); 440. 	    else 441. 		pline("%s %s leashed!", Monnam(mtmp), (!obj->leashmon) ?  442.  				"cannot be" : "is not"); 443. 	    return; 444. 	}  445.  	if(!obj->leashmon) { 446. 		if(mtmp->mleashed) { 447. 			pline("This %s is already leashed.",  448.  			      spotmon ? l_monnam(mtmp) : "monster"); 449. 			return; 450. 		}  451.  		You("slip the leash around %s%s.",  452.  		    spotmon ? "your " : "", l_monnam(mtmp)); 453. 		mtmp->mleashed = 1; 454. 		obj->leashmon = (int)mtmp->m_id; 455. 		mtmp->msleeping = 0; 456. 		return; 457. 	}  458.  	if(obj->leashmon != (int)mtmp->m_id) { 459. 		pline("This leash is not attached to that creature."); 460. 		return; 461. 	} else { 462. 		if(obj->cursed) { 463. 			pline_The("leash would not come off!"); 464. 			obj->bknown = TRUE; 465. 			return; 466. 		}  467.  		mtmp->mleashed = 0; 468. 		obj->leashmon = 0; 469. 		You("remove the leash from %s%s.",  470.  		    spotmon ? "your " : "", l_monnam(mtmp)); 471. 	}  472.  	return; 473. }  474.   475.  struct obj * 476. get_mleash(mtmp)	/* assuming mtmp->mleashed has been checked */ 477. register struct monst *mtmp; 478. {  479.  	register struct obj *otmp; 480.  481.  	otmp = invent; 482. 	while(otmp) { 483. 		if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id) 484. 			return(otmp); 485. 		otmp = otmp->nobj; 486. 	}  487.  	return((struct obj *)0); 488. }  489.   490.  #endif /* OVLB */ 491. #ifdef OVL1 492.  493.  boolean 494. next_to_u 495. {  496.  	register struct monst *mtmp; 497. 	register struct obj *otmp; 498.  499.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 500. 		if (DEADMONSTER(mtmp)) continue; 501. 		if(mtmp->mleashed) { 502. 			if (distu(mtmp->mx,mtmp->my) > 2) mnexto(mtmp); 503. 			if (distu(mtmp->mx,mtmp->my) > 2) { 504. 			    for(otmp = invent; otmp; otmp = otmp->nobj) 505. 				if(otmp->otyp == LEASH &&  506.  					otmp->leashmon == (int)mtmp->m_id) { 507. 				    if(otmp->cursed) return(FALSE); 508. 				    You_feel("%s leash go slack.",  509.  					(number_leashed > 1) ? "a" : "the"); 510. 				    mtmp->mleashed = 0; 511. 				    otmp->leashmon = 0; 512. 				}  513.  			}  514.  		}  515.  	}  516.  #ifdef STEED 517. 	/* no pack mules for the Amulet */ 518. 	if (u.usteed && mon_has_amulet(u.usteed)) return FALSE; 519. #endif 520. 	return(TRUE); 521. }  522.   523.  #endif /* OVL1 */ 524. #ifdef OVL0 525.  526.  void 527. check_leash(x, y)  528. register xchar x, y; 529. { 530.  	register struct obj *otmp; 531. 	register struct monst *mtmp = fmon; 532.  533.  	for(otmp = invent; otmp; otmp = otmp->nobj) 534. 	    if(otmp->otyp == LEASH && otmp->leashmon != 0) { 535. 		while(mtmp) { 536. 		    if(!DEADMONSTER(mtmp) && ((int)mtmp->m_id == otmp->leashmon && 537. 			    (dist2(u.ux,u.uy,mtmp->mx,mtmp->my) >  538.  				dist2(x,y,mtmp->mx,mtmp->my)))  539.  			) { 540. 			if(otmp->cursed && !breathless(mtmp->data)) { 541. 			    if(um_dist(mtmp->mx, mtmp->my, 5)) { 542. 				pline("%s chokes to death!",Monnam(mtmp)); 543. 				mondied(mtmp); 544. 			    } else 545. 				if(um_dist(mtmp->mx, mtmp->my, 3)) 546. 					pline("%s chokes on the leash!",  547.  						Monnam(mtmp)); 548. 			} else { 549. 			    if(um_dist(mtmp->mx, mtmp->my, 5)) { 550. 				pline("%s leash snaps loose!",  551.  					s_suffix(Monnam(mtmp))); 552. 				m_unleash(mtmp, FALSE); 553. 			    } else { 554. 				if(um_dist(mtmp->mx, mtmp->my, 3)) { 555. 				    You("pull on the leash."); 556. 				    if (mtmp->data->msound != MS_SILENT) 557. 					switch(rn2(3)) { 558. 					    case 0:  growl(mtmp);	break; 559. 					    case 1:  yelp(mtmp);	break; 560. 					    default: whimper(mtmp); break; 561. 					}  562.  				}  563.  			    }  564.  			}  565.  		    }  566.  		    mtmp = mtmp->nmon; 567. 		}  568.  	    }  569.  }  570.   571.  #endif /* OVL0 */ 572. #ifdef OVLB 573.  574.  boolean 575. wield_tool(obj) 576. struct obj *obj; 577. {  578.  	if(welded(uwep)) { 579. 		/* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */ 580. 		if(flags.verbose) { 581. 			pline("Since your weapon is welded to your %s,",  582.  				bimanual(uwep) ?  583.  				(const char *)makeplural(body_part(HAND))  584.  				: body_part(HAND)); 585. 			pline("you cannot wield that %s.", xname(obj)); 586. 		}  587.  		return(FALSE); 588. 	}  589.  	if (cantwield(youmonst.data)) { 590. 		You_cant("hold it strongly enough."); 591. 		return(FALSE); 592. 	}  593.  	/* Check shield */ 594. 	if (uarms && bimanual(obj)) { 595. 		You("cannot wield a two-handed tool while wearing a shield."); 596. 		return(FALSE); 597. 	}  598.  	if(uquiver == obj) setuqwep((struct obj *)0); 599. 	if(uswapwep == obj) { 600. 	    (void) doswapweapon; 601. 	    /* If doswapweapon failed... */ 602.  	    if(uswapwep == obj) return (FALSE); 603. 	} else { 604. 	    You("now wield %s.", doname(obj)); 605. 	    setuwep(obj); 606. 	}  607.  	if (uwep != obj) return(FALSE); /* rewielded old object after dying */ 608. 	/* applying weapon or tool that gets wielded ends two-weapon combat */ 609. 	if (u.twoweap) 610. 		untwoweapon; 611. 	if (obj->oclass != WEAPON_CLASS) 612. 		unweapon = TRUE; 613. 	return(TRUE); 614. }  615.   616.  #define WEAK	3	/* from eat.c */ 617.  618.  static char look_str[] = "look %s."; 619.  620.  STATIC_OVL int 621. use_mirror(obj) 622. struct obj *obj; 623. {  624.  	register struct monst *mtmp; 625. 	register char mlet; 626. 	boolean vis; 627.  628.  	if(!getdir((char *)0)) return 0; 629. 	if(obj->cursed && !rn2(2)) { 630. 		if (!Blind) 631. 			pline_The("mirror fogs up and doesn't reflect!"); 632. 		return 1; 633. 	}  634.  	if(!u.dx && !u.dy && !u.dz) { 635. 		if(!Blind && !Invisible) { 636. 		    if (u.umonnum == PM_FLOATING_EYE) { 637. 			if (!Free_action) { 638. 			pline(Hallucination ?  639.  			      "Yow!  The mirror stares back!" :  640.  			      "Yikes!  You've frozen yourself!"); 641. 			nomul(-rnd((MAXULEV+6) - u.ulevel)); 642. 			} else You("stiffen momentarily under your gaze."); 643. 		    } else if (youmonst.data->mlet == S_VAMPIRE) 644. 			You("don't have a reflection."); 645. 		    else if (u.umonnum == PM_UMBER_HULK) { 646. 			pline("Huh?  That doesn't look like you!"); 647. 			make_confused(HConfusion + d(3,4),FALSE); 648. 		    } else if (Hallucination) 649. 			You(look_str, hcolor((char *)0)); 650. 		    else if (Sick) 651. 			You(look_str, "peaked"); 652. 		    else if (u.uhs >= WEAK) 653. 			You(look_str, "undernourished"); 654. 		    else You("look as %s as ever.",  655.  				ACURR(A_CHA) > 14 ?  656.  				(poly_gender==1 ? "beautiful" : "handsome") : 657.  				"ugly"); 658. 		} else { 659. 			You_cant("see your %s %s.",  660.  				ACURR(A_CHA) > 14 ?  661.  				(poly_gender==1 ? "beautiful" : "handsome") : 662.  				"ugly",  663.  				body_part(FACE)); 664. 		}  665.  		return 1; 666. 	}  667.  	if(u.uswallow) { 668. 		if (!Blind) You("reflect %s %s.", s_suffix(mon_nam(u.ustuck)),  669.  		    mbodypart(u.ustuck, STOMACH)); 670. 		return 1; 671. 	}  672.  	if(Underwater) { 673. 		You(Hallucination ?  674.  		    "give the fish a chance to fix their makeup." :  675.  		    "reflect the murky water."); 676. 		return 1; 677. 	}  678.  	if(u.dz) { 679. 		if (!Blind) 680. 		    You("reflect the %s.",  681.  			(u.dz > 0) ? surface(u.ux,u.uy) : ceiling(u.ux,u.uy)); 682. 		return 1; 683. 	}  684.  	mtmp = bhit(u.dx, u.dy, COLNO, INVIS_BEAM,  685.  		    (int FDECL((*),(MONST_P,OBJ_P)))0,  686.  		    (int FDECL((*),(OBJ_P,OBJ_P)))0,  687.  		    obj); 688. 	if (!mtmp || !haseyes(mtmp->data)) 689. 		return 1; 690.  691.  	vis = canseemon(mtmp); 692. 	mlet = mtmp->data->mlet; 693. 	if (mtmp->msleeping) { 694. 		if (vis) 695. 		    pline ("%s is too tired to look at your mirror.",  696.  			    Monnam(mtmp)); 697. 	} else if (!mtmp->mcansee) { 698. 	    if (vis) 699. 		pline("%s can't see anything right now.", Monnam(mtmp)); 700. 	/* some monsters do special things */ 701. 	} else if (mlet == S_VAMPIRE || mlet == S_GHOST) { 702. 	    if (vis) 703. 		pline ("%s doesn't have a reflection.", Monnam(mtmp)); 704. 	} else if(!mtmp->mcan && !mtmp->minvis &&  705.  					mtmp->data == &mons[PM_MEDUSA]) { 706. 		if (mon_reflects(mtmp, "The gaze is reflected away by %s %s!")) 707. 			return 1; 708. 		if (vis) 709. 			pline("%s is turned to stone!", Monnam(mtmp)); 710. 		stoned = TRUE; 711. 		killed(mtmp); 712. 	} else if(!mtmp->mcan && !mtmp->minvis &&  713.  					mtmp->data == &mons[PM_FLOATING_EYE]) { 714. 		int tmp = d((int)mtmp->m_lev, (int)mtmp->data->mattk[0].damd); 715. 		if (!rn2(4)) tmp = 120; 716. 		if (vis) 717. 			pline("%s is frozen by its reflection.", Monnam(mtmp)); 718. 		else You_hear("%s stop moving.",something); 719. 		mtmp->mcanmove = 0; 720. 		if ( (int) mtmp->mfrozen + tmp > 127) 721. 			mtmp->mfrozen = 127; 722. 		else mtmp->mfrozen += tmp; 723. 	} else if(!mtmp->mcan && !mtmp->minvis &&  724.  					mtmp->data == &mons[PM_UMBER_HULK]) { 725. 		if (vis) 726. 			pline ("%s confuses itself!", Monnam(mtmp)); 727. 		mtmp->mconf = 1; 728. 	} else if(!mtmp->mcan && !mtmp->minvis && (mlet == S_NYMPH 729. 				     || mtmp->data==&mons[PM_SUCCUBUS])) { 730. 		if (vis) { 731. 		    pline ("%s admires herself in your mirror.", Monnam(mtmp)); 732. 		    pline ("She takes it!"); 733. 		} else pline ("It steals your mirror!"); 734. 		setnotworn(obj); /* in case mirror was wielded */ 735. 		freeinv(obj); 736. 		(void) mpickobj(mtmp,obj); 737. 		if (!tele_restrict(mtmp)) rloc(mtmp); 738. 	} else if (!is_unicorn(mtmp->data) && !humanoid(mtmp->data) &&  739.  			(!mtmp->minvis || perceives(mtmp->data)) && rn2(5)) { 740. 		if (vis) 741. 		    pline("%s is frightened by its reflection.", Monnam(mtmp)); 742. 		monflee(mtmp, d(2,4), FALSE, FALSE); 743. 	} else if (!Blind) { 744. 		if (mtmp->minvis && !See_invisible) 745. 		    ;  746.  		else if ((mtmp->minvis && !perceives(mtmp->data))  747.  			 || !haseyes(mtmp->data)) 748. 		    pline("%s doesn't seem to notice its reflection.",  749.  			Monnam(mtmp)); 750. 		else 751. 		    pline("%s ignores %s reflection.",  752.  			  Monnam(mtmp), mhis(mtmp)); 753. 	}  754.  	return 1; 755. }  756.   757.  STATIC_OVL void 758. use_bell(obj) 759. register struct obj *obj; 760. {  761.  	struct monst *mtmp; 762. 	boolean wakem = FALSE, learno = FALSE, 763. 		ordinary = (obj->otyp != BELL_OF_OPENING || !obj->spe), 764. 		invoking = (obj->otyp == BELL_OF_OPENING &&  765.  			 invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)); 766.  767.  	You("ring %s.", the(xname(obj))); 768.  769.  	if (Underwater || (u.uswallow && ordinary)) { 770. #ifdef	AMIGA 771. 	    amii_speaker( obj, "AhDhGqEqDhEhAqDqFhGw", AMII_MUFFLED_VOLUME ); 772. #endif 773. 	    pline("But the sound is muffled."); 774.  775.  	} else if (invoking && ordinary) { 776. 	    /* needs to be recharged... */ 777.  	    pline("But it makes no sound."); 778. 	    learno = TRUE;	/* help player figure out why */ 779.  780.  	} else if (ordinary) { 781. #ifdef	AMIGA 782. 	    amii_speaker( obj, "ahdhgqeqdhehaqdqfhgw", AMII_MUFFLED_VOLUME ); 783. #endif 784. 	    if (obj->cursed && !rn2(4) &&  785.  		    /* note: once any of them are gone, we stop all of them */  786.  		    !(mvitals[PM_WOOD_NYMPH].mvflags & G_GONE) &&  787.  		    !(mvitals[PM_WATER_NYMPH].mvflags & G_GONE) &&  788.  		    !(mvitals[PM_MOUNTAIN_NYMPH].mvflags & G_GONE) &&  789.  		    (mtmp = makemon(mkclass(S_NYMPH, 0),  790.  					u.ux, u.uy, NO_MINVENT)) != 0) { 791. 		You("summon %s!", a_monnam(mtmp)); 792. 		if (!obj_resists(obj, 93, 100)) { 793. 		    pline("%s shattered!", Tobjnam(obj, "have")); 794. 		    useup(obj); 795. 		} else switch (rn2(3)) { 796. 			default: 797. 				break; 798. 			case 1: 799. 				mon_adjust_speed(mtmp, 2, (struct obj *)0); 800. 				break; 801. 			case 2: /* no explanation; it just happens... */ 802.  				nomovemsg = ""; 803. 				nomul(-rnd(2)); 804. 				break; 805. 		}  806.  	    }  807.  	    wakem = TRUE; 808.  809.  	} else { 810. 	    /* charged Bell of Opening */ 811. 	    check_unpaid(obj); 812. 	    obj->spe--; 813.  814.  	    if (u.uswallow) { 815. 		if (!obj->cursed) 816. 		    (void) openit; 817. 		else 818. 		    pline(nothing_happens); 819.  820.  	    } else if (obj->cursed) { 821. 		coord mm; 822.  823.  		mm.x = u.ux; 824. 		mm.y = u.uy; 825. 		mkundead(&mm, FALSE, NO_MINVENT); 826. 		wakem = TRUE; 827.  828.  	    } else  if (invoking) { 829. 		pline("%s an unsettling shrill sound...",  830.  		      Tobjnam(obj, "issue")); 831. #ifdef	AMIGA 832. 		amii_speaker( obj, "aefeaefeaefeaefeaefe", AMII_LOUDER_VOLUME ); 833. #endif 834. 		obj->age = moves; 835. 		learno = TRUE; 836. 		wakem = TRUE; 837.  838.  	    } else if (obj->blessed) { 839. 		int res = 0; 840.  841.  #ifdef	AMIGA 842. 		amii_speaker( obj, "ahahahDhEhCw", AMII_SOFT_VOLUME ); 843. #endif 844. 		if (uchain) { 845. 		    unpunish; 846. 		    res = 1; 847. 		}  848.  		res += openit; 849. 		switch (res) { 850. 		  case 0:  pline(nothing_happens); break; 851. 		  case 1:  pline("%s opens...", Something); 852. 			   learno = TRUE; break; 853. 		  default: pline("Things open around you..."); 854. 			   learno = TRUE; break; 855. 		}  856.   857.  	    } else {  /* uncursed */ 858. #ifdef	AMIGA 859. 		amii_speaker( obj, "AeFeaeFeAefegw", AMII_OKAY_VOLUME ); 860. #endif 861. 		if (findit != 0) learno = TRUE; 862. 		else pline(nothing_happens); 863. 	    }  864.   865.  	}	/* charged BofO */ 866.  867.  	if (learno) { 868. 	    makeknown(BELL_OF_OPENING); 869. 	    obj->known = 1; 870. 	}  871.  	if (wakem) wake_nearby; 872. }  873.   874.  STATIC_OVL void 875. use_candelabrum(obj) 876. register struct obj *obj; 877. {  878.  	char *s = obj->spe != 1 ? "candles" : "candle"; 879.  880.  	if(Underwater) { 881. 		You("cannot make fire under water."); 882. 		return; 883. 	}  884.  	if(obj->lamplit) { 885. 		You("snuff the %s.", s); 886. 		end_burn(obj, TRUE); 887. 		return; 888. 	}  889.  	if(obj->spe <= 0) { 890. 		pline("This %s has no %s.", xname(obj), s); 891. 		return; 892. 	}  893.  	if(u.uswallow || obj->cursed) { 894. 		if (!Blind) 895. 		    pline_The("%s %s for a moment, then %s.",  896.  			      s, vtense(s, "flicker"), vtense(s, "die")); 897. 		return; 898. 	}  899.  	if(obj->spe < 7) { 900. 		There("%s only %d %s in %s.",  901.  		      vtense(s, "are"), obj->spe, s, the(xname(obj))); 902. 		if (!Blind) 903. 		    pline("%s lit.  %s dimly.",  904.  			  obj->spe == 1 ? "It is" : "They are",  905.  			  Tobjnam(obj, "shine")); 906. 	} else { 907. 		pline("%s's %s burn%s", The(xname(obj)), s,  908.  			(Blind ? "." : " brightly!")); 909. 	}  910.  	if (!invocation_pos(u.ux, u.uy)) { 911. 		pline_The("%s %s being rapidly consumed!", s, vtense(s, "are")); 912. 		obj->age /= 2; 913. 	} else { 914. 		if(obj->spe == 7) { 915. 		    if (Blind) 916. 		      pline("%s a strange warmth!", Tobjnam(obj, "radiate")); 917. 		    else 918. 		      pline("%s with a strange light!", Tobjnam(obj, "glow")); 919. 		}  920.  		obj->known = 1; 921. 	}  922.  	begin_burn(obj, FALSE); 923. }  924.   925.  STATIC_OVL void 926. use_candle(obj) 927. register struct obj *obj; 928. {  929.  	register struct obj *otmp; 930. 	char *s = obj->quan != 1 ? "candles" : "candle"; 931. 	char qbuf[QBUFSZ]; 932.  933.  	if(u.uswallow) { 934. 		You(no_elbow_room); 935. 		return; 936. 	}  937.  	if(Underwater) { 938. 		pline("Sorry, fire and water don't mix."); 939. 		return; 940. 	}  941.   942.  	otmp = carrying(CANDELABRUM_OF_INVOCATION); 943. 	if(!otmp || otmp->spe == 7) { 944. 		use_lamp(obj); 945. 		return; 946. 	}  947.   948.  	Sprintf(qbuf, "Attach %s", the(xname(obj))); 949. 	Sprintf(eos(qbuf), " to %s?", the(xname(otmp))); 950. 	if(yn(qbuf) == 'n') { 951. 		if (!obj->lamplit) 952. 		    You("try to light %s...", the(xname(obj))); 953. 		use_lamp(obj); 954. 		return; 955. 	} else { 956. 		if ((long)otmp->spe + obj->quan > 7L) 957. 		    obj = splitobj(obj, 7L - (long)otmp->spe); 958. 		You("attach %ld%s %s to %s.",  959.  		    obj->quan, !otmp->spe ? "" : " more",  960.  		    s, the(xname(otmp))); 961. 		if (!otmp->spe || otmp->age > obj->age) 962. 		    otmp->age = obj->age; 963. 		otmp->spe += (int)obj->quan; 964. 		if (otmp->lamplit && !obj->lamplit) 965. 		    pline_The("new %s magically %s!", s, vtense(s, "ignite")); 966. 		else if (!otmp->lamplit && obj->lamplit) 967. 		    pline("%s out.", (obj->quan > 1L) ? "They go" : "It goes"); 968. 		if (obj->unpaid) 969. 		    verbalize("You %s %s, you bought %s!",  970.  			      otmp->lamplit ? "burn" : "use",  971.  			      (obj->quan > 1L) ? "them" : "it",  972.  			      (obj->quan > 1L) ? "them" : "it"); 973. 		if (obj->quan < 7L && otmp->spe == 7) 974. 		    pline("%s now has seven%s %s attached.",  975.  			  The(xname(otmp)), otmp->lamplit ? " lit" : "", s); 976. 		/* candelabrum's light range might increase */ 977. 		if (otmp->lamplit) obj_merge_light_sources(otmp, otmp); 978. 		/* candles are no longer a separate light source */ 979. 		if (obj->lamplit) end_burn(obj, TRUE); 980. 		/* candles are now gone */ 981. 		useupall(obj); 982. 	}  983.  }  984.   985.  boolean 986. snuff_candle(otmp)  /* call in drop, throw, and put in box, etc. */ 987. register struct obj *otmp; 988. {  989.  	register boolean candle = Is_candle(otmp); 990.  991.  	if ((candle || otmp->otyp == CANDELABRUM_OF_INVOCATION) &&  992.  		otmp->lamplit) { 993. 	    char buf[BUFSZ]; 994. 	    xchar x, y;  995. register boolean many = candle ? otmp->quan > 1L : otmp->spe > 1; 996.  997.  	    (void) get_obj_location(otmp, &x, &y, 0); 998. 	    if (otmp->where == OBJ_MINVENT ? cansee(x,y) : !Blind) 999. 		pline("%s %scandle%s flame%s extinguished.",  1000. 		      Shk_Your(buf, otmp),  1001. 		      (candle ? "" : "candelabrum's "), 1002. 		      (many ? "s'" : "'s"), (many ? "s are" : " is")); 1003. 	  end_burn(otmp, TRUE); 1004. 	  return(TRUE); 1005. 	} 1006. 	return(FALSE); 1007. } 1008.  1009. /* called when lit lamp is hit by water or put into a container or  1010. you've been swallowed by a monster; obj might be in transit while 1011.   being thrown or dropped so don't assume that its location is valid */ 1012. boolean 1013. snuff_lit(obj) 1014. struct obj *obj; 1015. { 1016. 	xchar x, y;  1017. 1018. 	if (obj->lamplit) { 1019. 	   if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||  1020. 		    obj->otyp == BRASS_LANTERN || obj->otyp == POT_OIL) { 1021. 		(void) get_obj_location(obj, &x, &y, 0); 1022. 		if (obj->where == OBJ_MINVENT ? cansee(x,y) : !Blind) 1023. 		   pline("%s %s out!", Yname2(obj), otense(obj, "go")); 1024. 		end_burn(obj, TRUE); 1025. 		return TRUE; 1026. 	   }  1027. 	    if (snuff_candle(obj)) return TRUE; 1028. 	} 1029. 	return FALSE; 1030. } 1031.  1032. /* Called when potentially lightable object is affected by fire_damage. 1033.   Return TRUE if object was lit and FALSE otherwise --ALI */ 1034. boolean 1035. catch_lit(obj) 1036. struct obj *obj; 1037. { 1038. 	xchar x, y;  1039. 1040. 	if (!obj->lamplit && (obj->otyp == CANDELABRUM_OF_INVOCATION || 1041. 		obj->otyp == WAX_CANDLE || obj->otyp == TALLOW_CANDLE || 1042. 		obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP || 1043. 		obj->otyp == BRASS_LANTERN || obj->otyp == POT_OIL)) { 1044. 	   if ((obj->otyp == MAGIC_LAMP || 1045. 		 obj->otyp == CANDELABRUM_OF_INVOCATION) && 1046. 		obj->spe == 0) 1047. 		return FALSE; 1048. 	   else if (obj->otyp != MAGIC_LAMP && obj->age == 0) 1049. 		return FALSE; 1050. 	   if (!get_obj_location(obj, &x, &y, 0)) 1051. 		return FALSE; 1052. 	   if (obj->otyp == CANDELABRUM_OF_INVOCATION && obj->cursed) 1053. 		return FALSE; 1054. 	   if ((obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP || 1055. 		 obj->otyp == BRASS_LANTERN) && obj->cursed && !rn2(2)) 1056. 		return FALSE; 1057. 	   if (obj->where == OBJ_MINVENT ? cansee(x,y) : !Blind) 1058. 		pline("%s %s light!", Yname2(obj), otense(obj, "catch")); 1059. 	   begin_burn(obj, TRUE); 1060. 	   return TRUE; 1061. 	} 1062. 	return FALSE; 1063. } 1064.  1065. STATIC_OVL void 1066. use_lamp(obj) 1067. struct obj *obj; 1068. { 1069. 	char buf[BUFSZ]; 1070. 1071. 	if(Underwater) { 1072. 		pline("This is not a diving lamp."); 1073. 		return; 1074. 	} 1075. 	if(obj->lamplit) { 1076. 		if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP || 1077. 				obj->otyp == BRASS_LANTERN) 1078. 		   pline("%s lamp is now off.", Shk_Your(buf, obj)); 1079. 		else 1080. 		   You("snuff out %s.", yname(obj)); 1081. 		end_burn(obj, TRUE); 1082. 		return; 1083. 	} 1084. 	/* magic lamps with an spe == 0 (wished for) cannot be lit */ 1085. 	if ((!Is_candle(obj) && obj->age == 0) 1086. 			|| (obj->otyp == MAGIC_LAMP && obj->spe == 0)) { 1087. 		if (obj->otyp == BRASS_LANTERN) 1088. 			Your("lamp has run out of power."); 1089. 		else pline("This %s has no oil.", xname(obj)); 1090. 		return; 1091. 	} 1092. 	if (obj->cursed && !rn2(2)) { 1093. 		pline("%s for a moment, then %s.", 1094. 		      Tobjnam(obj, "flicker"), otense(obj, "die")); 1095. 	} else { 1096. 		if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP || 1097. 				obj->otyp == BRASS_LANTERN) { 1098. 		   check_unpaid(obj); 1099. 		   pline("%s lamp is now on.", Shk_Your(buf, obj)); 1100. 		} else {	/* candle(s) */ 1101. 		   pline("%s flame%s %s%s",  1102. 			s_suffix(Yname2(obj)),  1103. 			plur(obj->quan), otense(obj, "burn"),  1104. 			Blind ? "." : " brightly!"); 1105. 		   if (obj->unpaid && costly_spot(u.ux, u.uy) &&  1106. 			  obj->age == 20L * (long)objects[obj->otyp].oc_cost) { 1107. 			const char *ithem = obj->quan > 1L ? "them" : "it"; 1108. 			verbalize("You burn %s, you bought %s!", ithem, ithem); 1109. 			bill_dummy_object(obj); 1110. 		   }  1111. 		}  1112. 		begin_burn(obj, FALSE); 1113. 	} 1114. }  1115.  1116. STATIC_OVL void 1117. light_cocktail(obj) 1118. 	struct obj *obj;	/* obj is a potion of oil */ 1119. { 1120. 	char buf[BUFSZ]; 1121. 1122. 	if (u.uswallow) { 1123. 	   You(no_elbow_room); 1124. 	   return; 1125. 	} 1126.  1127. 	if (obj->lamplit) { 1128. 	   You("snuff the lit potion."); 1129. 	   end_burn(obj, TRUE); 1130. 	   /*  1131. 	     * Free & add to re-merge potion. This will average the 1132. 	    * age of the potions. Not exactly the best solution, 1133. 	    * but its easy. 1134. 	    */  1135. 	    freeinv(obj); 1136. 	   (void) addinv(obj); 1137. 	   return; 1138. 	} else if (Underwater) { 1139. 	   There("is not enough oxygen to sustain a fire."); 1140. 	   return; 1141. 	} 1142.  1143. 	You("light %s potion.%s", shk_your(buf, obj),  1144. 	    Blind ? "" : "  It gives off a dim light."); 1145. 	if (obj->unpaid && costly_spot(u.ux, u.uy)) { 1146. 	   /* Normally, we shouldn't both partially and fully charge 1147. 	    * for an item, but (Yendorian Fuel) Taxes are inevitable...  1148. */ 1149. 	    check_unpaid(obj); 1150. 	   verbalize("That's in addition to the cost of the potion, of course."); 1151. 	   bill_dummy_object(obj); 1152. 	} 1153. 	makeknown(obj->otyp); 1154. 1155. 	if (obj->quan > 1L) { 1156. 	   obj = splitobj(obj, 1L); 1157. 	   begin_burn(obj, FALSE);	/* burn before free to get position */ 1158. 	   obj_extract_self(obj);	/* free from inv */ 1159. 1160. 	    /* shouldn't merge */ 1161. 	   obj = hold_another_object(obj, "You drop %s!",  1162. 				      doname(obj), (const char *)0); 1163. 	} else 1164. 	   begin_burn(obj, FALSE); 1165. } 1166.  1167. static NEARDATA const char cuddly[] = { TOOL_CLASS, GEM_CLASS, 0 }; 1168. 1169. int 1170. dorub 1171. { 1172. 	struct obj *obj = getobj(cuddly, "rub"); 1173. 1174. 	if (obj && obj->oclass == GEM_CLASS) { 1175. 	   if (is_graystone(obj)) { 1176. 		use_stone(obj); 1177. 		return 1; 1178. 	   } else { 1179. 		pline("Sorry, I don't know how to use that."); 1180. 		return 0; 1181. 	   }  1182. 	}  1183.  1184. 	if(!obj || (obj != uwep && !wield_tool(obj))) return 0; 1185. 1186. 	/* now uwep is obj */ 1187. 	if (uwep->otyp == MAGIC_LAMP) { 1188. 	   if (uwep->spe > 0 && !rn2(3)) { 1189. 		check_unpaid_usage(uwep, TRUE);		/* unusual item use */ 1190. 		djinni_from_bottle(uwep); 1191. 		makeknown(MAGIC_LAMP); 1192. 		uwep->otyp = OIL_LAMP; 1193. 		uwep->spe = 0; /* for safety */ 1194. 		uwep->age = rn1(500,1000); 1195. 		if (uwep->lamplit) begin_burn(uwep, TRUE); 1196. 		update_inventory; 1197. 	   } else if (rn2(2) && !Blind) 1198. 		You("see a puff of smoke."); 1199. 	   else pline(nothing_happens); 1200. 	} else if (obj->otyp == BRASS_LANTERN) { 1201. 	   /* message from Adventure */ 1202. 	   pline("Rubbing the electric lamp is not particularly rewarding."); 1203. 	   pline("Anyway, nothing exciting happens."); 1204. 	} else pline(nothing_happens); 1205. 	return 1; 1206. } 1207.  1208. int 1209. dojump 1210. { 1211. 	/* Physical jump */ 1212. 	return jump(0); 1213. } 1214.  1215. int 1216. jump(magic) 1217. int magic; /* 0=Physical, otherwise skill level */ 1218. { 1219. 	coord cc; 1220. 1221. 	if (!magic && (nolimbs(youmonst.data) || slithy(youmonst.data))) { 1222. 		/* normally (nolimbs || slithy) implies !Jumping, 1223. 		  but that isn't necessarily the case for knights */ 1224. 		You_cant("jump; you have no legs!"); 1225. 		return 0; 1226. 	} else if (!magic && !Jumping) { 1227. 		You_cant("jump very far."); 1228. 		return 0; 1229. 	} else if (u.uswallow) { 1230. 		if (magic) { 1231. 			You("bounce around a little."); 1232. 			return 1; 1233. 		} 1234. 		pline("You've got to be kidding!"); 1235. 		return 0; 1236. 	} else if (u.uinwater) { 1237. 		if (magic) { 1238. 			You("swish around a little."); 1239. 			return 1; 1240. 		} 1241. 		pline("This calls for swimming, not jumping!"); 1242. 		return 0; 1243. 	} else if (u.ustuck) { 1244. 		if (u.ustuck->mtame && !Conflict && !u.ustuck->mconf) { 1245. 		   You("pull free from %s.", mon_nam(u.ustuck)); 1246. 		   u.ustuck = 0; 1247. 		   return 1; 1248. 		} 1249. 		if (magic) { 1250. 			You("writhe a little in the grasp of %s!", mon_nam(u.ustuck)); 1251. 			return 1; 1252. 		} 1253. 		You("cannot escape from %s!", mon_nam(u.ustuck)); 1254. 		return 0; 1255. 	} else if (Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) { 1256. 		if (magic) { 1257. 			You("flail around a little."); 1258. 			return 1; 1259. 		} 1260. 		You("don't have enough traction to jump."); 1261. 		return 0; 1262. 	} else if (!magic && near_capacity > UNENCUMBERED) { 1263. 		You("are carrying too much to jump!"); 1264. 		return 0; 1265. 	} else if (!magic && (u.uhunger <= 100 || ACURR(A_STR) < 6)) { 1266. 		You("lack the strength to jump!"); 1267. 		return 0; 1268. 	} else if (Wounded_legs) { 1269. 		long wl = (Wounded_legs & BOTH_SIDES); 1270. 		const char *bp = body_part(LEG); 1271. 1272. 		if (wl == BOTH_SIDES) bp = makeplural(bp); 1273. #ifdef STEED 1274. 		if (u.usteed) 1275. 		   pline("%s is in no shape for jumping.", Monnam(u.usteed)); 1276. 		else 1277. #endif 1278. 		Your("%s%s %s in no shape for jumping.", 1279. 		     (wl == LEFT_SIDE) ? "left " :  1280. 			(wl == RIGHT_SIDE) ? "right " : "",  1281. 		     bp, (wl == BOTH_SIDES) ? "are" : "is"); 1282. 		return 0; 1283. 	} 1284. #ifdef STEED 1285. 	else if (u.usteed && u.utrap) { 1286. 		pline("%s is stuck in a trap.", Monnam(u.usteed)); 1287. 		return (0); 1288. 	} 1289. #endif 1290. 1291. 	pline("Where do you want to jump?"); 1292. 	cc.x = u.ux; 1293. 	cc.y = u.uy; 1294. 	if (getpos(&cc, TRUE, "the desired position") < 0) 1295. 		return 0;	/* user pressed ESC */ 1296. 	if (!magic && !(HJumping & ~INTRINSIC) && !EJumping && 1297. 			distu(cc.x, cc.y) != 5) { 1298. 		/* The Knight jumping restriction still applies when riding a 1299. * horse. After all, what shape is the knight piece in chess? 1300. 		 */ 1301. 		pline("Illegal move!"); 1302. 		return 0; 1303. 	} else if (distu(cc.x, cc.y) > (magic ? 6+magic*3 : 9)) { 1304. 		pline("Too far!"); 1305. 		return 0; 1306. 	} else if (!cansee(cc.x, cc.y)) { 1307. 		You("cannot see where to land!"); 1308. 		return 0; 1309. 	} else if (!isok(cc.x, cc.y)) { 1310. 		You("cannot jump there!"); 1311. 		return 0; 1312. 	} else { 1313. 	   coord uc; 1314. 	   int range, temp; 1315. 1316. 	    if(u.utrap) 1317. 		switch(u.utraptype) { 1318. 		case TT_BEARTRAP: { 1319. 		   register long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE; 1320. 		   You("rip yourself free of the bear trap!  Ouch!"); 1321. 		   losehp(rnd(10), "jumping out of a bear trap", KILLED_BY); 1322. 		   set_wounded_legs(side, rn1(1000,500)); 1323. 		   break; 1324. 		 }  1325. 		case TT_PIT: 1326. 		   You("leap from the pit!"); 1327. 		   break; 1328. 		case TT_WEB: 1329. 		   You("tear the web apart as you pull yourself free!"); 1330. 		   deltrap(t_at(u.ux,u.uy)); 1331. 		   break; 1332. 		case TT_LAVA: 1333. 		   You("pull yourself above the lava!"); 1334. 		   u.utrap = 0; 1335. 		   return 1; 1336. 		case TT_INFLOOR: 1337. 		   You("strain your %s, but you're still stuck in the floor.",  1338. 			makeplural(body_part(LEG))); 1339. 		   set_wounded_legs(LEFT_SIDE, rn1(10, 11)); 1340. 		   set_wounded_legs(RIGHT_SIDE, rn1(10, 11)); 1341. 		   return 1; 1342. 		} 1343.  1344. 	    /*  1345. 	     * Check the path from uc to cc, calling hurtle_step at each 1346. 	    * location. The final position actually reached will be 1347. * in cc. 1348. 	    */  1349. 	    uc.x = u.ux; 1350. 	   uc.y = u.uy; 1351. 	   /* calculate max(abs(dx), abs(dy)) as the range */ 1352. 	   range = cc.x - uc.x;  1353. if (range < 0) range = -range; 1354. 	   temp = cc.y - uc.y;  1355. if (temp < 0) temp = -temp; 1356. 	   if (range < temp) 1357. 		range = temp; 1358. 	   (void) walk_path(&uc, &cc, hurtle_step, (genericptr_t)&range); 1359. 1360. 	    /* A little Sokoban guilt... */ 1361. 	    if (In_sokoban(&u.uz)) 1362. 		change_luck(-1); 1363. 1364. 	    teleds(cc.x, cc.y); 1365. 	   nomul(-1); 1366. 	   nomovemsg = ""; 1367. 	   morehungry(rnd(25)); 1368. 	   return 1; 1369. 	} 1370. }  1371.  1372. boolean 1373. tinnable(corpse) 1374. struct obj *corpse; 1375. { 1376. 	if (corpse->oeaten) return 0; 1377. 	if (!mons[corpse->corpsenm].cnutrit) return 0; 1378. 	return 1; 1379. } 1380.  1381. STATIC_OVL void 1382. use_tinning_kit(obj) 1383. register struct obj *obj; 1384. { 1385. 	register struct obj *corpse, *can; 1386. 1387. 	/* This takes only 1 move. If this is to be changed to take many 1388. 	 * moves, we've got to deal with decaying corpses... 1389. */ 1390. 	if (obj->spe <= 0) { 1391. 		You("seem to be out of tins."); 1392. 		return; 1393. 	} 1394. 	if (!(corpse = floorfood("tin", 2))) return; 1395. 	if (corpse->oeaten) { 1396. 		You("cannot tin %s which is partly eaten.",something); 1397. 		return; 1398. 	} 1399. 	if (touch_petrifies(&mons[corpse->corpsenm])  1400. 		&& !Stone_resistance && !uarmg) { 1401. 	   char kbuf[BUFSZ]; 1402. 1403. 	    if (poly_when_stoned(youmonst.data)) 1404. 		You("tin %s without wearing gloves.", 1405. 			an(mons[corpse->corpsenm].mname)); 1406. 	   else { 1407. 		pline("Tinning %s without wearing gloves is a fatal mistake...", 1408. 			an(mons[corpse->corpsenm].mname)); 1409. 		Sprintf(kbuf, "trying to tin %s without gloves", 1410. 			an(mons[corpse->corpsenm].mname)); 1411. 	   }  1412. 	    instapetrify(kbuf); 1413. 	} 1414. 	if (is_rider(&mons[corpse->corpsenm])) { 1415. 		(void) revive_corpse(corpse); 1416. 		verbalize("Yes... But War does not preserve its enemies..."); 1417. 		return; 1418. 	} 1419. 	if (mons[corpse->corpsenm].cnutrit == 0) { 1420. 		pline("That's too insubstantial to tin."); 1421. 		return; 1422. 	} 1423. 	obj->spe--; 1424. 	if ((can = mksobj(TIN, FALSE, FALSE)) != 0) { 1425. 	   static const char you_buy_it[] = "You tin it, you bought it!"; 1426. 1427. 	    can->corpsenm = corpse->corpsenm; 1428. 	   can->cursed = obj->cursed; 1429. 	   can->blessed = obj->blessed; 1430. 	   can->owt = weight(can); 1431. 	   can->known = 1; 1432. 	   can->spe = -1;  /* Mark tinned tins. No spinach allowed... */ 1433. 	    if (carried(corpse)) { 1434. 		if (corpse->unpaid) 1435. 		   verbalize(you_buy_it); 1436. 		useup(corpse); 1437. 	   } else { 1438. 		if (costly_spot(corpse->ox, corpse->oy) && !corpse->no_charge) 1439. 		   verbalize(you_buy_it); 1440. 		useupf(corpse, 1L); 1441. 	   }  1442. 	    can = hold_another_object(can, "You make, but cannot pick up, %s.",  1443. 				      doname(can), (const char *)0); 1444. 	} else impossible("Tinning failed."); 1445. } 1446.  1447. void 1448. use_unicorn_horn(obj) 1449. struct obj *obj; 1450. { 1451. #define PROP_COUNT 6		/* number of properties we're dealing with */ 1452. #define ATTR_COUNT (A_MAX*3)	/* number of attribute points we might fix */ 1453. 	int idx, val, val_limit, 1454. 	   trouble_count, unfixable_trbl, did_prop, did_attr; 1455. 	int trouble_list[PROP_COUNT + ATTR_COUNT]; 1456. 1457. 	if (obj && obj->cursed) { 1458. 	   long lcount = (long) rnd(100); 1459. 1460. 	    switch (rn2(6)) { 1461. 	   case 0: make_sick(Sick ? Sick/3L + 1L : (long)rn1(ACURR(A_CON),20),  1462. 			xname(obj), TRUE, SICK_NONVOMITABLE); 1463. 		   break; 1464. 	   case 1: make_blinded(Blinded + lcount, TRUE); 1465. 		   break; 1466. 	   case 2: if (!Confusion) 1467. 			You("suddenly feel %s.", 1468. 			    Hallucination ? "trippy" : "confused"); 1469. 		   make_confused(HConfusion + lcount, TRUE); 1470. 		   break; 1471. 	   case 3: make_stunned(HStun + lcount, TRUE); 1472. 		   break; 1473. 	   case 4: (void) adjattrib(rn2(A_MAX), -1, FALSE); 1474. 		   break; 1475. 	   case 5: make_hallucinated(HHallucination + lcount, TRUE, 0L); 1476. 		   break; 1477. 	   }  1478. 	    return; 1479. 	} 1480.  1481. /*  1482.  * Entries in the trouble list use a very simple encoding scheme. 1483. */  1484. #define prop2trbl(X)	((X) + A_MAX) 1485. #define attr2trbl(Y)	(Y) 1486. #define prop_trouble(X) trouble_list[trouble_count++] = prop2trbl(X) 1487. #define attr_trouble(Y) trouble_list[trouble_count++] = attr2trbl(Y) 1488. 1489. 	trouble_count = unfixable_trbl = did_prop = did_attr = 0; 1490. 1491. 	/* collect property troubles */ 1492. 	if (Sick) prop_trouble(SICK); 1493. 	if (Blinded > (long)u.ucreamed) prop_trouble(BLINDED); 1494. 	if (HHallucination) prop_trouble(HALLUC); 1495. 	if (Vomiting) prop_trouble(VOMITING); 1496. 	if (HConfusion) prop_trouble(CONFUSION); 1497. 	if (HStun) prop_trouble(STUNNED); 1498. 1499. 	unfixable_trbl = unfixable_trouble_count(TRUE); 1500. 1501. 	/* collect attribute troubles */ 1502. 	for (idx = 0; idx < A_MAX; idx++) { 1503. 	   val_limit = AMAX(idx); 1504. 	   /* don't recover strength lost from hunger */ 1505. 	   if (idx == A_STR && u.uhs >= WEAK) val_limit--; 1506. 	   /* don't recover more than 3 points worth of any attribute */ 1507. 	   if (val_limit > ABASE(idx) + 3) val_limit = ABASE(idx) + 3; 1508. 1509. 	    for (val = ABASE(idx); val < val_limit; val++) 1510. 		attr_trouble(idx); 1511. 	   /* keep track of unfixed trouble, for message adjustment below */ 1512. 	   unfixable_trbl += (AMAX(idx) - val_limit); 1513. 	} 1514.  1515. 	if (trouble_count == 0) { 1516. 	   pline(nothing_happens); 1517. 	   return; 1518. 	} else if (trouble_count > 1) {		/* shuffle */ 1519. 	   int i, j, k;  1520. 1521. 	   for (i = trouble_count - 1; i > 0; i--) 1522. 		if ((j = rn2(i + 1)) != i) { 1523. 		   k = trouble_list[j]; 1524. 		   trouble_list[j] = trouble_list[i]; 1525. 		   trouble_list[i] = k;  1526. } 1527. 	}  1528.  1529. 	/*  1530. 	 *		Chances for number of troubles to be fixed 1531. 	 *		 0	1     2      3      4	    5	   6	  7  1532. 	 *   blessed:  22.7%  22.7%  19.5%  15.4%  10.7%   5.7%   2.6%	 0.8% 1533. 	 * uncursed:  35.4%  35.4%  22.9%   6.3%    0	    0	   0	  0 1534. 	 */ 1535. 	val_limit = rn2( d(2, (obj && obj->blessed) ? 4 : 2) ); 1536. 	if (val_limit > trouble_count) val_limit = trouble_count; 1537. 1538. 	/* fix [some of] the troubles */ 1539. 	for (val = 0; val < val_limit; val++) { 1540. 	   idx = trouble_list[val]; 1541. 1542. 	    switch (idx) { 1543. 	   case prop2trbl(SICK): 1544. 		make_sick(0L, (char *) 0, TRUE, SICK_ALL); 1545. 		did_prop++; 1546. 		break; 1547. 	   case prop2trbl(BLINDED): 1548. 		make_blinded((long)u.ucreamed, TRUE); 1549. 		did_prop++; 1550. 		break; 1551. 	   case prop2trbl(HALLUC): 1552. 		make_hallucinated(0L, TRUE, 0L); 1553. 		did_prop++; 1554. 		break; 1555. 	   case prop2trbl(VOMITING): 1556. 		make_vomiting(0L, TRUE); 1557. 		did_prop++; 1558. 		break; 1559. 	   case prop2trbl(CONFUSION): 1560. 		make_confused(0L, TRUE); 1561. 		did_prop++; 1562. 		break; 1563. 	   case prop2trbl(STUNNED): 1564. 		make_stunned(0L, TRUE); 1565. 		did_prop++; 1566. 		break; 1567. 	   default: 1568. 		if (idx >= 0 && idx < A_MAX) { 1569. 		   ABASE(idx) += 1; 1570. 		   did_attr++; 1571. 		} else 1572. 		   panic("use_unicorn_horn: bad trouble? (%d)", idx); 1573. 		break; 1574. 	   }  1575. 	}  1576.  1577. 	if (did_attr) 1578. 	   pline("This makes you feel %s!",  1579. 		  (did_prop + did_attr) == (trouble_count + unfixable_trbl) ?  1580. 		  "great" : "better"); 1581. 	else if (!did_prop) 1582. 	   pline("Nothing seems to happen."); 1583. 1584. 	flags.botl = (did_attr || did_prop); 1585. #undef PROP_COUNT 1586. #undef ATTR_COUNT 1587. #undef prop2trbl 1588. #undef attr2trbl 1589. #undef prop_trouble 1590. #undef attr_trouble 1591. } 1592.  1593. /*  1594.  * Timer callback routine: turn figurine into monster 1595. */  1596. void 1597. fig_transform(arg, timeout) 1598. genericptr_t arg; 1599. long timeout; 1600. { 1601. 	struct obj *figurine = (struct obj *)arg; 1602. 	struct monst *mtmp; 1603. 	coord cc; 1604. 	boolean cansee_spot, silent, okay_spot; 1605. 	boolean redraw = FALSE; 1606. 	char monnambuf[BUFSZ], carriedby[BUFSZ]; 1607. 1608. 	if (!figurine) { 1609. #ifdef DEBUG 1610. 	   pline("null figurine in fig_transform"); 1611. #endif 1612. 	   return; 1613. 	} 1614. 	silent = (timeout != monstermoves); /* happened while away */ 1615. 	okay_spot = get_obj_location(figurine, &cc.x, &cc.y, 0); 1616. 	if (figurine->where == OBJ_INVENT || 1617. 	    figurine->where == OBJ_MINVENT) 1618. 		okay_spot = enexto(&cc, cc.x, cc.y, 1619. 				   &mons[figurine->corpsenm]); 1620. 	if (!okay_spot || 1621. 	    !figurine_location_checks(figurine,&cc, TRUE)) { 1622. 		/* reset the timer to try again later */ 1623. 		(void) start_timer((long)rnd(5000), TIMER_OBJECT, 1624. 				FIG_TRANSFORM, (genericptr_t)figurine); 1625. 		return; 1626. 	} 1627.  1628. 	cansee_spot = cansee(cc.x, cc.y); 1629. 	mtmp = make_familiar(figurine, cc.x, cc.y, TRUE); 1630. 	if (mtmp) { 1631. 	   Sprintf(monnambuf, "%s",a_monnam(mtmp)); 1632. 	   switch (figurine->where) { 1633. 		case OBJ_INVENT: 1634. 		   if (Blind) 1635. 			You_feel("%s %s from your pack!", something, 1636. 			    locomotion(mtmp->data,"drop")); 1637. 		   else 1638. 			You("see %s %s out of your pack!", 1639. 			    monnambuf,  1640. 			    locomotion(mtmp->data,"drop")); 1641. 		   break; 1642. 1643. 		case OBJ_FLOOR: 1644. 		   if (cansee_spot && !silent) { 1645. 			You("suddenly see a figurine transform into %s!", 1646. 				monnambuf); 1647. 			redraw = TRUE;	/* update figurine's map location */ 1648. 		   }  1649. 		    break; 1650. 1651. 		case OBJ_MINVENT: 1652. 		   if (cansee_spot && !silent) { 1653. 			struct monst *mon; 1654. 			mon = figurine->ocarry; 1655. 			/* figurine carring monster might be invisible */ 1656. 			if (canseemon(figurine->ocarry)) { 1657. 			   Sprintf(carriedby, "%s pack",  1658. 				     s_suffix(a_monnam(mon))); 1659. 			} 1660. 			else if (is_pool(mon->mx, mon->my)) 1661. 			   Strcpy(carriedby, "empty water"); 1662. 			else 1663. 			   Strcpy(carriedby, "thin air"); 1664. 			You("see %s %s out of %s!", monnambuf, 1665. 			    locomotion(mtmp->data, "drop"), carriedby); 1666. 		   }  1667. 		    break; 1668. #if 0 1669. 		case OBJ_MIGRATING: 1670. 		   break; 1671. #endif 1672. 1673. 		default: 1674. 		   impossible("figurine came to life where? (%d)",  1675. 				(int)figurine->where); 1676. 		break; 1677. 	   }  1678. 	}  1679. 	/* free figurine now */ 1680. 	obj_extract_self(figurine); 1681. 	obfree(figurine, (struct obj *)0); 1682. 	if (redraw) newsym(cc.x, cc.y); 1683. } 1684.  1685. STATIC_OVL boolean 1686. figurine_location_checks(obj, cc, quietly) 1687. struct obj *obj; 1688. coord *cc; 1689. boolean quietly; 1690. { 1691. 	xchar x,y; 1692. 1693. 	x = cc->x; y = cc->y; 1694. 	if (!isok(x,y)) { 1695. 		if (!quietly) 1696. 			You("cannot put the figurine there."); 1697. 		return FALSE; 1698. 	} 1699. 	if (IS_ROCK(levl[x][y].typ) &&  1700. 	    !(passes_walls(&mons[obj->corpsenm]) && may_passwall(x,y))) { 1701. 		if (!quietly) 1702. 		   You("cannot place a figurine in %s!",  1703. 			IS_TREE(levl[x][y].typ) ? "a tree" : "solid rock"); 1704. 		return FALSE; 1705. 	} 1706. 	if (sobj_at(BOULDER,x,y) && !passes_walls(&mons[obj->corpsenm])  1707. 			&& !throws_rocks(&mons[obj->corpsenm])) { 1708. 		if (!quietly) 1709. 			You("cannot fit the figurine on the boulder."); 1710. 		return FALSE; 1711. 	} 1712. 	return TRUE; 1713. } 1714.  1715. STATIC_OVL void 1716. use_figurine(obj) 1717. register struct obj *obj; 1718. { 1719. 	xchar x, y;  1720. coord cc; 1721. 1722. 	if(!getdir((char *)0)) { 1723. 		flags.move = multi = 0; 1724. 		return; 1725. 	} 1726. 	x = u.ux + u.dx; y = u.uy + u.dy; 1727. 	cc.x = x; cc.y = y; 1728. /* Passing FALSE arg here will result in messages displayed */ 1729. 	if (!figurine_location_checks(obj, &cc, FALSE)) return; 1730. 	You("%s and it transforms.", 1731. 	    (u.dx||u.dy) ? "set the figurine beside you" :  1732. 	    (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) ?  1733. 		"release the figurine" :  1734. 	    (u.dz < 0 ? 1735. 		"toss the figurine into the air" : 1736. 		"set the figurine on the ground")); 1737. 	(void) make_familiar(obj, u.ux+u.dx, u.uy+u.dy, FALSE); 1738. 	(void) stop_timer(FIG_TRANSFORM, (genericptr_t)obj); 1739. 	useup(obj); 1740. } 1741.  1742. static NEARDATA const char lubricables[] = { ALL_CLASSES, ALLOW_NONE, 0 }; 1743. static NEARDATA const char need_to_remove_outer_armor[] = 1744. 			"need to remove your %s to grease your %s."; 1745. 1746. STATIC_OVL void 1747. use_grease(obj) 1748. struct obj *obj; 1749. { 1750. 	struct obj *otmp; 1751. 	char buf[BUFSZ]; 1752. 1753. 	if (Glib) { 1754. 	   dropx(obj); 1755. 	   pline("%s from your %s.", Tobjnam(obj, "slip"),  1756. 		  makeplural(body_part(FINGER))); 1757. 	   return; 1758. 	} 1759.  1760. 	if (obj->spe > 0) { 1761. 		if ((obj->cursed || Fumbling) && !rn2(2)) { 1762. 			check_unpaid(obj); 1763. 			obj->spe--; 1764. 			dropx(obj); 1765. 			pline("%s from your %s.", Tobjnam(obj, "slip"), 1766. 			      makeplural(body_part(FINGER))); 1767. 			return; 1768. 		} 1769. 		otmp = getobj(lubricables, "grease"); 1770. 		if (!otmp) return; 1771. 		if ((otmp->owornmask & WORN_ARMOR) && uarmc) { 1772. 			Strcpy(buf, xname(uarmc)); 1773. 			You(need_to_remove_outer_armor, buf, xname(otmp)); 1774. 			return; 1775. 		} 1776. #ifdef TOURIST 1777. 		if ((otmp->owornmask & WORN_SHIRT) && (uarmc || uarm)) { 1778. 			Strcpy(buf, uarmc ? xname(uarmc) : ""); 1779. 			if (uarmc && uarm) Strcat(buf, " and "); 1780. 			Strcat(buf, uarm ? xname(uarm) : ""); 1781. 			You(need_to_remove_outer_armor, buf, xname(otmp)); 1782. 			return; 1783. 		} 1784. #endif 1785. 		check_unpaid(obj); 1786. 		obj->spe--; 1787. 		if (otmp != &zeroobj) { 1788. 			You("cover %s with a thick layer of grease.", 1789. 			    yname(otmp)); 1790. 			otmp->greased = 1; 1791. 			if (obj->cursed && !nohands(youmonst.data)) { 1792. 			   incr_itimeout(&Glib, rnd(15)); 1793. 			   pline("Some of the grease gets all over your %s.",  1794. 				makeplural(body_part(HAND))); 1795. 			} 1796. 		} else { 1797. 			Glib += rnd(15); 1798. 			You("coat your %s with grease.", 1799. 			    makeplural(body_part(FINGER))); 1800. 		} 1801. 	} else { 1802. 	   if (obj->known) 1803. 		pline("%s empty.", Tobjnam(obj, "are")); 1804. 	   else 1805. 		pline("%s to be empty.", Tobjnam(obj, "seem")); 1806. 	} 1807. 	update_inventory; 1808. } 1809.  1810. static struct trapinfo { 1811. 	struct obj *tobj; 1812. 	xchar tx, ty; 1813. 	int time_needed; 1814. } trapinfo; 1815. 1816. void 1817. reset_trapset 1818. { 1819. 	trapinfo.tobj = 0; 1820. } 1821.  1822. /* touchstones - by Ken Arnold */ 1823. STATIC_OVL void 1824. use_stone(tstone) 1825. struct obj *tstone; 1826. { 1827.     struct obj *obj; 1828.    boolean do_scratch; 1829.    const char *streak_color; 1830.    char stonebuf[QBUFSZ]; 1831.    static const char scritch[] = "\"scritch, scritch\""; 1832.    static char allowall[3] = { GOLD_CLASS, ALL_CLASSES, 0 }; 1833. #ifndef GOLDOBJ 1834.    struct obj goldobj; 1835. #endif 1836. 1837.     Sprintf(stonebuf, "rub on the stone%s", plur(tstone->quan)); 1838.    if ((obj = getobj(allowall, stonebuf)) == 0) 1839. 	return; 1840. #ifndef GOLDOBJ 1841.    if (obj->oclass == GOLD_CLASS) { 1842. 	u.ugold += obj->quan;	/* keep botl up to date */ 1843. 	goldobj = *obj; 1844. 	dealloc_obj(obj); 1845. 	obj = &goldobj; 1846.    }  1847. #endif 1848. 1849.     if (obj == tstone && obj->quan == 1) { 1850. 	You_cant("rub %s on itself.", the(xname(obj))); 1851. 	return; 1852.    }  1853.  1854.     if (tstone->otyp == TOUCHSTONE && tstone->cursed &&  1855. 	    obj->oclass == GEM_CLASS && !is_graystone(obj) &&  1856. 	    !obj_resists(obj, 80, 100)) { 1857. 	if (Blind) 1858. 	   pline("You feel something shatter."); 1859. 	else if (Hallucination) 1860. 	   pline("Oh, wow, look at the pretty shards."); 1861. 	else 1862. 	   pline("A sharp crack shatters %s%s.",  1863. 		  (obj->quan > 1) ? "one of " : "", the(xname(obj))); 1864. #ifndef GOLDOBJ 1865.     /* assert(obj != &goldobj); */ 1866. #endif 1867. 	useup(obj); 1868. 	return; 1869.    }  1870.  1871.     if (Blind) { 1872. 	pline(scritch); 1873. 	return; 1874.    } else if (Hallucination) { 1875. 	pline("Oh wow, man: Fractals!"); 1876. 	return; 1877.    }  1878.  1879.     do_scratch = FALSE; 1880.    streak_color = 0; 1881. 1882.     switch (obj->oclass) { 1883.    case GEM_CLASS:	/* these have class-specific handling below */ 1884.    case RING_CLASS: 1885. 	if (tstone->otyp != TOUCHSTONE) { 1886. 	   do_scratch = TRUE; 1887. 	} else if (obj->oclass == GEM_CLASS && (tstone->blessed || 1888. 		(!tstone->cursed && 1889. 		    (Role_if(PM_ARCHEOLOGIST) || Race_if(PM_GNOME))))) { 1890. 	   makeknown(TOUCHSTONE); 1891. 	   makeknown(obj->otyp); 1892. 	   prinv((char *)0, obj, 0L); 1893. 	   return; 1894. 	} else { 1895. 	   /* either a ring or the touchstone was not effective */ 1896. 	   if (objects[obj->otyp].oc_material == GLASS) { 1897. 		do_scratch = TRUE; 1898. 		break; 1899. 	   }  1900. 	}  1901. 	streak_color = c_obj_colors[objects[obj->otyp].oc_color]; 1902. 	break;		/* gem or ring */ 1903. 1904.     default: 1905. 	switch (objects[obj->otyp].oc_material) { 1906. 	case CLOTH: 1907. 	   pline("%s a little more polished now.", Tobjnam(tstone, "look")); 1908. 	   return; 1909. 	case LIQUID: 1910. 	   if (!obj->known)		/* note: not "whetstone" */ 1911. 		You("must think this is a wetstone, do you?"); 1912. 	   else 1913. 		pline("%s a little wetter now.", Tobjnam(tstone, "are")); 1914. 	   return; 1915. 	case WAX: 1916. 	   streak_color = "waxy"; 1917. 	   break;		/* okay even if not touchstone */ 1918. 	case WOOD: 1919. 	   streak_color = "wooden"; 1920. 	   break;		/* okay even if not touchstone */ 1921. 	case GOLD: 1922. 	   do_scratch = TRUE;	/* scratching and streaks */ 1923. 	   streak_color = "golden"; 1924. 	   break; 1925. 	case SILVER: 1926. 	   do_scratch = TRUE;	/* scratching and streaks */ 1927. 	   streak_color = "silvery"; 1928. 	   break; 1929. 	default: 1930. 	   /* Objects passing the is_flimsy test will not 1931. 	      scratch a stone. They will leave streaks on 1932. non-touchstones and touchstones alike. */ 1933. 	    if (is_flimsy(obj)) 1934. 		streak_color = c_obj_colors[objects[obj->otyp].oc_color]; 1935. 	   else 1936. 		do_scratch = (tstone->otyp != TOUCHSTONE); 1937. 	   break; 1938. 	} 1939. 	break;		/* default oclass */ 1940.    }  1941.  1942.     Sprintf(stonebuf, "stone%s", plur(tstone->quan)); 1943.    if (do_scratch) 1944. 	pline("You make %s%sscratch marks on the %s.", 1945. 	      streak_color ? streak_color : (const char *)"",  1946. 	      streak_color ? " " : "", stonebuf); 1947.    else if (streak_color) 1948. 	pline("You see %s streaks on the %s.", streak_color, stonebuf); 1949.    else 1950. 	pline(scritch); 1951.    return; 1952. } 1953.  1954. /* Place a landmine/bear trap. Helge Hafting */ 1955. STATIC_OVL void 1956. use_trap(otmp) 1957. struct obj *otmp; 1958. { 1959. 	int ttyp, tmp; 1960. 	const char *what = (char *)0; 1961. 	char buf[BUFSZ]; 1962. 	const char *occutext = "setting the trap"; 1963. 1964. 	if (nohands(youmonst.data)) 1965. 	   what = "without hands"; 1966. 	else if (Stunned) 1967. 	   what = "while stunned"; 1968. 	else if (u.uswallow) 1969. 	   what = is_animal(u.ustuck->data) ? "while swallowed" : 1970. 			"while engulfed"; 1971. 	else if (Underwater) 1972. 	   what = "underwater"; 1973. 	else if (Levitation) 1974. 	   what = "while levitating"; 1975. 	else if (is_pool(u.ux, u.uy)) 1976. 	   what = "in water"; 1977. 	else if (is_lava(u.ux, u.uy)) 1978. 	   what = "in lava"; 1979. 	else if (On_stairs(u.ux, u.uy)) 1980. 	   what = (u.ux == xdnladder || u.ux == xupladder) ? 1981. 			"on the ladder" : "on the stairs"; 1982. 	else if (IS_FURNITURE(levl[u.ux][u.uy].typ) || 1983. 		IS_ROCK(levl[u.ux][u.uy].typ) ||  1984. 		closed_door(u.ux, u.uy) || t_at(u.ux, u.uy)) 1985. 	   what = "here"; 1986. 	if (what) { 1987. 	   You_cant("set a trap %s!",what); 1988. 	   reset_trapset; 1989. 	   return; 1990. 	} 1991. 	ttyp = (otmp->otyp == LAND_MINE) ? LANDMINE : BEAR_TRAP; 1992. 	if (otmp == trapinfo.tobj && 1993. 		u.ux == trapinfo.tx && u.uy == trapinfo.ty) { 1994. 	   You("resume setting %s %s.",  1995. 		shk_your(buf, otmp),  1996. 		defsyms[trap_to_defsym(what_trap(ttyp))].explanation); 1997. 	   set_occupation(set_trap, occutext, 0); 1998. 	   return; 1999. 	} 2000. 	trapinfo.tobj = otmp; 2001. 	trapinfo.tx = u.ux, trapinfo.ty = u.uy; 2002. 	tmp = ACURR(A_DEX); 2003. 	trapinfo.time_needed = (tmp > 17) ? 2 : (tmp > 12) ? 3 : 2004. 				(tmp > 7) ? 4 : 5; 2005. 	if (Blind) trapinfo.time_needed *= 2; 2006. 	tmp = ACURR(A_STR); 2007. 	if (ttyp == BEAR_TRAP && tmp < 18) 2008. 	   trapinfo.time_needed += (tmp > 12) ? 1 : (tmp > 7) ? 2 : 4; 2009. 	/*[fumbling and/or confusion and/or cursed object check(s) 2010. 	  should be incorporated here instead of in set_trap]*/ 2011. 2012. 	You("begin setting %s %s.",  2013. 	    shk_your(buf, otmp),  2014. 	    defsyms[trap_to_defsym(what_trap(ttyp))].explanation); 2015. 	set_occupation(set_trap, occutext, 0); 2016. 	return; 2017. } 2018.  2019. STATIC_PTR 2020. int 2021. set_trap 2022. { 2023. 	struct obj *otmp = trapinfo.tobj; 2024. 	struct trap *ttmp; 2025. 	int ttyp; 2026. 2027. 	if (!otmp || !carried(otmp) ||  2028. 		u.ux != trapinfo.tx || u.uy != trapinfo.ty) { 2029. 	   /* ?? */  2030. 	    reset_trapset; 2031. 	   return 0; 2032. 	} 2033.  2034. 	if (--trapinfo.time_needed > 0) return 1;	/* still busy */ 2035. 2036. 	ttyp = (otmp->otyp == LAND_MINE) ? LANDMINE : BEAR_TRAP; 2037. 	ttmp = maketrap(u.ux, u.uy, ttyp); 2038. 	if (ttmp) { 2039. 	   ttmp->tseen = 1; 2040. 	   ttmp->madeby_u = 1; 2041. 	   newsym(u.ux, u.uy); /* if our hero happens to be invisible */ 2042. 	   if (*in_rooms(u.ux,u.uy,SHOPBASE)) { 2043. 		add_damage(u.ux, u.uy, 0L);		/* schedule removal */ 2044. 	   }  2045. 	    You("finish arming %s.",  2046. 		the(defsyms[trap_to_defsym(what_trap(ttyp))].explanation)); 2047. 	   if ((otmp->cursed || Fumbling) && (rnl(10) > 5)) dotrap(ttmp, 0); 2048. 	} else { 2049. 	   /* this shouldn't happen */ 2050. 	   Your("trap setting attempt fails."); 2051. 	} 2052. 	useup(otmp); 2053. 	reset_trapset; 2054. 	return 0; 2055. } 2056.  2057. STATIC_OVL int 2058. use_whip(obj) 2059. struct obj *obj; 2060. { 2061.     char buf[BUFSZ]; 2062.    struct monst *mtmp; 2063.    struct obj *otmp; 2064.    int rx, ry, proficient, res = 0; 2065.    const char *msg_slipsfree = "The bullwhip slips free."; 2066.    const char *msg_snap = "Snap!"; 2067. 2068.     if (obj != uwep) { 2069. 	if (!wield_tool(obj)) return 0; 2070. 	else res = 1; 2071. 	/* prevent bashing msg */ 2072. 	unweapon = FALSE; 2073.    }  2074.     if (!getdir((char *)0)) return res; 2075. 2076.     if (Stunned || (Confusion && !rn2(5))) confdir; 2077.    rx = u.ux + u.dx; 2078.    ry = u.uy + u.dy; 2079.    mtmp = m_at(rx, ry); 2080. 2081.     /* fake some proficiency checks */ 2082.    proficient = 0; 2083.    if (Role_if(PM_ARCHEOLOGIST)) ++proficient; 2084.    if (ACURR(A_DEX) < 6) proficient--; 2085.    else if (ACURR(A_DEX) >= 14) proficient += (ACURR(A_DEX) - 14); 2086.    if (Fumbling) --proficient; 2087.    if (proficient > 3) proficient = 3; 2088.    if (proficient < 0) proficient = 0; 2089. 2090.     if (u.uswallow && attack(u.ustuck)) { 2091. 	There("is not enough room to flick your bullwhip."); 2092. 2093.     } else if (Underwater) { 2094. 	There("is too much resistance to flick your bullwhip."); 2095. 2096.     } else if (u.dz < 0) { 2097. 	You("flick a bug off of the %s.",ceiling(u.ux,u.uy)); 2098. 2099.     } else if ((!u.dx && !u.dy) || (u.dz > 0)) { 2100. 	int dam; 2101. 2102. #ifdef STEED 2103. 	/* Sometimes you hit your steed by mistake */ 2104. 	if (u.usteed && !rn2(proficient + 2)) { 2105. 	   You("whip %s!", mon_nam(u.usteed)); 2106. 	   kick_steed; 2107. 	   return 1; 2108. 	} 2109. #endif 2110. 	if (Levitation 2111. #ifdef STEED  2112. 			|| u.usteed  2113. #endif  2114. 		) { 2115. 	   /* Have a shot at snaring something on the floor */ 2116. 	   otmp = level.objects[u.ux][u.uy]; 2117. 	   if (otmp && otmp->otyp == CORPSE && otmp->corpsenm == PM_HORSE) { 2118. 		pline("Why beat a dead horse?"); 2119. 		return 1; 2120. 	   }  2121. 	    if (otmp && proficient) { 2122. 		You("wrap your bullwhip around %s on the %s.", 2123. 		    an(singular(otmp, xname)), surface(u.ux, u.uy)); 2124. 		if (rnl(6) || pickup_object(otmp, 1L, TRUE) < 1) 2125. 		   pline(msg_slipsfree); 2126. 		return 1; 2127. 	   }  2128. 	}  2129. 	dam = rnd(2) + dbon + obj->spe; 2130. 	if (dam <= 0) dam = 1; 2131. 	You("hit your %s with your bullwhip.", body_part(FOOT)); 2132. 	Sprintf(buf, "killed %sself with %s bullwhip", uhim, uhis); 2133. 	losehp(dam, buf, NO_KILLER_PREFIX); 2134. 	flags.botl = 1; 2135. 	return 1; 2136. 2137.     } else if ((Fumbling || Glib) && !rn2(5)) { 2138. 	pline_The("bullwhip slips out of your %s.", body_part(HAND)); 2139. 	dropx(obj); 2140. 2141.     } else if (u.utrap && u.utraptype == TT_PIT) { 2142. 	/* 2143. 	 *     Assumptions: 2144. 	 * 2145. 	 *	if you're in a pit 2146. 	 *		- you are attempting to get out of the pit 2147. 	 *		- or, if you are applying it towards a small 2148. 	 *		 monster then it is assumed that you are 2149. 	 *		 trying to hit it. 2150. 	 *	else if the monster is wielding a weapon 2151. 	 *		- you are attempting to disarm a monster 2152. 	 *	else 2153. 	 *		- you are attempting to hit the monster 2154. 	 * 2155. 	 *	if you're confused (and thus off the mark) 2156. 	 *		- you only end up hitting. 2157. 	 * 2158. 	 */  2159. 	const char *wrapped_what = (char *)0; 2160. 2161. 	if (mtmp) { 2162. 	   if (bigmonst(mtmp->data)) { 2163. 		wrapped_what = strcpy(buf, mon_nam(mtmp)); 2164. 	   } else if (proficient) { 2165. 		if (attack(mtmp)) return 1; 2166. 		else pline(msg_snap); 2167. 	   }  2168. 	}  2169. 	if (!wrapped_what) { 2170. 	   if (IS_FURNITURE(levl[rx][ry].typ)) 2171. 		wrapped_what = something; 2172. 	   else if (sobj_at(BOULDER, rx, ry)) 2173. 		wrapped_what = "a boulder"; 2174. 	} 2175. 	if (wrapped_what) { 2176. 	   coord cc; 2177. 2178. 	    cc.x = rx; cc.y = ry; 2179. 	   You("wrap your bullwhip around %s.", wrapped_what); 2180. 	   if (proficient && rn2(proficient + 2)) { 2181. 		if (!mtmp || enexto(&cc, rx, ry, youmonst.data)) { 2182. 		   You("yank yourself out of the pit!"); 2183. 		   teleds(cc.x, cc.y); 2184. 		   u.utrap = 0; 2185. 		   vision_full_recalc = 1; 2186. 		} 2187. 	    } else { 2188. 		pline(msg_slipsfree); 2189. 	   }  2190. 	    if (mtmp) wakeup(mtmp); 2191. 	} else pline(msg_snap); 2192. 2193.     } else if (mtmp) { 2194. 	if (!canspotmon(mtmp) && 2195. 		!glyph_is_invisible(levl[rx][ry].glyph)) { 2196. 	  pline("A monster is there that you couldn't see."); 2197. 	  map_invisible(rx, ry); 2198. 	} 2199. 	otmp = MON_WEP(mtmp);	/* can be null */ 2200. 	if (otmp) { 2201. 	   char onambuf[BUFSZ]; 2202. 	   const char *mon_hand; 2203. 	   boolean gotit = proficient && (!Fumbling || !rn2(10)); 2204. 2205. 	    Strcpy(onambuf, cxname(otmp)); 2206. 	   if (gotit) { 2207. 		mon_hand = mbodypart(mtmp, HAND); 2208. 		if (bimanual(otmp)) mon_hand = makeplural(mon_hand); 2209. 	   } else 2210. 		mon_hand = 0;	/* lint suppression */ 2211. 2212. 	    You("wrap your bullwhip around %s %s.",  2213. 		s_suffix(mon_nam(mtmp)), onambuf); 2214. 	   if (gotit && otmp->cursed) { 2215. 		pline("%s welded to %s %s%c", 2216. 		      (otmp->quan == 1L) ? "It is" : "They are",  2217. 		      mhis(mtmp), mon_hand,  2218. 		      !otmp->bknown ? '!' : '.'); 2219. 		otmp->bknown = 1; 2220. 		gotit = FALSE;	/* can't pull it free */ 2221. 	   }  2222. 	    if (gotit) { 2223. 		obj_extract_self(otmp); 2224. 		possibly_unwield(mtmp); 2225. 		setmnotwielded(mtmp,otmp); 2226. 2227. 		switch (rn2(proficient + 1)) { 2228. 		case 2: 2229. 		   /* to floor near you */ 2230. 		   You("yank %s %s to the %s!", s_suffix(mon_nam(mtmp)),  2231. 			onambuf, surface(u.ux, u.uy)); 2232. 		   place_object(otmp, u.ux, u.uy); 2233. 		   stackobj(otmp); 2234. 		   break; 2235. 		case 3: 2236. 		   /* right to you */ 2237. #if 0 2238. 		   if (!rn2(25)) { 2239. 			/* proficient with whip, but maybe not 2240. 			  so proficient at catching weapons */ 2241. 			int hitu, hitvalu; 2242. 2243. 			hitvalu = 8 + otmp->spe; 2244. 			hitu = thitu(hitvalu, 2245. 				     dmgval(otmp, &youmonst),  2246. 				     otmp, (char *)0); 2247. 			if (hitu) { 2248. 			   pline_The("%s hits you as you try to snatch it!",  2249. 				the(onambuf)); 2250. 			} 2251. 			place_object(otmp, u.ux, u.uy); 2252. 			stackobj(otmp); 2253. 			break; 2254. 		   }  2255. #endif /* 0 */ 2256. 		   /* right into your inventory */ 2257. 		   You("snatch %s %s!", s_suffix(mon_nam(mtmp)), onambuf); 2258. 		   if (otmp->otyp == CORPSE &&  2259. 			    touch_petrifies(&mons[otmp->corpsenm]) &&  2260. 			    !uarmg && !Stone_resistance &&  2261. 			    !(poly_when_stoned(youmonst.data) && 2262. 				polymon(PM_STONE_GOLEM))) { 2263. 			char kbuf[BUFSZ]; 2264. 2265. 			Sprintf(kbuf, "%s corpse",  2266. 				an(mons[otmp->corpsenm].mname)); 2267. 			pline("Snatching %s is a fatal mistake.", kbuf); 2268. 			instapetrify(kbuf); 2269. 		   }  2270. 		    otmp = hold_another_object(otmp, "You drop %s!",  2271. 					       doname(otmp), (const char *)0); 2272. 		   break; 2273. 		default: 2274. 		   /* to floor beneath mon */ 2275. 		   You("yank %s from %s %s!", the(onambuf),  2276. 			s_suffix(mon_nam(mtmp)), mon_hand); 2277. 		   obj_no_longer_held(otmp); 2278. 		   place_object(otmp, mtmp->mx, mtmp->my); 2279. 		   stackobj(otmp); 2280. 		   break; 2281. 		} 2282. 	    } else { 2283. 		pline(msg_slipsfree); 2284. 	   }  2285. 	    wakeup(mtmp); 2286. 	} else { 2287. 	   if (mtmp->m_ap_type &&  2288. 		!Protection_from_shape_changers && !sensemon(mtmp)) 2289. 		stumble_onto_mimic(mtmp); 2290. 	   else You("flick your bullwhip towards %s.", mon_nam(mtmp)); 2291. 	   if (proficient) { 2292. 		if (attack(mtmp)) return 1; 2293. 		else pline(msg_snap); 2294. 	   }  2295. 	}  2296.  2297.     } else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) { 2298. 	   /* it must be air -- water checked above */ 2299. 	   You("snap your whip through thin air."); 2300. 2301.     } else { 2302. 	pline(msg_snap); 2303. 2304.     }  2305.     return 1; 2306. } 2307.  2308.  2309. static const char 2310. 	*not_enough_room = "There's not enough room here to use that.", 2311. 	*where_to_hit = "Where do you want to hit?", 2312. 	*cant_see_spot = "won't hit anything if you can't see that spot."; 2313. 2314. /* Distance attacks by pole-weapons */ 2315. STATIC_OVL int 2316. use_pole (obj) 2317. 	struct obj *obj; 2318. { 2319. 	int res = 0, typ, max_range = 4, min_range = 4; 2320. 	coord cc; 2321. 	struct monst *mtmp; 2322. 2323.  2324. 	/* Are you allowed to use the pole? */ 2325. 	if (u.uswallow) { 2326. 	   pline(not_enough_room); 2327. 	   return (0); 2328. 	} 2329. 	if (obj != uwep) { 2330. 	   if (!wield_tool(obj)) return(0); 2331. 	   else res = 1; 2332. 	} 2333.      /* assert(obj == uwep); */ 2334. 2335. 	/* Prompt for a location */ 2336. 	pline(where_to_hit); 2337. 	cc.x = u.ux; 2338. 	cc.y = u.uy; 2339. 	if (getpos(&cc, TRUE, "the spot to hit") < 0) 2340. 	   return 0;	/* user pressed ESC */ 2341. 2342. 	/* Calculate range */ 2343. 	typ = uwep_skill_type; 2344. 	if (typ == P_NONE || P_SKILL(typ) <= P_BASIC) max_range = 4; 2345. 	else if (P_SKILL(typ) == P_SKILLED) max_range = 5; 2346. 	else max_range = 8; 2347. 	if (distu(cc.x, cc.y) > max_range) { 2348. 	   pline("Too far!"); 2349. 	   return (res); 2350. 	} else if (distu(cc.x, cc.y) < min_range) { 2351. 	   pline("Too close!"); 2352. 	   return (res); 2353. 	} else if (!cansee(cc.x, cc.y)) { 2354. 	   You(cant_see_spot); 2355. 	   return (res); 2356. 	} 2357.  2358. 	/* Attack the monster there */ 2359. 	if ((mtmp = m_at(cc.x, cc.y)) != (struct monst *)0) { 2360. 	   int oldhp = mtmp->mhp; 2361. 2362. 	    (void) thitmonst(mtmp, uwep); 2363. 	   /* check the monster's HP because thitmonst doesn't return 2364. 	    * an indication of whether it hit. Not perfect (what if it's a 2365. 	     * non-silver weapon on a shade?) 2366. 	    */  2367. 	    if (mtmp->mhp < oldhp) 2368. 		u.uconduct.weaphit++; 2369. 	} else 2370. 	   /* Now you know that nothing is there... */ 2371. 	    pline(nothing_happens); 2372. 	return (1); 2373. } 2374.  2375.  2376. STATIC_OVL int 2377. use_grapple (obj) 2378. 	struct obj *obj; 2379. { 2380. 	int res = 0, typ, max_range = 4; 2381. 	coord cc; 2382. 	struct monst *mtmp; 2383. 	struct obj *otmp; 2384. 2385. 	/* Are you allowed to use the hook? */ 2386. 	if (u.uswallow) { 2387. 	   pline(not_enough_room); 2388. 	   return (0); 2389. 	} 2390. 	if (obj != uwep) { 2391. 	   if (!wield_tool(obj)) return(0); 2392. 	   else res = 1; 2393. 	} 2394.      /* assert(obj == uwep); */ 2395. 2396. 	/* Prompt for a location */ 2397. 	pline(where_to_hit); 2398. 	cc.x = u.ux; 2399. 	cc.y = u.uy; 2400. 	if (getpos(&cc, TRUE, "the spot to hit") < 0) 2401. 	   return 0;	/* user pressed ESC */ 2402. 2403. 	/* Calculate range */ 2404. 	typ = uwep_skill_type; 2405. 	if (typ == P_NONE || P_SKILL(typ) <= P_BASIC) max_range = 4; 2406. 	else if (P_SKILL(typ) == P_SKILLED) max_range = 5; 2407. 	else max_range = 8; 2408. 	if (distu(cc.x, cc.y) > max_range) { 2409. 		pline("Too far!"); 2410. 		return (res); 2411. 	} else if (!cansee(cc.x, cc.y)) { 2412. 		You(cant_see_spot); 2413. 		return (res); 2414. 	} 2415.  2416. 	/* What did you hit? */ 2417. 	switch (rn2(5)) { 2418. 	case 0:	/* Trap */ 2419. 	   /* FIXME -- untrap needs to deal with non-adjacent traps */ 2420. 	   break; 2421. 	case 1:	/* Object */ 2422. 	   if ((otmp = level.objects[cc.x][cc.y]) != 0) { 2423. 		You("snag an object from the %s!", surface(cc.x, cc.y)); 2424. 		(void) pickup_object(otmp, 1L, FALSE); 2425. 		/* If pickup fails, leave it alone */ 2426. 		newsym(cc.x, cc.y); 2427. 		return (1); 2428. 	   }  2429. 	    break; 2430. 	case 2:	/* Monster */ 2431. 	   if ((mtmp = m_at(cc.x, cc.y)) == (struct monst *)0) break; 2432. 	   if (verysmall(mtmp->data) && !rn2(4) &&  2433. 			enexto(&cc, u.ux, u.uy, (struct permonst *)0)) { 2434. 		You("pull in %s!", mon_nam(mtmp)); 2435. 		mtmp->mundetected = 0; 2436. 		rloc_to(mtmp, cc.x, cc.y); 2437. 		return (1); 2438. 	   } else if ((!bigmonst(mtmp->data) && !strongmonst(mtmp->data)) ||  2439. 		       rn2(4)) { 2440. 		(void) thitmonst(mtmp, uwep); 2441. 		return (1); 2442. 	   }  2443. 	    /* FALL THROUGH */ 2444. 	case 3:	/* Surface */ 2445. 	   if (IS_AIR(levl[cc.x][cc.y].typ) || is_pool(cc.x, cc.y)) 2446. 		pline_The("hook slices through the %s.", surface(cc.x, cc.y)); 2447. 	   else { 2448. 		You("are yanked toward the %s!", surface(cc.x, cc.y)); 2449. 		hurtle(sgn(cc.x-u.ux), sgn(cc.y-u.uy), 1, FALSE); 2450. 		spoteffects(TRUE); 2451. 	   }  2452. 	    return (1); 2453. 	default:	/* Yourself (oops!) */ 2454. 	   if (P_SKILL(typ) <= P_BASIC) { 2455. 		You("hook yourself!"); 2456. 		losehp(rn1(10,10), "a grappling hook", KILLED_BY); 2457. 		return (1); 2458. 	   }  2459. 	    break; 2460. 	} 2461. 	pline(nothing_happens); 2462. 	return (1); 2463. } 2464.  2465.  2466. #define BY_OBJECT	((struct monst *)0) 2467. 2468. /* return 1 if the wand is broken, hence some time elapsed */ 2469. STATIC_OVL int 2470. do_break_wand(obj) 2471.    struct obj *obj; 2472. { 2473.     static const char nothing_else_happens[] = "But nothing else happens..."; 2474.    register int i, x, y;  2475. register struct monst *mon; 2476.    int dmg, damage; 2477.    boolean affects_objects; 2478.    int expltype = EXPL_MAGICAL; 2479.    char confirm[QBUFSZ], the_wand[BUFSZ], buf[BUFSZ]; 2480. 2481.     Strcpy(the_wand, yname(obj)); 2482.    Sprintf(confirm, "Are you really sure you want to break %s?", the_wand); 2483.    if (yn(confirm) == 'n' ) return 0; 2484. 2485.     if (nohands(youmonst.data)) { 2486. 	You_cant("break %s without hands!", the_wand); 2487. 	return 0; 2488.    } else if (ACURR(A_STR) < 10) { 2489. 	You("don't have the strength to break %s!", the_wand); 2490. 	return 0; 2491.    }  2492.     pline("Raising %s high above your %s, you break it in two!",  2493. 	  the_wand, body_part(HEAD)); 2494. 2495.     /* [ALI] Do this first so that wand is removed from bill. Otherwise, 2496.     * the freeinv below also hides it from setpaid which causes problems. 2497.     */  2498.     if (obj->unpaid) { 2499. 	check_unpaid(obj);		/* Extra charge for use */ 2500. 	bill_dummy_object(obj); 2501.    }  2502.  2503.     current_wand = obj;		/* destroy_item might reset this */ 2504.    freeinv(obj);		/* hide it from destroy_item instead... */ 2505.     setnotworn(obj);		/* so we need to do this ourselves */ 2506. 2507.     if (obj->spe <= 0) { 2508. 	pline(nothing_else_happens); 2509. 	goto discard_broken_wand; 2510.    }  2511.     obj->ox = u.ux; 2512.    obj->oy = u.uy; 2513.    dmg = obj->spe * 4; 2514.    affects_objects = FALSE; 2515. 2516.     switch (obj->otyp) { 2517.    case WAN_WISHING: 2518.    case WAN_NOTHING: 2519.    case WAN_LOCKING: 2520.    case WAN_PROBING: 2521.    case WAN_ENLIGHTENMENT: 2522.    case WAN_OPENING: 2523.    case WAN_SECRET_DOOR_DETECTION: 2524. 	pline(nothing_else_happens); 2525. 	goto discard_broken_wand; 2526.    case WAN_DEATH: 2527.    case WAN_LIGHTNING: 2528. 	dmg *= 4; 2529. 	goto wanexpl; 2530.    case WAN_FIRE: 2531. 	expltype = EXPL_FIERY; 2532.    case WAN_COLD: 2533. 	if (expltype == EXPL_MAGICAL) expltype = EXPL_FROSTY; 2534. 	dmg *= 2; 2535.    case WAN_MAGIC_MISSILE: 2536.    wanexpl: 2537. 	explode(u.ux, u.uy, 2538. 		(obj->otyp - WAN_MAGIC_MISSILE), dmg, WAND_CLASS, expltype); 2539. 	makeknown(obj->otyp);	/* explode described the effect */ 2540. 	goto discard_broken_wand; 2541.    case WAN_STRIKING: 2542. 	/* we want this before the explosion instead of at the very end */ 2543. 	pline("A wall of force smashes down around you!"); 2544. 	dmg = d(1 + obj->spe,6);	/* normally 2d12 */ 2545.    case WAN_CANCELLATION: 2546.    case WAN_POLYMORPH: 2547.    case WAN_TELEPORTATION: 2548.    case WAN_UNDEAD_TURNING: 2549. 	affects_objects = TRUE; 2550. 	break; 2551.    default: 2552. 	break; 2553.    }  2554.  2555.     /* magical explosion and its visual effect occur before specific effects */ 2556.    explode(obj->ox, obj->oy, 0, rnd(dmg), WAND_CLASS, EXPL_MAGICAL); 2557. 2558.     /* this makes it hit us last, so that we can see the action first */ 2559.    for (i = 0; i <= 8; i++) { 2560. 	bhitpos.x = x = obj->ox + xdir[i]; 2561. 	bhitpos.y = y = obj->oy + ydir[i]; 2562. 	if (!isok(x,y)) continue; 2563. 2564. 	if (obj->otyp == WAN_DIGGING) { 2565. 	   if(dig_check(BY_OBJECT, FALSE, x, y)) 2566. 		digactualhole(x, y, BY_OBJECT, 2567. 			      (rn2(obj->spe) < 3 || !Can_dig_down(&u.uz)) ?  2568. 			       PIT : HOLE); 2569. 	   continue; 2570. 	} else if(obj->otyp == WAN_CREATE_MONSTER) { 2571. 	   /* u.ux,u.uy creates it near you--x,y might create it in rock */ 2572. 	   (void) makemon((struct permonst *)0, u.ux, u.uy, NO_MM_FLAGS); 2573. 	   continue; 2574. 	} else { 2575. 	   if (x == u.ux && y == u.uy) { 2576. 		/* teleport objects first to avoid race with tele control and 2577. 		  autopickup. Other wand/object effects handled after 2578. 		  possible wand damage is assessed */ 2579. 		if (obj->otyp == WAN_TELEPORTATION && 2580. 		    affects_objects && level.objects[x][y]) { 2581. 		   (void) bhitpile(obj, bhito, x, y); 2582. 		   if (flags.botl) bot;		/* potion effects */ 2583. 		} 2584. 		damage = zapyourself(obj, FALSE); 2585. 		if (damage) { 2586. 		   Sprintf(buf, "killed %sself by breaking a wand", uhim); 2587. 		   losehp(damage, buf, NO_KILLER_PREFIX); 2588. 		} 2589. 		if (flags.botl) bot;		/* blindness */ 2590. 	   } else if ((mon = m_at(x, y)) != 0) { 2591. 		(void) bhitm(mon, obj); 2592. 	    /* if (flags.botl) bot; */ 2593. 	   }  2594. 	    if (affects_objects && level.objects[x][y]) { 2595. 		(void) bhitpile(obj, bhito, x, y); 2596. 		if (flags.botl) bot;		/* potion effects */ 2597. 	   }  2598. 	}  2599.     }  2600.  2601.     if (obj->otyp == WAN_LIGHT) 2602. 	litroom(TRUE, obj);	/* only needs to be done once */ 2603. 2604.  discard_broken_wand: 2605.    obj = current_wand;		/* [see dozap and destroy_item] */ 2606.    current_wand = 0; 2607.    if (obj) 2608. 	delobj(obj); 2609.    nomul(0); 2610.    return 1; 2611. } 2612.  2613. STATIC_OVL boolean 2614. uhave_graystone 2615. { 2616. 	register struct obj *otmp; 2617. 2618. 	for(otmp = invent; otmp; otmp = otmp->nobj) 2619. 		if(is_graystone(otmp)) 2620. 			return TRUE; 2621. 	return FALSE; 2622. } 2623.  2624. int 2625. doapply 2626. { 2627. 	register struct obj *obj; 2628. 	register int res = 1; 2629. 2630. 	if(check_capacity((char *)0)) return (0); 2631. 	obj = getobj(carrying(POT_OIL) || uhave_graystone 2632. 		? tools_too : tools, "use or apply"); 2633. 	if(!obj) return 0; 2634. 2635. 	if (obj->oclass == WAND_CLASS) 2636. 	   return do_break_wand(obj); 2637. 2638. 	switch(obj->otyp){ 2639. 	case BLINDFOLD: 2640. 	case LENSES: 2641. 		if (obj == ublindf) { 2642. 		   if (!cursed(obj)) Blindf_off(obj); 2643. 		} else if (!ublindf) 2644. 		   Blindf_on(obj); 2645. 		else You("are already %s.", 2646. 			ublindf->otyp == TOWEL ?     "covered by a towel" :  2647. 			ublindf->otyp == BLINDFOLD ? "wearing a blindfold" :  2648. 						     "wearing lenses"); 2649. 		break; 2650. 	case BULLWHIP: 2651. 		res = use_whip(obj); 2652. 		break; 2653. 	case GRAPPLING_HOOK: 2654. 		res = use_grapple(obj); 2655. 		break; 2656. 	case LARGE_BOX: 2657. 	case CHEST: 2658. 	case ICE_BOX: 2659. 	case SACK: 2660. 	case BAG_OF_HOLDING: 2661. 	case OILSKIN_SACK: 2662. 		res = use_container(obj, 1); 2663. 		break; 2664. 	case BAG_OF_TRICKS: 2665. 		if(obj->spe > 0) { 2666. 			register int cnt = 1; 2667. 2668. 			check_unpaid(obj); 2669. 			obj->spe--; 2670. 			if(!rn2(23)) cnt += rn2(7) + 1; 2671. 			while(cnt--) 2672. 			  (void) makemon((struct permonst *) 0,  2673. 						u.ux, u.uy, NO_MM_FLAGS); 2674. 			makeknown(BAG_OF_TRICKS); 2675. 		} else 2676. 			pline(nothing_happens); 2677. 		break; 2678. 	case CAN_OF_GREASE: 2679. 		use_grease(obj); 2680. 		break; 2681. 	case LOCK_PICK: 2682. #ifdef TOURIST 2683. 	case CREDIT_CARD: 2684. #endif 2685. 	case SKELETON_KEY: 2686. 		(void) pick_lock(obj); 2687. 		break; 2688. 	case PICK_AXE: 2689. 	case DWARVISH_MATTOCK: 2690. 		res = use_pick_axe(obj); 2691. 		break; 2692. 	case TINNING_KIT: 2693. 		use_tinning_kit(obj); 2694. 		break; 2695. 	case LEASH: 2696. 		use_leash(obj); 2697. 		break; 2698. #ifdef STEED 2699. 	case SADDLE: 2700. 		res = use_saddle(obj); 2701. 		break; 2702. #endif 2703. 	case MAGIC_WHISTLE: 2704. 		use_magic_whistle(obj); 2705. 		break; 2706. 	case TIN_WHISTLE: 2707. 		use_whistle(obj); 2708. 		break; 2709. 	case STETHOSCOPE: 2710. 		res = use_stethoscope(obj); 2711. 		break; 2712. 	case MIRROR: 2713. 		res = use_mirror(obj); 2714. 		break; 2715. 	case BELL: 2716. 	case BELL_OF_OPENING: 2717. 		use_bell(obj); 2718. 		break; 2719. 	case CANDELABRUM_OF_INVOCATION: 2720. 		use_candelabrum(obj); 2721. 		break; 2722. 	case WAX_CANDLE: 2723. 	case TALLOW_CANDLE: 2724. 		use_candle(obj); 2725. 		break; 2726. 	case OIL_LAMP: 2727. 	case MAGIC_LAMP: 2728. 	case BRASS_LANTERN: 2729. 		use_lamp(obj); 2730. 		break; 2731. 	case POT_OIL: 2732. 		light_cocktail(obj); 2733. 		break; 2734. #ifdef TOURIST 2735. 	case EXPENSIVE_CAMERA: 2736. 		res = use_camera(obj); 2737. 		break; 2738. #endif 2739. 	case TOWEL: 2740. 		res = use_towel(obj); 2741. 		break; 2742. 	case CRYSTAL_BALL: 2743. 		use_crystal_ball(obj); 2744. 		break; 2745. 	case MAGIC_MARKER: 2746. 		res = dowrite(obj); 2747. 		break; 2748. 	case TIN_OPENER: 2749. 		if(!carrying(TIN)) { 2750. 			You("have no tin to open."); 2751. 			goto xit; 2752. 		} 2753. 		You("cannot open a tin without eating or discarding its contents."); 2754. 		if(flags.verbose) 2755. 			pline("In order to eat, use the 'e' command."); 2756. 		if(obj != uwep) 2757.    pline("Opening the tin will be much easier if you wield the tin opener."); 2758. 		goto xit; 2759. 2760. 	case FIGURINE: 2761. 		use_figurine(obj); 2762. 		break; 2763. 	case UNICORN_HORN: 2764. 		use_unicorn_horn(obj); 2765. 		break; 2766. 	case WOODEN_FLUTE: 2767. 	case MAGIC_FLUTE: 2768. 	case TOOLED_HORN: 2769. 	case FROST_HORN: 2770. 	case FIRE_HORN: 2771. 	case WOODEN_HARP: 2772. 	case MAGIC_HARP: 2773. 	case BUGLE: 2774. 	case LEATHER_DRUM: 2775. 	case DRUM_OF_EARTHQUAKE: 2776. 		res = do_play_instrument(obj); 2777. 		break; 2778. 	case HORN_OF_PLENTY:	/* not a musical instrument */ 2779. 		if (obj->spe > 0) { 2780. 		   struct obj *otmp; 2781. 		   const char *what; 2782. 2783. 		    check_unpaid(obj); 2784. 		   obj->spe--; 2785. 		   if (!rn2(13)) { 2786. 			otmp = mkobj(POTION_CLASS, FALSE); 2787. 			if (objects[otmp->otyp].oc_magic) do { 2788. 			   otmp->otyp = rnd_class(POT_BOOZE, POT_WATER); 2789. 			} while (otmp->otyp == POT_SICKNESS); 2790. 			what = "A potion"; 2791. 		   } else { 2792. 			otmp = mkobj(FOOD_CLASS, FALSE); 2793. 			if (otmp->otyp == FOOD_RATION && !rn2(7)) 2794. 			   otmp->otyp = LUMP_OF_ROYAL_JELLY; 2795. 			what = "Some food"; 2796. 		   }  2797. 		    pline("%s spills out.", what); 2798. 		   otmp->blessed = obj->blessed; 2799. 		   otmp->cursed = obj->cursed; 2800. 		   otmp->owt = weight(otmp); 2801. 		   otmp = hold_another_object(otmp,  2802. 					(u.uswallow || Is_airlevel(&u.uz) || 2803. 					 u.uinwater || Is_waterlevel(&u.uz)) ? 2804. 					       "Oops!  %s away from you!" :  2805. 					       "Oops!  %s to the floor!",  2806. 					       The(aobjnam(otmp, "slip")),  2807. 					       (const char *)0); 2808. 		   makeknown(HORN_OF_PLENTY); 2809. 		} else 2810. 		   pline(nothing_happens); 2811. 		break; 2812. 	case LAND_MINE: 2813. 	case BEARTRAP: 2814. 		use_trap(obj); 2815. 		break; 2816. 	case FLINT: 2817. 	case LUCKSTONE: 2818. 	case LOADSTONE: 2819. 	case TOUCHSTONE: 2820. 		use_stone(obj); 2821. 		break; 2822. 	default: 2823. 		/* Pole-weapons can strike at a distance */ 2824. 		if (is_pole(obj)) { 2825. 			res = use_pole(obj); 2826. 			break; 2827. 		} else if (is_pick(obj) /* || is_axe(obj) */) { 2828. 			res = use_pick_axe(obj); 2829. 			break; 2830. 		} 2831. 		pline("Sorry, I don't know how to use that."); 2832. 	xit: 2833. 		nomul(0); 2834. 		return 0; 2835. 	} 2836. 	if (res && obj->oartifact) arti_speak(obj); 2837. 	nomul(0); 2838. 	return res; 2839. } 2840.  2841. /* Keep track of unfixable troubles for purposes of messages saying you feel 2842. * great. 2843. */  2844. int unfixable_trouble_count(is_horn) 2845. 	boolean is_horn; 2846. { 2847. 	int unfixable_trbl = 0; 2848. 2849. 	if (Stoned) unfixable_trbl++; 2850. 	if (Strangled) unfixable_trbl++; 2851. 	if (Wounded_legs 2852. #ifdef STEED  2853. 		    && !u.usteed  2854. #endif  2855. 				) unfixable_trbl++; 2856. 	if (Slimed) unfixable_trbl++; 2857. 	/* lycanthropy is not desirable, but it doesn't actually make you feel 2858. 	  bad */ 2859. 2860. 	/* we'll assume that intrinsic stunning from being a bat/stalker 2861. 	  doesn't make you feel bad */ 2862. 	if (!is_horn) { 2863. 	   if (Confusion) unfixable_trbl++; 2864. 	   if (Sick) unfixable_trbl++; 2865. 	   if (HHallucination) unfixable_trbl++; 2866. 	   if (Vomiting) unfixable_trbl++; 2867. 	   if (HStun) unfixable_trbl++; 2868. 	} 2869. 	return unfixable_trbl; 2870. } 2871.  2872. #endif /* OVLB */ 2873. 2874. /*apply.c*/