Source:SLASH'EM 0.0.7E7F3/apply.c

From NetHackWiki
Jump to: navigation, search

Below is the full text to apply.c from the source code of SLASH'EM 0.0.7E7F3. To link to a particular line, write {{sourcecode|apply.c|123|version=SLASH'EM 0.0.7E7F3}}, for example.

The latest source code for vanilla NetHack is at Source code.

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

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