OSDN Git Service

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