Wikihack
Advertisement

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

Top of file[]

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.    
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
5.    #include "hack.h"
6.    #include "edog.h"
7.    
8.    #ifdef OVLB
9.    
10.   static const char tools[] = { TOOL_CLASS, WEAPON_CLASS, WAND_CLASS, 0 };
11.   static const char tools_too[] = { ALL_CLASSES, TOOL_CLASS, POTION_CLASS,
12.   				  WEAPON_CLASS, WAND_CLASS, GEM_CLASS, 0 };
13.   
14.   #ifdef TOURIST
15.   STATIC_DCL int FDECL(use_camera, (struct obj *));
16.   #endif
17.   STATIC_DCL int FDECL(use_towel, (struct obj *));
18.   STATIC_DCL boolean FDECL(its_dead, (int,int,int *));
19.   STATIC_DCL int FDECL(use_stethoscope, (struct obj *));
20.   STATIC_DCL void FDECL(use_whistle, (struct obj *));
21.   STATIC_DCL void FDECL(use_magic_whistle, (struct obj *));
22.   STATIC_DCL void FDECL(use_leash, (struct obj *));
23.   STATIC_DCL int FDECL(use_mirror, (struct obj *));
24.   STATIC_DCL void FDECL(use_bell, (struct obj **));
25.   STATIC_DCL void FDECL(use_candelabrum, (struct obj *));
26.   STATIC_DCL void FDECL(use_candle, (struct obj **));
27.   STATIC_DCL void FDECL(use_lamp, (struct obj *));
28.   STATIC_DCL void FDECL(light_cocktail, (struct obj *));
29.   STATIC_DCL void FDECL(use_tinning_kit, (struct obj *));
30.   STATIC_DCL void FDECL(use_figurine, (struct obj **));
31.   STATIC_DCL void FDECL(use_grease, (struct obj *));
32.   STATIC_DCL void FDECL(use_trap, (struct obj *));
33.   STATIC_DCL void FDECL(use_stone, (struct obj *));
34.   STATIC_PTR int NDECL(set_trap);		/* occupation callback */
35.   STATIC_DCL int FDECL(use_whip, (struct obj *));
36.   STATIC_DCL int FDECL(use_pole, (struct obj *));
37.   STATIC_DCL int FDECL(use_cream_pie, (struct obj *));
38.   STATIC_DCL int FDECL(use_grapple, (struct obj *));
39.   STATIC_DCL int FDECL(do_break_wand, (struct obj *));
40.   STATIC_DCL boolean FDECL(figurine_location_checks,
41.   				(struct obj *, coord *, BOOLEAN_P));
42.   STATIC_DCL boolean NDECL(uhave_graystone);
43.   STATIC_DCL void FDECL(add_class, (char *, CHAR_P));
44.   
45.   #ifdef	AMIGA
46.   void FDECL( amii_speaker, ( struct obj *, char *, int ) );
47.   #endif
48.   

use_camera[]

49.   static const char no_elbow_room[] = "don't have enough elbow-room to maneuver.";
50.   
51.   #ifdef TOURIST
52.   STATIC_OVL int
53.   use_camera(obj)
54.   	struct obj *obj;
55.   {
56.   	register struct monst *mtmp;
57.   
58.   	if(Underwater) {
59.   		pline("Using your camera underwater would void the warranty.");
60.   		return(0);
61.   	}
62.   	if(!getdir((char *)0)) return(0);
63.   
64.   	if (obj->spe <= 0) {
65.   		pline(nothing_happens);
66.   		return (1);
67.   	}
68.   	consume_obj_charge(obj, TRUE);
69.   
70.   	if (obj->cursed && !rn2(2)) {
71.   		(void) zapyourself(obj, TRUE);
72.   	} else if (u.uswallow) {
73.   		You("take a picture of %s %s.", s_suffix(mon_nam(u.ustuck)),
74.   		    mbodypart(u.ustuck, STOMACH));
75.   	} else if (u.dz) {
76.   		You("take a picture of the %s.",
77.   			(u.dz > 0) ? surface(u.ux,u.uy) : ceiling(u.ux,u.uy));
78.   	} else if (!u.dx && !u.dy) {
79.   		(void) zapyourself(obj, TRUE);
80.   	} else if ((mtmp = bhit(u.dx, u.dy, COLNO, FLASHED_LIGHT,
81.   				(int FDECL((*),(MONST_P,OBJ_P)))0,
82.   				(int FDECL((*),(OBJ_P,OBJ_P)))0,
83.   				obj)) != 0) {
84.   		obj->ox = u.ux,  obj->oy = u.uy;
85.   		(void) flash_hits_mon(mtmp, obj);
86.   	}
87.   	return 1;
88.   }
89.   #endif
90.   

use_towel[]

91.   STATIC_OVL int
92.   use_towel(obj)
93.   	struct obj *obj;
94.   {
95.   	if(!freehand()) {
96.   		You("have no free %s!", body_part(HAND));
97.   		return 0;
98.   	} else if (obj->owornmask) {
99.   		You("cannot use it while you're wearing it!");
100.  		return 0;
101.  	} else if (obj->cursed) {
102.  		long old;
103.  		switch (rn2(3)) {
104.  		case 2:
105.  		    old = Glib;
106.  		    Glib += rn1(10, 3);
107.  		    Your("%s %s!", makeplural(body_part(HAND)),
108.  			(old ? "are filthier than ever" : "get slimy"));
109.  		    return 1;
110.  		case 1:
111.  		    if (!ublindf) {
112.  			old = u.ucreamed;
113.  			u.ucreamed += rn1(10, 3);
114.  			pline("Yecch! Your %s %s gunk on it!", body_part(FACE),
115.  			      (old ? "has more" : "now has"));
116.  			make_blinded(Blinded + (long)u.ucreamed - old, TRUE);
117.  		    } else {
118.  			const char *what = (ublindf->otyp == LENSES) ?
119.  					    "lenses" : "blindfold";
120.  			if (ublindf->cursed) {
121.  			    You("push your %s %s.", what,
122.  				rn2(2) ? "cock-eyed" : "crooked");
123.  			} else {
124.  			    struct obj *saved_ublindf = ublindf;
125.  			    You("push your %s off.", what);
126.  			    Blindf_off(ublindf);
127.  			    dropx(saved_ublindf);
128.  			}
129.  		    }
130.  		    return 1;
131.  		case 0:
132.  		    break;
133.  		}
134.  	}
135.  
136.  	if (Glib) {
137.  		Glib = 0;
138.  		You("wipe off your %s.", makeplural(body_part(HAND)));
139.  		return 1;
140.  	} else if(u.ucreamed) {
141.  		Blinded -= u.ucreamed;
142.  		u.ucreamed = 0;
143.  
144.  		if (!Blinded) {
145.  			pline("You've got the glop off.");
146.  			Blinded = 1;
147.  			make_blinded(0L,TRUE);
148.  		} else {
149.  			Your("%s feels clean now.", body_part(FACE));
150.  		}
151.  		return 1;
152.  	}
153.  
154.  	Your("%s and %s are already clean.",
155.  		body_part(FACE), makeplural(body_part(HAND)));
156.  
157.  	return 0;
158.  }
159.  

its_dead[]

160.  /* maybe give a stethoscope message based on floor objects */
161.  STATIC_OVL boolean
162.  its_dead(rx, ry, resp)
163.  int rx, ry, *resp;
164.  {
165.  	struct obj *otmp;
166.  	struct trap *ttmp;
167.  
168.  	if (!can_reach_floor()) return FALSE;
169.  
170.  	/* additional stethoscope messages from jyoung@apanix.apana.org.au */
171.  	if (Hallucination && sobj_at(CORPSE, rx, ry)) {
172.  	    /* (a corpse doesn't retain the monster's sex,
173.  	       so we're forced to use generic pronoun here) */
174.  	    You_hear("a voice say, \"It's dead, Jim.\"");
175.  	    *resp = 1;
176.  	    return TRUE;
177.  	} else if (Role_if(PM_HEALER) && ((otmp = sobj_at(CORPSE, rx, ry)) != 0 ||
178.  				    (otmp = sobj_at(STATUE, rx, ry)) != 0)) {
179.  	    /* possibly should check uppermost {corpse,statue} in the pile
180.  	       if both types are present, but it's not worth the effort */
181.  	    if (vobj_at(rx, ry)->otyp == STATUE) otmp = vobj_at(rx, ry);
182.  	    if (otmp->otyp == CORPSE) {
183.  		You("determine that %s unfortunate being is dead.",
184.  		    (rx == u.ux && ry == u.uy) ? "this" : "that");
185.  	    } else {
186.  		ttmp = t_at(rx, ry);
187.  		pline("%s appears to be in %s health for a statue.",
188.  		      The(mons[otmp->corpsenm].mname),
189.  		      (ttmp && ttmp->ttyp == STATUE_TRAP) ?
190.  			"extraordinary" : "excellent");
191.  	    }
192.  	    return TRUE;
193.  	}
194.  	return FALSE;
195.  }
196.  

use_stethoscope[]

197.  static const char hollow_str[] = "a hollow sound.  This must be a secret %s!";
198.  
199.  /* Strictly speaking it makes no sense for usage of a stethoscope to
200.     not take any time; however, unless it did, the stethoscope would be
201.     almost useless.  As a compromise, one use per turn is free, another
202.     uses up the turn; this makes curse status have a tangible effect. */
203.  STATIC_OVL int
204.  use_stethoscope(obj)
205.  	register struct obj *obj;
206.  {
207.  	static long last_used_move = -1;
208.  	static short last_used_movement = 0;
209.  	struct monst *mtmp;
210.  	struct rm *lev;
211.  	int rx, ry, res;
212.  	boolean interference = (u.uswallow && is_whirly(u.ustuck->data) &&
213.  				!rn2(Role_if(PM_HEALER) ? 10 : 3));
214.  
215.  	if (nohands(youmonst.data)) {	/* should also check for no ears and/or deaf */
216.  		You("have no hands!");	/* not `body_part(HAND)' */
217.  		return 0;
218.  	} else if (!freehand()) {
219.  		You("have no free %s.", body_part(HAND));
220.  		return 0;
221.  	}
222.  	if (!getdir((char *)0)) return 0;
223.  
224.  	res = (moves == last_used_move) &&
225.  	      (youmonst.movement == last_used_movement);
226.  	last_used_move = moves;
227.  	last_used_movement = youmonst.movement;
228.  
229.  #ifdef STEED
230.  	if (u.usteed && u.dz > 0) {
231.  		if (interference) {
232.  			pline("%s interferes.", Monnam(u.ustuck));
233.  			mstatusline(u.ustuck);
234.  		} else
235.  			mstatusline(u.usteed);
236.  		return res;
237.  	} else
238.  #endif
239.  	if (u.uswallow && (u.dx || u.dy || u.dz)) {
240.  		mstatusline(u.ustuck);
241.  		return res;
242.  	} else if (u.uswallow && interference) {
243.  		pline("%s interferes.", Monnam(u.ustuck));
244.  		mstatusline(u.ustuck);
245.  		return res;
246.  	} else if (u.dz) {
247.  		if (Underwater)
248.  		    You_hear("faint splashing.");
249.  		else if (u.dz < 0 || !can_reach_floor())
250.  		    You_cant("reach the %s.",
251.  			(u.dz > 0) ? surface(u.ux,u.uy) : ceiling(u.ux,u.uy));
252.  		else if (its_dead(u.ux, u.uy, &res))
253.  		    ;	/* message already given */
254.  		else if (Is_stronghold(&u.uz))
255.  		    You_hear("the crackling of hellfire.");
256.  		else
257.  		    pline_The("%s seems healthy enough.", surface(u.ux,u.uy));
258.  		return res;
259.  	} else if (obj->cursed && !rn2(2)) {
260.  		You_hear("your heart beat.");
261.  		return res;
262.  	}
263.  	if (Stunned || (Confusion && !rn2(5))) confdir();
264.  	if (!u.dx && !u.dy) {
265.  		ustatusline();
266.  		return res;
267.  	}
268.  	rx = u.ux + u.dx; ry = u.uy + u.dy;
269.  	if (!isok(rx,ry)) {
270.  		You_hear("a faint typing noise.");
271.  		return 0;
272.  	}
273.  	if ((mtmp = m_at(rx,ry)) != 0) {
274.  		mstatusline(mtmp);
275.  		if (mtmp->mundetected) {
276.  			mtmp->mundetected = 0;
277.  			if (cansee(rx,ry)) newsym(mtmp->mx,mtmp->my);
278.  		}
279.  		if (!canspotmon(mtmp))
280.  			map_invisible(rx,ry);
281.  		return res;
282.  	}
283.  	if (glyph_is_invisible(levl[rx][ry].glyph)) {
284.  		unmap_object(rx, ry);
285.  		newsym(rx, ry);
286.  		pline_The("invisible monster must have moved.");
287.  	}
288.  	lev = &levl[rx][ry];
289.  	switch(lev->typ) {
290.  	case SDOOR:
291.  		You_hear(hollow_str, "door");
292.  		cvt_sdoor_to_door(lev);		/* ->typ = DOOR */
293.  		if (Blind) feel_location(rx,ry);
294.  		else newsym(rx,ry);
295.  		return res;
296.  	case SCORR:
297.  		You_hear(hollow_str, "passage");
298.  		lev->typ = CORR;
299.  		unblock_point(rx,ry);
300.  		if (Blind) feel_location(rx,ry);
301.  		else newsym(rx,ry);
302.  		return res;
303.  	}
304.  
305.  	if (!its_dead(rx, ry, &res))
306.  	    You("hear nothing special.");	/* not You_hear()  */
307.  	return res;
308.  }
309.  

use_whistle[]

310.  static const char whistle_str[] = "produce a %s whistling sound.";
311.  
312.  STATIC_OVL void
313.  use_whistle(obj)
314.  struct obj *obj;
315.  {
316.  	You(whistle_str, obj->cursed ? "shrill" : "high");
317.  	wake_nearby();
318.  }
319.  

use_magic_whistle[]

320.  STATIC_OVL void
321.  use_magic_whistle(obj)
322.  struct obj *obj;
323.  {
324.  	register struct monst *mtmp, *nextmon;
325.  
326.  	if(obj->cursed && !rn2(2)) {
327.  		You("produce a high-pitched humming noise.");
328.  		wake_nearby();
329.  	} else {
330.  		int pet_cnt = 0;
331.  		You(whistle_str, Hallucination ? "normal" : "strange");
332.  		for(mtmp = fmon; mtmp; mtmp = nextmon) {
333.  		    nextmon = mtmp->nmon; /* trap might kill mon */
334.  		    if (DEADMONSTER(mtmp)) continue;
335.  		    if (mtmp->mtame) {
336.  			if (mtmp->mtrapped) {
337.  			    /* no longer in previous trap (affects mintrap) */
338.  			    mtmp->mtrapped = 0;
339.  			    fill_pit(mtmp->mx, mtmp->my);
340.  			}
341.  			mnexto(mtmp);
342.  			if (canspotmon(mtmp)) ++pet_cnt;
343.  			if (mintrap(mtmp) == 2) change_luck(-1);
344.  		    }
345.  		}
346.  		if (pet_cnt > 0) makeknown(obj->otyp);
347.  	}
348.  }
349.  

um_dist[]

350.  boolean
351.  um_dist(x,y,n)
352.  register xchar x, y, n;
353.  {
354.  	return((boolean)(abs(u.ux - x) > n  || abs(u.uy - y) > n));
355.  }
356.  

number_leashed[]

357.  int
358.  number_leashed()
359.  {
360.  	register int i = 0;
361.  	register struct obj *obj;
362.  
363.  	for(obj = invent; obj; obj = obj->nobj)
364.  		if(obj->otyp == LEASH && obj->leashmon != 0) i++;
365.  	return(i);
366.  }
367.  

o_unleash[]

368.  void
369.  o_unleash(otmp)		/* otmp is about to be destroyed or stolen */
370.  register struct obj *otmp;
371.  {
372.  	register struct monst *mtmp;
373.  
374.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
375.  		if(mtmp->m_id == (unsigned)otmp->leashmon)
376.  			mtmp->mleashed = 0;
377.  	otmp->leashmon = 0;
378.  }
379.  

m_unleash[]

