1 /* NetHack 3.6 dig.c $NHDT-Date: 1517913682 2018/02/06 10:41:22 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.108 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Michael Allison, 2012. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 static NEARDATA boolean did_dig_msg;
15 STATIC_DCL boolean NDECL(rm_waslit);
16 STATIC_DCL void FDECL(mkcavepos,
17 (XCHAR_P, XCHAR_P, int, BOOLEAN_P, BOOLEAN_P));
18 STATIC_DCL void FDECL(mkcavearea, (BOOLEAN_P));
19 STATIC_DCL int NDECL(dig);
20 STATIC_DCL void FDECL(dig_up_grave, (coord *));
21 STATIC_DCL int FDECL(adj_pit_checks, (coord *, char *));
22 STATIC_DCL void FDECL(pit_flow, (struct trap *, SCHAR_P));
24 /* Indices returned by dig_typ() */
26 DIGTYP_UNDIGGABLE = 0,
39 if (levl[u.ux][u.uy].typ == ROOM && levl[u.ux][u.uy].waslit)
41 for (x = u.ux - 2; x < u.ux + 3; x++)
42 for (y = u.uy - 1; y < u.uy + 2; y++)
43 if (isok(x, y) && levl[x][y].waslit)
48 /* Change level topology. Messes with vision tables and ignores things like
49 * boulders in the name of a nice effect. Vision will get fixed up again
50 * immediately after the effect is complete.
53 mkcavepos(x, y, dist, waslit, rockit)
56 boolean waslit, rockit;
58 register struct rm *lev;
65 register struct monst *mtmp;
67 if (IS_ROCK(lev->typ))
70 return; /* don't cover the portal */
71 if ((mtmp = m_at(x, y)) != 0) /* make sure crucial monsters survive */
72 if (!passes_walls(mtmp->data))
73 (void) rloc(mtmp, TRUE);
74 } else if (lev->typ == ROOM)
77 unblock_point(x, y); /* make sure vision knows this location is open */
79 /* fake out saved state */
83 lev->lit = (rockit ? FALSE : TRUE);
85 lev->waslit = (rockit ? FALSE : TRUE);
86 lev->horizontal = FALSE;
87 /* short-circuit vision recalc */
88 viz_array[y][x] = (dist < 3) ? (IN_SIGHT | COULD_SEE) : COULD_SEE;
89 lev->typ = (rockit ? STONE : ROOM);
91 impossible("mkcavepos called with dist %d", dist);
97 register boolean rockit;
100 xchar xmin = u.ux, xmax = u.ux;
101 xchar ymin = u.uy, ymax = u.uy;
103 register boolean waslit = rm_waslit();
107 pline("Crash! The ceiling collapses around you!");
109 pline("
\82°
\82°
\82ñ
\81I
\82 \82È
\82½
\82Ì
\82Ü
\82í
\82è
\82Ì
\93V
\88ä
\82ª
\95ö
\82ê
\82½
\81I");
112 pline("A mysterious force %s cave around you!",
113 (levl[u.ux][u.uy].typ == CORR) ? "creates a" : "extends the");
115 pline("
\90_
\94é
\93I
\82È
\97Í
\82É
\82æ
\82è
\82 \82È
\82½
\82Ì
\82Ü
\82í
\82è%s
\82½
\81I",
116 (levl[u.ux][u.uy].typ == CORR) ? "
\82É
\93´
\8cA
\82ª
\82Å
\82«" : "
\82Ì
\93´
\8cA
\82ª
\8dL
\82ª
\82Á");
118 display_nhwindow(WIN_MESSAGE, TRUE);
120 for (dist = 1; dist <= 2; dist++) {
125 if (dist < 2) { /* the area is wider that it is high */
128 for (i = xmin + 1; i < xmax; i++) {
129 mkcavepos(i, ymin, dist, waslit, rockit);
130 mkcavepos(i, ymax, dist, waslit, rockit);
135 for (i = ymin; i <= ymax; i++) {
136 mkcavepos(xmin, i, dist, waslit, rockit);
137 mkcavepos(xmax, i, dist, waslit, rockit);
140 flush_screen(1); /* make sure the new glyphs shows up */
144 if (!rockit && levl[u.ux][u.uy].typ == CORR) {
145 levl[u.ux][u.uy].typ = ROOM;
147 levl[u.ux][u.uy].waslit = TRUE;
148 newsym(u.ux, u.uy); /* in case player is invisible */
151 vision_full_recalc = 1; /* everything changed */
154 /* When digging into location <x,y>, what are you actually digging into? */
163 return DIGTYP_UNDIGGABLE;
164 ispick = is_pick(otmp);
165 if (!ispick && !is_axe(otmp))
166 return DIGTYP_UNDIGGABLE;
168 return ((ispick && sobj_at(STATUE, x, y))
170 : (ispick && sobj_at(BOULDER, x, y))
174 : IS_TREE(levl[x][y].typ)
175 ? (ispick ? DIGTYP_UNDIGGABLE : DIGTYP_TREE)
176 : (ispick && IS_ROCK(levl[x][y].typ)
177 && (!level.flags.arboreal
178 || IS_WALL(levl[x][y].typ)))
180 : DIGTYP_UNDIGGABLE);
186 if (occupation == dig) {
192 #define BY_YOU (&youmonst)
193 #define BY_OBJECT ((struct monst *) 0)
196 dig_check(madeby, verbose, x, y)
197 struct monst *madeby;
201 struct trap *ttmp = t_at(x, y);
204 (madeby == BY_YOU && uwep && is_axe(uwep)) ? "chop" : "dig in";
206 (madeby == BY_YOU && uwep && is_axe(uwep)) ? "
\8dÓ
\82¯
\82È
\82¢" : "
\8c@
\82ê
\82È
\82¢";
208 if (On_stairs(x, y)) {
209 if (x == xdnladder || x == xupladder) {
212 pline_The("ladder resists your effort.");
214 pline("
\82Í
\82µ
\82²
\82ª
\8e×
\96\82\82ð
\82µ
\82½
\81D");
217 pline_The("stairs are too hard to %s.", verb);
219 pline("
\8aK
\92i
\82Í
\82Æ
\82Ä
\82à
\8cÅ
\82
\82Ä%s
\81D", verb);
221 } else if (IS_THRONE(levl[x][y].typ) && madeby != BY_OBJECT) {
224 pline_The("throne is too hard to break apart.");
226 pline("
\8bÊ
\8dÀ
\82Í
\82Æ
\82Ä
\82à
\8cÅ
\82
\82Ä
\8dÓ
\82¯
\82È
\82¢
\81D");
228 } else if (IS_ALTAR(levl[x][y].typ)
229 && (madeby != BY_OBJECT || Is_astralevel(&u.uz)
230 || Is_sanctum(&u.uz))) {
233 pline_The("altar is too hard to break apart.");
235 pline_The("
\8dÕ
\92d
\82Í
\82Æ
\82Ä
\82à
\8cÅ
\82
\82Ä
\8dÓ
\82¯
\82È
\82¢
\81D");
237 } else if (Is_airlevel(&u.uz)) {
240 You("cannot %s thin air.", verb);
242 You("
\89½
\82à
\82È
\82¢
\8bó
\8aÔ
\82Í%s
\81D", verb);
244 } else if (Is_waterlevel(&u.uz)) {
247 pline_The("%s splashes and subsides.", hliquid("water"));
249 pline_The("%s
\82ª
\83s
\83V
\83\83\83b
\82Æ
\92µ
\82Ë
\82½
\81D", hliquid("
\90\85"));
251 } else if ((IS_ROCK(levl[x][y].typ) && levl[x][y].typ != SDOOR
252 && (levl[x][y].wall_info & W_NONDIGGABLE) != 0)
254 && (ttmp->ttyp == MAGIC_PORTAL
255 || ttmp->ttyp == VIBRATING_SQUARE
256 || (!Can_dig_down(&u.uz) && !levl[x][y].candig)))) {
259 pline_The("%s here is too hard to %s.", surface(x, y), verb);
261 pline_The("%s
\82Í
\82Æ
\82Ä
\82à
\8cÅ
\82
\82Ä%s
\81D", surface(x,y), verb);
263 } else if (sobj_at(BOULDER, x, y)) {
266 There("isn't enough room to %s here.", verb);
268 pline("
\8f\
\95ª
\82È
\8fê
\8f\8a\82ª
\82È
\82¢
\82Ì
\82Å%s
\81D", verb);
270 } else if (madeby == BY_OBJECT
271 /* the block against existing traps is mainly to
272 prevent broken wands from turning holes into pits */
273 && (ttmp || is_pool_or_lava(x, y))) {
274 /* digging by player handles pools separately */
283 register struct rm *lev;
284 register xchar dpx = context.digging.pos.x, dpy = context.digging.pos.y;
285 register boolean ispick = uwep && is_pick(uwep);
287 const char *verb = (!uwep || is_pick(uwep)) ? "dig into" : "chop through";
289 const char *verb = (!uwep || is_pick(uwep)) ? "
\8c@
\82ê
\82È
\82¢" : "
\8dÓ
\82¯
\82È
\82¢";
291 lev = &levl[dpx][dpy];
292 /* perhaps a nymph stole your pick-axe while you were busy digging */
293 /* or perhaps you teleported away */
294 if (u.uswallow || !uwep || (!ispick && !is_axe(uwep))
295 || !on_level(&context.digging.level, &u.uz)
296 || ((context.digging.down ? (dpx != u.ux || dpy != u.uy)
297 : (distu(dpx, dpy) > 2))))
300 if (context.digging.down) {
301 if (!dig_check(BY_YOU, TRUE, u.ux, u.uy))
303 } else { /* !context.digging.down */
304 if (IS_TREE(lev->typ) && !may_dig(dpx, dpy)
305 && dig_typ(uwep, dpx, dpy) == DIGTYP_TREE) {
307 pline("This tree seems to be petrified.");
309 pline("
\82±
\82Ì
\96Ø
\82Í
\90Î
\89»
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D");
312 if (IS_ROCK(lev->typ) && !may_dig(dpx, dpy)
313 && dig_typ(uwep, dpx, dpy) == DIGTYP_ROCK) {
315 pline("This %s is too hard to %s.",
316 is_db_wall(dpx, dpy) ? "drawbridge" : "wall", verb);
318 pline("
\82±
\82Ì%s
\82Í
\82Æ
\82Ä
\82à
\8cÅ
\82
\82Ä%s
\81D",
319 is_db_wall(dpx, dpy) ? "
\92µ
\82Ë
\8b´" : "
\95Ç", verb);
324 if (Fumbling && !rn2(3)) {
329 You("fumble and drop %s.", yname(uwep));
331 You("
\8eè
\82ª
\8a\8a\82è%s
\82ð
\97\8e\82µ
\82½
\81D", yname(uwep));
336 pline("%s and %s %s!", Yobjnam2(uwep, "bounce"),
337 otense(uwep, "hit"), mon_nam(u.usteed));
339 pline("%s
\82Í
\92µ
\82Ë
\82©
\82¦
\82è%s
\82É
\96½
\92\86\82µ
\82½
\81I",
340 xname(uwep), mon_nam(u.usteed));
344 pline("Ouch! %s and %s you!", Yobjnam2(uwep, "bounce"),
345 otense(uwep, "hit"));
347 pline("
\82¢
\82Ä
\82Á
\81I%s
\82Í
\92µ
\82Ë
\82©
\82¦
\82è
\82 \82È
\82½
\82É
\96½
\92\86\82µ
\82½
\81I",
350 set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
355 pline("Bang! You hit with the broad side of %s!",
357 pline("
\83o
\83\93\81I%s
\82Ì
\95¿
\82Å
\91Å
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I",
362 Your("swing misses its mark.");
364 You("
\91_
\82¢
\82ð
\92è
\82ß
\82Ä
\90U
\82è
\82¨
\82ë
\82µ
\82½
\82ª
\82Í
\82¸
\82µ
\82½
\81D");
370 context.digging.effort +=
371 10 + rn2(5) + abon() + uwep->spe - greatest_erosion(uwep) + u.udaminc;
372 if (Race_if(PM_DWARF))
373 context.digging.effort *= 2;
374 if (context.digging.down) {
375 struct trap *ttmp = t_at(dpx, dpy);
377 if (context.digging.effort > 250 || (ttmp && ttmp->ttyp == HOLE)) {
378 (void) dighole(FALSE, FALSE, (coord *) 0);
379 (void) memset((genericptr_t) &context.digging, 0,
380 sizeof context.digging);
381 return 0; /* done with digging */
384 if (context.digging.effort <= 50
385 || (ttmp && (ttmp->ttyp == TRAPDOOR || ttmp->ttyp == PIT
386 || ttmp->ttyp == SPIKED_PIT))) {
388 } else if (ttmp && (ttmp->ttyp == LANDMINE
389 || (ttmp->ttyp == BEAR_TRAP && !u.utrap))) {
390 /* digging onto a set object trap triggers it;
391 hero should have used #untrap first */
392 dotrap(ttmp, FORCETRAP);
393 /* restart completely from scratch if we resume digging */
394 (void) memset((genericptr_t) &context.digging, 0,
395 sizeof context.digging);
397 } else if (ttmp && ttmp->ttyp == BEAR_TRAP && u.utrap) {
398 if (rnl(7) > (Fumbling ? 1 : 4)) {
400 int dmg = dmgval(uwep, &youmonst) + dbon();
407 You("hit yourself in the %s.", body_part(FOOT));
409 pline("%s
\82É
\93\96\82½
\82Á
\82½
\81D", body_part(FOOT));
411 Sprintf(kbuf, "chopping off %s own %s", uhis(),
414 Sprintf(kbuf, "
\8e©
\95ª
\82Ì%s
\82ð
\90Ø
\82è
\97\8e\82Æ
\82µ
\82Ä", body_part(FOOT));
416 losehp(Maybe_Half_Phys(dmg), kbuf, KILLED_BY);
419 You("destroy the bear trap with %s.",
420 yobjnam(uwep, (const char *) 0));
422 You("%s
\82Å
\8cF
\82Ìã©
\82ð
\89ó
\82µ
\82½
\81D", xname(uwep));
424 u.utrap = 0; /* release from trap */
427 /* we haven't made any progress toward a pit yet */
428 context.digging.effort = 0;
432 if (IS_ALTAR(lev->typ)) {
433 altar_wrath(dpx, dpy);
437 /* make pit at <u.ux,u.uy> */
438 if (dighole(TRUE, FALSE, (coord *) 0)) {
439 context.digging.level.dnum = 0;
440 context.digging.level.dlevel = -1;
445 if (context.digging.effort > 100) {
446 register const char *digtxt, *dmgtxt = (const char *) 0;
447 register struct obj *obj;
448 register boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE);
450 if ((obj = sobj_at(STATUE, dpx, dpy)) != 0) {
451 if (break_statue(obj))
453 digtxt = "The statue shatters.";
455 digtxt = "
\92¤
\91\9c\82Í
\82±
\82È
\82²
\82È
\82É
\82È
\82Á
\82½
\81D";
457 /* it was a statue trap; break_statue()
458 * printed a message and updated the screen
461 } else if ((obj = sobj_at(BOULDER, dpx, dpy)) != 0) {
465 if ((bobj = sobj_at(BOULDER, dpx, dpy)) != 0) {
466 /* another boulder here, restack it to the top */
467 obj_extract_self(bobj);
468 place_object(bobj, dpx, dpy);
471 digtxt = "The boulder falls apart.";
473 digtxt = "
\8aâ
\82Í
\82±
\82È
\82²
\82È
\82É
\82È
\82Á
\82½
\81D";
474 } else if (lev->typ == STONE || lev->typ == SCORR
475 || IS_TREE(lev->typ)) {
476 if (Is_earthlevel(&u.uz)) {
477 if (uwep->blessed && !rn2(3)) {
480 } else if ((uwep->cursed && !rn2(4))
481 || (!uwep->blessed && !rn2(6))) {
486 if (IS_TREE(lev->typ)) {
488 digtxt = "You cut down the tree.";
490 digtxt = "
\96Ø
\82ð
\90Ø
\82è
\93|
\82µ
\82½
\81D";
493 (void) rnd_treefruit_at(dpx, dpy);
496 digtxt = "You succeed in cutting away some rock.";
498 digtxt = "
\8aâ
\82ð
\8f
\82µ
\90Ø
\82è
\82Æ
\82Á
\82½
\81D";
501 } else if (IS_WALL(lev->typ)) {
503 add_damage(dpx, dpy, SHOP_WALL_DMG);
507 dmgtxt = "
\8f\9d\82Â
\82¯
\82é";
509 if (level.flags.is_maze_lev) {
511 } else if (level.flags.is_cavernous_lev && !in_town(dpx, dpy)) {
515 lev->doormask = D_NODOOR;
518 digtxt = "You make an opening in the wall.";
520 digtxt = "
\95Ç
\82É
\8c\8a\82ð
\8bó
\82¯
\82½
\81D";
521 } else if (lev->typ == SDOOR) {
522 cvt_sdoor_to_door(lev); /* ->typ = DOOR */
524 digtxt = "You break through a secret door!";
526 digtxt = "
\94é
\96§
\82Ì
\94à
\82ð
\92Ê
\82è
\94²
\82¯
\82½
\81I";
527 if (!(lev->doormask & D_TRAPPED))
528 lev->doormask = D_BROKEN;
529 } else if (closed_door(dpx, dpy)) {
531 digtxt = "You break through the door.";
533 digtxt = "
\94à
\82ð
\92Ê
\82è
\94²
\82¯
\82½
\81D";
535 add_damage(dpx, dpy, SHOP_DOOR_COST);
541 if (!(lev->doormask & D_TRAPPED))
542 lev->doormask = D_BROKEN;
544 return 0; /* statue or boulder got taken */
546 if (!does_block(dpx, dpy, &levl[dpx][dpy]))
547 unblock_point(dpx, dpy); /* vision: can see through */
548 feel_newsym(dpx, dpy);
549 if (digtxt && !context.digging.quiet)
550 pline1(digtxt); /* after newsym */
552 pay_for_damage(dmgtxt, FALSE);
554 if (Is_earthlevel(&u.uz) && !rn2(3)) {
555 register struct monst *mtmp;
559 mtmp = makemon(&mons[PM_EARTH_ELEMENTAL], dpx, dpy,
563 mtmp = makemon(&mons[PM_XORN], dpx, dpy, NO_MM_FLAGS);
568 pline_The("debris from your digging comes to life!");
570 pline("
\8aâ
\82Ì
\94j
\95Ð
\82ª
\90¶
\96½
\82ð
\91Ñ
\82Ñ
\82½
\81I");
572 if (IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) {
573 lev->doormask = D_NODOOR;
575 b_trapped("door", 0);
577 b_trapped("
\94à", 0);
581 context.digging.lastdigtime = moves;
582 context.digging.quiet = FALSE;
583 context.digging.level.dnum = 0;
584 context.digging.level.dlevel = -1;
586 } else { /* not enough effort has been spent yet */
588 static const char *const d_target[6] = { "", "rock", "statue",
589 "boulder", "door", "tree" };
591 static const char *const d_target[6] = { "", "
\90Î", "
\92¤
\91\9c",
592 "
\8aâ", "
\94à", "
\96Ø" };
594 int dig_target = dig_typ(uwep, dpx, dpy);
596 if (IS_WALL(lev->typ) || dig_target == DIGTYP_DOOR) {
597 if (*in_rooms(dpx, dpy, SHOPBASE)) {
599 pline("This %s seems too hard to %s.",
600 IS_DOOR(lev->typ) ? "door" : "wall", verb);
602 pline("
\82±
\82Ì%s
\82Í
\82Æ
\82Ä
\82à
\8cÅ
\82
\82Ä%s
\81D",
603 IS_DOOR(lev->typ) ? "
\94à" : "
\95Ç", verb);
607 } else if (dig_target == DIGTYP_UNDIGGABLE
608 || (dig_target == DIGTYP_ROCK && !IS_ROCK(lev->typ)))
609 return 0; /* statue or boulder got taken */
613 You("hit the %s with all your might.", d_target[dig_target]);
615 You("%s
\82ð
\97Í
\88ê
\94t
\91Å
\82¿
\82Â
\82¯
\82½
\81D", d_target[dig_target]);
622 /* When will hole be finished? Very rough indication used by shopkeeper. */
626 if (occupation != dig || !*u.ushops)
628 return ((250 - context.digging.effort) / 20);
631 /* Return typ of liquid to fill a hole with, or ROOM, if no liquid nearby */
633 fillholetyp(x, y, fill_if_any)
635 boolean fill_if_any; /* force filling if it exists at all */
638 int lo_x = max(1, x - 1), hi_x = min(x + 1, COLNO - 1),
639 lo_y = max(0, y - 1), hi_y = min(y + 1, ROWNO - 1);
640 int pool_cnt = 0, moat_cnt = 0, lava_cnt = 0;
642 for (x1 = lo_x; x1 <= hi_x; x1++)
643 for (y1 = lo_y; y1 <= hi_y; y1++)
646 else if (is_pool(x1, y1))
647 /* This must come after is_moat since moats are pools
648 * but not vice-versa. */
650 else if (is_lava(x1, y1))
654 pool_cnt /= 3; /* not as much liquid as the others */
656 if ((lava_cnt > moat_cnt + pool_cnt && rn2(lava_cnt + 1))
657 || (lava_cnt && fill_if_any))
659 else if ((moat_cnt > 0 && rn2(moat_cnt + 1)) || (moat_cnt && fill_if_any))
661 else if ((pool_cnt > 0 && rn2(pool_cnt + 1)) || (pool_cnt && fill_if_any))
668 digactualhole(x, y, madeby, ttyp)
670 struct monst *madeby;
673 struct obj *oldobjs, *newobjs;
674 register struct trap *ttmp;
675 char surface_type[BUFSZ];
676 struct rm *lev = &levl[x][y];
678 struct monst *mtmp = m_at(x, y); /* may be madeby */
679 boolean madeby_u = (madeby == BY_YOU);
680 boolean madeby_obj = (madeby == BY_OBJECT);
681 boolean at_u = (x == u.ux) && (y == u.uy);
682 boolean wont_fall = Levitation || Flying;
684 if (at_u && u.utrap) {
685 if (u.utraptype == TT_BURIEDBALL)
686 buried_ball_to_punishment();
687 else if (u.utraptype == TT_INFLOOR)
691 /* these furniture checks were in dighole(), but wand
692 breaking bypasses that routine and calls us directly */
693 if (IS_FOUNTAIN(lev->typ)) {
695 SET_FOUNTAIN_WARNED(x, y); /* force dryup */
696 dryup(x, y, madeby_u);
698 } else if (IS_SINK(lev->typ)) {
701 } else if (lev->typ == DRAWBRIDGE_DOWN
702 || (is_drawbridge_wall(x, y) >= 0)) {
704 /* if under the portcullis, the bridge is adjacent */
705 (void) find_drawbridge(&bx, &by);
706 destroy_drawbridge(bx, by);
710 if (ttyp != PIT && (!Can_dig_down(&u.uz) && !lev->candig)) {
711 impossible("digactualhole: can't dig %s on this level.",
712 defsyms[trap_to_defsym(ttyp)].explanation);
716 /* maketrap() might change it, also, in this situation,
717 surface() returns an inappropriate string for a grave */
718 if (IS_GRAVE(lev->typ))
720 Strcpy(surface_type, "grave");
722 Strcpy(surface_type, "
\95æ");
724 Strcpy(surface_type, surface(x, y));
725 shopdoor = IS_DOOR(lev->typ) && *in_rooms(x, y, SHOPBASE);
726 oldobjs = level.objects[x][y];
727 ttmp = maketrap(x, y, ttyp);
730 newobjs = level.objects[x][y];
731 ttmp->madeby_u = madeby_u;
740 if (x != u.ux || y != u.uy)
742 You("dig an adjacent pit.");
744 You("
\97×
\82Ì
\97\8e\82µ
\8c\8a\82ð
\8c@
\82Á
\82½
\81D");
747 You("dig a pit in the %s.", surface_type);
749 You("%s
\82É
\97\8e\82µ
\8c\8a\82ð
\8c@
\82Á
\82½
\81D", surface_type);
752 pay_for_damage("ruin", FALSE);
754 pay_for_damage("
\89ó
\82·", FALSE);
755 } else if (!madeby_obj && canseemon(madeby))
757 pline("%s digs a pit in the %s.", Monnam(madeby), surface_type);
759 pline("%s
\82Í%s
\82É
\97\8e\82µ
\8c\8a\82ð
\8c@
\82Á
\82½
\81D", Monnam(madeby), surface_type);
760 else if (cansee(x, y) && flags.verbose)
762 pline("A pit appears in the %s.", surface_type);
764 pline("
\97\8e\82µ
\8c\8a\82ª%s
\82É
\8c»
\82í
\82ê
\82½
\81D", surface_type);
769 u.utraptype = TT_PIT;
770 vision_full_recalc = 1; /* vision limits change */
773 if (oldobjs != newobjs) /* something unearthed */
774 (void) pickup(1); /* detects pit */
776 if (is_flyer(mtmp->data) || is_floater(mtmp->data)) {
779 pline("%s %s over the pit.", Monnam(mtmp),
780 (is_flyer(mtmp->data)) ? "flies" : "floats");
782 pline("%s
\82Í%s
\97\8e\82µ
\8c\8a\82ð
\89z
\82¦
\82½
\81D", Monnam(mtmp),
783 (is_flyer(mtmp->data)) ? "
\94ò
\82ñ
\82Å" : "
\95\82\82¢
\82Ä");
785 } else if (mtmp != madeby)
786 (void) mintrap(mtmp);
788 } else { /* was TRAPDOOR now a HOLE*/
792 You("dig a hole through the %s.", surface_type);
794 You("%s
\82É
\8c\8a\82ð
\8aJ
\82¯
\82½
\81D", surface_type);
795 else if (!madeby_obj && canseemon(madeby))
797 pline("%s digs a hole through the %s.", Monnam(madeby),
800 pline("%s
\82Í%s
\82É
\8c\8a\82ð
\8aJ
\82¯
\82½
\81D", Monnam(madeby),
803 else if (cansee(x, y) && flags.verbose)
805 pline("A hole appears in the %s.", surface_type);
807 pline("%s
\82É
\8c\8a\82ª
\8c»
\82í
\82ê
\82½
\81D", surface_type);
810 if (!u.ustuck && !wont_fall && !next_to_u()) {
812 You("are jerked back by your pet!");
814 You("
\83y
\83b
\83g
\82É
\82æ
\82Á
\82Ä
\88ø
\82«
\96ß
\82³
\82ê
\82½
\81I");
818 /* Floor objects get a chance of falling down. The case where
819 * the hero does NOT fall down is treated here. The case
820 * where the hero does fall down is treated in goto_level().
822 if (u.ustuck || wont_fall) {
824 impact_drop((struct obj *) 0, x, y, 0);
825 if (oldobjs != newobjs)
827 if (shopdoor && madeby_u)
829 pay_for_damage("ruin", FALSE);
831 pay_for_damage("
\82ß
\82¿
\82á
\82ß
\82¿
\82á
\82É
\82·
\82é", FALSE);
836 if (*u.ushops && madeby_u)
837 shopdig(1); /* shk might snatch pack */
838 /* handle earlier damage, eg breaking wand of digging */
841 pay_for_damage("dig into", TRUE);
843 pay_for_damage("
\8c\8a\82ð
\82 \82¯
\82é", TRUE);
846 You("fall through...");
848 You("
\97\8e\82¿
\82½
\81D
\81D
\81D");
849 /* Earlier checks must ensure that the destination
850 * level exists and is in the present dungeon.
852 newlevel.dnum = u.uz.dnum;
853 newlevel.dlevel = u.uz.dlevel + 1;
854 goto_level(&newlevel, FALSE, TRUE, FALSE);
855 /* messages for arriving in special rooms */
859 if (shopdoor && madeby_u)
861 pay_for_damage("ruin", FALSE);
863 pay_for_damage("
\82ß
\82¿
\82á
\82ß
\82¿
\82á
\82É
\82·
\82é", FALSE);
865 impact_drop((struct obj *) 0, x, y, 0);
867 /*[don't we need special sokoban handling here?]*/
868 if (is_flyer(mtmp->data) || is_floater(mtmp->data)
869 || mtmp->data == &mons[PM_WUMPUS]
870 || (mtmp->wormno && count_wsegs(mtmp) > 5)
871 || mtmp->data->msize >= MZ_HUGE)
873 if (mtmp == u.ustuck) /* probably a vortex */
874 return; /* temporary? kludge */
876 if (teleport_pet(mtmp, FALSE)) {
879 if (Is_stronghold(&u.uz)) {
880 assign_level(&tolevel, &valley_level);
881 } else if (Is_botlevel(&u.uz)) {
884 pline("%s avoids the trap.", Monnam(mtmp));
886 pline("%s
\82Íã©
\82ð
\94ð
\82¯
\82½
\81D", Monnam(mtmp));
889 get_level(&tolevel, depth(&u.uz) + 1);
892 make_angry_shk(mtmp, 0, 0);
893 migrate_to_level(mtmp, ledger_no(&tolevel),
894 MIGR_RANDOM, (coord *) 0);
902 * Called from dighole(), but also from do_break_wand()
906 liquid_flow(x, y, typ, ttmp, fillmsg)
912 boolean u_spot = (x == u.ux && y == u.uy);
915 (void) delfloortrap(ttmp);
916 /* if any objects were frozen here, they're released now */
921 pline(fillmsg, hliquid(typ == LAVAPOOL ? "lava" : "water"));
923 pline(fillmsg, hliquid(typ == LAVAPOOL ? "
\97n
\8aâ" : "
\90\85"));
924 if (u_spot && !(Levitation || Flying)) {
926 (void) lava_effects();
932 /* return TRUE if digging succeeded, FALSE otherwise */
934 dighole(pit_only, by_magic, cc)
935 boolean pit_only, by_magic;
938 register struct trap *ttmp;
940 struct obj *boulder_here;
951 if (!isok(dig_x, dig_y))
955 ttmp = t_at(dig_x, dig_y);
956 lev = &levl[dig_x][dig_y];
957 nohole = (!Can_dig_down(&u.uz) && !lev->candig);
959 if ((ttmp && (ttmp->ttyp == MAGIC_PORTAL
960 || ttmp->ttyp == VIBRATING_SQUARE || nohole))
961 || (IS_ROCK(lev->typ) && lev->typ != SDOOR
962 && (lev->wall_info & W_NONDIGGABLE) != 0)) {
964 pline_The("%s %shere is too hard to dig in.", surface(dig_x, dig_y),
965 (dig_x != u.ux || dig_y != u.uy) ? "t" : "");
967 pline("%s
\82Í
\82Æ
\82Ä
\82à
\8cÅ
\82
\82Ä
\8c@
\82ê
\82È
\82¢
\81D", surface(dig_x, dig_y));
970 } else if (is_pool_or_lava(dig_x, dig_y)) {
972 pline_The("%s sloshes furiously for a moment, then subsides.",
973 hliquid(is_lava(dig_x, dig_y) ? "lava" : "water"));
975 pline("%s
\82Í
\8c\83\82µ
\82
\94g
\82¤
\82Á
\82½
\81D",
976 hliquid(is_lava(dig_x, dig_y) ? "
\97n
\8aâ" : "
\90\85"));
978 wake_nearby(); /* splashing */
980 } else if (lev->typ == DRAWBRIDGE_DOWN
981 || (is_drawbridge_wall(dig_x, dig_y) >= 0)) {
982 /* drawbridge_down is the platform crossing the moat when the
983 bridge is extended; drawbridge_wall is the open "doorway" or
984 closed "door" where the portcullis/mechanism is located */
987 pline_The("drawbridge seems too hard to dig through.");
989 pline("
\92µ
\82Ë
\8b´
\82Í
\82Æ
\82Ä
\82à
\8cÅ
\82
\82Ä
\8c@
\82ê
\82»
\82¤
\82É
\82È
\82¢
\81D");
992 int x = dig_x, y = dig_y;
993 /* if under the portcullis, the bridge is adjacent */
994 (void) find_drawbridge(&x, &y);
995 destroy_drawbridge(x, y);
999 } else if ((boulder_here = sobj_at(BOULDER, dig_x, dig_y)) != 0) {
1000 if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)
1003 pline_The("boulder settles into the %spit.",
1004 (dig_x != u.ux || dig_y != u.uy) ? "adjacent " : "");
1006 pline("
\8aâ
\82Í%s
\97\8e\82µ
\8c\8a\82ð
\96\84\82ß
\82½
\81D",
1007 (dig_x != u.ux || dig_y != u.uy) ? "
\97×
\82Ì" : "");
1009 ttmp->ttyp = PIT; /* crush spikes */
1012 * digging makes a hole, but the boulder immediately
1013 * fills it. Final outcome: no hole, no boulder.
1016 pline("KADOOM! The boulder falls in!");
1018 pline("
\82Ç
\82Ç
\81[
\82ñ
\81I
\8aâ
\82Í
\97\8e\82¿
\82½
\81I");
1019 (void) delfloortrap(ttmp);
1021 delobj(boulder_here);
1024 } else if (IS_GRAVE(lev->typ)) {
1025 digactualhole(dig_x, dig_y, BY_YOU, PIT);
1028 } else if (lev->typ == DRAWBRIDGE_UP) {
1029 /* must be floor or ice, other cases handled above */
1030 /* dig "pit" and let fluid flow in (if possible) */
1031 typ = fillholetyp(dig_x, dig_y, FALSE);
1035 * We can't dig a hole here since that will destroy
1036 * the drawbridge. The following is a cop-out. --dlc
1039 pline_The("%s %shere is too hard to dig in.",
1040 surface(dig_x, dig_y),
1041 (dig_x != u.ux || dig_y != u.uy) ? "t" : "");
1043 pline("%s
\82Í
\82Æ
\82Ä
\82à
\8cÅ
\82
\82Ä
\8c@
\82ê
\82È
\82¢
\81D", surface(dig_x, dig_y));
1048 lev->drawbridgemask &= ~DB_UNDER;
1049 lev->drawbridgemask |= (typ == LAVAPOOL) ? DB_LAVA : DB_MOAT;
1051 liquid_flow(dig_x, dig_y, typ, ttmp,
1052 "As you dig, the hole fills with %s!");
1054 liquid_flow(dig_x, dig_y, typ, ttmp,
1055 "
\82 \82È
\82½
\82ª
\8c@
\82é
\82Æ
\81C%s
\82ª
\97N
\82¢
\82Ä
\82«
\82½
\81I");
1059 /* the following two are here for the wand of digging */
1060 } else if (IS_THRONE(lev->typ)) {
1062 pline_The("throne is too hard to break apart.");
1064 pline("
\8bÊ
\8dÀ
\82Í
\82Æ
\82Ä
\82à
\8cÅ
\82
\82Ä
\8dÓ
\82¯
\82È
\82¢
\81D");
1066 } else if (IS_ALTAR(lev->typ)) {
1068 pline_The("altar is too hard to break apart.");
1070 pline("
\8dÕ
\92d
\82Í
\82Æ
\82Ä
\82à
\8cÅ
\82
\82Ä
\8dÓ
\82¯
\82È
\82¢
\81D");
1073 typ = fillholetyp(dig_x, dig_y, FALSE);
1078 liquid_flow(dig_x, dig_y, typ, ttmp,
1079 "As you dig, the hole fills with %s!");
1081 liquid_flow(dig_x, dig_y, typ, ttmp,
1082 "
\82 \82È
\82½
\82ª
\8c@
\82é
\82Æ
\81C%s
\82ª
\97N
\82¢
\82Ä
\82«
\82½
\81I");
1087 /* magical digging disarms settable traps */
1088 if (by_magic && ttmp
1089 && (ttmp->ttyp == LANDMINE || ttmp->ttyp == BEAR_TRAP)) {
1090 int otyp = (ttmp->ttyp == LANDMINE) ? LAND_MINE : BEARTRAP;
1092 /* convert trap into buried object (deletes trap) */
1093 cnv_trap_obj(otyp, 1, ttmp, TRUE);
1096 /* finally we get to make a hole */
1097 if (nohole || pit_only)
1098 digactualhole(dig_x, dig_y, BY_YOU, PIT);
1100 digactualhole(dig_x, dig_y, BY_YOU, HOLE);
1121 if (!isok(dig_x, dig_y))
1125 /* Grave-robbing is frowned upon... */
1126 exercise(A_WIS, FALSE);
1127 if (Role_if(PM_ARCHEOLOGIST)) {
1128 adjalign(-sgn(u.ualign.type) * 3);
1130 You_feel("like a despicable grave-robber!");
1132 pline("
\82±
\82ê
\82Å
\82Í
\82Ü
\82é
\82Å
\95æ
\93D
\96_
\82¾
\81I");
1133 } else if (Role_if(PM_SAMURAI)) {
1134 adjalign(-sgn(u.ualign.type));
1136 You("disturb the honorable dead!");
1138 You("
\96¼
\97_
\82 \82é
\8e\80\8eÒ
\82Ì
\96°
\82è
\82ð
\96W
\82°
\82¾
\81I");
1139 } else if ((u.ualign.type == A_LAWFUL) && (u.ualign.record > -10)) {
1140 adjalign(-sgn(u.ualign.type));
1142 You("have violated the sanctity of this grave!");
1144 You("
\90¹
\82È
\82é
\95æ
\92n
\82ð
\94Æ
\82µ
\82½
\81I");
1151 You("unearth a corpse.");
1153 You("
\8e\80\91Ì
\82ð
\8c@
\82è
\8bN
\82µ
\82½
\81D");
1154 if ((otmp = mk_tt_object(CORPSE, dig_x, dig_y)) != 0)
1155 otmp->age -= 100; /* this is an *OLD* corpse */
1160 pline(Hallucination ? "Dude! The living dead!"
1162 pline(Hallucination ? "
\83]
\83\93\83r
\82ª
\82
\82é
\82è
\82Æ
\97Ö
\82ð
\95`
\82¢
\82½
\81I"
1164 : "The grave's owner is very upset!");
1166 : "
\95æ
\82Ì
\8f\8a\97L
\8eÒ
\82Í
\82Æ
\82Ä
\82à
\8bÁ
\82¢
\82½
\81I");
1167 (void) makemon(mkclass(S_ZOMBIE, 0), dig_x, dig_y, NO_MM_FLAGS);
1172 pline(Hallucination ? "I want my mummy!"
1174 pline(Hallucination ? "
\83}
\83~
\81[
\82ª
\95K
\97v
\82¾
\81I"
1176 : "You've disturbed a tomb!");
1178 : "
\95æ
\82ð
\8dr
\82µ
\82Ä
\82µ
\82Ü
\82Á
\82½
\81I");
1179 (void) makemon(mkclass(S_MUMMY, 0), dig_x, dig_y, NO_MM_FLAGS);
1184 pline_The("grave seems unused. Strange....");
1186 pline("
\82±
\82Ì
\95æ
\82Í
\96¢
\8eg
\97p
\82Ì
\82æ
\82¤
\82¾
\81D
\8aï
\96
\82¾
\81D
\81D
\81D");
1189 levl[dig_x][dig_y].typ = ROOM;
1190 del_engr_at(dig_x, dig_y);
1191 newsym(dig_x, dig_y);
1199 const char *sdp, *verb;
1200 char *dsp, dirsyms[12], qbuf[BUFSZ];
1202 int rx, ry, downok, res = 0;
1206 if (!wield_tool(obj, "swing"))
1211 ispick = is_pick(obj);
1213 verb = ispick ? "dig" : "chop";
1215 verb = ispick ? "
\8c@
\82é" : "
\8dÓ
\82";
1217 if (u.utrap && u.utraptype == TT_WEB) {
1219 pline("%s you can't %s while entangled in a web.",
1220 /* res==0 => no prior message;
1221 res==1 => just got "You now wield a pick-axe." message */
1222 !res ? "Unfortunately," : "But", verb);
1224 pline("%s
\82
\82à
\82Ì
\91\83\82É
\82Ð
\82Á
\82©
\82©
\82Á
\82Ä
\82¢
\82é
\8aÔ
\82Í%s
\81D",
1225 !res ? "
\8ec
\94O
\82È
\82ª
\82ç" : "
\82µ
\82©
\82µ", jconj(verb, "
\82È
\82¢"));
1230 /* construct list of directions to show player for likely choices */
1231 downok = !!can_reach_floor(FALSE);
1233 for (sdp = Cmd.dirchars; *sdp; ++sdp) {
1234 /* filter out useless directions */
1236 ; /* all directions are viable when swallowed */
1237 } else if (movecmd(*sdp)) {
1238 /* normal direction, within plane of the level map;
1239 movecmd() sets u.dx, u.dy, u.dz and returns !u.dz */
1241 continue; /* handle NODIAG */
1244 if (!isok(rx, ry) || dig_typ(obj, rx, ry) == DIGTYP_UNDIGGABLE)
1247 /* up or down; we used to always include down, so that
1248 there would always be at least one choice shown, but
1249 it shouldn't be a likely candidate when floating high
1250 above the floor; include up instead in that situation
1251 (as a silly candidate rather than a likely one...) */
1252 if ((u.dz > 0) ^ downok)
1255 /* include this direction */
1260 Sprintf(qbuf, "In what direction do you want to %s? [%s]", verb, dirsyms);
1262 Sprintf(qbuf, "
\82Ç
\82Ì
\95û
\8cü
\82ð%s
\81H[%s]", verb, dirsyms);
1266 return use_pick_axe2(obj);
1269 /* MRKR: use_pick_axe() is split in two to allow autodig to bypass */
1270 /* the "In what direction do you want to dig?" query. */
1271 /* use_pick_axe2() uses the existing u.dx, u.dy and u.dz */
1276 register int rx, ry;
1277 register struct rm *lev;
1278 struct trap *trap, *trap_with_u;
1280 boolean ispick = is_pick(obj);
1282 const char *verbing = ispick ? "digging" : "chopping";
1284 const char *verbing = ispick ? "
\8c@
\82é" : "
\8dÓ
\82";
1286 if (u.uswallow && attack(u.ustuck)) {
1288 } else if (Underwater) {
1290 pline("Turbulence torpedoes your %s attempts.", verbing);
1292 pline("%s
\82Æ
\82·
\82é
\82Æ
\97\90\90\85\97¬
\82ª
\8bN
\82«
\82½
\81D", jconj(verbing, "
\82æ
\82¤"));
1293 } else if (u.dz < 0) {
1296 You("don't have enough leverage.");
1298 You("
\95\82\82¢
\82Ä
\82¢
\82é
\82Ì
\82Å
\82Ó
\82ñ
\82Î
\82è
\82ª
\82«
\82©
\82È
\82¢
\81D");
1301 You_cant("reach the %s.", ceiling(u.ux, u.uy));
1303 You("%s
\82É
\93Í
\82©
\82È
\82¢
\81D", ceiling(u.ux,u.uy));
1304 } else if (!u.dx && !u.dy && !u.dz) {
1308 dam = rnd(2) + dbon() + obj->spe;
1312 You("hit yourself with %s.", yname(uwep));
1314 You("
\8e©
\95ª
\8e©
\90g
\82ð%s
\82Å
\92@
\82¢
\82½
\81D", yname(uwep));
1316 Sprintf(buf, "%s own %s", uhis(), OBJ_NAME(objects[obj->otyp]));
1318 Sprintf(buf, "
\8e©
\95ª
\8e©
\90g
\82ð%s
\82Å
\92@
\82¢
\82Ä", yname(uwep));
1319 losehp(Maybe_Half_Phys(dam), buf, KILLED_BY);
1322 } else if (u.dz == 0) {
1323 if (Stunned || (Confusion && !rn2(5)))
1327 if (!isok(rx, ry)) {
1331 pline("
\83K
\83\89\83K
\83\89\81I");
1334 lev = &levl[rx][ry];
1335 if (MON_AT(rx, ry) && attack(m_at(rx, ry)))
1337 dig_target = dig_typ(obj, rx, ry);
1338 if (dig_target == DIGTYP_UNDIGGABLE) {
1339 /* ACCESSIBLE or POOL */
1340 trap = t_at(rx, ry);
1341 if (trap && trap->ttyp == WEB) {
1345 There("is a spider web there!");
1347 pline("
\82»
\82±
\82É
\82Í
\82
\82à
\82Ì
\91\83\82ª
\82 \82é
\81I");
1350 pline("%s entangled in the web.", Yobjnam2(obj, "become"));
1352 Your("%s
\82Í
\82
\82à
\82Ì
\91\83\82É
\82©
\82ç
\82Ü
\82Á
\82½
\81D", xname(obj));
1353 /* you ought to be able to let go; tough luck */
1354 /* (maybe `move_into_trap()' would be better) */
1357 multi_reason = "stuck in a spider web";
1359 multi_reason = "
\82
\82à
\82Ì
\91\83\82É
\95ß
\82Ü
\82Á
\82Ä
\82¢
\82é
\8aÔ
\82É";
1361 nomovemsg = "You pull free.";
1363 nomovemsg = "
\82Ð
\82«
\82Í
\82È
\82µ
\82½
\81D";
1364 } else if (lev->typ == IRONBARS) {
1368 pline("
\83K
\83c
\83\93\81I");
1370 } else if (IS_TREE(lev->typ)) {
1372 You("need an axe to cut down a tree.");
1374 You("
\96Ø
\82ð
\90Ø
\82é
\82É
\82Í
\95\80\82ª
\95K
\97v
\82¾
\81D");
1375 } else if (IS_ROCK(lev->typ)) {
1377 You("need a pick to dig rock.");
1379 You("
\8c@
\82é
\82É
\82Í
\82Â
\82é
\82Í
\82µ
\82ª
\95K
\97v
\82¾
\81D");
1380 } else if (!ispick && (sobj_at(STATUE, rx, ry)
1381 || sobj_at(BOULDER, rx, ry))) {
1382 boolean vibrate = !rn2(3);
1385 pline("Sparks fly as you whack the %s.%s",
1386 sobj_at(STATUE, rx, ry) ? "statue" : "boulder",
1387 vibrate ? " The axe-handle vibrates violently!" : "");
1389 pline("%s
\82ð
\90Ø
\82ë
\82¤
\82Æ
\82µ
\82½
\82ç
\89Î
\89Ô
\82ª
\8eU
\82Á
\82½
\81I%s",
1390 sobj_at(STATUE, rx, ry) ? "
\92¤
\91\9c" : "
\8aâ",
1391 vibrate ? "
\95\80\82Í
\8c\83\82µ
\82
\90U
\93®
\82µ
\82½
\81I" : "");
1395 losehp(Maybe_Half_Phys(2), "axing a hard object",
1397 losehp(Maybe_Half_Phys(2), "
\8cÅ
\82¢
\82à
\82Ì
\82É
\95\80\82ð
\8eg
\82¨
\82¤
\82Æ
\82µ
\82Ä",
1399 } else if (u.utrap && u.utraptype == TT_PIT && trap
1400 && (trap_with_u = t_at(u.ux, u.uy))
1401 && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)
1402 && !conjoined_pits(trap, trap_with_u, FALSE)) {
1405 for (idx = 0; idx < 8; idx++) {
1406 if (xdir[idx] == u.dx && ydir[idx] == u.dy)
1409 /* idx is valid if < 8 */
1411 int adjidx = (idx + 4) % 8;
1413 trap_with_u->conjoined |= (1 << idx);
1414 trap->conjoined |= (1 << adjidx);
1416 pline("You clear some debris from between the pits.");
1418 pline("
\82 \82È
\82½
\82Í
\97\8e\82µ
\8c\8a\82Ì
\8aÔ
\82©
\82ç
\82²
\82Ý
\82ð
\8eæ
\82è
\82Ì
\82¼
\82¢
\82½
\81D");
1420 } else if (u.utrap && u.utraptype == TT_PIT
1421 && (trap_with_u = t_at(u.ux, u.uy))) {
1423 You("swing %s, but the rubble has no place to go.",
1424 yobjnam(obj, (char *) 0));
1426 You("%s
\82ð
\90U
\82è
\89ñ
\82µ
\82½
\82ª
\81C
\94j
\95Ð
\82Ì
\8ds
\82«
\8fê
\8f\8a\82ª
\82È
\82¢
\81D", xname(obj));
1430 You("swing %s through thin air.", yobjnam(obj, (char *) 0));
1432 You("
\8bó
\92\86\82Å%s
\82ð
\90U
\82è
\89ñ
\82µ
\82½
\81D", xname(obj));
1436 static const char *const d_action[6] = { "swinging", "digging",
1437 "chipping the statue",
1438 "hitting the boulder",
1439 "chopping at the door",
1440 "cutting the tree" };
1442 static const char * const d_action1[6] = {
1445 "
\92¤
\91\9c\82ð
\8dí
\82è",
1446 "
\8aâ
\82ð
\91Å
\82¿
\82Â
\82¯",
1450 static const char * const d_action2[6] = {
1453 "
\92¤
\91\9c\82ð
\8dí
\82é",
1454 "
\8aâ
\82ð
\91Å
\82¿
\82Â
\82¯
\82é",
1460 did_dig_msg = FALSE;
1461 context.digging.quiet = FALSE;
1462 if (context.digging.pos.x != rx || context.digging.pos.y != ry
1463 || !on_level(&context.digging.level, &u.uz)
1464 || context.digging.down) {
1465 if (flags.autodig && dig_target == DIGTYP_ROCK
1466 && !context.digging.down
1467 && context.digging.pos.x == u.ux
1468 && context.digging.pos.y == u.uy
1469 && (moves <= context.digging.lastdigtime + 2
1470 && moves >= context.digging.lastdigtime)) {
1471 /* avoid messages if repeated autodigging */
1473 context.digging.quiet = TRUE;
1475 context.digging.down = context.digging.chew = FALSE;
1476 context.digging.warned = FALSE;
1477 context.digging.pos.x = rx;
1478 context.digging.pos.y = ry;
1479 assign_level(&context.digging.level, &u.uz);
1480 context.digging.effort = 0;
1481 if (!context.digging.quiet)
1483 You("start %s.", d_action[dig_target]);
1485 You("%s
\82Í
\82¶
\82ß
\82½
\81D", d_action1[dig_target]);
1488 You("%s %s.", context.digging.chew ? "begin" : "continue",
1489 d_action[dig_target]);
1491 You("%s
\82Ì
\82ð%s
\82µ
\82½
\81D", d_action2[dig_target],
1492 context.digging.chew ? "
\8aJ
\8en" : "
\8dÄ
\8aJ");
1494 context.digging.chew = FALSE;
1496 set_occupation(dig, verbing, 0);
1498 } else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
1499 /* it must be air -- water checked above */
1501 You("swing %s through thin air.", yobjnam(obj, (char *) 0));
1503 You("
\89½
\82à
\82È
\82¢
\8bó
\8aÔ
\82Å%s
\82ð
\90U
\82è
\82Ü
\82í
\82µ
\82½
\81D", xname(obj));
1504 } else if (!can_reach_floor(FALSE)) {
1505 cant_reach_floor(u.ux, u.uy, FALSE, FALSE);
1506 } else if (is_pool_or_lava(u.ux, u.uy)) {
1507 /* Monsters which swim also happen not to be able to dig */
1509 You("cannot stay under%s long enough.",
1510 is_pool(u.ux, u.uy) ? "water" : " the lava");
1512 You("%s
\82É
\82Í
\92·
\8e\9e\8aÔ
\82¢
\82ç
\82ê
\82È
\82¢
\81D",
1513 is_pool(u.ux, u.uy) ? "
\90\85\96Ê
\89º" : "
\97n
\8aâ
\82Ì
\92\86");
1515 } else if ((trap = t_at(u.ux, u.uy)) != 0
1516 && uteetering_at_seen_pit(trap)) {
1517 dotrap(trap, FORCEBUNGLE);
1518 /* might escape trap and still be teetering at brink */
1520 cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
1522 /* can only dig down with an axe when doing so will
1523 trigger or disarm a trap here */
1524 && (!trap || (trap->ttyp != LANDMINE
1525 && trap->ttyp != BEAR_TRAP))) {
1527 pline("%s merely scratches the %s.", Yobjnam2(obj, (char *) 0),
1528 surface(u.ux, u.uy));
1530 Your("%s
\82Í%s
\82É
\82©
\82·
\82è
\8f\9d\82ð
\82Â
\82¯
\82½
\82¾
\82¯
\82¾
\82Á
\82½
\81D", aobjnam(obj, (char *)0),
1531 surface(u.ux,u.uy));
1535 if (context.digging.pos.x != u.ux || context.digging.pos.y != u.uy
1536 || !on_level(&context.digging.level, &u.uz)
1537 || !context.digging.down) {
1538 context.digging.chew = FALSE;
1539 context.digging.down = TRUE;
1540 context.digging.warned = FALSE;
1541 context.digging.pos.x = u.ux;
1542 context.digging.pos.y = u.uy;
1543 assign_level(&context.digging.level, &u.uz);
1544 context.digging.effort = 0;
1546 You("start %s downward.", verbing);
1548 You("
\89º
\8cü
\82«
\82É
\8c@
\82è
\82Í
\82¶
\82ß
\82½
\81D");
1553 You("continue %s downward.", verbing);
1555 You("
\89º
\8cü
\82«
\82É
\8c@
\82é
\82Ì
\82ð
\8dÄ
\8aJ
\82µ
\82½
\81D");
1556 did_dig_msg = FALSE;
1557 set_occupation(dig, verbing, 0);
1563 * Town Watchmen frown on damage to the town walls, trees or fountains.
1564 * It's OK to dig holes in the ground, however.
1565 * If mtmp is assumed to be a watchman, a watchman is found if mtmp == 0
1566 * zap == TRUE if wand/spell of digging, FALSE otherwise (chewing)
1569 watch_dig(mtmp, x, y, zap)
1574 struct rm *lev = &levl[x][y];
1577 && (closed_door(x, y) || lev->typ == SDOOR || IS_WALL(lev->typ)
1578 || IS_FOUNTAIN(lev->typ) || IS_TREE(lev->typ))) {
1580 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1581 if (DEADMONSTER(mtmp))
1583 if (is_watch(mtmp->data) && mtmp->mcansee && m_canseeu(mtmp)
1584 && couldsee(mtmp->mx, mtmp->my) && mtmp->mpeaceful)
1590 if (zap || context.digging.warned) {
1592 verbalize("Halt, vandal! You're under arrest!");
1594 verbalize("
\8e~
\82Ü
\82ê
\96ì
\94Ø
\90l
\81I
\82¨
\82Ü
\82¦
\82ð
\91ß
\95ß
\82·
\82é
\81I");
1595 (void) angry_guards(!!Deaf);
1599 if (IS_DOOR(lev->typ))
1604 else if (IS_TREE(lev->typ))
1609 else if (IS_ROCK(lev->typ))
1620 verbalize("Hey, stop damaging that %s!", str);
1622 verbalize("
\82¨
\82¢
\81C%s
\82ð
\94j
\89ó
\82·
\82é
\82Ì
\82ð
\82â
\82ß
\82ë
\81I", str);
1623 context.digging.warned = TRUE;
1631 /* Return TRUE if monster died, FALSE otherwise. Called from m_move(). */
1634 register struct monst *mtmp;
1636 register struct rm *here;
1639 here = &levl[mtmp->mx][mtmp->my];
1640 if (here->typ == SDOOR)
1641 cvt_sdoor_to_door(here); /* ->typ = DOOR */
1643 /* Eats away door if present & closed or locked */
1644 if (closed_door(mtmp->mx, mtmp->my)) {
1645 if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
1646 add_damage(mtmp->mx, mtmp->my, 0L);
1647 unblock_point(mtmp->mx, mtmp->my); /* vision */
1648 if (here->doormask & D_TRAPPED) {
1649 here->doormask = D_NODOOR;
1650 if (mb_trapped(mtmp)) { /* mtmp is killed */
1651 newsym(mtmp->mx, mtmp->my);
1655 if (!rn2(3) && flags.verbose) /* not too often.. */
1656 draft_message(TRUE); /* "You feel an unexpected draft." */
1657 here->doormask = D_BROKEN;
1659 newsym(mtmp->mx, mtmp->my);
1661 } else if (here->typ == SCORR) {
1663 unblock_point(mtmp->mx, mtmp->my);
1664 newsym(mtmp->mx, mtmp->my);
1665 draft_message(FALSE); /* "You feel a draft." */
1667 } else if (!IS_ROCK(here->typ) && !IS_TREE(here->typ)) { /* no dig */
1671 /* Only rock, trees, and walls fall through to this point. */
1672 if ((here->wall_info & W_NONDIGGABLE) != 0) {
1673 impossible("mdig_tunnel: %s at (%d,%d) is undiggable",
1674 (IS_WALL(here->typ) ? "wall"
1675 : IS_TREE(here->typ) ? "tree" : "stone"),
1676 (int) mtmp->mx, (int) mtmp->my);
1677 return FALSE; /* still alive */
1680 if (IS_WALL(here->typ)) {
1681 /* KMH -- Okay on arboreal levels (room walls are still stone) */
1682 if (flags.verbose && !rn2(5))
1684 You_hear("crashing rock.");
1686 You_hear("
\8aâ
\82Ì
\82
\82¾
\82¯
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1687 if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
1688 add_damage(mtmp->mx, mtmp->my, 0L);
1689 if (level.flags.is_maze_lev) {
1691 } else if (level.flags.is_cavernous_lev
1692 && !in_town(mtmp->mx, mtmp->my)) {
1696 here->doormask = D_NODOOR;
1698 } else if (IS_TREE(here->typ)) {
1700 if (pile && pile < 5)
1701 (void) rnd_treefruit_at(mtmp->mx, mtmp->my);
1704 if (pile && pile < 5)
1705 (void) mksobj_at((pile == 1) ? BOULDER : ROCK, mtmp->mx, mtmp->my,
1708 newsym(mtmp->mx, mtmp->my);
1709 if (!sobj_at(BOULDER, mtmp->mx, mtmp->my))
1710 unblock_point(mtmp->mx, mtmp->my); /* vision */
1715 #define STRIDENT 4 /* from pray.c */
1717 /* draft refers to air currents, but can be a pun on "draft" as conscription
1718 for military service (probably not a good pun if it has to be explained) */
1720 draft_message(unexpected)
1724 * [Bug or TODO? Have caller pass coordinates and use the travel
1725 * mechanism to determine whether there is a path between
1726 * destroyed door (or exposed secret corridor) and hero's location.
1727 * When there is no such path, no draft should be felt.]
1733 You_feel("an unexpected draft.");
1735 You("
\8ev
\82¢
\82à
\82æ
\82ç
\82¸
\81C
\82·
\82«
\82Ü
\95\97\82ð
\8a´
\82¶
\82½
\81D");
1737 /* U.S. classification system uses 1-A for eligible to serve
1738 and 4-F for ineligible due to physical or mental defect;
1739 some intermediate values exist but are rarely seen */
1741 You_feel("like you are %s.",
1742 (ACURR(A_STR) < 6 || ACURR(A_DEX) < 6
1743 || ACURR(A_CON) < 6 || ACURR(A_CHA) < 6
1744 || ACURR(A_INT) < 6 || ACURR(A_WIS) < 6) ? "4-F"
1747 You("
\93Ë
\91R
\90\99\97Ç
\91¾
\98Y
\82ð
\8ev
\82¢
\8fo
\82µ
\82½
\81D");
1750 if (!Hallucination) {
1752 You_feel("a draft.");
1754 You_feel("
\82·
\82«
\82Ü
\95\97\82ð
\8a´
\82¶
\82½
\81D");
1756 #if 0 /*JP*//*"draft"=
\81u
\92¥
\95º
\81v*/
1757 /* "marching" is deliberately ambiguous; it might mean drills
1758 after entering military service or mean engaging in protests */
1759 static const char *draft_reaction[] = {
1760 "enlisting", "marching", "protesting", "fleeing",
1764 /* Lawful: 0..1, Neutral: 1..2, Chaotic: 2..3 */
1765 dridx = rn1(2, 1 - sgn(u.ualign.type));
1766 if (u.ualign.record < STRIDENT)
1767 /* L: +(0..2), N: +(-1..1), C: +(-2..0); all: 0..3 */
1768 dridx += rn1(3, sgn(u.ualign.type) - 1);
1769 You_feel("like %s.", draft_reaction[dridx]);
1770 #else /*JP:
\93ú
\96{
\8cê
\82Å
\82Í
\8bÃ
\82Á
\82½
\82±
\82Æ
\82Í
\82µ
\82È
\82¢*/
1771 You("
\90\99\97Ç
\91¾
\98Y
\82ð
\8ev
\82¢
\8fo
\82µ
\82½
\81D");
1777 /* digging via wand zap or spell cast */
1784 struct trap *trap_with_u = (struct trap *) 0;
1785 int zx, zy, diridx = 8, digdepth, flow_x = -1, flow_y = -1;
1786 boolean shopdoor, shopwall, maze_dig, pitdig = FALSE, pitflow = FALSE;
1789 * Original effect (approximately):
1790 * from CORR: dig until we pierce a wall
1791 * from ROOM: pierce wall and dig until we reach
1792 * an ACCESSIBLE place.
1793 * Currently: dig for digdepth positions;
1794 * also down on request of Lennart Augustsson.
1795 * 3.6.0: from a PIT: dig one adjacent pit.
1801 if (!is_whirly(mtmp->data)) {
1802 if (is_animal(mtmp->data))
1804 You("pierce %s %s wall!", s_suffix(mon_nam(mtmp)),
1805 mbodypart(mtmp, STOMACH));
1807 You("%s
\82Ì%s
\82Ì
\95Ç
\82É
\8c\8a\82ð
\8aJ
\82¯
\82½
\81I", mon_nam(mtmp),
1808 mbodypart(mtmp, STOMACH));
1810 mtmp->mhp = 1; /* almost dead */
1811 expels(mtmp, mtmp->data, !is_animal(mtmp->data));
1817 if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !Underwater) {
1818 if (u.dz < 0 || On_stairs(u.ux, u.uy)) {
1820 if (On_stairs(u.ux, u.uy))
1822 pline_The("beam bounces off the %s and hits the %s.",
1823 (u.ux == xdnladder || u.ux == xupladder)
1826 ceiling(u.ux, u.uy));
1828 pline("
\8cõ
\90ü
\82Í%s
\82Å
\94½
\8eË
\82µ%s
\82É
\96½
\92\86\82µ
\82½
\81D",
1829 (u.ux == xdnladder || u.ux == xupladder)
1832 ceiling(u.ux, u.uy));
1835 You("loosen a rock from the %s.", ceiling(u.ux, u.uy));
1837 pline("%s
\82Ì
\8aâ
\82ª
\83K
\83^
\83K
\83^
\82µ
\82Í
\82¶
\82ß
\82½
\81D", ceiling(u.ux, u.uy));
1839 pline("It falls on your %s!", body_part(HEAD));
1841 pline("
\82»
\82ê
\82Í
\82 \82È
\82½
\82Ì%s
\82É
\97\8e\82¿
\82Ä
\82«
\82½
\81I", body_part(HEAD));
1842 dmg = rnd((uarmh && is_metallic(uarmh)) ? 2 : 6);
1844 losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
1846 losehp(Maybe_Half_Phys(dmg), "
\97\8e\8aâ
\82Å", KILLED_BY_AN);
1847 otmp = mksobj_at(ROCK, u.ux, u.uy, FALSE, FALSE);
1849 (void) xname(otmp); /* set dknown, maybe bknown */
1854 watch_dig((struct monst *) 0, u.ux, u.uy, TRUE);
1855 (void) dighole(FALSE, TRUE, (coord *) 0);
1861 /* normal case: digging across the level */
1862 shopdoor = shopwall = FALSE;
1863 maze_dig = level.flags.is_maze_lev && !Is_earthlevel(&u.uz);
1866 if (u.utrap && u.utraptype == TT_PIT
1867 && (trap_with_u = t_at(u.ux, u.uy))) {
1869 for (diridx = 0; diridx < 8; diridx++) {
1870 if (xdir[diridx] == u.dx && ydir[diridx] == u.dy)
1872 /* diridx is valid if < 8 */
1875 digdepth = rn1(18, 8);
1876 tmp_at(DISP_BEAM, cmap_to_glyph(S_digbeam));
1877 while (--digdepth >= 0) {
1880 room = &levl[zx][zy];
1882 delay_output(); /* wait a little bit */
1884 if (pitdig) { /* we are already in a pit if this is true */
1886 struct trap *adjpit = t_at(zx, zy);
1887 if ((diridx < 8) && !conjoined_pits(adjpit, trap_with_u, FALSE)) {
1888 digdepth = 0; /* limited to the adjacent location only */
1889 if (!(adjpit && (adjpit->ttyp == PIT
1890 || adjpit->ttyp == SPIKED_PIT))) {
1894 if (!adj_pit_checks(&cc, buf)) {
1898 /* this can also result in a pool at zx,zy */
1899 dighole(TRUE, TRUE, &cc);
1900 adjpit = t_at(zx, zy);
1904 && (adjpit->ttyp == PIT || adjpit->ttyp == SPIKED_PIT)) {
1905 int adjidx = (diridx + 4) % 8;
1906 trap_with_u->conjoined |= (1 << diridx);
1907 adjpit->conjoined |= (1 << adjidx);
1912 if (is_pool(zx, zy) || is_lava(zx, zy)) {
1919 } else if (closed_door(zx, zy) || room->typ == SDOOR) {
1920 if (*in_rooms(zx, zy, SHOPBASE)) {
1921 add_damage(zx, zy, SHOP_DOOR_COST);
1924 if (room->typ == SDOOR)
1926 else if (cansee(zx, zy))
1928 pline_The("door is razed!");
1930 pline("
\94à
\82Í
\95ö
\82ê
\97\8e\82¿
\82½
\81I");
1931 watch_dig((struct monst *) 0, zx, zy, TRUE);
1932 room->doormask = D_NODOOR;
1933 unblock_point(zx, zy); /* vision */
1937 } else if (maze_dig) {
1938 if (IS_WALL(room->typ)) {
1939 if (!(room->wall_info & W_NONDIGGABLE)) {
1940 if (*in_rooms(zx, zy, SHOPBASE)) {
1941 add_damage(zx, zy, SHOP_WALL_COST);
1945 unblock_point(zx, zy); /* vision */
1948 pline_The("wall glows then fades.");
1950 pline("
\95Ç
\82Í
\88ê
\8fu
\8bP
\82¢
\82½
\81D");
1952 } else if (IS_TREE(room->typ)) { /* check trees before stone */
1953 if (!(room->wall_info & W_NONDIGGABLE)) {
1955 unblock_point(zx, zy); /* vision */
1958 pline_The("tree shudders but is unharmed.");
1960 pline("
\96Ø
\82Í
\82ä
\82ê
\82½
\82ª
\8f\9d\82Â
\82©
\82È
\82©
\82Á
\82½
\81D");
1962 } else if (room->typ == STONE || room->typ == SCORR) {
1963 if (!(room->wall_info & W_NONDIGGABLE)) {
1965 unblock_point(zx, zy); /* vision */
1968 pline_The("rock glows then fades.");
1970 pline("
\90Î
\82Í
\88ê
\8fu
\8bP
\82¢
\82½
\81D");
1973 } else if (IS_ROCK(room->typ)) {
1974 if (!may_dig(zx, zy))
1976 if (IS_WALL(room->typ) || room->typ == SDOOR) {
1977 if (*in_rooms(zx, zy, SHOPBASE)) {
1978 add_damage(zx, zy, SHOP_WALL_COST);
1981 watch_dig((struct monst *) 0, zx, zy, TRUE);
1982 if (level.flags.is_cavernous_lev && !in_town(zx, zy)) {
1986 room->doormask = D_NODOOR;
1989 } else if (IS_TREE(room->typ)) {
1992 } else { /* IS_ROCK but not IS_WALL or SDOOR */
1996 unblock_point(zx, zy); /* vision */
2001 tmp_at(DISP_END, 0); /* closing call */
2003 if (pitflow && isok(flow_x, flow_y)) {
2004 struct trap *ttmp = t_at(flow_x, flow_y);
2005 if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)) {
2006 schar filltyp = fillholetyp(ttmp->tx, ttmp->ty, TRUE);
2007 if (filltyp != ROOM)
2008 pit_flow(ttmp, filltyp);
2012 if (shopdoor || shopwall)
2014 pay_for_damage(shopdoor ? "destroy" : "dig into", FALSE);
2016 pay_for_damage(shopdoor ? "
\94j
\89ó
\82·
\82é" : "
\8c\8a\82ð
\82 \82¯
\82é", FALSE);
2021 * This checks what is on the surface above the
2022 * location where an adjacent pit might be created if
2023 * you're zapping a wand of digging laterally while
2027 adj_pit_checks(cc, msg)
2033 const char *foundation_msg =
2035 "The foundation is too hard to dig through from this angle.";
2037 "
\8aî
\91b
\82Í
\82±
\82Ì
\8ap
\93x
\82©
\82ç
\8c@
\82é
\82É
\82Í
\8cÅ
\82·
\82¬
\82é
\81D";
2041 if (!isok(cc->x, cc->y))
2044 room = &levl[cc->x][cc->y];
2047 if (is_pool(cc->x, cc->y) || is_lava(cc->x, cc->y)) {
2048 /* this is handled by the caller after we return FALSE */
2050 } else if (closed_door(cc->x, cc->y) || room->typ == SDOOR) {
2051 /* We reject this here because dighole() isn't
2052 prepared to deal with this case */
2053 Strcpy(msg, foundation_msg);
2055 } else if (IS_WALL(ltyp)) {
2056 /* if (room->wall_info & W_NONDIGGABLE) */
2057 Strcpy(msg, foundation_msg);
2059 } else if (IS_TREE(ltyp)) { /* check trees before stone */
2060 /* if (room->wall_info & W_NONDIGGABLE) */
2062 Strcpy(msg, "The tree's roots glow then fade.");
2064 Strcpy(msg, "
\96Ø
\82Ì
\8dª
\82Í
\88ê
\8fu
\8bP
\82¢
\82½
\81D");
2066 } else if (ltyp == STONE || ltyp == SCORR) {
2067 if (room->wall_info & W_NONDIGGABLE) {
2069 Strcpy(msg, "The rock glows then fades.");
2071 Strcpy(msg, "
\90Î
\82Í
\88ê
\8fu
\8bP
\82¢
\82½
\81D");
2074 } else if (ltyp == IRONBARS) {
2075 /* "set of iron bars" */
2077 Strcpy(msg, "The bars go much deeper than your pit.");
2079 Strcpy(msg, "
\96_
\82Í
\97\8e\82µ
\8c\8a\82æ
\82è
\97y
\82©
\82É
\90[
\82¢
\82Æ
\82±
\82ë
\82Ü
\82Å
\96\84\82Ü
\82Á
\82Ä
\82¢
\82é
\81D");
2081 } else if (is_lava(cc->x, cc->y)) {
2082 } else if (is_ice(cc->x, cc->y)) {
2083 } else if (is_pool(cc->x, cc->y)) {
2084 } else if (IS_GRAVE(ltyp)) {
2086 } else if (IS_SINK(ltyp)) {
2088 Strcpy(msg, "A tangled mass of plumbing remains below the sink.");
2090 Strcpy(msg, "
\93ü
\82è
\91g
\82ñ
\82¾
\94z
\8aÇ
\82ª
\97¬
\82µ
\91ä
\82Ì
\89º
\82É
\8ec
\82Á
\82½
\82Ü
\82Ü
\82¾
\81D");
2092 } else if ((cc->x == xupladder && cc->y == yupladder) /* ladder up */
2093 || (cc->x == xdnladder && cc->y == ydnladder)) { /* " down */
2095 Strcpy(msg, "The ladder is unaffected.");
2097 Strcpy(msg, "
\82Í
\82µ
\82²
\82Í
\89e
\8b¿
\82ð
\8eó
\82¯
\82È
\82¢
\81D");
2100 const char *supporting = (const char *) 0;
2102 if (IS_FOUNTAIN(ltyp))
2104 supporting = "fountain";
2106 supporting = "
\90ò";
2107 else if (IS_THRONE(ltyp))
2109 supporting = "throne";
2111 supporting = "
\8bÊ
\8dÀ";
2112 else if (IS_ALTAR(ltyp))
2114 supporting = "altar";
2116 supporting = "
\8dÕ
\92d";
2117 else if ((cc->x == xupstair && cc->y == yupstair)
2118 || (cc->x == sstairs.sx && cc->y == sstairs.sy
2120 /* "staircase up" */
2122 supporting = "stairs";
2124 supporting = "
\8aK
\92i";
2125 else if ((cc->x == xdnstair && cc->y == ydnstair)
2126 || (cc->x == sstairs.sx && cc->y == sstairs.sy
2128 /* "staircase down" */
2130 supporting = "stairs";
2132 supporting = "
\8aK
\92i";
2133 else if (ltyp == DRAWBRIDGE_DOWN /* "lowered drawbridge" */
2134 || ltyp == DBWALL) /* "raised drawbridge" */
2136 supporting = "drawbridge";
2138 supporting = "
\92µ
\82Ë
\8b´";
2142 Sprintf(msg, "The %s%ssupporting structures remain intact.",
2143 supporting ? s_suffix(supporting) : "",
2144 supporting ? " " : "");
2146 Sprintf(msg, "%s%s
\8ex
\82¦
\82Ä
\82¢
\82é
\95\94\95ª
\82Í
\82»
\82Ì
\82Ü
\82Ü
\82¾
\81D",
2147 supporting ? supporting : "",
2148 supporting ? "
\82ð" : "");
2157 * Ensure that all conjoined pits fill up.
2160 pit_flow(trap, filltyp)
2164 if (trap && (filltyp != ROOM)
2165 && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
2170 levl[trap->tx][trap->ty].typ = filltyp;
2171 liquid_flow(trap->tx, trap->ty, filltyp, trap,
2172 (trap->tx == u.ux && trap->ty == u.uy)
2174 ? "Suddenly %s flows in from the adjacent pit!"
2176 ? "
\93Ë
\91R
\97×
\82Ì
\97\8e\82µ
\8c\8a\82©
\82ç%s
\82ª
\97¬
\82ê
\8d\9e\82ñ
\82Å
\82«
\82½
\81I"
2178 for (idx = 0; idx < 8; ++idx) {
2179 if (t.conjoined & (1 << idx)) {
2183 x = t.tx + xdir[idx];
2184 y = t.ty + ydir[idx];
2187 /* cannot do this back-check; liquid_flow()
2188 * called deltrap() which cleaned up the
2189 * conjoined fields on both pits.
2191 if (t2 && (t2->conjoined & (1 << ((idx + 4) % 8))))
2194 pit_flow(t2, filltyp);
2204 int odist, bdist = COLNO;
2205 struct obj *otmp, *ball = 0;
2208 * This is just approximate; if multiple buried balls meet the
2209 * criterium (within 2 steps of tethered hero's present location)
2210 * it will find an arbitrary one rather than the one which used
2211 * to be uball. Once 3.6.{0,1} save file compatibility is broken,
2212 * we should add context.buriedball_oid and then we can find the
2213 * actual former uball, which might be extra heavy or christened
2214 * or not the one buried directly underneath the target spot.
2216 * [Why does this search within a radius of two when trapmove()
2217 * only lets hero get one step away from the buried ball?]
2220 if (u.utrap && u.utraptype == TT_BURIEDBALL)
2221 for (otmp = level.buriedobjlist; otmp; otmp = otmp->nobj) {
2222 if (otmp->otyp != HEAVY_IRON_BALL)
2224 /* if found at the target spot, we're done */
2225 if (otmp->ox == cc->x && otmp->oy == cc->y)
2227 /* find nearest within allowable vicinity: +/-2
2232 odist = dist2(otmp->ox, otmp->oy, cc->x, cc->y);
2233 if (odist <= 8 && (!ball || odist < bdist)) {
2234 /* remember nearest buried ball but keep checking others */
2240 /* found, but not at < cc->x, cc->y > */
2248 buried_ball_to_punishment()
2255 ball = buried_ball(&cc);
2257 obj_extract_self(ball);
2259 /* rusting buried metallic objects is not implemented yet */
2261 (void) stop_timer(RUST_METAL, obj_to_any(ball));
2263 punish(ball); /* use ball as flag for unearthed buried ball */
2266 del_engr_at(cc.x, cc.y);
2272 buried_ball_to_freedom()
2279 ball = buried_ball(&cc);
2281 obj_extract_self(ball);
2283 /* rusting buried metallic objects is not implemented yet */
2285 (void) stop_timer(RUST_METAL, obj_to_any(ball));
2287 place_object(ball, cc.x, cc.y);
2291 del_engr_at(cc.x, cc.y);
2296 /* move objects from fobj/nexthere lists to buriedobjlist, keeping position
2299 bury_an_obj(otmp, dealloced)
2306 debugpline1("bury_an_obj: %s", xname(otmp));
2309 if (otmp == uball) {
2311 u.utrap = rn1(50, 20);
2312 u.utraptype = TT_BURIEDBALL;
2314 pline_The("iron ball gets buried!");
2316 pline_The("
\93S
\82Ì
\8b\85\82Í
\96\84\82Ü
\82Á
\82½
\81I");
2318 /* after unpunish(), or might get deallocated chain */
2319 otmp2 = otmp->nexthere;
2321 * obj_resists(,0,0) prevents Rider corpses from being buried.
2322 * It also prevents The Amulet and invocation tools from being
2323 * buried. Since they can't be confined to bags and statues,
2324 * it makes sense that they can't be buried either, even though
2325 * the real reason there (direct accessibility when carried) is
2326 * completely different.
2328 if (otmp == uchain || obj_resists(otmp, 0, 0))
2331 if (otmp->otyp == LEASH && otmp->leashmon != 0)
2334 if (otmp->lamplit && otmp->otyp != POT_OIL)
2335 end_burn(otmp, TRUE);
2337 obj_extract_self(otmp);
2339 under_ice = is_ice(otmp->ox, otmp->oy);
2340 if (otmp->otyp == ROCK && !under_ice) {
2341 /* merges into burying material */
2344 obfree(otmp, (struct obj *) 0);
2348 * Start a rot on organic material. Not corpses -- they
2349 * are already handled.
2351 if (otmp->otyp == CORPSE) {
2352 ; /* should cancel timer if under_ice */
2353 } else if ((under_ice ? otmp->oclass == POTION_CLASS : is_organic(otmp))
2354 && !obj_resists(otmp, 5, 95)) {
2355 (void) start_timer((under_ice ? 0L : 250L) + (long) rnd(250),
2356 TIMER_OBJECT, ROT_ORGANIC, obj_to_any(otmp));
2358 /* rusting of buried metal not yet implemented */
2359 } else if (is_rustprone(otmp)) {
2360 (void) start_timer((long) rnd((otmp->otyp == HEAVY_IRON_BALL)
2363 TIMER_OBJECT, RUST_METAL, obj_to_any(otmp));
2366 add_to_buried(otmp);
2374 struct obj *otmp, *otmp2;
2379 costly = ((shkp = shop_keeper(*in_rooms(x, y, SHOPBASE)))
2380 && costly_spot(x, y));
2382 if (level.objects[x][y] != (struct obj *) 0) {
2383 debugpline2("bury_objs: at <%d,%d>", x, y);
2385 for (otmp = level.objects[x][y]; otmp; otmp = otmp2) {
2387 loss += stolen_value(otmp, x, y, (boolean) shkp->mpeaceful, TRUE);
2388 if (otmp->oclass != COIN_CLASS)
2389 otmp->no_charge = 1;
2391 otmp2 = bury_an_obj(otmp, (boolean *) 0);
2394 /* don't expect any engravings here, but just in case */
2398 if (costly && loss) {
2400 You("owe %s %ld %s for burying merchandise.", mon_nam(shkp), loss,
2403 You("
\96\84\82Ü
\82Á
\82½
\8f¤
\95i
\82É
\8aÖ
\82µ
\82Ä%s
\82É%ld%s
\82Ì
\95\89\8dÂ
\82ð
\95\89\82Á
\82½
\81D", mon_nam(shkp), loss,
2409 /* move objects from buriedobjlist to fobj/nexthere lists */
2414 struct obj *otmp, *otmp2, *bball;
2417 debugpline2("unearth_objs: at <%d,%d>", x, y);
2420 bball = buried_ball(&cc);
2421 for (otmp = level.buriedobjlist; otmp; otmp = otmp2) {
2423 if (otmp->ox == x && otmp->oy == y) {
2424 if (bball && otmp == bball
2425 && u.utrap && u.utraptype == TT_BURIEDBALL) {
2426 buried_ball_to_punishment();
2428 obj_extract_self(otmp);
2430 (void) stop_timer(ROT_ORGANIC, obj_to_any(otmp));
2431 place_object(otmp, x, y);
2441 * The organic material has rotted away while buried. As an expansion,
2442 * we could add add partial damage. A damage count is kept in the object
2443 * and every time we are called we increment the count and reschedule another
2444 * timeout. Eventually the object rots away.
2446 * This is used by buried objects other than corpses. When a container rots
2447 * away, any contents become newly buried objects.
2451 rot_organic(arg, timeout)
2453 long timeout UNUSED;
2455 struct obj *obj = arg->a_obj;
2457 while (Has_contents(obj)) {
2458 /* We don't need to place contained object on the floor
2459 first, but we do need to update its map coordinates. */
2460 obj->cobj->ox = obj->ox, obj->cobj->oy = obj->oy;
2461 /* Everything which can be held in a container can also be
2462 buried, so bury_an_obj's use of obj_extract_self insures
2463 that Has_contents(obj) will eventually become false. */
2464 (void) bury_an_obj(obj->cobj, (boolean *) 0);
2466 obj_extract_self(obj);
2467 obfree(obj, (struct obj *) 0);
2471 * Called when a corpse has rotted completely away.
2474 rot_corpse(arg, timeout)
2479 struct obj *obj = arg->a_obj;
2480 boolean on_floor = obj->where == OBJ_FLOOR,
2481 in_invent = obj->where == OBJ_INVENT;
2486 } else if (in_invent) {
2487 if (flags.verbose) {
2488 char *cname = corpse_xname(obj, (const char *) 0, CXN_NO_PFX);
2491 Your("%s%s %s away%c", obj == uwep ? "wielded " : "", cname,
2492 otense(obj, "rot"), obj == uwep ? '!' : '.');
2494 pline("
\82 \82È
\82½
\82Ì%s%s
\82Í
\95\85\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½%s",
2495 obj == uwep ? "
\8eè
\82É
\82µ
\82Ä
\82¢
\82é" : "", cname,
2496 obj == uwep ? "
\81I" : "
\81D");
2500 uwepgone(); /* now bare handed */
2502 } else if (obj == uswapwep) {
2505 } else if (obj == uquiver) {
2509 } else if (obj->where == OBJ_MINVENT && obj->owornmask) {
2510 if (obj == MON_WEP(obj->ocarry))
2511 setmnotwielded(obj->ocarry, obj);
2512 } else if (obj->where == OBJ_MIGRATING) {
2513 /* clear destination flag so that obfree()'s check for
2514 freeing a worn object doesn't get a false hit */
2515 obj->owornmask = 0L;
2517 rot_organic(arg, timeout);
2519 struct monst *mtmp = m_at(x, y);
2521 /* a hiding monster may be exposed */
2522 if (mtmp && !OBJ_AT(x, y) && mtmp->mundetected
2523 && hides_under(mtmp->data)) {
2524 mtmp->mundetected = 0;
2525 } else if (x == u.ux && y == u.uy && u.uundetected && hides_under(youmonst.data))
2526 (void) hideunder(&youmonst);
2528 } else if (in_invent)
2537 debugpline1("bury_monst: %s", mon_nam(mtmp));
2538 if (canseemon(mtmp)) {
2539 if (is_flyer(mtmp->data) || is_floater(mtmp->data)) {
2540 pline_The("%s opens up, but %s is not swallowed!",
2541 surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
2544 pline_The("%s opens up and swallows %s!",
2545 surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
2548 mtmp->mburied = TRUE;
2549 wakeup(mtmp, FALSE); /* at least give it a chance :-) */
2550 newsym(mtmp->mx, mtmp->my);
2556 debugpline0("bury_you");
2557 if (!Levitation && !Flying) {
2560 You_feel("a sensation like falling into a trap!");
2562 You("ã©
\82É
\97\8e\82¿
\82é
\82æ
\82¤
\82È
\8a´
\8ao
\82É
\82¨
\82»
\82í
\82ê
\82½
\81I");
2565 pline_The("%s opens beneath you and you fall in!",
2567 pline("%s
\82ª
\89º
\95û
\82É
\8aJ
\82«
\81C
\82 \82È
\82½
\82Í
\97\8e\82¿
\82½
\81I",
2568 surface(u.ux, u.uy));
2571 if (!Strangled && !Breathless)
2580 debugpline0("unearth_you");
2583 if (!uamul || uamul->otyp != AMULET_OF_STRANGULATION)
2591 debugpline0("escape_tomb");
2592 if ((Teleportation || can_teleport(youmonst.data))
2593 && (Teleport_control || rn2(3) < Luck+2)) {
2595 You("attempt a teleport spell.");
2597 You("
\8fu
\8aÔ
\88Ú
\93®
\82ð
\8e\8e\82Ý
\82½
\81D");
2598 (void) dotele(); /* calls unearth_you() */
2599 } else if (u.uburied) { /* still buried after 'port attempt */
2602 if (amorphous(youmonst.data) || Passes_walls
2603 || noncorporeal(youmonst.data)
2604 || (unsolid(youmonst.data)
2605 && youmonst.data != &mons[PM_WATER_ELEMENTAL])
2606 || (tunnels(youmonst.data) && !needspick(youmonst.data))) {
2608 You("%s up through the %s.",
2609 (tunnels(youmonst.data) && !needspick(youmonst.data))
2611 : (amorphous(youmonst.data))
2614 surface(u.ux, u.uy));
2616 You("%s
\82É%s
\82ë
\82¤
\82Æ
\82µ
\82½
\81D",
2617 surface(u.ux, u.uy),
2618 (tunnels(youmonst.data) && !needspick(youmonst.data))
2619 ? "
\83g
\83\93\83l
\83\8b\82ð
\8c@"
2620 : (amorphous(youmonst.data))
2621 ? "
\82É
\82¶
\82Ý
\82Ì
\82Ú"
2622 : "
\8f\99\81X
\82É
\82Í
\82¢
\82 \82ª");
2625 good = (tunnels(youmonst.data) && !needspick(youmonst.data))
2626 ? dighole(TRUE, FALSE, (coord *)0) : TRUE;
2637 debugpline0("bury_obj");
2638 if (cansee(otmp->ox, otmp->oy))
2640 pline_The("objects on the %s tumble into a hole!",
2642 pline_The("%s
\82Ì
\95¨
\91Ì
\82Í
\8c\8a\82É
\93]
\82ª
\82Á
\82½
\81I",
2643 surface(otmp->ox, otmp->oy));
2645 bury_objs(otmp->ox, otmp->oy);
2650 /* bury everything at your loc and around */
2652 wiz_debug_cmd_bury()
2656 for (x = u.ux - 1; x <= u.ux + 1; x++)
2657 for (y = u.uy - 1; y <= u.uy + 1; y++)