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