OSDN Git Service

patch artifact
[jnethack/source.git] / src / dig.c
1 /* NetHack 3.6  dig.c   $NHDT-Date: 1449269915 2015/12/04 22:58:35 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.103 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016            */
8 /* JNetHack may be freely redistributed.  See license for details. */
9
10 #include "hack.h"
11
12 static NEARDATA boolean did_dig_msg;
13
14 STATIC_DCL boolean NDECL(rm_waslit);
15 STATIC_DCL void FDECL(mkcavepos,
16                       (XCHAR_P, XCHAR_P, int, BOOLEAN_P, BOOLEAN_P));
17 STATIC_DCL void FDECL(mkcavearea, (BOOLEAN_P));
18 STATIC_DCL int NDECL(dig);
19 STATIC_DCL void FDECL(dig_up_grave, (coord *));
20 STATIC_DCL int FDECL(adj_pit_checks, (coord *, char *));
21 STATIC_DCL void FDECL(pit_flow, (struct trap *, SCHAR_P));
22
23 /* Indices returned by dig_typ() */
24 #define DIGTYP_UNDIGGABLE 0
25 #define DIGTYP_ROCK 1
26 #define DIGTYP_STATUE 2
27 #define DIGTYP_BOULDER 3
28 #define DIGTYP_DOOR 4
29 #define DIGTYP_TREE 5
30
31 STATIC_OVL boolean
32 rm_waslit()
33 {
34     register xchar x, y;
35
36     if (levl[u.ux][u.uy].typ == ROOM && levl[u.ux][u.uy].waslit)
37         return TRUE;
38     for (x = u.ux - 2; x < u.ux + 3; x++)
39         for (y = u.uy - 1; y < u.uy + 2; y++)
40             if (isok(x, y) && levl[x][y].waslit)
41                 return TRUE;
42     return FALSE;
43 }
44
45 /* Change level topology.  Messes with vision tables and ignores things like
46  * boulders in the name of a nice effect.  Vision will get fixed up again
47  * immediately after the effect is complete.
48  */
49 STATIC_OVL void
50 mkcavepos(x, y, dist, waslit, rockit)
51 xchar x, y;
52 int dist;
53 boolean waslit, rockit;
54 {
55     register struct rm *lev;
56
57     if (!isok(x, y))
58         return;
59     lev = &levl[x][y];
60
61     if (rockit) {
62         register struct monst *mtmp;
63
64         if (IS_ROCK(lev->typ))
65             return;
66         if (t_at(x, y))
67             return;                   /* don't cover the portal */
68         if ((mtmp = m_at(x, y)) != 0) /* make sure crucial monsters survive */
69             if (!passes_walls(mtmp->data))
70                 (void) rloc(mtmp, TRUE);
71     } else if (lev->typ == ROOM)
72         return;
73
74     unblock_point(x, y); /* make sure vision knows this location is open */
75
76     /* fake out saved state */
77     lev->seenv = 0;
78     lev->doormask = 0;
79     if (dist < 3)
80         lev->lit = (rockit ? FALSE : TRUE);
81     if (waslit)
82         lev->waslit = (rockit ? FALSE : TRUE);
83     lev->horizontal = FALSE;
84     /* short-circuit vision recalc */
85     viz_array[y][x] = (dist < 3) ? (IN_SIGHT | COULD_SEE) : COULD_SEE;
86     lev->typ = (rockit ? STONE : ROOM);
87     if (dist >= 3)
88         impossible("mkcavepos called with dist %d", dist);
89     feel_newsym(x, y);
90 }
91
92 STATIC_OVL void
93 mkcavearea(rockit)
94 register boolean rockit;
95 {
96     int dist;
97     xchar xmin = u.ux, xmax = u.ux;
98     xchar ymin = u.uy, ymax = u.uy;
99     register xchar i;
100     register boolean waslit = rm_waslit();
101
102     if (rockit)
103 /*JP
104         pline("Crash!  The ceiling collapses around you!");
105 */
106         pline("\82°\82°\82ñ\81I\82 \82È\82½\82Ì\82Ü\82í\82è\82Ì\93V\88ä\82ª\95ö\82ê\82½\81I");
107     else
108 #if 0 /*JP*/
109         pline("A mysterious force %s cave around you!",
110               (levl[u.ux][u.uy].typ == CORR) ? "creates a" : "extends the");
111 #else
112         pline("\90_\94é\93I\82È\97Í\82É\82æ\82è\82 \82È\82½\82Ì\82Ü\82í\82è%s\82½\81I",
113               (levl[u.ux][u.uy].typ == CORR) ? "\82É\93´\8cA\82ª\82Å\82«" : "\82Ì\93´\8cA\82ª\8dL\82ª\82Á");
114 #endif
115     display_nhwindow(WIN_MESSAGE, TRUE);
116
117     for (dist = 1; dist <= 2; dist++) {
118         xmin--;
119         xmax++;
120
121         /* top and bottom */
122         if (dist < 2) { /* the area is wider that it is high */
123             ymin--;
124             ymax++;
125             for (i = xmin + 1; i < xmax; i++) {
126                 mkcavepos(i, ymin, dist, waslit, rockit);
127                 mkcavepos(i, ymax, dist, waslit, rockit);
128             }
129         }
130
131         /* left and right */
132         for (i = ymin; i <= ymax; i++) {
133             mkcavepos(xmin, i, dist, waslit, rockit);
134             mkcavepos(xmax, i, dist, waslit, rockit);
135         }
136
137         flush_screen(1); /* make sure the new glyphs shows up */
138         delay_output();
139     }
140
141     if (!rockit && levl[u.ux][u.uy].typ == CORR) {
142         levl[u.ux][u.uy].typ = ROOM;
143         if (waslit)
144             levl[u.ux][u.uy].waslit = TRUE;
145         newsym(u.ux, u.uy); /* in case player is invisible */
146     }
147
148     vision_full_recalc = 1; /* everything changed */
149 }
150
151 /* When digging into location <x,y>, what are you actually digging into? */
152 int
153 dig_typ(otmp, x, y)
154 struct obj *otmp;
155 xchar x, y;
156 {
157     boolean ispick;
158
159     if (!otmp)
160         return DIGTYP_UNDIGGABLE;
161     ispick = is_pick(otmp);
162     if (!ispick && !is_axe(otmp))
163         return DIGTYP_UNDIGGABLE;
164
165     return ((ispick && sobj_at(STATUE, x, y))
166                ? DIGTYP_STATUE
167                : (ispick && sobj_at(BOULDER, x, y))
168                   ? DIGTYP_BOULDER
169                   : closed_door(x, y)
170                      ? DIGTYP_DOOR
171                      : IS_TREE(levl[x][y].typ)
172                         ? (ispick ? DIGTYP_UNDIGGABLE : DIGTYP_TREE)
173                         : (ispick && IS_ROCK(levl[x][y].typ)
174                            && (!level.flags.arboreal
175                                || IS_WALL(levl[x][y].typ)))
176                            ? DIGTYP_ROCK
177                            : DIGTYP_UNDIGGABLE);
178 }
179
180 boolean
181 is_digging()
182 {
183     if (occupation == dig) {
184         return TRUE;
185     }
186     return FALSE;
187 }
188
189 #define BY_YOU (&youmonst)
190 #define BY_OBJECT ((struct monst *) 0)
191
192 boolean
193 dig_check(madeby, verbose, x, y)
194 struct monst *madeby;
195 boolean verbose;
196 int x, y;
197 {
198     struct trap *ttmp = t_at(x, y);
199     const char *verb =
200 /*JP
201         (madeby == BY_YOU && uwep && is_axe(uwep)) ? "chop" : "dig in";
202 */
203         (madeby == BY_YOU && uwep && is_axe(uwep)) ? "\8dÓ\82¯\82È\82¢" : "\8c@\82ê\82È\82¢";
204
205     if (On_stairs(x, y)) {
206         if (x == xdnladder || x == xupladder) {
207             if (verbose)
208 /*JP
209                 pline_The("ladder resists your effort.");
210 */
211                 pline("\82Í\82µ\82²\82ª\8e×\96\82\82ð\82µ\82½\81D");
212         } else if (verbose)
213 /*JP
214             pline_The("stairs are too hard to %s.", verb);
215 */
216             pline("\8aK\92i\82Í\82Æ\82Ä\82à\8cÅ\82­\82Ä%s\81D", verb);
217         return FALSE;
218     } else if (IS_THRONE(levl[x][y].typ) && madeby != BY_OBJECT) {
219         if (verbose)
220 /*JP
221             pline_The("throne is too hard to break apart.");
222 */
223             pline("\8bÊ\8dÀ\82Í\82Æ\82Ä\82à\8cÅ\82­\82Ä\8dÓ\82¯\82È\82¢\81D");
224         return FALSE;
225     } else if (IS_ALTAR(levl[x][y].typ)
226                && (madeby != BY_OBJECT || Is_astralevel(&u.uz)
227                    || Is_sanctum(&u.uz))) {
228         if (verbose)
229 /*JP
230             pline_The("altar is too hard to break apart.");
231 */
232             pline_The("\8dÕ\92d\82Í\82Æ\82Ä\82à\8cÅ\82­\82Ä\8dÓ\82¯\82È\82¢\81D");
233         return FALSE;
234     } else if (Is_airlevel(&u.uz)) {
235         if (verbose)
236 /*JP
237             You("cannot %s thin air.", verb);
238 */
239             You("\89½\82à\82È\82¢\8bó\8aÔ\82Í%s\81D", verb);
240         return FALSE;
241     } else if (Is_waterlevel(&u.uz)) {
242         if (verbose)
243 /*JP
244             pline_The("water splashes and subsides.");
245 */
246             pline("\90\85\82ª\83s\83V\83\83\83b\82Æ\92µ\82Ë\82½\81D");
247         return FALSE;
248     } else if ((IS_ROCK(levl[x][y].typ) && levl[x][y].typ != SDOOR
249                 && (levl[x][y].wall_info & W_NONDIGGABLE) != 0)
250                || (ttmp
251                    && (ttmp->ttyp == MAGIC_PORTAL
252                        || ttmp->ttyp == VIBRATING_SQUARE
253                        || (!Can_dig_down(&u.uz) && !levl[x][y].candig)))) {
254         if (verbose)
255 /*JP
256             pline_The("%s here is too hard to %s.", surface(x, y), verb);
257 */
258             pline_The("%s\82Í\82Æ\82Ä\82à\8cÅ\82­\82Ä%s\81D", surface(x,y), verb);
259         return FALSE;
260     } else if (sobj_at(BOULDER, x, y)) {
261         if (verbose)
262 /*JP
263             There("isn't enough room to %s here.", verb);
264 */
265             pline("\8f\\95ª\82È\8fê\8f\8a\82ª\82È\82¢\82Ì\82Å%s\81D", verb);
266         return FALSE;
267     } else if (madeby == BY_OBJECT
268                /* the block against existing traps is mainly to
269                   prevent broken wands from turning holes into pits */
270                && (ttmp || is_pool_or_lava(x, y))) {
271         /* digging by player handles pools separately */
272         return FALSE;
273     }
274     return TRUE;
275 }
276
277 STATIC_OVL int
278 dig(VOID_ARGS)
279 {
280     register struct rm *lev;
281     register xchar dpx = context.digging.pos.x, dpy = context.digging.pos.y;
282     register boolean ispick = uwep && is_pick(uwep);
283 /*JP
284     const char *verb = (!uwep || is_pick(uwep)) ? "dig into" : "chop through";
285 */
286     const char *verb = (!uwep || is_pick(uwep)) ? "\8c@\82ê\82È\82¢" : "\8dÓ\82¯\82È\82¢";
287
288     lev = &levl[dpx][dpy];
289     /* perhaps a nymph stole your pick-axe while you were busy digging */
290     /* or perhaps you teleported away */
291     if (u.uswallow || !uwep || (!ispick && !is_axe(uwep))
292         || !on_level(&context.digging.level, &u.uz)
293         || ((context.digging.down ? (dpx != u.ux || dpy != u.uy)
294                                   : (distu(dpx, dpy) > 2))))
295         return 0;
296
297     if (context.digging.down) {
298         if (!dig_check(BY_YOU, TRUE, u.ux, u.uy))
299             return 0;
300     } else { /* !context.digging.down */
301         if (IS_TREE(lev->typ) && !may_dig(dpx, dpy)
302             && dig_typ(uwep, dpx, dpy) == DIGTYP_TREE) {
303 /*JP
304             pline("This tree seems to be petrified.");
305 */
306             pline("\82±\82Ì\96Ø\82Í\90Î\89»\82µ\82Ä\82¢\82é\82æ\82¤\82¾\81D");
307             return 0;
308         }
309         if (IS_ROCK(lev->typ) && !may_dig(dpx, dpy)
310             && dig_typ(uwep, dpx, dpy) == DIGTYP_ROCK) {
311 #if 0 /*JP*/
312             pline("This %s is too hard to %s.",
313                   is_db_wall(dpx, dpy) ? "drawbridge" : "wall", verb);
314 #else
315             pline("\82±\82Ì%s\82Í\82Æ\82Ä\82à\8cÅ\82­\82Ä%s\81D",
316                   is_db_wall(dpx, dpy) ? "\92µ\82Ë\8b´" : "\95Ç", verb);
317 #endif
318             return 0;
319         }
320     }
321     if (Fumbling && !rn2(3)) {
322         switch (rn2(3)) {
323         case 0:
324             if (!welded(uwep)) {
325 /*JP
326                 You("fumble and drop %s.", yname(uwep));
327 */
328                 You("\8eè\82ª\8a\8a\82è%s\82ð\97\8e\82µ\82½\81D", yname(uwep));
329                 dropx(uwep);
330             } else {
331                 if (u.usteed)
332 #if 0 /*JP:T*/
333                     pline("%s and %s %s!", Yobjnam2(uwep, "bounce"),
334                           otense(uwep, "hit"), mon_nam(u.usteed));
335 #else
336                     pline("%s\82Í\92µ\82Ë\82©\82¦\82è%s\82É\96½\92\86\82µ\82½\81I",
337                           xname(uwep), mon_nam(u.usteed));
338 #endif
339                 else
340 #if 0 /*JP:T*/
341                     pline("Ouch!  %s and %s you!", Yobjnam2(uwep, "bounce"),
342                           otense(uwep, "hit"));
343 #else
344                     pline("\82¢\82Ä\82Á\81I%s\82Í\92µ\82Ë\82©\82¦\82è\82 \82È\82½\82É\96½\92\86\82µ\82½\81I",
345                           xname(uwep));
346 #endif
347                 set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
348             }
349             break;
350         case 1:
351 /*JP
352             pline("Bang!  You hit with the broad side of %s!",
353 */
354             pline("\83o\83\93\81I%s\82Ì\95¿\82Å\91Å\82Á\82Ä\82µ\82Ü\82Á\82½\81I",
355                   the(xname(uwep)));
356             break;
357         default:
358 /*JP
359             Your("swing misses its mark.");
360 */
361             You("\91_\82¢\82ð\92è\82ß\82Ä\90U\82è\82¨\82ë\82µ\82½\82ª\82Í\82¸\82µ\82½\81D");
362             break;
363         }
364         return 0;
365     }
366
367     context.digging.effort +=
368         10 + rn2(5) + abon() + uwep->spe - greatest_erosion(uwep) + u.udaminc;
369     if (Race_if(PM_DWARF))
370         context.digging.effort *= 2;
371     if (context.digging.down) {
372         struct trap *ttmp = t_at(dpx, dpy);
373
374         if (context.digging.effort > 250 || (ttmp && ttmp->ttyp == HOLE)) {
375             (void) dighole(FALSE, FALSE, (coord *) 0);
376             (void) memset((genericptr_t) &context.digging, 0,
377                           sizeof context.digging);
378             return 0; /* done with digging */
379         }
380
381         if (context.digging.effort <= 50
382             || (ttmp && (ttmp->ttyp == TRAPDOOR || ttmp->ttyp == PIT
383                          || ttmp->ttyp == SPIKED_PIT))) {
384             return 1;
385         } else if (ttmp && (ttmp->ttyp == LANDMINE
386                             || (ttmp->ttyp == BEAR_TRAP && !u.utrap))) {
387             /* digging onto a set object trap triggers it;
388                hero should have used #untrap first */
389             dotrap(ttmp, FORCETRAP);
390             /* restart completely from scratch if we resume digging */
391             (void) memset((genericptr_t) &context.digging, 0,
392                           sizeof context.digging);
393             return 0;
394         } else if (ttmp && ttmp->ttyp == BEAR_TRAP && u.utrap) {
395             if (rnl(7) > (Fumbling ? 1 : 4)) {
396                 char kbuf[BUFSZ];
397                 int dmg = dmgval(uwep, &youmonst) + dbon();
398
399                 if (dmg < 1)
400                     dmg = 1;
401                 else if (uarmf)
402                     dmg = (dmg + 1) / 2;
403                 You("hit yourself in the %s.", body_part(FOOT));
404                 Sprintf(kbuf, "chopping off %s own %s", uhis(),
405                         body_part(FOOT));
406                 losehp(Maybe_Half_Phys(dmg), kbuf, KILLED_BY);
407             } else {
408                 You("destroy the bear trap with %s.",
409                     yobjnam(uwep, (const char *) 0));
410                 u.utrap = 0; /* release from trap */
411                 deltrap(ttmp);
412             }
413             /* we haven't made any progress toward a pit yet */
414             context.digging.effort = 0;
415             return 0;
416         }
417
418         if (IS_ALTAR(lev->typ)) {
419             altar_wrath(dpx, dpy);
420             angry_priest();
421         }
422
423         /* make pit at <u.ux,u.uy> */
424         if (dighole(TRUE, FALSE, (coord *) 0)) {
425             context.digging.level.dnum = 0;
426             context.digging.level.dlevel = -1;
427         }
428         return 0;
429     }
430
431     if (context.digging.effort > 100) {
432         register const char *digtxt, *dmgtxt = (const char *) 0;
433         register struct obj *obj;
434         register boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE);
435
436         if ((obj = sobj_at(STATUE, dpx, dpy)) != 0) {
437             if (break_statue(obj))
438 /*JP
439                 digtxt = "The statue shatters.";
440 */
441                 digtxt = "\92¤\91\9c\82Í\82±\82È\82²\82È\82É\82È\82Á\82½\81D";
442             else
443                 /* it was a statue trap; break_statue()
444                  * printed a message and updated the screen
445                  */
446                 digtxt = (char *) 0;
447         } else if ((obj = sobj_at(BOULDER, dpx, dpy)) != 0) {
448             struct obj *bobj;
449
450             fracture_rock(obj);
451             if ((bobj = sobj_at(BOULDER, dpx, dpy)) != 0) {
452                 /* another boulder here, restack it to the top */
453                 obj_extract_self(bobj);
454                 place_object(bobj, dpx, dpy);
455             }
456 /*JP
457             digtxt = "The boulder falls apart.";
458 */
459             digtxt = "\8aâ\82Í\82±\82È\82²\82È\82É\82È\82Á\82½\81D";
460         } else if (lev->typ == STONE || lev->typ == SCORR
461                    || IS_TREE(lev->typ)) {
462             if (Is_earthlevel(&u.uz)) {
463                 if (uwep->blessed && !rn2(3)) {
464                     mkcavearea(FALSE);
465                     goto cleanup;
466                 } else if ((uwep->cursed && !rn2(4))
467                            || (!uwep->blessed && !rn2(6))) {
468                     mkcavearea(TRUE);
469                     goto cleanup;
470                 }
471             }
472             if (IS_TREE(lev->typ)) {
473 /*JP
474                 digtxt = "You cut down the tree.";
475 */
476                 digtxt = "\96Ø\82ð\90Ø\82è\93|\82µ\82½\81D";
477                 lev->typ = ROOM;
478                 if (!rn2(5))
479                     (void) rnd_treefruit_at(dpx, dpy);
480             } else {
481 /*JP
482                 digtxt = "You succeed in cutting away some rock.";
483 */
484                 digtxt = "\8aâ\82ð\8f­\82µ\90Ø\82è\82Æ\82Á\82½\81D";
485                 lev->typ = CORR;
486             }
487         } else if (IS_WALL(lev->typ)) {
488             if (shopedge) {
489                 add_damage(dpx, dpy, 10L * ACURRSTR);
490 /*JP
491                 dmgtxt = "damage";
492 */
493                 dmgtxt = "\8f\9d\82Â\82¯\82é";
494             }
495             if (level.flags.is_maze_lev) {
496                 lev->typ = ROOM;
497             } else if (level.flags.is_cavernous_lev && !in_town(dpx, dpy)) {
498                 lev->typ = CORR;
499             } else {
500                 lev->typ = DOOR;
501                 lev->doormask = D_NODOOR;
502             }
503 /*JP
504             digtxt = "You make an opening in the wall.";
505 */
506             digtxt = "\95Ç\82É\8c\8a\82ð\8bó\82¯\82½\81D";
507         } else if (lev->typ == SDOOR) {
508             cvt_sdoor_to_door(lev); /* ->typ = DOOR */
509 /*JP
510             digtxt = "You break through a secret door!";
511 */
512             digtxt = "\94é\96§\82Ì\94à\82ð\92Ê\82è\94²\82¯\82½\81I";
513             if (!(lev->doormask & D_TRAPPED))
514                 lev->doormask = D_BROKEN;
515         } else if (closed_door(dpx, dpy)) {
516 /*JP
517             digtxt = "You break through the door.";
518 */
519             digtxt = "\94à\82ð\92Ê\82è\94²\82¯\82½\81D";
520             if (shopedge) {
521                 add_damage(dpx, dpy, 400L);
522 /*JP
523                 dmgtxt = "break";
524 */
525                 dmgtxt = "\89ó\82·";
526             }
527             if (!(lev->doormask & D_TRAPPED))
528                 lev->doormask = D_BROKEN;
529         } else
530             return 0; /* statue or boulder got taken */
531
532         if (!does_block(dpx, dpy, &levl[dpx][dpy]))
533             unblock_point(dpx, dpy); /* vision:  can see through */
534         feel_newsym(dpx, dpy);
535         if (digtxt && !context.digging.quiet)
536             pline1(digtxt); /* after newsym */
537         if (dmgtxt)
538             pay_for_damage(dmgtxt, FALSE);
539
540         if (Is_earthlevel(&u.uz) && !rn2(3)) {
541             register struct monst *mtmp;
542
543             switch (rn2(2)) {
544             case 0:
545                 mtmp = makemon(&mons[PM_EARTH_ELEMENTAL], dpx, dpy,
546                                NO_MM_FLAGS);
547                 break;
548             default:
549                 mtmp = makemon(&mons[PM_XORN], dpx, dpy, NO_MM_FLAGS);
550                 break;
551             }
552             if (mtmp)
553 /*JP
554                 pline_The("debris from your digging comes to life!");
555 */
556                 pline("\8aâ\82Ì\94j\95Ð\82ª\90\96½\82ð\91Ñ\82Ñ\82½\81I");
557         }
558         if (IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) {
559             lev->doormask = D_NODOOR;
560 /*JP
561             b_trapped("door", 0);
562 */
563             b_trapped("\94à", 0);
564             newsym(dpx, dpy);
565         }
566     cleanup:
567         context.digging.lastdigtime = moves;
568         context.digging.quiet = FALSE;
569         context.digging.level.dnum = 0;
570         context.digging.level.dlevel = -1;
571         return 0;
572     } else { /* not enough effort has been spent yet */
573 #if 0 /*JP:T*/
574         static const char *const d_target[6] = { "",        "rock", "statue",
575                                                  "boulder", "door", "tree" };
576 #else
577         static const char *const d_target[6] = { "",   "\90Î", "\92¤\91\9c",
578                                                  "\8aâ", "\94à", "\96Ø" };
579 #endif
580         int dig_target = dig_typ(uwep, dpx, dpy);
581
582         if (IS_WALL(lev->typ) || dig_target == DIGTYP_DOOR) {
583             if (*in_rooms(dpx, dpy, SHOPBASE)) {
584 #if 0 /*JP:T*/
585                 pline("This %s seems too hard to %s.",
586                       IS_DOOR(lev->typ) ? "door" : "wall", verb);
587 #else
588                 pline("\82±\82Ì%s\82Í\82Æ\82Ä\82à\8cÅ\82­\82Ä%s\81D",
589                       IS_DOOR(lev->typ) ? "\94à" : "\95Ç", verb);
590 #endif
591                 return 0;
592             }
593         } else if (dig_target == DIGTYP_UNDIGGABLE
594                    || (dig_target == DIGTYP_ROCK && !IS_ROCK(lev->typ)))
595             return 0; /* statue or boulder got taken */
596
597         if (!did_dig_msg) {
598 /*JP
599             You("hit the %s with all your might.", d_target[dig_target]);
600 */
601             You("%s\82ð\97Í\88ê\94t\91Å\82¿\82Â\82¯\82½\81D", d_target[dig_target]);
602             did_dig_msg = TRUE;
603         }
604     }
605     return 1;
606 }
607
608 /* When will hole be finished? Very rough indication used by shopkeeper. */
609 int
610 holetime()
611 {
612     if (occupation != dig || !*u.ushops)
613         return -1;
614     return ((250 - context.digging.effort) / 20);
615 }
616
617 /* Return typ of liquid to fill a hole with, or ROOM, if no liquid nearby */
618 schar
619 fillholetyp(x, y, fill_if_any)
620 int x, y;
621 boolean fill_if_any; /* force filling if it exists at all */
622 {
623     register int x1, y1;
624     int lo_x = max(1, x - 1), hi_x = min(x + 1, COLNO - 1),
625         lo_y = max(0, y - 1), hi_y = min(y + 1, ROWNO - 1);
626     int pool_cnt = 0, moat_cnt = 0, lava_cnt = 0;
627
628     for (x1 = lo_x; x1 <= hi_x; x1++)
629         for (y1 = lo_y; y1 <= hi_y; y1++)
630             if (is_moat(x1, y1))
631                 moat_cnt++;
632             else if (is_pool(x1, y1))
633                 /* This must come after is_moat since moats are pools
634                  * but not vice-versa. */
635                 pool_cnt++;
636             else if (is_lava(x1, y1))
637                 lava_cnt++;
638
639     if (!fill_if_any)
640         pool_cnt /= 3; /* not as much liquid as the others */
641
642     if ((lava_cnt > moat_cnt + pool_cnt && rn2(lava_cnt + 1))
643         || (lava_cnt && fill_if_any))
644         return LAVAPOOL;
645     else if ((moat_cnt > 0 && rn2(moat_cnt + 1)) || (moat_cnt && fill_if_any))
646         return MOAT;
647     else if ((pool_cnt > 0 && rn2(pool_cnt + 1)) || (pool_cnt && fill_if_any))
648         return POOL;
649     else
650         return ROOM;
651 }
652
653 void
654 digactualhole(x, y, madeby, ttyp)
655 register int x, y;
656 struct monst *madeby;
657 int ttyp;
658 {
659     struct obj *oldobjs, *newobjs;
660     register struct trap *ttmp;
661     char surface_type[BUFSZ];
662     struct rm *lev = &levl[x][y];
663     boolean shopdoor;
664     struct monst *mtmp = m_at(x, y); /* may be madeby */
665     boolean madeby_u = (madeby == BY_YOU);
666     boolean madeby_obj = (madeby == BY_OBJECT);
667     boolean at_u = (x == u.ux) && (y == u.uy);
668     boolean wont_fall = Levitation || Flying;
669
670     if (at_u && u.utrap) {
671         if (u.utraptype == TT_BURIEDBALL)
672             buried_ball_to_punishment();
673         else if (u.utraptype == TT_INFLOOR)
674             u.utrap = 0;
675     }
676
677     /* these furniture checks were in dighole(), but wand
678        breaking bypasses that routine and calls us directly */
679     if (IS_FOUNTAIN(lev->typ)) {
680         dogushforth(FALSE);
681         SET_FOUNTAIN_WARNED(x, y); /* force dryup */
682         dryup(x, y, madeby_u);
683         return;
684     } else if (IS_SINK(lev->typ)) {
685         breaksink(x, y);
686         return;
687     } else if (lev->typ == DRAWBRIDGE_DOWN
688                || (is_drawbridge_wall(x, y) >= 0)) {
689         int bx = x, by = y;
690         /* if under the portcullis, the bridge is adjacent */
691         (void) find_drawbridge(&bx, &by);
692         destroy_drawbridge(bx, by);
693         return;
694     }
695
696     if (ttyp != PIT && (!Can_dig_down(&u.uz) && !lev->candig)) {
697         impossible("digactualhole: can't dig %s on this level.",
698                    defsyms[trap_to_defsym(ttyp)].explanation);
699         ttyp = PIT;
700     }
701
702     /* maketrap() might change it, also, in this situation,
703        surface() returns an inappropriate string for a grave */
704     if (IS_GRAVE(lev->typ))
705 /*JP
706         Strcpy(surface_type, "grave");
707 */
708         Strcpy(surface_type, "\95æ");
709     else
710         Strcpy(surface_type, surface(x, y));
711     shopdoor = IS_DOOR(lev->typ) && *in_rooms(x, y, SHOPBASE);
712     oldobjs = level.objects[x][y];
713     ttmp = maketrap(x, y, ttyp);
714     if (!ttmp)
715         return;
716     newobjs = level.objects[x][y];
717     ttmp->madeby_u = madeby_u;
718     ttmp->tseen = 0;
719     if (cansee(x, y))
720         seetrap(ttmp);
721     else if (madeby_u)
722         feeltrap(ttmp);
723
724     if (ttyp == PIT) {
725         if (madeby_u) {
726             if (x != u.ux || y != u.uy)
727                 You("dig an adjacent pit.");
728             else
729 /*JP
730                 You("dig a pit in the %s.", surface_type);
731 */
732                 You("%s\82É\97\8e\82µ\8c\8a\82ð\8c@\82Á\82½\81D", surface_type);
733             if (shopdoor)
734 /*JP
735                 pay_for_damage("ruin", FALSE);
736 */
737                 pay_for_damage("\89ó\82·", FALSE);
738         } else if (!madeby_obj && canseemon(madeby))
739 /*JP
740             pline("%s digs a pit in the %s.", Monnam(madeby), surface_type);
741 */
742             pline("%s\82Í%s\82É\97\8e\82µ\8c\8a\82ð\8c@\82Á\82½\81D", Monnam(madeby), surface_type);
743         else if (cansee(x, y) && flags.verbose)
744 /*JP
745             pline("A pit appears in the %s.", surface_type);
746 */
747             pline("\97\8e\82µ\8c\8a\82ª%s\82É\8c»\82í\82ê\82½\81D", surface_type);
748
749         if (at_u) {
750             if (!wont_fall) {
751                 u.utrap = rn1(4, 2);
752                 u.utraptype = TT_PIT;
753                 vision_full_recalc = 1; /* vision limits change */
754             } else
755                 u.utrap = 0;
756             if (oldobjs != newobjs) /* something unearthed */
757                 (void) pickup(1);   /* detects pit */
758         } else if (mtmp) {
759             if (is_flyer(mtmp->data) || is_floater(mtmp->data)) {
760                 if (canseemon(mtmp))
761 #if 0 /*JP*/
762                     pline("%s %s over the pit.", Monnam(mtmp),
763                           (is_flyer(mtmp->data)) ? "flies" : "floats");
764 #else
765                     pline("%s\82Í%s\97\8e\82µ\8c\8a\82ð\89z\82¦\82½\81D", Monnam(mtmp),
766                           (is_flyer(mtmp->data)) ? "\94ò\82ñ\82Å" : "\95\82\82¢\82Ä");
767 #endif
768             } else if (mtmp != madeby)
769                 (void) mintrap(mtmp);
770         }
771     } else { /* was TRAPDOOR now a HOLE*/
772
773         if (madeby_u)
774 /*JP
775             You("dig a hole through the %s.", surface_type);
776 */
777             You("%s\82É\8c\8a\82ð\8aJ\82¯\82½\81D", surface_type);
778         else if (!madeby_obj && canseemon(madeby))
779 #if 0 /*JP:T*/
780             pline("%s digs a hole through the %s.", Monnam(madeby),
781                   surface_type);
782 #else
783             pline("%s\82Í%s\82É\8c\8a\82ð\8aJ\82¯\82½\81D", Monnam(madeby),
784                   surface_type);
785 #endif
786         else if (cansee(x, y) && flags.verbose)
787 /*JP
788             pline("A hole appears in the %s.", surface_type);
789 */
790             pline("%s\82É\8c\8a\82ª\8c»\82í\82ê\82½\81D", surface_type);
791
792         if (at_u) {
793             if (!u.ustuck && !wont_fall && !next_to_u()) {
794 /*JP
795                 You("are jerked back by your pet!");
796 */
797                 You("\83y\83b\83g\82É\82æ\82Á\82Ä\88ø\82«\96ß\82³\82ê\82½\81I");
798                 wont_fall = TRUE;
799             }
800
801             /* Floor objects get a chance of falling down.  The case where
802              * the hero does NOT fall down is treated here.  The case
803              * where the hero does fall down is treated in goto_level().
804              */
805             if (u.ustuck || wont_fall) {
806                 if (newobjs)
807                     impact_drop((struct obj *) 0, x, y, 0);
808                 if (oldobjs != newobjs)
809                     (void) pickup(1);
810                 if (shopdoor && madeby_u)
811 /*JP
812                     pay_for_damage("ruin", FALSE);
813 */
814                     pay_for_damage("\82ß\82¿\82á\82ß\82¿\82á\82É\82·\82é", FALSE);
815
816             } else {
817                 d_level newlevel;
818
819                 if (*u.ushops && madeby_u)
820                     shopdig(1); /* shk might snatch pack */
821                 /* handle earlier damage, eg breaking wand of digging */
822                 else if (!madeby_u)
823 /*JP
824                     pay_for_damage("dig into", TRUE);
825 */
826                     pay_for_damage("\8c\8a\82ð\82 \82¯\82é", TRUE);
827
828 /*JP
829                 You("fall through...");
830 */
831                 You("\97\8e\82¿\82½\81D\81D\81D");
832                 /* Earlier checks must ensure that the destination
833                  * level exists and is in the present dungeon.
834                  */
835                 newlevel.dnum = u.uz.dnum;
836                 newlevel.dlevel = u.uz.dlevel + 1;
837                 goto_level(&newlevel, FALSE, TRUE, FALSE);
838                 /* messages for arriving in special rooms */
839                 spoteffects(FALSE);
840             }
841         } else {
842             if (shopdoor && madeby_u)
843 /*JP
844                 pay_for_damage("ruin", FALSE);
845 */
846                 pay_for_damage("\82ß\82¿\82á\82ß\82¿\82á\82É\82·\82é", FALSE);
847             if (newobjs)
848                 impact_drop((struct obj *) 0, x, y, 0);
849             if (mtmp) {
850                 /*[don't we need special sokoban handling here?]*/
851                 if (is_flyer(mtmp->data) || is_floater(mtmp->data)
852                     || mtmp->data == &mons[PM_WUMPUS]
853                     || (mtmp->wormno && count_wsegs(mtmp) > 5)
854                     || mtmp->data->msize >= MZ_HUGE)
855                     return;
856                 if (mtmp == u.ustuck) /* probably a vortex */
857                     return;           /* temporary? kludge */
858
859                 if (teleport_pet(mtmp, FALSE)) {
860                     d_level tolevel;
861
862                     if (Is_stronghold(&u.uz)) {
863                         assign_level(&tolevel, &valley_level);
864                     } else if (Is_botlevel(&u.uz)) {
865                         if (canseemon(mtmp))
866 /*JP
867                             pline("%s avoids the trap.", Monnam(mtmp));
868 */
869                             pline("%s\82Íã©\82ð\94ð\82¯\82½\81D", Monnam(mtmp));
870                         return;
871                     } else {
872                         get_level(&tolevel, depth(&u.uz) + 1);
873                     }
874                     if (mtmp->isshk)
875                         make_angry_shk(mtmp, 0, 0);
876                     migrate_to_level(mtmp, ledger_no(&tolevel), MIGR_RANDOM,
877                                      (coord *) 0);
878                 }
879             }
880         }
881     }
882 }
883
884 /*
885  * Called from dighole(), but also from do_break_wand()
886  * in apply.c.
887  */
888 void
889 liquid_flow(x, y, typ, ttmp, fillmsg)
890 xchar x, y;
891 schar typ;
892 struct trap *ttmp;
893 const char *fillmsg;
894 {
895     boolean u_spot = (x == u.ux && y == u.uy);
896
897     if (ttmp)
898         (void) delfloortrap(ttmp);
899     /* if any objects were frozen here, they're released now */
900     unearth_objs(x, y);
901
902     if (fillmsg)
903 /*JP
904         pline(fillmsg, typ == LAVAPOOL ? "lava" : "water");
905 */
906         pline(fillmsg, typ == LAVAPOOL ? "\97n\8aâ" : "\90\85");
907     if (u_spot && !(Levitation || Flying)) {
908         if (typ == LAVAPOOL)
909             (void) lava_effects();
910         else if (!Wwalking)
911             (void) drown();
912     }
913 }
914
915 /* return TRUE if digging succeeded, FALSE otherwise */
916 boolean
917 dighole(pit_only, by_magic, cc)
918 boolean pit_only, by_magic;
919 coord *cc;
920 {
921     register struct trap *ttmp;
922     struct rm *lev;
923     struct obj *boulder_here;
924     schar typ;
925     xchar dig_x, dig_y;
926     boolean nohole;
927
928     if (!cc) {
929         dig_x = u.ux;
930         dig_y = u.uy;
931     } else {
932         dig_x = cc->x;
933         dig_y = cc->y;
934         if (!isok(dig_x, dig_y))
935             return FALSE;
936     }
937
938     ttmp = t_at(dig_x, dig_y);
939     lev = &levl[dig_x][dig_y];
940     nohole = (!Can_dig_down(&u.uz) && !lev->candig);
941
942     if ((ttmp && (ttmp->ttyp == MAGIC_PORTAL
943                   || ttmp->ttyp == VIBRATING_SQUARE || nohole))
944         || (IS_ROCK(lev->typ) && lev->typ != SDOOR
945             && (lev->wall_info & W_NONDIGGABLE) != 0)) {
946 #if 0 /*JP:T*/
947         pline_The("%s %shere is too hard to dig in.", surface(dig_x, dig_y),
948                   (dig_x != u.ux || dig_y != u.uy) ? "t" : "");
949 #else
950         pline("%s\82Í\82Æ\82Ä\82à\8cÅ\82­\82Ä\8c@\82ê\82È\82¢\81D", surface(dig_x, dig_y));
951 #endif
952
953     } else if (is_pool_or_lava(dig_x, dig_y)) {
954 #if 0 /*JP:T*/
955         pline_The("%s sloshes furiously for a moment, then subsides.",
956                   is_lava(dig_x, dig_y) ? "lava" : "water");
957 #else
958         pline("%s\82Í\8c\83\82µ\82­\94g\82¤\82Á\82½\81D",
959                   is_lava(dig_x, dig_y) ? "\97n\8aâ" : "\90\85");
960 #endif
961         wake_nearby(); /* splashing */
962
963     } else if (lev->typ == DRAWBRIDGE_DOWN
964                || (is_drawbridge_wall(dig_x, dig_y) >= 0)) {
965         /* drawbridge_down is the platform crossing the moat when the
966            bridge is extended; drawbridge_wall is the open "doorway" or
967            closed "door" where the portcullis/mechanism is located */
968         if (pit_only) {
969 /*JP
970             pline_The("drawbridge seems too hard to dig through.");
971 */
972             pline("\92µ\82Ë\8b´\82Í\82Æ\82Ä\82à\8cÅ\82­\82Ä\8c@\82ê\82»\82¤\82É\82È\82¢\81D");
973             return FALSE;
974         } else {
975             int x = dig_x, y = dig_y;
976             /* if under the portcullis, the bridge is adjacent */
977             (void) find_drawbridge(&x, &y);
978             destroy_drawbridge(x, y);
979             return TRUE;
980         }
981
982     } else if ((boulder_here = sobj_at(BOULDER, dig_x, dig_y)) != 0) {
983         if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)
984             && rn2(2)) {
985 #if 0 /*JP*/
986             pline_The("boulder settles into the %spit.",
987                       (dig_x != u.ux || dig_y != u.uy) ? "adjacent " : "");
988 #else
989             pline("\8aâ\82Í%s\97\8e\82µ\8c\8a\82ð\96\84\82ß\82½\81D",
990                       (dig_x != u.ux || dig_y != u.uy) ? "\97×\82Ì" : "");
991 #endif
992             ttmp->ttyp = PIT; /* crush spikes */
993         } else {
994             /*
995              * digging makes a hole, but the boulder immediately
996              * fills it.  Final outcome:  no hole, no boulder.
997              */
998 /*JP
999             pline("KADOOM! The boulder falls in!");
1000 */
1001             pline("\82Ç\82Ç\81[\82ñ\81I\8aâ\82Í\97\8e\82¿\82½\81I");
1002             (void) delfloortrap(ttmp);
1003         }
1004         delobj(boulder_here);
1005         return TRUE;
1006
1007     } else if (IS_GRAVE(lev->typ)) {
1008         digactualhole(dig_x, dig_y, BY_YOU, PIT);
1009         dig_up_grave(cc);
1010         return TRUE;
1011     } else if (lev->typ == DRAWBRIDGE_UP) {
1012         /* must be floor or ice, other cases handled above */
1013         /* dig "pit" and let fluid flow in (if possible) */
1014         typ = fillholetyp(dig_x, dig_y, FALSE);
1015
1016         if (typ == ROOM) {
1017             /*
1018              * We can't dig a hole here since that will destroy
1019              * the drawbridge.  The following is a cop-out. --dlc
1020              */
1021 #if 0 /*JP*/
1022             pline_The("%s %shere is too hard to dig in.",
1023                       surface(dig_x, dig_y),
1024                       (dig_x != u.ux || dig_y != u.uy) ? "t" : "");
1025 #else
1026             pline("%s\82Í\82Æ\82Ä\82à\8cÅ\82­\82Ä\8c@\82ê\82È\82¢\81D", surface(dig_x, dig_y));
1027 #endif
1028             return FALSE;
1029         }
1030
1031         lev->drawbridgemask &= ~DB_UNDER;
1032         lev->drawbridgemask |= (typ == LAVAPOOL) ? DB_LAVA : DB_MOAT;
1033 #if 0 /*JP:T*/
1034         liquid_flow(dig_x, dig_y, typ, ttmp,
1035                     "As you dig, the hole fills with %s!");
1036 #else
1037         liquid_flow(dig_x, dig_y, typ, ttmp,
1038                     "\82 \82È\82½\82ª\8c@\82é\82Æ\81C%s\82ª\97N\82¢\82Ä\82«\82½\81I");
1039 #endif
1040         return TRUE;
1041
1042         /* the following two are here for the wand of digging */
1043     } else if (IS_THRONE(lev->typ)) {
1044 /*JP
1045         pline_The("throne is too hard to break apart.");
1046 */
1047         pline("\8bÊ\8dÀ\82Í\82Æ\82Ä\82à\8cÅ\82­\82Ä\8dÓ\82¯\82È\82¢\81D");
1048
1049     } else if (IS_ALTAR(lev->typ)) {
1050 /*JP
1051         pline_The("altar is too hard to break apart.");
1052 */
1053         pline("\8dÕ\92d\82Í\82Æ\82Ä\82à\8cÅ\82­\82Ä\8dÓ\82¯\82È\82¢\81D");
1054
1055     } else {
1056         typ = fillholetyp(dig_x, dig_y, FALSE);
1057
1058         if (typ != ROOM) {
1059             lev->typ = typ;
1060 #if 0 /*JP*/
1061             liquid_flow(dig_x, dig_y, typ, ttmp,
1062                         "As you dig, the hole fills with %s!");
1063 #else
1064             liquid_flow(dig_x, dig_y, typ, ttmp,
1065                         "\82 \82È\82½\82ª\8c@\82é\82Æ\81C%s\82ª\97N\82¢\82Ä\82«\82½\81I");
1066 #endif
1067             return TRUE;
1068         }
1069
1070         /* magical digging disarms settable traps */
1071         if (by_magic && ttmp
1072             && (ttmp->ttyp == LANDMINE || ttmp->ttyp == BEAR_TRAP)) {
1073             int otyp = (ttmp->ttyp == LANDMINE) ? LAND_MINE : BEARTRAP;
1074
1075             /* convert trap into buried object (deletes trap) */
1076             cnv_trap_obj(otyp, 1, ttmp, TRUE);
1077         }
1078
1079         /* finally we get to make a hole */
1080         if (nohole || pit_only)
1081             digactualhole(dig_x, dig_y, BY_YOU, PIT);
1082         else
1083             digactualhole(dig_x, dig_y, BY_YOU, HOLE);
1084
1085         return TRUE;
1086     }
1087
1088     return FALSE;
1089 }
1090
1091 STATIC_OVL void
1092 dig_up_grave(cc)
1093 coord *cc;
1094 {
1095     struct obj *otmp;
1096     xchar dig_x, dig_y;
1097
1098     if (!cc) {
1099         dig_x = u.ux;
1100         dig_y = u.uy;
1101     } else {
1102         dig_x = cc->x;
1103         dig_y = cc->y;
1104         if (!isok(dig_x, dig_y))
1105             return;
1106     }
1107
1108     /* Grave-robbing is frowned upon... */
1109     exercise(A_WIS, FALSE);
1110     if (Role_if(PM_ARCHEOLOGIST)) {
1111         adjalign(-sgn(u.ualign.type) * 3);
1112 /*JP
1113         You_feel("like a despicable grave-robber!");
1114 */
1115         pline("\82±\82ê\82Å\82Í\82Ü\82é\82Å\95æ\93D\96_\82¾\81I");
1116     } else if (Role_if(PM_SAMURAI)) {
1117         adjalign(-sgn(u.ualign.type));
1118 /*JP
1119         You("disturb the honorable dead!");
1120 */
1121         You("\96¼\97_\82 \82é\8e\80\8eÒ\82Ì\96°\82è\82ð\96W\82°\82¾\81I");
1122     } else if ((u.ualign.type == A_LAWFUL) && (u.ualign.record > -10)) {
1123         adjalign(-sgn(u.ualign.type));
1124 /*JP
1125         You("have violated the sanctity of this grave!");
1126 */
1127         You("\90¹\82È\82é\95æ\92n\82ð\94Æ\82µ\82½\81I");
1128     }
1129
1130     switch (rn2(5)) {
1131     case 0:
1132     case 1:
1133 /*JP
1134         You("unearth a corpse.");
1135 */
1136         You("\8e\80\91Ì\82ð\8c@\82è\8bN\82µ\82½\81D");
1137         if (!!(otmp = mk_tt_object(CORPSE, dig_x, dig_y)))
1138             otmp->age -= 100; /* this is an *OLD* corpse */
1139         ;
1140         break;
1141     case 2:
1142         if (!Blind)
1143 /*JP
1144             pline(Hallucination ? "Dude!  The living dead!"
1145 */
1146             pline(Hallucination ? "\83]\83\93\83r\82ª\82­\82é\82è\82Æ\97Ö\82ð\95`\82¢\82½\81I"
1147 /*JP
1148                                 : "The grave's owner is very upset!");
1149 */
1150                                 : "\95æ\82Ì\8f\8a\97L\8eÒ\82Í\82Æ\82Ä\82à\8bÁ\82¢\82½\81I");
1151         (void) makemon(mkclass(S_ZOMBIE, 0), dig_x, dig_y, NO_MM_FLAGS);
1152         break;
1153     case 3:
1154         if (!Blind)
1155 /*JP
1156             pline(Hallucination ? "I want my mummy!"
1157 */
1158             pline(Hallucination ? "\83}\83~\81[\82ª\95K\97v\82¾\81I"
1159 /*JP
1160                                 : "You've disturbed a tomb!");
1161 */
1162                                 : "\95æ\82ð\8dr\82µ\82Ä\82µ\82Ü\82Á\82½\81I");
1163         (void) makemon(mkclass(S_MUMMY, 0), dig_x, dig_y, NO_MM_FLAGS);
1164         break;
1165     default:
1166         /* No corpse */
1167 /*JP
1168         pline_The("grave seems unused.  Strange....");
1169 */
1170         pline("\82±\82Ì\95æ\82Í\96¢\8eg\97p\82Ì\82æ\82¤\82¾\81D\8aï\96­\82¾\81D\81D\81D");
1171         break;
1172     }
1173     levl[dig_x][dig_y].typ = ROOM;
1174     del_engr_at(dig_x, dig_y);
1175     newsym(dig_x, dig_y);
1176     return;
1177 }
1178
1179 int
1180 use_pick_axe(obj)
1181 struct obj *obj;
1182 {
1183     const char *sdp, *verb;
1184     char *dsp, dirsyms[12], qbuf[BUFSZ];
1185     boolean ispick;
1186     int rx, ry, downok, res = 0;
1187
1188     /* Check tool */
1189     if (obj != uwep) {
1190         if (!wield_tool(obj, "swing"))
1191             return 0;
1192         else
1193             res = 1;
1194     }
1195     ispick = is_pick(obj);
1196 /*JP
1197     verb = ispick ? "dig" : "chop";
1198 */
1199     verb = ispick ? "\8c@\82é" : "\8dÓ\82­";
1200
1201     if (u.utrap && u.utraptype == TT_WEB) {
1202 #if 0 /*JP:T*/
1203         pline("%s you can't %s while entangled in a web.",
1204               /* res==0 => no prior message;
1205                  res==1 => just got "You now wield a pick-axe." message */
1206               !res ? "Unfortunately," : "But", verb);
1207 #else
1208         pline("%s\82­\82à\82Ì\91\83\82É\82Ð\82Á\82©\82©\82Á\82Ä\82¢\82é\8aÔ\82Í%s\81D",
1209               !res ? "\8ec\94O\82È\82ª\82ç" : "\82µ\82©\82µ", jconj(verb, "\82È\82¢"));
1210 #endif
1211         return res;
1212     }
1213
1214     /* construct list of directions to show player for likely choices */
1215     downok = !!can_reach_floor(FALSE);
1216     dsp = dirsyms;
1217     for (sdp = Cmd.dirchars; *sdp; ++sdp) {
1218         /* filter out useless directions */
1219         if (u.uswallow) {
1220             ; /* all directions are viable when swallowed */
1221         } else if (movecmd(*sdp)) {
1222             /* normal direction, within plane of the level map;
1223                movecmd() sets u.dx, u.dy, u.dz and returns !u.dz */
1224             if (!dxdy_moveok())
1225                 continue; /* handle NODIAG */
1226             rx = u.ux + u.dx;
1227             ry = u.uy + u.dy;
1228             if (!isok(rx, ry) || dig_typ(obj, rx, ry) == DIGTYP_UNDIGGABLE)
1229                 continue;
1230         } else {
1231             /* up or down; we used to always include down, so that
1232                there would always be at least one choice shown, but
1233                it shouldn't be a likely candidate when floating high
1234                above the floor; include up instead in that situation
1235                (as a silly candidate rather than a likely one...) */
1236             if ((u.dz > 0) ^ downok)
1237                 continue;
1238         }
1239         /* include this direction */
1240         *dsp++ = *sdp;
1241     }
1242     *dsp = 0;
1243 /*JP
1244     Sprintf(qbuf, "In what direction do you want to %s? [%s]", verb, dirsyms);
1245 */
1246     Sprintf(qbuf, "\82Ç\82Ì\95û\8cü\82ð%s\81H[%s]", verb, dirsyms);
1247     if (!getdir(qbuf))
1248         return res;
1249
1250     return use_pick_axe2(obj);
1251 }
1252
1253 /* MRKR: use_pick_axe() is split in two to allow autodig to bypass */
1254 /*       the "In what direction do you want to dig?" query.        */
1255 /*       use_pick_axe2() uses the existing u.dx, u.dy and u.dz    */
1256 int
1257 use_pick_axe2(obj)
1258 struct obj *obj;
1259 {
1260     register int rx, ry;
1261     register struct rm *lev;
1262     struct trap *trap, *trap_with_u;
1263     int dig_target;
1264     boolean ispick = is_pick(obj);
1265 /*JP
1266     const char *verbing = ispick ? "digging" : "chopping";
1267 */
1268     const char *verbing = ispick ? "\8c@\82é" : "\8dÓ\82­";
1269
1270     if (u.uswallow && attack(u.ustuck)) {
1271         ; /* return 1 */
1272     } else if (Underwater) {
1273 /*JP
1274         pline("Turbulence torpedoes your %s attempts.", verbing);
1275 */
1276         pline("%s\82Æ\82·\82é\82Æ\97\90\90\85\97¬\82ª\8bN\82«\82½\81D", jconj(verbing, "\82æ\82¤"));
1277     } else if (u.dz < 0) {
1278         if (Levitation)
1279 /*JP
1280             You("don't have enough leverage.");
1281 */
1282             You("\95\82\82¢\82Ä\82¢\82é\82Ì\82Å\82Ó\82ñ\82Î\82è\82ª\82«\82©\82È\82¢\81D");
1283         else
1284 /*JP
1285             You_cant("reach the %s.", ceiling(u.ux, u.uy));
1286 */
1287             You("%s\82É\93Í\82©\82È\82¢\81D", ceiling(u.ux,u.uy));
1288     } else if (!u.dx && !u.dy && !u.dz) {
1289         char buf[BUFSZ];
1290         int dam;
1291
1292         dam = rnd(2) + dbon() + obj->spe;
1293         if (dam <= 0)
1294             dam = 1;
1295 /*JP
1296         You("hit yourself with %s.", yname(uwep));
1297 */
1298         You("\8e©\95ª\8e©\90g\82ð%s\82Å\92@\82¢\82½\81D", yname(uwep));
1299 /*JP
1300         Sprintf(buf, "%s own %s", uhis(), OBJ_NAME(objects[obj->otyp]));
1301 */
1302         Sprintf(buf, "\8e©\95ª\8e©\90g\82ð%s\82Å\92@\82¢\82Ä", yname(uwep));
1303         losehp(Maybe_Half_Phys(dam), buf, KILLED_BY);
1304         context.botl = 1;
1305         return 1;
1306     } else if (u.dz == 0) {
1307         if (Stunned || (Confusion && !rn2(5)))
1308             confdir();
1309         rx = u.ux + u.dx;
1310         ry = u.uy + u.dy;
1311         if (!isok(rx, ry)) {
1312 /*JP
1313             pline("Clash!");
1314 */
1315             pline("\83K\83\89\83K\83\89\81I");
1316             return 1;
1317         }
1318         lev = &levl[rx][ry];
1319         if (MON_AT(rx, ry) && attack(m_at(rx, ry)))
1320             return 1;
1321         dig_target = dig_typ(obj, rx, ry);
1322         if (dig_target == DIGTYP_UNDIGGABLE) {
1323             /* ACCESSIBLE or POOL */
1324             trap = t_at(rx, ry);
1325             if (trap && trap->ttyp == WEB) {
1326                 if (!trap->tseen) {
1327                     seetrap(trap);
1328 /*JP
1329                     There("is a spider web there!");
1330 */
1331                     pline("\82»\82±\82É\82Í\82­\82à\82Ì\91\83\82ª\82 \82é\81I");
1332                 }
1333 /*JP
1334                 pline("%s entangled in the web.", Yobjnam2(obj, "become"));
1335 */
1336                 Your("%s\82Í\82­\82à\82Ì\91\83\82É\82©\82ç\82Ü\82Á\82½\81D", xname(obj));
1337                 /* you ought to be able to let go; tough luck */
1338                 /* (maybe `move_into_trap()' would be better) */
1339                 nomul(-d(2, 2));
1340                 multi_reason = "stuck in a spider web";
1341 /*JP
1342                 nomovemsg = "You pull free.";
1343 */
1344                 nomovemsg = "\82Ð\82«\82Í\82È\82µ\82½\81D";
1345             } else if (lev->typ == IRONBARS) {
1346 /*JP
1347                 pline("Clang!");
1348 */
1349                 pline("\83K\83c\83\93\81I");
1350                 wake_nearby();
1351             } else if (IS_TREE(lev->typ))
1352 /*JP
1353                 You("need an axe to cut down a tree.");
1354 */
1355                 You("\96Ø\82ð\90Ø\82é\82É\82Í\95\80\82ª\95K\97v\82¾\81D");
1356             else if (IS_ROCK(lev->typ))
1357 /*JP
1358                 You("need a pick to dig rock.");
1359 */
1360                 You("\8c@\82é\82É\82Í\82Â\82é\82Í\82µ\82ª\95K\97v\82¾\81D");
1361             else if (!ispick && (sobj_at(STATUE, rx, ry)
1362                                  || sobj_at(BOULDER, rx, ry))) {
1363                 boolean vibrate = !rn2(3);
1364 #if 0 /*JP:T*/
1365                 pline("Sparks fly as you whack the %s.%s",
1366                       sobj_at(STATUE, rx, ry) ? "statue" : "boulder",
1367                       vibrate ? " The axe-handle vibrates violently!" : "");
1368 #else
1369                 pline("%s\82ð\90Ø\82ë\82¤\82Æ\82µ\82½\82ç\89Î\89Ô\82ª\8eU\82Á\82½\81I%s",
1370                       sobj_at(STATUE, rx, ry) ? "\92¤\91\9c" : "\8aâ",
1371                       vibrate ? "\95\80\82Í\8c\83\82µ\82­\90U\93®\82µ\82½\81I" : "");
1372 #endif
1373                 if (vibrate)
1374 /*JP
1375                     losehp(Maybe_Half_Phys(2), "axing a hard object",
1376 */
1377                     losehp(Maybe_Half_Phys(2), "\8cÅ\82¢\82à\82Ì\82É\95\80\82ð\8eg\82¨\82¤\82Æ\82µ\82Ä",
1378                            KILLED_BY);
1379             } else if (u.utrap && u.utraptype == TT_PIT && trap
1380                        && (trap_with_u = t_at(u.ux, u.uy))
1381                        && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)
1382                        && !conjoined_pits(trap, trap_with_u, FALSE)) {
1383                 int idx;
1384                 for (idx = 0; idx < 8; idx++) {
1385                     if (xdir[idx] == u.dx && ydir[idx] == u.dy)
1386                         break;
1387                 }
1388                 /* idx is valid if < 8 */
1389                 if (idx < 8) {
1390                     int adjidx = (idx + 4) % 8;
1391                     trap_with_u->conjoined |= (1 << idx);
1392                     trap->conjoined |= (1 << adjidx);
1393                     pline("You clear some debris from between the pits.");
1394                 }
1395             } else if (u.utrap && u.utraptype == TT_PIT
1396                        && (trap_with_u = t_at(u.ux, u.uy))) {
1397                 You("swing %s, but the rubble has no place to go.",
1398                     yobjnam(obj, (char *) 0));
1399             } else
1400                 You("swing %s through thin air.", yobjnam(obj, (char *) 0));
1401         } else {
1402 #if 0 /*JP*/
1403             static const char *const d_action[6] = { "swinging", "digging",
1404                                                      "chipping the statue",
1405                                                      "hitting the boulder",
1406                                                      "chopping at the door",
1407                                                      "cutting the tree" };
1408 #else
1409             static const char * const d_action1[6] = {
1410                 "\90U\82è",
1411                 "\8c@\82è",
1412                 "\92¤\91\9c\82ð\8dí\82è",
1413                 "\8aâ\82ð\91Å\82¿\82Â\82¯",
1414                 "\94à\82ð\8dí\82è",
1415                 "\96Ø\82ð\90Ø\82è"
1416               };
1417             static const char * const d_action2[6] = {
1418                 "\90U\82é",
1419                 "\8c@\82é",
1420                 "\92¤\91\9c\82ð\8dí\82é",
1421                 "\8aâ\82ð\91Å\82¿\82Â\82¯\82é",
1422                 "\94à\82ð\8dí\82é",
1423                 "\96Ø\82ð\90Ø\82é"
1424               };
1425 #endif
1426             did_dig_msg = FALSE;
1427             context.digging.quiet = FALSE;
1428             if (context.digging.pos.x != rx || context.digging.pos.y != ry
1429                 || !on_level(&context.digging.level, &u.uz)
1430                 || context.digging.down) {
1431                 if (flags.autodig && dig_target == DIGTYP_ROCK
1432                     && !context.digging.down && context.digging.pos.x == u.ux
1433                     && context.digging.pos.y == u.uy
1434                     && (moves <= context.digging.lastdigtime + 2
1435                         && moves >= context.digging.lastdigtime)) {
1436                     /* avoid messages if repeated autodigging */
1437                     did_dig_msg = TRUE;
1438                     context.digging.quiet = TRUE;
1439                 }
1440                 context.digging.down = context.digging.chew = FALSE;
1441                 context.digging.warned = FALSE;
1442                 context.digging.pos.x = rx;
1443                 context.digging.pos.y = ry;
1444                 assign_level(&context.digging.level, &u.uz);
1445                 context.digging.effort = 0;
1446                 if (!context.digging.quiet)
1447 /*JP
1448                     You("start %s.", d_action[dig_target]);
1449 */
1450                     You("%s\82Í\82\82ß\82½\81D", d_action1[dig_target]);
1451             } else {
1452 #if 0 /*JP*/
1453                 You("%s %s.", context.digging.chew ? "begin" : "continue",
1454                     d_action[dig_target]);
1455 #else
1456                 You("%s\82Ì\82ð%s\82µ\82½\81D", d_action2[dig_target],
1457                     context.digging.chew ? "\8aJ\8en" : "\8dÄ\8aJ");
1458 #endif
1459                 context.digging.chew = FALSE;
1460             }
1461             set_occupation(dig, verbing, 0);
1462         }
1463     } else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) {
1464         /* it must be air -- water checked above */
1465 /*JP
1466         You("swing %s through thin air.", yobjnam(obj, (char *) 0));
1467 */
1468         You("\89½\82à\82È\82¢\8bó\8aÔ\82Å%s\82ð\90U\82è\82Ü\82í\82µ\82½\81D", xname(obj));
1469     } else if (!can_reach_floor(FALSE)) {
1470         cant_reach_floor(u.ux, u.uy, FALSE, FALSE);
1471     } else if (is_pool_or_lava(u.ux, u.uy)) {
1472         /* Monsters which swim also happen not to be able to dig */
1473 #if 0 /*JP:T*/
1474         You("cannot stay under%s long enough.",
1475             is_pool(u.ux, u.uy) ? "water" : " the lava");
1476 #else
1477         You("%s\82É\82Í\92·\8e\9e\8aÔ\82¢\82ç\82ê\82È\82¢\81D",
1478             is_pool(u.ux, u.uy) ? "\90\85\96Ê\89º" : "\97n\8aâ\82Ì\92\86");
1479 #endif
1480     } else if ((trap = t_at(u.ux, u.uy)) != 0
1481                && uteetering_at_seen_pit(trap)) {
1482         dotrap(trap, FORCEBUNGLE);
1483         /* might escape trap and still be teetering at brink */
1484         if (!u.utrap)
1485             cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
1486     } else if (!ispick
1487                /* can only dig down with an axe when doing so will
1488                   trigger or disarm a trap here */
1489                && (!trap || (trap->ttyp != LANDMINE
1490                              && trap->ttyp != BEAR_TRAP))) {
1491 #if 0 /*JP:T*/
1492         pline("%s merely scratches the %s.", Yobjnam2(obj, (char *) 0),
1493               surface(u.ux, u.uy));
1494 #else
1495         Your("%s\82Í%s\82É\82©\82·\82è\8f\9d\82ð\82Â\82¯\82½\82¾\82¯\82¾\82Á\82½\81D", aobjnam(obj, (char *)0),
1496               surface(u.ux,u.uy));
1497 #endif
1498         u_wipe_engr(3);
1499     } else {
1500         if (context.digging.pos.x != u.ux || context.digging.pos.y != u.uy
1501             || !on_level(&context.digging.level, &u.uz)
1502             || !context.digging.down) {
1503             context.digging.chew = FALSE;
1504             context.digging.down = TRUE;
1505             context.digging.warned = FALSE;
1506             context.digging.pos.x = u.ux;
1507             context.digging.pos.y = u.uy;
1508             assign_level(&context.digging.level, &u.uz);
1509             context.digging.effort = 0;
1510 /*JP
1511             You("start %s downward.", verbing);
1512 */
1513             You("\89º\8cü\82«\82É\8c@\82è\82Í\82\82ß\82½\81D");
1514             if (*u.ushops)
1515                 shopdig(0);
1516         } else
1517 /*JP
1518             You("continue %s downward.", verbing);
1519 */
1520             You("\89º\8cü\82«\82É\8c@\82é\82Ì\82ð\8dÄ\8aJ\82µ\82½\81D");
1521         did_dig_msg = FALSE;
1522         set_occupation(dig, verbing, 0);
1523     }
1524     return 1;
1525 }
1526
1527 /*
1528  * Town Watchmen frown on damage to the town walls, trees or fountains.
1529  * It's OK to dig holes in the ground, however.
1530  * If mtmp is assumed to be a watchman, a watchman is found if mtmp == 0
1531  * zap == TRUE if wand/spell of digging, FALSE otherwise (chewing)
1532  */
1533 void
1534 watch_dig(mtmp, x, y, zap)
1535 struct monst *mtmp;
1536 xchar x, y;
1537 boolean zap;
1538 {
1539     struct rm *lev = &levl[x][y];
1540
1541     if (in_town(x, y)
1542         && (closed_door(x, y) || lev->typ == SDOOR || IS_WALL(lev->typ)
1543             || IS_FOUNTAIN(lev->typ) || IS_TREE(lev->typ))) {
1544         if (!mtmp) {
1545             for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
1546                 if (DEADMONSTER(mtmp))
1547                     continue;
1548                 if (is_watch(mtmp->data) && mtmp->mcansee && m_canseeu(mtmp)
1549                     && couldsee(mtmp->mx, mtmp->my) && mtmp->mpeaceful)
1550                     break;
1551             }
1552         }
1553
1554         if (mtmp) {
1555             if (zap || context.digging.warned) {
1556 /*JP
1557                 verbalize("Halt, vandal!  You're under arrest!");
1558 */
1559                 verbalize("\8e~\82Ü\82ê\96ì\94Ø\90l\81I\82¨\82Ü\82¦\82ð\91ß\95ß\82·\82é\81I");
1560                 (void) angry_guards(!!Deaf);
1561             } else {
1562                 const char *str;
1563
1564                 if (IS_DOOR(lev->typ))
1565 /*JP
1566                     str = "door";
1567 */
1568                     str = "\94à";
1569                 else if (IS_TREE(lev->typ))
1570 /*JP
1571                     str = "tree";
1572 */
1573                     str = "\96Ø";
1574                 else if (IS_ROCK(lev->typ))
1575 /*JP
1576                     str = "wall";
1577 */
1578                     str = "\95Ç";
1579                 else
1580 /*JP
1581                     str = "fountain";
1582 */
1583                     str = "\90ò";
1584 /*JP
1585                 verbalize("Hey, stop damaging that %s!", str);
1586 */
1587                 verbalize("\82¨\82¢\81C%s\82ð\94j\89ó\82·\82é\82Ì\82ð\82â\82ß\82ë\81I", str);
1588                 context.digging.warned = TRUE;
1589             }
1590             if (is_digging())
1591                 stop_occupation();
1592         }
1593     }
1594 }
1595
1596 /* Return TRUE if monster died, FALSE otherwise.  Called from m_move(). */
1597 boolean
1598 mdig_tunnel(mtmp)
1599 register struct monst *mtmp;
1600 {
1601     register struct rm *here;
1602     int pile = rnd(12);
1603
1604     here = &levl[mtmp->mx][mtmp->my];
1605     if (here->typ == SDOOR)
1606         cvt_sdoor_to_door(here); /* ->typ = DOOR */
1607
1608     /* Eats away door if present & closed or locked */
1609     if (closed_door(mtmp->mx, mtmp->my)) {
1610         if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
1611             add_damage(mtmp->mx, mtmp->my, 0L);
1612         unblock_point(mtmp->mx, mtmp->my); /* vision */
1613         if (here->doormask & D_TRAPPED) {
1614             here->doormask = D_NODOOR;
1615             if (mb_trapped(mtmp)) { /* mtmp is killed */
1616                 newsym(mtmp->mx, mtmp->my);
1617                 return TRUE;
1618             }
1619         } else {
1620             if (!rn2(3) && flags.verbose) /* not too often.. */
1621                 draft_message(TRUE); /* "You feel an unexpected draft." */
1622             here->doormask = D_BROKEN;
1623         }
1624         newsym(mtmp->mx, mtmp->my);
1625         return FALSE;
1626     } else if (here->typ == SCORR) {
1627         here->typ = CORR;
1628         unblock_point(mtmp->mx, mtmp->my);
1629         newsym(mtmp->mx, mtmp->my);
1630         draft_message(FALSE); /* "You feel a draft." */
1631         return FALSE;
1632     } else if (!IS_ROCK(here->typ) && !IS_TREE(here->typ)) /* no dig */
1633         return FALSE;
1634
1635     /* Only rock, trees, and walls fall through to this point. */
1636     if ((here->wall_info & W_NONDIGGABLE) != 0) {
1637         impossible("mdig_tunnel:  %s at (%d,%d) is undiggable",
1638                    (IS_WALL(here->typ) ? "wall"
1639                     : IS_TREE(here->typ) ? "tree" : "stone"),
1640                    (int) mtmp->mx, (int) mtmp->my);
1641         return FALSE; /* still alive */
1642     }
1643
1644     if (IS_WALL(here->typ)) {
1645         /* KMH -- Okay on arboreal levels (room walls are still stone) */
1646         if (flags.verbose && !rn2(5))
1647 /*JP
1648             You_hear("crashing rock.");
1649 */
1650             You_hear("\8aâ\82Ì\82­\82¾\82¯\82é\89¹\82ð\95·\82¢\82½\81D");
1651         if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
1652             add_damage(mtmp->mx, mtmp->my, 0L);
1653         if (level.flags.is_maze_lev) {
1654             here->typ = ROOM;
1655         } else if (level.flags.is_cavernous_lev
1656                    && !in_town(mtmp->mx, mtmp->my)) {
1657             here->typ = CORR;
1658         } else {
1659             here->typ = DOOR;
1660             here->doormask = D_NODOOR;
1661         }
1662     } else if (IS_TREE(here->typ)) {
1663         here->typ = ROOM;
1664         if (pile && pile < 5)
1665             (void) rnd_treefruit_at(mtmp->mx, mtmp->my);
1666     } else {
1667         here->typ = CORR;
1668         if (pile && pile < 5)
1669             (void) mksobj_at((pile == 1) ? BOULDER : ROCK, mtmp->mx, mtmp->my,
1670                              TRUE, FALSE);
1671     }
1672     newsym(mtmp->mx, mtmp->my);
1673     if (!sobj_at(BOULDER, mtmp->mx, mtmp->my))
1674         unblock_point(mtmp->mx, mtmp->my); /* vision */
1675
1676     return FALSE;
1677 }
1678
1679 #define STRIDENT 4 /* from pray.c */
1680
1681 /* draft refers to air currents, but can be a pun on "draft" as conscription
1682    for military service (probably not a good pun if it has to be explained) */
1683 void
1684 draft_message(unexpected)
1685 boolean unexpected;
1686 {
1687     /*
1688      * [Bug or TODO?  Have caller pass coordinates and use the travel
1689      * mechanism to determine whether there is a path between
1690      * destroyed door (or exposed secret corridor) and hero's location.
1691      * When there is no such path, no draft should be felt.]
1692      */
1693
1694     if (unexpected) {
1695         if (!Hallucination)
1696 /*JP
1697             You_feel("an unexpected draft.");
1698 */
1699             You("\8ev\82¢\82à\82æ\82ç\82¸\81C\82·\82«\82Ü\95\97\82ð\8a´\82\82½\81D");
1700         else
1701             /* U.S. classification system uses 1-A for eligible to serve
1702                and 4-F for ineligible due to physical or mental defect;
1703                some intermediate values exist but are rarely seen */
1704             You_feel("like you are %s.",
1705                      (ACURR(A_STR) < 6 || ACURR(A_DEX) < 6
1706                       || ACURR(A_CON) < 6 || ACURR(A_CHA) < 6
1707                       || ACURR(A_INT) < 6 || ACURR(A_WIS) < 6) ? "4-F"
1708                                                                : "1-A");
1709     } else {
1710         if (!Hallucination) {
1711             You_feel("a draft.");
1712         } else {
1713             /* "marching" is deliberately ambiguous; it might mean drills
1714                 after entering military service or mean engaging in protests */
1715             static const char *draft_reaction[] = {
1716                 "enlisting", "marching", "protesting", "fleeing",
1717             };
1718             int dridx;
1719
1720             /* Lawful: 0..1, Neutral: 1..2, Chaotic: 2..3 */
1721             dridx = rn1(2, 1 - sgn(u.ualign.type));
1722             if (u.ualign.record < STRIDENT)
1723                 /* L: +(0..2), N: +(-1..1), C: +(-2..0); all: 0..3 */
1724                 dridx += rn1(3, sgn(u.ualign.type) - 1);
1725             You_feel("like %s.", draft_reaction[dridx]);
1726         }
1727     }
1728 }
1729
1730 /* digging via wand zap or spell cast */
1731 void
1732 zap_dig()
1733 {
1734     struct rm *room;
1735     struct monst *mtmp;
1736     struct obj *otmp;
1737     struct trap *trap_with_u = (struct trap *) 0;
1738     int zx, zy, diridx = 8, digdepth, flow_x = -1, flow_y = -1;
1739     boolean shopdoor, shopwall, maze_dig, pitdig = FALSE, pitflow = FALSE;
1740
1741     /*
1742      * Original effect (approximately):
1743      * from CORR: dig until we pierce a wall
1744      * from ROOM: pierce wall and dig until we reach
1745      * an ACCESSIBLE place.
1746      * Currently: dig for digdepth positions;
1747      * also down on request of Lennart Augustsson.
1748      * 3.6.0: from a PIT: dig one adjacent pit.
1749      */
1750
1751     if (u.uswallow) {
1752         mtmp = u.ustuck;
1753
1754         if (!is_whirly(mtmp->data)) {
1755             if (is_animal(mtmp->data))
1756 #if 0 /*JP*/
1757                 You("pierce %s %s wall!", s_suffix(mon_nam(mtmp)),
1758                     mbodypart(mtmp, STOMACH));
1759 #else
1760                 You("%s\82Ì%s\82Ì\95Ç\82É\8c\8a\82ð\8aJ\82¯\82½\81I", s_suffix(mon_nam(mtmp)),
1761                     mbodypart(mtmp, STOMACH));
1762 #endif
1763             mtmp->mhp = 1; /* almost dead */
1764             expels(mtmp, mtmp->data, !is_animal(mtmp->data));
1765         }
1766         return;
1767     } /* swallowed */
1768
1769     if (u.dz) {
1770         if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !Underwater) {
1771             if (u.dz < 0 || On_stairs(u.ux, u.uy)) {
1772                 int dmg;
1773                 if (On_stairs(u.ux, u.uy))
1774 #if 0 /*JP*/
1775                     pline_The("beam bounces off the %s and hits the %s.",
1776                               (u.ux == xdnladder || u.ux == xupladder)
1777                                   ? "ladder"
1778                                   : "stairs",
1779                               ceiling(u.ux, u.uy));
1780 #else
1781                     pline("\8cõ\90ü\82Í%s\82Å\94½\8eË\82µ%s\82É\96½\92\86\82µ\82½\81D",
1782                               (u.ux == xdnladder || u.ux == xupladder)
1783                                   ? "\82Í\82µ\82²"
1784                                   : "\8aK\92i",
1785                               ceiling(u.ux, u.uy));
1786 #endif
1787 /*JP
1788                 You("loosen a rock from the %s.", ceiling(u.ux, u.uy));
1789 */
1790                 pline("%s\82Ì\8aâ\82ª\83K\83^\83K\83^\82µ\82Í\82\82ß\82½\81D", ceiling(u.ux, u.uy));
1791 /*JP
1792                 pline("It falls on your %s!", body_part(HEAD));
1793 */
1794                 pline("\82»\82ê\82Í\82 \82È\82½\82Ì%s\82É\97\8e\82¿\82Ä\82«\82½\81I", body_part(HEAD));
1795                 dmg = rnd((uarmh && is_metallic(uarmh)) ? 2 : 6);
1796 /*JP
1797                 losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN);
1798 */
1799                 losehp(Maybe_Half_Phys(dmg), "\97\8e\8aâ\82Å", KILLED_BY_AN);
1800                 otmp = mksobj_at(ROCK, u.ux, u.uy, FALSE, FALSE);
1801                 if (otmp) {
1802                     (void) xname(otmp); /* set dknown, maybe bknown */
1803                     stackobj(otmp);
1804                 }
1805                 newsym(u.ux, u.uy);
1806             } else {
1807                 watch_dig((struct monst *) 0, u.ux, u.uy, TRUE);
1808                 (void) dighole(FALSE, TRUE, (coord *) 0);
1809             }
1810         }
1811         return;
1812     } /* up or down */
1813
1814     /* normal case: digging across the level */
1815     shopdoor = shopwall = FALSE;
1816     maze_dig = level.flags.is_maze_lev && !Is_earthlevel(&u.uz);
1817     zx = u.ux + u.dx;
1818     zy = u.uy + u.dy;
1819     if (u.utrap && u.utraptype == TT_PIT
1820         && (trap_with_u = t_at(u.ux, u.uy))) {
1821         pitdig = TRUE;
1822         for (diridx = 0; diridx < 8; diridx++) {
1823             if (xdir[diridx] == u.dx && ydir[diridx] == u.dy)
1824                 break;
1825             /* diridx is valid if < 8 */
1826         }
1827     }
1828     digdepth = rn1(18, 8);
1829     tmp_at(DISP_BEAM, cmap_to_glyph(S_digbeam));
1830     while (--digdepth >= 0) {
1831         if (!isok(zx, zy))
1832             break;
1833         room = &levl[zx][zy];
1834         tmp_at(zx, zy);
1835         delay_output(); /* wait a little bit */
1836
1837         if (pitdig) { /* we are already in a pit if this is true */
1838             coord cc;
1839             struct trap *adjpit = t_at(zx, zy);
1840             if ((diridx < 8) && !conjoined_pits(adjpit, trap_with_u, FALSE)) {
1841                 digdepth = 0; /* limited to the adjacent location only */
1842                 if (!(adjpit && (adjpit->ttyp == PIT
1843                                  || adjpit->ttyp == SPIKED_PIT))) {
1844                     char buf[BUFSZ];
1845                     cc.x = zx;
1846                     cc.y = zy;
1847                     if (!adj_pit_checks(&cc, buf)) {
1848                         if (buf[0])
1849                             pline1(buf);
1850                     } else {
1851                         /* this can also result in a pool at zx,zy */
1852                         dighole(TRUE, TRUE, &cc);
1853                         adjpit = t_at(zx, zy);
1854                     }
1855                 }
1856                 if (adjpit
1857                     && (adjpit->ttyp == PIT || adjpit->ttyp == SPIKED_PIT)) {
1858                     int adjidx = (diridx + 4) % 8;
1859                     trap_with_u->conjoined |= (1 << diridx);
1860                     adjpit->conjoined |= (1 << adjidx);
1861                     flow_x = zx;
1862                     flow_y = zy;
1863                     pitflow = TRUE;
1864                 }
1865                 if (is_pool(zx, zy) || is_lava(zx, zy)) {
1866                     flow_x = zx - u.dx;
1867                     flow_y = zy - u.dy;
1868                     pitflow = TRUE;
1869                 }
1870                 break;
1871             }
1872         } else if (closed_door(zx, zy) || room->typ == SDOOR) {
1873             if (*in_rooms(zx, zy, SHOPBASE)) {
1874                 add_damage(zx, zy, 400L);
1875                 shopdoor = TRUE;
1876             }
1877             if (room->typ == SDOOR)
1878                 room->typ = DOOR;
1879             else if (cansee(zx, zy))
1880 /*JP
1881                 pline_The("door is razed!");
1882 */
1883                 pline("\94à\82Í\95ö\82ê\97\8e\82¿\82½\81I");
1884             watch_dig((struct monst *) 0, zx, zy, TRUE);
1885             room->doormask = D_NODOOR;
1886             unblock_point(zx, zy); /* vision */
1887             digdepth -= 2;
1888             if (maze_dig)
1889                 break;
1890         } else if (maze_dig) {
1891             if (IS_WALL(room->typ)) {
1892                 if (!(room->wall_info & W_NONDIGGABLE)) {
1893                     if (*in_rooms(zx, zy, SHOPBASE)) {
1894                         add_damage(zx, zy, 200L);
1895                         shopwall = TRUE;
1896                     }
1897                     room->typ = ROOM;
1898                     unblock_point(zx, zy); /* vision */
1899                 } else if (!Blind)
1900 /*JP
1901                     pline_The("wall glows then fades.");
1902 */
1903                     pline("\95Ç\82Í\88ê\8fu\8bP\82¢\82½\81D");
1904                 break;
1905             } else if (IS_TREE(room->typ)) { /* check trees before stone */
1906                 if (!(room->wall_info & W_NONDIGGABLE)) {
1907                     room->typ = ROOM;
1908                     unblock_point(zx, zy); /* vision */
1909                 } else if (!Blind)
1910 /*JP
1911                     pline_The("tree shudders but is unharmed.");
1912 */
1913                     pline("\96Ø\82Í\82ä\82ê\82½\82ª\8f\9d\82Â\82©\82È\82©\82Á\82½\81D");
1914                 break;
1915             } else if (room->typ == STONE || room->typ == SCORR) {
1916                 if (!(room->wall_info & W_NONDIGGABLE)) {
1917                     room->typ = CORR;
1918                     unblock_point(zx, zy); /* vision */
1919                 } else if (!Blind)
1920 /*JP
1921                     pline_The("rock glows then fades.");
1922 */
1923                     pline("\90Î\82Í\88ê\8fu\8bP\82¢\82½\81D");
1924                 break;
1925             }
1926         } else if (IS_ROCK(room->typ)) {
1927             if (!may_dig(zx, zy))
1928                 break;
1929             if (IS_WALL(room->typ) || room->typ == SDOOR) {
1930                 if (*in_rooms(zx, zy, SHOPBASE)) {
1931                     add_damage(zx, zy, 200L);
1932                     shopwall = TRUE;
1933                 }
1934                 watch_dig((struct monst *) 0, zx, zy, TRUE);
1935                 if (level.flags.is_cavernous_lev && !in_town(zx, zy)) {
1936                     room->typ = CORR;
1937                 } else {
1938                     room->typ = DOOR;
1939                     room->doormask = D_NODOOR;
1940                 }
1941                 digdepth -= 2;
1942             } else if (IS_TREE(room->typ)) {
1943                 room->typ = ROOM;
1944                 digdepth -= 2;
1945             } else { /* IS_ROCK but not IS_WALL or SDOOR */
1946                 room->typ = CORR;
1947                 digdepth--;
1948             }
1949             unblock_point(zx, zy); /* vision */
1950         }
1951         zx += u.dx;
1952         zy += u.dy;
1953     }                    /* while */
1954     tmp_at(DISP_END, 0); /* closing call */
1955
1956     if (pitflow && isok(flow_x, flow_y)) {
1957         struct trap *ttmp = t_at(flow_x, flow_y);
1958         if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)) {
1959             schar filltyp = fillholetyp(ttmp->tx, ttmp->ty, TRUE);
1960             if (filltyp != ROOM)
1961                 pit_flow(ttmp, filltyp);
1962         }
1963     }
1964
1965     if (shopdoor || shopwall)
1966 /*JP
1967         pay_for_damage(shopdoor ? "destroy" : "dig into", FALSE);
1968 */
1969         pay_for_damage(shopdoor ? "\94j\89ó\82·\82é" : "\8c\8a\82ð\82 \82¯\82é", FALSE);
1970     return;
1971 }
1972
1973 /*
1974  * This checks what is on the surface above the
1975  * location where an adjacent pit might be created if
1976  * you're zapping a wand of digging laterally while
1977  * down in the pit.
1978  */
1979 STATIC_OVL int
1980 adj_pit_checks(cc, msg)
1981 coord *cc;
1982 char *msg;
1983 {
1984     int ltyp;
1985     struct rm *room;
1986     const char *foundation_msg =
1987         "The foundation is too hard to dig through from this angle.";
1988
1989     if (!cc)
1990         return FALSE;
1991     if (!isok(cc->x, cc->y))
1992         return FALSE;
1993     *msg = '\0';
1994     room = &levl[cc->x][cc->y];
1995     ltyp = room->typ;
1996
1997     if (is_pool(cc->x, cc->y) || is_lava(cc->x, cc->y)) {
1998         /* this is handled by the caller after we return FALSE */
1999         return FALSE;
2000     } else if (closed_door(cc->x, cc->y) || room->typ == SDOOR) {
2001         /* We reject this here because dighole() isn't
2002            prepared to deal with this case */
2003         Strcpy(msg, foundation_msg);
2004         return FALSE;
2005     } else if (IS_WALL(ltyp)) {
2006         /* if (room->wall_info & W_NONDIGGABLE) */
2007         Strcpy(msg, foundation_msg);
2008         return FALSE;
2009     } else if (IS_TREE(ltyp)) { /* check trees before stone */
2010         /* if (room->wall_info & W_NONDIGGABLE) */
2011         Strcpy(msg, "The tree's roots glow then fade.");
2012         return FALSE;
2013     } else if (ltyp == STONE || ltyp == SCORR) {
2014         if (room->wall_info & W_NONDIGGABLE) {
2015             Strcpy(msg, "The rock glows then fades.");
2016             return FALSE;
2017         }
2018     } else if (ltyp == IRONBARS) {
2019         /* "set of iron bars" */
2020         Strcpy(msg, "The bars go much deeper than your pit.");
2021 #if 0
2022     } else if (is_lava(cc->x, cc->y)) {
2023     } else if (is_ice(cc->x, cc->y)) {
2024     } else if (is_pool(cc->x, cc->y)) {
2025     } else if (IS_GRAVE(ltyp)) {
2026 #endif
2027     } else if (IS_SINK(ltyp)) {
2028         Strcpy(msg, "A tangled mass of plumbing remains below the sink.");
2029         return FALSE;
2030     } else if ((cc->x == xupladder && cc->y == yupladder) /* ladder up */
2031                || (cc->x == xdnladder && cc->y == ydnladder)) { /* " down */
2032         Strcpy(msg, "The ladder is unaffected.");
2033         return FALSE;
2034     } else {
2035         const char *supporting = (const char *) 0;
2036
2037         if (IS_FOUNTAIN(ltyp))
2038             supporting = "fountain";
2039         else if (IS_THRONE(ltyp))
2040             supporting = "throne";
2041         else if (IS_ALTAR(ltyp))
2042             supporting = "altar";
2043         else if ((cc->x == xupstair && cc->y == yupstair)
2044                  || (cc->x == sstairs.sx && cc->y == sstairs.sy
2045                      && sstairs.up))
2046             /* "staircase up" */
2047             supporting = "stairs";
2048         else if ((cc->x == xdnstair && cc->y == ydnstair)
2049                  || (cc->x == sstairs.sx && cc->y == sstairs.sy
2050                      && !sstairs.up))
2051             /* "staircase down" */
2052             supporting = "stairs";
2053         else if (ltyp == DRAWBRIDGE_DOWN   /* "lowered drawbridge" */
2054                  || ltyp == DBWALL)        /* "raised drawbridge" */
2055             supporting = "drawbridge";
2056
2057         if (supporting) {
2058             Sprintf(msg, "The %s%ssupporting structures remain intact.",
2059                     supporting ? s_suffix(supporting) : "",
2060                     supporting ? " " : "");
2061             return FALSE;
2062         }
2063     }
2064     return TRUE;
2065 }
2066
2067 /*
2068  * Ensure that all conjoined pits fill up.
2069  */
2070 STATIC_OVL void
2071 pit_flow(trap, filltyp)
2072 struct trap *trap;
2073 schar filltyp;
2074 {
2075     if (trap && (filltyp != ROOM)
2076         && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
2077         struct trap t;
2078         int idx;
2079
2080         t = *trap;
2081         levl[trap->tx][trap->ty].typ = filltyp;
2082         liquid_flow(trap->tx, trap->ty, filltyp, trap,
2083                     (trap->tx == u.ux && trap->ty == u.uy)
2084                         ? "Suddenly %s flows in from the adjacent pit!"
2085                         : (char *) 0);
2086         for (idx = 0; idx < 8; ++idx) {
2087             if (t.conjoined & (1 << idx)) {
2088                 int x, y;
2089                 struct trap *t2;
2090
2091                 x = t.tx + xdir[idx];
2092                 y = t.ty + ydir[idx];
2093                 t2 = t_at(x, y);
2094 #if 0
2095                 /* cannot do this back-check; liquid_flow()
2096                  * called deltrap() which cleaned up the
2097                  * conjoined fields on both pits.
2098                  */
2099                 if (t2 && (t2->conjoined & (1 << ((idx + 4) % 8))))
2100 #endif
2101                 /* recursion */
2102                 pit_flow(t2, filltyp);
2103             }
2104         }
2105     }
2106 }
2107
2108 struct obj *
2109 buried_ball(cc)
2110 coord *cc;
2111 {
2112     xchar check_x, check_y;
2113     struct obj *otmp, *otmp2;
2114
2115     if (u.utraptype == TT_BURIEDBALL)
2116         for (otmp = level.buriedobjlist; otmp; otmp = otmp2) {
2117             otmp2 = otmp->nobj;
2118             if (otmp->otyp != HEAVY_IRON_BALL)
2119                 continue;
2120             /* try the exact location first */
2121             if (otmp->ox == cc->x && otmp->oy == cc->y)
2122                 return otmp;
2123             /* Now try the vicinity */
2124             /*
2125              * (x-2,y-2)       (x+2,y-2)
2126              *           (x,y)
2127              * (x-2,y+2)       (x+2,y+2)
2128              */
2129             for (check_x = cc->x - 2; check_x <= cc->x + 2; ++check_x)
2130                 for (check_y = cc->y - 2; check_y <= cc->y + 2; ++check_y) {
2131                     if (check_x == cc->x && check_y == cc->y)
2132                         continue;
2133                     if (isok(check_x, check_y)
2134                         && (otmp->ox == check_x && otmp->oy == check_y)) {
2135                         cc->x = check_x;
2136                         cc->y = check_y;
2137                         return otmp;
2138                     }
2139                 }
2140         }
2141     return (struct obj *) 0;
2142 }
2143
2144 void
2145 buried_ball_to_punishment()
2146 {
2147     coord cc;
2148     struct obj *ball;
2149     cc.x = u.ux;
2150     cc.y = u.uy;
2151     ball = buried_ball(&cc);
2152     if (ball) {
2153         obj_extract_self(ball);
2154 #if 0
2155         /* rusting buried metallic objects is not implemented yet */
2156         if (ball->timed)
2157             (void) stop_timer(RUST_METAL, obj_to_any(ball));
2158 #endif
2159         punish(ball); /* use ball as flag for unearthed buried ball */
2160         u.utrap = 0;
2161         u.utraptype = 0;
2162         del_engr_at(cc.x, cc.y);
2163         newsym(cc.x, cc.y);
2164     }
2165 }
2166
2167 void
2168 buried_ball_to_freedom()
2169 {
2170     coord cc;
2171     struct obj *ball;
2172     cc.x = u.ux;
2173     cc.y = u.uy;
2174     ball = buried_ball(&cc);
2175     if (ball) {
2176         obj_extract_self(ball);
2177 #if 0
2178         /* rusting buried metallic objects is not implemented yet */
2179         if (ball->timed)
2180             (void) stop_timer(RUST_METAL, obj_to_any(ball));
2181 #endif
2182         place_object(ball, cc.x, cc.y);
2183         stackobj(ball);
2184         u.utrap = 0;
2185         u.utraptype = 0;
2186         del_engr_at(cc.x, cc.y);
2187         newsym(cc.x, cc.y);
2188     }
2189 }
2190
2191 /* move objects from fobj/nexthere lists to buriedobjlist, keeping position
2192    information */
2193 struct obj *
2194 bury_an_obj(otmp, dealloced)
2195 struct obj *otmp;
2196 boolean *dealloced;
2197 {
2198     struct obj *otmp2;
2199     boolean under_ice;
2200
2201     debugpline1("bury_an_obj: %s", xname(otmp));
2202     if (dealloced)
2203         *dealloced = FALSE;
2204     if (otmp == uball) {
2205         unpunish();
2206         u.utrap = rn1(50, 20);
2207         u.utraptype = TT_BURIEDBALL;
2208         pline_The("iron ball gets buried!");
2209     }
2210     /* after unpunish(), or might get deallocated chain */
2211     otmp2 = otmp->nexthere;
2212     /*
2213      * obj_resists(,0,0) prevents Rider corpses from being buried.
2214      * It also prevents The Amulet and invocation tools from being
2215      * buried.  Since they can't be confined to bags and statues,
2216      * it makes sense that they can't be buried either, even though
2217      * the real reason there (direct accessibility when carried) is
2218      * completely different.
2219      */
2220     if (otmp == uchain || obj_resists(otmp, 0, 0))
2221         return otmp2;
2222
2223     if (otmp->otyp == LEASH && otmp->leashmon != 0)
2224         o_unleash(otmp);
2225
2226     if (otmp->lamplit && otmp->otyp != POT_OIL)
2227         end_burn(otmp, TRUE);
2228
2229     obj_extract_self(otmp);
2230
2231     under_ice = is_ice(otmp->ox, otmp->oy);
2232     if (otmp->otyp == ROCK && !under_ice) {
2233         /* merges into burying material */
2234         if (dealloced)
2235             *dealloced = TRUE;
2236         obfree(otmp, (struct obj *) 0);
2237         return otmp2;
2238     }
2239     /*
2240      * Start a rot on organic material.  Not corpses -- they
2241      * are already handled.
2242      */
2243     if (otmp->otyp == CORPSE) {
2244         ; /* should cancel timer if under_ice */
2245     } else if ((under_ice ? otmp->oclass == POTION_CLASS : is_organic(otmp))
2246                && !obj_resists(otmp, 5, 95)) {
2247         (void) start_timer((under_ice ? 0L : 250L) + (long) rnd(250),
2248                            TIMER_OBJECT, ROT_ORGANIC, obj_to_any(otmp));
2249 #if 0
2250     /* rusting of buried metal not yet implemented */
2251     } else if (is_rustprone(otmp)) {
2252         (void) start_timer((long) rnd((otmp->otyp == HEAVY_IRON_BALL)
2253                                          ? 1500
2254                                          : 250),
2255                            TIMER_OBJECT, RUST_METAL, obj_to_any(otmp));
2256 #endif
2257     }
2258     add_to_buried(otmp);
2259     return  otmp2;
2260 }
2261
2262 void
2263 bury_objs(x, y)
2264 int x, y;
2265 {
2266     struct obj *otmp, *otmp2;
2267
2268     if (level.objects[x][y] != (struct obj *) 0) {
2269         debugpline2("bury_objs: at <%d,%d>", x, y);
2270     }
2271     for (otmp = level.objects[x][y]; otmp; otmp = otmp2)
2272         otmp2 = bury_an_obj(otmp, (boolean *) 0);
2273
2274     /* don't expect any engravings here, but just in case */
2275     del_engr_at(x, y);
2276     newsym(x, y);
2277 }
2278
2279 /* move objects from buriedobjlist to fobj/nexthere lists */
2280 void
2281 unearth_objs(x, y)
2282 int x, y;
2283 {
2284     struct obj *otmp, *otmp2, *bball;
2285     coord cc;
2286
2287     debugpline2("unearth_objs: at <%d,%d>", x, y);
2288     cc.x = x;
2289     cc.y = y;
2290     bball = buried_ball(&cc);
2291     for (otmp = level.buriedobjlist; otmp; otmp = otmp2) {
2292         otmp2 = otmp->nobj;
2293         if (otmp->ox == x && otmp->oy == y) {
2294             if (bball && otmp == bball && u.utraptype == TT_BURIEDBALL) {
2295                 buried_ball_to_punishment();
2296             } else {
2297                 obj_extract_self(otmp);
2298                 if (otmp->timed)
2299                     (void) stop_timer(ROT_ORGANIC, obj_to_any(otmp));
2300                 place_object(otmp, x, y);
2301                 stackobj(otmp);
2302             }
2303         }
2304     }
2305     del_engr_at(x, y);
2306     newsym(x, y);
2307 }
2308
2309 /*
2310  * The organic material has rotted away while buried.  As an expansion,
2311  * we could add add partial damage.  A damage count is kept in the object
2312  * and every time we are called we increment the count and reschedule another
2313  * timeout.  Eventually the object rots away.
2314  *
2315  * This is used by buried objects other than corpses.  When a container rots
2316  * away, any contents become newly buried objects.
2317  */
2318 /* ARGSUSED */
2319 void
2320 rot_organic(arg, timeout)
2321 anything *arg;
2322 long timeout UNUSED;
2323 {
2324     struct obj *obj = arg->a_obj;
2325
2326     while (Has_contents(obj)) {
2327         /* We don't need to place contained object on the floor
2328            first, but we do need to update its map coordinates. */
2329         obj->cobj->ox = obj->ox, obj->cobj->oy = obj->oy;
2330         /* Everything which can be held in a container can also be
2331            buried, so bury_an_obj's use of obj_extract_self insures
2332            that Has_contents(obj) will eventually become false. */
2333         (void) bury_an_obj(obj->cobj, (boolean *) 0);
2334     }
2335     obj_extract_self(obj);
2336     obfree(obj, (struct obj *) 0);
2337 }
2338
2339 /*
2340  * Called when a corpse has rotted completely away.
2341  */
2342 void
2343 rot_corpse(arg, timeout)
2344 anything *arg;
2345 long timeout;
2346 {
2347     xchar x = 0, y = 0;
2348     struct obj *obj = arg->a_obj;
2349     boolean on_floor = obj->where == OBJ_FLOOR,
2350             in_invent = obj->where == OBJ_INVENT;
2351
2352     if (on_floor) {
2353         x = obj->ox;
2354         y = obj->oy;
2355     } else if (in_invent) {
2356         if (flags.verbose) {
2357             char *cname = corpse_xname(obj, (const char *) 0, CXN_NO_PFX);
2358
2359 #if 0 /*JP:T*/
2360             Your("%s%s %s away%c", obj == uwep ? "wielded " : "", cname,
2361                  otense(obj, "rot"), obj == uwep ? '!' : '.');
2362 #else
2363             pline("\82 \82È\82½\82Ì%s%s\82Í\95\85\82Á\82Ä\82µ\82Ü\82Á\82½%s",
2364                      obj == uwep ? "\8eè\82É\82µ\82Ä\82¢\82é" : "", cname,
2365                      obj == uwep ? "\81I" : "\81D");
2366 #endif
2367         }
2368         if (obj == uwep) {
2369             uwepgone(); /* now bare handed */
2370             stop_occupation();
2371         } else if (obj == uswapwep) {
2372             uswapwepgone();
2373             stop_occupation();
2374         } else if (obj == uquiver) {
2375             uqwepgone();
2376             stop_occupation();
2377         }
2378     } else if (obj->where == OBJ_MINVENT && obj->owornmask) {
2379         if (obj == MON_WEP(obj->ocarry))
2380             setmnotwielded(obj->ocarry, obj);
2381     } else if (obj->where == OBJ_MIGRATING) {
2382         /* clear destination flag so that obfree()'s check for
2383            freeing a worn object doesn't get a false hit */
2384         obj->owornmask = 0L;
2385     }
2386     rot_organic(arg, timeout);
2387     if (on_floor) {
2388         struct monst *mtmp = m_at(x, y);
2389
2390         /* a hiding monster may be exposed */
2391         if (mtmp && !OBJ_AT(x, y) && mtmp->mundetected
2392             && hides_under(mtmp->data)) {
2393             mtmp->mundetected = 0;
2394         } else if (x == u.ux && y == u.uy && u.uundetected && hides_under(youmonst.data))
2395             (void) hideunder(&youmonst);
2396         newsym(x, y);
2397     } else if (in_invent)
2398         update_inventory();
2399 }
2400
2401 #if 0
2402 void
2403 bury_monst(mtmp)
2404 struct monst *mtmp;
2405 {
2406     debugpline1("bury_monst: %s", mon_nam(mtmp));
2407     if (canseemon(mtmp)) {
2408         if (is_flyer(mtmp->data) || is_floater(mtmp->data)) {
2409             pline_The("%s opens up, but %s is not swallowed!",
2410                       surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
2411             return;
2412         } else
2413             pline_The("%s opens up and swallows %s!",
2414                       surface(mtmp->mx, mtmp->my), mon_nam(mtmp));
2415     }
2416
2417     mtmp->mburied = TRUE;
2418     wakeup(mtmp);       /* at least give it a chance :-) */
2419     newsym(mtmp->mx, mtmp->my);
2420 }
2421
2422 void
2423 bury_you()
2424 {
2425     debugpline0("bury_you");
2426     if (!Levitation && !Flying) {
2427         if (u.uswallow)
2428 /*JP
2429             You_feel("a sensation like falling into a trap!");
2430 */
2431             You("ã©\82É\97\8e\82¿\82é\82æ\82¤\82È\8a´\8ao\82É\82¨\82»\82í\82ê\82½\81I");
2432         else
2433 /*JP
2434             pline_The("%s opens beneath you and you fall in!",
2435 */
2436             pline("%s\82ª\89º\95û\82É\8aJ\82«\81C\82 \82È\82½\82Í\97\8e\82¿\82½\81I",
2437                       surface(u.ux, u.uy));
2438
2439         u.uburied = TRUE;
2440         if (!Strangled && !Breathless)
2441             Strangled = 6;
2442         under_ground(1);
2443     }
2444 }
2445
2446 void
2447 unearth_you()
2448 {
2449     debugpline0("unearth_you");
2450     u.uburied = FALSE;
2451     under_ground(0);
2452     if (!uamul || uamul->otyp != AMULET_OF_STRANGULATION)
2453         Strangled = 0;
2454     vision_recalc(0);
2455 }
2456
2457 void
2458 escape_tomb()
2459 {
2460     debugpline0("escape_tomb");
2461     if ((Teleportation || can_teleport(youmonst.data))
2462         && (Teleport_control || rn2(3) < Luck+2)) {
2463 /*JP
2464         You("attempt a teleport spell.");
2465 */
2466         You("\8fu\8aÔ\88Ú\93®\82ð\8e\8e\82Ý\82½\81D");
2467         (void) dotele();        /* calls unearth_you() */
2468     } else if (u.uburied) { /* still buried after 'port attempt */
2469         boolean good;
2470
2471         if (amorphous(youmonst.data) || Passes_walls
2472             || noncorporeal(youmonst.data)
2473             || (unsolid(youmonst.data)
2474                 && youmonst.data != &mons[PM_WATER_ELEMENTAL])
2475             || (tunnels(youmonst.data) && !needspick(youmonst.data))) {
2476 #if 0 /*JP*/
2477             You("%s up through the %s.",
2478                 (tunnels(youmonst.data) && !needspick(youmonst.data))
2479                    ? "try to tunnel"
2480                    : (amorphous(youmonst.data))
2481                       ? "ooze"
2482                       : "phase",
2483                 surface(u.ux, u.uy));
2484 #else
2485             You("%s\82É%s\82ë\82¤\82Æ\82µ\82½\81D",
2486                 surface(u.ux, u.uy),
2487                 (tunnels(youmonst.data) && !needspick(youmonst.data))
2488                 ? "\83g\83\93\83l\83\8b\82ð\8c@"
2489                 : (amorphous(youmonst.data))
2490                    ? "\82É\82\82Ý\82Ì\82Ú"
2491                    : "\8f\99\81X\82É\82Í\82¢\82 \82ª");
2492 #endif
2493
2494             good = (tunnels(youmonst.data) && !needspick(youmonst.data))
2495                       ? dighole(TRUE, FALSE, (coord *)0) : TRUE;
2496             if (good)
2497                 unearth_you();
2498         }
2499     }
2500 }
2501
2502 void
2503 bury_obj(otmp)
2504 struct obj *otmp;
2505 {
2506     debugpline0("bury_obj");
2507     if (cansee(otmp->ox, otmp->oy))
2508 /*JP
2509         pline_The("objects on the %s tumble into a hole!",
2510 */
2511         pline_The("%s\82Ì\95¨\91Ì\82Í\8c\8a\82É\93]\82ª\82Á\82½\81I",
2512                   surface(otmp->ox, otmp->oy));
2513
2514     bury_objs(otmp->ox, otmp->oy);
2515 }
2516 #endif /*0*/
2517
2518 #ifdef DEBUG
2519 /* bury everything at your loc and around */
2520 int
2521 wiz_debug_cmd_bury()
2522 {
2523     int x, y;
2524
2525     for (x = u.ux - 1; x <= u.ux + 1; x++)
2526         for (y = u.uy - 1; y <= u.uy + 1; y++)
2527             if (isok(x, y))
2528                 bury_objs(x, y);
2529     return 0;
2530 }
2531 #endif /* DEBUG */
2532
2533 /*dig.c*/