380.  void
381.  m_unleash(mtmp, feedback)	/* mtmp is about to die, or become untame */
382.  register struct monst *mtmp;
383.  boolean feedback;
384.  {
385.  	register struct obj *otmp;
386.  
387.  	if (feedback) {
388.  	    if (canseemon(mtmp))
389.  		pline("%s pulls free of %s leash!", Monnam(mtmp), mhis(mtmp));
390.  	    else
391.  		Your("leash falls slack.");
392.  	}
393.  	for(otmp = invent; otmp; otmp = otmp->nobj)
394.  		if(otmp->otyp == LEASH &&
395.  				otmp->leashmon == (int)mtmp->m_id)
396.  			otmp->leashmon = 0;
397.  	mtmp->mleashed = 0;
398.  }
399.  

unleash_all[]

400.  void
401.  unleash_all()		/* player is about to die (for bones) */
402.  {
403.  	register struct obj *otmp;
404.  	register struct monst *mtmp;
405.  
406.  	for(otmp = invent; otmp; otmp = otmp->nobj)
407.  		if(otmp->otyp == LEASH) otmp->leashmon = 0;
408.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
409.  		mtmp->mleashed = 0;
410.  }
411.  

use_leash[]

412.  #define MAXLEASHED	2
413.  
414.  /* ARGSUSED */
415.  STATIC_OVL void
416.  use_leash(obj)
417.  struct obj *obj;
418.  {
419.  	coord cc;
420.  	register struct monst *mtmp;
421.  	int spotmon;
422.  
423.  	if(!obj->leashmon && number_leashed() >= MAXLEASHED) {
424.  		You("cannot leash any more pets.");
425.  		return;
426.  	}
427.  
428.  	if(!get_adjacent_loc((char *)0, (char *)0, u.ux, u.uy, &cc)) return;
429.  
430.  	if((cc.x == u.ux) && (cc.y == u.uy)) {
431.  #ifdef STEED
432.  		if (u.usteed && u.dz > 0) {
433.  		    mtmp = u.usteed;
434.  		    spotmon = 1;
435.  		    goto got_target;
436.  		}
437.  #endif
438.  		pline("Leash yourself?  Very funny...");
439.  		return;
440.  	}
441.  
442.  	if(!(mtmp = m_at(cc.x, cc.y))) {
443.  		There("is no creature there.");
444.  		return;
445.  	}
446.  
447.  	spotmon = canspotmon(mtmp);
448.  #ifdef STEED
449.   got_target:
450.  #endif
451.  
452.  	if(!mtmp->mtame) {
453.  	    if(!spotmon)
454.  		There("is no creature there.");
455.  	    else
456.  		pline("%s %s leashed!", Monnam(mtmp), (!obj->leashmon) ?
457.  				"cannot be" : "is not");
458.  	    return;
459.  	}
460.  	if(!obj->leashmon) {
461.  		if(mtmp->mleashed) {
462.  			pline("This %s is already leashed.",
463.  			      spotmon ? l_monnam(mtmp) : "monster");
464.  			return;
465.  		}
466.  		You("slip the leash around %s%s.",
467.  		    spotmon ? "your " : "", l_monnam(mtmp));
468.  		mtmp->mleashed = 1;
469.  		obj->leashmon = (int)mtmp->m_id;
470.  		mtmp->msleeping = 0;
471.  		return;
472.  	}
473.  	if(obj->leashmon != (int)mtmp->m_id) {
474.  		pline("This leash is not attached to that creature.");
475.  		return;
476.  	} else {
477.  		if(obj->cursed) {
478.  			pline_The("leash would not come off!");
479.  			obj->bknown = TRUE;
480.  			return;
481.  		}
482.  		mtmp->mleashed = 0;
483.  		obj->leashmon = 0;
484.  		You("remove the leash from %s%s.",
485.  		    spotmon ? "your " : "", l_monnam(mtmp));
486.  	}
487.  	return;
488.  }
489.  

get_mleash[]

490.  struct obj *
491.  get_mleash(mtmp)	/* assuming mtmp->mleashed has been checked */
492.  register struct monst *mtmp;
493.  {
494.  	register struct obj *otmp;
495.  
496.  	otmp = invent;
497.  	while(otmp) {
498.  		if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id)
499.  			return(otmp);
500.  		otmp = otmp->nobj;
501.  	}
502.  	return((struct obj *)0);
503.  }
504.  
505.  #endif /* OVLB */

next_to_u[]

506.  #ifdef OVL1
507.  
508.  boolean
509.  next_to_u()
510.  {
511.  	register struct monst *mtmp;
512.  	register struct obj *otmp;
513.  
514.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
515.  		if (DEADMONSTER(mtmp)) continue;
516.  		if(mtmp->mleashed) {
517.  			if (distu(mtmp->mx,mtmp->my) > 2) mnexto(mtmp);
518.  			if (distu(mtmp->mx,mtmp->my) > 2) {
519.  			    for(otmp = invent; otmp; otmp = otmp->nobj)
520.  				if(otmp->otyp == LEASH &&
521.  					otmp->leashmon == (int)mtmp->m_id) {
522.  				    if(otmp->cursed) return(FALSE);
523.  				    You_feel("%s leash go slack.",
524.  					(number_leashed() > 1) ? "a" : "the");
525.  				    mtmp->mleashed = 0;
526.  				    otmp->leashmon = 0;
527.  				}
528.  			}
529.  		}
530.  	}
531.  #ifdef STEED
532.  	/* no pack mules for the Amulet */
533.  	if (u.usteed && mon_has_amulet(u.usteed)) return FALSE;
534.  #endif
535.  	return(TRUE);
536.  }
537.  
538.  #endif /* OVL1 */

check_leash[]

539.  #ifdef OVL0
540.  
541.  void
542.  check_leash(x, y)
543.  register xchar x, y;
544.  {
545.  	register struct obj *otmp;
546.  	register struct monst *mtmp;
547.  
548.  	for (otmp = invent; otmp; otmp = otmp->nobj) {
549.  	    if (otmp->otyp != LEASH || otmp->leashmon == 0) continue;
550.  	    for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
551.  		if (DEADMONSTER(mtmp)) continue;
552.  		if ((int)mtmp->m_id == otmp->leashmon) break; 
553.  	    }
554.  	    if (!mtmp) {
555.  		impossible("leash in use isn't attached to anything?");
556.  		otmp->leashmon = 0;
557.  		continue;
558.  	    }
559.  	    if (dist2(u.ux,u.uy,mtmp->mx,mtmp->my) >
560.  		    dist2(x,y,mtmp->mx,mtmp->my)) {
561.  		if (!um_dist(mtmp->mx, mtmp->my, 3)) {
562.  		    ;	/* still close enough */
563.  		} else if (otmp->cursed && !breathless(mtmp->data)) {
564.  		    if (um_dist(mtmp->mx, mtmp->my, 5) ||
565.  			    (mtmp->mhp -= rnd(2)) <= 0) {
566.  			long save_pacifism = u.uconduct.killer;
567.  
568.  			Your("leash chokes %s to death!", mon_nam(mtmp));
569.  			/* hero might not have intended to kill pet, but
570.  			   that's the result of his actions; gain experience,
571.  			   lose pacifism, take alignment and luck hit, make
572.  			   corpse less likely to remain tame after revival */
573.  			xkilled(mtmp, 0);	/* no "you kill it" message */
574.  			/* life-saving doesn't ordinarily reset this */
575.  			if (mtmp->mhp > 0) u.uconduct.killer = save_pacifism;
576.  		    } else {
577.  			pline("%s chokes on the leash!", Monnam(mtmp));
578.  			/* tameness eventually drops to 1 here (never 0) */
579.  			if (mtmp->mtame && rn2(mtmp->mtame)) mtmp->mtame--;
580.  		    }
581.  		} else {
582.  		    if (um_dist(mtmp->mx, mtmp->my, 5)) {
583.  			pline("%s leash snaps loose!", s_suffix(Monnam(mtmp)));
584.  			m_unleash(mtmp, FALSE);
585.  		    } else {
586.  			You("pull on the leash.");
587.  			if (mtmp->data->msound != MS_SILENT)
588.  			    switch (rn2(3)) {
589.  			    case 0:  growl(mtmp);   break;
590.  			    case 1:  yelp(mtmp);    break;
591.  			    default: whimper(mtmp); break;
592.  			    }
593.  		    }
594.  		}
595.  	    }
596.  	}
597.  }
598.  
599.  #endif /* OVL0 */

use_mirror[]

600.  #ifdef OVLB
601.  
602.  #define WEAK	3	/* from eat.c */
603.  
604.  static const char look_str[] = "look %s.";
605.  
606.  STATIC_OVL int
607.  use_mirror(obj)
608.  struct obj *obj;
609.  {
610.  	register struct monst *mtmp;
611.  	register char mlet;
612.  	boolean vis;
613.  
614.  	if(!getdir((char *)0)) return 0;
615.  	if(obj->cursed && !rn2(2)) {
616.  		if (!Blind)
617.  			pline_The("mirror fogs up and doesn't reflect!");
618.  		return 1;
619.  	}
620.  	if(!u.dx && !u.dy && !u.dz) {
621.  		if(!Blind && !Invisible) {
622.  		    if (u.umonnum == PM_FLOATING_EYE) {
623.  			if (!Free_action) {
624.  			pline(Hallucination ?
625.  			      "Yow!  The mirror stares back!" :
626.  			      "Yikes!  You've frozen yourself!");
627.  			nomul(-rnd((MAXULEV+6) - u.ulevel));
628.  			} else You("stiffen momentarily under your gaze.");
629.  		    } else if (youmonst.data->mlet == S_VAMPIRE)
630.  			You("don't have a reflection.");
631.  		    else if (u.umonnum == PM_UMBER_HULK) {
632.  			pline("Huh?  That doesn't look like you!");
633.  			make_confused(HConfusion + d(3,4),FALSE);
634.  		    } else if (Hallucination)
635.  			You(look_str, hcolor((char *)0));
636.  		    else if (Sick)
637.  			You(look_str, "peaked");
638.  		    else if (u.uhs >= WEAK)
639.  			You(look_str, "undernourished");
640.  		    else You("look as %s as ever.",
641.  				ACURR(A_CHA) > 14 ?
642.  				(poly_gender()==1 ? "beautiful" : "handsome") :
643.  				"ugly");
644.  		} else {
645.  			You_cant("see your %s %s.",
646.  				ACURR(A_CHA) > 14 ?
647.  				(poly_gender()==1 ? "beautiful" : "handsome") :
648.  				"ugly",
649.  				body_part(FACE));
650.  		}
651.  		return 1;
652.  	}
653.  	if(u.uswallow) {
654.  		if (!Blind) You("reflect %s %s.", s_suffix(mon_nam(u.ustuck)),
655.  		    mbodypart(u.ustuck, STOMACH));
656.  		return 1;
657.  	}
658.  	if(Underwater) {
659.  		You(Hallucination ?
660.  		    "give the fish a chance to fix their makeup." :
661.  		    "reflect the murky water.");
662.  		return 1;
663.  	}
664.  	if(u.dz) {
665.  		if (!Blind)
666.  		    You("reflect the %s.",
667.  			(u.dz > 0) ? surface(u.ux,u.uy) : ceiling(u.ux,u.uy));
668.  		return 1;
669.  	}
670.  	mtmp = bhit(u.dx, u.dy, COLNO, INVIS_BEAM,
671.  		    (int FDECL((*),(MONST_P,OBJ_P)))0,
672.  		    (int FDECL((*),(OBJ_P,OBJ_P)))0,
673.  		    obj);
674.  	if (!mtmp || !haseyes(mtmp->data))
675.  		return 1;
676.  
677.  	vis = canseemon(mtmp);
678.  	mlet = mtmp->data->mlet;
679.  	if (mtmp->msleeping) {
680.  		if (vis)
681.  		    pline ("%s is too tired to look at your mirror.",
682.  			    Monnam(mtmp));
683.  	} else if (!mtmp->mcansee) {
684.  	    if (vis)
685.  		pline("%s can't see anything right now.", Monnam(mtmp));
686.  	/* some monsters do special things */
687.  	} else if (mlet == S_VAMPIRE || mlet == S_GHOST) {
688.  	    if (vis)
689.  		pline ("%s doesn't have a reflection.", Monnam(mtmp));
690.  	} else if(!mtmp->mcan && !mtmp->minvis &&
691.  					mtmp->data == &mons[PM_MEDUSA]) {
692.  		if (mon_reflects(mtmp, "The gaze is reflected away by %s %s!"))
693.  			return 1;
694.  		if (vis)
695.  			pline("%s is turned to stone!", Monnam(mtmp));
696.  		stoned = TRUE;
697.  		killed(mtmp);
698.  	} else if(!mtmp->mcan && !mtmp->minvis &&
699.  					mtmp->data == &mons[PM_FLOATING_EYE]) {
700.  		int tmp = d((int)mtmp->m_lev, (int)mtmp->data->mattk[0].damd);
701.  		if (!rn2(4)) tmp = 120;
702.  		if (vis)
703.  			pline("%s is frozen by its reflection.", Monnam(mtmp));
704.  		else You_hear("%s stop moving.",something);
705.  		mtmp->mcanmove = 0;
706.  		if ( (int) mtmp->mfrozen + tmp > 127)
707.  			mtmp->mfrozen = 127;
708.  		else mtmp->mfrozen += tmp;
709.  	} else if(!mtmp->mcan && !mtmp->minvis &&
710.  					mtmp->data == &mons[PM_UMBER_HULK]) {
711.  		if (vis)
712.  			pline ("%s confuses itself!", Monnam(mtmp));
713.  		mtmp->mconf = 1;
714.  	} else if(!mtmp->mcan && !mtmp->minvis && (mlet == S_NYMPH
715.  				     || mtmp->data==&mons[PM_SUCCUBUS])) {
716.  		if (vis) {
717.  		    pline ("%s admires herself in your mirror.", Monnam(mtmp));
718.  		    pline ("She takes it!");
719.  		} else pline ("It steals your mirror!");
720.  		setnotworn(obj); /* in case mirror was wielded */
721.  		freeinv(obj);
722.  		(void) mpickobj(mtmp,obj);
723.  		if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
724.  	} else if (!is_unicorn(mtmp->data) && !humanoid(mtmp->data) &&
725.  			(!mtmp->minvis || perceives(mtmp->data)) && rn2(5)) {
726.  		if (vis)
727.  		    pline("%s is frightened by its reflection.", Monnam(mtmp));
728.  		monflee(mtmp, d(2,4), FALSE, FALSE);
729.  	} else if (!Blind) {
730.  		if (mtmp->minvis && !See_invisible)
731.  		    ;
732.  		else if ((mtmp->minvis && !perceives(mtmp->data))
733.  			 || !haseyes(mtmp->data))
734.  		    pline("%s doesn't seem to notice its reflection.",
735.  			Monnam(mtmp));
736.  		else
737.  		    pline("%s ignores %s reflection.",
738.  			  Monnam(mtmp), mhis(mtmp));
739.  	}
740.  	return 1;
741.  }
742.  

use_bell[]

