Source:NetHack 3.3.0/dig.c

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

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

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