Source:NetHack 3.0.0/apply.c

From NetHackWiki
Revision as of 04:17, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/apply.c moved to Source:NetHack 3.0.0/apply.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Below is the full text to apply.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.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.

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

1.    /*	SCCS Id: @(#)apply.c	3.0	88/10/24
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    /* block some unused #defines to avoid overloading some cpp's */
6.    #define MONATTK_H
7.    #include	"hack.h"
8.    #include	"edog.h"
9.    
10.   #ifdef MUSIC
11.   #define IS_INSTRUMENT(typ)	((typ) >= FLUTE && (typ) <= DRUM_OF_EARTHQUAKE)
12.   #endif /* MUSIC /**/
13.   
14.   static const char tools[] = { TOOL_SYM, 0 };
15.   
16.   static boolean did_dig_msg;
17.   
18.   /* version of bhit for cameras and mirrors */
19.   static
20.   struct monst *
21.   bchit(ddx,ddy,range,sym) register int ddx,ddy,range; char sym; {
22.   	register struct monst *mtmp = (struct monst *) 0;
23.   	register int bchx = u.ux, bchy = u.uy;
24.   
25.   	if(sym) {
26.   		Tmp_at2(-1, sym);	/* open call */
27.   #ifdef MSDOSCOLOR
28.   		Tmp_at2(-3, (int)AT_WHITE);
29.   #endif
30.   	}
31.   	while(range--) {
32.   		bchx += ddx;
33.   		bchy += ddy;
34.   		if(levl[bchx][bchy].mmask) {
35.   			mtmp = m_at(bchx,bchy);
36.   			break;
37.   		}
38.   		if(!ZAP_POS(levl[bchx][bchy].typ) ||
39.   		    (IS_DOOR(levl[bchx][bchy].typ) &&
40.   			    (levl[bchx][bchy].doormask & (D_CLOSED | D_LOCKED)))
41.   		  ) {
42.   			bchx -= ddx;
43.   			bchy -= ddy;
44.   			break;
45.   		}
46.   		if(sym) Tmp_at2(bchx, bchy);
47.   	}
48.   	if(sym) Tmp_at2(-1, -1);
49.   	return(mtmp);
50.   }
51.   
52.   static void
53.   use_camera(obj) /* register */ struct obj *obj; {
54.   register struct monst *mtmp;
55.   	if(!getdir(1)){		/* ask: in what direction? */
56.   		flags.move = multi = 0;
57.   		return;
58.   	}
59.   	if(u.uswallow) {
60.   		You("take a picture of %s's stomach.", mon_nam(u.ustuck));
61.   		return;
62.   	}
63.   	if(obj->cursed && !rn2(2)) goto blindu;
64.   	if(u.dz) {
65.   		You("take a picture of the %s.",
66.   			(u.dz > 0) ? "floor" : "ceiling");
67.   		return;
68.   	}
69.   	if(!u.dx && !u.dy && !u.dz) {
70.   blindu:
71.   		if(!Blind) {
72.   			You("are blinded by the flash!");
73.   			make_blinded((long)rnd(25),FALSE);
74.   		}
75.   		return;
76.   	}
77.   	if(mtmp = bchit(u.dx, u.dy, COLNO, '!')) {
78.   		if(mtmp->msleep){
79.   			mtmp->msleep = 0;
80.   			pline("The flash awakens %s.", mon_nam(mtmp)); /* a3 */
81.   		} else
82.   		if(mtmp->data->mlet != S_YLIGHT)
83.   		if(mtmp->mcansee || mtmp->mblinded){
84.   			register int tmp = dist(mtmp->mx,mtmp->my);
85.   			register int tmp2;
86.   			if(cansee(mtmp->mx,mtmp->my))
87.   			  pline("%s is blinded by the flash!", Monnam(mtmp));
88.   			if(mtmp->data == &mons[PM_GREMLIN]) {
89.   			  /* Rule #1: Keep them out of the light. */
90.   			  kludge("%s cries out in pain!", Monnam(mtmp));
91.   			  if (mtmp->mhp > 1) mtmp->mhp--;
92.   			}
93.   			setmangry(mtmp);
94.   			if(tmp < 9 && !mtmp->isshk && rn2(4)) {
95.   				mtmp->mflee = 1;
96.   				if(rn2(4)) mtmp->mfleetim = rnd(100);
97.   			}
98.   			if(tmp < 3) mtmp->mcansee  = mtmp->mblinded = 0;
99.   			else {
100.  				tmp2 = mtmp->mblinded;
101.  				tmp2 += rnd(1 + 50/tmp);
102.  				if(tmp2 > 127) tmp2 = 127;
103.  				mtmp->mblinded = tmp2;
104.  				mtmp->mcansee = 0;
105.  			}
106.  		}
107.  	}
108.  }
109.  
110.  /* Strictly speaking it makes no sense for usage of a stethoscope to
111.     not take any time; however, unless it did, the stethoscope would be
112.     almost useless. */
113.  static void
114.  use_stethoscope(obj) register struct obj *obj; {
115.  register struct monst *mtmp;
116.  register struct rm *lev;
117.  register int rx, ry;
118.  	if(!freehand()) {
119.  		You("have no free %s!", body_part(HAND));
120.  		return;
121.  	}
122.  	if (!getdir(1)) {
123.  		flags.move=multi=0;
124.  		return;
125.  	}
126.  	if(u.dz < 0 || (u.dz && Levitation)) {
127.  		You("can't reach the %s!", u.dz<0 ? "ceiling" : "floor");
128.  		return;
129.  	}
130.  	if(obj->cursed && !rn2(2)) {
131.  		You("hear your heart beat.");
132.  		return;
133.  	}
134.  	if(u.dz) {
135.  #ifdef STRONGHOLD
136.  		if (dlevel == stronghold_level)
137.  			You("hear the crackling of hellfire.");
138.  		else
139.  #endif
140.  			pline("The floor seems healthy enough.");
141.  		return;
142.  	}
143.  	if (Stunned || (Confusion && !rn2(5))) confdir();
144.  	if (!u.dx && !u.dy && !u.dz) {
145.  		ustatusline();
146.  		return;
147.  	}
148.  	rx = u.ux + u.dx; ry = u.uy + u.dy;
149.  	if(u.uswallow) {
150.  		mstatusline(u.ustuck);
151.  		return;
152.  	}
153.  	if (!isok(rx,ry)) {
154.  		You("hear a faint typing noise.");
155.  		return;
156.  	}
157.  	lev = &levl[rx][ry];
158.  	if(lev->mmask) {
159.  		mtmp = m_at(rx,ry);
160.  		mstatusline(mtmp);
161.  		return;
162.  	}
163.  	if(lev->typ == SDOOR) {
164.  		You("hear a hollow sound!  This must be a secret door!");
165.  		lev->typ = DOOR;
166.  		lev->seen = 0;		/* force prl */
167.  		prl(rx,ry);
168.  		return;
169.  	}
170.  	if(lev->typ == SCORR) {
171.  		You("hear a hollow sound!  This must be a secret passage!");
172.  		lev->typ = CORR;
173.  		lev->seen = 0;		/* force prl */
174.  		prl(rx,ry);
175.  		return;
176.  	}
177.  	You("hear nothing special.");
178.  }
179.  
180.  /* ARGSUSED */
181.  static void
182.  use_whistle(obj)
183.  struct obj *obj; {
184.  	You("produce a high whistling sound.");
185.  	wake_nearby();
186.  }
187.  
188.  static void
189.  use_magic_whistle(obj)
190.  struct obj *obj; {
191.  	register struct monst *mtmp = fmon;
192.  
193.  	if(obj->cursed && !rn2(2)) {
194.  		You("produce a high-pitched humming noise.");
195.  		wake_nearby();
196.  	} else {
197.  		You("produce a %s whistling sound.", Hallucination
198.  			? "normal" : "strange");
199.  		while(mtmp) {
200.  			if(mtmp->mtame) mnexto(mtmp);
201.  			mtmp = mtmp->nmon;
202.  		}
203.  	}
204.  }
205.  
206.  boolean
207.  um_dist(x,y,n)
208.  register xchar x, y, n;
209.  {
210.  	return(abs(u.ux - x) > n  || abs(u.uy - y) > n);
211.  }
212.  
213.  #ifdef WALKIES
214.  #define MAXLEASHED	2
215.  
216.  int
217.  number_leashed()
218.  {
219.  	register int i = 0;
220.  	register struct obj *obj;
221.  
222.  	for(obj = invent; obj; obj = obj->nobj)
223.  		if(obj->otyp == LEASH && obj->leashmon != 0) i++;
224.  	return(i);
225.  }
226.  
227.  void
228.  o_unleash(otmp) 	/* otmp is about to be destroyed or stolen */
229.  register struct obj *otmp;
230.  {
231.  	register struct monst *mtmp;
232.  
233.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
234.  		if(mtmp->m_id == (unsigned)otmp->leashmon)
235.  			mtmp->mleashed = 0;
236.  	otmp->leashmon = 0;
237.  }
238.  
239.  void
240.  m_unleash(mtmp) 	/* mtmp is about to die, or become untame */
241.  register struct monst *mtmp;
242.  {
243.  	register struct obj *otmp;
244.  
245.  	for(otmp = invent; otmp; otmp = otmp->nobj)
246.  		if(otmp->otyp == LEASH &&
247.  				otmp->leashmon == (int)mtmp->m_id)
248.  			otmp->leashmon = 0;
249.  	mtmp->mleashed = 0;
250.  }
251.  
252.  void
253.  unleash_all()		/* player is about to die (for bones) */
254.  {
255.  	register struct obj *otmp;
256.  	register struct monst *mtmp;
257.  
258.  	for(otmp = invent; otmp; otmp = otmp->nobj)
259.  		if(otmp->otyp == LEASH) otmp->leashmon = 0;
260.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
261.  		if(mtmp->mtame) mtmp->mleashed = 0;
262.  }
263.  
264.  /* ARGSUSED */
265.  static void
266.  use_leash(obj)
267.  struct obj *obj;
268.  {
269.  	register int x, y;
270.  	register struct monst *mtmp;
271.  
272.  	if(!obj->leashmon && number_leashed() >= MAXLEASHED) {
273.  		You("can't leash additional pets.");
274.  		return;
275.  	}
276.  
277.  	if(!getdir(1)) return;
278.  
279.  	x = u.ux + u.dx;
280.  	y = u.uy + u.dy;
281.  
282.  	if((x == u.ux) && (y == u.uy)) {
283.  		pline("Leash yourself?  Very funny...");
284.  		return;
285.  	}
286.  
287.  	if(levl[x][y].mmask == 0) {
288.  		pline("There is no creature here.");
289.  		return;
290.  	}
291.  
292.  	mtmp = m_at(x, y);
293.  
294.  	if(!mtmp->mtame) {
295.  		pline("%s is not %s!", Monnam(mtmp), (!obj->leashmon) ?
296.  				"leashable" : "leashed");
297.  		return;
298.  	}
299.  	if(!obj->leashmon) {
300.  		if(mtmp->mleashed) {
301.  			pline("This %s is already leashed!", lmonnam(mtmp)+4);
302.  			return;
303.  		}
304.  		You("slip the leash around your %s.",
305.  				mtmp->data->mname);
306.  		mtmp->mleashed = 1;
307.  		obj->leashmon = (int)mtmp->m_id;
308.  		if(mtmp->msleep)  mtmp->msleep = 0;
309.  		return;
310.  	}
311.  	if(obj->leashmon != (int)mtmp->m_id) {
312.  		pline("This leash is not attached to that creature!");
313.  		return;
314.  	} else {
315.  		if(obj->cursed) {
316.  			pline("The leash wouldn't come off!");
317.  			return;
318.  		}
319.  		mtmp->mleashed = 0;
320.  		obj->leashmon = 0;
321.  		You("remove the leash from your %s.",
322.  		/* a hack to include the dogs full name.  +4 eliminates */
323.  		/* the 'the' at the start of the name */
324.  				 lmonnam(mtmp)+4);
325.  	}
326.  	return;
327.  }
328.  
329.  boolean
330.  next_to_u()
331.  {
332.  	register struct monst *mtmp;
333.  	register struct obj *otmp;
334.  
335.  	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
336.  		if(mtmp->mleashed) {
337.  			if(dist(mtmp->mx,mtmp->my) > 2) mnexto(mtmp);
338.  			if(dist(mtmp->mx,mtmp->my) > 2) {
339.  			    for(otmp = invent; otmp; otmp = otmp->nobj)
340.  				if(otmp->otyp == LEASH &&
341.  					otmp->leashmon == (int)mtmp->m_id) {
342.  				    if(otmp->cursed) return(FALSE);
343.  				    You("feel %s leash go slack.",
344.  					(number_leashed() > 1) ? "a" : "the");
345.  				    mtmp->mleashed = 0;
346.  				    otmp->leashmon = 0;
347.  				}
348.  			}
349.  		}
350.  	return(TRUE);
351.  }
352.  
353.  struct obj *
354.  get_mleash(mtmp) 	/* assuming mtmp->mleashed has been checked */
355.  register struct monst *mtmp;
356.  {
357.  	register struct obj *otmp;
358.  
359.  	otmp = invent;
360.  	while(otmp) {
361.  		if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id)
362.  			return(otmp);
363.  		otmp = otmp->nobj;
364.  	}
365.  	return((struct obj *)0);
366.  }
367.  
368.  void
369.  check_leash(x, y)
370.  register xchar x, y;
371.  {
372.  	register struct obj *otmp;
373.  	register struct monst *mtmp = fmon;
374.  
375.  	for(otmp = invent; otmp; otmp = otmp->nobj)
376.  	    if(otmp->otyp == LEASH && otmp->leashmon != 0) {
377.  		while(mtmp) {
378.  		    if((int)mtmp->m_id == otmp->leashmon &&
379.  			    (dist2(u.ux,u.uy,mtmp->mx,mtmp->my) >
380.  				dist2(x,y,mtmp->mx,mtmp->my))
381.  			) {
382.  			if(otmp->cursed) {
383.  			    if(um_dist(mtmp->mx, mtmp->my, 5)) {
384.  				pline("%s chokes to death!",Monnam(mtmp));
385.  				mondied(mtmp);
386.  			    } else
387.  				if(um_dist(mtmp->mx, mtmp->my, 3))
388.  					pline("%s chokes on the leash!",
389.  						Monnam(mtmp));
390.  			} else {
391.  			    if(um_dist(mtmp->mx, mtmp->my, 5)) {
392.  				pline("%s's leash snaps loose!",Monnam(mtmp));
393.  				m_unleash(mtmp);
394.  			    } else {
395.  				if(um_dist(mtmp->mx, mtmp->my, 3)) {
396.  				    You("pull on the leash.");
397.  # ifdef SOUNDS
398.  				    if (mtmp->data->msound != MS_SILENT)
399.  				    switch(rn2(3)) {
400.  					case 0:  growl(mtmp);	break;
401.  					case 1:  yelp(mtmp);	break;
402.  					default: whimper(mtmp); break;
403.  				    }
404.  # endif
405.  				}
406.  			    }
407.  			}
408.  		    }
409.  		    mtmp = mtmp->nmon;
410.  		}
411.  	    }
412.  }
413.  #endif /* WALKIES */
414.  
415.  
416.  static int
417.  dig() {
418.  	register struct rm *lev;
419.  	register int dpx = dig_pos.x, dpy = dig_pos.y;
420.  
421.  	lev = &levl[dpx][dpy];
422.  	/* perhaps a nymph stole his pick-axe while he was busy digging */
423.  	/* or perhaps he teleported away */
424.  	if(u.uswallow || !uwep || uwep->otyp != PICK_AXE ||
425.  	    dig_level != dlevel ||
426.  	    ((dig_down && (dpx != u.ux || dpy != u.uy)) ||
427.  	     (!dig_down && dist(dpx,dpy) > 2)))
428.  		return(0);
429.  
430.  	if(dig_down && is_maze_lev) {
431.  		pline("The floor here is too hard to dig in.");
432.  		return(0);
433.  	}
434.  	if(!dig_down && IS_ROCK(lev->typ) && !may_dig(dpx,dpy)) {
435.  		pline("This wall is too hard to dig into.");
436.  		return(0);
437.  	}
438.  	if(Fumbling && !rn2(3)) {
439.  		switch(rn2(3)) {
440.  		case 0:  if(!welded(uwep)) {
441.  			     You("fumble and drop your %s", xname(uwep));
442.  			     dropx(uwep);
443.  			 } else {
444.  			     pline("Ouch!  Your %s bounces and hits you!",
445.  				xname(uwep));
446.  			     set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
447.  			 }
448.  			 break;
449.  		case 1:  pline("Bang!  You hit with the broad side of the %s!",
450.  			 xname(uwep)); break;
451.  		default: Your("swing misses its mark."); 
452.  			 break;
453.  		}
454.  		return(0);
455.  	}
456.  	dig_effort += 10 + abon() + uwep->spe + rn2(5);
457.  	if(dig_down) {
458.  		if(dig_effort > 250) {
459.  			dighole();
460.  			dig_level = -1;
461.  			return(0);	/* done with digging */
462.  		}
463.  		if(dig_effort > 50) {
464.  			register struct trap *ttmp = t_at(dpx,dpy);
465.  
466.  			if(!ttmp) {
467.  				ttmp = maketrap(dpx,dpy,PIT);
468.  				ttmp->tseen = 1;
469.  				if(Invisible) newsym(ttmp->tx,ttmp->ty);
470.  				You("have dug a pit.");
471.  				u.utrap = rn1(4,2);
472.  				u.utraptype = TT_PIT;
473.  				dig_level = -1;
474.  				return(0);
475.  			}
476.  		}
477.  	} else
478.  	if(dig_effort > 100) {
479.  		register char *digtxt;
480.  		register struct obj *obj;
481.  
482.  		if(obj = sobj_at(BOULDER, dpx, dpy)) {
483.  			fracture_rock(obj);
484.  			digtxt = "The boulder falls apart.";
485.  		} else if(obj = sobj_at(STATUE, dpx, dpy)) {
486.  			if (break_statue(obj))
487.  				digtxt = "The statue shatters.";
488.  			else
489.  	digtxt = "Instead of shattering, the statue suddenly comes alive!";
490.  		} else if(!lev->typ || lev->typ == SCORR) {
491.  			lev->typ = CORR;
492.  			digtxt = "You succeeded in cutting away some rock.";
493.  		} else if(IS_WALL(lev->typ)) {
494.  			lev->typ = is_maze_lev ? ROOM : DOOR;
495.  			digtxt = "You just made an opening in the wall.";
496.  		} else if(lev->typ == SDOOR) {
497.  			lev->typ = DOOR;
498.  			digtxt = "You just broke through a secret door.";
499.  			if(!(lev->doormask & D_TRAPPED))
500.  				lev->doormask = D_BROKEN;
501.  		} else if (IS_DOOR(lev->typ) &&
502.  			   (lev->doormask & (D_CLOSED | D_LOCKED))) {
503.  			digtxt = "You just broke a hole through the door.";
504.  			if(!(lev->doormask & D_TRAPPED))
505.  				lev->doormask = D_BROKEN;
506.  		} else
507.  		  digtxt = "Now what exactly was it that you were digging in?";
508.  		mnewsym(dpx, dpy);
509.  		prl(dpx, dpy);
510.  		pline(digtxt);		/* after mnewsym & prl */
511.  		if(IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) {
512.  			b_trapped("door");
513.  			lev->doormask = D_NODOOR;
514.  		}
515.  		dig_level = -1;
516.  		return(0);
517.  	} else {
518.  		if(IS_WALL(lev->typ) ||
519.  		 (IS_DOOR(lev->typ) && lev->doormask & (D_CLOSED | D_LOCKED))) {
520.  		    register int rno = inroom(dpx,dpy);
521.  
522.  		    if(rno >= 0 && rooms[rno].rtype >= SHOPBASE) {
523.  			pline("This %s seems too hard to dig into.",
524.  			IS_DOOR(lev->typ) ? "door" : "wall");
525.  			return(0);
526.  		    }
527.  		}
528.  		if(!did_dig_msg) {
529.  		    You("hit the %s with all your might.",
530.  			sobj_at(STATUE, dpx, dpy) ? "statue" :
531.  			sobj_at(BOULDER, dpx, dpy) ? "boulder" :
532.  			IS_DOOR(lev->typ) ? "door" : "rock");
533.  		    did_dig_msg = TRUE;
534.  		}
535.  	}
536.  	return(1);
537.  }
538.  
539.  /* When will hole be finished? Very rough indication used by shopkeeper. */
540.  int
541.  holetime() {
542.  	return( (occupation == dig) ? (250 - dig_effort)/20 : -1);
543.  }
544.  
545.  void
546.  dighole()
547.  {
548.  	register struct trap *ttmp = t_at(u.ux, u.uy);
549.  
550.  	if(is_maze_lev
551.  #ifdef ENDGAME
552.  			|| dlevel == ENDLEVEL
553.  #endif
554.  						) {
555.  		pline("The floor here seems too hard to dig in.");
556.  	} else {
557.  		if(IS_FURNITURE(levl[u.ux][u.uy].typ)) {
558.  #if defined(ALTARS) && defined(THEOLOGY)
559.  	            if(IS_ALTAR(levl[u.ux][u.uy].typ)) {
560.  		    	altar_wrath(u.ux, u.uy);
561.  			if(in_temple(u.ux, u.uy)) angry_priest();
562.  		    }
563.  #endif
564.  		    levl[u.ux][u.uy].typ = ROOM;
565.  		    levl[u.ux][u.uy].altarmask = 0;
566.  		}
567.  		if(ttmp)
568.  			ttmp->ttyp = TRAPDOOR;
569.  		else
570.  			ttmp = maketrap(u.ux, u.uy, TRAPDOOR);
571.  		ttmp->tseen = 1;
572.  		if(Invisible) newsym(ttmp->tx,ttmp->ty);
573.  		pline("You've made a hole in the floor.");
574.  		if(!u.ustuck && !Levitation) {			/* KAA */
575.  			if(inshop())
576.  				shopdig(1);
577.  #ifdef WALKIES
578.  			if(!next_to_u())
579.  			    You("are jerked back by your pet!");
580.  			else {
581.  #endif
582.  			    You("fall through...");
583.  			    if(u.utraptype == TT_PIT) {
584.  				u.utrap = 0;
585.  				u.utraptype = 0;
586.  			    }
587.  			    unsee();
588.  			    goto_level(dlevel+1, FALSE);
589.  #ifdef WALKIES
590.  			}
591.  #endif
592.  		}
593.  	}
594.  }
595.  
596.  static boolean
597.  wield_tool(obj)
598.  struct obj *obj;
599.  {
600.  	if(uwep && uwep->cursed) {
601.  		/* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */
602.  		if(flags.verbose) {
603.  			pline("Since your weapon is welded to your %s,",
604.  				bimanual(uwep) ?
605.  				makeplural(body_part(HAND))
606.  				: body_part(HAND));
607.  			pline("you cannot wield that %s.", xname(obj));
608.  		}
609.  		return(FALSE);
610.  	}
611.  # ifdef POLYSELF
612.  	if(cantwield(uasmon)) {
613.  		You("can't hold it strongly enough.");
614.  		return(FALSE);
615.  	}
616.  # endif
617.  	unweapon = TRUE;
618.  	You("now wield %s.", doname(obj));
619.  	setuwep(obj);
620.  	if (uwep != obj) return(FALSE); /* rewielded old object after dying */
621.  	return(TRUE);
622.  }
623.  
624.  static int
625.  use_pick_axe(obj)
626.  struct obj *obj;
627.  {
628.  	char dirsyms[12];
629.  	register char *dsp = dirsyms, *sdp = flags.num_pad ? ndir : sdir;
630.  	register struct rm *lev;
631.  	register int rx, ry, res = 0;
632.  	register boolean isclosedoor = FALSE;
633.  
634.  	if(obj != uwep)
635.  	    if (!wield_tool(obj)) return(0);
636.  	    else res = 1;
637.  
638.  	while(*sdp) {
639.  		(void) movecmd(*sdp);	/* sets u.dx and u.dy and u.dz */
640.  		rx = u.ux + u.dx;
641.  		ry = u.uy + u.dy;
642.  		if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) &&
643.  		    (IS_ROCK(levl[rx][ry].typ)
644.  		    || sobj_at(STATUE, rx, ry)
645.  		    || sobj_at(BOULDER, rx, ry))))
646.  			*dsp++ = *sdp;
647.  		sdp++;
648.  	}
649.  	*dsp = 0;
650.  	pline("In what direction do you want to dig? [%s] ", dirsyms);
651.  	if(!getdir(0))		/* no txt */
652.  		return(res);
653.  	if(u.uswallow && attack(u.ustuck)) /* return(1) */;
654.  	else if(u.dz < 0) You("cannot reach the ceiling.");
655.  	else if(!u.dx && !u.dy && !u.dz) {
656.  		int dam;
657.  
658.  		dam = rnd(2) + dbon();
659.  		if (dam <= 0) dam = 1;
660.  		You("hit yourself with your own pick-axe.");
661.  		losehp(dam, "self-inflicted wound");
662.  		flags.botl=1;
663.  		return(1);
664.  	} else if(u.dz == 0) {
665.  		if(Stunned || (Confusion && !rn2(5))) confdir();
666.  		rx = u.ux + u.dx;
667.  		ry = u.uy + u.dy;
668.  		lev = &levl[rx][ry];
669.  		if(lev->mmask && attack(m_at(rx, ry)))
670.  			return(1);
671.  		if(!isok(rx, ry)) {
672.  			pline("Clash!");
673.  			return(1);
674.  		}
675.  		isclosedoor = (IS_DOOR(lev->typ) &&
676.  			       (lev->doormask & (D_CLOSED | D_LOCKED)));
677.  		if(!IS_ROCK(lev->typ)
678.  		     && (!IS_DOOR(lev->typ) || (lev->doormask==D_NODOOR
679.  			|| lev->doormask & (D_ISOPEN | D_BROKEN)))
680.  		     && !sobj_at(STATUE, rx, ry)
681.  		     && !sobj_at(BOULDER, rx, ry)) {
682.  			/* ACCESSIBLE or POOL */
683.  			You("swing your %s through thin air.",
684.  				aobjnam(obj, NULL));
685.  		} else {
686.  			if(dig_pos.x != rx || dig_pos.y != ry
687.  			    || dig_level != dlevel || dig_down) {
688.  				dig_down = FALSE;
689.  				dig_pos.x = rx;
690.  				dig_pos.y = ry;
691.  				dig_level = dlevel;
692.  				dig_effort = 0;
693.  			    	You("start %s.",
694.  				   isclosedoor ? "chopping at the door" :
695.  				   sobj_at(STATUE, rx, ry) ?
696.  						"chipping the statue" :
697.  				   sobj_at(BOULDER, rx, ry) ?
698.  						"hitting the boulder" :
699.  						"digging");
700.  			} else
701.  				You("continue %s.",
702.  				   isclosedoor ? "chopping at the door" :
703.  				   sobj_at(STATUE, rx, ry) ?
704.  						"chipping the statue" :
705.  				   sobj_at(BOULDER, rx, ry) ?
706.  						"hitting the boulder" :
707.  						"digging");
708.  			did_dig_msg = FALSE;
709.  			set_occupation(dig, "digging", 0);
710.  		}
711.  	} else if(Levitation) {
712.  		You("cannot reach the floor.");
713.  	} else {
714.  		if(dig_pos.x != u.ux || dig_pos.y != u.uy
715.  		    || dig_level != dlevel || !dig_down) {
716.  			dig_down = TRUE;
717.  			dig_pos.x = u.ux;
718.  			dig_pos.y = u.uy;
719.  			dig_level = dlevel;
720.  			dig_effort = 0;
721.  			You("start digging in the floor.");
722.  			if(inshop())
723.  				shopdig(0);
724.  		} else
725.  			You("continue digging in the floor.");
726.  		did_dig_msg = FALSE;
727.  		set_occupation(dig, "digging", 0);
728.  	}
729.  	return(1);
730.  }
731.  
732.  #define WEAK	3	/* from eat.c */
733.  
734.  #ifdef MEDUSA
735.  static void
736.  use_mirror(obj)
737.  struct obj *obj;
738.  {
739.       register struct monst *mtmp;
740.       register char mlet;
741.  
742.  	if(!getdir(1)){		/* ask: in what direction? */
743.  		flags.move = multi = 0;
744.  		return;
745.  	}
746.  	if(!u.dx && !u.dy && !u.dz) {
747.  		if(!Blind && !Invisible)
748.  #ifdef POLYSELF
749.  		    if(u.umonnum == PM_FLOATING_EYE) {
750.  			pline("Yikes!  You've frozen yourself!");
751.  			nomul(-rnd((MAXULEV+6) - (int)u.ulevel));
752.  		    } else if (u.usym == S_VAMPIRE || u.usym == S_DEMON)
753.  			You("don't seem to reflect anything.");
754.  		    else if(u.umonnum == PM_UMBER_HULK) {
755.  			pline("Huh?  That doesn't look like you!");
756.  			make_confused(HConfusion + d(3,4),FALSE);
757.  		    } else
758.  #endif
759.  			   if (Hallucination) You("look %s.", hcolor());
760.  		    else if (Sick)
761.  			You("look peakish.");
762.  		    else if (u.uhs >= WEAK)
763.  			You("look undernourished.");
764.  #ifdef POLYSELF
765.  		    else if (u.usym == S_NYMPH
766.  #ifdef HARD
767.  			     || u.umonnum==PM_SUCCUBUS
768.  #endif
769.  			     )
770.  			You("look beautiful in the mirror.");
771.  #ifdef HARD
772.  		    else if (u.umonnum == PM_INCUBUS)
773.  			You("look handsome in the mirror.");
774.  #endif
775.  #endif
776.  		    else You("look as %s as ever.",
777.  				ACURR(A_CHA) > 14 ?
778.  				(poly_gender()==1 ? "beautiful" : "handsome") :
779.  				"ugly");
780.  		else {
781.  		if (rn2(4-u.uluck/3) || !HTelepat ||
782.  		    (u.ukilled_medusa
783.  #ifdef HARD
784.  			&& u.udemigod
785.  #endif
786.  		    )) {
787.  			You("can't see your %s %s.",
788.  				ACURR(A_CHA) > 14 ?
789.  				(poly_gender()==1 ? "beautiful" : "handsome") :
790.  				"ugly",
791.  				body_part(FACE));
792.  		} else {
793.  			static char buf[35];
794.  			char *tm, *tl; int ll;
795.  			if (!u.ukilled_medusa && rn2(4)) {
796.  			    tm = "n ugly snake-headed monster";
797.  			    ll = dlevel - medusa_level;
798.  			}
799.  			else {
800.  			    tm = " powerful wizard";
801.  			    ll = dlevel - wiz_level;
802.  			}
803.  			if (ll < -10) tl = "far below you";
804.  			else if (ll < -1) tl = "below you";
805.  			else if (ll == -1) {
806.  			    Sprintf(buf, "under your %s", makeplural(
807.  				body_part(FOOT)));
808.  			    tl = buf;
809.  			} else if (ll == 0)  tl = "very close to you";
810.  			else if (ll == 1) {
811.  			    Sprintf(buf, "above your %s", body_part(HEAD));
812.  			    tl = buf;
813.  			} else if (ll > 10) tl = "far above you";
814.  			else tl = "above you";
815.  			You("get an impression that a%s lives %s.",
816.  				tm, tl);
817.  		    }
818.  		}
819.  		return;
820.  	}
821.  	if(u.uswallow) {
822.  		You("reflect %s's stomach.", mon_nam(u.ustuck));
823.  		return;
824.  	}
825.  	if(u.dz) {
826.  		You("reflect the %s.",
827.  			(u.dz > 0) ? "floor" : "ceiling");
828.  		return;
829.  	}
830.  	if((mtmp = bchit(u.dx, u.dy, COLNO, 0)) && haseyes(mtmp->data)) {
831.  	    mlet = mtmp->data->mlet;
832.  	    if(mtmp->msleep) {
833.  		if (!Blind)
834.  		    pline ("%s is tired and doesn't look at your mirror.",
835.  			    Monnam(mtmp));
836.  		mtmp->msleep = 0;
837.  	    } else if (!mtmp->mcansee) {
838.  		if (!Blind)
839.  		    pline("%s can't see anything at the moment.", Monnam(mtmp));
840.  	    } else if (mtmp->minvis || mlet == S_VAMPIRE ||
841.  					mlet == S_DEMON || mlet == S_GHOST) {
842.  		if (!Blind)
843.  		   pline ("%s doesn't seem to reflect anything.", Monnam(mtmp));
844.  	    } else if (!mtmp->mcan) {
845.  	    /* some monsters do special things */
846.  		if(obj->cursed && !rn2(2)) {
847.  		    if (!Blind)
848.  			pline("The mirror gets foggy and doesn't reflect!");
849.  		    return;
850.  		} else if(mtmp->data == &mons[PM_MEDUSA]) {
851.  		    if (!Blind)
852.  			pline("%s is turned to stone!", Monnam(mtmp));
853.  		    stoned = TRUE;
854.  		    killed(mtmp);
855.  		} else if(mtmp->data == &mons[PM_FLOATING_EYE]) {
856.  		    if (!Blind)
857.  			pline("%s is frozen by its reflection.",Monnam(mtmp));
858.  		    mtmp->mfroz = 1;
859.  		} else if(mtmp->data == &mons[PM_UMBER_HULK]) {
860.  		    if (!Blind)
861.  			pline ("%s has confused itself!", Monnam(mtmp));
862.  	    	    mtmp->mconf = 1;
863.  		} else if(mlet == S_NYMPH
864.  #ifdef HARD
865.  			  || mtmp->data==&mons[PM_SUCCUBUS]
866.  #endif
867.  			  ) {
868.  		    if (!Blind) {
869.  	    	      pline ("%s looks beautiful in your mirror.",Monnam(mtmp));
870.  	    	      pline ("She decides to take it!");
871.  		    } else pline ("It steals your mirror!");
872.  	    	    freeinv(obj);
873.  	    	    mpickobj(mtmp,obj);
874.  	    	    rloc(mtmp);
875.  		}
876.  	    } else if (mlet != S_UNICORN && !humanoid(mtmp->data) && rn2(5)) {
877.  		if (!Blind)
878.  		pline ("%s is frightened by its reflection.", Monnam(mtmp));
879.  		mtmp->mflee = 1;
880.  		mtmp->mfleetim += d(2,4);
881.  	    } else if (!Blind)
882.  		pline("%s doesn't seem to mind %s reflection.", Monnam(mtmp),
883.  		      (is_female(mtmp) ? "her" :
884.  		       is_human(mtmp->data) ? "his" : "its"));
885.  	}
886.  }/* use_mirror */
887.  
888.  #endif
889.  
890.  static void
891.  use_lamp(obj)
892.  struct obj *obj;
893.  {
894.  	if(obj->spe <= 0 || obj->otyp == MAGIC_LAMP ) {
895.  		pline("This lamp has no oil.");
896.  		return;
897.  	}
898.  	if(obj->cursed && !rn2(2))
899.  		pline("The lamp flickers on for a moment and dies.");
900.  	else litroom(TRUE);
901.  	obj->spe -= 1;
902.  }
903.  
904.  static void
905.  use_crystal_ball(obj)
906.  	struct obj *obj;
907.  {
908.  	char buf[BUFSZ];
909.  	int oops, ret;
910.  
911.  	if (Blind) {
912.  		pline("Too bad you can't see the crystal ball.");
913.  		return;
914.  	}
915.  	oops = (rnd(20) > ACURR(A_INT) || obj->cursed);
916.  	if (oops && (obj->spe > 0)) {
917.  		switch(rnd(5)) {
918.  		case 1 : pline("The crystal ball is too much to comprehend!");
919.  			break;
920.  		case 2 : pline("The crystal ball confuses you!");
921.  			make_confused(HConfusion + rnd(100),FALSE);
922.  			break;
923.  		case 3 : pline("The crystal ball damages your vision!");
924.  			make_blinded(Blinded + rnd(100),FALSE);
925.  			break;
926.  		case 4 : pline("The crystal ball zaps your mind!");
927.  			make_hallucinated(Hallucination + rnd(100),FALSE);
928.  			break;
929.  		case 5 : pline("The crystal ball explodes!");
930.  			useup(obj);
931.  			losehp(rnd(30), "exploding crystal ball");
932.  			break;
933.  		}
934.  		obj->spe -= 1;
935.  		return;
936.  	}
937.  
938.  	pline("What do you want to look for? ");
939.  	getlin(buf);
940.  	clrlin();
941.  	if (!buf[0] || buf[0] == '\033') {
942.  		if(flags.verbose) pline("Never mind.");
943.  		return;
944.  		}
945.  	You("peer into the crystal ball.");
946.  	nomul(-rnd(10));
947.  	nomovemsg = "";
948.  	if(obj->spe <= 0)
949.  		pline("The vision is unclear.");
950.  	else {
951.  	  	obj->spe -= 1;
952.  		switch(buf[0]) {
953.  		case GOLD_SYM :	ret = gold_detect((struct obj *)0);
954.  			break;
955.  		case '^' :	ret = trap_detect((struct obj *)0);
956.  			break;
957.  		case FOOD_SYM :	ret = food_detect((struct obj *)0);
958.  			break;
959.  		case POTION_SYM :
960.  		case GEM_SYM :
961.  		case TOOL_SYM :
962.  		case WEAPON_SYM :
963.  		case WAND_SYM :
964.  		case SCROLL_SYM :
965.  #ifdef SPELLS
966.  		case SPBOOK_SYM :
967.  #endif
968.  		case ARMOR_SYM :	ret = object_detect((struct obj *)0);
969.  			break;
970.  		default  : lcase(buf);
971.  			if (!strncmp(buf,"gold",4) || !strncmp(buf,"money",5))
972.  				ret = gold_detect((struct obj *)0);
973.  			else if (!strncmp(buf,"trap",4))
974.  				ret = trap_detect((struct obj *)0);
975.  			else if (!strncmp(buf,"food",4) ||
976.  				 !strncmp(buf,"dead",4) ||
977.  				 !strncmp(buf,"corpse",6))
978.  				ret = food_detect((struct obj *)0);
979.  			else if (!strncmp(buf,"obj",3) ||
980.  				 !strncmp(buf,"the",3) ||
981.  				 !strncmp(buf,"a ",2) ||
982.  				 !strncmp(buf,"an ",3))
983.  				 /* || strstr(buf, " of") */
984.  				ret = object_detect((struct obj *)0);
985.  			else ret = monster_detect((struct obj *)0);
986.  			break;
987.  		}
988.  		if (ret)
989.  		    if (!rn2(100))  /* make them nervous */
990.  			You("see the Wizard of Yendor gazing out at you.");
991.  		    else pline("The vision is unclear.");
992.  	}
993.  	return;
994.  }
995.  
996.  static const char cuddly[] = { TOOL_SYM, 0 };
997.  
998.  int
999.  dorub()
1000. {
1001. 	struct obj *obj = getobj(cuddly, "rub");
1002. 
1003. 	if(!obj || (obj != uwep && !wield_tool(obj))) return 0;
1004. 
1005. 	if (uwep->otyp == MAGIC_LAMP) {
1006. 	    if (uwep->spe > 0 && !rn2(3)) {
1007. 		uwep->spe = 0;
1008. 		djinni_from_bottle(uwep);
1009. 	    } else if (rn2(2) && !Blind)
1010. 		You("see a puff of smoke.");
1011. 	    else pline(nothing_happens);
1012. 	} else pline(nothing_happens);
1013. 	return 1;
1014. }
1015. 
1016. int
1017. dojump()
1018. {
1019. 	coord cc;
1020. 	register struct monst *mtmp;
1021. 	if (!Jumping) {
1022. 		You("can't jump very far.");
1023. 		return 0;
1024. 	} else if (u.uswallow) {
1025. 		pline("You've got to be kidding!");
1026. 		return 0;
1027. 	} else if (u.ustuck) {
1028. 		kludge("You cannot escape from %s!",
1029. 			mon_nam(u.ustuck));
1030. 		return 0;
1031. 	} else if (inv_weight() > -5) {
1032. 		You("are carrying too much to jump!");
1033. 		return 0;
1034. 	} else if (u.uhunger <= 100 || ACURR(A_STR) < 6) {
1035. 		You("lack the strength to jump!");
1036. 		return 0;
1037. 	}
1038. 	pline("Where do you want to jump?");
1039. 	getpos(&cc, 1, "the desired position");
1040. 	if (dist(cc.x, cc.y) > 9) {
1041. 		pline("Too far!");
1042. 		return 0;
1043. 	} else if (!cansee(cc.x, cc.y)) {
1044. 		You("cannot see where to land!");
1045. 		return 0;
1046. 	} else if (levl[cc.x][cc.y].mmask) {
1047. 		mtmp = m_at(cc.x, cc.y);
1048. 		You("cannot trample %s!", mon_nam(mtmp));
1049. 		return 0;
1050. 	} else if (!isok(cc.x, cc.y) ||
1051. #ifdef POLYSELF
1052. 		(IS_ROCK(levl[cc.x][cc.y].typ) && !passes_walls(uasmon)) ||
1053. #else
1054. 		IS_ROCK(levl[cc.x][cc.y].typ) ||
1055. #endif
1056. 		sobj_at(BOULDER, cc.x, cc.x) ) {
1057. 			You("cannot jump there!");
1058. 			return 0;
1059. 	} else {
1060. 			teleds(cc.x, cc.y);
1061. 			nomul(-1);
1062. 			nomovemsg = "";
1063. 			morehungry(rnd(25));
1064. 			return 1;
1065. 	}
1066. }
1067. 
1068. static void
1069. use_tinning_kit(obj)
1070. register struct obj *obj;
1071. {
1072. 	register struct obj *corpse, *can;
1073. 
1074. 	/* This takes only 1 move.  If this is to be changed to take many
1075. 	 * moves, we've got to deal with decaying corpses...
1076. 	 */
1077. 	if (!(corpse = floorfood("can", 1))) return;
1078. 	if ((corpse->corpsenm == PM_COCKATRICE)
1079. #ifdef POLYSELF
1080. 		&& !resists_ston(uasmon)
1081. #endif
1082. 		&& !uarmg) {
1083. pline("Tinning a cockatrice corpse without gloves was not a very wise move...");
1084. 		You("turn to stone...");
1085. 		killer = "unwise tinning decision";
1086. 		done("stoned");
1087. 	}
1088. 	can = mksobj(TIN,FALSE);
1089. 	can->corpsenm = corpse->corpsenm;
1090. 	can->quan = 1; /* Defeat the occasional creation of pairs of tins */
1091. 	can->owt = weight(can);
1092. 	can->known = 1;
1093. 	can->spe = 0; /* No spinach allowed... */
1094. 	can->cursed = obj->cursed;
1095. 	can->blessed = obj->blessed;
1096. 	can = addinv(can);
1097. 	You("now have %s.", doname(can));
1098. 	useup(corpse);
1099. }
1100. 
1101. int
1102. doapply() {
1103. 	register struct obj *obj;
1104. 	register int res = 1;
1105. 
1106. 	obj = getobj(tools, "use or apply");
1107. 	if(!obj) return 0;
1108. 
1109. 	check_unpaid(obj);
1110. 
1111. #ifdef MUSIC
1112. 	if (IS_INSTRUMENT(obj->otyp)) {
1113. 		res = do_play_instrument(obj);
1114. 		return (res);
1115. 	}
1116. #endif /* MUSIC /**/
1117. 
1118. 	switch(obj->otyp){
1119. 	case EXPENSIVE_CAMERA:
1120. 		use_camera(obj); break;
1121. 	case CREDIT_CARD:
1122. 	case LOCK_PICK:
1123. 	case SKELETON_KEY:
1124. 	case KEY:
1125. 		(void) pick_lock(obj);
1126. 		break;
1127. 	case BAG_OF_TRICKS:
1128. 		if(obj->spe > 0) {
1129. 			register int cnt = 1;
1130. 
1131. 			obj->spe -= 1;
1132. 			if(!rn2(23)) cnt += rn2(7) + 1;
1133. 			while(cnt--)
1134. 			    (void) makemon((struct permonst *) 0, u.ux, u.uy);
1135. 			makeknown(BAG_OF_TRICKS);
1136. 		}
1137. 		break;
1138. 	case LARGE_BOX:
1139. 	case CHEST:
1140. 	case ICE_BOX:
1141. 	case SACK:
1142. 	case BAG_OF_HOLDING:
1143. 		use_container(obj, 1); break;
1144. 	case PICK_AXE:
1145. 		res = use_pick_axe(obj);
1146. 		break;
1147. 	case TINNING_KIT:
1148. 		use_tinning_kit(obj);
1149. 		break;
1150. 	case MAGIC_WHISTLE:
1151. 		if(pl_character[0] == 'W' || u.ulevel > (MAXULEV/3)) {
1152. 			use_magic_whistle(obj);
1153. 			break;
1154. 		}
1155. 		/* fall into next case */
1156. 	case WHISTLE:
1157. 		use_whistle(obj);
1158. 		break;
1159. #ifdef MEDUSA
1160. 	case MIRROR:
1161. 		use_mirror(obj);
1162. 		break;
1163. #endif
1164. 	case LAMP:
1165. 	case MAGIC_LAMP:
1166. 		use_lamp(obj);
1167. 		break;
1168. 	case CRYSTAL_BALL:
1169. 		use_crystal_ball(obj);
1170. 		break;
1171. #ifdef WALKIES
1172. 	case LEASH:
1173. 		use_leash(obj);
1174. 		break;
1175. #endif
1176. 	case MAGIC_MARKER:
1177. 		dowrite(obj);
1178. 		break;
1179. 	case TIN_OPENER:
1180. 		if(!carrying(TIN)) {
1181. 			You("have no tin to open.");
1182. 			goto xit;
1183. 		}
1184. 		You("cannot open a tin without eating its contents.");
1185. 		if(flags.verbose)
1186. 			pline("In order to eat, use the 'e' command.");
1187. 		if(obj != uwep)
1188.     pline("Opening the tin will be much easier if you wield the tin opener.");
1189. 		goto xit;
1190. 
1191. 	case STETHOSCOPE:
1192. 		res = 0;
1193. 		use_stethoscope(obj);
1194. 		break;
1195. 	case FIGURINE:
1196. 		You("set the figurine on the ground and it transforms.");
1197. 		make_familiar(obj);
1198. 		useup(obj);
1199. 		break;
1200. 	case BLINDFOLD:
1201. 		if (obj == ublindf) {
1202. 		    if(cursed(obj)) break;
1203. 		    else Blindf_off(obj);
1204. 		} 
1205. 		else if (!ublindf) Blindf_on(obj);
1206. 		else You("are already wearing a blindfold!");
1207. 		break;
1208. 	default:
1209. 		pline("Sorry, I don't know how to use that.");
1210. 	xit:
1211. 		nomul(0);
1212. 		return 0;
1213. 	}
1214. 	nomul(0);
1215. 	return res;
1216. }