743.  STATIC_OVL void
744.  use_bell(optr)
745.  struct obj **optr;
746.  {
747.  	register struct obj *obj = *optr;
748.  	struct monst *mtmp;
749.  	boolean wakem = FALSE, learno = FALSE,
750.  		ordinary = (obj->otyp != BELL_OF_OPENING || !obj->spe),
751.  		invoking = (obj->otyp == BELL_OF_OPENING &&
752.  			 invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy));
753.  
754.  	You("ring %s.", the(xname(obj)));
755.  
756.  	if (Underwater || (u.uswallow && ordinary)) {
757.  #ifdef	AMIGA
758.  	    amii_speaker( obj, "AhDhGqEqDhEhAqDqFhGw", AMII_MUFFLED_VOLUME );
759.  #endif
760.  	    pline("But the sound is muffled.");
761.  
762.  	} else if (invoking && ordinary) {
763.  	    /* needs to be recharged... */
764.  	    pline("But it makes no sound.");
765.  	    learno = TRUE;	/* help player figure out why */
766.  
767.  	} else if (ordinary) {
768.  #ifdef	AMIGA
769.  	    amii_speaker( obj, "ahdhgqeqdhehaqdqfhgw", AMII_MUFFLED_VOLUME );
770.  #endif
771.  	    if (obj->cursed && !rn2(4) &&
772.  		    /* note: once any of them are gone, we stop all of them */
773.  		    !(mvitals[PM_WOOD_NYMPH].mvflags & G_GONE) &&
774.  		    !(mvitals[PM_WATER_NYMPH].mvflags & G_GONE) &&
775.  		    !(mvitals[PM_MOUNTAIN_NYMPH].mvflags & G_GONE) &&
776.  		    (mtmp = makemon(mkclass(S_NYMPH, 0),
777.  					u.ux, u.uy, NO_MINVENT)) != 0) {
778.  		You("summon %s!", a_monnam(mtmp));
779.  		if (!obj_resists(obj, 93, 100)) {
780.  		    pline("%s shattered!", Tobjnam(obj, "have"));
781.  		    useup(obj);
782.  		    *optr = 0;
783.  		} else switch (rn2(3)) {
784.  			default:
785.  				break;
786.  			case 1:
787.  				mon_adjust_speed(mtmp, 2, (struct obj *)0);
788.  				break;
789.  			case 2: /* no explanation; it just happens... */
790.  				nomovemsg = "";
791.  				nomul(-rnd(2));
792.  				break;
793.  		}
794.  	    }
795.  	    wakem = TRUE;
796.  
797.  	} else {
798.  	    /* charged Bell of Opening */
799.  	    consume_obj_charge(obj, TRUE);
800.  
801.  	    if (u.uswallow) {
802.  		if (!obj->cursed)
803.  		    (void) openit();
804.  		else
805.  		    pline(nothing_happens);
806.  
807.  	    } else if (obj->cursed) {
808.  		coord mm;
809.  
810.  		mm.x = u.ux;
811.  		mm.y = u.uy;
812.  		mkundead(&mm, FALSE, NO_MINVENT);
813.  		wakem = TRUE;
814.  
815.  	    } else  if (invoking) {
816.  		pline("%s an unsettling shrill sound...",
817.  		      Tobjnam(obj, "issue"));
818.  #ifdef	AMIGA
819.  		amii_speaker( obj, "aefeaefeaefeaefeaefe", AMII_LOUDER_VOLUME );
820.  #endif
821.  		obj->age = moves;
822.  		learno = TRUE;
823.  		wakem = TRUE;
824.  
825.  	    } else if (obj->blessed) {
826.  		int res = 0;
827.  
828.  #ifdef	AMIGA
829.  		amii_speaker( obj, "ahahahDhEhCw", AMII_SOFT_VOLUME );
830.  #endif
831.  		if (uchain) {
832.  		    unpunish();
833.  		    res = 1;
834.  		}
835.  		res += openit();
836.  		switch (res) {
837.  		  case 0:  pline(nothing_happens); break;
838.  		  case 1:  pline("%s opens...", Something);
839.  			   learno = TRUE; break;
840.  		  default: pline("Things open around you...");
841.  			   learno = TRUE; break;
842.  		}
843.  
844.  	    } else {  /* uncursed */
845.  #ifdef	AMIGA
846.  		amii_speaker( obj, "AeFeaeFeAefegw", AMII_OKAY_VOLUME );
847.  #endif
848.  		if (findit() != 0) learno = TRUE;
849.  		else pline(nothing_happens);
850.  	    }
851.  
852.  	}	/* charged BofO */
853.  
854.  	if (learno) {
855.  	    makeknown(BELL_OF_OPENING);
856.  	    obj->known = 1;
857.  	}
858.  	if (wakem) wake_nearby();
859.  }
860.  

use_candelabrum[]

861.  STATIC_OVL void
862.  use_candelabrum(obj)
863.  register struct obj *obj;
864.  {
865.  	const char *s = (obj->spe != 1) ? "candles" : "candle";
866.  
867.  	if(Underwater) {
868.  		You("cannot make fire under water.");
869.  		return;
870.  	}
871.  	if(obj->lamplit) {
872.  		You("snuff the %s.", s);
873.  		end_burn(obj, TRUE);
874.  		return;
875.  	}
876.  	if(obj->spe <= 0) {
877.  		pline("This %s has no %s.", xname(obj), s);
878.  		return;
879.  	}
880.  	if(u.uswallow || obj->cursed) {
881.  		if (!Blind)
882.  		    pline_The("%s %s for a moment, then %s.",
883.  			      s, vtense(s, "flicker"), vtense(s, "die"));
884.  		return;
885.  	}
886.  	if(obj->spe < 7) {
887.  		There("%s only %d %s in %s.",
888.  		      vtense(s, "are"), obj->spe, s, the(xname(obj)));
889.  		if (!Blind)
890.  		    pline("%s lit.  %s dimly.",
891.  			  obj->spe == 1 ? "It is" : "They are",
892.  			  Tobjnam(obj, "shine"));
893.  	} else {
894.  		pline("%s's %s burn%s", The(xname(obj)), s,
895.  			(Blind ? "." : " brightly!"));
896.  	}
897.  	if (!invocation_pos(u.ux, u.uy)) {
898.  		pline_The("%s %s being rapidly consumed!", s, vtense(s, "are"));
899.  		obj->age /= 2;
900.  	} else {
901.  		if(obj->spe == 7) {
902.  		    if (Blind)
903.  		      pline("%s a strange warmth!", Tobjnam(obj, "radiate"));
904.  		    else
905.  		      pline("%s with a strange light!", Tobjnam(obj, "glow"));
906.  		}
907.  		obj->known = 1;
908.  	}
909.  	begin_burn(obj, FALSE);
910.  }
911.  

use_candle[]

912.  STATIC_OVL void
913.  use_candle(optr)
914.  struct obj **optr;
915.  {
916.  	register struct obj *obj = *optr;
917.  	register struct obj *otmp;
918.  	const char *s = (obj->quan != 1) ? "candles" : "candle";
919.  	char qbuf[QBUFSZ];
920.  
921.  	if(u.uswallow) {
922.  		You(no_elbow_room);
923.  		return;
924.  	}
925.  	if(Underwater) {
926.  		pline("Sorry, fire and water don't mix.");
927.  		return;
928.  	}
929.  
930.  	otmp = carrying(CANDELABRUM_OF_INVOCATION);
931.  	if(!otmp || otmp->spe == 7) {
932.  		use_lamp(obj);
933.  		return;
934.  	}
935.  
936.  	Sprintf(qbuf, "Attach %s", the(xname(obj)));
937.  	Sprintf(eos(qbuf), " to %s?",
938.  		safe_qbuf(qbuf, sizeof(" to ?"), the(xname(otmp)),
939.  			the(simple_typename(otmp->otyp)), "it"));
940.  	if(yn(qbuf) == 'n') {
941.  		if (!obj->lamplit)
942.  		    You("try to light %s...", the(xname(obj)));
943.  		use_lamp(obj);
944.  		return;
945.  	} else {
946.  		if ((long)otmp->spe + obj->quan > 7L)
947.  		    obj = splitobj(obj, 7L - (long)otmp->spe);
948.  		else *optr = 0;
949.  		You("attach %ld%s %s to %s.",
950.  		    obj->quan, !otmp->spe ? "" : " more",
951.  		    s, the(xname(otmp)));
952.  		if (!otmp->spe || otmp->age > obj->age)
953.  		    otmp->age = obj->age;
954.  		otmp->spe += (int)obj->quan;
955.  		if (otmp->lamplit && !obj->lamplit)
956.  		    pline_The("new %s magically %s!", s, vtense(s, "ignite"));
957.  		else if (!otmp->lamplit && obj->lamplit)
958.  		    pline("%s out.", (obj->quan > 1L) ? "They go" : "It goes");
959.  		if (obj->unpaid)
960.  		    verbalize("You %s %s, you bought %s!",
961.  			      otmp->lamplit ? "burn" : "use",
962.  			      (obj->quan > 1L) ? "them" : "it",
963.  			      (obj->quan > 1L) ? "them" : "it");
964.  		if (obj->quan < 7L && otmp->spe == 7)
965.  		    pline("%s now has seven%s candles attached.",
966.  			  The(xname(otmp)), otmp->lamplit ? " lit" : "");
967.  		/* candelabrum's light range might increase */
968.  		if (otmp->lamplit) obj_merge_light_sources(otmp, otmp);
969.  		/* candles are no longer a separate light source */
970.  		if (obj->lamplit) end_burn(obj, TRUE);
971.  		/* candles are now gone */
972.  		useupall(obj);
973.  	}
974.  }
975.  

snuff_candle[]

976.  boolean
977.  snuff_candle(otmp)  /* call in drop, throw, and put in box, etc. */
978.  register struct obj *otmp;
979.  {
980.  	register boolean candle = Is_candle(otmp);
981.  
982.  	if ((candle || otmp->otyp == CANDELABRUM_OF_INVOCATION) &&
983.  		otmp->lamplit) {
984.  	    char buf[BUFSZ];
985.  	    xchar x, y;
986.  	    register boolean many = candle ? otmp->quan > 1L : otmp->spe > 1;
987.  
988.  	    (void) get_obj_location(otmp, &x, &y, 0);
989.  	    if (otmp->where == OBJ_MINVENT ? cansee(x,y) : !Blind)
990.  		pline("%s %scandle%s flame%s extinguished.",
991.  		      Shk_Your(buf, otmp),
992.  		      (candle ? "" : "candelabrum's "),
993.  		      (many ? "s'" : "'s"), (many ? "s are" : " is"));
994.  	   end_burn(otmp, TRUE);
995.  	   return(TRUE);
996.  	}
997.  	return(FALSE);
998.  }
999.  

snuff_lit[]

1000. /* called when lit lamp is hit by water or put into a container or
1001.    you've been swallowed by a monster; obj might be in transit while
1002.    being thrown or dropped so don't assume that its location is valid */
1003. boolean
1004. snuff_lit(obj)
1005. struct obj *obj;
1006. {
1007. 	xchar x, y;
1008. 
1009. 	if (obj->lamplit) {
1010. 	    if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
1011. 		    obj->otyp == BRASS_LANTERN || obj->otyp == POT_OIL) {
1012. 		(void) get_obj_location(obj, &x, &y, 0);
1013. 		if (obj->where == OBJ_MINVENT ? cansee(x,y) : !Blind)
1014. 		    pline("%s %s out!", Yname2(obj), otense(obj, "go"));
1015. 		end_burn(obj, TRUE);
1016. 		return TRUE;
1017. 	    }
1018. 	    if (snuff_candle(obj)) return TRUE;
1019. 	}
1020. 	return FALSE;
1021. }
1022. 

catch_lit[]

1023. /* Called when potentially lightable object is affected by fire_damage().
1024.    Return TRUE if object was lit and FALSE otherwise --ALI */
1025. boolean
1026. catch_lit(obj)
1027. struct obj *obj;
1028. {
1029. 	xchar x, y;
1030. 
1031. 	if (!obj->lamplit && (obj->otyp == MAGIC_LAMP || ignitable(obj))) {
1032. 	    if ((obj->otyp == MAGIC_LAMP ||
1033. 		 obj->otyp == CANDELABRUM_OF_INVOCATION) &&
1034. 		obj->spe == 0)
1035. 		return FALSE;
1036. 	    else if (obj->otyp != MAGIC_LAMP && obj->age == 0)
1037. 		return FALSE;
1038. 	    if (!get_obj_location(obj, &x, &y, 0))
1039. 		return FALSE;
1040. 	    if (obj->otyp == CANDELABRUM_OF_INVOCATION && obj->cursed)
1041. 		return FALSE;
1042. 	    if ((obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
1043. 		 obj->otyp == BRASS_LANTERN) && obj->cursed && !rn2(2))
1044. 		return FALSE;
1045. 	    if (obj->where == OBJ_MINVENT ? cansee(x,y) : !Blind)
1046. 		pline("%s %s light!", Yname2(obj), otense(obj, "catch"));
1047. 	    if (obj->otyp == POT_OIL) makeknown(obj->otyp);
1048. 	    if (obj->unpaid && costly_spot(u.ux, u.uy) && (obj->where == OBJ_INVENT)) {
1049. 	        /* if it catches while you have it, then it's your tough luck */
1050. 		check_unpaid(obj);
1051. 	        verbalize("That's in addition to the cost of %s %s, of course.",
1052. 				Yname2(obj), obj->quan == 1 ? "itself" : "themselves");
1053. 		bill_dummy_object(obj);
1054. 	    }
1055. 	    begin_burn(obj, FALSE);
1056. 	    return TRUE;
1057. 	}
1058. 	return FALSE;
1059. }
1060. 

use_lamp[]

1061. STATIC_OVL void
1062. use_lamp(obj)
1063. struct obj *obj;
1064. {
1065. 	char buf[BUFSZ];
1066. 
1067. 	if(Underwater) {
1068. 		pline("This is not a diving lamp.");
1069. 		return;
1070. 	}
1071. 	if(obj->lamplit) {
1072. 		if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
1073. 				obj->otyp == BRASS_LANTERN)
1074. 		    pline("%s lamp is now off.", Shk_Your(buf, obj));
1075. 		else
1076. 		    You("snuff out %s.", yname(obj));
1077. 		end_burn(obj, TRUE);
1078. 		return;
1079. 	}
1080. 	/* magic lamps with an spe == 0 (wished for) cannot be lit */
1081. 	if ((!Is_candle(obj) && obj->age == 0)
1082. 			|| (obj->otyp == MAGIC_LAMP && obj->spe == 0)) {
1083. 		if (obj->otyp == BRASS_LANTERN)
1084. 			Your("lamp has run out of power.");
1085. 		else pline("This %s has no oil.", xname(obj));
1086. 		return;
1087. 	}
1088. 	if (obj->cursed && !rn2(2)) {
1089. 		pline("%s for a moment, then %s.",
1090. 		      Tobjnam(obj, "flicker"), otense(obj, "die"));
1091. 	} else {
1092. 		if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
1093. 				obj->otyp == BRASS_LANTERN) {
1094. 		    check_unpaid(obj);
1095. 		    pline("%s lamp is now on.", Shk_Your(buf, obj));
1096. 		} else {	/* candle(s) */
1097. 		    pline("%s flame%s %s%s",
1098. 			s_suffix(Yname2(obj)),
1099. 			plur(obj->quan), otense(obj, "burn"),
1100. 			Blind ? "." : " brightly!");
1101. 		    if (obj->unpaid && costly_spot(u.ux, u.uy) &&
1102. 			  obj->age == 20L * (long)objects[obj->otyp].oc_cost) {
1103. 			const char *ithem = obj->quan > 1L ? "them" : "it";
1104. 			verbalize("You burn %s, you bought %s!", ithem, ithem);
1105. 			bill_dummy_object(obj);
1106. 		    }
1107. 		}
1108. 		begin_burn(obj, FALSE);
1109. 	}
1110. }
1111. 

light_cocktail[]

1112. STATIC_OVL void
1113. light_cocktail(obj)
1114. 	struct obj *obj;	/* obj is a potion of oil */
1115. {
1116. 	char buf[BUFSZ];
1117. 
1118. 	if (u.uswallow) {
1119. 	    You(no_elbow_room);
1120. 	    return;
1121. 	}
1122. 
1123. 	if (obj->lamplit) {
1124. 	    You("snuff the lit potion.");
1125. 	    end_burn(obj, TRUE);
1126. 	    /*
1127. 	     * Free & add to re-merge potion.  This will average the
1128. 	     * age of the potions.  Not exactly the best solution,
1129. 	     * but its easy.
1130. 	     */
1131. 	    freeinv(obj);
1132. 	    (void) addinv(obj);
1133. 	    return;
1134. 	} else if (Underwater) {
1135. 	    There("is not enough oxygen to sustain a fire.");
1136. 	    return;
1137. 	}
1138. 
1139. 	You("light %s potion.%s", shk_your(buf, obj),
1140. 	    Blind ? "" : "  It gives off a dim light.");
1141. 	if (obj->unpaid && costly_spot(u.ux, u.uy)) {
1142. 	    /* Normally, we shouldn't both partially and fully charge
1143. 	     * for an item, but (Yendorian Fuel) Taxes are inevitable...
1144. 	     */
1145. 	    check_unpaid(obj);
1146. 	    verbalize("That's in addition to the cost of the potion, of course.");
1147. 	    bill_dummy_object(obj);
1148. 	}
1149. 	makeknown(obj->otyp);
1150. 
1151. 	if (obj->quan > 1L) {
1152. 	    obj = splitobj(obj, 1L);
1153. 	    begin_burn(obj, FALSE);	/* burn before free to get position */
1154. 	    obj_extract_self(obj);	/* free from inv */
1155. 
1156. 	    /* shouldn't merge */
1157. 	    obj = hold_another_object(obj, "You drop %s!",
1158. 				      doname(obj), (const char *)0);
1159. 	} else
1160. 	    begin_burn(obj, FALSE);
1161. }
1162. 

