Source:Apply.c

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