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.
Top of file[]
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.
| The NetHack General Public License applies to screenshots, source code and other content from NetHack. |
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.
rm_waslit[]
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.
mkcavepos[]
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.
mkcavearea[]
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.
dig_typ[]
132. /* When digging into location <x,y>, what are you actually digging into? */ 133. STATIC_OVL int 134. dig_typ(otmp, x, y) 135. struct obj *otmp; 136. xchar x, y; 137. { 138. boolean ispick = is_pick(otmp); 139. 140. return (ispick && sobj_at(STATUE, x, y) ? DIGTYP_STATUE : 141. ispick && sobj_at(BOULDER, x, y) ? DIGTYP_BOULDER : 142. closed_door(x, y) ? DIGTYP_DOOR : 143. IS_TREE(levl[x][y].typ) ? 144. (ispick ? DIGTYP_UNDIGGABLE : DIGTYP_TREE) : 145. ispick && IS_ROCK(levl[x][y].typ) && 146. (!level.flags.arboreal || IS_WALL(levl[x][y].typ)) ? 147. DIGTYP_ROCK : DIGTYP_UNDIGGABLE); 148. } 149.
is_digging[]
150. boolean 151. is_digging() 152. { 153. if (occupation == dig) { 154. return TRUE; 155. } 156. return FALSE; 157. } 158.
dig_check[]
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.
dig[]
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 <u.ux,u.uy> */ 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.
holetime[]
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.
fillholetyp[]
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.
digactualhole[]
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.
dighole[]
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.
dig_up_grave[]
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.
use_pick_axe[]
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.
use_pick_axe2[]
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.
watch_dig[]
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 */
mdig_tunnel[]
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 */
zap_dig[]
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.
bury_an_obj[]
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.
bury_objs[]
bury_objs() takes two parameters, an x,y coordinate, and buries all objects on the floor at the location.
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.
unearth_objs[]
unearth_objs() takes two parameters, an x,y coordinate, and unearths all objects buried at that location.
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.
rot_organic[]
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.
rot_corpse[]
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.
bury_monst[]
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.
bury_you[]
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.
unearth_you[]
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.
escape_tomb[]
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.
bury_obj[]
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.
wiz_debug_cmd[]
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*/