dorub[]

1163. static NEARDATA const char cuddly[] = { TOOL_CLASS, GEM_CLASS, 0 };
1164. 
1165. int
1166. dorub()
1167. {
1168. 	struct obj *obj = getobj(cuddly, "rub");
1169. 
1170. 	if (obj && obj->oclass == GEM_CLASS) {
1171. 	    if (is_graystone(obj)) {
1172. 		use_stone(obj);
1173. 		return 1;
1174. 	    } else {
1175. 		pline("Sorry, I don't know how to use that.");
1176. 		return 0;
1177. 	    }
1178. 	}
1179. 
1180. 	if (!obj || !wield_tool(obj, "rub")) return 0;
1181. 
1182. 	/* now uwep is obj */
1183. 	if (uwep->otyp == MAGIC_LAMP) {
1184. 	    if (uwep->spe > 0 && !rn2(3)) {
1185. 		check_unpaid_usage(uwep, TRUE);		/* unusual item use */
1186. 		djinni_from_bottle(uwep);
1187. 		makeknown(MAGIC_LAMP);
1188. 		uwep->otyp = OIL_LAMP;
1189. 		uwep->spe = 0; /* for safety */
1190. 		uwep->age = rn1(500,1000);
1191. 		if (uwep->lamplit) begin_burn(uwep, TRUE);
1192. 		update_inventory();
1193. 	    } else if (rn2(2) && !Blind)
1194. 		You("see a puff of smoke.");
1195. 	    else pline(nothing_happens);
1196. 	} else if (obj->otyp == BRASS_LANTERN) {
1197. 	    /* message from Adventure */
1198. 	    pline("Rubbing the electric lamp is not particularly rewarding.");
1199. 	    pline("Anyway, nothing exciting happens.");
1200. 	} else pline(nothing_happens);
1201. 	return 1;
1202. }
1203. 

dojump[]

1204. int
1205. dojump()
1206. {
1207. 	/* Physical jump */
1208. 	return jump(0);
1209. }
1210. 

jump[]

1211. int
1212. jump(magic)
1213. int magic; /* 0=Physical, otherwise skill level */
1214. {
1215. 	coord cc;
1216. 
1217. 	if (!magic && (nolimbs(youmonst.data) || slithy(youmonst.data))) {
1218. 		/* normally (nolimbs || slithy) implies !Jumping,
1219. 		   but that isn't necessarily the case for knights */
1220. 		You_cant("jump; you have no legs!");
1221. 		return 0;
1222. 	} else if (!magic && !Jumping) {
1223. 		You_cant("jump very far.");
1224. 		return 0;
1225. 	} else if (u.uswallow) {
1226. 		if (magic) {
1227. 			You("bounce around a little.");
1228. 			return 1;
1229. 		}
1230. 		pline("You've got to be kidding!");
1231. 		return 0;
1232. 	} else if (u.uinwater) {
1233. 		if (magic) {
1234. 			You("swish around a little.");
1235. 			return 1;
1236. 		}
1237. 		pline("This calls for swimming, not jumping!");
1238. 		return 0;
1239. 	} else if (u.ustuck) {
1240. 		if (u.ustuck->mtame && !Conflict && !u.ustuck->mconf) {
1241. 		    You("pull free from %s.", mon_nam(u.ustuck));
1242. 		    u.ustuck = 0;
1243. 		    return 1;
1244. 		}
1245. 		if (magic) {
1246. 			You("writhe a little in the grasp of %s!", mon_nam(u.ustuck));
1247. 			return 1;
1248. 		}
1249. 		You("cannot escape from %s!", mon_nam(u.ustuck));
1250. 		return 0;
1251. 	} else if (Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
1252. 		if (magic) {
1253. 			You("flail around a little.");
1254. 			return 1;
1255. 		}
1256. 		You("don't have enough traction to jump.");
1257. 		return 0;
1258. 	} else if (!magic && near_capacity() > UNENCUMBERED) {
1259. 		You("are carrying too much to jump!");
1260. 		return 0;
1261. 	} else if (!magic && (u.uhunger <= 100 || ACURR(A_STR) < 6)) {
1262. 		You("lack the strength to jump!");
1263. 		return 0;
1264. 	} else if (Wounded_legs) {
1265. 		long wl = (Wounded_legs & BOTH_SIDES);
1266. 		const char *bp = body_part(LEG);
1267. 
1268. 		if (wl == BOTH_SIDES) bp = makeplural(bp);
1269. #ifdef STEED
1270. 		if (u.usteed)
1271. 		    pline("%s is in no shape for jumping.", Monnam(u.usteed));
1272. 		else
1273. #endif
1274. 		Your("%s%s %s in no shape for jumping.",
1275. 		     (wl == LEFT_SIDE) ? "left " :
1276. 			(wl == RIGHT_SIDE) ? "right " : "",
1277. 		     bp, (wl == BOTH_SIDES) ? "are" : "is");
1278. 		return 0;
1279. 	}
1280. #ifdef STEED
1281. 	else if (u.usteed && u.utrap) {
1282. 		pline("%s is stuck in a trap.", Monnam(u.usteed));
1283. 		return (0);
1284. 	}
1285. #endif
1286. 
1287. 	pline("Where do you want to jump?");
1288. 	cc.x = u.ux;
1289. 	cc.y = u.uy;
1290. 	if (getpos(&cc, TRUE, "the desired position") < 0)
1291. 		return 0;	/* user pressed ESC */
1292. 	if (!magic && !(HJumping & ~INTRINSIC) && !EJumping &&
1293. 			distu(cc.x, cc.y) != 5) {
1294. 		/* The Knight jumping restriction still applies when riding a
1295. 		 * horse.  After all, what shape is the knight piece in chess?
1296. 		 */
1297. 		pline("Illegal move!");
1298. 		return 0;
1299. 	} else if (distu(cc.x, cc.y) > (magic ? 6+magic*3 : 9)) {
1300. 		pline("Too far!");
1301. 		return 0;
1302. 	} else if (!cansee(cc.x, cc.y)) {
1303. 		You("cannot see where to land!");
1304. 		return 0;
1305. 	} else if (!isok(cc.x, cc.y)) {
1306. 		You("cannot jump there!");
1307. 		return 0;
1308. 	} else {
1309. 	    coord uc;
1310. 	    int range, temp;
1311. 
1312. 	    if(u.utrap)
1313. 		switch(u.utraptype) {
1314. 		case TT_BEARTRAP: {
1315. 		    register long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
1316. 		    You("rip yourself free of the bear trap!  Ouch!");
1317. 		    losehp(rnd(10), "jumping out of a bear trap", KILLED_BY);
1318. 		    set_wounded_legs(side, rn1(1000,500));
1319. 		    break;
1320. 		  }
1321. 		case TT_PIT:
1322. 		    You("leap from the pit!");
1323. 		    break;
1324. 		case TT_WEB:
1325. 		    You("tear the web apart as you pull yourself free!");
1326. 		    deltrap(t_at(u.ux,u.uy));
1327. 		    break;
1328. 		case TT_LAVA:
1329. 		    You("pull yourself above the lava!");
1330. 		    u.utrap = 0;
1331. 		    return 1;
1332. 		case TT_INFLOOR:
1333. 		    You("strain your %s, but you're still stuck in the floor.",
1334. 			makeplural(body_part(LEG)));
1335. 		    set_wounded_legs(LEFT_SIDE, rn1(10, 11));
1336. 		    set_wounded_legs(RIGHT_SIDE, rn1(10, 11));
1337. 		    return 1;
1338. 		}
1339. 
1340. 	    /*
1341. 	     * Check the path from uc to cc, calling hurtle_step at each
1342. 	     * location.  The final position actually reached will be
1343. 	     * in cc.
1344. 	     */
1345. 	    uc.x = u.ux;
1346. 	    uc.y = u.uy;
1347. 	    /* calculate max(abs(dx), abs(dy)) as the range */
1348. 	    range = cc.x - uc.x;
1349. 	    if (range < 0) range = -range;
1350. 	    temp = cc.y - uc.y;
1351. 	    if (temp < 0) temp = -temp;
1352. 	    if (range < temp)
1353. 		range = temp;
1354. 	    (void) walk_path(&uc, &cc, hurtle_step, (genericptr_t)&range);
1355. 
1356. 	    /* A little Sokoban guilt... */
1357. 	    if (In_sokoban(&u.uz))
1358. 		change_luck(-1);
1359. 
1360. 	    teleds(cc.x, cc.y, TRUE);
1361. 	    nomul(-1);
1362. 	    nomovemsg = "";
1363. 	    morehungry(rnd(25));
1364. 	    return 1;
1365. 	}
1366. }
1367. 

tinnable[]

1368. boolean
1369. tinnable(corpse)
1370. struct obj *corpse;
1371. {
1372. 	if (corpse->oeaten) return 0;
1373. 	if (!mons[corpse->corpsenm].cnutrit) return 0;
1374. 	return 1;
1375. }
1376. 

use_tinning_kit[]

1377. STATIC_OVL void
1378. use_tinning_kit(obj)
1379. register struct obj *obj;
1380. {
1381. 	register struct obj *corpse, *can;
1382. 
1383. 	/* This takes only 1 move.  If this is to be changed to take many
1384. 	 * moves, we've got to deal with decaying corpses...
1385. 	 */
1386. 	if (obj->spe <= 0) {
1387. 		You("seem to be out of tins.");
1388. 		return;
1389. 	}
1390. 	if (!(corpse = floorfood("tin", 2))) return;
1391. 	if (corpse->oeaten) {
1392. 		You("cannot tin %s which is partly eaten.",something);
1393. 		return;
1394. 	}
1395. 	if (touch_petrifies(&mons[corpse->corpsenm])
1396. 		&& !Stone_resistance && !uarmg) {
1397. 	    char kbuf[BUFSZ];
1398. 
1399. 	    if (poly_when_stoned(youmonst.data))
1400. 		You("tin %s without wearing gloves.",
1401. 			an(mons[corpse->corpsenm].mname));
1402. 	    else {
1403. 		pline("Tinning %s without wearing gloves is a fatal mistake...",
1404. 			an(mons[corpse->corpsenm].mname));
1405. 		Sprintf(kbuf, "trying to tin %s without gloves",
1406. 			an(mons[corpse->corpsenm].mname));
1407. 	    }
1408. 	    instapetrify(kbuf);
1409. 	}
1410. 	if (is_rider(&mons[corpse->corpsenm])) {
1411. 		(void) revive_corpse(corpse);
1412. 		verbalize("Yes...  But War does not preserve its enemies...");
1413. 		return;
1414. 	}
1415. 	if (mons[corpse->corpsenm].cnutrit == 0) {
1416. 		pline("That's too insubstantial to tin.");
1417. 		return;
1418. 	}
1419. 	consume_obj_charge(obj, TRUE);
1420. 
1421. 	if ((can = mksobj(TIN, FALSE, FALSE)) != 0) {
1422. 	    static const char you_buy_it[] = "You tin it, you bought it!";
1423. 
1424. 	    can->corpsenm = corpse->corpsenm;
1425. 	    can->cursed = obj->cursed;
1426. 	    can->blessed = obj->blessed;
1427. 	    can->owt = weight(can);
1428. 	    can->known = 1;
1429. 	    can->spe = -1;  /* Mark tinned tins. No spinach allowed... */
1430. 	    if (carried(corpse)) {
1431. 		if (corpse->unpaid)
1432. 		    verbalize(you_buy_it);
1433. 		useup(corpse);
1434. 	    } else {
1435. 		if (costly_spot(corpse->ox, corpse->oy) && !corpse->no_charge)
1436. 		    verbalize(you_buy_it);
1437. 		useupf(corpse, 1L);
1438. 	    }
1439. 	    can = hold_another_object(can, "You make, but cannot pick up, %s.",
1440. 				      doname(can), (const char *)0);
1441. 	} else impossible("Tinning failed.");
1442. }
1443. 

use_unicorn_horn[]

1444. void
1445. use_unicorn_horn(obj)
1446. struct obj *obj;
1447. {
1448. #define PROP_COUNT 6		/* number of properties we're dealing with */
1449. #define ATTR_COUNT (A_MAX*3)	/* number of attribute points we might fix */
1450. 	int idx, val, val_limit,
1451. 	    trouble_count, unfixable_trbl, did_prop, did_attr;
1452. 	int trouble_list[PROP_COUNT + ATTR_COUNT];
1453. 
1454. 	if (obj && obj->cursed) {
1455. 	    long lcount = (long) rnd(100);
1456. 
1457. 	    switch (rn2(6)) {
1458. 	    case 0: make_sick(Sick ? Sick/3L + 1L : (long)rn1(ACURR(A_CON),20),
1459. 			xname(obj), TRUE, SICK_NONVOMITABLE);
1460. 		    break;
1461. 	    case 1: make_blinded(Blinded + lcount, TRUE);
1462. 		    break;
1463. 	    case 2: if (!Confusion)
1464. 			You("suddenly feel %s.",
1465. 			    Hallucination ? "trippy" : "confused");
1466. 		    make_confused(HConfusion + lcount, TRUE);
1467. 		    break;
1468. 	    case 3: make_stunned(HStun + lcount, TRUE);
1469. 		    break;
1470. 	    case 4: (void) adjattrib(rn2(A_MAX), -1, FALSE);
1471. 		    break;
1472. 	    case 5: (void) make_hallucinated(HHallucination + lcount, TRUE, 0L);
1473. 		    break;
1474. 	    }
1475. 	    return;
1476. 	}
1477. 
1478. /*
1479.  * Entries in the trouble list use a very simple encoding scheme.
1480.  */
1481. #define prop2trbl(X)	((X) + A_MAX)
1482. #define attr2trbl(Y)	(Y)
1483. #define prop_trouble(X) trouble_list[trouble_count++] = prop2trbl(X)
1484. #define attr_trouble(Y) trouble_list[trouble_count++] = attr2trbl(Y)
1485. 
1486. 	trouble_count = unfixable_trbl = did_prop = did_attr = 0;
1487. 
1488. 	/* collect property troubles */
1489. 	if (Sick) prop_trouble(SICK);
1490. 	if (Blinded > (long)u.ucreamed) prop_trouble(BLINDED);
1491. 	if (HHallucination) prop_trouble(HALLUC);
1492. 	if (Vomiting) prop_trouble(VOMITING);
1493. 	if (HConfusion) prop_trouble(CONFUSION);
1494. 	if (HStun) prop_trouble(STUNNED);
1495. 
1496. 	unfixable_trbl = unfixable_trouble_count(TRUE);
1497. 
1498. 	/* collect attribute troubles */
1499. 	for (idx = 0; idx < A_MAX; idx++) {
1500. 	    val_limit = AMAX(idx);
1501. 	    /* don't recover strength lost from hunger */
1502. 	    if (idx == A_STR && u.uhs >= WEAK) val_limit--;
1503. 	    /* don't recover more than 3 points worth of any attribute */
1504. 	    if (val_limit > ABASE(idx) + 3) val_limit = ABASE(idx) + 3;
1505. 
1506. 	    for (val = ABASE(idx); val < val_limit; val++)
1507. 		attr_trouble(idx);
1508. 	    /* keep track of unfixed trouble, for message adjustment below */
1509. 	    unfixable_trbl += (AMAX(idx) - val_limit);
1510. 	}
1511. 
1512. 	if (trouble_count == 0) {
1513. 	    pline(nothing_happens);
1514. 	    return;
1515. 	} else if (trouble_count > 1) {		/* shuffle */
1516. 	    int i, j, k;
1517. 
1518. 	    for (i = trouble_count - 1; i > 0; i--)
1519. 		if ((j = rn2(i + 1)) != i) {
1520. 		    k = trouble_list[j];
1521. 		    trouble_list[j] = trouble_list[i];
1522. 		    trouble_list[i] = k;
1523. 		}
1524. 	}
1525. 
1526. 	/*
1527. 	 *		Chances for number of troubles to be fixed
1528. 	 *		 0	1      2      3      4	    5	   6	  7
1529. 	 *   blessed:  22.7%  22.7%  19.5%  15.4%  10.7%   5.7%   2.6%	 0.8%
1530. 	 *  uncursed:  35.4%  35.4%  22.9%   6.3%    0	    0	   0	  0
1531. 	 */
1532. 	val_limit = rn2( d(2, (obj && obj->blessed) ? 4 : 2) );
1533. 	if (val_limit > trouble_count) val_limit = trouble_count;
1534. 
1535. 	/* fix [some of] the troubles */
1536. 	for (val = 0; val < val_limit; val++) {
1537. 	    idx = trouble_list[val];
1538. 
1539. 	    switch (idx) {
1540. 	    case prop2trbl(SICK):
1541. 		make_sick(0L, (char *) 0, TRUE, SICK_ALL);
1542. 		did_prop++;
1543. 		break;
1544. 	    case prop2trbl(BLINDED):
1545. 		make_blinded((long)u.ucreamed, TRUE);
1546. 		did_prop++;
1547. 		break;
1548. 	    case prop2trbl(HALLUC):
1549. 		(void) make_hallucinated(0L, TRUE, 0L);
1550. 		did_prop++;
1551. 		break;
1552. 	    case prop2trbl(VOMITING):
1553. 		make_vomiting(0L, TRUE);
1554. 		did_prop++;
1555. 		break;
1556. 	    case prop2trbl(CONFUSION):
1557. 		make_confused(0L, TRUE);
1558. 		did_prop++;
1559. 		break;
1560. 	    case prop2trbl(STUNNED):
1561. 		make_stunned(0L, TRUE);
1562. 		did_prop++;
1563. 		break;
1564. 	    default:
1565. 		if (idx >= 0 && idx < A_MAX) {
1566. 		    ABASE(idx) += 1;
1567. 		    did_attr++;
1568. 		} else
1569. 		    panic("use_unicorn_horn: bad trouble? (%d)", idx);
1570. 		break;
1571. 	    }
1572. 	}
1573. 
1574. 	if (did_attr)
1575. 	    pline("This makes you feel %s!",
1576. 		  (did_prop + did_attr) == (trouble_count + unfixable_trbl) ?
1577. 		  "great" : "better");
1578. 	else if (!did_prop)
1579. 	    pline("Nothing seems to happen.");
1580. 
1581. 	flags.botl = (did_attr || did_prop);
1582. #undef PROP_COUNT
1583. #undef ATTR_COUNT
1584. #undef prop2trbl
1585. #undef attr2trbl
1586. #undef prop_trouble
1587. #undef attr_trouble
1588. }
1589. 

