Fandom

Wikihack

Source:NetHack 3.2.0/apply.c

2,034pages on
this wiki
Add New Page
Talk0

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

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

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /*	SCCS Id: @(#)apply.c	3.2	96/01/28	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    #include "edog.h"
7.    
8.    #ifdef OVLB
9.    
10.   static const char tools[] = { TOOL_CLASS, POTION_CLASS,
11.   				WEAPON_CLASS, WAND_CLASS, 0 };
12.   
13.   #ifdef TOURIST
14.   static int FDECL(use_camera, (struct obj *));
15.   #endif
16.   static int FDECL(use_towel, (struct obj *));
17.   static boolean FDECL(its_dead, (int,int,int *));
18.   static int FDECL(use_stethoscope, (struct obj *));
19.   static void FDECL(use_whistle, (struct obj *));
20.   static void FDECL(use_magic_whistle, (struct obj *));
21.   static void FDECL(use_leash, (struct obj *));
22.   static int FDECL(use_mirror, (struct obj *));
23.   static void FDECL(use_bell, (struct obj *));
24.   static void FDECL(use_candelabrum, (struct obj *));
25.   static void FDECL(use_candle, (struct obj *));
26.   static void FDECL(use_lamp, (struct obj *));
27.   static void FDECL(light_cocktail, (struct obj *));
28.   static void FDECL(use_tinning_kit, (struct obj *));
29.   static void FDECL(use_figurine, (struct obj *));
30.   static void FDECL(use_grease, (struct obj *));
31.   static void FDECL(use_trap, (struct obj *));
32.   static int FDECL(use_whip, (struct obj *));
33.   static int FDECL(do_break_wand, (struct obj *));
34.   
35.   #ifdef	AMIGA
36.   void FDECL( amii_speaker, ( struct obj *, char *, int ) );
37.   #endif
38.   
39.   static char no_elbow_room[] = "don't have enough elbow-room to maneuver.";
40.   
41.   #ifdef TOURIST
42.   static int
43.   use_camera(obj)
44.   	struct obj *obj;
45.   {
46.   	register struct monst *mtmp;
47.   
48.   	if(Underwater) {
49.   		pline("Using your camera underwater would void the warranty.");
50.   		return(0);
51.   	}
52.   	if(!getdir((char *)0)) return(0);
53.   
54.   	if (obj->cursed && !rn2(2)) {
55.   		(void) zapyourself(obj, TRUE);
56.   	} else if (u.uswallow) {
57.   		You("take a picture of %s %s.", s_suffix(mon_nam(u.ustuck)),
58.   		    is_animal(u.ustuck->data) ? "stomach" : "interior");
59.   	} else if (u.dz) {
60.   		You("take a picture of the %s.",
61.   			(u.dz > 0) ? surface(u.ux,u.uy) : ceiling(u.ux,u.uy));
62.   	} else if (!u.dx && !u.dy) {
63.   		(void) zapyourself(obj, TRUE);
64.   	} else if ((mtmp = bhit(u.dx,u.dy,COLNO,FLASHED_LIGHT,
65.   				(int(*)())0,(int(*)())0,obj)) != 0) {
66.   		obj->ox = u.ux,  obj->oy = u.uy;
67.   		(void) flash_hits_mon(mtmp, obj);
68.   	}
69.   	return 1;
70.   }
71.   #endif
72.   
73.   static int
74.   use_towel(obj)
75.   	struct obj *obj;
76.   {
77.   	if(!freehand()) {
78.   		You("have no free %s!", body_part(HAND));
79.   		return 0;
80.   	} else if (obj->owornmask) {
81.   		You("cannot use it while you're wearing it!");
82.   		return 0;
83.   	} else if (obj->cursed) {
84.   		long old;
85.   		switch (rn2(3)) {
86.   		case 2:
87.   		    old = Glib;
88.   		    Glib += rn1(10, 3);
89.   		    Your("%s %s!", makeplural(body_part(HAND)),
90.   			(old ? "are filthier than ever" : "get slimy"));
91.   		    return 1;
92.   		case 1:
93.   		    if (!Blindfolded) {
94.   			old = u.ucreamed;
95.   			u.ucreamed += rn1(10, 3);
96.   			pline("Yecch! Your %s %s gunk on it!", body_part(FACE),
97.   			      (old ? "has more" : "now has"));
98.   			make_blinded(Blinded + (long)u.ucreamed - old, TRUE);
99.   		    } else {
100.  			if (ublindf->cursed) {
101.  			    You("push your blindfold %s.",
102.  				rn2(2) ? "cock-eyed" : "crooked");
103.  			} else {
104.  			    You("push your blindfold off.");
105.  			    Blindf_off(ublindf);
106.  			    dropx(ublindf);
107.  			}
108.  		    }
109.  		    return 1;
110.  		case 0:
111.  		    break;
112.  		}
113.  	}
114.  
115.  	if (Glib) {
116.  		Glib = 0;
117.  		You("wipe off your %s.", makeplural(body_part(HAND)));
118.  		return 1;
119.  	} else if(u.ucreamed) {
120.  		Blinded -= u.ucreamed;
121.  		u.ucreamed = 0;
122.  
123.  		if (!Blinded) {
124.  			pline("You've got the glop off.");
125.  			Blinded = 1;
126.  			make_blinded(0L,TRUE);
127.  		} else {
128.  			Your("%s feels clean now.", body_part(FACE));
129.  		}
130.  		return 1;
131.  	}
132.  
133.  	Your("%s and %s are already clean.",
134.  		body_part(FACE), makeplural(body_part(HAND)));
135.  
136.  	return 0;
137.  }
138.  
139.  /* maybe give a stethoscope message based on floor objects */
140.  static boolean
141.  its_dead(rx, ry, resp)
142.  int rx, ry, *resp;
143.  {
144.  	struct obj *otmp;
145.  	struct trap *ttmp;
146.  
147.  	/* additional stethoscope messages from jyoung@apanix.apana.org.au */
148.  	if (Hallucination && sobj_at(CORPSE, rx, ry)) {
149.  	    /* (a corpse doesn't retain the monster's sex,
150.  	       so we're forced to use generic pronoun here) */
151.  	    You_hear("a voice say, \"It's dead, Jim.\"");
152.  	    *resp = 1;
153.  	    return TRUE;
154.  	} else if (Role_is('H') && ((otmp = sobj_at(CORPSE, rx, ry)) != 0 ||
155.  				    (otmp = sobj_at(STATUE, rx, ry)) != 0)) {
156.  	    /* possibly should check uppermost {corpse,statue} in the pile
157.  	       if both types are present, but it's not worth the effort */
158.  	    if (vobj_at(rx, ry)->otyp == STATUE) otmp = vobj_at(rx, ry);
159.  	    if (otmp->otyp == CORPSE) {
160.  		You("determine that %s unfortunate being is dead.",
161.  		    (rx == u.ux && ry == u.uy) ? "this" : "that");
162.  	    } else {
163.  		ttmp = t_at(rx, ry);
164.  		pline("%s appears to be in %s health for a statue.",
165.  		      The(mons[otmp->corpsenm].mname),
166.  		      (ttmp && ttmp->ttyp == STATUE_TRAP) ?
167.  			"extraordinary" : "excellent");
168.  	    }
169.  	    return TRUE;
170.  	}
171.  	return FALSE;
172.  }
173.  
174.  static char hollow_str[] = "a hollow sound.  This must be a secret %s!";
175.  
176.  /* Strictly speaking it makes no sense for usage of a stethoscope to
177.     not take any time; however, unless it did, the stethoscope would be
178.     almost useless.  As a compromise, one use per turn is free, another
179.     uses up the turn; this makes curse status have a tangible effect. */
180.  static int
181.  use_stethoscope(obj)
182.  	register struct obj *obj;
183.  {
184.  	static long last_used = 0;
185.  	struct monst *mtmp;
186.  	struct rm *lev;
187.  	int rx, ry, res;
188.  
189.  	if (nohands(uasmon)) {	/* should also check for no ears and/or deaf */
190.  		You("have no hands!");	/* not `body_part(HAND)' */
191.  		return 0;
192.  	} else if (!freehand()) {
193.  		You("have no free %s.", body_part(HAND));
194.  		return 0;
195.  	}
196.  	if (!getdir((char *)0)) return 0;
197.  
198.  	res = (moves + monstermoves == last_used);
199.  	last_used = moves + monstermoves;
200.  
201.  	if (u.uswallow && (u.dx || u.dy || u.dz)) {
202.  		mstatusline(u.ustuck);
203.  		return res;
204.  	} else if (u.dz) {
205.  		if (Underwater)
206.  		    You_hear("faint splashing.");
207.  		else if (u.dz < 0 || !can_reach_floor())
208.  		    You_cant("reach the %s.",
209.  			(u.dz > 0) ? surface(u.ux,u.uy) : ceiling(u.ux,u.uy));
210.  		else if (its_dead(u.ux, u.uy, &res))
211.  		    ;	/* message already given */
212.  		else if (Is_stronghold(&u.uz))
213.  		    You_hear("the crackling of hellfire.");
214.  		else
215.  		    pline_The("%s seems healthy enough.", surface(u.ux,u.uy));
216.  		return res;
217.  	} else if (obj->cursed && !rn2(2)) {
218.  		You_hear("your heart beat.");
219.  		return res;
220.  	}
221.  	if (Stunned || (Confusion && !rn2(5))) confdir();
222.  	if (!u.dx && !u.dy) {
223.  		ustatusline();
224.  		return res;
225.  	}
226.  	rx = u.ux + u.dx; ry = u.uy + u.dy;
227.  	if (!isok(rx,ry)) {
228.  		You_hear("a faint typing noise.");
229.  		return 0;
230.  	}
231.  	if ((mtmp = m_at(rx,ry)) != 0) {
232.  		mstatusline(mtmp);
233.  		if (mtmp->mundetected) {
234.  			mtmp->mundetected = 0;
235.  			if (cansee(rx,ry)) newsym(mtmp->my,mtmp->my);
236.  		}
237.  		return res;
238.  	}
239.  
240.  	lev = &levl[rx][ry];
241.  	switch(lev->typ) {
242.  	case SDOOR:
243.  		You_hear(hollow_str, "door");
244.  		lev->typ = DOOR;
245.  		lev->doormask = exposed_sdoor_mask(lev);
246.  		if (Blind) feel_location(rx,ry);
247.  		else newsym(rx,ry);
248.  		return res;
249.  	case SCORR:
250.  		You_hear(hollow_str, "passage");
251.  		lev->typ = CORR;
252.  		if (Blind) feel_location(rx,ry);
253.  		else newsym(rx,ry);
254.  		return res;
255.  	}
256.  
257.  	if (!its_dead(rx, ry, &res))
258.  		You_hear("nothing special.");
259.  	return res;
260.  }
261.  
262.  static char whistle_str[] = "produce a %s whistling sound.";
263.  
264.  static void
265.  use_whistle(obj)
266.  struct obj *obj;
267.  {
268.  	You(whistle_str, obj->cursed ? "shrill" : "high");
269.  	wake_nearby();
270.  }
271.  
272.  static void
273.  use_magic_whistle(obj)
274.  struct obj *obj;
275.  {
276.  	register struct monst *mtmp, *nextmon;
277.  
278.  	if(obj->cursed && !rn2(2)) {
279.  		You("produce a high-pitched humming noise.");
280.  		wake_nearby();
281.  	} else {
282.  		int pet_cnt = 0;
283.  		You(whistle_str, Hallucination ? "normal" : "strange");
284.  		for(mtmp = fmon; mtmp; mtmp = nextmon) {
285.  		    nextmon = mtmp->nmon; /* trap might kill mon */
286.  		    if (mtmp->mtame) {
287.  			mnexto(mtmp);
288.  			if (canspotmon(mtmp)) ++pet_cnt;
289.  			/* No longer in previous trap.  Necessary since */
290.  			/* mintrap acts differently for already-trapped mons */
291.  			mtmp->mtrapped = 0;
292.  			(void) mintrap(mtmp);
293.  		    }
294.  		}
295.  		if (pet_cnt > 0) makeknown(MAGIC_WHISTLE);
296.  	}
297.  }
298.  
299.  boolean
300.  um_dist(x,y,n)
301.  register xchar x, y, n;
302.  {
303.  	return((boolean)(abs(u.ux - x) > n  || abs(u.uy - y) > n));
304.  }
305.  
306.  int
307.  number_leashed()
308.  {
309.  	register int i = 0;
310.  	register struct obj *obj;
311.  
312.  	for(obj = invent; obj; obj = obj->nobj)
313.  		if(obj->otyp == LEASH && obj->leashmon != 0) i++;
314.  	return(i);
315.  }
316.  
317.  void
318.  o_unleash(otmp)		/* otmp is about to be destroyed or stolen */
319.  register struct obj *otmp;
320.  {
321.  	register struct monst *mtmp;
322.  
323.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
324.  		if(mtmp->m_id == (unsigned)otmp->leashmon)
325.  			mtmp->mleashed = 0;
326.  	otmp->leashmon = 0;
327.  }
328.  
329.  void
330.  m_unleash(mtmp)		/* mtmp is about to die, or become untame */
331.  register struct monst *mtmp;
332.  {
333.  	register struct obj *otmp;
334.  
335.  	for(otmp = invent; otmp; otmp = otmp->nobj)
336.  		if(otmp->otyp == LEASH &&
337.  				otmp->leashmon == (int)mtmp->m_id)
338.  			otmp->leashmon = 0;
339.  	mtmp->mleashed = 0;
340.  }
341.  
342.  void
343.  unleash_all()		/* player is about to die (for bones) */
344.  {
345.  	register struct obj *otmp;
346.  	register struct monst *mtmp;
347.  
348.  	for(otmp = invent; otmp; otmp = otmp->nobj)
349.  		if(otmp->otyp == LEASH) otmp->leashmon = 0;
350.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
351.  		if(mtmp->mtame) mtmp->mleashed = 0;
352.  }
353.  
354.  #define MAXLEASHED	2
355.  
356.  /* ARGSUSED */
357.  static void
358.  use_leash(obj)
359.  struct obj *obj;
360.  {
361.  	register int x, y;
362.  	register struct monst *mtmp;
363.  	int spotmon;
364.  
365.  	if(!obj->leashmon && number_leashed() >= MAXLEASHED) {
366.  		You("cannot leash any more pets.");
367.  		return;
368.  	}
369.  
370.  	if(!getdir((char *)0)) return;
371.  
372.  	x = u.ux + u.dx;
373.  	y = u.uy + u.dy;
374.  
375.  	if((x == u.ux) && (y == u.uy)) {
376.  		pline("Leash yourself?  Very funny...");
377.  		return;
378.  	}
379.  
380.  	if(!(mtmp = m_at(x, y))) {
381.  		pline("There is no creature there.");
382.  		return;
383.  	}
384.  
385.  	spotmon = canspotmon(mtmp);
386.  
387.  	if(!mtmp->mtame) {
388.  	    if(!spotmon)
389.  		pline("There is no creature there.");
390.  	    else
391.  		pline("%s %s leashed!", Monnam(mtmp), (!obj->leashmon) ?
392.  				"cannot be" : "is not");
393.  	    return;
394.  	}
395.  	if(!obj->leashmon) {
396.  		if(mtmp->mleashed) {
397.  			pline("This %s is already leashed.",
398.  			      spotmon ? l_monnam(mtmp) : "monster");
399.  			return;
400.  		}
401.  		You("slip the leash around %s%s.",
402.  		    spotmon ? "your " : "", l_monnam(mtmp));
403.  		mtmp->mleashed = 1;
404.  		obj->leashmon = (int)mtmp->m_id;
405.  		if(mtmp->msleep)  mtmp->msleep = 0;
406.  		return;
407.  	}
408.  	if(obj->leashmon != (int)mtmp->m_id) {
409.  		pline("This leash is not attached to that creature.");
410.  		return;
411.  	} else {
412.  		if(obj->cursed) {
413.  			pline_The("leash would not come off!");
414.  			obj->bknown = TRUE;
415.  			return;
416.  		}
417.  		mtmp->mleashed = 0;
418.  		obj->leashmon = 0;
419.  		You("remove the leash from %s%s.",
420.  		    spotmon ? "your " : "", l_monnam(mtmp));
421.  	}
422.  	return;
423.  }
424.  
425.  struct obj *
426.  get_mleash(mtmp)	/* assuming mtmp->mleashed has been checked */
427.  register struct monst *mtmp;
428.  {
429.  	register struct obj *otmp;
430.  
431.  	otmp = invent;
432.  	while(otmp) {
433.  		if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id)
434.  			return(otmp);
435.  		otmp = otmp->nobj;
436.  	}
437.  	return((struct obj *)0);
438.  }
439.  
440.  #endif /* OVLB */
441.  #ifdef OVL1
442.  
443.  boolean
444.  next_to_u()
445.  {
446.  	register struct monst *mtmp;
447.  	register struct obj *otmp;
448.  
449.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
450.  		if(mtmp->mleashed) {
451.  			if (distu(mtmp->mx,mtmp->my) > 2) mnexto(mtmp);
452.  			if (distu(mtmp->mx,mtmp->my) > 2) {
453.  			    for(otmp = invent; otmp; otmp = otmp->nobj)
454.  				if(otmp->otyp == LEASH &&
455.  					otmp->leashmon == (int)mtmp->m_id) {
456.  				    if(otmp->cursed) return(FALSE);
457.  				    You_feel("%s leash go slack.",
458.  					(number_leashed() > 1) ? "a" : "the");
459.  				    mtmp->mleashed = 0;
460.  				    otmp->leashmon = 0;
461.  				}
462.  			}
463.  		}
464.  	return(TRUE);
465.  }
466.  
467.  #endif /* OVL1 */
468.  #ifdef OVL0
469.  
470.  void
471.  check_leash(x, y)
472.  register xchar x, y;
473.  {
474.  	register struct obj *otmp;
475.  	register struct monst *mtmp = fmon;
476.  
477.  	for(otmp = invent; otmp; otmp = otmp->nobj)
478.  	    if(otmp->otyp == LEASH && otmp->leashmon != 0) {
479.  		while(mtmp) {
480.  		    if((int)mtmp->m_id == otmp->leashmon &&
481.  			    (dist2(u.ux,u.uy,mtmp->mx,mtmp->my) >
482.  				dist2(x,y,mtmp->mx,mtmp->my))
483.  			) {
484.  			if(otmp->cursed) {
485.  			    if(um_dist(mtmp->mx, mtmp->my, 5)) {
486.  				pline("%s chokes to death!",Monnam(mtmp));
487.  				mondied(mtmp);
488.  			    } else
489.  				if(um_dist(mtmp->mx, mtmp->my, 3))
490.  					pline("%s chokes on the leash!",
491.  						Monnam(mtmp));
492.  			} else {
493.  			    if(um_dist(mtmp->mx, mtmp->my, 5)) {
494.  				pline("%s leash snaps loose!",
495.  					s_suffix(Monnam(mtmp)));
496.  				m_unleash(mtmp);
497.  			    } else {
498.  				if(um_dist(mtmp->mx, mtmp->my, 3)) {
499.  				    You("pull on the leash.");
500.  				    if (mtmp->data->msound != MS_SILENT)
501.  					switch(rn2(3)) {
502.  					    case 0:  growl(mtmp);	break;
503.  					    case 1:  yelp(mtmp);	break;
504.  					    default: whimper(mtmp); break;
505.  					}
506.  				}
507.  			    }
508.  			}
509.  		    }
510.  		    mtmp = mtmp->nmon;
511.  		}
512.  	    }
513.  }
514.  
515.  #endif /* OVL0 */
516.  #ifdef OVLB
517.  
518.  boolean
519.  wield_tool(obj)
520.  struct obj *obj;
521.  {
522.  	if(welded(uwep)) {
523.  		/* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */
524.  		if(flags.verbose) {
525.  			pline("Since your weapon is welded to your %s,",
526.  				bimanual(uwep) ?
527.  				(const char *)makeplural(body_part(HAND))
528.  				: body_part(HAND));
529.  			pline("you cannot wield that %s.", xname(obj));
530.  		}
531.  		return(FALSE);
532.  	}
533.  	if (cantwield(uasmon)) {
534.  		You_cant("hold it strongly enough.");
535.  		return(FALSE);
536.  	}
537.  	You("now wield %s.", doname(obj));
538.  	setuwep(obj);
539.  	if (uwep != obj) return(FALSE); /* rewielded old object after dying */
540.  	unweapon = TRUE;
541.  	return(TRUE);
542.  }
543.  
544.  #define WEAK	3	/* from eat.c */
545.  
546.  static char look_str[] = "look %s.";
547.  
548.  static int
549.  use_mirror(obj)
550.  struct obj *obj;
551.  {
552.  	register struct monst *mtmp;
553.  	register char mlet;
554.  	boolean vis;
555.  
556.  	if(!getdir((char *)0)) return 0;
557.  	if(obj->cursed && !rn2(2)) {
558.  		if (!Blind)
559.  			pline_The("mirror fogs up and doesn't reflect!");
560.  		return 1;
561.  	}
562.  	if(!u.dx && !u.dy && !u.dz) {
563.  		if(!Blind && !Invisible) {
564.  		    if (u.umonnum == PM_FLOATING_EYE) {
565.  			pline(Hallucination ?
566.  			      "Yow!  The mirror stares back!" :
567.  			      "Yikes!  You've frozen yourself!");
568.  			nomul(-rnd((MAXULEV+6) - u.ulevel));
569.  		    } else if (u.usym == S_VAMPIRE)
570.  			You("don't have a reflection.");
571.  		    else if (u.umonnum == PM_UMBER_HULK) {
572.  			pline("Huh?  That doesn't look like you!");
573.  			make_confused(HConfusion + d(3,4),FALSE);
574.  		    } else if (Hallucination)
575.  			You(look_str, hcolor((char *)0));
576.  		    else if (Sick)
577.  			You(look_str, "peaked");
578.  		    else if (u.uhs >= WEAK)
579.  			You(look_str, "undernourished");
580.  		    else You("look as %s as ever.",
581.  				ACURR(A_CHA) > 14 ?
582.  				(poly_gender()==1 ? "beautiful" : "handsome") :
583.  				"ugly");
584.  		} else {
585.  			You_cant("see your %s %s.",
586.  				ACURR(A_CHA) > 14 ?
587.  				(poly_gender()==1 ? "beautiful" : "handsome") :
588.  				"ugly",
589.  				body_part(FACE));
590.  		}
591.  		return 1;
592.  	}
593.  	if(u.uswallow) {
594.  		if (!Blind) You("reflect %s %s.", s_suffix(mon_nam(u.ustuck)),
595.  		    is_animal(u.ustuck->data)? "stomach" : "interior");
596.  		return 1;
597.  	}
598.  	if(Underwater) {
599.  		You(Hallucination ?
600.  		    "give the fish a chance to fix their makeup." :
601.  		    "reflect the murky water.");
602.  		return 1;
603.  	}
604.  	if(u.dz) {
605.  		if (!Blind)
606.  		    You("reflect the %s.",
607.  			(u.dz > 0) ? surface(u.ux,u.uy) : ceiling(u.ux,u.uy));
608.  		return 1;
609.  	}
610.  	if(!(mtmp = bhit(u.dx,u.dy,COLNO,INVIS_BEAM,
611.  					(int(*)())0,(int(*)())0,obj)) ||
612.  	   !haseyes(mtmp->data))
613.  		return 1;
614.  
615.  	vis = canseemon(mtmp);
616.  	mlet = mtmp->data->mlet;
617.  	if(mtmp->msleep) {
618.  		if (vis)
619.  		    pline ("%s is too tired to look at your mirror.",
620.  			    Monnam(mtmp));
621.  	} else if (!mtmp->mcansee) {
622.  	    if (vis)
623.  		pline("%s can't see anything right now.", Monnam(mtmp));
624.  	/* some monsters do special things */
625.  	} else if (mlet == S_VAMPIRE || mlet == S_GHOST) {
626.  	    if (vis)
627.  		pline ("%s doesn't have a reflection.", Monnam(mtmp));
628.  	} else if(!mtmp->mcan && mtmp->data == &mons[PM_MEDUSA]) {
629.  		if (vis)
630.  			pline("%s is turned to stone!", Monnam(mtmp));
631.  		stoned = TRUE;
632.  		killed(mtmp);
633.  	} else if(!mtmp->mcan && !mtmp->minvis &&
634.  					mtmp->data == &mons[PM_FLOATING_EYE]) {
635.  		int tmp = d((int)mtmp->m_lev, (int)mtmp->data->mattk[0].damd);
636.  		if (!rn2(4)) tmp = 120;
637.  	/* Note: floating eyes cannot use their abilities while invisible,
638.  	 * but Medusa and umber hulks can.
639.  	 */
640.  		if (vis)
641.  			pline("%s is frozen by its reflection.", Monnam(mtmp));
642.  		else You_hear("%s stop moving.",something);
643.  		mtmp->mcanmove = 0;
644.  		if ( (int) mtmp->mfrozen + tmp > 127)
645.  			mtmp->mfrozen = 127;
646.  		else mtmp->mfrozen += tmp;
647.  	} else if(!mtmp->mcan && mtmp->data == &mons[PM_UMBER_HULK]) {
648.  		if (vis)
649.  			pline ("%s confuses itself!", Monnam(mtmp));
650.  		mtmp->mconf = 1;
651.  	} else if(!mtmp->mcan && !mtmp->minvis && (mlet == S_NYMPH
652.  				     || mtmp->data==&mons[PM_SUCCUBUS])) {
653.  		if (vis) {
654.  		    pline ("%s admires herself in your mirror.", Monnam(mtmp));
655.  		    pline ("She takes it!");
656.  		} else pline ("It steals your mirror!");
657.  		setnotworn(obj); /* in case mirror was wielded */
658.  		freeinv(obj);
659.  		mpickobj(mtmp,obj);
660.  		rloc(mtmp);
661.  	} else if (mlet != S_UNICORN && !humanoid(mtmp->data) &&
662.  			(!mtmp->minvis || perceives(mtmp->data)) && rn2(5)) {
663.  		if (vis)
664.  			pline ("%s is frightened by its reflection.",
665.  				Monnam(mtmp));
666.  		mtmp->mflee = 1;
667.  		mtmp->mfleetim += d(2,4);
668.  	} else if (!Blind) {
669.  		if (mtmp->minvis && !See_invisible)
670.  		    ;
671.  		else if ((mtmp->minvis && !perceives(mtmp->data))
672.  			 || !haseyes(mtmp->data))
673.  		    pline("%s doesn't seem to notice its reflection.",
674.  			Monnam(mtmp));
675.  		else
676.  		    pline("%s ignores %s reflection.",
677.  			  Monnam(mtmp), his[pronoun_gender(mtmp)]);
678.  	}
679.  	return 1;
680.  }
681.  
682.  static void
683.  use_bell(obj)
684.  register struct obj *obj;
685.  {
686.  	struct monst *mtmp;
687.  	boolean wakem = FALSE, learno = FALSE,
688.  		ordinary = (obj->otyp != BELL_OF_OPENING || !obj->spe),
689.  		invoking = (obj->otyp == BELL_OF_OPENING &&
690.  			 invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy));
691.  
692.  	You("ring %s.", the(xname(obj)));
693.  
694.  	if (Underwater || (u.uswallow && ordinary)) {
695.  #ifdef	AMIGA
696.  	    amii_speaker( obj, "AhDhGqEqDhEhAqDqFhGw", AMII_MUFFLED_VOLUME );
697.  #endif
698.  	    pline("But the sound is muffled.");
699.  
700.  	} else if (invoking && ordinary) {
701.  	    /* needs to be recharged... */
702.  	    pline("But it makes no sound.");
703.  	    learno = TRUE;	/* help player figure out why */
704.  
705.  	} else if (ordinary) {
706.  #ifdef	AMIGA
707.  	    amii_speaker( obj, "ahdhgqeqdhehaqdqfhgw", AMII_MUFFLED_VOLUME );
708.  #endif
709.  	    if (obj->cursed && !rn2(4) &&
710.  		    /* note: once any of them are gone, we stop all of them */
711.  		    !(mvitals[PM_WOOD_NYMPH].mvflags & G_GONE) &&
712.  		    !(mvitals[PM_WATER_NYMPH].mvflags & G_GONE) &&
713.  		    !(mvitals[PM_MOUNTAIN_NYMPH].mvflags & G_GONE) &&
714.  		    (mtmp = makemon(mkclass(S_NYMPH, 0), u.ux, u.uy)) != 0) {
715.  		You("summon %s!", a_monnam(mtmp));
716.  		discard_minvent(mtmp);	/* treat this like reverse genocide */
717.  		if (!obj_resists(obj, 93, 100)) {
718.  		    pline("%s has shattered!", The(xname(obj)));
719.  		    useup(obj);
720.  		} else switch (rn2(3)) {
721.  			default:
722.  				break;
723.  			case 1: mtmp->mspeed = MFAST;
724.  				break;
725.  			case 2: /* no explanation; it just happens... */
726.  				nomovemsg = "";
727.  				nomul(-rnd(2));
728.  				break;
729.  		}
730.  	    }
731.  	    wakem = TRUE;
732.  
733.  	} else {
734.  	    /* charged Bell of Opening */
735.  	    check_unpaid(obj);
736.  	    obj->spe--;
737.  
738.  	    if (u.uswallow) {
739.  		if (!obj->cursed)
740.  		    (void) openit();
741.  		else
742.  		    pline(nothing_happens);
743.  
744.  	    } else if (obj->cursed) {
745.  		coord mm;
746.  
747.  		mm.x = u.ux;
748.  		mm.y = u.uy;
749.  		mkundead(&mm);
750.  		wakem = TRUE;
751.  
752.  	    } else  if (invoking) {
753.  		pline("%s issues an unsettling shrill sound...",
754.  		      The(xname(obj)));
755.  #ifdef	AMIGA
756.  		amii_speaker( obj, "aefeaefeaefeaefeaefe", AMII_LOUDER_VOLUME );
757.  #endif
758.  		obj->age = moves;
759.  		learno = TRUE;
760.  		wakem = TRUE;
761.  
762.  	    } else if (obj->blessed) {
763.  #ifdef	AMIGA
764.  		amii_speaker( obj, "ahahahDhEhCw", AMII_SOFT_VOLUME );
765.  #endif
766.  		switch (openit()) {
767.  		  case 0:  pline(nothing_happens); break;
768.  		  case 1:  pline("%s opens...", Something);
769.  			   learno = TRUE; break;
770.  		  default: pline("Things open around you...");
771.  			   learno = TRUE; break;
772.  		}
773.  
774.  	    } else {  /* uncursed */
775.  #ifdef	AMIGA
776.  		amii_speaker( obj, "AeFeaeFeAefegw", AMII_OKAY_VOLUME );
777.  #endif
778.  		if (findit() != 0) learno = TRUE;
779.  		else pline(nothing_happens);
780.  	    }
781.  
782.  	}	/* charged BofO */
783.  
784.  	if (learno) {
785.  	    makeknown(BELL_OF_OPENING);
786.  	    obj->known = 1;
787.  	}
788.  	if (wakem) wake_nearby();
789.  }
790.  
791.  static void
792.  use_candelabrum(obj)
793.  register struct obj *obj;
794.  {
795.  	if(Underwater) {
796.  		You("cannot make fire under water.");
797.  		return;
798.  	}
799.  	if(obj->lamplit) {
800.  		You("snuff the candle%s.", obj->spe > 1 ? "s" : "");
801.  		end_burn(obj, TRUE);
802.  		return;
803.  	}
804.  	if(obj->spe <= 0) {
805.  		pline("This %s has no candles.", xname(obj));
806.  		return;
807.  	}
808.  	if(u.uswallow || obj->cursed) {
809.  		pline_The("candle%s flicker%s for a moment, then die%s.",
810.  			obj->spe > 1 ? "s" : "",
811.  			obj->spe > 1 ? "" : "s",
812.  			obj->spe > 1 ? "" : "s");
813.  		return;
814.  	}
815.  	if(obj->spe < 7) {
816.  		pline("There %s only %d candle%s in %s.",
817.  		       obj->spe == 1 ? "is" : "are",
818.  		       obj->spe,
819.  		       obj->spe > 1 ? "s" : "",
820.  		       the(xname(obj)));
821.  		if (!Blind)
822.  		    pline("%s lit.  %s shines dimly.",
823.  		       obj->spe == 1 ? "It is" : "They are", The(xname(obj)));
824.  	} else {
825.  		pline("%s's candles burn%s", The(xname(obj)),
826.  			(Blind ? "." : " brightly!"));
827.  	}
828.  	if (!invocation_pos(u.ux, u.uy)) {
829.  		pline_The("candle%s being rapidly consumed!",
830.  			(obj->spe > 1 ? "s are" : " is"));
831.  		obj->age /= 2;
832.  	} else {
833.  		if(obj->spe == 7) {
834.  		    if (Blind)
835.  		      pline("%s radiates a strange warmth!", The(xname(obj)));
836.  		    else
837.  		      pline("%s glows with a strange light!", The(xname(obj)));
838.  		}
839.  		obj->known = 1;
840.  	}
841.  	begin_burn(obj, FALSE);
842.  }
843.  
844.  static void
845.  use_candle(obj)
846.  register struct obj *obj;
847.  {
848.  	register struct obj *otmp;
849.  	char qbuf[QBUFSZ];
850.  
851.  	if(obj->lamplit) {
852.  		use_lamp(obj);
853.  		return;
854.  	}
855.  
856.  	if(u.uswallow) {
857.  		You(no_elbow_room);
858.  		return;
859.  	}
860.  	if(Underwater) {
861.  		pline("Sorry, fire and water don't mix.");
862.  		return;
863.  	}
864.  
865.  	for(otmp = invent; otmp; otmp = otmp->nobj) {
866.  		if (otmp->otyp == CANDELABRUM_OF_INVOCATION)
867.  			break;
868.  	}
869.  	if(!otmp || otmp->spe == 7) {
870.  		use_lamp(obj);
871.  		return;
872.  	}
873.  
874.  	Sprintf(qbuf, "Attach %s", the(xname(obj)));
875.  	Sprintf(eos(qbuf), " to %s?", the(xname(otmp)));
876.  	if(yn(qbuf) == 'n') {
877.  		You("try to light %s...", the(xname(obj)));
878.  		use_lamp(obj);
879.  		return;
880.  	} else {
881.  		register long needed = 7L - (long)otmp->spe;
882.  
883.  		You("attach %ld%s candle%s to %s.",
884.  			obj->quan >= needed ? needed : obj->quan,
885.  			!otmp->spe ? "" : " more",
886.  			(needed > 1L && obj->quan > 1L) ? "s" : "",
887.  			the(xname(otmp)));
888.  		if(otmp->lamplit)
889.  			pline_The("new candle%s magically ignite%s!",
890.  			    (needed > 1L && obj->quan > 1L) ? "s" : "",
891.  			    (needed > 1L && obj->quan > 1L) ? "" : "s");
892.  		if(obj->unpaid)
893.  			verbalize("You burn %s, you bought %s!",
894.  			    (needed > 1L && obj->quan > 1L) ? "them" : "it",
895.  			    (needed > 1L && obj->quan > 1L) ? "them" : "it");
896.  		if(!otmp->spe || otmp->age > obj->age)
897.  			otmp->age = obj->age;
898.  		if(obj->quan > needed) {
899.  		    if(obj->unpaid) {
900.  			/* this is a hack, until we re-write the billing */
901.  			/* code to accommodate such cases directly. IM*/
902.  			register long delta = obj->quan - needed;
903.  
904.  			subfrombill(obj, shop_keeper(*u.ushops));
905.  			obj->quan = needed;
906.  			addtobill(obj, TRUE, FALSE, TRUE);
907.  			bill_dummy_object(obj);
908.  			obj->quan = delta;
909.  			addtobill(obj, TRUE, FALSE, TRUE);
910.  		     } else {
911.  			obj->quan -= needed;
912.  		     }
913.  		     otmp->spe += (int)needed;
914.  		} else {
915.  		    otmp->spe += (int)obj->quan;
916.  		    freeinv(obj);
917.  		    obfree(obj, (struct obj *)0);
918.  		}
919.  		if(needed < 7L && otmp->spe == 7)
920.  		    pline("%s now has seven%s candles attached.",
921.  			The(xname(otmp)), otmp->lamplit ? " lit" : "");
922.  	}
923.  }
924.  
925.  boolean
926.  snuff_candle(otmp)  /* call in drop, throw, and put in box, etc. */
927.  register struct obj *otmp;
928.  {
929.  	register boolean candle = Is_candle(otmp);
930.  
931.  	if ((candle || otmp->otyp == CANDELABRUM_OF_INVOCATION) &&
932.  		otmp->lamplit) {
933.  	    char buf[BUFSZ];
934.  	    xchar x, y;
935.  	    register boolean many = candle ? otmp->quan > 1L : otmp->spe > 1;
936.  
937.  	    (void) get_obj_location(otmp, &x, &y, 0);
938.  	    if (otmp->where == OBJ_MINVENT ? cansee(x,y) : !Blind)
939.  		pline("%s %scandle%s flame%s extinguished.",
940.  		      Shk_Your(buf, otmp),
941.  		      (candle ? "" : "candelabrum's "),
942.  		      (many ? "s'" : "'s"), (many ? "s are" : " is"));
943.  	   end_burn(otmp, TRUE);
944.  	   return(TRUE);
945.  	}
946.  	return(FALSE);
947.  }
948.  
949.  /* called when lit lamp is hit by water or put into a container or
950.     you've been swallowed by a monster; obj might be in transit while
951.     being thrown or dropped so don't assume that its location is valid */
952.  boolean
953.  snuff_lit(obj)
954.  struct obj *obj;
955.  {
956.  	char buf[BUFSZ];
957.  	xchar x, y;
958.  
959.  	if (obj->lamplit) {
960.  	    if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
961.  		    obj->otyp == BRASS_LANTERN || obj->otyp == POT_OIL) {
962.  		(void) get_obj_location(obj, &x, &y, 0);
963.  		if (obj->where == OBJ_MINVENT ? cansee(x,y) : !Blind)
964.  		    pline("%s %s goes out!", Shk_Your(buf, obj), xname(obj));
965.  		end_burn(obj, TRUE);
966.  		return TRUE;
967.  	    }
968.  	    if (snuff_candle(obj)) return TRUE;
969.  	}
970.  	return FALSE;
971.  }
972.  
973.  static void
974.  use_lamp(obj)
975.  struct obj *obj;
976.  {
977.  	char buf[BUFSZ];
978.  
979.  	if(Underwater) {
980.  		pline("This is not a diving lamp.");
981.  		return;
982.  	}
983.  	if(obj->lamplit) {
984.  		if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
985.  				obj->otyp == BRASS_LANTERN)
986.  		    pline("%s lamp is now off.", Shk_Your(buf, obj));
987.  		else
988.  		    You("snuff out %s %s.", shk_your(buf, obj), xname(obj));
989.  		end_burn(obj, TRUE);
990.  		return;
991.  	}
992.  	/* magic lamps with an spe == 0 (wished for) cannot be lit */
993.  	if ((!Is_candle(obj) && obj->age == 0)
994.  			|| (obj->otyp == MAGIC_LAMP && obj->spe == 0)) {
995.  		if (obj->otyp == BRASS_LANTERN)
996.  			Your("lamp has run out of power.");
997.  		else pline("This %s has no oil.", xname(obj));
998.  		return;
999.  	}
1000. 	if (obj->cursed && !rn2(2)) {
1001. 		pline("%s flicker%s for a moment, then die%s.",
1002. 		       The(xname(obj)),
1003. 		       obj->quan > 1L ? "" : "s",
1004. 		       obj->quan > 1L ? "" : "s");
1005. 	} else {
1006. 		if(obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
1007. 				obj->otyp == BRASS_LANTERN) {
1008. 		    check_unpaid(obj);
1009. 		    pline("%s lamp is now on.", Shk_Your(buf, obj));
1010. 		} else {	/* candle(s) */
1011. 		    pline("%s %s flame%s burn%s%s",
1012. 			Shk_Your(buf, obj),
1013. 			s_suffix(xname(obj)),
1014. 			obj->quan > 1L ? "s" : "",
1015. 			obj->quan > 1L ? "" : "s",
1016. 			Blind ? "." : " brightly!");
1017. 		    if (obj->unpaid &&
1018. 			  obj->age == 20L * (long)objects[obj->otyp].oc_cost) {
1019. 			const char *ithem = obj->quan > 1L ? "them" : "it";
1020. 			verbalize("You burn %s, you bought %s!", ithem, ithem);
1021. 			bill_dummy_object(obj);
1022. 		    }
1023. 		}
1024. 		begin_burn(obj, FALSE);
1025. 	}
1026. }
1027. 
1028. static void
1029. light_cocktail(obj)
1030. 	struct obj *obj;	/* obj is a potion of oil */
1031. {
1032. 	char buf[BUFSZ];
1033. 
1034. 	if (u.uswallow) {
1035. 	    You(no_elbow_room);
1036. 	    return;
1037. 	}
1038. 
1039. 	if (obj->lamplit) {
1040. 	    You("snuff the lit potion.");
1041. 	    end_burn(obj, TRUE);
1042. 	    /*
1043. 	     * Free & add to re-merge potion.  This will average the
1044. 	     * age of the potions.  Not exactly the best solution,
1045. 	     * but its easy.
1046. 	     */
1047. 	    freeinv(obj);
1048. 	    (void) addinv(obj);
1049. 	    return;
1050. 	}
1051. 
1052. 	You("light %s potion.  It gives off a dim light.", shk_your(buf, obj));
1053. 	if (obj->unpaid) {
1054. 	    check_unpaid(obj);		/* surcharge for use of unpaid item */
1055. 	    bill_dummy_object(obj);	/* treat it as having been used up    */
1056. 	    obj->no_charge = 1;		/* you're now obligated to pay for it */
1057. 	    obj->unpaid = 0;
1058. 	}
1059. 
1060. 	if (obj->quan > 1L) {
1061. 	    (void) splitobj(obj, 1L);
1062. 	    begin_burn(obj, FALSE);	/* burn before free to get position */
1063. 	    obj_extract_self(obj);	/* free from inv */
1064. 
1065. 	    /* shouldn't merge */
1066. 	    obj = hold_another_object(obj, "You drop %s!",
1067. 				      doname(obj), (const char *)0);
1068. 	} else
1069. 	    begin_burn(obj, FALSE);
1070. }
1071. 
1072. static NEARDATA const char cuddly[] = { TOOL_CLASS, 0 };
1073. 
1074. int
1075. dorub()
1076. {
1077. 	struct obj *obj = getobj(cuddly, "rub");
1078. 
1079. 	if(!obj || (obj != uwep && !wield_tool(obj))) return 0;
1080. 
1081. 	/* now uwep is obj */
1082. 	if (uwep->otyp == MAGIC_LAMP) {
1083. 	    if (uwep->spe > 0 && !rn2(3)) {
1084. 		check_unpaid(uwep); /* this is not adequate; it simply charges
1085. 				       the same amount as lighting the lamp! */
1086. 		djinni_from_bottle(uwep);
1087. 		makeknown(MAGIC_LAMP);
1088. 		uwep->otyp = OIL_LAMP;
1089. 		uwep->spe = 0; /* for safety */
1090. 		uwep->age = rn1(500,1000);
1091. 		if (uwep->lamplit) begin_burn(uwep, TRUE);
1092. 	    } else if (rn2(2) && !Blind)
1093. 		You("see a puff of smoke.");
1094. 	    else pline(nothing_happens);
1095. 	} else if (obj->otyp == BRASS_LANTERN) {
1096. 	    /* message from Adventure */
1097. 	    pline("Rubbing the electric lamp is not particularly rewarding.");
1098. 	    pline("Anyway, nothing exciting happens.");
1099. 	} else pline(nothing_happens);
1100. 	return 1;
1101. }
1102. 
1103. int
1104. dojump()
1105. {
1106. 	coord cc;
1107. 	struct monst *mtmp;
1108. 
1109. 	if (!Jumping) {
1110. 		You_cant("jump very far.");
1111. 		return 0;
1112. 	} else if (u.uswallow) {
1113. 		pline("You've got to be kidding!");
1114. 		return 0;
1115. 	} else if (u.uinwater) {
1116. 		pline("This calls for swimming, not jumping!");
1117. 		return 0;
1118. 	} else if (u.ustuck) {
1119. 		You("cannot escape from %s!", mon_nam(u.ustuck));
1120. 		return 0;
1121. 	} else if (Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
1122. 		You("don't have enough traction to jump.");
1123. 		return 0;
1124. 	} else if (near_capacity() > UNENCUMBERED) {
1125. 		You("are carrying too much to jump!");
1126. 		return 0;
1127. 	} else if (u.uhunger <= 100 || ACURR(A_STR) < 6) {
1128. 		You("lack the strength to jump!");
1129. 		return 0;
1130. 	}
1131. 
1132. 	pline("Where do you want to jump?");
1133. 	cc.x = u.ux;
1134. 	cc.y = u.uy;
1135. 	getpos(&cc, TRUE, "the desired position");
1136. 	if(cc.x == -10) return 0; /* user pressed esc */
1137. 	if (!(Jumping & ~INTRINSIC) && distu(cc.x, cc.y) != 5) {
1138. 		pline("Illegal move!");
1139. 		return 0;
1140. 	} else if (distu(cc.x, cc.y) > 9) {
1141. 		pline("Too far!");
1142. 		return 0;
1143. 	} else if (!cansee(cc.x, cc.y)) {
1144. 		You("cannot see where to land!");
1145. 		return 0;
1146. 	} else if ((mtmp = m_at(cc.x, cc.y)) != 0) {
1147. 		You("cannot trample %s!", mon_nam(mtmp));
1148. 		return 0;
1149. 	} else if (!isok(cc.x, cc.y) ||
1150. 		   ((IS_ROCK(levl[cc.x][cc.y].typ) ||
1151. 		     sobj_at(BOULDER, cc.x, cc.y) || closed_door(cc.x, cc.y))
1152. 		    && !(passes_walls(uasmon) && may_passwall(cc.x, cc.y)))) {
1153. 			You("cannot jump there!");
1154. 			return 0;
1155. 	} else {
1156. 	    if(u.utrap)
1157. 		switch(u.utraptype) {
1158. 		case TT_BEARTRAP: {
1159. 		    register long side = rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
1160. 		    You("rip yourself free of the bear trap!  Ouch!");
1161. 		    losehp(rnd(10), "jumping out of a bear trap", KILLED_BY);
1162. 		    set_wounded_legs(side, rn1(1000,500));
1163. 		    break;
1164. 		  }
1165. 		case TT_PIT:
1166. 		    You("leap from the pit!");
1167. 		    break;
1168. 		case TT_WEB:
1169. 		    You("tear the web apart as you pull yourself free!");
1170. 		    deltrap(t_at(u.ux,u.uy));
1171. 		    break;
1172. 		case TT_LAVA:
1173. 		    You("pull yourself above the lava!");
1174. 		    u.utrap = 0;
1175. 		    return 1;
1176. 		case TT_INFLOOR:
1177. 		    You("strain your %s, but you're still stuck in the floor.",
1178. 			makeplural(body_part(LEG)));
1179. 		    set_wounded_legs(LEFT_SIDE, rn1(10, 11));
1180. 		    set_wounded_legs(RIGHT_SIDE, rn1(10, 11));
1181. 		    return 1;
1182. 		}
1183. 
1184. 	    teleds(cc.x, cc.y);
1185. 	    nomul(-1);
1186. 	    nomovemsg = "";
1187. 	    morehungry(rnd(25));
1188. 	    return 1;
1189. 	}
1190. }
1191. 
1192. boolean
1193. tinnable(corpse)
1194. struct obj *corpse;
1195. {
1196. 	if (corpse->oeaten) return 0;
1197. 	if (!mons[corpse->corpsenm].cnutrit) return 0;
1198. 	return 1;
1199. }
1200. 
1201. static void
1202. use_tinning_kit(obj)
1203. register struct obj *obj;
1204. {
1205. 	register struct obj *corpse, *can;
1206. 
1207. 	/* This takes only 1 move.  If this is to be changed to take many
1208. 	 * moves, we've got to deal with decaying corpses...
1209. 	 */
1210. 	if (!(corpse = floorfood("tin", 2))) return;
1211. 	if (corpse->oeaten) {
1212. 		You("cannot tin %s which is partly eaten.",something);
1213. 		return;
1214. 	}
1215. 	if ((corpse->corpsenm == PM_COCKATRICE)
1216. 		&& !resists_ston(&youmonst) && !uarmg) {
1217. pline("Tinning a cockatrice without wearing gloves is a fatal mistake...");
1218. 		/* this will have to change if more monsters can poly */
1219. 		if (!(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))) {
1220. 		    You("turn to stone...");
1221. 		    killer_format = KILLED_BY;
1222. 		    killer = "trying to tin a cockatrice without gloves";
1223. 		    done(STONING);
1224. 		}
1225. 	}
1226. 	if (is_rider(&mons[corpse->corpsenm])) {
1227. 		(void) revive_corpse(corpse);
1228. 		verbalize("Yes...  But War does not preserve its enemies...");
1229. 		return;
1230. 	}
1231. 	if (mons[corpse->corpsenm].cnutrit == 0) {
1232. 		pline("That's too insubstantial to tin.");
1233. 		return;
1234. 	}
1235. 	if ((can = mksobj(TIN, FALSE, FALSE)) != 0) {
1236. 	    static const char you_buy_it[] = "You tin it, you bought it!";
1237. 
1238. 	    can->corpsenm = corpse->corpsenm;
1239. 	    can->cursed = obj->cursed;
1240. 	    can->blessed = obj->blessed;
1241. 	    can->owt = weight(can);
1242. 	    can->known = 1;
1243. 	    can->spe = -1;  /* Mark tinned tins. No spinach allowed... */
1244. 	    if (carried(corpse)) {
1245. 		if (corpse->unpaid)
1246. 		    verbalize(you_buy_it);
1247. 		useup(corpse);
1248. 	    } else {
1249. 		if (costly_spot(corpse->ox, corpse->oy) && !corpse->no_charge)
1250. 		    verbalize(you_buy_it);
1251. 		useupf(corpse);
1252. 	    }
1253. 	    can = hold_another_object(can, "You make, but cannot pick up, %s.",
1254. 				      doname(can), (const char *)0);
1255. 	} else impossible("Tinning failed.");
1256. }
1257. 
1258. void
1259. use_unicorn_horn(obj)
1260. struct obj *obj;
1261. {
1262. #define PROP_COUNT 6		/* number of properties we're dealing with */
1263. #define ATTR_COUNT (A_MAX*3)	/* number of attribute points we might fix */
1264. 	int idx, val, val_limit,
1265. 	    trouble_count, unfixable_trbl, did_prop, did_attr;
1266. 	int trouble_list[PROP_COUNT + ATTR_COUNT];
1267. 
1268. 	if (obj && obj->cursed) {
1269. 	    long lcount = (long) rnd(100);
1270. 
1271. 	    switch (rn2(6)) {
1272. 	    case 0: make_sick(Sick ? Sick/3L + 1L : (long)rn1(ACURR(A_CON),20),
1273. 			xname(obj), TRUE, SICK_NONVOMITABLE);
1274. 		    break;
1275. 	    case 1: make_blinded(Blinded + lcount, TRUE);
1276. 		    break;
1277. 	    case 2: if (!Confusion)
1278. 			You("suddenly feel %s.",
1279. 			    Hallucination ? "trippy" : "confused");
1280. 		    make_confused(HConfusion + lcount, TRUE);
1281. 		    break;
1282. 	    case 3: make_stunned(HStun + lcount, TRUE);
1283. 		    break;
1284. 	    case 4: (void) adjattrib(rn2(6), -1, FALSE);
1285. 		    break;
1286. 	    case 5: make_hallucinated(HHallucination + lcount, TRUE, 0L);
1287. 		    break;
1288. 	    }
1289. 	    return;
1290. 	}
1291. 
1292. /*
1293.  * Entries in the trouble list use a very simple encoding scheme.
1294.  */
1295. #define prop2trbl(X)	((X) + A_MAX)
1296. #define attr2trbl(Y)	(Y)
1297. #define prop_trouble(X) trouble_list[trouble_count++] = prop2trbl(X)
1298. #define attr_trouble(Y) trouble_list[trouble_count++] = attr2trbl(Y)
1299. 
1300. 	trouble_count = unfixable_trbl = did_prop = did_attr = 0;
1301. 
1302. 	/* collect property troubles */
1303. 	if (Sick) prop_trouble(SICK);
1304. 	if (Blinded > (long)(u.ucreamed + 1)) prop_trouble(BLINDED);
1305. 	if (HHallucination) prop_trouble(HALLUC);
1306. 	if (Vomiting) prop_trouble(VOMITING);
1307. 	if (HConfusion) prop_trouble(CONFUSION);
1308. 	if (HStun) prop_trouble(STUNNED);
1309. 	/* keep track of unfixed trouble, for message adjustment below
1310. 	   (can't "feel great" with these problems present) */
1311. 	if (Stoned) unfixable_trbl++;
1312. 	if (Strangled) unfixable_trbl++;
1313. 	if (Wounded_legs) unfixable_trbl++;
1314. 
1315. 	/* collect attribute troubles */
1316. 	for (idx = 0; idx < A_MAX; idx++) {
1317. 	    val_limit = AMAX(idx);
1318. 	    /* don't recover strength lost from hunger */
1319. 	    if (idx == A_STR && u.uhs >= WEAK) val_limit--;
1320. 	    /* don't recover more than 3 points worth of any attribute */
1321. 	    if (val_limit > ABASE(idx) + 3) val_limit = ABASE(idx) + 3;
1322. 
1323. 	    for (val = ABASE(idx); val < val_limit; val++)
1324. 		attr_trouble(idx);
1325. 	    /* keep track of unfixed trouble, for message adjustment below */
1326. 	    unfixable_trbl += (AMAX(idx) - val_limit);
1327. 	}
1328. 
1329. 	if (trouble_count == 0) {
1330. 	    pline(nothing_happens);
1331. 	    return;
1332. 	} else if (trouble_count > 1) {		/* shuffle */
1333. 	    int i, j, k;
1334. 
1335. 	    for (i = trouble_count - 1; i > 0; i--)
1336. 		if ((j = rn2(i + 1)) != i) {
1337. 		    k = trouble_list[j];
1338. 		    trouble_list[j] = trouble_list[i];
1339. 		    trouble_list[i] = k;
1340. 		}
1341. 	}
1342. 
1343. 	/*
1344. 	 *		Chances for number of troubles to be fixed
1345. 	 *		 0	1      2      3      4	    5	   6	  7
1346. 	 *   blessed:  16/80  16/80  15/80  13/80  10/80   6/80   3/80	 1/80
1347. 	 *  uncursed:	4/12   4/12   3/12   1/12    0	    0	   0	  0
1348. 	 */
1349. 	val_limit = rn2( d(2, (obj && obj->blessed) ? 4 : 2) );
1350. 	if (val_limit > trouble_count) val_limit = trouble_count;
1351. 
1352. 	/* fix [some of] the troubles */
1353. 	for (val = 0; val < val_limit; val++) {
1354. 	    idx = trouble_list[val];
1355. 
1356. 	    switch (idx) {
1357. 	    case prop2trbl(SICK):
1358. 		make_sick(0L, (char *) 0, TRUE, SICK_ALL);
1359. 		did_prop++;
1360. 		break;
1361. 	    case prop2trbl(BLINDED):
1362. 		make_blinded(u.ucreamed ? (long)(u.ucreamed+1) : 0L, TRUE);
1363. 		did_prop++;
1364. 		break;
1365. 	    case prop2trbl(HALLUC):
1366. 		make_hallucinated(0L, TRUE, 0L);
1367. 		did_prop++;
1368. 		break;
1369. 	    case prop2trbl(VOMITING):
1370. 		make_vomiting(0L, TRUE);
1371. 		did_prop++;
1372. 		break;
1373. 	    case prop2trbl(CONFUSION):
1374. 		make_confused(0L, TRUE);
1375. 		did_prop++;
1376. 		break;
1377. 	    case prop2trbl(STUNNED):
1378. 		make_stunned(0L, TRUE);
1379. 		did_prop++;
1380. 		break;
1381. 	    default:
1382. 		if (idx >= 0 && idx < A_MAX) {
1383. 		    ABASE(idx) += 1;
1384. 		    did_attr++;
1385. 		} else
1386. 		    panic("use_unicorn_horn: bad trouble? (%d)", idx);
1387. 		break;
1388. 	    }
1389. 	}
1390. 
1391. 	if (did_attr)
1392. 	    pline("This makes you feel %s!",
1393. 		  (did_prop + did_attr) == (trouble_count + unfixable_trbl) ?
1394. 		  "great" : "better");
1395. 	else if (!did_prop)
1396. 	    pline("Nothing seems to happen.");
1397. 
1398. 	flags.botl = (did_attr || did_prop);
1399. #undef PROP_COUNT
1400. #undef ATTR_COUNT
1401. #undef prop2trbl
1402. #undef attr2trbl
1403. #undef prop_trouble
1404. #undef attr_trouble
1405. }
1406. 
1407. static void
1408. use_figurine(obj)
1409. register struct obj *obj;
1410. {
1411. 	xchar x, y;
1412. 
1413. 	if(!getdir((char *)0)) {
1414. 		flags.move = multi = 0;
1415. 		return;
1416. 	}
1417. 	x = u.ux + u.dx; y = u.uy + u.dy;
1418. 	if (!isok(x,y)) {
1419. 		You("cannot put the figurine there.");
1420. 		return;
1421. 	}
1422. 	if (IS_ROCK(levl[x][y].typ) &&
1423. 	    !(passes_walls(&mons[obj->corpsenm]) && may_passwall(x,y))) {
1424. 		You("cannot place a figurine in solid rock!");
1425. 		return;
1426. 	}
1427. 	if (sobj_at(BOULDER,x,y) && !passes_walls(&mons[obj->corpsenm])
1428. 			&& !throws_rocks(&mons[obj->corpsenm])) {
1429. 		You("cannot fit the figurine on the boulder.");
1430. 		return;
1431. 	}
1432. 	You("%s and it transforms.",
1433. 	    (u.dx||u.dy) ? "set the figurine beside you" :
1434. 	    (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) ?
1435. 		"release the figurine" :
1436. 	    (u.dz < 0 ?
1437. 		"toss the figurine into the air" :
1438. 		"set the figurine on the ground"));
1439. 	make_familiar(obj, u.ux+u.dx, u.uy+u.dy);
1440. 	useup(obj);
1441. }
1442. 
1443. static NEARDATA const char lubricables[] = { ALL_CLASSES, ALLOW_NONE, 0 };
1444. static NEARDATA const char need_to_remove_outer_armor[] =
1445. 			"need to remove your %s to grease your %s.";
1446. 
1447. static void
1448. use_grease(obj)
1449. struct obj *obj;
1450. {
1451. 	struct obj *otmp;
1452. 	char buf[BUFSZ];
1453. 
1454. 	if (Glib) {
1455. 	    dropx(obj);
1456. 	    pline("%s slips from your %s.", The(xname(obj)),
1457. 		  makeplural(body_part(FINGER)));
1458. 	    return;
1459. 	}
1460. 
1461. 	if (obj->spe > 0) {
1462. 		if ((obj->cursed || Fumbling) && !rn2(2)) {
1463. 			check_unpaid(obj);
1464. 			obj->spe--;
1465. 			dropx(obj);
1466. 			pline("%s slips from your %s.", The(xname(obj)),
1467. 			      makeplural(body_part(FINGER)));
1468. 			return;
1469. 		}
1470. 		otmp = getobj(lubricables, "grease");
1471. 		if (!otmp) return;
1472. 		if ((otmp->owornmask & WORN_ARMOR) && uarmc) {
1473. 			Strcpy(buf, xname(uarmc));
1474. 			You(need_to_remove_outer_armor, buf, xname(otmp));
1475. 			return;
1476. 		}
1477. #ifdef TOURIST
1478. 		if ((otmp->owornmask & WORN_SHIRT) && (uarmc || uarm)) {
1479. 			Strcpy(buf, uarmc ? xname(uarmc) : "");
1480. 			if (uarmc && uarm) Strcat(buf, " and ");
1481. 			Strcat(buf, uarm ? xname(uarm) : "");
1482. 			You(need_to_remove_outer_armor, buf, xname(otmp));
1483. 			return;
1484. 		}
1485. #endif
1486. 		check_unpaid(obj);
1487. 		obj->spe--;
1488. 		if (otmp != &zeroobj) {
1489. 			You("cover %s %s with a thick layer of grease.",
1490. 			    shk_your(buf, otmp),
1491. 			    xname(otmp));
1492. 			otmp->greased = 1;
1493. 			if (obj->cursed && !nohands(uasmon)) {
1494. 			    Glib += rnd(15);
1495. 			    pline("Some of the grease gets all over your %s.",
1496. 				makeplural(body_part(HAND)));
1497. 			}
1498. 		} else {
1499. 			Glib += rnd(15);
1500. 			You("coat your %s with grease.",
1501. 			    makeplural(body_part(FINGER)));
1502. 		}
1503. 	} else {
1504. 		pline("%s %s empty.", The(xname(obj)),
1505. 			obj->known ? "is" : "seems to be");
1506. 	}
1507. }
1508. 
1509. /* Place a landmine/bear trap.  Helge Hafting */
1510. static void
1511. use_trap(otmp)
1512. struct obj *otmp;
1513. {
1514. 	struct trap *ttmp;
1515. 	int ttyp;
1516. 	const char *what = (char *)0;
1517. 
1518. 	if (u.uswallow)
1519. 	    what = is_animal(u.ustuck->data) ? "while swallowed" :
1520. 			"while engulfed";
1521. 	else if (Underwater)
1522. 	    what = "underwater";
1523. 	else if (Levitation)
1524. 	    what = "while levitating";
1525. 	else if (On_stairs(u.ux, u.uy))
1526. 	    what = (u.ux == xdnladder || u.ux == xupladder) ?
1527. 			"on the ladder" : "on the stairs";
1528. 	else if (IS_FURNITURE(levl[u.ux][u.uy].typ) || t_at(u.ux, u.uy))
1529. 	    what = "here";
1530. 	if (what) {
1531. 	    You_cant("set a trap %s!",what);
1532. 	    return;
1533. 	}
1534. 	ttyp = (otmp->otyp == LAND_MINE) ? LANDMINE : BEAR_TRAP;
1535. 	ttmp = maketrap(u.ux, u.uy, ttyp);
1536. 	if (ttmp) {
1537. 	    ttmp->tseen = 1;
1538. 	    ttmp->madeby_u = 1;
1539. 	    newsym(u.ux, u.uy); /* if our hero happens to be invisible */
1540. 	    You("set and arm %s.",
1541. 		an(defsyms[trap_to_defsym(ttyp)].explanation));
1542. 	    if ((otmp->cursed || Fumbling) && (rnl(10) > 5)) dotrap(ttmp);
1543. 	} else {
1544. 	    /* this shouldn't happen */
1545. 	    Your("attempt fails.");
1546. 	}
1547. 	useup(otmp);
1548. }
1549. 
1550. static int
1551. use_whip(obj)
1552. struct obj *obj;
1553. {
1554. 	char buf[BUFSZ];
1555. 	struct monst *mtmp;
1556. 	register int rx, ry;
1557. 	int res = 0;
1558. 	int proficient = 0;
1559. 	const char *msg_slipsfree = "The bullwhip slips free.";
1560. 	const char *msg_snap = "Snap!";
1561. 	struct obj *otmp;
1562. 
1563. 	if (obj != uwep) {
1564. 	    if (!wield_tool(obj)) return(0);
1565. 	    else res = 1;
1566. 	    /* prevent bashing msg */
1567. 	    unweapon = FALSE;
1568. 	}
1569. 	if(!getdir((char *)0)) return(res);
1570. 	if (Stunned || (Confusion && !rn2(5))) confdir();
1571. 	rx = u.ux + u.dx;
1572. 	ry = u.uy + u.dy;
1573. 	mtmp = m_at(rx, ry);
1574. 
1575. 	/* fake some proficiency checks */
1576. 	proficient = 0;
1577. 	if (Role_is('A')) ++proficient;
1578. 	if (ACURR(A_DEX) < 6) proficient--;
1579. 	else if (ACURR(A_DEX) >= 14) proficient += (ACURR(A_DEX) - 14);
1580. 	if (Fumbling) --proficient;
1581. 	if (proficient > 3) proficient = 3;
1582. 	if (proficient < 0) proficient = 0;
1583. 
1584. 	if (u.uswallow && attack(u.ustuck))
1585. 		pline("There is not enough room to flick your bullwhip.");
1586. 	else if (Underwater)
1587. 		pline("There is too much resistance to flick your bullwhip.");
1588. 	else if (u.dz < 0)
1589. 		You("flick a bug off of the %s.",ceiling(u.ux,u.uy));
1590. 	else if((!u.dx && !u.dy) || (u.dz > 0)) {
1591. 		int dam;
1592. 		if (Levitation) {
1593. 			/* Have a shot at snaring something on the floor */
1594. 			otmp = level.objects[u.ux][u.uy];
1595. 			if (otmp && proficient) {
1596. 				You("wrap your bullwhip around %s on the %s.",
1597. 					an(singular(otmp,xname)),
1598. 					surface(u.ux, u.uy));
1599. 				if (!rnl(6))
1600. 					if (pickup_object(otmp, 1L, TRUE) > 0)
1601. 						return 1;
1602. 				pline(msg_slipsfree);
1603. 				return 1;
1604. 			}
1605. 		}
1606. 		dam = rnd(2) + dbon() + obj->spe;
1607. 		if (dam <= 0) dam = 1;
1608. 		You("hit your %s with your bullwhip.", body_part(FOOT));
1609. 		/* self_pronoun() won't work twice in a sentence */
1610. 		Strcpy(buf, self_pronoun("killed %sself with %%s bullwhip",
1611. 			"him"));
1612. 		losehp(dam, self_pronoun(buf, "his"), NO_KILLER_PREFIX);
1613. 		flags.botl=1;
1614. 		return(1);
1615. 	} else if ((Fumbling || Glib) && !rn2(5)) {
1616. 		pline_The("bullwhip slips out of your %s.",
1617. 			body_part(HAND));
1618. 		dropx(obj);
1619. 		setuwep((struct obj *)0);
1620. 	}
1621. 	/*
1622. 	 *     Assumptions:
1623. 	 *
1624. 	 *		if you're in a pit
1625. 	 *			- you are attempting to get out of the pit
1626. 	 *			- or, if you are applying it towards a small
1627. 	 *			  monster then it is assumed that you are
1628. 	 *			  trying to hit it.
1629. 	 *		else if the monster is wielding a weapon
1630. 	 *			- you are attempting to disarm a monster
1631. 	 *		else
1632. 	 *			- you are attempting to hit the monster
1633. 	 *
1634. 	 *		if you're confused (and thus off the mark)
1635. 	 *			- you only end up hitting.
1636. 	 *
1637. 	 */
1638. 	else if(u.utraptype == TT_PIT) {
1639. 		const char *wrapped_what = (char *)0;
1640. 
1641. 		if (mtmp) {
1642. 			if (bigmonst(mtmp->data)) {
1643. 				Strcpy(buf, mon_nam(mtmp));
1644. 				wrapped_what = buf;
1645. 			} else if (proficient)
1646. 				if (attack(mtmp)) return(1);
1647. 				else pline(msg_snap);
1648. 		}
1649. 		if (!wrapped_what) {
1650. 			if (IS_FURNITURE(levl[rx][ry].typ))
1651. 				wrapped_what = something;
1652. 			else if (sobj_at(BOULDER, rx, ry))
1653. 				wrapped_what = "a boulder";
1654. 		}
1655. 		if (wrapped_what) {
1656. 			coord cc;
1657. 
1658. 			cc.x = rx; cc.y = ry;
1659. 			You("wrap your bullwhip around %s.", wrapped_what);
1660. 			if (proficient && rn2(proficient + 2)) {
1661. 				if (!mtmp || enexto(&cc, rx, ry, &playermon)) {
1662. 					You("yank yourself out of the pit!");
1663. 					teleds(cc.x, cc.y);
1664. 					u.utrap = 0;
1665. 					vision_full_recalc = 1;
1666. 				}
1667. 			} else
1668. 				pline(msg_slipsfree);
1669. 		} else pline(msg_snap);
1670. 	} else if (mtmp) {
1671. 		otmp = MON_WEP(mtmp);	/* can be null */
1672. 		if (otmp) {
1673. 			You("wrap your bullwhip around %s %s.",
1674. 				s_suffix(mon_nam(mtmp)), xname(otmp));
1675. 			if (proficient && (!Fumbling || !rn2(10))) {
1676. 			    obj_extract_self(otmp);
1677. 			    possibly_unwield(mtmp);
1678. 			    otmp->owornmask &= ~W_WEP;
1679. 			    switch(rn2(proficient + 1)) {
1680. 				case 2:
1681. 				    /* to floor near you */
1682. 				    You("yank %s %s to the %s!",
1683. 					s_suffix(mon_nam(mtmp)),
1684. 					xname(otmp),
1685. 					surface(u.ux, u.uy));
1686. 				    if(otmp->otyp == CRYSKNIFE)
1687. 					otmp->otyp = WORM_TOOTH;
1688. 				    place_object(otmp,u.ux, u.uy);
1689. 				    break;
1690. 				case 3:
1691. 				    /* right into your inventory */
1692. 				    if (rn2(25)) {
1693. 					You("snatch %s %s!",
1694. 						s_suffix(mon_nam(mtmp)),
1695. 						xname(otmp));
1696. 						otmp = hold_another_object(otmp,
1697. 						   "You drop %s!", doname(otmp),
1698. 						   (const char *)0);
1699. 				    /* proficient with whip, but maybe not
1700. 				       so proficient at catching weapons */
1701. 				    }
1702. #if 0
1703. 				    else {
1704. 					int hitu, hitvalu;
1705. 
1706. 					hitvalu = 8 + otmp->spe;
1707. 					hitu = thitu(hitvalu,
1708. 						dmgval(otmp, &youmonst),
1709. 						otmp, xname(otmp));
1710. 					if (hitu) {
1711. 				You("The %s hits you as you try to snatch it!",
1712. 						the(xname(otmp)));
1713. 					}
1714. 					place_object(otmp, u.ux, u.uy);
1715. 				    }
1716. #endif /* 0 */
1717. 				    break;
1718. 				default:
1719. 				    /* to floor beneath mon */
1720. 				    You("yank %s from %s %s!",
1721. 					the(xname(otmp)),
1722. 					s_suffix(mon_nam(mtmp)),
1723. 					body_part(HAND));
1724. 				    if(otmp->otyp == CRYSKNIFE)
1725. 					otmp->otyp = WORM_TOOTH;
1726. 				    place_object(otmp, mtmp->mx, mtmp->my);
1727. 			    }
1728. 			} else {
1729. 				pline(msg_slipsfree);
1730. 			}
1731. 		} else {
1732. 			You("flick your bullwhip towards %s.", mon_nam(mtmp));
1733. 			if (proficient)
1734. 				if (attack(mtmp)) return(1);
1735. 			else
1736. 				pline(msg_snap);
1737. 		}
1738. 	} else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
1739. 		/* it must be air -- water checked above */
1740. 		You("snap your whip through thin air.");
1741. 	} else
1742. 		pline(msg_snap);
1743. 	return(1);
1744. }
1745. 
1746. 
1747. #define BY_OBJECT	((struct monst *)0)
1748. 
1749. /* return 1 if the wand is broken, hence some time elapsed */
1750. static int
1751. do_break_wand(obj)
1752.     struct obj *obj;
1753. {
1754.     static const char nothing_else_happens[] = "But nothing else happens...";
1755.     register int i, x, y;
1756.     register struct monst *mon;
1757.     int dmg, damage;
1758.     boolean affects_objects;
1759.     char confirm[QBUFSZ], the_wand[BUFSZ];
1760. 
1761.     Strcat(strcat(shk_your(the_wand, obj), " "), xname(obj));
1762.     Sprintf(confirm, "Are you really sure you want to break %s?", the_wand);
1763.     if (yn(confirm) == 'n' ) return 0;
1764. 
1765.     if (nohands(uasmon)) {
1766. 	You_cant("break %s without hands!", the_wand);
1767. 	return 0;
1768.     } else if (ACURR(A_STR) < 10) {
1769. 	You("don't have the strength to break %s!", the_wand);
1770. 	return 0;
1771.     }
1772.     pline("Raising %s high above your %s, you break it in two!",
1773. 	  the_wand, body_part(HEAD));
1774.     if (obj->spe <= 0) {
1775. 	pline(nothing_else_happens);
1776. 	goto discard_broken_wand;
1777.     }
1778.     obj->ox = u.ux;
1779.     obj->oy = u.uy;
1780.     current_wand = obj;		/* for destroy_item */
1781.     dmg = obj->spe * 4;
1782.     affects_objects = FALSE;
1783. 
1784.     switch (obj->otyp) {
1785.     case WAN_WISHING:
1786.     case WAN_NOTHING:
1787.     case WAN_LOCKING:
1788.     case WAN_PROBING:
1789.     case WAN_OPENING:
1790.     case WAN_SECRET_DOOR_DETECTION:
1791. 	pline(nothing_else_happens);
1792. 	goto discard_broken_wand;
1793.     case WAN_DEATH:
1794.     case WAN_LIGHTNING:
1795. 	dmg *= 2;
1796.     case WAN_FIRE:
1797.     case WAN_COLD:
1798. 	dmg *= 2;
1799.     case WAN_MAGIC_MISSILE:
1800. 	explode(u.ux, u.uy, (obj->otyp - WAN_MAGIC_MISSILE), dmg, WAND_CLASS);
1801. 	makeknown(obj->otyp);	/* explode described the effect */
1802. 	goto discard_broken_wand;
1803.     case WAN_STRIKING:
1804. 	/* we want this before the explosion instead of at the very end */
1805. 	pline("A wall of force smashes down around you!");
1806. 	dmg = d(1 + obj->spe,6);	/* normally 2d12 */
1807.     case WAN_CANCELLATION:
1808.     case WAN_POLYMORPH:
1809.     case WAN_TELEPORTATION:
1810.     case WAN_UNDEAD_TURNING:
1811. 	affects_objects = TRUE;
1812. 	break;
1813.     default:
1814. 	break;
1815.     }
1816. 
1817.     /* magical explosion and its visual effect occur before specific effects */
1818.     explode(obj->ox, obj->oy, 0, rnd(dmg), WAND_CLASS);
1819. 
1820.     /* this makes it hit us last, so that we can see the action first */
1821.     for (i = 0; i <= 8; i++) {
1822. 	bhitpos.x = x = obj->ox + xdir[i];
1823. 	bhitpos.y = y = obj->oy + ydir[i];
1824. 	if (!isok(x,y)) continue;
1825. 
1826. 	if (obj->otyp == WAN_DIGGING) {
1827. 	    if(dig_check(BY_OBJECT, FALSE, x, y))
1828. 		digactualhole(x, y, BY_OBJECT,
1829. 			      (rn2(obj->spe)<3 || !Can_fall_thru(&u.uz)) ?
1830. 			       PIT : HOLE);
1831. 	    continue;
1832. 	} else if(obj->otyp == WAN_CREATE_MONSTER) {
1833. 	    (void) makemon((struct permonst *)0, x, y);
1834. 	    continue;
1835. 	} else {
1836. 	    if (x == u.ux && y == u.uy) {
1837. 		damage = zapyourself(obj, FALSE);
1838. 		if (damage)
1839. 		    losehp(damage,
1840. 			   self_pronoun("killed %sself by breaking a wand",
1841. 					"him"),
1842. 			   NO_KILLER_PREFIX);
1843. 		if (flags.botl) bot();		/* blindness */
1844. 	    } else if ((mon = m_at(x, y)) != 0) {
1845. 		(void) bhitm(mon, obj);
1846. 	     /* if (flags.botl) bot(); */
1847. 	    }
1848. 	    if (affects_objects && level.objects[x][y]) {
1849. 		(void) bhitpile(obj, bhito, x, y);
1850. 		if (flags.botl) bot();		/* potion effects */
1851. 	    }
1852. 	}
1853.     }
1854. 
1855.     if (obj->otyp == WAN_LIGHT)
1856. 	litroom(TRUE, obj);	/* only needs to be done once */
1857. 
1858.  discard_broken_wand:
1859.     current_wand = 0;
1860.     check_unpaid(obj);	/* extra charge for _use_ prior to destruction */
1861.     delobj(obj);
1862.     nomul(0);
1863.     return 1;
1864. }
1865. 
1866. int
1867. doapply()
1868. {
1869. 	register struct obj *obj;
1870. 	register int res = 1;
1871. 
1872. 	if(check_capacity((char *)0)) return (0);
1873. 	obj = getobj(tools, "use or apply");
1874. 	if(!obj) return 0;
1875. 
1876. 	if (obj->oclass == WAND_CLASS)
1877. 	    return do_break_wand(obj);
1878. 
1879. 	switch(obj->otyp){
1880. 	case BLINDFOLD:
1881. 		if (obj == ublindf) {
1882. 		    if(cursed(obj)) break;
1883. 		    else Blindf_off(obj);
1884. 		}
1885. 		else if (!ublindf) Blindf_on(obj);
1886. 		else You("are already %s.", ublindf->otyp == TOWEL ?
1887. 			 "covered by a towel" : "wearing a blindfold");
1888. 		break;
1889. 	case BULLWHIP:
1890. 		res = use_whip(obj);
1891. 		break;
1892. 	case LARGE_BOX:
1893. 	case CHEST:
1894. 	case ICE_BOX:
1895. 	case SACK:
1896. 	case BAG_OF_HOLDING:
1897. 	case OILSKIN_SACK:
1898. 		res = use_container(obj, 1);
1899. 		break;
1900. 	case BAG_OF_TRICKS:
1901. 		if(obj->spe > 0) {
1902. 			register int cnt = 1;
1903. 
1904. 			check_unpaid(obj);
1905. 			obj->spe--;
1906. 			if(!rn2(23)) cnt += rn2(7) + 1;
1907. 			while(cnt--)
1908. 			    (void) makemon((struct permonst *) 0, u.ux, u.uy);
1909. 			makeknown(BAG_OF_TRICKS);
1910. 		} else
1911. 			pline(nothing_happens);
1912. 		break;
1913. 	case CAN_OF_GREASE:
1914. 		use_grease(obj);
1915. 		break;
1916. 	case LOCK_PICK:
1917. #ifdef TOURIST
1918. 	case CREDIT_CARD:
1919. #endif
1920. 	case SKELETON_KEY:
1921. 		(void) pick_lock(obj);
1922. 		break;
1923. 	case PICK_AXE:
1924. 		res = use_pick_axe(obj);
1925. 		break;
1926. 	case TINNING_KIT:
1927. 		use_tinning_kit(obj);
1928. 		break;
1929. 	case LEASH:
1930. 		use_leash(obj);
1931. 		break;
1932. 	case MAGIC_WHISTLE:
1933. 		use_magic_whistle(obj);
1934. 		break;
1935. 	case TIN_WHISTLE:
1936. 		use_whistle(obj);
1937. 		break;
1938. 	case STETHOSCOPE:
1939. 		res = use_stethoscope(obj);
1940. 		break;
1941. 	case MIRROR:
1942. 		res = use_mirror(obj);
1943. 		break;
1944. 	case BELL:
1945. 	case BELL_OF_OPENING:
1946. 		use_bell(obj);
1947. 		break;
1948. 	case CANDELABRUM_OF_INVOCATION:
1949. 		use_candelabrum(obj);
1950. 		break;
1951. 	case WAX_CANDLE:
1952. 	case TALLOW_CANDLE:
1953. 		use_candle(obj);
1954. 		break;
1955. 	case OIL_LAMP:
1956. 	case MAGIC_LAMP:
1957. 	case BRASS_LANTERN:
1958. 		use_lamp(obj);
1959. 		break;
1960. 	case POT_OIL:
1961. 		light_cocktail(obj);
1962. 		break;
1963. #ifdef TOURIST
1964. 	case EXPENSIVE_CAMERA:
1965. 		res = use_camera(obj);
1966. 		break;
1967. #endif
1968. 	case TOWEL:
1969. 		res = use_towel(obj);
1970. 		break;
1971. 	case CRYSTAL_BALL:
1972. 		use_crystal_ball(obj);
1973. 		break;
1974. 	case MAGIC_MARKER:
1975. 		res = dowrite(obj);
1976. 		break;
1977. 	case TIN_OPENER:
1978. 		if(!carrying(TIN)) {
1979. 			You("have no tin to open.");
1980. 			goto xit;
1981. 		}
1982. 		You("cannot open a tin without eating or discarding its contents.");
1983. 		if(flags.verbose)
1984. 			pline("In order to eat, use the 'e' command.");
1985. 		if(obj != uwep)
1986.     pline("Opening the tin will be much easier if you wield the tin opener.");
1987. 		goto xit;
1988. 
1989. 	case FIGURINE:
1990. 		use_figurine(obj);
1991. 		break;
1992. 	case UNICORN_HORN:
1993. 		use_unicorn_horn(obj);
1994. 		break;
1995. 	case WOODEN_FLUTE:
1996. 	case MAGIC_FLUTE:
1997. 	case TOOLED_HORN:
1998. 	case FROST_HORN:
1999. 	case FIRE_HORN:
2000. 	case WOODEN_HARP:
2001. 	case MAGIC_HARP:
2002. 	case BUGLE:
2003. 	case LEATHER_DRUM:
2004. 	case DRUM_OF_EARTHQUAKE:
2005. 		res = do_play_instrument(obj);
2006. 		break;
2007. 	case HORN_OF_PLENTY:	/* not a musical instrument */
2008. 		if (obj->spe > 0) {
2009. 		    struct obj *otmp;
2010. 		    const char *what;
2011. 
2012. 		    check_unpaid(obj);
2013. 		    obj->spe--;
2014. 		    if (!rn2(13)) {
2015. 			otmp = mkobj(POTION_CLASS, FALSE);
2016. 			if (objects[otmp->otyp].oc_magic) do {
2017. 			    otmp->otyp = rnd_class(POT_BOOZE, POT_WATER);
2018. 			} while (otmp->otyp == POT_SICKNESS);
2019. 			what = "A potion";
2020. 		    } else {
2021. 			otmp = mkobj(FOOD_CLASS, FALSE);
2022. 			if (otmp->otyp == FOOD_RATION && !rn2(7))
2023. 			    otmp->otyp = LUMP_OF_ROYAL_JELLY;
2024. 			what = "Some food";
2025. 		    }
2026. 		    pline("%s spills out.", what);
2027. 		    otmp->blessed = obj->blessed;
2028. 		    otmp->cursed = obj->cursed;
2029. 		    otmp->owt = weight(otmp);
2030. 		    otmp = hold_another_object(otmp,
2031. 					(u.uswallow || Is_airlevel(&u.uz) ||
2032. 					 u.uinwater || Is_waterlevel(&u.uz)) ?
2033. 					       "Oops!  %s away from you!" :
2034. 					       "Oops!  %s to the floor!",
2035. 					       The(aobjnam(otmp, "slip")),
2036. 					       (const char *)0);
2037. 		    makeknown(HORN_OF_PLENTY);
2038. 		} else
2039. 		    pline(nothing_happens);
2040. 		break;
2041. 	case LAND_MINE:
2042. 	case BEARTRAP:
2043. 		use_trap(obj);
2044. 		break;
2045. 	default:
2046. 		pline("Sorry, I don't know how to use that.");
2047. 	xit:
2048. 		nomul(0);
2049. 		return 0;
2050. 	}
2051. 	nomul(0);
2052. 	return res;
2053. }
2054. 
2055. #endif /* OVLB */
2056. 
2057. /*apply.c*/

Also on Fandom

Random Wiki