Wikia

Wikihack

Source:SLASH'EM 0.0.7E7F2/dig.c

2,032pages on
this wiki
Talk0

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.
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  */</span>
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*/

Around Wikia's network

Random Wiki