fig_transform[]

1590. /*
1591.  * Timer callback routine: turn figurine into monster
1592.  */
1593. void
1594. fig_transform(arg, timeout)
1595. genericptr_t arg;
1596. long timeout;
1597. {
1598. 	struct obj *figurine = (struct obj *)arg;
1599. 	struct monst *mtmp;
1600. 	coord cc;
1601. 	boolean cansee_spot, silent, okay_spot;
1602. 	boolean redraw = FALSE;
1603. 	char monnambuf[BUFSZ], carriedby[BUFSZ];
1604. 
1605. 	if (!figurine) {
1606. #ifdef DEBUG
1607. 	    pline("null figurine in fig_transform()");
1608. #endif
1609. 	    return;
1610. 	}
1611. 	silent = (timeout != monstermoves); /* happened while away */
1612. 	okay_spot = get_obj_location(figurine, &cc.x, &cc.y, 0);
1613. 	if (figurine->where == OBJ_INVENT ||
1614. 	    figurine->where == OBJ_MINVENT)
1615. 		okay_spot = enexto(&cc, cc.x, cc.y,
1616. 				   &mons[figurine->corpsenm]);
1617. 	if (!okay_spot ||
1618. 	    !figurine_location_checks(figurine,&cc, TRUE)) {
1619. 		/* reset the timer to try again later */
1620. 		(void) start_timer((long)rnd(5000), TIMER_OBJECT,
1621. 				FIG_TRANSFORM, (genericptr_t)figurine);
1622. 		return;
1623. 	}
1624. 
1625. 	cansee_spot = cansee(cc.x, cc.y);
1626. 	mtmp = make_familiar(figurine, cc.x, cc.y, TRUE);
1627. 	if (mtmp) {
1628. 	    Sprintf(monnambuf, "%s",an(m_monnam(mtmp)));
1629. 	    switch (figurine->where) {
1630. 		case OBJ_INVENT:
1631. 		    if (Blind)
1632. 			You_feel("%s %s from your pack!", something,
1633. 			    locomotion(mtmp->data,"drop"));
1634. 		    else
1635. 			You("see %s %s out of your pack!",
1636. 			    monnambuf,
1637. 			    locomotion(mtmp->data,"drop"));
1638. 		    break;
1639. 
1640. 		case OBJ_FLOOR:
1641. 		    if (cansee_spot && !silent) {
1642. 			You("suddenly see a figurine transform into %s!",
1643. 				monnambuf);
1644. 			redraw = TRUE;	/* update figurine's map location */
1645. 		    }
1646. 		    break;
1647. 
1648. 		case OBJ_MINVENT:
1649. 		    if (cansee_spot && !silent) {
1650. 			struct monst *mon;
1651. 			mon = figurine->ocarry;
1652. 			/* figurine carring monster might be invisible */
1653. 			if (canseemon(figurine->ocarry)) {
1654. 			    Sprintf(carriedby, "%s pack",
1655. 				     s_suffix(a_monnam(mon)));
1656. 			}
1657. 			else if (is_pool(mon->mx, mon->my))
1658. 			    Strcpy(carriedby, "empty water");
1659. 			else
1660. 			    Strcpy(carriedby, "thin air");
1661. 			You("see %s %s out of %s!", monnambuf,
1662. 			    locomotion(mtmp->data, "drop"), carriedby);
1663. 		    }
1664. 		    break;
1665. #if 0
1666. 		case OBJ_MIGRATING:
1667. 		    break;
1668. #endif
1669. 
1670. 		default:
1671. 		    impossible("figurine came to life where? (%d)",
1672. 				(int)figurine->where);
1673. 		break;
1674. 	    }
1675. 	}
1676. 	/* free figurine now */
1677. 	obj_extract_self(figurine);
1678. 	obfree(figurine, (struct obj *)0);
1679. 	if (redraw) newsym(cc.x, cc.y);
1680. }
1681. 

figurine_location_checks[]

1682. STATIC_OVL boolean
1683. figurine_location_checks(obj, cc, quietly)
1684. struct obj *obj;
1685. coord *cc;
1686. boolean quietly;
1687. {
1688. 	xchar x,y;
1689. 
1690. 	if (carried(obj) && u.uswallow) {
1691. 		if (!quietly)
1692. 			You("don't have enough room in here.");
1693. 		return FALSE;
1694. 	}
1695. 	x = cc->x; y = cc->y;
1696. 	if (!isok(x,y)) {
1697. 		if (!quietly)
1698. 			You("cannot put the figurine there.");
1699. 		return FALSE;
1700. 	}
1701. 	if (IS_ROCK(levl[x][y].typ) &&
1702. 	    !(passes_walls(&mons[obj->corpsenm]) && may_passwall(x,y))) {
1703. 		if (!quietly)
1704. 		    You("cannot place a figurine in %s!",
1705. 			IS_TREE(levl[x][y].typ) ? "a tree" : "solid rock");
1706. 		return FALSE;
1707. 	}
1708. 	if (sobj_at(BOULDER,x,y) && !passes_walls(&mons[obj->corpsenm])
1709. 			&& !throws_rocks(&mons[obj->corpsenm])) {
1710. 		if (!quietly)
1711. 			You("cannot fit the figurine on the boulder.");
1712. 		return FALSE;
1713. 	}
1714. 	return TRUE;
1715. }
1716. 

use_figurine[]

1717. STATIC_OVL void
1718. use_figurine(optr)
1719. struct obj **optr;
1720. {
1721. 	register struct obj *obj = *optr;
1722. 	xchar x, y;
1723. 	coord cc;
1724. 
1725. 	if (u.uswallow) {
1726. 		/* can't activate a figurine while swallowed */
1727. 		if (!figurine_location_checks(obj, (coord *)0, FALSE))
1728. 			return;
1729. 	}
1730. 	if(!getdir((char *)0)) {
1731. 		flags.move = multi = 0;
1732. 		return;
1733. 	}
1734. 	x = u.ux + u.dx; y = u.uy + u.dy;
1735. 	cc.x = x; cc.y = y;
1736. 	/* Passing FALSE arg here will result in messages displayed */
1737. 	if (!figurine_location_checks(obj, &cc, FALSE)) return;
1738. 	You("%s and it transforms.",
1739. 	    (u.dx||u.dy) ? "set the figurine beside you" :
1740. 	    (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ||
1741. 	     is_pool(cc.x, cc.y)) ?
1742. 		"release the figurine" :
1743. 	    (u.dz < 0 ?
1744. 		"toss the figurine into the air" :
1745. 		"set the figurine on the ground"));
1746. 	(void) make_familiar(obj, cc.x, cc.y, FALSE);
1747. 	(void) stop_timer(FIG_TRANSFORM, (genericptr_t)obj);
1748. 	useup(obj);
1749. 	*optr = 0;
1750. }
1751. 

use_grease[]

1752. static NEARDATA const char lubricables[] = { ALL_CLASSES, ALLOW_NONE, 0 };
1753. static NEARDATA const char need_to_remove_outer_armor[] =
1754. 			"need to remove your %s to grease your %s.";
1755. 
1756. STATIC_OVL void
1757. use_grease(obj)
1758. struct obj *obj;
1759. {
1760. 	struct obj *otmp;
1761. 	char buf[BUFSZ];
1762. 
1763. 	if (Glib) {
1764. 	    pline("%s from your %s.", Tobjnam(obj, "slip"),
1765. 		  makeplural(body_part(FINGER)));
1766. 	    dropx(obj);
1767. 	    return;
1768. 	}
1769. 
1770. 	if (obj->spe > 0) {
1771. 		if ((obj->cursed || Fumbling) && !rn2(2)) {
1772. 			consume_obj_charge(obj, TRUE);
1773. 
1774. 			pline("%s from your %s.", Tobjnam(obj, "slip"),
1775. 			      makeplural(body_part(FINGER)));
1776. 			dropx(obj);
1777. 			return;
1778. 		}
1779. 		otmp = getobj(lubricables, "grease");
1780. 		if (!otmp) return;
1781. 		if ((otmp->owornmask & WORN_ARMOR) && uarmc) {
1782. 			Strcpy(buf, xname(uarmc));
1783. 			You(need_to_remove_outer_armor, buf, xname(otmp));
1784. 			return;
1785. 		}
1786. #ifdef TOURIST
1787. 		if ((otmp->owornmask & WORN_SHIRT) && (uarmc || uarm)) {
1788. 			Strcpy(buf, uarmc ? xname(uarmc) : "");
1789. 			if (uarmc && uarm) Strcat(buf, " and ");
1790. 			Strcat(buf, uarm ? xname(uarm) : "");
1791. 			You(need_to_remove_outer_armor, buf, xname(otmp));
1792. 			return;
1793. 		}
1794. #endif
1795. 		consume_obj_charge(obj, TRUE);
1796. 
1797. 		if (otmp != &zeroobj) {
1798. 			You("cover %s with a thick layer of grease.",
1799. 			    yname(otmp));
1800. 			otmp->greased = 1;
1801. 			if (obj->cursed && !nohands(youmonst.data)) {
1802. 			    incr_itimeout(&Glib, rnd(15));
1803. 			    pline("Some of the grease gets all over your %s.",
1804. 				makeplural(body_part(HAND)));
1805. 			}
1806. 		} else {
1807. 			Glib += rnd(15);
1808. 			You("coat your %s with grease.",
1809. 			    makeplural(body_part(FINGER)));
1810. 		}
1811. 	} else {
1812. 	    if (obj->known)
1813. 		pline("%s empty.", Tobjnam(obj, "are"));
1814. 	    else
1815. 		pline("%s to be empty.", Tobjnam(obj, "seem"));
1816. 	}
1817. 	update_inventory();
1818. }
1819. 

reset_trapset[]

1820. static struct trapinfo {
1821. 	struct obj *tobj;
1822. 	xchar tx, ty;
1823. 	int time_needed;
1824. 	boolean force_bungle;
1825. } trapinfo;
1826. 
1827. void
1828. reset_trapset()
1829. {
1830. 	trapinfo.tobj = 0;
1831. 	trapinfo.force_bungle = 0;
1832. }
1833. 

use_stone[]

1834. /* touchstones - by Ken Arnold */
1835. STATIC_OVL void
1836. use_stone(tstone)
1837. struct obj *tstone;
1838. {
1839.     struct obj *obj;
1840.     boolean do_scratch;
1841.     const char *streak_color, *choices;
1842.     char stonebuf[QBUFSZ];
1843.     static const char scritch[] = "\"scritch, scritch\"";
1844.     static const char allowall[3] = { COIN_CLASS, ALL_CLASSES, 0 };
1845.     static const char justgems[3] = { ALLOW_NONE, GEM_CLASS, 0 };
1846. #ifndef GOLDOBJ
1847.     struct obj goldobj;
1848. #endif
1849. 
1850.     /* in case it was acquired while blinded */
1851.     if (!Blind) tstone->dknown = 1;
1852.     /* when the touchstone is fully known, don't bother listing extra
1853.        junk as likely candidates for rubbing */
1854.     choices = (tstone->otyp == TOUCHSTONE && tstone->dknown &&
1855. 		objects[TOUCHSTONE].oc_name_known) ? justgems : allowall;
1856.     Sprintf(stonebuf, "rub on the stone%s", plur(tstone->quan));
1857.     if ((obj = getobj(choices, stonebuf)) == 0)
1858. 	return;
1859. #ifndef GOLDOBJ
1860.     if (obj->oclass == COIN_CLASS) {
1861. 	u.ugold += obj->quan;	/* keep botl up to date */
1862. 	goldobj = *obj;
1863. 	dealloc_obj(obj);
1864. 	obj = &goldobj;
1865.     }
1866. #endif
1867. 
1868.     if (obj == tstone && obj->quan == 1) {
1869. 	You_cant("rub %s on itself.", the(xname(obj)));
1870. 	return;
1871.     }
1872. 
1873.     if (tstone->otyp == TOUCHSTONE && tstone->cursed &&
1874. 	    obj->oclass == GEM_CLASS && !is_graystone(obj) &&
1875. 	    !obj_resists(obj, 80, 100)) {
1876. 	if (Blind)
1877. 	    pline("You feel something shatter.");
1878. 	else if (Hallucination)
1879. 	    pline("Oh, wow, look at the pretty shards.");
1880. 	else
1881. 	    pline("A sharp crack shatters %s%s.",
1882. 		  (obj->quan > 1) ? "one of " : "", the(xname(obj)));
1883. #ifndef GOLDOBJ
1884.      /* assert(obj != &goldobj); */
1885. #endif
1886. 	useup(obj);
1887. 	return;
1888.     }
1889. 
1890.     if (Blind) {
1891. 	pline(scritch);
1892. 	return;
1893.     } else if (Hallucination) {
1894. 	pline("Oh wow, man: Fractals!");
1895. 	return;
1896.     }
1897. 
1898.     do_scratch = FALSE;
1899.     streak_color = 0;
1900. 
1901.     switch (obj->oclass) {
1902.     case GEM_CLASS:	/* these have class-specific handling below */
1903.     case RING_CLASS:
1904. 	if (tstone->otyp != TOUCHSTONE) {
1905. 	    do_scratch = TRUE;
1906. 	} else if (obj->oclass == GEM_CLASS && (tstone->blessed ||
1907. 		(!tstone->cursed &&
1908. 		    (Role_if(PM_ARCHEOLOGIST) || Race_if(PM_GNOME))))) {
1909. 	    makeknown(TOUCHSTONE);
1910. 	    makeknown(obj->otyp);
1911. 	    prinv((char *)0, obj, 0L);
1912. 	    return;
1913. 	} else {
1914. 	    /* either a ring or the touchstone was not effective */
1915. 	    if (objects[obj->otyp].oc_material == GLASS) {
1916. 		do_scratch = TRUE;
1917. 		break;
1918. 	    }
1919. 	}
1920. 	streak_color = c_obj_colors[objects[obj->otyp].oc_color];
1921. 	break;		/* gem or ring */
1922. 
1923.     default:
1924. 	switch (objects[obj->otyp].oc_material) {
1925. 	case CLOTH:
1926. 	    pline("%s a little more polished now.", Tobjnam(tstone, "look"));
1927. 	    return;
1928. 	case LIQUID:
1929. 	    if (!obj->known)		/* note: not "whetstone" */
1930. 		You("must think this is a wetstone, do you?");
1931. 	    else
1932. 		pline("%s a little wetter now.", Tobjnam(tstone, "are"));
1933. 	    return;
1934. 	case WAX:
1935. 	    streak_color = "waxy";
1936. 	    break;		/* okay even if not touchstone */
1937. 	case WOOD:
1938. 	    streak_color = "wooden";
1939. 	    break;		/* okay even if not touchstone */
1940. 	case GOLD:
1941. 	    do_scratch = TRUE;	/* scratching and streaks */
1942. 	    streak_color = "golden";
1943. 	    break;
1944. 	case SILVER:
1945. 	    do_scratch = TRUE;	/* scratching and streaks */
1946. 	    streak_color = "silvery";
1947. 	    break;
1948. 	default:
1949. 	    /* Objects passing the is_flimsy() test will not
1950. 	       scratch a stone.  They will leave streaks on
1951. 	       non-touchstones and touchstones alike. */
1952. 	    if (is_flimsy(obj))
1953. 		streak_color = c_obj_colors[objects[obj->otyp].oc_color];
1954. 	    else
1955. 		do_scratch = (tstone->otyp != TOUCHSTONE);
1956. 	    break;
1957. 	}
1958. 	break;		/* default oclass */
1959.     }
1960. 
1961.     Sprintf(stonebuf, "stone%s", plur(tstone->quan));
1962.     if (do_scratch)
1963. 	pline("You make %s%sscratch marks on the %s.",
1964. 	      streak_color ? streak_color : (const char *)"",
1965. 	      streak_color ? " " : "", stonebuf);
1966.     else if (streak_color)
1967. 	pline("You see %s streaks on the %s.", streak_color, stonebuf);
1968.     else
1969. 	pline(scritch);
1970.     return;
1971. }
1972. 

