Source:SLASH'EM 0.0.7E7F2/dig.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to dig.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/dig.c#line123]], for example.

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


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

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: @(#)dig.c	3.4	2003/03/23	*/
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.    /* #define DEBUG */	/* turn on for diagnostics */
8.    
9.    #ifdef OVLB
10.   
11.   static NEARDATA boolean did_dig_msg;
12.   
13.   STATIC_DCL boolean NDECL(rm_waslit);
14.   STATIC_DCL void FDECL(mkcavepos, (XCHAR_P,XCHAR_P,int,BOOLEAN_P,BOOLEAN_P));
15.   STATIC_DCL void FDECL(mkcavearea, (BOOLEAN_P));
16.   STATIC_DCL int FDECL(dig_typ, (struct obj *,XCHAR_P,XCHAR_P));
17.   STATIC_DCL int NDECL(dig);
18.   STATIC_DCL schar FDECL(fillholetyp, (int, int));
19.   STATIC_DCL void NDECL(dig_up_grave);
20.   
21.   /* Indices returned by dig_typ() */
22.   #define DIGTYP_UNDIGGABLE 0
23.   #define DIGTYP_ROCK       1
24.   #define DIGTYP_STATUE     2
25.   #define DIGTYP_BOULDER    3
26.   #define DIGTYP_DOOR       4
27.   #define DIGTYP_TREE       5
28.   
29.   
30.   STATIC_OVL boolean
31.   rm_waslit()
32.   {
33.       register xchar x, y;
34.   
35.       if(levl[u.ux][u.uy].typ == ROOM && levl[u.ux][u.uy].waslit)
36.   	return(TRUE);
37.       for(x = u.ux-2; x < u.ux+3; x++)
38.   	for(y = u.uy-1; y < u.uy+2; y++)
39.   	    if(isok(x,y) && levl[x][y].waslit) return(TRUE);
40.       return(FALSE);
41.   }
42.   
43.   /* Change level topology.  Messes with vision tables and ignores things like
44.    * boulders in the name of a nice effect.  Vision will get fixed up again
45.    * immediately after the effect is complete.
46.    */
47.   STATIC_OVL void
48.   mkcavepos(x, y, dist, waslit, rockit)
49.       xchar x,y;
50.       int dist;
51.       boolean waslit, rockit;
52.   {
53.       register struct rm *lev;
54.   
55.       if(!isok(x,y)) return;
56.       lev = &levl[x][y];
57.   
58.       if(rockit) {
59.   	register struct monst *mtmp;
60.   
61.   	if(IS_ROCK(lev->typ)) return;
62.   	if(t_at(x, y)) return; /* don't cover the portal */
63.   	if ((mtmp = m_at(x, y)) != 0)	/* make sure crucial monsters survive */
64.   	    if(!passes_walls(mtmp->data)) (void) rloc(mtmp, FALSE);
65.       } else if(lev->typ == ROOM) return;
66.   
67.       unblock_point(x,y);	/* make sure vision knows this location is open */
68.   
69.       /* fake out saved state */
70.       lev->seenv = 0;
71.       lev->doormask = 0;
72.       if(dist < 3) lev->lit = (rockit ? FALSE : TRUE);
73.       if(waslit) lev->waslit = (rockit ? FALSE : TRUE);
74.       lev->horizontal = FALSE;
75.       viz_array[y][x] = (dist < 3 ) ?
76.   	(IN_SIGHT|COULD_SEE) : /* short-circuit vision recalc */
77.   	COULD_SEE;
78.       lev->typ = (rockit ? STONE : ROOM);
79.       if(dist >= 3)
80.   	impossible("mkcavepos called with dist %d", dist);
81.       if(Blind)
82.   	feel_location(x, y);
83.       else newsym(x,y);
84.   }
85.   
86.   STATIC_OVL void
87.   mkcavearea(rockit)
88.   register boolean rockit;
89.   {
90.       int dist;
91.       xchar xmin = u.ux, xmax = u.ux;
92.       xchar ymin = u.uy, ymax = u.uy;
93.       register xchar i;
94.       register boolean waslit = rm_waslit();
95.   
96.       if(rockit) pline("Crash!  The ceiling collapses around you!");
97.       else pline("A mysterious force %s cave around you!",
98.   	     (levl[u.ux][u.uy].typ == CORR) ? "creates a" : "extends the");
99.       display_nhwindow(WIN_MESSAGE, TRUE);
100.  
101.      for(dist = 1; dist <= 2; dist++) {
102.  	xmin--; xmax++;
103.  
104.  	/* top and bottom */
105.  	if(dist < 2) { /* the area is wider that it is high */
106.  	    ymin--; ymax++;
107.  	    for(i = xmin+1; i < xmax; i++) {
108.  		mkcavepos(i, ymin, dist, waslit, rockit);
109.  		mkcavepos(i, ymax, dist, waslit, rockit);
110.  	    }
111.  	}
112.  
113.  	/* left and right */
114.  	for(i = ymin; i <= ymax; i++) {
115.  	    mkcavepos(xmin, i, dist, waslit, rockit);
116.  	    mkcavepos(xmax, i, dist, waslit, rockit);
117.  	}
118.  
119.  	flush_screen(1);	/* make sure the new glyphs shows up */
120.  	delay_output();
121.      }
122.  
123.      if(!rockit && levl[u.ux][u.uy].typ == CORR) {
124.  	levl[u.ux][u.uy].typ = ROOM;
125.  	if(waslit) levl[u.ux][u.uy].waslit = TRUE;
126.  	newsym(u.ux, u.uy); /* in case player is invisible */
127.      }
128.  
129.      vision_full_recalc = 1;	/* everything changed */
130.  }
131.  
132.  /* When digging into location <x,y>, what are you actually digging into? */
133.  STATIC_OVL int
134.  dig_typ(otmp, x, y)
135.  struct obj *otmp;
136.  xchar x, y;
137.  {
138.  	boolean ispick = is_pick(otmp);
139.  
140.  	return (ispick && sobj_at(STATUE, x, y) ? DIGTYP_STATUE :
141.  		ispick && sobj_at(BOULDER, x, y) ? DIGTYP_BOULDER :
142.  		closed_door(x, y) ? DIGTYP_DOOR :
143.  		IS_TREE(levl[x][y].typ) ?
144.  			(ispick ? DIGTYP_UNDIGGABLE : DIGTYP_TREE) :
145.  		ispick && IS_ROCK(levl[x][y].typ) &&
146.  			(!level.flags.arboreal || IS_WALL(levl[x][y].typ)) ?
147.  			DIGTYP_ROCK : DIGTYP_UNDIGGABLE);
148.  }
149.  
150.  boolean
151.  is_digging()
152.  {
153.  	if (occupation == dig) {
154.  	    return TRUE;
155.  	}
156.  	return FALSE;
157.  }
158.  
159.  #define BY_YOU		(&youmonst)
160.  #define BY_OBJECT	((struct monst *)0)
161.  
162.  boolean
163.  dig_check(madeby, verbose, x, y)
164.  	struct monst	*madeby;
165.  	boolean		verbose;
166.  	int		x, y;
167.  {
168.  	struct trap *ttmp = t_at(x, y);
169.  	const char *verb =
170.  	    (madeby != BY_YOU || !uwep || is_pick(uwep)) ? "dig in" :
171.  #ifdef LIGHTSABERS
172.  	    is_lightsaber(uwep) ? "cut" :
173.  #endif
174.  	    "chop";
175.  
176.  	if (On_stairs(x, y)) {
177.  	    if (x == xdnladder || x == xupladder) {
178.  		if(verbose) pline_The("ladder resists your effort.");
179.  	    } else if(verbose) pline_The("stairs are too hard to %s.", verb);
180.  	    return(FALSE);
181.  	/* ALI - Artifact doors */
182.  	} else if (IS_DOOR(levl[x][y].typ) && artifact_door(x, y)) {
183.  	    if(verbose) pline_The("%s here is too hard to dig in.",
184.  				  surface(x,y));
185.  	    return(FALSE);
186.  	} else if (IS_THRONE(levl[x][y].typ) && madeby != BY_OBJECT) {
187.  	    if(verbose) pline_The("throne is too hard to break apart.");
188.  	    return(FALSE);
189.  	} else if (IS_ALTAR(levl[x][y].typ) && (madeby != BY_OBJECT ||
190.  				Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) {
191.  	    if(verbose) pline_The("altar is too hard to break apart.");
192.  	    return(FALSE);
193.  	} else if (Is_airlevel(&u.uz)) {
194.  	    if(verbose) You("cannot %s thin air.", verb);
195.  	    return(FALSE);
196.  	} else if (Is_waterlevel(&u.uz)) {
197.  	    if(verbose) pline_The("water splashes and subsides.");
198.  	    return(FALSE);
199.  	} else if ((IS_ROCK(levl[x][y].typ) && levl[x][y].typ != SDOOR &&
200.  		      (levl[x][y].wall_info & W_NONDIGGABLE) != 0)
201.  		|| (ttmp &&
202.  		      (ttmp->ttyp == MAGIC_PORTAL || !Can_dig_down(&u.uz)))) {
203.  	    if(verbose) pline_The("%s here is too hard to %s.",
204.  				  surface(x,y), verb);
205.  	    return(FALSE);
206.  	} else if (sobj_at(BOULDER, x, y)) {
207.  	    if(verbose) There("isn't enough room to %s here.", verb);
208.  	    return(FALSE);
209.  	} else if (madeby == BY_OBJECT &&
210.  		    /* the block against existing traps is mainly to
211.  		       prevent broken wands from turning holes into pits */
212.  		    (ttmp || is_pool(x,y) || is_lava(x,y))) {
213.  	    /* digging by player handles pools separately */
214.  	    return FALSE;
215.  	}
216.  	return(TRUE);
217.  }
218.  
219.  STATIC_OVL int
220.  dig()
221.  {
222.  	register struct rm *lev;
223.  	register xchar dpx = digging.pos.x, dpy = digging.pos.y;
224.  	register boolean ispick = uwep && is_pick(uwep);
225.  	const char *verb =
226.  	    (!uwep || is_pick(uwep)) ? "dig into" :
227.  #ifdef LIGHTSABERS
228.  	    is_lightsaber(uwep) ? "cut through" :
229.  #endif
230.  	    "chop through";
231.  	int bonus;
232.  
233.  	lev = &levl[dpx][dpy];
234.  	/* perhaps a nymph stole your pick-axe while you were busy digging */
235.  	/* or perhaps you teleported away */
236.  	/* WAC allow lightsabers */
237.  	if (u.uswallow || !uwep || (!ispick &&
238.  #ifdef LIGHTSABERS
239.  		(!is_lightsaber(uwep) || !uwep->lamplit) &&
240.  #endif
241.  		!is_axe(uwep)) ||
242.  	    !on_level(&digging.level, &u.uz) ||
243.  	    ((digging.down ? (dpx != u.ux || dpy != u.uy)
244.  			   : (distu(dpx,dpy) > 2))))
245.  		return(0);
246.  
247.  	if (digging.down) {
248.  	    if(!dig_check(BY_YOU, TRUE, u.ux, u.uy)) return(0);
249.  	} else { /* !digging.down */
250.  	    if (IS_TREE(lev->typ) && !may_dig(dpx,dpy) &&
251.  			dig_typ(uwep, dpx, dpy) == DIGTYP_TREE) {
252.  		pline("This tree seems to be petrified.");
253.  		return(0);
254.  	    }
255.  	    /* ALI - Artifact doors */
256.  	    if (IS_ROCK(lev->typ) && !may_dig(dpx,dpy) &&
257.  	    		dig_typ(uwep, dpx, dpy) == DIGTYP_ROCK ||
258.  		    IS_DOOR(lev->typ) && artifact_door(dpx, dpy)) {
259.  		pline("This %s is too hard to %s.",
260.  			IS_DOOR(lev->typ) ? "door" : "wall", verb);
261.  		return(0);
262.  	    }
263.  	}
264.  	if(Fumbling &&
265.  #ifdef LIGHTSABERS
266.  		/* Can't exactly miss holding a lightsaber to the wall */
267.  		!is_lightsaber(uwep) &&
268.  #endif
269.  		!rn2(3)) {
270.  	    switch(rn2(3)) {
271.  	    case 0:
272.  		if(!welded(uwep)) {
273.  		    You("fumble and drop your %s.", xname(uwep));
274.  		    dropx(uwep);
275.  		} else {
276.  #ifdef STEED
277.  		    if (u.usteed)
278.  			Your("%s %s and %s %s!",
279.  			     xname(uwep),
280.  			     otense(uwep, "bounce"), otense(uwep, "hit"),
281.  			     mon_nam(u.usteed));
282.  		    else
283.  #endif
284.  			pline("Ouch!  Your %s %s and %s you!",
285.  			      xname(uwep),
286.  			      otense(uwep, "bounce"), otense(uwep, "hit"));
287.  		    set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
288.  		}
289.  		break;
290.  	    case 1:
291.  		pline("Bang!  You hit with the broad side of %s!",
292.  		      the(xname(uwep)));
293.  		break;
294.  	    default: Your("swing misses its mark.");
295.  		break;
296.  	    }
297.  	    return(0);
298.  	}
299.  
300.  	bonus = 10 + rn2(5) + abon() + uwep->spe - greatest_erosion(uwep) + u.udaminc;
301.  	if (Race_if(PM_DWARF))
302.  	    bonus *= 2;
303.  #ifdef LIGHTSABERS
304.  	if (is_lightsaber(uwep))
305.  	    bonus -= rn2(20); /* Melting a hole takes longer */
306.  #endif
307.  
308.  	digging.effort += bonus;
309.  
310.  	if (digging.down) {
311.  		register struct trap *ttmp;
312.  
313.  		if (digging.effort > 250) {
314.  		    (void) dighole(FALSE);
315.  		    (void) memset((genericptr_t)&digging, 0, sizeof digging);
316.  		    return(0);	/* done with digging */
317.  		}
318.  
319.  		if (digging.effort <= 50 ||
320.  #ifdef LIGHTSABERS
321.  		    is_lightsaber(uwep) ||
322.  #endif
323.  		    ((ttmp = t_at(dpx,dpy)) != 0 &&
324.  			(ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT ||
325.  			 ttmp->ttyp == TRAPDOOR || ttmp->ttyp == HOLE)))
326.  		    return(1);
327.  
328.  		if (IS_ALTAR(lev->typ)) {
329.  		    altar_wrath(dpx, dpy);
330.  		    angry_priest();
331.  		}
332.  
333.  		if (dighole(TRUE)) {	/* make pit at <u.ux,u.uy> */
334.  		    digging.level.dnum = 0;
335.  		    digging.level.dlevel = -1;
336.  		}
337.  		return(0);
338.  	}
339.  
340.  	if (digging.effort > 100) {
341.  		register const char *digtxt, *dmgtxt = (const char*) 0;
342.  		register struct obj *obj;
343.  		register boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE);
344.  
345.  		if ((obj = sobj_at(STATUE, dpx, dpy)) != 0) {
346.  			if (break_statue(obj))
347.  				digtxt = "The statue shatters.";
348.  			else
349.  				/* it was a statue trap; break_statue()
350.  				 * printed a message and updated the screen
351.  				 */
352.  				digtxt = (char *)0;
353.  		} else if ((obj = sobj_at(BOULDER, dpx, dpy)) != 0) {
354.  			struct obj *bobj;
355.  
356.  			fracture_rock(obj);
357.  			if ((bobj = sobj_at(BOULDER, dpx, dpy)) != 0) {
358.  			    /* another boulder here, restack it to the top */
359.  			    obj_extract_self(bobj);
360.  			    place_object(bobj, dpx, dpy);
361.  			}
362.  			digtxt = "The boulder falls apart.";
363.  		} else if (lev->typ == STONE || lev->typ == SCORR ||
364.  				IS_TREE(lev->typ)) {
365.  			if(Is_earthlevel(&u.uz)) {
366.  			    if(uwep->blessed && !rn2(3)) {
367.  				mkcavearea(FALSE);
368.  				goto cleanup;
369.  			    } else if((uwep->cursed && !rn2(4)) ||
370.  					  (!uwep->blessed && !rn2(6))) {
371.  				mkcavearea(TRUE);
372.  				goto cleanup;
373.  			    }
374.  			}
375.  			if (IS_TREE(lev->typ)) {
376.  			    digtxt = "You cut down the tree.";
377.  			    lev->typ = ROOM;
378.  			    if (!rn2(5)) (void) rnd_treefruit_at(dpx, dpy);
379.  			} else {
380.  			    digtxt = "You succeed in cutting away some rock.";
381.  			    lev->typ = CORR;
382.  			}
383.  		} else if(IS_WALL(lev->typ)) {
384.  			if(shopedge) {
385.  			    add_damage(dpx, dpy, 10L * ACURRSTR);
386.  			    dmgtxt = "damage";
387.  			}
388.  			if (level.flags.is_maze_lev) {
389.  			    lev->typ = ROOM;
390.  			} else if (level.flags.is_cavernous_lev &&
391.  				   !in_town(dpx, dpy)) {
392.  			    lev->typ = CORR;
393.  			} else {
394.  			    lev->typ = DOOR;
395.  			    lev->doormask = D_NODOOR;
396.  			}
397.  			digtxt = "You make an opening in the wall.";
398.  		} else if(lev->typ == SDOOR) {
399.  			cvt_sdoor_to_door(lev);	/* ->typ = DOOR */
400.  			digtxt = "You break through a secret door!";
401.  			if(!(lev->doormask & D_TRAPPED))
402.  				lev->doormask = D_BROKEN;
403.  		} else if(closed_door(dpx, dpy)) {
404.  			digtxt = "You break through the door.";
405.  			if(shopedge) {
406.  			    add_damage(dpx, dpy, 400L);
407.  			    dmgtxt = "break";
408.  			}
409.  			if(!(lev->doormask & D_TRAPPED))
410.  				lev->doormask = D_BROKEN;
411.  		} else return(0); /* statue or boulder got taken */
412.  
413.  		if(!does_block(dpx,dpy,&levl[dpx][dpy]))
414.  		    unblock_point(dpx,dpy);	/* vision:  can see through */
415.  		if(Blind)
416.  		    feel_location(dpx, dpy);
417.  		else
418.  		    newsym(dpx, dpy);
419.  		if(digtxt && !digging.quiet) pline(digtxt); /* after newsym */
420.  		if(dmgtxt)
421.  		    pay_for_damage(dmgtxt, FALSE);
422.  
423.  		if(Is_earthlevel(&u.uz) && !rn2(3)) {
424.  		    register struct monst *mtmp;
425.  
426.  		    switch(rn2(2)) {
427.  		      case 0:
428.  			mtmp = makemon(&mons[PM_EARTH_ELEMENTAL],
429.  					dpx, dpy, NO_MM_FLAGS);
430.  			break;
431.  		      default:
432.  			mtmp = makemon(&mons[PM_XORN],
433.  					dpx, dpy, NO_MM_FLAGS);
434.  			break;
435.  		    }
436.  		    if(mtmp) pline_The("debris reassembles and comes to life!");
437.  		}
438.  		if(IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) {
439.  			lev->doormask = D_NODOOR;
440.  			b_trapped("door", 0);
441.  			newsym(dpx, dpy);
442.  		}
443.  cleanup:
444.  		digging.lastdigtime = moves;
445.  		digging.quiet = FALSE;
446.  		digging.level.dnum = 0;
447.  		digging.level.dlevel = -1;
448.  		return(0);
449.  	} else {		/* not enough effort has been spent yet */
450.  		static const char *const d_target[6] = {
451.  			"", "rock", "statue", "boulder", "door", "tree"
452.  		};
453.  		int dig_target = dig_typ(uwep, dpx, dpy);
454.  
455.  		if (IS_WALL(lev->typ) || dig_target == DIGTYP_DOOR) {
456.  		    if(*in_rooms(dpx, dpy, SHOPBASE)) {
457.  			pline("This %s seems too hard to %s.",
458.  			      IS_DOOR(lev->typ) ? "door" : "wall", verb);
459.  			return(0);
460.  		    }
461.  		} else if (!IS_ROCK(lev->typ) && dig_target == DIGTYP_ROCK)
462.  		    return(0); /* statue or boulder got taken */
463.  		if(!did_dig_msg) {
464.  #ifdef LIGHTSABERS
465.  		    if (is_lightsaber(uwep)) You("burn steadily through %s.",
466.  			the(d_target[dig_target]));
467.  		    else
468.  #endif
469.  		    You("hit the %s with all your might.",
470.  			d_target[dig_target]);
471.  		    did_dig_msg = TRUE;
472.  		}
473.  	}
474.  	return(1);
475.  }
476.  
477.  /* When will hole be finished? Very rough indication used by shopkeeper. */
478.  int
479.  holetime()
480.  {
481.  	if(occupation != dig || !*u.ushops) return(-1);
482.  	return ((250 - digging.effort) / 20);
483.  }
484.  
485.  /* Return typ of liquid to fill a hole with, or ROOM, if no liquid nearby */
486.  STATIC_OVL
487.  schar
488.  fillholetyp(x,y)
489.  int x, y;
490.  {
491.      register int x1, y1;
492.      int lo_x = max(1,x-1), hi_x = min(x+1,COLNO-1),
493.  	lo_y = max(0,y-1), hi_y = min(y+1,ROWNO-1);
494.      int pool_cnt = 0, moat_cnt = 0, lava_cnt = 0;
495.  
496.      for (x1 = lo_x; x1 <= hi_x; x1++)
497.  	for (y1 = lo_y; y1 <= hi_y; y1++)
498.  	    if (levl[x1][y1].typ == POOL)
499.  		pool_cnt++;
500.  	    else if (levl[x1][y1].typ == MOAT ||
501.  		    (levl[x1][y1].typ == DRAWBRIDGE_UP &&
502.  			(levl[x1][y1].drawbridgemask & DB_UNDER) == DB_MOAT))
503.  		moat_cnt++;
504.  	    else if (levl[x1][y1].typ == LAVAPOOL ||
505.  		    (levl[x1][y1].typ == DRAWBRIDGE_UP &&
506.  			(levl[x1][y1].drawbridgemask & DB_UNDER) == DB_LAVA))
507.  		lava_cnt++;
508.      pool_cnt /= 3;		/* not as much liquid as the others */
509.  
510.      if (lava_cnt > moat_cnt + pool_cnt && rn2(lava_cnt + 1))
511.  	return LAVAPOOL;
512.      else if (moat_cnt > 0 && rn2(moat_cnt + 1))
513.  	return MOAT;
514.      else if (pool_cnt > 0 && rn2(pool_cnt + 1))
515.  	return POOL;
516.      else
517.  	return ROOM;
518.  }
519.  
520.  void
521.  digactualhole(x, y, madeby, ttyp)
522.  register int	x, y;
523.  struct monst	*madeby;
524.  int ttyp;
525.  {
526.  	struct obj *oldobjs, *newobjs;
527.  	register struct trap *ttmp;
528.  	char surface_type[BUFSZ];
529.  	struct rm *lev = &levl[x][y];
530.  	boolean shopdoor;
531.  	struct monst *mtmp = m_at(x, y);	/* may be madeby */
532.  	boolean madeby_u = (madeby == BY_YOU);
533.  	boolean madeby_obj = (madeby == BY_OBJECT);
534.  	boolean at_u = (x == u.ux) && (y == u.uy);
535.  	boolean wont_fall = Levitation || Flying;
536.  
537.  	if (u.utrap && u.utraptype == TT_INFLOOR) u.utrap = 0;
538.  
539.  	/* these furniture checks were in dighole(), but wand
540.  	   breaking bypasses that routine and calls us directly */
541.  	if (IS_FOUNTAIN(lev->typ)) {
542.  	    dogushforth(FALSE);
543.  	    SET_FOUNTAIN_WARNED(x,y);		/* force dryup */
544.  	    dryup(x, y, madeby_u);
545.  	    return;
546.  #ifdef SINKS
547.  	} else if (IS_SINK(lev->typ)) {
548.  	    breaksink(x, y);
549.  	    return;
550.  	} else if (IS_TOILET(lev->typ)) {
551.  		breaktoilet(u.ux,u.uy);
552.  #endif
553.  	} else if (lev->typ == DRAWBRIDGE_DOWN ||
554.  		   (is_drawbridge_wall(x, y) >= 0)) {
555.  	    int bx = x, by = y;
556.  	    /* if under the portcullis, the bridge is adjacent */
557.  	    (void) find_drawbridge(&bx, &by);
558.  	    destroy_drawbridge(bx, by);
559.  	    return;
560.  	}
561.  
562.  	if (ttyp != PIT && !Can_dig_down(&u.uz)) {
563.  	    impossible("digactualhole: can't dig %s on this level.",
564.  		       defsyms[trap_to_defsym(ttyp)].explanation);
565.  	    ttyp = PIT;
566.  	}
567.  
568.  	/* maketrap() might change it, also, in this situation,
569.  	   surface() returns an inappropriate string for a grave */
570.  	if (IS_GRAVE(lev->typ))
571.  	    Strcpy(surface_type, "grave");
572.  	else
573.  	    Strcpy(surface_type, surface(x,y));
574.  	shopdoor = IS_DOOR(lev->typ) && *in_rooms(x, y, SHOPBASE);
575.  	oldobjs = level.objects[x][y];
576.  	ttmp = maketrap(x, y, ttyp);
577.  	if (!ttmp) return;
578.  	newobjs = level.objects[x][y];
579.  	ttmp->tseen = (madeby_u || cansee(x,y));
580.  	ttmp->madeby_u = madeby_u;
581.  	newsym(ttmp->tx,ttmp->ty);
582.  
583.  	if (ttyp == PIT) {
584.  
585.  	    if(madeby_u) {
586.  		You("dig a pit in the %s.", surface_type);
587.  		if (shopdoor) pay_for_damage("ruin", FALSE);
588.  	    } else if (!madeby_obj && canseemon(madeby))
589.  		pline("%s digs a pit in the %s.", Monnam(madeby), surface_type);
590.  	    else if (cansee(x, y) && flags.verbose)
591.  		pline("A pit appears in the %s.", surface_type);
592.  
593.  	    if(at_u) {
594.  		if (!wont_fall) {
595.  		    if (!Passes_walls)
596.  			u.utrap = rn1(4,2);
597.  		    u.utraptype = TT_PIT;
598.  		    vision_full_recalc = 1;	/* vision limits change */
599.  		} else
600.  		    u.utrap = 0;
601.  		if (oldobjs != newobjs)	/* something unearthed */
602.  			(void) pickup(1);	/* detects pit */
603.  	    } else if(mtmp) {
604.  		if(is_flyer(mtmp->data) || is_floater(mtmp->data)) {
605.  		    if(canseemon(mtmp))
606.  			pline("%s %s over the pit.", Monnam(mtmp),
607.  						     (is_flyer(mtmp->data)) ?
608.  						     "flies" : "floats");
609.  		} else if(mtmp != madeby)
610.  		    (void) mintrap(mtmp);
611.  	    }
612.  	} else {	/* was TRAPDOOR now a HOLE*/
613.  
614.  	    if(madeby_u)
615.  		You("dig a hole through the %s.", surface_type);
616.  	    else if(!madeby_obj && canseemon(madeby))
617.  		pline("%s digs a hole through the %s.",
618.  		      Monnam(madeby), surface_type);
619.  	    else if(cansee(x, y) && flags.verbose)
620.  		pline("A hole appears in the %s.", surface_type);
621.  
622.  	    if (at_u) {
623.  		if (!u.ustuck && !wont_fall && !next_to_u()) {
624.  		    You("are jerked back by your pet!");
625.  		    wont_fall = TRUE;
626.  		}
627.  
628.  		/* Floor objects get a chance of falling down.  The case where
629.  		 * the hero does NOT fall down is treated here.  The case
630.  		 * where the hero does fall down is treated in goto_level().
631.  		 */
632.  		if (u.ustuck || wont_fall) {
633.  		    if (newobjs)
634.  			impact_drop((struct obj *)0, x, y, 0);
635.  		    if (oldobjs != newobjs)
636.  			(void) pickup(1);
637.  		    if (shopdoor && madeby_u) pay_for_damage("ruin", FALSE);
638.  
639.  		} else {
640.  		    d_level newlevel;
641.  		    const char *You_fall = "You fall through...";
642.  
643.  		    if (*u.ushops && madeby_u)
644.  			shopdig(1); /* shk might snatch pack */
645.  		    /* handle earlier damage, eg breaking wand of digging */
646.  		    else if (!madeby_u) pay_for_damage("dig into", TRUE);
647.  
648.  		    /* Earlier checks must ensure that the destination
649.  		     * level exists and is in the present dungeon.
650.  		     */
651.  		    newlevel.dnum = u.uz.dnum;
652.  		    newlevel.dlevel = u.uz.dlevel + 1;
653.  		    /* Cope with holes caused by monster's actions -- ALI */
654.  		    if (flags.mon_moving) {
655.  			schedule_goto(&newlevel, FALSE, TRUE, FALSE,
656.  			  You_fall, (char *)0);
657.  		    } else {
658.  			pline(You_fall);
659.  		    goto_level(&newlevel, FALSE, TRUE, FALSE);
660.  		    /* messages for arriving in special rooms */
661.  		    spoteffects(FALSE);
662.  		}
663.  		}
664.  	    } else {
665.  		if (shopdoor && madeby_u) pay_for_damage("ruin", FALSE);
666.  		if (newobjs)
667.  		    impact_drop((struct obj *)0, x, y, 0);
668.  		if (mtmp) {
669.  		     /*[don't we need special sokoban handling here?]*/
670.  		    if (is_flyer(mtmp->data) || is_floater(mtmp->data) ||
671.  		        mtmp->data == &mons[PM_WUMPUS] ||
672.  			(mtmp->wormno && count_wsegs(mtmp) > 5) ||
673.  			mtmp->data->msize >= MZ_HUGE) return;
674.  		    if (mtmp == u.ustuck)	/* probably a vortex */
675.  			    return;		/* temporary? kludge */
676.  
677.  		    if (teleport_pet(mtmp, FALSE)) {
678.  			d_level tolevel;
679.  
680.  			if (Is_stronghold(&u.uz)) {
681.  			    assign_level(&tolevel, &valley_level);
682.  			} else if (Is_botlevel(&u.uz)) {
683.  			    if (canseemon(mtmp))
684.  				pline("%s avoids the trap.", Monnam(mtmp));
685.  			    return;
686.  			} else {
687.  			    get_level(&tolevel, depth(&u.uz) + 1);
688.  			}
689.  			if (mtmp->isshk) make_angry_shk(mtmp, 0, 0);
690.  			migrate_to_level(mtmp, ledger_no(&tolevel),
691.  					 MIGR_RANDOM, (coord *)0);
692.  		    }
693.  		}
694.  	    }
695.  	}
696.  }
697.  
698.  /* return TRUE if digging succeeded, FALSE otherwise */
699.  boolean
700.  dighole(pit_only)
701.  boolean pit_only;
702.  {
703.  	register struct trap *ttmp = t_at(u.ux, u.uy);
704.  	struct rm *lev = &levl[u.ux][u.uy];
705.  	struct obj *boulder_here;
706.  	schar typ;
707.  	boolean nohole = !Can_dig_down(&u.uz);
708.  
709.  	if ((ttmp && (ttmp->ttyp == MAGIC_PORTAL || nohole)) ||
710.  	   /* ALI - artifact doors */
711.  	   IS_DOOR(levl[u.ux][u.uy].typ) && artifact_door(u.ux, u.uy) ||
712.  	   (IS_ROCK(lev->typ) && lev->typ != SDOOR &&
713.  	    (lev->wall_info & W_NONDIGGABLE) != 0)) {
714.  		pline_The("%s here is too hard to dig in.", surface(u.ux,u.uy));
715.  
716.  	} else if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) {
717.  		pline_The("%s sloshes furiously for a moment, then subsides.",
718.  			is_lava(u.ux, u.uy) ? "lava" : "water");
719.  		wake_nearby();	/* splashing */
720.  
721.  	} else if (lev->typ == DRAWBRIDGE_DOWN ||
722.  		   (is_drawbridge_wall(u.ux, u.uy) >= 0)) {
723.  		/* drawbridge_down is the platform crossing the moat when the
724.  		   bridge is extended; drawbridge_wall is the open "doorway" or
725.  		   closed "door" where the portcullis/mechanism is located */
726.  		if (pit_only) {
727.  		    pline_The("drawbridge seems too hard to dig through.");
728.  		    return FALSE;
729.  	} else if (IS_GRAVE(lev->typ)) {        
730.  	    digactualhole(u.ux, u.uy, BY_YOU, PIT);
731.  	    dig_up_grave();
732.  	    return TRUE;
733.  		} else {
734.  		    int x = u.ux, y = u.uy;
735.  		    /* if under the portcullis, the bridge is adjacent */
736.  		    (void) find_drawbridge(&x, &y);
737.  		    destroy_drawbridge(x, y);
738.  		    return TRUE;
739.  		}
740.  
741.  	} else if ((boulder_here = sobj_at(BOULDER, u.ux, u.uy)) != 0) {
742.  		if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT) &&
743.  		    rn2(2)) {
744.  			pline_The("boulder settles into the pit.");
745.  			ttmp->ttyp = PIT;	 /* crush spikes */
746.  		} else {
747.  			/*
748.  			 * digging makes a hole, but the boulder immediately
749.  			 * fills it.  Final outcome:  no hole, no boulder.
750.  			 */
751.  			pline("KADOOM! The boulder falls in!");
752.  			(void) delfloortrap(ttmp);
753.  		}
754.  		delobj(boulder_here);
755.  		return TRUE;
756.  
757.  	} else if (IS_GRAVE(lev->typ)) {        
758.  	    dig_up_grave();
759.  			digactualhole(u.ux, u.uy, BY_YOU, PIT);
760.  	    return TRUE;
761.  	} else if (lev->typ == DRAWBRIDGE_UP) {
762.  		/* must be floor or ice, other cases handled above */
763.  		/* dig "pit" and let fluid flow in (if possible) */
764.  		typ = fillholetyp(u.ux,u.uy);
765.  
766.  		if (typ == ROOM) {
767.  			/*
768.  			 * We can't dig a hole here since that will destroy
769.  			 * the drawbridge.  The following is a cop-out. --dlc
770.  			 */
771.  			pline_The("%s here is too hard to dig in.",
772.  			      surface(u.ux, u.uy));
773.  			return FALSE;
774.  		}
775.  
776.  		lev->drawbridgemask &= ~DB_UNDER;
777.  		lev->drawbridgemask |= (typ == LAVAPOOL) ? DB_LAVA : DB_MOAT;
778.  
779.   liquid_flow:
780.  		if (ttmp) (void) delfloortrap(ttmp);
781.  		/* if any objects were frozen here, they're released now */
782.  		unearth_objs(u.ux, u.uy);
783.  
784.  		pline("As you dig, the hole fills with %s!",
785.  		      typ == LAVAPOOL ? "lava" : "water");
786.  		/* KMH, balance patch -- new intrinsic */
787.  		if (!Levitation && !Flying) {
788.  		    if (typ == LAVAPOOL)
789.  			(void) lava_effects();
790.  		    else if (!Wwalking && !Swimming)
791.  			(void) drown();
792.  		}
793.  		return TRUE;
794.  
795.  	/* the following two are here for the wand of digging */
796.  	} else if (IS_THRONE(lev->typ)) {
797.  		pline_The("throne is too hard to break apart.");
798.  
799.  	} else if (IS_ALTAR(lev->typ)) {
800.  		pline_The("altar is too hard to break apart.");
801.  
802.  	} else {
803.  		typ = fillholetyp(u.ux,u.uy);
804.  
805.  		if (typ != ROOM) {
806.  			lev->typ = typ;
807.  			goto liquid_flow;
808.  		}
809.  
810.  		/* finally we get to make a hole */
811.  		if (nohole || pit_only)
812.  			digactualhole(u.ux, u.uy, BY_YOU, PIT);
813.  		else
814.  			digactualhole(u.ux, u.uy, BY_YOU, HOLE);
815.  
816.  		return TRUE;
817.  	}
818.  
819.  	return FALSE;
820.  }
821.  
822.  STATIC_OVL void
823.  dig_up_grave()
824.  {
825.  	struct obj *otmp;
826.  
827.  	/* Grave-robbing is frowned upon... */
828.  	exercise(A_WIS, FALSE);
829.  	if (Role_if(PM_ARCHEOLOGIST)) {
830.  	    adjalign(-sgn(u.ualign.type)*3);
831.  	    You_feel("like a despicable grave-robber!");
832.  	} else if (Role_if(PM_SAMURAI)) {
833.  	    adjalign(-sgn(u.ualign.type));
834.  	    You("disturb the honorable dead!");
835.  	} else if ((u.ualign.type == A_LAWFUL) && (u.ualign.record > -10)) {
836.  	    adjalign(-sgn(u.ualign.type));
837.  	    You("have violated the sanctity of this grave!");
838.  	}
839.  
840.  	switch (rn2(5)) {
841.  	case 0:
842.  	case 1:
843.  	    You("unearth a corpse.");
844.  	    if (!!(otmp = mk_tt_object(CORPSE, u.ux, u.uy)))
845.  	    	otmp->age -= 100;		/* this is an *OLD* corpse */;
846.  	    break;
847.  	case 2:
848.  	    if (!Blind) pline(Hallucination ? "Dude!  The living dead!" :
849.   			"The grave's owner is very upset!");
850.   	    (void) makemon(mkclass(S_ZOMBIE,0), u.ux, u.uy, NO_MM_FLAGS);
851.  	    break;
852.  	case 3:
853.  	    if (!Blind) pline(Hallucination ? "I want my mummy!" :
854.   			"You've disturbed a tomb!");
855.   	    (void) makemon(mkclass(S_MUMMY,0), u.ux, u.uy, NO_MM_FLAGS);
856.  	    break;
857.  	default:
858.  	    /* No corpse */
859.  	    pline_The("grave seems unused.  Strange....");
860.  	    break;
861.  	}
862.  	levl[u.ux][u.uy].typ = ROOM;
863.  	del_engr_at(u.ux, u.uy);
864.  	newsym(u.ux,u.uy);
865.  	return;
866.  }
867.  
868.  int
869.  use_pick_axe(obj)
870.  struct obj *obj;
871.  {
872.  	boolean ispick;
873.  	char dirsyms[12];
874.  	char qbuf[QBUFSZ];
875.  	register char *dsp = dirsyms;
876.  	register int rx, ry;
877.  	int res = 0;
878.  	register const char *sdp, *verb;
879.  
880.  	if(iflags.num_pad) sdp = ndir; else sdp = sdir;	/* DICE workaround */
881.  
882.  	/* Check tool */
883.  	if (obj != uwep) {
884.  	    if (!wield_tool(obj, "swing")) return 0;
885.  	    else res = 1;
886.  	}
887.  	ispick = is_pick(obj);
888.  	verb = ispick ? "dig" : "chop";
889.  
890.  	if (u.utrap && u.utraptype == TT_WEB) {
891.  	    pline("%s you can't %s while entangled in a web.",
892.  		  /* res==0 => no prior message;
893.  		     res==1 => just got "You now wield a pick-axe." message */
894.  		  !res ? "Unfortunately," : "But", verb);
895.  	    return res;
896.  	}
897.  
898.  	while(*sdp) {
899.  		(void) movecmd(*sdp);	/* sets u.dx and u.dy and u.dz */
900.  		rx = u.ux + u.dx;
901.  		ry = u.uy + u.dy;
902.  		/* Include down even with axe, so we have at least one direction */
903.  		if (u.dz > 0 ||
904.  		    (u.dz == 0 && isok(rx, ry) &&
905.  		     dig_typ(obj, rx, ry) != DIGTYP_UNDIGGABLE))
906.  			*dsp++ = *sdp;
907.  		sdp++;
908.  	}
909.  	*dsp = 0;
910.  	Sprintf(qbuf, "In what direction do you want to %s? [%s]", verb, dirsyms);
911.  	if(!getdir(qbuf))
912.  		return(res);
913.  
914.  	return (use_pick_axe2(obj));
915.  }
916.  
917.  /* general dig through doors/etc. function
918.   * Handles pickaxes/lightsabers/axes
919.   * called from doforce and use_pick_axe
920.   */
921.  
922.  /* MRKR: use_pick_axe() is split in two to allow autodig to bypass */
923.  /*       the "In what direction do you want to dig?" query.        */
924.  /*       use_pick_axe2() uses the existing u.dx, u.dy and u.dz    */
925.  
926.  int use_pick_axe2(obj)
927.  struct obj *obj;
928.  {
929.  	register int rx, ry;
930.  	register struct rm *lev;
931.  	int dig_target, digtyp;
932.  	boolean ispick = is_pick(obj);
933.  	const char *verbing = ispick ? "digging" :
934.  #ifdef LIGHTSABERS
935.  		is_lightsaber(uwep) ? "cutting" :
936.  #endif
937.  		"chopping";
938.  
939.  	/* 0 = pick, 1 = lightsaber, 2 = axe */
940.  	digtyp = (is_pick(uwep) ? 0 :
941.  #ifdef LIGHTSABERS
942.  		is_lightsaber(uwep) ? 1 :
943.  #endif
944.  		2);
945.  
946.  	if (u.uswallow && attack(u.ustuck)) {
947.  		;  /* return(1) */
948.  	} else if (Underwater) {
949.  		pline("Turbulence torpedoes your %s attempts.", verbing);
950.  	} else if(u.dz < 0) {
951.  		if(Levitation)
952.  		    if (digtyp == 1)
953.  			pline_The("ceiling is too hard to cut through.");
954.  		    else
955.  			You("don't have enough leverage.");
956.  		else
957.  			You_cant("reach the %s.",ceiling(u.ux,u.uy));
958.  	} else if(!u.dx && !u.dy && !u.dz) {
959.  		/* NOTREACHED for lightsabers/axes called from doforce */
960.  		
961.  		char buf[BUFSZ];
962.  		int dam;
963.  
964.  		dam = rnd(2) + dbon() + obj->spe;
965.  		if (dam <= 0) dam = 1;
966.  		You("hit yourself with %s.", yname(uwep));
967.  		Sprintf(buf, "%s own %s", uhis(),
968.  				OBJ_NAME(objects[obj->otyp]));
969.  		losehp(dam, buf, KILLED_BY);
970.  		flags.botl=1;
971.  		return(1);
972.  	} else if(u.dz == 0) {
973.  		if(Stunned || (Confusion && !rn2(5))) confdir();
974.  		rx = u.ux + u.dx;
975.  		ry = u.uy + u.dy;
976.  		if(!isok(rx, ry)) {
977.  			if (digtyp == 1) pline("Your %s bounces off harmlessly.",
978.  				aobjnam(obj, (char *)0));
979.  			else pline("Clash!");
980.  			return(1);
981.  		}
982.  		lev = &levl[rx][ry];
983.  		if(MON_AT(rx, ry) && attack(m_at(rx, ry)))
984.  			return(1);
985.  		dig_target = dig_typ(obj, rx, ry);
986.  		if (dig_target == DIGTYP_UNDIGGABLE) {
987.  			/* ACCESSIBLE or POOL */
988.  			struct trap *trap = t_at(rx, ry);
989.  
990.  			if (trap && trap->ttyp == WEB) {
991.  			    if (!trap->tseen) {
992.  				seetrap(trap);
993.  				There("is a spider web there!");
994.  			    }
995.  			    Your("%s entangled in the web.",
996.  				aobjnam(obj, "become"));
997.  			    /* you ought to be able to let go; tough luck */
998.  			    /* (maybe `move_into_trap()' would be better) */
999.  			    nomul(-d(2,2));
1000. 			    nomovemsg = "You pull free.";
1001. 			} else if (lev->typ == IRONBARS) {
1002. 			    pline("Clang!");
1003. 			    wake_nearby();
1004. 			} else if (IS_TREE(lev->typ))
1005. 			    You("need an axe to cut down a tree.");
1006. 			else if (IS_ROCK(lev->typ))
1007. 			    You("need a pick to dig rock.");
1008. 			else if (!ispick && (sobj_at(STATUE, rx, ry) ||
1009. 					     sobj_at(BOULDER, rx, ry))) {
1010. 			    boolean vibrate = !rn2(3);
1011. 			    pline("Sparks fly as you whack the %s.%s",
1012. 				sobj_at(STATUE, rx, ry) ? "statue" : "boulder",
1013. 				vibrate ? " The axe-handle vibrates violently!" : "");
1014. 			    if (vibrate) losehp(2, "axing a hard object", KILLED_BY);
1015. 			}
1016. 			else
1017. 			    You("swing your %s through thin air.",
1018. 				aobjnam(obj, (char *)0));
1019. 		} else {
1020. 			static const char * const d_action[6][2] = {
1021. 			    {"swinging","slicing the air"},
1022. 			    {"digging","cutting through the wall"},
1023. 			    {"chipping the statue","cutting the statue"},
1024. 			    {"hitting the boulder","cutting through the boulder"},
1025. 			    {"chopping at the door","burning through the door"},
1026. 			    {"cutting the tree","razing the tree"}
1027. 			};
1028. 			did_dig_msg = FALSE;
1029. 			digging.quiet = FALSE;
1030. 			if (digging.pos.x != rx || digging.pos.y != ry ||
1031. 			    !on_level(&digging.level, &u.uz) || digging.down) {
1032. 			    if (flags.autodig &&
1033. 				dig_target == DIGTYP_ROCK && !digging.down &&
1034. 				digging.pos.x == u.ux &&
1035. 				digging.pos.y == u.uy &&
1036. 				(moves <= digging.lastdigtime+2 &&
1037. 				 moves >= digging.lastdigtime)) {
1038. 				/* avoid messages if repeated autodigging */
1039. 				did_dig_msg = TRUE;
1040. 				digging.quiet = TRUE;
1041. 			    }
1042. 			    digging.down = digging.chew = FALSE;
1043. 			    digging.warned = FALSE;
1044. 			    digging.pos.x = rx;
1045. 			    digging.pos.y = ry;
1046. 			    assign_level(&digging.level, &u.uz);
1047. 			    digging.effort = 0;
1048. 			    if (!digging.quiet)
1049. 				You("start %s.", d_action[dig_target][digtyp == 1]);
1050. 			} else {
1051. 			    You("%s %s.", digging.chew ? "begin" : "continue",
1052. 					d_action[dig_target][digtyp == 1]);
1053. 			    digging.chew = FALSE;
1054. 			}
1055. 			set_occupation(dig, verbing, 0);
1056. 		}
1057. 	} else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
1058. 		/* it must be air -- water checked above */
1059. 		You("swing your %s through thin air.", aobjnam(obj, (char *)0));
1060. 	} else if (!can_reach_floor()) {
1061. 		You_cant("reach the %s.", surface(u.ux,u.uy));
1062. 	} else if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) {
1063. 		/* Monsters which swim also happen not to be able to dig */
1064. 		You("cannot stay under%s long enough.",
1065. 				is_pool(u.ux, u.uy) ? "water" : " the lava");
1066. 	} else if (digtyp == 2) {
1067. 		Your("%s merely scratches the %s.",
1068. 				aobjnam(obj, (char *)0), surface(u.ux,u.uy));
1069. 		u_wipe_engr(3);
1070. 	} else {
1071. 		if (digging.pos.x != u.ux || digging.pos.y != u.uy ||
1072. 			!on_level(&digging.level, &u.uz) || !digging.down) {
1073. 		    digging.chew = FALSE;
1074. 		    digging.down = TRUE;
1075. 		    digging.warned = FALSE;
1076. 		    digging.pos.x = u.ux;
1077. 		    digging.pos.y = u.uy;
1078. 		    assign_level(&digging.level, &u.uz);
1079. 		    digging.effort = 0;
1080. 		    You("start %s downward.", verbing);
1081. 		    if (*u.ushops) shopdig(0);
1082. 		} else
1083. 		    You("continue %s downward.", verbing);
1084. 		did_dig_msg = FALSE;
1085. 		set_occupation(dig, verbing, 0);
1086. 	}
1087. 	return(1);
1088. }
1089. 
1090. /*
1091.  * Town Watchmen frown on damage to the town walls, trees or fountains.
1092.  * It's OK to dig holes in the ground, however.
1093.  * If mtmp is assumed to be a watchman, a watchman is found if mtmp == 0
1094.  * zap == TRUE if wand/spell of digging, FALSE otherwise (chewing)
1095.  */
1096. void
1097. watch_dig(mtmp, x, y, zap)
1098.     struct monst *mtmp;
1099.     xchar x, y;
1100.     boolean zap;
1101. {
1102. 	struct rm *lev = &levl[x][y];
1103. 
1104. 	if (in_town(x, y) &&
1105. 	    (closed_door(x, y) || lev->typ == SDOOR ||
1106. 	     IS_WALL(lev->typ) || IS_FOUNTAIN(lev->typ) || IS_TREE(lev->typ))) {
1107. 	    if (!mtmp) {
1108. 		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1109. 		    if (DEADMONSTER(mtmp)) continue;
1110. 		    if ((mtmp->data == &mons[PM_WATCHMAN] ||
1111. 			 mtmp->data == &mons[PM_WATCH_CAPTAIN]) &&
1112. 			mtmp->mcansee && m_canseeu(mtmp) &&
1113. 			couldsee(mtmp->mx, mtmp->my) && mtmp->mpeaceful)
1114. 			break;
1115. 		}
1116. 	    }
1117. 
1118. 	    if (mtmp) {
1119. 		if(zap || digging.warned) {
1120. 		    verbalize("Halt, vandal!  You're under arrest!");
1121. 		    (void) angry_guards(!(flags.soundok));
1122. 		} else {
1123. 		    const char *str;
1124. 
1125. 		    if (IS_DOOR(lev->typ))
1126. 			str = "door";
1127. 		    else if (IS_TREE(lev->typ))
1128. 			str = "tree";
1129. 		    else if (IS_ROCK(lev->typ))
1130. 			str = "wall";
1131. 		    else
1132. 			str = "fountain";
1133. 		    verbalize("Hey, stop damaging that %s!", str);
1134. 		    digging.warned = TRUE;
1135. 		}
1136. 		if (is_digging())
1137. 		    stop_occupation();
1138. 	    }
1139. 	}
1140. }
1141. 
1142. #endif /* OVLB */
1143. #ifdef OVL0
1144. 
1145. /* Return TRUE if monster died, FALSE otherwise.  Called from m_move(). */
1146. boolean
1147. mdig_tunnel(mtmp)
1148. register struct monst *mtmp;
1149. {
1150. 	register struct rm *here;
1151. 	int pile = rnd(12);
1152. 
1153. 	here = &levl[mtmp->mx][mtmp->my];
1154. 	if (here->typ == SDOOR)
1155. 	    cvt_sdoor_to_door(here);	/* ->typ = DOOR */
1156. 
1157. 	/* Eats away door if present & closed or locked */
1158. 	if (closed_door(mtmp->mx, mtmp->my)) {
1159. 	    if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
1160. 		add_damage(mtmp->mx, mtmp->my, 0L);
1161. 	    unblock_point(mtmp->mx, mtmp->my);	/* vision */
1162. 	    if (here->doormask & D_TRAPPED) {
1163. 		here->doormask = D_NODOOR;
1164. 		if (mb_trapped(mtmp)) {	/* mtmp is killed */
1165. 		    newsym(mtmp->mx, mtmp->my);
1166. 		    return TRUE;
1167. 		}
1168. 	    } else {
1169. 		if (!rn2(3) && flags.verbose)	/* not too often.. */
1170. 		    You_feel("an unexpected draft.");
1171. 		here->doormask = D_BROKEN;
1172. 	    }
1173. 	    newsym(mtmp->mx, mtmp->my);
1174. 	    return FALSE;
1175. 	} else if (!IS_ROCK(here->typ) && !IS_TREE(here->typ)) /* no dig */
1176. 	    return FALSE;
1177. 
1178. 	/* Only rock, trees, and walls fall through to this point. */
1179. 	if ((here->wall_info & W_NONDIGGABLE) != 0) {
1180. 	    impossible("mdig_tunnel:  %s at (%d,%d) is undiggable",
1181. 		       (IS_WALL(here->typ) ? "wall" : "stone"),
1182. 		       (int) mtmp->mx, (int) mtmp->my);
1183. 	    return FALSE;	/* still alive */
1184. 	}
1185. 
1186. 	if (IS_WALL(here->typ)) {
1187. 	    /* KMH -- Okay on arboreal levels (room walls are still stone) */
1188. 	    if (flags.soundok && flags.verbose && !rn2(5))
1189. 	    /* KMH -- Okay on arboreal levels (room walls are still stone) */
1190. 		You_hear("crashing rock.");
1191. 	    if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
1192. 		add_damage(mtmp->mx, mtmp->my, 0L);
1193. 	    if (level.flags.is_maze_lev) {
1194. 		here->typ = ROOM;
1195. 	    } else if (level.flags.is_cavernous_lev &&
1196. 		       !in_town(mtmp->mx, mtmp->my)) {
1197. 		here->typ = CORR;
1198. 	    } else {
1199. 		here->typ = DOOR;
1200. 		here->doormask = D_NODOOR;
1201. 	    }
1202. 	} else if (IS_TREE(here->typ)) {
1203. 	    here->typ = ROOM;
1204. 	    if (pile && pile < 5)
1205. 		(void) rnd_treefruit_at(mtmp->mx, mtmp->my);
1206. 	} else {
1207. 	    here->typ = CORR;
1208. 	    if (pile && pile < 5)
1209. 	    (void) mksobj_at((pile == 1) ? BOULDER : ROCK,
1210. 			     mtmp->mx, mtmp->my, TRUE, FALSE);
1211. 	}
1212. 	newsym(mtmp->mx, mtmp->my);
1213. 	if (!sobj_at(BOULDER, mtmp->mx, mtmp->my))
1214. 	    unblock_point(mtmp->mx, mtmp->my);	/* vision */
1215. 
1216. 	return FALSE;
1217. }
1218. 
1219. #endif /* OVL0 */
1220. #ifdef OVL3
1221. 
1222. /* digging via wand zap or spell cast */
1223. void
1224. zap_dig()
1225. {
1226. 	struct rm *room;
1227. 	struct monst *mtmp;
1228. /*        struct obj *otmp;*/
1229.         register struct obj *otmp, *next_obj;
1230. 	int zx, zy, digdepth;
1231. 	boolean shopdoor, shopwall, maze_dig;
1232. 	/*
1233. 	 * Original effect (approximately):
1234. 	 * from CORR: dig until we pierce a wall
1235. 	 * from ROOM: pierce wall and dig until we reach
1236. 	 * an ACCESSIBLE place.
1237. 	 * Currently: dig for digdepth positions;
1238. 	 * also down on request of Lennart Augustsson.
1239. 	 */
1240. 
1241. 	if (u.uswallow) {
1242. 	    mtmp = u.ustuck;
1243. 
1244. 	    if (!is_whirly(mtmp->data)) {
1245. 		if (is_animal(mtmp->data))
1246. 		    You("pierce %s %s wall!",
1247. 			s_suffix(mon_nam(mtmp)), mbodypart(mtmp, STOMACH));
1248. 		mtmp->mhp = 1;		/* almost dead */
1249. 		expels(mtmp, mtmp->data, !is_animal(mtmp->data));
1250. 	    }
1251. 	    return;
1252. 	} /* swallowed */
1253. 
1254. 	if (u.dz) {
1255. 	    if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !Underwater) {
1256. 		if (u.dz < 0 || On_stairs(u.ux, u.uy)) {
1257. 		    if (On_stairs(u.ux, u.uy))
1258. 			pline_The("beam bounces off the %s and hits the %s.",
1259. 			      (u.ux == xdnladder || u.ux == xupladder) ?
1260. 			      "ladder" : "stairs", ceiling(u.ux, u.uy));
1261. 		    You("loosen a rock from the %s.", ceiling(u.ux, u.uy));
1262. 		    pline("It falls on your %s!", body_part(HEAD));
1263. 		    losehp(rnd((uarmh && is_metallic(uarmh)) ? 2 : 6),
1264. 			   "falling rock", KILLED_BY_AN);
1265. 		    otmp = mksobj_at(ROCK, u.ux, u.uy, FALSE, FALSE);
1266. 		    if (otmp) {
1267. 			(void)xname(otmp);	/* set dknown, maybe bknown */
1268. 			stackobj(otmp);
1269. 		    }
1270. 		    newsym(u.ux, u.uy);
1271. 		} else {
1272. 		    watch_dig((struct monst *)0, u.ux, u.uy, TRUE);
1273. 		    (void) dighole(FALSE);
1274. 		}
1275. 	    }
1276. 	    return;
1277. 	} /* up or down */
1278. 
1279. 	/* normal case: digging across the level */
1280. 	shopdoor = shopwall = FALSE;
1281. 	maze_dig = level.flags.is_maze_lev && !Is_earthlevel(&u.uz);
1282. 	zx = u.ux + u.dx;
1283. 	zy = u.uy + u.dy;
1284. 	digdepth = rn1(18, 8);
1285. 	tmp_at(DISP_BEAM, cmap_to_glyph(S_digbeam));
1286. 	while (--digdepth >= 0) {
1287. 	    if (!isok(zx,zy)) break;
1288. 	    room = &levl[zx][zy];
1289. 	    tmp_at(zx,zy);
1290. 	    delay_output();	/* wait a little bit */
1291. 
1292.             /* WAC check for monster, boulder */
1293.             if ((mtmp = m_at(zx, zy)) != 0) {
1294.                 if (made_of_rock(mtmp->data)) {
1295.                     You("gouge a hole in %s!", mon_nam(mtmp));
1296.                     mtmp->mhp /= 2;
1297.                     if (mtmp->mhp < 1) mtmp->mhp = 1;
1298. 		    setmangry(mtmp);
1299.                 } else pline("%s is unaffected!", Monnam(mtmp));
1300.             }
1301.             for(otmp = level.objects[zx][zy]; otmp; otmp = next_obj) {
1302.                 next_obj = otmp->nexthere;
1303. 		/* vaporize boulders */
1304.                 if (otmp->otyp == BOULDER) {
1305. 		    delobj(otmp);
1306. 		    /* A little Sokoban guilt... */
1307. 		    if (In_sokoban(&u.uz))
1308. 			change_luck(-1);
1309. 		    unblock_point(zx, zy);
1310. 		    newsym(zx, zy);
1311. 		    pline_The("boulder is vaporized!");
1312. 		}
1313. 		break;
1314.             }
1315. 
1316. 	    if (closed_door(zx, zy) || room->typ == SDOOR) {
1317. 		/* ALI - Artifact doors */
1318. 		if (artifact_door(zx, zy)) {
1319. 		    if (cansee(zx, zy))
1320. 			pline_The("door glows then fades.");
1321. 		    break;
1322. 		}
1323. 		if (*in_rooms(zx,zy,SHOPBASE)) {
1324. 		    add_damage(zx, zy, 400L);
1325. 		    shopdoor = TRUE;
1326. 		}
1327. 		if (room->typ == SDOOR)
1328. 		    room->typ = DOOR;
1329. 		else if (cansee(zx, zy))
1330. 		    pline_The("door is razed!");
1331. 		watch_dig((struct monst *)0, zx, zy, TRUE);
1332. 		room->doormask = D_NODOOR;
1333. 		unblock_point(zx,zy); /* vision */
1334. 		digdepth -= 2;
1335. 		if (maze_dig) break;
1336. 	    } else if (maze_dig) {
1337. 		if (IS_WALL(room->typ)) {
1338. 		    if (!(room->wall_info & W_NONDIGGABLE)) {
1339. 			if (*in_rooms(zx,zy,SHOPBASE)) {
1340. 			    add_damage(zx, zy, 200L);
1341. 			    shopwall = TRUE;
1342. 			}
1343. 			room->typ = ROOM;
1344. 			unblock_point(zx,zy); /* vision */
1345. 		    } else if (!Blind)
1346. 			pline_The("wall glows then fades.");
1347. 		    break;
1348. 		} else if (IS_TREE(room->typ)) { /* check trees before stone */
1349. 		    if (!(room->wall_info & W_NONDIGGABLE)) {
1350. 			room->typ = ROOM;
1351. 			unblock_point(zx,zy); /* vision */
1352. 		    } else if (!Blind)
1353. 			pline_The("tree shudders but is unharmed.");
1354. 		    break;
1355. 		} else if (room->typ == STONE || room->typ == SCORR) {
1356. 		    if (!(room->wall_info & W_NONDIGGABLE)) {
1357. 			room->typ = CORR;
1358. 			unblock_point(zx,zy); /* vision */
1359. 		    } else if (!Blind)
1360. 			pline_The("rock glows then fades.");
1361. 		    break;
1362. 		}
1363. 	    } else if (IS_ROCK(room->typ)) {
1364. 		if (!may_dig(zx,zy)) break;
1365. 		if (IS_WALL(room->typ) || room->typ == SDOOR) {
1366. 		    if (*in_rooms(zx,zy,SHOPBASE)) {
1367. 			add_damage(zx, zy, 200L);
1368. 			shopwall = TRUE;
1369. 		    }
1370. 		    watch_dig((struct monst *)0, zx, zy, TRUE);
1371. 		    if (level.flags.is_cavernous_lev && !in_town(zx, zy)) {
1372. 			room->typ = CORR;
1373. 		    } else {
1374. 			room->typ = DOOR;
1375. 			room->doormask = D_NODOOR;
1376. 		    }
1377. 		    digdepth -= 2;
1378. 		} else if (IS_TREE(room->typ)) {
1379. 		    room->typ = ROOM;
1380. 		    digdepth -= 2;
1381. 		} else {	/* IS_ROCK but not IS_WALL or SDOOR */
1382. 		    room->typ = CORR;
1383. 		    digdepth--;
1384. 		}
1385. 		unblock_point(zx,zy); /* vision */
1386. 	    }
1387. 	    zx += u.dx;
1388. 	    zy += u.dy;
1389. 	} /* while */
1390. 	tmp_at(DISP_END,0);	/* closing call */
1391. 	if (shopdoor || shopwall)
1392. 	    pay_for_damage(shopdoor ? "destroy" : "dig into", FALSE);
1393. 	return;
1394. }
1395. 
1396. /* move objects from fobj/nexthere lists to buriedobjlist, keeping position */
1397. /* information */
1398. struct obj *
1399. bury_an_obj(otmp)
1400. 	struct obj *otmp;
1401. {
1402. 	struct obj *otmp2;
1403. 	boolean under_ice;
1404. 
1405. #ifdef DEBUG
1406. 	pline("bury_an_obj: %s", xname(otmp));
1407. #endif
1408. 	if (otmp == uball)
1409. 		unpunish();
1410. 	/* after unpunish(), or might get deallocated chain */
1411. 	otmp2 = otmp->nexthere;
1412. 	/*
1413. 	 * obj_resists(,0,0) prevents Rider corpses from being buried.
1414. 	 * It also prevents The Amulet and invocation tools from being
1415. 	 * buried.  Since they can't be confined to bags and statues,
1416. 	 * it makes sense that they can't be buried either, even though
1417. 	 * the real reason there (direct accessibility when carried) is
1418. 	 * completely different.
1419. 	 */
1420. 	if (otmp == uchain || obj_resists(otmp, 0, 0))
1421. 		return(otmp2);
1422. 
1423. 	if (otmp->otyp == LEASH && otmp->leashmon != 0)
1424. 		o_unleash(otmp);
1425. 
1426. #ifdef STEED
1427. 	if (otmp == usaddle)
1428. 		dismount_steed(DISMOUNT_GENERIC);
1429. #endif
1430. 
1431. 	if (otmp->lamplit && otmp->otyp != POT_OIL)
1432. 		end_burn(otmp, TRUE);
1433. 
1434. 	obj_extract_self(otmp);
1435. 
1436. 	under_ice = is_ice(otmp->ox, otmp->oy);
1437. 	if (otmp->otyp == ROCK && !under_ice) {
1438. 		/* merges into burying material */
1439. 		obfree(otmp, (struct obj *)0);
1440. 		return(otmp2);
1441. 	}
1442. 	/*
1443. 	 * Start a rot on organic material.  Not corpses -- they
1444. 	 * are already handled.
1445. 	 */
1446. 	if (otmp->otyp == CORPSE) {
1447. 	    ;		/* should cancel timer if under_ice */
1448. 	} else if ((under_ice ? otmp->oclass == POTION_CLASS : is_organic(otmp))
1449. 		&& !obj_resists(otmp, 5, 95)) {
1450. 	    (void) start_timer((under_ice ? 0L : 250L) + (long)rnd(250),
1451. 			       TIMER_OBJECT, ROT_ORGANIC, (genericptr_t)otmp);
1452. 	}
1453. 	add_to_buried(otmp);
1454. 	return(otmp2);
1455. }
1456. 
1457. void
1458. bury_objs(x, y)
1459. int x, y;
1460. {
1461. 	struct obj *otmp, *otmp2;
1462. 
1463. #ifdef DEBUG
1464. 	if(level.objects[x][y] != (struct obj *)0)
1465. 		pline("bury_objs: at %d, %d", x, y);
1466. #endif
1467. 	for (otmp = level.objects[x][y]; otmp; otmp = otmp2)
1468. 		otmp2 = bury_an_obj(otmp);
1469. 
1470. 	/* don't expect any engravings here, but just in case */
1471. 	del_engr_at(x, y);
1472. 	newsym(x, y);
1473. }
1474. 
1475. /* move objects from buriedobjlist to fobj/nexthere lists */
1476. void
1477. unearth_objs(x, y)
1478. int x, y;
1479. {
1480. 	struct obj *otmp, *otmp2;
1481. 
1482. #ifdef DEBUG
1483. 	pline("unearth_objs: at %d, %d", x, y);
1484. #endif
1485. 	for (otmp = level.buriedobjlist; otmp; otmp = otmp2) {
1486. 		otmp2 = otmp->nobj;
1487. 		if (otmp->ox == x && otmp->oy == y) {
1488. 		    obj_extract_self(otmp);
1489. 		    if (otmp->timed)
1490. 			(void) stop_timer(ROT_ORGANIC, (genericptr_t)otmp);
1491. 		    place_object(otmp, x, y);
1492. 		    stackobj(otmp);
1493. 		}
1494. 	}
1495. 	del_engr_at(x, y);
1496. 	newsym(x, y);
1497. }
1498. 
1499. /*
1500.  * The organic material has rotted away while buried.  As an expansion,
1501.  * we could add add partial damage.  A damage count is kept in the object
1502.  * and every time we are called we increment the count and reschedule another
1503.  * timeout.  Eventually the object rots away.
1504.  *
1505.  * This is used by buried objects other than corpses.  When a container rots
1506.  * away, any contents become newly buried objects.
1507.  */
1508. /* ARGSUSED */
1509. void
1510. rot_organic(arg, timeout)
1511. genericptr_t arg;
1512. long timeout;	/* unused */
1513. {
1514. #if defined(MAC_MPW)
1515. # pragma unused ( timeout )
1516. #endif
1517. 	struct obj *obj = (struct obj *) arg;
1518. 
1519. 	while (Has_contents(obj)) {
1520. 	    /* We don't need to place contained object on the floor
1521. 	       first, but we do need to update its map coordinates. */
1522. 	    obj->cobj->ox = obj->ox,  obj->cobj->oy = obj->oy;
1523. 	    /* Everything which can be held in a container can also be
1524. 	       buried, so bury_an_obj's use of obj_extract_self insures
1525. 	       that Has_contents(obj) will eventually become false. */
1526. 	    (void)bury_an_obj(obj->cobj);
1527. 	}
1528. 	obj_extract_self(obj);
1529. 	obfree(obj, (struct obj *) 0);
1530. }
1531. 
1532. /*
1533.  * Called when a corpse has rotted completely away.
1534.  */
1535. void
1536. rot_corpse(arg, timeout)
1537. genericptr_t arg;
1538. long timeout;	/* unused */
1539. {
1540. 	xchar x = 0, y = 0;
1541. 	struct obj *obj = (struct obj *) arg;
1542. 	boolean on_floor = obj->where == OBJ_FLOOR,
1543.                 in_minvent = obj->where == OBJ_MINVENT,
1544. 		in_invent = obj->where == OBJ_INVENT;
1545. 
1546. 	if (on_floor) {
1547. 	    x = obj->ox;
1548. 	    y = obj->oy;
1549.         } else if (in_minvent) {
1550.             /* WAC unwield if wielded */
1551.             if (MON_WEP(obj->ocarry) && MON_WEP(obj->ocarry) == obj) {
1552. 		    obj->owornmask &= ~W_WEP;
1553.                     MON_NOWEP(obj->ocarry);
1554. 	    }
1555. 	} else if (in_invent) {
1556. 	    if (flags.verbose) {
1557. 		char *cname = corpse_xname(obj, FALSE);
1558. 		Your("%s%s %s away%c",
1559. 		     obj == uwep ? "wielded " : nul, cname,
1560. 		     otense(obj, "rot"), obj == uwep ? '!' : '.');
1561. 	    }
1562. 	    if (obj == uwep) {
1563. 		uwepgone();	/* now bare handed */
1564. 		stop_occupation();
1565. 	    } else if (obj == uswapwep) {
1566. 		uswapwepgone();
1567. 		stop_occupation();
1568. 	    } else if (obj == uquiver) {
1569. 		uqwepgone();
1570. 		stop_occupation();
1571. 	    } else if (obj == uswapwep) {
1572. 		uswapwepgone();
1573. 		stop_occupation();
1574. 	    } else if (obj == uquiver) {
1575. 		uqwepgone();
1576. 		stop_occupation();
1577. 	    }
1578. 	} else if (obj->where == OBJ_MINVENT && obj->owornmask) {
1579. 	    if (obj == MON_WEP(obj->ocarry)) {
1580. 		setmnotwielded(obj->ocarry,obj);
1581. 		MON_NOWEP(obj->ocarry);
1582. 	    }
1583. 	}
1584. 	rot_organic(arg, timeout);
1585. 	if (on_floor) newsym(x, y);
1586. 	else if (in_invent) update_inventory();
1587. }
1588. 
1589. #if 0
1590. void
1591. bury_monst(mtmp)
1592. struct monst *mtmp;
1593. {
1594. #ifdef DEBUG
1595. 	pline("bury_monst: %s", mon_nam(mtmp));
1596. #endif
1597. 	if(canseemon(mtmp)) {
1598. 	    if(is_flyer(mtmp->data) || is_floater(mtmp->data)) {
1599. 		pline_The("%s opens up, but %s is not swallowed!",
1600. 			surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
1601. 		return;
1602. 	    } else
1603. 	        pline_The("%s opens up and swallows %s!",
1604. 			surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
1605. 	}
1606. 
1607. 	mtmp->mburied = TRUE;
1608. 	wakeup(mtmp);			/* at least give it a chance :-) */
1609. 	newsym(mtmp->mx, mtmp->my);
1610. }
1611. 
1612. void
1613. bury_you()
1614. {
1615. #ifdef DEBUG
1616. 	pline("bury_you");
1617. #endif
1618. 	/* KMH, balance patch -- new intrinsic */
1619.     if (!Levitation && !Flying) {
1620. 	if(u.uswallow)
1621. 	    You_feel("a sensation like falling into a trap!");
1622. 	else
1623. 	    pline_The("%s opens beneath you and you fall in!",
1624. 		  surface(u.ux, u.uy));
1625. 
1626. 	u.uburied = TRUE;
1627. 	if(!Strangled && !Breathless) Strangled = 6;
1628. 	under_ground(1);
1629.     }
1630. }
1631. 
1632. void
1633. unearth_you()
1634. {
1635. #ifdef DEBUG
1636. 	pline("unearth_you");
1637. #endif
1638. 	u.uburied = FALSE;
1639. 	under_ground(0);
1640. 	if(!uamul || uamul->otyp != AMULET_OF_STRANGULATION)
1641. 		Strangled = 0;
1642. 	vision_recalc(0);
1643. }
1644. 
1645. void
1646. escape_tomb()
1647. {
1648. #ifdef DEBUG
1649. 	pline("escape_tomb");
1650. #endif
1651. 	if ((Teleportation || can_teleport(youmonst.data)) &&
1652. 	    (Teleport_control || rn2(3) < Luck+2)) {
1653. 		You("attempt a teleport spell.");
1654. 		(void) dotele();	/* calls unearth_you() */
1655. 	} else if(u.uburied) { /* still buried after 'port attempt */
1656. 		boolean good;
1657. 
1658. 		if(amorphous(youmonst.data) || Passes_walls ||
1659. 		   noncorporeal(youmonst.data) || unsolid(youmonst.data) ||
1660. 		   (tunnels(youmonst.data) && !needspick(youmonst.data))) {
1661. 
1662. 		    You("%s up through the %s.",
1663. 			(tunnels(youmonst.data) && !needspick(youmonst.data)) ?
1664. 			 "try to tunnel" : (amorphous(youmonst.data)) ?
1665. 			 "ooze" : "phase", surface(u.ux, u.uy));
1666. 
1667. 		    if(tunnels(youmonst.data) && !needspick(youmonst.data))
1668. 			good = dighole(TRUE);
1669. 		    else good = TRUE;
1670. 		    if(good) unearth_you();
1671. 		}
1672. 	}
1673. }
1674. 
1675. void
1676. bury_obj(otmp)
1677. struct obj *otmp;
1678. {
1679. 
1680. #ifdef DEBUG
1681. 	pline("bury_obj");
1682. #endif
1683. 	if(cansee(otmp->ox, otmp->oy))
1684. 	   pline_The("objects on the %s tumble into a hole!",
1685. 		surface(otmp->ox, otmp->oy));
1686. 
1687. 	bury_objs(otmp->ox, otmp->oy);
1688. }
1689. #endif
1690. 
1691. #ifdef DEBUG
1692. int
1693. wiz_debug_cmd() /* in this case, bury everything at your loc and around */
1694. {
1695. 	int x, y;
1696. 
1697. 	for (x = u.ux - 1; x <= u.ux + 1; x++)
1698. 	    for (y = u.uy - 1; y <= u.uy + 1; y++)
1699. 		if (isok(x,y)) bury_objs(x,y);
1700. 	return 0;
1701. }
1702. 
1703. #endif /* DEBUG */
1704. #endif /* OVL3 */
1705. 
1706. /*dig.c*/