Wikihack
Advertisement

Below is the full text to apply.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/apply.c#line123]], 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.
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. /* KMH, balance patch -- Distance attacks by pole-weapons */
2751. /* WAC -- Range limited by skill */
2752. static int
2753. use_pole(obj)
2754. 	struct obj *obj;
2755. {
2756. 	int res = 0, max_range = 8, min_range;
2757. 	coord cc;
2758. 	struct monst *mtmp;
2759. 	struct obj *otmp;
2760. 	boolean fishing;
2761. 
2762. 
2763. 	/* Are you allowed to use the pole? */
2764. 	if (u.uswallow) {
2765. 		pline("There's not enough room here to use that.");
2766. 		return (0);
2767. 	}
2768. 	if (obj != uwep) {
2769. 	    if (!wield_tool(obj, "swing")) return(0);
2770. 	    else res = 1;
2771. 	}
2772. 
2773. 	/* Prompt for a location */
2774. 	pline("Where do you want to hit?");
2775. 	cc.x = u.ux;
2776. 	cc.y = u.uy;
2777. 	getpos(&cc, TRUE, "the spot to hit");
2778. 	if (cc.x == -10) return (0); /* user pressed esc */
2779. 
2780. #ifdef WEAPON_SKILLS
2781. 	/* WAC -- range depends on skill.  Default is 8 */
2782. 	if (weapon_type(obj) == P_NONE) max_range = 4;
2783. 	else if (P_SKILL(weapon_type(obj)) <= P_BASIC) max_range = 4;
2784. 	else if (P_SKILL(weapon_type(obj)) <= P_SKILLED) max_range = 5;
2785. #endif
2786. 	
2787. 	min_range = ((obj->otyp == FISHING_POLE) ? 1 : 4);
2788. 
2789. 	if (distu(cc.x, cc.y) > max_range) {
2790. 		pline("Too far!");
2791. 		return (res);
2792. 	} else if (distu(cc.x, cc.y) < min_range) {
2793. 		pline("Too close!");
2794. 		return (res);
2795. 	} else if (!cansee(cc.x, cc.y)) {
2796. 		You("won't hit anything if you can't see that spot.");
2797. 		return (res);
2798. 	}
2799. 
2800. 	/* What is there? */
2801. 	mtmp = m_at(cc.x, cc.y);
2802. 	fishing = (obj->otyp == FISHING_POLE) && is_pool(cc.x, cc.y);
2803. 
2804. 	/* Try a random effect */
2805. 	switch (rnd(6))
2806. 	{
2807. 		case 1:
2808. 			/* Snag yourself */
2809. 			if (obj->otyp == FISHING_POLE) {
2810. 				You("hook yourself!");
2811. 				losehp(rn1(10,10), "a fishing hook", KILLED_BY);
2812. 				return (1);
2813. 			}
2814. 			break;
2815. 		case 2:
2816. 			/* Reel in a fish */
2817. 			if (fishing && mtmp) {
2818. 				if ((bigmonst(mtmp->data) || strongmonst(mtmp->data))
2819. 						&& !rn2(2)) {
2820. 					You("are yanked toward the %s",
2821. 							surface(cc.x, cc.y));
2822. 					hurtle(sgn(cc.x-u.ux), sgn(cc.y-u.uy), 1, TRUE);
2823. 					return (1);
2824. 				} else if (enexto(&cc, u.ux, u.uy, 0)) {
2825. 					You("reel in %s!", mon_nam(mtmp));
2826. 					mtmp->mundetected = 0;
2827. 					rloc_to(mtmp, cc.x, cc.y);
2828. 					return (1);
2829. 				}
2830. 			}
2831. 			break;
2832. 		case 3:
2833. 			/* Snag an existing object */
2834. 			if (obj->otyp == FISHING_POLE &&
2835. 					(otmp = level.objects[cc.x][cc.y]) !=
2836. 					(struct obj *)0) {
2837. 				You("snag an object from the %s!", surface(cc.x, cc.y));
2838. 				pickup_object(otmp, 1, FALSE);
2839. 				/* If pickup fails, leave it alone */
2840. 				newsym(cc.x, cc.y);
2841. 				return (1);
2842. 			}
2843. 			break;
2844. 		case 4:
2845. 			/* Snag some garbage */
2846. 			if (fishing && flags.boot_count < 1 &&
2847. 					(otmp = mksobj(LOW_BOOTS, TRUE, FALSE)) !=
2848. 					(struct obj *)0) {
2849. 				flags.boot_count++;
2850. 				You("snag some garbage from the %s!",
2851. 						surface(cc.x, cc.y));
2852. 				if (pickup_object(otmp, 1, FALSE) <= 0) {
2853. 					obj_extract_self(otmp);
2854. 					place_object(otmp, u.ux, u.uy);
2855. 					newsym(u.ux, u.uy);
2856. 				}
2857. 				return (1);
2858. 			}
2859. #ifdef SINKS
2860. 			/* Or a rat in the sink/toilet */
2861. 			if (obj->otyp == FISHING_POLE &&
2862. 					!(mvitals[PM_SEWER_RAT].mvflags & G_GONE) &&
2863. 					(IS_SINK(levl[cc.x][cc.y].typ) ||
2864. 					IS_TOILET(levl[cc.x][cc.y].typ))) {
2865. 				mtmp = makemon(&mons[PM_SEWER_RAT],
2866. 						cc.x, cc.y, NO_MM_FLAGS);
2867. 				pline("Eek!  There's %s there!",
2868. 					Blind ? "something squirmy" :
2869. 					a_monnam(mtmp));
2870. 				return (1);
2871. 			}
2872. #endif
2873. 			break;
2874. 		case 5:
2875. 			/* Catch your dinner */
2876. 			if (fishing &&
2877. 					(otmp = mksobj(CRAM_RATION, TRUE, FALSE)) !=
2878. 					(struct obj *)0) {
2879. 				You("catch tonight's dinner!");
2880. 				if (pickup_object(otmp, 1, FALSE) <= 0) {
2881. 					obj_extract_self(otmp);
2882. 					place_object(otmp, u.ux, u.uy);
2883. 					newsym(u.ux, u.uy);
2884. 				}
2885. 				return (1);
2886. 			}
2887. 			break;
2888. 		default:
2889. 		case 6:
2890. 			/* Untrap */
2891. 			/* FIXME -- needs to deal with non-adjacent traps */
2892. 			break;
2893. 	}
2894. 
2895. 	/* The effect didn't apply.  Attack whatever is there. */
2896. 	if (mtmp) {
2897. 		(void) thitmonst(mtmp, uwep, 1);
2898. 		return (1);
2899. 	}
2900. 
2901. 	pline(nothing_happens);
2902. 	return (1);
2903. }
2904. 
2905. 
2906. static const char
2907. 	not_enough_room[] = "There's not enough room here to use that.",
2908. 	where_to_hit[] = "Where do you want to hit?",
2909. 	cant_see_spot[] = "won't hit anything if you can't see that spot.",
2910. 	cant_reach[] = "can't reach that spot from here.";
2911. 
2912. #if 0
2913. /* Distance attacks by pole-weapons */
2914. STATIC_OVL int
2915. use_pole (obj)
2916. 	struct obj *obj;
2917. {
2918. 	int res = 0, typ, max_range = 4, min_range = 4;
2919. 	coord cc;
2920. 	struct monst *mtmp;
2921. 
2922. 
2923. 	/* Are you allowed to use the pole? */
2924. 	if (u.uswallow) {
2925. 	    pline(not_enough_room);
2926. 	    return (0);
2927. 	}
2928. 	if (obj != uwep) {
2929. 	    if (!wield_tool(obj, "swing")) return(0);
2930. 	    else res = 1;
2931. 	}
2932.      /* assert(obj == uwep); */
2933. 
2934. 	/* Prompt for a location */
2935. 	pline(where_to_hit);
2936. 	cc.x = u.ux;
2937. 	cc.y = u.uy;
2938. 	if (getpos(&cc, TRUE, "the spot to hit") < 0)
2939. 	    return 0;	/* user pressed ESC */
2940. 
2941. 	/* Calculate range */
2942. 	typ = uwep_skill_type();
2943. 	if (typ == P_NONE || P_SKILL(typ) <= P_BASIC) max_range = 4;
2944. 	else if (P_SKILL(typ) == P_SKILLED) max_range = 5;
2945. 	else max_range = 8;
2946. 	if (distu(cc.x, cc.y) > max_range) {
2947. 	    pline("Too far!");
2948. 	    return (res);
2949. 	} else if (distu(cc.x, cc.y) < min_range) {
2950. 	    pline("Too close!");
2951. 	    return (res);
2952. 	} else if (!cansee(cc.x, cc.y) &&
2953. 		   ((mtmp = m_at(cc.x, cc.y)) == (struct monst *)0 ||
2954. 		    !canseemon(mtmp))) {
2955. 	    You(cant_see_spot);
2956. 	    return (res);
2957. 	} else if (!couldsee(cc.x, cc.y)) { /* Eyes of the Overworld */
2958. 	    You(cant_reach);
2959. 	    return res;
2960. 	} else if (!couldsee(cc.x, cc.y)) { /* Eyes of the Overworld */
2961. 	    You(cant_reach);
2962. 	    return res;
2963. 	}
2964. 
2965. 	/* Attack the monster there */
2966. 	if ((mtmp = m_at(cc.x, cc.y)) != (struct monst *)0) {
2967. 	    int oldhp = mtmp->mhp;
2968. 
2969. 	    bhitpos = cc;
2970. 	    check_caitiff(mtmp);
2971. 	    (void) thitmonst(mtmp, uwep, 1);
2972. 	    /* check the monster's HP because thitmonst() doesn't return
2973. 	     * an indication of whether it hit.  Not perfect (what if it's a
2974. 	     * non-silver weapon on a shade?)
2975. 	     */
2976. 	    if (mtmp->mhp < oldhp)
2977. 		u.uconduct.weaphit++;
2978. 	} else
2979. 	    /* Now you know that nothing is there... */
2980. 	    pline(nothing_happens);
2981. 	return (1);
2982. }
2983. #endif
2984. 
2985. STATIC_OVL int
2986. use_cream_pie(obj)
2987. struct obj *obj;
2988. {
2989. 	boolean wasblind = Blind;
2990. 	boolean wascreamed = u.ucreamed;
2991. 	boolean several = FALSE;
2992. 
2993. 	if (obj->quan > 1L) {
2994. 		several = TRUE;
2995. 		obj = splitobj(obj, 1L);
2996. 	}
2997. 	if (Hallucination)
2998. 		You("give yourself a facial.");
2999. 	else
3000. 		pline("You immerse your %s in %s%s.", body_part(FACE),
3001. 			several ? "one of " : "",
3002. 			several ? makeplural(the(xname(obj))) : the(xname(obj)));
3003. 	if(can_blnd((struct monst*)0, &youmonst, AT_WEAP, obj)) {
3004. 		int blindinc = rnd(25);
3005. 		u.ucreamed += blindinc;
3006. 		make_blinded(Blinded + (long)blindinc, FALSE);
3007. 		if (!Blind || (Blind && wasblind))
3008. 			pline("There's %ssticky goop all over your %s.",
3009. 				wascreamed ? "more " : "",
3010. 				body_part(FACE));
3011. 		else /* Blind  && !wasblind */
3012. 			You_cant("see through all the sticky goop on your %s.",
3013. 				body_part(FACE));
3014. 	}
3015. 	if (obj->unpaid) {
3016. 		verbalize("You used it, you bought it!");
3017. 		bill_dummy_object(obj);
3018. 	}
3019. 	obj_extract_self(obj);
3020. 	delobj(obj);
3021. 	return(0);
3022. }
3023. 
3024. STATIC_OVL int
3025. use_grapple (obj)
3026. 	struct obj *obj;
3027. {
3028. 	int res = 0, typ, max_range = 4, tohit;
3029. 	coord cc;
3030. 	struct monst *mtmp;
3031. 	struct obj *otmp;
3032. 
3033. 	/* Are you allowed to use the hook? */
3034. 	if (u.uswallow) {
3035. 	    pline(not_enough_room);
3036. 	    return (0);
3037. 	}
3038. 	if (obj != uwep) {
3039. 	    if (!wield_tool(obj, "cast")) return(0);
3040. 	    else res = 1;
3041. 	}
3042.      /* assert(obj == uwep); */
3043. 
3044. 	/* Prompt for a location */
3045. 	pline(where_to_hit);
3046. 	cc.x = u.ux;
3047. 	cc.y = u.uy;
3048. 	if (getpos(&cc, TRUE, "the spot to hit") < 0)
3049. 	    return 0;	/* user pressed ESC */
3050. 
3051. 	/* Calculate range */
3052. 	typ = uwep_skill_type();
3053. 	if (typ == P_NONE || P_SKILL(typ) <= P_BASIC) max_range = 4;
3054. 	else if (P_SKILL(typ) == P_SKILLED) max_range = 5;
3055. 	else max_range = 8;
3056. 	if (distu(cc.x, cc.y) > max_range) {
3057. 		pline("Too far!");
3058. 		return (res);
3059. 	} else if (!cansee(cc.x, cc.y)) {
3060. 		You(cant_see_spot);
3061. 		return (res);
3062. 	}
3063. 
3064. 	/* What do you want to hit? */
3065. 	tohit = rn2(5);
3066. 	if (typ != P_NONE && P_SKILL(typ) >= P_SKILLED) {
3067. 	    winid tmpwin = create_nhwindow(NHW_MENU);
3068. 	    anything any;
3069. 	    char buf[BUFSZ];
3070. 	    menu_item *selected;
3071. 
3072. 	    any.a_void = 0;	/* set all bits to zero */
3073. 	    any.a_int = 1;	/* use index+1 (cant use 0) as identifier */
3074. 	    start_menu(tmpwin);
3075. 	    any.a_int++;
3076. 	    Sprintf(buf, "an object on the %s", surface(cc.x, cc.y));
3077. 	    add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
3078. 			 buf, MENU_UNSELECTED);
3079. 	    any.a_int++;
3080. 	    add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
3081. 			"a monster", MENU_UNSELECTED);
3082. 	    any.a_int++;
3083. 	    Sprintf(buf, "the %s", surface(cc.x, cc.y));
3084. 	    add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
3085. 			 buf, MENU_UNSELECTED);
3086. 	    end_menu(tmpwin, "Aim for what?");
3087. 	    tohit = rn2(4);
3088. 	    if (select_menu(tmpwin, PICK_ONE, &selected) > 0 &&
3089. 			rn2(P_SKILL(typ) > P_SKILLED ? 20 : 2))
3090. 		tohit = selected[0].item.a_int - 1;
3091. 	    free((genericptr_t)selected);
3092. 	    destroy_nhwindow(tmpwin);
3093. 	}
3094. 
3095. 	/* What did you hit? */
3096. 	switch (tohit) {
3097. 	case 0:	/* Trap */
3098. 	    /* FIXME -- untrap needs to deal with non-adjacent traps */
3099. 	    break;
3100. 	case 1:	/* Object */
3101. 	    if ((otmp = level.objects[cc.x][cc.y]) != 0) {
3102. 		You("snag an object from the %s!", surface(cc.x, cc.y));
3103. 		(void) pickup_object(otmp, 1L, FALSE);
3104. 		/* If pickup fails, leave it alone */
3105. 		newsym(cc.x, cc.y);
3106. 		return (1);
3107. 	    }
3108. 	    break;
3109. 	case 2:	/* Monster */
3110. 	    if ((mtmp = m_at(cc.x, cc.y)) == (struct monst *)0) break;
3111. 	    if (verysmall(mtmp->data) && !rn2(4) &&
3112. 			enexto(&cc, u.ux, u.uy, (struct permonst *)0)) {
3113. 		You("pull in %s!", mon_nam(mtmp));
3114. 		mtmp->mundetected = 0;
3115. 		rloc_to(mtmp, cc.x, cc.y);
3116. 		return (1);
3117. 	    } else if ((!bigmonst(mtmp->data) && !strongmonst(mtmp->data)) ||
3118. 		       rn2(4)) {
3119. 		(void) thitmonst(mtmp, uwep, 1);
3120. 		return (1);
3121. 	    }
3122. 	    /* FALL THROUGH */
3123. 	case 3:	/* Surface */
3124. 	    if (IS_AIR(levl[cc.x][cc.y].typ) || is_pool(cc.x, cc.y))
3125. 		pline_The("hook slices through the %s.", surface(cc.x, cc.y));
3126. 	    else {
3127. 		You("are yanked toward the %s!", surface(cc.x, cc.y));
3128. 		hurtle(sgn(cc.x-u.ux), sgn(cc.y-u.uy), 1, FALSE);
3129. 		spoteffects(TRUE);
3130. 	    }
3131. 	    return (1);
3132. 	default:	/* Yourself (oops!) */
3133. 	    if (P_SKILL(typ) <= P_BASIC) {
3134. 		You("hook yourself!");
3135. 		losehp(rn1(10,10), "a grappling hook", KILLED_BY);
3136. 		return (1);
3137. 	    }
3138. 	    break;
3139. 	}
3140. 	pline(nothing_happens);
3141. 	return (1);
3142. }
3143. 
3144. 
3145. #define BY_OBJECT	((struct monst *)0)
3146. 
3147. /* return 1 if the wand is broken, hence some time elapsed */
3148. STATIC_OVL int
3149. do_break_wand(obj)
3150.     struct obj *obj;
3151. {
3152.     char confirm[QBUFSZ], the_wand[BUFSZ];
3153. 
3154.     Strcpy(the_wand, yname(obj));
3155.     Sprintf(confirm, "Are you really sure you want to break %s?",
3156. 	safe_qbuf("", sizeof("Are you really sure you want to break ?"),
3157. 				the_wand, ysimple_name(obj), "the wand"));
3158.     if (yn(confirm) == 'n' ) return 0;
3159. 
3160.     if (nohands(youmonst.data)) {
3161. 	You_cant("break %s without hands!", the_wand);
3162. 	return 0;
3163.     } else if (ACURR(A_STR) < 10) {
3164. 	You("don't have the strength to break %s!", the_wand);
3165. 	return 0;
3166.     }
3167.     pline("Raising %s high above your %s, you break it in two!",
3168. 	  the_wand, body_part(HEAD));
3169.     return wand_explode(obj, TRUE);
3170. }
3171. 
3172. /* This function takes care of the effects wands exploding, via
3173.  * user-specified 'applying' as well as wands exploding by accident
3174.  * during use (called by backfire() in zap.c)
3175.  *
3176.  * If the effect is directly recognisable as pertaining to a 
3177.  * specific wand, the wand should be makeknown()
3178.  * Otherwise, if there is an ambiguous or indirect but visible effect
3179.  * the wand should be allowed to be named by the user.
3180.  *
3181.  * If there is no obvious effect,  do nothing. (Should this be changed
3182.  * to letting the user call that type of wand?)
3183.  *
3184.  * hero_broke is nonzero if the user initiated the action that caused
3185.  * the wand to explode (zapping or applying).
3186.  */
3187. int
3188. wand_explode(obj, hero_broke)
3189.     struct obj *obj;
3190.     boolean hero_broke;
3191. {
3192.     static const char nothing_else_happens[] = "But nothing else happens...";
3193.     register int i, x, y;
3194.     register struct monst *mon;
3195.     int dmg, damage;
3196.     boolean affects_objects;
3197.     boolean shop_damage = FALSE;
3198.     int expltype = EXPL_MAGICAL;
3199.     char buf[BUFSZ];
3200. 
3201.     /* [ALI] Do this first so that wand is removed from bill. Otherwise,
3202.      * the freeinv() below also hides it from setpaid() which causes problems.
3203.      */
3204.     if (carried(obj) ? obj->unpaid :
3205. 	    !obj->no_charge && costly_spot(obj->ox, obj->oy)) {
3206. 	if (hero_broke)
3207. 	check_unpaid(obj);		/* Extra charge for use */
3208. 	bill_dummy_object(obj);
3209.     }
3210. 
3211.     current_wand = obj;		/* destroy_item might reset this */
3212.     freeinv(obj);		/* hide it from destroy_item instead... */
3213.     setnotworn(obj);		/* so we need to do this ourselves */
3214. 
3215.     if (obj->spe <= 0) {
3216. 	pline(nothing_else_happens);
3217. 	goto discard_broken_wand;
3218.     }
3219.     obj->ox = u.ux;
3220.     obj->oy = u.uy;
3221.     dmg = obj->spe * 4;
3222.     affects_objects = FALSE;
3223. 
3224.     switch (obj->otyp) {
3225.     case WAN_WISHING:
3226.     case WAN_NOTHING:
3227.     case WAN_LOCKING:
3228.     case WAN_PROBING:
3229.     case WAN_ENLIGHTENMENT:
3230.     case WAN_OPENING:
3231.     case WAN_SECRET_DOOR_DETECTION:
3232. 	pline(nothing_else_happens);
3233. 	goto discard_broken_wand;
3234.     case WAN_DEATH:
3235.     case WAN_LIGHTNING:
3236. 	dmg *= 4;
3237. 	goto wanexpl;
3238.     case WAN_COLD:
3239. 	expltype = EXPL_FROSTY;
3240. 	dmg *= 2;
3241.     case WAN_MAGIC_MISSILE:
3242.     wanexpl:
3243. 	explode(u.ux, u.uy, ZT_MAGIC_MISSILE, dmg, WAND_CLASS, expltype);
3244. 	makeknown(obj->otyp);	/* explode described the effect */
3245. 	goto discard_broken_wand;
3246. /*WAC for wands of fireball- no double damage
3247.  * As well, effect is the same as fire, so no makeknown
3248.  */
3249.     case WAN_FIRE:
3250. 	dmg *= 2;
3251.     case WAN_FIREBALL:
3252. 	expltype = EXPL_FIERY;
3253.         explode(u.ux, u.uy, ZT_FIRE, dmg, WAND_CLASS, expltype);
3254. 	if (obj->dknown && !objects[obj->otyp].oc_name_known &&
3255. 		!objects[obj->otyp].oc_uname)
3256.         docall(obj);
3257. 	goto discard_broken_wand;
3258.     case WAN_STRIKING:
3259. 	/* we want this before the explosion instead of at the very end */
3260. 	pline("A wall of force smashes down around you!");
3261. 	dmg = d(1 + obj->spe,6);	/* normally 2d12 */
3262.     case WAN_CANCELLATION:
3263.     case WAN_POLYMORPH:
3264.     case WAN_UNDEAD_TURNING:
3265.     case WAN_DRAINING:	/* KMH */
3266. 	affects_objects = TRUE;
3267. 	break;
3268.     case WAN_TELEPORTATION:
3269. 		/* WAC make tele trap if you broke a wand of teleport */
3270. 		/* But make sure the spot is valid! */
3271. 	    if ((obj->spe > 2) && rn2(obj->spe - 2) && !level.flags.noteleport &&
3272. 		    !u.uswallow && !On_stairs(u.ux, u.uy) && (!IS_FURNITURE(levl[u.ux][u.uy].typ) &&
3273. 		    !IS_ROCK(levl[u.ux][u.uy].typ) &&
3274. 		    !closed_door(u.ux, u.uy) && !t_at(u.ux, u.uy))) {
3275. 
3276. 			struct trap *ttmp;
3277. 
3278. 			ttmp = maketrap(u.ux, u.uy, TELEP_TRAP);
3279. 			if (ttmp) {
3280. 				ttmp->madeby_u = 1;
3281. 				newsym(u.ux, u.uy); /* if our hero happens to be invisible */
3282. 				if (*in_rooms(u.ux,u.uy,SHOPBASE)) {
3283. 					/* shopkeeper will remove it */
3284. 					add_damage(u.ux, u.uy, 0L);             
3285. 				}
3286. 			}
3287. 		}
3288. 	affects_objects = TRUE;
3289. 	break;
3290.     case WAN_CREATE_HORDE: /* More damage than Create monster */
3291. 	        dmg *= 2;
3292. 	        break;
3293.     case WAN_HEALING:
3294.     case WAN_EXTRA_HEALING:
3295. 		dmg = 0;
3296. 		break;
3297.     default:
3298. 	break;
3299.     }
3300. 
3301.     /* magical explosion and its visual effect occur before specific effects */
3302.     explode(obj->ox, obj->oy, ZT_MAGIC_MISSILE, dmg ? rnd(dmg) : 0, WAND_CLASS,
3303. 	    EXPL_MAGICAL);
3304. 
3305.     /* this makes it hit us last, so that we can see the action first */
3306.     for (i = 0; i <= 8; i++) {
3307. 	bhitpos.x = x = obj->ox + xdir[i];
3308. 	bhitpos.y = y = obj->oy + ydir[i];
3309. 	if (!isok(x,y)) continue;
3310. 
3311. 	if (obj->otyp == WAN_DIGGING) {
3312. 	    if(dig_check(BY_OBJECT, FALSE, x, y)) {
3313. 		if (IS_WALL(levl[x][y].typ) || IS_DOOR(levl[x][y].typ)) {
3314. 		    /* normally, pits and holes don't anger guards, but they
3315. 		     * do if it's a wall or door that's being dug */
3316. 		    watch_dig((struct monst *)0, x, y, TRUE);
3317. 		    if (*in_rooms(x,y,SHOPBASE)) shop_damage = TRUE;
3318. 		}		    
3319. 		digactualhole(x, y, BY_OBJECT,
3320. 			      (rn2(obj->spe) < 3 || !Can_dig_down(&u.uz)) ?
3321. 			       PIT : HOLE);
3322. 	    }
3323. 	    continue;
3324. /* WAC catch Create Horde wands too */
3325. /* MAR make the monsters around you */
3326. 	} else if(obj->otyp == WAN_CREATE_MONSTER
3327.                 || obj->otyp == WAN_CREATE_HORDE) {
3328. 	    /* u.ux,u.uy creates it near you--x,y might create it in rock */
3329. 	    (void) makemon((struct permonst *)0, u.ux, u.uy, NO_MM_FLAGS);
3330. 	    continue;
3331. 	} else {
3332. 	    if (x == u.ux && y == u.uy) {
3333. 		/* teleport objects first to avoid race with tele control and
3334. 		   autopickup.  Other wand/object effects handled after
3335. 		   possible wand damage is assessed */
3336. 		if (obj->otyp == WAN_TELEPORTATION &&
3337. 		    affects_objects && level.objects[x][y]) {
3338. 		    (void) bhitpile(obj, bhito, x, y);
3339. 		    if (flags.botl) bot();		/* potion effects */
3340. 			/* makeknown is handled in zapyourself */
3341. 		}
3342. 		damage = zapyourself(obj, FALSE);
3343. 		if (damage) {
3344. 		    if (hero_broke) {
3345. 		    Sprintf(buf, "killed %sself by breaking a wand", uhim());
3346. 		    losehp(damage, buf, NO_KILLER_PREFIX);
3347. 		    } else
3348. 			losehp(damage, "exploding wand", KILLED_BY_AN);
3349. 		}
3350. 		if (flags.botl) bot();		/* blindness */
3351. 	    } else if ((mon = m_at(x, y)) != 0 && !DEADMONSTER(mon)) {
3352. 		(void) bhitm(mon, obj);
3353. 	     /* if (flags.botl) bot(); */
3354. 	    }
3355. 	    if (affects_objects && level.objects[x][y]) {
3356. 		(void) bhitpile(obj, bhito, x, y);
3357. 		if (flags.botl) bot();		/* potion effects */
3358. 	    }
3359. 	}
3360.     }
3361. 
3362.     /* Note: if player fell thru, this call is a no-op.
3363.        Damage is handled in digactualhole in that case */
3364.     if (shop_damage) pay_for_damage("dig into", FALSE);
3365. 
3366.     if (obj->otyp == WAN_LIGHT)
3367. 	litroom(TRUE, obj);	/* only needs to be done once */
3368. 
3369.  discard_broken_wand:
3370.     obj = current_wand;		/* [see dozap() and destroy_item()] */
3371.     current_wand = 0;
3372.     if (obj)
3373. 	delobj(obj);
3374.     nomul(0);
3375.     return 1;
3376. }
3377. 
3378. STATIC_OVL boolean
3379. uhave_graystone()
3380. {
3381. 	register struct obj *otmp;
3382. 
3383. 	for(otmp = invent; otmp; otmp = otmp->nobj)
3384. 		if(is_graystone(otmp))
3385. 			return TRUE;
3386. 	return FALSE;
3387. }
3388. 
3389. STATIC_OVL void
3390. add_class(cl, class)
3391. char *cl;
3392. char class;
3393. {
3394. 	char tmp[2];
3395. 	tmp[0] = class;
3396. 	tmp[1] = '\0';
3397. 	Strcat(cl, tmp);
3398. }
3399. 
3400. int
3401. doapply()
3402. {
3403. 	struct obj *obj;
3404. 	register int res = 1;
3405. 	register boolean can_use = FALSE;
3406. 	char class_list[MAXOCLASSES+2];
3407. 
3408. 	if(check_capacity((char *)0)) return (0);
3409. 
3410. 	if (carrying(POT_OIL) || uhave_graystone())
3411. 		Strcpy(class_list, tools_too);
3412. 	else
3413. 		Strcpy(class_list, tools);
3414. 	if (carrying(CREAM_PIE) || carrying(EUCALYPTUS_LEAF))
3415. 		add_class(class_list, FOOD_CLASS);
3416. 
3417. 	obj = getobj(class_list, "use or apply");
3418. 	if(!obj) return 0;
3419. 
3420. 	if (obj->oartifact && !touch_artifact(obj, &youmonst))
3421. 	    return 1;	/* evading your grasp costs a turn; just be
3422. 			   grateful that you don't drop it as well */
3423. 
3424. 	if (obj->oclass == WAND_CLASS)
3425. 	    return do_break_wand(obj);
3426. 
3427. 	switch(obj->otyp){
3428. 	case BLINDFOLD:
3429. 	case LENSES:
3430. 		if (obj == ublindf) {
3431. 		    if (!cursed(obj)) Blindf_off(obj);
3432. 		} else if (!ublindf)
3433. 		    Blindf_on(obj);
3434. 		else You("are already %s.",
3435. 			ublindf->otyp == TOWEL ?     "covered by a towel" :
3436. 			ublindf->otyp == BLINDFOLD ? "wearing a blindfold" :
3437. 						     "wearing lenses");
3438. 		break;
3439. 	case CREAM_PIE:
3440. 		res = use_cream_pie(obj);
3441. 		break;
3442. 	case BULLWHIP:
3443. 		res = use_whip(obj);
3444. 		break;
3445. 	case GRAPPLING_HOOK:
3446. 		res = use_grapple(obj);
3447. 		break;
3448. 	case LARGE_BOX:
3449. 	case CHEST:
3450. 	case ICE_BOX:
3451. 	case SACK:
3452. 	case BAG_OF_HOLDING:
3453. 	case OILSKIN_SACK:
3454. 		res = use_container(&obj, 1);
3455. 		break;
3456. 	case BAG_OF_TRICKS:
3457. 		bagotricks(obj);
3458. 		break;
3459. 	case CAN_OF_GREASE:
3460. 		use_grease(obj);
3461. 		break;
3462. #ifdef TOURIST
3463. 	case CREDIT_CARD:
3464. #endif
3465. 	case LOCK_PICK:
3466. 	case SKELETON_KEY:
3467. 		(void) pick_lock(&obj);
3468. 		break;
3469. 	case PICK_AXE:
3470. 	case DWARVISH_MATTOCK: /* KMH, balance patch -- the mattock is a pick, too */
3471. 		res = use_pick_axe(obj);
3472. 		break;
3473. 	case FISHING_POLE:
3474. 		res = use_pole(obj);
3475. 		break;
3476. 	case TINNING_KIT:
3477. 		use_tinning_kit(obj);
3478. 		break;
3479. 	case LEASH:
3480. 		use_leash(obj);
3481. 		break;
3482. #ifdef STEED
3483. 	case SADDLE:
3484. 		res = use_saddle(obj);
3485. 		break;
3486. #endif
3487. 	case MAGIC_WHISTLE:
3488. 		use_magic_whistle(obj);
3489. 		break;
3490. 	case TIN_WHISTLE:
3491. 		use_whistle(obj);
3492. 		break;
3493. 	case EUCALYPTUS_LEAF:
3494. 		/* MRKR: Every Australian knows that a gum leaf makes an */
3495. 		/*	 excellent whistle, especially if your pet is a  */
3496. 		/*	 tame kangaroo named Skippy.			 */
3497. 		if (obj->blessed) {
3498. 		    use_magic_whistle(obj);
3499. 		    /* sometimes the blessing will be worn off */
3500. 		    if (!rn2(49)) {
3501. 			if (!Blind) {
3502. 			    char buf[BUFSZ];
3503. 
3504. 			    pline("%s %s %s.", Shk_Your(buf, obj),
3505. 				  aobjnam(obj, "glow"), hcolor("brown"));
3506. 			    obj->bknown = 1;
3507. 			}
3508. 			unbless(obj);
3509. 		    }
3510. 		} else {
3511. 		    use_whistle(obj);
3512. 		}
3513. 		break;
3514. 	case STETHOSCOPE:
3515. 		res = use_stethoscope(obj);
3516. 		break;
3517. 	case MIRROR:
3518. 		res = use_mirror(obj);
3519. 		break;
3520. # ifdef P_SPOON
3521. 	case SPOON:
3522. 		pline("It's a finely crafted antique spoon; what do you want to do with it?");
3523. 		break;
3524. # endif /* P_SPOON */
3525. 	case BELL:
3526. 	case BELL_OF_OPENING:
3527. 		use_bell(&obj);
3528. 		break;
3529. 	case CANDELABRUM_OF_INVOCATION:
3530. 		use_candelabrum(obj);
3531. 		break;
3532. 	case WAX_CANDLE:
3533. /* STEPHEN WHITE'S NEW CODE */           
3534. 	case MAGIC_CANDLE:
3535. 	case TALLOW_CANDLE:
3536. 		use_candle(&obj);
3537. 		break;
3538. #ifdef LIGHTSABERS
3539. 	case GREEN_LIGHTSABER:
3540. #ifdef D_SABER
3541.   	case BLUE_LIGHTSABER:
3542. #endif
3543. 	case RED_LIGHTSABER:
3544. 	case RED_DOUBLE_LIGHTSABER:
3545. 		if (uwep != obj && !wield_tool(obj, (const char *)0)) break;
3546. 		/* Fall through - activate via use_lamp */
3547. #endif
3548. 	case OIL_LAMP:
3549. 	case MAGIC_LAMP:
3550. 	case BRASS_LANTERN:
3551. 		use_lamp(obj);
3552. 		break;
3553. 	case TORCH:
3554. 	        res = use_torch(obj);
3555. 		break;
3556. 	case POT_OIL:
3557. 		light_cocktail(obj);
3558. 		break;
3559. #ifdef TOURIST
3560. 	case EXPENSIVE_CAMERA:
3561. 		res = use_camera(obj);
3562. 		break;
3563. #endif
3564. 	case TOWEL:
3565. 		res = use_towel(obj);
3566. 		break;
3567. 	case CRYSTAL_BALL:
3568. 		use_crystal_ball(obj);
3569. 		break;
3570. /* STEPHEN WHITE'S NEW CODE */
3571. /* KMH, balance patch -- source of abuse */
3572. #if 0
3573. 	case ORB_OF_ENCHANTMENT:
3574. 	    if(obj->spe > 0) {
3575. 		
3576. 		check_unpaid(obj);
3577. 		if(uwep && (uwep->oclass == WEAPON_CLASS ||
3578. 			    uwep->otyp == PICK_AXE ||
3579. 			    uwep->otyp == UNICORN_HORN)) {
3580. 		if (uwep->spe < 5) {
3581. 		if (obj->blessed) {
3582. 				if (!Blind) pline("Your %s glows silver.",xname(uwep));
3583. 				uwep->spe += rnd(2);
3584. 		} else if (obj->cursed) {                               
3585. 				if (!Blind) pline("Your %s glows black.",xname(uwep));
3586. 				uwep->spe -= rnd(2);
3587. 		} else {
3588. 				if (rn2(3)) {
3589. 					if (!Blind) pline("Your %s glows bright for a moment." ,xname(uwep));
3590. 					uwep->spe += 1;
3591. 				} else {
3592. 					if (!Blind) pline("Your %s glows dark for a moment." ,xname(uwep));
3593. 					uwep->spe -= 1;
3594. 				}
3595. 		}
3596. 		} else pline("Nothing seems to happen.");                
3597. 		
3598. 		if (uwep->spe > 5) uwep->spe = 5;
3599. 				
3600. 		} else pline("The orb glows for a moment, then fades.");
3601. 		consume_obj_charge(obj, FALSE);
3602. 	    
3603. 	    } else pline("This orb is burnt out.");
3604. 	    break;
3605. 	case ORB_OF_CHARGING:
3606. 		if(obj->spe > 0) {
3607. 			register struct obj *otmp;
3608. 			makeknown(ORB_OF_CHARGING);
3609. 			consume_obj_charge(obj, TRUE);
3610. 			otmp = getobj(all_count, "charge");
3611. 			if (!otmp) break;
3612. 			recharge(otmp, obj->cursed ? -1 : (obj->blessed ? 1 : 0));
3613. 		} else pline("This orb is burnt out.");
3614. 		break;
3615. 	case ORB_OF_DESTRUCTION:
3616. 		useup(obj);
3617. 		pline("As you activate the orb, it explodes!");
3618. 		explode(u.ux, u.uy, ZT_SPELL(ZT_MAGIC_MISSILE), d(12,6), WAND_CLASS);
3619. 		check_unpaid(obj);
3620. 		break;
3621. #endif
3622. 	case MAGIC_MARKER:
3623. 		res = dowrite(obj);
3624. 		break;
3625. 	case TIN_OPENER:
3626. 		if(!carrying(TIN)) {
3627. 			You("have no tin to open.");
3628. 			goto xit;
3629. 		}
3630. 		You("cannot open a tin without eating or discarding its contents.");
3631. 		if(flags.verbose)
3632. 			pline("In order to eat, use the 'e' command.");
3633. 		if(obj != uwep)
3634.     pline("Opening the tin will be much easier if you wield the tin opener.");
3635. 		goto xit;
3636. 
3637. 	case FIGURINE:
3638. 		use_figurine(&obj);
3639. 		break;
3640. 	case UNICORN_HORN:
3641. 		use_unicorn_horn(obj);
3642. 		break;
3643. 	case WOODEN_FLUTE:
3644. 	case MAGIC_FLUTE:
3645. 	case TOOLED_HORN:
3646. 	case FROST_HORN:
3647. 	case FIRE_HORN:
3648. 	case WOODEN_HARP:
3649. 	case MAGIC_HARP:
3650. 	case BUGLE:
3651. 	case LEATHER_DRUM:
3652. 	case DRUM_OF_EARTHQUAKE:
3653. 	/* KMH, balance patch -- removed
3654. 	case PAN_PIPE_OF_SUMMONING:                
3655. 	case PAN_PIPE_OF_THE_SEWERS:
3656. 	case PAN_PIPE:*/
3657. 		res = do_play_instrument(obj);
3658. 		break;
3659. 	case MEDICAL_KIT:        
3660. 		if (Role_if(PM_HEALER)) can_use = TRUE;
3661. 		else if ((Role_if(PM_PRIEST) || Role_if(PM_MONK) ||
3662. 			Role_if(PM_UNDEAD_SLAYER) || Role_if(PM_SAMURAI)) &&
3663. 			!rn2(2)) can_use = TRUE;
3664. 		else if(!rn2(4)) can_use = TRUE;
3665. 
3666. 		if (obj->cursed && rn2(3)) can_use = FALSE;
3667. 		if (obj->blessed && rn2(3)) can_use = TRUE;  
3668. 
3669. 		makeknown(MEDICAL_KIT);
3670. 		if (obj->cobj) {
3671. 		    struct obj *otmp;
3672. 		    for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
3673. 			if (otmp->otyp == PILL)
3674. 			    break;
3675. 		    if (!otmp)
3676. 			You_cant("find any more pills in %s.", yname(obj));
3677. 		    else if (!is_edible(otmp))
3678. 			You("find, but cannot eat, a white pill in %s.",
3679. 			  yname(obj));
3680. 		    else {
3681. 			check_unpaid(obj);
3682. 			if (otmp->quan > 1L)
3683. 			    otmp->quan--;
3684. 			else {
3685. 			    obj_extract_self(otmp);
3686. 			    obfree(otmp, (struct obj *)0);
3687. 			}
3688. 			/*
3689. 			 * Note that while white and pink pills share the
3690. 			 * same otyp value, they are quite different.
3691. 			 */
3692. 			You("take a white pill from %s and swallow it.",
3693. 				yname(obj));
3694. 			if (can_use) {
3695. 			    if (Sick) make_sick(0L, (char *) 0,TRUE ,SICK_ALL);
3696. 			    else if (Blinded > (long)(u.ucreamed+1))
3697. 				make_blinded(u.ucreamed ?
3698. 					(long)(u.ucreamed+1) : 0L, TRUE);
3699. 			    else if (HHallucination)
3700. 				make_hallucinated(0L, TRUE, 0L);
3701. 			    else if (Vomiting) make_vomiting(0L, TRUE);
3702. 			    else if (HConfusion) make_confused(0L, TRUE);
3703. 			    else if (HStun) make_stunned(0L, TRUE);
3704. 			    else if (u.uhp < u.uhpmax) {
3705. 				u.uhp += rn1(10,10);
3706. 				if (u.uhp > u.uhpmax) u.uhp = u.uhpmax;
3707. 				You_feel("better.");
3708. 				flags.botl = TRUE;
3709. 			    } else pline(nothing_happens);
3710. 			} else if (!rn2(3))
3711. 			    pline("Nothing seems to happen.");
3712. 			else if (!Sick)
3713. 			    make_sick(rn1(10,10), "bad pill", TRUE,
3714. 			      SICK_VOMITABLE);
3715. 			else {
3716. 			    You("seem to have made your condition worse!");
3717. 			    losehp(rn1(10,10), "a drug overdose", KILLED_BY);
3718. 			}
3719. 		    }
3720. 		} else You("seem to be out of medical supplies");
3721. 		break;
3722. 	case HORN_OF_PLENTY:	/* not a musical instrument */
3723. 		if (obj->spe > 0) {
3724. 		    struct obj *otmp;
3725. 		    const char *what;
3726. 
3727. 		    consume_obj_charge(obj, TRUE);
3728. 		    if (!rn2(13)) {
3729. 			otmp = mkobj(POTION_CLASS, FALSE);
3730. 			/* KMH, balance patch -- rewritten */
3731. 			while ((otmp->otyp == POT_SICKNESS) ||
3732. 					objects[otmp->otyp].oc_magic)
3733. 			    otmp->otyp = rnd_class(POT_BOOZE, POT_WATER);
3734. 			what = "A potion";
3735. 		    } else {
3736. 			otmp = mkobj(FOOD_CLASS, FALSE);
3737. 			if (otmp->otyp == FOOD_RATION && !rn2(7))
3738. 			    otmp->otyp = LUMP_OF_ROYAL_JELLY;
3739. 			what = "Some food";
3740. 		    }
3741. 		    pline("%s spills out.", what);
3742. 		    otmp->blessed = obj->blessed;
3743. 		    otmp->cursed = obj->cursed;
3744. 		    otmp->owt = weight(otmp);
3745. 		    otmp = hold_another_object(otmp, u.uswallow ?
3746. 				       "Oops!  %s out of your reach!" :
3747. 					(Is_airlevel(&u.uz) ||
3748. 					 Is_waterlevel(&u.uz) ||
3749. 					 levl[u.ux][u.uy].typ < IRONBARS ||
3750. 					 levl[u.ux][u.uy].typ >= ICE) ?
3751. 					       "Oops!  %s away from you!" :
3752. 					       "Oops!  %s to the floor!",
3753. 					       The(aobjnam(otmp, "slip")),
3754. 					       (const char *)0);
3755. 		    makeknown(HORN_OF_PLENTY);
3756. 		} else
3757. 		    pline(nothing_happens);
3758. 		break;
3759. 	case LAND_MINE:
3760. 	case BEARTRAP:
3761. 		use_trap(obj);
3762. 		break;
3763. 	case FLINT:
3764. 	case LUCKSTONE:
3765. 	case LOADSTONE:
3766. 	case TOUCHSTONE:
3767. 	case HEALTHSTONE:
3768. 	case WHETSTONE:
3769. 		use_stone(obj);
3770. 		break;
3771. #ifdef FIREARMS
3772. 	case ASSAULT_RIFLE:
3773. 		/* Switch between WP_MODE_SINGLE, WP_MODE_BURST and WP_MODE_AUTO */
3774. 
3775. 		if (obj->altmode == WP_MODE_AUTO) {
3776. 			obj->altmode = WP_MODE_BURST;
3777. 		} else if (obj->altmode == WP_MODE_BURST) {
3778. 			obj->altmode = WP_MODE_SINGLE;
3779. 		} else {
3780. 			obj->altmode = WP_MODE_AUTO;
3781. 		}
3782. 		
3783. 		You("switch %s to %s mode.", yname(obj), 
3784. 			((obj->altmode == WP_MODE_SINGLE) ? "single shot" : 
3785. 			 ((obj->altmode == WP_MODE_BURST) ? "burst" :
3786. 			  "full automatic")));
3787. 		break;	
3788. 	case AUTO_SHOTGUN:
3789. 	case SUBMACHINE_GUN:		
3790. 		if (obj->altmode == WP_MODE_AUTO) obj-> altmode = WP_MODE_SINGLE;
3791. 		else obj->altmode = WP_MODE_AUTO;
3792. 		You("switch %s to %s mode.", yname(obj), 
3793. 			(obj->altmode ? "semi-automatic" : "full automatic"));
3794. 		break;
3795. 	case FRAG_GRENADE:
3796. 	case GAS_GRENADE:
3797. 		if (!obj->oarmed) {
3798. 			You("arm %s.", yname(obj));
3799. 			arm_bomb(obj, TRUE);
3800. 		} else pline("It's already armed!");
3801. 		break;
3802. 	case STICK_OF_DYNAMITE:
3803. 		light_cocktail(obj);
3804. 		break;
3805. #endif
3806. 	default:
3807. 		/* KMH, balance patch -- polearms can strike at a distance */
3808. 		if (is_pole(obj)) {
3809. 			res = use_pole(obj);
3810. 			break;
3811. 		} else if (is_pick(obj) || is_axe(obj)) {
3812. 			res = use_pick_axe(obj);
3813. 			break;
3814. 		}
3815. 		pline("Sorry, I don't know how to use that.");
3816. 	xit:
3817. 		nomul(0);
3818. 		return 0;
3819. 	}
3820. 	if (res && obj && obj->oartifact) arti_speak(obj);
3821. 	nomul(0);
3822. 	return res;
3823. }
3824. 
3825. /* Keep track of unfixable troubles for purposes of messages saying you feel
3826.  * great.
3827.  */
3828. int
3829. unfixable_trouble_count(is_horn)
3830. 	boolean is_horn;
3831. {
3832. 	int unfixable_trbl = 0;
3833. 
3834. 	if (Stoned) unfixable_trbl++;
3835. 	if (Strangled) unfixable_trbl++;
3836. 	if (Wounded_legs
3837. #ifdef STEED
3838. 		    && !u.usteed
3839. #endif
3840. 				) unfixable_trbl++;
3841. 	if (Slimed) unfixable_trbl++;
3842. 	/* lycanthropy is not desirable, but it doesn't actually make you feel
3843. 	   bad */
3844. 
3845. 	/* we'll assume that intrinsic stunning from being a bat/stalker
3846. 	   doesn't make you feel bad */
3847. 	if (!is_horn) {
3848. 	    if (Confusion) unfixable_trbl++;
3849. 	    if (Sick) unfixable_trbl++;
3850. 	    if (HHallucination) unfixable_trbl++;
3851. 	    if (Vomiting) unfixable_trbl++;
3852. 	    if (HStun) unfixable_trbl++;
3853. 	}
3854. 	return unfixable_trbl;
3855. }
3856. 
3857. #endif /* OVLB */
3858. 
3859. /*apply.c*/
Advertisement