use_trap[]

1973. /* Place a landmine/bear trap.  Helge Hafting */
1974. STATIC_OVL void
1975. use_trap(otmp)
1976. struct obj *otmp;
1977. {
1978. 	int ttyp, tmp;
1979. 	const char *what = (char *)0;
1980. 	char buf[BUFSZ];
1981. 	const char *occutext = "setting the trap";
1982. 
1983. 	if (nohands(youmonst.data))
1984. 	    what = "without hands";
1985. 	else if (Stunned)
1986. 	    what = "while stunned";
1987. 	else if (u.uswallow)
1988. 	    what = is_animal(u.ustuck->data) ? "while swallowed" :
1989. 			"while engulfed";
1990. 	else if (Underwater)
1991. 	    what = "underwater";
1992. 	else if (Levitation)
1993. 	    what = "while levitating";
1994. 	else if (is_pool(u.ux, u.uy))
1995. 	    what = "in water";
1996. 	else if (is_lava(u.ux, u.uy))
1997. 	    what = "in lava";
1998. 	else if (On_stairs(u.ux, u.uy))
1999. 	    what = (u.ux == xdnladder || u.ux == xupladder) ?
2000. 			"on the ladder" : "on the stairs";
2001. 	else if (IS_FURNITURE(levl[u.ux][u.uy].typ) ||
2002. 		IS_ROCK(levl[u.ux][u.uy].typ) ||
2003. 		closed_door(u.ux, u.uy) || t_at(u.ux, u.uy))
2004. 	    what = "here";
2005. 	if (what) {
2006. 	    You_cant("set a trap %s!",what);
2007. 	    reset_trapset();
2008. 	    return;
2009. 	}
2010. 	ttyp = (otmp->otyp == LAND_MINE) ? LANDMINE : BEAR_TRAP;
2011. 	if (otmp == trapinfo.tobj &&
2012. 		u.ux == trapinfo.tx && u.uy == trapinfo.ty) {
2013. 	    You("resume setting %s %s.",
2014. 		shk_your(buf, otmp),
2015. 		defsyms[trap_to_defsym(what_trap(ttyp))].explanation);
2016. 	    set_occupation(set_trap, occutext, 0);
2017. 	    return;
2018. 	}
2019. 	trapinfo.tobj = otmp;
2020. 	trapinfo.tx = u.ux,  trapinfo.ty = u.uy;
2021. 	tmp = ACURR(A_DEX);
2022. 	trapinfo.time_needed = (tmp > 17) ? 2 : (tmp > 12) ? 3 :
2023. 				(tmp > 7) ? 4 : 5;
2024. 	if (Blind) trapinfo.time_needed *= 2;
2025. 	tmp = ACURR(A_STR);
2026. 	if (ttyp == BEAR_TRAP && tmp < 18)
2027. 	    trapinfo.time_needed += (tmp > 12) ? 1 : (tmp > 7) ? 2 : 4;
2028. 	/*[fumbling and/or confusion and/or cursed object check(s)
2029. 	   should be incorporated here instead of in set_trap]*/
2030. #ifdef STEED
2031. 	if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) {
2032. 	    boolean chance;
2033. 
2034. 	    if (Fumbling || otmp->cursed) chance = (rnl(10) > 3);
2035. 	    else  chance = (rnl(10) > 5);
2036. 	    You("aren't very skilled at reaching from %s.",
2037. 		mon_nam(u.usteed));
2038. 	    Sprintf(buf, "Continue your attempt to set %s?",
2039. 		the(defsyms[trap_to_defsym(what_trap(ttyp))].explanation));
2040. 	    if(yn(buf) == 'y') {
2041. 		if (chance) {
2042. 			switch(ttyp) {
2043. 			    case LANDMINE:	/* set it off */
2044. 			    	trapinfo.time_needed = 0;
2045. 			    	trapinfo.force_bungle = TRUE;
2046. 				break;
2047. 			    case BEAR_TRAP:	/* drop it without arming it */
2048. 				reset_trapset();
2049. 				You("drop %s!",
2050. 			  the(defsyms[trap_to_defsym(what_trap(ttyp))].explanation));
2051. 				dropx(otmp);
2052. 				return;
2053. 			}
2054. 		}
2055. 	    } else {
2056. 	    	reset_trapset();
2057. 		return;
2058. 	    }
2059. 	}
2060. #endif
2061. 	You("begin setting %s %s.",
2062. 	    shk_your(buf, otmp),
2063. 	    defsyms[trap_to_defsym(what_trap(ttyp))].explanation);
2064. 	set_occupation(set_trap, occutext, 0);
2065. 	return;
2066. }
2067. 

set_trap[]

2068. STATIC_PTR
2069. int
2070. set_trap()
2071. {
2072. 	struct obj *otmp = trapinfo.tobj;
2073. 	struct trap *ttmp;
2074. 	int ttyp;
2075. 
2076. 	if (!otmp || !carried(otmp) ||
2077. 		u.ux != trapinfo.tx || u.uy != trapinfo.ty) {
2078. 	    /* ?? */
2079. 	    reset_trapset();
2080. 	    return 0;
2081. 	}
2082. 
2083. 	if (--trapinfo.time_needed > 0) return 1;	/* still busy */
2084. 
2085. 	ttyp = (otmp->otyp == LAND_MINE) ? LANDMINE : BEAR_TRAP;
2086. 	ttmp = maketrap(u.ux, u.uy, ttyp);
2087. 	if (ttmp) {
2088. 	    ttmp->tseen = 1;
2089. 	    ttmp->madeby_u = 1;
2090. 	    newsym(u.ux, u.uy); /* if our hero happens to be invisible */
2091. 	    if (*in_rooms(u.ux,u.uy,SHOPBASE)) {
2092. 		add_damage(u.ux, u.uy, 0L);		/* schedule removal */
2093. 	    }
2094. 	    if (!trapinfo.force_bungle)
2095. 		You("finish arming %s.",
2096. 			the(defsyms[trap_to_defsym(what_trap(ttyp))].explanation));
2097. 	    if (((otmp->cursed || Fumbling) && (rnl(10) > 5)) || trapinfo.force_bungle)
2098. 		dotrap(ttmp,
2099. 			(unsigned)(trapinfo.force_bungle ? FORCEBUNGLE : 0));
2100. 	} else {
2101. 	    /* this shouldn't happen */
2102. 	    Your("trap setting attempt fails.");
2103. 	}
2104. 	useup(otmp);
2105. 	reset_trapset();
2106. 	return 0;
2107. }
2108. 

use_whip[]

2109. STATIC_OVL int
2110. use_whip(obj)
2111. struct obj *obj;
2112. {
2113.     char buf[BUFSZ];
2114.     struct monst *mtmp;
2115.     struct obj *otmp;
2116.     int rx, ry, proficient, res = 0;
2117.     const char *msg_slipsfree = "The bullwhip slips free.";
2118.     const char *msg_snap = "Snap!";
2119. 
2120.     if (obj != uwep) {
2121. 	if (!wield_tool(obj, "lash")) return 0;
2122. 	else res = 1;
2123.     }
2124.     if (!getdir((char *)0)) return res;
2125. 
2126.     if (Stunned || (Confusion && !rn2(5))) confdir();
2127.     rx = u.ux + u.dx;
2128.     ry = u.uy + u.dy;
2129.     mtmp = m_at(rx, ry);
2130. 
2131.     /* fake some proficiency checks */
2132.     proficient = 0;
2133.     if (Role_if(PM_ARCHEOLOGIST)) ++proficient;
2134.     if (ACURR(A_DEX) < 6) proficient--;
2135.     else if (ACURR(A_DEX) >= 14) proficient += (ACURR(A_DEX) - 14);
2136.     if (Fumbling) --proficient;
2137.     if (proficient > 3) proficient = 3;
2138.     if (proficient < 0) proficient = 0;
2139. 
2140.     if (u.uswallow && attack(u.ustuck)) {
2141. 	There("is not enough room to flick your bullwhip.");
2142. 
2143.     } else if (Underwater) {
2144. 	There("is too much resistance to flick your bullwhip.");
2145. 
2146.     } else if (u.dz < 0) {
2147. 	You("flick a bug off of the %s.",ceiling(u.ux,u.uy));
2148. 
2149.     } else if ((!u.dx && !u.dy) || (u.dz > 0)) {
2150. 	int dam;
2151. 
2152. #ifdef STEED
2153. 	/* Sometimes you hit your steed by mistake */
2154. 	if (u.usteed && !rn2(proficient + 2)) {
2155. 	    You("whip %s!", mon_nam(u.usteed));
2156. 	    kick_steed();
2157. 	    return 1;
2158. 	}
2159. #endif
2160. 	if (Levitation
2161. #ifdef STEED
2162. 			|| u.usteed
2163. #endif
2164. 		) {
2165. 	    /* Have a shot at snaring something on the floor */
2166. 	    otmp = level.objects[u.ux][u.uy];
2167. 	    if (otmp && otmp->otyp == CORPSE && otmp->corpsenm == PM_HORSE) {
2168. 		pline("Why beat a dead horse?");
2169. 		return 1;
2170. 	    }
2171. 	    if (otmp && proficient) {
2172. 		You("wrap your bullwhip around %s on the %s.",
2173. 		    an(singular(otmp, xname)), surface(u.ux, u.uy));
2174. 		if (rnl(6) || pickup_object(otmp, 1L, TRUE) < 1)
2175. 		    pline(msg_slipsfree);
2176. 		return 1;
2177. 	    }
2178. 	}
2179. 	dam = rnd(2) + dbon() + obj->spe;
2180. 	if (dam <= 0) dam = 1;
2181. 	You("hit your %s with your bullwhip.", body_part(FOOT));
2182. 	Sprintf(buf, "killed %sself with %s bullwhip", uhim(), uhis());
2183. 	losehp(dam, buf, NO_KILLER_PREFIX);
2184. 	flags.botl = 1;
2185. 	return 1;
2186. 
2187.     } else if ((Fumbling || Glib) && !rn2(5)) {
2188. 	pline_The("bullwhip slips out of your %s.", body_part(HAND));
2189. 	dropx(obj);
2190. 
2191.     } else if (u.utrap && u.utraptype == TT_PIT) {
2192. 	/*
2193. 	 *     Assumptions:
2194. 	 *
2195. 	 *	if you're in a pit
2196. 	 *		- you are attempting to get out of the pit
2197. 	 *		- or, if you are applying it towards a small
2198. 	 *		  monster then it is assumed that you are
2199. 	 *		  trying to hit it.
2200. 	 *	else if the monster is wielding a weapon
2201. 	 *		- you are attempting to disarm a monster
2202. 	 *	else
2203. 	 *		- you are attempting to hit the monster
2204. 	 *
2205. 	 *	if you're confused (and thus off the mark)
2206. 	 *		- you only end up hitting.
2207. 	 *
2208. 	 */
2209. 	const char *wrapped_what = (char *)0;
2210. 
2211. 	if (mtmp) {
2212. 	    if (bigmonst(mtmp->data)) {
2213. 		wrapped_what = strcpy(buf, mon_nam(mtmp));
2214. 	    } else if (proficient) {
2215. 		if (attack(mtmp)) return 1;
2216. 		else pline(msg_snap);
2217. 	    }
2218. 	}
2219. 	if (!wrapped_what) {
2220. 	    if (IS_FURNITURE(levl[rx][ry].typ))
2221. 		wrapped_what = something;
2222. 	    else if (sobj_at(BOULDER, rx, ry))
2223. 		wrapped_what = "a boulder";
2224. 	}
2225. 	if (wrapped_what) {
2226. 	    coord cc;
2227. 
2228. 	    cc.x = rx; cc.y = ry;
2229. 	    You("wrap your bullwhip around %s.", wrapped_what);
2230. 	    if (proficient && rn2(proficient + 2)) {
2231. 		if (!mtmp || enexto(&cc, rx, ry, youmonst.data)) {
2232. 		    You("yank yourself out of the pit!");
2233. 		    teleds(cc.x, cc.y, TRUE);
2234. 		    u.utrap = 0;
2235. 		    vision_full_recalc = 1;
2236. 		}
2237. 	    } else {
2238. 		pline(msg_slipsfree);
2239. 	    }
2240. 	    if (mtmp) wakeup(mtmp);
2241. 	} else pline(msg_snap);
2242. 
2243.     } else if (mtmp) {
2244. 	if (!canspotmon(mtmp) &&
2245. 		!glyph_is_invisible(levl[rx][ry].glyph)) {
2246. 	   pline("A monster is there that you couldn't see.");
2247. 	   map_invisible(rx, ry);
2248. 	}
2249. 	otmp = MON_WEP(mtmp);	/* can be null */
2250. 	if (otmp) {
2251. 	    char onambuf[BUFSZ];
2252. 	    const char *mon_hand;
2253. 	    boolean gotit = proficient && (!Fumbling || !rn2(10));
2254. 
2255. 	    Strcpy(onambuf, cxname(otmp));
2256. 	    if (gotit) {
2257. 		mon_hand = mbodypart(mtmp, HAND);
2258. 		if (bimanual(otmp)) mon_hand = makeplural(mon_hand);
2259. 	    } else
2260. 		mon_hand = 0;	/* lint suppression */
2261. 
2262. 	    You("wrap your bullwhip around %s %s.",
2263. 		s_suffix(mon_nam(mtmp)), onambuf);
2264. 	    if (gotit && otmp->cursed) {
2265. 		pline("%s welded to %s %s%c",
2266. 		      (otmp->quan == 1L) ? "It is" : "They are",
2267. 		      mhis(mtmp), mon_hand,
2268. 		      !otmp->bknown ? '!' : '.');
2269. 		otmp->bknown = 1;
2270. 		gotit = FALSE;	/* can't pull it free */
2271. 	    }
2272. 	    if (gotit) {
2273. 		obj_extract_self(otmp);
2274. 		possibly_unwield(mtmp, FALSE);
2275. 		setmnotwielded(mtmp,otmp);
2276. 
2277. 		switch (rn2(proficient + 1)) {
2278. 		case 2:
2279. 		    /* to floor near you */
2280. 		    You("yank %s %s to the %s!", s_suffix(mon_nam(mtmp)),
2281. 			onambuf, surface(u.ux, u.uy));
2282. 		    place_object(otmp, u.ux, u.uy);
2283. 		    stackobj(otmp);
2284. 		    break;
2285. 		case 3:
2286. 		    /* right to you */
2287. #if 0
2288. 		    if (!rn2(25)) {
2289. 			/* proficient with whip, but maybe not
2290. 			   so proficient at catching weapons */
2291. 			int hitu, hitvalu;
2292. 
2293. 			hitvalu = 8 + otmp->spe;
2294. 			hitu = thitu(hitvalu,
2295. 				     dmgval(otmp, &youmonst),
2296. 				     otmp, (char *)0);
2297. 			if (hitu) {
2298. 			    pline_The("%s hits you as you try to snatch it!",
2299. 				the(onambuf));
2300. 			}
2301. 			place_object(otmp, u.ux, u.uy);
2302. 			stackobj(otmp);
2303. 			break;
2304. 		    }
2305. #endif /* 0 */
2306. 		    /* right into your inventory */
2307. 		    You("snatch %s %s!", s_suffix(mon_nam(mtmp)), onambuf);
2308. 		    if (otmp->otyp == CORPSE &&
2309. 			    touch_petrifies(&mons[otmp->corpsenm]) &&
2310. 			    !uarmg && !Stone_resistance &&
2311. 			    !(poly_when_stoned(youmonst.data) &&
2312. 				polymon(PM_STONE_GOLEM))) {
2313. 			char kbuf[BUFSZ];
2314. 
2315. 			Sprintf(kbuf, "%s corpse",
2316. 				an(mons[otmp->corpsenm].mname));
2317. 			pline("Snatching %s is a fatal mistake.", kbuf);
2318. 			instapetrify(kbuf);
2319. 		    }
2320. 		    otmp = hold_another_object(otmp, "You drop %s!",
2321. 					       doname(otmp), (const char *)0);
2322. 		    break;
2323. 		default:
2324. 		    /* to floor beneath mon */
2325. 		    You("yank %s from %s %s!", the(onambuf),
2326. 			s_suffix(mon_nam(mtmp)), mon_hand);
2327. 		    obj_no_longer_held(otmp);
2328. 		    place_object(otmp, mtmp->mx, mtmp->my);
2329. 		    stackobj(otmp);
2330. 		    break;
2331. 		}
2332. 	    } else {
2333. 		pline(msg_slipsfree);
2334. 	    }
2335. 	    wakeup(mtmp);
2336. 	} else {
2337. 	    if (mtmp->m_ap_type &&
2338. 		!Protection_from_shape_changers && !sensemon(mtmp))
2339. 		stumble_onto_mimic(mtmp);
2340. 	    else You("flick your bullwhip towards %s.", mon_nam(mtmp));
2341. 	    if (proficient) {
2342. 		if (attack(mtmp)) return 1;
2343. 		else pline(msg_snap);
2344. 	    }
2345. 	}
2346. 
2347.     } else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
2348. 	    /* it must be air -- water checked above */
2349. 	    You("snap your whip through thin air.");
2350. 
2351.     } else {
2352. 	pline(msg_snap);
2353. 
2354.     }
2355.     return 1;
2356. }
2357. 
2358. 

