Source:NetHack 3.2.0/dig.c

From NetHackWiki
(Redirected from NetHack 3.2.0/dig.c)
Jump to navigation Jump to search

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

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

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

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

1.    /*	SCCS Id: @(#)dig.c	3.2	96/03/15	*/
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 boolean NDECL(rm_waslit);
14.   static void FDECL(mkcavepos, (XCHAR_P,XCHAR_P,int,BOOLEAN_P,BOOLEAN_P));
15.   static void FDECL(mkcavearea, (BOOLEAN_P));
16.   static int FDECL(dig_typ, (XCHAR_P,XCHAR_P));
17.   STATIC_DCL int NDECL(dig);
18.   STATIC_DCL schar FDECL(fillholetyp, (int, int));
19.   
20.   static boolean
21.   rm_waslit()
22.   {
23.       register xchar x, y;
24.   
25.       if(levl[u.ux][u.uy].typ == ROOM && levl[u.ux][u.uy].waslit)
26.   	return(TRUE);
27.       for(x = u.ux-2; x < u.ux+3; x++)
28.   	for(y = u.uy-1; y < u.uy+2; y++)
29.   	    if(isok(x,y) && levl[x][y].waslit) return(TRUE);
30.       return(FALSE);
31.   }
32.   
33.   /* Change level topology.  Messes with vision tables and ignores things like
34.    * boulders in the name of a nice effect.  Vision will get fixed up again
35.    * immediately after the effect is complete.
36.    */
37.   static void
38.   mkcavepos(x, y, dist, waslit, rockit)
39.       xchar x,y;
40.       int dist;
41.       boolean waslit, rockit;
42.   {
43.       register struct rm *lev;
44.   
45.       if(!isok(x,y)) return;
46.       lev = &levl[x][y];
47.   
48.       if(rockit) {
49.   	register struct monst *mtmp;
50.   
51.   	if(IS_ROCK(lev->typ)) return;
52.   	if(t_at(x, y)) return; /* don't cover the portal */
53.   	if ((mtmp = m_at(x, y)) != 0)	/* make sure crucial monsters survive */
54.   	    if(!passes_walls(mtmp->data)) rloc(mtmp);
55.       } else if(lev->typ == ROOM) return;
56.   
57.       unblock_point(x,y);	/* make sure vision knows this location is open */
58.   
59.       /* fake out saved state */
60.       lev->seenv = 0;
61.       lev->doormask = 0;
62.       if(dist < 3) lev->lit = (rockit ? FALSE : TRUE);
63.       if(waslit) lev->waslit = (rockit ? FALSE : TRUE);
64.       lev->horizontal = FALSE;
65.       viz_array[y][x] = (dist < 3 ) ?
66.   	(IN_SIGHT|COULD_SEE) : /* short-circuit vision recalc */
67.   	COULD_SEE;
68.       lev->typ = (rockit ? STONE : ROOM);
69.       if(dist >= 3)
70.   	impossible("mkcavepos called with dist %d", dist);
71.       if(Blind)
72.   	feel_location(x, y);
73.       else newsym(x,y);
74.   }
75.   
76.   static void
77.   mkcavearea(rockit)
78.   register boolean rockit;
79.   {
80.       int dist;
81.       xchar xmin = u.ux, xmax = u.ux;
82.       xchar ymin = u.uy, ymax = u.uy;
83.       register xchar i;
84.       register boolean waslit = rm_waslit();
85.   
86.       if(rockit) pline("Crash!  The ceiling collapses around you!");
87.       else pline("A mysterious force %s cave around you!",
88.   	     (levl[u.ux][u.uy].typ == CORR) ? "creates a" : "extends the");
89.       display_nhwindow(WIN_MESSAGE, TRUE);
90.   
91.       for(dist = 1; dist <= 2; dist++) {
92.   	xmin--; xmax++;
93.   
94.   	/* top and bottom */
95.   	if(dist < 2) { /* the area is wider that it is high */
96.   	    ymin--; ymax++;
97.   	    for(i = xmin+1; i < xmax; i++) {
98.   		mkcavepos(i, ymin, dist, waslit, rockit);
99.   		mkcavepos(i, ymax, dist, waslit, rockit);
100.  	    }
101.  	}
102.  
103.  	/* left and right */
104.  	for(i = ymin; i <= ymax; i++) {
105.  	    mkcavepos(xmin, i, dist, waslit, rockit);
106.  	    mkcavepos(xmax, i, dist, waslit, rockit);
107.  	}
108.  
109.  	flush_screen(1);	/* make sure the new glyphs shows up */
110.  	delay_output();
111.      }
112.  
113.      if(!rockit && levl[u.ux][u.uy].typ == CORR) {
114.  	levl[u.ux][u.uy].typ = ROOM;
115.  	if(waslit) levl[u.ux][u.uy].waslit = TRUE;
116.  	newsym(u.ux, u.uy); /* in case player is invisible */
117.      }
118.  
119.      vision_full_recalc = 1;	/* everything changed */
120.  }
121.  
122.  /* When digging into location <x,y>, what are you actually digging into? */
123.  /* result: 1=>statue, 2=>boulder, 3=>door, 0=>other; used as array index */
124.  static int
125.  dig_typ(x, y)
126.  xchar x, y;
127.  {
128.  	return (sobj_at(STATUE, x, y) ? 1 :
129.  		sobj_at(BOULDER, x, y) ? 2 :
130.  		closed_door(x, y) ? 3 : 0);
131.  }
132.  
133.  #define BY_YOU		(&youmonst)
134.  #define BY_OBJECT	((struct monst *)0)
135.  
136.  boolean
137.  dig_check(madeby, verbose, x, y)
138.  	struct monst	*madeby;
139.  	boolean		verbose;
140.  	int		x, y;
141.  {
142.  	struct trap *ttmp;
143.  
144.  	if (On_stairs(x, y)) {
145.  	    if (x == xdnladder || x == xupladder) {
146.  		if(verbose) pline_The("ladder resists your effort.");
147.  	    } else if(verbose) pline_The("stairs are too hard to dig in.");
148.  	    return(FALSE);
149.  	} else if (IS_THRONE(levl[x][y].typ) && madeby != BY_OBJECT) {
150.  	    if(verbose) pline_The("throne is too hard to break apart.");
151.  	    return(FALSE);
152.  	} else if (IS_ALTAR(levl[x][y].typ) && (madeby != BY_OBJECT ||
153.  				Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) {
154.  	    if(verbose) pline_The("altar is too hard to break apart.");
155.  	    return(FALSE);
156.  	} else if (Is_airlevel(&u.uz)) {
157.  	    if(verbose) You("cannot dig in thin air.");
158.  	    return(FALSE);
159.  	} else if (Is_waterlevel(&u.uz)) {
160.  	    if(verbose) pline_The("water splashes and subsides.");
161.  	    return(FALSE);
162.  	} else if ((IS_WALL(levl[x][y].typ)
163.  		&& (levl[x][y].wall_info & W_NONDIGGABLE) != 0)
164.  		|| ((ttmp = t_at(x, y)) != 0 &&
165.  		    (ttmp->ttyp == MAGIC_PORTAL || !Can_dig_down(&u.uz)))) {
166.  	    if(verbose) pline_The("%s here is too hard to dig in.",
167.  				  surface(x,y));
168.  	    return(FALSE);
169.  	} else if (sobj_at(BOULDER, x, y)) {
170.  	    if(verbose) pline("There isn't enough room to dig here.");
171.  	    return(FALSE);
172.  	} else if (madeby == BY_OBJECT && (is_pool(x,y) || is_lava(x,y))) {
173.  	    /* digging by player handles pools separately */
174.  	    return FALSE;
175.  	}
176.  	return(TRUE);
177.  }
178.  
179.  STATIC_OVL int
180.  dig()
181.  {
182.  	register struct rm *lev;
183.  	register xchar dpx = digging.pos.x, dpy = digging.pos.y;
184.  
185.  	lev = &levl[dpx][dpy];
186.  	/* perhaps a nymph stole your pick-axe while you were busy digging */
187.  	/* or perhaps you teleported away */
188.  	if (u.uswallow || !uwep || uwep->otyp != PICK_AXE ||
189.  	    !on_level(&digging.level, &u.uz) ||
190.  	    ((digging.down ? (dpx != u.ux || dpy != u.uy)
191.  			   : (distu(dpx,dpy) > 2))))
192.  		return(0);
193.  
194.  	if (digging.down) {
195.  	    if(!dig_check(BY_YOU, TRUE, u.ux, u.uy)) return(0);
196.  	} else { /* !digging.down */
197.  	    if (IS_ROCK(lev->typ) && !may_dig(dpx,dpy) && !dig_typ(dpx, dpy)) {
198.  		pline("This wall is too hard to dig into.");
199.  		return(0);
200.  	    }
201.  	}
202.  	if(Fumbling && !rn2(3)) {
203.  		switch(rn2(3)) {
204.  		case 0:  if(!welded(uwep)) {
205.  			     You("fumble and drop your %s.", xname(uwep));
206.  			     dropx(uwep);
207.  			     setuwep((struct obj *)0);
208.  			 } else {
209.  			     pline("Ouch!  Your %s bounces and hits you!",
210.  				xname(uwep));
211.  			     set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
212.  			 }
213.  			 break;
214.  		case 1:  pline("Bang!  You hit with the broad side of %s!",
215.  			       the(xname(uwep)));
216.  			 break;
217.  		default: Your("swing misses its mark.");
218.  			 break;
219.  		}
220.  		return(0);
221.  	}
222.  
223.  	digging.effort += 10 + rn2(5) + abon() +
224.  			   uwep->spe - uwep->oeroded + u.udaminc;
225.  	if (digging.down) {
226.  		register struct trap *ttmp;
227.  
228.  		if (digging.effort > 250) {
229.  		    (void) dighole(FALSE);
230.  		    (void) memset((genericptr_t)&digging, 0, sizeof digging);
231.  		    return(0);	/* done with digging */
232.  		}
233.  
234.  		if (digging.effort <= 50 ||
235.  		    ((ttmp = t_at(dpx,dpy)) != 0 &&
236.  			(ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT ||
237.  			 ttmp->ttyp == TRAPDOOR || ttmp->ttyp == HOLE)))
238.  		    return(1);
239.  
240.  		if (IS_ALTAR(lev->typ)) {
241.  		    altar_wrath(dpx, dpy);
242.  		    angry_priest();
243.  		}
244.  
245.  		if (dighole(TRUE)) {	/* make pit at <u.ux,u.uy> */
246.  		    digging.level.dnum = 0;
247.  		    digging.level.dlevel = -1;
248.  		}
249.  		return(0);
250.  	}
251.  
252.  	if (digging.effort > 100) {
253.  		register const char *digtxt, *dmgtxt = (const char*) 0;
254.  		register struct obj *obj;
255.  		register boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE);
256.  
257.  		if ((obj = sobj_at(STATUE, dpx, dpy)) != 0) {
258.  			if (break_statue(obj))
259.  				digtxt = "The statue shatters.";
260.  			else
261.  				/* it was a statue trap; break_statue()
262.  				 * printed a message and updated the screen
263.  				 */
264.  				digtxt = (char *)0;
265.  		} else if ((obj = sobj_at(BOULDER, dpx, dpy)) != 0) {
266.  			fracture_rock(obj);
267.  			digtxt = "The boulder falls apart.";
268.  		} else if (lev->typ == STONE || lev->typ == SCORR) {
269.  			if(Is_earthlevel(&u.uz)) {
270.  			    if(uwep->blessed && !rn2(3)) {
271.  				mkcavearea(FALSE);
272.  				goto cleanup;
273.  			    } else if((uwep->cursed && !rn2(4)) ||
274.  					  (!uwep->blessed && !rn2(6))) {
275.  				mkcavearea(TRUE);
276.  				goto cleanup;
277.  			    }
278.  			}
279.  			lev->typ = CORR;
280.  			digtxt = "You succeed in cutting away some rock.";
281.  		} else if(IS_WALL(lev->typ)) {
282.  			if(shopedge) {
283.  			    add_damage(dpx, dpy, 10L * ACURRSTR);
284.  			    dmgtxt = "damage";
285.  			}
286.  			if (level.flags.is_maze_lev) {
287.  			    lev->typ = ROOM;
288.  			} else if (level.flags.is_cavernous_lev) {
289.  			    lev->typ = CORR;
290.  			} else {
291.  			    lev->typ = DOOR;
292.  			    lev->doormask = D_NODOOR;
293.  			}
294.  			digtxt = "You make an opening in the wall.";
295.  		} else if(lev->typ == SDOOR) {
296.  			lev->typ = DOOR;
297.  			lev->doormask = exposed_sdoor_mask(lev);
298.  			digtxt = "You break through a secret door!";
299.  			if(!(lev->doormask & D_TRAPPED))
300.  				lev->doormask = D_BROKEN;
301.  		} else if(closed_door(dpx, dpy)) {
302.  			digtxt = "You break through the door.";
303.  			if(shopedge) {
304.  			    add_damage(dpx, dpy, 400L);
305.  			    dmgtxt = "break";
306.  			}
307.  			if(!(lev->doormask & D_TRAPPED))
308.  				lev->doormask = D_BROKEN;
309.  		} else return(0); /* statue or boulder got taken */
310.  
311.  		unblock_point(dpx,dpy);	/* vision:  can see through */
312.  		if(Blind)
313.  		    feel_location(dpx, dpy);
314.  		else
315.  		    newsym(dpx, dpy);
316.  		if(digtxt) pline(digtxt);	/* after newsym */
317.  		if(dmgtxt)
318.  		    pay_for_damage(dmgtxt);
319.  
320.  		if(Is_earthlevel(&u.uz) && !rn2(3)) {
321.  		    register struct monst *mtmp;
322.  
323.  		    switch(rn2(2)) {
324.  		      case 0:
325.  			mtmp = makemon(&mons[PM_EARTH_ELEMENTAL], dpx, dpy);
326.  			break;
327.  		      default:
328.  			mtmp = makemon(&mons[PM_XORN], dpx, dpy);
329.  			break;
330.  		    }
331.  		    if(mtmp) pline_The("debris from your digging comes to life!");
332.  		}
333.  		if(IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) {
334.  			lev->doormask = D_NODOOR;
335.  			b_trapped("door", 0);
336.  			newsym(dpx, dpy);
337.  		}
338.  cleanup:
339.  		digging.level.dnum = 0;
340.  		digging.level.dlevel = -1;
341.  		return(0);
342.  	} else {		/* not enough effort has been spent yet */
343.  		static const char *d_target[4] = {
344.  					"rock", "statue", "boulder", "door"
345.  		};
346.  		int dig_target = dig_typ(dpx, dpy);
347.  
348.  		if (IS_WALL(lev->typ) || dig_target == 3) {
349.  		    if(*in_rooms(dpx, dpy, SHOPBASE)) {
350.  			pline("This %s seems too hard to dig into.",
351.  			      IS_DOOR(lev->typ) ? "door" : "wall");
352.  			return(0);
353.  		    }
354.  		} else if (!IS_ROCK(lev->typ) && !dig_target)
355.  			return(0); /* statue or boulder got taken */
356.  		if(!did_dig_msg) {
357.  		    You("hit the %s with all your might.",
358.  			d_target[dig_target]);
359.  		    did_dig_msg = TRUE;
360.  		}
361.  	}
362.  	return(1);
363.  }
364.  
365.  /* When will hole be finished? Very rough indication used by shopkeeper. */
366.  int
367.  holetime()
368.  {
369.  	if(occupation != dig || !*u.ushops) return(-1);
370.  	return ((250 - digging.effort) / 20);
371.  }
372.  
373.  /* Return typ of liquid to fill a hole with, or ROOM, if no liquid nearby */
374.  STATIC_OVL
375.  schar
376.  fillholetyp(x,y)
377.  int x, y;
378.  {
379.      register int x1, y1;
380.      int lo_x = max(1,x-1), hi_x = min(x+1,COLNO-1),
381.  	lo_y = max(0,y-1), hi_y = min(y+1,ROWNO-1);
382.      int pool_cnt = 0, moat_cnt = 0, lava_cnt = 0;
383.  
384.      for (x1 = lo_x; x1 <= hi_x; x1++)
385.  	for (y1 = lo_y; y1 <= hi_y; y1++)
386.  	    if (levl[x1][y1].typ == POOL)
387.  		pool_cnt++;
388.  	    else if (levl[x1][y1].typ == MOAT ||
389.  		    (levl[x1][y1].typ == DRAWBRIDGE_UP &&
390.  			(levl[x1][y1].drawbridgemask & DB_UNDER) == DB_MOAT))
391.  		moat_cnt++;
392.  	    else if (levl[x1][y1].typ == LAVAPOOL ||
393.  		    (levl[x1][y1].typ == DRAWBRIDGE_UP &&
394.  			(levl[x1][y1].drawbridgemask & DB_UNDER) == DB_LAVA))
395.  		lava_cnt++;
396.      pool_cnt /= 3;		/* not as much liquid as the others */
397.  
398.      if (lava_cnt > moat_cnt + pool_cnt && rn2(lava_cnt + 1))
399.  	return LAVAPOOL;
400.      else if (moat_cnt > 0 && rn2(moat_cnt + 1))
401.  	return MOAT;
402.      else if (pool_cnt > 0 && rn2(pool_cnt + 1))
403.  	return POOL;
404.      else
405.  	return ROOM;
406.  }
407.  
408.  void
409.  digactualhole(x, y, madeby, ttyp)
410.  register int	x, y;
411.  struct monst	*madeby;
412.  int ttyp;
413.  {
414.  	struct obj *oldobjs, *newobjs;
415.  	register struct trap *ttmp;
416.  	char surface_type[BUFSZ];
417.  	struct rm *lev = &levl[x][y];
418.  	boolean shopdoor;
419.  	struct monst *mtmp = m_at(x, y);	/* may be madeby */
420.  	boolean madeby_u = (madeby == BY_YOU);
421.  	boolean madeby_obj = (madeby == BY_OBJECT);
422.  	boolean at_u = (x == u.ux) && (y == u.uy);
423.  	boolean wont_fall = Levitation || is_flyer(uasmon);
424.  
425.  	/* these furniture checks were in dighole(), but wand
426.  	   breaking bypasses that routine and calls us directly */
427.  	if (IS_FOUNTAIN(lev->typ)) {
428.  	    dogushforth(FALSE);
429.  	    lev->looted |= F_WARNED;		/* force dryup */
430.  	    dryup(x, y);
431.  	    return;
432.  #ifdef SINKS
433.  	} else if (IS_SINK(lev->typ)) {
434.  	    breaksink(x, y);
435.  	    return;
436.  #endif
437.  	}
438.  
439.  	Strcpy(surface_type, surface(x,y));	/* maketrap() might change it */
440.  	shopdoor = IS_DOOR(lev->typ) && *in_rooms(x, y, SHOPBASE);
441.  	oldobjs = level.objects[x][y];
442.  	ttmp = maketrap(x, y, ttyp);
443.  	if (!ttmp) return;
444.  	newobjs = level.objects[x][y];
445.  	ttmp->tseen = (madeby_u || cansee(x,y));
446.  	ttmp->madeby_u = madeby_u;
447.  	newsym(ttmp->tx,ttmp->ty);
448.  
449.  	if (ttyp == PIT) {
450.  
451.  	    if(madeby_u) {
452.  		You("dig a pit in the %s.", surface_type);
453.  		if (shopdoor) pay_for_damage("ruin");
454.  	    } else if (!madeby_obj && canseemon(madeby))
455.  		pline("%s digs a pit in the %s.", Monnam(madeby), surface_type);
456.  	    else if (cansee(x, y) && flags.verbose)
457.  		pline("A pit appears in the %s.", surface_type);
458.  
459.  	    if(at_u) {
460.  		if (!wont_fall) {
461.  			u.utrap = rn1(4,2);
462.  			u.utraptype = TT_PIT;
463.  			vision_full_recalc = 1;	/* vision limits change */
464.  		} else
465.  			u.utrap = 0;
466.  		if (oldobjs != newobjs)	/* something unearthed */
467.  			pickup(1);	/* detects pit */
468.  	    } else if(mtmp) {
469.  		if(is_flyer(mtmp->data) || is_floater(mtmp->data)) {
470.  		    if(canseemon(mtmp))
471.  			pline("%s %s over the pit.", Monnam(mtmp),
472.  						     (is_flyer(mtmp->data)) ?
473.  						     "flies" : "floats");
474.  		} else if(mtmp != madeby)
475.  		    (void) mintrap(mtmp);
476.  	    }
477.  	} else {	/* was TRAPDOOR now a HOLE*/
478.  	    if (!Can_fall_thru(&u.uz))
479.  		panic("Holes & trapdoors cannot exist on this level.");
480.  
481.  	    if(madeby_u)
482.  		You("dig a hole through the %s.", surface_type);
483.  	    else if(!madeby_obj && canseemon(madeby))
484.  		pline("%s digs a hole through the %s.",
485.  		      Monnam(madeby), surface_type);
486.  	    else if(cansee(x, y) && flags.verbose)
487.  		pline("A hole appears in the %s.", surface_type);
488.  
489.  	    if (at_u) {
490.  		if (!u.ustuck && !wont_fall && !next_to_u()) {
491.  		    You("are jerked back by your pet!");
492.  		    wont_fall = TRUE;
493.  		}
494.  
495.  		/* Floor objects get a chance of falling down.  The case where
496.  		 * the hero does NOT fall down is treated here.  The case
497.  		 * where the hero does fall down is treated in goto_level().
498.  		 */
499.  		if (u.ustuck || wont_fall) {
500.  		    if (newobjs)
501.  			impact_drop((struct obj *)0, x, y, 0);
502.  		    if (oldobjs != newobjs)
503.  			pickup(1);
504.  		    if (shopdoor && madeby_u) pay_for_damage("ruin");
505.  
506.  		} else {
507.  		    d_level newlevel;
508.  
509.  		    if (*u.ushops && madeby_u)
510.  			shopdig(1); /* shk might snatch pack */
511.  
512.  		    You("fall through...");
513.  		    /* Earlier checks must ensure that the destination
514.  		     * level exists and is in the present dungeon.
515.  		     */
516.  		    newlevel.dnum = u.uz.dnum;
517.  		    newlevel.dlevel = u.uz.dlevel + 1;
518.  		    goto_level(&newlevel, FALSE, TRUE, FALSE);
519.  		}
520.  	    } else {
521.  		if (shopdoor && madeby_u) pay_for_damage("ruin");
522.  		if (newobjs)
523.  		    impact_drop((struct obj *)0, x, y, 0);
524.  		if (mtmp) {
525.  
526.  		    if (is_flyer(mtmp->data) || is_floater(mtmp->data) ||
527.  		        mtmp->data == &mons[PM_WUMPUS] ||
528.  			(mtmp->wormno && count_wsegs(mtmp) > 5) ||
529.  			mtmp->data->msize >= MZ_HUGE) return;
530.  		    if (mtmp == u.ustuck)	/* probably a vortex */
531.  			    return;		/* temporary? kludge */
532.  
533.  		    if (teleport_pet(mtmp)) {
534.  			d_level tolevel;
535.  
536.  			if (Is_stronghold(&u.uz)) {
537.  			    assign_level(&tolevel, &valley_level);
538.  			} else if (Is_botlevel(&u.uz)) {
539.  			    if (canseemon(mtmp))
540.  				pline("%s avoids the trap.", Monnam(mtmp));
541.  			    return;
542.  			} else {
543.  			    get_level(&tolevel, depth(&u.uz) + 1);
544.  			}
545.  			migrate_to_level(mtmp, ledger_no(&tolevel),
546.  					 MIGR_RANDOM, (coord *)0);
547.  		    }
548.  		}
549.  	    }
550.  	}
551.  }
552.  
553.  /* return TRUE if digging succeeded, FALSE otherwise */
554.  boolean
555.  dighole(pit_only)
556.  boolean pit_only;
557.  {
558.  	register struct trap *ttmp = t_at(u.ux, u.uy);
559.  	struct rm *lev = &levl[u.ux][u.uy];
560.  	struct obj *boulder_here;
561.  	schar typ;
562.  	boolean nohole = !Can_dig_down(&u.uz);
563.  
564.  	if ((ttmp && (ttmp->ttyp == MAGIC_PORTAL || nohole)) ||
565.  	   (IS_WALL(lev->typ) && (lev->wall_info & W_NONDIGGABLE) != 0)) {
566.  		pline_The("%s here is too hard to dig in.", surface(u.ux,u.uy));
567.  
568.  	} else if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) {
569.  		pline_The("%s sloshes furiously for a moment, then subsides.",
570.  			is_lava(u.ux, u.uy) ? "lava" : "water");
571.  		wake_nearby();	/* splashing */
572.  
573.  	} else if (lev->typ == DRAWBRIDGE_DOWN ||
574.  		   (is_drawbridge_wall(u.ux, u.uy) >= 0)) {
575.  		/* drawbridge_down is the platform crossing the moat when the
576.  		   bridge is extended; drawbridge_wall is the open "doorway" or
577.  		   closed "door" where the portcullis/mechanism is located */
578.  		if (pit_only) {
579.  		    pline_The("drawbridge seems too hard to dig through.");
580.  		    return FALSE;
581.  		} else {
582.  		    int x = u.ux, y = u.uy;
583.  		    /* if under the portcullis, the bridge is adjacent */
584.  		    (void) find_drawbridge(&x, &y);
585.  		    destroy_drawbridge(x, y);
586.  		    return TRUE;
587.  		}
588.  
589.  	} else if ((boulder_here = sobj_at(BOULDER, u.ux, u.uy)) != 0) {
590.  		if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT) &&
591.  		    rn2(2)) {
592.  			pline_The("boulder settles into the pit.");
593.  			ttmp->ttyp = PIT;	 /* crush spikes */
594.  		} else {
595.  			/*
596.  			 * digging makes a hole, but the boulder immediately
597.  			 * fills it.  Final outcome:  no hole, no boulder.
598.  			 */
599.  			pline("KADOOM! The boulder falls in!");
600.  			(void) delfloortrap(ttmp);
601.  		}
602.  		delobj(boulder_here);
603.  		return TRUE;
604.  
605.  	} else if (lev->typ == DRAWBRIDGE_UP) {
606.  		/* must be floor or ice, other cases handled above */
607.  		/* dig "pit" and let fluid flow in (if possible) */
608.  		typ = fillholetyp(u.ux,u.uy);
609.  
610.  		if (typ == ROOM) {
611.  			/*
612.  			 * We can't dig a hole here since that will destroy
613.  			 * the drawbridge.  The following is a cop-out. --dlc
614.  			 */
615.  			pline_The("%s here is too hard to dig in.",
616.  			      surface(u.ux, u.uy));
617.  			return FALSE;
618.  		}
619.  
620.  		lev->drawbridgemask &= ~DB_UNDER;
621.  		lev->drawbridgemask |= (typ == LAVAPOOL) ? DB_LAVA : DB_MOAT;
622.  
623.   liquid_flow:
624.  		if (ttmp) (void) delfloortrap(ttmp);
625.  		/* if any objects were frozen here, they're released now */
626.  		unearth_objs(u.ux, u.uy);
627.  
628.  		pline("As you dig, the hole fills with %s!",
629.  		      typ == LAVAPOOL ? "lava" : "water");
630.  		if (!Levitation && !is_flyer(uasmon)) {
631.  		    if (typ == LAVAPOOL)
632.  			(void) lava_effects();
633.  		    else if (!Wwalking)
634.  			(void) drown();
635.  		}
636.  		return TRUE;
637.  
638.  	/* the following two are here for the wand of digging */
639.  	} else if (IS_THRONE(lev->typ)) {
640.  		pline_The("throne is too hard to break apart.");
641.  
642.  	} else if (IS_ALTAR(lev->typ)) {
643.  		pline_The("altar is too hard to break apart.");
644.  
645.  	} else {
646.  		typ = fillholetyp(u.ux,u.uy);
647.  
648.  		if (typ != ROOM) {
649.  			lev->typ = typ;
650.  			goto liquid_flow;
651.  		}
652.  
653.  		/* finally we get to make a hole */
654.  		if (nohole || pit_only)
655.  			digactualhole(u.ux, u.uy, BY_YOU, PIT);
656.  		else
657.  			digactualhole(u.ux, u.uy, BY_YOU, HOLE);
658.  
659.  		return TRUE;
660.  	}
661.  
662.  	return FALSE;
663.  }
664.  
665.  int
666.  use_pick_axe(obj)
667.  struct obj *obj;
668.  {
669.  	char dirsyms[12];
670.  	char qbuf[QBUFSZ];
671.  	register char *dsp = dirsyms;
672.  	register struct rm *lev;
673.  	register int rx, ry;
674.  	int dig_target, res = 0;
675.  	register const char *sdp;
676.  	if(flags.num_pad) sdp = ndir; else sdp = sdir;	/* DICE workaround */
677.  
678.  	if (obj != uwep) {
679.  	    if (!wield_tool(obj)) return(0);
680.  	    else res = 1;
681.  	}
682.  	if (u.utrap && u.utraptype == TT_WEB) {
683.  	    pline("%s you can't dig while entangled in a web.",
684.  		  /* res==0 => no prior message;
685.  		     res==1 => just got "You now wield a pick-axe." message */
686.  		  !res ? "Unfortunately," : "But");
687.  	    return res;
688.  	}
689.  
690.  	while(*sdp) {
691.  		(void) movecmd(*sdp);	/* sets u.dx and u.dy and u.dz */
692.  		rx = u.ux + u.dx;
693.  		ry = u.uy + u.dy;
694.  		if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) &&
695.  		    (IS_ROCK(levl[rx][ry].typ) || dig_typ(rx, ry))))
696.  			*dsp++ = *sdp;
697.  		sdp++;
698.  	}
699.  	*dsp = 0;
700.  	Sprintf(qbuf, "In what direction do you want to dig? [%s]", dirsyms);
701.  	if(!getdir(qbuf))
702.  		return(res);
703.  	if (u.uswallow && attack(u.ustuck)) {
704.  		;  /* return(1) */
705.  	} else if (Underwater) {
706.  		pline("Turbulence torpedoes your digging attempts.");
707.  	} else if(u.dz < 0) {
708.  		if(Levitation)
709.  			You("don't have enough leverage.");
710.  		else
711.  			You_cant("reach the %s.",ceiling(u.ux,u.uy));
712.  	} else if(!u.dx && !u.dy && !u.dz) {
713.  		char buf[BUFSZ];
714.  		int dam;
715.  
716.  		dam = rnd(2) + dbon() + obj->spe;
717.  		if (dam <= 0) dam = 1;
718.  		You("hit yourself with your pick-axe.");
719.  		/* self_pronoun() won't work twice in a sentence */
720.  		Strcpy(buf, self_pronoun("killed %sself with %%s pick-axe",
721.  			"him"));
722.  		losehp(dam, self_pronoun(buf, "his"), NO_KILLER_PREFIX);
723.  		flags.botl=1;
724.  		return(1);
725.  	} else if(u.dz == 0) {
726.  		if(Stunned || (Confusion && !rn2(5))) confdir();
727.  		rx = u.ux + u.dx;
728.  		ry = u.uy + u.dy;
729.  		if(!isok(rx, ry)) {
730.  			pline("Clash!");
731.  			return(1);
732.  		}
733.  		lev = &levl[rx][ry];
734.  		if(MON_AT(rx, ry) && attack(m_at(rx, ry)))
735.  			return(1);
736.  		dig_target = dig_typ(rx, ry);
737.  		if (!IS_ROCK(lev->typ) && !dig_target) {
738.  			/* ACCESSIBLE or POOL */
739.  			struct trap *trap = t_at(rx, ry);
740.  
741.  			if (trap && trap->ttyp == WEB) {
742.  			    if (!trap->tseen) {
743.  				seetrap(trap);
744.  				pline("There is a spider web there!");
745.  			    }
746.  			    Your("%s becomes entangled in the web.",
747.  				aobjnam(obj, (char *)0));
748.  			    /* you ought to be able to let go; tough luck */
749.  			    /* (maybe `move_into_trap()' would be better) */
750.  			    nomul(-d(2,2));
751.  			    nomovemsg = "You pull free.";
752.  			} else
753.  			    You("swing your %s through thin air.",
754.  				aobjnam(obj, (char *)0));
755.  		} else {
756.  			static const char *d_action[4] = {
757.  						"digging",
758.  						"chipping the statue",
759.  						"hitting the boulder",
760.  						"chopping at the door"
761.  			};
762.  			if (digging.pos.x != rx || digging.pos.y != ry ||
763.  			    !on_level(&digging.level, &u.uz) || digging.down) {
764.  			    digging.down = digging.chew = FALSE;
765.  			    digging.pos.x = rx;
766.  			    digging.pos.y = ry;
767.  			    assign_level(&digging.level, &u.uz);
768.  			    digging.effort = 0;
769.  			    You("start %s.", d_action[dig_target]);
770.  			} else {
771.  			    You("%s %s.", digging.chew ? "begin" : "continue",
772.  					d_action[dig_target]);
773.  			    digging.chew = FALSE;
774.  			}
775.  			did_dig_msg = FALSE;
776.  			set_occupation(dig, "digging", 0);
777.  		}
778.  	} else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
779.  		/* it must be air -- water checked above */
780.  		You("swing your %s through thin air.", aobjnam(obj, (char *)0));
781.  	} else if (!can_reach_floor()) {
782.  		You_cant("reach the %s.", surface(u.ux,u.uy));
783.  	} else if (is_pool(u.ux, u.uy)) {
784.  		/* Monsters which swim also happen not to be able to dig */
785.  		You("cannot stay underwater long enough.");
786.  	} else {
787.  		if (digging.pos.x != u.ux || digging.pos.y != u.uy ||
788.  			!on_level(&digging.level, &u.uz) || !digging.down) {
789.  		    digging.chew = FALSE;
790.  		    digging.down = TRUE;
791.  		    digging.pos.x = u.ux;
792.  		    digging.pos.y = u.uy;
793.  		    assign_level(&digging.level, &u.uz);
794.  		    digging.effort = 0;
795.  		    You("start digging downward.");
796.  		    if (*u.ushops) shopdig(0);
797.  		} else
798.  		    You("continue digging downward.");
799.  		did_dig_msg = FALSE;
800.  		set_occupation(dig, "digging", 0);
801.  	}
802.  	return(1);
803.  }
804.  
805.  #endif /* OVLB */
806.  #ifdef OVL0
807.  
808.  /* Return TRUE if monster died, FALSE otherwise.  Called from m_move(). */
809.  boolean
810.  mdig_tunnel(mtmp)
811.  register struct monst *mtmp;
812.  {
813.  	register struct rm *here;
814.  	int pile;
815.  
816.  	here = &levl[mtmp->mx][mtmp->my];
817.  	if (here->typ == SDOOR) {
818.  	    here->typ = DOOR;
819.  	    here->doormask = exposed_sdoor_mask(here);
820.  	}
821.  
822.  	/* Eats away door if present & closed or locked */
823.  	if (closed_door(mtmp->mx, mtmp->my)) {
824.  	    if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
825.  		add_damage(mtmp->mx, mtmp->my, 0L);
826.  	    unblock_point(mtmp->mx, mtmp->my);	/* vision */
827.  	    if (here->doormask & D_TRAPPED) {
828.  		here->doormask = D_NODOOR;
829.  		if (mb_trapped(mtmp)) {	/* mtmp is killed */
830.  		    newsym(mtmp->mx, mtmp->my);
831.  		    return TRUE;
832.  		}
833.  	    } else {
834.  		if (!rn2(3) && flags.verbose)	/* not too often.. */
835.  		    You_feel("an unexpected draft.");
836.  		here->doormask = D_BROKEN;
837.  	    }
838.  	    newsym(mtmp->mx, mtmp->my);
839.  	    return FALSE;
840.  	} else
841.  	if (!IS_ROCK(here->typ)) /* no dig */
842.  	    return FALSE;
843.  
844.  	/* Only rock and walls fall through to this point. */
845.  	if ((here->wall_info & W_NONDIGGABLE) != 0) {
846.  	    impossible("mdig_tunnel:  %s at (%d,%d) is undiggable",
847.  		       (IS_WALL(here->typ) ? "wall" : "stone"),
848.  		       (int) mtmp->mx, (int) mtmp->my);
849.  	    return FALSE;	/* still alive */
850.  	}
851.  
852.  	if (IS_WALL(here->typ)) {
853.  	    if (flags.soundok && flags.verbose && !rn2(5))
854.  		You_hear("crashing rock.");
855.  	    if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
856.  		add_damage(mtmp->mx, mtmp->my, 0L);
857.  	    if (level.flags.is_maze_lev) {
858.  		here->typ = ROOM;
859.  	    } else if (level.flags.is_cavernous_lev) {
860.  		here->typ = CORR;
861.  	    } else {
862.  		here->typ = DOOR;
863.  		here->doormask = D_NODOOR;
864.  	    }
865.  	} else
866.  	    here->typ = CORR;
867.  
868.  	pile = rnd(12);
869.  	if (pile < 5)	/* leave behind some rocks? */
870.  	    (void) mksobj_at((pile == 1) ? BOULDER : ROCK,
871.  			     mtmp->mx, mtmp->my, TRUE);
872.  	newsym(mtmp->mx, mtmp->my);
873.  	if (!sobj_at(BOULDER, mtmp->mx, mtmp->my))
874.  	    unblock_point(mtmp->mx, mtmp->my);	/* vision */
875.  
876.  	return FALSE;
877.  }
878.  
879.  #endif /* OVL0 */
880.  #ifdef OVL3
881.  
882.  /* digging via wand zap or spell cast */
883.  void
884.  zap_dig()
885.  {
886.  	struct rm *room;
887.  	struct monst *mtmp;
888.  	struct obj *otmp;
889.  	int zx, zy, digdepth;
890.  	boolean shopdoor, shopwall, maze_dig;
891.  	/*
892.  	 * Original effect (approximately):
893.  	 * from CORR: dig until we pierce a wall
894.  	 * from ROOM: pierce wall and dig until we reach
895.  	 * an ACCESSIBLE place.
896.  	 * Currently: dig for digdepth positions;
897.  	 * also down on request of Lennart Augustsson.
898.  	 */
899.  
900.  	if (u.uswallow) {
901.  	    mtmp = u.ustuck;
902.  
903.  	    if (!is_whirly(mtmp->data)) {
904.  		if (is_animal(mtmp->data))
905.  		    You("pierce %s stomach wall!", s_suffix(mon_nam(mtmp)));
906.  		mtmp->mhp = 1;		/* almost dead */
907.  		expels(mtmp, mtmp->data, !is_animal(mtmp->data));
908.  	    }
909.  	    return;
910.  	} /* swallowed */
911.  
912.  	if (u.dz) {
913.  	    if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) {
914.  		if (u.dz < 0 || On_stairs(u.ux, u.uy)) {
915.  		    if (On_stairs(u.ux, u.uy))
916.  			pline_The("beam bounces off the %s and hits the %s.",
917.  			      (u.ux == xdnladder || u.ux == xupladder) ?
918.  			      "ladder" : "stairs", ceiling(u.ux, u.uy));
919.  		    You("loosen a rock from the %s.", ceiling(u.ux, u.uy));
920.  		    pline("It falls on your %s!", body_part(HEAD));
921.  		    losehp(1, "falling rock", KILLED_BY_AN);
922.  		    if ((otmp = mksobj_at(ROCK, u.ux, u.uy, FALSE)) != 0) {
923.  		(void)xname(otmp);	/* set dknown, maybe bknown */
924.  		stackobj(otmp);
925.  		    }
926.  		    if (Invisible) newsym(u.ux, u.uy);
927.  		} else {
928.  		    (void) dighole(FALSE);
929.  		}
930.  	    }
931.  	    return;
932.  	} /* up or down */
933.  
934.  	/* normal case: digging across the level */
935.  	shopdoor = shopwall = FALSE;
936.  	maze_dig = level.flags.is_maze_lev && !Is_earthlevel(&u.uz);
937.  	zx = u.ux + u.dx;
938.  	zy = u.uy + u.dy;
939.  	digdepth = rn1(18, 8);
940.  	tmp_at(DISP_BEAM, cmap_to_glyph(S_digbeam));
941.  	while (--digdepth >= 0) {
942.  	    if (!isok(zx,zy)) break;
943.  	    room = &levl[zx][zy];
944.  	    tmp_at(zx,zy);
945.  	    delay_output();	/* wait a little bit */
946.  	    if (closed_door(zx, zy) || room->typ == SDOOR) {
947.  		if (*in_rooms(zx,zy,SHOPBASE)) {
948.  		    add_damage(zx, zy, 400L);
949.  		    shopdoor = TRUE;
950.  		}
951.  		if (room->typ == SDOOR)
952.  		    room->typ = DOOR;
953.  		else if (cansee(zx, zy))
954.  		    pline_The("door is razed!");
955.  		room->doormask = D_NODOOR;
956.  		unblock_point(zx,zy); /* vision */
957.  		digdepth -= 2;
958.  		if (maze_dig) break;
959.  	    } else if (maze_dig) {
960.  		if (IS_WALL(room->typ)) {
961.  		    if (!(room->wall_info & W_NONDIGGABLE)) {
962.  			if (*in_rooms(zx,zy,SHOPBASE)) {
963.  			    add_damage(zx, zy, 200L);
964.  			    shopwall = TRUE;
965.  			}
966.  			room->typ = ROOM;
967.  			unblock_point(zx,zy); /* vision */
968.  		    } else if (!Blind)
969.  			pline_The("wall glows then fades.");
970.  		    break;
971.  		} else if (room->typ == STONE || room->typ == SCORR) {
972.  		    if (!(room->wall_info & W_NONDIGGABLE)) {
973.  			room->typ = CORR;
974.  			unblock_point(zx,zy); /* vision */
975.  		    } else if (!Blind)
976.  			pline_The("rock glows then fades.");
977.  		    break;
978.  		}
979.  	    } else if (IS_ROCK(room->typ)) {
980.  		if (!may_dig(zx,zy)) break;
981.  		if (IS_WALL(room->typ) || room->typ == SDOOR) {
982.  		    if (*in_rooms(zx,zy,SHOPBASE)) {
983.  			add_damage(zx, zy, 200L);
984.  			shopwall = TRUE;
985.  		    }
986.  		    if (level.flags.is_cavernous_lev) {
987.  			room->typ = CORR;
988.  		    } else {
989.  			room->typ = DOOR;
990.  			room->doormask = D_NODOOR;
991.  		    }
992.  		    digdepth -= 2;
993.  		} else {	/* IS_ROCK but not IS_WALL or SDOOR */
994.  		    room->typ = CORR;
995.  		    digdepth--;
996.  		}
997.  		unblock_point(zx,zy); /* vision */
998.  	    }
999.  	    zx += u.dx;
1000. 	    zy += u.dy;
1001. 	} /* while */
1002. 	tmp_at(DISP_END,0);	/* closing call */
1003. 	if (shopdoor || shopwall)
1004. 	    pay_for_damage(shopdoor ? "destroy" : "dig into");
1005. 	return;
1006. }
1007. 
1008. /* move objects from fobj/nexthere lists to buriedobjlist, keeping position */
1009. /* information */
1010. struct obj *
1011. bury_an_obj(otmp)
1012. 	struct obj *otmp;
1013. {
1014. 	struct obj *otmp2;
1015. 	boolean under_ice;
1016. 
1017. #ifdef DEBUG
1018. 	pline("bury_an_obj: %s", xname(otmp));
1019. #endif
1020. 	if (otmp == uball)
1021. 		unpunish();
1022. 	/* after unpunish(), or might get deallocated chain */
1023. 	otmp2 = otmp->nexthere;
1024. 	/*
1025. 	 * obj_resists(,0,0) prevents Rider corpses from being buried.
1026. 	 * It also prevents The Amulet and invocation tools from being
1027. 	 * buried.  Since they can't be confined to bags and statues,
1028. 	 * it makes sense that they can't be buried either, even though
1029. 	 * the real reason there (direct accessibility when carried) is
1030. 	 * completely different.
1031. 	 */
1032. 	if (otmp == uchain || obj_resists(otmp, 0, 0))
1033. 		return(otmp2);
1034. 
1035. 	if (otmp->otyp == LEASH && otmp->leashmon != 0)
1036. 		o_unleash(otmp);
1037. 
1038. 	if (otmp->lamplit && otmp->otyp != POT_OIL)
1039. 		end_burn(otmp, TRUE);
1040. 
1041. 	obj_extract_self(otmp);
1042. 
1043. 	under_ice = is_ice(otmp->ox, otmp->oy);
1044. 	if (otmp->otyp == ROCK && !under_ice) {
1045. 		/* merges into burying material */
1046. 		obfree(otmp, (struct obj *)0);
1047. 		return(otmp2);
1048. 	}
1049. 	/*
1050. 	 * Start a rot on organic material.  Not corpses -- they
1051. 	 * are already handled.
1052. 	 */
1053. 	if (otmp->otyp == CORPSE) {
1054. 	    ;		/* should cancel timer if under_ice */
1055. 	} else if ((under_ice ? otmp->oclass == POTION_CLASS : is_organic(otmp))
1056. 		&& !obj_resists(otmp, 5, 95)) {
1057. 	    (void) start_timer((under_ice ? 0L : 250L) + (long)rnd(250),
1058. 			       TIMER_OBJECT, ROT_ORGANIC, (genericptr_t)otmp);
1059. 	}
1060. 	add_to_buried(otmp);
1061. 	return(otmp2);
1062. }
1063. 
1064. void
1065. bury_objs(x, y)
1066. int x, y;
1067. {
1068. 	struct obj *otmp, *otmp2;
1069. 
1070. #ifdef DEBUG
1071. 	if(level.objects[x][y] != (struct obj *)0)
1072. 		pline("bury_objs: at %d, %d", x, y);
1073. #endif
1074. 	for (otmp = level.objects[x][y]; otmp; otmp = otmp2)
1075. 		otmp2 = bury_an_obj(otmp);
1076. 
1077. 	/* don't expect any engravings here, but just in case */
1078. 	del_engr_at(x, y);
1079. 	newsym(x, y);
1080. }
1081. 
1082. /* move objects from buriedobjlist to fobj/nexthere lists */
1083. void
1084. unearth_objs(x, y)
1085. int x, y;
1086. {
1087. 	struct obj *otmp, *otmp2;
1088. 
1089. #ifdef DEBUG
1090. 	pline("unearth_objs: at %d, %d", x, y);
1091. #endif
1092. 	for (otmp = level.buriedobjlist; otmp; otmp = otmp2) {
1093. 		otmp2 = otmp->nobj;
1094. 		if (otmp->ox == x && otmp->oy == y) {
1095. 		    obj_extract_self(otmp);
1096. 		    if (otmp->timed)
1097. 			(void) stop_timer(ROT_ORGANIC, (genericptr_t)otmp);
1098. 		    place_object(otmp, x, y);
1099. 		    stackobj(otmp);
1100. 		}
1101. 	}
1102. 	del_engr_at(x, y);
1103. 	newsym(x, y);
1104. }
1105. 
1106. /*
1107.  * The organic material has rotted away while buried.  As an expansion,
1108.  * we could add add partial damage.  A damage count is kept in the object
1109.  * and every time we are called we increment the count and reschedule another
1110.  * timeout.  Eventually the object rots away.
1111.  *
1112.  * This is used by buried objects.  This has a different entry in the
1113.  * table than rot_corpse() because the rot stops when unearthed.
1114.  */
1115. /* ARGSUSED */
1116. void
1117. rot_organic(arg, timeout)
1118. genericptr_t arg;
1119. long timeout;	/* unused */
1120. {
1121. 	struct obj *obj = (struct obj *) arg;
1122. 
1123. 	obj_extract_self(obj);
1124. 	obfree(obj, (struct obj *) 0);
1125. }
1126. 
1127. /*
1128.  * See rot_organic above.  This needs to be different from rot_organic,
1129.  * even though they act the same.
1130.  */
1131. void
1132. rot_corpse(arg, timeout)
1133. genericptr_t arg;
1134. long timeout;	/* unused */
1135. {
1136. 	xchar x = 0, y = 0;
1137. 	struct obj *obj = (struct obj *) arg;
1138. 	boolean on_floor = obj->where == OBJ_FLOOR,
1139. 		in_invent = obj->where == OBJ_INVENT;
1140. 
1141. 	if (on_floor) {
1142. 	    x = obj->ox;
1143. 	    y = obj->oy;
1144. 	} else if (in_invent) {
1145. 	    if (flags.verbose)
1146. 		Your("%s%s rot%s away%c",
1147. 		     obj == uwep ? "wielded " : "", corpse_xname(obj, FALSE),
1148. 		     obj->quan == 1L ? "s" : "", obj == uwep ? '!' : '.');
1149. 	    if (obj == uwep) {
1150. 		uwepgone();	/* now bare handed */
1151. 		stop_occupation();
1152. 	    }
1153. 	}
1154. 	rot_organic(arg, timeout);
1155. 	if (on_floor) newsym(x, y);
1156. 	else if (in_invent) update_inventory();
1157. }
1158. 
1159. #if 0
1160. void
1161. bury_monst(mtmp)
1162. struct monst *mtmp;
1163. {
1164. #ifdef DEBUG
1165. 	pline("bury_monst: %s", mon_nam(mtmp));
1166. #endif
1167. 	if(canseemon(mtmp)) {
1168. 	    if(is_flyer(mtmp->data) || is_floater(mtmp->data)) {
1169. 		pline_The("%s opens up, but %s is not swallowed!",
1170. 			surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
1171. 		return;
1172. 	    } else
1173. 	        pline_The("%s opens up and swallows %s!",
1174. 			surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
1175. 	}
1176. 
1177. 	mtmp->mburied = TRUE;
1178. 	wakeup(mtmp);			/* at least give it a chance :-) */
1179. 	newsym(mtmp->mx, mtmp->my);
1180. }
1181. 
1182. void
1183. bury_you()
1184. {
1185. #ifdef DEBUG
1186. 	pline("bury_you");
1187. #endif
1188.     if (!Levitation && !is_flyer(uasmon)) {
1189. 	if(u.uswallow)
1190. 	    You_feel("a sensation like falling into a trap!");
1191. 	else
1192. 	    pline_The("%s opens beneath you and you fall in!",
1193. 		  surface(u.ux, u.uy));
1194. 
1195. 	u.uburied = TRUE;
1196. 	if(!Strangled && !Breathless) Strangled = 6;
1197. 	under_ground(1);
1198.     }
1199. }
1200. 
1201. void
1202. unearth_you()
1203. {
1204. #ifdef DEBUG
1205. 	pline("unearth_you");
1206. #endif
1207. 	u.uburied = FALSE;
1208. 	under_ground(0);
1209. 	if(!uamul || uamul->otyp != AMULET_OF_STRANGULATION)
1210. 		Strangled = 0;
1211. 	vision_recalc(0);
1212. }
1213. 
1214. void
1215. escape_tomb()
1216. {
1217. #ifdef DEBUG
1218. 	pline("escape_tomb");
1219. #endif
1220. 	if ((Teleportation || can_teleport(uasmon)) &&
1221. 	    (Teleport_control || rn2(3) < Luck+2)) {
1222. 		You("attempt a teleport spell.");
1223. 		(void) dotele();	/* calls unearth_you() */
1224. 	} else if(u.uburied) { /* still buried after 'port attempt */
1225. 		boolean good;
1226. 
1227. 		if(amorphous(uasmon) || passes_walls(uasmon) ||
1228. 		   noncorporeal(uasmon) || unsolid(uasmon) ||
1229. 		   (tunnels(uasmon) && !needspick(uasmon))) {
1230. 
1231. 		    You("%s up through the floor.",
1232. 			(tunnels(uasmon) && !needspick(uasmon)) ?
1233. 			 "try to tunnel" : (amorphous(uasmon)) ?
1234. 			 "ooze" : "phase");
1235. 
1236. 		    if(tunnels(uasmon) && !needspick(uasmon))
1237. 			good = dighole(TRUE);
1238. 		    else good = TRUE;
1239. 		    if(good) unearth_you();
1240. 		}
1241. 	}
1242. }
1243. 
1244. void
1245. bury_obj(otmp)
1246. struct obj *otmp;
1247. {
1248. 
1249. #ifdef DEBUG
1250. 	pline("bury_obj");
1251. #endif
1252. 	if(cansee(otmp->ox, otmp->oy))
1253. 	   pline_The("objects on the %s tumble into a hole!",
1254. 		surface(otmp->ox, otmp->oy));
1255. 
1256. 	bury_objs(otmp->ox, otmp->oy);
1257. }
1258. #endif
1259. 
1260. #ifdef DEBUG
1261. void
1262. wiz_debug_cmd() /* in this case, bury everything at your loc and around */
1263. {
1264. 	int x, y;
1265. 
1266. 	for (x = u.ux - 1; x <= u.ux + 1; x++)
1267. 	    for (y = u.uy - 1; y <= u.uy + 1; y++)
1268. 		if (isok(x,y)) bury_objs(x,y);
1269. }
1270. 
1271. #endif /* DEBUG */
1272. #endif /* OVL3 */
1273. 
1274. /*dig.c*/