Source:Dig.c

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