use_pole[]

2359. static const char
2360. 	not_enough_room[] = "There's not enough room here to use that.",
2361. 	where_to_hit[] = "Where do you want to hit?",
2362. 	cant_see_spot[] = "won't hit anything if you can't see that spot.",
2363. 	cant_reach[] = "can't reach that spot from here.";
2364. 
2365. /* Distance attacks by pole-weapons */
2366. STATIC_OVL int
2367. use_pole (obj)
2368. 	struct obj *obj;
2369. {
2370. 	int res = 0, typ, max_range = 4, min_range = 4;
2371. 	coord cc;
2372. 	struct monst *mtmp;
2373. 
2374. 
2375. 	/* Are you allowed to use the pole? */
2376. 	if (u.uswallow) {
2377. 	    pline(not_enough_room);
2378. 	    return (0);
2379. 	}
2380. 	if (obj != uwep) {
2381. 	    if (!wield_tool(obj, "swing")) return(0);
2382. 	    else res = 1;
2383. 	}
2384.      /* assert(obj == uwep); */
2385. 
2386. 	/* Prompt for a location */
2387. 	pline(where_to_hit);
2388. 	cc.x = u.ux;
2389. 	cc.y = u.uy;
2390. 	if (getpos(&cc, TRUE, "the spot to hit") < 0)
2391. 	    return 0;	/* user pressed ESC */
2392. 
2393. 	/* Calculate range */
2394. 	typ = uwep_skill_type();
2395. 	if (typ == P_NONE || P_SKILL(typ) <= P_BASIC) max_range = 4;
2396. 	else if (P_SKILL(typ) == P_SKILLED) max_range = 5;
2397. 	else max_range = 8;
2398. 	if (distu(cc.x, cc.y) > max_range) {
2399. 	    pline("Too far!");
2400. 	    return (res);
2401. 	} else if (distu(cc.x, cc.y) < min_range) {
2402. 	    pline("Too close!");
2403. 	    return (res);
2404. 	} else if (!cansee(cc.x, cc.y) &&
2405. 		   ((mtmp = m_at(cc.x, cc.y)) == (struct monst *)0 ||
2406. 		    !canseemon(mtmp))) {
2407. 	    You(cant_see_spot);
2408. 	    return (res);
2409. 	} else if (!couldsee(cc.x, cc.y)) { /* Eyes of the Overworld */
2410. 	    You(cant_reach);
2411. 	    return res;
2412. 	}
2413. 
2414. 	/* Attack the monster there */
2415. 	if ((mtmp = m_at(cc.x, cc.y)) != (struct monst *)0) {
2416. 	    int oldhp = mtmp->mhp;
2417. 
2418. 	    bhitpos = cc;
2419. 	    check_caitiff(mtmp);
2420. 	    (void) thitmonst(mtmp, uwep);
2421. 	    /* check the monster's HP because thitmonst() doesn't return
2422. 	     * an indication of whether it hit.  Not perfect (what if it's a
2423. 	     * non-silver weapon on a shade?)
2424. 	     */
2425. 	    if (mtmp->mhp < oldhp)
2426. 		u.uconduct.weaphit++;
2427. 	} else
2428. 	    /* Now you know that nothing is there... */
2429. 	    pline(nothing_happens);
2430. 	return (1);
2431. }
2432. 

use_cream_pie[]

2433. STATIC_OVL int
2434. use_cream_pie(obj)
2435. struct obj *obj;
2436. {
2437. 	boolean wasblind = Blind;
2438. 	boolean wascreamed = u.ucreamed;
2439. 	boolean several = FALSE;
2440. 
2441. 	if (obj->quan > 1L) {
2442. 		several = TRUE;
2443. 		obj = splitobj(obj, 1L);
2444. 	}
2445. 	if (Hallucination)
2446. 		You("give yourself a facial.");
2447. 	else
2448. 		pline("You immerse your %s in %s%s.", body_part(FACE),
2449. 			several ? "one of " : "",
2450. 			several ? makeplural(the(xname(obj))) : the(xname(obj)));
2451. 	if(can_blnd((struct monst*)0, &youmonst, AT_WEAP, obj)) {
2452. 		int blindinc = rnd(25);
2453. 		u.ucreamed += blindinc;
2454. 		make_blinded(Blinded + (long)blindinc, FALSE);
2455. 		if (!Blind || (Blind && wasblind))
2456. 			pline("There's %ssticky goop all over your %s.",
2457. 				wascreamed ? "more " : "",
2458. 				body_part(FACE));
2459. 		else /* Blind  && !wasblind */
2460. 			You_cant("see through all the sticky goop on your %s.",
2461. 				body_part(FACE));
2462. 	}
2463. 	if (obj->unpaid) {
2464. 		verbalize("You used it, you bought it!");
2465. 		bill_dummy_object(obj);
2466. 	}
2467. 	obj_extract_self(obj);
2468. 	delobj(obj);
2469. 	return(0);
2470. }
2471. 

use_grapple[]

2472. STATIC_OVL int
2473. use_grapple (obj)
2474. 	struct obj *obj;
2475. {
2476. 	int res = 0, typ, max_range = 4, tohit;
2477. 	coord cc;
2478. 	struct monst *mtmp;
2479. 	struct obj *otmp;
2480. 
2481. 	/* Are you allowed to use the hook? */
2482. 	if (u.uswallow) {
2483. 	    pline(not_enough_room);
2484. 	    return (0);
2485. 	}
2486. 	if (obj != uwep) {
2487. 	    if (!wield_tool(obj, "cast")) return(0);
2488. 	    else res = 1;
2489. 	}
2490.      /* assert(obj == uwep); */
2491. 
2492. 	/* Prompt for a location */
2493. 	pline(where_to_hit);
2494. 	cc.x = u.ux;
2495. 	cc.y = u.uy;
2496. 	if (getpos(&cc, TRUE, "the spot to hit") < 0)
2497. 	    return 0;	/* user pressed ESC */
2498. 
2499. 	/* Calculate range */
2500. 	typ = uwep_skill_type();
2501. 	if (typ == P_NONE || P_SKILL(typ) <= P_BASIC) max_range = 4;
2502. 	else if (P_SKILL(typ) == P_SKILLED) max_range = 5;
2503. 	else max_range = 8;
2504. 	if (distu(cc.x, cc.y) > max_range) {
2505. 	    pline("Too far!");
2506. 	    return (res);
2507. 	} else if (!cansee(cc.x, cc.y)) {
2508. 	    You(cant_see_spot);
2509. 	    return (res);
2510. 	} else if (!couldsee(cc.x, cc.y)) { /* Eyes of the Overworld */
2511. 	    You(cant_reach);
2512. 	    return res;
2513. 	}
2514. 
2515. 	/* What do you want to hit? */
2516. 	tohit = rn2(5);
2517. 	if (typ != P_NONE && P_SKILL(typ) >= P_SKILLED) {
2518. 	    winid tmpwin = create_nhwindow(NHW_MENU);
2519. 	    anything any;
2520. 	    char buf[BUFSZ];
2521. 	    menu_item *selected;
2522. 
2523. 	    any.a_void = 0;	/* set all bits to zero */
2524. 	    any.a_int = 1;	/* use index+1 (cant use 0) as identifier */
2525. 	    start_menu(tmpwin);
2526. 	    any.a_int++;
2527. 	    Sprintf(buf, "an object on the %s", surface(cc.x, cc.y));
2528. 	    add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
2529. 			 buf, MENU_UNSELECTED);
2530. 	    any.a_int++;
2531. 	    add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
2532. 			"a monster", MENU_UNSELECTED);
2533. 	    any.a_int++;
2534. 	    Sprintf(buf, "the %s", surface(cc.x, cc.y));
2535. 	    add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
2536. 			 buf, MENU_UNSELECTED);
2537. 	    end_menu(tmpwin, "Aim for what?");
2538. 	    tohit = rn2(4);
2539. 	    if (select_menu(tmpwin, PICK_ONE, &selected) > 0 &&
2540. 			rn2(P_SKILL(typ) > P_SKILLED ? 20 : 2))
2541. 		tohit = selected[0].item.a_int - 1;
2542. 	    free((genericptr_t)selected);
2543. 	    destroy_nhwindow(tmpwin);
2544. 	}
2545. 
2546. 	/* What did you hit? */
2547. 	switch (tohit) {
2548. 	case 0:	/* Trap */
2549. 	    /* FIXME -- untrap needs to deal with non-adjacent traps */
2550. 	    break;
2551. 	case 1:	/* Object */
2552. 	    if ((otmp = level.objects[cc.x][cc.y]) != 0) {
2553. 		You("snag an object from the %s!", surface(cc.x, cc.y));
2554. 		(void) pickup_object(otmp, 1L, FALSE);
2555. 		/* If pickup fails, leave it alone */
2556. 		newsym(cc.x, cc.y);
2557. 		return (1);
2558. 	    }
2559. 	    break;
2560. 	case 2:	/* Monster */
2561. 	    if ((mtmp = m_at(cc.x, cc.y)) == (struct monst *)0) break;
2562. 	    if (verysmall(mtmp->data) && !rn2(4) &&
2563. 			enexto(&cc, u.ux, u.uy, (struct permonst *)0)) {
2564. 		You("pull in %s!", mon_nam(mtmp));
2565. 		mtmp->mundetected = 0;
2566. 		rloc_to(mtmp, cc.x, cc.y);
2567. 		return (1);
2568. 	    } else if ((!bigmonst(mtmp->data) && !strongmonst(mtmp->data)) ||
2569. 		       rn2(4)) {
2570. 		(void) thitmonst(mtmp, uwep);
2571. 		return (1);
2572. 	    }
2573. 	    /* FALL THROUGH */
2574. 	case 3:	/* Surface */
2575. 	    if (IS_AIR(levl[cc.x][cc.y].typ) || is_pool(cc.x, cc.y))
2576. 		pline_The("hook slices through the %s.", surface(cc.x, cc.y));
2577. 	    else {
2578. 		You("are yanked toward the %s!", surface(cc.x, cc.y));
2579. 		hurtle(sgn(cc.x-u.ux), sgn(cc.y-u.uy), 1, FALSE);
2580. 		spoteffects(TRUE);
2581. 	    }
2582. 	    return (1);
2583. 	default:	/* Yourself (oops!) */
2584. 	    if (P_SKILL(typ) <= P_BASIC) {
2585. 		You("hook yourself!");
2586. 		losehp(rn1(10,10), "a grappling hook", KILLED_BY);
2587. 		return (1);
2588. 	    }
2589. 	    break;
2590. 	}
2591. 	pline(nothing_happens);
2592. 	return (1);
2593. }
2594. 
2595. 

do_break_wand[]

