OSDN Git Service

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