2596. #define BY_OBJECT	((struct monst *)0)
2597. 
2598. /* return 1 if the wand is broken, hence some time elapsed */
2599. STATIC_OVL int
2600. do_break_wand(obj)
2601.     struct obj *obj;
2602. {
2603.     static const char nothing_else_happens[] = "But nothing else happens...";
2604.     register int i, x, y;
2605.     register struct monst *mon;
2606.     int dmg, damage;
2607.     boolean affects_objects;
2608.     boolean shop_damage = FALSE;
2609.     int expltype = EXPL_MAGICAL;
2610.     char confirm[QBUFSZ], the_wand[BUFSZ], buf[BUFSZ];
2611. 
2612.     Strcpy(the_wand, yname(obj));
2613.     Sprintf(confirm, "Are you really sure you want to break %s?",
2614. 	safe_qbuf("", sizeof("Are you really sure you want to break ?"),
2615. 				the_wand, ysimple_name(obj), "the wand"));
2616.     if (yn(confirm) == 'n' ) return 0;
2617. 
2618.     if (nohands(youmonst.data)) {
2619. 	You_cant("break %s without hands!", the_wand);
2620. 	return 0;
2621.     } else if (ACURR(A_STR) < 10) {
2622. 	You("don't have the strength to break %s!", the_wand);
2623. 	return 0;
2624.     }
2625.     pline("Raising %s high above your %s, you break it in two!",
2626. 	  the_wand, body_part(HEAD));
2627. 
2628.     /* [ALI] Do this first so that wand is removed from bill. Otherwise,
2629.      * the freeinv() below also hides it from setpaid() which causes problems.
2630.      */
2631.     if (obj->unpaid) {
2632. 	check_unpaid(obj);		/* Extra charge for use */
2633. 	bill_dummy_object(obj);
2634.     }
2635. 
2636.     current_wand = obj;		/* destroy_item might reset this */
2637.     freeinv(obj);		/* hide it from destroy_item instead... */
2638.     setnotworn(obj);		/* so we need to do this ourselves */
2639. 
2640.     if (obj->spe <= 0) {
2641. 	pline(nothing_else_happens);
2642. 	goto discard_broken_wand;
2643.     }
2644.     obj->ox = u.ux;
2645.     obj->oy = u.uy;
2646.     dmg = obj->spe * 4;
2647.     affects_objects = FALSE;
2648. 
2649.     switch (obj->otyp) {
2650.     case WAN_WISHING:
2651.     case WAN_NOTHING:
2652.     case WAN_LOCKING:
2653.     case WAN_PROBING:
2654.     case WAN_ENLIGHTENMENT:
2655.     case WAN_OPENING:
2656.     case WAN_SECRET_DOOR_DETECTION:
2657. 	pline(nothing_else_happens);
2658. 	goto discard_broken_wand;
2659.     case WAN_DEATH:
2660.     case WAN_LIGHTNING:
2661. 	dmg *= 4;
2662. 	goto wanexpl;
2663.     case WAN_FIRE:
2664. 	expltype = EXPL_FIERY;
2665.     case WAN_COLD:
2666. 	if (expltype == EXPL_MAGICAL) expltype = EXPL_FROSTY;
2667. 	dmg *= 2;
2668.     case WAN_MAGIC_MISSILE:
2669.     wanexpl:
2670. 	explode(u.ux, u.uy,
2671. 		(obj->otyp - WAN_MAGIC_MISSILE), dmg, WAND_CLASS, expltype);
2672. 	makeknown(obj->otyp);	/* explode described the effect */
2673. 	goto discard_broken_wand;
2674.     case WAN_STRIKING:
2675. 	/* we want this before the explosion instead of at the very end */
2676. 	pline("A wall of force smashes down around you!");
2677. 	dmg = d(1 + obj->spe,6);	/* normally 2d12 */
2678.     case WAN_CANCELLATION:
2679.     case WAN_POLYMORPH:
2680.     case WAN_TELEPORTATION:
2681.     case WAN_UNDEAD_TURNING:
2682. 	affects_objects = TRUE;
2683. 	break;
2684.     default:
2685. 	break;
2686.     }
2687. 
2688.     /* magical explosion and its visual effect occur before specific effects */
2689.     explode(obj->ox, obj->oy, 0, rnd(dmg), WAND_CLASS, EXPL_MAGICAL);
2690. 
2691.     /* this makes it hit us last, so that we can see the action first */
2692.     for (i = 0; i <= 8; i++) {
2693. 	bhitpos.x = x = obj->ox + xdir[i];
2694. 	bhitpos.y = y = obj->oy + ydir[i];
2695. 	if (!isok(x,y)) continue;
2696. 
2697. 	if (obj->otyp == WAN_DIGGING) {
2698. 	    if(dig_check(BY_OBJECT, FALSE, x, y)) {
2699. 		if (IS_WALL(levl[x][y].typ) || IS_DOOR(levl[x][y].typ)) {
2700. 		    /* normally, pits and holes don't anger guards, but they
2701. 		     * do if it's a wall or door that's being dug */
2702. 		    watch_dig((struct monst *)0, x, y, TRUE);
2703. 		    if (*in_rooms(x,y,SHOPBASE)) shop_damage = TRUE;
2704. 		}		    
2705. 		digactualhole(x, y, BY_OBJECT,
2706. 			      (rn2(obj->spe) < 3 || !Can_dig_down(&u.uz)) ?
2707. 			       PIT : HOLE);
2708. 	    }
2709. 	    continue;
2710. 	} else if(obj->otyp == WAN_CREATE_MONSTER) {
2711. 	    /* u.ux,u.uy creates it near you--x,y might create it in rock */
2712. 	    (void) makemon((struct permonst *)0, u.ux, u.uy, NO_MM_FLAGS);
2713. 	    continue;
2714. 	} else {
2715. 	    if (x == u.ux && y == u.uy) {
2716. 		/* teleport objects first to avoid race with tele control and
2717. 		   autopickup.  Other wand/object effects handled after
2718. 		   possible wand damage is assessed */
2719. 		if (obj->otyp == WAN_TELEPORTATION &&
2720. 		    affects_objects && level.objects[x][y]) {
2721. 		    (void) bhitpile(obj, bhito, x, y);
2722. 		    if (flags.botl) bot();		/* potion effects */
2723. 		}
2724. 		damage = zapyourself(obj, FALSE);
2725. 		if (damage) {
2726. 		    Sprintf(buf, "killed %sself by breaking a wand", uhim());
2727. 		    losehp(damage, buf, NO_KILLER_PREFIX);
2728. 		}
2729. 		if (flags.botl) bot();		/* blindness */
2730. 	    } else if ((mon = m_at(x, y)) != 0) {
2731. 		(void) bhitm(mon, obj);
2732. 	     /* if (flags.botl) bot(); */
2733. 	    }
2734. 	    if (affects_objects && level.objects[x][y]) {
2735. 		(void) bhitpile(obj, bhito, x, y);
2736. 		if (flags.botl) bot();		/* potion effects */
2737. 	    }
2738. 	}
2739.     }
2740. 
2741.     /* Note: if player fell thru, this call is a no-op.
2742.        Damage is handled in digactualhole in that case */
2743.     if (shop_damage) pay_for_damage("dig into", FALSE);
2744. 
2745.     if (obj->otyp == WAN_LIGHT)
2746. 	litroom(TRUE, obj);	/* only needs to be done once */
2747. 
2748.  discard_broken_wand:
2749.     obj = current_wand;		/* [see dozap() and destroy_item()] */
2750.     current_wand = 0;
2751.     if (obj)
2752. 	delobj(obj);
2753.     nomul(0);
2754.     return 1;
2755. }
2756. 

uhave_graystone[]

2757. STATIC_OVL boolean
2758. uhave_graystone()
2759. {
2760. 	register struct obj *otmp;
2761. 
2762. 	for(otmp = invent; otmp; otmp = otmp->nobj)
2763. 		if(is_graystone(otmp))
2764. 			return TRUE;
2765. 	return FALSE;
2766. }
2767. 

add_class[]

2768. STATIC_OVL void
2769. add_class(cl, class)
2770. char *cl;
2771. char class;
2772. {
2773. 	char tmp[2];
2774. 	tmp[0] = class;
2775. 	tmp[1] = '\0';
2776. 	Strcat(cl, tmp);
2777. }
2778. 

doapply[]

2779. int
2780. doapply()
2781. {
2782. 	struct obj *obj;
2783. 	register int res = 1;
2784. 	char class_list[MAXOCLASSES+2];
2785. 
2786. 	if(check_capacity((char *)0)) return (0);
2787. 
2788. 	if (carrying(POT_OIL) || uhave_graystone())
2789. 		Strcpy(class_list, tools_too);
2790. 	else
2791. 		Strcpy(class_list, tools);
2792. 	if (carrying(CREAM_PIE) || carrying(EUCALYPTUS_LEAF))
2793. 		add_class(class_list, FOOD_CLASS);
2794. 
2795. 	obj = getobj(class_list, "use or apply");
2796. 	if(!obj) return 0;
2797. 
2798. 	if (obj->oartifact && !touch_artifact(obj, &youmonst))
2799. 	    return 1;	/* evading your grasp costs a turn; just be
2800. 			   grateful that you don't drop it as well */
2801. 
2802. 	if (obj->oclass == WAND_CLASS)
2803. 	    return do_break_wand(obj);
2804. 
2805. 	switch(obj->otyp){
2806. 	case BLINDFOLD:
2807. 	case LENSES:
2808. 		if (obj == ublindf) {
2809. 		    if (!cursed(obj)) Blindf_off(obj);
2810. 		} else if (!ublindf)
2811. 		    Blindf_on(obj);
2812. 		else You("are already %s.",
2813. 			ublindf->otyp == TOWEL ?     "covered by a towel" :
2814. 			ublindf->otyp == BLINDFOLD ? "wearing a blindfold" :
2815. 						     "wearing lenses");
2816. 		break;
2817. 	case CREAM_PIE:
2818. 		res = use_cream_pie(obj);
2819. 		break;
2820. 	case BULLWHIP:
2821. 		res = use_whip(obj);
2822. 		break;
2823. 	case GRAPPLING_HOOK:
2824. 		res = use_grapple(obj);
2825. 		break;
2826. 	case LARGE_BOX:
2827. 	case CHEST:
2828. 	case ICE_BOX:
2829. 	case SACK:
2830. 	case BAG_OF_HOLDING:
2831. 	case OILSKIN_SACK:
2832. 		res = use_container(obj, 1);
2833. 		break;
2834. 	case BAG_OF_TRICKS:
2835. 		bagotricks(obj);
2836. 		break;
2837. 	case CAN_OF_GREASE:
2838. 		use_grease(obj);
2839. 		break;
2840. 	case LOCK_PICK:
2841. #ifdef TOURIST
2842. 	case CREDIT_CARD:
2843. #endif
2844. 	case SKELETON_KEY:
2845. 		(void) pick_lock(obj);
2846. 		break;
2847. 	case PICK_AXE:
2848. 	case DWARVISH_MATTOCK:
2849. 		res = use_pick_axe(obj);
2850. 		break;
2851. 	case TINNING_KIT:
2852. 		use_tinning_kit(obj);
2853. 		break;
2854. 	case LEASH:
2855. 		use_leash(obj);
2856. 		break;
2857. #ifdef STEED
2858. 	case SADDLE:
2859. 		res = use_saddle(obj);
2860. 		break;
2861. #endif
2862. 	case MAGIC_WHISTLE:
2863. 		use_magic_whistle(obj);
2864. 		break;
2865. 	case TIN_WHISTLE:
2866. 		use_whistle(obj);
2867. 		break;
2868. 	case EUCALYPTUS_LEAF:
2869. 		/* MRKR: Every Australian knows that a gum leaf makes an */
2870. 		/*	 excellent whistle, especially if your pet is a  */
2871. 		/*	 tame kangaroo named Skippy.			 */
2872. 		if (obj->blessed) {
2873. 		    use_magic_whistle(obj);
2874. 		    /* sometimes the blessing will be worn off */
2875. 		    if (!rn2(49)) {
2876. 			if (!Blind) {
2877. 			    char buf[BUFSZ];
2878. 
2879. 			    pline("%s %s %s.", Shk_Your(buf, obj),
2880. 				  aobjnam(obj, "glow"), hcolor("brown"));
2881. 			    obj->bknown = 1;
2882. 			}
2883. 			unbless(obj);
2884. 		    }
2885. 		} else {
2886. 		    use_whistle(obj);
2887. 		}
2888. 		break;
2889. 	case STETHOSCOPE:
2890. 		res = use_stethoscope(obj);
2891. 		break;
2892. 	case MIRROR:
2893. 		res = use_mirror(obj);
2894. 		break;
2895. 	case BELL:
2896. 	case BELL_OF_OPENING:
2897. 		use_bell(&obj);
2898. 		break;
2899. 	case CANDELABRUM_OF_INVOCATION:
2900. 		use_candelabrum(obj);
2901. 		break;
2902. 	case WAX_CANDLE:
2903. 	case TALLOW_CANDLE:
2904. 		use_candle(&obj);
2905. 		break;
2906. 	case OIL_LAMP:
2907. 	case MAGIC_LAMP:
2908. 	case BRASS_LANTERN:
2909. 		use_lamp(obj);
2910. 		break;
2911. 	case POT_OIL:
2912. 		light_cocktail(obj);
2913. 		break;
2914. #ifdef TOURIST
2915. 	case EXPENSIVE_CAMERA:
2916. 		res = use_camera(obj);
2917. 		break;
2918. #endif
2919. 	case TOWEL:
2920. 		res = use_towel(obj);
2921. 		break;
2922. 	case CRYSTAL_BALL:
2923. 		use_crystal_ball(obj);
2924. 		break;
2925. 	case MAGIC_MARKER:
2926. 		res = dowrite(obj);
2927. 		break;
2928. 	case TIN_OPENER:
2929. 		if(!carrying(TIN)) {
2930. 			You("have no tin to open.");
2931. 			goto xit;
2932. 		}
2933. 		You("cannot open a tin without eating or discarding its contents.");
2934. 		if(flags.verbose)
2935. 			pline("In order to eat, use the 'e' command.");
2936. 		if(obj != uwep)
2937.     pline("Opening the tin will be much easier if you wield the tin opener.");
2938. 		goto xit;
2939. 
2940. 	case FIGURINE:
2941. 		use_figurine(&obj);
2942. 		break;
2943. 	case UNICORN_HORN:
2944. 		use_unicorn_horn(obj);
2945. 		break;
2946. 	case WOODEN_FLUTE:
2947. 	case MAGIC_FLUTE:
2948. 	case TOOLED_HORN:
2949. 	case FROST_HORN:
2950. 	case FIRE_HORN:
2951. 	case WOODEN_HARP:
2952. 	case MAGIC_HARP:
2953. 	case BUGLE:
2954. 	case LEATHER_DRUM:
2955. 	case DRUM_OF_EARTHQUAKE:
2956. 		res = do_play_instrument(obj);
2957. 		break;
2958. 	case HORN_OF_PLENTY:	/* not a musical instrument */
2959. 		if (obj->spe > 0) {
2960. 		    struct obj *otmp;
2961. 		    const char *what;
2962. 
2963. 		    consume_obj_charge(obj, TRUE);
2964. 		    if (!rn2(13)) {
2965. 			otmp = mkobj(POTION_CLASS, FALSE);
2966. 			if (objects[otmp->otyp].oc_magic) do {
2967. 			    otmp->otyp = rnd_class(POT_BOOZE, POT_WATER);
2968. 			} while (otmp->otyp == POT_SICKNESS);
2969. 			what = "A potion";
2970. 		    } else {
2971. 			otmp = mkobj(FOOD_CLASS, FALSE);
2972. 			if (otmp->otyp == FOOD_RATION && !rn2(7))
2973. 			    otmp->otyp = LUMP_OF_ROYAL_JELLY;
2974. 			what = "Some food";
2975. 		    }
2976. 		    pline("%s spills out.", what);
2977. 		    otmp->blessed = obj->blessed;
2978. 		    otmp->cursed = obj->cursed;
2979. 		    otmp->owt = weight(otmp);
2980. 		    otmp = hold_another_object(otmp, u.uswallow ?
2981. 				       "Oops!  %s out of your reach!" :
2982. 					(Is_airlevel(&u.uz) ||
2983. 					 Is_waterlevel(&u.uz) ||
2984. 					 levl[u.ux][u.uy].typ < IRONBARS ||
2985. 					 levl[u.ux][u.uy].typ >= ICE) ?
2986. 					       "Oops!  %s away from you!" :
2987. 					       "Oops!  %s to the floor!",
2988. 					       The(aobjnam(otmp, "slip")),
2989. 					       (const char *)0);
2990. 		    makeknown(HORN_OF_PLENTY);
2991. 		} else
2992. 		    pline(nothing_happens);
2993. 		break;
2994. 	case LAND_MINE:
2995. 	case BEARTRAP:
2996. 		use_trap(obj);
2997. 		break;
2998. 	case FLINT:
2999. 	case LUCKSTONE:
3000. 	case LOADSTONE:
3001. 	case TOUCHSTONE:
3002. 		use_stone(obj);
3003. 		break;
3004. 	default:
3005. 		/* Pole-weapons can strike at a distance */
3006. 		if (is_pole(obj)) {
3007. 			res = use_pole(obj);
3008. 			break;
3009. 		} else if (is_pick(obj) || is_axe(obj)) {
3010. 			res = use_pick_axe(obj);
3011. 			break;
3012. 		}
3013. 		pline("Sorry, I don't know how to use that.");
3014. 	xit:
3015. 		nomul(0);
3016. 		return 0;
3017. 	}
3018. 	if (res && obj && obj->oartifact) arti_speak(obj);
3019. 	nomul(0);
3020. 	return res;
3021. }
3022. 

unfixable_trouble_count[]

3023. /* Keep track of unfixable troubles for purposes of messages saying you feel
3024.  * great.
3025.  */
3026. int
3027. unfixable_trouble_count(is_horn)
3028. 	boolean is_horn;
3029. {
3030. 	int unfixable_trbl = 0;
3031. 
3032. 	if (Stoned) unfixable_trbl++;
3033. 	if (Strangled) unfixable_trbl++;
3034. 	if (Wounded_legs
3035. #ifdef STEED
3036. 		    && !u.usteed
3037. #endif
3038. 				) unfixable_trbl++;
3039. 	if (Slimed) unfixable_trbl++;
3040. 	/* lycanthropy is not desirable, but it doesn't actually make you feel
3041. 	   bad */
3042. 
3043. 	/* we'll assume that intrinsic stunning from being a bat/stalker
3044. 	   doesn't make you feel bad */
3045. 	if (!is_horn) {
3046. 	    if (Confusion) unfixable_trbl++;
3047. 	    if (Sick) unfixable_trbl++;
3048. 	    if (HHallucination) unfixable_trbl++;
3049. 	    if (Vomiting) unfixable_trbl++;
3050. 	    if (HStun) unfixable_trbl++;
3051. 	}
3052. 	return unfixable_trbl;
3053. }
3054. 
3055. #endif /* OVLB */
3056. 
3057. /*apply.c*/
Advertisement